--- linux-2.6.28.orig/Makefile +++ linux-2.6.28/Makefile @@ -328,14 +328,24 @@ CFLAGS_KERNEL = AFLAGS_KERNEL = +# Prefer linux-backports-modules +ifneq ($(KBUILD_SRC),) +ifneq ($(shell if test -e $(KBUILD_OUTPUT)/ubuntu-build; then echo yes; fi),yes) +UBUNTUINCLUDE := -I/usr/src/linux-headers-lbm-$(KERNELRELEASE) +endif +endif # Use LINUXINCLUDE when you must reference the include/ directory. # Needed to be compatible with the O= option -LINUXINCLUDE := -Iinclude \ +LINUXINCLUDE := $(UBUNTUINCLUDE) -Iinclude \ $(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include) \ -I$(srctree)/arch/$(hdr-arch)/include \ -include include/linux/autoconf.h +# UBUNTU: Include our third party driver stuff too +LINUXINCLUDE += -Iubuntu/include \ + $(if $(KBUILD_SRC),-I$(srctree)/ubuntu/include) + KBUILD_CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ @@ -458,7 +468,7 @@ # Objects we will link into vmlinux / subdirs we need to visit init-y := init/ -drivers-y := drivers/ sound/ firmware/ +drivers-y := drivers/ sound/ firmware/ ubuntu/ net-y := net/ libs-y := lib/ core-y := usr/ --- linux-2.6.28.orig/ubuntu/Kconfig +++ linux-2.6.28/ubuntu/Kconfig @@ -0,0 +1,22 @@ +menu "Ubuntu Supplied Third-Party Device Drivers" + +source "ubuntu/drbd/Kconfig" +source "ubuntu/iscsitarget/Kconfig" +source "ubuntu/squashfs/Kconfig" +source "ubuntu/aufs/Kconfig" +source "ubuntu/atl2/Kconfig" +source "ubuntu/et131x/Kconfig" +source "ubuntu/dm-raid4-5/Kconfig" +source "ubuntu/dm-loop/Kconfig" +source "ubuntu/ndiswrapper/Kconfig" +source "ubuntu/compcache/Kconfig" +source "ubuntu/misc/Kconfig" +source "ubuntu/heci/Kconfig" +source "ubuntu/qc-usb/Kconfig" +source "ubuntu/rfkill/Kconfig" +source "ubuntu/unionfs/Kconfig" +source "ubuntu/lirc/Kconfig" +source "ubuntu/gfs/Kconfig" +source "ubuntu/tlsup/Kconfig" + +endmenu --- linux-2.6.28.orig/ubuntu/Makefile +++ linux-2.6.28/ubuntu/Makefile @@ -0,0 +1,25 @@ +# +# Makefile for the Linux kernel ubuntu supplied third-party device drivers. +# + +obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ +obj-$(CONFIG_SCSI_ISCSITARGET) += iscsitarget/ +obj-$(CONFIG_SQUASHFS) += squashfs/ +obj-$(CONFIG_AUFS) += aufs/ +obj-$(CONFIG_ATL2) += atl2/ +obj-$(CONFIG_NET_ET131X) += et131x/ +obj-$(CONFIG_DM_RAID45) += dm-raid4-5/ +obj-$(CONFIG_DM_LOOP) += dm-loop/ +obj-$(CONFIG_NDISWRAPPER) += ndiswrapper/ +obj-$(CONFIG_TLSF) += compcache/ +obj-$(CONFIG_HECI) += heci/ +obj-$(CONFIG_QC_USB) += qc-usb/ +obj-$(CONFIG_FS_UNIONFS) += unionfs/ +obj-$(CONFIG_LIRC_DEV) += lirc/ +obj-$(CONFIG_GFS_FS) += gfs/ +obj-$(CONFIG_TLSUP) += tlsup/ + +obj-m += misc/ rfkill/ + +# This is a stupid trick to get kbuild to create ubuntu/built-in.o +obj- += foo.o --- linux-2.6.28.orig/ubuntu/unionfs/rdstate.c +++ linux-2.6.28/ubuntu/unionfs/rdstate.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: rdstate.c,v 1.34 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* This file contains the routines for maintaining readdir state. */ +/* There are two structures here, rdstate which is a hash table + * of the second structure which is a filldir_node. */ + +/* This is a struct kmem_cache for filldir nodes, because we allocate a lot of them + * and they shouldn't waste memory. If the node has a small name (as defined + * by the dentry structure), then we use an inline name to preserve kmalloc + * space. */ +static struct kmem_cache *unionfs_filldir_cachep; +int init_filldir_cache(void) +{ + unionfs_filldir_cachep = + kmem_cache_create("unionfs_filldir", sizeof(struct filldir_node), 0, + SLAB_RECLAIM_ACCOUNT, NULL); + + if (!unionfs_filldir_cachep) + return -ENOMEM; + + return 0; +} + +void destroy_filldir_cache(void) +{ + if (!unionfs_filldir_cachep) + return; + kmem_cache_destroy(unionfs_filldir_cachep); + return; +} + +/* This is a tuning parameter that tells us roughly how big to make the + * hash table in directory entries per page. This isn't perfect, but + * at least we get a hash table size that shouldn't be too overloaded. + * The following averages are based on my home directory. + * 14.44693 Overall + * 12.29 Single Page Directories + * 117.93 Multi-page directories + */ +#define DENTPAGE 4096 +#define DENTPERONEPAGE 12 +#define DENTPERPAGE 118 +#define MINHASHSIZE 1 +static int guesstimate_hash_size(struct inode *inode) +{ + struct inode *hidden_inode; + int bindex; + int hashsize = MINHASHSIZE; + + if (itopd(inode)->uii_hashsize > 0) + return itopd(inode)->uii_hashsize; + + for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { + if (!(hidden_inode = itohi_index(inode, bindex))) + continue; + + if (hidden_inode->i_size == DENTPAGE) { + hashsize += DENTPERONEPAGE; + } else { + hashsize += + (hidden_inode->i_size / DENTPAGE) * DENTPERPAGE; + } + } + + return hashsize; +} + +int init_rdstate(struct file *file) +{ + BUG_ON(sizeof(loff_t) != (sizeof(unsigned int) + sizeof(unsigned int))); + BUG_ON(ftopd(file)->rdstate != NULL); + + ftopd(file)->rdstate = + alloc_rdstate(file->f_dentry->d_inode, fbstart(file)); + if (!ftopd(file)->rdstate) + return -ENOMEM; + return 0; +} + +struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos) +{ + struct unionfs_dir_state *rdstate = NULL; + struct list_head *pos; + + print_entry("f_pos: %lld", fpos); + spin_lock(&itopd(inode)->uii_rdlock); + list_for_each(pos, &itopd(inode)->uii_readdircache) { + struct unionfs_dir_state *r = + list_entry(pos, struct unionfs_dir_state, uds_cache); + if (fpos == rdstate2offset(r)) { + itopd(inode)->uii_rdcount--; + list_del(&r->uds_cache); + rdstate = r; + break; + } + } + spin_unlock(&itopd(inode)->uii_rdlock); + print_exit_pointer(rdstate); + return rdstate; +} + +struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex) +{ + int i = 0; + int hashsize; + int mallocsize = sizeof(struct unionfs_dir_state); + struct unionfs_dir_state *rdstate; + + hashsize = guesstimate_hash_size(inode); + mallocsize += hashsize * sizeof(struct list_head); + /* Round it up to the next highest power of two. */ + mallocsize--; + mallocsize |= mallocsize >> 1; + mallocsize |= mallocsize >> 2; + mallocsize |= mallocsize >> 4; + mallocsize |= mallocsize >> 8; + mallocsize |= mallocsize >> 16; + mallocsize++; + + /* This should give us about 500 entries anyway. */ + if (mallocsize > PAGE_SIZE) + mallocsize = PAGE_SIZE; + + hashsize = + (mallocsize - + sizeof(struct unionfs_dir_state)) / sizeof(struct list_head); + + rdstate = KMALLOC(mallocsize, GFP_KERNEL); + if (!rdstate) + return NULL; + + spin_lock(&itopd(inode)->uii_rdlock); + if (itopd(inode)->uii_cookie >= (MAXRDCOOKIE - 1)) + itopd(inode)->uii_cookie = 1; + else + itopd(inode)->uii_cookie++; + + rdstate->uds_cookie = itopd(inode)->uii_cookie; + spin_unlock(&itopd(inode)->uii_rdlock); + rdstate->uds_offset = 1; + rdstate->uds_access = jiffies; + rdstate->uds_bindex = bindex; + rdstate->uds_dirpos = 0; + rdstate->uds_hashentries = 0; + rdstate->uds_size = hashsize; + for (i = 0; i < rdstate->uds_size; i++) + INIT_LIST_HEAD(&rdstate->uds_list[i]); + + return rdstate; +} + +static void free_filldir_node(struct filldir_node *node) +{ + if (node->namelen >= DNAME_INLINE_LEN_MIN) + KFREE(node->name); + kmem_cache_free(unionfs_filldir_cachep, node); +} + +void free_rdstate(struct unionfs_dir_state *state) +{ + struct filldir_node *tmp; + int i; + + for (i = 0; i < state->uds_size; i++) { + struct list_head *head = &(state->uds_list[i]); + struct list_head *pos, *n; + + /* traverse the list and deallocate space */ + list_for_each_safe(pos, n, head) { + tmp = list_entry(pos, struct filldir_node, file_list); + list_del(&tmp->file_list); + free_filldir_node(tmp); + } + } + + KFREE(state); +} + +struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate, + const char *name, int namelen) +{ + int index; + unsigned int hash; + struct list_head *head; + struct list_head *pos; + struct filldir_node *cursor = NULL; + int found = 0; + + /* If we print entry, we end up with spurious data. */ + /* print_entry("name = %*s", namelen, name); */ + print_entry_location(); + + BUG_ON(namelen <= 0); + + hash = full_name_hash(name, namelen); + index = hash % rdstate->uds_size; + + head = &(rdstate->uds_list[index]); + list_for_each(pos, head) { + cursor = list_entry(pos, struct filldir_node, file_list); + + if (cursor->namelen == namelen && cursor->hash == hash + && !strncmp(cursor->name, name, namelen)) { + /* a duplicate exists, and hence no need to create entry to the list */ + found = 1; + /* if the duplicate is in this branch, then the file system is corrupted. */ + if (cursor->bindex == rdstate->uds_bindex) { + //buf->error = err = -EIO; + dprint(PRINT_DEBUG, + "Possible I/O error unionfs_filldir: a file is duplicated in the same branch %d: %s\n", + rdstate->uds_bindex, cursor->name); + } + break; + } + } + + if (!found) { + cursor = NULL; + } + print_exit_pointer(cursor); + return cursor; +} + +inline struct filldir_node *alloc_filldir_node(const char *name, int namelen, + unsigned int hash, int bindex) +{ + struct filldir_node *newnode; + + newnode = + (struct filldir_node *)kmem_cache_alloc(unionfs_filldir_cachep, + GFP_KERNEL); + if (!newnode) + goto out; + + out: + return newnode; +} + +int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name, + int namelen, int bindex, int whiteout) +{ + struct filldir_node *new; + unsigned int hash; + int index; + int err = 0; + struct list_head *head; + + /* We can't print this because we end up Oopsing. */ + /* print_entry("name = %*s", namelen, name); */ + print_entry_location(); + + BUG_ON(namelen <= 0); + + hash = full_name_hash(name, namelen); + index = hash % rdstate->uds_size; + head = &(rdstate->uds_list[index]); + + new = alloc_filldir_node(name, namelen, hash, bindex); + if (!new) { + err = -ENOMEM; + goto out; + } + + INIT_LIST_HEAD(&new->file_list); + new->namelen = namelen; + new->hash = hash; + new->bindex = bindex; + new->whiteout = whiteout; + + if (namelen < DNAME_INLINE_LEN_MIN) { + new->name = new->iname; + } else { + new->name = (char *)KMALLOC(namelen + 1, GFP_KERNEL); + if (!new->name) { + kmem_cache_free(unionfs_filldir_cachep, new); + new = NULL; + goto out; + } + } + + memcpy(new->name, name, namelen); + new->name[namelen] = '\0'; + + rdstate->uds_hashentries++; + + list_add(&(new->file_list), head); + out: + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/dirfops.c +++ linux-2.6.28/ubuntu/unionfs/dirfops.c @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: dirfops.c,v 1.25 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* Make sure our rdstate is playing by the rules. */ +static void verify_rdstate_offset(struct unionfs_dir_state *rdstate) +{ + BUG_ON(rdstate->uds_offset >= DIREOF); + BUG_ON(rdstate->uds_cookie >= MAXRDCOOKIE); +} + +struct unionfs_getdents_callback { + struct unionfs_dir_state *rdstate; + void *dirent; + int entries_written; + int filldir_called; + int filldir_error; + filldir_t filldir; + struct super_block *sb; +}; + +/* copied from generic filldir in fs/readir.c */ +static int unionfs_filldir(void *dirent, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + struct unionfs_getdents_callback *buf = + (struct unionfs_getdents_callback *)dirent; + struct filldir_node *found = NULL; + int err = 0; + int is_wh_entry = 0; + + dprint(PRINT_DEBUG, "unionfs_filldir name=%*s\n", namelen, name); + + buf->filldir_called++; + + if ((namelen > WHLEN) && !strncmp(name, WHPFX, WHLEN)) { + name += WHLEN; + namelen -= WHLEN; + is_wh_entry = 1; + } + + found = find_filldir_node(buf->rdstate, name, namelen); + + if (found) + goto out; + + /* if 'name' isn't a whiteout filldir it. */ + if (!is_wh_entry) { + off_t pos = rdstate2offset(buf->rdstate); + ino_t unionfs_ino = ino; +#ifdef UNIONFS_IMAP + if (stopd(buf->sb)->usi_persistent) + err = read_uin(buf->sb, buf->rdstate->uds_bindex, + ino, O_CREAT, &unionfs_ino); +#endif + if (!err) { + err = buf->filldir(buf->dirent, name, namelen, pos, + unionfs_ino, d_type); + buf->rdstate->uds_offset++; + verify_rdstate_offset(buf->rdstate); + } + } + /* If we did fill it, stuff it in our hash, otherwise return an error */ + if (err) { + buf->filldir_error = err; + goto out; + } + buf->entries_written++; + if ((err = add_filldir_node(buf->rdstate, name, namelen, + buf->rdstate->uds_bindex, is_wh_entry))) + buf->filldir_error = err; + + out: + return err; +} + +static int unionfs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + int err = 0; + struct file *hidden_file = NULL; + struct inode *inode = NULL; + struct unionfs_getdents_callback buf; + struct unionfs_dir_state *uds; + int bend; + loff_t offset; + + print_entry("file = %p, pos = %llx", file, file->f_pos); + + print_file("In unionfs_readdir()", file); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + inode = file->f_dentry->d_inode; + checkinode(inode, "unionfs_readdir"); + + uds = ftopd(file)->rdstate; + if (!uds) { + if (file->f_pos == DIREOF) { + goto out; + } else if (file->f_pos > 0) { + uds = find_rdstate(inode, file->f_pos); + if (!uds) { + err = -ESTALE; + goto out; + } + ftopd(file)->rdstate = uds; + } else { + init_rdstate(file); + uds = ftopd(file)->rdstate; + } + } + bend = fbend(file); + + while (uds->uds_bindex <= bend) { + hidden_file = ftohf_index(file, uds->uds_bindex); + if (!hidden_file) { + dprint(PRINT_DEBUG, + "Incremented bindex to %d of %d," + " because hidden file is NULL.\n", + uds->uds_bindex, bend); + uds->uds_bindex++; + uds->uds_dirpos = 0; + continue; + } + + /* prepare callback buffer */ + buf.filldir_called = 0; + buf.filldir_error = 0; + buf.entries_written = 0; + buf.dirent = dirent; + buf.filldir = filldir; + buf.rdstate = uds; + buf.sb = inode->i_sb; + + /* Read starting from where we last left off. */ + offset = vfs_llseek(hidden_file, uds->uds_dirpos, 0); + if (offset < 0) { + err = offset; + goto out; + } + dprint(PRINT_DEBUG, "calling readdir for %d.%lld (offset = %lld)\n", + uds->uds_bindex, uds->uds_dirpos, offset); + err = vfs_readdir(hidden_file, unionfs_filldir, (void *)&buf); + dprint(PRINT_DEBUG, + "readdir on %d.%lld = %d (entries written %d, filldir called %d)\n", + uds->uds_bindex, (long long)uds->uds_dirpos, err, + buf.entries_written, buf.filldir_called); + /* Save the position for when we continue. */ + + offset = vfs_llseek(hidden_file, 0, 1); + if (offset < 0) { + err = offset; + goto out; + } + uds->uds_dirpos = offset; + + /* Copy the atime. */ + fist_copy_attr_atime(inode, hidden_file->f_dentry->d_inode); + + if (err < 0) { + goto out; + } + + if (buf.filldir_error) { + break; + } + + if (!buf.entries_written) { + uds->uds_bindex++; + uds->uds_dirpos = 0; + } + } + + if (!buf.filldir_error && uds->uds_bindex >= bend) { + dprint(PRINT_DEBUG, + "Discarding rdstate because readdir is over (hashsize = %d)\n", + uds->uds_hashentries); + /* Save the number of hash entries for next time. */ + itopd(inode)->uii_hashsize = uds->uds_hashentries; + free_rdstate(uds); + ftopd(file)->rdstate = NULL; + file->f_pos = DIREOF; + } else { + file->f_pos = rdstate2offset(uds); + dprint(PRINT_DEBUG, "rdstate now has a cookie of %u (err = %d)\n", + uds->uds_cookie, err); + } + + out: + checkinode(inode, "post unionfs_readdir"); + print_exit_status(err); + return err; +} + +/* This is not meant to be a generic repositioning function. If you do + * things that aren't supported, then we return EINVAL. + * + * What is allowed: + * (1) seeking to the same position that you are currently at + * This really has no effect, but returns where you are. + * (2) seeking to the end of the file, if you've read everything + * This really has no effect, but returns where you are. + * (3) seeking to the beginning of the file + * This throws out all state, and lets you begin again. + */ +static loff_t unionfs_dir_llseek(struct file *file, loff_t offset, int origin) +{ + struct unionfs_dir_state *rdstate; + loff_t err; + + print_entry(" file=%p, offset=0x%llx, origin = %d", file, offset, + origin); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + rdstate = ftopd(file)->rdstate; + + /* We let users seek to their current position, but not anywhere else. */ + if (!offset) { + switch (origin) { + case SEEK_SET: + if (rdstate) { + free_rdstate(rdstate); + ftopd(file)->rdstate = NULL; + } + init_rdstate(file); + err = 0; + break; + case SEEK_CUR: + if (file->f_pos) { + if (file->f_pos == DIREOF) + err = DIREOF; + else + BUG_ON(file->f_pos != + rdstate2offset(rdstate)); + err = file->f_pos; + } else { + err = 0; + } + break; + case SEEK_END: + /* Unsupported, because we would break everything. */ + err = -EINVAL; + break; + } + } else { + switch (origin) { + case SEEK_SET: + if (rdstate) { + if (offset == rdstate2offset(rdstate)) { + err = offset; + } else if (file->f_pos == DIREOF) { + err = DIREOF; + } else { + err = -EINVAL; + } + } else { + if ((rdstate = + find_rdstate(file->f_dentry->d_inode, + offset))) { + ftopd(file)->rdstate = rdstate; + err = rdstate->uds_offset; + } else { + err = -EINVAL; + } + } + break; + case SEEK_CUR: + case SEEK_END: + /* Unsupported, because we would break everything. */ + err = -EINVAL; + break; + } + } + + out: + print_exit_status((int)err); + return err; +} + +/* Trimmed directory options, we shouldn't pass everything down since + * we don't want to operate on partial directories. + */ +struct file_operations unionfs_dir_fops = { + .llseek = unionfs_dir_llseek, + .read = generic_read_dir, + .readdir = unionfs_readdir, + .unlocked_ioctl = unionfs_ioctl, + .open = unionfs_open, + .release = unionfs_file_release, + .flush = unionfs_flush, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/copyup.c +++ linux-2.6.28/ubuntu/unionfs/copyup.c @@ -0,0 +1,738 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York* + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: copyup.c,v 1.78 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +/*Not Working Yet*/ +static int copyup_xattrs(struct dentry *old_hidden_dentry, + struct dentry *new_hidden_dentry) +{ + int err = 0; + ssize_t list_size = -1; + char *name_list = NULL; + char *attr_value = NULL; + char *name_list_orig = NULL; + + print_entry_location(); + + list_size = vfs_listxattr(old_hidden_dentry, NULL, NULL, 0, NULL); + + if (list_size <= 0) { + err = list_size; + goto out; + } + + name_list = xattr_alloc(list_size + 1, XATTR_LIST_MAX); + if (!name_list || IS_ERR(name_list)) { + err = PTR_ERR(name_list); + goto out; + } + list_size = vfs_listxattr(old_hidden_dentry, NULL, name_list, + list_size, NULL); + attr_value = xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX); + if (!attr_value || IS_ERR(attr_value)) { + err = PTR_ERR(name_list); + goto out; + } + name_list_orig = name_list; + while (*name_list) { + ssize_t size; + + //We need to lock here since vfs_getxattr doesn't lock for us. + mutex_lock(&old_hidden_dentry->d_inode->i_mutex); + size = vfs_getxattr(old_hidden_dentry, NULL, name_list, + attr_value, XATTR_SIZE_MAX, NULL); + mutex_unlock(&old_hidden_dentry->d_inode->i_mutex); + if (size < 0) { + err = size; + goto out; + } + + if (size > XATTR_SIZE_MAX) { + err = -E2BIG; + goto out; + } + //We don't need to lock here since vfs_setxattr does it for us. + err = vfs_setxattr(new_hidden_dentry, NULL, name_list, + attr_value, size, 0, NULL); + + if (err < 0) + goto out; + name_list += strlen(name_list) + 1; + } + out: + name_list = name_list_orig; + + if (name_list) + xattr_free(name_list, list_size + 1); + if (attr_value) + xattr_free(attr_value, XATTR_SIZE_MAX); + /* It is no big deal if this fails, we just roll with the punches. */ + if (err == -ENOTSUPP || err == -EOPNOTSUPP) + err = 0; + return err; +} + +/* Determine the mode based on the copyup flags, and the existing dentry. */ +static int copyup_permissions(struct super_block *sb, + struct dentry *old_hidden_dentry, + struct dentry *new_hidden_dentry) +{ + struct iattr newattrs; + int err; + + print_entry_location(); + + newattrs.ia_atime = old_hidden_dentry->d_inode->i_atime; + newattrs.ia_mtime = old_hidden_dentry->d_inode->i_mtime; + newattrs.ia_ctime = old_hidden_dentry->d_inode->i_ctime; + newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME | ATTR_MTIME | + ATTR_ATIME_SET | ATTR_MTIME_SET; + /* original mode of old file */ + newattrs.ia_mode = old_hidden_dentry->d_inode->i_mode; + newattrs.ia_gid = old_hidden_dentry->d_inode->i_gid; + newattrs.ia_uid = old_hidden_dentry->d_inode->i_uid; + newattrs.ia_valid |= ATTR_FORCE | ATTR_GID | ATTR_UID | ATTR_MODE; + if (newattrs.ia_valid & ATTR_MODE) { + newattrs.ia_mode = + (newattrs.ia_mode & S_IALLUGO) | (old_hidden_dentry-> + d_inode-> + i_mode & ~S_IALLUGO); + } + + err = notify_change(new_hidden_dentry, NULL, &newattrs); + + print_exit_status(err); + return err; +} + +int copyup_dentry(struct inode *dir, struct dentry *dentry, + int bstart, int new_bindex, + struct file **copyup_file, loff_t len) +{ + return copyup_named_dentry(dir, dentry, bstart, new_bindex, + dentry->d_name.name, + dentry->d_name.len, copyup_file, len); +} + +int copyup_named_dentry(struct inode *dir, struct dentry *dentry, + int bstart, int new_bindex, const char *name, + int namelen, struct file **copyup_file, loff_t len) +{ + struct dentry *new_hidden_dentry; + struct dentry *old_hidden_dentry = NULL; + struct super_block *sb; + struct file *input_file = NULL; + struct file *output_file = NULL; + struct sioq_args args; + ssize_t read_bytes, write_bytes; + mm_segment_t old_fs; + int err = 0; + char *buf; + int old_bindex; + int got_branch_input = -1; + int got_branch_output = -1; + int old_bstart; + int old_bend; + int old_mode; + loff_t size = len; + struct dentry *new_hidden_parent_dentry = NULL; + mm_segment_t oldfs; + char *symbuf = NULL; + + print_entry_location(); + verify_locked(dentry); + print_dentry("IN: copyup_named_dentry", dentry); + + old_bindex = bstart; + old_bstart = dbstart(dentry); + old_bend = dbend(dentry); + + BUG_ON(new_bindex < 0); + BUG_ON(new_bindex >= old_bindex); + + sb = dir->i_sb; + + unionfs_read_lock(sb); + + if ((err = is_robranch_super(sb, new_bindex))) + goto out; + + /* Create the directory structure above this dentry. */ + new_hidden_dentry = create_parents_named(dir, dentry, name, new_bindex); + if (IS_ERR(new_hidden_dentry)) { + err = PTR_ERR(new_hidden_dentry); + goto out; + } + + print_dentry("Copyup Object", new_hidden_dentry); + + /* Now we actually create the object. */ + old_hidden_dentry = dtohd_index(dentry, old_bindex); + DGET(old_hidden_dentry); + + old_mode = old_hidden_dentry->d_inode->i_mode; + + /* For symlinks, we must read the link before we lock the directory. */ + if (S_ISLNK(old_mode)) { + + symbuf = KMALLOC(PATH_MAX, GFP_KERNEL); + if (!symbuf) { + err = -ENOMEM; + goto copyup_readlink_err; + } + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = + old_hidden_dentry->d_inode->i_op-> + readlink(old_hidden_dentry, (char __user *)symbuf, + PATH_MAX); + set_fs(oldfs); + if (err < 0) + goto copyup_readlink_err; + symbuf[err] = '\0'; + } + + /* Now we lock the parent, and create the object in the new branch. */ + new_hidden_parent_dentry = lock_parent(new_hidden_dentry); + if (S_ISDIR(old_mode)) { + args.mkdir.parent = new_hidden_parent_dentry->d_inode; + args.mkdir.dentry = new_hidden_dentry; + args.mkdir.mode = old_mode; /*S_IRWXU*/ + run_sioq(__unionfs_mkdir, &args); + err = args.err; + } else if (S_ISLNK(old_mode)) { + args.symlink.parent = new_hidden_parent_dentry->d_inode; + args.symlink.dentry = new_hidden_dentry; + args.symlink.symbuf = symbuf; + args.symlink.mode = old_mode; + run_sioq(__unionfs_symlink, &args); + err = args.err; + } else if (S_ISBLK(old_mode) + || S_ISCHR(old_mode) + || S_ISFIFO(old_mode) + || S_ISSOCK(old_mode)) { + args.mknod.parent = new_hidden_parent_dentry->d_inode; + args.mknod.dentry = new_hidden_dentry; + args.mknod.mode = old_mode; + args.mknod.dev = old_hidden_dentry->d_inode->i_rdev; + run_sioq(__unionfs_mknod, &args); + err = args.err; + } else if (S_ISREG(old_mode)) { + args.create.parent = new_hidden_parent_dentry->d_inode; + args.create.dentry = new_hidden_dentry; + args.create.mode = old_mode; + args.create.nd = NULL; + run_sioq(__unionfs_create, &args); + err = args.err; + } else { + printk(KERN_ERR "Unknown inode type %d\n", + old_hidden_dentry->d_inode->i_mode); + BUG(); + } + + copyup_readlink_err: + KFREE(symbuf); + if (err) { + /* get rid of the hidden dentry and all its traces */ + DPUT(new_hidden_dentry); + set_dtohd_index(dentry, new_bindex, NULL); + set_dbstart(dentry, old_bstart); + set_dbend(dentry, old_bend); + goto out_dir; + } +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + err = write_uin(dentry->d_sb, dentry->d_inode->i_ino, + new_bindex, new_hidden_dentry->d_inode->i_ino); + if (err) + goto out_dir; + } +#endif + /* We actually copyup the file here. */ + if (S_ISREG(old_hidden_dentry->d_inode->i_mode)) { + mntget(stohiddenmnt_index(sb, old_bindex)); + branchget(sb, old_bindex); + got_branch_input = old_bindex; + input_file = + DENTRY_OPEN(old_hidden_dentry, + stohiddenmnt_index(sb, old_bindex), + O_RDONLY | O_LARGEFILE); + if (IS_ERR(input_file)) { + err = PTR_ERR(input_file); + goto out_dir; + } + if (!input_file->f_op || !input_file->f_op->read) { + err = -EINVAL; + goto out_dir; + } + + /* copy the new file */ + DGET(new_hidden_dentry); + mntget(stohiddenmnt_index(sb, new_bindex)); + branchget(sb, new_bindex); + got_branch_output = new_bindex; + output_file = + DENTRY_OPEN(new_hidden_dentry, + stohiddenmnt_index(sb, new_bindex), + O_WRONLY | O_LARGEFILE); + if (IS_ERR(output_file)) { + err = PTR_ERR(output_file); + goto out_dir; + } + if (!output_file->f_op || !output_file->f_op->write) { + err = -EINVAL; + goto out_dir; + } + + /* allocating a buffer */ + buf = (char *)KMALLOC(PAGE_SIZE, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto out_dir; + } + + /* now read PAGE_SIZE bytes from offset 0 in a loop */ + old_fs = get_fs(); + + input_file->f_pos = 0; + output_file->f_pos = 0; + + err = 0; // reset error just in case + set_fs(KERNEL_DS); + do { + if (len >= PAGE_SIZE) + size = PAGE_SIZE; + else if ((len < PAGE_SIZE) && (len > 0)) + size = len; + + len -= PAGE_SIZE; + + read_bytes = + input_file->f_op->read(input_file, + (char __user *)buf, size, + &input_file->f_pos); + if (read_bytes <= 0) { + err = read_bytes; + break; + } + + write_bytes = + output_file->f_op->write(output_file, + (char __user *)buf, + read_bytes, + &output_file->f_pos); + if (write_bytes < 0 || (write_bytes < read_bytes)) { + err = write_bytes; + break; + } + } while ((read_bytes > 0) && (len > 0)); + set_fs(old_fs); + KFREE(buf); +#ifdef UNIONFS_MMAP + /* SP: Now that we copied up the file, have to sync its data + * as otherwise when we do a read_cache_page(), we'll possibly + * read crap. + * + * another posisble solution would be in the address op code + * would be to check the "lower" page to see if its dirty, + * and if it's dirty, use it directl + */ + if (!err) { + err = + output_file->f_op->fsync(output_file, + new_hidden_dentry, 0); + } +#endif + if (err) { + /* copyup failed, because we ran out of space or quota, + * or something else happened so let's unlink; we don't + * really care about the return value of vfs_unlink */ + vfs_unlink(new_hidden_parent_dentry->d_inode, + new_hidden_dentry, NULL); + + goto out_dir; + } + } + + /* Set permissions. */ + if ((err = + copyup_permissions(sb, old_hidden_dentry, new_hidden_dentry))) + goto out_dir; + /* Selinux uses extended attributes for permissions. */ + if ((err = copyup_xattrs(old_hidden_dentry, new_hidden_dentry))) + goto out_dir; + + /* do not allow files getting deleted to be reinterposed */ + if (!d_deleted(dentry)) + unionfs_reinterpose(dentry); + + out_dir: + if (new_hidden_parent_dentry) + unlock_dir(new_hidden_parent_dentry); + + out: + if (input_file && !IS_ERR(input_file)) { + fput(input_file); + } else { + /* since input file was not opened, we need to explicitly + * dput the old_hidden_dentry + */ + DPUT(old_hidden_dentry); + } + + /* in any case, we have to branchput */ + if (got_branch_input >= 0) + branchput(sb, got_branch_input); + + if (output_file) { + if (copyup_file && !err) { + *copyup_file = output_file; + } else { + /* close the file if there was no error, or if we ran + * out of space in which case we unlinked the file */ + if (!IS_ERR(output_file)) + fput(output_file); + branchput(sb, got_branch_output); + } + } + + unionfs_read_unlock(sb); + + print_dentry("OUT: copyup_dentry", dentry); + print_inode("OUT: copyup_dentry", dentry->d_inode); + + print_exit_status(err); + return err; +} + +/* This function creates a copy of a file represented by 'file' which currently + * resides in branch 'bstart' to branch 'new_bindex. The copy will be named + * "name". */ +int copyup_named_file(struct inode *dir, struct file *file, char *name, + int bstart, int new_bindex, loff_t len) +{ + int err = 0; + struct file *output_file = NULL; + + print_entry_location(); + + err = copyup_named_dentry(dir, file->f_dentry, bstart, + new_bindex, name, strlen(name), &output_file, + len); + if (!err) { + fbstart(file) = new_bindex; + set_ftohf_index(file, new_bindex, output_file); + } + + print_exit_status(err); + return err; +} + +/* This function creates a copy of a file represented by 'file' which currently + * resides in branch 'bstart' to branch 'new_bindex. + */ +int copyup_file(struct inode *dir, struct file *file, int bstart, + int new_bindex, loff_t len) +{ + int err = 0; + struct file *output_file = NULL; + + print_entry_location(); + + err = copyup_dentry(dir, file->f_dentry, bstart, new_bindex, + &output_file, len); + if (!err) { + fbstart(file) = new_bindex; + set_ftohf_index(file, new_bindex, output_file); + } + + print_exit_status(err); + return err; +} + +/* This function replicates the directory structure upto given dentry + * in the bindex branch. Can create directory structure recursively to the right + * also. + */ +struct dentry *create_parents(struct inode *dir, struct dentry *dentry, + int bindex) +{ + struct dentry *hidden_dentry; + + print_entry_location(); + hidden_dentry = + create_parents_named(dir, dentry, dentry->d_name.name, bindex); + print_exit_location(); + + return (hidden_dentry); +} + +/* This function replicates the directory structure upto given dentry + * in the bindex branch. */ +struct dentry *create_parents_named(struct inode *dir, struct dentry *dentry, + const char *name, int bindex) +{ + int err; + struct dentry *child_dentry; + struct dentry *parent_dentry; + struct dentry *hidden_parent_dentry = NULL; + struct dentry *hidden_dentry = NULL; + struct sioq_args args; + const char *childname; + unsigned int childnamelen; + + int old_kmalloc_size; + int kmalloc_size; + int num_dentry; + int count; + + int old_bstart; + int old_bend; + struct dentry **path = NULL; + struct dentry **tmp_path; + struct super_block *sb; +#ifdef UNIONFS_IMAP + int persistent; +#endif + print_entry_location(); + + verify_locked(dentry); + + /* There is no sense allocating any less than the minimum. */ + kmalloc_size = 128; + num_dentry = kmalloc_size / sizeof(struct dentry *); + + if ((err = is_robranch_super(dir->i_sb, bindex))) { + hidden_dentry = ERR_PTR(err); + goto out; + } + + print_dentry("IN: create_parents_named", dentry); + dprint(PRINT_DEBUG, "name = %s\n", name); + + old_bstart = dbstart(dentry); + old_bend = dbend(dentry); + + hidden_dentry = ERR_PTR(-ENOMEM); + path = (struct dentry **)KZALLOC(kmalloc_size, GFP_KERNEL); + if (!path) + goto out; + + /* assume the negative dentry of unionfs as the parent dentry */ + parent_dentry = dentry; + + count = 0; + /* This loop finds the first parent that exists in the given branch. + * We start building the directory structure from there. At the end + * of the loop, the following should hold: + * child_dentry is the first nonexistent child + * parent_dentry is the first existent parent + * path[0] is the = deepest child + * path[count] is the first child to create + */ + do { + child_dentry = parent_dentry; + + /* find the parent directory dentry in unionfs */ + parent_dentry = child_dentry->d_parent; + lock_dentry(parent_dentry); + + /* find out the hidden_parent_dentry in the given branch */ + hidden_parent_dentry = dtohd_index(parent_dentry, bindex); + + /* store the child dentry */ + path[count++] = child_dentry; + if (count == num_dentry) { + old_kmalloc_size = kmalloc_size; + kmalloc_size *= 2; + num_dentry = kmalloc_size / sizeof(struct dentry *); + + tmp_path = + (struct dentry **)KZALLOC(kmalloc_size, GFP_KERNEL); + if (!tmp_path) { + hidden_dentry = ERR_PTR(-ENOMEM); + goto out; + } + memcpy(tmp_path, path, old_kmalloc_size); + KFREE(path); + path = tmp_path; + tmp_path = NULL; + } + + } while (!hidden_parent_dentry); + count--; + + sb = dentry->d_sb; +#ifdef UNIONFS_IMAP + persistent = stopd(sb)->usi_persistent; +#endif + /* This is basically while(child_dentry != dentry). This loop is + * horrible to follow and should be replaced with cleaner code. */ + while (1) { + // get hidden parent dir in the current branch + hidden_parent_dentry = dtohd_index(parent_dentry, bindex); + unlock_dentry(parent_dentry); + + // init the values to lookup + childname = child_dentry->d_name.name; + childnamelen = child_dentry->d_name.len; + + if (child_dentry != dentry) { + // lookup child in the underlying file system + hidden_dentry = + LOOKUP_ONE_LEN(childname, hidden_parent_dentry, + childnamelen); + if (IS_ERR(hidden_dentry)) + goto out; + } else { + int loop_start; + int loop_end; + int new_bstart = -1; + int new_bend = -1; + int i; + + /* is the name a whiteout of the childname ? */ + //lookup the whiteout child in the underlying file system + hidden_dentry = + LOOKUP_ONE_LEN(name, hidden_parent_dentry, + strlen(name)); + if (IS_ERR(hidden_dentry)) + goto out; + + /* Replace the current dentry (if any) with the new one. */ + DPUT(dtohd_index(dentry, bindex)); + set_dtohd_index(dentry, bindex, hidden_dentry); + + loop_start = + (old_bstart < bindex) ? old_bstart : bindex; + loop_end = (old_bend > bindex) ? old_bend : bindex; + + /* This loop sets the bstart and bend for the new + * dentry by traversing from left to right. + * It also dputs all negative dentries except + * bindex (the newly looked dentry + */ + for (i = loop_start; i <= loop_end; i++) { + if (!dtohd_index(dentry, i)) + continue; + + if (i == bindex) { + new_bend = i; + if (new_bstart < 0) + new_bstart = i; + continue; + } + + if (!dtohd_index(dentry, i)->d_inode) { + DPUT(dtohd_index(dentry, i)); + set_dtohd_index(dentry, i, NULL); + } else { + if (new_bstart < 0) + new_bstart = i; + new_bend = i; + } + } + + if (new_bstart < 0) + new_bstart = bindex; + if (new_bend < 0) + new_bend = bindex; + set_dbstart(dentry, new_bstart); + set_dbend(dentry, new_bend); + break; + } + + if (hidden_dentry->d_inode) { + /* since this already exists we dput to avoid + * multiple references on the same dentry */ + DPUT(hidden_dentry); + } else { + + /* its a negative dentry, create a new dir */ + hidden_parent_dentry = lock_parent(hidden_dentry); + args.mkdir.parent = hidden_parent_dentry->d_inode; + args.mkdir.dentry = hidden_dentry; + args.mkdir.mode = child_dentry->d_inode->i_mode; + run_sioq(__unionfs_mkdir, &args); + err = args.err; + if (!err) + err = copyup_permissions + (dir->i_sb, child_dentry, hidden_dentry); + unlock_dir(hidden_parent_dentry); + if (err) { + DPUT(hidden_dentry); + hidden_dentry = ERR_PTR(err); + goto out; + } +#ifdef UNIONFS_IMAP + if (persistent) { + err = write_uin + (sb, child_dentry->d_inode->i_ino, + bindex, hidden_dentry->d_inode->i_ino); + if (err) { + DPUT(hidden_dentry); + hidden_dentry = ERR_PTR(err); + goto out; + } + } +#endif + set_itohi_index(child_dentry->d_inode, bindex, + IGRAB(hidden_dentry->d_inode)); + if (ibstart(child_dentry->d_inode) > bindex) + ibstart(child_dentry->d_inode) = bindex; + if (ibend(child_dentry->d_inode) < bindex) + ibend(child_dentry->d_inode) = bindex; + + set_dtohd_index(child_dentry, bindex, hidden_dentry); + if (dbstart(child_dentry) > bindex) + set_dbstart(child_dentry, bindex); + if (dbend(child_dentry) < bindex) + set_dbend(child_dentry, bindex); + } + + parent_dentry = child_dentry; + child_dentry = path[--count]; + } + out: + KFREE(path); + print_dentry("OUT: create_parents_named", dentry); + print_exit_pointer(hidden_dentry); + return hidden_dentry; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/rename.c +++ linux-2.6.28/ubuntu/unionfs/rename.c @@ -0,0 +1,943 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: rename.c,v 1.47 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +static int do_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + int bindex, struct dentry **wh_old) +{ + int err = 0; + struct dentry *hidden_old_dentry; + struct dentry *hidden_new_dentry; + struct dentry *hidden_old_dir_dentry; + struct dentry *hidden_new_dir_dentry; + struct dentry *hidden_wh_dentry; + struct dentry *hidden_wh_dir_dentry; + char *wh_name = NULL; + + print_entry(" bindex=%d", bindex); + + print_dentry("IN: do_rename, old_dentry", old_dentry); + print_dentry("IN: do_rename, new_dentry", new_dentry); + dprint(PRINT_DEBUG, "do_rename for bindex = %d\n", bindex); + + hidden_new_dentry = dtohd_index(new_dentry, bindex); + hidden_old_dentry = dtohd_index(old_dentry, bindex); + + if (!hidden_new_dentry) { + hidden_new_dentry = + create_parents(new_dentry->d_parent->d_inode, new_dentry, + bindex); + if (IS_ERR(hidden_new_dentry)) { + dprint(PRINT_DEBUG, + "error creating directory tree for rename, bindex = %d\n", + bindex); + err = PTR_ERR(hidden_new_dentry); + goto out; + } + } + + wh_name = alloc_whname(new_dentry->d_name.name, new_dentry->d_name.len); + if (IS_ERR(wh_name)) { + err = PTR_ERR(wh_name); + goto out; + } + + hidden_wh_dentry = + LOOKUP_ONE_LEN(wh_name, hidden_new_dentry->d_parent, + new_dentry->d_name.len + WHLEN); + if (IS_ERR(hidden_wh_dentry)) { + err = PTR_ERR(hidden_wh_dentry); + goto out; + } + + if (hidden_wh_dentry->d_inode) { + /* get rid of the whiteout that is existing */ + if (hidden_new_dentry->d_inode) { + printk(KERN_WARNING + "Both a whiteout and a dentry exist when doing a rename!\n"); + err = -EIO; + + DPUT(hidden_wh_dentry); + goto out; + } + + hidden_wh_dir_dentry = lock_parent(hidden_wh_dentry); + if (!(err = is_robranch_super(old_dentry->d_sb, bindex))) { + err = + vfs_unlink(hidden_wh_dir_dentry->d_inode, + hidden_wh_dentry, NULL); + } + DPUT(hidden_wh_dentry); + unlock_dir(hidden_wh_dir_dentry); + if (err) + goto out; + } else + DPUT(hidden_wh_dentry); + + DGET(hidden_old_dentry); + hidden_old_dir_dentry = GET_PARENT(hidden_old_dentry); + hidden_new_dir_dentry = GET_PARENT(hidden_new_dentry); + + lock_rename(hidden_old_dir_dentry, hidden_new_dir_dentry); + + err = is_robranch_super(old_dentry->d_sb, bindex); + if (err) + goto out_unlock; + + /* ready to whiteout for old_dentry. + caller will create the actual whiteout, + and must dput(*wh_old) */ + if (wh_old) { + char *whname; + whname = alloc_whname(old_dentry->d_name.name, + old_dentry->d_name.len); + err = PTR_ERR(whname); + if (IS_ERR(whname)) + goto out_unlock; + *wh_old = LOOKUP_ONE_LEN(whname, hidden_old_dir_dentry, + old_dentry->d_name.len + WHLEN); + KFREE(whname); + err = PTR_ERR(*wh_old); + if (IS_ERR(*wh_old)) { + *wh_old = NULL; + goto out_unlock; + } + } + + print_dentry("NEWBEF", new_dentry); + print_dentry("OLDBEF", old_dentry); + err = vfs_rename(hidden_old_dir_dentry->d_inode, hidden_old_dentry, + NULL, hidden_new_dir_dentry->d_inode, + hidden_new_dentry, NULL); + print_dentry("NEWAFT", new_dentry); + print_dentry("OLDAFT", old_dentry); + + out_unlock: + unlock_rename(hidden_old_dir_dentry, hidden_new_dir_dentry); + + DPUT(hidden_old_dir_dentry); + DPUT(hidden_new_dir_dentry); + DPUT(hidden_old_dentry); + + out: + if (!err) { + /* Fixup the newdentry. */ + if (bindex < dbstart(new_dentry)) + set_dbstart(new_dentry, bindex); + else if (bindex > dbend(new_dentry)) + set_dbend(new_dentry, bindex); + } + + KFREE(wh_name); + + print_dentry("OUT: do_rename, old_dentry", old_dentry); + print_dentry("OUT: do_rename, new_dentry", new_dentry); + + print_exit_status(err); + return err; +} + +static int unionfs_rename_whiteout(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry) +{ + int err = 0; + int bindex, bwh_old; + int old_bstart, old_bend; + int new_bstart, new_bend; + int do_copyup = -1; + struct dentry *parent_dentry; + int local_err = 0; + int eio = 0; + int revert = 0; + struct dentry *wh_old = NULL; + + print_entry_location(); + + old_bstart = dbstart(old_dentry); + bwh_old = old_bstart; + old_bend = dbend(old_dentry); + parent_dentry = old_dentry->d_parent; + + new_bstart = dbstart(new_dentry); + new_bend = dbend(new_dentry); + + /* Rename source to destination. */ + err = do_rename(old_dir, old_dentry, new_dir, new_dentry, old_bstart, + &wh_old); + if (err) { + if (!IS_COPYUP_ERR(err)) { + goto out; + } + do_copyup = old_bstart - 1; + } else { + revert = 1; + } + + /* Unlink all instances of destination that exist to the left of + * bstart of source. On error, revert back, goto out. + */ + for (bindex = old_bstart - 1; bindex >= new_bstart; bindex--) { + struct dentry *unlink_dentry; + struct dentry *unlink_dir_dentry; + + unlink_dentry = dtohd_index(new_dentry, bindex); + if (!unlink_dentry) { + continue; + } + + unlink_dir_dentry = lock_parent(unlink_dentry); + if (!(err = is_robranch_super(old_dir->i_sb, bindex))) { + err = + vfs_unlink(unlink_dir_dentry->d_inode, + unlink_dentry, NULL); + } + + fist_copy_attr_times(new_dentry->d_parent->d_inode, + unlink_dir_dentry->d_inode); + /* propagate number of hard-links */ + new_dentry->d_parent->d_inode->i_nlink = + get_nlinks(new_dentry->d_parent->d_inode); + + unlock_dir(unlink_dir_dentry); + if (!err) { + if (bindex != new_bstart) { + DPUT(unlink_dentry); + set_dtohd_index(new_dentry, bindex, NULL); + } + } else if (IS_COPYUP_ERR(err)) { + do_copyup = bindex - 1; + } else if (revert) { + DPUT(wh_old); + goto revert; + } + } + + if (do_copyup != -1) { + for (bindex = do_copyup; bindex >= 0; bindex--) { + /* copyup the file into some left directory, so that you can rename it */ + err = + copyup_dentry(old_dentry->d_parent->d_inode, + old_dentry, old_bstart, bindex, NULL, + old_dentry->d_inode->i_size); + if (!err) { + DPUT(wh_old); + bwh_old = bindex; + err = + do_rename(old_dir, old_dentry, new_dir, + new_dentry, bindex, &wh_old); + break; + } + } + } + + /* make it opaque */ + if (S_ISDIR(old_dentry->d_inode->i_mode)) { + err = make_dir_opaque(old_dentry, dbstart(old_dentry)); + if (err) + goto revert; + } + + /* Create whiteout for source, only if: + * (1) There is more than one underlying instance of source. + * (2) We did a copy_up + */ + if ((old_bstart != old_bend) || (do_copyup != -1)) { + struct dentry *hidden_parent; + BUG_ON(!wh_old || IS_ERR(wh_old) || wh_old->d_inode + || bwh_old < 0); + hidden_parent = lock_parent(wh_old); + local_err = vfs_create(hidden_parent->d_inode, wh_old, S_IRUGO, + NULL); + unlock_dir(hidden_parent); + if (!local_err) + set_dbopaque(old_dentry, bwh_old); + else { + /* We can't fix anything now, so we cop-out and use -EIO. */ + printk + ("<0>We can't create a whiteout for the source in rename!\n"); + err = -EIO; + } + } + + out: + DPUT(wh_old); + print_exit_status(err); + return err; + + revert: + /* Do revert here. */ + local_err = unionfs_refresh_hidden_dentry(new_dentry, old_bstart); + if (local_err) { + printk(KERN_WARNING + "Revert failed in rename: the new refresh failed.\n"); + eio = -EIO; + } + + local_err = unionfs_refresh_hidden_dentry(old_dentry, old_bstart); + if (local_err) { + printk(KERN_WARNING + "Revert failed in rename: the old refresh failed.\n"); + eio = -EIO; + goto revert_out; + } + + if (!dtohd_index(new_dentry, bindex) + || !dtohd_index(new_dentry, bindex)->d_inode) { + printk(KERN_WARNING + "Revert failed in rename: the object disappeared from under us!\n"); + eio = -EIO; + goto revert_out; + } + + if (dtohd_index(old_dentry, bindex) + && dtohd_index(old_dentry, bindex)->d_inode) { + printk(KERN_WARNING + "Revert failed in rename: the object was created underneath us!\n"); + eio = -EIO; + goto revert_out; + } + + local_err = + do_rename(new_dir, new_dentry, old_dir, old_dentry, old_bstart, + NULL); + + /* If we can't fix it, then we cop-out with -EIO. */ + if (local_err) { + printk(KERN_WARNING "Revert failed in rename!\n"); + eio = -EIO; + } + + local_err = unionfs_refresh_hidden_dentry(new_dentry, bindex); + if (local_err) + eio = -EIO; + local_err = unionfs_refresh_hidden_dentry(old_dentry, bindex); + if (local_err) + eio = -EIO; + + revert_out: + if (eio) + err = eio; + print_exit_status(err); + return err; +} + +/* + * Unfortunately, we cannot simply call things like dbstart() in different + * places of the rename code because we move things around. So, we use this + * structure to pass the necessary information around to all the places that + * need it. + */ +struct rename_info { + int do_copyup; + int do_whiteout; + int rename_ok; + + int old_bstart; + int old_bend; + int new_bstart; + int new_bend; + + int isdir; /* Is the source a directory? */ + int clobber; /* Are we clobbering the destination? */ + + int bwh_old; /* where we create the whiteout */ + struct dentry *wh_old; /* lookup and set by do_rename() */ +}; +#ifdef UNIONFS_DELETE_ALL +/* + * Rename all occurences of source except for the leftmost destination + */ +static int __rename_all(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + fd_set * success_mask, struct rename_info *info) +{ + int bindex; + int err = 0; + + print_entry_location(); + + /* Loop through all the branches from right to left and rename all + * instances of source to destination, except the leftmost destination + */ + for (bindex = info->old_bend; bindex >= info->old_bstart; bindex--) { + /* We don't rename if there is no source. */ + if (dtohd_index(old_dentry, bindex) == NULL) + continue; + + /* we rename the bstart of destination only at the last of + * all operations, so that we don't lose it on error + */ + if (info->clobber && (bindex == info->new_bstart)) + continue; + + DPUT(info->wh_old); + info->bwh_old = bindex; + /* We shouldn't have a handle on this if there is no inode. */ + err = + do_rename(old_dir, old_dentry, new_dir, new_dentry, bindex, + &info->wh_old); + if (!err) { + /* For reverting. */ + FD_SET(bindex, success_mask); + /* So we know not to copyup on failures the right */ + info->rename_ok = bindex; + } else if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + break; + } + + /* we need a whiteout... */ + info->do_whiteout = bindex - 1; + + if (bindex == info->old_bstart) + /* ...and a copyup */ + info->do_copyup = bindex - 1; + + err = 0; /* reset error */ + } else + break; /* error is set by do_rename */ + } + + print_exit_status(err); + return err; +} + +/* + * Unlink all destinations (if they exist) to the left of the left-most + * source + */ +static int __rename_all_unlink(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + struct rename_info *info) +{ + int bindex; + + struct dentry *unlink_dentry; + struct dentry *unlink_dir_dentry; + + int err = 0; + + print_entry_location(); + + for (bindex = info->old_bstart - 1; bindex > info->new_bstart; bindex--) { + unlink_dentry = dtohd_index(new_dentry, bindex); + if (!unlink_dentry) + continue; + + /* lock, unlink if possible, copyup times, unlock */ + unlink_dir_dentry = lock_parent(unlink_dentry); + if (!(err = is_robranch_super(old_dir->i_sb, bindex))) + err = + vfs_unlink(unlink_dir_dentry->d_inode, + unlink_dentry, NULL); + + fist_copy_attr_times(new_dentry->d_parent->d_inode, + unlink_dir_dentry->d_inode); + new_dentry->d_parent->d_inode->i_nlink = + get_nlinks(new_dentry->d_parent->d_inode); + + unlock_dir(unlink_dir_dentry); + + if (!err) { + if (bindex != info->new_bstart) { + DPUT(unlink_dentry); + set_dtohd_index(new_dentry, bindex, NULL); + } + } else if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + break; + } + info->do_copyup = bindex - 1; + + err = 0; /* reset error */ + } else + break; /* err is set by is_ro_branch_super or vfs_unlink */ + } + + print_exit_status(err); + return err; +} + +/* + * Try to revert everything we have done in __rename_all and __rename_all_unlink + */ +static int __rename_all_revert(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + fd_set * success_mask, struct rename_info *info) +{ + int bindex; + + int err; + int eio = 0; + + print_entry_location(); + + for (bindex = info->old_bstart; bindex <= info->old_bend; bindex++) { + if (!FD_ISSET(bindex, success_mask)) + continue; + + err = unionfs_refresh_hidden_dentry(new_dentry, bindex); + if (err) { + printk(KERN_WARNING "Revert failed in rename: " + "the new refresh failed.\n"); + eio = -EIO; + } + + err = unionfs_refresh_hidden_dentry(old_dentry, bindex); + if (err) { + printk(KERN_WARNING "Revert failed in rename: " + "the old refresh failed.\n"); + eio = -EIO; + continue; + } + + if (!dtohd_index(new_dentry, bindex) + || !dtohd_index(new_dentry, bindex)->d_inode) { + printk(KERN_WARNING "Revert failed in rename: " + "the object disappeared from under us!\n"); + eio = -EIO; + continue; + } + + if (dtohd_index(old_dentry, bindex) + && dtohd_index(old_dentry, bindex)->d_inode) { + printk(KERN_WARNING "Revert failed in rename: " + "the object was created underneath us!\n"); + eio = -EIO; + continue; + } + + err = + do_rename(new_dir, new_dentry, old_dir, old_dentry, bindex, + NULL); + /* If we can't fix it, then we cop-out with -EIO. */ + if (err) { + printk(KERN_WARNING "Revert failed in rename!\n"); + eio = -EIO; + } + + err = unionfs_refresh_hidden_dentry(new_dentry, bindex); + if (err) + eio = -EIO; + err = unionfs_refresh_hidden_dentry(old_dentry, bindex); + if (err) + eio = -EIO; + } + + print_exit_status(eio); + return eio; +} + +/* + * Finish off the rename, by either over writing the last destination or + * unlinking the last destination to the left of us + */ +static int __rename_all_clobber(struct inode *old_dir, + struct dentry *old_dentry, + struct inode *new_dir, + struct dentry *new_dentry, + struct rename_info *info) +{ + int err = 0; + + print_entry_location(); + + if (dtohd_index(old_dentry, info->new_bstart)) { + /* rename the last source, knowing we're overwriting something */ + DPUT(info->wh_old); + info->bwh_old = info->new_bstart; + err = + do_rename(old_dir, old_dentry, new_dir, new_dentry, + info->new_bstart, &info->wh_old); + if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + goto out; + } + if (info->rename_ok > info->new_bstart) { + if ((info->do_copyup == -1) + || (info->new_bstart - 1 < info->do_copyup)) + info->do_copyup = info->new_bstart - 1; + } + if ((info->do_whiteout == -1) + || (info->new_bstart - 1 < info->do_whiteout)) { + info->do_whiteout = info->new_bstart - 1; + } + err = 0; // reset error + } + } else if (info->new_bstart < info->old_bstart) { + /* the newly renamed file would get hidden, let's unlink the + * file to the left of it */ + struct dentry *unlink_dentry; + struct dentry *unlink_dir_dentry; + + unlink_dentry = dtohd_index(new_dentry, info->new_bstart); + + unlink_dir_dentry = lock_parent(unlink_dentry); + if (!(err = is_robranch_super(old_dir->i_sb, info->new_bstart))) + err = vfs_unlink(unlink_dir_dentry->d_inode, + unlink_dentry, NULL); + + fist_copy_attr_times(new_dentry->d_parent->d_inode, + unlink_dir_dentry->d_inode); + new_dentry->d_parent->d_inode->i_nlink = + get_nlinks(new_dentry->d_parent->d_inode); + + unlock_dir(unlink_dir_dentry); + + if (IS_COPYUP_ERR(err)) { + if (info->isdir) { + err = -EXDEV; + goto out; + } + if ((info->do_copyup == -1) + || (info->new_bstart - 1 < info->do_copyup)) + info->do_copyup = info->new_bstart - 1; + + err = 0; // reset error + } + } + + out: + print_exit_status(err); + return err; +} + +/* + * The function is nasty, nasty, nasty, but so is rename. :( + */ +static int unionfs_rename_all(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + struct dentry *parent_dentry = NULL; + int err = 0; + int eio; + + /* These variables control error handling. */ + fd_set success_mask; + char *name = NULL; + + /* unfortunately, we have to resort to this, because dbstart/dbend would + return different things in different place of the rename code */ + struct rename_info info; + + info.rename_ok = FD_SETSIZE; /* The last rename that is ok. */ + info.do_copyup = -1; /* Where we should start copyup. */ + info.do_whiteout = -1; /* Where we should start whiteouts of the source. */ + info.wh_old = NULL; + info.bwh_old = -1; + + print_entry_location(); + + parent_dentry = old_dentry->d_parent; + name = KMALLOC(old_dentry->d_name.len + 1, GFP_KERNEL); + if (!name) { + err = -ENOMEM; + goto out; + } + strncpy(name, old_dentry->d_name.name, old_dentry->d_name.len + 1); + + info.new_bstart = dbstart(new_dentry); + info.new_bend = dbend(new_dentry); + + info.old_bstart = dbstart(old_dentry); + info.old_bend = dbend(old_dentry); + + BUG_ON(info.new_bstart < 0); + BUG_ON(info.old_bstart < 0); + + /* The failure mask only can deal with FD_SETSIZE entries. */ + BUG_ON(info.old_bend > FD_SETSIZE); + BUG_ON(info.new_bend > FD_SETSIZE); + FD_ZERO(&success_mask); + + /* Life is simpler if the dentry doesn't exist. */ + info.clobber = + (dtohd_index(new_dentry, info.new_bstart)->d_inode) ? 1 : 0; + info.isdir = S_ISDIR(old_dentry->d_inode->i_mode); + + /* rename everything we can */ + err = + __rename_all(old_dir, old_dentry, new_dir, new_dentry, + &success_mask, &info); + if (err) + goto revert; + + /* unlink destinations even further left */ + err = + __rename_all_unlink(old_dir, old_dentry, new_dir, new_dentry, + &info); + if (err) + goto revert; + + if (info.clobber) { + /* Now we need to handle the leftmost of the destination. */ + err = + __rename_all_clobber(old_dir, old_dentry, new_dir, + new_dentry, &info); + if (err) + goto revert; + } + + /* Copy up if necessary */ + if (info.do_copyup != -1) { + int bindex; + + for (bindex = info.do_copyup; bindex >= 0; bindex--) { + err = + copyup_dentry(old_dentry->d_parent->d_inode, + old_dentry, info.old_bstart, bindex, + NULL, old_dentry->d_inode->i_size); + if (!err) { + DPUT(info.wh_old); + info.bwh_old = bindex; + err = + do_rename(old_dir, old_dentry, new_dir, + new_dentry, bindex, &info.wh_old); + break; + } + } + } + + /* make it opaque */ + if (S_ISDIR(old_dentry->d_inode->i_mode)) { + err = make_dir_opaque(old_dentry, dbstart(old_dentry)); + if (err) + goto revert; + } + + /* Create a whiteout for the source. */ + if (info.do_whiteout != -1) { + struct dentry *hidden_parent; + BUG_ON(info.do_whiteout < 0 + || !info.wh_old || IS_ERR(info.wh_old) + || info.wh_old->d_inode || info.bwh_old < 0); + hidden_parent = lock_parent(info.wh_old); + err = vfs_create(hidden_parent->d_inode, info.wh_old, S_IRUGO, + NULL); + unlock_dir(hidden_parent); + if (!err) + set_dbopaque(old_dentry, info.bwh_old); + else { + /* We can't fix anything now, so we -EIO. */ + printk(KERN_WARNING "We can't create a whiteout for the" + "source in rename!\n"); + err = -EIO; + goto out; + } + } + + /* We are at the point where reverting doesn't happen. */ + goto out; + + revert: + /* something bad happened, try to revert */ + eio = + __rename_all_revert(old_dir, old_dentry, new_dir, new_dentry, + &success_mask, &info); + if (eio) + err = eio; + + out: + DPUT(info.wh_old); + KFREE(name); + print_exit_status(err); + return err; +} +#endif + +static struct dentry *lookup_whiteout(struct dentry *dentry) +{ + char *whname; + int bindex = -1, bstart = -1, bend = -1; + struct dentry *parent, *hidden_parent, *wh_dentry; + + whname = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(whname)) + return (void *)whname; + + parent = GET_PARENT(dentry); + lock_dentry(parent); + bstart = dbstart(parent); + bend = dbend(parent); + wh_dentry = ERR_PTR(-ENOENT); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_parent = dtohd_index(parent, bindex); + if (!hidden_parent) + continue; + wh_dentry = + LOOKUP_ONE_LEN(whname, hidden_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(wh_dentry)) + continue; + if (wh_dentry->d_inode) + break; + DPUT(wh_dentry); + wh_dentry = ERR_PTR(-ENOENT); + } + unlock_dentry(parent); + DPUT(parent); + KFREE(whname); + return wh_dentry; +} + +/* We can't copyup a directory, because it may involve huge + * numbers of children, etc. Doing that in the kernel would + * be bad, so instead we let the userspace recurse and ask us + * to copy up each file separately + */ +static int may_rename_dir(struct dentry *dentry) +{ + int err, bstart; + + err = check_empty(dentry, NULL); + if (err == -ENOTEMPTY) { + if (is_robranch(dentry)) + return -EXDEV; + } else if (err) + return err; + + bstart = dbstart(dentry); + if (dbend(dentry) == bstart || dbopaque(dentry) == bstart) + return 0; + + set_dbstart(dentry, bstart + 1); + err = check_empty(dentry, NULL); + set_dbstart(dentry, bstart); + if (err == -ENOTEMPTY) + err = -EXDEV; + return err; +} + +int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + int err = 0; + struct dentry *wh_dentry; + + print_entry_location(); + + double_lock_dentry(old_dentry, new_dentry); + + checkinode(old_dir, "unionfs_rename-old_dir"); + checkinode(new_dir, "unionfs_rename-new_dir"); + print_dentry("IN: unionfs_rename, old_dentry", old_dentry); + print_dentry("IN: unionfs_rename, new_dentry", new_dentry); + + if (!S_ISDIR(old_dentry->d_inode->i_mode)) + err = unionfs_partial_lookup(old_dentry); + else + err = may_rename_dir(old_dentry); + + if (err) + goto out; + + err = unionfs_partial_lookup(new_dentry); + if (err) + goto out; + + /* + * if new_dentry is already hidden because of whiteout, + * simply override it even if the whiteouted dir is not empty. + */ + wh_dentry = lookup_whiteout(new_dentry); + if (!IS_ERR(wh_dentry)) + DPUT(wh_dentry); + else if (new_dentry->d_inode) { + if (S_ISDIR(old_dentry->d_inode->i_mode) != + S_ISDIR(new_dentry->d_inode->i_mode)) { + err = + S_ISDIR(old_dentry->d_inode-> + i_mode) ? -ENOTDIR : -EISDIR; + goto out; + } + + if (S_ISDIR(new_dentry->d_inode->i_mode)) { + struct unionfs_dir_state *namelist; + /* check if this unionfs directory is empty or not */ + err = check_empty(new_dentry, &namelist); + if (err) + goto out; + + if (!is_robranch(new_dentry)) + err = delete_whiteouts(new_dentry, + dbstart(new_dentry), + namelist); + + free_rdstate(namelist); + + if (err) + goto out; + } + } +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(old_dir->i_sb, DELETE_ALL)) + err = unionfs_rename_all(old_dir, old_dentry, new_dir, + new_dentry); + else +#endif + err = unionfs_rename_whiteout(old_dir, old_dentry, new_dir, + new_dentry); + + out: + checkinode(new_dir, "post unionfs_rename-new_dir"); + print_dentry("OUT: unionfs_rename, old_dentry", old_dentry); + + if (err) { + /* clear the new_dentry stuff created */ + d_drop(new_dentry); + } else { + /* force re-lookup since the dir on ro branch is not renamed, + and hidden dentries still indicate the un-renamed ones. */ + if (S_ISDIR(old_dentry->d_inode->i_mode)) + atomic_dec(&dtopd(old_dentry)->udi_generation); + print_dentry("OUT: unionfs_rename, new_dentry", + new_dentry); + } + + unlock_dentry(new_dentry); + unlock_dentry(old_dentry); + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/unionfs_debug.h +++ linux-2.6.28/ubuntu/unionfs/unionfs_debug.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unionfs_debug.h,v 1.3 2006/06/01 21:25:18 jsipek Exp $ + */ + +#ifndef __UNIONFS_H_ +#error This file should only be included from unionfs.h! +#endif + +#ifdef UNIONFS_DEBUG +#define DEFAULT_DEBUG_MASK 0 +#else +#define DEFAULT_DEBUG_MASK (~0) +#endif + +/* debug print levels */ +#define PRINT_NONE 0x0000 +#define PRINT_MAIN_ENTRY 0x0001 +#define PRINT_MAIN_EXIT 0x0002 +#define PRINT_UTILITY_ENTRY 0x0004 +#define PRINT_UTILITY_EXIT 0x0008 +#define PRINT_MISC_ENTRY 0x0010 +#define PRINT_MISC_EXIT 0x0020 +#define PRINT_DATA_DENTRY 0x0040 +#define PRINT_DATA_FILE 0x0080 +#define PRINT_DATA_INODE 0x0100 +#define PRINT_DATA_SB 0x0200 +#define PRINT_DEBUG 0x0400 +#define __PRINT_DEBUG_XATTR 0x0800 +#define PRINT_DEBUG_XATTR (PRINT_DEBUG | __PRINT_DEBUG_XATTR) +#define __PRINT_DEBUG_WHITEOUT 0x1000 +#define PRINT_DEBUG_WHITEOUT (PRINT_DEBUG | __PRINT_DEBUG_WHITEOUT) + +#define PRINT_MAX (0x2000 - 1) +#define PRINT_ALL (~PRINT_NONE) + +extern unsigned int get_debug_mask(void); +extern int set_debug_mask(int val); + +/* print inode */ +extern void unionfs_print_inode(const unsigned int req, const char *prefix, const struct inode *inode); + +/* check inode */ +extern void unionfs_checkinode(const unsigned int req, const struct inode *inode, const char *msg); + +/* prunt file */ +extern void unionfs_print_file(const unsigned int req, const char *prefix, const struct file *file); + +/* print dentry */ +extern void unionfs_print_dentry(const unsigned int req, const char *prefix, const struct dentry *dentry); + +extern void unionfs_print_dentry_nocheck(const unsigned int req, const char *prefix, const struct dentry *dentry); + +/* print superblock */ +extern void unionfs_print_sb(const unsigned int req, const char *prefix, const struct super_block *sb); + +/* print message */ +extern int unionfs_print(const unsigned int req, const char *fmt, ...); + +/* forced print-debugging functions */ +#define force_print_dentry(prefix, ptr) \ + unionfs_print_dentry(PRINT_ALL, (prefix), (ptr)) +#define force_print_dentry_nocheck(prefix, ptr) \ + unionfs_print_dentry_nocheck(PRINT_ALL, (prefix), (ptr)) +#define force_print_file(prefix, ptr) \ + unionfs_print_file(PRINT_ALL, (prefix), (ptr)) +#define force_print_inode(prefix, ptr) \ + unionfs_print_inode(PRINT_ALL, (prefix), (ptr)) +#define force_print_sb(prefix, ptr) \ + unionfs_print_sb(PRINT_ALL, (prefix), (ptr)) + +#ifdef UNIONFS_DEBUG +/* + * Full-fledged debugging enabled + */ + +#define print_dentry(prefix, ptr) \ + unionfs_print_dentry(PRINT_DATA_DENTRY, (prefix), (ptr)) +#define print_dentry_nocheck(prefix, ptr) \ + unionfs_print_dentry_nocheck(PRINT_DATA_DENTRY, (prefix), (ptr)) +#define print_file(prefix, ptr) \ + unionfs_print_file(PRINT_DATA_FILE, (prefix), (ptr)) +#define print_inode(prefix, ptr) \ + unionfs_print_inode(PRINT_DATA_INODE, (prefix), (ptr)) +#define print_sb(prefix, ptr) \ + unionfs_print_sb(PRINT_DATA_SB, (prefix), (ptr)) +#define dprint(req, fmt, args...) \ + unionfs_print(req, fmt, ## args) + +#define checkinode(ptr, msg) \ + unionfs_checkinode(PRINT_DEBUG, (ptr), (msg)) + +#define __print_entryexit(req, ee, fmt, args...) \ + unionfs_print((req), \ + ee " %s %s:%d" fmt "\n", \ + __FUNCTION__, \ + __FILE__, \ + __LINE__, \ + ##args) + +#define print_entry(fmt, args...) \ + __print_entryexit(PRINT_MAIN_ENTRY, \ + "IN: ", " " fmt, ##args) + +#define print_entry_location() \ + __print_entryexit(PRINT_MAIN_ENTRY, \ + "IN: ", "") + +#define print_exit_location() \ + __print_entryexit(PRINT_MAIN_EXIT, \ + "OUT:", "") + +#define print_exit_status(status) \ + __print_entryexit(PRINT_MAIN_EXIT, \ + "OUT:", ", STATUS: %d", status) + +static inline void __print_exit_pointer(unsigned int req, void *status) +{ + if (IS_ERR(status)) + __print_entryexit(req, "OUT:", ", STATUS: %ld", + PTR_ERR(status)); + else + __print_entryexit(req, "OUT:", ", STATUS: 0x%p", + status); +} +#define print_exit_pointer(status) \ + __print_exit_pointer(PRINT_MAIN_EXIT, status) + +#define print_util_entry(fmt, args...) \ + __print_entryexit(PRINT_UTILITY_ENTRY, \ + "IN: ", " " fmt, ##args) + +#define print_util_entry_location() \ + __print_entryexit(PRINT_UTILITY_ENTRY, \ + "IN: ", "") + +#define print_util_exit_location() \ + __print_entryexit(PRINT_UTILITY_EXIT, \ + "OUT:", "") + +#define print_util_exit_status(status) \ + __print_entryexit(PRINT_UTILITY_EXIT, \ + "OUT:", ", STATUS: %d", status) + +#define print_util_exit_pointer(status) \ + __print_exit_pointer(PRINT_UTILITY_EXIT, status) + +#else /* UNIONFS_DEBUG */ +/* + * Full-fledged debugging disabled + */ + +#define print_dentry(prefix, ptr) +#define print_dentry_nocheck(prefix, ptr) +#define print_file(prefix, ptr) +#define print_inode(prefix, ptr) +#define print_sb(prefix, ptr) +#define dprint(req, fmt, args...) + +#define checkinode(ptr, msg) + +#define print_entry(args...) +#define print_entry_location() +#define print_exit_location() +#define print_exit_status(status) +#define print_exit_pointer(status) +#define print_util_entry(args...) +#define print_util_entry_location() +#define print_util_exit_location() +#define print_util_exit_status(status) +#define print_util_exit_pointer(status) + +#endif /* ! UNIONFS_DEBUG */ + + --- linux-2.6.28.orig/ubuntu/unionfs/dirhelper.c +++ linux-2.6.28/ubuntu/unionfs/dirhelper.c @@ -0,0 +1,309 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: dirhelper.c,v 1.32 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +/* Delete all of the whiteouts in a given directory for rmdir. */ +int do_delete_whiteouts(struct dentry *dentry, int bindex, + struct unionfs_dir_state *namelist) +{ + int err = 0; + struct dentry *hidden_dir_dentry = NULL; + struct dentry *hidden_dentry; + char *name = NULL, *p; + struct inode *hidden_dir; + + int i; + struct list_head *pos; + struct filldir_node *cursor; + + /* Find out hidden parent dentry */ + hidden_dir_dentry = dtohd_index(dentry, bindex); + BUG_ON(!S_ISDIR(hidden_dir_dentry->d_inode->i_mode)); + hidden_dir = hidden_dir_dentry->d_inode; + BUG_ON(!S_ISDIR(hidden_dir->i_mode)); + + err = -ENOMEM; + name = __getname(); + if (!name) + goto out; + strcpy(name, WHPFX); + p = name + WHLEN; + + err = 0; + for (i = 0; !err && i < namelist->uds_size; i++) { + list_for_each(pos, &namelist->uds_list[i]) { + cursor = + list_entry(pos, struct filldir_node, file_list); + /* Only operate on whiteouts in this branch. */ + if (cursor->bindex != bindex) + continue; + if (!cursor->whiteout) + continue; + + strcpy(p, cursor->name); + hidden_dentry = + lookup_one_len(name, hidden_dir_dentry, + cursor->namelen + WHLEN); + if (IS_ERR(hidden_dentry)) { + err = PTR_ERR(hidden_dentry); + break; + } + if (hidden_dentry->d_inode) + err = vfs_unlink(hidden_dir, hidden_dentry, + NULL); + dput(hidden_dentry); + if (err) + break; + } + } + + __putname(name); + + /* After all of the removals, we should copy the attributes once. */ + fist_copy_attr_times(dentry->d_inode, hidden_dir_dentry->d_inode); + +out: + return err; +} + +/* Delete all of the whiteouts in a given directory for rmdir. */ +int delete_whiteouts(struct dentry *dentry, int bindex, + struct unionfs_dir_state *namelist) +{ + int err = 0; + struct dentry *hidden_dir_dentry = NULL; + struct super_block *sb; + char *name = NULL, *p; + struct inode *hidden_dir; + + struct sioq_args args; + + print_entry_location(); + + sb = dentry->d_sb; + unionfs_read_lock(sb); + + BUG_ON(!S_ISDIR(dentry->d_inode->i_mode)); + BUG_ON(bindex < dbstart(dentry)); + BUG_ON(bindex > dbend(dentry)); + err = is_robranch_super(sb, bindex); + if (err) + goto out; + + /* Find out hidden parent dentry */ + hidden_dir_dentry = dtohd_index(dentry, bindex); + BUG_ON(!S_ISDIR(hidden_dir_dentry->d_inode->i_mode)); + hidden_dir = hidden_dir_dentry->d_inode; + BUG_ON(!S_ISDIR(hidden_dir->i_mode)); + + err = -ENOMEM; + name = __getname(); + if (!name) + goto out; + strcpy(name, WHPFX); + p = name + WHLEN; + + err = 0; + mutex_lock(&hidden_dir->i_mutex); + + if (!inode_permission(hidden_dir, MAY_WRITE | MAY_EXEC)) + err = do_delete_whiteouts(dentry, bindex, namelist); + else { + args.deletewh.namelist = namelist; + args.deletewh.dentry = dentry; + args.deletewh.bindex = bindex; + run_sioq(__delete_whiteouts, &args); + err = args.err; + } + + mutex_unlock(&hidden_dir->i_mutex); + + out: + unionfs_read_unlock(sb); + print_exit_status(err); + return err; +} + +#define RD_NONE 0 +#define RD_CHECK_EMPTY 1 +/* The callback structure for check_empty. */ +struct unionfs_rdutil_callback { + int err; + int filldir_called; + struct unionfs_dir_state *rdstate; + int mode; +}; + +/* This filldir function makes sure only whiteouts exist within a directory. */ +static int readdir_util_callback(void *dirent, const char *name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + int err = 0; + struct unionfs_rdutil_callback *buf = + (struct unionfs_rdutil_callback *)dirent; + int whiteout = 0; + struct filldir_node *found; + + print_entry_location(); + + buf->filldir_called = 1; + + if (name[0] == '.' + && (namelen == 1 || (name[1] == '.' && namelen == 2))) + goto out; + + if ((namelen > WHLEN) && !strncmp(name, WHPFX, WHLEN)) { + namelen -= WHLEN; + name += WHLEN; + whiteout = 1; + } + + found = find_filldir_node(buf->rdstate, name, namelen); + /* If it was found in the table there was a previous whiteout. */ + if (found) + goto out; + + /* If it wasn't found and isn't a whiteout, the directory isn't empty. */ + err = -ENOTEMPTY; + if ((buf->mode == RD_CHECK_EMPTY) && !whiteout) + goto out; + + err = add_filldir_node(buf->rdstate, name, namelen, + buf->rdstate->uds_bindex, whiteout); + + out: + buf->err = err; + print_exit_status(err); + return err; +} + +/* Is a directory logically empty? */ +int check_empty(struct dentry *dentry, struct unionfs_dir_state **namelist) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct super_block *sb; + struct file *hidden_file; + struct unionfs_rdutil_callback *buf = NULL; + int bindex, bstart, bend, bopaque; + + print_entry_location(); + + sb = dentry->d_sb; + + unionfs_read_lock(sb); + + BUG_ON(!S_ISDIR(dentry->d_inode->i_mode)); + + if ((err = unionfs_partial_lookup(dentry))) + goto out; + + bstart = dbstart(dentry); + bend = dbend(dentry); + bopaque = dbopaque(dentry); + if (0 <= bopaque && bopaque < bend) + bend = bopaque; + + buf = KMALLOC(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto out; + } + buf->err = 0; + buf->mode = RD_CHECK_EMPTY; + buf->rdstate = alloc_rdstate(dentry->d_inode, bstart); + if (!buf->rdstate) { + err = -ENOMEM; + goto out; + } + + /* Process the hidden directories with rdutil_callback as a filldir. */ + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + if (!hidden_dentry->d_inode) + continue; + if (!S_ISDIR(hidden_dentry->d_inode->i_mode)) + continue; + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(sb, bindex)); + branchget(sb, bindex); + hidden_file = + DENTRY_OPEN(hidden_dentry, stohiddenmnt_index(sb, bindex), + O_RDONLY); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + DPUT(hidden_dentry); + branchput(sb, bindex); + goto out; + } + + do { + buf->filldir_called = 0; + buf->rdstate->uds_bindex = bindex; + err = vfs_readdir(hidden_file, + readdir_util_callback, buf); + if (buf->err) + err = buf->err; + } while ((err >= 0) && buf->filldir_called); + + /* fput calls dput for hidden_dentry */ + fput(hidden_file); + branchput(sb, bindex); + + if (err < 0) + goto out; + } + + out: + if (buf) { + if (namelist && !err) + *namelist = buf->rdstate; + else if (buf->rdstate) + free_rdstate(buf->rdstate); + KFREE(buf); + } + + unionfs_read_unlock(sb); + + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/branchman.c +++ linux-2.6.28/ubuntu/unionfs/branchman.c @@ -0,0 +1,579 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: branchman.c,v 1.66 2006/10/31 00:05:22 yiannos Exp $ + */ + +#include "unionfs.h" + +struct dentry **alloc_new_dentries(int objs) +{ + if (!objs) + return NULL; + + return KZALLOC(sizeof(struct dentry *) * objs, GFP_KERNEL); +} + +struct unionfs_usi_data *alloc_new_data(int objs) +{ + if (!objs) + return NULL; + + return KZALLOC(sizeof(struct unionfs_usi_data) * objs, GFP_KERNEL); +} + +static void fixputmaps(struct super_block *sb) +{ + struct unionfs_sb_info *spd; + struct putmap *cur; + int gen; + int i; + + print_entry_location(); + + spd = stopd(sb); + cur = spd->usi_putmaps[spd->usi_lastputmap - spd->usi_firstputmap]; + + for (gen = 0; gen < spd->usi_lastputmap - spd->usi_firstputmap; gen++) { + if (!spd->usi_putmaps[gen]) + continue; + for (i = 0; i <= spd->usi_putmaps[gen]->bend; i++) + spd->usi_putmaps[gen]->map[i] = + cur->map[spd->usi_putmaps[gen]->map[i]]; + } + + print_exit_location(); +} + +static int newputmap(struct super_block *sb) +{ + struct unionfs_sb_info *spd; + struct putmap *newmap; + int count = 0; + int i; + + print_entry_location(); + + spd = stopd(sb); + + i = sizeof(int) * (sbend(sb) + 1); + newmap = KMALLOC(sizeof(struct putmap) + i, GFP_KERNEL); + if (!newmap) { + print_exit_status(-ENOMEM); + return -ENOMEM; + } + + if (!spd->usi_firstputmap) { + spd->usi_firstputmap = 1; + spd->usi_lastputmap = 1; + + spd->usi_putmaps = KMALLOC(sizeof(struct putmap *), GFP_KERNEL); + if (!spd->usi_putmaps) { + KFREE(newmap); + print_exit_status(-ENOMEM); + return -ENOMEM; + } + } else { + struct putmap **newlist; + int newfirst = spd->usi_firstputmap; + + while (!spd->usi_putmaps[newfirst - spd->usi_firstputmap] && + newfirst <= spd->usi_lastputmap) { + newfirst++; + } + + newlist = + KMALLOC(sizeof(struct putmap *) * + (1 + spd->usi_lastputmap - newfirst), GFP_KERNEL); + if (!newlist) { + KFREE(newmap); + print_exit_status(-ENOMEM); + return -ENOMEM; + } + + for (i = newfirst; i <= spd->usi_lastputmap; i++) { + newlist[i - newfirst] = + spd->usi_putmaps[i - spd->usi_firstputmap]; + } + + KFREE(spd->usi_putmaps); + spd->usi_putmaps = newlist; + spd->usi_firstputmap = newfirst; + spd->usi_lastputmap++; + } + + newmap->bend = sbend(sb); + for (i = 0; i <= sbend(sb); i++) { + count += branch_count(sb, i); + newmap->map[i] = i; + } + for (i = spd->usi_firstputmap; i < spd->usi_lastputmap; i++) { + struct putmap *cur; + cur = spd->usi_putmaps[i - spd->usi_firstputmap]; + if (!cur) + continue; + count -= atomic_read(&cur->count); + } + atomic_set(&newmap->count, count); + spd->usi_putmaps[spd->usi_lastputmap - spd->usi_firstputmap] = newmap; + + print_exit_status(0); + return 0; +} + +/* XXX: this function needs to go. There is no reason for this to be here */ +int unionfs_ioctl_branchcount(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int err = 0; + int bstart, bend; + int i; + struct super_block *sb = file->f_dentry->d_sb; + + print_entry_location(); + + bstart = sbstart(sb); + bend = sbend(sb); + + err = bend + 1; + if (!arg) + goto out; + + for (i = bstart; i <= bend; i++) { + if (put_user(branch_count(sb, i), ((int __user *)arg) + i)) { + err = -EFAULT; + goto out; + } + } + + out: + print_exit_status(err); + return err; +} + +int unionfs_ioctl_incgen(struct file *file, unsigned int cmd, unsigned long arg) +{ + int err = 0; + struct super_block *sb; + + print_entry_location(); + + sb = file->f_dentry->d_sb; + + unionfs_write_lock(sb); + if ((err = newputmap(sb))) + goto out; + + atomic_inc(&stopd(sb)->usi_generation); + err = atomic_read(&stopd(sb)->usi_generation); + + atomic_set(&dtopd(sb->s_root)->udi_generation, err); + atomic_set(&itopd(sb->s_root->d_inode)->uii_generation, err); + + out: + unionfs_write_unlock(sb); + print_exit_status(err); + return err; +} + +int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd, + unsigned long arg) +{ + int err; + struct unionfs_addbranch_args *addargs = NULL; + struct nameidata nd; + char *path = NULL; + int gen; + int i; + + int pobjects; + + struct unionfs_usi_data *new_data = NULL; + struct dentry **new_udi_dentry = NULL; + struct inode **new_uii_inode = NULL; + + struct dentry *root = NULL; + struct dentry *hidden_root = NULL; + + print_entry_location(); + +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + printk(KERN_ERR "Cannot manipulate branches if imap is used\n"); + err = -EPERM; + goto out; + } +#endif + + err = -ENOMEM; + addargs = KMALLOC(sizeof(struct unionfs_addbranch_args), GFP_KERNEL); + if (!addargs) + goto out; + + err = -EFAULT; + if (copy_from_user + (addargs, (const void __user *)arg, + sizeof(struct unionfs_addbranch_args))) + goto out; + + err = -EINVAL; + if (addargs->ab_perms & ~(MAY_READ | MAY_WRITE | MAY_NFSRO)) + goto out; + if (!(addargs->ab_perms & MAY_READ)) + goto out; + + err = -E2BIG; + if (sbend(inode->i_sb) > FD_SETSIZE) + goto out; + + err = -ENOMEM; + if (!(path = getname((const char __user *)addargs->ab_path))) + goto out; + + err = path_lookup(path, LOOKUP_FOLLOW, &nd); + + RECORD_PATH_LOOKUP(&nd); + if (err) + goto out; + if ((err = check_branch(&nd))) { + path_put(&nd.path); + RECORD_PATH_RELEASE(&nd); + goto out; + } + + unionfs_write_lock(inode->i_sb); + lock_dentry(inode->i_sb->s_root); + + root = inode->i_sb->s_root; + for (i = dbstart(inode->i_sb->s_root); i <= dbend(inode->i_sb->s_root); + i++) { + hidden_root = dtohd_index(root, i); + if (is_branch_overlap(hidden_root, nd.path.dentry)) { + err = -EINVAL; + goto out; + } + } + + err = -EINVAL; + if (addargs->ab_branch < 0 + || (addargs->ab_branch > (sbend(inode->i_sb) + 1))) + goto out; + + if ((err = newputmap(inode->i_sb))) + goto out; + + stopd(inode->i_sb)->b_end++; + dtopd(inode->i_sb->s_root)->udi_bcount++; + set_dbend(inode->i_sb->s_root, dbend(inode->i_sb->s_root) + 1); + itopd(inode->i_sb->s_root->d_inode)->b_end++; + + atomic_inc(&stopd(inode->i_sb)->usi_generation); + gen = atomic_read(&stopd(inode->i_sb)->usi_generation); + + pobjects = sbend(inode->i_sb) + 1; + + /* Reallocate the dynamic structures. */ + new_data = alloc_new_data(pobjects); + new_udi_dentry = alloc_new_dentries(pobjects); + new_uii_inode = KZALLOC(sizeof(struct inode *) * pobjects, GFP_KERNEL); + + if (!new_udi_dentry || !new_uii_inode || !new_data) { + err = -ENOMEM; + goto out; + } + + /* Copy the in-place values to our new structure. */ + for (i = 0; i < addargs->ab_branch; i++) { + atomic_set(&(new_data[i].sbcount), + branch_count(inode->i_sb, i)); + + new_data[i].branchperms = branchperms(inode->i_sb, i); + new_data[i].hidden_mnt = stohiddenmnt_index(inode->i_sb, i); + new_data[i].sb = stohs_index(inode->i_sb, i); + + new_udi_dentry[i] = dtohd_index(inode->i_sb->s_root, i); + new_uii_inode[i] = itohi_index(inode->i_sb->s_root->d_inode, i); + } + + /* Shift the ends to the right (only handle reallocated bits). */ + for (i = sbend(inode->i_sb) - 1; i >= (int)addargs->ab_branch; i--) { + int j = i + 1; + int pmindex; + + atomic_set(&new_data[j].sbcount, branch_count(inode->i_sb, i)); + + new_data[j].branchperms = branchperms(inode->i_sb, i); + new_data[j].hidden_mnt = stohiddenmnt_index(inode->i_sb, i); + new_data[j].sb = stohs_index(inode->i_sb, i); + new_udi_dentry[j] = dtohd_index(inode->i_sb->s_root, i); + new_uii_inode[j] = itohi_index(inode->i_sb->s_root->d_inode, i); + + /* Update the newest putmap, so it is correct for later. */ + pmindex = stopd(inode->i_sb)->usi_lastputmap; + pmindex -= stopd(inode->i_sb)->usi_firstputmap; + stopd(inode->i_sb)->usi_putmaps[pmindex]->map[i] = j; + + } + + /* Now we can free the old ones. */ + KFREE(dtopd(inode->i_sb->s_root)->udi_dentry); + KFREE(itopd(inode->i_sb->s_root->d_inode)->uii_inode); + KFREE(stopd(inode->i_sb)->usi_data); + + /* Update the real pointers. */ + dtohd_ptr(inode->i_sb->s_root) = new_udi_dentry; + itohi_ptr(inode->i_sb->s_root->d_inode) = new_uii_inode; + stopd(inode->i_sb)->usi_data = new_data; + + /* Re-NULL the new ones so we don't try to free them. */ + new_data = NULL; + new_udi_dentry = NULL; + new_uii_inode = NULL; + + /* Put the new dentry information into it's slot. */ + set_dtohd_index(inode->i_sb->s_root, addargs->ab_branch, nd.path.dentry); + set_itohi_index(inode->i_sb->s_root->d_inode, addargs->ab_branch, + IGRAB(nd.path.dentry->d_inode)); + set_branchperms(inode->i_sb, addargs->ab_branch, addargs->ab_perms); + set_branch_count(inode->i_sb, addargs->ab_branch, 0); + set_stohiddenmnt_index(inode->i_sb, addargs->ab_branch, nd.path.mnt); + set_stohs_index(inode->i_sb, addargs->ab_branch, nd.path.dentry->d_sb); + + atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen); + atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen); + + fixputmaps(inode->i_sb); + + out: + unlock_dentry(inode->i_sb->s_root); + unionfs_write_unlock(inode->i_sb); + + KFREE(new_udi_dentry); + KFREE(new_uii_inode); + KFREE(new_data); + KFREE(addargs); + if (path) + putname(path); + + print_exit_status(err); + + return err; +} + +/* This must be called with the super block already locked. */ +int unionfs_ioctl_delbranch(struct super_block *sb, unsigned long arg) +{ + struct dentry *hidden_dentry; + struct inode *hidden_inode; + struct vfsmount *hidden_mnt; + struct dentry *root_dentry; + struct inode *root_inode; + int err = 0; + int pmindex, i, gen; + + print_entry("branch = %lu ", arg); + lock_dentry(sb->s_root); + +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + printk(KERN_ERR "Cannot manipulate branches if imap is used\n"); + err = -EPERM; + goto out; + } +#endif + err = -EBUSY; + if (sbmax(sb) == 1) + goto out; + err = -EINVAL; + if (arg < 0 || arg > stopd(sb)->b_end) + goto out; + err = -EBUSY; + if (branch_count(sb, arg)) + goto out; + if ((err = newputmap(sb))) + goto out; + + pmindex = stopd(sb)->usi_lastputmap; + pmindex -= stopd(sb)->usi_firstputmap; + + atomic_inc(&stopd(sb)->usi_generation); + gen = atomic_read(&stopd(sb)->usi_generation); + + root_dentry = sb->s_root; + root_inode = sb->s_root->d_inode; + + hidden_dentry = dtohd_index(root_dentry, arg); + hidden_mnt = stohiddenmnt_index(sb, arg); + hidden_inode = itohi_index(root_inode, arg); + + DPUT(hidden_dentry); + IPUT(hidden_inode); + mntput(hidden_mnt); + + for (i = arg; i <= (sbend(sb) - 1); i++) { + set_branch_count(sb, i, branch_count(sb, i + 1)); + set_stohiddenmnt_index(sb, i, stohiddenmnt_index(sb, i + 1)); + set_stohs_index(sb, i, stohs_index(sb, i + 1)); + set_branchperms(sb, i, branchperms(sb, i + 1)); + set_dtohd_index(root_dentry, i, + dtohd_index(root_dentry, i + 1)); + set_itohi_index(root_inode, i, itohi_index(root_inode, i + 1)); + stopd(sb)->usi_putmaps[pmindex]->map[i + 1] = i; + } + + set_dtohd_index(root_dentry, sbend(sb), NULL); + set_itohi_index(root_inode, sbend(sb), NULL); + set_stohiddenmnt_index(sb, sbend(sb), NULL); + set_stohs_index(sb, sbend(sb), NULL); + + //XXX: Place check for inode maps and removal of branch here + + stopd(sb)->b_end--; + set_dbend(root_dentry, dbend(root_dentry) - 1); + dtopd(root_dentry)->udi_bcount--; + itopd(root_inode)->b_end--; + + atomic_set(&dtopd(root_dentry)->udi_generation, gen); + atomic_set(&itopd(root_inode)->uii_generation, gen); + + fixputmaps(sb); + + /* This doesn't open a file, so we might have to free the map here. */ + if (atomic_read(&stopd(sb)->usi_putmaps[pmindex]->count) == 0) { + KFREE(stopd(sb)->usi_putmaps[pmindex]); + stopd(sb)->usi_putmaps[pmindex] = NULL; + } + + out: + unlock_dentry(sb->s_root); + print_exit_status(err); + + return err; +} + +int unionfs_ioctl_rdwrbranch(struct inode *inode, unsigned int cmd, + unsigned long arg) +{ + int err; + struct unionfs_rdwrbranch_args *rdwrargs = NULL; + int gen; + + print_entry_location(); + + unionfs_write_lock(inode->i_sb); + lock_dentry(inode->i_sb->s_root); + + if ((err = newputmap(inode->i_sb))) + goto out; + + err = -ENOMEM; + rdwrargs = KMALLOC(sizeof(struct unionfs_rdwrbranch_args), GFP_KERNEL); + if (!rdwrargs) + goto out; + + err = -EFAULT; + if (copy_from_user + (rdwrargs, (const void __user *)arg, + sizeof(struct unionfs_rdwrbranch_args))) + goto out; + + err = -EINVAL; + if (rdwrargs->rwb_branch < 0 + || (rdwrargs->rwb_branch > (sbend(inode->i_sb) + 1))) + goto out; + if (rdwrargs->rwb_perms & ~(MAY_READ | MAY_WRITE | MAY_NFSRO)) + goto out; + if (!(rdwrargs->rwb_perms & MAY_READ)) + goto out; + + set_branchperms(inode->i_sb, rdwrargs->rwb_branch, rdwrargs->rwb_perms); + + atomic_inc(&stopd(inode->i_sb)->usi_generation); + gen = atomic_read(&stopd(inode->i_sb)->usi_generation); + atomic_set(&dtopd(inode->i_sb->s_root)->udi_generation, gen); + atomic_set(&itopd(inode->i_sb->s_root->d_inode)->uii_generation, gen); + + err = 0; + + out: + unlock_dentry(inode->i_sb->s_root); + unionfs_write_unlock(inode->i_sb); + KFREE(rdwrargs); + + print_exit_status(err); + + return err; +} + +int unionfs_ioctl_queryfile(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int err = 0; + fd_set branchlist; + + int bstart = 0, bend = 0, bindex = 0; + struct dentry *dentry, *hidden_dentry; + + print_entry_location(); + + dentry = file->f_dentry; + lock_dentry(dentry); + if ((err = unionfs_partial_lookup(dentry))) + goto out; + bstart = dbstart(dentry); + bend = dbend(dentry); + + FD_ZERO(&branchlist); + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + if (hidden_dentry->d_inode) + FD_SET(bindex, &branchlist); + } + + err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set)); + if (err) { + err = -EFAULT; + goto out; + } + + out: + unlock_dentry(dentry); + err = err < 0 ? err : bend; + print_exit_status(err); + return (err); +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/super.c +++ linux-2.6.28/ubuntu/unionfs/super.c @@ -0,0 +1,762 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: super.c,v 1.101 2006/11/04 22:27:51 jsipek Exp $ + */ + +#include "unionfs.h" + +/* The inode cache is used with alloc_inode for both our inode info and the + * vfs inode. */ +static struct kmem_cache *unionfs_inode_cachep; + +void unionfs_read_inode(struct inode *inode) +{ +#ifdef UNIONFS_MMAP + /* SP: use real address operations */ + extern struct address_space_operations unionfs_aops; +#else + static struct address_space_operations unionfs_empty_aops; +#endif + int size; + + print_entry_location(); + + if (!itopd(inode)) { + printk(KERN_ERR + "No kernel memory when allocating inode private data!\n"); + BUG(); + } + + memset(itopd(inode), 0, sizeof(struct unionfs_inode_info)); + itopd(inode)->b_start = -1; + itopd(inode)->b_end = -1; + atomic_set(&itopd(inode)->uii_generation, + atomic_read(&stopd(inode->i_sb)->usi_generation)); + itopd(inode)->uii_rdlock = SPIN_LOCK_UNLOCKED; + itopd(inode)->uii_rdcount = 1; + itopd(inode)->uii_hashsize = -1; + INIT_LIST_HEAD(&itopd(inode)->uii_readdircache); + + size = sbmax(inode->i_sb) * sizeof(struct inode *); + itohi_ptr(inode) = KZALLOC(size, GFP_KERNEL); + if (!itohi_ptr(inode)) { + printk(KERN_ERR + "No kernel memory when allocating lower-pointer array!\n"); + BUG(); + } + + inode->i_version++; + inode->i_op = &unionfs_main_iops; + inode->i_fop = &unionfs_main_fops; +#ifdef UNIONFS_MMAP + inode->i_mapping->a_ops = &unionfs_aops; +#else + /* I don't think ->a_ops is ever allowed to be NULL */ + inode->i_mapping->a_ops = &unionfs_empty_aops; + dprint(PRINT_DEBUG, "setting inode 0x%p a_ops to empty (0x%p)\n", + inode, inode->i_mapping->a_ops); +#endif + + print_exit_location(); +} + +#if 0 +static void unionfs_put_inode(struct inode *inode) +{ + print_entry_location(); + + dprint(PRINT_DEBUG, "%s i_count = %d, i_nlink = %d\n", __FUNCTION__, + atomic_read(&inode->i_count), inode->i_nlink); + + /* + * This is really funky stuff: + * Basically, if i_count == 1, iput will then decrement it and this + * inode will be destroyed. It is currently holding a reference to the + * hidden inode. Therefore, it needs to release that reference by + * calling iput on the hidden inode. iput() _will_ do it for us (by + * calling our clear_inode), but _only_ if i_nlink == 0. The problem + * is, NFS keeps i_nlink == 1 for silly_rename'd files. So we must for + * our i_nlink to 0 here to trick iput() into calling our clear_inode. + */ + + if (atomic_read(&inode->i_count) == 1) + inode->i_nlink = 0; + + print_exit_location(); +} +#endif + +/* + * we now define delete_inode, because there are two VFS paths that may + * destroy an inode: one of them calls clear inode before doing everything + * else that's needed, and the other is fine. This way we truncate the inode + * size (and its pages) and then clear our own inode, which will do an iput + * on our and the lower inode. + */ +static void unionfs_delete_inode(struct inode *inode) +{ + print_entry_location(); + + checkinode(inode, "unionfs_delete_inode IN"); + inode->i_size = 0; /* every f/s seems to do that */ + +#ifdef UNIONFS_MMAP + /* SP: if you try to clear_inode() when + * inode->i_data.nrpages != 0, you'll hit a BUG + * this is also what generic_delete_inode does */ + if (inode->i_data.nrpages) + truncate_inode_pages(&inode->i_data, 0); +#endif + clear_inode(inode); + + print_exit_location(); +} + +/* final actions when unmounting a file system */ +static void unionfs_put_super(struct super_block *sb) +{ + int bindex, bstart, bend; + struct unionfs_sb_info *spd; + + print_entry_location(); + + if ((spd = stopd(sb))) { +#ifdef UNIONFS_IMAP + /* XXX: Free persistent inode stuff. */ + cleanup_imap_data(sb); +#endif + bstart = sbstart(sb); + bend = sbend(sb); + for (bindex = bstart; bindex <= bend; bindex++) + mntput(stohiddenmnt_index(sb, bindex)); + + /* Make sure we have no leaks of branchget/branchput. */ + for (bindex = bstart; bindex <= bend; bindex++) + BUG_ON(branch_count(sb, bindex) != 0); + + KFREE(spd->usi_data); + KFREE(spd); + stopd_lhs(sb) = NULL; + } + dprint(PRINT_DEBUG, "unionfs: released super\n"); + + print_exit_location(); +} + +/* Since people use this to answer the "How big of a file can I write?" + * question, we report the size of the highest priority branch as the size of + * the union. + */ +static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + int err = 0; + struct super_block *sb, *hidden_sb; + + sb = dentry->d_sb; + + hidden_sb = stohs_index(sb, sbstart(sb)); + err = vfs_statfs(hidden_sb->s_root, buf); + + buf->f_type = UNIONFS_SUPER_MAGIC; + buf->f_namelen -= WHLEN; + + memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t)); + memset(&buf->f_spare, 0, sizeof(buf->f_spare)); + + return err; +} + +static int do_binary_remount(struct super_block *sb, int *flags, char *data) +{ + unsigned long *uldata = (unsigned long *)data; + int err; + + uldata++; + + switch (*uldata) { + case UNIONFS_IOCTL_DELBRANCH: + err = unionfs_ioctl_delbranch(sb, *(uldata + 1)); + break; + default: + err = -ENOTTY; + } + + return err; +} + +/* We don't support a standard text remount, but we do have a magic remount + * for unionctl. The idea is that you can remove a branch without opening + * the union. Eventually it would be nice to support a full-on remount, so + * that you can have all of the directories change at once, but that would + * require some pretty complicated matching code. */ +static int unionfs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + if (data && *((unsigned long *)data) == UNIONFS_REMOUNT_MAGIC) + return do_binary_remount(sb, flags, data); + printk("Warning! dirs delete and imap options to remount are ignored\n"); + return 0; +} + +/* + * Called by iput() when the inode reference count reached zero + * and the inode is not hashed anywhere. Used to clear anything + * that needs to be, before the inode is completely destroyed and put + * on the inode free list. + */ +static void unionfs_clear_inode(struct inode *inode) +{ + int bindex, bstart, bend; + struct inode *hidden_inode; + struct list_head *pos, *n; + struct unionfs_dir_state *rdstate; + + print_entry_location(); + + checkinode(inode, "unionfs_clear_inode IN"); + + list_for_each_safe(pos, n, &itopd(inode)->uii_readdircache) { + rdstate = list_entry(pos, struct unionfs_dir_state, uds_cache); + list_del(&rdstate->uds_cache); + free_rdstate(rdstate); + } + + /* Decrement a reference to a hidden_inode, which was incremented + * by our read_inode when it was created initially. */ + bstart = ibstart(inode); + bend = ibend(inode); + if (bstart >= 0) { + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_inode = itohi_index(inode, bindex); + if (!hidden_inode) + continue; + IPUT(hidden_inode); + } + } + // XXX: why this assertion fails? + // because it doesn't like us + // BUG_ON((inode->i_state & I_DIRTY) != 0); + KFREE(itohi_ptr(inode)); + itohi_ptr(inode) = NULL; + + print_exit_location(); +} + +static struct inode *unionfs_alloc_inode(struct super_block *sb) +{ + struct unionfs_inode_container *c; + + print_entry_location(); + + c = (struct unionfs_inode_container *) + kmem_cache_alloc(unionfs_inode_cachep, GFP_KERNEL); + if (!c) { + print_exit_pointer(NULL); + return NULL; + } + + memset(&c->info, 0, sizeof(c->info)); + + c->vfs_inode.i_version = 1; + print_exit_pointer(&c->vfs_inode); + return &c->vfs_inode; +} + +static void unionfs_destroy_inode(struct inode *inode) +{ + print_entry("inode = %p", inode); + kmem_cache_free(unionfs_inode_cachep, itopd(inode)); + print_exit_location(); +} + +static void init_once(void *v) +{ + struct unionfs_inode_container *c = (struct unionfs_inode_container *)v; + + print_entry_location(); + + inode_init_once(&c->vfs_inode); + + print_exit_location(); +} + +int init_inode_cache(void) +{ + int err = 0; + + print_entry_location(); + + unionfs_inode_cachep = + kmem_cache_create("unionfs_inode_cache", + sizeof(struct unionfs_inode_container), 0, + SLAB_RECLAIM_ACCOUNT, init_once); + if (!unionfs_inode_cachep) + err = -ENOMEM; + print_exit_status(err); + return err; +} + +void destroy_inode_cache(void) +{ + print_entry_location(); + if (!unionfs_inode_cachep) + goto out; + kmem_cache_destroy(unionfs_inode_cachep); + out: + print_exit_location(); + return; +} + +/* Called when we have a dirty inode, right here we only throw out + * parts of our readdir list that are too old. + */ +static int unionfs_write_inode(struct inode *inode, int sync) +{ + struct list_head *pos, *n; + struct unionfs_dir_state *rdstate; + + print_entry_location(); + + spin_lock(&itopd(inode)->uii_rdlock); + list_for_each_safe(pos, n, &itopd(inode)->uii_readdircache) { + rdstate = list_entry(pos, struct unionfs_dir_state, uds_cache); + /* We keep this list in LRU order. */ + if ((rdstate->uds_access + RDCACHE_JIFFIES) > jiffies) + break; + itopd(inode)->uii_rdcount--; + list_del(&rdstate->uds_cache); + free_rdstate(rdstate); + } + spin_unlock(&itopd(inode)->uii_rdlock); + + print_exit_location(); + return 0; +} + +/* + * Used only in nfs, to kill any pending RPC tasks, so that subsequent + * code can actually succeed and won't leave tasks that need handling. + * + * PS. I wonder if this is somehow useful to undo damage that was + * left in the kernel after a user level file server (such as amd) + * dies. + */ +static void unionfs_umount_begin(struct super_block *sb) +{ + struct super_block *hidden_sb; + int bindex, bstart, bend; + + print_entry_location(); +#if 0 + if (!(flags & MNT_FORCE)) + /* we are not being MNT_FORCEd, therefore we should emulate old + * behaviour + */ + goto out; +#endif + bstart = sbstart(sb); + bend = sbend(sb); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_sb = stohs_index(sb, bindex); + + if (hidden_sb && hidden_sb->s_op && + hidden_sb->s_op->umount_begin) + hidden_sb->s_op->umount_begin(hidden_sb); + } + + print_exit_location(); +} + +static int unionfs_show_options(struct seq_file *m, struct vfsmount *mnt) +{ + struct super_block *sb = mnt->mnt_sb; + int ret = 0; + unsigned long tmp = 0; + char *hidden_path; + int bindex, bstart, bend; + int perms; + + lock_dentry(sb->s_root); + + tmp = __get_free_page(GFP_KERNEL); + if (!tmp) { + ret = -ENOMEM; + goto out; + } + + bindex = bstart = sbstart(sb); + bend = sbend(sb); + + seq_printf(m, ",dirs="); + for (bindex = bstart; bindex <= bend; bindex++) { + struct path tp; + tp.dentry = dtohd_index(sb->s_root, bindex); + tp.mnt = stohiddenmnt_index(sb, bindex); + + hidden_path = + d_path(&tp, (char *)tmp, PAGE_SIZE); + perms = branchperms(sb, bindex); + seq_printf(m, "%s=%s", hidden_path, + perms & MAY_WRITE ? "rw" : + perms & MAY_NFSRO ? "nfsro" : "ro"); + if (bindex != bend) { + seq_printf(m, ":"); + } + } + + seq_printf(m, ",debug=%u", get_debug_mask()); + +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(sb, DELETE_ALL)) + seq_printf(m, ",delete=all"); + else +#endif + seq_printf(m, ",delete=whiteout"); + out: + if (tmp) + free_page(tmp); + unlock_dentry(sb->s_root); + return ret; +} + +#ifdef CONFIG_EXPORTFS +/* + * export operations. + * unionfs cannot handle disconnected dentry, since it has no hidden dentries. + */ +/* un-tested 64 bit environment (pointer and inode number) */ + +#define is_anon(d) ((d)->d_flags & DCACHE_DISCONNECTED) +extern struct export_operations export_op_default; + +static void prepend_path(char **path, const char *name, int len) +{ + *path -= len; + memcpy(*path, name, len); + (*path)--; + **path = '/'; +} + +struct filldir_arg { + int found, called; + char *path; + ino_t ino, parent_ino; +}; + +static int filldir(void *arg, const char *name, int len, loff_t pos, ino_t ino, + unsigned int d_type) +{ + struct filldir_arg *a = arg; + + a->called++; + if (len == 2 && !strncmp(name, "..", 2)) { + a->parent_ino = ino; + a->found++; + } else if (ino == a->ino) { + if (len != 1 || *name != '.') + prepend_path(&a->path, name, len); + a->found++; + } + return (a->found == 2) ? 1 : 0; +} + +static struct dentry *get_hidden_parent(struct super_block *hidden_sb, + ino_t hidden_parent_ino) +{ + __u32 fh[2]; + + if (hidden_sb->s_root->d_inode->i_ino == hidden_parent_ino) + return DGET(hidden_sb->s_root); + + fh[0] = hidden_parent_ino; + fh[1] = 0; + return export_op_default.get_dentry(hidden_sb, fh); +} + +static struct dentry *do_get_dentry(struct super_block *sb, ino_t ino, + __u32 gen, struct dentry *hidden_root, + ino_t hidden_ino, ino_t hidden_parent_ino) +{ + struct dentry *dentry, *hidden_parent, *parent; + char *path, *p; + struct filldir_arg arg = { + .ino = hidden_ino, + .parent_ino = hidden_parent_ino + }; + int open_flags, err, bindex, bend, found; + struct file *hidden_file; + struct super_block *hidden_sb; + + print_entry("hr%p, hi%lu, hpi%lu", + hidden_root, hidden_ino, hidden_parent_ino); + + dentry = ERR_PTR(-ENOMEM); + path = __getname(); + if (!path) + goto out; + arg.path = path + PATH_MAX - 1; + *arg.path = 0; + + open_flags = O_RDONLY | O_DIRECTORY /* | O_NOATIME */ ; + if (force_o_largefile()) + open_flags |= O_LARGEFILE; + + dentry = ERR_PTR(-ESTALE); + unionfs_read_lock(sb); + lock_dentry(sb->s_root); + bend = dbend(sb->s_root); + found = -1; + for (bindex = 0; found == -1 && bindex <= bend; bindex++) + if (hidden_root == dtohd_index(sb->s_root, bindex)) + found = bindex; + unlock_dentry(sb->s_root); + if (found == -1) + goto out_unlock; + + bindex = found; + hidden_sb = stohs_index(sb, bindex); + while (1) { + hidden_parent = get_hidden_parent(hidden_sb, hidden_parent_ino); + dentry = hidden_parent; + if (IS_ERR(hidden_parent)) + goto out_unlock; + + branchget(sb, bindex); + hidden_file = DENTRY_OPEN(DGET(hidden_parent), NULL, + open_flags); + if (IS_ERR(hidden_file)) { + dentry = (void *)hidden_file; + DPUT(hidden_parent); + branchput(sb, bindex); + goto out_unlock; + } + + arg.found = 0; + while (arg.found != 2) { + arg.called = 0; + err = vfs_readdir(hidden_file, filldir, &arg); + if (!arg.called || err < 0) + break; + } + fput(hidden_file); + branchput(sb, bindex); + if (arg.found != 2) { + dentry = ERR_PTR(-ESTALE); + DPUT(hidden_parent); + goto out_unlock; + } + + DPUT(hidden_parent); + if (hidden_parent_ino == hidden_root->d_inode->i_ino) + break; + arg.ino = hidden_parent_ino; + hidden_parent_ino = arg.parent_ino; + } + BUG_ON(arg.path < path); + + parent = DGET(sb->s_root); + p = strchr(++arg.path, '/'); + while (p) { + mutex_lock(&parent->d_inode->i_mutex); + dentry = LOOKUP_ONE_LEN(arg.path, parent, p - arg.path); + mutex_unlock(&parent->d_inode->i_mutex); + DPUT(parent); + if (IS_ERR(dentry)) + goto out_unlock; + if (!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)) { + DPUT(dentry); + dentry = ERR_PTR(-ESTALE); + goto out_unlock; + } + parent = dentry; + arg.path = p + 1; + p = strchr(arg.path, '/'); + } + mutex_lock(&parent->d_inode->i_mutex); + dentry = LOOKUP_ONE_LEN(arg.path, parent, strlen(arg.path)); + mutex_unlock(&parent->d_inode->i_mutex); + DPUT(parent); + if (!IS_ERR(dentry) + && (!dentry->d_inode + || dentry->d_inode->i_ino != ino + || dentry->d_inode->i_generation != gen)) { + DPUT(dentry); + dentry = ERR_PTR(-ESTALE); + } + + out_unlock: + unionfs_read_unlock(sb); + __putname(path); + out: + print_exit_pointer(dentry); + return dentry; +} + +enum { + FhHead = 4, FhHRoot1 = FhHead, FhHRoot2, + FhHIno1, FhHIno2, FhHPIno1, FhHPIno2, + FhTail +}; + +static void do_decode(__u32 * fh, struct dentry **hidden_root, + ino_t * hidden_ino, ino_t * hidden_parent_ino) +{ + unsigned long root; + + root = fh[FhHRoot2]; + *hidden_ino = fh[FhHIno2]; + *hidden_parent_ino = fh[FhHPIno2]; +#if BITS_PER_LONG == 64 + root |= ((unsigned long)fh[FhHRoot1]) << 32; + *hidden_ino |= ((unsigned long) fh[FhHIno1]) << 32; + *hidden_parent_ino |= ((unsigned long) fh[FhHPIno1]) << 32; +#elif BITS_PER_LONG == 32 + /* ok */ +#else +#error unknown size +#endif + + *hidden_root = (struct dentry*) root; +} + +static int unionfs_encode_fh(struct dentry *dentry, __u32 * fh, int *max_len, + int connectable) +{ + int type, len, bindex; + struct super_block *sb; + struct dentry *h_root; + ino_t h_ino, hp_ino; + static int warn; + + print_entry("dentry %p", dentry); + BUG_ON(is_anon(dentry) || !dentry->d_inode + || is_anon(dentry->d_parent)); + +#ifdef UNIONFS_IMAP + if (!warn && stopd(dentry->d_sb)->usi_persistent) + warn++; +#endif + if (!warn) { + printk(KERN_WARNING "Exporting Unionfs without imap" + " option may stop your NFS server or client"); + warn++; + } + + sb = dentry->d_sb; + unionfs_read_lock(sb); + lock_dentry(dentry); + + len = *max_len; + type = export_op_default.encode_fh(dentry, fh, max_len, connectable); + if (type == 255 || *max_len > FhHead || len < FhTail) { + type = 255; + goto out; + } + + *max_len = FhTail; + bindex = dbstart(dentry); + lock_dentry(sb->s_root); + h_root = dtohd_index(sb->s_root, bindex); + unlock_dentry(sb->s_root); + h_ino = itohi_index(dentry->d_inode, bindex)->i_ino; + hp_ino = parent_ino(dtohd(dentry)); + fh[FhHRoot2] = (unsigned long) h_root; + fh[FhHIno2] = h_ino; + fh[FhHPIno2] = hp_ino; +#if BITS_PER_LONG == 64 + fh[FhHRoot1] = ((unsigned long) h_root) >> 32; + fh[FhHIno1] = h_ino >> 32; + fh[FhHPIno1] = hp_ino >> 32; +#endif + + out: + unionfs_print(PRINT_MAIN_EXIT, "%d, fh{i%u, g%d, hr%x, hi%u, hpi%u}\n", + type, fh[0], fh[1], fh[FhHRoot2], fh[FhHIno2], + fh[FhHPIno2]); + unlock_dentry(dentry); + unionfs_read_unlock(sb); + return type; +} + +static struct dentry *unionfs_decode_fh(struct super_block *sb, __u32 * fh, + int fh_len, int fh_type, + int (*acceptable) (void *context, + struct dentry * de), + void *context) +{ + struct dentry *dentry, *hidden_root; + ino_t hidden_ino, hidden_parent_ino; + + print_entry("%d, fh{i%u, g%d, hr%x, hi%u, hpi%u}", + fh_type, fh[0], fh[1], fh[FhHRoot2], fh[FhHIno2], + fh[FhHPIno2]); + + dentry = export_op_default.get_dentry(sb, fh); + if (!dentry || IS_ERR(dentry) || (dentry->d_inode && !is_anon(dentry))) + return dentry; + + d_drop(dentry); + DPUT(dentry); + do_decode(fh, &hidden_root, &hidden_ino, &hidden_parent_ino); + dentry = do_get_dentry(sb, fh[0], fh[1], hidden_root, hidden_ino, + hidden_parent_ino); + if (!IS_ERR(dentry)) { + if (acceptable(context, dentry)) + return dentry; /* success */ + DPUT(dentry); + dentry = NULL; + } + return dentry; +} + +struct export_operations unionfs_export_ops = { + .decode_fh = unionfs_decode_fh, + .encode_fh = unionfs_encode_fh +}; +#endif + +struct super_operations unionfs_sops = { + //.put_inode = unionfs_put_inode, + .delete_inode = unionfs_delete_inode, + .put_super = unionfs_put_super, + .statfs = unionfs_statfs, + .remount_fs = unionfs_remount_fs, + .clear_inode = unionfs_clear_inode, + .umount_begin = unionfs_umount_begin, + .show_options = unionfs_show_options, + .write_inode = unionfs_write_inode, + .alloc_inode = unionfs_alloc_inode, + .destroy_inode = unionfs_destroy_inode, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/subr.c +++ linux-2.6.28/ubuntu/unionfs/subr.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: subr.c,v 1.142 2006/09/21 18:19:36 jsipek Exp $ + */ + +#include "unionfs.h" +#include + +/* Pass an unionfs dentry and an index. It will try to create a whiteout + * for the filename in dentry, and will try in branch 'index'. On error, + * it will proceed to a branch to the left. + */ +int create_whiteout(struct dentry *dentry, int start) +{ + int bstart, bend, bindex; + struct dentry *hidden_dir_dentry; + struct dentry *hidden_dentry; + struct dentry *hidden_wh_dentry; + char *name = NULL; + int err = -EINVAL; + + print_entry("start = %d", start); + + verify_locked(dentry); + + print_dentry("IN create_whiteout", dentry); + bstart = dbstart(dentry); + bend = dbend(dentry); + + /* create dentry's whiteout equivalent */ + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + for (bindex = start; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + + if (!hidden_dentry) { + /* if hidden dentry is not present, create the entire + * hidden dentry directory structure and go ahead. + * Since we want to just create whiteout, we only want + * the parent dentry, and hence get rid of this dentry. + */ + hidden_dentry = create_parents(dentry->d_inode, + dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + dprint(PRINT_DEBUG_WHITEOUT, + "create_parents failed for bindex = %d\n", + bindex); + continue; + } + } + hidden_wh_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(hidden_wh_dentry)) + continue; + + /* The whiteout already exists. This used to be impossible, but + * now is possible because of opaqueness. */ + if (hidden_wh_dentry->d_inode) { + DPUT(hidden_wh_dentry); + err = 0; + goto out; + } + + hidden_dir_dentry = lock_parent(hidden_wh_dentry); + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + err = + vfs_create(hidden_dir_dentry->d_inode, + hidden_wh_dentry, + ~current->fs->umask & S_IRWXUGO, NULL); + + } + unlock_dir(hidden_dir_dentry); + DPUT(hidden_wh_dentry); + + if (!err) + break; + + if (!IS_COPYUP_ERR(err)) + break; + } + + /* set dbopaque so that lookup will not proceed after this branch */ + if (!err) + set_dbopaque(dentry, bindex); + + print_dentry("OUT create_whiteout", dentry); + out: + KFREE(name); + print_exit_status(err); + return err; +} + +/* This is a helper function for rename, which ends up with hosed over dentries + * when it needs to revert. */ +int unionfs_refresh_hidden_dentry(struct dentry *dentry, int bindex) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_parent; + int err = 0; + + print_entry(" bindex = %d", bindex); + + verify_locked(dentry); + lock_dentry(dentry->d_parent); + hidden_parent = dtohd_index(dentry->d_parent, bindex); + unlock_dentry(dentry->d_parent); + + BUG_ON(!S_ISDIR(hidden_parent->d_inode->i_mode)); + + hidden_dentry = + LOOKUP_ONE_LEN(dentry->d_name.name, hidden_parent, + dentry->d_name.len); + if (IS_ERR(hidden_dentry)) { + err = PTR_ERR(hidden_dentry); + goto out; + } + + if (dtohd_index(dentry, bindex)) + DPUT(dtohd_index(dentry, bindex)); + if (itohi_index(dentry->d_inode, bindex)) { + IPUT(itohi_index(dentry->d_inode, bindex)); + set_itohi_index(dentry->d_inode, bindex, NULL); + } + if (!hidden_dentry->d_inode) { + DPUT(hidden_dentry); + set_dtohd_index(dentry, bindex, NULL); + } else { + set_dtohd_index(dentry, bindex, hidden_dentry); + set_itohi_index(dentry->d_inode, bindex, + IGRAB(hidden_dentry->d_inode)); + } + + out: + print_exit_status(err); + return err; +} + +int make_dir_opaque(struct dentry *dentry, int bindex) +{ + int err; + struct dentry *hidden_dentry, *diropq; + struct inode *hidden_dir; + + hidden_dentry = dtohd_index(dentry, bindex); + hidden_dir = hidden_dentry->d_inode; + BUG_ON(!S_ISDIR(dentry->d_inode->i_mode) + || !S_ISDIR(hidden_dir->i_mode)); + + mutex_lock(&hidden_dir->i_mutex); + diropq = LOOKUP_ONE_LEN(UNIONFS_DIR_OPAQUE, hidden_dentry, + sizeof(UNIONFS_DIR_OPAQUE) - 1); + err = PTR_ERR(diropq); + if (IS_ERR(diropq)) + goto out; + err = 0; + + if (!diropq->d_inode) + err = vfs_create(hidden_dir, diropq, S_IRUGO, NULL); + DPUT(diropq); + if (!err) + set_dbopaque(dentry, bindex); + + out: + mutex_unlock(&hidden_dir->i_mutex); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/commonfops.c +++ linux-2.6.28/ubuntu/unionfs/commonfops.c @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: commonfops.c,v 1.61 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* We only need this function here, but it could get promoted to unionfs.h, if + * other things need a generation specific branch putting function. */ +static inline void branchput_gen(int generation, struct super_block *sb, + int index) +{ + struct putmap *putmap; + + if (generation == atomic_read(&stopd(sb)->usi_generation)) { + branchput(sb, index); + return; + } + + BUG_ON(stopd(sb)->usi_firstputmap > generation); + BUG_ON(stopd(sb)->usi_lastputmap < generation); + + putmap = + stopd(sb)->usi_putmaps[generation - stopd(sb)->usi_firstputmap]; + BUG_ON(index < 0); + BUG_ON(index > putmap->bend); + BUG_ON(putmap->map[index] < 0); + branchput(sb, putmap->map[index]); + if (atomic_dec_and_test(&putmap->count)) { + stopd(sb)->usi_putmaps[generation - stopd(sb)->usi_firstputmap] + = NULL; + dprint(PRINT_DEBUG, "Freeing putmap %d.\n", generation); + KFREE(putmap); + } +} + +static char *get_random_name(int size, unsigned char *name) +{ + int i; + int j; + unsigned char *tmpbuf = NULL; + + if (size <= WHLEN) + return NULL; + + if (!name) + name = KMALLOC(size + 1, GFP_KERNEL); + if (!name) { + name = ERR_PTR(-ENOMEM); + goto out; + } + strncpy(name, WHPFX, WHLEN); + + tmpbuf = KMALLOC(size, GFP_KERNEL); + if (!tmpbuf) { + KFREE(name); + name = ERR_PTR(-ENOMEM); + goto out; + } + + get_random_bytes((void *)tmpbuf, (size - 3) / 2); + + j = WHLEN; + i = 0; + while ((i < (size - 3) / 2) && (j < size)) { + /* get characters in the 0-9, A-F range */ + + name[j] = + (tmpbuf[i] % 16) < + 10 ? (tmpbuf[i] % 16) + '0' : (tmpbuf[i] % 16) + 'a'; + j++; + if (j == size) + break; + name[j] = + (tmpbuf[i] >> 4) < + 10 ? (tmpbuf[i] >> 4) + '0' : (tmpbuf[i] >> 4) + 'a'; + j++; + + i++; + } + + name[size] = '\0'; + + out: + KFREE(tmpbuf); + return (name); + +} + +static int copyup_deleted_file(struct file *file, struct dentry *dentry, + int bstart, int bindex) +{ + int attempts = 0; + int err; + int exists = 1; + char *name = NULL; + struct dentry *tmp_dentry = NULL; + struct dentry *hidden_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + + print_entry_location(); + + /* Try five times to get a unique file name, fail after that. Five is + * simply a magic number, because we shouldn't try forever. */ + while (exists) { + /* The first call allocates, the subsequent ones reuse. */ + name = get_random_name(UNIONFS_TMPNAM_LEN, name); + err = -ENOMEM; + if (!name) + goto out; + //XXX: Why do we do this every time? bstart never changes? + hidden_dentry = dtohd_index(dentry, bstart); + + tmp_dentry = LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + UNIONFS_TMPNAM_LEN); + err = PTR_ERR(tmp_dentry); + if (IS_ERR(tmp_dentry)) + goto out; + exists = tmp_dentry->d_inode ? 1 : 0; + DPUT(tmp_dentry); + + err = -EEXIST; + if (++attempts > 5) + goto out; + } + + err = copyup_named_file(dentry->d_parent->d_inode, file, name, bstart, + bindex, file->f_dentry->d_inode->i_size); + if (err) + goto out; + + /* bring it to the same state as an unlinked file */ + hidden_dentry = dtohd_index(dentry, dbstart(dentry)); + hidden_dir_dentry = lock_parent(hidden_dentry); + err = vfs_unlink(hidden_dir_dentry->d_inode, hidden_dentry, NULL); + unlock_dir(hidden_dir_dentry); + + out: + KFREE(name); + print_exit_status(err); + return err; +} + +int unionfs_file_revalidate(struct file *file, int willwrite) +{ + struct super_block *sb; + struct dentry *dentry; + int sbgen, fgen, dgen; + int bindex, bstart, bend; + struct file *hidden_file; + struct dentry *hidden_dentry; + int size; + + int err = 0; + + print_entry(" file = %p", file); + + dentry = file->f_dentry; + lock_dentry(dentry); + sb = dentry->d_sb; + unionfs_read_lock(sb); + if (!unionfs_d_revalidate(dentry, NULL) && !d_deleted(dentry)) { + err = -ESTALE; + goto out; + } + print_dentry("file revalidate in", dentry); + + sbgen = atomic_read(&stopd(sb)->usi_generation); + dgen = atomic_read(&dtopd(dentry)->udi_generation); + fgen = atomic_read(&ftopd(file)->ufi_generation); + + BUG_ON(sbgen > dgen); + + /* There are two cases we are interested in. The first is if the + * generation is lower than the super-block. The second is if someone + * has copied up this file from underneath us, we also need to refresh + * things. */ + if (!d_deleted(dentry) && + ((sbgen > fgen) || (dbstart(dentry) != fbstart(file)))) { + /* First we throw out the existing files. */ + bstart = fbstart(file); + bend = fbend(file); + for (bindex = bstart; bindex <= bend; bindex++) { + if (ftohf_index(file, bindex)) { + branchput_gen(fgen, dentry->d_sb, bindex); + fput(ftohf_index(file, bindex)); + } + } + + if (ftohf_ptr(file)) { + KFREE(ftohf_ptr(file)); + ftohf_ptr(file) = NULL; + } + + /* Now we reopen the file(s) as in unionfs_open. */ + bstart = fbstart(file) = dbstart(dentry); + bend = fbend(file) = dbend(dentry); + + size = sizeof(struct file *) * sbmax(sb); + ftohf_ptr(file) = KZALLOC(size, GFP_KERNEL); + if (!ftohf_ptr(file)) { + err = -ENOMEM; + goto out; + } + + if (S_ISDIR(dentry->d_inode->i_mode)) { + /* We need to open all the files. */ + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(sb, bindex)); + branchget(sb, bindex); + + hidden_file = + DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(sb, bindex), + file->f_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } else { + set_ftohf_index(file, bindex, + hidden_file); + } + } + } else { + /* We only open the highest priority branch. */ + hidden_dentry = dtohd(dentry); + if (willwrite && IS_WRITE_FLAG(file->f_flags) + && is_robranch(dentry)) { + for (bindex = bstart - 1; bindex >= 0; bindex--) { + + err = copyup_file(dentry-> + d_parent-> + d_inode, + file, + bstart, + bindex, + file-> + f_dentry-> + d_inode->i_size); + + if (!err) + break; + else + continue; + + } + atomic_set(&ftopd(file)->ufi_generation, + atomic_read(&itopd(dentry->d_inode)-> + uii_generation)); + goto out; + } + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(sb, bstart)); + branchget(sb, bstart); + hidden_file = + DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(sb, bstart), + file->f_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } + set_ftohf(file, hidden_file); + /* Fix up the position. */ + hidden_file->f_pos = file->f_pos; + + memcpy(&(hidden_file->f_ra), &(file->f_ra), + sizeof(struct file_ra_state)); + } + atomic_set(&ftopd(file)->ufi_generation, + atomic_read(&itopd(dentry->d_inode)-> + uii_generation)); + } + + /* Copyup on the first write to a file on a readonly branch. */ + if (willwrite && IS_WRITE_FLAG(file->f_flags) + && !IS_WRITE_FLAG(ftohf(file)->f_flags) && is_robranch(dentry)) { + dprint(PRINT_DEBUG, + "Doing delayed copyup of a read-write file on a read-only branch.\n"); + bstart = fbstart(file); + bend = fbend(file); + + BUG_ON(!S_ISREG(file->f_dentry->d_inode->i_mode)); + + for (bindex = bstart - 1; bindex >= 0; bindex--) { + if (!d_deleted(file->f_dentry)) { + err = + copyup_file(dentry->d_parent-> + d_inode, file, bstart, + bindex, + file->f_dentry-> + d_inode->i_size); + } else { + err = + copyup_deleted_file(file, dentry, bstart, + bindex); + } + + if (!err) + break; + else + continue; + + } + if (!err && (bstart > fbstart(file))) { + bend = fbend(file); + for (bindex = bstart; bindex <= bend; bindex++) { + if (ftohf_index(file, bindex)) { + branchput(dentry->d_sb, bindex); + fput(ftohf_index(file, bindex)); + set_ftohf_index(file, bindex, NULL); + } + } + fbend(file) = bend; + } + } + + out: + print_dentry("file revalidate out", dentry); + unlock_dentry(dentry); + unionfs_read_unlock(dentry->d_sb); + print_exit_status(err); + return err; +} + +int unionfs_open(struct inode *inode, struct file *file) +{ + int err = 0; + int hidden_flags; + struct file *hidden_file = NULL; + struct dentry *hidden_dentry = NULL; + struct dentry *dentry = NULL; + int bindex = 0, bstart = 0, bend = 0; + int locked = 0; + int size; + + print_entry_location(); + + ftopd_lhs(file) = KZALLOC(sizeof(struct unionfs_file_info), GFP_KERNEL); + if (!ftopd(file)) { + err = -ENOMEM; + goto out; + } + fbstart(file) = -1; + fbend(file) = -1; + atomic_set(&ftopd(file)->ufi_generation, + atomic_read(&itopd(inode)->uii_generation)); + + size = sizeof(struct file *) * sbmax(inode->i_sb); + ftohf_ptr(file) = KZALLOC(size, GFP_KERNEL); + if (!ftohf_ptr(file)) { + err = -ENOMEM; + goto out; + } + + hidden_flags = file->f_flags; + + dentry = file->f_dentry; + dprint(PRINT_DEBUG, "dentry to open is %p\n", dentry); + lock_dentry(dentry); + unionfs_read_lock(inode->i_sb); + locked = 1; + + bstart = fbstart(file) = dbstart(dentry); + bend = fbend(file) = dbend(dentry); + + /* increment to show the kind of open, so that we can + * flush appropriately + */ + atomic_inc(&itopd(dentry->d_inode)->uii_totalopens); + + /* open all directories and make the unionfs file struct point to these hidden file structs */ + if (S_ISDIR(inode->i_mode)) { + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + DGET(hidden_dentry); + mntget(stohiddenmnt_index(inode->i_sb, bindex)); + hidden_file = + DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(inode->i_sb, bindex), + hidden_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } + + set_ftohf_index(file, bindex, hidden_file); + /* The branchget goes after the open, because otherwise + * we would miss the reference on release. */ + branchget(inode->i_sb, bindex); + } + } else { + /* open a file */ + hidden_dentry = dtohd(dentry); + + /* check for the permission for hidden file. If the error is COPYUP_ERR, + * copyup the file. + */ + if (hidden_dentry->d_inode && is_robranch(dentry)) { + /* if the open will change the file, copy it up otherwise defer it. */ + if (hidden_flags & O_TRUNC) { + int size = 0; + + err = -EROFS; + /* copyup the file */ + for (bindex = bstart - 1; bindex >= 0; bindex--) { + err = + copyup_file(dentry-> + d_parent-> + d_inode, file, + bstart, bindex, size); + if (!err) { + break; + } + } + goto out; + } else { + hidden_flags &= ~(OPEN_WRITE_FLAGS); + } + } + + DGET(hidden_dentry); + /* dentry_open will decrement mnt refcnt if err. + * otherwise fput() will do an mntput() for us upon file close. + */ + mntget(stohiddenmnt_index(inode->i_sb, bstart)); + hidden_file = DENTRY_OPEN(hidden_dentry, + stohiddenmnt_index(inode->i_sb, + bstart), + hidden_flags); + if (IS_ERR(hidden_file)) { + err = PTR_ERR(hidden_file); + goto out; + } else { + set_ftohf(file, hidden_file); + branchget(inode->i_sb, bstart); + } + } + + out: + /* freeing the allocated resources, and fput the opened files */ + if (err < 0 && ftopd(file)) { + if (!locked) + unionfs_read_lock(file->f_dentry->d_sb); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_file = ftohf_index(file, bindex); + if (hidden_file) { + branchput(file->f_dentry->d_sb, bindex); + /* fput calls dput for hidden_dentry */ + fput(hidden_file); + } + } + if (!locked) + unionfs_read_unlock(file->f_dentry->d_sb); + KFREE(ftohf_ptr(file)); + KFREE(ftopd(file)); + } + + print_file("OUT: unionfs_open", file); + + if (locked) { + unlock_dentry(dentry); + unionfs_read_unlock(inode->i_sb); + } + print_exit_status(err); + return err; +} + +int unionfs_file_release(struct inode *inode, struct file *file) +{ + int err = 0; + struct file *hidden_file = NULL; + int bindex, bstart, bend; + int fgen; + + print_entry_location(); + + checkinode(inode, "unionfs_release"); + + /* fput all the hidden files */ + fgen = atomic_read(&ftopd(file)->ufi_generation); + bstart = fbstart(file); + bend = fbend(file); + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_file = ftohf_index(file, bindex); + + if (hidden_file) { + fput(hidden_file); + unionfs_read_lock(inode->i_sb); + branchput_gen(fgen, inode->i_sb, bindex); + unionfs_read_unlock(inode->i_sb); + } + } + KFREE(ftohf_ptr(file)); + + if (ftopd(file)->rdstate) { + ftopd(file)->rdstate->uds_access = jiffies; + dprint(PRINT_DEBUG, "Saving rdstate with cookie %u [%d.%lld]\n", + ftopd(file)->rdstate->uds_cookie, + ftopd(file)->rdstate->uds_bindex, + (long long)ftopd(file)->rdstate->uds_dirpos); + spin_lock(&itopd(inode)->uii_rdlock); + itopd(inode)->uii_rdcount++; + list_add_tail(&ftopd(file)->rdstate->uds_cache, + &itopd(inode)->uii_readdircache); + mark_inode_dirty(inode); + spin_unlock(&itopd(inode)->uii_rdlock); + ftopd(file)->rdstate = NULL; + } + KFREE(ftopd(file)); + + checkinode(inode, "post unionfs_release"); + + print_exit_status(err); + return err; +} + +long unionfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long err = 0; /* don't fail by default */ + struct file *hidden_file = NULL; + int val; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + + /* check if asked for local commands */ + switch (cmd) { + case FIST_IOCTL_GET_DEBUG_VALUE: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + val = get_debug_mask(); + err = put_user(val, (int __user *)arg); + break; + + case FIST_IOCTL_SET_DEBUG_VALUE: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = get_user(val, (int __user *)arg); + if (err) + break; + dprint(PRINT_DEBUG, "IOCTL SET: got arg %d\n", val); + if (val < 0 || val > PRINT_MAX) { + err = -EINVAL; + break; + } + set_debug_mask(val); + break; + + /* add non-debugging fist ioctl's here */ + + case UNIONFS_IOCTL_BRANCH_COUNT: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = unionfs_ioctl_branchcount(file, cmd, arg); + break; + + case UNIONFS_IOCTL_INCGEN: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = unionfs_ioctl_incgen(file, cmd, arg); + break; + + case UNIONFS_IOCTL_ADDBRANCH: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = + unionfs_ioctl_addbranch(file->f_dentry->d_inode, cmd, arg); + break; + + case UNIONFS_IOCTL_RDWRBRANCH: + if (!capable(CAP_SYS_ADMIN)) { + err = -EACCES; + goto out; + } + err = + unionfs_ioctl_rdwrbranch(file->f_dentry->d_inode, cmd, arg); + break; + + case UNIONFS_IOCTL_QUERYFILE: + /* XXX: This should take the file. */ + err = unionfs_ioctl_queryfile(file, cmd, arg); + break; + + default: + hidden_file = ftohf(file); + + err = -ENOTTY; + if (!hidden_file || !hidden_file->f_op) + goto out; + if (hidden_file->f_op->unlocked_ioctl) { + err = + hidden_file->f_op->unlocked_ioctl(hidden_file, cmd, + arg); + } else if (hidden_file->f_op->ioctl) { + lock_kernel(); + err = + hidden_file->f_op->ioctl(hidden_file->f_dentry-> + d_inode, hidden_file, cmd, + arg); + unlock_kernel(); + } + } /* end of outer switch statement */ + + out: + print_exit_status((int)err); + return err; +} + +int unionfs_flush(struct file *file, fl_owner_t id) +{ + int err = 0; /* assume ok (see open.c:close_fp) */ + struct file *hidden_file = NULL; + int bindex, bstart, bend; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + if (!atomic_dec_and_test + (&itopd(file->f_dentry->d_inode)->uii_totalopens)) + goto out; + + lock_dentry(file->f_dentry); + + bstart = fbstart(file); + bend = fbend(file); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_file = ftohf_index(file, bindex); + + if (hidden_file && hidden_file->f_op + && hidden_file->f_op->flush) { + err = hidden_file->f_op->flush(hidden_file, id); + if (err) + goto out_lock; + /* This was earlier done in the unlink_all function in unlink.c */ + /* if there are no more references to the dentry, dput it */ + if (d_deleted(file->f_dentry)) { + DPUT(dtohd_index(file->f_dentry, bindex)); + set_dtohd_index(file->f_dentry, bindex, NULL); + } + } + + } + + out_lock: + unlock_dentry(file->f_dentry); + out: + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/print.c +++ linux-2.6.28/ubuntu/unionfs/print.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: print.c,v 1.77 2006/07/08 17:58:31 ezk Exp $ + */ + +/* Print debugging functions */ + +#include "unionfs.h" + +static unsigned int debug_mask = DEFAULT_DEBUG_MASK; + +/* get value of debugging variable */ +unsigned int get_debug_mask(void) +{ + return debug_mask; +} + +/* set debug level variable and return the previous value */ +int set_debug_mask(int val) +{ +#ifdef UNIONFS_DEBUG + int prev = debug_mask; + + debug_mask = val; + + printk(KERN_INFO UNIONFS_NAME ": debug mask set to %u\n", debug_mask); + + return prev; +#else /* UNIONFS_DEBUG */ + printk(KERN_WARNING UNIONFS_NAME ": debugging is not enabled\n"); + return -ENOTSUPP; +#endif /* ! UNIONFS_DEBUG */ +} + +static inline int should_print(const unsigned int req) +{ + return (req & debug_mask); +} + +static void unionfs_print_generic_inode(const char *prefix, + const char *prefix2, const struct inode *inode) +{ + if (!inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: NULL INODE PASSED!\n", prefix, prefix2); + return; + } + + if (IS_ERR(inode)) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: ERROR INODE PASSED: %ld\n", prefix, prefix2, + PTR_ERR(inode)); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_ino=%lu\n", + prefix, prefix2, inode->i_ino); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_count=%u\n", + prefix, prefix2, atomic_read(&inode->i_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_nlink=%u\n", + prefix, prefix2, inode->i_nlink); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_mode=%o\n", + prefix, prefix2, inode->i_mode); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_size=%llu\n", + prefix, prefix2, inode->i_size); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_op=%p\n", + prefix, prefix2, inode->i_op); + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s%s: i_sb=%p (%s)\n", + prefix, prefix2, inode->i_sb, (inode->i_sb ? sbt(inode->i_sb) : "NullTypeSB")); +} + +void unionfs_print_inode(const unsigned int req, const char *prefix, const struct inode *inode) +{ + int bindex; + + if (!should_print(req)) + return; + + if (!inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: NULL INODE PASSED!\n", prefix); + return; + } + if (IS_ERR(inode)) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: ERROR INODE PASSED: %ld\n", prefix, PTR_ERR(inode)); + return; + } + + unionfs_print_generic_inode(prefix, "", inode); + + if (strcmp("unionfs", sbt(inode->i_sb))) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: Not a " UNIONFS_NAME " inode.\n", prefix); + return; + } + + if (!itopd(inode)) + return; + + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: ibstart=%d, ibend=%d\n", prefix, ibstart(inode), ibend(inode)); + + if (ibstart(inode) == -1) + return; + + for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { + struct inode *hidden_inode = itohi_index(inode, bindex); + char newstr[10]; + if (!hidden_inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PI:%s: HI#%d: NULL\n", prefix, bindex); + continue; + } + snprintf(newstr, 10, ": HI%d", bindex); + unionfs_print_generic_inode(prefix, newstr, hidden_inode); + } +} + +static void unionfs_print_generic_file(const char *prefix, const char *prefix2, + const struct file *file) +{ + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_dentry=0x%p\n", prefix, prefix2, file->f_dentry); + + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: name=%s\n", prefix, prefix2, file->f_dentry->d_name.name); + if (file->f_dentry->d_inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_dentry->d_inode->i_ino=%lu\n", prefix, prefix2, file->f_dentry->d_inode->i_ino); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_dentry->d_inode->i_mode=%o\n", prefix, prefix2, file->f_dentry->d_inode->i_mode); + } + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_op=0x%p\n", prefix, prefix2, file->f_op); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_mode=0x%x\n", prefix, prefix2, file->f_mode); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_pos=0x%llu\n", prefix, prefix2, file->f_pos); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_count=%u\n", prefix, prefix2, atomic_read(&file->f_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_flags=0x%x\n", prefix, prefix2, file->f_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s%s: f_version=%llu\n", prefix, prefix2, file->f_version); +} + +void unionfs_print_file(const unsigned int req, const char *prefix, const struct file *file) +{ + struct file *hidden_file; + + if (!should_print(req)) + return; + + if (!file) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: NULL FILE PASSED!\n", prefix); + return; + } + + unionfs_print_generic_file(prefix, "", file); + + if (strcmp("unionfs", sbt(file->f_dentry->d_sb))) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: Not a " UNIONFS_NAME " file.\n", prefix); + return; + } + + if (ftopd(file)) { + int bindex; + + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: fbstart=%d, fbend=%d\n", prefix, fbstart(file), fbend(file)); + + for (bindex = fbstart(file); bindex <= fbend(file); bindex++) { + char newstr[10]; + hidden_file = ftohf_index(file, bindex); + if (!hidden_file) { + printk(KERN_DEBUG UNIONFS_NAME ": PF:%s: HF#%d is NULL\n", prefix, bindex); + continue; + } + snprintf(newstr, 10, ": HF%d", bindex); + unionfs_print_generic_file(prefix, newstr, hidden_file); + } + } +} + +static char mode_to_type(mode_t mode) +{ + if (S_ISDIR(mode)) + return 'd'; + if (S_ISLNK(mode)) + return 'l'; + if (S_ISCHR(mode)) + return 'c'; + if (S_ISBLK(mode)) + return 'b'; + if (S_ISREG(mode)) + return 'f'; + return '?'; +} + +static void unionfs_print_generic_dentry(const char *prefix, const char *prefix2, const + struct dentry *dentry, int check) +{ + if (!dentry) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: NULL DENTRY PASSED!\n", prefix, prefix2); + return; + } + + if (IS_ERR(dentry)) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: ERROR DENTRY (%ld)!\n", prefix, prefix2, + PTR_ERR(dentry)); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: dentry = %p\n", prefix, prefix2, dentry); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_count=%d\n", prefix, prefix2, atomic_read(&dentry->d_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_flags=%x\n", prefix, prefix2, (int)dentry->d_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_name.name=\"%s\" (len = %d)\n", prefix, prefix2, dentry->d_name.name, dentry->d_name.len); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_sb=%p (%s)\n", prefix, prefix2, dentry->d_sb, sbt(dentry->d_sb)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_inode=%p\n", prefix, prefix2, dentry->d_inode); + + if (dentry->d_inode) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_inode->i_ino=%ld (%s)\n", prefix, prefix2, + dentry->d_inode->i_ino, + sbt(dentry->d_inode->i_sb)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: dentry->d_inode->i_mode: %c%o\n", prefix, + prefix2, mode_to_type(dentry->d_inode->i_mode), + dentry->d_inode->i_mode); + } + + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_parent=%p (%s)\n", prefix, prefix2, + dentry->d_parent, + (dentry->d_parent ? sbt(dentry->d_parent->d_sb) : "nil")); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_parent->d_name.name=\"%s\"\n", prefix, prefix2, + dentry->d_parent->d_name.name); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_parent->d_count=%d\n", prefix, prefix2, + atomic_read(&dentry->d_parent->d_count)); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_op=%p\n", prefix, prefix2, dentry->d_op); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: d_fsdata=%p\n", prefix, prefix2, + dentry->d_fsdata); + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s%s: hlist_unhashed(d_hash)=%d\n", prefix, prefix2, + hlist_unhashed(&((struct dentry *)dentry)->d_hash)); + + /* After we have printed it, we can assert something about it. */ + if (check) + BUG_ON(atomic_read(&dentry->d_count) <= 0); +} + +static void __unionfs_print_dentry(const char *prefix, const struct dentry *dentry, + int check) +{ + if (!dentry) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: NULL DENTRY PASSED!\n", prefix); + return; + } + + if (IS_ERR(dentry)) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: ERROR DENTRY (%ld)!\n", prefix, + PTR_ERR(dentry)); + return; + } + + unionfs_print_generic_dentry(prefix, "", dentry, check); + + if (strcmp("unionfs", sbt(dentry->d_sb))) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: Not a " UNIONFS_NAME " dentry.\n", prefix); + return; + } + + if (!dtopd(dentry)) + return; + + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: dbstart=%d, dbend=%d, dbopaque=%d\n", + prefix, dbstart(dentry), dbend(dentry), dbopaque(dentry)); + + if (dbstart(dentry) != -1) { + int bindex; + char newstr[10]; + struct dentry *hidden_dentry; + + for (bindex = dbstart(dentry); bindex <= dbend(dentry); + bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + printk(KERN_DEBUG UNIONFS_NAME ": PD:%s: HD#%d: NULL\n", prefix, bindex); + continue; + } + snprintf(newstr, 10, ": HD%d", bindex); + unionfs_print_generic_dentry(prefix, newstr, hidden_dentry, check); + } + } +} + +void unionfs_print_dentry(const unsigned int req, const char *prefix, const struct dentry *dentry) +{ + if (!should_print(req)) + return; + + __unionfs_print_dentry(prefix, dentry, 1); +} + +void unionfs_print_dentry_nocheck(const unsigned int req, const char *prefix, const struct dentry *dentry) +{ + if (!should_print(req)) + return; + + __unionfs_print_dentry(prefix, dentry, 0); +} + +void unionfs_checkinode(const unsigned int req, const struct inode *inode, const char *msg) +{ + if (!should_print(req)) + return; + + if (!inode) { + printk(KERN_DEBUG UNIONFS_NAME ": unionfs_checkinode - inode is NULL! (%s)\n", + msg); + return; + } + + if (!itopd(inode)) { + printk(KERN_DEBUG UNIONFS_NAME ": unionfs_checkinode(%ld) - no private data (%s)\n", + inode->i_ino, msg); + return; + } + + if ((itopd(inode)->b_start < 0) || !itohi(inode)) { + printk(KERN_DEBUG UNIONFS_NAME + "unionfs_checkinode(%ld) - underlying is NULL! (%s)\n", + inode->i_ino, msg); + return; + } + + if (!inode->i_sb) { + printk(KERN_DEBUG UNIONFS_NAME + ": unionfs_checkinode(%ld) - inode->i_sb is NULL! (%s)\n", + inode->i_ino, msg); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": inode->i_sb->s_type %p\n", inode->i_sb->s_type); + if (!inode->i_sb->s_type) { + printk(KERN_DEBUG UNIONFS_NAME + ": unionfs_checkinode(%ld) - inode->i_sb->s_type is NULL! (%s)\n", + inode->i_ino, msg); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME + ": CI: %s: inode->i_count = %d, hidden_inode->i_count = %d, inode = %lu, sb = %s, hidden_sb = %s\n", + msg, atomic_read(&inode->i_count), + itopd(inode)->b_start >= + 0 ? atomic_read(&itohi(inode)->i_count) : -1, inode->i_ino, + inode->i_sb->s_type->name, + itopd(inode)->b_start >= + 0 ? itohi(inode)->i_sb->s_type->name : "(none)"); +} + +void unionfs_print_sb(const unsigned int req, const char *prefix, const struct super_block *sb) +{ + struct super_block *hidden_superblock; + + if (!should_print(req)) + return; + + if (!sb) { + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: NULL SB PASSED!\n", prefix); + return; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_blocksize=%lu\n", prefix, sb->s_blocksize); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_blocksize_bits=%u\n", prefix, sb->s_blocksize_bits); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_flags=0x%lx\n", prefix, sb->s_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_magic=0x%lx\n", prefix, sb->s_magic); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_maxbytes=%llu\n", prefix, sb->s_maxbytes); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_count=%d\n", prefix, sb->s_count); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: s_active=%d\n", prefix, atomic_read(&sb->s_active)); + + if (stopd(sb)) + printk(KERN_DEBUG UNIONFS_NAME ": sbstart=%d, sbend=%d\n", sbstart(sb), + sbend(sb)); + + if (stopd(sb)) { + int bindex; + for (bindex = sbstart(sb); bindex <= sbend(sb); bindex++) { + hidden_superblock = stohs_index(sb, bindex); + if (!hidden_superblock) { + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d is NULL", prefix, + bindex); + continue; + } + + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_blocksize=%lu\n", prefix, bindex, + hidden_superblock->s_blocksize); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_blocksize_bits=%u\n", prefix, bindex, + hidden_superblock->s_blocksize_bits); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_flags=0x%lx\n", prefix, bindex, + hidden_superblock->s_flags); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_magic=0x%lx\n", prefix, bindex, + hidden_superblock->s_magic); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_maxbytes=%llu\n", prefix, bindex, + hidden_superblock->s_maxbytes); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_count=%d\n", prefix, bindex, + hidden_superblock->s_count); + printk(KERN_DEBUG UNIONFS_NAME ": PSB:%s: HS#%d: s_active=%d\n", prefix, bindex, + atomic_read(&hidden_superblock->s_active)); + } + } +} + +int unionfs_print(const unsigned int req, const char *fmt, ...) +{ + va_list ap; + int r; + + if (!should_print(req)) + return 0; + + printk(KERN_DEBUG UNIONFS_NAME ": "); + va_start(ap, fmt); + r = vprintk(fmt, ap); + va_end(ap); + + return r; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/main.c +++ linux-2.6.28/ubuntu/unionfs/main.c @@ -0,0 +1,869 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: main.c,v 1.176 2006/10/10 07:28:13 jsipek Exp $ + */ + +#include "unionfs.h" +#include +#include + +/* declarations added for "sparse" */ +extern void unionfs_kill_block_super(struct super_block *sb); + +/* declarations added for malloc_debugging */ + +#ifdef FIST_MALLOC_DEBUG +extern atomic_t unionfs_malloc_counter; +extern atomic_t unionfs_mallocs_outstanding; +#endif + +extern void unionfs_read_inode(struct inode *inode); + +static struct inode *unionfs_iget(struct super_block *sb, ino_t ino) +{ + struct inode *inode; + + inode = iget_locked(sb, ino); + if (!inode) + return ERR_PTR(-ENOMEM); + if (inode->i_state & I_NEW) { + unionfs_read_inode(inode); + unlock_new_inode(inode); + } + return inode; +} + +/* sb we pass is unionfs's super_block */ +int unionfs_interpose(struct dentry *dentry, struct super_block *sb, int flag) +{ + struct inode *hidden_inode; + struct dentry *hidden_dentry; + int err = 0; + struct inode *inode; + int is_negative_dentry = 1; + int bindex, bstart, bend; + + print_entry("flag = %d", flag); + + verify_locked(dentry); + + print_dentry("In unionfs_interpose", dentry); + + bstart = dbstart(dentry); + bend = dbend(dentry); + + /* Make sure that we didn't get a negative dentry. */ + for (bindex = bstart; bindex <= bend; bindex++) { + if (dtohd_index(dentry, bindex) && + dtohd_index(dentry, bindex)->d_inode) { + is_negative_dentry = 0; + break; + } + } + BUG_ON(is_negative_dentry); + + /* We allocate our new inode below, by calling iget. + * iget will call our read_inode which will initialize some + * of the new inode's fields + */ + + /* On revalidate we've already got our own inode and just need + * to fix it up. */ + if (flag == INTERPOSE_REVAL) { + inode = dentry->d_inode; + itopd(inode)->b_start = -1; + itopd(inode)->b_end = -1; + atomic_set(&itopd(inode)->uii_generation, + atomic_read(&stopd(sb)->usi_generation)); + + itohi_ptr(inode) = + KZALLOC(sbmax(sb) * sizeof(struct inode *), GFP_KERNEL); + if (!itohi_ptr(inode)) { + err = -ENOMEM; + goto out; + } + mutex_lock(&inode->i_mutex); + } else { + ino_t ino; + /* get unique inode number for unionfs */ +#ifdef UNIONFS_IMAP + if (stopd(sb)->usi_persistent) { + err = read_uin(sb, bindex, + dtohd_index(dentry, + bindex)->d_inode->i_ino, + O_CREAT, &ino); + if (err) + goto out; + } else +#endif + ino = iunique(sb, UNIONFS_ROOT_INO); + + inode = unionfs_iget(sb, ino); + if (IS_ERR(inode)) { + err = PTR_ERR(inode); + goto out; + } + + mutex_lock(&inode->i_mutex); + if (atomic_read(&inode->i_count) > 1) + goto skip; + } + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + set_itohi_index(inode, bindex, NULL); + continue; + } + /* Initialize the hidden inode to the new hidden inode. */ + if (!hidden_dentry->d_inode) + continue; + set_itohi_index(inode, bindex, IGRAB(hidden_dentry->d_inode)); + } + + ibstart(inode) = dbstart(dentry); + ibend(inode) = dbend(dentry); + + /* Use attributes from the first branch. */ + hidden_inode = itohi(inode); + + /* Use different set of inode ops for symlinks & directories */ + if (S_ISLNK(hidden_inode->i_mode)) + inode->i_op = &unionfs_symlink_iops; + else if (S_ISDIR(hidden_inode->i_mode)) + inode->i_op = &unionfs_dir_iops; + + /* Use different set of file ops for directories */ + if (S_ISDIR(hidden_inode->i_mode)) + inode->i_fop = &unionfs_dir_fops; + + /* properly initialize special inodes */ + if (S_ISBLK(hidden_inode->i_mode) || S_ISCHR(hidden_inode->i_mode) || + S_ISFIFO(hidden_inode->i_mode) || S_ISSOCK(hidden_inode->i_mode)) + init_special_inode(inode, hidden_inode->i_mode, + hidden_inode->i_rdev); +#ifndef UNIONFS_MMAP + /* Fix our inode's address operations to that of the lower inode (Unionfs is FiST-Lite) */ + if (inode->i_mapping->a_ops != hidden_inode->i_mapping->a_ops) { + dprint(PRINT_DEBUG, "fixing inode 0x%p a_ops (0x%p -> 0x%p)\n", + inode, inode->i_mapping->a_ops, + hidden_inode->i_mapping->a_ops); + inode->i_mapping->a_ops = hidden_inode->i_mapping->a_ops; + } +#endif + /* all well, copy inode attributes */ + fist_copy_attr_all(inode, hidden_inode); + + skip: + /* only (our) lookup wants to do a d_add */ + switch (flag) { + case INTERPOSE_DEFAULT: + case INTERPOSE_REVAL_NEG: + d_instantiate(dentry, inode); + break; + case INTERPOSE_LOOKUP: + err = PTR_ERR(d_splice_alias(inode, dentry)); + break; + case INTERPOSE_REVAL: + /* Do nothing. */ + break; + default: + printk(KERN_ERR "Invalid interpose flag passed!"); + BUG(); + } + + print_dentry("Leaving unionfs_interpose", dentry); + print_inode("Leaving unionfs_interpose", inode); + mutex_unlock(&inode->i_mutex); + + out: + print_exit_status(err); + return err; +} + +void unionfs_reinterpose(struct dentry *dentry) +{ + struct dentry *hidden_dentry; + struct inode *inode; + int bindex, bstart, bend; + + print_entry_location(); + verify_locked(dentry); + print_dentry("IN: unionfs_reinterpose: ", dentry); + + /* This is pre-allocated inode */ + inode = dentry->d_inode; + + bstart = dbstart(dentry); + bend = dbend(dentry); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + if (!hidden_dentry->d_inode) + continue; + if (itohi_index(inode, bindex)) + continue; + set_itohi_index(inode, bindex, IGRAB(hidden_dentry->d_inode)); + } + ibstart(inode) = dbstart(dentry); + ibend(inode) = dbend(dentry); + + print_dentry("OUT: unionfs_reinterpose: ", dentry); + print_inode("OUT: unionfs_reinterpose: ", inode); + + print_exit_location(); +} + +int check_branch(struct nameidata *nd) +{ + if (!strcmp(nd->path.dentry->d_sb->s_type->name, "unionfs")) + return -EINVAL; + if (!nd->path.dentry->d_inode) + return -ENOENT; + if (!S_ISDIR(nd->path.dentry->d_inode->i_mode)) + return -ENOTDIR; + return 0; +} + +/* checks if two hidden_dentries have overlapping branches */ +int is_branch_overlap(struct dentry *dent1, struct dentry *dent2) +{ + struct dentry *dent = NULL; + + dent = dent1; + while ((dent != dent2) && (dent->d_parent != dent)) { + dent = dent->d_parent; + } + if (dent == dent2) { + return 1; + } + + dent = dent2; + while ((dent != dent1) && (dent->d_parent != dent)) { + dent = dent->d_parent; + } + if (dent == dent1) { + return 1; + } + + return 0; +} +static int parse_branch_mode(char *name) +{ + int perms; + int l = strlen(name); + if (!strcmp(name + l - 3, "=ro")) { + perms = MAY_READ; + name[l - 3] = '\0'; + } else if (!strcmp(name + l - 6, "=nfsro")) { + perms = MAY_READ | MAY_NFSRO; + name[l - 6] = '\0'; + } else if (!strcmp(name + l - 3, "=rw")) { + perms = MAY_READ | MAY_WRITE; + name[l - 3] = '\0'; + } else { + perms = MAY_READ | MAY_WRITE; + } + + return perms; +} +static int get_separator_count(char *options, char *separator) +{ + char *token, *locopts, *locsep = NULL; + int count = 0; + /* + * We copy options so we dont destroy our pointer for parsing + */ + if (separator == NULL) { + locsep = KMALLOC(2, GFP_KERNEL); + if (!locsep) { + count = -ENOMEM; + goto out; + } + strcpy(locsep, ":"); + } else { + locsep = separator; + } + locopts = KMALLOC(strlen(options) + 1, GFP_KERNEL); + if (!locopts) { + count = -ENOMEM; + goto out; + } + strcpy(locopts, options); + while ((token = strsep(&locopts, locsep)) != NULL) + count++; + out: + KFREE(locopts); + return count; +} +static int parse_dirs_option(struct super_block *sb, struct unionfs_dentry_info + *hidden_root_info, char *options, char *separator) +{ + struct nameidata nd; + char *name, *locsep = NULL; + int err = 0; + int branches = 1; + int bindex = 0; + int i = 0; + int j = 0; + + struct dentry *dent1 = NULL; + struct dentry *dent2 = NULL; + + if (options[0] == '\0') { + printk(KERN_WARNING "unionfs: no branches specified\n"); + err = -EINVAL; + goto out; + } + /* + * Check to see if separator is specified otherwise use ':' + */ + if (separator == NULL) { + locsep = KMALLOC(2, GFP_KERNEL); + if (!locsep) { + err = -ENOMEM; + goto out; + } + strcpy(locsep, ":"); + } else { + locsep = separator; + } + branches = get_separator_count(options, separator); + /* allocate space for underlying pointers to hidden dentry */ + if (!(stopd(sb)->usi_data = alloc_new_data(branches))) { + err = -ENOMEM; + goto out; + } + + if (!(hidden_root_info->udi_dentry = alloc_new_dentries(branches))) { + err = -ENOMEM; + goto out; + } + + /* now parsing the string b1:b2=rw:b3=ro:b4 */ + branches = 0; + while ((name = strsep(&options, locsep)) != NULL) { + int perms; + + if (!*name) + continue; + branches++; + + /* strip off =rw or =ro if it is specified. */ + perms = parse_branch_mode(name); + if (!bindex && !(perms & MAY_WRITE)) { + err = -EINVAL; + goto out; + } + + dprint(PRINT_DEBUG, "using directory: %s (%c%c%c)\n", + name, perms & MAY_READ ? 'r' : '-', + perms & MAY_WRITE ? 'w' : '-', + perms & MAY_NFSRO ? 'n' : '-'); + + err = path_lookup(name, LOOKUP_FOLLOW, &nd); + RECORD_PATH_LOOKUP(&nd); + if (err) { + printk(KERN_WARNING "unionfs: error accessing " + "hidden directory '%s' (error %d)\n", name, err); + goto out; + } + + if ((err = check_branch(&nd))) { + printk(KERN_WARNING "unionfs: hidden directory " + "'%s' is not a valid branch\n", name); + path_put(&nd.path); + RECORD_PATH_RELEASE(&nd); + goto out; + } + + hidden_root_info->udi_dentry[bindex] = nd.path.dentry; + + set_stohiddenmnt_index(sb, bindex, nd.path.mnt); + set_branchperms(sb, bindex, perms); + set_branch_count(sb, bindex, 0); + + if (hidden_root_info->udi_bstart < 0) + hidden_root_info->udi_bstart = bindex; + hidden_root_info->udi_bend = bindex; + bindex++; + } + + if (branches == 0) { + printk(KERN_WARNING "unionfs: no branches specified\n"); + err = -EINVAL; + goto out; + } + + BUG_ON(branches != (hidden_root_info->udi_bend + 1)); + + /* ensure that no overlaps exist in the branches */ + for (i = 0; i < branches; i++) { + for (j = i + 1; j < branches; j++) { + dent1 = hidden_root_info->udi_dentry[i]; + dent2 = hidden_root_info->udi_dentry[j]; + + if (is_branch_overlap(dent1, dent2)) { + goto out_overlap; + } + } + } + + out_overlap: + + if (i != branches) { + printk(KERN_WARNING "unionfs: branches %d and %d overlap\n", i, + j); + err = -EINVAL; + goto out; + } + + out: + if (err) { + for (i = 0; i < branches; i++) { + if (hidden_root_info->udi_dentry[i]) + DPUT(hidden_root_info->udi_dentry[i]); + } + + KFREE(hidden_root_info->udi_dentry); + KFREE(stopd(sb)->usi_data); + + /* MUST clear the pointers to prevent potential double free if + * the caller dies later on + */ + hidden_root_info->udi_dentry = NULL; + stopd(sb)->usi_data = NULL; + } + if (!separator) + KFREE(locsep); + return err; +} + +/* + * Parse mount options. See the manual page for usage instructions. + * + * Returns the dentry object of the lower-level (hidden) directory; + * We want to mount our stackable file system on top of that hidden directory. + * + * Sets default debugging level to N, if any. + */ +static struct unionfs_dentry_info *unionfs_parse_options(struct super_block *sb, + char *options) +{ + struct unionfs_dentry_info *hidden_root_info; + char *optname, *separator = NULL; + int err = 0; + int bindex; + int sepfound = 0; + int dirsfound = 0; +#ifdef UNIONFS_IMAP + int imapfound = 0; +#endif + print_entry_location(); + + /* allocate private data area */ + err = -ENOMEM; + hidden_root_info = + KZALLOC(sizeof(struct unionfs_dentry_info), GFP_KERNEL); + if (!hidden_root_info) + goto out_error; + hidden_root_info->udi_bstart = -1; + hidden_root_info->udi_bend = -1; + hidden_root_info->udi_bopaque = -1; + + while ((optname = strsep(&options, ",")) != NULL) { + char *optarg; + char *endptr; + int intval; + + if (!*optname) { + continue; + } + + optarg = strchr(optname, '='); + if (optarg) { + *optarg++ = '\0'; + } + + /* All of our options take an argument now. Insert ones that + * don't, above this check. */ + if (!optarg) { + printk("unionfs: %s requires an argument.\n", optname); + err = -EINVAL; + goto out_error; + } + + if (!strcmp("dirs", optname)) { + if (++dirsfound > 1) { + printk(KERN_WARNING + "unionfs: multiple dirs specified\n"); + err = -EINVAL; + goto out_error; + } + err = + parse_dirs_option(sb, hidden_root_info, optarg, + separator); + if (err) + goto out_error; + continue; + } +#ifdef UNIONFS_IMAP + if (!strcmp("imap", optname)) { + if (++imapfound > 1) { + printk(KERN_WARNING + "unionfs: multiple imap specified\n"); + err = -EINVAL; + goto out_error; + } + err = parse_imap_option(sb, hidden_root_info, optarg); + if (err) + goto out_error; + continue; + } +#endif + if (!strcmp("delete", optname)) { + if (!strcmp("whiteout", optarg)) { + /* default */ +#ifdef UNIONFS_DELETE_ALL + } else if (!strcmp("all", optarg)) { + MOUNT_FLAG(sb) |= DELETE_ALL; +#endif + } else { + printk(KERN_WARNING + "unionfs: invalid delete option '%s'\n", + optarg); + err = -EINVAL; + goto out_error; + } + continue; + } + + if (!strcmp("separator", optname)) { + if (dirsfound) { + printk(KERN_WARNING + "unionfs: dirs= already parsed separator '%s' will have no effect\n", + optarg); + continue; + } + sepfound = 1; + separator = KMALLOC(strlen(optarg) + 1, GFP_KERNEL); + if (!separator) { + err = -ENOMEM; + goto out_error; + } + strcpy(separator, optarg); + continue; + } + /* All of these options require an integer argument. */ + intval = simple_strtoul(optarg, &endptr, 0); + if (*endptr) { + printk(KERN_WARNING + "unionfs: invalid %s option '%s'\n", + optname, optarg); + err = -EINVAL; + goto out_error; + } + + if (!strcmp("debug", optname)) { + set_debug_mask(intval); + continue; + } + + err = -EINVAL; + printk(KERN_WARNING + "unionfs: unrecognized option '%s'\n", optname); + goto out_error; + } + if (dirsfound != 1) { + printk(KERN_WARNING "unionfs: dirs option required\n"); + err = -EINVAL; + goto out_error; + } + goto out; + + out_error: + if (hidden_root_info && hidden_root_info->udi_dentry) { + for (bindex = hidden_root_info->udi_bstart; + bindex >= 0 && bindex <= hidden_root_info->udi_bend; + bindex++) { + struct dentry *d; + d = hidden_root_info->udi_dentry[bindex]; + DPUT(d); + if (stohiddenmnt_index(sb, bindex)) + mntput(stohiddenmnt_index(sb, bindex)); + } + } + + KFREE(hidden_root_info->udi_dentry); + KFREE(hidden_root_info); + + KFREE(stopd(sb)->usi_data); + stopd(sb)->usi_data = NULL; + + hidden_root_info = ERR_PTR(err); + KFREE(separator); + out: + print_exit_location(); + return hidden_root_info; +} + +static struct dentry *unionfs_d_alloc_root(struct super_block *sb) +{ + struct dentry *ret = NULL; + + if (sb) { + static const struct qstr name = {.name = "/",.len = 1 }; + + ret = d_alloc(NULL, &name); + if (ret) { + ret->d_op = &unionfs_dops; + ret->d_sb = sb; + ret->d_parent = ret; + } + } + return ret; +} + +static int unionfs_read_super(struct super_block *sb, void *raw_data, + int silent) +{ + int err = 0; + + struct unionfs_dentry_info *hidden_root_info = NULL; + int bindex, bstart, bend; + unsigned long long maxbytes; + + print_entry_location(); + + if (!raw_data) { + printk(KERN_WARNING + "unionfs_read_super: missing data argument\n"); + err = -EINVAL; + goto out; + } + + /* + * Allocate superblock private data + */ + stopd_lhs(sb) = KZALLOC(sizeof(struct unionfs_sb_info), GFP_KERNEL); + if (!stopd(sb)) { + printk(KERN_WARNING "%s: out of memory\n", __FUNCTION__); + err = -ENOMEM; + goto out; + } + stopd(sb)->b_end = -1; + atomic_set(&stopd(sb)->usi_generation, 1); + init_rwsem(&stopd(sb)->usi_rwsem); + + hidden_root_info = unionfs_parse_options(sb, raw_data); + if (IS_ERR(hidden_root_info)) { + printk(KERN_WARNING + "unionfs_read_super: error while parsing options (err = %ld)\n", + PTR_ERR(hidden_root_info)); + err = PTR_ERR(hidden_root_info); + hidden_root_info = NULL; + goto out_free; + } + if (hidden_root_info->udi_bstart == -1) { + err = -ENOENT; + goto out_free; + } + + /* set the hidden superblock field of upper superblock */ + bstart = hidden_root_info->udi_bstart; + BUG_ON(bstart != 0); + sbend(sb) = bend = hidden_root_info->udi_bend; + for (bindex = bstart; bindex <= bend; bindex++) { + struct dentry *d; + + d = hidden_root_info->udi_dentry[bindex]; + + set_stohs_index(sb, bindex, d->d_sb); + } + + /* Unionfs: Max Bytes is the maximum bytes from among all the branches */ + maxbytes = -1; + for (bindex = bstart; bindex <= bend; bindex++) + if (maxbytes < stohs_index(sb, bindex)->s_maxbytes) + maxbytes = stohs_index(sb, bindex)->s_maxbytes; + sb->s_maxbytes = maxbytes; + + sb->s_op = &unionfs_sops; +#ifdef CONFIG_EXPORTFS + sb->s_export_op = &unionfs_export_ops; +#endif + + /* + * we can't use d_alloc_root if we want to use + * our own interpose function unchanged, + * so we simply call our own "fake" d_alloc_root + */ + sb->s_root = unionfs_d_alloc_root(sb); + if (!sb->s_root) { + err = -ENOMEM; + goto out_dput; + } + + /* link the upper and lower dentries */ + dtopd_lhs(sb->s_root) = NULL; + if ((err = new_dentry_private_data(sb->s_root))) + goto out_freedpd; + + /* Set the hidden dentries for s_root */ + for (bindex = bstart; bindex <= bend; bindex++) { + struct dentry *d; + + d = hidden_root_info->udi_dentry[bindex]; + + set_dtohd_index(sb->s_root, bindex, d); + } + set_dbstart(sb->s_root, bstart); + set_dbend(sb->s_root, bend); + + /* Set the generation number to one, since this is for the mount. */ + atomic_set(&dtopd(sb->s_root)->udi_generation, 1); + + /* call interpose to create the upper level inode */ + if ((err = unionfs_interpose(sb->s_root, sb, 0))) + goto out_freedpd; + unlock_dentry(sb->s_root); + goto out; + + out_freedpd: + if (dtopd(sb->s_root)) { + KFREE(dtohd_ptr(sb->s_root)); + free_dentry_private_data(dtopd(sb->s_root)); + } + DPUT(sb->s_root); + out_dput: + if (hidden_root_info && !IS_ERR(hidden_root_info)) { + for (bindex = hidden_root_info->udi_bstart; + bindex <= hidden_root_info->udi_bend; bindex++) { + struct dentry *d; + + d = hidden_root_info->udi_dentry[bindex]; + + if (d) + DPUT(d); + + if (stopd(sb) && stohiddenmnt_index(sb, bindex)) + mntput(stohiddenmnt_index(sb, bindex)); + } + KFREE(hidden_root_info->udi_dentry); + KFREE(hidden_root_info); + hidden_root_info = NULL; + } + out_free: + KFREE(stopd(sb)->usi_data); + KFREE(stopd(sb)); + stopd_lhs(sb) = NULL; + out: + if (hidden_root_info && !IS_ERR(hidden_root_info)) { + KFREE(hidden_root_info->udi_dentry); + KFREE(hidden_root_info); + } + print_exit_status(err); + return err; +} + +static int unionfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, + void *raw_data, struct vfsmount *mnt) +{ + return get_sb_nodev(fs_type, flags, raw_data, unionfs_read_super, mnt); +} + +static struct file_system_type unionfs_fs_type = { + .owner = THIS_MODULE, + .name = "unionfs", + .get_sb = unionfs_get_sb, + .kill_sb = kill_anon_super, + .fs_flags = FS_REVAL_DOT, +}; + +static int init_debug = 0; +module_param_named(debug, init_debug, int, S_IRUGO); +MODULE_PARM_DESC(debug, "Initial Unionfs debug value."); + +static int __init init_unionfs_fs(void) +{ + int err; + printk("Registering unionfs " UNIONFS_VERSION "\n"); + + set_debug_mask(init_debug); + +#ifdef FIST_MALLOC_DEBUG + atomic_set(&unionfs_malloc_counter, 0); + atomic_set(&unionfs_mallocs_outstanding, 0); +#endif /* FIST_MALLOC_DEBUG */ + + if ((err = init_filldir_cache())) + goto out; + if ((err = init_inode_cache())) + goto out; + if ((err = init_dentry_cache())) + goto out; + if ((err = init_sioq())) + goto out; + err = register_filesystem(&unionfs_fs_type); + out: + if (err) { + fin_sioq(); + destroy_filldir_cache(); + destroy_inode_cache(); + destroy_dentry_cache(); + } + return err; +} +static void __exit exit_unionfs_fs(void) +{ + fin_sioq(); + destroy_filldir_cache(); + destroy_inode_cache(); + destroy_dentry_cache(); + unregister_filesystem(&unionfs_fs_type); + printk("Completed unionfs module unload.\n"); +} + +MODULE_AUTHOR + ("Filesystems and Storage Lab, Stony Brook University (http://www.fsl.cs.sunysb.edu/)"); +MODULE_DESCRIPTION("Unionfs " UNIONFS_VERSION + " (http://unionfs.filesystems.org/)"); +MODULE_LICENSE("GPL"); + +module_init(init_unionfs_fs); +module_exit(exit_unionfs_fs); +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/file.c +++ linux-2.6.28/ubuntu/unionfs/file.c @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: file.c,v 1.143 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* declarations for sparse */ +extern ssize_t unionfs_read(struct file *, char __user *, size_t, loff_t *); +extern ssize_t unionfs_write(struct file *, const char __user *, size_t, + loff_t *); + +/******************* + * File Operations * + *******************/ + +#ifndef UNIONFS_MMAP +/* SP: Disable unionfs_llseek, as use generic_file_llseek on upper file */ +static loff_t unionfs_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t err; + struct file *hidden_file = NULL; + + print_entry_location(); + + dprint(PRINT_DEBUG, "unionfs_llseek: file=%p, offset=0x%llx, origin=%d\n", + file, offset, origin); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + hidden_file = ftohf(file); + /* always set hidden position to this one */ + hidden_file->f_pos = file->f_pos; + + memcpy(&(hidden_file->f_ra), &(file->f_ra), + sizeof(struct file_ra_state)); + + if (hidden_file->f_op && hidden_file->f_op->llseek) + err = hidden_file->f_op->llseek(hidden_file, offset, origin); + else + err = generic_file_llseek(hidden_file, offset, origin); + + if (err < 0) + goto out; + if (err != file->f_pos) { + file->f_pos = err; + // ION maybe this? + // file->f_pos = hidden_file->f_pos; + + file->f_version++; + } + out: + print_exit_status((int)err); + return err; +} +#endif +ssize_t __unionfs_read(struct file * file, char __user * buf, size_t count, + loff_t * ppos) +{ + int err = -EINVAL; + struct file *hidden_file = NULL; + loff_t pos = *ppos; + + print_file("entering __unionfs_read()", file); + + hidden_file = ftohf(file); + if (!hidden_file->f_op || !hidden_file->f_op->read) + goto out; + + err = hidden_file->f_op->read(hidden_file, buf, count, &pos); + *ppos = pos; + + out: + print_file("leaving __unionfs_read()", file); + + print_exit_status(err); + return err; +} + +ssize_t unionfs_read(struct file * file, char __user * buf, size_t count, + loff_t * ppos) +{ + int err = -EINVAL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + +#ifdef UNIONFS_MMAP + err = generic_file_read(file, buf, count, ppos); + if (err >= 0) + file_accessed(ftohf(file)); +#else + err = __unionfs_read(file, buf, count, ppos); +#endif + + out: + + print_exit_status(err); + return err; +} + +/* SP: Sendfile code not updated, but should be able to use + * generic_file_sendfile, as it would use readpage, which we now have */ +#ifdef SUPPORT_BROKEN_LOSETUP +static ssize_t unionfs_sendfile(struct file *file, loff_t * ppos, + size_t count, read_actor_t actor, void *target) +{ + ssize_t err; + struct file *hidden_file = NULL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 0))) + goto out; + + hidden_file = ftohf(file); + + err = -EINVAL; + if (!hidden_file->f_op || !hidden_file->f_op->sendfile) + goto out; + + err = hidden_file->f_op->sendfile(hidden_file, ppos, count, actor, + target); + + out: + print_exit_status(err); + return err; +} +#endif +ssize_t __unionfs_write(struct file * file, const char __user * buf, + size_t count, loff_t * ppos) +{ + int err = -EINVAL; + struct file *hidden_file = NULL; + struct inode *inode; + struct inode *hidden_inode; + loff_t pos = *ppos; + int bstart, bend; + + print_entry_location(); + + inode = file->f_dentry->d_inode; + + bstart = fbstart(file); + bend = fbend(file); + + BUG_ON(bstart == -1); + + hidden_file = ftohf(file); + hidden_inode = hidden_file->f_dentry->d_inode; + + if (!hidden_file->f_op || !hidden_file->f_op->write) + goto out; + + /* adjust for append -- seek to the end of the file */ + if (file->f_flags & O_APPEND) + pos = inode->i_size; + + err = hidden_file->f_op->write(hidden_file, buf, count, &pos); + + /* + * copy ctime and mtime from lower layer attributes + * atime is unchanged for both layers + */ + if (err >= 0) + fist_copy_attr_times(inode, hidden_inode); + + *ppos = pos; + + /* update this inode's size */ + if (pos > inode->i_size) + inode->i_size = pos; + out: + print_exit_status(err); + return err; +} + +ssize_t unionfs_write(struct file * file, const char __user * buf, size_t count, + loff_t * ppos) +{ + int err = 0; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; +#ifdef UNIONFS_MMAP + err = generic_file_write(file, buf, count, ppos); +#else + err = __unionfs_write(file, buf, count, ppos); +#endif + out: + print_exit_status(err); + return err; +} + +static int unionfs_file_readdir(struct file *file, void *dirent, + filldir_t filldir) +{ + int err = -ENOTDIR; + print_entry_location(); + print_exit_status(err); + return err; +} + +static unsigned int unionfs_poll(struct file *file, poll_table * wait) +{ + unsigned int mask = DEFAULT_POLLMASK; + struct file *hidden_file = NULL; + + print_entry_location(); + + if (unionfs_file_revalidate(file, 0)) { + /* We should pretend an error happend. */ + mask = POLLERR | POLLIN | POLLOUT; + goto out; + } + + hidden_file = ftohf(file); + + if (!hidden_file->f_op || !hidden_file->f_op->poll) + goto out; + + mask = hidden_file->f_op->poll(hidden_file, wait); + + out: + print_exit_status(mask); + return mask; +} + +#ifndef UNIONFS_MMAP +static int __do_mmap(struct file *file, struct vm_area_struct *vma) +{ + int err; + struct file *hidden_file; + + print_entry_location(); + hidden_file = ftohf(file); + + err = -ENODEV; + if (!hidden_file->f_op || !hidden_file->f_op->mmap) + goto out; + + vma->vm_file = hidden_file; + err = hidden_file->f_op->mmap(hidden_file, vma); + get_file(hidden_file); /* make sure it doesn't get freed on us */ + fput(file); /* no need to keep extra ref on ours */ + out: + print_exit_status(err); + return err; +} +#endif +/* SP: mmap code now maps upper file + * like old code, will only copyup at this point, it's possible to copyup + * in writepage(), but I haven't bothered with that, as only apt-get seem + * to want to write to a shared/write mapping + */ +static int unionfs_mmap(struct file *file, struct vm_area_struct *vma) +{ + int err = 0; + int willwrite; + + print_entry_location(); + + /* This might could be deferred to mmap's writepage. */ + willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags); + if ((err = unionfs_file_revalidate(file, willwrite))) + goto out; +#ifdef UNIONFS_MMAP + err = generic_file_mmap(file, vma); + if (err) { + printk("unionfs_mmap: generic_file_mmap failed\n"); + } +#else + err = __do_mmap(file, vma); +#endif + + out: + print_exit_status(err); + return err; +} + +/* SP: disabled as use the generic file_fsync */ +#ifndef UNIONFS_MMAP +static int unionfs_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + int err; + struct file *hidden_file = NULL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + + hidden_file = ftohf(file); + + err = -EINVAL; + if (!hidden_file->f_op || !hidden_file->f_op->fsync) + goto out; + + mutex_lock(&hidden_file->f_dentry->d_inode->i_mutex); + err = hidden_file->f_op->fsync(hidden_file, hidden_file->f_dentry, + datasync); + mutex_unlock(&hidden_file->f_dentry->d_inode->i_mutex); + + out: + print_exit_status(err); + return err; +} +#endif + +/* SP: disabled as none of the other in kernel fs's seem to use it */ +static int unionfs_fasync(int fd, struct file *file, int flag) +{ + int err = 0; + struct file *hidden_file = NULL; + + print_entry_location(); + + if ((err = unionfs_file_revalidate(file, 1))) + goto out; + + hidden_file = ftohf(file); + + if (hidden_file->f_op && hidden_file->f_op->fasync) + err = hidden_file->f_op->fasync(fd, hidden_file, flag); + + out: + print_exit_status(err); + return err; +} + +struct file_operations unionfs_main_fops = { +#ifdef UNIONFS_MMAP + .llseek = generic_file_llseek, +#else + .llseek = unionfs_llseek, +#endif + .read = unionfs_read, + .write = unionfs_write, + .readdir = unionfs_file_readdir, + .poll = unionfs_poll, + .unlocked_ioctl = unionfs_ioctl, + .mmap = unionfs_mmap, + .open = unionfs_open, + .flush = unionfs_flush, + .release = unionfs_file_release, +#ifdef UNIONFS_MMAP + .fsync = file_fsync, +#else + .fsync = unionfs_fsync, +#endif + .fasync = unionfs_fasync, +#ifdef SUPPORT_BROKEN_LOSETUP + .sendfile = unionfs_sendfile, +#endif +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/sioq.h +++ linux-2.6.28/ubuntu/unionfs/sioq.h @@ -0,0 +1,80 @@ +#ifndef _SIOQ_H +#define _SIOQ_H + +struct deletewh_args { + struct unionfs_dir_state *namelist; + struct dentry *dentry; + int bindex; +}; + +struct isopaque_args { + struct dentry *dentry; +}; + +struct create_args { + struct inode *parent; + struct dentry *dentry; + umode_t mode; + struct nameidata *nd; +}; + +struct mkdir_args { + struct inode *parent; + struct dentry *dentry; + umode_t mode; +}; + +struct mknod_args { + struct inode *parent; + struct dentry *dentry; + umode_t mode; + dev_t dev; +}; + +struct symlink_args { + struct inode *parent; + struct dentry *dentry; + char *symbuf; + umode_t mode; +}; + +struct unlink_args { + struct inode *parent; + struct dentry *dentry; +}; + + +struct sioq_args { + + struct completion comp; + struct work_struct wk; + int err; + void *ret; + + union { + struct deletewh_args deletewh; + struct isopaque_args isopaque; + struct create_args create; + struct mkdir_args mkdir; + struct mknod_args mknod; + struct symlink_args symlink; + struct unlink_args unlink; + }; //} u; +}; + +extern struct workqueue_struct *sioq; +int __init init_sioq(void); +extern void fin_sioq(void); +extern void run_sioq(work_func_t func, struct sioq_args *args); + +/* Extern definitions for our privledge escalation helpers */ +extern void __unionfs_create(struct work_struct *work); +extern void __unionfs_mkdir(struct work_struct *work); +extern void __unionfs_mknod(struct work_struct *work); +extern void __unionfs_symlink(struct work_struct *work); +extern void __unionfs_unlink(struct work_struct *work); +extern void __delete_whiteouts(struct work_struct *work); +extern void __is_opaque_dir(struct work_struct *work); + +#endif /* _SIOQ_H */ + --- linux-2.6.28.orig/ubuntu/unionfs/dentry.c +++ linux-2.6.28/ubuntu/unionfs/dentry.c @@ -0,0 +1,282 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: dentry.c,v 1.77 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +/* declarations added for "sparse" */ +extern int unionfs_d_revalidate_wrap(struct dentry *dentry, + struct nameidata *nd); +extern void unionfs_d_release(struct dentry *dentry); +extern void unionfs_d_iput(struct dentry *dentry, struct inode *inode); + +/* + * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise. + */ +int unionfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) +{ + int valid = 1; /* default is valid (1); invalid is 0. */ + struct dentry *hidden_dentry; + int bindex, bstart, bend; + int sbgen, dgen; + int positive = 0; + int locked = 0; + int restart = 0; + int interpose_flag; + + struct nameidata lowernd; + + if(nd) + memcpy(&lowernd, nd, sizeof(struct nameidata)); + else + memset(&lowernd, 0, sizeof(struct nameidata)); + + print_util_entry_location(); + + restart: + verify_locked(dentry); + + /* if the dentry is unhashed, do NOT revalidate */ + if (d_deleted(dentry)) { + dprint(PRINT_DEBUG, "unhashed dentry being revalidated: %*s\n", + dentry->d_name.len, dentry->d_name.name); + goto out; + } + + BUG_ON(dbstart(dentry) == -1); + if (dentry->d_inode) + positive = 1; + dgen = atomic_read(&dtopd(dentry)->udi_generation); + sbgen = atomic_read(&stopd(dentry->d_sb)->usi_generation); + /* If we are working on an unconnected dentry, then there is no + * revalidation to be done, because this file does not exist within the + * namespace, and Unionfs operates on the namespace, not data. + */ + if (sbgen != dgen) { + struct dentry *result; + int pdgen; + + unionfs_read_lock(dentry->d_sb); + locked = 1; + + /* The root entry should always be valid */ + BUG_ON(IS_ROOT(dentry)); + + /* We can't work correctly if our parent isn't valid. */ + pdgen = atomic_read(&dtopd(dentry->d_parent)->udi_generation); + if (!restart && (pdgen != sbgen)) { + unionfs_read_unlock(dentry->d_sb); + locked = 0; + /* We must be locked before our parent. */ + if (! + (dentry->d_parent->d_op-> + d_revalidate(dentry->d_parent, nd))) { + valid = 0; + goto out; + } + restart = 1; + goto restart; + } + BUG_ON(pdgen != sbgen); + + /* Free the pointers for our inodes and this dentry. */ + bstart = dbstart(dentry); + bend = dbend(dentry); + if (bstart >= 0) { + struct dentry *hidden_dentry; + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = + dtohd_index_nocheck(dentry, bindex); + if (!hidden_dentry) + continue; + DPUT(hidden_dentry); + } + } + set_dbstart(dentry, -1); + set_dbend(dentry, -1); + + interpose_flag = INTERPOSE_REVAL_NEG; + if (positive) { + interpose_flag = INTERPOSE_REVAL; + mutex_lock(&dentry->d_inode->i_mutex); + bstart = ibstart(dentry->d_inode); + bend = ibend(dentry->d_inode); + if (bstart >= 0) { + struct inode *hidden_inode; + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_inode = + itohi_index(dentry->d_inode, + bindex); + if (!hidden_inode) + continue; + IPUT(hidden_inode); + } + } + KFREE(itohi_ptr(dentry->d_inode)); + itohi_ptr(dentry->d_inode) = NULL; + ibstart(dentry->d_inode) = -1; + ibend(dentry->d_inode) = -1; + mutex_unlock(&dentry->d_inode->i_mutex); + } + + result = unionfs_lookup_backend(dentry, &lowernd, interpose_flag); + if (result) { + if (IS_ERR(result)) { + valid = 0; + goto out; + } + /* current unionfs_lookup_backend() doesn't return + a valid dentry */ + DPUT(dentry); + dentry = result; + } + + if (positive && itopd(dentry->d_inode)->uii_stale) { + make_stale_inode(dentry->d_inode); + d_drop(dentry); + valid = 0; + goto out; + } + goto out; + } + + /* The revalidation must occur across all branches */ + bstart = dbstart(dentry); + bend = dbend(dentry); + BUG_ON(bstart == -1); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry || !hidden_dentry->d_op + || !hidden_dentry->d_op->d_revalidate) + continue; + + if (!hidden_dentry->d_op->d_revalidate(hidden_dentry, nd)) + valid = 0; + } + + if (!dentry->d_inode) + valid = 0; + if (valid) + fist_copy_attr_all(dentry->d_inode, itohi(dentry->d_inode)); + + out: + if (locked) + unionfs_read_unlock(dentry->d_sb); + print_dentry("revalidate out", dentry); + print_util_exit_status(valid); + return valid; +} + +int unionfs_d_revalidate_wrap(struct dentry *dentry, struct nameidata *nd) +{ + int err; + + print_entry_location(); + lock_dentry(dentry); + + err = unionfs_d_revalidate(dentry, nd); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +void unionfs_d_release(struct dentry *dentry) +{ + struct dentry *hidden_dentry; + int bindex, bstart, bend; + + print_entry_location(); + /* There is no reason to lock the dentry, because we have the only + * reference, but the printing functions verify that we have a lock + * on the dentry before calling dbstart, etc. */ + lock_dentry(dentry); + print_dentry_nocheck("unionfs_d_release IN dentry", dentry); + + /* this could be a negative dentry, so check first */ + if (!dtopd(dentry)) { + dprint(PRINT_DEBUG, "dentry without private data: %*s", + dentry->d_name.len, dentry->d_name.name); + goto out; + } else if (dbstart(dentry) < 0) { + /* this is due to a failed lookup */ + /* the failed lookup has a dtohd_ptr set to null, + but this is a better check */ + dprint(PRINT_DEBUG, "dentry without hidden dentries : %*s", + dentry->d_name.len, dentry->d_name.name); + goto out_free; + } + + /* Release all the hidden dentries */ + bstart = dbstart(dentry); + bend = dbend(dentry); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + DPUT(hidden_dentry); + set_dtohd_index(dentry, bindex, NULL); + } + /* free private data (unionfs_dentry_info) here */ + KFREE(dtohd_ptr(dentry)); + dtohd_ptr(dentry) = NULL; + out_free: + /* No need to unlock it, because it is disappeared. */ +#ifdef TRACKLOCK + printk("DESTROYLOCK:%p\n", dentry); +#endif + free_dentry_private_data(dtopd(dentry)); + dtopd_lhs(dentry) = NULL; /* just to be safe */ + out: + print_exit_location(); +} + +/* + * we don't really need unionfs_d_iput, because dentry_iput will call iput() if + * unionfs_d_iput is not defined. We left this implemented for ease of + * tracing/debugging. + */ +void unionfs_d_iput(struct dentry *dentry, struct inode *inode) +{ + print_entry_location(); + IPUT(inode); + print_exit_location(); +} + +struct dentry_operations unionfs_dops = { + .d_revalidate = unionfs_d_revalidate_wrap, + .d_release = unionfs_d_release, + .d_iput = unionfs_d_iput, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/unionfs_imap.h +++ linux-2.6.28/ubuntu/unionfs/unionfs_imap.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unionfs_imap.h,v 1.1 2006/05/30 21:38:45 jsipek Exp $ + */ + +#ifndef __UNIONFS_H_ +#error This file should only be included from unionfs.h! +#endif + +#ifdef UNIONFS_IMAP + +/*UUID typedef needed later*/ +typedef uint8_t uuid_t[16]; + +/* +* Defines,structs,and functions for persistent used by kernel and user +*/ +#define MAX_MAPS 256 +#define UUID_LEN 16 +#define FORWARDMAP_MAGIC 0x4b1cb38f +#define REVERSEMAP_MAGIC 0Xfcafad71 +#define FORWARDMAP_VERSION 0x02 +#define REVERSEMAP_VERSION 0x01 +#define FIRST_VALID_INODE 3 +struct fmaphdr { + uint32_t magic; + uint32_t version; + uint8_t usedbranches; + uint8_t uuid[UUID_LEN]; +}; + +struct rmaphdr { + uint32_t magic; + uint32_t version; + uint8_t fwduuid[UUID_LEN]; + uint8_t revuuid[UUID_LEN]; + fsid_t fsid; +}; +struct bmapent { + fsid_t fsid; + uint8_t uuid[UUID_LEN]; +}; +struct fmapent { + uint8_t fsnum; + uint64_t inode; +}; + +/* Persistant Inode functions */ +extern int read_uin(struct super_block *sb, uint8_t branchnum, + ino_t inode_number, int flag, ino_t * uino); +extern int write_uin(struct super_block *sb, ino_t ino, int bindex, + ino_t hidden_ino); +extern int get_lin(struct super_block *sb, ino_t inode_number, + struct fmapent *entry); +extern int parse_imap_option(struct super_block *sb, + struct unionfs_dentry_info *hidden_root_info, + char *options); +extern void cleanup_imap_data(struct super_block *sb); + +#endif /*#ifdef UNIONFS_IMAP */ + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/Kconfig +++ linux-2.6.28/ubuntu/unionfs/Kconfig @@ -0,0 +1,9 @@ +config FS_UNIONFS + tristate "UnionFS 1.4 Legacy" + default m + help + This is the v1.4 module, forward ported and beaten into + AppArmor submission. It is a fallback for aufs in case it ends + up being broken. We know this one works for the LiveCD, so + this is to keep the release managers from having to spend + long nights and pushing off deadlines. --- linux-2.6.28.orig/ubuntu/unionfs/sioq.c +++ linux-2.6.28/ubuntu/unionfs/sioq.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2004-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ + +#include "unionfs.h" + +struct workqueue_struct *sioq; + +int __init init_sioq(void) +{ + int err; + + sioq = create_workqueue("unionfs_siod"); + if (!IS_ERR(sioq)) + return 0; + + err = PTR_ERR(sioq); + printk(KERN_ERR "create_workqueue failed %d\n", err); + sioq = NULL; + return err; +} + +void fin_sioq(void) +{ + if (sioq) + destroy_workqueue(sioq); +} + +void run_sioq(work_func_t func, struct sioq_args *args) +{ + INIT_WORK(&args->wk, func); + + init_completion(&args->comp); + while (!queue_work(sioq, &args->wk)) { + // TODO: do accounting if needed + schedule(); + } + wait_for_completion(&args->comp); +} + +void __unionfs_create(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct create_args *c = &args->create; + args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd); + complete(&args->comp); +} + +void __unionfs_mkdir(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct mkdir_args *m = &args->mkdir; + args->err = vfs_mkdir(m->parent, m->dentry, NULL, m->mode); + complete(&args->comp); +} + +void __unionfs_mknod(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct mknod_args *m = &args->mknod; + args->err = vfs_mknod(m->parent, m->dentry, NULL, m->mode, m->dev); + complete(&args->comp); +} +void __unionfs_symlink(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct symlink_args *s = &args->symlink; + args->err = vfs_symlink(s->parent, s->dentry, NULL, s->symbuf); + complete(&args->comp); +} + +void __unionfs_unlink(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct unlink_args *u = &args->unlink; + args->err = vfs_unlink(u->parent, u->dentry, NULL); + complete(&args->comp); +} + +void __delete_whiteouts(struct work_struct *work) { + struct sioq_args *args = container_of(work, struct sioq_args, wk); + struct deletewh_args *d = &args->deletewh; + args->err = delete_whiteouts(d->dentry, d->bindex, d->namelist); + complete(&args->comp); +} + +void __is_opaque_dir(struct work_struct *work) +{ + struct sioq_args *args = container_of(work, struct sioq_args, wk); + + args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE, args->isopaque.dentry, + sizeof(UNIONFS_DIR_OPAQUE) - 1); + complete(&args->comp); +} --- linux-2.6.28.orig/ubuntu/unionfs/unlink.c +++ linux-2.6.28/ubuntu/unionfs/unlink.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unlink.c,v 1.44 2006/08/05 01:28:46 jro Exp $ + */ + +#include "unionfs.h" + +#ifdef UNIONFS_DELETE_ALL +static int unionfs_unlink_all(struct inode *dir, struct dentry *dentry) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry; + int bstart, bend, bindex; + int err = 0; + int global_err = 0; + + print_entry_location(); + + if ((err = unionfs_partial_lookup(dentry))) + goto out; + + bstart = dbstart(dentry); + bend = dbend(dentry); + + for (bindex = bend; bindex >= bstart; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + hidden_dir_dentry = lock_parent(hidden_dentry); + + /* avoid destroying the hidden inode if the file is in use */ + DGET(hidden_dentry); + if (!(err = is_robranch_super(dentry->d_sb, bindex))) + err = vfs_unlink(hidden_dir_dentry->d_inode, + hidden_dentry, NULL); + DPUT(hidden_dentry); + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + unlock_dir(hidden_dir_dentry); + + if (err) { + /* passup the last error we got */ + if (!IS_COPYUP_ERR(err)) + goto out; + global_err = err; + } + } + + /* check if encountered error in the above loop */ + if (global_err) { + /* If we failed in the leftmost branch, then err will be set + * and we should move one over to create the whiteout. + * Otherwise, we should try in the leftmost branch. */ + if (err) { + if (dbstart(dentry) == 0) { + goto out; + } + err = create_whiteout(dentry, dbstart(dentry) - 1); + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + } else if (dbopaque(dentry) != -1) { + /* There is a hidden lower-priority file with the same name. */ + err = create_whiteout(dentry, dbopaque(dentry)); + } + out: + /* propagate number of hard-links */ + if (dentry->d_inode->i_nlink != 0) { + dentry->d_inode->i_nlink = get_nlinks(dentry->d_inode); + if (!err && global_err) + dentry->d_inode->i_nlink--; + } + /* We don't want to leave negative leftover dentries for revalidate. */ + if (!err && (global_err || dbopaque(dentry) != -1)) + update_bstart(dentry); + + print_exit_status(err); + return err; +} +#endif +static int unionfs_unlink_whiteout(struct inode *dir, struct dentry *dentry) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry; + int bindex; + int err = 0; + + print_entry_location(); + + if ((err = unionfs_partial_lookup(dentry))) + goto out; + + bindex = dbstart(dentry); + + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + goto out; + + hidden_dir_dentry = lock_parent(hidden_dentry); + + /* avoid destroying the hidden inode if the file is in use */ + DGET(hidden_dentry); + if (!(err = is_robranch_super(dentry->d_sb, bindex))) + err = vfs_unlink(hidden_dir_dentry->d_inode, hidden_dentry, + NULL); + DPUT(hidden_dentry); + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + unlock_dir(hidden_dir_dentry); + + if (err && !IS_COPYUP_ERR(err)) + goto out; + + if (err) { + if (dbstart(dentry) == 0) + goto out; + + err = create_whiteout(dentry, dbstart(dentry) - 1); + } else if (dbopaque(dentry) != -1) { + /* There is a hidden lower-priority file with the same name. */ + err = create_whiteout(dentry, dbopaque(dentry)); + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + + out: + if (!err) + dentry->d_inode->i_nlink--; + + /* We don't want to leave negative leftover dentries for revalidate. */ + if (!err && (dbopaque(dentry) != -1)) + update_bstart(dentry); + + print_exit_status(err); + return err; + +} + +int unionfs_unlink(struct inode *dir, struct dentry *dentry) +{ + int err = 0; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_unlink", dentry); + +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(dir->i_sb, DELETE_ALL)) + err = unionfs_unlink_all(dir, dentry); + else +#endif + err = unionfs_unlink_whiteout(dir, dentry); + /* call d_drop so the system "forgets" about us */ + if (!err) + d_drop(dentry); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +static int unionfs_rmdir_first(struct inode *dir, struct dentry *dentry, + struct unionfs_dir_state *namelist) +{ + int err; + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry = NULL; + + print_entry_location(); + print_dentry("IN unionfs_rmdir_first: ", dentry); + + /* Here we need to remove whiteout entries. */ + err = delete_whiteouts(dentry, dbstart(dentry), namelist); + if (err) { + goto out; + } + + hidden_dentry = dtohd(dentry); + + hidden_dir_dentry = lock_parent(hidden_dentry); + + /* avoid destroying the hidden inode if the file is in use */ + DGET(hidden_dentry); + if (!(err = is_robranch(dentry))) { + err = vfs_rmdir(hidden_dir_dentry->d_inode, hidden_dentry, + NULL); + } + DPUT(hidden_dentry); + + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + /* propagate number of hard-links */ + dentry->d_inode->i_nlink = get_nlinks(dentry->d_inode); + + out: + if (hidden_dir_dentry) { + unlock_dir(hidden_dir_dentry); + } + print_dentry("OUT unionfs_rmdir_first: ", dentry); + print_exit_status(err); + return err; +} + +#ifdef UNIONFS_DELETE_ALL +static int unionfs_rmdir_all(struct inode *dir, struct dentry *dentry, + struct unionfs_dir_state *namelist) +{ + struct dentry *hidden_dentry; + struct dentry *hidden_dir_dentry; + int bstart, bend, bindex; + int err = 0; + int global_err = 0; + + print_entry_location(); + print_dentry("IN unionfs_rmdir_all: ", dentry); + + bstart = dbstart(dentry); + bend = dbend(dentry); + + for (bindex = bend; bindex >= bstart; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + + hidden_dir_dentry = lock_parent(hidden_dentry); + if (S_ISDIR(hidden_dentry->d_inode->i_mode)) { + err = delete_whiteouts(dentry, bindex, namelist); + if (!err + && !(err = + is_robranch_super(dentry->d_sb, bindex))) { + err = + vfs_rmdir(hidden_dir_dentry->d_inode, + hidden_dentry, NULL); + } + } else { + err = -EISDIR; + } + + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + unlock_dir(hidden_dir_dentry); + if (err) { + int local_err = + unionfs_refresh_hidden_dentry(dentry, bindex); + if (local_err) { + err = local_err; + goto out; + } + + if (!IS_COPYUP_ERR(err) && err != -ENOTEMPTY + && err != -EISDIR) + goto out; + + global_err = err; + } + } + + /* check if encountered error in the above loop */ + if (global_err) { + /* If we failed in the leftmost branch, then err will be set and we should + * move one over to create the whiteout. Otherwise, we should try in the + * leftmost branch. + */ + if (err) { + if (dbstart(dentry) == 0) { + goto out; + } + err = create_whiteout(dentry, dbstart(dentry) - 1); + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + } else { + err = create_whiteout(dentry, dbstart(dentry)); + } + + out: + /* propagate number of hard-links */ + dentry->d_inode->i_nlink = get_nlinks(dentry->d_inode); + + print_dentry("OUT unionfs_rmdir_all: ", dentry); + print_exit_status(err); + return err; +} +#endif +int unionfs_rmdir(struct inode *dir, struct dentry *dentry) +{ + int err = 0; + struct unionfs_dir_state *namelist = NULL; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_rmdir: ", dentry); + + /* check if this unionfs directory is empty or not */ + err = check_empty(dentry, &namelist); + if (err) { +#if 0 + /* vfs_rmdir(our caller) unhashed the dentry. This will recover + * the Unionfs inode number for the directory itself, but the + * children are already lost. It seems that tmpfs manages its + * way around this by upping the refcount on everything. + * + * Even if we do this, we still lose the inode numbers of the + * children. The best way to fix this is to fix the VFS (or + * use persistent inode maps). */ + if (d_unhashed(dentry)) + d_rehash(dentry); +#endif + goto out; + } +#ifdef UNIONFS_DELETE_ALL + if (IS_SET(dir->i_sb, DELETE_ALL)) { + /* delete all. */ + err = unionfs_rmdir_all(dir, dentry, namelist); + } else { /* Delete the first directory. */ +#endif + err = unionfs_rmdir_first(dir, dentry, namelist); + /* create whiteout */ + if (!err) { + err = create_whiteout(dentry, dbstart(dentry)); + } else { + int new_err; + + if (dbstart(dentry) == 0) + goto out; + + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + + new_err = create_whiteout(dentry, dbstart(dentry) - 1); + if (new_err != -EEXIST) + err = new_err; + } + +#ifdef UNIONFS_DELETE_ALL + } +#endif + out: + /* call d_drop so the system "forgets" about us */ + if (!err) + d_drop(dentry); + + if (namelist) + free_rdstate(namelist); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/persistent_inode.c +++ linux-2.6.28/ubuntu/unionfs/persistent_inode.c @@ -0,0 +1,658 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: persistent_inode.c,v 1.36 2006/07/08 17:58:31 ezk Exp $ + */ +#ifdef UNIONFS_IMAP + +#include "unionfs.h" + +static ssize_t __fread(struct file *filp, void *buf, size_t size, loff_t * pos) +{ + int err; + mm_segment_t oldfs; + ssize_t(*func) (struct file *, char __user *, size_t, loff_t *); + + func = do_sync_read; + if (filp->f_op && filp->f_op->read) + func = filp->f_op->read; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + err = func(filp, (char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + return err; +} + +static ssize_t __fwrite(struct file *filp, void *buf, size_t size, loff_t * pos) +{ + int err; + mm_segment_t oldfs; + unsigned long flim; + struct rlimit *rl; + ssize_t(*func) (struct file *, const char __user *, size_t, loff_t *); + + func = do_sync_write; + if (filp->f_op && filp->f_op->write) + func = filp->f_op->write; + + /* + * it breaks RLIMIT_FSIZE, + * but users should be careful to quota. + */ + rl = current->signal->rlim + RLIMIT_FSIZE; + flim = rl->rlim_cur; + rl->rlim_cur = RLIM_INFINITY; + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + err = func(filp, (const char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + rl->rlim_cur = flim; + return err; +} + +/* + * verify_forwardmap(super_block *sb) + * sb: pointer to a superblock containing the forwardmap. + * returns: 0 on success EINVAL or ENOMEM on failure; + */ +static int verify_forwardmap(struct super_block *sb) +{ + int err = 0, bytesread = 0, bindex = 0, mallocsize = 0; + loff_t readpos = 0; + struct file *forwardmap = NULL; + struct fmaphdr header; + struct unionfs_sb_info *spd = NULL; + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + forwardmap = spd->usi_forwardmap; + if (!forwardmap) { + err = -EINVAL; + goto out; + } + bytesread = __fread(forwardmap, &header, sizeof(struct fmaphdr), + &readpos); + if (bytesread < sizeof(struct fmaphdr)) { + err = -EINVAL; + goto out; + } + if (header.magic != FORWARDMAP_MAGIC + || header.version != FORWARDMAP_VERSION) { + err = -EINVAL; + goto out; + } + spd->usi_bmap = + KMALLOC(sizeof(struct bmapent) * header.usedbranches, GFP_KERNEL); + + if (!spd->usi_bmap) { + err = -ENOMEM; + goto out; + } + + while (bindex < header.usedbranches) { + bytesread = __fread(forwardmap, &stopd(sb)->usi_bmap[bindex], + sizeof(struct bmapent), &readpos); + if (bytesread < sizeof(struct bmapent)) { + err = -EINVAL; + goto out_err; + } + bindex++; + } + + mallocsize = sizeof(int) * header.usedbranches; + goto out; + out_err: + if (spd->usi_bmap) + KFREE(spd->usi_bmap); + out: + print_exit_status(err); + return err; +} + +/* + * verify_reversemap(struct super_block sb, int rmapindex) + * + * sb: The unionfs superblock containing all of the current imap info + * rmapindex: the index in the usi_reversemaps array that we wish to + * verify + * + * Assumes the reverse maps less than rmapindex are valid. + * + * returns: 0 if the opperation succeds + * -EINVAL if the map file does not belong to the forward map + * + */ +static int verify_reversemap(struct super_block *sb, int rmapindex, + struct unionfs_dentry_info *hidden_root_info) +{ + int err = 0, i = 0, bindex = 0, found = 0, bytesread; + loff_t readpos = 0; + struct file *forwardmap, *reversemap; + struct fmaphdr fheader; + struct rmaphdr rheader; + struct kstatfs st; + struct unionfs_sb_info *spd = NULL; + + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + forwardmap = spd->usi_forwardmap; + if (!forwardmap) { + err = -EINVAL; + goto out; + } + reversemap = spd->usi_reversemaps[rmapindex]; + if (!reversemap) { + err = -EINVAL; + goto out; + } + bytesread = __fread(forwardmap, &fheader, sizeof(struct fmaphdr), + &readpos); + if (bytesread < sizeof(struct fmaphdr)) { + err = -EINVAL; + goto out; + } + readpos = 0; + bytesread = __fread(reversemap, &rheader, sizeof(struct rmaphdr), + &readpos); + if (bytesread < sizeof(struct rmaphdr)) { + err = -EINVAL; + goto out; + } + if (rheader.magic != REVERSEMAP_MAGIC + || rheader.version != REVERSEMAP_VERSION) { + err = -EINVAL; + goto out; + } + if (memcmp(fheader.uuid, rheader.fwduuid, sizeof(fheader.uuid))) { + err = -EINVAL; + goto out; + } + + /* XXX: Ok so here we take the new map and read the fsid from it. Then + * we go through all the branches in the union and see which ones it + * matches with*/ + for (i = 0; i < spd->usi_num_bmapents && !found; i++) { + if (memcmp + (rheader.revuuid, spd->usi_bmap[i].uuid, + sizeof(rheader.revuuid))) + continue; + + found = 1; + for (bindex = 0; bindex <= hidden_root_info->udi_bend; bindex++) { + struct dentry *d; + fsid_t fsid; + dev_t dev; + memset(&st, 0, sizeof(struct kstatfs)); + + d = hidden_root_info->udi_dentry[bindex]; + + err = d->d_sb->s_op->statfs(d->d_sb, &st); + if (err) + goto out; + + if (st.f_fsid.val[0] || st.f_fsid.val[1]) { + fsid = st.f_fsid; + } else { + + dev = d->d_sb->s_dev; + fsid.val[0] = MAJOR(dev); + fsid.val[1] = MINOR(dev); + } + + if (memcmp(&fsid, &rheader.fsid, sizeof(fsid))) + continue; + + if (spd->usi_bnum_table[bindex] == -1) + spd->usi_bnum_table[bindex] = i; + if (spd->usi_map_table[bindex]) { + printk(KERN_WARNING + "Two reverse maps share fsid %u%u!\n", + rheader.fsid.val[0], + rheader.fsid.val[1]); + err = -EINVAL; + goto out; + } else { + spd->usi_map_table[bindex] = reversemap; + } + } + } + if (!found) { + printk(KERN_WARNING + "Could not match the reversemap uuid with an entry in the forwardmap table\n"); + err = -EINVAL; + } + out: + print_exit_status(err); + return err; +} + +int init_imap_data(struct super_block *sb, + struct unionfs_dentry_info *hidden_root_info) +{ + int i, err = 0, mallocsize = 0; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + + spd->usi_forwardmap = NULL; + spd->usi_reversemaps = NULL; + spd->usi_bnum_table = NULL; + + mallocsize = sizeof(struct file *) * (hidden_root_info->udi_bend + 1); + spd->usi_reversemaps = KZALLOC(mallocsize, GFP_KERNEL); + if (!spd->usi_reversemaps) { + err = -ENOMEM; + goto out_error; + } + + spd->usi_map_table = KZALLOC(mallocsize, GFP_KERNEL); + if (!spd->usi_map_table) { + err = -ENOMEM; + goto out_error; + } + + mallocsize = sizeof(int) * (hidden_root_info->udi_bend + 1); + spd->usi_bnum_table = KMALLOC(mallocsize, GFP_KERNEL); + if (!spd->usi_bnum_table) { + err = -ENOMEM; + goto out_error; + } + + for (i = 0; i <= hidden_root_info->udi_bend; i++) { + spd->usi_bnum_table[i] = -1; + } + + if (!err) + goto out; + out_error: + + if (spd->usi_reversemaps) { + KFREE(spd->usi_reversemaps); + spd->usi_reversemaps = NULL; + } + + if (spd->usi_map_table) { + KFREE(spd->usi_map_table); + spd->usi_map_table = NULL; + } + + if (spd->usi_bnum_table) { + KFREE(spd->usi_bnum_table); + spd->usi_bnum_table = NULL; + + } + + out: + print_exit_status(err); + return err; + +} + +void cleanup_imap_data(struct super_block *sb) +{ + int count = 0; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + + spd->usi_persistent = 0; + count = spd->usi_num_bmapents; + while (count - 1 >= 0) { + if (spd->usi_reversemaps[count - 1]) { + filp_close(spd->usi_reversemaps[count - 1], NULL); + spd->usi_reversemaps[count - 1] = NULL; + } + count--; + } + if (spd->usi_reversemaps) { + KFREE(spd->usi_reversemaps); + spd->usi_reversemaps = NULL; + } + + if (spd->usi_map_table) { + KFREE(spd->usi_map_table); + spd->usi_map_table = NULL; + } + + if (spd->usi_bnum_table) { + KFREE(spd->usi_bnum_table); + spd->usi_bnum_table = NULL; + } + if (spd->usi_forwardmap) { + filp_close(spd->usi_forwardmap, NULL); + spd->usi_forwardmap = NULL; + } + print_exit_location(); +} + +int parse_imap_option(struct super_block *sb, + struct unionfs_dentry_info *hidden_root_info, + char *options) +{ + int count = 0, err = 0; + char *name; + struct unionfs_sb_info *spd = NULL; + + print_entry_location(); + spd = stopd(sb); + BUG_ON(!spd); + + err = init_imap_data(sb, hidden_root_info); + if (err) + goto out_error; + while ((name = strsep(&options, ":")) != NULL) { + if (!*name) + continue; + if (!spd->usi_forwardmap) { + spd->usi_forwardmap = filp_open(name, O_RDWR, 0); + if (IS_ERR(spd->usi_forwardmap)) { + err = PTR_ERR(spd->usi_forwardmap); + spd->usi_forwardmap = NULL; + goto out_error; + } + } else { + spd->usi_reversemaps[count] = + filp_open(name, O_RDWR, 0); + if (IS_ERR(spd->usi_reversemaps[count])) { + err = PTR_ERR(spd->usi_reversemaps[count]); + spd->usi_reversemaps[count] = NULL; + goto out_error; + + } + count++; + } + } + if (count <= 0) { + printk(KERN_WARNING "unionfs: no reverse maps specified.\n"); + err = -EINVAL; + } + if (err) + goto out_error; + + /* Initialize the super block's next_avail field */ + /* Dave, you can't use 64-bit division here because the i386 doesn't + * support it natively. Instead you need to punt if the size is + * greater than unsigned long, and then cast it down. Then you should + * be able to assign to this value, without having these problems. */ + + if (spd->usi_forwardmap->f_dentry->d_inode->i_size > ULONG_MAX) { + err = -EFBIG; + goto out_error; + } + spd->usi_next_avail = + ((unsigned long)(spd->usi_forwardmap->f_dentry->d_inode-> + i_size - (sizeof(struct fmaphdr) + + sizeof(struct bmapent[256]))) + / sizeof(struct fmapent)); + + if (spd->usi_next_avail < FIRST_VALID_INODE) + spd->usi_next_avail = FIRST_VALID_INODE; + + spd->usi_num_bmapents = count; + err = verify_forwardmap(sb); + if (err) + goto out_error; + while (count > 0) { + err = verify_reversemap(sb, --count, hidden_root_info); + if (err) + goto out_error; + } + spd->usi_persistent = 1; + + goto out; + + out_error: + spd->usi_num_bmapents = count; + cleanup_imap_data(sb); + + out: + print_exit_status(err); + return err; +} + + /* + * get @ino from @hidden_ino. + */ +static int __read_uin(struct unionfs_sb_info *sbi, ino_t hidden_ino, int bindex, + ino_t * ino) +{ + int err; + struct file *rev; + loff_t pos; + ssize_t sz; + uint64_t ino64; + const int elmnt = sizeof(ino64); + + rev = sbi->usi_map_table[bindex]; + pos = sizeof(struct rmaphdr) + elmnt * hidden_ino; + *ino = 0; + err = 0; + if (pos + elmnt > rev->f_dentry->d_inode->i_size) + goto out; + + sz = __fread(rev, &ino64, elmnt, &pos); + err = sz; + if (err < 0) + goto out; + err = 0; + *ino = -1; + if (sz != elmnt || ino64 > *ino) + err = -EIO; + *ino = ino64; + out: + print_exit_status(err); + return err; +} + +/* + * put unionfs @ino for @hidden_ino on @bindex. + */ +static int __write_uin(struct unionfs_sb_info *sbi, ino_t ino, int bindex, + ino_t hidden_ino) +{ + struct file *fwd, *rev; + struct fmapent ent; + loff_t pos; + ssize_t sz; + int err; + uint64_t ino64; + const int fwdhdr = sizeof(struct fmaphdr) + sizeof(struct bmapent[256]); + const int fwd_elmnt = sizeof(ent); + const int rev_elmnt = sizeof(ino64); + + err = -ENOSPC; + if (ino < FIRST_VALID_INODE) + goto out; + + fwd = sbi->usi_forwardmap; + ent.fsnum = sbi->usi_bnum_table[bindex]; + ent.inode = hidden_ino; + pos = fwdhdr + fwd_elmnt * ino; + sz = __fwrite(fwd, &ent, fwd_elmnt, &pos); + err = sz; + if (err < 0) + goto out; + err = -EIO; + if (sz != fwd_elmnt) + goto out; + + rev = sbi->usi_map_table[bindex]; + pos = sizeof(struct rmaphdr) + rev_elmnt * hidden_ino; + ino64 = ino; + sz = __fwrite(rev, &ino64, rev_elmnt, &pos); + err = sz; + if (err < 0) + goto out; + err = 0; + if (sz != rev_elmnt) + err = -EIO; + out: + print_exit_status(err); + return err; +} + +/* + * read_uin(struct super_block *sb, uint8_t branchnum, ino_t inode_number, int flag, ino_t *uino) + * fsnum: branch to reference when getting the inode number + * inode_number: lower level inode number use to reference the proper inode. + * flag: if set to O_CREAT it will creat the entry if it doesent exist + * otherwise it will return the existing one. + * returns: the unionfs inode number either created or retrieved based on + * the information. + */ +int read_uin(struct super_block *sb, uint8_t branchnum, ino_t inode_number, + int flag, ino_t * uino) +{ + int err = 0; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + /* Find appropriate reverse map and then read from the required position */ + /* get it from the array. */ + err = __read_uin(spd, inode_number, branchnum, uino); + if (err || *uino) + goto out; + + err = -EIO; + if (!(flag & O_CREAT)) + goto out; + + /* If we haven't found an entry and we have the O_CREAT flag set we want to + * create a new entry write it out to the file and return its index + */ + mutex_lock(&sb->s_lock); + *uino = spd->usi_next_avail++; + err = __write_uin(spd, *uino, branchnum, inode_number); + if (err) + spd->usi_next_avail--; + mutex_unlock(&sb->s_lock); + out: + print_exit_status(err); + return err; +} + +int write_uin(struct super_block *sb, ino_t ino, int bindex, ino_t hidden_ino) +{ + int err; + + print_entry_location(); + err = __write_uin(stopd(sb), ino, bindex, hidden_ino); + print_exit_status(err); + return err; +} + +/* + * get_lin(ino_t inode_number) + * inode_number : inode number for the unionfs inode + * returns: the lower level inode# and branch# + */ +/* entry should use a poiner on the stack. should be staticly allocated one + * level up*/ +int get_lin(struct super_block *sb, ino_t inode_number, struct fmapent *entry) +{ + struct file *forwardmap; + loff_t seek_size; + mm_segment_t oldfs; + int err = 0, bytesread = 0; + + print_entry_location(); + + if (!entry) { + entry = ERR_PTR(-ENOMEM); + goto out; + } + forwardmap = stopd(sb)->usi_forwardmap; + seek_size = + sizeof(struct fmaphdr) + sizeof(struct bmapent[256]) + + (sizeof(struct fmapent) * inode_number); + oldfs = get_fs(); + set_fs(KERNEL_DS); + bytesread = __fread(forwardmap, entry, sizeof(*entry), &seek_size); + set_fs(oldfs); + if (bytesread != sizeof(*entry)) + err = -EINVAL; + + out: + print_exit_location(); + return err; +} + +/* + * remove_map(struct super_block *sb,int bindex) + * + * sb: The super block containing all the current imap info + * bindex: the index of the branch that is being removed. + * + * This assumes that end hasen't been decremented yet. + * + * Returns: This function really can't fail. The only thing + * that could possibly happen is that it will oops but that + * requires unionfs to be in an inconsistant state which + * shoulden't happen. + */ +int remove_map(struct super_block *sb, int bindex) +{ + int i; + struct unionfs_sb_info *spd; + + print_entry_location(); + + spd = stopd(sb); + BUG_ON(!spd); + + for (i = bindex; i < sbend(sb); i++) { + spd->usi_map_table[i] = spd->usi_map_table[i + 1]; + spd->usi_bnum_table[i] = spd->usi_bnum_table[i + 1]; + } + return 0; +} + +#endif +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/Makefile +++ linux-2.6.28/ubuntu/unionfs/Makefile @@ -0,0 +1,16 @@ +UNIONFS_VERSION = 1.4 +SUP_MAJOR= 2 +SUP_MINOR= 6 +SUP_PATCH= 18 + +EXTRA_CFLAGS+=-DUNIONFS_VERSION=\"${UNIONFS_VERSION}\" -DSUP_MAJOR=${SUP_MAJOR} -DSUP_MINOR=${SUP_MINOR} -DSUP_PATCH=${SUP_PATCH} -DUNIONFS_UNSUPPORTED + +# This will enable full debugging support +# EXTRA_CFLAGS+=-DUNIONFS_DEBUG + +obj-$(CONFIG_FS_UNIONFS) += unionfs.o + +unionfs-objs := subr.o dentry.o file.o inode.o main.o super.o \ + stale_inode.o branchman.o xattr.o rdstate.o copyup.o \ + dirhelper.o rename.o unlink.o lookup.o persistent_inode.o \ + commonfops.o dirfops.o print.o sioq.o --- linux-2.6.28.orig/ubuntu/unionfs/unionfs.h +++ linux-2.6.28/ubuntu/unionfs/unionfs.h @@ -0,0 +1,736 @@ +#ifndef __UNIONFS_H_ +#define __UNIONFS_H_ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#ifndef UNIONFS_UNSUPPORTED +#if LINUX_VERSION_CODE != KERNEL_VERSION(SUP_MAJOR,SUP_MINOR,SUP_PATCH) +#warning You are compiling Unionfs on an unsupported kernel version. +#warning To compile Unionfs, you will need to define UNIONFS_UNSUPPORTED. +#warning Try adding: EXTRACFLAGS=-DUNIONFS_UNSUPPORTED to fistdev.mk +#endif +#endif + +/* the file system name */ +#define UNIONFS_NAME "unionfs" + +/* unionfs file systems superblock magic */ +#define UNIONFS_SUPER_MAGIC 0xf15f083d + +/* unionfs root inode number */ +#define UNIONFS_ROOT_INO 1 + +/* Mount time flags */ +#define MOUNT_FLAG(sb) (stopd(sb)->usi_mount_flag) + +/* number of characters while generating unique temporary file names */ +#define UNIONFS_TMPNAM_LEN 12 + +/* Operations vectors defined in specific files. */ +extern struct file_operations unionfs_main_fops; +extern struct file_operations unionfs_dir_fops; +extern struct inode_operations unionfs_main_iops; +extern struct inode_operations unionfs_dir_iops; +extern struct inode_operations unionfs_symlink_iops; +extern struct super_operations unionfs_sops; +extern struct dentry_operations unionfs_dops; +#ifdef CONFIG_EXPORTFS +extern struct export_operations unionfs_export_ops; +#endif + +/* How long should an entry be allowed to persist */ +#define RDCACHE_JIFFIES 5*HZ + +/* file private data. */ +struct unionfs_file_info { + int b_start; + int b_end; + atomic_t ufi_generation; + + struct unionfs_dir_state *rdstate; + struct file **ufi_file; +}; + +/* unionfs inode data in memory */ +struct unionfs_inode_info { + int b_start; + int b_end; + atomic_t uii_generation; + int uii_stale; + /* Stuff for readdir over NFS. */ + spinlock_t uii_rdlock; + struct list_head uii_readdircache; + int uii_rdcount; + int uii_hashsize; + int uii_cookie; + /* The hidden inodes */ + struct inode **uii_inode; + /* to keep track of reads/writes for unlinks before closes */ + atomic_t uii_totalopens; +}; + +struct unionfs_inode_container { + struct unionfs_inode_info info; + struct inode vfs_inode; +}; + +/* unionfs dentry data in memory */ +struct unionfs_dentry_info { + /* The semaphore is used to lock the dentry as soon as we get into a + * unionfs function from the VFS. Our lock ordering is that children + * go before their parents. */ + struct semaphore udi_sem; + int udi_bstart; + int udi_bend; + int udi_bopaque; + int udi_bcount; + atomic_t udi_generation; + struct dentry **udi_dentry; +}; + +/* A putmap is used so that older files can still do branchput correctly. */ +struct putmap { + atomic_t count; + int bend; + int map[0]; +}; + +/* These are the pointers to our various objects. */ +struct unionfs_usi_data { + struct super_block *sb; + struct vfsmount *hidden_mnt; + atomic_t sbcount; + int branchperms; +}; + +/* unionfs super-block data in memory */ +struct unionfs_sb_info { + int b_end; + + atomic_t usi_generation; + unsigned long usi_mount_flag; + struct rw_semaphore usi_rwsem; + + struct unionfs_usi_data *usi_data; + + /* These map branch numbers for old generation numbers to the new bindex, + * so that branchput will behave properly. */ + int usi_firstputmap; + int usi_lastputmap; + struct putmap **usi_putmaps; + +#ifdef UNIONFS_IMAP + int usi_persistent; + /* These will need a lock. */ + uint64_t usi_next_avail; + uint8_t usi_num_bmapents; + struct bmapent *usi_bmap; + struct file *usi_forwardmap; + struct file **usi_reversemaps; + struct file **usi_map_table; + int *usi_bnum_table; //This is a table of branches to fsnums. +#endif /* UNIONFS_IMAP */ +}; + +/* + * structure for making the linked list of entries by readdir on left branch + * to compare with entries on right branch + */ +struct filldir_node { + struct list_head file_list; // list for directory entries + char *name; // name entry + int hash; // name hash + int namelen; // name len since name is not 0 terminated + int bindex; // we can check for duplicate whiteouts and files in the same branch in order to return -EIO. + int whiteout; // is this a whiteout entry? + char iname[DNAME_INLINE_LEN_MIN]; // Inline name, so we don't need to separately kmalloc small ones +}; + +/* Directory hash table. */ +struct unionfs_dir_state { + unsigned int uds_cookie; /* The cookie, which is based off of uii_rdversion */ + unsigned int uds_offset; /* The entry we have returned. */ + int uds_bindex; + loff_t uds_dirpos; /* The offset within the lower level directory. */ + int uds_size; /* How big is the hash table? */ + int uds_hashentries; /* How many entries have been inserted? */ + unsigned long uds_access; + /* This cache list is used when the inode keeps us around. */ + struct list_head uds_cache; + struct list_head uds_list[0]; +}; + +/* privileged io workqueue */ +#include "sioq.h" + +/* include miscellaneous macros */ +#include "unionfs_macros.h" + +/* include debug macros */ +#include "unionfs_debug.h" + +/* include persistent imap code */ +#include "unionfs_imap.h" + +/* Cache creation/deletion routines. */ +void destroy_filldir_cache(void); +int init_filldir_cache(void); +int init_inode_cache(void); +void destroy_inode_cache(void); +int init_dentry_cache(void); +void destroy_dentry_cache(void); + +/* Initialize and free readdir-specific state. */ +int init_rdstate(struct file *file); +struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex); +struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos); +void free_rdstate(struct unionfs_dir_state *state); +int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name, + int namelen, int bindex, int whiteout); +struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate, + const char *name, int namelen); + +struct dentry **alloc_new_dentries(int objs); +struct unionfs_usi_data *alloc_new_data(int objs); + +#ifdef FIST_MALLOC_DEBUG + +extern void *unionfs_kzalloc(size_t size, gfp_t flags, int line, + const char *file); +extern void *unionfs_kmalloc(size_t size, gfp_t flags, int line, + const char *file); +extern void unionfs_kfree(void *ptr, int line, const char *file); + +extern struct dentry *unionfs_dget_parent(struct dentry *child, int line, + const char *file); +extern struct dentry *unionfs_dget(struct dentry *ptr, int line, + const char *file); +extern void unionfs_dput(struct dentry *ptr, int line, const char *file); +extern struct inode *unionfs_igrab(struct inode *inode, int line, char *file); +extern void unionfs_iput(struct inode *inode, int line, char *file); +extern struct dentry *unionfs_lookup_one_len(const char *name, + struct dentry *parent, int len, + int line, const char *file); +void record_path_lookup(struct nameidata *nd, int line, const char *file); +void record_path_release(struct nameidata *nd, int line, const char *file); +struct file *unionfs_dentry_open(struct dentry *ptr, struct vfsmount *mnt, + int flags, int line, const char *file); +void record_set(struct dentry *upper, int index, struct dentry *ptr, + struct dentry *old, int line, const char *file); + +#define KZALLOC(size,flags) unionfs_kzalloc((size),(flags),__LINE__,__FILE__) +#define KMALLOC(size,flags) unionfs_kmalloc((size),(flags),__LINE__,__FILE__) +#define KFREE(ptr) unionfs_kfree((ptr),__LINE__,__FILE__) +#define DGET(d) unionfs_dget((d),__LINE__,__FILE__) +#define DPUT(d) unionfs_dput((d),__LINE__,__FILE__) +# define IPUT(a) unionfs_iput((a),__LINE__,__FILE__) +# define IGRAB(a) unionfs_igrab((a),__LINE__,__FILE__) +#define LOOKUP_ONE_LEN(name,parent,len) unionfs_lookup_one_len((name),(parent),(len),__LINE__,__FILE__) +# define RECORD_PATH_LOOKUP(nd) record_path_lookup((nd),__LINE__,__FILE__) +# define RECORD_PATH_RELEASE(nd) record_path_release((nd),__LINE__,__FILE__) +/* This has the effect of reducing the reference count sooner or later, + * if the file is closed. If it isn't then the mount will be busy and + * you can't unmount. + */ +# define DENTRY_OPEN(d,m,f) unionfs_dentry_open((d),(m),(f),__LINE__,__FILE__) +# define GET_PARENT(dentry) unionfs_dget_parent((dentry),__LINE__,__FILE__) +#else /* not FIST_MALLOC_DEBUG */ +# define KZALLOC(a,b) kzalloc((a),(b)) +# define KMALLOC(a,b) kmalloc((a),(b)) +# define KFREE(a) kfree((a)) +# define DPUT(a) dput((a)) +# define DGET(a) dget((a)) +# define IPUT(a) iput((a)) +# define IGRAB(a) igrab((a)) +# define LOOKUP_ONE_LEN(a,b,c) lookup_one_len((a),(b),(c)) +# define RECORD_PATH_LOOKUP(a) +# define RECORD_PATH_RELEASE(a) +# define DENTRY_OPEN(d,m,f) dentry_open((d),(m),(f)) +# define GET_PARENT(d) dget_parent(d) +#endif /* not FIST_MALLOC_DEBUG */ + +/* We can only use 32-bits of offset for rdstate --- blech! */ +#define DIREOF (0xfffff) +#define RDOFFBITS 20 /* This is the number of bits in DIREOF. */ +#define MAXRDCOOKIE (0xfff) +/* Turn an rdstate into an offset. */ +static inline off_t rdstate2offset(struct unionfs_dir_state *buf) +{ + off_t tmp; + tmp = + ((buf->uds_cookie & MAXRDCOOKIE) << RDOFFBITS) | (buf-> + uds_offset & + DIREOF); + return tmp; +} + +#define unionfs_read_lock(sb) down_read(&stopd(sb)->usi_rwsem) +#define unionfs_read_unlock(sb) up_read(&stopd(sb)->usi_rwsem) +#define unionfs_write_lock(sb) down_write(&stopd(sb)->usi_rwsem) +#define unionfs_write_unlock(sb) up_write(&stopd(sb)->usi_rwsem) + +/* The double lock function needs to go after the debugmacros, so that + * dtopd is defined. */ +static inline void double_lock_dentry(struct dentry *d1, struct dentry *d2) +{ + if (d2 < d1) { + struct dentry *tmp = d1; + d1 = d2; + d2 = tmp; + } + lock_dentry(d1); + lock_dentry(d2); +} + +extern int new_dentry_private_data(struct dentry *dentry); +void free_dentry_private_data(struct unionfs_dentry_info *udi); +void update_bstart(struct dentry *dentry); +#define sbt(sb) ((sb)->s_type->name) + +/* + * EXTERNALS: + */ +/* replicates the directory structure upto given dentry in given branch */ +extern struct dentry *create_parents(struct inode *dir, struct dentry *dentry, + int bindex); +struct dentry *create_parents_named(struct inode *dir, struct dentry *dentry, + const char *name, int bindex); + +/* check if two branches overlap */ +extern int is_branch_overlap(struct dentry *dent1, struct dentry *dent2); + +/* partial lookup */ +extern int unionfs_partial_lookup(struct dentry *dentry); + +/* Pass an unionfs dentry and an index and it will try to create a whiteout in branch 'index'. + On error, it will proceed to a branch to the left */ +extern int create_whiteout(struct dentry *dentry, int start); +/* copies a file from dbstart to newbindex branch */ +extern int copyup_file(struct inode *dir, struct file *file, int bstart, + int newbindex, loff_t size); +extern int copyup_named_file(struct inode *dir, struct file *file, + char *name, int bstart, int new_bindex, + loff_t len); + +/* copies a dentry from dbstart to newbindex branch */ +extern int copyup_dentry(struct inode *dir, struct dentry *dentry, int bstart, + int new_bindex, struct file **copyup_file, loff_t len); +extern int copyup_named_dentry(struct inode *dir, struct dentry *dentry, + int bstart, int new_bindex, const char *name, + int namelen, struct file **copyup_file, + loff_t len); + +extern int remove_whiteouts(struct dentry *dentry, struct dentry *hidden_dentry, + int bindex); + +/* Is this directory empty: 0 if it is empty, -ENOTEMPTY if not. */ +extern int check_empty(struct dentry *dentry, + struct unionfs_dir_state **namelist); +/* Delete whiteouts from this directory in branch bindex. */ +extern int delete_whiteouts(struct dentry *dentry, int bindex, + struct unionfs_dir_state *namelist); + +/* Re-lookup a hidden dentry. */ +extern int unionfs_refresh_hidden_dentry(struct dentry *dentry, int bindex); + +extern void unionfs_reinterpose(struct dentry *this_dentry); +extern struct super_block *unionfs_duplicate_super(struct super_block *sb); + +/* Locking functions. */ +extern int unionfs_setlk(struct file *file, int cmd, struct file_lock *fl); +extern int unionfs_getlk(struct file *file, struct file_lock *fl); + +/* Common file operations. */ +extern int unionfs_file_revalidate(struct file *file, int willwrite); +extern int unionfs_open(struct inode *inode, struct file *file); +extern int unionfs_file_release(struct inode *inode, struct file *file); +extern int unionfs_flush(struct file *file, fl_owner_t id); +extern long unionfs_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); + +/* Inode operations */ +extern int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); +int unionfs_unlink(struct inode *dir, struct dentry *dentry); +int unionfs_rmdir(struct inode *dir, struct dentry *dentry); + +int unionfs_d_revalidate(struct dentry *dentry, struct nameidata *nd); + +/* The values for unionfs_interpose's flag. */ +#define INTERPOSE_DEFAULT 0 +#define INTERPOSE_LOOKUP 1 +#define INTERPOSE_REVAL 2 +#define INTERPOSE_REVAL_NEG 3 +#define INTERPOSE_PARTIAL 4 + +extern int unionfs_interpose(struct dentry *this_dentry, struct super_block *sb, + int flag); + +/* Branch management ioctls. */ +int unionfs_ioctl_branchcount(struct file *file, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_incgen(struct file *file, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_addbranch(struct inode *inode, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_delbranch(struct super_block *sb, unsigned long arg); +int unionfs_ioctl_rdwrbranch(struct inode *inode, unsigned int cmd, + unsigned long arg); +int unionfs_ioctl_queryfile(struct file *file, unsigned int cmd, + unsigned long arg); + +/* Verify that a branch is valid. */ +int check_branch(struct nameidata *nd); + +/* Extended attribute functions. */ +extern void *xattr_alloc(size_t size, size_t limit); +extern void xattr_free(void *ptr, size_t size); + +extern ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, + void *value, size_t size); +extern int unionfs_removexattr(struct dentry *dentry, const char *name); +extern ssize_t unionfs_listxattr(struct dentry *dentry, char *list, + size_t size); + +int unionfs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags); + +/* The root directory is unhashed, but isn't deleted. */ +static inline int d_deleted(struct dentry *d) +{ + return d_unhashed(d) && (d != d->d_sb->s_root); +} + +/* returns the sum of the n_link values of all the underlying inodes of the passed inode */ +static inline int get_nlinks(struct inode *inode) +{ + int sum_nlinks = 0; + int dirs = 0; + int bindex; + struct inode *hidden_inode; + + if (!S_ISDIR(inode->i_mode)) + return itohi(inode)->i_nlink; + + for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) { + hidden_inode = itohi_index(inode, bindex); + if (!hidden_inode || !S_ISDIR(hidden_inode->i_mode)) + continue; + BUG_ON(hidden_inode->i_nlink < 0); + + /* A deleted directory. */ + if (hidden_inode->i_nlink == 0) + continue; + dirs++; + /* A broken directory (e.g., squashfs). */ + if (hidden_inode->i_nlink == 1) + sum_nlinks += 2; + else + sum_nlinks += (hidden_inode->i_nlink - 2); + } + + if (!dirs) + return 0; + return sum_nlinks + 2; +} + +static inline void fist_copy_attr_atime(struct inode *dest, + const struct inode *src) +{ + dest->i_atime = src->i_atime; +} +static inline void fist_copy_attr_times(struct inode *dest, + const struct inode *src) +{ + dest->i_atime = src->i_atime; + dest->i_mtime = src->i_mtime; + dest->i_ctime = src->i_ctime; +} +static inline void fist_copy_attr_timesizes(struct inode *dest, + const struct inode *src) +{ + dest->i_atime = src->i_atime; + dest->i_mtime = src->i_mtime; + dest->i_ctime = src->i_ctime; + dest->i_size = src->i_size; + dest->i_blocks = src->i_blocks; +} +static inline void fist_copy_attr_all(struct inode *dest, + const struct inode *src) +{ + print_entry_location(); + + dest->i_mode = src->i_mode; + /* we do not need to copy if the file is a deleted file */ + if (dest->i_nlink > 0) + dest->i_nlink = get_nlinks(dest); + dest->i_uid = src->i_uid; + dest->i_gid = src->i_gid; + dest->i_rdev = src->i_rdev; + dest->i_atime = src->i_atime; + dest->i_mtime = src->i_mtime; + dest->i_ctime = src->i_ctime; + dest->i_blkbits = src->i_blkbits; + dest->i_size = src->i_size; + dest->i_blocks = src->i_blocks; + dest->i_flags = src->i_flags; + + print_exit_location(); +} + +struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *nd, int lookupmode); +int is_stale_inode(struct inode *inode); +void make_stale_inode(struct inode *inode); + +#define IS_SET(sb, check_flag) (check_flag & MOUNT_FLAG(sb)) + +/* unionfs_permission, check if we should bypass error to facilitate copyup */ +#define IS_COPYUP_ERR(err) (err == -EROFS) + +/* unionfs_open, check if we need to copyup the file */ +#define OPEN_WRITE_FLAGS (O_WRONLY | O_RDWR | O_APPEND) +#define IS_WRITE_FLAG(flag) (flag & (OPEN_WRITE_FLAGS)) + +static inline int branchperms(struct super_block *sb, int index) +{ + BUG_ON(index < 0); + + return stopd(sb)->usi_data[index].branchperms; +} +static inline int set_branchperms(struct super_block *sb, int index, int perms) +{ + BUG_ON(index < 0); + + stopd(sb)->usi_data[index].branchperms = perms; + + return perms; +} + +/* Is this file on a read-only branch? */ +static inline int __is_robranch_super(struct super_block *sb, int index, + char *file, const char *function, + int line) +{ + int err = 0; + + print_util_entry_location(); + + if (!(branchperms(sb, index) & MAY_WRITE)) + err = -EROFS; + + print_util_exit_status(err); + return err; +} + +/* Is this file on a read-only branch? */ +static inline int __is_robranch_index(struct dentry *dentry, int index, + char *file, const char *function, + int line) +{ + int err = 0; + int perms; + + print_util_entry_location(); + + BUG_ON(index < 0); + + perms = stopd(dentry->d_sb)->usi_data[index].branchperms; + + if ((!(perms & MAY_WRITE)) + || (IS_RDONLY(dtohd_index(dentry, index)->d_inode))) + err = -EROFS; + + print_util_exit_status(err); + + return err; +} +static inline int __is_robranch(struct dentry *dentry, char *file, + const char *function, int line) +{ + int index; + int err; + + print_util_entry_location(); + + index = dtopd(dentry)->udi_bstart; + BUG_ON(index < 0); + + err = __is_robranch_index(dentry, index, file, function, line); + + print_util_exit_status(err); + + return err; +} + +#define is_robranch(d) __is_robranch(d, __FILE__, __FUNCTION__, __LINE__) +#define is_robranch_super(s, n) __is_robranch_super(s, n, __FILE__, __FUNCTION__, __LINE__) + +/* What do we use for whiteouts. */ +#define WHPFX ".wh." +#define WHLEN 4 +/* If a directory contains this file, then it is opaque. We start with the + * .wh. flag so that it is blocked by loomkup. + */ +#define UNIONFS_DIR_OPAQUE_NAME "__dir_opaque" +#define UNIONFS_DIR_OPAQUE WHPFX UNIONFS_DIR_OPAQUE_NAME + +/* construct whiteout filename */ +static inline char *alloc_whname(const char *name, int len) +{ + char *buf; + + buf = KMALLOC(len + WHLEN + 1, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + strcpy(buf, WHPFX); + strlcat(buf, name, len + WHLEN + 1); + + return buf; +} + +/* Definitions for various ways to handle errors. + Each flag's value is its bit position */ + +/* 1 = DELETE_ALL, 0 = check for DELETE_WHITEOUT */ +#ifdef UNIONFS_DELETE_ALL +#define DELETE_ALL 4 +#else +#define DELETE_ALL 0 +#endif + +#define VALID_MOUNT_FLAGS (DELETE_ALL) + +/* + * MACROS: + */ + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif /* not SEEK_SET */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif /* not SEEK_CUR */ + +#ifndef SEEK_END +#define SEEK_END 2 +#endif /* not SEEK_END */ + +#ifndef DEFAULT_POLLMASK +#define DEFAULT_POLLMASK (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) +#endif + +/* + * EXTERNALS: + */ + +/* JS: These two functions are here because it is kind of daft to copy and paste the + * contents of the two functions to 32+ places in unionfs + */ +static inline struct dentry *lock_parent(struct dentry *dentry) +{ + struct dentry *dir = DGET(dentry->d_parent); + + mutex_lock(&dir->d_inode->i_mutex); + return dir; +} + +static inline void unlock_dir(struct dentry *dir) +{ + mutex_unlock(&dir->d_inode->i_mutex); + DPUT(dir); +} + +extern int make_dir_opaque(struct dentry *dir, int bindex); + +#endif /* __KERNEL__ */ + +/* + * DEFINITIONS FOR USER AND KERNEL CODE: + * (Note: ioctl numbers 1--9 are reserved for fistgen, the rest + * are auto-generated automatically based on the user's .fist file.) + */ +# define FIST_IOCTL_GET_DEBUG_VALUE _IOR(0x15, 1, int) +# define FIST_IOCTL_SET_DEBUG_VALUE _IOW(0x15, 2, int) +# define UNIONFS_IOCTL_BRANCH_COUNT _IOR(0x15, 10, int) +# define UNIONFS_IOCTL_INCGEN _IOR(0x15, 11, int) +# define UNIONFS_IOCTL_ADDBRANCH _IOW(0x15, 12, int) +# define UNIONFS_IOCTL_DELBRANCH _IOW(0x15, 13, int) +# define UNIONFS_IOCTL_RDWRBRANCH _IOW(0x15, 14, int) +# define UNIONFS_IOCTL_QUERYFILE _IOR(0x15, 15, int) + +/* We don't support normal remount, but unionctl uses it. */ +# define UNIONFS_REMOUNT_MAGIC 0x4a5a4380 + +/* should be at least LAST_USED_UNIONFS_PERMISSION<<1 */ +#define MAY_NFSRO 16 + +struct unionfs_addbranch_args { + unsigned int ab_branch; + char *ab_path; + unsigned int ab_perms; +}; + +struct unionfs_rdwrbranch_args { + unsigned int rwb_branch; + unsigned int rwb_perms; +}; + +#endif /* not __UNIONFS_H_ */ +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/stale_inode.c +++ linux-2.6.28/ubuntu/unionfs/stale_inode.c @@ -0,0 +1,133 @@ +/* + * Adpated from linux/fs/bad_inode.c + * + * Copyright (C) 1997, Stephen Tweedie + * + * Provide stub functions for "stale" inodes, a bit friendlier than the + * -EIO that bad_inode.c does. + */ +/* + * $Id: stale_inode.c,v 1.13 2006/03/21 09:22:11 jsipek Exp $ + */ + +#include + +#include +#include +#include + +static struct address_space_operations unionfs_stale_aops; + +/* declarations for "sparse */ +extern struct inode_operations stale_inode_ops; + +/* + * The follow_link operation is special: it must behave as a no-op + * so that a stale root inode can at least be unmounted. To do this + * we must dput() the base and return the dentry with a dget(). + */ +static void *stale_follow_link(struct dentry *dent, struct nameidata *nd) +{ + int err = vfs_follow_link(nd, ERR_PTR(-ESTALE)); + return ERR_PTR(err); +} + +static int return_ESTALE(void) +{ + return -ESTALE; +} + +#define ESTALE_ERROR ((void *) (return_ESTALE)) + +static struct file_operations stale_file_ops = { + .llseek = ESTALE_ERROR, + .read = ESTALE_ERROR, + .write = ESTALE_ERROR, + .readdir = ESTALE_ERROR, + .poll = ESTALE_ERROR, + .ioctl = ESTALE_ERROR, + .mmap = ESTALE_ERROR, + .open = ESTALE_ERROR, + .flush = ESTALE_ERROR, + .release = ESTALE_ERROR, + .fsync = ESTALE_ERROR, + .fasync = ESTALE_ERROR, + .lock = ESTALE_ERROR, +}; + +struct inode_operations stale_inode_ops = { + .create = ESTALE_ERROR, + .lookup = ESTALE_ERROR, + .link = ESTALE_ERROR, + .unlink = ESTALE_ERROR, + .symlink = ESTALE_ERROR, + .mkdir = ESTALE_ERROR, + .rmdir = ESTALE_ERROR, + .mknod = ESTALE_ERROR, + .rename = ESTALE_ERROR, + .readlink = ESTALE_ERROR, + .follow_link = stale_follow_link, + .truncate = ESTALE_ERROR, + .permission = ESTALE_ERROR, +}; + +/* + * When a filesystem is unable to read an inode due to an I/O error in + * its read_inode() function, it can call make_stale_inode() to return a + * set of stubs which will return ESTALE errors as required. + * + * We only need to do limited initialisation: all other fields are + * preinitialised to zero automatically. + */ + +/** + * make_stale_inode - mark an inode stale due to an I/O error + * @inode: Inode to mark stale + * + * When an inode cannot be read due to a media or remote network + * failure this function makes the inode "stale" and causes I/O operations + * on it to fail from this point on. + */ + +void make_stale_inode(struct inode *inode) +{ + inode->i_mode = S_IFREG; + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; + inode->i_op = &stale_inode_ops; + inode->i_fop = &stale_file_ops; + inode->i_mapping->a_ops = &unionfs_stale_aops; +} + +/* + * This tests whether an inode has been flagged as stale. The test uses + * &stale_inode_ops to cover the case of invalidated inodes as well as + * those created by make_stale_inode() above. + */ + +/** + * is_stale_inode - is an inode errored + * @inode: inode to test + * + * Returns true if the inode in question has been marked as stale. + */ + +int is_stale_inode(struct inode *inode) +{ + return (inode->i_op == &stale_inode_ops); +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/xattr.c +++ linux-2.6.28/ubuntu/unionfs/xattr.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: xattr.c,v 1.32 2006/06/01 03:11:03 jsipek Exp $ + */ + +#include "unionfs.h" + +/* This is lifted from fs/xattr.c */ +void *xattr_alloc(size_t size, size_t limit) +{ + void *ptr; + + if (size > limit) + return ERR_PTR(-E2BIG); + + if (!size) /* size request, no buffer is needed */ + return NULL; + else if (size <= PAGE_SIZE) + ptr = KMALLOC((unsigned long)size, GFP_KERNEL); + else + ptr = vmalloc((unsigned long)size); + if (!ptr) + return ERR_PTR(-ENOMEM); + return ptr; +} + +void xattr_free(void *ptr, size_t size) +{ + if (!size) /* size request, no buffer was needed */ + return; + else if (size <= PAGE_SIZE) + KFREE(ptr); + else + vfree(ptr); +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + * ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); + */ +ssize_t unionfs_getxattr(struct dentry * dentry, const char *name, void *value, + size_t size) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + + print_entry_location(); + + dprint(PRINT_DEBUG_XATTR, "getxattr: name=\"%s\", value %lu bytes\n", + name, size); + + lock_dentry(dentry); + + hidden_dentry = dtohd(dentry); + + err = vfs_getxattr(hidden_dentry, NULL, (char*)name, value, size, + NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + */ +int +unionfs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + + print_entry_location(); + + lock_dentry(dentry); + hidden_dentry = dtohd(dentry); + + dprint(PRINT_DEBUG_XATTR, "setxattr: name=\"%s\", value %lu bytes," + "flags=%x\n", name, (unsigned long)size, flags); + + err = + vfs_setxattr(hidden_dentry, NULL, (char *)name, (char *)value, + size, flags, NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + */ +int unionfs_removexattr(struct dentry *dentry, const char *name) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + + print_entry_location(); + + lock_dentry(dentry); + hidden_dentry = dtohd(dentry); + + dprint(PRINT_DEBUG_XATTR, "removexattr: name=\"%s\"\n", name); + + err = vfs_removexattr(hidden_dentry, NULL, (char*)name, NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* BKL held by caller. + * dentry->d_inode->i_mutex locked + */ +ssize_t unionfs_listxattr(struct dentry * dentry, char *list, size_t size) +{ + struct dentry *hidden_dentry = NULL; + int err = -EOPNOTSUPP; + char *encoded_list = NULL; + + print_entry_location(); + lock_dentry(dentry); + + hidden_dentry = dtohd(dentry); + + encoded_list = list; + err = vfs_listxattr(hidden_dentry, NULL, encoded_list, size, NULL); + + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/lookup.c +++ linux-2.6.28/ubuntu/unionfs/lookup.c @@ -0,0 +1,524 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: lookup.c,v 1.49 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +static int is_opaque_dir(struct dentry *dentry, int bindex); +static int is_validname(const char *name); + +struct dentry *unionfs_lookup_backend(struct dentry *dentry, struct nameidata *nd, int lookupmode) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct dentry *wh_hidden_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + struct dentry *parent_dentry = NULL; + int bindex, bstart, bend, bopaque; + int dentry_count = 0; /* Number of positive dentries. */ + int first_dentry_offset = -1; + struct dentry *first_hidden_dentry = NULL; + int locked_parent = 0; + int locked_child = 0; + + int opaque; + char *whname = NULL; + const char *name; + int namelen; + + print_entry("mode = %d", lookupmode); + + /* We should already have a lock on this dentry in the case of a + * partial lookup, or a revalidation. Otherwise it is returned from + * new_dentry_private_data already locked. */ + if (lookupmode == INTERPOSE_PARTIAL || lookupmode == INTERPOSE_REVAL + || lookupmode == INTERPOSE_REVAL_NEG) { + verify_locked(dentry); + } else { + BUG_ON(dtopd_nocheck(dentry) != NULL); + locked_child = 1; + } + if (lookupmode != INTERPOSE_PARTIAL) + if ((err = new_dentry_private_data(dentry))) + goto out; + /* must initialize dentry operations */ + dentry->d_op = &unionfs_dops; + + parent_dentry = GET_PARENT(dentry); + /* We never partial lookup the root directory. */ + if (parent_dentry != dentry) { + lock_dentry(parent_dentry); + locked_parent = 1; + } else { + DPUT(parent_dentry); + parent_dentry = NULL; + goto out; + } + + print_dentry("IN unionfs_lookup (parent)", parent_dentry); + print_dentry("IN unionfs_lookup (child)", dentry); + + name = dentry->d_name.name; + namelen = dentry->d_name.len; + + /* No dentries should get created for possible whiteout names. */ + if (!is_validname(name)) { + err = -EPERM; + goto out_free; + } + + /* Now start the actual lookup procedure. */ + bstart = dbstart(parent_dentry); + bend = dbend(parent_dentry); + bopaque = dbopaque(parent_dentry); + BUG_ON(bstart < 0); + + /* It would be ideal if we could convert partial lookups to only have + * to do this work when they really need to. It could probably improve + * performance quite a bit, and maybe simplify the rest of the code. */ + if (lookupmode == INTERPOSE_PARTIAL) { + bstart++; + if ((bopaque != -1) && (bopaque < bend)) + bend = bopaque; + } + + dprint(PRINT_DEBUG, "bstart = %d, bend = %d\n", bstart, bend); + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (lookupmode == INTERPOSE_PARTIAL && hidden_dentry) + continue; + BUG_ON(hidden_dentry != NULL); + + hidden_dir_dentry = dtohd_index(parent_dentry, bindex); + + /* if the parent hidden dentry does not exist skip this */ + if (!(hidden_dir_dentry && hidden_dir_dentry->d_inode)) + continue; + + /* also skip it if the parent isn't a directory. */ + if (!S_ISDIR(hidden_dir_dentry->d_inode->i_mode)) + continue; + + /* Reuse the whiteout name because its value doesn't change. */ + if (!whname) { + whname = alloc_whname(name, namelen); + if (IS_ERR(whname)) { + err = PTR_ERR(whname); + goto out_free; + } + } + + /* check if whiteout exists in this branch: lookup .wh.foo */ + wh_hidden_dentry = LOOKUP_ONE_LEN(whname, hidden_dir_dentry, + namelen + WHLEN); + if (IS_ERR(wh_hidden_dentry)) { + DPUT(first_hidden_dentry); + err = PTR_ERR(wh_hidden_dentry); + goto out_free; + } + + if (wh_hidden_dentry->d_inode) { + /* We found a whiteout so lets give up. */ + dprint(PRINT_DEBUG, "whiteout found in %d\n", bindex); + if (S_ISREG(wh_hidden_dentry->d_inode->i_mode)) { + set_dbend(dentry, bindex); + set_dbopaque(dentry, bindex); + DPUT(wh_hidden_dentry); + break; + } + err = -EIO; + printk(KERN_NOTICE "EIO: Invalid whiteout entry type" + " %d.\n", wh_hidden_dentry->d_inode->i_mode); + DPUT(wh_hidden_dentry); + DPUT(first_hidden_dentry); + goto out_free; + } + + DPUT(wh_hidden_dentry); + wh_hidden_dentry = NULL; + + /* Now do regular lookup; lookup foo */ + nd->path.dentry = dtohd_index(dentry, bindex); + /* FIXME: fix following line for mount point crossing */ + nd->path.mnt = stohiddenmnt_index(parent_dentry->d_sb, bindex); + + hidden_dentry = LOOKUP_ONE_LEN(name, hidden_dir_dentry, namelen); + print_dentry("hidden result", hidden_dentry); + if (IS_ERR(hidden_dentry)) { + DPUT(first_hidden_dentry); + err = PTR_ERR(hidden_dentry); + goto out_free; + } + + /* Store the first negative dentry specially, because if they + * are all negative we need this for future creates. */ + if (!hidden_dentry->d_inode) { + if (!first_hidden_dentry && (dbstart(dentry) == -1)) { + first_hidden_dentry = hidden_dentry; + first_dentry_offset = bindex; + } else { + DPUT(hidden_dentry); + } + continue; + } + + /* number of positive dentries */ + dentry_count++; + + /* store underlying dentry */ + if (dbstart(dentry) == -1) + set_dbstart(dentry, bindex); + set_dtohd_index(dentry, bindex, hidden_dentry); + set_dbend(dentry, bindex); + + /* update parent directory's atime with the bindex */ + fist_copy_attr_atime(parent_dentry->d_inode, + hidden_dir_dentry->d_inode); + + /* We terminate file lookups here. */ + if (!S_ISDIR(hidden_dentry->d_inode->i_mode)) { + if (lookupmode == INTERPOSE_PARTIAL) + continue; + if (dentry_count == 1) + goto out_positive; + /* This can only happen with mixed D-*-F-* */ + BUG_ON(!S_ISDIR(dtohd(dentry)->d_inode->i_mode)); + continue; + } + + opaque = is_opaque_dir(dentry, bindex); + if (opaque < 0) { + DPUT(first_hidden_dentry); + err = opaque; + goto out_free; + } + if (opaque) { + set_dbend(dentry, bindex); + set_dbopaque(dentry, bindex); + break; + } + } + + if (dentry_count) + goto out_positive; + else + goto out_negative; + + out_negative: + if (lookupmode == INTERPOSE_PARTIAL) + goto out; + + /* If we've only got negative dentries, then use the leftmost one. */ + if (lookupmode == INTERPOSE_REVAL) { + if (dentry->d_inode) { + itopd(dentry->d_inode)->uii_stale = 1; + } + goto out; + } + /* This should only happen if we found a whiteout. */ + if (first_dentry_offset == -1) { + nd->path.dentry = dentry; + /* FIXME: fix following line for mount point crossing */ + nd->path.mnt = stohiddenmnt_index(parent_dentry->d_sb, bindex); + + first_hidden_dentry = LOOKUP_ONE_LEN(name, hidden_dir_dentry, + namelen); + + first_dentry_offset = bindex; + if (IS_ERR(first_hidden_dentry)) { + err = PTR_ERR(first_hidden_dentry); + goto out; + } + } + set_dtohd_index(dentry, first_dentry_offset, first_hidden_dentry); + set_dbstart(dentry, first_dentry_offset); + set_dbend(dentry, first_dentry_offset); + + if (lookupmode == INTERPOSE_REVAL_NEG) + BUG_ON(dentry->d_inode != NULL); + else + d_add(dentry, NULL); + goto out; + +/* This part of the code is for positive dentries. */ + out_positive: + BUG_ON(dentry_count <= 0); + + /* If we're holding onto the first negative dentry throw it out. */ + DPUT(first_hidden_dentry); + + /* Partial lookups need to reinterpose, or throw away older negs. */ + if (lookupmode == INTERPOSE_PARTIAL) { + if (dentry->d_inode) { + unionfs_reinterpose(dentry); + goto out; + } + + /* This somehow turned positive, so it is as if we had a + * negative revalidation. */ + lookupmode = INTERPOSE_REVAL_NEG; + + update_bstart(dentry); + bstart = dbstart(dentry); + bend = dbend(dentry); + } + + err = unionfs_interpose(dentry, dentry->d_sb, lookupmode); + if (err) + goto out_drop; + + checkinode(dentry->d_inode, "unionfs_lookup OUT: child"); + checkinode(parent_dentry->d_inode, "unionfs_lookup OUT: dir"); + goto out; + + out_drop: + d_drop(dentry); + + out_free: + /* should dput all the underlying dentries on error condition */ + bstart = dbstart(dentry); + if (bstart >= 0) { + bend = dbend(dentry); + for (bindex = bstart; bindex <= bend; bindex++) + DPUT(dtohd_index(dentry, bindex)); + } + KFREE(dtohd_ptr(dentry)); + dtohd_ptr(dentry) = NULL; + set_dbstart(dentry, -1); + set_dbend(dentry, -1); + + out: + if (!err && dtopd(dentry)) { + BUG_ON(dbend(dentry) > dtopd(dentry)->udi_bcount); + BUG_ON(dbend(dentry) > sbmax(dentry->d_sb)); + BUG_ON(dbstart(dentry) < 0); + } + KFREE(whname); + print_dentry("OUT unionfs_lookup (parent)", parent_dentry); + print_dentry("OUT unionfs_lookup (child)", dentry); + if (locked_parent) + unlock_dentry(parent_dentry); + DPUT(parent_dentry); + if (locked_child) + unlock_dentry(dentry); + print_exit_status(err); + return ERR_PTR(err); +} + +/* This is a utility function that fills in a unionfs dentry.*/ +int unionfs_partial_lookup(struct dentry *dentry) +{ + struct dentry *tmp; + struct nameidata nd = { .flags = 0 }; + + tmp = unionfs_lookup_backend(dentry, &nd, INTERPOSE_PARTIAL); + if (!tmp) + return 0; + if (IS_ERR(tmp)) + return PTR_ERR(tmp); + /* need to change the interface */ + BUG_ON(tmp != dentry); + return -ENOSYS; +} + +/* The rest of these are utility functions for lookup. */ +static int is_opaque_dir(struct dentry *dentry, int bindex) +{ + int err = 0; + struct dentry *hidden_dentry; + struct dentry *wh_hidden_dentry; + struct inode *hidden_inode; + struct sioq_args args; + + print_entry_location(); + + hidden_dentry = dtohd_index(dentry, bindex); + hidden_inode = hidden_dentry->d_inode; + + BUG_ON(!S_ISDIR(hidden_inode->i_mode)); + + mutex_lock(&hidden_inode->i_mutex); + if (!inode_permission(hidden_inode, MAY_EXEC)) + wh_hidden_dentry = LOOKUP_ONE_LEN(UNIONFS_DIR_OPAQUE, + hidden_dentry, + sizeof(UNIONFS_DIR_OPAQUE) - 1); + else { + args.isopaque.dentry = hidden_dentry; + run_sioq(__is_opaque_dir, &args); + wh_hidden_dentry = args.ret; + } + + mutex_unlock(&hidden_inode->i_mutex); + if (IS_ERR(wh_hidden_dentry)) { + err = PTR_ERR(wh_hidden_dentry); + dprint(PRINT_DEBUG, "LOOKUP_ONE_LEN returned: %d\n", err); + goto out; + } + if (wh_hidden_dentry->d_inode) + err = 1; + DPUT(wh_hidden_dentry); + out: + print_exit_status(err); + return err; +} + +static int is_validname(const char *name) +{ + if (!strncmp(name, WHPFX, WHLEN)) + return 0; + if (!strncmp(name, UNIONFS_DIR_OPAQUE_NAME, + sizeof(UNIONFS_DIR_OPAQUE_NAME) - 1)) + return 0; + return 1; +} + +/* The dentry cache is just so we have properly sized dentries. */ +static struct kmem_cache *unionfs_dentry_cachep; +int init_dentry_cache(void) +{ + unionfs_dentry_cachep = + kmem_cache_create("unionfs_dentry", + sizeof(struct unionfs_dentry_info), 0, + SLAB_RECLAIM_ACCOUNT, NULL); + + if (!unionfs_dentry_cachep) + return -ENOMEM; + return 0; +} + +void destroy_dentry_cache(void) +{ + if (!unionfs_dentry_cachep) + return; + kmem_cache_destroy(unionfs_dentry_cachep); + return; +} + +void free_dentry_private_data(struct unionfs_dentry_info *udi) +{ + if (!udi) + return; + kmem_cache_free(unionfs_dentry_cachep, udi); +} + +int new_dentry_private_data(struct dentry *dentry) +{ + int newsize; + int oldsize = 0; + + spin_lock(&dentry->d_lock); + if (!dtopd_nocheck(dentry)) { + dtopd_lhs(dentry) = (struct unionfs_dentry_info *) + kmem_cache_alloc(unionfs_dentry_cachep, GFP_ATOMIC); + if (!dtopd_nocheck(dentry)) + goto out; +#ifdef CONFIG_PREEMPT_RT + init_MUTEX(&dtopd_nocheck(dentry)->udi_sem); + down(&dtopd_nocheck(dentry)->udi_sem); +#else + init_MUTEX_LOCKED(&dtopd_nocheck(dentry)->udi_sem); +#endif + +#ifdef TRACKLOCK + printk("INITLOCK:%p\n", dentry); +#endif + dtohd_ptr(dentry) = NULL; + } else { + oldsize = sizeof(struct dentry *) * dtopd(dentry)->udi_bcount; + } + + dtopd_nocheck(dentry)->udi_bstart = -1; + dtopd_nocheck(dentry)->udi_bend = -1; + dtopd_nocheck(dentry)->udi_bopaque = -1; + dtopd_nocheck(dentry)->udi_bcount = sbmax(dentry->d_sb); + atomic_set(&dtopd_nocheck(dentry)->udi_generation, + atomic_read(&stopd(dentry->d_sb)->usi_generation)); + newsize = sizeof(struct dentry *) * sbmax(dentry->d_sb); + + /* Don't reallocate when we already have enough space. */ + /* It would be ideal if we could actually use the slab macros to + * determine what our object sizes is, but those are not exported. + */ + if (oldsize) { + int minsize = 128; + + if (!newsize || ((oldsize < newsize) && (newsize > minsize))) { + KFREE(dtohd_ptr(dentry)); + dtohd_ptr(dentry) = NULL; + } + } + + if (!dtohd_ptr(dentry) && newsize) { + dtohd_ptr(dentry) = KMALLOC(newsize, GFP_ATOMIC); + if (!dtohd_ptr(dentry)) + goto out; + } + + if (oldsize > newsize) + memset(dtohd_ptr(dentry), 0, oldsize); + else + memset(dtohd_ptr(dentry), 0, newsize); + + spin_unlock(&dentry->d_lock); + return 0; + + out: + free_dentry_private_data(dtopd_nocheck(dentry)); + dtopd_lhs(dentry) = NULL; + spin_unlock(&dentry->d_lock); + return -ENOMEM; +} + +void update_bstart(struct dentry *dentry) +{ + int bindex; + int bstart = dbstart(dentry); + int bend = dbend(dentry); + struct dentry *hidden_dentry; + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + if (hidden_dentry->d_inode) { + set_dbstart(dentry, bindex); + break; + } + DPUT(hidden_dentry); + set_dtohd_index(dentry, bindex, NULL); + } +} + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/inode.c +++ linux-2.6.28/ubuntu/unionfs/inode.c @@ -0,0 +1,1034 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef 'Jeff' Sipek + * Copyright (c) 2005-2006 Junjiro Okajima + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: inode.c,v 1.275 2006/10/31 18:05:33 yiannos Exp $ + */ + +#include "unionfs.h" + +/* declarations added for "sparse" */ +extern struct dentry *unionfs_lookup(struct inode *, struct dentry *, + struct nameidata *); +extern int unionfs_readlink(struct dentry *dentry, char __user * buf, + int bufsiz); +extern void unionfs_put_link(struct dentry *dentry, struct nameidata *nd, + void *cookie); + +static int unionfs_create(struct inode *parent, struct dentry *dentry, + int mode, struct nameidata *nd) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct dentry *whiteout_dentry = NULL; + struct dentry *new_hidden_dentry; + struct dentry *hidden_parent_dentry = NULL; + int bindex = 0, bstart; + char *name = NULL; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_create", dentry); + + /* We start out in the leftmost branch. */ + bstart = dbstart(dentry); + hidden_dentry = dtohd(dentry); + + /* check if whiteout exists in this branch, i.e. lookup .wh.foo first */ + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + whiteout_dentry = NULL; + goto out; + } + + if (whiteout_dentry->d_inode) { + /* .wh.foo has been found. */ + /* First truncate it and then rename it to foo (hence having + * the same overall effect as a normal create. + * + * XXX: This is not strictly correct. If we have unlinked the + * file and it still has a reference count, then we should + * actually unlink the whiteout so that user's data isn't + * hosed over. + */ + struct dentry *hidden_dir_dentry; + struct iattr newattrs; + + mutex_lock(&whiteout_dentry->d_inode->i_mutex); + newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME + | ATTR_MTIME | ATTR_UID | ATTR_GID | ATTR_FORCE + | ATTR_KILL_SUID | ATTR_KILL_SGID; + + newattrs.ia_mode = mode & ~current->fs->umask; + newattrs.ia_uid = current->fsuid; + newattrs.ia_gid = current->fsgid; + + if (whiteout_dentry->d_inode->i_size != 0) { + newattrs.ia_valid |= ATTR_SIZE; + newattrs.ia_size = 0; + } + + err = notify_change(whiteout_dentry, NULL, &newattrs); + + mutex_unlock(&whiteout_dentry->d_inode->i_mutex); + + if (err) + printk(KERN_WARNING + "unionfs: %s:%d: notify_change failed: %d, ignoring..\n", + __FILE__, __LINE__, err); + + new_hidden_dentry = dtohd(dentry); + DGET(new_hidden_dentry); + + hidden_dir_dentry = GET_PARENT(whiteout_dentry); + lock_rename(hidden_dir_dentry, hidden_dir_dentry); + + if (!(err = is_robranch_super(dentry->d_sb, bstart))) { + err = + vfs_rename(hidden_dir_dentry->d_inode, + whiteout_dentry, NULL, + hidden_dir_dentry->d_inode, + new_hidden_dentry, NULL); + } + if (!err) { + fist_copy_attr_timesizes(parent, + new_hidden_dentry->d_parent-> + d_inode); + parent->i_nlink = get_nlinks(parent); + } + + unlock_rename(hidden_dir_dentry, hidden_dir_dentry); + DPUT(hidden_dir_dentry); + + DPUT(new_hidden_dentry); + + if (err) { + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + /* We were not able to create the file in this branch, + * so, we try to create it in one branch to left + */ + bstart--; + } else { + /* reset the unionfs dentry to point to the .wh.foo entry. */ + + /* Discard any old reference. */ + DPUT(dtohd(dentry)); + + /* Trade one reference to another. */ + set_dtohd_index(dentry, bstart, whiteout_dentry); + whiteout_dentry = NULL; + + err = unionfs_interpose(dentry, parent->i_sb, 0); + goto out; + } + } + + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + /* if hidden_dentry is NULL, create the entire + * dentry directory structure in branch 'bindex'. + * hidden_dentry will NOT be null when bindex == bstart + * because lookup passed as a negative unionfs dentry + * pointing to a lone negative underlying dentry */ + hidden_dentry = create_parents(parent, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + if (IS_ERR(hidden_dentry)) + err = PTR_ERR(hidden_dentry); + continue; + } + } + + checkinode(parent, "unionfs_create"); + + hidden_parent_dentry = lock_parent(hidden_dentry); + if (IS_ERR(hidden_parent_dentry)) { + err = PTR_ERR(hidden_parent_dentry); + goto out; + } + /* We shouldn't create things in a read-only branch. */ + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + //DQ: vfs_create has a different prototype in 2.6 + err = vfs_create(hidden_parent_dentry->d_inode, + hidden_dentry, mode, nd); + } + if (err || !hidden_dentry->d_inode) { + unlock_dir(hidden_parent_dentry); + + /* break out of for loop if the error wasn't -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + err = unionfs_interpose(dentry, parent->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(parent, + hidden_parent_dentry-> + d_inode); + /* update number of links on parent directory */ + parent->i_nlink = get_nlinks(parent); + } + unlock_dir(hidden_parent_dentry); + break; + } + } + + out: + DPUT(whiteout_dentry); + KFREE(name); + + print_dentry("OUT unionfs_create :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +struct dentry *unionfs_lookup(struct inode *parent, struct dentry *dentry, + struct nameidata *nd) +{ + struct nameidata lowernd; + + if(nd) + memcpy(&lowernd, nd, sizeof(struct nameidata)); + else + memset(&lowernd, 0, sizeof(struct nameidata)); + + /* The locking is done by unionfs_lookup_backend. */ + return unionfs_lookup_backend(dentry, &lowernd, INTERPOSE_LOOKUP); +} + +static int unionfs_link(struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry) +{ + int err = 0; + struct dentry *hidden_old_dentry = NULL; + struct dentry *hidden_new_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + struct dentry *whiteout_dentry; + char *name = NULL; + + print_entry_location(); + double_lock_dentry(new_dentry, old_dentry); + + hidden_new_dentry = dtohd(new_dentry); + + /* check if whiteout exists in the branch of new dentry, i.e. lookup + * .wh.foo first. If present, delete it */ + name = alloc_whname(new_dentry->d_name.name, new_dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_new_dentry->d_parent, + new_dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + /* found a .wh.foo entry, unlink it and then call vfs_link() */ + hidden_dir_dentry = lock_parent(whiteout_dentry); + if (! + (err = + is_robranch_super(new_dentry->d_sb, + dbstart(new_dentry)))) { + err = + vfs_unlink(hidden_dir_dentry->d_inode, + whiteout_dentry, NULL); + } + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + dir->i_nlink = get_nlinks(dir); + unlock_dir(hidden_dir_dentry); + hidden_dir_dentry = NULL; + DPUT(whiteout_dentry); + if (err) + goto out; + } + + if (dbstart(old_dentry) != dbstart(new_dentry)) { + hidden_new_dentry = + create_parents(dir, new_dentry, dbstart(old_dentry)); + err = PTR_ERR(hidden_new_dentry); + if (IS_COPYUP_ERR(err)) + goto docopyup; + if (!hidden_new_dentry || IS_ERR(hidden_new_dentry)) + goto out; + } + hidden_new_dentry = dtohd(new_dentry); + hidden_old_dentry = dtohd(old_dentry); + + BUG_ON(dbstart(old_dentry) != dbstart(new_dentry)); + hidden_dir_dentry = lock_parent(hidden_new_dentry); + if (!(err = is_robranch(old_dentry))) + err = + vfs_link(hidden_old_dentry, NULL, + hidden_dir_dentry->d_inode, + hidden_new_dentry, NULL); + unlock_dir(hidden_dir_dentry); + + docopyup: + if (IS_COPYUP_ERR(err)) { + int old_bstart = dbstart(old_dentry); + int bindex; + + for (bindex = old_bstart - 1; bindex >= 0; bindex--) { + err = + copyup_dentry(old_dentry->d_parent-> + d_inode, old_dentry, + old_bstart, bindex, NULL, + old_dentry->d_inode->i_size); + if (!err) { + hidden_new_dentry = + create_parents(dir, new_dentry, bindex); + hidden_old_dentry = dtohd(old_dentry); + hidden_dir_dentry = + lock_parent(hidden_new_dentry); + /* do vfs_link */ + err = vfs_link(hidden_old_dentry, NULL, + hidden_dir_dentry->d_inode, + hidden_new_dentry, NULL); + unlock_dir(hidden_dir_dentry); + goto check_link; + } + } + goto out; + } + check_link: + if (err || !hidden_new_dentry->d_inode) + goto out; + + /* Its a hard link, so use the same inode */ + new_dentry->d_inode = IGRAB(old_dentry->d_inode); + d_instantiate(new_dentry, new_dentry->d_inode); + fist_copy_attr_all(dir, hidden_new_dentry->d_parent->d_inode); + /* propagate number of hard-links */ + old_dentry->d_inode->i_nlink = get_nlinks(old_dentry->d_inode); + + out: + if (!new_dentry->d_inode) + d_drop(new_dentry); + + KFREE(name); + + unlock_dentry(new_dentry); + unlock_dentry(old_dentry); + + print_exit_status(err); + return err; +} + +static int unionfs_symlink(struct inode *dir, struct dentry *dentry, + const char *symname) +{ + int err = 0; + struct dentry *hidden_dentry = NULL; + struct dentry *whiteout_dentry = NULL; + struct dentry *hidden_dir_dentry = NULL; + umode_t mode; + int bindex = 0, bstart; + char *name = NULL; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_symlink", dentry); + + /* We start out in the leftmost branch. */ + bstart = dbstart(dentry); + + hidden_dentry = dtohd(dentry); + + /* check if whiteout exists in this branch, i.e. lookup .wh.foo first. If present, delete it */ + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + /* found a .wh.foo entry, unlink it and then call vfs_symlink() */ + hidden_dir_dentry = lock_parent(whiteout_dentry); + + print_dentry("HDD", hidden_dir_dentry); + print_dentry("WD", whiteout_dentry); + + if (!(err = is_robranch_super(dentry->d_sb, bstart))) { + err = + vfs_unlink(hidden_dir_dentry->d_inode, + whiteout_dentry, NULL); + } + DPUT(whiteout_dentry); + + fist_copy_attr_times(dir, hidden_dir_dentry->d_inode); + /* propagate number of hard-links */ + dir->i_nlink = get_nlinks(dir); + + unlock_dir(hidden_dir_dentry); + + if (err) { + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + /* should now try to create symlink in the another branch */ + bstart--; + } + } + + /* deleted whiteout if it was present, now do a normal vfs_symlink() with + possible recursive directory creation */ + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + /* if hidden_dentry is NULL, create the entire + * dentry directory structure in branch 'bindex'. hidden_dentry will NOT be null when + * bindex == bstart because lookup passed as a negative unionfs dentry pointing to a + * lone negative underlying dentry */ + hidden_dentry = create_parents(dir, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + if (IS_ERR(hidden_dentry)) { + err = PTR_ERR(hidden_dentry); + } + dprint(PRINT_DEBUG, + "hidden dentry NULL (or error) for bindex = %d\n", + bindex); + continue; + } + } + + hidden_dir_dentry = lock_parent(hidden_dentry); + + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + mode = S_IALLUGO; + err = + vfs_symlink(hidden_dir_dentry->d_inode, + hidden_dentry, NULL, symname); + } + unlock_dir(hidden_dir_dentry); + + if (err || !hidden_dentry->d_inode) { + /* break out of for loop if error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + err = unionfs_interpose(dentry, dir->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(dir, + hidden_dir_dentry-> + d_inode); + /* update number of links on parent directory */ + dir->i_nlink = get_nlinks(dir); + } + break; + } + } + + out: + if (!dentry->d_inode) + d_drop(dentry); + + KFREE(name); + print_dentry("OUT unionfs_symlink :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +static int unionfs_mkdir(struct inode *parent, struct dentry *dentry, int mode) +{ + int err = 0; + struct dentry *hidden_dentry = NULL, *whiteout_dentry = NULL; + struct dentry *hidden_parent_dentry = NULL; + int bindex = 0, bstart; + char *name = NULL; + int whiteout_unlinked = 0; + struct sioq_args args; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_mkdir", dentry); + bstart = dbstart(dentry); + + hidden_dentry = dtohd(dentry); + + // check if whiteout exists in this branch, i.e. lookup .wh.foo first + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + hidden_parent_dentry = lock_parent(whiteout_dentry); + + //found a.wh.foo entry, remove it then do vfs_mkdir + if (!(err = is_robranch_super(dentry->d_sb, bstart))) { + args.unlink.parent = hidden_parent_dentry->d_inode; + args.unlink.dentry = whiteout_dentry; + run_sioq(__unionfs_unlink, &args); + err = args.err; + } + DPUT(whiteout_dentry); + + unlock_dir(hidden_parent_dentry); + + if (err) { + /* exit if the error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + goto out; + bstart--; + } else { + whiteout_unlinked = 1; + } + } + + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + hidden_dentry = create_parents(parent, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + dprint(PRINT_DEBUG, + "hidden dentry NULL for bindex = %d\n", + bindex); + continue; + } + } + + hidden_parent_dentry = lock_parent(hidden_dentry); + if (IS_ERR(hidden_parent_dentry)) { + err = PTR_ERR(hidden_parent_dentry); + goto out; + } + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + err = + vfs_mkdir(hidden_parent_dentry->d_inode, + hidden_dentry, NULL, mode); + } + unlock_dir(hidden_parent_dentry); + + /* XXX this could potentially return a negative hidden_dentry! */ + if (err || !hidden_dentry->d_inode) { + /* break out of for loop if error returned was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + int i; + int bend = dbend(dentry); + + for (i = bindex + 1; i < bend; i++) { + if (dtohd_index(dentry, i)) { + DPUT(dtohd_index(dentry, i)); + set_dtohd_index(dentry, i, NULL); + } + } + bend = bindex; + set_dbend(dentry, bend); + + err = unionfs_interpose(dentry, parent->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(parent, + hidden_parent_dentry-> + d_inode); + /* update number of links on parent directory */ + parent->i_nlink = get_nlinks(parent); + } + + err = make_dir_opaque(dentry, dbstart(dentry)); + if (err) { + dprint(PRINT_DEBUG, + "mkdir: error creating directory override entry: %d\n", + err); + goto out; + } + break; + } + } + + out: + if (!dentry->d_inode) + d_drop(dentry); + + KFREE(name); + + print_dentry("OUT unionfs_mkdir :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +static int unionfs_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev) +{ + int err = 0; + struct dentry *hidden_dentry = NULL, *whiteout_dentry = NULL; + struct dentry *hidden_parent_dentry = NULL; + int bindex = 0, bstart; + char *name = NULL; + int whiteout_unlinked = 0; + + print_entry_location(); + lock_dentry(dentry); + print_dentry("IN unionfs_mknod", dentry); + bstart = dbstart(dentry); + + hidden_dentry = dtohd(dentry); + + // check if whiteout exists in this branch, i.e. lookup .wh.foo first + name = alloc_whname(dentry->d_name.name, dentry->d_name.len); + if (IS_ERR(name)) { + err = PTR_ERR(name); + goto out; + } + + whiteout_dentry = + LOOKUP_ONE_LEN(name, hidden_dentry->d_parent, + dentry->d_name.len + WHLEN); + if (IS_ERR(whiteout_dentry)) { + err = PTR_ERR(whiteout_dentry); + goto out; + } + + if (!whiteout_dentry->d_inode) { + DPUT(whiteout_dentry); + whiteout_dentry = NULL; + } else { + /* found .wh.foo, unlink it */ + hidden_parent_dentry = lock_parent(whiteout_dentry); + + //found a.wh.foo entry, remove it then do vfs_mkdir + if (!(err = is_robranch_super(dentry->d_sb, bstart))) + err = vfs_unlink(hidden_parent_dentry->d_inode, + whiteout_dentry, NULL); + DPUT(whiteout_dentry); + + unlock_dir(hidden_parent_dentry); + + if (err) { + if (!IS_COPYUP_ERR(err)) + goto out; + + bstart--; + } else { + whiteout_unlinked = 1; + } + } + + for (bindex = bstart; bindex >= 0; bindex--) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) { + hidden_dentry = create_parents(dir, dentry, bindex); + if (!hidden_dentry || IS_ERR(hidden_dentry)) { + dprint(PRINT_DEBUG, + "hidden dentry NULL for bindex = %d\n", + bindex); + continue; + } + } + + hidden_parent_dentry = lock_parent(hidden_dentry); + if (IS_ERR(hidden_parent_dentry)) { + err = PTR_ERR(hidden_parent_dentry); + goto out; + } + if (!(err = is_robranch_super(dentry->d_sb, bindex))) { + err = vfs_mknod(hidden_parent_dentry->d_inode, + hidden_dentry, NULL, mode, dev); + } + /* XXX this could potentially return a negative hidden_dentry! */ + if (err || !hidden_dentry->d_inode) { + unlock_dir(hidden_parent_dentry); + /* break out of for, if error was NOT -EROFS */ + if (!IS_COPYUP_ERR(err)) + break; + } else { + err = unionfs_interpose(dentry, dir->i_sb, 0); + if (!err) { + fist_copy_attr_timesizes(dir, + hidden_parent_dentry-> + d_inode); + /* update number of links on parent directory */ + dir->i_nlink = get_nlinks(dir); + } + unlock_dir(hidden_parent_dentry); + + break; + } + } + + out: + if (!dentry->d_inode) + d_drop(dentry); + + if (name) { + KFREE(name); + } + + print_dentry("OUT unionfs_mknod :", dentry); + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +int unionfs_readlink(struct dentry *dentry, char __user * buf, int bufsiz) +{ + int err; + struct dentry *hidden_dentry; + + print_entry_location(); + lock_dentry(dentry); + hidden_dentry = dtohd(dentry); + print_dentry("unionfs_readlink IN", dentry); + + if (!hidden_dentry->d_inode->i_op || + !hidden_dentry->d_inode->i_op->readlink) { + err = -EINVAL; + goto out; + } + + err = hidden_dentry->d_inode->i_op->readlink(hidden_dentry, + buf, bufsiz); + if (err > 0) + fist_copy_attr_atime(dentry->d_inode, hidden_dentry->d_inode); + + out: + unlock_dentry(dentry); + print_exit_status(err); + return err; +} + +/* We don't lock the dentry here, because readlink does the heavy lifting. */ +static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + char *buf; + int len = PAGE_SIZE, err; + mm_segment_t old_fs; + + print_entry_location(); + + /* This is freed by the put_link method assuming a successful call. */ + buf = (char *)KMALLOC(len, GFP_KERNEL); + if (!buf) { + err = -ENOMEM; + goto out; + } + + /* read the symlink, and then we will follow it */ + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len); + set_fs(old_fs); + if (err < 0) { + KFREE(buf); + buf = NULL; + goto out; + } + buf[err] = 0; + nd_set_link(nd, buf); + err = 0; + + out: + print_exit_status(err); + return ERR_PTR(err); +} + +void unionfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) +{ + char *link; + print_entry_location(); + link = nd_get_link(nd); + KFREE(link); + print_exit_location(); +} + +/* Basically copied from the kernel vfs permission(), but we've changed + * the following: (1) the IS_RDONLY check is skipped, and (2) if you set + * the mount option `nfsperms=insceure', we assume that -EACCES means that + * the export is read-only and we should check standard Unix permissions. + * This means that NFS ACL checks (or other advanced permission features) + * are bypassed. + */ +static int unionfs_inode_permission(struct inode *inode, int mask, struct nameidata *nd, + int bindex) +{ + int retval, submask; + + if (mask & MAY_WRITE) { + /* The first branch is allowed to be really readonly. */ + if (bindex == 0) { + umode_t mode = inode->i_mode; + if (IS_RDONLY(inode) && (S_ISREG(mode) || S_ISDIR(mode) + || S_ISLNK(mode))) + return -EROFS; + } + /* + * Nobody gets write access to an immutable file. + */ + if (IS_IMMUTABLE(inode)) + return -EACCES; + } + + /* Ordinary permission routines do not understand MAY_APPEND. */ + submask = mask & ~MAY_APPEND; + if (inode->i_op && inode->i_op->permission) { + retval = inode->i_op->permission(inode, submask); + if ((retval == -EACCES) && (submask & MAY_WRITE) && + (!strcmp("nfs", (inode)->i_sb->s_type->name)) && + (nd) && (nd->path.mnt) && (nd->path.mnt->mnt_sb) && + (branchperms(nd->path.mnt->mnt_sb, bindex) & MAY_NFSRO)) { + retval = generic_permission(inode, submask, NULL); + } + } else { + retval = generic_permission(inode, submask, NULL); + } + + if (retval && retval != -EROFS) /* ignore EROFS */ + return retval; + + /* + * skip the LSM permission check. This means unionfs will wrongly + * copy up a LSM non-writable/non-readable file on a readonly branch + * to a read-write branch leading to odd behaviour. Until the mess + * of the LSM interface changes are resolved, there's nothing else + * that can be done. + * retval = security_inode_permission(inode, mask, nd); + */ + return ((retval == -EROFS) ? 0 : retval); /* ignore EROFS */ +} + +static int unionfs_permission(struct inode *inode, int mask) +{ + struct inode *hidden_inode = NULL; + int err = 0; + int bindex, bstart, bend; + const int is_file = !S_ISDIR(inode->i_mode); + const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ); + + print_entry_location(); + + bstart = ibstart(inode); + bend = ibend(inode); + + print_inode("IN unionfs_permission", inode); + + for (bindex = bstart; bindex <= bend; bindex++) { + hidden_inode = itohi_index(inode, bindex); + if (!hidden_inode) + continue; + + /* check the condition for D-F-D underlying files/directories, + * we dont have to check for files, if we are checking for + * directories. + */ + if (!is_file && !S_ISDIR(hidden_inode->i_mode)) + continue; + /* We use our own special version of permission, such that + * only the first branch returns -EROFS. */ + err = unionfs_inode_permission(hidden_inode, mask, NULL, bindex); + /* The permissions are an intersection of the overall directory + * permissions, so we fail if one fails. */ + if (err) + goto out; + /* only the leftmost file matters. */ + if (is_file || write_mask) { + if (is_file && write_mask) { + err = get_write_access(hidden_inode); + if (!err) + put_write_access(hidden_inode); + } + break; + } + } + + out: + print_exit_status(err); + return err; +} + +static int unionfs_setattr(struct dentry *dentry, struct iattr *ia) +{ + int err = 0; + struct dentry *hidden_dentry; + struct inode *inode = NULL; + struct inode *hidden_inode = NULL; + int bstart, bend, bindex; + int i; + int copyup = 0; + + print_entry_location(); + lock_dentry(dentry); + bstart = dbstart(dentry); + bend = dbend(dentry); + inode = dentry->d_inode; + + for (bindex = bstart; (bindex <= bend) || (bindex == bstart); bindex++) { + hidden_dentry = dtohd_index(dentry, bindex); + if (!hidden_dentry) + continue; + BUG_ON(hidden_dentry->d_inode == NULL); + + /* If the file is on a read only branch */ + if (is_robranch_super(dentry->d_sb, bindex) + || IS_RDONLY(hidden_dentry->d_inode)) { + if (copyup || (bindex != bstart)) + continue; + /* Only if its the leftmost file, copyup the file */ + for (i = bstart - 1; i >= 0; i--) { + loff_t size = dentry->d_inode->i_size; + if (ia->ia_valid & ATTR_SIZE) + size = ia->ia_size; + err = copyup_dentry(dentry->d_parent->d_inode, + dentry, bstart, i, NULL, + size); + + if (!err) { + copyup = 1; + hidden_dentry = dtohd(dentry); + break; + } + /* if error is in the leftmost f/s, pass it up */ + if (i == 0) + goto out; + } + + } + /* + * mode change is for clearing setuid/setgid bits. Allow lower fs + * to interpret this in its own way. + */ + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) + ia->ia_valid &= ~ATTR_MODE; + + err = notify_change(hidden_dentry, NULL, ia); + if (err) + goto out; + break; + } +#ifdef UNIONFS_MMAP + /* + * SP: notify_change will change the lower file's size, + * but we need to truncate the page tables, so need to call + * vmtruncate() + */ + + if (ia->ia_valid & ATTR_SIZE) { + if (ia->ia_size != i_size_read(inode)) { + err = vmtruncate(inode, ia->ia_size); + if (err) { + printk("unionfs_setattr: vmtruncate failed\n"); + } + } + } +#endif + /* get the size from the first hidden inode */ + hidden_inode = itohi(dentry->d_inode); + checkinode(inode, "unionfs_setattr"); + fist_copy_attr_all(inode, hidden_inode); + + out: + unlock_dentry(dentry); + checkinode(inode, "post unionfs_setattr"); + print_exit_status(err); + return err; +} + +struct inode_operations unionfs_symlink_iops = { + .readlink = unionfs_readlink, + .permission = unionfs_permission, + .follow_link = unionfs_follow_link, + .setattr = unionfs_setattr, + .put_link = unionfs_put_link, +}; + +struct inode_operations unionfs_dir_iops = { + .create = unionfs_create, + .lookup = unionfs_lookup, + .link = unionfs_link, + .unlink = unionfs_unlink, + .symlink = unionfs_symlink, + .mkdir = unionfs_mkdir, + .rmdir = unionfs_rmdir, + .mknod = unionfs_mknod, + .rename = unionfs_rename, + .permission = unionfs_permission, + .setattr = unionfs_setattr, + .setxattr = unionfs_setxattr, + .getxattr = unionfs_getxattr, + .removexattr = unionfs_removexattr, + .listxattr = unionfs_listxattr, +}; + +struct inode_operations unionfs_main_iops = { + .permission = unionfs_permission, + .setattr = unionfs_setattr, + .setxattr = unionfs_setxattr, + .getxattr = unionfs_getxattr, + .removexattr = unionfs_removexattr, + .listxattr = unionfs_listxattr, +}; + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/unionfs/BOM +++ linux-2.6.28/ubuntu/unionfs/BOM @@ -0,0 +1,7 @@ +Downloaded from: http://www.filesystems.org/project-unionfs.html +Current Version: 1.4 + +Don't bother updating this code. No, we do not want 2.3.x. Yes, this is +heavily patched to account for upstream VFS API changes and AppArmor. + +DO NOT TOUCH :) --- linux-2.6.28.orig/ubuntu/unionfs/unionfs_macros.h +++ linux-2.6.28/ubuntu/unionfs/unionfs_macros.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2003-2006 Erez Zadok + * Copyright (c) 2003-2006 Charles P. Wright + * Copyright (c) 2005-2006 Josef Sipek + * Copyright (c) 2005 Arun M. Krishnakumar + * Copyright (c) 2005-2006 David P. Quigley + * Copyright (c) 2003-2004 Mohammad Nayyer Zubair + * Copyright (c) 2003 Puja Gupta + * Copyright (c) 2003 Harikesavan Krishnan + * Copyright (c) 2003-2006 Stony Brook University + * Copyright (c) 2003-2006 The Research Foundation of State University of New York + * + * For specific licensing information, see the COPYING file distributed with + * this package. + * + * This Copyright notice must be kept intact and distributed with all sources. + */ +/* + * $Id: unionfs_macros.h,v 1.13 2006/06/01 03:11:03 jsipek Exp $ + */ + +#ifndef __UNIONFS_H_ +#error This file should only be included from unionfs.h! +#endif + +/* Inode to private data */ +static inline struct unionfs_inode_info *itopd(const struct inode *inode) +{ + return + &(container_of(inode, struct unionfs_inode_container, vfs_inode)-> + info); +} + +#define itohi_ptr(ino) (itopd(ino)->uii_inode) +#define ibstart(ino) (itopd(ino)->b_start) +#define ibend(ino) (itopd(ino)->b_end) + +/* Superblock to private data */ +#define stopd(super) ((struct unionfs_sb_info *)(super)->s_fs_info) +#define stopd_lhs(super) ((super)->s_fs_info) +#define sbstart(sb) 0 +#define sbend(sb) stopd(sb)->b_end +#define sbmax(sb) (stopd(sb)->b_end + 1) + +/* File to private Data */ +#define ftopd(file) ((struct unionfs_file_info *)((file)->private_data)) +#define ftopd_lhs(file) ((file)->private_data) +#define ftohf_ptr(file) (ftopd(file)->ufi_file) +#define fbstart(file) (ftopd(file)->b_start) +#define fbend(file) (ftopd(file)->b_end) + +/* File to hidden file. */ +static inline struct file *ftohf(struct file *f) +{ + return ftopd(f)->ufi_file[fbstart(f)]; +} + +static inline struct file *ftohf_index(const struct file *f, int index) +{ + return ftopd(f)->ufi_file[index]; +} + +static inline void set_ftohf_index(struct file *f, int index, struct file *val) +{ + ftopd(f)->ufi_file[index] = val; +} + +static inline void set_ftohf(struct file *f, struct file *val) +{ + ftopd(f)->ufi_file[fbstart(f)] = val; +} + +/* Inode to hidden inode. */ +static inline struct inode *itohi(const struct inode *i) +{ + return itopd(i)->uii_inode[ibstart(i)]; +} + +static inline struct inode *itohi_index(const struct inode *i, int index) +{ + return itopd(i)->uii_inode[index]; +} + +static inline void set_itohi_index(struct inode *i, int index, + struct inode *val) +{ + itopd(i)->uii_inode[index] = val; +} + +static inline void set_itohi(struct inode *i, struct inode *val) +{ + itopd(i)->uii_inode[ibstart(i)] = val; +} + +/* Superblock to hidden superblock. */ +static inline struct super_block *stohs(const struct super_block *o) +{ + return stopd(o)->usi_data[sbstart(o)].sb; +} + +static inline struct super_block *stohs_index(const struct super_block *o, int index) +{ + return stopd(o)->usi_data[index].sb; +} + +static inline void set_stohs_index(struct super_block *o, int index, + struct super_block *val) +{ + stopd(o)->usi_data[index].sb = val; +} + +static inline void set_stohs(struct super_block *o, struct super_block *val) +{ + stopd(o)->usi_data[sbstart(o)].sb = val; +} + +/* Super to hidden mount. */ +static inline struct vfsmount *stohiddenmnt_index(struct super_block *o, + int index) +{ + return stopd(o)->usi_data[index].hidden_mnt; +} + +static inline void set_stohiddenmnt_index(struct super_block *o, int index, + struct vfsmount *val) +{ + stopd(o)->usi_data[index].hidden_mnt = val; +} + +/* Branch count macros. */ +static inline int branch_count(struct super_block *o, int index) +{ + return atomic_read(&stopd(o)->usi_data[index].sbcount); +} + +static inline void set_branch_count(struct super_block *o, int index, int val) +{ + atomic_set(&stopd(o)->usi_data[index].sbcount, val); +} + +static inline void branchget(struct super_block *o, int index) +{ + atomic_inc(&stopd(o)->usi_data[index].sbcount); +} + +static inline void branchput(struct super_block *o, int index) +{ + atomic_dec(&stopd(o)->usi_data[index].sbcount); +} + +/* Dentry macros */ +static inline struct unionfs_dentry_info *dtopd(const struct dentry *dent) +{ + return (struct unionfs_dentry_info *)dent->d_fsdata; +} + +#define dtopd_lhs(dent) ((dent)->d_fsdata) +#define dtopd_nocheck(dent) dtopd(dent) +#define dbstart(dent) (dtopd(dent)->udi_bstart) +#define set_dbstart(dent, val) do { dtopd(dent)->udi_bstart = val; } while(0) +#define dbend(dent) (dtopd(dent)->udi_bend) +#define set_dbend(dent, val) do { dtopd(dent)->udi_bend = val; } while(0) +#define dbopaque(dent) (dtopd(dent)->udi_bopaque) +#define set_dbopaque(dent, val) do { dtopd(dent)->udi_bopaque = val; } while (0) + +static inline void set_dtohd_index(struct dentry *dent, int index, + struct dentry *val) +{ + dtopd(dent)->udi_dentry[index] = val; +} + +static inline struct dentry *dtohd_index(const struct dentry *dent, int index) +{ + return dtopd(dent)->udi_dentry[index]; +} + +static inline struct dentry *dtohd(const struct dentry *dent) +{ + return dtopd(dent)->udi_dentry[dbstart(dent)]; +} + +#define set_dtohd_index_nocheck(dent, index, val) set_dtohd_index(dent, index, val) +#define dtohd_index_nocheck(dent, index) dtohd_index(dent, index) + +#define dtohd_ptr(dent) (dtopd_nocheck(dent)->udi_dentry) + +/* Macros for locking a dentry. */ +#define lock_dentry(d) down(&dtopd(d)->udi_sem) +#define unlock_dentry(d) up(&dtopd(d)->udi_sem) +#define verify_locked(d) + +/* + * + * vim:shiftwidth=8 + * vim:tabstop=8 + * + * For Emacs: + * Local variables: + * c-basic-offset: 8 + * c-comment-only-line-offset: 0 + * c-offsets-alist: ((statement-block-intro . +) (knr-argdecl-intro . 0) + * (substatement-open . 0) (label . 0) (statement-cont . +)) + * indent-tabs-mode: t + * tab-width: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/rfkill/Kconfig +++ linux-2.6.28/ubuntu/rfkill/Kconfig @@ -0,0 +1,7 @@ +config AVERATEC_5100P + tristate "Software kill switch for Averatec 5100P" + default m + +config PACKARDBELL_E5 + tristate "Software kill switch for Packard Bell EasyNote E5" + default m --- linux-2.6.28.orig/ubuntu/rfkill/pbe5.c +++ linux-2.6.28/ubuntu/rfkill/pbe5.c @@ -0,0 +1,205 @@ +/******************************************************************************* + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License 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. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Author: + Pedro Ramalhais + + Based on: + av5100.c from http://ipw2100.sourceforge.net/ + +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "pbe5" +#define DRV_VERSION "1.3" +#define DRV_DESCRIPTION "SW RF kill switch for Packard Bell EasyNote E5" +#define DRV_AUTHOR "Pedro Ramalhais" +#define DRV_LICENSE "GPL" + +static int radio = 1; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + +MODULE_PARM(radio, "i"); + +#else /* LINUX_VERSION_CODE < 2.6.0 */ + +#include +module_param(radio, int, 1); + +#endif /* LINUX_VERSION_CODE < 2.6.0 */ + +MODULE_PARM_DESC(radio, "controls state of radio (1=on, 0=off)"); + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_AUTHOR); +MODULE_LICENSE(DRV_LICENSE); + +/* + * NOTE: These values were obtained from disassembling the Icon.exe program + * installed in the Packard Bell EasyNote E5 laptop. The names were guessed, + * so don't rely on them. + */ +#define PBE5_PORT_TOGGLE 0x0b3 +#define PBE5_VALUE_TOGGLE_ON 0x01 +#define PBE5_VALUE_TOGGLE_OFF 0x00 +#define PBE5_PORT_APPLY 0x0b2 +#define PBE5_VALUE_APPLY 0xef + +// Some "booleans" =;-) +#define PBE5_RADIO_OFF 0 +#define PBE5_RADIO_ON 1 + +static int pbe5_radio_status = PBE5_RADIO_ON; + +unsigned char pbe5_get_radio(void) +{ + unsigned char val = 0x00; + + val = inb(PBE5_PORT_TOGGLE); + + return val; +} + +static void pbe5_set_radio(int state_set) +{ + pbe5_radio_status = pbe5_get_radio(); + + if (pbe5_radio_status != state_set) { + // Set the radio toggle register + outb(PBE5_VALUE_TOGGLE_ON, PBE5_PORT_TOGGLE); + // Commit the radio toggle register value + outb(PBE5_VALUE_APPLY, PBE5_PORT_APPLY); + // Update the radio status + pbe5_radio_status = pbe5_get_radio(); + + printk(KERN_INFO DRV_NAME ": Radio turned %s\n", + (state_set == PBE5_RADIO_ON) ? "ON" : "OFF"); + } else { + printk(KERN_INFO DRV_NAME ": Radio already %s\n", + (state_set == PBE5_RADIO_ON) ? "ON" : "OFF"); + } +} + + +/* + * proc stuff + */ +static struct proc_dir_entry *dir_base = NULL; + +static int proc_set_radio(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + pbe5_set_radio(buffer[0] == '0' ? PBE5_RADIO_OFF : PBE5_RADIO_ON); + + return count; +} + +static int proc_get_radio(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + + len += snprintf(page, count, DRV_NAME ": %d\n", + pbe5_radio_status == PBE5_RADIO_OFF ? 0 : 1); + + *eof = 1; + return len; +} + + +static void pbe5_proc_cleanup(void) +{ + if (dir_base) { + remove_proc_entry("radio", dir_base); + remove_proc_entry(DRV_NAME, NULL); + dir_base = NULL; + } +} + + +static int pbe5_proc_init(void) +{ + struct proc_dir_entry *ent; + int err = 0; + + dir_base = create_proc_entry(DRV_NAME, S_IFDIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" + DRV_NAME "\n"); + err = -ENOMEM; + goto fail; + } + + + ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR, + dir_base); + if (ent) { + ent->read_proc = proc_get_radio; + ent->write_proc = proc_set_radio; + } else { + printk(KERN_ERR + "Unable to initialize /proc/" DRV_NAME "/radio\n"); + err = -ENOMEM; + goto fail; + } + + return 0; + + fail: + pbe5_proc_cleanup(); + return err; +} + +/* + * module stuff + */ +static int __init pbe5_init(void) +{ + pbe5_proc_init(); + + pbe5_set_radio((radio == 1) ? PBE5_RADIO_ON : PBE5_RADIO_OFF); + + return 0; +} + +static void __exit pbe5_exit(void) +{ + pbe5_set_radio(PBE5_RADIO_OFF); + + pbe5_proc_cleanup(); +} + +module_init(pbe5_init); +module_exit(pbe5_exit); + +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ --- linux-2.6.28.orig/ubuntu/rfkill/Makefile +++ linux-2.6.28/ubuntu/rfkill/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for Ubuntu additional drivers +# + +obj-$(CONFIG_AVERATEC_5100P) += av5100.o +obj-$(CONFIG_PACKARDBELL_E5) += pbe5.o --- linux-2.6.28.orig/ubuntu/rfkill/av5100.c +++ linux-2.6.28/ubuntu/rfkill/av5100.c @@ -0,0 +1,174 @@ +/******************************************************************************* + + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License 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. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define DRV_NAME "av5100" +#define DRV_VERSION "1.3" +#define DRV_DESCRIPTION "SW RF kill switch for Averatec 5100P" +#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation" + +static int radio = 1; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) + +MODULE_PARM(radio, "i"); + +#else /* LINUX_VERSION_CODE < 2.6.0 */ + +#include +module_param(radio, int, 1); + +#endif /* LINUX_VERSION_CODE < 2.6.0 */ + +MODULE_PARM_DESC(radio, "controls state of radio (1=on, 0=off)"); + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_COPYRIGHT); +MODULE_LICENSE("GPL"); + +#define AV5100_RADIO_ON (0xe0) +#define AV5100_RADIO_OFF (0xe1) + +static int av5100_radio = AV5100_RADIO_OFF; + +static void av5100_set_radio(int state) +{ + printk(KERN_INFO DRV_NAME ": Radio being turned %s\n", + (state == AV5100_RADIO_ON) ? "ON" : "OFF"); + outl(0x80020800, 0xcf8); + outb(0x6f, 0x0072); + outl(0x1800ffff, 0x1184); + outb(state, 0x00b2); + av5100_radio = state; +} + + +/* + * proc stuff + */ +static struct proc_dir_entry *dir_base = NULL; + +static int proc_set_radio(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + av5100_set_radio(buffer[0] == '0' ? AV5100_RADIO_OFF : AV5100_RADIO_ON); + + return count; +} + +static int proc_get_radio(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = 0; + + len += snprintf(page, count, DRV_NAME ": %d\n", + av5100_radio == AV5100_RADIO_OFF ? 0 : 1); + + *eof = 1; + return len; +} + + +static void av5100_proc_cleanup(void) +{ + if (dir_base) { + remove_proc_entry("radio", dir_base); + remove_proc_entry(DRV_NAME, NULL); + dir_base = NULL; + } +} + + +static int av5100_proc_init(void) +{ + struct proc_dir_entry *ent; + int err = 0; + + dir_base = create_proc_entry(DRV_NAME, S_IFDIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialise /proc/" + DRV_NAME "\n"); + err = -ENOMEM; + goto fail; + } + + + ent = create_proc_entry("radio", S_IFREG | S_IRUGO | S_IWUSR, + dir_base); + if (ent) { + ent->read_proc = proc_get_radio; + ent->write_proc = proc_set_radio; + } else { + printk(KERN_ERR + "Unable to initialize /proc/" DRV_NAME "/radio\n"); + err = -ENOMEM; + goto fail; + } + + return 0; + + fail: + av5100_proc_cleanup(); + return err; +} + +/* + * module stuff + */ +static int __init av5100_init(void) +{ + av5100_proc_init(); + + av5100_set_radio((radio == 1) ? AV5100_RADIO_ON : AV5100_RADIO_OFF); + + return 0; +} + +static void __exit av5100_exit(void) +{ + av5100_set_radio(AV5100_RADIO_OFF); + + av5100_proc_cleanup(); +} + +module_init(av5100_init); +module_exit(av5100_exit); + +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ --- linux-2.6.28.orig/ubuntu/rfkill/BOM +++ linux-2.6.28/ubuntu/rfkill/BOM @@ -0,0 +1,6 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=108766 +Current Version: 1.3 +Comments: + +Had to change &proc_root to NULL due to changes in create/remove proc +entry usage. --- linux-2.6.28.orig/ubuntu/lirc/kcompat.h +++ linux-2.6.28/ubuntu/lirc/kcompat.h @@ -0,0 +1,369 @@ +/* $Id: kcompat.h,v 5.36 2008/05/14 16:37:49 lirc Exp $ */ + +#ifndef _KCOMPAT_H +#define _KCOMPAT_H + +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) +#define LIRC_THIS_MODULE(x) x, +#else /* >= 2.6.16 */ +#define LIRC_THIS_MODULE(x) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#define LIRC_HAVE_DEVFS +#define LIRC_HAVE_DEVFS_26 +#endif + +#define LIRC_HAVE_SYSFS + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13) + +typedef struct class_simple lirc_class_t; + +static inline lirc_class_t *class_create(struct module *owner, char *name) +{ + return class_simple_create(owner, name); +} + +static inline void class_destroy(lirc_class_t *cls) +{ + class_simple_destroy(cls); +} + +#define lirc_device_create(cs, parent, dev, fmt, args...) \ + class_simple_device_add(cs, dev, parent, fmt, ## args) + +static inline void lirc_device_destroy(lirc_class_t *cls, dev_t devt) +{ + class_simple_device_remove(devt); +} + +#else /* >= 2.6.13 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + +#define lirc_device_create(cs, parent, dev, fmt, args...) \ + class_device_create(cs, dev, parent, fmt, ## args) + +#else /* >= 2.6.15 */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + +#define lirc_device_create(cs, parent, dev, fmt, args...) \ + class_device_create(cs, NULL, dev, parent, fmt, ## args) + +#else /* >= 2.6.26 */ + +#define lirc_device_create device_create + +#endif /* >= 2.6.26 */ + +#define LIRC_DEVFS_PREFIX + +#endif /* >= 2.6.15 */ + +typedef struct class lirc_class_t; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + +#define lirc_device_destroy class_device_destroy + +#else + +#define lirc_device_destroy device_destroy + +#endif + +#endif /* >= 2.6.13 */ + +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#define LIRC_HAVE_DEVFS +#define LIRC_HAVE_DEVFS_24 +#endif + +#ifndef LIRC_DEVFS_PREFIX +#define LIRC_DEVFS_PREFIX "usb/" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) +#include +#include +static inline void del_timer_sync(struct timer_list *timerlist) +{ + start_bh_atomic(); + del_timer(timerlist); + end_bh_atomic(); +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#ifdef daemonize +#undef daemonize +#endif +#define daemonize(name) do { \ + \ + lock_kernel(); \ + \ + exit_mm(current); \ + exit_files(current); \ + exit_fs(current); \ + current->session = 1; \ + current->pgrp = 1; \ + current->euid = 0; \ + current->tty = NULL; \ + sigfillset(¤t->blocked); \ + \ + strcpy(current->comm, name); \ + \ + unlock_kernel(); \ + \ +} while (0) + +/* Not sure when this was introduced, sometime during 2.5.X */ +#define MODULE_PARM_int(x) MODULE_PARM(x, "i") +#define MODULE_PARM_bool(x) MODULE_PARM(x, "i") +#define MODULE_PARM_long(x) MODULE_PARM(x, "l") +#define module_param(x, y, z) MODULE_PARM_##y(x) +#else +#include +#endif /* Linux < 2.6.0 */ + +/* DevFS header */ +#if defined(LIRC_HAVE_DEVFS) +#include +#endif + +#ifdef LIRC_HAVE_DEVFS_24 +#ifdef register_chrdev +#undef register_chrdev +#endif +#define register_chrdev devfs_register_chrdev +#ifdef unregister_chrdev +#undef unregister_chrdev +#endif +#define unregister_chrdev devfs_unregister_chrdev +#endif /* DEVFS 2.4 */ + +#ifndef LIRC_HAVE_SYSFS +#define class_destroy(x) do { } while (0) +#define class_create(x, y) NULL +#define lirc_class_destroy(x, y) do { } while (0) +#define lirc_class_create(x, y, z, xx, yy, zz) 0 +#define IS_ERR(x) 0 +typedef struct class_simple +{ + int notused; +} lirc_class_t; +#endif /* No SYSFS */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) +#define KERNEL_2_5 + +/* + * We still are using MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT in the set_use_inc + * function of all modules for 2.4 kernel compatibility. + * + * For 2.6 kernels reference counting is done in lirc_dev by + * try_module_get()/module_put() because the old approach is racy. + * + */ +#ifdef MOD_INC_USE_COUNT +#undef MOD_INC_USE_COUNT +#endif +#define MOD_INC_USE_COUNT + +#ifdef MOD_DEC_USE_COUNT +#undef MOD_DEC_USE_COUNT +#endif +#define MOD_DEC_USE_COUNT + +#ifdef EXPORT_NO_SYMBOLS +#undef EXPORT_NO_SYMBOLS +#endif +#define EXPORT_NO_SYMBOLS + +#else /* Kernel < 2.5.0 */ + +static inline int try_module_get(struct module *module) +{ + return 1; +} + +static inline void module_put(struct module *module) +{ +} + +#endif /* Kernel >= 2.5.0 */ + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + +#ifndef MODULE_PARM_DESC +#define MODULE_PARM_DESC(x, y) +#endif + +#ifndef MODULE_ALIAS_CHARDEV_MAJOR +#define MODULE_ALIAS_CHARDEV_MAJOR(x) +#endif + +#ifndef MODULE_DEVICE_TABLE +#define MODULE_DEVICE_TABLE(x, y) +#endif + +#include +#ifndef IRQ_RETVAL +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +#ifndef MOD_IN_USE +#ifdef CONFIG_MODULE_UNLOAD +#define MOD_IN_USE module_refcount(THIS_MODULE) +#else +#error "LIRC modules currently require" +#error " 'Loadable module support ---> Module unloading'" +#error "to be enabled in the kernel" +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#if !defined(local_irq_save) +#define local_irq_save(flags) do { save_flags(flags); cli(); } while (0) +#endif +#if !defined(local_irq_restore) +#define local_irq_restore(flags) do { restore_flags(flags); } while (0) +#endif +#endif + +#if KERNEL_VERSION(2, 4, 0) <= LINUX_VERSION_CODE +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) +#include +static inline char *pci_name(struct pci_dev *pdev) +{ + return pdev->slot_name; +} +#endif /* kernel < 2.4.22 */ +#endif /* kernel >= 2.4.0 */ + +/*************************** I2C specific *****************************/ +#include + +#ifndef I2C_CLIENT_END +#error "********************************************************" +#error " Sorry, this driver needs the new I2C stack. " +#error " You can get it at http://www2.lm-sensors.nu/~lm78/. " +#error "********************************************************" +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) + +#undef i2c_get_clientdata +#define i2c_get_clientdata(client) ((client)->data) + + +#undef i2c_set_clientdata +#define i2c_set_clientdata(client_ptr, new_data) do { \ + (client_ptr)->data = new_data; \ +} while (0) + + +#endif + +/* removed in 2.6.14 */ +#ifndef I2C_ALGO_BIT +# define I2C_ALGO_BIT 0 +#endif + +/* removed in 2.6.16 */ +#ifndef I2C_DRIVERID_EXP3 +# define I2C_DRIVERID_EXP3 0xf003 +#endif + +/*************************** USB specific *****************************/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 8) +static inline int usb_kill_urb(struct urb *urb) +{ + return usb_unlink_urb(urb); +} +#endif + +/* removed in 2.6.14 */ +#ifndef URB_ASYNC_UNLINK +#define URB_ASYNC_UNLINK 0 +#endif +#endif + +/*************************** bttv specific ****************************/ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) /* BTTV_* -> BTTV_BOARD_* */ +#define BTTV_BOARD_UNKNOWN BTTV_UNKNOWN +#define BTTV_BOARD_PXELVWPLTVPAK BTTV_PXELVWPLTVPAK +#define BTTV_BOARD_PXELVWPLTVPRO BTTV_PXELVWPLTVPRO +#define BTTV_BOARD_PV_BT878P_9B BTTV_PV_BT878P_9B +#define BTTV_BOARD_PV_BT878P_PLUS BTTV_PV_BT878P_PLUS +#define BTTV_BOARD_AVERMEDIA BTTV_AVERMEDIA +#define BTTV_BOARD_AVPHONE98 BTTV_AVPHONE98 +#define BTTV_BOARD_AVERMEDIA98 BTTV_AVERMEDIA98 +#define BTTV_BOARD_CHRONOS_VS2 BTTV_CHRONOS_VS2 +#define BTTV_BOARD_MIRO BTTV_MIRO +#define BTTV_BOARD_DYNALINK BTTV_DYNALINK +#define BTTV_BOARD_WINVIEW_601 BTTV_WINVIEW_601 +#ifdef BTTV_KWORLD +#define BTTV_BOARD_KWORLD BTTV_KWORLD +#endif +#define BTTV_BOARD_MAGICTVIEW061 BTTV_MAGICTVIEW061 +#define BTTV_BOARD_MAGICTVIEW063 BTTV_MAGICTVIEW063 +#define BTTV_BOARD_PHOEBE_TVMAS BTTV_PHOEBE_TVMAS +#ifdef BTTV_BESTBUY_EASYTV2 +#define BTTV_BOARD_BESTBUY_EASYTV BTTV_BESTBUY_EASYTV +#define BTTV_BOARD_BESTBUY_EASYTV2 BTTV_BESTBUY_EASYTV2 +#endif +#define BTTV_BOARD_FLYVIDEO BTTV_FLYVIDEO +#define BTTV_BOARD_FLYVIDEO_98 BTTV_FLYVIDEO_98 +#define BTTV_BOARD_TYPHOON_TVIEW BTTV_TYPHOON_TVIEW +#ifdef BTTV_FLYVIDEO_98FM +#define BTTV_BOARD_FLYVIDEO_98FM BTTV_FLYVIDEO_98FM +#endif +#define BTTV_BOARD_WINFAST2000 BTTV_WINFAST2000 +#ifdef BTTV_GVBCTV5PCI +#define BTTV_BOARD_GVBCTV5PCI BTTV_GVBCTV5PCI +#endif +#endif /* end BTTV_* -> BTTV_BOARD_* */ + + +/******************************* pm.h *********************************/ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +typedef u32 pm_message_t; +#endif /* kernel < 2.6.11 */ +#endif /* kernel >= 2.6.0 */ + +/*************************** interrupt.h ******************************/ +/* added in 2.6.18, old defines removed in 2.6.24 */ +#ifndef IRQF_DISABLED +#define IRQF_DISABLED SA_INTERRUPT +#endif +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +/*************************** spinlock.h *******************************/ +/* added in 2.6.11 */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED +#endif + +#endif /* _KCOMPAT_H */ --- linux-2.6.28.orig/ubuntu/lirc/Kconfig +++ linux-2.6.28/ubuntu/lirc/Kconfig @@ -0,0 +1,93 @@ +config LIRC_DEV + tristate "LIRC Device support" + default m + +config LIRC_ATIUSB + tristate "LIRC ATI RF Remote" + default m + depends on LIRC_DEV + +config LIRC_BT829 + tristate "LIRC BT829" + default m + depends on LIRC_DEV + +config LIRC_CMDIR + tristate "LIRC CommandIR kernel support" + default m + depends on LIRC_DEV + +config LIRC_I2C + tristate "LIRC I2C interface remote" + default m + depends on LIRC_DEV + +config LIRC_IGORPLUGUSB + tristate "LIRC IGOR custom remote" + default m + depends on LIRC_DEV + +config LIRC_IMON + tristate "LIRC Imon remote or pad" + default m + depends on LIRC_DEV + +config LIRC_IT87 + tristate "LIRC IT87" + default m + depends on LIRC_DEV + +config LIRC_MCEUSB + tristate "LIRC Microsoft Media Center Remote" + default m + depends on LIRC_DEV + +config LIRC_MCEUSB2 + tristate "LIRC Microsoft Media Center Remote v2" + default m + depends on LIRC_DEV + +config LIRC_PVR150 + tristate "LIRC Hauppauge PVR-XXX remote" + default m + depends on LIRC_DEV + +config LIRC_PARALLEL + tristate "LIRC Parallel port custom remote" + default n + depends on LIRC_DEV + +config LIRC_SASEM + tristate "LIRC Sasem" + default m + depends on LIRC_DEV + +config LIRC_SERIAL + tristate "LIRC Serial port remote" + default m + depends on LIRC_DEV + +config LIRC_SERIAL_IGOR + tristate "LIRC Igor design serial remote" + default m + depends on LIRC_DEV + +config LIRC_SIR + tristate "LIRC Laptop port IR (SIR))" + default m + depends on LIRC_DEV + +config LIRC_STREAMZAP + tristate "LIRC Streamzap remote" + default m + depends on LIRC_DEV + +config LIRC_TTUSBIR + tristate "LIRC TT USB IR device" + default m + depends on LIRC_DEV + +config LIRC_GPIO + tristate "LIRC TV Card GPIO remote" + default n + depends on LIRC_DEV --- linux-2.6.28.orig/ubuntu/lirc/Makefile +++ linux-2.6.28/ubuntu/lirc/Makefile @@ -0,0 +1,24 @@ +#include $(src)/../../.config + +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src) + +obj-$(CONFIG_LIRC_DEV) += lirc_dev/ +obj-$(CONFIG_LIRC_ATIUSB) += lirc_atiusb/ +obj-$(CONFIG_LIRC_BT829) += lirc_bt829/ +obj-$(CONFIG_LIRC_CMDIR) += lirc_cmdir/ +obj-$(CONFIG_LIRC_I2C) += lirc_i2c/ +obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb/ +obj-$(CONFIG_LIRC_IMON) += lirc_imon/ +obj-$(CONFIG_LIRC_IT87) += lirc_it87/ +obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb/ +obj-$(CONFIG_LIRC_MCEUSB2) += lirc_mceusb2/ +obj-$(CONFIG_LIRC_PVR150) += lirc_pvr150/ +obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel/ +obj-$(CONFIG_LIRC_SASEM) += lirc_sasem/ +obj-$(CONFIG_LIRC_SERIAL) += lirc_serial/ +obj-$(CONFIG_LIRC_SERIAL_IGOR) += lirc_serial_igor/ +obj-$(CONFIG_LIRC_SIR) += lirc_sir/ +obj-$(CONFIG_LIRC_STREAMZAP) += lirc_streamzap/ +obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir/ +obj-$(CONFIG_LIRC_GPIO) += lirc_gpio/ +obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir/ --- linux-2.6.28.orig/ubuntu/lirc/lirc.h +++ linux-2.6.28/ubuntu/lirc/lirc.h @@ -0,0 +1,110 @@ +/* $Id: lirc.h,v 5.14 2008/01/12 21:57:57 lirc Exp $ */ + +#ifndef _LINUX_LIRC_H +#define _LINUX_LIRC_H + +#if defined(__linux__) +#include +#include +#else +#include +#if defined(__NetBSD__) +#include +#endif +typedef u_int32_t __u32; +#endif + +#define PULSE_BIT 0x01000000 +#define PULSE_MASK 0x00FFFFFF + +typedef int lirc_t; + +/* + * lirc compatible hardware features + */ + + +#define LIRC_MODE2SEND(x) (x) +#define LIRC_SEND2MODE(x) (x) +#define LIRC_MODE2REC(x) ((x) << 16) +#define LIRC_REC2MODE(x) ((x) >> 16) + +#define LIRC_MODE_RAW 0x00000001 +#define LIRC_MODE_PULSE 0x00000002 +#define LIRC_MODE_MODE2 0x00000004 +#define LIRC_MODE_CODE 0x00000008 +#define LIRC_MODE_LIRCCODE 0x00000010 +#define LIRC_MODE_STRING 0x00000020 + + +#define LIRC_CAN_SEND_RAW LIRC_MODE2SEND(LIRC_MODE_RAW) +#define LIRC_CAN_SEND_PULSE LIRC_MODE2SEND(LIRC_MODE_PULSE) +#define LIRC_CAN_SEND_MODE2 LIRC_MODE2SEND(LIRC_MODE_MODE2) +#define LIRC_CAN_SEND_CODE LIRC_MODE2SEND(LIRC_MODE_CODE) +#define LIRC_CAN_SEND_LIRCCODE LIRC_MODE2SEND(LIRC_MODE_LIRCCODE) +#define LIRC_CAN_SEND_STRING LIRC_MODE2SEND(LIRC_MODE_STRING) + +#define LIRC_CAN_SEND_MASK 0x0000003f + +#define LIRC_CAN_SET_SEND_CARRIER 0x00000100 +#define LIRC_CAN_SET_SEND_DUTY_CYCLE 0x00000200 +#define LIRC_CAN_SET_TRANSMITTER_MASK 0x00000400 + +#define LIRC_CAN_REC_RAW LIRC_MODE2REC(LIRC_MODE_RAW) +#define LIRC_CAN_REC_PULSE LIRC_MODE2REC(LIRC_MODE_PULSE) +#define LIRC_CAN_REC_MODE2 LIRC_MODE2REC(LIRC_MODE_MODE2) +#define LIRC_CAN_REC_CODE LIRC_MODE2REC(LIRC_MODE_CODE) +#define LIRC_CAN_REC_LIRCCODE LIRC_MODE2REC(LIRC_MODE_LIRCCODE) +#define LIRC_CAN_REC_STRING LIRC_MODE2REC(LIRC_MODE_STRING) + +#define LIRC_CAN_REC_MASK LIRC_MODE2REC(LIRC_CAN_SEND_MASK) + +#define LIRC_CAN_SET_REC_CARRIER (LIRC_CAN_SET_SEND_CARRIER << 16) +#define LIRC_CAN_SET_REC_DUTY_CYCLE (LIRC_CAN_SET_SEND_DUTY_CYCLE << 16) + +#define LIRC_CAN_SET_REC_DUTY_CYCLE_RANGE 0x40000000 +#define LIRC_CAN_SET_REC_CARRIER_RANGE 0x80000000 +#define LIRC_CAN_GET_REC_RESOLUTION 0x20000000 + +#define LIRC_CAN_SEND(x) ((x)&LIRC_CAN_SEND_MASK) +#define LIRC_CAN_REC(x) ((x)&LIRC_CAN_REC_MASK) + +#define LIRC_CAN_NOTIFY_DECODE 0x01000000 + +/* + * IOCTL commands for lirc driver + */ + +#define LIRC_GET_FEATURES _IOR('i', 0x00000000, __u32) + +#define LIRC_GET_SEND_MODE _IOR('i', 0x00000001, __u32) +#define LIRC_GET_REC_MODE _IOR('i', 0x00000002, __u32) +#define LIRC_GET_SEND_CARRIER _IOR('i', 0x00000003, __u32) +#define LIRC_GET_REC_CARRIER _IOR('i', 0x00000004, __u32) +#define LIRC_GET_SEND_DUTY_CYCLE _IOR('i', 0x00000005, __u32) +#define LIRC_GET_REC_DUTY_CYCLE _IOR('i', 0x00000006, __u32) +#define LIRC_GET_REC_RESOLUTION _IOR('i', 0x00000007, __u32) + +/* code length in bits, currently only for LIRC_MODE_LIRCCODE */ +#define LIRC_GET_LENGTH _IOR('i', 0x0000000f, __u32) + +#define LIRC_SET_SEND_MODE _IOW('i', 0x00000011, __u32) +#define LIRC_SET_REC_MODE _IOW('i', 0x00000012, __u32) +/* Note: these can reset the according pulse_width */ +#define LIRC_SET_SEND_CARRIER _IOW('i', 0x00000013, __u32) +#define LIRC_SET_REC_CARRIER _IOW('i', 0x00000014, __u32) +#define LIRC_SET_SEND_DUTY_CYCLE _IOW('i', 0x00000015, __u32) +#define LIRC_SET_REC_DUTY_CYCLE _IOW('i', 0x00000016, __u32) +#define LIRC_SET_TRANSMITTER_MASK _IOW('i', 0x00000017, __u32) + +/* to set a range use + LIRC_SET_REC_DUTY_CYCLE_RANGE/LIRC_SET_REC_CARRIER_RANGE with the + lower bound first and later + LIRC_SET_REC_DUTY_CYCLE/LIRC_SET_REC_CARRIER with the upper bound */ + +#define LIRC_SET_REC_DUTY_CYCLE_RANGE _IOW('i', 0x0000001e, __u32) +#define LIRC_SET_REC_CARRIER_RANGE _IOW('i', 0x0000001f, __u32) + +#define LIRC_NOTIFY_DECODE _IO('i', 0x00000020) + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_ttusbir/lirc_ttusbir.c +++ linux-2.6.28/ubuntu/lirc/lirc_ttusbir/lirc_ttusbir.c @@ -0,0 +1,401 @@ +/**************************************************************************** + ** lirc_ttusbir.c *********************************************************** + **************************************************************************** + * + * lirc_ttusbir - LIRC device driver for the TechnoTrend USB IR Receiver + * + * Copyright (C) 2007 Stefan Macher + * + * 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 + * + */ + +/* This LIRC driver provides access to the TechnoTrend USB IR Receiver. + * The receiver delivers the IR signal as raw sampled true/false data in + * isochronous USB packets each of size 128 byte. + * Currently the driver reduces the sampling rate by factor of 8 as this + * is still more than enough to decode RC-5 - others should be analyzed. + * But the driver does not rely on RC-5 it should be able to decode every + * IR signal that is not too fast. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +MODULE_DESCRIPTION("TechnoTrend USB IR device driver for LIRC"); +MODULE_AUTHOR("Stefan Macher (st_maker-lirc@yahoo.de)"); +MODULE_LICENSE("GPL"); + +/* #define DEBUG */ +#ifdef DEBUG +#define DPRINTK printk +#else +#define DPRINTK(_x_, a...) +#endif + +/* function declarations */ +static int probe(struct usb_interface *intf, const struct usb_device_id *id); +static void disconnect(struct usb_interface *intf); +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void urb_complete(struct urb *urb, struct pt_regs *pt_regs); +#else +static void urb_complete(struct urb *urb); +#endif +static int set_use_inc(void *data); +static void set_use_dec(void *data); + +static int num_urbs = 2; +module_param(num_urbs, int, 0444); +MODULE_PARM_DESC(num_urbs, + "Number of URBs in queue. Try to increase to 4 in case " + "of problems (default: 2; minimum: 2)"); + +/* table of devices that work with this driver */ +static struct usb_device_id device_id_table[] = { + { USB_DEVICE(0x0B48, 0x2003) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, device_id_table); + +/* USB driver definition */ +static struct usb_driver driver = { + .name = "TTUSBIR", + .id_table = &(device_id_table[0]), + .probe = probe, + .disconnect = disconnect, +}; + +/* USB device definition */ +struct ttusbir_device { + struct usb_driver *driver; + struct usb_device *udev; + struct usb_interface *interf; + struct usb_class_driver class_driver; + unsigned int ifnum; /* Interface number to use */ + unsigned int alt_setting; /* alternate setting to use */ + unsigned int endpoint; /* Endpoint to use */ + struct urb **urb; /* num_urb URB pointers*/ + char **buffer; /* 128 byte buffer for each URB */ + struct lirc_buffer rbuf; /* Buffer towards LIRC */ + struct lirc_plugin plugin; + int minor; + int last_pulse; /* remembers if last received byte was pulse or space */ + int last_num; /* remembers how many last bytes appeared */ + int opened; +}; + +/************************************* + * LIRC specific functions + */ +static int set_use_inc(void *data) +{ + int i; + struct ttusbir_device *ttusbir = data; + + DPRINTK("Sending first URBs\n"); + /* @TODO Do I need to check if I am already opened */ + ttusbir->opened = 1; + + for (i = 0; i < num_urbs; i++) + usb_submit_urb(ttusbir->urb[i], GFP_KERNEL); + + return 0; +} + +static void set_use_dec(void *data) +{ + struct ttusbir_device *ttusbir = data; + + DPRINTK("Device closed\n"); + + ttusbir->opened = 0; +} + +/************************************* + * USB specific functions + */ + +/* This mapping table is used to do a very simple filtering of the + * input signal. + * For a value with at least 4 bits set it returns 0xFF otherwise + * 0x00. For faster IR signals this can not be used. But for RC-5 we + * still have about 14 samples per pulse/space, i.e. we sample with 14 + * times higher frequency than the signal frequency */ +const unsigned char map_table[] = +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void urb_complete(struct urb *urb, struct pt_regs *pt_regs) +#else +static void urb_complete(struct urb *urb) +#endif +{ + struct ttusbir_device *ttusbir; + unsigned char *buf; + int i; + lirc_t l; + + ttusbir = urb->context; + + if (!ttusbir->opened) + return; + + buf = (unsigned char *)urb->transfer_buffer; + + for (i = 0; i < 128; i++) { + /* Here we do the filtering and some kind of down sampling */ + buf[i] = ~map_table[buf[i]]; + if (ttusbir->last_pulse == buf[i]) { + if (ttusbir->last_num < PULSE_MASK/63) + ttusbir->last_num++; + /* else we are in a idle period and do not need to + * increment any longer */ + } else { + l = ttusbir->last_num * 62; /* about 62 = us/byte */ + if (ttusbir->last_pulse) /* pulse or space? */ + l |= PULSE_BIT; + if (!lirc_buffer_full(&ttusbir->rbuf)) { + lirc_buffer_write_1(&ttusbir->rbuf, (void *)&l); + wake_up_interruptible(&ttusbir->rbuf.wait_poll); + } + ttusbir->last_num = 0; + ttusbir->last_pulse = buf[i]; + } + } + usb_submit_urb(urb, GFP_ATOMIC); /* keep data rolling :-) */ +} + +/* Called whenever the USB subsystem thinks we could be the right driver + to handle this device +*/ +static int probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + int alt_set, endp; + int found = 0; + int i, j; + int struct_size; + struct usb_host_interface *host_interf; + struct usb_interface_descriptor *interf_desc; + struct usb_host_endpoint *host_endpoint; + struct ttusbir_device *ttusbir; + + DPRINTK("Module ttusbir probe\n"); + + /* To reduce memory fragmentation we use only one allocation */ + struct_size = sizeof(struct ttusbir_device) + + (sizeof(struct urb *) * num_urbs) + + (sizeof(char *) * num_urbs) + + (num_urbs * 128); + ttusbir = kmalloc(struct_size, GFP_KERNEL); + if (!ttusbir) + return -ENOMEM; + memset(ttusbir, 0, struct_size); + + ttusbir->urb = (struct urb **)((char *)ttusbir + + sizeof(struct ttusbir_device)); + ttusbir->buffer = (char **)((char *)ttusbir->urb + + (sizeof(struct urb *) * num_urbs)); + for (i = 0; i < num_urbs; i++) + ttusbir->buffer[i] = (char *)ttusbir->buffer + + (sizeof(char *)*num_urbs) + (i * 128); + + ttusbir->driver = &driver; + ttusbir->alt_setting = -1; + /* @TODO check if error can be returned */ + ttusbir->udev = usb_get_dev(interface_to_usbdev(intf)); + ttusbir->interf = intf; + ttusbir->last_pulse = 0x00; + ttusbir->last_num = 0; + + /* Now look for interface setting we can handle + We are searching for the alt setting where end point + 0x82 has max packet size 16 + */ + for (alt_set = 0; alt_set < intf->num_altsetting && !found; alt_set++) { + host_interf = &intf->altsetting[alt_set]; + interf_desc = &host_interf->desc; + for (endp = 0; endp < interf_desc->bNumEndpoints; endp++) { + host_endpoint = &host_interf->endpoint[endp]; + if ((host_endpoint->desc.bEndpointAddress == 0x82) && + (host_endpoint->desc.wMaxPacketSize == 0x10)) { + ttusbir->alt_setting = alt_set; + ttusbir->endpoint = endp; + found = 1; + break; + } + } + } + if (ttusbir->alt_setting != -1) + DPRINTK("alt setting: %d\n", ttusbir->alt_setting); + else { + err("Could not find alternate setting\n"); + kfree(ttusbir); + return -EINVAL; + } + + /* OK lets setup this interface setting */ + usb_set_interface(ttusbir->udev, 0, ttusbir->alt_setting); + + /* Store device info in interface structure */ + usb_set_intfdata(intf, ttusbir); + + /* Register as a LIRC plugin */ + if (lirc_buffer_init(&ttusbir->rbuf, sizeof(lirc_t), 256) < 0) { + err("Could not get memory for LIRC data buffer\n"); + usb_set_intfdata(intf, NULL); + kfree(ttusbir); + return -ENOMEM; + } + strcpy(ttusbir->plugin.name, "TTUSBIR"); + ttusbir->plugin.minor = -1; + ttusbir->plugin.code_length = 1; + ttusbir->plugin.sample_rate = 0; + ttusbir->plugin.data = ttusbir; + ttusbir->plugin.add_to_buf = NULL; + ttusbir->plugin.get_queue = NULL; + ttusbir->plugin.rbuf = &ttusbir->rbuf; + ttusbir->plugin.set_use_inc = set_use_inc; + ttusbir->plugin.set_use_dec = set_use_dec; + ttusbir->plugin.ioctl = NULL; + ttusbir->plugin.fops = NULL; + ttusbir->plugin.owner = THIS_MODULE; + ttusbir->plugin.features = LIRC_CAN_REC_MODE2; + ttusbir->minor = lirc_register_plugin(&ttusbir->plugin); + if (ttusbir->minor < 0) { + err("Error registering as LIRC plugin\n"); + usb_set_intfdata(intf, NULL); + lirc_buffer_free(&ttusbir->rbuf); + kfree(ttusbir); + return -EIO; + } + + /* Allocate and setup the URB that we will use to talk to the device */ + for (i = 0; i < num_urbs; i++) { + ttusbir->urb[i] = usb_alloc_urb(8, GFP_KERNEL); + if (!ttusbir->urb[i]) { + err("Could not allocate memory for the URB\n"); + for (j = i - 1; j >= 0; j--) + kfree(ttusbir->urb[j]); + lirc_buffer_free(&ttusbir->rbuf); + lirc_unregister_plugin(ttusbir->minor); + kfree(ttusbir); + usb_set_intfdata(intf, NULL); + return -ENOMEM; + } + ttusbir->urb[i]->dev = ttusbir->udev; + ttusbir->urb[i]->context = ttusbir; + ttusbir->urb[i]->pipe = usb_rcvisocpipe(ttusbir->udev, + ttusbir->endpoint); + ttusbir->urb[i]->interval = 1; + ttusbir->urb[i]->transfer_flags = URB_ISO_ASAP; + ttusbir->urb[i]->transfer_buffer = &ttusbir->buffer[i][0]; + ttusbir->urb[i]->complete = urb_complete; + ttusbir->urb[i]->number_of_packets = 8; + ttusbir->urb[i]->transfer_buffer_length = 128; + for (j = 0; j < 8; j++) { + ttusbir->urb[i]->iso_frame_desc[j].offset = j*16; + ttusbir->urb[i]->iso_frame_desc[j].length = 16; + } + } + return 0; +} + +/* Called when the driver is unloaded or the device is unplugged + */ +static void disconnect(struct usb_interface *intf) +{ + int i; + struct ttusbir_device *ttusbir; + + DPRINTK("Module ttusbir disconnect\n"); + + ttusbir = (struct ttusbir_device *) usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); + lirc_unregister_plugin(ttusbir->minor); + DPRINTK("unregistered\n"); + + for (i = 0; i < num_urbs; i++) { + usb_kill_urb(ttusbir->urb[i]); + usb_free_urb(ttusbir->urb[i]); + } + DPRINTK("URBs killed\n"); + lirc_buffer_free(&ttusbir->rbuf); + kfree(ttusbir); +} + +static int ttusbir_init_module(void) +{ + int result; + + DPRINTK(KERN_DEBUG "Module ttusbir init\n"); + + /* register this driver with the USB subsystem */ + result = usb_register(&driver); + if (result) + err("usb_register failed. Error number %d", result); + return result; +} + +static void ttusbir_exit_module(void) +{ + printk(KERN_DEBUG "Module ttusbir exit\n"); + /* deregister this driver with the USB subsystem */ + usb_deregister(&driver); +} + +module_init(ttusbir_init_module); +module_exit(ttusbir_exit_module); --- linux-2.6.28.orig/ubuntu/lirc/lirc_ttusbir/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_ttusbir/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_TTUSBIR) += lirc_ttusbir.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_igorplugusb/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_igorplugusb/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_igorplugusb/lirc_igorplugusb.c +++ linux-2.6.28/ubuntu/lirc/lirc_igorplugusb/lirc_igorplugusb.c @@ -0,0 +1,697 @@ +/* lirc_igorplugusb - USB remote support for LIRC + * + * Supports the standard homebrew IgorPlugUSB receiver with Igor's firmware. + * See http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm + * + * The device can only record bursts of up to 36 pulses/spaces. + * Works fine with RC5. Longer commands lead to device buffer overrun. + * (Maybe a better firmware or a microcontroller with more ram can help?) + * + * Version 0.1 [beta status] + * + * Copyright (C) 2004 Jan M. Hochstein + * + * + * This driver was derived from: + * Paul Miller + * "lirc_atiusb" module + * Vladimir Dergachev 's 2002 + * "USB ATI Remote support" (input device) + * Adrian Dewhurst 's 2002 + * "USB StreamZap remote driver" (LIRC) + * Artur Lipowski 's 2002 + * "lirc_dev" and "lirc_gpio" LIRC modules + * + */ + +/* + * 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.4.0 or higher" +#error "*******************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + +#if !defined(KERNEL_2_5) +#define USB_CTRL_GET_TIMEOUT 5 +#endif + +/* lock irctl structure */ +#define IRLOCK down_interruptible(&ir->lock) +#define IRUNLOCK up(&ir->lock) + +/* module identification */ +#define DRIVER_VERSION "0.1" +#define DRIVER_AUTHOR \ + "Jan M. Hochstein " +#define DRIVER_DESC "USB remote driver for LIRC" +#define DRIVER_NAME "lirc_igorplugusb" + +/* debugging support */ +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +/* general constants */ +#define SUCCESS 0 + +/* One mode2 pulse/space has 4 bytes. */ +#define CODE_LENGTH sizeof(lirc_t) + +/* Igor's firmware cannot record bursts longer than 36. */ +#define DEVICE_BUFLEN 36 + +/** Header at the beginning of the device's buffer: + unsigned char data_length + unsigned char data_start (!=0 means ring-buffer overrun) + unsigned char counter (incremented by each burst) +**/ +#define DEVICE_HEADERLEN 3 + +/* This is for the gap */ +#define ADDITIONAL_LIRC_BYTES 2 + +/* times to poll per second */ +#define SAMPLE_RATE 100 + +static int sample_rate = SAMPLE_RATE; + +/**** Igor's USB Request Codes */ + +#define SET_INFRABUFFER_EMPTY 1 +/** + * Params: none + * Answer: empty + * +**/ + +#define GET_INFRACODE 2 +/** + * Params: + * wValue: offset to begin reading infra buffer + * + * Answer: infra data + * +**/ + +#define SET_DATAPORT_DIRECTION 3 +/** + * Params: + * wValue: (byte) 1 bit for each data port pin (0=in, 1=out) + * + * Answer: empty + * +**/ + +#define GET_DATAPORT_DIRECTION 4 +/** + * Params: none + * + * Answer: (byte) 1 bit for each data port pin (0=in, 1=out) + * +**/ + +#define SET_OUT_DATAPORT 5 +/** + * Params: + * wValue: byte to write to output data port + * + * Answer: empty + * +**/ + +#define GET_OUT_DATAPORT 6 +/** + * Params: none + * + * Answer: least significant 3 bits read from output data port + * +**/ + +#define GET_IN_DATAPORT 7 +/** + * Params: none + * + * Answer: least significant 3 bits read from input data port + * +**/ + +#define READ_EEPROM 8 +/** + * Params: + * wValue: offset to begin reading EEPROM + * + * Answer: EEPROM bytes + * +**/ + +#define WRITE_EEPROM 9 +/** + * Params: + * wValue: offset to EEPROM byte + * wIndex: byte to write + * + * Answer: empty + * +**/ + +#define SEND_RS232 10 +/** + * Params: + * wValue: byte to send + * + * Answer: empty + * +**/ + +#define RECV_RS232 11 +/** + * Params: none + * + * Answer: byte received + * +**/ + +#define SET_RS232_BAUD 12 +/** + * Params: + * wValue: byte to write to UART bit rate register (UBRR) + * + * Answer: empty + * +**/ + +#define GET_RS232_BAUD 13 +/** + * Params: none + * + * Answer: byte read from UART bit rate register (UBRR) + * +**/ + + +/* data structure for each usb remote */ +struct irctl { + + /* usb */ + struct usb_device *usbdev; + struct urb *urb_in; + int devnum; + + unsigned char *buf_in; + unsigned int len_in; + int in_space; + struct timeval last_time; + +#if defined(KERNEL_2_5) + dma_addr_t dma_in; +#endif + + /* lirc */ + struct lirc_plugin *p; + + /* handle sending (init strings) */ + int send_flags; + wait_queue_head_t wait_out; + + struct semaphore lock; +}; + +static int unregister_from_lirc(struct irctl *ir) +{ + struct lirc_plugin *p = ir->p; + int devnum; + + if (!ir->p) + return -EINVAL; + + devnum = ir->devnum; + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); + + lirc_unregister_plugin(p->minor); + + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); + + lirc_buffer_free(p->rbuf); + kfree(p->rbuf); + kfree(p); + kfree(ir); + ir->p = NULL; + return SUCCESS; +} + +static int set_use_inc(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); + return -EIO; + } + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); + + MOD_INC_USE_COUNT; + + if (!ir->usbdev) + return -ENODEV; + + return SUCCESS; +} + +static void set_use_dec(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); + return; + } + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); + + MOD_DEC_USE_COUNT; +} + + +/** + * Called in user context. + * return 0 if data was added to the buffer and + * -ENODATA if none was available. This should add some number of bits + * evenly divisible by code_length to the buffer +**/ +static int usb_remote_poll(void *data, struct lirc_buffer *buf) +{ + int ret; + struct irctl *ir = (struct irctl *)data; + + if (!ir->usbdev) /* Has the device been removed? */ + return -ENODEV; + + memset(ir->buf_in, 0, ir->len_in); + + ret = usb_control_msg( + ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + GET_INFRACODE, USB_TYPE_VENDOR|USB_DIR_IN, + 0/* offset */, /*unused*/0, + ir->buf_in, ir->len_in, + /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); + if (ret > 0) { + int i = DEVICE_HEADERLEN; + lirc_t code, timediff; + struct timeval now; + + if (ret <= 1) /* ACK packet has 1 byte --> ignore */ + return -ENODATA; + + dprintk(DRIVER_NAME ": Got %d bytes. Header: %02x %02x %02x\n", + ret, ir->buf_in[0], ir->buf_in[1], ir->buf_in[2]); + + if (ir->buf_in[2] != 0) { + printk(DRIVER_NAME "[%d]: Device buffer overrun.\n", + ir->devnum); + /* start at earliest byte */ + i = DEVICE_HEADERLEN + ir->buf_in[2]; + /* where are we now? space, gap or pulse? */ + } + + do_gettimeofday(&now); + timediff = now.tv_sec - ir->last_time.tv_sec; + if (timediff + 1 > PULSE_MASK / 1000000) + timediff = PULSE_MASK; + else { + timediff *= 1000000; + timediff += now.tv_usec - ir->last_time.tv_usec; + } + ir->last_time.tv_sec = now.tv_sec; + ir->last_time.tv_usec = now.tv_usec; + + /* create leading gap */ + code = timediff; + lirc_buffer_write_n(buf, (unsigned char *)&code, 1); + ir->in_space = 1; /* next comes a pulse */ + + /* MODE2: pulse/space (PULSE_BIT) in 1us units */ + + while (i < ret) { + /* 1 Igor-tick = 85.333333 us */ + code = (unsigned int)ir->buf_in[i] * 85 + + (unsigned int)ir->buf_in[i] / 3; + ir->last_time.tv_usec += code; + if (ir->in_space) + code |= PULSE_BIT; + lirc_buffer_write_n(buf, (unsigned char *)&code, 1); + /* 1 chunk = CODE_LENGTH bytes */ + ir->in_space ^= 1; + ++i; + } + + ret = usb_control_msg( + ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, + /*unused*/0, /*unused*/0, + /*dummy*/ir->buf_in, /*dummy*/ir->len_in, + /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); + if (ret < 0) + printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: " + "error %d\n", ir->devnum, ret); + return SUCCESS; + } else + printk(DRIVER_NAME "[%d]: GET_INFRACODE: error %d\n", + ir->devnum, ret); + + return -ENODATA; +} + + + +#if defined(KERNEL_2_5) +static int usb_remote_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = NULL; + struct usb_host_interface *idesc = NULL; + struct usb_host_endpoint *ep_ctl2; +#else +static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *intf; + struct usb_interface_descriptor *idesc; + struct usb_endpoint_descriptor *ep_ctl2; +#endif + struct irctl *ir = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int devnum, pipe, maxp, bytes_in_key; + int minor = 0; + char buf[63], name[128] = ""; + int mem_failure = 0; + int ret; + + dprintk(DRIVER_NAME ": usb probe called.\n"); + +#if defined(KERNEL_2_5) + dev = interface_to_usbdev(intf); + +# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + idesc = &intf->altsetting[intf->act_altsetting]; /* in 2.6.4 */ +# else + idesc = intf->cur_altsetting; /* in 2.6.6 */ +# endif + + if (idesc->desc.bNumEndpoints != 1) + return -ENODEV; + ep_ctl2 = idesc->endpoint; + if (((ep_ctl2->desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) + != USB_DIR_IN) + || (ep_ctl2->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_CONTROL) + return -ENODEV; + pipe = usb_rcvctrlpipe(dev, ep_ctl2->desc.bEndpointAddress); +#else + intf = &dev->actconfig->interface[ifnum]; + idesc = &intf->altsetting[intf->act_altsetting]; + if (idesc->bNumEndpoints != 1) + return NULL; + ep_ctl2 = idesc->endpoint; + if (((ep_ctl2->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + != USB_DIR_IN) + || (ep_ctl2->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_CONTROL) + return NULL; + pipe = usb_rcvctrlpipe(dev, ep_ctl2->bEndpointAddress); +#endif + devnum = dev->devnum; + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + bytes_in_key = CODE_LENGTH; + + dprintk(DRIVER_NAME "[%d]: bytes_in_key=%d maxp=%d\n", + devnum, bytes_in_key, maxp); + + + /* allocate kernel memory */ + mem_failure = 0; + ir = kmalloc(sizeof(struct irctl), GFP_KERNEL); + if (!ir) { + mem_failure = 1; + goto mem_failure_switch; + } + + memset(ir, 0, sizeof(struct irctl)); + + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + mem_failure = 2; + goto mem_failure_switch; + } + + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + mem_failure = 3; + goto mem_failure_switch; + } + + if (lirc_buffer_init(rbuf, bytes_in_key, + DEVICE_BUFLEN+ADDITIONAL_LIRC_BYTES)) { + mem_failure = 4; + goto mem_failure_switch; + } + +#if defined(KERNEL_2_5) + ir->buf_in = usb_buffer_alloc(dev, + DEVICE_BUFLEN+DEVICE_HEADERLEN, + GFP_ATOMIC, &ir->dma_in); +#else + ir->buf_in = kmalloc(DEVICE_BUFLEN+DEVICE_HEADERLEN, + GFP_KERNEL); +#endif + if (!ir->buf_in) { + mem_failure = 5; + goto mem_failure_switch; + } + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = -1; + plugin->code_length = bytes_in_key*8; /* in bits */ + plugin->features = LIRC_CAN_REC_MODE2; + plugin->data = ir; + plugin->rbuf = rbuf; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; + plugin->sample_rate = sample_rate; /* per second */ + plugin->add_to_buf = &usb_remote_poll; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + + init_MUTEX(&ir->lock); + init_waitqueue_head(&ir->wait_out); + + minor = lirc_register_plugin(plugin); + if (minor < 0) + mem_failure = 9; + +mem_failure_switch: + + /* free allocated memory in case of failure */ + switch (mem_failure) { + case 9: +#if defined(KERNEL_2_5) + usb_buffer_free(dev, DEVICE_BUFLEN+DEVICE_HEADERLEN, + ir->buf_in, ir->dma_in); +#else + kfree(ir->buf_in); +#endif + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(ir); + case 1: + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", + devnum, mem_failure); +#if defined(KERNEL_2_5) + return -ENOMEM; +#else + return NULL; +#endif + } + + plugin->minor = minor; + ir->p = plugin; + ir->devnum = devnum; + ir->usbdev = dev; + ir->len_in = DEVICE_BUFLEN+DEVICE_HEADERLEN; + ir->in_space = 1; /* First mode2 event is a space. */ + do_gettimeofday(&ir->last_time); + + if (dev->descriptor.iManufacturer + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + if (dev->descriptor.iProduct + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, + dev->bus->busnum, devnum); + + /* clear device buffer */ + ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), + SET_INFRABUFFER_EMPTY, USB_TYPE_VENDOR|USB_DIR_IN, + /*unused*/0, /*unused*/0, + /*dummy*/ir->buf_in, /*dummy*/ir->len_in, + /*timeout*/HZ * USB_CTRL_GET_TIMEOUT); + if (ret < 0) + printk(DRIVER_NAME "[%d]: SET_INFRABUFFER_EMPTY: error %d\n", + devnum, ret); + +#if defined(KERNEL_2_5) + usb_set_intfdata(intf, ir); + return SUCCESS; +#else + return ir; +#endif +} + + +#if defined(KERNEL_2_5) +static void usb_remote_disconnect(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct irctl *ir = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); +#else +static void usb_remote_disconnect(struct usb_device *dev, void *ptr) +{ + struct irctl *ir = ptr; +#endif + + if (!ir || !ir->p) + return; + + ir->usbdev = NULL; + wake_up_all(&ir->wait_out); + + IRLOCK; +#if defined(KERNEL_2_5) + usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); +#else + kfree(ir->buf_in); +#endif + IRUNLOCK; + + unregister_from_lirc(ir); +} + +static struct usb_device_id usb_remote_id_table [] = { + /* Igor Plug USB (Atmel's Manufact. ID) */ + { USB_DEVICE(0x03eb, 0x0002) }, + + /* Terminating entry */ + { } +}; + +static struct usb_driver usb_remote_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = usb_remote_probe, + .disconnect = usb_remote_disconnect, + .id_table = usb_remote_id_table +}; + +static int __init usb_remote_init(void) +{ + int i; + + printk(KERN_INFO "\n" + DRIVER_NAME ": " DRIVER_DESC " v" DRIVER_VERSION "\n"); + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled\n"); + + request_module("lirc_dev"); + + i = usb_register(&usb_remote_driver); + if (i < 0) { + printk(DRIVER_NAME ": usb register failed, result = %d\n", i); + return -ENODEV; + } + + return SUCCESS; +} + +static void __exit usb_remote_exit(void) +{ + usb_deregister(&usb_remote_driver); +} + +module_init(usb_remote_init); +module_exit(usb_remote_exit); + +#if defined(KERNEL_2_5) +#include +MODULE_INFO(vermagic, VERMAGIC_STRING); +#endif + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, usb_remote_id_table); + +module_param(sample_rate, int, 0644); +MODULE_PARM_DESC(sample_rate, "Sampling rate in Hz (default: 100)"); + +EXPORT_NO_SYMBOLS; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_parallel/lirc_parallel.h +++ linux-2.6.28/ubuntu/lirc/lirc_parallel/lirc_parallel.h @@ -0,0 +1,26 @@ +/* $Id: lirc_parallel.h,v 5.2 2007/01/25 04:32:05 lirc Exp $ */ + +#ifndef _LIRC_PARALLEL_H +#define _LIRC_PARALLEL_H + +#include + +#define LIRC_PORT_LEN 3 + +#define LIRC_LP_BASE 0 +#define LIRC_LP_STATUS 1 +#define LIRC_LP_CONTROL 2 + +#define LIRC_PORT_DATA LIRC_LP_BASE /* base */ +#define LIRC_PORT_TIMER LIRC_LP_STATUS /* status port */ +#define LIRC_PORT_TIMER_BIT LP_PBUSY /* busy signal */ +#define LIRC_PORT_SIGNAL LIRC_LP_STATUS /* status port */ +#define LIRC_PORT_SIGNAL_BIT LP_PACK /* ack signal */ +#define LIRC_PORT_IRQ LIRC_LP_CONTROL /* control port */ + +#define LIRC_SFH506_DELAY 0 /* delay t_phl in usecs */ + +#define LIRC_PARALLEL_MAX_TRANSMITTERS 8 +#define LIRC_PARALLEL_TRANSMITTER_MASK ((1< + * + * 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 + * + */ + +/*********************************************************************** + ************************* Includes *********************** + ***********************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include + +#ifdef CONFIG_SMP +#error "--- Sorry, this driver is not SMP safe. ---" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) +#include +#endif + +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#include "lirc_parallel.h" + +#define LIRC_DRIVER_NAME "lirc_parallel" + +#ifndef LIRC_IRQ +#define LIRC_IRQ 7 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x378 +#endif +#ifndef LIRC_TIMER +#define LIRC_TIMER 65536 +#endif + +/*********************************************************************** + ************************* Globale Variablen *********************** + ***********************************************************************/ + +static int debug; +static int check_pselecd; + +unsigned int irq = LIRC_IRQ; +unsigned int io = LIRC_PORT; +#ifdef LIRC_TIMER +unsigned int timer; +unsigned int default_timer = LIRC_TIMER; +#endif + +#define WBUF_SIZE (256) +#define RBUF_SIZE (256) /* this must be a power of 2 larger than 1 */ + +static lirc_t wbuf[WBUF_SIZE]; +static lirc_t rbuf[RBUF_SIZE]; + +DECLARE_WAIT_QUEUE_HEAD(lirc_wait); + +unsigned int rptr; +unsigned int wptr; +unsigned int lost_irqs; +int is_open; + +struct parport *pport; +struct pardevice *ppdevice; +int is_claimed; + +unsigned int tx_mask = 1; + +/*********************************************************************** + ************************* Interne Funktionen *********************** + ***********************************************************************/ + +static inline unsigned int in(int offset) +{ + switch (offset) { + case LIRC_LP_BASE: + return (parport_read_data(pport)); + case LIRC_LP_STATUS: + return (parport_read_status(pport)); + case LIRC_LP_CONTROL: + return (parport_read_control(pport)); + } + return 0; /* make compiler happy */ +} + +static inline void out(int offset, int value) +{ + switch (offset) { + case LIRC_LP_BASE: + parport_write_data(pport, value); + break; + case LIRC_LP_CONTROL: + parport_write_control(pport, value); + break; + case LIRC_LP_STATUS: + printk(KERN_INFO "%s: attempt to write to status register\n", + LIRC_DRIVER_NAME); + break; + } +} + +static inline unsigned int lirc_get_timer(void) +{ + return (in(LIRC_PORT_TIMER)&LIRC_PORT_TIMER_BIT); +} + +static inline unsigned int lirc_get_signal(void) +{ + return (in(LIRC_PORT_SIGNAL)&LIRC_PORT_SIGNAL_BIT); +} + +static inline void lirc_on(void) +{ + out(LIRC_PORT_DATA, tx_mask); +} + +static inline void lirc_off(void) +{ + out(LIRC_PORT_DATA, 0); +} + +static unsigned int init_lirc_timer(void) +{ + struct timeval tv, now; + unsigned int level, newlevel, timeelapsed, newtimer; + int count = 0; + + do_gettimeofday(&tv); + tv.tv_sec++; /* wait max. 1 sec. */ + level = lirc_get_timer(); + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + count++; + level = newlevel; + do_gettimeofday(&now); + } while (count < 1000 && (now.tv_sec < tv.tv_sec + || (now.tv_sec == tv.tv_sec + && now.tv_usec < tv.tv_usec))); + + timeelapsed = ((now.tv_sec + 1 - tv.tv_sec)*1000000 + + (now.tv_usec - tv.tv_usec)); + if (count >= 1000 && timeelapsed > 0) { + if (default_timer == 0) { + /* autodetect timer */ + newtimer = (1000000*count)/timeelapsed; + printk(KERN_INFO "%s: %u Hz timer detected\n", + LIRC_DRIVER_NAME, newtimer); + return newtimer; + } else { + newtimer = (1000000*count)/timeelapsed; + if (abs(newtimer - default_timer) > default_timer/10) { + /* bad timer */ + printk(KERN_NOTICE "%s: bad timer: %u Hz\n", + LIRC_DRIVER_NAME, newtimer); + printk(KERN_NOTICE "%s: using default timer: " + "%u Hz\n", + LIRC_DRIVER_NAME, default_timer); + return default_timer; + } else { + printk(KERN_INFO "%s: %u Hz timer detected\n", + LIRC_DRIVER_NAME, newtimer); + return newtimer; /* use detected value */ + } + } + } else { + printk(KERN_NOTICE "%s: no timer detected\n", LIRC_DRIVER_NAME); + return 0; + } +} + +static int lirc_claim(void) +{ + if (parport_claim(ppdevice) != 0) { + printk(KERN_WARNING "%s: could not claim port\n", + LIRC_DRIVER_NAME); + printk(KERN_WARNING "%s: waiting for port becoming available" + "\n", LIRC_DRIVER_NAME); + if (parport_claim_or_block(ppdevice) < 0) { + printk(KERN_NOTICE "%s: could not claim port, giving" + " up\n", LIRC_DRIVER_NAME); + return 0; + } + } + out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP); + is_claimed = 1; + return 1; +} + +/*********************************************************************** + ************************* interrupt handler ************************ + ***********************************************************************/ + +static inline void rbuf_write(lirc_t signal) +{ + unsigned int nwptr; + + nwptr = (wptr + 1) & (RBUF_SIZE - 1); + if (nwptr == rptr) { + /* no new signals will be accepted */ + lost_irqs++; + printk(KERN_NOTICE "%s: buffer overrun\n", LIRC_DRIVER_NAME); + return; + } + rbuf[wptr] = signal; + wptr = nwptr; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void irq_handler(int i, void *blah, struct pt_regs *regs) +#else +static void irq_handler(int i, void *blah) +#endif +{ + struct timeval tv; + static struct timeval lasttv; + static int init; + long signal; + lirc_t data; + unsigned int level, newlevel; + unsigned int timeout; + + if (!MOD_IN_USE) + return; + + if (!is_claimed) + return; + + /* disable interrupt */ + /* + disable_irq(irq); + out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ) & (~LP_PINTEN)); + */ + if (check_pselecd && (in(1) & LP_PSELECD)) + return; + +#ifdef LIRC_TIMER + if (init) { + do_gettimeofday(&tv); + + signal = tv.tv_sec - lasttv.tv_sec; + if (signal > 15) + /* really long time */ + data = PULSE_MASK; + else + data = (lirc_t) (signal*1000000 + + tv.tv_usec - lasttv.tv_usec + + LIRC_SFH506_DELAY); + + rbuf_write(data); /* space */ + } else { + if (timer == 0) { + /* wake up; we'll lose this signal + * but it will be garbage if the device + * is turned on anyway */ + timer = init_lirc_timer(); + /* enable_irq(irq); */ + return; + } + init = 1; + } + + timeout = timer/10; /* timeout after 1/10 sec. */ + signal = 1; + level = lirc_get_timer(); + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + signal++; + level = newlevel; + + /* giving up */ + if (signal > timeout + || (check_pselecd && (in(1) & LP_PSELECD))) { + signal = 0; + printk(KERN_NOTICE "%s: timeout\n", LIRC_DRIVER_NAME); + break; + } + } + while (lirc_get_signal()); + if (signal != 0) { + /* ajust value to usecs */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) + unsigned long long helper; + + helper = ((unsigned long long) signal)*1000000; + do_div(helper, timer); + signal = (long) helper; +#else + signal = (long) ((((double) signal)*1000000)/timer); +#endif + + if (signal > LIRC_SFH506_DELAY) + data = signal - LIRC_SFH506_DELAY; + else + data = 1; + rbuf_write(PULSE_BIT|data); /* pulse */ + } + do_gettimeofday(&lasttv); +#else + /* add your code here */ +#endif + + wake_up_interruptible(&lirc_wait); + + /* enable interrupt */ + /* + enable_irq(irq); + out(LIRC_PORT_IRQ, in(LIRC_PORT_IRQ)|LP_PINTEN); + */ +} + +/*********************************************************************** + ************************** file_operations ************************ + ***********************************************************************/ + +static loff_t lirc_lseek(struct file *filep, loff_t offset, int orig) +{ + return -ESPIPE; +} + +static ssize_t lirc_read(struct file *filep, char *buf, size_t n, loff_t *ppos) +{ + int result = 0; + int count = 0; + DECLARE_WAITQUEUE(wait, current); + + if (n % sizeof(lirc_t)) + return -EINVAL; + + add_wait_queue(&lirc_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + while (count < n) { + if (rptr != wptr) { + if (copy_to_user(buf+count, (char *) &rbuf[rptr], + sizeof(lirc_t))) { + result = -EFAULT; + break; + } + rptr = (rptr + 1) & (RBUF_SIZE - 1); + count += sizeof(lirc_t); + } else { + if (filep->f_flags & O_NONBLOCK) { + result = -EAGAIN; + break; + } + if (signal_pending(current)) { + result = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + } + remove_wait_queue(&lirc_wait, &wait); + set_current_state(TASK_RUNNING); + return (count ? count : result); +} + +static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, + loff_t *ppos) +{ + int count; + unsigned int i; + unsigned int level, newlevel; + unsigned long flags; + lirc_t counttimer; + + if (!is_claimed) + return(-EBUSY); + + if (n % sizeof(lirc_t)) + return(-EINVAL); + + count = n / sizeof(lirc_t); + + if (count > WBUF_SIZE || count % 2 == 0) + return(-EINVAL); + + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + +#ifdef LIRC_TIMER + if (timer == 0) { + /* try again if device is ready */ + timer = init_lirc_timer(); + if (timer == 0) + return(-EIO); + } + + /* ajust values from usecs */ + for (i = 0; i < count; i++) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) + unsigned long long helper; + + helper = ((unsigned long long) wbuf[i])*timer; + do_div(helper, 1000000); + wbuf[i] = (lirc_t) helper; +#else + wbuf[i] = (lirc_t) (((double) wbuf[i])*timer/1000000); +#endif + } + + local_irq_save(flags); + i = 0; + while (i < count) { + level = lirc_get_timer(); + counttimer = 0; + lirc_on(); + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + counttimer++; + level = newlevel; + if (check_pselecd && (in(1) & LP_PSELECD)) { + lirc_off(); + local_irq_restore(flags); + return -EIO; + } + } while (counttimer < wbuf[i]); + i++; + + lirc_off(); + if (i == count) + break; + counttimer = 0; + do { + newlevel = lirc_get_timer(); + if (level == 0 && newlevel != 0) + counttimer++; + level = newlevel; + if (check_pselecd && (in(1) & LP_PSELECD)) { + local_irq_restore(flags); + return -EIO; + } + } while (counttimer < wbuf[i]); + i++; + } + local_irq_restore(flags); +#else + /* place code that handles write + * without external timer here */ +#endif + return n; +} + +static unsigned int lirc_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &lirc_wait, wait); + if (rptr != wptr) + return (POLLIN|POLLRDNORM); + return 0; +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long features = LIRC_CAN_SET_TRANSMITTER_MASK | + LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; + unsigned long mode; + unsigned int ivalue; + + switch (cmd) { + case LIRC_GET_FEATURES: + result = put_user(features, (unsigned long *) arg); + if (result) + return result; + break; + case LIRC_GET_SEND_MODE: + result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); + if (result) + return result; + break; + case LIRC_GET_REC_MODE: + result = put_user(LIRC_MODE_MODE2, (unsigned long *) arg); + if (result) + return result; + break; + case LIRC_SET_SEND_MODE: + result = get_user(mode, (unsigned long *) arg); + if (result) + return result; + if (mode != LIRC_MODE_PULSE) + return -EINVAL; + break; + case LIRC_SET_REC_MODE: + result = get_user(mode, (unsigned long *) arg); + if (result) + return result; + if (mode != LIRC_MODE_MODE2) + return -ENOSYS; + break; + case LIRC_SET_TRANSMITTER_MASK: + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if ((ivalue & LIRC_PARALLEL_TRANSMITTER_MASK) != ivalue) + return LIRC_PARALLEL_MAX_TRANSMITTERS; + tx_mask = ivalue; + break; + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static int lirc_open(struct inode *node, struct file *filep) +{ + if (MOD_IN_USE || !lirc_claim()) + return -EBUSY; + + parport_enable_irq(pport); + + /* init read ptr */ + rptr = 0; + wptr = 0; + lost_irqs = 0; + + MOD_INC_USE_COUNT; + is_open = 1; + return 0; +} + +static int lirc_close(struct inode *node, struct file *filep) +{ + if (is_claimed) { + is_claimed = 0; + parport_release(ppdevice); + } + is_open = 0; + MOD_DEC_USE_COUNT; + return 0; +} + +static struct file_operations lirc_fops = { + .llseek = lirc_lseek, + .read = lirc_read, + .write = lirc_write, + .poll = lirc_poll, + .ioctl = lirc_ioctl, + .open = lirc_open, + .release = lirc_close +}; + +static int set_use_inc(void *data) +{ +#if WE_DONT_USE_LOCAL_OPEN_CLOSE + MOD_INC_USE_COUNT; +#endif + return 0; +} + +static void set_use_dec(void *data) +{ +#if WE_DONT_USE_LOCAL_OPEN_CLOSE + MOD_DEC_USE_COUNT; +#endif +} + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +static int pf(void *handle); +static void kf(void *handle); + +static struct timer_list poll_timer; +static void poll_state(unsigned long ignored); + +static void poll_state(unsigned long ignored) +{ + printk(KERN_NOTICE "%s: time\n", + LIRC_DRIVER_NAME); + del_timer(&poll_timer); + if (is_claimed) + return; + kf(NULL); + if (!is_claimed) { + printk(KERN_NOTICE "%s: could not claim port, giving up\n", + LIRC_DRIVER_NAME); + init_timer(&poll_timer); + poll_timer.expires = jiffies + HZ; + poll_timer.data = (unsigned long)current; + poll_timer.function = poll_state; + add_timer(&poll_timer); + } +} + +static int pf(void *handle) +{ + parport_disable_irq(pport); + is_claimed = 0; + return 0; +} + +static void kf(void *handle) +{ + if (!is_open) + return; + if (!lirc_claim()) + return; + parport_enable_irq(pport); + lirc_off(); + /* this is a bit annoying when you actually print...*/ + /* + printk(KERN_INFO "%s: reclaimed port\n", LIRC_DRIVER_NAME); + */ +} + +/*********************************************************************** + ****************** init_module()/cleanup_module() ****************** + ***********************************************************************/ + +int init_module(void) +{ +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3) + pport = parport_find_base(io); +#else + pport = parport_enumerate(); + while (pport != NULL) { + if (pport->base == io) + break; + pport = pport->next; + } +#endif + if (pport == NULL) { + printk(KERN_NOTICE "%s: no port at %x found\n", + LIRC_DRIVER_NAME, io); + return -ENXIO; + } + ppdevice = parport_register_device(pport, LIRC_DRIVER_NAME, + pf, kf, irq_handler, 0, NULL); +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 3) + parport_put_port(pport); +#endif + if (ppdevice == NULL) { + printk(KERN_NOTICE "%s: parport_register_device() failed\n", + LIRC_DRIVER_NAME); + return -ENXIO; + } + if (parport_claim(ppdevice) != 0) + goto skip_init; + is_claimed = 1; + out(LIRC_LP_CONTROL, LP_PSELECP|LP_PINITP); + +#ifdef LIRC_TIMER + if (debug) + out(LIRC_PORT_DATA, tx_mask); + + timer = init_lirc_timer(); + +#if 0 /* continue even if device is offline */ + if (timer == 0) { + is_claimed = 0; + parport_release(pport); + parport_unregister_device(ppdevice); + return -EIO; + } + +#endif + if (debug) + out(LIRC_PORT_DATA, 0); +#endif + + is_claimed = 0; + parport_release(ppdevice); + skip_init: + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_NOTICE "%s: register_chrdev() failed\n", + LIRC_DRIVER_NAME); + parport_unregister_device(ppdevice); + return -EIO; + } + printk(KERN_INFO "%s: installed using port 0x%04x irq %d\n", + LIRC_DRIVER_NAME, io, irq); + return 0; +} + +void cleanup_module(void) +{ + parport_unregister_device(ppdevice); + lirc_unregister_plugin(plugin.minor); +} + +MODULE_DESCRIPTION("Infrared receiver driver for parallel ports."); +MODULE_AUTHOR("Christoph Bartelmus"); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O address base (0x3bc, 0x378 or 0x278)"); + +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (7 or 5)"); + +module_param(tx_mask, int, 0444); +MODULE_PARM_DESC(tx_maxk, "Transmitter mask (default: 0x01)"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +module_param(check_pselecd, bool, 0644); +MODULE_PARM_DESC(debug, "Check for printer (default: 0)"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_it87/TODO +++ linux-2.6.28/ubuntu/lirc/lirc_it87/TODO @@ -0,0 +1,5 @@ +This is my todo-list for lirc_it87: + +1. enabling/using shared IRQ +2. init/drop IRQ-usage in lirc_open/lirc_close + --- linux-2.6.28.orig/ubuntu/lirc/lirc_it87/lirc_it87.h +++ linux-2.6.28/ubuntu/lirc/lirc_it87/lirc_it87.h @@ -0,0 +1,116 @@ +/* lirc_it87.h */ +/* SECTION: Definitions */ + +/********************************* ITE IT87xx ************************/ + +/* based on the following documentation from ITE: + a) IT8712F Preliminary CIR Programming Guide V0.1 + b) IT8705F Simple LPC I/O Preliminary Specifiction V0.3 + c) IT8712F EC-LPC I/O Preliminary Specification V0.5 +*/ + +/* IT8712/05 Ports: */ +#define IT87_ADRPORT 0x2e +#define IT87_DATAPORT 0x2f +#define IT87_INIT 0x87, 0x01, 0x55, 0x55 + +/* alternate Ports: */ +/* +#define IT87_ADRPORT 0x4e +#define IT87_DATAPORT 0x4f +#define IT87_INIT 0x87, 0x01, 0x55, 0xaa + */ + +/* IT8712/05 Registers */ +#define IT87_CFGCTRL 0x2 +#define IT87_LDN 0x7 +#define IT87_CHIP_ID1 0x20 +#define IT87_CHIP_ID2 0x21 +#define IT87_CFG_VERSION 0x22 +#define IT87_SWSUSPEND 0x23 + +#define IT8712_CIR_LDN 0xa +#define IT8705_CIR_LDN 0x7 + +/* CIR Configuration Registers: */ +#define IT87_CIR_ACT 0x30 +#define IT87_CIR_BASE_MSB 0x60 +#define IT87_CIR_BASE_LSB 0x61 +#define IT87_CIR_IRQ 0x70 +#define IT87_CIR_CONFIG 0xf0 + +/* List of IT87_CIR registers: offset to BaseAddr */ +#define IT87_CIR_DR 0 +#define IT87_CIR_IER 1 +#define IT87_CIR_RCR 2 +#define IT87_CIR_TCR1 3 +#define IT87_CIR_TCR2 4 +#define IT87_CIR_TSR 5 +#define IT87_CIR_RSR 6 +#define IT87_CIR_BDLR 5 +#define IT87_CIR_BDHR 6 +#define IT87_CIR_IIR 7 + +/* Bit Definitionen */ +/* IER: */ +#define IT87_CIR_IER_TM_EN 0x80 +#define IT87_CIR_IER_RESEVED 0x40 +#define IT87_CIR_IER_RESET 0x20 +#define IT87_CIR_IER_BR 0x10 +#define IT87_CIR_IER_IEC 0x8 +#define IT87_CIR_IER_RFOIE 0x4 +#define IT87_CIR_IER_RDAIE 0x2 +#define IT87_CIR_IER_TLDLIE 0x1 + +/* RCR: */ +#define IT87_CIR_RCR_RDWOS 0x80 +#define IT87_CIR_RCR_HCFS 0x40 +#define IT87_CIR_RCR_RXEN 0x20 +#define IT87_CIR_RCR_RXEND 0x10 +#define IT87_CIR_RCR_RXACT 0x8 +#define IT87_CIR_RCR_RXDCR 0x7 + +/* TCR1: */ +#define IT87_CIR_TCR1_FIFOCLR 0x80 +#define IT87_CIR_TCR1_ILE 0x40 +#define IT87_CIR_TCR1_FIFOTL 0x30 +#define IT87_CIR_TCR1_TXRLE 0x8 +#define IT87_CIR_TCR1_TXENDF 0x4 +#define IT87_CIR_TCR1_TXMPM 0x3 + +/* TCR2: */ +#define IT87_CIR_TCR2_CFQ 0xf8 +#define IT87_CIR_TCR2_TXMPW 0x7 + +/* TSR: */ +#define IT87_CIR_TSR_RESERVED 0xc0 +#define IT87_CIR_TSR_TXFBC 0x3f + +/* RSR: */ +#define IT87_CIR_RSR_RXFTO 0x80 +#define IT87_CIR_RSR_RESERVED 0x40 +#define IT87_CIR_RSR_RXFBC 0x3f + +/* IIR: */ +#define IT87_CIR_IIR_RESERVED 0xf8 +#define IT87_CIR_IIR_IID 0x6 +#define IT87_CIR_IIR_IIP 0x1 + +/* TM: */ +#define IT87_CIR_TM_IL_SEL 0x80 +#define IT87_CIR_TM_RESERVED 0x40 +#define IT87_CIR_TM_TM_REG 0x3f + +#define IT87_CIR_FIFO_SIZE 32 + +/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */ +#define IT87_CIR_BAUDRATE_DIVISOR 0x1 +#define IT87_CIR_DEFAULT_IOBASE 0x310 +#define IT87_CIR_DEFAULT_IRQ 0x7 +#define IT87_CIR_SPACE 0x00 +#define IT87_CIR_PULSE 0xff +#define IT87_CIR_FREQ_MIN 27 +#define IT87_CIR_FREQ_MAX 58 +#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul) + +/********************************* ITE IT87xx ************************/ --- linux-2.6.28.orig/ubuntu/lirc/lirc_it87/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_it87/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_IT87) += lirc_it87.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_it87/lirc_it87.c +++ linux-2.6.28/ubuntu/lirc/lirc_it87/lirc_it87.c @@ -0,0 +1,1023 @@ +/* + * LIRC driver for ITE IT8712/IT8705 CIR port + * + * Copyright (C) 2001 Hans-Günter Lütke Uphues + * + * 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 + * + * ITE IT8705 and IT8712(not tested) CIR-port support for lirc based + * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula + * + * Attention: Sendmode only tested with debugging logs + * + * 2001/02/27 Christoph Bartelmus : + * reimplemented read function + * 2005/06/05 Andrew Calkin implemented support for Asus Digimatrix, + * based on work of the following member of the Outertrack Digimatrix + * Forum: Art103 + */ + + +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +#include +#include +#include +#include +#else +#include +#include +#include +#include +#endif + +#include + +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" +#include "kcompat.h" + +#include "lirc_it87.h" + +#ifdef LIRC_IT87_DIGIMATRIX +static int digimatrix = 1; +static int it87_freq = 36; /* kHz */ +static int irq = 9; +#else +static int digimatrix; +static int it87_freq = 38; /* kHz */ +static int irq = IT87_CIR_DEFAULT_IRQ; +#endif + +static unsigned long it87_bits_in_byte_out; +static unsigned long it87_send_counter; +static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN; + +#define RBUF_LEN 1024 +#define WBUF_LEN 1024 + +#define LIRC_DRIVER_NAME "lirc_it87" + +/* timeout for sequences in jiffies (=5/100s) */ +/* must be longer than TIME_CONST */ +#define IT87_TIMEOUT (HZ*5/100) + +/* insmod parameters */ +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +static int io = IT87_CIR_DEFAULT_IOBASE; +/* receiver demodulator default: off */ +static int it87_enable_demodulator; + +static int timer_enabled; +static DEFINE_SPINLOCK(timer_lock); +static struct timer_list timerlist; +/* time of last signal change detected */ +static struct timeval last_tv = {0, 0}; +/* time of last UART data ready interrupt */ +static struct timeval last_intr_tv = {0, 0}; +static int last_value; + +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); + +static DEFINE_SPINLOCK(hardware_lock); +static DEFINE_SPINLOCK(dev_lock); + +static lirc_t rx_buf[RBUF_LEN]; +unsigned int rx_tail, rx_head; +static lirc_t tx_buf[WBUF_LEN]; + +/* SECTION: Prototypes */ + +/* Communication with user-space */ +static int lirc_open(struct inode *inode, struct file *file); +static int lirc_close(struct inode *inode, struct file *file); +static unsigned int lirc_poll(struct file *file, poll_table *wait); +static ssize_t lirc_read(struct file *file, char *buf, + size_t count, loff_t *ppos); +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *pos); +static int lirc_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg); +static void add_read_queue(int flag, unsigned long val); +#ifdef MODULE +static int init_chrdev(void); +static void drop_chrdev(void); +#endif + /* Hardware */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t it87_interrupt(int irq, void *dev_id, + struct pt_regs *regs); +#else +static irqreturn_t it87_interrupt(int irq, void *dev_id); +#endif +static void send_space(unsigned long len); +static void send_pulse(unsigned long len); +static void init_send(void); +static void terminate_send(unsigned long len); +static int init_hardware(void); +static void drop_hardware(void); + /* Initialisation */ +static int init_port(void); +static void drop_port(void); +int init_module(void); +void cleanup_module(void); + + +/* SECTION: Communication with user-space */ + +static int lirc_open(struct inode *inode, struct file *file) +{ + spin_lock(&dev_lock); + if (MOD_IN_USE) { + spin_unlock(&dev_lock); + return -EBUSY; + } + MOD_INC_USE_COUNT; + spin_unlock(&dev_lock); + return 0; +} + + +static int lirc_close(struct inode *inode, struct file *file) +{ + MOD_DEC_USE_COUNT; + return 0; +} + + +static unsigned int lirc_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &lirc_read_queue, wait); + if (rx_head != rx_tail) + return POLLIN | POLLRDNORM; + return 0; +} + + +static ssize_t lirc_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + int n = 0; + int retval = 0; + + while (n < count) { + if (file->f_flags & O_NONBLOCK && rx_head == rx_tail) { + retval = -EAGAIN; + break; + } + retval = wait_event_interruptible(lirc_read_queue, + rx_head != rx_tail); + if (retval) + break; + + if (copy_to_user((void *) buf + n, (void *) (rx_buf + rx_head), + sizeof(lirc_t))) { + retval = -EFAULT; + break; + } + rx_head = (rx_head + 1) & (RBUF_LEN - 1); + n += sizeof(lirc_t); + } + if (n) + return n; + return retval; +} + + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *pos) +{ + int i = 0; + + if (n % sizeof(lirc_t) || (n / sizeof(lirc_t)) > WBUF_LEN) + return -EINVAL; + if (copy_from_user(tx_buf, buf, n)) + return -EFAULT; + n /= sizeof(lirc_t); + init_send(); + while (1) { + if (i >= n) + break; + if (tx_buf[i]) + send_pulse(tx_buf[i]); + i++; + if (i >= n) + break; + if (tx_buf[i]) + send_space(tx_buf[i]); + i++; + } + terminate_send(tx_buf[i - 1]); + return n; +} + + +static int lirc_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg) +{ + int retval = 0; + unsigned long value = 0; + unsigned int ivalue; + unsigned long hw_flags; + + if (cmd == LIRC_GET_FEATURES) + value = LIRC_CAN_SEND_PULSE | + LIRC_CAN_SET_SEND_CARRIER | + LIRC_CAN_REC_MODE2; + else if (cmd == LIRC_GET_SEND_MODE) + value = LIRC_MODE_PULSE; + else if (cmd == LIRC_GET_REC_MODE) + value = LIRC_MODE_MODE2; + + switch (cmd) { + case LIRC_GET_FEATURES: + case LIRC_GET_SEND_MODE: + case LIRC_GET_REC_MODE: + retval = put_user(value, (unsigned long *) arg); + break; + + case LIRC_SET_SEND_MODE: + case LIRC_SET_REC_MODE: + retval = get_user(value, (unsigned long *) arg); + break; + + case LIRC_SET_SEND_CARRIER: + retval = get_user(ivalue, (unsigned int *) arg); + if (retval) + return retval; + ivalue /= 1000; + if (ivalue > IT87_CIR_FREQ_MAX || + ivalue < IT87_CIR_FREQ_MIN) + return -EINVAL; + + it87_freq = ivalue; + + spin_lock_irqsave(&hardware_lock, hw_flags); + outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) | + (it87_freq - IT87_CIR_FREQ_MIN) << 3), + io + IT87_CIR_TCR2); + spin_unlock_irqrestore(&hardware_lock, hw_flags); + dprintk("demodulation frequency: %d kHz\n", it87_freq); + + break; + + default: + retval = -ENOIOCTLCMD; + } + + if (retval) + return retval; + + if (cmd == LIRC_SET_REC_MODE) { + if (value != LIRC_MODE_MODE2) + retval = -ENOSYS; + } else if (cmd == LIRC_SET_SEND_MODE) { + if (value != LIRC_MODE_PULSE) + retval = -ENOSYS; + } + return retval; +} + +static void add_read_queue(int flag, unsigned long val) +{ + unsigned int new_rx_tail; + lirc_t newval; + + dprintk("add flag %d with val %lu\n", flag, val); + + newval = val & PULSE_MASK; + + /* statistically pulses are ~TIME_CONST/2 too long: we could + maybe make this more exactly but this is good enough */ + if (flag) { + /* pulse */ + if (newval > TIME_CONST / 2) + newval -= TIME_CONST / 2; + else /* should not ever happen */ + newval = 1; + newval |= PULSE_BIT; + } else + newval += TIME_CONST / 2; + new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); + if (new_rx_tail == rx_head) { + dprintk("Buffer overrun.\n"); + return; + } + rx_buf[rx_tail] = newval; + rx_tail = new_rx_tail; + wake_up_interruptible(&lirc_read_queue); +} + + +static struct file_operations lirc_fops = { + .read = lirc_read, + .write = lirc_write, + .poll = lirc_poll, + .ioctl = lirc_ioctl, + .open = lirc_open, + .release = lirc_close, +}; + +static int set_use_inc(void *data) +{ + return 0; +} + +static void set_use_dec(void *data) +{ + +} +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + + +#ifdef MODULE +static int init_chrdev(void) +{ + plugin.minor = lirc_register_plugin(&plugin); + + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); + return -EIO; + } + return 0; +} + + +static void drop_chrdev(void) +{ + lirc_unregister_plugin(plugin.minor); +} +#endif + + +/* SECTION: Hardware */ +static long delta(struct timeval *tv1, struct timeval *tv2) +{ + unsigned long deltv; + + deltv = tv2->tv_sec - tv1->tv_sec; + if (deltv > 15) + deltv = 0xFFFFFF; + else + deltv = deltv*1000000 + tv2->tv_usec - tv1->tv_usec; + return deltv; +} + +static void it87_timeout(unsigned long data) +{ + unsigned long flags; + + /* avoid interference with interrupt */ + spin_lock_irqsave(&timer_lock, flags); + + if (digimatrix) { + /* We have timed out. + Disable the RX mechanism. + */ + + outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) | + IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR); + if (it87_RXEN_mask) + outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + dprintk(" TIMEOUT\n"); + timer_enabled = 0; + + /* fifo clear */ + outb(inb(io + IT87_CIR_TCR1) | IT87_CIR_TCR1_FIFOCLR, + io+IT87_CIR_TCR1); + + } else { + /* if last received signal was a pulse, but receiving + stopped within the 9 bit frame, we need to finish + this pulse and simulate a signal change to from + pulse to space. Otherwise upper layers will receive + two sequences next time. */ + + if (last_value) { + unsigned long pulse_end; + + /* determine 'virtual' pulse end: */ + pulse_end = delta(&last_tv, &last_intr_tv); + dprintk("timeout add %d for %lu usec\n", + last_value, pulse_end); + add_read_queue(last_value, pulse_end); + last_value = 0; + last_tv = last_intr_tv; + } + } + spin_unlock_irqrestore(&timer_lock, flags); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t it87_interrupt(int irq, void *dev_id, struct pt_regs *regs) +#else +static irqreturn_t it87_interrupt(int irq, void *dev_id) +#endif +{ + unsigned char data; + struct timeval curr_tv; + static unsigned long deltv; + unsigned long deltintrtv; + unsigned long flags, hw_flags; + int iir, lsr; + int fifo = 0; + static char lastbit; + char bit; + + /* Bit duration in microseconds */ + const unsigned long bit_duration = 1000000ul / + (115200 / IT87_CIR_BAUDRATE_DIVISOR); + + + iir = inb(io + IT87_CIR_IIR); + + switch (iir & IT87_CIR_IIR_IID) { + case 0x4: + case 0x6: + lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO | + IT87_CIR_RSR_RXFBC); + fifo = lsr & IT87_CIR_RSR_RXFBC; + dprintk("iir: 0x%x fifo: 0x%x\n", iir, lsr); + + /* avoid interference with timer */ + spin_lock_irqsave(&timer_lock, flags); + spin_lock_irqsave(&hardware_lock, hw_flags); + if (digimatrix) { + static unsigned long acc_pulse; + static unsigned long acc_space; + + do { + data = inb(io + IT87_CIR_DR); + data = ~data; + fifo--; + if (data != 0x00) { + if (timer_enabled) + del_timer(&timerlist); + /* start timer for end of + * sequence detection */ + timerlist.expires = jiffies + + IT87_TIMEOUT; + add_timer(&timerlist); + timer_enabled = 1; + } + /* Loop through */ + for (bit = 0; bit < 8; ++bit) { + if ((data >> bit) & 1) { + ++acc_pulse; + if (lastbit == 0) { + add_read_queue(0, + acc_space * + bit_duration); + acc_space = 0; + } + } else { + ++acc_space; + if (lastbit == 1) { + add_read_queue(1, + acc_pulse * + bit_duration); + acc_pulse = 0; + } + } + lastbit = (data >> bit) & 1; + } + + } while (fifo != 0); + } else { /* Normal Operation */ + do { + del_timer(&timerlist); + data = inb(io + IT87_CIR_DR); + + dprintk("data=%.2x\n", data); + do_gettimeofday(&curr_tv); + deltv = delta(&last_tv, &curr_tv); + deltintrtv = delta(&last_intr_tv, &curr_tv); + + dprintk("t %lu , d %d\n", + deltintrtv, (int)data); + + /* if nothing came in last 2 cycles, + it was gap */ + if (deltintrtv > TIME_CONST * 2) { + if (last_value) { + dprintk("GAP\n"); + + /* simulate signal change */ + add_read_queue(last_value, + deltv - + deltintrtv); + last_value = 0; + last_tv.tv_sec = + last_intr_tv.tv_sec; + last_tv.tv_usec = + last_intr_tv.tv_usec; + deltv = deltintrtv; + } + } + data = 1; + if (data ^ last_value) { + /* deltintrtv > 2*TIME_CONST, + remember ? */ + /* the other case is timeout */ + add_read_queue(last_value, + deltv-TIME_CONST); + last_value = data; + last_tv = curr_tv; + if (last_tv.tv_usec >= TIME_CONST) + last_tv.tv_usec -= TIME_CONST; + else { + last_tv.tv_sec--; + last_tv.tv_usec += 1000000 - + TIME_CONST; + } + } + last_intr_tv = curr_tv; + if (data) { + /* start timer for end of + * sequence detection */ + timerlist.expires = + jiffies + IT87_TIMEOUT; + add_timer(&timerlist); + } + outb((inb(io + IT87_CIR_RCR) & + ~IT87_CIR_RCR_RXEN) | + IT87_CIR_RCR_RXACT, + io + IT87_CIR_RCR); + if (it87_RXEN_mask) + outb(inb(io + IT87_CIR_RCR) | + IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + fifo--; + } while (fifo != 0); + } + spin_unlock_irqrestore(&hardware_lock, hw_flags); + spin_unlock_irqrestore(&timer_lock, flags); + + return IRQ_RETVAL(IRQ_HANDLED); + + default: + /* not our irq */ + dprintk("unknown IRQ (shouldn't happen) !!\n"); + return IRQ_RETVAL(IRQ_NONE); + } +} + + +static void send_it87(unsigned long len, unsigned long stime, + unsigned char send_byte, unsigned int count_bits) +{ + long count = len / stime; + long time_left = 0; + static unsigned char byte_out; + unsigned long hw_flags; + + dprintk("%s: len=%ld, sb=%d\n", __FUNCTION__, len, send_byte); + + time_left = (long)len - (long)count * (long)stime; + count += ((2 * time_left) / stime); + while (count) { + long i = 0; + for (i = 0; i < count_bits; i++) { + byte_out = (byte_out << 1) | (send_byte & 1); + it87_bits_in_byte_out++; + } + if (it87_bits_in_byte_out == 8) { + dprintk("out=0x%x, tsr_txfbc: 0x%x\n", + byte_out, + inb(io + IT87_CIR_TSR) & + IT87_CIR_TSR_TXFBC); + + while ((inb(io + IT87_CIR_TSR) & + IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE) + ; + + spin_lock_irqsave(&hardware_lock, hw_flags); + outb(byte_out, io + IT87_CIR_DR); + spin_unlock_irqrestore(&hardware_lock, hw_flags); + + it87_bits_in_byte_out = 0; + it87_send_counter++; + byte_out = 0; + } + count--; + } +} + + +/* +maybe: exchange space and pulse because +it8705 only modulates 0-bits +*/ + + +static void send_space(unsigned long len) +{ + send_it87(len, TIME_CONST, IT87_CIR_SPACE, IT87_CIR_BAUDRATE_DIVISOR); +} + +static void send_pulse(unsigned long len) +{ + send_it87(len, TIME_CONST, IT87_CIR_PULSE, IT87_CIR_BAUDRATE_DIVISOR); +} + + +static void init_send() +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + /* RXEN=0: receiver disable */ + it87_RXEN_mask = 0; + outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + spin_unlock_irqrestore(&hardware_lock, flags); + it87_bits_in_byte_out = 0; + it87_send_counter = 0; +} + + +static void terminate_send(unsigned long len) +{ + unsigned long flags; + unsigned long last = 0; + + last = it87_send_counter; + /* make sure all necessary data has been sent */ + while (last == it87_send_counter) + send_space(len); + /* wait until all data sent */ + while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0); + /* then reenable receiver */ + spin_lock_irqsave(&hardware_lock, flags); + it87_RXEN_mask = IT87_CIR_RCR_RXEN; + outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN, + io + IT87_CIR_RCR); + spin_unlock_irqrestore(&hardware_lock, flags); +} + + +static int init_hardware(void) +{ + unsigned long flags; + unsigned char it87_rcr = 0; + + spin_lock_irqsave(&hardware_lock, flags); + /* init cir-port */ + /* enable r/w-access to Baudrate-Register */ + outb(IT87_CIR_IER_BR, io + IT87_CIR_IER); + outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR); + outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR); + /* Baudrate Register off, define IRQs: Input only */ + if (digimatrix) { + outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RFOIE, io + IT87_CIR_IER); + /* RX: HCFS=0, RXDCR = 001b (33,75..38,25 kHz), RXEN=1 */ + } else { + outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER); + /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */ + } + it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1; + if (it87_enable_demodulator) + it87_rcr |= IT87_CIR_RCR_RXEND; + outb(it87_rcr, io + IT87_CIR_RCR); + if (digimatrix) { + /* Set FIFO depth to 1 byte, and disable TX */ + outb(inb(io + IT87_CIR_TCR1) | 0x00, + io + IT87_CIR_TCR1); + + /* TX: it87_freq (36kHz), + 'reserved' sensitivity setting (0x00) */ + outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x00, + io + IT87_CIR_TCR2); + } else { + /* TX: 38kHz, 13,3us (pulse-width */ + outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06, + io + IT87_CIR_TCR2); + } + spin_unlock_irqrestore(&hardware_lock, flags); + return 0; +} + + +static void drop_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + disable_irq(irq); + /* receiver disable */ + it87_RXEN_mask = 0; + outb(0x1, io + IT87_CIR_RCR); + /* turn off irqs */ + outb(0, io + IT87_CIR_IER); + /* fifo clear */ + outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1); + /* reset */ + outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); + enable_irq(irq); + spin_unlock_irqrestore(&hardware_lock, flags); +} + + +static unsigned char it87_read(unsigned char port) +{ + outb(port, IT87_ADRPORT); + return inb(IT87_DATAPORT); +} + + +static void it87_write(unsigned char port, unsigned char data) +{ + outb(port, IT87_ADRPORT); + outb(data, IT87_DATAPORT); +} + + +/* SECTION: Initialisation */ + +static int init_port(void) +{ + unsigned long hw_flags; + int retval = 0; + + unsigned char init_bytes[4] = {IT87_INIT}; + unsigned char it87_chipid = 0; + unsigned char ldn = 0; + unsigned int it87_io = 0; + unsigned int it87_irq = 0; + + /* Enter MB PnP Mode */ + outb(init_bytes[0], IT87_ADRPORT); + outb(init_bytes[1], IT87_ADRPORT); + outb(init_bytes[2], IT87_ADRPORT); + outb(init_bytes[3], IT87_ADRPORT); + + /* 8712 or 8705 ? */ + it87_chipid = it87_read(IT87_CHIP_ID1); + if (it87_chipid != 0x87) { + retval = -ENXIO; + return retval; + } + it87_chipid = it87_read(IT87_CHIP_ID2); + if ((it87_chipid != 0x12) && (it87_chipid != 0x05)) { + printk(KERN_INFO LIRC_DRIVER_NAME + ": no IT8705/12 found, exiting..\n"); + retval = -ENXIO; + return retval; + } + printk(KERN_INFO LIRC_DRIVER_NAME + ": found IT87%.2x.\n", + it87_chipid); + + /* get I/O-Port and IRQ */ + if (it87_chipid == 0x12) + ldn = IT8712_CIR_LDN; + else + ldn = IT8705_CIR_LDN; + it87_write(IT87_LDN, ldn); + + it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 + + it87_read(IT87_CIR_BASE_LSB); + if (it87_io == 0) { + if (io == 0) + io = IT87_CIR_DEFAULT_IOBASE; + printk(KERN_INFO LIRC_DRIVER_NAME + ": set default io 0x%x\n", + io); + it87_write(IT87_CIR_BASE_MSB, io / 0x100); + it87_write(IT87_CIR_BASE_LSB, io % 0x100); + } else + io = it87_io; + + it87_irq = it87_read(IT87_CIR_IRQ); + if (digimatrix || it87_irq == 0) { + if (irq == 0) + irq = IT87_CIR_DEFAULT_IRQ; + printk(KERN_INFO LIRC_DRIVER_NAME + ": set default irq 0x%x\n", + irq); + it87_write(IT87_CIR_IRQ, irq); + } else + irq = it87_irq; + + spin_lock_irqsave(&hardware_lock, hw_flags); + /* reset */ + outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER); + /* fifo clear */ + outb(IT87_CIR_TCR1_FIFOCLR | + /* IT87_CIR_TCR1_ILE | */ + IT87_CIR_TCR1_TXRLE | + IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1); + spin_unlock_irqrestore(&hardware_lock, hw_flags); + + /* get I/O port access and IRQ line */ + if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": i/o port 0x%.4x already in use.\n", io); + /* Leaving MB PnP Mode */ + it87_write(IT87_CFGCTRL, 0x2); + return -EBUSY; + } + + /* activate CIR-Device */ + it87_write(IT87_CIR_ACT, 0x1); + + /* Leaving MB PnP Mode */ + it87_write(IT87_CFGCTRL, 0x2); + + retval = request_irq(irq, it87_interrupt, 0 /*IRQF_DISABLED*/, + LIRC_DRIVER_NAME, NULL); + if (retval < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": IRQ %d already in use.\n", + irq); + release_region(io, 8); + return retval; + } + + printk(KERN_INFO LIRC_DRIVER_NAME + ": I/O port 0x%.4x, IRQ %d.\n", io, irq); + + init_timer(&timerlist); + timerlist.function = it87_timeout; + timerlist.data = 0xabadcafe; + + return 0; +} + + +static void drop_port(void) +{ +/* + unsigned char init_bytes[4] = {IT87_INIT}; + + / * Enter MB PnP Mode * / + outb(init_bytes[0], IT87_ADRPORT); + outb(init_bytes[1], IT87_ADRPORT); + outb(init_bytes[2], IT87_ADRPORT); + outb(init_bytes[3], IT87_ADRPORT); + + / * deactivate CIR-Device * / + it87_write(IT87_CIR_ACT, 0x0); + + / * Leaving MB PnP Mode * / + it87_write(IT87_CFGCTRL, 0x2); +*/ + + del_timer_sync(&timerlist); + free_irq(irq, NULL); + release_region(io, 8); +} + + +static int init_lirc_it87(void) +{ + int retval; + + init_waitqueue_head(&lirc_read_queue); + retval = init_port(); + if (retval < 0) + return retval; + init_hardware(); + printk(KERN_INFO LIRC_DRIVER_NAME ": Installed.\n"); + return 0; +} + + +#ifdef MODULE + +int init_module(void) +{ + int retval; + + retval = init_chrdev(); + if (retval < 0) + return retval; + retval = init_lirc_it87(); + if (retval) { + drop_chrdev(); + return retval; + } + return 0; +} + + +void cleanup_module(void) +{ + drop_hardware(); + drop_chrdev(); + drop_port(); + printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); +} + +MODULE_DESCRIPTION("LIRC driver for ITE IT8712/IT8705 CIR port"); +MODULE_AUTHOR("Hans-Günter Lütke Uphues"); +MODULE_LICENSE("GPL"); + +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O base address (default: 0x310)"); + +module_param(irq, int, 0444); +#ifdef LIRC_IT87_DIGIMATRIX +MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 9)"); +#else +MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)"); +#endif + +module_param(it87_enable_demodulator, bool, 0444); +MODULE_PARM_DESC(it87_enable_demodulator, + "Receiver demodulator enable/disable (1/0), default: 0"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +module_param(digimatrix, bool, 0644); +#ifdef LIRC_IT87_DIGIMATRIX +MODULE_PARM_DESC(digimatrix, + "Asus Digimatrix it87 compat. enable/disable (1/0), default: 1"); +#else +MODULE_PARM_DESC(digimatrix, + "Asus Digimatrix it87 compat. enable/disable (1/0), default: 0"); +#endif + + +module_param(it87_freq, int, 0444); +#ifdef LIRC_IT87_DIGIMATRIX +MODULE_PARM_DESC(it87_freq, + "Carrier demodulator frequency (kHz), (default: 36)"); +#else +MODULE_PARM_DESC(it87_freq, + "Carrier demodulator frequency (kHz), (default: 38)"); +#endif + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_it87/README +++ linux-2.6.28/ubuntu/lirc/lirc_it87/README @@ -0,0 +1,46 @@ +This is the README using the ITE IT8705 and IT8712 CIR port for LIRC. + +The IT8705 for example can be found on the ECS K7S5A. + +The driver supports receiving (MODE2) and sending (PULSE). It seems +sending 'LIRC_CAN_SEND_PULSE' isn't optimal for this type of hardware. +But because I don't know how to implement 'LIRC_CAN_SEND_CODE', I did +it this way. + +Attention: +Because of missing hardware, the following hasn't been tested: +a) receiving with demodulator enabled, +b) sending (debugging output looks good) and +c) using IT8712 + +Any help and/or additions etc. is welcome. + +lirc_it87 knows about the following module-parameters: +MODULE_DESCRIPTION("LIRC driver for ITE IT8712/IT8705 CIR port"); +MODULE_PARM(io, "i"); +MODULE_PARM_DESC(io, "I/O base address (default: 0x310)"); +MODULE_PARM(irq, "i"); +MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)"); +MODULE_PARM(it87_enable_demodulator, "i"); +MODULE_PARM_DESC(it87_enable_demodulator, "Receiver demodulator + enable/disable (1/0), default: 0"); + + +Usage: + +a) io and irq: + +If the driver finds the IT8705/12-CIR port initialized, io and irq of +the preinitialized hardware is used by the driver. If both values are +read 0x0 from the hardware, the default or given value is used. +Note: I experienced using irq=3. The driver initialized without any +problems, but no irqs are recognized by the system. I had to switch +back to default, irq 7. + +b) it87_enable_demodulator: + +The demodulator for the receiver can be switched off (default within +the driver). If you need the demodulator simple enable it by the +following way: it87_enable_demodulator=1. + +Hans-Günter Lütke Uphues --- linux-2.6.28.orig/ubuntu/lirc/lirc_dev/lirc_dev.c +++ linux-2.6.28/ubuntu/lirc/lirc_dev/lirc_dev.c @@ -0,0 +1,960 @@ +/* + * LIRC base driver + * + * (L) by Artur Lipowski + * + * 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 + * + * $Id: lirc_dev.c,v 1.58 2008/05/14 16:37:49 lirc Exp $ + * + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#include +#else +#include +#include +#endif +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#include +#endif +#define __KERNEL_SYSCALLS__ +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 23) +#include +#endif + +#include "kcompat.h" + +/* SysFS header */ +#if defined(LIRC_HAVE_SYSFS) +#include +#endif + +#include "lirc.h" +#include "lirc_dev.h" + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +#define IRCTL_DEV_NAME "BaseRemoteCtl" +#define SUCCESS 0 +#define NOPLUG -1 +#define LOGHEAD "lirc_dev (%s[%d]): " + +struct irctl { + struct lirc_plugin p; + int attached; + int open; + + struct semaphore buffer_sem; + struct lirc_buffer *buf; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + int tpid; + struct completion *t_notify; + struct completion *t_notify2; + int shutdown; +#else + struct task_struct *task; +#endif + long jiffies_to_wait; + +#ifdef LIRC_HAVE_DEVFS_24 + devfs_handle_t devfs_handle; +#endif +}; + +DECLARE_MUTEX(plugin_lock); + +static struct irctl irctls[MAX_IRCTL_DEVICES]; +static struct file_operations fops; + +/* Only used for sysfs but defined to void otherwise */ +static lirc_class_t *lirc_class; + +/* helper function + * initializes the irctl structure + */ +static inline void init_irctl(struct irctl *ir) +{ + memset(&ir->p, 0, sizeof(struct lirc_plugin)); + sema_init(&ir->buffer_sem, 1); + ir->p.minor = NOPLUG; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + ir->tpid = -1; + ir->t_notify = NULL; + ir->t_notify2 = NULL; + ir->shutdown = 0; +#else + ir->task = NULL; +#endif + ir->jiffies_to_wait = 0; + + ir->open = 0; + ir->attached = 0; +} + +static void cleanup(struct irctl *ir) +{ + dprintk(LOGHEAD "cleaning up\n", ir->p.name, ir->p.minor); + +#ifdef LIRC_HAVE_DEVFS_24 + devfs_unregister(ir->devfs_handle); +#endif +#ifdef LIRC_HAVE_DEVFS_26 + devfs_remove(DEV_LIRC "/%u", ir->p.minor); +#endif + lirc_device_destroy(lirc_class, + MKDEV(IRCTL_DEV_MAJOR, ir->p.minor)); + + if (ir->buf != ir->p.rbuf) { + lirc_buffer_free(ir->buf); + kfree(ir->buf); + } + ir->buf = NULL; + + init_irctl(ir); +} + +/* helper function + * reads key codes from plugin and puts them into buffer + * buffer free space is checked and locking performed + * returns 0 on success + */ +static inline int add_to_buf(struct irctl *ir) +{ + if (lirc_buffer_full(ir->buf)) { + dprintk(LOGHEAD "buffer overflow\n", + ir->p.name, ir->p.minor); + return -EOVERFLOW; + } + + if (ir->p.add_to_buf) { + int res = -ENODATA; + int got_data = 0; + + /* service the device as long as it is returning + * data and we have space + */ + while (!lirc_buffer_full(ir->buf)) { + res = ir->p.add_to_buf(ir->p.data, ir->buf); + if (res == SUCCESS) + got_data++; + else + break; + } + + if (res == -ENODEV) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + ir->shutdown = 1; +#else + kthread_stop(ir->task); +#endif + + return (got_data ? SUCCESS : res); + } + + return SUCCESS; +} + +/* main function of the polling thread + */ +static int lirc_thread(void *irctl) +{ + struct irctl *ir = irctl; + + /* This thread doesn't need any user-level access, + * so get rid of all our resources + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + daemonize("lirc_dev"); + + if (ir->t_notify != NULL) + complete(ir->t_notify); +#endif + + dprintk(LOGHEAD "poll thread started\n", ir->p.name, ir->p.minor); + + do { + if (ir->open) { + if (ir->jiffies_to_wait) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(ir->jiffies_to_wait); + } else { + interruptible_sleep_on( + ir->p.get_queue(ir->p.data)); + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + if (ir->shutdown) +#else + if (kthread_should_stop()) +#endif + break; + if (!add_to_buf(ir)) + wake_up_interruptible(&ir->buf->wait_poll); + } else { + /* if device not opened so we can sleep half a second */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/2); + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + } while (!ir->shutdown); + + if (ir->t_notify2 != NULL) + wait_for_completion(ir->t_notify2); + + ir->tpid = -1; + if (ir->t_notify != NULL) + complete(ir->t_notify); +#else + } while (!kthread_should_stop()); +#endif + + dprintk(LOGHEAD "poll thread ended\n", ir->p.name, ir->p.minor); + + return 0; +} + +int lirc_register_plugin(struct lirc_plugin *p) +{ + struct irctl *ir; + int minor; + int bytes_in_key; + int err; +#ifdef LIRC_HAVE_DEVFS_24 + char name[16]; +#endif + DECLARE_COMPLETION(tn); + + if (!p) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "plugin pointer must be not NULL!\n"); + err = -EBADRQC; + goto out; + } + + if (MAX_IRCTL_DEVICES <= p->minor) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "\"minor\" must be between 0 and %d (%d)!\n", + MAX_IRCTL_DEVICES-1, p->minor); + err = -EBADRQC; + goto out; + } + + if (1 > p->code_length || (BUFLEN * 8) < p->code_length) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "code length in bits for minor (%d) " + "must be less than %d!\n", + p->minor, BUFLEN * 8); + err = -EBADRQC; + goto out; + } + + printk(KERN_INFO "lirc_dev: lirc_register_plugin: sample_rate: %d\n", + p->sample_rate); + if (p->sample_rate) { + if (2 > p->sample_rate || HZ < p->sample_rate) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "sample_rate must be between 2 and %d!\n", HZ); + err = -EBADRQC; + goto out; + } + if (!p->add_to_buf) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "add_to_buf cannot be NULL when " + "sample_rate is set\n"); + err = -EBADRQC; + goto out; + } + } else if (!(p->fops && p->fops->read) + && !p->get_queue && !p->rbuf) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "fops->read, get_queue and rbuf " + "cannot all be NULL!\n"); + err = -EBADRQC; + goto out; + } else if (!p->get_queue && !p->rbuf) { + if (!(p->fops && p->fops->read && p->fops->poll) + || (!p->fops->ioctl && !p->ioctl)) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "neither read, poll nor ioctl can be NULL!\n"); + err = -EBADRQC; + goto out; + } + } + + if (p->owner == NULL) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "no module owner registered\n"); + err = -EBADRQC; + goto out; + } + + down(&plugin_lock); + + minor = p->minor; + + if (0 > minor) { + /* find first free slot for plugin */ + for (minor = 0; minor < MAX_IRCTL_DEVICES; minor++) + if (irctls[minor].p.minor == NOPLUG) + break; + if (MAX_IRCTL_DEVICES == minor) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "no free slots for plugins!\n"); + err = -ENOMEM; + goto out_lock; + } + } else if (irctls[minor].p.minor != NOPLUG) { + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "minor (%d) just registered!\n", minor); + err = -EBUSY; + goto out_lock; + } + + ir = &irctls[minor]; + + if (p->sample_rate) { + ir->jiffies_to_wait = HZ / p->sample_rate; + } else { + /* it means - wait for external event in task queue */ + ir->jiffies_to_wait = 0; + } + + /* some safety check 8-) */ + p->name[sizeof(p->name)-1] = '\0'; + + bytes_in_key = p->code_length/8 + (p->code_length%8 ? 1 : 0); + + if (p->rbuf) { + ir->buf = p->rbuf; + } else { + ir->buf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!ir->buf) { + err = -ENOMEM; + goto out_lock; + } + if (lirc_buffer_init(ir->buf, bytes_in_key, + BUFLEN/bytes_in_key) != 0) { + kfree(ir->buf); + err = -ENOMEM; + goto out_lock; + } + } + + if (p->features == 0) + p->features = (p->code_length > 8) ? + LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_CODE; + + ir->p = *p; + ir->p.minor = minor; + +#if defined(LIRC_HAVE_DEVFS_24) + sprintf(name, DEV_LIRC "/%d", ir->p.minor); + ir->devfs_handle = devfs_register(NULL, name, DEVFS_FL_DEFAULT, + IRCTL_DEV_MAJOR, ir->p.minor, + S_IFCHR | S_IRUSR | S_IWUSR, + &fops, NULL); +#elif defined(LIRC_HAVE_DEVFS_26) + devfs_mk_cdev(MKDEV(IRCTL_DEV_MAJOR, ir->p.minor), + S_IFCHR|S_IRUSR|S_IWUSR, + DEV_LIRC "/%u", ir->p.minor); +#endif + (void) device_create(lirc_class, ir->p.dev, + MKDEV(IRCTL_DEV_MAJOR, ir->p.minor), + NULL, "lirc%u", ir->p.minor); + + if (p->sample_rate || p->get_queue) { + /* try to fire up polling thread */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + ir->t_notify = &tn; + ir->tpid = kernel_thread(lirc_thread, (void *)ir, 0); + if (ir->tpid < 0) { +#else + ir->task = kthread_run(lirc_thread, (void *)ir, "lirc_dev"); + if (IS_ERR(ir->task)) { +#endif + printk(KERN_ERR "lirc_dev: lirc_register_plugin: " + "cannot run poll thread for minor = %d\n", + p->minor); + err = -ECHILD; + goto out_sysfs; + } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + wait_for_completion(&tn); + ir->t_notify = NULL; +#endif + } + ir->attached = 1; + up(&plugin_lock); + +/* + * Recent kernels should handle this autmatically by increasing/decreasing + * use count when a dependant module is loaded/unloaded. + */ +#ifndef KERNEL_2_5 + MOD_INC_USE_COUNT; +#endif + dprintk("lirc_dev: plugin %s registered at minor number = %d\n", + ir->p.name, ir->p.minor); + p->minor = minor; + return minor; + +out_sysfs: + lirc_device_destroy(lirc_class, + MKDEV(IRCTL_DEV_MAJOR, ir->p.minor)); +#ifdef LIRC_HAVE_DEVFS_24 + devfs_unregister(ir->devfs_handle); +#endif +#ifdef LIRC_HAVE_DEVFS_26 + devfs_remove(DEV_LIRC "/%i", ir->p.minor); +#endif +out_lock: + up(&plugin_lock); +out: + return err; +} +EXPORT_SYMBOL(lirc_register_plugin); + +int lirc_unregister_plugin(int minor) +{ + struct irctl *ir; + DECLARE_COMPLETION(tn); + DECLARE_COMPLETION(tn2); + + if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { + printk(KERN_ERR "lirc_dev: lirc_unregister_plugin: " + "\"minor\" must be between 0 and %d!\n", + MAX_IRCTL_DEVICES-1); + return -EBADRQC; + } + + ir = &irctls[minor]; + + down(&plugin_lock); + + if (ir->p.minor != minor) { + printk(KERN_ERR "lirc_dev: lirc_unregister_plugin: " + "minor (%d) device not registered!", minor); + up(&plugin_lock); + return -ENOENT; + } + + /* end up polling thread */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + if (ir->tpid >= 0) { + ir->t_notify = &tn; + ir->t_notify2 = &tn2; + ir->shutdown = 1; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0) + { + struct task_struct *p; + + p = find_task_by_pid(ir->tpid); + wake_up_process(p); + } +#else + /* 2.2.x does not export wake_up_process() */ + wake_up_interruptible(ir->p.get_queue(ir->p.data)); +#endif + complete(&tn2); + wait_for_completion(&tn); + ir->t_notify = NULL; + ir->t_notify2 = NULL; + } +#else /* kernel >= 2.6.23 */ + if (ir->task) { + wake_up_process(ir->task); + kthread_stop(ir->task); + } +#endif + + dprintk("lirc_dev: plugin %s unregistered from minor number = %d\n", + ir->p.name, ir->p.minor); + + ir->attached = 0; + if (ir->open) { + dprintk(LOGHEAD "releasing opened plugin\n", + ir->p.name, ir->p.minor); + wake_up_interruptible(&ir->buf->wait_poll); + down(&ir->buffer_sem); + ir->p.set_use_dec(ir->p.data); + module_put(ir->p.owner); + up(&ir->buffer_sem); + } else + cleanup(ir); + up(&plugin_lock); + +/* + * Recent kernels should handle this autmatically by increasing/decreasing + * use count when a dependant module is loaded/unloaded. + */ +#ifndef KERNEL_2_5 + MOD_DEC_USE_COUNT; +#endif + + return SUCCESS; +} +EXPORT_SYMBOL(lirc_unregister_plugin); + +/* + * + */ +static int irctl_open(struct inode *inode, struct file *file) +{ + struct irctl *ir; + int retval; + + if (MINOR(inode->i_rdev) >= MAX_IRCTL_DEVICES) { + dprintk("lirc_dev [%d]: open result = -ENODEV\n", + MINOR(inode->i_rdev)); + return -ENODEV; + } + + ir = &irctls[MINOR(inode->i_rdev)]; + + dprintk(LOGHEAD "open called\n", ir->p.name, ir->p.minor); + + /* if the plugin has an open function use it instead */ + if (ir->p.fops && ir->p.fops->open) + return ir->p.fops->open(inode, file); + + if (down_interruptible(&plugin_lock)) + return -ERESTARTSYS; + + if (ir->p.minor == NOPLUG) { + up(&plugin_lock); + dprintk(LOGHEAD "open result = -ENODEV\n", + ir->p.name, ir->p.minor); + return -ENODEV; + } + + if (ir->open) { + up(&plugin_lock); + dprintk(LOGHEAD "open result = -EBUSY\n", + ir->p.name, ir->p.minor); + return -EBUSY; + } + + /* there is no need for locking here because ir->open is 0 + * and lirc_thread isn't using buffer + * plugins which use irq's should allocate them on set_use_inc, + * so there should be no problem with those either. + */ + ir->buf->head = ir->buf->tail; + ir->buf->fill = 0; + + if (ir->p.owner != NULL && try_module_get(ir->p.owner)) { + ++ir->open; + retval = ir->p.set_use_inc(ir->p.data); + + if (retval != SUCCESS) { + module_put(ir->p.owner); + --ir->open; + } + } else { + if (ir->p.owner == NULL) + dprintk(LOGHEAD "no module owner!!!\n", + ir->p.name, ir->p.minor); + + retval = -ENODEV; + } + + dprintk(LOGHEAD "open result = %d\n", ir->p.name, ir->p.minor, retval); + up(&plugin_lock); + + return retval; +} + +/* + * + */ +static int irctl_close(struct inode *inode, struct file *file) +{ + struct irctl *ir = &irctls[MINOR(inode->i_rdev)]; + + dprintk(LOGHEAD "close called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a close function use it instead */ + if (ir->p.fops && ir->p.fops->release) + return ir->p.fops->release(inode, file); + + if (down_interruptible(&plugin_lock)) + return -ERESTARTSYS; + + --ir->open; + if (ir->attached) { + ir->p.set_use_dec(ir->p.data); + module_put(ir->p.owner); + } else { + cleanup(ir); + } + + up(&plugin_lock); + + return SUCCESS; +} + +/* + * + */ +static unsigned int irctl_poll(struct file *file, poll_table *wait) +{ + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + unsigned int ret; + + dprintk(LOGHEAD "poll called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a poll function use it instead */ + if (ir->p.fops && ir->p.fops->poll) + return ir->p.fops->poll(file, wait); + + down(&ir->buffer_sem); + if (!ir->attached) { + up(&ir->buffer_sem); + return POLLERR; + } + + poll_wait(file, &ir->buf->wait_poll, wait); + + dprintk(LOGHEAD "poll result = %s\n", + ir->p.name, ir->p.minor, + lirc_buffer_empty(ir->buf) ? "0" : "POLLIN|POLLRDNORM"); + + ret = lirc_buffer_empty(ir->buf) ? 0 : (POLLIN|POLLRDNORM); + + up(&ir->buffer_sem); + return ret; +} + +/* + * + */ +static int irctl_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + unsigned long mode; + int result; + struct irctl *ir = &irctls[MINOR(inode->i_rdev)]; + + dprintk(LOGHEAD "ioctl called (0x%x)\n", + ir->p.name, ir->p.minor, cmd); + + /* if the plugin has a ioctl function use it instead */ + if (ir->p.fops && ir->p.fops->ioctl) + return ir->p.fops->ioctl(inode, file, cmd, arg); + + if (ir->p.minor == NOPLUG || !ir->attached) { + dprintk(LOGHEAD "ioctl result = -ENODEV\n", + ir->p.name, ir->p.minor); + return -ENODEV; + } + + /* Give the plugin a chance to handle the ioctl */ + if (ir->p.ioctl) { + result = ir->p.ioctl(inode, file, cmd, arg); + if (result != -ENOIOCTLCMD) + return result; + } + /* The plugin can't handle cmd */ + result = SUCCESS; + + switch (cmd) { + case LIRC_GET_FEATURES: + result = put_user(ir->p.features, (unsigned long *)arg); + break; + case LIRC_GET_REC_MODE: + if (!(ir->p.features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = put_user(LIRC_REC2MODE + (ir->p.features&LIRC_CAN_REC_MASK), + (unsigned long *)arg); + break; + case LIRC_SET_REC_MODE: + if (!(ir->p.features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = get_user(mode, (unsigned long *)arg); + if (!result && !(LIRC_MODE2REC(mode) & ir->p.features)) + result = -EINVAL; + /* + * FIXME: We should actually set the mode somehow but + * for now, lirc_serial doesn't support mode changing either + */ + break; + case LIRC_GET_LENGTH: + result = put_user((unsigned long)ir->p.code_length, + (unsigned long *)arg); + break; + default: + result = -ENOIOCTLCMD; + } + + dprintk(LOGHEAD "ioctl result = %d\n", + ir->p.name, ir->p.minor, result); + + return result; +} + +/* + * + */ +static ssize_t irctl_read(struct file *file, + char *buffer, + size_t length, + loff_t *ppos) +{ + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + unsigned char buf[ir->buf->chunk_size]; + int ret = 0, written = 0; + DECLARE_WAITQUEUE(wait, current); + + dprintk(LOGHEAD "read called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a specific read function use it instead */ + if (ir->p.fops && ir->p.fops->read) + return ir->p.fops->read(file, buffer, length, ppos); + + if (down_interruptible(&ir->buffer_sem)) + return -ERESTARTSYS; + if (!ir->attached) { + up(&ir->buffer_sem); + return -ENODEV; + } + + if (length % ir->buf->chunk_size) { + dprintk(LOGHEAD "read result = -EINVAL\n", + ir->p.name, ir->p.minor); + up(&ir->buffer_sem); + return -EINVAL; + } + + /* + * we add ourselves to the task queue before buffer check + * to avoid losing scan code (in case when queue is awaken somewhere + * beetwen while condition checking and scheduling) + */ + add_wait_queue(&ir->buf->wait_poll, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + /* + * while we did't provide 'length' bytes, device is opened in blocking + * mode and 'copy_to_user' is happy, wait for data. + */ + while (written < length && ret == 0) { + if (lirc_buffer_empty(ir->buf)) { + /* According to the read(2) man page, 'written' can be + * returned as less than 'length', instead of blocking + * again, returning -EWOULDBLOCK, or returning + * -ERESTARTSYS */ + if (written) + break; + if (file->f_flags & O_NONBLOCK) { + ret = -EWOULDBLOCK; + break; + } + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + if (!ir->attached) { + ret = -ENODEV; + break; + } + } else { + lirc_buffer_read_1(ir->buf, buf); + ret = copy_to_user((void *)buffer+written, buf, + ir->buf->chunk_size); + written += ir->buf->chunk_size; + } + } + + remove_wait_queue(&ir->buf->wait_poll, &wait); + set_current_state(TASK_RUNNING); + up(&ir->buffer_sem); + + dprintk(LOGHEAD "read result = %s (%d)\n", + ir->p.name, ir->p.minor, ret ? "-EFAULT" : "OK", ret); + + return ret ? ret : written; +} + + +void *lirc_get_pdata(struct file *file) +{ + void *data = NULL; + + if (file && file->f_dentry && file->f_dentry->d_inode && + file->f_dentry->d_inode->i_rdev) { + struct irctl *ir; + ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + data = ir->p.data; + } + + return data; +} +EXPORT_SYMBOL(lirc_get_pdata); + + +static ssize_t irctl_write(struct file *file, const char *buffer, + size_t length, loff_t *ppos) +{ + struct irctl *ir = &irctls[MINOR(file->f_dentry->d_inode->i_rdev)]; + + dprintk(LOGHEAD "write called\n", ir->p.name, ir->p.minor); + + /* if the plugin has a specific read function use it instead */ + if (ir->p.fops && ir->p.fops->write) + return ir->p.fops->write(file, buffer, length, ppos); + + if (!ir->attached) + return -ENODEV; + + return -EINVAL; +} + + +static struct file_operations fops = { + .read = irctl_read, + .write = irctl_write, + .poll = irctl_poll, + .ioctl = irctl_ioctl, + .open = irctl_open, + .release = irctl_close +}; + + +static int lirc_dev_init(void) +{ + int i; + + for (i = 0; i < MAX_IRCTL_DEVICES; ++i) + init_irctl(&irctls[i]); + + if (register_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME, &fops)) { + printk(KERN_ERR "lirc_dev: register_chrdev failed\n"); + goto out; + } + + lirc_class = class_create(THIS_MODULE, "lirc"); + if (IS_ERR(lirc_class)) { + printk(KERN_ERR "lirc_dev: class_create failed\n"); + goto out_unregister; + } + + printk(KERN_INFO "lirc_dev: IR Remote Control driver registered, " + "major %d \n", IRCTL_DEV_MAJOR); + + return SUCCESS; + +out_unregister: +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + if (unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME)) + printk(KERN_ERR "lirc_dev: unregister_chrdev failed!\n"); +#else + /* unregister_chrdev returns void now */ + unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); +#endif +out: + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/* For now dont try to use it as a static version ! */ + +#ifdef MODULE + +/* + * + */ +int init_module(void) +{ + return lirc_dev_init(); +} + +/* + * + */ +void cleanup_module(void) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + int ret; + + ret = unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); + class_destroy(lirc_class); + + if (ret) + printk(KERN_ERR "lirc_dev: error in " + "module_unregister_chrdev: %d\n", ret); + else + dprintk("lirc_dev: module successfully unloaded\n"); +#else + /* unregister_chrdev returns void now */ + unregister_chrdev(IRCTL_DEV_MAJOR, IRCTL_DEV_NAME); + class_destroy(lirc_class); + dprintk("lirc_dev: module unloaded\n"); +#endif +} + +MODULE_DESCRIPTION("LIRC base driver module"); +MODULE_AUTHOR("Artur Lipowski"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_CHARDEV_MAJOR(IRCTL_DEV_MAJOR); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_dev/lirc_dev.h +++ linux-2.6.28/ubuntu/lirc/lirc_dev/lirc_dev.h @@ -0,0 +1,264 @@ +/* + * LIRC base driver + * + * (L) by Artur Lipowski + * This code is licensed under GNU GPL + * + * $Id: lirc_dev.h,v 1.22 2008/01/13 10:45:02 lirc Exp $ + * + */ + +#ifndef _LINUX_LIRC_DEV_H +#define _LINUX_LIRC_DEV_H + +#define MAX_IRCTL_DEVICES 4 +#define BUFLEN 16 + +/* #define LIRC_BUFF_POWER_OF_2 */ +#ifdef LIRC_BUFF_POWER_OF_2 +#define mod(n, div) ((n) & ((div) - 1)) +#else +#define mod(n, div) ((n) % (div)) +#endif +#include +#include + +struct lirc_buffer { + wait_queue_head_t wait_poll; + spinlock_t lock; + + unsigned char *data; + unsigned int chunk_size; + unsigned int size; /* in chunks */ + unsigned int fill; /* in chunks */ + int head, tail; /* in chunks */ + /* Using chunks instead of bytes pretends to simplify boundary checking + * And should allow for some performance fine tunning later */ +}; +static inline void _lirc_buffer_clear(struct lirc_buffer *buf) +{ + buf->head = 0; + buf->tail = 0; + buf->fill = 0; +} +static inline int lirc_buffer_init(struct lirc_buffer *buf, + unsigned int chunk_size, + unsigned int size) +{ + /* Adjusting size to the next power of 2 would allow for + * inconditional LIRC_BUFF_POWER_OF_2 optimization */ + init_waitqueue_head(&buf->wait_poll); + spin_lock_init(&buf->lock); + _lirc_buffer_clear(buf); + buf->chunk_size = chunk_size; + buf->size = size; + buf->data = kmalloc(size*chunk_size, GFP_KERNEL); + if (buf->data == NULL) + return -1; + memset(buf->data, 0, size*chunk_size); + return 0; +} +static inline void lirc_buffer_free(struct lirc_buffer *buf) +{ + kfree(buf->data); + buf->data = NULL; + buf->head = 0; + buf->tail = 0; + buf->fill = 0; + buf->chunk_size = 0; + buf->size = 0; +} +static inline int lirc_buffer_full(struct lirc_buffer *buf) +{ + return (buf->fill >= buf->size); +} +static inline int lirc_buffer_empty(struct lirc_buffer *buf) +{ + return !(buf->fill); +} +static inline int lirc_buffer_available(struct lirc_buffer *buf) +{ + return (buf->size - buf->fill); +} +static inline void lirc_buffer_lock(struct lirc_buffer *buf, + unsigned long *flags) +{ + spin_lock_irqsave(&buf->lock, *flags); +} +static inline void lirc_buffer_unlock(struct lirc_buffer *buf, + unsigned long *flags) +{ + spin_unlock_irqrestore(&buf->lock, *flags); +} +static inline void lirc_buffer_clear(struct lirc_buffer *buf) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_clear(buf); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_remove_1(struct lirc_buffer *buf) +{ + buf->head = mod(buf->head+1, buf->size); + buf->fill -= 1; +} +static inline void lirc_buffer_remove_1(struct lirc_buffer *buf) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_remove_1(buf); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_read_1(struct lirc_buffer *buf, + unsigned char *dest) +{ + memcpy(dest, &buf->data[buf->head*buf->chunk_size], buf->chunk_size); + buf->head = mod(buf->head+1, buf->size); + buf->fill -= 1; +} +static inline void lirc_buffer_read_1(struct lirc_buffer *buf, + unsigned char *dest) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_read_1(buf, dest); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_write_1(struct lirc_buffer *buf, + unsigned char *orig) +{ + memcpy(&buf->data[buf->tail*buf->chunk_size], orig, buf->chunk_size); + buf->tail = mod(buf->tail+1, buf->size); + buf->fill++; +} +static inline void lirc_buffer_write_1(struct lirc_buffer *buf, + unsigned char *orig) +{ + unsigned long flags; + lirc_buffer_lock(buf, &flags); + _lirc_buffer_write_1(buf, orig); + lirc_buffer_unlock(buf, &flags); +} +static inline void _lirc_buffer_write_n(struct lirc_buffer *buf, + unsigned char *orig, int count) +{ + memcpy(&buf->data[buf->tail * buf->chunk_size], orig, + count * buf->chunk_size); + buf->tail = mod(buf->tail + count, buf->size); + buf->fill += count; +} +static inline void lirc_buffer_write_n(struct lirc_buffer *buf, + unsigned char *orig, int count) +{ + unsigned long flags; + int space1; + + lirc_buffer_lock(buf, &flags); + if (buf->head > buf->tail) + space1 = buf->head - buf->tail; + else + space1 = buf->size - buf->tail; + + if (count > space1) { + _lirc_buffer_write_n(buf, orig, space1); + _lirc_buffer_write_n(buf, orig+(space1*buf->chunk_size), + count-space1); + } else { + _lirc_buffer_write_n(buf, orig, count); + } + lirc_buffer_unlock(buf, &flags); +} + +struct lirc_plugin { + char name[40]; + int minor; + int code_length; + int sample_rate; + unsigned long features; + void *data; + int (*add_to_buf) (void *data, struct lirc_buffer *buf); + wait_queue_head_t* (*get_queue) (void *data); + struct lirc_buffer *rbuf; + int (*set_use_inc) (void *data); + void (*set_use_dec) (void *data); + int (*ioctl) (struct inode *, struct file *, unsigned int, + unsigned long); + struct file_operations *fops; + struct device *dev; + struct module *owner; +}; +/* name: + * this string will be used for logs + * + * minor: + * indicates minor device (/dev/lirc) number for registered plugin + * if caller fills it with negative value, then the first free minor + * number will be used (if available) + * + * code_length: + * length of the remote control key code expressed in bits + * + * sample_rate: + * sample_rate equal to 0 means that no polling will be performed and + * add_to_buf will be triggered by external events (through task queue + * returned by get_queue) + * + * data: + * it may point to any plugin data and this pointer will be passed to + * all callback functions + * + * add_to_buf: + * add_to_buf will be called after specified period of the time or + * triggered by the external event, this behavior depends on value of + * the sample_rate this function will be called in user context. This + * routine should return 0 if data was added to the buffer and + * -ENODATA if none was available. This should add some number of bits + * evenly divisible by code_length to the buffer + * + * get_queue: + * this callback should return a pointer to the task queue which will + * be used for external event waiting + * + * rbuf: + * if not NULL, it will be used as a read buffer, you will have to + * write to the buffer by other means, like irq's (see also + * lirc_serial.c). + * + * set_use_inc: + * set_use_inc will be called after device is opened + * + * set_use_dec: + * set_use_dec will be called after device is closed + * + * ioctl: + * Some ioctl's can be directly handled by lirc_dev but will be + * forwared here if not NULL and only handled if it returns + * -ENOIOCTLCMD (see also lirc_serial.c). + * + * fops: + * file_operations for drivers which don't fit the current plugin model. + * + * owner: + * the module owning this struct + * + */ + + +/* following functions can be called ONLY from user context + * + * returns negative value on error or minor number + * of the registered device if success + * contens of the structure pointed by p is copied + */ +extern int lirc_register_plugin(struct lirc_plugin *p); + +/* returns negative value on error or 0 if success +*/ +extern int lirc_unregister_plugin(int minor); + +/* Returns the private data stored in the lirc_plugin + * associated with the given device file pointer. + */ +void *lirc_get_pdata(struct file *file); + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_dev/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_dev/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_DEV) += lirc_dev.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/lirc_gpio.c +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/lirc_gpio.c @@ -0,0 +1,630 @@ +/* + * Remote control driver for the TV-card + * key codes are obtained from GPIO port + * + * (L) by Artur Lipowski + * patch for the AverMedia by Santiago Garcia Mantinan + * and Christoph Bartelmus + * patch for the BestBuy by Miguel Angel Alvarez + * patch for the Winfast TV2000 by Juan Toledo + * + * patch for the I-O Data GV-BCTV5/PCI by Jens C. Rasmussen + * + * + * 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 + * + * $Id: lirc_gpio.c,v 1.50 2007/09/27 19:47:20 lirc Exp $ + * + */ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 4) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.2.4 or higher" +#error "*******************************************************" +#endif + +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#include +#endif +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#include "../drivers/char/bttv.h" +#include "../drivers/char/bttvp.h" +#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,6,16) +#include "extra_2.6.16/bttv.h" +#include "extra_2.6.16/bttvp.h" +#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,6,17) +#include "extra_2.6.17/bttv.h" +#include "extra_2.6.17/bttvp.h" +#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18) +#include "extra_2.6.18/bttv.h" +#include "extra_2.6.18/bttvp.h" +#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,6,20) +#include "extra_2.6.20/bttv.h" +#include "extra_2.6.20/bttvp.h" +#elif LINUX_VERSION_CODE == KERNEL_VERSION(2,6,22) +#include "extra_2.6.22/bttv.h" +#include "extra_2.6.22/bttvp.h" +#include "bttv_deprecated.h" +#endif + +#if BTTV_VERSION_CODE < KERNEL_VERSION(0, 7, 45) +#error "*******************************************************" +#error " Sorry, this driver needs bttv version 0.7.45 or " +#error " higher. If you are using the bttv package, copy it to " +#error " the kernel " +#error "*******************************************************" +#endif + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +/* insmod parameters */ +static int debug; +static int card; +static int minor = -1; +static int bttv_id = BTTV_BOARD_UNKNOWN; +static unsigned long gpio_mask; +static unsigned long gpio_enable; +static unsigned long gpio_lock_mask; +static unsigned long gpio_xor_mask; +static int soft_gap; +static int sample_rate = 10; + +struct rcv_info { + int bttv_id; + int card_id; + unsigned long gpio_mask; + unsigned long gpio_enable; + unsigned long gpio_lock_mask; + unsigned long gpio_xor_mask; + int soft_gap; + int sample_rate; + unsigned char code_length; +}; + +static struct rcv_info rcv_infos[] = { + {BTTV_BOARD_UNKNOWN, + 0, 0, 0, 0, 0, 0, 1, 0}, + {BTTV_BOARD_PXELVWPLTVPAK, + 0, 0x00003e00, 0, 0x0010000, 0, 0, 15, 32}, + {BTTV_BOARD_PXELVWPLTVPRO, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, + {BTTV_BOARD_PV_BT878P_9B, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, + {BTTV_BOARD_PV_BT878P_PLUS, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, +#ifdef BTTV_BOARD_PV_M4900 + {BTTV_BOARD_PV_M4900, + 0, 0x00001f00, 0, 0x0008000, 0, 500, 12, 32}, +#endif + {BTTV_BOARD_AVERMEDIA, + 0, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + + /* mapped to Capture98 */ + {BTTV_BOARD_AVPHONE98, + 0x00011461, 0x003b8000, 0x00004000, + 0x0800000, 0x00800000, 0, 10, 0}, + {BTTV_BOARD_AVERMEDIA98, + 0x00021461, 0x003b8000, 0x00004000, + 0x0800000, 0x00800000, 0, 10, 0}, + + /* mapped to Phone98 */ + {BTTV_BOARD_AVPHONE98, + 0x00031461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + /* is this one correct? */ + {BTTV_BOARD_AVERMEDIA98, + 0x00041461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + /* work-around for VDOMATE */ + {BTTV_BOARD_AVERMEDIA98, + 0x03001461, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + /* reported by Danijel Korzinek, AVerTV GOw/FM */ + {BTTV_BOARD_AVERMEDIA98, + 0x00000000, 0x00f88000, 0, 0x0010000, 0x00010000, 0, 10, 32}, + + {BTTV_BOARD_CHRONOS_VS2, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 20, 0}, + /* CPH031 and CPH033 cards (?) */ + /* MIRO was just a work-around */ + {BTTV_BOARD_MIRO, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32}, + {BTTV_BOARD_DYNALINK, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32}, +#ifdef BTTV_BOARD_ASKEY_CPH03X + {BTTV_BOARD_ASKEY_CPH03X, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 10, 32}, +#endif + {BTTV_BOARD_WINVIEW_601, + 0, 0x00001f00, 0, 0x0004000, 0, 0, 0, 32}, +#ifdef BTTV_BOARD_KWORLD + {BTTV_BOARD_KWORLD, + 0, 0x00007f00, 0, 0x0004000, 0, 0, 12, 32}, +#endif + /* just a guess */ + {BTTV_BOARD_MAGICTVIEW061, + 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32}, + {BTTV_BOARD_MAGICTVIEW063, + 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32}, + {BTTV_BOARD_PHOEBE_TVMAS, + 0, 0x0028e000, 0, 0x0020000, 0, 0, 20, 32}, +#ifdef BTTV_BOARD_BESTBUY_EASYTV2 + {BTTV_BOARD_BESTBUY_EASYTV, + 0, 0x00007F00, 0, 0x0004000, 0, 0, 10, 8}, + {BTTV_BOARD_BESTBUY_EASYTV2, + 0, 0x00007F00, 0, 0x0008000, 0, 0, 10, 8}, +#endif + /* lock_mask probably also 0x100, or maybe it is 0x0 for all others? */ + {BTTV_BOARD_FLYVIDEO, + 0, 0x000000f8, 0, 0, 0, 0, 0, 42}, + {BTTV_BOARD_FLYVIDEO_98, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42}, + {BTTV_BOARD_TYPHOON_TVIEW, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42}, +#ifdef BTTV_BOARD_FLYVIDEO_98FM + /* smorar@alfonzo.smuts.uct.ac.za */ + {BTTV_BOARD_FLYVIDEO_98FM, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 42}, +#endif + /* The Leadtek WinFast TV 2000 XP card (id 0x6606107d) uses an + * extra gpio bit compared to the original TV 2000 card (id + * 0x217d6606); as the bttv-0.7.100 driver does not + * distinguish between the two cards, we enable the extra bit + * based on the card id: */ + {BTTV_BOARD_WINFAST2000, + 0x6606107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32}, + {BTTV_BOARD_WINFAST2000, + 0x6609107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32}, + {BTTV_BOARD_WINFAST2000, + 0xff06107d, 0x000008f8, 0, 0x0000100, 0, 0, 0, 32}, + /* default: */ + {BTTV_BOARD_WINFAST2000, + 0, 0x000000f8, 0, 0x0000100, 0, 0, 0, 32}, +#ifdef BTTV_BOARD_GVBCTV5PCI + {BTTV_BOARD_GVBCTV5PCI, + 0, 0x00f0b000, 0, 0, 0, 0, 20, 8}, +#endif +}; + +static unsigned char code_length; +static unsigned char code_bytes = 1; + +#define MAX_BYTES 8 + +#define SUCCESS 0 +#define LOGHEAD "lirc_gpio (%d): " + +/* how many bits GPIO value can be shifted right before processing + * it is computed from the value of gpio_mask_parameter + */ +static unsigned char gpio_pre_shift; + +static inline int reverse(int data, int bits) +{ + int i; + int c; + + for (c = 0, i = 0; i < bits; i++) + c |= (((data & (1<>= gpio_pre_shift; + while (mask) { + if (mask & 1u) + codes[0] |= (gpio_val & 1u) << shift++; + mask >>= 1; + gpio_val >>= 1; + } + + dprintk(LOGHEAD "code is %lx\n", card, (unsigned long) codes[0]); + switch (bttv_id) { + case BTTV_BOARD_AVERMEDIA: + codes[2] = (codes[0]<<2)&0xff; + codes[3] = (~codes[2])&0xff; + codes[0] = 0x02; + codes[1] = 0xFD; + break; + case BTTV_BOARD_AVPHONE98: + codes[2] = ((codes[0]&(~0x1))<<2)&0xff; + codes[3] = (~codes[2])&0xff; + if (codes[0]&0x1) { + codes[0] = 0xc0; + codes[1] = 0x3f; + } else { + codes[0] = 0x40; + codes[1] = 0xbf; + } + break; + case BTTV_BOARD_AVERMEDIA98: + break; + case BTTV_BOARD_FLYVIDEO: + case BTTV_BOARD_FLYVIDEO_98: + case BTTV_BOARD_TYPHOON_TVIEW: +#ifdef BTTV_BOARD_FLYVIDEO_98FM + case BTTV_BOARD_FLYVIDEO_98FM: +#endif + codes[4] = codes[0]<<3; + codes[5] = ((~codes[4])&0xff); + + codes[0] = 0x00; + codes[1] = 0x1A; + codes[2] = 0x1F; + codes[3] = 0x2F; + break; + case BTTV_BOARD_MAGICTVIEW061: + case BTTV_BOARD_MAGICTVIEW063: + case BTTV_BOARD_PHOEBE_TVMAS: + codes[0] = (codes[0]&0x01) + | ((codes[0]&0x02)<<1) + | ((codes[0]&0x04)<<2) + | ((codes[0]&0x08)>>2) + | ((codes[0]&0x10)>>1); + /* FALLTHROUGH */ + case BTTV_BOARD_MIRO: + case BTTV_BOARD_DYNALINK: +#ifdef BTTV_BOARD_ASKEY_CPH03X + case BTTV_BOARD_ASKEY_CPH03X: +#endif + case BTTV_BOARD_PXELVWPLTVPAK: + case BTTV_BOARD_PXELVWPLTVPRO: + case BTTV_BOARD_PV_BT878P_9B: + case BTTV_BOARD_PV_BT878P_PLUS: +#ifdef BTTV_BOARD_PV_M4900 + case BTTV_BOARD_PV_M4900: +#endif +#ifdef BTTV_BOARD_KWORLD + case BTTV_BOARD_KWORLD: +#endif + codes[2] = reverse(codes[0], 8); + codes[3] = (~codes[2])&0xff; + codes[0] = 0x61; + codes[1] = 0xD6; + break; +#if 0 + /* derived from e-tech config file */ + /* 26 + 16 bits */ + /* won't apply it until it's confirmed with a fly98 */ + case BTTV_BOARD_FLYVIDEO_98: + case BTTV_BOARD_FLYVIDEO_98FM: + codes[4] = codes[0]<<3; + codes[5] = (~codes[4])&0xff; + + codes[0] = 0x00; + codes[1] = 0x1A; + codes[2] = 0x1F; + codes[3] = 0x2F; + break; +#endif + case BTTV_BOARD_WINFAST2000: + /* shift extra bit */ + codes[0] = (codes[0]&0x1f) | ((codes[0]&0x20) << 1); + case BTTV_BOARD_WINVIEW_601: + codes[2] = reverse(codes[0], 8); + codes[3] = (~codes[2])&0xff; + codes[0] = 0xC0; + codes[1] = 0x3F; + break; + default: + break; + } + + return SUCCESS; +} + +/* add_to_buf - copy a code to the buffer */ +static int add_to_buf(void *data, struct lirc_buffer *buf) +{ + static unsigned long next_time; + static unsigned char prev_codes[MAX_BYTES]; + unsigned long code = 0; + unsigned char cur_codes[MAX_BYTES]; + + if (bttv_read_gpio(card, &code)) { + dprintk(LOGHEAD "cannot read GPIO\n", card); + return -EIO; + } + + if (build_key(code, cur_codes)) + return -EFAULT; + + if (soft_gap) { + if (!memcmp(prev_codes, cur_codes, code_bytes) && + jiffies < next_time) + return -EAGAIN; + + next_time = jiffies + soft_gap; + } + memcpy(prev_codes, cur_codes, code_bytes); + + lirc_buffer_write_1(buf, cur_codes); + + return SUCCESS; +} + +static int set_use_inc(void *data) +{ + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + MOD_DEC_USE_COUNT; +} + +static wait_queue_head_t *get_queue(void *data) +{ + return bttv_get_gpio_queue(card); +} + +static struct lirc_plugin plugin = { + .name = "lirc_gpio ", + .add_to_buf = add_to_buf, + .get_queue = get_queue, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .dev = NULL, + .owner = THIS_MODULE, +}; + +/* + * + */ +static int gpio_remote_init(void) +{ + int ret; + unsigned int mask; + + /* "normalize" gpio_mask + * this means shift it right until first bit is set + */ + while (!(gpio_mask & 1u)) { + gpio_pre_shift++; + gpio_mask >>= 1; + } + + if (code_length) + plugin.code_length = code_length; + else { + /* calculate scan code length in bits if needed */ + plugin.code_length = 1; + mask = gpio_mask >> 1; + while (mask) { + if (mask & 1u) + plugin.code_length++; + mask >>= 1; + } + } + + code_bytes = (plugin.code_length/8) + (plugin.code_length % 8 ? 1 : 0); + if (MAX_BYTES < code_bytes) { + printk(LOGHEAD "scan code too long (%d bytes)\n", + minor, code_bytes); + return -EBADRQC; + } + + if (gpio_enable) { + if (bttv_gpio_enable(card, gpio_enable, gpio_enable)) { + printk(LOGHEAD "gpio_enable failure\n", minor); + return -EIO; + } + } + + + /* translate ms to jiffies */ + soft_gap = (soft_gap*HZ) / 1000; + + plugin.minor = minor; + plugin.sample_rate = sample_rate; + + ret = lirc_register_plugin(&plugin); + + if (0 > ret) { + printk(LOGHEAD "device registration failed with %d\n", + minor, ret); + return ret; + } + + minor = ret; + printk(LOGHEAD "driver registered\n", minor); + + return SUCCESS; +} + +#ifdef MODULE +/* + * + */ +int init_module(void) +{ + int type, cardid, card_type; + + if (MAX_IRCTL_DEVICES < minor) { + printk(KERN_INFO "lirc_gpio: parameter minor (%d) " + "must be less than %d!\n", + minor, MAX_IRCTL_DEVICES - 1); + return -EBADRQC; + } + + request_module("bttv"); + + /* if gpio_mask not zero then use module parameters + * instead of autodetecting TV card + */ + if (gpio_mask) { + if (sample_rate != 0 && + (2 > sample_rate || HZ < sample_rate)) { + printk(LOGHEAD "parameter sample_rate " + "must be between 2 and %d!\n", minor, HZ); + return -EBADRQC; + } + + if (sample_rate != 0 && soft_gap && + ((2000/sample_rate) > soft_gap || 1000 < soft_gap)) { + printk(LOGHEAD "parameter soft_gap " + "must be between %d and 1000!\n", + minor, 2000/sample_rate); + return -EBADRQC; + } + } else { + if (bttv_get_cardinfo(card, &type, &cardid) == -1) { + printk(LOGHEAD "could not get card type\n", minor); + return -EBADRQC; + } + printk(LOGHEAD "card type 0x%x, id 0x%x\n", minor, + type, cardid); + + if (type == BTTV_BOARD_UNKNOWN) { + printk(LOGHEAD "cannot detect TV card nr %d!\n", + minor, card); + return -EBADRQC; + } + for (card_type = 1; + card_type < sizeof(rcv_infos)/sizeof(struct rcv_info); + card_type++) { + if (rcv_infos[card_type].bttv_id == type && + (rcv_infos[card_type].card_id == 0 || + rcv_infos[card_type].card_id == cardid)) { + bttv_id = rcv_infos[card_type].bttv_id; + gpio_mask = rcv_infos[card_type].gpio_mask; + gpio_enable = rcv_infos[card_type].gpio_enable; + gpio_lock_mask = + rcv_infos[card_type].gpio_lock_mask; + gpio_xor_mask = + rcv_infos[card_type].gpio_xor_mask; + soft_gap = rcv_infos[card_type].soft_gap; + sample_rate = rcv_infos[card_type].sample_rate; + code_length = rcv_infos[card_type].code_length; + break; + } + } + if (type == BTTV_BOARD_AVPHONE98 && cardid == 0x00011461) + bttv_id = BTTV_BOARD_AVERMEDIA98; + + if (type == BTTV_BOARD_AVERMEDIA98 && cardid == 0x00041461) + bttv_id = BTTV_BOARD_AVPHONE98; + + if (type == BTTV_BOARD_AVERMEDIA98 && cardid == 0x03001461) + bttv_id = BTTV_BOARD_AVPHONE98; + + if (type == BTTV_BOARD_AVERMEDIA98 && cardid == 0x00000000) + bttv_id = BTTV_BOARD_AVPHONE98; + + if (card_type == sizeof(rcv_infos)/sizeof(struct rcv_info)) { + printk(LOGHEAD "TV card type 0x%x not supported!\n", + minor, type); + return -EBADRQC; + } + } + + request_module("lirc_dev"); + + return gpio_remote_init(); +} + +/* + * + */ +void cleanup_module(void) +{ + lirc_unregister_plugin(minor); + + dprintk(LOGHEAD "module successfully unloaded\n", minor); +} + +/* Dont try to use it as a static version ! */ +MODULE_DESCRIPTION("Driver module for remote control (data " + "from bt848 GPIO port)"); +MODULE_AUTHOR("Artur Lipowski"); +MODULE_LICENSE("GPL"); + +module_param(minor, int, 0444); +MODULE_PARM_DESC(minor, "Preferred minor device number"); + +module_param(card, int, 0444); +MODULE_PARM_DESC(card, "TV card number to attach to"); + +module_param(gpio_mask, long, 0444); +MODULE_PARM_DESC(gpio_mask, "gpio_mask"); + +module_param(gpio_lock_mask, long, 0444); +MODULE_PARM_DESC(gpio_lock_mask, "gpio_lock_mask"); + +module_param(gpio_xor_mask, long, 0444); +MODULE_PARM_DESC(gpio_xor_mask, "gpio_xor_mask"); + +module_param(soft_gap, int, 0444); +MODULE_PARM_DESC(soft_gap, "Time between keypresses (in ms)"); + +module_param(sample_rate, int, 0444); +MODULE_PARM_DESC(sample_rate, "Sample rate (between 2 and HZ)"); + +module_param(bttv_id, int, 0444); +MODULE_PARM_DESC(bttv_id, "BTTV card type"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/bttv_deprecated.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/bttv_deprecated.h @@ -0,0 +1,6 @@ +//Temporarily re-added for Ubuntu Kernel 2.6.22 until upstream +//Resolution is reached. +extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card); +extern int bttv_get_cardinfo(unsigned int card, int *type, + unsigned int *cardid); + --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/bttv_deprecated.c +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/bttv_deprecated.c @@ -0,0 +1,44 @@ +//Temporarily added until a resolution is reached upstream +//For kernel 2.6.22 + +#include +#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,22) +#include "extra_2.6.22/bttv.h" +#include "extra_2.6.22/bttvp.h" +#else +#include "../drivers/media/video/bt8xx/bttv.h" +#include "../drivers/media/video/bt8xx/bttvp.h" +#endif + +struct bttv bttvs[BTTV_MAX]; +unsigned int bttv_debug; +unsigned int bttv_num; /* number of Bt848s in use */ + +int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid) +{ + printk("The bttv_* interface is obsolete and will go away,\n" + "please use the new, sysfs based interface instead.\n"); + if (card >= bttv_num) { + return -1; + } + *type = bttvs[card].c.type; + *cardid = bttvs[card].cardid; + return 0; +} + +wait_queue_head_t* bttv_get_gpio_queue(unsigned int card) +{ + struct bttv *btv; + + if (card >= bttv_num) { + return NULL; + } + + btv = &bttvs[card]; + if (bttvs[card].shutdown) { + return NULL; + } + return &btv->gpioq; +} + + --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/Makefile @@ -0,0 +1,4 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_GPIO) += lirc_gpio.o +lirc_gpio/lirc_gpio-objs += bttv_deprecated.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.16/bttvp.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.16/bttvp.h @@ -0,0 +1,410 @@ +/* + + bttv - Bt848 frame grabber driver + + bttv's *private* header file -- nobody other than bttv itself + should ever include this file. + + (c) 2000-2002 Gerd Knorr + + 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. +*/ + +#ifndef _BTTVP_H_ +#define _BTTVP_H_ + +#include +#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +#include "bt848.h" +#include "bttv.h" +#include "btcx-risc.h" + +#ifdef __KERNEL__ + +#define FORMAT_FLAGS_DITHER 0x01 +#define FORMAT_FLAGS_PACKED 0x02 +#define FORMAT_FLAGS_PLANAR 0x04 +#define FORMAT_FLAGS_RAW 0x08 +#define FORMAT_FLAGS_CrCb 0x10 + +#define RISC_SLOT_O_VBI 4 +#define RISC_SLOT_O_FIELD 6 +#define RISC_SLOT_E_VBI 10 +#define RISC_SLOT_E_FIELD 12 +#define RISC_SLOT_LOOP 14 + +#define RESOURCE_OVERLAY 1 +#define RESOURCE_VIDEO 2 +#define RESOURCE_VBI 4 + +#define RAW_LINES 640 +#define RAW_BPL 1024 + +#define UNSET (-1U) + +#define clamp(x, low, high) min (max (low, x), high) + +/* ---------------------------------------------------------- */ + +struct bttv_tvnorm { + int v4l2_id; + char *name; + u32 Fsc; + u16 swidth, sheight; /* scaled standard width, height */ + u16 totalwidth; + u8 adelay, bdelay, iform; + u32 scaledtwidth; + u16 hdelayx1, hactivex1; + u16 vdelay; + u8 vbipack; + u16 vtotal; + int sram; + /* ITU-R frame line number of the first VBI line we can + capture, of the first and second field. */ + u16 vbistart[2]; +}; +extern const struct bttv_tvnorm bttv_tvnorms[]; + +struct bttv_format { + char *name; + int palette; /* video4linux 1 */ + int fourcc; /* video4linux 2 */ + int btformat; /* BT848_COLOR_FMT_* */ + int btswap; /* BT848_COLOR_CTL_* */ + int depth; /* bit/pixel */ + int flags; + int hshift,vshift; /* for planar modes */ +}; + +/* ---------------------------------------------------------- */ + +struct bttv_geometry { + u8 vtc,crop,comb; + u16 width,hscale,hdelay; + u16 sheight,vscale,vdelay,vtotal; +}; + +struct bttv_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + /* bttv specific */ + const struct bttv_format *fmt; + int tvnorm; + int btformat; + int btswap; + struct bttv_geometry geo; + struct btcx_riscmem top; + struct btcx_riscmem bottom; +}; + +struct bttv_buffer_set { + struct bttv_buffer *top; /* top field buffer */ + struct bttv_buffer *bottom; /* bottom field buffer */ + unsigned int top_irq; + unsigned int frame_irq; +}; + +struct bttv_overlay { + int tvnorm; + struct v4l2_rect w; + enum v4l2_field field; + struct v4l2_clip *clips; + int nclips; + int setup_ok; +}; + +struct bttv_fh { + struct bttv *btv; + int resources; +#ifdef VIDIOC_G_PRIORITY + enum v4l2_priority prio; +#endif + enum v4l2_buf_type type; + + /* video capture */ + struct videobuf_queue cap; + const struct bttv_format *fmt; + int width; + int height; + + /* current settings */ + const struct bttv_format *ovfmt; + struct bttv_overlay ov; + + /* video overlay */ + struct videobuf_queue vbi; + int lines; +}; + +/* ---------------------------------------------------------- */ +/* bttv-risc.c */ + +/* risc code generators - capture */ +int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, + struct scatterlist *sglist, + unsigned int offset, unsigned int bpl, + unsigned int pitch, unsigned int lines); + +/* control dma register + risc main loop */ +void bttv_set_dma(struct bttv *btv, int override); +int bttv_risc_init_main(struct bttv *btv); +int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, + int irqflags); + +/* capture buffer handling */ +int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf); +int bttv_buffer_activate_video(struct bttv *btv, + struct bttv_buffer_set *set); +int bttv_buffer_activate_vbi(struct bttv *btv, + struct bttv_buffer *vbi); +void bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf); + +/* overlay handling */ +int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, + const struct bttv_format *fmt, + struct bttv_buffer *buf); + + +/* ---------------------------------------------------------- */ +/* bttv-vbi.c */ + +void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines); + +extern struct videobuf_queue_ops bttv_vbi_qops; + +/* ---------------------------------------------------------- */ +/* bttv-gpio.c */ + + +extern struct bus_type bttv_sub_bus_type; +int bttv_sub_add_device(struct bttv_core *core, char *name); +int bttv_sub_del_devices(struct bttv_core *core); +void bttv_gpio_irq(struct bttv_core *core); + + +/* ---------------------------------------------------------- */ +/* bttv-driver.c */ + +/* insmod options */ +extern unsigned int bttv_verbose; +extern unsigned int bttv_debug; +extern unsigned int bttv_gpio; +extern void bttv_gpio_tracking(struct bttv *btv, char *comment); +extern int init_bttv_i2c(struct bttv *btv); +extern int fini_bttv_i2c(struct bttv *btv); + +#define bttv_printk if (bttv_verbose) printk +#define dprintk if (bttv_debug >= 1) printk +#define d2printk if (bttv_debug >= 2) printk + +#define BTTV_MAX_FBUF 0x208000 +#define VBIBUF_SIZE (2048*VBI_MAXLINES*2) +#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ +#define BTTV_FREE_IDLE (HZ) /* one second */ + + +struct bttv_pll_info { + unsigned int pll_ifreq; /* PLL input frequency */ + unsigned int pll_ofreq; /* PLL output frequency */ + unsigned int pll_crystal; /* Crystal used for input */ + unsigned int pll_current; /* Currently programmed ofreq */ +}; + +/* for gpio-connected remote control */ +struct bttv_input { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + u32 mask_keycode; + u32 mask_keydown; +}; + +struct bttv_suspend_state { + u32 gpio_enable; + u32 gpio_data; + int disabled; + int loop_irq; + struct bttv_buffer_set video; + struct bttv_buffer *vbi; +}; + +struct bttv { + struct bttv_core c; + + /* pci device config */ + unsigned short id; + unsigned char revision; + unsigned char __iomem *bt848_mmio; /* pointer to mmio */ + + /* card configuration info */ + unsigned int cardid; /* pci subsystem id (bt878 based ones) */ + unsigned int tuner_type; /* tuner chip type */ + unsigned int tda9887_conf; + unsigned int svhs; + struct bttv_pll_info pll; + int triton1; + int gpioirq; + int (*custom_irq)(struct bttv *btv); + + int use_i2c_hw; + + /* old gpio interface */ + wait_queue_head_t gpioq; + int shutdown; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + + /* new gpio interface */ + spinlock_t gpio_lock; + + /* i2c layer */ + struct i2c_algo_bit_data i2c_algo; + struct i2c_client i2c_client; + int i2c_state, i2c_rc; + int i2c_done; + wait_queue_head_t i2c_queue; + + /* video4linux (1) */ + struct video_device *video_dev; + struct video_device *radio_dev; + struct video_device *vbi_dev; + + /* infrared remote */ + int has_remote; + struct bttv_ir *remote; + + /* locking */ + spinlock_t s_lock; + struct mutex lock; + int resources; + struct mutex reslock; +#ifdef VIDIOC_G_PRIORITY + struct v4l2_prio_state prio; +#endif + + /* video state */ + unsigned int input; + unsigned int audio; + unsigned long freq; + int tvnorm,hue,contrast,bright,saturation; + struct v4l2_framebuffer fbuf; + unsigned int field_count; + + /* various options */ + int opt_combfilter; + int opt_lumafilter; + int opt_automute; + int opt_chroma_agc; + int opt_adc_crush; + int opt_vcr_hack; + int opt_whitecrush_upper; + int opt_whitecrush_lower; + int opt_uv_ratio; + int opt_full_luma_range; + int opt_coring; + + /* radio data/state */ + int has_radio; + int radio_user; + + /* miro/pinnacle + Aimslab VHX + philips matchbox (tea5757 radio tuner) support */ + int has_matchbox; + int mbox_we; + int mbox_data; + int mbox_clk; + int mbox_most; + int mbox_mask; + + /* ISA stuff (Terratec Active Radio Upgrade) */ + int mbox_ior; + int mbox_iow; + int mbox_csel; + + /* risc memory management data + - must aquire s_lock before changing these + - only the irq handler is supported to touch top + bottom + vcurr */ + struct btcx_riscmem main; + struct bttv_buffer *screen; /* overlay */ + struct list_head capture; /* video capture queue */ + struct list_head vcapture; /* vbi capture queue */ + struct bttv_buffer_set curr; /* active buffers */ + struct bttv_buffer *cvbi; /* active vbi buffer */ + int loop_irq; + int new_input; + + unsigned long cap_ctl; + unsigned long dma_on; + struct timer_list timeout; + struct bttv_suspend_state state; + + /* stats */ + unsigned int errors; + unsigned int framedrop; + unsigned int irq_total; + unsigned int irq_me; + + unsigned int users; + struct bttv_fh init; +}; + +/* our devices */ +#define BTTV_MAX 16 +extern unsigned int bttv_num; +extern struct bttv bttvs[BTTV_MAX]; + +/* private ioctls */ +#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int) +#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int) + +#endif + +#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) +#define btread(adr) readl(btv->bt848_mmio+(adr)) + +#define btand(dat,adr) btwrite((dat) & btread(adr), adr) +#define btor(dat,adr) btwrite((dat) | btread(adr), adr) +#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) + +#endif /* _BTTVP_H_ */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.16/bttv.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.16/bttv.h @@ -0,0 +1,407 @@ +/* + * + * bttv - Bt848 frame grabber driver + * + * card ID's and external interfaces of the bttv driver + * basically stuff needed by other drivers (i2c, lirc, ...) + * and is supported not to change much over time. + * + * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de) + * (c) 1999,2000 Gerd Knorr + * + */ + +#ifndef _BTTV_H_ +#define _BTTV_H_ + +#include +#include +#include +#include + +/* ---------------------------------------------------------- */ +/* exported by bttv-cards.c */ + +#define BTTV_BOARD_UNKNOWN 0x00 +#define BTTV_BOARD_MIRO 0x01 +#define BTTV_BOARD_HAUPPAUGE 0x02 +#define BTTV_BOARD_STB 0x03 +#define BTTV_BOARD_INTEL 0x04 +#define BTTV_BOARD_DIAMOND 0x05 +#define BTTV_BOARD_AVERMEDIA 0x06 +#define BTTV_BOARD_MATRIX_VISION 0x07 +#define BTTV_BOARD_FLYVIDEO 0x08 +#define BTTV_BOARD_TURBOTV 0x09 +#define BTTV_BOARD_HAUPPAUGE878 0x0a +#define BTTV_BOARD_MIROPRO 0x0b +#define BTTV_BOARD_ADSTECH_TV 0x0c +#define BTTV_BOARD_AVERMEDIA98 0x0d +#define BTTV_BOARD_VHX 0x0e +#define BTTV_BOARD_ZOLTRIX 0x0f +#define BTTV_BOARD_PIXVIEWPLAYTV 0x10 +#define BTTV_BOARD_WINVIEW_601 0x11 +#define BTTV_BOARD_AVEC_INTERCAP 0x12 +#define BTTV_BOARD_LIFE_FLYKIT 0x13 +#define BTTV_BOARD_CEI_RAFFLES 0x14 +#define BTTV_BOARD_CONFERENCETV 0x15 +#define BTTV_BOARD_PHOEBE_TVMAS 0x16 +#define BTTV_BOARD_MODTEC_205 0x17 +#define BTTV_BOARD_MAGICTVIEW061 0x18 +#define BTTV_BOARD_VOBIS_BOOSTAR 0x19 +#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a +#define BTTV_BOARD_MAXI 0x1b +#define BTTV_BOARD_TERRATV 0x1c +#define BTTV_BOARD_PXC200 0x1d +#define BTTV_BOARD_FLYVIDEO_98 0x1e +#define BTTV_BOARD_IPROTV 0x1f +#define BTTV_BOARD_INTEL_C_S_PCI 0x20 +#define BTTV_BOARD_TERRATVALUE 0x21 +#define BTTV_BOARD_WINFAST2000 0x22 +#define BTTV_BOARD_CHRONOS_VS2 0x23 +#define BTTV_BOARD_TYPHOON_TVIEW 0x24 +#define BTTV_BOARD_PXELVWPLTVPRO 0x25 +#define BTTV_BOARD_MAGICTVIEW063 0x26 +#define BTTV_BOARD_PINNACLE 0x27 +#define BTTV_BOARD_STB2 0x28 +#define BTTV_BOARD_AVPHONE98 0x29 +#define BTTV_BOARD_PV951 0x2a +#define BTTV_BOARD_ONAIR_TV 0x2b +#define BTTV_BOARD_SIGMA_TVII_FM 0x2c +#define BTTV_BOARD_MATRIX_VISION2 0x2d +#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e +#define BTTV_BOARD_TERRATVRADIO 0x2f +#define BTTV_BOARD_DYNALINK 0x30 +#define BTTV_BOARD_GVBCTV3PCI 0x31 +#define BTTV_BOARD_PXELVWPLTVPAK 0x32 +#define BTTV_BOARD_EAGLE 0x33 +#define BTTV_BOARD_PINNACLEPRO 0x34 +#define BTTV_BOARD_TVIEW_RDS_FM 0x35 +#define BTTV_BOARD_LIFETEC_9415 0x36 +#define BTTV_BOARD_BESTBUY_EASYTV 0x37 +#define BTTV_BOARD_FLYVIDEO_98FM 0x38 +#define BTTV_BOARD_GRANDTEC 0x39 +#define BTTV_BOARD_ASKEY_CPH060 0x3a +#define BTTV_BOARD_ASKEY_CPH03X 0x3b +#define BTTV_BOARD_MM100PCTV 0x3c +#define BTTV_BOARD_GMV1 0x3d +#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e +#define BTTV_BOARD_ATI_TVWONDER 0x3f +#define BTTV_BOARD_ATI_TVWONDERVE 0x40 +#define BTTV_BOARD_FLYVIDEO2000 0x41 +#define BTTV_BOARD_TERRATVALUER 0x42 +#define BTTV_BOARD_GVBCTV4PCI 0x43 +#define BTTV_BOARD_VOODOOTV_FM 0x44 +#define BTTV_BOARD_AIMMS 0x45 +#define BTTV_BOARD_PV_BT878P_PLUS 0x46 +#define BTTV_BOARD_FLYVIDEO98EZ 0x47 +#define BTTV_BOARD_PV_BT878P_9B 0x48 +#define BTTV_BOARD_SENSORAY311 0x49 +#define BTTV_BOARD_RV605 0x4a +#define BTTV_BOARD_POWERCLR_MTV878 0x4b +#define BTTV_BOARD_WINDVR 0x4c +#define BTTV_BOARD_GRANDTEC_MULTI 0x4d +#define BTTV_BOARD_KWORLD 0x4e +#define BTTV_BOARD_DSP_TCVIDEO 0x4f +#define BTTV_BOARD_HAUPPAUGEPVR 0x50 +#define BTTV_BOARD_GVBCTV5PCI 0x51 +#define BTTV_BOARD_OSPREY1x0 0x52 +#define BTTV_BOARD_OSPREY1x0_848 0x53 +#define BTTV_BOARD_OSPREY101_848 0x54 +#define BTTV_BOARD_OSPREY1x1 0x55 +#define BTTV_BOARD_OSPREY1x1_SVID 0x56 +#define BTTV_BOARD_OSPREY2xx 0x57 +#define BTTV_BOARD_OSPREY2x0_SVID 0x58 +#define BTTV_BOARD_OSPREY2x0 0x59 +#define BTTV_BOARD_OSPREY500 0x5a +#define BTTV_BOARD_OSPREY540 0x5b +#define BTTV_BOARD_OSPREY2000 0x5c +#define BTTV_BOARD_IDS_EAGLE 0x5d +#define BTTV_BOARD_PINNACLESAT 0x5e +#define BTTV_BOARD_FORMAC_PROTV 0x5f +#define BTTV_BOARD_MACHTV 0x60 +#define BTTV_BOARD_EURESYS_PICOLO 0x61 +#define BTTV_BOARD_PV150 0x62 +#define BTTV_BOARD_AD_TVK503 0x63 +#define BTTV_BOARD_HERCULES_SM_TV 0x64 +#define BTTV_BOARD_PACETV 0x65 +#define BTTV_BOARD_IVC200 0x66 +#define BTTV_BOARD_XGUARD 0x67 +#define BTTV_BOARD_NEBULA_DIGITV 0x68 +#define BTTV_BOARD_PV143 0x69 +#define BTTV_BOARD_VD009X1_MINIDIN 0x6a +#define BTTV_BOARD_VD009X1_COMBI 0x6b +#define BTTV_BOARD_VD009_MINIDIN 0x6c +#define BTTV_BOARD_VD009_COMBI 0x6d +#define BTTV_BOARD_IVC100 0x6e +#define BTTV_BOARD_IVC120 0x6f +#define BTTV_BOARD_PC_HDTV 0x70 +#define BTTV_BOARD_TWINHAN_DST 0x71 +#define BTTV_BOARD_WINFASTVC100 0x72 +#define BTTV_BOARD_TEV560 0x73 +#define BTTV_BOARD_SIMUS_GVC1100 0x74 +#define BTTV_BOARD_NGSTV_PLUS 0x75 +#define BTTV_BOARD_LMLBT4 0x76 +#define BTTV_BOARD_TEKRAM_M205 0x77 +#define BTTV_BOARD_CONTVFMI 0x78 +#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 +#define BTTV_BOARD_SPIRIT_TV 0x7a +#define BTTV_BOARD_AVDVBT_771 0x7b +#define BTTV_BOARD_AVDVBT_761 0x7c +#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d +#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e +#define BTTV_BOARD_APAC_VIEWCOMP 0x7f +#define BTTV_BOARD_DVICO_DVBT_LITE 0x80 +#define BTTV_BOARD_VGEAR_MYVCD 0x81 +#define BTTV_BOARD_SUPER_TV 0x82 +#define BTTV_BOARD_TIBET_CS16 0x83 +#define BTTV_BOARD_KODICOM_4400R 0x84 +#define BTTV_BOARD_KODICOM_4400R_SL 0x85 +#define BTTV_BOARD_ADLINK_RTV24 0x86 +#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 +#define BTTV_BOARD_ACORP_Y878F 0x88 +#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89 +#define BTTV_BOARD_PV_BT878P_2E 0x8a +#define BTTV_BOARD_PV_M4900 0x8b +#define BTTV_BOARD_OSPREY440 0x8c +#define BTTV_BOARD_ASOUND_SKYEYE 0x8d +#define BTTV_BOARD_SABRENT_TVFM 0x8e +#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f +#define BTTV_BOARD_MACHTV_MAGICTV 0x90 + +/* i2c address list */ +#define I2C_TSA5522 0xc2 +#define I2C_TDA7432 0x8a +#define I2C_BT832_ALT1 0x88 +#define I2C_BT832_ALT2 0x8a // alternate setting +#define I2C_TDA8425 0x82 +#define I2C_TDA9840 0x84 +#define I2C_TDA9850 0xb6 /* also used by 9855,9873 */ +#define I2C_TDA9874 0xb0 /* also used by 9875 */ +#define I2C_TDA9875 0xb0 +#define I2C_HAUPEE 0xa0 +#define I2C_STBEE 0xae +#define I2C_VHX 0xc0 +#define I2C_MSP3400 0x80 +#define I2C_MSP3400_ALT 0x88 +#define I2C_TEA6300 0x80 /* also used by 6320 */ +#define I2C_DPL3518 0x84 +#define I2C_TDA9887 0x86 + +/* more card-specific defines */ +#define PT2254_L_CHANNEL 0x10 +#define PT2254_R_CHANNEL 0x08 +#define PT2254_DBS_IN_2 0x400 +#define PT2254_DBS_IN_10 0x20000 +#define WINVIEW_PT2254_CLK 0x40 +#define WINVIEW_PT2254_DATA 0x20 +#define WINVIEW_PT2254_STROBE 0x80 + +/* digital_mode */ +#define DIGITAL_MODE_VIDEO 1 +#define DIGITAL_MODE_CAMERA 2 + +struct bttv_core { + /* device structs */ + struct pci_dev *pci; + struct i2c_adapter i2c_adap; + struct list_head subs; /* struct bttv_sub_device */ + + /* device config */ + unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ + unsigned int type; /* card type (pointer into tvcards[]) */ + char name[8]; /* dev name */ +}; + +struct bttv; + + +struct bttv_ir { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + + /* Usual gpio signalling */ + + u32 mask_keycode; + u32 mask_keydown; + u32 mask_keyup; + u32 polling; + u32 last_gpio; + struct work_struct work; + struct timer_list timer; + + /* RC5 gpio */ + u32 rc5_gpio; + struct timer_list timer_end; /* timer_end for code completion */ + struct timer_list timer_keyup; /* timer_end for key release */ + u32 last_rc5; /* last good rc5 code */ + u32 last_bit; /* last raw bit seen */ + u32 code; /* raw code under construction */ + struct timeval base_time; /* time of last seen code */ + int active; /* building raw code */ +}; + +struct tvcard +{ + char *name; + unsigned int video_inputs; + unsigned int audio_inputs; + unsigned int tuner; + unsigned int svhs; + unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO + u32 gpiomask; + u32 muxsel[16]; + u32 audiomux[6]; /* Tuner, Radio, external, internal, mute, stereo */ + u32 gpiomask2; /* GPIO MUX mask */ + + /* i2c audio flags */ + unsigned int no_msp34xx:1; + unsigned int no_tda9875:1; + unsigned int no_tda7432:1; + unsigned int needs_tvaudio:1; + unsigned int msp34xx_alt:1; + + /* flag: video pci function is unused */ + unsigned int no_video:1; + unsigned int has_dvb:1; + unsigned int has_remote:1; + unsigned int no_gpioirq:1; + + /* other settings */ + unsigned int pll; +#define PLL_NONE 0 +#define PLL_28 1 +#define PLL_35 2 + + unsigned int tuner_type; + unsigned int tuner_addr; + unsigned int radio_addr; + + unsigned int has_radio; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + void (*muxsel_hook)(struct bttv *btv, unsigned int input); +}; + +extern struct tvcard bttv_tvcards[]; + +/* identification / initialization of the card */ +extern void bttv_idcard(struct bttv *btv); +extern void bttv_init_card1(struct bttv *btv); +extern void bttv_init_card2(struct bttv *btv); + +/* card-specific funtions */ +extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); +extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); + +/* extra tweaks for some chipsets */ +extern void bttv_check_chipset(void); +extern int bttv_handle_chipset(struct bttv *btv); + +/* ---------------------------------------------------------- */ +/* exported by bttv-if.c */ + +/* this obsolete -- please use the sysfs-based + interface below for new code */ + +/* returns card type + card ID (for bt878-based ones) + for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN + returns negative value if error occurred +*/ +extern int bttv_get_cardinfo(unsigned int card, int *type, + unsigned int *cardid); +extern struct pci_dev* bttv_get_pcidev(unsigned int card); + +/* obsolete, use bttv_get_cardinfo instead */ +extern int bttv_get_id(unsigned int card); + +/* sets GPOE register (BT848_GPIO_OUT_EN) to new value: + data | (current_GPOE_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_gpio_enable(unsigned int card, + unsigned long mask, unsigned long data); + +/* fills data with GPDATA register contents + returns negative value if error occurred +*/ +extern int bttv_read_gpio(unsigned int card, unsigned long *data); + +/* sets GPDATA register to new value: + (data & mask) | (current_GPDATA_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_write_gpio(unsigned int card, + unsigned long mask, unsigned long data); + +/* returns pointer to task queue which can be used as parameter to + interruptible_sleep_on + in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated + (wake_up_interruptible) and following call to the function bttv_read_gpio + should return new value of GPDATA, + returns NULL value if error occurred or queue is not available + WARNING: because there is no buffer for GPIO data, one MUST + process data ASAP +*/ +extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card); + +/* call i2c clients +*/ +extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg); + + + +/* ---------------------------------------------------------- */ +/* sysfs/driver-moded based gpio access interface */ + + +struct bttv_sub_device { + struct device dev; + struct bttv_core *core; + struct list_head list; +}; +#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev) + +struct bttv_sub_driver { + struct device_driver drv; + char wanted[BUS_ID_SIZE]; + int (*probe)(struct bttv_sub_device *sub); + void (*remove)(struct bttv_sub_device *sub); + void (*gpio_irq)(struct bttv_sub_device *sub); +}; +#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) + +int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); +int bttv_sub_unregister(struct bttv_sub_driver *drv); + +/* gpio access functions */ +void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits); +u32 bttv_gpio_read(struct bttv_core *core); +void bttv_gpio_write(struct bttv_core *core, u32 value); +void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); + +#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits) +#define gpio_read() bttv_gpio_read(&btv->c) +#define gpio_write(value) bttv_gpio_write(&btv->c, value) +#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) + + +/* ---------------------------------------------------------- */ +/* i2c */ + +extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); +extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); +extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, + unsigned char b2, int both); +extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); + +extern int bttv_input_init(struct bttv *dev); +extern void bttv_input_fini(struct bttv *dev); +extern void bttv_input_irq(struct bttv *dev); + +#endif /* _BTTV_H_ */ +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.16/bt848.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.16/bt848.h @@ -0,0 +1,366 @@ +/* + bt848.h - Bt848 register offsets + + Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + + 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. +*/ + +#ifndef _BT848_H_ +#define _BT848_H_ + +#ifndef PCI_VENDOR_ID_BROOKTREE +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#endif +#ifndef PCI_DEVICE_ID_BT848 +#define PCI_DEVICE_ID_BT848 0x350 +#endif +#ifndef PCI_DEVICE_ID_BT849 +#define PCI_DEVICE_ID_BT849 0x351 +#endif +#ifndef PCI_DEVICE_ID_BT878 +#define PCI_DEVICE_ID_BT878 0x36e +#endif +#ifndef PCI_DEVICE_ID_BT879 +#define PCI_DEVICE_ID_BT879 0x36f +#endif + + +/* Brooktree 848 registers */ + +#define BT848_DSTATUS 0x000 +#define BT848_DSTATUS_PRES (1<<7) +#define BT848_DSTATUS_HLOC (1<<6) +#define BT848_DSTATUS_FIELD (1<<5) +#define BT848_DSTATUS_NUML (1<<4) +#define BT848_DSTATUS_CSEL (1<<3) +#define BT848_DSTATUS_PLOCK (1<<2) +#define BT848_DSTATUS_LOF (1<<1) +#define BT848_DSTATUS_COF (1<<0) + +#define BT848_IFORM 0x004 +#define BT848_IFORM_HACTIVE (1<<7) +#define BT848_IFORM_MUXSEL (3<<5) +#define BT848_IFORM_MUX0 (2<<5) +#define BT848_IFORM_MUX1 (3<<5) +#define BT848_IFORM_MUX2 (1<<5) +#define BT848_IFORM_XTSEL (3<<3) +#define BT848_IFORM_XT0 (1<<3) +#define BT848_IFORM_XT1 (2<<3) +#define BT848_IFORM_XTAUTO (3<<3) +#define BT848_IFORM_XTBOTH (3<<3) +#define BT848_IFORM_NTSC 1 +#define BT848_IFORM_NTSC_J 2 +#define BT848_IFORM_PAL_BDGHI 3 +#define BT848_IFORM_PAL_M 4 +#define BT848_IFORM_PAL_N 5 +#define BT848_IFORM_SECAM 6 +#define BT848_IFORM_PAL_NC 7 +#define BT848_IFORM_AUTO 0 +#define BT848_IFORM_NORM 7 + +#define BT848_TDEC 0x008 +#define BT848_TDEC_DEC_FIELD (1<<7) +#define BT848_TDEC_FLDALIGN (1<<6) +#define BT848_TDEC_DEC_RAT (0x1f) + +#define BT848_E_CROP 0x00C +#define BT848_O_CROP 0x08C + +#define BT848_E_VDELAY_LO 0x010 +#define BT848_O_VDELAY_LO 0x090 + +#define BT848_E_VACTIVE_LO 0x014 +#define BT848_O_VACTIVE_LO 0x094 + +#define BT848_E_HDELAY_LO 0x018 +#define BT848_O_HDELAY_LO 0x098 + +#define BT848_E_HACTIVE_LO 0x01C +#define BT848_O_HACTIVE_LO 0x09C + +#define BT848_E_HSCALE_HI 0x020 +#define BT848_O_HSCALE_HI 0x0A0 + +#define BT848_E_HSCALE_LO 0x024 +#define BT848_O_HSCALE_LO 0x0A4 + +#define BT848_BRIGHT 0x028 + +#define BT848_E_CONTROL 0x02C +#define BT848_O_CONTROL 0x0AC +#define BT848_CONTROL_LNOTCH (1<<7) +#define BT848_CONTROL_COMP (1<<6) +#define BT848_CONTROL_LDEC (1<<5) +#define BT848_CONTROL_CBSENSE (1<<4) +#define BT848_CONTROL_CON_MSB (1<<2) +#define BT848_CONTROL_SAT_U_MSB (1<<1) +#define BT848_CONTROL_SAT_V_MSB (1<<0) + +#define BT848_CONTRAST_LO 0x030 +#define BT848_SAT_U_LO 0x034 +#define BT848_SAT_V_LO 0x038 +#define BT848_HUE 0x03C + +#define BT848_E_SCLOOP 0x040 +#define BT848_O_SCLOOP 0x0C0 +#define BT848_SCLOOP_CAGC (1<<6) +#define BT848_SCLOOP_CKILL (1<<5) +#define BT848_SCLOOP_HFILT_AUTO (0<<3) +#define BT848_SCLOOP_HFILT_CIF (1<<3) +#define BT848_SCLOOP_HFILT_QCIF (2<<3) +#define BT848_SCLOOP_HFILT_ICON (3<<3) + +#define BT848_SCLOOP_PEAK (1<<7) +#define BT848_SCLOOP_HFILT_MINP (1<<3) +#define BT848_SCLOOP_HFILT_MEDP (2<<3) +#define BT848_SCLOOP_HFILT_MAXP (3<<3) + + +#define BT848_OFORM 0x048 +#define BT848_OFORM_RANGE (1<<7) +#define BT848_OFORM_CORE0 (0<<5) +#define BT848_OFORM_CORE8 (1<<5) +#define BT848_OFORM_CORE16 (2<<5) +#define BT848_OFORM_CORE32 (3<<5) + +#define BT848_E_VSCALE_HI 0x04C +#define BT848_O_VSCALE_HI 0x0CC +#define BT848_VSCALE_YCOMB (1<<7) +#define BT848_VSCALE_COMB (1<<6) +#define BT848_VSCALE_INT (1<<5) +#define BT848_VSCALE_HI 15 + +#define BT848_E_VSCALE_LO 0x050 +#define BT848_O_VSCALE_LO 0x0D0 +#define BT848_TEST 0x054 +#define BT848_ADELAY 0x060 +#define BT848_BDELAY 0x064 + +#define BT848_ADC 0x068 +#define BT848_ADC_RESERVED (2<<6) +#define BT848_ADC_SYNC_T (1<<5) +#define BT848_ADC_AGC_EN (1<<4) +#define BT848_ADC_CLK_SLEEP (1<<3) +#define BT848_ADC_Y_SLEEP (1<<2) +#define BT848_ADC_C_SLEEP (1<<1) +#define BT848_ADC_CRUSH (1<<0) + +#define BT848_WC_UP 0x044 +#define BT848_WC_DOWN 0x078 + +#define BT848_E_VTC 0x06C +#define BT848_O_VTC 0x0EC +#define BT848_VTC_HSFMT (1<<7) +#define BT848_VTC_VFILT_2TAP 0 +#define BT848_VTC_VFILT_3TAP 1 +#define BT848_VTC_VFILT_4TAP 2 +#define BT848_VTC_VFILT_5TAP 3 + +#define BT848_SRESET 0x07C + +#define BT848_COLOR_FMT 0x0D4 +#define BT848_COLOR_FMT_O_RGB32 (0<<4) +#define BT848_COLOR_FMT_O_RGB24 (1<<4) +#define BT848_COLOR_FMT_O_RGB16 (2<<4) +#define BT848_COLOR_FMT_O_RGB15 (3<<4) +#define BT848_COLOR_FMT_O_YUY2 (4<<4) +#define BT848_COLOR_FMT_O_BtYUV (5<<4) +#define BT848_COLOR_FMT_O_Y8 (6<<4) +#define BT848_COLOR_FMT_O_RGB8 (7<<4) +#define BT848_COLOR_FMT_O_YCrCb422 (8<<4) +#define BT848_COLOR_FMT_O_YCrCb411 (9<<4) +#define BT848_COLOR_FMT_O_RAW (14<<4) +#define BT848_COLOR_FMT_E_RGB32 0 +#define BT848_COLOR_FMT_E_RGB24 1 +#define BT848_COLOR_FMT_E_RGB16 2 +#define BT848_COLOR_FMT_E_RGB15 3 +#define BT848_COLOR_FMT_E_YUY2 4 +#define BT848_COLOR_FMT_E_BtYUV 5 +#define BT848_COLOR_FMT_E_Y8 6 +#define BT848_COLOR_FMT_E_RGB8 7 +#define BT848_COLOR_FMT_E_YCrCb422 8 +#define BT848_COLOR_FMT_E_YCrCb411 9 +#define BT848_COLOR_FMT_E_RAW 14 + +#define BT848_COLOR_FMT_RGB32 0x00 +#define BT848_COLOR_FMT_RGB24 0x11 +#define BT848_COLOR_FMT_RGB16 0x22 +#define BT848_COLOR_FMT_RGB15 0x33 +#define BT848_COLOR_FMT_YUY2 0x44 +#define BT848_COLOR_FMT_BtYUV 0x55 +#define BT848_COLOR_FMT_Y8 0x66 +#define BT848_COLOR_FMT_RGB8 0x77 +#define BT848_COLOR_FMT_YCrCb422 0x88 +#define BT848_COLOR_FMT_YCrCb411 0x99 +#define BT848_COLOR_FMT_RAW 0xee + +#define BT848_VTOTAL_LO 0xB0 +#define BT848_VTOTAL_HI 0xB4 + +#define BT848_COLOR_CTL 0x0D8 +#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7) +#define BT848_COLOR_CTL_COLOR_BARS (1<<6) +#define BT848_COLOR_CTL_RGB_DED (1<<5) +#define BT848_COLOR_CTL_GAMMA (1<<4) +#define BT848_COLOR_CTL_WSWAP_ODD (1<<3) +#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2) +#define BT848_COLOR_CTL_BSWAP_ODD (1<<1) +#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0) + +#define BT848_CAP_CTL 0x0DC +#define BT848_CAP_CTL_DITH_FRAME (1<<4) +#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3) +#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2) +#define BT848_CAP_CTL_CAPTURE_ODD (1<<1) +#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0) + +#define BT848_VBI_PACK_SIZE 0x0E0 + +#define BT848_VBI_PACK_DEL 0x0E4 +#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc +#define BT848_VBI_PACK_DEL_EXT_FRAME 2 +#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1 + + +#define BT848_INT_STAT 0x100 +#define BT848_INT_MASK 0x104 + +#define BT848_INT_ETBF (1<<23) + +#define BT848_INT_RISCS (0xf<<28) +#define BT848_INT_RISC_EN (1<<27) +#define BT848_INT_RACK (1<<25) +#define BT848_INT_FIELD (1<<24) +#define BT848_INT_SCERR (1<<19) +#define BT848_INT_OCERR (1<<18) +#define BT848_INT_PABORT (1<<17) +#define BT848_INT_RIPERR (1<<16) +#define BT848_INT_PPERR (1<<15) +#define BT848_INT_FDSR (1<<14) +#define BT848_INT_FTRGT (1<<13) +#define BT848_INT_FBUS (1<<12) +#define BT848_INT_RISCI (1<<11) +#define BT848_INT_GPINT (1<<9) +#define BT848_INT_I2CDONE (1<<8) +#define BT848_INT_VPRES (1<<5) +#define BT848_INT_HLOCK (1<<4) +#define BT848_INT_OFLOW (1<<3) +#define BT848_INT_HSYNC (1<<2) +#define BT848_INT_VSYNC (1<<1) +#define BT848_INT_FMTCHG (1<<0) + + +#define BT848_GPIO_DMA_CTL 0x10C +#define BT848_GPIO_DMA_CTL_GPINTC (1<<15) +#define BT848_GPIO_DMA_CTL_GPINTI (1<<14) +#define BT848_GPIO_DMA_CTL_GPWEC (1<<13) +#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11) +#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10) +#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6) +#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4) +#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2) +#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2) +#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2) +#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2) +#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1) +#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0) + +#define BT848_I2C 0x110 +#define BT878_I2C_MODE (1<<7) +#define BT878_I2C_RATE (1<<6) +#define BT878_I2C_NOSTOP (1<<5) +#define BT878_I2C_NOSTART (1<<4) +#define BT848_I2C_DIV (0xf<<4) +#define BT848_I2C_SYNC (1<<3) +#define BT848_I2C_W3B (1<<2) +#define BT848_I2C_SCL (1<<1) +#define BT848_I2C_SDA (1<<0) + +#define BT848_RISC_STRT_ADD 0x114 +#define BT848_GPIO_OUT_EN 0x118 +#define BT848_GPIO_REG_INP 0x11C +#define BT848_RISC_COUNT 0x120 +#define BT848_GPIO_DATA 0x200 + + +/* Bt848 RISC commands */ + +/* only for the SYNC RISC command */ +#define BT848_FIFO_STATUS_FM1 0x06 +#define BT848_FIFO_STATUS_FM3 0x0e +#define BT848_FIFO_STATUS_SOL 0x02 +#define BT848_FIFO_STATUS_EOL4 0x01 +#define BT848_FIFO_STATUS_EOL3 0x0d +#define BT848_FIFO_STATUS_EOL2 0x09 +#define BT848_FIFO_STATUS_EOL1 0x05 +#define BT848_FIFO_STATUS_VRE 0x04 +#define BT848_FIFO_STATUS_VRO 0x0c +#define BT848_FIFO_STATUS_PXV 0x00 + +#define BT848_RISC_RESYNC (1<<15) + +/* WRITE and SKIP */ +/* disable which bytes of each DWORD */ +#define BT848_RISC_BYTE0 (1U<<12) +#define BT848_RISC_BYTE1 (1U<<13) +#define BT848_RISC_BYTE2 (1U<<14) +#define BT848_RISC_BYTE3 (1U<<15) +#define BT848_RISC_BYTE_ALL (0x0fU<<12) +#define BT848_RISC_BYTE_NONE 0 +/* cause RISCI */ +#define BT848_RISC_IRQ (1U<<24) +/* RISC command is last one in this line */ +#define BT848_RISC_EOL (1U<<26) +/* RISC command is first one in this line */ +#define BT848_RISC_SOL (1U<<27) + +#define BT848_RISC_WRITE (0x01U<<28) +#define BT848_RISC_SKIP (0x02U<<28) +#define BT848_RISC_WRITEC (0x05U<<28) +#define BT848_RISC_JUMP (0x07U<<28) +#define BT848_RISC_SYNC (0x08U<<28) + +#define BT848_RISC_WRITE123 (0x09U<<28) +#define BT848_RISC_SKIP123 (0x0aU<<28) +#define BT848_RISC_WRITE1S23 (0x0bU<<28) + + +/* Bt848A and higher only !! */ +#define BT848_TGLB 0x080 +#define BT848_TGCTRL 0x084 +#define BT848_FCAP 0x0E8 +#define BT848_PLL_F_LO 0x0F0 +#define BT848_PLL_F_HI 0x0F4 + +#define BT848_PLL_XCI 0x0F8 +#define BT848_PLL_X (1<<7) +#define BT848_PLL_C (1<<6) + +#define BT848_DVSIF 0x0FC + +/* Bt878 register */ + +#define BT878_DEVCTRL 0x40 +#define BT878_EN_TBFX 0x02 +#define BT878_EN_VSFX 0x04 + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.16/btcx-risc.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.16/btcx-risc.h @@ -0,0 +1,34 @@ +/* + */ +struct btcx_riscmem { + unsigned int size; + u32 *cpu; + u32 *jmp; + dma_addr_t dma; +}; + +struct btcx_skiplist { + int start; + int end; +}; + +int btcx_riscmem_alloc(struct pci_dev *pci, + struct btcx_riscmem *risc, + unsigned int size); +void btcx_riscmem_free(struct pci_dev *pci, + struct btcx_riscmem *risc); + +int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win, + struct v4l2_clip *clips, unsigned int n); +int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, + unsigned int n, int mask); +void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips); +void btcx_calc_skips(int line, int width, unsigned int *maxy, + struct btcx_skiplist *skips, unsigned int *nskips, + const struct v4l2_clip *clips, unsigned int nclips); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.20/bttvp.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.20/bttvp.h @@ -0,0 +1,413 @@ +/* + + bttv - Bt848 frame grabber driver + + bttv's *private* header file -- nobody other than bttv itself + should ever include this file. + + (c) 2000-2002 Gerd Knorr + + 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. +*/ + +#ifndef _BTTVP_H_ +#define _BTTVP_H_ + +#include +#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "bt848.h" +#include "bttv.h" +#include "btcx-risc.h" + +#ifdef __KERNEL__ + +#define FORMAT_FLAGS_DITHER 0x01 +#define FORMAT_FLAGS_PACKED 0x02 +#define FORMAT_FLAGS_PLANAR 0x04 +#define FORMAT_FLAGS_RAW 0x08 +#define FORMAT_FLAGS_CrCb 0x10 + +#define RISC_SLOT_O_VBI 4 +#define RISC_SLOT_O_FIELD 6 +#define RISC_SLOT_E_VBI 10 +#define RISC_SLOT_E_FIELD 12 +#define RISC_SLOT_LOOP 14 + +#define RESOURCE_OVERLAY 1 +#define RESOURCE_VIDEO 2 +#define RESOURCE_VBI 4 + +#define RAW_LINES 640 +#define RAW_BPL 1024 + +#define UNSET (-1U) + +#define clamp(x, low, high) min (max (low, x), high) + +/* ---------------------------------------------------------- */ + +struct bttv_tvnorm { + int v4l2_id; + char *name; + u32 Fsc; + u16 swidth, sheight; /* scaled standard width, height */ + u16 totalwidth; + u8 adelay, bdelay, iform; + u32 scaledtwidth; + u16 hdelayx1, hactivex1; + u16 vdelay; + u8 vbipack; + u16 vtotal; + int sram; + /* ITU-R frame line number of the first VBI line we can + capture, of the first and second field. */ + u16 vbistart[2]; +}; +extern const struct bttv_tvnorm bttv_tvnorms[]; + +struct bttv_format { + char *name; + int palette; /* video4linux 1 */ + int fourcc; /* video4linux 2 */ + int btformat; /* BT848_COLOR_FMT_* */ + int btswap; /* BT848_COLOR_CTL_* */ + int depth; /* bit/pixel */ + int flags; + int hshift,vshift; /* for planar modes */ +}; + +/* ---------------------------------------------------------- */ + +struct bttv_geometry { + u8 vtc,crop,comb; + u16 width,hscale,hdelay; + u16 sheight,vscale,vdelay,vtotal; +}; + +struct bttv_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + /* bttv specific */ + const struct bttv_format *fmt; + int tvnorm; + int btformat; + int btswap; + struct bttv_geometry geo; + struct btcx_riscmem top; + struct btcx_riscmem bottom; +}; + +struct bttv_buffer_set { + struct bttv_buffer *top; /* top field buffer */ + struct bttv_buffer *bottom; /* bottom field buffer */ + unsigned int top_irq; + unsigned int frame_irq; +}; + +struct bttv_overlay { + int tvnorm; + struct v4l2_rect w; + enum v4l2_field field; + struct v4l2_clip *clips; + int nclips; + int setup_ok; +}; + +struct bttv_fh { + struct bttv *btv; + int resources; +#ifdef VIDIOC_G_PRIORITY + enum v4l2_priority prio; +#endif + enum v4l2_buf_type type; + + /* video capture */ + struct videobuf_queue cap; + const struct bttv_format *fmt; + int width; + int height; + + /* current settings */ + const struct bttv_format *ovfmt; + struct bttv_overlay ov; + + /* video overlay */ + struct videobuf_queue vbi; + int lines; +}; + +/* ---------------------------------------------------------- */ +/* bttv-risc.c */ + +/* risc code generators - capture */ +int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, + struct scatterlist *sglist, + unsigned int offset, unsigned int bpl, + unsigned int pitch, unsigned int lines); + +/* control dma register + risc main loop */ +void bttv_set_dma(struct bttv *btv, int override); +int bttv_risc_init_main(struct bttv *btv); +int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, + int irqflags); + +/* capture buffer handling */ +int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf); +int bttv_buffer_activate_video(struct bttv *btv, + struct bttv_buffer_set *set); +int bttv_buffer_activate_vbi(struct bttv *btv, + struct bttv_buffer *vbi); +void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv, + struct bttv_buffer *buf); + +/* overlay handling */ +int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, + const struct bttv_format *fmt, + struct bttv_buffer *buf); + + +/* ---------------------------------------------------------- */ +/* bttv-vbi.c */ + +void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines); + +extern struct videobuf_queue_ops bttv_vbi_qops; + +/* ---------------------------------------------------------- */ +/* bttv-gpio.c */ + + +extern struct bus_type bttv_sub_bus_type; +int bttv_sub_add_device(struct bttv_core *core, char *name); +int bttv_sub_del_devices(struct bttv_core *core); + + +/* ---------------------------------------------------------- */ +/* bttv-driver.c */ + +/* insmod options */ +extern unsigned int bttv_verbose; +extern unsigned int bttv_debug; +extern unsigned int bttv_gpio; +extern void bttv_gpio_tracking(struct bttv *btv, char *comment); +extern int init_bttv_i2c(struct bttv *btv); +extern int fini_bttv_i2c(struct bttv *btv); + +#define bttv_printk if (bttv_verbose) printk +#define dprintk if (bttv_debug >= 1) printk +#define d2printk if (bttv_debug >= 2) printk + +#define BTTV_MAX_FBUF 0x208000 +#define VBIBUF_SIZE (2048*VBI_MAXLINES*2) +#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ +#define BTTV_FREE_IDLE (HZ) /* one second */ + + +struct bttv_pll_info { + unsigned int pll_ifreq; /* PLL input frequency */ + unsigned int pll_ofreq; /* PLL output frequency */ + unsigned int pll_crystal; /* Crystal used for input */ + unsigned int pll_current; /* Currently programmed ofreq */ +}; + +/* for gpio-connected remote control */ +struct bttv_input { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + u32 mask_keycode; + u32 mask_keydown; +}; + +struct bttv_suspend_state { + u32 gpio_enable; + u32 gpio_data; + int disabled; + int loop_irq; + struct bttv_buffer_set video; + struct bttv_buffer *vbi; +}; + +struct bttv { + struct bttv_core c; + + /* pci device config */ + unsigned short id; + unsigned char revision; + unsigned char __iomem *bt848_mmio; /* pointer to mmio */ + + /* card configuration info */ + unsigned int cardid; /* pci subsystem id (bt878 based ones) */ + unsigned int tuner_type; /* tuner chip type */ + unsigned int tda9887_conf; + unsigned int svhs; + struct bttv_pll_info pll; + int triton1; + int gpioirq; + int (*custom_irq)(struct bttv *btv); + + int use_i2c_hw; + + /* old gpio interface */ + wait_queue_head_t gpioq; + int shutdown; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + + /* new gpio interface */ + spinlock_t gpio_lock; + + /* i2c layer */ + struct i2c_algo_bit_data i2c_algo; + struct i2c_client i2c_client; + int i2c_state, i2c_rc; + int i2c_done; + wait_queue_head_t i2c_queue; + struct i2c_client *i2c_msp34xx_client; + struct i2c_client *i2c_tvaudio_client; + + /* video4linux (1) */ + struct video_device *video_dev; + struct video_device *radio_dev; + struct video_device *vbi_dev; + + /* infrared remote */ + int has_remote; + struct bttv_ir *remote; + + /* locking */ + spinlock_t s_lock; + struct mutex lock; + int resources; + struct mutex reslock; +#ifdef VIDIOC_G_PRIORITY + struct v4l2_prio_state prio; +#endif + + /* video state */ + unsigned int input; + unsigned int audio; + unsigned int mute; + unsigned long freq; + int tvnorm,hue,contrast,bright,saturation; + struct v4l2_framebuffer fbuf; + unsigned int field_count; + + /* various options */ + int opt_combfilter; + int opt_lumafilter; + int opt_automute; + int opt_chroma_agc; + int opt_adc_crush; + int opt_vcr_hack; + int opt_whitecrush_upper; + int opt_whitecrush_lower; + int opt_uv_ratio; + int opt_full_luma_range; + int opt_coring; + + /* radio data/state */ + int has_radio; + int radio_user; + + /* miro/pinnacle + Aimslab VHX + philips matchbox (tea5757 radio tuner) support */ + int has_matchbox; + int mbox_we; + int mbox_data; + int mbox_clk; + int mbox_most; + int mbox_mask; + + /* ISA stuff (Terratec Active Radio Upgrade) */ + int mbox_ior; + int mbox_iow; + int mbox_csel; + + /* risc memory management data + - must acquire s_lock before changing these + - only the irq handler is supported to touch top + bottom + vcurr */ + struct btcx_riscmem main; + struct bttv_buffer *screen; /* overlay */ + struct list_head capture; /* video capture queue */ + struct list_head vcapture; /* vbi capture queue */ + struct bttv_buffer_set curr; /* active buffers */ + struct bttv_buffer *cvbi; /* active vbi buffer */ + int loop_irq; + int new_input; + + unsigned long cap_ctl; + unsigned long dma_on; + struct timer_list timeout; + struct bttv_suspend_state state; + + /* stats */ + unsigned int errors; + unsigned int framedrop; + unsigned int irq_total; + unsigned int irq_me; + + unsigned int users; + struct bttv_fh init; +}; + +/* our devices */ +#define BTTV_MAX 16 +extern unsigned int bttv_num; +extern struct bttv bttvs[BTTV_MAX]; + +/* private ioctls */ +#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int) +#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int) + +#endif + +#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) +#define btread(adr) readl(btv->bt848_mmio+(adr)) + +#define btand(dat,adr) btwrite((dat) & btread(adr), adr) +#define btor(dat,adr) btwrite((dat) | btread(adr), adr) +#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) + +#endif /* _BTTVP_H_ */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.20/bttv.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.20/bttv.h @@ -0,0 +1,389 @@ +/* + * + * bttv - Bt848 frame grabber driver + * + * card ID's and external interfaces of the bttv driver + * basically stuff needed by other drivers (i2c, lirc, ...) + * and is supported not to change much over time. + * + * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de) + * (c) 1999,2000 Gerd Knorr + * + */ + +#ifndef _BTTV_H_ +#define _BTTV_H_ + +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------- */ +/* exported by bttv-cards.c */ + +#define BTTV_BOARD_UNKNOWN 0x00 +#define BTTV_BOARD_MIRO 0x01 +#define BTTV_BOARD_HAUPPAUGE 0x02 +#define BTTV_BOARD_STB 0x03 +#define BTTV_BOARD_INTEL 0x04 +#define BTTV_BOARD_DIAMOND 0x05 +#define BTTV_BOARD_AVERMEDIA 0x06 +#define BTTV_BOARD_MATRIX_VISION 0x07 +#define BTTV_BOARD_FLYVIDEO 0x08 +#define BTTV_BOARD_TURBOTV 0x09 +#define BTTV_BOARD_HAUPPAUGE878 0x0a +#define BTTV_BOARD_MIROPRO 0x0b +#define BTTV_BOARD_ADSTECH_TV 0x0c +#define BTTV_BOARD_AVERMEDIA98 0x0d +#define BTTV_BOARD_VHX 0x0e +#define BTTV_BOARD_ZOLTRIX 0x0f +#define BTTV_BOARD_PIXVIEWPLAYTV 0x10 +#define BTTV_BOARD_WINVIEW_601 0x11 +#define BTTV_BOARD_AVEC_INTERCAP 0x12 +#define BTTV_BOARD_LIFE_FLYKIT 0x13 +#define BTTV_BOARD_CEI_RAFFLES 0x14 +#define BTTV_BOARD_CONFERENCETV 0x15 +#define BTTV_BOARD_PHOEBE_TVMAS 0x16 +#define BTTV_BOARD_MODTEC_205 0x17 +#define BTTV_BOARD_MAGICTVIEW061 0x18 +#define BTTV_BOARD_VOBIS_BOOSTAR 0x19 +#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a +#define BTTV_BOARD_MAXI 0x1b +#define BTTV_BOARD_TERRATV 0x1c +#define BTTV_BOARD_PXC200 0x1d +#define BTTV_BOARD_FLYVIDEO_98 0x1e +#define BTTV_BOARD_IPROTV 0x1f +#define BTTV_BOARD_INTEL_C_S_PCI 0x20 +#define BTTV_BOARD_TERRATVALUE 0x21 +#define BTTV_BOARD_WINFAST2000 0x22 +#define BTTV_BOARD_CHRONOS_VS2 0x23 +#define BTTV_BOARD_TYPHOON_TVIEW 0x24 +#define BTTV_BOARD_PXELVWPLTVPRO 0x25 +#define BTTV_BOARD_MAGICTVIEW063 0x26 +#define BTTV_BOARD_PINNACLE 0x27 +#define BTTV_BOARD_STB2 0x28 +#define BTTV_BOARD_AVPHONE98 0x29 +#define BTTV_BOARD_PV951 0x2a +#define BTTV_BOARD_ONAIR_TV 0x2b +#define BTTV_BOARD_SIGMA_TVII_FM 0x2c +#define BTTV_BOARD_MATRIX_VISION2 0x2d +#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e +#define BTTV_BOARD_TERRATVRADIO 0x2f +#define BTTV_BOARD_DYNALINK 0x30 +#define BTTV_BOARD_GVBCTV3PCI 0x31 +#define BTTV_BOARD_PXELVWPLTVPAK 0x32 +#define BTTV_BOARD_EAGLE 0x33 +#define BTTV_BOARD_PINNACLEPRO 0x34 +#define BTTV_BOARD_TVIEW_RDS_FM 0x35 +#define BTTV_BOARD_LIFETEC_9415 0x36 +#define BTTV_BOARD_BESTBUY_EASYTV 0x37 +#define BTTV_BOARD_FLYVIDEO_98FM 0x38 +#define BTTV_BOARD_GRANDTEC 0x39 +#define BTTV_BOARD_ASKEY_CPH060 0x3a +#define BTTV_BOARD_ASKEY_CPH03X 0x3b +#define BTTV_BOARD_MM100PCTV 0x3c +#define BTTV_BOARD_GMV1 0x3d +#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e +#define BTTV_BOARD_ATI_TVWONDER 0x3f +#define BTTV_BOARD_ATI_TVWONDERVE 0x40 +#define BTTV_BOARD_FLYVIDEO2000 0x41 +#define BTTV_BOARD_TERRATVALUER 0x42 +#define BTTV_BOARD_GVBCTV4PCI 0x43 +#define BTTV_BOARD_VOODOOTV_FM 0x44 +#define BTTV_BOARD_AIMMS 0x45 +#define BTTV_BOARD_PV_BT878P_PLUS 0x46 +#define BTTV_BOARD_FLYVIDEO98EZ 0x47 +#define BTTV_BOARD_PV_BT878P_9B 0x48 +#define BTTV_BOARD_SENSORAY311 0x49 +#define BTTV_BOARD_RV605 0x4a +#define BTTV_BOARD_POWERCLR_MTV878 0x4b +#define BTTV_BOARD_WINDVR 0x4c +#define BTTV_BOARD_GRANDTEC_MULTI 0x4d +#define BTTV_BOARD_KWORLD 0x4e +#define BTTV_BOARD_DSP_TCVIDEO 0x4f +#define BTTV_BOARD_HAUPPAUGEPVR 0x50 +#define BTTV_BOARD_GVBCTV5PCI 0x51 +#define BTTV_BOARD_OSPREY1x0 0x52 +#define BTTV_BOARD_OSPREY1x0_848 0x53 +#define BTTV_BOARD_OSPREY101_848 0x54 +#define BTTV_BOARD_OSPREY1x1 0x55 +#define BTTV_BOARD_OSPREY1x1_SVID 0x56 +#define BTTV_BOARD_OSPREY2xx 0x57 +#define BTTV_BOARD_OSPREY2x0_SVID 0x58 +#define BTTV_BOARD_OSPREY2x0 0x59 +#define BTTV_BOARD_OSPREY500 0x5a +#define BTTV_BOARD_OSPREY540 0x5b +#define BTTV_BOARD_OSPREY2000 0x5c +#define BTTV_BOARD_IDS_EAGLE 0x5d +#define BTTV_BOARD_PINNACLESAT 0x5e +#define BTTV_BOARD_FORMAC_PROTV 0x5f +#define BTTV_BOARD_MACHTV 0x60 +#define BTTV_BOARD_EURESYS_PICOLO 0x61 +#define BTTV_BOARD_PV150 0x62 +#define BTTV_BOARD_AD_TVK503 0x63 +#define BTTV_BOARD_HERCULES_SM_TV 0x64 +#define BTTV_BOARD_PACETV 0x65 +#define BTTV_BOARD_IVC200 0x66 +#define BTTV_BOARD_XGUARD 0x67 +#define BTTV_BOARD_NEBULA_DIGITV 0x68 +#define BTTV_BOARD_PV143 0x69 +#define BTTV_BOARD_VD009X1_MINIDIN 0x6a +#define BTTV_BOARD_VD009X1_COMBI 0x6b +#define BTTV_BOARD_VD009_MINIDIN 0x6c +#define BTTV_BOARD_VD009_COMBI 0x6d +#define BTTV_BOARD_IVC100 0x6e +#define BTTV_BOARD_IVC120 0x6f +#define BTTV_BOARD_PC_HDTV 0x70 +#define BTTV_BOARD_TWINHAN_DST 0x71 +#define BTTV_BOARD_WINFASTVC100 0x72 +#define BTTV_BOARD_TEV560 0x73 +#define BTTV_BOARD_SIMUS_GVC1100 0x74 +#define BTTV_BOARD_NGSTV_PLUS 0x75 +#define BTTV_BOARD_LMLBT4 0x76 +#define BTTV_BOARD_TEKRAM_M205 0x77 +#define BTTV_BOARD_CONTVFMI 0x78 +#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 +#define BTTV_BOARD_SPIRIT_TV 0x7a +#define BTTV_BOARD_AVDVBT_771 0x7b +#define BTTV_BOARD_AVDVBT_761 0x7c +#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d +#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e +#define BTTV_BOARD_APAC_VIEWCOMP 0x7f +#define BTTV_BOARD_DVICO_DVBT_LITE 0x80 +#define BTTV_BOARD_VGEAR_MYVCD 0x81 +#define BTTV_BOARD_SUPER_TV 0x82 +#define BTTV_BOARD_TIBET_CS16 0x83 +#define BTTV_BOARD_KODICOM_4400R 0x84 +#define BTTV_BOARD_KODICOM_4400R_SL 0x85 +#define BTTV_BOARD_ADLINK_RTV24 0x86 +#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 +#define BTTV_BOARD_ACORP_Y878F 0x88 +#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89 +#define BTTV_BOARD_PV_BT878P_2E 0x8a +#define BTTV_BOARD_PV_M4900 0x8b +#define BTTV_BOARD_OSPREY440 0x8c +#define BTTV_BOARD_ASOUND_SKYEYE 0x8d +#define BTTV_BOARD_SABRENT_TVFM 0x8e +#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f +#define BTTV_BOARD_MACHTV_MAGICTV 0x90 + +/* more card-specific defines */ +#define PT2254_L_CHANNEL 0x10 +#define PT2254_R_CHANNEL 0x08 +#define PT2254_DBS_IN_2 0x400 +#define PT2254_DBS_IN_10 0x20000 +#define WINVIEW_PT2254_CLK 0x40 +#define WINVIEW_PT2254_DATA 0x20 +#define WINVIEW_PT2254_STROBE 0x80 + +/* digital_mode */ +#define DIGITAL_MODE_VIDEO 1 +#define DIGITAL_MODE_CAMERA 2 + +struct bttv_core { + /* device structs */ + struct pci_dev *pci; + struct i2c_adapter i2c_adap; + struct list_head subs; /* struct bttv_sub_device */ + + /* device config */ + unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ + unsigned int type; /* card type (pointer into tvcards[]) */ + char name[8]; /* dev name */ +}; + +struct bttv; + + +struct bttv_ir { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + + /* Usual gpio signalling */ + + u32 mask_keycode; + u32 mask_keydown; + u32 mask_keyup; + u32 polling; + u32 last_gpio; + struct work_struct work; + struct timer_list timer; + + /* RC5 gpio */ + u32 rc5_gpio; + struct timer_list timer_end; /* timer_end for code completion */ + struct timer_list timer_keyup; /* timer_end for key release */ + u32 last_rc5; /* last good rc5 code */ + u32 last_bit; /* last raw bit seen */ + u32 code; /* raw code under construction */ + struct timeval base_time; /* time of last seen code */ + int active; /* building raw code */ +}; + +struct tvcard +{ + char *name; + unsigned int video_inputs; + unsigned int audio_inputs; + unsigned int tuner; + unsigned int svhs; + unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO + u32 gpiomask; + u32 muxsel[16]; + u32 gpiomux[4]; /* Tuner, Radio, external, internal */ + u32 gpiomute; /* GPIO mute setting */ + u32 gpiomask2; /* GPIO MUX mask */ + + /* i2c audio flags */ + unsigned int no_msp34xx:1; + unsigned int no_tda9875:1; + unsigned int no_tda7432:1; + unsigned int needs_tvaudio:1; + unsigned int msp34xx_alt:1; + + /* flag: video pci function is unused */ + unsigned int no_video:1; + unsigned int has_dvb:1; + unsigned int has_remote:1; + unsigned int no_gpioirq:1; + + /* other settings */ + unsigned int pll; +#define PLL_NONE 0 +#define PLL_28 1 +#define PLL_35 2 + + unsigned int tuner_type; + unsigned int tuner_addr; + unsigned int radio_addr; + + unsigned int has_radio; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + void (*muxsel_hook)(struct bttv *btv, unsigned int input); +}; + +extern struct tvcard bttv_tvcards[]; + +/* identification / initialization of the card */ +extern void bttv_idcard(struct bttv *btv); +extern void bttv_init_card1(struct bttv *btv); +extern void bttv_init_card2(struct bttv *btv); + +/* card-specific funtions */ +extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); +extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); + +/* extra tweaks for some chipsets */ +extern void bttv_check_chipset(void); +extern int bttv_handle_chipset(struct bttv *btv); + +/* ---------------------------------------------------------- */ +/* exported by bttv-if.c */ + +/* this obsolete -- please use the sysfs-based + interface below for new code */ + +/* returns card type + card ID (for bt878-based ones) + for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN + returns negative value if error occurred +*/ +extern int bttv_get_cardinfo(unsigned int card, int *type, + unsigned int *cardid); +extern struct pci_dev* bttv_get_pcidev(unsigned int card); + +/* obsolete, use bttv_get_cardinfo instead */ +extern int bttv_get_id(unsigned int card); + +/* sets GPOE register (BT848_GPIO_OUT_EN) to new value: + data | (current_GPOE_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_gpio_enable(unsigned int card, + unsigned long mask, unsigned long data); + +/* fills data with GPDATA register contents + returns negative value if error occurred +*/ +extern int bttv_read_gpio(unsigned int card, unsigned long *data); + +/* sets GPDATA register to new value: + (data & mask) | (current_GPDATA_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_write_gpio(unsigned int card, + unsigned long mask, unsigned long data); + +/* returns pointer to task queue which can be used as parameter to + interruptible_sleep_on + in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated + (wake_up_interruptible) and following call to the function bttv_read_gpio + should return new value of GPDATA, + returns NULL value if error occurred or queue is not available + WARNING: because there is no buffer for GPIO data, one MUST + process data ASAP +*/ +extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card); + +/* call i2c clients +*/ +extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg); + + + +/* ---------------------------------------------------------- */ +/* sysfs/driver-moded based gpio access interface */ + + +struct bttv_sub_device { + struct device dev; + struct bttv_core *core; + struct list_head list; +}; +#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev) + +struct bttv_sub_driver { + struct device_driver drv; + char wanted[BUS_ID_SIZE]; + int (*probe)(struct bttv_sub_device *sub); + void (*remove)(struct bttv_sub_device *sub); +}; +#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) + +int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); +int bttv_sub_unregister(struct bttv_sub_driver *drv); + +/* gpio access functions */ +void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits); +u32 bttv_gpio_read(struct bttv_core *core); +void bttv_gpio_write(struct bttv_core *core, u32 value); +void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); + +#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits) +#define gpio_read() bttv_gpio_read(&btv->c) +#define gpio_write(value) bttv_gpio_write(&btv->c, value) +#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) + + +/* ---------------------------------------------------------- */ +/* i2c */ + +extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); +extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); +extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, + unsigned char b2, int both); +extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); + +extern int bttv_input_init(struct bttv *dev); +extern void bttv_input_fini(struct bttv *dev); +extern void bttv_input_irq(struct bttv *dev); + +#endif /* _BTTV_H_ */ +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.20/bt848.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.20/bt848.h @@ -0,0 +1,366 @@ +/* + bt848.h - Bt848 register offsets + + Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + + 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. +*/ + +#ifndef _BT848_H_ +#define _BT848_H_ + +#ifndef PCI_VENDOR_ID_BROOKTREE +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#endif +#ifndef PCI_DEVICE_ID_BT848 +#define PCI_DEVICE_ID_BT848 0x350 +#endif +#ifndef PCI_DEVICE_ID_BT849 +#define PCI_DEVICE_ID_BT849 0x351 +#endif +#ifndef PCI_DEVICE_ID_BT878 +#define PCI_DEVICE_ID_BT878 0x36e +#endif +#ifndef PCI_DEVICE_ID_BT879 +#define PCI_DEVICE_ID_BT879 0x36f +#endif + + +/* Brooktree 848 registers */ + +#define BT848_DSTATUS 0x000 +#define BT848_DSTATUS_PRES (1<<7) +#define BT848_DSTATUS_HLOC (1<<6) +#define BT848_DSTATUS_FIELD (1<<5) +#define BT848_DSTATUS_NUML (1<<4) +#define BT848_DSTATUS_CSEL (1<<3) +#define BT848_DSTATUS_PLOCK (1<<2) +#define BT848_DSTATUS_LOF (1<<1) +#define BT848_DSTATUS_COF (1<<0) + +#define BT848_IFORM 0x004 +#define BT848_IFORM_HACTIVE (1<<7) +#define BT848_IFORM_MUXSEL (3<<5) +#define BT848_IFORM_MUX0 (2<<5) +#define BT848_IFORM_MUX1 (3<<5) +#define BT848_IFORM_MUX2 (1<<5) +#define BT848_IFORM_XTSEL (3<<3) +#define BT848_IFORM_XT0 (1<<3) +#define BT848_IFORM_XT1 (2<<3) +#define BT848_IFORM_XTAUTO (3<<3) +#define BT848_IFORM_XTBOTH (3<<3) +#define BT848_IFORM_NTSC 1 +#define BT848_IFORM_NTSC_J 2 +#define BT848_IFORM_PAL_BDGHI 3 +#define BT848_IFORM_PAL_M 4 +#define BT848_IFORM_PAL_N 5 +#define BT848_IFORM_SECAM 6 +#define BT848_IFORM_PAL_NC 7 +#define BT848_IFORM_AUTO 0 +#define BT848_IFORM_NORM 7 + +#define BT848_TDEC 0x008 +#define BT848_TDEC_DEC_FIELD (1<<7) +#define BT848_TDEC_FLDALIGN (1<<6) +#define BT848_TDEC_DEC_RAT (0x1f) + +#define BT848_E_CROP 0x00C +#define BT848_O_CROP 0x08C + +#define BT848_E_VDELAY_LO 0x010 +#define BT848_O_VDELAY_LO 0x090 + +#define BT848_E_VACTIVE_LO 0x014 +#define BT848_O_VACTIVE_LO 0x094 + +#define BT848_E_HDELAY_LO 0x018 +#define BT848_O_HDELAY_LO 0x098 + +#define BT848_E_HACTIVE_LO 0x01C +#define BT848_O_HACTIVE_LO 0x09C + +#define BT848_E_HSCALE_HI 0x020 +#define BT848_O_HSCALE_HI 0x0A0 + +#define BT848_E_HSCALE_LO 0x024 +#define BT848_O_HSCALE_LO 0x0A4 + +#define BT848_BRIGHT 0x028 + +#define BT848_E_CONTROL 0x02C +#define BT848_O_CONTROL 0x0AC +#define BT848_CONTROL_LNOTCH (1<<7) +#define BT848_CONTROL_COMP (1<<6) +#define BT848_CONTROL_LDEC (1<<5) +#define BT848_CONTROL_CBSENSE (1<<4) +#define BT848_CONTROL_CON_MSB (1<<2) +#define BT848_CONTROL_SAT_U_MSB (1<<1) +#define BT848_CONTROL_SAT_V_MSB (1<<0) + +#define BT848_CONTRAST_LO 0x030 +#define BT848_SAT_U_LO 0x034 +#define BT848_SAT_V_LO 0x038 +#define BT848_HUE 0x03C + +#define BT848_E_SCLOOP 0x040 +#define BT848_O_SCLOOP 0x0C0 +#define BT848_SCLOOP_CAGC (1<<6) +#define BT848_SCLOOP_CKILL (1<<5) +#define BT848_SCLOOP_HFILT_AUTO (0<<3) +#define BT848_SCLOOP_HFILT_CIF (1<<3) +#define BT848_SCLOOP_HFILT_QCIF (2<<3) +#define BT848_SCLOOP_HFILT_ICON (3<<3) + +#define BT848_SCLOOP_PEAK (1<<7) +#define BT848_SCLOOP_HFILT_MINP (1<<3) +#define BT848_SCLOOP_HFILT_MEDP (2<<3) +#define BT848_SCLOOP_HFILT_MAXP (3<<3) + + +#define BT848_OFORM 0x048 +#define BT848_OFORM_RANGE (1<<7) +#define BT848_OFORM_CORE0 (0<<5) +#define BT848_OFORM_CORE8 (1<<5) +#define BT848_OFORM_CORE16 (2<<5) +#define BT848_OFORM_CORE32 (3<<5) + +#define BT848_E_VSCALE_HI 0x04C +#define BT848_O_VSCALE_HI 0x0CC +#define BT848_VSCALE_YCOMB (1<<7) +#define BT848_VSCALE_COMB (1<<6) +#define BT848_VSCALE_INT (1<<5) +#define BT848_VSCALE_HI 15 + +#define BT848_E_VSCALE_LO 0x050 +#define BT848_O_VSCALE_LO 0x0D0 +#define BT848_TEST 0x054 +#define BT848_ADELAY 0x060 +#define BT848_BDELAY 0x064 + +#define BT848_ADC 0x068 +#define BT848_ADC_RESERVED (2<<6) +#define BT848_ADC_SYNC_T (1<<5) +#define BT848_ADC_AGC_EN (1<<4) +#define BT848_ADC_CLK_SLEEP (1<<3) +#define BT848_ADC_Y_SLEEP (1<<2) +#define BT848_ADC_C_SLEEP (1<<1) +#define BT848_ADC_CRUSH (1<<0) + +#define BT848_WC_UP 0x044 +#define BT848_WC_DOWN 0x078 + +#define BT848_E_VTC 0x06C +#define BT848_O_VTC 0x0EC +#define BT848_VTC_HSFMT (1<<7) +#define BT848_VTC_VFILT_2TAP 0 +#define BT848_VTC_VFILT_3TAP 1 +#define BT848_VTC_VFILT_4TAP 2 +#define BT848_VTC_VFILT_5TAP 3 + +#define BT848_SRESET 0x07C + +#define BT848_COLOR_FMT 0x0D4 +#define BT848_COLOR_FMT_O_RGB32 (0<<4) +#define BT848_COLOR_FMT_O_RGB24 (1<<4) +#define BT848_COLOR_FMT_O_RGB16 (2<<4) +#define BT848_COLOR_FMT_O_RGB15 (3<<4) +#define BT848_COLOR_FMT_O_YUY2 (4<<4) +#define BT848_COLOR_FMT_O_BtYUV (5<<4) +#define BT848_COLOR_FMT_O_Y8 (6<<4) +#define BT848_COLOR_FMT_O_RGB8 (7<<4) +#define BT848_COLOR_FMT_O_YCrCb422 (8<<4) +#define BT848_COLOR_FMT_O_YCrCb411 (9<<4) +#define BT848_COLOR_FMT_O_RAW (14<<4) +#define BT848_COLOR_FMT_E_RGB32 0 +#define BT848_COLOR_FMT_E_RGB24 1 +#define BT848_COLOR_FMT_E_RGB16 2 +#define BT848_COLOR_FMT_E_RGB15 3 +#define BT848_COLOR_FMT_E_YUY2 4 +#define BT848_COLOR_FMT_E_BtYUV 5 +#define BT848_COLOR_FMT_E_Y8 6 +#define BT848_COLOR_FMT_E_RGB8 7 +#define BT848_COLOR_FMT_E_YCrCb422 8 +#define BT848_COLOR_FMT_E_YCrCb411 9 +#define BT848_COLOR_FMT_E_RAW 14 + +#define BT848_COLOR_FMT_RGB32 0x00 +#define BT848_COLOR_FMT_RGB24 0x11 +#define BT848_COLOR_FMT_RGB16 0x22 +#define BT848_COLOR_FMT_RGB15 0x33 +#define BT848_COLOR_FMT_YUY2 0x44 +#define BT848_COLOR_FMT_BtYUV 0x55 +#define BT848_COLOR_FMT_Y8 0x66 +#define BT848_COLOR_FMT_RGB8 0x77 +#define BT848_COLOR_FMT_YCrCb422 0x88 +#define BT848_COLOR_FMT_YCrCb411 0x99 +#define BT848_COLOR_FMT_RAW 0xee + +#define BT848_VTOTAL_LO 0xB0 +#define BT848_VTOTAL_HI 0xB4 + +#define BT848_COLOR_CTL 0x0D8 +#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7) +#define BT848_COLOR_CTL_COLOR_BARS (1<<6) +#define BT848_COLOR_CTL_RGB_DED (1<<5) +#define BT848_COLOR_CTL_GAMMA (1<<4) +#define BT848_COLOR_CTL_WSWAP_ODD (1<<3) +#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2) +#define BT848_COLOR_CTL_BSWAP_ODD (1<<1) +#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0) + +#define BT848_CAP_CTL 0x0DC +#define BT848_CAP_CTL_DITH_FRAME (1<<4) +#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3) +#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2) +#define BT848_CAP_CTL_CAPTURE_ODD (1<<1) +#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0) + +#define BT848_VBI_PACK_SIZE 0x0E0 + +#define BT848_VBI_PACK_DEL 0x0E4 +#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc +#define BT848_VBI_PACK_DEL_EXT_FRAME 2 +#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1 + + +#define BT848_INT_STAT 0x100 +#define BT848_INT_MASK 0x104 + +#define BT848_INT_ETBF (1<<23) + +#define BT848_INT_RISCS (0xf<<28) +#define BT848_INT_RISC_EN (1<<27) +#define BT848_INT_RACK (1<<25) +#define BT848_INT_FIELD (1<<24) +#define BT848_INT_SCERR (1<<19) +#define BT848_INT_OCERR (1<<18) +#define BT848_INT_PABORT (1<<17) +#define BT848_INT_RIPERR (1<<16) +#define BT848_INT_PPERR (1<<15) +#define BT848_INT_FDSR (1<<14) +#define BT848_INT_FTRGT (1<<13) +#define BT848_INT_FBUS (1<<12) +#define BT848_INT_RISCI (1<<11) +#define BT848_INT_GPINT (1<<9) +#define BT848_INT_I2CDONE (1<<8) +#define BT848_INT_VPRES (1<<5) +#define BT848_INT_HLOCK (1<<4) +#define BT848_INT_OFLOW (1<<3) +#define BT848_INT_HSYNC (1<<2) +#define BT848_INT_VSYNC (1<<1) +#define BT848_INT_FMTCHG (1<<0) + + +#define BT848_GPIO_DMA_CTL 0x10C +#define BT848_GPIO_DMA_CTL_GPINTC (1<<15) +#define BT848_GPIO_DMA_CTL_GPINTI (1<<14) +#define BT848_GPIO_DMA_CTL_GPWEC (1<<13) +#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11) +#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10) +#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6) +#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4) +#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2) +#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2) +#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2) +#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2) +#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1) +#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0) + +#define BT848_I2C 0x110 +#define BT878_I2C_MODE (1<<7) +#define BT878_I2C_RATE (1<<6) +#define BT878_I2C_NOSTOP (1<<5) +#define BT878_I2C_NOSTART (1<<4) +#define BT848_I2C_DIV (0xf<<4) +#define BT848_I2C_SYNC (1<<3) +#define BT848_I2C_W3B (1<<2) +#define BT848_I2C_SCL (1<<1) +#define BT848_I2C_SDA (1<<0) + +#define BT848_RISC_STRT_ADD 0x114 +#define BT848_GPIO_OUT_EN 0x118 +#define BT848_GPIO_REG_INP 0x11C +#define BT848_RISC_COUNT 0x120 +#define BT848_GPIO_DATA 0x200 + + +/* Bt848 RISC commands */ + +/* only for the SYNC RISC command */ +#define BT848_FIFO_STATUS_FM1 0x06 +#define BT848_FIFO_STATUS_FM3 0x0e +#define BT848_FIFO_STATUS_SOL 0x02 +#define BT848_FIFO_STATUS_EOL4 0x01 +#define BT848_FIFO_STATUS_EOL3 0x0d +#define BT848_FIFO_STATUS_EOL2 0x09 +#define BT848_FIFO_STATUS_EOL1 0x05 +#define BT848_FIFO_STATUS_VRE 0x04 +#define BT848_FIFO_STATUS_VRO 0x0c +#define BT848_FIFO_STATUS_PXV 0x00 + +#define BT848_RISC_RESYNC (1<<15) + +/* WRITE and SKIP */ +/* disable which bytes of each DWORD */ +#define BT848_RISC_BYTE0 (1U<<12) +#define BT848_RISC_BYTE1 (1U<<13) +#define BT848_RISC_BYTE2 (1U<<14) +#define BT848_RISC_BYTE3 (1U<<15) +#define BT848_RISC_BYTE_ALL (0x0fU<<12) +#define BT848_RISC_BYTE_NONE 0 +/* cause RISCI */ +#define BT848_RISC_IRQ (1U<<24) +/* RISC command is last one in this line */ +#define BT848_RISC_EOL (1U<<26) +/* RISC command is first one in this line */ +#define BT848_RISC_SOL (1U<<27) + +#define BT848_RISC_WRITE (0x01U<<28) +#define BT848_RISC_SKIP (0x02U<<28) +#define BT848_RISC_WRITEC (0x05U<<28) +#define BT848_RISC_JUMP (0x07U<<28) +#define BT848_RISC_SYNC (0x08U<<28) + +#define BT848_RISC_WRITE123 (0x09U<<28) +#define BT848_RISC_SKIP123 (0x0aU<<28) +#define BT848_RISC_WRITE1S23 (0x0bU<<28) + + +/* Bt848A and higher only !! */ +#define BT848_TGLB 0x080 +#define BT848_TGCTRL 0x084 +#define BT848_FCAP 0x0E8 +#define BT848_PLL_F_LO 0x0F0 +#define BT848_PLL_F_HI 0x0F4 + +#define BT848_PLL_XCI 0x0F8 +#define BT848_PLL_X (1<<7) +#define BT848_PLL_C (1<<6) + +#define BT848_DVSIF 0x0FC + +/* Bt878 register */ + +#define BT878_DEVCTRL 0x40 +#define BT878_EN_TBFX 0x02 +#define BT878_EN_VSFX 0x04 + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.20/btcx-risc.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.20/btcx-risc.h @@ -0,0 +1,34 @@ +/* + */ +struct btcx_riscmem { + unsigned int size; + u32 *cpu; + u32 *jmp; + dma_addr_t dma; +}; + +struct btcx_skiplist { + int start; + int end; +}; + +int btcx_riscmem_alloc(struct pci_dev *pci, + struct btcx_riscmem *risc, + unsigned int size); +void btcx_riscmem_free(struct pci_dev *pci, + struct btcx_riscmem *risc); + +int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win, + struct v4l2_clip *clips, unsigned int n); +int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, + unsigned int n, int mask); +void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips); +void btcx_calc_skips(int line, int width, unsigned int *maxy, + struct btcx_skiplist *skips, unsigned int *nskips, + const struct v4l2_clip *clips, unsigned int nclips); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.18/bttvp.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.18/bttvp.h @@ -0,0 +1,413 @@ +/* + + bttv - Bt848 frame grabber driver + + bttv's *private* header file -- nobody other than bttv itself + should ever include this file. + + (c) 2000-2002 Gerd Knorr + + 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. +*/ + +#ifndef _BTTVP_H_ +#define _BTTVP_H_ + +#include +#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "bt848.h" +#include "bttv.h" +#include "btcx-risc.h" + +#ifdef __KERNEL__ + +#define FORMAT_FLAGS_DITHER 0x01 +#define FORMAT_FLAGS_PACKED 0x02 +#define FORMAT_FLAGS_PLANAR 0x04 +#define FORMAT_FLAGS_RAW 0x08 +#define FORMAT_FLAGS_CrCb 0x10 + +#define RISC_SLOT_O_VBI 4 +#define RISC_SLOT_O_FIELD 6 +#define RISC_SLOT_E_VBI 10 +#define RISC_SLOT_E_FIELD 12 +#define RISC_SLOT_LOOP 14 + +#define RESOURCE_OVERLAY 1 +#define RESOURCE_VIDEO 2 +#define RESOURCE_VBI 4 + +#define RAW_LINES 640 +#define RAW_BPL 1024 + +#define UNSET (-1U) + +#define clamp(x, low, high) min (max (low, x), high) + +/* ---------------------------------------------------------- */ + +struct bttv_tvnorm { + int v4l2_id; + char *name; + u32 Fsc; + u16 swidth, sheight; /* scaled standard width, height */ + u16 totalwidth; + u8 adelay, bdelay, iform; + u32 scaledtwidth; + u16 hdelayx1, hactivex1; + u16 vdelay; + u8 vbipack; + u16 vtotal; + int sram; + /* ITU-R frame line number of the first VBI line we can + capture, of the first and second field. */ + u16 vbistart[2]; +}; +extern const struct bttv_tvnorm bttv_tvnorms[]; + +struct bttv_format { + char *name; + int palette; /* video4linux 1 */ + int fourcc; /* video4linux 2 */ + int btformat; /* BT848_COLOR_FMT_* */ + int btswap; /* BT848_COLOR_CTL_* */ + int depth; /* bit/pixel */ + int flags; + int hshift,vshift; /* for planar modes */ +}; + +/* ---------------------------------------------------------- */ + +struct bttv_geometry { + u8 vtc,crop,comb; + u16 width,hscale,hdelay; + u16 sheight,vscale,vdelay,vtotal; +}; + +struct bttv_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + /* bttv specific */ + const struct bttv_format *fmt; + int tvnorm; + int btformat; + int btswap; + struct bttv_geometry geo; + struct btcx_riscmem top; + struct btcx_riscmem bottom; +}; + +struct bttv_buffer_set { + struct bttv_buffer *top; /* top field buffer */ + struct bttv_buffer *bottom; /* bottom field buffer */ + unsigned int top_irq; + unsigned int frame_irq; +}; + +struct bttv_overlay { + int tvnorm; + struct v4l2_rect w; + enum v4l2_field field; + struct v4l2_clip *clips; + int nclips; + int setup_ok; +}; + +struct bttv_fh { + struct bttv *btv; + int resources; +#ifdef VIDIOC_G_PRIORITY + enum v4l2_priority prio; +#endif + enum v4l2_buf_type type; + + /* video capture */ + struct videobuf_queue cap; + const struct bttv_format *fmt; + int width; + int height; + + /* current settings */ + const struct bttv_format *ovfmt; + struct bttv_overlay ov; + + /* video overlay */ + struct videobuf_queue vbi; + int lines; +}; + +/* ---------------------------------------------------------- */ +/* bttv-risc.c */ + +/* risc code generators - capture */ +int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, + struct scatterlist *sglist, + unsigned int offset, unsigned int bpl, + unsigned int pitch, unsigned int lines); + +/* control dma register + risc main loop */ +void bttv_set_dma(struct bttv *btv, int override); +int bttv_risc_init_main(struct bttv *btv); +int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, + int irqflags); + +/* capture buffer handling */ +int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf); +int bttv_buffer_activate_video(struct bttv *btv, + struct bttv_buffer_set *set); +int bttv_buffer_activate_vbi(struct bttv *btv, + struct bttv_buffer *vbi); +void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv, + struct bttv_buffer *buf); + +/* overlay handling */ +int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, + const struct bttv_format *fmt, + struct bttv_buffer *buf); + + +/* ---------------------------------------------------------- */ +/* bttv-vbi.c */ + +void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines); + +extern struct videobuf_queue_ops bttv_vbi_qops; + +/* ---------------------------------------------------------- */ +/* bttv-gpio.c */ + + +extern struct bus_type bttv_sub_bus_type; +int bttv_sub_add_device(struct bttv_core *core, char *name); +int bttv_sub_del_devices(struct bttv_core *core); + + +/* ---------------------------------------------------------- */ +/* bttv-driver.c */ + +/* insmod options */ +extern unsigned int bttv_verbose; +extern unsigned int bttv_debug; +extern unsigned int bttv_gpio; +extern void bttv_gpio_tracking(struct bttv *btv, char *comment); +extern int init_bttv_i2c(struct bttv *btv); +extern int fini_bttv_i2c(struct bttv *btv); + +#define bttv_printk if (bttv_verbose) printk +#define dprintk if (bttv_debug >= 1) printk +#define d2printk if (bttv_debug >= 2) printk + +#define BTTV_MAX_FBUF 0x208000 +#define VBIBUF_SIZE (2048*VBI_MAXLINES*2) +#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ +#define BTTV_FREE_IDLE (HZ) /* one second */ + + +struct bttv_pll_info { + unsigned int pll_ifreq; /* PLL input frequency */ + unsigned int pll_ofreq; /* PLL output frequency */ + unsigned int pll_crystal; /* Crystal used for input */ + unsigned int pll_current; /* Currently programmed ofreq */ +}; + +/* for gpio-connected remote control */ +struct bttv_input { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + u32 mask_keycode; + u32 mask_keydown; +}; + +struct bttv_suspend_state { + u32 gpio_enable; + u32 gpio_data; + int disabled; + int loop_irq; + struct bttv_buffer_set video; + struct bttv_buffer *vbi; +}; + +struct bttv { + struct bttv_core c; + + /* pci device config */ + unsigned short id; + unsigned char revision; + unsigned char __iomem *bt848_mmio; /* pointer to mmio */ + + /* card configuration info */ + unsigned int cardid; /* pci subsystem id (bt878 based ones) */ + unsigned int tuner_type; /* tuner chip type */ + unsigned int tda9887_conf; + unsigned int svhs; + struct bttv_pll_info pll; + int triton1; + int gpioirq; + int (*custom_irq)(struct bttv *btv); + + int use_i2c_hw; + + /* old gpio interface */ + wait_queue_head_t gpioq; + int shutdown; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + + /* new gpio interface */ + spinlock_t gpio_lock; + + /* i2c layer */ + struct i2c_algo_bit_data i2c_algo; + struct i2c_client i2c_client; + int i2c_state, i2c_rc; + int i2c_done; + wait_queue_head_t i2c_queue; + struct i2c_client *i2c_msp34xx_client; + struct i2c_client *i2c_tvaudio_client; + + /* video4linux (1) */ + struct video_device *video_dev; + struct video_device *radio_dev; + struct video_device *vbi_dev; + + /* infrared remote */ + int has_remote; + struct bttv_ir *remote; + + /* locking */ + spinlock_t s_lock; + struct mutex lock; + int resources; + struct mutex reslock; +#ifdef VIDIOC_G_PRIORITY + struct v4l2_prio_state prio; +#endif + + /* video state */ + unsigned int input; + unsigned int audio; + unsigned int mute; + unsigned long freq; + int tvnorm,hue,contrast,bright,saturation; + struct v4l2_framebuffer fbuf; + unsigned int field_count; + + /* various options */ + int opt_combfilter; + int opt_lumafilter; + int opt_automute; + int opt_chroma_agc; + int opt_adc_crush; + int opt_vcr_hack; + int opt_whitecrush_upper; + int opt_whitecrush_lower; + int opt_uv_ratio; + int opt_full_luma_range; + int opt_coring; + + /* radio data/state */ + int has_radio; + int radio_user; + + /* miro/pinnacle + Aimslab VHX + philips matchbox (tea5757 radio tuner) support */ + int has_matchbox; + int mbox_we; + int mbox_data; + int mbox_clk; + int mbox_most; + int mbox_mask; + + /* ISA stuff (Terratec Active Radio Upgrade) */ + int mbox_ior; + int mbox_iow; + int mbox_csel; + + /* risc memory management data + - must acquire s_lock before changing these + - only the irq handler is supported to touch top + bottom + vcurr */ + struct btcx_riscmem main; + struct bttv_buffer *screen; /* overlay */ + struct list_head capture; /* video capture queue */ + struct list_head vcapture; /* vbi capture queue */ + struct bttv_buffer_set curr; /* active buffers */ + struct bttv_buffer *cvbi; /* active vbi buffer */ + int loop_irq; + int new_input; + + unsigned long cap_ctl; + unsigned long dma_on; + struct timer_list timeout; + struct bttv_suspend_state state; + + /* stats */ + unsigned int errors; + unsigned int framedrop; + unsigned int irq_total; + unsigned int irq_me; + + unsigned int users; + struct bttv_fh init; +}; + +/* our devices */ +#define BTTV_MAX 16 +extern unsigned int bttv_num; +extern struct bttv bttvs[BTTV_MAX]; + +/* private ioctls */ +#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int) +#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int) + +#endif + +#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) +#define btread(adr) readl(btv->bt848_mmio+(adr)) + +#define btand(dat,adr) btwrite((dat) & btread(adr), adr) +#define btor(dat,adr) btwrite((dat) | btread(adr), adr) +#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) + +#endif /* _BTTVP_H_ */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.18/bttv.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.18/bttv.h @@ -0,0 +1,389 @@ +/* + * + * bttv - Bt848 frame grabber driver + * + * card ID's and external interfaces of the bttv driver + * basically stuff needed by other drivers (i2c, lirc, ...) + * and is supported not to change much over time. + * + * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de) + * (c) 1999,2000 Gerd Knorr + * + */ + +#ifndef _BTTV_H_ +#define _BTTV_H_ + +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------- */ +/* exported by bttv-cards.c */ + +#define BTTV_BOARD_UNKNOWN 0x00 +#define BTTV_BOARD_MIRO 0x01 +#define BTTV_BOARD_HAUPPAUGE 0x02 +#define BTTV_BOARD_STB 0x03 +#define BTTV_BOARD_INTEL 0x04 +#define BTTV_BOARD_DIAMOND 0x05 +#define BTTV_BOARD_AVERMEDIA 0x06 +#define BTTV_BOARD_MATRIX_VISION 0x07 +#define BTTV_BOARD_FLYVIDEO 0x08 +#define BTTV_BOARD_TURBOTV 0x09 +#define BTTV_BOARD_HAUPPAUGE878 0x0a +#define BTTV_BOARD_MIROPRO 0x0b +#define BTTV_BOARD_ADSTECH_TV 0x0c +#define BTTV_BOARD_AVERMEDIA98 0x0d +#define BTTV_BOARD_VHX 0x0e +#define BTTV_BOARD_ZOLTRIX 0x0f +#define BTTV_BOARD_PIXVIEWPLAYTV 0x10 +#define BTTV_BOARD_WINVIEW_601 0x11 +#define BTTV_BOARD_AVEC_INTERCAP 0x12 +#define BTTV_BOARD_LIFE_FLYKIT 0x13 +#define BTTV_BOARD_CEI_RAFFLES 0x14 +#define BTTV_BOARD_CONFERENCETV 0x15 +#define BTTV_BOARD_PHOEBE_TVMAS 0x16 +#define BTTV_BOARD_MODTEC_205 0x17 +#define BTTV_BOARD_MAGICTVIEW061 0x18 +#define BTTV_BOARD_VOBIS_BOOSTAR 0x19 +#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a +#define BTTV_BOARD_MAXI 0x1b +#define BTTV_BOARD_TERRATV 0x1c +#define BTTV_BOARD_PXC200 0x1d +#define BTTV_BOARD_FLYVIDEO_98 0x1e +#define BTTV_BOARD_IPROTV 0x1f +#define BTTV_BOARD_INTEL_C_S_PCI 0x20 +#define BTTV_BOARD_TERRATVALUE 0x21 +#define BTTV_BOARD_WINFAST2000 0x22 +#define BTTV_BOARD_CHRONOS_VS2 0x23 +#define BTTV_BOARD_TYPHOON_TVIEW 0x24 +#define BTTV_BOARD_PXELVWPLTVPRO 0x25 +#define BTTV_BOARD_MAGICTVIEW063 0x26 +#define BTTV_BOARD_PINNACLE 0x27 +#define BTTV_BOARD_STB2 0x28 +#define BTTV_BOARD_AVPHONE98 0x29 +#define BTTV_BOARD_PV951 0x2a +#define BTTV_BOARD_ONAIR_TV 0x2b +#define BTTV_BOARD_SIGMA_TVII_FM 0x2c +#define BTTV_BOARD_MATRIX_VISION2 0x2d +#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e +#define BTTV_BOARD_TERRATVRADIO 0x2f +#define BTTV_BOARD_DYNALINK 0x30 +#define BTTV_BOARD_GVBCTV3PCI 0x31 +#define BTTV_BOARD_PXELVWPLTVPAK 0x32 +#define BTTV_BOARD_EAGLE 0x33 +#define BTTV_BOARD_PINNACLEPRO 0x34 +#define BTTV_BOARD_TVIEW_RDS_FM 0x35 +#define BTTV_BOARD_LIFETEC_9415 0x36 +#define BTTV_BOARD_BESTBUY_EASYTV 0x37 +#define BTTV_BOARD_FLYVIDEO_98FM 0x38 +#define BTTV_BOARD_GRANDTEC 0x39 +#define BTTV_BOARD_ASKEY_CPH060 0x3a +#define BTTV_BOARD_ASKEY_CPH03X 0x3b +#define BTTV_BOARD_MM100PCTV 0x3c +#define BTTV_BOARD_GMV1 0x3d +#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e +#define BTTV_BOARD_ATI_TVWONDER 0x3f +#define BTTV_BOARD_ATI_TVWONDERVE 0x40 +#define BTTV_BOARD_FLYVIDEO2000 0x41 +#define BTTV_BOARD_TERRATVALUER 0x42 +#define BTTV_BOARD_GVBCTV4PCI 0x43 +#define BTTV_BOARD_VOODOOTV_FM 0x44 +#define BTTV_BOARD_AIMMS 0x45 +#define BTTV_BOARD_PV_BT878P_PLUS 0x46 +#define BTTV_BOARD_FLYVIDEO98EZ 0x47 +#define BTTV_BOARD_PV_BT878P_9B 0x48 +#define BTTV_BOARD_SENSORAY311 0x49 +#define BTTV_BOARD_RV605 0x4a +#define BTTV_BOARD_POWERCLR_MTV878 0x4b +#define BTTV_BOARD_WINDVR 0x4c +#define BTTV_BOARD_GRANDTEC_MULTI 0x4d +#define BTTV_BOARD_KWORLD 0x4e +#define BTTV_BOARD_DSP_TCVIDEO 0x4f +#define BTTV_BOARD_HAUPPAUGEPVR 0x50 +#define BTTV_BOARD_GVBCTV5PCI 0x51 +#define BTTV_BOARD_OSPREY1x0 0x52 +#define BTTV_BOARD_OSPREY1x0_848 0x53 +#define BTTV_BOARD_OSPREY101_848 0x54 +#define BTTV_BOARD_OSPREY1x1 0x55 +#define BTTV_BOARD_OSPREY1x1_SVID 0x56 +#define BTTV_BOARD_OSPREY2xx 0x57 +#define BTTV_BOARD_OSPREY2x0_SVID 0x58 +#define BTTV_BOARD_OSPREY2x0 0x59 +#define BTTV_BOARD_OSPREY500 0x5a +#define BTTV_BOARD_OSPREY540 0x5b +#define BTTV_BOARD_OSPREY2000 0x5c +#define BTTV_BOARD_IDS_EAGLE 0x5d +#define BTTV_BOARD_PINNACLESAT 0x5e +#define BTTV_BOARD_FORMAC_PROTV 0x5f +#define BTTV_BOARD_MACHTV 0x60 +#define BTTV_BOARD_EURESYS_PICOLO 0x61 +#define BTTV_BOARD_PV150 0x62 +#define BTTV_BOARD_AD_TVK503 0x63 +#define BTTV_BOARD_HERCULES_SM_TV 0x64 +#define BTTV_BOARD_PACETV 0x65 +#define BTTV_BOARD_IVC200 0x66 +#define BTTV_BOARD_XGUARD 0x67 +#define BTTV_BOARD_NEBULA_DIGITV 0x68 +#define BTTV_BOARD_PV143 0x69 +#define BTTV_BOARD_VD009X1_MINIDIN 0x6a +#define BTTV_BOARD_VD009X1_COMBI 0x6b +#define BTTV_BOARD_VD009_MINIDIN 0x6c +#define BTTV_BOARD_VD009_COMBI 0x6d +#define BTTV_BOARD_IVC100 0x6e +#define BTTV_BOARD_IVC120 0x6f +#define BTTV_BOARD_PC_HDTV 0x70 +#define BTTV_BOARD_TWINHAN_DST 0x71 +#define BTTV_BOARD_WINFASTVC100 0x72 +#define BTTV_BOARD_TEV560 0x73 +#define BTTV_BOARD_SIMUS_GVC1100 0x74 +#define BTTV_BOARD_NGSTV_PLUS 0x75 +#define BTTV_BOARD_LMLBT4 0x76 +#define BTTV_BOARD_TEKRAM_M205 0x77 +#define BTTV_BOARD_CONTVFMI 0x78 +#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 +#define BTTV_BOARD_SPIRIT_TV 0x7a +#define BTTV_BOARD_AVDVBT_771 0x7b +#define BTTV_BOARD_AVDVBT_761 0x7c +#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d +#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e +#define BTTV_BOARD_APAC_VIEWCOMP 0x7f +#define BTTV_BOARD_DVICO_DVBT_LITE 0x80 +#define BTTV_BOARD_VGEAR_MYVCD 0x81 +#define BTTV_BOARD_SUPER_TV 0x82 +#define BTTV_BOARD_TIBET_CS16 0x83 +#define BTTV_BOARD_KODICOM_4400R 0x84 +#define BTTV_BOARD_KODICOM_4400R_SL 0x85 +#define BTTV_BOARD_ADLINK_RTV24 0x86 +#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 +#define BTTV_BOARD_ACORP_Y878F 0x88 +#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89 +#define BTTV_BOARD_PV_BT878P_2E 0x8a +#define BTTV_BOARD_PV_M4900 0x8b +#define BTTV_BOARD_OSPREY440 0x8c +#define BTTV_BOARD_ASOUND_SKYEYE 0x8d +#define BTTV_BOARD_SABRENT_TVFM 0x8e +#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f +#define BTTV_BOARD_MACHTV_MAGICTV 0x90 + +/* more card-specific defines */ +#define PT2254_L_CHANNEL 0x10 +#define PT2254_R_CHANNEL 0x08 +#define PT2254_DBS_IN_2 0x400 +#define PT2254_DBS_IN_10 0x20000 +#define WINVIEW_PT2254_CLK 0x40 +#define WINVIEW_PT2254_DATA 0x20 +#define WINVIEW_PT2254_STROBE 0x80 + +/* digital_mode */ +#define DIGITAL_MODE_VIDEO 1 +#define DIGITAL_MODE_CAMERA 2 + +struct bttv_core { + /* device structs */ + struct pci_dev *pci; + struct i2c_adapter i2c_adap; + struct list_head subs; /* struct bttv_sub_device */ + + /* device config */ + unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ + unsigned int type; /* card type (pointer into tvcards[]) */ + char name[8]; /* dev name */ +}; + +struct bttv; + + +struct bttv_ir { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + + /* Usual gpio signalling */ + + u32 mask_keycode; + u32 mask_keydown; + u32 mask_keyup; + u32 polling; + u32 last_gpio; + struct work_struct work; + struct timer_list timer; + + /* RC5 gpio */ + u32 rc5_gpio; + struct timer_list timer_end; /* timer_end for code completion */ + struct timer_list timer_keyup; /* timer_end for key release */ + u32 last_rc5; /* last good rc5 code */ + u32 last_bit; /* last raw bit seen */ + u32 code; /* raw code under construction */ + struct timeval base_time; /* time of last seen code */ + int active; /* building raw code */ +}; + +struct tvcard +{ + char *name; + unsigned int video_inputs; + unsigned int audio_inputs; + unsigned int tuner; + unsigned int svhs; + unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO + u32 gpiomask; + u32 muxsel[16]; + u32 gpiomux[4]; /* Tuner, Radio, external, internal */ + u32 gpiomute; /* GPIO mute setting */ + u32 gpiomask2; /* GPIO MUX mask */ + + /* i2c audio flags */ + unsigned int no_msp34xx:1; + unsigned int no_tda9875:1; + unsigned int no_tda7432:1; + unsigned int needs_tvaudio:1; + unsigned int msp34xx_alt:1; + + /* flag: video pci function is unused */ + unsigned int no_video:1; + unsigned int has_dvb:1; + unsigned int has_remote:1; + unsigned int no_gpioirq:1; + + /* other settings */ + unsigned int pll; +#define PLL_NONE 0 +#define PLL_28 1 +#define PLL_35 2 + + unsigned int tuner_type; + unsigned int tuner_addr; + unsigned int radio_addr; + + unsigned int has_radio; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + void (*muxsel_hook)(struct bttv *btv, unsigned int input); +}; + +extern struct tvcard bttv_tvcards[]; + +/* identification / initialization of the card */ +extern void bttv_idcard(struct bttv *btv); +extern void bttv_init_card1(struct bttv *btv); +extern void bttv_init_card2(struct bttv *btv); + +/* card-specific funtions */ +extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); +extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); + +/* extra tweaks for some chipsets */ +extern void bttv_check_chipset(void); +extern int bttv_handle_chipset(struct bttv *btv); + +/* ---------------------------------------------------------- */ +/* exported by bttv-if.c */ + +/* this obsolete -- please use the sysfs-based + interface below for new code */ + +/* returns card type + card ID (for bt878-based ones) + for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN + returns negative value if error occurred +*/ +extern int bttv_get_cardinfo(unsigned int card, int *type, + unsigned int *cardid); +extern struct pci_dev* bttv_get_pcidev(unsigned int card); + +/* obsolete, use bttv_get_cardinfo instead */ +extern int bttv_get_id(unsigned int card); + +/* sets GPOE register (BT848_GPIO_OUT_EN) to new value: + data | (current_GPOE_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_gpio_enable(unsigned int card, + unsigned long mask, unsigned long data); + +/* fills data with GPDATA register contents + returns negative value if error occurred +*/ +extern int bttv_read_gpio(unsigned int card, unsigned long *data); + +/* sets GPDATA register to new value: + (data & mask) | (current_GPDATA_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_write_gpio(unsigned int card, + unsigned long mask, unsigned long data); + +/* returns pointer to task queue which can be used as parameter to + interruptible_sleep_on + in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated + (wake_up_interruptible) and following call to the function bttv_read_gpio + should return new value of GPDATA, + returns NULL value if error occurred or queue is not available + WARNING: because there is no buffer for GPIO data, one MUST + process data ASAP +*/ +extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card); + +/* call i2c clients +*/ +extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg); + + + +/* ---------------------------------------------------------- */ +/* sysfs/driver-moded based gpio access interface */ + + +struct bttv_sub_device { + struct device dev; + struct bttv_core *core; + struct list_head list; +}; +#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev) + +struct bttv_sub_driver { + struct device_driver drv; + char wanted[BUS_ID_SIZE]; + int (*probe)(struct bttv_sub_device *sub); + void (*remove)(struct bttv_sub_device *sub); +}; +#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) + +int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); +int bttv_sub_unregister(struct bttv_sub_driver *drv); + +/* gpio access functions */ +void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits); +u32 bttv_gpio_read(struct bttv_core *core); +void bttv_gpio_write(struct bttv_core *core, u32 value); +void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); + +#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits) +#define gpio_read() bttv_gpio_read(&btv->c) +#define gpio_write(value) bttv_gpio_write(&btv->c, value) +#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) + + +/* ---------------------------------------------------------- */ +/* i2c */ + +extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); +extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); +extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, + unsigned char b2, int both); +extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); + +extern int bttv_input_init(struct bttv *dev); +extern void bttv_input_fini(struct bttv *dev); +extern void bttv_input_irq(struct bttv *dev); + +#endif /* _BTTV_H_ */ +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.18/bt848.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.18/bt848.h @@ -0,0 +1,366 @@ +/* + bt848.h - Bt848 register offsets + + Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + + 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. +*/ + +#ifndef _BT848_H_ +#define _BT848_H_ + +#ifndef PCI_VENDOR_ID_BROOKTREE +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#endif +#ifndef PCI_DEVICE_ID_BT848 +#define PCI_DEVICE_ID_BT848 0x350 +#endif +#ifndef PCI_DEVICE_ID_BT849 +#define PCI_DEVICE_ID_BT849 0x351 +#endif +#ifndef PCI_DEVICE_ID_BT878 +#define PCI_DEVICE_ID_BT878 0x36e +#endif +#ifndef PCI_DEVICE_ID_BT879 +#define PCI_DEVICE_ID_BT879 0x36f +#endif + + +/* Brooktree 848 registers */ + +#define BT848_DSTATUS 0x000 +#define BT848_DSTATUS_PRES (1<<7) +#define BT848_DSTATUS_HLOC (1<<6) +#define BT848_DSTATUS_FIELD (1<<5) +#define BT848_DSTATUS_NUML (1<<4) +#define BT848_DSTATUS_CSEL (1<<3) +#define BT848_DSTATUS_PLOCK (1<<2) +#define BT848_DSTATUS_LOF (1<<1) +#define BT848_DSTATUS_COF (1<<0) + +#define BT848_IFORM 0x004 +#define BT848_IFORM_HACTIVE (1<<7) +#define BT848_IFORM_MUXSEL (3<<5) +#define BT848_IFORM_MUX0 (2<<5) +#define BT848_IFORM_MUX1 (3<<5) +#define BT848_IFORM_MUX2 (1<<5) +#define BT848_IFORM_XTSEL (3<<3) +#define BT848_IFORM_XT0 (1<<3) +#define BT848_IFORM_XT1 (2<<3) +#define BT848_IFORM_XTAUTO (3<<3) +#define BT848_IFORM_XTBOTH (3<<3) +#define BT848_IFORM_NTSC 1 +#define BT848_IFORM_NTSC_J 2 +#define BT848_IFORM_PAL_BDGHI 3 +#define BT848_IFORM_PAL_M 4 +#define BT848_IFORM_PAL_N 5 +#define BT848_IFORM_SECAM 6 +#define BT848_IFORM_PAL_NC 7 +#define BT848_IFORM_AUTO 0 +#define BT848_IFORM_NORM 7 + +#define BT848_TDEC 0x008 +#define BT848_TDEC_DEC_FIELD (1<<7) +#define BT848_TDEC_FLDALIGN (1<<6) +#define BT848_TDEC_DEC_RAT (0x1f) + +#define BT848_E_CROP 0x00C +#define BT848_O_CROP 0x08C + +#define BT848_E_VDELAY_LO 0x010 +#define BT848_O_VDELAY_LO 0x090 + +#define BT848_E_VACTIVE_LO 0x014 +#define BT848_O_VACTIVE_LO 0x094 + +#define BT848_E_HDELAY_LO 0x018 +#define BT848_O_HDELAY_LO 0x098 + +#define BT848_E_HACTIVE_LO 0x01C +#define BT848_O_HACTIVE_LO 0x09C + +#define BT848_E_HSCALE_HI 0x020 +#define BT848_O_HSCALE_HI 0x0A0 + +#define BT848_E_HSCALE_LO 0x024 +#define BT848_O_HSCALE_LO 0x0A4 + +#define BT848_BRIGHT 0x028 + +#define BT848_E_CONTROL 0x02C +#define BT848_O_CONTROL 0x0AC +#define BT848_CONTROL_LNOTCH (1<<7) +#define BT848_CONTROL_COMP (1<<6) +#define BT848_CONTROL_LDEC (1<<5) +#define BT848_CONTROL_CBSENSE (1<<4) +#define BT848_CONTROL_CON_MSB (1<<2) +#define BT848_CONTROL_SAT_U_MSB (1<<1) +#define BT848_CONTROL_SAT_V_MSB (1<<0) + +#define BT848_CONTRAST_LO 0x030 +#define BT848_SAT_U_LO 0x034 +#define BT848_SAT_V_LO 0x038 +#define BT848_HUE 0x03C + +#define BT848_E_SCLOOP 0x040 +#define BT848_O_SCLOOP 0x0C0 +#define BT848_SCLOOP_CAGC (1<<6) +#define BT848_SCLOOP_CKILL (1<<5) +#define BT848_SCLOOP_HFILT_AUTO (0<<3) +#define BT848_SCLOOP_HFILT_CIF (1<<3) +#define BT848_SCLOOP_HFILT_QCIF (2<<3) +#define BT848_SCLOOP_HFILT_ICON (3<<3) + +#define BT848_SCLOOP_PEAK (1<<7) +#define BT848_SCLOOP_HFILT_MINP (1<<3) +#define BT848_SCLOOP_HFILT_MEDP (2<<3) +#define BT848_SCLOOP_HFILT_MAXP (3<<3) + + +#define BT848_OFORM 0x048 +#define BT848_OFORM_RANGE (1<<7) +#define BT848_OFORM_CORE0 (0<<5) +#define BT848_OFORM_CORE8 (1<<5) +#define BT848_OFORM_CORE16 (2<<5) +#define BT848_OFORM_CORE32 (3<<5) + +#define BT848_E_VSCALE_HI 0x04C +#define BT848_O_VSCALE_HI 0x0CC +#define BT848_VSCALE_YCOMB (1<<7) +#define BT848_VSCALE_COMB (1<<6) +#define BT848_VSCALE_INT (1<<5) +#define BT848_VSCALE_HI 15 + +#define BT848_E_VSCALE_LO 0x050 +#define BT848_O_VSCALE_LO 0x0D0 +#define BT848_TEST 0x054 +#define BT848_ADELAY 0x060 +#define BT848_BDELAY 0x064 + +#define BT848_ADC 0x068 +#define BT848_ADC_RESERVED (2<<6) +#define BT848_ADC_SYNC_T (1<<5) +#define BT848_ADC_AGC_EN (1<<4) +#define BT848_ADC_CLK_SLEEP (1<<3) +#define BT848_ADC_Y_SLEEP (1<<2) +#define BT848_ADC_C_SLEEP (1<<1) +#define BT848_ADC_CRUSH (1<<0) + +#define BT848_WC_UP 0x044 +#define BT848_WC_DOWN 0x078 + +#define BT848_E_VTC 0x06C +#define BT848_O_VTC 0x0EC +#define BT848_VTC_HSFMT (1<<7) +#define BT848_VTC_VFILT_2TAP 0 +#define BT848_VTC_VFILT_3TAP 1 +#define BT848_VTC_VFILT_4TAP 2 +#define BT848_VTC_VFILT_5TAP 3 + +#define BT848_SRESET 0x07C + +#define BT848_COLOR_FMT 0x0D4 +#define BT848_COLOR_FMT_O_RGB32 (0<<4) +#define BT848_COLOR_FMT_O_RGB24 (1<<4) +#define BT848_COLOR_FMT_O_RGB16 (2<<4) +#define BT848_COLOR_FMT_O_RGB15 (3<<4) +#define BT848_COLOR_FMT_O_YUY2 (4<<4) +#define BT848_COLOR_FMT_O_BtYUV (5<<4) +#define BT848_COLOR_FMT_O_Y8 (6<<4) +#define BT848_COLOR_FMT_O_RGB8 (7<<4) +#define BT848_COLOR_FMT_O_YCrCb422 (8<<4) +#define BT848_COLOR_FMT_O_YCrCb411 (9<<4) +#define BT848_COLOR_FMT_O_RAW (14<<4) +#define BT848_COLOR_FMT_E_RGB32 0 +#define BT848_COLOR_FMT_E_RGB24 1 +#define BT848_COLOR_FMT_E_RGB16 2 +#define BT848_COLOR_FMT_E_RGB15 3 +#define BT848_COLOR_FMT_E_YUY2 4 +#define BT848_COLOR_FMT_E_BtYUV 5 +#define BT848_COLOR_FMT_E_Y8 6 +#define BT848_COLOR_FMT_E_RGB8 7 +#define BT848_COLOR_FMT_E_YCrCb422 8 +#define BT848_COLOR_FMT_E_YCrCb411 9 +#define BT848_COLOR_FMT_E_RAW 14 + +#define BT848_COLOR_FMT_RGB32 0x00 +#define BT848_COLOR_FMT_RGB24 0x11 +#define BT848_COLOR_FMT_RGB16 0x22 +#define BT848_COLOR_FMT_RGB15 0x33 +#define BT848_COLOR_FMT_YUY2 0x44 +#define BT848_COLOR_FMT_BtYUV 0x55 +#define BT848_COLOR_FMT_Y8 0x66 +#define BT848_COLOR_FMT_RGB8 0x77 +#define BT848_COLOR_FMT_YCrCb422 0x88 +#define BT848_COLOR_FMT_YCrCb411 0x99 +#define BT848_COLOR_FMT_RAW 0xee + +#define BT848_VTOTAL_LO 0xB0 +#define BT848_VTOTAL_HI 0xB4 + +#define BT848_COLOR_CTL 0x0D8 +#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7) +#define BT848_COLOR_CTL_COLOR_BARS (1<<6) +#define BT848_COLOR_CTL_RGB_DED (1<<5) +#define BT848_COLOR_CTL_GAMMA (1<<4) +#define BT848_COLOR_CTL_WSWAP_ODD (1<<3) +#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2) +#define BT848_COLOR_CTL_BSWAP_ODD (1<<1) +#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0) + +#define BT848_CAP_CTL 0x0DC +#define BT848_CAP_CTL_DITH_FRAME (1<<4) +#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3) +#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2) +#define BT848_CAP_CTL_CAPTURE_ODD (1<<1) +#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0) + +#define BT848_VBI_PACK_SIZE 0x0E0 + +#define BT848_VBI_PACK_DEL 0x0E4 +#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc +#define BT848_VBI_PACK_DEL_EXT_FRAME 2 +#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1 + + +#define BT848_INT_STAT 0x100 +#define BT848_INT_MASK 0x104 + +#define BT848_INT_ETBF (1<<23) + +#define BT848_INT_RISCS (0xf<<28) +#define BT848_INT_RISC_EN (1<<27) +#define BT848_INT_RACK (1<<25) +#define BT848_INT_FIELD (1<<24) +#define BT848_INT_SCERR (1<<19) +#define BT848_INT_OCERR (1<<18) +#define BT848_INT_PABORT (1<<17) +#define BT848_INT_RIPERR (1<<16) +#define BT848_INT_PPERR (1<<15) +#define BT848_INT_FDSR (1<<14) +#define BT848_INT_FTRGT (1<<13) +#define BT848_INT_FBUS (1<<12) +#define BT848_INT_RISCI (1<<11) +#define BT848_INT_GPINT (1<<9) +#define BT848_INT_I2CDONE (1<<8) +#define BT848_INT_VPRES (1<<5) +#define BT848_INT_HLOCK (1<<4) +#define BT848_INT_OFLOW (1<<3) +#define BT848_INT_HSYNC (1<<2) +#define BT848_INT_VSYNC (1<<1) +#define BT848_INT_FMTCHG (1<<0) + + +#define BT848_GPIO_DMA_CTL 0x10C +#define BT848_GPIO_DMA_CTL_GPINTC (1<<15) +#define BT848_GPIO_DMA_CTL_GPINTI (1<<14) +#define BT848_GPIO_DMA_CTL_GPWEC (1<<13) +#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11) +#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10) +#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6) +#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4) +#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2) +#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2) +#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2) +#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2) +#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1) +#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0) + +#define BT848_I2C 0x110 +#define BT878_I2C_MODE (1<<7) +#define BT878_I2C_RATE (1<<6) +#define BT878_I2C_NOSTOP (1<<5) +#define BT878_I2C_NOSTART (1<<4) +#define BT848_I2C_DIV (0xf<<4) +#define BT848_I2C_SYNC (1<<3) +#define BT848_I2C_W3B (1<<2) +#define BT848_I2C_SCL (1<<1) +#define BT848_I2C_SDA (1<<0) + +#define BT848_RISC_STRT_ADD 0x114 +#define BT848_GPIO_OUT_EN 0x118 +#define BT848_GPIO_REG_INP 0x11C +#define BT848_RISC_COUNT 0x120 +#define BT848_GPIO_DATA 0x200 + + +/* Bt848 RISC commands */ + +/* only for the SYNC RISC command */ +#define BT848_FIFO_STATUS_FM1 0x06 +#define BT848_FIFO_STATUS_FM3 0x0e +#define BT848_FIFO_STATUS_SOL 0x02 +#define BT848_FIFO_STATUS_EOL4 0x01 +#define BT848_FIFO_STATUS_EOL3 0x0d +#define BT848_FIFO_STATUS_EOL2 0x09 +#define BT848_FIFO_STATUS_EOL1 0x05 +#define BT848_FIFO_STATUS_VRE 0x04 +#define BT848_FIFO_STATUS_VRO 0x0c +#define BT848_FIFO_STATUS_PXV 0x00 + +#define BT848_RISC_RESYNC (1<<15) + +/* WRITE and SKIP */ +/* disable which bytes of each DWORD */ +#define BT848_RISC_BYTE0 (1U<<12) +#define BT848_RISC_BYTE1 (1U<<13) +#define BT848_RISC_BYTE2 (1U<<14) +#define BT848_RISC_BYTE3 (1U<<15) +#define BT848_RISC_BYTE_ALL (0x0fU<<12) +#define BT848_RISC_BYTE_NONE 0 +/* cause RISCI */ +#define BT848_RISC_IRQ (1U<<24) +/* RISC command is last one in this line */ +#define BT848_RISC_EOL (1U<<26) +/* RISC command is first one in this line */ +#define BT848_RISC_SOL (1U<<27) + +#define BT848_RISC_WRITE (0x01U<<28) +#define BT848_RISC_SKIP (0x02U<<28) +#define BT848_RISC_WRITEC (0x05U<<28) +#define BT848_RISC_JUMP (0x07U<<28) +#define BT848_RISC_SYNC (0x08U<<28) + +#define BT848_RISC_WRITE123 (0x09U<<28) +#define BT848_RISC_SKIP123 (0x0aU<<28) +#define BT848_RISC_WRITE1S23 (0x0bU<<28) + + +/* Bt848A and higher only !! */ +#define BT848_TGLB 0x080 +#define BT848_TGCTRL 0x084 +#define BT848_FCAP 0x0E8 +#define BT848_PLL_F_LO 0x0F0 +#define BT848_PLL_F_HI 0x0F4 + +#define BT848_PLL_XCI 0x0F8 +#define BT848_PLL_X (1<<7) +#define BT848_PLL_C (1<<6) + +#define BT848_DVSIF 0x0FC + +/* Bt878 register */ + +#define BT878_DEVCTRL 0x40 +#define BT878_EN_TBFX 0x02 +#define BT878_EN_VSFX 0x04 + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.18/btcx-risc.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.18/btcx-risc.h @@ -0,0 +1,34 @@ +/* + */ +struct btcx_riscmem { + unsigned int size; + u32 *cpu; + u32 *jmp; + dma_addr_t dma; +}; + +struct btcx_skiplist { + int start; + int end; +}; + +int btcx_riscmem_alloc(struct pci_dev *pci, + struct btcx_riscmem *risc, + unsigned int size); +void btcx_riscmem_free(struct pci_dev *pci, + struct btcx_riscmem *risc); + +int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win, + struct v4l2_clip *clips, unsigned int n); +int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, + unsigned int n, int mask); +void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips); +void btcx_calc_skips(int line, int width, unsigned int *maxy, + struct btcx_skiplist *skips, unsigned int *nskips, + const struct v4l2_clip *clips, unsigned int nclips); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.22/bttvp.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.22/bttvp.h @@ -0,0 +1,480 @@ +/* + + bttv - Bt848 frame grabber driver + + bttv's *private* header file -- nobody other than bttv itself + should ever include this file. + + (c) 2000-2002 Gerd Knorr + + 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. +*/ + +#ifndef _BTTVP_H_ +#define _BTTVP_H_ + +#include +#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,17) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "bt848.h" +#include "bttv.h" +#include "btcx-risc.h" + +#ifdef __KERNEL__ + +#define FORMAT_FLAGS_DITHER 0x01 +#define FORMAT_FLAGS_PACKED 0x02 +#define FORMAT_FLAGS_PLANAR 0x04 +#define FORMAT_FLAGS_RAW 0x08 +#define FORMAT_FLAGS_CrCb 0x10 + +#define RISC_SLOT_O_VBI 4 +#define RISC_SLOT_O_FIELD 6 +#define RISC_SLOT_E_VBI 10 +#define RISC_SLOT_E_FIELD 12 +#define RISC_SLOT_LOOP 14 + +#define RESOURCE_OVERLAY 1 +#define RESOURCE_VIDEO_STREAM 2 +#define RESOURCE_VBI 4 +#define RESOURCE_VIDEO_READ 8 + +#define RAW_LINES 640 +#define RAW_BPL 1024 + +#define UNSET (-1U) + +/* Min. value in VDELAY register. */ +#define MIN_VDELAY 2 +/* Even to get Cb first, odd for Cr. */ +#define MAX_HDELAY (0x3FF & -2) +/* Limits scaled width, which must be a multiple of 4. */ +#define MAX_HACTIVE (0x3FF & -4) + +#define clamp(x, low, high) min (max (low, x), high) + +/* ---------------------------------------------------------- */ + +struct bttv_tvnorm { + int v4l2_id; + char *name; + u32 Fsc; + u16 swidth, sheight; /* scaled standard width, height */ + u16 totalwidth; + u8 adelay, bdelay, iform; + u32 scaledtwidth; + u16 hdelayx1, hactivex1; + u16 vdelay; + u8 vbipack; + u16 vtotal; + int sram; + /* ITU-R frame line number of the first VBI line we can + capture, of the first and second field. The last possible line + is determined by cropcap.bounds. */ + u16 vbistart[2]; + /* Horizontally this counts fCLKx1 samples following the leading + edge of the horizontal sync pulse, vertically ITU-R frame line + numbers of the first field times two (2, 4, 6, ... 524 or 624). */ + struct v4l2_cropcap cropcap; +}; +extern const struct bttv_tvnorm bttv_tvnorms[]; + +struct bttv_format { + char *name; + int palette; /* video4linux 1 */ + int fourcc; /* video4linux 2 */ + int btformat; /* BT848_COLOR_FMT_* */ + int btswap; /* BT848_COLOR_CTL_* */ + int depth; /* bit/pixel */ + int flags; + int hshift,vshift; /* for planar modes */ +}; + +/* ---------------------------------------------------------- */ + +struct bttv_geometry { + u8 vtc,crop,comb; + u16 width,hscale,hdelay; + u16 sheight,vscale,vdelay,vtotal; +}; + +struct bttv_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + /* bttv specific */ + const struct bttv_format *fmt; + int tvnorm; + int btformat; + int btswap; + struct bttv_geometry geo; + struct btcx_riscmem top; + struct btcx_riscmem bottom; + struct v4l2_rect crop; + unsigned int vbi_skip[2]; + unsigned int vbi_count[2]; +}; + +struct bttv_buffer_set { + struct bttv_buffer *top; /* top field buffer */ + struct bttv_buffer *bottom; /* bottom field buffer */ + unsigned int top_irq; + unsigned int frame_irq; +}; + +struct bttv_overlay { + int tvnorm; + struct v4l2_rect w; + enum v4l2_field field; + struct v4l2_clip *clips; + int nclips; + int setup_ok; +}; + +struct bttv_vbi_fmt { + struct v4l2_vbi_format fmt; + + /* fmt.start[] and count[] refer to this video standard. */ + const struct bttv_tvnorm *tvnorm; + + /* Earliest possible start of video capturing with this + v4l2_vbi_format, in struct bttv_crop.rect units. */ + __s32 end; +}; + +/* bttv-vbi.c */ +void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm); + +struct bttv_crop { + /* A cropping rectangle in struct bttv_tvnorm.cropcap units. */ + struct v4l2_rect rect; + + /* Scaled image size limits with this crop rect. Divide + max_height, but not min_height, by two when capturing + single fields. See also bttv_crop_reset() and + bttv_crop_adjust() in bttv-driver.c. */ + __s32 min_scaled_width; + __s32 min_scaled_height; + __s32 max_scaled_width; + __s32 max_scaled_height; +}; + +struct bttv_fh { + struct bttv *btv; + int resources; +#ifdef VIDIOC_G_PRIORITY + enum v4l2_priority prio; +#endif + enum v4l2_buf_type type; + + /* video capture */ + struct videobuf_queue cap; + const struct bttv_format *fmt; + int width; + int height; + + /* video overlay */ + const struct bttv_format *ovfmt; + struct bttv_overlay ov; + + /* Application called VIDIOC_S_CROP. */ + int do_crop; + + /* vbi capture */ + struct videobuf_queue vbi; + /* Current VBI capture window as seen through this fh (cannot + be global for compatibility with earlier drivers). Protected + by struct bttv.lock and struct bttv_fh.vbi.lock. */ + struct bttv_vbi_fmt vbi_fmt; +}; + +/* ---------------------------------------------------------- */ +/* bttv-risc.c */ + +/* risc code generators - capture */ +int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, + struct scatterlist *sglist, + unsigned int offset, unsigned int bpl, + unsigned int pitch, unsigned int skip_lines, + unsigned int store_lines); + +/* control dma register + risc main loop */ +void bttv_set_dma(struct bttv *btv, int override); +int bttv_risc_init_main(struct bttv *btv); +int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, + int irqflags); + +/* capture buffer handling */ +int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf); +int bttv_buffer_activate_video(struct bttv *btv, + struct bttv_buffer_set *set); +int bttv_buffer_activate_vbi(struct bttv *btv, + struct bttv_buffer *vbi); +void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv, + struct bttv_buffer *buf); + +/* overlay handling */ +int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, + const struct bttv_format *fmt, + struct bttv_buffer *buf); + + +/* ---------------------------------------------------------- */ +/* bttv-vbi.c */ + +int bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); +void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); +int bttv_vbi_set_fmt(struct bttv_fh *fh, struct v4l2_vbi_format *f); + +extern struct videobuf_queue_ops bttv_vbi_qops; + +/* ---------------------------------------------------------- */ +/* bttv-gpio.c */ + + +extern struct bus_type bttv_sub_bus_type; +int bttv_sub_add_device(struct bttv_core *core, char *name); +int bttv_sub_del_devices(struct bttv_core *core); + + +/* ---------------------------------------------------------- */ +/* bttv-driver.c */ + +/* insmod options */ +extern unsigned int bttv_verbose; +extern unsigned int bttv_debug; +extern unsigned int bttv_gpio; +extern void bttv_gpio_tracking(struct bttv *btv, char *comment); +extern int init_bttv_i2c(struct bttv *btv); +extern int fini_bttv_i2c(struct bttv *btv); + +#define bttv_printk if (bttv_verbose) printk +#define dprintk if (bttv_debug >= 1) printk +#define d2printk if (bttv_debug >= 2) printk + +#define BTTV_MAX_FBUF 0x208000 +#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ +#define BTTV_FREE_IDLE (HZ) /* one second */ + + +struct bttv_pll_info { + unsigned int pll_ifreq; /* PLL input frequency */ + unsigned int pll_ofreq; /* PLL output frequency */ + unsigned int pll_crystal; /* Crystal used for input */ + unsigned int pll_current; /* Currently programmed ofreq */ +}; + +/* for gpio-connected remote control */ +struct bttv_input { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + u32 mask_keycode; + u32 mask_keydown; +}; + +struct bttv_suspend_state { + u32 gpio_enable; + u32 gpio_data; + int disabled; + int loop_irq; + struct bttv_buffer_set video; + struct bttv_buffer *vbi; +}; + +struct bttv { + struct bttv_core c; + + /* pci device config */ + unsigned short id; + unsigned char revision; + unsigned char __iomem *bt848_mmio; /* pointer to mmio */ + + /* card configuration info */ + unsigned int cardid; /* pci subsystem id (bt878 based ones) */ + unsigned int tuner_type; /* tuner chip type */ + unsigned int tda9887_conf; + unsigned int svhs; + struct bttv_pll_info pll; + int triton1; + int gpioirq; + int (*custom_irq)(struct bttv *btv); + + int use_i2c_hw; + + /* old gpio interface */ + wait_queue_head_t gpioq; + int shutdown; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + + /* new gpio interface */ + spinlock_t gpio_lock; + + /* i2c layer */ + struct i2c_algo_bit_data i2c_algo; + struct i2c_client i2c_client; + int i2c_state, i2c_rc; + int i2c_done; + wait_queue_head_t i2c_queue; + struct i2c_client *i2c_msp34xx_client; + struct i2c_client *i2c_tvaudio_client; + + /* video4linux (1) */ + struct video_device *video_dev; + struct video_device *radio_dev; + struct video_device *vbi_dev; + + /* infrared remote */ + int has_remote; + struct card_ir *remote; + + /* locking */ + spinlock_t s_lock; + struct mutex lock; + int resources; +#ifdef VIDIOC_G_PRIORITY + struct v4l2_prio_state prio; +#endif + + /* video state */ + unsigned int input; + unsigned int audio; + unsigned int mute; + unsigned long freq; + int tvnorm,hue,contrast,bright,saturation; + struct v4l2_framebuffer fbuf; + unsigned int field_count; + + /* various options */ + int opt_combfilter; + int opt_lumafilter; + int opt_automute; + int opt_chroma_agc; + int opt_adc_crush; + int opt_vcr_hack; + int opt_whitecrush_upper; + int opt_whitecrush_lower; + int opt_uv_ratio; + int opt_full_luma_range; + int opt_coring; + + /* radio data/state */ + int has_radio; + int radio_user; + + /* miro/pinnacle + Aimslab VHX + philips matchbox (tea5757 radio tuner) support */ + int has_matchbox; + int mbox_we; + int mbox_data; + int mbox_clk; + int mbox_most; + int mbox_mask; + + /* ISA stuff (Terratec Active Radio Upgrade) */ + int mbox_ior; + int mbox_iow; + int mbox_csel; + + /* risc memory management data + - must acquire s_lock before changing these + - only the irq handler is supported to touch top + bottom + vcurr */ + struct btcx_riscmem main; + struct bttv_buffer *screen; /* overlay */ + struct list_head capture; /* video capture queue */ + struct list_head vcapture; /* vbi capture queue */ + struct bttv_buffer_set curr; /* active buffers */ + struct bttv_buffer *cvbi; /* active vbi buffer */ + int loop_irq; + int new_input; + + unsigned long cap_ctl; + unsigned long dma_on; + struct timer_list timeout; + struct bttv_suspend_state state; + + /* stats */ + unsigned int errors; + unsigned int framedrop; + unsigned int irq_total; + unsigned int irq_me; + + unsigned int users; + struct bttv_fh init; + + /* used to make dvb-bt8xx autoloadable */ + struct work_struct request_module_wk; + + /* Default (0) and current (1) video capturing and overlay + cropping parameters in bttv_tvnorm.cropcap units. Protected + by bttv.lock. */ + struct bttv_crop crop[2]; + + /* Earliest possible start of video capturing in + bttv_tvnorm.cropcap line units. Set by check_alloc_btres() + and free_btres(). Protected by bttv.lock. */ + __s32 vbi_end; + + /* Latest possible end of VBI capturing (= crop[x].rect.top when + VIDEO_RESOURCES are locked). Set by check_alloc_btres() + and free_btres(). Protected by bttv.lock. */ + __s32 crop_start; +}; + +/* our devices */ +#define BTTV_MAX 16 +extern unsigned int bttv_num; +extern struct bttv bttvs[BTTV_MAX]; + +/* private ioctls */ +#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int) +#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int) + +#endif + +#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) +#define btread(adr) readl(btv->bt848_mmio+(adr)) + +#define btand(dat,adr) btwrite((dat) & btread(adr), adr) +#define btor(dat,adr) btwrite((dat) | btread(adr), adr) +#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) + +#endif /* _BTTVP_H_ */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.22/bttv.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.22/bttv.h @@ -0,0 +1,341 @@ +/* + * + * bttv - Bt848 frame grabber driver + * + * card ID's and external interfaces of the bttv driver + * basically stuff needed by other drivers (i2c, lirc, ...) + * and is supported not to change much over time. + * + * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de) + * (c) 1999,2000 Gerd Knorr + * + */ + +#ifndef _BTTV_H_ +#define _BTTV_H_ + +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------- */ +/* exported by bttv-cards.c */ + +#define BTTV_BOARD_UNKNOWN 0x00 +#define BTTV_BOARD_MIRO 0x01 +#define BTTV_BOARD_HAUPPAUGE 0x02 +#define BTTV_BOARD_STB 0x03 +#define BTTV_BOARD_INTEL 0x04 +#define BTTV_BOARD_DIAMOND 0x05 +#define BTTV_BOARD_AVERMEDIA 0x06 +#define BTTV_BOARD_MATRIX_VISION 0x07 +#define BTTV_BOARD_FLYVIDEO 0x08 +#define BTTV_BOARD_TURBOTV 0x09 +#define BTTV_BOARD_HAUPPAUGE878 0x0a +#define BTTV_BOARD_MIROPRO 0x0b +#define BTTV_BOARD_ADSTECH_TV 0x0c +#define BTTV_BOARD_AVERMEDIA98 0x0d +#define BTTV_BOARD_VHX 0x0e +#define BTTV_BOARD_ZOLTRIX 0x0f +#define BTTV_BOARD_PIXVIEWPLAYTV 0x10 +#define BTTV_BOARD_WINVIEW_601 0x11 +#define BTTV_BOARD_AVEC_INTERCAP 0x12 +#define BTTV_BOARD_LIFE_FLYKIT 0x13 +#define BTTV_BOARD_CEI_RAFFLES 0x14 +#define BTTV_BOARD_CONFERENCETV 0x15 +#define BTTV_BOARD_PHOEBE_TVMAS 0x16 +#define BTTV_BOARD_MODTEC_205 0x17 +#define BTTV_BOARD_MAGICTVIEW061 0x18 +#define BTTV_BOARD_VOBIS_BOOSTAR 0x19 +#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a +#define BTTV_BOARD_MAXI 0x1b +#define BTTV_BOARD_TERRATV 0x1c +#define BTTV_BOARD_PXC200 0x1d +#define BTTV_BOARD_FLYVIDEO_98 0x1e +#define BTTV_BOARD_IPROTV 0x1f +#define BTTV_BOARD_INTEL_C_S_PCI 0x20 +#define BTTV_BOARD_TERRATVALUE 0x21 +#define BTTV_BOARD_WINFAST2000 0x22 +#define BTTV_BOARD_CHRONOS_VS2 0x23 +#define BTTV_BOARD_TYPHOON_TVIEW 0x24 +#define BTTV_BOARD_PXELVWPLTVPRO 0x25 +#define BTTV_BOARD_MAGICTVIEW063 0x26 +#define BTTV_BOARD_PINNACLE 0x27 +#define BTTV_BOARD_STB2 0x28 +#define BTTV_BOARD_AVPHONE98 0x29 +#define BTTV_BOARD_PV951 0x2a +#define BTTV_BOARD_ONAIR_TV 0x2b +#define BTTV_BOARD_SIGMA_TVII_FM 0x2c +#define BTTV_BOARD_MATRIX_VISION2 0x2d +#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e +#define BTTV_BOARD_TERRATVRADIO 0x2f +#define BTTV_BOARD_DYNALINK 0x30 +#define BTTV_BOARD_GVBCTV3PCI 0x31 +#define BTTV_BOARD_PXELVWPLTVPAK 0x32 +#define BTTV_BOARD_EAGLE 0x33 +#define BTTV_BOARD_PINNACLEPRO 0x34 +#define BTTV_BOARD_TVIEW_RDS_FM 0x35 +#define BTTV_BOARD_LIFETEC_9415 0x36 +#define BTTV_BOARD_BESTBUY_EASYTV 0x37 +#define BTTV_BOARD_FLYVIDEO_98FM 0x38 +#define BTTV_BOARD_GRANDTEC 0x39 +#define BTTV_BOARD_ASKEY_CPH060 0x3a +#define BTTV_BOARD_ASKEY_CPH03X 0x3b +#define BTTV_BOARD_MM100PCTV 0x3c +#define BTTV_BOARD_GMV1 0x3d +#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e +#define BTTV_BOARD_ATI_TVWONDER 0x3f +#define BTTV_BOARD_ATI_TVWONDERVE 0x40 +#define BTTV_BOARD_FLYVIDEO2000 0x41 +#define BTTV_BOARD_TERRATVALUER 0x42 +#define BTTV_BOARD_GVBCTV4PCI 0x43 +#define BTTV_BOARD_VOODOOTV_FM 0x44 +#define BTTV_BOARD_AIMMS 0x45 +#define BTTV_BOARD_PV_BT878P_PLUS 0x46 +#define BTTV_BOARD_FLYVIDEO98EZ 0x47 +#define BTTV_BOARD_PV_BT878P_9B 0x48 +#define BTTV_BOARD_SENSORAY311 0x49 +#define BTTV_BOARD_RV605 0x4a +#define BTTV_BOARD_POWERCLR_MTV878 0x4b +#define BTTV_BOARD_WINDVR 0x4c +#define BTTV_BOARD_GRANDTEC_MULTI 0x4d +#define BTTV_BOARD_KWORLD 0x4e +#define BTTV_BOARD_DSP_TCVIDEO 0x4f +#define BTTV_BOARD_HAUPPAUGEPVR 0x50 +#define BTTV_BOARD_GVBCTV5PCI 0x51 +#define BTTV_BOARD_OSPREY1x0 0x52 +#define BTTV_BOARD_OSPREY1x0_848 0x53 +#define BTTV_BOARD_OSPREY101_848 0x54 +#define BTTV_BOARD_OSPREY1x1 0x55 +#define BTTV_BOARD_OSPREY1x1_SVID 0x56 +#define BTTV_BOARD_OSPREY2xx 0x57 +#define BTTV_BOARD_OSPREY2x0_SVID 0x58 +#define BTTV_BOARD_OSPREY2x0 0x59 +#define BTTV_BOARD_OSPREY500 0x5a +#define BTTV_BOARD_OSPREY540 0x5b +#define BTTV_BOARD_OSPREY2000 0x5c +#define BTTV_BOARD_IDS_EAGLE 0x5d +#define BTTV_BOARD_PINNACLESAT 0x5e +#define BTTV_BOARD_FORMAC_PROTV 0x5f +#define BTTV_BOARD_MACHTV 0x60 +#define BTTV_BOARD_EURESYS_PICOLO 0x61 +#define BTTV_BOARD_PV150 0x62 +#define BTTV_BOARD_AD_TVK503 0x63 +#define BTTV_BOARD_HERCULES_SM_TV 0x64 +#define BTTV_BOARD_PACETV 0x65 +#define BTTV_BOARD_IVC200 0x66 +#define BTTV_BOARD_XGUARD 0x67 +#define BTTV_BOARD_NEBULA_DIGITV 0x68 +#define BTTV_BOARD_PV143 0x69 +#define BTTV_BOARD_VD009X1_MINIDIN 0x6a +#define BTTV_BOARD_VD009X1_COMBI 0x6b +#define BTTV_BOARD_VD009_MINIDIN 0x6c +#define BTTV_BOARD_VD009_COMBI 0x6d +#define BTTV_BOARD_IVC100 0x6e +#define BTTV_BOARD_IVC120 0x6f +#define BTTV_BOARD_PC_HDTV 0x70 +#define BTTV_BOARD_TWINHAN_DST 0x71 +#define BTTV_BOARD_WINFASTVC100 0x72 +#define BTTV_BOARD_TEV560 0x73 +#define BTTV_BOARD_SIMUS_GVC1100 0x74 +#define BTTV_BOARD_NGSTV_PLUS 0x75 +#define BTTV_BOARD_LMLBT4 0x76 +#define BTTV_BOARD_TEKRAM_M205 0x77 +#define BTTV_BOARD_CONTVFMI 0x78 +#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 +#define BTTV_BOARD_SPIRIT_TV 0x7a +#define BTTV_BOARD_AVDVBT_771 0x7b +#define BTTV_BOARD_AVDVBT_761 0x7c +#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d +#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e +#define BTTV_BOARD_APAC_VIEWCOMP 0x7f +#define BTTV_BOARD_DVICO_DVBT_LITE 0x80 +#define BTTV_BOARD_VGEAR_MYVCD 0x81 +#define BTTV_BOARD_SUPER_TV 0x82 +#define BTTV_BOARD_TIBET_CS16 0x83 +#define BTTV_BOARD_KODICOM_4400R 0x84 +#define BTTV_BOARD_KODICOM_4400R_SL 0x85 +#define BTTV_BOARD_ADLINK_RTV24 0x86 +#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 +#define BTTV_BOARD_ACORP_Y878F 0x88 +#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89 +#define BTTV_BOARD_PV_BT878P_2E 0x8a +#define BTTV_BOARD_PV_M4900 0x8b +#define BTTV_BOARD_OSPREY440 0x8c +#define BTTV_BOARD_ASOUND_SKYEYE 0x8d +#define BTTV_BOARD_SABRENT_TVFM 0x8e +#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f +#define BTTV_BOARD_MACHTV_MAGICTV 0x90 +#define BTTV_BOARD_SSAI_SECURITY 0x91 +#define BTTV_BOARD_SSAI_ULTRASOUND 0x92 + +/* more card-specific defines */ +#define PT2254_L_CHANNEL 0x10 +#define PT2254_R_CHANNEL 0x08 +#define PT2254_DBS_IN_2 0x400 +#define PT2254_DBS_IN_10 0x20000 +#define WINVIEW_PT2254_CLK 0x40 +#define WINVIEW_PT2254_DATA 0x20 +#define WINVIEW_PT2254_STROBE 0x80 + +/* digital_mode */ +#define DIGITAL_MODE_VIDEO 1 +#define DIGITAL_MODE_CAMERA 2 + +struct bttv_core { + /* device structs */ + struct pci_dev *pci; + struct i2c_adapter i2c_adap; + struct list_head subs; /* struct bttv_sub_device */ + + /* device config */ + unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ + unsigned int type; /* card type (pointer into tvcards[]) */ + char name[8]; /* dev name */ +}; + +struct bttv; + + +struct tvcard +{ + char *name; + unsigned int video_inputs; + unsigned int audio_inputs; + unsigned int tuner; + unsigned int svhs; + unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO + u32 gpiomask; + u32 muxsel[16]; + u32 gpiomux[4]; /* Tuner, Radio, external, internal */ + u32 gpiomute; /* GPIO mute setting */ + u32 gpiomask2; /* GPIO MUX mask */ + + /* i2c audio flags */ + unsigned int no_msp34xx:1; + unsigned int no_tda9875:1; + unsigned int no_tda7432:1; + unsigned int needs_tvaudio:1; + unsigned int msp34xx_alt:1; + + /* flag: video pci function is unused */ + unsigned int no_video:1; + unsigned int has_dvb:1; + unsigned int has_remote:1; + unsigned int no_gpioirq:1; + + /* other settings */ + unsigned int pll; +#define PLL_NONE 0 +#define PLL_28 1 +#define PLL_35 2 + + unsigned int tuner_type; + unsigned int tuner_addr; + unsigned int radio_addr; + + unsigned int has_radio; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + void (*muxsel_hook)(struct bttv *btv, unsigned int input); +}; + +extern struct tvcard bttv_tvcards[]; + +/* identification / initialization of the card */ +extern void bttv_idcard(struct bttv *btv); +extern void bttv_init_card1(struct bttv *btv); +extern void bttv_init_card2(struct bttv *btv); + +/* card-specific funtions */ +extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); +extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); + +/* extra tweaks for some chipsets */ +extern void bttv_check_chipset(void); +extern int bttv_handle_chipset(struct bttv *btv); + +/* ---------------------------------------------------------- */ +/* exported by bttv-if.c */ + +/* this obsolete -- please use the sysfs-based + interface below for new code */ + +extern struct pci_dev* bttv_get_pcidev(unsigned int card); + +/* sets GPOE register (BT848_GPIO_OUT_EN) to new value: + data | (current_GPOE_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_gpio_enable(unsigned int card, + unsigned long mask, unsigned long data); + +/* fills data with GPDATA register contents + returns negative value if error occurred +*/ +extern int bttv_read_gpio(unsigned int card, unsigned long *data); + +/* sets GPDATA register to new value: + (data & mask) | (current_GPDATA_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_write_gpio(unsigned int card, + unsigned long mask, unsigned long data); + + + + +/* ---------------------------------------------------------- */ +/* sysfs/driver-moded based gpio access interface */ + + +struct bttv_sub_device { + struct device dev; + struct bttv_core *core; + struct list_head list; +}; +#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev) + +struct bttv_sub_driver { + struct device_driver drv; + char wanted[BUS_ID_SIZE]; + int (*probe)(struct bttv_sub_device *sub); + void (*remove)(struct bttv_sub_device *sub); +}; +#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) + +int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); +int bttv_sub_unregister(struct bttv_sub_driver *drv); + +/* gpio access functions */ +void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits); +u32 bttv_gpio_read(struct bttv_core *core); +void bttv_gpio_write(struct bttv_core *core, u32 value); +void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); + +#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits) +#define gpio_read() bttv_gpio_read(&btv->c) +#define gpio_write(value) bttv_gpio_write(&btv->c, value) +#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) + + +/* ---------------------------------------------------------- */ +/* i2c */ + +extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); +extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); +extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, + unsigned char b2, int both); +extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); + +extern int bttv_input_init(struct bttv *dev); +extern void bttv_input_fini(struct bttv *dev); +extern void bttv_input_irq(struct bttv *dev); + +#endif /* _BTTV_H_ */ +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.22/bt848.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.22/bt848.h @@ -0,0 +1,366 @@ +/* + bt848.h - Bt848 register offsets + + Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + + 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. +*/ + +#ifndef _BT848_H_ +#define _BT848_H_ + +#ifndef PCI_VENDOR_ID_BROOKTREE +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#endif +#ifndef PCI_DEVICE_ID_BT848 +#define PCI_DEVICE_ID_BT848 0x350 +#endif +#ifndef PCI_DEVICE_ID_BT849 +#define PCI_DEVICE_ID_BT849 0x351 +#endif +#ifndef PCI_DEVICE_ID_BT878 +#define PCI_DEVICE_ID_BT878 0x36e +#endif +#ifndef PCI_DEVICE_ID_BT879 +#define PCI_DEVICE_ID_BT879 0x36f +#endif + + +/* Brooktree 848 registers */ + +#define BT848_DSTATUS 0x000 +#define BT848_DSTATUS_PRES (1<<7) +#define BT848_DSTATUS_HLOC (1<<6) +#define BT848_DSTATUS_FIELD (1<<5) +#define BT848_DSTATUS_NUML (1<<4) +#define BT848_DSTATUS_CSEL (1<<3) +#define BT848_DSTATUS_PLOCK (1<<2) +#define BT848_DSTATUS_LOF (1<<1) +#define BT848_DSTATUS_COF (1<<0) + +#define BT848_IFORM 0x004 +#define BT848_IFORM_HACTIVE (1<<7) +#define BT848_IFORM_MUXSEL (3<<5) +#define BT848_IFORM_MUX0 (2<<5) +#define BT848_IFORM_MUX1 (3<<5) +#define BT848_IFORM_MUX2 (1<<5) +#define BT848_IFORM_XTSEL (3<<3) +#define BT848_IFORM_XT0 (1<<3) +#define BT848_IFORM_XT1 (2<<3) +#define BT848_IFORM_XTAUTO (3<<3) +#define BT848_IFORM_XTBOTH (3<<3) +#define BT848_IFORM_NTSC 1 +#define BT848_IFORM_NTSC_J 2 +#define BT848_IFORM_PAL_BDGHI 3 +#define BT848_IFORM_PAL_M 4 +#define BT848_IFORM_PAL_N 5 +#define BT848_IFORM_SECAM 6 +#define BT848_IFORM_PAL_NC 7 +#define BT848_IFORM_AUTO 0 +#define BT848_IFORM_NORM 7 + +#define BT848_TDEC 0x008 +#define BT848_TDEC_DEC_FIELD (1<<7) +#define BT848_TDEC_FLDALIGN (1<<6) +#define BT848_TDEC_DEC_RAT (0x1f) + +#define BT848_E_CROP 0x00C +#define BT848_O_CROP 0x08C + +#define BT848_E_VDELAY_LO 0x010 +#define BT848_O_VDELAY_LO 0x090 + +#define BT848_E_VACTIVE_LO 0x014 +#define BT848_O_VACTIVE_LO 0x094 + +#define BT848_E_HDELAY_LO 0x018 +#define BT848_O_HDELAY_LO 0x098 + +#define BT848_E_HACTIVE_LO 0x01C +#define BT848_O_HACTIVE_LO 0x09C + +#define BT848_E_HSCALE_HI 0x020 +#define BT848_O_HSCALE_HI 0x0A0 + +#define BT848_E_HSCALE_LO 0x024 +#define BT848_O_HSCALE_LO 0x0A4 + +#define BT848_BRIGHT 0x028 + +#define BT848_E_CONTROL 0x02C +#define BT848_O_CONTROL 0x0AC +#define BT848_CONTROL_LNOTCH (1<<7) +#define BT848_CONTROL_COMP (1<<6) +#define BT848_CONTROL_LDEC (1<<5) +#define BT848_CONTROL_CBSENSE (1<<4) +#define BT848_CONTROL_CON_MSB (1<<2) +#define BT848_CONTROL_SAT_U_MSB (1<<1) +#define BT848_CONTROL_SAT_V_MSB (1<<0) + +#define BT848_CONTRAST_LO 0x030 +#define BT848_SAT_U_LO 0x034 +#define BT848_SAT_V_LO 0x038 +#define BT848_HUE 0x03C + +#define BT848_E_SCLOOP 0x040 +#define BT848_O_SCLOOP 0x0C0 +#define BT848_SCLOOP_CAGC (1<<6) +#define BT848_SCLOOP_CKILL (1<<5) +#define BT848_SCLOOP_HFILT_AUTO (0<<3) +#define BT848_SCLOOP_HFILT_CIF (1<<3) +#define BT848_SCLOOP_HFILT_QCIF (2<<3) +#define BT848_SCLOOP_HFILT_ICON (3<<3) + +#define BT848_SCLOOP_PEAK (1<<7) +#define BT848_SCLOOP_HFILT_MINP (1<<3) +#define BT848_SCLOOP_HFILT_MEDP (2<<3) +#define BT848_SCLOOP_HFILT_MAXP (3<<3) + + +#define BT848_OFORM 0x048 +#define BT848_OFORM_RANGE (1<<7) +#define BT848_OFORM_CORE0 (0<<5) +#define BT848_OFORM_CORE8 (1<<5) +#define BT848_OFORM_CORE16 (2<<5) +#define BT848_OFORM_CORE32 (3<<5) + +#define BT848_E_VSCALE_HI 0x04C +#define BT848_O_VSCALE_HI 0x0CC +#define BT848_VSCALE_YCOMB (1<<7) +#define BT848_VSCALE_COMB (1<<6) +#define BT848_VSCALE_INT (1<<5) +#define BT848_VSCALE_HI 15 + +#define BT848_E_VSCALE_LO 0x050 +#define BT848_O_VSCALE_LO 0x0D0 +#define BT848_TEST 0x054 +#define BT848_ADELAY 0x060 +#define BT848_BDELAY 0x064 + +#define BT848_ADC 0x068 +#define BT848_ADC_RESERVED (2<<6) +#define BT848_ADC_SYNC_T (1<<5) +#define BT848_ADC_AGC_EN (1<<4) +#define BT848_ADC_CLK_SLEEP (1<<3) +#define BT848_ADC_Y_SLEEP (1<<2) +#define BT848_ADC_C_SLEEP (1<<1) +#define BT848_ADC_CRUSH (1<<0) + +#define BT848_WC_UP 0x044 +#define BT848_WC_DOWN 0x078 + +#define BT848_E_VTC 0x06C +#define BT848_O_VTC 0x0EC +#define BT848_VTC_HSFMT (1<<7) +#define BT848_VTC_VFILT_2TAP 0 +#define BT848_VTC_VFILT_3TAP 1 +#define BT848_VTC_VFILT_4TAP 2 +#define BT848_VTC_VFILT_5TAP 3 + +#define BT848_SRESET 0x07C + +#define BT848_COLOR_FMT 0x0D4 +#define BT848_COLOR_FMT_O_RGB32 (0<<4) +#define BT848_COLOR_FMT_O_RGB24 (1<<4) +#define BT848_COLOR_FMT_O_RGB16 (2<<4) +#define BT848_COLOR_FMT_O_RGB15 (3<<4) +#define BT848_COLOR_FMT_O_YUY2 (4<<4) +#define BT848_COLOR_FMT_O_BtYUV (5<<4) +#define BT848_COLOR_FMT_O_Y8 (6<<4) +#define BT848_COLOR_FMT_O_RGB8 (7<<4) +#define BT848_COLOR_FMT_O_YCrCb422 (8<<4) +#define BT848_COLOR_FMT_O_YCrCb411 (9<<4) +#define BT848_COLOR_FMT_O_RAW (14<<4) +#define BT848_COLOR_FMT_E_RGB32 0 +#define BT848_COLOR_FMT_E_RGB24 1 +#define BT848_COLOR_FMT_E_RGB16 2 +#define BT848_COLOR_FMT_E_RGB15 3 +#define BT848_COLOR_FMT_E_YUY2 4 +#define BT848_COLOR_FMT_E_BtYUV 5 +#define BT848_COLOR_FMT_E_Y8 6 +#define BT848_COLOR_FMT_E_RGB8 7 +#define BT848_COLOR_FMT_E_YCrCb422 8 +#define BT848_COLOR_FMT_E_YCrCb411 9 +#define BT848_COLOR_FMT_E_RAW 14 + +#define BT848_COLOR_FMT_RGB32 0x00 +#define BT848_COLOR_FMT_RGB24 0x11 +#define BT848_COLOR_FMT_RGB16 0x22 +#define BT848_COLOR_FMT_RGB15 0x33 +#define BT848_COLOR_FMT_YUY2 0x44 +#define BT848_COLOR_FMT_BtYUV 0x55 +#define BT848_COLOR_FMT_Y8 0x66 +#define BT848_COLOR_FMT_RGB8 0x77 +#define BT848_COLOR_FMT_YCrCb422 0x88 +#define BT848_COLOR_FMT_YCrCb411 0x99 +#define BT848_COLOR_FMT_RAW 0xee + +#define BT848_VTOTAL_LO 0xB0 +#define BT848_VTOTAL_HI 0xB4 + +#define BT848_COLOR_CTL 0x0D8 +#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7) +#define BT848_COLOR_CTL_COLOR_BARS (1<<6) +#define BT848_COLOR_CTL_RGB_DED (1<<5) +#define BT848_COLOR_CTL_GAMMA (1<<4) +#define BT848_COLOR_CTL_WSWAP_ODD (1<<3) +#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2) +#define BT848_COLOR_CTL_BSWAP_ODD (1<<1) +#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0) + +#define BT848_CAP_CTL 0x0DC +#define BT848_CAP_CTL_DITH_FRAME (1<<4) +#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3) +#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2) +#define BT848_CAP_CTL_CAPTURE_ODD (1<<1) +#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0) + +#define BT848_VBI_PACK_SIZE 0x0E0 + +#define BT848_VBI_PACK_DEL 0x0E4 +#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc +#define BT848_VBI_PACK_DEL_EXT_FRAME 2 +#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1 + + +#define BT848_INT_STAT 0x100 +#define BT848_INT_MASK 0x104 + +#define BT848_INT_ETBF (1<<23) + +#define BT848_INT_RISCS (0xf<<28) +#define BT848_INT_RISC_EN (1<<27) +#define BT848_INT_RACK (1<<25) +#define BT848_INT_FIELD (1<<24) +#define BT848_INT_SCERR (1<<19) +#define BT848_INT_OCERR (1<<18) +#define BT848_INT_PABORT (1<<17) +#define BT848_INT_RIPERR (1<<16) +#define BT848_INT_PPERR (1<<15) +#define BT848_INT_FDSR (1<<14) +#define BT848_INT_FTRGT (1<<13) +#define BT848_INT_FBUS (1<<12) +#define BT848_INT_RISCI (1<<11) +#define BT848_INT_GPINT (1<<9) +#define BT848_INT_I2CDONE (1<<8) +#define BT848_INT_VPRES (1<<5) +#define BT848_INT_HLOCK (1<<4) +#define BT848_INT_OFLOW (1<<3) +#define BT848_INT_HSYNC (1<<2) +#define BT848_INT_VSYNC (1<<1) +#define BT848_INT_FMTCHG (1<<0) + + +#define BT848_GPIO_DMA_CTL 0x10C +#define BT848_GPIO_DMA_CTL_GPINTC (1<<15) +#define BT848_GPIO_DMA_CTL_GPINTI (1<<14) +#define BT848_GPIO_DMA_CTL_GPWEC (1<<13) +#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11) +#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10) +#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6) +#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4) +#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2) +#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2) +#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2) +#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2) +#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1) +#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0) + +#define BT848_I2C 0x110 +#define BT878_I2C_MODE (1<<7) +#define BT878_I2C_RATE (1<<6) +#define BT878_I2C_NOSTOP (1<<5) +#define BT878_I2C_NOSTART (1<<4) +#define BT848_I2C_DIV (0xf<<4) +#define BT848_I2C_SYNC (1<<3) +#define BT848_I2C_W3B (1<<2) +#define BT848_I2C_SCL (1<<1) +#define BT848_I2C_SDA (1<<0) + +#define BT848_RISC_STRT_ADD 0x114 +#define BT848_GPIO_OUT_EN 0x118 +#define BT848_GPIO_REG_INP 0x11C +#define BT848_RISC_COUNT 0x120 +#define BT848_GPIO_DATA 0x200 + + +/* Bt848 RISC commands */ + +/* only for the SYNC RISC command */ +#define BT848_FIFO_STATUS_FM1 0x06 +#define BT848_FIFO_STATUS_FM3 0x0e +#define BT848_FIFO_STATUS_SOL 0x02 +#define BT848_FIFO_STATUS_EOL4 0x01 +#define BT848_FIFO_STATUS_EOL3 0x0d +#define BT848_FIFO_STATUS_EOL2 0x09 +#define BT848_FIFO_STATUS_EOL1 0x05 +#define BT848_FIFO_STATUS_VRE 0x04 +#define BT848_FIFO_STATUS_VRO 0x0c +#define BT848_FIFO_STATUS_PXV 0x00 + +#define BT848_RISC_RESYNC (1<<15) + +/* WRITE and SKIP */ +/* disable which bytes of each DWORD */ +#define BT848_RISC_BYTE0 (1U<<12) +#define BT848_RISC_BYTE1 (1U<<13) +#define BT848_RISC_BYTE2 (1U<<14) +#define BT848_RISC_BYTE3 (1U<<15) +#define BT848_RISC_BYTE_ALL (0x0fU<<12) +#define BT848_RISC_BYTE_NONE 0 +/* cause RISCI */ +#define BT848_RISC_IRQ (1U<<24) +/* RISC command is last one in this line */ +#define BT848_RISC_EOL (1U<<26) +/* RISC command is first one in this line */ +#define BT848_RISC_SOL (1U<<27) + +#define BT848_RISC_WRITE (0x01U<<28) +#define BT848_RISC_SKIP (0x02U<<28) +#define BT848_RISC_WRITEC (0x05U<<28) +#define BT848_RISC_JUMP (0x07U<<28) +#define BT848_RISC_SYNC (0x08U<<28) + +#define BT848_RISC_WRITE123 (0x09U<<28) +#define BT848_RISC_SKIP123 (0x0aU<<28) +#define BT848_RISC_WRITE1S23 (0x0bU<<28) + + +/* Bt848A and higher only !! */ +#define BT848_TGLB 0x080 +#define BT848_TGCTRL 0x084 +#define BT848_FCAP 0x0E8 +#define BT848_PLL_F_LO 0x0F0 +#define BT848_PLL_F_HI 0x0F4 + +#define BT848_PLL_XCI 0x0F8 +#define BT848_PLL_X (1<<7) +#define BT848_PLL_C (1<<6) + +#define BT848_DVSIF 0x0FC + +/* Bt878 register */ + +#define BT878_DEVCTRL 0x40 +#define BT878_EN_TBFX 0x02 +#define BT878_EN_VSFX 0x04 + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.22/btcx-risc.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.22/btcx-risc.h @@ -0,0 +1,34 @@ +/* + */ +struct btcx_riscmem { + unsigned int size; + u32 *cpu; + u32 *jmp; + dma_addr_t dma; +}; + +struct btcx_skiplist { + int start; + int end; +}; + +int btcx_riscmem_alloc(struct pci_dev *pci, + struct btcx_riscmem *risc, + unsigned int size); +void btcx_riscmem_free(struct pci_dev *pci, + struct btcx_riscmem *risc); + +int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win, + struct v4l2_clip *clips, unsigned int n); +int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, + unsigned int n, int mask); +void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips); +void btcx_calc_skips(int line, int width, unsigned int *maxy, + struct btcx_skiplist *skips, unsigned int *nskips, + const struct v4l2_clip *clips, unsigned int nclips); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.17/bttvp.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.17/bttvp.h @@ -0,0 +1,413 @@ +/* + + bttv - Bt848 frame grabber driver + + bttv's *private* header file -- nobody other than bttv itself + should ever include this file. + + (c) 2000-2002 Gerd Knorr + + 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. +*/ + +#ifndef _BTTVP_H_ +#define _BTTVP_H_ + +#include +#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + +#include "bt848.h" +#include "bttv.h" +#include "btcx-risc.h" + +#ifdef __KERNEL__ + +#define FORMAT_FLAGS_DITHER 0x01 +#define FORMAT_FLAGS_PACKED 0x02 +#define FORMAT_FLAGS_PLANAR 0x04 +#define FORMAT_FLAGS_RAW 0x08 +#define FORMAT_FLAGS_CrCb 0x10 + +#define RISC_SLOT_O_VBI 4 +#define RISC_SLOT_O_FIELD 6 +#define RISC_SLOT_E_VBI 10 +#define RISC_SLOT_E_FIELD 12 +#define RISC_SLOT_LOOP 14 + +#define RESOURCE_OVERLAY 1 +#define RESOURCE_VIDEO 2 +#define RESOURCE_VBI 4 + +#define RAW_LINES 640 +#define RAW_BPL 1024 + +#define UNSET (-1U) + +#define clamp(x, low, high) min (max (low, x), high) + +/* ---------------------------------------------------------- */ + +struct bttv_tvnorm { + int v4l2_id; + char *name; + u32 Fsc; + u16 swidth, sheight; /* scaled standard width, height */ + u16 totalwidth; + u8 adelay, bdelay, iform; + u32 scaledtwidth; + u16 hdelayx1, hactivex1; + u16 vdelay; + u8 vbipack; + u16 vtotal; + int sram; + /* ITU-R frame line number of the first VBI line we can + capture, of the first and second field. */ + u16 vbistart[2]; +}; +extern const struct bttv_tvnorm bttv_tvnorms[]; + +struct bttv_format { + char *name; + int palette; /* video4linux 1 */ + int fourcc; /* video4linux 2 */ + int btformat; /* BT848_COLOR_FMT_* */ + int btswap; /* BT848_COLOR_CTL_* */ + int depth; /* bit/pixel */ + int flags; + int hshift,vshift; /* for planar modes */ +}; + +/* ---------------------------------------------------------- */ + +struct bttv_geometry { + u8 vtc,crop,comb; + u16 width,hscale,hdelay; + u16 sheight,vscale,vdelay,vtotal; +}; + +struct bttv_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + + /* bttv specific */ + const struct bttv_format *fmt; + int tvnorm; + int btformat; + int btswap; + struct bttv_geometry geo; + struct btcx_riscmem top; + struct btcx_riscmem bottom; +}; + +struct bttv_buffer_set { + struct bttv_buffer *top; /* top field buffer */ + struct bttv_buffer *bottom; /* bottom field buffer */ + unsigned int top_irq; + unsigned int frame_irq; +}; + +struct bttv_overlay { + int tvnorm; + struct v4l2_rect w; + enum v4l2_field field; + struct v4l2_clip *clips; + int nclips; + int setup_ok; +}; + +struct bttv_fh { + struct bttv *btv; + int resources; +#ifdef VIDIOC_G_PRIORITY + enum v4l2_priority prio; +#endif + enum v4l2_buf_type type; + + /* video capture */ + struct videobuf_queue cap; + const struct bttv_format *fmt; + int width; + int height; + + /* current settings */ + const struct bttv_format *ovfmt; + struct bttv_overlay ov; + + /* video overlay */ + struct videobuf_queue vbi; + int lines; +}; + +/* ---------------------------------------------------------- */ +/* bttv-risc.c */ + +/* risc code generators - capture */ +int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc, + struct scatterlist *sglist, + unsigned int offset, unsigned int bpl, + unsigned int pitch, unsigned int lines); + +/* control dma register + risc main loop */ +void bttv_set_dma(struct bttv *btv, int override); +int bttv_risc_init_main(struct bttv *btv); +int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc, + int irqflags); + +/* capture buffer handling */ +int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf); +int bttv_buffer_activate_video(struct bttv *btv, + struct bttv_buffer_set *set); +int bttv_buffer_activate_vbi(struct bttv *btv, + struct bttv_buffer *vbi); +void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv, + struct bttv_buffer *buf); + +/* overlay handling */ +int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, + const struct bttv_format *fmt, + struct bttv_buffer *buf); + + +/* ---------------------------------------------------------- */ +/* bttv-vbi.c */ + +void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f); +void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines); + +extern struct videobuf_queue_ops bttv_vbi_qops; + +/* ---------------------------------------------------------- */ +/* bttv-gpio.c */ + + +extern struct bus_type bttv_sub_bus_type; +int bttv_sub_add_device(struct bttv_core *core, char *name); +int bttv_sub_del_devices(struct bttv_core *core); +void bttv_gpio_irq(struct bttv_core *core); + + +/* ---------------------------------------------------------- */ +/* bttv-driver.c */ + +/* insmod options */ +extern unsigned int bttv_verbose; +extern unsigned int bttv_debug; +extern unsigned int bttv_gpio; +extern void bttv_gpio_tracking(struct bttv *btv, char *comment); +extern int init_bttv_i2c(struct bttv *btv); +extern int fini_bttv_i2c(struct bttv *btv); + +#define bttv_printk if (bttv_verbose) printk +#define dprintk if (bttv_debug >= 1) printk +#define d2printk if (bttv_debug >= 2) printk + +#define BTTV_MAX_FBUF 0x208000 +#define VBIBUF_SIZE (2048*VBI_MAXLINES*2) +#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */ +#define BTTV_FREE_IDLE (HZ) /* one second */ + + +struct bttv_pll_info { + unsigned int pll_ifreq; /* PLL input frequency */ + unsigned int pll_ofreq; /* PLL output frequency */ + unsigned int pll_crystal; /* Crystal used for input */ + unsigned int pll_current; /* Currently programmed ofreq */ +}; + +/* for gpio-connected remote control */ +struct bttv_input { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + u32 mask_keycode; + u32 mask_keydown; +}; + +struct bttv_suspend_state { + u32 gpio_enable; + u32 gpio_data; + int disabled; + int loop_irq; + struct bttv_buffer_set video; + struct bttv_buffer *vbi; +}; + +struct bttv { + struct bttv_core c; + + /* pci device config */ + unsigned short id; + unsigned char revision; + unsigned char __iomem *bt848_mmio; /* pointer to mmio */ + + /* card configuration info */ + unsigned int cardid; /* pci subsystem id (bt878 based ones) */ + unsigned int tuner_type; /* tuner chip type */ + unsigned int tda9887_conf; + unsigned int svhs; + struct bttv_pll_info pll; + int triton1; + int gpioirq; + int (*custom_irq)(struct bttv *btv); + + int use_i2c_hw; + + /* old gpio interface */ + wait_queue_head_t gpioq; + int shutdown; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + + /* new gpio interface */ + spinlock_t gpio_lock; + + /* i2c layer */ + struct i2c_algo_bit_data i2c_algo; + struct i2c_client i2c_client; + int i2c_state, i2c_rc; + int i2c_done; + wait_queue_head_t i2c_queue; + struct i2c_client *i2c_msp34xx_client; + struct i2c_client *i2c_tvaudio_client; + + /* video4linux (1) */ + struct video_device *video_dev; + struct video_device *radio_dev; + struct video_device *vbi_dev; + + /* infrared remote */ + int has_remote; + struct bttv_ir *remote; + + /* locking */ + spinlock_t s_lock; + struct mutex lock; + int resources; + struct mutex reslock; +#ifdef VIDIOC_G_PRIORITY + struct v4l2_prio_state prio; +#endif + + /* video state */ + unsigned int input; + unsigned int audio; + unsigned int mute; + unsigned long freq; + int tvnorm,hue,contrast,bright,saturation; + struct v4l2_framebuffer fbuf; + unsigned int field_count; + + /* various options */ + int opt_combfilter; + int opt_lumafilter; + int opt_automute; + int opt_chroma_agc; + int opt_adc_crush; + int opt_vcr_hack; + int opt_whitecrush_upper; + int opt_whitecrush_lower; + int opt_uv_ratio; + int opt_full_luma_range; + int opt_coring; + + /* radio data/state */ + int has_radio; + int radio_user; + + /* miro/pinnacle + Aimslab VHX + philips matchbox (tea5757 radio tuner) support */ + int has_matchbox; + int mbox_we; + int mbox_data; + int mbox_clk; + int mbox_most; + int mbox_mask; + + /* ISA stuff (Terratec Active Radio Upgrade) */ + int mbox_ior; + int mbox_iow; + int mbox_csel; + + /* risc memory management data + - must aquire s_lock before changing these + - only the irq handler is supported to touch top + bottom + vcurr */ + struct btcx_riscmem main; + struct bttv_buffer *screen; /* overlay */ + struct list_head capture; /* video capture queue */ + struct list_head vcapture; /* vbi capture queue */ + struct bttv_buffer_set curr; /* active buffers */ + struct bttv_buffer *cvbi; /* active vbi buffer */ + int loop_irq; + int new_input; + + unsigned long cap_ctl; + unsigned long dma_on; + struct timer_list timeout; + struct bttv_suspend_state state; + + /* stats */ + unsigned int errors; + unsigned int framedrop; + unsigned int irq_total; + unsigned int irq_me; + + unsigned int users; + struct bttv_fh init; +}; + +/* our devices */ +#define BTTV_MAX 16 +extern unsigned int bttv_num; +extern struct bttv bttvs[BTTV_MAX]; + +/* private ioctls */ +#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int) +#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int) + +#endif + +#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) +#define btread(adr) readl(btv->bt848_mmio+(adr)) + +#define btand(dat,adr) btwrite((dat) & btread(adr), adr) +#define btor(dat,adr) btwrite((dat) | btread(adr), adr) +#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) + +#endif /* _BTTVP_H_ */ + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.17/bttv.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.17/bttv.h @@ -0,0 +1,390 @@ +/* + * + * bttv - Bt848 frame grabber driver + * + * card ID's and external interfaces of the bttv driver + * basically stuff needed by other drivers (i2c, lirc, ...) + * and is supported not to change much over time. + * + * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de) + * (c) 1999,2000 Gerd Knorr + * + */ + +#ifndef _BTTV_H_ +#define _BTTV_H_ + +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------- */ +/* exported by bttv-cards.c */ + +#define BTTV_BOARD_UNKNOWN 0x00 +#define BTTV_BOARD_MIRO 0x01 +#define BTTV_BOARD_HAUPPAUGE 0x02 +#define BTTV_BOARD_STB 0x03 +#define BTTV_BOARD_INTEL 0x04 +#define BTTV_BOARD_DIAMOND 0x05 +#define BTTV_BOARD_AVERMEDIA 0x06 +#define BTTV_BOARD_MATRIX_VISION 0x07 +#define BTTV_BOARD_FLYVIDEO 0x08 +#define BTTV_BOARD_TURBOTV 0x09 +#define BTTV_BOARD_HAUPPAUGE878 0x0a +#define BTTV_BOARD_MIROPRO 0x0b +#define BTTV_BOARD_ADSTECH_TV 0x0c +#define BTTV_BOARD_AVERMEDIA98 0x0d +#define BTTV_BOARD_VHX 0x0e +#define BTTV_BOARD_ZOLTRIX 0x0f +#define BTTV_BOARD_PIXVIEWPLAYTV 0x10 +#define BTTV_BOARD_WINVIEW_601 0x11 +#define BTTV_BOARD_AVEC_INTERCAP 0x12 +#define BTTV_BOARD_LIFE_FLYKIT 0x13 +#define BTTV_BOARD_CEI_RAFFLES 0x14 +#define BTTV_BOARD_CONFERENCETV 0x15 +#define BTTV_BOARD_PHOEBE_TVMAS 0x16 +#define BTTV_BOARD_MODTEC_205 0x17 +#define BTTV_BOARD_MAGICTVIEW061 0x18 +#define BTTV_BOARD_VOBIS_BOOSTAR 0x19 +#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a +#define BTTV_BOARD_MAXI 0x1b +#define BTTV_BOARD_TERRATV 0x1c +#define BTTV_BOARD_PXC200 0x1d +#define BTTV_BOARD_FLYVIDEO_98 0x1e +#define BTTV_BOARD_IPROTV 0x1f +#define BTTV_BOARD_INTEL_C_S_PCI 0x20 +#define BTTV_BOARD_TERRATVALUE 0x21 +#define BTTV_BOARD_WINFAST2000 0x22 +#define BTTV_BOARD_CHRONOS_VS2 0x23 +#define BTTV_BOARD_TYPHOON_TVIEW 0x24 +#define BTTV_BOARD_PXELVWPLTVPRO 0x25 +#define BTTV_BOARD_MAGICTVIEW063 0x26 +#define BTTV_BOARD_PINNACLE 0x27 +#define BTTV_BOARD_STB2 0x28 +#define BTTV_BOARD_AVPHONE98 0x29 +#define BTTV_BOARD_PV951 0x2a +#define BTTV_BOARD_ONAIR_TV 0x2b +#define BTTV_BOARD_SIGMA_TVII_FM 0x2c +#define BTTV_BOARD_MATRIX_VISION2 0x2d +#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e +#define BTTV_BOARD_TERRATVRADIO 0x2f +#define BTTV_BOARD_DYNALINK 0x30 +#define BTTV_BOARD_GVBCTV3PCI 0x31 +#define BTTV_BOARD_PXELVWPLTVPAK 0x32 +#define BTTV_BOARD_EAGLE 0x33 +#define BTTV_BOARD_PINNACLEPRO 0x34 +#define BTTV_BOARD_TVIEW_RDS_FM 0x35 +#define BTTV_BOARD_LIFETEC_9415 0x36 +#define BTTV_BOARD_BESTBUY_EASYTV 0x37 +#define BTTV_BOARD_FLYVIDEO_98FM 0x38 +#define BTTV_BOARD_GRANDTEC 0x39 +#define BTTV_BOARD_ASKEY_CPH060 0x3a +#define BTTV_BOARD_ASKEY_CPH03X 0x3b +#define BTTV_BOARD_MM100PCTV 0x3c +#define BTTV_BOARD_GMV1 0x3d +#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e +#define BTTV_BOARD_ATI_TVWONDER 0x3f +#define BTTV_BOARD_ATI_TVWONDERVE 0x40 +#define BTTV_BOARD_FLYVIDEO2000 0x41 +#define BTTV_BOARD_TERRATVALUER 0x42 +#define BTTV_BOARD_GVBCTV4PCI 0x43 +#define BTTV_BOARD_VOODOOTV_FM 0x44 +#define BTTV_BOARD_AIMMS 0x45 +#define BTTV_BOARD_PV_BT878P_PLUS 0x46 +#define BTTV_BOARD_FLYVIDEO98EZ 0x47 +#define BTTV_BOARD_PV_BT878P_9B 0x48 +#define BTTV_BOARD_SENSORAY311 0x49 +#define BTTV_BOARD_RV605 0x4a +#define BTTV_BOARD_POWERCLR_MTV878 0x4b +#define BTTV_BOARD_WINDVR 0x4c +#define BTTV_BOARD_GRANDTEC_MULTI 0x4d +#define BTTV_BOARD_KWORLD 0x4e +#define BTTV_BOARD_DSP_TCVIDEO 0x4f +#define BTTV_BOARD_HAUPPAUGEPVR 0x50 +#define BTTV_BOARD_GVBCTV5PCI 0x51 +#define BTTV_BOARD_OSPREY1x0 0x52 +#define BTTV_BOARD_OSPREY1x0_848 0x53 +#define BTTV_BOARD_OSPREY101_848 0x54 +#define BTTV_BOARD_OSPREY1x1 0x55 +#define BTTV_BOARD_OSPREY1x1_SVID 0x56 +#define BTTV_BOARD_OSPREY2xx 0x57 +#define BTTV_BOARD_OSPREY2x0_SVID 0x58 +#define BTTV_BOARD_OSPREY2x0 0x59 +#define BTTV_BOARD_OSPREY500 0x5a +#define BTTV_BOARD_OSPREY540 0x5b +#define BTTV_BOARD_OSPREY2000 0x5c +#define BTTV_BOARD_IDS_EAGLE 0x5d +#define BTTV_BOARD_PINNACLESAT 0x5e +#define BTTV_BOARD_FORMAC_PROTV 0x5f +#define BTTV_BOARD_MACHTV 0x60 +#define BTTV_BOARD_EURESYS_PICOLO 0x61 +#define BTTV_BOARD_PV150 0x62 +#define BTTV_BOARD_AD_TVK503 0x63 +#define BTTV_BOARD_HERCULES_SM_TV 0x64 +#define BTTV_BOARD_PACETV 0x65 +#define BTTV_BOARD_IVC200 0x66 +#define BTTV_BOARD_XGUARD 0x67 +#define BTTV_BOARD_NEBULA_DIGITV 0x68 +#define BTTV_BOARD_PV143 0x69 +#define BTTV_BOARD_VD009X1_MINIDIN 0x6a +#define BTTV_BOARD_VD009X1_COMBI 0x6b +#define BTTV_BOARD_VD009_MINIDIN 0x6c +#define BTTV_BOARD_VD009_COMBI 0x6d +#define BTTV_BOARD_IVC100 0x6e +#define BTTV_BOARD_IVC120 0x6f +#define BTTV_BOARD_PC_HDTV 0x70 +#define BTTV_BOARD_TWINHAN_DST 0x71 +#define BTTV_BOARD_WINFASTVC100 0x72 +#define BTTV_BOARD_TEV560 0x73 +#define BTTV_BOARD_SIMUS_GVC1100 0x74 +#define BTTV_BOARD_NGSTV_PLUS 0x75 +#define BTTV_BOARD_LMLBT4 0x76 +#define BTTV_BOARD_TEKRAM_M205 0x77 +#define BTTV_BOARD_CONTVFMI 0x78 +#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79 +#define BTTV_BOARD_SPIRIT_TV 0x7a +#define BTTV_BOARD_AVDVBT_771 0x7b +#define BTTV_BOARD_AVDVBT_761 0x7c +#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d +#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e +#define BTTV_BOARD_APAC_VIEWCOMP 0x7f +#define BTTV_BOARD_DVICO_DVBT_LITE 0x80 +#define BTTV_BOARD_VGEAR_MYVCD 0x81 +#define BTTV_BOARD_SUPER_TV 0x82 +#define BTTV_BOARD_TIBET_CS16 0x83 +#define BTTV_BOARD_KODICOM_4400R 0x84 +#define BTTV_BOARD_KODICOM_4400R_SL 0x85 +#define BTTV_BOARD_ADLINK_RTV24 0x86 +#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87 +#define BTTV_BOARD_ACORP_Y878F 0x88 +#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89 +#define BTTV_BOARD_PV_BT878P_2E 0x8a +#define BTTV_BOARD_PV_M4900 0x8b +#define BTTV_BOARD_OSPREY440 0x8c +#define BTTV_BOARD_ASOUND_SKYEYE 0x8d +#define BTTV_BOARD_SABRENT_TVFM 0x8e +#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f +#define BTTV_BOARD_MACHTV_MAGICTV 0x90 + +/* more card-specific defines */ +#define PT2254_L_CHANNEL 0x10 +#define PT2254_R_CHANNEL 0x08 +#define PT2254_DBS_IN_2 0x400 +#define PT2254_DBS_IN_10 0x20000 +#define WINVIEW_PT2254_CLK 0x40 +#define WINVIEW_PT2254_DATA 0x20 +#define WINVIEW_PT2254_STROBE 0x80 + +/* digital_mode */ +#define DIGITAL_MODE_VIDEO 1 +#define DIGITAL_MODE_CAMERA 2 + +struct bttv_core { + /* device structs */ + struct pci_dev *pci; + struct i2c_adapter i2c_adap; + struct list_head subs; /* struct bttv_sub_device */ + + /* device config */ + unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */ + unsigned int type; /* card type (pointer into tvcards[]) */ + char name[8]; /* dev name */ +}; + +struct bttv; + + +struct bttv_ir { + struct input_dev *dev; + struct ir_input_state ir; + char name[32]; + char phys[32]; + + /* Usual gpio signalling */ + + u32 mask_keycode; + u32 mask_keydown; + u32 mask_keyup; + u32 polling; + u32 last_gpio; + struct work_struct work; + struct timer_list timer; + + /* RC5 gpio */ + u32 rc5_gpio; + struct timer_list timer_end; /* timer_end for code completion */ + struct timer_list timer_keyup; /* timer_end for key release */ + u32 last_rc5; /* last good rc5 code */ + u32 last_bit; /* last raw bit seen */ + u32 code; /* raw code under construction */ + struct timeval base_time; /* time of last seen code */ + int active; /* building raw code */ +}; + +struct tvcard +{ + char *name; + unsigned int video_inputs; + unsigned int audio_inputs; + unsigned int tuner; + unsigned int svhs; + unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO + u32 gpiomask; + u32 muxsel[16]; + u32 gpiomux[4]; /* Tuner, Radio, external, internal */ + u32 gpiomute; /* GPIO mute setting */ + u32 gpiomask2; /* GPIO MUX mask */ + + /* i2c audio flags */ + unsigned int no_msp34xx:1; + unsigned int no_tda9875:1; + unsigned int no_tda7432:1; + unsigned int needs_tvaudio:1; + unsigned int msp34xx_alt:1; + + /* flag: video pci function is unused */ + unsigned int no_video:1; + unsigned int has_dvb:1; + unsigned int has_remote:1; + unsigned int no_gpioirq:1; + + /* other settings */ + unsigned int pll; +#define PLL_NONE 0 +#define PLL_28 1 +#define PLL_35 2 + + unsigned int tuner_type; + unsigned int tuner_addr; + unsigned int radio_addr; + + unsigned int has_radio; + void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set); + void (*muxsel_hook)(struct bttv *btv, unsigned int input); +}; + +extern struct tvcard bttv_tvcards[]; + +/* identification / initialization of the card */ +extern void bttv_idcard(struct bttv *btv); +extern void bttv_init_card1(struct bttv *btv); +extern void bttv_init_card2(struct bttv *btv); + +/* card-specific funtions */ +extern void tea5757_set_freq(struct bttv *btv, unsigned short freq); +extern void bttv_tda9880_setnorm(struct bttv *btv, int norm); + +/* extra tweaks for some chipsets */ +extern void bttv_check_chipset(void); +extern int bttv_handle_chipset(struct bttv *btv); + +/* ---------------------------------------------------------- */ +/* exported by bttv-if.c */ + +/* this obsolete -- please use the sysfs-based + interface below for new code */ + +/* returns card type + card ID (for bt878-based ones) + for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN + returns negative value if error occurred +*/ +extern int bttv_get_cardinfo(unsigned int card, int *type, + unsigned int *cardid); +extern struct pci_dev* bttv_get_pcidev(unsigned int card); + +/* obsolete, use bttv_get_cardinfo instead */ +extern int bttv_get_id(unsigned int card); + +/* sets GPOE register (BT848_GPIO_OUT_EN) to new value: + data | (current_GPOE_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_gpio_enable(unsigned int card, + unsigned long mask, unsigned long data); + +/* fills data with GPDATA register contents + returns negative value if error occurred +*/ +extern int bttv_read_gpio(unsigned int card, unsigned long *data); + +/* sets GPDATA register to new value: + (data & mask) | (current_GPDATA_value & ~mask) + returns negative value if error occurred +*/ +extern int bttv_write_gpio(unsigned int card, + unsigned long mask, unsigned long data); + +/* returns pointer to task queue which can be used as parameter to + interruptible_sleep_on + in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated + (wake_up_interruptible) and following call to the function bttv_read_gpio + should return new value of GPDATA, + returns NULL value if error occurred or queue is not available + WARNING: because there is no buffer for GPIO data, one MUST + process data ASAP +*/ +extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card); + +/* call i2c clients +*/ +extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg); + + + +/* ---------------------------------------------------------- */ +/* sysfs/driver-moded based gpio access interface */ + + +struct bttv_sub_device { + struct device dev; + struct bttv_core *core; + struct list_head list; +}; +#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev) + +struct bttv_sub_driver { + struct device_driver drv; + char wanted[BUS_ID_SIZE]; + int (*probe)(struct bttv_sub_device *sub); + void (*remove)(struct bttv_sub_device *sub); + void (*gpio_irq)(struct bttv_sub_device *sub); +}; +#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv) + +int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted); +int bttv_sub_unregister(struct bttv_sub_driver *drv); + +/* gpio access functions */ +void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits); +u32 bttv_gpio_read(struct bttv_core *core); +void bttv_gpio_write(struct bttv_core *core, u32 value); +void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits); + +#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits) +#define gpio_read() bttv_gpio_read(&btv->c) +#define gpio_write(value) bttv_gpio_write(&btv->c, value) +#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits) + + +/* ---------------------------------------------------------- */ +/* i2c */ + +extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg); +extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for); +extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1, + unsigned char b2, int both); +extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr); + +extern int bttv_input_init(struct bttv *dev); +extern void bttv_input_fini(struct bttv *dev); +extern void bttv_input_irq(struct bttv *dev); + +#endif /* _BTTV_H_ */ +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.17/bt848.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.17/bt848.h @@ -0,0 +1,366 @@ +/* + bt848.h - Bt848 register offsets + + Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) + + 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. +*/ + +#ifndef _BT848_H_ +#define _BT848_H_ + +#ifndef PCI_VENDOR_ID_BROOKTREE +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#endif +#ifndef PCI_DEVICE_ID_BT848 +#define PCI_DEVICE_ID_BT848 0x350 +#endif +#ifndef PCI_DEVICE_ID_BT849 +#define PCI_DEVICE_ID_BT849 0x351 +#endif +#ifndef PCI_DEVICE_ID_BT878 +#define PCI_DEVICE_ID_BT878 0x36e +#endif +#ifndef PCI_DEVICE_ID_BT879 +#define PCI_DEVICE_ID_BT879 0x36f +#endif + + +/* Brooktree 848 registers */ + +#define BT848_DSTATUS 0x000 +#define BT848_DSTATUS_PRES (1<<7) +#define BT848_DSTATUS_HLOC (1<<6) +#define BT848_DSTATUS_FIELD (1<<5) +#define BT848_DSTATUS_NUML (1<<4) +#define BT848_DSTATUS_CSEL (1<<3) +#define BT848_DSTATUS_PLOCK (1<<2) +#define BT848_DSTATUS_LOF (1<<1) +#define BT848_DSTATUS_COF (1<<0) + +#define BT848_IFORM 0x004 +#define BT848_IFORM_HACTIVE (1<<7) +#define BT848_IFORM_MUXSEL (3<<5) +#define BT848_IFORM_MUX0 (2<<5) +#define BT848_IFORM_MUX1 (3<<5) +#define BT848_IFORM_MUX2 (1<<5) +#define BT848_IFORM_XTSEL (3<<3) +#define BT848_IFORM_XT0 (1<<3) +#define BT848_IFORM_XT1 (2<<3) +#define BT848_IFORM_XTAUTO (3<<3) +#define BT848_IFORM_XTBOTH (3<<3) +#define BT848_IFORM_NTSC 1 +#define BT848_IFORM_NTSC_J 2 +#define BT848_IFORM_PAL_BDGHI 3 +#define BT848_IFORM_PAL_M 4 +#define BT848_IFORM_PAL_N 5 +#define BT848_IFORM_SECAM 6 +#define BT848_IFORM_PAL_NC 7 +#define BT848_IFORM_AUTO 0 +#define BT848_IFORM_NORM 7 + +#define BT848_TDEC 0x008 +#define BT848_TDEC_DEC_FIELD (1<<7) +#define BT848_TDEC_FLDALIGN (1<<6) +#define BT848_TDEC_DEC_RAT (0x1f) + +#define BT848_E_CROP 0x00C +#define BT848_O_CROP 0x08C + +#define BT848_E_VDELAY_LO 0x010 +#define BT848_O_VDELAY_LO 0x090 + +#define BT848_E_VACTIVE_LO 0x014 +#define BT848_O_VACTIVE_LO 0x094 + +#define BT848_E_HDELAY_LO 0x018 +#define BT848_O_HDELAY_LO 0x098 + +#define BT848_E_HACTIVE_LO 0x01C +#define BT848_O_HACTIVE_LO 0x09C + +#define BT848_E_HSCALE_HI 0x020 +#define BT848_O_HSCALE_HI 0x0A0 + +#define BT848_E_HSCALE_LO 0x024 +#define BT848_O_HSCALE_LO 0x0A4 + +#define BT848_BRIGHT 0x028 + +#define BT848_E_CONTROL 0x02C +#define BT848_O_CONTROL 0x0AC +#define BT848_CONTROL_LNOTCH (1<<7) +#define BT848_CONTROL_COMP (1<<6) +#define BT848_CONTROL_LDEC (1<<5) +#define BT848_CONTROL_CBSENSE (1<<4) +#define BT848_CONTROL_CON_MSB (1<<2) +#define BT848_CONTROL_SAT_U_MSB (1<<1) +#define BT848_CONTROL_SAT_V_MSB (1<<0) + +#define BT848_CONTRAST_LO 0x030 +#define BT848_SAT_U_LO 0x034 +#define BT848_SAT_V_LO 0x038 +#define BT848_HUE 0x03C + +#define BT848_E_SCLOOP 0x040 +#define BT848_O_SCLOOP 0x0C0 +#define BT848_SCLOOP_CAGC (1<<6) +#define BT848_SCLOOP_CKILL (1<<5) +#define BT848_SCLOOP_HFILT_AUTO (0<<3) +#define BT848_SCLOOP_HFILT_CIF (1<<3) +#define BT848_SCLOOP_HFILT_QCIF (2<<3) +#define BT848_SCLOOP_HFILT_ICON (3<<3) + +#define BT848_SCLOOP_PEAK (1<<7) +#define BT848_SCLOOP_HFILT_MINP (1<<3) +#define BT848_SCLOOP_HFILT_MEDP (2<<3) +#define BT848_SCLOOP_HFILT_MAXP (3<<3) + + +#define BT848_OFORM 0x048 +#define BT848_OFORM_RANGE (1<<7) +#define BT848_OFORM_CORE0 (0<<5) +#define BT848_OFORM_CORE8 (1<<5) +#define BT848_OFORM_CORE16 (2<<5) +#define BT848_OFORM_CORE32 (3<<5) + +#define BT848_E_VSCALE_HI 0x04C +#define BT848_O_VSCALE_HI 0x0CC +#define BT848_VSCALE_YCOMB (1<<7) +#define BT848_VSCALE_COMB (1<<6) +#define BT848_VSCALE_INT (1<<5) +#define BT848_VSCALE_HI 15 + +#define BT848_E_VSCALE_LO 0x050 +#define BT848_O_VSCALE_LO 0x0D0 +#define BT848_TEST 0x054 +#define BT848_ADELAY 0x060 +#define BT848_BDELAY 0x064 + +#define BT848_ADC 0x068 +#define BT848_ADC_RESERVED (2<<6) +#define BT848_ADC_SYNC_T (1<<5) +#define BT848_ADC_AGC_EN (1<<4) +#define BT848_ADC_CLK_SLEEP (1<<3) +#define BT848_ADC_Y_SLEEP (1<<2) +#define BT848_ADC_C_SLEEP (1<<1) +#define BT848_ADC_CRUSH (1<<0) + +#define BT848_WC_UP 0x044 +#define BT848_WC_DOWN 0x078 + +#define BT848_E_VTC 0x06C +#define BT848_O_VTC 0x0EC +#define BT848_VTC_HSFMT (1<<7) +#define BT848_VTC_VFILT_2TAP 0 +#define BT848_VTC_VFILT_3TAP 1 +#define BT848_VTC_VFILT_4TAP 2 +#define BT848_VTC_VFILT_5TAP 3 + +#define BT848_SRESET 0x07C + +#define BT848_COLOR_FMT 0x0D4 +#define BT848_COLOR_FMT_O_RGB32 (0<<4) +#define BT848_COLOR_FMT_O_RGB24 (1<<4) +#define BT848_COLOR_FMT_O_RGB16 (2<<4) +#define BT848_COLOR_FMT_O_RGB15 (3<<4) +#define BT848_COLOR_FMT_O_YUY2 (4<<4) +#define BT848_COLOR_FMT_O_BtYUV (5<<4) +#define BT848_COLOR_FMT_O_Y8 (6<<4) +#define BT848_COLOR_FMT_O_RGB8 (7<<4) +#define BT848_COLOR_FMT_O_YCrCb422 (8<<4) +#define BT848_COLOR_FMT_O_YCrCb411 (9<<4) +#define BT848_COLOR_FMT_O_RAW (14<<4) +#define BT848_COLOR_FMT_E_RGB32 0 +#define BT848_COLOR_FMT_E_RGB24 1 +#define BT848_COLOR_FMT_E_RGB16 2 +#define BT848_COLOR_FMT_E_RGB15 3 +#define BT848_COLOR_FMT_E_YUY2 4 +#define BT848_COLOR_FMT_E_BtYUV 5 +#define BT848_COLOR_FMT_E_Y8 6 +#define BT848_COLOR_FMT_E_RGB8 7 +#define BT848_COLOR_FMT_E_YCrCb422 8 +#define BT848_COLOR_FMT_E_YCrCb411 9 +#define BT848_COLOR_FMT_E_RAW 14 + +#define BT848_COLOR_FMT_RGB32 0x00 +#define BT848_COLOR_FMT_RGB24 0x11 +#define BT848_COLOR_FMT_RGB16 0x22 +#define BT848_COLOR_FMT_RGB15 0x33 +#define BT848_COLOR_FMT_YUY2 0x44 +#define BT848_COLOR_FMT_BtYUV 0x55 +#define BT848_COLOR_FMT_Y8 0x66 +#define BT848_COLOR_FMT_RGB8 0x77 +#define BT848_COLOR_FMT_YCrCb422 0x88 +#define BT848_COLOR_FMT_YCrCb411 0x99 +#define BT848_COLOR_FMT_RAW 0xee + +#define BT848_VTOTAL_LO 0xB0 +#define BT848_VTOTAL_HI 0xB4 + +#define BT848_COLOR_CTL 0x0D8 +#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7) +#define BT848_COLOR_CTL_COLOR_BARS (1<<6) +#define BT848_COLOR_CTL_RGB_DED (1<<5) +#define BT848_COLOR_CTL_GAMMA (1<<4) +#define BT848_COLOR_CTL_WSWAP_ODD (1<<3) +#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2) +#define BT848_COLOR_CTL_BSWAP_ODD (1<<1) +#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0) + +#define BT848_CAP_CTL 0x0DC +#define BT848_CAP_CTL_DITH_FRAME (1<<4) +#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3) +#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2) +#define BT848_CAP_CTL_CAPTURE_ODD (1<<1) +#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0) + +#define BT848_VBI_PACK_SIZE 0x0E0 + +#define BT848_VBI_PACK_DEL 0x0E4 +#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc +#define BT848_VBI_PACK_DEL_EXT_FRAME 2 +#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1 + + +#define BT848_INT_STAT 0x100 +#define BT848_INT_MASK 0x104 + +#define BT848_INT_ETBF (1<<23) + +#define BT848_INT_RISCS (0xf<<28) +#define BT848_INT_RISC_EN (1<<27) +#define BT848_INT_RACK (1<<25) +#define BT848_INT_FIELD (1<<24) +#define BT848_INT_SCERR (1<<19) +#define BT848_INT_OCERR (1<<18) +#define BT848_INT_PABORT (1<<17) +#define BT848_INT_RIPERR (1<<16) +#define BT848_INT_PPERR (1<<15) +#define BT848_INT_FDSR (1<<14) +#define BT848_INT_FTRGT (1<<13) +#define BT848_INT_FBUS (1<<12) +#define BT848_INT_RISCI (1<<11) +#define BT848_INT_GPINT (1<<9) +#define BT848_INT_I2CDONE (1<<8) +#define BT848_INT_VPRES (1<<5) +#define BT848_INT_HLOCK (1<<4) +#define BT848_INT_OFLOW (1<<3) +#define BT848_INT_HSYNC (1<<2) +#define BT848_INT_VSYNC (1<<1) +#define BT848_INT_FMTCHG (1<<0) + + +#define BT848_GPIO_DMA_CTL 0x10C +#define BT848_GPIO_DMA_CTL_GPINTC (1<<15) +#define BT848_GPIO_DMA_CTL_GPINTI (1<<14) +#define BT848_GPIO_DMA_CTL_GPWEC (1<<13) +#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11) +#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10) +#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6) +#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6) +#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4) +#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4) +#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2) +#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2) +#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2) +#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2) +#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1) +#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0) + +#define BT848_I2C 0x110 +#define BT878_I2C_MODE (1<<7) +#define BT878_I2C_RATE (1<<6) +#define BT878_I2C_NOSTOP (1<<5) +#define BT878_I2C_NOSTART (1<<4) +#define BT848_I2C_DIV (0xf<<4) +#define BT848_I2C_SYNC (1<<3) +#define BT848_I2C_W3B (1<<2) +#define BT848_I2C_SCL (1<<1) +#define BT848_I2C_SDA (1<<0) + +#define BT848_RISC_STRT_ADD 0x114 +#define BT848_GPIO_OUT_EN 0x118 +#define BT848_GPIO_REG_INP 0x11C +#define BT848_RISC_COUNT 0x120 +#define BT848_GPIO_DATA 0x200 + + +/* Bt848 RISC commands */ + +/* only for the SYNC RISC command */ +#define BT848_FIFO_STATUS_FM1 0x06 +#define BT848_FIFO_STATUS_FM3 0x0e +#define BT848_FIFO_STATUS_SOL 0x02 +#define BT848_FIFO_STATUS_EOL4 0x01 +#define BT848_FIFO_STATUS_EOL3 0x0d +#define BT848_FIFO_STATUS_EOL2 0x09 +#define BT848_FIFO_STATUS_EOL1 0x05 +#define BT848_FIFO_STATUS_VRE 0x04 +#define BT848_FIFO_STATUS_VRO 0x0c +#define BT848_FIFO_STATUS_PXV 0x00 + +#define BT848_RISC_RESYNC (1<<15) + +/* WRITE and SKIP */ +/* disable which bytes of each DWORD */ +#define BT848_RISC_BYTE0 (1U<<12) +#define BT848_RISC_BYTE1 (1U<<13) +#define BT848_RISC_BYTE2 (1U<<14) +#define BT848_RISC_BYTE3 (1U<<15) +#define BT848_RISC_BYTE_ALL (0x0fU<<12) +#define BT848_RISC_BYTE_NONE 0 +/* cause RISCI */ +#define BT848_RISC_IRQ (1U<<24) +/* RISC command is last one in this line */ +#define BT848_RISC_EOL (1U<<26) +/* RISC command is first one in this line */ +#define BT848_RISC_SOL (1U<<27) + +#define BT848_RISC_WRITE (0x01U<<28) +#define BT848_RISC_SKIP (0x02U<<28) +#define BT848_RISC_WRITEC (0x05U<<28) +#define BT848_RISC_JUMP (0x07U<<28) +#define BT848_RISC_SYNC (0x08U<<28) + +#define BT848_RISC_WRITE123 (0x09U<<28) +#define BT848_RISC_SKIP123 (0x0aU<<28) +#define BT848_RISC_WRITE1S23 (0x0bU<<28) + + +/* Bt848A and higher only !! */ +#define BT848_TGLB 0x080 +#define BT848_TGCTRL 0x084 +#define BT848_FCAP 0x0E8 +#define BT848_PLL_F_LO 0x0F0 +#define BT848_PLL_F_HI 0x0F4 + +#define BT848_PLL_XCI 0x0F8 +#define BT848_PLL_X (1<<7) +#define BT848_PLL_C (1<<6) + +#define BT848_DVSIF 0x0FC + +/* Bt878 register */ + +#define BT878_DEVCTRL 0x40 +#define BT878_EN_TBFX 0x02 +#define BT878_EN_VSFX 0x04 + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_gpio/extra_2.6.17/btcx-risc.h +++ linux-2.6.28/ubuntu/lirc/lirc_gpio/extra_2.6.17/btcx-risc.h @@ -0,0 +1,34 @@ +/* + */ +struct btcx_riscmem { + unsigned int size; + u32 *cpu; + u32 *jmp; + dma_addr_t dma; +}; + +struct btcx_skiplist { + int start; + int end; +}; + +int btcx_riscmem_alloc(struct pci_dev *pci, + struct btcx_riscmem *risc, + unsigned int size); +void btcx_riscmem_free(struct pci_dev *pci, + struct btcx_riscmem *risc); + +int btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win, + struct v4l2_clip *clips, unsigned int n); +int btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, + unsigned int n, int mask); +void btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips); +void btcx_calc_skips(int line, int width, unsigned int *maxy, + struct btcx_skiplist *skips, unsigned int *nskips, + const struct v4l2_clip *clips, unsigned int nclips); + +/* + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_sasem/lirc_sasem.c +++ linux-2.6.28/ubuntu/lirc/lirc_sasem/lirc_sasem.c @@ -0,0 +1,1130 @@ +/* $Id: lirc_sasem.c,v 1.21 2007/09/30 09:58:46 lirc Exp $ */ + +/* lirc_sasem.c - USB remote support for LIRC + * Version 0.5 + * + * Copyright (C) 2004-2005 Oliver Stabel + * Tim Davies + * + * This driver was derived from: + * Venky Raju + * "lirc_imon - "LIRC plugin/VFD driver for Ahanix/Soundgraph IMON IR/VFD" + * Paul Miller 's 2003-2004 + * "lirc_atiusb - USB remote support for LIRC" + * Culver Consulting Services 's 2003 + * "Sasem OnAir VFD/IR USB driver" + * + * + * 2004/06/13 - 0.1 + * initial version + * + * 2004/06/28 - 0.2 + * added file system support to write data to VFD device (used + * in conjunction with LCDProc) + * + * 2004/11/22 - 0.3 + * Ported to 2.6 kernel + * - Tim Davies + * + * 2005/03/29 - 0.4 + * A few tidyups and keypress timings + * - Tim Davies + * + * 2005/06/23 - 0.5 + * A complete rewrite (shamelessly) based on lirc_imon.c + * Tim Davies + * + * NOTE - The LCDproc iMon driver should work with this module. More info at + * http://www.frogstorm.info/sasem + */ + +/* + * 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 + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) +#error "*** Sorry, this driver requires kernel version 2.4.22 or higher" +#endif + +#include + +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + + +#define MOD_AUTHOR "Oliver Stabel , " \ + "Tim Davies " +#define MOD_DESC "USB Driver for Sasem Remote Controller V1.1" +#define MOD_NAME "lirc_sasem" +#define MOD_VERSION "0.5" + +#define VFD_MINOR_BASE 144 /* Same as LCD */ +#define DEVFS_MODE S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH +#define DEVFS_NAME LIRC_DEVFS_PREFIX "lcd%d" + +#define BUF_CHUNK_SIZE 8 +#define BUF_SIZE 128 + +#define SUCCESS 0 +#define TRUE 1 +#define FALSE 0 + +#define IOCTL_LCD_CONTRAST 1 + +/* ------------------------------------------------------------ + * P R O T O T Y P E S + * ------------------------------------------------------------ + */ + +/* USB Callback prototypes */ +#ifdef KERNEL_2_5 +static int sasem_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void sasem_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs); +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs); +#else +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif +#else +static void *sasem_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id); +static void sasem_disconnect(struct usb_device *dev, void *data); +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif + +/* VFD file_operations function prototypes */ +static int vfd_open(struct inode *inode, struct file *file); +static int vfd_ioctl(struct inode *inode, struct file *file, + unsigned cmd, unsigned long arg); +static int vfd_close(struct inode *inode, struct file *file); +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/* LIRC plugin function prototypes */ +static int ir_open(void *data); +static void ir_close(void *data); + +/* Driver init/exit prototypes */ +static int __init sasem_init(void); +static void __exit sasem_exit(void); + +/* ------------------------------------------------------------ + * G L O B A L S + * ------------------------------------------------------------ + */ + +struct sasem_context { + + struct usb_device *dev; + int vfd_isopen; /* VFD port has been opened */ + unsigned int vfd_contrast; /* VFD contrast */ +#if !defined(KERNEL_2_5) + int subminor; /* index into minor_table */ + devfs_handle_t devfs; +#endif + int ir_isopen; /* IR port has been opened */ + int dev_present; /* USB device presence */ + struct semaphore sem; /* to lock this object */ + wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ + + struct lirc_plugin *plugin; + struct usb_endpoint_descriptor *rx_endpoint; + struct usb_endpoint_descriptor *tx_endpoint; + struct urb *rx_urb; + struct urb *tx_urb; + unsigned char usb_rx_buf [8]; + unsigned char usb_tx_buf [8]; + + struct tx_t { + unsigned char data_buf [32]; /* user data buffer */ + struct completion finished; /* wait for write to finish */ + atomic_t busy; /* write in progress */ + int status; /* status of tx completion */ + } tx; + + /* for dealing with repeat codes (wish there was a toggle bit!) */ + struct timeval presstime; + char lastcode[8]; + int codesaved; +}; + +#define LOCK_CONTEXT down(&context->sem) +#define UNLOCK_CONTEXT up(&context->sem) + +/* VFD file operations */ +static struct file_operations vfd_fops = { + + .owner = THIS_MODULE, + .open = &vfd_open, + .write = &vfd_write, + .ioctl = &vfd_ioctl, + .release = &vfd_close +}; + +/* USB Device ID for Sasem USB Control Board */ +static struct usb_device_id sasem_usb_id_table [] = { + { USB_DEVICE(0x11ba, 0x0101) }, /* Sasem */ + {} +}; + +/* USB Device data */ +static struct usb_driver sasem_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = MOD_NAME, + .probe = sasem_probe, + .disconnect = sasem_disconnect, + .id_table = sasem_usb_id_table, +#if !defined(KERNEL_2_5) + .fops = &vfd_fops, + .minor = VFD_MINOR_BASE, +#endif +}; + +#ifdef KERNEL_2_5 +static struct usb_class_driver sasem_class = { + .name = DEVFS_NAME, + .fops = &vfd_fops, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + .mode = DEVFS_MODE, +#endif + .minor_base = VFD_MINOR_BASE, +}; +#endif + +/* to prevent races between open() and disconnect() */ +static DECLARE_MUTEX(disconnect_sem); + +static int debug; + +#if !defined(KERNEL_2_5) + +#define MAX_DEVICES 4 /* In case there's more than one Sasem device */ +static struct sasem_context *minor_table [MAX_DEVICES]; + +/* the global usb devfs handle */ +extern devfs_handle_t usb_devfs_handle; + +#endif + +/* ------------------------------------------------------------ + * M O D U L E C O D E + * ------------------------------------------------------------ + */ + +MODULE_AUTHOR(MOD_AUTHOR); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_LICENSE("GPL"); +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes (default: no)"); + +static inline void delete_context(struct sasem_context *context) +{ + usb_free_urb(context->tx_urb); /* VFD */ + usb_free_urb(context->rx_urb); /* IR */ + lirc_buffer_free(context->plugin->rbuf); + kfree(context->plugin->rbuf); + kfree(context->plugin); + kfree(context); + + if (debug) + info("%s: context deleted", __FUNCTION__); +} + +static inline void deregister_from_lirc(struct sasem_context *context) +{ + int retval; + int minor = context->plugin->minor; + + retval = lirc_unregister_plugin(minor); + if (retval) + err("%s: unable to deregister from lirc (%d)", + __FUNCTION__, retval); + else + info("Deregistered Sasem plugin (minor:%d)", minor); + +} + +/** + * Called when the VFD device (e.g. /dev/usb/lcd) + * is opened by the application. + */ +static int vfd_open(struct inode *inode, struct file *file) +{ +#ifdef KERNEL_2_5 + struct usb_interface *interface; +#endif + struct sasem_context *context = NULL; + int subminor; + int retval = SUCCESS; + + /* prevent races with disconnect */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + subminor = iminor(inode); + interface = usb_find_interface(&sasem_driver, subminor); + if (!interface) { + err("%s: could not find interface for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = usb_get_intfdata(interface); +#else + subminor = MINOR(inode->i_rdev) - VFD_MINOR_BASE; + if (subminor < 0 || subminor >= MAX_DEVICES) { + err("%s: no record of minor %d", __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = minor_table [subminor]; +#endif + + if (!context) { + err("%s: no context found for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + + LOCK_CONTEXT; + + if (context->vfd_isopen) { + err("%s: VFD port is already open", __FUNCTION__); + retval = -EBUSY; + } else { + MOD_INC_USE_COUNT; + context->vfd_isopen = TRUE; + file->private_data = context; + info("VFD port opened"); + } + + UNLOCK_CONTEXT; + +exit: + up(&disconnect_sem); + return retval; +} + +/** + * Called when the VFD device (e.g. /dev/usb/lcd) + * is closed by the application. + */ +static int vfd_ioctl(struct inode *inode, struct file *file, + unsigned cmd, unsigned long arg) +{ + struct sasem_context *context = NULL; + + context = (struct sasem_context *) file->private_data; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + switch (cmd) { + case IOCTL_LCD_CONTRAST: + if (arg > 1000) + arg = 1000; + if (arg < 0) + arg = 0; + context->vfd_contrast = (unsigned int)arg; + break; + default: + info("Unknown IOCTL command"); + UNLOCK_CONTEXT; + return -ENOIOCTLCMD; /* not supported */ + } + + UNLOCK_CONTEXT; + return 0; +} + +/** + * Called when the VFD device (e.g. /dev/usb/lcd) + * is closed by the application. + */ +static int vfd_close(struct inode *inode, struct file *file) +{ + struct sasem_context *context = NULL; + int retval = SUCCESS; + + context = (struct sasem_context *) file->private_data; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->vfd_isopen) { + err("%s: VFD is not open", __FUNCTION__); + retval = -EIO; + } else { + context->vfd_isopen = FALSE; + MOD_DEC_USE_COUNT; + info("VFD port closed"); + if (!context->dev_present && !context->ir_isopen) { + + /* Device disconnected before close and IR port is + * not open. If IR port is open, context will be + * deleted by ir_close. */ + UNLOCK_CONTEXT; + delete_context(context); + return retval; + } + } + + UNLOCK_CONTEXT; + return retval; +} + +/** + * Sends a packet to the VFD. + */ +static inline int send_packet(struct sasem_context *context) +{ + unsigned int pipe; + int interval = 0; + int retval = SUCCESS; + + pipe = usb_sndintpipe(context->dev, + context->tx_endpoint->bEndpointAddress); +#ifdef KERNEL_2_5 + interval = context->tx_endpoint->bInterval; +#endif /* Use 0 for 2.4 kernels */ + + usb_fill_int_urb(context->tx_urb, context->dev, pipe, + context->usb_tx_buf, sizeof(context->usb_tx_buf), + usb_tx_callback, context, interval); + + context->tx_urb->actual_length = 0; + + init_completion(&context->tx.finished); + atomic_set(&(context->tx.busy), 1); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->tx_urb); +#endif + if (retval != SUCCESS) { + atomic_set(&(context->tx.busy), 0); + err("%s: error submitting urb (%d)", __FUNCTION__, retval); + } else { + /* Wait for tranmission to complete (or abort) */ + UNLOCK_CONTEXT; + wait_for_completion(&context->tx.finished); + LOCK_CONTEXT; + + retval = context->tx.status; + if (retval != SUCCESS) + err("%s: packet tx failed (%d)", __FUNCTION__, retval); + } + + return retval; +} + +/** + * Writes data to the VFD. The Sasem VFD is 2x16 characters + * and requires data in 9 consecutive USB interrupt packets, + * each packet carrying 8 bytes. + */ +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int i; + int retval = SUCCESS; + struct sasem_context *context; + + context = (struct sasem_context *) file->private_data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no Sasem device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + if (n_bytes <= 0 || n_bytes > 32) { + err("%s: invalid payload size", __FUNCTION__); + retval = -EINVAL; + goto exit; + } + + copy_from_user(context->tx.data_buf, buf, n_bytes); + + /* Pad with spaces */ + for (i = n_bytes; i < 32; ++i) + context->tx.data_buf [i] = ' '; + + /* Nine 8 byte packets to be sent */ + /* NOTE: "\x07\x01\0\0\0\0\0\0" or "\x0c\0\0\0\0\0\0\0" + * will clear the VFD */ + for (i = 0; i < 9; i++) { + switch (i) { + case 0: + memcpy(context->usb_tx_buf, "\x07\0\0\0\0\0\0\0", 8); + context->usb_tx_buf[1] = (context->vfd_contrast) ? + (0x2B - (context->vfd_contrast - 1) / 250):0x2B; + break; + case 1: + memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); + break; + case 2: + memcpy(context->usb_tx_buf, "\x0b\x01\0\0\0\0\0\0", 8); + break; + case 3: + memcpy(context->usb_tx_buf, context->tx.data_buf, 8); + break; + case 4: + memcpy(context->usb_tx_buf, + context->tx.data_buf + 8, 8); + break; + case 5: + memcpy(context->usb_tx_buf, "\x09\x01\0\0\0\0\0\0", 8); + break; + case 6: + memcpy(context->usb_tx_buf, "\x0b\x02\0\0\0\0\0\0", 8); + break; + case 7: + memcpy(context->usb_tx_buf, + context->tx.data_buf + 16, 8); + break; + case 8: + memcpy(context->usb_tx_buf, + context->tx.data_buf + 24, 8); + break; + } + retval = send_packet(context); + if (retval != SUCCESS) { + + err("%s: send packet failed for packet #%d", + __FUNCTION__, i); + goto exit; + } + } +exit: + + UNLOCK_CONTEXT; + + return (retval == SUCCESS) ? n_bytes : retval; +} + +/** + * Callback function for USB core API: transmit data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_tx_callback(struct urb *urb) +#endif +{ + struct sasem_context *context; + + if (!urb) + return; + context = (struct sasem_context *) urb->context; + if (!context) + return; + + context->tx.status = urb->status; + + /* notify waiters that write has finished */ + atomic_set(&context->tx.busy, 0); + complete(&context->tx.finished); + + return; +} + +/** + * Called by lirc_dev when the application opens /dev/lirc + */ +static int ir_open(void *data) +{ + int retval = SUCCESS; + struct sasem_context *context; + + /* prevent races with disconnect */ + down(&disconnect_sem); + + context = (struct sasem_context *) data; + + LOCK_CONTEXT; + + if (context->ir_isopen) { + err("%s: IR port is already open", __FUNCTION__); + retval = -EBUSY; + goto exit; + } + + usb_fill_int_urb(context->rx_urb, context->dev, + usb_rcvintpipe(context->dev, + context->rx_endpoint->bEndpointAddress), + context->usb_rx_buf, sizeof(context->usb_rx_buf), + usb_rx_callback, context, context->rx_endpoint->bInterval); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->rx_urb); +#endif + + if (retval) + err("%s: usb_submit_urb failed for ir_open (%d)", + __FUNCTION__, retval); + else { + MOD_INC_USE_COUNT; + context->ir_isopen = TRUE; + info("IR port opened"); + } + +exit: + UNLOCK_CONTEXT; + + up(&disconnect_sem); + return SUCCESS; +} + +/** + * Called by lirc_dev when the application closes /dev/lirc + */ +static void ir_close(void *data) +{ + struct sasem_context *context; + + context = (struct sasem_context *)data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return; + } + + LOCK_CONTEXT; + + usb_kill_urb(context->rx_urb); + context->ir_isopen = FALSE; + MOD_DEC_USE_COUNT; + info("IR port closed"); + + if (!context->dev_present) { + + /* + * Device disconnected while IR port was + * still open. Plugin was not deregistered + * at disconnect time, so do it now. + */ + deregister_from_lirc(context); + + if (!context->vfd_isopen) { + + UNLOCK_CONTEXT; + delete_context(context); + return; + } + /* If VFD port is open, context will be deleted by vfd_close */ + } + + UNLOCK_CONTEXT; + return; +} + +/** + * Process the incoming packet + */ +static inline void incoming_packet(struct sasem_context *context, + struct urb *urb) +{ + int len = urb->actual_length; + unsigned char *buf = urb->transfer_buffer; + long ms; + struct timeval tv; + + if (len != 8) { + warn("%s: invalid incoming packet size (%d)", + __FUNCTION__, len); + return; + } + +#ifdef DEBUG + int i; + for (i = 0; i < 8; ++i) + printk(KERN_INFO "%02x ", buf [i]); + printk(KERN_INFO "\n"); +#endif + + /* Lirc could deal with the repeat code, but we really need to block it + * if it arrives too late. Otherwise we could repeat the wrong code. */ + + /* get the time since the last button press */ + do_gettimeofday(&tv); + ms = (tv.tv_sec - context->presstime.tv_sec) * 1000 + + (tv.tv_usec - context->presstime.tv_usec) / 1000; + + if (memcmp(buf, "\x08\0\0\0\0\0\0\0", 8) == 0) { + /* the repeat code is being sent, so we copy + * the old code to LIRC */ + + /* NOTE: Only if the last code was less than 250ms ago + * - no one should be able to push another (undetected) button + * in that time and then get a false repeat of the previous + * press but it is long enough for a genuine repeat */ + if ((ms < 250) && (context->codesaved != 0)) { + memcpy(buf, &context->lastcode, 8); + context->presstime.tv_sec = tv.tv_sec; + context->presstime.tv_usec = tv.tv_usec; + } + } else { + /* save the current valid code for repeats */ + memcpy(&context->lastcode, buf, 8); + /* set flag to signal a valid code was save; + * just for safety reasons */ + context->codesaved = 1; + context->presstime.tv_sec = tv.tv_sec; + context->presstime.tv_usec = tv.tv_usec; + } + + lirc_buffer_write_1(context->plugin->rbuf, buf); + wake_up(&context->plugin->rbuf->wait_poll); +} + +/** + * Callback function for USB core API: receive data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_rx_callback(struct urb *urb) +#endif +{ + struct sasem_context *context; + + if (!urb) + return; + context = (struct sasem_context *) urb->context; + if (!context) + return; + + switch (urb->status) { + + case -ENOENT: /* usbcore unlink successful! */ + return; + + case SUCCESS: + if (context->ir_isopen) + incoming_packet(context, urb); + break; + + default: + warn("%s: status (%d): ignored", + __FUNCTION__, urb->status); + break; + } + +#ifdef KERNEL_2_5 + usb_submit_urb(context->rx_urb, GFP_ATOMIC); +#endif + return; +} + + + +/** + * Callback function for USB core API: Probe + */ +#ifdef KERNEL_2_5 +static int sasem_probe(struct usb_interface *interface, + const struct usb_device_id *id) +#else +static void *sasem_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id) +#endif +{ +#ifdef KERNEL_2_5 + struct usb_device *dev = NULL; + struct usb_host_interface *iface_desc = NULL; +#else + struct usb_interface *interface = NULL; + struct usb_interface_descriptor *iface_desc = NULL; + char name [10]; + int subminor = 0; +#endif + struct usb_endpoint_descriptor *rx_endpoint = NULL; + struct usb_endpoint_descriptor *tx_endpoint = NULL; + struct urb *rx_urb = NULL; + struct urb *tx_urb = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int lirc_minor = 0; + int num_endpoints; + int retval = SUCCESS; + int vfd_ep_found; + int ir_ep_found; + int alloc_status; + struct sasem_context *context = NULL; + int i; + + info("%s: found Sasem device", __FUNCTION__); + +#if !defined(KERNEL_2_5) + for (subminor = 0; subminor < MAX_DEVICES; ++subminor) { + if (minor_table [subminor] == NULL) + break; + } + if (subminor == MAX_DEVICES) { + err("%s: allowed number of devices already present", + __FUNCTION__); + retval = -ENOMEM; + goto exit; + } +#endif + +#ifdef KERNEL_2_5 + dev = usb_get_dev(interface_to_usbdev(interface)); + iface_desc = interface->cur_altsetting; + num_endpoints = iface_desc->desc.bNumEndpoints; +#else + interface = &dev->actconfig->interface [intf]; + iface_desc = &interface->altsetting [interface->act_altsetting]; + num_endpoints = iface_desc->bNumEndpoints; +#endif + + /* + * Scan the endpoint list and set: + * first input endpoint = IR endpoint + * first output endpoint = VFD endpoint + */ + + ir_ep_found = FALSE; + vfd_ep_found = FALSE; + + for (i = 0; i < num_endpoints && !(ir_ep_found && vfd_ep_found); ++i) { + + struct usb_endpoint_descriptor *ep; + int ep_dir; + int ep_type; +#ifdef KERNEL_2_5 + ep = &iface_desc->endpoint [i].desc; +#else + ep = &iface_desc->endpoint [i]; +#endif + ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; + ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + + if (!ir_ep_found && + ep_dir == USB_DIR_IN && + ep_type == USB_ENDPOINT_XFER_INT) { + + rx_endpoint = ep; + ir_ep_found = TRUE; + if (debug) + info("%s: found IR endpoint", __FUNCTION__); + + } else if (!vfd_ep_found && + ep_dir == USB_DIR_OUT && + ep_type == USB_ENDPOINT_XFER_INT) { + + tx_endpoint = ep; + vfd_ep_found = TRUE; + if (debug) + info("%s: found VFD endpoint", __FUNCTION__); + } + } + + /* Input endpoint is mandatory */ + if (!ir_ep_found) { + + err("%s: no valid input (IR) endpoint found.", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + /* Warning if no VFD endpoint */ + if (!vfd_ep_found) + info("%s: no valid output (VFD) endpoint found.", __FUNCTION__); + + + /* Allocate memory */ + alloc_status = SUCCESS; + + context = kmalloc(sizeof(struct sasem_context), GFP_KERNEL); + if (!context) { + err("%s: kmalloc failed for context", __FUNCTION__); + alloc_status = 1; + goto alloc_status_switch; + } + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + err("%s: kmalloc failed for lirc_plugin", __FUNCTION__); + alloc_status = 2; + goto alloc_status_switch; + } + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + err("%s: kmalloc failed for lirc_buffer", __FUNCTION__); + alloc_status = 3; + goto alloc_status_switch; + } + if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { + err("%s: lirc_buffer_init failed", __FUNCTION__); + alloc_status = 4; + goto alloc_status_switch; + } +#ifdef KERNEL_2_5 + rx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + rx_urb = usb_alloc_urb(0); +#endif + if (!rx_urb) { + err("%s: usb_alloc_urb failed for IR urb", __FUNCTION__); + alloc_status = 5; + goto alloc_status_switch; + } + if (vfd_ep_found) { +#ifdef KERNEL_2_5 + tx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + tx_urb = usb_alloc_urb(0); +#endif + if (!tx_urb) { + err("%s: usb_alloc_urb failed for VFD urb", + __FUNCTION__); + alloc_status = 6; + goto alloc_status_switch; + } + } + + /* clear all members of sasem_context and lirc_plugin */ + memset(context, 0, sizeof(struct sasem_context)); + init_MUTEX(&context->sem); + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, MOD_NAME); + plugin->minor = -1; + plugin->code_length = 64; + plugin->sample_rate = 0; + plugin->features = LIRC_CAN_REC_LIRCCODE; + plugin->data = context; + plugin->rbuf = rbuf; + plugin->set_use_inc = ir_open; + plugin->set_use_dec = ir_close; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + + LOCK_CONTEXT; + + lirc_minor = lirc_register_plugin(plugin); + if (lirc_minor < 0) { + err("%s: lirc_register_plugin failed", __FUNCTION__); + alloc_status = 7; + UNLOCK_CONTEXT; + } else + info("%s: Registered Sasem plugin (minor:%d)", + __FUNCTION__, lirc_minor); + +alloc_status_switch: + + switch (alloc_status) { + + case 7: + if (vfd_ep_found) + usb_free_urb(tx_urb); + case 6: + usb_free_urb(rx_urb); + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(context); + context = NULL; + case 1: + retval = -ENOMEM; + goto exit; + } + + /* Needed while unregistering! */ + plugin->minor = lirc_minor; + + context->dev = dev; + context->dev_present = TRUE; + context->rx_endpoint = rx_endpoint; + context->rx_urb = rx_urb; + if (vfd_ep_found) { + context->tx_endpoint = tx_endpoint; + context->tx_urb = tx_urb; + context->vfd_contrast = 1000; /* range 0 - 1000 */ + } + context->plugin = plugin; + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, context); +#else + minor_table [subminor] = context; + context->subminor = subminor; +#endif + + if (vfd_ep_found) { + + if (debug) + info("Registering VFD with devfs"); +#ifdef KERNEL_2_5 + if (usb_register_dev(interface, &sasem_class)) + /* Not a fatal error, so ignore */ + info("%s: could not get a minor number for VFD", + __FUNCTION__); +#else + sprintf(name, DEVFS_NAME, subminor); + context->devfs = devfs_register(usb_devfs_handle, name, + DEVFS_FL_DEFAULT, + USB_MAJOR, VFD_MINOR_BASE + subminor, + DEVFS_MODE, &vfd_fops, NULL); + if (!context->devfs) + /* not a fatal error so ignore */ + info("%s: devfs register failed for VFD", + __FUNCTION__); +#endif + } + + info("%s: Sasem device on usb<%d:%d> initialized", + __FUNCTION__, dev->bus->busnum, dev->devnum); + + UNLOCK_CONTEXT; +exit: +#ifdef KERNEL_2_5 + return retval; +#else + return (retval == SUCCESS) ? context : NULL; +#endif +} + +/** + * Callback function for USB core API: disonnect + */ +#ifdef KERNEL_2_5 +static void sasem_disconnect(struct usb_interface *interface) +#else +static void sasem_disconnect(struct usb_device *dev, void *data) +#endif +{ + struct sasem_context *context; + + /* prevent races with ir_open()/vfd_open() */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + context = usb_get_intfdata(interface); +#else + context = (struct sasem_context *)data; +#endif + LOCK_CONTEXT; + + info("%s: Sasem device disconnected", __FUNCTION__); + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, NULL); +#else + minor_table [context->subminor] = NULL; +#endif + context->dev_present = FALSE; + + /* Stop reception */ + usb_kill_urb(context->rx_urb); + + /* Abort ongoing write */ + if (atomic_read(&context->tx.busy)) { + + usb_kill_urb(context->tx_urb); + wait_for_completion(&context->tx.finished); + } + + /* De-register from lirc_dev if IR port is not open */ + if (!context->ir_isopen) + deregister_from_lirc(context); + +#ifdef KERNEL_2_5 + usb_deregister_dev(interface, &sasem_class); +#else + if (context->devfs) + devfs_unregister(context->devfs); +#endif + + UNLOCK_CONTEXT; + + if (!context->ir_isopen && !context->vfd_isopen) + delete_context(context); + + up(&disconnect_sem); +} + +static int __init sasem_init(void) +{ + int rc; + + info(MOD_DESC ", v" MOD_VERSION); + info(MOD_AUTHOR); + + rc = usb_register(&sasem_driver); + if (rc < 0) { + err("%s: usb register failed (%d)", __FUNCTION__, rc); + return -ENODEV; + } + return SUCCESS; +} + +static void __exit sasem_exit(void) +{ + usb_deregister(&sasem_driver); + info("module removed. Goodbye!"); +} + + +module_init(sasem_init); +module_exit(sasem_exit); + +#if !defined(KERNEL_2_5) +EXPORT_NO_SYMBOLS; +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_sasem/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_sasem/Makefile @@ -0,0 +1,2 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. +obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_serial/lirc_serial.c +++ linux-2.6.28/ubuntu/lirc/lirc_serial/lirc_serial.c @@ -0,0 +1,1368 @@ +/* $Id: lirc_serial.c,v 5.89 2008/04/06 19:03:52 lirc Exp $ */ + +/**************************************************************************** + ** lirc_serial.c *********************************************************** + **************************************************************************** + * + * lirc_serial - Device driver that records pulse- and pause-lengths + * (space-lengths) between DDCD event on a serial port. + * + * Copyright (C) 1996,97 Ralph Metzler + * Copyright (C) 1998 Trent Piepho + * Copyright (C) 1998 Ben Pfaff + * Copyright (C) 1999 Christoph Bartelmus + * Copyright (C) 2007 Andrei Tanas (suspend/resume 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; 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 + * + */ + +/* Steve's changes to improve transmission fidelity: + - for systems with the rdtsc instruction and the clock counter, a + send_pule that times the pulses directly using the counter. + This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is + not needed. Measurement shows very stable waveform, even where + PCI activity slows the access to the UART, which trips up other + versions. + - For other system, non-integer-microsecond pulse/space lengths, + done using fixed point binary. So, much more accurate carrier + frequency. + - fine tuned transmitter latency, taking advantage of fractional + microseconds in previous change + - Fixed bug in the way transmitter latency was accounted for by + tuning the pulse lengths down - the send_pulse routine ignored + this overhead as it timed the overall pulse length - so the + pulse frequency was right but overall pulse length was too + long. Fixed by accounting for latency on each pulse/space + iteration. + + Steve Davies July 2001 +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +#include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#include +#else +#include +#endif +#include +#include + +#if defined(LIRC_SERIAL_NSLU2) +#include +/* From Intel IXP42X Developer's Manual (#252480-005): */ +/* ftp://download.intel.com/design/network/manuals/25248005.pdf */ +#define UART_IE_IXP42X_UUE 0x40 /* IXP42X UART Unit enable */ +#define UART_IE_IXP42X_RTOIE 0x10 /* IXP42X Receiver Data Timeout int.enable */ +#ifndef NSLU2_LED_GRN_GPIO +/* added in 2.6.22 */ +#define NSLU2_LED_GRN_GPIO NSLU2_LED_GRN +#endif +#endif + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#if defined(LIRC_SERIAL_SOFTCARRIER) && !defined(LIRC_SERIAL_TRANSMITTER) +#warning "Software carrier only affects transmitting" +#endif + +#if defined(rdtscl) + +#define USE_RDTSC +#warning "Note: using rdtsc instruction" +#endif + +#ifdef LIRC_SERIAL_ANIMAX +#ifdef LIRC_SERIAL_TRANSMITTER +#warning "******************************************" +#warning " This receiver does not have a " +#warning " transmitter diode " +#warning "******************************************" +#endif +#endif + +#define LIRC_DRIVER_NAME "lirc_serial" + +struct lirc_serial { + int signal_pin; + int signal_pin_change; + int on; + int off; + long (*send_pulse)(unsigned long length); + void (*send_space)(long length); + int features; +}; + +#define LIRC_HOMEBREW 0 +#define LIRC_IRDEO 1 +#define LIRC_IRDEO_REMOTE 2 +#define LIRC_ANIMAX 3 +#define LIRC_IGOR 4 +#define LIRC_NSLU2 5 + +#ifdef LIRC_SERIAL_IRDEO +static int type = LIRC_IRDEO; +#elif defined(LIRC_SERIAL_IRDEO_REMOTE) +static int type = LIRC_IRDEO_REMOTE; +#elif defined(LIRC_SERIAL_ANIMAX) +static int type = LIRC_ANIMAX; +#elif defined(LIRC_SERIAL_IGOR) +static int type = LIRC_IGOR; +#elif defined(LIRC_SERIAL_NSLU2) +static int type = LIRC_NSLU2; +#else +static int type = LIRC_HOMEBREW; +#endif + +/* Set defaults for NSLU2 */ +#if defined(LIRC_SERIAL_NSLU2) +#ifndef LIRC_IRQ +#define LIRC_IRQ IRQ_IXP4XX_UART2 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT (IXP4XX_UART2_BASE_VIRT + REG_OFFSET) +#endif +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP IXP4XX_UART2_BASE_PHYS +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 2 +#endif +#ifndef LIRC_ALLOW_MMAPPED_IO +#define LIRC_ALLOW_MMAPPED_IO +#endif +#endif + +#if defined(LIRC_ALLOW_MMAPPED_IO) +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP 0 +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 0 +#endif +static int iommap = LIRC_IOMMAP; +static int ioshift = LIRC_IOSHIFT; +#endif + +#ifdef LIRC_SERIAL_SOFTCARRIER +static int softcarrier = 1; +#else +static int softcarrier; +#endif + +static int share_irq; +static int debug; + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +/* forward declarations */ +static long send_pulse_irdeo(unsigned long length); +static long send_pulse_homebrew(unsigned long length); +static void send_space_irdeo(long length); +static void send_space_homebrew(long length); + +static struct lirc_serial hardware[] = { + /* home-brew receiver/transmitter */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo classic */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo remote */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* AnimaX */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + 0, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + NULL, + NULL, + LIRC_CAN_REC_MODE2 + }, + + /* home-brew receiver/transmitter (Igor Cesko's variation) */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + +#if defined(LIRC_SERIAL_NSLU2) + /* Modified Linksys Network Storage Link USB 2.0 (NSLU2): + We receive on CTS of the 2nd serial port (R142,LHS), we + transmit with a IR diode between GPIO[1] (green status LED), + and ground (Matthias Goebl ). + See also http://www.nslu2-linux.org for this device */ + { + UART_MSR_CTS, + UART_MSR_DCTS, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, +#endif + +}; + +#define RS_ISR_PASS_LIMIT 256 + +/* A long pulse code from a remote might take upto 300 bytes. The + daemon should read the bytes as soon as they are generated, so take + the number of keys you think you can push before the daemon runs + and multiply by 300. The driver will warn you if you overrun this + buffer. If you have a slow computer or non-busmastering IDE disks, + maybe you will need to increase this. */ + +/* This MUST be a power of two! It has to be larger than 1 as well. */ + +#define RBUF_LEN 256 +#define WBUF_LEN 256 + +static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ +static int txsense; /* 0 = active high, 1 = active low */ + +#ifndef LIRC_IRQ +#define LIRC_IRQ 4 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x3f8 +#endif + +static int io = LIRC_PORT; +static int irq = LIRC_IRQ; + +static struct timeval lasttv = {0, 0}; + +static struct lirc_buffer rbuf; + +static lirc_t wbuf[WBUF_LEN]; + +static unsigned int freq = 38000; +static unsigned int duty_cycle = 50; + +/* Initialized in init_timing_params() */ +static unsigned long period; +static unsigned long pulse_width; +static unsigned long space_width; + +#if defined(__i386__) +/* + From: + Linux I/O port programming mini-HOWTO + Author: Riku Saikkonen + v, 28 December 1997 + + [...] + Actually, a port I/O instruction on most ports in the 0-0x3ff range + takes almost exactly 1 microsecond, so if you're, for example, using + the parallel port directly, just do additional inb()s from that port + to delay. + [...] +*/ +/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from + * comment above plus trimming to match actual measured frequency. + * This will be sensitive to cpu speed, though hopefully most of the 1.5us + * is spent in the uart access. Still - for reference test machine was a + * 1.13GHz Athlon system - Steve + */ + +/* changed from 400 to 450 as this works better on slower machines; + faster machines will use the rdtsc code anyway */ + +#define LIRC_SERIAL_TRANSMITTER_LATENCY 450 + +#else + +/* does anybody have information on other platforms ? */ +/* 256 = 1<<8 */ +#define LIRC_SERIAL_TRANSMITTER_LATENCY 256 + +#endif /* __i386__ */ + +static inline unsigned int sinp(int offset) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { + /* the register is memory-mapped */ + offset <<= ioshift; + return readb(io + offset); + } +#endif + return inb(io + offset); +} + +static inline void soutp(int offset, int value) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { + /* the register is memory-mapped */ + offset <<= ioshift; + writeb(value, io + offset); + } +#endif + outb(value, io + offset); +} + +static inline void on(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + /* On NSLU2, we put the transmit diode between the output of the green + status LED and ground */ + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_LOW); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].off); + else + soutp(UART_MCR, hardware[type].on); +} + +static inline void off(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_HIGH); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].on); + else + soutp(UART_MCR, hardware[type].off); +} + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +#ifdef USE_RDTSC +/* This is an overflow/precision juggle, complicated in that we can't + do long long divide in the kernel */ + +/* When we use the rdtsc instruction to measure clocks, we keep the + * pulse and space widths as clock cycles. As this is CPU speed + * dependent, the widths must be calculated in init_port and ioctl + * time + */ + +/* So send_pulse can quickly convert microseconds to clocks */ +static unsigned long conv_us_to_clocks; + +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ + unsigned long long loops_per_sec, work; + + duty_cycle = new_duty_cycle; + freq = new_freq; + + loops_per_sec = current_cpu_data.loops_per_jiffy; + loops_per_sec *= HZ; + + /* How many clocks in a microsecond?, avoiding long long divide */ + work = loops_per_sec; + work *= 4295; /* 4295 = 2^32 / 1e6 */ + conv_us_to_clocks = (work>>32); + + /* Carrier period in clocks, approach good up to 32GHz clock, + gets carrier frequency within 8Hz */ + period = loops_per_sec>>3; + period /= (freq>>3); + + /* Derive pulse and space from the period */ + + pulse_width = period*duty_cycle/100; + space_width = period - pulse_width; + dprintk("in init_timing_params, freq=%d, duty_cycle=%d, " + "clk/jiffy=%ld, pulse=%ld, space=%ld, " + "conv_us_to_clocks=%ld\n", + freq, duty_cycle, current_cpu_data.loops_per_jiffy, + pulse_width, space_width, conv_us_to_clocks); + return 0; +} +#else /* ! USE_RDTSC */ +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ +/* period, pulse/space width are kept with 8 binary places - + * IE multiplied by 256. */ + if (256*1000000L/new_freq*new_duty_cycle/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return -EINVAL; + if (256*1000000L/new_freq*(100-new_duty_cycle)/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return -EINVAL; + duty_cycle = new_duty_cycle; + freq = new_freq; + period = 256*1000000L/freq; + pulse_width = period*duty_cycle/100; + space_width = period-pulse_width; + dprintk("in init_timing_params, freq=%d pulse=%ld, " + "space=%ld\n", freq, pulse_width, space_width); + return 0; +} +#endif /* USE_RDTSC */ + + +/* return value: space length delta */ + +static long send_pulse_irdeo(unsigned long length) +{ + long rawbits; + int i; + unsigned char output; + unsigned char chunk, shifted; + + /* how many bits have to be sent ? */ + rawbits = length*1152/10000; + if (duty_cycle > 50) + chunk = 3; + else + chunk = 1; + for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) { + shifted = chunk<<(i*3); + shifted >>= 1; + output &= (~shifted); + i++; + if (i == 3) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_THRE)); + output = 0x7f; + i = 0; + } + } + if (i != 0) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_TEMT)); + } + + if (i == 0) + return ((-rawbits)*10000/1152); + else + return ((3-i)*3*10000/1152+(-rawbits)*10000/1152); +} + +#ifdef USE_RDTSC +/* Version that uses Pentium rdtsc instruction to measure clocks */ + +/* This version does sub-microsecond timing using rdtsc instruction, + * and does away with the fudged LIRC_SERIAL_TRANSMITTER_LATENCY + * Implicitly i586 architecture... - Steve + */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long target, start, now; + + /* Get going quick as we can */ + rdtscl(start); on(); + /* Convert length from microseconds to clocks */ + length *= conv_us_to_clocks; + /* And loop till time is up - flipping at right intervals */ + now = start; + target = pulse_width; + flag = 1; + while ((now-start) < length) { + /* Delay till flip time */ + do + rdtscl(now); + while ((now-start) < target); + + /* flip */ + if (flag) { + rdtscl(now); off(); + target += space_width; + } else { + rdtscl(now); on(); + target += pulse_width; + } + flag = !flag; + } + rdtscl(now); + return (((now-start)-length)/conv_us_to_clocks); +} +#else /* ! USE_RDTSC */ +/* Version using udelay() */ + +/* here we use fixed point arithmetic, with 8 + fractional bits. that gets us within 0.1% or so of the right average + frequency, albeit with some jitter in pulse length - Steve */ + +/* To match 8 fractional bits used for pulse/space length */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long actual, target, d; + length <<= 8; + + actual = 0; target = 0; flag = 0; + while (actual < length) { + if (flag) { + off(); + target += space_width; + } else { + on(); + target += pulse_width; + } + d = (target-actual-LIRC_SERIAL_TRANSMITTER_LATENCY+128)>>8; + /* Note - we've checked in ioctl that the pulse/space + widths are big enough so that d is > 0 */ + udelay(d); + actual += (d<<8)+LIRC_SERIAL_TRANSMITTER_LATENCY; + flag = !flag; + } + return ((actual-length)>>8); +} +#endif /* USE_RDTSC */ + +static long send_pulse_homebrew(unsigned long length) +{ + if (length <= 0) + return 0; + + if (softcarrier) + return send_pulse_homebrew_softcarrier(length); + else { + on(); + safe_udelay(length); + return 0; + } +} + +static void send_space_irdeo(long length) +{ + if (length <= 0) + return; + + safe_udelay(length); +} + +static void send_space_homebrew(long length) +{ + off(); + if (length <= 0) + return; + safe_udelay(length); +} + +static inline void rbwrite(lirc_t l) +{ + if (lirc_buffer_full(&rbuf)) { + /* no new signals will be accepted */ + dprintk("Buffer overrun\n"); + return; + } + _lirc_buffer_write_1(&rbuf, (void *)&l); +} + +static inline void frbwrite(lirc_t l) +{ + /* simple noise filter */ + static lirc_t pulse = 0L, space = 0L; + static unsigned int ptr; + + if (ptr > 0 && (l&PULSE_BIT)) { + pulse += l&PULSE_MASK; + if (pulse > 250) { + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + return; + } + if (!(l&PULSE_BIT)) { + if (ptr == 0) { + if (l > 20000) { + space = l; + ptr++; + return; + } + } else { + if (l > 20000) { + space += pulse; + if (space > PULSE_MASK) + space = PULSE_MASK; + space += l; + if (space > PULSE_MASK) + space = PULSE_MASK; + pulse = 0; + return; + } + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + } + rbwrite(l); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) +static irqreturn_t irq_handler(int i, void *blah) +#else +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) +#endif +{ + struct timeval tv; + int status, counter, dcd; + long deltv; + lirc_t data; + static int last_dcd = -1; + + if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { + /* not our interrupt */ + return IRQ_RETVAL(IRQ_NONE); + } + + counter = 0; + do { + counter++; + status = sinp(UART_MSR); + if (counter > RS_ISR_PASS_LIMIT) { + printk(KERN_WARNING LIRC_DRIVER_NAME ": AIEEEE: " + "We're caught!\n"); + break; + } + if ((status&hardware[type].signal_pin_change) && sense != -1) { + /* get current time */ + do_gettimeofday(&tv); + + /* New mode, written by Trent Piepho + . */ + + /* The old format was not very portable. + We now use the type lirc_t to pass pulses + and spaces to user space. + + If PULSE_BIT is set a pulse has been + received, otherwise a space has been + received. The driver needs to know if your + receiver is active high or active low, or + the space/pulse sense could be + inverted. The bits denoted by PULSE_MASK are + the length in microseconds. Lengths greater + than or equal to 16 seconds are clamped to + PULSE_MASK. All other bits are unused. + This is a much simpler interface for user + programs, as well as eliminating "out of + phase" errors with space/pulse + autodetection. */ + + /* calculate time since last interrupt in + microseconds */ + dcd = (status & hardware[type].signal_pin) ? 1:0; + + if (dcd == last_dcd) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": ignoring spike: %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + continue; + } + + deltv = tv.tv_sec-lasttv.tv_sec; + if (tv.tv_sec < lasttv.tv_sec || + (tv.tv_sec == lasttv.tv_sec && + tv.tv_usec < lasttv.tv_usec)) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: your clock just jumped " + "backwards\n"); + printk(KERN_WARNING LIRC_DRIVER_NAME + ": %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + data = PULSE_MASK; + } else if (deltv > 15) { + data = PULSE_MASK; /* really long time */ + if (!(dcd^sense)) { + /* sanity check */ + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: " + "%d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + /* detecting pulse while this + MUST be a space! */ + sense = sense ? 0:1; + } + } else + data = (lirc_t) (deltv*1000000 + + tv.tv_usec - + lasttv.tv_usec); + frbwrite(dcd^sense ? data : (data|PULSE_BIT)); + lasttv = tv; + last_dcd = dcd; + wake_up_interruptible(&rbuf.wait_poll); + } + } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void hardware_init_port(void) +{ + unsigned long flags; + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { + /* Setup NSLU2 UART */ + + /* Enable UART */ + soutp(UART_IER, sinp(UART_IER) | UART_IE_IXP42X_UUE); + /* Disable Receiver data Time out interrupt */ + soutp(UART_IER, sinp(UART_IER) & ~UART_IE_IXP42X_RTOIE); + /* set out2 = interupt unmask; off() doesn't set MCR + on NSLU2 */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + } +#endif + + /* Set line for power source */ + off(); + + /* Clear registers again to be sure. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + switch (type) { + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + /* setup port to 7N1 @ 115200 Baud */ + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + /* Set DLAB 0 + 7N1 */ + soutp(UART_LCR, UART_LCR_WLEN7); + /* THR interrupt already disabled at this point */ + break; + default: + break; + } + + local_irq_restore(flags); +} + +static int init_port(void) +{ + int i, nlow, nhigh; + + /* Reserve io region. */ +#if defined(LIRC_ALLOW_MMAPPED_IO) + /* Future MMAP-Developers: Attention! + For memory mapped I/O you *might* need to use ioremap() first, + for the NSLU2 it's done in boot code. */ + if (((iommap != 0) + && (request_mem_region(iommap, 8<= nhigh ? 1 : 0); + printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active " + "%s receiver\n", sense ? "low":"high"); + } else + printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " + "%s receiver\n", sense ? "low":"high"); + + return 0; +} + +static int set_use_inc(void *data) +{ + int result; + unsigned long flags; + + /* Init read buffer. */ + if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) + return -ENOMEM; + + /* initialize timestamp */ + do_gettimeofday(&lasttv); + + result = request_irq(irq, irq_handler, + IRQF_DISABLED | (share_irq ? IRQF_SHARED:0), + LIRC_DRIVER_NAME, (void *)&hardware); + + switch (result) { + case -EBUSY: + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); + lirc_buffer_free(&rbuf); + return -EBUSY; + case -EINVAL: + printk(KERN_ERR LIRC_DRIVER_NAME + ": Bad irq number or handler\n"); + lirc_buffer_free(&rbuf); + return -EINVAL; + default: + dprintk("Interrupt %d, port %04x obtained\n", irq, io); + break; + }; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + + local_irq_restore(flags); + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ unsigned long flags; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + local_irq_restore(flags); + + free_irq(irq, (void *)&hardware); + + dprintk("freed IRQ %d\n", irq); + lirc_buffer_free(&rbuf); + + MOD_DEC_USE_COUNT; +} + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count; + unsigned long flags; + long delta = 0; + + if (!(hardware[type].features&LIRC_CAN_SEND_PULSE)) + return -EBADF; + + if (n % sizeof(lirc_t)) + return -EINVAL; + count = n / sizeof(lirc_t); + if (count > WBUF_LEN || count % 2 == 0) + return -EINVAL; + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + local_irq_save(flags); + if (type == LIRC_IRDEO) { + /* DTR, RTS down */ + on(); + } + for (i = 0; i < count; i++) { + if (i%2) + hardware[type].send_space(wbuf[i]-delta); + else + delta = hardware[type].send_pulse(wbuf[i]); + } + off(); + local_irq_restore(flags); + return n; +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long value; + unsigned int ivalue; + + switch (cmd) { + case LIRC_GET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = put_user(LIRC_SEND2MODE + (hardware[type].features&LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = get_user(value, (unsigned long *) arg); + if (result) + return result; + /* only LIRC_MODE_PULSE supported */ + if (value != LIRC_MODE_PULSE) + return -ENOSYS; + break; + + case LIRC_GET_LENGTH: + return -ENOSYS; + break; + + case LIRC_SET_SEND_DUTY_CYCLE: + dprintk("SET_SEND_DUTY_CYCLE\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + return init_timing_params(ivalue, freq); + break; + + case LIRC_SET_SEND_CARRIER: + dprintk("SET_SEND_CARRIER\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue > 500000 || ivalue < 20000) + return -EINVAL; + return init_timing_params(duty_cycle, ivalue); + break; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .rbuf = &rbuf, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .ioctl = lirc_ioctl, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +static struct platform_device *lirc_serial_dev; + +static int __devinit lirc_serial_probe(struct platform_device *dev) +{ + return 0; +} + +static int __devexit lirc_serial_remove(struct platform_device *dev) +{ + return 0; +} + +static int lirc_serial_suspend(struct platform_device *dev, + pm_message_t state) +{ + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* Disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + return 0; +} + +static int lirc_serial_resume(struct platform_device *dev) +{ + unsigned long flags; + + hardware_init_port(); + + local_irq_save(flags); + /* Enable Interrupt */ + do_gettimeofday(&lasttv); + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + off(); + + lirc_buffer_clear(&rbuf); + + local_irq_restore(flags); + + return 0; +} + +static struct platform_driver lirc_serial_driver = { + .probe = lirc_serial_probe, + .remove = __devexit_p(lirc_serial_remove), + .suspend = lirc_serial_suspend, + .resume = lirc_serial_resume, + .driver = { + .name = "lirc_serial", + .owner = THIS_MODULE, + }, +}; + +static int __init lirc_serial_init(void) +{ + int result; + + result = platform_driver_register(&lirc_serial_driver); + if (result) { + printk("lirc register returned %d\n", result); + return result; + } + + lirc_serial_dev = platform_device_alloc("lirc_serial", 0); + if (!lirc_serial_dev) { + result = -ENOMEM; + goto exit_driver_unregister; + } + + result = platform_device_add(lirc_serial_dev); + if (result) + goto exit_device_put; + + return 0; + +exit_device_put: + platform_device_put(lirc_serial_dev); +exit_driver_unregister: + platform_driver_unregister(&lirc_serial_driver); + return result; +} + +static void __exit lirc_serial_exit(void) +{ + platform_device_unregister(lirc_serial_dev); + platform_driver_unregister(&lirc_serial_driver); +} +#endif + +int __init init_module(void) +{ + int result; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + result = lirc_serial_init(); + if (result) + return result; +#endif + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + case LIRC_ANIMAX: + case LIRC_IGOR: +#if defined(LIRC_SERIAL_NSLU2) + case LIRC_NSLU2: +#endif + break; + default: + result = -EINVAL; + goto exit_serial_exit; + } + if (!softcarrier) { + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IGOR: + case LIRC_NSLU2: + hardware[type].features &= + ~(LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER); + break; + } + } + result = init_port(); + if (result < 0) + goto exit_serial_exit; + plugin.features = hardware[type].features; + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": register_chrdev failed!\n"); + result = -EIO; + goto exit_release; + } + return 0; +exit_release: + release_region(io, 8); +exit_serial_exit: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_exit(); +#endif + return result; +} + +void __exit cleanup_module(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_exit(); +#endif +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) + release_mem_region(iommap, 8< + * + * 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "This driver needs kernel version 2.4.0 or higher" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +static int poll_main(void); +static int atir_init_start(void); + +static void write_index(unsigned char index, unsigned int value); +static unsigned int read_index(unsigned char index); + +static void do_i2c_start(void); +static void do_i2c_stop(void); + +static void seems_wr_byte(unsigned char al); +static unsigned char seems_rd_byte(void); + +static unsigned int read_index(unsigned char al); +static void write_index(unsigned char ah, unsigned int edx); + +static void cycle_delay(int cycle); + +static void do_set_bits(unsigned char bl); +static unsigned char do_get_bits(void); + +#define DATA_PCI_OFF 0x7FFC00 +#define WAIT_CYCLE 20 + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +static int atir_minor; +static unsigned long pci_addr_phys; +static unsigned char *pci_addr_lin; + +static struct lirc_plugin atir_plugin; + +static struct pci_dev *do_pci_probe(void) +{ + struct pci_dev *my_dev; +#ifndef KERNEL_2_5 + /* unnecessary with recent kernels */ + if (!pci_present()) + printk(KERN_ERR "ATIR: no pci in this kernel\n"); +#endif + my_dev = pci_get_device(PCI_VENDOR_ID_ATI, + PCI_DEVICE_ID_ATI_264VT, NULL); + if (my_dev) { + printk(KERN_ERR "ATIR: Using device: %s\n", + pci_name(my_dev)); + pci_addr_phys = 0; + if (my_dev->resource[0].flags & IORESOURCE_MEM) { + pci_addr_phys = my_dev->resource[0].start; + printk(KERN_INFO "ATIR memory at 0x%08X \n", + (unsigned int)pci_addr_phys); + } + if (pci_addr_phys == 0) { + printk(KERN_ERR "ATIR no memory resource ?\n"); + return NULL; + } + } else { + printk(KERN_ERR "ATIR: pci_prob failed\n"); + return NULL; + } + return my_dev; +} + +static int atir_add_to_buf(void *data, struct lirc_buffer *buf) +{ + unsigned char key; + int status; + status = poll_main(); + key = (status >> 8) & 0xFF; + if (status & 0xFF) { + dprintk("ATIR reading key %02X\n", key); + lirc_buffer_write_1(buf, &key); + return 0; + } + return -ENODATA; +} + +static int atir_set_use_inc(void *data) +{ + MOD_INC_USE_COUNT; + dprintk("ATIR driver is opened\n"); + return 0; +} + +static void atir_set_use_dec(void *data) +{ + MOD_DEC_USE_COUNT; + dprintk("ATIR driver is closed\n"); +} + +int init_module(void) +{ + struct pci_dev *pdev; + + pdev = do_pci_probe(); + if (pdev == NULL) + return 1; + + if (!atir_init_start()) + return 1; + + strcpy(atir_plugin.name, "ATIR"); + atir_plugin.minor = -1; + atir_plugin.code_length = 8; + atir_plugin.sample_rate = 10; + atir_plugin.data = 0; + atir_plugin.add_to_buf = atir_add_to_buf; + atir_plugin.set_use_inc = atir_set_use_inc; + atir_plugin.set_use_dec = atir_set_use_dec; +#ifdef LIRC_HAVE_SYSFS + atir_plugin.dev = &pdev->dev; +#endif + atir_plugin.owner = THIS_MODULE; + + atir_minor = lirc_register_plugin(&atir_plugin); + dprintk("ATIR driver is registered on minor %d\n", atir_minor); + + return 0; +} + + +void cleanup_module(void) +{ + lirc_unregister_plugin(atir_minor); +} + + +static int atir_init_start(void) +{ + pci_addr_lin = ioremap(pci_addr_phys + DATA_PCI_OFF, 0x400); + if (pci_addr_lin == 0) { + printk(KERN_INFO "atir: pci mem must be mapped\n"); + return 0; + } + return 1; +} + +static void cycle_delay(int cycle) +{ + udelay(WAIT_CYCLE*cycle); +} + + +static int poll_main() +{ + unsigned char status_high, status_low; + + do_i2c_start(); + + seems_wr_byte(0xAA); + seems_wr_byte(0x01); + + do_i2c_start(); + + seems_wr_byte(0xAB); + + status_low = seems_rd_byte(); + status_high = seems_rd_byte(); + + do_i2c_stop(); + + return (status_high << 8) | status_low; +} + +static void do_i2c_start(void) +{ + do_set_bits(3); + cycle_delay(4); + + do_set_bits(1); + cycle_delay(7); + + do_set_bits(0); + cycle_delay(2); +} + +static void do_i2c_stop(void) +{ + unsigned char bits; + bits = do_get_bits() & 0xFD; + do_set_bits(bits); + cycle_delay(1); + + bits |= 1; + do_set_bits(bits); + cycle_delay(2); + + bits |= 2; + do_set_bits(bits); + bits = 3; + do_set_bits(bits); + cycle_delay(2); +} + +static void seems_wr_byte(unsigned char value) +{ + int i; + unsigned char reg; + + reg = do_get_bits(); + for (i = 0; i < 8; i++) { + if (value & 0x80) + reg |= 0x02; + else + reg &= 0xFD; + + do_set_bits(reg); + cycle_delay(1); + + reg |= 1; + do_set_bits(reg); + cycle_delay(1); + + reg &= 0xFE; + do_set_bits(reg); + cycle_delay(1); + value <<= 1; + } + cycle_delay(2); + + reg |= 2; + do_set_bits(reg); + + reg |= 1; + do_set_bits(reg); + + cycle_delay(1); + do_get_bits(); + + reg &= 0xFE; + do_set_bits(reg); + cycle_delay(3); +} + +static unsigned char seems_rd_byte(void) +{ + int i; + int rd_byte; + unsigned char bits_2, bits_1; + + bits_1 = do_get_bits() | 2; + do_set_bits(bits_1); + + rd_byte = 0; + for (i = 0; i < 8; i++) { + bits_1 &= 0xFE; + do_set_bits(bits_1); + cycle_delay(2); + + bits_1 |= 1; + do_set_bits(bits_1); + cycle_delay(1); + + bits_2 = do_get_bits(); + if (bits_2 & 2) + rd_byte |= 1; + + rd_byte <<= 1; + } + + bits_1 = 0; + if (bits_2 == 0) + bits_1 |= 2; + + do_set_bits(bits_1); + cycle_delay(2); + + bits_1 |= 1; + do_set_bits(bits_1); + cycle_delay(3); + + bits_1 &= 0xFE; + do_set_bits(bits_1); + cycle_delay(2); + + rd_byte >>= 1; + rd_byte &= 0xFF; + return rd_byte; +} + +static void do_set_bits(unsigned char new_bits) +{ + int reg_val; + reg_val = read_index(0x34); + if (new_bits & 2) { + reg_val &= 0xFFFFFFDF; + reg_val |= 1; + } else { + reg_val &= 0xFFFFFFFE; + reg_val |= 0x20; + } + reg_val |= 0x10; + write_index(0x34, reg_val); + + reg_val = read_index(0x31); + if (new_bits & 1) { + reg_val |= 0x1000000; + } else { + reg_val &= 0xFEFFFFFF; + } + reg_val |= 0x8000000; + write_index(0x31, reg_val); +} + +static unsigned char do_get_bits(void) +{ + unsigned char bits; + int reg_val; + + reg_val = read_index(0x34); + reg_val |= 0x10; + reg_val &= 0xFFFFFFDF; + write_index(0x34, reg_val); + + reg_val = read_index(0x34); + bits = 0; + if (reg_val & 8) { + bits |= 2; + } else { + bits &= 0xFD; + } + reg_val = read_index(0x31); + if (reg_val & 0x1000000) { + bits |= 1; + } else { + bits &= 0xFE; + } + return bits; +} + +static unsigned int read_index(unsigned char index) +{ + unsigned char *addr; + unsigned int value; + /* addr = pci_addr_lin + DATA_PCI_OFF + ((index & 0xFF) << 2); */ + addr = pci_addr_lin + ((index & 0xFF) << 2); + value = readl(addr); + return value; +} + +static void write_index(unsigned char index, unsigned int reg_val) +{ + unsigned char *addr; + addr = pci_addr_lin + ((index & 0xFF) << 2); + writel(reg_val, addr); +} + +MODULE_AUTHOR("Froenchenko Leonid"); +MODULE_DESCRIPTION("IR remote driver for bt829 based TV cards"); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +EXPORT_NO_SYMBOLS; + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_atiusb/lirc_atiusb.c +++ linux-2.6.28/ubuntu/lirc/lirc_atiusb/lirc_atiusb.c @@ -0,0 +1,1437 @@ +/* lirc_atiusb - USB remote support for LIRC + * (currently only supports X10 USB remotes) + * (supports ATI Remote Wonder and ATI Remote Wonder II, too) + * + * Copyright (C) 2003-2004 Paul Miller + * + * This driver was derived from: + * Vladimir Dergachev 's 2002 + * "USB ATI Remote support" (input device) + * Adrian Dewhurst 's 2002 + * "USB StreamZap remote driver" (LIRC) + * Artur Lipowski 's 2002 + * "lirc_dev" and "lirc_gpio" LIRC modules + * Michael Wojciechowski + * initial xbox support + * Vassilis Virvilis 2006 + * reworked the patch for lirc submission + * + * $Id: lirc_atiusb.c,v 1.69 2008/04/28 06:47:29 lirc Exp $ + */ + +/* + * 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.4.0 or higher" +#error "*******************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include +#include +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#define DRIVER_VERSION "$Revision: 1.69 $" +#define DRIVER_AUTHOR "Paul Miller " +#define DRIVER_DESC "USB remote driver for LIRC" +#define DRIVER_NAME "lirc_atiusb" + +#define CODE_LENGTH code_length[ir->remote_type] +#define CODE_MIN_LENGTH code_min_length[ir->remote_type] +#define DECODE_LENGTH decode_length[ir->remote_type] + +#define RW2_MODENAV_KEYCODE 0x3F +#define RW2_NULL_MODE 0xFF +/* Fake (virtual) keycode indicating compass mouse usage */ +#define RW2_MOUSE_KEYCODE 0xFF +#define RW2_PRESSRELEASE_KEYCODE 0xFE + +#define RW2_PRESS_CODE 1 +#define RW2_HOLD_CODE 2 +#define RW2_RELEASE_CODE 0 + +/* module parameters */ +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +/* ATI, ATI2, XBOX */ +static const int code_length[] = {5, 3, 6}; +static const int code_min_length[] = {3, 3, 6}; +static const int decode_length[] = {5, 3, 1}; +/* USB_BUFF_LEN must be the maximum value of the code_length array. + * It is used for static arrays. */ +#define USB_BUFF_LEN 6 + +static int mask = 0xFFFF; /* channel acceptance bit mask */ +static int unique; /* enable channel-specific codes */ +static int repeat = 10; /* repeat time in 1/100 sec */ +static int emit_updown; /* send seperate press/release codes (rw2) */ +static int emit_modekeys; /* send keycodes for aux1-4, pc, and mouse (rw2) */ +static unsigned long repeat_jiffies; /* repeat timeout */ +static int mdeadzone; /* mouse sensitivity >= 0 */ +static int mgradient = 375; /* 1000*gradient from cardinal direction */ + +/* get hi and low bytes of a 16-bits int */ +#define HI(a) ((unsigned char)((a) >> 8)) +#define LO(a) ((unsigned char)((a) & 0xff)) + +/* lock irctl structure */ +#define IRLOCK down_interruptible(&ir->lock) +#define IRUNLOCK up(&ir->lock) + +/* general constants */ +#define SUCCESS 0 +#define SEND_FLAG_IN_PROGRESS 1 +#define SEND_FLAG_COMPLETE 2 +#define FREE_ALL 0xFF + +/* endpoints */ +#define EP_KEYS 0 +#define EP_MOUSE 1 +#define EP_MOUSE_ADDR 0x81 +#define EP_KEYS_ADDR 0x82 + +#define VENDOR_ATI1 0x0bc7 +#define VENDOR_ATI2 0x0471 +#define VENDOR_MS1 0x040b +#define VENDOR_MS2 0x045e +#define VENDOR_MS3 0xFFFF + +static struct usb_device_id usb_remote_table [] = { + /* X10 USB Firecracker Interface */ + { USB_DEVICE(VENDOR_ATI1, 0x0002) }, + + /* X10 VGA Video Sender */ + { USB_DEVICE(VENDOR_ATI1, 0x0003) }, + + /* ATI Wireless Remote Receiver */ + { USB_DEVICE(VENDOR_ATI1, 0x0004) }, + + /* NVIDIA Wireless Remote Receiver */ + { USB_DEVICE(VENDOR_ATI1, 0x0005) }, + + /* ATI Wireless Remote Receiver */ + { USB_DEVICE(VENDOR_ATI1, 0x0006) }, + + /* X10 USB Wireless Transceivers */ + { USB_DEVICE(VENDOR_ATI1, 0x0007) }, + { USB_DEVICE(VENDOR_ATI1, 0x0008) }, + { USB_DEVICE(VENDOR_ATI1, 0x0009) }, + { USB_DEVICE(VENDOR_ATI1, 0x000A) }, + { USB_DEVICE(VENDOR_ATI1, 0x000B) }, + { USB_DEVICE(VENDOR_ATI1, 0x000C) }, + { USB_DEVICE(VENDOR_ATI1, 0x000D) }, + { USB_DEVICE(VENDOR_ATI1, 0x000E) }, + { USB_DEVICE(VENDOR_ATI1, 0x000F) }, + + /* ATI Remote Wonder 2: Input Device */ + { USB_DEVICE(VENDOR_ATI2, 0x0602) }, + + /* ATI Remote Wonder 2: Controller (???) */ + { USB_DEVICE(VENDOR_ATI2, 0x0603) }, + + /* Gamester Xbox DVD Movie Playback Kit IR */ + { USB_DEVICE(VENDOR_MS1, 0x6521) }, + + /* Microsoft Xbox DVD Movie Playback Kit IR */ + { USB_DEVICE(VENDOR_MS2, 0x0284) }, + + /* Some chinese manufacterer -- conflicts with the joystick from the + * same manufacterer */ + { USB_DEVICE(VENDOR_MS3, 0xFFFF) }, + + /* Terminating entry */ + { } +}; + + +/* init strings */ +#define USB_OUTLEN 7 + +static char init1[] = {0x01, 0x00, 0x20, 0x14}; +static char init2[] = {0x01, 0x00, 0x20, 0x14, 0x20, 0x20, 0x20}; + +struct in_endpt { + /* inner link in list of endpoints for the remote specified by ir */ + struct list_head iep_list_link; + struct irctl *ir; + struct urb *urb; + struct usb_endpoint_descriptor *ep; + int type; + + /* buffers and dma */ + unsigned char *buf; + unsigned int len; +#ifdef KERNEL_2_5 + dma_addr_t dma; +#endif + + /* handle repeats */ + unsigned char old[USB_BUFF_LEN]; + unsigned long old_jiffies; +}; + +struct out_endpt { + struct irctl *ir; + struct urb *urb; + struct usb_endpoint_descriptor *ep; + + /* buffers and dma */ + unsigned char *buf; +#ifdef KERNEL_2_5 + dma_addr_t dma; +#endif + + /* handle sending (init strings) */ + int send_flags; + wait_queue_head_t wait; +}; + + +/* data structure for each usb remote */ +struct irctl { + /* inner link in list of all remotes managed by this module */ + struct list_head remote_list_link; + /* Number of usb interfaces associated with this device */ + int dev_refcount; + + /* usb */ + struct usb_device *usbdev; + /* Head link to list of all inbound endpoints in this remote */ + struct list_head iep_listhead; + struct out_endpt *out_init; + int devnum; + + /* remote type based on usb_device_id tables */ + enum { + ATI1_COMPATIBLE, + ATI2_COMPATIBLE, + XBOX_COMPATIBLE + } remote_type; + + /* rw2 current mode (mirror's remote's state) */ + int mode; + + /* lirc */ + struct lirc_plugin *p; + int connected; + + /* locking */ + struct semaphore lock; +}; + +/* list of all registered devices via the remote_list_link in irctl */ +static struct list_head remote_list; + +/* Convenience macros to retrieve a pointer to the surrounding struct from + * the given list_head reference within, pointed at by link. */ +#define get_iep_from_link(link) \ + list_entry((link), struct in_endpt, iep_list_link); +#define get_irctl_from_link(link) \ + list_entry((link), struct irctl, remote_list_link); + +/* send packet - used to initialize remote */ +static void send_packet(struct out_endpt *oep, u16 cmd, unsigned char *data) +{ + struct irctl *ir = oep->ir; + DECLARE_WAITQUEUE(wait, current); + int timeout = HZ; /* 1 second */ + unsigned char buf[USB_OUTLEN]; + + dprintk(DRIVER_NAME "[%d]: send called (%#x)\n", ir->devnum, cmd); + + IRLOCK; + oep->urb->transfer_buffer_length = LO(cmd) + 1; + oep->urb->dev = oep->ir->usbdev; + oep->send_flags = SEND_FLAG_IN_PROGRESS; + + memcpy(buf+1, data, LO(cmd)); + buf[0] = HI(cmd); + memcpy(oep->buf, buf, LO(cmd)+1); + + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&oep->wait, &wait); + +#ifdef KERNEL_2_5 + if (usb_submit_urb(oep->urb, GFP_ATOMIC)) { +#else + if (usb_submit_urb(oep->urb)) { +#endif + set_current_state(TASK_RUNNING); + remove_wait_queue(&oep->wait, &wait); + IRUNLOCK; + return; + } + IRUNLOCK; + + while (timeout && (oep->urb->status == -EINPROGRESS) + && !(oep->send_flags & SEND_FLAG_COMPLETE)) { + timeout = schedule_timeout(timeout); + rmb(); + } + + dprintk(DRIVER_NAME "[%d]: send complete (%#x)\n", ir->devnum, cmd); + + set_current_state(TASK_RUNNING); + remove_wait_queue(&oep->wait, &wait); +#ifdef KERNEL_2_5 + oep->urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(oep->urb); +} + +static int unregister_from_lirc(struct irctl *ir) +{ + struct lirc_plugin *p = ir->p; + int devnum; + + devnum = ir->devnum; + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); + + lirc_unregister_plugin(p->minor); + + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); + return SUCCESS; +} + + +static int set_use_inc(void *data) +{ + struct irctl *ir = data; + struct list_head *pos, *n; + struct in_endpt *iep; + int rtn; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); + return -EIO; + } + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); + + MOD_INC_USE_COUNT; + + IRLOCK; + if (!ir->connected) { + if (!ir->usbdev) { + IRUNLOCK; + dprintk(DRIVER_NAME "[%d]: !ir->usbdev\n", ir->devnum); + return -ENOENT; + } + + /* Iterate through the inbound endpoints */ + list_for_each_safe(pos, n, &ir->iep_listhead) { + /* extract the current in_endpt */ + iep = get_iep_from_link(pos); + iep->urb->dev = ir->usbdev; + dprintk(DRIVER_NAME "[%d]: linking iep 0x%02x (%p)\n", + ir->devnum, iep->ep->bEndpointAddress, iep); +#ifdef KERNEL_2_5 + rtn = usb_submit_urb(iep->urb, GFP_ATOMIC); +#else + rtn = usb_submit_urb(iep->urb); +#endif + if (rtn) { + printk(DRIVER_NAME "[%d]: open result = %d " + "error submitting urb\n", + ir->devnum, rtn); + IRUNLOCK; + MOD_DEC_USE_COUNT; + return -EIO; + } + } + ir->connected = 1; + } + IRUNLOCK; + + return SUCCESS; +} + +static void set_use_dec(void *data) +{ + struct irctl *ir = data; + struct list_head *pos, *n; + struct in_endpt *iep; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); + return; + } + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); + + IRLOCK; + if (ir->connected) { + /* Free inbound usb urbs */ + list_for_each_safe(pos, n, &ir->iep_listhead) { + iep = get_iep_from_link(pos); + dprintk(DRIVER_NAME "[%d]: unlinking iep 0x%02x (%p)\n", + ir->devnum, iep->ep->bEndpointAddress, iep); + usb_kill_urb(iep->urb); + } + ir->connected = 0; + } + IRUNLOCK; + MOD_DEC_USE_COUNT; +} + +static void print_data(struct in_endpt *iep, char *buf, int len) +{ + const int clen = code_length[iep->ir->remote_type]; + char codes[clen * 3 + 1]; + int i; + + if (len <= 0) + return; + + for (i = 0; i < len && i < clen; i++) + snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF); + printk(DRIVER_NAME "[%d]: data received %s (ep=0x%x length=%d)\n", + iep->ir->devnum, codes, iep->ep->bEndpointAddress, len); +} + +static int code_check_ati1(struct in_endpt *iep, int len) +{ + struct irctl *ir = iep->ir; + int i, chan; + + /* ATI RW1: some remotes emit both 4 and 5 byte length codes. */ + /* ATI RW2: emit 3 byte codes */ + if (len < CODE_MIN_LENGTH || len > CODE_LENGTH) + return -1; + + /* *** channel not tested with 4/5-byte Dutch remotes *** */ + chan = ((iep->buf[len-1]>>4) & 0x0F); + + /* strip channel code */ + if (!unique) { + iep->buf[len-1] &= 0x0F; + iep->buf[len-3] -= (chan<<4); + } + + if (!((1U<devnum, chan+1); + return -1; + } + dprintk(DRIVER_NAME "[%d]: accept channel %d\n", ir->devnum, chan+1); + + if (ir->remote_type == ATI1_COMPATIBLE) { + for (i = len; i < CODE_LENGTH; i++) iep->buf[i] = 0; + /* check for repeats */ + if (memcmp(iep->old, iep->buf, len) == 0) { + if (iep->old_jiffies + repeat_jiffies > jiffies) + return -1; + } else + memcpy(iep->old, iep->buf, CODE_LENGTH); + iep->old_jiffies = jiffies; + } + + return SUCCESS; +} + +/* + * Since the ATI Remote Wonder II has quite a different structure from the + * prior version, this function was seperated out to clarify the sanitization + * process. + * + * Here is a summary of the main differences: + * + * a. The rw2 has no sense of a transmission channel. But, it does have an + * auxilliary mode state, which is set by the mode buttons Aux1 through + * Aux4 and "PC". These map respectively to 0-4 in the first byte of the + * recv buffer. Any subsequent button press sends this mode number as its + * "channel code." Annoyingly enough, the mode setting buttons all send + * the same key code (0x3f), and can only be distinguished via their mode + * byte. + * + * Because of this, old-style "unique"-parameter-enabled channel squashing + * kills the functionality of the aux1-aux4 and PC buttons. However, to + * not do so would cause each remote key to send a different code depending + * on the active aux. Further complicating matters, using the mouse norb + * also sends an identical code as would pushing the active aux button. To + * handle this we need a seperate parameter, like rw2modes, with the + * following values and meanings: + * + * 0: Don't squash any channel info + * 1: Only squash channel data for non-mode setting keys + * 2: Ignore aux keypresses, but don't squash channel + * 3: Ignore aux keypresses and squash channel data + * + * Option 1 may seem useless since the mouse sends the same code, but one + * need only ignore in userspace any press of a mode-setting code that only + * reaffirms the current mode. The 3rd party lirccd should be able to + * handle this easily enough, but lircd doesn't keep the state necessary + * for this. TODO We could work around this in the driver by emitting a + * single 02 (press) code for a mode key only if that mode is not currently + * active. + * + * Option 2 would be useful for those wanting super configurability, + * offering the ability to program 5 times the number actions based on the + * current mode. + * + * b. The rw2 has its own built in repeat handling; the keys endpoint + * encodes this in the second byte as 1 for press, 2 for hold, and 0 for + * release. This is generally much more responsive than lirc's built-in + * timeout handling. + * + * The problem is that the remote can send the release-recieve pair + * (0,1) while one is still holding down the same button if the + * transmission is momentarilly interrupted. (It seems that the receiver + * manages this count instead of the remote.) By default, this information + * is squashed to 2. + * + * In order to expose the built-in repeat code, set the emit_updown + * parameter as described below. + * + * c. The mouse norb is much more sensitive than on the rw1. It emulates + * a joystick-like controller with the second byte representing the x-axis + * and the third, the y-axis. Treated as signed integers, these axes range + * approximately as follows: + * + * x: (left) -46 ... 46 (right) (0xd2..0x2e) + * y: (up) -46 ... 46 (down) (0xd2..0x2e) + * + * NB these values do not correspond to the pressure with which the mouse + * norb is pushed in a given direction, but rather seems to indicate the + * duration for which a given direction is held. + * + * These are normalized to 8 cardinal directions for easy configuration via + * lircd.conf. The normalization can be fined tuned with the mdeadzone and + * mgradient parameters as described below. + * + * d. The interrupt rate of the mouse vs. the normal keys is different. + * + * mouse: ~27Hz (37ms between interrupts) + * keys: ~10Hz (100ms between interrupts) + * + * This means that the normal gap mechanism for lircd won't work as + * expected; is emit_updown>0 if you can get away with it. + */ +static int code_check_ati2(struct in_endpt *iep, int len) +{ + struct irctl *ir = iep->ir; + int mode, i; + char *buf = iep->buf; + + if (len != CODE_LENGTH) { + dprintk(DRIVER_NAME + "[%d]: Huh? Abnormal length (%d) buffer recieved.\n", + ir->devnum, len); + return -1; + } + for (i = len; i < CODE_LENGTH; i++) iep->buf[i] = 0; + + mode = buf[0]; + + /* Squash the mode indicator if unique wasn't set non-zero */ + if (!unique) + buf[0] = 0; + + if (iep->ep->bEndpointAddress == EP_KEYS_ADDR) { + /* ignore mouse navigation indicator key and + * mode-set (aux) keys */ + if (buf[2] == RW2_MODENAV_KEYCODE) { + if (emit_modekeys >= 2) /* emit raw */ + buf[0] = mode; + else if (emit_modekeys == 1) { + /* translate */ + buf[0] = mode; + if (ir->mode != mode) { + buf[1] = 0x03; + ir->mode = mode; + return SUCCESS; + } + } else { + dprintk(DRIVER_NAME + "[%d]: ignore dummy code 0x%x " + "(ep=0x%x)\n", ir->devnum, + buf[2], iep->ep->bEndpointAddress); + return -1; + } + } + + if (buf[1] != 2) { + /* handle press/release codes */ + if (emit_updown == 0) /* ignore */ + return -1; + else if (emit_updown == 1) /* normalize keycode */ + buf[2] = RW2_PRESSRELEASE_KEYCODE; + /* else emit raw */ + } + + } else { + int x = (signed char)buf[1]; + int y = (signed char)buf[2]; + int code = 0x00; + int dir_ew, dir_ns; + + buf[2] = RW2_MOUSE_KEYCODE; + + /* sensitivity threshold (use L2norm^2) */ + if (mdeadzone > (x*x+y*y)) { + buf[1] = 0x00; + return SUCCESS; + } + +/* Nybble encoding: xy, 2 is -1 (S or W); 1 (N or E) */ +#define MOUSE_N 0x01 +#define MOUSE_NE 0x11 +#define MOUSE_E 0x10 +#define MOUSE_SE 0x12 +#define MOUSE_S 0x02 +#define MOUSE_SW 0x22 +#define MOUSE_W 0x20 +#define MOUSE_NW 0x21 + + /* cardinal leanings: positive x -> E, positive y -> S */ + dir_ew = (x > 0) ? MOUSE_E : MOUSE_W; + dir_ns = (y > 0) ? MOUSE_S : MOUSE_N; + + /* convert coordintes(angle) into compass direction */ + if (x == 0) + code = dir_ns; + else if (y == 0) + code = dir_ew; + else { + if (abs(1000*y/x) > mgradient) + code = dir_ns; + if (abs(1000*x/y) > mgradient) + code |= dir_ew; + } + + buf[1] = code; + dprintk(DRIVER_NAME "[%d]: mouse compass=0x%x %s%s (%d,%d)\n", + ir->devnum, code, + (code & MOUSE_S ? "S" : (code & MOUSE_N ? "N" : "")), + (code & MOUSE_E ? "E" : (code & MOUSE_W ? "W" : "")), + x, y); + } + + return SUCCESS; +} + +static int code_check_xbox(struct in_endpt *iep, int len) +{ + struct irctl *ir = iep->ir; + const int clen = CODE_LENGTH; + + if (len != clen) { + dprintk(DRIVER_NAME ": We got %d instead of %d bytes from xbox " + "ir.. ?\n", len, clen); + return -1; + } + + /* check for repeats */ + if (memcmp(iep->old, iep->buf, len) == 0) { + if (iep->old_jiffies + repeat_jiffies > jiffies) + return -1; + } else { + /* the third byte of xbox ir packet seems to contain key info + * the last two bytes are.. some kind of clock? */ + iep->buf[0] = iep->buf[2]; + memset(iep->buf + 1, 0, len - 1); + memcpy(iep->old, iep->buf, len); + } + iep->old_jiffies = jiffies; + + return SUCCESS; +} + +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_remote_recv(struct urb *urb, struct pt_regs *regs) +#else +static void usb_remote_recv(struct urb *urb) +#endif +{ + struct in_endpt *iep; + int len, result = -1; + + if (!urb) + return; + iep = urb->context; + if (!iep) { +#ifdef KERNEL_2_5 + urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(urb); + return; + } + if (!iep->ir->usbdev) + return; + + len = urb->actual_length; + if (debug) + print_data(iep, urb->transfer_buffer, len); + + switch (urb->status) { + + /* success */ + case SUCCESS: + switch (iep->ir->remote_type) { + case XBOX_COMPATIBLE: + result = code_check_xbox(iep, len); + break; + case ATI2_COMPATIBLE: + result = code_check_ati2(iep, len); + break; + case ATI1_COMPATIBLE: + default: + result = code_check_ati1(iep, len); + } + if (result < 0) + break; + lirc_buffer_write_1(iep->ir->p->rbuf, iep->buf); + wake_up(&iep->ir->p->rbuf->wait_poll); + break; + + /* unlink */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: +#ifdef KERNEL_2_5 + urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(urb); + return; + + case -EPIPE: + default: + break; + } + + /* resubmit urb */ +#ifdef KERNEL_2_5 + usb_submit_urb(urb, GFP_ATOMIC); +#endif +} + +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_remote_send(struct urb *urb, struct pt_regs *regs) +#else +static void usb_remote_send(struct urb *urb) +#endif +{ + struct out_endpt *oep; + + if (!urb) + return; + oep = urb->context; + if (!oep) { +#ifdef KERNEL_2_5 + urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(urb); + return; + } + if (!oep->ir->usbdev) + return; + + dprintk(DRIVER_NAME "[%d]: usb out called\n", oep->ir->devnum); + + if (urb->status) + return; + + oep->send_flags |= SEND_FLAG_COMPLETE; + wmb(); + if (waitqueue_active(&oep->wait)) + wake_up(&oep->wait); +} + + +/*************************************************************************** + * Initialization and removal + ***************************************************************************/ + +/* + * Free iep according to mem_failure which specifies a checkpoint into the + * initialization sequence for rollback recovery. + */ +static void free_in_endpt(struct in_endpt *iep, int mem_failure) +{ + struct irctl *ir; + dprintk(DRIVER_NAME ": free_in_endpt(%p, %d)\n", iep, mem_failure); + if (!iep) + return; + + ir = iep->ir; + if (!ir) { + dprintk(DRIVER_NAME ": free_in_endpt: WARNING! null ir\n"); + return; + } + IRLOCK; + switch (mem_failure) { + case FREE_ALL: + case 5: + list_del(&iep->iep_list_link); + dprintk(DRIVER_NAME "[%d]: free_in_endpt removing ep=0x%0x " + "from list\n", ir->devnum, iep->ep->bEndpointAddress); + case 4: + if (iep->urb) { +#ifdef KERNEL_2_5 + iep->urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(iep->urb); + usb_free_urb(iep->urb); + iep->urb = 0; + } else + dprintk(DRIVER_NAME "[%d]: free_in_endpt null urb!\n", + ir->devnum); + case 3: +#ifdef KERNEL_2_5 + usb_buffer_free(iep->ir->usbdev, iep->len, iep->buf, iep->dma); +#else + kfree(iep->buf); +#endif + iep->buf = 0; + case 2: + kfree(iep); + } + IRUNLOCK; +} + +/* + * Construct a new inbound endpoint for this remote, and add it to the list of + * in_epts in ir. + */ +static struct in_endpt *new_in_endpt(struct irctl *ir, + struct usb_endpoint_descriptor *ep) +{ + struct usb_device *dev = ir->usbdev; + struct in_endpt *iep; + int pipe, maxp, len, addr; + int mem_failure; + + addr = ep->bEndpointAddress; + pipe = usb_rcvintpipe(dev, addr); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + +/* len = (maxp > USB_BUFLEN) ? USB_BUFLEN : maxp; + * len -= (len % CODE_LENGTH); */ + len = CODE_LENGTH; + + dprintk(DRIVER_NAME "[%d]: acceptable inbound endpoint (0x%x) found " + "(maxp=%d len=%d)\n", ir->devnum, addr, maxp, len); + + mem_failure = 0; + iep = kmalloc(sizeof(*iep), GFP_KERNEL); + if (!iep) { + mem_failure = 1; + goto new_in_endpt_failure_check; + } + memset(iep, 0, sizeof(*iep)); + iep->ir = ir; + iep->ep = ep; + iep->len = len; + +#ifdef KERNEL_2_5 + iep->buf = usb_buffer_alloc(dev, len, GFP_ATOMIC, &iep->dma); +#else + iep->buf = kmalloc(len, GFP_KERNEL); +#endif + if (!iep->buf) { + mem_failure = 2; + goto new_in_endpt_failure_check; + } + +#ifdef KERNEL_2_5 + iep->urb = usb_alloc_urb(0, GFP_KERNEL); +#else + iep->urb = usb_alloc_urb(0); +#endif + if (!iep->urb) + mem_failure = 3; + +new_in_endpt_failure_check: + + if (mem_failure) { + free_in_endpt(iep, mem_failure); + printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", + ir->devnum, addr, mem_failure); + return NULL; + } + list_add_tail(&iep->iep_list_link, &ir->iep_listhead); + dprintk(DRIVER_NAME "[%d]: adding ep=0x%0x to list\n", + ir->devnum, iep->ep->bEndpointAddress); + return iep; +} + +static void free_out_endpt(struct out_endpt *oep, int mem_failure) +{ + struct irctl *ir; + dprintk(DRIVER_NAME ": free_out_endpt(%p, %d)\n", oep, mem_failure); + if (!oep) + return; + + wake_up_all(&oep->wait); + + ir = oep->ir; + if (!ir) { + dprintk(DRIVER_NAME ": free_out_endpt: WARNING! null ir\n"); + return; + } + IRLOCK; + switch (mem_failure) { + case FREE_ALL: + case 4: + if (oep->urb) { +#ifdef KERNEL_2_5 + oep->urb->transfer_flags |= URB_ASYNC_UNLINK; +#endif + usb_unlink_urb(oep->urb); + usb_free_urb(oep->urb); + oep->urb = 0; + } else { + dprintk(DRIVER_NAME "[%d]: free_out_endpt: null urb!\n", + ir->devnum); + } + case 3: +#ifdef KERNEL_2_5 + usb_buffer_free(oep->ir->usbdev, USB_OUTLEN, + oep->buf, oep->dma); +#else + kfree(oep->buf); +#endif + oep->buf = 0; + case 2: + kfree(oep); + } + IRUNLOCK; +} + +static struct out_endpt *new_out_endpt(struct irctl *ir, + struct usb_endpoint_descriptor *ep) +{ +#ifdef KERNEL_2_5 + struct usb_device *dev = ir->usbdev; +#endif + struct out_endpt *oep; + int mem_failure; + + dprintk(DRIVER_NAME "[%d]: acceptable outbound endpoint (0x%x) found\n", + ir->devnum, ep->bEndpointAddress); + + mem_failure = 0; + oep = kmalloc(sizeof(*oep), GFP_KERNEL); + if (!oep) + mem_failure = 1; + else { + memset(oep, 0, sizeof(*oep)); + oep->ir = ir; + oep->ep = ep; + init_waitqueue_head(&oep->wait); + +#ifdef KERNEL_2_5 + oep->buf = usb_buffer_alloc(dev, USB_OUTLEN, + GFP_ATOMIC, &oep->dma); +#else + oep->buf = kmalloc(USB_OUTLEN, GFP_KERNEL); +#endif + if (!oep->buf) + mem_failure = 2; + else { +#ifdef KERNEL_2_5 + oep->urb = usb_alloc_urb(0, GFP_KERNEL); +#else + oep->urb = usb_alloc_urb(0); +#endif + if (!oep->urb) + mem_failure = 3; + } + } + if (mem_failure) { + free_out_endpt(oep, mem_failure); + printk(DRIVER_NAME "[%d]: ep=0x%x out of memory (code=%d)\n", + ir->devnum, ep->bEndpointAddress, mem_failure); + return NULL; + } + return oep; +} + +static void free_irctl(struct irctl *ir, int mem_failure) +{ + struct list_head *pos, *n; + struct in_endpt *in; + dprintk(DRIVER_NAME ": free_irctl(%p, %d)\n", ir, mem_failure); + + if (!ir) + return; + + list_for_each_safe(pos, n, &ir->iep_listhead) { + in = get_iep_from_link(pos); + free_in_endpt(in, FREE_ALL); + } + if (ir->out_init) { + free_out_endpt(ir->out_init, FREE_ALL); + ir->out_init = NULL; + } + + IRLOCK; + switch (mem_failure) { + case FREE_ALL: + case 6: + if (!--ir->dev_refcount) { + list_del(&ir->remote_list_link); + dprintk(DRIVER_NAME "[%d]: free_irctl: removing " + "remote from list\n", ir->devnum); + } else { + dprintk(DRIVER_NAME "[%d]: free_irctl: refcount at %d," + "aborting free_irctl\n", + ir->devnum, ir->dev_refcount); + IRUNLOCK; + return; + } + case 5: + case 4: + case 3: + if (ir->p) { + switch (mem_failure) { + case 5: + lirc_buffer_free(ir->p->rbuf); + case 4: + kfree(ir->p->rbuf); + case 3: + kfree(ir->p); + } + } else + printk(DRIVER_NAME "[%d]: ir->p is a null pointer!\n", + ir->devnum); + case 2: + IRUNLOCK; + kfree(ir); + return; + } + IRUNLOCK; +} + +static struct irctl *new_irctl(struct usb_device *dev) +{ + struct irctl *ir; + struct lirc_plugin *plugin; + int type, devnum; + int mem_failure; + int dclen; + + devnum = dev->devnum; + + /* determine remote type */ + switch (cpu_to_le16(dev->descriptor.idVendor)) { + case VENDOR_ATI1: + type = ATI1_COMPATIBLE; + break; + case VENDOR_ATI2: + type = ATI2_COMPATIBLE; + break; + case VENDOR_MS1: + case VENDOR_MS2: + case VENDOR_MS3: + type = XBOX_COMPATIBLE; + break; + default: + dprintk(DRIVER_NAME "[%d]: unknown type\n", devnum); + return NULL; + } + dprintk(DRIVER_NAME "[%d]: remote type = %d\n", devnum, type); + + /* allocate kernel memory */ + mem_failure = 0; + ir = kmalloc(sizeof(*ir), GFP_KERNEL); + if (!ir) { + mem_failure = 1; + goto new_irctl_failure_check; + } + + /* at this stage we cannot use the macro [DE]CODE_LENGTH: ir + * is not yet setup */ + dclen = decode_length[type]; + memset(ir, 0, sizeof(*ir)); + /* add this infrared remote struct to remote_list, keeping track + * of the number of drivers registered. */ + dprintk(DRIVER_NAME "[%d]: adding remote to list\n", devnum); + list_add_tail(&ir->remote_list_link, &remote_list); + ir->dev_refcount = 1; + + plugin = kmalloc(sizeof(*plugin), GFP_KERNEL); + if (!plugin) { + mem_failure = 2; + goto new_irctl_failure_check; + } + + memset(plugin, 0, sizeof(*plugin)); + ir->p = plugin; + plugin->rbuf = kmalloc(sizeof(*(plugin->rbuf)), GFP_KERNEL); + if (!plugin->rbuf) { + mem_failure = 3; + goto new_irctl_failure_check; + } + + if (lirc_buffer_init(plugin->rbuf, dclen, 1)) { + mem_failure = 4; + goto new_irctl_failure_check; + } + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = -1; + plugin->code_length = dclen * 8; + plugin->features = LIRC_CAN_REC_LIRCCODE; + plugin->data = ir; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + ir->usbdev = dev; + ir->remote_type = type; + ir->devnum = devnum; + ir->mode = RW2_NULL_MODE; + + init_MUTEX(&ir->lock); + INIT_LIST_HEAD(&ir->iep_listhead); + +new_irctl_failure_check: + + if (mem_failure) { + free_irctl(ir, mem_failure); + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", + devnum, mem_failure); + return NULL; + } + return ir; +} + + +/* + * Scan the global list of remotes to see if the device listed is one of them. + * If it is, the corresponding irctl is returned, with its dev_refcount + * incremented. Otherwise, returns null. + */ +static struct irctl *get_prior_reg_ir(struct usb_device *dev) +{ + struct list_head *pos; + struct irctl *ir = NULL; + + dprintk(DRIVER_NAME "[%d]: scanning remote_list...\n", dev->devnum); + list_for_each(pos, &remote_list) { + ir = get_irctl_from_link(pos); + if (ir->usbdev != dev) { + dprintk(DRIVER_NAME "[%d]: device %d isn't it...", + dev->devnum, ir->devnum); + ir = NULL; + } else { + dprintk(DRIVER_NAME "[%d]: prior instance found.\n", + dev->devnum); + ir->dev_refcount++; + break; + } + } + return ir; +} + +/* If the USB interface has an out endpoint for control (eg, the first Remote + * Wonder) send the appropriate initialization packets. */ +static void send_outbound_init(struct irctl *ir) +{ + if (ir->out_init) { + struct out_endpt *oep = ir->out_init; + dprintk(DRIVER_NAME "[%d]: usb_remote_probe: initializing " + "outbound ep\n", ir->devnum); + usb_fill_int_urb(oep->urb, ir->usbdev, + usb_sndintpipe(ir->usbdev, oep->ep->bEndpointAddress), + oep->buf, USB_OUTLEN, usb_remote_send, + oep, oep->ep->bInterval); + + send_packet(oep, 0x8004, init1); + send_packet(oep, 0x8007, init2); + } +} + +/* Log driver and usb info */ +static void log_usb_dev_info(struct usb_device *dev) +{ + char buf[63], name[128] = ""; + if (dev->descriptor.iManufacturer + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + if (dev->descriptor.iProduct + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", dev->devnum, name, + dev->bus->busnum, dev->devnum); +} + + +#ifdef KERNEL_2_5 +static int usb_remote_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *idesc; +#else +static void *usb_remote_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *intf = &dev->actconfig->interface[ifnum]; + struct usb_interface_descriptor *idesc; +#endif + struct usb_endpoint_descriptor *ep; + struct in_endpt *iep; + struct irctl *ir; + int i, type; + + dprintk(DRIVER_NAME "[%d]: usb_remote_probe: dev:%p, intf:%p, id:%p)\n", + dev->devnum, dev, intf, id); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + idesc = &intf->altsetting[intf->act_altsetting]; +#else + idesc = intf->cur_altsetting; +#endif + + /* Check if a usb remote has already been registered for this device */ + ir = get_prior_reg_ir(dev); + + if (!ir) { + ir = new_irctl(dev); + if (!ir) +#ifdef KERNEL_2_5 + return -ENOMEM; +#else + return NULL; +#endif + } + type = ir->remote_type; + + /* step through the endpoints to find first in and first out endpoint + * of type interrupt transfer */ +#ifdef KERNEL_2_5 + for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { + ep = &idesc->endpoint[i].desc; +#else + for (i = 0; i < idesc->bNumEndpoints; ++i) { + ep = &idesc->endpoint[i]; +#endif + dprintk(DRIVER_NAME "[%d]: processing endpoint %d\n", + dev->devnum, i); + if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == + USB_DIR_IN) && + ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT)) { + + iep = new_in_endpt(ir, ep); + if (iep) + usb_fill_int_urb(iep->urb, dev, + usb_rcvintpipe(dev, + iep->ep->bEndpointAddress), + iep->buf, iep->len, usb_remote_recv, + iep, iep->ep->bInterval); + } + + if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == + USB_DIR_OUT) && + ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_INT) && + (ir->out_init == NULL)) + ir->out_init = new_out_endpt(ir, ep); + } + if (list_empty(&ir->iep_listhead)) { + printk(DRIVER_NAME "[%d]: inbound endpoint not found\n", + ir->devnum); + free_irctl(ir, FREE_ALL); +#ifdef KERNEL_2_5 + return -ENODEV; +#else + return NULL; +#endif + } + if (ir->dev_refcount == 1) { + ir->p->minor = lirc_register_plugin(ir->p); + if (ir->p->minor < 0) { + free_irctl(ir, FREE_ALL); +#ifdef KERNEL_2_5 + return -ENODEV; +#else + return NULL; +#endif + } + + /* Note new driver registration in kernel logs */ + log_usb_dev_info(dev); + + /* outbound data (initialization) */ + send_outbound_init(ir); + } + +#ifdef KERNEL_2_5 + usb_set_intfdata(intf, ir); + return SUCCESS; +#else + return ir; +#endif +} + +#ifdef KERNEL_2_5 +static void usb_remote_disconnect(struct usb_interface *intf) +{ +/* struct usb_device *dev = interface_to_usbdev(intf); */ + struct irctl *ir = usb_get_intfdata(intf); + usb_set_intfdata(intf, NULL); +#else +static void usb_remote_disconnect(struct usb_device *dev, void *ptr) +{ + struct irctl *ir = ptr; +#endif + + dprintk(DRIVER_NAME ": disconnecting remote %d:\n", + (ir? ir->devnum: -1)); + if (!ir || !ir->p) + return; + + if (ir->usbdev) { + /* Only unregister once */ + ir->usbdev = NULL; + unregister_from_lirc(ir); + } + + /* This also removes the current remote from remote_list */ + free_irctl(ir, FREE_ALL); +} + +static struct usb_driver usb_remote_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = usb_remote_probe, + .disconnect = usb_remote_disconnect, + .id_table = usb_remote_table +}; + +static int __init usb_remote_init(void) +{ + int i; + + INIT_LIST_HEAD(&remote_list); + + printk(KERN_INFO "\n" DRIVER_NAME ": " DRIVER_DESC " " + DRIVER_VERSION "\n"); + printk(DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled: " + "$Id: lirc_atiusb.c,v 1.69 2008/04/28 06:47:29 lirc Exp $\n"); + + request_module("lirc_dev"); + + repeat_jiffies = repeat*HZ/100; + + i = usb_register(&usb_remote_driver); + if (i) { + printk(DRIVER_NAME ": usb register failed, result = %d\n", i); + return -ENODEV; + } + + return SUCCESS; +} + +static void __exit usb_remote_exit(void) +{ + usb_deregister(&usb_remote_driver); +} + +module_init(usb_remote_init); +module_exit(usb_remote_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, usb_remote_table); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not (default: 0)"); + +module_param(mask, int, 0644); +MODULE_PARM_DESC(mask, "Set channel acceptance bit mask (default: 0xFFFF)"); + +module_param(unique, bool, 0644); +MODULE_PARM_DESC(unique, "Enable channel-specific codes (default: 0)"); + +module_param(repeat, int, 0644); +MODULE_PARM_DESC(repeat, "Repeat timeout (1/100 sec) (default: 10)"); + +module_param(mdeadzone, int, 0644); +MODULE_PARM_DESC(mdeadzone, "rw2 mouse sensitivity threshold (default: 0)"); + +/* + * Enabling this will cause the built-in Remote Wonder II repeate coding to + * not be squashed. The second byte of the keys output will then be: + * + * 1 initial press (button down) + * 2 holding (button remains pressed) + * 0 release (button up) + * + * By default, the driver emits 2 for both 1 and 2, and emits nothing for 0. + * This is good for people having trouble getting their rw2 to send a good + * consistent signal to the receiver. + * + * However, if you have no troubles with the driver outputting up-down pairs + * at random points while you're still holding a button, then you can enable + * this parameter to get finer grain repeat control out of your remote: + * + * 1 Emit a single (per-channel) virtual code for all up/down events + * 2 Emit the actual rw2 output + * + * 1 is easier to write lircd configs for; 2 allows full control. + */ +module_param(emit_updown, int, 0644); +MODULE_PARM_DESC(emit_updown, "emit press/release codes (rw2): 0:don't " + "(default), 1:emit 2 codes only, 2:code for each button"); + +module_param(emit_modekeys, int, 0644); +MODULE_PARM_DESC(emit_modekeys, "emit keycodes for aux1-aux4, pc, and mouse " + "(rw2): 0:don't (default), 1:emit translated codes: one for " + "mode switch, one for same mode, 2:raw codes"); + +module_param(mgradient, int, 0644); +MODULE_PARM_DESC(mgradient, "rw2 mouse: 1000*gradient from E to NE (default: " + "500 => .5 => ~27 degrees)"); + +EXPORT_NO_SYMBOLS; --- linux-2.6.28.orig/ubuntu/lirc/lirc_atiusb/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_atiusb/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_ATIUSB) += lirc_atiusb.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_mceusb/lirc_mceusb.c +++ linux-2.6.28/ubuntu/lirc/lirc_mceusb/lirc_mceusb.c @@ -0,0 +1,1000 @@ +/* + * USB Microsoft IR Transceiver driver - 0.2 + * + * Copyright (c) 2003-2004 Dan Conti (dconti@acm.wwu.edu) + * + * This driver is based on the USB skeleton driver packaged with the + * kernel, and the notice from that package has been retained below. + * + * The Microsoft IR Transceiver is a neat little IR receiver with two + * emitters on it designed for Windows Media Center. This driver might + * work for all media center remotes, but I have only tested it with + * the philips model. The first revision of this driver only supports + * the receive function - the transmit function will be much more + * tricky due to the nature of the hardware. Microsoft chose to build + * this device inexpensively, therefore making it extra dumb. + * There is no interrupt endpoint on this device; all usb traffic + * happens over two bulk endpoints. As a result of this, poll() for + * this device is an actual hardware poll (instead of a receive queue + * check) and is rather expensive. + * + * All trademarks property of their respective owners. This driver was + * originally based on the USB skeleton driver, although significant + * portions of that code have been removed as the driver has evolved. + * + * 2003_11_11 - Restructured to minimalize code interpretation in the + * driver. The normal use case will be with lirc. + * + * 2004_01_01 - Removed all code interpretation. Generate mode2 data + * for passing off to lirc. Cleanup + * + * 2004_01_04 - Removed devfs handle. Put in a temporary workaround + * for a known issue where repeats generate two + * sequential spaces (last_was_repeat_gap) + * + * 2004_02_17 - Changed top level api to no longer use fops, and + * instead use new interface for polling via + * lirc_thread. Restructure data read/mode2 generation to + * a single pass, reducing number of buffers. Rev to .2 + * + * 2004_02_27 - Last of fixups to plugin->add_to_buf API. Properly + * handle broken fragments from the receiver. Up the + * sample rate and remove any pacing from + * fetch_more_data. Fixes all known issues. + * + * TODO + * - Fix up minor number, registration of major/minor with usb subsystem + * + */ +/* + * USB Skeleton driver - 1.1 + * + * Copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2. + * + * + * This driver is to be used as a skeleton driver to be able to create a + * USB driver quickly. The design of it is based on the usb-serial and + * dc2xx drivers. + * + * Thanks to Oliver Neukum, David Brownell, and Alan Stern for their help + * in debugging this driver. + * + * + * History: + * + * 2003-05-06 - 1.1 - changes due to usb core changes with usb_register_dev() + * 2003-02-25 - 1.0 - fix races involving urb->status, unlink_urb(), and + * disconnect. Fix transfer amount in read(). Use + * macros instead of magic numbers in probe(). Change + * size variables to size_t. Show how to eliminate + * DMA bounce buffer. + * 2002_12_12 - 0.9 - compile fixes and got rid of fixed minor array. + * 2002_09_26 - 0.8 - changes due to USB core conversion to struct device + * driver. + * 2002_02_12 - 0.7 - zero out dev in probe function for devices that do + * not have both a bulk in and bulk out endpoint. + * Thanks to Holger Waechtler for the fix. + * 2001_11_05 - 0.6 - fix minor locking problem in skel_disconnect. + * Thanks to Pete Zaitcev for the fix. + * 2001_09_04 - 0.5 - fix devfs bug in skel_disconnect. Thanks to wim delvaux + * 2001_08_21 - 0.4 - more small bug fixes. + * 2001_05_29 - 0.3 - more bug fixes based on review from linux-usb-devel + * 2001_05_24 - 0.2 - bug fixes based on review from linux-usb-devel people + * 2001_05_01 - 0.1 - first version + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef KERNEL_2_5 +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +#include +#else +#include +#endif +#else +#include +#include +#include +#include +#include +#include +#endif + +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + +/* Use our own dbg macro */ +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG __FILE__ ": " \ + fmt "\n", ## args); \ + } while (0) + +/* Version Information */ +#define DRIVER_VERSION "v0.2" +#define DRIVER_AUTHOR "Dan Conti, dconti@acm.wwu.edu" +#define DRIVER_DESC "USB Microsoft IR Transceiver Driver" +#define DRIVER_NAME "lirc_mceusb" + +/* Define these values to match your device */ +#define USB_MCEUSB_VENDOR_ID 0x045e +#define USB_MCEUSB_PRODUCT_ID 0x006d + +/* table of devices that work with this driver */ +static struct usb_device_id mceusb_table[] = { + { USB_DEVICE(USB_MCEUSB_VENDOR_ID, USB_MCEUSB_PRODUCT_ID) }, + { } /* Terminating entry */ +}; + +/* we can have up to this number of device plugged in at once */ +#define MAX_DEVICES 16 + +/* Structure to hold all of our device specific stuff */ +struct usb_skel { + struct usb_device *udev; /* save off the usb device pointer */ + struct usb_interface *interface; /* the interface for this device */ + unsigned char minor; /* the starting minor number for this device */ + unsigned char num_ports; /* the number of ports this device has */ + char num_interrupt_in; /* number of interrupt in endpoints */ + char num_bulk_in; /* number of bulk in endpoints */ + char num_bulk_out; /* number of bulk out endpoints */ + + unsigned char *bulk_in_buffer; /* the buffer to receive data */ + int bulk_in_size; /* the size of the receive buffer */ + __u8 bulk_in_endpointAddr; /* the address of bulk in endpoint */ + + unsigned char *bulk_out_buffer; /* the buffer to send data */ + int bulk_out_size; /* the size of the send buffer */ + struct urb *write_urb; /* the urb used to send data */ + __u8 bulk_out_endpointAddr; /* the address of bulk out endpoint */ + + atomic_t write_busy; /* true iff write urb is busy */ + struct completion write_finished; /* wait for the write to finish */ + + wait_queue_head_t wait_q; /* for timeouts */ + int open_count; /* number of times this port has been opened */ + struct semaphore sem; /* locks this structure */ + + int present; /* if the device is not disconnected */ + + struct lirc_plugin *plugin; + + lirc_t lircdata[256]; /* place to store data until lirc processes it */ + int lircidx; /* current index */ + int lirccnt; /* remaining values */ + + int usb_valid_bytes_in_bulk_buffer; /* leftover data from prior read */ + int mce_bytes_left_in_packet; /* for packets split across reads */ + + /* Value to hold the last received space; 0 if last value + * received was a pulse */ + int last_space; + +#ifdef KERNEL_2_5 + dma_addr_t dma_in; + dma_addr_t dma_out; +#endif +}; + +#define MCE_TIME_UNIT 50 + +/* driver api */ +#ifdef KERNEL_2_5 +static int mceusb_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void mceusb_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void mceusb_write_bulk_callback(struct urb *urb, struct pt_regs *regs); +#else +static void mceusb_write_bulk_callback(struct urb *urb); +#endif +#else +static void *mceusb_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); +static void mceusb_disconnect(struct usb_device *dev, void *ptr); +static void mceusb_write_bulk_callback(struct urb *urb); +#endif + +/* read data from the usb bus; convert to mode2 */ +static int msir_fetch_more_data(struct usb_skel *dev, int dont_block); + +/* helper functions */ +static void msir_cleanup(struct usb_skel *dev); +static void set_use_dec(void *data); +static int set_use_inc(void *data); + +/* array of pointers to our devices that are currently connected */ +static struct usb_skel *minor_table[MAX_DEVICES]; + +/* lock to protect the minor_table structure */ +static DECLARE_MUTEX(minor_table_mutex); +static void mceusb_setup(struct usb_device *udev); + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver mceusb_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = mceusb_probe, + .disconnect = mceusb_disconnect, + .id_table = mceusb_table, +}; + + +/** + * usb_mceusb_debug_data + */ +static inline void usb_mceusb_debug_data(const char *function, int size, + const unsigned char *data) +{ + int i; + if (!debug) + return; + + printk(KERN_DEBUG __FILE__": %s - length = %d, data = ", + function, size); + for (i = 0; i < size; ++i) + printk(KERN_DEBUG "%.2x ", data[i]); + printk(KERN_DEBUG "\n"); +} + +/** + *mceusb_delete + */ +static inline void mceusb_delete(struct usb_skel *dev) +{ + dprintk("%s", __func__); + minor_table[dev->minor] = NULL; +#ifdef KERNEL_2_5 + usb_buffer_free(dev->udev, dev->bulk_in_size, + dev->bulk_in_buffer, dev->dma_in); + usb_buffer_free(dev->udev, dev->bulk_out_size, + dev->bulk_out_buffer, dev->dma_out); +#else + if (dev->bulk_in_buffer != NULL) + kfree(dev->bulk_in_buffer); + if (dev->bulk_out_buffer != NULL) + kfree(dev->bulk_out_buffer); +#endif + if (dev->write_urb != NULL) + usb_free_urb(dev->write_urb); + kfree(dev); +} + +static void mceusb_setup(struct usb_device *udev) +{ + char data[8]; + int res; + + memset(data, 0, 8); + + /* Get Status */ + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + USB_REQ_GET_STATUS, USB_DIR_IN, + 0, 0, data, 2, HZ * 3); + + /* res = usb_get_status( udev, 0, 0, data ); */ + dprintk("%s - res = %d status = 0x%x 0x%x", __func__, + res, data[0], data[1]); + + /* This is a strange one. They issue a set address to the device + * on the receive control pipe and expect a certain value pair back + */ + memset(data, 0, 8); + + res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 5, USB_TYPE_VENDOR, 0, 0, + data, 2, HZ * 3); + dprintk("%s - res = %d, devnum = %d", __func__, res, udev->devnum); + dprintk("%s - data[0] = %d, data[1] = %d", __func__, + data[0], data[1]); + + + /* set feature */ + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, + 0xc04e, 0x0000, NULL, 0, HZ * 3); + + dprintk("%s - res = %d", __func__, res); + + /* These two are sent by the windows driver, but stall for + * me. I dont have an analyzer on the linux side so i can't + * see what is actually different and why the device takes + * issue with them + */ +#if 0 + /* this is some custom control message they send */ + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + 0x04, USB_TYPE_VENDOR, + 0x0808, 0x0000, NULL, 0, HZ * 3); + + dprintk("%s - res = %d", __func__, res); + + /* this is another custom control message they send */ + res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + 0x02, USB_TYPE_VENDOR, + 0x0000, 0x0100, NULL, 0, HZ * 3); + + dprintk("%s - res = %d", __func__, res); +#endif +} + +static void msir_cleanup(struct usb_skel *dev) +{ + memset(dev->bulk_in_buffer, 0, dev->bulk_in_size); + + dev->usb_valid_bytes_in_bulk_buffer = 0; + + dev->last_space = PULSE_MASK; + + dev->mce_bytes_left_in_packet = 0; + dev->lircidx = 0; + dev->lirccnt = 0; + memset(dev->lircdata, 0, sizeof(dev->lircdata)); +} + +static int set_use_inc(void *data) +{ + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + MOD_DEC_USE_COUNT; +} + +/* + * msir_fetch_more_data + * + * The goal here is to read in more remote codes from the remote. In + * the event that the remote isn't sending us anything, the caller + * will block until a key is pressed (i.e. this performs phys read, + * filtering, and queueing of data) unless dont_block is set to 1; in + * this situation, it will perform a few reads and will exit out if it + * does not see any appropriate data + * + * dev->sem should be locked when this function is called - fine grain + * locking isn't really important here anyways + * + * This routine always returns the number of words available + * + */ +static int msir_fetch_more_data(struct usb_skel *dev, int dont_block) +{ + int retries = 0; + int words_to_read = + (sizeof(dev->lircdata)/sizeof(lirc_t)) - dev->lirccnt; + int partial, this_read = 0; + int bulkidx = 0; + int bytes_left_in_packet = 0; + signed char *signedp = (signed char*)dev->bulk_in_buffer; + + if (words_to_read == 0) + return dev->lirccnt; + + /* this forces all existing data to be read by lirc before we + * issue another usb command. this is the only form of + * throttling we have + */ + if (dev->lirccnt) + return dev->lirccnt; + + /* reserve room for our leading space */ + if (dev->last_space) + words_to_read--; + + while (words_to_read) { + /* handle signals and USB disconnects */ + if (signal_pending(current)) + return dev->lirccnt ? dev->lirccnt : -EINTR; + if (!dev->udev) + return -ENODEV; + + bulkidx = 0; + + /* + * perform data read (phys or from previous buffer) + */ + + /* use leftovers if present, otherwise perform a read */ + if (dev->usb_valid_bytes_in_bulk_buffer) { + this_read = dev->usb_valid_bytes_in_bulk_buffer; + partial = this_read; + dev->usb_valid_bytes_in_bulk_buffer = 0; + } else { + int retval; + + this_read = dev->bulk_in_size; + partial = 0; + retval = usb_bulk_msg(dev->udev, + usb_rcvbulkpipe(dev->udev, + dev->bulk_in_endpointAddr), + (unsigned char *)dev->bulk_in_buffer, + this_read, &partial, HZ*10); + + /* retry a few times on overruns; map all + other errors to -EIO */ + if (retval) { + if (retval == -EOVERFLOW && retries < 5) { + retries++; + interruptible_sleep_on_timeout( + &dev->wait_q, HZ); + continue; + } else + return -EIO; + } + + retries = 0; + if (partial) + this_read = partial; + + /* skip the header */ + bulkidx += 2; + + /* check for empty reads (header only) */ + if (this_read == 2) { + /* assume no data */ + if (dont_block) + break; + + /* sleep for a bit before performing + another read */ + interruptible_sleep_on_timeout(&dev->wait_q, 1); + continue; + } + } + + /* + * process data + */ + + /* at this point this_read is > 0 */ + while (bulkidx < this_read && + (words_to_read > (dev->last_space ? 1 : 0))) { + /* while( bulkidx < this_read && words_to_read) */ + int keycode; + int pulse = 0; + + /* read packet length if needed */ + if (!bytes_left_in_packet) { + /* we assume we are on a packet length + * value. it is possible, in some + * cases, to get a packet that does + * not start with a length, apparently + * due to some sort of fragmenting, + * but occaisonally we do not receive + * the second half of a fragment + */ + bytes_left_in_packet = + 128 + signedp[bulkidx++]; + + /* unfortunately rather than keep all + * the data in the packetized format, + * the transceiver sends a trailing 8 + * bytes that aren't part of the + * transmittion from the remote, + * aren't packetized, and dont really + * have any value. we can basically + * tell we have hit them if 1) we have + * a loooong space currently stored + * up, and 2) the bytes_left value for + * this packet is obviously wrong + */ + if (bytes_left_in_packet > 4) { + if (dev->mce_bytes_left_in_packet) { + bytes_left_in_packet = + dev->mce_bytes_left_in_packet; + bulkidx--; + } + bytes_left_in_packet = 0; + bulkidx = this_read; + } + + /* always clear this if we have a + valid packet */ + dev->mce_bytes_left_in_packet = 0; + + /* continue here to verify we haven't + hit the end of the bulk_in */ + continue; + + } + + /* + * generate mode2 + */ + + keycode = signedp[bulkidx++]; + if (keycode < 0) { + pulse = 1; + keycode += 128; + } + keycode *= MCE_TIME_UNIT; + + bytes_left_in_packet--; + + if (pulse) { + if (dev->last_space) { + dev->lircdata[dev->lirccnt++] = + dev->last_space; + dev->last_space = 0; + words_to_read--; + + /* clear the lirc_t for the pulse */ + dev->lircdata[dev->lirccnt] = 0; + } + dev->lircdata[dev->lirccnt] += keycode; + dev->lircdata[dev->lirccnt] |= PULSE_BIT; + } else { + /* on pulse->space transition, add one + for the existing pulse */ + if (dev->lircdata[dev->lirccnt] && + !dev->last_space) { + dev->lirccnt++; + words_to_read--; + } + + dev->last_space += keycode; + } + } + } + + /* save off some info if we are exiting mid-packet, or with + leftovers */ + if (bytes_left_in_packet) + dev->mce_bytes_left_in_packet = bytes_left_in_packet; + if (bulkidx < this_read) { + dev->usb_valid_bytes_in_bulk_buffer = (this_read - bulkidx); + memcpy(dev->bulk_in_buffer, &(dev->bulk_in_buffer[bulkidx]), + dev->usb_valid_bytes_in_bulk_buffer); + } + return dev->lirccnt; +} + +/* mceusb_add_to_buf: called by lirc_dev to fetch all available keys + * this is used as a polling interface for us: since we set + * plugin->sample_rate we will periodically get the below call to + * check for new data returns 0 on success, or -ENODATA if nothing is + * available + */ +static int mceusb_add_to_buf(void *data, struct lirc_buffer *buf) +{ + struct usb_skel *dev = (struct usb_skel *) data; + + down(&dev->sem); + + /* verify device still present */ + if (dev->udev == NULL) { + up(&dev->sem); + return -ENODEV; + } + + if (!dev->lirccnt) { + int res; + dev->lircidx = 0; + + res = msir_fetch_more_data(dev, 1); + + if (res == 0) + res = -ENODATA; + if (res < 0) { + up(&dev->sem); + return res; + } + } + + if (dev->lirccnt) { + int keys_to_copy; + + /* determine available buffer space and available data */ + keys_to_copy = lirc_buffer_available(buf); + if (keys_to_copy > dev->lirccnt) + keys_to_copy = dev->lirccnt; + + lirc_buffer_write_n(buf, + (unsigned char *) &(dev->lircdata[dev->lircidx]), + keys_to_copy); + dev->lircidx += keys_to_copy; + dev->lirccnt -= keys_to_copy; + + up(&dev->sem); + return 0; + } + + up(&dev->sem); + return -ENODATA; +} + +/** + * mceusb_write_bulk_callback + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void mceusb_write_bulk_callback(struct urb *urb, struct pt_regs *regs) +#else +static void mceusb_write_bulk_callback(struct urb *urb) +#endif +{ + struct usb_skel *dev = (struct usb_skel *)urb->context; + + dprintk("%s - minor %d", __func__, dev->minor); + + if ((urb->status != -ENOENT) && + (urb->status != -ECONNRESET)) { + dprintk("%s - nonzero write buld status received: %d", + __func__, urb->status); + return; + } + + return; +} + +/** + * mceusb_probe + * + * Called by the usb core when a new device is connected that it + * thinks this driver might be interested in. + */ +#ifdef KERNEL_2_5 +static int mceusb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *iface_desc; +#else +static void *mceusb_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *interface = &udev->actconfig->interface[ifnum]; + struct usb_interface_descriptor *iface_desc; +#endif + struct usb_skel *dev = NULL; + struct usb_endpoint_descriptor *endpoint; + + struct lirc_plugin *plugin; + struct lirc_buffer *rbuf; + + int minor; + size_t buffer_size; + int i; + int retval = -ENOMEM; + char junk[64]; + int partial = 0; + + /* See if the device offered us matches what we can accept */ + if (cpu_to_le16(udev->descriptor.idVendor) != USB_MCEUSB_VENDOR_ID || + cpu_to_le16(udev->descriptor.idProduct) != USB_MCEUSB_PRODUCT_ID) { + dprintk("Wrong Vendor/Product IDs"); +#ifdef KERNEL_2_5 + return -ENODEV; +#else + return NULL; +#endif + } + + /* select a "subminor" number (part of a minor number) */ + down(&minor_table_mutex); + for (minor = 0; minor < MAX_DEVICES; ++minor) { + if (minor_table[minor] == NULL) + break; + } + if (minor >= MAX_DEVICES) { + info("Too many devices plugged in, " + "can not handle this device."); + goto error; + } + + /* allocate memory for our device state and initialize it */ + dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL); + if (dev == NULL) { + err("Out of memory"); +#ifdef KERNEL_2_5 + retval = -ENOMEM; +#endif + goto error; + } + minor_table[minor] = dev; + + memset(dev, 0x00, sizeof(*dev)); + init_MUTEX(&dev->sem); + dev->udev = udev; + dev->interface = interface; + dev->minor = minor; + + /* set up the endpoint information */ + /* check out the endpoints */ + /* use only the first bulk-in and bulk-out endpoints */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + iface_desc = &interface->altsetting[0]; +#else + iface_desc = interface->cur_altsetting; +#endif + +#ifdef KERNEL_2_5 + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; +#else + for (i = 0; i < iface_desc->bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i]; +#endif + if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK)) { + dprintk("we found a bulk in endpoint"); + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; +#ifdef KERNEL_2_5 + dev->bulk_in_buffer = + usb_buffer_alloc(udev, buffer_size, + GFP_ATOMIC, &dev->dma_in); +#else + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); +#endif + if (!dev->bulk_in_buffer) { + err("Couldn't allocate bulk_in_buffer"); + goto error; + } + } + + if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == 0x00) + && ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == + USB_ENDPOINT_XFER_BULK)) { + dprintk("we found a bulk out endpoint"); +#ifdef KERNEL_2_5 + dev->write_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + dev->write_urb = usb_alloc_urb(0); +#endif + if (!dev->write_urb) { + err("No free urbs available"); + goto error; + } + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_out_size = buffer_size; + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; +#ifdef KERNEL_2_5 + dev->bulk_out_buffer = + usb_buffer_alloc(udev, buffer_size, + GFP_ATOMIC, &dev->dma_out); +#else + dev->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); +#endif + if (!dev->bulk_out_buffer) { + err("Couldn't allocate bulk_out_buffer"); + goto error; + } +#ifdef KERNEL_2_5 + usb_fill_bulk_urb(dev->write_urb, udev, + usb_sndbulkpipe + (udev, endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + mceusb_write_bulk_callback, dev); +#else + FILL_BULK_URB(dev->write_urb, udev, + usb_sndbulkpipe(udev, + endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + mceusb_write_bulk_callback, dev); +#endif + } + } + + if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { + err("Couldn't find both bulk-in and bulk-out endpoints"); + goto error; + } + + /* init the waitq */ + init_waitqueue_head(&dev->wait_q); + + + /* Set up our lirc plugin */ + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + err("out of memory"); + goto error; + } + memset(plugin, 0, sizeof(struct lirc_plugin)); + + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + err("out of memory"); + kfree(plugin); + goto error; + } + + /* the lirc_atiusb module doesn't memset rbuf here ... ? */ + if (lirc_buffer_init(rbuf, sizeof(lirc_t), 128)) { + err("out of memory"); + kfree(plugin); + kfree(rbuf); + goto error; + } + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = minor; + plugin->code_length = sizeof(lirc_t) * 8; + plugin->features = LIRC_CAN_REC_MODE2; /* | LIRC_CAN_SEND_MODE2; */ + plugin->data = dev; + plugin->rbuf = rbuf; + plugin->ioctl = NULL; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; + plugin->sample_rate = 80; /* sample at 100hz (10ms) */ + plugin->add_to_buf = &mceusb_add_to_buf; + /* plugin->fops = &mceusb_fops; */ +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &udev->dev; +#endif + plugin->owner = THIS_MODULE; + if (lirc_register_plugin(plugin) < 0) { + kfree(plugin); + lirc_buffer_free(rbuf); + kfree(rbuf); + goto error; + } + dev->plugin = plugin; + + /* clear off the first few messages. these look like + * calibration or test data, i can't really tell + * this also flushes in case we have random ir data queued up + */ + for (i = 0; i < 40; i++) + (void) usb_bulk_msg(udev, + usb_rcvbulkpipe(udev, + dev->bulk_in_endpointAddr), + junk, 64, &partial, HZ*10); + + msir_cleanup(dev); + mceusb_setup(udev); + +#ifdef KERNEL_2_5 + /* we can register the device now, as it is ready */ + usb_set_intfdata(interface, dev); +#endif + /* let the user know what node this device is now attached to */ + /* info("USB Microsoft IR Transceiver device now attached to msir%d", + dev->minor); */ + up(&minor_table_mutex); +#ifdef KERNEL_2_5 + return 0; +#else + return dev; +#endif +error: + mceusb_delete(dev); + dev = NULL; + dprintk("%s: retval = %x", __func__, retval); + up(&minor_table_mutex); +#ifdef KERNEL_2_5 + return retval; +#else + return NULL; +#endif +} + +/** + * mceusb_disconnect + * + * Called by the usb core when the device is removed from the system. + * + * This routine guarantees that the driver will not submit any more urbs + * by clearing dev->udev. It is also supposed to terminate any currently + * active urbs. Unfortunately, usb_bulk_msg(), used in skel_read(), does + * not provide any way to do this. But at least we can cancel an active + * write. + */ +#ifdef KERNEL_2_5 +static void mceusb_disconnect(struct usb_interface *interface) +#else +static void mceusb_disconnect(struct usb_device *udev, void *ptr) +#endif +{ + struct usb_skel *dev; + int minor; +#ifdef KERNEL_2_5 + dev = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); +#else + dev = (struct usb_skel *)ptr; +#endif + + down(&minor_table_mutex); + down(&dev->sem); + minor = dev->minor; + + /* unhook lirc things */ + lirc_unregister_plugin(minor); + lirc_buffer_free(dev->plugin->rbuf); + kfree(dev->plugin->rbuf); + kfree(dev->plugin); +#ifdef KERNEL_2_5 + /* terminate an ongoing write */ + if (atomic_read(&dev->write_busy)) { + usb_kill_urb(dev->write_urb); + wait_for_completion(&dev->write_finished); + } + + /* prevent device read, write and ioctl */ + dev->present = 0; +#endif + + mceusb_delete(dev); + + info("Microsoft IR Transceiver #%d now disconnected", minor); + up(&dev->sem); + up(&minor_table_mutex); +} + + + +/** + * usb_mceusb_init + */ +static int __init usb_mceusb_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + result = usb_register(&mceusb_driver); +#ifdef KERNEL_2_5 + if (result) { +#else + if (result < 0) { +#endif + err("usb_register failed for the " DRIVER_NAME + " driver. error number %d", result); +#ifdef KERNEL_2_5 + return result; +#else + return -1; +#endif + } + + info(DRIVER_DESC " " DRIVER_VERSION); + return 0; +} + + +/** + * usb_mceusb_exit + */ +static void __exit usb_mceusb_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&mceusb_driver); +} + +module_init(usb_mceusb_init); +module_exit(usb_mceusb_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, mceusb_table); + +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +EXPORT_NO_SYMBOLS; --- linux-2.6.28.orig/ubuntu/lirc/lirc_mceusb/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_mceusb/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_MCEUSB) += lirc_mceusb.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_mceusb2/lirc_mceusb2.c +++ linux-2.6.28/ubuntu/lirc/lirc_mceusb2/lirc_mceusb2.c @@ -0,0 +1,1076 @@ +/* + * LIRC driver for Philips eHome USB Infrared Transceiver + * and the Microsoft MCE 2005 Remote Control + * + * (C) by Martin A. Blatter + * + * Transmitter support and reception code cleanup. + * (C) by Daniel Melander + * + * Derived from ATI USB driver by Paul Miller and the original + * MCE USB driver by Dan Corti + * + * This driver will only work reliably with kernel version 2.6.10 + * or higher, probably because of differences in USB device enumeration + * in the kernel code. Device initialization fails most of the time + * with earlier kernel versions. + * + ********************************************************************** + * + * 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 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.6.5 or higher" +#error "*******************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include +#include +#include +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#define DRIVER_VERSION "$Revision: 1.44 $" +#define DRIVER_AUTHOR "Daniel Melander , " \ + "Martin Blatter " +#define DRIVER_DESC "Philips eHome USB IR Transceiver and Microsoft " \ + "MCE 2005 Remote Control driver for LIRC" +#define DRIVER_NAME "lirc_mceusb2" + +#define USB_BUFLEN 16 /* USB reception buffer length */ +#define LIRCBUF_SIZE 256 /* LIRC work buffer length */ + +/* MCE constants */ +#define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ +#define MCE_TIME_UNIT 50 /* Approx 50us resolution */ +#define MCE_CODE_LENGTH 5 /* Normal length of packet (with header) */ +#define MCE_PACKET_SIZE 4 /* Normal length of packet (without header) */ +#define MCE_PACKET_HEADER 0x84 /* Actual header format is 0x80 + num_bytes */ +#define MCE_CONTROL_HEADER 0x9F /* MCE status header */ +#define MCE_TX_HEADER_LENGTH 3 /* # of bytes in the initializing tx header */ +#define MCE_MAX_CHANNELS 2 /* Two transmitters, hardware dependent? */ +#define MCE_DEFAULT_TX_MASK 0x03 /* Val opts: TX1=0x01, TX2=0x02, ALL=0x03 */ +#define MCE_PULSE_BIT 0x80 /* Pulse bit, MSB set == PULSE else SPACE */ +#define MCE_PULSE_MASK 0x7F /* Pulse mask */ +#define MCE_MAX_PULSE_LENGTH 0x7F /* Longest transmittable pulse symbol */ + + +/* module parameters */ +#ifdef CONFIG_USB_DEBUG +static int debug = 1; +#else +static int debug; +#endif +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +/* lock irctl structure */ +/*#define IRLOCK down_interruptible(&ir->lock) */ +#define IRLOCK down(&ir->lock) +#define IRUNLOCK up(&ir->lock) + +/* general constants */ +#define SUCCESS 0 +#define SEND_FLAG_IN_PROGRESS 1 +#define SEND_FLAG_COMPLETE 2 +#define RECV_FLAG_IN_PROGRESS 3 +#define RECV_FLAG_COMPLETE 4 + +#define PHILUSB_INBOUND 1 +#define PHILUSB_OUTBOUND 2 + +#define VENDOR_PHILIPS 0x0471 +#define VENDOR_SMK 0x0609 +#define VENDOR_TATUNG 0x1460 +#define VENDOR_GATEWAY 0x107b +#define VENDOR_SHUTTLE 0x1308 +#define VENDOR_SHUTTLE2 0x051c +#define VENDOR_MITSUMI 0x03ee +#define VENDOR_TOPSEED 0x1784 +#define VENDOR_RICAVISION 0x179d +#define VENDOR_ITRON 0x195d +#define VENDOR_FIC 0x1509 +#define VENDOR_LG 0x043e +#define VENDOR_MICROSOFT 0x045e +#define VENDOR_FORMOSA 0x147a +#define VENDOR_FINTEK 0x1934 + +static struct usb_device_id usb_remote_table [] = { + /* Philips eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_PHILIPS, 0x0815) }, + /* Philips Infrared Transceiver - HP branded */ + { USB_DEVICE(VENDOR_PHILIPS, 0x060c) }, + /* Philips SRM5100 */ + { USB_DEVICE(VENDOR_PHILIPS, 0x060d) }, + /* SMK/Toshiba G83C0004D410 */ + { USB_DEVICE(VENDOR_SMK, 0x031d) }, + /* SMK eHome Infrared Transceiver (Sony VAIO) */ + { USB_DEVICE(VENDOR_SMK, 0x0322) }, + /* bundled with Hauppauge PVR-150 */ + { USB_DEVICE(VENDOR_SMK, 0x0334) }, + /* Tatung eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, + /* Shuttle eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_SHUTTLE, 0xc001) }, + /* Shuttle eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_SHUTTLE2, 0xc001) }, + /* Gateway eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_GATEWAY, 0x3009) }, + /* Mitsumi */ + { USB_DEVICE(VENDOR_MITSUMI, 0x2501) }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0001) }, + /* Topseed HP eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0006) }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0007) }, + /* Topseed eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_TOPSEED, 0x0008) }, + /* Ricavision internal Infrared Transceiver */ + { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, + /* Itron ione Libra Q-11 */ + { USB_DEVICE(VENDOR_ITRON, 0x7002) }, + /* FIC eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FIC, 0x9242) }, + /* LG eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_LG, 0x9803) }, + /* Microsoft MCE Infrared Transceiver */ + { USB_DEVICE(VENDOR_MICROSOFT, 0x00a0) }, + /* Formosa eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe015) }, + /* Formosa aim / Trust MCE Infrared Receiver */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe017) }, + /* Formosa Industrial Computing / Beanbag Emulation Device */ + { USB_DEVICE(VENDOR_FORMOSA, 0xe018) }, + /* Fintek eHome Infrared Transceiver */ + { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, + /* Terminating entry */ + { } +}; + +/* data structure for each usb remote */ +struct irctl { + + /* usb */ + struct usb_device *usbdev; + struct urb *urb_in; + int devnum; + struct usb_endpoint_descriptor *usb_ep_in; + struct usb_endpoint_descriptor *usb_ep_out; + + /* buffers and dma */ + unsigned char *buf_in; + unsigned int len_in; + dma_addr_t dma_in; + dma_addr_t dma_out; + + /* lirc */ + struct lirc_plugin *p; + lirc_t lircdata; + unsigned char is_pulse; + int connected; + + unsigned char transmitter_mask; + unsigned int carrier_freq; + + /* handle sending (init strings) */ + int send_flags; + wait_queue_head_t wait_out; + + struct semaphore lock; +}; + +/* init strings */ +static char init1[] = {0x00, 0xff, 0xaa, 0xff, 0x0b}; +static char init2[] = {0xff, 0x18}; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11) +static inline unsigned long usecs_to_jiffies(const unsigned int u) +{ + if (u > jiffies_to_usecs(MAX_JIFFY_OFFSET)) + return MAX_JIFFY_OFFSET; +#if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) + return (u + (USEC_PER_SEC / HZ) - 1) / (USEC_PER_SEC / HZ); +#elif HZ > USEC_PER_SEC && !(HZ % USEC_PER_SEC) + return u * (HZ / USEC_PER_SEC); +#else + return (u * HZ + USEC_PER_SEC - 1) / USEC_PER_SEC; +#endif +} +#endif + + +static void usb_remote_printdata(struct irctl *ir, char *buf, int len) +{ + char codes[USB_BUFLEN*3 + 1]; + int i; + + if (len <= 0) + return; + + for (i = 0; i < len && i < USB_BUFLEN; i++) + snprintf(codes+i*3, 4, "%02x ", buf[i] & 0xFF); + + printk(KERN_INFO "" DRIVER_NAME "[%d]: data received %s (length=%d)\n", + ir->devnum, codes, len); +} + +static void usb_async_callback(struct urb *urb, struct pt_regs *regs) +{ + struct irctl *ir; + int len; + + if (!urb) + return; + + ir = urb->context; + if (ir) { + len = urb->actual_length; + + dprintk(DRIVER_NAME + "[%d]: callback called (status=%d len=%d)\n", + ir->devnum, urb->status, len); + + if (debug) + usb_remote_printdata(ir, urb->transfer_buffer, len); + } + +} + + +/* request incoming or send outgoing usb packet - used to initialize remote */ +static void request_packet_async(struct irctl *ir, + struct usb_endpoint_descriptor *ep, + unsigned char *data, int size, int urb_type) +{ + int res; + struct urb *async_urb; + unsigned char *async_buf; + + if (urb_type) { + async_urb = usb_alloc_urb(0, GFP_KERNEL); + if (async_urb) { + /* alloc buffer */ + async_buf = kmalloc(size, GFP_KERNEL); + if (async_buf) { + if (urb_type == PHILUSB_OUTBOUND) { + /* outbound data */ + usb_fill_int_urb(async_urb, ir->usbdev, + usb_sndintpipe(ir->usbdev, + ep->bEndpointAddress), + async_buf, + size, + (usb_complete_t) usb_async_callback, + ir, ep->bInterval); + + memcpy(async_buf, data, size); + async_urb->transfer_flags = + URB_ASYNC_UNLINK; + } else { + /* inbound data */ + usb_fill_int_urb(async_urb, ir->usbdev, + usb_rcvintpipe(ir->usbdev, + ep->bEndpointAddress), + async_buf, size, + (usb_complete_t) usb_async_callback, + ir, ep->bInterval); + + async_urb->transfer_flags = + URB_ASYNC_UNLINK; + } + } else { + usb_free_urb(async_urb); + return; + } + } + } else { + /* standard request */ + async_urb = ir->urb_in; + ir->send_flags = RECV_FLAG_IN_PROGRESS; + } + dprintk(DRIVER_NAME "[%d]: receive request called (size=%#x)\n", + ir->devnum, size); + + async_urb->transfer_buffer_length = size; + async_urb->dev = ir->usbdev; + + res = usb_submit_urb(async_urb, GFP_ATOMIC); + if (res) { + dprintk(DRIVER_NAME "[%d]: receive request FAILED! (res=%d)\n", + ir->devnum, res); + return; + } + dprintk(DRIVER_NAME "[%d]: receive request complete (res=%d)\n", + ir->devnum, res); +} + +static int unregister_from_lirc(struct irctl *ir) +{ + struct lirc_plugin *p = ir->p; + int devnum; + int rtn; + + devnum = ir->devnum; + dprintk(DRIVER_NAME "[%d]: unregister from lirc called\n", devnum); + + rtn = lirc_unregister_plugin(p->minor); + if (rtn > 0) { + printk(DRIVER_NAME "[%d]: error in lirc_unregister minor: %d\n" + "Trying again...\n", devnum, p->minor); + if (rtn == -EBUSY) { + printk(DRIVER_NAME + "[%d]: device is opened, will unregister" + " on close\n", devnum); + return -EAGAIN; + } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ); + + rtn = lirc_unregister_plugin(p->minor); + if (rtn > 0) + printk(DRIVER_NAME "[%d]: lirc_unregister failed\n", + devnum); + } + + if (rtn != SUCCESS) { + printk(DRIVER_NAME "[%d]: didn't free resources\n", devnum); + return -EAGAIN; + } + + printk(DRIVER_NAME "[%d]: usb remote disconnected\n", devnum); + + lirc_buffer_free(p->rbuf); + kfree(p->rbuf); + kfree(p); + kfree(ir); + return SUCCESS; +} + +static int set_use_inc(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_inc called with no context\n"); + return -EIO; + } + dprintk(DRIVER_NAME "[%d]: set use inc\n", ir->devnum); + + MOD_INC_USE_COUNT; + + if (!ir->connected) { + if (!ir->usbdev) + return -ENOENT; + ir->connected = 1; + } + + return SUCCESS; +} + +static void set_use_dec(void *data) +{ + struct irctl *ir = data; + + if (!ir) { + printk(DRIVER_NAME "[?]: set_use_dec called with no context\n"); + return; + } + dprintk(DRIVER_NAME "[%d]: set use dec\n", ir->devnum); + + if (ir->connected) { + IRLOCK; + ir->connected = 0; + IRUNLOCK; + } + MOD_DEC_USE_COUNT; +} + +static void send_packet_to_lirc(struct irctl *ir) +{ + if (ir->lircdata != 0) { + lirc_buffer_write_1(ir->p->rbuf, + (unsigned char *) &ir->lircdata); + wake_up(&ir->p->rbuf->wait_poll); + ir->lircdata = 0; + } +} + +static void usb_remote_recv(struct urb *urb, struct pt_regs *regs) +{ + struct irctl *ir; + int buf_len, packet_len; + int i, j; + + if (!urb) + return; + + ir = urb->context; + if (!ir) { + urb->transfer_flags |= URB_ASYNC_UNLINK; + usb_unlink_urb(urb); + return; + } + + buf_len = urb->actual_length; + packet_len = 0; + + if (debug) + usb_remote_printdata(ir, urb->transfer_buffer, buf_len); + + if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { + ir->send_flags = SEND_FLAG_COMPLETE; + dprintk(DRIVER_NAME "[%d]: setup answer received %d bytes\n", + ir->devnum, buf_len); + } + + switch (urb->status) { + /* success */ + case SUCCESS: + for (i = 0; i < buf_len; i++) { + /* decode mce packets on the form (84),AA,BB,CC,DD */ + switch (ir->buf_in[i]) { + /* data headers */ + case 0x8F: + case 0x8E: + case 0x8D: + case 0x8C: + case 0x8B: + case 0x8A: + case 0x89: + case 0x88: + case 0x87: + case 0x86: + case 0x85: + case 0x84: + case 0x83: + case 0x82: + case 0x81: + case 0x80: + /* decode packet data */ + packet_len = ir->buf_in[i] & MCE_PULSE_MASK; + for (j = 1; + j <= packet_len && (i+j < buf_len); + j++) { + /* rising/falling flank */ + if (ir->is_pulse != + (ir->buf_in[i + j] & + MCE_PULSE_BIT)) { + send_packet_to_lirc(ir); + ir->is_pulse = + ir->buf_in[i + j] & + MCE_PULSE_BIT; + } + + /* accumulate mce pulse/space values */ + ir->lircdata += + (ir->buf_in[i + j] & + MCE_PULSE_MASK)*MCE_TIME_UNIT; + ir->lircdata |= + (ir->is_pulse ? PULSE_BIT : 0); + } + + i += packet_len; + break; + + /* status header (0x9F) */ + case MCE_CONTROL_HEADER: + /* A transmission containing one or + more consecutive ir commands always + ends with a GAP of 100ms followed by the + sequence 0x9F 0x01 0x01 0x9F 0x15 + 0x00 0x00 0x80 */ + + /* + Uncomment this if the last 100ms + "infinity"-space should be transmitted + to lirc directly instead of at the beginning + of the next transmission. Changes pulse/space order. + + if (++i < buf_len && ir->buf_in[i]==0x01) + send_packet_to_lirc(ir); + + */ + + /* end decode loop */ + i = buf_len; + break; + default: + break; + } + } + + break; + + /* unlink */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + urb->transfer_flags |= URB_ASYNC_UNLINK; + usb_unlink_urb(urb); + return; + + case -EPIPE: + default: + break; + } + + /* resubmit urb */ + usb_submit_urb(urb, GFP_ATOMIC); +} + + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count = 0, cmdcount = 0; + struct irctl *ir = NULL; + lirc_t wbuf[LIRCBUF_SIZE]; /* Workbuffer with values from lirc */ + unsigned char cmdbuf[MCE_CMDBUF_SIZE]; /* MCE command buffer */ + unsigned long signal_duration = 0; /* Singnal length in us */ + struct timeval start_time, end_time; + + do_gettimeofday(&start_time); + + /* Retrieve lirc_plugin data for the device */ + ir = lirc_get_pdata(file); + if (!ir && !ir->usb_ep_out) + return -EFAULT; + + if (n % sizeof(lirc_t)) + return(-EINVAL); + count = n / sizeof(lirc_t); + + /* Check if command is within limits */ + if (count > LIRCBUF_SIZE || count%2 == 0) + return(-EINVAL); + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + + /* MCE tx init header */ + cmdbuf[cmdcount++] = MCE_CONTROL_HEADER; + cmdbuf[cmdcount++] = 0x08; + cmdbuf[cmdcount++] = ir->transmitter_mask; + + /* Generate mce packet data */ + for (i = 0; (i < count) && (cmdcount < MCE_CMDBUF_SIZE); i++) { + signal_duration += wbuf[i]; + wbuf[i] = wbuf[i] / MCE_TIME_UNIT; + + do { /* loop to support long pulses/spaces > 127*50us=6.35ms */ + + /* Insert mce packet header every 4th entry */ + if ((cmdcount < MCE_CMDBUF_SIZE) && + (cmdcount - MCE_TX_HEADER_LENGTH) % + MCE_CODE_LENGTH == 0) + cmdbuf[cmdcount++] = MCE_PACKET_HEADER; + + /* Insert mce packet data */ + if (cmdcount < MCE_CMDBUF_SIZE) + cmdbuf[cmdcount++] = + (wbuf[i] < MCE_PULSE_BIT ? + wbuf[i] : MCE_MAX_PULSE_LENGTH) | + (i & 1 ? 0x00 : MCE_PULSE_BIT); + else + return -EINVAL; + } while ((wbuf[i] > MCE_MAX_PULSE_LENGTH) && + (wbuf[i] -= MCE_MAX_PULSE_LENGTH)); + } + + /* Fix packet length in last header */ + cmdbuf[cmdcount - (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH] = + 0x80 + (cmdcount - MCE_TX_HEADER_LENGTH) % MCE_CODE_LENGTH - 1; + + /* Check if we have room for the empty packet at the end */ + if (cmdcount >= MCE_CMDBUF_SIZE) + return -EINVAL; + + /* All mce commands end with an empty packet (0x80) */ + cmdbuf[cmdcount++] = 0x80; + + /* Transmit the command to the mce device */ + request_packet_async(ir, ir->usb_ep_out, cmdbuf, + cmdcount, PHILUSB_OUTBOUND); + + /* The lircd gap calculation expects the write function to + wait the time it takes for the ircommand to be sent before + it returns. */ + do_gettimeofday(&end_time); + signal_duration -= (end_time.tv_usec - start_time.tv_usec) + + (end_time.tv_sec - start_time.tv_sec) * 1000000; + + /* delay with the closest number of ticks */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(usecs_to_jiffies(signal_duration)); + + return n; +} + +static void set_transmitter_mask(struct irctl *ir, unsigned int mask) +{ + + /* SMK Transceiver does not use the inverted scheme, nor does Topseed*/ + if ((ir->usbdev->descriptor.idVendor == VENDOR_SMK && + (ir->usbdev->descriptor.idProduct == 0x031d || + ir->usbdev->descriptor.idProduct == 0x0322 || + ir->usbdev->descriptor.idProduct == 0x0334)) || + (ir->usbdev->descriptor.idVendor == VENDOR_TOPSEED && + (ir->usbdev->descriptor.idProduct == 0x0001 || + ir->usbdev->descriptor.idProduct == 0x0007 || + ir->usbdev->descriptor.idProduct == 0x0008))) + ir->transmitter_mask = mask; + else + /* The mask begins at 0x02 and has an inverted + numbering scheme */ + ir->transmitter_mask = (mask != 0x03 ? mask ^ 0x03 : mask) << 1; +} + + +/* Sets the send carrier frequency */ +static int set_send_carrier(struct irctl *ir, int carrier) +{ + int clk = 10000000; + int prescaler = 0, divisor = 0; + unsigned char cmdbuf[] = { 0x9F, 0x06, 0x01, 0x80 }; + + /* Carrier is changed */ + if (ir->carrier_freq != carrier) { + + if (carrier <= 0) { + ir->carrier_freq = carrier; + dprintk(DRIVER_NAME "[%d]: SET_CARRIER disabling " + "carrier modulation\n", ir->devnum); + request_packet_async(ir, ir->usb_ep_out, + cmdbuf, sizeof(cmdbuf), + PHILUSB_OUTBOUND); + return carrier; + } + + for (prescaler = 0; prescaler < 4; ++prescaler) { + divisor = (clk >> (2 * prescaler)) / carrier; + if (divisor <= 0xFF) { + ir->carrier_freq = carrier; + cmdbuf[2] = prescaler; + cmdbuf[3] = divisor; + dprintk(DRIVER_NAME "[%d]: SET_CARRIER " + "requesting %d Hz\n", + ir->devnum, carrier); + + /* Transmit the new carrier to the mce + device */ + request_packet_async(ir, ir->usb_ep_out, + cmdbuf, sizeof(cmdbuf), + PHILUSB_OUTBOUND); + return carrier; + } + } + + return -EINVAL; + + } + + return carrier; +} + + +static int lirc_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg) +{ + int result; + unsigned int ivalue; + unsigned long lvalue; + struct irctl *ir = NULL; + + /* Retrieve lirc_plugin data for the device */ + ir = lirc_get_pdata(filep); + if (!ir && !ir->usb_ep_out) + return -EFAULT; + + + switch (cmd) { + case LIRC_SET_TRANSMITTER_MASK: + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + switch (ivalue) { + case 0x01: /* Transmitter 1 => 0x04 */ + case 0x02: /* Transmitter 2 => 0x02 */ + case 0x03: /* Transmitter 1 & 2 => 0x06 */ + set_transmitter_mask(ir, ivalue); + break; + + default: /* Unsupported transmitter mask */ + return MCE_MAX_CHANNELS; + } + + dprintk(DRIVER_NAME ": SET_TRANSMITTERS mask=%d\n", ivalue); + break; + + case LIRC_GET_SEND_MODE: + + result = put_user(LIRC_SEND2MODE(LIRC_CAN_SEND_PULSE & + LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + + result = get_user(lvalue, (unsigned long *) arg); + + if (result) + return result; + if (lvalue != (LIRC_MODE_PULSE&LIRC_CAN_SEND_MASK)) + return -EINVAL; + break; + + case LIRC_SET_SEND_CARRIER: + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + + set_send_carrier(ir, ivalue); + break; + + default: + return -ENOIOCTLCMD; + } + + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + + +static int usb_remote_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *idesc; + struct usb_endpoint_descriptor *ep = NULL; + struct usb_endpoint_descriptor *ep_in = NULL; + struct usb_endpoint_descriptor *ep_out = NULL; + struct usb_host_config *config; + struct irctl *ir = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int devnum, pipe, maxp; + int minor = 0; + int i; + char buf[63], name[128] = ""; + int mem_failure = 0; + + dprintk(DRIVER_NAME ": usb probe called\n"); + + usb_reset_device(dev); + + config = dev->actconfig; + + idesc = intf->cur_altsetting; + + /* step through the endpoints to find first bulk in and out endpoint */ + for (i = 0; i < idesc->desc.bNumEndpoints; ++i) { + ep = &idesc->endpoint[i].desc; + + if ((ep_in == NULL) + && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_IN) + && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) + || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT))) { + + dprintk(DRIVER_NAME ": acceptable inbound endpoint " + "found\n"); + ep_in = ep; + ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; + ep_in->bInterval = 1; + } + + if ((ep_out == NULL) + && ((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + == USB_DIR_OUT) + && (((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK) + || ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_INT))) { + + dprintk(DRIVER_NAME ": acceptable outbound endpoint " + "found\n"); + ep_out = ep; + ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; + ep_out->bInterval = 1; + } + } + if (ep_in == NULL) { + dprintk(DRIVER_NAME ": inbound and/or endpoint not found\n"); + return -ENODEV; + } + + devnum = dev->devnum; + pipe = usb_rcvintpipe(dev, ep_in->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + /* allocate kernel memory */ + mem_failure = 0; + ir = kmalloc(sizeof(struct irctl), GFP_KERNEL); + if (!ir) { + mem_failure = 1; + goto mem_failure_switch; + } + + memset(ir, 0, sizeof(struct irctl)); + + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + mem_failure = 2; + goto mem_failure_switch; + } + + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + mem_failure = 3; + goto mem_failure_switch; + } + + if (lirc_buffer_init(rbuf, sizeof(lirc_t), LIRCBUF_SIZE)) { + mem_failure = 4; + goto mem_failure_switch; + } + + ir->buf_in = usb_buffer_alloc(dev, maxp, GFP_ATOMIC, &ir->dma_in); + if (!ir->buf_in) { + mem_failure = 5; + goto mem_failure_switch; + } + + ir->urb_in = usb_alloc_urb(0, GFP_KERNEL); + if (!ir->urb_in) { + mem_failure = 7; + goto mem_failure_switch; + } + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, DRIVER_NAME " "); + plugin->minor = -1; + plugin->features = LIRC_CAN_SEND_PULSE | + LIRC_CAN_SET_TRANSMITTER_MASK | + LIRC_CAN_REC_MODE2 | + LIRC_CAN_SET_SEND_CARRIER; + plugin->data = ir; + plugin->rbuf = rbuf; + plugin->set_use_inc = &set_use_inc; + plugin->set_use_dec = &set_use_dec; + plugin->code_length = sizeof(lirc_t) * 8; + plugin->ioctl = lirc_ioctl; + plugin->fops = &lirc_fops; + plugin->dev = &dev->dev; + plugin->owner = THIS_MODULE; + + init_MUTEX(&ir->lock); + init_waitqueue_head(&ir->wait_out); + + minor = lirc_register_plugin(plugin); + if (minor < 0) + mem_failure = 9; + +mem_failure_switch: + + /* free allocated memory incase of failure */ + switch (mem_failure) { + case 9: + usb_free_urb(ir->urb_in); + case 7: + usb_buffer_free(dev, maxp, ir->buf_in, ir->dma_in); + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(ir); + case 1: + printk(DRIVER_NAME "[%d]: out of memory (code=%d)\n", + devnum, mem_failure); + return -ENOMEM; + } + + plugin->minor = minor; + ir->p = plugin; + ir->devnum = devnum; + ir->usbdev = dev; + ir->len_in = maxp; + ir->connected = 0; + + ir->lircdata = PULSE_MASK; + ir->is_pulse = 0; + + /* ir->usbdev must be set */ + set_transmitter_mask(ir, MCE_DEFAULT_TX_MASK); + /* Saving usb interface data for use by the transmitter routine */ + ir->usb_ep_in = ep_in; + ir->usb_ep_out = ep_out; + + if (dev->descriptor.iManufacturer + && usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + if (dev->descriptor.iProduct + && usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + printk(DRIVER_NAME "[%d]: %s on usb%d:%d\n", devnum, name, + dev->bus->busnum, devnum); + + /* inbound data */ + usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, + maxp, (usb_complete_t) usb_remote_recv, ir, ep_in->bInterval); + + /* initialize device */ + request_packet_async(ir, ep_in, NULL, maxp, PHILUSB_INBOUND); + request_packet_async(ir, ep_in, NULL, maxp, PHILUSB_INBOUND); + request_packet_async(ir, ep_out, init1, + sizeof(init1), PHILUSB_OUTBOUND); + request_packet_async(ir, ep_in, NULL, maxp, PHILUSB_INBOUND); + request_packet_async(ir, ep_out, init2, + sizeof(init2), PHILUSB_OUTBOUND); + request_packet_async(ir, ep_in, NULL, maxp, 0); + + usb_set_intfdata(intf, ir); + + return SUCCESS; +} + + +static void usb_remote_disconnect(struct usb_interface *intf) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct irctl *ir = usb_get_intfdata(intf); + + usb_set_intfdata(intf, NULL); + + if (!ir || !ir->p) + return; + + ir->usbdev = NULL; + wake_up_all(&ir->wait_out); + + IRLOCK; + usb_kill_urb(ir->urb_in); + usb_free_urb(ir->urb_in); + usb_buffer_free(dev, ir->len_in, ir->buf_in, ir->dma_in); + IRUNLOCK; + + unregister_from_lirc(ir); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +static int usb_remote_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct irctl *ir = usb_get_intfdata(intf); + printk(DRIVER_NAME "[%d]: suspend\n", ir->devnum); + usb_kill_urb(ir->urb_in); + return 0; +} + +static int usb_remote_resume(struct usb_interface *intf) +{ + struct irctl *ir = usb_get_intfdata(intf); + printk(DRIVER_NAME "[%d]: resume\n", ir->devnum); + if (usb_submit_urb(ir->urb_in, GFP_ATOMIC)) + return -EIO; + return 0; +} +#endif + +static struct usb_driver usb_remote_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = usb_remote_probe, + .disconnect = usb_remote_disconnect, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + .suspend = usb_remote_suspend, + .resume = usb_remote_resume, +#endif + .id_table = usb_remote_table +}; + +static int __init usb_remote_init(void) +{ + int i; + + printk(KERN_INFO "\n"); + printk(KERN_INFO DRIVER_NAME ": " DRIVER_DESC " " DRIVER_VERSION "\n"); + printk(KERN_INFO DRIVER_NAME ": " DRIVER_AUTHOR "\n"); + dprintk(DRIVER_NAME ": debug mode enabled\n"); + + request_module("lirc_dev"); + + i = usb_register(&usb_remote_driver); + if (i < 0) { + printk(DRIVER_NAME ": usb register failed, result = %d\n", i); + return -ENODEV; + } + + return SUCCESS; +} + +static void __exit usb_remote_exit(void) +{ + usb_deregister(&usb_remote_driver); +} + +module_init(usb_remote_init); +module_exit(usb_remote_exit); + +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, usb_remote_table); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Debug enabled or not"); + +EXPORT_NO_SYMBOLS; --- linux-2.6.28.orig/ubuntu/lirc/lirc_mceusb2/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_mceusb2/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_MCEUSB2) += lirc_mceusb2.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_imon/lirc_imon.c +++ linux-2.6.28/ubuntu/lirc/lirc_imon/lirc_imon.c @@ -0,0 +1,1524 @@ +/* + * lirc_imon.c: LIRC plugin/VFD driver for Ahanix/Soundgraph IMON IR/VFD + * + * $Id: lirc_imon.c,v 1.23 2008/01/19 10:06:46 lirc Exp $ + * + * Version 0.3 + * Supports newer iMON models that send decoded IR signals. + * This includes the iMON PAD model. + * Removed module option for vfd_proto_6p. This driver supports + * multiple iMON devices so it is meaningless to have + * a global option to set protocol variants. + * + * Version 0.2 beta 2 [January 31, 2005] + * USB disconnect/reconnect no longer causes problems for lircd + * + * Version 0.2 beta 1 [January 29, 2005] + * Added support for original iMON receiver(ext USB) + * + * Version 0.2 alpha 2 [January 24, 2005] + * Added support for VFDs with 6-packet protocol + * + * Version 0.2 alpha 1 [January 23, 2005] + * Added support for 2.6 kernels + * Reworked disconnect handling + * Incorporated Changwoo Ryu's algorithm + * + * Version 0.1 alpha 1[July 5, 2004] + * + * Copyright(C) 2004 Venky Raju(dev@venky.ws) + * + * lirc_imon 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. + * + */ +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 22) +#error "*** Sorry, this driver requires kernel version 2.4.22 or higher" +#endif + +#include + +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include + +#include "kcompat.h" +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" + + +#define MOD_AUTHOR "Venky Raju " +#define MOD_DESC "Driver for Soundgraph iMON MultiMedia IR/VFD w/imon pad2keys patch" +#define MOD_NAME "lirc_imon" +#define MOD_VERSION "0.3p2k" + +#define VFD_MINOR_BASE 144 /* Same as LCD */ +#define DEVFS_MODE (S_IFCHR | S_IRUSR | S_IWUSR | \ + S_IRGRP | S_IWGRP | S_IROTH) +#define DEVFS_NAME LIRC_DEVFS_PREFIX "lcd%d" + +#define BUF_CHUNK_SIZE 4 +#define BUF_SIZE 128 + +#define BIT_DURATION 250 /* each bit received is 250us */ + +#define SUCCESS 0 +#define TRUE 1 +#define FALSE 0 + +#define CURSOR_LIMIT 16 + +/* ------------------------------------------------------------ + * P R O T O T Y P E S + * ------------------------------------------------------------ + */ + +/* USB Callback prototypes */ +#ifdef KERNEL_2_5 +static int imon_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void imon_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs); +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs); +#else +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif +#else +static void *imon_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id); +static void imon_disconnect(struct usb_device *dev, void *data); +static void usb_rx_callback(struct urb *urb); +static void usb_tx_callback(struct urb *urb); +#endif + +/* VFD file_operations function prototypes */ +static int vfd_open(struct inode *inode, struct file *file); +static int vfd_close(struct inode *inode, struct file *file); +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/* LCD file_operations override function prototypes */ +static ssize_t lcd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos); + +/* LIRC plugin function prototypes */ +static int ir_open(void *data); +static void ir_close(void *data); + +/* Driver init/exit prototypes */ +static int __init imon_init(void); +static void __exit imon_exit(void); + +/* ------------------------------------------------------------ + * G L O B A L S + * ------------------------------------------------------------ + */ + +struct imon_context { + struct usb_device *dev; + int vfd_supported; /* not all controllers do */ + int vfd_isopen; /* VFD port has been opened */ +#if !defined(KERNEL_2_5) + int subminor; /* index into minor_table */ + devfs_handle_t devfs; +#endif + int ir_isopen; /* IR port open */ + int ir_isassociating; /* IR port open for association */ + int dev_present; /* USB device presence */ + struct semaphore sem; /* to lock this object */ + wait_queue_head_t remove_ok; /* For unexpected USB disconnects */ + + int vfd_proto_6p; /* VFD requires 6th packet */ + int ir_onboard_decode; /* IR signals decoded onboard */ + + struct lirc_plugin *plugin; + struct usb_endpoint_descriptor *rx_endpoint; + struct usb_endpoint_descriptor *tx_endpoint; + struct urb *rx_urb; + struct urb *tx_urb; + unsigned char usb_rx_buf[8]; + unsigned char usb_tx_buf[8]; + + struct rx_data { + int count; /* length of 0 or 1 sequence */ + int prev_bit; /* logic level of sequence */ + int initial_space; /* initial space flag */ + } rx; + + struct tx_t { + unsigned char data_buf[35]; /* user data buffer */ + struct completion finished; /* wait for write to finish */ + atomic_t busy; /* write in progress */ + int status; /* status of tx completion */ + } tx; + + int key_x; + int key_y; + int last_count; /* number of times pressed */ +}; + +#define LOCK_CONTEXT down(&context->sem) +#define UNLOCK_CONTEXT up(&context->sem) + +/* VFD file operations */ +static struct file_operations vfd_fops = { + .owner = THIS_MODULE, + .open = &vfd_open, + .write = &vfd_write, + .release = &vfd_close +}; + +/* USB Device ID for IMON USB Control Board */ +static struct usb_device_id imon_usb_id_table[] = { + { USB_DEVICE(0x0aa8, 0xffda) }, /* IR & VFD */ + { USB_DEVICE(0x0aa8, 0x8001) }, /* IR only */ + { USB_DEVICE(0x15c2, 0xffda) }, /* IR & VFD */ + { USB_DEVICE(0x15c2, 0xffdc) }, /* IR & VFD */ + { USB_DEVICE(0x04e8, 0xff30) }, /* ext IR only */ + {} +}; + +/* Some iMON VFD models requires a 6th packet */ +static unsigned short vfd_proto_6p_vendor_list[] = { + /* terminate this list with a 0 */ + 0x15c2, + 0 }; +static unsigned char vfd_packet6[] = { + 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; + +/* Newer iMON models decode the signal onboard */ +static unsigned short ir_onboard_decode_product_list[] = { + /* terminate this list with a 0 */ + 0xffdc, + 0 }; + +/* USB Device data */ +static struct usb_driver imon_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = MOD_NAME, + .probe = imon_probe, + .disconnect = imon_disconnect, + .id_table = imon_usb_id_table, +#if !defined(KERNEL_2_5) + .fops = &vfd_fops, + .minor = VFD_MINOR_BASE, +#endif +}; + +#ifdef KERNEL_2_5 +static struct usb_class_driver imon_class = { + .name = DEVFS_NAME, + .fops = &vfd_fops, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 15) + .mode = DEVFS_MODE, +#endif + .minor_base = VFD_MINOR_BASE, +}; +#endif + +/* to prevent races between open() and disconnect() */ +static DECLARE_MUTEX(disconnect_sem); + +static int debug; +#ifdef LIRC_IMON_LCD +static int is_lcd = 1; +#else +static int is_lcd; /* If LIRC_IMON_LCD not defined, default to non-LCD */ +#endif + +/* pad2keys module parameter. pad2keys patch active? */ +static int pad2keys_active = 0; + +#if !defined(KERNEL_2_5) + +#define MAX_DEVICES 4 /* In case there's more than one iMON device */ +static struct imon_context *minor_table[MAX_DEVICES]; + +/* +static DECLARE_MUTEX(minor_table_sem); +#define LOCK_MINOR_TABLE down(&minor_table_sem) +#define UNLOCK_MINOR_TABLE up(&minor_table_sem) +*/ + +/* the global usb devfs handle */ +extern devfs_handle_t usb_devfs_handle; + +#endif + +/* ------------------------------------------------------------ + * M O D U L E C O D E + * ------------------------------------------------------------ + */ + +MODULE_AUTHOR(MOD_AUTHOR); +MODULE_DESCRIPTION(MOD_DESC); +MODULE_VERSION(MOD_VERSION); /* MBr: was missing */ +MODULE_LICENSE("GPL"); +MODULE_DEVICE_TABLE(usb, imon_usb_id_table); + +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "Debug messages: 0=no, 1=yes(default: no)"); + +#ifdef LIRC_IMON_LCD +module_param(is_lcd, int, 1); +MODULE_PARM_DESC(is_lcd, "The device is an LCD: 0=no (it's a VFD), " + "1=yes (default:yes)"); +#else +module_param(is_lcd, int, 0); +MODULE_PARM_DESC(is_lcd, "The device is an LCD: 0=no (it's a VFD), " + "1=yes (default:no)"); +#endif +module_param (pad2keys_active, int, 0); +MODULE_PARM_DESC (pad2keys_active, "pad2keys patch active: 0=no, 1=yes (default: no)"); + +static inline void delete_context(struct imon_context *context) +{ + if (context->vfd_supported) + usb_free_urb(context->tx_urb); + usb_free_urb(context->rx_urb); + lirc_buffer_free(context->plugin->rbuf); + kfree(context->plugin->rbuf); + kfree(context->plugin); + kfree(context); + + if (debug) + info("%s: context deleted", __FUNCTION__); +} + +static inline void deregister_from_lirc(struct imon_context *context) +{ + int retval; + int minor = context->plugin->minor; + + retval = lirc_unregister_plugin(minor); + if (retval) + err("%s: unable to deregister from lirc(%d)", + __FUNCTION__, retval); + else + info("Deregistered iMON plugin(minor:%d)", minor); + +} + +/** + * Called when the VFD device(e.g. /dev/usb/lcd) + * is opened by the application. + */ +static int vfd_open(struct inode *inode, struct file *file) +{ +#ifdef KERNEL_2_5 + struct usb_interface *interface; +#endif + struct imon_context *context = NULL; + int subminor; + int retval = SUCCESS; + + /* prevent races with disconnect */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + subminor = iminor(inode); + interface = usb_find_interface(&imon_driver, subminor); + if (!interface) { + err("%s: could not find interface for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = usb_get_intfdata(interface); +#else + subminor = MINOR(inode->i_rdev) - VFD_MINOR_BASE; + if (subminor < 0 || subminor >= MAX_DEVICES) { + err("%s: no record of minor %d", __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + context = minor_table[subminor]; +#endif + + if (!context) { + err("%s: no context found for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + + LOCK_CONTEXT; + + if (!context->vfd_supported) { + err("%s: VFD not supported by device", __FUNCTION__); + retval = -ENODEV; + } else if (context->vfd_isopen) { + err("%s: VFD port is already open", __FUNCTION__); + retval = -EBUSY; + } else { + MOD_INC_USE_COUNT; + context->vfd_isopen = TRUE; + file->private_data = context; + info("VFD port opened"); + } + + UNLOCK_CONTEXT; + +exit: + up(&disconnect_sem); + return retval; +} + +/** + * Called when the VFD device(e.g. /dev/usb/lcd) + * is closed by the application. + */ +static int vfd_close(struct inode *inode, struct file *file) +{ + struct imon_context *context = NULL; + int retval = SUCCESS; + + context = (struct imon_context *) file->private_data; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->vfd_supported) { + err("%s: VFD not supported by device", __FUNCTION__); + retval = -ENODEV; + } else if (!context->vfd_isopen) { + err("%s: VFD is not open", __FUNCTION__); + retval = -EIO; + } else { + context->vfd_isopen = FALSE; + MOD_DEC_USE_COUNT; + info("VFD port closed"); + if (!context->dev_present && !context->ir_isopen) { + /* Device disconnected before close and IR port is not + * open. If IR port is open, context will be deleted by + * ir_close. */ + UNLOCK_CONTEXT; + delete_context(context); + return retval; + } + } + + UNLOCK_CONTEXT; + return retval; +} + +/** + * Sends a packet to the VFD. + */ +static inline int send_packet(struct imon_context *context) +{ + unsigned int pipe; + int interval = 0; + int retval = SUCCESS; + + pipe = usb_sndintpipe(context->dev, + context->tx_endpoint->bEndpointAddress); +#ifdef KERNEL_2_5 + interval = context->tx_endpoint->bInterval; +#endif /* Use 0 for 2.4 kernels */ + + usb_fill_int_urb(context->tx_urb, context->dev, pipe, + context->usb_tx_buf, sizeof(context->usb_tx_buf), + usb_tx_callback, context, interval); + + context->tx_urb->actual_length = 0; + + init_completion(&context->tx.finished); + atomic_set(&(context->tx.busy), 1); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->tx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->tx_urb); +#endif + if (retval != SUCCESS) { + atomic_set(&(context->tx.busy), 0); + err("%s: error submitting urb(%d)", __FUNCTION__, retval); + } else { + /* Wait for tranmission to complete(or abort) */ + UNLOCK_CONTEXT; + wait_for_completion(&context->tx.finished); + LOCK_CONTEXT; + + retval = context->tx.status; + if (retval != SUCCESS) + err("%s: packet tx failed(%d)", __FUNCTION__, retval); + } + + return retval; +} + +/** + * Sends an associate packet to the iMON 2.4G. + * + * This might not be such a good idea, since it has an id + * collition with some versions of the "IR & VFD" combo. + * The only way to determine if it is a RF version is to look + * at the product description string.(Which we currently do + * not fetch). + */ +static inline int send_associate_24g(struct imon_context *context) +{ + int retval; + const unsigned char packet[8] = { 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20 }; + + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no iMON device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + memcpy(context->usb_tx_buf, packet, sizeof(packet)); + retval = send_packet(context); + +exit: + UNLOCK_CONTEXT; + + return retval; +} + +#ifdef KERNEL_2_5 +/** + * This is the sysfs functions to handle the association og the iMON 2.4G LT. + * + * + */ + +static ssize_t show_associate_remote(struct device *d, + struct device_attribute *attr, + char *buf) +{ + struct imon_context *context = dev_get_drvdata(d); + + if (!context) + return -ENODEV; + + if (context->ir_isassociating) { + strcpy(buf, "The device it associating press some button " + "on the remote.\n"); + } else if (context->ir_isopen) { + strcpy(buf, "Device is open and ready to associate.\n" + "Echo something into this file to start " + "the process.\n"); + } else { + strcpy(buf, "Device is closed, you need to open it to " + "associate the remote(you can use irw).\n"); + } + return strlen(buf); +} + +static ssize_t store_associate_remote(struct device *d, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct imon_context *context; + + context = dev_get_drvdata(d); + + if (!context) + return -ENODEV; + + if (!context->ir_isopen) + return -EINVAL; + + if (context->ir_isopen) { + context->ir_isassociating = TRUE; + send_associate_24g(context); + } + + return count; +} + +static DEVICE_ATTR(associate_remote, S_IWUSR | S_IRUGO, show_associate_remote, + store_associate_remote); + +static struct attribute *imon_sysfs_entries[] = { + &dev_attr_associate_remote.attr, + NULL +}; + +static struct attribute_group imon_attribute_group = { + .attrs = imon_sysfs_entries +}; + +#endif + + + +/** + * Writes data to the VFD. The IMON VFD is 2x16 characters + * and requires data in 5 consecutive USB interrupt packets, + * each packet but the last carrying 7 bytes. + * + * I don't know if the VFD board supports features such as + * scrolling, clearing rows, blanking, etc. so at + * the caller must provide a full screen of data. If fewer + * than 32 bytes are provided spaces will be appended to + * generate a full screen. + */ +static ssize_t vfd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int i; + int offset; + int seq; + int retval = SUCCESS; + struct imon_context *context; + + context = (struct imon_context *) file->private_data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no iMON device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + if (n_bytes <= 0 || n_bytes > 32) { + err("%s: invalid payload size", __FUNCTION__); + retval = -EINVAL; + goto exit; + } + + if (copy_from_user(context->tx.data_buf, buf, n_bytes)) + return -EFAULT; + + /* Pad with spaces */ + for (i = n_bytes; i < 32; ++i) + context->tx.data_buf[i] = ' '; + + for (i = 32; i < 35; ++i) + context->tx.data_buf[i] = 0xFF; + + offset = 0; + seq = 0; + + do { + memcpy(context->usb_tx_buf, context->tx.data_buf + offset, 7); + context->usb_tx_buf[7] = (unsigned char) seq; + + retval = send_packet(context); + if (retval != SUCCESS) { + err("%s: send packet failed for packet #%d", + __FUNCTION__, seq/2); + goto exit; + } else { + seq += 2; + offset += 7; + } + + } while (offset < 35); + + if (context->vfd_proto_6p) { + /* Send packet #6 */ + memcpy(context->usb_tx_buf, vfd_packet6, 7); + context->usb_tx_buf[7] = (unsigned char) seq; + retval = send_packet(context); + if (retval != SUCCESS) + err("%s: send packet failed for packet #%d", + __FUNCTION__, seq/2); + } + +exit: + UNLOCK_CONTEXT; + + return(retval == SUCCESS) ? n_bytes : retval; +} + +/** + * Writes data to the LCD. The iMON OEM LCD screen excepts 8-byte + * packets. We accept data as 16 hexadecimal digits, followed by a + * newline (to make it easy to drive the device from a command-line + * -- even though the actual binary data is a bit complicated). + * + * The device itself is not a "traditional" text-mode display. It's + * actually a 16x96 pixel bitmap display. That means if you want to + * display text, you've got to have your own "font" and translate the + * text into bitmaps for display. This is really flexible (you can + * display whatever diacritics you need, and so on), but it's also + * a lot more complicated than most LCDs... + */ +static ssize_t lcd_write(struct file *file, const char *buf, + size_t n_bytes, loff_t *pos) +{ + int retval = SUCCESS; + struct imon_context *context; + + context = (struct imon_context *) file->private_data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return -ENODEV; + } + + LOCK_CONTEXT; + + if (!context->dev_present) { + err("%s: no iMON device present", __FUNCTION__); + retval = -ENODEV; + goto exit; + } + + if (n_bytes != 8) { + err("%s: invalid payload size: %d (expecting 8)", + __FUNCTION__, (int) n_bytes); + retval = -EINVAL; + goto exit; + } + + if (copy_from_user(context->usb_tx_buf, buf, 8)) + return -EFAULT; + + retval = send_packet(context); + if (retval != SUCCESS) { + err("%s: send packet failed!", + __FUNCTION__); + goto exit; + } else if (debug) { + info("%s: write %d bytes to LCD", __FUNCTION__, (int) n_bytes); + } +exit: + UNLOCK_CONTEXT; + return (retval == SUCCESS) ? n_bytes : retval; +} + +/** + * Callback function for USB core API: transmit data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_tx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_tx_callback(struct urb *urb) +#endif +{ + struct imon_context *context; + + if (!urb) + return; + context = (struct imon_context *) urb->context; + if (!context) + return; + + context->tx.status = urb->status; + + /* notify waiters that write has finished */ + atomic_set(&context->tx.busy, 0); + complete(&context->tx.finished); + + return; +} + +/** + * Called by lirc_dev when the application opens /dev/lirc + */ +static int ir_open(void *data) +{ + int retval = SUCCESS; + struct imon_context *context; + + /* prevent races with disconnect */ + down(&disconnect_sem); + + context = (struct imon_context *) data; + + LOCK_CONTEXT; + + if (context->ir_isopen) { + err("%s: IR port is already open", __FUNCTION__); + retval = -EBUSY; + goto exit; + } + + /* initial IR protocol decode variables */ + context->rx.count = 0; + context->rx.initial_space = 1; + context->rx.prev_bit = 0; + + /* init pad context for pad2keys */ + context ->key_x = 0; + context ->key_y = 0; + context ->last_count = 0; + + usb_fill_int_urb(context->rx_urb, context->dev, + usb_rcvintpipe(context->dev, + context->rx_endpoint->bEndpointAddress), + context->usb_rx_buf, sizeof(context->usb_rx_buf), + usb_rx_callback, context, context->rx_endpoint->bInterval); + +#ifdef KERNEL_2_5 + retval = usb_submit_urb(context->rx_urb, GFP_KERNEL); +#else + retval = usb_submit_urb(context->rx_urb); +#endif + + if (retval) + err("%s: usb_submit_urb failed for ir_open(%d)", + __FUNCTION__, retval); + else { + MOD_INC_USE_COUNT; + context->ir_isopen = TRUE; + info("IR port opened"); + } + +exit: + UNLOCK_CONTEXT; + + up(&disconnect_sem); + return SUCCESS; +} + +/** + * Called by lirc_dev when the application closes /dev/lirc + */ +static void ir_close(void *data) +{ + struct imon_context *context; + + context = (struct imon_context *)data; + if (!context) { + err("%s: no context for device", __FUNCTION__); + return; + } + + LOCK_CONTEXT; + + usb_kill_urb(context->rx_urb); + context->ir_isopen = FALSE; + context->ir_isassociating = FALSE; + MOD_DEC_USE_COUNT; + info("IR port closed"); + + if (!context->dev_present) { + /* Device disconnected while IR port was + * still open. Plugin was not deregistered + * at disconnect time, so do it now. */ + deregister_from_lirc(context); + + if (!context->vfd_isopen) { + UNLOCK_CONTEXT; + delete_context(context); + return; + } + /* If VFD port is open, context will be deleted by vfd_close */ + } + + UNLOCK_CONTEXT; + return; +} + +/** + * Convert bit count to time duration(in us) and submit + * the value to lirc_dev. + */ +static inline void submit_data(struct imon_context *context) +{ + unsigned char buf[4]; + int value = context->rx.count; + int i; + + if (debug) + info("submitting data to LIRC\n"); + + value *= BIT_DURATION; + value &= PULSE_MASK; + if (context->rx.prev_bit) + value |= PULSE_BIT; + + for (i = 0; i < 4; ++i) + buf[i] = value>>(i*8); + + lirc_buffer_write_1(context->plugin->rbuf, buf); + wake_up(&context->plugin->rbuf->wait_poll); + return; +} + +/** + * Process the incoming packet + */ +static inline void incoming_packet(struct imon_context *context, + struct urb *urb) +{ + int len = urb->actual_length; + unsigned char *buf = urb->transfer_buffer; + int octet, bit; + unsigned char mask; + int chunk_num; +#ifdef DEBUG + int i; +#endif + + if (len != 8) { + warn("%s: invalid incoming packet size(%d)", + __FUNCTION__, len); + return; + } + + /* iMON 2.4G associate frame */ + if (buf[0] == 0x00 && + buf[2] == 0xFF && /* REFID */ + buf[3] == 0xFF && + buf[4] == 0xFF && + buf[5] == 0xFF && /* iMON 2.4G */ + ((buf[6] == 0x4E && buf[7] == 0xDF) || /* LT */ + (buf[6] == 0x5E && buf[7] == 0xDF))) { /* DT */ + warn("%s: remote associated refid=%02X", __FUNCTION__, buf[1]); + context->ir_isassociating = FALSE; + } + + chunk_num = buf[7]; + + if (chunk_num == 0xFF) + return; /* filler frame, no data here */ + + if (buf[0] == 0xFF && + buf[1] == 0xFF && + buf[2] == 0xFF && + buf[3] == 0xFF && + buf[4] == 0xFF && + buf[5] == 0xFF && /* iMON 2.4G */ + ((buf[6] == 0x4E && buf[7] == 0xAF) || /* LT */ + (buf[6] == 0x5E && buf[7] == 0xAF))) /* DT */ + return; /* filler frame, no data here */ + +#ifdef DEBUG + for (i = 0; i < 8; ++i) + printk(KERN_INFO "%02x ", buf[i]); + printk(KERN_INFO "\n"); +#endif + + if (context->ir_onboard_decode) { + /* The signals have been decoded onboard the iMON controller */ + + if (pad2keys_active) + { + /* imon pad2keys patch + * + * make PAD and mouse buttons available for use with VDR, + * based on pad-mouse-emu patch from venky's forum + * + * last change: M.Brakemeier 2007-10-14 + * + * generated PAD key codes: + * Mouse_N 0x690281B7 + * Mouse_S 0x688291B7 + * Mouse_W 0x6A8281B7 + * Mouse_E 0x688A81B7 + * + * mouse buttons (non-synthetic): + * MouseRightClick 0x688481B7 + * MouseLeftClick 0x688301B7 + */ + if((buf[0] & 0x40) && + !(buf[1] & 0x01 || buf[1] >> 2 & 0x01)) + { + int rel_x = (buf[1] & 0x08) | (buf[1] & 0x10) >> 2 | (buf[1] & 0x20) >> 4 | (buf[1] & 0x40) >> 6; + int rel_y = (buf[2] & 0x08) | (buf[2] & 0x10) >> 2 | (buf[2] & 0x20) >> 4 | (buf[2] & 0x40) >> 6; + + if(buf[0] & 0x02) + rel_x |= ~0x10+1; + if(buf[0] & 0x01) + rel_y |= ~0x10+1; + + /* keyboard direction key emulation */ + if( context->last_count > 32 ) + { /* Hopefully eliminate drift*/ + context->last_count=0; + context->key_y=0; + context->key_x=0; + } + context->last_count++; + + /* limit decoded events */ + if(abs(context->key_x) > CURSOR_LIMIT || abs(context->key_y) > CURSOR_LIMIT ) + { + if(abs(context->key_y ) > abs(context->key_x)) + { /* mouse s/n */ + if(context->key_y > 0 && rel_y > 0) + { /* mouse s */ + buf[0] = 0x68; + buf[1] = 0x82; + buf[2] = 0x91; + } + else if(context->key_y < 0 && rel_y < 0) + { /* mouse n */ + buf[0] = 0x69; + buf[1] = 0x02; + buf[2] = 0x81; + } + } + else + { /* mouse e/w*/ + if(context->key_x > 0 && rel_x > 0 ) + { /* mouse e */ + buf[0] = 0x68; + buf[1] = 0x8A; + buf[2] = 0x81; + } + else if(context->key_x < 0 && rel_x < 0 ) + { /* mouse w */ + buf[0] = 0x6A; + buf[1] = 0x82; + buf[2] = 0x81; + } + } + } + else + { + context->key_x += rel_x; + context->key_y += rel_y; + + return; /* discard those key codes */ + } + } + /* a key was pressed, reset count */ + context->key_x = 0; + context->key_y = 0; + context->last_count = 0; + } + + lirc_buffer_write_1(context->plugin->rbuf, buf); + wake_up(&context->plugin->rbuf->wait_poll); + return; + } + + /* Translate received data to pulse and space lengths. + * Received data is active low, i.e. pulses are 0 and + * spaces are 1. + * + * My original algorithm was essentially similar to + * Changwoo Ryu's with the exception that he switched + * the incoming bits to active high and also fed an + * initial space to LIRC at the start of a new sequence + * if the previous bit was a pulse. + * + * I've decided to adopt his algorithm. */ + + if (chunk_num == 1 && context->rx.initial_space) { + /* LIRC requires a leading space */ + context->rx.prev_bit = 0; + context->rx.count = 4; + submit_data(context); + context->rx.count = 0; + } + + for (octet = 0; octet < 5; ++octet) { + mask = 0x80; + for (bit = 0; bit < 8; ++bit) { + int curr_bit = !(buf[octet] & mask); + if (curr_bit != context->rx.prev_bit) { + if (context->rx.count) { + submit_data(context); + context->rx.count = 0; + } + context->rx.prev_bit = curr_bit; + } + ++context->rx.count; + mask >>= 1; + } + } + + if (chunk_num == 10) { + if (context->rx.count) { + submit_data(context); + context->rx.count = 0; + } + context->rx.initial_space = context->rx.prev_bit; + } +} + +/** + * Callback function for USB core API: receive data + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_rx_callback(struct urb *urb, struct pt_regs *regs) +#else +static void usb_rx_callback(struct urb *urb) +#endif +{ + struct imon_context *context; + + if (!urb) + return; + context = (struct imon_context *) urb->context; + if (!context) + return; + + switch (urb->status) { + case -ENOENT: /* usbcore unlink successful! */ + return; + case SUCCESS: + if (context->ir_isopen) + incoming_packet(context, urb); + break; + default : + warn("%s: status(%d): ignored", __FUNCTION__, urb->status); + break; + } + +#ifdef KERNEL_2_5 + usb_submit_urb(context->rx_urb, GFP_ATOMIC); +#endif + return; +} + + + +/** + * Callback function for USB core API: Probe + */ +#ifdef KERNEL_2_5 +static int imon_probe(struct usb_interface *interface, + const struct usb_device_id *id) +#else +static void *imon_probe(struct usb_device *dev, unsigned int intf, + const struct usb_device_id *id) +#endif +{ +#ifdef KERNEL_2_5 + struct usb_device *dev = NULL; + struct usb_host_interface *iface_desc = NULL; +#else + struct usb_interface *interface = NULL; + struct usb_interface_descriptor *iface_desc = NULL; + char name[10]; + int subminor = 0; +#endif + struct usb_endpoint_descriptor *rx_endpoint = NULL; + struct usb_endpoint_descriptor *tx_endpoint = NULL; + struct urb *rx_urb = NULL; + struct urb *tx_urb = NULL; + struct lirc_plugin *plugin = NULL; + struct lirc_buffer *rbuf = NULL; + int lirc_minor = 0; + int num_endpoints; + int retval = SUCCESS; + int vfd_ep_found; + int ir_ep_found; + int alloc_status; + int vfd_proto_6p = FALSE; + int ir_onboard_decode = FALSE; + struct imon_context *context = NULL; + int i; + + info("%s: found IMON device", __FUNCTION__); + + /* + * If it's the LCD, as opposed to the VFD, we just need to replace + * the "write" file op. + */ + if (is_lcd) + vfd_fops.write = &lcd_write; + +#if !defined(KERNEL_2_5) + for (subminor = 0; subminor < MAX_DEVICES; ++subminor) { + if (minor_table[subminor] == NULL) + break; + } + if (subminor == MAX_DEVICES) { + err("%s: allowed max number of devices already present", + __FUNCTION__); + retval = -ENOMEM; + goto exit; + } +#endif + +#ifdef KERNEL_2_5 + dev = usb_get_dev(interface_to_usbdev(interface)); + iface_desc = interface->cur_altsetting; + num_endpoints = iface_desc->desc.bNumEndpoints; +#else + interface = &dev->actconfig->interface[intf]; + iface_desc = &interface->altsetting[interface->act_altsetting]; + num_endpoints = iface_desc->bNumEndpoints; +#endif + + /* + * Scan the endpoint list and set: + * first input endpoint = IR endpoint + * first output endpoint = VFD endpoint + */ + + ir_ep_found = FALSE; + vfd_ep_found = FALSE; + + for (i = 0; i < num_endpoints && !(ir_ep_found && vfd_ep_found); ++i) { + struct usb_endpoint_descriptor *ep; + int ep_dir; + int ep_type; +#ifdef KERNEL_2_5 + ep = &iface_desc->endpoint[i].desc; +#else + ep = &iface_desc->endpoint[i]; +#endif + ep_dir = ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK; + ep_type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + + if (!ir_ep_found && + ep_dir == USB_DIR_IN && + ep_type == USB_ENDPOINT_XFER_INT) { + + rx_endpoint = ep; + ir_ep_found = TRUE; + if (debug) + info("%s: found IR endpoint", __FUNCTION__); + + } else if (!vfd_ep_found && + ep_dir == USB_DIR_OUT && + ep_type == USB_ENDPOINT_XFER_INT) { + tx_endpoint = ep; + vfd_ep_found = TRUE; + if (debug) + info("%s: found VFD endpoint", __FUNCTION__); + } + } + + /* Input endpoint is mandatory */ + if (!ir_ep_found) { + err("%s: no valid input(IR) endpoint found.", __FUNCTION__); + retval = -ENODEV; + goto exit; + } else { + /* Determine if the IR signals are decoded onboard */ + unsigned short product_id; + unsigned short *id_list_item; + + product_id = cpu_to_le16(dev->descriptor.idProduct); + id_list_item = ir_onboard_decode_product_list; + while (*id_list_item) { + if (*id_list_item++ == product_id) { + ir_onboard_decode = TRUE; + break; + } + } + + if (debug) + info("ir_onboard_decode: %d", ir_onboard_decode); + } + + /* Determine if VFD requires 6 packets */ + if (vfd_ep_found) { + unsigned short vendor_id; + unsigned short *id_list_item; + + vendor_id = cpu_to_le16(dev->descriptor.idVendor); + id_list_item = vfd_proto_6p_vendor_list; + while (*id_list_item) { + if (*id_list_item++ == vendor_id) { + vfd_proto_6p = TRUE; + break; + } + } + + if (debug) + info("vfd_proto_6p: %d", vfd_proto_6p); + } + + + /* Allocate memory */ + + alloc_status = SUCCESS; + + context = kmalloc(sizeof(struct imon_context), GFP_KERNEL); + if (!context) { + err("%s: kmalloc failed for context", __FUNCTION__); + alloc_status = 1; + goto alloc_status_switch; + } + plugin = kmalloc(sizeof(struct lirc_plugin), GFP_KERNEL); + if (!plugin) { + err("%s: kmalloc failed for lirc_plugin", __FUNCTION__); + alloc_status = 2; + goto alloc_status_switch; + } + rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL); + if (!rbuf) { + err("%s: kmalloc failed for lirc_buffer", __FUNCTION__); + alloc_status = 3; + goto alloc_status_switch; + } + if (lirc_buffer_init(rbuf, BUF_CHUNK_SIZE, BUF_SIZE)) { + err("%s: lirc_buffer_init failed", __FUNCTION__); + alloc_status = 4; + goto alloc_status_switch; + } +#ifdef KERNEL_2_5 + rx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + rx_urb = usb_alloc_urb(0); +#endif + if (!rx_urb) { + err("%s: usb_alloc_urb failed for IR urb", __FUNCTION__); + alloc_status = 5; + goto alloc_status_switch; + } + if (vfd_ep_found) { +#ifdef KERNEL_2_5 + tx_urb = usb_alloc_urb(0, GFP_KERNEL); +#else + tx_urb = usb_alloc_urb(0); +#endif + if (!tx_urb) { + err("%s: usb_alloc_urb failed for VFD urb", + __FUNCTION__); + alloc_status = 6; + goto alloc_status_switch; + } + } + + /* clear all members of imon_context and lirc_plugin */ + memset(context, 0, sizeof(struct imon_context)); + init_MUTEX(&context->sem); + context->vfd_proto_6p = vfd_proto_6p; + context->ir_onboard_decode = ir_onboard_decode; + + memset(plugin, 0, sizeof(struct lirc_plugin)); + + strcpy(plugin->name, MOD_NAME); + plugin->minor = -1; + plugin->code_length = (ir_onboard_decode) ? + 32 : sizeof(lirc_t) * 8; + plugin->sample_rate = 0; + plugin->features = (ir_onboard_decode) ? + LIRC_CAN_REC_LIRCCODE : LIRC_CAN_REC_MODE2; + plugin->data = context; + plugin->rbuf = rbuf; + plugin->set_use_inc = ir_open; + plugin->set_use_dec = ir_close; +#ifdef LIRC_HAVE_SYSFS + plugin->dev = &dev->dev; +#endif + plugin->owner = THIS_MODULE; + + LOCK_CONTEXT; + + lirc_minor = lirc_register_plugin(plugin); + if (lirc_minor < 0) { + err("%s: lirc_register_plugin failed", __FUNCTION__); + alloc_status = 7; + UNLOCK_CONTEXT; + goto alloc_status_switch; + } else + info("%s: Registered iMON plugin(minor:%d)", + __FUNCTION__, lirc_minor); + +alloc_status_switch: + + switch (alloc_status) { + case 7: + if (vfd_ep_found) + usb_free_urb(tx_urb); + case 6: + usb_free_urb(rx_urb); + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(plugin); + case 2: + kfree(context); + context = NULL; + case 1: + retval = -ENOMEM; + } + + /* Needed while unregistering! */ + plugin->minor = lirc_minor; + + context->dev = dev; + context->dev_present = TRUE; + context->rx_endpoint = rx_endpoint; + context->rx_urb = rx_urb; + if (vfd_ep_found) { + context->vfd_supported = TRUE; + context->tx_endpoint = tx_endpoint; + context->tx_urb = tx_urb; + } + context->plugin = plugin; + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, context); + + if (cpu_to_le16(dev->descriptor.idProduct) == 0xffdc) { + int err; + + err = sysfs_create_group(&interface->dev.kobj, + &imon_attribute_group); + if (err) + err("%s: Could not create sysfs entries(%d)", + __FUNCTION__, err); + } +#else + minor_table[subminor] = context; + context->subminor = subminor; +#endif + + if (vfd_ep_found) { + if (debug) + info("Registering VFD with devfs"); +#ifdef KERNEL_2_5 + if (usb_register_dev(interface, &imon_class)) { + /* Not a fatal error, so ignore */ + info("%s: could not get a minor number for VFD", + __FUNCTION__); + } +#else + sprintf(name, DEVFS_NAME, subminor); + if (!(context->devfs = devfs_register(usb_devfs_handle, name, + DEVFS_FL_DEFAULT, + USB_MAJOR, VFD_MINOR_BASE + subminor, + DEVFS_MODE, &vfd_fops, NULL))) { + /* not a fatal error so ignore */ + info("%s: devfs register failed for VFD", + __FUNCTION__); + } +#endif + } + + info("%s: iMON device on usb<%d:%d> initialized", + __FUNCTION__, dev->bus->busnum, dev->devnum); + + UNLOCK_CONTEXT; + + exit: +#ifdef KERNEL_2_5 + return retval; +#else + return (retval == SUCCESS) ? context : NULL; +#endif +} + +/** + * Callback function for USB core API: disonnect + */ +#ifdef KERNEL_2_5 +static void imon_disconnect(struct usb_interface *interface) +#else +static void imon_disconnect(struct usb_device *dev, void *data) +#endif +{ + struct imon_context *context; + + /* prevent races with ir_open()/vfd_open() */ + down(&disconnect_sem); + +#ifdef KERNEL_2_5 + context = usb_get_intfdata(interface); +#else + context = (struct imon_context *)data; +#endif + LOCK_CONTEXT; + + info("%s: iMON device disconnected", __FUNCTION__); + +#ifdef KERNEL_2_5 + /* sysfs_remove_group is safe to call even if sysfs_create_group + * hasn't been called */ + sysfs_remove_group(&interface->dev.kobj, + &imon_attribute_group); + usb_set_intfdata(interface, NULL); +#else + minor_table[context->subminor] = NULL; +#endif + context->dev_present = FALSE; + + /* Stop reception */ + usb_kill_urb(context->rx_urb); + + /* Abort ongoing write */ + if (atomic_read(&context->tx.busy)) { + usb_kill_urb(context->tx_urb); + wait_for_completion(&context->tx.finished); + } + + /* De-register from lirc_dev if IR port is not open */ + if (!context->ir_isopen) + deregister_from_lirc(context); + + if (context->vfd_supported) +#ifdef KERNEL_2_5 + usb_deregister_dev(interface, &imon_class); +#else + if (context->devfs) + devfs_unregister(context->devfs); +#endif + + UNLOCK_CONTEXT; + + if (!context->ir_isopen && !context->vfd_isopen) + delete_context(context); + + up(&disconnect_sem); +} + +static int __init imon_init(void) +{ + int rc; + + info(MOD_DESC ", v" MOD_VERSION); + info(MOD_AUTHOR); + + rc = usb_register(&imon_driver); + if (rc) { + err("%s: usb register failed(%d)", __FUNCTION__, rc); + return -ENODEV; + } + return SUCCESS; +} + +static void __exit imon_exit(void) +{ + usb_deregister(&imon_driver); + info("module removed. Goodbye!"); +} + + +module_init(imon_init); +module_exit(imon_exit); + +#if !defined(KERNEL_2_5) +EXPORT_NO_SYMBOLS; +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_imon/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_imon/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_IMON) += lirc_imon.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_i2c/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_i2c/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_I2C) += lirc_i2c.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_i2c/lirc_i2c.c +++ linux-2.6.28/ubuntu/lirc/lirc_i2c/lirc_i2c.c @@ -0,0 +1,681 @@ +/* $Id: lirc_i2c.c,v 1.46 2008/05/04 13:49:53 lirc Exp $ */ + +/* + * i2c IR lirc plugin for Hauppauge and Pixelview cards - new 2.3.x i2c stack + * + * Copyright (c) 2000 Gerd Knorr + * modified for PixelView (BT878P+W/FM) by + * Michal Kochanowicz + * Christoph Bartelmus + * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by + * Ulrich Mueller + * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by + * Stefan Jahn + * modified for inclusion into kernel sources by + * Jerome Brock + * modified for Leadtek Winfast PVR2000 by + * Thomas Reitmayr (treitmayr@yahoo.com) + * modified for Hauppauge HVR-1300 by + * Jan Frey (jfrey@gmx.de) + * + * parts are cut&pasted from the old lirc_haup.c driver + * + * 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 + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +struct IR { + struct lirc_plugin l; + struct i2c_client c; + int nextkey; + unsigned char b[3]; + unsigned char bits; + unsigned char flag; +}; + +/* ----------------------------------------------------------------------- */ + +#define DEVICE_NAME "lirc_i2c" + +/* ----------------------------------------------------------------------- */ +/* insmod parameters */ + +static int debug; /* debug output */ +static int minor = -1; /* minor number */ + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG DEVICE_NAME ": " fmt, \ + ## args); \ + } while (0) + +/* ----------------------------------------------------------------------- */ + +static inline int reverse(int data, int bits) +{ + int i; + int c; + + for (c = 0, i = 0; i < bits; i++) + c |= (((data & (1<c, keybuf, 1); + /* poll IR chip */ + if (i2c_master_recv(&ir->c, keybuf, sizeof(keybuf)) != sizeof(keybuf)) { + dprintk("read error\n"); + return -EIO; + } + + dprintk("key (0x%02x%02x%02x%02x)\n", + keybuf[0], keybuf[1], keybuf[2], keybuf[3]); + + /* key pressed ? */ + if (keybuf[2] == 0xff) + return -ENODATA; + + /* remove repeat bit */ + keybuf[2] &= 0x7f; + keybuf[3] |= 0x80; + + lirc_buffer_write_1(buf, keybuf); + return 0; +} + +static int add_to_buf_pcf8574(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + int rc; + unsigned char all, mask; + unsigned char key; + + /* compute all valid bits (key code + pressed/release flag) */ + all = ir->bits | ir->flag; + + /* save IR writable mask bits */ + mask = i2c_smbus_read_byte(&ir->c) & ~all; + + /* send bit mask */ + rc = i2c_smbus_write_byte(&ir->c, (0xff & all) | mask); + + /* receive scan code */ + rc = i2c_smbus_read_byte(&ir->c); + + if (rc == -1) { + dprintk("%s read error\n", ir->c.name); + return -EIO; + } + + /* drop duplicate polls */ + if (ir->b[0] == (rc & all)) + return -ENODATA; + + ir->b[0] = rc & all; + + dprintk("%s key 0x%02X %s\n", ir->c.name, rc & ir->bits, + (rc & ir->flag) ? "released" : "pressed"); + + if (rc & ir->flag) { + /* ignore released buttons */ + return -ENODATA; + } + + /* set valid key code */ + key = rc & ir->bits; + lirc_buffer_write_1(buf, &key); + return 0; +} + +/* common for Hauppauge IR receivers */ +static int add_to_buf_haup_common(void *data, struct lirc_buffer *buf, + unsigned char *keybuf, int size, int offset) +{ + struct IR *ir = data; + __u16 code; + unsigned char codes[2]; + + /* poll IR chip */ + if (size == i2c_master_recv(&ir->c, keybuf, size)) { + ir->b[0] = keybuf[offset]; + ir->b[1] = keybuf[offset+1]; + ir->b[2] = keybuf[offset+2]; + dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); + } else { + dprintk("read error\n"); + /* keep last successfull read buffer */ + } + + /* key pressed ? */ + if ((ir->b[0] & 0x80) == 0) + return -ENODATA; + + /* look what we have */ + code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2); + + codes[0] = (code >> 8) & 0xff; + codes[1] = code & 0xff; + + /* return it */ + lirc_buffer_write_1(buf, codes); + return 0; +} + +/* specific for the Hauppauge PVR150 IR receiver */ +static int add_to_buf_haup_pvr150(void *data, struct lirc_buffer *buf) +{ + unsigned char keybuf[6]; + /* fetch 6 bytes, first relevant is at offset 3 */ + return add_to_buf_haup_common(data, buf, keybuf, 6, 3); +} + +/* used for all Hauppauge IR receivers but the PVR150 */ +static int add_to_buf_haup(void *data, struct lirc_buffer *buf) +{ + unsigned char keybuf[3]; + /* fetch 3 bytes, first relevant is at offset 0 */ + return add_to_buf_haup_common(data, buf, keybuf, 3, 0); +} + + +static int add_to_buf_pvr2000(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + unsigned char key; + s32 flags; + s32 code; + + /* poll IR chip */ + flags = i2c_smbus_read_byte_data(&ir->c, 0x10); + if (-1 == flags) { + dprintk("read error\n"); + return -ENODATA; + } + /* key pressed ? */ + if (0 == (flags & 0x80)) + return -ENODATA; + + /* read actual key code */ + code = i2c_smbus_read_byte_data(&ir->c, 0x00); + if (-1 == code) { + dprintk("read error\n"); + return -ENODATA; + } + + key = code & 0xFF; + + dprintk("IR Key/Flags: (0x%02x/0x%02x)\n", key, flags & 0xFF); + + /* return it */ + lirc_buffer_write_1(buf, &key); + return 0; +} + +static int add_to_buf_pixelview(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + unsigned char key; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c, &key, 1)) { + dprintk("read error\n"); + return -1; + } + dprintk("key %02x\n", key); + + /* return it */ + lirc_buffer_write_1(buf, &key); + return 0; +} + +static int add_to_buf_pv951(void *data, struct lirc_buffer *buf) +{ + struct IR *ir = data; + unsigned char key; + unsigned char codes[4]; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c, &key, 1)) { + dprintk("read error\n"); + return -ENODATA; + } + /* ignore 0xaa */ + if (key == 0xaa) + return -ENODATA; + dprintk("key %02x\n", key); + + codes[0] = 0x61; + codes[1] = 0xD6; + codes[2] = reverse(key, 8); + codes[3] = (~codes[2])&0xff; + + lirc_buffer_write_1(buf, codes); + return 0; +} + +static int add_to_buf_knc1(void *data, struct lirc_buffer *buf) +{ + static unsigned char last_key = 0xFF; + struct IR *ir = data; + unsigned char key; + + /* poll IR chip */ + if (1 != i2c_master_recv(&ir->c, &key, 1)) { + dprintk("read error\n"); + return -ENODATA; + } + + /* it seems that 0xFE indicates that a button is still hold + down, while 0xFF indicates that no button is hold + down. 0xFE sequences are sometimes interrupted by 0xFF */ + + dprintk("key %02x\n", key); + + if (key == 0xFF) + return -ENODATA; + + if (key == 0xFE) + key = last_key; + + last_key = key; + lirc_buffer_write_1(buf, &key); + + return 0; +} + +static int set_use_inc(void *data) +{ + struct IR *ir = data; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 25) + i2c_use_client(&ir->c); +#else + int ret; + + /* lock bttv in memory while /dev/lirc is in use */ + ret = i2c_use_client(&ir->c); + if (ret != 0) + return ret; +#endif + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + struct IR *ir = data; + + i2c_release_client(&ir->c); + MOD_DEC_USE_COUNT; +} + +static struct lirc_plugin lirc_template = { + .name = "lirc_i2c", + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .dev = NULL, + .owner = THIS_MODULE, +}; + +/* ----------------------------------------------------------------------- */ + +static int ir_attach(struct i2c_adapter *adap, int addr, + unsigned short flags, int kind); +static int ir_detach(struct i2c_client *client); +static int ir_probe(struct i2c_adapter *adap); +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg); + +static struct i2c_driver driver = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .name = "i2c ir driver", + .flags = I2C_DF_NOTIFY, +#else + .driver = { + .owner = THIS_MODULE, + .name = "i2c ir driver", + }, +#endif + .id = I2C_DRIVERID_EXP3, /* FIXME */ + .attach_adapter = ir_probe, + .detach_client = ir_detach, + .command = ir_command, +}; + +static struct i2c_client client_template = { + .name = "unset", + .driver = &driver +}; + +static int ir_attach(struct i2c_adapter *adap, int addr, + unsigned short flags, int kind) +{ + struct IR *ir; + int err; + + client_template.adapter = adap; + client_template.addr = addr; + + ir = kmalloc(sizeof(struct IR), GFP_KERNEL); + if (!ir) + return -ENOMEM; + memcpy(&ir->l, &lirc_template, sizeof(struct lirc_plugin)); + memcpy(&ir->c, &client_template, sizeof(struct i2c_client)); + + ir->c.adapter = adap; + ir->c.addr = addr; + i2c_set_clientdata(&ir->c, ir); + ir->l.data = ir; + ir->l.minor = minor; + ir->l.sample_rate = 10; + ir->nextkey = -1; + + switch (addr) { + case 0x64: + strlcpy(ir->c.name, "Pixelview IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_pixelview; + break; + case 0x4b: + strlcpy(ir->c.name, "PV951 IR", I2C_NAME_SIZE); + ir->l.code_length = 32; + ir->l.add_to_buf = add_to_buf_pv951; + break; + case 0x71: +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) { +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) { +#endif + /* The PVR150 IR receiver uses the same protocol as + * other Hauppauge cards, but the data flow is + * different, so we need to deal with it by its own. */ + strlcpy(ir->c.name, "Hauppauge PVR150", I2C_NAME_SIZE); + } else /* I2C_HW_B_CX2388x */ + strlcpy(ir->c.name, "Hauppauge HVR1300", I2C_NAME_SIZE); + ir->l.code_length = 13; + ir->l.add_to_buf = add_to_buf_haup_pvr150; + break; + case 0x6b: + strlcpy(ir->c.name, "Adaptec IR", I2C_NAME_SIZE); + ir->l.code_length = 32; + ir->l.add_to_buf = add_to_buf_adap; + break; + case 0x18: + case 0x1a: +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) { +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) { +#endif + strlcpy(ir->c.name, "Hauppauge IR", I2C_NAME_SIZE); + ir->l.code_length = 13; + ir->l.add_to_buf = add_to_buf_haup; + } else { /* I2C_HW_B_CX2388x */ + strlcpy(ir->c.name, "Leadtek IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_pvr2000; + } + break; + case 0x30: + strlcpy(ir->c.name, "KNC ONE IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_knc1; + break; + case 0x21: + case 0x23: + strlcpy(ir->c.name, "TV-Box IR", I2C_NAME_SIZE); + ir->l.code_length = 8; + ir->l.add_to_buf = add_to_buf_pcf8574; + ir->bits = flags & 0xff; + ir->flag = (flags >> 8) & 0xff; + break; + default: + /* shouldn't happen */ + printk("lirc_i2c: Huh? unknown i2c address (0x%02x)?\n", addr); + kfree(ir); + return -1; + } + printk(KERN_INFO "lirc_i2c: chip 0x%x found @ 0x%02x (%s)\n", + adap->id, addr, ir->c.name); + + /* register device */ + err = i2c_attach_client(&ir->c); + if (err) { + kfree(ir); + return err; + } + ir->l.minor = lirc_register_plugin(&ir->l); + + return 0; +} + +static int ir_detach(struct i2c_client *client) +{ + struct IR *ir = i2c_get_clientdata(client); + + /* unregister device */ + lirc_unregister_plugin(ir->l.minor); + i2c_detach_client(&ir->c); + + /* free memory */ + kfree(ir); + return 0; +} + +static int ir_probe(struct i2c_adapter *adap) +{ + /* The external IR receiver is at i2c address 0x34 (0x35 for + * reads). Future Hauppauge cards will have an internal + * receiver at 0x30 (0x31 for reads). In theory, both can be + * fitted, and Hauppauge suggest an external overrides an + * internal. + * + * That's why we probe 0x1a (~0x34) first. CB + * + * The i2c address for the Hauppauge PVR-150 card is 0xe2, + * so we need to probe 0x71 as well. */ + + static const int probe[] = { + 0x1a, /* Hauppauge IR external */ + 0x18, /* Hauppauge IR internal */ + 0x71, /* Hauppauge IR (PVR150) */ + 0x4b, /* PV951 IR */ + 0x64, /* Pixelview IR */ + 0x30, /* KNC ONE IR */ + 0x6b, /* Adaptec IR */ + -1}; + +#ifdef I2C_HW_B_CX2388x + static const int probe_cx88[] = { + 0x18, /* Leadtek Winfast PVR2000 */ + 0x71, /* Hauppauge HVR-IR */ + -1}; +#endif + + struct i2c_client c; + char buf; + int i, rc; + +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) +#endif + { + memset(&c, 0, sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != probe[i]; i++) { + c.addr = probe[i]; + rc = i2c_master_recv(&c, &buf, 1); + dprintk("probe 0x%02x @ %s: %s\n", + probe[i], adap->name, + (1 == rc) ? "yes" : "no"); + if (1 == rc) + ir_attach(adap, probe[i], 0, 0); + } + } + +#ifdef I2C_HW_B_CX2388x + /* Leadtek Winfast PVR2000 or Hauppauge HVR-1300 */ + else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2388x)) { + memset(&c, 0, sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != probe_cx88[i]; i++) { + c.addr = probe_cx88[i]; + rc = i2c_master_recv(&c, &buf, 1); + dprintk("probe 0x%02x @ %s: %s\n", + c.addr, adap->name, + (1 == rc) ? "yes" : "no"); + if (1 == rc) + ir_attach(adap, c.addr, 0, 0); + } + } +#endif + + /* Asus TV-Box and Creative/VisionTek BreakOut-Box (PCF8574) */ + else if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_RIVA)) { + /* addresses to probe; + leave 0x24 and 0x25 because SAA7113H possibly uses it + 0x21 and 0x22 possibly used by SAA7108E + Asus: 0x21 is a correct address (channel 1 of PCF8574) + Creative: 0x23 is a correct address (channel 3 of PCF8574) + VisionTek: 0x23 is a correct address (channel 3 of PCF8574) + */ + static const int pcf_probe[] = { 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, -1 }; + int ret1, ret2, ret3, ret4; + unsigned char bits = 0, flag = 0; + + memset(&c, 0, sizeof(c)); + c.adapter = adap; + for (i = 0; -1 != pcf_probe[i]; i++) { + c.addr = pcf_probe[i]; + ret1 = i2c_smbus_write_byte(&c, 0xff); + ret2 = i2c_smbus_read_byte(&c); + ret3 = i2c_smbus_write_byte(&c, 0x00); + ret4 = i2c_smbus_read_byte(&c); + + /* ensure that the writable bitmask works correctly */ + rc = 0; + if (ret1 != -1 && ret2 != -1 && + ret3 != -1 && ret4 != -1) { + /* in the Asus TV-Box: bit 1-0 */ + if (((ret2 & 0x03) == 0x03) && + ((ret4 & 0x03) == 0x00)) { + bits = (unsigned char) ~0x07; + flag = 0x04; + rc = 1; + } + /* in the Creative/VisionTek BreakOut-Box: bit 7-6 */ + if (((ret2 & 0xc0) == 0xc0) && + ((ret4 & 0xc0) == 0x00)) { + bits = (unsigned char) ~0xe0; + flag = 0x20; + rc = 1; + } + } + dprintk("probe 0x%02x @ %s: %s\n", + c.addr, adap->name, rc ? "yes" : "no"); + if (rc) + ir_attach(adap, pcf_probe[i], + bits|(flag<<8), 0); + } + } + + return 0; +} + +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg) +{ + /* nothing */ + return 0; +} + +/* ----------------------------------------------------------------------- */ +#ifdef MODULE + +int init_module(void) +{ + request_module("bttv"); + request_module("rivatv"); + request_module("ivtv"); + request_module("cx8800"); + i2c_add_driver(&driver); + return 0; +} + +void cleanup_module(void) +{ + i2c_del_driver(&driver); +} + +MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge and " + "Pixelview cards (i2c stack)"); +MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, " + "Ulrich Mueller, Stefan Jahn, Jerome Brock"); +MODULE_LICENSE("GPL"); + +module_param(minor, int, 0444); +MODULE_PARM_DESC(minor, "Preferred minor device number"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_streamzap/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_streamzap/Makefile @@ -0,0 +1,3 @@ + +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. +obj-$(CONFIG_LIRC_STREAMZAP) += lirc_streamzap.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_streamzap/lirc_streamzap.c +++ linux-2.6.28/ubuntu/lirc/lirc_streamzap/lirc_streamzap.c @@ -0,0 +1,912 @@ +/* $Id: lirc_streamzap.c,v 1.27 2008/01/13 11:13:50 lirc Exp $ */ + +/* + * Streamzap Remote Control driver + * + * Copyright (c) 2005 Christoph Bartelmus + * + * This driver was based on the work of Greg Wickham and Adrian + * Dewhurst. It was substantially rewritten to support correct signal + * gaps and now maintains a delay buffer, which is used to present + * consistent timing behaviour to user space applications. Without the + * delay buffer an ugly hack would be required in lircd, which can + * cause sluggish signal decoding in certain situations. + * + * This driver is based on the USB skeleton driver packaged with the + * kernel; copyright (C) 2001-2003 Greg Kroah-Hartman (greg@kroah.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0) +#error "*******************************************************" +#error "Sorry, this driver needs kernel version 2.4.0 or higher" +#error "*******************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#define DRIVER_VERSION "$Revision: 1.27 $" +#define DRIVER_NAME "lirc_streamzap" +#define DRIVER_DESC "Streamzap Remote Control driver" + +/* ------------------------------------------------------------------ */ + +static int debug; + +#define USB_STREAMZAP_VENDOR_ID 0x0e9c +#define USB_STREAMZAP_PRODUCT_ID 0x0000 + +/* Use our own dbg macro */ +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG DRIVER_NAME "[%d]: " \ + fmt "\n", ## args); \ + } while (0) + +/* + * table of devices that work with this driver + */ +static struct usb_device_id streamzap_table [] = { + { USB_DEVICE(USB_STREAMZAP_VENDOR_ID, USB_STREAMZAP_PRODUCT_ID) }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, streamzap_table); + +#define STREAMZAP_PULSE_MASK 0xf0 +#define STREAMZAP_SPACE_MASK 0x0f +#define STREAMZAP_RESOLUTION 256 + +/* number of samples buffered */ +#define STREAMZAP_BUFFER_SIZE 128 + +enum StreamzapDecoderState { + PulseSpace, + FullPulse, + FullSpace, + IgnorePulse +}; + +/* Structure to hold all of our device specific stuff */ +/* some remarks regarding locking: + theoretically this struct can be accessed from three threads: + + - from lirc_dev through set_use_inc/set_use_dec + + - from the USB layer throuh probe/disconnect/irq + + Careful placement of lirc_register_plugin/lirc_unregister_plugin + calls will prevent conflicts. lirc_dev makes sure that + set_use_inc/set_use_dec are not being executed and will not be + called after lirc_unregister_plugin returns. + + - by the timer callback + + The timer is only running when the device is connected and the + LIRC device is open. Making sure the timer is deleted by + set_use_dec will make conflicts impossible. +*/ +struct usb_streamzap { + + /* usb */ + /* save off the usb device pointer */ + struct usb_device *udev; + /* the interface for this device */ + struct usb_interface *interface; + + /* buffer & dma */ + unsigned char *buf_in; + dma_addr_t dma_in; + unsigned int buf_in_len; + + struct usb_endpoint_descriptor *endpoint; + + /* IRQ */ + struct urb *urb_in; + + /* lirc */ + struct lirc_plugin plugin; + struct lirc_buffer delay_buf; + struct lirc_buffer lirc_buf; + + /* timer used to support delay buffering */ + struct timer_list delay_timer; + int timer_running; + spinlock_t timer_lock; + + /* tracks whether we are currently receiving some signal */ + int idle; + /* sum of signal lengths received since signal start */ + unsigned long sum; + /* start time of signal; necessary for gap tracking */ + struct timeval signal_last; + struct timeval signal_start; + enum StreamzapDecoderState decoder_state; + struct timer_list flush_timer; + int flush; + int in_use; +}; + + +/* local function prototypes */ +#ifdef KERNEL_2_5 +static int streamzap_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void streamzap_disconnect(struct usb_interface *interface); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_streamzap_irq(struct urb *urb, struct pt_regs *regs); +#else +static void usb_streamzap_irq(struct urb *urb); +#endif +#else +static void *streamzap_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id); +static void streamzap_disconnect(struct usb_device *dev, void *ptr); +static void usb_streamzap_irq(struct urb *urb); +#endif +static int streamzap_use_inc(void *data); +static void streamzap_use_dec(void *data); +static int streamzap_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +static int streamzap_suspend(struct usb_interface *intf, pm_message_t message); +static int streamzap_resume(struct usb_interface *intf); +#endif + +/* usb specific object needed to register this driver with the usb subsystem */ + +static struct usb_driver streamzap_driver = { + LIRC_THIS_MODULE(.owner = THIS_MODULE) + .name = DRIVER_NAME, + .probe = streamzap_probe, + .disconnect = streamzap_disconnect, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) + .suspend = streamzap_suspend, + .resume = streamzap_resume, +#endif + .id_table = streamzap_table, +}; + +static void stop_timer(struct usb_streamzap *sz) +{ + unsigned long flags; + + spin_lock_irqsave(&sz->timer_lock, flags); + if (sz->timer_running) { + sz->timer_running = 0; + del_timer_sync(&sz->delay_timer); + } + spin_unlock_irqrestore(&sz->timer_lock, flags); +} + +static void flush_timeout(unsigned long arg) +{ + struct usb_streamzap *sz = (struct usb_streamzap *) arg; + + /* finally start accepting data */ + sz->flush = 0; +} +static void delay_timeout(unsigned long arg) +{ + unsigned long flags; + /* deliver data every 10 ms */ + static unsigned long timer_inc = + (10000/(1000000/HZ)) == 0 ? 1:(10000/(1000000/HZ)); + struct usb_streamzap *sz = (struct usb_streamzap *) arg; + lirc_t data; + + spin_lock_irqsave(&sz->timer_lock, flags); + + if (!lirc_buffer_empty(&sz->delay_buf) && + !lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data); + lirc_buffer_write_1(&sz->lirc_buf, (unsigned char *) &data); + } + if (!lirc_buffer_empty(&sz->delay_buf)) { + while (lirc_buffer_available(&sz->delay_buf) < + STREAMZAP_BUFFER_SIZE/2 && + !lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_read_1(&sz->delay_buf, + (unsigned char *) &data); + lirc_buffer_write_1(&sz->lirc_buf, + (unsigned char *) &data); + } + if (sz->timer_running) { + sz->delay_timer.expires += timer_inc; + add_timer(&sz->delay_timer); + } + } else { + sz->timer_running = 0; + } + + if (!lirc_buffer_empty(&sz->lirc_buf)) + wake_up(&sz->lirc_buf.wait_poll); + + spin_unlock_irqrestore(&sz->timer_lock, flags); +} + +static inline void flush_delay_buffer(struct usb_streamzap *sz) +{ + lirc_t data; + int empty = 1; + + while (!lirc_buffer_empty(&sz->delay_buf)) { + empty = 0; + lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data); + if (!lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_write_1(&sz->lirc_buf, + (unsigned char *) &data); + } else { + dprintk("buffer overflow\n", sz->plugin.minor); + } + } + if (!empty) + wake_up(&sz->lirc_buf.wait_poll); +} + +static inline void push(struct usb_streamzap *sz, unsigned char *data) +{ + unsigned long flags; + + spin_lock_irqsave(&sz->timer_lock, flags); + if (lirc_buffer_full(&sz->delay_buf)) { + lirc_t data; + + lirc_buffer_read_1(&sz->delay_buf, (unsigned char *) &data); + if (!lirc_buffer_full(&sz->lirc_buf)) { + lirc_buffer_write_1(&sz->lirc_buf, + (unsigned char *) &data); + } else { + dprintk("buffer overflow", sz->plugin.minor); + } + } + + lirc_buffer_write_1(&sz->delay_buf, data); + + if (!sz->timer_running) { + sz->delay_timer.expires = jiffies + HZ/10; + add_timer(&sz->delay_timer); + sz->timer_running = 1; + } + + spin_unlock_irqrestore(&sz->timer_lock, flags); +} + +static inline void push_full_pulse(struct usb_streamzap *sz, + unsigned char value) +{ + lirc_t pulse; + + if (sz->idle) { + long deltv; + lirc_t tmp; + + sz->signal_last = sz->signal_start; + do_gettimeofday(&sz->signal_start); + + deltv = sz->signal_start.tv_sec-sz->signal_last.tv_sec; + if (deltv > 15) { + tmp = PULSE_MASK; /* really long time */ + } else { + tmp = (lirc_t) (deltv*1000000+ + sz->signal_start.tv_usec - + sz->signal_last.tv_usec); + tmp -= sz->sum; + } + dprintk("ls %u", sz->plugin.minor, tmp); + push(sz, (char *)&tmp); + + sz->idle = 0; + sz->sum = 0; + } + + pulse = ((lirc_t) value)*STREAMZAP_RESOLUTION; + pulse += STREAMZAP_RESOLUTION/2; + sz->sum += pulse; + pulse |= PULSE_BIT; + + dprintk("p %u", sz->plugin.minor, pulse&PULSE_MASK); + push(sz, (char *)&pulse); +} + +static inline void push_half_pulse(struct usb_streamzap *sz, + unsigned char value) +{ + push_full_pulse(sz, (value & STREAMZAP_PULSE_MASK)>>4); +} + +static inline void push_full_space(struct usb_streamzap *sz, + unsigned char value) +{ + lirc_t space; + + space = ((lirc_t) value)*STREAMZAP_RESOLUTION; + space += STREAMZAP_RESOLUTION/2; + sz->sum += space; + dprintk("s %u", sz->plugin.minor, space); + push(sz, (char *)&space); +} + +static inline void push_half_space(struct usb_streamzap *sz, + unsigned char value) +{ + push_full_space(sz, value & STREAMZAP_SPACE_MASK); +} + +/* + * usb_streamzap_irq - IRQ handler + * + * This procedure is invoked on reception of data from + * the usb remote. + */ +#if defined(KERNEL_2_5) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static void usb_streamzap_irq(struct urb *urb, struct pt_regs *regs) +#else +static void usb_streamzap_irq(struct urb *urb) +#endif +{ + struct usb_streamzap *sz; + int len; + unsigned int i = 0; + + if (!urb) + return; + + sz = urb->context; + len = urb->actual_length; + + switch (urb->status) { + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + /* sz might already be invalid at this point */ + dprintk("urb status: %d", -1, urb->status); + return; + default: + break; + } + + dprintk("received %d", sz->plugin.minor, urb->actual_length); + if (!sz->flush) { + for (i = 0; i < urb->actual_length; i++) { + dprintk("%d: %x", sz->plugin.minor, + i, (unsigned char) sz->buf_in[i]); + switch (sz->decoder_state) { + case PulseSpace: + if ((sz->buf_in[i]&STREAMZAP_PULSE_MASK) == + STREAMZAP_PULSE_MASK) { + sz->decoder_state = FullPulse; + continue; + } else if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) + == STREAMZAP_SPACE_MASK) { + push_half_pulse(sz, sz->buf_in[i]); + sz->decoder_state = FullSpace; + continue; + } else { + push_half_pulse(sz, sz->buf_in[i]); + push_half_space(sz, sz->buf_in[i]); + } + break; + case FullPulse: + push_full_pulse(sz, sz->buf_in[i]); + sz->decoder_state = IgnorePulse; + break; + case FullSpace: + if (sz->buf_in[i] == 0xff) { + sz->idle = 1; + stop_timer(sz); + flush_delay_buffer(sz); + } else + push_full_space(sz, sz->buf_in[i]); + sz->decoder_state = PulseSpace; + break; + case IgnorePulse: + if ((sz->buf_in[i]&STREAMZAP_SPACE_MASK) == + STREAMZAP_SPACE_MASK) { + sz->decoder_state = FullSpace; + continue; + } + push_half_space(sz, sz->buf_in[i]); + sz->decoder_state = PulseSpace; + break; + } + } + } + +#ifdef KERNEL_2_5 + /* resubmit only for 2.6 */ + usb_submit_urb(urb, GFP_ATOMIC); +#endif + + return; +} + +/** + * streamzap_probe + * + * Called by usb-core to associated with a candidate device + * On any failure the return value is the ERROR + * On success return 0 + */ +#ifdef KERNEL_2_5 +static int streamzap_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(interface); + struct usb_host_interface *iface_host; +#else +static void *streamzap_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_interface *interface = &udev->actconfig->interface[ifnum]; + struct usb_interface_descriptor *iface_host; +#endif + int retval = -ENOMEM; + struct usb_streamzap *sz = NULL; + char buf[63], name[128] = ""; + + /*************************************************** + * Allocate space for device driver specific data + */ + sz = kmalloc(sizeof(struct usb_streamzap), GFP_KERNEL); + if (sz == NULL) + goto error; + + memset(sz, 0, sizeof(*sz)); + sz->udev = udev; + sz->interface = interface; + + /*************************************************** + * Check to ensure endpoint information matches requirements + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 5) + iface_host = &interface->altsetting[interface->act_altsetting]; +#else + iface_host = interface->cur_altsetting; +#endif + +#ifdef KERNEL_2_5 + if (iface_host->desc.bNumEndpoints != 1) { +#else + if (iface_host->bNumEndpoints != 1) { +#endif +#ifdef KERNEL_2_5 + err("%s: Unexpected desc.bNumEndpoints (%d)", __FUNCTION__, + iface_host->desc.bNumEndpoints); +#else + err("%s: Unexpected desc.bNumEndpoints (%d)", __FUNCTION__, + iface_host->bNumEndpoints); +#endif + retval = -ENODEV; + goto error; + } + +#ifdef KERNEL_2_5 + sz->endpoint = &(iface_host->endpoint[0].desc); +#else + sz->endpoint = &(iface_host->endpoint[0]); +#endif + if ((sz->endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) + != USB_DIR_IN) { + err("%s: endpoint doesn't match input device 02%02x", + __FUNCTION__, sz->endpoint->bEndpointAddress); + retval = -ENODEV; + goto error; + } + + if ((sz->endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + != USB_ENDPOINT_XFER_INT) { + err("%s: endpoint attributes don't match xfer 02%02x", + __FUNCTION__, sz->endpoint->bmAttributes); + retval = -ENODEV; + goto error; + } + + if (sz->endpoint->wMaxPacketSize == 0) { + err("%s: endpoint message size==0? ", __FUNCTION__); + retval = -ENODEV; + goto error; + } + + /*************************************************** + * Allocate the USB buffer and IRQ URB + */ + + sz->buf_in_len = sz->endpoint->wMaxPacketSize; +#ifdef KERNEL_2_5 + sz->buf_in = usb_buffer_alloc(sz->udev, sz->buf_in_len, + GFP_ATOMIC, &sz->dma_in); +#else + sz->buf_in = kmalloc(sz->buf_in_len, GFP_KERNEL); +#endif + if (sz->buf_in == NULL) + goto error; + +#ifdef KERNEL_2_5 + sz->urb_in = usb_alloc_urb(0, GFP_KERNEL); +#else + + sz->urb_in = usb_alloc_urb(0); +#endif + if (sz->urb_in == NULL) + goto error; + + /*************************************************** + * Connect this device to the LIRC sub-system + */ + + if (lirc_buffer_init(&sz->lirc_buf, sizeof(lirc_t), + STREAMZAP_BUFFER_SIZE)) + goto error; + + if (lirc_buffer_init(&sz->delay_buf, sizeof(lirc_t), + STREAMZAP_BUFFER_SIZE)) { + lirc_buffer_free(&sz->lirc_buf); + goto error; + } + + /*************************************************** + * As required memory is allocated now populate the plugin structure + */ + + memset(&sz->plugin, 0, sizeof(sz->plugin)); + + strcpy(sz->plugin.name, DRIVER_NAME); + sz->plugin.minor = -1; + sz->plugin.sample_rate = 0; + sz->plugin.code_length = sizeof(lirc_t) * 8; + sz->plugin.features = LIRC_CAN_REC_MODE2|LIRC_CAN_GET_REC_RESOLUTION; + sz->plugin.data = sz; + sz->plugin.rbuf = &sz->lirc_buf; + sz->plugin.set_use_inc = &streamzap_use_inc; + sz->plugin.set_use_dec = &streamzap_use_dec; + sz->plugin.ioctl = streamzap_ioctl; +#ifdef LIRC_HAVE_SYSFS + sz->plugin.dev = &udev->dev; +#endif + sz->plugin.owner = THIS_MODULE; + + sz->idle = 1; + sz->decoder_state = PulseSpace; + init_timer(&sz->delay_timer); + sz->delay_timer.function = delay_timeout; + sz->delay_timer.data = (unsigned long) sz; + sz->timer_running = 0; + spin_lock_init(&sz->timer_lock); + + init_timer(&sz->flush_timer); + sz->flush_timer.function = flush_timeout; + sz->flush_timer.data = (unsigned long) sz; + /*************************************************** + * Complete final initialisations + */ + + usb_fill_int_urb(sz->urb_in, udev, + usb_rcvintpipe(udev, sz->endpoint->bEndpointAddress), + sz->buf_in, sz->buf_in_len, usb_streamzap_irq, sz, + sz->endpoint->bInterval); + + if (udev->descriptor.iManufacturer + && usb_string(udev, udev->descriptor.iManufacturer, buf, 63) > 0) + strncpy(name, buf, 128); + + if (udev->descriptor.iProduct + && usb_string(udev, udev->descriptor.iProduct, buf, 63) > 0) + snprintf(name, 128, "%s %s", name, buf); + + printk(KERN_INFO DRIVER_NAME "[%d]: %s on usb%d:%d attached\n", + sz->plugin.minor, name, + udev->bus->busnum, sz->udev->devnum); + +#ifdef KERNEL_2_5 + usb_set_intfdata(interface, sz); +#endif + + if (lirc_register_plugin(&sz->plugin) < 0) { + lirc_buffer_free(&sz->delay_buf); + lirc_buffer_free(&sz->lirc_buf); + goto error; + } + +#ifdef KERNEL_2_5 + return 0; +#else + return sz; +#endif + +error: + + /*************************************************** + * Premise is that a 'goto error' can be invoked from inside the + * probe function and all necessary cleanup actions will be taken + * including freeing any necessary memory blocks + */ + + if (retval == -ENOMEM) + err("Out of memory"); + + if (sz) { + + if (sz->urb_in) + usb_free_urb(sz->urb_in); + + if (sz->buf_in) { +#ifdef KERNEL_2_5 + usb_buffer_free(udev, sz->buf_in_len, + sz->buf_in, sz->dma_in); +#else + kfree(sz->buf_in); +#endif + } + kfree(sz); + } + +#ifdef KERNEL_2_5 + return retval; +#else + return NULL; +#endif +} + +static int streamzap_use_inc(void *data) +{ + struct usb_streamzap *sz = data; + + if (!sz) { + dprintk("%s called with no context", -1, __FUNCTION__); + return -EINVAL; + } + dprintk("set use inc", sz->plugin.minor); + + MOD_INC_USE_COUNT; + + while (!lirc_buffer_empty(&sz->lirc_buf)) + lirc_buffer_remove_1(&sz->lirc_buf); + while (!lirc_buffer_empty(&sz->delay_buf)) + lirc_buffer_remove_1(&sz->delay_buf); + + sz->flush_timer.expires = jiffies + HZ; + sz->flush = 1; + add_timer(&sz->flush_timer); + + sz->urb_in->dev = sz->udev; +#ifdef KERNEL_2_5 + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { +#else + if (usb_submit_urb(sz->urb_in)) { +#endif + dprintk("open result = -EIO error submitting urb", + sz->plugin.minor); + MOD_DEC_USE_COUNT; + return -EIO; + } + sz->in_use++; + + return 0; +} + +static void streamzap_use_dec(void *data) +{ + struct usb_streamzap *sz = data; + + if (!sz) { + dprintk("%s called with no context", -1, __FUNCTION__); + return; + } + dprintk("set use dec", sz->plugin.minor); + + if (sz->flush) { + sz->flush = 0; + del_timer_sync(&sz->flush_timer); + } + + stop_timer(sz); + + usb_kill_urb(sz->urb_in); + + MOD_DEC_USE_COUNT; + sz->in_use--; +} + +static int streamzap_ioctl(struct inode *node, struct file *filep, + unsigned int cmd, unsigned long arg) +{ + int result; + + switch (cmd) { + case LIRC_GET_REC_RESOLUTION: + result = put_user(STREAMZAP_RESOLUTION, (unsigned long *) arg); + if (result) + return(result); + break; + default: + return -ENOIOCTLCMD; + } + return 0; +} + +/** + * streamzap_disconnect + * + * Called by the usb core when the device is removed from the system. + * + * This routine guarantees that the driver will not submit any more urbs + * by clearing dev->udev. It is also supposed to terminate any currently + * active urbs. Unfortunately, usb_bulk_msg(), used in streamzap_read(), + * does not provide any way to do this. + */ +#ifdef KERNEL_2_5 +static void streamzap_disconnect(struct usb_interface *interface) +#else +static void streamzap_disconnect(struct usb_device *dev, void *ptr) +#endif +{ + struct usb_streamzap *sz; + int errnum; + int minor; + +#ifdef KERNEL_2_5 + sz = usb_get_intfdata(interface); +#else + sz = ptr; +#endif + + /* + * unregister from the LIRC sub-system + */ + + errnum = lirc_unregister_plugin(sz->plugin.minor); + if (errnum != 0) + dprintk("error in lirc_unregister: (returned %d)", + sz->plugin.minor, errnum); + + lirc_buffer_free(&sz->delay_buf); + lirc_buffer_free(&sz->lirc_buf); + + /* + * unregister from the USB sub-system + */ + + usb_free_urb(sz->urb_in); + +#ifdef KERNEL_2_5 + usb_buffer_free(sz->udev, sz->buf_in_len, sz->buf_in, sz->dma_in); +#else + kfree(sz->buf_in); +#endif + + minor = sz->plugin.minor; + kfree(sz); + + printk(KERN_INFO DRIVER_NAME "[%d]: disconnected\n", minor); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +static int streamzap_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct usb_streamzap *sz = usb_get_intfdata(intf); + + printk(DRIVER_NAME "[%d]: suspend\n", sz->plugin.minor); + if (sz->in_use) { + if (sz->flush) { + sz->flush = 0; + del_timer_sync(&sz->flush_timer); + } + + stop_timer(sz); + + usb_kill_urb(sz->urb_in); + } + return 0; +} + +static int streamzap_resume(struct usb_interface *intf) +{ + struct usb_streamzap *sz = usb_get_intfdata(intf); + + while (!lirc_buffer_empty(&sz->lirc_buf)) + lirc_buffer_remove_1(&sz->lirc_buf); + while (!lirc_buffer_empty(&sz->delay_buf)) + lirc_buffer_remove_1(&sz->delay_buf); + + if (sz->in_use) { + sz->flush_timer.expires = jiffies + HZ; + sz->flush = 1; + add_timer(&sz->flush_timer); + + sz->urb_in->dev = sz->udev; +#ifdef KERNEL_2_5 + if (usb_submit_urb(sz->urb_in, GFP_ATOMIC)) { +#else + if (usb_submit_urb(sz->urb_in)) { +#endif + dprintk("open result = -EIO error submitting urb", + sz->plugin.minor); + MOD_DEC_USE_COUNT; + return -EIO; + } + } + return 0; +} +#endif + +#ifdef MODULE + +/** + * usb_streamzap_init + */ +static int __init usb_streamzap_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + + result = usb_register(&streamzap_driver); + + if (result) { + err("usb_register failed. Error number %d", + result); + return result; + } + + printk(KERN_INFO DRIVER_NAME " " DRIVER_VERSION " registered\n"); + return 0; +} + +/** + * usb_streamzap_exit + */ +static void __exit usb_streamzap_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&streamzap_driver); +} + + +module_init(usb_streamzap_init); +module_exit(usb_streamzap_exit); + +MODULE_AUTHOR("Christoph Bartelmus, Greg Wickham, Adrian Dewhurst"); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/commandir.c +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/commandir.c @@ -0,0 +1,1521 @@ + +/* + * + * Hardware Driver for COMMANDIR USB Transceiver + * 2005-2007 InnovationOne - Matt Bodkin, Evelyn Yeung + * + * Version 1.4.2 + * For 2.4.* or 2.6.* kernel versions + * Based on the USB Skeleton driver, versions 0.7 and 2.0 + * + */ + +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include "commandir.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +#include +#include +#include +#include +#include +#include +#include +#else +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#endif + +#define DRIVER_VERSION "v1.1.2" +#define DRIVER_AUTHOR "Evelyn Yeung, InnovationOne" +#define DRIVER_DESC "CommandIR USB Transceiver Driver" + +#define USB_CMDIR_VENDOR_ID 0x10c4 +#define USB_CMDIR_PRODUCT_ID 0x0003 +#define USB_CMDIR_MINOR_BASE 192 + +/* table of devices that work with this driver */ +static struct usb_device_id cmdir_table [] = +{ + { USB_DEVICE(USB_CMDIR_VENDOR_ID, USB_CMDIR_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, cmdir_table); + +static int cmdir_open(struct inode *inode, struct file *file); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void *cmdir_probe(struct usb_device *dev, unsigned int ifnum, + const struct usb_device_id *id); +static int cmdir_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); +static void cmdir_disconnect(struct usb_device *dev, void *ptr); +#else +static int cmdir_probe(struct usb_interface *interface, + const struct usb_device_id *id); +static void cmdir_disconnect(struct usb_interface *interface); +#endif +static int cmdir_release(struct inode *inode, struct file *file); +static int cmdir_check(int device_num); +static void init_cmdir_var(int device_num); +static void reset_cmdir(int device_num); +static void update_cmdir_string(int device_num); +static void print_cmdir(int device_num); +static ssize_t cmdir_file_read(struct file *file, char *buffer, + size_t count, loff_t *ppos); +ssize_t cmdir_read(unsigned char *buffer, size_t count); +static ssize_t cmdir_file_write(struct file *file, const char *buffer, + size_t count, loff_t *ppos); +int cmdir_write(unsigned char *buffer, int count, void *callback_fct, int u); +int write_core(unsigned char *buffer, int count, + void *callback_fct, int device_num); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void cmdir_write_bulk_callback(struct urb *urb); +#else +static void cmdir_write_bulk_callback(struct urb *urb, struct pt_regs *regs); +#endif +int set_tx_channels(unsigned int next_tx); + +int add_cmdir_queue(unsigned char *buffer, int count, + void *callback_vct, int usecdelay); +int cmdir_write_queue(unsigned char *buffer, int count, void *callback_vct); +int send_queue(void); +int wait_to_tx(int usecs); + +/* circular packet queue */ +unsigned char ourbuffers[QUEUELENGTH][64]; +int waitusecs[QUEUELENGTH]; +int ourbufferlengths[QUEUELENGTH]; +int nexttosend; +int nexttofill; +int send_status = SEND_IDLE; +int last_tx_sec; +int last_tx_usec; + +static int curTXFill; +struct timeval tp; + +int debug_commandir; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + +/* Structure to hold all of our device specific stuff */ +struct usb_skel { + struct usb_device *udev; /* save off the usb device pointer */ + struct usb_interface *interface; /* the interface for this device */ + devfs_handle_t devfs; /* devfs device node */ + unsigned char minor; /* the starting minor number */ + unsigned char num_ports; /* the number of ports this device has */ + char num_interrupt_in; /* number of interrupt in endpoints */ + char num_bulk_in; /* number of bulk in endpoints */ + char num_bulk_out; /* number of bulk out endpoints */ + + unsigned char *bulk_in_buffer; /* the buffer to receive data */ + int bulk_in_size; /* the size of the receive buffer */ + __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ + + unsigned char *bulk_out_buffer; /* the buffer to send data */ + int bulk_out_size; /* the size of the send buffer */ + struct urb *write_urb; /* the urb used to send data */ + __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ + + struct tq_struct tqueue; /* task queue for line discipline waking up */ + int open_count; /* number of times this port has been opened */ + struct semaphore sem; /* locks this structure */ +}; + +extern devfs_handle_t usb_devfs_handle; /* the global usb devfs handle */ + +/* array of pointers to our devices that are currently connected */ +static struct usb_skel *minor_table[MAX_DEVICES]; +/* lock to protect the minor_table structure */ +static DECLARE_MUTEX(minor_table_mutex); + +static struct file_operations cmdir_fops = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .owner = THIS_MODULE, +#endif /* kernel < 2.6.16 */ +#endif /* kernel >= 2.6.0 */ + .read = cmdir_file_read, + .write = cmdir_file_write, + .ioctl = cmdir_ioctl, + .open = cmdir_open, + .release = cmdir_release, +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver cmdir_driver = { + .name = "commandir", + .probe = cmdir_probe, + .disconnect = cmdir_disconnect, + .fops = &cmdir_fops, + .minor = USB_CMDIR_MINOR_BASE, + .id_table = cmdir_table, +}; + +#else /* kernel >= 2.6 */ + +/* Structure to hold all of our device specific stuff */ +struct usb_skel { + struct usb_device *udev; /* the usb device for this device */ + struct usb_interface *interface; /* the interface for this device */ + unsigned char *bulk_in_buffer; /* the buffer to receive data */ + size_t bulk_in_size; /* the size of the receive buffer */ + __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ + __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ + struct kref kref; +}; +#define to_skel_dev(d) container_of(d, struct usb_skel, kref) + +static struct file_operations cmdir_fops = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .owner = THIS_MODULE, +#endif /* kernel < 2.6.16 */ +#endif /* kernel >= 2.6.0 */ + .read = cmdir_file_read, + .write = cmdir_file_write, + .open = cmdir_open, + .release = cmdir_release, +}; + +/* usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with devfs and the driver core */ +static struct usb_class_driver cmdir_class = { + .name = "usb/commandir%d", + .fops = &cmdir_fops, + /* .mode = S_IFCHR | S_IRUSR | S_IWUSR | + * S_IRGRP | S_IWGRP | S_IROTH, */ + .minor_base = USB_CMDIR_MINOR_BASE, +}; + +static struct usb_driver cmdir_driver = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + .owner = THIS_MODULE, +#endif /* kernel < 2.6.16 */ +#endif /* kernel >= 2.6.0 */ + .name = "commandir", + .probe = cmdir_probe, + .disconnect = cmdir_disconnect, + .id_table = cmdir_table, +}; + +#endif /* kernel < 2.6.0 */ + +static int lcd_device; +static int rx_device; +static int def_device; + +#define DEFAULT_TRANSMITTERS 0x0F +static unsigned int transmitters = DEFAULT_TRANSMITTERS; +static unsigned int next_transmitters = DEFAULT_TRANSMITTERS; + +#define CMDIR_VAR_LEN 68 +static char cmdir_var[] = +"COMMANDIRx:\n TX Enabled: 1, 2, 3, 4\n RX: commandirx\n LCD: commandirx"; + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static inline void cmdir_delete(struct usb_skel *dev) +{ + minor_table[dev->minor] = NULL; + if (dev->bulk_in_buffer != NULL) + kfree(dev->bulk_in_buffer); + if (dev->bulk_out_buffer != NULL) + kfree(dev->bulk_out_buffer); + if (dev->write_urb != NULL) + usb_free_urb(dev->write_urb); + kfree(dev); +} +#else +static void cmdir_delete(struct kref *kref) +{ + struct usb_skel *dev = to_skel_dev(kref); + + usb_put_dev(dev->udev); + kfree(dev->bulk_in_buffer); + kfree(dev); +} +#endif + +static int __init usb_cmdir_init(void) +{ + int result; + + /* register this driver with the USB subsystem */ + result = usb_register(&cmdir_driver); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + if (result < 0) { + err("usb_register failed for the "__FILE__ + " driver. Error number %d", result); + return -1; + } + + info(DRIVER_DESC " " DRIVER_VERSION); + + return 0; +#else + if (result) + err("usb_register failed. Error number %d", result); + + return result; +#endif +} + +static int cmdir_open(struct inode *inode, struct file *file) +{ + struct usb_skel *dev; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) + struct usb_interface *interface; +#endif + int subminor; + int retval = 0; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + subminor = MINOR(inode->i_rdev) - USB_CMDIR_MINOR_BASE; + if ((subminor < 0) || (subminor >= MAX_DEVICES)) + return -ENODEV; + MOD_INC_USE_COUNT; + + /* lock our minor table and get our local data for this minor */ + down(&minor_table_mutex); + dev = minor_table[subminor]; + if (dev == NULL) { + up(&minor_table_mutex); + MOD_DEC_USE_COUNT; + return -ENODEV; + } + + down(&dev->sem); /* lock this device */ + up(&minor_table_mutex); /* unlock the minor table */ + ++dev->open_count; /* increment our usage count for the driver */ + file->private_data = dev; /* save object in file's private structure */ + up(&dev->sem); /* unlock this device */ + + return retval; +#else + subminor = iminor(inode); + interface = usb_find_interface(&cmdir_driver, subminor); + if (!interface) { + err("%s - error, can't find device for minor %d", + __FUNCTION__, subminor); + retval = -ENODEV; + goto exit; + } + + dev = usb_get_intfdata(interface); + if (!dev) { + retval = -ENODEV; + goto exit; + } + + kref_get(&dev->kref); /* increment our usage count for the device */ + file->private_data = dev; /* save object in file's private structure */ + +exit: + return retval; +#endif +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void *cmdir_probe(struct usb_device *udev, unsigned int ifnum, + const struct usb_device_id *id) +{ + struct usb_skel *dev = NULL; + struct usb_interface *interface; + struct usb_interface_descriptor *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int minor; + int buffer_size; + int i; + char name[10]; + + /* See if the device offered us matches what we can accept */ + if ((udev->descriptor.idVendor != USB_CMDIR_VENDOR_ID) || + (udev->descriptor.idProduct != USB_CMDIR_PRODUCT_ID)) + return NULL; + + /* select a "subminor" number (part of a minor number) */ + down(&minor_table_mutex); + for (minor = 0; minor < MAX_DEVICES; ++minor) { + if (minor_table[minor] == NULL) + break; + } + if (minor >= MAX_DEVICES) { + info("Too many devices plugged in, cannot handle this device."); + goto exit; + } + + /* allocate memory for our device state and intialize it */ + dev = kmalloc(sizeof(struct usb_skel), GFP_KERNEL); + if (dev == NULL) { + err("Out of memory"); + goto exit; + } + memset(dev, 0x00, sizeof(*dev)); + minor_table[minor] = dev; + + interface = &udev->actconfig->interface[ifnum]; + + init_MUTEX(&dev->sem); + dev->udev = udev; + dev->interface = interface; + dev->minor = minor; + + /* set up and check the endpoint information */ + iface_desc = &interface->altsetting[0]; + for (i = 0; i < iface_desc->bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i]; + + if ((endpoint->bEndpointAddress & 0x80) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk in endpoint */ + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { + err("Couldn't allocate bulk_in_buffer"); + goto error; + } + } + + if (((endpoint->bEndpointAddress & 0x80) == 0x00) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk out endpoint */ + dev->write_urb = usb_alloc_urb(0); + if (!dev->write_urb) { + err("No free urbs available"); + goto error; + } + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_out_size = buffer_size; + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!dev->bulk_out_buffer) { + err("Couldn't allocate bulk_out_buffer"); + goto error; + } + FILL_BULK_URB(dev->write_urb, udev, + usb_sndbulkpipe(udev, + endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + cmdir_write_bulk_callback, dev); + } + } + + /* initialize the devfs node for this device and register it */ + sprintf(name, "commandir%d", dev->minor); + + dev->devfs = devfs_register(usb_devfs_handle, name, + DEVFS_FL_DEFAULT, USB_MAJOR, + USB_CMDIR_MINOR_BASE + dev->minor, + S_IFCHR | S_IRUSR | S_IWUSR | + S_IRGRP | S_IWGRP | S_IROTH, + &cmdir_fops, NULL); + + /* let the user know what node this device is now attached to */ + info("CommandIR USB device now attached to commandir%d", dev->minor); + + /* should reset just the one that was plugged in */ + reset_cmdir(minor); + + goto exit; + +error: + cmdir_delete(dev); + dev = NULL; + +exit: + up(&minor_table_mutex); + return dev; +} +#else +static int cmdir_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_skel *dev = NULL; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t buffer_size; + + int i; + int retval = -ENOMEM; + int minor; + + /* allocate memory for our device state and initialize it */ + dev = kmalloc(sizeof(*dev), GFP_KERNEL); + if (dev == NULL) { + err("Out of memory"); + goto error; + } + memset(dev, 0x00, sizeof(*dev)); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_init(&dev->kref, cmdir_delete); +#else + kref_init(&dev->kref); +#endif + dev->udev = usb_get_dev(interface_to_usbdev(interface)); + dev->interface = interface; + + /* set up the endpoint information */ + /* use only the first bulk-in and bulk-out endpoints */ + iface_desc = interface->cur_altsetting; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + + if (!dev->bulk_in_endpointAddr && + (endpoint->bEndpointAddress & USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK)) { + /* we found a bulk in endpoint */ + buffer_size = endpoint->wMaxPacketSize; + dev->bulk_in_size = buffer_size; + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); + if (!dev->bulk_in_buffer) { + err("Could not allocate bulk_in_buffer"); + goto error; + } + } + + if (!dev->bulk_out_endpointAddr && + !(endpoint->bEndpointAddress & USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + == USB_ENDPOINT_XFER_BULK)) { + /* we found a bulk out endpoint */ + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; + } + } + if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { + err("Could not find both bulk-in and bulk-out endpoints"); + goto error; + } + + /* save our data pointer in this interface device */ + usb_set_intfdata(interface, dev); + + /* we can register the device now, as it is ready */ + retval = usb_register_dev(interface, &cmdir_class); + if (retval) { + /* something prevented us from registering this driver */ + err("Not able to get a minor for this device."); + usb_set_intfdata(interface, NULL); + goto error; + } + + /* check whether minor already includes base */ + minor = interface->minor; + if (minor >= USB_CMDIR_MINOR_BASE) + minor = minor-USB_CMDIR_MINOR_BASE; + + /* let the user know what node this device is now attached to */ + info("CommandIR USB device now attached to commandir%d", minor); + + reset_cmdir(minor); + + return 0; + +error: + if (dev) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_put(&dev->kref); +#else + kref_put(&dev->kref, cmdir_delete); +#endif + return retval; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static int cmdir_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct usb_skel *dev; + + dev = (struct usb_skel *)file->private_data; + + /* lock this object */ + down(&dev->sem); + + /* verify that the device wasn't unplugged */ + if (dev->udev == NULL) { + up(&dev->sem); + return -ENODEV; + } + + /* unlock the device */ + up(&dev->sem); + + /* return that we did not understand this ioctl call */ + return -ENOTTY; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void cmdir_disconnect(struct usb_device *udev, void *ptr) +{ + struct usb_skel *dev; + int minor; + + dev = (struct usb_skel *)ptr; + + down(&minor_table_mutex); + down(&dev->sem); + + minor = dev->minor; + + /* remove our devfs node */ + devfs_unregister(dev->devfs); + + /* if the device is not opened, then we clean up right now */ + if (!dev->open_count) { + up(&dev->sem); + cmdir_delete(dev); + } else { + dev->udev = NULL; + up(&dev->sem); + } + + info("CommandIR #%d now disconnected", minor); + up(&minor_table_mutex); + + /* check if default RX device still exists */ + if (minor == rx_device) { + /* decrement until find next valid device */ + while (rx_device > 0) { + rx_device--; + if (cmdir_check(rx_device) == 0) break; + } + if (minor > 0) + info("Active Receiver is on CommandIR #%d", rx_device); + } + +} +#else +static void cmdir_disconnect(struct usb_interface *interface) +{ + struct usb_skel *dev; + int minor = interface->minor; + + /* prevent cmdir_open() from racing cmdir_disconnect() */ + lock_kernel(); + + dev = usb_get_intfdata(interface); + usb_set_intfdata(interface, NULL); + + /* give back our minor */ + usb_deregister_dev(interface, &cmdir_class); + + unlock_kernel(); + + /* decrement our usage count */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_put(&dev->kref); +#else + kref_put(&dev->kref, cmdir_delete); +#endif + + /* check whether minor already includes base */ + if (minor >= USB_CMDIR_MINOR_BASE) + minor = minor-USB_CMDIR_MINOR_BASE; + + info("CommandIR #%d now disconnected", minor); + + /* check if default RX device still exists */ + if (minor == rx_device) { + /* decrement until find next valid device */ + while (rx_device > 0) { + rx_device--; + if (cmdir_check(rx_device) == 0) + break; + } + if (minor > 0) + info("Active Receiver is on CommandIR #%d", rx_device); + } +} +#endif + +static int cmdir_release(struct inode *inode, struct file *file) +{ + struct usb_skel *dev; + int retval = 0; + + dev = (struct usb_skel *)file->private_data; + if (dev == NULL) + /*dbg(" - object is NULL");*/ + return -ENODEV; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + + /* lock our minor table */ + down(&minor_table_mutex); + + /* lock our device */ + down(&dev->sem); + + if (dev->open_count <= 0) { + /*dbg(" - device not opened");*/ + retval = -ENODEV; + goto exit_not_opened; + } + + if (dev->udev == NULL) { + /* the device was unplugged before the file was released */ + /*dbg(" - device unplugged before file released");*/ + up(&dev->sem); + cmdir_delete(dev); + up(&minor_table_mutex); + MOD_DEC_USE_COUNT; + return 0; + } + + /* decrement our usage count for the device */ + --dev->open_count; + if (dev->open_count <= 0) { + /* shutdown any bulk writes that might be going on */ + usb_unlink_urb(dev->write_urb); + dev->open_count = 0; + } + + /* decrement our usage count for the module */ + MOD_DEC_USE_COUNT; + +exit_not_opened: + up(&dev->sem); + up(&minor_table_mutex); + + return retval; + +#else + /* decrement the count on our device */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9) + kref_put(&dev->kref); +#else + kref_put(&dev->kref, cmdir_delete); +#endif + return retval; +#endif +} + +static void __exit usb_cmdir_exit(void) +{ + /* deregister this driver with the USB subsystem */ + usb_deregister(&cmdir_driver); + +} + +static int cmdir_check(int device_num) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + if (minor_table[device_num] == NULL) + return -ENODEV; + return 0; +#else + struct usb_interface *interface; + + interface = usb_find_interface(&cmdir_driver, + USB_CMDIR_MINOR_BASE+device_num); + if (!interface) { + /* also check without adding base, for devfs */ + interface = usb_find_interface(&cmdir_driver, rx_device); + if (!interface) + return -ENODEV; + } + return 0; +#endif +} + +static void init_cmdir_var(int device_num) +{ + int i; + unsigned int multiplier = 1; + + for (i = 0; i < device_num; i++) + multiplier = multiplier*0x10; + transmitters |= multiplier * 0x0F; + next_transmitters = transmitters; + info("commandir%d reset", device_num); + return; +} + +static void reset_cmdir(int device_num) +{ + unsigned char ctrl_buffer[MCU_CTRL_SIZE]; + int retval; + int i; + + ctrl_buffer[0] = RESET_HEADER; + for (i = 1; i < MCU_CTRL_SIZE; i++) + ctrl_buffer[i] = 'j'; + retval = write_core(ctrl_buffer, MCU_CTRL_SIZE, NULL, device_num); + + init_cmdir_var(device_num); + print_cmdir(device_num); + + return; +} + +static void update_cmdir_string(int device_num) +{ + int next_comma = 0; + int next_pos = 25; + unsigned int multiplier; + int i; + + /* cmdir_var[] = "COMMANDIRx:\n" + * " TX Enabled: 1, 2, 3, 4\n" + * " RX: commandirx\n" + * " LCD: commandirx\n" */ + + cmdir_var[9] = ASCII0+device_num; + cmdir_var[50] = ASCII0+rx_device; + cmdir_var[67] = ASCII0+lcd_device; + + for (i = 25; i < 35; i++) + cmdir_var[i] = ' '; + + multiplier = 1; + for (i = 0; i < device_num; i++) + multiplier = multiplier*0x10; + + if (transmitters & (multiplier*0x01)) { + cmdir_var[next_pos] = '1'; + next_pos += 3; + next_comma++; + } + if (transmitters & (multiplier*0x02)) { + cmdir_var[next_pos] = '2'; + if (next_comma > 0) + cmdir_var[next_pos-2] = ','; + next_pos += 3; + next_comma++; + } + if (transmitters & (multiplier*0x04)) { + cmdir_var[next_pos] = '3'; + if (next_comma > 0) + cmdir_var[next_pos-2] = ','; + next_pos += 3; + next_comma++; + } + if (transmitters & (multiplier*0x08)) { + cmdir_var[next_pos] = '4'; + if (next_comma > 0) + cmdir_var[next_pos-2] = ','; + next_pos += 3; + next_comma++; + } + return; +} + +static void print_cmdir(int device_num) +{ + update_cmdir_string(device_num); + info("%s", cmdir_var); + return; +} + +static ssize_t cmdir_file_read(struct file *file, char *buffer, + size_t count, loff_t *ppos) +{ + int retval = 0; + int minor = 0; + struct usb_skel *dev; + + dev = (struct usb_skel *)file->private_data; +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + minor = dev->minor; +#else + minor = dev->interface->minor; + if (minor >= USB_CMDIR_MINOR_BASE) + minor = minor - USB_CMDIR_MINOR_BASE; +#endif + + if (((int)*ppos) == 0) { + update_cmdir_string(minor); + if (copy_to_user(buffer, cmdir_var, CMDIR_VAR_LEN)) + retval = -EFAULT; + else + retval = CMDIR_VAR_LEN; + return retval; + } else + return 0; +} + +/* Read data from CommandIR */ +ssize_t cmdir_read(unsigned char *buffer, size_t count) +{ + struct usb_skel *dev; + int retval = 0; + int len; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + if (minor_table[rx_device] == NULL) + return -ENODEV; + dev = minor_table[rx_device]; + + /* lock this object */ + down(&dev->sem); + retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, + dev->bulk_in_endpointAddr), + dev->bulk_in_buffer, dev->bulk_in_size, &len, HZ*100); +#else + struct usb_interface *interface; + interface = usb_find_interface(&cmdir_driver, + USB_CMDIR_MINOR_BASE+rx_device); + if (!interface) { + /* also check without adding base, for devfs */ + interface = usb_find_interface(&cmdir_driver, rx_device); + if (!interface) + return -ENODEV; + } + dev = usb_get_intfdata(interface); + if (!dev) + return -ENODEV; + retval = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, + dev->bulk_in_endpointAddr), + dev->bulk_in_buffer, min(dev->bulk_in_size, count), + &len, HZ*10); +#endif + if (!retval) { + if (!memcpy(buffer, dev->bulk_in_buffer, len)) + retval = -EFAULT; + else { + /* current status of the TX buffer */ + curTXFill = buffer[2]; + retval = len; + } + } + /* suppress errors */ + /* + else { + err("Read from device failed, error %d",retval); + } + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + /* unlock the device */ + up(&dev->sem); +#endif + /* printk(KERN_INFO "CommandIR Reporting TX buffer at %d bytes. \n", + * curTXFill); */ + return retval; +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +EXPORT_SYMBOL_NOVERS(cmdir_read); +#else +EXPORT_SYMBOL(cmdir_read); +#endif + +static ssize_t cmdir_file_write(struct file *file, const char *buffer, + size_t count, loff_t *ppos) +{ + int retval; + int i; + int equalsign = 0; + int changeType = 0; + unsigned char ctrl_buffer[MCU_CTRL_SIZE]; + char *local_buffer; + int minor; + + /* set as default - if non-specific error, + * won't keep calling this function */ + retval = count; + local_buffer = kmalloc(count, GFP_KERNEL); + + /* verify that we actually have some data to write */ + if (count == 0) { + err("Write request of 0 bytes"); + goto exit; + } + if (count > 64) { + err("Input too long"); + goto exit; + } + + /* copy the data from userspace into our local buffer */ + if (copy_from_user(local_buffer, buffer, count)) { + retval = -EFAULT; + goto exit; + } + + /* parse code */ + changeType = cNothing; + equalsign = 0; + for (i = 0; i < MCU_CTRL_SIZE; i++) + ctrl_buffer[i] = 'j'; + + for (i = 0; i < count; i++) { + switch (local_buffer[i]) { + case 'X': + case 'x': + if ((i > 0) && ((local_buffer[i - 1] == 'R') + || (local_buffer[i - 1] == 'r'))) + changeType = cRX; + break; + case 'S': + case 's': + if ((i > 1) && ((local_buffer[i - 1] == 'E') + || (local_buffer[i - 1] == 'e'))) { + if ((local_buffer[i-2] == 'R') + || (local_buffer[i-2] == 'r')) + changeType = cRESET; + } + break; + case 'L': + case 'l': + if ((i > 0) && ((local_buffer[i - 1] == 'F') + || (local_buffer[i - 1] == 'f'))) + changeType = cFLASH; + break; + case 'C': + case 'c': + if ((i > 0) && ((local_buffer[i - 1] == 'L') + || (local_buffer[i - 1] == 'l'))) + changeType = cLCD; + break; + case '=': + if (changeType != cNothing) + equalsign = i; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + if (equalsign > 0) { + minor = local_buffer[i] - ASCII0; + switch (changeType) { + case cRESET: + ctrl_buffer[0] = RESET_HEADER; + retval = write_core(ctrl_buffer, + MCU_CTRL_SIZE, + cmdir_write_bulk_callback, + minor); + if (retval != MCU_CTRL_SIZE) { + if (retval == -ENODEV) + err("Device %d " + "unplugged", minor); + else + err("Error on write to " + "%d", minor); + goto exit; + } else + retval = count; + init_cmdir_var(minor); + break; + case cFLASH: + ctrl_buffer[0] = FLASH_HEADER; + info("Flashing indicators on device %d", + minor); + retval = write_core(ctrl_buffer, + MCU_CTRL_SIZE, + cmdir_write_bulk_callback, + minor); + if (retval != MCU_CTRL_SIZE) { + if (retval == -ENODEV) + err("Device %d " + "unplugged", minor); + else + err("Error on write to " + "%d", minor); + goto exit; + } else + retval = count; + break; + case cRX: + rx_device = minor; + info("Default receiver set to %d", + minor); + break; + case cLCD: + lcd_device = minor; + info("commandir: Default LCD set to %d", + minor); + break; + default: + break; + } + } + break; + case ',': + equalsign = 0; + changeType = cNothing; + break; + default: + if ((equalsign > 0) && (local_buffer[i] > 32)) { + err("Non-numerical argument"); + goto exit; + } + break; + } + } + + if ((changeType != cNothing) && (equalsign == 0)) + err("No device specified"); + if (changeType == cNothing) + err("Unknown command"); + +exit: + kfree(local_buffer); + return retval; +} + +int cmdir_write(unsigned char *buffer, int count, + void *callback_fct, int usecdelay) +{ + /* Always add to queue, then send queue number + * no locks + * mbodkin, Sept 8, 2005 */ + int ret = 0; + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "cmdir_write at %d\n", (int)tp.tv_usec); + } + ret = add_cmdir_queue(buffer, count, callback_fct, usecdelay); + + if (ret == -1) { + printk(KERN_INFO "cmdir_write returning 0\n"); + return 0; + } + return count; + +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +EXPORT_SYMBOL_NOVERS(cmdir_write); +#else +EXPORT_SYMBOL(cmdir_write); +#endif + +int add_cmdir_queue(unsigned char *buffer, int count, + void *callback_vct, int usecdelay) +{ + int ret = 0; + if ((nexttofill + 1) % (QUEUELENGTH - 1) == nexttosend) { + + /* our buffer is full */ + printk(KERN_INFO "Too many packets backlogged " + "in CommandIR Queue.\n"); + return -1; + } + /* go ahead and use this one: */ + memcpy(ourbuffers[nexttofill], buffer, count); + ourbufferlengths[nexttofill] = count; + waitusecs[nexttofill] = (usecdelay == 0) ? 10000 : usecdelay; + /* printk(KERN_INFO "Adding %d to queue at position %d.\n", + * count, nexttofill); */ + nexttofill = (nexttofill + 1) % (QUEUELENGTH - 1); + ret = nexttofill; + /* if (timer_running == 0) */ + send_queue(); /* fake it if the timer's not running */ + return ret; /* we accepted the full packet */ + +} + +int send_queue() +{ + int last_sent = 0; + int ret = 0; + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "Send_queue() at %d\n", (int)tp.tv_usec); + } + /* initiate the send/callback routine if not already running. */ + if (send_status == SEND_IDLE) { + if (!(nexttofill == nexttosend)) { + /* start it up: */ + + last_sent = nexttosend - 1; + if (last_sent < 0) + last_sent = QUEUELENGTH - 1; + /* Final check - is it TIME to send this packet yet? */ + /* if (wait_to_tx(waitusecs[last_sent]) == 0) { */ + /* always send if there's room, + * otherwise wait until room */ + if (curTXFill < 190) { + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "Sending packet data " + "at %d\n", (int)tp.tv_usec); + } + ret = cmdir_write_queue(ourbuffers[nexttosend], + ourbufferlengths[nexttosend], NULL); + if (ret <= 0) { + /* send failed - the device is either + * unplugged or full + * nexttosend = + * (nexttosend + 1) + * % (QUEUELENGTH - 1); */ + send_status = SEND_IDLE; + return 0; /*send_queue(); */ + } else + nexttosend = (nexttosend + 1) + % (QUEUELENGTH - 1); + return 1; + } else { + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "Not time to send yet " + "- starting timer at %d.\n", + (int)tp.tv_usec); + printk(KERN_INFO "Enabling timer.\n"); + } + return 0; /* doesn't matter anymore */ + } + } else { + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "No more data to send %d!\n", + (int)tp.tv_usec); + } + last_tx_sec = 0; /* reset our TX counters */ + last_tx_usec = 0; + return 1; /* nothing more to send! */ + } + } else { + if (debug_commandir == 1) + /* will try again on the callback */ + printk(KERN_INFO "Already sending\n"); + return 1; /* then the timer shouldn't be running... */ + } + return 0; /* should never get here... */ +} + + +int wait_to_tx(int usecs) +{ + /* don't return until last_time + usecs has been reached + * for non-zero last_tx's. */ + int wait_until_sec = 0, wait_until_usec = 0; + int now_sec = 0, now_usec = 0; + if (debug_commandir == 1) + printk(KERN_INFO "waittotx(%d)\n", usecs); + if (usecs == 0) + return 0; + + if (!(last_tx_sec == 0 && last_tx_usec == 0)) { + /* calculate wait time: */ + wait_until_sec = last_tx_sec + (usecs / 1000000); + wait_until_usec = last_tx_usec + usecs; + + do_gettimeofday(&tp); + now_sec = tp.tv_sec; + now_usec = tp.tv_usec; + + if (wait_until_usec > 1000000) { + /* we've spilled over to the next second. */ + wait_until_sec++; + wait_until_usec -= 1000000; + /* printk(KERN_INFO "usec rollover\n"); */ + } + if (debug_commandir == 1) + printk(KERN_INFO "Testing for the right second, now = " + "%d %d, wait = %d %d\n", + now_sec, now_usec, + wait_until_sec, wait_until_usec); + /* now we are always on the same second. */ + if (now_sec > wait_until_sec) { + if (debug_commandir == 1) + printk(KERN_INFO "Setting last_tx_sec to %d.\n", + wait_until_sec); + last_tx_sec = wait_until_sec; + last_tx_usec = wait_until_usec; + return 0; + } + + if ((now_sec == wait_until_sec) + && (now_usec > wait_until_usec)) { + if (debug_commandir == 1) + printk(KERN_INFO "Setting last_tx_sec to %d.\n", + wait_until_sec); + last_tx_sec = wait_until_sec; + last_tx_usec = wait_until_usec; + return 0; + } + return -1; /* didn't send */ + } + + do_gettimeofday(&tp); + last_tx_usec = tp.tv_usec; + last_tx_sec = tp.tv_sec; + return 0; /* if there's no last even, go ahead and send */ +} + + +int cmdir_write_queue(unsigned char *buffer, int count, void *callback_fct) +{ + int retval = count; + static char prev_signal_num; + unsigned char next_mask; + unsigned int multiplier; + int i; + + send_status = SEND_ACTIVE; + + if (count < 2) { + err("Not enough bytes (write request of %d bytes)", count); + return count; + } + + /* check data; decide which device to send to */ + switch (buffer[0]) { + case TX_HEADER: + case TX_HEADER_NEW: + /* this is LIRC transmit data */ + if (curTXFill >= 190) { + printk(KERN_INFO + "TX buffer too full to send more TX data\n"); + return 0; + } + if (next_transmitters != transmitters) { + if (buffer[1] != prev_signal_num) + /* this is new signal; change transmitter mask*/ + transmitters = next_transmitters; + } + prev_signal_num = buffer[1]; + + multiplier = 1; + for (i = 0; i < MAX_DEVICES; i++) { + next_mask = 0; + if (transmitters & (0x01*multiplier)) + next_mask |= TX1_ENABLE; + if (transmitters & (0x02*multiplier)) + next_mask |= TX2_ENABLE; + if (transmitters & (0x04*multiplier)) + next_mask |= TX3_ENABLE; + if (transmitters & (0x08*multiplier)) + next_mask |= TX4_ENABLE; + + if (next_mask > 0) { + buffer[1] = next_mask; + retval = write_core(buffer, count, + callback_fct, i); + if (retval != count) { + if (retval == -ENODEV) + err("Device %d not plugged in", + i); + else + err("Write error to device %d", + i); + return retval; + } + } + multiplier = multiplier*0x10; + } + return retval; + break; + case LCD_HEADER: + return write_core(buffer, count, callback_fct, lcd_device); + break; + default: + return write_core(buffer, count, callback_fct, def_device); + break; + } + /* should never get here */ + return retval; + +} + +int write_core(unsigned char *buffer, int count, + void *callback_fct, int device_num) +{ + struct usb_skel *dev; + int retval = count; + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) + ssize_t bytes_written = 0; + if (minor_table[device_num] == NULL) + /* device is unplugged */ + return -ENODEV; + dev = minor_table[device_num]; + + /* lock this object */ + down(&dev->sem); + + /* see if we are already in the middle of a write */ + if (dev->write_urb->status == -EINPROGRESS) { + /*suppress errors - should just try sending again*/ + /*dbg(" - already writing");*/ + retval = -EINPROGRESS; + goto exit; + } + + /* we can only write as much as 1 urb will hold */ + bytes_written = (count > dev->bulk_out_size) ? + dev->bulk_out_size : count; + + /* copy the data into our urb */ + if (!(memcpy(dev->write_urb->transfer_buffer, buffer, bytes_written))) { + retval = -EFAULT; + goto exit; + } + + /* set up our urb */ + if (callback_fct == NULL) { + /*FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + dev->write_urb->transfer_buffer, bytes_written, + cmdir_write_bulk_callback, dev); */ + usb_fill_bulk_urb(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + dev->write_urb->transfer_buffer, bytes_written, + cmdir_write_bulk_callback, dev); + } else { + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + dev->write_urb->transfer_buffer, bytes_written, + callback_fct, dev); + } + + /* send the data out the bulk port */ + retval = usb_submit_urb(dev->write_urb); + if (!(retval)) + retval = bytes_written; + /* suppress errors */ + /* else { + err("Failed submitting write urb, error %d", retval); + } */ +exit: + /* unlock the device */ + up(&dev->sem); + return retval; /* this should be return error I think */ + +#else + struct usb_interface *interface; + struct urb *urb = NULL; + char *buf = NULL; + interface = usb_find_interface(&cmdir_driver, + USB_CMDIR_MINOR_BASE + device_num); + if (!interface) { + /* also check without adding base, for devfs */ + interface = usb_find_interface(&cmdir_driver, device_num); + if (!interface) + return -ENODEV; + } + dev = usb_get_intfdata(interface); + if (!dev) + return -ENODEV; + /* create a urb, and a buffer for it, and copy the data to the urb */ + urb = usb_alloc_urb(0, GFP_ATOMIC); /* Now -=Atomic=- */ + if (!urb) { + retval = -ENOMEM; + goto error; + } + buf = usb_buffer_alloc(dev->udev, count, + GFP_KERNEL, &urb->transfer_dma); + if (!buf) { + retval = -ENOMEM; + goto error; + } + if (!memcpy(buf, buffer, count)) { + retval = -EFAULT; + goto error; + } + /* initialize the urb properly */ + if (callback_fct == NULL) { + usb_fill_bulk_urb(urb, dev->udev, + usb_sndbulkpipe(dev->udev, + dev->bulk_out_endpointAddr), + buf, count, (void *) cmdir_write_bulk_callback, dev); + } else { + usb_fill_bulk_urb(urb, dev->udev, + usb_sndbulkpipe(dev->udev, + dev->bulk_out_endpointAddr), + buf, count, callback_fct, dev); + } + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; /* double check this */ + + /* send the data out the bulk port */ + retval = usb_submit_urb(urb, GFP_KERNEL); + if (retval) { + err("%s - failed submitting write urb, error %d", + __FUNCTION__, retval); + goto error; + } + + /* release our reference to this urb, the USB + * core will eventually free it entirely */ + usb_free_urb(urb); + return count; + +error: + usb_buffer_free(dev->udev, count, buf, urb->transfer_dma); + usb_free_urb(urb); + return retval; +#endif +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +static void cmdir_write_bulk_callback(struct urb *urb) +{ + if (debug_commandir == 1) { + do_gettimeofday(&tp); + printk(KERN_INFO "cmdir_write_bulk_callback at %d\n", + (int)tp.tv_usec); + } + /*if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) + return; + else { + dbg(" - urb status: %d", urb->status); + return; + }*/ + + send_status = SEND_IDLE; + /* printk(KERN_INFO "cmdir_write_bulk_callback - set idle\n"); */ + send_queue(); /* send the next packet */ + return; +} +#else +static void cmdir_write_bulk_callback(struct urb *urb, struct pt_regs *regs) +{ + struct usb_skel *dev; + dev = (struct usb_skel *)urb->context; + send_status = SEND_IDLE; + if (debug_commandir == 1) + printk(KERN_INFO "callback()\n"); + /* free up our allocated buffer */ + + usb_buffer_free(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + send_queue(); /* send the next packet */ + +} +#endif + +int set_tx_channels(unsigned int next_tx) +{ + next_transmitters = next_tx; + return 0; +} +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +EXPORT_SYMBOL_NOVERS(set_tx_channels); +#else +EXPORT_SYMBOL(set_tx_channels); +#endif + +module_init(usb_cmdir_init); +module_exit(usb_cmdir_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/commandir.h +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/commandir.h @@ -0,0 +1,41 @@ +/* + * commandir.h + */ + +#define ASCII0 48 + +/* transmitter channel control */ +#define MAX_DEVICES 8 +#define MAX_CHANNELS 32 +#define TX1_ENABLE 0x80 +#define TX2_ENABLE 0x40 +#define TX3_ENABLE 0x20 +#define TX4_ENABLE 0x10 + +/* command types */ +#define cNothing 0 +#define cRESET 1 +#define cFLASH 2 +#define cLCD 3 +#define cRX 4 + +/* CommandIR control codes */ +#define MCU_CTRL_SIZE 3 +#define FREQ_HEADER 2 +#define RESET_HEADER 3 +#define FLASH_HEADER 4 +#define LCD_HEADER 5 +#define TX_HEADER 7 +#define TX_HEADER_NEW 8 + +/* Queue buffering constants */ +#define SEND_IDLE 0 +#define SEND_ACTIVE 1 + +#define QUEUELENGTH 256 + +extern int cmdir_write(unsigned char *buffer, int count, + void *callback_fct, int u); +extern ssize_t cmdir_read(unsigned char *buffer, size_t count); +extern int set_tx_channels(unsigned int next_tx); + --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_CMDIR) += lirc_cmdir.o commandir.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/lirc_cmdir.h +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/lirc_cmdir.h @@ -0,0 +1,27 @@ +/* $Id: lirc_cmdir.h,v 1.3 2007/09/27 19:47:20 lirc Exp $ */ + +/* + * lirc_cmdir.h + */ + +#ifndef LIRC_CMDIR_H +#define LIRC_CMDIR_H + +#define ON 1 +#define OFF 0 + +/* transmitter channel control */ +#define MAX_CHANNELS 32 + +/* CommandIR control codes */ +#define MCU_CTRL_SIZE 3 +#define FREQ_HEADER 2 +#define TX_HEADER 7 +#define TX_HEADER_NEW 8 + +extern int cmdir_write(unsigned char *buffer, int count, + void *callback_fct, int u); +extern ssize_t cmdir_read(unsigned char *buffer, size_t count); +extern int set_tx_channels(unsigned int next_tx); + +#endif --- linux-2.6.28.orig/ubuntu/lirc/lirc_cmdir/lirc_cmdir.c +++ linux-2.6.28/ubuntu/lirc/lirc_cmdir/lirc_cmdir.c @@ -0,0 +1,613 @@ +/* $Id: lirc_cmdir.c,v 1.9 2008/01/13 11:13:49 lirc Exp $ */ + +/* + * lirc_cmdir.c - Driver for InnovationOne's COMMANDIR USB Transceiver + * + * This driver requires the COMMANDIR hardware driver, available at + * http://www.commandir.com/. + * + * Copyright (C) 2005 InnovationOne - Evelyn Yeung + * + * 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 + */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" +#include "kcompat.h" +#include "lirc_cmdir.h" + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG fmt, ## args); \ + } while (0) + +struct lirc_cmdir { + int features; +}; + +struct lirc_cmdir hardware = { + ( + /* LIRC_CAN_SET_SEND_DUTY_CYCLE| */ + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_SET_TRANSMITTER_MASK| + LIRC_CAN_REC_MODE2) + , +}; + +#define LIRC_DRIVER_NAME "lirc_cmdir" +#define RBUF_LEN 256 +#define WBUF_LEN 256 +#define MAX_PACKET 64 + +static struct lirc_buffer rbuf; +static lirc_t wbuf[WBUF_LEN]; +static unsigned char cmdir_char[4*WBUF_LEN]; +static unsigned char write_control[MCU_CTRL_SIZE]; +static unsigned int last_mc_time; +static int usb_status = ON; +static unsigned char signal_num; +char timerval; + +unsigned int freq = 38000; +/* unsigned int duty_cycle = 50; */ + + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +static unsigned int get_time_value(unsigned int firstint, + unsigned int secondint, unsigned char overflow) +{ /* get difference between two timestamps from MCU */ + unsigned int t_answer = 0; + + if (secondint > firstint) { + t_answer = secondint - firstint + overflow*65536; + } else { + if (overflow > 0) + t_answer = (65536 - firstint) + secondint + + (overflow - 1) * 65536; + else + t_answer = (65536 - firstint) + secondint; + } + + /* clamp to long signal */ + if (t_answer > 16000000) + t_answer = PULSE_MASK; + + return t_answer; +} + + +static int set_use_inc(void *data) +{ + /* Init read buffer. */ + if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) + return -ENOMEM; + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ + lirc_buffer_free(&rbuf); + MOD_DEC_USE_COUNT; +} + + +static void usb_error_handle(int retval) +{ + switch (retval) { + case -ENODEV: + /* device has been unplugged */ + if (usb_status == ON) { + usb_status = OFF; + printk(LIRC_DRIVER_NAME ": device is unplugged\n"); + } + break; + default: + printk(LIRC_DRIVER_NAME ": usb error = %d\n", retval); + break; + } +} + +static int write_to_usb(unsigned char *buffer, int count, int time_elapsed) +{ + int write_return; + + write_return = cmdir_write(buffer, count, NULL, time_elapsed); + if (write_return != count) { + usb_error_handle(write_return); + } else { + if (usb_status == OFF) { + printk(LIRC_DRIVER_NAME ": device is now plugged in\n"); + usb_status = ON; + } + } + return write_return; +} + +static void set_freq(void) +{ + /* float tempfreq = 0.0; */ + int write_return; + + /* + * Can't use floating point in 2.6 kernel! + * May be some loss of precision + */ + timerval = (1000000 / freq) / 2; + write_control[0] = FREQ_HEADER; + write_control[1] = timerval; + write_control[2] = 0; + write_return = write_to_usb(write_control, MCU_CTRL_SIZE, 0); + if (write_return == MCU_CTRL_SIZE) + printk(LIRC_DRIVER_NAME ": freq set to %dHz\n", freq); + else + printk(LIRC_DRIVER_NAME ": freq unchanged\n"); + +} + +static int cmdir_convert_RX(unsigned char *orig_rxbuffer) +{ + unsigned char tmp_char_buffer[80]; + unsigned int tmp_int_buffer[20]; + unsigned int final_data_buffer[20]; + unsigned int num_data_values = 0; + unsigned char num_data_bytes = 0; + unsigned int orig_index = 0; + int i; + + for (i = 0; i < 80; i++) + tmp_char_buffer[i] = 0; + for (i = 0; i < 20; i++) + tmp_int_buffer[i] = 0; + + /* + * get number of data bytes that follow the control bytes + * (NOT including them) + */ + num_data_bytes = orig_rxbuffer[1]; + + /* check if num_bytes is multiple of 3; if not, error */ + if (num_data_bytes % 3 > 0) + return -1; + if (num_data_bytes > 60) + return -3; + if (num_data_bytes < 3) + return -2; + + /* + * get number of ints to be returned; num_data_bytes does + * NOT include control bytes + */ + num_data_values = num_data_bytes/3; + + for (i = 0; i < num_data_values; i++) { + tmp_char_buffer[i*4] = orig_rxbuffer[(i+1)*3]; + tmp_char_buffer[i*4+1] = orig_rxbuffer[(i+1)*3+1]; + tmp_char_buffer[i*4+2] = 0; + tmp_char_buffer[i*4+3] = 0; + } + + /* convert to int array */ + memcpy((unsigned char *)tmp_int_buffer, tmp_char_buffer, + (num_data_values*4)); + + if (orig_rxbuffer[5] < 255) { + /* space */ + final_data_buffer[0] = get_time_value(last_mc_time, + tmp_int_buffer[0], + orig_rxbuffer[5]); + } else { /* is pulse */ + final_data_buffer[0] = get_time_value(last_mc_time, + tmp_int_buffer[0], + 0); + final_data_buffer[0] |= PULSE_BIT; + } + for (i = 1; i < num_data_values; i++) { + /* + * index of orig_rxbuffer that corresponds to + * overflow/pulse/space + */ + orig_index = (i + 1)*3 + 2; + if (orig_rxbuffer[orig_index] < 255) { + final_data_buffer[i] = + get_time_value(tmp_int_buffer[i - 1], + tmp_int_buffer[i], + orig_rxbuffer[orig_index]); + } else { + final_data_buffer[i] = + get_time_value(tmp_int_buffer[i - 1], + tmp_int_buffer[i], + 0); + final_data_buffer[i] |= PULSE_BIT; + } + } + last_mc_time = tmp_int_buffer[num_data_values - 1]; + + if (lirc_buffer_full(&rbuf)) { + printk(KERN_ERR LIRC_DRIVER_NAME ": lirc_buffer is full\n"); + return -EOVERFLOW; + } + lirc_buffer_write_n(&rbuf, (char *)final_data_buffer, num_data_values); + + return 0; +} + + +static int usb_read_once(void) +{ + int read_retval = 0; + int conv_retval = 0; + unsigned char read_buffer[MAX_PACKET]; + int i = 0; + int tooFull = 5; /* read up to 5 packets */ + + for (i = 0; i < MAX_PACKET; i++) + read_buffer[i] = 0; + + while (tooFull--) { + read_retval = cmdir_read(read_buffer, MAX_PACKET); + /* Loop until we unload the data build-up */ + if (read_buffer[1] < 60) + tooFull = 0; + if (!(read_retval == MAX_PACKET)) { + if (read_retval == -ENODEV) { + if (usb_status == ON) { + printk(KERN_ALERT LIRC_DRIVER_NAME + ": device is unplugged\n"); + usb_status = OFF; + } + } else { + /* supress errors */ + printk(KERN_ALERT LIRC_DRIVER_NAME + ": usb error on read = %d\n", + read_retval); + return -ENODATA; + } + dprintk("Error 3\n"); + return -ENODATA; + } else { + if (usb_status == OFF) { + usb_status = ON; + printk(LIRC_DRIVER_NAME + ": device is now plugged in\n"); + } + } + + if (read_buffer[0] & 0x08) { + conv_retval = cmdir_convert_RX(read_buffer); + if (conv_retval == 0) { + if (!tooFull) + return 0; + else + dprintk("Looping for more data...\n"); + } else { + dprintk("Error 2: %d\n", (int)conv_retval); + return -ENODATA; + } + } else { + /* There really is no data in their buffer */ + dprintk("Empty RX Buffer!\n"); + return -ENODATA; + } + } + return -1; +} + +int add_to_buf(void *data, struct lirc_buffer *buf) +{ + return usb_read_once(); +} + + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count; + unsigned int mod_signal_length = 0; + unsigned int time_elapse = 0; + unsigned int total_time_elapsed = 0; + unsigned int num_bytes_already_sent = 0; + unsigned int hibyte = 0; + unsigned int lobyte = 0; + int cmdir_cnt = 0; + unsigned int wait_this = 0; + struct timeval start_time; + struct timeval end_time; + unsigned int real_time_elapsed = 0; + + /* save the time we started the write: */ + do_gettimeofday(&start_time); + + if (n % sizeof(lirc_t)) + return -EINVAL; + + count = n/sizeof(lirc_t); + if (count > WBUF_LEN || count % 2 == 0) + return -EINVAL; + if (copy_from_user(wbuf, buf, n)) + return -EFAULT; + + /* + * the first time we have to flag that this is the start of a new + * signal otherwise COMMANDIR may receive 2 back-to-back pulses & + * invert the signal + */ + cmdir_char[0] = TX_HEADER_NEW; + signal_num++; + cmdir_char[1] = signal_num; + cmdir_cnt = 2; + for (i = 0; i < count; i++) { + /* conversion to number of modulation frequency pulse edges */ + mod_signal_length = wbuf[i] >> 3; + /* + * account for minor rounding errors - + * calculate length from this: + */ + time_elapse += mod_signal_length * timerval; + + hibyte = mod_signal_length / 256; + lobyte = mod_signal_length % 256; + cmdir_char[cmdir_cnt+1] = lobyte; + cmdir_char[cmdir_cnt] = hibyte; + cmdir_cnt += 2; + + /* write data to usb if full packet is collected */ + if (cmdir_cnt % MAX_PACKET == 0) { + write_to_usb(cmdir_char, MAX_PACKET, time_elapse); + + total_time_elapsed += time_elapse; + + num_bytes_already_sent += MAX_PACKET; + time_elapse = 0; + + if ((i + 1) < count) { + /* still more to send: */ + cmdir_char[0] = TX_HEADER; /* Next Packet */ + cmdir_char[1] = signal_num; + cmdir_cnt = 2; /* reset the count */ + } + } + } + + /* send last chunk of data */ + if (cmdir_cnt > 0) { + total_time_elapsed += time_elapse; + write_to_usb(cmdir_char, cmdir_cnt, time_elapse); + } + /* XXX ERS remove all this? */ + /* + * we need to _manually delay ourselves_ to remain backwards + * compatible with LIRC and prevent our queue buffer from overflowing. + * Queuing in this driver is about instant, and send_start for example + * will fill it up quickly and prevent send_stop from taking immediate + * effect. + */ + dprintk("Total elapsed time is: %d. \n", total_time_elapsed); + do_gettimeofday(&end_time); + /* + * udelay for the difference between endtime and + * start + total_time_elapsed + */ + if (start_time.tv_usec < end_time.tv_usec) + real_time_elapsed = (end_time.tv_usec - start_time.tv_usec); + else + real_time_elapsed = ((end_time.tv_usec + 1000000) - + start_time.tv_usec); + dprintk("Real time elapsed was %u.\n", real_time_elapsed); + if (real_time_elapsed < (total_time_elapsed - 1000)) + wait_this = total_time_elapsed - real_time_elapsed - 1000; + +#if 0 /* enable this for backwards compatibility */ + safe_udelay(wait_this); +#endif + + return(n); +} + + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long value; + unsigned int ivalue; + unsigned int multiplier = 1; + unsigned int mask = 0; + int i; + + switch (cmd) { + case LIRC_SET_TRANSMITTER_MASK: + if (!(hardware.features&LIRC_CAN_SET_TRANSMITTER_MASK)) + return -ENOIOCTLCMD; + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + for (i = 0; i < MAX_CHANNELS; i++) { + multiplier = multiplier * 0x10; + mask |= multiplier; + } + if (ivalue >= mask) + return MAX_CHANNELS; + set_tx_channels(ivalue); + return 0; + break; + + case LIRC_GET_SEND_MODE: + if (!(hardware.features & LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = put_user(LIRC_SEND2MODE + (hardware.features & LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + if (!(hardware.features&LIRC_CAN_SEND_MASK)) + return -ENOIOCTLCMD; + + result = get_user(value, (unsigned long *)arg); + if (result) + return result; + break; + + case LIRC_GET_LENGTH: + return -ENOSYS; + break; + + case LIRC_SET_SEND_DUTY_CYCLE: + dprintk(KERN_WARNING LIRC_DRIVER_NAME + ": SET_SEND_DUTY_CYCLE\n"); + + if (!(hardware.features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *)arg); + if (result) + return result; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + + /* TODO: */ + dprintk(LIRC_DRIVER_NAME + ": set_send_duty_cycle not yet supported\n"); + + return 0; + break; + + case LIRC_SET_SEND_CARRIER: + dprintk(KERN_WARNING LIRC_DRIVER_NAME ": SET_SEND_CARRIER\n"); + + if (!(hardware.features & LIRC_CAN_SET_SEND_CARRIER)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *)arg); + if (result) + return result; + if (ivalue > 500000 || ivalue < 24000) + return -EINVAL; + if (ivalue != freq) { + freq = ivalue; + set_freq(); + } + return 0; + break; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 20, + .data = NULL, + .add_to_buf = add_to_buf, + .get_queue = NULL, + .rbuf = &rbuf, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .ioctl = lirc_ioctl, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +MODULE_AUTHOR("Evelyn Yeung, Matt Bodkin"); +MODULE_DESCRIPTION("InnovationOne driver for " + "CommandIR USB infrared transceiver"); +#ifdef MODULE_LICENSE +MODULE_LICENSE("GPL"); +#endif + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +#ifndef KERNEL_2_5 +EXPORT_NO_SYMBOLS; +#endif + +int init_module(void) +{ + plugin.features = hardware.features; + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": register_chrdev failed!\n"); + return -EIO; + } + set_freq(); + return 0; +} + +void cleanup_module(void) +{ + lirc_unregister_plugin(plugin.minor); + printk(KERN_INFO LIRC_DRIVER_NAME ": module removed\n"); +} + +#endif + + --- linux-2.6.28.orig/ubuntu/lirc/lirc_pvr150/lirc_pvr150.c +++ linux-2.6.28/ubuntu/lirc/lirc_pvr150/lirc_pvr150.c @@ -0,0 +1,1481 @@ +/* $Id: $ */ + +/* + * i2c IR lirc plugin for Hauppauge PVR 150 card + * + * Copyright (c) 2000 Gerd Knorr + * modified for PixelView (BT878P+W/FM) by + * Michal Kochanowicz + * Christoph Bartelmus + * modified for KNC ONE TV Station/Anubis Typhoon TView Tuner by + * Ulrich Mueller + * modified for Asus TV-Box and Creative/VisionTek BreakOut-Box by + * Stefan Jahn + * modified for inclusion into kernel sources by + * Jerome Brock + * modified for Leadtek Winfast PVR2000 by + * Thomas Reitmayr (treitmayr@yahoo.com) + * modified for Hauppauge PVR-150 IR TX device by + * Mark Weaver + * + * parts are cut&pasted from the lirc_pvr150.c driver + * + * 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 + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" +#include "lirc.h" + +/* We need to be able to reset the crappy IR chip by talking to the ivtv driver */ +struct ivtv; +void ivtv_reset_ir_gpio(struct ivtv *itv); + +struct IR +{ + struct lirc_plugin l; + + /* Device info */ + struct semaphore lock; + int open; + + /* RX device */ + struct i2c_client c_rx; + + /* RX device buffer & lock */ + struct lirc_buffer buf; + struct semaphore buf_sem; + + /* RX polling thread data */ + struct completion *t_notify; + struct completion *t_notify2; + int shutdown; + int tpid; + + /* RX read data */ + unsigned char b[3]; + + /* TX device */ + struct i2c_client c_tx; + int need_boot; + + /* # devices, for shutdown */ + int devs; +}; + +/* Minor -> data mapping */ +static struct IR *ir_devices[MAX_IRCTL_DEVICES]; + +/* Block size for haup PVR-150 IR transmitter */ +#define TX_BLOCK_SIZE 99 + +/* Hauppuage IR transmitter data */ +typedef struct TX_DATA_s +{ + /* Boot block */ + unsigned char *boot_data; + + /* Start of binary data block */ + unsigned char *datap; + + /* End of binary data block */ + unsigned char *endp; + + /* Number of installed codesets */ + unsigned int num_code_sets; + + /* Pointers to codesets */ + unsigned char **code_sets; + + /* Global fixed data template */ + int fixed[TX_BLOCK_SIZE]; +} TX_DATA; + +static TX_DATA *tx_data; +struct semaphore tx_data_lock; + +/* ----------------------------------------------------------------------- */ + +#define DEVICE_NAME "lirc_pvr150" + +/* ----------------------------------------------------------------------- */ +/* insmod parameters */ + +static int debug = 0; /* debug output */ +static int disable_rx = 0; /* disable RX device */ +static int disable_tx = 0; /* disable TX device */ +static int minor = -1; /* minor number */ + +#define dprintk(fmt, args...) \ + do{ \ + if(debug) printk(KERN_DEBUG DEVICE_NAME ": " fmt, \ + ## args); \ + }while(0) + +/* ----------------------------------------------------------------------- */ + +static int add_to_buf(struct IR *ir) +{ + __u16 code; + unsigned char codes[2]; + unsigned char keybuf[6]; + int got_data = 0; + int ret; + int failures = 0; + unsigned char sendbuf[1] = { 0 }; + + if (lirc_buffer_full(&ir->buf)) { + dprintk("buffer overflow\n"); + return -EOVERFLOW; + } + + /* service the device as long as it is returning + * data and we have space + */ + do + { + /* Lock i2c bus for the duration. RX/TX chips interfere so + this is worth it + */ + down(&ir->lock); + + /* Send random "poll command" (?) Windows driver does this + and it is a good point to detect chip failure. + */ + ret = i2c_master_send(&ir->c_rx, sendbuf, 1); + if (ret != 1) + { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", + ret); + if (failures >= 3) { + up(&ir->lock); + printk(KERN_ERR "lirc_pvr150: unable to read " + "from the IR chip after 3 " + "resets, giving up\n"); + return ret; + } + + /* Looks like the chip crashed, reset it */ + printk(KERN_ERR "lirc_pvr150: polling the IR receiver " + "chip failed, trying reset\n"); + + ivtv_reset_ir_gpio(i2c_get_adapdata(ir->c_rx.adapter)); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((100 * HZ + 999) / 1000); + ir->need_boot = 1; + + ++failures; + up(&ir->lock); + continue; + } + + ret = i2c_master_recv(&ir->c_rx, keybuf, sizeof(keybuf)); + up(&ir->lock); + if (ret != sizeof(keybuf)) + { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d" + " -- keeping last read buffer\n", ret); + } + else + { + ir->b[0] = keybuf[3]; + ir->b[1] = keybuf[4]; + ir->b[2] = keybuf[5]; + dprintk("key (0x%02x/0x%02x)\n", ir->b[0], ir->b[1]); + } + + /* key pressed ? */ + if ((ir->b[0] & 0x80) == 0) + return got_data ? 0 : -ENODATA; + + /* look what we have */ + code = (((__u16)ir->b[0]&0x7f)<<6) | (ir->b[1]>>2); + + codes[0] = (code >> 8) & 0xff; + codes[1] = code & 0xff; + + /* return it */ + lirc_buffer_write_1( &ir->buf, codes ); + ++got_data; + } while (!lirc_buffer_full(&ir->buf)); + return 0; +} + +/* Main function of the polling thread -- from lirc_dev. + * We don't fit the LIRC model at all anymore. This is horrible, but + * basically we have a single RX/TX device with a nasty failure mode + * that needs to be accounted for across the pair. lirc lets us provide + * fops, but prevents us from using the internal polling, etc. if we do + * so. Hence the replication. Might be neater to extend the LIRC model + * to account for this but I'd think it's a very special case of seriously + * messed up hardware. + */ +static int lirc_thread(void *arg) +{ + struct IR *ir = arg; + + /* This thread doesn't need any user-level access, + * so get rid of all our resources + */ + daemonize("lirc_pvr150"); + + if (ir->t_notify != NULL) { + complete(ir->t_notify); + } + + dprintk("poll thread started\n"); + + do { + if (ir->open) { + set_current_state(TASK_INTERRUPTIBLE); + + /* This is ~113*2 + 24 + jitter (2*repeat gap + + code length). We use this interval as the chip + resets every time you poll it (bad!). This is + therefore just sufficient to catch all of the + button presses. It makes the remote much more + responsive. You can see the difference by + running irw and holding down a button. With + 100ms, the old polling interval, you'll notice + breaks in the repeat sequence corresponding to + lost keypresses. + */ + schedule_timeout((260 * HZ) / 1000); + if (ir->shutdown) { + break; + } + if (!add_to_buf(ir)) { + wake_up_interruptible(&ir->buf.wait_poll); + } + } else { + /* if device not opened so we can sleep half a second */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/2); + } + } while (!ir->shutdown); + + if (ir->t_notify2 != NULL) { + wait_for_completion(ir->t_notify2); + } + + ir->tpid = -1; + if (ir->t_notify != NULL) { + complete(ir->t_notify); + } + + dprintk("poll thread ended\n"); + return 0; +} + +static int set_use_inc(void* data) +{ + struct IR *ir = data; + + if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0) { + return -ENODEV; + } + + /* lock bttv in memory while /dev/lirc is in use */ + /* this is completely broken code. lirc_unregister_plugin() + must be possible even when the device is open */ + if (ir->c_rx.addr) i2c_use_client(&ir->c_rx); + if (ir->c_tx.addr) i2c_use_client(&ir->c_tx); + MOD_INC_USE_COUNT; + + return 0; +} + +static void set_use_dec(void* data) +{ + struct IR *ir = data; + + if (ir->c_rx.addr) i2c_release_client(&ir->c_rx); + if (ir->c_tx.addr) i2c_release_client(&ir->c_tx); + MOD_DEC_USE_COUNT; + if (ir->l.owner != NULL) + module_put(ir->l.owner); +} + +/* safe read of a uint32 (always network byte order) */ +static __inline int read_uint32(unsigned char **data, + unsigned char *endp, unsigned int *val) +{ + if (*data + 4 > endp) + return 0; + *val = ((*data)[0] << 24) | ((*data)[1] << 16) | + ((*data)[2] << 8) | (*data)[3]; + *data += 4; + return 1; +} + +/* safe read of a uint8 */ +static __inline int read_uint8(unsigned char **data, + unsigned char *endp, unsigned char *val) +{ + if (*data + 1 > endp) + return 0; + *val = *((*data)++); + return 1; +} + +/* safe skipping of N bytes */ +static __inline int skip(unsigned char **data, + unsigned char *endp, unsigned int distance) +{ + if (*data + distance > endp) + return 0; + *data += distance; + return 1; +} + +/* decompress key data into the given buffer */ +static int get_key_data(unsigned char *buf, + unsigned int codeset, unsigned int key) +{ + unsigned char *data, *endp, *diffs, *key_block; + unsigned char keys, ndiffs, id; + unsigned int base, lim, pos, i; + + /* Binary search for the codeset */ + for (base = 0, lim = tx_data->num_code_sets; lim; lim >>= 1) { + pos = base + (lim >> 1); + data = tx_data->code_sets[pos]; + + if (!read_uint32(&data, tx_data->endp, &i)) + goto corrupt; + + if (i == codeset) + break; + else if (codeset > i) { + base = pos + 1; + --lim; + } + } + /* Not found? */ + if (!lim) + return -EPROTO; + + /* Set end of data block */ + endp = pos < tx_data->num_code_sets - 1 ? + tx_data->code_sets[pos + 1] : tx_data->endp; + + /* Read the block header */ + if (!read_uint8(&data, endp, &keys) || + !read_uint8(&data, endp, &ndiffs) || + ndiffs > TX_BLOCK_SIZE || keys == 0) + goto corrupt; + + /* Save diffs & skip */ + diffs = data; + if (!skip(&data, endp, ndiffs)) + goto corrupt; + + /* Read the id of the first key */ + if (!read_uint8(&data, endp, &id)) + goto corrupt; + + /* Unpack the first key's data */ + for (i = 0; i < TX_BLOCK_SIZE; ++i) + { + if (tx_data->fixed[i] == -1) + { + if (!read_uint8(&data, endp, &buf[i])) + goto corrupt; + } + else + { + buf[i] = (unsigned char)tx_data->fixed[i]; + } + } + + /* Early out key found/not found */ + if (key == id) + return 0; + if (keys == 1) + return -EPROTO; + + /* Sanity check */ + key_block = data; + if (!skip(&data, endp, (keys - 1) * (ndiffs + 1))) + goto corrupt; + + /* Binary search for the key */ + for (base = 0, lim = keys - 1; lim; lim >>= 1) { + /* Seek to block */ + unsigned char *key_data; + pos = base + (lim >> 1); + key_data = key_block + (ndiffs + 1) * pos; + + if (*key_data == key) { + /* skip key id */ + ++key_data; + + /* found, so unpack the diffs */ + for (i = 0; i < ndiffs; ++i) { + unsigned char val; + if (!read_uint8(&key_data, endp, &val) || + diffs[i] >= TX_BLOCK_SIZE) + goto corrupt; + buf[diffs[i]] = val; + } + + return 0; + } else if (key > *key_data) { + base = pos + 1; + --lim; + } + } + /* Key not found */ + return -EPROTO; + +corrupt: + printk(KERN_ERR "lirc_pvr150: firmware is corrupt\n"); + return -EFAULT; +} + +/* send a block of data to the IR TX device of the PVR-150 */ +static int send_data_block(struct IR *ir, unsigned char *data_block) +{ + int i, j, ret; + unsigned char buf[5]; + + for (i = 0; i < TX_BLOCK_SIZE; ) + { + int tosend = TX_BLOCK_SIZE - i; + if (tosend > 4) + tosend = 4; + buf[0] = (unsigned char)(i + 1); + for (j = 0; j < tosend; ++j) + buf[1 + j] = data_block[i + j]; + dprintk("%02x %02x %02x %02x %02x", + buf[0],buf[1],buf[2],buf[3],buf[4]); + ret = i2c_master_send(&ir->c_tx, buf, tosend + 1); + if (ret != tosend + 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", + ret); + return ret < 0 ? ret : -EFAULT; + } + i += tosend; + } + return 0; +} + +/* send boot data to the IR TX device of the PVR-150 */ +static int send_boot_data(struct IR *ir) +{ + int ret; + unsigned char buf[4]; + + /* send the boot block */ + ret = send_data_block(ir, tx_data->boot_data); + if (ret != 0) + return ret; + + /* kick it off? */ + buf[0] = 0x00; + buf[1] = 0x20; + ret = i2c_master_send(&ir->c_tx, buf, 2); + if (ret != 2) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + ret = i2c_master_send(&ir->c_tx, buf, 1); + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* Here comes the firmware version... (hopefully) */ + ret = i2c_master_recv(&ir->c_tx, buf, 4); + if (ret != 4) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d\n", ret); + return 0; + } + if (buf[0] != 0x80) { + printk(KERN_ERR + "lirc_pvr150: unexpected IR TX response: %02x\n", + buf[0]); + return 0; + } + printk(KERN_INFO + "lirc_pvr150: Hauppauge PVR-150 IR blaster: " + "firmware version %d.%d.%d\n", + buf[1], buf[2], buf[3]); + + return 0; +} + +/* unload "firmware", lock held */ +static void fw_unload_locked(void) +{ + if (tx_data) { + if (tx_data->code_sets) + vfree(tx_data->code_sets); + + if (tx_data->datap) + vfree(tx_data->datap); + + vfree(tx_data); + tx_data = NULL; + dprintk("successfully unloaded PVR-150 IR " + "blaster firmware\n"); + } +} + +/* unload "firmware" for the IR TX device of the PVR-150 */ +static void fw_unload(void) +{ + down(&tx_data_lock); + fw_unload_locked(); + up(&tx_data_lock); +} + +/* load "firmware" for the IR TX device of the PVR-150 */ +static int fw_load(struct IR *ir) +{ + int ret; + unsigned int i; + unsigned char *data, version, num_global_fixed; + const struct firmware *fw_entry = NULL; + + /* Already loaded? */ + down(&tx_data_lock); + if (tx_data) { + ret = 0; + goto out; + } + + /* Request codeset data file */ + ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &ir->c_tx.dev); + if (ret != 0) { + printk(KERN_ERR + "lirc_pvr150: firmware haup-ir-blaster.bin " + "not available (%d)\n", ret); + ret = ret < 0 ? ret : -EFAULT; + goto out; + } + printk(KERN_INFO + "lirc_pvr150: firmware of size %zd loaded\n", fw_entry->size); + + /* Parse the file */ + tx_data = vmalloc(sizeof(TX_DATA)); + if (tx_data == NULL) { + printk(KERN_ERR + "lirc_pvr150: out of memory\n"); + release_firmware(fw_entry); + ret = -ENOMEM; + goto out; + } + tx_data->code_sets = NULL; + + /* Copy the data so hotplug doesn't get confused and timeout */ + tx_data->datap = vmalloc(fw_entry->size); + if (tx_data->datap == NULL) { + printk(KERN_ERR + "lirc_pvr150: out of memory\n"); + release_firmware(fw_entry); + vfree(tx_data); + ret = -ENOMEM; + goto out; + } + memcpy(tx_data->datap, fw_entry->data, fw_entry->size); + tx_data->endp = tx_data->datap + fw_entry->size; + release_firmware(fw_entry); fw_entry = NULL; + + /* Check version */ + data = tx_data->datap; + if (!read_uint8(&data, tx_data->endp, &version)) + goto corrupt; + if (version != 1) { + printk(KERN_ERR + "lirc_pvr150: unsupported code set file version (%u, " + "expected 1) -- please upgrade to a newer driver", + version); + fw_unload_locked(); + ret = -EFAULT; + goto out; + } + + /* Save boot block for later */ + tx_data->boot_data = data; + if (!skip(&data, tx_data->endp, TX_BLOCK_SIZE)) + goto corrupt; + + if (!read_uint32(&data, tx_data->endp, + &tx_data->num_code_sets)) + goto corrupt; + + printk(KERN_INFO + "lirc_pvr150: %u codesets loaded\n", tx_data->num_code_sets); + + tx_data->code_sets = vmalloc( + tx_data->num_code_sets * sizeof(char *)); + if (tx_data->code_sets == NULL) { + fw_unload_locked(); + ret = -ENOMEM; + goto out; + } + + for (i = 0; i < TX_BLOCK_SIZE; ++i) + tx_data->fixed[i] = -1; + + /* Read global fixed data template */ + if (!read_uint8(&data, tx_data->endp, &num_global_fixed) || + num_global_fixed > TX_BLOCK_SIZE) + goto corrupt; + for (i = 0; i < num_global_fixed; ++i) { + unsigned char pos, val; + if (!read_uint8(&data, tx_data->endp, &pos) || + !read_uint8(&data, tx_data->endp, &val) || + pos >= TX_BLOCK_SIZE) { + goto corrupt; + } + tx_data->fixed[pos] = (int)val; + } + + /* Filch out the position of each code set */ + for (i = 0; i < tx_data->num_code_sets; ++i) { + unsigned int id; + unsigned char keys; + unsigned char ndiffs; + + /* Save the codeset position */ + tx_data->code_sets[i] = data; + + /* Read header */ + if (!read_uint32(&data, tx_data->endp, &id) || + !read_uint8(&data, tx_data->endp, &keys) || + !read_uint8(&data, tx_data->endp, &ndiffs) || + ndiffs > TX_BLOCK_SIZE || keys == 0) + goto corrupt; + + /* skip diff positions */ + if (!skip(&data, tx_data->endp, ndiffs)) + goto corrupt; + + /* After the diffs we have the first key id + data - + global fixed */ + if (!skip(&data, tx_data->endp, + 1 + TX_BLOCK_SIZE - num_global_fixed)) + goto corrupt; + + /* Then we have keys-1 blocks of key id+diffs */ + if (!skip(&data, tx_data->endp, + (ndiffs + 1) * (keys - 1))) + goto corrupt; + } + ret = 0; + goto out; + +corrupt: + printk(KERN_ERR "lirc_pvr150: firmware is corrupt\n"); + fw_unload_locked(); + ret = -EFAULT; + +out: + up(&tx_data_lock); + return ret; +} + +/* initialise the IR TX device of the PVR-150 */ +static int tx_init(struct IR *ir) +{ + int ret; + + /* Load 'firmware' */ + ret = fw_load(ir); + if (ret != 0) + return ret; + + /* Send boot block */ + ret = send_boot_data(ir); + if (ret != 0) + return ret; + ir->need_boot = 0; + + /* Looks good */ + return 0; +} + +/* do nothing stub to make LIRC happy */ +static loff_t lseek(struct file *filep,loff_t offset,int orig) +{ + return(-ESPIPE); +} + +/* copied from lirc_dev */ +static ssize_t read(struct file *filep,char *outbuf,size_t n,loff_t *ppos) +{ + struct IR *ir = (struct IR *)filep->private_data; + unsigned char buf[ir->buf.chunk_size]; + int ret=0, written=0; + DECLARE_WAITQUEUE(wait, current); + + dprintk("read called\n"); + if (ir->c_rx.addr == 0) + return -ENODEV; + + if (down_interruptible(&ir->buf_sem)) + return -ERESTARTSYS; + + if (n % ir->buf.chunk_size) { + dprintk("read result = -EINVAL\n"); + up(&ir->buf_sem); + return -EINVAL; + } + + /* we add ourselves to the task queue before buffer check + * to avoid losing scan code (in case when queue is awaken somewhere + * beetwen while condition checking and scheduling) + */ + add_wait_queue(&ir->buf.wait_poll, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + /* while we did't provide 'length' bytes, device is opened in blocking + * mode and 'copy_to_user' is happy, wait for data. + */ + while (written < n && ret == 0) { + if (lirc_buffer_empty(&ir->buf)) { + /* According to the read(2) man page, 'written' can be + * returned as less than 'n', instead of blocking + * again, returning -EWOULDBLOCK, or returning + * -ERESTARTSYS */ + if (written) break; + if (filep->f_flags & O_NONBLOCK) { + ret = -EWOULDBLOCK; + break; + } + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } else { + lirc_buffer_read_1(&ir->buf, buf); + ret = copy_to_user((void *)outbuf+written, buf, + ir->buf.chunk_size); + written += ir->buf.chunk_size; + } + } + + remove_wait_queue(&ir->buf.wait_poll, &wait); + set_current_state(TASK_RUNNING); + up(&ir->buf_sem); + + dprintk("read result = %s (%d)\n", + ret ? "-EFAULT" : "OK", ret); + + return ret ? ret : written; +} + +/* send a keypress to the IR TX device of the PVR-150 */ +static int send_code(struct IR *ir, unsigned int code, unsigned int key) +{ + unsigned char data_block[TX_BLOCK_SIZE]; + unsigned char buf[2]; + int i, ret; + + /* Get data for the codeset/key */ + ret = get_key_data(data_block, code, key); + + if (ret == -EPROTO) { + printk(KERN_ERR + "lirc_pvr150: failed to get data for code %u, " + "key %u -- check lircd.conf entries\n", + code, key); + return ret; + } else if (ret != 0) + return ret; + + /* Send the data block */ + ret = send_data_block(ir, data_block); + if (ret != 0) + return ret; + + /* Send data block length? */ + buf[0] = 0x00; + buf[1] = 0x40; + ret = i2c_master_send(&ir->c_tx, buf, 2); + if (ret != 2) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + ret = i2c_master_send(&ir->c_tx, buf, 1); + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* Send finished download? */ + ret = i2c_master_recv(&ir->c_tx, buf, 1); + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + if (buf[0] != 0xA0) { + printk(KERN_ERR + "lirc_pvr150: unexpected IR TX response #1: %02x\n", + buf[0]); + return ret < 0 ? ret : -EFAULT; + } + + /* Send prepare command? */ + buf[0] = 0x00; + buf[1] = 0x80; + ret = i2c_master_send(&ir->c_tx, buf, 2); + if (ret != 2) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* This bit NAKs until the device is ready, so we retry it + sleeping a bit each time. This seems to be what the windows + driver does, approximately. + Try for up to 1s. + */ + for (i = 0; i < 20; ++i) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((50 * HZ + 999) / 1000); + ret = i2c_master_send(&ir->c_tx, buf, 1); + if (ret == 1) + break; + dprintk("NAK expected: i2c_master_send " + "failed with %d (try %d)\n", ret, i+1); + } + if (ret != 1) { + printk(KERN_ERR + "lirc_pvr150: IR TX chip never got ready: last " + "i2c_master_send failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + + /* Seems to be an 'ok' response */ + i = i2c_master_recv(&ir->c_tx, buf, 1); + if (i != 1) { + printk(KERN_ERR + "lirc_pvr150: i2c_master_recv failed with %d\n", ret); + return ret < 0 ? ret : -EFAULT; + } + if (buf[0] != 0x80) { + printk(KERN_ERR + "lirc_pvr150: unexpected IR TX response #2: %02x\n", + buf[0]); + return -EFAULT; + } + + /* Oh good, it worked */ + dprintk("sent code %u, key %u\n", code, key); + return 0; +} + +/* Write a code to the device. We take in a 32-bit number (a lirc_t) and then + decode this to a codeset/key index. The key data is then decompressed and + sent to the device. We have a spin lock as per i2c documentation to prevent + multiple concurrent sends which would probably cause the device to explode. + */ +static ssize_t write(struct file *filep,const char *buf,size_t n, + loff_t *ppos) +{ + struct IR *ir = (struct IR *)filep->private_data; + size_t i; + int failures = 0; + + if (ir->c_tx.addr == 0) + return -ENODEV; + + /* Validate user parameters */ + if (n % sizeof(lirc_t)) + return(-EINVAL); + + /* Lock i2c bus for the duration */ + down(&ir->lock); + + /* Send each keypress */ + for (i = 0; i < n; ) + { + int ret = 0; + lirc_t command; + + if (copy_from_user(&command, buf + i, sizeof(command))) { + up(&ir->lock); + return -EFAULT; + } + + /* Send boot data first if required */ + if (ir->need_boot == 1) + { + ret = send_boot_data(ir); + if (ret == 0) + ir->need_boot = 0; + } + + /* Send the code */ + if (ret == 0) { + ret = send_code(ir, (unsigned)command >> 16, + (unsigned)command & 0xFFFF); + if (ret == -EPROTO) { + up(&ir->lock); + return ret; + } + } + + /* Hmm, a failure. If we've had a few then give up, otherwise + try a reset + */ + if (ret != 0) { + /* Looks like the chip crashed, reset it */ + printk(KERN_ERR "lirc_pvr150: sending to the IR " + "transmitter chip failed, trying " + "reset\n"); + + if (failures >= 3) { + printk(KERN_ERR "lirc_pvr150: unable to send " + "to the IR chip after 3 " + "resets, giving up\n"); + up(&ir->lock); + return ret; + } + ivtv_reset_ir_gpio(i2c_get_adapdata(ir->c_tx.adapter)); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((100 * HZ + 999) / 1000); + ir->need_boot = 1; + ++failures; + } + else + { + i += sizeof(lirc_t); + } + } + + /* Release i2c bus */ + up(&ir->lock); + + /* All looks good */ + return n; +} + +/* copied from lirc_dev */ +static unsigned int poll(struct file *filep, poll_table * wait) +{ + struct IR *ir = (struct IR *)filep->private_data; + unsigned int ret; + + dprintk("poll called\n"); + if (ir->c_rx.addr == 0) + return -ENODEV; + + down(&ir->buf_sem); + + poll_wait(filep, &ir->buf.wait_poll, wait); + + dprintk("poll result = %s\n", + lirc_buffer_empty(&ir->buf) ? "0" : "POLLIN|POLLRDNORM"); + + ret = lirc_buffer_empty(&ir->buf) ? 0 : (POLLIN|POLLRDNORM); + + up(&ir->buf_sem); + return ret; +} + +static int ioctl(struct inode *node,struct file *filep,unsigned int cmd, + unsigned long arg) +{ + struct IR *ir = (struct IR *)filep->private_data; + int result; + unsigned long mode, features = 0; + + if (ir->c_rx.addr != 0) + features |= LIRC_CAN_REC_LIRCCODE; + if (ir->c_tx.addr != 0) + features |= LIRC_CAN_SEND_PULSE; + + switch(cmd) + { + case LIRC_GET_LENGTH: + result = put_user((unsigned long)13, + (unsigned long *)arg); + break; + case LIRC_GET_FEATURES: + result=put_user(features,(unsigned long *) arg); + if(result) return(result); + break; + case LIRC_GET_REC_MODE: + if(!(features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = put_user(LIRC_REC2MODE + (features&LIRC_CAN_REC_MASK), + (unsigned long*)arg); + break; + case LIRC_SET_REC_MODE: + if(!(features&LIRC_CAN_REC_MASK)) + return -ENOSYS; + + result = get_user(mode, (unsigned long*)arg); + if(!result && !(LIRC_MODE2REC(mode) & features)) { + result = -EINVAL; + } + break; + case LIRC_GET_SEND_MODE: + if(!(features&LIRC_CAN_SEND_MASK)) + return -ENOSYS; + + result=put_user(LIRC_MODE_PULSE,(unsigned long *) arg); + if(result) return(result); + break; + case LIRC_SET_SEND_MODE: + if(!(features&LIRC_CAN_SEND_MASK)) + return -ENOSYS; + + result=get_user(mode,(unsigned long *) arg); + if(result) return(result); + if(mode!=LIRC_MODE_PULSE) return(-EINVAL); + break; + default: + return(-ENOIOCTLCMD); + } + return (0); +} + +/* Open the IR device of the PVR-150. Get hold of our IR structure and + stash it in private_data for the file */ +static int open(struct inode* node,struct file* filep) +{ + struct IR *ir; + int ret; + + /* find our IR struct */ + unsigned minor = MINOR(node->i_rdev); + if (minor >= MAX_IRCTL_DEVICES) { + dprintk("minor %d: open result = -ENODEV\n", + minor); + return -ENODEV; + } + ir = ir_devices[minor]; + + /* increment in use count */ + down(&ir->lock); + ++ir->open; + ret = set_use_inc(ir); + if (ret != 0) { + --ir->open; + up(&ir->lock); + return ret; + } + up(&ir->lock); + + /* stash our IR struct */ + filep->private_data = ir; + + return(0); +} + +/* Close the IR device of the PVR-150 */ +static int close(struct inode* node,struct file* filep) +{ + /* find our IR struct */ + struct IR *ir = (struct IR *)filep->private_data; + if (ir == NULL) { + printk(KERN_ERR + "lirc_pvr150: close: no private_data " + "attached to the file!\n"); + return -ENODEV; + } + + /* decrement in use count */ + down(&ir->lock); + --ir->open; + set_use_dec(ir); + up(&ir->lock); + + return(0); +} + +static struct lirc_plugin lirc_template = { + name: "lirc_pvr150", + set_use_inc: set_use_inc, + set_use_dec: set_use_dec, + owner: THIS_MODULE +}; + +/* ----------------------------------------------------------------------- */ + +static int ir_attach(struct i2c_adapter *adap, int have_rx, int have_tx); +static int ir_detach(struct i2c_client *client); +static int ir_probe(struct i2c_adapter *adap); +static int ir_command(struct i2c_client *client, unsigned int cmd, void *arg); + +static struct i2c_driver driver = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 16) + name: "i2c ir driver", + flags: I2C_DF_NOTIFY, +#else + .driver = { + owner: THIS_MODULE, + name: "i2c ir driver", + }, +#endif + id: I2C_DRIVERID_EXP3, /* FIXME */ + attach_adapter: ir_probe, + detach_client: ir_detach, + command: ir_command, +}; + +static struct i2c_client client_template = +{ + name: "unset", + driver: &driver +}; + +static struct file_operations lirc_fops = +{ + llseek: lseek, + read: read, + write: write, + poll: poll, + ioctl: ioctl, + open: open, + release: close +}; + +static int i2c_attach(struct i2c_client *client, struct IR *ir) +{ + int ret; + + i2c_set_clientdata(client, ir); + + ret = i2c_attach_client(client); + if (ret != 0) { + client->addr = 0; + return ret; + } + if (i2c_use_client(client) == NULL) { + i2c_detach_client(client); + client->addr = 0; + return ret; + } + ++ir->devs; + return 0; +} + +static int ir_attach(struct i2c_adapter *adap, int have_rx, int have_tx) +{ + struct IR *ir; + int ret, i; + + printk("lirc_pvr150: chip found with %s\n", + have_rx && have_tx ? "RX and TX" : + have_rx ? "RX only" : "TX only"); + + if (NULL == (ir = kmalloc(sizeof(struct IR),GFP_KERNEL))) + return -ENOMEM; + if (lirc_buffer_init(&ir->buf, 2, BUFLEN/2) != 0) { + kfree(ir); + return -ENOMEM; + } + init_MUTEX(&ir->lock); + init_MUTEX(&ir->buf_sem); + ir->open = 0; + ir->devs = 0; + ir->tpid = 0; + ir->need_boot = 1; + ir->shutdown = 0; + ir->t_notify = ir->t_notify2 = NULL; + for (i = 0; i < sizeof(ir->b); ++i) + ir->b[0] = 0; + + memcpy(&ir->l,&lirc_template,sizeof(struct lirc_plugin)); + ir->l.minor = -1; + + /* initialise RX device */ + client_template.adapter = adap; + memcpy(&ir->c_rx,&client_template,sizeof(struct i2c_client)); + if (have_rx) { + DECLARE_COMPLETION(tn); + + /* I2C attach to device */ + ir->c_rx.addr = 0x71; + strlcpy(ir->c_rx.name, "Hauppauge PVR150 RX", + sizeof(ir->c_rx.name)); + if ( (ret = i2c_attach(&ir->c_rx, ir)) != 0 ) + goto err; + + /* try to fire up polling thread */ + ir->t_notify = &tn; + ir->tpid = kernel_thread(lirc_thread, ir, 0); + if (ir->tpid < 0) { + printk(KERN_ERR "lirc_pvr150: lirc_register_plugin: " + "cannot run poll thread\n"); + ret = -ECHILD; + goto err; + } + wait_for_completion(&tn); + ir->t_notify = NULL; + } + + /* initialise TX device */ + memcpy(&ir->c_tx,&client_template,sizeof(struct i2c_client)); + if (have_tx) { + /* I2C attach to device */ + ir->c_tx.addr = 0x70; + strlcpy(ir->c_tx.name, "Hauppauge PVR150 TX", + sizeof(ir->c_tx.name)); + if ( (ret = i2c_attach(&ir->c_tx, ir)) != 0 ) + goto err; + } + + /* set lirc_dev stuff */ + ir->l.code_length = 13; + ir->l.rbuf = &ir->buf; + ir->l.fops = &lirc_fops; + ir->l.data = ir; + ir->l.minor = minor; + ir->l.sample_rate = 0; + + /* register with lirc */ + ir->l.minor = lirc_register_plugin(&ir->l); + if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { + printk(KERN_ERR + "lirc_pvr150: ir_attach: " + "\"minor\" must be between 0 and %d (%d)!\n", + MAX_IRCTL_DEVICES-1, ir->l.minor); + ret = -EBADRQC; + goto err; + } + + /* store this for getting back in open() later on */ + ir_devices[ir->l.minor] = ir; + + /* if we have the tx device, load the 'firmware'. We do this + after registering with lirc as otherwise hotplug seems to take + 10s to create the lirc device. + */ + if (have_tx) { + /* Special TX init */ + ret = tx_init(ir); + if (ret != 0) + goto err; + } + return 0; + +err: + /* undo everything, hopefully... */ + if (ir->c_rx.addr) ir_detach(&ir->c_rx); + if (ir->c_tx.addr) ir_detach(&ir->c_tx); + return ret; +} + +static int ir_detach(struct i2c_client *client) +{ + struct IR *ir = i2c_get_clientdata(client); + down(&ir->lock); + + if (client == &ir->c_rx) { + DECLARE_COMPLETION(tn); + DECLARE_COMPLETION(tn2); + + /* end up polling thread */ + if (ir->tpid >= 0) { + ir->t_notify = &tn; + ir->t_notify2 = &tn2; + ir->shutdown = 1; + { + struct task_struct *p; + p = find_task_by_pid_ns(ir->tpid, &init_pid_ns); + wake_up_process(p); + } + complete(&tn2); + wait_for_completion(&tn); + ir->t_notify = NULL; + ir->t_notify2 = NULL; + } + + /* unregister device */ + i2c_release_client(&ir->c_rx); + i2c_detach_client(&ir->c_rx); + } else if (client == &ir->c_tx) { + i2c_release_client(&ir->c_tx); + i2c_detach_client(&ir->c_tx); + } else { + up(&ir->lock); + printk(KERN_ERR "lirc_pvr150: ir_detach: detached from " + "something we didn't attach to\n"); + return -ENODEV; + } + + --ir->devs; + if (ir->devs < 0) + { + up(&ir->lock); + printk(KERN_ERR "lirc_pvr150: ir_detach: invalid " + "device count\n"); + return -ENODEV; + } + else if (ir->devs == 0) + { + /* unregister lirc plugin */ + if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) + { + lirc_unregister_plugin(ir->l.minor); + ir_devices[ir->l.minor] = NULL; + } + + /* free memory */ + lirc_buffer_free(&ir->buf); + up(&ir->lock); + kfree(ir); + return 0; + } + up(&ir->lock); + return 0; +} + +static int ir_probe(struct i2c_adapter *adap) +{ + struct i2c_client c; + char buf; + +#ifdef I2C_HW_B_CX2341X + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848) || + adap->id == (I2C_ALGO_BIT | I2C_HW_B_CX2341X)) +#else + if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848)) +#endif + { + int have_rx = 0, have_tx = 0; + + /* The external IR receiver is at i2c address 0x71 on the PVR-150 + The IR transmitter is at 0x70. + */ + memset(&c,0,sizeof(c)); + c.adapter = adap; + c.addr = 0x70; + + if (!disable_rx) { + if (i2c_master_recv(&c,&buf,1) == 1) + have_rx = 1; + dprintk("probe 0x70 @ %s: %s\n", + adap->name, + have_rx ? "yes" : "no"); + } + + if (!disable_tx) { + c.addr = 0x71; + if (i2c_master_recv(&c,&buf,1) == 1) + have_tx = 1; + dprintk("probe 0x71 @ %s: %s\n", + adap->name, + have_tx ? "yes" : "no"); + } + + if (have_rx || have_tx) + return ir_attach(adap, have_rx, have_tx); + else + { + printk(KERN_ERR "lirc_pvr150: %s: no devices found\n", adap->name); + } + } + + return 0; +} + +static int ir_command(struct i2c_client *client,unsigned int cmd, void *arg) +{ + /* nothing */ + return 0; +} + +/* ----------------------------------------------------------------------- */ +#ifdef MODULE + +int init_module(void) +{ + init_MUTEX(&tx_data_lock); + request_module("ivtv"); + request_module("firmware_class"); + i2c_add_driver(&driver); + return 0; +} + +void cleanup_module(void) +{ + i2c_del_driver(&driver); + /* if loaded */ + fw_unload(); +} + +MODULE_DESCRIPTION("Infrared receiver driver for Hauppauge PVR-150 card (i2c stack)"); +MODULE_AUTHOR("Gerd Knorr, Michal Kochanowicz, Christoph Bartelmus, Ulrich Mueller, Stefan Jahn, Jerome Brock, Mark Weaver"); +MODULE_LICENSE("GPL"); + +module_param(minor, int, 0444); +MODULE_PARM_DESC(minor, "Preferred minor device number"); + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +module_param(disable_rx, bool, 0644); +MODULE_PARM_DESC(disable_rx, "Disable the IR receiver device"); + +module_param(disable_tx, bool, 0644); +MODULE_PARM_DESC(disable_tx, "Disable the IR transmitter device"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ + +/* + * Overrides for Emacs so that we follow Linus's tabbing style. + * --------------------------------------------------------------------------- + * Local variables: + * c-basic-offset: 8 + * End: + */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_pvr150/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_pvr150/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_PVR150) += lirc_pvr150.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_sir/lirc_sir.c +++ linux-2.6.28/ubuntu/lirc/lirc_sir/lirc_sir.c @@ -0,0 +1,1323 @@ +/* + * LIRC SIR driver, (C) 2000 Milan Pikula + * + * lirc_sir - Device driver for use with SIR (serial infra red) + * mode of IrDA on many notebooks. + * + * 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 + * + * + * 2000/09/16 Frank Przybylski : + * added timeout and relaxed pulse detection, removed gap bug + * + * 2000/12/15 Christoph Bartelmus : + * added support for Tekram Irmate 210 (sending does not work yet, + * kind of disappointing that nobody was able to implement that + * before), + * major clean-up + * + * 2001/02/27 Christoph Bartelmus : + * added support for StrongARM SA1100 embedded microprocessor + * parts cut'n'pasted from sa1100_ir.c (C) 2000 Russell King + */ + + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef LIRC_ON_SA1100 +#include +#ifdef CONFIG_SA1100_COLLIE +#include +#include +#endif +#endif + +#include + +#include "lirc.h" +#include "lirc_dev/lirc_dev.h" +#include "kcompat.h" + +/* SECTION: Definitions */ + +/**************************** Tekram dongle ***************************/ +#ifdef LIRC_SIR_TEKRAM +/* stolen from kernel source */ +/* definitions for Tekram dongle */ +#define TEKRAM_115200 0x00 +#define TEKRAM_57600 0x01 +#define TEKRAM_38400 0x02 +#define TEKRAM_19200 0x03 +#define TEKRAM_9600 0x04 +#define TEKRAM_2400 0x08 + +#define TEKRAM_PW 0x10 /* Pulse select bit */ + +/* 10bit * 1s/115200bit in miliseconds = 87ms*/ +#define TIME_CONST (10000000ul/115200ul) + +#endif + +#ifdef LIRC_SIR_ACTISYS_ACT200L +static void init_act200(void); +#elif defined(LIRC_SIR_ACTISYS_ACT220L) +static void init_act220(void); +#endif + +/******************************* SA1100 ********************************/ +#ifdef LIRC_ON_SA1100 +struct sa1100_ser2_registers { + /* HSSP control register */ + unsigned char hscr0; + /* UART registers */ + unsigned char utcr0; + unsigned char utcr1; + unsigned char utcr2; + unsigned char utcr3; + unsigned char utcr4; + unsigned char utdr; + unsigned char utsr0; + unsigned char utsr1; +} sr; + +static int irq = IRQ_Ser2ICP; + +#define LIRC_ON_SA1100_TRANSMITTER_LATENCY 0 + +/* pulse/space ratio of 50/50 */ +static unsigned long pulse_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY); +/* 1000000/freq-pulse_width */ +static unsigned long space_width = (13-LIRC_ON_SA1100_TRANSMITTER_LATENCY); +static unsigned int freq = 38000; /* modulation frequency */ +static unsigned int duty_cycle = 50; /* duty cycle of 50% */ + +#endif + +#define RBUF_LEN 1024 +#define WBUF_LEN 1024 + +#define LIRC_DRIVER_NAME "lirc_sir" + +#define PULSE '[' + +#ifndef LIRC_SIR_TEKRAM +/* 9bit * 1s/115200bit in milli seconds = 78.125ms*/ +#define TIME_CONST (9000000ul/115200ul) +#endif + + +/* timeout for sequences in jiffies (=5/100s) */ +/* must be longer than TIME_CONST */ +#define SIR_TIMEOUT (HZ*5/100) + +#ifndef LIRC_ON_SA1100 +#ifndef LIRC_IRQ +#define LIRC_IRQ 4 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x3e8 +#endif + +static int io = LIRC_PORT; +static int irq = LIRC_IRQ; +static int threshold = 3; +#endif + +static DEFINE_SPINLOCK(timer_lock); +static struct timer_list timerlist; +/* time of last signal change detected */ +static struct timeval last_tv = {0, 0}; +/* time of last UART data ready interrupt */ +static struct timeval last_intr_tv = {0, 0}; +static int last_value; + +static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue); + +static DEFINE_SPINLOCK(hardware_lock); +static DEFINE_SPINLOCK(dev_lock); + +static lirc_t rx_buf[RBUF_LEN]; +static unsigned int rx_tail, rx_head; +static lirc_t tx_buf[WBUF_LEN]; + +static int debug; +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +/* SECTION: Prototypes */ + +/* Communication with user-space */ +static int lirc_open(struct inode *inode, struct file *file); +static int lirc_close(struct inode *inode, struct file *file); +static unsigned int lirc_poll(struct file *file, poll_table *wait); +static ssize_t lirc_read(struct file *file, char *buf, size_t count, + loff_t *ppos); +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, + loff_t *pos); +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg); +static void add_read_queue(int flag, unsigned long val); +#ifdef MODULE +static int init_chrdev(void); +static void drop_chrdev(void); +#endif + /* Hardware */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t sir_interrupt(int irq, void *dev_id, + struct pt_regs *regs); +#else +static irqreturn_t sir_interrupt(int irq, void *dev_id); +#endif +static void send_space(unsigned long len); +static void send_pulse(unsigned long len); +static int init_hardware(void); +static void drop_hardware(void); + /* Initialisation */ +static int init_port(void); +static void drop_port(void); +int init_module(void); +void cleanup_module(void); + +#ifdef LIRC_ON_SA1100 +static inline void on(void) +{ + PPSR |= PPC_TXD2; +} + +static inline void off(void) +{ + PPSR &= ~PPC_TXD2; +} +#else +static inline unsigned int sinp(int offset) +{ + return inb(io + offset); +} + +static inline void soutp(int offset, int value) +{ + outb(value, io + offset); +} +#endif + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +/* SECTION: Communication with user-space */ + +static int lirc_open(struct inode *inode, struct file *file) +{ + spin_lock(&dev_lock); + if (MOD_IN_USE) { + spin_unlock(&dev_lock); + return -EBUSY; + } + MOD_INC_USE_COUNT; + spin_unlock(&dev_lock); + return 0; +} + +static int lirc_close(struct inode *inode, struct file *file) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +static unsigned int lirc_poll(struct file *file, poll_table *wait) +{ + poll_wait(file, &lirc_read_queue, wait); + if (rx_head != rx_tail) + return POLLIN | POLLRDNORM; + return 0; +} + +static ssize_t lirc_read(struct file *file, char *buf, size_t count, + loff_t *ppos) +{ + int n = 0; + int retval = 0; + DECLARE_WAITQUEUE(wait, current); + + if (n % sizeof(lirc_t)) + return -EINVAL; + + add_wait_queue(&lirc_read_queue, &wait); + set_current_state(TASK_INTERRUPTIBLE); + while (n < count) { + if (rx_head != rx_tail) { + if (copy_to_user((void *) buf + n, + (void *) (rx_buf + rx_head), + sizeof(lirc_t))) { + retval = -EFAULT; + break; + } + rx_head = (rx_head + 1) & (RBUF_LEN - 1); + n += sizeof(lirc_t); + } else { + if (file->f_flags & O_NONBLOCK) { + retval = -EAGAIN; + break; + } + if (signal_pending(current)) { + retval = -ERESTARTSYS; + break; + } + schedule(); + set_current_state(TASK_INTERRUPTIBLE); + } + } + remove_wait_queue(&lirc_read_queue, &wait); + set_current_state(TASK_RUNNING); + return (n ? n : retval); +} +static ssize_t lirc_write(struct file *file, const char *buf, size_t n, + loff_t *pos) +{ + unsigned long flags; + int i; + + if (n % sizeof(lirc_t) || (n/sizeof(lirc_t)) > WBUF_LEN) + return -EINVAL; + if (copy_from_user(tx_buf, buf, n)) + return -EFAULT; + i = 0; + n /= sizeof(lirc_t); +#ifdef LIRC_ON_SA1100 + /* disable receiver */ + Ser2UTCR3 = 0; +#endif + local_irq_save(flags); + while (1) { + if (i >= n) + break; + if (tx_buf[i]) + send_pulse(tx_buf[i]); + i++; + if (i >= n) + break; + if (tx_buf[i]) + send_space(tx_buf[i]); + i++; + } + local_irq_restore(flags); +#ifdef LIRC_ON_SA1100 + off(); + udelay(1000); /* wait 1ms for IR diode to recover */ + Ser2UTCR3 = 0; + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + /* enable receiver */ + Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE; +#endif + return n; +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int retval = 0; + unsigned long value = 0; +#ifdef LIRC_ON_SA1100 + unsigned int ivalue; + + if (cmd == LIRC_GET_FEATURES) + value = LIRC_CAN_SEND_PULSE | + LIRC_CAN_SET_SEND_DUTY_CYCLE | + LIRC_CAN_SET_SEND_CARRIER | + LIRC_CAN_REC_MODE2; + else if (cmd == LIRC_GET_SEND_MODE) + value = LIRC_MODE_PULSE; + else if (cmd == LIRC_GET_REC_MODE) + value = LIRC_MODE_MODE2; +#else + if (cmd == LIRC_GET_FEATURES) + value = LIRC_CAN_SEND_PULSE | LIRC_CAN_REC_MODE2; + else if (cmd == LIRC_GET_SEND_MODE) + value = LIRC_MODE_PULSE; + else if (cmd == LIRC_GET_REC_MODE) + value = LIRC_MODE_MODE2; +#endif + + switch (cmd) { + case LIRC_GET_FEATURES: + case LIRC_GET_SEND_MODE: + case LIRC_GET_REC_MODE: + retval = put_user(value, (unsigned long *) arg); + break; + + case LIRC_SET_SEND_MODE: + case LIRC_SET_REC_MODE: + retval = get_user(value, (unsigned long *) arg); + break; +#ifdef LIRC_ON_SA1100 + case LIRC_SET_SEND_DUTY_CYCLE: + retval = get_user(ivalue, (unsigned int *) arg); + if (retval) + return reetval; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + /* (ivalue/100)*(1000000/freq) */ + duty_cycle = ivalue; + pulse_width = (unsigned long) duty_cycle*10000/freq; + space_width = (unsigned long) 1000000L/freq-pulse_width; + if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + break; + case LIRC_SET_SEND_CARRIER: + retval = get_user(ivalue, (unsigned int *) arg); + if (retval) + return retval; + if (ivalue > 500000 || ivalue < 20000) + return -EINVAL; + freq = ivalue; + pulse_width = (unsigned long) duty_cycle*10000/freq; + space_width = (unsigned long) 1000000L/freq-pulse_width; + if (pulse_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + pulse_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + if (space_width >= LIRC_ON_SA1100_TRANSMITTER_LATENCY) + space_width -= LIRC_ON_SA1100_TRANSMITTER_LATENCY; + break; +#endif + default: + retval = -ENOIOCTLCMD; + + } + + if (retval) + return retval; + if (cmd == LIRC_SET_REC_MODE) { + if (value != LIRC_MODE_MODE2) + retval = -ENOSYS; + } else if (cmd == LIRC_SET_SEND_MODE) { + if (value != LIRC_MODE_PULSE) + retval = -ENOSYS; + } + + return retval; +} + +static void add_read_queue(int flag, unsigned long val) +{ + unsigned int new_rx_tail; + lirc_t newval; + + dprintk("add flag %d with val %lu\n", flag, val); + + newval = val & PULSE_MASK; + + /* statistically pulses are ~TIME_CONST/2 too long: we could + maybe make this more exactly but this is good enough */ + if (flag) { + /* pulse */ + if (newval > TIME_CONST/2) + newval -= TIME_CONST/2; + else /* should not ever happen */ + newval = 1; + newval |= PULSE_BIT; + } else { + newval += TIME_CONST/2; + } + new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1); + if (new_rx_tail == rx_head) { + dprintk("Buffer overrun.\n"); + return; + } + rx_buf[rx_tail] = newval; + rx_tail = new_rx_tail; + wake_up_interruptible(&lirc_read_queue); +} + +static struct file_operations lirc_fops = { + .read = lirc_read, + .write = lirc_write, + .poll = lirc_poll, + .ioctl = lirc_ioctl, + .open = lirc_open, + .release = lirc_close, +}; + +static int set_use_inc(void *data) +{ + return 0; +} + +static void set_use_dec(void *data) +{ +} +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + + +#ifdef MODULE +static int init_chrdev(void) +{ + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n"); + return -EIO; + } + return 0; +} + +static void drop_chrdev(void) +{ + lirc_unregister_plugin(plugin.minor); +} +#endif + +/* SECTION: Hardware */ +static long delta(struct timeval *tv1, struct timeval *tv2) +{ + unsigned long deltv; + + deltv = tv2->tv_sec - tv1->tv_sec; + if (deltv > 15) + deltv = 0xFFFFFF; + else + deltv = deltv*1000000 + + tv2->tv_usec - + tv1->tv_usec; + return deltv; +} + +static void sir_timeout(unsigned long data) +{ + /* if last received signal was a pulse, but receiving stopped + within the 9 bit frame, we need to finish this pulse and + simulate a signal change to from pulse to space. Otherwise + upper layers will receive two sequences next time. */ + + unsigned long flags; + unsigned long pulse_end; + + /* avoid interference with interrupt */ + spin_lock_irqsave(&timer_lock, flags); + if (last_value) { +#ifndef LIRC_ON_SA1100 + /* clear unread bits in UART and restart */ + outb(UART_FCR_CLEAR_RCVR, io + UART_FCR); +#endif + /* determine 'virtual' pulse end: */ + pulse_end = delta(&last_tv, &last_intr_tv); + dprintk("timeout add %d for %lu usec\n", last_value, pulse_end); + add_read_queue(last_value, pulse_end); + last_value = 0; + last_tv = last_intr_tv; + } + spin_unlock_irqrestore(&timer_lock, flags); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19) +static irqreturn_t sir_interrupt(int irq, void *dev_id, + struct pt_regs *regs) +#else +static irqreturn_t sir_interrupt(int irq, void *dev_id) +#endif +{ + unsigned char data; + struct timeval curr_tv; + static unsigned long deltv; +#ifdef LIRC_ON_SA1100 + int status; + static int n; + + status = Ser2UTSR0; + /* + * Deal with any receive errors first. The bytes in error may be + * the only bytes in the receive FIFO, so we do this first. + */ + while (status & UTSR0_EIF) { + int bstat; + + if (debug) { + dprintk("EIF\n"); + bstat = Ser2UTSR1; + + if (bstat & UTSR1_FRE) + dprintk("frame error\n"); + if (bstat & UTSR1_ROR) + dprintk("receive fifo overrun\n"); + if (bstat & UTSR1_PRE) + dprintk("parity error\n"); + } + + bstat = Ser2UTDR; + n++; + status = Ser2UTSR0; + } + + if (status & (UTSR0_RFS | UTSR0_RID)) { + do_gettimeofday(&curr_tv); + deltv = delta(&last_tv, &curr_tv); + do { + data = Ser2UTDR; + dprintk("%d data: %u\n", n, (unsigned int) data); + n++; + } while (status & UTSR0_RID && /* do not empty fifo in + order to get UTSR0_RID in + any case */ + Ser2UTSR1 & UTSR1_RNE); /* data ready */ + + if (status&UTSR0_RID) { + add_read_queue(0 , deltv - n * TIME_CONST); /*space*/ + add_read_queue(1, n * TIME_CONST); /*pulse*/ + n = 0; + last_tv = curr_tv; + } + } + + if (status & UTSR0_TFS) + printk(KERN_ERR "transmit fifo not full, shouldn't happen\n"); + + /* + * We must clear certain bits. + */ + status &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + if (status) + Ser2UTSR0 = status; +#else + unsigned long deltintrtv; + unsigned long flags; + int iir, lsr; + + while ((iir = inb(io + UART_IIR) & UART_IIR_ID)) { + switch (iir&UART_IIR_ID) { /* FIXME toto treba preriedit */ + case UART_IIR_MSI: + (void) inb(io + UART_MSR); + break; + case UART_IIR_RLSI: + (void) inb(io + UART_LSR); + break; + case UART_IIR_THRI: +#if 0 + if (lsr & UART_LSR_THRE) /* FIFO is empty */ + outb(data, io + UART_TX) +#endif + break; + case UART_IIR_RDI: + /* avoid interference with timer */ + spin_lock_irqsave(&timer_lock, flags); + do { + del_timer(&timerlist); + data = inb(io + UART_RX); + do_gettimeofday(&curr_tv); + deltv = delta(&last_tv, &curr_tv); + deltintrtv = delta(&last_intr_tv, &curr_tv); + dprintk("t %lu, d %d\n", deltintrtv, (int)data); + /* if nothing came in last X cycles, + it was gap */ + if (deltintrtv > TIME_CONST * threshold) { + if (last_value) { + dprintk("GAP\n"); + /* simulate signal change */ + add_read_queue(last_value, + deltv - + deltintrtv); + last_value = 0; + last_tv.tv_sec = + last_intr_tv.tv_sec; + last_tv.tv_usec = + last_intr_tv.tv_usec; + deltv = deltintrtv; + } + } + data = 1; + if (data ^ last_value) { + /* deltintrtv > 2*TIME_CONST, + remember ? */ + /* the other case is timeout */ + add_read_queue(last_value, + deltv-TIME_CONST); + last_value = data; + last_tv = curr_tv; + if (last_tv.tv_usec >= TIME_CONST) { + last_tv.tv_usec -= TIME_CONST; + } else { + last_tv.tv_sec--; + last_tv.tv_usec += 1000000 - + TIME_CONST; + } + } + last_intr_tv = curr_tv; + if (data) { + /* start timer for end of + * sequence detection */ + timerlist.expires = jiffies + + SIR_TIMEOUT; + add_timer(&timerlist); + } + } + while ((lsr = inb(io + UART_LSR)) + & UART_LSR_DR); /* data ready */ + spin_unlock_irqrestore(&timer_lock, flags); + break; + default: + break; + } + } +#endif + return IRQ_RETVAL(IRQ_HANDLED); +} + +#ifdef LIRC_ON_SA1100 +static void send_pulse(unsigned long length) +{ + unsigned long k, delay; + int flag; + + if (length == 0) + return; + /* this won't give us the carrier frequency we really want + due to integer arithmetic, but we can accept this inaccuracy */ + + for (k = flag = 0; k < length; k += delay, flag = !flag) { + if (flag) { + off(); + delay = space_width; + } else { + on(); + delay = pulse_width; + } + safe_udelay(delay); + } + off(); +} + +static void send_space(unsigned long length) +{ + if (length == 0) + return; + off(); + safe_udelay(length); +} +#else +static void send_space(unsigned long len) +{ + safe_udelay(len); +} + +static void send_pulse(unsigned long len) +{ + long bytes_out = len / TIME_CONST; + long time_left; + + time_left = (long)len - (long)bytes_out * (long)TIME_CONST; + if (bytes_out == 0) { + bytes_out++; + time_left = 0; + } + while (bytes_out--) { + outb(PULSE, io + UART_TX); + /* FIXME treba seriozne cakanie z drivers/char/serial.c */ + while (!(inb(io + UART_LSR) & UART_LSR_THRE)); + } +#if 0 + if (time_left > 0) + safe_udelay(time_left); +#endif +} +#endif + +#ifdef CONFIG_SA1100_COLLIE +static inline int sa1100_irda_set_power_collie(int state) +{ + if (state) { + /* + * 0 - off + * 1 - short range, lowest power + * 2 - medium range, medium power + * 3 - maximum range, high power + */ + ucb1200_set_io_direction(TC35143_GPIO_IR_ON, + TC35143_IODIR_OUTPUT); + ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_LOW); + udelay(100); + } else { + /* OFF */ + ucb1200_set_io_direction(TC35143_GPIO_IR_ON, + TC35143_IODIR_OUTPUT); + ucb1200_set_io(TC35143_GPIO_IR_ON, TC35143_IODAT_HIGH); + } + return 0; +} +#endif + +static int init_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + /* reset UART */ +#ifdef LIRC_ON_SA1100 +#ifdef CONFIG_SA1100_BITSY + if (machine_is_bitsy()) { + printk(KERN_INFO "Power on IR module\n"); + set_bitsy_egpio(EGPIO_BITSY_IR_ON); + } +#endif +#ifdef CONFIG_SA1100_COLLIE + sa1100_irda_set_power_collie(3); /* power on */ +#endif + sr.hscr0 = Ser2HSCR0; + + sr.utcr0 = Ser2UTCR0; + sr.utcr1 = Ser2UTCR1; + sr.utcr2 = Ser2UTCR2; + sr.utcr3 = Ser2UTCR3; + sr.utcr4 = Ser2UTCR4; + + sr.utdr = Ser2UTDR; + sr.utsr0 = Ser2UTSR0; + sr.utsr1 = Ser2UTSR1; + + /* configure GPIO */ + /* output */ + PPDR |= PPC_TXD2; + PSDR |= PPC_TXD2; + /* set output to 0 */ + off(); + + /* + * Enable HP-SIR modulation, and ensure that the port is disabled. + */ + Ser2UTCR3 = 0; + Ser2HSCR0 = sr.hscr0 & (~HSCR0_HSSP); + + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + + /* 7N1 */ + Ser2UTCR0 = UTCR0_1StpBit|UTCR0_7BitData; + /* 115200 */ + Ser2UTCR1 = 0; + Ser2UTCR2 = 1; + /* use HPSIR, 1.6 usec pulses */ + Ser2UTCR4 = UTCR4_HPSIR|UTCR4_Z1_6us; + + /* enable receiver, receive fifo interrupt */ + Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE; + + /* clear status register to prevent unwanted interrupts */ + Ser2UTSR0 &= (UTSR0_RID | UTSR0_RBB | UTSR0_REB); + +#elif defined(LIRC_SIR_TEKRAM) + /* disable FIFO */ + soutp(UART_FCR, + UART_FCR_CLEAR_RCVR| + UART_FCR_CLEAR_XMIT| + UART_FCR_TRIGGER_1); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + + /* Set divisor to 12 => 9600 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 12); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* power supply */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + safe_udelay(50*1000); + + /* -DTR low -> reset PIC */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + udelay(1*1000); + + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(100); + + + /* -RTS low -> send control byte */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); + udelay(7); + soutp(UART_TX, TEKRAM_115200|TEKRAM_PW); + + /* one byte takes ~1042 usec to transmit at 9600,8N1 */ + udelay(1500); + + /* back to normal operation */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(50); + + udelay(1500); + + /* read previous control byte */ + printk(KERN_INFO LIRC_DRIVER_NAME + ": 0x%02x\n", sinp(UART_RX)); + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + + /* Set DLAB 0, 8 Bit */ + soutp(UART_LCR, UART_LCR_WLEN8); + /* enable interrupts */ + soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); +#else + outb(0, io + UART_MCR); + outb(0, io + UART_IER); + /* init UART */ + /* set DLAB, speed = 115200 */ + outb(UART_LCR_DLAB | UART_LCR_WLEN7, io + UART_LCR); + outb(1, io + UART_DLL); outb(0, io + UART_DLM); + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 44000 */ + outb(UART_LCR_WLEN7, io + UART_LCR); + /* FIFO operation */ + outb(UART_FCR_ENABLE_FIFO, io + UART_FCR); + /* interrupts */ + /* outb(UART_IER_RLSI|UART_IER_RDI|UART_IER_THRI, io + UART_IER); */ + outb(UART_IER_RDI, io + UART_IER); + /* turn on UART */ + outb(UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2, io + UART_MCR); +#ifdef LIRC_SIR_ACTISYS_ACT200L + init_act200(); +#elif defined(LIRC_SIR_ACTISYS_ACT220L) + init_act220(); +#endif +#endif + spin_unlock_irqrestore(&hardware_lock, flags); + return 0; +} + +static void drop_hardware(void) +{ + unsigned long flags; + + spin_lock_irqsave(&hardware_lock, flags); + +#ifdef LIRC_ON_SA1100 + Ser2UTCR3 = 0; + + Ser2UTCR0 = sr.utcr0; + Ser2UTCR1 = sr.utcr1; + Ser2UTCR2 = sr.utcr2; + Ser2UTCR4 = sr.utcr4; + Ser2UTCR3 = sr.utcr3; + + Ser2HSCR0 = sr.hscr0; +#ifdef CONFIG_SA1100_BITSY + if (machine_is_bitsy()) + clr_bitsy_egpio(EGPIO_BITSY_IR_ON); +#endif +#ifdef CONFIG_SA1100_COLLIE + sa1100_irda_set_power_collie(0); /* power off */ +#endif +#else + /* turn off interrupts */ + outb(0, io + UART_IER); +#endif + spin_unlock_irqrestore(&hardware_lock, flags); +} + +/* SECTION: Initialisation */ + +static int init_port(void) +{ + int retval; + + /* get I/O port access and IRQ line */ +#ifndef LIRC_ON_SA1100 + if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": i/o port 0x%.4x already in use.\n", io); + return -EBUSY; + } +#endif + retval = request_irq(irq, sir_interrupt, IRQF_DISABLED, + LIRC_DRIVER_NAME, NULL); + if (retval < 0) { +# ifndef LIRC_ON_SA1100 + release_region(io, 8); +# endif + printk(KERN_ERR LIRC_DRIVER_NAME + ": IRQ %d already in use.\n", + irq); + return retval; + } +#ifndef LIRC_ON_SA1100 + printk(KERN_INFO LIRC_DRIVER_NAME + ": I/O port 0x%.4x, IRQ %d.\n", + io, irq); +#endif + + init_timer(&timerlist); + timerlist.function = sir_timeout; + timerlist.data = 0xabadcafe; + + return 0; +} + +static void drop_port(void) +{ + free_irq(irq, NULL); + del_timer_sync(&timerlist); +#ifndef LIRC_ON_SA1100 + release_region(io, 8); +#endif +} + +#ifdef LIRC_SIR_ACTISYS_ACT200L +/******************************************************/ +/* Crystal/Cirrus CS8130 IR transceiver, used in Actisys Act200L dongle */ +/* some code borrowed from Linux IRDA driver */ + +/* Regsiter 0: Control register #1 */ +#define ACT200L_REG0 0x00 +#define ACT200L_TXEN 0x01 /* Enable transmitter */ +#define ACT200L_RXEN 0x02 /* Enable receiver */ +#define ACT200L_ECHO 0x08 /* Echo control chars */ + +/* Register 1: Control register #2 */ +#define ACT200L_REG1 0x10 +#define ACT200L_LODB 0x01 /* Load new baud rate count value */ +#define ACT200L_WIDE 0x04 /* Expand the maximum allowable pulse */ + +/* Register 3: Transmit mode register #2 */ +#define ACT200L_REG3 0x30 +#define ACT200L_B0 0x01 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ +#define ACT200L_B1 0x02 /* DataBits, 0=6, 1=7, 2=8, 3=9(8P) */ +#define ACT200L_CHSY 0x04 /* StartBit Synced 0=bittime, 1=startbit */ + +/* Register 4: Output Power register */ +#define ACT200L_REG4 0x40 +#define ACT200L_OP0 0x01 /* Enable LED1C output */ +#define ACT200L_OP1 0x02 /* Enable LED2C output */ +#define ACT200L_BLKR 0x04 + +/* Register 5: Receive Mode register */ +#define ACT200L_REG5 0x50 +#define ACT200L_RWIDL 0x01 /* fixed 1.6us pulse mode */ + /*.. other various IRDA bit modes, and TV remote modes..*/ + +/* Register 6: Receive Sensitivity register #1 */ +#define ACT200L_REG6 0x60 +#define ACT200L_RS0 0x01 /* receive threshold bit 0 */ +#define ACT200L_RS1 0x02 /* receive threshold bit 1 */ + +/* Register 7: Receive Sensitivity register #2 */ +#define ACT200L_REG7 0x70 +#define ACT200L_ENPOS 0x04 /* Ignore the falling edge */ + +/* Register 8,9: Baud Rate Dvider register #1,#2 */ +#define ACT200L_REG8 0x80 +#define ACT200L_REG9 0x90 + +#define ACT200L_2400 0x5f +#define ACT200L_9600 0x17 +#define ACT200L_19200 0x0b +#define ACT200L_38400 0x05 +#define ACT200L_57600 0x03 +#define ACT200L_115200 0x01 + +/* Register 13: Control register #3 */ +#define ACT200L_REG13 0xd0 +#define ACT200L_SHDW 0x01 /* Enable access to shadow registers */ + +/* Register 15: Status register */ +#define ACT200L_REG15 0xf0 + +/* Register 21: Control register #4 */ +#define ACT200L_REG21 0x50 +#define ACT200L_EXCK 0x02 /* Disable clock output driver */ +#define ACT200L_OSCL 0x04 /* oscillator in low power, medium accuracy mode */ + +static void init_act200(void) +{ + int i; + __u8 control[] = { + ACT200L_REG15, + ACT200L_REG13 | ACT200L_SHDW, + ACT200L_REG21 | ACT200L_EXCK | ACT200L_OSCL, + ACT200L_REG13, + ACT200L_REG7 | ACT200L_ENPOS, + ACT200L_REG6 | ACT200L_RS0 | ACT200L_RS1, + ACT200L_REG5 | ACT200L_RWIDL, + ACT200L_REG4 | ACT200L_OP0 | ACT200L_OP1 | ACT200L_BLKR, + ACT200L_REG3 | ACT200L_B0, + ACT200L_REG0 | ACT200L_TXEN | ACT200L_RXEN, + ACT200L_REG8 | (ACT200L_115200 & 0x0f), + ACT200L_REG9 | ((ACT200L_115200 >> 4) & 0x0f), + ACT200L_REG1 | ACT200L_LODB | ACT200L_WIDE + }; + + /* Set DLAB 1. */ + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN8); + + /* Set divisor to 12 => 9600 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 12); + + /* Set DLAB 0. */ + soutp(UART_LCR, UART_LCR_WLEN8); + /* Set divisor to 12 => 9600 Baud */ + + /* power supply */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + for (i = 0; i < 50; i++) + safe_udelay(1000); + + /* Reset the dongle : set RTS low for 25 ms */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); + for (i = 0; i < 25; i++) + udelay(1000); + + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(100); + + /* Clear DTR and set RTS to enter command mode */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + udelay(7); + +/* send out the control register settings for 115K 7N1 SIR operation */ + for (i = 0; i < sizeof(control); i++) { + soutp(UART_TX, control[i]); + /* one byte takes ~1042 usec to transmit at 9600,8N1 */ + udelay(1500); + } + + /* back to normal operation */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + udelay(50); + + udelay(1500); + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + + /* Set DLAB 1. */ + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); + + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* Set DLAB 0, 7 Bit */ + soutp(UART_LCR, UART_LCR_WLEN7); + + /* enable interrupts */ + soutp(UART_IER, sinp(UART_IER)|UART_IER_RDI); +} +#endif + +#ifdef LIRC_SIR_ACTISYS_ACT220L +/* Derived from linux IrDA driver (drivers/net/irda/actisys.c) + * Drop me a mail for any kind of comment: maxx@spaceboyz.net */ + +void init_act220(void) +{ + int i; + + /* DLAB 1 */ + soutp(UART_LCR, UART_LCR_DLAB|UART_LCR_WLEN7); + + /* 9600 baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 12); + + /* DLAB 0 */ + soutp(UART_LCR, UART_LCR_WLEN7); + + /* reset the dongle, set DTR low for 10us */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + udelay(10); + + /* back to normal (still 9600) */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_RTS|UART_MCR_OUT2); + + /* send RTS pulses until we reach 115200 + * i hope this is really the same for act220l/act220l+ */ + for (i = 0; i < 3; i++) { + udelay(10); + /* set RTS low for 10 us */ + soutp(UART_MCR, UART_MCR_DTR|UART_MCR_OUT2); + udelay(10); + /* set RTS high for 10 us */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2); + } + + /* back to normal operation */ + udelay(1500); /* better safe than sorry ;) */ + + /* Set DLAB 1. */ + soutp(UART_LCR, UART_LCR_DLAB | UART_LCR_WLEN7); + + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + + /* Set DLAB 0, 7 Bit */ + /* The dongle doesn't seem to have any problems with operation + at 7N1 */ + soutp(UART_LCR, UART_LCR_WLEN7); + + /* enable interrupts */ + soutp(UART_IER, UART_IER_RDI); +} +#endif + +static int init_lirc_sir(void) +{ + int retval; + + init_waitqueue_head(&lirc_read_queue); + retval = init_port(); + if (retval < 0) + return retval; + init_hardware(); + printk(KERN_INFO LIRC_DRIVER_NAME + ": Installed.\n"); + return 0; +} + +#ifdef MODULE + +int init_module(void) +{ + int retval; + + retval = init_chrdev(); + if (retval < 0) + return retval; + retval = init_lirc_sir(); + if (retval) { + drop_chrdev(); + return retval; + } + return 0; +} + +void cleanup_module(void) +{ + drop_hardware(); + drop_chrdev(); + drop_port(); + printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n"); +} + +#ifdef LIRC_SIR_TEKRAM +MODULE_DESCRIPTION("Infrared receiver driver for Tekram Irmate 210"); +MODULE_AUTHOR("Christoph Bartelmus"); +#elif defined(LIRC_ON_SA1100) +MODULE_DESCRIPTION("LIRC driver for StrongARM SA1100 embedded microprocessor"); +MODULE_AUTHOR("Christoph Bartelmus"); +#elif defined(LIRC_SIR_ACTISYS_ACT200L) +MODULE_DESCRIPTION("LIRC driver for Actisys Act200L"); +MODULE_AUTHOR("Karl Bongers"); +#elif defined(LIRC_SIR_ACTISYS_ACT220L) +MODULE_DESCRIPTION("LIRC driver for Actisys Act220L(+)"); +MODULE_AUTHOR("Jan Roemisch"); +#else +MODULE_DESCRIPTION("Infrared receiver driver for SIR type serial ports"); +MODULE_AUTHOR("Milan Pikula"); +#endif +MODULE_LICENSE("GPL"); + +#ifdef LIRC_ON_SA1100 +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (16)"); +#else +module_param(io, int, 0444); +MODULE_PARM_DESC(io, "I/O address base (0x3f8 or 0x2f8)"); + +module_param(irq, int, 0444); +MODULE_PARM_DESC(irq, "Interrupt (4 or 3)"); + +module_param(threshold, int, 0444); +MODULE_PARM_DESC(threshold, "space detection threshold (3)"); +#endif + +module_param(debug, bool, 0644); +MODULE_PARM_DESC(debug, "Enable debugging messages"); + +EXPORT_NO_SYMBOLS; + +#endif /* MODULE */ --- linux-2.6.28.orig/ubuntu/lirc/lirc_sir/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_sir/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_SIR) += lirc_sir.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_serial_igor/Makefile +++ linux-2.6.28/ubuntu/lirc/lirc_serial_igor/Makefile @@ -0,0 +1,4 @@ + +EXTRA_CFLAGS =-DIRCTL_DEV_MAJOR=61 -DLIRC_SERIAL_TRANSMITTER -DLIRC_SERIAL_SOFTCARRIER -I$(src)/.. + +obj-$(CONFIG_LIRC_SERIAL_IGOR) += lirc_serial_igor.o --- linux-2.6.28.orig/ubuntu/lirc/lirc_serial_igor/lirc_serial_igor.c +++ linux-2.6.28/ubuntu/lirc/lirc_serial_igor/lirc_serial_igor.c @@ -0,0 +1,1341 @@ +/* $Id: lirc_serial.c,v 5.87 2007/12/15 17:28:01 lirc Exp $ */ + +/**************************************************************************** + ** lirc_serial.c *********************************************************** + **************************************************************************** + * + * lirc_serial - Device driver that records pulse- and pause-lengths + * (space-lengths) between DDCD event on a serial port. + * + * Copyright (C) 1996,97 Ralph Metzler + * Copyright (C) 1998 Trent Piepho + * Copyright (C) 1998 Ben Pfaff + * Copyright (C) 1999 Christoph Bartelmus + * Copyright (C) 2007 Andrei Tanas (suspend/resume support) + * Copyright (C) 2007 Mario Limonciello Compile for Ubuntu with igor 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; 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 + * + */ + +/* Steve's changes to improve transmission fidelity: + - for systems with the rdtsc instruction and the clock counter, a + send_pule that times the pulses directly using the counter. + This means that the LIRC_SERIAL_TRANSMITTER_LATENCY fudge is + not needed. Measurement shows very stable waveform, even where + PCI activity slows the access to the UART, which trips up other + versions. + - For other system, non-integer-microsecond pulse/space lengths, + done using fixed point binary. So, much more accurate carrier + frequency. + - fine tuned transmitter latency, taking advantage of fractional + microseconds in previous change + - Fixed bug in the way transmitter latency was accounted for by + tuning the pulse lengths down - the send_pulse routine ignored + this overhead as it timed the overall pulse length - so the + pulse frequency was right but overall pulse length was too + long. Fixed by accounting for latency on each pulse/space + iteration. + + Steve Davies July 2001 +*/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) +#error "**********************************************************" +#error " Sorry, this driver needs kernel version 2.2.18 or higher " +#error "**********************************************************" +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +#include +#endif + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) +#include +#else +#include +#endif +#include +#include +#include + +#if defined(LIRC_SERIAL_NSLU2) +#include +/* From Intel IXP42X Developer's Manual (#252480-005): */ +/* ftp://download.intel.com/design/network/manuals/25248005.pdf */ +#define UART_IE_IXP42X_UUE 0x40 /* IXP42X UART Unit enable */ +#define UART_IE_IXP42X_RTOIE 0x10 /* IXP42X Receiver Data Timeout int.enable */ +#ifndef NSLU2_LED_GRN_GPIO +/* added in 2.6.22 */ +#define NSLU2_LED_GRN_GPIO NSLU2_LED_GRN +#endif +#endif + +#include "lirc.h" +#include "kcompat.h" +#include "lirc_dev/lirc_dev.h" + +#if defined(LIRC_SERIAL_SOFTCARRIER) && !defined(LIRC_SERIAL_TRANSMITTER) +#warning "Software carrier only affects transmitting" +#endif + +#if defined(rdtscl) + +#define USE_RDTSC +#warning "Note: using rdtsc instruction" +#endif + +#ifdef LIRC_SERIAL_ANIMAX +#ifdef LIRC_SERIAL_TRANSMITTER +#warning "******************************************" +#warning " This receiver does not have a " +#warning " transmitter diode " +#warning "******************************************" +#endif +#endif + +#define LIRC_DRIVER_NAME "lirc_serial_igor" + +struct lirc_serial_igor +{ + int signal_pin; + int signal_pin_change; + int on; + int off; + long (*send_pulse)(unsigned long length); + void (*send_space)(long length); + int features; +}; + +#define LIRC_HOMEBREW 0 +#define LIRC_IRDEO 1 +#define LIRC_IRDEO_REMOTE 2 +#define LIRC_ANIMAX 3 +#define LIRC_IGOR 4 +#define LIRC_NSLU2 5 + +static int type = LIRC_IGOR; + +/* Set defaults for NSLU2 */ +#if defined(LIRC_SERIAL_NSLU2) +#ifndef LIRC_IRQ +#define LIRC_IRQ IRQ_IXP4XX_UART2 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT (IXP4XX_UART2_BASE_VIRT + REG_OFFSET) +#endif +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP IXP4XX_UART2_BASE_PHYS +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 2 +#endif +#ifndef LIRC_ALLOW_MMAPPED_IO +#define LIRC_ALLOW_MMAPPED_IO +#endif +#endif + +#if defined(LIRC_ALLOW_MMAPPED_IO) +#ifndef LIRC_IOMMAP +#define LIRC_IOMMAP 0 +#endif +#ifndef LIRC_IOSHIFT +#define LIRC_IOSHIFT 0 +#endif +static int iommap = LIRC_IOMMAP; +static int ioshift = LIRC_IOSHIFT; +#endif + +static int softcarrier; + +static int share_irq; +static int debug; + +#define dprintk(fmt, args...) \ + do { \ + if (debug) \ + printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \ + fmt, ## args); \ + } while (0) + +/* forward declarations */ +static long send_pulse_irdeo(unsigned long length); +static long send_pulse_homebrew(unsigned long length); +static void send_space_irdeo(long length); +static void send_space_homebrew(long length); + +static struct lirc_serial_igor hardware[] = { + /* home-brew receiver/transmitter */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo classic */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* IRdeo remote */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + send_pulse_irdeo, + send_space_irdeo, + (LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SEND_PULSE| + LIRC_CAN_REC_MODE2) + }, + + /* AnimaX */ + { + UART_MSR_DCD, + UART_MSR_DDCD, + 0, + UART_MCR_RTS|UART_MCR_DTR|UART_MCR_OUT2, + NULL, + NULL, + LIRC_CAN_REC_MODE2 + }, + + /* home-brew receiver/transmitter (Igor Cesko's variation) */ + { + UART_MSR_DSR, + UART_MSR_DDSR, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, + +#if defined(LIRC_SERIAL_NSLU2) + /* Modified Linksys Network Storage Link USB 2.0 (NSLU2): + We receive on CTS of the 2nd serial port (R142,LHS), we + transmit with a IR diode between GPIO[1] (green status LED), + and ground (Matthias Goebl ). + See also http://www.nslu2-linux.org for this device */ + { + UART_MSR_CTS, + UART_MSR_DCTS, + UART_MCR_RTS|UART_MCR_OUT2|UART_MCR_DTR, + UART_MCR_RTS|UART_MCR_OUT2, + send_pulse_homebrew, + send_space_homebrew, + ( +#ifdef LIRC_SERIAL_TRANSMITTER + LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER| + LIRC_CAN_SEND_PULSE| +#endif + LIRC_CAN_REC_MODE2) + }, +#endif + +}; + +#define RS_ISR_PASS_LIMIT 256 + +/* A long pulse code from a remote might take upto 300 bytes. The + daemon should read the bytes as soon as they are generated, so take + the number of keys you think you can push before the daemon runs + and multiply by 300. The driver will warn you if you overrun this + buffer. If you have a slow computer or non-busmastering IDE disks, + maybe you will need to increase this. */ + +/* This MUST be a power of two! It has to be larger than 1 as well. */ + +#define RBUF_LEN 256 +#define WBUF_LEN 256 + +static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */ +static int txsense; /* 0 = active high, 1 = active low */ + +#ifndef LIRC_IRQ +#define LIRC_IRQ 4 +#endif +#ifndef LIRC_PORT +#define LIRC_PORT 0x3f8 +#endif + +static int io = LIRC_PORT; +static int irq = LIRC_IRQ; + +static struct timeval lasttv = {0, 0}; + +static struct lirc_buffer rbuf; + +static lirc_t wbuf[WBUF_LEN]; + +static unsigned int freq = 38000; +static unsigned int duty_cycle = 50; + +/* Initialized in init_timing_params() */ +static unsigned long period; +static unsigned long pulse_width; +static unsigned long space_width; + +#if defined(__i386__) +/* + From: + Linux I/O port programming mini-HOWTO + Author: Riku Saikkonen + v, 28 December 1997 + + [...] + Actually, a port I/O instruction on most ports in the 0-0x3ff range + takes almost exactly 1 microsecond, so if you're, for example, using + the parallel port directly, just do additional inb()s from that port + to delay. + [...] +*/ +/* transmitter latency 1.5625us 0x1.90 - this figure arrived at from + * comment above plus trimming to match actual measured frequency. + * This will be sensitive to cpu speed, though hopefully most of the 1.5us + * is spent in the uart access. Still - for reference test machine was a + * 1.13GHz Athlon system - Steve + */ + +/* changed from 400 to 450 as this works better on slower machines; + faster machines will use the rdtsc code anyway */ + +#define LIRC_SERIAL_TRANSMITTER_LATENCY 450 + +#else + +/* does anybody have information on other platforms ? */ +/* 256 = 1<<8 */ +#define LIRC_SERIAL_TRANSMITTER_LATENCY 256 + +#endif /* __i386__ */ + +static inline unsigned int sinp(int offset) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { /* the register is memory-mapped */ + offset <<= ioshift; + return readb(io + offset); + } +#endif + return inb(io + offset); +} + +static inline void soutp(int offset, int value) +{ +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) { /* the register is memory-mapped */ + offset <<= ioshift; + writeb(value, io + offset); + } +#endif + outb(value, io + offset); +} + +static inline void on(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + /* On NSLU2, we put the transmit diode between the output of the green + status LED and ground */ + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_LOW); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].off); + else + soutp(UART_MCR, hardware[type].on); +} + +static inline void off(void) +{ +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { + gpio_line_set(NSLU2_LED_GRN_GPIO, IXP4XX_GPIO_HIGH); + return; + } +#endif + if (txsense) + soutp(UART_MCR, hardware[type].on); + else + soutp(UART_MCR, hardware[type].off); +} + +#ifndef MAX_UDELAY_MS +#define MAX_UDELAY_US 5000 +#else +#define MAX_UDELAY_US (MAX_UDELAY_MS*1000) +#endif + +static inline void safe_udelay(unsigned long usecs) +{ + while (usecs > MAX_UDELAY_US) { + udelay(MAX_UDELAY_US); + usecs -= MAX_UDELAY_US; + } + udelay(usecs); +} + +#ifdef USE_RDTSC +/* This is an overflow/precision juggle, complicated in that we can't + do long long divide in the kernel */ + +/* When we use the rdtsc instruction to measure clocks, we keep the + * pulse and space widths as clock cycles. As this is CPU speed + * dependent, the widths must be calculated in init_port and ioctl + * time + */ + +/* So send_pulse can quickly convert microseconds to clocks */ +static unsigned long conv_us_to_clocks; + +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ + unsigned long long loops_per_sec, work; + + duty_cycle = new_duty_cycle; + freq = new_freq; + + loops_per_sec = current_cpu_data.loops_per_jiffy; + loops_per_sec *= HZ; + + /* How many clocks in a microsecond?, avoiding long long divide */ + work = loops_per_sec; + work *= 4295; /* 4295 = 2^32 / 1e6 */ + conv_us_to_clocks = (work>>32); + + /* Carrier period in clocks, approach good up to 32GHz clock, + gets carrier frequency within 8Hz */ + period = loops_per_sec>>3; + period /= (freq>>3); + + /* Derive pulse and space from the period */ + + pulse_width = period*duty_cycle/100; + space_width = period - pulse_width; + dprintk("in init_timing_params, freq=%d, duty_cycle=%d, " + "clk/jiffy=%ld, pulse=%ld, space=%ld, " + "conv_us_to_clocks=%ld\n", + freq, duty_cycle, current_cpu_data.loops_per_jiffy, + pulse_width, space_width, conv_us_to_clocks); + return 0; +} +#else /* ! USE_RDTSC */ +static inline int init_timing_params(unsigned int new_duty_cycle, + unsigned int new_freq) +{ +/* period, pulse/space width are kept with 8 binary places - + * IE multiplied by 256. */ + if (256*1000000L/new_freq*new_duty_cycle/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return(-EINVAL); + if (256*1000000L/new_freq*(100-new_duty_cycle)/100 <= + LIRC_SERIAL_TRANSMITTER_LATENCY) + return(-EINVAL); + duty_cycle = new_duty_cycle; + freq = new_freq; + period = 256*1000000L/freq; + pulse_width = period*duty_cycle/100; + space_width = period-pulse_width; + dprintk("in init_timing_params, freq=%d pulse=%ld, " + "space=%ld\n", freq, pulse_width, space_width); + return 0; +} +#endif /* USE_RDTSC */ + + +/* return value: space length delta */ + +static long send_pulse_irdeo(unsigned long length) +{ + long rawbits; + int i; + unsigned char output; + unsigned char chunk, shifted; + + /* how many bits have to be sent ? */ + rawbits = length*1152/10000; + if (duty_cycle > 50) + chunk = 3; + else + chunk = 1; + for (i = 0, output = 0x7f; rawbits > 0; rawbits -= 3) { + shifted = chunk<<(i*3); + shifted >>= 1; + output &= (~shifted); + i++; + if (i == 3) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_THRE)); + output = 0x7f; + i = 0; + } + } + if (i != 0) { + soutp(UART_TX, output); + while (!(sinp(UART_LSR) & UART_LSR_TEMT)); + } + + if (i == 0) + return ((-rawbits)*10000/1152); + else + return ((3-i)*3*10000/1152+(-rawbits)*10000/1152); +} + +#ifdef USE_RDTSC +/* Version that uses Pentium rdtsc instruction to measure clocks */ + +/* This version does sub-microsecond timing using rdtsc instruction, + * and does away with the fudged LIRC_SERIAL_TRANSMITTER_LATENCY + * Implicitly i586 architecture... - Steve + */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long target, start, now; + + /* Get going quick as we can */ + rdtscl(start); on(); + /* Convert length from microseconds to clocks */ + length *= conv_us_to_clocks; + /* And loop till time is up - flipping at right intervals */ + now = start; + target = pulse_width; + flag = 1; + while ((now-start) < length) { + /* Delay till flip time */ + do + rdtscl(now); + while ((now-start) < target); + + /* flip */ + if (flag) { + rdtscl(now); off(); + target += space_width; + } else { + rdtscl(now); on(); + target += pulse_width; + } + flag = !flag; + } + rdtscl(now); + return (((now-start)-length)/conv_us_to_clocks); +} +#else /* ! USE_RDTSC */ +/* Version using udelay() */ + +/* here we use fixed point arithmetic, with 8 + fractional bits. that gets us within 0.1% or so of the right average + frequency, albeit with some jitter in pulse length - Steve */ + +/* To match 8 fractional bits used for pulse/space length */ + +static inline long send_pulse_homebrew_softcarrier(unsigned long length) +{ + int flag; + unsigned long actual, target, d; + length <<= 8; + + actual = 0; target = 0; flag = 0; + while (actual < length) { + if (flag) { + off(); + target += space_width; + } else { + on(); + target += pulse_width; + } + d = (target-actual-LIRC_SERIAL_TRANSMITTER_LATENCY+128)>>8; + /* Note - we've checked in ioctl that the pulse/space + widths are big enough so that d is > 0 */ + udelay(d); + actual += (d<<8)+LIRC_SERIAL_TRANSMITTER_LATENCY; + flag = !flag; + } + return ((actual-length)>>8); +} +#endif /* USE_RDTSC */ + +static long send_pulse_homebrew(unsigned long length) +{ + if (length <= 0) + return 0; + + if (softcarrier) + return send_pulse_homebrew_softcarrier(length); + else { + on(); + safe_udelay(length); + return 0; + } +} + +static void send_space_irdeo(long length) +{ + if (length <= 0) + return; + + safe_udelay(length); +} + +static void send_space_homebrew(long length) +{ + off(); + if (length <= 0) + return; + safe_udelay(length); +} + +static inline void rbwrite(lirc_t l) +{ + if (lirc_buffer_full(&rbuf)) { /* no new signals will be accepted */ + dprintk("Buffer overrun\n"); + return; + } + _lirc_buffer_write_1(&rbuf, (void *)&l); +} + +static inline void frbwrite(lirc_t l) +{ + /* simple noise filter */ + static lirc_t pulse = 0L, space = 0L; + static unsigned int ptr; + + if (ptr > 0 && (l&PULSE_BIT)) { + pulse += l&PULSE_MASK; + if (pulse > 250) { + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + return; + } + if (!(l&PULSE_BIT)) { + if (ptr == 0) { + if (l > 20000) { + space = l; + ptr++; + return; + } + } else { + if (l > 20000) { + space += pulse; + if (space > PULSE_MASK) + space = PULSE_MASK; + space += l; + if (space > PULSE_MASK) + space = PULSE_MASK; + pulse = 0; + return; + } + rbwrite(space); + rbwrite(pulse|PULSE_BIT); + ptr = 0; + pulse = 0; + } + } + rbwrite(l); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) +static irqreturn_t irq_handler(int i, void *blah) +#else +static irqreturn_t irq_handler(int i, void *blah, struct pt_regs *regs) +#endif +{ + struct timeval tv; + int status, counter, dcd; + long deltv; + lirc_t data; + static int last_dcd = -1; + + if ((sinp(UART_IIR) & UART_IIR_NO_INT)) { + /* not our interrupt */ + return IRQ_RETVAL(IRQ_NONE); + } + + counter = 0; + do { + counter++; + status = sinp(UART_MSR); + if (counter > RS_ISR_PASS_LIMIT) { + printk(KERN_WARNING LIRC_DRIVER_NAME ": AIEEEE: " + "We're caught!\n"); + break; + } + if ((status&hardware[type].signal_pin_change) && sense != -1) { + /* get current time */ + do_gettimeofday(&tv); + + /* New mode, written by Trent Piepho + . */ + + /* The old format was not very portable. + We now use the type lirc_t to pass pulses + and spaces to user space. + + If PULSE_BIT is set a pulse has been + received, otherwise a space has been + received. The driver needs to know if your + receiver is active high or active low, or + the space/pulse sense could be + inverted. The bits denoted by PULSE_MASK are + the length in microseconds. Lengths greater + than or equal to 16 seconds are clamped to + PULSE_MASK. All other bits are unused. + This is a much simpler interface for user + programs, as well as eliminating "out of + phase" errors with space/pulse + autodetection. */ + + /* calculate time since last interrupt in + microseconds */ + dcd = (status & hardware[type].signal_pin) ? 1:0; + + if (dcd == last_dcd) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": ignoring spike: %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + continue; + } + + deltv = tv.tv_sec-lasttv.tv_sec; + if (tv.tv_sec < lasttv.tv_sec || + (tv.tv_sec == lasttv.tv_sec && + tv.tv_usec < lasttv.tv_usec)) { + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: your clock just jumped " + "backwards\n"); + printk(KERN_WARNING LIRC_DRIVER_NAME + ": %d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + data = PULSE_MASK; + } else if (deltv > 15) { + data = PULSE_MASK; /* really long time */ + if (!(dcd^sense)) { /* sanity check */ + printk(KERN_WARNING LIRC_DRIVER_NAME + ": AIEEEE: " + "%d %d %lx %lx %lx %lx\n", + dcd, sense, + tv.tv_sec, lasttv.tv_sec, + tv.tv_usec, lasttv.tv_usec); + /* detecting pulse while this + MUST be a space! */ + sense = sense ? 0:1; + } + } else + data = (lirc_t) (deltv*1000000 + + tv.tv_usec - + lasttv.tv_usec); + frbwrite(dcd^sense ? data : (data|PULSE_BIT)); + lasttv = tv; + last_dcd = dcd; + wake_up_interruptible(&rbuf.wait_poll); + } + } while (!(sinp(UART_IIR) & UART_IIR_NO_INT)); /* still pending ? */ + return IRQ_RETVAL(IRQ_HANDLED); +} + +static void hardware_init_port(void) +{ + unsigned long flags; + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + +#if defined(LIRC_SERIAL_NSLU2) + if (type == LIRC_NSLU2) { /* Setup NSLU2 UART */ + /* Enable UART */ + soutp(UART_IER, sinp(UART_IER) | UART_IE_IXP42X_UUE); + /* Disable Receiver data Time out interrupt */ + soutp(UART_IER, sinp(UART_IER) & ~UART_IE_IXP42X_RTOIE); + /* set out2 = interupt unmask; off() doesn't set MCR + on NSLU2 */ + soutp(UART_MCR, UART_MCR_RTS|UART_MCR_OUT2); + } +#endif + + /* Set line for power source */ + off(); + + /* Clear registers again to be sure. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + switch (type) { + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + /* setup port to 7N1 @ 115200 Baud */ + /* 7N1+start = 9 bits at 115200 ~ 3 bits at 38kHz */ + + /* Set DLAB 1. */ + soutp(UART_LCR, sinp(UART_LCR) | UART_LCR_DLAB); + /* Set divisor to 1 => 115200 Baud */ + soutp(UART_DLM, 0); + soutp(UART_DLL, 1); + /* Set DLAB 0 + 7N1 */ + soutp(UART_LCR, UART_LCR_WLEN7); + /* THR interrupt already disabled at this point */ + break; + default: + break; + } + + local_irq_restore(flags); +} + +static int init_port(void) +{ + int i, nlow, nhigh; + + /* Reserve io region. */ +#if defined(LIRC_ALLOW_MMAPPED_IO) + /* Future MMAP-Developers: Attention! + For memory mapped I/O you *might* need to use ioremap() first, + for the NSLU2 it's done in boot code. */ + if (((iommap != 0) + && (request_mem_region(iommap, 8<= nhigh ? 1 : 0); + printk(KERN_INFO LIRC_DRIVER_NAME ": auto-detected active " + "%s receiver\n", sense ? "low":"high"); + } else + printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " + "%s receiver\n", sense ? "low":"high"); + + return 0; +} + +static int set_use_inc(void *data) +{ + int result; + unsigned long flags; + + /* Init read buffer. */ + if (lirc_buffer_init(&rbuf, sizeof(lirc_t), RBUF_LEN) < 0) + return -ENOMEM; + + /* initialize timestamp */ + do_gettimeofday(&lasttv); + + result = request_irq(irq, irq_handler, + IRQF_DISABLED | (share_irq ? IRQF_SHARED:0), + LIRC_DRIVER_NAME, (void *)&hardware); + + switch (result) { + case -EBUSY: + printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); + lirc_buffer_free(&rbuf); + return -EBUSY; + case -EINVAL: + printk(KERN_ERR LIRC_DRIVER_NAME + ": Bad irq number or handler\n"); + lirc_buffer_free(&rbuf); + return -EINVAL; + default: + dprintk("Interrupt %d, port %04x obtained\n", irq, io); + break; + }; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + + local_irq_restore(flags); + + MOD_INC_USE_COUNT; + return 0; +} + +static void set_use_dec(void *data) +{ unsigned long flags; + + local_irq_save(flags); + + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* First of all, disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + local_irq_restore(flags); + + free_irq(irq, (void *)&hardware); + + dprintk("freed IRQ %d\n", irq); + lirc_buffer_free(&rbuf); + + MOD_DEC_USE_COUNT; +} + +static ssize_t lirc_write(struct file *file, const char *buf, + size_t n, loff_t *ppos) +{ + int i, count; + unsigned long flags; + long delta = 0; + + if (!(hardware[type].features&LIRC_CAN_SEND_PULSE)) + return(-EBADF); + + if (n%sizeof(lirc_t)) return(-EINVAL); + count = n/sizeof(lirc_t); + if (count > WBUF_LEN || count%2 == 0) return(-EINVAL); + if (copy_from_user(wbuf, buf, n)) return -EFAULT; + local_irq_save(flags); + if (type == LIRC_IRDEO) { + /* DTR, RTS down */ + on(); + } + for (i = 0; i < count; i++) { + if (i%2) + hardware[type].send_space(wbuf[i]-delta); + else + delta = hardware[type].send_pulse(wbuf[i]); + } + off(); + local_irq_restore(flags); + return(n); +} + +static int lirc_ioctl(struct inode *node, struct file *filep, unsigned int cmd, + unsigned long arg) +{ + int result; + unsigned long value; + unsigned int ivalue; + + switch (cmd) { + case LIRC_GET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return(-ENOIOCTLCMD); + + result = put_user(LIRC_SEND2MODE + (hardware[type].features&LIRC_CAN_SEND_MASK), + (unsigned long *) arg); + if (result) + return result; + break; + + case LIRC_SET_SEND_MODE: + if (!(hardware[type].features&LIRC_CAN_SEND_MASK)) + return(-ENOIOCTLCMD); + + result = get_user(value, (unsigned long *) arg); + if (result) + return result; + /* only LIRC_MODE_PULSE supported */ + if (value != LIRC_MODE_PULSE) + return -ENOSYS; + break; + + case LIRC_GET_LENGTH: + return -ENOSYS; + break; + + case LIRC_SET_SEND_DUTY_CYCLE: + dprintk("SET_SEND_DUTY_CYCLE\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_DUTY_CYCLE)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue <= 0 || ivalue > 100) + return -EINVAL; + return init_timing_params(ivalue, freq); + break; + + case LIRC_SET_SEND_CARRIER: + dprintk("SET_SEND_CARRIER\n"); + if (!(hardware[type].features&LIRC_CAN_SET_SEND_CARRIER)) + return -ENOIOCTLCMD; + + result = get_user(ivalue, (unsigned int *) arg); + if (result) + return result; + if (ivalue > 500000 || ivalue < 20000) + return -EINVAL; + return init_timing_params(duty_cycle, ivalue); + break; + + default: + return -ENOIOCTLCMD; + } + return 0; +} + +static struct file_operations lirc_fops = { + .write = lirc_write, +}; + +static struct lirc_plugin plugin = { + .name = LIRC_DRIVER_NAME, + .minor = -1, + .code_length = 1, + .sample_rate = 0, + .data = NULL, + .add_to_buf = NULL, + .get_queue = NULL, + .rbuf = &rbuf, + .set_use_inc = set_use_inc, + .set_use_dec = set_use_dec, + .ioctl = lirc_ioctl, + .fops = &lirc_fops, + .dev = NULL, + .owner = THIS_MODULE, +}; + +#ifdef MODULE + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) +static struct platform_device *lirc_serial_igor_dev; + +static int __devinit lirc_serial_igor_probe(struct platform_device *dev) +{ + return 0; +} + +static int __devexit lirc_serial_igor_remove(struct platform_device * dev) +{ + return 0; +} + +static int lirc_serial_igor_suspend(struct platform_device *dev, + pm_message_t state) +{ + /* Set DLAB 0. */ + soutp(UART_LCR, sinp(UART_LCR) & (~UART_LCR_DLAB)); + + /* Disable all interrupts */ + soutp(UART_IER, sinp(UART_IER) & + (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); + + /* Clear registers. */ + sinp(UART_LSR); + sinp(UART_RX); + sinp(UART_IIR); + sinp(UART_MSR); + + return 0; +} + +static int lirc_serial_igor_resume(struct platform_device *dev) +{ + unsigned long flags; + + hardware_init_port(); + + local_irq_save(flags); + /* Enable Interrupt */ + do_gettimeofday(&lasttv); + soutp(UART_IER, sinp(UART_IER)|UART_IER_MSI); + off(); + + lirc_buffer_clear(&rbuf); + + local_irq_restore(flags); + + return 0; +} + +static struct platform_driver lirc_serial_igor_driver = { + .probe = lirc_serial_igor_probe, + .remove = __devexit_p(lirc_serial_igor_remove), + .suspend = lirc_serial_igor_suspend, + .resume = lirc_serial_igor_resume, + .driver = { + .name = "lirc_serial_igor", + .owner = THIS_MODULE, + }, +}; + +static int __init lirc_serial_igor_init(void) +{ + int result; + + result = platform_driver_register(&lirc_serial_igor_driver); + if (result) { + printk("lirc register returned %d\n", result); + return result; + } + + lirc_serial_igor_dev = platform_device_alloc("lirc_serial_igor", 0); + if (!lirc_serial_igor_dev) { + result = -ENOMEM; + goto exit_driver_unregister; + } + + result = platform_device_add(lirc_serial_igor_dev); + if (result) + goto exit_device_put; + + return 0; + +exit_device_put: + platform_device_put(lirc_serial_igor_dev); +exit_driver_unregister: + platform_driver_unregister(&lirc_serial_igor_driver); + return result; +} + +static void __exit lirc_serial_igor_exit(void) +{ + platform_device_unregister(lirc_serial_igor_dev); + platform_driver_unregister(&lirc_serial_igor_driver); +} +#endif + +int __init init_module(void) +{ + int result; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + result = lirc_serial_igor_init(); + if (result) + return result; +#endif + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IRDEO: + case LIRC_IRDEO_REMOTE: + case LIRC_ANIMAX: + case LIRC_IGOR: +#if defined(LIRC_SERIAL_NSLU2) + case LIRC_NSLU2: +#endif + break; + default: + result = -EINVAL; + goto exit_serial_exit; + } + if (!softcarrier) { + switch (type) { + case LIRC_HOMEBREW: + case LIRC_IGOR: + case LIRC_NSLU2: + hardware[type].features &= + ~(LIRC_CAN_SET_SEND_DUTY_CYCLE| + LIRC_CAN_SET_SEND_CARRIER); + break; + } + } + result = init_port(); + if (result < 0) + goto exit_serial_exit; + plugin.features = hardware[type].features; + plugin.minor = lirc_register_plugin(&plugin); + if (plugin.minor < 0) { + printk(KERN_ERR LIRC_DRIVER_NAME + ": register_chrdev failed!\n"); + result = -EIO; + goto exit_release; + } + return 0; +exit_release: + release_region(io, 8); +exit_serial_exit: +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_igor_exit(); +#endif + return result; +} + +void __exit cleanup_module(void) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 18) + lirc_serial_igor_exit(); +#endif +#if defined(LIRC_ALLOW_MMAPPED_IO) + if (iommap != 0) + release_mem_region(iommap, 8< + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel 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; 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. + * + * Some of these defines are unused for various reasons. Some describe + * hardware features we don't yet use. Some are specific to the cousin atl1 + * hardware, which we may merge this driver with in the future. Please + * remember this is a surrogate for hardware specs, and don't unnecessarily + * abuse the content or formatting. -- CHS + */ + +#ifndef _ATL2_HW_H_ +#define _ATL2_HW_H_ + +#include "atl2_osdep.h" + +struct atl2_adapter; +struct atl2_hw; + +/* function prototype */ +s32 atl2_reset_hw(struct atl2_hw *hw); +s32 atl2_read_mac_addr(struct atl2_hw *hw); +s32 atl2_init_hw(struct atl2_hw *hw); +s32 atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed, u16 *duplex); +u32 atl2_auto_get_fc(struct atl2_adapter *adapter, u16 duplex); +u32 atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr); +void atl2_hash_set(struct atl2_hw *hw, u32 hash_value); +s32 atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data); +s32 atl2_write_phy_reg(struct atl2_hw *hw, u32 reg_addr, u16 phy_data); +void atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value); +void atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value); +s32 atl2_validate_mdi_setting(struct atl2_hw *hw); +void atl2_set_mac_addr(struct atl2_hw *hw); +bool atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue); +bool atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value); +s32 atl2_phy_init(struct atl2_hw *hw); +int atl2_check_eeprom_exist(struct atl2_hw *hw); +void atl2_force_ps(struct atl2_hw *hw); + +/* register definition */ +#define REG_PM_CTRLSTAT 0x44 + +#define REG_PCIE_CAP_LIST 0x58 + +#define REG_VPD_CAP 0x6C +#define VPD_CAP_ID_MASK 0xff +#define VPD_CAP_ID_SHIFT 0 +#define VPD_CAP_NEXT_PTR_MASK 0xFF +#define VPD_CAP_NEXT_PTR_SHIFT 8 +#define VPD_CAP_VPD_ADDR_MASK 0x7FFF +#define VPD_CAP_VPD_ADDR_SHIFT 16 +#define VPD_CAP_VPD_FLAG 0x80000000 + +#define REG_VPD_DATA 0x70 + +#define REG_SPI_FLASH_CTRL 0x200 +#define SPI_FLASH_CTRL_STS_NON_RDY 0x1 +#define SPI_FLASH_CTRL_STS_WEN 0x2 +#define SPI_FLASH_CTRL_STS_WPEN 0x80 +#define SPI_FLASH_CTRL_DEV_STS_MASK 0xFF +#define SPI_FLASH_CTRL_DEV_STS_SHIFT 0 +#define SPI_FLASH_CTRL_INS_MASK 0x7 +#define SPI_FLASH_CTRL_INS_SHIFT 8 +#define SPI_FLASH_CTRL_START 0x800 +#define SPI_FLASH_CTRL_EN_VPD 0x2000 +#define SPI_FLASH_CTRL_LDSTART 0x8000 +#define SPI_FLASH_CTRL_CS_HI_MASK 0x3 +#define SPI_FLASH_CTRL_CS_HI_SHIFT 16 +#define SPI_FLASH_CTRL_CS_HOLD_MASK 0x3 +#define SPI_FLASH_CTRL_CS_HOLD_SHIFT 18 +#define SPI_FLASH_CTRL_CLK_LO_MASK 0x3 +#define SPI_FLASH_CTRL_CLK_LO_SHIFT 20 +#define SPI_FLASH_CTRL_CLK_HI_MASK 0x3 +#define SPI_FLASH_CTRL_CLK_HI_SHIFT 22 +#define SPI_FLASH_CTRL_CS_SETUP_MASK 0x3 +#define SPI_FLASH_CTRL_CS_SETUP_SHIFT 24 +#define SPI_FLASH_CTRL_EROM_PGSZ_MASK 0x3 +#define SPI_FLASH_CTRL_EROM_PGSZ_SHIFT 26 +#define SPI_FLASH_CTRL_WAIT_READY 0x10000000 + +#define REG_SPI_ADDR 0x204 + +#define REG_SPI_DATA 0x208 + +#define REG_SPI_FLASH_CONFIG 0x20C +#define SPI_FLASH_CONFIG_LD_ADDR_MASK 0xFFFFFF +#define SPI_FLASH_CONFIG_LD_ADDR_SHIFT 0 +#define SPI_FLASH_CONFIG_VPD_ADDR_MASK 0x3 +#define SPI_FLASH_CONFIG_VPD_ADDR_SHIFT 24 +#define SPI_FLASH_CONFIG_LD_EXIST 0x4000000 + +#define REG_SPI_FLASH_OP_PROGRAM 0x210 +#define REG_SPI_FLASH_OP_SC_ERASE 0x211 +#define REG_SPI_FLASH_OP_CHIP_ERASE 0x212 +#define REG_SPI_FLASH_OP_RDID 0x213 +#define REG_SPI_FLASH_OP_WREN 0x214 +#define REG_SPI_FLASH_OP_RDSR 0x215 +#define REG_SPI_FLASH_OP_WRSR 0x216 +#define REG_SPI_FLASH_OP_READ 0x217 + +#define REG_TWSI_CTRL 0x218 +#define TWSI_CTRL_LD_OFFSET_MASK 0xFF +#define TWSI_CTRL_LD_OFFSET_SHIFT 0 +#define TWSI_CTRL_LD_SLV_ADDR_MASK 0x7 +#define TWSI_CTRL_LD_SLV_ADDR_SHIFT 8 +#define TWSI_CTRL_SW_LDSTART 0x800 +#define TWSI_CTRL_HW_LDSTART 0x1000 +#define TWSI_CTRL_SMB_SLV_ADDR_MASK 0x0x7F +#define TWSI_CTRL_SMB_SLV_ADDR_SHIFT 15 +#define TWSI_CTRL_LD_EXIST 0x400000 +#define TWSI_CTRL_READ_FREQ_SEL_MASK 0x3 +#define TWSI_CTRL_READ_FREQ_SEL_SHIFT 23 +#define TWSI_CTRL_FREQ_SEL_100K 0 +#define TWSI_CTRL_FREQ_SEL_200K 1 +#define TWSI_CTRL_FREQ_SEL_300K 2 +#define TWSI_CTRL_FREQ_SEL_400K 3 +#define TWSI_CTRL_SMB_SLV_ADDR +#define TWSI_CTRL_WRITE_FREQ_SEL_MASK 0x3 +#define TWSI_CTRL_WRITE_FREQ_SEL_SHIFT 24 + +#define REG_PCIE_DEV_MISC_CTRL 0x21C +#define PCIE_DEV_MISC_CTRL_EXT_PIPE 0x2 +#define PCIE_DEV_MISC_CTRL_RETRY_BUFDIS 0x1 +#define PCIE_DEV_MISC_CTRL_SPIROM_EXIST 0x4 +#define PCIE_DEV_MISC_CTRL_SERDES_ENDIAN 0x8 +#define PCIE_DEV_MISC_CTRL_SERDES_SEL_DIN 0x10 + +#define REG_PCIE_PHYMISC 0x1000 +#define PCIE_PHYMISC_FORCE_RCV_DET 0x4 + +#define REG_PCIE_DLL_TX_CTRL1 0x1104 +#define PCIE_DLL_TX_CTRL1_SEL_NOR_CLK 0x0400 +#define PCIE_DLL_TX_CTRL1_DEF 0x0568 + +#define REG_LTSSM_TEST_MODE 0x12FC +#define LTSSM_TEST_MODE_DEF 0x6500 + +/* Master Control Register */ +#define REG_MASTER_CTRL 0x1400 +#define MASTER_CTRL_SOFT_RST 0x1 +#define MASTER_CTRL_MTIMER_EN 0x2 +#define MASTER_CTRL_ITIMER_EN 0x4 +#define MASTER_CTRL_MANUAL_INT 0x8 +#define MASTER_CTRL_REV_NUM_SHIFT 16 +#define MASTER_CTRL_REV_NUM_MASK 0xff +#define MASTER_CTRL_DEV_ID_SHIFT 24 +#define MASTER_CTRL_DEV_ID_MASK 0xff + +/* Timer Initial Value Register */ +#define REG_MANUAL_TIMER_INIT 0x1404 + +/* IRQ ModeratorTimer Initial Value Register */ +#define REG_IRQ_MODU_TIMER_INIT 0x1408 + +#define REG_PHY_ENABLE 0x140C +// IRQ Anti-Lost Timer Initial Value Register +//#define REG_IRQ_CLR_TIMER 0x140c // Maximum allowance for software to clear the interrupt. +// IRQ Anti-Lost Timer Initial Value Register +#define REG_CMBDISDMA_TIMER 0x140E + +/* Block IDLE Status Register */ +#define REG_IDLE_STATUS 0x1410 +#define IDLE_STATUS_RXMAC 1 /* 1: RXMAC state machine is in non-IDLE state. 0: RXMAC is idling */ +#define IDLE_STATUS_TXMAC 2 /* 1: TXMAC state machine is in non-IDLE state. 0: TXMAC is idling */ +#define IDLE_STATUS_DMAR 8 /* 1: DMAR state machine is in non-IDLE state. 0: DMAR is idling */ +#define IDLE_STATUS_DMAW 4 /* 1: DMAW state machine is in non-IDLE state. 0: DMAW is idling */ + +/* MDIO Control Register */ +#define REG_MDIO_CTRL 0x1414 +#define MDIO_DATA_MASK 0xffff /* On MDIO write, the 16-bit control data to write to PHY MII management register */ +#define MDIO_DATA_SHIFT 0 /* On MDIO read, the 16-bit status data that was read from the PHY MII management register. */ +#define MDIO_REG_ADDR_MASK 0x1f /* MDIO register address */ +#define MDIO_REG_ADDR_SHIFT 16 +#define MDIO_RW 0x200000 /* 1: read, 0: write */ +#define MDIO_SUP_PREAMBLE 0x400000 /* Suppress preamble */ +#define MDIO_START 0x800000 /* Write 1 to initiate the MDIO master. And this bit is self cleared after one cycle. */ +#define MDIO_CLK_SEL_SHIFT 24 +#define MDIO_CLK_25_4 0 +#define MDIO_CLK_25_6 2 +#define MDIO_CLK_25_8 3 +#define MDIO_CLK_25_10 4 +#define MDIO_CLK_25_14 5 +#define MDIO_CLK_25_20 6 +#define MDIO_CLK_25_28 7 +#define MDIO_BUSY 0x8000000 +#define MDIO_WAIT_TIMES 10 + +/* SerDes Lock Detect Control and Status Register */ +#define REG_SERDES_LOCK 0x1424 +#define SERDES_LOCK_DETECT 1 /* 1: SerDes lock detected. This signal comes from Analog SerDes. */ +#define SERDES_LOCK_DETECT_EN 2 /* 1: Enable SerDes Lock detect function. */ + +/* MAC Control Register */ +#define REG_MAC_CTRL 0x1480 +#define MAC_CTRL_TX_EN 1 /* 1: Transmit Enable */ +#define MAC_CTRL_RX_EN 2 /* 1: Receive Enable */ +#define MAC_CTRL_TX_FLOW 4 /* 1: Transmit Flow Control Enable */ +#define MAC_CTRL_RX_FLOW 8 /* 1: Receive Flow Control Enable */ +#define MAC_CTRL_LOOPBACK 0x10 /* 1: Loop back at G/MII Interface */ +#define MAC_CTRL_DUPLX 0x20 /* 1: Full-duplex mode 0: Half-duplex mode */ +#define MAC_CTRL_ADD_CRC 0x40 /* 1: Instruct MAC to attach CRC on all egress Ethernet frames */ +#define MAC_CTRL_PAD 0x80 /* 1: Instruct MAC to pad short frames to 60-bytes, and then attach CRC. This bit has higher priority over CRC_EN */ +#define MAC_CTRL_PRMLEN_SHIFT 10 /* Preamble length, it's 0x07 by standard */ +#define MAC_CTRL_PRMLEN_MASK 0xf +#define MAC_CTRL_RMV_VLAN 0x4000 /* 1: to remove VLAN Tag automatically from all receive packets */ +#define MAC_CTRL_PROMIS_EN 0x8000 /* 1: Promiscuous Mode Enable */ +#define MAC_CTRL_DBG_TX_BKPRESURE 0x100000 /* 1: transmit maximum backoff (half-duplex test bit) */ +#define MAC_CTRL_MC_ALL_EN 0x2000000 /* 1: upload all multicast frame without error to system */ +#define MAC_CTRL_BC_EN 0x4000000 /* 1: upload all broadcast frame without error to system */ +#define MAC_CTRL_MACLP_CLK_PHY 0x8000000 /* 1: MAC-LoopBack clock from phy, 0:from sys_25M */ +#define MAC_CTRL_HALF_LEFT_BUF_SHIFT 28 +#define MAC_CTRL_HALF_LEFT_BUF_MASK 0xF /* When half-duplex mode, should hold some bytes for mac retry . (8*4bytes unit) */ + +/* MAC IPG/IFG Control Register */ +#define REG_MAC_IPG_IFG 0x1484 +#define MAC_IPG_IFG_IPGT_SHIFT 0 /* Desired back to back inter-packet gap. The default is 96-bit time. */ +#define MAC_IPG_IFG_IPGT_MASK 0x7f +#define MAC_IPG_IFG_MIFG_SHIFT 8 /* Minimum number of IFG to enforce in between RX frames. */ +#define MAC_IPG_IFG_MIFG_MASK 0xff /* Frame gap below such IFP is dropped. */ +#define MAC_IPG_IFG_IPGR1_SHIFT 16 /* 64bit Carrier-Sense window */ +#define MAC_IPG_IFG_IPGR1_MASK 0x7f +#define MAC_IPG_IFG_IPGR2_SHIFT 24 /* 96-bit IPG window */ +#define MAC_IPG_IFG_IPGR2_MASK 0x7f + +/* MAC STATION ADDRESS */ +#define REG_MAC_STA_ADDR 0x1488 + +/* Hash table for multicast address */ +#define REG_RX_HASH_TABLE 0x1490 + +/* MAC Half-Duplex Control Register */ +#define REG_MAC_HALF_DUPLX_CTRL 0x1498 +#define MAC_HALF_DUPLX_CTRL_LCOL_SHIFT 0 /* Collision Window. */ +#define MAC_HALF_DUPLX_CTRL_LCOL_MASK 0x3ff +#define MAC_HALF_DUPLX_CTRL_RETRY_SHIFT 12 /* Retransmission maximum, afterwards the packet will be discarded. */ +#define MAC_HALF_DUPLX_CTRL_RETRY_MASK 0xf +#define MAC_HALF_DUPLX_CTRL_EXC_DEF_EN 0x10000 /* 1: Allow the transmission of a packet which has been excessively deferred */ +#define MAC_HALF_DUPLX_CTRL_NO_BACK_C 0x20000 /* 1: No back-off on collision, immediately start the retransmission. */ +#define MAC_HALF_DUPLX_CTRL_NO_BACK_P 0x40000 /* 1: No back-off on backpressure, immediately start the transmission after back pressure */ +#define MAC_HALF_DUPLX_CTRL_ABEBE 0x80000 /* 1: Alternative Binary Exponential Back-off Enabled */ +#define MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT 20 /* Maximum binary exponential number. */ +#define MAC_HALF_DUPLX_CTRL_ABEBT_MASK 0xf +#define MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT 24 /* IPG to start JAM for collision based flow control in half-duplex */ +#define MAC_HALF_DUPLX_CTRL_JAMIPG_MASK 0xf /* mode. In unit of 8-bit time. */ + +/* Maximum Frame Length Control Register */ +#define REG_MTU 0x149c + +/* Wake-On-Lan control register */ +#define REG_WOL_CTRL 0x14a0 +#define WOL_PATTERN_EN 0x00000001 +#define WOL_PATTERN_PME_EN 0x00000002 +#define WOL_MAGIC_EN 0x00000004 +#define WOL_MAGIC_PME_EN 0x00000008 +#define WOL_LINK_CHG_EN 0x00000010 +#define WOL_LINK_CHG_PME_EN 0x00000020 +#define WOL_PATTERN_ST 0x00000100 +#define WOL_MAGIC_ST 0x00000200 +#define WOL_LINKCHG_ST 0x00000400 +#define WOL_PT0_EN 0x00010000 +#define WOL_PT1_EN 0x00020000 +#define WOL_PT2_EN 0x00040000 +#define WOL_PT3_EN 0x00080000 +#define WOL_PT4_EN 0x00100000 +#define WOL_PT0_MATCH 0x01000000 +#define WOL_PT1_MATCH 0x02000000 +#define WOL_PT2_MATCH 0x04000000 +#define WOL_PT3_MATCH 0x08000000 +#define WOL_PT4_MATCH 0x10000000 + +/* Internal SRAM Partition Register */ +#define REG_SRAM_TXRAM_END 0x1500 /* Internal tail address of TXRAM default: 2byte*1024 */ +#define REG_SRAM_RXRAM_END 0x1502 /* Internal tail address of RXRAM default: 2byte*1024 */ + +/* +#define REG_SRAM_TCPH_PATH_ADDR (REG_SRAM_RFD_ADDR+48) +#define SRAM_TCPH_ADDR_MASK 0x0fff +#define SRAM_TCPH_ADDR_SHIFT 0 +#define SRAM_PATH_ADDR_MASK 0x0fff +#define SRAM_PATH_ADDR_SHIFT 16 +*/ + +/* Descriptor Control register */ +#define REG_DESC_BASE_ADDR_HI 0x1540 +#define REG_TXD_BASE_ADDR_LO 0x1544 /* The base address of the Transmit Data Memory low 32-bit(dword align) */ +#define REG_TXD_MEM_SIZE 0x1548 /* Transmit Data Memory size(by double word , max 256KB) */ +#define REG_TXS_BASE_ADDR_LO 0x154C /* The base address of the Transmit Status Memory low 32-bit(dword word align) */ +#define REG_TXS_MEM_SIZE 0x1550 /* double word unit, max 4*2047 bytes. */ +#define REG_RXD_BASE_ADDR_LO 0x1554 /* The base address of the Transmit Status Memory low 32-bit(unit 8 bytes) */ +#define REG_RXD_BUF_NUM 0x1558 /* Receive Data & Status Memory buffer number (unit 1536bytes, max 1536*2047) */ + +/* DMAR Control Register */ +#define REG_DMAR 0x1580 +#define DMAR_EN 0x1 /* 1: Enable DMAR */ + +/* TX Cur-Through (early tx threshold) Control Register */ +#define REG_TX_CUT_THRESH 0x1590 /* TxMac begin transmit packet threshold(unit word) */ + +/* DMAW Control Register */ +#define REG_DMAW 0x15A0 +#define DMAW_EN 0x1 + +/* Flow control register */ +#define REG_PAUSE_ON_TH 0x15A8 /* RXD high watermark of overflow threshold configuration register */ +#define REG_PAUSE_OFF_TH 0x15AA /* RXD lower watermark of overflow threshold configuration register */ + +/* Mailbox Register */ +#define REG_MB_TXD_WR_IDX 0x15f0 /* double word align */ +#define REG_MB_RXD_RD_IDX 0x15F4 /* RXD Read index (unit: 1536byets) */ + +/* Interrupt Status Register */ +#define REG_ISR 0x1600 +#define ISR_TIMER 1 /* Interrupt when Timer is counted down to zero */ +#define ISR_MANUAL 2 /* Software manual interrupt, for debug. Set when SW_MAN_INT_EN is set in Table 51 Selene Master Control Register (Offset 0x1400). */ +#define ISR_RXF_OV 4 /* RXF overflow interrupt */ +#define ISR_TXF_UR 8 /* TXF underrun interrupt */ +#define ISR_TXS_OV 0x10 /* Internal transmit status buffer full interrupt */ +#define ISR_RXS_OV 0x20 /* Internal receive status buffer ful interrupt */ +#define ISR_LINK_CHG 0x40 /* Link Status Change Interrupt */ +#define ISR_HOST_TXD_UR 0x80 +#define ISR_HOST_RXD_OV 0x100 /* Host rx data memory full , one pulse */ +//#define ISR_HOST_TXS_OV 0x200 /* Host tx status memory full , one pulse */ +#define ISR_DMAR_TO_RST 0x200 /* DMAR op timeout interrupt. SW should do Reset */ +#define ISR_DMAW_TO_RST 0x400 +#define ISR_PHY 0x800 /* phy interrupt */ +#define ISR_TS_UPDATE 0x10000 /* interrupt after new tx pkt status written to host */ +#define ISR_RS_UPDATE 0x20000 /* interrupt ater new rx pkt status written to host. */ +#define ISR_TX_EARLY 0x40000 /* interrupt when txmac begin transmit one packet */ +#define ISR_UR_DETECTED 0x1000000 +#define ISR_FERR_DETECTED 0x2000000 +#define ISR_NFERR_DETECTED 0x4000000 +#define ISR_CERR_DETECTED 0x8000000 +#define ISR_PHY_LINKDOWN 0x10000000 +#define ISR_DIS_INT 0x80000000 + +#define ISR_TX_EVENT (ISR_TXF_UR|ISR_TXS_OV|ISR_HOST_TXD_UR|ISR_TS_UPDATE|ISR_TX_EARLY) +#define ISR_RX_EVENT (ISR_RXF_OV|ISR_RXS_OV|ISR_HOST_RXD_OV|ISR_RS_UPDATE) + +/* Interrupt Mask Register */ +#define REG_IMR 0x1604 + +#define IMR_NORMAL_MASK (\ + /*ISR_LINK_CHG |*/\ + ISR_MANUAL |\ + ISR_DMAR_TO_RST |\ + ISR_DMAW_TO_RST |\ + ISR_PHY |\ + ISR_PHY_LINKDOWN |\ + ISR_TS_UPDATE |\ + ISR_RS_UPDATE ) + +/* Receive MAC Statistics Registers */ +#define REG_STS_RX_PAUSE 0x1700 /* The number of Pause packet received */ +#define REG_STS_RXD_OV 0x1704 /* The number of frame dropped due to occurrence of RX FIFO overflow */ +#define REG_STS_RXS_OV 0x1708 /* The number of frame dropped due to occerrence of RX Status Buffer Overflow */ +#define REG_STS_RX_FILTER 0x170C /* The number of packet dropped due to address filtering */ + +/* MII definitions */ + +/* PHY Common Register */ +#define MII_AT001_CR 0x09 +#define MII_AT001_SR 0x0A +#define MII_AT001_ESR 0x0F +#define MII_AT001_PSCR 0x10 +#define MII_AT001_PSSR 0x11 +#define MII_SMARTSPEED 0x14 +#define MII_DBG_ADDR 0x1D +#define MII_DBG_DATA 0x1E + +/* PHY Control Register */ +#define MII_CR_SPEED_SELECT_MSB 0x0040 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_COLL_TEST_ENABLE 0x0080 /* Collision test enable */ +#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */ +#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */ +#define MII_CR_ISOLATE 0x0400 /* Isolate PHY from MII */ +#define MII_CR_POWER_DOWN 0x0800 /* Power down */ +#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */ +#define MII_CR_SPEED_SELECT_LSB 0x2000 /* bits 6,13: 10=1000, 01=100, 00=10 */ +#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */ +#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */ +#define MII_CR_SPEED_MASK 0x2040 +#define MII_CR_SPEED_1000 0x0040 +#define MII_CR_SPEED_100 0x2000 +#define MII_CR_SPEED_10 0x0000 + +/* PHY Status Register */ +#define MII_SR_EXTENDED_CAPS 0x0001 /* Extended register capabilities */ +#define MII_SR_JABBER_DETECT 0x0002 /* Jabber Detected */ +#define MII_SR_LINK_STATUS 0x0004 /* Link Status 1 = link */ +#define MII_SR_AUTONEG_CAPS 0x0008 /* Auto Neg Capable */ +#define MII_SR_REMOTE_FAULT 0x0010 /* Remote Fault Detect */ +#define MII_SR_AUTONEG_COMPLETE 0x0020 /* Auto Neg Complete */ +#define MII_SR_PREAMBLE_SUPPRESS 0x0040 /* Preamble may be suppressed */ +#define MII_SR_EXTENDED_STATUS 0x0100 /* Ext. status info in Reg 0x0F */ +#define MII_SR_100T2_HD_CAPS 0x0200 /* 100T2 Half Duplex Capable */ +#define MII_SR_100T2_FD_CAPS 0x0400 /* 100T2 Full Duplex Capable */ +#define MII_SR_10T_HD_CAPS 0x0800 /* 10T Half Duplex Capable */ +#define MII_SR_10T_FD_CAPS 0x1000 /* 10T Full Duplex Capable */ +#define MII_SR_100X_HD_CAPS 0x2000 /* 100X Half Duplex Capable */ +#define MII_SR_100X_FD_CAPS 0x4000 /* 100X Full Duplex Capable */ +#define MII_SR_100T4_CAPS 0x8000 /* 100T4 Capable */ + +/* Link partner ability register. */ +#define MII_LPA_SLCT 0x001f /* Same as advertise selector */ +#define MII_LPA_10HALF 0x0020 /* Can do 10mbps half-duplex */ +#define MII_LPA_10FULL 0x0040 /* Can do 10mbps full-duplex */ +#define MII_LPA_100HALF 0x0080 /* Can do 100mbps half-duplex */ +#define MII_LPA_100FULL 0x0100 /* Can do 100mbps full-duplex */ +#define MII_LPA_100BASE4 0x0200 /* 100BASE-T4 */ +#define MII_LPA_PAUSE 0x0400 /* PAUSE */ +#define MII_LPA_ASYPAUSE 0x0800 /* Asymmetrical PAUSE */ +#define MII_LPA_RFAULT 0x2000 /* Link partner faulted */ +#define MII_LPA_LPACK 0x4000 /* Link partner acked us */ +#define MII_LPA_NPAGE 0x8000 /* Next page bit */ + +/* Autoneg Advertisement Register */ +#define MII_AR_SELECTOR_FIELD 0x0001 /* indicates IEEE 802.3 CSMA/CD */ +#define MII_AR_10T_HD_CAPS 0x0020 /* 10T Half Duplex Capable */ +#define MII_AR_10T_FD_CAPS 0x0040 /* 10T Full Duplex Capable */ +#define MII_AR_100TX_HD_CAPS 0x0080 /* 100TX Half Duplex Capable */ +#define MII_AR_100TX_FD_CAPS 0x0100 /* 100TX Full Duplex Capable */ +#define MII_AR_100T4_CAPS 0x0200 /* 100T4 Capable */ +#define MII_AR_PAUSE 0x0400 /* Pause operation desired */ +#define MII_AR_ASM_DIR 0x0800 /* Asymmetric Pause Direction bit */ +#define MII_AR_REMOTE_FAULT 0x2000 /* Remote Fault detected */ +#define MII_AR_NEXT_PAGE 0x8000 /* Next Page ability supported */ +#define MII_AR_SPEED_MASK 0x01E0 +#define MII_AR_DEFAULT_CAP_MASK 0x0DE0 + +/* 1000BASE-T Control Register */ +#define MII_AT001_CR_1000T_HD_CAPS 0x0100 /* Advertise 1000T HD capability */ +#define MII_AT001_CR_1000T_FD_CAPS 0x0200 /* Advertise 1000T FD capability */ +#define MII_AT001_CR_1000T_REPEATER_DTE 0x0400 /* 1=Repeater/switch device port, 0=DTE device */ +#define MII_AT001_CR_1000T_MS_VALUE 0x0800 /* 1=Configure PHY as Master, 0=Configure PHY as Slave */ +#define MII_AT001_CR_1000T_MS_ENABLE 0x1000 /* 1=Master/Slave manual config value, 0=Automatic Master/Slave config */ +#define MII_AT001_CR_1000T_TEST_MODE_NORMAL 0x0000 /* Normal Operation */ +#define MII_AT001_CR_1000T_TEST_MODE_1 0x2000 /* Transmit Waveform test */ +#define MII_AT001_CR_1000T_TEST_MODE_2 0x4000 /* Master Transmit Jitter test */ +#define MII_AT001_CR_1000T_TEST_MODE_3 0x6000 /* Slave Transmit Jitter test */ +#define MII_AT001_CR_1000T_TEST_MODE_4 0x8000 /* Transmitter Distortion test */ +#define MII_AT001_CR_1000T_SPEED_MASK 0x0300 +#define MII_AT001_CR_1000T_DEFAULT_CAP_MASK 0x0300 + +/* 1000BASE-T Status Register */ +#define MII_AT001_SR_1000T_LP_HD_CAPS 0x0400 /* LP is 1000T HD capable */ +#define MII_AT001_SR_1000T_LP_FD_CAPS 0x0800 /* LP is 1000T FD capable */ +#define MII_AT001_SR_1000T_REMOTE_RX_STATUS 0x1000 /* Remote receiver OK */ +#define MII_AT001_SR_1000T_LOCAL_RX_STATUS 0x2000 /* Local receiver OK */ +#define MII_AT001_SR_1000T_MS_CONFIG_RES 0x4000 /* 1=Local TX is Master, 0=Slave */ +#define MII_AT001_SR_1000T_MS_CONFIG_FAULT 0x8000 /* Master/Slave config fault */ +#define MII_AT001_SR_1000T_REMOTE_RX_STATUS_SHIFT 12 +#define MII_AT001_SR_1000T_LOCAL_RX_STATUS_SHIFT 13 + +/* Extended Status Register */ +#define MII_AT001_ESR_1000T_HD_CAPS 0x1000 /* 1000T HD capable */ +#define MII_AT001_ESR_1000T_FD_CAPS 0x2000 /* 1000T FD capable */ +#define MII_AT001_ESR_1000X_HD_CAPS 0x4000 /* 1000X HD capable */ +#define MII_AT001_ESR_1000X_FD_CAPS 0x8000 /* 1000X FD capable */ + +/* AT001 PHY Specific Control Register */ +#define MII_AT001_PSCR_JABBER_DISABLE 0x0001 /* 1=Jabber Function disabled */ +#define MII_AT001_PSCR_POLARITY_REVERSAL 0x0002 /* 1=Polarity Reversal enabled */ +#define MII_AT001_PSCR_SQE_TEST 0x0004 /* 1=SQE Test enabled *// +#define MII_AT001_PSCR_MAC_POWERDOWN 0x0008 +#define MII_AT001_PSCR_CLK125_DISABLE 0x0010 /* 1=CLK125 low, 0=CLK125 toggling */ +#define MII_AT001_PSCR_MDI_MANUAL_MODE 0x0000 /* MDI Crossover Mode bits 6:5, Manual MDI configuration */ +#define MII_AT001_PSCR_MDIX_MANUAL_MODE 0x0020 /* Manual MDIX configuration */ +#define MII_AT001_PSCR_AUTO_X_1000T 0x0040 /* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */ +#define MII_AT001_PSCR_AUTO_X_MODE 0x0060 /* Auto crossover enabled all speeds. */ +#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE 0x0080 /* 1=Enable Extended 10BASE-T distance (Lower 10BASE-T RX Threshold), 0=Normal 10BASE-T RX Threshold */ +#define MII_AT001_PSCR_MII_5BIT_ENABLE 0x0100 /* 1=5-Bit interface in 100BASE-TX, 0=MII interface in 100BASE-TX */ +#define MII_AT001_PSCR_SCRAMBLER_DISABLE 0x0200 /* 1=Scrambler disable */ +#define MII_AT001_PSCR_FORCE_LINK_GOOD 0x0400 /* 1=Force link good */ +#define MII_AT001_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */ +#define MII_AT001_PSCR_POLARITY_REVERSAL_SHIFT 1 +#define MII_AT001_PSCR_AUTO_X_MODE_SHIFT 5 +#define MII_AT001_PSCR_10BT_EXT_DIST_ENABLE_SHIFT 7 + +/* AT001 PHY Specific Status Register */ +#define MII_AT001_PSSR_SPD_DPLX_RESOLVED 0x0800 /* 1=Speed & Duplex resolved */ +#define MII_AT001_PSSR_DPLX 0x2000 /* 1=Duplex 0=Half Duplex */ +#define MII_AT001_PSSR_SPEED 0xC000 /* Speed, bits 14:15 */ +#define MII_AT001_PSSR_10MBS 0x0000 /* 00=10Mbs */ +#define MII_AT001_PSSR_100MBS 0x4000 /* 01=100Mbs */ +#define MII_AT001_PSSR_1000MBS 0x8000 /* 10=1000Mbs */ + +/* PCI Command Register Bit Definitions */ +#define PCI_REG_COMMAND 0x04 +#define CMD_IO_SPACE 0x0001 +#define CMD_MEMORY_SPACE 0x0002 +#define CMD_BUS_MASTER 0x0004 + +/* Wake Up Filter Control */ +#define ATL2_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */ +#define ATL2_WUFC_MAG 0x00000002 /* Magic Packet Wakeup Enable */ +#define ATL2_WUFC_EX 0x00000004 /* Directed Exact Wakeup Enable */ +#define ATL2_WUFC_MC 0x00000008 /* Multicast Wakeup Enable */ +#define ATL2_WUFC_BC 0x00000010 /* Broadcast Wakeup Enable */ + +/* Error Codes */ +#define ATL2_SUCCESS 0 +#define ATL2_ERR_EEPROM 1 +#define ATL2_ERR_PHY 2 +#define ATL2_ERR_CONFIG 3 +#define ATL2_ERR_PARAM 4 +#define ATL2_ERR_MAC_TYPE 5 +#define ATL2_ERR_PHY_TYPE 6 +#define ATL2_ERR_PHY_SPEED 7 +#define ATL2_ERR_PHY_RES 8 + +#define SPEED_0 0xffff +#define SPEED_10 10 +#define SPEED_100 100 +#define HALF_DUPLEX 1 +#define FULL_DUPLEX 2 + +#define MEDIA_TYPE_AUTO_SENSOR 0 +#define MEDIA_TYPE_100M_FULL 1 +#define MEDIA_TYPE_100M_HALF 2 +#define MEDIA_TYPE_10M_FULL 3 +#define MEDIA_TYPE_10M_HALF 4 + +#define ADVERTISE_10_HALF 0x0001 +#define ADVERTISE_10_FULL 0x0002 +#define ADVERTISE_100_HALF 0x0004 +#define ADVERTISE_100_FULL 0x0008 +#define ADVERTISE_1000_HALF 0x0010 /* Not used, just FYI */ +#define ADVERTISE_1000_FULL 0x0020 + +#define AUTONEG_ADVERTISE_SPEED_DEFAULT 0x000F /* Everything */ +#define AUTONEG_ADVERTISE_10_100_ALL 0x000F /* All 10/100 speeds*/ +#define AUTONEG_ADVERTISE_10_ALL 0x0003 /* 10Mbps Full & Half speeds*/ + +/* The size (in bytes) of a ethernet packet */ +#define ENET_HEADER_SIZE 14 +#define MAXIMUM_ETHERNET_FRAME_SIZE 1518 /* with FCS */ +#define MINIMUM_ETHERNET_FRAME_SIZE 64 /* with FCS */ +#define ETHERNET_FCS_SIZE 4 +#define MAX_JUMBO_FRAME_SIZE 0x2000 +#define VLAN_SIZE 4 + +#define PHY_AUTO_NEG_TIME 45 /* 4.5 Seconds */ +#define PHY_FORCE_TIME 20 /* 2.0 Seconds */ + +/* For checksumming , the sum of all words in the EEPROM should equal 0xBABA */ +#define EEPROM_SUM 0xBABA +#define NODE_ADDRESS_SIZE 6 + +typedef struct _tx_pkt_header { + unsigned pkt_size : 11; + unsigned : 4; // reserved + unsigned ins_vlan : 1; // txmac should insert vlan + unsigned short vlan ; // vlan tag +} tx_pkt_header_t; +/* FIXME: replace above bitfields with MASK/SHIFT defines below */ +#define TX_PKT_HEADER_SIZE_MASK 0x7FF +#define TX_PKT_HEADER_SIZE_SHIFT 0 +#define TX_PKT_HEADER_INS_VLAN_MASK 0x1 +#define TX_PKT_HEADER_INS_VLAN_SHIFT 15 +#define TX_PKT_HEADER_VLAN_TAG_MASK 0xFFFF +#define TX_PKT_HEADER_VLAN_TAG_SHIFT 16 + +typedef struct _tx_pkt_status { + unsigned pkt_size : 11; + unsigned : 5; // reserved + unsigned ok : 1; // current packet is transmitted ok without error + unsigned bcast : 1; // current packet is broadcast + unsigned mcast : 1; // current packet is multicast + unsigned pause : 1; // transmiited a pause frame + unsigned ctrl : 1; + unsigned defer : 1; // current packet is xmitted with defer. + unsigned exc_defer : 1; + unsigned single_col : 1; + unsigned multi_col : 1; + unsigned late_col : 1; + unsigned abort_col : 1; + unsigned underun : 1; // current packet is abort due to txram underrun. + unsigned : 3; // reserved + unsigned update : 1; // always 1'b1 in tx_status_buf. +} tx_pkt_status_t; +/* FIXME: replace above bitfields with MASK/SHIFT defines below */ +#define TX_PKT_STATUS_SIZE_MASK 0x7FF +#define TX_PKT_STATUS_SIZE_SHIFT 0 +#define TX_PKT_STATUS_OK_MASK 0x1 +#define TX_PKT_STATUS_OK_SHIFT 16 +#define TX_PKT_STATUS_BCAST_MASK 0x1 +#define TX_PKT_STATUS_BCAST_SHIFT 17 +#define TX_PKT_STATUS_MCAST_MASK 0x1 +#define TX_PKT_STATUS_MCAST_SHIFT 18 +#define TX_PKT_STATUS_PAUSE_MASK 0x1 +#define TX_PKT_STATUS_PAUSE_SHIFT 19 +#define TX_PKT_STATUS_CTRL_MASK 0x1 +#define TX_PKT_STATUS_CTRL_SHIFT 20 +#define TX_PKT_STATUS_DEFER_MASK 0x1 +#define TX_PKT_STATUS_DEFER_SHIFT 21 +#define TX_PKT_STATUS_EXC_DEFER_MASK 0x1 +#define TX_PKT_STATUS_EXC_DEFER_SHIFT 22 +#define TX_PKT_STATUS_SINGLE_COL_MASK 0x1 +#define TX_PKT_STATUS_SINGLE_COL_SHIFT 23 +#define TX_PKT_STATUS_MULTI_COL_MASK 0x1 +#define TX_PKT_STATUS_MULTI_COL_SHIFT 24 +#define TX_PKT_STATUS_LATE_COL_MASK 0x1 +#define TX_PKT_STATUS_LATE_COL_SHIFT 25 +#define TX_PKT_STATUS_ABORT_COL_MASK 0x1 +#define TX_PKT_STATUS_ABORT_COL_SHIFT 26 +#define TX_PKT_STATUS_UNDERRUN_MASK 0x1 +#define TX_PKT_STATUS_UNDERRUN_SHIFT 27 +#define TX_PKT_STATUS_UPDATE_MASK 0x1 +#define TX_PKT_STATUS_UPDATE_SHIFT 31 + +typedef struct _rx_pkt_status { + unsigned pkt_size : 11; // packet size, max 2047bytes + unsigned : 5; // reserved + unsigned ok : 1; // current packet is received ok without error. + unsigned bcast : 1; // current packet is broadcast. + unsigned mcast : 1; // current packet is multicast. + unsigned pause : 1; + unsigned ctrl : 1; + unsigned crc : 1; // received a packet with crc error. + unsigned code : 1; // received a packet with code error. + unsigned runt : 1; // received a packet less than 64bytes with good crc + unsigned frag : 1; // ....................................with bad crc + unsigned trunc : 1; // current frame is cutted due to rxram full. + unsigned align : 1; // this packet is alignment error. + unsigned vlan : 1; // this packet has vlan + unsigned : 3; // reserved + unsigned update : 1; + unsigned short vtag ; // vlan tag + unsigned : 16; +} rx_pkt_status_t; +/* FIXME: replace above bitfields with MASK/SHIFT defines below */ +#define RX_PKT_STATUS_SIZE_MASK 0x7FF +#define RX_PKT_STATUS_SIZE_SHIFT 0 +#define RX_PKT_STATUS_OK_MASK 0x1 +#define RX_PKT_STATUS_OK_SHIFT 16 +#define RX_PKT_STATUS_BCAST_MASK 0x1 +#define RX_PKT_STATUS_BCAST_SHIFT 17 +#define RX_PKT_STATUS_MCAST_MASK 0x1 +#define RX_PKT_STATUS_MCAST_SHIFT 18 +#define RX_PKT_STATUS_PAUSE_MASK 0x1 +#define RX_PKT_STATUS_PAUSE_SHIFT 19 +#define RX_PKT_STATUS_CTRL_MASK 0x1 +#define RX_PKT_STATUS_CTRL_SHIFT 20 +#define RX_PKT_STATUS_CRC_MASK 0x1 +#define RX_PKT_STATUS_CRC_SHIFT 21 +#define RX_PKT_STATUS_CODE_MASK 0x1 +#define RX_PKT_STATUS_CODE_SHIFT 22 +#define RX_PKT_STATUS_RUNT_MASK 0x1 +#define RX_PKT_STATUS_RUNT_SHIFT 23 +#define RX_PKT_STATUS_FRAG_MASK 0x1 +#define RX_PKT_STATUS_FRAG_SHIFT 24 +#define RX_PKT_STATUS_TRUNK_MASK 0x1 +#define RX_PKT_STATUS_TRUNK_SHIFT 25 +#define RX_PKT_STATUS_ALIGN_MASK 0x1 +#define RX_PKT_STATUS_ALIGN_SHIFT 26 +#define RX_PKT_STATUS_VLAN_MASK 0x1 +#define RX_PKT_STATUS_VLAN_SHIFT 27 +#define RX_PKT_STATUS_UPDATE_MASK 0x1 +#define RX_PKT_STATUS_UPDATE_SHIFT 31 +#define RX_PKT_STATUS_VLAN_TAG_MASK 0xFFFF +#define RX_PKT_STATUS_VLAN_TAG_SHIFT 32 + +typedef struct _rx_desc { + rx_pkt_status_t status; + unsigned char packet[1536-sizeof(rx_pkt_status_t)]; +} rx_desc_t; + +typedef enum { + atl2_10_half = 0, + atl2_10_full = 1, + atl2_100_half = 2, + atl2_100_full = 3 +} atl2_speed_duplex_type; + +struct atl2_spi_flash_dev { + const char *manu_name; /* manufacturer id */ + /* op-code */ + u8 cmdWRSR; + u8 cmdREAD; + u8 cmdPROGRAM; + u8 cmdWREN; + u8 cmdWRDI; + u8 cmdRDSR; + u8 cmdRDID; + u8 cmdSECTOR_ERASE; + u8 cmdCHIP_ERASE; +}; + +/* Structure containing variables used by the shared code (atl2_hw.c) */ +struct atl2_hw { + u8 *hw_addr; + void *back; + + u8 preamble_len; + u8 max_retry; // Retransmission maximum , afterwards the packet will be discarded. + u8 jam_ipg; // IPG to start JAM for collision based flow control in half-duplex mode. In unit of 8-bit time. + u8 ipgt; // Desired back to back inter-packet gap. The default is 96-bit time. + u8 min_ifg; // Minimum number of IFG to enforce in between RX frames. Frame gap below such IFP is dropped. + u8 ipgr1; // 64bit Carrier-Sense window + u8 ipgr2; // 96-bit IPG window + u8 retry_buf; // When half-duplex mode, should hold some bytes for mac retry . (8*4bytes unit) + + u16 fc_rxd_hi; + u16 fc_rxd_lo; + u16 lcol; // Collision Window + u16 max_frame_size; + + u16 MediaType; + u16 autoneg_advertised; + u16 pci_cmd_word; + + u16 mii_autoneg_adv_reg; + + u32 mem_rang; + u32 txcw; + u32 mc_filter_type; + u32 num_mc_addrs; + u32 collision_delta; + u32 tx_packet_delta; + u16 phy_spd_default; + + u16 device_id; + u16 vendor_id; + u16 subsystem_id; + u16 subsystem_vendor_id; + u8 revision_id; + + // spi flash + u8 flash_vendor; + + u8 dma_fairness; + u8 mac_addr[NODE_ADDRESS_SIZE]; + u8 perm_mac_addr[NODE_ADDRESS_SIZE]; + + // bool phy_preamble_sup; + bool phy_configured; +}; + +#endif /* _ATL2_HW_H_ */ --- linux-2.6.28.orig/ubuntu/atl2/atl2_osdep.h +++ linux-2.6.28/ubuntu/atl2/atl2_osdep.h @@ -0,0 +1,72 @@ +/* atl2_osdep.h -- atl2 compat cruft + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel 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; 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 _ATL2_OSDEP_H_ +#define _ATL2_OSDEP_H_ + +#include +#include +#include +#include + +#define usec_delay(x) udelay(x) +#ifndef msec_delay +#define msec_delay(x) do { \ + if(in_interrupt()) BUG(); \ + else msleep(x); \ + } while (0) + +/* Some workarounds require millisecond delays and are run during interrupt + * context. Most notably, when establishing link, the phy may need tweaking + * but cannot process phy register reads/writes faster than millisecond + * intervals...and we establish link due to a "link status change" interrupt. + */ +#define msec_delay_irq(x) mdelay(x) +#endif + +#define PCI_COMMAND_REGISTER PCI_COMMAND +#define CMD_MEM_WRT_INVALIDATE PCI_COMMAND_INVALIDATE +#define ETH_ADDR_LEN ETH_ALEN + +#define ATL2_WRITE_REG(a, reg, value) (writel((value), ((a)->hw_addr + reg))) + +#define ATL2_WRITE_FLUSH(a) (readl((a)->hw_addr)) + +#define ATL2_READ_REG(a, reg) (readl((a)->hw_addr + reg)) + +#define ATL2_WRITE_REGB(a, reg, value) (writeb((value), ((a)->hw_addr + reg))) + +#define ATL2_READ_REGB(a, reg) (readb((a)->hw_addr + reg)) + +#define ATL2_WRITE_REGW(a, reg, value) (writew((value), ((a)->hw_addr + reg))) + +#define ATL2_READ_REGW(a, reg) (readw((a)->hw_addr + reg)) + +#define ATL2_WRITE_REG_ARRAY(a, reg, offset, value) \ + (writel((value), (((a)->hw_addr + reg) + ((offset) << 2)))) + +#define ATL2_READ_REG_ARRAY(a, reg, offset) \ + (readl(((a)->hw_addr + reg) + ((offset) << 2))) + +#endif /* _ATL2_OSDEP_H_ */ --- linux-2.6.28.orig/ubuntu/atl2/atl2.h +++ linux-2.6.28/ubuntu/atl2/atl2.h @@ -0,0 +1,120 @@ +/* atl2.h -- atl2 driver definitions + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel 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; 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 _ATL2_H_ +#define _ATL2_H_ + +#include +#include + +#include "atl2_hw.h" + +struct atl2_ring_header { + /* pointer to the descriptor ring memory */ + void *desc; + /* physical adress of the descriptor ring */ + dma_addr_t dma; + /* length of descriptor ring in bytes */ + unsigned int size; +}; + +/* board specific private data structure */ +struct atl2_adapter { + /* OS defined structs */ + struct net_device *netdev; + struct pci_dev *pdev; + struct net_device_stats net_stats; +#ifdef NETIF_F_HW_VLAN_TX + struct vlan_group *vlgrp; +#endif + u32 wol; + u16 link_speed; + u16 link_duplex; + + spinlock_t stats_lock; + spinlock_t tx_lock; + + struct work_struct reset_task; + struct work_struct link_chg_task; + struct timer_list watchdog_timer; + struct timer_list phy_config_timer; + + unsigned long cfg_phy; + bool mac_disabled; + + /* All Descriptor memory */ + dma_addr_t ring_dma; + void *ring_vir_addr; + int ring_size; + + tx_pkt_header_t *txd_ring; + dma_addr_t txd_dma; + + tx_pkt_status_t *txs_ring; + dma_addr_t txs_dma; + + rx_desc_t *rxd_ring; + dma_addr_t rxd_dma; + + u32 txd_ring_size; // bytes per unit + u32 txs_ring_size; // dwords per unit + u32 rxd_ring_size; // 1536bytes per unit + + // read /write ptr: + // host + u32 txd_write_ptr; + u32 txs_next_clear; + u32 rxd_read_ptr; + + // nic + atomic_t txd_read_ptr; + atomic_t txs_write_ptr; + u32 rxd_write_ptr; + + /* Interrupt Moderator timer ( 2us resolution) */ + u16 imt; + /* Interrupt Clear timer (2us resolution) */ + u16 ict; + + unsigned long flags; + /* structs defined in atl2_hw.h */ + u32 bd_number; // board number; + bool pci_using_64; + bool have_msi; + struct atl2_hw hw; + + u32 usr_cmd; +// u32 regs_buff[ATL2_REGS_LEN]; + u32 pci_state[16]; + + u32 *config_space; +}; + +enum atl2_state_t { + __ATL2_TESTING, + __ATL2_RESETTING, + __ATL2_DOWN +}; + +#endif /* _ATL2_H_ */ --- linux-2.6.28.orig/ubuntu/atl2/atl2_hw.c +++ linux-2.6.28/ubuntu/atl2/atl2_hw.c @@ -0,0 +1,760 @@ +/* atl2_hw.c -- atl2 hardware control functions + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel 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; 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 "atl2.h" +#include "atl2_hw.h" + +#define LBYTESWAP( a ) ( ( ( (a) & 0x00ff00ff ) << 8 ) | ( ( (a) & 0xff00ff00 ) >> 8 ) ) +#define LONGSWAP( a ) ( ( LBYTESWAP( a ) << 16 ) | ( LBYTESWAP( a ) >> 16 ) ) +#define SHORTSWAP( a ) ( ( (a) << 8 ) | ( (a) >> 8 ) ) + +/* + * Reset the transmit and receive units; mask and clear all interrupts. + * + * hw - Struct containing variables accessed by shared code + * return : ATL2_SUCCESS or idle status (if error) + */ +s32 +atl2_reset_hw(struct atl2_hw *hw) +{ + u32 icr; + u16 pci_cfg_cmd_word; + int i; + + /* Workaround for PCI problem when BIOS sets MMRBC incorrectly. */ + atl2_read_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word); + if ((pci_cfg_cmd_word & + (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) != + (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER)) { + pci_cfg_cmd_word |= + (CMD_IO_SPACE|CMD_MEMORY_SPACE|CMD_BUS_MASTER); + atl2_write_pci_cfg(hw, PCI_REG_COMMAND, &pci_cfg_cmd_word); + } + + /* Clear Interrupt mask to stop board from generating + * interrupts & Clear any pending interrupt events + */ +// ATL2_WRITE_REG(hw, REG_IMR, 0); +// ATL2_WRITE_REG(hw, REG_ISR, 0xffffffff); + + /* Issue Soft Reset to the MAC. This will reset the chip's + * transmit, receive, DMA. It will not effect + * the current PCI configuration. The global reset bit is self- + * clearing, and should clear within a microsecond. + */ + ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); + wmb(); + msec_delay(1); // delay about 1ms + + /* Wait at least 10ms for All module to be Idle */ + for (i=0; i < 10; i++) { + icr = ATL2_READ_REG(hw, REG_IDLE_STATUS); + if (!icr) + break; + msec_delay(1); // delay 1 ms + cpu_relax(); + } + + if (icr) + return icr; + + return ATL2_SUCCESS; +} + +#define CUSTOM_SPI_CS_SETUP 2 +#define CUSTOM_SPI_CLK_HI 2 +#define CUSTOM_SPI_CLK_LO 2 +#define CUSTOM_SPI_CS_HOLD 2 +#define CUSTOM_SPI_CS_HI 3 + +static struct atl2_spi_flash_dev flash_table[] = +{ +/* manu_name WRSR READ PROGRAM WREN WRDI RDSR RDID SECTOR_ERASE CHIP_ERASE */ + {"Atmel", 0x0, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62 }, + {"SST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60 }, + {"ST", 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xAB, 0xD8, 0xC7 }, +}; + +static bool +atl2_spi_read(struct atl2_hw* hw, u32 addr, u32* buf) +{ + int i; + u32 value; + + ATL2_WRITE_REG(hw, REG_SPI_DATA, 0); + ATL2_WRITE_REG(hw, REG_SPI_ADDR, addr); + + value = SPI_FLASH_CTRL_WAIT_READY | + (CUSTOM_SPI_CS_SETUP & SPI_FLASH_CTRL_CS_SETUP_MASK) << SPI_FLASH_CTRL_CS_SETUP_SHIFT | + (CUSTOM_SPI_CLK_HI & SPI_FLASH_CTRL_CLK_HI_MASK) << SPI_FLASH_CTRL_CLK_HI_SHIFT | + (CUSTOM_SPI_CLK_LO & SPI_FLASH_CTRL_CLK_LO_MASK) << SPI_FLASH_CTRL_CLK_LO_SHIFT | + (CUSTOM_SPI_CS_HOLD & SPI_FLASH_CTRL_CS_HOLD_MASK) << SPI_FLASH_CTRL_CS_HOLD_SHIFT | + (CUSTOM_SPI_CS_HI & SPI_FLASH_CTRL_CS_HI_MASK) << SPI_FLASH_CTRL_CS_HI_SHIFT | + (0x1 & SPI_FLASH_CTRL_INS_MASK) << SPI_FLASH_CTRL_INS_SHIFT; + + ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value); + + value |= SPI_FLASH_CTRL_START; + + ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value); + + for (i = 0; i < 10; i++) + { + msec_delay(1); // 1ms + value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL); + if (!(value & SPI_FLASH_CTRL_START)) + break; + } + + if (value & SPI_FLASH_CTRL_START) + return false; + + *buf = ATL2_READ_REG(hw, REG_SPI_DATA); + + return true; +} + +/* + * get_permanent_address + * return 0 if get valid mac address, + */ +static int +get_permanent_address(struct atl2_hw *hw) +{ + u32 Addr[2]; + u32 i, Control; + u16 Register; + u8 EthAddr[NODE_ADDRESS_SIZE]; + bool KeyValid; + + if (is_valid_ether_addr(hw->perm_mac_addr)) + return 0; + + Addr[0] = 0; + Addr[1] = 0; + + if (!atl2_check_eeprom_exist(hw)) { /* eeprom exists */ + Register = 0; + KeyValid = false; + + /* Read out all EEPROM content */ + i = 0; + while (1) { + if (atl2_read_eeprom(hw, i + 0x100, &Control)) { + if (KeyValid) { + if (Register == REG_MAC_STA_ADDR) + Addr[0] = Control; + else if (Register == (REG_MAC_STA_ADDR + 4)) + Addr[1] = Control; + KeyValid = false; + } else if ((Control & 0xff) == 0x5A) { + KeyValid = true; + Register = (u16) (Control >> 16); + } else { + break; /* assume data end while encount an invalid KEYWORD */ + } + } else { + break; /* read error */ + } + i += 4; + } + + *(u32*) &EthAddr[2] = LONGSWAP(Addr[0]); + *(u16*) &EthAddr[0] = SHORTSWAP(*(u16*)&Addr[1]); + + if (is_valid_ether_addr(EthAddr)) { + memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE); + return 0; + } + return 1; + } + + // see if SPI FLAHS exist ? + Addr[0] = 0; + Addr[1] = 0; + Register = 0; + KeyValid = false; + i = 0; + while (1) { + if (atl2_spi_read(hw, i + 0x1f000, &Control)) { + if (KeyValid) { + if (Register == REG_MAC_STA_ADDR) + Addr[0] = Control; + else if (Register == (REG_MAC_STA_ADDR + 4)) + Addr[1] = Control; + KeyValid = false; + } else if ((Control & 0xff) == 0x5A) { + KeyValid = true; + Register = (u16) (Control >> 16); + } else { + break; /* data end */ + } + } else { + break; /* read error */ + } + i += 4; + } + + *(u32*) &EthAddr[2] = LONGSWAP(Addr[0]); + *(u16*) &EthAddr[0] = SHORTSWAP(*(u16*)&Addr[1]); + if (is_valid_ether_addr(EthAddr)) { + memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE); + return 0; + } + /* maybe MAC-address is from BIOS */ + Addr[0] = ATL2_READ_REG(hw,REG_MAC_STA_ADDR); + Addr[1] = ATL2_READ_REG(hw,REG_MAC_STA_ADDR+4); + *(u32*) &EthAddr[2] = LONGSWAP(Addr[0]); + *(u16*) &EthAddr[0] = SHORTSWAP(*(u16*)&Addr[1]); + + if (is_valid_ether_addr(EthAddr)) { + memcpy(hw->perm_mac_addr, EthAddr, NODE_ADDRESS_SIZE); + return 0; + } + + return 1; +} + +/* + * Reads the adapter's MAC address from the EEPROM + * + * hw - Struct containing variables accessed by shared code + */ +s32 +atl2_read_mac_addr(struct atl2_hw *hw) +{ + u16 i; + + if (get_permanent_address(hw)) { + // for test + hw->perm_mac_addr[0] = 0x00; + hw->perm_mac_addr[1] = 0x13; + hw->perm_mac_addr[2] = 0x74; + hw->perm_mac_addr[3] = 0x00; + hw->perm_mac_addr[4] = 0x5c; + hw->perm_mac_addr[5] = 0x38; + } + + for(i = 0; i < NODE_ADDRESS_SIZE; i++) + hw->mac_addr[i] = hw->perm_mac_addr[i]; + + return ATL2_SUCCESS; +} + +/* + * Hashes an address to determine its location in the multicast table + * + * hw - Struct containing variables accessed by shared code + * mc_addr - the multicast address to hash + * + * atl2_hash_mc_addr + * purpose + * set hash value for a multicast address + * hash calcu processing : + * 1. calcu 32bit CRC for multicast address + * 2. reverse crc with MSB to LSB + */ +u32 +atl2_hash_mc_addr(struct atl2_hw *hw, u8 *mc_addr) +{ + u32 crc32, value=0; + int i; + + crc32 = ether_crc_le(6, mc_addr); + + for (i=0; i<32; i++) + value |= (((crc32>>i)&1)<<(31-i)); + + return value; +} + +/* + * Sets the bit in the multicast table corresponding to the hash value. + * + * hw - Struct containing variables accessed by shared code + * hash_value - Multicast address hash value + */ +void +atl2_hash_set(struct atl2_hw *hw, u32 hash_value) +{ + u32 hash_bit, hash_reg; + u32 mta; + + /* The HASH Table is a register array of 2 32-bit registers. + * It is treated like an array of 64 bits. We want to set + * bit BitArray[hash_value]. So we figure out what register + * the bit is in, read it, OR in the new bit, then write + * back the new value. The register is determined by the + * upper 7 bits of the hash value and the bit within that + * register are determined by the lower 5 bits of the value. + */ + hash_reg = (hash_value >> 31) & 0x1; + hash_bit = (hash_value >> 26) & 0x1F; + + mta = ATL2_READ_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg); + + mta |= (1 << hash_bit); + + ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, hash_reg, mta); +} + +/* + * atl2_init_pcie - init PCIE module + */ +static void +atl2_init_pcie(struct atl2_hw *hw) +{ + u32 value; + value = LTSSM_TEST_MODE_DEF; + ATL2_WRITE_REG(hw, REG_LTSSM_TEST_MODE, value); + + value = PCIE_DLL_TX_CTRL1_DEF; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, value); +} + +void +atl2_init_flash_opcode(struct atl2_hw *hw) +{ + if (hw->flash_vendor >= ARRAY_SIZE(flash_table)) { + hw->flash_vendor = 0; // ATMEL + } + // Init OP table + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_PROGRAM, flash_table[hw->flash_vendor].cmdPROGRAM); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_SC_ERASE, flash_table[hw->flash_vendor].cmdSECTOR_ERASE); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_CHIP_ERASE, flash_table[hw->flash_vendor].cmdCHIP_ERASE); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDID, flash_table[hw->flash_vendor].cmdRDID); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WREN, flash_table[hw->flash_vendor].cmdWREN); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_RDSR, flash_table[hw->flash_vendor].cmdRDSR); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_WRSR, flash_table[hw->flash_vendor].cmdWRSR); + ATL2_WRITE_REGB(hw, REG_SPI_FLASH_OP_READ, flash_table[hw->flash_vendor].cmdREAD); +} + +/******************************************************************** +* Performs basic configuration of the adapter. +* +* hw - Struct containing variables accessed by shared code +* Assumes that the controller has previously been reset and is in a +* post-reset uninitialized state. Initializes multicast table, +* and Calls routines to setup link +* Leaves the transmit and receive units disabled and uninitialized. +********************************************************************/ +s32 +atl2_init_hw(struct atl2_hw *hw) +{ + u32 ret_val = 0; + + atl2_init_pcie(hw); + + /* Zero out the Multicast HASH table */ + /* clear the old settings from the multicast hash table */ + ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); + ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); + + atl2_init_flash_opcode(hw); + + ret_val = atl2_phy_init(hw); + + return ret_val; +} + +/* + * Detects the current speed and duplex settings of the hardware. + * + * hw - Struct containing variables accessed by shared code + * speed - Speed of the connection + * duplex - Duplex setting of the connection + */ +s32 +atl2_get_speed_and_duplex(struct atl2_hw *hw, u16 *speed, u16 *duplex) +{ + s32 ret_val; + u16 phy_data; + + // ; --- Read PHY Specific Status Register (17) + ret_val = atl2_read_phy_reg(hw, MII_AT001_PSSR, &phy_data); + if (ret_val) + return ret_val; + + if (!(phy_data & MII_AT001_PSSR_SPD_DPLX_RESOLVED)) + return ATL2_ERR_PHY_RES; + + switch(phy_data & MII_AT001_PSSR_SPEED) { + case MII_AT001_PSSR_100MBS: + *speed = SPEED_100; + break; + case MII_AT001_PSSR_10MBS: + *speed = SPEED_10; + break; + default: + return ATL2_ERR_PHY_SPEED; + break; + } + + if (phy_data & MII_AT001_PSSR_DPLX) { + *duplex = FULL_DUPLEX; + } else { + *duplex = HALF_DUPLEX; + } + + return ATL2_SUCCESS; +} + +/* + * Reads the value from a PHY register + * hw - Struct containing variables accessed by shared code + * reg_addr - address of the PHY register to read + */ +s32 +atl2_read_phy_reg(struct atl2_hw *hw, u16 reg_addr, u16 *phy_data) +{ + u32 val; + int i; + + val = ((u32)(reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | + MDIO_START | + MDIO_SUP_PREAMBLE | + MDIO_RW | + MDIO_CLK_25_4 << MDIO_CLK_SEL_SHIFT; + ATL2_WRITE_REG(hw, REG_MDIO_CTRL, val); + + wmb(); + + for (i=0; iMediaType) { + case MEDIA_TYPE_AUTO_SENSOR: + mii_autoneg_adv_reg |= + (MII_AR_10T_HD_CAPS | + MII_AR_10T_FD_CAPS | + MII_AR_100TX_HD_CAPS | + MII_AR_100TX_FD_CAPS); + hw->autoneg_advertised = + ADVERTISE_10_HALF | + ADVERTISE_10_FULL | + ADVERTISE_100_HALF | + ADVERTISE_100_FULL; + break; + case MEDIA_TYPE_100M_FULL: + mii_autoneg_adv_reg |= MII_AR_100TX_FD_CAPS; + hw->autoneg_advertised = ADVERTISE_100_FULL; + break; + case MEDIA_TYPE_100M_HALF: + mii_autoneg_adv_reg |= MII_AR_100TX_HD_CAPS; + hw->autoneg_advertised = ADVERTISE_100_HALF; + break; + case MEDIA_TYPE_10M_FULL: + mii_autoneg_adv_reg |= MII_AR_10T_FD_CAPS; + hw->autoneg_advertised = ADVERTISE_10_FULL; + break; + default: + mii_autoneg_adv_reg |= MII_AR_10T_HD_CAPS; + hw->autoneg_advertised = ADVERTISE_10_HALF; + break; + } + + /* flow control fixed to enable all */ + mii_autoneg_adv_reg |= (MII_AR_ASM_DIR | MII_AR_PAUSE); + + hw->mii_autoneg_adv_reg = mii_autoneg_adv_reg; + + ret_val = atl2_write_phy_reg(hw, MII_ADVERTISE, mii_autoneg_adv_reg); + + if(ret_val) + return ret_val; + + return ATL2_SUCCESS; +} + +/* + * Resets the PHY and make all config validate + * + * hw - Struct containing variables accessed by shared code + * + * Sets bit 15 and 12 of the MII Control regiser (for F001 bug) + */ +static s32 +atl2_phy_commit(struct atl2_hw *hw) +{ + s32 ret_val; + u16 phy_data; + +/* FIXME: use or remove -- CHS + if (hw->MediaType == MEDIA_TYPE_AUTO_SENSOR) { + phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN; + } else { + switch (hw->MediaType) + { + case MEDIA_TYPE_100M_FULL: + phy_data = MII_CR_FULL_DUPLEX|MII_CR_SPEED_100|MII_CR_RESET; + break; + case MEDIA_TYPE_100M_HALF: + phy_data = MII_CR_SPEED_100|MII_CR_RESET; + break; + case MEDIA_TYPE_10M_FULL: + phy_data = MII_CR_FULL_DUPLEX|MII_CR_SPEED_10|MII_CR_RESET; + break; + default: // MEDIA_TYPE_10M_HALF: + phy_data = MII_CR_SPEED_10|MII_CR_RESET; + break; + } + } +*/ + phy_data = MII_CR_RESET | MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG; + ret_val = atl2_write_phy_reg(hw, MII_BMCR, phy_data); + if (ret_val) { // bug fixed + u32 val; + int i; + /* pcie serdes link may be down ! */ + for (i=0; i < 25; i++) { + msec_delay(1); + val = ATL2_READ_REG(hw, REG_MDIO_CTRL); + if (!(val & (MDIO_START | MDIO_BUSY))) + break; + } + + if (0 != (val & (MDIO_START | MDIO_BUSY))) { + printk(KERN_ERR "atl2: PCIe link down for at least 25ms !\n"); + return ret_val; + } + } + return ATL2_SUCCESS; +} + +s32 +atl2_phy_init(struct atl2_hw *hw) +{ + s32 ret_val; + u16 phy_val; + + if (hw->phy_configured) + return 0; + + /* Enable PHY */ + ATL2_WRITE_REGW(hw, REG_PHY_ENABLE, 1); + ATL2_WRITE_FLUSH(hw); + msec_delay(1); + + /* check if the PHY is in powersaving mode */ + atl2_write_phy_reg(hw, MII_DBG_ADDR, 0); + atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val); + + /* 024E / 124E 0r 0274 / 1274 ? */ + if (phy_val & 0x1000) { + phy_val &= ~0x1000; + atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val); + } + + msec_delay(1); + + + /*Enable PHY LinkChange Interrupt */ + ret_val = atl2_write_phy_reg(hw, 18, 0xC00); + if (ret_val) + return ret_val; + + /* setup AutoNeg parameters */ + ret_val = atl2_phy_setup_autoneg_adv(hw); + if(ret_val) + return ret_val; + + /* SW.Reset & En-Auto-Neg to restart Auto-Neg */ + ret_val = atl2_phy_commit(hw); + if (ret_val) + return ret_val; + + hw->phy_configured = true; + + return ret_val; +} + +void +atl2_set_mac_addr(struct atl2_hw *hw) +{ + u32 value; + // 00-0B-6A-F6-00-DC + // 0: 6AF600DC 1: 000B + // low dword + value = (((u32)hw->mac_addr[2]) << 24) | + (((u32)hw->mac_addr[3]) << 16) | + (((u32)hw->mac_addr[4]) << 8 ) | + (((u32)hw->mac_addr[5]) ) ; + ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 0, value); + // hight dword + value = (((u32)hw->mac_addr[0]) << 8 ) | + (((u32)hw->mac_addr[1]) ) ; + ATL2_WRITE_REG_ARRAY(hw, REG_MAC_STA_ADDR, 1, value); +} + +/* + * check_eeprom_exist + * return 0 if eeprom exist + */ +int +atl2_check_eeprom_exist(struct atl2_hw *hw) +{ + u32 value; + + value = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL); + if (value & SPI_FLASH_CTRL_EN_VPD) { + value &= ~SPI_FLASH_CTRL_EN_VPD; + ATL2_WRITE_REG(hw, REG_SPI_FLASH_CTRL, value); + } + value = ATL2_READ_REGW(hw, REG_PCIE_CAP_LIST); + return ((value & 0xFF00) == 0x6C00) ? 0 : 1; +} + +// FIXME: This doesn't look right. -- CHS +bool +atl2_write_eeprom(struct atl2_hw *hw, u32 offset, u32 value) +{ + return true; +} + +bool +atl2_read_eeprom(struct atl2_hw *hw, u32 Offset, u32 *pValue) +{ + int i; + u32 Control; + + if (Offset & 0x3) + return false; /* address do not align */ + + ATL2_WRITE_REG(hw, REG_VPD_DATA, 0); + Control = (Offset & VPD_CAP_VPD_ADDR_MASK) << VPD_CAP_VPD_ADDR_SHIFT; + ATL2_WRITE_REG(hw, REG_VPD_CAP, Control); + + for (i = 0; i < 10; i++) { + msec_delay(2); + Control = ATL2_READ_REG(hw, REG_VPD_CAP); + if (Control & VPD_CAP_VPD_FLAG) + break; + } + + if (Control & VPD_CAP_VPD_FLAG) { + *pValue = ATL2_READ_REG(hw, REG_VPD_DATA); + return true; + } + return false; /* timeout */ +} + +void +atl2_force_ps(struct atl2_hw *hw) +{ + u16 phy_val; + + atl2_write_phy_reg(hw, MII_DBG_ADDR, 0); + atl2_read_phy_reg(hw, MII_DBG_DATA, &phy_val); + atl2_write_phy_reg(hw, MII_DBG_DATA, phy_val | 0x1000); + + atl2_write_phy_reg(hw, MII_DBG_ADDR, 2); + atl2_write_phy_reg(hw, MII_DBG_DATA, 0x3000); + atl2_write_phy_reg(hw, MII_DBG_ADDR, 3); + atl2_write_phy_reg(hw, MII_DBG_DATA, 0); +} --- linux-2.6.28.orig/ubuntu/atl2/atl2_main.c +++ linux-2.6.28/ubuntu/atl2/atl2_main.c @@ -0,0 +1,1851 @@ +/* atl2_main.c -- atl2 driver main functions + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel 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; 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "atl2.h" + +#define ATL2_DRV_VERSION "2.0.4" + +char atl2_driver_name[] = "atl2"; +static const char atl2_driver_string[] = "Atheros(R) L2 Ethernet Driver"; +static char atl2_copyright[] = "Copyright (c) 2007 Atheros Corporation."; +char atl2_driver_version[] = ATL2_DRV_VERSION; + +MODULE_AUTHOR("Atheros Corporation , Chris Snook "); +MODULE_DESCRIPTION("Atheros Fast Ethernet Network Driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(ATL2_DRV_VERSION); + +/* FIXME: remove this after merging, goes in pci_ids.h */ +#ifndef PCI_DEVICE_ID_ATTANSIC_L2 +#define PCI_DEVICE_ID_ATTANSIC_L2 0x2048 +#endif + +/* + * atl2_pci_tbl - PCI Device ID Table + */ +static struct pci_device_id atl2_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L2)}, + /* required last entry */ + {0,} +}; +MODULE_DEVICE_TABLE(pci, atl2_pci_tbl); + +extern void atl2_set_ethtool_ops(struct net_device *netdev); +#ifdef ETHTOOL_OPS_COMPAT +extern int ethtool_ioctl(struct ifreq *ifr); +#endif + +#define COPYBREAK_DEFAULT 256 +static unsigned int copybreak __read_mostly = COPYBREAK_DEFAULT; +module_param(copybreak, uint, 0644); +MODULE_PARM_DESC(copybreak, "Maximum size of packet that is copied to a new buffer on receive"); + +extern void atl2_check_options(struct atl2_adapter *adapter); +#ifdef SIOCDEVPRIVATE +extern int atl2_priv_ioctl(struct net_device* netdev, struct ifreq* ifr); +#endif + +/** + * atl2_sw_init - Initialize general software structures (struct atl2_adapter) + * @adapter: board private structure to initialize + * + * atl2_sw_init initializes the Adapter private data structure. + * Fields are initialized based on PCI device information and + * OS network device settings (MTU size). + **/ +static int __devinit +atl2_sw_init(struct atl2_adapter *adapter) +{ + struct atl2_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; + + /* PCI config space info */ + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_id = pdev->subsystem_device; + + pci_read_config_byte(pdev, PCI_REVISION_ID, &hw->revision_id); + pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); + + adapter->wol = 0; + adapter->ict = 50000; // 100ms + adapter->link_speed = SPEED_0; // hardware init + adapter->link_duplex = FULL_DUPLEX; + + hw->phy_configured = false; + hw->preamble_len = 7; + hw->ipgt = 0x60; + hw->min_ifg = 0x50; + hw->ipgr1 = 0x40; + hw->ipgr2 = 0x60; + hw->retry_buf = 2; + hw->max_retry = 0xf; + hw->lcol = 0x37; + hw->jam_ipg = 7; + hw->fc_rxd_hi = 0; + hw->fc_rxd_lo = 0; + hw->max_frame_size = adapter->netdev->mtu; + + spin_lock_init(&adapter->stats_lock); + spin_lock_init(&adapter->tx_lock); + + set_bit(__ATL2_DOWN, &adapter->flags); + + return 0; +} + +/** + * atl2_set_multi - Multicast and Promiscuous mode set + * @netdev: network interface device structure + * + * The set_multi entry point is called whenever the multicast address + * list or the network interface flags are updated. This routine is + * responsible for configuring the hardware for proper multicast, + * promiscuous mode, and all-multi behavior. + **/ +static void +atl2_set_multi(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + struct dev_mc_list *mc_ptr; + u32 rctl; + u32 hash_value; + + /* Check for Promiscuous and All Multicast modes */ + rctl = ATL2_READ_REG(hw, REG_MAC_CTRL); + + if(netdev->flags & IFF_PROMISC) { + rctl |= MAC_CTRL_PROMIS_EN; + } else if(netdev->flags & IFF_ALLMULTI) { + rctl |= MAC_CTRL_MC_ALL_EN; + rctl &= ~MAC_CTRL_PROMIS_EN; + } else { + rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN); + } + + ATL2_WRITE_REG(hw, REG_MAC_CTRL, rctl); + + /* clear the old settings from the multicast hash table */ + ATL2_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); + ATL2_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); + + /* comoute mc addresses' hash value ,and put it into hash table */ + for(mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { + hash_value = atl2_hash_mc_addr(hw, mc_ptr->dmi_addr); + atl2_hash_set(hw, hash_value); + } +} + +static void +init_ring_ptrs(struct atl2_adapter *adapter) +{ + // Read / Write Ptr Initialize: + adapter->txd_write_ptr = 0; + atomic_set(&adapter->txd_read_ptr, 0); + + adapter->rxd_read_ptr = 0; + adapter->rxd_write_ptr = 0; + + atomic_set(&adapter->txs_write_ptr, 0); + adapter->txs_next_clear = 0; +} + +/** + * atl2_configure - Configure Transmit&Receive Unit after Reset + * @adapter: board private structure + * + * Configure the Tx /Rx unit of the MAC after a reset. + **/ +static int +atl2_configure(struct atl2_adapter *adapter) +{ + struct atl2_hw * hw = &adapter->hw; + u32 value; + + // clear interrupt status + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0xffffffff); + + // set MAC Address + value = (((u32)hw->mac_addr[2]) << 24) | + (((u32)hw->mac_addr[3]) << 16) | + (((u32)hw->mac_addr[4]) << 8 ) | + (((u32)hw->mac_addr[5]) ) ; + ATL2_WRITE_REG(hw, REG_MAC_STA_ADDR, value); + value = (((u32)hw->mac_addr[0]) << 8 ) | + (((u32)hw->mac_addr[1]) ) ; + ATL2_WRITE_REG(hw, (REG_MAC_STA_ADDR+4), value); + + // HI base address + ATL2_WRITE_REG(hw, REG_DESC_BASE_ADDR_HI, + (u32)((adapter->ring_dma & 0xffffffff00000000ULL) >> 32)); + + // LO base address + ATL2_WRITE_REG(hw, REG_TXD_BASE_ADDR_LO, + (u32)(adapter->txd_dma & 0x00000000ffffffffULL)); + ATL2_WRITE_REG(hw, REG_TXS_BASE_ADDR_LO, + (u32)(adapter->txs_dma & 0x00000000ffffffffULL)); + ATL2_WRITE_REG(hw, REG_RXD_BASE_ADDR_LO, + (u32)(adapter->rxd_dma & 0x00000000ffffffffULL)); + + // element count + ATL2_WRITE_REGW(hw, REG_TXD_MEM_SIZE, (u16)(adapter->txd_ring_size/4)); + ATL2_WRITE_REGW(hw, REG_TXS_MEM_SIZE, (u16)adapter->txs_ring_size); + ATL2_WRITE_REGW(hw, REG_RXD_BUF_NUM, (u16)adapter->rxd_ring_size); + + /* config Internal SRAM */ +/* + ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_tx_end); + ATL2_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_rx_end); +*/ + + /* config IPG/IFG */ + value = (((u32)hw->ipgt & MAC_IPG_IFG_IPGT_MASK) << MAC_IPG_IFG_IPGT_SHIFT) | + (((u32)hw->min_ifg & MAC_IPG_IFG_MIFG_MASK) << MAC_IPG_IFG_MIFG_SHIFT) | + (((u32)hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK) << MAC_IPG_IFG_IPGR1_SHIFT)| + (((u32)hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK) << MAC_IPG_IFG_IPGR2_SHIFT); + ATL2_WRITE_REG(hw, REG_MAC_IPG_IFG, value); + + /* config Half-Duplex Control */ + value = ((u32)hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) | + (((u32)hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK) << + MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) | + MAC_HALF_DUPLX_CTRL_EXC_DEF_EN | + (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) | + (((u32)hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) << + MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT); + ATL2_WRITE_REG(hw, REG_MAC_HALF_DUPLX_CTRL, value); + + /* set Interrupt Moderator Timer */ + ATL2_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, adapter->imt); + ATL2_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_ITIMER_EN); + + /* set Interrupt Clear Timer */ + ATL2_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, adapter->ict); + + /* set MTU */ + ATL2_WRITE_REG(hw, REG_MTU, adapter->netdev->mtu + + ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE); + + /* 1590 */ + ATL2_WRITE_REG(hw, REG_TX_CUT_THRESH, 0x177); + + /* flow control */ + ATL2_WRITE_REGW(hw, REG_PAUSE_ON_TH, hw->fc_rxd_hi); + ATL2_WRITE_REGW(hw, REG_PAUSE_OFF_TH, hw->fc_rxd_lo); + + /* Init mailbox */ + ATL2_WRITE_REGW(hw, REG_MB_TXD_WR_IDX, (u16)adapter->txd_write_ptr); + ATL2_WRITE_REGW(hw, REG_MB_RXD_RD_IDX, (u16)adapter->rxd_read_ptr); + + /* enable DMA read/write */ + ATL2_WRITE_REGB(hw, REG_DMAR, DMAR_EN); + ATL2_WRITE_REGB(hw, REG_DMAW, DMAW_EN); + + value = ATL2_READ_REG(&adapter->hw, REG_ISR); + if ((value & ISR_PHY_LINKDOWN) != 0) { + value = 1; // config failed + } else { + value = 0; + } + + // clear all interrupt status + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0x3fffffff); + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0); + return value; +} + +/** + * atl2_setup_ring_resources - allocate Tx / RX descriptor resources + * @adapter: board private structure + * + * Return 0 on success, negative on failure + **/ +static s32 +atl2_setup_ring_resources(struct atl2_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + int size; + u8 offset = 0; + + /* real ring DMA buffer */ + adapter->ring_size = size = + adapter->txd_ring_size * 1 + 7 + // dword align + adapter->txs_ring_size * 4 + 7 + // dword align + adapter->rxd_ring_size * 1536 + 127; // 128bytes align + + adapter->ring_vir_addr = pci_alloc_consistent(pdev, size, &adapter->ring_dma); + if (!adapter->ring_vir_addr) { + return -ENOMEM; + } +#if 0 + if (adapter->pci_using_64) { + // test whether HIDWORD dma buffer is not cross boundary + if ( ((adapter->ring_dma &0xffffffff00000000ULL)>>32) + != (((adapter->ring_dma+size)&0xffffffff00000000ULL)>>32) ) { + pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr, adapter->ring_dma); + DEBUGOUT("memory allocated cross 32bit boundary !"); + return -ENOMEM; + } + } +#endif + memset(adapter->ring_vir_addr, 0, adapter->ring_size); + + // Init TXD Ring + adapter->txd_dma = adapter->ring_dma ; + offset = (adapter->txd_dma & 0x7) ? (8 - (adapter->txd_dma & 0x7)) : 0; + adapter->txd_dma += offset; + adapter->txd_ring = (tx_pkt_header_t*) (adapter->ring_vir_addr + offset); + + // Init TXS Ring + adapter->txs_dma = adapter->txd_dma + adapter->txd_ring_size; + offset = (adapter->txs_dma & 0x7) ? (8- (adapter->txs_dma & 0x7)) : 0; + adapter->txs_dma += offset; + adapter->txs_ring = (tx_pkt_status_t*) + (((u8*)adapter->txd_ring) + (adapter->txd_ring_size+offset)); + + // Init RXD Ring + adapter->rxd_dma = adapter->txs_dma + adapter->txs_ring_size*4; + offset = (adapter->rxd_dma & 127) ? (128 - (adapter->rxd_dma & 127)) : 0; + if (offset > 7) { + offset -= 8; + } else { + offset += (128 - 8); + } + adapter->rxd_dma += offset; + adapter->rxd_ring = (rx_desc_t*) (((u8*)adapter->txs_ring) + + (adapter->txs_ring_size*4 + offset)); + +// Read / Write Ptr Initialize: +// init_ring_ptrs(adapter); + + return ATL2_SUCCESS; +} + +/** + * atl2_irq_enable - Enable default interrupt generation settings + * @adapter: board private structure + **/ +static inline void +atl2_irq_enable(struct atl2_adapter *adapter) +{ + ATL2_WRITE_REG(&adapter->hw, REG_IMR, IMR_NORMAL_MASK); + ATL2_WRITE_FLUSH(&adapter->hw); +} + +/** + * atl2_irq_disable - Mask off interrupt generation on the NIC + * @adapter: board private structure + **/ +static inline void +atl2_irq_disable(struct atl2_adapter *adapter) +{ + ATL2_WRITE_REG(&adapter->hw, REG_IMR, 0); + ATL2_WRITE_FLUSH(&adapter->hw); + synchronize_irq(adapter->pdev->irq); +} + +#ifdef NETIF_F_HW_VLAN_TX +static void +atl2_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + u32 ctrl; + + atl2_irq_disable(adapter); + adapter->vlgrp = grp; + + if(grp) { + /* enable VLAN tag insert/strip */ + ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); + ctrl |= MAC_CTRL_RMV_VLAN; + ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); + } else { + /* disable VLAN tag insert/strip */ + ctrl = ATL2_READ_REG(&adapter->hw, REG_MAC_CTRL); + ctrl &= ~MAC_CTRL_RMV_VLAN; + ATL2_WRITE_REG(&adapter->hw, REG_MAC_CTRL, ctrl); + } + + atl2_irq_enable(adapter); +} + +static void +atl2_restore_vlan(struct atl2_adapter *adapter) +{ + atl2_vlan_rx_register(adapter->netdev, adapter->vlgrp); +} +#endif + +static void +atl2_intr_rx(struct atl2_adapter* adapter) +{ + struct net_device *netdev = adapter->netdev; + rx_desc_t* rxd; + struct sk_buff* skb; + + do { + rxd = adapter->rxd_ring+adapter->rxd_write_ptr; + if (!rxd->status.update) + break; // end of tx + + // clear this flag at once + rxd->status.update = 0; + + if (rxd->status.ok && rxd->status.pkt_size >= 60) { + int rx_size = (int)(rxd->status.pkt_size - 4); + // alloc new buffer + skb = netdev_alloc_skb(netdev, rx_size + NET_IP_ALIGN); + if (NULL == skb) { + printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n", + netdev->name); + /* We should check that some rx space is free. + * If not, free one and mark stats->rx_dropped++. */ + adapter->net_stats.rx_dropped++; + break; + } +/* FIXME: ??? + if (rx_size > 1400) { + int s,c; + c = 0; + printk("rx_size= %d\n", rx_size); + for (s=0; s < 800; s++) { + if (0 == c) { + printk("%04x ", s); + } + printk("%02x ", rxd->packet[s]); + if (++c == 16) { + c = 0; + printk("\n"); + } + } + printk(KERN_WARNING"\n"); + } +*/ + skb_reserve(skb, NET_IP_ALIGN); + skb->dev = netdev; +/* gone in 2.6.23, just use memcpy? -- CHS + eth_copy_and_sum(skb, rxd->packet, rx_size, 0); */ + memcpy(skb->data, rxd->packet, rx_size); /* totally untested -- CHS */ + skb_put(skb, rx_size); + /* FIXME ??? + memcpy(skb_put(skb, rx_size), + rxd->packet, + rx_size); + */ + skb->protocol = eth_type_trans(skb, netdev); +#ifdef NETIF_F_HW_VLAN_TX + if(adapter->vlgrp && (rxd->status.vlan)) { + u16 vlan_tag = (rxd->status.vtag>>4) | + ((rxd->status.vtag&7) << 13) | + ((rxd->status.vtag&8) << 9); + vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag); + } else +#endif + netif_rx(skb); + adapter->net_stats.rx_bytes += rx_size; + adapter->net_stats.rx_packets++; + netdev->last_rx = jiffies; + } else { + adapter->net_stats.rx_errors++; + + if (rxd->status.ok && rxd->status.pkt_size <= 60) { + adapter->net_stats.rx_length_errors++; + } + if (rxd->status.mcast) adapter->net_stats.multicast++; + if (rxd->status.crc) adapter->net_stats.rx_crc_errors++; + if (rxd->status.align) adapter->net_stats.rx_frame_errors++; + } + + // advance write ptr + if (++adapter->rxd_write_ptr == adapter->rxd_ring_size) + adapter->rxd_write_ptr = 0; + } while (1); + + // update mailbox ? + adapter->rxd_read_ptr = adapter->rxd_write_ptr; + ATL2_WRITE_REGW(&adapter->hw, REG_MB_RXD_RD_IDX, adapter->rxd_read_ptr); +} + +static void +atl2_intr_tx(struct atl2_adapter* adapter) +{ + u32 txd_read_ptr; + u32 txs_write_ptr; + tx_pkt_status_t* txs; + tx_pkt_header_t* txph; + int free_hole = 0; + + do { + txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr); + txs = adapter->txs_ring + txs_write_ptr; + if (!txs->update) + break; // tx stop here + + free_hole = 1; + txs->update = 0; + + if (++txs_write_ptr == adapter->txs_ring_size) + txs_write_ptr = 0; + atomic_set(&adapter->txs_write_ptr, (int)txs_write_ptr); + + txd_read_ptr = (u32) atomic_read(&adapter->txd_read_ptr); + txph = (tx_pkt_header_t*) (((u8*)adapter->txd_ring) + txd_read_ptr); + + if ( txph->pkt_size != txs->pkt_size) { + tx_pkt_status_t* old_txs = txs; + printk(KERN_WARNING + "%s: txs packet size do not coinsist with txd" + " txd_:0x%08x, txs_:0x%08x!\n", + adapter->netdev->name, + *(u32*)txph, *(u32*)txs); + printk(KERN_WARNING + "txd read ptr: 0x%x\n", + txd_read_ptr); + txs = adapter->txs_ring + txs_write_ptr; + printk(KERN_WARNING + "txs-behind:0x%08x\n", + *(u32*)txs); + if (txs_write_ptr < 2) { + txs = adapter->txs_ring + + (adapter->txs_ring_size + + txs_write_ptr - 2); + } else { + txs = adapter->txs_ring + (txs_write_ptr - 2); + } + printk(KERN_WARNING + "txs-before:0x%08x\n", + *(u32*)txs); + txs = old_txs; + } + + txd_read_ptr += (((u32)(txph->pkt_size)+7)& ~3);//4for TPH + if (txd_read_ptr >= adapter->txd_ring_size) + txd_read_ptr -= adapter->txd_ring_size; + + atomic_set(&adapter->txd_read_ptr, (int)txd_read_ptr); + + // tx statistics: + if (txs->ok) + adapter->net_stats.tx_packets++; + else + adapter->net_stats.tx_errors++; + + if (txs->defer) adapter->net_stats.collisions++; + if (txs->abort_col) adapter->net_stats.tx_aborted_errors++; + if (txs->late_col) adapter->net_stats.tx_window_errors++; + if (txs->underun) adapter->net_stats.tx_fifo_errors++; + } while (1); + + if (free_hole) { + if(netif_queue_stopped(adapter->netdev) && + netif_carrier_ok(adapter->netdev)) + netif_wake_queue(adapter->netdev); + } +} + +static void +atl2_check_for_link(struct atl2_adapter* adapter) +{ + struct net_device *netdev = adapter->netdev; + u16 phy_data = 0; + + spin_lock(&adapter->stats_lock); + atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); + atl2_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data); + spin_unlock(&adapter->stats_lock); + + // notify upper layer link down ASAP + if (!(phy_data & BMSR_LSTATUS)) { // Link Down + if (netif_carrier_ok(netdev)) { // old link state: Up + printk(KERN_INFO "%s: %s NIC Link is Down\n", + atl2_driver_name, netdev->name); + adapter->link_speed = SPEED_0; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + } + schedule_work(&adapter->link_chg_task); +} + +static inline void +atl2_clear_phy_int(struct atl2_adapter *adapter) +{ + u16 phy_data; + spin_lock(&adapter->stats_lock); + atl2_read_phy_reg(&adapter->hw, 19, &phy_data); + spin_unlock(&adapter->stats_lock); +} + +/** + * atl2_intr - Interrupt Handler + * @irq: interrupt number + * @data: pointer to a network interface device structure + * @pt_regs: CPU registers structure + **/ +static irqreturn_t +atl2_intr(int irq, void *data) +{ + struct atl2_adapter *adapter = netdev_priv(data); + struct atl2_hw *hw = &adapter->hw; + u32 status; + + status = ATL2_READ_REG(hw, REG_ISR); + if (0 == status) + return IRQ_NONE; + + // link event + if (status & ISR_PHY) { + atl2_clear_phy_int(adapter); + } + + // clear ISR status, and Enable CMB DMA/Disable Interrupt + ATL2_WRITE_REG(hw, REG_ISR, status | ISR_DIS_INT); + + // FIXME: if PCIe link is down, how did we read the register? -- CHS + // check if PCIE PHY Link down + if (status & ISR_PHY_LINKDOWN) { + if(netif_running(adapter->netdev)) { // reset MAC + ATL2_WRITE_REG(hw, REG_ISR, 0); + ATL2_WRITE_REG(hw, REG_IMR, 0); + ATL2_WRITE_FLUSH(hw); + schedule_work(&adapter->reset_task); + return IRQ_HANDLED; + } + } + + // check if DMA read/write error ? + if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) + { + //ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); + ATL2_WRITE_REG(hw, REG_ISR, 0); + ATL2_WRITE_REG(hw, REG_IMR, 0); + ATL2_WRITE_FLUSH(hw); + schedule_work(&adapter->reset_task); + return IRQ_HANDLED; + } + + // link event + if (status & (ISR_PHY | ISR_MANUAL)) + { + adapter->net_stats.tx_carrier_errors++; + atl2_check_for_link(adapter); + } + + // transmit event + if (status & ISR_TX_EVENT) { + atl2_intr_tx(adapter); + } + + // rx exception + if (status & ISR_RX_EVENT) { + atl2_intr_rx(adapter); + } + + // re-enable Interrupt + ATL2_WRITE_REG(&adapter->hw, REG_ISR, 0); + return IRQ_HANDLED; +} + +static int +atl2_request_irq(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int flags, err = 0; + + flags = IRQF_SHARED; +#ifdef CONFIG_PCI_MSI + adapter->have_msi = true; + if ((err = pci_enable_msi(adapter->pdev))) + adapter->have_msi = false; + + if (adapter->have_msi) + flags &= ~IRQF_SHARED; +#endif + + return request_irq(adapter->pdev->irq, &atl2_intr, flags, netdev->name, netdev); +} + +/** + * atl2_free_ring_resources - Free Tx / RX descriptor Resources + * @adapter: board private structure + * + * Free all transmit software resources + **/ +static void +atl2_free_ring_resources(struct atl2_adapter *adapter) +{ + struct pci_dev *pdev = adapter->pdev; + pci_free_consistent(pdev, adapter->ring_size, adapter->ring_vir_addr, adapter->ring_dma); +} + +/** + * atl2_open - Called when a network interface is made active + * @netdev: network interface device structure + * + * Returns 0 on success, negative value on failure + * + * The open entry point is called when a network interface is made + * active by the system (IFF_UP). At this point all resources needed + * for transmit and receive operations are allocated, the interrupt + * handler is registered with the OS, the watchdog timer is started, + * and the stack is notified that the interface is ready. + **/ +static int +atl2_open(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + int err; + u32 val; + + /* disallow open during test */ + if (test_bit(__ATL2_TESTING, &adapter->flags)) + return -EBUSY; + + /* allocate transmit descriptors */ + if((err = atl2_setup_ring_resources(adapter))) + return err; + + if((err = atl2_init_hw(&adapter->hw))) { + err = -EIO; + goto err_init_hw; + } + + /* hardware has been reset, we need to reload some things */ + atl2_set_multi(netdev); + init_ring_ptrs(adapter); + +#ifdef NETIF_F_HW_VLAN_TX + atl2_restore_vlan(adapter); +#endif + + if (atl2_configure(adapter)) { + err = -EIO; + goto err_config; + } + + if ((err = atl2_request_irq(adapter))) + goto err_req_irq; + + clear_bit(__ATL2_DOWN, &adapter->flags); + + mod_timer(&adapter->watchdog_timer, jiffies + 4*HZ); + + val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL); + ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val | MASTER_CTRL_MANUAL_INT); + + atl2_irq_enable(adapter); + + return 0; + +err_init_hw: +err_req_irq: +err_config: + atl2_free_ring_resources(adapter); + atl2_reset_hw(&adapter->hw); + + return err; +} + +void +atl2_down(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + /* signal that we're down so the interrupt handler does not + * reschedule our watchdog timer */ + set_bit(__ATL2_DOWN, &adapter->flags); + +#ifdef NETIF_F_LLTX + netif_stop_queue(netdev); +#else + netif_tx_disable(netdev); +#endif + + /* reset MAC to disable all RX/TX */ + atl2_reset_hw(&adapter->hw); + msleep(1); + + atl2_irq_disable(adapter); + + del_timer_sync(&adapter->watchdog_timer); + del_timer_sync(&adapter->phy_config_timer); + clear_bit(0, &adapter->cfg_phy); + + netif_carrier_off(netdev); + adapter->link_speed = SPEED_0; + adapter->link_duplex = -1; + +// atl2_reset(adapter); +} + +static void +atl2_free_irq(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + + free_irq(adapter->pdev->irq, netdev); + +#ifdef CONFIG_PCI_MSI + if (adapter->have_msi) + pci_disable_msi(adapter->pdev); +#endif +} + +/** + * atl2_close - Disables a network interface + * @netdev: network interface device structure + * + * Returns 0, this is not allowed to fail + * + * The close entry point is called when an interface is de-activated + * by the OS. The hardware is still under the drivers control, but + * needs to be disabled. A global MAC reset is issued to stop the + * hardware, and all transmit and receive resources are freed. + **/ +static int +atl2_close(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags)); + + atl2_down(adapter); + atl2_free_irq(adapter); + atl2_free_ring_resources(adapter); + + return 0; +} + +static inline int +TxsFreeUnit(struct atl2_adapter *adapter) +{ + u32 txs_write_ptr = (u32) atomic_read(&adapter->txs_write_ptr); + + return (adapter->txs_next_clear >= txs_write_ptr) ? + (int) (adapter->txs_ring_size - adapter->txs_next_clear + + txs_write_ptr - 1) : + (int) (txs_write_ptr - adapter->txs_next_clear - 1); +} + +static inline int +TxdFreeBytes(struct atl2_adapter *adapter) +{ + u32 txd_read_ptr = (u32)atomic_read(&adapter->txd_read_ptr); + + return (adapter->txd_write_ptr >= txd_read_ptr) ? + (int) (adapter->txd_ring_size - adapter->txd_write_ptr + + txd_read_ptr - 1): + (int) (txd_read_ptr - adapter->txd_write_ptr - 1); +} + +static int +atl2_xmit_frame(struct sk_buff *skb, struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + unsigned long flags; + tx_pkt_header_t* txph; + u32 offset, copy_len; + int txs_unused; + int txbuf_unused; + + if (test_bit(__ATL2_DOWN, &adapter->flags)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + + if (unlikely(skb->len <= 0)) { + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; + } + +#ifdef NETIF_F_LLTX + local_irq_save(flags); + if (!spin_trylock(&adapter->tx_lock)) { + /* Collision - tell upper layer to requeue */ + local_irq_restore(flags); + return NETDEV_TX_LOCKED; + } +#else + spin_lock_irqsave(&adapter->tx_lock, flags); +#endif + txs_unused = TxsFreeUnit(adapter); + txbuf_unused = TxdFreeBytes(adapter); + + if (txs_unused < 1 || skb->len > txbuf_unused) { + // no enough resource + netif_stop_queue(netdev); + spin_unlock_irqrestore(&adapter->tx_lock, flags); + return NETDEV_TX_BUSY; + } + + offset = adapter->txd_write_ptr; + + txph = (tx_pkt_header_t*) (((u8*)adapter->txd_ring)+offset); + + *(u32*)txph = 0; + txph->pkt_size = skb->len; + + offset += 4; + if (offset >= adapter->txd_ring_size) + offset -= adapter->txd_ring_size; + copy_len = adapter->txd_ring_size - offset; + if (copy_len >= skb->len) { + memcpy(((u8*)adapter->txd_ring)+offset, skb->data, skb->len); + offset += ((u32)(skb->len+3)&~3); + } else { + memcpy(((u8*)adapter->txd_ring)+offset, skb->data, copy_len); + memcpy((u8*)adapter->txd_ring, skb->data+copy_len, skb->len-copy_len); + offset = ((u32)(skb->len-copy_len+3)&~3); + } +#ifdef NETIF_F_HW_VLAN_TX + if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + u16 vlan_tag = vlan_tx_tag_get(skb); + vlan_tag = (vlan_tag << 4) | + (vlan_tag >> 13) | + ((vlan_tag >>9) & 0x8); + txph->ins_vlan = 1; + txph->vlan = vlan_tag; + } +#endif + if (offset >= adapter->txd_ring_size) + offset -= adapter->txd_ring_size; + adapter->txd_write_ptr = offset; + + // clear txs before send + adapter->txs_ring[adapter->txs_next_clear].update = 0; + if (++adapter->txs_next_clear == adapter->txs_ring_size) + adapter->txs_next_clear = 0; + + ATL2_WRITE_REGW(&adapter->hw, REG_MB_TXD_WR_IDX, (adapter->txd_write_ptr >> 2)); + + spin_unlock_irqrestore(&adapter->tx_lock, flags); + + netdev->trans_start = jiffies; + dev_kfree_skb_any(skb); + return NETDEV_TX_OK; +} + +/** + * atl2_get_stats - Get System Network Statistics + * @netdev: network interface device structure + * + * Returns the address of the device statistics structure. + * The statistics are actually updated from the timer callback. + **/ +static struct net_device_stats * +atl2_get_stats(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + return &adapter->net_stats; +} + +/** + * atl2_change_mtu - Change the Maximum Transfer Unit + * @netdev: network interface device structure + * @new_mtu: new value for maximum frame size + * + * Returns 0 on success, negative on failure + **/ +static int +atl2_change_mtu(struct net_device *netdev, int new_mtu) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + + if ((new_mtu < 40) || (new_mtu > (ETH_DATA_LEN + VLAN_SIZE))) + return -EINVAL; + + /* set MTU */ + if (hw->max_frame_size != new_mtu) { +// while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags)) +// msleep(1); + netdev->mtu = new_mtu; + + ATL2_WRITE_REG(hw, REG_MTU, + new_mtu + ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE); +// clear_bit(__ATL2_RESETTING, &adapter->flags); + } + + return 0; +} + +/** + * atl2_set_mac - Change the Ethernet Address of the NIC + * @netdev: network interface device structure + * @p: pointer to an address structure + * + * Returns 0 on success, negative on failure + **/ +static int +atl2_set_mac(struct net_device *netdev, void *p) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct sockaddr *addr = p; + + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + if (netif_running(netdev)) + return -EBUSY; + + memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); + memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len); + + atl2_set_mac_addr(&adapter->hw); + + return 0; +} + +/** + * atl2_mii_ioctl - + * @netdev: + * @ifreq: + * @cmd: + **/ +static int +atl2_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct mii_ioctl_data *data = if_mii(ifr); + unsigned long flags; + + switch (cmd) { + case SIOCGMIIPHY: + data->phy_id = 0; + break; + case SIOCGMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + spin_lock_irqsave(&adapter->stats_lock, flags); + if (atl2_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, &data->val_out)) { + spin_unlock_irqrestore(&adapter->stats_lock, flags); + return -EIO; + } + spin_unlock_irqrestore(&adapter->stats_lock, flags); + break; + case SIOCSMIIREG: + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + if (data->reg_num & ~(0x1F)) + return -EFAULT; + spin_lock_irqsave(&adapter->stats_lock, flags); + if (atl2_write_phy_reg(&adapter->hw, data->reg_num, data->val_in)) { + spin_unlock_irqrestore(&adapter->stats_lock, flags); + return -EIO; + } + spin_unlock_irqrestore(&adapter->stats_lock, flags); + break; + default: + return -EOPNOTSUPP; + } + return ATL2_SUCCESS; +} + +/** + * atl2_ioctl - + * @netdev: + * @ifreq: + * @cmd: + **/ +static int +atl2_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) +{ + switch (cmd) { + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + return atl2_mii_ioctl(netdev, ifr, cmd); +#ifdef ETHTOOL_OPS_COMPAT + case SIOCETHTOOL: + return ethtool_ioctl(ifr); +#endif + default: + return -EOPNOTSUPP; + } +} + +/** + * atl2_tx_timeout - Respond to a Tx Hang + * @netdev: network interface device structure + **/ +static void +atl2_tx_timeout(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + /* Do the reset outside of interrupt context */ + schedule_work(&adapter->reset_task); +} + +/** + * atl2_watchdog - Timer Call-back + * @data: pointer to netdev cast into an unsigned long + **/ +static void +atl2_watchdog(unsigned long data) +{ + struct atl2_adapter *adapter = (struct atl2_adapter *) data; + u32 drop_rxd, drop_rxs; + unsigned long flags; + + if (!test_bit(__ATL2_DOWN, &adapter->flags)) { + spin_lock_irqsave(&adapter->stats_lock, flags); + drop_rxd = ATL2_READ_REG(&adapter->hw, REG_STS_RXD_OV); + drop_rxs = ATL2_READ_REG(&adapter->hw, REG_STS_RXS_OV); + adapter->net_stats.rx_over_errors += (drop_rxd+drop_rxs); + spin_unlock_irqrestore(&adapter->stats_lock, flags); + + /* Reset the timer */ + mod_timer(&adapter->watchdog_timer, jiffies + 4 * HZ); + } +} + +/** + * atl2_phy_config - Timer Call-back + * @data: pointer to netdev cast into an unsigned long + **/ +static void +atl2_phy_config(unsigned long data) +{ + struct atl2_adapter *adapter = (struct atl2_adapter *) data; + struct atl2_hw *hw = &adapter->hw; + unsigned long flags; + + spin_lock_irqsave(&adapter->stats_lock, flags); + atl2_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg); + atl2_write_phy_reg(hw, MII_BMCR, MII_CR_RESET|MII_CR_AUTO_NEG_EN|MII_CR_RESTART_AUTO_NEG); + spin_unlock_irqrestore(&adapter->stats_lock, flags); + clear_bit(0, &adapter->cfg_phy); +} + +int +atl2_up(struct atl2_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + int err = 0; + u32 val; + + /* hardware has been reset, we need to reload some things */ + + err = atl2_init_hw(&adapter->hw); + if (err) { + err = -EIO; + return err; + } + + atl2_set_multi(netdev); + init_ring_ptrs(adapter); + +#ifdef NETIF_F_HW_VLAN_TX + atl2_restore_vlan(adapter); +#endif + + if (atl2_configure(adapter)) { + err = -EIO; + goto err_up; + } + + clear_bit(__ATL2_DOWN, &adapter->flags); + + val = ATL2_READ_REG(&adapter->hw, REG_MASTER_CTRL); + ATL2_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val | MASTER_CTRL_MANUAL_INT); + + atl2_irq_enable(adapter); + +err_up: + return err; +} + +void +atl2_reinit_locked(struct atl2_adapter *adapter) +{ + WARN_ON(in_interrupt()); + while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags)) + msleep(1); + atl2_down(adapter); + atl2_up(adapter); + clear_bit(__ATL2_RESETTING, &adapter->flags); +} + +static void +atl2_reset_task(struct work_struct *work) +{ + struct atl2_adapter *adapter; + adapter = container_of(work, struct atl2_adapter, reset_task); + + atl2_reinit_locked(adapter); +} + +static inline void +atl2_setup_mac_ctrl(struct atl2_adapter *adapter) +{ + u32 value; + struct atl2_hw* hw = &adapter->hw; + struct net_device* netdev = adapter->netdev; + + /* Config MAC CTRL Register */ + value = MAC_CTRL_TX_EN | MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY; + + // duplex + if (FULL_DUPLEX == adapter->link_duplex) + value |= MAC_CTRL_DUPLX; + + // flow control + value |= (MAC_CTRL_TX_FLOW | MAC_CTRL_RX_FLOW); + + // PAD & CRC + value |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); + + // preamble length + value |= (((u32)adapter->hw.preamble_len & MAC_CTRL_PRMLEN_MASK) << + MAC_CTRL_PRMLEN_SHIFT); + + // vlan + if (adapter->vlgrp) + value |= MAC_CTRL_RMV_VLAN; + + // filter mode + value |= MAC_CTRL_BC_EN; + if (netdev->flags & IFF_PROMISC) + value |= MAC_CTRL_PROMIS_EN; + else if (netdev->flags & IFF_ALLMULTI) + value |= MAC_CTRL_MC_ALL_EN; + + // half retry buffer + value |= (((u32)(adapter->hw.retry_buf & MAC_CTRL_HALF_LEFT_BUF_MASK)) << + MAC_CTRL_HALF_LEFT_BUF_SHIFT); + + ATL2_WRITE_REG(hw, REG_MAC_CTRL, value); +} + +static int +atl2_check_link(struct atl2_adapter *adapter) +{ + struct atl2_hw *hw = &adapter->hw; + struct net_device * netdev = adapter->netdev; + int ret_val; + u16 speed, duplex, phy_data; + int reconfig = 0; + + // MII_BMSR must read twise + atl2_read_phy_reg(hw, MII_BMSR, &phy_data); + atl2_read_phy_reg(hw, MII_BMSR, &phy_data); + if (!(phy_data&BMSR_LSTATUS)) { // link down + if (netif_carrier_ok(netdev)) { // old link state: Up + u32 value; + //disable rx + value = ATL2_READ_REG(hw, REG_MAC_CTRL); + value &= ~MAC_CTRL_RX_EN; + ATL2_WRITE_REG(hw, REG_MAC_CTRL, value); + adapter->link_speed = SPEED_0; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + return ATL2_SUCCESS; + } + + // Link Up + ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex); + if (ret_val) + return ret_val; + switch( hw->MediaType ) { + case MEDIA_TYPE_100M_FULL: + if (speed != SPEED_100 || duplex != FULL_DUPLEX) + reconfig = 1; + break; + case MEDIA_TYPE_100M_HALF: + if (speed != SPEED_100 || duplex != HALF_DUPLEX) + reconfig = 1; + break; + case MEDIA_TYPE_10M_FULL: + if (speed != SPEED_10 || duplex != FULL_DUPLEX) + reconfig = 1; + break; + case MEDIA_TYPE_10M_HALF: + if (speed != SPEED_10 || duplex != HALF_DUPLEX) + reconfig = 1; + break; + } + // link result is our setting + if (0 == reconfig) { + if (adapter->link_speed != speed || adapter->link_duplex != duplex ) { + adapter->link_speed = speed; + adapter->link_duplex = duplex; + atl2_setup_mac_ctrl(adapter); + printk(KERN_INFO "%s: %s NIC Link is Up<%d Mbps %s>\n", + atl2_driver_name, netdev->name, + adapter->link_speed, + adapter->link_duplex == FULL_DUPLEX ? + "Full Duplex" : "Half Duplex"); + } + + if (!netif_carrier_ok(netdev)) { // Link down -> Up + netif_carrier_on(netdev); + netif_wake_queue(netdev); + } + return ATL2_SUCCESS; + } + + // change orignal link status + if (netif_carrier_ok(netdev)) { + u32 value; + // disable rx + value = ATL2_READ_REG(hw, REG_MAC_CTRL); + value &= ~MAC_CTRL_RX_EN; + ATL2_WRITE_REG(hw, REG_MAC_CTRL, value); + + adapter->link_speed = SPEED_0; + netif_carrier_off(netdev); + netif_stop_queue(netdev); + } + + // auto-neg, insert timer to re-config phy (if interval smaller than 5 seconds, something strange) + if (!test_bit(__ATL2_DOWN, &adapter->flags)) { + if (!test_and_set_bit(0, &adapter->cfg_phy)) { + mod_timer(&adapter->phy_config_timer, jiffies + 5 * HZ); + } + } + + return ATL2_SUCCESS; +} + +/** + * atl2_link_chg_task - deal with link change event Out of interrupt context + * @netdev: network interface device structure + **/ +static void +atl2_link_chg_task(struct work_struct *work) +{ + struct atl2_adapter *adapter; + unsigned long flags; + + adapter = container_of(work, struct atl2_adapter, link_chg_task); + + spin_lock_irqsave(&adapter->stats_lock, flags); + atl2_check_link(adapter); + spin_unlock_irqrestore(&adapter->stats_lock, flags); +} + +static void +atl2_setup_pcicmd(struct pci_dev *pdev) +{ + u16 cmd; + + pci_read_config_word(pdev, PCI_COMMAND, &cmd); + + if (cmd & PCI_COMMAND_INTX_DISABLE) + cmd &= ~PCI_COMMAND_INTX_DISABLE; + if (cmd & PCI_COMMAND_IO) + cmd &= ~PCI_COMMAND_IO; + if (0 == (cmd & PCI_COMMAND_MEMORY)) + cmd |= PCI_COMMAND_MEMORY; + if (0 == (cmd & PCI_COMMAND_MASTER)) + cmd |= PCI_COMMAND_MASTER; + pci_write_config_word(pdev, PCI_COMMAND, cmd); + + /* + * some motherboards BIOS(PXE/EFI) driver may set PME + * while they transfer control to OS (Windows/Linux) + * so we should clear this bit before NIC work normally + */ + pci_write_config_dword(pdev, REG_PM_CTRLSTAT, 0); +} + +/** + * atl2_probe - Device Initialization Routine + * @pdev: PCI device information struct + * @ent: entry in atl2_pci_tbl + * + * Returns 0 on success, negative on failure + * + * atl2_probe initializes an adapter identified by a pci_dev structure. + * The OS initialization, configuring of the adapter private structure, + * and a hardware reset occur. + **/ +static int __devinit +atl2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) +{ + struct net_device *netdev; + struct atl2_adapter *adapter; + static int cards_found = 0; + unsigned long mmio_start; + int mmio_len; + int err; + + if((err = pci_enable_device(pdev))) + return err; + + /* + * atl2 is a shared-high-32-bit device, so we're stuck with 32-bit DMA + * until the kernel has the proper infrastructure to support 64-bit DMA + * on these devices. + */ + if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) && + (err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK))) { + printk(KERN_ERR "atl2: No usable DMA configuration, aborting\n"); + goto err_dma; + } + + // Mark all PCI regions associated with PCI device + // pdev as being reserved by owner atl2_driver_name + if((err = pci_request_regions(pdev, atl2_driver_name))) + goto err_pci_reg; + + // Enables bus-mastering on the device and calls + // pcibios_set_master to do the needed arch specific settings + pci_set_master(pdev); + + err = -ENOMEM; + netdev = alloc_etherdev(sizeof(struct atl2_adapter)); + if(!netdev) + goto err_alloc_etherdev; + + SET_NETDEV_DEV(netdev, &pdev->dev); + + pci_set_drvdata(pdev, netdev); + adapter = netdev_priv(netdev); + adapter->netdev = netdev; + adapter->pdev = pdev; + adapter->hw.back = adapter; + + mmio_start = pci_resource_start(pdev, 0x0); + mmio_len = pci_resource_len(pdev, 0x0); + + adapter->hw.mem_rang = (u32)mmio_len; + adapter->hw.hw_addr = ioremap(mmio_start, mmio_len); + if(!adapter->hw.hw_addr) { + err = -EIO; + goto err_ioremap; + } + + atl2_setup_pcicmd(pdev); + + netdev->open = &atl2_open; + netdev->stop = &atl2_close; + netdev->hard_start_xmit = &atl2_xmit_frame; + netdev->get_stats = &atl2_get_stats; + netdev->set_multicast_list = &atl2_set_multi; + netdev->set_mac_address = &atl2_set_mac; + netdev->change_mtu = &atl2_change_mtu; + netdev->do_ioctl = &atl2_ioctl; + atl2_set_ethtool_ops(netdev); + +#ifdef HAVE_TX_TIMEOUT + netdev->tx_timeout = &atl2_tx_timeout; + netdev->watchdog_timeo = 5 * HZ; //FIXME -- CHS +#endif +#ifdef NETIF_F_HW_VLAN_TX + netdev->vlan_rx_register = atl2_vlan_rx_register; +#endif + strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); + + netdev->mem_start = mmio_start; + netdev->mem_end = mmio_start + mmio_len; + //netdev->base_addr = adapter->io_base; + adapter->bd_number = cards_found; + adapter->pci_using_64 = false; + + /* setup the private structure */ + + if((err = atl2_sw_init(adapter))) + goto err_sw_init; + + err = -EIO; + +#ifdef NETIF_F_HW_VLAN_TX + netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX ); +#endif + +#ifdef NETIF_F_LLTX + netdev->features |= NETIF_F_LLTX; +#endif + + /* Init PHY as early as possible due to power saving issue */ + atl2_phy_init(&adapter->hw); + + /* reset the controller to + * put the device in a known good starting state */ + + if (atl2_reset_hw(&adapter->hw)) { + err = -EIO; + goto err_reset; + } + + /* copy the MAC address out of the EEPROM */ + atl2_read_mac_addr(&adapter->hw); + memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len); +//FIXME: do we still need this? +#ifdef ETHTOOL_GPERMADDR + memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len); + + if (!is_valid_ether_addr(netdev->perm_addr)) { +#else + if (!is_valid_ether_addr(netdev->dev_addr)) { +#endif + err = -EIO; + goto err_eeprom; + } + + atl2_check_options(adapter); + + init_timer(&adapter->watchdog_timer); + adapter->watchdog_timer.function = &atl2_watchdog; + adapter->watchdog_timer.data = (unsigned long) adapter; + + init_timer(&adapter->phy_config_timer); + adapter->phy_config_timer.function = &atl2_phy_config; + adapter->phy_config_timer.data = (unsigned long) adapter; + + INIT_WORK(&adapter->reset_task, atl2_reset_task); + INIT_WORK(&adapter->link_chg_task, atl2_link_chg_task); + + strcpy(netdev->name, "eth%d"); // ?? + if((err = register_netdev(netdev))) + goto err_register; + + /* assume we have no link for now */ + netif_carrier_off(netdev); + netif_stop_queue(netdev); + + cards_found++; + + return 0; + +//err_init_hw: +err_reset: +err_register: +err_sw_init: +err_eeprom: + iounmap(adapter->hw.hw_addr); +err_ioremap: + free_netdev(netdev); +err_alloc_etherdev: + pci_release_regions(pdev); +err_pci_reg: +err_dma: + pci_disable_device(pdev); + return err; +} + +/** + * atl2_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * atl2_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. The could be caused by a + * Hot-Plug event, or because the driver is going to be removed from + * memory. + **/ +/* FIXME: write the original MAC address back in case it was changed from a + * BIOS-set value, as in atl1 -- CHS */ +static void __devexit +atl2_remove(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl2_adapter *adapter = netdev_priv(netdev); + + /* flush_scheduled work may reschedule our watchdog task, so + * explicitly disable watchdog tasks from being rescheduled */ + set_bit(__ATL2_DOWN, &adapter->flags); + + del_timer_sync(&adapter->watchdog_timer); + del_timer_sync(&adapter->phy_config_timer); + + flush_scheduled_work(); + + unregister_netdev(netdev); + + atl2_force_ps(&adapter->hw); + + iounmap(adapter->hw.hw_addr); + pci_release_regions(pdev); + + free_netdev(netdev); + + pci_disable_device(pdev); +} + +static int +atl2_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw * hw = &adapter->hw; + u16 speed, duplex; + u32 ctrl = 0; + u32 wufc = adapter->wol; + +#ifdef CONFIG_PM + int retval = 0; +#endif + + netif_device_detach(netdev); + + if (netif_running(netdev)) { + WARN_ON(test_bit(__ATL2_RESETTING, &adapter->flags)); + atl2_down(adapter); + } + +#ifdef CONFIG_PM + retval = pci_save_state(pdev); + if (retval) + return retval; +#endif + + atl2_read_phy_reg(hw, MII_BMSR, (u16*)&ctrl); + atl2_read_phy_reg(hw, MII_BMSR, (u16*)&ctrl); + if(ctrl & BMSR_LSTATUS) + wufc &= ~ATL2_WUFC_LNKC; + + if (0 != (ctrl & BMSR_LSTATUS) && 0 != wufc) { + u32 ret_val; + /* get current link speed & duplex */ + ret_val = atl2_get_speed_and_duplex(hw, &speed, &duplex); + if (ret_val) { + printk(KERN_DEBUG "%s: get speed&duplex error while suspend\n", atl2_driver_name); + goto wol_dis; + } + + ctrl = 0; + + /* turn on magic packet wol */ + if (wufc & ATL2_WUFC_MAG) + ctrl |= (WOL_MAGIC_EN | WOL_MAGIC_PME_EN); + + /* ignore Link Chg event when Link is up */ + ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl); + + /* Config MAC CTRL Register */ + ctrl = MAC_CTRL_RX_EN | MAC_CTRL_MACLP_CLK_PHY; + if (FULL_DUPLEX == adapter->link_duplex) + ctrl |= MAC_CTRL_DUPLX; + ctrl |= (MAC_CTRL_ADD_CRC | MAC_CTRL_PAD); + ctrl |= (((u32)adapter->hw.preamble_len & + MAC_CTRL_PRMLEN_MASK) << MAC_CTRL_PRMLEN_SHIFT); + ctrl |= (((u32)(adapter->hw.retry_buf & + MAC_CTRL_HALF_LEFT_BUF_MASK)) << + MAC_CTRL_HALF_LEFT_BUF_SHIFT); + if (wufc & ATL2_WUFC_MAG) { + /* magic packet maybe Broadcast&multicast&Unicast frame */ + ctrl |= MAC_CTRL_BC_EN; + } + + ATL2_WRITE_REG(hw, REG_MAC_CTRL, ctrl); + + /* pcie patch */ + ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1); + ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl); + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + goto suspend_exit; + } + + if (0 == (ctrl&BMSR_LSTATUS) && 0 != (wufc&ATL2_WUFC_LNKC)) { + /* link is down, so only LINK CHG WOL event enable */ + ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN); + ATL2_WRITE_REG(hw, REG_WOL_CTRL, ctrl); + ATL2_WRITE_REG(hw, REG_MAC_CTRL, 0); + + /* pcie patch */ + ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1); + ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl); + + hw->phy_configured = false; /* re-init PHY when resume */ + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); + + goto suspend_exit; + } + +wol_dis: + /* WOL disabled */ + ATL2_WRITE_REG(hw, REG_WOL_CTRL, 0); + + /* pcie patch */ + ctrl = ATL2_READ_REG(hw, REG_PCIE_PHYMISC); + ctrl |= PCIE_PHYMISC_FORCE_RCV_DET; + ATL2_WRITE_REG(hw, REG_PCIE_PHYMISC, ctrl); + ctrl = ATL2_READ_REG(hw, REG_PCIE_DLL_TX_CTRL1); + ctrl |= PCIE_DLL_TX_CTRL1_SEL_NOR_CLK; + ATL2_WRITE_REG(hw, REG_PCIE_DLL_TX_CTRL1, ctrl); + + atl2_force_ps(hw); + hw->phy_configured = false; /* re-init PHY when resume */ + + pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); + +suspend_exit: + if (netif_running(netdev)) + atl2_free_irq(adapter); + + pci_disable_device(pdev); + + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +#ifdef CONFIG_PM +static int +atl2_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct atl2_adapter *adapter = netdev_priv(netdev); + u32 err; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + if ((err = pci_enable_device(pdev))) { + printk(KERN_ERR "atl2: Cannot enable PCI device from suspend\n"); + return err; + } + + pci_set_master(pdev); + + ATL2_READ_REG(&adapter->hw, REG_WOL_CTRL); /* clear WOL status */ + + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + ATL2_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); + + if (netif_running(netdev) && (err = atl2_request_irq(adapter))) + return err; + + atl2_reset_hw(&adapter->hw); + + if(netif_running(netdev)) + atl2_up(adapter); + + netif_device_attach(netdev); + + return 0; +} +#endif + +static void +atl2_shutdown(struct pci_dev *pdev) +{ + atl2_suspend(pdev, PMSG_SUSPEND); +} + +static struct pci_driver atl2_driver = { + .name = atl2_driver_name, + .id_table = atl2_pci_tbl, + .probe = atl2_probe, + .remove = __devexit_p(atl2_remove), + /* Power Managment Hooks */ + .suspend = atl2_suspend, +#ifdef CONFIG_PM + .resume = atl2_resume, +#endif + .shutdown = atl2_shutdown, +}; + +/** + * atl2_init_module - Driver Registration Routine + * + * atl2_init_module is the first routine called when the driver is + * loaded. All it does is register with the PCI subsystem. + **/ +static int __init +atl2_init_module(void) +{ + int ret; + printk(KERN_INFO "%s - version %s\n", atl2_driver_string, atl2_driver_version); + printk(KERN_INFO "%s\n", atl2_copyright); + + ret = pci_register_driver(&atl2_driver); + if (copybreak != COPYBREAK_DEFAULT) { + if (copybreak == 0) + printk(KERN_INFO "atl2: copybreak disabled\n"); + else + printk(KERN_INFO "atl2: copybreak enabled for packets <= %u bytes\n", copybreak); + } + return ret; +} +module_init(atl2_init_module); + +/** + * atl2_exit_module - Driver Exit Cleanup Routine + * + * atl2_exit_module is called just before the driver is removed + * from memory. + **/ +static void __exit +atl2_exit_module(void) +{ + pci_unregister_driver(&atl2_driver); +} +module_exit(atl2_exit_module); + +void +atl2_read_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value) +{ + struct atl2_adapter *adapter = hw->back; + pci_read_config_word(adapter->pdev, reg, value); +} + +void +atl2_write_pci_cfg(struct atl2_hw *hw, u32 reg, u16 *value) +{ + struct atl2_adapter *adapter = hw->back; + pci_write_config_word(adapter->pdev, reg, *value); +} --- linux-2.6.28.orig/ubuntu/atl2/Kconfig +++ linux-2.6.28/ubuntu/atl2/Kconfig @@ -0,0 +1,10 @@ +config ATL2 + tristate "Atheros L2 Fast Ethernet support (EXPERIMENTAL)" + depends on PCI && EXPERIMENTAL + select CRC32 + select MII + help + This driver supports the Atheros L2 fast ethernet adapter. + + To compile this driver as a module, choose M here. The module + will be called atl2. --- linux-2.6.28.orig/ubuntu/atl2/Makefile +++ linux-2.6.28/ubuntu/atl2/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_ATL2) += atl2.o + +atl2-objs += atl2_main.o atl2_hw.o atl2_ethtool.o atl2_param.o --- linux-2.6.28.orig/ubuntu/atl2/atl2_ethtool.c +++ linux-2.6.28/ubuntu/atl2/atl2_ethtool.c @@ -0,0 +1,416 @@ +/* atl2_ethtool.c -- atl2 ethtool support + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel 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; 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 "atl2.h" +#include "atl2_hw.h" + +extern char atl2_driver_name[]; +extern char atl2_driver_version[]; + +extern int atl2_up(struct atl2_adapter *adapter); +extern void atl2_down(struct atl2_adapter *adapter); +extern void atl2_reinit_locked(struct atl2_adapter *adapter); +extern s32 atl2_reset_hw(struct atl2_hw *hw); + +static int +atl2_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + + ecmd->supported = (SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_Autoneg | + SUPPORTED_TP); + ecmd->advertising = ADVERTISED_TP; + + ecmd->advertising |= ADVERTISED_Autoneg; + ecmd->advertising |= hw->autoneg_advertised; + + ecmd->port = PORT_TP; + ecmd->phy_address = 0; + ecmd->transceiver = XCVR_INTERNAL; + + if (adapter->link_speed != SPEED_0) { + ecmd->speed = adapter->link_speed; + if (adapter->link_duplex == FULL_DUPLEX) + ecmd->duplex = DUPLEX_FULL; + else + ecmd->duplex = DUPLEX_HALF; + } else { + ecmd->speed = -1; + ecmd->duplex = -1; + } + + ecmd->autoneg = AUTONEG_ENABLE; + return 0; +} + +static int +atl2_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + + while (test_and_set_bit(__ATL2_RESETTING, &adapter->flags)) + msleep(1); + + if (ecmd->autoneg == AUTONEG_ENABLE) { +#define MY_ADV_MASK (ADVERTISE_10_HALF| \ + ADVERTISE_10_FULL| \ + ADVERTISE_100_HALF| \ + ADVERTISE_100_FULL) + + if ((ecmd->advertising&MY_ADV_MASK) == MY_ADV_MASK) { + hw->MediaType = MEDIA_TYPE_AUTO_SENSOR; + hw->autoneg_advertised = MY_ADV_MASK; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_100_FULL) { + hw->MediaType = MEDIA_TYPE_100M_FULL; + hw->autoneg_advertised = ADVERTISE_100_FULL; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_100_HALF) { + hw->MediaType = MEDIA_TYPE_100M_HALF; + hw->autoneg_advertised = ADVERTISE_100_HALF; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_10_FULL) { + hw->MediaType = MEDIA_TYPE_10M_FULL; + hw->autoneg_advertised = ADVERTISE_10_FULL; + } else if ((ecmd->advertising&MY_ADV_MASK) == ADVERTISE_10_HALF) { + hw->MediaType = MEDIA_TYPE_10M_HALF; + hw->autoneg_advertised = ADVERTISE_10_HALF; + } else { + clear_bit(__ATL2_RESETTING, &adapter->flags); + return -EINVAL; + } + ecmd->advertising = hw->autoneg_advertised | + ADVERTISED_TP | ADVERTISED_Autoneg; + } else { + clear_bit(__ATL2_RESETTING, &adapter->flags); + return -EINVAL; + } + + /* reset the link */ + if (netif_running(adapter->netdev)) { + atl2_down(adapter); + atl2_up(adapter); + } else + atl2_reset_hw(&adapter->hw); + + clear_bit(__ATL2_RESETTING, &adapter->flags); + return 0; +} + +static u32 +atl2_get_tx_csum(struct net_device *netdev) +{ + return (netdev->features & NETIF_F_HW_CSUM) != 0; +} + +static u32 +atl2_get_msglevel(struct net_device *netdev) +{ + return 0; +} + +/* + * It's sane for this to be empty, but we might want to take advantage of this. + */ +static void +atl2_set_msglevel(struct net_device *netdev, u32 data) +{ +} + +static int +atl2_get_regs_len(struct net_device *netdev) +{ +#define ATL2_REGS_LEN 42 + return ATL2_REGS_LEN * sizeof(u32); +} + +static void +atl2_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + u32 *regs_buff = p; + u16 phy_data; + + memset(p, 0, ATL2_REGS_LEN * sizeof(u32)); + + regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id; + + regs_buff[0] = ATL2_READ_REG(hw, REG_VPD_CAP); + regs_buff[1] = ATL2_READ_REG(hw, REG_SPI_FLASH_CTRL); + regs_buff[2] = ATL2_READ_REG(hw, REG_SPI_FLASH_CONFIG); + regs_buff[3] = ATL2_READ_REG(hw, REG_TWSI_CTRL); + regs_buff[4] = ATL2_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL); + regs_buff[5] = ATL2_READ_REG(hw, REG_MASTER_CTRL); + regs_buff[6] = ATL2_READ_REG(hw, REG_MANUAL_TIMER_INIT); + regs_buff[7] = ATL2_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT); + regs_buff[8] = ATL2_READ_REG(hw, REG_PHY_ENABLE); + regs_buff[9] = ATL2_READ_REG(hw, REG_CMBDISDMA_TIMER); + regs_buff[10] = ATL2_READ_REG(hw, REG_IDLE_STATUS); + regs_buff[11] = ATL2_READ_REG(hw, REG_MDIO_CTRL); + regs_buff[12] = ATL2_READ_REG(hw, REG_SERDES_LOCK); + regs_buff[13] = ATL2_READ_REG(hw, REG_MAC_CTRL); + regs_buff[14] = ATL2_READ_REG(hw, REG_MAC_IPG_IFG); + regs_buff[15] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR); + regs_buff[16] = ATL2_READ_REG(hw, REG_MAC_STA_ADDR+4); + regs_buff[17] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE); + regs_buff[18] = ATL2_READ_REG(hw, REG_RX_HASH_TABLE+4); + regs_buff[19] = ATL2_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL); + regs_buff[20] = ATL2_READ_REG(hw, REG_MTU); + regs_buff[21] = ATL2_READ_REG(hw, REG_WOL_CTRL); + regs_buff[22] = ATL2_READ_REG(hw, REG_SRAM_TXRAM_END); + regs_buff[23] = ATL2_READ_REG(hw, REG_DESC_BASE_ADDR_HI); + regs_buff[24] = ATL2_READ_REG(hw, REG_TXD_BASE_ADDR_LO); + regs_buff[25] = ATL2_READ_REG(hw, REG_TXD_MEM_SIZE); + regs_buff[26] = ATL2_READ_REG(hw, REG_TXS_BASE_ADDR_LO); + regs_buff[27] = ATL2_READ_REG(hw, REG_TXS_MEM_SIZE); + regs_buff[28] = ATL2_READ_REG(hw, REG_RXD_BASE_ADDR_LO); + regs_buff[29] = ATL2_READ_REG(hw, REG_RXD_BUF_NUM); + regs_buff[30] = ATL2_READ_REG(hw, REG_DMAR); + regs_buff[31] = ATL2_READ_REG(hw, REG_TX_CUT_THRESH); + regs_buff[32] = ATL2_READ_REG(hw, REG_DMAW); + regs_buff[33] = ATL2_READ_REG(hw, REG_PAUSE_ON_TH); + regs_buff[34] = ATL2_READ_REG(hw, REG_PAUSE_OFF_TH); + regs_buff[35] = ATL2_READ_REG(hw, REG_MB_TXD_WR_IDX); + regs_buff[36] = ATL2_READ_REG(hw, REG_MB_RXD_RD_IDX); + regs_buff[38] = ATL2_READ_REG(hw, REG_ISR); + regs_buff[39] = ATL2_READ_REG(hw, REG_IMR); + + atl2_read_phy_reg(hw, MII_BMCR, &phy_data); + regs_buff[40] = (u32)phy_data; + atl2_read_phy_reg(hw, MII_BMSR, &phy_data); + regs_buff[41] = (u32)phy_data; +} + +static int +atl2_get_eeprom_len(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + if (!atl2_check_eeprom_exist(&adapter->hw)) { + return 512; + } else + return 0; +} + +static int +atl2_get_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + u32 *eeprom_buff; + int first_dword, last_dword; + int ret_val = 0; + int i; + + if (eeprom->len == 0) + return -EINVAL; + + if (atl2_check_eeprom_exist(hw)) { + return -EINVAL; + } + + eeprom->magic = hw->vendor_id | (hw->device_id << 16); + + first_dword = eeprom->offset >> 2; + last_dword = (eeprom->offset + eeprom->len - 1) >> 2; + + eeprom_buff = kmalloc(sizeof(u32) * (last_dword - first_dword + 1), GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + for (i=first_dword; i < last_dword; i++) { + if (!atl2_read_eeprom(hw, i*4, &(eeprom_buff[i-first_dword]))) + return -EIO; + } + + memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 3), + eeprom->len); + kfree(eeprom_buff); + + return ret_val; +} + +static int +atl2_set_eeprom(struct net_device *netdev, struct ethtool_eeprom *eeprom, u8 *bytes) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + struct atl2_hw *hw = &adapter->hw; + u32 *eeprom_buff; + u32 *ptr; + int max_len, first_dword, last_dword, ret_val = 0; + int i; + + if (eeprom->len == 0) + return -EOPNOTSUPP; + + if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) + return -EFAULT; + + max_len = 512; + + first_dword = eeprom->offset >> 2; + last_dword = (eeprom->offset + eeprom->len - 1) >> 2; + eeprom_buff = kmalloc(max_len, GFP_KERNEL); + if (!eeprom_buff) + return -ENOMEM; + + ptr = (u32 *)eeprom_buff; + + if (eeprom->offset & 3) { + /* need read/modify/write of first changed EEPROM word */ + /* only the second byte of the word is being modified */ + if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) + return -EIO; + ptr++; + } + if (((eeprom->offset + eeprom->len) & 3) ) { + /* need read/modify/write of last changed EEPROM word */ + /* only the first byte of the word is being modified */ + + if (!atl2_read_eeprom(hw, last_dword*4, &(eeprom_buff[last_dword - first_dword]))) + return -EIO; + } + + /* Device's eeprom is always little-endian, word addressable */ + memcpy(ptr, bytes, eeprom->len); + + for (i = 0; i < last_dword - first_dword + 1; i++) { + if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) + return -EIO; + } + + kfree(eeprom_buff); + return ret_val; +} + +static void +atl2_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + strncpy(drvinfo->driver, atl2_driver_name, 32); + strncpy(drvinfo->version, atl2_driver_version, 32); + strncpy(drvinfo->fw_version, "L2", 32); + strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); + drvinfo->n_stats = 0; + drvinfo->testinfo_len = 0; + drvinfo->regdump_len = atl2_get_regs_len(netdev); + drvinfo->eedump_len = atl2_get_eeprom_len(netdev); +} + +static void +atl2_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + wol->supported = WAKE_MAGIC; + wol->wolopts = 0; + + if (adapter->wol & ATL2_WUFC_EX) + wol->wolopts |= WAKE_UCAST; + if (adapter->wol & ATL2_WUFC_MC) + wol->wolopts |= WAKE_MCAST; + if (adapter->wol & ATL2_WUFC_BC) + wol->wolopts |= WAKE_BCAST; + if (adapter->wol & ATL2_WUFC_MAG) + wol->wolopts |= WAKE_MAGIC; + if (adapter->wol & ATL2_WUFC_LNKC) + wol->wolopts |= WAKE_PHY; +} + +static int +atl2_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + + if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE)) + return -EOPNOTSUPP; + + if (wol->wolopts & (WAKE_MCAST|WAKE_BCAST|WAKE_MCAST)) + return -EOPNOTSUPP; + + /* these settings will always override what we currently have */ + adapter->wol = 0; + + if (wol->wolopts & WAKE_MAGIC) + adapter->wol |= ATL2_WUFC_MAG; + if (wol->wolopts & WAKE_PHY) + adapter->wol |= ATL2_WUFC_LNKC; + + return 0; +} + +static int +atl2_nway_reset(struct net_device *netdev) +{ + struct atl2_adapter *adapter = netdev_priv(netdev); + if (netif_running(netdev)) + atl2_reinit_locked(adapter); + return 0; +} + +static struct ethtool_ops atl2_ethtool_ops = { + .get_settings = atl2_get_settings, + .set_settings = atl2_set_settings, + .get_drvinfo = atl2_get_drvinfo, + .get_regs_len = atl2_get_regs_len, + .get_regs = atl2_get_regs, + .get_wol = atl2_get_wol, + .set_wol = atl2_set_wol, + .get_msglevel = atl2_get_msglevel, + .set_msglevel = atl2_set_msglevel, + .nway_reset = atl2_nway_reset, + .get_link = ethtool_op_get_link, + .get_eeprom_len = atl2_get_eeprom_len, + .get_eeprom = atl2_get_eeprom, + .set_eeprom = atl2_set_eeprom, + .get_tx_csum = atl2_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .set_sg = ethtool_op_set_sg, +#ifdef NETIF_F_TSO + .get_tso = ethtool_op_get_tso, +#endif +#if 0 //FIXME: not implemented? +//#ifdef ETHTOOL_GPERMADDR + .get_perm_addr = ethtool_op_get_perm_addr, +#endif +}; + +void +atl2_set_ethtool_ops(struct net_device *netdev) +{ + SET_ETHTOOL_OPS(netdev, &atl2_ethtool_ops); +} --- linux-2.6.28.orig/ubuntu/atl2/atl2_param.c +++ linux-2.6.28/ubuntu/atl2/atl2_param.c @@ -0,0 +1,317 @@ +/* atl2_param.c -- atl2 parameter processing + * + * Copyright(c) 2007 Atheros Corporation. All rights reserved. + * Copyright(c) 2006 xiong huang + * Copyright(c) 2007 Chris Snook + * + * Derived from Intel e1000 driver + * Copyright(c) 1999 - 2005 Intel 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; 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 "atl2.h" + +/* This is the only thing that needs to be changed to adjust the + * maximum number of ports that the driver can manage. + */ +#define ATL2_MAX_NIC 4 + +#define OPTION_UNSET -1 +#define OPTION_DISABLED 0 +#define OPTION_ENABLED 1 + +/* All parameters are treated the same, as an integer array of values. + * This macro just reduces the need to repeat the same declaration code + * over and over (plus this helps to avoid typo bugs). + */ +#define ATL2_PARAM_INIT { [0 ... ATL2_MAX_NIC] = OPTION_UNSET } +#ifndef module_param_array +/* Module Parameters are always initialized to -1, so that the driver + * can tell the difference between no user specified value or the + * user asking for the default value. + * The true default values are loaded in when atl2_check_options is called. + * + * This is a GCC extension to ANSI C. + * See the item "Labeled Elements in Initializers" in the section + * "Extensions to the C Language Family" of the GCC documentation. + */ + +#define ATL2_PARAM(X, desc) \ + static const int __devinitdata X[ATL2_MAX_NIC + 1] = ATL2_PARAM_INIT; \ + MODULE_PARM(X, "1-" __MODULE_STRING(ATL2_MAX_NIC) "i"); \ + MODULE_PARM_DESC(X, desc); +#else +#define ATL2_PARAM(X, desc) \ + static int __devinitdata X[ATL2_MAX_NIC+1] = ATL2_PARAM_INIT; \ + static int num_##X = 0; \ + module_param_array_named(X, X, int, &num_##X, 0); \ + MODULE_PARM_DESC(X, desc); +#endif + +/* Transmit Memory Size + * + * Valid Range: 64-2048 + * + * Default Value: 128 + */ +#define ATL2_MIN_TX_MEMSIZE 4 // 4KB +#define ATL2_MAX_TX_MEMSIZE 64 // 64KB +#define ATL2_DEFAULT_TX_MEMSIZE 8 // 8KB +ATL2_PARAM(TxMemSize, "Bytes of Transmit Memory"); + +/* Receive Memory Block Count + * + * Valid Range: 16-512 + * + * Default Value: 128 + */ +#define ATL2_MIN_RXD_COUNT 16 +#define ATL2_MAX_RXD_COUNT 512 +#define ATL2_DEFAULT_RXD_COUNT 64 +ATL2_PARAM(RxMemBlock, "Number of receive memory block"); + +/* User Specified MediaType Override + * + * Valid Range: 0-5 + * - 0 - auto-negotiate at all supported speeds + * - 1 - only link at 1000Mbps Full Duplex + * - 2 - only link at 100Mbps Full Duplex + * - 3 - only link at 100Mbps Half Duplex + * - 4 - only link at 10Mbps Full Duplex + * - 5 - only link at 10Mbps Half Duplex + * Default Value: 0 + */ +ATL2_PARAM(MediaType, "MediaType Select"); + +/* Interrupt Moderate Timer in units of 2 us + * + * Valid Range: 10-65535 + * + * Default Value: 45000(90ms) + */ +#define INT_MOD_DEFAULT_CNT 100 // 200us +#define INT_MOD_MAX_CNT 65000 +#define INT_MOD_MIN_CNT 50 +ATL2_PARAM(IntModTimer, "Interrupt Moderator Timer"); + +/* FlashVendor + * Valid Range: 0-2 + * 0 - Atmel + * 1 - SST + * 2 - ST + */ +ATL2_PARAM(FlashVendor, "SPI Flash Vendor"); + +#define AUTONEG_ADV_DEFAULT 0x2F +#define AUTONEG_ADV_MASK 0x2F +#define FLOW_CONTROL_DEFAULT FLOW_CONTROL_FULL + +#define FLASH_VENDOR_DEFAULT 0 +#define FLASH_VENDOR_MIN 0 +#define FLASH_VENDOR_MAX 2 + +struct atl2_option { + enum { enable_option, range_option, list_option } type; + char *name; + char *err; + int def; + union { + struct { /* range_option info */ + int min; + int max; + } r; + struct { /* list_option info */ + int nr; + struct atl2_opt_list { int i; char *str; } *p; + } l; + } arg; +}; + +static int __devinit +atl2_validate_option(int *value, struct atl2_option *opt) +{ + int i; + struct atl2_opt_list *ent; + + if(*value == OPTION_UNSET) { + *value = opt->def; + return 0; + } + + switch (opt->type) { + case enable_option: + switch (*value) { + case OPTION_ENABLED: + printk(KERN_INFO "%s Enabled\n", opt->name); + return 0; + break; + case OPTION_DISABLED: + printk(KERN_INFO "%s Disabled\n", opt->name); + return 0; + break; + } + break; + case range_option: + if(*value >= opt->arg.r.min && *value <= opt->arg.r.max) { + printk(KERN_INFO "%s set to %i\n", opt->name, *value); + return 0; + } + break; + case list_option: + for(i = 0; i < opt->arg.l.nr; i++) { + ent = &opt->arg.l.p[i]; + if(*value == ent->i) { + if(ent->str[0] != '\0') + printk(KERN_INFO "%s\n", ent->str); + return 0; + } + } + break; + default: + BUG(); + } + + printk(KERN_INFO "Invalid %s specified (%i) %s\n", + opt->name, *value, opt->err); + *value = opt->def; + return -1; +} + +/** + * atl2_check_options - Range Checking for Command Line Parameters + * @adapter: board private structure + * + * This routine checks all command line parameters for valid user + * input. If an invalid value is given, or if no user specified + * value exists, a default value is used. The final value is stored + * in a variable in the adapter structure. + **/ +void __devinit +atl2_check_options(struct atl2_adapter *adapter) +{ + int val; + struct atl2_option opt; + int bd = adapter->bd_number; + if(bd >= ATL2_MAX_NIC) { + printk(KERN_NOTICE "Warning: no configuration for board #%i\n", bd); + printk(KERN_NOTICE "Using defaults for all values\n"); +#ifndef module_param_array + bd = ATL2_MAX_NIC; +#endif + } + + /* Bytes of Transmit Memory */ + opt.type = range_option; + opt.name = "Bytes of Transmit Memory"; + opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_TX_MEMSIZE); + opt.def = ATL2_DEFAULT_TX_MEMSIZE; + opt.arg.r.min = ATL2_MIN_TX_MEMSIZE; + opt.arg.r.max = ATL2_MAX_TX_MEMSIZE; +#ifdef module_param_array + if(num_TxMemSize > bd) { +#endif + val = TxMemSize[bd]; + atl2_validate_option(&val, &opt); + adapter->txd_ring_size = ((u32) val) * 1024; +#ifdef module_param_array + } else { + adapter->txd_ring_size = ((u32)opt.def) * 1024; + } +#endif + // txs ring size: + adapter->txs_ring_size = adapter->txd_ring_size / 128; + if (adapter->txs_ring_size > 160) + adapter->txs_ring_size = 160; + + /* Receive Memory Block Count */ + opt.type = range_option; + opt.name = "Number of receive memory block"; + opt.err = "using default of " __MODULE_STRING(ATL2_DEFAULT_RXD_COUNT); + opt.def = ATL2_DEFAULT_RXD_COUNT; + opt.arg.r.min = ATL2_MIN_RXD_COUNT; + opt.arg.r.max = ATL2_MAX_RXD_COUNT; +#ifdef module_param_array + if(num_RxMemBlock > bd) { +#endif + val = RxMemBlock[bd]; + atl2_validate_option(&val, &opt); + adapter->rxd_ring_size = (u32)val; //((u16)val)&~1; // even number +#ifdef module_param_array + } else { + adapter->rxd_ring_size = (u32)opt.def; + } +#endif + // init RXD Flow control value + adapter->hw.fc_rxd_hi = (adapter->rxd_ring_size/8)*7; + adapter->hw.fc_rxd_lo = (ATL2_MIN_RXD_COUNT/8) > (adapter->rxd_ring_size/12) ? + (ATL2_MIN_RXD_COUNT/8) : (adapter->rxd_ring_size/12); + + /* Interrupt Moderate Timer */ + opt.type = range_option; + opt.name = "Interrupt Moderate Timer"; + opt.err = "using default of " __MODULE_STRING(INT_MOD_DEFAULT_CNT); + opt.def = INT_MOD_DEFAULT_CNT; + opt.arg.r.min = INT_MOD_MIN_CNT; + opt.arg.r.max = INT_MOD_MAX_CNT; +#ifdef module_param_array + if(num_IntModTimer > bd) { +#endif + val = IntModTimer[bd]; + atl2_validate_option(&val, &opt); + adapter->imt = (u16) val; +#ifdef module_param_array + } else { + adapter->imt = (u16)(opt.def); + } +#endif + /* Flash Vendor */ + opt.type = range_option; + opt.name = "SPI Flash Vendor"; + opt.err = "using default of " __MODULE_STRING(FLASH_VENDOR_DEFAULT); + opt.def = FLASH_VENDOR_DEFAULT; + opt.arg.r.min = FLASH_VENDOR_MIN; + opt.arg.r.max = FLASH_VENDOR_MAX; +#ifdef module_param_array + if(num_FlashVendor > bd) { +#endif + val = FlashVendor[bd]; + atl2_validate_option(&val, &opt); + adapter->hw.flash_vendor = (u8) val; +#ifdef module_param_array + } else { + adapter->hw.flash_vendor = (u8)(opt.def); + } +#endif + /* MediaType */ + opt.type = range_option; + opt.name = "Speed/Duplex Selection"; + opt.err = "using default of " __MODULE_STRING(MEDIA_TYPE_AUTO_SENSOR); + opt.def = MEDIA_TYPE_AUTO_SENSOR; + opt.arg.r.min = MEDIA_TYPE_AUTO_SENSOR; + opt.arg.r.max = MEDIA_TYPE_10M_HALF; +#ifdef module_param_array + if(num_MediaType > bd) { +#endif + val = MediaType[bd]; + atl2_validate_option(&val, &opt); + adapter->hw.MediaType = (u16) val; +#ifdef module_param_array + } else { + adapter->hw.MediaType = (u16)(opt.def); + } +#endif +} --- linux-2.6.28.orig/ubuntu/atl2/BOM +++ linux-2.6.28/ubuntu/atl2/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://people.redhat.com/csnook/atl2/ +Current Version: 2.0.4 --- linux-2.6.28.orig/ubuntu/ndiswrapper/proc.c +++ linux-2.6.28/ubuntu/ndiswrapper/proc.c @@ -0,0 +1,565 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ +#include +#include +#include + +#include "ndis.h" +#include "iw_ndis.h" +#include "wrapndis.h" +#include "pnp.h" +#include "wrapper.h" + +#define MAX_PROC_STR_LEN 32 + +static struct proc_dir_entry *wrap_procfs_entry; + +static int procfs_read_ndis_stats(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct ndis_wireless_stats stats; + NDIS_STATUS res; + ndis_rssi rssi; + + if (off != 0) { + *eof = 1; + return 0; + } + + res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi)); + if (!res) + p += sprintf(p, "signal_level=%d dBm\n", (s32)rssi); + + res = mp_query(wnd, OID_802_11_STATISTICS, &stats, sizeof(stats)); + if (!res) { + + p += sprintf(p, "tx_frames=%Lu\n", stats.tx_frag); + p += sprintf(p, "tx_multicast_frames=%Lu\n", + stats.tx_multi_frag); + p += sprintf(p, "tx_failed=%Lu\n", stats.failed); + p += sprintf(p, "tx_retry=%Lu\n", stats.retry); + p += sprintf(p, "tx_multi_rerty=%Lu\n", stats.multi_retry); + p += sprintf(p, "tx_rtss_success=%Lu\n", stats.rtss_succ); + p += sprintf(p, "tx_rtss_fail=%Lu\n", stats.rtss_fail); + p += sprintf(p, "ack_fail=%Lu\n", stats.ack_fail); + p += sprintf(p, "frame_duplicates=%Lu\n", stats.frame_dup); + p += sprintf(p, "rx_frames=%Lu\n", stats.rx_frag); + p += sprintf(p, "rx_multicast_frames=%Lu\n", + stats.rx_multi_frag); + p += sprintf(p, "fcs_errors=%Lu\n", stats.fcs_err); + } + + if (p - page > count) { + ERROR("wrote %lu bytes (limit is %u)\n", + (unsigned long)(p - page), count); + *eof = 1; + } + + return (p - page); +} + +static int procfs_read_ndis_encr(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + int i, encr_status, auth_mode, infra_mode; + NDIS_STATUS res; + struct ndis_essid essid; + mac_address ap_address; + + if (off != 0) { + *eof = 1; + return 0; + } + + res = mp_query(wnd, OID_802_11_BSSID, + &ap_address, sizeof(ap_address)); + if (res) + memset(ap_address, 0, ETH_ALEN); + p += sprintf(p, "ap_address=%2.2X", ap_address[0]); + for (i = 1 ; i < ETH_ALEN ; i++) + p += sprintf(p, ":%2.2X", ap_address[i]); + p += sprintf(p, "\n"); + + res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid)); + if (!res) + p += sprintf(p, "essid=%.*s\n", essid.length, essid.essid); + + res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status); + if (!res) { + typeof(&wnd->encr_info.keys[0]) tx_key; + p += sprintf(p, "tx_key=%u\n", wnd->encr_info.tx_key_index); + p += sprintf(p, "key="); + tx_key = &wnd->encr_info.keys[wnd->encr_info.tx_key_index]; + if (tx_key->length > 0) + for (i = 0; i < tx_key->length; i++) + p += sprintf(p, "%2.2X", tx_key->key[i]); + else + p += sprintf(p, "off"); + p += sprintf(p, "\n"); + p += sprintf(p, "encr_mode=%d\n", encr_status); + } + res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &auth_mode); + if (!res) + p += sprintf(p, "auth_mode=%d\n", auth_mode); + res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &infra_mode); + p += sprintf(p, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ? + "adhoc" : (infra_mode == Ndis802_11Infrastructure) ? + "managed" : "auto"); + if (p - page > count) { + WARNING("wrote %lu bytes (limit is %u)", + (unsigned long)(p - page), count); + *eof = 1; + } + + return (p - page); +} + +static int procfs_read_ndis_hw(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct ndis_configuration config; + unsigned int power_mode; + NDIS_STATUS res; + ndis_tx_power_level tx_power; + ULONG bit_rate; + ndis_rts_threshold rts_threshold; + ndis_fragmentation_threshold frag_threshold; + ndis_antenna antenna; + ULONG packet_filter; + int n; + mac_address mac; + char *hw_status[] = {"ready", "initializing", "resetting", "closing", + "not ready"}; + + if (off != 0) { + *eof = 1; + return 0; + } + + res = mp_query_int(wnd, OID_GEN_HARDWARE_STATUS, &n); + if (res == NDIS_STATUS_SUCCESS && + n >= 0 && n < sizeof(hw_status) / sizeof(hw_status[0])) + p += sprintf(p, "status=%s\n", hw_status[n]); + + res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac)); + if (!res) + p += sprintf(p, "mac: " MACSTRSEP "\n", MAC2STR(mac)); + res = mp_query(wnd, OID_802_11_CONFIGURATION, &config, sizeof(config)); + if (!res) { + p += sprintf(p, "beacon_period=%u msec\n", + config.beacon_period); + p += sprintf(p, "atim_window=%u msec\n", config.atim_window); + p += sprintf(p, "frequency=%u kHZ\n", config.ds_config); + p += sprintf(p, "hop_pattern=%u\n", + config.fh_config.hop_pattern); + p += sprintf(p, "hop_set=%u\n", + config.fh_config.hop_set); + p += sprintf(p, "dwell_time=%u msec\n", + config.fh_config.dwell_time); + } + + res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, + &tx_power, sizeof(tx_power)); + if (!res) + p += sprintf(p, "tx_power=%u mW\n", tx_power); + + res = mp_query(wnd, OID_GEN_LINK_SPEED, &bit_rate, sizeof(bit_rate)); + if (!res) + p += sprintf(p, "bit_rate=%u kBps\n", (u32)bit_rate / 10); + + res = mp_query(wnd, OID_802_11_RTS_THRESHOLD, + &rts_threshold, sizeof(rts_threshold)); + if (!res) + p += sprintf(p, "rts_threshold=%u bytes\n", rts_threshold); + + res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, + &frag_threshold, sizeof(frag_threshold)); + if (!res) + p += sprintf(p, "frag_threshold=%u bytes\n", frag_threshold); + + res = mp_query_int(wnd, OID_802_11_POWER_MODE, &power_mode); + if (!res) + p += sprintf(p, "power_mode=%s\n", + (power_mode == NDIS_POWER_OFF) ? "always_on" : + (power_mode == NDIS_POWER_MAX) ? + "max_savings" : "min_savings"); + + res = mp_query(wnd, OID_802_11_NUMBER_OF_ANTENNAS, + &antenna, sizeof(antenna)); + if (!res) + p += sprintf(p, "num_antennas=%u\n", antenna); + + res = mp_query(wnd, OID_802_11_TX_ANTENNA_SELECTED, + &antenna, sizeof(antenna)); + if (!res) + p += sprintf(p, "tx_antenna=%u\n", antenna); + + res = mp_query(wnd, OID_802_11_RX_ANTENNA_SELECTED, + &antenna, sizeof(antenna)); + if (!res) + p += sprintf(p, "rx_antenna=%u\n", antenna); + + p += sprintf(p, "encryption_modes=%s%s%s%s%s%s%s\n", + test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ? + "WEP" : "none", + + test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ? + "; TKIP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : "", + + test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ? + "; AES/CCMP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : ""); + + res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter); + if (!res) { + if (packet_filter != wnd->packet_filter) + WARNING("wrong packet_filter? 0x%08x, 0x%08x\n", + packet_filter, wnd->packet_filter); + p += sprintf(p, "packet_filter: 0x%08x\n", packet_filter); + } + if (p - page > count) { + WARNING("wrote %lu bytes (limit is %u)", + (unsigned long)(p - page), count); + *eof = 1; + } + + return (p - page); +} + +static int procfs_read_ndis_settings(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct wrap_device_setting *setting; + + if (off != 0) { + *eof = 1; + return 0; + } + + p += sprintf(p, "hangcheck_interval=%d\n", + hangcheck_interval == 0 ? + (int)(wnd->hangcheck_interval / HZ) : -1); + + list_for_each_entry(setting, &wnd->wd->settings, list) { + p += sprintf(p, "%s=%s\n", setting->name, setting->value); + } + + list_for_each_entry(setting, &wnd->wd->driver->settings, list) { + p += sprintf(p, "%s=%s\n", setting->name, setting->value); + } + + return (p - page); +} + +static int procfs_write_ndis_settings(struct file *file, const char __user *buf, + unsigned long count, void *data) +{ + struct ndis_device *wnd = (struct ndis_device *)data; + char setting[MAX_PROC_STR_LEN], *p; + unsigned int i; + NDIS_STATUS res; + + if (count > MAX_PROC_STR_LEN) + return -EINVAL; + + memset(setting, 0, sizeof(setting)); + if (copy_from_user(setting, buf, count)) + return -EFAULT; + + if ((p = strchr(setting, '\n'))) + *p = 0; + + if ((p = strchr(setting, '='))) + *p = 0; + + if (!strcmp(setting, "hangcheck_interval")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + hangcheck_del(wnd); + if (i > 0) { + wnd->hangcheck_interval = i * HZ; + hangcheck_add(wnd); + } + } else if (!strcmp(setting, "suspend")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + if (i <= 0 || i > 3) + return -EINVAL; + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + i = wrap_pnp_suspend_pci_device(wnd->wd->pci.pdev, + PMSG_SUSPEND); + else +#ifdef ENABLE_USB + i = wrap_pnp_suspend_usb_device(wnd->wd->usb.intf, + PMSG_SUSPEND); +#else + i = -1; +#endif + if (i) + return -EINVAL; + } else if (!strcmp(setting, "resume")) { + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + i = wrap_pnp_resume_pci_device(wnd->wd->pci.pdev); + else +#ifdef ENABLE_USB + i = wrap_pnp_resume_usb_device(wnd->wd->usb.intf); +#else + i = -1; +#endif + if (i) + return -EINVAL; + } else if (!strcmp(setting, "stats_enabled")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + if (i > 0) + wnd->iw_stats_enabled = TRUE; + else + wnd->iw_stats_enabled = FALSE; + } else if (!strcmp(setting, "packet_filter")) { + if (!p) + return -EINVAL; + p++; + i = simple_strtol(p, NULL, 10); + res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, i); + if (res) + WARNING("setting packet_filter failed: %08X", res); + } else if (!strcmp(setting, "reinit")) { + if (ndis_reinit(wnd) != NDIS_STATUS_SUCCESS) + return -EFAULT; + } else { + struct ndis_configuration_parameter param; + struct unicode_string key; + struct ansi_string ansi; + + if (!p) + return -EINVAL; + p++; + RtlInitAnsiString(&ansi, p); + if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi, + TRUE) != STATUS_SUCCESS) + EXIT1(return -EFAULT); + param.type = NdisParameterString; + RtlInitAnsiString(&ansi, setting); + if (RtlAnsiStringToUnicodeString(&key, &ansi, + TRUE) != STATUS_SUCCESS) { + RtlFreeUnicodeString(¶m.data.string); + EXIT1(return -EINVAL); + } + NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m); + RtlFreeUnicodeString(&key); + RtlFreeUnicodeString(¶m.data.string); + if (res != NDIS_STATUS_SUCCESS) + return -EFAULT; + } + return count; +} + +int wrap_procfs_add_ndis_device(struct ndis_device *wnd) +{ + struct proc_dir_entry *procfs_entry; + + if (wrap_procfs_entry == NULL) + return -ENOMEM; + + if (wnd->procfs_iface) { + ERROR("%s already registered?", wnd->netdev_name); + return -EINVAL; + } + wnd->procfs_iface = proc_mkdir(wnd->netdev_name, wrap_procfs_entry); + if (wnd->procfs_iface == NULL) { + ERROR("couldn't create proc directory"); + return -ENOMEM; + } + wnd->procfs_iface->uid = proc_uid; + wnd->procfs_iface->gid = proc_gid; + + procfs_entry = create_proc_entry("hw", S_IFREG | S_IRUSR | S_IRGRP, + wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'hw'"); + goto err_hw; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_hw; + } + + procfs_entry = create_proc_entry("stats", S_IFREG | S_IRUSR | S_IRGRP, + wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'stats'"); + goto err_stats; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_stats; + } + + procfs_entry = create_proc_entry("encr", S_IFREG | S_IRUSR | S_IRGRP, + wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'encr'"); + goto err_encr; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_encr; + } + + procfs_entry = create_proc_entry("settings", S_IFREG | + S_IRUSR | S_IRGRP | + S_IWUSR | S_IWGRP, wnd->procfs_iface); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'settings'"); + goto err_settings; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->data = wnd; + procfs_entry->read_proc = procfs_read_ndis_settings; + procfs_entry->write_proc = procfs_write_ndis_settings; + } + return 0; + +err_settings: + remove_proc_entry("encr", wnd->procfs_iface); +err_encr: + remove_proc_entry("stats", wnd->procfs_iface); +err_stats: + remove_proc_entry("hw", wnd->procfs_iface); +err_hw: + remove_proc_entry(wnd->netdev_name, wrap_procfs_entry); + wnd->procfs_iface = NULL; + return -ENOMEM; +} + +void wrap_procfs_remove_ndis_device(struct ndis_device *wnd) +{ + struct proc_dir_entry *procfs_iface = xchg(&wnd->procfs_iface, NULL); + + if (procfs_iface == NULL) + return; + remove_proc_entry("hw", procfs_iface); + remove_proc_entry("stats", procfs_iface); + remove_proc_entry("encr", procfs_iface); + remove_proc_entry("settings", procfs_iface); + if (wrap_procfs_entry) + remove_proc_entry(wnd->netdev_name, wrap_procfs_entry); +} + +static int procfs_read_debug(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *p = page; + enum alloc_type type; + + if (off != 0) { + *eof = 1; + return 0; + } + p += sprintf(p, "%d\n", debug); + type = 0; +#ifdef ALLOC_DEBUG + for (type = 0; type < ALLOC_TYPE_MAX; type++) + p += sprintf(p, "total size of allocations in %d: %d\n", + type, alloc_size(type)); +#endif + return (p - page); +} + +static int procfs_write_debug(struct file *file, const char __user *buf, + unsigned long count, void *data) +{ + int i; + char setting[MAX_PROC_STR_LEN], *p; + + if (count > MAX_PROC_STR_LEN) + return -EINVAL; + + memset(setting, 0, sizeof(setting)); + if (copy_from_user(setting, buf, count)) + return -EFAULT; + + if ((p = strchr(setting, '\n'))) + *p = 0; + + if ((p = strchr(setting, '='))) + *p = 0; + + i = simple_strtol(setting, NULL, 10); + if (i >= 0 && i < 10) + debug = i; + else + return -EINVAL; + return count; +} + +int wrap_procfs_init(void) +{ + struct proc_dir_entry *procfs_entry; + + wrap_procfs_entry = proc_mkdir(DRIVER_NAME, proc_net_root); + if (wrap_procfs_entry == NULL) { + ERROR("couldn't create procfs directory"); + return -ENOMEM; + } + wrap_procfs_entry->uid = proc_uid; + wrap_procfs_entry->gid = proc_gid; + + procfs_entry = create_proc_entry("debug", S_IFREG | S_IRUSR | S_IRGRP, + wrap_procfs_entry); + if (procfs_entry == NULL) { + ERROR("couldn't create proc entry for 'debug'"); + return -ENOMEM; + } else { + procfs_entry->uid = proc_uid; + procfs_entry->gid = proc_gid; + procfs_entry->read_proc = procfs_read_debug; + procfs_entry->write_proc = procfs_write_debug; + } + return 0; +} + +void wrap_procfs_remove(void) +{ + if (wrap_procfs_entry == NULL) + return; + remove_proc_entry("debug", wrap_procfs_entry); + remove_proc_entry(DRIVER_NAME, proc_net_root); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/usb.c +++ linux-2.6.28/ubuntu/ndiswrapper/usb.c @@ -0,0 +1,1457 @@ +/* + * Copyright (C) 2004 Jan Kiszka + * Copyright (C) 2005 Giridhar Pemmasani + * + * 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. + * + */ + +#include "ndis.h" +#include "usb.h" +#include "usb_exports.h" + +#ifdef USB_DEBUG +static unsigned int urb_id = 0; + +#define DUMP_WRAP_URB(wrap_urb, dir) \ + USBTRACE("urb %p (%d) %s: buf: %p, len: %d, pipe: 0x%x, %d", \ + (wrap_urb)->urb, (wrap_urb)->id, \ + (dir == USB_DIR_OUT) ? "going down" : "coming back", \ + (wrap_urb)->urb->transfer_buffer, \ + (wrap_urb)->urb->transfer_buffer_length, \ + (wrap_urb)->urb->pipe, (wrap_urb)->urb->status) + +#define DUMP_URB_BUFFER(urb, dir) \ + while (debug >= 2) { \ + int i; \ + char msg[20], *t; \ + if (!urb->transfer_buffer) \ + break; \ + if (!((usb_pipein(urb->pipe) && dir == USB_DIR_IN) || \ + (usb_pipeout(urb->pipe) && dir == USB_DIR_OUT))) \ + break; \ + t = msg; \ + t += sprintf(t, "%d: ", (urb)->actual_length); \ + for (i = 0; i < urb->actual_length && \ + t < &msg[sizeof(msg) - 4]; i++) \ + t += sprintf(t, "%02X ", \ + ((char *)urb->transfer_buffer)[i]); \ + *t = 0; \ + USBTRACE("%s", msg); \ + break; \ + } + +#else + +#define DUMP_WRAP_URB(wrap_urb, dir) (void)0 +#define DUMP_URB_BUFFER(urb, dir) (void)0 + +#endif + +#define CUR_ALT_SETTING(intf) (intf)->cur_altsetting + +#ifndef USB_CTRL_SET_TIMEOUT +#define USB_CTRL_SET_TIMEOUT 5000 +#endif + +#ifndef USB_CTRL_GET_TIMEOUT +#define USB_CTRL_GET_TIMEOUT 5000 +#endif + +#ifndef URB_NO_TRANSFER_DMA_MAP +#define URB_NO_TRANSFER_DMA_MAP 0 +#endif + +/* wrap_urb->flags */ +/* transfer_buffer for urb is allocated; free it in wrap_free_urb */ +#define WRAP_URB_COPY_BUFFER 0x01 + +static int inline wrap_cancel_urb(struct wrap_urb *wrap_urb) +{ + int ret; + USBTRACE("%p, %p, %d", wrap_urb, wrap_urb->urb, wrap_urb->state); + if (wrap_urb->state != URB_SUBMITTED) + USBEXIT(return -1); + ret = usb_unlink_urb(wrap_urb->urb); + USBTRACE("ret: %d", ret); + if (ret == -EINPROGRESS) + return 0; + else { + WARNING("unlink failed: %d", ret); + return ret; + } +} + +#define URB_STATUS(wrap_urb) (wrap_urb->urb->status) + +static struct nt_list wrap_urb_complete_list; +static spinlock_t wrap_urb_complete_list_lock; + +static work_struct_t wrap_urb_complete_work; +static void wrap_urb_complete_worker(worker_param_t dummy); + +static void kill_all_urbs(struct wrap_device *wd, int complete) +{ + struct nt_list *ent; + struct wrap_urb *wrap_urb; + KIRQL irql; + + USBTRACE("%d", wd->usb.num_alloc_urbs); + while (1) { + IoAcquireCancelSpinLock(&irql); + ent = RemoveHeadList(&wd->usb.wrap_urb_list); + IoReleaseCancelSpinLock(irql); + if (!ent) + break; + wrap_urb = container_of(ent, struct wrap_urb, list); + if (wrap_urb->state == URB_SUBMITTED) { + WARNING("Windows driver %s didn't free urb: %p", + wd->driver->name, wrap_urb->urb); + if (!complete) + wrap_urb->urb->complete = NULL; + usb_kill_urb(wrap_urb->urb); + } + USBTRACE("%p, %p", wrap_urb, wrap_urb->urb); + usb_free_urb(wrap_urb->urb); + kfree(wrap_urb); + } + wd->usb.num_alloc_urbs = 0; +} + +/* for a given Linux urb status code, return corresponding NT urb status */ +static USBD_STATUS wrap_urb_status(int urb_status) +{ + switch (urb_status) { + case 0: + return USBD_STATUS_SUCCESS; + case -EPROTO: + return USBD_STATUS_TIMEOUT; + case -EILSEQ: + return USBD_STATUS_CRC; + case -EPIPE: + return USBD_STATUS_INVALID_PIPE_HANDLE; + case -ECOMM: + return USBD_STATUS_DATA_OVERRUN; + case -ENOSR: + return USBD_STATUS_DATA_UNDERRUN; + case -EOVERFLOW: + return USBD_STATUS_BABBLE_DETECTED; + case -EREMOTEIO: + return USBD_STATUS_ERROR_SHORT_TRANSFER;; + case -ENODEV: + case -ESHUTDOWN: + case -ENOENT: + return USBD_STATUS_DEVICE_GONE; + case -ENOMEM: + return USBD_STATUS_NO_MEMORY; + case -EINVAL: + return USBD_STATUS_REQUEST_FAILED; + default: + return USBD_STATUS_NOT_SUPPORTED; + } +} + +/* for a given USBD_STATUS, return its corresponding NTSTATUS (for irp) */ +static NTSTATUS nt_urb_irp_status(USBD_STATUS nt_urb_status) +{ + switch (nt_urb_status) { + case USBD_STATUS_SUCCESS: + return STATUS_SUCCESS; + case USBD_STATUS_DEVICE_GONE: + return STATUS_DEVICE_REMOVED; + case USBD_STATUS_PENDING: + return STATUS_PENDING; + case USBD_STATUS_NOT_SUPPORTED: + return STATUS_NOT_IMPLEMENTED; + case USBD_STATUS_NO_MEMORY: + return STATUS_NO_MEMORY; + case USBD_STATUS_REQUEST_FAILED: + return STATUS_NOT_SUPPORTED; + default: + return STATUS_FAILURE; + } +} + +static void wrap_free_urb(struct urb *urb) +{ + struct irp *irp; + struct wrap_urb *wrap_urb; + + USBTRACE("freeing urb: %p", urb); + wrap_urb = urb->context; + irp = wrap_urb->irp; + if (wrap_urb->flags & WRAP_URB_COPY_BUFFER) { + USBTRACE("freeing DMA buffer for URB: %p %p", + urb, urb->transfer_buffer); + usb_buffer_free(IRP_WRAP_DEVICE(irp)->usb.udev, + urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + } + if (urb->setup_packet) + kfree(urb->setup_packet); + if (IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs > MAX_ALLOCATED_URBS) { + IoAcquireCancelSpinLock(&irp->cancel_irql); + RemoveEntryList(&wrap_urb->list); + IRP_WRAP_DEVICE(irp)->usb.num_alloc_urbs--; + IoReleaseCancelSpinLock(irp->cancel_irql); + usb_free_urb(urb); + kfree(wrap_urb); + } else { + wrap_urb->state = URB_FREE; + wrap_urb->flags = 0; + wrap_urb->irp = NULL; + } + return; +} + +void wrap_suspend_urbs(struct wrap_device *wd) +{ + /* TODO: do we need to cancel urbs? */ + USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs); +} + +void wrap_resume_urbs(struct wrap_device *wd) +{ + /* TODO: do we need to resubmit urbs? */ + USBTRACE("%p, %d", wd, wd->usb.num_alloc_urbs); +} + +wstdcall void wrap_cancel_irp(struct device_object *dev_obj, struct irp *irp) +{ + struct urb *urb; + + /* NB: this function is called holding Cancel spinlock */ + USBENTER("irp: %p", irp); + urb = IRP_WRAP_URB(irp)->urb; + USBTRACE("canceling urb %p", urb); + if (wrap_cancel_urb(IRP_WRAP_URB(irp))) { + irp->cancel = FALSE; + ERROR("urb %p can't be canceld: %d", urb, + IRP_WRAP_URB(irp)->state); + } else + USBTRACE("urb %p canceled", urb); + IoReleaseCancelSpinLock(irp->cancel_irql); + return; +} +WIN_FUNC_DECL(wrap_cancel_irp,2) + +static struct urb *wrap_alloc_urb(struct irp *irp, unsigned int pipe, + void *buf, unsigned int buf_len) +{ + struct urb *urb; + gfp_t alloc_flags; + struct wrap_urb *wrap_urb; + struct wrap_device *wd; + + USBENTER("irp: %p", irp); + wd = IRP_WRAP_DEVICE(irp); + alloc_flags = irql_gfp(); + IoAcquireCancelSpinLock(&irp->cancel_irql); + urb = NULL; + nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) { + if (cmpxchg(&wrap_urb->state, URB_FREE, + URB_ALLOCATED) == URB_FREE) { + urb = wrap_urb->urb; + usb_init_urb(urb); + break; + } + } + if (!urb) { + IoReleaseCancelSpinLock(irp->cancel_irql); + wrap_urb = kzalloc(sizeof(*wrap_urb), alloc_flags); + if (!wrap_urb) { + WARNING("couldn't allocate memory"); + return NULL; + } + urb = usb_alloc_urb(0, alloc_flags); + if (!urb) { + WARNING("couldn't allocate urb"); + kfree(wrap_urb); + return NULL; + } + IoAcquireCancelSpinLock(&irp->cancel_irql); + wrap_urb->urb = urb; + wrap_urb->state = URB_ALLOCATED; + InsertTailList(&wd->usb.wrap_urb_list, &wrap_urb->list); + wd->usb.num_alloc_urbs++; + } + +#ifdef URB_ASYNC_UNLINK + urb->transfer_flags |= URB_ASYNC_UNLINK; +#elif defined(USB_ASYNC_UNLINK) + urb->transfer_flags |= USB_ASYNC_UNLINK; +#endif + urb->context = wrap_urb; + wrap_urb->irp = irp; + IRP_WRAP_URB(irp) = wrap_urb; + /* called as Windows function */ + irp->cancel_routine = WIN_FUNC_PTR(wrap_cancel_irp,2); + IoReleaseCancelSpinLock(irp->cancel_irql); + USBTRACE("urb: %p", urb); + + urb->transfer_buffer_length = buf_len; + if (buf_len && buf && (!virt_addr_valid(buf) +#if defined(CONFIG_HIGHMEM) || defined(CONFIG_HIGHMEM4G) + || PageHighMem(virt_to_page(buf)) +#endif + )) { + urb->transfer_buffer = + usb_buffer_alloc(wd->usb.udev, buf_len, alloc_flags, + &urb->transfer_dma); + if (!urb->transfer_buffer) { + WARNING("couldn't allocate dma buf"); + IoAcquireCancelSpinLock(&irp->cancel_irql); + wrap_urb->state = URB_FREE; + wrap_urb->irp = NULL; + IRP_WRAP_URB(irp) = NULL; + IoReleaseCancelSpinLock(irp->cancel_irql); + return NULL; + } + if (urb->transfer_dma) + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + wrap_urb->flags |= WRAP_URB_COPY_BUFFER; + if (usb_pipeout(pipe)) + memcpy(urb->transfer_buffer, buf, buf_len); + USBTRACE("DMA buf for urb %p: %p", urb, urb->transfer_buffer); + } else + urb->transfer_buffer = buf; + return urb; +} + +static USBD_STATUS wrap_submit_urb(struct irp *irp) +{ + int ret; + struct urb *urb; + union nt_urb *nt_urb; + + urb = IRP_WRAP_URB(irp)->urb; + nt_urb = IRP_URB(irp); +#ifdef USB_DEBUG + if (IRP_WRAP_URB(irp)->state != URB_ALLOCATED) { + ERROR("urb %p is in wrong state: %d", + urb, IRP_WRAP_URB(irp)->state); + NT_URB_STATUS(nt_urb) = USBD_STATUS_REQUEST_FAILED; + return NT_URB_STATUS(nt_urb); + } + IRP_WRAP_URB(irp)->id = pre_atomic_add(urb_id, 1); +#endif + DUMP_WRAP_URB(IRP_WRAP_URB(irp), USB_DIR_OUT); + irp->io_status.status = STATUS_PENDING; + irp->io_status.info = 0; + NT_URB_STATUS(nt_urb) = USBD_STATUS_PENDING; + IoMarkIrpPending(irp); + DUMP_URB_BUFFER(urb, USB_DIR_OUT); + USBTRACE("%p", urb); + IRP_WRAP_URB(irp)->state = URB_SUBMITTED; + ret = usb_submit_urb(urb, irql_gfp()); + if (ret) { + USBTRACE("ret: %d", ret); + wrap_free_urb(urb); + /* we assume that IRP was not in pending state before */ + IoUnmarkIrpPending(irp); + NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); + USBEXIT(return NT_URB_STATUS(nt_urb)); + } else + USBEXIT(return USBD_STATUS_PENDING); +} + +static void wrap_urb_complete(struct urb *urb ISR_PT_REGS_PARAM_DECL) +{ + struct irp *irp; + struct wrap_urb *wrap_urb; + + wrap_urb = urb->context; + USBTRACE("%p (%p) completed", wrap_urb, urb); + irp = wrap_urb->irp; + DUMP_WRAP_URB(wrap_urb, USB_DIR_IN); + irp->cancel_routine = NULL; +#ifdef USB_DEBUG + if (wrap_urb->state != URB_SUBMITTED) { + WARNING("urb %p in wrong state: %d (%d)", urb, wrap_urb->state, + urb->status); + return; + } +#endif + wrap_urb->state = URB_COMPLETED; + spin_lock(&wrap_urb_complete_list_lock); + InsertTailList(&wrap_urb_complete_list, &wrap_urb->complete_list); + spin_unlock(&wrap_urb_complete_list_lock); + schedule_ntos_work(&wrap_urb_complete_work); +} + +/* one worker for all devices */ +static void wrap_urb_complete_worker(worker_param_t dummy) +{ + struct irp *irp; + struct urb *urb; + struct usbd_bulk_or_intr_transfer *bulk_int_tx; + struct usbd_vendor_or_class_request *vc_req; + union nt_urb *nt_urb; + struct wrap_urb *wrap_urb; + struct nt_list *ent; + unsigned long flags; + + USBENTER(""); + while (1) { + spin_lock_irqsave(&wrap_urb_complete_list_lock, flags); + ent = RemoveHeadList(&wrap_urb_complete_list); + spin_unlock_irqrestore(&wrap_urb_complete_list_lock, flags); + if (!ent) + break; + wrap_urb = container_of(ent, struct wrap_urb, complete_list); + urb = wrap_urb->urb; +#ifdef USB_DEBUG + if (wrap_urb->state != URB_COMPLETED && + wrap_urb->state != URB_INT_UNLINKED) + WARNING("urb %p in wrong state: %d", + urb, wrap_urb->state); +#endif + irp = wrap_urb->irp; + DUMP_IRP(irp); + nt_urb = IRP_URB(irp); + USBTRACE("urb: %p, nt_urb: %p, status: %d", + urb, nt_urb, urb->status); + switch (urb->status) { + case 0: + /* succesfully transferred */ + irp->io_status.info = urb->actual_length; + if (nt_urb->header.function == + URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER) { + bulk_int_tx = &nt_urb->bulk_int_transfer; + bulk_int_tx->transfer_buffer_length = + urb->actual_length; + DUMP_URB_BUFFER(urb, USB_DIR_IN); + if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) && + usb_pipein(urb->pipe)) + memcpy(bulk_int_tx->transfer_buffer, + urb->transfer_buffer, + urb->actual_length); + } else { // vendor or class request + vc_req = &nt_urb->vendor_class_request; + vc_req->transfer_buffer_length = + urb->actual_length; + DUMP_URB_BUFFER(urb, USB_DIR_IN); + if ((wrap_urb->flags & WRAP_URB_COPY_BUFFER) && + usb_pipein(urb->pipe)) + memcpy(vc_req->transfer_buffer, + urb->transfer_buffer, + urb->actual_length); + } + NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; + irp->io_status.status = STATUS_SUCCESS; + break; + case -ENOENT: + case -ECONNRESET: + /* urb canceled */ + irp->io_status.info = 0; + TRACE2("urb %p canceled", urb); + NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; + irp->io_status.status = STATUS_CANCELLED; + break; + default: + TRACE2("irp: %p, urb: %p, status: %d/%d", + irp, urb, urb->status, wrap_urb->state); + irp->io_status.info = 0; + NT_URB_STATUS(nt_urb) = wrap_urb_status(urb->status); + irp->io_status.status = + nt_urb_irp_status(NT_URB_STATUS(nt_urb)); + break; + } + wrap_free_urb(urb); + IoCompleteRequest(irp, IO_NO_INCREMENT); + } + USBEXIT(return); +} + +static USBD_STATUS wrap_bulk_or_intr_trans(struct irp *irp) +{ + usbd_pipe_handle pipe_handle; + struct urb *urb; + unsigned int pipe; + struct usbd_bulk_or_intr_transfer *bulk_int_tx; + USBD_STATUS status; + struct usb_device *udev; + union nt_urb *nt_urb; + + nt_urb = IRP_URB(irp); + udev = IRP_WRAP_DEVICE(irp)->usb.udev; + bulk_int_tx = &nt_urb->bulk_int_transfer; + pipe_handle = bulk_int_tx->pipe_handle; + USBTRACE("flags: 0x%x, length: %u, buffer: %p, handle: %p", + bulk_int_tx->transfer_flags, + bulk_int_tx->transfer_buffer_length, + bulk_int_tx->transfer_buffer, pipe_handle); + + if (USBD_IS_BULK_PIPE(pipe_handle)) { + if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN) + pipe = usb_rcvbulkpipe(udev, + pipe_handle->bEndpointAddress); + else + pipe = usb_sndbulkpipe(udev, + pipe_handle->bEndpointAddress); + } else { + if (bulk_int_tx->transfer_flags & USBD_TRANSFER_DIRECTION_IN) + pipe = usb_rcvintpipe(udev, + pipe_handle->bEndpointAddress); + else + pipe = usb_sndintpipe(udev, + pipe_handle->bEndpointAddress); + } + + DUMP_IRP(irp); + urb = wrap_alloc_urb(irp, pipe, bulk_int_tx->transfer_buffer, + bulk_int_tx->transfer_buffer_length); + if (!urb) { + ERROR("couldn't allocate urb"); + return USBD_STATUS_NO_MEMORY; + } + if (usb_pipein(pipe) && + (!(bulk_int_tx->transfer_flags & USBD_SHORT_TRANSFER_OK))) { + USBTRACE("short not ok"); + urb->transfer_flags |= URB_SHORT_NOT_OK; + } + if (usb_pipebulk(pipe)) { + usb_fill_bulk_urb(urb, udev, pipe, urb->transfer_buffer, + bulk_int_tx->transfer_buffer_length, + wrap_urb_complete, urb->context); + USBTRACE("submitting bulk urb %p on pipe 0x%x (ep 0x%x)", + urb, urb->pipe, pipe_handle->bEndpointAddress); + } else { + usb_fill_int_urb(urb, udev, pipe, urb->transfer_buffer, + bulk_int_tx->transfer_buffer_length, + wrap_urb_complete, urb->context, + pipe_handle->bInterval); + USBTRACE("submitting interrupt urb %p on pipe 0x%x (ep 0x%x), " + "intvl: %d", urb, urb->pipe, + pipe_handle->bEndpointAddress, pipe_handle->bInterval); + } + status = wrap_submit_urb(irp); + USBTRACE("status: %08X", status); + USBEXIT(return status); +} + +static USBD_STATUS wrap_vendor_or_class_req(struct irp *irp) +{ + u8 req_type; + unsigned int pipe; + struct usbd_vendor_or_class_request *vc_req; + struct usb_device *udev; + union nt_urb *nt_urb; + USBD_STATUS status; + struct urb *urb; + struct usb_ctrlrequest *dr; + + nt_urb = IRP_URB(irp); + udev = IRP_WRAP_DEVICE(irp)->usb.udev; + vc_req = &nt_urb->vendor_class_request; + USBTRACE("bits: %x, req: %x, val: %08x, index: %08x, flags: %x," + "buf: %p, len: %d", vc_req->reserved_bits, vc_req->request, + vc_req->value, vc_req->index, vc_req->transfer_flags, + vc_req->transfer_buffer, vc_req->transfer_buffer_length); + + USBTRACE("%x", nt_urb->header.function); + switch (nt_urb->header.function) { + case URB_FUNCTION_VENDOR_DEVICE: + req_type = USB_TYPE_VENDOR | USB_RECIP_DEVICE; + break; + case URB_FUNCTION_VENDOR_INTERFACE: + req_type = USB_TYPE_VENDOR | USB_RECIP_INTERFACE; + break; + case URB_FUNCTION_VENDOR_ENDPOINT: + req_type = USB_TYPE_VENDOR | USB_RECIP_ENDPOINT; + break; + case URB_FUNCTION_VENDOR_OTHER: + req_type = USB_TYPE_VENDOR | USB_RECIP_OTHER; + break; + case URB_FUNCTION_CLASS_DEVICE: + req_type = USB_TYPE_CLASS | USB_RECIP_DEVICE; + break; + case URB_FUNCTION_CLASS_INTERFACE: + req_type = USB_TYPE_CLASS | USB_RECIP_INTERFACE; + break; + case URB_FUNCTION_CLASS_ENDPOINT: + req_type = USB_TYPE_CLASS | USB_RECIP_ENDPOINT; + break; + case URB_FUNCTION_CLASS_OTHER: + req_type = USB_TYPE_CLASS | USB_RECIP_OTHER; + break; + default: + ERROR("unknown request type: %x", nt_urb->header.function); + req_type = 0; + break; + } + + req_type |= vc_req->reserved_bits; + USBTRACE("req type: %08x", req_type); + + if (vc_req->transfer_flags & USBD_TRANSFER_DIRECTION_IN) { + pipe = usb_rcvctrlpipe(udev, 0); + req_type |= USB_DIR_IN; + USBTRACE("pipe: %x, dir in", pipe); + } else { + pipe = usb_sndctrlpipe(udev, 0); + req_type |= USB_DIR_OUT; + USBTRACE("pipe: %x, dir out", pipe); + } + urb = wrap_alloc_urb(irp, pipe, vc_req->transfer_buffer, + vc_req->transfer_buffer_length); + if (!urb) { + ERROR("couldn't allocate urb"); + return USBD_STATUS_NO_MEMORY; + } + + if (usb_pipein(pipe) && + (!(vc_req->transfer_flags & USBD_SHORT_TRANSFER_OK))) { + USBTRACE("short not ok"); + urb->transfer_flags |= URB_SHORT_NOT_OK; + } + + dr = kzalloc(sizeof(*dr), GFP_ATOMIC); + if (!dr) { + ERROR("couldn't allocate memory"); + wrap_free_urb(urb); + return USBD_STATUS_NO_MEMORY; + } + dr->bRequestType = req_type; + dr->bRequest = vc_req->request; + dr->wValue = cpu_to_le16(vc_req->value); + dr->wIndex = cpu_to_le16((u16)vc_req->index); + dr->wLength = cpu_to_le16((u16)urb->transfer_buffer_length); + + usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr, + urb->transfer_buffer, urb->transfer_buffer_length, + wrap_urb_complete, urb->context); + status = wrap_submit_urb(irp); + USBTRACE("status: %08X", status); + USBEXIT(return status); +} + +static USBD_STATUS wrap_reset_pipe(struct usb_device *udev, struct irp *irp) +{ + int ret; + union nt_urb *nt_urb; + usbd_pipe_handle pipe_handle; + unsigned int pipe1, pipe2; + + nt_urb = IRP_URB(irp); + pipe_handle = nt_urb->pipe_req.pipe_handle; + /* TODO: not clear if both directions should be cleared? */ + if (USBD_IS_BULK_PIPE(pipe_handle)) { + pipe1 = usb_rcvbulkpipe(udev, pipe_handle->bEndpointAddress); + pipe2 = usb_sndbulkpipe(udev, pipe_handle->bEndpointAddress); + } else if (USBD_IS_INT_PIPE(pipe_handle)) { + pipe1 = usb_rcvintpipe(udev, pipe_handle->bEndpointAddress); + pipe2 = pipe1; + } else { + WARNING("invalid pipe %d", pipe_handle->bEndpointAddress); + return USBD_STATUS_INVALID_PIPE_HANDLE; + } + USBTRACE("ep: %d, pipe: 0x%x", pipe_handle->bEndpointAddress, pipe1); + ret = usb_clear_halt(udev, pipe1); + if (ret) + USBTRACE("resetting pipe %d failed: %d", pipe1, ret); + if (pipe2 != pipe1) { + ret = usb_clear_halt(udev, pipe2); + if (ret) + USBTRACE("resetting pipe %d failed: %d", pipe2, ret); + } +// return wrap_urb_status(ret); + return USBD_STATUS_SUCCESS; +} + +static USBD_STATUS wrap_abort_pipe(struct usb_device *udev, struct irp *irp) +{ + union nt_urb *nt_urb; + usbd_pipe_handle pipe_handle; + struct wrap_urb *wrap_urb; + struct wrap_device *wd; + KIRQL irql; + + wd = IRP_WRAP_DEVICE(irp); + nt_urb = IRP_URB(irp); + pipe_handle = nt_urb->pipe_req.pipe_handle; + USBENTER("%p, %x", irp, pipe_handle->bEndpointAddress); + IoAcquireCancelSpinLock(&irql); + nt_list_for_each_entry(wrap_urb, &wd->usb.wrap_urb_list, list) { + USBTRACE("%p, %p, %d, %x, %x", wrap_urb, wrap_urb->urb, + wrap_urb->state, wrap_urb->urb->pipe, + usb_pipeendpoint(wrap_urb->urb->pipe)); + /* for WG111T driver, urbs for endpoint 0 should also + * be canceled */ + if ((usb_pipeendpoint(wrap_urb->urb->pipe) == + pipe_handle->bEndpointAddress) || + (usb_pipeendpoint(wrap_urb->urb->pipe) == 0)) { + if (wrap_cancel_urb(wrap_urb) == 0) + USBTRACE("canceled wrap_urb: %p", wrap_urb); + } + } + IoReleaseCancelSpinLock(irql); + NT_URB_STATUS(nt_urb) = USBD_STATUS_CANCELED; + USBEXIT(return USBD_STATUS_SUCCESS); +} + +static USBD_STATUS wrap_set_clear_feature(struct usb_device *udev, + struct irp *irp) +{ + union nt_urb *nt_urb; + struct urb_control_feature_request *feat_req; + int ret = 0; + __u8 request, type; + __u16 feature; + + nt_urb = IRP_URB(irp); + feat_req = &nt_urb->feat_req; + feature = feat_req->feature_selector; + switch (nt_urb->header.function) { + case URB_FUNCTION_SET_FEATURE_TO_DEVICE: + request = USB_REQ_SET_FEATURE; + type = USB_DT_DEVICE; + break; + case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: + request = USB_REQ_SET_FEATURE; + type = USB_DT_INTERFACE; + break; + case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: + request = USB_REQ_SET_FEATURE; + type = USB_DT_ENDPOINT; + break; + case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: + request = USB_REQ_CLEAR_FEATURE; + type = USB_DT_DEVICE; + break; + case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: + request = USB_REQ_CLEAR_FEATURE; + type = USB_DT_INTERFACE; + break; + case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: + request = USB_REQ_CLEAR_FEATURE; + type = USB_DT_ENDPOINT; + break; + default: + WARNING("invalid function: %x", nt_urb->header.function); + NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; + return NT_URB_STATUS(nt_urb); + } + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), request, type, + feature, feat_req->index, NULL, 0, 1000); + NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); + USBEXIT(return NT_URB_STATUS(nt_urb)); +} + +static USBD_STATUS wrap_get_status_request(struct usb_device *udev, + struct irp *irp) +{ + union nt_urb *nt_urb; + struct urb_control_get_status_request *status_req; + int ret = 0; + __u8 type; + + nt_urb = IRP_URB(irp); + status_req = &nt_urb->status_req; + switch (nt_urb->header.function) { + case URB_FUNCTION_GET_STATUS_FROM_DEVICE: + type = USB_RECIP_DEVICE; + break; + case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: + type = USB_RECIP_INTERFACE; + break; + case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: + type = USB_RECIP_ENDPOINT; + break; + default: + WARNING("invalid function: %x", nt_urb->header.function); + NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; + return NT_URB_STATUS(nt_urb); + } + assert(status_req->transfer_buffer_length == sizeof(u16)); + ret = usb_get_status(udev, type, status_req->index, + status_req->transfer_buffer); + if (ret >= 0) { + assert(ret <= status_req->transfer_buffer_length); + status_req->transfer_buffer_length = ret; + NT_URB_STATUS(nt_urb) = USBD_STATUS_SUCCESS; + } else + NT_URB_STATUS(nt_urb) = wrap_urb_status(ret); + USBEXIT(return NT_URB_STATUS(nt_urb)); +} + +static void set_intf_pipe_info(struct wrap_device *wd, + struct usb_interface *usb_intf, + struct usbd_interface_information *intf) +{ + int i; + struct usb_endpoint_descriptor *ep; + struct usbd_pipe_information *pipe; + + for (i = 0; i < CUR_ALT_SETTING(usb_intf)->desc.bNumEndpoints; i++) { + ep = &(CUR_ALT_SETTING(usb_intf)->endpoint[i]).desc; + if (i >= intf->bNumEndpoints) { + ERROR("intf %p has only %d endpoints, " + "ignoring endpoints above %d", + intf, intf->bNumEndpoints, i); + break; + } + pipe = &intf->pipes[i]; + + if (pipe->flags & USBD_PF_CHANGE_MAX_PACKET) + USBTRACE("pkt_sz: %d: %d", pipe->wMaxPacketSize, + pipe->max_tx_size); + USBTRACE("driver wants max_tx_size to %d", + pipe->max_tx_size); + + pipe->wMaxPacketSize = le16_to_cpu(ep->wMaxPacketSize); + pipe->bEndpointAddress = ep->bEndpointAddress; + pipe->type = ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; + if (pipe->type == UsbdPipeTypeInterrupt) { + /* Windows and Linux differ in how the + * bInterval is interpretted */ + /* for low speed: + interval (Windows) -> frames per ms (Linux) + 0 to 15 -> 8 + 16 to 35 -> 16 + 36 to 255 -> 32 + + for full speed: interval -> frames per ms + 1 -> 1 + 2 to 3 -> 2 + 4 to 7 -> 4 + 8 to 15 -> 8 + 16 to 31 -> 16 + 32 to 255 -> 32 + + for high speed: interval -> microframes + 1 -> 1 + 2 -> 2 + 3 -> 4 + 4 -> 8 + 5 -> 16 + 6 -> 32 + 7 to 255 -> 32 + */ + if (wd->usb.udev->speed == USB_SPEED_LOW) + pipe->bInterval = ep->bInterval + 5; + else if (wd->usb.udev->speed == USB_SPEED_FULL) + pipe->bInterval = ep->bInterval; + else { + int j, k; + for (j = k = 1; j < ep->bInterval; k++) + j *= 2; + pipe->bInterval = k; + } + } + pipe->handle = ep; + USBTRACE("%d: ep 0x%x, type %d, pkt_sz %d, intv %d (%d)," + "type: %d, handle %p", i, ep->bEndpointAddress, + ep->bmAttributes, pipe->wMaxPacketSize, ep->bInterval, + pipe->bInterval, pipe->type, pipe->handle); + } +} + +static USBD_STATUS wrap_select_configuration(struct wrap_device *wd, + union nt_urb *nt_urb, + struct irp *irp) +{ + int i, ret; + struct usbd_select_configuration *sel_conf; + struct usb_device *udev; + struct usbd_interface_information *intf; + struct usb_config_descriptor *config; + struct usb_interface *usb_intf; + + udev = wd->usb.udev; + sel_conf = &nt_urb->select_conf; + config = sel_conf->config; + USBTRACE("%p", config); + if (config == NULL) { + kill_all_urbs(wd, 1); + ret = usb_reset_configuration(udev); + return wrap_urb_status(ret); + } + + USBTRACE("conf: %d, type: %d, length: %d, numif: %d, attr: %08x", + config->bConfigurationValue, config->bDescriptorType, + config->wTotalLength, config->bNumInterfaces, + config->bmAttributes); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + USB_REQ_SET_CONFIGURATION, 0, + config->bConfigurationValue, 0, + NULL, 0, USB_CTRL_SET_TIMEOUT); + if (ret < 0) { + ERROR("ret: %d", ret); + return wrap_urb_status(ret); + } + sel_conf->handle = udev->actconfig; + intf = &sel_conf->intf; + for (i = 0; i < config->bNumInterfaces && intf->bLength > 0; + i++, intf = (((void *)intf) + intf->bLength)) { + + USBTRACE("intf: %d, alt setting: %d", + intf->bInterfaceNumber, intf->bAlternateSetting); + ret = usb_set_interface(udev, intf->bInterfaceNumber, + intf->bAlternateSetting); + if (ret < 0) { + ERROR("failed with %d", ret); + return wrap_urb_status(ret); + } + usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber); + if (!usb_intf) { + ERROR("couldn't obtain ifnum"); + return USBD_STATUS_REQUEST_FAILED; + } + USBTRACE("intf: %p, num ep: %d", intf, intf->bNumEndpoints); + set_intf_pipe_info(wd, usb_intf, intf); + } + return USBD_STATUS_SUCCESS; +} + +static USBD_STATUS wrap_select_interface(struct wrap_device *wd, + union nt_urb *nt_urb, + struct irp *irp) +{ + int ret; + struct usbd_select_interface *sel_intf; + struct usb_device *udev; + struct usbd_interface_information *intf; + struct usb_interface *usb_intf; + + udev = wd->usb.udev; + sel_intf = &nt_urb->select_intf; + intf = &sel_intf->intf; + + ret = usb_set_interface(udev, intf->bInterfaceNumber, + intf->bAlternateSetting); + if (ret < 0) { + ERROR("failed with %d", ret); + return wrap_urb_status(ret); + } + usb_intf = usb_ifnum_to_if(udev, intf->bInterfaceNumber); + if (!usb_intf) { + ERROR("couldn't get interface information"); + return USBD_STATUS_REQUEST_FAILED; + } + USBTRACE("intf: %p, num ep: %d", usb_intf, intf->bNumEndpoints); + set_intf_pipe_info(wd, usb_intf, intf); + return USBD_STATUS_SUCCESS; +} + +static int wrap_usb_get_string(struct usb_device *udev, unsigned short langid, + unsigned char index, void *buf, int size) +{ + int i, ret; + /* if langid is 0, return array of langauges supported in + * buf */ + for (i = 0; i < 3; i++) { + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, + (USB_DT_STRING << 8) + index, langid, + buf, size, USB_CTRL_GET_TIMEOUT); + if (ret > 0 || ret == -EPIPE) + break; + } + return ret; +} + +static USBD_STATUS wrap_get_descriptor(struct wrap_device *wd, + union nt_urb *nt_urb, struct irp *irp) +{ + struct usbd_control_descriptor_request *control_desc; + int ret = 0; + struct usb_device *udev; + + udev = wd->usb.udev; + control_desc = &nt_urb->control_desc; + USBTRACE("desctype = %d, descindex = %d, transfer_buffer = %p," + "transfer_buffer_length = %d", control_desc->desc_type, + control_desc->index, control_desc->transfer_buffer, + control_desc->transfer_buffer_length); + + if (control_desc->desc_type == USB_DT_STRING) { + USBTRACE("langid: %x", control_desc->language_id); + ret = wrap_usb_get_string(udev, control_desc->language_id, + control_desc->index, + control_desc->transfer_buffer, + control_desc->transfer_buffer_length); + } else { + ret = usb_get_descriptor(udev, control_desc->desc_type, + control_desc->index, + control_desc->transfer_buffer, + control_desc->transfer_buffer_length); + } + if (ret < 0) { + USBTRACE("request %d failed: %d", control_desc->desc_type, ret); + control_desc->transfer_buffer_length = 0; + return wrap_urb_status(ret); + } else { + USBTRACE("ret: %08x", ret); + control_desc->transfer_buffer_length = ret; + irp->io_status.info = ret; + return USBD_STATUS_SUCCESS; + } +} + +static USBD_STATUS wrap_process_nt_urb(struct irp *irp) +{ + union nt_urb *nt_urb; + struct usb_device *udev; + USBD_STATUS status; + struct wrap_device *wd; + + wd = IRP_WRAP_DEVICE(irp); + udev = wd->usb.udev; + nt_urb = IRP_URB(irp); + USBENTER("nt_urb = %p, irp = %p, length = %d, function = %x", + nt_urb, irp, nt_urb->header.length, nt_urb->header.function); + + DUMP_IRP(irp); + switch (nt_urb->header.function) { + /* bulk/int and vendor/class urbs are submitted to + * Linux USB core; if the call is sucessful, urb's + * completion worker will return IRP later */ + case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: + USBTRACE("submitting bulk/int irp: %p", irp); + status = wrap_bulk_or_intr_trans(irp); + break; + + case URB_FUNCTION_VENDOR_DEVICE: + case URB_FUNCTION_VENDOR_INTERFACE: + case URB_FUNCTION_VENDOR_ENDPOINT: + case URB_FUNCTION_VENDOR_OTHER: + case URB_FUNCTION_CLASS_DEVICE: + case URB_FUNCTION_CLASS_INTERFACE: + case URB_FUNCTION_CLASS_ENDPOINT: + case URB_FUNCTION_CLASS_OTHER: + USBTRACE("submitting vendor/class irp: %p", irp); + status = wrap_vendor_or_class_req(irp); + break; + + /* rest are synchronous */ + case URB_FUNCTION_SELECT_CONFIGURATION: + status = wrap_select_configuration(wd, nt_urb, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_SELECT_INTERFACE: + status = wrap_select_interface(wd, nt_urb, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE: + status = wrap_get_descriptor(wd, nt_urb, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL: + status = wrap_reset_pipe(udev, irp); + NT_URB_STATUS(nt_urb) = status; + break; + + case URB_FUNCTION_ABORT_PIPE: + status = wrap_abort_pipe(udev, irp); + break; + + case URB_FUNCTION_SET_FEATURE_TO_DEVICE: + case URB_FUNCTION_SET_FEATURE_TO_INTERFACE: + case URB_FUNCTION_SET_FEATURE_TO_ENDPOINT: + case URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE: + case URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE: + case URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT: + status = wrap_set_clear_feature(udev, irp); + break; + + case URB_FUNCTION_GET_STATUS_FROM_DEVICE: + case URB_FUNCTION_GET_STATUS_FROM_INTERFACE: + case URB_FUNCTION_GET_STATUS_FROM_ENDPOINT: + status = wrap_get_status_request(udev, irp); + break; + + default: + ERROR("function %x not implemented", nt_urb->header.function); + status = NT_URB_STATUS(nt_urb) = USBD_STATUS_NOT_SUPPORTED; + break; + } + USBTRACE("status: %08X", status); + return status; +} + +static USBD_STATUS wrap_reset_port(struct irp *irp) +{ + no_warn_unused int ret, lock = 0; + struct wrap_device *wd; + + wd = IRP_WRAP_DEVICE(irp); + USBENTER("%p, %p", wd, wd->usb.udev); + lock = usb_lock_device_for_reset(wd->usb.udev, wd->usb.intf); + if (lock < 0) { + WARNING("locking failed: %d", lock); +// return wrap_urb_status(lock); + return USBD_STATUS_SUCCESS; + } + ret = usb_reset_device(wd->usb.udev); + if (ret < 0) + USBTRACE("reset failed: %d", ret); + /* TODO: should reconfigure? */ + if (lock) + usb_unlock_device(wd->usb.udev); +// return wrap_urb_status(ret); + return USBD_STATUS_SUCCESS; +} + +static USBD_STATUS wrap_get_port_status(struct irp *irp) +{ + struct wrap_device *wd; + ULONG *status; + enum usb_device_state state; + + wd = IRP_WRAP_DEVICE(irp); + USBENTER("%p, %p", wd, wd->usb.udev); + status = IoGetCurrentIrpStackLocation(irp)->params.others.arg1; + state = wd->usb.udev->state; + if (state != USB_STATE_NOTATTACHED && + state != USB_STATE_SUSPENDED) { + *status |= USBD_PORT_CONNECTED; + if (state == USB_STATE_CONFIGURED) + *status |= USBD_PORT_ENABLED; + } + USBTRACE("state: %d, *status: %08X", state, *status); + return USBD_STATUS_SUCCESS; +} + +NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct wrap_device *wd; + USBD_STATUS status; + struct usbd_idle_callback *idle_callback; + + USBENTER("%p, %p", pdo, irp); + wd = pdo->reserved; + if (wd->usb.intf == NULL) { + USBTRACE("%p", irp); + irp->io_status.status = STATUS_DEVICE_REMOVED; + irp->io_status.info = 0; + USBEXIT(return STATUS_DEVICE_REMOVED); + } + IRP_WRAP_DEVICE(irp) = wd; + irp_sl = IoGetCurrentIrpStackLocation(irp); + switch (irp_sl->params.dev_ioctl.code) { + case IOCTL_INTERNAL_USB_SUBMIT_URB: + status = wrap_process_nt_urb(irp); + break; + case IOCTL_INTERNAL_USB_RESET_PORT: + status = wrap_reset_port(irp); + break; + case IOCTL_INTERNAL_USB_GET_PORT_STATUS: + status = wrap_get_port_status(irp); + break; + case IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION: + idle_callback = irp_sl->params.dev_ioctl.type3_input_buf; + USBTRACE("suspend function: %p", idle_callback->callback); + status = USBD_STATUS_NOT_SUPPORTED; + break; + default: + ERROR("ioctl %08X NOT IMPLEMENTED", + irp_sl->params.dev_ioctl.code); + status = USBD_STATUS_NOT_SUPPORTED; + break; + } + + USBTRACE("status: %08X", status); + if (status == USBD_STATUS_PENDING) { + /* don't touch this IRP - it may have been already + * completed/returned */ + return STATUS_PENDING; + } else { + irp->io_status.status = nt_urb_irp_status(status); + if (status != USBD_STATUS_SUCCESS) + irp->io_status.info = 0; + USBEXIT(return irp->io_status.status); + } +} + +/* TODO: The example on msdn in reference section suggests that second + * argument should be an array of usbd_interface_information, but + * description and examples elsewhere suggest that it should be + * usbd_interface_list_entry structre. Which is correct? */ + +wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequestEx,2) + (struct usb_config_descriptor *config, + struct usbd_interface_list_entry *intf_list) +{ + int size, i, n; + struct usbd_interface_information *intf; + struct usbd_pipe_information *pipe; + struct usb_interface_descriptor *intf_desc; + struct usbd_select_configuration *select_conf; + + USBENTER("config = %p, intf_list = %p", config, intf_list); + + /* calculate size required; select_conf already has space for + * one intf structure */ + size = sizeof(*select_conf) - sizeof(*intf); + for (n = 0; n < config->bNumInterfaces; n++) { + i = intf_list[n].intf_desc->bNumEndpoints; + /* intf already has space for one pipe */ + size += sizeof(*intf) + (i - 1) * sizeof(*pipe); + } + /* don't use kmalloc - driver frees it with ExFreePool */ + select_conf = ExAllocatePoolWithTag(NonPagedPool, size, + POOL_TAG('L', 'U', 'S', 'B')); + if (!select_conf) { + WARNING("couldn't allocate memory"); + return NULL; + } + memset(select_conf, 0, size); + intf = &select_conf->intf; + select_conf->handle = config; + for (n = 0; n < config->bNumInterfaces && intf_list[n].intf_desc; n++) { + /* initialize 'intf' fields in intf_list so they point + * to appropriate entry; these may be read/written by + * driver after this function returns */ + intf_list[n].intf = intf; + intf_desc = intf_list[n].intf_desc; + + i = intf_desc->bNumEndpoints; + intf->bLength = sizeof(*intf) + (i - 1) * sizeof(*pipe); + + intf->bInterfaceNumber = intf_desc->bInterfaceNumber; + intf->bAlternateSetting = intf_desc->bAlternateSetting; + intf->bInterfaceClass = intf_desc->bInterfaceClass; + intf->bInterfaceSubClass = intf_desc->bInterfaceSubClass; + intf->bInterfaceProtocol = intf_desc->bInterfaceProtocol; + intf->bNumEndpoints = intf_desc->bNumEndpoints; + + pipe = &intf->pipes[0]; + for (i = 0; i < intf->bNumEndpoints; i++) { + memset(&pipe[i], 0, sizeof(*pipe)); + pipe[i].max_tx_size = + USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE; + } + intf->handle = intf_desc; + intf = (((void *)intf) + intf->bLength); + } + select_conf->header.function = URB_FUNCTION_SELECT_CONFIGURATION; + select_conf->header.length = size; + select_conf->config = config; + USBEXIT(return (union nt_urb *)select_conf); +} + +WIN_SYMBOL_MAP("_USBD_CreateConfigurationRequestEx@8", USBD_CreateConfigurationRequestEx) + +wstdcall struct usb_interface_descriptor * +WIN_FUNC(USBD_ParseConfigurationDescriptorEx,7) + (struct usb_config_descriptor *config, void *start, + LONG bInterfaceNumber, LONG bAlternateSetting, LONG bInterfaceClass, + LONG bInterfaceSubClass, LONG bInterfaceProtocol) +{ + void *pos; + struct usb_interface_descriptor *intf; + + USBENTER("config = %p, start = %p, ifnum = %d, alt_setting = %d," + " class = %d, subclass = %d, proto = %d", config, start, + bInterfaceNumber, bAlternateSetting, bInterfaceClass, + bInterfaceSubClass, bInterfaceProtocol); + + for (pos = start; + pos < ((void *)config + le16_to_cpu(config->wTotalLength)); + pos += intf->bLength) { + + intf = pos; + + if ((intf->bDescriptorType == USB_DT_INTERFACE) && + ((bInterfaceNumber == -1) || + (intf->bInterfaceNumber == bInterfaceNumber)) && + ((bAlternateSetting == -1) || + (intf->bAlternateSetting == bAlternateSetting)) && + ((bInterfaceClass == -1) || + (intf->bInterfaceClass == bInterfaceClass)) && + ((bInterfaceSubClass == -1) || + (intf->bInterfaceSubClass == bInterfaceSubClass)) && + ((bInterfaceProtocol == -1) || + (intf->bInterfaceProtocol == bInterfaceProtocol))) { + USBTRACE("selected interface = %p", intf); + USBEXIT(return intf); + } + } + USBEXIT(return NULL); +} + +WIN_SYMBOL_MAP("_USBD_ParseConfigurationDescriptorEx@28", USBD_ParseConfigurationDescriptorEx) + +wstdcall union nt_urb *WIN_FUNC(USBD_CreateConfigurationRequest,2) + (struct usb_config_descriptor *config, USHORT *size) +{ + union nt_urb *nt_urb; + struct usbd_interface_list_entry intf_list[2]; + struct usb_interface_descriptor *intf_desc; + + USBENTER("config = %p, urb_size = %p", config, size); + + intf_desc = USBD_ParseConfigurationDescriptorEx(config, config, -1, -1, + -1, -1, -1); + intf_list[0].intf_desc = intf_desc; + intf_list[0].intf = NULL; + intf_list[1].intf_desc = NULL; + intf_list[1].intf = NULL; + nt_urb = USBD_CreateConfigurationRequestEx(config, intf_list); + if (!nt_urb) + return NULL; + + *size = nt_urb->select_conf.header.length; + USBEXIT(return nt_urb); +} + +wstdcall struct usb_interface_descriptor * +WIN_FUNC(USBD_ParseConfigurationDescriptor,3) + (struct usb_config_descriptor *config, UCHAR bInterfaceNumber, + UCHAR bAlternateSetting) +{ + return USBD_ParseConfigurationDescriptorEx(config, config, + bInterfaceNumber, + bAlternateSetting, + -1, -1, -1); +} + +wstdcall usb_common_descriptor_t *WIN_FUNC(USBD_ParseDescriptors,4) + (void *buf, ULONG length, void *start, LONG type) +{ + usb_common_descriptor_t *descr = start; + + while ((void *)descr < buf + length) { + if (descr->bDescriptorType == type) + return descr; + if (descr->bLength == 0) + break; + descr = (void *)descr + descr->bLength; + } + USBEXIT(return NULL); +} + +WIN_SYMBOL_MAP("_USBD_ParseDescriptors@16", USBD_ParseDescriptors) + +wstdcall void WIN_FUNC(USBD_GetUSBDIVersion,1) + (struct usbd_version_info *version_info) +{ + /* this function is obsolete in Windows XP */ + if (version_info) { + version_info->usbdi_version = USBDI_VERSION_XP; + /* TODO: how do we get this correctly? */ + version_info->supported_usb_version = 0x110; + } + USBEXIT(return); +} + +wstdcall void +USBD_InterfaceGetUSBDIVersion(void *context, + struct usbd_version_info *version_info, + ULONG *hcd_capa) +{ + struct wrap_device *wd = context; + + if (version_info) { + version_info->usbdi_version = USBDI_VERSION_XP; + if (wd->usb.udev->speed == USB_SPEED_HIGH) + version_info->supported_usb_version = 0x200; + else + version_info->supported_usb_version = 0x110; + } + *hcd_capa = USB_HCD_CAPS_SUPPORTS_RT_THREADS; + USBEXIT(return); +} + +wstdcall BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context) +{ + struct wrap_device *wd = context; + + USBTRACE("wd: %p", wd); + if (wd->usb.udev->speed == USB_SPEED_HIGH) + USBEXIT(return TRUE); + else + USBEXIT(return FALSE); +} + +wstdcall void USBD_InterfaceReference(void *context) +{ + USBTRACE("%p", context); + TODO(); +} + +wstdcall void USBD_InterfaceDereference(void *context) +{ + USBTRACE("%p", context); + TODO(); +} + +wstdcall NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame) +{ + struct wrap_device *wd = context; + + *frame = usb_get_current_frame_number(wd->usb.udev); + USBEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context, + union nt_urb *nt_urb) +{ + /* TODO: implement this */ + TODO(); + USBEXIT(return STATUS_NOT_IMPLEMENTED); +} + +wstdcall NTSTATUS +USBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf, + ULONG *buf_length, ULONG *buf_actual_length) +{ + struct wrap_device *wd = context; + struct usb_bus_information_level *bus_info; + struct usb_bus *bus; + + bus = wd->usb.udev->bus; + bus_info = buf; + TODO(); + USBEXIT(return STATUS_NOT_IMPLEMENTED); +} + +wstdcall NTSTATUS +USBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag, + ULONG p1, ULONG p2) +{ + ERROR("%p, %x, %x, %x, %x", context, driver_tag, enum_tag, p1, p2); + USBEXIT(return STATUS_SUCCESS); +} + +int usb_init(void) +{ + InitializeListHead(&wrap_urb_complete_list); + spin_lock_init(&wrap_urb_complete_list_lock); + initialize_work(&wrap_urb_complete_work, wrap_urb_complete_worker, NULL); +#ifdef USB_DEBUG + urb_id = 0; +#endif + return 0; +} + +void usb_exit(void) +{ + USBEXIT(return); +} + +int usb_init_device(struct wrap_device *wd) +{ + InitializeListHead(&wd->usb.wrap_urb_list); + wd->usb.num_alloc_urbs = 0; + USBEXIT(return 0); +} + +void usb_exit_device(struct wrap_device *wd) +{ + kill_all_urbs(wd, 0); + USBEXIT(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapndis.c +++ linux-2.6.28/ubuntu/ndiswrapper/wrapndis.c @@ -0,0 +1,2085 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ndis.h" +#include "iw_ndis.h" +#include "pnp.h" +#include "loader.h" +#include "wrapndis.h" +#include +#include +#include +#include +#include +#include "wrapper.h" + +/* Functions callable from the NDIS driver */ +wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo, + struct irp *irp); +wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp); +wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp); + +workqueue_struct_t *wrapndis_wq; +static struct nt_thread *wrapndis_worker_thread; + +static int set_packet_filter(struct ndis_device *wnd, + ULONG packet_filter); +static void add_iw_stats_timer(struct ndis_device *wnd); +static void del_iw_stats_timer(struct ndis_device *wnd); +static NDIS_STATUS ndis_start_device(struct ndis_device *wnd); +static int ndis_remove_device(struct ndis_device *wnd); +static void set_multicast_list(struct ndis_device *wnd); +static int ndis_net_dev_open(struct net_device *net_dev); +static int ndis_net_dev_close(struct net_device *net_dev); + +/* MiniportReset */ +NDIS_STATUS mp_reset(struct ndis_device *wnd) +{ + NDIS_STATUS res; + struct miniport *mp; + BOOLEAN reset_address; + KIRQL irql; + + ENTER2("wnd: %p", wnd); + if (down_interruptible(&wnd->tx_ring_mutex)) + EXIT3(return NDIS_STATUS_FAILURE); + if (down_interruptible(&wnd->ndis_req_mutex)) { + up(&wnd->tx_ring_mutex); + EXIT3(return NDIS_STATUS_FAILURE); + } + mp = &wnd->wd->driver->ndis_driver->mp; + prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0); + WARNING("%s is being reset", wnd->net_dev->name); + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + res = LIN2WIN2(mp->reset, &reset_address, wnd->nmb->mp_ctx); + serialize_unlock_irql(wnd, irql); + + TRACE2("%08X, %08X", res, reset_address); + if (res == NDIS_STATUS_PENDING) { + /* wait for NdisMResetComplete */ + if (wait_condition((wnd->ndis_req_done > 0), 0, + TASK_INTERRUPTIBLE) < 0) + res = NDIS_STATUS_FAILURE; + else { + res = wnd->ndis_req_status; + reset_address = wnd->ndis_req_done - 1; + } + TRACE2("%08X, %08X", res, reset_address); + } + up(&wnd->ndis_req_mutex); + if (res == NDIS_STATUS_SUCCESS && reset_address) { + set_packet_filter(wnd, wnd->packet_filter); + set_multicast_list(wnd); + } + up(&wnd->tx_ring_mutex); + EXIT3(return res); +} + +/* MiniportRequest(Query/Set)Information */ +NDIS_STATUS mp_request(enum ndis_request_type request, + struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen, ULONG *written, ULONG *needed) +{ + NDIS_STATUS res; + ULONG w, n; + struct miniport *mp; + KIRQL irql; + + if (down_interruptible(&wnd->ndis_req_mutex)) + EXIT3(return NDIS_STATUS_FAILURE); + if (!written) + written = &w; + if (!needed) + needed = &n; + mp = &wnd->wd->driver->ndis_driver->mp; + prepare_wait_condition(wnd->ndis_req_task, wnd->ndis_req_done, 0); + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + switch (request) { + case NdisRequestQueryInformation: + TRACE2("%p, %08X, %p", mp->queryinfo, oid, wnd->nmb->mp_ctx); + res = LIN2WIN6(mp->queryinfo, wnd->nmb->mp_ctx, oid, buf, + buflen, written, needed); + break; + case NdisRequestSetInformation: + TRACE2("%p, %08X, %p", mp->setinfo, oid, wnd->nmb->mp_ctx); + res = LIN2WIN6(mp->setinfo, wnd->nmb->mp_ctx, oid, buf, + buflen, written, needed); + break; + default: + WARNING("invalid request %d, %08X", request, oid); + res = NDIS_STATUS_NOT_SUPPORTED; + break; + } + serialize_unlock_irql(wnd, irql); + TRACE2("%08X, %08X", res, oid); + if (res == NDIS_STATUS_PENDING) { + /* wait for NdisMQueryInformationComplete */ + if (wait_condition((wnd->ndis_req_done > 0), 0, + TASK_INTERRUPTIBLE) < 0) + res = NDIS_STATUS_FAILURE; + else + res = wnd->ndis_req_status; + TRACE2("%08X, %08X", res, oid); + } + up(&wnd->ndis_req_mutex); + DBG_BLOCK(2) { + if (res || needed) + TRACE2("%08X, %d, %d, %d", res, buflen, *written, + *needed); + } + EXIT3(return res); +} + +/* MiniportPnPEventNotify */ +static NDIS_STATUS mp_pnp_event(struct ndis_device *wnd, + enum ndis_device_pnp_event event, + ULONG power_profile) +{ + struct miniport *mp; + + ENTER1("%p, %d", wnd, event); + mp = &wnd->wd->driver->ndis_driver->mp; + if (!mp->pnp_event_notify) { + TRACE1("Windows driver %s doesn't support " + "MiniportPnpEventNotify", wnd->wd->driver->name); + return NDIS_STATUS_FAILURE; + } + /* RNDIS driver doesn't like to be notified if device is + * already halted */ + if (!test_bit(HW_INITIALIZED, &wnd->wd->hw_status)) + EXIT1(return NDIS_STATUS_SUCCESS); + switch (event) { + case NdisDevicePnPEventSurpriseRemoved: + TRACE1("%u, %p", + (wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK), + mp->pnp_event_notify); + if ((wnd->attributes & NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK) && + !test_bit(HW_PRESENT, &wnd->wd->hw_status) && + mp->pnp_event_notify) { + TRACE1("calling surprise_removed"); + LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, + NdisDevicePnPEventSurpriseRemoved, NULL, 0); + } else + TRACE1("Windows driver %s doesn't support " + "MiniportPnpEventNotify for safe unplugging", + wnd->wd->driver->name); + return NDIS_STATUS_SUCCESS; + case NdisDevicePnPEventPowerProfileChanged: + if (power_profile) + power_profile = NdisPowerProfileAcOnLine; + LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, + NdisDevicePnPEventPowerProfileChanged, + &power_profile, (ULONG)sizeof(power_profile)); + return NDIS_STATUS_SUCCESS; + default: + WARNING("event %d not yet implemented", event); + return NDIS_STATUS_SUCCESS; + } +} + +/* MiniportInitialize */ +static NDIS_STATUS mp_init(struct ndis_device *wnd) +{ + NDIS_STATUS error_status, status; + UINT medium_index; + enum ndis_medium medium_array[] = {NdisMedium802_3}; + struct miniport *mp; + + ENTER1("irql: %d", current_irql()); + if (test_bit(HW_INITIALIZED, &wnd->wd->hw_status)) { + WARNING("device %p already initialized!", wnd); + return NDIS_STATUS_FAILURE; + } + + if (!wnd->wd->driver->ndis_driver || + !wnd->wd->driver->ndis_driver->mp.init) { + WARNING("assuming WDM (non-NDIS) driver"); + EXIT1(return NDIS_STATUS_NOT_RECOGNIZED); + } + mp = &wnd->wd->driver->ndis_driver->mp; + status = LIN2WIN6(mp->init, &error_status, &medium_index, medium_array, + sizeof(medium_array) / sizeof(medium_array[0]), + wnd->nmb, wnd->nmb); + TRACE1("init returns: %08X, irql: %d", status, current_irql()); + if (status != NDIS_STATUS_SUCCESS) { + WARNING("couldn't initialize device: %08X", status); + EXIT1(return NDIS_STATUS_FAILURE); + } + + /* Wait a little to let card power up otherwise ifup might + * fail after boot */ + sleep_hz(HZ / 5); + status = mp_pnp_event(wnd, NdisDevicePnPEventPowerProfileChanged, + NdisPowerProfileAcOnLine); + if (status != NDIS_STATUS_SUCCESS) + TRACE1("setting power failed: %08X", status); + set_bit(HW_INITIALIZED, &wnd->wd->hw_status); + /* the description about NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND is + * misleading/confusing */ + status = mp_query(wnd, OID_PNP_CAPABILITIES, + &wnd->pnp_capa, sizeof(wnd->pnp_capa)); + if (status == NDIS_STATUS_SUCCESS) { + TRACE1("%d, %d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup, + wnd->pnp_capa.wakeup.min_pattern_wakeup); + wnd->attributes |= NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + status = mp_query_int(wnd, OID_PNP_ENABLE_WAKE_UP, + &wnd->ndis_wolopts); + TRACE1("%08X, %x", status, wnd->ndis_wolopts); + } else if (status == NDIS_STATUS_NOT_SUPPORTED) + wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + TRACE1("%d", wnd->pnp_capa.wakeup.min_magic_packet_wakeup); + /* although some NDIS drivers support suspend, Linux kernel + * has issues with suspending USB devices */ + if (wrap_is_usb_bus(wnd->wd->dev_bus)) { + wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + wnd->ndis_wolopts = 0; + } + mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF); + EXIT1(return NDIS_STATUS_SUCCESS); +} + +/* MiniportHalt */ +static void mp_halt(struct ndis_device *wnd) +{ + struct miniport *mp; + + ENTER1("%p", wnd); + if (!test_and_clear_bit(HW_INITIALIZED, &wnd->wd->hw_status)) { + WARNING("device %p is not initialized - not halting", wnd); + return; + } + hangcheck_del(wnd); + del_iw_stats_timer(wnd); + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan && + wrap_is_pci_bus(wnd->wd->dev_bus)) { + up(&wnd->ndis_req_mutex); + disassociate(wnd, 0); + if (down_interruptible(&wnd->ndis_req_mutex)) + WARNING("couldn't obtain ndis_req_mutex"); + } + mp = &wnd->wd->driver->ndis_driver->mp; + TRACE1("halt: %p", mp->mp_halt); + LIN2WIN1(mp->mp_halt, wnd->nmb->mp_ctx); + /* if a driver doesn't call NdisMDeregisterInterrupt during + * halt, deregister it now */ + if (wnd->mp_interrupt) + NdisMDeregisterInterrupt(wnd->mp_interrupt); + /* cancel any timers left by bugyy windows driver; also free + * the memory for timers */ + while (1) { + struct nt_slist *slist; + struct wrap_timer *wrap_timer; + + spin_lock_bh(&ntoskernel_lock); + if ((slist = wnd->wrap_timer_slist.next)) + wnd->wrap_timer_slist.next = slist->next; + spin_unlock_bh(&ntoskernel_lock); + TIMERTRACE("%p", slist); + if (!slist) + break; + wrap_timer = container_of(slist, struct wrap_timer, slist); + wrap_timer->repeat = 0; + /* ktimer that this wrap_timer is associated to can't + * be touched, as it may have been freed by the driver + * already */ + if (del_timer_sync(&wrap_timer->timer)) + WARNING("Buggy Windows driver left timer %p " + "running", wrap_timer->nt_timer); + memset(wrap_timer, 0, sizeof(*wrap_timer)); + kfree(wrap_timer); + } + EXIT1(return); +} + +static NDIS_STATUS mp_set_power_state(struct ndis_device *wnd, + enum ndis_power_state state) +{ + NDIS_STATUS status; + + TRACE1("%d", state); + if (state == NdisDeviceStateD0) { + status = NDIS_STATUS_SUCCESS; + up(&wnd->ndis_req_mutex); + if (test_and_clear_bit(HW_HALTED, &wnd->wd->hw_status)) { + status = mp_init(wnd); + if (status == NDIS_STATUS_SUCCESS) { + set_packet_filter(wnd, wnd->packet_filter); + set_multicast_list(wnd); + } + } else if (test_and_clear_bit(HW_SUSPENDED, + &wnd->wd->hw_status)) { + status = mp_set_int(wnd, OID_PNP_SET_POWER, state); + if (status != NDIS_STATUS_SUCCESS) + WARNING("%s: setting power to state %d failed? " + "%08X", wnd->net_dev->name, state, + status); + } else + return NDIS_STATUS_FAILURE; + + if (wrap_is_pci_bus(wnd->wd->dev_bus)) { + pci_enable_wake(wnd->wd->pci.pdev, PCI_D3hot, 0); + pci_enable_wake(wnd->wd->pci.pdev, PCI_D3cold, 0); + } + if (status == NDIS_STATUS_SUCCESS) { + up(&wnd->tx_ring_mutex); + netif_device_attach(wnd->net_dev); + hangcheck_add(wnd); + add_iw_stats_timer(wnd); + } else + WARNING("%s: couldn't set power to state %d; device not" + " resumed", wnd->net_dev->name, state); + EXIT1(return status); + } else { + if (down_interruptible(&wnd->tx_ring_mutex)) + EXIT1(return NDIS_STATUS_FAILURE); + netif_device_detach(wnd->net_dev); + hangcheck_del(wnd); + del_iw_stats_timer(wnd); + status = NDIS_STATUS_NOT_SUPPORTED; + if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) { + status = mp_set_int(wnd, OID_PNP_ENABLE_WAKE_UP, + wnd->ndis_wolopts); + TRACE2("0x%x, 0x%x", status, wnd->ndis_wolopts); + if (status == NDIS_STATUS_SUCCESS) { + if (wnd->ndis_wolopts) + wnd->wd->pci.wake_state = + PowerDeviceD3; + else + wnd->wd->pci.wake_state = + PowerDeviceUnspecified; + } else + WARNING("couldn't set wake-on-lan options: " + "0x%x, %08X", wnd->ndis_wolopts, status); + status = mp_set_int(wnd, OID_PNP_SET_POWER, state); + if (status == NDIS_STATUS_SUCCESS) + set_bit(HW_SUSPENDED, &wnd->wd->hw_status); + else + WARNING("suspend failed: %08X", status); + } + if (status != NDIS_STATUS_SUCCESS) { + WARNING("%s does not support power management; " + "halting the device", wnd->net_dev->name); + mp_halt(wnd); + set_bit(HW_HALTED, &wnd->wd->hw_status); + status = STATUS_SUCCESS; + } + if (down_interruptible(&wnd->ndis_req_mutex)) + WARNING("couldn't lock ndis_req_mutex"); + EXIT1(return status); + } +} + +static int ndis_set_mac_address(struct net_device *dev, void *p) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct sockaddr *addr = p; + struct ndis_configuration_parameter param; + struct unicode_string key; + struct ansi_string ansi; + NDIS_STATUS res; + unsigned char mac_string[2 * ETH_ALEN + 1]; + mac_address mac; + + memcpy(mac, addr->sa_data, sizeof(mac)); + memset(mac_string, 0, sizeof(mac_string)); + res = snprintf(mac_string, sizeof(mac_string), MACSTR, MAC2STR(mac)); + if (res != (sizeof(mac_string) - 1)) + EXIT1(return -EINVAL); + TRACE1("new mac: %s", mac_string); + + RtlInitAnsiString(&ansi, mac_string); + if (RtlAnsiStringToUnicodeString(¶m.data.string, &ansi, + TRUE) != STATUS_SUCCESS) + EXIT1(return -EINVAL); + + param.type = NdisParameterString; + RtlInitAnsiString(&ansi, "NetworkAddress"); + if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) { + RtlFreeUnicodeString(¶m.data.string); + EXIT1(return -EINVAL); + } + NdisWriteConfiguration(&res, wnd->nmb, &key, ¶m); + RtlFreeUnicodeString(&key); + RtlFreeUnicodeString(¶m.data.string); + + if (res != NDIS_STATUS_SUCCESS) + EXIT1(return -EFAULT); + if (ndis_reinit(wnd) == NDIS_STATUS_SUCCESS) { + res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, + mac, sizeof(mac)); + if (res == NDIS_STATUS_SUCCESS) { + TRACE1("mac:" MACSTRSEP, MAC2STR(mac)); + memcpy(dev->dev_addr, mac, sizeof(mac)); + } else + ERROR("couldn't get mac address: %08X", res); + } + EXIT1(return 0); +} + +static int setup_tx_sg_list(struct ndis_device *wnd, struct sk_buff *skb, + struct ndis_packet_oob_data *oob_data) +{ + struct ndis_sg_element *sg_element; + struct ndis_sg_list *sg_list; + int i; + + ENTER3("%p, %d", skb, skb_shinfo(skb)->nr_frags); + if (skb_shinfo(skb)->nr_frags <= 1) { + sg_element = &oob_data->wrap_tx_sg_list.elements[0]; + sg_element->address = + PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data, + skb->len, PCI_DMA_TODEVICE); + sg_element->length = skb->len; + oob_data->wrap_tx_sg_list.nent = 1; + oob_data->ext.info[ScatterGatherListPacketInfo] = + &oob_data->wrap_tx_sg_list; + TRACE3("%Lx, %u", sg_element->address, sg_element->length); + return 0; + } + sg_list = kmalloc(sizeof(*sg_list) + + (skb_shinfo(skb)->nr_frags + 1) * sizeof(*sg_element), + GFP_ATOMIC); + if (!sg_list) + return -ENOMEM; + sg_list->nent = skb_shinfo(skb)->nr_frags + 1; + TRACE3("%p, %d", sg_list, sg_list->nent); + sg_element = sg_list->elements; + sg_element->length = skb_headlen(skb); + sg_element->address = + PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, skb->data, + skb_headlen(skb), PCI_DMA_TODEVICE); + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + sg_element++; + sg_element->length = frag->size; + sg_element->address = + pci_map_page(wnd->wd->pci.pdev, frag->page, + frag->page_offset, frag->size, + PCI_DMA_TODEVICE); + TRACE3("%Lx, %u", sg_element->address, sg_element->length); + } + oob_data->ext.info[ScatterGatherListPacketInfo] = sg_list; + return 0; +} + +static void free_tx_sg_list(struct ndis_device *wnd, + struct ndis_packet_oob_data *oob_data) +{ + int i; + struct ndis_sg_element *sg_element; + struct ndis_sg_list *sg_list = + oob_data->ext.info[ScatterGatherListPacketInfo]; + sg_element = sg_list->elements; + TRACE3("%p, %d", sg_list, sg_list->nent); + PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, sg_element->address, + sg_element->length, PCI_DMA_TODEVICE); + if (sg_list->nent == 1) + EXIT3(return); + for (i = 1; i < sg_list->nent; i++, sg_element++) { + TRACE3("%Lx, %u", sg_element->address, sg_element->length); + pci_unmap_page(wnd->wd->pci.pdev, sg_element->address, + sg_element->length, PCI_DMA_TODEVICE); + } + TRACE3("%p", sg_list); + kfree(sg_list); +} + +static struct ndis_packet *alloc_tx_packet(struct ndis_device *wnd, + struct sk_buff *skb) +{ + struct ndis_packet *packet; + ndis_buffer *buffer; + struct ndis_packet_oob_data *oob_data; + NDIS_STATUS status; + + NdisAllocatePacket(&status, &packet, wnd->tx_packet_pool); + if (status != NDIS_STATUS_SUCCESS) + return NULL; + NdisAllocateBuffer(&status, &buffer, wnd->tx_buffer_pool, + skb->data, skb->len); + if (status != NDIS_STATUS_SUCCESS) { + NdisFreePacket(packet); + return NULL; + } + packet->private.buffer_head = buffer; + packet->private.buffer_tail = buffer; + + oob_data = NDIS_PACKET_OOB_DATA(packet); + oob_data->tx_skb = skb; + if (wnd->sg_dma_size) { + if (setup_tx_sg_list(wnd, skb, oob_data)) { + NdisFreeBuffer(buffer); + NdisFreePacket(packet); + return NULL; + } + } + if (skb->ip_summed == CHECKSUM_PARTIAL) { + struct ndis_tcp_ip_checksum_packet_info csum; + int protocol; +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) + protocol = ntohs(skb->protocol); +#else + protocol = skb->nh.iph->protocol; +#endif + csum.value = 0; + csum.tx.v4 = 1; + if (protocol == IPPROTO_TCP) + csum.tx.tcp = 1; + else if (protocol == IPPROTO_UDP) + csum.tx.udp = 1; +// csum->tx.ip = 1; + packet->private.flags |= NDIS_PROTOCOL_ID_TCP_IP; + oob_data->ext.info[TcpIpChecksumPacketInfo] = + (void *)(ULONG_PTR)csum.value; + } + DBG_BLOCK(4) { + dump_bytes(__FUNCTION__, skb->data, skb->len); + } + TRACE4("%p, %p, %p", packet, buffer, skb); + return packet; +} + +void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet, + NDIS_STATUS status) +{ + ndis_buffer *buffer; + struct ndis_packet_oob_data *oob_data; + struct sk_buff *skb; + struct ndis_packet_pool *pool; + + assert_irql(_irql_ <= DISPATCH_LEVEL); + assert(packet->private.packet_flags); + oob_data = NDIS_PACKET_OOB_DATA(packet); + skb = oob_data->tx_skb; + buffer = packet->private.buffer_head; + TRACE4("%p, %p, %p, %08X", packet, buffer, skb, status); + if (status == NDIS_STATUS_SUCCESS) { + pre_atomic_add(wnd->net_stats.tx_bytes, packet->private.len); + atomic_inc_var(wnd->net_stats.tx_packets); + } else { + TRACE1("packet dropped: %08X", status); + atomic_inc_var(wnd->net_stats.tx_dropped); + } + if (wnd->sg_dma_size) + free_tx_sg_list(wnd, oob_data); + NdisFreeBuffer(buffer); + dev_kfree_skb_any(skb); + pool = packet->private.pool; + NdisFreePacket(packet); + if (netif_queue_stopped(wnd->net_dev) && + ((pool->max_descr - pool->num_used_descr) >= + (wnd->max_tx_packets / 4))) { + set_bit(NETIF_WAKEQ, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + EXIT4(return); +} + +/* MiniportSend and MiniportSendPackets */ +/* this function is called holding tx_ring_mutex. start and n are such + * that start + n < TX_RING_SIZE; i.e., packets don't wrap around + * ring */ +static u8 mp_tx_packets(struct ndis_device *wnd, u8 start, u8 n) +{ + NDIS_STATUS res; + struct miniport *mp; + struct ndis_packet *packet; + u8 sent; + KIRQL irql; + + ENTER3("%d, %d", start, n); + mp = &wnd->wd->driver->ndis_driver->mp; + if (mp->send_packets) { + if (deserialized_driver(wnd)) { + LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, + &wnd->tx_ring[start], n); + sent = n; + } else { + irql = serialize_lock_irql(wnd); + LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, + &wnd->tx_ring[start], n); + serialize_unlock_irql(wnd, irql); + for (sent = 0; sent < n && wnd->tx_ok; sent++) { + struct ndis_packet_oob_data *oob_data; + packet = wnd->tx_ring[start + sent]; + oob_data = NDIS_PACKET_OOB_DATA(packet); + switch ((res = + xchg(&oob_data->status, + NDIS_STATUS_NOT_RECOGNIZED))) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, + NDIS_STATUS_SUCCESS); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + /* resubmit this packet and + * the rest when resources + * become available */ + sent--; + break; + case NDIS_STATUS_FAILURE: + free_tx_packet(wnd, packet, + NDIS_STATUS_FAILURE); + break; + default: + ERROR("%p: invalid status: %08X", + packet, res); + free_tx_packet(wnd, packet, + oob_data->status); + break; + } + TRACE3("%p, %d", packet, res); + } + } + TRACE3("sent: %d(%d)", sent, n); + } else { + for (sent = 0; sent < n && wnd->tx_ok; sent++) { + struct ndis_packet_oob_data *oob_data; + packet = wnd->tx_ring[start + sent]; + oob_data = NDIS_PACKET_OOB_DATA(packet); + oob_data->status = NDIS_STATUS_NOT_RECOGNIZED; + irql = serialize_lock_irql(wnd); + res = LIN2WIN3(mp->send, wnd->nmb->mp_ctx, + packet, packet->private.flags); + serialize_unlock_irql(wnd, irql); + switch (res) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, res); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + /* resend this packet when resources + * become available */ + sent--; + break; + case NDIS_STATUS_FAILURE: + free_tx_packet(wnd, packet, res); + break; + default: + ERROR("packet %p: invalid status: %08X", + packet, res); + break; + } + } + } + EXIT3(return sent); +} + +static void tx_worker(worker_param_t param) +{ + struct ndis_device *wnd; + s8 n; + + wnd = worker_param_data(param, struct ndis_device, tx_work); + ENTER3("tx_ok %d", wnd->tx_ok); + while (wnd->tx_ok) { + if (down_interruptible(&wnd->tx_ring_mutex)) + break; + spin_lock_bh(&wnd->tx_ring_lock); + n = wnd->tx_ring_end - wnd->tx_ring_start; + TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n); + /* end == start if either ring is empty or full; in + * the latter case is_tx_ring_full is set */ + if (n == 0) { + if (wnd->is_tx_ring_full) + n = TX_RING_SIZE - wnd->tx_ring_start; + else { + spin_unlock_bh(&wnd->tx_ring_lock); + up(&wnd->tx_ring_mutex); + break; + } + } else if (n < 0) + n = TX_RING_SIZE - wnd->tx_ring_start; + spin_unlock_bh(&wnd->tx_ring_lock); + if (unlikely(n > wnd->max_tx_packets)) + n = wnd->max_tx_packets; + n = mp_tx_packets(wnd, wnd->tx_ring_start, n); + if (n) { + wnd->net_dev->trans_start = jiffies; + wnd->tx_ring_start = + (wnd->tx_ring_start + n) % TX_RING_SIZE; + wnd->is_tx_ring_full = 0; + } + up(&wnd->tx_ring_mutex); + TRACE3("%d, %d, %d", wnd->tx_ring_start, wnd->tx_ring_end, n); + } + EXIT3(return); +} + +static int tx_skbuff(struct sk_buff *skb, struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct ndis_packet *packet; + + packet = alloc_tx_packet(wnd, skb); + if (!packet) { + TRACE2("couldn't allocate packet"); + netif_tx_lock(dev); + netif_stop_queue(dev); + netif_tx_unlock(dev); + return NETDEV_TX_BUSY; + } + spin_lock(&wnd->tx_ring_lock); + wnd->tx_ring[wnd->tx_ring_end++] = packet; + if (wnd->tx_ring_end == TX_RING_SIZE) + wnd->tx_ring_end = 0; + if (wnd->tx_ring_end == wnd->tx_ring_start) { + netif_tx_lock(dev); + wnd->is_tx_ring_full = 1; + netif_stop_queue(dev); + netif_tx_unlock(dev); + } + spin_unlock(&wnd->tx_ring_lock); + TRACE4("ring: %d, %d", wnd->tx_ring_start, wnd->tx_ring_end); + schedule_wrapndis_work(&wnd->tx_work); + return NETDEV_TX_OK; +} + +static int set_packet_filter(struct ndis_device *wnd, ULONG packet_filter) +{ + NDIS_STATUS res; + + while (1) { + res = mp_set_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, + packet_filter); + if (res == NDIS_STATUS_SUCCESS) + break; + TRACE2("couldn't set filter 0x%08x", packet_filter); + /* NDIS_PACKET_TYPE_PROMISCUOUS may not work with 802.11 */ + if (packet_filter & NDIS_PACKET_TYPE_PROMISCUOUS) { + packet_filter &= ~NDIS_PACKET_TYPE_PROMISCUOUS; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_ALL_LOCAL) { + packet_filter &= ~NDIS_PACKET_TYPE_ALL_LOCAL; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_ALL_FUNCTIONAL) { + packet_filter &= ~NDIS_PACKET_TYPE_ALL_FUNCTIONAL; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_MULTICAST) { + packet_filter &= ~NDIS_PACKET_TYPE_MULTICAST; + packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; + continue; + } + if (packet_filter & NDIS_PACKET_TYPE_ALL_MULTICAST) { + packet_filter &= ~NDIS_PACKET_TYPE_ALL_MULTICAST; + continue; + } + break; + } + + wnd->packet_filter = packet_filter; + res = mp_query_int(wnd, OID_GEN_CURRENT_PACKET_FILTER, &packet_filter); + if (packet_filter != wnd->packet_filter) { + WARNING("filter not set: 0x%08x, 0x%08x", + packet_filter, wnd->packet_filter); + wnd->packet_filter = packet_filter; + } + if (wnd->packet_filter) + EXIT3(return 0); + else + EXIT3(return -1); +} + +static int ndis_net_dev_open(struct net_device *net_dev) +{ + ENTER1("%p", netdev_priv(net_dev)); + netif_start_queue(net_dev); + netif_poll_enable(net_dev); + EXIT1(return 0); +} + +static int ndis_net_dev_close(struct net_device *net_dev) +{ + ENTER1("%p", netdev_priv(net_dev)); + netif_poll_disable(net_dev); + netif_tx_disable(net_dev); + EXIT1(return 0); +} + +static int ndis_change_mtu(struct net_device *net_dev, int mtu) +{ + struct ndis_device *wnd = netdev_priv(net_dev); + int max; + + if (mtu < ETH_ZLEN) + return -EINVAL; + if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &max) != + NDIS_STATUS_SUCCESS) + return -EOPNOTSUPP; + TRACE1("%d", max); + max -= ETH_HLEN; + if (max <= ETH_ZLEN) + return -EINVAL; + if (mtu + ETH_HLEN > max) + return -EINVAL; + net_dev->mtu = mtu; + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void ndis_poll_controller(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + + disable_irq(dev->irq); + ndis_isr(wnd->mp_interrupt->kinterrupt, wnd->mp_interrupt); + enable_irq(dev->irq); +} +#endif + +/* called from BH context */ +static struct net_device_stats *ndis_get_stats(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + return &wnd->net_stats; +} + +/* called from BH context */ +static void ndis_set_multicast_list(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + set_bit(SET_MULTICAST_LIST, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); +} + +/* called from BH context */ +struct iw_statistics *get_iw_stats(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + return &wnd->iw_stats; +} + +static void update_iw_stats(struct ndis_device *wnd) +{ + struct iw_statistics *iw_stats = &wnd->iw_stats; + struct ndis_wireless_stats ndis_stats; + NDIS_STATUS res; + ndis_rssi rssi; + int qual; + + ENTER2("%p", wnd); + if (wnd->iw_stats_enabled == FALSE || !netif_carrier_ok(wnd->net_dev)) { + memset(iw_stats, 0, sizeof(*iw_stats)); + EXIT2(return); + } + res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi)); + if (res == NDIS_STATUS_SUCCESS) + iw_stats->qual.level = rssi; + + qual = 100 * (rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE); + if (qual < 0) + qual = 0; + else if (qual > 100) + qual = 100; + + iw_stats->qual.noise = WL_NOISE; + iw_stats->qual.qual = qual; + + res = mp_query(wnd, OID_802_11_STATISTICS, + &ndis_stats, sizeof(ndis_stats)); + if (res != NDIS_STATUS_SUCCESS) + EXIT2(return); + iw_stats->discard.retries = (unsigned long)ndis_stats.retry + + (unsigned long)ndis_stats.multi_retry; + iw_stats->discard.misc = (unsigned long)ndis_stats.fcs_err + + (unsigned long)ndis_stats.rtss_fail + + (unsigned long)ndis_stats.ack_fail + + (unsigned long)ndis_stats.frame_dup; + + EXIT2(return); +} + +static void set_multicast_list(struct ndis_device *wnd) +{ + struct net_device *net_dev; + ULONG packet_filter; + NDIS_STATUS res; + + net_dev = wnd->net_dev; + packet_filter = wnd->packet_filter; + + TRACE2("0x%08x", packet_filter); + if (net_dev->flags & IFF_PROMISC) { + packet_filter |= NDIS_PACKET_TYPE_PROMISCUOUS | + NDIS_PACKET_TYPE_ALL_LOCAL; + } else if (net_dev->flags & IFF_ALLMULTI || + net_dev->mc_count > wnd->multicast_size) { + packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; + TRACE2("0x%08x", packet_filter); + } else if (net_dev->mc_count > 0) { + int i, size; + char *buf; + struct dev_mc_list *mclist; + size = min(wnd->multicast_size, net_dev->mc_count); + TRACE2("%d, %d", wnd->multicast_size, net_dev->mc_count); + buf = kmalloc(size * ETH_ALEN, GFP_KERNEL); + if (!buf) { + WARNING("couldn't allocate memory"); + EXIT2(return); + } + mclist = net_dev->mc_list; + for (i = 0; i < size && mclist; mclist = mclist->next) { + if (mclist->dmi_addrlen != ETH_ALEN) + continue; + memcpy(buf + i * ETH_ALEN, mclist->dmi_addr, ETH_ALEN); + TRACE2(MACSTRSEP, MAC2STR(mclist->dmi_addr)); + i++; + } + res = mp_set(wnd, OID_802_3_MULTICAST_LIST, buf, i * ETH_ALEN); + if (res == NDIS_STATUS_SUCCESS && i > 0) + packet_filter |= NDIS_PACKET_TYPE_MULTICAST; + else + packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST; + kfree(buf); + } + TRACE2("0x%08x", packet_filter); + res = set_packet_filter(wnd, packet_filter); + if (res) + TRACE1("couldn't set packet filter (%08X)", res); + EXIT2(return); +} + +static void link_status_off(struct ndis_device *wnd) +{ +#ifdef CONFIG_WIRELESS_EXT + union iwreq_data wrqu; + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL); +#endif + EXIT2(return); +} + +static void link_status_on(struct ndis_device *wnd) +{ +#ifdef CONFIG_WIRELESS_EXT + struct ndis_assoc_info *ndis_assoc_info; + union iwreq_data wrqu; + NDIS_STATUS res; + const int assoc_size = sizeof(*ndis_assoc_info) + IW_CUSTOM_MAX + 32; +#endif + + ENTER2(""); +#ifdef CONFIG_WIRELESS_EXT + memset(&wrqu, 0, sizeof(wrqu)); + ndis_assoc_info = kzalloc(assoc_size, GFP_KERNEL); + if (!ndis_assoc_info) { + ERROR("couldn't allocate memory"); + goto send_assoc_event; + } + res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION, + ndis_assoc_info, assoc_size); + if (res) { + TRACE2("query assoc_info failed (%08X)", res); + kfree(ndis_assoc_info); + goto send_assoc_event; + } + TRACE2("%u, 0x%x, %u, 0x%x, %u", ndis_assoc_info->length, + ndis_assoc_info->req_ies, ndis_assoc_info->req_ie_length, + ndis_assoc_info->resp_ies, ndis_assoc_info->resp_ie_length); + if (ndis_assoc_info->req_ie_length > 0) { + wrqu.data.length = ndis_assoc_info->req_ie_length; + wireless_send_event(wnd->net_dev, IWEVASSOCREQIE, &wrqu, + ((char *)ndis_assoc_info) + + ndis_assoc_info->offset_req_ies); + } + if (ndis_assoc_info->resp_ie_length > 0) { + wrqu.data.length = ndis_assoc_info->resp_ie_length; + wireless_send_event(wnd->net_dev, IWEVASSOCRESPIE, &wrqu, + ((char *)ndis_assoc_info) + + ndis_assoc_info->offset_resp_ies); + } + kfree(ndis_assoc_info); + +send_assoc_event: + get_ap_address(wnd, wrqu.ap_addr.sa_data); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + TRACE2(MACSTRSEP, MAC2STR(wrqu.ap_addr.sa_data)); + wireless_send_event(wnd->net_dev, SIOCGIWAP, &wrqu, NULL); +#endif + EXIT2(return); +} + +static void iw_stats_timer_proc(unsigned long data) +{ + struct ndis_device *wnd = (struct ndis_device *)data; + + ENTER2("%d", wnd->iw_stats_interval); + if (wnd->iw_stats_interval > 0) { + set_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval); +} + +static void add_iw_stats_timer(struct ndis_device *wnd) +{ + if (wnd->physical_medium != NdisPhysicalMediumWirelessLan) + return; + if (wnd->iw_stats_interval < 0) + wnd->iw_stats_interval *= -1; + wnd->iw_stats_timer.data = (unsigned long)wnd; + wnd->iw_stats_timer.function = iw_stats_timer_proc; + mod_timer(&wnd->iw_stats_timer, jiffies + wnd->iw_stats_interval); +} + +static void del_iw_stats_timer(struct ndis_device *wnd) +{ + ENTER2("%d", wnd->iw_stats_interval); + wnd->iw_stats_interval *= -1; + del_timer_sync(&wnd->iw_stats_timer); + EXIT2(return); +} + +static void hangcheck_proc(unsigned long data) +{ + struct ndis_device *wnd = (struct ndis_device *)data; + + ENTER3("%d", wnd->hangcheck_interval); + if (wnd->hangcheck_interval > 0) { + set_bit(HANGCHECK, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval); + EXIT3(return); +} + +void hangcheck_add(struct ndis_device *wnd) +{ + if (!wnd->wd->driver->ndis_driver->mp.hangcheck || + hangcheck_interval < 0) + EXIT2(return); + + if (hangcheck_interval > 0) + wnd->hangcheck_interval = hangcheck_interval * HZ; + if (wnd->hangcheck_interval < 0) + wnd->hangcheck_interval *= -1; + wnd->hangcheck_timer.data = (unsigned long)wnd; + wnd->hangcheck_timer.function = hangcheck_proc; + mod_timer(&wnd->hangcheck_timer, jiffies + wnd->hangcheck_interval); + EXIT2(return); +} + +void hangcheck_del(struct ndis_device *wnd) +{ + ENTER2("%d", wnd->hangcheck_interval); + if (wnd->hangcheck_interval > 0) + wnd->hangcheck_interval *= -1; + del_timer_sync(&wnd->hangcheck_timer); + EXIT2(return); +} + +/* worker procedure to take care of setting/checking various states */ +static void ndis_worker(worker_param_t param) +{ + struct ndis_device *wnd; + + wnd = worker_param_data(param, struct ndis_device, ndis_work); + WORKTRACE("0x%lx", wnd->ndis_pending_work); + + if (test_and_clear_bit(NETIF_WAKEQ, &wnd->ndis_pending_work)) { + netif_tx_lock_bh(wnd->net_dev); + netif_wake_queue(wnd->net_dev); + netif_tx_unlock_bh(wnd->net_dev); + } + + if (test_and_clear_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work)) + link_status_off(wnd); + + if (test_and_clear_bit(LINK_STATUS_ON, &wnd->ndis_pending_work)) + link_status_on(wnd); + + if (test_and_clear_bit(COLLECT_IW_STATS, &wnd->ndis_pending_work)) + update_iw_stats(wnd); + + if (test_and_clear_bit(SET_MULTICAST_LIST, + &wnd->ndis_pending_work)) + set_multicast_list(wnd); + + if (test_and_clear_bit(HANGCHECK, &wnd->ndis_pending_work)) { + struct miniport *mp; + BOOLEAN reset; + KIRQL irql; + + mp = &wnd->wd->driver->ndis_driver->mp; + irql = serialize_lock_irql(wnd); + reset = LIN2WIN1(mp->hangcheck, wnd->nmb->mp_ctx); + serialize_unlock_irql(wnd, irql); + if (reset) { + TRACE2("%s needs reset", wnd->net_dev->name); + mp_reset(wnd); + } + } + WORKEXIT(return); +} + +NDIS_STATUS ndis_reinit(struct ndis_device *wnd) +{ + NDIS_STATUS status; + + wnd->attributes &= ~NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; + status = mp_set_power_state(wnd, NdisDeviceStateD3); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("halting device %s failed: %08X", wnd->net_dev->name, + status); + return status; + } + status = mp_set_power_state(wnd, NdisDeviceStateD0); + if (status != NDIS_STATUS_SUCCESS) + ERROR("starting device %s failed: %08X", wnd->net_dev->name, + status); + return status; +} + +static void get_encryption_capa(struct ndis_device *wnd, char *buf, + const int buf_len) +{ + int i, mode; + NDIS_STATUS res; + struct ndis_assoc_info ndis_assoc_info; + struct ndis_add_key ndis_key; + struct ndis_capability *c; + + ENTER1("%p", wnd); + /* set network type to g, b, or a, in that order */ + res = mp_query(wnd, OID_802_11_NETWORK_TYPES_SUPPORTED, buf, buf_len); + if (res == NDIS_STATUS_SUCCESS) { + struct network_type_list *net_types; + unsigned long types = 0; + net_types = (typeof(net_types))buf; + for (i = 0; i < net_types->num; i++) { + TRACE2("%d", net_types->types[i]); + set_bit(net_types->types[i], &types); + } + if (types & Ndis802_11OFDM24) + mode = Ndis802_11OFDM24; + else if (types & Ndis802_11DS) + mode = Ndis802_11DS; + else if (types & Ndis802_11OFDM5) + mode = Ndis802_11OFDM5; + else + mode = Ndis802_11DS; + mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, mode); + } + /* check if WEP is supported */ + if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, + IW_AUTH_CIPHER_NONE) == 0 && + get_ndis_encr_mode(wnd) == Ndis802_11Encryption1KeyAbsent) + set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr); + + /* check if WPA is supported */ + if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPA) == 0 && + get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPA) + set_bit(Ndis802_11AuthModeWPA, &wnd->capa.encr); + else + EXIT1(return); + + if (set_ndis_auth_mode(wnd, Ndis802_11AuthModeWPAPSK) == 0 && + get_ndis_auth_mode(wnd) == Ndis802_11AuthModeWPAPSK) + set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.encr); + + /* check for highest encryption */ + mode = 0; + if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_CCMP, + IW_AUTH_CIPHER_NONE) == 0 && + (i = get_ndis_encr_mode(wnd)) > 0 && + (i == Ndis802_11Encryption3KeyAbsent || + i == Ndis802_11Encryption3Enabled)) + mode = Ndis802_11Encryption3Enabled; + else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_TKIP, + IW_AUTH_CIPHER_NONE) == 0 && + (i = get_ndis_encr_mode(wnd)) > 0 && + (i == Ndis802_11Encryption2KeyAbsent || + i == Ndis802_11Encryption2Enabled)) + mode = Ndis802_11Encryption2Enabled; + else if (set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, + IW_AUTH_CIPHER_NONE) == 0 && + (i = get_ndis_encr_mode(wnd)) > 0 && + (i == Ndis802_11Encryption1KeyAbsent || + i == Ndis802_11Encryption1Enabled)) + mode = Ndis802_11Encryption1Enabled; + + TRACE1("mode: %d", mode); + if (mode == 0) + EXIT1(return); + set_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr); + if (mode == Ndis802_11Encryption1Enabled) + EXIT1(return); + + ndis_key.length = 32; + ndis_key.index = 0xC0000001; + ndis_key.struct_size = sizeof(ndis_key); + res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size); + TRACE2("%08X, %lu", res, (unsigned long)sizeof(ndis_key)); + if (res && res != NDIS_STATUS_INVALID_DATA) + EXIT1(return); + res = mp_query(wnd, OID_802_11_ASSOCIATION_INFORMATION, + &ndis_assoc_info, sizeof(ndis_assoc_info)); + TRACE1("%08X", res); + if (res == NDIS_STATUS_NOT_SUPPORTED) + EXIT1(return); + + set_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr); + if (mode == Ndis802_11Encryption3Enabled) + set_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr); + /* not all drivers support OID_802_11_CAPABILITY, so we don't + * know for sure if driver support WPA or WPAPSK; assume + * WPAPSK */ + set_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth); + wnd->max_pmkids = 1; + + memset(buf, 0, buf_len); + c = (struct ndis_capability *)buf; + res = mp_query(wnd, OID_802_11_CAPABILITY, buf, buf_len); + if (!(res == NDIS_STATUS_SUCCESS && c->version == 2)) + EXIT1(return); + wnd->max_pmkids = c->num_PMKIDs; + + for (i = 0; i < c->num_auth_encr_pair; i++) { + struct ndis_auth_encr_pair *ae; + + ae = &c->auth_encr_pair[i]; + if ((char *)(ae + 1) > buf + buf_len) + break; + switch (ae->auth_mode) { + case Ndis802_11AuthModeOpen: + case Ndis802_11AuthModeShared: + case Ndis802_11AuthModeWPA: + case Ndis802_11AuthModeWPAPSK: + case Ndis802_11AuthModeWPANone: + case Ndis802_11AuthModeWPA2: + case Ndis802_11AuthModeWPA2PSK: + set_bit(ae->auth_mode, &wnd->capa.auth); + break; + default: + WARNING("unknown auth_mode: %d", ae->auth_mode); + break; + } + switch (ae->encr_mode) { + case Ndis802_11EncryptionDisabled: + case Ndis802_11Encryption1Enabled: + case Ndis802_11Encryption2Enabled: + case Ndis802_11Encryption3Enabled: + set_bit(ae->encr_mode, &wnd->capa.encr); + break; + default: + WARNING("unknown encr_mode: %d", ae->encr_mode); + break; + } + } + EXIT1(return); +} + +wstdcall NTSTATUS NdisDispatchDeviceControl(struct device_object *fdo, + struct irp *irp) +{ + struct ndis_device *wnd; + + TRACE3("fdo: %p", fdo); + /* for now, we don't have anything intresting here, so pass it + * down to bus driver */ + wnd = fdo->reserved; + return IoPassIrpDown(wnd->nmb->pdo, irp); +} +WIN_FUNC_DECL(NdisDispatchDeviceControl,2) + +wstdcall NTSTATUS NdisDispatchPower(struct device_object *fdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct ndis_device *wnd; + enum ndis_power_state state; + NTSTATUS status; + NDIS_STATUS ndis_status; + + irp_sl = IoGetCurrentIrpStackLocation(irp); + wnd = fdo->reserved; + IOTRACE("fdo: %p, fn: %d:%d, wnd: %p", fdo, irp_sl->major_fn, + irp_sl->minor_fn, wnd); + if ((irp_sl->params.power.type == SystemPowerState && + irp_sl->params.power.state.system_state > PowerSystemWorking) || + (irp_sl->params.power.type == DevicePowerState && + irp_sl->params.power.state.device_state > PowerDeviceD0)) + state = NdisDeviceStateD3; + else + state = NdisDeviceStateD0; + switch (irp_sl->minor_fn) { + case IRP_MN_SET_POWER: + if (state == NdisDeviceStateD0) { + status = IoSyncForwardIrp(wnd->nmb->pdo, irp); + if (status != STATUS_SUCCESS) + break; + ndis_status = mp_set_power_state(wnd, state); + if (ndis_status != NDIS_STATUS_SUCCESS) + WARNING("couldn't set power to %d: %08X", + state, ndis_status); + TRACE2("%s: device resumed", wnd->net_dev->name); + irp->io_status.status = status = STATUS_SUCCESS; + IoCompleteRequest(irp, IO_NO_INCREMENT); + break; + } else { + ndis_status = mp_set_power_state(wnd, state); + /* TODO: handle error case */ + if (ndis_status != NDIS_STATUS_SUCCESS) + WARNING("setting power to %d failed: %08X", + state, ndis_status); + status = IoAsyncForwardIrp(wnd->nmb->pdo, irp); + } + break; + case IRP_MN_QUERY_POWER: + if (wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND) { + ndis_status = mp_query(wnd, OID_PNP_QUERY_POWER, + &state, sizeof(state)); + TRACE2("%d, %08X", state, ndis_status); + /* this OID must always succeed */ + if (ndis_status != NDIS_STATUS_SUCCESS) + TRACE1("query power returns %08X", ndis_status); + irp->io_status.status = STATUS_SUCCESS; + } else + irp->io_status.status = STATUS_SUCCESS; + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + case IRP_MN_WAIT_WAKE: + case IRP_MN_POWER_SEQUENCE: + /* TODO: implement WAIT_WAKE */ + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + default: + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + } + IOEXIT(return status); +} +WIN_FUNC_DECL(NdisDispatchPower,2) + +wstdcall NTSTATUS NdisDispatchPnp(struct device_object *fdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct ndis_device *wnd; + struct device_object *pdo; + NTSTATUS status; + + IOTRACE("fdo: %p, irp: %p", fdo, irp); + irp_sl = IoGetCurrentIrpStackLocation(irp); + wnd = fdo->reserved; + pdo = wnd->nmb->pdo; + switch (irp_sl->minor_fn) { + case IRP_MN_START_DEVICE: + status = IoSyncForwardIrp(pdo, irp); + if (status != STATUS_SUCCESS) + break; + if (ndis_start_device(wnd) == NDIS_STATUS_SUCCESS) + status = STATUS_SUCCESS; + else + status = STATUS_FAILURE; + irp->io_status.status = status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + break; + case IRP_MN_QUERY_STOP_DEVICE: + /* TODO: implement in NDIS */ + status = IoPassIrpDown(wnd->nmb->pdo, irp); + break; + case IRP_MN_STOP_DEVICE: + mp_halt(wnd); + irp->io_status.status = STATUS_SUCCESS; + status = IoAsyncForwardIrp(pdo, irp); + break; + case IRP_MN_REMOVE_DEVICE: + TRACE1("%s", wnd->net_dev->name); + mp_pnp_event(wnd, NdisDevicePnPEventSurpriseRemoved, 0); + if (ndis_remove_device(wnd)) { + status = STATUS_FAILURE; + break; + } + /* wnd is already freed */ + status = IoAsyncForwardIrp(pdo, irp); + IoDetachDevice(fdo); + IoDeleteDevice(fdo); + break; + default: + status = IoAsyncForwardIrp(pdo, irp); + break; + } + IOTRACE("status: %08X", status); + IOEXIT(return status); +} +WIN_FUNC_DECL(NdisDispatchPnp,2) + +static void set_task_offload(struct ndis_device *wnd, void *buf, + const int buf_size) +{ + struct ndis_task_offload_header *task_offload_header; + struct ndis_task_offload *task_offload; + struct ndis_task_tcp_ip_checksum *csum = NULL; + struct ndis_task_tcp_large_send *tso = NULL; + NDIS_STATUS status; + + memset(buf, 0, buf_size); + task_offload_header = buf; + task_offload_header->version = NDIS_TASK_OFFLOAD_VERSION; + task_offload_header->size = sizeof(*task_offload_header); + task_offload_header->encap_format.flags.fixed_header_size = 1; + task_offload_header->encap_format.header_size = sizeof(struct ethhdr); + task_offload_header->encap_format.encap = IEEE_802_3_Encapsulation; + status = mp_query(wnd, OID_TCP_TASK_OFFLOAD, buf, buf_size); + TRACE1("%08X", status); + if (status != NDIS_STATUS_SUCCESS) + EXIT1(return); + if (task_offload_header->offset_first_task == 0) + EXIT1(return); + task_offload = ((void *)task_offload_header + + task_offload_header->offset_first_task); + while (1) { + TRACE1("%d, %d", task_offload->version, task_offload->task); + switch(task_offload->task) { + case TcpIpChecksumNdisTask: + csum = (void *)task_offload->task_buf; + break; + case TcpLargeSendNdisTask: + tso = (void *)task_offload->task_buf; + break; + default: + TRACE1("%d", task_offload->task); + break; + } + if (task_offload->offset_next_task == 0) + break; + task_offload = (void *)task_offload + + task_offload->offset_next_task; + } + if (tso) + TRACE1("%u, %u, %d, %d", tso->max_size, tso->min_seg_count, + tso->tcp_opts, tso->ip_opts); + if (!csum) + EXIT1(return); + TRACE1("%08x, %08x", csum->v4_tx.value, csum->v4_rx.value); + task_offload_header->encap_format.flags.fixed_header_size = 1; + task_offload_header->encap_format.header_size = sizeof(struct ethhdr); + task_offload_header->offset_first_task = sizeof(*task_offload_header); + task_offload = ((void *)task_offload_header + + task_offload_header->offset_first_task); + task_offload->offset_next_task = 0; + task_offload->size = sizeof(*task_offload); + task_offload->task = TcpIpChecksumNdisTask; + memcpy(task_offload->task_buf, csum, sizeof(*csum)); + task_offload->task_buf_length = sizeof(*csum); + status = mp_set(wnd, OID_TCP_TASK_OFFLOAD, task_offload_header, + sizeof(*task_offload_header) + + sizeof(*task_offload) + sizeof(*csum)); + TRACE1("%08X", status); + if (status != NDIS_STATUS_SUCCESS) + EXIT2(return); + wnd->tx_csum = csum->v4_tx; + if (csum->v4_tx.tcp_csum && csum->v4_tx.udp_csum) { + if (csum->v4_tx.ip_csum) { + wnd->net_dev->features |= NETIF_F_HW_CSUM; + TRACE1("hw checksum enabled"); + } else { + wnd->net_dev->features |= NETIF_F_IP_CSUM; + TRACE1("IP checksum enabled"); + } + if (wnd->sg_dma_size) + wnd->net_dev->features |= NETIF_F_SG; + } + wnd->rx_csum = csum->v4_rx; + EXIT1(return); +} + +static void get_supported_oids(struct ndis_device *wnd) +{ + NDIS_STATUS res; + int i, n, needed; + ndis_oid *oids; + + res = mp_query_info(wnd, OID_GEN_SUPPORTED_LIST, NULL, 0, NULL, + &needed); + if (!(res == NDIS_STATUS_BUFFER_TOO_SHORT || + res == NDIS_STATUS_INVALID_LENGTH)) + EXIT1(return); + oids = kmalloc(needed, GFP_KERNEL); + if (!oids) { + TRACE1("couldn't allocate memory"); + EXIT1(return); + } + res = mp_query(wnd, OID_GEN_SUPPORTED_LIST, oids, needed); + if (res) { + TRACE1("failed: %08X", res); + kfree(oids); + EXIT1(return); + } + for (i = 0, n = needed / sizeof(*oids); i < n; i++) { + TRACE1("oid: %08X", oids[i]); + /* if a wireless device didn't say so for + * OID_GEN_PHYSICAL_MEDIUM (they should, but in case) */ + if (wnd->physical_medium != NdisPhysicalMediumWirelessLan && + oids[i] == OID_802_11_SSID) + wnd->physical_medium = NdisPhysicalMediumWirelessLan; + } + kfree(oids); + EXIT1(return); +} + +static void ndis_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct ndis_device *wnd = netdev_priv(dev); + strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 2); + strcat(info->driver, "+"); + strncat(info->driver, wnd->wd->driver->name, + sizeof(info->driver) - strlen(DRIVER_NAME) - 1); + strncpy(info->version, DRIVER_VERSION, sizeof(info->version) - 2); + strcat(info->version, "+"); + strncat(info->version, wnd->wd->driver->version, + sizeof(info->version) - strlen(DRIVER_VERSION) - 1); + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + strncpy(info->bus_info, pci_name(wnd->wd->pci.pdev), + sizeof(info->bus_info) - 1); +#ifdef ENABLE_USB + else + usb_make_path(wnd->wd->usb.udev, info->bus_info, + sizeof(info->bus_info) - 1); +#endif + return; +} + +static u32 ndis_get_link(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + return netif_carrier_ok(wnd->net_dev); +} + +static void ndis_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct ndis_device *wnd = netdev_priv(dev); + + wol->supported = 0; + wol->wolopts = 0; + if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND)) + EXIT2(return); + if (!wrap_is_pci_bus(wnd->wd->dev_bus)) + EXIT2(return); + /* we always suspend to D3 */ + if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3) + return; + wol->supported |= WAKE_MAGIC; + if (wnd->ndis_wolopts & NDIS_PNP_WAKE_UP_MAGIC_PACKET) + wol->wolopts |= WAKE_MAGIC; + return; +} + +static int ndis_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (!(wnd->attributes & NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND)) + return -EOPNOTSUPP; + if (wnd->pnp_capa.wakeup.min_magic_packet_wakeup < NdisDeviceStateD3) + EXIT2(return -EOPNOTSUPP); + TRACE2("0x%x", wol->wolopts); + if (wol->wolopts & WAKE_MAGIC) { + wnd->ndis_wolopts |= NDIS_PNP_WAKE_UP_MAGIC_PACKET; + if (wol->wolopts != WAKE_MAGIC) + WARNING("ignored wake-on-lan options: 0x%x", + wol->wolopts & ~WAKE_MAGIC); + } else if (!wol->wolopts) + wnd->ndis_wolopts = 0; + else + return -EOPNOTSUPP; + TRACE2("0x%x", wnd->ndis_wolopts); + return 0; +} + +static u32 ndis_get_tx_csum(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->tx_csum.tcp_csum && wnd->tx_csum.udp_csum) + return 1; + else + return 0; +} + +static u32 ndis_get_rx_csum(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->rx_csum.value) + return 1; + else + return 0; +} + +static int ndis_set_tx_csum(struct net_device *dev, u32 data) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (data && (wnd->tx_csum.value == 0)) + return -EOPNOTSUPP; + + if (wnd->tx_csum.ip_csum) { + ethtool_op_set_tx_hw_csum(dev, data); + } else + ethtool_op_set_tx_csum(dev, data); + return 0; +} + +static int ndis_set_rx_csum(struct net_device *dev, u32 data) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (data && (wnd->tx_csum.value == 0)) + return -EOPNOTSUPP; + + /* TODO: enable/disable rx csum through NDIS */ + return 0; +} + +static u32 ndis_get_sg(struct net_device *dev) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->sg_dma_size) + return ethtool_op_get_sg(dev); + else + return 0; +} + +static int ndis_set_sg(struct net_device *dev, u32 data) +{ + struct ndis_device *wnd = netdev_priv(dev); + if (wnd->sg_dma_size) + return ethtool_op_set_sg(dev, data); + else + return -EOPNOTSUPP; +} + +static struct ethtool_ops ndis_ethtool_ops = { + .get_drvinfo = ndis_get_drvinfo, + .get_link = ndis_get_link, + .get_wol = ndis_get_wol, + .set_wol = ndis_set_wol, + .get_tx_csum = ndis_get_tx_csum, + .get_rx_csum = ndis_get_rx_csum, + .set_tx_csum = ndis_set_tx_csum, + .set_rx_csum = ndis_set_rx_csum, + .get_sg = ndis_get_sg, + .set_sg = ndis_set_sg, +}; + +static int notifier_event(struct notifier_block *notifier, unsigned long event, + void *ptr) +{ + struct net_device *net_dev = ptr; + + ENTER2("0x%lx", event); + if (net_dev->open == ndis_net_dev_open && event == NETDEV_CHANGENAME) { + struct ndis_device *wnd = netdev_priv(net_dev); + /* called with rtnl lock held, so no need to lock */ + wrap_procfs_remove_ndis_device(wnd); + printk(KERN_INFO "%s: changing interface name from '%s' to " + "'%s'\n", DRIVER_NAME, wnd->netdev_name, net_dev->name); + memcpy(wnd->netdev_name, net_dev->name, + sizeof(wnd->netdev_name)); + wrap_procfs_add_ndis_device(wnd); + } + return NOTIFY_DONE; +} + +static struct notifier_block netdev_notifier = { + .notifier_call = notifier_event, +}; + +static NDIS_STATUS ndis_start_device(struct ndis_device *wnd) +{ + struct wrap_device *wd; + struct net_device *net_dev; + NDIS_STATUS status; + char *buf; + const int buf_len = 256; + mac_address mac; + struct transport_header_offset *tx_header_offset; + int n; + + ENTER2("%d", in_atomic()); + status = mp_init(wnd); + if (status == NDIS_STATUS_NOT_RECOGNIZED) + EXIT1(return NDIS_STATUS_SUCCESS); + if (status != NDIS_STATUS_SUCCESS) + EXIT1(return status); + wd = wnd->wd; + net_dev = wnd->net_dev; + + get_supported_oids(wnd); + memset(mac, 0, sizeof(mac)); + status = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac)); + if (memcmp(mac, "\x00\x00\x00\x00\x00\x00", sizeof(mac)) == 0) { + status = mp_query(wnd, OID_802_3_PERMANENT_ADDRESS, mac, + sizeof(mac)); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("couldn't get mac address: %08X", status); + goto err_start; + } + } + TRACE1("mac:" MACSTRSEP, MAC2STR(mac)); + memcpy(net_dev->dev_addr, mac, ETH_ALEN); + + strncpy(net_dev->name, if_name, IFNAMSIZ - 1); + net_dev->name[IFNAMSIZ - 1] = 0; + + wnd->packet_filter = NDIS_PACKET_TYPE_DIRECTED | + NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_MULTICAST; + net_dev->open = ndis_net_dev_open; + net_dev->hard_start_xmit = tx_skbuff; + net_dev->stop = ndis_net_dev_close; + net_dev->get_stats = ndis_get_stats; + net_dev->change_mtu = ndis_change_mtu; + net_dev->do_ioctl = NULL; + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + net_dev->wireless_handlers = &ndis_handler_def; + } + net_dev->set_multicast_list = ndis_set_multicast_list; + net_dev->set_mac_address = ndis_set_mac_address; + net_dev->ethtool_ops = &ndis_ethtool_ops; + if (wnd->mp_interrupt) + net_dev->irq = wnd->mp_interrupt->irq; + net_dev->mem_start = wnd->mem_start; + net_dev->mem_end = wnd->mem_end; + status = mp_query_int(wnd, OID_802_3_MAXIMUM_LIST_SIZE, + &wnd->multicast_size); + if (status != NDIS_STATUS_SUCCESS || wnd->multicast_size < 0) + wnd->multicast_size = 0; + if (wnd->multicast_size > 0) + net_dev->flags |= IFF_MULTICAST; + else + net_dev->flags &= ~IFF_MULTICAST; +#ifdef CONFIG_NET_POLL_CONTROLLER + net_dev->poll_controller = ndis_poll_controller; +#endif + + buf = kmalloc(buf_len, GFP_KERNEL); + if (!buf) { + WARNING("couldn't allocate memory"); + goto err_start; + } + + set_task_offload(wnd, buf, buf_len); +#ifdef NETIF_F_LLTX + net_dev->features |= NETIF_F_LLTX; +#endif + + if (register_netdev(net_dev)) { + ERROR("cannot register net device %s", net_dev->name); + goto err_register; + } + memcpy(wnd->netdev_name, net_dev->name, sizeof(wnd->netdev_name)); + memset(buf, 0, buf_len); + status = mp_query(wnd, OID_GEN_VENDOR_DESCRIPTION, buf, buf_len); + if (status != NDIS_STATUS_SUCCESS) { + WARNING("couldn't get vendor information: 0x%x", status); + buf[0] = 0; + } + wnd->drv_ndis_version = n = 0; + mp_query_int(wnd, OID_GEN_DRIVER_VERSION, &wnd->drv_ndis_version); + mp_query_int(wnd, OID_GEN_VENDOR_DRIVER_VERSION, &n); + + printk(KERN_INFO "%s: ethernet device " MACSTRSEP " using %sNDIS " + "driver: %s, version: 0x%x, NDIS version: 0x%x, vendor: '%s', " + "%s\n", net_dev->name, MAC2STR(net_dev->dev_addr), + deserialized_driver(wnd) ? "" : "serialized ", + wnd->wd->driver->name, n, wnd->drv_ndis_version, buf, + wnd->wd->conf_file_name); + + if (deserialized_driver(wnd)) { + /* deserialized drivers don't have a limit, but we + * keep max at TX_RING_SIZE */ + wnd->max_tx_packets = TX_RING_SIZE; + } else { + status = mp_query_int(wnd, OID_GEN_MAXIMUM_SEND_PACKETS, + &wnd->max_tx_packets); + if (status != NDIS_STATUS_SUCCESS) + wnd->max_tx_packets = 1; + if (wnd->max_tx_packets > TX_RING_SIZE) + wnd->max_tx_packets = TX_RING_SIZE; + } + TRACE2("maximum send packets: %d", wnd->max_tx_packets); + NdisAllocatePacketPoolEx(&status, &wnd->tx_packet_pool, + wnd->max_tx_packets, 0, + PROTOCOL_RESERVED_SIZE_IN_PACKET); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("couldn't allocate packet pool"); + goto packet_pool_err; + } + NdisAllocateBufferPool(&status, &wnd->tx_buffer_pool, + wnd->max_tx_packets + 4); + if (status != NDIS_STATUS_SUCCESS) { + ERROR("couldn't allocate buffer pool"); + goto buffer_pool_err; + } + TRACE1("pool: %p", wnd->tx_buffer_pool); + + if (mp_query_int(wnd, OID_GEN_MAXIMUM_TOTAL_SIZE, &n) == + NDIS_STATUS_SUCCESS && n > ETH_HLEN) + ndis_change_mtu(wnd->net_dev, n - ETH_HLEN); + + if (mp_query_int(wnd, OID_GEN_MAC_OPTIONS, &n) == NDIS_STATUS_SUCCESS) + TRACE2("mac options supported: 0x%x", n); + + tx_header_offset = (typeof(tx_header_offset))buf; + tx_header_offset->protocol_type = NDIS_PROTOCOL_ID_TCP_IP; + tx_header_offset->header_offset = sizeof(ETH_HLEN); + status = mp_set(wnd, OID_GEN_TRANSPORT_HEADER_OFFSET, + tx_header_offset, sizeof(*tx_header_offset)); + TRACE2("%08X", status); + + status = mp_query_int(wnd, OID_GEN_PHYSICAL_MEDIUM, + &wnd->physical_medium); + if (status != NDIS_STATUS_SUCCESS) + wnd->physical_medium = NdisPhysicalMediumUnspecified; + + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + mp_set_int(wnd, OID_802_11_POWER_MODE, NDIS_POWER_OFF); + get_encryption_capa(wnd, buf, buf_len); + TRACE1("capbilities = %ld", wnd->capa.encr); + printk(KERN_INFO "%s: encryption modes supported: " + "%s%s%s%s%s%s%s\n", net_dev->name, + test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ? + "WEP" : "none", + + test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr) ? + "; TKIP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : "", + + test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr) ? + "; AES/CCMP with WPA" : "", + test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) ? + ", WPA2" : "", + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth) ? + ", WPA2PSK" : ""); + + set_default_iw_params(wnd); + } + kfree(buf); + wrap_procfs_add_ndis_device(wnd); + hangcheck_add(wnd); + add_iw_stats_timer(wnd); + EXIT1(return NDIS_STATUS_SUCCESS); + +buffer_pool_err: + wnd->tx_buffer_pool = NULL; + if (wnd->tx_packet_pool) { + NdisFreePacketPool(wnd->tx_packet_pool); + wnd->tx_packet_pool = NULL; + } +packet_pool_err: +err_register: + kfree(buf); +err_start: + ndis_remove_device(wnd); + EXIT1(return NDIS_STATUS_FAILURE); +} + +static int ndis_remove_device(struct ndis_device *wnd) +{ + s8 tx_pending; + + /* prevent setting essid during disassociation */ + memset(&wnd->essid, 0, sizeof(wnd->essid)); + wnd->tx_ok = 0; + if (wnd->max_tx_packets) + unregister_netdev(wnd->net_dev); + netif_carrier_off(wnd->net_dev); + /* if device is suspended, but resume failed, tx_ring_mutex + * may already be locked */ + if (down_trylock(&wnd->tx_ring_mutex)) + WARNING("couldn't obtain tx_ring_mutex"); + spin_lock_bh(&wnd->tx_ring_lock); + tx_pending = wnd->tx_ring_end - wnd->tx_ring_start; + if (tx_pending < 0) + tx_pending += TX_RING_SIZE; + else if (tx_pending == 0 && wnd->is_tx_ring_full) + tx_pending = TX_RING_SIZE - 1; + wnd->is_tx_ring_full = 0; + /* throw away pending packets */ + while (tx_pending-- > 0) { + struct ndis_packet *packet; + + packet = wnd->tx_ring[wnd->tx_ring_start]; + free_tx_packet(wnd, packet, NDIS_STATUS_CLOSING); + wnd->tx_ring_start = (wnd->tx_ring_start + 1) % TX_RING_SIZE; + } + spin_unlock_bh(&wnd->tx_ring_lock); + up(&wnd->tx_ring_mutex); + wrap_procfs_remove_ndis_device(wnd); + mp_halt(wnd); + ndis_exit_device(wnd); + + if (wnd->tx_packet_pool) { + NdisFreePacketPool(wnd->tx_packet_pool); + wnd->tx_packet_pool = NULL; + } + if (wnd->tx_buffer_pool) { + NdisFreeBufferPool(wnd->tx_buffer_pool); + wnd->tx_buffer_pool = NULL; + } + if (wnd->pmkids) + kfree(wnd->pmkids); + printk(KERN_INFO "%s: device %s removed\n", DRIVER_NAME, + wnd->net_dev->name); + kfree(wnd->nmb); + free_netdev(wnd->net_dev); + EXIT2(return 0); +} + +static wstdcall NTSTATUS NdisAddDevice(struct driver_object *drv_obj, + struct device_object *pdo) +{ + struct device_object *fdo; + struct ndis_mp_block *nmb; + NTSTATUS status; + struct ndis_device *wnd; + struct net_device *net_dev; + struct wrap_device *wd; + unsigned long i; + + ENTER2("%p, %p", drv_obj, pdo); + if (strlen(if_name) >= IFNAMSIZ) { + ERROR("interface name '%s' is too long", if_name); + return STATUS_INVALID_PARAMETER; + } + net_dev = alloc_etherdev(sizeof(*wnd)); + if (!net_dev) { + ERROR("couldn't allocate device"); + return STATUS_RESOURCES; + } + wd = pdo->reserved; + if (wrap_is_pci_bus(wd->dev_bus)) + SET_NETDEV_DEV(net_dev, &wd->pci.pdev->dev); + if (wrap_is_usb_bus(wd->dev_bus)) + SET_NETDEV_DEV(net_dev, &wd->usb.intf->dev); + status = IoCreateDevice(drv_obj, 0, NULL, FILE_DEVICE_UNKNOWN, 0, + FALSE, &fdo); + if (status != STATUS_SUCCESS) { + free_netdev(net_dev); + EXIT2(return status); + } + wnd = netdev_priv(net_dev); + TRACE1("wnd: %p", wnd); + + nmb = kmalloc(sizeof(*nmb), GFP_KERNEL); + if (!nmb) { + WARNING("couldn't allocate memory"); + IoDeleteDevice(fdo); + free_netdev(net_dev); + return STATUS_RESOURCES; + } +#if defined(DEBUG) && DEBUG >= 6 + /* poison nmb so if a driver accesses uninitialized pointers, we + * know what it is */ + for (i = 0; i < sizeof(*nmb) / sizeof(unsigned long); i++) + ((unsigned long *)nmb)[i] = i + 0x8a3fc1; +#endif + + wnd->nmb = nmb; + nmb->wnd = wnd; + nmb->pdo = pdo; + wd->wnd = wnd; + wnd->wd = wd; + wnd->net_dev = net_dev; + fdo->reserved = wnd; + nmb->fdo = fdo; + if (ndis_init_device(wnd)) { + IoDeleteDevice(fdo); + kfree(nmb); + free_netdev(net_dev); + EXIT1(return STATUS_RESOURCES); + } + nmb->next_device = IoAttachDeviceToDeviceStack(fdo, pdo); + spin_lock_init(&wnd->tx_ring_lock); + init_MUTEX(&wnd->tx_ring_mutex); + init_MUTEX(&wnd->ndis_req_mutex); + wnd->ndis_req_done = 0; + initialize_work(&wnd->tx_work, tx_worker, wnd); + wnd->tx_ring_start = 0; + wnd->tx_ring_end = 0; + wnd->is_tx_ring_full = 0; + wnd->capa.encr = 0; + wnd->capa.auth = 0; + wnd->attributes = 0; + wnd->dma_map_count = 0; + wnd->dma_map_addr = NULL; + wnd->nick[0] = 0; + init_timer(&wnd->hangcheck_timer); + wnd->scan_timestamp = 0; + init_timer(&wnd->iw_stats_timer); + wnd->iw_stats_interval = 10 * HZ; + wnd->ndis_pending_work = 0; + memset(&wnd->essid, 0, sizeof(wnd->essid)); + memset(&wnd->encr_info, 0, sizeof(wnd->encr_info)); + wnd->infrastructure_mode = Ndis802_11Infrastructure; + initialize_work(&wnd->ndis_work, ndis_worker, wnd); + wnd->iw_stats_enabled = TRUE; + + TRACE1("nmb: %p, pdo: %p, fdo: %p, attached: %p, next: %p", + nmb, pdo, fdo, fdo->attached, nmb->next_device); + + /* dispatch routines are called as Windows functions */ + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + drv_obj->major_func[i] = WIN_FUNC_PTR(IoPassIrpDown,2); + + drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(NdisDispatchPnp,2); + drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(NdisDispatchPower,2); + drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] = + WIN_FUNC_PTR(NdisDispatchDeviceControl,2); +// drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] = +// WIN_FUNC_PTR(NdisDispatchDeviceControl,2); + EXIT2(return STATUS_SUCCESS); +} + +int init_ndis_driver(struct driver_object *drv_obj) +{ + ENTER1("%p", drv_obj); + drv_obj->drv_ext->add_device = NdisAddDevice; + return 0; +} + +int wrapndis_init(void) +{ + wrapndis_wq = create_singlethread_workqueue("wrapndis_wq"); + if (!wrapndis_wq) + EXIT1(return -ENOMEM); + wrapndis_worker_thread = wrap_worker_init(wrapndis_wq); + TRACE1("%p", wrapndis_worker_thread); + register_netdevice_notifier(&netdev_notifier); + return 0; +} + +void wrapndis_exit(void) +{ + unregister_netdevice_notifier(&netdev_notifier); + if (wrapndis_wq) + destroy_workqueue(wrapndis_wq); + TRACE1("%p", wrapndis_worker_thread); + if (wrapndis_worker_thread) + ObDereferenceObject(wrapndis_worker_thread); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapmem.c +++ linux-2.6.28/ubuntu/ndiswrapper/wrapmem.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2006 Giridhar Pemmasani + * + * 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. + * + */ + +#define _WRAPMEM_C_ + +#include "ntoskernel.h" + +struct slack_alloc_info { + struct nt_list list; + size_t size; +}; + +static struct nt_list allocs; +static struct nt_list slack_allocs; +static spinlock_t alloc_lock; + +struct vmem_block { + struct nt_list list; + int size; +}; + +static struct nt_list vmem_list; + +#if defined(ALLOC_DEBUG) +struct alloc_info { + enum alloc_type type; + size_t size; +#if ALLOC_DEBUG > 1 + struct nt_list list; + const char *file; + int line; + ULONG tag; +#endif +}; + +static atomic_t alloc_sizes[ALLOC_TYPE_MAX]; +#endif + +void wrapmem_info(void) +{ +#ifdef ALLOC_DEBUG + enum alloc_type type; + for (type = 0; type < ALLOC_TYPE_MAX; type++) + INFO("total size of allocations in %d: %d", + type, atomic_read(&alloc_sizes[type])); +#endif +} + +/* allocate memory and add it to list of allocated pointers; if a + * driver doesn't free this memory for any reason (buggy driver or we + * allocate space behind driver's back since we need more space than + * corresponding Windows structure provides etc.), this gets freed + * automatically when module is unloaded + */ +void *slack_kmalloc(size_t size) +{ + struct slack_alloc_info *info; + gfp_t flags; + + ENTER4("size = %lu", (unsigned long)size); + + if (irql_gfp() & GFP_ATOMIC) + flags = GFP_ATOMIC; + else + flags = GFP_KERNEL; + info = kmalloc(size + sizeof(*info), flags); + if (!info) + return NULL; + info->size = size; + spin_lock_bh(&alloc_lock); + InsertTailList(&slack_allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#ifdef ALLOC_DEBUG + atomic_add(size, &alloc_sizes[ALLOC_TYPE_SLACK]); +#endif + TRACE4("%p, %p", info, info + 1); + EXIT4(return info + 1); +} + +/* free pointer and remove from list of allocated pointers */ +void slack_kfree(void *ptr) +{ + struct slack_alloc_info *info; + + ENTER4("%p", ptr); + info = ptr - sizeof(*info); + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); +#ifdef ALLOC_DEBUG + atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); +#endif + kfree(info); + EXIT4(return); +} + +#if defined(ALLOC_DEBUG) +void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line) +{ + struct alloc_info *info; + + info = kmalloc(size + sizeof(*info), flags); + if (!info) + return NULL; + if (flags & GFP_ATOMIC) + info->type = ALLOC_TYPE_KMALLOC_ATOMIC; + else + info->type = ALLOC_TYPE_KMALLOC_NON_ATOMIC; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + TRACE4("%p", info + 1); + return (info + 1); +} + +void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line) +{ + void *ptr = wrap_kmalloc(size, flags, file, line); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +void wrap_kfree(void *ptr) +{ + struct alloc_info *info; + + TRACE4("%p", ptr); + if (!ptr) + return; + info = ptr - sizeof(*info); + atomic_sub(info->size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); + if (!(info->type == ALLOC_TYPE_KMALLOC_ATOMIC || + info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC)) + WARNING("invliad type: %d", info->type); +#endif + kfree(info); +} + +void *wrap_vmalloc(unsigned long size, const char *file, int line) +{ + struct alloc_info *info; + + info = vmalloc(size + sizeof(*info)); + if (!info) + return NULL; + info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + return (info + 1); +} + +void *wrap__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot, + const char *file, int line) +{ + struct alloc_info *info; + + info = __vmalloc(size + sizeof(*info), gfp_mask, prot); + if (!info) + return NULL; + if (gfp_mask & GFP_ATOMIC) + info->type = ALLOC_TYPE_VMALLOC_ATOMIC; + else + info->type = ALLOC_TYPE_VMALLOC_NON_ATOMIC; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + return (info + 1); +} + +void wrap_vfree(void *ptr) +{ + struct alloc_info *info; + + info = ptr - sizeof(*info); + atomic_sub(info->size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); + if (!(info->type == ALLOC_TYPE_VMALLOC_ATOMIC || + info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC)) + WARNING("invliad type: %d", info->type); +#endif + vfree(info); +} + +void *wrap_alloc_pages(gfp_t flags, unsigned int size, + const char *file, int line) +{ + struct alloc_info *info; + + size += sizeof(*info); + info = (struct alloc_info *)__get_free_pages(flags, get_order(size)); + if (!info) + return NULL; + info->type = ALLOC_TYPE_PAGES; + info->size = size; + atomic_add(size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + info->file = file; + info->line = line; + info->tag = 0; + spin_lock_bh(&alloc_lock); + InsertTailList(&allocs, &info->list); + spin_unlock_bh(&alloc_lock); +#endif + return info + 1; +} + +void wrap_free_pages(unsigned long ptr, int order) +{ + struct alloc_info *info; + + info = (void *)ptr - sizeof(*info); + atomic_sub(info->size, &alloc_sizes[info->type]); +#if ALLOC_DEBUG > 1 + spin_lock_bh(&alloc_lock); + RemoveEntryList(&info->list); + spin_unlock_bh(&alloc_lock); + if (info->type != ALLOC_TYPE_PAGES) + WARNING("invliad type: %d", info->type); +#endif + free_pages((unsigned long)info, get_order(info->size)); +} + +#if ALLOC_DEBUG > 1 +#undef ExAllocatePoolWithTag +void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, + ULONG tag, const char *file, int line) +{ + void *addr; + struct alloc_info *info; + + ENTER4("pool_type: %d, size: %lu, tag: %u", pool_type, size, tag); + addr = ExAllocatePoolWithTag(pool_type, size, tag); + if (!addr) + return NULL; + info = addr - sizeof(*info); + info->file = file; + info->line = line; + info->tag = tag; + EXIT4(return addr); +} +#endif + +int alloc_size(enum alloc_type type) +{ + if (type >= 0 && type < ALLOC_TYPE_MAX) + return atomic_read(&alloc_sizes[type]); + else + return -EINVAL; +} + +#endif // ALLOC_DEBUG + +int wrapmem_init(void) +{ + InitializeListHead(&allocs); + InitializeListHead(&slack_allocs); + InitializeListHead(&vmem_list); + spin_lock_init(&alloc_lock); + return 0; +} + +void wrapmem_exit(void) +{ + enum alloc_type type; + struct nt_list *ent; + + /* free all pointers on the slack list */ + while (1) { + struct slack_alloc_info *info; + spin_lock_bh(&alloc_lock); + ent = RemoveHeadList(&slack_allocs); + spin_unlock_bh(&alloc_lock); + if (!ent) + break; + info = container_of(ent, struct slack_alloc_info, list); +#ifdef ALLOC_DEBUG + atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); +#endif + kfree(info); + } + type = 0; +#ifdef ALLOC_DEBUG + for (type = 0; type < ALLOC_TYPE_MAX; type++) { + int n = atomic_read(&alloc_sizes[type]); + if (n) + WARNING("%d bytes of memory in %d leaking", n, type); + } + +#if ALLOC_DEBUG > 1 + while (1) { + struct alloc_info *info; + + spin_lock_bh(&alloc_lock); + ent = RemoveHeadList(&allocs); + spin_unlock_bh(&alloc_lock); + if (!ent) + break; + info = container_of(ent, struct alloc_info, list); + atomic_sub(info->size, &alloc_sizes[ALLOC_TYPE_SLACK]); + WARNING("%p in %d of size %zu allocated at %s(%d) " + "with tag 0x%08X leaking; freeing it now", + info + 1, info->type, info->size, info->file, + info->line, info->tag); + if (info->type == ALLOC_TYPE_KMALLOC_ATOMIC || + info->type == ALLOC_TYPE_KMALLOC_NON_ATOMIC) + kfree(info); + else if (info->type == ALLOC_TYPE_VMALLOC_ATOMIC || + info->type == ALLOC_TYPE_VMALLOC_NON_ATOMIC) + vfree(info); + else if (info->type == ALLOC_TYPE_PAGES) + free_pages((unsigned long)info, get_order(info->size)); + else + WARNING("invalid type: %d; not freed", info->type); + } +#endif +#endif + return; +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/pe_linker.c +++ linux-2.6.28/ubuntu/ndiswrapper/pe_linker.c @@ -0,0 +1,609 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifdef TEST_LOADER + +#include "usr_linker.h" + +#else + +#include +#include + +//#define DEBUGLINKER 2 + +#include "ntoskernel.h" + +#endif + +struct pe_exports { + char *dll; + char *name; + generic_func addr; +}; + +static struct pe_exports pe_exports[40]; +static int num_pe_exports; + +#define RVA2VA(image, rva, type) (type)(ULONG_PTR)((void *)image + rva) +#define CHECK_SZ(a,b) { if (sizeof(a) != b) { \ + ERROR("%s is bad, got %zd, expected %d", \ + #a , sizeof(a), (b)); return -EINVAL; } } + +#if defined(DEBUGLINKER) && DEBUGLINKER > 0 +#define DBGLINKER(fmt, ...) printk(KERN_INFO "%s (%s:%d): " fmt "\n", \ + DRIVER_NAME, __FUNCTION__, \ + __LINE__ , ## __VA_ARGS__); +static const char *image_directory_name[] = { + "EXPORT", + "IMPORT", + "RESOURCE", + "EXCEPTION", + "SECURITY", + "BASERELOC", + "DEBUG", + "COPYRIGHT", + "GLOBALPTR", + "TLS", + "LOAD_CONFIG", + "BOUND_IMPORT", + "IAT", + "DELAY_IMPORT", + "COM_DESCRIPTOR" }; +#else +#define DBGLINKER(fmt, ...) do { } while (0) +#endif + +#ifndef TEST_LOADER +extern struct wrap_export ntoskernel_exports[], ntoskernel_io_exports[], + ndis_exports[], crt_exports[], hal_exports[], rtl_exports[]; +#ifdef ENABLE_USB +extern struct wrap_export usb_exports[]; +#endif + +static char *get_export(char *name) +{ + int i; + + for (i = 0 ; ntoskernel_exports[i].name != NULL; i++) + if (strcmp(ntoskernel_exports[i].name, name) == 0) + return (char *)ntoskernel_exports[i].func; + + for (i = 0 ; ntoskernel_io_exports[i].name != NULL; i++) + if (strcmp(ntoskernel_io_exports[i].name, name) == 0) + return (char *)ntoskernel_io_exports[i].func; + + for (i = 0 ; ndis_exports[i].name != NULL; i++) + if (strcmp(ndis_exports[i].name, name) == 0) + return (char *)ndis_exports[i].func; + + for (i = 0 ; crt_exports[i].name != NULL; i++) + if (strcmp(crt_exports[i].name, name) == 0) + return (char *)crt_exports[i].func; + + for (i = 0 ; hal_exports[i].name != NULL; i++) + if (strcmp(hal_exports[i].name, name) == 0) + return (char *)hal_exports[i].func; + + for (i = 0 ; rtl_exports[i].name != NULL; i++) + if (strcmp(rtl_exports[i].name, name) == 0) + return (char *)rtl_exports[i].func; + +#ifdef ENABLE_USB + for (i = 0 ; usb_exports[i].name != NULL; i++) + if (strcmp(usb_exports[i].name, name) == 0) + return (char *)usb_exports[i].func; +#endif + + for (i = 0; i < num_pe_exports; i++) + if (strcmp(pe_exports[i].name, name) == 0) + return (char *)pe_exports[i].addr; + + return NULL; +} +#endif // TEST_LOADER + +static void *get_dll_init(char *name) +{ + int i; + for (i = 0; i < num_pe_exports; i++) + if ((strcmp(pe_exports[i].dll, name) == 0) && + (strcmp(pe_exports[i].name, "DllInitialize") == 0)) + return (void *)pe_exports[i].addr; + return NULL; +} + +/* + * Find and validate the coff header + * + */ +static int check_nt_hdr(IMAGE_NT_HEADERS *nt_hdr) +{ + int i; + WORD attr; + PIMAGE_OPTIONAL_HEADER opt_hdr; + + /* Validate the "PE\0\0" signature */ + if (nt_hdr->Signature != IMAGE_NT_SIGNATURE) { + ERROR("is this driver file? bad signature %08x", + nt_hdr->Signature); + return -EINVAL; + } + + opt_hdr = &nt_hdr->OptionalHeader; + /* Make sure Image is PE32 or PE32+ */ +#ifdef CONFIG_X86_64 + if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC) { + ERROR("kernel is 64-bit, but Windows driver is not 64-bit;" + "bad magic: %04X", opt_hdr->Magic); + return -EINVAL; + } +#else + if (opt_hdr->Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" + "bad magic: %04X", opt_hdr->Magic); + return -EINVAL; + } +#endif + + /* Validate the image for the current architecture. */ +#ifdef CONFIG_X86_64 + if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64) { + ERROR("kernel is 64-bit, but Windows driver is not 64-bit;" + " (PE signature is %04X)", nt_hdr->FileHeader.Machine); + return -EINVAL; + } +#else + if (nt_hdr->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) { + ERROR("kernel is 32-bit, but Windows driver is not 32-bit;" + " (PE signature is %04X)", nt_hdr->FileHeader.Machine); + return -EINVAL; + } +#endif + + /* Must have attributes */ +#ifdef CONFIG_X86_64 + attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LARGE_ADDRESS_AWARE; +#else + attr = IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_32BIT_MACHINE; +#endif + if ((nt_hdr->FileHeader.Characteristics & attr) != attr) + return -EINVAL; + + /* Must be relocatable */ + attr = IMAGE_FILE_RELOCS_STRIPPED; + if ((nt_hdr->FileHeader.Characteristics & attr)) + return -EINVAL; + + /* Make sure we have at least one section */ + if (nt_hdr->FileHeader.NumberOfSections == 0) + return -EINVAL; + + if (opt_hdr->SectionAlignment < opt_hdr->FileAlignment) { + ERROR("alignment mismatch: secion: 0x%x, file: 0x%x", + opt_hdr->SectionAlignment, opt_hdr->FileAlignment); + return -EINVAL; + } + + DBGLINKER("number of datadictionary entries %d", + opt_hdr->NumberOfRvaAndSizes); + for (i = 0; i < opt_hdr->NumberOfRvaAndSizes; i++) { + DBGLINKER("datadirectory %s RVA:%X Size:%d", + (i<=IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR)? + image_directory_name[i] : "unknown", + opt_hdr->DataDirectory[i].VirtualAddress, + opt_hdr->DataDirectory[i].Size); + } + + if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_DLL)) + return IMAGE_FILE_DLL; + if ((nt_hdr->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) + return IMAGE_FILE_EXECUTABLE_IMAGE; + return -EINVAL; +} + +static int import(void *image, IMAGE_IMPORT_DESCRIPTOR *dirent, char *dll) +{ + ULONG_PTR *lookup_tbl, *address_tbl; + char *symname = NULL; + int i; + int ret = 0; + void *adr; + + lookup_tbl = RVA2VA(image, dirent->u.OriginalFirstThunk, ULONG_PTR *); + address_tbl = RVA2VA(image, dirent->FirstThunk, ULONG_PTR *); + + for (i = 0; lookup_tbl[i]; i++) { + if (IMAGE_SNAP_BY_ORDINAL(lookup_tbl[i])) { + ERROR("ordinal import not supported: %Lu", + (uint64_t)lookup_tbl[i]); + return -1; + } + else { + symname = RVA2VA(image, + ((lookup_tbl[i] & + ~IMAGE_ORDINAL_FLAG) + 2), char *); + } + + adr = get_export(symname); + if (adr == NULL) { + ERROR("unknown symbol: %s:'%s'", dll, symname); + ret = -1; + } else { + DBGLINKER("found symbol: %s:%s: addr: %p, rva = %Lu", + dll, symname, adr, (uint64_t)address_tbl[i]); + address_tbl[i] = (ULONG_PTR)adr; + } + } + return ret; +} + +static int read_exports(struct pe_image *pe) +{ + IMAGE_EXPORT_DIRECTORY *export_dir_table; + uint32_t *export_addr_table; + int i; + uint32_t *name_table; + PIMAGE_OPTIONAL_HEADER opt_hdr; + IMAGE_DATA_DIRECTORY *export_data_dir; + + opt_hdr = &pe->nt_hdr->OptionalHeader; + export_data_dir = + &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]; + + if (export_data_dir->Size == 0) { + DBGLINKER("no exports"); + return 0; + } + + export_dir_table = + RVA2VA(pe->image, export_data_dir->VirtualAddress, + IMAGE_EXPORT_DIRECTORY *); + + name_table = (unsigned int *)(pe->image + + export_dir_table->AddressOfNames); + export_addr_table = (uint32_t *) + (pe->image + export_dir_table->AddressOfFunctions); + + for (i = 0; i < export_dir_table->NumberOfNames; i++) { + + if (export_data_dir->VirtualAddress <= *export_addr_table || + *export_addr_table >= (export_data_dir->VirtualAddress + + export_data_dir->Size)) + DBGLINKER("forwarder rva"); + + DBGLINKER("export symbol: %s, at %p", + (char *)(pe->image + *name_table), + pe->image + *export_addr_table); + + pe_exports[num_pe_exports].dll = pe->name; + pe_exports[num_pe_exports].name = pe->image + *name_table; + pe_exports[num_pe_exports].addr = + pe->image + *export_addr_table; + + num_pe_exports++; + name_table++; + export_addr_table++; + } + return 0; +} + +static int fixup_imports(void *image, IMAGE_NT_HEADERS *nt_hdr) +{ + int i; + char *name; + int ret = 0; + IMAGE_IMPORT_DESCRIPTOR *dirent; + IMAGE_DATA_DIRECTORY *import_data_dir; + PIMAGE_OPTIONAL_HEADER opt_hdr; + + opt_hdr = &nt_hdr->OptionalHeader; + import_data_dir = + &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; + dirent = RVA2VA(image, import_data_dir->VirtualAddress, + IMAGE_IMPORT_DESCRIPTOR *); + + for (i = 0; dirent[i].Name; i++) { + name = RVA2VA(image, dirent[i].Name, char*); + + DBGLINKER("imports from dll: %s", name); + ret += import(image, &dirent[i], name); + } + return ret; +} + +static int fixup_reloc(void *image, IMAGE_NT_HEADERS *nt_hdr) +{ + ULONG_PTR base; + ULONG_PTR size; + IMAGE_BASE_RELOCATION *fixup_block; + IMAGE_DATA_DIRECTORY *base_reloc_data_dir; + PIMAGE_OPTIONAL_HEADER opt_hdr; + + opt_hdr = &nt_hdr->OptionalHeader; + base = opt_hdr->ImageBase; + base_reloc_data_dir = + &opt_hdr->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC]; + if (base_reloc_data_dir->Size == 0) + return 0; + + fixup_block = RVA2VA(image, base_reloc_data_dir->VirtualAddress, + IMAGE_BASE_RELOCATION *); + DBGLINKER("fixup_block=%p, image=%p", fixup_block, image); + DBGLINKER("fixup_block info: %x %d", + fixup_block->VirtualAddress, fixup_block->SizeOfBlock); + + while (fixup_block->SizeOfBlock) { + int i; + WORD fixup, offset; + + size = (fixup_block->SizeOfBlock - + sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD); + DBGLINKER("found %Lu relocations in this block", + (uint64_t)size); + + for (i = 0; i < size; i++) { + fixup = fixup_block->TypeOffset[i]; + offset = fixup & 0xfff; + switch ((fixup >> 12) & 0x0f) { + case IMAGE_REL_BASED_ABSOLUTE: + break; + + case IMAGE_REL_BASED_HIGHLOW: { + uint32_t addr; + uint32_t *loc = + RVA2VA(image, + fixup_block->VirtualAddress + + offset, uint32_t *); + addr = RVA2VA(image, (*loc - base), uint32_t); + DBGLINKER("relocation: *%p (Val:%X)= %X", + loc, *loc, addr); + *loc = addr; + } + break; + + case IMAGE_REL_BASED_DIR64: { + uint64_t addr; + uint64_t *loc = + RVA2VA(image, + fixup_block->VirtualAddress + + offset, uint64_t *); + addr = RVA2VA(image, (*loc - base), uint64_t); + DBGLINKER("relocation: *%p (Val:%llX)= %llx", + loc, *loc, addr); + *loc = addr; + } + break; + + default: + ERROR("unknown fixup: %08X", + (fixup >> 12) & 0x0f); + return -EOPNOTSUPP; + break; + } + } + DBGLINKER("finished relocating block"); + + fixup_block = (IMAGE_BASE_RELOCATION *) + ((void *)fixup_block + fixup_block->SizeOfBlock); + }; + DBGLINKER("done relocating all"); + + return 0; +} + +/* Expand the image in memroy if necessary. The image on disk does not + * necessarily maps the image of the driver in memory, so we have to + * re-write it in order to fullfill the sections alignements. The + * advantage to do that is that rva_to_va becomes a simple + * addition. */ +static int fix_pe_image(struct pe_image *pe) +{ + void *image; + IMAGE_SECTION_HEADER *sect_hdr; + int i, sections; + int image_size; + + if (pe->size == pe->opt_hdr->SizeOfImage) { + /* Nothing to do */ + return 0; + } + + image_size = pe->opt_hdr->SizeOfImage; +#ifdef CONFIG_X86_64 +#ifdef PAGE_KERNEL_EXECUTABLE + image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXECUTABLE); +#elif defined PAGE_KERNEL_EXEC + image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXEC); +#else +#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC +#endif +#else +#ifdef cpu_has_nx + /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is + * not available to modules! */ + if (cpu_has_nx) + image = __vmalloc(image_size, GFP_KERNEL | __GFP_HIGHMEM, + __pgprot(__PAGE_KERNEL & ~_PAGE_NX)); + else + image = vmalloc(image_size); +#else + image = vmalloc(image_size); +#endif +#endif + if (image == NULL) { + ERROR("failed to allocate enough space for new image:" + " %d bytes", image_size); + return -ENOMEM; + } + + /* Copy all the headers, ie everything before the first section. */ + + sections = pe->nt_hdr->FileHeader.NumberOfSections; + sect_hdr = IMAGE_FIRST_SECTION(pe->nt_hdr); + + DBGLINKER("copying headers: %u bytes", sect_hdr->PointerToRawData); + + memcpy(image, pe->image, sect_hdr->PointerToRawData); + + /* Copy all the sections */ + for (i = 0; i < sections; i++) { + DBGLINKER("Copy section %s from %x to %x", + sect_hdr->Name, sect_hdr->PointerToRawData, + sect_hdr->VirtualAddress); + if (sect_hdr->VirtualAddress+sect_hdr->SizeOfRawData > + image_size) { + ERROR("Invalid section %s in driver", sect_hdr->Name); + vfree(image); + return -EINVAL; + } + + memcpy(image+sect_hdr->VirtualAddress, + pe->image + sect_hdr->PointerToRawData, + sect_hdr->SizeOfRawData); + sect_hdr++; + } + + vfree(pe->image); + pe->image = image; + pe->size = image_size; + + /* Update our internal pointers */ + pe->nt_hdr = (IMAGE_NT_HEADERS *) + (pe->image + ((IMAGE_DOS_HEADER *)pe->image)->e_lfanew); + pe->opt_hdr = &pe->nt_hdr->OptionalHeader; + + DBGLINKER("set nt headers: nt_hdr=%p, opt_hdr=%p, image=%p", + pe->nt_hdr, pe->opt_hdr, pe->image); + + return 0; +} + +#if defined(CONFIG_X86_64) +static void fix_user_shared_data_addr(char *driver, unsigned long length) +{ + unsigned long i, n, max_addr, *addr; + + n = length - sizeof(unsigned long); + max_addr = KI_USER_SHARED_DATA + sizeof(kuser_shared_data); + for (i = 0; i < n; i++) { + addr = (unsigned long *)(driver + i); + if (*addr >= KI_USER_SHARED_DATA && *addr < max_addr) { + *addr -= KI_USER_SHARED_DATA; + *addr += (unsigned long)&kuser_shared_data; + kuser_shared_data.reserved1 = 1; + } + } +} +#endif + +int link_pe_images(struct pe_image *pe_image, unsigned short n) +{ + int i; + struct pe_image *pe; + +#ifdef DEBUG + /* Sanity checkings */ + CHECK_SZ(IMAGE_SECTION_HEADER, IMAGE_SIZEOF_SECTION_HEADER); + CHECK_SZ(IMAGE_FILE_HEADER, IMAGE_SIZEOF_FILE_HEADER); + CHECK_SZ(IMAGE_OPTIONAL_HEADER, IMAGE_SIZEOF_NT_OPTIONAL_HEADER); + CHECK_SZ(IMAGE_NT_HEADERS, 4 + IMAGE_SIZEOF_FILE_HEADER + + IMAGE_SIZEOF_NT_OPTIONAL_HEADER); + CHECK_SZ(IMAGE_DOS_HEADER, 0x40); + CHECK_SZ(IMAGE_EXPORT_DIRECTORY, 40); + CHECK_SZ(IMAGE_BASE_RELOCATION, 8); + CHECK_SZ(IMAGE_IMPORT_DESCRIPTOR, 20); +#endif + + for (i = 0; i < n; i++) { + IMAGE_DOS_HEADER *dos_hdr; + pe = &pe_image[i]; + dos_hdr = pe->image; + + if (pe->size < sizeof(IMAGE_DOS_HEADER)) { + TRACE1("image too small: %d", pe->size); + return -EINVAL; + } + + pe->nt_hdr = + (IMAGE_NT_HEADERS *)(pe->image + dos_hdr->e_lfanew); + pe->opt_hdr = &pe->nt_hdr->OptionalHeader; + + pe->type = check_nt_hdr(pe->nt_hdr); + if (pe->type <= 0) { + TRACE1("type <= 0"); + return -EINVAL; + } + + if (fix_pe_image(pe)) { + TRACE1("bad PE image"); + return -EINVAL; + } + + if (read_exports(pe)) { + TRACE1("read exports failed"); + return -EINVAL; + } + } + + for (i = 0; i < n; i++) { + pe = &pe_image[i]; + + if (fixup_reloc(pe->image, pe->nt_hdr)) { + TRACE1("fixup reloc failed"); + return -EINVAL; + } + if (fixup_imports(pe->image, pe->nt_hdr)) { + TRACE1("fixup imports failed"); + return -EINVAL; + } +#if defined(CONFIG_X86_64) + INFO("fixing KI_USER_SHARED_DATA address in the driver"); + fix_user_shared_data_addr(pe_image[i].image, pe_image[i].size); +#endif + flush_icache_range(pe->image, pe->size); + + pe->entry = + RVA2VA(pe->image, + pe->opt_hdr->AddressOfEntryPoint, void *); + TRACE1("entry is at %p, rva at %08X", pe->entry, + pe->opt_hdr->AddressOfEntryPoint); + } + + for (i = 0; i < n; i++) { + pe = &pe_image[i]; + + if (pe->type == IMAGE_FILE_DLL) { + struct unicode_string ustring; + char *buf = "0/0t0m0p00"; + int (*dll_entry)(struct unicode_string *ustring) + wstdcall; + + memset(&ustring, 0, sizeof(ustring)); + ustring.buf = (wchar_t *)buf; + dll_entry = (void *)get_dll_init(pe->name); + + TRACE1("calling dll_init at %p", dll_entry); + if (!dll_entry || dll_entry(&ustring)) + ERROR("DLL initialize failed for %s", + pe->name); + } + else if (pe->type != IMAGE_FILE_EXECUTABLE_IMAGE) + ERROR("illegal image type: %d", pe->type); + } + return 0; +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/usb.h +++ linux-2.6.28/ubuntu/ndiswrapper/usb.h @@ -0,0 +1,376 @@ +/* + * Copyright (C) 2004 Jan Kiszka + * Copyright (C) 2005 Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _USB_H_ +#define _USB_H_ + +#include "ntoskernel.h" + +#define IOCTL_INTERNAL_USB_SUBMIT_URB 0x00220003 +#define IOCTL_INTERNAL_USB_RESET_PORT 0x00220007 +#define IOCTL_INTERNAL_USB_GET_PORT_STATUS 0x00220013 +#define IOCTL_INTERNAL_USB_CYCLE_PORT 0x0022001F +#define IOCTL_INTERNAL_USB_SUBMIT_IDLE_NOTIFICATION 0x00220027 + +#define URB_FUNCTION_SELECT_CONFIGURATION 0x0000 +#define URB_FUNCTION_SELECT_INTERFACE 0x0001 +#define URB_FUNCTION_ABORT_PIPE 0x0002 +#define URB_FUNCTION_TAKE_FRAME_LENGTH_CONTROL 0x0003 +#define URB_FUNCTION_RELEASE_FRAME_LENGTH_CONTROL 0x0004 +#define URB_FUNCTION_GET_FRAME_LENGTH 0x0005 +#define URB_FUNCTION_SET_FRAME_LENGTH 0x0006 +#define URB_FUNCTION_GET_CURRENT_FRAME_NUMBER 0x0007 +#define URB_FUNCTION_CONTROL_TRANSFER 0x0008 +#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009 +#define URB_FUNCTION_ISOCH_TRANSFER 0x000A +#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B +#define URB_FUNCTION_SET_DESCRIPTOR_TO_DEVICE 0x000C +#define URB_FUNCTION_SET_FEATURE_TO_DEVICE 0x000D +#define URB_FUNCTION_SET_FEATURE_TO_INTERFACE 0x000E +#define URB_FUNCTION_SET_FEATURE_TO_ENDPOINT 0x000F +#define URB_FUNCTION_CLEAR_FEATURE_TO_DEVICE 0x0010 +#define URB_FUNCTION_CLEAR_FEATURE_TO_INTERFACE 0x0011 +#define URB_FUNCTION_CLEAR_FEATURE_TO_ENDPOINT 0x0012 +#define URB_FUNCTION_GET_STATUS_FROM_DEVICE 0x0013 +#define URB_FUNCTION_GET_STATUS_FROM_INTERFACE 0x0014 +#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT 0x0015 +#define URB_FUNCTION_RESERVED_0X0016 0x0016 +#define URB_FUNCTION_VENDOR_DEVICE 0x0017 +#define URB_FUNCTION_VENDOR_INTERFACE 0x0018 +#define URB_FUNCTION_VENDOR_ENDPOINT 0x0019 +#define URB_FUNCTION_CLASS_DEVICE 0x001A +#define URB_FUNCTION_CLASS_INTERFACE 0x001B +#define URB_FUNCTION_CLASS_ENDPOINT 0x001C +#define URB_FUNCTION_RESERVE_0X001D 0x001D +#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL 0x001E +#define URB_FUNCTION_CLASS_OTHER 0x001F +#define URB_FUNCTION_VENDOR_OTHER 0x0020 +#define URB_FUNCTION_GET_STATUS_FROM_OTHER 0x0021 +#define URB_FUNCTION_CLEAR_FEATURE_TO_OTHER 0x0022 +#define URB_FUNCTION_SET_FEATURE_TO_OTHER 0x0023 +#define URB_FUNCTION_GET_DESCRIPTOR_FROM_ENDPOINT 0x0024 +#define URB_FUNCTION_SET_DESCRIPTOR_TO_ENDPOINT 0x0025 +#define URB_FUNCTION_GET_CONFIGURATION 0x0026 +#define URB_FUNCTION_GET_INTERFACE 0x0027 +#define URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE 0x0028 +#define URB_FUNCTION_SET_DESCRIPTOR_TO_INTERFACE 0x0029 +#define URB_FUNCTION_GET_MS_FEATURE_DESCRIPTOR 0x002A +#define URB_FUNCTION_RESERVE_0X002B 0x002B +#define URB_FUNCTION_RESERVE_0X002C 0x002C +#define URB_FUNCTION_RESERVE_0X002D 0x002D +#define URB_FUNCTION_RESERVE_0X002E 0x002E +#define URB_FUNCTION_RESERVE_0X002F 0x002F +// USB 2.0 calls start at 0x0030 +#define URB_FUNCTION_SYNC_RESET_PIPE 0x0030 +#define URB_FUNCTION_SYNC_CLEAR_STALL 0x0031 +#define URB_FUNCTION_CONTROL_TRANSFER_EX 0x0032 + +#define USBD_PF_CHANGE_MAX_PACKET 0x00000001 + +#define USBD_TRANSFER_DIRECTION_OUT 0 +#define USBD_TRANSFER_DIRECTION_IN 1 + +#define USBD_SHORT_TRANSFER_OK 0x00000002 +#define USBD_START_ISO_TRANSFER_ASAP 0x00000004 +#define USBD_DEFAULT_PIPE_TRANSFER 0x00000008 + +#define USBD_TRANSFER_DIRECTION(flags) \ + ((flags) & USBD_TRANSFER_DIRECTION_IN) + +enum pipe_type {UsbdPipeTypeControl = USB_ENDPOINT_XFER_CONTROL, + UsbdPipeTypeIsochronous = USB_ENDPOINT_XFER_ISOC, + UsbdPipeTypeBulk = USB_ENDPOINT_XFER_BULK, + UsbdPipeTypeInterrupt = USB_ENDPOINT_XFER_INT}; + +#define USBD_IS_BULK_PIPE(pipe_handle) \ + (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \ + == USB_ENDPOINT_XFER_BULK) + +#define USBD_IS_INT_PIPE(pipe_handle) \ + (((pipe_handle)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) \ + == USB_ENDPOINT_XFER_INT) + +#define USBD_PORT_ENABLED 0x00000001 +#define USBD_PORT_CONNECTED 0x00000002 + +typedef LONG USBD_STATUS; + +#define USBD_STATUS_SUCCESS 0x0 +#define USBD_STATUS_PENDING 0x40000000 +#define USBD_STATUS_CANCELED 0x00010000 + +#define USBD_STATUS_CRC 0xC0000001 +#define USBD_STATUS_BTSTUFF 0xC0000002 +#define USBD_STATUS_DATA_TOGGLE_MISMATCH 0xC0000003 +#define USBD_STATUS_STALL_PID 0xC0000004 +#define USBD_STATUS_DEV_NOT_RESPONDING 0xC0000005 +#define USBD_STATUS_PID_CHECK_FAILURE 0xC0000006 +#define USBD_STATUS_UNEXPECTED_PID 0xC0000007 +#define USBD_STATUS_DATA_OVERRUN 0xC0000008 +#define USBD_STATUS_DATA_UNDERRUN 0xC0000009 +#define USBD_STATUS_RESERVED1 0xC000000A +#define USBD_STATUS_RESERVED2 0xC000000B +#define USBD_STATUS_BUFFER_OVERRUN 0xC000000C +#define USBD_STATUS_BUFFER_UNDERRUN 0xC000000D +#define USBD_STATUS_NOT_ACCESSED 0xC000000F +#define USBD_STATUS_FIFO 0xC0000010 +#define USBD_STATUS_XACT_ERROR 0xC0000011 +#define USBD_STATUS_BABBLE_DETECTED 0xC0000012 +#define USBD_STATUS_DATA_BUFFER_ERROR 0xC0000013 + +#define USBD_STATUS_NOT_SUPPORTED 0xC0000E00 +#define USBD_STATUS_BUFFER_TOO_SMALL 0xC0003000 +#define USBD_STATUS_TIMEOUT 0xC0006000 +#define USBD_STATUS_DEVICE_GONE 0xC0007000 + +#define USBD_STATUS_NO_MEMORY 0x80000100 +#define USBD_STATUS_INVALID_URB_FUNCTION 0x80000200 +#define USBD_STATUS_INVALID_PARAMETER 0x80000300 +#define USBD_STATUS_REQUEST_FAILED 0x80000500 +#define USBD_STATUS_INVALID_PIPE_HANDLE 0x80000600 +#define USBD_STATUS_ERROR_SHORT_TRANSFER 0x80000900 + +#define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE PAGE_SIZE + +struct urb_hcd_area { + void *reserved8[8]; +}; + +typedef struct usb_endpoint_descriptor *usbd_pipe_handle; +typedef struct usb_descriptor_header usb_common_descriptor_t; + +struct usbd_pipe_information { + USHORT wMaxPacketSize; + UCHAR bEndpointAddress; + UCHAR bInterval; + enum pipe_type type; + usbd_pipe_handle handle; + ULONG max_tx_size; + ULONG flags; +}; + +struct usbd_interface_information { + USHORT bLength; + UCHAR bInterfaceNumber; + UCHAR bAlternateSetting; + UCHAR bInterfaceClass; + UCHAR bInterfaceSubClass; + UCHAR bInterfaceProtocol; + UCHAR reserved; + void *handle; + ULONG bNumEndpoints; + struct usbd_pipe_information pipes[1]; +}; + +struct usbd_interface_list_entry { + struct usb_interface_descriptor *intf_desc; + struct usbd_interface_information *intf; +}; + +struct nt_urb_header { + USHORT length; + USHORT function; + USBD_STATUS status; + void *usbd_dev_handle; + ULONG usbd_flags; +}; + +struct usbd_select_interface { + struct nt_urb_header header; + void *handle; + struct usbd_interface_information intf; +}; + +struct usbd_select_configuration { + struct nt_urb_header header; + struct usb_config_descriptor *config; + void *handle; + struct usbd_interface_information intf; +}; + +struct usbd_control_descriptor_request { + struct nt_urb_header header; + void *reserved; + ULONG reserved0; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *urb_link; + struct urb_hcd_area hca; + USHORT reserved1; + UCHAR index; + UCHAR desc_type; + USHORT language_id; + USHORT reserved2; +}; + +struct usbd_bulk_or_intr_transfer { + struct nt_urb_header header; + usbd_pipe_handle pipe_handle; + ULONG transfer_flags; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *urb_link; + struct urb_hcd_area hca; +}; + +struct usbd_pipe_request { + struct nt_urb_header header; + usbd_pipe_handle pipe_handle; +}; + +struct usbd_vendor_or_class_request { + struct nt_urb_header header; + void *reserved; + ULONG transfer_flags; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *link; + struct urb_hcd_area hca; + UCHAR reserved_bits; + UCHAR request; + USHORT value; + USHORT index; + USHORT reserved1; +}; + +struct urb_control_feature_request { + struct nt_urb_header header; + void *reserved; + ULONG reserved2; + ULONG reserved3; + void *reserved4; + struct mdl *reserved5; + union nt_urb *link; + struct urb_hcd_area hca; + USHORT reserved0; + USHORT feature_selector; + USHORT index; + USHORT reserved1; +}; + +struct urb_control_get_status_request { + struct nt_urb_header header; + void *reserved; + ULONG reserved0; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *link; + struct urb_hcd_area hca; + UCHAR reserved1[4]; + USHORT index; + USHORT reserved2; +}; + +struct usbd_iso_packet_desc { + ULONG offset; + ULONG length; + USBD_STATUS status; +}; + +struct usbd_isochronous_transfer { + struct nt_urb_header header; + usbd_pipe_handle pipe_handle; + ULONG transfer_flags; + ULONG transfer_buffer_length; + void *transfer_buffer; + struct mdl *mdl; + union nt_urb *urb_link; + struct urb_hcd_area hca; + ULONG start_frame; + ULONG number_of_packets; + ULONG error_count; + struct usbd_iso_packet_desc iso_packet[1]; +}; + +union nt_urb { + struct nt_urb_header header; + struct usbd_select_interface select_intf; + struct usbd_select_configuration select_conf; + struct usbd_bulk_or_intr_transfer bulk_int_transfer; + struct usbd_control_descriptor_request control_desc; + struct usbd_vendor_or_class_request vendor_class_request; + struct usbd_isochronous_transfer isochronous; + struct usbd_pipe_request pipe_req; + struct urb_control_feature_request feat_req; + struct urb_control_get_status_request status_req; +}; + +struct usbd_bus_interface_usbdi { + USHORT Size; + USHORT Version; + void *Context; + void *InterfaceReference; + void *InterfaceDereference; + void *GetUSBDIVersion; + void *QueryBusTime; + void *SubmitIsoOutUrb; + void *QueryBusInformation; + /* version 1 and above have following field */ + void *IsDeviceHighSpeed; + /* version 2 (and above) have following field */ + void *LogEntry; +}; + +struct usbd_bus_information_level { + ULONG TotalBandwidth; + ULONG ConsumedBandwidth; + /* level 1 and above have following fields */ + ULONG ControllerNameLength; + wchar_t ControllerName[1]; +}; + +#define USBDI_VERSION_XP 0x00000500 // Windows XP +#define USB_HCD_CAPS_SUPPORTS_RT_THREADS 0x00000001 +#define USB_BUSIF_USBDI_VERSION_0 0x0000 +#define USB_BUSIF_USBDI_VERSION_1 0x0001 +#define USB_BUSIF_USBDI_VERSION_2 0x0002 + +struct usbd_version_info { + ULONG usbdi_version; + ULONG supported_usb_version; +}; + +struct usbd_idle_callback { + void *callback; + void *context; +}; + +#define NT_URB_STATUS(nt_urb) ((nt_urb)->header.status) + +NTSTATUS wrap_submit_irp(struct device_object *pdo, struct irp *irp); +void wrap_suspend_urbs(struct wrap_device *wd); +void wrap_resume_urbs(struct wrap_device *wd); + +void USBD_InterfaceGetUSBDIVersion(void *context, + struct usbd_version_info *version_info, + ULONG *hcd_capa) wstdcall; +BOOLEAN USBD_InterfaceIsDeviceHighSpeed(void *context) wstdcall; +void USBD_InterfaceReference(void *context) wstdcall; +void USBD_InterfaceDereference(void *context) wstdcall; +NTSTATUS USBD_InterfaceQueryBusTime(void *context, ULONG *frame) wstdcall; +NTSTATUS USBD_InterfaceSubmitIsoOutUrb(void *context, + union nt_urb *nt_urb) wstdcall; +NTSTATUS USBD_InterfaceQueryBusInformation(void *context, ULONG level, void *buf, + ULONG *buf_length, + ULONG *buf_actual_length) wstdcall; +NTSTATUS USBD_InterfaceLogEntry(void *context, ULONG driver_tag, ULONG enum_tag, + ULONG p1, ULONG p2) wstdcall; + +#endif /* USB_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/longlong.h +++ linux-2.6.28/ubuntu/ndiswrapper/longlong.h @@ -0,0 +1,1333 @@ +/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. + Copyright (C) 1991, 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* You have to define the following before including this file: + + UWtype -- An unsigned type, default type for operations (typically a "word") + UHWtype -- An unsigned type, at least half the size of UWtype. + UDWtype -- An unsigned type, at least twice as large a UWtype + W_TYPE_SIZE -- size in bits of UWtype + + UQItype -- Unsigned 8 bit type. + SItype, USItype -- Signed and unsigned 32 bit types. + DItype, UDItype -- Signed and unsigned 64 bit types. + + On a 32 bit machine UWtype should typically be USItype; + on a 64 bit machine, UWtype should typically be UDItype. +*/ + +#define __BITS4 (W_TYPE_SIZE / 4) +#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) +#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) +#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) + +#ifndef W_TYPE_SIZE +#define W_TYPE_SIZE 32 +#define UWtype USItype +#define UHWtype USItype +#define UDWtype UDItype +#endif + +/* Define auxiliary asm macros. + + 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) multiplies two + UWtype integers MULTIPLER and MULTIPLICAND, and generates a two UWtype + word product in HIGH_PROD and LOW_PROD. + + 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a + UDWtype product. This is just a variant of umul_ppmm. + + 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator) divides a UDWtype, composed by the UWtype integers + HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient + in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less + than DENOMINATOR for correct operation. If, in addition, the most + significant bit of DENOMINATOR must be 1, then the pre-processor symbol + UDIV_NEEDS_NORMALIZATION is defined to 1. + + 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, + denominator). Like udiv_qrnnd but the numbers are signed. The quotient + is rounded towards 0. + + 5) count_leading_zeros(count, x) counts the number of zero-bits from the + msb to the first nonzero bit in the UWtype X. This is the number of + steps X needs to be shifted left to set the msb. Undefined for X == 0, + unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. + + 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts + from the least significant end. + + 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, + high_addend_2, low_addend_2) adds two UWtype integers, composed by + HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 + respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow + (i.e. carry out) is not stored anywhere, and is lost. + + 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, + high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, + composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and + LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE + and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, + and is lost. + + If any of these macros are left undefined for a particular CPU, + C macros are used. */ + +/* The CPUs come in alphabetical order below. + + Please add support for more CPUs here, or improve the current support + for the CPUs below! + (E.g. WE32100, IBM360.) */ + +#if defined (__GNUC__) && !defined (NO_ASM) + +/* We sometimes need to clobber "cc" with gcc2, but that would not be + understood by gcc1. Use cpp to avoid major code duplication. */ +#if __GNUC__ < 2 +#define __CLOBBER_CC +#define __AND_CLOBBER_CC +#else /* __GNUC__ >= 2 */ +#define __CLOBBER_CC : "cc" +#define __AND_CLOBBER_CC , "cc" +#endif /* __GNUC__ < 2 */ + +#if defined (__alpha) && W_TYPE_SIZE == 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("umulh %r1,%2,%0" \ + : "=r" ((UDItype) ph) \ + : "%rJ" (__m0), \ + "rI" (__m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 46 +#ifndef LONGLONG_STANDALONE +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { UDItype __r; \ + (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ + (r) = __r; \ + } while (0) +extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); +#define UDIV_TIME 220 +#endif /* LONGLONG_STANDALONE */ +#ifdef __alpha_cix__ +#define count_leading_zeros(COUNT,X) \ + __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X)) +#define count_trailing_zeros(COUNT,X) \ + __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X)) +#define COUNT_LEADING_ZEROS_0 64 +#else +extern const UQItype __clz_tab[]; +#define count_leading_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ + __a = __clz_tab[__t ^ 0xff] - 1; \ + __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ + (COUNT) = 64 - (__clz_tab[__t] + __a*8); \ + } while (0) +#define count_trailing_zeros(COUNT,X) \ + do { \ + UDItype __xr = (X), __t, __a; \ + __asm__("cmpbge $31,%1,%0" : "=r"(__t) : "r"(__xr)); \ + __t = ~__t & -~__t; \ + __a = ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + __asm__("extbl %1,%2,%0" : "=r"(__t) : "r"(__xr), "r"(__a)); \ + __a <<= 3; \ + __t &= -__t; \ + __a += ((__t & 0xCC) != 0) * 2; \ + __a += ((__t & 0xF0) != 0) * 4; \ + __a += ((__t & 0xAA) != 0); \ + (COUNT) = __a; \ + } while (0) +#endif /* __alpha_cix__ */ +#endif /* __alpha */ + +#if defined (__arc__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add.f %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rIJ" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rIJ" ((USItype) (bl))) +/* Call libgcc routine. */ +#define umul_ppmm(w1, w0, u, v) \ +do { \ + DWunion __w; \ + __w.ll = __umulsidi3 (u, v); \ + w1 = __w.s.high; \ + w0 = __w.s.low; \ +} while (0) +#define __umulsidi3 __umulsidi3 +UDItype __umulsidi3 (USItype, USItype); +#endif + +#if defined (__arm__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("adds %1, %4, %5\n\tadc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subs %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ + "rI" ((USItype) (bl))) +#define umul_ppmm(xh, xl, a, b) \ +{register USItype __t0, __t1, __t2; \ + __asm__ ("%@ Inlined umul_ppmm\n" \ + " mov %2, %5, lsr #16\n" \ + " mov %0, %6, lsr #16\n" \ + " bic %3, %5, %2, lsl #16\n" \ + " bic %4, %6, %0, lsl #16\n" \ + " mul %1, %3, %4\n" \ + " mul %4, %2, %4\n" \ + " mul %3, %0, %3\n" \ + " mul %0, %2, %0\n" \ + " adds %3, %4, %3\n" \ + " addcs %0, %0, #65536\n" \ + " adds %1, %1, %3, lsl #16\n" \ + " adc %0, %0, %3, lsr #16" \ + : "=&r" ((USItype) (xh)), \ + "=r" ((USItype) (xl)), \ + "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ + : "r" ((USItype) (a)), \ + "r" ((USItype) (b)));} +#define UMUL_TIME 20 +#define UDIV_TIME 100 +#endif /* __arm__ */ + +#if defined (__hppa) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "%rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %4,%5,%1\n\tsubb %2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rM" ((USItype) (ah)), \ + "rM" ((USItype) (bh)), \ + "rM" ((USItype) (al)), \ + "rM" ((USItype) (bl))) +#if defined (_PA_RISC1_1) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + union \ + { \ + UDItype __f; \ + struct {USItype __w1, __w0;} __w1w0; \ + } __t; \ + __asm__ ("xmpyu %1,%2,%0" \ + : "=x" (__t.__f) \ + : "x" ((USItype) (u)), \ + "x" ((USItype) (v))); \ + (w1) = __t.__w1w0.__w1; \ + (w0) = __t.__w1w0.__w0; \ + } while (0) +#define UMUL_TIME 8 +#else +#define UMUL_TIME 30 +#endif +#define UDIV_TIME 40 +#define count_leading_zeros(count, x) \ + do { \ + USItype __tmp; \ + __asm__ ( \ + "ldi 1,%0\n" \ +" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ +" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n"\ +" ldo 16(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ +" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n"\ +" ldo 8(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ +" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n"\ +" ldo 4(%0),%0 ; Yes. Perform add.\n" \ +" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ +" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n"\ +" ldo 2(%0),%0 ; Yes. Perform add.\n" \ +" extru %1,30,1,%1 ; Extract bit 1.\n" \ +" sub %0,%1,%0 ; Subtract it.\n" \ + : "=r" (count), "=r" (__tmp) : "1" (x)); \ + } while (0) +#endif + +#if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mr %0,%3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "r" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define smul_ppmm(xh, xl, m0, m1) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mr %0,%3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (m0), \ + "r" (m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("dr %0,%2" \ + : "=r" (__xx.__ll) \ + : "0" (__xx.__ll), "r" (d)); \ + (q) = __xx.__i.__l; (r) = __xx.__i.__h; \ + } while (0) +#endif + +#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl %5,%1\n\tadcl %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl %5,%1\n\tsbbl %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mull %3" \ + : "=a" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "rm" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, dv) \ + __asm__ ("divl %4" \ + : "=a" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "rm" ((USItype) (dv))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("bsrl %1,%0" \ + : "=r" (__cbtmp) : "rm" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define count_trailing_zeros(count, x) \ + __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x))) +#define UMUL_TIME 40 +#define UDIV_TIME 40 +#endif /* 80x86 */ + +#if defined (__i960__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__xx.__ll) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("emul %2,%1,%0" \ + : "=d" (__w) \ + : "%dI" ((USItype) (u)), \ + "dI" ((USItype) (v))); \ + __w; }) +#endif /* __i960__ */ + +#if defined (__M32R__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\taddx %%5,%1\n\taddx %%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + /* The cmp clears the condition bit. */ \ + __asm__ ("cmp %0,%0\n\tsubx %5,%1\n\tsubx %3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl)) \ + : "cbit") +#endif /* __M32R__ */ + +#if defined (__mc68000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ + : "=d" ((USItype) (sh)), \ + "=&d" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "d" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) + +/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */ +#if defined (__mc68020__) || defined(mc68020) \ + || defined(__mc68030__) || defined(mc68030) \ + || defined(__mc68040__) || defined(mc68040) \ + || defined(__mcpu32__) || defined(mcpu32) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("mulu%.l %3,%1:%0" \ + : "=d" ((USItype) (w0)), \ + "=d" ((USItype) (w1)) \ + : "%0" ((USItype) (u)), \ + "dmi" ((USItype) (v))) +#define UMUL_TIME 45 +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divu%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) +#define UDIV_TIME 90 +#define sdiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("divs%.l %4,%1:%0" \ + : "=d" ((USItype) (q)), \ + "=d" ((USItype) (r)) \ + : "0" ((USItype) (n0)), \ + "1" ((USItype) (n1)), \ + "dmi" ((USItype) (d))) + +#else /* not mc68020 */ +#if !defined(__mcf5200__) +/* %/ inserts REGISTER_PREFIX, %# inserts IMMEDIATE_PREFIX. */ +#define umul_ppmm(xh, xl, a, b) \ + __asm__ ("| Inlined umul_ppmm\n" \ + " move%.l %2,%/d0\n" \ + " move%.l %3,%/d1\n" \ + " move%.l %/d0,%/d2\n" \ + " swap %/d0\n" \ + " move%.l %/d1,%/d3\n" \ + " swap %/d1\n" \ + " move%.w %/d2,%/d4\n" \ + " mulu %/d3,%/d4\n" \ + " mulu %/d1,%/d2\n" \ + " mulu %/d0,%/d3\n" \ + " mulu %/d0,%/d1\n" \ + " move%.l %/d4,%/d0\n" \ + " eor%.w %/d0,%/d0\n" \ + " swap %/d0\n" \ + " add%.l %/d0,%/d2\n" \ + " add%.l %/d3,%/d2\n" \ + " jcc 1f\n" \ + " add%.l %#65536,%/d1\n" \ + "1: swap %/d2\n" \ + " moveq %#0,%/d0\n" \ + " move%.w %/d2,%/d0\n" \ + " move%.w %/d4,%/d2\n" \ + " move%.l %/d2,%1\n" \ + " add%.l %/d1,%/d0\n" \ + " move%.l %/d0,%0" \ + : "=g" ((USItype) (xh)), \ + "=g" ((USItype) (xl)) \ + : "g" ((USItype) (a)), \ + "g" ((USItype) (b)) \ + : "d0", "d1", "d2", "d3", "d4") +#define UMUL_TIME 100 +#define UDIV_TIME 400 +#endif /* not mcf5200 */ +#endif /* not mc68020 */ + +/* The '020, '030, '040 and '060 have bitfield insns. */ +#if defined (__mc68020__) || defined(mc68020) \ + || defined(__mc68030__) || defined(mc68030) \ + || defined(__mc68040__) || defined(mc68040) \ + || defined(__mc68060__) || defined(mc68060) +#define count_leading_zeros(count, x) \ + __asm__ ("bfffo %1{%b2:%b2},%0" \ + : "=d" ((USItype) (count)) \ + : "od" ((USItype) (x)), "n" (0)) +#endif +#endif /* mc68000 */ + +#if defined (__m88000__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rJ" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rJ" ((USItype) (bl))) +#define count_leading_zeros(count, x) \ + do { \ + USItype __cbtmp; \ + __asm__ ("ff1 %0,%1" \ + : "=r" (__cbtmp) \ + : "r" ((USItype) (x))); \ + (count) = __cbtmp ^ 31; \ + } while (0) +#define COUNT_LEADING_ZEROS_0 63 /* sic */ +#if defined (__mc88110__) +#define umul_ppmm(wh, wl, u, v) \ + do { \ + union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + __asm__ ("mulu.d %0,%1,%2" \ + : "=r" (__xx.__ll) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))); \ + (wh) = __xx.__i.__h; \ + (wl) = __xx.__i.__l; \ + } while (0) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __h, __l;} __i; \ + } __xx; \ + USItype __q; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("divu.d %0,%1,%2" \ + : "=r" (__q) \ + : "r" (__xx.__ll), \ + "r" ((USItype) (d))); \ + (r) = (n0) - __q * (d); (q) = __q; }) +#define UMUL_TIME 5 +#define UDIV_TIME 25 +#else +#define UMUL_TIME 17 +#define UDIV_TIME 150 +#endif /* __mc88110__ */ +#endif /* __m88000__ */ + +#if defined (__mips__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("multu %2,%3" \ + : "=l" ((USItype) (w0)), \ + "=h" ((USItype) (w1)) \ + : "d" ((USItype) (u)), \ + "d" ((USItype) (v))) +#define UMUL_TIME 10 +#define UDIV_TIME 100 +#endif /* __mips__ */ + +#if defined (__ns32000__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __asm__ ("meid %2,%0" \ + : "=g" (__xx.__ll) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) +#define __umulsidi3(u, v) \ + ({UDItype __w; \ + __asm__ ("meid %2,%0" \ + : "=g" (__w) \ + : "%0" ((USItype) (u)), \ + "g" ((USItype) (v))); \ + __w; }) +#define udiv_qrnnd(q, r, n1, n0, d) \ + ({union {UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = (n1); __xx.__i.__l = (n0); \ + __asm__ ("deid %2,%0" \ + : "=g" (__xx.__ll) \ + : "0" (__xx.__ll), \ + "g" ((USItype) (d))); \ + (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) +#define count_trailing_zeros(count,x) \ + do { \ + __asm__ ("ffsd %2,%0" \ + : "=r" ((USItype) (count)) \ + : "0" ((USItype) 0), \ + "r" ((USItype) (x))); \ + } while (0) +#endif /* __ns32000__ */ + +/* FIXME: We should test _IBMR2 here when we add assembly support for the + system vendor compilers. + FIXME: What's needed for gcc PowerPC VxWorks? __vxworks__ is not good + enough, since that hits ARM and m68k too. */ +#if (defined (_ARCH_PPC) /* AIX */ \ + || defined (_ARCH_PWR) /* AIX */ \ + || defined (_ARCH_COM) /* AIX */ \ + || defined (__powerpc__) /* gcc */ \ + || defined (__POWERPC__) /* BEOS */ \ + || defined (__ppc__) /* Darwin */ \ + || defined (PPC) /* GNU/Linux, SysV */ \ + ) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("{cntlz|cntlzw} %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 32 +#if defined (_ARCH_PPC) || defined (__powerpc__) || defined (__POWERPC__) \ + || defined (__ppc__) || defined (PPC) || defined (__vxworks__) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + SItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 +#define UDIV_TIME 120 +#elif defined (_ARCH_PWR) +#define UMUL_TIME 8 +#define smul_ppmm(xh, xl, m0, m1) \ + __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) +#define SMUL_TIME 4 +#define sdiv_qrnnd(q, r, nh, nl, d) \ + __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) +#define UDIV_TIME 100 +#endif +#endif /* 32-bit POWER architecture variants. */ + +/* We should test _IBMR2 here when we add assembly support for the system + vendor compilers. */ +#if (defined (_ARCH_PPC64) || defined (__powerpc64__)) && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl));\ + else \ + __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \ + : "=r" (sh), "=&r" (sl) \ + : "%r" (ah), "r" (bh), "%r" (al), "rI" (bl)); \ + } while (0) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + if (__builtin_constant_p (ah) && (ah) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ + __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \ + : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl));\ + else \ + __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \ + : "=r" (sh), "=&r" (sl) \ + : "r" (ah), "r" (bh), "rI" (al), "r" (bl)); \ + } while (0) +#define count_leading_zeros(count, x) \ + __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) +#define COUNT_LEADING_ZEROS_0 64 +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + UDItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define UMUL_TIME 15 +#define smul_ppmm(ph, pl, m0, m1) \ + do { \ + DItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ + (pl) = __m0 * __m1; \ + } while (0) +#define SMUL_TIME 14 /* ??? */ +#define UDIV_TIME 120 /* ??? */ +#endif /* 64-bit PowerPC. */ + +#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("a %1,%5\n\tae %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("s %1,%5\n\tse %0,%3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "r" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "r" ((USItype) (bl))) +#define umul_ppmm(ph, pl, m0, m1) \ + do { \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ( \ + "s r2,r2\n" \ +" mts r10,%2\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" m r2,%3\n" \ +" cas %0,r2,r0\n" \ +" mfs r10,%1" \ + : "=r" ((USItype) (ph)), \ + "=r" ((USItype) (pl)) \ + : "%r" (__m0), \ + "r" (__m1) \ + : "r2"); \ + (ph) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define UMUL_TIME 20 +#define UDIV_TIME 200 +#define count_leading_zeros(count, x) \ + do { \ + if ((x) >= 0x10000) \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x) >> 16)); \ + else \ + { \ + __asm__ ("clz %0,%1" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + (count) += 16; \ + } \ + } while (0) +#endif + +#if defined (__sh2__) && W_TYPE_SIZE == 32 +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ( \ + "dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \ + : "=r" ((USItype)(w1)), \ + "=r" ((USItype)(w0)) \ + : "r" ((USItype)(u)), \ + "r" ((USItype)(v)) \ + : "macl", "mach") +#define UMUL_TIME 5 +#endif + +#if defined (__SH5__) && __SHMEDIA__ && W_TYPE_SIZE == 32 +#define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) +#define count_leading_zeros(count, x) \ + do \ + { \ + UDItype x_ = (USItype)(x); \ + SItype c_; \ + \ + __asm__ ("nsb %1, %0" : "=r" (c_) : "r" (x_)); \ + (count) = c_ - 31; \ + } \ + while (0) +#define COUNT_LEADING_ZEROS_0 32 +#endif + +#if defined (__sparc__) && !defined (__arch64__) && !defined (__sparcv9) \ + && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "%rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "rJ" ((USItype) (ah)), \ + "rI" ((USItype) (bh)), \ + "rJ" ((USItype) (al)), \ + "rI" ((USItype) (bl)) \ + __CLOBBER_CC) +#if defined (__sparc_v8__) +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("mov %2,%%y;nop;nop;nop;udiv %3,%4,%0;umul %0,%4,%1;sub %3,%1,%1"\ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__n1)), \ + "r" ((USItype) (__n0)), \ + "r" ((USItype) (__d))) +#else +#if defined (__sparclite__) +/* This has hardware multiply but not divide. It also has two additional + instructions scan (ffs from high bit) and divscc. */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("umul %2,%3,%1;rd %%y,%0" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "r" ((USItype) (u)), \ + "r" ((USItype) (v))) +#define udiv_qrnnd(q, r, n1, n0, d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ +" tst %%g0\n" \ +" divscc %3,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%%g1\n" \ +" divscc %%g1,%4,%0\n" \ +" rd %%y,%1\n" \ +" bl,a 1f\n" \ +" add %1,%4,%1\n" \ +"1: ! End of inline udiv_qrnnd" \ + : "=r" ((USItype) (q)), \ + "=r" ((USItype) (r)) \ + : "r" ((USItype) (n1)), \ + "r" ((USItype) (n0)), \ + "rI" ((USItype) (d)) \ + : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME 37 +#define count_leading_zeros(count, x) \ + do { \ + __asm__ ("scan %1,1,%0" \ + : "=r" ((USItype) (count)) \ + : "r" ((USItype) (x))); \ + } while (0) +/* Early sparclites return 63 for an argument of 0, but they warn that future + implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 + undefined. */ +#else +/* SPARC without integer multiplication and divide instructions. + (i.e. at least Sun4/20,40,60,65,75,110,260,280,330,360,380,470,490) */ +#define umul_ppmm(w1, w0, u, v) \ + __asm__ ("! Inlined umul_ppmm\n" \ +" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n"\ +" sra %3,31,%%o5 ! Don't move this insn\n" \ +" and %2,%%o5,%%o5 ! Don't move this insn\n" \ +" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,%3,%%g1\n" \ +" mulscc %%g1,0,%%g1\n" \ +" add %%g1,%%o5,%0\n" \ +" rd %%y,%1" \ + : "=r" ((USItype) (w1)), \ + "=r" ((USItype) (w0)) \ + : "%rI" ((USItype) (u)), \ + "r" ((USItype) (v)) \ + : "g1", "o5" __AND_CLOBBER_CC) +#define UMUL_TIME 39 /* 39 instructions */ +/* It's quite necessary to add this much assembler for the sparc. + The default udiv_qrnnd (in C) is more than 10 times slower! */ +#define udiv_qrnnd(__q, __r, __n1, __n0, __d) \ + __asm__ ("! Inlined udiv_qrnnd\n" \ +" mov 32,%%g1\n" \ +" subcc %1,%2,%%g0\n" \ +"1: bcs 5f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +" addx %1,%1,%1 ! so this can't give carry\n" \ +" subcc %%g1,1,%%g1\n" \ +"2: bne 1b\n" \ +" subcc %1,%2,%%g0\n" \ +" bcs 3f\n" \ +" addxcc %0,%0,%0 ! shift n1n0 and a q-bit in lsb\n" \ +" b 3f\n" \ +" sub %1,%2,%1 ! this kills msb of n\n" \ +"4: sub %1,%2,%1\n" \ +"5: addxcc %1,%1,%1\n" \ +" bcc 2b\n" \ +" subcc %%g1,1,%%g1\n" \ +"! Got carry from n. Subtract next step to cancel this carry.\n" \ +" bne 4b\n" \ +" addcc %0,%0,%0 ! shift n1n0 and a 0-bit in lsb\n" \ +" sub %1,%2,%1\n" \ +"3: xnor %0,0,%0\n" \ +" ! End of inline udiv_qrnnd" \ + : "=&r" ((USItype) (__q)), \ + "=&r" ((USItype) (__r)) \ + : "r" ((USItype) (__d)), \ + "1" ((USItype) (__n1)), \ + "0" ((USItype) (__n0)) : "g1" __AND_CLOBBER_CC) +#define UDIV_TIME (3+7*32) /* 7 instructions/iteration. 32 iterations. */ +#endif /* __sparclite__ */ +#endif /* __sparc_v8__ */ +#endif /* sparc32 */ + +#if ((defined (__sparc__) && defined (__arch64__)) || defined (__sparcv9)) \ + && W_TYPE_SIZE == 64 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addcc %r4,%5,%1\n\t" \ + "add %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "add %0, 1, %0\n" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "%rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "%rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subcc %r4,%5,%1\n\t" \ + "sub %r2,%3,%0\n\t" \ + "bcs,a,pn %%xcc, 1f\n\t" \ + "sub %0, 1, %0\n\t" \ + "1:" \ + : "=r" ((UDItype)(sh)), \ + "=&r" ((UDItype)(sl)) \ + : "rJ" ((UDItype)(ah)), \ + "rI" ((UDItype)(bh)), \ + "rJ" ((UDItype)(al)), \ + "rI" ((UDItype)(bl)) \ + __CLOBBER_CC) + +#define umul_ppmm(wh, wl, u, v) \ + do { \ + UDItype tmp1, tmp2, tmp3, tmp4; \ + __asm__ __volatile__ ( \ + "srl %7,0,%3\n\t" \ + "mulx %3,%6,%1\n\t" \ + "srlx %6,32,%2\n\t" \ + "mulx %2,%3,%4\n\t" \ + "sllx %4,32,%5\n\t" \ + "srl %6,0,%3\n\t" \ + "sub %1,%5,%5\n\t" \ + "srlx %5,32,%5\n\t" \ + "addcc %4,%5,%4\n\t" \ + "srlx %7,32,%5\n\t" \ + "mulx %3,%5,%3\n\t" \ + "mulx %2,%5,%5\n\t" \ + "sethi %%hi(0x80000000),%2\n\t" \ + "addcc %4,%3,%4\n\t" \ + "srlx %4,32,%4\n\t" \ + "add %2,%2,%2\n\t" \ + "movcc %%xcc,%%g0,%2\n\t" \ + "addcc %5,%4,%5\n\t" \ + "sllx %3,32,%3\n\t" \ + "add %1,%3,%1\n\t" \ + "add %5,%2,%0" \ + : "=r" ((UDItype)(wh)), \ + "=&r" ((UDItype)(wl)), \ + "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \ + : "r" ((UDItype)(u)), \ + "r" ((UDItype)(v)) \ + __CLOBBER_CC); \ + } while (0) +#define UMUL_TIME 96 +#define UDIV_TIME 230 +#endif /* sparc64 */ + +#if defined (__vax__) && W_TYPE_SIZE == 32 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "%0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "%1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ + : "=g" ((USItype) (sh)), \ + "=&g" ((USItype) (sl)) \ + : "0" ((USItype) (ah)), \ + "g" ((USItype) (bh)), \ + "1" ((USItype) (al)), \ + "g" ((USItype) (bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union { \ + UDItype __ll; \ + struct {USItype __l, __h;} __i; \ + } __xx; \ + USItype __m0 = (m0), __m1 = (m1); \ + __asm__ ("emul %1,%2,$0,%0" \ + : "=r" (__xx.__ll) \ + : "g" (__m0), \ + "g" (__m1)); \ + (xh) = __xx.__i.__h; \ + (xl) = __xx.__i.__l; \ + (xh) += ((((SItype) __m0 >> 31) & __m1) \ + + (((SItype) __m1 >> 31) & __m0)); \ + } while (0) +#define sdiv_qrnnd(q, r, n1, n0, d) \ + do { \ + union {DItype __ll; \ + struct {SItype __l, __h;} __i; \ + } __xx; \ + __xx.__i.__h = n1; __xx.__i.__l = n0; \ + __asm__ ("ediv %3,%2,%0,%1" \ + : "=g" (q), "=g" (r) \ + : "g" (__xx.__ll), "g" (d)); \ + } while (0) +#endif /* __vax__ */ + +#if defined (__z8000__) && W_TYPE_SIZE == 16 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "%0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "%1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ + : "=r" ((unsigned int)(sh)), \ + "=&r" ((unsigned int)(sl)) \ + : "0" ((unsigned int)(ah)), \ + "r" ((unsigned int)(bh)), \ + "1" ((unsigned int)(al)), \ + "rQR" ((unsigned int)(bl))) +#define umul_ppmm(xh, xl, m0, m1) \ + do { \ + union {long int __ll; \ + struct {unsigned int __h, __l;} __i; \ + } __xx; \ + unsigned int __m0 = (m0), __m1 = (m1); \ + __asm__ ("mult %S0,%H3" \ + : "=r" (__xx.__i.__h), \ + "=r" (__xx.__i.__l) \ + : "%1" (__m0), \ + "rQR" (__m1)); \ + (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ + (xh) += ((((signed int) __m0 >> 15) & __m1) \ + + (((signed int) __m1 >> 15) & __m0)); \ + } while (0) +#endif /* __z8000__ */ + +#endif /* __GNUC__ */ + +/* If this machine has no inline assembler, use C macros. */ + +#if !defined (add_ssaaaa) +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) + (bl); \ + (sh) = (ah) + (bh) + (__x < (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (sub_ddmmss) +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + do { \ + UWtype __x; \ + __x = (al) - (bl); \ + (sh) = (ah) - (bh) - (__x > (al)); \ + (sl) = __x; \ + } while (0) +#endif + +#if !defined (umul_ppmm) +#define umul_ppmm(w1, w0, u, v) \ + do { \ + UWtype __x0, __x1, __x2, __x3; \ + UHWtype __ul, __vl, __uh, __vh; \ + \ + __ul = __ll_lowpart (u); \ + __uh = __ll_highpart (u); \ + __vl = __ll_lowpart (v); \ + __vh = __ll_highpart (v); \ + \ + __x0 = (UWtype) __ul * __vl; \ + __x1 = (UWtype) __ul * __vh; \ + __x2 = (UWtype) __uh * __vl; \ + __x3 = (UWtype) __uh * __vh; \ + \ + __x1 += __ll_highpart (__x0);/* this can't give carry */ \ + __x1 += __x2; /* but this indeed can */ \ + if (__x1 < __x2) /* did we get it? */ \ + __x3 += __ll_B; /* yes, add it in the proper pos. */ \ + \ + (w1) = __x3 + __ll_highpart (__x1); \ + (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ + } while (0) +#endif + +#if !defined (__umulsidi3) +#define __umulsidi3(u, v) \ + ({DWunion __w; \ + umul_ppmm (__w.s.high, __w.s.low, u, v); \ + __w.ll; }) +#endif + +/* Define this unconditionally, so it can be used for debugging. */ +#define __udiv_qrnnd_c(q, r, n1, n0, d) \ + do { \ + UWtype __d1, __d0, __q1, __q0; \ + UWtype __r1, __r0, __m; \ + __d1 = __ll_highpart (d); \ + __d0 = __ll_lowpart (d); \ + \ + __r1 = (n1) % __d1; \ + __q1 = (n1) / __d1; \ + __m = (UWtype) __q1 * __d0; \ + __r1 = __r1 * __ll_B | __ll_highpart (n0); \ + if (__r1 < __m) \ + { \ + __q1--, __r1 += (d); \ + if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ + if (__r1 < __m) \ + __q1--, __r1 += (d); \ + } \ + __r1 -= __m; \ + \ + __r0 = __r1 % __d1; \ + __q0 = __r1 / __d1; \ + __m = (UWtype) __q0 * __d0; \ + __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ + if (__r0 < __m) \ + { \ + __q0--, __r0 += (d); \ + if (__r0 >= (d)) \ + if (__r0 < __m) \ + __q0--, __r0 += (d); \ + } \ + __r0 -= __m; \ + \ + (q) = (UWtype) __q1 * __ll_B | __q0; \ + (r) = __r0; \ + } while (0) + +/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through + __udiv_w_sdiv (defined in libgcc or elsewhere). */ +#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) +#define udiv_qrnnd(q, r, nh, nl, d) \ + do { \ + USItype __r; \ + (q) = __udiv_w_sdiv (&__r, nh, nl, d); \ + (r) = __r; \ + } while (0) +#endif + +/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ +#if !defined (udiv_qrnnd) +#define UDIV_NEEDS_NORMALIZATION 1 +#define udiv_qrnnd __udiv_qrnnd_c +#endif + +#if !defined (count_leading_zeros) +extern const UQItype __clz_tab[]; +#define count_leading_zeros(count, x) \ + do { \ + UWtype __xr = (x); \ + UWtype __a; \ + \ + if (W_TYPE_SIZE <= 32) \ + { \ + __a = __xr < ((UWtype)1<<2*__BITS4) \ + ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ + : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ + } \ + else \ + { \ + for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ + if (((__xr >> __a) & 0xff) != 0) \ + break; \ + } \ + \ + (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ + } while (0) +#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif + +#if !defined (count_trailing_zeros) +/* Define count_trailing_zeros using count_leading_zeros. The latter might be + defined in asm, but if it is not, the C version above is good enough. */ +#define count_trailing_zeros(count, x) \ + do { \ + UWtype __ctz_x = (x); \ + UWtype __ctz_c; \ + count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ + (count) = W_TYPE_SIZE - 1 - __ctz_c; \ + } while (0) +#endif + +#ifndef UDIV_NEEDS_NORMALIZATION +#define UDIV_NEEDS_NORMALIZATION 0 +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapper.h +++ linux-2.6.28/ubuntu/ndiswrapper/wrapper.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef WRAPPER_H +#define WRAPPER_H + +extern char *if_name; +extern int proc_uid; +extern int proc_gid; +extern int hangcheck_interval; + +#endif /* WRAPPER_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/win2lin_stubs.S +++ linux-2.6.28/ubuntu/ndiswrapper/win2lin_stubs.S @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2005 Karl Vogel, Giridhar Pemmasani + * + * 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. + * + */ + +#include + +#ifdef CONFIG_X86_64 + +/* +# Windows <---> Linux register usage conversion when calling functions +# V = Volatile +# NV = Non Volatile (needs to be saved) +# +# Win Lin +# --------------------------------------- +# Rax Return V Return V +# Rbx NV NV +# Rcx Arg1 V Arg4 V +# Rdx Arg2 V Arg3 V +# Rsi NV Arg2 V +# Rdi NV Arg1 V +# Rsp NV NV +# Rbp NV NV +# R8 Arg3 V Arg5 V +# R9 Arg4 V Arg6 V +# R10 V V +# R11 V V +# R12 NV NV +# R13 NV NV +# R14 NV NV +# R15 NV NV +# +# In addition, Linux uses %rax to indicate number of SSE registers used +# when variadic functions are called. Since there is no way to obtain this +# from Windows, for now, we just assume this is 0 (hence %rax is cleared). +# +# Windows pushes arguments 5 and higher onto stack in case of integer +# variables and 4 and higher in case of floating point variabes (passed +# in SSE registers). + +In a windows function, the stackframe/registers look like this: + +# 0x0048 .... +# 0x0040 arg8 +# 0x0038 arg7 +# 0x0030 arg6 +# 0x0028 arg5 +# 0x0020 shadow/spill space for arg4 +# 0x0018 shadow/spill space for arg3 +# 0x0010 shadow/spill space for arg2 +# 0x0008 shadow/spill space for arg1 +# 0x0000 ret + +# register spill space is same irrespective of number of arguments - even +# if Windows function takes less than 4 arguments, 32 bytes above return +# address is reserved for the function + +In Linux it should look like: + +# 0x0018 .... +# 0x0010 arg8 +# 0x0008 arg7 +# 0x0000 ret + +*/ + +# +# setup for Windows to Linux function call +# + + .text + +.macro win2lin_prolog + push %rsi + push %rdi +.endm + +.macro win2lin_epilog + pop %rdi + pop %rsi +.endm + +# when Windows function calls Linux function, the function address is in %r10 + +.macro call_lin_func + xor %rax, %rax # rax indicates number of SSE regs + call *%r10 +.endm + +# before prolog, 0(%rsp) is return address, 8(%rsp) would be arg1 +# (but it is in register) and so on, so n'th arg would be at n*8(%rsp) +# for n > 4. But in prolog, we push 2 registers that are non-volaile in +# Windows, but volatile in Linux. So after prolog, args are at (n+2)*8(%rsp) + +#define win2lin_win_arg(n) (n+2)*8(%rsp) + +#define win2lin_arg1 mov %rcx, %rdi +#define win2lin_arg2 mov %rdx, %rsi +#define win2lin_arg3 mov %r8, %rdx +#define win2lin_arg4 mov %r9, %rcx +#define win2lin_arg5 mov win2lin_win_arg(5), %r8 +#define win2lin_arg6 mov win2lin_win_arg(6), %r9 + + .type win2lin0, @function +win2lin0: + win2lin_prolog + call_lin_func + win2lin_epilog + ret + .size win2lin0, .-win2lin0 + + .type win2lin1, @function +win2lin1: + win2lin_prolog + win2lin_arg1 + call_lin_func + win2lin_epilog + ret + .size win2lin1, .-win2lin1 + + .type win2lin2, @function +win2lin2: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + call_lin_func + win2lin_epilog + ret + .size win2lin2, .-win2lin2 + + .type win2lin3, @function +win2lin3: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + call_lin_func + win2lin_epilog + ret + .size win2lin3, .-win2lin3 + + .type win2lin4, @function +win2lin4: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + call_lin_func + win2lin_epilog + ret + .size win2lin4, .-win2lin4 + + .type win2lin5, @function +win2lin5: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + call_lin_func + win2lin_epilog + ret + .size win2lin5, .-win2lin5 + + .type win2lin6, @function +win2lin6: + win2lin_prolog + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + call_lin_func + win2lin_epilog + ret + .size win2lin6, .-win2lin6 + +# Allocate stack frame for Linux arguments before calling function. +# First 6 args are passed through registers, so we need space for 7 and above. +# The arguments should have been copied onto stack already. + +.macro call_lin_func_args n + sub $(\n-6)*8, %rsp + call_lin_func + add $(\n-6)*8, %rsp + .endm + +# m is index of Linux arg required, n is total number of args to function +# After stack frame is allocated, Linux arg 7 should be at 0(%rsp), +# arg 8 should be at 1*8(%rsp) and so on. So Linux arg m should be at (m-7)*8 +# Stack frame starts at -(n-6)*8(%rsp), so before stack frame is allocated +# Linux arg m should be at (6-n+m-7)*8(%rsp) + +#define win2lin_lin_arg(m,n) (m-1-n)*8(%rsp) + + .type win2lin7, @function +win2lin7: + win2lin_prolog + + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + + # copy windows argument 7 onto stack for Linux function + mov win2lin_win_arg(7), %r11 + mov %r11, win2lin_lin_arg(7,7) + + call_lin_func_args(7) + win2lin_epilog + ret + .size win2lin7, .-win2lin7 + + .type win2lin8, @function +win2lin8: + win2lin_prolog + + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + + # copy windows arguments 7 and 8 onto stack for Linux function + mov win2lin_win_arg(7), %r11 + mov %r11, win2lin_lin_arg(7,8) + mov win2lin_win_arg(8), %r11 + mov %r11, win2lin_lin_arg(8,8) + + call_lin_func_args(8) + win2lin_epilog + ret + .size win2lin8, .-win2lin8 + + .type win2lin9, @function +win2lin9: +win2lin10: +win2lin11: +win2lin12: + win2lin_prolog + + # since we destroy rsi and rdi here, first copy windows + # arguments 7 through 12 onto stack for Linux function + mov %rcx, %r11 # save rcx + lea win2lin_win_arg(7), %rsi # source (windows arg 7 and up) + lea win2lin_lin_arg(7,12), %rdi # = destination + mov $6, %rcx # 6 arguments + rep + movsq + mov %r11, %rcx # restore rcx + + win2lin_arg1 + win2lin_arg2 + win2lin_arg3 + win2lin_arg4 + win2lin_arg5 + win2lin_arg6 + + call_lin_func_args(12) + win2lin_epilog + ret + .size win2lin9, .-win2lin9 + +#define win2lin(name, argc) \ +ENTRY(win2lin_ ## name ## _ ## argc) \ + lea name(%rip), %r10 ; \ + jmp win2lin ## argc + +#include "win2lin_stubs.h" + +#endif // CONFIG_X86_64 --- linux-2.6.28.orig/ubuntu/ndiswrapper/pnp.h +++ linux-2.6.28/ubuntu/ndiswrapper/pnp.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005 Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _PNP_H_ +#define _PNP_H_ + +#include "ntoskernel.h" +#include "ndis.h" +#include "wrapndis.h" + +NTSTATUS pnp_start_device(struct wrap_device *wd); +NTSTATUS pnp_stop_device(struct wrap_device *wd); +NTSTATUS pnp_remove_device(struct wrap_device *wd); + +int wrap_pnp_start_pci_device(struct pci_dev *pdev, + const struct pci_device_id *ent); +void __devexit wrap_pnp_remove_pci_device(struct pci_dev *pdev); +int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state); +int wrap_pnp_resume_pci_device(struct pci_dev *pdev); + +#ifdef ENABLE_USB +int wrap_pnp_start_usb_device(struct usb_interface *intf, + const struct usb_device_id *usb_id); +void wrap_pnp_remove_usb_device(struct usb_interface *intf); +int wrap_pnp_suspend_usb_device(struct usb_interface *intf, + pm_message_t state); +int wrap_pnp_resume_usb_device(struct usb_interface *intf); +#endif + +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/loader.h +++ linux-2.6.28/ubuntu/ndiswrapper/loader.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _LOADER_H_ +#define _LOADER_H_ + +#include "ndiswrapper.h" + +#ifndef __KERNEL__ +#define __user +#endif + +struct load_driver_file { + char driver_name[MAX_DRIVER_NAME_LEN]; + char name[MAX_DRIVER_NAME_LEN]; + size_t size; + void __user *data; +}; + +struct load_device_setting { + char name[MAX_SETTING_NAME_LEN]; + char value[MAX_SETTING_VALUE_LEN]; +}; + +struct load_device { + int bus; + int vendor; + int device; + int subvendor; + int subdevice; + char conf_file_name[MAX_DRIVER_NAME_LEN]; + char driver_name[MAX_DRIVER_NAME_LEN]; +}; + +struct load_devices { + int count; + struct load_device *devices; +}; + +struct load_driver { + char name[MAX_DRIVER_NAME_LEN]; + char conf_file_name[MAX_DRIVER_NAME_LEN]; + unsigned int num_sys_files; + struct load_driver_file sys_files[MAX_DRIVER_PE_IMAGES]; + unsigned int num_settings; + struct load_device_setting settings[MAX_DEVICE_SETTINGS]; + unsigned int num_bin_files; + struct load_driver_file bin_files[MAX_DRIVER_BIN_FILES]; +}; + +#define WRAP_IOCTL_LOAD_DEVICE _IOW(('N' + 'd' + 'i' + 'S'), 0, \ + struct load_device *) +#define WRAP_IOCTL_LOAD_DRIVER _IOW(('N' + 'd' + 'i' + 'S'), 1, \ + struct load_driver *) +#define WRAP_IOCTL_LOAD_BIN_FILE _IOW(('N' + 'd' + 'i' + 'S'), 2, \ + struct load_driver_file *) + +#define WRAP_CMD_LOAD_DEVICE "load_device" +#define WRAP_CMD_LOAD_DRIVER "load_driver" +#define WRAP_CMD_LOAD_BIN_FILE "load_bin_file" + +int loader_init(void); +void loader_exit(void); + +#ifdef __KERNEL__ +struct wrap_device *load_wrap_device(struct load_device *load_device); +struct wrap_driver *load_wrap_driver(struct wrap_device *device); +struct wrap_bin_file *get_bin_file(char *bin_file_name); +void free_bin_file(struct wrap_bin_file *bin_file); +void unload_wrap_driver(struct wrap_driver *driver); +void unload_wrap_device(struct wrap_device *wd); +struct wrap_device *get_wrap_device(void *dev, int bus_type); + +extern struct semaphore loader_mutex; +#endif + +#endif /* LOADER_H */ + --- linux-2.6.28.orig/ubuntu/ndiswrapper/mkexport.sh +++ linux-2.6.28/ubuntu/ndiswrapper/mkexport.sh @@ -0,0 +1,42 @@ +#! /bin/sh + +# Generate exports symbol table from C files + +input="$1" +output="$2" +exports=$(basename "$output" .h) +exec >"$output" + +echo "/* automatically generated from src */"; + +sed -n -e '/^\(wstdcall\|wfastcall\|noregparm\|__attribute__\)/{ +:more +N +s/\([^{]\)$/\1/ +t more +s/\n{$/;/ +p +}' $input + +echo "#ifdef CONFIG_X86_64"; + +sed -n \ + -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +'WIN_FUNC_DECL(\1, \2)/p' \ + -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +'WIN_FUNC_DECL(\1, \2)/p' $input | sort -u + +echo "#endif" +echo "extern struct wrap_export $exports[];" +echo "struct wrap_export $exports[] = {" + +sed -n \ + -e 's/.*WIN_FUNC(_win_\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +' WIN_WIN_SYMBOL(\1, \2),/p' \ + -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/'\ +' WIN_SYMBOL(\1, \2),/p' \ + -e 's/.*WIN_SYMBOL_MAP(\("[^"]\+"\)[ ,\n]\+\([^)]\+\)).*/'\ +' {\1, (generic_func)\2},/p' $input | sort -u + +echo " {NULL, NULL}" +echo "};" --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapndis.h +++ linux-2.6.28/ubuntu/ndiswrapper/wrapndis.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _WRAPNDIS_H_ +#define _WRAPNDIS_H_ + +#include "ndis.h" +#include "pnp.h" + +int wrapndis_init(void); +void wrapndis_exit(void); + +NDIS_STATUS mp_reset(struct ndis_device *wnd); + +NDIS_STATUS mp_request(enum ndis_request_type request, + struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen, ULONG *written, ULONG *needed); + +static inline NDIS_STATUS mp_query_info(struct ndis_device *wnd, + ndis_oid oid, void *buf, ULONG buflen, + ULONG *written, ULONG *needed) +{ + return mp_request(NdisRequestQueryInformation, wnd, oid, + buf, buflen, written, needed); +} + +static inline NDIS_STATUS mp_set_info(struct ndis_device *wnd, + ndis_oid oid, void *buf, ULONG buflen, + ULONG *written, ULONG *needed) +{ + return mp_request(NdisRequestSetInformation, wnd, oid, + buf, buflen, written, needed); +} + +static inline NDIS_STATUS mp_query(struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen) +{ + return mp_request(NdisRequestQueryInformation, wnd, oid, + buf, buflen, NULL, NULL); +} + +static inline NDIS_STATUS mp_query_int(struct ndis_device *wnd, + ndis_oid oid, ULONG *data) +{ + return mp_request(NdisRequestQueryInformation, wnd, oid, + data, sizeof(ULONG), NULL, NULL); +} + +static inline NDIS_STATUS mp_set(struct ndis_device *wnd, ndis_oid oid, + void *buf, ULONG buflen) +{ + return mp_request(NdisRequestSetInformation, wnd, oid, + buf, buflen, NULL, NULL); +} + +static inline NDIS_STATUS mp_set_int(struct ndis_device *wnd, + ndis_oid oid, ULONG data) +{ + return mp_request(NdisRequestSetInformation, wnd, oid, + &data, sizeof(ULONG), NULL, NULL); +} + +void free_tx_packet(struct ndis_device *wnd, struct ndis_packet *packet, + NDIS_STATUS status); +int init_ndis_driver(struct driver_object *drv_obj); +NDIS_STATUS ndis_reinit(struct ndis_device *wnd); + +void hangcheck_add(struct ndis_device *wnd); +void hangcheck_del(struct ndis_device *wnd); + +driver_dispatch_t winNdisDispatchPnp; +driver_dispatch_t winNdisDispatchPower; +driver_dispatch_t winNdisDispatchDeviceControl; + +struct iw_statistics *get_iw_stats(struct net_device *dev); + +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapper.c +++ linux-2.6.28/ubuntu/ndiswrapper/wrapper.c @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ndis.h" +#include "iw_ndis.h" +#include "loader.h" +#include "pnp.h" +#include "wrapper.h" + +char *if_name = "wlan%d"; +int proc_uid, proc_gid; +int hangcheck_interval; +static char *utils_version = UTILS_VERSION; + +#if defined(DEBUG) && (DEBUG > 0) +int debug = DEBUG; +#else +int debug = 0; +#endif + +WRAP_MODULE_PARM_STRING(if_name, 0400); +MODULE_PARM_DESC(if_name, "Network interface name or template " + "(default: wlan%d)"); +WRAP_MODULE_PARM_INT(proc_uid, 0600); +MODULE_PARM_DESC(proc_uid, "The uid of the files created in /proc " + "(default: 0)."); +WRAP_MODULE_PARM_INT(proc_gid, 0600); +MODULE_PARM_DESC(proc_gid, "The gid of the files created in /proc " + "(default: 0)."); +WRAP_MODULE_PARM_INT(debug, 0600); +MODULE_PARM_DESC(debug, "debug level"); + +/* 0 - default value provided by NDIS driver, + * positive value - force hangcheck interval to that many seconds + * negative value - disable hangcheck + */ +WRAP_MODULE_PARM_INT(hangcheck_interval, 0600); +MODULE_PARM_DESC(hangcheck_interval, "The interval, in seconds, for checking" + " if driver is hung. (default: 0)"); + +WRAP_MODULE_PARM_STRING(utils_version, 0400); +MODULE_PARM_DESC(utils_version, "Compatible version of utils " + "(read only: " UTILS_VERSION ")"); + +MODULE_AUTHOR("ndiswrapper team "); +#ifdef MODULE_DESCRIPTION +MODULE_DESCRIPTION("NDIS wrapper driver"); +#endif +#ifdef MODULE_VERSION +MODULE_VERSION(DRIVER_VERSION); +#endif +MODULE_LICENSE("GPL"); + +static void module_cleanup(void) +{ + loader_exit(); +#ifdef ENABLE_USB + usb_exit(); +#endif + + wrap_procfs_remove(); + wrapndis_exit(); + ndis_exit(); + rtl_exit(); + crt_exit(); + ntoskernel_exit(); + wrapmem_exit(); +} + +static int __init wrapper_init(void) +{ + printk(KERN_INFO "%s version %s loaded (smp=%s, preempt=%s)\n", + DRIVER_NAME, DRIVER_VERSION, +#ifdef CONFIG_SMP + "yes" +#else + "no" +#endif + , +#ifdef CONFIG_PREEMPT_RT + "rt" +#elif defined(CONFIG_PREEMPT) + "yes" +#else + "no" +#endif + ); + + if (wrapmem_init() || ntoskernel_init() || crt_init() || + rtl_init() || ndis_init() || wrapndis_init() || +#ifdef ENABLE_USB + usb_init() || +#endif + wrap_procfs_init() || loader_init()) { + module_cleanup(); + ERROR("%s: initialization failed", DRIVER_NAME); + return -EINVAL; + } + EXIT1(return 0); +} + +static void __exit wrapper_exit(void) +{ + ENTER1(""); + module_cleanup(); +} + +module_init(wrapper_init); +module_exit(wrapper_exit); --- linux-2.6.28.orig/ubuntu/ndiswrapper/Kconfig +++ linux-2.6.28/ubuntu/ndiswrapper/Kconfig @@ -0,0 +1,4 @@ +config NDISWRAPPER + tristate "Wrapper for Windows NDIS network drivers" + depends on NET + default m --- linux-2.6.28.orig/ubuntu/ndiswrapper/ndis.c +++ linux-2.6.28/ubuntu/ndiswrapper/ndis.c @@ -0,0 +1,2988 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ndis.h" +#include "iw_ndis.h" +#include "wrapndis.h" +#include "pnp.h" +#include "loader.h" +#include +#include +#include "ndis_exports.h" + +#define MAX_ALLOCATED_NDIS_PACKETS TX_RING_SIZE +#define MAX_ALLOCATED_NDIS_BUFFERS TX_RING_SIZE + +static void ndis_worker(worker_param_t dummy); +static work_struct_t ndis_work; +static struct nt_list ndis_work_list; +static spinlock_t ndis_work_list_lock; + +workqueue_struct_t *ndis_wq; +static struct nt_thread *ndis_worker_thread; + +static void *ndis_get_routine_address(char *name); + +wstdcall void WIN_FUNC(NdisInitializeWrapper,4) + (void **driver_handle, struct driver_object *driver, + struct unicode_string *reg_path, void *unused) +{ + ENTER1("handle: %p, driver: %p", driver_handle, driver); + *driver_handle = driver; + EXIT1(return); +} + +wstdcall void WIN_FUNC(NdisTerminateWrapper,2) + (struct device_object *dev_obj, void *system_specific) +{ + EXIT1(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterMiniport,3) + (struct driver_object *drv_obj, struct miniport *mp, UINT length) +{ + int min_length; + struct wrap_driver *wrap_driver; + struct ndis_driver *ndis_driver; + + min_length = ((char *)&mp->co_create_vc) - ((char *)mp); + + ENTER1("%p %p %d", drv_obj, mp, length); + + if (mp->major_version < 4) { + ERROR("Driver is using ndis version %d which is too old.", + mp->major_version); + EXIT1(return NDIS_STATUS_BAD_VERSION); + } + + if (length < min_length) { + ERROR("Characteristics length %d is too small", length); + EXIT1(return NDIS_STATUS_BAD_CHARACTERISTICS); + } + + TRACE1("%d.%d, %d, %u", mp->major_version, mp->minor_version, length, + (u32)sizeof(struct miniport)); + wrap_driver = IoGetDriverObjectExtension(drv_obj, + (void *)WRAP_DRIVER_CLIENT_ID); + if (!wrap_driver) { + ERROR("couldn't get wrap_driver"); + EXIT1(return NDIS_STATUS_RESOURCES); + } + if (IoAllocateDriverObjectExtension( + drv_obj, (void *)NDIS_DRIVER_CLIENT_ID, + sizeof(*ndis_driver), (void **)&ndis_driver) != + STATUS_SUCCESS) + EXIT1(return NDIS_STATUS_RESOURCES); + wrap_driver->ndis_driver = ndis_driver; + TRACE1("driver: %p", ndis_driver); + memcpy(&ndis_driver->mp, mp, min_t(int, sizeof(*mp), length)); + + DBG_BLOCK(2) { + int i; + void **func; + char *mp_funcs[] = { + "queryinfo", "reconfig", "reset", "send", "setinfo", + "tx_data", "return_packet", "send_packets", + "alloc_complete", "co_create_vc", "co_delete_vc", + "co_activate_vc", "co_deactivate_vc", + "co_send_packets", "co_request", "cancel_send_packets", + "pnp_event_notify", "shutdown", + }; + func = (void **)&ndis_driver->mp.queryinfo; + for (i = 0; i < (sizeof(mp_funcs) / sizeof(mp_funcs[0])); i++) + TRACE2("function '%s' is at %p", mp_funcs[i], func[i]); + } + EXIT1(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterDevice,6) + (struct driver_object *drv_obj, struct unicode_string *dev_name, + struct unicode_string *link, void **funcs, + struct device_object **dev_obj, void **dev_obj_handle) +{ + NTSTATUS status; + struct device_object *tmp; + int i; + + ENTER1("%p, %p, %p", drv_obj, dev_name, link); + status = IoCreateDevice(drv_obj, 0, dev_name, FILE_DEVICE_NETWORK, 0, + FALSE, &tmp); + + if (status != STATUS_SUCCESS) + EXIT1(return NDIS_STATUS_RESOURCES); + if (link) + status = IoCreateSymbolicLink(link, dev_name); + if (status != STATUS_SUCCESS) { + IoDeleteDevice(tmp); + EXIT1(return NDIS_STATUS_RESOURCES); + } + + *dev_obj = tmp; + *dev_obj_handle = *dev_obj; + for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) + if (funcs[i] && i != IRP_MJ_PNP && i != IRP_MJ_POWER) { + drv_obj->major_func[i] = funcs[i]; + TRACE1("mj_fn for 0x%x is at %p", i, funcs[i]); + } + EXIT1(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMDeregisterDevice,1) + (struct device_object *dev_obj) +{ + ENTER2("%p", dev_obj); + IoDeleteDevice(dev_obj); + return NDIS_STATUS_SUCCESS; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemoryWithTag,3) + (void **dest, UINT length, ULONG tag) +{ + void *addr; + + assert_irql(_irql_ <= DISPATCH_LEVEL); + addr = ExAllocatePoolWithTag(NonPagedPool, length, tag); + TRACE4("%p", addr); + if (addr) { + *dest = addr; + EXIT4(return NDIS_STATUS_SUCCESS); + } else + EXIT4(return NDIS_STATUS_FAILURE); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisAllocateMemory,4) + (void **dest, UINT length, UINT flags, NDIS_PHY_ADDRESS highest_address) +{ + return NdisAllocateMemoryWithTag(dest, length, 0); +} + +/* length_tag is either length or tag, depending on if + * NdisAllocateMemory or NdisAllocateMemoryTag is used to allocate + * memory */ +wstdcall void WIN_FUNC(NdisFreeMemory,3) + (void *addr, UINT length_tag, UINT flags) +{ + TRACE4("%p", addr); + ExFreePool(addr); +} + +noregparm void WIN_FUNC(NdisWriteErrorLogEntry,12) + (struct driver_object *drv_obj, ULONG error, ULONG count, ...) +{ + va_list args; + int i; + ULONG code; + + va_start(args, count); + ERROR("log: %08X, count: %d, return_address: %p", + error, count, __builtin_return_address(0)); + for (i = 0; i < count; i++) { + code = va_arg(args, ULONG); + ERROR("code: 0x%x", code); + } + va_end(args); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenConfiguration,3) + (NDIS_STATUS *status, struct ndis_mp_block **conf_handle, + struct ndis_mp_block *handle) +{ + ENTER2("%p", conf_handle); + *conf_handle = handle; + *status = NDIS_STATUS_SUCCESS; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenProtocolConfiguration,3) + (NDIS_STATUS *status, void **confhandle, + struct unicode_string *section) +{ + ENTER2("%p", confhandle); + *status = NDIS_STATUS_SUCCESS; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByName,4) + (NDIS_STATUS *status, void *handle, + struct unicode_string *key, void **subkeyhandle) +{ + struct ansi_string ansi; + ENTER2(""); + if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE) == STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + *subkeyhandle = handle; + *status = NDIS_STATUS_SUCCESS; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisOpenConfigurationKeyByIndex,5) + (NDIS_STATUS *status, void *handle, ULONG index, + struct unicode_string *key, void **subkeyhandle) +{ + ENTER2("%u", index); +// *subkeyhandle = handle; + *status = NDIS_STATUS_FAILURE; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisCloseConfiguration,1) + (void *handle) +{ + /* instead of freeing all configuration parameters as we are + * supposed to do here, we free them when the device is + * removed */ + ENTER2("%p", handle); + return; +} + +wstdcall void WIN_FUNC(NdisOpenFile,5) + (NDIS_STATUS *status, struct wrap_bin_file **file, + UINT *filelength, struct unicode_string *filename, + NDIS_PHY_ADDRESS highest_address) +{ + struct ansi_string ansi; + struct wrap_bin_file *bin_file; + + ENTER2("%p, %d, %llx, %p", status, *filelength, highest_address, *file); + if (RtlUnicodeStringToAnsiString(&ansi, filename, TRUE) != + STATUS_SUCCESS) { + *status = NDIS_STATUS_RESOURCES; + EXIT2(return); + } + TRACE2("%s", ansi.buf); + bin_file = get_bin_file(ansi.buf); + if (bin_file) { + *file = bin_file; + *filelength = bin_file->size; + *status = NDIS_STATUS_SUCCESS; + } else + *status = NDIS_STATUS_FILE_NOT_FOUND; + + RtlFreeAnsiString(&ansi); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisMapFile,3) + (NDIS_STATUS *status, void **mappedbuffer, struct wrap_bin_file *file) +{ + ENTER2("%p", file); + + if (!file) { + *status = NDIS_STATUS_ALREADY_MAPPED; + EXIT2(return); + } + + *status = NDIS_STATUS_SUCCESS; + *mappedbuffer = file->data; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisUnmapFile,1) + (struct wrap_bin_file *file) +{ + ENTER2("%p", file); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisCloseFile,1) + (struct wrap_bin_file *file) +{ + ENTER2("%p", file); + free_bin_file(file); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisGetSystemUpTime,1) + (ULONG *ms) +{ + *ms = 1000 * jiffies / HZ; + EXIT5(return); +} + +wstdcall ULONG WIN_FUNC(NDIS_BUFFER_TO_SPAN_PAGES,1) + (ndis_buffer *buffer) +{ + ULONG n, length; + + if (buffer == NULL) + EXIT2(return 0); + if (MmGetMdlByteCount(buffer) == 0) + EXIT2(return 1); + + length = MmGetMdlByteCount(buffer); + n = SPAN_PAGES(MmGetMdlVirtualAddress(buffer), length); + TRACE4("%p, %p, %d, %d", buffer->startva, buffer->mappedsystemva, + length, n); + EXIT3(return n); +} + +wstdcall void WIN_FUNC(NdisGetBufferPhysicalArraySize,2) + (ndis_buffer *buffer, UINT *arraysize) +{ + ENTER3("%p", buffer); + *arraysize = NDIS_BUFFER_TO_SPAN_PAGES(buffer); + EXIT3(return); +} + +static struct ndis_configuration_parameter * +ndis_encode_setting(struct wrap_device_setting *setting, + enum ndis_parameter_type type) +{ + struct ansi_string ansi; + struct ndis_configuration_parameter *param; + + param = setting->encoded; + if (param) { + if (param->type == type) + EXIT2(return param); + if (param->type == NdisParameterString) + RtlFreeUnicodeString(¶m->data.string); + setting->encoded = NULL; + } else + param = ExAllocatePoolWithTag(NonPagedPool, sizeof(*param), 0); + if (!param) { + ERROR("couldn't allocate memory"); + return NULL; + } + switch(type) { + case NdisParameterInteger: + param->data.integer = simple_strtol(setting->value, NULL, 0); + TRACE2("0x%x", (ULONG)param->data.integer); + break; + case NdisParameterHexInteger: + param->data.integer = simple_strtol(setting->value, NULL, 16); + TRACE2("0x%x", (ULONG)param->data.integer); + break; + case NdisParameterString: + RtlInitAnsiString(&ansi, setting->value); + TRACE2("'%s'", ansi.buf); + if (RtlAnsiStringToUnicodeString(¶m->data.string, + &ansi, TRUE)) { + ExFreePool(param); + EXIT2(return NULL); + } + break; + case NdisParameterBinary: + param->data.integer = simple_strtol(setting->value, NULL, 2); + TRACE2("0x%x", (ULONG)param->data.integer); + break; + default: + ERROR("unknown type: %d", type); + ExFreePool(param); + return NULL; + } + param->type = type; + setting->encoded = param; + EXIT2(return param); +} + +static int ndis_decode_setting(struct wrap_device_setting *setting, + struct ndis_configuration_parameter *param) +{ + struct ansi_string ansi; + struct ndis_configuration_parameter *prev; + + ENTER2("%p, %p", setting, param); + prev = setting->encoded; + if (prev && prev->type == NdisParameterString) { + RtlFreeUnicodeString(&prev->data.string); + setting->encoded = NULL; + } + switch(param->type) { + case NdisParameterInteger: + snprintf(setting->value, sizeof(u32), "%u", + param->data.integer); + setting->value[sizeof(ULONG)] = 0; + break; + case NdisParameterHexInteger: + snprintf(setting->value, sizeof(u32), "%x", + param->data.integer); + setting->value[sizeof(ULONG)] = 0; + break; + case NdisParameterString: + ansi.buf = setting->value; + ansi.max_length = MAX_SETTING_VALUE_LEN; + if ((RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, + FALSE) != STATUS_SUCCESS) + || ansi.length >= MAX_SETTING_VALUE_LEN) { + EXIT1(return -1); + } + if (ansi.length == ansi.max_length) + ansi.length--; + setting->value[ansi.length] = 0; + break; + case NdisParameterBinary: + snprintf(setting->value, sizeof(u32), "%u", + param->data.integer); + setting->value[sizeof(ULONG)] = 0; + break; + default: + TRACE2("unknown setting type: %d", param->type); + return -1; + } + TRACE2("setting changed %s='%s', %d", setting->name, setting->value, + ansi.length); + return 0; +} + +static int read_setting(struct nt_list *setting_list, char *keyname, int length, + struct ndis_configuration_parameter **param, + enum ndis_parameter_type type) +{ + struct wrap_device_setting *setting; + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_entry(setting, setting_list, list) { + if (strnicmp(keyname, setting->name, length) == 0) { + TRACE2("setting %s='%s'", keyname, setting->value); + up(&loader_mutex); + *param = ndis_encode_setting(setting, type); + if (*param) + EXIT2(return 0); + else + EXIT2(return -1); + } + } + up(&loader_mutex); + EXIT2(return -1); +} + +wstdcall void WIN_FUNC(NdisReadConfiguration,5) + (NDIS_STATUS *status, struct ndis_configuration_parameter **param, + struct ndis_mp_block *nmb, struct unicode_string *key, + enum ndis_parameter_type type) +{ + struct ansi_string ansi; + int ret; + + ENTER2("nmb: %p", nmb); + ret = RtlUnicodeStringToAnsiString(&ansi, key, TRUE); + if (ret != STATUS_SUCCESS || ansi.buf == NULL) { + *param = NULL; + *status = NDIS_STATUS_FAILURE; + RtlFreeAnsiString(&ansi); + EXIT2(return); + } + TRACE2("%d, %s", type, ansi.buf); + + if (read_setting(&nmb->wnd->wd->settings, ansi.buf, + ansi.length, param, type) == 0 || + read_setting(&nmb->wnd->wd->driver->settings, ansi.buf, + ansi.length, param, type) == 0) + *status = NDIS_STATUS_SUCCESS; + else { + TRACE2("setting %s not found (type:%d)", ansi.buf, type); + *status = NDIS_STATUS_FAILURE; + } + RtlFreeAnsiString(&ansi); + EXIT2(return); + +} + +wstdcall void WIN_FUNC(NdisWriteConfiguration,4) + (NDIS_STATUS *status, struct ndis_mp_block *nmb, + struct unicode_string *key, struct ndis_configuration_parameter *param) +{ + struct ansi_string ansi; + char *keyname; + struct wrap_device_setting *setting; + + ENTER2("nmb: %p", nmb); + if (RtlUnicodeStringToAnsiString(&ansi, key, TRUE)) { + *status = NDIS_STATUS_FAILURE; + EXIT2(return); + } + keyname = ansi.buf; + TRACE2("%s", keyname); + + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_entry(setting, &nmb->wnd->wd->settings, list) { + if (strnicmp(keyname, setting->name, ansi.length) == 0) { + up(&loader_mutex); + if (ndis_decode_setting(setting, param)) + *status = NDIS_STATUS_FAILURE; + else + *status = NDIS_STATUS_SUCCESS; + RtlFreeAnsiString(&ansi); + EXIT2(return); + } + } + up(&loader_mutex); + setting = kzalloc(sizeof(*setting), GFP_KERNEL); + if (setting) { + if (ansi.length == ansi.max_length) + ansi.length--; + memcpy(setting->name, keyname, ansi.length); + setting->name[ansi.length] = 0; + if (ndis_decode_setting(setting, param)) + *status = NDIS_STATUS_FAILURE; + else { + *status = NDIS_STATUS_SUCCESS; + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + InsertTailList(&nmb->wnd->wd->settings, &setting->list); + up(&loader_mutex); + } + } else + *status = NDIS_STATUS_RESOURCES; + + RtlFreeAnsiString(&ansi); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisReadNetworkAddress,4) + (NDIS_STATUS *status, void **addr, UINT *len, + struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + struct ndis_configuration_parameter *param; + struct unicode_string key; + struct ansi_string ansi; + typeof(wnd->mac) mac; + int i, ret; + + ENTER2("%p", nmb); + RtlInitAnsiString(&ansi, "NetworkAddress"); + *status = NDIS_STATUS_FAILURE; + if (RtlAnsiStringToUnicodeString(&key, &ansi, TRUE) != STATUS_SUCCESS) + EXIT1(return); + + NdisReadConfiguration(&ret, ¶m, nmb, &key, NdisParameterString); + RtlFreeUnicodeString(&key); + if (ret != NDIS_STATUS_SUCCESS) + EXIT1(return); + ret = RtlUnicodeStringToAnsiString(&ansi, ¶m->data.string, TRUE); + if (ret != STATUS_SUCCESS) + EXIT1(return); + + i = 0; + if (ansi.length >= 2 * sizeof(mac)) { + for (i = 0; i < sizeof(mac); i++) { + char c[3]; + int x; + c[0] = ansi.buf[i*2]; + c[1] = ansi.buf[i*2+1]; + c[2] = 0; + ret = sscanf(c, "%x", &x); + if (ret != 1) + break; + mac[i] = x; + } + } + TRACE2("%s, %d, " MACSTR, ansi.buf, i, MAC2STR(mac)); + RtlFreeAnsiString(&ansi); + if (i == sizeof(mac)) { + memcpy(wnd->mac, mac, sizeof(wnd->mac)); + *len = sizeof(mac); + *addr = wnd->mac; + *status = NDIS_STATUS_SUCCESS; + } + EXIT1(return); +} + +wstdcall void WIN_FUNC(NdisInitializeString,2) + (struct unicode_string *dest, UCHAR *src) +{ + struct ansi_string ansi; + + ENTER2(""); + if (src == NULL) { + dest->length = dest->max_length = 0; + dest->buf = NULL; + } else { + RtlInitAnsiString(&ansi, src); + /* the string is freed with NdisFreeMemory */ + RtlAnsiStringToUnicodeString(dest, &ansi, TRUE); + } + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisInitAnsiString,2) + (struct ansi_string *dst, CHAR *src) +{ + RtlInitAnsiString(dst, src); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisInitUnicodeString,2) + (struct unicode_string *dest, const wchar_t *src) +{ + RtlInitUnicodeString(dest, src); + return; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisAnsiStringToUnicodeString,2) + (struct unicode_string *dst, struct ansi_string *src) +{ + ENTER2(""); + if (dst == NULL || src == NULL) + EXIT2(return NDIS_STATUS_FAILURE); + if (RtlAnsiStringToUnicodeString(dst, src, FALSE) == STATUS_SUCCESS) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisUnicodeStringToAnsiString,2) + (struct ansi_string *dst, struct unicode_string *src) +{ + ENTER2(""); + if (dst == NULL || src == NULL) + EXIT2(return NDIS_STATUS_FAILURE); + if (RtlUnicodeStringToAnsiString(dst, src, FALSE) == STATUS_SUCCESS) + return NDIS_STATUS_SUCCESS; + else + return NDIS_STATUS_FAILURE; +} + +wstdcall NTSTATUS WIN_FUNC(NdisUpcaseUnicodeString,2) + (struct unicode_string *dst, struct unicode_string *src) +{ + EXIT2(return RtlUpcaseUnicodeString(dst, src, FALSE)); +} + +wstdcall void WIN_FUNC(NdisMSetAttributesEx,5) + (struct ndis_mp_block *nmb, void *mp_ctx, + UINT hangcheck_interval, UINT attributes, ULONG adaptertype) +{ + struct ndis_device *wnd; + + ENTER1("%p, %p, %d, %08x, %d", nmb, mp_ctx, hangcheck_interval, + attributes, adaptertype); + wnd = nmb->wnd; + nmb->mp_ctx = mp_ctx; + wnd->attributes = attributes; + + if ((attributes & NDIS_ATTRIBUTE_BUS_MASTER) && + wrap_is_pci_bus(wnd->wd->dev_bus)) + pci_set_master(wnd->wd->pci.pdev); + + if (hangcheck_interval > 0) + wnd->hangcheck_interval = 2 * hangcheck_interval * HZ; + else + wnd->hangcheck_interval = 2 * HZ; + + EXIT1(return); +} + +wstdcall ULONG WIN_FUNC(NdisReadPciSlotInformation,5) + (struct ndis_mp_block *nmb, ULONG slot, + ULONG offset, char *buf, ULONG len) +{ + struct wrap_device *wd = nmb->wnd->wd; + ULONG i; + for (i = 0; i < len; i++) + if (pci_read_config_byte(wd->pci.pdev, offset + i, &buf[i]) != + PCIBIOS_SUCCESSFUL) + break; + DBG_BLOCK(2) { + if (i != len) + WARNING("%u, %u", i, len); + } + return i; +} + +wstdcall ULONG WIN_FUNC(NdisImmediateReadPciSlotInformation,5) + (struct ndis_mp_block *nmb, ULONG slot, + ULONG offset, char *buf, ULONG len) +{ + return NdisReadPciSlotInformation(nmb, slot, offset, buf, len); +} + +wstdcall ULONG WIN_FUNC(NdisWritePciSlotInformation,5) + (struct ndis_mp_block *nmb, ULONG slot, + ULONG offset, char *buf, ULONG len) +{ + struct wrap_device *wd = nmb->wnd->wd; + ULONG i; + for (i = 0; i < len; i++) + if (pci_write_config_byte(wd->pci.pdev, offset + i, buf[i]) != + PCIBIOS_SUCCESSFUL) + break; + DBG_BLOCK(2) { + if (i != len) + WARNING("%u, %u", i, len); + } + return i; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterIoPortRange,4) + (void **virt, struct ndis_mp_block *nmb, UINT start, UINT len) +{ + ENTER3("%08x %08x", start, len); + *virt = (void *)(ULONG_PTR)start; + return NDIS_STATUS_SUCCESS; +} + +wstdcall void WIN_FUNC(NdisMDeregisterIoPortRange,4) + (struct ndis_mp_block *nmb, UINT start, UINT len, void* virt) +{ + ENTER1("%08x %08x", start, len); +} + +wstdcall void WIN_FUNC(NdisReadPortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char *data) +{ + *data = inb(port); +} + +wstdcall void WIN_FUNC(NdisImmediateReadPortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char *data) +{ + *data = inb(port); +} + +wstdcall void WIN_FUNC(NdisWritePortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char data) +{ + outb(data, port); +} + +wstdcall void WIN_FUNC(NdisImmediateWritePortUchar,3) + (struct ndis_mp_block *nmb, ULONG port, char data) +{ + outb(data, port); +} + +wstdcall void WIN_FUNC(NdisMQueryAdapterResources,4) + (NDIS_STATUS *status, struct ndis_mp_block *nmb, + NDIS_RESOURCE_LIST *resource_list, UINT *size) +{ + struct ndis_device *wnd = nmb->wnd; + NDIS_RESOURCE_LIST *list; + UINT resource_length; + + list = &wnd->wd->resource_list->list->partial_resource_list; + resource_length = sizeof(struct cm_partial_resource_list) + + sizeof(struct cm_partial_resource_descriptor) * + (list->count - 1); + TRACE2("%p, %p,%d (%d), %p %d %d", wnd, resource_list, *size, + resource_length, &list->partial_descriptors[list->count-1], + list->partial_descriptors[list->count-1].u.interrupt.level, + list->partial_descriptors[list->count-1].u.interrupt.vector); + if (*size < sizeof(*list)) { + *size = resource_length; + *status = NDIS_STATUS_BUFFER_TOO_SHORT; + } else { + ULONG count; + if (*size >= resource_length) { + *size = resource_length; + count = list->count; + } else { + UINT n = sizeof(*list); + count = 1; + while (count++ < list->count && n < *size) + n += sizeof(list->partial_descriptors); + *size = n; + } + memcpy(resource_list, list, *size); + resource_list->count = count; + *status = NDIS_STATUS_SUCCESS; + } + EXIT2(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMPciAssignResources,3) + (struct ndis_mp_block *nmb, ULONG slot_number, + NDIS_RESOURCE_LIST **resources) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER2("%p, %p", wnd, wnd->wd->resource_list); + *resources = &wnd->wd->resource_list->list->partial_resource_list; + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMMapIoSpace,4) + (void __iomem **virt, struct ndis_mp_block *nmb, + NDIS_PHY_ADDRESS phy_addr, UINT len) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER2("%Lx, %d", phy_addr, len); + *virt = MmMapIoSpace(phy_addr, len, MmCached); + if (*virt == NULL) { + ERROR("ioremap failed"); + EXIT2(return NDIS_STATUS_FAILURE); + } + wnd->mem_start = phy_addr; + wnd->mem_end = phy_addr + len; + TRACE2("%p", *virt); + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMUnmapIoSpace,3) + (struct ndis_mp_block *nmb, void __iomem *virt, UINT len) +{ + ENTER2("%p, %d", virt, len); + MmUnmapIoSpace(virt, len); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisAllocateSpinLock,1) + (struct ndis_spinlock *lock) +{ + TRACE4("lock %p, %p", lock, &lock->klock); + KeInitializeSpinLock(&lock->klock); + lock->irql = PASSIVE_LEVEL; + return; +} + +wstdcall void WIN_FUNC(NdisFreeSpinLock,1) + (struct ndis_spinlock *lock) +{ + TRACE4("lock %p, %p", lock, &lock->klock); + return; +} + +wstdcall void WIN_FUNC(NdisAcquireSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p, %p", lock, &lock->klock); +// assert_irql(_irql_ <= DISPATCH_LEVEL); + lock->irql = nt_spin_lock_irql(&lock->klock, DISPATCH_LEVEL); + return; +} + +wstdcall void WIN_FUNC(NdisReleaseSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p, %p", lock, &lock->klock); +// assert_irql(_irql_ == DISPATCH_LEVEL); + nt_spin_unlock_irql(&lock->klock, lock->irql); + return; +} + +wstdcall void WIN_FUNC(NdisDprAcquireSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p", &lock->klock); +// assert_irql(_irql_ == DISPATCH_LEVEL); + nt_spin_lock(&lock->klock); + return; +} + +wstdcall void WIN_FUNC(NdisDprReleaseSpinLock,1) + (struct ndis_spinlock *lock) +{ + ENTER6("lock %p", &lock->klock); +// assert_irql(_irql_ == DISPATCH_LEVEL); + nt_spin_unlock(&lock->klock); + return; +} + +wstdcall void WIN_FUNC(NdisInitializeReadWriteLock,1) + (struct ndis_rw_lock *rw_lock) +{ + ENTER3("%p", rw_lock); + memset(rw_lock, 0, sizeof(*rw_lock)); + KeInitializeSpinLock(&rw_lock->klock); + return; +} + +/* read/write locks are implemented in a rather simplisitic way - we + * should probably use Linux's rw_lock implementation */ + +wstdcall void WIN_FUNC(NdisAcquireReadWriteLock,3) + (struct ndis_rw_lock *rw_lock, BOOLEAN write, + struct lock_state *lock_state) +{ + if (write) { + while (1) { + if (cmpxchg(&rw_lock->count, 0, -1) == 0) + return; + while (rw_lock->count) + cpu_relax(); + } + return; + } + while (1) { + typeof(rw_lock->count) count; + while ((count = rw_lock->count) < 0) + cpu_relax(); + if (cmpxchg(&rw_lock->count, count, count + 1) == count) + return; + } +} + +wstdcall void WIN_FUNC(NdisReleaseReadWriteLock,2) + (struct ndis_rw_lock *rw_lock, struct lock_state *lock_state) +{ + if (rw_lock->count > 0) + pre_atomic_add(rw_lock->count, -1); + else if (rw_lock->count == -1) + rw_lock->count = 0; + else + WARNING("invalid state: %d", rw_lock->count); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateMapRegisters,5) + (struct ndis_mp_block *nmb, UINT dmachan, + NDIS_DMA_SIZE dmasize, ULONG basemap, ULONG max_buf_size) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER2("%p, %d %d %d %d", wnd, dmachan, dmasize, basemap, max_buf_size); + if (wnd->dma_map_count > 0) { + WARNING("%s: map registers already allocated: %u", + wnd->net_dev->name, wnd->dma_map_count); + EXIT2(return NDIS_STATUS_RESOURCES); + } + if (dmasize == NDIS_DMA_24BITS) { + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_24BIT_MASK) || + pci_set_consistent_dma_mask(wnd->wd->pci.pdev, + DMA_24BIT_MASK)) + WARNING("setting dma mask failed"); + } else if (dmasize == NDIS_DMA_32BITS) { + /* consistent dma is in low 32-bits by default */ + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_32BIT_MASK)) + WARNING("setting dma mask failed"); +#ifdef CONFIG_X86_64 + } else if (dmasize == NDIS_DMA_64BITS) { + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_64BIT_MASK) || + pci_set_consistent_dma_mask(wnd->wd->pci.pdev, + DMA_64BIT_MASK)) + WARNING("setting dma mask failed"); + else + wnd->net_dev->features |= NETIF_F_HIGHDMA; +#endif + } + /* since memory for buffer is allocated with kmalloc, buffer + * is physically contiguous, so entire map will fit in one + * register */ + if (basemap > 64) { + WARNING("Windows driver %s requesting too many (%u) " + "map registers", wnd->wd->driver->name, basemap); + /* As per NDIS, NDIS_STATUS_RESOURCES should be + * returned, but with that Atheros PCI driver fails - + * for now tolerate it */ +// EXIT2(return NDIS_STATUS_RESOURCES); + } + + wnd->dma_map_addr = kmalloc(basemap * sizeof(*(wnd->dma_map_addr)), + GFP_KERNEL); + if (!wnd->dma_map_addr) + EXIT2(return NDIS_STATUS_RESOURCES); + memset(wnd->dma_map_addr, 0, basemap * sizeof(*(wnd->dma_map_addr))); + wnd->dma_map_count = basemap; + TRACE2("%u", wnd->dma_map_count); + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMFreeMapRegisters,1) + (struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + int i; + + ENTER2("wnd: %p", wnd); + if (wnd->dma_map_addr) { + for (i = 0; i < wnd->dma_map_count; i++) { + if (wnd->dma_map_addr[i]) + WARNING("%s: dma addr %p not freed by " + "Windows driver", wnd->net_dev->name, + (void *)wnd->dma_map_addr[i]); + } + kfree(wnd->dma_map_addr); + wnd->dma_map_addr = NULL; + } else + WARNING("map registers already freed?"); + wnd->dma_map_count = 0; + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisMStartBufferPhysicalMapping,6) + (struct ndis_mp_block *nmb, ndis_buffer *buf, + ULONG index, BOOLEAN write_to_dev, + struct ndis_phy_addr_unit *phy_addr_array, UINT *array_size) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER3("%p, %p, %u, %u", wnd, buf, index, wnd->dma_map_count); + if (unlikely(wnd->sg_dma_size || !write_to_dev || + index >= wnd->dma_map_count)) { + WARNING("invalid request: %d, %d, %d, %d", wnd->sg_dma_size, + write_to_dev, index, wnd->dma_map_count); + phy_addr_array[0].phy_addr = 0; + phy_addr_array[0].length = 0; + *array_size = 0; + return; + } + if (wnd->dma_map_addr[index]) { + TRACE2("buffer %p at %d is already mapped: %lx", buf, index, + (unsigned long)wnd->dma_map_addr[index]); +// *array_size = 1; + return; + } + TRACE3("%p, %p, %u", buf, MmGetSystemAddressForMdl(buf), + MmGetMdlByteCount(buf)); + DBG_BLOCK(4) { + dump_bytes(__FUNCTION__, MmGetSystemAddressForMdl(buf), + MmGetMdlByteCount(buf)); + } + wnd->dma_map_addr[index] = + PCI_DMA_MAP_SINGLE(wnd->wd->pci.pdev, + MmGetSystemAddressForMdl(buf), + MmGetMdlByteCount(buf), PCI_DMA_TODEVICE); + phy_addr_array[0].phy_addr = wnd->dma_map_addr[index]; + phy_addr_array[0].length = MmGetMdlByteCount(buf); + TRACE4("%Lx, %d, %d", phy_addr_array[0].phy_addr, + phy_addr_array[0].length, index); + *array_size = 1; +} + +wstdcall void WIN_FUNC(NdisMCompleteBufferPhysicalMapping,3) + (struct ndis_mp_block *nmb, ndis_buffer *buf, ULONG index) +{ + struct ndis_device *wnd = nmb->wnd; + + ENTER3("%p, %p %u (%u)", wnd, buf, index, wnd->dma_map_count); + + if (unlikely(wnd->sg_dma_size)) + WARNING("buffer %p may have been unmapped already", buf); + if (index >= wnd->dma_map_count) { + ERROR("invalid map register (%u >= %u)", + index, wnd->dma_map_count); + return; + } + TRACE4("%lx", (unsigned long)wnd->dma_map_addr[index]); + if (wnd->dma_map_addr[index]) { + PCI_DMA_UNMAP_SINGLE(wnd->wd->pci.pdev, wnd->dma_map_addr[index], + MmGetMdlByteCount(buf), PCI_DMA_TODEVICE); + wnd->dma_map_addr[index] = 0; + } else + WARNING("map registers at %u not used", index); +} + +wstdcall void WIN_FUNC(NdisMAllocateSharedMemory,5) + (struct ndis_mp_block *nmb, ULONG size, + BOOLEAN cached, void **virt, NDIS_PHY_ADDRESS *phys) +{ + dma_addr_t dma_addr; + struct wrap_device *wd = nmb->wnd->wd; + + ENTER3("size: %u, cached: %d", size, cached); + *virt = PCI_DMA_ALLOC_COHERENT(wd->pci.pdev, size, &dma_addr); + if (*virt) + *phys = dma_addr; + else + WARNING("couldn't allocate %d bytes of %scached DMA memory", + size, cached ? "" : "un-"); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisMFreeSharedMemory,5) + (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, + void *virt, NDIS_PHY_ADDRESS addr) +{ + struct wrap_device *wd = nmb->wnd->wd; + ENTER3("%p, %Lx, %u", virt, addr, size); + PCI_DMA_FREE_COHERENT(wd->pci.pdev, size, virt, addr); + EXIT3(return); +} + +wstdcall void alloc_shared_memory_async(void *arg1, void *arg2) +{ + struct ndis_device *wnd; + struct alloc_shared_mem *alloc_shared_mem; + struct miniport *mp; + void *virt; + NDIS_PHY_ADDRESS phys; + KIRQL irql; + + wnd = arg1; + alloc_shared_mem = arg2; + mp = &wnd->wd->driver->ndis_driver->mp; + NdisMAllocateSharedMemory(wnd->nmb, alloc_shared_mem->size, + alloc_shared_mem->cached, &virt, &phys); + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN5(mp->alloc_complete, wnd->nmb, virt, + &phys, alloc_shared_mem->size, alloc_shared_mem->ctx); + serialize_unlock_irql(wnd, irql); + kfree(alloc_shared_mem); +} +WIN_FUNC_DECL(alloc_shared_memory_async,2) + +wstdcall NDIS_STATUS WIN_FUNC(NdisMAllocateSharedMemoryAsync,4) + (struct ndis_mp_block *nmb, ULONG size, BOOLEAN cached, void *ctx) +{ + struct ndis_device *wnd = nmb->wnd; + struct alloc_shared_mem *alloc_shared_mem; + + ENTER3("wnd: %p", wnd); + alloc_shared_mem = kmalloc(sizeof(*alloc_shared_mem), irql_gfp()); + if (!alloc_shared_mem) { + WARNING("couldn't allocate memory"); + return NDIS_STATUS_FAILURE; + } + + alloc_shared_mem->size = size; + alloc_shared_mem->cached = cached; + alloc_shared_mem->ctx = ctx; + if (schedule_ntos_work_item(WIN_FUNC_PTR(alloc_shared_memory_async,2), + wnd, alloc_shared_mem)) + EXIT3(return NDIS_STATUS_FAILURE); + EXIT3(return NDIS_STATUS_PENDING); +} + +/* Some drivers allocate NDIS_BUFFER (aka MDL) very often; instead of + * allocating and freeing with kernel functions, we chain them into + * ndis_buffer_pool. When an MDL is freed, it is added to the list of + * free MDLs. When allocated, we first check if there is one in free + * list and if so just return it; otherwise, we allocate a new one and + * return that. This reduces memory fragmentation. Windows DDK says + * that the driver itself shouldn't check what is returned in + * pool_handle, presumably because buffer pools are not used in + * XP. However, as long as driver follows rest of the semantics - that + * it should indicate maximum number of MDLs used with num_descr and + * pass the same pool_handle in other buffer functions, this should + * work. Sadly, though, NdisFreeBuffer doesn't pass the pool_handle, + * so we use 'process' field of MDL to store pool_handle. */ + +wstdcall void WIN_FUNC(NdisAllocateBufferPool,3) + (NDIS_STATUS *status, struct ndis_buffer_pool **pool_handle, + UINT num_descr) +{ + struct ndis_buffer_pool *pool; + + ENTER1("buffers: %d", num_descr); + pool = kmalloc(sizeof(*pool), irql_gfp()); + if (!pool) { + *status = NDIS_STATUS_RESOURCES; + EXIT3(return); + } + spin_lock_init(&pool->lock); + pool->max_descr = num_descr; + pool->num_allocated_descr = 0; + pool->free_descr = NULL; + *pool_handle = pool; + *status = NDIS_STATUS_SUCCESS; + TRACE1("pool: %p, num_descr: %d", pool, num_descr); + EXIT1(return); +} + +wstdcall void WIN_FUNC(NdisAllocateBuffer,5) + (NDIS_STATUS *status, ndis_buffer **buffer, + struct ndis_buffer_pool *pool, void *virt, UINT length) +{ + ndis_buffer *descr; + + ENTER4("pool: %p (%d)", pool, pool->num_allocated_descr); + /* NDIS drivers should call this at DISPATCH_LEVEL, but + * alloc_tx_packet calls at SOFT_IRQL */ + assert_irql(_irql_ <= SOFT_LEVEL); + if (!pool) { + *status = NDIS_STATUS_FAILURE; + *buffer = NULL; + EXIT4(return); + } + spin_lock_bh(&pool->lock); + if ((descr = pool->free_descr)) + pool->free_descr = descr->next; + spin_unlock_bh(&pool->lock); + if (descr) { + typeof(descr->flags) flags; + flags = descr->flags; + memset(descr, 0, sizeof(*descr)); + MmInitializeMdl(descr, virt, length); + if (flags & MDL_CACHE_ALLOCATED) + descr->flags |= MDL_CACHE_ALLOCATED; + } else { + if (pool->num_allocated_descr > pool->max_descr) { + TRACE2("pool %p is full: %d(%d)", pool, + pool->num_allocated_descr, pool->max_descr); +#ifndef ALLOW_POOL_OVERFLOW + *status = NDIS_STATUS_FAILURE; + *buffer = NULL; + return; +#endif + } + descr = allocate_init_mdl(virt, length); + if (!descr) { + WARNING("couldn't allocate buffer"); + *status = NDIS_STATUS_FAILURE; + *buffer = NULL; + EXIT4(return); + } + TRACE4("buffer %p for %p, %d", descr, virt, length); + atomic_inc_var(pool->num_allocated_descr); + } + /* TODO: make sure this mdl can map given buffer */ + MmBuildMdlForNonPagedPool(descr); +// descr->flags |= MDL_ALLOCATED_FIXED_SIZE | +// MDL_MAPPED_TO_SYSTEM_VA | MDL_PAGES_LOCKED; + descr->pool = pool; + *buffer = descr; + *status = NDIS_STATUS_SUCCESS; + TRACE4("buffer: %p", descr); + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisFreeBuffer,1) + (ndis_buffer *buffer) +{ + struct ndis_buffer_pool *pool; + + ENTER4("%p", buffer); + if (!buffer || !buffer->pool) { + ERROR("invalid buffer"); + EXIT4(return); + } + pool = buffer->pool; + if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_BUFFERS) { + /* NB NB NB: set mdl's 'pool' field to NULL before + * calling free_mdl; otherwise free_mdl calls + * NdisFreeBuffer back */ + atomic_dec_var(pool->num_allocated_descr); + buffer->pool = NULL; + free_mdl(buffer); + } else { + spin_lock_bh(&pool->lock); + buffer->next = pool->free_descr; + pool->free_descr = buffer; + spin_unlock_bh(&pool->lock); + } + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisFreeBufferPool,1) + (struct ndis_buffer_pool *pool) +{ + ndis_buffer *cur, *next; + + TRACE3("pool: %p", pool); + if (!pool) { + WARNING("invalid pool"); + EXIT3(return); + } + spin_lock_bh(&pool->lock); + cur = pool->free_descr; + while (cur) { + next = cur->next; + cur->pool = NULL; + free_mdl(cur); + cur = next; + } + spin_unlock_bh(&pool->lock); + kfree(pool); + pool = NULL; + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisAdjustBufferLength,2) + (ndis_buffer *buffer, UINT length) +{ + ENTER4("%p, %d", buffer, length); + buffer->bytecount = length; +} + +wstdcall void WIN_FUNC(NdisQueryBuffer,3) + (ndis_buffer *buffer, void **virt, UINT *length) +{ + ENTER4("buffer: %p", buffer); + if (virt) + *virt = MmGetSystemAddressForMdl(buffer); + *length = MmGetMdlByteCount(buffer); + TRACE4("%p, %u", virt? *virt : NULL, *length); + return; +} + +wstdcall void WIN_FUNC(NdisQueryBufferSafe,4) + (ndis_buffer *buffer, void **virt, UINT *length, + enum mm_page_priority priority) +{ + ENTER4("%p, %p, %p, %d", buffer, virt, length, priority); + if (virt) + *virt = MmGetSystemAddressForMdlSafe(buffer, priority); + *length = MmGetMdlByteCount(buffer); + TRACE4("%p, %u", virt? *virt : NULL, *length); +} + +wstdcall void *WIN_FUNC(NdisBufferVirtualAddress,1) + (ndis_buffer *buffer) +{ + ENTER3("%p", buffer); + return MmGetSystemAddressForMdl(buffer); +} + +wstdcall ULONG WIN_FUNC(NdisBufferLength,1) + (ndis_buffer *buffer) +{ + ENTER3("%p", buffer); + return MmGetMdlByteCount(buffer); +} + +wstdcall void WIN_FUNC(NdisQueryBufferOffset,3) + (ndis_buffer *buffer, UINT *offset, UINT *length) +{ + ENTER3("%p", buffer); + *offset = MmGetMdlByteOffset(buffer); + *length = MmGetMdlByteCount(buffer); + TRACE3("%d, %d", *offset, *length); +} + +wstdcall void WIN_FUNC(NdisUnchainBufferAtBack,2) + (struct ndis_packet *packet, ndis_buffer **buffer) +{ + ndis_buffer *b, *btail; + + ENTER3("%p", packet); + b = packet->private.buffer_head; + if (!b) { + /* no buffer in packet */ + *buffer = NULL; + EXIT3(return); + } + btail = packet->private.buffer_tail; + *buffer = btail; + if (b == btail) { + /* one buffer in packet */ + packet->private.buffer_head = NULL; + packet->private.buffer_tail = NULL; + } else { + while (b->next != btail) + b = b->next; + packet->private.buffer_tail = b; + b->next = NULL; + } + packet->private.valid_counts = FALSE; + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisUnchainBufferAtFront,2) + (struct ndis_packet *packet, ndis_buffer **buffer) +{ + ENTER3("%p", packet); + if (packet->private.buffer_head == NULL) { + /* no buffer in packet */ + *buffer = NULL; + EXIT3(return); + } + + *buffer = packet->private.buffer_head; + if (packet->private.buffer_head == packet->private.buffer_tail) { + /* one buffer in packet */ + packet->private.buffer_head = NULL; + packet->private.buffer_tail = NULL; + } else + packet->private.buffer_head = (*buffer)->next; + + packet->private.valid_counts = FALSE; + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacketSafe,6) + (struct ndis_packet *packet, ndis_buffer **first_buffer, + void **first_buffer_va, UINT *first_buffer_length, + UINT *total_buffer_length, enum mm_page_priority priority) +{ + ndis_buffer *b = packet->private.buffer_head; + + ENTER3("%p(%p)", packet, b); + *first_buffer = b; + if (b) { + *first_buffer_va = MmGetSystemAddressForMdlSafe(b, priority); + *first_buffer_length = *total_buffer_length = + MmGetMdlByteCount(b); + for (b = b->next; b; b = b->next) + *total_buffer_length += MmGetMdlByteCount(b); + } else { + *first_buffer_va = NULL; + *first_buffer_length = 0; + *total_buffer_length = 0; + } + TRACE3("%p, %d, %d", *first_buffer_va, *first_buffer_length, + *total_buffer_length); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisGetFirstBufferFromPacket,6) + (struct ndis_packet *packet, ndis_buffer **first_buffer, + void **first_buffer_va, UINT *first_buffer_length, + UINT *total_buffer_length, enum mm_page_priority priority) +{ + NdisGetFirstBufferFromPacketSafe(packet, first_buffer, + first_buffer_va, first_buffer_length, + total_buffer_length, + NormalPagePriority); +} + +wstdcall void WIN_FUNC(NdisAllocatePacketPoolEx,5) + (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle, + UINT num_descr, UINT overflowsize, UINT proto_rsvd_length) +{ + struct ndis_packet_pool *pool; + + ENTER3("buffers: %d, length: %d", num_descr, proto_rsvd_length); + pool = kzalloc(sizeof(*pool), irql_gfp()); + if (!pool) { + *status = NDIS_STATUS_RESOURCES; + EXIT3(return); + } + spin_lock_init(&pool->lock); + pool->max_descr = num_descr; + pool->num_allocated_descr = 0; + pool->num_used_descr = 0; + pool->free_descr = NULL; + pool->proto_rsvd_length = proto_rsvd_length; + *pool_handle = pool; + *status = NDIS_STATUS_SUCCESS; + TRACE3("pool: %p", pool); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisAllocatePacketPool,4) + (NDIS_STATUS *status, struct ndis_packet_pool **pool_handle, + UINT num_descr, UINT proto_rsvd_length) +{ + NdisAllocatePacketPoolEx(status, pool_handle, num_descr, 0, + proto_rsvd_length); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisFreePacketPool,1) + (struct ndis_packet_pool *pool) +{ + struct ndis_packet *packet, *next; + + ENTER3("pool: %p", pool); + if (!pool) { + WARNING("invalid pool"); + EXIT3(return); + } + spin_lock_bh(&pool->lock); + packet = pool->free_descr; + while (packet) { + next = (struct ndis_packet *)packet->reserved[0]; + kfree(packet); + packet = next; + } + pool->num_allocated_descr = 0; + pool->num_used_descr = 0; + pool->free_descr = NULL; + spin_unlock_bh(&pool->lock); + kfree(pool); + EXIT3(return); +} + +wstdcall UINT WIN_FUNC(NdisPacketPoolUsage,1) + (struct ndis_packet_pool *pool) +{ + EXIT4(return pool->num_used_descr); +} + +wstdcall void WIN_FUNC(NdisAllocatePacket,3) + (NDIS_STATUS *status, struct ndis_packet **ndis_packet, + struct ndis_packet_pool *pool) +{ + struct ndis_packet *packet; + int packet_length; + + ENTER4("pool: %p", pool); + if (!pool) { + *status = NDIS_STATUS_RESOURCES; + *ndis_packet = NULL; + EXIT4(return); + } + assert_irql(_irql_ <= SOFT_LEVEL); + if (pool->num_used_descr > pool->max_descr) { + TRACE3("pool %p is full: %d(%d)", pool, + pool->num_used_descr, pool->max_descr); +#ifndef ALLOW_POOL_OVERFLOW + *status = NDIS_STATUS_RESOURCES; + *ndis_packet = NULL; + return; +#endif + } + /* packet has space for 1 byte in protocol_reserved field */ + packet_length = sizeof(*packet) - 1 + pool->proto_rsvd_length + + sizeof(struct ndis_packet_oob_data); + spin_lock_bh(&pool->lock); + if ((packet = pool->free_descr)) + pool->free_descr = (void *)packet->reserved[0]; + spin_unlock_bh(&pool->lock); + if (!packet) { + packet = kmalloc(packet_length, irql_gfp()); + if (!packet) { + WARNING("couldn't allocate packet"); + *status = NDIS_STATUS_RESOURCES; + *ndis_packet = NULL; + return; + } + atomic_inc_var(pool->num_allocated_descr); + } + TRACE4("%p, %p", pool, packet); + atomic_inc_var(pool->num_used_descr); + memset(packet, 0, packet_length); + packet->private.oob_offset = + packet_length - sizeof(struct ndis_packet_oob_data); + packet->private.packet_flags = fPACKET_ALLOCATED_BY_NDIS; + packet->private.pool = pool; + *ndis_packet = packet; + *status = NDIS_STATUS_SUCCESS; + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisDprAllocatePacket,3) + (NDIS_STATUS *status, struct ndis_packet **packet, + struct ndis_packet_pool *pool) +{ + NdisAllocatePacket(status, packet, pool); +} + +wstdcall void WIN_FUNC(NdisFreePacket,1) + (struct ndis_packet *packet) +{ + struct ndis_packet_pool *pool; + + ENTER4("%p, %p", packet, packet->private.pool); + pool = packet->private.pool; + if (!pool) { + ERROR("invalid pool %p", packet); + EXIT4(return); + } + assert((int)pool->num_used_descr > 0); + atomic_dec_var(pool->num_used_descr); + if (packet->reserved[1]) { + TRACE3("%p, %p", packet, (void *)packet->reserved[1]); + kfree((void *)packet->reserved[1]); + packet->reserved[1] = 0; + } + if (pool->num_allocated_descr > MAX_ALLOCATED_NDIS_PACKETS) { + TRACE3("%p", pool); + atomic_dec_var(pool->num_allocated_descr); + kfree(packet); + } else { + TRACE4("%p, %p, %p", pool, packet, pool->free_descr); + spin_lock_bh(&pool->lock); + packet->reserved[0] = + (typeof(packet->reserved[0]))pool->free_descr; + pool->free_descr = packet; + spin_unlock_bh(&pool->lock); + } + EXIT4(return); +} + +wstdcall struct ndis_packet_stack *WIN_FUNC(NdisIMGetCurrentPacketStack,2) + (struct ndis_packet *packet, BOOLEAN *stacks_remain) +{ + struct ndis_packet_stack *stack; + + if (!packet->reserved[1]) { + stack = kzalloc(2 * sizeof(*stack), irql_gfp()); + TRACE3("%p, %p", packet, stack); + packet->reserved[1] = (typeof(packet->reserved[1]))stack; + } else { + stack = (void *)packet->reserved[1];; + if (xchg(&stack->ndis_reserved[0], 1)) { + stack++; + if (xchg(&stack->ndis_reserved[0], 1)) + stack = NULL; + } + TRACE3("%p", stack); + } + if (stack) + *stacks_remain = TRUE; + else + *stacks_remain = FALSE; + + EXIT3(return stack); +} + +wstdcall void WIN_FUNC(NdisCopyFromPacketToPacketSafe,7) + (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy, + struct ndis_packet *src, UINT src_offset, UINT *num_copied, + enum mm_page_priority priority) +{ + UINT dst_n, src_n, n, left; + ndis_buffer *dst_buf; + ndis_buffer *src_buf; + + ENTER4(""); + if (!dst || !src) { + *num_copied = 0; + EXIT4(return); + } + + dst_buf = dst->private.buffer_head; + src_buf = src->private.buffer_head; + + if (!dst_buf || !src_buf) { + *num_copied = 0; + EXIT4(return); + } + dst_n = MmGetMdlByteCount(dst_buf) - dst_offset; + src_n = MmGetMdlByteCount(src_buf) - src_offset; + + n = min(src_n, dst_n); + n = min(n, num_to_copy); + memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset, + MmGetSystemAddressForMdl(src_buf) + src_offset, n); + + left = num_to_copy - n; + while (left > 0) { + src_offset += n; + dst_offset += n; + dst_n -= n; + src_n -= n; + if (dst_n == 0) { + dst_buf = dst_buf->next; + if (!dst_buf) + break; + dst_n = MmGetMdlByteCount(dst_buf); + dst_offset = 0; + } + if (src_n == 0) { + src_buf = src_buf->next; + if (!src_buf) + break; + src_n = MmGetMdlByteCount(src_buf); + src_offset = 0; + } + + n = min(src_n, dst_n); + n = min(n, left); + memcpy(MmGetSystemAddressForMdl(dst_buf) + dst_offset, + MmGetSystemAddressForMdl(src_buf) + src_offset, n); + left -= n; + } + *num_copied = num_to_copy - left; + EXIT4(return); +} + +wstdcall void WIN_FUNC(NdisCopyFromPacketToPacket,6) + (struct ndis_packet *dst, UINT dst_offset, UINT num_to_copy, + struct ndis_packet *src, UINT src_offset, UINT *num_copied) +{ + NdisCopyFromPacketToPacketSafe(dst, dst_offset, num_to_copy, + src, src_offset, num_copied, + NormalPagePriority); + return; +} + +wstdcall void WIN_FUNC(NdisIMCopySendPerPacketInfo,2) + (struct ndis_packet *dst, struct ndis_packet *src) +{ + struct ndis_packet_oob_data *dst_oob, *src_oob; + dst_oob = NDIS_PACKET_OOB_DATA(dst); + src_oob = NDIS_PACKET_OOB_DATA(src); + memcpy(&dst_oob->ext, &src_oob->ext, sizeof(dst_oob->ext)); + return; +} + +wstdcall void WIN_FUNC(NdisSend,3) + (NDIS_STATUS *status, struct ndis_mp_block *nmb, + struct ndis_packet *packet) +{ + struct ndis_device *wnd = nmb->wnd; + struct miniport *mp; + KIRQL irql; + + mp = &wnd->wd->driver->ndis_driver->mp; + if (mp->send_packets) { + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN3(mp->send_packets, wnd->nmb->mp_ctx, &packet, 1); + serialize_unlock_irql(wnd, irql); + if (deserialized_driver(wnd)) + *status = NDIS_STATUS_PENDING; + else { + struct ndis_packet_oob_data *oob_data; + oob_data = NDIS_PACKET_OOB_DATA(packet); + *status = oob_data->status; + switch (*status) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, *status); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + break; + case NDIS_STATUS_FAILURE: + default: + free_tx_packet(wnd, packet, *status); + break; + } + } + } else { + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + *status = LIN2WIN3(mp->send, wnd->nmb->mp_ctx, packet, 0); + serialize_unlock_irql(wnd, irql); + switch (*status) { + case NDIS_STATUS_SUCCESS: + free_tx_packet(wnd, packet, *status); + break; + case NDIS_STATUS_PENDING: + break; + case NDIS_STATUS_RESOURCES: + wnd->tx_ok = 0; + break; + case NDIS_STATUS_FAILURE: + default: + free_tx_packet(wnd, packet, *status); + break; + } + } + EXIT3(return); +} + +/* called for serialized drivers only */ +wstdcall void mp_timer_dpc(struct kdpc *kdpc, void *ctx, void *arg1, void *arg2) +{ + struct ndis_mp_timer *timer; + struct ndis_mp_block *nmb; + + timer = ctx; + TIMERENTER("%p, %p, %p, %p", timer, timer->func, timer->ctx, timer->nmb); + assert_irql(_irql_ == DISPATCH_LEVEL); + nmb = timer->nmb; + serialize_lock(nmb->wnd); + LIN2WIN4(timer->func, NULL, timer->ctx, NULL, NULL); + serialize_unlock(nmb->wnd); + TIMEREXIT(return); +} +WIN_FUNC_DECL(mp_timer_dpc,4) + +wstdcall void WIN_FUNC(NdisMInitializeTimer,4) + (struct ndis_mp_timer *timer, struct ndis_mp_block *nmb, + DPC func, void *ctx) +{ + TIMERENTER("%p, %p, %p, %p", timer, func, ctx, nmb); + assert_irql(_irql_ == PASSIVE_LEVEL); + timer->func = func; + timer->ctx = ctx; + timer->nmb = nmb; + if (deserialized_driver(nmb->wnd)) + KeInitializeDpc(&timer->kdpc, func, ctx); + else + KeInitializeDpc(&timer->kdpc, WIN_FUNC_PTR(mp_timer_dpc,4), + timer); + wrap_init_timer(&timer->nt_timer, NotificationTimer, nmb); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisMSetPeriodicTimer,2) + (struct ndis_mp_timer *timer, UINT period_ms) +{ + unsigned long expires = MSEC_TO_HZ(period_ms); + + TIMERENTER("%p, %u, %ld", timer, period_ms, expires); + assert_irql(_irql_ <= DISPATCH_LEVEL); + wrap_set_timer(&timer->nt_timer, expires, expires, &timer->kdpc); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisMCancelTimer,2) + (struct ndis_mp_timer *timer, BOOLEAN *canceled) +{ + TIMERENTER("%p", timer); + assert_irql(_irql_ <= DISPATCH_LEVEL); + *canceled = KeCancelTimer(&timer->nt_timer); + TIMERTRACE("%d", *canceled); + return; +} + +wstdcall void WIN_FUNC(NdisInitializeTimer,3) + (struct ndis_timer *timer, void *func, void *ctx) +{ + TIMERENTER("%p, %p, %p", timer, func, ctx); + assert_irql(_irql_ == PASSIVE_LEVEL); + KeInitializeDpc(&timer->kdpc, func, ctx); + wrap_init_timer(&timer->nt_timer, NotificationTimer, NULL); + TIMEREXIT(return); +} + +/* NdisMSetTimer is a macro that calls NdisSetTimer with + * ndis_mp_timer typecast to ndis_timer */ + +wstdcall void WIN_FUNC(NdisSetTimer,2) + (struct ndis_timer *timer, UINT duetime_ms) +{ + unsigned long expires = MSEC_TO_HZ(duetime_ms); + + TIMERENTER("%p, %p, %u, %ld", timer, timer->nt_timer.wrap_timer, + duetime_ms, expires); + assert_irql(_irql_ <= DISPATCH_LEVEL); + wrap_set_timer(&timer->nt_timer, expires, 0, &timer->kdpc); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisCancelTimer,2) + (struct ndis_timer *timer, BOOLEAN *canceled) +{ + TIMERENTER("%p", timer); + assert_irql(_irql_ <= DISPATCH_LEVEL); + *canceled = KeCancelTimer(&timer->nt_timer); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(NdisMRegisterAdapterShutdownHandler,3) + (struct ndis_mp_block *nmb, void *ctx, void *func) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER1("%p", func); + wnd->wd->driver->ndis_driver->mp.shutdown = func; + wnd->shutdown_ctx = ctx; +} + +wstdcall void WIN_FUNC(NdisMDeregisterAdapterShutdownHandler,1) + (struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + wnd->wd->driver->ndis_driver->mp.shutdown = NULL; + wnd->shutdown_ctx = NULL; +} + +/* TODO: rt61 (serialized) driver doesn't want MiniportEnableInterrupt + * to be called in irq handler, but mrv800c (deserialized) driver + * wants. NDIS is confusing about when to call MiniportEnableInterrupt + * For now, handle these cases with two separate irq handlers based on + * observation of these two drivers. However, it is likely not + * correct. */ +wstdcall void deserialized_irq_handler(struct kdpc *kdpc, void *ctx, + void *arg1, void *arg2) +{ + struct ndis_device *wnd = ctx; + ndis_interrupt_handler irq_handler = arg1; + struct miniport *mp = arg2; + + TRACE6("%p", irq_handler); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN1(irq_handler, wnd->nmb->mp_ctx); + if (mp->enable_interrupt) + LIN2WIN1(mp->enable_interrupt, wnd->nmb->mp_ctx); + EXIT6(return); +} +WIN_FUNC_DECL(deserialized_irq_handler,4) + +wstdcall void serialized_irq_handler(struct kdpc *kdpc, void *ctx, + void *arg1, void *arg2) +{ + struct ndis_device *wnd = ctx; + ndis_interrupt_handler irq_handler = arg1; + + TRACE6("%p, %p, %p", wnd, irq_handler, arg2); + assert_irql(_irql_ == DISPATCH_LEVEL); + serialize_lock(wnd); + LIN2WIN1(irq_handler, arg2); + serialize_unlock(wnd); + EXIT6(return); +} +WIN_FUNC_DECL(serialized_irq_handler,4) + +wstdcall BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx) +{ + struct ndis_mp_interrupt *mp_interrupt = ctx; + struct ndis_device *wnd = mp_interrupt->nmb->wnd; + BOOLEAN recognized, queue_handler; + + TRACE6("%p", wnd); + /* kernel may call ISR when registering interrupt, in + * the same context if DEBUG_SHIRQ is enabled */ + assert_irql(_irql_ == DIRQL || _irql_ == PASSIVE_LEVEL); + if (mp_interrupt->shared) + LIN2WIN3(mp_interrupt->isr, &recognized, &queue_handler, + wnd->nmb->mp_ctx); + else { + struct miniport *mp; + mp = &wnd->wd->driver->ndis_driver->mp; + LIN2WIN1(mp->disable_interrupt, wnd->nmb->mp_ctx); + /* it is not shared interrupt, so handler must be called */ + recognized = queue_handler = TRUE; + } + if (recognized) { + if (queue_handler) { + TRACE5("%p", &wnd->irq_kdpc); + queue_kdpc(&wnd->irq_kdpc); + } + EXIT6(return TRUE); + } + EXIT6(return FALSE); +} +WIN_FUNC_DECL(ndis_isr,2) + +wstdcall NDIS_STATUS WIN_FUNC(NdisMRegisterInterrupt,7) + (struct ndis_mp_interrupt *mp_interrupt, + struct ndis_mp_block *nmb, UINT vector, UINT level, + BOOLEAN req_isr, BOOLEAN shared, enum kinterrupt_mode mode) +{ + struct ndis_device *wnd = nmb->wnd; + struct miniport *mp; + + ENTER1("%p, vector:%d, level:%d, req_isr:%d, shared:%d, mode:%d", + mp_interrupt, vector, level, req_isr, shared, mode); + + mp = &wnd->wd->driver->ndis_driver->mp; + nt_spin_lock_init(&mp_interrupt->lock); + mp_interrupt->irq = vector; + mp_interrupt->isr = mp->isr; + mp_interrupt->mp_dpc = mp->handle_interrupt; + mp_interrupt->nmb = nmb; + mp_interrupt->req_isr = req_isr; + if (shared && !req_isr) + WARNING("shared but dynamic interrupt!"); + mp_interrupt->shared = shared; + wnd->mp_interrupt = mp_interrupt; + if (mp->enable_interrupt) + mp_interrupt->enable = TRUE; + else + mp_interrupt->enable = FALSE; + + if (deserialized_driver(wnd)) { + KeInitializeDpc(&wnd->irq_kdpc, + WIN_FUNC_PTR(deserialized_irq_handler,4), + nmb->wnd); + wnd->irq_kdpc.arg1 = mp->handle_interrupt; + wnd->irq_kdpc.arg2 = mp; + TRACE2("%p, %p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2, + nmb->wnd, nmb->mp_ctx); + } else { + KeInitializeDpc(&wnd->irq_kdpc, + WIN_FUNC_PTR(serialized_irq_handler,4), + nmb->wnd); + wnd->irq_kdpc.arg1 = mp->handle_interrupt; + wnd->irq_kdpc.arg2 = nmb->mp_ctx; + TRACE2("%p, %p, %p", wnd->irq_kdpc.arg1, wnd->irq_kdpc.arg2, + nmb->wnd); + } + + if (IoConnectInterrupt(&mp_interrupt->kinterrupt, + WIN_FUNC_PTR(ndis_isr,2), mp_interrupt, NULL, + vector, DIRQL, DIRQL, mode, shared, 0, FALSE) != + STATUS_SUCCESS) { + printk(KERN_WARNING "%s: request for IRQ %d failed\n", + DRIVER_NAME, vector); + return NDIS_STATUS_RESOURCES; + } + printk(KERN_INFO "%s: using IRQ %d\n", DRIVER_NAME, vector); + EXIT1(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMDeregisterInterrupt,1) + (struct ndis_mp_interrupt *mp_interrupt) +{ + struct ndis_mp_block *nmb; + + ENTER1("%p", mp_interrupt); + nmb = xchg(&mp_interrupt->nmb, NULL); + TRACE1("%p", nmb); + if (!nmb) { + WARNING("interrupt already freed?"); + return; + } + nmb->wnd->mp_interrupt = NULL; + if (dequeue_kdpc(&nmb->wnd->irq_kdpc)) + TRACE2("interrupt kdpc was pending"); + flush_workqueue(wrapndis_wq); + IoDisconnectInterrupt(mp_interrupt->kinterrupt); + EXIT1(return); +} + +wstdcall BOOLEAN WIN_FUNC(NdisMSynchronizeWithInterrupt,3) + (struct ndis_mp_interrupt *mp_interrupt, + PKSYNCHRONIZE_ROUTINE sync_func, void *ctx) +{ + return KeSynchronizeExecution(mp_interrupt->kinterrupt, sync_func, ctx); +} + +/* called via function pointer; but 64-bit RNDIS driver calls directly */ +wstdcall void WIN_FUNC(NdisMIndicateStatus,4) + (struct ndis_mp_block *nmb, NDIS_STATUS status, void *buf, UINT len) +{ + struct ndis_device *wnd = nmb->wnd; + struct ndis_status_indication *si; + + ENTER2("status=0x%x len=%d", status, len); + switch (status) { + case NDIS_STATUS_MEDIA_CONNECT: + netif_carrier_on(wnd->net_dev); + wnd->tx_ok = 1; + if (netif_queue_stopped(wnd->net_dev)) + netif_wake_queue(wnd->net_dev); + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + set_bit(LINK_STATUS_ON, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + break; + case NDIS_STATUS_MEDIA_DISCONNECT: + netif_carrier_off(wnd->net_dev); + netif_stop_queue(wnd->net_dev); + wnd->tx_ok = 0; + if (wnd->physical_medium == NdisPhysicalMediumWirelessLan) { + memset(&wnd->essid, 0, sizeof(wnd->essid)); + set_bit(LINK_STATUS_OFF, &wnd->ndis_pending_work); + schedule_wrapndis_work(&wnd->ndis_work); + } + break; + case NDIS_STATUS_MEDIA_SPECIFIC_INDICATION: + if (!buf) + break; + si = buf; + TRACE2("status_type=%d", si->status_type); + switch (si->status_type) { + case Ndis802_11StatusType_MediaStreamMode: + break; +#ifdef CONFIG_WIRELESS_EXT + case Ndis802_11StatusType_Authentication: + buf = (char *)buf + sizeof(*si); + len -= sizeof(*si); + while (len > 0) { + int pairwise_error = 0, group_error = 0; + struct ndis_auth_req *auth_req = + (struct ndis_auth_req *)buf; + TRACE1(MACSTRSEP, MAC2STR(auth_req->bssid)); + if (auth_req->flags & 0x01) + TRACE2("reauth request"); + if (auth_req->flags & 0x02) + TRACE2("key update request"); + if (auth_req->flags & 0x06) { + pairwise_error = 1; + TRACE2("pairwise_error"); + } + if (auth_req->flags & 0x0E) { + group_error = 1; + TRACE2("group_error"); + } + if (pairwise_error || group_error) { + union iwreq_data wrqu; + struct iw_michaelmicfailure micfailure; + + memset(&micfailure, 0, sizeof(micfailure)); + if (pairwise_error) + micfailure.flags |= + IW_MICFAILURE_PAIRWISE; + if (group_error) + micfailure.flags |= + IW_MICFAILURE_GROUP; + memcpy(micfailure.src_addr.sa_data, + auth_req->bssid, ETH_ALEN); + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(micfailure); + wireless_send_event(wnd->net_dev, + IWEVMICHAELMICFAILURE, + &wrqu, (u8 *)&micfailure); + } + len -= auth_req->length; + buf = (char *)buf + auth_req->length; + } + break; + case Ndis802_11StatusType_PMKID_CandidateList: + { + u8 *end; + unsigned long i; + struct ndis_pmkid_candidate_list *cand; + + cand = buf + sizeof(struct ndis_status_indication); + if (len < sizeof(struct ndis_status_indication) + + sizeof(struct ndis_pmkid_candidate_list) || + cand->version != 1) { + WARNING("unrecognized PMKID ignored"); + EXIT1(return); + } + + end = (u8 *)buf + len; + TRACE2("PMKID ver %d num_cand %d", + cand->version, cand->num_candidates); + for (i = 0; i < cand->num_candidates; i++) { + struct iw_pmkid_cand pcand; + union iwreq_data wrqu; + struct ndis_pmkid_candidate *c = + &cand->candidates[i]; + if ((u8 *)(c + 1) > end) { + TRACE2("truncated PMKID"); + break; + } + TRACE2("%ld: " MACSTRSEP " 0x%x", + i, MAC2STR(c->bssid), c->flags); + memset(&pcand, 0, sizeof(pcand)); + if (c->flags & 0x01) + pcand.flags |= IW_PMKID_CAND_PREAUTH; + pcand.index = i; + memcpy(pcand.bssid.sa_data, c->bssid, ETH_ALEN); + + memset(&wrqu, 0, sizeof(wrqu)); + wrqu.data.length = sizeof(pcand); + wireless_send_event(wnd->net_dev, IWEVPMKIDCAND, + &wrqu, (u8 *)&pcand); + } + break; + } + case Ndis802_11StatusType_RadioState: + { + struct ndis_radio_status_indication *radio_status = buf; + if (radio_status->radio_state == + Ndis802_11RadioStatusOn) + INFO("radio is turned on"); + else if (radio_status->radio_state == + Ndis802_11RadioStatusHardwareOff) + INFO("radio is turned off by hardware"); + else if (radio_status->radio_state == + Ndis802_11RadioStatusSoftwareOff) + INFO("radio is turned off by software"); + break; + } +#endif + default: + /* is this RSSI indication? */ + TRACE2("unknown indication: %x", si->status_type); + break; + } + break; + default: + TRACE2("unknown status: %08X", status); + break; + } + + EXIT2(return); +} + +/* called via function pointer; but 64-bit RNDIS driver calls directly */ +wstdcall void WIN_FUNC(NdisMIndicateStatusComplete,1) + (struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER2("%p", wnd); + if (wnd->tx_ok) + schedule_wrapndis_work(&wnd->tx_work); +} + +/* called via function pointer */ +wstdcall void NdisMSendComplete(struct ndis_mp_block *nmb, + struct ndis_packet *packet, NDIS_STATUS status) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER4("%p, %08X", packet, status); + assert_irql(_irql_ <= DISPATCH_LEVEL); + if (deserialized_driver(wnd)) + free_tx_packet(wnd, packet, status); + else { + struct ndis_packet_oob_data *oob_data; + NDIS_STATUS pkt_status; + TRACE3("%p, %08x", packet, status); + oob_data = NDIS_PACKET_OOB_DATA(packet); + switch ((pkt_status = xchg(&oob_data->status, status))) { + case NDIS_STATUS_NOT_RECOGNIZED: + free_tx_packet(wnd, packet, status); + break; + case NDIS_STATUS_PENDING: + case 0: + break; + default: + WARNING("%p: invalid status: %08X", packet, pkt_status); + break; + } + /* In case a serialized driver has earlier requested a + * pause by returning NDIS_STATUS_RESOURCES during + * MiniportSend(Packets), wakeup tx worker now. + */ + if (xchg(&wnd->tx_ok, 1) == 0) { + TRACE3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end); + schedule_wrapndis_work(&wnd->tx_work); + } + } + EXIT3(return); +} + +/* called via function pointer */ +wstdcall void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER3("%d, %d", wnd->tx_ring_start, wnd->tx_ring_end); + wnd->tx_ok = 1; + schedule_wrapndis_work(&wnd->tx_work); + EXIT3(return); +} + +wstdcall void return_packet(void *arg1, void *arg2) +{ + struct ndis_device *wnd; + struct ndis_packet *packet; + struct miniport *mp; + KIRQL irql; + + wnd = arg1; + packet = arg2; + ENTER4("%p, %p", wnd, packet); + mp = &wnd->wd->driver->ndis_driver->mp; + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN2(mp->return_packet, wnd->nmb->mp_ctx, packet); + serialize_unlock_irql(wnd, irql); + EXIT4(return); +} +WIN_FUNC_DECL(return_packet,2) + +/* called via function pointer */ +wstdcall void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb, + struct ndis_packet **packets, + UINT nr_packets) +{ + struct ndis_device *wnd; + ndis_buffer *buffer; + struct ndis_packet *packet; + struct sk_buff *skb; + ULONG i, length, total_length; + struct ndis_packet_oob_data *oob_data; + void *virt; + struct ndis_tcp_ip_checksum_packet_info csum; + + ENTER3("%p, %d", nmb, nr_packets); + assert_irql(_irql_ <= DISPATCH_LEVEL); + wnd = nmb->wnd; + for (i = 0; i < nr_packets; i++) { + packet = packets[i]; + if (!packet) { + WARNING("empty packet ignored"); + continue; + } + wnd->net_dev->last_rx = jiffies; + /* get total number of bytes in packet */ + NdisGetFirstBufferFromPacketSafe(packet, &buffer, &virt, + &length, &total_length, + NormalPagePriority); + TRACE3("%d, %d", length, total_length); + oob_data = NDIS_PACKET_OOB_DATA(packet); + TRACE3("0x%x, 0x%x, %Lu", packet->private.flags, + packet->private.packet_flags, oob_data->time_rxed); + skb = dev_alloc_skb(total_length); + if (skb) { + while (buffer) { + memcpy_skb(skb, MmGetSystemAddressForMdl(buffer), + MmGetMdlByteCount(buffer)); + buffer = buffer->next; + } + skb->dev = wnd->net_dev; + skb->protocol = eth_type_trans(skb, wnd->net_dev); + pre_atomic_add(wnd->net_stats.rx_bytes, total_length); + atomic_inc_var(wnd->net_stats.rx_packets); + csum.value = (typeof(csum.value))(ULONG_PTR) + oob_data->ext.info[TcpIpChecksumPacketInfo]; + TRACE3("0x%05x", csum.value); + if (wnd->rx_csum.value && + (csum.rx.tcp_succeeded || csum.rx.udp_succeeded || + csum.rx.ip_succeeded)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + } else { + WARNING("couldn't allocate skb; packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + } + + /* serialized drivers check the status upon return + * from this function */ + if (!deserialized_driver(wnd)) { + oob_data->status = NDIS_STATUS_SUCCESS; + continue; + } + + /* if a deserialized driver sets + * NDIS_STATUS_RESOURCES, then it reclaims the packet + * upon return from this function */ + if (oob_data->status == NDIS_STATUS_RESOURCES) + continue; + + assert(oob_data->status == NDIS_STATUS_SUCCESS); + /* deserialized driver doesn't check the status upon + * return from this function; we need to call + * MiniportReturnPacket later for this packet. Calling + * MiniportReturnPacket from here is not correct - the + * driver doesn't expect it (at least Centrino driver + * crashes) */ + schedule_ntos_work_item(WIN_FUNC_PTR(return_packet,2), + wnd, packet); + } + EXIT3(return); +} + +/* called via function pointer (by NdisMEthIndicateReceive macro); the + * first argument is nmb->eth_db */ +wstdcall void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx, + char *header1, char *header, UINT header_size, + void *look_ahead, UINT look_ahead_size, + UINT packet_size) +{ + struct sk_buff *skb = NULL; + struct ndis_device *wnd; + unsigned int skb_size = 0; + KIRQL irql; + struct ndis_packet_oob_data *oob_data; + + ENTER3("nmb = %p, rx_ctx = %p, buf = %p, size = %d, buf = %p, " + "size = %d, packet = %d", nmb, rx_ctx, header, header_size, + look_ahead, look_ahead_size, packet_size); + + wnd = nmb->wnd; + TRACE3("wnd = %p", wnd); + if (!wnd) { + ERROR("nmb is NULL"); + EXIT3(return); + } + wnd->net_dev->last_rx = jiffies; + + if (look_ahead_size < packet_size) { + struct ndis_packet *packet; + struct miniport *mp; + unsigned int bytes_txed; + NDIS_STATUS res; + + NdisAllocatePacket(&res, &packet, wnd->tx_packet_pool); + if (res != NDIS_STATUS_SUCCESS) { + atomic_inc_var(wnd->net_stats.rx_dropped); + EXIT3(return); + } + oob_data = NDIS_PACKET_OOB_DATA(packet); + mp = &wnd->wd->driver->ndis_driver->mp; + irql = serialize_lock_irql(wnd); + assert_irql(_irql_ == DISPATCH_LEVEL); + res = LIN2WIN6(mp->tx_data, packet, &bytes_txed, nmb, + rx_ctx, look_ahead_size, packet_size); + serialize_unlock_irql(wnd, irql); + TRACE3("%d, %d, %d", header_size, look_ahead_size, bytes_txed); + if (res == NDIS_STATUS_SUCCESS) { + ndis_buffer *buffer; + struct ndis_tcp_ip_checksum_packet_info csum; + skb = dev_alloc_skb(header_size + look_ahead_size + + bytes_txed); + if (!skb) { + ERROR("couldn't allocate skb; packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + NdisFreePacket(packet); + return; + } + memcpy_skb(skb, header, header_size); + memcpy_skb(skb, look_ahead, look_ahead_size); + buffer = packet->private.buffer_head; + while (buffer) { + memcpy_skb(skb, + MmGetSystemAddressForMdl(buffer), + MmGetMdlByteCount(buffer)); + buffer = buffer->next; + } + skb_size = header_size + look_ahead_size + bytes_txed; + csum.value = (typeof(csum.value))(ULONG_PTR) + oob_data->ext.info[TcpIpChecksumPacketInfo]; + TRACE3("0x%05x", csum.value); + if (wnd->rx_csum.value && + (csum.rx.tcp_succeeded || csum.rx.udp_succeeded)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + NdisFreePacket(packet); + } else if (res == NDIS_STATUS_PENDING) { + /* driver will call td_complete */ + oob_data->look_ahead = kmalloc(look_ahead_size, + GFP_ATOMIC); + if (!oob_data->look_ahead) { + NdisFreePacket(packet); + ERROR("packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + EXIT3(return); + } + assert(sizeof(oob_data->header) == header_size); + memcpy(oob_data->header, header, + sizeof(oob_data->header)); + memcpy(oob_data->look_ahead, look_ahead, + look_ahead_size); + oob_data->look_ahead_size = look_ahead_size; + EXIT3(return); + } else { + WARNING("packet dropped: %08X", res); + atomic_inc_var(wnd->net_stats.rx_dropped); + NdisFreePacket(packet); + EXIT3(return); + } + } else { + skb_size = header_size + packet_size; + skb = dev_alloc_skb(skb_size); + if (skb) { + memcpy_skb(skb, header, header_size); + memcpy_skb(skb, look_ahead, packet_size); + } + } + + if (skb) { + skb->dev = wnd->net_dev; + skb->protocol = eth_type_trans(skb, wnd->net_dev); + pre_atomic_add(wnd->net_stats.rx_bytes, skb_size); + atomic_inc_var(wnd->net_stats.rx_packets); + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); + } + + EXIT3(return); +} + +/* called via function pointer */ +wstdcall void NdisMTransferDataComplete(struct ndis_mp_block *nmb, + struct ndis_packet *packet, + NDIS_STATUS status, UINT bytes_txed) +{ + struct ndis_device *wnd = nmb->wnd; + struct sk_buff *skb; + unsigned int skb_size; + struct ndis_packet_oob_data *oob_data; + ndis_buffer *buffer; + struct ndis_tcp_ip_checksum_packet_info csum; + + ENTER3("wnd = %p, packet = %p, bytes_txed = %d", + wnd, packet, bytes_txed); + if (!packet) { + WARNING("illegal packet"); + EXIT3(return); + } + wnd->net_dev->last_rx = jiffies; + oob_data = NDIS_PACKET_OOB_DATA(packet); + skb_size = sizeof(oob_data->header) + oob_data->look_ahead_size + + bytes_txed; + skb = dev_alloc_skb(skb_size); + if (!skb) { + kfree(oob_data->look_ahead); + NdisFreePacket(packet); + ERROR("couldn't allocate skb; packet dropped"); + atomic_inc_var(wnd->net_stats.rx_dropped); + EXIT3(return); + } + memcpy_skb(skb, oob_data->header, sizeof(oob_data->header)); + memcpy_skb(skb, oob_data->look_ahead, oob_data->look_ahead_size); + buffer = packet->private.buffer_head; + while (buffer) { + memcpy_skb(skb, MmGetSystemAddressForMdl(buffer), + MmGetMdlByteCount(buffer)); + buffer = buffer->next; + } + kfree(oob_data->look_ahead); + NdisFreePacket(packet); + skb->dev = wnd->net_dev; + skb->protocol = eth_type_trans(skb, wnd->net_dev); + pre_atomic_add(wnd->net_stats.rx_bytes, skb_size); + atomic_inc_var(wnd->net_stats.rx_packets); + + csum.value = (typeof(csum.value))(ULONG_PTR) + oob_data->ext.info[TcpIpChecksumPacketInfo]; + TRACE3("0x%05x", csum.value); + if (wnd->rx_csum.value && + (csum.rx.tcp_succeeded || csum.rx.udp_succeeded)) + skb->ip_summed = CHECKSUM_UNNECESSARY; + else + skb->ip_summed = CHECKSUM_NONE; + + if (in_interrupt()) + netif_rx(skb); + else + netif_rx_ni(skb); +} + +/* called via function pointer */ +wstdcall void EthRxComplete(struct ndis_mp_block *nmb) +{ + TRACE3(""); +} + +/* called via function pointer */ +wstdcall void NdisMQueryInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER2("nmb: %p, wnd: %p, %08X", nmb, wnd, status); + wnd->ndis_req_status = status; + wnd->ndis_req_done = 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT2(return); +} + +/* called via function pointer */ +wstdcall void NdisMSetInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER2("status = %08X", status); + wnd->ndis_req_status = status; + wnd->ndis_req_done = 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT2(return); +} + +/* called via function pointer */ +wstdcall void NdisMResetComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status, BOOLEAN address_reset) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER2("status: %08X, %u", status, address_reset); + wnd->ndis_req_status = status; + wnd->ndis_req_done = address_reset + 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT2(return); +} + +wstdcall void WIN_FUNC(NdisMSleep,1) + (ULONG us) +{ + unsigned long delay; + + ENTER4("%p: us: %u", current, us); + delay = USEC_TO_HZ(us); + sleep_hz(delay); + TRACE4("%p: done", current); +} + +wstdcall void WIN_FUNC(NdisGetCurrentSystemTime,1) + (LARGE_INTEGER *time) +{ + *time = ticks_1601(); + TRACE5("%Lu, %lu", *time, jiffies); +} + +wstdcall LONG WIN_FUNC(NdisInterlockedDecrement,1) + (LONG *val) +{ + return InterlockedDecrement(val); +} + +wstdcall LONG WIN_FUNC(NdisInterlockedIncrement,1) + (LONG *val) +{ + return InterlockedIncrement(val); +} + +wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertHeadList,3) + (struct nt_list *head, struct nt_list *entry, + struct ndis_spinlock *lock) +{ + return ExInterlockedInsertHeadList(head, entry, &lock->klock); +} + +wstdcall struct nt_list *WIN_FUNC(NdisInterlockedInsertTailList,3) + (struct nt_list *head, struct nt_list *entry, + struct ndis_spinlock *lock) +{ + return ExInterlockedInsertTailList(head, entry, &lock->klock); +} + +wstdcall struct nt_list *WIN_FUNC(NdisInterlockedRemoveHeadList,2) + (struct nt_list *head, struct ndis_spinlock *lock) +{ + return ExInterlockedRemoveHeadList(head, &lock->klock); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMInitializeScatterGatherDma,3) + (struct ndis_mp_block *nmb, BOOLEAN dma_size, ULONG max_phy_map) +{ + struct ndis_device *wnd = nmb->wnd; + ENTER2("dma_size=%d, maxtransfer=%u", dma_size, max_phy_map); +#ifdef CONFIG_X86_64 + if (dma_size != NDIS_DMA_64BITS) { + TRACE1("DMA size is not 64-bits"); + if (pci_set_dma_mask(wnd->wd->pci.pdev, DMA_32BIT_MASK) || + pci_set_consistent_dma_mask(wnd->wd->pci.pdev, + DMA_32BIT_MASK)) + WARNING("setting dma mask failed"); + } +#endif + if ((wnd->attributes & NDIS_ATTRIBUTE_BUS_MASTER) && + wrap_is_pci_bus(wnd->wd->dev_bus)) { + wnd->sg_dma_size = max_phy_map; + return NDIS_STATUS_SUCCESS; + } else + EXIT1(return NDIS_STATUS_NOT_SUPPORTED); +} + +wstdcall ULONG WIN_FUNC(NdisMGetDmaAlignment,1) + (struct ndis_mp_block *nmb) +{ + ENTER3(""); + return dma_get_cache_alignment(); +} + +wstdcall CHAR WIN_FUNC(NdisSystemProcessorCount,0) + (void) +{ + return NR_CPUS; +} + +wstdcall void WIN_FUNC(NdisGetCurrentProcessorCounts,3) + (ULONG *idle, ULONG *kernel_user, ULONG *index) +{ + int cpu = smp_processor_id(); + *idle = kstat_cpu(cpu).cpustat.idle; + *kernel_user = kstat_cpu(cpu).cpustat.system + + kstat_cpu(cpu).cpustat.user; + *index = cpu; +} + +wstdcall void WIN_FUNC(NdisInitializeEvent,1) + (struct ndis_event *ndis_event) +{ + EVENTENTER("%p", ndis_event); + KeInitializeEvent(&ndis_event->nt_event, NotificationEvent, 0); +} + +wstdcall BOOLEAN WIN_FUNC(NdisWaitEvent,2) + (struct ndis_event *ndis_event, UINT ms) +{ + LARGE_INTEGER ticks; + NTSTATUS res; + + EVENTENTER("%p %u", ndis_event, ms); + ticks = -((LARGE_INTEGER)ms * TICKSPERMSEC); + res = KeWaitForSingleObject(&ndis_event->nt_event, 0, 0, TRUE, + ms == 0 ? NULL : &ticks); + if (res == STATUS_SUCCESS) + EXIT3(return TRUE); + else + EXIT3(return FALSE); +} + +wstdcall void WIN_FUNC(NdisSetEvent,1) + (struct ndis_event *ndis_event) +{ + EVENTENTER("%p", ndis_event); + KeSetEvent(&ndis_event->nt_event, 0, 0); +} + +wstdcall void WIN_FUNC(NdisResetEvent,1) + (struct ndis_event *ndis_event) +{ + EVENTENTER("%p", ndis_event); + KeResetEvent(&ndis_event->nt_event); +} + +static void ndis_worker(worker_param_t dummy) +{ + struct nt_list *ent; + struct ndis_work_item *ndis_work_item; + + WORKENTER(""); + while (1) { + spin_lock_bh(&ndis_work_list_lock); + ent = RemoveHeadList(&ndis_work_list); + spin_unlock_bh(&ndis_work_list_lock); + if (!ent) + break; + ndis_work_item = container_of(ent, struct ndis_work_item, list); + WORKTRACE("%p: %p, %p", ndis_work_item, + ndis_work_item->func, ndis_work_item->ctx); + LIN2WIN2(ndis_work_item->func, ndis_work_item, + ndis_work_item->ctx); + WORKTRACE("%p done", ndis_work_item); + } + WORKEXIT(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisScheduleWorkItem,1) + (struct ndis_work_item *ndis_work_item) +{ + ENTER3("%p", ndis_work_item); + spin_lock_bh(&ndis_work_list_lock); + InsertTailList(&ndis_work_list, &ndis_work_item->list); + spin_unlock_bh(&ndis_work_list_lock); + WORKTRACE("scheduling %p", ndis_work_item); + schedule_ndis_work(&ndis_work); + EXIT3(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMGetDeviceProperty,6) + (struct ndis_mp_block *nmb, void **phy_dev, void **func_dev, + void **next_dev, void **alloc_res, void**trans_res) +{ + ENTER2("nmb: %p, phy_dev = %p, func_dev = %p, next_dev = %p, " + "alloc_res = %p, trans_res = %p", nmb, phy_dev, func_dev, + next_dev, alloc_res, trans_res); + if (phy_dev) + *phy_dev = nmb->pdo; + if (func_dev) + *func_dev = nmb->fdo; + if (next_dev) + *next_dev = nmb->next_device; +} + +wstdcall void WIN_FUNC(NdisMRegisterUnloadHandler,2) + (struct driver_object *drv_obj, void *unload) +{ + if (drv_obj) + drv_obj->unload = unload; + return; +} + +wstdcall UINT WIN_FUNC(NdisGetVersion,0) + (void) +{ + return 0x00050001; +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMQueryAdapterInstanceName,2) + (struct unicode_string *name, struct ndis_mp_block *nmb) +{ + struct ndis_device *wnd = nmb->wnd; + struct ansi_string ansi; + + if (wrap_is_pci_bus(wnd->wd->dev_bus)) + RtlInitAnsiString(&ansi, "PCI Ethernet Adapter"); + else + RtlInitAnsiString(&ansi, "USB Ethernet Adapter"); + + if (RtlAnsiStringToUnicodeString(name, &ansi, TRUE)) + EXIT2(return NDIS_STATUS_RESOURCES); + else + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisWriteEventLogEntry,7) + (void *handle, NDIS_STATUS code, ULONG value, USHORT n, + void *strings, ULONG datasize, void *data) +{ + TRACE1("0x%x, 0x%x, %u, %u", code, value, n, datasize); + return NDIS_STATUS_SUCCESS; +} + +wstdcall void *WIN_FUNC(NdisGetRoutineAddress,1) + (struct unicode_string *unicode_string) +{ + struct ansi_string ansi_string; + void *address; + + if (RtlUnicodeStringToAnsiString(&ansi_string, unicode_string, TRUE) != + STATUS_SUCCESS) + EXIT1(return NULL); + INFO("%s", ansi_string.buf); + address = ndis_get_routine_address(ansi_string.buf); + RtlFreeAnsiString(&ansi_string); + return address; +} + +wstdcall ULONG WIN_FUNC(NdisReadPcmciaAttributeMemory,4) + (struct ndis_mp_block *nmb, ULONG offset, void *buffer, + ULONG length) +{ + TODO(); + return 0; +} + +wstdcall ULONG WIN_FUNC(NdisWritePcmciaAttributeMemory,4) + (struct ndis_mp_block *nmb, ULONG offset, void *buffer, + ULONG length) +{ + TODO(); + return 0; +} + +wstdcall void WIN_FUNC(NdisMCoIndicateReceivePacket,3) + (struct ndis_mp_block *nmb, struct ndis_packet **packets, + UINT nr_packets) +{ + ENTER3("nmb = %p", nmb); + NdisMIndicateReceivePacket(nmb, packets, nr_packets); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisMCoSendComplete,3) + (NDIS_STATUS status, struct ndis_mp_block *nmb, + struct ndis_packet *packet) +{ + ENTER3("%08x", status); + NdisMSendComplete(nmb, packet, status); + EXIT3(return); +} + +wstdcall void WIN_FUNC(NdisMCoRequestComplete,3) + (NDIS_STATUS status, struct ndis_mp_block *nmb, + struct ndis_request *ndis_request) +{ + struct ndis_device *wnd = nmb->wnd; + typeof(wnd->ndis_req_task) task; + + ENTER3("%08X", status); + wnd->ndis_req_status = status; + wnd->ndis_req_done = 1; + if ((task = xchg(&wnd->ndis_req_task, NULL))) + wake_up_process(task); + else + WARNING("invalid task"); + EXIT3(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisIMNotifiyPnPEvent,2) + (struct ndis_mp_block *nmb, struct net_pnp_event *event) +{ + ENTER2("%p, %d", nmb, event->code); + /* NdisWrapper never calls protocol's pnp event notifier, so + * nothing to do here */ + EXIT2(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisCompletePnPEvent,2) + (NDIS_STATUS status, void *handle, struct net_pnp_event *event) +{ + ENTER2("%d, %p, %d", status, handle, event->code); + /* NdisWrapper never calls protocol's pnp event notifier, so + * nothing to do here */ + EXIT2(return); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMSetMiniportSecondary,2) + (struct ndis_mp_block *nmb2, struct ndis_mp_block *nmb1) +{ + ENTER3("%p, %p", nmb1, nmb2); + TODO(); + EXIT3(return NDIS_STATUS_SUCCESS); +} + +wstdcall NDIS_STATUS WIN_FUNC(NdisMPromoteMiniport,1) + (struct ndis_mp_block *nmb) +{ + ENTER3("%p", nmb); + TODO(); + EXIT3(return NDIS_STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(NdisMCoActivateVcComplete,3) + (NDIS_STATUS status, void *handle, void *params) +{ + TODO(); +} + +wstdcall void WIN_FUNC(NdisMCoDeactivateVcComplete,2) + (NDIS_STATUS status, void *handle) +{ + TODO(); +} + +wstdcall void WIN_FUNC(NdisMRemoveMiniport,1) + (void *handle) +{ + TODO(); +} + +static void *ndis_get_routine_address(char *name) +{ + int i; + ENTER2("%p", name); + for (i = 0; i < sizeof(ndis_exports) / sizeof(ndis_exports[0]); i++) { + if (strcmp(name, ndis_exports[i].name) == 0) { + TRACE2("%p", ndis_exports[i].func); + return ndis_exports[i].func; + } + } + EXIT2(return NULL); +} + +/* ndis_init_device is called for each device */ +int ndis_init_device(struct ndis_device *wnd) +{ + struct ndis_mp_block *nmb = wnd->nmb; + + KeInitializeSpinLock(&nmb->lock); + wnd->mp_interrupt = NULL; + wnd->wrap_timer_slist.next = NULL; + if (wnd->wd->driver->ndis_driver) + wnd->wd->driver->ndis_driver->mp.shutdown = NULL; + + nmb->filterdbs.eth_db = nmb; + nmb->filterdbs.tr_db = nmb; + nmb->filterdbs.fddi_db = nmb; + nmb->filterdbs.arc_db = nmb; + + nmb->rx_packet = WIN_FUNC_PTR(NdisMIndicateReceivePacket,3); + nmb->send_complete = WIN_FUNC_PTR(NdisMSendComplete,3); + nmb->send_resource_avail = WIN_FUNC_PTR(NdisMSendResourcesAvailable,1); + nmb->status = WIN_FUNC_PTR(NdisMIndicateStatus,4); + nmb->status_complete = WIN_FUNC_PTR(NdisMIndicateStatusComplete,1); + nmb->queryinfo_complete = WIN_FUNC_PTR(NdisMQueryInformationComplete,2); + nmb->setinfo_complete = WIN_FUNC_PTR(NdisMSetInformationComplete,2); + nmb->reset_complete = WIN_FUNC_PTR(NdisMResetComplete,3); + nmb->eth_rx_indicate = WIN_FUNC_PTR(EthRxIndicateHandler,8); + nmb->eth_rx_complete = WIN_FUNC_PTR(EthRxComplete,1); + nmb->td_complete = WIN_FUNC_PTR(NdisMTransferDataComplete,4); + return 0; +} + +/* ndis_exit_device is called for each device */ +void ndis_exit_device(struct ndis_device *wnd) +{ + struct wrap_device_setting *setting; + ENTER2("%p", wnd); + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_entry(setting, &wnd->wd->settings, list) { + struct ndis_configuration_parameter *param; + param = setting->encoded; + if (param) { + if (param->type == NdisParameterString) + RtlFreeUnicodeString(¶m->data.string); + ExFreePool(param); + setting->encoded = NULL; + } + } + up(&loader_mutex); +} + +/* ndis_init is called once when module is loaded */ +int ndis_init(void) +{ + InitializeListHead(&ndis_work_list); + spin_lock_init(&ndis_work_list_lock); + initialize_work(&ndis_work, ndis_worker, NULL); + + ndis_wq = create_singlethread_workqueue("ndis_wq"); + if (!ndis_wq) { + WARNING("couldn't create worker thread"); + EXIT1(return -ENOMEM); + } + + ndis_worker_thread = wrap_worker_init(ndis_wq); + TRACE1("%p", ndis_worker_thread); + return 0; +} + +/* ndis_exit is called once when module is removed */ +void ndis_exit(void) +{ + ENTER1(""); + if (ndis_wq) + destroy_workqueue(ndis_wq); + TRACE1("%p", ndis_worker_thread); + if (ndis_worker_thread) + ObDereferenceObject(ndis_worker_thread); + EXIT1(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/iw_ndis.c +++ linux-2.6.28/ubuntu/ndiswrapper/iw_ndis.c @@ -0,0 +1,1956 @@ + /* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "iw_ndis.h" +#include "wrapndis.h" + +static int freq_chan[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; + +static const char *network_names[] = {"IEEE 802.11FH", "IEEE 802.11b", + "IEEE 802.11a", "IEEE 802.11g", "Auto"}; + +int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len) +{ + NDIS_STATUS res; + struct ndis_essid req; + + if (ssid_len > NDIS_ESSID_MAX_SIZE) + return -EINVAL; + + memset(&req, 0, sizeof(req)); + req.length = ssid_len; + if (ssid_len) + memcpy(&req.essid, ssid, ssid_len); + + res = mp_set(wnd, OID_802_11_SSID, &req, sizeof(req)); + if (res) { + WARNING("setting essid failed (%08X)", res); + EXIT2(return -EINVAL); + } + memcpy(&wnd->essid, &req, sizeof(req)); + EXIT2(return 0); +} + +static int set_assoc_params(struct ndis_device *wnd) +{ + TRACE2("wpa_version=0x%x auth_alg=0x%x key_mgmt=0x%x " + "cipher_pairwise=0x%x cipher_group=0x%x", + wnd->iw_auth_wpa_version, wnd->iw_auth_80211_alg, + wnd->iw_auth_key_mgmt, wnd->iw_auth_cipher_pairwise, + wnd->iw_auth_cipher_group); + set_auth_mode(wnd); + set_priv_filter(wnd); + set_encr_mode(wnd); + return 0; +} + +static int iw_set_essid(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + char ssid[NDIS_ESSID_MAX_SIZE]; + int length; + + ENTER2(""); + memset(ssid, 0, sizeof(ssid)); + /* there is no way to turn off essid other than to set to + * random bytes; instead, we use off to mean any */ + if (wrqu->essid.flags) { + /* wireless-tools prior to version 20 add extra 1, and + * later than 20 don't! Deal with that mess */ + length = wrqu->essid.length - 1; + if (length > 0) + length--; + while (length < wrqu->essid.length && extra[length]) + length++; + TRACE2("%d", length); + if (length <= 0 || length > NDIS_ESSID_MAX_SIZE) + EXIT2(return -EINVAL); + } else + length = 0; + + set_assoc_params(wnd); + + memcpy(ssid, extra, length); + if (set_essid(wnd, ssid, length)) + EXIT2(return -EINVAL); + + EXIT2(return 0); +} + +static int iw_get_essid(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + struct ndis_essid req; + + ENTER2(""); + memset(&req, 0, sizeof(req)); + res = mp_query(wnd, OID_802_11_SSID, &req, sizeof(req)); + if (res) { + WARNING("getting essid failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + memcpy(extra, req.essid, req.length); + if (req.length > 0) + wrqu->essid.flags = 1; + else + wrqu->essid.flags = 0; + wrqu->essid.length = req.length; + EXIT2(return 0); +} + +int set_infra_mode(struct ndis_device *wnd, + enum ndis_infrastructure_mode mode) +{ + NDIS_STATUS res; + unsigned int i; + + ENTER2("%d", mode); + res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, + &wnd->infrastructure_mode); + if (res != NDIS_STATUS_SUCCESS) { + WARNING("getting operating mode to failed (%08X)", res); + EXIT2(return -EINVAL); + } + if (wnd->infrastructure_mode == mode) + EXIT2(return 0); + res = mp_set_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, mode); + if (res) { + WARNING("setting operating mode to %d failed (%08X)", + mode, res); + EXIT2(return -EINVAL); + } + /* NDIS drivers clear keys when infrastructure mode is + * changed. But Linux tools assume otherwise. So set the + * keys */ + if (wnd->iw_auth_key_mgmt == 0 || + wnd->iw_auth_key_mgmt == IW_AUTH_KEY_MGMT_802_1X) { + for (i = 0; i < MAX_ENCR_KEYS; i++) { + if (wnd->encr_info.keys[i].length > 0) + add_wep_key(wnd, wnd->encr_info.keys[i].key, + wnd->encr_info.keys[i].length, i); + } + } + wnd->infrastructure_mode = mode; + EXIT2(return 0); +} + +static int iw_set_infra_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + enum ndis_infrastructure_mode ndis_mode; + + ENTER2("%d", wrqu->mode); + switch (wrqu->mode) { + case IW_MODE_ADHOC: + ndis_mode = Ndis802_11IBSS; + break; + case IW_MODE_INFRA: + ndis_mode = Ndis802_11Infrastructure; + break; + case IW_MODE_AUTO: + ndis_mode = Ndis802_11AutoUnknown; + break; + default: + EXIT2(return -EINVAL); + } + + if (set_infra_mode(wnd, ndis_mode)) + EXIT2(return -EINVAL); + + EXIT2(return 0); +} + +static int iw_get_infra_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int ndis_mode, iw_mode; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &ndis_mode); + if (res) { + WARNING("getting operating mode failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + + switch(ndis_mode) { + case Ndis802_11IBSS: + iw_mode = IW_MODE_ADHOC; + break; + case Ndis802_11Infrastructure: + iw_mode = IW_MODE_INFRA; + break; + case Ndis802_11AutoUnknown: + iw_mode = IW_MODE_AUTO; + break; + default: + ERROR("invalid operating mode (%u)", ndis_mode); + EXIT2(return -EINVAL); + } + wrqu->mode = iw_mode; + EXIT2(return 0); +} + +static const char *network_type_to_name(int net_type) +{ + if (net_type >= 0 && + net_type < (sizeof(network_names)/sizeof(network_names[0]))) + return network_names[net_type]; + else + return network_names[sizeof(network_names) / + sizeof(network_names[0]) - 1]; +} + +static int iw_get_network_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + unsigned int network_type; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, + &network_type); + if (res) { + WARNING("getting network type failed: %08X", res); + network_type = -1; + } + strncpy(wrqu->name, network_type_to_name(network_type), + sizeof(wrqu->name) - 1); + wrqu->name[sizeof(wrqu->name)-1] = 0; + return 0; +} + +static int iw_get_freq(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + struct ndis_configuration req; + + ENTER2(""); + memset(&req, 0, sizeof(req)); + res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); + if (res) { + WARNING("getting configuration failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + + memset(&(wrqu->freq), 0, sizeof(struct iw_freq)); + + /* see comment in wireless.h above the "struct iw_freq" + definition for an explanation of this if + NOTE: 1000000 is due to the kHz + */ + if (req.ds_config > 1000000) { + wrqu->freq.m = req.ds_config / 10; + wrqu->freq.e = 1; + } + else + wrqu->freq.m = req.ds_config; + + /* convert from kHz to Hz */ + wrqu->freq.e += 3; + + return 0; +} + +static int iw_set_freq(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + struct ndis_configuration req; + + ENTER2(""); + /* this OID is valid only when not associated */ + if (netif_carrier_ok(wnd->net_dev)) + EXIT2(return 0); + memset(&req, 0, sizeof(req)); + res = mp_query(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); + if (res) { + WARNING("getting configuration failed (%08X)", res); + EXIT2(return 0); + } + + if (wrqu->freq.m < 1000 && wrqu->freq.e == 0) { + if (wrqu->freq.m >= 1 && + wrqu->freq.m <= (sizeof(freq_chan) / sizeof(freq_chan[0]))) + req.ds_config = freq_chan[wrqu->freq.m - 1] * 1000; + else + return -EINVAL; + } else { + int i; + req.ds_config = wrqu->freq.m; + for (i = wrqu->freq.e; i > 0; i--) + req.ds_config *= 10; + req.ds_config /= 1000; + } + res = mp_set(wnd, OID_802_11_CONFIGURATION, &req, sizeof(req)); + if (res) + WARNING("setting configuration failed (%08X)", res); + return 0; +} + +static int iw_get_tx_power(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_tx_power_level ndis_power; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, + &ndis_power, sizeof(ndis_power)); + if (res) + return -EOPNOTSUPP; + wrqu->txpower.flags = IW_TXPOW_MWATT; + wrqu->txpower.disabled = 0; + wrqu->txpower.fixed = 0; + wrqu->txpower.value = ndis_power; + return 0; +} + +static int iw_set_tx_power(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_tx_power_level ndis_power; + NDIS_STATUS res; + + ENTER2(""); + if (wrqu->txpower.disabled) + ndis_power = 0; + else { + if (wrqu->txpower.flags == IW_TXPOW_MWATT) + ndis_power = wrqu->txpower.value; + else { // wrqu->txpower.flags == IW_TXPOW_DBM + if (wrqu->txpower.value > 20) + ndis_power = 128; + else if (wrqu->txpower.value < -43) + ndis_power = 127; + else { + signed char tmp; + tmp = wrqu->txpower.value; + tmp = -12 - tmp; + tmp <<= 2; + ndis_power = (unsigned char)tmp; + } + } + } + TRACE2("%d", ndis_power); + res = mp_set(wnd, OID_802_11_TX_POWER_LEVEL, + &ndis_power, sizeof(ndis_power)); + if (res) + EXIT2(return -EOPNOTSUPP); + if (ndis_power == 0) + res = disassociate(wnd, 0); + EXIT2(return 0); +} + +static int iw_get_bitrate(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ULONG ndis_rate; + int res; + + ENTER2(""); + res = mp_query(wnd, OID_GEN_LINK_SPEED, &ndis_rate, sizeof(ndis_rate)); + if (res) { + WARNING("getting bitrate failed (%08X)", res); + ndis_rate = 0; + } + + wrqu->bitrate.value = ndis_rate * 100; + return 0; +} + +static int iw_set_bitrate(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int i, n; + NDIS_STATUS res; + ndis_rates_ex rates; + + ENTER2(""); + if (wrqu->bitrate.fixed == 0) + EXIT2(return 0); + + res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES, &rates, + sizeof(rates), &n, NULL); + if (res) { + WARNING("getting bit rate failed (%08X)", res); + EXIT2(return 0); + } + for (i = 0; i < n; i++) { + if (rates[i] & 0x80) + continue; + if ((rates[i] & 0x7f) * 500000 > wrqu->bitrate.value) { + TRACE2("setting rate %d to 0", + (rates[i] & 0x7f) * 500000); + rates[i] = 0; + } + } + + res = mp_set(wnd, OID_802_11_DESIRED_RATES, &rates, n); + if (res) { + WARNING("setting bit rate failed (%08X)", res); + EXIT2(return 0); + } + + return 0; +} + +static int iw_set_dummy(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + /* Do nothing. Used for ioctls that are not implemented. */ + return 0; +} + +static int iw_get_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_rts_threshold threshold; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_RTS_THRESHOLD, + &threshold, sizeof(threshold)); + if (res) + return -EOPNOTSUPP; + + wrqu->rts.value = threshold; + return 0; +} + +static int iw_set_rts_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_rts_threshold threshold; + NDIS_STATUS res; + + ENTER2(""); + threshold = wrqu->rts.value; + res = mp_set(wnd, OID_802_11_RTS_THRESHOLD, + &threshold, sizeof(threshold)); + if (res == NDIS_STATUS_INVALID_DATA) + return -EINVAL; + if (res) + return -EOPNOTSUPP; + + return 0; +} + +static int iw_get_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_fragmentation_threshold frag_threshold; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, + &frag_threshold, sizeof(frag_threshold)); + if (res) + return -ENOTSUPP; + + wrqu->frag.value = frag_threshold; + return 0; +} + +static int iw_set_frag_threshold(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + ndis_rts_threshold threshold; + NDIS_STATUS res; + + ENTER2(""); + threshold = wrqu->frag.value; + res = mp_set(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, + &threshold, sizeof(threshold)); + if (res == NDIS_STATUS_INVALID_DATA) + return -EINVAL; + if (res) + return -EOPNOTSUPP; + return 0; +} + +int get_ap_address(struct ndis_device *wnd, mac_address ap_addr) +{ + NDIS_STATUS res; + + res = mp_query(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN); + TRACE2(MACSTRSEP, MAC2STR(ap_addr)); + if (res) { + TRACE2("res: %08X", res); + memset(ap_addr, 0x0, ETH_ALEN); + EXIT2(return -EOPNOTSUPP); + } + EXIT2(return 0); +} + +static int iw_get_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + mac_address ap_addr; + + ENTER2(""); + get_ap_address(wnd, ap_addr); + memcpy(wrqu->ap_addr.sa_data, ap_addr, ETH_ALEN); + wrqu->ap_addr.sa_family = ARPHRD_ETHER; + EXIT2(return 0); +} + +static int iw_set_ap_address(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + mac_address ap_addr; + + ENTER2(""); + memcpy(ap_addr, wrqu->ap_addr.sa_data, ETH_ALEN); + TRACE2(MACSTRSEP, MAC2STR(ap_addr)); + res = mp_set(wnd, OID_802_11_BSSID, ap_addr, ETH_ALEN); + /* user apps may set ap's mac address, which is not required; + * they may fail to work if this function fails, so return + * success */ + if (res) + WARNING("setting AP mac address failed (%08X)", res); + + EXIT2(return 0); +} + +int set_iw_auth_mode(struct ndis_device *wnd, int wpa_version, + int auth_80211_alg) +{ + NDIS_STATUS res; + ULONG auth_mode; + + ENTER2("%d, %d", wpa_version, auth_80211_alg); + if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) { + if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) + auth_mode = Ndis802_11AuthModeWPA2; + else + auth_mode = Ndis802_11AuthModeWPA2PSK; + } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) { + if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_802_1X) + auth_mode = Ndis802_11AuthModeWPA; + else if (wnd->iw_auth_key_mgmt & IW_AUTH_KEY_MGMT_PSK) + auth_mode = Ndis802_11AuthModeWPAPSK; + else + auth_mode = Ndis802_11AuthModeWPANone; + } else if (auth_80211_alg & IW_AUTH_ALG_SHARED_KEY) { + if (auth_80211_alg & IW_AUTH_ALG_OPEN_SYSTEM) + auth_mode = Ndis802_11AuthModeAutoSwitch; + else + auth_mode = Ndis802_11AuthModeShared; + } else + auth_mode = Ndis802_11AuthModeOpen; + + res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode); + if (res) { + WARNING("setting auth mode to %u failed (%08X)", + auth_mode, res); + if (res == NDIS_STATUS_INVALID_DATA) + EXIT2(return -EINVAL); + return -EOPNOTSUPP; + } + wnd->iw_auth_wpa_version = wpa_version; + wnd->iw_auth_80211_alg = auth_80211_alg; + EXIT2(return 0); +} + +int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode) +{ + NDIS_STATUS res; + + ENTER2("%d", auth_mode); + res = mp_set_int(wnd, OID_802_11_AUTHENTICATION_MODE, auth_mode); + if (res) { + WARNING("setting auth mode to %u failed (%08X)", + auth_mode, res); + if (res == NDIS_STATUS_INVALID_DATA) + EXIT2(return -EINVAL); + return -EOPNOTSUPP; + } + switch (auth_mode) { + case Ndis802_11AuthModeWPA: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X; + break; + case Ndis802_11AuthModeWPAPSK: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; + case Ndis802_11AuthModeWPANone: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; + break; + case Ndis802_11AuthModeWPA2: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_802_1X; + break; + case Ndis802_11AuthModeWPA2PSK: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_WPA2; + wnd->iw_auth_key_mgmt = IW_AUTH_KEY_MGMT_PSK; + break; + case Ndis802_11AuthModeOpen: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_80211_alg = IW_AUTH_ALG_OPEN_SYSTEM; + break; + case Ndis802_11AuthModeShared: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY; + break; + case Ndis802_11AuthModeAutoSwitch: + wnd->iw_auth_wpa_version = IW_AUTH_WPA_VERSION_DISABLED; + wnd->iw_auth_80211_alg = IW_AUTH_ALG_SHARED_KEY; + wnd->iw_auth_80211_alg |= IW_AUTH_ALG_OPEN_SYSTEM; + break; + default: + WARNING("invalid authentication algorithm: %d", auth_mode); + break; + } + EXIT2(return 0); +} + +int set_auth_mode(struct ndis_device *wnd) +{ + return set_iw_auth_mode(wnd, wnd->iw_auth_wpa_version, + wnd->iw_auth_80211_alg); +} + +int get_ndis_auth_mode(struct ndis_device *wnd) +{ + ULONG mode; + NDIS_STATUS res; + + res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &mode); + if (res) { + WARNING("getting authentication mode failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + TRACE2("%d", mode); + return mode; +} + +int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise, + int cipher_groupwise) +{ + NDIS_STATUS res; + ULONG ndis_mode; + + ENTER2("%d, %d", cipher_pairwise, cipher_groupwise); + if (cipher_pairwise & IW_AUTH_CIPHER_CCMP) + ndis_mode = Ndis802_11Encryption3Enabled; + else if (cipher_pairwise & IW_AUTH_CIPHER_TKIP) + ndis_mode = Ndis802_11Encryption2Enabled; + else if (cipher_pairwise & + (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104)) + ndis_mode = Ndis802_11Encryption1Enabled; + else if (cipher_groupwise & IW_AUTH_CIPHER_CCMP) + ndis_mode = Ndis802_11Encryption3Enabled; + else if (cipher_groupwise & IW_AUTH_CIPHER_TKIP) + ndis_mode = Ndis802_11Encryption2Enabled; + else + ndis_mode = Ndis802_11EncryptionDisabled; + + res = mp_set_int(wnd, OID_802_11_ENCRYPTION_STATUS, ndis_mode); + if (res) { + WARNING("setting encryption mode to %u failed (%08X)", + ndis_mode, res); + if (res == NDIS_STATUS_INVALID_DATA) + EXIT2(return -EINVAL); + return -EOPNOTSUPP; + } + wnd->iw_auth_cipher_pairwise = cipher_pairwise; + wnd->iw_auth_cipher_group = cipher_groupwise; + EXIT2(return 0); +} + +int set_encr_mode(struct ndis_device *wnd) +{ + return set_iw_encr_mode(wnd, wnd->iw_auth_cipher_pairwise, + wnd->iw_auth_cipher_group); +} + +int get_ndis_encr_mode(struct ndis_device *wnd) +{ + ULONG mode; + NDIS_STATUS res; + + ENTER2(""); + res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &mode); + if (res) { + WARNING("getting encryption status failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } else + EXIT2(return mode); +} + +static int iw_get_encr(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int index, mode; + struct encr_info *encr_info = &wnd->encr_info; + + ENTER2("wnd = %p", wnd); + wrqu->data.length = 0; + extra[0] = 0; + + index = (wrqu->encoding.flags & IW_ENCODE_INDEX); + TRACE2("index = %u", index); + if (index > 0) + index--; + else + index = encr_info->tx_key_index; + + if (index < 0 || index >= MAX_ENCR_KEYS) { + WARNING("encryption index out of range (%u)", index); + EXIT2(return -EINVAL); + } + + if (index != encr_info->tx_key_index) { + if (encr_info->keys[index].length > 0) { + wrqu->data.flags |= IW_ENCODE_ENABLED; + wrqu->data.length = encr_info->keys[index].length; + memcpy(extra, encr_info->keys[index].key, + encr_info->keys[index].length); + } + else + wrqu->data.flags |= IW_ENCODE_DISABLED; + + EXIT2(return 0); + } + + /* transmit key */ + mode = get_ndis_encr_mode(wnd); + if (mode < 0) + EXIT2(return -EOPNOTSUPP); + + if (mode == Ndis802_11EncryptionDisabled || + mode == Ndis802_11EncryptionNotSupported) + wrqu->data.flags |= IW_ENCODE_DISABLED; + else { + if (mode == Ndis802_11Encryption1KeyAbsent || + mode == Ndis802_11Encryption2KeyAbsent || + mode == Ndis802_11Encryption3KeyAbsent) + wrqu->data.flags |= IW_ENCODE_NOKEY; + else { + wrqu->data.flags |= IW_ENCODE_ENABLED; + wrqu->encoding.flags |= index+1; + wrqu->data.length = encr_info->keys[index].length; + memcpy(extra, encr_info->keys[index].key, + encr_info->keys[index].length); + } + } + mode = get_ndis_auth_mode(wnd); + if (mode < 0) + EXIT2(return -EOPNOTSUPP); + + if (mode == Ndis802_11AuthModeOpen) + wrqu->data.flags |= IW_ENCODE_OPEN; + else if (mode == Ndis802_11AuthModeAutoSwitch) + wrqu->data.flags |= IW_ENCODE_RESTRICTED; + else // Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA etc. + wrqu->data.flags |= IW_ENCODE_RESTRICTED; + + EXIT2(return 0); +} + +/* index must be 0 - N, as per NDIS */ +int add_wep_key(struct ndis_device *wnd, char *key, int key_len, + int index) +{ + struct ndis_encr_key ndis_key; + NDIS_STATUS res; + + ENTER2("key index: %d, length: %d", index, key_len); + if (key_len <= 0 || key_len > NDIS_ENCODING_TOKEN_MAX) { + WARNING("invalid key length (%d)", key_len); + EXIT2(return -EINVAL); + } + if (index < 0 || index >= MAX_ENCR_KEYS) { + WARNING("invalid key index (%d)", index); + EXIT2(return -EINVAL); + } + ndis_key.struct_size = sizeof(ndis_key); + ndis_key.length = key_len; + memcpy(&ndis_key.key, key, key_len); + ndis_key.index = index; + + if (index == wnd->encr_info.tx_key_index) { + ndis_key.index |= (1 << 31); + res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_WEP104, + IW_AUTH_CIPHER_NONE); + if (res) + WARNING("encryption couldn't be enabled (%08X)", res); + } + TRACE2("key %d: " MACSTRSEP, index, MAC2STR(key)); + res = mp_set(wnd, OID_802_11_ADD_WEP, &ndis_key, sizeof(ndis_key)); + if (res) { + WARNING("adding encryption key %d failed (%08X)", + index+1, res); + EXIT2(return -EINVAL); + } + + /* Atheros driver messes up ndis_key during ADD_WEP, so + * don't rely on that; instead use info in key and key_len */ + wnd->encr_info.keys[index].length = key_len; + memcpy(&wnd->encr_info.keys[index].key, key, key_len); + + EXIT2(return 0); +} + +/* remove_key is for both wep and wpa */ +static int remove_key(struct ndis_device *wnd, int index, + mac_address bssid) +{ + NDIS_STATUS res; + if (wnd->encr_info.keys[index].length == 0) + EXIT2(return 0); + wnd->encr_info.keys[index].length = 0; + memset(&wnd->encr_info.keys[index].key, 0, + sizeof(wnd->encr_info.keys[index].length)); + if (wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_TKIP || + wnd->iw_auth_cipher_pairwise == IW_AUTH_CIPHER_CCMP || + wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_TKIP || + wnd->iw_auth_cipher_group == IW_AUTH_CIPHER_CCMP) { + struct ndis_remove_key remove_key; + remove_key.struct_size = sizeof(remove_key); + remove_key.index = index; + if (bssid) { + /* pairwise key */ + if (memcmp(bssid, "\xff\xff\xff\xff\xff\xff", + ETH_ALEN) != 0) + remove_key.index |= (1 << 30); + memcpy(remove_key.bssid, bssid, + sizeof(remove_key.bssid)); + } else + memset(remove_key.bssid, 0xff, + sizeof(remove_key.bssid)); + if (mp_set(wnd, OID_802_11_REMOVE_KEY, + &remove_key, sizeof(remove_key))) + EXIT2(return -EINVAL); + } else { + ndis_key_index keyindex = index; + res = mp_set_int(wnd, OID_802_11_REMOVE_WEP, keyindex); + if (res) { + WARNING("removing encryption key %d failed (%08X)", + keyindex, res); + EXIT2(return -EINVAL); + } + } + /* if it is transmit key, disable encryption */ + if (index == wnd->encr_info.tx_key_index) { + res = set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE, + IW_AUTH_CIPHER_NONE); + if (res) + WARNING("changing encr status failed (%08X)", res); + } + TRACE2("key %d removed", index); + EXIT2(return 0); +} + +static int iw_set_wep(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + unsigned int index, key_len; + struct encr_info *encr_info = &wnd->encr_info; + unsigned char *key; + + ENTER2(""); + index = (wrqu->encoding.flags & IW_ENCODE_INDEX); + TRACE2("index = %u", index); + + /* iwconfig gives index as 1 - N */ + if (index > 0) + index--; + else + index = encr_info->tx_key_index; + + if (index < 0 || index >= MAX_ENCR_KEYS) { + WARNING("encryption index out of range (%u)", index); + EXIT2(return -EINVAL); + } + + /* remove key if disabled */ + if (wrqu->data.flags & IW_ENCODE_DISABLED) { + if (remove_key(wnd, index, NULL)) + EXIT2(return -EINVAL); + else + EXIT2(return 0); + } + + /* global encryption state (for all keys) */ + if (wrqu->data.flags & IW_ENCODE_OPEN) + res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen); + else // if (wrqu->data.flags & IW_ENCODE_RESTRICTED) + res = set_ndis_auth_mode(wnd, Ndis802_11AuthModeShared); + if (res) { + WARNING("setting authentication mode failed (%08X)", res); + EXIT2(return -EINVAL); + } + + TRACE2("key length: %d", wrqu->data.length); + + if (wrqu->data.length > 0) { + key_len = wrqu->data.length; + key = extra; + } else { // must be set as tx key + if (encr_info->keys[index].length == 0) { + WARNING("key %d is not set", index+1); + EXIT2(return -EINVAL); + } + key_len = encr_info->keys[index].length; + key = encr_info->keys[index].key; + encr_info->tx_key_index = index; + } + + if (add_wep_key(wnd, key, key_len, index)) + EXIT2(return -EINVAL); + + if (index == encr_info->tx_key_index) { + /* if transmit key is at index other than 0, some + * drivers, at least Atheros and TI, want another + * (global) non-transmit key to be set; don't know why */ + if (index != 0) { + int i; + for (i = 0; i < MAX_ENCR_KEYS; i++) + if (i != index && + encr_info->keys[i].length != 0) + break; + if (i == MAX_ENCR_KEYS) { + if (index == 0) + i = index + 1; + else + i = index - 1; + if (add_wep_key(wnd, key, key_len, i)) + WARNING("couldn't add broadcast key" + " at %d", i); + } + } + /* ndis drivers want essid to be set after setting encr */ + set_essid(wnd, wnd->essid.essid, wnd->essid.length); + } + EXIT2(return 0); +} + +static int iw_set_nick(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + + if (wrqu->data.length >= IW_ESSID_MAX_SIZE || wrqu->data.length <= 0) + return -EINVAL; + memcpy(wnd->nick, extra, wrqu->data.length); + wnd->nick[wrqu->data.length] = 0; + return 0; +} + +static int iw_get_nick(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + + wrqu->data.length = strlen(wnd->nick); + memcpy(extra, wnd->nick, wrqu->data.length); + return 0; +} + +static char *ndis_translate_scan(struct net_device *dev, char *event, + char *end_buf, void *item, + struct iw_request_info *info) +{ + struct iw_event iwe; + char *current_val; + int i, nrates; + unsigned char buf[MAX_WPA_IE_LEN * 2 + 30]; + struct ndis_wlan_bssid *bssid; + struct ndis_wlan_bssid_ex *bssid_ex; + + ENTER2("%p, %p", event, item); + bssid = item; + bssid_ex = item; + /* add mac address */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + iwe.len = IW_EV_ADDR_LEN; + memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* add essid */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWESSID; + iwe.u.data.length = bssid->ssid.length; + if (iwe.u.data.length > IW_ESSID_MAX_SIZE) + iwe.u.data.length = IW_ESSID_MAX_SIZE; + iwe.u.data.flags = 1; + iwe.len = IW_EV_POINT_LEN + iwe.u.data.length; + event = iwe_stream_add_point(info, event, end_buf, &iwe, bssid->ssid.essid); + + /* add protocol name */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWNAME; + strncpy(iwe.u.name, network_type_to_name(bssid->net_type), IFNAMSIZ); + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_CHAR_LEN); + + /* add mode */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWMODE; + if (bssid->mode == Ndis802_11IBSS) + iwe.u.mode = IW_MODE_ADHOC; + else if (bssid->mode == Ndis802_11Infrastructure) + iwe.u.mode = IW_MODE_INFRA; + else // if (bssid->mode == Ndis802_11AutoUnknown) + iwe.u.mode = IW_MODE_AUTO; + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_UINT_LEN); + + /* add freq */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = bssid->config.ds_config; + if (bssid->config.ds_config > 1000000) { + iwe.u.freq.m = bssid->config.ds_config / 10; + iwe.u.freq.e = 1; + } + else + iwe.u.freq.m = bssid->config.ds_config; + /* convert from kHz to Hz */ + iwe.u.freq.e += 3; + iwe.len = IW_EV_FREQ_LEN; + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* add qual */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVQUAL; + i = 100 * (bssid->rssi - WL_NOISE) / (WL_SIGMAX - WL_NOISE); + if (i < 0) + i = 0; + else if (i > 100) + i = 100; + iwe.u.qual.level = bssid->rssi; + iwe.u.qual.noise = WL_NOISE; + iwe.u.qual.qual = i; + iwe.len = IW_EV_QUAL_LEN; + event = iwe_stream_add_event(info, event, end_buf, &iwe, IW_EV_QUAL_LEN); + + /* add key info */ + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = SIOCGIWENCODE; + if (bssid->privacy == Ndis802_11PrivFilterAcceptAll) + iwe.u.data.flags = IW_ENCODE_DISABLED; + else + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + iwe.u.data.length = 0; + iwe.len = IW_EV_POINT_LEN; + event = iwe_stream_add_point(info, event, end_buf, &iwe, bssid->ssid.essid); + + /* add rate */ + memset(&iwe, 0, sizeof(iwe)); + current_val = event + IW_EV_LCP_LEN; + iwe.cmd = SIOCGIWRATE; + if (bssid->length > sizeof(*bssid)) + nrates = NDIS_MAX_RATES_EX; + else + nrates = NDIS_MAX_RATES; + for (i = 0 ; i < nrates ; i++) { + if (bssid->rates[i] & 0x7f) { + iwe.u.bitrate.value = ((bssid->rates[i] & 0x7f) * + 500000); + current_val = iwe_stream_add_value(info, event, current_val, + end_buf, &iwe, + IW_EV_PARAM_LEN); + } + } + + if ((current_val - event) > IW_EV_LCP_LEN) + event = current_val; + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + sprintf(buf, "bcn_int=%d", bssid->config.beacon_period); + iwe.u.data.length = strlen(buf); + event = iwe_stream_add_point(info, event, end_buf, &iwe, buf); + + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVCUSTOM; + sprintf(buf, "atim=%u", bssid->config.atim_window); + iwe.u.data.length = strlen(buf); + event = iwe_stream_add_point(info, event, end_buf, &iwe, buf); + + TRACE2("%d, %u", bssid->length, (unsigned int)sizeof(*bssid)); + if (bssid->length > sizeof(*bssid)) { + unsigned char *iep = (unsigned char *)bssid_ex->ies + + sizeof(struct ndis_fixed_ies); + no_warn_unused unsigned char *end = iep + bssid_ex->ie_length; + + while (iep + 1 < end && iep + 2 + iep[1] <= end) { + unsigned char ielen = 2 + iep[1]; + + if (ielen > SSID_MAX_WPA_IE_LEN) { + iep += ielen; + continue; + } + if ((iep[0] == WLAN_EID_GENERIC && iep[1] >= 4 && + memcmp(iep + 2, "\x00\x50\xf2\x01", 4) == 0) || + iep[0] == RSN_INFO_ELEM) { + memset(&iwe, 0, sizeof(iwe)); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = ielen; + event = iwe_stream_add_point(info, event, end_buf, + &iwe, iep); + } + iep += ielen; + } + } + TRACE2("event = %p, current_val = %p", event, current_val); + EXIT2(return event); +} + +int set_scan(struct ndis_device *wnd) +{ + NDIS_STATUS res; + + ENTER2(""); + res = mp_set(wnd, OID_802_11_BSSID_LIST_SCAN, NULL, 0); + if (res) { + WARNING("scanning failed (%08X)", res); + EXIT2(return -EOPNOTSUPP); + } + wnd->scan_timestamp = jiffies; + EXIT2(return 0); +} + +static int iw_set_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + return set_scan(wnd); +} + +static int iw_get_scan(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + unsigned int i, list_len, needed; + NDIS_STATUS res; + struct ndis_bssid_list *bssid_list = NULL; + char *event = extra; + struct ndis_wlan_bssid *cur_item ; + + ENTER2(""); + if (time_before(jiffies, wnd->scan_timestamp + 3 * HZ)) + return -EAGAIN; + /* try with space for a few scan items */ + list_len = sizeof(ULONG) + sizeof(struct ndis_wlan_bssid_ex) * 8; + bssid_list = kmalloc(list_len, GFP_KERNEL); + if (!bssid_list) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + /* some drivers don't set bssid_list->num_items to 0 if + OID_802_11_BSSID_LIST returns no items (prism54 driver, e.g.,) */ + memset(bssid_list, 0, list_len); + + needed = 0; + res = mp_query_info(wnd, OID_802_11_BSSID_LIST, + bssid_list, list_len, NULL, &needed); + if (res == NDIS_STATUS_INVALID_LENGTH || + res == NDIS_STATUS_BUFFER_TOO_SHORT) { + /* now try with required space */ + kfree(bssid_list); + list_len = needed; + bssid_list = kmalloc(list_len, GFP_KERNEL); + if (!bssid_list) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + memset(bssid_list, 0, list_len); + + res = mp_query(wnd, OID_802_11_BSSID_LIST, + bssid_list, list_len); + } + if (res) { + WARNING("getting BSSID list failed (%08X)", res); + kfree(bssid_list); + EXIT2(return -EOPNOTSUPP); + } + TRACE2("%d", bssid_list->num_items); + cur_item = &bssid_list->bssid[0]; + for (i = 0; i < bssid_list->num_items; i++) { + event = ndis_translate_scan(dev, event, + extra + IW_SCAN_MAX_DATA, cur_item, info); + cur_item = (struct ndis_wlan_bssid *)((char *)cur_item + + cur_item->length); + } + wrqu->data.length = event - extra; + wrqu->data.flags = 0; + kfree(bssid_list); + EXIT2(return 0); +} + +static int iw_set_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ULONG power_mode; + + if (wrqu->power.disabled == 1) + power_mode = NDIS_POWER_OFF; + else if (wrqu->power.flags & IW_POWER_MIN) + power_mode = NDIS_POWER_MIN; + else // if (wrqu->power.flags & IW_POWER_MAX) + power_mode = NDIS_POWER_MAX; + + TRACE2("%d", power_mode); + res = mp_set(wnd, OID_802_11_POWER_MODE, + &power_mode, sizeof(power_mode)); + if (res) + WARNING("setting power mode failed (%08X)", res); + return 0; +} + +static int iw_get_power_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ULONG power_mode; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_POWER_MODE, + &power_mode, sizeof(power_mode)); + if (res) + return -ENOTSUPP; + + if (power_mode == NDIS_POWER_OFF) + wrqu->power.disabled = 1; + else { + if (wrqu->power.flags != 0) + return 0; + wrqu->power.flags |= IW_POWER_ALL_R; + wrqu->power.flags |= IW_POWER_TIMEOUT; + wrqu->power.value = 0; + wrqu->power.disabled = 0; + + if (power_mode == NDIS_POWER_MIN) + wrqu->power.flags |= IW_POWER_MIN; + else // if (power_mode == NDIS_POWER_MAX) + wrqu->power.flags |= IW_POWER_MAX; + } + return 0; +} + +static int iw_get_sensitivity(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ndis_rssi rssi_trigger; + + ENTER2(""); + res = mp_query(wnd, OID_802_11_RSSI_TRIGGER, + &rssi_trigger, sizeof(rssi_trigger)); + if (res) + return -EOPNOTSUPP; + wrqu->param.value = rssi_trigger; + wrqu->param.disabled = (rssi_trigger == 0); + wrqu->param.fixed = 1; + return 0; +} + +static int iw_set_sensitivity(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + ndis_rssi rssi_trigger; + + ENTER2(""); + if (wrqu->param.disabled) + rssi_trigger = 0; + else + rssi_trigger = wrqu->param.value; + res = mp_set(wnd, OID_802_11_RSSI_TRIGGER, + &rssi_trigger, sizeof(rssi_trigger)); + if (res == NDIS_STATUS_INVALID_DATA) + return -EINVAL; + if (res) + return -EOPNOTSUPP; + return 0; +} + +static int iw_get_ndis_stats(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct iw_statistics *stats = &wnd->iw_stats; + memcpy(&wrqu->qual, &stats->qual, sizeof(stats->qual)); + return 0; +} + +static int iw_get_range(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_range *range = (struct iw_range *)extra; + struct iw_point *data = &wrqu->data; + struct ndis_device *wnd = netdev_priv(dev); + unsigned int i, n; + NDIS_STATUS res; + ndis_rates_ex rates; + ndis_tx_power_level tx_power; + + ENTER2(""); + data->length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + + range->txpower_capa = IW_TXPOW_MWATT; + range->num_txpower = 0; + + res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, + &tx_power, sizeof(tx_power)); + if (!res) { + range->num_txpower = 1; + range->txpower[0] = tx_power; + } + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 18; + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->min_retry = 0; + range->max_retry = 255; + + range->num_channels = 1; + + range->max_qual.qual = 100; + range->max_qual.level = 154; + range->max_qual.noise = 154; + range->sensitivity = 3; + + range->max_encoding_tokens = 4; + range->num_encoding_sizes = 2; + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + + range->num_bitrates = 0; + memset(&rates, 0, sizeof(rates)); + res = mp_query_info(wnd, OID_802_11_SUPPORTED_RATES, + &rates, sizeof(rates), &n, NULL); + if (res) + WARNING("getting bit rates failed: %08X", res); + else { + for (i = 0; i < n && range->num_bitrates < IW_MAX_BITRATES; i++) + if (rates[i] & 0x80) + continue; + else if (rates[i] & 0x7f) { + range->bitrate[range->num_bitrates] = + (rates[i] & 0x7f) * 500000; + range->num_bitrates++; + } + } + + range->num_channels = (sizeof(freq_chan)/sizeof(freq_chan[0])); + + for (i = 0; i < (sizeof(freq_chan)/sizeof(freq_chan[0])) && + i < IW_MAX_FREQUENCIES; i++) { + range->freq[i].i = i + 1; + range->freq[i].m = freq_chan[i] * 100000; + range->freq[i].e = 1; + } + range->num_frequency = i; + + range->min_rts = 0; + range->max_rts = 2347; + range->min_frag = 256; + range->max_frag = 2346; + + /* Event capability (kernel + driver) */ + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | + IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) | + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; + range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVTXDROP) | + IW_EVENT_CAPA_MASK(IWEVCUSTOM) | + IW_EVENT_CAPA_MASK(IWEVREGISTERED) | + IW_EVENT_CAPA_MASK(IWEVEXPIRED)); + + range->enc_capa = 0; + + if (test_bit(Ndis802_11Encryption2Enabled, &wnd->capa.encr)) + range->enc_capa |= IW_ENC_CAPA_CIPHER_TKIP; + if (test_bit(Ndis802_11Encryption3Enabled, &wnd->capa.encr)) + range->enc_capa |= IW_ENC_CAPA_CIPHER_CCMP; + + if (test_bit(Ndis802_11AuthModeWPA, &wnd->capa.auth) || + test_bit(Ndis802_11AuthModeWPAPSK, &wnd->capa.auth)) + range->enc_capa |= IW_ENC_CAPA_WPA; + if (test_bit(Ndis802_11AuthModeWPA2, &wnd->capa.auth) || + test_bit(Ndis802_11AuthModeWPA2PSK, &wnd->capa.auth)) + range->enc_capa |= IW_ENC_CAPA_WPA2; + + return 0; +} + +void set_default_iw_params(struct ndis_device *wnd) +{ + wnd->iw_auth_key_mgmt = 0; + wnd->iw_auth_wpa_version = 0; + set_infra_mode(wnd, Ndis802_11Infrastructure); + set_ndis_auth_mode(wnd, Ndis802_11AuthModeOpen); + set_priv_filter(wnd); + set_iw_encr_mode(wnd, IW_AUTH_CIPHER_NONE, IW_AUTH_CIPHER_NONE); +} + +static int deauthenticate(struct ndis_device *wnd) +{ + int ret; + + ENTER2(""); + ret = disassociate(wnd, 1); + set_default_iw_params(wnd); + EXIT2(return ret); +} + +NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid) +{ + NDIS_STATUS res; + u8 buf[NDIS_ESSID_MAX_SIZE]; + int i; + + TRACE2(""); + res = mp_set(wnd, OID_802_11_DISASSOCIATE, NULL, 0); + /* disassociate causes radio to be turned off; if reset_ssid + * is given, set ssid to random to enable radio */ + if (reset_ssid) { + get_random_bytes(buf, sizeof(buf)); + for (i = 0; i < sizeof(buf); i++) + buf[i] = 'a' + (buf[i] % 26); + set_essid(wnd, buf, sizeof(buf)); + } + return res; +} + +static ULONG ndis_priv_mode(struct ndis_device *wnd) +{ + if (wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2 || + wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA) + return Ndis802_11PrivFilter8021xWEP; + else + return Ndis802_11PrivFilterAcceptAll; +} + +int set_priv_filter(struct ndis_device *wnd) +{ + NDIS_STATUS res; + ULONG flags; + + flags = ndis_priv_mode(wnd); + ENTER2("filter: %d", flags); + res = mp_set_int(wnd, OID_802_11_PRIVACY_FILTER, flags); + if (res) + TRACE2("setting privacy filter to %d failed (%08X)", + flags, res); + EXIT2(return 0); +} + +static int iw_set_mlme(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct iw_mlme *mlme = (struct iw_mlme *)extra; + + ENTER2(""); + switch (mlme->cmd) { + case IW_MLME_DEAUTH: + return deauthenticate(wnd); + case IW_MLME_DISASSOC: + TRACE2("cmd=%d reason_code=%d", mlme->cmd, mlme->reason_code); + return disassociate(wnd, 1); + default: + return -EOPNOTSUPP; + } + + return 0; +} + +static int iw_set_genie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + /* + * NDIS drivers do not allow IEs to be configured; this is + * done by the driver based on other configuration. Return 0 + * to avoid causing issues with user space programs that + * expect this function to succeed. + */ + return 0; +} + +static int iw_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + TRACE2("index=%d value=%d", wrqu->param.flags & IW_AUTH_INDEX, + wrqu->param.value); + switch (wrqu->param.flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + wnd->iw_auth_wpa_version = wrqu->param.value; + break; + case IW_AUTH_CIPHER_PAIRWISE: + wnd->iw_auth_cipher_pairwise = wrqu->param.value; + break; + case IW_AUTH_CIPHER_GROUP: + wnd->iw_auth_cipher_group = wrqu->param.value; + break; + case IW_AUTH_KEY_MGMT: + wnd->iw_auth_key_mgmt = wrqu->param.value; + break; + case IW_AUTH_80211_AUTH_ALG: + wnd->iw_auth_80211_alg = wrqu->param.value; + break; + case IW_AUTH_WPA_ENABLED: + if (wrqu->param.value) + deauthenticate(wnd); + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + case IW_AUTH_DROP_UNENCRYPTED: + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + case IW_AUTH_PRIVACY_INVOKED: + TRACE2("%d not implemented: %d", + wrqu->param.flags & IW_AUTH_INDEX, wrqu->param.value); + break; + default: + WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX); + return -EOPNOTSUPP; + } + return 0; +} + +static int iw_get_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + + ENTER2("index=%d", wrqu->param.flags & IW_AUTH_INDEX); + switch (wrqu->param.flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + wrqu->param.value = wnd->iw_auth_wpa_version; + break; + case IW_AUTH_CIPHER_PAIRWISE: + wrqu->param.value = wnd->iw_auth_cipher_pairwise; + break; + case IW_AUTH_CIPHER_GROUP: + wrqu->param.value = wnd->iw_auth_cipher_group; + break; + case IW_AUTH_KEY_MGMT: + wrqu->param.value = wnd->iw_auth_key_mgmt; + break; + case IW_AUTH_80211_AUTH_ALG: + wrqu->param.value = wnd->iw_auth_80211_alg; + break; + default: + WARNING("invalid cmd %d", wrqu->param.flags & IW_AUTH_INDEX); + return -EOPNOTSUPP; + } + return 0; +} + +static int iw_set_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + struct ndis_device *wnd = netdev_priv(dev); + struct ndis_add_key ndis_key; + int i, keyidx; + NDIS_STATUS res; + u8 *addr; + + keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; + ENTER2("%d", keyidx); + if (keyidx) + keyidx--; + else + keyidx = wnd->encr_info.tx_key_index; + + if (keyidx < 0 || keyidx >= MAX_ENCR_KEYS) + return -EINVAL; + + if (ext->alg == WPA_ALG_WEP) { + if (!test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr)) + EXIT2(return -1); + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + wnd->encr_info.tx_key_index = keyidx; + if (add_wep_key(wnd, ext->key, ext->key_len, keyidx)) + EXIT2(return -1); + else + EXIT2(return 0); + } + if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) || + ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) + EXIT2(return remove_key(wnd, keyidx, ndis_key.bssid)); + + if (ext->key_len > sizeof(ndis_key.key)) { + TRACE2("incorrect key length (%u)", ext->key_len); + EXIT2(return -1); + } + + memset(&ndis_key, 0, sizeof(ndis_key)); + + ndis_key.struct_size = + sizeof(ndis_key) - sizeof(ndis_key.key) + ext->key_len; + ndis_key.length = ext->key_len; + ndis_key.index = keyidx; + + if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) { + for (i = 0; i < 6 ; i++) + ndis_key.rsc |= (((u64)ext->rx_seq[i]) << (i * 8)); + TRACE2("0x%Lx", ndis_key.rsc); + ndis_key.index |= 1 << 29; + } + + addr = ext->addr.sa_data; + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + /* group key */ + if (wnd->infrastructure_mode == Ndis802_11IBSS) + memset(ndis_key.bssid, 0xff, ETH_ALEN); + else + get_ap_address(wnd, ndis_key.bssid); + } else { + /* pairwise key */ + ndis_key.index |= (1 << 30); + memcpy(ndis_key.bssid, addr, ETH_ALEN); + } + TRACE2(MACSTRSEP, MAC2STR(ndis_key.bssid)); + + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + ndis_key.index |= (1 << 31); + + if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) { + /* wpa_supplicant gives us the Michael MIC RX/TX keys in + * different order than NDIS spec, so swap the order here. */ + memcpy(ndis_key.key, ext->key, 16); + memcpy(ndis_key.key + 16, ext->key + 24, 8); + memcpy(ndis_key.key + 24, ext->key + 16, 8); + } else + memcpy(ndis_key.key, ext->key, ext->key_len); + + res = mp_set(wnd, OID_802_11_ADD_KEY, &ndis_key, ndis_key.struct_size); + if (res) { + TRACE2("adding key failed (%08X), %u", + res, ndis_key.struct_size); + EXIT2(return -1); + } + wnd->encr_info.keys[keyidx].length = ext->key_len; + memcpy(&wnd->encr_info.keys[keyidx].key, ndis_key.key, ext->key_len); + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) + wnd->encr_info.tx_key_index = keyidx; + TRACE2("key %d added", keyidx); + + EXIT2(return 0); +} + +static int iw_get_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + /* struct iw_encode_ext *ext = (struct iw_encode_ext *) extra; */ + /* TODO */ + ENTER2(""); + return 0; +} + +static int iw_set_pmksa(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_pmksa *pmksa = (struct iw_pmksa *)extra; + struct ndis_pmkid pmkid; + NDIS_STATUS res; + struct ndis_device *wnd = netdev_priv(dev); + + /* TODO: must keep local list of PMKIDs since NDIS drivers + * expect that all PMKID entries are included whenever a new + * one is added. */ + + ENTER2("%d", pmksa->cmd); + if ((pmksa->cmd == IW_PMKSA_ADD || pmksa->cmd == IW_PMKSA_REMOVE) && + (!(wnd->iw_auth_wpa_version & IW_AUTH_WPA_VERSION_WPA2))) + EXIT2(return -EOPNOTSUPP); + + memset(&pmkid, 0, sizeof(pmkid)); + if (pmksa->cmd == IW_PMKSA_ADD) { + pmkid.bssid_info_count = 1; + memcpy(pmkid.bssid_info[0].bssid, pmksa->bssid.sa_data, + ETH_ALEN); + memcpy(pmkid.bssid_info[0].pmkid, pmksa->pmkid, IW_PMKID_LEN); + } + pmkid.length = sizeof(pmkid); + + res = mp_set(wnd, OID_802_11_PMKID, &pmkid, pmkid.length); + if (res == NDIS_STATUS_FAILURE) + EXIT2(return -EOPNOTSUPP); + TRACE2("OID_802_11_PMKID -> %d", res); + if (res) + return -EINVAL; + + return 0; +} + +#define WEXT(id) [id - SIOCIWFIRST] + +static const iw_handler ndis_handler[] = { + WEXT(SIOCGIWNAME) = iw_get_network_type, + WEXT(SIOCSIWESSID) = iw_set_essid, + WEXT(SIOCGIWESSID) = iw_get_essid, + WEXT(SIOCSIWMODE) = iw_set_infra_mode, + WEXT(SIOCGIWMODE) = iw_get_infra_mode, + WEXT(SIOCGIWFREQ) = iw_get_freq, + WEXT(SIOCSIWFREQ) = iw_set_freq, + WEXT(SIOCGIWTXPOW) = iw_get_tx_power, + WEXT(SIOCSIWTXPOW) = iw_set_tx_power, + WEXT(SIOCGIWRATE) = iw_get_bitrate, + WEXT(SIOCSIWRATE) = iw_set_bitrate, + WEXT(SIOCGIWRTS) = iw_get_rts_threshold, + WEXT(SIOCSIWRTS) = iw_set_rts_threshold, + WEXT(SIOCGIWFRAG) = iw_get_frag_threshold, + WEXT(SIOCSIWFRAG) = iw_set_frag_threshold, + WEXT(SIOCGIWAP) = iw_get_ap_address, + WEXT(SIOCSIWAP) = iw_set_ap_address, + WEXT(SIOCSIWENCODE) = iw_set_wep, + WEXT(SIOCGIWENCODE) = iw_get_encr, + WEXT(SIOCSIWSCAN) = iw_set_scan, + WEXT(SIOCGIWSCAN) = iw_get_scan, + WEXT(SIOCGIWPOWER) = iw_get_power_mode, + WEXT(SIOCSIWPOWER) = iw_set_power_mode, + WEXT(SIOCGIWRANGE) = iw_get_range, + WEXT(SIOCGIWSTATS) = iw_get_ndis_stats, + WEXT(SIOCGIWSENS) = iw_get_sensitivity, + WEXT(SIOCSIWSENS) = iw_set_sensitivity, + WEXT(SIOCGIWNICKN) = iw_get_nick, + WEXT(SIOCSIWNICKN) = iw_set_nick, + WEXT(SIOCSIWCOMMIT) = iw_set_dummy, + WEXT(SIOCSIWMLME) = iw_set_mlme, + WEXT(SIOCSIWGENIE) = iw_set_genie, + WEXT(SIOCSIWAUTH) = iw_set_auth, + WEXT(SIOCGIWAUTH) = iw_get_auth, + WEXT(SIOCSIWENCODEEXT) = iw_set_encodeext, + WEXT(SIOCGIWENCODEEXT) = iw_get_encodeext, + WEXT(SIOCSIWPMKSA) = iw_set_pmksa, +}; + +/* private ioctl's */ + +static int priv_reset(struct net_device *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int res; + ENTER2(""); + res = mp_reset(netdev_priv(dev)); + if (res) { + WARNING("reset failed: %08X", res); + return -EOPNOTSUPP; + } + return 0; +} + +static int priv_deauthenticate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int res; + ENTER2(""); + res = deauthenticate(netdev_priv(dev)); + return res; +} + +static int priv_power_profile(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + struct miniport *mp; + ULONG profile_inf; + + ENTER2(""); + mp = &wnd->wd->driver->ndis_driver->mp; + if (!mp->pnp_event_notify) + EXIT2(return -EOPNOTSUPP); + + /* 1 for AC and 0 for Battery */ + if (wrqu->param.value) + profile_inf = NdisPowerProfileAcOnLine; + else + profile_inf = NdisPowerProfileBattery; + + LIN2WIN4(mp->pnp_event_notify, wnd->nmb->mp_ctx, + NdisDevicePnPEventPowerProfileChanged, + &profile_inf, sizeof(profile_inf)); + EXIT2(return 0); +} + +static int priv_network_type(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + enum network_type network_type; + NDIS_STATUS res; + char type; + + ENTER2(""); + type = wrqu->param.value; + if (type == 'f') + network_type = Ndis802_11FH; + else if (type == 'b') + network_type = Ndis802_11DS; + else if (type == 'a') + network_type = Ndis802_11OFDM5; + else if (type == 'g' || type == 'n') + network_type = Ndis802_11OFDM24; + else + network_type = Ndis802_11Automode; + + res = mp_set_int(wnd, OID_802_11_NETWORK_TYPE_IN_USE, network_type); + if (res) { + WARNING("setting network type to %d failed (%08X)", + network_type, res); + EXIT2(return -EINVAL); + } + + EXIT2(return 0); +} + +static int priv_media_stream_mode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + NDIS_STATUS res; + int mode; + + ENTER2(""); + if (wrqu->param.value > 0) + mode = Ndis802_11MediaStreamOn; + else + mode = Ndis802_11MediaStreamOff; + res = mp_set_int(wnd, OID_802_11_MEDIA_STREAM_MODE, mode); + if (res) { + WARNING("oid failed (%08X)", res); + EXIT2(return -EINVAL); + } + EXIT2(return 0); +} + +static int priv_reload_defaults(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct ndis_device *wnd = netdev_priv(dev); + int res; + ENTER2(""); + res = mp_set_int(wnd, OID_802_11_RELOAD_DEFAULTS, + Ndis802_11ReloadWEPKeys); + if (res) { + WARNING("reloading defaults failed: %08X", res); + return -EOPNOTSUPP; + } + return 0; +} + +static const struct iw_priv_args priv_args[] = { + {PRIV_RESET, 0, 0, "ndis_reset"}, + {PRIV_POWER_PROFILE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "power_profile"}, + {PRIV_DEAUTHENTICATE, 0, 0, "deauthenticate"}, + {PRIV_NETWORK_TYPE, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 1, 0, + "network_type"}, + {PRIV_MEDIA_STREAM_MODE, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "media_stream"}, + + {PRIV_RELOAD_DEFAULTS, 0, 0, "reload_defaults"}, +}; + +#define WEPRIV(id) [id - SIOCIWFIRSTPRIV] + +static const iw_handler priv_handler[] = { + WEPRIV(PRIV_RESET) = priv_reset, + WEPRIV(PRIV_POWER_PROFILE) = priv_power_profile, + WEPRIV(PRIV_DEAUTHENTICATE) = priv_deauthenticate, + WEPRIV(PRIV_NETWORK_TYPE) = priv_network_type, + WEPRIV(PRIV_MEDIA_STREAM_MODE) = priv_media_stream_mode, + WEPRIV(PRIV_RELOAD_DEFAULTS) = priv_reload_defaults, +}; + +const struct iw_handler_def ndis_handler_def = { + .num_standard = sizeof(ndis_handler) / sizeof(ndis_handler[0]), + .num_private = sizeof(priv_handler) / sizeof(priv_handler[0]), + .num_private_args = sizeof(priv_args) / sizeof(priv_args[0]), + + .standard = (iw_handler *)ndis_handler, + .private = (iw_handler *)priv_handler, + .private_args = (struct iw_priv_args *)priv_args, + .get_wireless_stats = get_iw_stats, +}; --- linux-2.6.28.orig/ubuntu/ndiswrapper/winnt_types.h +++ linux-2.6.28/ubuntu/ndiswrapper/winnt_types.h @@ -0,0 +1,1702 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _WINNT_TYPES_H_ +#define _WINNT_TYPES_H_ + +#define TRUE 1 +#define FALSE 0 + +#define PASSIVE_LEVEL 0 +#define APC_LEVEL 1 +#define DISPATCH_LEVEL 2 +#define DEVICE_LEVEL_BASE 4 + +/* soft interrupts / bottom-half's are disabled at SOFT_IRQL */ +#define SOFT_IRQL (DEVICE_LEVEL_BASE + 1) +#define DIRQL (DEVICE_LEVEL_BASE + 2) + +#define STATUS_WAIT_0 0 +#define STATUS_SUCCESS 0 +#define STATUS_ALERTED 0x00000101 +#define STATUS_TIMEOUT 0x00000102 +#define STATUS_PENDING 0x00000103 +#define STATUS_FAILURE 0xC0000001 +#define STATUS_NOT_IMPLEMENTED 0xC0000002 +#define STATUS_INVALID_PARAMETER 0xC000000D +#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 +#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 +#define STATUS_ACCESS_DENIED 0xC0000022 +#define STATUS_BUFFER_TOO_SMALL 0xC0000023 +#define STATUS_OBJECT_NAME_INVALID 0xC0000023 +#define STATUS_MUTANT_NOT_OWNED 0xC0000046 +#define STATUS_RESOURCES 0xC000009A +#define STATUS_DELETE_PENDING 0xC0000056 +#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A +#define STATUS_NOT_SUPPORTED 0xC00000BB +#define STATUS_INVALID_PARAMETER_2 0xC00000F0 +#define STATUS_NO_MEMORY 0xC0000017 +#define STATUS_CANCELLED 0xC0000120 +#define STATUS_DEVICE_REMOVED 0xC00002B6 +#define STATUS_DEVICE_NOT_CONNECTED 0xC000009D + +#define STATUS_BUFFER_OVERFLOW 0x80000005 + +#define SL_PENDING_RETURNED 0x01 +#define SL_INVOKE_ON_CANCEL 0x20 +#define SL_INVOKE_ON_SUCCESS 0x40 +#define SL_INVOKE_ON_ERROR 0x80 + +#define IRP_MJ_CREATE 0x00 +#define IRP_MJ_CREATE_NAMED_PIPE 0x01 +#define IRP_MJ_CLOSE 0x02 +#define IRP_MJ_READ 0x03 +#define IRP_MJ_WRITE 0x04 + +#define IRP_MJ_DEVICE_CONTROL 0x0E +#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0F +#define IRP_MJ_POWER 0x16 +#define IRP_MJ_SYSTEM_CONTROL 0x0E +#define IRP_MJ_PNP 0x1b +#define IRP_MJ_MAXIMUM_FUNCTION 0x1b + +#define IRP_MN_WAIT_WAKE 0x00 +#define IRP_MN_POWER_SEQUENCE 0x01 +#define IRP_MN_SET_POWER 0x02 +#define IRP_MN_QUERY_POWER 0x03 + +#define IRP_MN_REGINFO 0x08 +#define IRP_MN_REGINFO_EX 0x0b + +#define IRP_MN_START_DEVICE 0x00 +#define IRP_MN_QUERY_REMOVE_DEVICE 0x01 +#define IRP_MN_REMOVE_DEVICE 0x02 +#define IRP_MN_CANCEL_REMOVE_DEVICE 0x03 +#define IRP_MN_STOP_DEVICE 0x04 +#define IRP_MN_QUERY_STOP_DEVICE 0x05 +#define IRP_MN_CANCEL_STOP_DEVICE 0x06 +#define IRP_MN_QUERY_DEVICE_RELATIONS 0x07 +#define IRP_MN_QUERY_INTERFACE 0x08 + +#define IRP_BUFFERED_IO 0x00000010 +#define IRP_DEALLOCATE_BUFFER 0x00000020 +#define IRP_INPUT_OPERATION 0x00000040 + +#define IRP_DEFFER_IO_COMPLETION 0x00000800 + +#define THREAD_WAIT_OBJECTS 3 +#define MAX_WAIT_OBJECTS 64 + +#define LOW_PRIORITY 0 +#define LOW_REALTIME_PRIORITY 16 +#define HIGH_PRIORITY 31 +#define MAXIMUM_PRIORITY 32 + +#define PROCESSOR_FEATURE_MAX 64 + +#define IO_NO_INCREMENT 0 + +#define WMIREG_ACTION_REGISTER 1 +#define WMIREG_ACTION_DEREGISTER 2 +#define WMIREG_ACTION_REREGISTER 3 +#define WMIREG_ACTION_UPDATE_GUIDS 4 + +#define WMIREGISTER 0 +#define WMIUPDATE 1 + +#ifdef CONFIG_X86_64 +#define wstdcall +#define wfastcall +#define noregparm + +#define KI_USER_SHARED_DATA 0xfffff78000000000UL + +#else + +#define noregparm __attribute__((regparm(0))) +#define wstdcall __attribute__((__stdcall__, regparm(0))) +#if defined(__GNUC__) && ((__GNUC__ == 3 && __GNUC_MINOR__ > 3) || __GNUC__ > 3) +#undef fastcall +#define wfastcall __attribute__((fastcall)) +#else +#error "gcc 3.4 or newer should be used for compiling this module" +#endif + +#define KI_USER_SHARED_DATA 0xffdf0000 + +#endif + +#define packed __attribute__((packed)) +#define no_warn_unused __attribute__((unused)) + +typedef u8 BOOLEAN; +typedef u8 BYTE; +typedef u8 *LPBYTE; +typedef s8 CHAR; +typedef u8 UCHAR; +typedef s16 SHORT; +typedef u16 USHORT; +typedef u16 WORD; +typedef s32 INT; +typedef u32 UINT; +typedef u32 DWORD; +typedef s32 LONG; +typedef u32 ULONG; +typedef s64 LONGLONG; +typedef u64 ULONGLONG; +typedef u64 ULONGULONG; +typedef u64 ULONG64; + +typedef CHAR CCHAR; +typedef USHORT wchar_t; +typedef SHORT CSHORT; +typedef LONGLONG LARGE_INTEGER; + +typedef LONG NTSTATUS; + +typedef LONG KPRIORITY; +typedef LARGE_INTEGER PHYSICAL_ADDRESS; +typedef UCHAR KIRQL; +typedef CHAR KPROCESSOR_MODE; + +/* ULONG_PTR is 32 bits on 32-bit platforms and 64 bits on 64-bit + * platform, which is same as 'unsigned long' in Linux */ +typedef unsigned long ULONG_PTR; + +typedef ULONG_PTR SIZE_T; +typedef ULONG_PTR KAFFINITY; +typedef ULONG ACCESS_MASK; + +typedef ULONG_PTR PFN_NUMBER; +typedef ULONG SECURITY_INFORMATION; + +/* non-negative numbers indicate success */ +#define NT_SUCCESS(status) ((NTSTATUS)(status) >= 0) + +struct ansi_string { + USHORT length; + USHORT max_length; + char *buf; +}; + +struct unicode_string { + USHORT length; + USHORT max_length; + wchar_t *buf; +}; + +struct nt_slist { + struct nt_slist *next; +}; + +#ifdef CONFIG_X86_64 +/* it is not clear how nt_slist_head is used to store pointer to + * slists and depth; here we assume 'align' field is used to store + * depth and 'region' field is used to store slist pointers */ +struct nt_slist_head { + union { + USHORT depth; + ULONGLONG align; + }; + union { + ULONGLONG region; + struct nt_slist *next; + }; +} __attribute__((aligned(16))); +typedef struct nt_slist_head nt_slist_header; +#else +union nt_slist_head { + ULONGLONG align; + struct { + struct nt_slist *next; + USHORT depth; + USHORT sequence; + }; +}; +typedef union nt_slist_head nt_slist_header; +#endif + +struct nt_list { + struct nt_list *next; + struct nt_list *prev; +}; + +typedef ULONG_PTR NT_SPIN_LOCK; + +enum kdpc_importance {LowImportance, MediumImportance, HighImportance}; + +struct kdpc; +typedef void (*DPC)(struct kdpc *kdpc, void *ctx, void *arg1, + void *arg2) wstdcall; +struct kdpc { + SHORT type; + UCHAR nr_cpu; + UCHAR importance; + struct nt_list list; + DPC func; + void *ctx; + void *arg1; + void *arg2; + union { + NT_SPIN_LOCK *lock; + /* 'lock' is not used; 'queued' represents whether + * kdpc is queued or not */ + int queued; + }; +}; + +enum pool_type { + NonPagedPool, PagedPool, NonPagedPoolMustSucceed, DontUseThisType, + NonPagedPoolCacheAligned, PagedPoolCacheAligned, + NonPagedPoolCacheAlignedMustS, MaxPoolType, + NonPagedPoolSession = 32, + PagedPoolSession = NonPagedPoolSession + 1, + NonPagedPoolMustSucceedSession = PagedPoolSession + 1, + DontUseThisTypeSession = NonPagedPoolMustSucceedSession + 1, + NonPagedPoolCacheAlignedSession = DontUseThisTypeSession + 1, + PagedPoolCacheAlignedSession = NonPagedPoolCacheAlignedSession + 1, + NonPagedPoolCacheAlignedMustSSession = PagedPoolCacheAlignedSession + 1 +}; + +enum memory_caching_type_orig { + MmFrameBufferCached = 2 +}; + +enum memory_caching_type { + MmNonCached = FALSE, MmCached = TRUE, + MmWriteCombined = MmFrameBufferCached, MmHardwareCoherentCached, + MmNonCachedUnordered, MmUSWCCached, MmMaximumCacheType +}; + +enum lock_operation { + IoReadAccess, IoWriteAccess, IoModifyAccess +}; + +enum mode { + KernelMode, UserMode, MaximumMode +}; + +struct mdl { + struct mdl *next; + CSHORT size; + CSHORT flags; + /* NdisFreeBuffer doesn't pass pool, so we store pool in + * unused field 'process' */ + union { + void *process; + void *pool; + }; + void *mappedsystemva; + void *startva; + ULONG bytecount; + ULONG byteoffset; +}; + +#define MDL_MAPPED_TO_SYSTEM_VA 0x0001 +#define MDL_PAGES_LOCKED 0x0002 +#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004 +#define MDL_ALLOCATED_FIXED_SIZE 0x0008 +#define MDL_PARTIAL 0x0010 +#define MDL_PARTIAL_HAS_BEEN_MAPPED 0x0020 +#define MDL_IO_PAGE_READ 0x0040 +#define MDL_WRITE_OPERATION 0x0080 +#define MDL_PARENT_MAPPED_SYSTEM_VA 0x0100 +#define MDL_FREE_EXTRA_PTES 0x0200 +#define MDL_IO_SPACE 0x0800 +#define MDL_NETWORK_HEADER 0x1000 +#define MDL_MAPPING_CAN_FAIL 0x2000 +#define MDL_ALLOCATED_MUST_SUCCEED 0x4000 + +#define MDL_POOL_ALLOCATED 0x0400 +#define MDL_CACHE_ALLOCATED 0x8000 + +#define PAGE_START(ptr) ((void *)((ULONG_PTR)(ptr) & ~(PAGE_SIZE - 1))) +#define BYTE_OFFSET(ptr) ((ULONG)((ULONG_PTR)(ptr) & (PAGE_SIZE - 1))) + +#define MmGetMdlByteCount(mdl) ((mdl)->bytecount) +#define MmGetMdlVirtualAddress(mdl) ((mdl)->startva + (mdl)->byteoffset) +#define MmGetMdlByteOffset(mdl) ((mdl)->byteoffset) +#define MmGetSystemAddressForMdl(mdl) ((mdl)->mappedsystemva) +#define MmGetSystemAddressForMdlSafe(mdl, priority) ((mdl)->mappedsystemva) +#define MmGetMdlPfnArray(mdl) ((PFN_NUMBER *)(mdl + 1)) +#define MmInitializeMdl(mdl, baseva, length) \ +do { \ + (mdl)->next = NULL; \ + (mdl)->size = MmSizeOfMdl(baseva, length); \ + (mdl)->flags = 0; \ + (mdl)->startva = PAGE_START(baseva); \ + (mdl)->byteoffset = BYTE_OFFSET(baseva); \ + (mdl)->bytecount = length; \ + (mdl)->mappedsystemva = baseva; \ + TRACE4("%p %p %p %d %d", (mdl), baseva, (mdl)->startva, \ + (mdl)->byteoffset, length); \ +} while (0) + +struct kdevice_queue_entry { + struct nt_list list; + ULONG sort_key; + BOOLEAN inserted; +}; + +struct kdevice_queue { + USHORT type; + USHORT size; + struct nt_list list; + NT_SPIN_LOCK lock; + BOOLEAN busy; +}; + +struct wait_context_block { + struct kdevice_queue_entry wait_queue_entry; + void *device_routine; + void *device_context; + ULONG num_regs; + void *device_object; + void *current_irp; + void *buffer_chaining_dpc; +}; + +struct wait_block { + struct nt_list list; + struct task_struct *thread; + void *object; + int *wait_done; + USHORT wait_key; + USHORT wait_type; +}; + +struct dispatcher_header { + UCHAR type; + UCHAR absolute; + UCHAR size; + UCHAR inserted; + LONG signal_state; + struct nt_list wait_blocks; +}; + +enum event_type { + NotificationEvent, + SynchronizationEvent, +}; + +enum timer_type { + NotificationTimer = NotificationEvent, + SynchronizationTimer = SynchronizationEvent, +}; + +enum dh_type { + NotificationObject = NotificationEvent, + SynchronizationObject = SynchronizationEvent, + MutexObject, + SemaphoreObject, + ThreadObject, +}; + +enum wait_type { + WaitAll, WaitAny +}; + +/* objects that use dispatcher_header have it as the first field, so + * whenever we need to initialize dispatcher_header, we can convert + * that object into a nt_event and access dispatcher_header */ +struct nt_event { + struct dispatcher_header dh; +}; + +struct wrap_timer; + +#define WRAP_TIMER_MAGIC 47697249 + +struct nt_timer { + struct dispatcher_header dh; + /* We can't fit Linux timer in this structure. Instead of + * padding the nt_timer structure, we replace due_time field + * with *wrap_timer and allocate memory for it when nt_timer is + * initialized */ + union { + ULONGLONG due_time; + struct wrap_timer *wrap_timer; + }; + struct nt_list nt_timer_list; + struct kdpc *kdpc; + union { + LONG period; + LONG wrap_timer_magic; + }; +}; + +struct nt_mutex { + struct dispatcher_header dh; + struct nt_list list; + struct task_struct *owner_thread; + BOOLEAN abandoned; + BOOLEAN apc_disable; +}; + +struct nt_semaphore { + struct dispatcher_header dh; + LONG limit; +}; + +struct nt_thread { + struct dispatcher_header dh; + /* the rest in Windows is a long structure; since this + * structure is opaque to drivers, we just define what we + * need */ + int pid; + NTSTATUS status; + struct task_struct *task; + struct nt_list irps; + NT_SPIN_LOCK lock; + KPRIORITY prio; +}; + +#define set_object_type(dh, type) ((dh)->type = (type)) +#define is_notify_object(dh) ((dh)->type == NotificationObject) +#define is_synch_object(dh) ((dh)->type == SynchronizationObject) +#define is_mutex_object(dh) ((dh)->type == MutexObject) +#define is_semaphore_object(dh) ((dh)->type == SemaphoreObject) +#define is_nt_thread_object(dh) ((dh)->type == ThreadObject) + +#define IO_TYPE_ADAPTER 1 +#define IO_TYPE_CONTROLLER 2 +#define IO_TYPE_DEVICE 3 +#define IO_TYPE_DRIVER 4 +#define IO_TYPE_FILE 5 +#define IO_TYPE_IRP 6 +#define IO_TYPE_DEVICE_OBJECT_EXTENSION 13 + +struct irp; +struct dev_obj_ext; +struct driver_object; + +struct device_object { + CSHORT type; + USHORT size; + LONG ref_count; + struct driver_object *drv_obj; + struct device_object *next; + struct device_object *attached; + struct irp *current_irp; + void *io_timer; + ULONG flags; + ULONG characteristics; + void *vpb; + void *dev_ext; + CCHAR stack_count; + union { + struct nt_list queue_list; + struct wait_context_block wcb; + } queue; + ULONG align_req; + struct kdevice_queue dev_queue; + struct kdpc dpc; + ULONG active_threads; + void *security_desc; + struct nt_event lock; + USHORT sector_size; + USHORT spare1; + struct dev_obj_ext *dev_obj_ext; + void *reserved; +}; + +struct dev_obj_ext { + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + struct device_object *attached_to; +}; + +struct io_status_block { + union { + NTSTATUS status; + void *pointer; + }; + ULONG_PTR info; +}; + +#ifdef CONFIG_X86_64 +struct io_status_block32 { + NTSTATUS status; + ULONG info; +}; +#endif + +#define DEVICE_TYPE ULONG + +struct driver_extension; + +typedef NTSTATUS driver_dispatch_t(struct device_object *dev_obj, + struct irp *irp) wstdcall; + +struct driver_object { + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + ULONG flags; + void *start; + ULONG driver_size; + void *section; + struct driver_extension *drv_ext; + struct unicode_string name; + struct unicode_string *hardware_database; + void *fast_io_dispatch; + void *init; + void *start_io; + void (*unload)(struct driver_object *driver) wstdcall; + driver_dispatch_t *major_func[IRP_MJ_MAXIMUM_FUNCTION + 1]; +}; + +struct driver_extension { + struct driver_object *drv_obj; + NTSTATUS (*add_device)(struct driver_object *drv_obj, + struct device_object *dev_obj) wstdcall; + ULONG count; + struct unicode_string service_key_name; + struct nt_list custom_ext; +}; + +struct custom_ext { + struct nt_list list; + void *client_id; +}; + +struct wrap_bin_file; + +struct file_object { + CSHORT type; + CSHORT size; + struct device_object *dev_obj; + void *volume_parameter_block; + void *fs_context; + void *fs_context2; + void *section_object_pointer; + void *private_cache_map; + NTSTATUS final_status; + union { + struct file_object *related_file_object; + struct wrap_bin_file *wrap_bin_file; + }; + BOOLEAN lock_operation; + BOOLEAN delete_pending; + BOOLEAN read_access; + BOOLEAN write_access; + BOOLEAN delete_access; + BOOLEAN shared_read; + BOOLEAN shared_write; + BOOLEAN shared_delete; + ULONG flags; + struct unicode_string _name_; + LARGE_INTEGER current_byte_offset; + ULONG waiters; + ULONG busy; + void *last_lock; + struct nt_event lock; + struct nt_event event; + void *completion_context; +}; + +#ifdef CONFIG_X86_64 +#define POINTER_ALIGN __attribute__((aligned(8))) +#else +#define POINTER_ALIGN +#endif + +#define CACHE_ALIGN __attribute__((aligned(128))) + +enum system_power_state { + PowerSystemUnspecified = 0, + PowerSystemWorking, PowerSystemSleeping1, PowerSystemSleeping2, + PowerSystemSleeping3, PowerSystemHibernate, PowerSystemShutdown, + PowerSystemMaximum, +}; + +enum device_power_state { + PowerDeviceUnspecified = 0, + PowerDeviceD0, PowerDeviceD1, PowerDeviceD2, PowerDeviceD3, + PowerDeviceMaximum, +}; + +union power_state { + enum system_power_state system_state; + enum device_power_state device_state; +}; + +enum power_state_type { + SystemPowerState = 0, DevicePowerState, +}; + +enum power_action { + PowerActionNone = 0, + PowerActionReserved, PowerActionSleep, PowerActionHibernate, + PowerActionShutdown, PowerActionShutdownReset, PowerActionShutdownOff, + PowerActionWarmEject, +}; + +struct guid { + ULONG data1; + USHORT data2; + USHORT data3; + UCHAR data4[8]; +}; + +struct nt_interface { + USHORT size; + USHORT version; + void *context; + void (*reference)(void *context) wstdcall; + void (*dereference)(void *context) wstdcall; +}; + +enum interface_type { + InterfaceTypeUndefined = -1, Internal, Isa, Eisa, MicroChannel, + TurboChannel, PCIBus, VMEBus, NuBus, PCMCIABus, CBus, MPIBus, + MPSABus, ProcessorInternal, InternalPowerBus, PNPISABus, + PNPBus, MaximumInterfaceType, +}; + +#define CmResourceTypeNull 0 +#define CmResourceTypePort 1 +#define CmResourceTypeInterrupt 2 +#define CmResourceTypeMemory 3 +#define CmResourceTypeDma 4 +#define CmResourceTypeDeviceSpecific 5 +#define CmResourceTypeBusNumber 6 +#define CmResourceTypeMaximum 7 + +#define CmResourceTypeNonArbitrated 128 +#define CmResourceTypeConfigData 128 +#define CmResourceTypeDevicePrivate 129 +#define CmResourceTypePcCardConfig 130 +#define CmResourceTypeMfCardConfig 131 + +enum cm_share_disposition { + CmResourceShareUndetermined = 0, CmResourceShareDeviceExclusive, + CmResourceShareDriverExclusive, CmResourceShareShared +}; + +#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0 +#define CM_RESOURCE_INTERRUPT_LATCHED 1 +#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000 +#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001 +#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002 +#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004 + +#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008 +#define CM_RESOURCE_MEMORY_24 0x0010 +#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020 + +#define CM_RESOURCE_PORT_MEMORY 0x0000 +#define CM_RESOURCE_PORT_IO 0x0001 +#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004 +#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008 +#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010 +#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020 +#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040 +#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080 + +#define CM_RESOURCE_DMA_8 0x0000 +#define CM_RESOURCE_DMA_16 0x0001 +#define CM_RESOURCE_DMA_32 0x0002 +#define CM_RESOURCE_DMA_8_AND_16 0x0004 +#define CM_RESOURCE_DMA_BUS_MASTER 0x0008 +#define CM_RESOURCE_DMA_TYPE_A 0x0010 +#define CM_RESOURCE_DMA_TYPE_B 0x0020 +#define CM_RESOURCE_DMA_TYPE_F 0x0040 + +#define MAX_RESOURCES 20 + +#pragma pack(push,4) +struct cm_partial_resource_descriptor { + UCHAR type; + UCHAR share; + USHORT flags; + union { + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } generic; + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } port; + struct { + ULONG level; + ULONG vector; + KAFFINITY affinity; + } interrupt; + struct { + PHYSICAL_ADDRESS start; + ULONG length; + } memory; + struct { + ULONG channel; + ULONG port; + ULONG reserved1; + } dma; + struct { + ULONG data[3]; + } device_private; + struct { + ULONG start; + ULONG length; + ULONG reserved; + } bus_number; + struct { + ULONG data_size; + ULONG reserved1; + ULONG reserved2; + } device_specific_data; + } u; +}; +#pragma pack(pop) + +struct cm_partial_resource_list { + USHORT version; + USHORT revision; + ULONG count; + struct cm_partial_resource_descriptor partial_descriptors[1]; +}; + +struct cm_full_resource_descriptor { + enum interface_type interface_type; + ULONG bus_number; + struct cm_partial_resource_list partial_resource_list; +}; + +struct cm_resource_list { + ULONG count; + struct cm_full_resource_descriptor list[1]; +}; + +enum file_info_class { + FileDirectoryInformation = 1, + FileBasicInformation = 4, + FileStandardInformation = 5, + FileNameInformation = 9, + FilePositionInformation = 14, + FileAlignmentInformation = 17, + FileNetworkOpenInformation = 34, + FileAttributeTagInformation = 35, + FileMaximumInformation = 41, +}; + +enum fs_info_class { + FileFsVolumeInformation = 1, + /* ... */ + FileFsMaximumInformation = 9, +}; + +enum device_relation_type { + BusRelations, EjectionRelations, PowerRelations, RemovalRelations, + TargetDeviceRelation, SingleBusRelations, +}; + +enum bus_query_id_type { + BusQueryDeviceID = 0, BusQueryHardwareIDs = 1, + BusQueryCompatibleIDs = 2, BusQueryInstanceID = 3, + BusQueryDeviceSerialNumber = 4, +}; + +enum device_text_type { + DeviceTextDescription = 0, DeviceTextLocationInformation = 1, +}; + +enum device_usage_notification_type { + DeviceUsageTypeUndefined, DeviceUsageTypePaging, + DeviceUsageTypeHibernation, DevbiceUsageTypeDumpFile, +}; + +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +#define CTL_CODE(dev_type, func, method, access) \ + (((dev_type) << 16) | ((access) << 14) | ((func) << 2) | (method)) + +#define IO_METHOD_FROM_CTL_CODE(code) (code & 0x3) + +#ifndef CONFIG_X86_64 +#pragma pack(push,4) +#endif +struct io_stack_location { + UCHAR major_fn; + UCHAR minor_fn; + UCHAR flags; + UCHAR control; + union { + struct { + void *security_context; + ULONG options; + USHORT POINTER_ALIGN file_attributes; + USHORT share_access; + ULONG POINTER_ALIGN ea_length; + } create; + struct { + ULONG length; + ULONG POINTER_ALIGN key; + LARGE_INTEGER byte_offset; + } read; + struct { + ULONG length; + ULONG POINTER_ALIGN key; + LARGE_INTEGER byte_offset; + } write; + struct { + ULONG length; + enum file_info_class POINTER_ALIGN file_info_class; + } query_file; + struct { + ULONG length; + enum file_info_class POINTER_ALIGN file_info_class; + struct file_object *file_object; + union { + struct { + BOOLEAN replace_if_exists; + BOOLEAN advance_only; + }; + ULONG cluster_count; + void *delete_handle; + }; + } set_file; + struct { + ULONG length; + enum fs_info_class POINTER_ALIGN fs_info_class; + } query_volume; + struct { + ULONG output_buf_len; + ULONG POINTER_ALIGN input_buf_len; + ULONG POINTER_ALIGN code; + void *type3_input_buf; + } dev_ioctl; + struct { + SECURITY_INFORMATION security_info; + ULONG POINTER_ALIGN length; + } query_security; + struct { + SECURITY_INFORMATION security_info; + void *security_descriptor; + } set_security; + struct { + void *vpb; + struct device_object *device_object; + } mount_volume; + struct { + void *vpb; + struct device_object *device_object; + } verify_volume; + struct { + void *srb; + } scsi; + struct { + enum device_relation_type type; + } query_device_relations; + struct { + const struct guid *type; + USHORT size; + USHORT version; + struct nt_interface *intf; + void *intf_data; + } query_intf; + struct { + void *capabilities; + } device_capabilities; + struct { + void *io_resource_requirement_list; + } filter_resource_requirements; + struct { + ULONG which_space; + void *buffer; + ULONG offset; + ULONG POINTER_ALIGN length; + } read_write_config; + struct { + BOOLEAN lock; + } set_lock; + struct { + enum bus_query_id_type id_type; + } query_id; + struct { + enum device_text_type device_text_type; + ULONG POINTER_ALIGN locale_id; + } query_device_text; + struct { + BOOLEAN in_path; + BOOLEAN reserved[3]; + enum device_usage_notification_type POINTER_ALIGN type; + } usage_notification; + struct { + enum system_power_state power_state; + } wait_wake; + struct { + void *power_sequence; + } power_sequence; + struct { + ULONG sys_context; + enum power_state_type POINTER_ALIGN type; + union power_state POINTER_ALIGN state; + enum power_action POINTER_ALIGN shutdown_type; + } power; + struct { + struct cm_resource_list *allocated_resources; + struct cm_resource_list *allocated_resources_translated; + } start_device; + struct { + ULONG_PTR provider_id; + void *data_path; + ULONG buf_len; + void *buf; + } wmi; + struct { + void *arg1; + void *arg2; + void *arg3; + void *arg4; + } others; + } params; + struct device_object *dev_obj; + struct file_object *file_obj; + NTSTATUS (*completion_routine)(struct device_object *, + struct irp *, void *) wstdcall; + void *context; +}; +#ifndef CONFIG_X86_64 +#pragma pack(pop) +#endif + +struct kapc { + CSHORT type; + CSHORT size; + ULONG spare0; + struct nt_thread *thread; + struct nt_list list; + void *kernele_routine; + void *rundown_routine; + void *normal_routine; + void *normal_context; + void *sys_arg1; + void *sys_arg2; + CCHAR apc_state_index; + KPROCESSOR_MODE apc_mode; + BOOLEAN inserted; +}; + +#define IRP_NOCACHE 0x00000001 +#define IRP_SYNCHRONOUS_API 0x00000004 +#define IRP_ASSOCIATED_IRP 0x00000008 + +enum urb_state { + URB_INVALID = 1, URB_ALLOCATED, URB_SUBMITTED, + URB_COMPLETED, URB_FREE, URB_SUSPEND, URB_INT_UNLINKED }; + +struct wrap_urb { + struct nt_list list; + enum urb_state state; + struct nt_list complete_list; + unsigned int flags; + struct urb *urb; + struct irp *irp; +#ifdef USB_DEBUG + unsigned int id; +#endif +}; + +struct irp { + SHORT type; + USHORT size; + struct mdl *mdl; + ULONG flags; + union { + struct irp *master_irp; + LONG irp_count; + void *system_buffer; + } associated_irp; + struct nt_list thread_list; + struct io_status_block io_status; + KPROCESSOR_MODE requestor_mode; + BOOLEAN pending_returned; + CHAR stack_count; + CHAR current_location; + BOOLEAN cancel; + KIRQL cancel_irql; + CCHAR apc_env; + UCHAR alloc_flags; + struct io_status_block *user_status; + struct nt_event *user_event; + union { + struct { + void *user_apc_routine; + void *user_apc_context; + } async_params; + LARGE_INTEGER alloc_size; + } overlay; + void (*cancel_routine)(struct device_object *, struct irp *) wstdcall; + void *user_buf; + union { + struct { + union { + struct kdevice_queue_entry dev_q_entry; + struct { + void *driver_context[4]; + }; + }; + void *thread; + char *aux_buf; + struct { + struct nt_list list; + union { + struct io_stack_location *csl; + ULONG packet_type; + }; + }; + struct file_object *file_object; + } overlay; + union { + struct kapc apc; + /* space for apc is used for ndiswrapper + * specific fields */ + struct { + struct wrap_urb *wrap_urb; + struct wrap_device *wrap_device; + }; + }; + void *completion_key; + } tail; +}; + +#define IoSizeOfIrp(stack_count) \ + ((USHORT)(sizeof(struct irp) + \ + ((stack_count) * sizeof(struct io_stack_location)))) +#define IoGetCurrentIrpStackLocation(irp) \ + (irp)->tail.overlay.csl +#define IoGetNextIrpStackLocation(irp) \ + (IoGetCurrentIrpStackLocation(irp) - 1) +#define IoGetPreviousIrpStackLocation(irp) \ + (IoGetCurrentIrpStackLocation(irp) + 1) + +#define IoSetNextIrpStackLocation(irp) \ +do { \ + KIRQL _irql_; \ + IoAcquireCancelSpinLock(&_irql_); \ + (irp)->current_location--; \ + IoGetCurrentIrpStackLocation(irp)--; \ + IoReleaseCancelSpinLock(_irql_); \ +} while (0) + +#define IoSkipCurrentIrpStackLocation(irp) \ +do { \ + KIRQL _irql_; \ + IoAcquireCancelSpinLock(&_irql_); \ + (irp)->current_location++; \ + IoGetCurrentIrpStackLocation(irp)++; \ + IoReleaseCancelSpinLock(_irql_); \ +} while (0) + +static inline void +IoCopyCurrentIrpStackLocationToNext(struct irp *irp) +{ + struct io_stack_location *next; + next = IoGetNextIrpStackLocation(irp); + memcpy(next, IoGetCurrentIrpStackLocation(irp), + offsetof(struct io_stack_location, completion_routine)); + next->control = 0; +} + +static inline void +IoSetCompletionRoutine(struct irp *irp, void *routine, void *context, + BOOLEAN success, BOOLEAN error, BOOLEAN cancel) +{ + struct io_stack_location *irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->completion_routine = routine; + irp_sl->context = context; + irp_sl->control = 0; + if (success) + irp_sl->control |= SL_INVOKE_ON_SUCCESS; + if (error) + irp_sl->control |= SL_INVOKE_ON_ERROR; + if (cancel) + irp_sl->control |= SL_INVOKE_ON_CANCEL; +} + +#define IoMarkIrpPending(irp) \ + (IoGetCurrentIrpStackLocation((irp))->control |= SL_PENDING_RETURNED) +#define IoUnmarkIrpPending(irp) \ + (IoGetCurrentIrpStackLocation((irp))->control &= ~SL_PENDING_RETURNED) + +#define IRP_SL(irp, n) (((struct io_stack_location *)((irp) + 1)) + (n)) +#define IRP_DRIVER_CONTEXT(irp) (irp)->tail.overlay.driver_context +#define IoIrpThread(irp) ((irp)->tail.overlay.thread) + +#define IRP_URB(irp) \ + (union nt_urb *)(IoGetCurrentIrpStackLocation(irp)->params.others.arg1) + +#define IRP_WRAP_DEVICE(irp) (irp)->tail.wrap_device +#define IRP_WRAP_URB(irp) (irp)->tail.wrap_urb + +struct wmi_guid_reg_info { + struct guid *guid; + ULONG instance_count; + ULONG flags; +}; + +struct wmilib_context { + ULONG guid_count; + struct wmi_guid_reg_info *guid_list; + void *query_wmi_reg_info; + void *query_wmi_data_block; + void *set_wmi_data_block; + void *set_wmi_data_item; + void *execute_wmi_method; + void *wmi_function_control; +}; + +enum key_value_information_class { + KeyValueBasicInformation, KeyValueFullInformation, + KeyValuePartialInformation, KeyValueFullInformationAlign64, + KeyValuePartialInformationAlign64 +}; + +struct file_name_info { + ULONG length; + wchar_t *name; +}; + +struct file_std_info { + LARGE_INTEGER alloc_size; + LARGE_INTEGER eof; + ULONG num_links; + BOOLEAN delete_pending; + BOOLEAN dir; +}; + +enum nt_obj_type { + NT_OBJ_EVENT = 10, NT_OBJ_MUTEX, NT_OBJ_THREAD, NT_OBJ_TIMER, + NT_OBJ_SEMAPHORE, +}; + +enum common_object_type { + OBJECT_TYPE_NONE, OBJECT_TYPE_DEVICE, OBJECT_TYPE_DRIVER, + OBJECT_TYPE_NT_THREAD, OBJECT_TYPE_FILE, OBJECT_TYPE_CALLBACK, +}; + +struct common_object_header { + struct nt_list list; + enum common_object_type type; + UINT size; + UINT ref_count; + BOOLEAN close_in_process; + BOOLEAN permanent; + struct unicode_string name; +}; + +#define OBJECT_TO_HEADER(object) \ + (struct common_object_header *)((void *)(object) - \ + sizeof(struct common_object_header)) +#define OBJECT_SIZE(size) \ + ((size) + sizeof(struct common_object_header)) +#define HEADER_TO_OBJECT(hdr) \ + ((void *)(hdr) + sizeof(struct common_object_header)) +#define HANDLE_TO_OBJECT(handle) HEADER_TO_OBJECT(handle) +#define HANDLE_TO_HEADER(handle) (handle) + +enum work_queue_type { + CriticalWorkQueue, DelayedWorkQueue, HyperCriticalWorkQueue, + MaximumWorkQueue +}; + +typedef void (*NTOS_WORK_FUNC)(void *arg1, void *arg2) wstdcall; + +struct io_workitem { + enum work_queue_type type; + struct device_object *dev_obj; + NTOS_WORK_FUNC worker_routine; + void *context; +}; + +struct io_workitem_entry { + struct nt_list list; + struct io_workitem *io_workitem; +}; + +enum mm_page_priority { + LowPagePriority, NormalPagePriority = 16, HighPagePriority = 32 +}; + +enum kinterrupt_mode { + LevelSensitive, Latched +}; + +enum ntos_wait_reason { + Executive, FreePage, PageIn, PoolAllocation, DelayExecution, + Suspended, UserRequest, WrExecutive, WrFreePage, WrPageIn, + WrPoolAllocation, WrDelayExecution, WrSuspended, WrUserRequest, + WrEventPair, WrQueue, WrLpcReceive, WrLpcReply, WrVirtualMemory, + WrPageOut, WrRendezvous, Spare2, Spare3, Spare4, Spare5, Spare6, + WrKernel, MaximumWaitReason +}; + +typedef enum ntos_wait_reason KWAIT_REASON; + +typedef void *LOOKASIDE_ALLOC_FUNC(enum pool_type pool_type, + SIZE_T size, ULONG tag) wstdcall; +typedef void LOOKASIDE_FREE_FUNC(void *) wstdcall; + +struct npaged_lookaside_list { + nt_slist_header head; + USHORT depth; + USHORT maxdepth; + ULONG totalallocs; + union { + ULONG allocmisses; + ULONG allochits; + } u1; + ULONG totalfrees; + union { + ULONG freemisses; + ULONG freehits; + } u2; + enum pool_type pool_type; + ULONG tag; + ULONG size; + LOOKASIDE_ALLOC_FUNC *alloc_func; + LOOKASIDE_FREE_FUNC *free_func; + struct nt_list list; + ULONG lasttotallocs; + union { + ULONG lastallocmisses; + ULONG lastallochits; + } u3; + ULONG pad[2]; +#ifndef CONFIG_X86_64 + NT_SPIN_LOCK obsolete; +#endif +} +#ifdef CONFIG_X86_64 +CACHE_ALIGN +#endif +; + +enum device_registry_property { + DevicePropertyDeviceDescription, DevicePropertyHardwareID, + DevicePropertyCompatibleIDs, DevicePropertyBootConfiguration, + DevicePropertyBootConfigurationTranslated, + DevicePropertyClassName, DevicePropertyClassGuid, + DevicePropertyDriverKeyName, DevicePropertyManufacturer, + DevicePropertyFriendlyName, DevicePropertyLocationInformation, + DevicePropertyPhysicalDeviceObjectName, DevicePropertyBusTypeGuid, + DevicePropertyLegacyBusType, DevicePropertyBusNumber, + DevicePropertyEnumeratorName, DevicePropertyAddress, + DevicePropertyUINumber, DevicePropertyInstallState, + DevicePropertyRemovalPolicy +}; + +enum trace_information_class { + TraceIdClass, TraceHandleClass, TraceEnableFlagsClass, + TraceEnableLevelClass, GlobalLoggerHandleClass, EventLoggerHandleClass, + AllLoggerHandlesClass, TraceHandleByNameClass +}; + +struct kinterrupt; +typedef BOOLEAN (*PKSERVICE_ROUTINE)(struct kinterrupt *interrupt, + void *context) wstdcall; +typedef BOOLEAN (*PKSYNCHRONIZE_ROUTINE)(void *context) wstdcall; + +struct kinterrupt { + ULONG vector; + KAFFINITY cpu_mask; + NT_SPIN_LOCK lock; + NT_SPIN_LOCK *actual_lock; + BOOLEAN shared; + BOOLEAN save_fp; + union { + CHAR processor_number; +#ifdef CONFIG_DEBUG_SHIRQ + CHAR enabled; +#endif + } u; + PKSERVICE_ROUTINE isr; + void *isr_ctx; + struct nt_list list; + KIRQL irql; + KIRQL synch_irql; + enum kinterrupt_mode mode; +}; + +struct time_fields { + CSHORT year; + CSHORT month; + CSHORT day; + CSHORT hour; + CSHORT minute; + CSHORT second; + CSHORT milliseconds; + CSHORT weekday; +}; + +struct object_attributes { + ULONG length; + void *root_dir; + struct unicode_string *name; + ULONG attributes; + void *security_descr; + void *security_qos; +}; + +typedef void (*PCALLBACK_FUNCTION)(void *context, void *arg1, + void *arg2) wstdcall; + +struct callback_object; +struct callback_func { + PCALLBACK_FUNCTION func; + void *context; + struct nt_list list; + struct callback_object *object; +}; + +struct callback_object { + NT_SPIN_LOCK lock; + struct nt_list list; + struct nt_list callback_funcs; + BOOLEAN allow_multiple_callbacks; + struct object_attributes *attributes; +}; + +enum section_inherit { + ViewShare = 1, ViewUnmap = 2 +}; + +struct ksystem_time { + ULONG low_part; + LONG high1_time; + LONG high2_time; +}; + +enum nt_product_type { + nt_product_win_nt = 1, nt_product_lan_man_nt, nt_product_server +}; + +enum alt_arch_type { + arch_type_standard, arch_type_nex98x86, end_alternatives +}; + +struct kuser_shared_data { + ULONG tick_count; + ULONG tick_count_multiplier; + volatile struct ksystem_time interrupt_time; + volatile struct ksystem_time system_time; + volatile struct ksystem_time time_zone_bias; + USHORT image_number_low; + USHORT image_number_high; + wchar_t nt_system_root[260]; + ULONG max_stack_trace_depth; + ULONG crypto_exponent; + ULONG time_zone_id; + ULONG large_page_min; + ULONG reserved2[7]; + enum nt_product_type nt_product_type; + BOOLEAN product_type_is_valid; + ULONG nt_major_version; + ULONG nt_minor_version; + BOOLEAN processor_features[PROCESSOR_FEATURE_MAX]; + ULONG reserved1; + ULONG reserved3; + volatile LONG time_slip; + enum alt_arch_type alt_arch_type; + LARGE_INTEGER system_expiration_date; + ULONG suite_mask; + BOOLEAN kdbg_enabled; + volatile ULONG active_console; + volatile ULONG dismount_count; + ULONG com_plus_package; + ULONG last_system_rite_event_tick_count; + ULONG num_phys_pages; + BOOLEAN safe_boot_mode; + ULONG trace_log; + ULONGLONG fill0; + ULONGLONG sys_call[4]; + union { + volatile struct ksystem_time tick_count; + volatile ULONG64 tick_count_quad; + } tick; +}; + +#define REG_NONE (0) +#define REG_SZ (1) +#define REG_EXPAND_SZ (2) +#define REG_BINARY (3) +#define REG_DWORD (4) + +#define RTL_REGISTRY_ABSOLUTE 0 +#define RTL_REGISTRY_SERVICES 1 +#define RTL_REGISTRY_CONTROL 2 +#define RTL_REGISTRY_WINDOWS_NT 3 +#define RTL_REGISTRY_DEVICEMAP 4 +#define RTL_REGISTRY_USER 5 +#define RTL_REGISTRY_MAXIMUM 6 +#define RTL_REGISTRY_HANDLE 0x40000000 +#define RTL_REGISTRY_OPTIONAL 0x80000000 + +#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 +#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 +#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 +#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 +#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 +#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 +#define RTL_QUERY_REGISTRY_DELETE 0x00000040 + +typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)(wchar_t *name, ULONG type, + void *data, ULONG length, + void *context, + void *entry) wstdcall; + +struct rtl_query_registry_table { + PRTL_QUERY_REGISTRY_ROUTINE query_func; + ULONG flags; + wchar_t *name; + void *context; + ULONG def_type; + void *def_data; + ULONG def_length; +}; + +struct io_remove_lock { + BOOLEAN removed; + BOOLEAN reserved[3]; + LONG io_count; + struct nt_event remove_event; +}; + +struct io_error_log_packet { + UCHAR major_fn_code; + UCHAR retry_count; + USHORT dump_data_size; + USHORT nr_of_strings; + USHORT string_offset; + USHORT event_category; + NTSTATUS error_code; + ULONG unique_error_value; + NTSTATUS final_status; + ULONG sequence_number; + ULONG io_control_code; + LARGE_INTEGER device_offset; + ULONG dump_data[1]; +}; + +/* some of the functions below are slightly different from DDK's + * implementation; e.g., Insert functions return appropriate + * pointer */ + +/* instead of using Linux's lists, we implement list manipulation + * functions because nt_list is used by drivers and we don't want to + * worry about Linux's list being different from nt_list (right now + * they are same, but in future they could be different) */ + +static inline void InitializeListHead(struct nt_list *head) +{ + head->next = head->prev = head; +} + +static inline BOOLEAN IsListEmpty(struct nt_list *head) +{ + if (head == head->next) + return TRUE; + else + return FALSE; +} + +static inline void RemoveEntryList(struct nt_list *entry) +{ + entry->prev->next = entry->next; + entry->next->prev = entry->prev; +} + +static inline struct nt_list *RemoveHeadList(struct nt_list *head) +{ + struct nt_list *entry; + + entry = head->next; + if (entry == head) + return NULL; + else { + RemoveEntryList(entry); + return entry; + } +} + +static inline struct nt_list *RemoveTailList(struct nt_list *head) +{ + struct nt_list *entry; + + entry = head->prev; + if (entry == head) + return NULL; + else { + RemoveEntryList(entry); + return entry; + } +} + +static inline void InsertListEntry(struct nt_list *entry, struct nt_list *prev, + struct nt_list *next) +{ + next->prev = entry; + entry->next = next; + entry->prev = prev; + prev->next = entry; +} + +static inline struct nt_list *InsertHeadList(struct nt_list *head, + struct nt_list *entry) +{ + struct nt_list *ret; + + if (IsListEmpty(head)) + ret = NULL; + else + ret = head->next; + + InsertListEntry(entry, head, head->next); + return ret; +} + +static inline struct nt_list *InsertTailList(struct nt_list *head, + struct nt_list *entry) +{ + struct nt_list *ret; + + if (IsListEmpty(head)) + ret = NULL; + else + ret = head->prev; + + InsertListEntry(entry, head->prev, head); + return ret; +} + +#define nt_list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = pos->next) + +#define nt_list_for_each_entry(pos, head, member) \ + for (pos = container_of((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = container_of(pos->member.next, typeof(*pos), member)) + +#define nt_list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + +/* device object flags */ +#define DO_VERIFY_VOLUME 0x00000002 +#define DO_BUFFERED_IO 0x00000004 +#define DO_EXCLUSIVE 0x00000008 +#define DO_DIRECT_IO 0x00000010 +#define DO_MAP_IO_BUFFER 0x00000020 +#define DO_DEVICE_HAS_NAME 0x00000040 +#define DO_DEVICE_INITIALIZING 0x00000080 +#define DO_SYSTEM_BOOT_PARTITION 0x00000100 +#define DO_LONG_TERM_REQUESTS 0x00000200 +#define DO_NEVER_LAST_DEVICE 0x00000400 +#define DO_SHUTDOWN_REGISTERED 0x00000800 +#define DO_BUS_ENUMERATED_DEVICE 0x00001000 +#define DO_POWER_PAGABLE 0x00002000 +#define DO_POWER_INRUSH 0x00004000 +#define DO_LOW_PRIORITY_FILESYSTEM 0x00010000 + +/* Various supported device types (used with IoCreateDevice()) */ + +#define FILE_DEVICE_BEEP 0x00000001 +#define FILE_DEVICE_CD_ROM 0x00000002 +#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 +#define FILE_DEVICE_CONTROLLER 0x00000004 +#define FILE_DEVICE_DATALINK 0x00000005 +#define FILE_DEVICE_DFS 0x00000006 +#define FILE_DEVICE_DISK 0x00000007 +#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008 +#define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#define FILE_DEVICE_INPORT_PORT 0x0000000A +#define FILE_DEVICE_KEYBOARD 0x0000000B +#define FILE_DEVICE_MAILSLOT 0x0000000C +#define FILE_DEVICE_MIDI_IN 0x0000000D +#define FILE_DEVICE_MIDI_OUT 0x0000000E +#define FILE_DEVICE_MOUSE 0x0000000F +#define FILE_DEVICE_MULTI_UNC_PROVIDER 0x00000010 +#define FILE_DEVICE_NAMED_PIPE 0x00000011 +#define FILE_DEVICE_NETWORK 0x00000012 +#define FILE_DEVICE_NETWORK_BROWSER 0x00000013 +#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014 +#define FILE_DEVICE_NULL 0x00000015 +#define FILE_DEVICE_PARALLEL_PORT 0x00000016 +#define FILE_DEVICE_PHYSICAL_NETCARD 0x00000017 +#define FILE_DEVICE_PRINTER 0x00000018 +#define FILE_DEVICE_SCANNER 0x00000019 +#define FILE_DEVICE_SERIAL_MOUSE_PORT 0x0000001A +#define FILE_DEVICE_SERIAL_PORT 0x0000001B +#define FILE_DEVICE_SCREEN 0x0000001C +#define FILE_DEVICE_SOUND 0x0000001D +#define FILE_DEVICE_STREAMS 0x0000001E +#define FILE_DEVICE_TAPE 0x0000001F +#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020 +#define FILE_DEVICE_TRANSPORT 0x00000021 +#define FILE_DEVICE_UNKNOWN 0x00000022 +#define FILE_DEVICE_VIDEO 0x00000023 +#define FILE_DEVICE_VIRTUAL_DISK 0x00000024 +#define FILE_DEVICE_WAVE_IN 0x00000025 +#define FILE_DEVICE_WAVE_OUT 0x00000026 +#define FILE_DEVICE_8042_PORT 0x00000027 +#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028 +#define FILE_DEVICE_BATTERY 0x00000029 +#define FILE_DEVICE_BUS_EXTENDER 0x0000002A +#define FILE_DEVICE_MODEM 0x0000002B +#define FILE_DEVICE_VDM 0x0000002C +#define FILE_DEVICE_MASS_STORAGE 0x0000002D +#define FILE_DEVICE_SMB 0x0000002E +#define FILE_DEVICE_KS 0x0000002F +#define FILE_DEVICE_CHANGER 0x00000030 +#define FILE_DEVICE_SMARTCARD 0x00000031 +#define FILE_DEVICE_ACPI 0x00000032 +#define FILE_DEVICE_DVD 0x00000033 +#define FILE_DEVICE_FULLSCREEN_VIDEO 0x00000034 +#define FILE_DEVICE_DFS_FILE_SYSTEM 0x00000035 +#define FILE_DEVICE_DFS_VOLUME 0x00000036 +#define FILE_DEVICE_SERENUM 0x00000037 +#define FILE_DEVICE_TERMSRV 0x00000038 +#define FILE_DEVICE_KSEC 0x00000039 +#define FILE_DEVICE_FIPS 0x0000003A + +/* Device characteristics */ + +#define FILE_REMOVABLE_MEDIA 0x00000001 +#define FILE_READ_ONLY_DEVICE 0x00000002 +#define FILE_FLOPPY_DISKETTE 0x00000004 +#define FILE_WRITE_ONCE_MEDIA 0x00000008 +#define FILE_REMOTE_DEVICE 0x00000010 +#define FILE_DEVICE_IS_MOUNTED 0x00000020 +#define FILE_VIRTUAL_VOLUME 0x00000040 +#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080 +#define FILE_DEVICE_SECURE_OPEN 0x00000100 + +#define FILE_READ_DATA 0x0001 +#define FILE_WRITE_DATA 0x0002 + +#define FILE_SUPERSEDED 0x00000000 +#define FILE_OPENED 0x00000001 +#define FILE_CREATED 0x00000002 +#define FILE_OVERWRITTEN 0x00000003 +#define FILE_EXISTS 0x00000004 +#define FILE_DOES_NOT_EXIST 0x00000005 + + +#endif /* WINNT_TYPES_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/ntoskernel.c +++ linux-2.6.28/ubuntu/ndiswrapper/ntoskernel.c @@ -0,0 +1,2677 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ntoskernel.h" +#include "ndis.h" +#include "usb.h" +#include "pnp.h" +#include "loader.h" +#include "ntoskernel_exports.h" + +/* MDLs describe a range of virtual address with an array of physical + * pages right after the header. For different ranges of virtual + * addresses, the number of entries of physical pages may be different + * (depending on number of entries required). If we want to allocate + * MDLs from a pool, the size has to be constant. So we assume that + * maximum range used by a driver is MDL_CACHE_PAGES; if a driver + * requests an MDL for a bigger region, we allocate it with kmalloc; + * otherwise, we allocate from the pool */ + +#define MDL_CACHE_PAGES 3 +#define MDL_CACHE_SIZE (sizeof(struct mdl) + \ + (sizeof(PFN_NUMBER) * MDL_CACHE_PAGES)) +struct wrap_mdl { + struct nt_list list; + struct mdl mdl[0]; +}; + +/* everything here is for all drivers/devices - not per driver/device */ +static spinlock_t dispatcher_lock; +spinlock_t ntoskernel_lock; +static void *mdl_cache; +static struct nt_list wrap_mdl_list; + +static work_struct_t kdpc_work; +static void kdpc_worker(worker_param_t dummy); + +static struct nt_list kdpc_list; +static spinlock_t kdpc_list_lock; + +static struct nt_list callback_objects; + +struct nt_list object_list; + +struct bus_driver { + struct nt_list list; + char name[MAX_DRIVER_NAME_LEN]; + struct driver_object drv_obj; +}; + +static struct nt_list bus_driver_list; + +static work_struct_t ntos_work; +static struct nt_list ntos_work_list; +static spinlock_t ntos_work_lock; +static void ntos_work_worker(worker_param_t dummy); +static struct nt_thread *ntos_worker_thread; +spinlock_t irp_cancel_lock; +static NT_SPIN_LOCK nt_list_lock; +static struct nt_slist wrap_timer_slist; + +/* compute ticks (100ns) since 1601 until when system booted into + * wrap_ticks_to_boot */ +u64 wrap_ticks_to_boot; + +#if defined(CONFIG_X86_64) +static struct timer_list shared_data_timer; +struct kuser_shared_data kuser_shared_data; +static void update_user_shared_data_proc(unsigned long data); +#endif + +WIN_SYMBOL_MAP("KeTickCount", &jiffies) + +WIN_SYMBOL_MAP("NlsMbCodePageTag", FALSE) + +workqueue_struct_t *ntos_wq; + +#ifdef WRAP_PREEMPT +DEFINE_PER_CPU(irql_info_t, irql_info); +#endif + +#if defined(CONFIG_X86_64) +static void update_user_shared_data_proc(unsigned long data) +{ + /* timer is supposed to be scheduled every 10ms, but bigger + * intervals seem to work (tried upto 50ms) */ + *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601(); + *((ULONG64 *)&kuser_shared_data.interrupt_time) = + jiffies * TICKSPERSEC / HZ; + *((ULONG64 *)&kuser_shared_data.tick) = jiffies; + + mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30)); +} +#endif + +void *allocate_object(ULONG size, enum common_object_type type, + struct unicode_string *name) +{ + struct common_object_header *hdr; + void *body; + + /* we pad header as prefix to body */ + hdr = ExAllocatePoolWithTag(NonPagedPool, OBJECT_SIZE(size), 0); + if (!hdr) { + WARNING("couldn't allocate memory"); + return NULL; + } + memset(hdr, 0, OBJECT_SIZE(size)); + if (name) { + hdr->name.buf = ExAllocatePoolWithTag(NonPagedPool, + name->max_length, 0); + if (!hdr->name.buf) { + ExFreePool(hdr); + return NULL; + } + memcpy(hdr->name.buf, name->buf, name->max_length); + hdr->name.length = name->length; + hdr->name.max_length = name->max_length; + } + hdr->type = type; + hdr->ref_count = 1; + spin_lock_bh(&ntoskernel_lock); + /* threads are looked up often (in KeWaitForXXX), so optimize + * for fast lookups of threads */ + if (type == OBJECT_TYPE_NT_THREAD) + InsertHeadList(&object_list, &hdr->list); + else + InsertTailList(&object_list, &hdr->list); + spin_unlock_bh(&ntoskernel_lock); + body = HEADER_TO_OBJECT(hdr); + TRACE3("allocated hdr: %p, body: %p", hdr, body); + return body; +} + +void free_object(void *object) +{ + struct common_object_header *hdr; + + hdr = OBJECT_TO_HEADER(object); + spin_lock_bh(&ntoskernel_lock); + RemoveEntryList(&hdr->list); + spin_unlock_bh(&ntoskernel_lock); + TRACE3("freed hdr: %p, body: %p", hdr, object); + if (hdr->name.buf) + ExFreePool(hdr->name.buf); + ExFreePool(hdr); +} + +static int add_bus_driver(const char *name) +{ + struct bus_driver *bus_driver; + + bus_driver = kzalloc(sizeof(*bus_driver), GFP_KERNEL); + if (!bus_driver) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + strncpy(bus_driver->name, name, sizeof(bus_driver->name)); + bus_driver->name[sizeof(bus_driver->name)-1] = 0; + spin_lock_bh(&ntoskernel_lock); + InsertTailList(&bus_driver_list, &bus_driver->list); + spin_unlock_bh(&ntoskernel_lock); + TRACE1("bus driver %s is at %p", name, &bus_driver->drv_obj); + return STATUS_SUCCESS; +} + +struct driver_object *find_bus_driver(const char *name) +{ + struct bus_driver *bus_driver; + struct driver_object *drv_obj; + + spin_lock_bh(&ntoskernel_lock); + drv_obj = NULL; + nt_list_for_each_entry(bus_driver, &bus_driver_list, list) { + if (strcmp(bus_driver->name, name) == 0) { + drv_obj = &bus_driver->drv_obj; + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + return drv_obj; +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertHeadList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + struct nt_list *first; + unsigned long flags; + + ENTER5("head = %p, entry = %p", head, entry); + nt_spin_lock_irqsave(lock, flags); + first = InsertHeadList(head, entry); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, old = %p", head, first); + return first; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertHeadList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedInsertHeadList(head, entry, lock); +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedInsertTailList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + struct nt_list *last; + unsigned long flags; + + ENTER5("head = %p, entry = %p", head, entry); + nt_spin_lock_irqsave(lock, flags); + last = InsertTailList(head, entry); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, old = %p", head, last); + return last; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedInsertTailList,3) + (struct nt_list *head, struct nt_list *entry, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedInsertTailList(head, entry, lock); +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveHeadList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + struct nt_list *ret; + unsigned long flags; + + ENTER5("head = %p", head); + nt_spin_lock_irqsave(lock, flags); + ret = RemoveHeadList(head); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, ret = %p", head, ret); + return ret; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveHeadList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedRemoveHeadList(head, lock); +} + +wfastcall struct nt_list *WIN_FUNC(ExfInterlockedRemoveTailList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + struct nt_list *ret; + unsigned long flags; + + ENTER5("head = %p", head); + nt_spin_lock_irqsave(lock, flags); + ret = RemoveTailList(head); + nt_spin_unlock_irqrestore(lock, flags); + TRACE5("head = %p, ret = %p", head, ret); + return ret; +} + +wfastcall struct nt_list *WIN_FUNC(ExInterlockedRemoveTailList,2) + (struct nt_list *head, NT_SPIN_LOCK *lock) +{ + ENTER5("%p", head); + return ExfInterlockedRemoveTailList(head, lock); +} + +wfastcall void WIN_FUNC(InitializeSListHead,1) + (nt_slist_header *head) +{ + memset(head, 0, sizeof(*head)); +} + +wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPushEntrySList,3) + (nt_slist_header *head, struct nt_slist *entry, NT_SPIN_LOCK *lock) +{ + struct nt_slist *ret; + + ret = PushEntrySList(head, entry, lock); + return ret; +} + +wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPushEntrySList,2) + (nt_slist_header *head, struct nt_slist *entry) +{ + struct nt_slist *ret; + + ret = PushEntrySList(head, entry, &nt_list_lock); + return ret; +} + +wfastcall struct nt_slist *WIN_FUNC(InterlockedPushEntrySList,2) + (nt_slist_header *head, struct nt_slist *entry) +{ + struct nt_slist *ret; + + ret = PushEntrySList(head, entry, &nt_list_lock); + return ret; +} + +wfastcall struct nt_slist *WIN_FUNC(ExInterlockedPopEntrySList,2) + (nt_slist_header *head, NT_SPIN_LOCK *lock) +{ + struct nt_slist *ret; + + ret = PopEntrySList(head, lock); + return ret; +} + +wstdcall struct nt_slist *WIN_FUNC(ExpInterlockedPopEntrySList,1) + (nt_slist_header *head) +{ + struct nt_slist *ret; + + ret = PopEntrySList(head, &nt_list_lock); + return ret; +} + +wfastcall struct nt_slist *WIN_FUNC(InterlockedPopEntrySList,1) + (nt_slist_header *head) +{ + struct nt_slist *ret; + + ret = PopEntrySList(head, &nt_list_lock); + return ret; +} + +wstdcall USHORT WIN_FUNC(ExQueryDepthSList,1) + (nt_slist_header *head) +{ + USHORT depth; + ENTER5("%p", head); + depth = head->depth; + TRACE5("%d, %p", depth, head->next); + return depth; +} + +wfastcall LONG WIN_FUNC(InterlockedIncrement,1) + (LONG volatile *val) +{ + return post_atomic_add(*val, 1); +} + +wfastcall LONG WIN_FUNC(InterlockedDecrement,1) + (LONG volatile *val) +{ + return post_atomic_add(*val, -1); +} + +wfastcall LONG WIN_FUNC(InterlockedExchange,2) + (LONG volatile *target, LONG val) +{ + return xchg(target, val); +} + +wfastcall LONG WIN_FUNC(InterlockedCompareExchange,3) + (LONG volatile *dest, LONG new, LONG old) +{ + return cmpxchg(dest, old, new); +} + +wfastcall void WIN_FUNC(ExInterlockedAddLargeStatistic,2) + (LARGE_INTEGER volatile *plint, ULONG n) +{ + unsigned long flags; + + local_irq_save(flags); +#ifdef CONFIG_X86_64 + __asm__ __volatile__( + "\n" + LOCK_PREFIX "add %1, %0\n\t" + : "+m" (*plint) + : "r" (n)); +#else + __asm__ __volatile__( + "1:\t" + " movl %1, %%ebx\n\t" + " movl %%edx, %%ecx\n\t" + " addl %%eax, %%ebx\n\t" + " adcl $0, %%ecx\n\t" + LOCK_PREFIX "cmpxchg8b %0\n\t" + " jnz 1b\n\t" + : "+m" (*plint) + : "m" (n), "A" (*plint) + : "ebx", "ecx"); +#endif + local_irq_restore(flags); +} + +static void initialize_object(struct dispatcher_header *dh, enum dh_type type, + int state) +{ + memset(dh, 0, sizeof(*dh)); + set_object_type(dh, type); + dh->signal_state = state; + InitializeListHead(&dh->wait_blocks); +} + +static void timer_proc(unsigned long data) +{ + struct wrap_timer *wrap_timer = (struct wrap_timer *)data; + struct nt_timer *nt_timer; + struct kdpc *kdpc; + + nt_timer = wrap_timer->nt_timer; + TIMERENTER("%p(%p), %lu", wrap_timer, nt_timer, jiffies); +#ifdef TIMER_DEBUG + BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); + BUG_ON(nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); +#endif + kdpc = nt_timer->kdpc; + if (kdpc) + queue_kdpc(kdpc); + KeSetEvent((struct nt_event *)nt_timer, 0, FALSE); + if (wrap_timer->repeat) + mod_timer(&wrap_timer->timer, jiffies + wrap_timer->repeat); + TIMEREXIT(return); +} + +void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type, + struct ndis_mp_block *nmb) +{ + struct wrap_timer *wrap_timer; + + /* TODO: if a timer is initialized more than once, we allocate + * memory for wrap_timer more than once for the same nt_timer, + * wasting memory. We can check if nt_timer->wrap_timer_magic is + * set and not allocate, but it is not guaranteed always to be + * safe */ + TIMERENTER("%p", nt_timer); + /* we allocate memory for wrap_timer behind driver's back and + * there is no NDIS/DDK function where this memory can be + * freed, so we use slack_kmalloc so it gets freed when driver + * is unloaded */ + if (nmb) + wrap_timer = kmalloc(sizeof(*wrap_timer), irql_gfp()); + else + wrap_timer = slack_kmalloc(sizeof(*wrap_timer)); + if (!wrap_timer) { + ERROR("couldn't allocate memory for timer"); + return; + } + + memset(wrap_timer, 0, sizeof(*wrap_timer)); + init_timer(&wrap_timer->timer); + wrap_timer->timer.data = (unsigned long)wrap_timer; + wrap_timer->timer.function = timer_proc; + wrap_timer->nt_timer = nt_timer; +#ifdef TIMER_DEBUG + wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; +#endif + nt_timer->wrap_timer = wrap_timer; + nt_timer->kdpc = NULL; + initialize_object(&nt_timer->dh, type, 0); + nt_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; + TIMERTRACE("timer %p (%p)", wrap_timer, nt_timer); + spin_lock_bh(&ntoskernel_lock); + if (nmb) { + wrap_timer->slist.next = nmb->wnd->wrap_timer_slist.next; + nmb->wnd->wrap_timer_slist.next = &wrap_timer->slist; + } else { + wrap_timer->slist.next = wrap_timer_slist.next; + wrap_timer_slist.next = &wrap_timer->slist; + } + spin_unlock_bh(&ntoskernel_lock); + TIMEREXIT(return); +} + +wstdcall void WIN_FUNC(KeInitializeTimerEx,2) + (struct nt_timer *nt_timer, enum timer_type type) +{ + TIMERENTER("%p", nt_timer); + wrap_init_timer(nt_timer, type, NULL); +} + +wstdcall void WIN_FUNC(KeInitializeTimer,1) + (struct nt_timer *nt_timer) +{ + TIMERENTER("%p", nt_timer); + wrap_init_timer(nt_timer, NotificationTimer, NULL); +} + +/* expires and repeat are in HZ */ +BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz, + unsigned long repeat_hz, struct kdpc *kdpc) +{ + struct wrap_timer *wrap_timer; + + TIMERENTER("%p, %lu, %lu, %p, %lu", + nt_timer, expires_hz, repeat_hz, kdpc, jiffies); + + wrap_timer = nt_timer->wrap_timer; + TIMERTRACE("%p", wrap_timer); +#ifdef TIMER_DEBUG + if (wrap_timer->nt_timer != nt_timer) + WARNING("bad timers: %p, %p, %p", wrap_timer, nt_timer, + wrap_timer->nt_timer); + if (nt_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) { + WARNING("buggy Windows timer didn't initialize timer %p", + nt_timer); + return FALSE; + } + if (wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC) { + WARNING("timer %p is not initialized (%lx)?", + wrap_timer, wrap_timer->wrap_timer_magic); + wrap_timer->wrap_timer_magic = WRAP_TIMER_MAGIC; + } +#endif + KeClearEvent((struct nt_event *)nt_timer); + nt_timer->kdpc = kdpc; + wrap_timer->repeat = repeat_hz; + if (mod_timer(&wrap_timer->timer, jiffies + expires_hz)) + TIMEREXIT(return TRUE); + else + TIMEREXIT(return FALSE); +} + +wstdcall BOOLEAN WIN_FUNC(KeSetTimerEx,4) + (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + LONG period_ms, struct kdpc *kdpc) +{ + unsigned long expires_hz, repeat_hz; + + TIMERENTER("%p, %Ld, %d", nt_timer, duetime_ticks, period_ms); + expires_hz = SYSTEM_TIME_TO_HZ(duetime_ticks); + repeat_hz = MSEC_TO_HZ(period_ms); + return wrap_set_timer(nt_timer, expires_hz, repeat_hz, kdpc); +} + +wstdcall BOOLEAN WIN_FUNC(KeSetTimer,3) + (struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + struct kdpc *kdpc) +{ + TIMERENTER("%p, %Ld, %p", nt_timer, duetime_ticks, kdpc); + return KeSetTimerEx(nt_timer, duetime_ticks, 0, kdpc); +} + +wstdcall BOOLEAN WIN_FUNC(KeCancelTimer,1) + (struct nt_timer *nt_timer) +{ + struct wrap_timer *wrap_timer; + int ret; + + TIMERENTER("%p", nt_timer); + wrap_timer = nt_timer->wrap_timer; + if (!wrap_timer) { + ERROR("invalid wrap_timer"); + return TRUE; + } +#ifdef TIMER_DEBUG + BUG_ON(wrap_timer->wrap_timer_magic != WRAP_TIMER_MAGIC); +#endif + TIMERTRACE("canceling timer %p(%p)", wrap_timer, nt_timer); + /* disable timer before deleting so if it is periodic timer, it + * won't be re-armed after deleting */ + wrap_timer->repeat = 0; + ret = del_timer(&wrap_timer->timer); + /* the documentation for KeCancelTimer suggests the DPC is + * deqeued, but actually DPC is left to run */ + if (ret) + TIMEREXIT(return TRUE); + else + TIMEREXIT(return FALSE); +} + +wstdcall BOOLEAN WIN_FUNC(KeReadStateTimer,1) + (struct nt_timer *nt_timer) +{ + if (nt_timer->dh.signal_state) + return TRUE; + else + return FALSE; +} + +wstdcall void WIN_FUNC(KeInitializeDpc,3) + (struct kdpc *kdpc, void *func, void *ctx) +{ + ENTER3("%p, %p, %p", kdpc, func, ctx); + memset(kdpc, 0, sizeof(*kdpc)); + kdpc->func = func; + kdpc->ctx = ctx; + InitializeListHead(&kdpc->list); +} + +static void kdpc_worker(worker_param_t dummy) +{ + struct nt_list *entry; + struct kdpc *kdpc; + unsigned long flags; + KIRQL irql; + + WORKENTER(""); + irql = raise_irql(DISPATCH_LEVEL); + while (1) { + spin_lock_irqsave(&kdpc_list_lock, flags); + entry = RemoveHeadList(&kdpc_list); + if (entry) { + kdpc = container_of(entry, struct kdpc, list); + assert(kdpc->queued); + kdpc->queued = 0; + } else + kdpc = NULL; + spin_unlock_irqrestore(&kdpc_list_lock, flags); + if (!kdpc) + break; + WORKTRACE("%p, %p, %p, %p, %p", kdpc, kdpc->func, kdpc->ctx, + kdpc->arg1, kdpc->arg2); + assert_irql(_irql_ == DISPATCH_LEVEL); + LIN2WIN4(kdpc->func, kdpc, kdpc->ctx, kdpc->arg1, kdpc->arg2); + assert_irql(_irql_ == DISPATCH_LEVEL); + } + lower_irql(irql); + WORKEXIT(return); +} + +wstdcall void WIN_FUNC(KeFlushQueuedDpcs,0) + (void) +{ + kdpc_worker(NULL); +} + +BOOLEAN queue_kdpc(struct kdpc *kdpc) +{ + BOOLEAN ret; + unsigned long flags; + + WORKENTER("%p", kdpc); + spin_lock_irqsave(&kdpc_list_lock, flags); + if (kdpc->queued) + ret = FALSE; + else { + if (unlikely(kdpc->importance == HighImportance)) + InsertHeadList(&kdpc_list, &kdpc->list); + else + InsertTailList(&kdpc_list, &kdpc->list); + kdpc->queued = 1; + ret = TRUE; + } + spin_unlock_irqrestore(&kdpc_list_lock, flags); + if (ret == TRUE) + schedule_ntos_work(&kdpc_work); + WORKTRACE("%d", ret); + return ret; +} + +BOOLEAN dequeue_kdpc(struct kdpc *kdpc) +{ + BOOLEAN ret; + unsigned long flags; + + WORKENTER("%p", kdpc); + spin_lock_irqsave(&kdpc_list_lock, flags); + if (kdpc->queued) { + RemoveEntryList(&kdpc->list); + kdpc->queued = 0; + ret = TRUE; + } else + ret = FALSE; + spin_unlock_irqrestore(&kdpc_list_lock, flags); + WORKTRACE("%d", ret); + return ret; +} + +wstdcall BOOLEAN WIN_FUNC(KeInsertQueueDpc,3) + (struct kdpc *kdpc, void *arg1, void *arg2) +{ + WORKENTER("%p, %p, %p", kdpc, arg1, arg2); + kdpc->arg1 = arg1; + kdpc->arg2 = arg2; + return queue_kdpc(kdpc); +} + +wstdcall BOOLEAN WIN_FUNC(KeRemoveQueueDpc,1) + (struct kdpc *kdpc) +{ + return dequeue_kdpc(kdpc); +} + +wstdcall void WIN_FUNC(KeSetImportanceDpc,2) + (struct kdpc *kdpc, enum kdpc_importance importance) +{ + kdpc->importance = importance; +} + +static void ntos_work_worker(worker_param_t dummy) +{ + struct ntos_work_item *ntos_work_item; + struct nt_list *cur; + + while (1) { + spin_lock_bh(&ntos_work_lock); + cur = RemoveHeadList(&ntos_work_list); + spin_unlock_bh(&ntos_work_lock); + if (!cur) + break; + ntos_work_item = container_of(cur, struct ntos_work_item, list); + WORKTRACE("%p: executing %p, %p, %p", current, + ntos_work_item->func, ntos_work_item->arg1, + ntos_work_item->arg2); + LIN2WIN2(ntos_work_item->func, ntos_work_item->arg1, + ntos_work_item->arg2); + kfree(ntos_work_item); + } + WORKEXIT(return); +} + +int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2) +{ + struct ntos_work_item *ntos_work_item; + + WORKENTER("adding work: %p, %p, %p", func, arg1, arg2); + ntos_work_item = kmalloc(sizeof(*ntos_work_item), irql_gfp()); + if (!ntos_work_item) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + ntos_work_item->func = func; + ntos_work_item->arg1 = arg1; + ntos_work_item->arg2 = arg2; + spin_lock_bh(&ntos_work_lock); + InsertTailList(&ntos_work_list, &ntos_work_item->list); + spin_unlock_bh(&ntos_work_lock); + schedule_ntos_work(&ntos_work); + WORKEXIT(return 0); +} + +wstdcall void WIN_FUNC(KeInitializeSpinLock,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + nt_spin_lock_init(lock); +} + +wstdcall void WIN_FUNC(KeAcquireSpinLock,2) + (NT_SPIN_LOCK *lock, KIRQL *irql) +{ + ENTER6("%p", lock); + *irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); +} + +wstdcall void WIN_FUNC(KeReleaseSpinLock,2) + (NT_SPIN_LOCK *lock, KIRQL oldirql) +{ + ENTER6("%p", lock); + nt_spin_unlock_irql(lock, oldirql); +} + +wstdcall void WIN_FUNC(KeAcquireSpinLockAtDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + nt_spin_lock(lock); +} + +wstdcall void WIN_FUNC(KeReleaseSpinLockFromDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + nt_spin_unlock(lock); +} + +wstdcall void WIN_FUNC(KeRaiseIrql,2) + (KIRQL newirql, KIRQL *oldirql) +{ + ENTER6("%d", newirql); + *oldirql = raise_irql(newirql); +} + +wstdcall KIRQL WIN_FUNC(KeRaiseIrqlToDpcLevel,0) + (void) +{ + return raise_irql(DISPATCH_LEVEL); +} + +wstdcall void WIN_FUNC(KeLowerIrql,1) + (KIRQL irql) +{ + ENTER6("%d", irql); + lower_irql(irql); +} + +wstdcall KIRQL WIN_FUNC(KeAcquireSpinLockRaiseToDpc,1) + (NT_SPIN_LOCK *lock) +{ + ENTER6("%p", lock); + return nt_spin_lock_irql(lock, DISPATCH_LEVEL); +} + +#undef ExAllocatePoolWithTag + +wstdcall void *WIN_FUNC(ExAllocatePoolWithTag,3) + (enum pool_type pool_type, SIZE_T size, ULONG tag) +{ + void *addr; + + ENTER4("pool_type: %d, size: %lu, tag: 0x%x", pool_type, size, tag); + assert_irql(_irql_ <= DISPATCH_LEVEL); + if (size < PAGE_SIZE) + addr = kmalloc(size, irql_gfp()); + else { + if (irql_gfp() & GFP_ATOMIC) { + addr = __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, + PAGE_KERNEL); + TRACE1("%p, %lu", addr, size); + } else { + addr = vmalloc(size); + TRACE1("%p, %lu", addr, size); + } + } + DBG_BLOCK(1) { + if (addr) + TRACE4("addr: %p, %lu", addr, size); + else + TRACE1("failed: %lu", size); + } + return addr; +} +WIN_FUNC_DECL(ExAllocatePoolWithTag,3) + +wstdcall void WIN_FUNC(ExFreePoolWithTag,2) + (void *addr, ULONG tag) +{ + TRACE4("%p", addr); + if ((unsigned long)addr < VMALLOC_START || + (unsigned long)addr >= VMALLOC_END) + kfree(addr); + else + vfree(addr); + + EXIT4(return); +} + +wstdcall void WIN_FUNC(ExFreePool,1) + (void *addr) +{ + ExFreePoolWithTag(addr, 0); +} +WIN_FUNC_DECL(ExFreePool,1) + +wstdcall void WIN_FUNC(ExInitializeNPagedLookasideList,7) + (struct npaged_lookaside_list *lookaside, + LOOKASIDE_ALLOC_FUNC *alloc_func, LOOKASIDE_FREE_FUNC *free_func, + ULONG flags, SIZE_T size, ULONG tag, USHORT depth) +{ + ENTER3("lookaside: %p, size: %lu, flags: %u, head: %p, " + "alloc: %p, free: %p", lookaside, size, flags, + lookaside, alloc_func, free_func); + + memset(lookaside, 0, sizeof(*lookaside)); + + lookaside->size = size; + lookaside->tag = tag; + lookaside->depth = 4; + lookaside->maxdepth = 256; + lookaside->pool_type = NonPagedPool; + + if (alloc_func) + lookaside->alloc_func = alloc_func; + else + lookaside->alloc_func = WIN_FUNC_PTR(ExAllocatePoolWithTag,3); + if (free_func) + lookaside->free_func = free_func; + else + lookaside->free_func = WIN_FUNC_PTR(ExFreePool,1); + +#ifndef CONFIG_X86_64 + nt_spin_lock_init(&lookaside->obsolete); +#endif + EXIT3(return); +} + +wstdcall void WIN_FUNC(ExDeleteNPagedLookasideList,1) + (struct npaged_lookaside_list *lookaside) +{ + struct nt_slist *entry; + + ENTER3("lookaside = %p", lookaside); + while ((entry = ExpInterlockedPopEntrySList(&lookaside->head))) + LIN2WIN1(lookaside->free_func, entry); + EXIT3(return); +} + +#if defined(ALLOC_DEBUG) && ALLOC_DEBUG > 1 +#define ExAllocatePoolWithTag(pool_type, size, tag) \ + wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__) +#endif + +wstdcall NTSTATUS WIN_FUNC(ExCreateCallback,4) + (struct callback_object **object, struct object_attributes *attributes, + BOOLEAN create, BOOLEAN allow_multiple_callbacks) +{ + struct callback_object *obj; + + ENTER2(""); + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(obj, &callback_objects, callback_funcs) { + if (obj->attributes == attributes) { + spin_unlock_bh(&ntoskernel_lock); + *object = obj; + return STATUS_SUCCESS; + } + } + spin_unlock_bh(&ntoskernel_lock); + obj = allocate_object(sizeof(struct callback_object), + OBJECT_TYPE_CALLBACK, NULL); + if (!obj) + EXIT2(return STATUS_INSUFFICIENT_RESOURCES); + InitializeListHead(&obj->callback_funcs); + nt_spin_lock_init(&obj->lock); + obj->allow_multiple_callbacks = allow_multiple_callbacks; + obj->attributes = attributes; + *object = obj; + EXIT2(return STATUS_SUCCESS); +} + +wstdcall void *WIN_FUNC(ExRegisterCallback,3) + (struct callback_object *object, PCALLBACK_FUNCTION func, void *context) +{ + struct callback_func *callback; + KIRQL irql; + + ENTER2(""); + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + if (object->allow_multiple_callbacks == FALSE && + !IsListEmpty(&object->callback_funcs)) { + nt_spin_unlock_irql(&object->lock, irql); + EXIT2(return NULL); + } + nt_spin_unlock_irql(&object->lock, irql); + callback = kmalloc(sizeof(*callback), GFP_KERNEL); + if (!callback) { + ERROR("couldn't allocate memory"); + return NULL; + } + callback->func = func; + callback->context = context; + callback->object = object; + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + InsertTailList(&object->callback_funcs, &callback->list); + nt_spin_unlock_irql(&object->lock, irql); + EXIT2(return callback); +} + +wstdcall void WIN_FUNC(ExUnregisterCallback,1) + (struct callback_func *callback) +{ + struct callback_object *object; + KIRQL irql; + + ENTER3("%p", callback); + if (!callback) + return; + object = callback->object; + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + RemoveEntryList(&callback->list); + nt_spin_unlock_irql(&object->lock, irql); + kfree(callback); + return; +} + +wstdcall void WIN_FUNC(ExNotifyCallback,3) + (struct callback_object *object, void *arg1, void *arg2) +{ + struct callback_func *callback; + KIRQL irql; + + ENTER3("%p", object); + irql = nt_spin_lock_irql(&object->lock, DISPATCH_LEVEL); + nt_list_for_each_entry(callback, &object->callback_funcs, list) { + LIN2WIN3(callback->func, callback->context, arg1, arg2); + } + nt_spin_unlock_irql(&object->lock, irql); + return; +} + +/* check and set signaled state; should be called with dispatcher_lock held */ +/* @grab indicates if the event should be grabbed or checked + * - note that a semaphore may stay in signaled state for multiple + * 'grabs' if the count is > 1 */ +static int grab_object(struct dispatcher_header *dh, + struct task_struct *thread, int grab) +{ + EVENTTRACE("%p, %p, %d, %d", dh, thread, grab, dh->signal_state); + if (unlikely(is_mutex_object(dh))) { + struct nt_mutex *nt_mutex; + nt_mutex = container_of(dh, struct nt_mutex, dh); + EVENTTRACE("%p, %p, %d, %p, %d", nt_mutex, + nt_mutex->owner_thread, dh->signal_state, + thread, grab); + /* either no thread owns the mutex or this thread owns + * it */ + assert(dh->signal_state == 1 && nt_mutex->owner_thread == NULL); + assert(dh->signal_state < 1 && nt_mutex->owner_thread != NULL); + if ((dh->signal_state == 1 && nt_mutex->owner_thread == NULL) || + nt_mutex->owner_thread == thread) { + if (grab) { + dh->signal_state--; + nt_mutex->owner_thread = thread; + } + EVENTEXIT(return 1); + } + } else if (dh->signal_state > 0) { + /* to grab, decrement signal_state for synchronization + * or semaphore objects */ + if (grab && (is_synch_object(dh) || is_semaphore_object(dh))) + dh->signal_state--; + EVENTEXIT(return 1); + } + EVENTEXIT(return 0); +} + +/* this function should be called holding dispatcher_lock */ +static void object_signalled(struct dispatcher_header *dh) +{ + struct nt_list *cur, *next; + struct wait_block *wb; + + EVENTENTER("%p", dh); + nt_list_for_each_safe(cur, next, &dh->wait_blocks) { + wb = container_of(cur, struct wait_block, list); + assert(wb->thread != NULL); + assert(wb->object == NULL); + if (!grab_object(dh, wb->thread, 1)) + continue; + EVENTTRACE("%p (%p): waking %p", dh, wb, wb->thread); + RemoveEntryList(cur); + wb->object = dh; + *(wb->wait_done) = 1; + wake_up_process(wb->thread); + } + EVENTEXIT(return); +} + +wstdcall NTSTATUS WIN_FUNC(KeWaitForMultipleObjects,8) + (ULONG count, void *object[], enum wait_type wait_type, + KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode, + BOOLEAN alertable, LARGE_INTEGER *timeout, + struct wait_block *wait_block_array) +{ + int i, res = 0, wait_count, wait_done; + typeof(jiffies) wait_hz = 0; + struct wait_block *wb, wb_array[THREAD_WAIT_OBJECTS]; + struct dispatcher_header *dh; + + EVENTENTER("%p, %d, %u, %p", current, count, wait_type, timeout); + + if (count > MAX_WAIT_OBJECTS || + (count > THREAD_WAIT_OBJECTS && wait_block_array == NULL)) + EVENTEXIT(return STATUS_INVALID_PARAMETER); + + if (wait_block_array == NULL) + wb = wb_array; + else + wb = wait_block_array; + + /* If *timeout == 0: In the case of WaitAny, if an object can + * be grabbed (object is in signaled state), grab and + * return. In the case of WaitAll, we have to first make sure + * all objects can be grabbed. If any/some of them can't be + * grabbed, either we return STATUS_TIMEOUT or wait for them, + * depending on how to satisfy wait. If all of them can be + * grabbed, we will grab them in the next loop below */ + + spin_lock_bh(&dispatcher_lock); + for (i = wait_count = 0; i < count; i++) { + dh = object[i]; + EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state); + /* wait_type == 1 for WaitAny, 0 for WaitAll */ + if (grab_object(dh, current, wait_type)) { + if (wait_type == WaitAny) { + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return STATUS_WAIT_0 + i); + } + } else { + EVENTTRACE("%p: wait for %p", current, dh); + wait_count++; + } + } + + if (timeout && *timeout == 0 && wait_count) { + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return STATUS_TIMEOUT); + } + + /* get the list of objects the thread needs to wait on and add + * the thread on the wait list for each such object */ + /* if *timeout == 0, this step will grab all the objects */ + wait_done = 0; + for (i = 0; i < count; i++) { + dh = object[i]; + EVENTTRACE("%p: event %p (%d)", current, dh, dh->signal_state); + wb[i].object = NULL; + if (grab_object(dh, current, 1)) { + EVENTTRACE("%p: no wait for %p (%d)", + current, dh, dh->signal_state); + /* mark that we are not waiting on this object */ + wb[i].thread = NULL; + } else { + wb[i].wait_done = &wait_done; + wb[i].thread = current; + EVENTTRACE("%p: wait for %p", current, dh); + InsertTailList(&dh->wait_blocks, &wb[i].list); + } + } + spin_unlock_bh(&dispatcher_lock); + if (wait_count == 0) + EVENTEXIT(return STATUS_SUCCESS); + + assert(timeout == NULL || *timeout != 0); + if (timeout == NULL) + wait_hz = 0; + else + wait_hz = SYSTEM_TIME_TO_HZ(*timeout); + + DBG_BLOCK(2) { + KIRQL irql = current_irql(); + if (irql >= DISPATCH_LEVEL) { + TRACE2("wait in atomic context: %lu, %d, %ld", + wait_hz, in_atomic(), in_interrupt()); + } + } + assert_irql(_irql_ < DISPATCH_LEVEL); + EVENTTRACE("%p: sleep for %ld on %p", current, wait_hz, &wait_done); + /* we don't honor 'alertable' - according to decription for + * this, even if waiting in non-alertable state, thread may be + * alerted in some circumstances */ + while (wait_count) { + res = wait_condition(wait_done, wait_hz, TASK_INTERRUPTIBLE); + spin_lock_bh(&dispatcher_lock); + EVENTTRACE("%p woke up: %d, %d", current, res, wait_done); + /* the event may have been set by the time + * wrap_wait_event returned and spinlock obtained, so + * don't rely on value of 'res' - check event status */ + if (!wait_done) { + assert(res <= 0); + /* timed out or interrupted; remove from wait list */ + for (i = 0; i < count; i++) { + if (!wb[i].thread) + continue; + EVENTTRACE("%p: timedout, dequeue %p (%p)", + current, object[i], wb[i].object); + assert(wb[i].object == NULL); + RemoveEntryList(&wb[i].list); + } + spin_unlock_bh(&dispatcher_lock); + if (res < 0) + EVENTEXIT(return STATUS_ALERTED); + else + EVENTEXIT(return STATUS_TIMEOUT); + } + assert(res > 0); + /* woken because object(s) signalled */ + for (i = 0; wait_count && i < count; i++) { + if (!wb[i].thread || !wb[i].object) + continue; + DBG_BLOCK(1) { + if (wb[i].object != object[i]) { + EVENTTRACE("oops %p != %p", + wb[i].object, object[i]); + continue; + } + } + wait_count--; + if (wait_type == WaitAny) { + int j; + /* done; remove from rest of wait list */ + for (j = i + 1; j < count; j++) { + if (wb[j].thread && !wb[j].object) + RemoveEntryList(&wb[j].list); + } + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return STATUS_WAIT_0 + i); + } + } + wait_done = 0; + spin_unlock_bh(&dispatcher_lock); + if (wait_count == 0) + EVENTEXIT(return STATUS_SUCCESS); + + /* this thread is still waiting for more objects, so + * let it wait for remaining time and those objects */ + if (timeout) + wait_hz = res; + else + wait_hz = 0; + } + /* should never reach here, but compiler wants return value */ + ERROR("%p: wait_hz: %ld", current, wait_hz); + EVENTEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(KeWaitForSingleObject,5) + (void *object, KWAIT_REASON wait_reason, KPROCESSOR_MODE wait_mode, + BOOLEAN alertable, LARGE_INTEGER *timeout) +{ + return KeWaitForMultipleObjects(1, &object, WaitAny, wait_reason, + wait_mode, alertable, timeout, NULL); +} + +wstdcall void WIN_FUNC(KeInitializeEvent,3) + (struct nt_event *nt_event, enum event_type type, BOOLEAN state) +{ + EVENTENTER("event = %p, type = %d, state = %d", nt_event, type, state); + initialize_object(&nt_event->dh, type, state); + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeSetEvent,3) + (struct nt_event *nt_event, KPRIORITY incr, BOOLEAN wait) +{ + LONG old_state; + + EVENTENTER("%p, %d", nt_event, nt_event->dh.type); + if (wait == TRUE) + WARNING("wait = %d, not yet implemented", wait); + spin_lock_bh(&dispatcher_lock); + old_state = nt_event->dh.signal_state; + nt_event->dh.signal_state = 1; + if (old_state == 0) + object_signalled(&nt_event->dh); + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return old_state); +} + +wstdcall void WIN_FUNC(KeClearEvent,1) + (struct nt_event *nt_event) +{ + EVENTENTER("%p", nt_event); + nt_event->dh.signal_state = 0; + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeResetEvent,1) + (struct nt_event *nt_event) +{ + LONG old_state; + + EVENTENTER("%p", nt_event); + old_state = xchg(&nt_event->dh.signal_state, 0); + EVENTEXIT(return old_state); +} + +wstdcall LONG WIN_FUNC(KeReadStateEvent,1) + (struct nt_event *nt_event) +{ + LONG state; + + state = nt_event->dh.signal_state; + EVENTTRACE("%d", state); + return state; +} + +wstdcall void WIN_FUNC(KeInitializeMutex,2) + (struct nt_mutex *mutex, ULONG level) +{ + EVENTENTER("%p", mutex); + initialize_object(&mutex->dh, MutexObject, 1); + mutex->dh.size = sizeof(*mutex); + InitializeListHead(&mutex->list); + mutex->abandoned = FALSE; + mutex->apc_disable = 1; + mutex->owner_thread = NULL; + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeReleaseMutex,2) + (struct nt_mutex *mutex, BOOLEAN wait) +{ + LONG ret; + struct task_struct *thread; + + EVENTENTER("%p, %d, %p", mutex, wait, current); + if (wait == TRUE) + WARNING("wait: %d", wait); + thread = current; + spin_lock_bh(&dispatcher_lock); + EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread, + mutex->dh.signal_state); + if ((mutex->owner_thread == thread) && (mutex->dh.signal_state <= 0)) { + ret = mutex->dh.signal_state++; + if (ret == 0) { + mutex->owner_thread = NULL; + object_signalled(&mutex->dh); + } + } else { + ret = STATUS_MUTANT_NOT_OWNED; + WARNING("invalid mutex: %p, %p, %p", mutex, mutex->owner_thread, + thread); + } + EVENTTRACE("%p, %p, %p, %d", mutex, thread, mutex->owner_thread, + mutex->dh.signal_state); + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return ret); +} + +wstdcall void WIN_FUNC(KeInitializeSemaphore,3) + (struct nt_semaphore *semaphore, LONG count, LONG limit) +{ + EVENTENTER("%p: %d", semaphore, count); + /* if limit > 1, we need to satisfy as many waits (until count + * becomes 0); so we keep decrementing count everytime a wait + * is satisified */ + initialize_object(&semaphore->dh, SemaphoreObject, count); + semaphore->dh.size = sizeof(*semaphore); + semaphore->limit = limit; + EVENTEXIT(return); +} + +wstdcall LONG WIN_FUNC(KeReleaseSemaphore,4) + (struct nt_semaphore *semaphore, KPRIORITY incr, LONG adjustment, + BOOLEAN wait) +{ + LONG ret; + + EVENTENTER("%p", semaphore); + spin_lock_bh(&dispatcher_lock); + ret = semaphore->dh.signal_state; + assert(ret >= 0); + if (semaphore->dh.signal_state + adjustment <= semaphore->limit) + semaphore->dh.signal_state += adjustment; + else { + WARNING("releasing %d over limit %d", adjustment, + semaphore->limit); + semaphore->dh.signal_state = semaphore->limit; + } + if (semaphore->dh.signal_state > 0) + object_signalled(&semaphore->dh); + spin_unlock_bh(&dispatcher_lock); + EVENTEXIT(return ret); +} + +wstdcall NTSTATUS WIN_FUNC(KeDelayExecutionThread,3) + (KPROCESSOR_MODE wait_mode, BOOLEAN alertable, LARGE_INTEGER *interval) +{ + int res; + long timeout; + + if (wait_mode != 0) + ERROR("invalid wait_mode %d", wait_mode); + + timeout = SYSTEM_TIME_TO_HZ(*interval); + EVENTTRACE("%p, %Ld, %ld", current, *interval, timeout); + if (timeout <= 0) + EVENTEXIT(return STATUS_SUCCESS); + + if (alertable) + set_current_state(TASK_INTERRUPTIBLE); + else + set_current_state(TASK_UNINTERRUPTIBLE); + + res = schedule_timeout(timeout); + EVENTTRACE("%p, %d", current, res); + if (res == 0) + EVENTEXIT(return STATUS_SUCCESS); + else + EVENTEXIT(return STATUS_ALERTED); +} + +wstdcall ULONGLONG WIN_FUNC(KeQueryInterruptTime,0) + (void) +{ + EXIT5(return jiffies * TICKSPERJIFFY); +} + +wstdcall ULONG WIN_FUNC(KeQueryTimeIncrement,0) + (void) +{ + EXIT5(return TICKSPERSEC / HZ); +} + +wstdcall void WIN_FUNC(KeQuerySystemTime,1) + (LARGE_INTEGER *time) +{ + *time = ticks_1601(); + TRACE5("%Lu, %lu", *time, jiffies); +} + +wstdcall void WIN_FUNC(KeQueryTickCount,1) + (LARGE_INTEGER *count) +{ + *count = jiffies; +} + +wstdcall LARGE_INTEGER WIN_FUNC(KeQueryPerformanceCounter,1) + (LARGE_INTEGER *counter) +{ + if (counter) + *counter = HZ; + return jiffies; +} + +wstdcall KAFFINITY WIN_FUNC(KeQueryActiveProcessors,0) + (void) +{ + int i, n; + KAFFINITY bits = 0; +#ifdef num_online_cpus + n = num_online_cpus(); +#else + n = NR_CPUS; +#endif + for (i = 0; i < n; i++) + bits = (bits << 1) | 1; + return bits; +} + +struct nt_thread *get_current_nt_thread(void) +{ + struct task_struct *task = current; + struct nt_thread *thread; + struct common_object_header *header; + + TRACE6("task: %p", task); + thread = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(header, &object_list, list) { + TRACE6("%p, %d", header, header->type); + if (header->type != OBJECT_TYPE_NT_THREAD) + break; + thread = HEADER_TO_OBJECT(header); + TRACE6("%p, %p", thread, thread->task); + if (thread->task == task) + break; + else + thread = NULL; + } + spin_unlock_bh(&ntoskernel_lock); + if (thread == NULL) + TRACE4("couldn't find thread for task %p, %d", task, task->pid); + TRACE6("%p", thread); + return thread; +} + +static struct task_struct *get_nt_thread_task(struct nt_thread *thread) +{ + struct task_struct *task; + struct common_object_header *header; + + TRACE6("%p", thread); + task = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(header, &object_list, list) { + TRACE6("%p, %d", header, header->type); + if (header->type != OBJECT_TYPE_NT_THREAD) + break; + if (thread == HEADER_TO_OBJECT(header)) { + task = thread->task; + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + if (task == NULL) + TRACE2("%p: couldn't find task for %p", current, thread); + return task; +} + +static struct nt_thread *create_nt_thread(struct task_struct *task) +{ + struct nt_thread *thread; + thread = allocate_object(sizeof(*thread), OBJECT_TYPE_NT_THREAD, NULL); + if (!thread) { + ERROR("couldn't allocate thread object"); + EXIT2(return NULL); + } + thread->task = task; + if (task) + thread->pid = task->pid; + else + thread->pid = 0; + nt_spin_lock_init(&thread->lock); + InitializeListHead(&thread->irps); + initialize_object(&thread->dh, ThreadObject, 0); + thread->dh.size = sizeof(*thread); + thread->prio = LOW_PRIORITY; + return thread; +} + +wstdcall struct nt_thread *WIN_FUNC(KeGetCurrentThread,0) + (void) +{ + struct nt_thread *thread = get_current_nt_thread(); + TRACE2("%p, %p", thread, current); + return thread; +} + +wstdcall KPRIORITY WIN_FUNC(KeQueryPriorityThread,1) + (struct nt_thread *thread) +{ + KPRIORITY prio; + struct task_struct *task; + + TRACE2("%p", thread); +#ifdef CONFIG_X86_64 + /* sis163u driver for amd64 passes 0x1f from thread created by + * PsCreateSystemThread - no idea what is 0x1f */ + if (thread == (void *)0x1f) + thread = get_current_nt_thread(); +#endif + if (!thread) { + TRACE2("invalid thread"); + EXIT2(return LOW_REALTIME_PRIORITY); + } + task = get_nt_thread_task(thread); + if (!task) { + TRACE2("couldn't find task for thread: %p", thread); + EXIT2(return LOW_REALTIME_PRIORITY); + } + + prio = thread->prio; + + TRACE2("%d", prio); + return prio; +} + +wstdcall KPRIORITY WIN_FUNC(KeSetPriorityThread,2) + (struct nt_thread *thread, KPRIORITY prio) +{ + KPRIORITY old_prio; + struct task_struct *task; + + TRACE2("thread: %p, priority = %u", thread, prio); +#ifdef CONFIG_X86_64 + if (thread == (void *)0x1f) + thread = get_current_nt_thread(); +#endif + if (!thread) { + TRACE2("invalid thread"); + EXIT2(return LOW_REALTIME_PRIORITY); + } + task = get_nt_thread_task(thread); + if (!task) { + TRACE2("couldn't find task for thread: %p", thread); + EXIT2(return LOW_REALTIME_PRIORITY); + } + + old_prio = thread->prio; + thread->prio = prio; + + TRACE2("%d, %d", old_prio, thread->prio); + return old_prio; +} + +struct thread_trampoline { + void (*func)(void *) wstdcall; + void *ctx; + struct nt_thread *thread; + struct completion started; +}; + +static int ntdriver_thread(void *data) +{ + struct thread_trampoline *thread_tramp = data; + /* yes, a tramp! */ + typeof(thread_tramp->func) func = thread_tramp->func; + typeof(thread_tramp->ctx) ctx = thread_tramp->ctx; + + thread_tramp->thread->task = current; + thread_tramp->thread->pid = current->pid; + TRACE2("thread: %p, task: %p (%d)", thread_tramp->thread, + current, current->pid); + complete(&thread_tramp->started); + +#ifdef PF_NOFREEZE + current->flags |= PF_NOFREEZE; +#endif + strncpy(current->comm, "ntdriver", sizeof(current->comm)); + current->comm[sizeof(current->comm)-1] = 0; + LIN2WIN1(func, ctx); + ERROR("task: %p", current); + return 0; +} + +wstdcall NTSTATUS WIN_FUNC(PsCreateSystemThread,7) + (void **handle, ULONG access, void *obj_attr, void *process, + void *client_id, void (*func)(void *) wstdcall, void *ctx) +{ + struct thread_trampoline thread_tramp; + + ENTER2("handle = %p, access = %u, obj_attr = %p, process = %p, " + "client_id = %p, func = %p, context = %p", handle, access, + obj_attr, process, client_id, func, ctx); + + thread_tramp.thread = create_nt_thread(NULL); + if (!thread_tramp.thread) { + ERROR("couldn't allocate thread object"); + EXIT2(return STATUS_RESOURCES); + } + TRACE2("thread: %p", thread_tramp.thread); + thread_tramp.func = func; + thread_tramp.ctx = ctx; + init_completion(&thread_tramp.started); + + thread_tramp.thread->task = kthread_run(ntdriver_thread, + &thread_tramp, "ntdriver"); + if (IS_ERR(thread_tramp.thread->task)) { + free_object(thread_tramp.thread); + EXIT2(return STATUS_FAILURE); + } + TRACE2("created task: %p", thread_tramp.thread->task); + + wait_for_completion(&thread_tramp.started); + *handle = OBJECT_TO_HEADER(thread_tramp.thread); + TRACE2("created thread: %p, %p", thread_tramp.thread, *handle); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(PsTerminateSystemThread,1) + (NTSTATUS status) +{ + struct nt_thread *thread; + + TRACE2("%p, %08X", current, status); + thread = get_current_nt_thread(); + TRACE2("%p", thread); + if (thread) { + KeSetEvent((struct nt_event *)&thread->dh, 0, FALSE); + while (1) { + struct nt_list *ent; + struct irp *irp; + KIRQL irql; + irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); + ent = RemoveHeadList(&thread->irps); + nt_spin_unlock_irql(&thread->lock, irql); + if (!ent) + break; + irp = container_of(ent, struct irp, thread_list); + IOTRACE("%p", irp); + IoCancelIrp(irp); + } + /* the driver may later query this status with + * ZwQueryInformationThread */ + thread->status = status; + } else + ERROR("couldn't find thread for task: %p", current); + + complete_and_exit(NULL, status); + ERROR("oops: %p, %d", thread->task, thread->pid); + return STATUS_FAILURE; +} + +wstdcall BOOLEAN WIN_FUNC(KeRemoveEntryDeviceQueue,2) + (struct kdevice_queue *dev_queue, struct kdevice_queue_entry *entry) +{ + struct kdevice_queue_entry *e; + KIRQL irql; + + irql = nt_spin_lock_irql(&dev_queue->lock, DISPATCH_LEVEL); + nt_list_for_each_entry(e, &dev_queue->list, list) { + if (e == entry) { + RemoveEntryList(&e->list); + nt_spin_unlock_irql(&dev_queue->lock, irql); + return TRUE; + } + } + nt_spin_unlock_irql(&dev_queue->lock, irql); + return FALSE; +} + +wstdcall BOOLEAN WIN_FUNC(KeSynchronizeExecution,3) + (struct kinterrupt *interrupt, PKSYNCHRONIZE_ROUTINE synch_routine, + void *ctx) +{ + BOOLEAN ret; + unsigned long flags; + + nt_spin_lock_irqsave(interrupt->actual_lock, flags); + ret = LIN2WIN1(synch_routine, ctx); + nt_spin_unlock_irqrestore(interrupt->actual_lock, flags); + TRACE6("%d", ret); + return ret; +} + +wstdcall void *WIN_FUNC(MmAllocateContiguousMemorySpecifyCache,5) + (SIZE_T size, PHYSICAL_ADDRESS lowest, PHYSICAL_ADDRESS highest, + PHYSICAL_ADDRESS boundary, enum memory_caching_type cache_type) +{ + void *addr; + gfp_t flags; + + ENTER2("%lu, 0x%lx, 0x%lx, 0x%lx, %d", size, (long)lowest, + (long)highest, (long)boundary, cache_type); + flags = irql_gfp(); + addr = wrap_get_free_pages(flags, size); + TRACE2("%p, %lu, 0x%x", addr, size, flags); + if (addr && ((virt_to_phys(addr) + size) <= highest)) + EXIT2(return addr); +#ifdef CONFIG_X86_64 + /* GFP_DMA is really only 16MB even on x86-64, but there is no + * other zone available */ + if (highest <= DMA_31BIT_MASK) + flags |= __GFP_DMA; + else if (highest <= DMA_32BIT_MASK) + flags |= __GFP_DMA32; +#else + if (highest <= DMA_24BIT_MASK) + flags |= __GFP_DMA; + else if (highest > DMA_30BIT_MASK) + flags |= __GFP_HIGHMEM; +#endif + addr = wrap_get_free_pages(flags, size); + TRACE2("%p, %lu, 0x%x", addr, size, flags); + return addr; +} + +wstdcall void WIN_FUNC(MmFreeContiguousMemorySpecifyCache,3) + (void *base, SIZE_T size, enum memory_caching_type cache_type) +{ + TRACE2("%p, %lu", base, size); + free_pages((unsigned long)base, get_order(size)); +} + +wstdcall PHYSICAL_ADDRESS WIN_FUNC(MmGetPhysicalAddress,1) + (void *base) +{ + unsigned long phy = virt_to_phys(base); + TRACE2("%p, %p", base, (void *)phy); + return phy; +} + +/* Atheros card with pciid 168C:0014 calls this function with 0xf0000 + * and 0xf6ef0 address, and then check for things that seem to be + * related to ACPI: "_SM_" and "_DMI_". This may be the hack they do + * to check if this card is installed in IBM thinkpads; we can + * probably get this device to work if we create a buffer with the + * strings as required by the driver and return virtual address for + * that address instead */ +wstdcall void __iomem *WIN_FUNC(MmMapIoSpace,3) + (PHYSICAL_ADDRESS phys_addr, SIZE_T size, + enum memory_caching_type cache) +{ + void __iomem *virt; + ENTER1("cache type: %d", cache); + if (cache == MmCached) + virt = ioremap(phys_addr, size); + else + virt = ioremap_nocache(phys_addr, size); + TRACE1("%Lx, %lu, %p", phys_addr, size, virt); + return virt; +} + +wstdcall void WIN_FUNC(MmUnmapIoSpace,2) + (void __iomem *addr, SIZE_T size) +{ + ENTER1("%p, %lu", addr, size); + iounmap(addr); + return; +} + +wstdcall ULONG WIN_FUNC(MmSizeOfMdl,2) + (void *base, ULONG length) +{ + return (sizeof(struct mdl) + + (sizeof(PFN_NUMBER) * SPAN_PAGES(base, length))); +} + +struct mdl *allocate_init_mdl(void *virt, ULONG length) +{ + struct wrap_mdl *wrap_mdl; + struct mdl *mdl; + int mdl_size = MmSizeOfMdl(virt, length); + + if (mdl_size <= MDL_CACHE_SIZE) { + wrap_mdl = kmem_cache_alloc(mdl_cache, irql_gfp()); + if (!wrap_mdl) + return NULL; + spin_lock_bh(&dispatcher_lock); + InsertHeadList(&wrap_mdl_list, &wrap_mdl->list); + spin_unlock_bh(&dispatcher_lock); + mdl = wrap_mdl->mdl; + TRACE3("allocated mdl from cache: %p(%p), %p(%d)", + wrap_mdl, mdl, virt, length); + memset(mdl, 0, MDL_CACHE_SIZE); + MmInitializeMdl(mdl, virt, length); + /* mark the MDL as allocated from cache pool so when + * it is freed, we free it back to the pool */ + mdl->flags = MDL_ALLOCATED_FIXED_SIZE | MDL_CACHE_ALLOCATED; + } else { + wrap_mdl = + kmalloc(sizeof(*wrap_mdl) + mdl_size, irql_gfp()); + if (!wrap_mdl) + return NULL; + mdl = wrap_mdl->mdl; + TRACE3("allocated mdl from memory: %p(%p), %p(%d)", + wrap_mdl, mdl, virt, length); + spin_lock_bh(&dispatcher_lock); + InsertHeadList(&wrap_mdl_list, &wrap_mdl->list); + spin_unlock_bh(&dispatcher_lock); + memset(mdl, 0, mdl_size); + MmInitializeMdl(mdl, virt, length); + mdl->flags = MDL_ALLOCATED_FIXED_SIZE; + } + return mdl; +} + +void free_mdl(struct mdl *mdl) +{ + /* A driver may allocate Mdl with NdisAllocateBuffer and free + * with IoFreeMdl (e.g., 64-bit Broadcom). Since we need to + * treat buffers allocated with Ndis calls differently, we + * must call NdisFreeBuffer if it is allocated with Ndis + * function. We set 'pool' field in Ndis functions. */ + if (!mdl) + return; + if (mdl->pool) + NdisFreeBuffer(mdl); + else { + struct wrap_mdl *wrap_mdl = (struct wrap_mdl *) + ((char *)mdl - offsetof(struct wrap_mdl, mdl)); + spin_lock_bh(&dispatcher_lock); + RemoveEntryList(&wrap_mdl->list); + spin_unlock_bh(&dispatcher_lock); + + if (mdl->flags & MDL_CACHE_ALLOCATED) { + TRACE3("freeing mdl cache: %p, %p, %p", + wrap_mdl, mdl, mdl->mappedsystemva); + kmem_cache_free(mdl_cache, wrap_mdl); + } else { + TRACE3("freeing mdl: %p, %p, %p", + wrap_mdl, mdl, mdl->mappedsystemva); + kfree(wrap_mdl); + } + } + return; +} + +wstdcall void WIN_FUNC(IoBuildPartialMdl,4) + (struct mdl *source, struct mdl *target, void *virt, ULONG length) +{ + MmInitializeMdl(target, virt, length); + target->flags |= MDL_PARTIAL; +} + +wstdcall void WIN_FUNC(MmBuildMdlForNonPagedPool,1) + (struct mdl *mdl) +{ + PFN_NUMBER *mdl_pages; + int i, n; + + ENTER4("%p", mdl); + /* already mapped */ +// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl); + mdl->flags |= MDL_SOURCE_IS_NONPAGED_POOL; + TRACE4("%p, %p, %p, %d, %d", mdl, mdl->mappedsystemva, mdl->startva, + mdl->byteoffset, mdl->bytecount); + n = SPAN_PAGES(MmGetSystemAddressForMdl(mdl), MmGetMdlByteCount(mdl)); + if (n > MDL_CACHE_PAGES) + WARNING("%p, %d, %d", MmGetSystemAddressForMdl(mdl), + MmGetMdlByteCount(mdl), n); + mdl_pages = MmGetMdlPfnArray(mdl); + for (i = 0; i < n; i++) + mdl_pages[i] = (ULONG_PTR)mdl->startva + (i * PAGE_SIZE); + EXIT4(return); +} + +wstdcall void *WIN_FUNC(MmMapLockedPages,2) + (struct mdl *mdl, KPROCESSOR_MODE access_mode) +{ + /* already mapped */ +// mdl->mappedsystemva = MmGetMdlVirtualAddress(mdl); + mdl->flags |= MDL_MAPPED_TO_SYSTEM_VA; + /* what is the need for MDL_PARTIAL_HAS_BEEN_MAPPED? */ + if (mdl->flags & MDL_PARTIAL) + mdl->flags |= MDL_PARTIAL_HAS_BEEN_MAPPED; + return mdl->mappedsystemva; +} + +wstdcall void *WIN_FUNC(MmMapLockedPagesSpecifyCache,6) + (struct mdl *mdl, KPROCESSOR_MODE access_mode, + enum memory_caching_type cache_type, void *base_address, + ULONG bug_check, enum mm_page_priority priority) +{ + return MmMapLockedPages(mdl, access_mode); +} + +wstdcall void WIN_FUNC(MmUnmapLockedPages,2) + (void *base, struct mdl *mdl) +{ + mdl->flags &= ~MDL_MAPPED_TO_SYSTEM_VA; + return; +} + +wstdcall void WIN_FUNC(MmProbeAndLockPages,3) + (struct mdl *mdl, KPROCESSOR_MODE access_mode, + enum lock_operation operation) +{ + /* already locked */ + mdl->flags |= MDL_PAGES_LOCKED; + return; +} + +wstdcall void WIN_FUNC(MmUnlockPages,1) + (struct mdl *mdl) +{ + mdl->flags &= ~MDL_PAGES_LOCKED; + return; +} + +wstdcall BOOLEAN WIN_FUNC(MmIsAddressValid,1) + (void *virt_addr) +{ + if (virt_addr_valid(virt_addr)) + return TRUE; + else + return FALSE; +} + +wstdcall void *WIN_FUNC(MmLockPagableDataSection,1) + (void *address) +{ + return address; +} + +wstdcall void WIN_FUNC(MmUnlockPagableImageSection,1) + (void *handle) +{ + return; +} + +wstdcall NTSTATUS WIN_FUNC(ObReferenceObjectByHandle,6) + (void *handle, ACCESS_MASK desired_access, void *obj_type, + KPROCESSOR_MODE access_mode, void **object, void *handle_info) +{ + struct common_object_header *hdr; + + TRACE2("%p", handle); + hdr = HANDLE_TO_HEADER(handle); + atomic_inc_var(hdr->ref_count); + *object = HEADER_TO_OBJECT(hdr); + TRACE2("%p, %p, %d, %p", hdr, object, hdr->ref_count, *object); + return STATUS_SUCCESS; +} + +/* DDK doesn't say if return value should be before incrementing or + * after incrementing reference count, but according to #reactos + * devels, it should be return value after incrementing */ +wfastcall LONG WIN_FUNC(ObfReferenceObject,1) + (void *object) +{ + struct common_object_header *hdr; + LONG ret; + + hdr = OBJECT_TO_HEADER(object); + ret = post_atomic_add(hdr->ref_count, 1); + TRACE2("%p, %d, %p", hdr, hdr->ref_count, object); + return ret; +} + +static int dereference_object(void *object) +{ + struct common_object_header *hdr; + int ref_count; + + ENTER2("object: %p", object); + hdr = OBJECT_TO_HEADER(object); + TRACE2("hdr: %p", hdr); + ref_count = post_atomic_add(hdr->ref_count, -1); + TRACE2("object: %p, %d", object, ref_count); + if (ref_count < 0) + ERROR("invalid object: %p (%d)", object, ref_count); + if (ref_count <= 0) { + free_object(object); + return 1; + } else + return 0; +} + +wfastcall void WIN_FUNC(ObfDereferenceObject,1) + (void *object) +{ + TRACE2("%p", object); + dereference_object(object); +} + +wstdcall NTSTATUS WIN_FUNC(ZwCreateFile,11) + (void **handle, ACCESS_MASK access_mask, + struct object_attributes *obj_attr, struct io_status_block *iosb, + LARGE_INTEGER *size, ULONG file_attr, ULONG share_access, + ULONG create_disposition, ULONG create_options, void *ea_buffer, + ULONG ea_length) +{ + struct common_object_header *coh; + struct file_object *fo; + struct ansi_string ansi; + struct wrap_bin_file *bin_file; + char *file_basename; + NTSTATUS status; + + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(coh, &object_list, list) { + if (coh->type != OBJECT_TYPE_FILE) + continue; + /* TODO: check if file is opened in shared mode */ + if (!RtlCompareUnicodeString(&coh->name, obj_attr->name, TRUE)) { + fo = HEADER_TO_OBJECT(coh); + bin_file = fo->wrap_bin_file; + *handle = coh; + spin_unlock_bh(&ntoskernel_lock); + ObReferenceObject(fo); + iosb->status = FILE_OPENED; + iosb->info = bin_file->size; + EXIT2(return STATUS_SUCCESS); + } + } + spin_unlock_bh(&ntoskernel_lock); + + if (RtlUnicodeStringToAnsiString(&ansi, obj_attr->name, TRUE) != + STATUS_SUCCESS) + EXIT2(return STATUS_INSUFFICIENT_RESOURCES); + + file_basename = strrchr(ansi.buf, '\\'); + if (file_basename) + file_basename++; + else + file_basename = ansi.buf; + TRACE2("file: '%s', '%s'", ansi.buf, file_basename); + + fo = allocate_object(sizeof(struct file_object), OBJECT_TYPE_FILE, + obj_attr->name); + if (!fo) { + RtlFreeAnsiString(&ansi); + iosb->status = STATUS_INSUFFICIENT_RESOURCES; + iosb->info = 0; + EXIT2(return STATUS_FAILURE); + } + coh = OBJECT_TO_HEADER(fo); + bin_file = get_bin_file(file_basename); + if (bin_file) { + TRACE2("%s, %s", bin_file->name, file_basename); + fo->flags = FILE_OPENED; + } else if (access_mask & FILE_WRITE_DATA) { + bin_file = kzalloc(sizeof(*bin_file), GFP_KERNEL); + if (bin_file) { + strncpy(bin_file->name, file_basename, + sizeof(bin_file->name)); + bin_file->name[sizeof(bin_file->name)-1] = 0; + bin_file->data = vmalloc(*size); + if (bin_file->data) { + memset(bin_file->data, 0, *size); + bin_file->size = *size; + fo->flags = FILE_CREATED; + } else { + kfree(bin_file); + bin_file = NULL; + } + } + } else + bin_file = NULL; + + RtlFreeAnsiString(&ansi); + if (!bin_file) { + iosb->status = FILE_DOES_NOT_EXIST; + iosb->info = 0; + free_object(fo); + EXIT2(return STATUS_FAILURE); + } + + fo->wrap_bin_file = bin_file; + fo->current_byte_offset = 0; + if (access_mask & FILE_READ_DATA) + fo->read_access = TRUE; + if (access_mask & FILE_WRITE_DATA) + fo->write_access = TRUE; + iosb->status = FILE_OPENED; + iosb->info = bin_file->size; + *handle = coh; + TRACE2("handle: %p", *handle); + status = STATUS_SUCCESS; + EXIT2(return status); +} + +wstdcall NTSTATUS WIN_FUNC(ZwOpenFile,6) + (void **handle, ACCESS_MASK access_mask, + struct object_attributes *obj_attr, struct io_status_block *iosb, + ULONG share_access, ULONG open_options) +{ + LARGE_INTEGER size; + return ZwCreateFile(handle, access_mask, obj_attr, iosb, &size, 0, + share_access, 0, open_options, NULL, 0); +} + +wstdcall NTSTATUS WIN_FUNC(ZwReadFile,9) + (void *handle, struct nt_event *event, void *apc_routine, + void *apc_context, struct io_status_block *iosb, void *buffer, + ULONG length, LARGE_INTEGER *byte_offset, ULONG *key) +{ + struct file_object *fo; + struct common_object_header *coh; + ULONG count; + size_t offset; + struct wrap_bin_file *file; + + TRACE2("%p", handle); + coh = handle; + if (coh->type != OBJECT_TYPE_FILE) { + ERROR("handle %p is invalid: %d", handle, coh->type); + EXIT2(return STATUS_FAILURE); + } + fo = HANDLE_TO_OBJECT(coh); + file = fo->wrap_bin_file; + TRACE2("file: %s (%zu)", file->name, file->size); + spin_lock_bh(&ntoskernel_lock); + if (byte_offset) + offset = *byte_offset; + else + offset = fo->current_byte_offset; + count = min((size_t)length, file->size - offset); + TRACE2("count: %u, offset: %zu, length: %u", count, offset, length); + memcpy(buffer, ((void *)file->data) + offset, count); + fo->current_byte_offset = offset + count; + spin_unlock_bh(&ntoskernel_lock); + iosb->status = STATUS_SUCCESS; + iosb->info = count; + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(ZwWriteFile,9) + (void *handle, struct nt_event *event, void *apc_routine, + void *apc_context, struct io_status_block *iosb, void *buffer, + ULONG length, LARGE_INTEGER *byte_offset, ULONG *key) +{ + struct file_object *fo; + struct common_object_header *coh; + struct wrap_bin_file *file; + unsigned long offset; + + TRACE2("%p", handle); + coh = handle; + if (coh->type != OBJECT_TYPE_FILE) { + ERROR("handle %p is invalid: %d", handle, coh->type); + EXIT2(return STATUS_FAILURE); + } + fo = HANDLE_TO_OBJECT(coh); + file = fo->wrap_bin_file; + TRACE2("file: %zu, %u", file->size, length); + spin_lock_bh(&ntoskernel_lock); + if (byte_offset) + offset = *byte_offset; + else + offset = fo->current_byte_offset; + if (length + offset > file->size) { + WARNING("%lu, %u", length + offset, (unsigned int)file->size); + /* TODO: implement writing past end of current size */ + iosb->status = STATUS_FAILURE; + iosb->info = 0; + } else { + memcpy(file->data + offset, buffer, length); + iosb->status = STATUS_SUCCESS; + iosb->info = length; + fo->current_byte_offset = offset + length; + } + spin_unlock_bh(&ntoskernel_lock); + EXIT2(return iosb->status); +} + +wstdcall NTSTATUS WIN_FUNC(ZwClose,1) + (void *handle) +{ + struct common_object_header *coh; + + TRACE2("%p", handle); + if (handle == NULL) { + TRACE1(""); + EXIT2(return STATUS_SUCCESS); + } + coh = handle; + if (coh->type == OBJECT_TYPE_FILE) { + struct file_object *fo; + struct wrap_bin_file *bin_file; + typeof(fo->flags) flags; + + fo = HANDLE_TO_OBJECT(handle); + flags = fo->flags; + bin_file = fo->wrap_bin_file; + if (dereference_object(fo)) { + if (flags == FILE_CREATED) { + vfree(bin_file->data); + kfree(bin_file); + } else + free_bin_file(bin_file); + } + } else if (coh->type == OBJECT_TYPE_NT_THREAD) { + struct nt_thread *thread = HANDLE_TO_OBJECT(handle); + TRACE2("thread: %p (%p)", thread, handle); + ObDereferenceObject(thread); + } else { + /* TODO: can we just dereference object here? */ + WARNING("closing handle 0x%x not implemented", coh->type); + } + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(ZwQueryInformationFile,5) + (void *handle, struct io_status_block *iosb, void *info, + ULONG length, enum file_info_class class) +{ + struct file_object *fo; + struct file_name_info *fni; + struct file_std_info *fsi; + struct wrap_bin_file *file; + struct common_object_header *coh; + + ENTER2("%p", handle); + coh = handle; + if (coh->type != OBJECT_TYPE_FILE) { + ERROR("handle %p is invalid: %d", coh, coh->type); + EXIT2(return STATUS_FAILURE); + } + fo = HANDLE_TO_OBJECT(handle); + TRACE2("fo: %p, %d", fo, class); + switch (class) { + case FileNameInformation: + fni = info; + fni->length = min(length, (typeof(length))coh->name.length); + memcpy(fni->name, coh->name.buf, fni->length); + iosb->status = STATUS_SUCCESS; + iosb->info = fni->length; + break; + case FileStandardInformation: + fsi = info; + file = fo->wrap_bin_file; + fsi->alloc_size = file->size; + fsi->eof = file->size; + fsi->num_links = 1; + fsi->delete_pending = FALSE; + fsi->dir = FALSE; + iosb->status = STATUS_SUCCESS; + iosb->info = 0; + break; + default: + WARNING("type %d not implemented yet", class); + iosb->status = STATUS_FAILURE; + iosb->info = 0; + break; + } + EXIT2(return iosb->status); +} + +wstdcall NTSTATUS WIN_FUNC(ZwOpenSection,3) + (void **handle, ACCESS_MASK access, struct object_attributes *obj_attrs) +{ + INFO("%p, 0x%x, %d", obj_attrs, obj_attrs->attributes, access); + TODO(); + *handle = obj_attrs; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwMapViewOfSection,10) + (void *secn_handle, void *process_handle, void **base_address, + ULONG zero_bits, LARGE_INTEGER *secn_offset, SIZE_T *view_size, + enum section_inherit inherit, ULONG alloc_type, ULONG protect) +{ + INFO("%p, %p, %p", secn_handle, process_handle, base_address); + TODO(); + *base_address = (void *)0xdeadbeef; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwUnmapViewOfSection,2) + (void *process_handle, void *base_address) +{ + INFO("%p, %p", process_handle, base_address); + TODO(); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwCreateKey,7) + (void **handle, ACCESS_MASK desired_access, + struct object_attributes *attr, ULONG title_index, + struct unicode_string *class, ULONG create_options, + ULONG *disposition) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == + STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + *handle = NULL; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwOpenKey,3) + (void **handle, ACCESS_MASK desired_access, + struct object_attributes *attr) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, attr->name, TRUE) == + STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + *handle = NULL; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwSetValueKey,6) + (void *handle, struct unicode_string *name, ULONG title_index, + ULONG type, void *data, ULONG data_size) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == + STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwQueryValueKey,6) + (void *handle, struct unicode_string *name, + enum key_value_information_class class, void *info, + ULONG length, ULONG *res_length) +{ + struct ansi_string ansi; + if (RtlUnicodeStringToAnsiString(&ansi, name, TRUE) == STATUS_SUCCESS) { + TRACE1("key: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + TODO(); + return STATUS_INVALID_PARAMETER; +} + +wstdcall NTSTATUS WIN_FUNC(ZwDeleteKey,1) + (void *handle) +{ + ENTER2("%p", handle); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(ZwPowerInformation,4) + (INT info_level, void *in_buf, ULONG in_buf_len, void *out_buf, + ULONG out_buf_len) +{ + INFO("%d, %u, %u", info_level, in_buf_len, out_buf_len); + TODO(); + return STATUS_ACCESS_DENIED; +} + +wstdcall NTSTATUS WIN_FUNC(WmiSystemControl,4) + (struct wmilib_context *info, struct device_object *dev_obj, + struct irp *irp, void *irp_disposition) +{ + TODO(); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(WmiCompleteRequest,5) + (struct device_object *dev_obj, struct irp *irp, NTSTATUS status, + ULONG buffer_used, CCHAR priority_boost) +{ + TODO(); + return STATUS_SUCCESS; +} + +noregparm NTSTATUS WIN_FUNC(WmiTraceMessage,12) + (void *tracehandle, ULONG message_flags, + void *message_guid, USHORT message_no, ...) +{ + TODO(); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(WmiQueryTraceInformation,4) + (enum trace_information_class trace_info_class, void *trace_info, + ULONG *req_length, void *buf) +{ + TODO(); + EXIT2(return STATUS_SUCCESS); +} + +/* this function can't be wstdcall as it takes variable number of args */ +noregparm ULONG WIN_FUNC(DbgPrint,12) + (char *format, ...) +{ +#ifdef DEBUG + va_list args; + static char buf[100]; + + va_start(args, format); + vsnprintf(buf, sizeof(buf), format, args); + printk(KERN_DEBUG "%s (%s): %s", DRIVER_NAME, __FUNCTION__, buf); + va_end(args); +#endif + return STATUS_SUCCESS; +} + +wstdcall void WIN_FUNC(KeBugCheckEx,5) + (ULONG code, ULONG_PTR param1, ULONG_PTR param2, + ULONG_PTR param3, ULONG_PTR param4) +{ + TODO(); + return; +} + +wstdcall void WIN_FUNC(ExSystemTimeToLocalTime,2) + (LARGE_INTEGER *system_time, LARGE_INTEGER *local_time) +{ + *local_time = *system_time; +} + +wstdcall ULONG WIN_FUNC(ExSetTimerResolution,2) + (ULONG time, BOOLEAN set) +{ + /* why a driver should change system wide timer resolution is + * beyond me */ + return time; +} + +wstdcall void WIN_FUNC(DbgBreakPoint,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(_except_handler3,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(__C_specific_handler,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(_purecall,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(__chkstk,0) + (void) +{ + TODO(); +} + +struct worker_init_struct { + work_struct_t work; + struct completion completion; + struct nt_thread *nt_thread; +}; + +static void wrap_worker_init_func(worker_param_t param) +{ + struct worker_init_struct *worker_init_struct; + + worker_init_struct = + worker_param_data(param, struct worker_init_struct, work); + TRACE1("%p", worker_init_struct); + worker_init_struct->nt_thread = create_nt_thread(current); + if (!worker_init_struct->nt_thread) + WARNING("couldn't create worker thread"); + complete(&worker_init_struct->completion); +} + +struct nt_thread *wrap_worker_init(workqueue_struct_t *wq) +{ + struct worker_init_struct worker_init_struct; + + TRACE1("%p", &worker_init_struct); + init_completion(&worker_init_struct.completion); + initialize_work(&worker_init_struct.work, wrap_worker_init_func, + &worker_init_struct); + worker_init_struct.nt_thread = NULL; + if (wq) + queue_work(wq, &worker_init_struct.work); + else + schedule_work(&worker_init_struct.work); + wait_for_completion(&worker_init_struct.completion); + TRACE1("%p", worker_init_struct.nt_thread); + return worker_init_struct.nt_thread; +} + +int ntoskernel_init(void) +{ + struct timeval now; + + spin_lock_init(&dispatcher_lock); + spin_lock_init(&ntoskernel_lock); + spin_lock_init(&ntos_work_lock); + spin_lock_init(&kdpc_list_lock); + spin_lock_init(&irp_cancel_lock); + InitializeListHead(&wrap_mdl_list); + InitializeListHead(&kdpc_list); + InitializeListHead(&callback_objects); + InitializeListHead(&bus_driver_list); + InitializeListHead(&object_list); + InitializeListHead(&ntos_work_list); + + nt_spin_lock_init(&nt_list_lock); + + initialize_work(&kdpc_work, kdpc_worker, NULL); + initialize_work(&ntos_work, ntos_work_worker, NULL); + wrap_timer_slist.next = NULL; + + do_gettimeofday(&now); + wrap_ticks_to_boot = TICKS_1601_TO_1970; + wrap_ticks_to_boot += (u64)now.tv_sec * TICKSPERSEC; + wrap_ticks_to_boot += now.tv_usec * 10; + wrap_ticks_to_boot -= jiffies * TICKSPERJIFFY; + TRACE2("%Lu", wrap_ticks_to_boot); + +#ifdef WRAP_PREEMPT + do { + int cpu; + for_each_possible_cpu(cpu) { + irql_info_t *info; + info = &per_cpu(irql_info, cpu); + mutex_init(&(info->lock)); + info->task = NULL; + info->count = 0; + } + } while (0); +#endif + + ntos_wq = create_singlethread_workqueue("ntos_wq"); + if (!ntos_wq) { + WARNING("couldn't create ntos_wq thread"); + return -ENOMEM; + } + ntos_worker_thread = wrap_worker_init(ntos_wq); + TRACE1("%p", ntos_worker_thread); + + if (add_bus_driver("PCI") +#ifdef ENABLE_USB + || add_bus_driver("USB") +#endif + ) { + ntoskernel_exit(); + return -ENOMEM; + } + mdl_cache = + wrap_kmem_cache_create("wrap_mdl", + sizeof(struct wrap_mdl) + MDL_CACHE_SIZE, + 0, 0); + TRACE2("%p", mdl_cache); + if (!mdl_cache) { + ERROR("couldn't allocate MDL cache"); + ntoskernel_exit(); + return -ENOMEM; + } + +#if defined(CONFIG_X86_64) + memset(&kuser_shared_data, 0, sizeof(kuser_shared_data)); + *((ULONG64 *)&kuser_shared_data.system_time) = ticks_1601(); + init_timer(&shared_data_timer); + shared_data_timer.function = update_user_shared_data_proc; + shared_data_timer.data = (unsigned long)0; +#endif + return 0; +} + +int ntoskernel_init_device(struct wrap_device *wd) +{ +#if defined(CONFIG_X86_64) + if (kuser_shared_data.reserved1) + mod_timer(&shared_data_timer, jiffies + MSEC_TO_HZ(30)); +#endif + return 0; +} + +void ntoskernel_exit_device(struct wrap_device *wd) +{ + ENTER2(""); + + KeFlushQueuedDpcs(); + EXIT2(return); +} + +void ntoskernel_exit(void) +{ + struct nt_list *cur; + + ENTER2(""); + + /* free kernel (Ke) timers */ + TRACE2("freeing timers"); + while (1) { + struct wrap_timer *wrap_timer; + struct nt_slist *slist; + + spin_lock_bh(&ntoskernel_lock); + if ((slist = wrap_timer_slist.next)) + wrap_timer_slist.next = slist->next; + spin_unlock_bh(&ntoskernel_lock); + TIMERTRACE("%p", slist); + if (!slist) + break; + wrap_timer = container_of(slist, struct wrap_timer, slist); + if (del_timer_sync(&wrap_timer->timer)) + WARNING("Buggy Windows driver left timer %p running", + wrap_timer->nt_timer); + memset(wrap_timer, 0, sizeof(*wrap_timer)); + slack_kfree(wrap_timer); + } + + TRACE2("freeing MDLs"); + if (mdl_cache) { + spin_lock_bh(&ntoskernel_lock); + if (!IsListEmpty(&wrap_mdl_list)) + ERROR("Windows driver didn't free all MDLs; " + "freeing them now"); + while ((cur = RemoveHeadList(&wrap_mdl_list))) { + struct wrap_mdl *wrap_mdl; + wrap_mdl = container_of(cur, struct wrap_mdl, list); + if (wrap_mdl->mdl->flags & MDL_CACHE_ALLOCATED) + kmem_cache_free(mdl_cache, wrap_mdl); + else + kfree(wrap_mdl); + } + spin_unlock_bh(&ntoskernel_lock); + kmem_cache_destroy(mdl_cache); + mdl_cache = NULL; + } + + TRACE2("freeing callbacks"); + spin_lock_bh(&ntoskernel_lock); + while ((cur = RemoveHeadList(&callback_objects))) { + struct callback_object *object; + struct nt_list *ent; + object = container_of(cur, struct callback_object, list); + while ((ent = RemoveHeadList(&object->callback_funcs))) { + struct callback_func *f; + f = container_of(ent, struct callback_func, list); + kfree(f); + } + kfree(object); + } + spin_unlock_bh(&ntoskernel_lock); + + spin_lock_bh(&ntoskernel_lock); + while ((cur = RemoveHeadList(&bus_driver_list))) { + struct bus_driver *bus_driver; + bus_driver = container_of(cur, struct bus_driver, list); + /* TODO: make sure all all drivers are shutdown/removed */ + kfree(bus_driver); + } + spin_unlock_bh(&ntoskernel_lock); + +#if defined(CONFIG_X86_64) + del_timer_sync(&shared_data_timer); +#endif + if (ntos_wq) + destroy_workqueue(ntos_wq); + TRACE1("%p", ntos_worker_thread); + if (ntos_worker_thread) + ObDereferenceObject(ntos_worker_thread); + ENTER2("freeing objects"); + spin_lock_bh(&ntoskernel_lock); + while ((cur = RemoveHeadList(&object_list))) { + struct common_object_header *hdr; + hdr = container_of(cur, struct common_object_header, list); + if (hdr->type == OBJECT_TYPE_NT_THREAD) + TRACE1("object %p(%d) was not freed, freeing it now", + HEADER_TO_OBJECT(hdr), hdr->type); + else + WARNING("object %p(%d) was not freed, freeing it now", + HEADER_TO_OBJECT(hdr), hdr->type); + ExFreePool(hdr); + } + spin_unlock_bh(&ntoskernel_lock); + + EXIT2(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/ntoskernel_io.c +++ linux-2.6.28/ubuntu/ndiswrapper/ntoskernel_io.c @@ -0,0 +1,1106 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ntoskernel.h" +#include "ndis.h" +#include "wrapndis.h" +#include "usb.h" +#include "loader.h" +#include "ntoskernel_io_exports.h" + +wstdcall void WIN_FUNC(IoAcquireCancelSpinLock,1) + (KIRQL *irql) __acquires(irql) +{ + spin_lock_bh(&irp_cancel_lock); + *irql = 0; +} + +wstdcall void WIN_FUNC(IoReleaseCancelSpinLock,1) + (KIRQL irql) __releases(irql) +{ + spin_unlock_bh(&irp_cancel_lock); +} + +wstdcall int WIN_FUNC(IoIsWdmVersionAvailable,2) + (UCHAR major, UCHAR minor) +{ + IOENTER("%d, %x", major, minor); + if (major == 1 && + (minor == 0x30 || // Windows 2003 + minor == 0x20 || // Windows XP + minor == 0x10)) // Windows 2000 + IOEXIT(return TRUE); + IOEXIT(return FALSE); +} + +wstdcall BOOLEAN WIN_FUNC(IoIs32bitProcess,1) + (struct irp *irp) +{ +#ifdef CONFIG_X86_64 + return FALSE; +#else + return TRUE; +#endif +} + +wstdcall void WIN_FUNC(IoInitializeIrp,3) + (struct irp *irp, USHORT size, CCHAR stack_count) +{ + IOENTER("irp: %p, %d, %d", irp, size, stack_count); + + memset(irp, 0, size); + irp->size = size; + irp->stack_count = stack_count; + irp->current_location = stack_count; + IoGetCurrentIrpStackLocation(irp) = IRP_SL(irp, stack_count); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoReuseIrp,2) + (struct irp *irp, NTSTATUS status) +{ + IOENTER("%p, %d", irp, status); + if (irp) { + UCHAR alloc_flags; + + alloc_flags = irp->alloc_flags; + IoInitializeIrp(irp, irp->size, irp->stack_count); + irp->alloc_flags = alloc_flags; + irp->io_status.status = status; + } + IOEXIT(return); +} + +wstdcall struct irp *WIN_FUNC(IoAllocateIrp,2) + (char stack_count, BOOLEAN charge_quota) +{ + struct irp *irp; + int irp_size; + + IOENTER("count: %d", stack_count); + stack_count++; + irp_size = IoSizeOfIrp(stack_count); + irp = kmalloc(irp_size, irql_gfp()); + if (irp) + IoInitializeIrp(irp, irp_size, stack_count); + IOTRACE("irp %p", irp); + IOEXIT(return irp); +} + +wstdcall BOOLEAN WIN_FUNC(IoCancelIrp,1) + (struct irp *irp) +{ + typeof(irp->cancel_routine) cancel_routine; + + /* NB: this function may be called at DISPATCH_LEVEL */ + IOTRACE("irp: %p", irp); + if (!irp) + return FALSE; + DUMP_IRP(irp); + IoAcquireCancelSpinLock(&irp->cancel_irql); + cancel_routine = xchg(&irp->cancel_routine, NULL); + IOTRACE("%p", cancel_routine); + irp->cancel = TRUE; + if (cancel_routine) { + struct io_stack_location *irp_sl; + irp_sl = IoGetCurrentIrpStackLocation(irp); + IOTRACE("%p, %p", irp_sl, irp_sl->dev_obj); + /* cancel_routine will release the spin lock */ + __release(irp->cancel_irql); + LIN2WIN2(cancel_routine, irp_sl->dev_obj, irp); + /* in usb's cancel, irp->cancel is set to indicate + * status of cancel */ + IOEXIT(return xchg(&irp->cancel, TRUE)); + } else { + IOTRACE("irp %p already canceled", irp); + IoReleaseCancelSpinLock(irp->cancel_irql); + IOEXIT(return FALSE); + } +} + +wstdcall void IoQueueThreadIrp(struct irp *irp) +{ + struct nt_thread *thread; + KIRQL irql; + + thread = get_current_nt_thread(); + if (thread) { + IOTRACE("thread: %p, task: %p", thread, thread->task); + irp->flags |= IRP_SYNCHRONOUS_API; + irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); + InsertTailList(&thread->irps, &irp->thread_list); + IoIrpThread(irp) = thread; + nt_spin_unlock_irql(&thread->lock, irql); + } else + IoIrpThread(irp) = NULL; +} + +wstdcall void IoDequeueThreadIrp(struct irp *irp) +{ + struct nt_thread *thread; + KIRQL irql; + + thread = IoIrpThread(irp); + if (thread) { + irql = nt_spin_lock_irql(&thread->lock, DISPATCH_LEVEL); + RemoveEntryList(&irp->thread_list); + nt_spin_unlock_irql(&thread->lock, irql); + } +} + +wstdcall void WIN_FUNC(IoFreeIrp,1) + (struct irp *irp) +{ + IOENTER("irp = %p", irp); + if (irp->flags & IRP_SYNCHRONOUS_API) + IoDequeueThreadIrp(irp); + kfree(irp); + + IOEXIT(return); +} + +wstdcall struct irp *WIN_FUNC(IoBuildAsynchronousFsdRequest,6) + (ULONG major_fn, struct device_object *dev_obj, void *buffer, + ULONG length, LARGE_INTEGER *offset, + struct io_status_block *user_status) +{ + struct irp *irp; + struct io_stack_location *irp_sl; + + IOENTER("%p", dev_obj); + if (!dev_obj) + IOEXIT(return NULL); + irp = IoAllocateIrp(dev_obj->stack_count, FALSE); + if (irp == NULL) { + WARNING("couldn't allocate irp"); + IOEXIT(return NULL); + } + + irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->major_fn = major_fn; + IOTRACE("major_fn: %d", major_fn); + irp_sl->minor_fn = 0; + irp_sl->flags = 0; + irp_sl->control = 0; + irp_sl->dev_obj = dev_obj; + irp_sl->file_obj = NULL; + irp_sl->completion_routine = NULL; + + if (dev_obj->flags & DO_DIRECT_IO) { + irp->mdl = IoAllocateMdl(buffer, length, FALSE, FALSE, irp); + if (irp->mdl == NULL) { + IoFreeIrp(irp); + return NULL; + } + MmProbeAndLockPages(irp->mdl, KernelMode, + major_fn == IRP_MJ_WRITE ? + IoReadAccess : IoWriteAccess); + IOTRACE("mdl: %p", irp->mdl); + } else if (dev_obj->flags & DO_BUFFERED_IO) { + irp->associated_irp.system_buffer = buffer; + irp->flags = IRP_BUFFERED_IO; + irp->mdl = NULL; + IOTRACE("buffer: %p", buffer); + } + if (major_fn == IRP_MJ_READ) { + irp_sl->params.read.length = length; + irp_sl->params.read.byte_offset = *offset; + } else if (major_fn == IRP_MJ_WRITE) { + irp_sl->params.write.length = length; + irp_sl->params.write.byte_offset = *offset; + } + irp->user_status = user_status; + IOTRACE("irp: %p", irp); + return irp; +} + +wstdcall struct irp *WIN_FUNC(IoBuildSynchronousFsdRequest,7) + (ULONG major_fn, struct device_object *dev_obj, void *buf, + ULONG length, LARGE_INTEGER *offset, struct nt_event *event, + struct io_status_block *user_status) +{ + struct irp *irp; + + irp = IoBuildAsynchronousFsdRequest(major_fn, dev_obj, buf, length, + offset, user_status); + if (irp == NULL) + return NULL; + irp->user_event = event; + IoQueueThreadIrp(irp); + return irp; +} + +wstdcall struct irp *WIN_FUNC(IoBuildDeviceIoControlRequest,9) + (ULONG ioctl, struct device_object *dev_obj, + void *input_buf, ULONG input_buf_len, void *output_buf, + ULONG output_buf_len, BOOLEAN internal_ioctl, + struct nt_event *event, struct io_status_block *io_status) +{ + struct irp *irp; + struct io_stack_location *irp_sl; + ULONG buf_len; + + IOENTER("%p, 0x%08x, %d", dev_obj, ioctl, internal_ioctl); + if (!dev_obj) + IOEXIT(return NULL); + irp = IoAllocateIrp(dev_obj->stack_count, FALSE); + if (irp == NULL) { + WARNING("couldn't allocate irp"); + return NULL; + } + irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->params.dev_ioctl.code = ioctl; + irp_sl->params.dev_ioctl.input_buf_len = input_buf_len; + irp_sl->params.dev_ioctl.output_buf_len = output_buf_len; + irp_sl->major_fn = (internal_ioctl) ? + IRP_MJ_INTERNAL_DEVICE_CONTROL : IRP_MJ_DEVICE_CONTROL; + IOTRACE("%d", IO_METHOD_FROM_CTL_CODE(ioctl)); + + switch (IO_METHOD_FROM_CTL_CODE(ioctl)) { + case METHOD_BUFFERED: + buf_len = max(input_buf_len, output_buf_len); + if (buf_len) { + irp->associated_irp.system_buffer = + ExAllocatePoolWithTag(NonPagedPool, buf_len, 0); + if (!irp->associated_irp.system_buffer) { + IoFreeIrp(irp); + IOEXIT(return NULL); + } + irp->associated_irp.system_buffer = input_buf; + if (input_buf) + memcpy(irp->associated_irp.system_buffer, + input_buf, input_buf_len); + irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; + if (output_buf) + irp->flags = IRP_INPUT_OPERATION; + irp->user_buf = output_buf; + } else + irp->user_buf = NULL; + break; + case METHOD_IN_DIRECT: + case METHOD_OUT_DIRECT: + if (input_buf) { + irp->associated_irp.system_buffer = + ExAllocatePoolWithTag(NonPagedPool, + input_buf_len, 0); + if (!irp->associated_irp.system_buffer) { + IoFreeIrp(irp); + IOEXIT(return NULL); + } + memcpy(irp->associated_irp.system_buffer, + input_buf, input_buf_len); + irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; + } + /* TODO: we are supposed to setup MDL, but USB layer + * doesn't use MDLs. Moreover, USB layer mirrors + * non-DMAable buffers, so no need to allocate + * DMAable buffer here */ + if (output_buf) { + irp->associated_irp.system_buffer = + ExAllocatePoolWithTag(NonPagedPool, + output_buf_len, 0); + if (!irp->associated_irp.system_buffer) { + IoFreeIrp(irp); + IOEXIT(return NULL); + } + irp->flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER; + } + break; + case METHOD_NEITHER: + irp->user_buf = output_buf; + irp_sl->params.dev_ioctl.type3_input_buf = input_buf; + break; + } + + irp->user_status = io_status; + irp->user_event = event; + IoQueueThreadIrp(irp); + + IOTRACE("irp: %p", irp); + IOEXIT(return irp); +} + +wfastcall NTSTATUS WIN_FUNC(IofCallDriver,2) + (struct device_object *dev_obj, struct irp *irp) +{ + struct io_stack_location *irp_sl; + NTSTATUS status; + driver_dispatch_t *major_func; + struct driver_object *drv_obj; + + if (irp->current_location <= 0) { + ERROR("invalid irp: %p, %d", irp, irp->current_location); + return STATUS_INVALID_PARAMETER; + } + IOTRACE("%p, %p, %p, %d, %d, %p", dev_obj, irp, dev_obj->drv_obj, + irp->current_location, irp->stack_count, + IoGetCurrentIrpStackLocation(irp)); + IoSetNextIrpStackLocation(irp); + DUMP_IRP(irp); + irp_sl = IoGetCurrentIrpStackLocation(irp); + drv_obj = dev_obj->drv_obj; + irp_sl->dev_obj = dev_obj; + major_func = drv_obj->major_func[irp_sl->major_fn]; + IOTRACE("major_func: %p, dev_obj: %p", major_func, dev_obj); + if (major_func) + status = LIN2WIN2(major_func, dev_obj, irp); + else { + ERROR("major_function %d is not implemented", + irp_sl->major_fn); + status = STATUS_NOT_SUPPORTED; + } + IOEXIT(return status); +} + +wfastcall void WIN_FUNC(IofCompleteRequest,2) + (struct irp *irp, CHAR prio_boost) +{ + struct io_stack_location *irp_sl; + +#ifdef IO_DEBUG + DUMP_IRP(irp); + if (irp->io_status.status == STATUS_PENDING) { + ERROR("invalid irp: %p, STATUS_PENDING", irp); + return; + } + if (irp->current_location < 0 || + irp->current_location >= irp->stack_count) { + ERROR("invalid irp: %p, %d", irp, irp->current_location); + return; + } +#endif + for (irp_sl = IoGetCurrentIrpStackLocation(irp); + irp->current_location < irp->stack_count; irp_sl++) { + struct device_object *dev_obj; + NTSTATUS status; + + DUMP_IRP(irp); + if (irp_sl->control & SL_PENDING_RETURNED) + irp->pending_returned = TRUE; + + /* current_location and dev_obj must be same as when + * driver called IoSetCompletionRoutine, which sets + * completion routine at next (lower) location, which + * is what we are going to call below; so we set + * current_location and dev_obj for the previous + * (higher) location */ + IoSkipCurrentIrpStackLocation(irp); + if (irp->current_location < irp->stack_count) + dev_obj = IoGetCurrentIrpStackLocation(irp)->dev_obj; + else + dev_obj = NULL; + + IOTRACE("%d, %d, %p", irp->current_location, irp->stack_count, + dev_obj); + if (irp_sl->completion_routine && + ((irp->io_status.status == STATUS_SUCCESS && + irp_sl->control & SL_INVOKE_ON_SUCCESS) || + (irp->io_status.status != STATUS_SUCCESS && + irp_sl->control & SL_INVOKE_ON_ERROR) || + (irp->cancel == TRUE && + irp_sl->control & SL_INVOKE_ON_CANCEL))) { + IOTRACE("calling completion_routine at: %p, %p", + irp_sl->completion_routine, irp_sl->context); + status = LIN2WIN3(irp_sl->completion_routine, + dev_obj, irp, irp_sl->context); + IOTRACE("status: %08X", status); + if (status == STATUS_MORE_PROCESSING_REQUIRED) + IOEXIT(return); + } else { + /* propagate pending status to next irp_sl */ + if (irp->pending_returned && + irp->current_location < irp->stack_count) + IoMarkIrpPending(irp); + } + } + + if (irp->user_status) { + irp->user_status->status = irp->io_status.status; + irp->user_status->info = irp->io_status.info; + } + + if (irp->user_event) { + IOTRACE("setting event %p", irp->user_event); + KeSetEvent(irp->user_event, prio_boost, FALSE); + } + + if (irp->associated_irp.system_buffer && + (irp->flags & IRP_DEALLOCATE_BUFFER)) + ExFreePool(irp->associated_irp.system_buffer); + else { + struct mdl *mdl; + while ((mdl = irp->mdl)) { + irp->mdl = mdl->next; + MmUnlockPages(mdl); + IoFreeMdl(mdl); + } + } + IOTRACE("freeing irp %p", irp); + IoFreeIrp(irp); + IOEXIT(return); +} + +wstdcall NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) +{ + IoSkipCurrentIrpStackLocation(irp); + IOEXIT(return IoCallDriver(dev_obj, irp)); +} + +wstdcall NTSTATUS IoIrpSyncComplete(struct device_object *dev_obj, + struct irp *irp, void *context) +{ + if (irp->pending_returned == TRUE) + KeSetEvent(context, IO_NO_INCREMENT, FALSE); + IOEXIT(return STATUS_MORE_PROCESSING_REQUIRED); +} +WIN_FUNC_DECL(IoIrpSyncComplete,3) + +wstdcall NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) +{ + struct nt_event event; + NTSTATUS status; + + IoCopyCurrentIrpStackLocationToNext(irp); + KeInitializeEvent(&event, SynchronizationEvent, FALSE); + /* completion function is called as Windows function */ + IoSetCompletionRoutine(irp, WIN_FUNC_PTR(IoIrpSyncComplete,3), &event, + TRUE, TRUE, TRUE); + status = IoCallDriver(dev_obj, irp); + IOTRACE("%08X", status); + if (status == STATUS_PENDING) { + KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, + NULL); + status = irp->io_status.status; + } + IOTRACE("%08X", status); + IOEXIT(return status); +} +WIN_FUNC_DECL(IoSyncForwardIrp,2) + +wstdcall NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) +{ + NTSTATUS status; + + IoCopyCurrentIrpStackLocationToNext(irp); + status = IoCallDriver(dev_obj, irp); + IOEXIT(return status); +} +WIN_FUNC_DECL(IoAsyncForwardIrp,2) + +wstdcall NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj, + struct irp *irp) +{ + struct io_stack_location *irp_sl; + NTSTATUS status; + + irp_sl = IoGetCurrentIrpStackLocation(irp); + WARNING("%d:%d not implemented", irp_sl->major_fn, irp_sl->minor_fn); + irp->io_status.status = STATUS_SUCCESS; + irp->io_status.info = 0; + status = irp->io_status.status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + IOEXIT(return status); +} +WIN_FUNC_DECL(IoInvalidDeviceRequest,2) + +static irqreturn_t io_irq_isr(int irq, void *data ISR_PT_REGS_PARAM_DECL) +{ + struct kinterrupt *interrupt = data; + BOOLEAN ret; + +#ifdef CONFIG_DEBUG_SHIRQ + if (!interrupt->u.enabled) + EXIT1(return IRQ_NONE); +#endif + TRACE6("%p", interrupt); + nt_spin_lock(interrupt->actual_lock); + ret = LIN2WIN2(interrupt->isr, interrupt, interrupt->isr_ctx); + nt_spin_unlock(interrupt->actual_lock); + if (ret == TRUE) + EXIT6(return IRQ_HANDLED); + else + EXIT6(return IRQ_NONE); +} + +wstdcall NTSTATUS WIN_FUNC(IoConnectInterrupt,11) + (struct kinterrupt **kinterrupt, PKSERVICE_ROUTINE isr, void *isr_ctx, + NT_SPIN_LOCK *lock, ULONG vector, KIRQL irql, KIRQL synch_irql, + enum kinterrupt_mode mode, BOOLEAN shared, KAFFINITY cpu_mask, + BOOLEAN save_fp) +{ + struct kinterrupt *interrupt; + IOENTER(""); + interrupt = kzalloc(sizeof(*interrupt), GFP_KERNEL); + if (!interrupt) + IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); + interrupt->vector = vector; + interrupt->cpu_mask = cpu_mask; + nt_spin_lock_init(&interrupt->lock); + if (lock) + interrupt->actual_lock = lock; + else + interrupt->actual_lock = &interrupt->lock; + interrupt->shared = shared; + interrupt->save_fp = save_fp; + interrupt->isr = isr; + interrupt->isr_ctx = isr_ctx; + InitializeListHead(&interrupt->list); + interrupt->irql = irql; + interrupt->synch_irql = synch_irql; + interrupt->mode = mode; + if (request_irq(vector, io_irq_isr, shared ? IRQF_SHARED : 0, + "ndiswrapper", interrupt)) { + WARNING("request for irq %d failed", vector); + kfree(interrupt); + IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); + } + *kinterrupt = interrupt; +#ifdef CONFIG_DEBUG_SHIRQ + interrupt->u.enabled = 1; +#endif + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(IoDisconnectInterrupt,1) + (struct kinterrupt *interrupt) +{ +#ifdef CONFIG_DEBUG_SHIRQ + interrupt->u.enabled = 0; +#endif + free_irq(interrupt->vector, interrupt); + kfree(interrupt); +} + +wstdcall struct mdl *WIN_FUNC(IoAllocateMdl,5) + (void *virt, ULONG length, BOOLEAN second_buf, BOOLEAN charge_quota, + struct irp *irp) +{ + struct mdl *mdl; + mdl = allocate_init_mdl(virt, length); + if (!mdl) + return NULL; + if (irp) { + if (second_buf == TRUE) { + struct mdl *last; + + last = irp->mdl; + while (last->next) + last = last->next; + last->next = mdl; + } else + irp->mdl = mdl; + } + IOTRACE("%p", mdl); + return mdl; +} + +wstdcall void WIN_FUNC(IoFreeMdl,1) + (struct mdl *mdl) +{ + IOTRACE("%p", mdl); + free_mdl(mdl); +} + +wstdcall struct io_workitem *WIN_FUNC(IoAllocateWorkItem,1) + (struct device_object *dev_obj) +{ + struct io_workitem *io_workitem; + + IOENTER("%p", dev_obj); + io_workitem = kmalloc(sizeof(*io_workitem), irql_gfp()); + if (!io_workitem) + IOEXIT(return NULL); + io_workitem->dev_obj = dev_obj; + IOEXIT(return io_workitem); +} + +wstdcall void WIN_FUNC(IoFreeWorkItem,1) + (struct io_workitem *io_workitem) +{ + kfree(io_workitem); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoQueueWorkItem,4) + (struct io_workitem *io_workitem, void *func, + enum work_queue_type queue_type, void *context) +{ + IOENTER("%p, %p", io_workitem, io_workitem->dev_obj); + io_workitem->worker_routine = func; + io_workitem->context = context; + schedule_ntos_work_item(func, io_workitem->dev_obj, context); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(ExQueueWorkItem,2) + (struct io_workitem *io_workitem, enum work_queue_type queue_type) +{ + IOENTER("%p", io_workitem); + schedule_ntos_work_item(io_workitem->worker_routine, + io_workitem->dev_obj, io_workitem->context); +} + +wstdcall NTSTATUS WIN_FUNC(IoAllocateDriverObjectExtension,4) + (struct driver_object *drv_obj, void *client_id, ULONG extlen, + void **ext) +{ + struct custom_ext *ce; + + IOENTER("%p, %p", drv_obj, client_id); + ce = kmalloc(sizeof(*ce) + extlen, irql_gfp()); + if (ce == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + IOTRACE("custom_ext: %p", ce); + ce->client_id = client_id; + spin_lock_bh(&ntoskernel_lock); + InsertTailList(&drv_obj->drv_ext->custom_ext, &ce->list); + spin_unlock_bh(&ntoskernel_lock); + + *ext = (void *)ce + sizeof(*ce); + IOTRACE("ext: %p", *ext); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall void *WIN_FUNC(IoGetDriverObjectExtension,2) + (struct driver_object *drv_obj, void *client_id) +{ + struct custom_ext *ce; + void *ret; + + IOENTER("drv_obj: %p, client_id: %p", drv_obj, client_id); + ret = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(ce, &drv_obj->drv_ext->custom_ext, list) { + if (ce->client_id == client_id) { + ret = (void *)ce + sizeof(*ce); + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + IOTRACE("ret: %p", ret); + return ret; +} + +void free_custom_extensions(struct driver_extension *drv_ext) +{ + struct nt_list *ent; + + IOENTER("%p", drv_ext); + spin_lock_bh(&ntoskernel_lock); + while ((ent = RemoveHeadList(&drv_ext->custom_ext))) + kfree(ent); + spin_unlock_bh(&ntoskernel_lock); + IOEXIT(return); +} + +wstdcall NTSTATUS WIN_FUNC(IoCreateDevice,7) + (struct driver_object *drv_obj, ULONG dev_ext_length, + struct unicode_string *dev_name, DEVICE_TYPE dev_type, + ULONG dev_chars, BOOLEAN exclusive, struct device_object **newdev) +{ + struct device_object *dev; + struct dev_obj_ext *dev_obj_ext; + int size; + + IOENTER("%p, %u, %p", drv_obj, dev_ext_length, dev_name); + + size = sizeof(*dev) + dev_ext_length + sizeof(*dev_obj_ext); + dev = allocate_object(size, OBJECT_TYPE_DEVICE, dev_name); + if (!dev) + IOEXIT(return STATUS_INSUFFICIENT_RESOURCES); + if (dev_ext_length) + dev->dev_ext = dev + 1; + else + dev->dev_ext = NULL; + + dev_obj_ext = ((void *)(dev + 1)) + dev_ext_length; + dev_obj_ext->dev_obj = dev; + dev_obj_ext->size = 0; + dev_obj_ext->type = IO_TYPE_DEVICE; + dev->dev_obj_ext = dev_obj_ext; + + dev->type = dev_type; + dev->flags = 0; + dev->size = sizeof(*dev) + dev_ext_length; + dev->ref_count = 1; + dev->attached = NULL; + dev->stack_count = 1; + + dev->drv_obj = drv_obj; + dev->next = drv_obj->dev_obj; + drv_obj->dev_obj = dev; + + dev->align_req = 1; + dev->characteristics = dev_chars; + dev->io_timer = NULL; + KeInitializeEvent(&dev->lock, SynchronizationEvent, TRUE); + dev->vpb = NULL; + + IOTRACE("dev: %p, ext: %p", dev, dev->dev_ext); + *newdev = dev; + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoCreateUnprotectedSymbolicLink,2) + (struct unicode_string *link, struct unicode_string *dev_name) +{ + struct ansi_string ansi; + + IOENTER("%p, %p", dev_name, link); + if (dev_name && (RtlUnicodeStringToAnsiString(&ansi, dev_name, TRUE) == + STATUS_SUCCESS)) { + IOTRACE("dev_name: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) == + STATUS_SUCCESS)) { + IOTRACE("link: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } +// TODO(); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoCreateSymbolicLink,2) + (struct unicode_string *link, struct unicode_string *dev_name) +{ + IOEXIT(return IoCreateUnprotectedSymbolicLink(link, dev_name)); +} + +wstdcall NTSTATUS WIN_FUNC(IoDeleteSymbolicLink,1) + (struct unicode_string *link) +{ + struct ansi_string ansi; + + IOENTER("%p", link); + if (link && (RtlUnicodeStringToAnsiString(&ansi, link, TRUE) == + STATUS_SUCCESS)) { + IOTRACE("dev_name: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(IoDeleteDevice,1) + (struct device_object *dev) +{ + IOENTER("%p", dev); + if (dev == NULL) + IOEXIT(return); + IOTRACE("drv_obj: %p", dev->drv_obj); + if (dev->drv_obj) { + struct device_object *prev; + + prev = dev->drv_obj->dev_obj; + IOTRACE("dev_obj: %p", prev); + if (prev == dev) + dev->drv_obj->dev_obj = dev->next; + else if (prev) { + while (prev->next != dev) + prev = prev->next; + prev->next = dev->next; + } + } + ObDereferenceObject(dev); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoDetachDevice,1) + (struct device_object *tgt) +{ + struct device_object *tail; + + IOENTER("%p", tgt); + if (!tgt) + IOEXIT(return); + tail = tgt->attached; + if (!tail) + IOEXIT(return); + IOTRACE("tail: %p", tail); + + spin_lock_bh(&ntoskernel_lock); + tgt->attached = tail->attached; + IOTRACE("attached:%p", tgt->attached); + for ( ; tail; tail = tail->attached) { + IOTRACE("tail:%p", tail); + tail->stack_count--; + } + spin_unlock_bh(&ntoskernel_lock); + IOEXIT(return); +} + +wstdcall struct device_object *WIN_FUNC(IoGetAttachedDevice,1) + (struct device_object *dev) +{ + IOENTER("%p", dev); + if (!dev) + IOEXIT(return NULL); + spin_lock_bh(&ntoskernel_lock); + while (dev->attached) + dev = dev->attached; + spin_unlock_bh(&ntoskernel_lock); + IOEXIT(return dev); +} + +wstdcall struct device_object *WIN_FUNC(IoGetAttachedDeviceReference,1) + (struct device_object *dev) +{ + IOENTER("%p", dev); + if (!dev) + IOEXIT(return NULL); + dev = IoGetAttachedDevice(dev); + ObReferenceObject(dev); + IOEXIT(return dev); +} + +wstdcall struct device_object *WIN_FUNC(IoAttachDeviceToDeviceStack,2) + (struct device_object *src, struct device_object *tgt) +{ + struct device_object *attached; + struct dev_obj_ext *src_dev_ext; + + IOENTER("%p, %p", src, tgt); + attached = IoGetAttachedDevice(tgt); + IOTRACE("%p", attached); + src_dev_ext = src->dev_obj_ext; + spin_lock_bh(&ntoskernel_lock); + if (attached) + attached->attached = src; + src->attached = NULL; + src->stack_count = attached->stack_count + 1; + src_dev_ext->attached_to = attached; + spin_unlock_bh(&ntoskernel_lock); + IOTRACE("stack_count: %d -> %d", attached->stack_count, + src->stack_count); + IOEXIT(return attached); +} + +wstdcall NTSTATUS WIN_FUNC(IoGetDeviceProperty,5) + (struct device_object *pdo, enum device_registry_property dev_property, + ULONG buffer_len, void *buffer, ULONG *result_len) +{ + struct ansi_string ansi; + struct unicode_string unicode; + struct wrap_device *wd; + ULONG need; + + IOENTER("dev_obj = %p, dev_property = %d, buffer_len = %u, " + "buffer = %p, result_len = %p", pdo, dev_property, + buffer_len, buffer, result_len); + + wd = pdo->reserved; + switch (dev_property) { + case DevicePropertyDeviceDescription: + case DevicePropertyFriendlyName: + case DevicePropertyDriverKeyName: + if (wrap_is_pci_bus(wd->dev_bus)) + RtlInitAnsiString(&ansi, "PCI"); + else // if (wrap_is_usb_bus(wd->dev_bus)) + RtlInitAnsiString(&ansi, "USB"); + need = sizeof(wchar_t) * (ansi.max_length + 1); + if (buffer_len < need) { + *result_len = need; + IOEXIT(return STATUS_BUFFER_TOO_SMALL); + } + unicode.max_length = buffer_len; + unicode.buf = buffer; + if (RtlAnsiStringToUnicodeString(&unicode, &ansi, + FALSE) != STATUS_SUCCESS) { + *result_len = unicode.length; + IOEXIT(return STATUS_BUFFER_TOO_SMALL); + } + IOEXIT(return STATUS_SUCCESS); + default: + WARNING("%d not implemented", dev_property); + IOEXIT(return STATUS_INVALID_PARAMETER_2); + } +} + +wstdcall NTSTATUS WIN_FUNC(IoGetDeviceObjectPointer,4) + (struct unicode_string *name, ACCESS_MASK desired_access, + void *file_obj, struct device_object *dev_obj) +{ + struct common_object_header *coh; + + dev_obj = NULL; + /* TODO: access is not checked and file_obj is set to NULL */ + file_obj = NULL; + spin_lock_bh(&ntoskernel_lock); + nt_list_for_each_entry(coh, &object_list, list) { + TRACE5("header: %p, type: %d", coh, coh->type); + if (coh->type != OBJECT_TYPE_DEVICE) + continue; + if (!RtlCompareUnicodeString(&coh->name, name, TRUE)) { + dev_obj = HEADER_TO_OBJECT(coh); + TRACE5("dev_obj: %p", dev_obj); + break; + } + } + spin_unlock_bh(&ntoskernel_lock); + if (dev_obj) + IOEXIT(return STATUS_SUCCESS); + else + IOEXIT(return STATUS_OBJECT_NAME_INVALID); +} + +/* NOTE: Make sure to compile with -freg-struct-return, so gcc will + * return union in register, like Windows */ +wstdcall union power_state WIN_FUNC(PoSetPowerState,3) + (struct device_object *dev_obj, enum power_state_type type, + union power_state state) +{ + IOEXIT(return state); +} + +wstdcall NTSTATUS WIN_FUNC(PoCallDriver,2) + (struct device_object *dev_obj, struct irp *irp) +{ + return IoCallDriver(dev_obj, irp); +} + +wstdcall NTSTATUS WIN_FUNC(PoRequestPowerIrp,6) + (struct device_object *dev_obj, UCHAR minor_fn, + union power_state power_state, void *completion_func, + void *context, struct irp **pirp) +{ + struct irp *irp; + struct io_stack_location *irp_sl; + + TRACE1("%p, %d, %p", dev_obj, dev_obj->stack_count, dev_obj->drv_obj); + irp = IoAllocateIrp(dev_obj->stack_count, FALSE); + if (!irp) + return STATUS_INSUFFICIENT_RESOURCES; + irp_sl = IoGetNextIrpStackLocation(irp); + irp_sl->major_fn = IRP_MJ_POWER; + irp_sl->minor_fn = minor_fn; + if (minor_fn == IRP_MN_WAIT_WAKE) + irp_sl->params.power.type = SystemPowerState; + else + irp_sl->params.power.type = DevicePowerState; + irp_sl->params.power.state = power_state; + irp_sl->completion_routine = completion_func; + irp->io_status.status = STATUS_NOT_SUPPORTED; + *pirp = irp; + return PoCallDriver(dev_obj, irp); +} + +wstdcall void WIN_FUNC(PoStartNextPowerIrp,1) + (struct irp *irp) +{ + IOENTER("irp = %p", irp); + IOEXIT(return); +} + +wstdcall void WIN_FUNC(IoInitializeRemoveLockEx,5) + (struct io_remove_lock *lock, ULONG alloc_tag, ULONG max_locked_min, + ULONG high_mark, ULONG lock_size) +{ + TODO(); +} + +wstdcall void *WIN_FUNC(IoAllocateErrorLogEntry,2) + (void *io_object, UCHAR entry_size) +{ + /* not implemented fully */ + void *ret = kmalloc(sizeof(struct io_error_log_packet) + entry_size, + irql_gfp()); + TRACE2("%p", ret); + if (ret) + return ret + sizeof(struct io_error_log_packet); + else + return NULL; +} + +wstdcall void WIN_FUNC(IoWriteErrorLogEntry,1) + (void *entry) +{ + /* TODO: log error with codes and message */ + ERROR(""); +} + +wstdcall void WIN_FUNC(IoFreeErrorLogEntry,1) + (void *entry) +{ + TRACE2("%p", entry); + kfree(entry - sizeof(struct io_error_log_packet)); +} + +wstdcall NTSTATUS WIN_FUNC(IoAcquireRemoveLockEx,5) + (struct io_remove_lock lock, void *tag, char *file, ULONG line, + ULONG lock_size) +{ + TODO(); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoReleaseRemoveLockEx,3) + (struct io_remove_lock lock, void *tag, ULONG lock_size) +{ + TODO(); + IOEXIT(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(IoRegisterDeviceInterface,4) + (struct device_object *pdo, struct guid *guid_class, + struct unicode_string *reference, struct unicode_string *link) +{ + struct ansi_string ansi; + + /* TODO: check if pdo is valid */ + RtlInitAnsiString(&ansi, "ndis"); + ENTER1("pdo: %p, ref: %p, link: %p, %x, %x, %x", pdo, reference, link, + guid_class->data1, guid_class->data2, guid_class->data3); + return RtlAnsiStringToUnicodeString(link, &ansi, TRUE); +} + +wstdcall NTSTATUS WIN_FUNC(IoSetDeviceInterfaceState,2) + (struct unicode_string *link, BOOLEAN enable) +{ + ENTER1("link: %p, enable: %d", link, enable); + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(IoOpenDeviceRegistryKey,4) + (struct device_object *dev_obj, ULONG type, ACCESS_MASK mask, + void **handle) +{ + ENTER1("dev_obj: %p", dev_obj); + *handle = dev_obj; + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(IoWMIRegistrationControl,2) + (struct device_object *dev_obj, ULONG action) +{ + ENTER2("%p, %d", dev_obj, action); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(IoInvalidateDeviceRelations,2) + (struct device_object *dev_obj, enum device_relation_type type) +{ + INFO("%p, %d", dev_obj, type); + TODO(); +} + +wstdcall void WIN_FUNC(IoInvalidateDeviceState,1) + (struct device_object *pdo) +{ + INFO("%p", pdo); + TODO(); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/crt.c +++ linux-2.6.28/ubuntu/ndiswrapper/crt.c @@ -0,0 +1,578 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ntoskernel.h" +#include "crt_exports.h" + +#ifdef CONFIG_X86_64 +/* Windows long is 32-bit, so strip single 'l' in integer formats */ +static void strip_l_modifier(char *str) +{ + char *ptr = str; + int in_format = 0; + char *lptr = NULL; + char last = 0; + char *end_ptr; + char *wptr; + + /* Replace single 'l' inside integer formats with '\0' */ + for (ptr = str; *ptr; ptr++) { + if (!in_format) { + if (*ptr == '%') + in_format = 1; + last = *ptr; + continue; + } + switch (*ptr) { + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + case 'p': + case 'n': + case 'm': + if (lptr) { + *lptr = '\0'; + lptr = NULL; + } + in_format = 0; + break; + case 'c': + case 'C': + case 's': + case 'S': + case 'f': + case 'e': + case 'E': + case 'g': + case 'G': + case 'a': + case 'A': + lptr = NULL; + in_format = 0; + break; + case '%': + lptr = NULL; + if (last == '%') + in_format = 0; + else + in_format = 1; /* ignore previous junk */ + break; + case 'l': + if (last == 'l') + lptr = NULL; + else + lptr = ptr; + break; + default: + break; + } + last = *ptr; + } + + /* Purge zeroes from the resulting string */ + end_ptr = ptr; + wptr = str; + for (ptr = str; ptr < end_ptr; ptr++) + if (*ptr != 0) + *(wptr++) = *ptr; + *wptr = 0; +} + +/* + * va_list on x86_64 Linux is designed to allow passing arguments in registers + * even to variadic functions. va_list is a structure holding pointers to the + * register save area, which holds the arguments passed in registers, and to + * the stack, which may have the arguments that did not fit the registers. + * va_list also holds offsets in the register save area for the next general + * purpose and floating point registers that the next va_arg() would fetch. + * + * Unlike Linux, the Windows va_list is just a pointer to the stack. No + * arguments are passed in the registers. That's why we construct the Linux + * va_list so that the register save area is never used. For that goal, we set + * the offsets to the maximal allowed values, meaning that the arguments passed + * in the registers have been exhausted. The values are 48 for general purpose + * registers (6 registers, 8 bytes each) and 304 for floating point registers + * (16 registers, 16 bytes each, on top of general purpose register). + */ + +struct x86_64_va_list { + int gp_offset; + int fp_offset; + void *overflow_arg_area; + void *reg_save_area; +}; + +#define VA_LIST_DECL(_args) \ + va_list _args##new; \ + struct x86_64_va_list *_args##x; +#define VA_LIST_PREP(_args) \ +do { \ + _args##x = (struct x86_64_va_list *)&_args##new; \ + _args##x->gp_offset = 6 * 8; /* GP registers exhausted */ \ + _args##x->fp_offset = 6 * 8 + 16 * 16; /* FP registers exhausted */ \ + _args##x->overflow_arg_area = (void *)_args; \ + _args##x->reg_save_area = NULL; \ +} while (0) +#define VA_LIST_CONV(_args) (_args##new) +#define VA_LIST_FREE(_args) +#define FMT_DECL(_fmt) \ + char *_fmt##copy; \ + int _fmt##len; +#define FMT_PREP(_fmt) \ +do { \ + _fmt##len = strlen(format) + 1; \ + _fmt##copy = kmalloc(_fmt##len, GFP_KERNEL); \ + if (_fmt##copy) { \ + memcpy(_fmt##copy, format, _fmt##len); \ + strip_l_modifier(_fmt##copy); \ + } \ +} while (0) +#define FMT_CONV(_fmt) (_fmt##copy ? _fmt##copy : format) +#define FMT_FREE(_fmt) kfree(_fmt##copy) + +#else /* !CONFIG_X86_64 */ + +#define VA_LIST_DECL(_args) +#define VA_LIST_PREP(_args) +#define VA_LIST_CONV(_args) (_args) +#define VA_LIST_FREE(_args) +#define FMT_DECL(_fmt) +#define FMT_PREP(_fmt) +#define FMT_CONV(_fmt) (format) +#define FMT_FREE(_fmt) + +#endif /* !CONFIG_X86_64 */ + +noregparm INT WIN_FUNC(_win_sprintf,12) + (char *buf, const char *format, ...) +{ + va_list args; + int res; + FMT_DECL(format) + + FMT_PREP(format); + va_start(args, format); + res = vsprintf(buf, FMT_CONV(format), args); + va_end(args); + FMT_FREE(format); + + TRACE2("buf: %p: %s", buf, buf); + return res; +} + +noregparm INT WIN_FUNC(swprintf,12) + (wchar_t *buf, const wchar_t *format, ...) +{ + TODO(); + EXIT2(return 0); +} + +noregparm INT WIN_FUNC(_win_vsprintf,3) + (char *str, const char *format, va_list ap) +{ + INT i; + VA_LIST_DECL(ap) + FMT_DECL(format) + + VA_LIST_PREP(ap); + FMT_PREP(format); + + i = vsprintf(str, FMT_CONV(format), VA_LIST_CONV(ap)); + TRACE2("str: %p: %s", str, str); + + FMT_FREE(format); + VA_LIST_FREE(ap); + EXIT2(return i); +} + +noregparm INT WIN_FUNC(_win_snprintf,12) + (char *buf, SIZE_T count, const char *format, ...) +{ + va_list args; + int res; + FMT_DECL(format) + + FMT_PREP(format); + va_start(args, format); + res = vsnprintf(buf, count, FMT_CONV(format), args); + va_end(args); + TRACE2("buf: %p: %s", buf, buf); + + FMT_FREE(format); + return res; +} + +noregparm INT WIN_FUNC(_win__snprintf,12) + (char *buf, SIZE_T count, const char *format, ...) +{ + va_list args; + int res; + FMT_DECL(format) + + FMT_PREP(format); + va_start(args, format); + res = vsnprintf(buf, count, FMT_CONV(format), args); + va_end(args); + TRACE2("buf: %p: %s", buf, buf); + + FMT_FREE(format); + return res; +} + +noregparm INT WIN_FUNC(_win_vsnprintf,4) + (char *str, SIZE_T size, const char *format, va_list ap) +{ + INT i; + VA_LIST_DECL(ap) + FMT_DECL(format) + + VA_LIST_PREP(ap); + FMT_PREP(format); + + i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap)); + TRACE2("str: %p: %s", str, str); + + FMT_FREE(format); + VA_LIST_FREE(ap); + EXIT2(return i); +} + +noregparm INT WIN_FUNC(_win__vsnprintf,4) + (char *str, SIZE_T size, const char *format, va_list ap) +{ + INT i; + VA_LIST_DECL(ap) + FMT_DECL(format) + + VA_LIST_PREP(ap); + FMT_PREP(format); + + i = vsnprintf(str, size, FMT_CONV(format), VA_LIST_CONV(ap)); + TRACE2("str: %p: %s", str, str); + + FMT_FREE(format); + VA_LIST_FREE(ap); + EXIT2(return i); +} + +noregparm char *WIN_FUNC(_win_strncpy,3) + (char *dst, char *src, SIZE_T n) +{ + return strncpy(dst, src, n); +} + +noregparm SIZE_T WIN_FUNC(_win_strlen,1) + (const char *s) +{ + return strlen(s); +} + +noregparm INT WIN_FUNC(_win_strncmp,3) + (const char *s1, const char *s2, SIZE_T n) +{ + return strncmp(s1, s2, n); +} + +noregparm INT WIN_FUNC(_win_strcmp,2) + (const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} + +noregparm INT WIN_FUNC(_win_stricmp,2) + (const char *s1, const char *s2) +{ + return stricmp(s1, s2); +} + +noregparm char *WIN_FUNC(_win_strncat,3) + (char *dest, const char *src, SIZE_T n) +{ + return strncat(dest, src, n); +} + +noregparm INT WIN_FUNC(_win_wcscmp,2) + (const wchar_t *s1, const wchar_t *s2) +{ + while (*s1 && *s1 == *s2) { + s1++; + s2++; + } + return *s1 - *s2; +} + +noregparm INT WIN_FUNC(_win_wcsicmp,2) + (const wchar_t *s1, const wchar_t *s2) +{ + while (*s1 && tolower((char)*s1) == tolower((char)*s2)) { + s1++; + s2++; + } + return tolower((char)*s1) - tolower((char)*s2); +} + +noregparm SIZE_T WIN_FUNC(_win_wcslen,1) + (const wchar_t *s) +{ + const wchar_t *t = s; + while (*t) + t++; + return t - s; +} + +noregparm wchar_t *WIN_FUNC(_win_wcsncpy,3) + (wchar_t *dest, const wchar_t *src, SIZE_T n) +{ + const wchar_t *s; + wchar_t *d; + s = src + n; + d = dest; + while (src < s && (*d++ = *src++)) + ; + if (s > src) + memset(d, 0, (s - src) * sizeof(wchar_t)); + return dest; +} + +noregparm wchar_t *WIN_FUNC(_win_wcscpy,2) + (wchar_t *dest, const wchar_t *src) +{ + wchar_t *d = dest; + while ((*d++ = *src++)) + ; + return dest; +} + +noregparm wchar_t *WIN_FUNC(_win_wcscat,2) + (wchar_t *dest, const wchar_t *src) +{ + wchar_t *d; + d = dest; + while (*d) + d++; + while ((*d++ = *src++)) + ; + return dest; +} + +noregparm INT WIN_FUNC(_win_towupper,1) + (wchar_t c) +{ + return toupper(c); +} + +noregparm INT WIN_FUNC(_win_towlower,1) + (wchar_t c) +{ + return tolower(c); +} + +noregparm INT WIN_FUNC(_win_tolower,1) + (INT c) +{ + return tolower(c); +} + +noregparm INT WIN_FUNC(_win_toupper,1) + (INT c) +{ + return toupper(c); +} + +noregparm void *WIN_FUNC(_win_strcpy,2) + (void *to, const void *from) +{ + return strcpy(to, from); +} + +noregparm char *WIN_FUNC(_win_strstr,2) + (const char *s1, const char *s2) +{ + return strstr(s1, s2); +} + +noregparm char *WIN_FUNC(_win_strchr,2) + (const char *s, int c) +{ + return strchr(s, c); +} + +noregparm char *WIN_FUNC(_win_strrchr,2) + (const char *s, int c) +{ + return strrchr(s, c); +} + +noregparm void *WIN_FUNC(_win_memmove,3) + (void *to, void *from, SIZE_T count) +{ + return memmove(to, from, count); +} + +noregparm void *WIN_FUNC(_win_memchr,3) + (const void *s, INT c, SIZE_T n) +{ + return memchr(s, c, n); +} + +noregparm void *WIN_FUNC(_win_memcpy,3) + (void *to, const void *from, SIZE_T n) +{ + return memcpy(to, from, n); +} + +noregparm void *WIN_FUNC(_win_memset,3) + (void *s, char c, SIZE_T count) +{ + return memset(s, c, count); +} + +noregparm int WIN_FUNC(_win_memcmp,3) + (void *s1, void *s2, SIZE_T n) +{ + return memcmp(s1, s2, n); +} + +noregparm void WIN_FUNC(_win_srand,1) + (UINT seed) +{ + net_srandom(seed); +} + +noregparm int WIN_FUNC(rand,0) + (void) +{ + char buf[6]; + int i, n; + + get_random_bytes(buf, sizeof(buf)); + for (n = i = 0; i < sizeof(buf) ; i++) + n += buf[i]; + return n; +} + +noregparm int WIN_FUNC(_win_atoi,1) + (const char *ptr) +{ + int i = simple_strtol(ptr, NULL, 10); + return i; +} + +noregparm int WIN_FUNC(_win_isprint,1) + (int c) +{ + return isprint(c); +} + +wstdcall s64 WIN_FUNC(_alldiv,2) + (s64 a, s64 b) +{ + return (a / b); +} + +wstdcall u64 WIN_FUNC(_aulldiv,2) + (u64 a, u64 b) +{ + return (a / b); +} + +wstdcall s64 WIN_FUNC(_allmul,2) + (s64 a, s64 b) +{ + return (a * b); +} + +wstdcall u64 WIN_FUNC(_aullmul,2) + (u64 a, u64 b) +{ + return (a * b); +} + +wstdcall s64 WIN_FUNC(_allrem,2) + (s64 a, s64 b) +{ + return (a % b); +} + +wstdcall u64 WIN_FUNC(_aullrem,2) + (u64 a, u64 b) +{ + return (a % b); +} + +__attribute__((regparm(3))) s64 WIN_FUNC(_allshl,2) + (s64 a, u8 b) +{ + return (a << b); +} + +__attribute__((regparm(3))) u64 WIN_FUNC(_aullshl,2) + (u64 a, u8 b) +{ + return (a << b); +} + +__attribute__((regparm(3))) s64 WIN_FUNC(_allshr,2) + (s64 a, u8 b) +{ + return (a >> b); +} + +__attribute__((regparm(3))) u64 WIN_FUNC(_aullshr,2) + (u64 a, u8 b) +{ + return (a >> b); +} + +int stricmp(const char *s1, const char *s2) +{ + while (*s1 && tolower(*s1) == tolower(*s2)) { + s1++; + s2++; + } + return *s1 - *s2; +} + +void dump_bytes(const char *ctx, const u8 *from, int len) +{ + int i, j; + u8 *buf; + + buf = kmalloc(len * 3 + 1, irql_gfp()); + if (!buf) { + ERROR("couldn't allocate memory"); + return; + } + for (i = j = 0; i < len; i++, j += 3) { + sprintf(&buf[j], "%02x ", from[i]); + } + buf[j] = 0; + printk(KERN_DEBUG "%s: %p: %s\n", ctx, from, buf); + kfree(buf); +} + +int crt_init(void) +{ + return 0; +} + +/* called when module is being removed */ +void crt_exit(void) +{ + EXIT4(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/mkstubs.sh +++ linux-2.6.28/ubuntu/ndiswrapper/mkstubs.sh @@ -0,0 +1,12 @@ +#! /bin/sh + +for file in "$@"; do + echo + echo "# automatically generated from $file" + sed -n \ + -e 's/.*WIN_FUNC(\([^\,]\+\) *\, *\([0-9]\+\)).*/\ + win2lin(\1, \2)/p' \ + -e 's/.*WIN_FUNC_PTR(\([^\,]\+\) *\, *\([0-9]\+\)).*/\ + win2lin(\1, \2)/p' \ + $file | sed -e 's/[ \t ]\+//' | sort -u; \ +done --- linux-2.6.28.orig/ubuntu/ndiswrapper/iw_ndis.h +++ linux-2.6.28/ubuntu/ndiswrapper/iw_ndis.h @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _IW_NDIS_H_ +#define _IW_NDIS_H_ + +#include "ndis.h" + +#define WL_NOISE -96 /* typical noise level in dBm */ +#define WL_SIGMAX -32 /* typical maximum signal level in dBm */ + +struct ndis_encr_key { + ULONG struct_size; + ULONG index; + ULONG length; + UCHAR key[NDIS_ENCODING_TOKEN_MAX]; +}; + +struct ndis_add_key { + ULONG struct_size; + ndis_key_index index; + ULONG length; + mac_address bssid; + UCHAR pad[6]; + ndis_key_rsc rsc; + UCHAR key[NDIS_ENCODING_TOKEN_MAX]; +}; + +struct ndis_remove_key { + ULONG struct_size; + ndis_key_index index; + mac_address bssid; +}; + +struct ndis_fixed_ies { + UCHAR time_stamp[8]; + USHORT beacon_interval; + USHORT capa; +}; + +struct ndis_variable_ies { + ULONG elem_id; + UCHAR length; + UCHAR data[1]; +}; + +enum ndis_reload_defaults { Ndis802_11ReloadWEPKeys }; + +struct ndis_assoc_info { + ULONG length; + USHORT req_ies; + struct req_ie { + USHORT capa; + USHORT listen_interval; + mac_address cur_ap_address; + } req_ie; + ULONG req_ie_length; + ULONG offset_req_ies; + USHORT resp_ies; + struct resp_ie { + USHORT capa; + USHORT status_code; + USHORT assoc_id; + } resp_ie; + ULONG resp_ie_length; + ULONG offset_resp_ies; +}; + +struct ndis_configuration_fh { + ULONG length; + ULONG hop_pattern; + ULONG hop_set; + ULONG dwell_time; +}; + +struct ndis_configuration { + ULONG length; + ULONG beacon_period; + ULONG atim_window; + ULONG ds_config; + struct ndis_configuration_fh fh_config; +}; + +struct ndis_wlan_bssid { + ULONG length; + mac_address mac; + UCHAR reserved[2]; + struct ndis_essid ssid; + ULONG privacy; + ndis_rssi rssi; + UINT net_type; + struct ndis_configuration config; + UINT mode; + ndis_rates rates; +}; + +struct ndis_wlan_bssid_ex { + ULONG length; + mac_address mac; + UCHAR reserved[2]; + struct ndis_essid ssid; + ULONG privacy; + ndis_rssi rssi; + UINT net_type; + struct ndis_configuration config; + UINT mode; + ndis_rates_ex rates_ex; + ULONG ie_length; + UCHAR ies[1]; +}; + +/* we use bssid_list as bssid_list_ex also */ +struct ndis_bssid_list { + ULONG num_items; + struct ndis_wlan_bssid bssid[1]; +}; + +enum ndis_priv_filter { + Ndis802_11PrivFilterAcceptAll, Ndis802_11PrivFilter8021xWEP +}; + +enum network_type { + Ndis802_11FH, Ndis802_11DS, Ndis802_11OFDM5, Ndis802_11OFDM24, + /* MSDN site uses Ndis802_11Automode, which is not mentioned + * in DDK, so add one and assign it to + * Ndis802_11NetworkTypeMax */ + Ndis802_11Automode, Ndis802_11NetworkTypeMax = Ndis802_11Automode +}; + +struct network_type_list { + ULONG num; + enum network_type types[1]; +}; + +enum ndis_power { + NDIS_POWER_OFF = 0, NDIS_POWER_MAX, NDIS_POWER_MIN, +}; + +struct ndis_auth_req { + ULONG length; + mac_address bssid; + ULONG flags; +}; + +struct ndis_bssid_info { + mac_address bssid; + ndis_pmkid_vavlue pmkid; +}; + +struct ndis_pmkid { + ULONG length; + ULONG bssid_info_count; + struct ndis_bssid_info bssid_info[1]; +}; + +int add_wep_key(struct ndis_device *wnd, char *key, int key_len, + int index); +int set_essid(struct ndis_device *wnd, const char *ssid, int ssid_len); +int set_infra_mode(struct ndis_device *wnd, + enum ndis_infrastructure_mode mode); +int get_ap_address(struct ndis_device *wnd, mac_address mac); +int set_ndis_auth_mode(struct ndis_device *wnd, ULONG auth_mode); +int set_iw_auth_mode(struct ndis_device *wnd, int wpa_version, + int auth_80211_alg); +int set_auth_mode(struct ndis_device *wnd); +int set_ndis_encr_mode(struct ndis_device *wnd, int cipher_pairwise, + int cipher_groupwise); +int get_ndis_encr_mode(struct ndis_device *wnd); +int set_encr_mode(struct ndis_device *wnd); +int set_iw_encr_mode(struct ndis_device *wnd, int cipher_pairwise, + int cipher_groupwise); +int get_ndis_auth_mode(struct ndis_device *wnd); +int set_priv_filter(struct ndis_device *wnd); +int set_scan(struct ndis_device *wnd); +NDIS_STATUS disassociate(struct ndis_device *wnd, int reset_ssid); +void set_default_iw_params(struct ndis_device *wnd); +extern const struct iw_handler_def ndis_handler_def; + +#define PRIV_RESET SIOCIWFIRSTPRIV+16 +#define PRIV_POWER_PROFILE SIOCIWFIRSTPRIV+17 +#define PRIV_NETWORK_TYPE SIOCIWFIRSTPRIV+18 +#define PRIV_DEAUTHENTICATE SIOCIWFIRSTPRIV+19 +#define PRIV_MEDIA_STREAM_MODE SIOCIWFIRSTPRIV+20 +#define PRIV_RELOAD_DEFAULTS SIOCIWFIRSTPRIV+23 + +#define RSN_INFO_ELEM 0x30 + +/* these have to match what is in wpa_supplicant */ + +typedef enum { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP } wpa_alg; +typedef enum { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, + CIPHER_WEP104 } wpa_cipher; +typedef enum { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE, + KEY_MGMT_802_1X_NO_WPA, KEY_MGMT_WPA_NONE } wpa_key_mgmt; + +#endif // IW_NDIS_H --- linux-2.6.28.orig/ubuntu/ndiswrapper/wrapmem.h +++ linux-2.6.28/ubuntu/ndiswrapper/wrapmem.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2006 Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _WRAPMEM_H_ + +/* set ALLOC_DEBUG to 1 to get information about memory used by both + * ndiswrapper and Windows driver by reading + * /proc/net/ndiswrapper/debug; this will also show memory leaks + * (memory allocated but not freed) when ndiswrapper module is + * unloaded. + + * ALLOC_DEBUG=2: details about individual allocations leaking is printed + * ALLOC_DEBUG=3: tags in ExAllocatePoolWithTag leaking printed +*/ + +//#ifndef ALLOC_DEBUG +//#define ALLOC_DEBUG 1 +//#endif + +enum alloc_type { ALLOC_TYPE_KMALLOC_ATOMIC, ALLOC_TYPE_KMALLOC_NON_ATOMIC, + ALLOC_TYPE_VMALLOC_ATOMIC, ALLOC_TYPE_VMALLOC_NON_ATOMIC, + ALLOC_TYPE_SLACK, ALLOC_TYPE_PAGES, ALLOC_TYPE_MAX }; + +int wrapmem_init(void); +void wrapmem_exit(void); +void *slack_kmalloc(size_t size); +void slack_kfree(void *ptr); +void wrapmem_info(void); + +#ifdef ALLOC_DEBUG +void *wrap_kmalloc(size_t size, gfp_t flags, const char *file, int line); +void *wrap_kzalloc(size_t size, gfp_t flags, const char *file, int line); +void wrap_kfree(void *ptr); +void *wrap_vmalloc(unsigned long size, const char *file, int line); +void *wrap__vmalloc(unsigned long size, gfp_t flags, pgprot_t prot, + const char *file, int line); +void wrap_vfree(void *ptr); +void *wrap_alloc_pages(gfp_t flags, unsigned int size, + const char *file, int line); +void wrap_free_pages(unsigned long ptr, int order); +int alloc_size(enum alloc_type type); + +#ifndef _WRAPMEM_C_ +#undef kmalloc +#undef kzalloc +#undef kfree +#undef vmalloc +#undef __vmalloc +#undef vfree +#define kmalloc(size, flags) \ + wrap_kmalloc(size, flags, __FILE__, __LINE__) +#define kzalloc(size, flags) \ + wrap_kzalloc(size, flags, __FILE__, __LINE__) +#define vmalloc(size) \ + wrap_vmalloc(size, __FILE__, __LINE__) +#define __vmalloc(size, flags, prot) \ + wrap__vmalloc(size, flags, prot, __FILE__, __LINE__) +#define kfree(ptr) wrap_kfree(ptr) +#define vfree(ptr) wrap_vfree(ptr) + +#define wrap_get_free_pages(flags, size) \ + wrap_alloc_pages(flags, size, __FILE__, __LINE__) +#undef free_pages +#define free_pages(ptr, order) wrap_free_pages(ptr, order) + +#if ALLOC_DEBUG > 1 +void *wrap_ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, + ULONG tag, const char *file, int line); +#define ExAllocatePoolWithTag(pool_type, size, tag) \ + wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__) +#endif + +#endif // _WRAPMEM_C_ + +#else + +#define wrap_get_free_pages(flags, size) \ + (void *)__get_free_pages(flags, get_order(size)) + +#endif // ALLOC_DEBUG + +#endif --- linux-2.6.28.orig/ubuntu/ndiswrapper/Makefile +++ linux-2.6.28/ubuntu/ndiswrapper/Makefile @@ -0,0 +1,38 @@ +ndiswrapper-objs := crt.o hal.o iw_ndis.o loader.o ndis.o ntoskernel.o ntoskernel_io.o \ + pe_linker.o pnp.o proc.o rtl.o wrapmem.o wrapndis.o wrapper.o usb.o + +EXPORTS = crt_exports.h hal_exports.h ndis_exports.h ntoskernel_exports.h \ + ntoskernel_io_exports.h rtl_exports.h usb_exports.h + +STUB_SRCS = crt.c hal.c ndis.c ntoskernel.c ntoskernel_io.c \ + pnp.c rtl.c wrapndis.c usb.c + + +EXTRA_CFLAGS += -DENABLE_USB -I$(obj) +EXTRA_AFLAGS += -I$(obj) + +# generate exports symbol table from C files +quiet_cmd_mkexport = MKEXPORT $@ +cmd_mkexport = $(SHELL) $(srctree)/$(src)/mkexport.sh $< $@ + +%_exports.h: %.c $(srctree)/$(src)/mkexport.sh FORCE + $(call if_changed,mkexport) + +$(addprefix $(obj)/,$(EXPORTS:_exports.h=.o)): %.o: %_exports.h +extra-y += $(EXPORTS) + +ifeq ($(CONFIG_X86_64),y) +quiet_cmd_mkstubs = MKSTUBS $@ +cmd_mkstubs = $(SHELL) $(srctree)/$(src)/mkstubs.sh $(addprefix $(srctree)/$(src)/,$(STUB_SRCS)) >$@ + +$(obj)/win2lin_stubs.h: $(addprefix $(srctree)/$(src)/,$(STUB_SRCS)) FORCE + $(call if_changed,mkstubs) + +$(obj)/win2lin_stubs.o: $(obj)/win2lin_stubs.h +extra-y += win2lin_stubs.h +ndiswrapper-objs += win2lin_stubs.o +else +ndiswrapper-objs += divdi3.o +endif + +obj-$(CONFIG_NDISWRAPPER) := ndiswrapper.o --- linux-2.6.28.orig/ubuntu/ndiswrapper/ntoskernel.h +++ linux-2.6.28/ubuntu/ndiswrapper/ntoskernel.h @@ -0,0 +1,1165 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _NTOSKERNEL_H_ +#define _NTOSKERNEL_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(CONFIG_X86) && !defined(CONFIG_X86_64) +#error "this module is for x86 or x86_64 architectures only" +#endif + +/* Interrupt backwards compatibility stuff */ +#include +#ifndef IRQ_HANDLED +#define IRQ_HANDLED +#define IRQ_NONE +#define irqreturn_t void +#endif + +/* pci functions in 2.6 kernels have problems allocating dma buffers, + * but seem to work fine with dma functions + */ +#include + +#define PCI_DMA_ALLOC_COHERENT(pci_dev,size,dma_handle) \ + dma_alloc_coherent(&pci_dev->dev,size,dma_handle, \ + GFP_KERNEL | __GFP_REPEAT) +#define PCI_DMA_FREE_COHERENT(pci_dev,size,cpu_addr,dma_handle) \ + dma_free_coherent(&pci_dev->dev,size,cpu_addr,dma_handle) +#define PCI_DMA_MAP_SINGLE(pci_dev,addr,size,direction) \ + dma_map_single(&pci_dev->dev,addr,size,direction) +#define PCI_DMA_UNMAP_SINGLE(pci_dev,dma_handle,size,direction) \ + dma_unmap_single(&pci_dev->dev,dma_handle,size,direction) +#define MAP_SG(pci_dev, sglist, nents, direction) \ + dma_map_sg(&pci_dev->dev, sglist, nents, direction) +#define UNMAP_SG(pci_dev, sglist, nents, direction) \ + dma_unmap_sg(&pci_dev->dev, sglist, nents, direction) +#define PCI_DMA_MAP_ERROR(dma_addr) dma_mapping_error(dma_addr) + + +#if defined(CONFIG_NET_RADIO) && !defined(CONFIG_WIRELESS_EXT) +#define CONFIG_WIRELESS_EXT +#endif + +#define prepare_wait_condition(task, var, value) \ +do { \ + var = value; \ + task = current; \ + barrier(); \ +} while (0) + +/* Wait in wait_state (e.g., TASK_INTERRUPTIBLE) for condition to + * become true; timeout is either jiffies (> 0) to wait or 0 to wait + * forever. + * When timeout == 0, return value is + * > 0 if condition becomes true, or + * < 0 if signal is pending on the thread. + * When timeout > 0, return value is + * > 0 if condition becomes true before timeout, + * < 0 if signal is pending on the thread before timeout, or + * 0 if timedout (condition may have become true at the same time) + */ + +#define wait_condition(condition, timeout, wait_state) \ +({ \ + long ret = timeout ? timeout : 1; \ + while (1) { \ + if (signal_pending(current)) { \ + ret = -ERESTARTSYS; \ + break; \ + } \ + set_current_state(wait_state); \ + if (condition) { \ + __set_current_state(TASK_RUNNING); \ + break; \ + } \ + if (timeout) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + } else \ + schedule(); \ + } \ + ret; \ +}) + +#ifdef WRAP_WQ + +struct workqueue_struct; + +struct workqueue_thread { + spinlock_t lock; + struct task_struct *task; + struct completion *completion; + char name[16]; + int pid; + /* whether any work_structs pending? <0 implies quit */ + s8 pending; + /* list of work_structs pending */ + struct list_head work_list; +}; + +typedef struct workqueue_struct { + u8 singlethread; + u8 qon; + int num_cpus; + struct workqueue_thread threads[0]; +} workqueue_struct_t; + +typedef struct { + struct list_head list; + void (*func)(void *data); + void *data; + /* whether/on which thread scheduled */ + struct workqueue_thread *thread; +} work_struct_t; + +#define initialize_work(work, pfunc, pdata) \ + do { \ + (work)->func = (pfunc); \ + (work)->data = (pdata); \ + (work)->thread = NULL; \ + } while (0) + +#undef create_singlethread_workqueue +#define create_singlethread_workqueue(name) wrap_create_wq(name, 1, 0) +#undef create_workqueue +#define create_workqueue(name) wrap_create_wq(name, 0, 0) +#undef destroy_workqueue +#define destroy_workqueue wrap_destroy_wq +#undef queue_work +#define queue_work wrap_queue_work +#undef flush_workqueue +#define flush_workqueue wrap_flush_wq + +workqueue_struct_t *wrap_create_wq(const char *name, u8 singlethread, u8 freeze); +void wrap_destroy_wq_on(workqueue_struct_t *workq, int cpu); +void wrap_destroy_wq(workqueue_struct_t *workq); +int wrap_queue_work_on(workqueue_struct_t *workq, work_struct_t *work, + int cpu); +int wrap_queue_work(workqueue_struct_t *workq, work_struct_t *work); +void wrap_cancel_work(work_struct_t *work); +void wrap_flush_wq_on(workqueue_struct_t *workq, int cpu); +void wrap_flush_wq(workqueue_struct_t *workq); +typedef void *worker_param_t; +#define worker_param_data(param, type, member) param + +#else // WRAP_WQ + +typedef struct workqueue_struct workqueue_struct_t; +typedef struct work_struct work_struct_t; + +#if defined(INIT_WORK_NAR) || defined(INIT_DELAYED_WORK_DEFERRABLE) +#define initialize_work(work, func, data) INIT_WORK(work, func) +typedef struct work_struct *worker_param_t; +#define worker_param_data(param, type, member) \ + container_of(param, type, member) +#else +#define initialize_work(work, func, data) INIT_WORK(work, func, data) +typedef void *worker_param_t; +#define worker_param_data(param, type, member) param +#endif // INIT_WORK_NAR + +#endif // WRAP_WQ + +struct nt_thread *wrap_worker_init(workqueue_struct_t *wq); + +#ifdef module_param +#define WRAP_MODULE_PARM_INT(name, perm) module_param(name, int, perm) +#define WRAP_MODULE_PARM_STRING(name, perm) module_param(name, charp, perm) +#else +#define WRAP_MODULE_PARM_INT(name, perm) MODULE_PARM(name, "i") +#define WRAP_MODULE_PARM_STRING(name, perm) MODULE_PARM(name, "s") +#endif + +#ifndef LOCK_PREFIX +#ifdef LOCK +#define LOCK_PREFIX LOCK +#else +#ifdef CONFIG_SMP +#define LOCK_PREFIX "lock ; " +#else +#define LOCK_PREFIX "" +#endif +#endif +#endif + +#ifndef NETDEV_TX_OK +#define NETDEV_TX_OK 0 +#endif + +#ifndef NETDEV_TX_BUSY +#define NETDEV_TX_BUSY 1 +#endif + +#ifndef CHECKSUM_HW +#define CHECKSUM_HW CHECKSUM_PARTIAL +#endif + +#ifndef offset_in_page +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK) +#endif + +#ifndef PMSG_SUSPEND +#ifdef PM_SUSPEND +/* this is not correct - the value of PM_SUSPEND is different from + * PMSG_SUSPEND, but ndiswrapper doesn't care about the value when + * suspending */ +#define PMSG_SUSPEND PM_SUSPEND +#define PSMG_ON PM_ON +#else +typedef u32 pm_message_t; +#define PMSG_SUSPEND 2 +#define PMSG_ON 0 +#endif +#endif + +#ifndef PCI_D0 +#define PCI_D0 0 +#endif + +#ifndef PCI_D3hot +#define PCI_D3hot 3 +#endif + +#ifndef PCI_D3cold +#define PCI_D3cold 3 +#endif + +#ifndef PM_EVENT_SUSPEND +#define PM_EVENT_SUSPEND 2 +#endif + +#if !defined(HAVE_NETDEV_PRIV) +#define netdev_priv(dev) ((dev)->priv) +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) +#define ISR_PT_REGS_PARAM_DECL +#define ISR_PT_REGS_ARG +#else +#define ISR_PT_REGS_PARAM_DECL , struct pt_regs *regs +#define ISR_PT_REGS_ARG , NULL +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,16) +#define for_each_possible_cpu(_cpu) for_each_cpu(_cpu) +#endif + +#ifndef flush_icache_range +#define flush_icache_range(start, end) do { } while (0) +#endif + +#ifndef CHECKSUM_PARTIAL +#define CHECKSUM_PARTIAL CHECKSUM_HW +#endif + +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +#define memcpy_skb(skb, from, length) \ + memcpy(skb_put(skb, length), from, length) + +#ifndef DMA_24BIT_MASK +#define DMA_24BIT_MASK 0x0000000000ffffffULL +#endif + +#ifndef DMA_30BIT_MASK +#define DMA_30BIT_MASK 0x000000003fffffffULL +#endif + +#ifndef DMA_31BIT_MASK +#define DMA_31BIT_MASK 0x000000007fffffffULL +#endif + +#ifndef DMA_32BIT_MASK +#define DMA_32BIT_MASK 0x00000000ffffffffULL +#endif + +#ifndef __GFP_DMA32 +#define __GFP_DMA32 GFP_DMA +#endif + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,22) +#define wrap_kmem_cache_create(name, size, align, flags) \ + kmem_cache_create(name, size, align, flags, NULL, NULL) +#else +#define wrap_kmem_cache_create(name, size, align, flags) \ + kmem_cache_create(name, size, align, flags, NULL) +#endif + +#include "winnt_types.h" +#include "ndiswrapper.h" +#include "pe_linker.h" +#include "wrapmem.h" +#include "lin2win.h" +#include "loader.h" + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +static inline void netif_tx_lock(struct net_device *dev) +{ + spin_lock(&dev->xmit_lock); +} +static inline void netif_tx_unlock(struct net_device *dev) +{ + spin_unlock(&dev->xmit_lock); +} +static inline void netif_tx_lock_bh(struct net_device *dev) +{ + spin_lock_bh(&dev->xmit_lock); +} +static inline void netif_tx_unlock_bh(struct net_device *dev) +{ + spin_unlock_bh(&dev->xmit_lock); +} +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +static inline void netif_poll_enable(struct net_device *dev) +{ +} +static inline void netif_poll_disable(struct net_device *dev) +{ +} +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#define proc_net_root init_net.proc_net +#else +#define proc_net_root proc_net +#endif + +/* TICK is 100ns */ +#define TICKSPERSEC 10000000 +#define TICKSPERMSEC 10000 +#define SECSPERDAY 86400 +#define TICKSPERJIFFY ((TICKSPERSEC + HZ - 1) / HZ) + +#define int_div_round(x, y) (((x) + (y - 1)) / (y)) + +/* 1601 to 1970 is 369 years plus 89 leap days */ +#define SECS_1601_TO_1970 ((369 * 365 + 89) * (u64)SECSPERDAY) +#define TICKS_1601_TO_1970 (SECS_1601_TO_1970 * TICKSPERSEC) + +/* 100ns units to HZ; if sys_time is negative, relative to current + * clock, otherwise from year 1601 */ +#define SYSTEM_TIME_TO_HZ(sys_time) \ + (((sys_time) <= 0) ? \ + int_div_round(((u64)HZ * (-(sys_time))), TICKSPERSEC) : \ + int_div_round(((s64)HZ * ((sys_time) - ticks_1601())), TICKSPERSEC)) + +#define MSEC_TO_HZ(ms) int_div_round((ms * HZ), 1000) +#define USEC_TO_HZ(us) int_div_round((us * HZ), 1000000) + +extern u64 wrap_ticks_to_boot; + +static inline u64 ticks_1601(void) +{ + return wrap_ticks_to_boot + (u64)jiffies * TICKSPERJIFFY; +} + +typedef void (*generic_func)(void); + +struct wrap_export { + const char *name; + generic_func func; +}; + +#ifdef CONFIG_X86_64 + +#define WIN_SYMBOL(name, argc) \ + {#name, (generic_func) win2lin_ ## name ## _ ## argc} +#define WIN_WIN_SYMBOL(name, argc) \ + {#name, (generic_func) win2lin__win_ ## name ## _ ## argc} +#define WIN_FUNC_DECL(name, argc) \ + extern typeof(name) win2lin_ ## name ## _ ## argc; +#define WIN_FUNC_PTR(name, argc) win2lin_ ## name ## _ ## argc + +#else + +#define WIN_SYMBOL(name, argc) {#name, (generic_func)name} +#define WIN_WIN_SYMBOL(name, argc) {#name, (generic_func)_win_ ## name} +#define WIN_FUNC_DECL(name, argc) +#define WIN_FUNC_PTR(name, argc) name + +#endif + +#define WIN_FUNC(name, argc) name +/* map name s to f - if f is different from s */ +#define WIN_SYMBOL_MAP(s, f) + +#define POOL_TAG(A, B, C, D) \ + ((ULONG)((A) + ((B) << 8) + ((C) << 16) + ((D) << 24))) + +struct pe_image { + char name[MAX_DRIVER_NAME_LEN]; + UINT (*entry)(struct driver_object *, struct unicode_string *) wstdcall; + void *image; + int size; + int type; + + IMAGE_NT_HEADERS *nt_hdr; + IMAGE_OPTIONAL_HEADER *opt_hdr; +}; + +struct ndis_mp_block; + +struct wrap_timer { + struct nt_slist slist; + struct timer_list timer; + struct nt_timer *nt_timer; + long repeat; +#ifdef TIMER_DEBUG + unsigned long wrap_timer_magic; +#endif +}; + +struct ntos_work_item { + struct nt_list list; + void *arg1; + void *arg2; + NTOS_WORK_FUNC func; +}; + +struct wrap_device_setting { + struct nt_list list; + char name[MAX_SETTING_NAME_LEN]; + char value[MAX_SETTING_VALUE_LEN]; + void *encoded; +}; + +struct wrap_bin_file { + char name[MAX_DRIVER_NAME_LEN]; + size_t size; + void *data; +}; + +#define WRAP_DRIVER_CLIENT_ID 1 + +struct wrap_driver { + struct nt_list list; + struct driver_object *drv_obj; + char name[MAX_DRIVER_NAME_LEN]; + char version[MAX_SETTING_VALUE_LEN]; + unsigned short num_pe_images; + struct pe_image pe_images[MAX_DRIVER_PE_IMAGES]; + unsigned short num_bin_files; + struct wrap_bin_file *bin_files; + struct nt_list wrap_devices; + struct nt_list settings; + int dev_type; + struct ndis_driver *ndis_driver; +}; + +enum hw_status { + HW_INITIALIZED = 1, HW_SUSPENDED, HW_HALTED, HW_PRESENT, +}; + +struct wrap_device { + /* first part is (de)initialized once by loader */ + struct nt_list list; + int dev_bus; + int vendor; + int device; + int subvendor; + int subdevice; + char conf_file_name[MAX_DRIVER_NAME_LEN]; + char driver_name[MAX_DRIVER_NAME_LEN]; + struct wrap_driver *driver; + struct nt_list settings; + + /* rest should be (de)initialized when a device is + * (un)plugged */ + struct cm_resource_list *resource_list; + unsigned long hw_status; + struct device_object *pdo; + union { + struct { + struct pci_dev *pdev; + enum device_power_state wake_state; + } pci; + struct { + struct usb_device *udev; + struct usb_interface *intf; + int num_alloc_urbs; + struct nt_list wrap_urb_list; + } usb; + }; + union { + struct ndis_device *wnd; + }; +}; + +#define wrap_is_pci_bus(dev_bus) \ + (WRAP_BUS(dev_bus) == WRAP_PCI_BUS || \ + WRAP_BUS(dev_bus) == WRAP_PCMCIA_BUS) +#ifdef ENABLE_USB +/* earlier versions of ndiswrapper used 0 as USB_BUS */ +#define wrap_is_usb_bus(dev_bus) \ + (WRAP_BUS(dev_bus) == WRAP_USB_BUS || \ + WRAP_BUS(dev_bus) == WRAP_INTERNAL_BUS) +#else +#define wrap_is_usb_bus(dev_bus) 0 +#endif +#define wrap_is_bluetooth_device(dev_bus) \ + (WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE1 || \ + WRAP_DEVICE(dev_bus) == WRAP_BLUETOOTH_DEVICE2) + +extern workqueue_struct_t *ntos_wq; +#define schedule_ntos_work(work_struct) queue_work(ntos_wq, work_struct) +#define schedule_work(work_struct) queue_work(ntos_wq, work_struct) + +extern workqueue_struct_t *ndis_wq; +#define schedule_ndis_work(work_struct) queue_work(ndis_wq, work_struct) + +extern workqueue_struct_t *wrapndis_wq; +#define schedule_wrapndis_work(work_struct) queue_work(wrapndis_wq, work_struct) + +#define atomic_unary_op(var, size, oper) \ +do { \ + if (size == 1) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "b %b0\n\t" : "+m" (var)); \ + else if (size == 2) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "w %w0\n\t" : "+m" (var)); \ + else if (size == 4) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "l %0\n\t" : "+m" (var)); \ + else if (size == 8) \ + __asm__ __volatile__( \ + LOCK_PREFIX oper "q %q0\n\t" : "+m" (var)); \ + else { \ + extern void _invalid_op_size_(void); \ + _invalid_op_size_(); \ + } \ +} while (0) + +#define atomic_inc_var_size(var, size) atomic_unary_op(var, size, "inc") + +#define atomic_inc_var(var) atomic_inc_var_size(var, sizeof(var)) + +#define atomic_dec_var_size(var, size) atomic_unary_op(var, size, "dec") + +#define atomic_dec_var(var) atomic_dec_var_size(var, sizeof(var)) + +#define pre_atomic_add(var, i) \ +({ \ + typeof(var) pre; \ + __asm__ __volatile__( \ + LOCK_PREFIX "xadd %0, %1\n\t" \ + : "=r"(pre), "+m"(var) \ + : "0"(i)); \ + pre; \ +}) + +#define post_atomic_add(var, i) (pre_atomic_add(var, i) + i) + +#ifndef in_atomic +#define in_atomic() in_interrupt() +#endif + +#ifndef preempt_enable_no_resched +#define preempt_enable_no_resched() preempt_enable() +#endif + +//#define DEBUG_IRQL 1 + +#ifdef DEBUG_IRQL +#define assert_irql(cond) \ +do { \ + KIRQL _irql_ = current_irql(); \ + if (!(cond)) { \ + WARNING("assertion '%s' failed: %d", #cond, _irql_); \ + DBG_BLOCK(4) { \ + dump_stack(); \ + } \ + } \ +} while (0) +#else +#define assert_irql(cond) do { } while (0) +#endif + +/* When preempt is enabled, we should preempt_disable to raise IRQL to + * DISPATCH_LEVEL, to be consistent with the semantics. However, using + * a mutex instead, so that only ndiswrapper threads run one at a time + * on a processor when at DISPATCH_LEVEL seems to be enough. So that + * is what we will use until we learn otherwise. If + * preempt_(en|dis)able is required for some reason, comment out + * following #define. */ + +#define WRAP_PREEMPT 1 + +#if !defined(CONFIG_PREEMPT) || defined(CONFIG_PREEMPT_RT) +#ifndef WRAP_PREEMPT +#define WRAP_PREEMPT 1 +#endif +#endif + +//#undef WRAP_PREEMPT + +#ifdef WRAP_PREEMPT + +typedef struct { + int count; + struct mutex lock; +#ifdef CONFIG_SMP + typeof(current->cpus_allowed) cpus_allowed; +#endif + struct task_struct *task; +} irql_info_t; + +DECLARE_PER_CPU(irql_info_t, irql_info); + +static inline KIRQL raise_irql(KIRQL newirql) +{ + irql_info_t *info; + + assert(newirql == DISPATCH_LEVEL); + info = &get_cpu_var(irql_info); + if (info->task == current) { + assert(info->count > 0); + assert(mutex_is_locked(&info->lock)); +#if defined(CONFIG_SMP) && defined(DEBUG) + do { + cpumask_t cpumask; + cpumask = cpumask_of_cpu(smp_processor_id()); + cpus_xor(cpumask, cpumask, current->cpus_allowed); + assert(cpus_empty(cpumask)); + } while (0); +#endif + info->count++; + put_cpu_var(irql_info); + return DISPATCH_LEVEL; + } + /* TODO: is this enough to pin down to current cpu? */ +#ifdef CONFIG_SMP + assert(task_cpu(current) == smp_processor_id()); + info->cpus_allowed = current->cpus_allowed; + current->cpus_allowed = cpumask_of_cpu(smp_processor_id()); +#endif + put_cpu_var(irql_info); + mutex_lock(&info->lock); + assert(info->count == 0); + assert(info->task == NULL); + info->count = 1; + info->task = current; + return PASSIVE_LEVEL; +} + +static inline void lower_irql(KIRQL oldirql) +{ + irql_info_t *info; + + assert(oldirql <= DISPATCH_LEVEL); + info = &get_cpu_var(irql_info); + assert(info->task == current); + assert(mutex_is_locked(&info->lock)); + assert(info->count > 0); + if (--info->count == 0) { + info->task = NULL; +#ifdef CONFIG_SMP + current->cpus_allowed = info->cpus_allowed; +#endif + mutex_unlock(&info->lock); + } + put_cpu_var(irql_info); +} + +static inline KIRQL current_irql(void) +{ + int count; + if (in_irq() || irqs_disabled()) + EXIT4(return DIRQL); + if (in_atomic() || in_interrupt()) + EXIT4(return SOFT_IRQL); + count = get_cpu_var(irql_info).count; + put_cpu_var(irql_info); + if (count) + EXIT6(return DISPATCH_LEVEL); + else + EXIT6(return PASSIVE_LEVEL); +} + +#else + +static inline KIRQL current_irql(void) +{ + if (in_irq() || irqs_disabled()) + EXIT4(return DIRQL); + if (in_interrupt()) + EXIT4(return SOFT_IRQL); + if (in_atomic()) + EXIT6(return DISPATCH_LEVEL); + else + EXIT6(return PASSIVE_LEVEL); +} + +static inline KIRQL raise_irql(KIRQL newirql) +{ + KIRQL ret = in_atomic() ? DISPATCH_LEVEL : PASSIVE_LEVEL; + assert(newirql == DISPATCH_LEVEL); + assert(current_irql() <= DISPATCH_LEVEL); + preempt_disable(); + return ret; +} + +static inline void lower_irql(KIRQL oldirql) +{ + assert(current_irql() == DISPATCH_LEVEL); + preempt_enable(); +} + +#endif + +#define irql_gfp() (in_atomic() ? GFP_ATOMIC : GFP_KERNEL) + +/* Windows spinlocks are of type ULONG_PTR which is not big enough to + * store Linux spinlocks; so we implement Windows spinlocks using + * ULONG_PTR space with our own functions/macros */ + +/* Windows seems to use 0 for unlocked state of spinlock - if Linux + * convention of 1 for unlocked state is used, at least prism54 driver + * crashes */ + +#define NT_SPIN_LOCK_UNLOCKED 0 +#define NT_SPIN_LOCK_LOCKED 1 + +static inline void nt_spin_lock_init(NT_SPIN_LOCK *lock) +{ + *lock = NT_SPIN_LOCK_UNLOCKED; +} + +#ifdef CONFIG_SMP + +static inline void nt_spin_lock(NT_SPIN_LOCK *lock) +{ + __asm__ __volatile__( + "1:\t" + " xchgl %1, %0\n\t" + " testl %1, %1\n\t" + " jz 3f\n" + "2:\t" + " rep; nop\n\t" + " cmpl %2, %0\n\t" + " je 1b\n\t" + " jmp 2b\n" + "3:\n\t" + : "+m" (*lock) + : "r" (NT_SPIN_LOCK_LOCKED), "i" (NT_SPIN_LOCK_UNLOCKED)); +} + +static inline void nt_spin_unlock(NT_SPIN_LOCK *lock) +{ + *lock = NT_SPIN_LOCK_UNLOCKED; +} + +#else // CONFIG_SMP + +#define nt_spin_lock(lock) do { } while (0) + +#define nt_spin_unlock(lock) do { } while (0) + +#endif // CONFIG_SMP + +/* When kernel would've disabled preempt (e.g., in interrupt + * handlers), we need to fake preempt so driver thinks it is running + * at right IRQL */ + +/* raise IRQL to given (higher) IRQL if necessary before locking */ +static inline KIRQL nt_spin_lock_irql(NT_SPIN_LOCK *lock, KIRQL newirql) +{ + KIRQL oldirql = raise_irql(newirql); + nt_spin_lock(lock); + return oldirql; +} + +/* lower IRQL to given (lower) IRQL if necessary after unlocking */ +static inline void nt_spin_unlock_irql(NT_SPIN_LOCK *lock, KIRQL oldirql) +{ + nt_spin_unlock(lock); + lower_irql(oldirql); +} + +#define nt_spin_lock_irqsave(lock, flags) \ +do { \ + local_irq_save(flags); \ + preempt_disable(); \ + nt_spin_lock(lock); \ +} while (0) + +#define nt_spin_unlock_irqrestore(lock, flags) \ +do { \ + nt_spin_unlock(lock); \ + preempt_enable_no_resched(); \ + local_irq_restore(flags); \ + preempt_check_resched(); \ +} while (0) + +static inline ULONG SPAN_PAGES(void *ptr, SIZE_T length) +{ + return PAGE_ALIGN(((unsigned long)ptr & (PAGE_SIZE - 1)) + length) + >> PAGE_SHIFT; +} + +#ifdef CONFIG_X86_64 + +/* TODO: can these be implemented without using spinlock? */ + +static inline struct nt_slist *PushEntrySList(nt_slist_header *head, + struct nt_slist *entry, + NT_SPIN_LOCK *lock) +{ + KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); + entry->next = head->next; + head->next = entry; + head->depth++; + nt_spin_unlock_irql(lock, irql); + TRACE4("%p, %p, %p", head, entry, entry->next); + return entry->next; +} + +static inline struct nt_slist *PopEntrySList(nt_slist_header *head, + NT_SPIN_LOCK *lock) +{ + struct nt_slist *entry; + KIRQL irql = nt_spin_lock_irql(lock, DISPATCH_LEVEL); + entry = head->next; + if (entry) { + head->next = entry->next; + head->depth--; + } + nt_spin_unlock_irql(lock, irql); + TRACE4("%p, %p", head, entry); + return entry; +} + +#else + +#define u64_low_32(x) ((u32)x) +#define u64_high_32(x) ((u32)(x >> 32)) + +static inline u64 cmpxchg8b(volatile u64 *ptr, u64 old, u64 new) +{ + u64 prev; + + __asm__ __volatile__( + "\n" + LOCK_PREFIX "cmpxchg8b %0\n" + : "+m" (*ptr), "=A" (prev) + : "A" (old), "b" (u64_low_32(new)), "c" (u64_high_32(new))); + return prev; +} + +/* slist routines below update slist atomically - no need for + * spinlocks */ + +static inline struct nt_slist *PushEntrySList(nt_slist_header *head, + struct nt_slist *entry, + NT_SPIN_LOCK *lock) +{ + nt_slist_header old, new; + do { + old.align = head->align; + entry->next = old.next; + new.next = entry; + new.depth = old.depth + 1; + } while (cmpxchg8b(&head->align, old.align, new.align) != old.align); + TRACE4("%p, %p, %p", head, entry, old.next); + return old.next; +} + +static inline struct nt_slist *PopEntrySList(nt_slist_header *head, + NT_SPIN_LOCK *lock) +{ + struct nt_slist *entry; + nt_slist_header old, new; + do { + old.align = head->align; + entry = old.next; + if (!entry) + break; + new.next = entry->next; + new.depth = old.depth - 1; + } while (cmpxchg8b(&head->align, old.align, new.align) != old.align); + TRACE4("%p, %p", head, entry); + return entry; +} + +#endif + +#define sleep_hz(n) \ +do { \ + set_current_state(TASK_INTERRUPTIBLE); \ + schedule_timeout(n); \ +} while (0) + +int ntoskernel_init(void); +void ntoskernel_exit(void); +int ntoskernel_init_device(struct wrap_device *wd); +void ntoskernel_exit_device(struct wrap_device *wd); +void *allocate_object(ULONG size, enum common_object_type type, + struct unicode_string *name); +void free_object(void *object); + +int usb_init(void); +void usb_exit(void); +int usb_init_device(struct wrap_device *wd); +void usb_exit_device(struct wrap_device *wd); +void usb_cancel_pending_urbs(void); + +int crt_init(void); +void crt_exit(void); +int rtl_init(void); +void rtl_exit(void); +int wrap_procfs_init(void); +void wrap_procfs_remove(void); + +int link_pe_images(struct pe_image *pe_image, unsigned short n); + +int stricmp(const char *s1, const char *s2); +void dump_bytes(const char *name, const u8 *from, int len); +struct mdl *allocate_init_mdl(void *virt, ULONG length); +void free_mdl(struct mdl *mdl); +struct driver_object *find_bus_driver(const char *name); +void free_custom_extensions(struct driver_extension *drv_obj_ext); +struct nt_thread *get_current_nt_thread(void); +u64 ticks_1601(void); +int schedule_ntos_work_item(NTOS_WORK_FUNC func, void *arg1, void *arg2); +void wrap_init_timer(struct nt_timer *nt_timer, enum timer_type type, + struct ndis_mp_block *nmb); +BOOLEAN wrap_set_timer(struct nt_timer *nt_timer, unsigned long expires_hz, + unsigned long repeat_hz, struct kdpc *kdpc); + +LONG InterlockedDecrement(LONG volatile *val) wfastcall; +LONG InterlockedIncrement(LONG volatile *val) wfastcall; +struct nt_list *ExInterlockedInsertHeadList + (struct nt_list *head, struct nt_list *entry, + NT_SPIN_LOCK *lock) wfastcall; +struct nt_list *ExInterlockedInsertTailList + (struct nt_list *head, struct nt_list *entry, + NT_SPIN_LOCK *lock) wfastcall; +struct nt_list *ExInterlockedRemoveHeadList + (struct nt_list *head, NT_SPIN_LOCK *lock) wfastcall; +NTSTATUS IofCallDriver(struct device_object *dev_obj, struct irp *irp) wfastcall; +KIRQL KfRaiseIrql(KIRQL newirql) wfastcall; +void KfLowerIrql(KIRQL oldirql) wfastcall; +KIRQL KfAcquireSpinLock(NT_SPIN_LOCK *lock) wfastcall; +void KfReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wfastcall; +void IofCompleteRequest(struct irp *irp, CHAR prio_boost) wfastcall; +void KefReleaseSpinLockFromDpcLevel(NT_SPIN_LOCK *lock) wfastcall; + +LONG ObfReferenceObject(void *object) wfastcall; +void ObfDereferenceObject(void *object) wfastcall; + +#define ObReferenceObject(object) ObfReferenceObject(object) +#define ObDereferenceObject(object) ObfDereferenceObject(object) + +void WRITE_PORT_UCHAR(ULONG_PTR port, UCHAR value) wstdcall; +UCHAR READ_PORT_UCHAR(ULONG_PTR port) wstdcall; + +#undef ExAllocatePoolWithTag +void *ExAllocatePoolWithTag(enum pool_type pool_type, SIZE_T size, + ULONG tag) wstdcall; +#if defined(ALLOC_DEBUG) && ALLOC_DEBUG > 1 +#define ExAllocatePoolWithTag(pool_type, size, tag) \ + wrap_ExAllocatePoolWithTag(pool_type, size, tag, __FILE__, __LINE__) +#endif + +void ExFreePool(void *p) wstdcall; +ULONG MmSizeOfMdl(void *base, ULONG length) wstdcall; +void __iomem *MmMapIoSpace(PHYSICAL_ADDRESS phys_addr, SIZE_T size, + enum memory_caching_type cache) wstdcall; +void MmUnmapIoSpace(void __iomem *addr, SIZE_T size) wstdcall; +void MmProbeAndLockPages(struct mdl *mdl, KPROCESSOR_MODE access_mode, + enum lock_operation operation) wstdcall; +void MmUnlockPages(struct mdl *mdl) wstdcall; +void KeInitializeEvent(struct nt_event *nt_event, + enum event_type type, BOOLEAN state) wstdcall; +LONG KeSetEvent(struct nt_event *nt_event, KPRIORITY incr, + BOOLEAN wait) wstdcall; +LONG KeResetEvent(struct nt_event *nt_event) wstdcall; +void KeClearEvent(struct nt_event *nt_event) wstdcall; +void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall; +BOOLEAN queue_kdpc(struct kdpc *kdpc); +BOOLEAN dequeue_kdpc(struct kdpc *kdpc); + +void KeFlushQueuedDpcs(void) wstdcall; +NTSTATUS IoConnectInterrupt(struct kinterrupt **kinterrupt, + PKSERVICE_ROUTINE service_routine, + void *service_context, NT_SPIN_LOCK *lock, + ULONG vector, KIRQL irql, KIRQL synch_irql, + enum kinterrupt_mode interrupt_mode, + BOOLEAN shareable, KAFFINITY processor_enable_mask, + BOOLEAN floating_save) wstdcall; +void IoDisconnectInterrupt(struct kinterrupt *interrupt) wstdcall; +BOOLEAN KeSynchronizeExecution(struct kinterrupt *interrupt, + PKSYNCHRONIZE_ROUTINE synch_routine, + void *ctx) wstdcall; + +NTSTATUS KeWaitForSingleObject(void *object, KWAIT_REASON reason, + KPROCESSOR_MODE waitmode, BOOLEAN alertable, + LARGE_INTEGER *timeout) wstdcall; +struct mdl *IoAllocateMdl(void *virt, ULONG length, BOOLEAN second_buf, + BOOLEAN charge_quota, struct irp *irp) wstdcall; +void MmBuildMdlForNonPagedPool(struct mdl *mdl) wstdcall; +void IoFreeMdl(struct mdl *mdl) wstdcall; +NTSTATUS IoCreateDevice(struct driver_object *driver, ULONG dev_ext_length, + struct unicode_string *dev_name, DEVICE_TYPE dev_type, + ULONG dev_chars, BOOLEAN exclusive, + struct device_object **dev_obj) wstdcall; +NTSTATUS IoCreateSymbolicLink(struct unicode_string *link, + struct unicode_string *dev_name) wstdcall; +void IoDeleteDevice(struct device_object *dev) wstdcall; +void IoDetachDevice(struct device_object *topdev) wstdcall; +struct device_object *IoGetAttachedDevice(struct device_object *dev) wstdcall; +struct device_object *IoGetAttachedDeviceReference + (struct device_object *dev) wstdcall; +NTSTATUS IoAllocateDriverObjectExtension + (struct driver_object *drv_obj, void *client_id, ULONG extlen, + void **ext) wstdcall; +void *IoGetDriverObjectExtension(struct driver_object *drv, + void *client_id) wstdcall; +struct device_object *IoAttachDeviceToDeviceStack + (struct device_object *src, struct device_object *dst) wstdcall; +void KeInitializeEvent(struct nt_event *nt_event, enum event_type type, + BOOLEAN state) wstdcall; +struct irp *IoAllocateIrp(char stack_count, BOOLEAN charge_quota) wstdcall; +void IoFreeIrp(struct irp *irp) wstdcall; +BOOLEAN IoCancelIrp(struct irp *irp) wstdcall; +struct irp *IoBuildSynchronousFsdRequest + (ULONG major_func, struct device_object *dev_obj, void *buf, + ULONG length, LARGE_INTEGER *offset, struct nt_event *event, + struct io_status_block *status) wstdcall; +struct irp *IoBuildAsynchronousFsdRequest + (ULONG major_func, struct device_object *dev_obj, void *buf, + ULONG length, LARGE_INTEGER *offset, + struct io_status_block *status) wstdcall; +NTSTATUS PoCallDriver(struct device_object *dev_obj, struct irp *irp) wstdcall; + +NTSTATUS IoPassIrpDown(struct device_object *dev_obj, struct irp *irp) wstdcall; +WIN_FUNC_DECL(IoPassIrpDown,2); +NTSTATUS IoSyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) wstdcall; +NTSTATUS IoAsyncForwardIrp(struct device_object *dev_obj, + struct irp *irp) wstdcall; +NTSTATUS IoInvalidDeviceRequest(struct device_object *dev_obj, + struct irp *irp) wstdcall; + +KIRQL KeGetCurrentIrql(void) wstdcall; +void KeInitializeSpinLock(NT_SPIN_LOCK *lock) wstdcall; +void KeAcquireSpinLock(NT_SPIN_LOCK *lock, KIRQL *irql) wstdcall; +void KeReleaseSpinLock(NT_SPIN_LOCK *lock, KIRQL oldirql) wstdcall; +KIRQL KeAcquireSpinLockRaiseToDpc(NT_SPIN_LOCK *lock) wstdcall; + +void IoAcquireCancelSpinLock(KIRQL *irql) wstdcall; +void IoReleaseCancelSpinLock(KIRQL irql) wstdcall; + +void RtlCopyMemory(void *dst, const void *src, SIZE_T length) wstdcall; +NTSTATUS RtlUnicodeStringToAnsiString + (struct ansi_string *dst, const struct unicode_string *src, + BOOLEAN dup) wstdcall; +NTSTATUS RtlAnsiStringToUnicodeString + (struct unicode_string *dst, const struct ansi_string *src, + BOOLEAN dup) wstdcall; +void RtlInitAnsiString(struct ansi_string *dst, const char *src) wstdcall; +void RtlInitString(struct ansi_string *dst, const char *src) wstdcall; +void RtlInitUnicodeString(struct unicode_string *dest, + const wchar_t *src) wstdcall; +void RtlFreeUnicodeString(struct unicode_string *string) wstdcall; +void RtlFreeAnsiString(struct ansi_string *string) wstdcall; +LONG RtlCompareUnicodeString(const struct unicode_string *s1, + const struct unicode_string *s2, + BOOLEAN case_insensitive) wstdcall; +void RtlCopyUnicodeString(struct unicode_string *dst, + struct unicode_string *src) wstdcall; +NTSTATUS RtlUpcaseUnicodeString(struct unicode_string *dst, + struct unicode_string *src, + BOOLEAN alloc) wstdcall; +void KeInitializeTimer(struct nt_timer *nt_timer) wstdcall; +void KeInitializeTimerEx(struct nt_timer *nt_timer, + enum timer_type type) wstdcall; +BOOLEAN KeSetTimerEx(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + LONG period_ms, struct kdpc *kdpc) wstdcall; +BOOLEAN KeSetTimer(struct nt_timer *nt_timer, LARGE_INTEGER duetime_ticks, + struct kdpc *kdpc) wstdcall; +BOOLEAN KeCancelTimer(struct nt_timer *nt_timer) wstdcall; +void KeInitializeDpc(struct kdpc *kdpc, void *func, void *ctx) wstdcall; +struct nt_thread *KeGetCurrentThread(void) wstdcall; +NTSTATUS ObReferenceObjectByHandle(void *handle, ACCESS_MASK desired_access, + void *obj_type, KPROCESSOR_MODE access_mode, + void **object, void *handle_info) wstdcall; + +void adjust_user_shared_data_addr(char *driver, unsigned long length); + +extern spinlock_t ntoskernel_lock; +extern spinlock_t irp_cancel_lock; +extern struct nt_list object_list; +#ifdef CONFIG_X86_64 +extern struct kuser_shared_data kuser_shared_data; +#endif + +#define IoCompleteRequest(irp, prio) IofCompleteRequest(irp, prio) +#define IoCallDriver(dev, irp) IofCallDriver(dev, irp) + +#if defined(IO_DEBUG) +#define DUMP_IRP(_irp) \ +do { \ + struct io_stack_location *_irp_sl; \ + _irp_sl = IoGetCurrentIrpStackLocation(_irp); \ + IOTRACE("irp: %p, stack size: %d, cl: %d, sl: %p, dev_obj: %p, " \ + "mj_fn: %d, minor_fn: %d, nt_urb: %p, event: %p", \ + _irp, _irp->stack_count, (_irp)->current_location, \ + _irp_sl, _irp_sl->dev_obj, _irp_sl->major_fn, \ + _irp_sl->minor_fn, IRP_URB(_irp), \ + (_irp)->user_event); \ +} while (0) +#else +#define DUMP_IRP(_irp) do { } while (0) +#endif + +#endif // _NTOSKERNEL_H_ --- linux-2.6.28.orig/ubuntu/ndiswrapper/loader.c +++ linux-2.6.28/ubuntu/ndiswrapper/loader.c @@ -0,0 +1,877 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ndis.h" +#include "loader.h" +#include "wrapndis.h" +#include "pnp.h" + +#include +#include +#include +#include + +/* + Network adapter: ClassGuid = {4d36e972-e325-11ce-bfc1-08002be10318} + Network client: ClassGuid = {4d36e973-e325-11ce-bfc1-08002be10318} + PCMCIA adapter: ClassGuid = {4d36e977-e325-11ce-bfc1-08002be10318} + USB: ClassGuid = {36fc9e60-c465-11cf-8056-444553540000} +*/ + +/* the indices used here must match macros WRAP_NDIS_DEVICE etc. */ +static struct guid class_guids[] = { + /* Network */ + {0x4d36e972, 0xe325, 0x11ce, }, + /* USB WDM */ + {0x36fc9e60, 0xc465, 0x11cf, }, + /* Bluetooth */ + {0xe0cbf06c, 0xcd8b, 0x4647, }, + /* ivtcorporatino.com's bluetooth device claims this is + * bluetooth guid */ + {0xf12d3cf8, 0xb11d, 0x457e, }, +}; + +struct semaphore loader_mutex; +static struct completion loader_complete; + +static struct nt_list wrap_devices; +static struct nt_list wrap_drivers; + +static int wrap_device_type(int data1) +{ + int i; + for (i = 0; i < sizeof(class_guids) / sizeof(class_guids[0]); i++) + if (data1 == class_guids[i].data1) + return i; + ERROR("unknown device: 0x%x\n", data1); + return -1; +} + +/* load driver for given device, if not already loaded */ +struct wrap_driver *load_wrap_driver(struct wrap_device *wd) +{ + int ret; + struct nt_list *cur; + struct wrap_driver *wrap_driver; + + ENTER1("device: %04X:%04X:%04X:%04X", wd->vendor, wd->device, + wd->subvendor, wd->subdevice); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + wrap_driver = NULL; + nt_list_for_each(cur, &wrap_drivers) { + wrap_driver = container_of(cur, struct wrap_driver, list); + if (!stricmp(wrap_driver->name, wd->driver_name)) { + TRACE1("driver %s already loaded", wrap_driver->name); + break; + } else + wrap_driver = NULL; + } + up(&loader_mutex); + + if (!wrap_driver) { + char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DRIVER, +#if defined(DEBUG) && DEBUG >= 1 + "1", +#else + "0", +#endif + UTILS_VERSION, wd->driver_name, + wd->conf_file_name, NULL}; + char *env[] = {NULL}; + + TRACE1("loading driver %s", wd->driver_name); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + INIT_COMPLETION(loader_complete); + ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1); + if (ret) { + up(&loader_mutex); + ERROR("couldn't load driver %s; check system log " + "for messages from 'loadndisdriver'", + wd->driver_name); + EXIT1(return NULL); + } + wait_for_completion(&loader_complete); + TRACE1("%s", wd->driver_name); + wrap_driver = NULL; + nt_list_for_each(cur, &wrap_drivers) { + wrap_driver = container_of(cur, struct wrap_driver, + list); + if (!stricmp(wrap_driver->name, wd->driver_name)) { + wd->driver = wrap_driver; + break; + } else + wrap_driver = NULL; + } + up(&loader_mutex); + if (wrap_driver) + TRACE1("driver %s is loaded", wrap_driver->name); + else + ERROR("couldn't load driver '%s'", wd->driver_name); + } + EXIT1(return wrap_driver); +} + +/* load the driver files from userspace. */ +static int load_sys_files(struct wrap_driver *driver, + struct load_driver *load_driver) +{ + int i, err; + + TRACE1("num_pe_images = %d", load_driver->num_sys_files); + TRACE1("loading driver: %s", load_driver->name); + strncpy(driver->name, load_driver->name, sizeof(driver->name)); + driver->name[sizeof(driver->name)-1] = 0; + TRACE1("driver: %s", driver->name); + err = 0; + driver->num_pe_images = 0; + for (i = 0; i < load_driver->num_sys_files; i++) { + struct pe_image *pe_image; + pe_image = &driver->pe_images[driver->num_pe_images]; + + strncpy(pe_image->name, load_driver->sys_files[i].name, + sizeof(pe_image->name)); + pe_image->name[sizeof(pe_image->name)-1] = 0; + TRACE1("image size: %lu bytes", + (unsigned long)load_driver->sys_files[i].size); + +#ifdef CONFIG_X86_64 +#ifdef PAGE_KERNEL_EXECUTABLE + pe_image->image = + __vmalloc(load_driver->sys_files[i].size, + GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXECUTABLE); +#elif defined PAGE_KERNEL_EXEC + pe_image->image = + __vmalloc(load_driver->sys_files[i].size, + GFP_KERNEL | __GFP_HIGHMEM, + PAGE_KERNEL_EXEC); +#else +#error x86_64 should have either PAGE_KERNEL_EXECUTABLE or PAGE_KERNEL_EXEC +#endif +#else + /* hate to play with kernel macros, but PAGE_KERNEL_EXEC is + * not available to modules! */ +#ifdef cpu_has_nx + if (cpu_has_nx) + pe_image->image = + __vmalloc(load_driver->sys_files[i].size, + GFP_KERNEL | __GFP_HIGHMEM, + __pgprot(__PAGE_KERNEL & ~_PAGE_NX)); + else + pe_image->image = + vmalloc(load_driver->sys_files[i].size); +#else + pe_image->image = + vmalloc(load_driver->sys_files[i].size); +#endif +#endif + if (!pe_image->image) { + ERROR("couldn't allocate memory"); + err = -ENOMEM; + break; + } + TRACE1("image is at %p", pe_image->image); + + if (copy_from_user(pe_image->image, + load_driver->sys_files[i].data, + load_driver->sys_files[i].size)) { + ERROR("couldn't load file %s", + load_driver->sys_files[i].name); + err = -EFAULT; + break; + } + pe_image->size = load_driver->sys_files[i].size; + driver->num_pe_images++; + } + + if (!err && link_pe_images(driver->pe_images, driver->num_pe_images)) { + ERROR("couldn't prepare driver '%s'", load_driver->name); + err = -EINVAL; + } + + if (driver->num_pe_images < load_driver->num_sys_files || err) { + for (i = 0; i < driver->num_pe_images; i++) + if (driver->pe_images[i].image) + vfree(driver->pe_images[i].image); + driver->num_pe_images = 0; + EXIT1(return err); + } else + EXIT1(return 0); +} + +struct wrap_bin_file *get_bin_file(char *bin_file_name) +{ + int i = 0; + struct wrap_driver *driver, *cur; + + ENTER1("%s", bin_file_name); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + driver = NULL; + nt_list_for_each_entry(cur, &wrap_drivers, list) { + for (i = 0; i < cur->num_bin_files; i++) + if (!stricmp(cur->bin_files[i].name, bin_file_name)) { + driver = cur; + break; + } + if (driver) + break; + } + up(&loader_mutex); + if (!driver) { + TRACE1("coudln't find bin file '%s'", bin_file_name); + return NULL; + } + + if (!driver->bin_files[i].data) { + char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_BIN_FILE, +#if defined(DEBUG) && DEBUG >= 1 + "1", +#else + "0", +#endif + UTILS_VERSION, driver->name, + driver->bin_files[i].name, NULL}; + char *env[] = {NULL}; + int ret; + + TRACE1("loading bin file %s/%s", driver->name, + driver->bin_files[i].name); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + INIT_COMPLETION(loader_complete); + ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1); + if (ret) { + up(&loader_mutex); + ERROR("couldn't load file %s/%s; check system log " + "for messages from 'loadndisdriver' (%d)", + driver->name, driver->bin_files[i].name, ret); + EXIT1(return NULL); + } + wait_for_completion(&loader_complete); + up(&loader_mutex); + if (!driver->bin_files[i].data) { + WARNING("couldn't load binary file %s", + driver->bin_files[i].name); + EXIT1(return NULL); + } + } + EXIT2(return &(driver->bin_files[i])); +} + +/* called with loader_mutex down */ +static int add_bin_file(struct load_driver_file *driver_file) +{ + struct wrap_driver *driver, *cur; + struct wrap_bin_file *bin_file; + int i = 0; + + driver = NULL; + nt_list_for_each_entry(cur, &wrap_drivers, list) { + for (i = 0; i < cur->num_bin_files; i++) + if (!stricmp(cur->bin_files[i].name, + driver_file->name)) { + driver = cur; + break; + } + if (driver) + break; + } + if (!driver) { + ERROR("couldn't find %s", driver_file->name); + return -EINVAL; + } + bin_file = &driver->bin_files[i]; + strncpy(bin_file->name, driver_file->name, sizeof(bin_file->name)); + bin_file->name[sizeof(bin_file->name)-1] = 0; + bin_file->data = vmalloc(driver_file->size); + if (!bin_file->data) { + ERROR("couldn't allocate memory"); + return -ENOMEM; + } + bin_file->size = driver_file->size; + if (copy_from_user(bin_file->data, driver_file->data, bin_file->size)) { + ERROR("couldn't copy data"); + free_bin_file(bin_file); + return -EFAULT; + } + return 0; +} + +void free_bin_file(struct wrap_bin_file *bin_file) +{ + TRACE2("unloading %s", bin_file->name); + if (bin_file->data) + vfree(bin_file->data); + bin_file->data = NULL; + bin_file->size = 0; + EXIT2(return); +} + +/* load firmware files from userspace */ +static int load_bin_files_info(struct wrap_driver *driver, + struct load_driver *load_driver) +{ + struct wrap_bin_file *bin_files; + int i; + + ENTER1("%s, %d", load_driver->name, load_driver->num_bin_files); + driver->num_bin_files = 0; + driver->bin_files = NULL; + if (load_driver->num_bin_files == 0) + EXIT1(return 0); + bin_files = kzalloc(load_driver->num_bin_files * sizeof(*bin_files), + GFP_KERNEL); + if (!bin_files) { + ERROR("couldn't allocate memory"); + EXIT1(return -ENOMEM); + } + + for (i = 0; i < load_driver->num_bin_files; i++) { + strncpy(bin_files[i].name, load_driver->bin_files[i].name, + sizeof(bin_files[i].name)); + bin_files[i].name[sizeof(bin_files[i].name)-1] = 0; + TRACE2("loaded bin file %s", bin_files[i].name); + } + driver->num_bin_files = load_driver->num_bin_files; + driver->bin_files = bin_files; + EXIT1(return 0); +} + +/* load settnigs for a device. called with loader_mutex down */ +static int load_settings(struct wrap_driver *wrap_driver, + struct load_driver *load_driver) +{ + int i, num_settings; + + ENTER1("%p, %p", wrap_driver, load_driver); + + num_settings = 0; + for (i = 0; i < load_driver->num_settings; i++) { + struct load_device_setting *load_setting = + &load_driver->settings[i]; + struct wrap_device_setting *setting; + ULONG data1; + + setting = kzalloc(sizeof(*setting), GFP_KERNEL); + if (!setting) { + ERROR("couldn't allocate memory"); + break; + } + strncpy(setting->name, load_setting->name, + sizeof(setting->name)); + setting->name[sizeof(setting->name)-1] = 0; + strncpy(setting->value, load_setting->value, + sizeof(setting->value)); + setting->value[sizeof(setting->value)-1] = 0; + TRACE2("%p: %s=%s", setting, setting->name, setting->value); + + if (strcmp(setting->name, "driver_version") == 0) { + strncpy(wrap_driver->version, setting->value, + sizeof(wrap_driver->version)); + wrap_driver->version[sizeof(wrap_driver->version)-1] = 0; + } else if (strcmp(setting->name, "class_guid") == 0 && + sscanf(setting->value, "%x", &data1) == 1) { + wrap_driver->dev_type = wrap_device_type(data1); + if (wrap_driver->dev_type < 0) { + WARNING("unknown guid: %x", data1); + wrap_driver->dev_type = 0; + } + } + InsertTailList(&wrap_driver->settings, &setting->list); + num_settings++; + } + /* it is not a fatal error if some settings couldn't be loaded */ + if (num_settings > 0) + EXIT1(return 0); + else + EXIT1(return -EINVAL); +} + +void unload_wrap_device(struct wrap_device *wd) +{ + struct nt_list *cur; + ENTER1("unloading device %p (%04X:%04X:%04X:%04X), driver %s", wd, + wd->vendor, wd->device, wd->subvendor, wd->subdevice, + wd->driver_name); + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + while ((cur = RemoveHeadList(&wd->settings))) { + struct wrap_device_setting *setting; + setting = container_of(cur, struct wrap_device_setting, list); + kfree(setting); + } + RemoveEntryList(&wd->list); + up(&loader_mutex); + kfree(wd); + EXIT1(return); +} + +/* should be called with loader_mutex down */ +void unload_wrap_driver(struct wrap_driver *driver) +{ + int i; + struct driver_object *drv_obj; + struct nt_list *cur, *next; + + ENTER1("unloading driver: %s (%p)", driver->name, driver); + TRACE1("freeing %d images", driver->num_pe_images); + drv_obj = driver->drv_obj; + for (i = 0; i < driver->num_pe_images; i++) + if (driver->pe_images[i].image) { + TRACE1("freeing image at %p", + driver->pe_images[i].image); + vfree(driver->pe_images[i].image); + } + + TRACE1("freeing %d bin files", driver->num_bin_files); + for (i = 0; i < driver->num_bin_files; i++) { + TRACE1("freeing image at %p", driver->bin_files[i].data); + if (driver->bin_files[i].data) + vfree(driver->bin_files[i].data); + } + if (driver->bin_files) + kfree(driver->bin_files); + RtlFreeUnicodeString(&drv_obj->name); + RemoveEntryList(&driver->list); + nt_list_for_each_safe(cur, next, &driver->settings) { + struct wrap_device_setting *setting; + struct ndis_configuration_parameter *param; + + setting = container_of(cur, struct wrap_device_setting, list); + TRACE2("%p", setting); + param = setting->encoded; + if (param) { + TRACE2("%p", param); + if (param->type == NdisParameterString) + RtlFreeUnicodeString(¶m->data.string); + ExFreePool(param); + } + kfree(setting); + } + /* this frees driver */ + free_custom_extensions(drv_obj->drv_ext); + kfree(drv_obj->drv_ext); + TRACE1("drv_obj: %p", drv_obj); + + EXIT1(return); +} + +/* call the entry point of the driver */ +static int start_wrap_driver(struct wrap_driver *driver) +{ + int i; + NTSTATUS ret, res; + struct driver_object *drv_obj; + typeof(driver->pe_images[0].entry) entry; + + ENTER1("%s", driver->name); + drv_obj = driver->drv_obj; + for (ret = res = 0, i = 0; i < driver->num_pe_images; i++) + /* dlls are already started by loader */ + if (driver->pe_images[i].type == IMAGE_FILE_EXECUTABLE_IMAGE) { + entry = driver->pe_images[i].entry; + drv_obj->start = driver->pe_images[i].entry; + drv_obj->driver_size = driver->pe_images[i].size; + TRACE1("entry: %p, %p, drv_obj: %p", + entry, *entry, drv_obj); + res = LIN2WIN2(entry, drv_obj, &drv_obj->name); + ret |= res; + TRACE1("entry returns %08X", res); + break; + } + if (ret) { + ERROR("driver initialization failed: %08X", ret); + RtlFreeUnicodeString(&drv_obj->name); + /* this frees ndis_driver */ + free_custom_extensions(drv_obj->drv_ext); + kfree(drv_obj->drv_ext); + TRACE1("drv_obj: %p", drv_obj); + ObDereferenceObject(drv_obj); + EXIT1(return -EINVAL); + } + EXIT1(return 0); +} + +/* + * add driver to list of loaded driver but make sure this driver is + * not loaded before. called with loader_mutex down + */ +static int add_wrap_driver(struct wrap_driver *driver) +{ + struct wrap_driver *tmp; + + ENTER1("name: %s", driver->name); + nt_list_for_each_entry(tmp, &wrap_drivers, list) { + if (stricmp(tmp->name, driver->name) == 0) { + ERROR("cannot add duplicate driver"); + EXIT1(return -EBUSY); + } + } + InsertHeadList(&wrap_drivers, &driver->list); + EXIT1(return 0); +} + +/* load a driver from userspace and initialize it. called with + * loader_mutex down */ +static int load_user_space_driver(struct load_driver *load_driver) +{ + struct driver_object *drv_obj; + struct ansi_string ansi_reg; + struct wrap_driver *wrap_driver = NULL; + + ENTER1("%p", load_driver); + drv_obj = allocate_object(sizeof(*drv_obj), OBJECT_TYPE_DRIVER, NULL); + if (!drv_obj) { + ERROR("couldn't allocate memory"); + EXIT1(return -ENOMEM); + } + TRACE1("drv_obj: %p", drv_obj); + drv_obj->drv_ext = kzalloc(sizeof(*(drv_obj->drv_ext)), GFP_KERNEL); + if (!drv_obj->drv_ext) { + ERROR("couldn't allocate memory"); + ObDereferenceObject(drv_obj); + EXIT1(return -ENOMEM); + } + InitializeListHead(&drv_obj->drv_ext->custom_ext); + if (IoAllocateDriverObjectExtension(drv_obj, + (void *)WRAP_DRIVER_CLIENT_ID, + sizeof(*wrap_driver), + (void **)&wrap_driver) != + STATUS_SUCCESS) + EXIT1(return -ENOMEM); + TRACE1("driver: %p", wrap_driver); + memset(wrap_driver, 0, sizeof(*wrap_driver)); + InitializeListHead(&wrap_driver->list); + InitializeListHead(&wrap_driver->settings); + InitializeListHead(&wrap_driver->wrap_devices); + wrap_driver->drv_obj = drv_obj; + RtlInitAnsiString(&ansi_reg, "/tmp"); + if (RtlAnsiStringToUnicodeString(&drv_obj->name, &ansi_reg, TRUE) != + STATUS_SUCCESS) { + ERROR("couldn't initialize registry path"); + free_custom_extensions(drv_obj->drv_ext); + kfree(drv_obj->drv_ext); + TRACE1("drv_obj: %p", drv_obj); + ObDereferenceObject(drv_obj); + EXIT1(return -EINVAL); + } + strncpy(wrap_driver->name, load_driver->name, sizeof(wrap_driver->name)); + wrap_driver->name[sizeof(wrap_driver->name)-1] = 0; + if (load_sys_files(wrap_driver, load_driver) || + load_bin_files_info(wrap_driver, load_driver) || + load_settings(wrap_driver, load_driver) || + start_wrap_driver(wrap_driver) || + add_wrap_driver(wrap_driver)) { + unload_wrap_driver(wrap_driver); + EXIT1(return -EINVAL); + } else { + printk(KERN_INFO "%s: driver %s (%s) loaded\n", + DRIVER_NAME, wrap_driver->name, wrap_driver->version); + add_taint(TAINT_PROPRIETARY_MODULE); + EXIT1(return 0); + } +} + +static struct pci_device_id wrap_pci_id_table[] = { + {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID}, +}; + +static struct pci_driver wrap_pci_driver = { + .name = DRIVER_NAME, + .id_table = wrap_pci_id_table, + .probe = wrap_pnp_start_pci_device, + .remove = __devexit_p(wrap_pnp_remove_pci_device), + .suspend = wrap_pnp_suspend_pci_device, + .resume = wrap_pnp_resume_pci_device, +}; + +#ifdef ENABLE_USB +static struct usb_device_id wrap_usb_id_table[] = { + { + .driver_info = 1 + }, +}; + +static struct usb_driver wrap_usb_driver = { + .name = DRIVER_NAME, + .id_table = wrap_usb_id_table, + .probe = wrap_pnp_start_usb_device, + .disconnect = __devexit_p(wrap_pnp_remove_usb_device), + .suspend = wrap_pnp_suspend_usb_device, + .resume = wrap_pnp_resume_usb_device, +}; +#endif + +/* register drivers for pci and usb */ +static void register_devices(void) +{ + int res; + + res = pci_register_driver(&wrap_pci_driver); + if (res < 0) { + ERROR("couldn't register pci driver: %d", res); + wrap_pci_driver.name = NULL; + } + +#ifdef ENABLE_USB + res = usb_register(&wrap_usb_driver); + if (res < 0) { + ERROR("couldn't register usb driver: %d", res); + wrap_usb_driver.name = NULL; + } +#endif + EXIT1(return); +} + +static void unregister_devices(void) +{ + struct nt_list *cur, *next; + + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_safe(cur, next, &wrap_devices) { + struct wrap_device *wd; + wd = container_of(cur, struct wrap_device, list); + set_bit(HW_PRESENT, &wd->hw_status); + } + up(&loader_mutex); + + if (wrap_pci_driver.name) + pci_unregister_driver(&wrap_pci_driver); +#ifdef ENABLE_USB + if (wrap_usb_driver.name) + usb_deregister(&wrap_usb_driver); +#endif +} + +struct wrap_device *load_wrap_device(struct load_device *load_device) +{ + int ret; + struct nt_list *cur; + struct wrap_device *wd = NULL; + char vendor[5], device[5], subvendor[5], subdevice[5], bus[5]; + + ENTER1("%04x, %04x, %04x, %04x", load_device->vendor, + load_device->device, load_device->subvendor, + load_device->subdevice); + if (sprintf(vendor, "%04x", load_device->vendor) == 4 && + sprintf(device, "%04x", load_device->device) == 4 && + sprintf(subvendor, "%04x", load_device->subvendor) == 4 && + sprintf(subdevice, "%04x", load_device->subdevice) == 4 && + sprintf(bus, "%04x", load_device->bus) == 4) { + char *argv[] = {"loadndisdriver", WRAP_CMD_LOAD_DEVICE, +#if defined(DEBUG) && DEBUG >= 1 + "1", +#else + "0", +#endif + UTILS_VERSION, vendor, device, + subvendor, subdevice, bus, NULL}; + char *env[] = {NULL}; + TRACE2("%s, %s, %s, %s, %s", vendor, device, + subvendor, subdevice, bus); + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + EXIT1(return NULL); + } + INIT_COMPLETION(loader_complete); + ret = call_usermodehelper("/sbin/loadndisdriver", argv, env, 1); + if (ret) { + up(&loader_mutex); + TRACE1("couldn't load device %04x:%04x; check system " + "log for messages from 'loadndisdriver'", + load_device->vendor, load_device->device); + EXIT1(return NULL); + } + wait_for_completion(&loader_complete); + wd = NULL; + nt_list_for_each(cur, &wrap_devices) { + wd = container_of(cur, struct wrap_device, list); + TRACE2("%p, %04x, %04x, %04x, %04x", wd, wd->vendor, + wd->device, wd->subvendor, wd->subdevice); + if (wd->vendor == load_device->vendor && + wd->device == load_device->device) + break; + else + wd = NULL; + } + up(&loader_mutex); + } else + wd = NULL; + EXIT1(return wd); +} + +struct wrap_device *get_wrap_device(void *dev, int bus) +{ + struct nt_list *cur; + struct wrap_device *wd; + + if (down_interruptible(&loader_mutex)) { + WARNING("couldn't obtain loader_mutex"); + return NULL; + } + wd = NULL; + nt_list_for_each(cur, &wrap_devices) { + wd = container_of(cur, struct wrap_device, list); + if (bus == WRAP_PCI_BUS && + wrap_is_pci_bus(wd->dev_bus) && wd->pci.pdev == dev) + break; + else if (bus == WRAP_USB_BUS && + wrap_is_usb_bus(wd->dev_bus) && wd->usb.udev == dev) + break; + else + wd = NULL; + } + up(&loader_mutex); + return wd; +} + +/* called with loader_mutex is down */ +static int wrapper_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct load_driver *load_driver; + struct load_device load_device; + struct load_driver_file load_bin_file; + int ret; + void __user *addr = (void __user *)arg; + + ENTER1("cmd: %u", cmd); + + ret = 0; + switch (cmd) { + case WRAP_IOCTL_LOAD_DEVICE: + if (copy_from_user(&load_device, addr, sizeof(load_device))) { + ret = -EFAULT; + break; + } + TRACE2("%04x, %04x, %04x, %04x", load_device.vendor, + load_device.device, load_device.subvendor, + load_device.subdevice); + if (load_device.vendor) { + struct wrap_device *wd; + wd = kzalloc(sizeof(*wd), GFP_KERNEL); + if (!wd) { + ret = -ENOMEM; + break; + } + InitializeListHead(&wd->settings); + wd->dev_bus = WRAP_BUS(load_device.bus); + wd->vendor = load_device.vendor; + wd->device = load_device.device; + wd->subvendor = load_device.subvendor; + wd->subdevice = load_device.subdevice; + strncpy(wd->conf_file_name, load_device.conf_file_name, + sizeof(wd->conf_file_name)); + wd->conf_file_name[sizeof(wd->conf_file_name)-1] = 0; + strncpy(wd->driver_name, load_device.driver_name, + sizeof(wd->driver_name)); + wd->driver_name[sizeof(wd->driver_name)-1] = 0; + InsertHeadList(&wrap_devices, &wd->list); + ret = 0; + } else + ret = -EINVAL; + break; + case WRAP_IOCTL_LOAD_DRIVER: + TRACE1("loading driver at %p", addr); + load_driver = vmalloc(sizeof(*load_driver)); + if (!load_driver) { + ret = -ENOMEM; + break; + } + if (copy_from_user(load_driver, addr, sizeof(*load_driver))) + ret = -EFAULT; + else + ret = load_user_space_driver(load_driver); + vfree(load_driver); + break; + case WRAP_IOCTL_LOAD_BIN_FILE: + if (copy_from_user(&load_bin_file, addr, sizeof(load_bin_file))) + ret = -EFAULT; + else + ret = add_bin_file(&load_bin_file); + break; + default: + ERROR("unknown ioctl %u", cmd); + ret = -EINVAL; + break; + } + complete(&loader_complete); + EXIT1(return ret); +} + +static int wrapper_ioctl_release(struct inode *inode, struct file *file) +{ + ENTER1(""); + return 0; +} + +static struct file_operations wrapper_fops = { + .owner = THIS_MODULE, + .ioctl = wrapper_ioctl, + .release = wrapper_ioctl_release, +}; + +static struct miscdevice wrapper_misc = { + .name = DRIVER_NAME, + .minor = MISC_DYNAMIC_MINOR, + .fops = &wrapper_fops +}; + +int loader_init(void) +{ + int err; + + InitializeListHead(&wrap_drivers); + InitializeListHead(&wrap_devices); + init_MUTEX(&loader_mutex); + init_completion(&loader_complete); + if ((err = misc_register(&wrapper_misc)) < 0 ) { + ERROR("couldn't register module (%d)", err); + unregister_devices(); + EXIT1(return err); + } + register_devices(); + EXIT1(return 0); +} + +void loader_exit(void) +{ + struct nt_list *cur, *next; + + ENTER1(""); + misc_deregister(&wrapper_misc); + unregister_devices(); + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + nt_list_for_each_safe(cur, next, &wrap_drivers) { + struct wrap_driver *driver; + driver = container_of(cur, struct wrap_driver, list); + unload_wrap_driver(driver); + } + up(&loader_mutex); + EXIT1(return); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/divdi3.c +++ linux-2.6.28/ubuntu/ndiswrapper/divdi3.c @@ -0,0 +1,329 @@ +/* 64-bit multiplication and division + Copyright (C) 1989, 1992-1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#include +#include + +#if BITS_PER_LONG != 32 +#error This is for 32-bit targets only +#endif + +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +#define Wtype SItype +#define HWtype SItype +#define DWtype DItype +#define UWtype USItype +#define UHWtype USItype +#define UDWtype UDItype +#define W_TYPE_SIZE 32 + +#include "longlong.h" + +#if defined(__BIG_ENDIAN) +struct DWstruct { Wtype high, low;}; +#elif defined(__LITTLE_ENDIAN) +struct DWstruct { Wtype low, high;}; +#else +#error Unhandled endianity +#endif +typedef union { struct DWstruct s; DWtype ll; } DWunion; + +/* Prototypes of exported functions. */ +extern DWtype __divdi3 (DWtype u, DWtype v); +extern DWtype __moddi3 (DWtype u, DWtype v); +extern UDWtype __udivdi3 (UDWtype u, UDWtype v); +extern UDWtype __umoddi3 (UDWtype u, UDWtype v); + +static UDWtype +__udivmoddi4 (UDWtype n, UDWtype d, UDWtype *rp) +{ + DWunion ww; + DWunion nn, dd; + DWunion rr; + UWtype d0, d1, n0, n1, n2; + UWtype q0, q1; + UWtype b, bm; + + nn.ll = n; + dd.ll = d; + + d0 = dd.s.low; + d1 = dd.s.high; + n0 = nn.s.low; + n1 = nn.s.high; + +#if !UDIV_NEEDS_NORMALIZATION + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + udiv_qrnnd (q1, n1, 0, n1, d0); + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0. */ + } + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = 0; + *rp = rr.ll; + } + } + +#else /* UDIV_NEEDS_NORMALIZATION */ + + if (d1 == 0) + { + if (d0 > n1) + { + /* 0q = nn / 0D */ + + count_leading_zeros (bm, d0); + + if (bm != 0) + { + /* Normalize, i.e. make the most significant bit of the + denominator set. */ + + d0 = d0 << bm; + n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); + n0 = n0 << bm; + } + + udiv_qrnnd (q0, n0, n1, n0, d0); + q1 = 0; + + /* Remainder in n0 >> bm. */ + } + else + { + /* qq = NN / 0d */ + + if (d0 == 0) + d0 = 1 / d0; /* Divide intentionally by zero. */ + + count_leading_zeros (bm, d0); + + if (bm == 0) + { + /* From (n1 >= d0) /\ (the most significant bit of d0 is set), + conclude (the most significant bit of n1 is set) /\ (the + leading quotient digit q1 = 1). + + This special case is necessary, not an optimization. + (Shifts counts of W_TYPE_SIZE are undefined.) */ + + n1 -= d0; + q1 = 1; + } + else + { + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q1, n1, n2, n1, d0); + } + + /* n1 != d0... */ + + udiv_qrnnd (q0, n0, n1, n0, d0); + + /* Remainder in n0 >> bm. */ + } + + if (rp != 0) + { + rr.s.low = n0 >> bm; + rr.s.high = 0; + *rp = rr.ll; + } + } +#endif /* UDIV_NEEDS_NORMALIZATION */ + + else + { + if (d1 > n1) + { + /* 00 = nn / DD */ + + q0 = 0; + q1 = 0; + + /* Remainder in n1n0. */ + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + /* 0q = NN / dd */ + + count_leading_zeros (bm, d1); + if (bm == 0) + { + /* From (n1 >= d1) /\ (the most significant bit of d1 is set), + conclude (the most significant bit of n1 is set) /\ (the + quotient digit q0 = 0 or 1). + + This special case is necessary, not an optimization. */ + + /* The condition on the next line takes advantage of that + n1 >= d1 (true due to program flow). */ + if (n1 > d1 || n0 >= d0) + { + q0 = 1; + sub_ddmmss (n1, n0, n1, n0, d1, d0); + } + else + q0 = 0; + + q1 = 0; + + if (rp != 0) + { + rr.s.low = n0; + rr.s.high = n1; + *rp = rr.ll; + } + } + else + { + UWtype m1, m0; + /* Normalize. */ + + b = W_TYPE_SIZE - bm; + + d1 = (d1 << bm) | (d0 >> b); + d0 = d0 << bm; + n2 = n1 >> b; + n1 = (n1 << bm) | (n0 >> b); + n0 = n0 << bm; + + udiv_qrnnd (q0, n1, n2, n1, d1); + umul_ppmm (m1, m0, q0, d0); + + if (m1 > n1 || (m1 == n1 && m0 > n0)) + { + q0--; + sub_ddmmss (m1, m0, m1, m0, d1, d0); + } + + q1 = 0; + + /* Remainder in (n1n0 - m1m0) >> bm. */ + if (rp != 0) + { + sub_ddmmss (n1, n0, n1, n0, m1, m0); + rr.s.low = (n1 << b) | (n0 >> bm); + rr.s.high = n1 >> bm; + *rp = rr.ll; + } + } + } + } + + ww.s.low = q0; + ww.s.high = q1; + return ww.ll; +} + +DWtype +__divdi3 (DWtype u, DWtype v) +{ + Wtype c = 0; + DWtype w; + + if (u < 0) + { + c = ~c; + u = -u; + } + if (v < 0) + { + c = ~c; + v = -v; + } + w = __udivmoddi4 (u, v, NULL); + if (c) + w = -w; + return w; +} + +DWtype +__moddi3 (DWtype u, DWtype v) +{ + Wtype c = 0; + DWtype w; + + if (u < 0) + { + c = ~c; + u = -u; + } + if (v < 0) + v = -v; + __udivmoddi4 (u, v, &w); + if (c) + w = -w; + return w; +} + +UDWtype +__udivdi3 (UDWtype u, UDWtype v) +{ + return __udivmoddi4 (u, v, NULL); +} + +UDWtype +__umoddi3 (UDWtype u, UDWtype v) +{ + UDWtype w; + + __udivmoddi4 (u, v, &w); + return w; +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/pe_linker.h +++ linux-2.6.28/ubuntu/ndiswrapper/pe_linker.h @@ -0,0 +1,993 @@ +/* + * This file is an excerpt of winnt.h from WINE, which bears the + * following copyright: + * + * Win32 definitions for Windows NT + * + * Copyright 1996 Alexandre Julliard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * File formats definitions + */ +typedef struct _IMAGE_DOS_HEADER { + WORD e_magic; /* 00: MZ Header signature */ + WORD e_cblp; /* 02: Bytes on last page of file */ + WORD e_cp; /* 04: Pages in file */ + WORD e_crlc; /* 06: Relocations */ + WORD e_cparhdr; /* 08: Size of header in paragraphs */ + WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */ + WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */ + WORD e_ss; /* 0e: Initial (relative) SS value */ + WORD e_sp; /* 10: Initial SP value */ + WORD e_csum; /* 12: Checksum */ + WORD e_ip; /* 14: Initial IP value */ + WORD e_cs; /* 16: Initial (relative) CS value */ + WORD e_lfarlc; /* 18: File address of relocation table */ + WORD e_ovno; /* 1a: Overlay number */ + WORD e_res[4]; /* 1c: Reserved words */ + WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */ + WORD e_oeminfo; /* 26: OEM information; e_oemid specific */ + WORD e_res2[10]; /* 28: Reserved words */ + DWORD e_lfanew; /* 3c: Offset to extended header */ +} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; + +#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ +#define IMAGE_OS2_SIGNATURE 0x454E /* NE */ +#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ +#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */ +#define IMAGE_VXD_SIGNATURE 0x454C /* LE */ +#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ + +/* + * This is the Windows executable (NE) header. + * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way. + */ +typedef struct +{ + WORD ne_magic; /* 00 NE signature 'NE' */ + BYTE ne_ver; /* 02 Linker version number */ + BYTE ne_rev; /* 03 Linker revision number */ + WORD ne_enttab; /* 04 Offset to entry table relative to NE */ + WORD ne_cbenttab; /* 06 Length of entry table in bytes */ + LONG ne_crc; /* 08 Checksum */ + WORD ne_flags; /* 0c Flags about segments in this file */ + WORD ne_autodata; /* 0e Automatic data segment number */ + WORD ne_heap; /* 10 Initial size of local heap */ + WORD ne_stack; /* 12 Initial size of stack */ + DWORD ne_csip; /* 14 Initial CS:IP */ + DWORD ne_sssp; /* 18 Initial SS:SP */ + WORD ne_cseg; /* 1c # of entries in segment table */ + WORD ne_cmod; /* 1e # of entries in module reference tab. */ + WORD ne_cbnrestab; /* 20 Length of nonresident-name table */ + WORD ne_segtab; /* 22 Offset to segment table */ + WORD ne_rsrctab; /* 24 Offset to resource table */ + WORD ne_restab; /* 26 Offset to resident-name table */ + WORD ne_modtab; /* 28 Offset to module reference table */ + WORD ne_imptab; /* 2a Offset to imported name table */ + DWORD ne_nrestab; /* 2c Offset to nonresident-name table */ + WORD ne_cmovent; /* 30 # of movable entry points */ + WORD ne_align; /* 32 Logical sector alignment shift count */ + WORD ne_cres; /* 34 # of resource segments */ + BYTE ne_exetyp; /* 36 Flags indicating target OS */ + BYTE ne_flagsothers; /* 37 Additional information flags */ + WORD ne_pretthunks; /* 38 Offset to return thunks */ + WORD ne_psegrefbytes; /* 3a Offset to segment ref. bytes */ + WORD ne_swaparea; /* 3c Reserved by Microsoft */ + WORD ne_expver; /* 3e Expected Windows version number */ +} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER; + +typedef struct _IMAGE_VXD_HEADER { + WORD e32_magic; + BYTE e32_border; + BYTE e32_worder; + DWORD e32_level; + WORD e32_cpu; + WORD e32_os; + DWORD e32_ver; + DWORD e32_mflags; + DWORD e32_mpages; + DWORD e32_startobj; + DWORD e32_eip; + DWORD e32_stackobj; + DWORD e32_esp; + DWORD e32_pagesize; + DWORD e32_lastpagesize; + DWORD e32_fixupsize; + DWORD e32_fixupsum; + DWORD e32_ldrsize; + DWORD e32_ldrsum; + DWORD e32_objtab; + DWORD e32_objcnt; + DWORD e32_objmap; + DWORD e32_itermap; + DWORD e32_rsrctab; + DWORD e32_rsrccnt; + DWORD e32_restab; + DWORD e32_enttab; + DWORD e32_dirtab; + DWORD e32_dircnt; + DWORD e32_fpagetab; + DWORD e32_frectab; + DWORD e32_impmod; + DWORD e32_impmodcnt; + DWORD e32_impproc; + DWORD e32_pagesum; + DWORD e32_datapage; + DWORD e32_preload; + DWORD e32_nrestab; + DWORD e32_cbnrestab; + DWORD e32_nressum; + DWORD e32_autodata; + DWORD e32_debuginfo; + DWORD e32_debuglen; + DWORD e32_instpreload; + DWORD e32_instdemand; + DWORD e32_heapsize; + BYTE e32_res3[12]; + DWORD e32_winresoff; + DWORD e32_winreslen; + WORD e32_devid; + WORD e32_ddkver; +} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER; + +/* These defines describe the meanings of the bits in the + Characteristics field */ + +#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */ +#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 +#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 +#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 +#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010 +#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020 +#define IMAGE_FILE_16BIT_MACHINE 0x0040 +#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 +#define IMAGE_FILE_32BIT_MACHINE 0x0100 +#define IMAGE_FILE_DEBUG_STRIPPED 0x0200 +#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800 +#define IMAGE_FILE_SYSTEM 0x1000 +#define IMAGE_FILE_DLL 0x2000 +#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000 +#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 + +/* These are the settings of the Machine field. */ +#define IMAGE_FILE_MACHINE_UNKNOWN 0 +#define IMAGE_FILE_MACHINE_I860 0x014d +#define IMAGE_FILE_MACHINE_I386 0x014c +#define IMAGE_FILE_MACHINE_R3000 0x0162 +#define IMAGE_FILE_MACHINE_R4000 0x0166 +#define IMAGE_FILE_MACHINE_R10000 0x0168 +#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 +#define IMAGE_FILE_MACHINE_ALPHA 0x0184 +#define IMAGE_FILE_MACHINE_SH3 0x01a2 +#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3 +#define IMAGE_FILE_MACHINE_SH3E 0x01a4 +#define IMAGE_FILE_MACHINE_SH4 0x01a6 +#define IMAGE_FILE_MACHINE_SH5 0x01a8 +#define IMAGE_FILE_MACHINE_ARM 0x01c0 +#define IMAGE_FILE_MACHINE_THUMB 0x01c2 +#define IMAGE_FILE_MACHINE_AM33 0x01d3 +#define IMAGE_FILE_MACHINE_POWERPC 0x01f0 +#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1 +#define IMAGE_FILE_MACHINE_IA64 0x0200 +#define IMAGE_FILE_MACHINE_MIPS16 0x0266 +#define IMAGE_FILE_MACHINE_ALPHA64 0x0284 +#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366 +#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466 +#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64 +#define IMAGE_FILE_MACHINE_TRICORE 0x0520 +#define IMAGE_FILE_MACHINE_CEF 0x0cef +#define IMAGE_FILE_MACHINE_EBC 0x0ebc +#define IMAGE_FILE_MACHINE_AMD64 0x8664 +#define IMAGE_FILE_MACHINE_M32R 0x9041 +#define IMAGE_FILE_MACHINE_CEE 0xc0ee + +#define IMAGE_SIZEOF_FILE_HEADER 20 +#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56 +#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER32 224 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER64 240 +#define IMAGE_SIZEOF_SHORT_NAME 8 +#define IMAGE_SIZEOF_SECTION_HEADER 40 +#define IMAGE_SIZEOF_SYMBOL 18 +#define IMAGE_SIZEOF_AUX_SYMBOL 18 +#define IMAGE_SIZEOF_RELOCATION 10 +#define IMAGE_SIZEOF_BASE_RELOCATION 8 +#define IMAGE_SIZEOF_LINENUMBER 6 +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +/* Possible Magic values */ +#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010b +#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020b +#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x0107 + +#ifdef CONFIG_X86_64 +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER64 +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC +#else +#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER IMAGE_SIZEOF_NT_OPTIONAL_HEADER32 +#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC +#endif + +/* These are indexes into the DataDirectory array */ +#define IMAGE_FILE_EXPORT_DIRECTORY 0 +#define IMAGE_FILE_IMPORT_DIRECTORY 1 +#define IMAGE_FILE_RESOURCE_DIRECTORY 2 +#define IMAGE_FILE_EXCEPTION_DIRECTORY 3 +#define IMAGE_FILE_SECURITY_DIRECTORY 4 +#define IMAGE_FILE_BASE_RELOCATION_TABLE 5 +#define IMAGE_FILE_DEBUG_DIRECTORY 6 +#define IMAGE_FILE_DESCRIPTION_STRING 7 +#define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */ +#define IMAGE_FILE_THREAD_LOCAL_STORAGE 9 +#define IMAGE_FILE_CALLBACK_DIRECTORY 10 + +/* Directory Entries, indices into the DataDirectory array */ + +#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 +#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 +#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 +#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 +#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 +#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 +#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 +#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 +#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */ +#define IMAGE_DIRECTORY_ENTRY_TLS 9 +#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 +#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 +#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ +#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 +#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 + +/* Subsystem Values */ + +#define IMAGE_SUBSYSTEM_UNKNOWN 0 +#define IMAGE_SUBSYSTEM_NATIVE 1 +#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */ +#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem */ +#define IMAGE_SUBSYSTEM_OS2_CUI 5 +#define IMAGE_SUBSYSTEM_POSIX_CUI 7 +#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8 /* native Win9x driver */ +#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9 /* Windows CE subsystem */ +#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10 +#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11 +#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12 +#define IMAGE_SUBSYSTEM_EFI_ROM 13 +#define IMAGE_SUBSYSTEM_XBOX 14 + +typedef struct _IMAGE_FILE_HEADER { + WORD Machine; + WORD NumberOfSections; + DWORD TimeDateStamp; + DWORD PointerToSymbolTable; + DWORD NumberOfSymbols; + WORD SizeOfOptionalHeader; + WORD Characteristics; +} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; + +typedef struct _IMAGE_DATA_DIRECTORY { + DWORD VirtualAddress; + DWORD Size; +} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; + +#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 + +typedef struct _IMAGE_OPTIONAL_HEADER32 { + + /* Standard fields */ + + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + DWORD BaseOfData; + + /* NT additional fields */ + DWORD ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + DWORD SizeOfStackReserve; + DWORD SizeOfStackCommit; + DWORD SizeOfHeapReserve; + DWORD SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32; + +typedef struct _IMAGE_OPTIONAL_HEADER64 { + + /* Standard fields */ + + WORD Magic; + BYTE MajorLinkerVersion; + BYTE MinorLinkerVersion; + DWORD SizeOfCode; + DWORD SizeOfInitializedData; + DWORD SizeOfUninitializedData; + DWORD AddressOfEntryPoint; + DWORD BaseOfCode; + + /* NT additional fields */ + ULONGLONG ImageBase; + DWORD SectionAlignment; + DWORD FileAlignment; + WORD MajorOperatingSystemVersion; + WORD MinorOperatingSystemVersion; + WORD MajorImageVersion; + WORD MinorImageVersion; + WORD MajorSubsystemVersion; + WORD MinorSubsystemVersion; + DWORD Win32VersionValue; + DWORD SizeOfImage; + DWORD SizeOfHeaders; + DWORD CheckSum; + WORD Subsystem; + WORD DllCharacteristics; + ULONGLONG SizeOfStackReserve; + ULONGLONG SizeOfStackCommit; + ULONGLONG SizeOfHeapReserve; + ULONGLONG SizeOfHeapCommit; + DWORD LoaderFlags; + DWORD NumberOfRvaAndSizes; + IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; +} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64; + +#ifdef CONFIG_X86_64 +typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER; +#else +typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER; +typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER; +#endif + +typedef struct _IMAGE_NT_HEADERS32 { + DWORD Signature; /* "PE"\0\0 */ /* 0x00 */ + IMAGE_FILE_HEADER FileHeader; /* 0x04 */ + IMAGE_OPTIONAL_HEADER32 OptionalHeader; /* 0x18 */ +} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; + +typedef struct _IMAGE_NT_HEADERS64 { + DWORD Signature; /* "PE"\0\0 */ /* 0x00 */ + IMAGE_FILE_HEADER FileHeader; /* 0x04 */ + IMAGE_OPTIONAL_HEADER64 OptionalHeader; /* 0x18 */ +} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64; + +#ifdef CONFIG_X86_64 +typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS; +#else +typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS; +typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS; +#endif + +#define IMAGE_SIZEOF_SHORT_NAME 8 + +typedef struct _IMAGE_SECTION_HEADER { + BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; + union { + DWORD PhysicalAddress; + DWORD VirtualSize; + } Misc; + DWORD VirtualAddress; + DWORD SizeOfRawData; + DWORD PointerToRawData; + DWORD PointerToRelocations; + DWORD PointerToLinenumbers; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD Characteristics; +} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; + +#define IMAGE_SIZEOF_SECTION_HEADER 40 + +#define IMAGE_FIRST_SECTION(ntheader) \ +((PIMAGE_SECTION_HEADER)((LPBYTE)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \ +((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader)) + +/* These defines are for the Characteristics bitfield. */ +/* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */ +/* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */ +/* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */ +/* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */ +#define IMAGE_SCN_TYPE_NO_PAD 0x00000008 /* Reserved */ +/* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */ + +#define IMAGE_SCN_CNT_CODE 0x00000020 +#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 + +#define IMAGE_SCN_LNK_OTHER 0x00000100 +#define IMAGE_SCN_LNK_INFO 0x00000200 +/* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */ +#define IMAGE_SCN_LNK_REMOVE 0x00000800 +#define IMAGE_SCN_LNK_COMDAT 0x00001000 + +/* 0x00002000 - Reserved */ +/* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */ +#define IMAGE_SCN_MEM_FARDATA 0x00008000 + +/* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */ +#define IMAGE_SCN_MEM_PURGEABLE 0x00020000 +#define IMAGE_SCN_MEM_16BIT 0x00020000 +#define IMAGE_SCN_MEM_LOCKED 0x00040000 +#define IMAGE_SCN_MEM_PRELOAD 0x00080000 + +#define IMAGE_SCN_ALIGN_1BYTES 0x00100000 +#define IMAGE_SCN_ALIGN_2BYTES 0x00200000 +#define IMAGE_SCN_ALIGN_4BYTES 0x00300000 +#define IMAGE_SCN_ALIGN_8BYTES 0x00400000 +#define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */ +#define IMAGE_SCN_ALIGN_32BYTES 0x00600000 +#define IMAGE_SCN_ALIGN_64BYTES 0x00700000 +#define IMAGE_SCN_ALIGN_128BYTES 0x00800000 +#define IMAGE_SCN_ALIGN_256BYTES 0x00900000 +#define IMAGE_SCN_ALIGN_512BYTES 0x00A00000 +#define IMAGE_SCN_ALIGN_1024BYTES 0x00B00000 +#define IMAGE_SCN_ALIGN_2048BYTES 0x00C00000 +#define IMAGE_SCN_ALIGN_4096BYTES 0x00D00000 +#define IMAGE_SCN_ALIGN_8192BYTES 0x00E00000 +/* 0x00F00000 - Unused */ +#define IMAGE_SCN_ALIGN_MASK 0x00F00000 + +#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 + + +#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 +#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 +#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 +#define IMAGE_SCN_MEM_SHARED 0x10000000 +#define IMAGE_SCN_MEM_EXECUTE 0x20000000 +#define IMAGE_SCN_MEM_READ 0x40000000 +#define IMAGE_SCN_MEM_WRITE 0x80000000 + +typedef struct _IMAGE_SYMBOL { + union { + BYTE ShortName[8]; + struct { + DWORD Short; + DWORD Long; + } Name; + DWORD LongName[2]; + } N; + DWORD Value; + SHORT SectionNumber; + WORD Type; + BYTE StorageClass; + BYTE NumberOfAuxSymbols; +} IMAGE_SYMBOL; +typedef IMAGE_SYMBOL *PIMAGE_SYMBOL; + +#define IMAGE_SIZEOF_SYMBOL 18 + +typedef struct _IMAGE_LINENUMBER { + union { + DWORD SymbolTableIndex; + DWORD VirtualAddress; + } Type; + WORD Linenumber; +} IMAGE_LINENUMBER; +typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER; + +#define IMAGE_SIZEOF_LINENUMBER 6 + +typedef union _IMAGE_AUX_SYMBOL { + struct { + DWORD TagIndex; + union { + struct { + WORD Linenumber; + WORD Size; + } LnSz; + DWORD TotalSize; + } Misc; + union { + struct { + DWORD PointerToLinenumber; + DWORD PointerToNextFunction; + } Function; + struct { + WORD Dimension[4]; + } Array; + } FcnAry; + WORD TvIndex; + } Sym; + struct { + BYTE Name[IMAGE_SIZEOF_SYMBOL]; + } File; + struct { + DWORD Length; + WORD NumberOfRelocations; + WORD NumberOfLinenumbers; + DWORD CheckSum; + SHORT Number; + BYTE Selection; + } Section; +} IMAGE_AUX_SYMBOL; +typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL; + +#define IMAGE_SIZEOF_AUX_SYMBOL 18 + +#define IMAGE_SYM_UNDEFINED (SHORT)0 +#define IMAGE_SYM_ABSOLUTE (SHORT)-1 +#define IMAGE_SYM_DEBUG (SHORT)-2 + +#define IMAGE_SYM_TYPE_NULL 0x0000 +#define IMAGE_SYM_TYPE_VOID 0x0001 +#define IMAGE_SYM_TYPE_CHAR 0x0002 +#define IMAGE_SYM_TYPE_SHORT 0x0003 +#define IMAGE_SYM_TYPE_INT 0x0004 +#define IMAGE_SYM_TYPE_LONG 0x0005 +#define IMAGE_SYM_TYPE_FLOAT 0x0006 +#define IMAGE_SYM_TYPE_DOUBLE 0x0007 +#define IMAGE_SYM_TYPE_STRUCT 0x0008 +#define IMAGE_SYM_TYPE_UNION 0x0009 +#define IMAGE_SYM_TYPE_ENUM 0x000A +#define IMAGE_SYM_TYPE_MOE 0x000B +#define IMAGE_SYM_TYPE_BYTE 0x000C +#define IMAGE_SYM_TYPE_WORD 0x000D +#define IMAGE_SYM_TYPE_UINT 0x000E +#define IMAGE_SYM_TYPE_DWORD 0x000F +#define IMAGE_SYM_TYPE_PCODE 0x8000 + +#define IMAGE_SYM_DTYPE_NULL 0 +#define IMAGE_SYM_DTYPE_POINTER 1 +#define IMAGE_SYM_DTYPE_FUNCTION 2 +#define IMAGE_SYM_DTYPE_ARRAY 3 + +#define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 +#define IMAGE_SYM_CLASS_NULL 0x0000 +#define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 +#define IMAGE_SYM_CLASS_EXTERNAL 0x0002 +#define IMAGE_SYM_CLASS_STATIC 0x0003 +#define IMAGE_SYM_CLASS_REGISTER 0x0004 +#define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 +#define IMAGE_SYM_CLASS_LABEL 0x0006 +#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 +#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 +#define IMAGE_SYM_CLASS_ARGUMENT 0x0009 +#define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A +#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B +#define IMAGE_SYM_CLASS_UNION_TAG 0x000C +#define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D +#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E +#define IMAGE_SYM_CLASS_ENUM_TAG 0x000F +#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 +#define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 +#define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 + +#define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 +#define IMAGE_SYM_CLASS_BLOCK 0x0064 +#define IMAGE_SYM_CLASS_FUNCTION 0x0065 +#define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 +#define IMAGE_SYM_CLASS_FILE 0x0067 +#define IMAGE_SYM_CLASS_SECTION 0x0068 +#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 + +#define N_BTMASK 0x000F +#define N_TMASK 0x0030 +#define N_TMASK1 0x00C0 +#define N_TMASK2 0x00F0 +#define N_BTSHFT 4 +#define N_TSHIFT 2 + +#define BTYPE(x) ((x) & N_BTMASK) + +#ifndef ISPTR +#define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)) +#endif + +#ifndef ISFCN +#define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT)) +#endif + +#ifndef ISARY +#define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT)) +#endif + +#ifndef ISTAG +#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG) +#endif + +#ifndef INCREF +#define INCREF(x) ((((x)&~N_BTMASK)<>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) +#endif + +#define IMAGE_COMDAT_SELECT_NODUPLICATES 1 +#define IMAGE_COMDAT_SELECT_ANY 2 +#define IMAGE_COMDAT_SELECT_SAME_SIZE 3 +#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 +#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 +#define IMAGE_COMDAT_SELECT_LARGEST 6 +#define IMAGE_COMDAT_SELECT_NEWEST 7 + +#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 +#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 +#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 + +/* Export module directory */ + +typedef struct _IMAGE_EXPORT_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + DWORD Name; + DWORD Base; + DWORD NumberOfFunctions; + DWORD NumberOfNames; + DWORD AddressOfFunctions; + DWORD AddressOfNames; + DWORD AddressOfNameOrdinals; +} IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; + +/* Import name entry */ +typedef struct _IMAGE_IMPORT_BY_NAME { + WORD Hint; + BYTE Name[1]; +} IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; + +/* Import thunk */ +typedef struct _IMAGE_THUNK_DATA32 { + union { + DWORD ForwarderString; + DWORD Function; + DWORD Ordinal; + DWORD AddressOfData; + } u1; +} IMAGE_THUNK_DATA32,*PIMAGE_THUNK_DATA32; + +typedef struct _IMAGE_THUNK_DATA64 { + union { + ULONGLONG ForwarderString; + ULONGLONG Function; + ULONGLONG Ordinal; + ULONGLONG AddressOfData; + } u1; +} IMAGE_THUNK_DATA64,*PIMAGE_THUNK_DATA64; + +#ifdef CONFIG_X86_64 +typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA; +typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA; +#else +typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA; +typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA; +#endif + +/* Import module directory */ + +typedef struct packed _IMAGE_IMPORT_DESCRIPTOR { + union { + DWORD Characteristics; /* 0 for terminating null + * import descriptor */ + DWORD OriginalFirstThunk; /* RVA to original unbound + * IAT */ + } u; + DWORD TimeDateStamp; /* 0 if not bound, + * -1 if bound, and real date\time stamp + * in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT + * (new BIND) + * otherwise date/time stamp of DLL bound to + * (Old BIND) + */ + DWORD ForwarderChain; /* -1 if no forwarders */ + DWORD Name; + /* RVA to IAT (if bound this IAT has actual addresses) */ + DWORD FirstThunk; +} IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; + +#define IMAGE_ORDINAL_FLAG32 0x80000000 +#define IMAGE_ORDINAL_FLAG64 0x8000000000000000UL +#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32) != 0) +#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64) != 0) +#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) + +#ifdef CONFIG_X86_64 +#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG64 +#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL64 +#else +#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG32 +#define IMAGE_SNAP_BY_ORDINAL IMAGE_SNAP_BY_ORDINAL32 +#endif + +typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR +{ + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD NumberOfModuleForwarderRefs; +/* Array of zero or more IMAGE_BOUND_FORWARDER_REF follows */ +} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR; + +typedef struct _IMAGE_BOUND_FORWARDER_REF +{ + DWORD TimeDateStamp; + WORD OffsetModuleName; + WORD Reserved; +} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF; + +typedef struct _IMAGE_BASE_RELOCATION +{ + DWORD VirtualAddress; + DWORD SizeOfBlock; + WORD TypeOffset[0]; +} IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; + +typedef struct _IMAGE_RELOCATION +{ + union { + DWORD VirtualAddress; + DWORD RelocCount; + } DUMMYUNIONNAME; + DWORD SymbolTableIndex; + WORD Type; +} IMAGE_RELOCATION, *PIMAGE_RELOCATION; + +#define IMAGE_SIZEOF_RELOCATION 10 + +/* generic relocation types */ +#define IMAGE_REL_BASED_ABSOLUTE 0 +#define IMAGE_REL_BASED_HIGH 1 +#define IMAGE_REL_BASED_LOW 2 +#define IMAGE_REL_BASED_HIGHLOW 3 +#define IMAGE_REL_BASED_HIGHADJ 4 +#define IMAGE_REL_BASED_MIPS_JMPADDR 5 +#define IMAGE_REL_BASED_SECTION 6 +#define IMAGE_REL_BASED_REL 7 +#define IMAGE_REL_BASED_MIPS_JMPADDR16 9 +#define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ +#define IMAGE_REL_BASED_DIR64 10 +#define IMAGE_REL_BASED_HIGH3ADJ 11 + +/* I386 relocation types */ +#define IMAGE_REL_I386_ABSOLUTE 0 +#define IMAGE_REL_I386_DIR16 1 +#define IMAGE_REL_I386_REL16 2 +#define IMAGE_REL_I386_DIR32 6 +#define IMAGE_REL_I386_DIR32NB 7 +#define IMAGE_REL_I386_SEG12 9 +#define IMAGE_REL_I386_SECTION 10 +#define IMAGE_REL_I386_SECREL 11 +#define IMAGE_REL_I386_REL32 20 + +/* MIPS relocation types */ +#define IMAGE_REL_MIPS_ABSOLUTE 0x0000 +#define IMAGE_REL_MIPS_REFHALF 0x0001 +#define IMAGE_REL_MIPS_REFWORD 0x0002 +#define IMAGE_REL_MIPS_JMPADDR 0x0003 +#define IMAGE_REL_MIPS_REFHI 0x0004 +#define IMAGE_REL_MIPS_REFLO 0x0005 +#define IMAGE_REL_MIPS_GPREL 0x0006 +#define IMAGE_REL_MIPS_LITERAL 0x0007 +#define IMAGE_REL_MIPS_SECTION 0x000A +#define IMAGE_REL_MIPS_SECREL 0x000B +#define IMAGE_REL_MIPS_SECRELLO 0x000C +#define IMAGE_REL_MIPS_SECRELHI 0x000D +#define IMAGE_REL_MIPS_JMPADDR16 0x0010 +#define IMAGE_REL_MIPS_REFWORDNB 0x0022 +#define IMAGE_REL_MIPS_PAIR 0x0025 + +/* ALPHA relocation types */ +#define IMAGE_REL_ALPHA_ABSOLUTE 0x0000 +#define IMAGE_REL_ALPHA_REFLONG 0x0001 +#define IMAGE_REL_ALPHA_REFQUAD 0x0002 +#define IMAGE_REL_ALPHA_GPREL 0x0003 +#define IMAGE_REL_ALPHA_LITERAL 0x0004 +#define IMAGE_REL_ALPHA_LITUSE 0x0005 +#define IMAGE_REL_ALPHA_GPDISP 0x0006 +#define IMAGE_REL_ALPHA_BRADDR 0x0007 +#define IMAGE_REL_ALPHA_HINT 0x0008 +#define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009 +#define IMAGE_REL_ALPHA_REFHI 0x000A +#define IMAGE_REL_ALPHA_REFLO 0x000B +#define IMAGE_REL_ALPHA_PAIR 0x000C +#define IMAGE_REL_ALPHA_MATCH 0x000D +#define IMAGE_REL_ALPHA_SECTION 0x000E +#define IMAGE_REL_ALPHA_SECREL 0x000F +#define IMAGE_REL_ALPHA_REFLONGNB 0x0010 +#define IMAGE_REL_ALPHA_SECRELLO 0x0011 +#define IMAGE_REL_ALPHA_SECRELHI 0x0012 +#define IMAGE_REL_ALPHA_REFQ3 0x0013 +#define IMAGE_REL_ALPHA_REFQ2 0x0014 +#define IMAGE_REL_ALPHA_REFQ1 0x0015 +#define IMAGE_REL_ALPHA_GPRELLO 0x0016 +#define IMAGE_REL_ALPHA_GPRELHI 0x0017 + +/* PowerPC relocation types */ +#define IMAGE_REL_PPC_ABSOLUTE 0x0000 +#define IMAGE_REL_PPC_ADDR64 0x0001 +#define IMAGE_REL_PPC_ADDR 0x0002 +#define IMAGE_REL_PPC_ADDR24 0x0003 +#define IMAGE_REL_PPC_ADDR16 0x0004 +#define IMAGE_REL_PPC_ADDR14 0x0005 +#define IMAGE_REL_PPC_REL24 0x0006 +#define IMAGE_REL_PPC_REL14 0x0007 +#define IMAGE_REL_PPC_TOCREL16 0x0008 +#define IMAGE_REL_PPC_TOCREL14 0x0009 +#define IMAGE_REL_PPC_ADDR32NB 0x000A +#define IMAGE_REL_PPC_SECREL 0x000B +#define IMAGE_REL_PPC_SECTION 0x000C +#define IMAGE_REL_PPC_IFGLUE 0x000D +#define IMAGE_REL_PPC_IMGLUE 0x000E +#define IMAGE_REL_PPC_SECREL16 0x000F +#define IMAGE_REL_PPC_REFHI 0x0010 +#define IMAGE_REL_PPC_REFLO 0x0011 +#define IMAGE_REL_PPC_PAIR 0x0012 +#define IMAGE_REL_PPC_SECRELLO 0x0013 +#define IMAGE_REL_PPC_SECRELHI 0x0014 +#define IMAGE_REL_PPC_GPREL 0x0015 +#define IMAGE_REL_PPC_TYPEMASK 0x00FF +/* modifier bits */ +#define IMAGE_REL_PPC_NEG 0x0100 +#define IMAGE_REL_PPC_BRTAKEN 0x0200 +#define IMAGE_REL_PPC_BRNTAKEN 0x0400 +#define IMAGE_REL_PPC_TOCDEFN 0x0800 + +/* SH3 ? relocation type */ +#define IMAGE_REL_SH3_ABSOLUTE 0x0000 +#define IMAGE_REL_SH3_DIRECT16 0x0001 +#define IMAGE_REL_SH3_DIRECT 0x0002 +#define IMAGE_REL_SH3_DIRECT8 0x0003 +#define IMAGE_REL_SH3_DIRECT8_WORD 0x0004 +#define IMAGE_REL_SH3_DIRECT8_LONG 0x0005 +#define IMAGE_REL_SH3_DIRECT4 0x0006 +#define IMAGE_REL_SH3_DIRECT4_WORD 0x0007 +#define IMAGE_REL_SH3_DIRECT4_LONG 0x0008 +#define IMAGE_REL_SH3_PCREL8_WORD 0x0009 +#define IMAGE_REL_SH3_PCREL8_LONG 0x000A +#define IMAGE_REL_SH3_PCREL12_WORD 0x000B +#define IMAGE_REL_SH3_STARTOF_SECTION 0x000C +#define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D +#define IMAGE_REL_SH3_SECTION 0x000E +#define IMAGE_REL_SH3_SECREL 0x000F +#define IMAGE_REL_SH3_DIRECT32_NB 0x0010 + +/* ARM (Archimedes?) relocation types */ +#define IMAGE_REL_ARM_ABSOLUTE 0x0000 +#define IMAGE_REL_ARM_ADDR 0x0001 +#define IMAGE_REL_ARM_ADDR32NB 0x0002 +#define IMAGE_REL_ARM_BRANCH24 0x0003 +#define IMAGE_REL_ARM_BRANCH11 0x0004 +#define IMAGE_REL_ARM_SECTION 0x000E +#define IMAGE_REL_ARM_SECREL 0x000F + +/* IA64 relocation types */ +#define IMAGE_REL_IA64_ABSOLUTE 0x0000 +#define IMAGE_REL_IA64_IMM14 0x0001 +#define IMAGE_REL_IA64_IMM22 0x0002 +#define IMAGE_REL_IA64_IMM64 0x0003 +#define IMAGE_REL_IA64_DIR 0x0004 +#define IMAGE_REL_IA64_DIR64 0x0005 +#define IMAGE_REL_IA64_PCREL21B 0x0006 +#define IMAGE_REL_IA64_PCREL21M 0x0007 +#define IMAGE_REL_IA64_PCREL21F 0x0008 +#define IMAGE_REL_IA64_GPREL22 0x0009 +#define IMAGE_REL_IA64_LTOFF22 0x000A +#define IMAGE_REL_IA64_SECTION 0x000B +#define IMAGE_REL_IA64_SECREL22 0x000C +#define IMAGE_REL_IA64_SECREL64I 0x000D +#define IMAGE_REL_IA64_SECREL 0x000E +#define IMAGE_REL_IA64_LTOFF64 0x000F +#define IMAGE_REL_IA64_DIR32NB 0x0010 +#define IMAGE_REL_IA64_RESERVED_11 0x0011 +#define IMAGE_REL_IA64_RESERVED_12 0x0012 +#define IMAGE_REL_IA64_RESERVED_13 0x0013 +#define IMAGE_REL_IA64_RESERVED_14 0x0014 +#define IMAGE_REL_IA64_RESERVED_15 0x0015 +#define IMAGE_REL_IA64_RESERVED_16 0x0016 +#define IMAGE_REL_IA64_ADDEND 0x001F + +/* archive format */ + +#define IMAGE_ARCHIVE_START_SIZE 8 +#define IMAGE_ARCHIVE_START "!\n" +#define IMAGE_ARCHIVE_END "`\n" +#define IMAGE_ARCHIVE_PAD "\n" +#define IMAGE_ARCHIVE_LINKER_MEMBER "/ " +#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " + +typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER +{ + BYTE Name[16]; + BYTE Date[12]; + BYTE UserID[6]; + BYTE GroupID[6]; + BYTE Mode[8]; + BYTE Size[10]; + BYTE EndHeader[2]; +} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; + +#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 + +/* + * Resource directory stuff + */ +typedef struct _IMAGE_RESOURCE_DIRECTORY { + DWORD Characteristics; + DWORD TimeDateStamp; + WORD MajorVersion; + WORD MinorVersion; + WORD NumberOfNamedEntries; + WORD NumberOfIdEntries; + /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ +} IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; + +#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 +#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 + +typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { + union { + struct { +#ifdef BITFIELDS_BIGENDIAN + unsigned NameIsString:1; + unsigned NameOffset:31; +#else + unsigned NameOffset:31; + unsigned NameIsString:1; +#endif + } DUMMYSTRUCTNAME1; + DWORD Name; + struct { +#ifdef WORDS_BIGENDIAN + WORD __pad; + WORD Id; +#else + WORD Id; + WORD __pad; +#endif + } DUMMYSTRUCTNAME2; + } DUMMYUNIONNAME1; + union { + DWORD OffsetToData; + struct { +#ifdef BITFIELDS_BIGENDIAN + unsigned DataIsDirectory:1; + unsigned OffsetToDirectory:31; +#else + unsigned OffsetToDirectory:31; + unsigned DataIsDirectory:1; +#endif + } DUMMYSTRUCTNAME3; + } DUMMYUNIONNAME2; +} IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; + + +typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { + WORD Length; + CHAR NameString[ 1 ]; +} IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; + --- linux-2.6.28.orig/ubuntu/ndiswrapper/ndis.h +++ linux-2.6.28/ubuntu/ndiswrapper/ndis.h @@ -0,0 +1,1309 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _NDIS_H_ +#define _NDIS_H_ + +#include "ntoskernel.h" + +//#define ALLOW_POOL_OVERFLOW 1 + +#define NDIS_DMA_24BITS 0 +#define NDIS_DMA_32BITS 1 +#define NDIS_DMA_64BITS 2 + +#ifdef CONFIG_X86_64 +#define MAXIMUM_PROCESSORS 64 +#else +#define MAXIMUM_PROCESSORS 32 +#endif + +typedef UINT NDIS_STATUS; +typedef UCHAR NDIS_DMA_SIZE; +typedef LONG ndis_rssi; +typedef ULONG ndis_key_index; +typedef ULONG ndis_tx_power_level; +typedef ULONGULONG ndis_key_rsc; +typedef UCHAR ndis_rates[NDIS_MAX_RATES]; +typedef UCHAR ndis_rates_ex[NDIS_MAX_RATES_EX]; +typedef UCHAR mac_address[ETH_ALEN]; +typedef ULONG ndis_fragmentation_threshold; +typedef ULONG ndis_rts_threshold; +typedef ULONG ndis_antenna; +typedef ULONG ndis_oid; + +typedef UCHAR ndis_pmkid_vavlue[16]; + +typedef uint64_t NDIS_PHY_ADDRESS; + +struct ndis_sg_element { + PHYSICAL_ADDRESS address; + ULONG length; + ULONG_PTR reserved; +}; + +struct ndis_sg_list { + ULONG nent; + ULONG_PTR reserved; + struct ndis_sg_element elements[]; +}; + +/* when sending packets, ndiswrapper associates exactly one sg element + * in sg list */ +struct wrap_tx_sg_list { + ULONG nent; + ULONG_PTR reserved; + struct ndis_sg_element elements[1]; +}; + +struct ndis_phy_addr_unit { + NDIS_PHY_ADDRESS phy_addr; + UINT length; +}; + +typedef struct mdl ndis_buffer; + +struct ndis_buffer_pool { + ndis_buffer *free_descr; +// NT_SPIN_LOCK lock; + spinlock_t lock; + UINT max_descr; + UINT num_allocated_descr; +}; + +#define NDIS_PROTOCOL_ID_DEFAULT 0x00 +#define NDIS_PROTOCOL_ID_TCP_IP 0x02 +#define NDIS_PROTOCOL_ID_IPX 0x06 +#define NDIS_PROTOCOL_ID_NBF 0x07 +#define NDIS_PROTOCOL_ID_MAX 0x0F +#define NDIS_PROTOCOL_ID_MASK 0x0F + +#define fPACKET_WRAPPER_RESERVED 0x3F +#define fPACKET_CONTAINS_MEDIA_SPECIFIC_INFO 0x40 +#define fPACKET_ALLOCATED_BY_NDIS 0x80 + +#define PROTOCOL_RESERVED_SIZE_IN_PACKET (4 * sizeof(void *)) + +struct transport_header_offset { + USHORT protocol_type; + USHORT header_offset; +}; + +struct ndis_network_address { + USHORT length; + USHORT type; + UCHAR address[1]; +}; + +struct ndis_network_address_list { + LONG count; + USHORT type; + struct ndis_network_address address[1]; +}; + +struct ndis_tcp_ip_checksum_packet_info { + union { + struct { + ULONG v4:1; + ULONG v6:1; + ULONG tcp:1; + ULONG udp:1; + ULONG ip:1; + } tx; + struct { + ULONG tcp_failed:1; + ULONG udp_failed:1; + ULONG ip_failed:1; + ULONG tcp_succeeded:1; + ULONG udp_succeeded:1; + ULONG ip_succeeded:1; + ULONG loopback:1; + } rx; + ULONG value; + }; +}; + +enum ndis_task { + TcpIpChecksumNdisTask, IpSecNdisTask, TcpLargeSendNdisTask, MaxNdisTask +}; + +enum ndis_encapsulation { + UNSPECIFIED_Encapsulation, NULL_Encapsulation, + IEEE_802_3_Encapsulation, IEEE_802_5_Encapsulation, + LLC_SNAP_ROUTED_Encapsulation, LLC_SNAP_BRIDGED_Encapsulation +}; + +#define NDIS_TASK_OFFLOAD_VERSION 1 + +struct ndis_encapsulation_format { + enum ndis_encapsulation encap; + struct { + ULONG fixed_header_size:1; + ULONG reserved:31; + } flags; + ULONG header_size; +}; + +struct ndis_task_offload_header { + ULONG version; + ULONG size; + ULONG reserved; + ULONG offset_first_task; + struct ndis_encapsulation_format encap_format; +}; + +struct ndis_task_offload { + ULONG version; + ULONG size; + enum ndis_task task; + ULONG offset_next_task; + ULONG task_buf_length; + UCHAR task_buf[1]; +}; + +struct v4_checksum { + union { + struct { + ULONG ip_opts:1; + ULONG tcp_opts:1; + ULONG tcp_csum:1; + ULONG udp_csum:1; + ULONG ip_csum:1; + }; + ULONG value; + }; +}; + +struct v6_checksum { + ULONG ip_supported:1; + ULONG tcp_supported:1; + ULONG tcp_csum:1; + ULONG udp_csum:1; +}; + +struct ndis_task_tcp_ip_checksum { + struct v4_checksum v4_tx; + struct v4_checksum v4_rx; + struct v6_checksum v6_tx; + struct v6_checksum v6_rx; +}; + +struct ndis_task_tcp_large_send { + ULONG version; + ULONG max_size; + ULONG min_seg_count; + BOOLEAN tcp_opts; + BOOLEAN ip_opts; +}; + +struct ndis_packet; + +struct ndis_packet_pool { + struct ndis_packet *free_descr; +// NT_SPIN_LOCK lock; + spinlock_t lock; + UINT max_descr; + UINT num_allocated_descr; + UINT num_used_descr; + UINT proto_rsvd_length; +}; + +struct ndis_packet_stack { + ULONG_PTR IM_reserved[2]; + ULONG_PTR ndis_reserved[4]; +}; + +enum ndis_per_packet_info { + TcpIpChecksumPacketInfo, IpSecPacketInfo, TcpLargeSendPacketInfo, + ClassificationHandlePacketInfo, NdisReserved, + ScatterGatherListPacketInfo, Ieee8021QInfo, OriginalPacketInfo, + PacketCancelId, MaxPerPacketInfo +}; + +struct ndis_packet_extension { + void *info[MaxPerPacketInfo]; +}; + +struct ndis_packet_private { + UINT nr_pages; + UINT len; + ndis_buffer *buffer_head; + ndis_buffer *buffer_tail; + struct ndis_packet_pool *pool; + UINT count; + ULONG flags; + BOOLEAN valid_counts; + UCHAR packet_flags; + USHORT oob_offset; +}; + +struct ndis_packet { + struct ndis_packet_private private; + /* for use by miniport */ + union { + /* for connectionless mininports */ + struct { + UCHAR miniport_reserved[2 * sizeof(void *)]; + UCHAR wrapper_reserved[2 * sizeof(void *)]; + } cl_reserved; + /* for deserialized miniports */ + struct { + UCHAR miniport_reserved_ex[3 * sizeof(void *)]; + UCHAR wrapper_reserved_ex[sizeof(void *)]; + } deserailized_reserved; + struct { + UCHAR mac_reserved[4 * sizeof(void *)]; + } mac_reserved; + }; + ULONG_PTR reserved[2]; + UCHAR protocol_reserved[1]; +}; + +/* OOB data */ +struct ndis_packet_oob_data { + union { + ULONGLONG time_to_tx; + ULONGLONG time_txed; + }; + ULONGLONG time_rxed; + UINT header_size; + UINT media_size; + void *media; + NDIS_STATUS status; + + /* ndiswrapper specific info; extension should be right after + * ndis's oob_data */ + struct ndis_packet_extension ext; + union { + /* used for tx only */ + struct { + struct sk_buff *tx_skb; + union { + struct wrap_tx_sg_list wrap_tx_sg_list; + struct ndis_sg_list *tx_sg_list; + }; + }; + /* used for rx only */ + struct { + unsigned char header[ETH_HLEN]; + unsigned char *look_ahead; + UINT look_ahead_size; + }; + }; +}; + +#define NDIS_PACKET_OOB_DATA(packet) \ + (struct ndis_packet_oob_data *)(((void *)(packet)) + \ + (packet)->private.oob_offset) + +enum ndis_device_pnp_event { + NdisDevicePnPEventQueryRemoved, NdisDevicePnPEventRemoved, + NdisDevicePnPEventSurpriseRemoved, NdisDevicePnPEventQueryStopped, + NdisDevicePnPEventStopped, NdisDevicePnPEventPowerProfileChanged, + NdisDevicePnPEventMaximum +}; + +enum ndis_request_type { + NdisRequestQueryInformation, NdisRequestSetInformation, + NdisRequestQueryStatistics, NdisRequestOpen, NdisRequestClose, + NdisRequestSend, NdisRequestTransferData, NdisRequestReset, + NdisRequestGeneric1, NdisRequestGeneric2, NdisRequestGeneric3, + NdisRequestGeneric4 +}; + +struct ndis_request { + mac_address mac; + enum ndis_request_type request_type; + union data { + struct query_info { + UINT oid; + void *buf; + UINT buf_len; + UINT written; + UINT needed; + } query_info; + struct set_info { + UINT oid; + void *buf; + UINT buf_len; + UINT written; + UINT needed; + } set_info; + } data; +}; + +enum ndis_medium { + NdisMedium802_3, NdisMedium802_5, NdisMediumFddi, NdisMediumWan, + NdisMediumLocalTalk, NdisMediumDix, NdisMediumArcnetRaw, + NdisMediumArcnet878_2, NdisMediumAtm, NdisMediumWirelessWan, + NdisMediumIrda, NdisMediumBpc, NdisMediumCoWan, + NdisMedium1394, NdisMediumMax +}; + +enum ndis_physical_medium { + NdisPhysicalMediumUnspecified, NdisPhysicalMediumWirelessLan, + NdisPhysicalMediumCableModem, NdisPhysicalMediumPhoneLine, + NdisPhysicalMediumPowerLine, NdisPhysicalMediumDSL, + NdisPhysicalMediumFibreChannel, NdisPhysicalMedium1394, + NdisPhysicalMediumWirelessWan, NdisPhysicalMediumMax +}; + +enum ndis_power_state { + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, NdisDeviceStateD1, NdisDeviceStateD2, + NdisDeviceStateD3, NdisDeviceStateMaximum +}; + +enum ndis_power_profile { + NdisPowerProfileBattery, NdisPowerProfileAcOnLine +}; + +struct ndis_pm_wakeup_capabilities { + enum ndis_power_state min_magic_packet_wakeup; + enum ndis_power_state min_pattern_wakeup; + enum ndis_power_state min_link_change_wakeup; +}; + +#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001 +#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002 +#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004 + +enum net_pnp_event_code { + NetEventSetPower, NetEventQueryPower, NetEventQueryRemoveDevice, + NetEventCancelRemoveDevice, NetEventReconfigure, NetEventBindList, + NetEventBindsComplete, NetEventPnPCapabilities, NetEventMaximum +}; + +struct net_pnp_event { + enum net_pnp_event_code code; + void *buf; + ULONG buf_length; + ULONG_PTR ndis_reserved[4]; + ULONG_PTR transport_reserved[4]; + ULONG_PTR tdi_reserved[4]; + ULONG_PTR tdi_client_reserved[4]; +}; + +struct ndis_pnp_capabilities { + ULONG flags; + struct ndis_pm_wakeup_capabilities wakeup; +}; + +typedef void (*ndis_isr_handler)(BOOLEAN *recognized, BOOLEAN *queue_handler, + void *handle) wstdcall; +typedef void (*ndis_interrupt_handler)(void *ctx) wstdcall; + +struct miniport { + /* NDIS 3.0 */ + UCHAR major_version; + UCHAR minor_version; + USHORT filler; + UINT reserved; + BOOLEAN (*hangcheck)(void *ctx) wstdcall; + void (*disable_interrupt)(void *ctx) wstdcall; + void (*enable_interrupt)(void *ctx) wstdcall; + void (*mp_halt)(void *ctx) wstdcall; + ndis_interrupt_handler handle_interrupt; + NDIS_STATUS (*init)(NDIS_STATUS *error_status, UINT *medium_index, + enum ndis_medium medium[], UINT medium_array_size, + void *handle, void *conf_handle) wstdcall; + ndis_isr_handler isr; + NDIS_STATUS (*queryinfo)(void *ctx, ndis_oid oid, void *buffer, + ULONG buflen, ULONG *written, + ULONG *needed) wstdcall; + void *reconfig; + NDIS_STATUS (*reset)(BOOLEAN *reset_address, void *ctx) wstdcall; + NDIS_STATUS (*send)(void *ctx, struct ndis_packet *packet, + UINT flags) wstdcall; + NDIS_STATUS (*setinfo)(void *ctx, ndis_oid oid, void *buffer, + ULONG buflen, ULONG *written, + ULONG *needed) wstdcall; + NDIS_STATUS (*tx_data)(struct ndis_packet *ndis_packet, + UINT *bytes_txed, void *mp_ctx, void *rx_ctx, + UINT offset, UINT bytes_to_tx) wstdcall; + /* NDIS 4.0 extensions */ + void (*return_packet)(void *ctx, void *packet) wstdcall; + void (*send_packets)(void *ctx, struct ndis_packet **packets, + INT nr_of_packets) wstdcall; + void (*alloc_complete)(void *handle, void *virt, + NDIS_PHY_ADDRESS *phys, + ULONG size, void *ctx) wstdcall; + /* NDIS 5.0 extensions */ + NDIS_STATUS (*co_create_vc)(void *ctx, void *vc_handle, + void *vc_ctx) wstdcall; + NDIS_STATUS (*co_delete_vc)(void *vc_ctx) wstdcall; + NDIS_STATUS (*co_activate_vc)(void *vc_ctx, void *call_params) wstdcall; + NDIS_STATUS (*co_deactivate_vc)(void *vc_ctx) wstdcall; + NDIS_STATUS (*co_send_packets)(void *vc_ctx, void **packets, + UINT nr_of_packets) wstdcall; + NDIS_STATUS (*co_request)(void *ctx, void *vc_ctx, UINT *req) wstdcall; + /* NDIS 5.1 extensions */ + void (*cancel_send_packets)(void *ctx, void *id) wstdcall; + void (*pnp_event_notify)(void *ctx, enum ndis_device_pnp_event event, + void *inf_buf, ULONG inf_buf_len) wstdcall; + void (*shutdown)(void *ctx) wstdcall; + void *reserved1; + void *reserved2; + void *reserved3; + void *reserved4; +}; + +struct ndis_spinlock { + NT_SPIN_LOCK klock; + KIRQL irql; +}; + +union ndis_rw_lock_refcount { + UCHAR cache_line[16]; +}; + +struct ndis_rw_lock { + union { + struct { + NT_SPIN_LOCK klock; + void *context; + }; + UCHAR reserved[16]; + }; + union { + union ndis_rw_lock_refcount ref_count[MAXIMUM_PROCESSORS]; + /* ndiswrapper specific */ + volatile int count; + }; +}; + +struct lock_state { + USHORT state; + KIRQL irql; +}; + +struct ndis_work_item; +typedef void (*NDIS_PROC)(struct ndis_work_item *, void *) wstdcall; + +struct ndis_work_item { + void *ctx; + NDIS_PROC func; + union { + UCHAR reserved[8 * sizeof(void *)]; + /* ndiswrapper specific */ + struct nt_list list; + }; +}; + +struct alloc_shared_mem { + void *ctx; + ULONG size; + BOOLEAN cached; +}; + +struct ndis_mp_block; + +/* this is opaque to drivers, so we can use it as we please */ +struct ndis_mp_interrupt { + struct kinterrupt *kinterrupt; + NT_SPIN_LOCK lock; + union { + void *reserved; + unsigned int irq; + }; + ndis_isr_handler isr; + ndis_interrupt_handler mp_dpc; + struct kdpc intr_dpc; + struct ndis_mp_block *nmb; + UCHAR dpc_count; + BOOLEAN enable; + struct nt_event dpc_completed_event; + BOOLEAN shared; + BOOLEAN req_isr; +}; + +struct ndis_binary_data { + USHORT len; + void *buf; +}; + +enum ndis_parameter_type { + NdisParameterInteger, NdisParameterHexInteger, + NdisParameterString, NdisParameterMultiString, NdisParameterBinary, +}; + +typedef struct unicode_string NDIS_STRING; + +struct ndis_configuration_parameter { + enum ndis_parameter_type type; + union { + ULONG integer; + NDIS_STRING string; + } data; +}; + +struct ndis_driver { + struct miniport mp; +}; + +/* IDs used to store extensions in driver_object's custom extension */ +#define NDIS_DRIVER_CLIENT_ID 10 + +struct ndis_wireless_stats { + ULONG length; + LARGE_INTEGER tx_frag; + LARGE_INTEGER tx_multi_frag; + LARGE_INTEGER failed; + LARGE_INTEGER retry; + LARGE_INTEGER multi_retry; + LARGE_INTEGER rtss_succ; + LARGE_INTEGER rtss_fail; + LARGE_INTEGER ack_fail; + LARGE_INTEGER frame_dup; + LARGE_INTEGER rx_frag; + LARGE_INTEGER rx_multi_frag; + LARGE_INTEGER fcs_err; + LARGE_INTEGER tkip_local_mic_failures; + LARGE_INTEGER tkip_icv_errors; + LARGE_INTEGER tkip_counter_measures_invoked; + LARGE_INTEGER tkip_replays; + LARGE_INTEGER ccmp_format_errors; + LARGE_INTEGER ccmp_replays; + LARGE_INTEGER ccmp_decrypt_errors; + LARGE_INTEGER fourway_handshake_failures; + LARGE_INTEGER wep_undecryptable_count; + LARGE_INTEGER wep_icv_errorcount; + LARGE_INTEGER decrypt_success_count; + LARGE_INTEGER decrypt_failure_count; +}; + +enum ndis_status_type { + Ndis802_11StatusType_Authentication, + Ndis802_11StatusType_MediaStreamMode, + Ndis802_11StatusType_PMKID_CandidateList, + Ndis802_11StatusType_RadioState, +}; + +struct ndis_status_indication { + enum ndis_status_type status_type; +}; + +enum ndis_radio_status { + Ndis802_11RadioStatusOn, Ndis802_11RadioStatusHardwareOff, + Ndis802_11RadioStatusSoftwareOff, +}; + +struct ndis_radio_status_indication +{ + enum ndis_status_type status_type; + enum ndis_radio_status radio_state; +}; + +enum ndis_media_stream_mode { + Ndis802_11MediaStreamOff, Ndis802_11MediaStreamOn +}; + +enum wrapper_work { + LINK_STATUS_OFF, LINK_STATUS_ON, SET_MULTICAST_LIST, COLLECT_IW_STATS, + HANGCHECK, NETIF_WAKEQ, +}; + +struct encr_info { + struct encr_key { + ULONG length; + UCHAR key[NDIS_ENCODING_TOKEN_MAX]; + } keys[MAX_ENCR_KEYS]; + unsigned short tx_key_index; +}; + +struct ndis_essid { + ULONG length; + UCHAR essid[NDIS_ESSID_MAX_SIZE]; +}; + +enum ndis_infrastructure_mode { + Ndis802_11IBSS, Ndis802_11Infrastructure, Ndis802_11AutoUnknown, + Ndis802_11InfrastructureMax +}; + +enum authentication_mode { + Ndis802_11AuthModeOpen, Ndis802_11AuthModeShared, + Ndis802_11AuthModeAutoSwitch, Ndis802_11AuthModeWPA, + Ndis802_11AuthModeWPAPSK, Ndis802_11AuthModeWPANone, + Ndis802_11AuthModeWPA2, Ndis802_11AuthModeWPA2PSK, + Ndis802_11AuthModeMax +}; + +enum encryption_status { + Ndis802_11WEPEnabled, + Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled, + Ndis802_11WEPDisabled, + Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled, + Ndis802_11WEPKeyAbsent, + Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent, + Ndis802_11WEPNotSupported, + Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported, + Ndis802_11Encryption2Enabled, Ndis802_11Encryption2KeyAbsent, + Ndis802_11Encryption3Enabled, Ndis802_11Encryption3KeyAbsent +}; + +struct ndis_auth_encr_pair { + enum authentication_mode auth_mode; + enum encryption_status encr_mode; +}; + +struct ndis_capability { + ULONG length; + ULONG version; + ULONG num_PMKIDs; + ULONG num_auth_encr_pair; + struct ndis_auth_encr_pair auth_encr_pair[1]; +}; + +struct ndis_guid { + struct guid guid; + union { + ndis_oid oid; + NDIS_STATUS status; + }; + ULONG size; + ULONG flags; +}; + +struct ndis_timer { + struct nt_timer nt_timer; + struct kdpc kdpc; +}; + +struct ndis_mp_timer { + struct nt_timer nt_timer; + struct kdpc kdpc; + DPC func; + void *ctx; + struct ndis_mp_block *nmb; + struct ndis_mp_timer *next; +}; + +typedef struct cm_partial_resource_list NDIS_RESOURCE_LIST; + +struct ndis_event { + struct nt_event nt_event; +}; + +struct ndis_bind_paths { + UINT number; + struct unicode_string paths[1]; +}; + +struct ndis_reference { + NT_SPIN_LOCK lock; + USHORT ref_count; + BOOLEAN closing; +}; + +struct ndis_filterdbs { + union { + void *eth_db; + void *null_db; + }; + void *tr_db; + void *fddi_db; + void *arc_db; +}; + +enum ndis_interface_type { + NdisInterfaceInternal, NdisInterfaceIsa, NdisInterfaceEisa, + NdisInterfaceMca, NdisInterfaceTurboChannel, NdisInterfacePci, + NdisInterfacePcMcia, +}; + +struct auth_encr_capa { + unsigned long auth; + unsigned long encr; +}; + +struct ndis_pmkid_candidate { + mac_address bssid; + DWORD flags; +}; + +struct ndis_pmkid_candidate_list { + ULONG version; + ULONG num_candidates; + struct ndis_pmkid_candidate candidates[1]; +}; + +/* + * This struct contains function pointers that the drivers references + * directly via macros, so it's important that they are at the correct + * position. + */ +struct ndis_mp_block { + void *signature; + struct ndis_mp_block *next; + struct driver_object *drv_obj; + void *mp_ctx; + struct unicode_string name; + struct ndis_bind_paths *bindpaths; + void *openqueue; + struct ndis_reference reference; + void *device_ctx; + UCHAR padding; + UCHAR lock_acquired; + UCHAR pmode_opens; + UCHAR assigned_cpu; + NT_SPIN_LOCK lock; + enum ndis_request_type *mediarequest; + struct ndis_mp_interrupt *interrupt; + ULONG flags; + ULONG pnp_flags; + struct nt_list packet_list; + struct ndis_packet *first_pending_tx_packet; + struct ndis_packet *return_packet_queue; + ULONG request_buffer; + void *set_mcast_buffer; + struct ndis_mp_block *primary_mp; + void *wrapper_ctx; + void *bus_data_ctx; + ULONG pnp_capa; + void *resources; + struct ndis_timer wakeup_dpc_timer; + struct unicode_string basename; + struct unicode_string symlink_name; + ULONG ndis_hangcheck_interval; + USHORT hanghcheck_ticks; + USHORT hangcheck_tick; + NDIS_STATUS ndis_reset_status; + void *resetopen; + struct ndis_filterdbs filterdbs; + void *rx_packet; + void *send_complete; + void *send_resource_avail; + void *reset_complete; + + enum ndis_medium media_type; + ULONG bus_number; + enum ndis_interface_type bus_type; + enum ndis_interface_type adapter_type; + struct device_object *fdo; + struct device_object *pdo; + struct device_object *next_device; + void *mapreg; + void *call_mgraflist; + void *mp_thread; + void *setinfobuf; + USHORT setinfo_buf_len; + USHORT max_send_pkts; + NDIS_STATUS fake_status; + void *lock_handler; + struct unicode_string *adapter_instance_name; + void *timer_queue; + UINT mac_options; + void *pending_req; + UINT max_long_addrs; + UINT max_short_addrs; + UINT cur_lookahead; + UINT max_lookahead; + + ndis_interrupt_handler irq_bh; + void *disable_intr; + void *enable_intr; + void *send_pkts; + void *deferred_send; + void *eth_rx_indicate; + void *tr_rx_indicate; + void *fddi_rx_indicate; + void *eth_rx_complete; + void *tr_rx_complete; + void *fddi_rx_complete; + + void *status; + void *status_complete; + void *td_complete; + + void *queryinfo_complete; + void *setinfo_complete; + void *wan_tx_complete; + void *wan_rx; + void *wan_rx_complete; + /* ndiswrapper specific */ + struct ndis_device *wnd; +}; + +struct ndis_device { + struct ndis_mp_block *nmb; + struct wrap_device *wd; + struct net_device *net_dev; + void *shutdown_ctx; + struct ndis_mp_interrupt *mp_interrupt; + struct kdpc irq_kdpc; + unsigned long mem_start; + unsigned long mem_end; + + struct net_device_stats net_stats; + struct iw_statistics iw_stats; + BOOLEAN iw_stats_enabled; + struct ndis_wireless_stats ndis_stats; + + work_struct_t tx_work; + struct ndis_packet *tx_ring[TX_RING_SIZE]; + u8 tx_ring_start; + u8 tx_ring_end; + u8 is_tx_ring_full; + u8 tx_ok; + spinlock_t tx_ring_lock; + struct semaphore tx_ring_mutex; + unsigned int max_tx_packets; + struct semaphore ndis_req_mutex; + struct task_struct *ndis_req_task; + int ndis_req_done; + NDIS_STATUS ndis_req_status; + ULONG packet_filter; + + ULONG sg_dma_size; + ULONG dma_map_count; + dma_addr_t *dma_map_addr; + + int hangcheck_interval; + struct timer_list hangcheck_timer; + int iw_stats_interval; + struct timer_list iw_stats_timer; + unsigned long scan_timestamp; + struct encr_info encr_info; + char nick[IW_ESSID_MAX_SIZE + 1]; + struct ndis_essid essid; + struct auth_encr_capa capa; + enum ndis_infrastructure_mode infrastructure_mode; + int max_pmkids; + int num_pmkids; + struct ndis_pmkid *pmkids; + mac_address mac; + struct proc_dir_entry *procfs_iface; + + work_struct_t ndis_work; + unsigned long ndis_pending_work; + UINT attributes; + int iw_auth_wpa_version; + int iw_auth_cipher_pairwise; + int iw_auth_cipher_group; + int iw_auth_key_mgmt; + int iw_auth_80211_alg; + struct ndis_packet_pool *tx_packet_pool; + struct ndis_buffer_pool *tx_buffer_pool; + int multicast_size; + struct v4_checksum rx_csum; + struct v4_checksum tx_csum; + enum ndis_physical_medium physical_medium; + ULONG ndis_wolopts; + struct nt_slist wrap_timer_slist; + int drv_ndis_version; + struct ndis_pnp_capabilities pnp_capa; + char netdev_name[IFNAMSIZ]; +}; + +BOOLEAN ndis_isr(struct kinterrupt *kinterrupt, void *ctx) wstdcall; + +int ndis_init(void); +void ndis_exit(void); +int ndis_init_device(struct ndis_device *wnd); +void ndis_exit_device(struct ndis_device *wnd); + +int wrap_procfs_add_ndis_device(struct ndis_device *wnd); +void wrap_procfs_remove_ndis_device(struct ndis_device *wnd); + +void NdisAllocatePacketPoolEx(NDIS_STATUS *status, + struct ndis_packet_pool **pool_handle, + UINT num_descr, UINT overflowsize, + UINT proto_rsvd_length) wstdcall; +void NdisFreePacketPool(struct ndis_packet_pool *pool) wstdcall; +void NdisAllocatePacket(NDIS_STATUS *status, struct ndis_packet **packet, + struct ndis_packet_pool *pool) wstdcall; +void NdisFreePacket(struct ndis_packet *descr) wstdcall; +void NdisAllocateBufferPool(NDIS_STATUS *status, + struct ndis_buffer_pool **pool_handle, + UINT num_descr) wstdcall; +void NdisFreeBufferPool(struct ndis_buffer_pool *pool) wstdcall; +void NdisAllocateBuffer(NDIS_STATUS *status, ndis_buffer **buffer, + struct ndis_buffer_pool *pool, void *virt, + UINT length) wstdcall; +void NdisFreeBuffer(ndis_buffer *descr) wstdcall; +void NdisMIndicateReceivePacket(struct ndis_mp_block *nmb, + struct ndis_packet **packets, + UINT nr_packets) wstdcall; +void NdisMSendComplete(struct ndis_mp_block *nmb, struct ndis_packet *packet, + NDIS_STATUS status) wstdcall; +void NdisMSendResourcesAvailable(struct ndis_mp_block *nmb) wstdcall; +void NdisMIndicateStatus(struct ndis_mp_block *nmb, + NDIS_STATUS status, void *buf, UINT len) wstdcall; +void NdisMIndicateStatusComplete(struct ndis_mp_block *nmb) wstdcall; +void NdisMQueryInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) wstdcall; +void NdisMSetInformationComplete(struct ndis_mp_block *nmb, + NDIS_STATUS status) wstdcall; +void NdisMResetComplete(struct ndis_mp_block *nmb, NDIS_STATUS status, + BOOLEAN address_reset) wstdcall; +ULONG NDIS_BUFFER_TO_SPAN_PAGES(ndis_buffer *buffer) wstdcall; +BOOLEAN NdisWaitEvent(struct ndis_event *event, UINT timeout) wstdcall; +void NdisSetEvent(struct ndis_event *event) wstdcall; +void NdisMDeregisterInterrupt(struct ndis_mp_interrupt *mp_interrupt) wstdcall; +void EthRxIndicateHandler(struct ndis_mp_block *nmb, void *rx_ctx, + char *header1, char *header, UINT header_size, + void *look_ahead, UINT look_ahead_size, + UINT packet_size) wstdcall; +void EthRxComplete(struct ndis_mp_block *nmb) wstdcall; +void NdisMTransferDataComplete(struct ndis_mp_block *nmb, + struct ndis_packet *packet, NDIS_STATUS status, + UINT bytes_txed) wstdcall; +void NdisWriteConfiguration(NDIS_STATUS *status, struct ndis_mp_block *nmb, + struct unicode_string *key, + struct ndis_configuration_parameter *param) wstdcall; +void NdisReadConfiguration(NDIS_STATUS *status, + struct ndis_configuration_parameter **param, + struct ndis_mp_block *nmb, + struct unicode_string *key, + enum ndis_parameter_type type) wstdcall; + +/* Required OIDs */ +#define OID_GEN_SUPPORTED_LIST 0x00010101 +#define OID_GEN_HARDWARE_STATUS 0x00010102 +#define OID_GEN_MEDIA_SUPPORTED 0x00010103 +#define OID_GEN_MEDIA_IN_USE 0x00010104 +#define OID_GEN_MAXIMUM_LOOKAHEAD 0x00010105 +#define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106 +#define OID_GEN_LINK_SPEED 0x00010107 +#define OID_GEN_TRANSMIT_BUFFER_SPACE 0x00010108 +#define OID_GEN_RECEIVE_BUFFER_SPACE 0x00010109 +#define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010A +#define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010B +#define OID_GEN_VENDOR_ID 0x0001010C +#define OID_GEN_VENDOR_DESCRIPTION 0x0001010D +#define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E +#define OID_GEN_CURRENT_LOOKAHEAD 0x0001010F +#define OID_GEN_DRIVER_VERSION 0x00010110 +#define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111 +#define OID_GEN_PROTOCOL_OPTIONS 0x00010112 +#define OID_GEN_MAC_OPTIONS 0x00010113 +#define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114 +#define OID_GEN_MAXIMUM_SEND_PACKETS 0x00010115 +#define OID_GEN_VENDOR_DRIVER_VERSION 0x00010116 +#define OID_GEN_SUPPORTED_GUIDS 0x00010117 +#define OID_GEN_NETWORK_LAYER_ADDRESSES 0x00010118 /* Set only */ +#define OID_GEN_TRANSPORT_HEADER_OFFSET 0x00010119 /* Set only */ +#define OID_GEN_MACHINE_NAME 0x0001021A +#define OID_GEN_RNDIS_CONFIG_PARAMETER 0x0001021B /* Set only */ +#define OID_GEN_VLAN_ID 0x0001021C + +/* Optional OIDs. */ +#define OID_GEN_MEDIA_CAPABILITIES 0x00010201 +#define OID_GEN_PHYSICAL_MEDIUM 0x00010202 + +/* Required statistics OIDs. */ +#define OID_GEN_XMIT_OK 0x00020101 +#define OID_GEN_RCV_OK 0x00020102 +#define OID_GEN_XMIT_ERROR 0x00020103 +#define OID_GEN_RCV_ERROR 0x00020104 +#define OID_GEN_RCV_NO_BUFFER 0x00020105 + +/* Optional OID statistics */ +#define OID_GEN_DIRECTED_BYTES_XMIT 0x00020201 +#define OID_GEN_DIRECTED_FRAMES_XMIT 0x00020202 +#define OID_GEN_MULTICAST_BYTES_XMIT 0x00020203 +#define OID_GEN_MULTICAST_FRAMES_XMIT 0x00020204 +#define OID_GEN_BROADCAST_BYTES_XMIT 0x00020205 +#define OID_GEN_BROADCAST_FRAMES_XMIT 0x00020206 +#define OID_GEN_DIRECTED_BYTES_RCV 0x00020207 +#define OID_GEN_DIRECTED_FRAMES_RCV 0x00020208 +#define OID_GEN_MULTICAST_BYTES_RCV 0x00020209 +#define OID_GEN_MULTICAST_FRAMES_RCV 0x0002020A +#define OID_GEN_BROADCAST_BYTES_RCV 0x0002020B +#define OID_GEN_BROADCAST_FRAMES_RCV 0x0002020C +#define OID_GEN_RCV_CRC_ERROR 0x0002020D +#define OID_GEN_TRANSMIT_QUEUE_LENGTH 0x0002020E +#define OID_GEN_GET_TIME_CAPS 0x0002020F +#define OID_GEN_GET_NETCARD_TIME 0x00020210 +#define OID_GEN_NETCARD_LOAD 0x00020211 +#define OID_GEN_DEVICE_PROFILE 0x00020212 + +/* 802.3 (ethernet) OIDs */ +#define OID_802_3_PERMANENT_ADDRESS 0x01010101 +#define OID_802_3_CURRENT_ADDRESS 0x01010102 +#define OID_802_3_MULTICAST_LIST 0x01010103 +#define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104 +#define OID_802_3_MAC_OPTIONS 0x01010105 +#define NDIS_802_3_MAC_OPTION_PRIORITY 0x00000001 +#define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101 +#define OID_802_3_XMIT_ONE_COLLISION 0x01020102 +#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103 +#define OID_802_3_XMIT_DEFERRED 0x01020201 +#define OID_802_3_XMIT_MAX_COLLISIONS 0x01020202 +#define OID_802_3_RCV_OVERRUN 0x01020203 +#define OID_802_3_XMIT_UNDERRUN 0x01020204 +#define OID_802_3_XMIT_HEARTBEAT_FAILURE 0x01020205 +#define OID_802_3_XMIT_TIMES_CRS_LOST 0x01020206 +#define OID_802_3_XMIT_LATE_COLLISIONS 0x01020207 + +/* PnP and power management OIDs */ +#define OID_PNP_CAPABILITIES 0xFD010100 +#define OID_PNP_SET_POWER 0xFD010101 +#define OID_PNP_QUERY_POWER 0xFD010102 +#define OID_PNP_ADD_WAKE_UP_PATTERN 0xFD010103 +#define OID_PNP_REMOVE_WAKE_UP_PATTERN 0xFD010104 +#define OID_PNP_WAKE_UP_PATTERN_LIST 0xFD010105 +#define OID_PNP_ENABLE_WAKE_UP 0xFD010106 + +/* PnP/PM Statistics (Optional). */ +#define OID_PNP_WAKE_UP_OK 0xFD020200 +#define OID_PNP_WAKE_UP_ERROR 0xFD020201 + +/* The following bits are defined for OID_PNP_ENABLE_WAKE_UP */ +#define NDIS_PNP_WAKE_UP_MAGIC_PACKET 0x00000001 +#define NDIS_PNP_WAKE_UP_PATTERN_MATCH 0x00000002 +#define NDIS_PNP_WAKE_UP_LINK_CHANGE 0x00000004 + +/* 802.11 OIDs */ +#define OID_802_11_BSSID 0x0D010101 +#define OID_802_11_SSID 0x0D010102 +#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0D010203 +#define OID_802_11_NETWORK_TYPE_IN_USE 0x0D010204 +#define OID_802_11_TX_POWER_LEVEL 0x0D010205 +#define OID_802_11_RSSI 0x0D010206 +#define OID_802_11_RSSI_TRIGGER 0x0D010207 +#define OID_802_11_INFRASTRUCTURE_MODE 0x0D010108 +#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0D010209 +#define OID_802_11_RTS_THRESHOLD 0x0D01020A +#define OID_802_11_NUMBER_OF_ANTENNAS 0x0D01020B +#define OID_802_11_RX_ANTENNA_SELECTED 0x0D01020C +#define OID_802_11_TX_ANTENNA_SELECTED 0x0D01020D +#define OID_802_11_SUPPORTED_RATES 0x0D01020E +#define OID_802_11_DESIRED_RATES 0x0D010210 +#define OID_802_11_CONFIGURATION 0x0D010211 +#define OID_802_11_STATISTICS 0x0D020212 +#define OID_802_11_ADD_WEP 0x0D010113 +#define OID_802_11_REMOVE_WEP 0x0D010114 +#define OID_802_11_DISASSOCIATE 0x0D010115 +#define OID_802_11_POWER_MODE 0x0D010216 +#define OID_802_11_BSSID_LIST 0x0D010217 +#define OID_802_11_AUTHENTICATION_MODE 0x0D010118 +#define OID_802_11_PRIVACY_FILTER 0x0D010119 +#define OID_802_11_BSSID_LIST_SCAN 0x0D01011A +#define OID_802_11_WEP_STATUS 0x0D01011B +#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS +#define OID_802_11_RELOAD_DEFAULTS 0x0D01011C +#define OID_802_11_ADD_KEY 0x0D01011D +#define OID_802_11_REMOVE_KEY 0x0D01011E +#define OID_802_11_ASSOCIATION_INFORMATION 0x0D01011F +#define OID_802_11_TEST 0x0D010120 +#define OID_802_11_MEDIA_STREAM_MODE 0x0D010121 +#define OID_802_11_CAPABILITY 0x0D010122 +#define OID_802_11_PMKID 0x0D010123 + +#define NDIS_STATUS_SUCCESS 0 +#define NDIS_STATUS_PENDING 0x00000103 +#define NDIS_STATUS_NOT_RECOGNIZED 0x00010001 +#define NDIS_STATUS_NOT_COPIED 0x00010002 +#define NDIS_STATUS_NOT_ACCEPTED 0x00010003 +#define NDIS_STATUS_CALL_ACTIVE 0x00010007 +#define NDIS_STATUS_ONLINE 0x40010003 +#define NDIS_STATUS_RESET_START 0x40010004 +#define NDIS_STATUS_RESET_END 0x40010005 +#define NDIS_STATUS_RING_STATUS 0x40010006 +#define NDIS_STATUS_CLOSED 0x40010007 +#define NDIS_STATUS_WAN_LINE_UP 0x40010008 +#define NDIS_STATUS_WAN_LINE_DOWN 0x40010009 +#define NDIS_STATUS_WAN_FRAGMENT 0x4001000A +#define NDIS_STATUS_MEDIA_CONNECT 0x4001000B +#define NDIS_STATUS_MEDIA_DISCONNECT 0x4001000C +#define NDIS_STATUS_HARDWARE_LINE_UP 0x4001000D +#define NDIS_STATUS_HARDWARE_LINE_DOWN 0x4001000E +#define NDIS_STATUS_INTERFACE_UP 0x4001000F +#define NDIS_STATUS_INTERFACE_DOWN 0x40010010 +#define NDIS_STATUS_MEDIA_BUSY 0x40010011 +#define NDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012 +#define NDIS_STATUS_WW_INDICATION NDIS_STATUS_MEDIA_SPECIFIC_INDICATION +#define NDIS_STATUS_LINK_SPEED_CHANGE 0x40010013 +#define NDIS_STATUS_WAN_GET_STATS 0x40010014 +#define NDIS_STATUS_WAN_CO_FRAGMENT 0x40010015 +#define NDIS_STATUS_WAN_CO_LINKPARAMS 0x40010016 +#define NDIS_STATUS_NOT_RESETTABLE 0x80010001 +#define NDIS_STATUS_SOFT_ERRORS 0x80010003 +#define NDIS_STATUS_HARD_ERRORS 0x80010004 +#define NDIS_STATUS_BUFFER_OVERFLOW 0x80000005 +#define NDIS_STATUS_FAILURE 0xC0000001 +#define NDIS_STATUS_INVALID_PARAMETER 0xC000000D +#define NDIS_STATUS_RESOURCES 0xC000009A +#define NDIS_STATUS_CLOSING 0xC0010002 +#define NDIS_STATUS_BAD_VERSION 0xC0010004 +#define NDIS_STATUS_BAD_CHARACTERISTICS 0xC0010005 +#define NDIS_STATUS_ADAPTER_NOT_FOUND 0xC0010006 +#define NDIS_STATUS_OPEN_FAILED 0xC0010007 +#define NDIS_STATUS_DEVICE_FAILED 0xC0010008 +#define NDIS_STATUS_MULTICAST_FULL 0xC0010009 +#define NDIS_STATUS_MULTICAST_EXISTS 0xC001000A +#define NDIS_STATUS_MULTICAST_NOT_FOUND 0xC001000B +#define NDIS_STATUS_REQUEST_ABORTED 0xC001000C +#define NDIS_STATUS_RESET_IN_PROGRESS 0xC001000D +#define NDIS_STATUS_CLOSING_INDICATING 0xC001000E +#define NDIS_STATUS_BAD_VERSION 0xC0010004 +#define NDIS_STATUS_NOT_SUPPORTED 0xC00000BB +#define NDIS_STATUS_INVALID_PACKET 0xC001000F +#define NDIS_STATUS_OPEN_LIST_FULL 0xC0010010 +#define NDIS_STATUS_ADAPTER_NOT_READY 0xC0010011 +#define NDIS_STATUS_ADAPTER_NOT_OPEN 0xC0010012 +#define NDIS_STATUS_NOT_INDICATING 0xC0010013 +#define NDIS_STATUS_INVALID_LENGTH 0xC0010014 +#define NDIS_STATUS_INVALID_DATA 0xC0010015 +#define NDIS_STATUS_BUFFER_TOO_SHORT 0xC0010016 +#define NDIS_STATUS_INVALID_OID 0xC0010017 +#define NDIS_STATUS_ADAPTER_REMOVED 0xC0010018 +#define NDIS_STATUS_UNSUPPORTED_MEDIA 0xC0010019 +#define NDIS_STATUS_GROUP_ADDRESS_IN_USE 0xC001001A +#define NDIS_STATUS_FILE_NOT_FOUND 0xC001001B +#define NDIS_STATUS_ERROR_READING_FILE 0xC001001C +#define NDIS_STATUS_ALREADY_MAPPED 0xC001001D +#define NDIS_STATUS_RESOURCE_CONFLICT 0xC001001E +#define NDIS_STATUS_NO_CABLE 0xC001001F +#define NDIS_STATUS_INVALID_SAP 0xC0010020 +#define NDIS_STATUS_SAP_IN_USE 0xC0010021 +#define NDIS_STATUS_INVALID_ADDRESS 0xC0010022 +#define NDIS_STATUS_VC_NOT_ACTIVATED 0xC0010023 +#define NDIS_STATUS_DEST_OUT_OF_ORDER 0xC0010024 +#define NDIS_STATUS_VC_NOT_AVAILABLE 0xC0010025 +#define NDIS_STATUS_CELLRATE_NOT_AVAILABLE 0xC0010026 +#define NDIS_STATUS_INCOMPATABLE_QOS 0xC0010027 +#define NDIS_STATUS_AAL_PARAMS_UNSUPPORTED 0xC0010028 +#define NDIS_STATUS_NO_ROUTE_TO_DESTINATION 0xC0010029 +#define NDIS_STATUS_TOKEN_RING_OPEN_ERROR 0xC0011000 +#define NDIS_STATUS_INVALID_DEVICE_REQUEST 0xC0000010 +#define NDIS_STATUS_NETWORK_UNREACHABLE 0xC000023C + +/* Event codes */ + +#define EVENT_NDIS_RESOURCE_CONFLICT 0xC0001388 +#define EVENT_NDIS_OUT_OF_RESOURCE 0xC0001389 +#define EVENT_NDIS_HARDWARE_FAILURE 0xC000138A +#define EVENT_NDIS_ADAPTER_NOT_FOUND 0xC000138B +#define EVENT_NDIS_INTERRUPT_CONNECT 0xC000138C +#define EVENT_NDIS_DRIVER_FAILURE 0xC000138D +#define EVENT_NDIS_BAD_VERSION 0xC000138E +#define EVENT_NDIS_TIMEOUT 0x8000138F +#define EVENT_NDIS_NETWORK_ADDRESS 0xC0001390 +#define EVENT_NDIS_UNSUPPORTED_CONFIGURATION 0xC0001391 +#define EVENT_NDIS_INVALID_VALUE_FROM_ADAPTER 0xC0001392 +#define EVENT_NDIS_MISSING_CONFIGURATION_PARAMETER 0xC0001393 +#define EVENT_NDIS_BAD_IO_BASE_ADDRESS 0xC0001394 +#define EVENT_NDIS_RECEIVE_SPACE_SMALL 0x40001395 +#define EVENT_NDIS_ADAPTER_DISABLED 0x80001396 +#define EVENT_NDIS_IO_PORT_CONFLICT 0x80001397 +#define EVENT_NDIS_PORT_OR_DMA_CONFLICT 0x80001398 +#define EVENT_NDIS_MEMORY_CONFLICT 0x80001399 +#define EVENT_NDIS_INTERRUPT_CONFLICT 0x8000139A +#define EVENT_NDIS_DMA_CONFLICT 0x8000139B +#define EVENT_NDIS_INVALID_DOWNLOAD_FILE_ERROR 0xC000139C +#define EVENT_NDIS_MAXRECEIVES_ERROR 0x8000139D +#define EVENT_NDIS_MAXTRANSMITS_ERROR 0x8000139E +#define EVENT_NDIS_MAXFRAMESIZE_ERROR 0x8000139F +#define EVENT_NDIS_MAXINTERNALBUFS_ERROR 0x800013A0 +#define EVENT_NDIS_MAXMULTICAST_ERROR 0x800013A1 +#define EVENT_NDIS_PRODUCTID_ERROR 0x800013A2 +#define EVENT_NDIS_LOBE_FAILUE_ERROR 0x800013A3 +#define EVENT_NDIS_SIGNAL_LOSS_ERROR 0x800013A4 +#define EVENT_NDIS_REMOVE_RECEIVED_ERROR 0x800013A5 +#define EVENT_NDIS_TOKEN_RING_CORRECTION 0x400013A6 +#define EVENT_NDIS_ADAPTER_CHECK_ERROR 0xC00013A7 +#define EVENT_NDIS_RESET_FAILURE_ERROR 0x800013A8 +#define EVENT_NDIS_CABLE_DISCONNECTED_ERROR 0x800013A9 +#define EVENT_NDIS_RESET_FAILURE_CORRECTION 0x800013AA + +/* packet filter bits used by NDIS_OID_PACKET_FILTER */ +#define NDIS_PACKET_TYPE_DIRECTED 0x00000001 +#define NDIS_PACKET_TYPE_MULTICAST 0x00000002 +#define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004 +#define NDIS_PACKET_TYPE_BROADCAST 0x00000008 +#define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010 +#define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020 +#define NDIS_PACKET_TYPE_SMT 0x00000040 +#define NDIS_PACKET_TYPE_ALL_LOCAL 0x00000080 +#define NDIS_PACKET_TYPE_GROUP 0x00001000 +#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL 0x00002000 +#define NDIS_PACKET_TYPE_FUNCTIONAL 0x00004000 +#define NDIS_PACKET_TYPE_MAC_FRAME 0x00008000 + +/* memory allocation flags */ +#define NDIS_MEMORY_CONTIGUOUS 0x00000001 +#define NDIS_MEMORY_NONCACHED 0x00000002 + +/* Atrribute flags to NdisMSetAtrributesEx */ +#define NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT 0x00000001 +#define NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT 0x00000002 +#define NDIS_ATTRIBUTE_IGNORE_TOKEN_RING_ERRORS 0x00000004 +#define NDIS_ATTRIBUTE_BUS_MASTER 0x00000008 +#define NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER 0x00000010 +#define NDIS_ATTRIBUTE_DESERIALIZE 0x00000020 +#define NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND 0x00000040 +#define NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK 0x00000080 +#define NDIS_ATTRIBUTE_NOT_CO_NDIS 0x00000100 +#define NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS 0x00000200 + +#define OID_TCP_TASK_OFFLOAD 0xFC010201 + +#define NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA 0x00000001 +#define NDIS_MAC_OPTION_RECEIVE_SERIALIZED 0x00000002 +#define NDIS_MAC_OPTION_TRANSFERS_NOT_PEND 0x00000004 +#define NDIS_MAC_OPTION_NO_LOOPBACK 0x00000008 +#define NDIS_MAC_OPTION_FULL_DUPLEX 0x00000010 +#define NDIS_MAC_OPTION_EOTX_INDICATION 0x00000020 +#define NDIS_MAC_OPTION_8021P_PRIORITY 0x00000040 +#define NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE 0x00000080 +#define NDIS_MAC_OPTION_RECEIVE_AT_DPC 0x00000100 +#define NDIS_MAC_OPTION_8021Q_VLAN 0x00000200 +#define NDIS_MAC_OPTION_RESERVED 0x80000000 + +#define deserialized_driver(wnd) (wnd->attributes & NDIS_ATTRIBUTE_DESERIALIZE) + +static inline void serialize_lock(struct ndis_device *wnd) +{ + nt_spin_lock(&wnd->nmb->lock); +} + +static inline void serialize_unlock(struct ndis_device *wnd) +{ + nt_spin_unlock(&wnd->nmb->lock); +} + +static inline KIRQL serialize_lock_irql(struct ndis_device *wnd) +{ + if (deserialized_driver(wnd)) + return raise_irql(DISPATCH_LEVEL); + else + return nt_spin_lock_irql(&wnd->nmb->lock, DISPATCH_LEVEL); +} + +static inline void serialize_unlock_irql(struct ndis_device *wnd, + KIRQL irql) +{ + if (deserialized_driver(wnd)) + lower_irql(irql); + else + nt_spin_unlock_irql(&wnd->nmb->lock, irql); +} + +static inline void if_serialize_lock(struct ndis_device *wnd) +{ + if (!deserialized_driver(wnd)) + nt_spin_lock(&wnd->nmb->lock); +} + +static inline void if_serialize_unlock(struct ndis_device *wnd) +{ + if (!deserialized_driver(wnd)) + nt_spin_unlock(&wnd->nmb->lock); +} + +#endif /* NDIS_H */ --- linux-2.6.28.orig/ubuntu/ndiswrapper/hal.c +++ linux-2.6.28/ubuntu/ndiswrapper/hal.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ntoskernel.h" +#include "hal_exports.h" + +wstdcall void WIN_FUNC(WRITE_PORT_ULONG,2) + (ULONG_PTR port, ULONG value) +{ + outl(value, port); +} + +wstdcall ULONG WIN_FUNC(READ_PORT_ULONG,1) + (ULONG_PTR port) +{ + return inl(port); +} + +wstdcall void WIN_FUNC(WRITE_PORT_USHORT,2) + (ULONG_PTR port, USHORT value) +{ + outw(value, port); +} + +wstdcall USHORT WIN_FUNC(READ_PORT_USHORT,1) + (ULONG_PTR port) +{ + return inw(port); +} + +wstdcall void WIN_FUNC(WRITE_PORT_UCHAR,2) + (ULONG_PTR port, UCHAR value) +{ + outb(value, port); +} + +wstdcall UCHAR WIN_FUNC(READ_PORT_UCHAR,1) + (ULONG_PTR port) +{ + return inb(port); +} + +wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_USHORT,3) + (ULONG_PTR port, USHORT *buf, ULONG count) +{ + outsw(port, buf, count); +} + +wstdcall void WIN_FUNC(READ_PORT_BUFFER_USHORT,3) + (ULONG_PTR port, USHORT *buf, ULONG count) +{ + insw(port, buf, count); +} + +wstdcall void WIN_FUNC(WRITE_PORT_BUFFER_ULONG,3) + (ULONG_PTR port, ULONG *buf, ULONG count) +{ + outsl(port, buf, count); +} + +wstdcall void WIN_FUNC(READ_PORT_BUFFER_ULONG,3) + (ULONG_PTR port, ULONG *buf, ULONG count) +{ + insl(port, buf, count); +} + +wstdcall USHORT WIN_FUNC(READ_REGISTER_USHORT,1) + (void __iomem *reg) +{ + return readw(reg); +} + +wstdcall void WIN_FUNC(WRITE_REGISTER_ULONG,2) + (void __iomem *reg, UINT val) +{ + writel(val, reg); +} + +wstdcall void WIN_FUNC(WRITE_REGISTER_USHORT,2) + (void __iomem *reg, USHORT val) +{ + writew(val, reg); +} + +wstdcall void WIN_FUNC(WRITE_REGISTER_UCHAR,2) + (void __iomem *reg, UCHAR val) +{ + writeb(val, reg); +} + +wstdcall void WIN_FUNC(KeStallExecutionProcessor,1) + (ULONG usecs) +{ + udelay(usecs); +} + +wstdcall KIRQL WIN_FUNC(KeGetCurrentIrql,0) + (void) +{ + return current_irql(); +} + +wfastcall KIRQL WIN_FUNC(KfRaiseIrql,1) + (KIRQL newirql) +{ + return raise_irql(newirql); +} + +wfastcall void WIN_FUNC(KfLowerIrql,1) + (KIRQL oldirql) +{ + lower_irql(oldirql); +} + +wfastcall KIRQL WIN_FUNC(KfAcquireSpinLock,1) + (NT_SPIN_LOCK *lock) +{ + return nt_spin_lock_irql(lock, DISPATCH_LEVEL); +} + +wfastcall void WIN_FUNC(KfReleaseSpinLock,2) + (NT_SPIN_LOCK *lock, KIRQL oldirql) +{ + nt_spin_unlock_irql(lock, oldirql); +} + +wfastcall void WIN_FUNC(KefAcquireSpinLockAtDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ +#ifdef DEBUG_IRQL + if (current_irql() != DISPATCH_LEVEL) + ERROR("irql != DISPATCH_LEVEL"); +#endif + nt_spin_lock(lock); +} + +wfastcall void WIN_FUNC(KefReleaseSpinLockFromDpcLevel,1) + (NT_SPIN_LOCK *lock) +{ +#ifdef DEBUG_IRQL + if (current_irql() != DISPATCH_LEVEL) + ERROR("irql != DISPATCH_LEVEL"); +#endif + nt_spin_unlock(lock); +} --- linux-2.6.28.orig/ubuntu/ndiswrapper/lin2win.h +++ linux-2.6.28/ubuntu/ndiswrapper/lin2win.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2006 Giridhar Pemmasani + * + * 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. + * + */ + +#ifdef CONFIG_X86_64 + +/* Windows functions must have 32 bytes of shadow space for arguments + * above return address, irrespective of number of args. So argc >= 4 + */ + +#define alloc_win_stack_frame(argc) \ + "sub $(" #argc "+1)*8, %%rsp\n\t" +#define free_win_stack_frame(argc) \ + "add $(" #argc "+1)*8, %%rsp\n\t" + +/* m is index of Windows arg required; Windows arg 1 should be at + * 0(%rsp), arg 2 at 8(%rsp) and so on after the frame is allocated. +*/ + +#define lin2win_win_arg(m) "(" #m "-1)*8(%%rsp)" + +/* args for Windows function must be in clobber / output list */ + +#define outputs() \ + "=a" (_ret), "=c" (_dummy), "=d" (_dummy), \ + "=r" (r8), "=r" (r9), "=r" (r10), "=r" (r11) + +#define clobbers() "cc" + +#define LIN2WIN0(func) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8"); \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN1(func, arg1) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8"); \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN2(func, arg1, arg2) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8"); \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), "d" (arg2), [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN3(func, arg1, arg2, arg3) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9"); \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9") = (u64)arg4; \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(4) \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(4) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9") = (u64)arg4; \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(5) \ + "movq %[rarg5], " lin2win_win_arg(5) "\n\t" \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(5) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \ + [rarg5] "ri" ((u64)arg5), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + u64 _ret, _dummy; \ + register u64 r8 __asm__("r8") = (u64)arg3; \ + register u64 r9 __asm__("r9") = (u64)arg4; \ + register u64 r10 __asm__("r10"); \ + register u64 r11 __asm__("r11"); \ + __asm__ __volatile__( \ + alloc_win_stack_frame(6) \ + "movq %[rarg5], " lin2win_win_arg(5) "\n\t" \ + "movq %[rarg6], " lin2win_win_arg(6) "\n\t" \ + "callq *%[fptr]\n\t" \ + free_win_stack_frame(6) \ + : outputs() \ + : "c" (arg1), "d" (arg2), "r" (r8), "r" (r9), \ + [rarg5] "ri" ((u64)arg5), [rarg6] "ri" ((u64)arg6), \ + [fptr] "r" (func) \ + : clobbers()); \ + _ret; \ +}) + +#else // CONFIG_X86_64 + +#define LIN2WIN1(func, arg1) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1); \ +}) +#define LIN2WIN2(func, arg1, arg2) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2); \ +}) +#define LIN2WIN3(func, arg1, arg2, arg3) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3); \ +}) +#define LIN2WIN4(func, arg1, arg2, arg3, arg4) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3, arg4); \ +}) +#define LIN2WIN5(func, arg1, arg2, arg3, arg4, arg5) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3, arg4, arg5); \ +}) +#define LIN2WIN6(func, arg1, arg2, arg3, arg4, arg5, arg6) \ +({ \ + TRACE6("calling %p", func); \ + func(arg1, arg2, arg3, arg4, arg5, arg6); \ +}) + +#endif // CONFIG_X86_64 --- linux-2.6.28.orig/ubuntu/ndiswrapper/BOM +++ linux-2.6.28/ubuntu/ndiswrapper/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=93482 +Current Version: 1.53 --- linux-2.6.28.orig/ubuntu/ndiswrapper/pnp.c +++ linux-2.6.28/ubuntu/ndiswrapper/pnp.c @@ -0,0 +1,742 @@ +/* + * Copyright (C) 2005 Giridhar Pemmasani + * + * 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. + * + */ + +#include "usb.h" +#include "pnp.h" +#include "wrapndis.h" +#include "loader.h" + +/* Functions callable from the NDIS driver */ +wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo, + struct irp *irp); +wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp); +wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp); + +static NTSTATUS start_pdo(struct device_object *pdo) +{ + int i, ret, count, resources_size; + struct wrap_device *wd; + struct pci_dev *pdev; + struct cm_partial_resource_descriptor *entry; + struct cm_partial_resource_list *partial_resource_list; + + ENTER1("%p, %p", pdo, pdo->reserved); + wd = pdo->reserved; + if (ntoskernel_init_device(wd)) + EXIT1(return STATUS_FAILURE); + if (wrap_is_usb_bus(wd->dev_bus)) { +#ifdef ENABLE_USB + if (usb_init_device(wd)) { + ntoskernel_exit_device(wd); + EXIT1(return STATUS_FAILURE); + } +#endif + EXIT1(return STATUS_SUCCESS); + } + if (!wrap_is_pci_bus(wd->dev_bus)) + EXIT1(return STATUS_SUCCESS); + pdev = wd->pci.pdev; + ret = pci_enable_device(pdev); + if (ret) { + ERROR("couldn't enable PCI device: %x", ret); + return STATUS_FAILURE; + } + ret = pci_request_regions(pdev, DRIVER_NAME); + if (ret) { + ERROR("couldn't request PCI regions: %x", ret); + goto err_enable; + } + pci_set_power_state(pdev, PCI_D0); +#ifdef CONFIG_X86_64 + /* 64-bit broadcom driver doesn't work if DMA is allocated + * from over 1GB */ + if (wd->vendor == 0x14e4) { + if (pci_set_dma_mask(pdev, DMA_30BIT_MASK) || + pci_set_consistent_dma_mask(pdev, DMA_30BIT_MASK)) + WARNING("couldn't set DMA mask; this driver " + "may not work with more than 1GB RAM"); + } +#endif + /* IRQ resource entry is filled in from pdev, instead of + * pci_resource macros */ + for (i = count = 0; pci_resource_start(pdev, i); i++) + if ((pci_resource_flags(pdev, i) & IORESOURCE_MEM) || + (pci_resource_flags(pdev, i) & IORESOURCE_IO)) + count++; + /* space for entry for IRQ is already in + * cm_partial_resource_list */ + resources_size = sizeof(struct cm_resource_list) + + sizeof(struct cm_partial_resource_descriptor) * count; + TRACE2("resources: %d, %d", count, resources_size); + wd->resource_list = kzalloc(resources_size, GFP_KERNEL); + if (!wd->resource_list) { + WARNING("couldn't allocate memory"); + goto err_regions; + } + wd->resource_list->count = 1; + wd->resource_list->list[0].interface_type = PCIBus; + /* bus_number is not used by WDM drivers */ + wd->resource_list->list[0].bus_number = pdev->bus->number; + + partial_resource_list = + &wd->resource_list->list->partial_resource_list; + partial_resource_list->version = 1; + partial_resource_list->revision = 1; + partial_resource_list->count = count + 1; + + for (i = count = 0; pci_resource_start(pdev, i); i++) { + entry = &partial_resource_list->partial_descriptors[count]; + TRACE2("%d", count); + if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { + entry->type = CmResourceTypeMemory; + entry->flags = CM_RESOURCE_MEMORY_READ_WRITE; + entry->share = CmResourceShareDeviceExclusive; + } else if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { + entry->type = CmResourceTypePort; + entry->flags = CM_RESOURCE_PORT_IO; + entry->share = CmResourceShareDeviceExclusive; +#if 0 + } else if (pci_resource_flags(pdev, i) & IORESOURCE_DMA) { + /* it looks like no driver uses this resource */ + typeof(pci_resource_flags(pdev, 0)) flags; + entry->type = CmResourceTypeDma; + flags = pci_resource_flags(pdev, i); + if (flags & IORESOURCE_DMA_TYPEA) + entry->flags |= CM_RESOURCE_DMA_TYPE_A; + else if (flags & IORESOURCE_DMA_TYPEB) + entry->flags |= CM_RESOURCE_DMA_TYPE_B; + else if (flags & IORESOURCE_DMA_TYPEF) + entry->flags |= CM_RESOURCE_DMA_TYPE_F; + if (flags & IORESOURCE_DMA_8BIT) + entry->flags |= CM_RESOURCE_DMA_8; + else if (flags & IORESOURCE_DMA_16BIT) + entry->flags |= CM_RESOURCE_DMA_16; + /* what about 32bit DMA? */ + else if (flags & IORESOURCE_DMA_8AND16BIT) + entry->flags |= CM_RESOURCE_DMA_8_AND_16; + if (flags & IORESOURCE_DMA_MASTER) + entry->flags |= CM_RESOURCE_DMA_BUS_MASTER; + entry->u.dma.channel = pci_resource_start(pdev, i); + /* what should this be? */ + entry->u.dma.port = 1; +#endif + } else + continue; + /* TODO: Add other resource types? */ + entry->u.generic.start = + (ULONG_PTR)pci_resource_start(pdev, i); + entry->u.generic.length = pci_resource_len(pdev, i); + count++; + } + + /* put IRQ resource at the end */ + entry = &partial_resource_list->partial_descriptors[count++]; + entry->type = CmResourceTypeInterrupt; + entry->flags = CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE; + /* we assume all devices use shared IRQ */ + entry->share = CmResourceShareShared; + /* as per documentation, interrupt level should be DIRQL, but + * examples from DDK as well some drivers, such as AR5211, + * RT8180L use interrupt level as interrupt vector also in + * NdisMRegisterInterrupt */ + entry->u.interrupt.level = pdev->irq; + entry->u.interrupt.vector = pdev->irq; + entry->u.interrupt.affinity = -1; + + TRACE2("resource list count %d, irq: %d", + partial_resource_list->count, pdev->irq); + pci_set_drvdata(pdev, wd); + EXIT1(return STATUS_SUCCESS); +err_regions: + pci_release_regions(pdev); +err_enable: + pci_disable_device(pdev); + wd->pci.pdev = NULL; + wd->pdo = NULL; + EXIT1(return STATUS_FAILURE); +} + +static void remove_pdo(struct device_object *pdo) +{ + struct wrap_device *wd = pdo->reserved; + + ntoskernel_exit_device(wd); + if (wrap_is_pci_bus(wd->dev_bus)) { + struct pci_dev *pdev = wd->pci.pdev; + pci_release_regions(pdev); + pci_disable_device(pdev); + wd->pci.pdev = NULL; + pci_set_drvdata(pdev, NULL); + } else if (wrap_is_usb_bus(wd->dev_bus)) { +#ifdef ENABLE_USB + usb_exit_device(wd); +#endif + } + if (wd->resource_list) + kfree(wd->resource_list); + wd->resource_list = NULL; + return; +} + +static NTSTATUS IoSendIrpTopDev(struct device_object *dev_obj, ULONG major_fn, + ULONG minor_fn, struct io_stack_location *sl) +{ + NTSTATUS status; + struct nt_event event; + struct irp *irp; + struct io_stack_location *irp_sl; + struct device_object *top_dev = IoGetAttachedDeviceReference(dev_obj); + + KeInitializeEvent(&event, NotificationEvent, FALSE); + irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP, top_dev, NULL, 0, NULL, + &event, NULL); + irp->io_status.status = STATUS_NOT_IMPLEMENTED; + irp->io_status.info = 0; + irp_sl = IoGetNextIrpStackLocation(irp); + if (sl) + memcpy(irp_sl, sl, sizeof(*irp_sl)); + irp_sl->major_fn = major_fn; + irp_sl->minor_fn = minor_fn; + status = IoCallDriver(top_dev, irp); + if (status == STATUS_PENDING) { + KeWaitForSingleObject(&event, Executive, KernelMode, + FALSE, NULL); + status = irp->io_status.status; + } + ObDereferenceObject(top_dev); + return status; +} + +wstdcall NTSTATUS pdoDispatchDeviceControl(struct device_object *pdo, + struct irp *irp) +{ + struct io_stack_location *irp_sl; + NTSTATUS status; + + DUMP_IRP(irp); + irp_sl = IoGetCurrentIrpStackLocation(irp); +#ifdef ENABLE_USB + status = wrap_submit_irp(pdo, irp); + IOTRACE("status: %08X", status); + if (status != STATUS_PENDING) + IoCompleteRequest(irp, IO_NO_INCREMENT); +#else + status = irp->io_status.status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(irp, IO_NO_INCREMENT); +#endif + IOEXIT(return status); +} +WIN_FUNC_DECL(pdoDispatchDeviceControl,2) + +wstdcall NTSTATUS pdoDispatchPnp(struct device_object *pdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct wrap_device *wd; + NTSTATUS status; +#ifdef ENABLE_USB + struct usbd_bus_interface_usbdi *usb_intf; +#endif + + irp_sl = IoGetCurrentIrpStackLocation(irp); + TRACE2("%p %d:%d", pdo, irp_sl->major_fn, irp_sl->minor_fn); + wd = pdo->reserved; + switch (irp_sl->minor_fn) { + case IRP_MN_START_DEVICE: + status = start_pdo(pdo); + break; + case IRP_MN_QUERY_STOP_DEVICE: + case IRP_MN_STOP_DEVICE: + case IRP_MN_QUERY_REMOVE_DEVICE: + status = STATUS_SUCCESS; + break; + case IRP_MN_REMOVE_DEVICE: + remove_pdo(pdo); + status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_INTERFACE: +#ifdef ENABLE_USB + if (!wrap_is_usb_bus(wd->dev_bus)) { + status = STATUS_NOT_IMPLEMENTED; + break; + } + TRACE2("type: %x, size: %d, version: %d", + irp_sl->params.query_intf.type->data1, + irp_sl->params.query_intf.size, + irp_sl->params.query_intf.version); + usb_intf = (struct usbd_bus_interface_usbdi *) + irp_sl->params.query_intf.intf; + usb_intf->Context = wd; + usb_intf->InterfaceReference = USBD_InterfaceReference; + usb_intf->InterfaceDereference = USBD_InterfaceDereference; + usb_intf->GetUSBDIVersion = USBD_InterfaceGetUSBDIVersion; + usb_intf->QueryBusTime = USBD_InterfaceQueryBusTime; + usb_intf->SubmitIsoOutUrb = USBD_InterfaceSubmitIsoOutUrb; + usb_intf->QueryBusInformation = + USBD_InterfaceQueryBusInformation; + if (irp_sl->params.query_intf.version >= + USB_BUSIF_USBDI_VERSION_1) + usb_intf->IsDeviceHighSpeed = + USBD_InterfaceIsDeviceHighSpeed; + if (irp_sl->params.query_intf.version >= + USB_BUSIF_USBDI_VERSION_2) + usb_intf->LogEntry = USBD_InterfaceLogEntry; + status = STATUS_SUCCESS; +#else + status = STATUS_NOT_IMPLEMENTED; +#endif + break; + default: + TRACE2("fn %d not implemented", irp_sl->minor_fn); + status = STATUS_SUCCESS; + break; + } + irp->io_status.status = status; + TRACE2("status: %08X", status); + IoCompleteRequest(irp, IO_NO_INCREMENT); + IOEXIT(return status); +} +WIN_FUNC_DECL(pdoDispatchPnp,2) + +wstdcall NTSTATUS pdoDispatchPower(struct device_object *pdo, struct irp *irp) +{ + struct io_stack_location *irp_sl; + struct wrap_device *wd; + union power_state power_state; + struct pci_dev *pdev; + NTSTATUS status; + + irp_sl = IoGetCurrentIrpStackLocation(irp); + wd = pdo->reserved; + TRACE2("pdo: %p, fn: %d:%d, wd: %p", + pdo, irp_sl->major_fn, irp_sl->minor_fn, wd); + switch (irp_sl->minor_fn) { + case IRP_MN_WAIT_WAKE: + /* TODO: this is not complete/correct */ + TRACE2("state: %d, completion: %p", + irp_sl->params.power.state.system_state, + irp_sl->completion_routine); + IoMarkIrpPending(irp); + status = STATUS_PENDING; + break; + case IRP_MN_SET_POWER: + power_state = irp_sl->params.power.state; + if (power_state.device_state == PowerDeviceD0) { + TRACE2("resuming %p", wd); + if (wrap_is_pci_bus(wd->dev_bus)) { + pdev = wd->pci.pdev; + pci_restore_state(pdev); + if (wd->pci.wake_state == PowerDeviceD3) { + pci_enable_wake(wd->pci.pdev, + PCI_D3hot, 0); + pci_enable_wake(wd->pci.pdev, + PCI_D3cold, 0); + } + pci_set_power_state(pdev, PCI_D0); + } else { // usb device +#ifdef ENABLE_USB + wrap_resume_urbs(wd); +#endif + } + } else { + TRACE2("suspending device %p", wd); + if (wrap_is_pci_bus(wd->dev_bus)) { + pdev = wd->pci.pdev; + pci_save_state(pdev); + TRACE2("%d", wd->pci.wake_state); + if (wd->pci.wake_state == PowerDeviceD3) { + pci_enable_wake(wd->pci.pdev, + PCI_D3hot, 1); + pci_enable_wake(wd->pci.pdev, + PCI_D3cold, 1); + } + pci_set_power_state(pdev, PCI_D3hot); + } else { // usb device +#ifdef ENABLE_USB + wrap_suspend_urbs(wd); +#endif + } + } + status = STATUS_SUCCESS; + break; + case IRP_MN_QUERY_POWER: + status = STATUS_SUCCESS; + break; + default: + TRACE2("fn %d not implemented", irp_sl->minor_fn); + status = STATUS_SUCCESS; + break; + } + irp->io_status.status = status; + IoCompleteRequest(irp, IO_NO_INCREMENT); + return status; +} +WIN_FUNC_DECL(pdoDispatchPower,2) + +static NTSTATUS pnp_set_device_power_state(struct wrap_device *wd, + enum device_power_state state) +{ + NTSTATUS status; + struct device_object *pdo; + struct io_stack_location irp_sl; + + pdo = wd->pdo; + IOTRACE("%p, %p", pdo, IoGetAttachedDevice(pdo)); + memset(&irp_sl, 0, sizeof(irp_sl)); + irp_sl.params.power.state.device_state = state; + irp_sl.params.power.type = DevicePowerState; + if (state > PowerDeviceD0) { + status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_QUERY_POWER, + &irp_sl); + if (status != STATUS_SUCCESS) { + TRACE1("query of power to %d returns %08X", + state, status); + EXIT1(return status); + } + } + status = IoSendIrpTopDev(pdo, IRP_MJ_POWER, IRP_MN_SET_POWER, &irp_sl); + if (status != STATUS_SUCCESS) + WARNING("setting power to %d failed: %08X", state, status); + EXIT1(return status); +} + +NTSTATUS pnp_start_device(struct wrap_device *wd) +{ + struct device_object *fdo; + struct device_object *pdo; + struct io_stack_location irp_sl; + NTSTATUS status; + + pdo = wd->pdo; + /* TODO: for now we use same resources for both translated + * resources and raw resources */ + memset(&irp_sl, 0, sizeof(irp_sl)); + irp_sl.params.start_device.allocated_resources = + wd->resource_list; + irp_sl.params.start_device.allocated_resources_translated = + wd->resource_list; + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_START_DEVICE, &irp_sl); + fdo = IoGetAttachedDevice(pdo); + if (status == STATUS_SUCCESS) + fdo->drv_obj->drv_ext->count++; + else + WARNING("Windows driver couldn't initialize the device (%08X)", + status); + EXIT1(return status); +} + +NTSTATUS pnp_stop_device(struct wrap_device *wd) +{ + struct device_object *pdo; + NTSTATUS status; + + pdo = wd->pdo; + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_STOP_DEVICE, + NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + /* for now we ignore query status */ + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_STOP_DEVICE, NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + EXIT2(return status); +} + +NTSTATUS pnp_remove_device(struct wrap_device *wd) +{ + struct device_object *pdo, *fdo; + struct driver_object *fdo_drv_obj; + NTSTATUS status; + + pdo = wd->pdo; + fdo = IoGetAttachedDevice(pdo); + fdo_drv_obj = fdo->drv_obj; + TRACE2("%p, %p, %p", pdo, fdo, fdo_drv_obj); + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_QUERY_REMOVE_DEVICE, + NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + + status = IoSendIrpTopDev(pdo, IRP_MJ_PNP, IRP_MN_REMOVE_DEVICE, NULL); + if (status != STATUS_SUCCESS) + WARNING("status: %08X", status); + /* TODO: should we use count in drv_ext or driver's Object + * header reference count to keep count of devices associated + * with a driver? */ + if (status == STATUS_SUCCESS) + fdo_drv_obj->drv_ext->count--; + TRACE1("count: %d", fdo_drv_obj->drv_ext->count); + if (fdo_drv_obj->drv_ext->count < 0) + WARNING("wrong count: %d", fdo_drv_obj->drv_ext->count); + if (fdo_drv_obj->drv_ext->count == 0) { + struct wrap_driver *wrap_driver; + TRACE1("unloading driver: %p", fdo_drv_obj); + wrap_driver = + IoGetDriverObjectExtension(fdo_drv_obj, + (void *)WRAP_DRIVER_CLIENT_ID); + if (fdo_drv_obj->unload) + LIN2WIN1(fdo_drv_obj->unload, fdo_drv_obj); + if (wrap_driver) { + if (down_interruptible(&loader_mutex)) + WARNING("couldn't obtain loader_mutex"); + unload_wrap_driver(wrap_driver); + up(&loader_mutex); + } else + ERROR("couldn't get wrap_driver"); + ObDereferenceObject(fdo_drv_obj); + } + IoDeleteDevice(pdo); + unload_wrap_device(wd); + EXIT1(return status); +} + +WIN_FUNC_DECL(IoInvalidDeviceRequest,2) + +static struct device_object *alloc_pdo(struct driver_object *drv_obj) +{ + struct device_object *pdo; + NTSTATUS status ; + int i; + struct ansi_string ansi_name; + struct unicode_string unicode_name; + + RtlInitAnsiString(&ansi_name, "NDISpdo"); + if (RtlAnsiStringToUnicodeString(&unicode_name, &ansi_name, TRUE) == + STATUS_SUCCESS) { + status = IoCreateDevice(drv_obj, 0, &unicode_name, + FILE_DEVICE_UNKNOWN, + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &pdo); + RtlFreeUnicodeString(&unicode_name); + } else { + status = IoCreateDevice(drv_obj, 0, NULL, + FILE_DEVICE_UNKNOWN, + FILE_AUTOGENERATED_DEVICE_NAME, + FALSE, &pdo); + } + TRACE1("%p, %d, %p", drv_obj, status, pdo); + if (status != STATUS_SUCCESS) + return NULL; + /* dispatch routines are called as Windows functions */ + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + drv_obj->major_func[i] = WIN_FUNC_PTR(IoInvalidDeviceRequest,2); + drv_obj->major_func[IRP_MJ_INTERNAL_DEVICE_CONTROL] = + WIN_FUNC_PTR(pdoDispatchDeviceControl,2); + drv_obj->major_func[IRP_MJ_DEVICE_CONTROL] = + WIN_FUNC_PTR(pdoDispatchDeviceControl,2); + drv_obj->major_func[IRP_MJ_POWER] = WIN_FUNC_PTR(pdoDispatchPower,2); + drv_obj->major_func[IRP_MJ_PNP] = WIN_FUNC_PTR(pdoDispatchPnp,2); + return pdo; +} + +static int wrap_pnp_start_device(struct wrap_device *wd) +{ + struct wrap_driver *driver; + struct device_object *pdo; + struct driver_object *pdo_drv_obj; + + ENTER1("wd: %p", wd); + + if (!((wrap_is_pci_bus(wd->dev_bus)) || + (wrap_is_usb_bus(wd->dev_bus)))) { + ERROR("bus type %d (%d) not supported", + WRAP_BUS(wd->dev_bus), wd->dev_bus); + EXIT1(return -EINVAL); + } + driver = load_wrap_driver(wd); + if (!driver) + return -ENODEV; + + wd->driver = driver; + wd->dev_bus = WRAP_DEVICE_BUS(driver->dev_type, WRAP_BUS(wd->dev_bus)); + TRACE1("dev type: %d, bus type: %d, %d", WRAP_DEVICE(wd->dev_bus), + WRAP_BUS(wd->dev_bus), wd->dev_bus); + TRACE1("%d, %d", driver->dev_type, wrap_is_usb_bus(wd->dev_bus)); + /* first create pdo */ + if (wrap_is_pci_bus(wd->dev_bus)) + pdo_drv_obj = find_bus_driver("PCI"); + else // if (wrap_is_usb_bus(wd->dev_bus)) + pdo_drv_obj = find_bus_driver("USB"); + if (!pdo_drv_obj) + return -EINVAL; + pdo = alloc_pdo(pdo_drv_obj); + if (!pdo) + return -ENOMEM; + wd->pdo = pdo; + pdo->reserved = wd; + if (WRAP_DEVICE(wd->dev_bus) == WRAP_NDIS_DEVICE) { + if (init_ndis_driver(driver->drv_obj)) { + IoDeleteDevice(pdo); + return -EINVAL; + } + } + TRACE1("%p", driver->drv_obj->drv_ext->add_device); + if (driver->drv_obj->drv_ext->add_device(driver->drv_obj, pdo) != + STATUS_SUCCESS) { + IoDeleteDevice(pdo); + return -ENOMEM; + } + if (pnp_start_device(wd) != STATUS_SUCCESS) { + /* TODO: we need proper cleanup, to deallocate memory, + * for example */ + pnp_remove_device(wd); + return -EINVAL; + } + return 0; +} + +/* + * This function should not be marked __devinit because PCI IDs are + * added dynamically. + */ +int wrap_pnp_start_pci_device(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct load_device load_device; + struct wrap_device *wd; + + ENTER1("called for %04x:%04x:%04x:%04x", pdev->vendor, pdev->device, + pdev->subsystem_vendor, pdev->subsystem_device); + + load_device.bus = WRAP_PCI_BUS; + load_device.vendor = pdev->vendor; + load_device.device = pdev->device; + load_device.subvendor = pdev->subsystem_vendor; + load_device.subdevice = pdev->subsystem_device; + wd = load_wrap_device(&load_device); + if (!wd) + EXIT1(return -ENODEV); + wd->pci.pdev = pdev; + return wrap_pnp_start_device(wd); +} + +void wrap_pnp_remove_pci_device(struct pci_dev *pdev) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)pci_get_drvdata(pdev); + ENTER1("%p, %p", pdev, wd); + if (!wd) + EXIT1(return); + pnp_remove_device(wd); +} + +int wrap_pnp_suspend_pci_device(struct pci_dev *pdev, pm_message_t state) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)pci_get_drvdata(pdev); + return pnp_set_device_power_state(wd, PowerDeviceD3); +} + +int wrap_pnp_resume_pci_device(struct pci_dev *pdev) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)pci_get_drvdata(pdev); + return pnp_set_device_power_state(wd, PowerDeviceD0); +} + +#ifdef ENABLE_USB +int wrap_pnp_start_usb_device(struct usb_interface *intf, + const struct usb_device_id *usb_id) +{ + struct wrap_device *wd; + int ret; + struct usb_device *udev = interface_to_usbdev(intf); + ENTER1("%04x, %04x, %04x", udev->descriptor.idVendor, + udev->descriptor.idProduct, udev->descriptor.bDeviceClass); + + /* USB device (e.g., RNDIS) may have multiple interfaces; + initialize one interface only (is there a way to know which + of these interfaces is for network?) */ + + if ((wd = get_wrap_device(udev, WRAP_USB_BUS))) { + TRACE1("device already initialized: %p", wd); + usb_set_intfdata(intf, NULL); + ret = 0; + } else { + struct load_device load_device; + + load_device.bus = WRAP_USB_BUS; + load_device.vendor = le16_to_cpu(udev->descriptor.idVendor); + load_device.device = le16_to_cpu(udev->descriptor.idProduct); + load_device.subvendor = 0; + load_device.subdevice = 0; + wd = load_wrap_device(&load_device); + TRACE2("%p", wd); + if (wd) { + /* some devices (e.g., TI 4150, RNDIS) need + * full reset */ + ret = usb_reset_device(udev); + if (ret) + WARNING("reset failed: %d", ret); + usb_set_intfdata(intf, wd); + wd->usb.intf = intf; + wd->usb.udev = udev; + ret = wrap_pnp_start_device(wd); + } else + ret = -ENODEV; + } + + TRACE2("ret: %d", ret); + if (ret) + EXIT1(return ret); + else + return 0; +} + +void __devexit wrap_pnp_remove_usb_device(struct usb_interface *intf) +{ + struct wrap_device *wd; + + wd = (struct wrap_device *)usb_get_intfdata(intf); + TRACE1("%p, %p", intf, wd); + if (wd == NULL) + EXIT1(return); + usb_set_intfdata(intf, NULL); + wd->usb.intf = NULL; + pnp_remove_device(wd); +} + +int wrap_pnp_suspend_usb_device(struct usb_interface *intf, pm_message_t state) +{ + struct wrap_device *wd; + struct device_object *pdo; + + wd = usb_get_intfdata(intf); + ENTER1("%p, %p", intf, wd); + if (!wd) + EXIT1(return 0); + pdo = wd->pdo; + if (pnp_set_device_power_state(wd, PowerDeviceD3)) + return -1; + return 0; +} + +int wrap_pnp_resume_usb_device(struct usb_interface *intf) +{ + struct wrap_device *wd; + wd = usb_get_intfdata(intf); + ENTER1("%p, %p", intf, wd); + if (!wd) + EXIT1(return 0); + if (pnp_set_device_power_state(wd, PowerDeviceD0)) + return -1; + return 0; +} + +#endif // USB --- linux-2.6.28.orig/ubuntu/ndiswrapper/ndiswrapper.h +++ linux-2.6.28/ubuntu/ndiswrapper/ndiswrapper.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#ifndef _NDISWRAPPER_H_ +#define _NDISWRAPPER_H_ + +#define DRIVER_VERSION "1.53" +#define UTILS_VERSION "1.9" + +#define DRIVER_NAME "ndiswrapper" +#define DRIVER_CONFIG_DIR "/etc/ndiswrapper" + +#define SSID_MAX_WPA_IE_LEN 40 +#define NDIS_ESSID_MAX_SIZE 32 +#define NDIS_ENCODING_TOKEN_MAX 32 +#define MAX_ENCR_KEYS 4 +#define TX_RING_SIZE 16 +#define NDIS_MAX_RATES 8 +#define NDIS_MAX_RATES_EX 16 +#define WLAN_EID_GENERIC 221 +#define MAX_WPA_IE_LEN 64 +#define MAX_STR_LEN 512 + +#define WRAP_PCI_BUS 5 +#define WRAP_PCMCIA_BUS 8 +/* some USB devices, e.g., DWL-G120 have BusType as 0 */ +#define WRAP_INTERNAL_BUS 0 +/* documentation at msdn says 15 is PNP bus, but inf files from all + * vendors say 15 is USB; which is correct? */ +#define WRAP_USB_BUS 15 + +/* NDIS device must be 0, for compatability with old versions of + * ndiswrapper where device type for NDIS drivers is 0 */ +#define WRAP_NDIS_DEVICE 0 +#define WRAP_USB_DEVICE 1 +#define WRAP_BLUETOOTH_DEVICE1 2 +#define WRAP_BLUETOOTH_DEVICE2 3 + +#define WRAP_DEVICE_BUS(dev, bus) ((dev) << 8 | (bus)) +#define WRAP_BUS(dev_bus) ((dev_bus) & 0x000FF) +#define WRAP_DEVICE(dev_bus) ((dev_bus) >> 8) + +#define MAX_DRIVER_NAME_LEN 32 +#define MAX_VERSION_STRING_LEN 64 +#define MAX_SETTING_NAME_LEN 128 +#define MAX_SETTING_VALUE_LEN 256 + +#define MAX_DRIVER_PE_IMAGES 4 +#define MAX_DRIVER_BIN_FILES 5 +#define MAX_DEVICE_SETTINGS 512 + +#define MAX_ALLOCATED_URBS 15 + +#define DEV_ANY_ID -1 + +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTRSEP "%02x:%02x:%02x:%02x:%02x:%02x" +#define MACSTR "%02x%02x%02x%02x%02x%02x" +#define MACINTADR(a) (int*)&((a)[0]), (int*)&((a)[1]), (int*)&((a)[2]), \ + (int*)&((a)[3]), (int*)&((a)[4]), (int*)&((a)[5]) + +#ifdef __KERNEL__ +/* DEBUG macros */ + +#define MSG(level, fmt, ...) \ + printk(level "ndiswrapper (%s:%d): " fmt "\n", \ + __FUNCTION__, __LINE__ , ## __VA_ARGS__) + +#define WARNING(fmt, ...) MSG(KERN_WARNING, fmt, ## __VA_ARGS__) +#define ERROR(fmt, ...) MSG(KERN_ERR, fmt , ## __VA_ARGS__) +#define INFO(fmt, ...) MSG(KERN_INFO, fmt , ## __VA_ARGS__) +#define TODO() WARNING("not fully implemented (yet)") + +#define TRACE(fmt, ...) do { } while (0) +#define TRACE1(fmt, ...) do { } while (0) +#define TRACE2(fmt, ...) do { } while (0) +#define TRACE3(fmt, ...) do { } while (0) +#define TRACE4(fmt, ...) do { } while (0) +#define TRACE5(fmt, ...) do { } while (0) +#define TRACE6(fmt, ...) do { } while (0) + +/* for a block of code */ +#define DBG_BLOCK(level) while (0) + +extern int debug; + +#if defined DEBUG +#undef TRACE +#define TRACE(level, fmt, ...) \ +do { \ + if (debug >= level) \ + printk(KERN_INFO "%s (%s:%d): " fmt "\n", DRIVER_NAME, \ + __FUNCTION__, __LINE__ , ## __VA_ARGS__); \ +} while (0) +#undef DBG_BLOCK +#define DBG_BLOCK(level) if (debug >= level) +#endif + +#if defined(DEBUG) && DEBUG >= 1 +#undef TRACE1 +#define TRACE1(fmt, ...) TRACE(1, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 2 +#undef TRACE2 +#define TRACE2(fmt, ...) TRACE(2, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 3 +#undef TRACE3 +#define TRACE3(fmt, ...) TRACE(3, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 4 +#undef TRACE4 +#define TRACE4(fmt, ...) TRACE(4, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 5 +#undef TRACE5 +#define TRACE5(fmt, ...) TRACE(5, fmt , ## __VA_ARGS__) +#endif + +#if defined(DEBUG) && DEBUG >= 6 +#undef TRACE6 +#define TRACE6(fmt, ...) TRACE(6, fmt , ## __VA_ARGS__) +#endif + +#define ENTER1(fmt, ...) TRACE1("Enter " fmt , ## __VA_ARGS__) +#define ENTER2(fmt, ...) TRACE2("Enter " fmt , ## __VA_ARGS__) +#define ENTER3(fmt, ...) TRACE3("Enter " fmt , ## __VA_ARGS__) +#define ENTER4(fmt, ...) TRACE4("Enter " fmt , ## __VA_ARGS__) +#define ENTER5(fmt, ...) TRACE5("Enter " fmt , ## __VA_ARGS__) +#define ENTER6(fmt, ...) TRACE6("Enter " fmt , ## __VA_ARGS__) + +#define EXIT1(stmt) do { TRACE1("Exit"); stmt; } while(0) +#define EXIT2(stmt) do { TRACE2("Exit"); stmt; } while(0) +#define EXIT3(stmt) do { TRACE3("Exit"); stmt; } while(0) +#define EXIT4(stmt) do { TRACE4("Exit"); stmt; } while(0) +#define EXIT5(stmt) do { TRACE5("Exit"); stmt; } while(0) +#define EXIT6(stmt) do { TRACE6("Exit"); stmt; } while(0) + +#if defined(USB_DEBUG) +#define USBTRACE TRACE1 +#define USBENTER ENTER1 +#define USBEXIT EXIT1 +#else +#define USBTRACE(fmt, ...) +#define USBENTER(fmt, ...) +#define USBEXIT(stmt) stmt +#endif + +#if defined(EVENT_DEBUG) +#define EVENTTRACE TRACE1 +#define EVENTENTER ENTER1 +#define EVENTEXIT EXIT1 +#else +#define EVENTTRACE(fmt, ...) +#define EVENTENTER(fmt, ...) +#define EVENTEXIT(stmt) stmt +#endif + +#if defined(TIMER_DEBUG) +#define TIMERTRACE TRACE1 +#define TIMERENTER ENTER1 +#define TIMEREXIT EXIT1 +#else +#define TIMERTRACE(fmt, ...) +#define TIMERENTER(fmt, ...) +#define TIMEREXIT(stmt) stmt +#endif + +#if defined(IO_DEBUG) +#define IOTRACE TRACE1 +#define IOENTER ENTER1 +#define IOEXIT EXIT1 +#else +#define IOTRACE(fmt, ...) +#define IOENTER(fmt, ...) +#define IOEXIT(stmt) stmt +#endif + +#if defined(WORK_DEBUG) +#define WORKTRACE TRACE1 +#define WORKENTER ENTER1 +#define WORKEXIT EXIT1 +#else +#define WORKTRACE(fmt, ...) +#define WORKENTER(fmt, ...) +#define WORKEXIT(stmt) stmt +#endif + +#ifdef DEBUG +#define assert(expr) \ +do { \ + if (!(expr)) { \ + ERROR("assertion '%s' failed", #expr); \ + dump_stack(); \ + } \ +} while (0) +#else +#define assert(expr) do { } while (0) +#endif + +#endif // __KERNEL__ + +#endif // NDISWRAPPER_H --- linux-2.6.28.orig/ubuntu/ndiswrapper/rtl.c +++ linux-2.6.28/ubuntu/ndiswrapper/rtl.c @@ -0,0 +1,716 @@ +/* + * Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani + * + * 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. + * + */ + +#include "ntoskernel.h" +#include "rtl_exports.h" + +wstdcall SIZE_T WIN_FUNC(RtlCompareMemory,3) + (const void *a, const void *b, SIZE_T len) +{ + size_t i; + char *x, *y; + + x = (char *)a; + y = (char *)b; + /* MSDN says this should return number of bytes that compare as + * equal. This can be interpretted as either all bytes that are + * equal in 'len' bytes or that only until the bytes compare as + * not equal. Initially we had it the former way, but Realtek driver + * doesn't like it that way - it takes many attempts to associate + * with WPA. ReactOS returns the number of bytes that are equal + * upto when they compare as not equal. + * According to lords at #reactos, that is the way it should be + * and that msdn is wrong about it! + */ + for (i = 0; i < len && x[i] == y[i]; i++) + ; + return i; +} + +wstdcall void WIN_FUNC(RtlCopyMemory,3) + (void *dst, const void *src, SIZE_T length) +{ + memcpy(dst, src, length); +} + +wstdcall void WIN_FUNC(RtlZeroMemory,2) + (void *dst, SIZE_T length) +{ + memset(dst, 0, length); +} + +wstdcall void WIN_FUNC(RtlSecureZeroMemory,2) + (void *dst, SIZE_T length) +{ + memset(dst, 0, length); +} + +wstdcall void WIN_FUNC(RtlFillMemory,3) + (void *dest, SIZE_T length, UCHAR fill) +{ + memset(dest, fill, length); +} + +wstdcall void WIN_FUNC(RtlMoveMemory,3) + (void *dest, const void *src, SIZE_T length) +{ + memmove(dest, src, length); +} + +wstdcall LONG WIN_FUNC(RtlCompareString,3) + (const struct ansi_string *s1, const struct ansi_string *s2, + BOOLEAN case_insensitive) +{ + unsigned int len; + LONG ret = 0; + const char *p1, *p2; + + ENTER2(""); + len = min(s1->length, s2->length); + p1 = s1->buf; + p2 = s2->buf; + if (case_insensitive) + while (!ret && len--) + ret = toupper(*p1++) - toupper(*p2++); + else + while (!ret && len--) + ret = *p1++ - *p2++; + if (!ret) + ret = s1->length - s2->length; + EXIT2(return ret); +} + +wstdcall LONG WIN_FUNC(RtlCompareUnicodeString,3) + (const struct unicode_string *s1, const struct unicode_string *s2, + BOOLEAN case_insensitive) +{ + unsigned int len; + LONG ret = 0; + const wchar_t *p1, *p2; + + ENTER2(""); + + len = min(s1->length, s2->length) / sizeof(wchar_t); + p1 = s1->buf; + p2 = s2->buf; + if (case_insensitive) + while (!ret && len--) + ret = toupper((u8)*p1++) - toupper((u8)*p2++); + else + while (!ret && len--) + ret = (u8)*p1++ - (u8)*p2++; + if (!ret) + ret = s1->length - s2->length; + TRACE2("len: %d, ret: %d", len, ret); + EXIT2(return ret); +} + +wstdcall BOOLEAN WIN_FUNC(RtlEqualString,3) + (const struct ansi_string *s1, const struct ansi_string *s2, + BOOLEAN case_insensitive) +{ + ENTER1(""); + if (s1->length != s2->length) + return FALSE; + return !RtlCompareString(s1, s2, case_insensitive); +} + +wstdcall BOOLEAN WIN_FUNC(RtlEqualUnicodeString,3) + (const struct unicode_string *s1, const struct unicode_string *s2, + BOOLEAN case_insensitive) +{ + if (s1->length != s2->length) + return FALSE; + return !RtlCompareUnicodeString(s1, s2, case_insensitive); +} + +wstdcall void WIN_FUNC(RtlCopyUnicodeString,2) + (struct unicode_string *dst, struct unicode_string *src) +{ + ENTER1("%p, %p", dst, src); + if (src && src->buf && dst->buf) { + dst->length = min(src->length, dst->max_length); + memcpy(dst->buf, src->buf, dst->length); + if (dst->length < dst->max_length) + dst->buf[dst->length / sizeof(dst->buf[0])] = 0; + } else + dst->length = 0; + EXIT1(return); +} + +wstdcall void WIN_FUNC(RtlCopyString,2) + (struct ansi_string *dst, struct ansi_string *src) +{ + ENTER1("%p, %p", dst, src); + if (src && src->buf && dst->buf) { + dst->length = min(src->length, dst->max_length); + memcpy(dst->buf, src->buf, dst->length); + if (dst->length < dst->max_length) + dst->buf[dst->length] = 0; + } else + dst->length = 0; + EXIT1(return); +} + +wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeToString,2) + (struct unicode_string *dst, wchar_t *src) +{ + if (src) { + int len; + for (len = 0; src[len]; len++) + ; + if (dst->length + (len * sizeof(dst->buf[0])) > dst->max_length) + return STATUS_BUFFER_TOO_SMALL; + memcpy(&dst->buf[dst->length], src, len * sizeof(dst->buf[0])); + dst->length += len * sizeof(dst->buf[0]); + if (dst->max_length > dst->length) + dst->buf[dst->length / sizeof(dst->buf[0])] = 0; + } + return STATUS_SUCCESS; +} + +wstdcall NTSTATUS WIN_FUNC(RtlAppendUnicodeStringToString,2) + (struct unicode_string *dst, struct unicode_string *src) +{ + if (dst->max_length < src->length + dst->length) + return STATUS_BUFFER_TOO_SMALL; + if (src->length) { + memcpy(&dst->buf[dst->length], src->buf, src->length); + dst->length += src->length; + if (dst->max_length > dst->length) + dst->buf[dst->length / sizeof(dst->buf[0])] = 0; + } + EXIT2(return STATUS_SUCCESS); +} + +wstdcall ULONG WIN_FUNC(RtlxAnsiStringToUnicodeSize,1) + (const struct ansi_string *string) +{ + int i; + + for (i = 0; i < string->max_length && string->buf[i]; i++) + ; + return (i * sizeof(wchar_t)); +} + +wstdcall ULONG WIN_FUNC(RtlxUnicodeStringToAnsiSize,1) + (const struct unicode_string *string) +{ + int i; + + for (i = 0; i < string->max_length && string->buf[i]; i++) + ; + return i; +} + +wstdcall NTSTATUS WIN_FUNC(RtlAnsiStringToUnicodeString,3) + (struct unicode_string *dst, const struct ansi_string *src, + BOOLEAN alloc) +{ + int i, n; + + n = RtlxAnsiStringToUnicodeSize(src); + TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length, + src->max_length, src->buf); + if (alloc == TRUE) { +#if 0 + if (n == 0) { + dst->length = dst->max_length = 0; + dst->buf = NULL; + EXIT2(return STATUS_SUCCESS); + } +#endif + dst->max_length = n + sizeof(dst->buf[0]); + dst->buf = ExAllocatePoolWithTag(NonPagedPool, + dst->max_length, 0); + if (!dst->buf) { + dst->max_length = dst->length = 0; + EXIT2(return STATUS_NO_MEMORY); + } + } else if (dst->max_length < n) + EXIT2(return STATUS_BUFFER_TOO_SMALL); + + dst->length = n; + n /= sizeof(dst->buf[0]); + for (i = 0; i < n; i++) + dst->buf[i] = src->buf[i]; + if (i * sizeof(dst->buf[0]) < dst->max_length) + dst->buf[i] = 0; + TRACE2("dst: length: %d, max_length: %d, string: %p", + dst->length, dst->max_length, src->buf); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToAnsiString,3) + (struct ansi_string *dst, const struct unicode_string *src, + BOOLEAN alloc) +{ + int i, n; + + n = RtlxUnicodeStringToAnsiSize(src); + TRACE2("%d, %d, %d, %d, %p", n, dst->max_length, src->length, + src->max_length, src->buf); + if (alloc == TRUE) { +#if 0 + if (n == 0) { + dst->length = dst->max_length = 0; + dst->buf = NULL; + EXIT2(return STATUS_SUCCESS); + } +#endif + dst->max_length = n + sizeof(dst->buf[0]); + dst->buf = ExAllocatePoolWithTag(NonPagedPool, + dst->max_length, 0); + if (!dst->buf) { + dst->max_length = dst->length = 0; + EXIT1(return STATUS_NO_MEMORY); + } + } else if (dst->max_length < n) + EXIT2(return STATUS_BUFFER_TOO_SMALL); + + dst->length = n; + for (i = 0; i < n; i++) + dst->buf[i] = src->buf[i]; + if (i < dst->max_length) + dst->buf[i] = 0; + TRACE2("string: %p, len: %d(%d)", dst->buf, dst->length, + dst->max_length); + EXIT2(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlUnicodeStringToInteger,3) + (struct unicode_string *ustring, ULONG base, ULONG *value) +{ + int i, sign = 1; + ULONG res; + typeof(ustring->buf) string; + + if (ustring->length == 0) { + *value = 0; + return STATUS_SUCCESS; + } + + string = ustring->buf; + i = 0; + while (i < (ustring->length / sizeof(*string)) && string[i] == ' ') + i++; + if (string[i] == '+') + i++; + else if (string[i] == '-') { + i++; + sign = -1; + } + if (base == 0) { + base = 10; + if (i <= ((ustring->length / sizeof(*string)) - 2) && + string[i] == '0') { + i++; + if (string[i] == 'b') { + base = 2; + i++; + } else if (string[i] == 'o') { + base = 8; + i++; + } else if (string[i] == 'x') { + base = 16; + i++; + } + } + } + if (!(base == 2 || base == 8 || base == 10 || base == 16)) + EXIT2(return STATUS_INVALID_PARAMETER); + + for (res = 0; i < (ustring->length / sizeof(*string)); i++) { + int v; + if (isdigit((char)string[i])) + v = string[i] - '0'; + else if (isxdigit((char)string[i])) + v = tolower((char)string[i]) - 'a' + 10; + else + v = base; + if (v >= base) + EXIT2(return STATUS_INVALID_PARAMETER); + res = res * base + v; + } + *value = sign * res; + EXIT3(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlCharToInteger,3) + (const char *string, ULONG base, ULONG *value) +{ + int sign = 1; + ULONG res; + + if (!string || !value) + EXIT2(return STATUS_INVALID_PARAMETER); + while (*string == ' ') + string++; + if (*string == '+') + string++; + else if (*string == '-') { + string++; + sign = -1; + } + if (base == 0) { + base = 10; + if (*string == '0') { + string++; + if (*string == 'b') { + base = 2; + string++; + } else if (*string == 'o') { + base = 8; + string++; + } else if (*string == 'x') { + base = 16; + string++; + } + } + } + if (!(base == 2 || base == 8 || base == 10 || base == 16)) + EXIT2(return STATUS_INVALID_PARAMETER); + + for (res = 0; *string; string++) { + int v; + if (isdigit(*string)) + v = *string - '0'; + else if (isxdigit(*string)) + v = tolower(*string) - 'a' + 10; + else + v = base; + if (v >= base) + EXIT2(return STATUS_INVALID_PARAMETER); + res = res * base + v; + } + *value = sign * res; + EXIT3(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlIntegerToUnicodeString,3) + (ULONG value, ULONG base, struct unicode_string *ustring) +{ + typeof(ustring->buf) buf = ustring->buf; + int i; + + if (base == 0) + base = 10; + if (!(base == 2 || base == 8 || base == 10 || base == 16)) + return STATUS_INVALID_PARAMETER; + for (i = 0; value && i < ustring->max_length / sizeof(*buf); i++) { + int r; + r = value % base; + value /= base; + if (r < 10) + buf[i] = r + '0'; + else + buf[i] = r + 'a' - 10; + } + if (value) + return STATUS_BUFFER_OVERFLOW; + ustring->length = i * sizeof(*buf); + return STATUS_SUCCESS; +} + +wstdcall LARGE_INTEGER WIN_FUNC(RtlConvertUlongToLargeInteger,1) + (ULONG ul) +{ + LARGE_INTEGER li = ul; + return li; +} + +wfastcall USHORT WIN_FUNC(RtlUshortByteSwap,1) + (USHORT src) +{ + return __swab16(src); +} + +wfastcall ULONG WIN_FUNC(RtlUlongByteSwap,1) + (ULONG src) +{ + /* ULONG is 32 bits for both 32-bit and 64-bit architectures */ + return __swab32(src); +} + +wstdcall NTSTATUS WIN_FUNC(RtlUpcaseUnicodeString,3) + (struct unicode_string *dst, struct unicode_string *src, BOOLEAN alloc) +{ + USHORT i, n; + + if (alloc) { + dst->buf = ExAllocatePoolWithTag(NonPagedPool, src->length, 0); + if (dst->buf) { + dst->max_length = src->length; + } else + EXIT2(return STATUS_NO_MEMORY); + } else { + if (dst->max_length < src->length) + EXIT2(return STATUS_BUFFER_OVERFLOW); + } + + n = src->length / sizeof(src->buf[0]); + for (i = 0; i < n; i++) + dst->buf[i] = toupper(src->buf[i]); + + dst->length = src->length; + EXIT3(return STATUS_SUCCESS); +} + +wstdcall void WIN_FUNC(RtlInitUnicodeString,2) + (struct unicode_string *dst, const wchar_t *src) +{ + ENTER2("%p", dst); + if (dst == NULL) + EXIT1(return); + if (src == NULL) { + dst->max_length = dst->length = 0; + dst->buf = NULL; + } else { + int i; + for (i = 0; (char)src[i]; i++) + ; + dst->buf = (typeof(dst->buf))src; + dst->length = i * sizeof(dst->buf[0]); + dst->max_length = (i + 1) * sizeof(dst->buf[0]); + } + EXIT1(return); +} + +wstdcall void WIN_FUNC(RtlInitAnsiString,2) + (struct ansi_string *dst, const char *src) +{ + ENTER2("%p", dst); + if (dst == NULL) + EXIT2(return); + if (src == NULL) { + dst->max_length = dst->length = 0; + dst->buf = NULL; + } else { + int i; + for (i = 0; src[i]; i++) + ; + dst->buf = (typeof(dst->buf))src; + dst->length = i; + dst->max_length = i + 1; + } + TRACE2("%p", dst->buf); + EXIT2(return); +} + +wstdcall void WIN_FUNC(RtlInitString,2) + (struct ansi_string *dst, const char *src) +{ + ENTER2("%p", dst); + RtlInitAnsiString(dst, src); + EXIT2(return); +} + +wstdcall void WIN_FUNC(RtlFreeUnicodeString,1) + (struct unicode_string *string) +{ + ENTER2("%p", string); + if (string == NULL) + return; + if (string->buf) + ExFreePool(string->buf); + string->length = string->max_length = 0; + string->buf = NULL; + return; +} + +wstdcall void WIN_FUNC(RtlFreeAnsiString,1) + (struct ansi_string *string) +{ + ENTER2("%p", string); + if (string == NULL) + return; + if (string->buf) + ExFreePool(string->buf); + string->length = string->max_length = 0; + string->buf = NULL; + return; +} + +/* guid string is of the form: {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */ +wstdcall NTSTATUS WIN_FUNC(RtlGUIDFromString,2) + (struct unicode_string *guid_string, struct guid *guid) +{ + struct ansi_string ansi; + NTSTATUS ret; + int i, j, k, l, m; + + ret = RtlUnicodeStringToAnsiString(&ansi, guid_string, TRUE); + if (ret != STATUS_SUCCESS) + return ret; + if (ansi.length != 37 || ansi.buf[0] != '{' || + ansi.buf[36] != '}' || ansi.buf[9] != '-' || + ansi.buf[14] != '-' || ansi.buf[19] != '-' || + ansi.buf[24] != '-') { + RtlFreeAnsiString(&ansi); + EXIT2(return STATUS_INVALID_PARAMETER); + } + memcpy(&guid->data4, &ansi.buf[29], sizeof(guid->data3)); + /* set end of data3 for scanf */ + ansi.buf[29] = 0; + if (sscanf(&ansi.buf[1], "%x", &i) == 1 && + sscanf(&ansi.buf[10], "%x", &j) == 1 && + sscanf(&ansi.buf[15], "%x", &k) == 1 && + sscanf(&ansi.buf[20], "%x", &l) == 1 && + sscanf(&ansi.buf[25], "%x", &m) == 1) { + guid->data1 = (i << 16) | (j < 8) | k; + guid->data2 = l; + guid->data3 = m; + ret = STATUS_SUCCESS; + } else + ret = STATUS_INVALID_PARAMETER; + RtlFreeAnsiString(&ansi); + return ret; +} + +wstdcall NTSTATUS WIN_FUNC(RtlQueryRegistryValues,5) + (ULONG relative, wchar_t *path, struct rtl_query_registry_table *tbl, + void *context, void *env) +{ + struct ansi_string ansi; + struct unicode_string unicode; + NTSTATUS status, ret; + static int i = 0; + + ENTER3("%x, %p", relative, tbl); +// TODO(); + + RtlInitUnicodeString(&unicode, path); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + ret = STATUS_SUCCESS; + for (; tbl->name; tbl++) { + RtlInitUnicodeString(&unicode, tbl->name); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("name: %s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + TRACE2("flags: %08X", tbl->flags); + if (tbl->flags == RTL_QUERY_REGISTRY_DIRECT) { + TRACE2("type: %08X", tbl->def_type); + if (tbl->def_type == REG_DWORD) { + /* Atheros USB driver needs this, but + * don't know where and how to get its + * value */ + if (tbl->def_data) { + TRACE2("def_data: %x", + *(int *)tbl->def_data); + *(DWORD *)tbl->context = 0x5f292a + i++; +// *(DWORD *)tbl->def_data; + } else + *(DWORD *)tbl->context = 0x2345dbe; + } + } else { + void *data; + ULONG type, length; + + if (!tbl->query_func) { + ERROR("oops: no query_func"); + ret = STATUS_INVALID_PARAMETER; + break; + } + if (tbl->flags & RTL_QUERY_REGISTRY_NOVALUE) { + data = NULL; + type = REG_NONE; + length = 0; + } else { + data = tbl->def_data; + type = tbl->def_type; + length = tbl->def_length;; + } + TRACE2("calling query_func: %p", tbl->query_func); + status = LIN2WIN6(tbl->query_func, tbl->name, type, + data, length, context, env); + TRACE2("status: %08X", status); + if (status) { + if (status == STATUS_BUFFER_TOO_SMALL) + ret = STATUS_BUFFER_TOO_SMALL; + else + EXIT2(return STATUS_INVALID_PARAMETER); + } + } + } + EXIT3(return ret); +} + +wstdcall NTSTATUS WIN_FUNC(RtlWriteRegistryValue,6) + (ULONG relative, wchar_t *path, wchar_t *name, ULONG type, + void *data, ULONG length) +{ + struct ansi_string ansi; + struct unicode_string unicode; + + ENTER3("%d", relative); + TODO(); + + RtlInitUnicodeString(&unicode, path); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + RtlInitUnicodeString(&unicode, name); + if (RtlUnicodeStringToAnsiString(&ansi, &unicode, TRUE) == + STATUS_SUCCESS) { + TRACE2("%s", ansi.buf); + RtlFreeAnsiString(&ansi); + } + EXIT5(return STATUS_SUCCESS); +} + +wstdcall NTSTATUS WIN_FUNC(RtlDeleteRegistryValue,3) + (ULONG relative, wchar_t *path, wchar_t *name) +{ + return STATUS_SUCCESS; +} + +wstdcall void WIN_FUNC(RtlAssert,4) + (char *failed_assertion, char *file_name, ULONG line_num, char *message) +{ + ERROR("assertion '%s' failed at %s line %d%s", + failed_assertion, file_name, line_num, message ? message : ""); + return; +} + +wstdcall void WIN_FUNC(RtlUnwind,0) + (void) +{ + TODO(); +} + +wstdcall void WIN_FUNC(RtlRaiseException,1) + (void *exception_record) +{ + TODO(); +} + +int rtl_init(void) +{ + return 0; +} + +/* called when module is being removed */ +void rtl_exit(void) +{ + EXIT4(return); +} --- linux-2.6.28.orig/ubuntu/heci/heci_interface.c +++ linux-2.6.28/ubuntu/heci/heci_interface.c @@ -0,0 +1,525 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + + +#include "heci.h" +#include "heci_interface.h" + + + +static const __u8 interface_start_wd_params[] = + { 0x02, 0x12, 0x13, 0x10 }; +static const __u8 interface_stop_wd_params[] = + { 0x02, 0x02, 0x14, 0x10 }; + +/** + * read_heci_register - Read a byte from the heci device + * @device: the device structure + * @offset: offset from which to read the data + * + * Return: + * the byte read. + */ +__u32 read_heci_register(struct iamt_heci_device * device, + unsigned long offset) +{ + return readl(device->mem_addr + offset); +} + +/** + * write_heci_register - Write 4 bytes to the heci device + * @device: the device structure + * @offset: offset from which to write the data + * + * @value: the byte to write + */ +void write_heci_register(struct iamt_heci_device * device, unsigned long offset, + __u32 value) +{ + writel(value, device->mem_addr + offset); +} + +/** + * host_buffer_is_empty - check if host buffer is empty. + * + * @device_object -Device object for our driver + * + * @return : + * TRUE if empty + * FALSE - otherwise. + */ +int host_buffer_is_empty(struct iamt_heci_device * device_object) +{ + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + read_ptr = (char) ((device_object->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((device_object->host_hw_state & H_CBWP) >> 16); + buffer_depth = + (unsigned char) ((device_object->host_hw_state & H_CBD) >> 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + + if (filled_slots > 0) + return FALSE; + return TRUE; +} + +/** + * count_empty_write_slots - count write empty slots. + * + * @device_object - Device object for our driver + * + * + * @return : + * -1(ESLOTS_OVERFLOW) if overflow + * otherwise filed slots count + */ +__s32 count_empty_write_slots(struct iamt_heci_device * device_object) +{ + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + + read_ptr = (char) ((device_object->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((device_object->host_hw_state & H_CBWP) >> 16); + buffer_depth = + (unsigned char) ((device_object->host_hw_state & H_CBD) >> 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + + if (filled_slots > buffer_depth) + /* overfolw */ + return -ESLOTS_OVERFLOW; + + return (__s32) empty_slots; +} + +/** + * heci_write_message - write a message to heci device. + * + * @heci_header - header of message + * @write_buffer - message buffer will be write + * @write_length - message size will be write + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_write_message(struct iamt_heci_device * device_object, + struct heci_message_header * header, + unsigned char *write_buffer, + unsigned long write_length) +{ + __u32 temp_msg = 0; + unsigned long bytes_written = 0; + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + unsigned long dw_to_write; + dw_to_write = ((write_length + 3) / 4); + DBG("host_hw_state = 0x%08x.\n", device_object->host_hw_state); + DBG("heci_write_message header=%08x.\n", *((__u32 *) header)); + + read_ptr = (char) ((device_object->host_hw_state & H_CBRP) >> 8); + write_ptr = (char) ((device_object->host_hw_state & H_CBWP) >> 16); + buffer_depth = + (unsigned char) ((device_object->host_hw_state & H_CBD) >> 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + DBG("filled = %hu, empty = %hu.\n", filled_slots, empty_slots); + + if (dw_to_write > empty_slots) { + return FALSE; + } + + write_heci_register(device_object, H_CB_WW, + *((__u32 *) header)); + + while (write_length >= 4) { + write_heci_register(device_object, H_CB_WW, + *(__u32 *) (write_buffer + + bytes_written)); + bytes_written += 4; + write_length -= 4; + } + + if (write_length > 0) { + memcpy(&temp_msg, &write_buffer[bytes_written], write_length); + write_heci_register(device_object, H_CB_WW, temp_msg); + } + + device_object->host_hw_state |= H_IG; + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + device_object->me_hw_state = + read_heci_register(device_object, ME_CSR_HA); + if ((device_object->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) + return FALSE; + + device_object->write_hang = 0; + return TRUE; +} + +/** + * count_full_read_slots - reset host and fw. + * + * @device_object -Device object for our driver + * + * + * @return : + * -1(ESLOTS_OVERFLOW) if overflow + * otherwise filed slots count + */ +__s32 count_full_read_slots(struct iamt_heci_device * device_object) +{ + + char read_ptr, write_ptr; + unsigned char buffer_depth, filled_slots, empty_slots; + + device_object->me_hw_state = read_heci_register(device_object, ME_CSR_HA); + read_ptr = (char) ((device_object->me_hw_state & ME_CBRP_HRA) >> 8); + write_ptr = (char) ((device_object->me_hw_state & ME_CBWP_HRA) >> 16); + buffer_depth = (unsigned char) ((device_object->me_hw_state & ME_CBD_HRA) >> + 24); + filled_slots = (unsigned char) (write_ptr - read_ptr); + empty_slots = buffer_depth - filled_slots; + + if (filled_slots > buffer_depth) + /* overflow */ + return -ESLOTS_OVERFLOW; + + DBG("filled_slots =%08x \n", filled_slots); + return (__s32) filled_slots; +} + +/** + * heci_read_slots - read a message from heci device. + * + * @device_object - device object for our driver + * @buffer - message buffer will be write + * @buffer_length - message size will be read + * + * @return : + * none; + */ +void heci_read_slots(struct iamt_heci_device * device_object, + unsigned char *buffer, unsigned long buffer_length) +{ + __u32 i = 0; + unsigned char temp_buf[sizeof(__u32)]; + + while (buffer_length >= sizeof(__u32)) { + ((__u32 *) buffer)[i] = + read_heci_register(device_object, ME_CB_RW); + DBG("buffer[%d]= %d\n", i, ((__u32 *) buffer)[i]); + i++; + buffer_length -= sizeof(__u32); + } + + if (buffer_length > 0) { + *((__u32 *) & temp_buf) = + read_heci_register(device_object, ME_CB_RW); + memcpy(&buffer[i * 4], temp_buf, buffer_length); + } + + device_object->host_hw_state |= H_IG; + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + return; +} + +/** + * flow_control_credentials - check flow_control credentials. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if flow_control_credentials >0 + * FALSE - otherwise. + */ +int flow_control_credentials(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + __u8 i; + + if (!device_object->num_heci_me_clients) + return FALSE; + if (file_extension == NULL) + return FALSE; + if (file_extension->flow_control_credentials > 0) + return TRUE; + + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (device_object->me_clients[i].client_id == + file_extension->me_client_id) { + if (device_object->me_clients[i].flow_control_credentials > 0) { + BUG_ON(device_object->me_clients[i]. + properteis.single_receive_buffer == 0); + return TRUE; + } + return FALSE; + } + } + BUG_ON(1); + return FALSE; +} + +/** + * flow_control_reduce - reduce flow_control . + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * none; + */ +void flow_control_reduce(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + __u8 i; + + if (!device_object->num_heci_me_clients) + return; + + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (device_object->me_clients[i].client_id == file_extension->me_client_id) { + if (device_object->me_clients[i].properteis.single_receive_buffer != 0) { + BUG_ON(device_object->me_clients[i]. + flow_control_credentials <= 0); + device_object->me_clients[i]. + flow_control_credentials--; + } else { + BUG_ON(file_extension-> + flow_control_credentials <= 0); + file_extension->flow_control_credentials--; + } + return; + } + } + BUG_ON(1); +} + +/** + * heci_send_flow_control - send flow control to fw. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_send_flow_control(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + struct heci_message_header *heci_header; + struct hbm_flow_control *heci_flow_control; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_flow_control); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + heci_flow_control = + (struct hbm_flow_control *) & device_object-> + write_message_buffer[1]; + memset(heci_flow_control, 0, sizeof(heci_flow_control)); + heci_flow_control->host_address = file_extension->host_client_id; + heci_flow_control->me_address = file_extension->me_client_id; + heci_flow_control->command.command = FLOW_CONTROL_CMD; + memset(heci_flow_control->reserved, 0, sizeof(heci_flow_control->reserved)); + DBG("sending flow control host client = %d, me client = %d\n", + file_extension->host_client_id, file_extension->me_client_id); + if (!heci_write_message(device_object, heci_header, + (unsigned char *) heci_flow_control, sizeof(struct hbm_flow_control))) + return FALSE; + return TRUE; + +} + +/** + * other_client_is_connecting - check if other + * client with the same client id is connected. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if other client is connected. + * FALSE - otherwise. + */ +int other_client_is_connecting(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + if ((file_extension_pos->state == HECI_FILE_CONNECTING) + && (file_extension_pos != file_extension) + && file_extension->me_client_id == + file_extension_pos->me_client_id) + return TRUE; + } + return FALSE; +} + +/** + * heci_send_wd - send watch dog message to fw. + * + * @device_object -Device object for our driver + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_send_wd(struct iamt_heci_device * device_object) +{ + struct heci_message_header *heci_header; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = + device_object->wd_file_extension.host_client_id; + heci_header->me_address = + device_object->wd_file_extension.me_client_id; + heci_header->message_complete = 1; + heci_header->reserved = 0; + + if (!memcmp(device_object->wd_data, interface_start_wd_params, + HECI_WD_PARAMS_SIZE)) { + heci_header->length = HECI_START_WD_DATA_SIZE; + } else { + BUG_ON(memcmp(device_object->wd_data, interface_stop_wd_params, + HECI_WD_PARAMS_SIZE)); + heci_header->length = HECI_WD_PARAMS_SIZE; + } + + if (!heci_write_message(device_object, heci_header, + device_object->wd_data, + heci_header->length)) + return FALSE; + return TRUE; +} + + +/** + * heci_disconnect - send disconnect message to fw. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_disconnect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + struct heci_message_header *heci_header; + struct hbm_client_disconnect_request *heci_cli_disconnect; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_client_disconnect_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + heci_cli_disconnect = + (struct hbm_client_disconnect_request *) & device_object-> + write_message_buffer[1]; + memset(heci_cli_disconnect, 0, sizeof(heci_cli_disconnect)); + heci_cli_disconnect->host_address = file_extension->host_client_id; + heci_cli_disconnect->me_address = file_extension->me_client_id; + heci_cli_disconnect->command.command = CLIENT_DISCONNECT_REQ_CMD; + heci_cli_disconnect->reserved[0] = 0; + + if (TRUE != heci_write_message(device_object, heci_header, + (unsigned char *) heci_cli_disconnect, sizeof(struct hbm_client_disconnect_request))) + return FALSE; + return TRUE; +} + +/** + * heci_connect - send connect message to fw. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * TRUE if success + * FALSE - otherwise. + */ +int heci_connect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + struct heci_message_header *heci_header; + struct hbm_client_connect_request *heci_cli_connect; + + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_client_connect_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + heci_cli_connect = + (struct hbm_client_connect_request *) & device_object-> + write_message_buffer[1]; + heci_cli_connect->host_address = file_extension->host_client_id; + heci_cli_connect->me_address = file_extension->me_client_id; + heci_cli_connect->command.command = CLIENT_CONNECT_REQ_CMD; + heci_cli_connect->reserved = 0; + if (TRUE != heci_write_message(device_object, heci_header, + (unsigned char *) heci_cli_connect, sizeof(struct hbm_client_connect_request))) + return FALSE; + return TRUE; +} --- linux-2.6.28.orig/ubuntu/heci/heci_main.c +++ linux-2.6.28/ubuntu/heci/heci_main.c @@ -0,0 +1,1444 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "heci.h" +#include "heci_interface.h" +#include "version.h" + + +#define HECI_READ_TIMEOUT 45 + +#define MAX_OPEN_HANDLE_COUNT 253 +/** + * heci driver strings + */ +char heci_driver_name[] = "heci"; +char heci_driver_string[] = "Intel(R) AMT Management Interface"; +char heci_driver_version[] = DRIVER_VERSION; +char heci_copyright[] = "Copyright (c) 2003 - 2007 Intel Corporation."; + + +#ifdef HECI_DEBUG +DEF_PARM(int, debug, 1, 0644, "Debug enabled or not"); +#else +DEF_PARM(int, debug, 0, 0644, "Debug enabled or not"); +#endif + +/* heci char device for registration */ +static struct cdev heci_cdev = { + .kobj = {.name = "heci", }, + .owner = THIS_MODULE, +}; + +/* iamt legacy char device for registration */ +static struct cdev iamt_legacy_cdev = { + .kobj = {.name = "iamt_legacy", }, + .owner = THIS_MODULE, +}; + +/* major number for device */ +static int heci_major; +/* The device pointer */ +static struct pci_dev *heci_device; + +/* heci_pci_tbl - PCI Device ID Table */ +static struct pci_device_id heci_pci_tbl[] = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID1)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID2)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID3)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID4)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID5)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID6)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID7)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_HECI_DEVICE_ID8)}, + /* required last entry */ + {0, } +}; + +MODULE_DEVICE_TABLE(pci, heci_pci_tbl); + +/** + * Local Function Prototypes + */ +static int __init heci_init_module(void); +static void __exit heci_exit_module(void); +static int __devinit heci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent); +static void __devexit heci_remove(struct pci_dev *pdev); +static int heci_open(struct inode *inode, struct file *file); +static int heci_release(struct inode *inode, struct file *file); +static unsigned int heci_legacy_poll(struct file *file, poll_table * wait); +static ssize_t heci_read(struct file *file, char __user * ubuf, + size_t length, loff_t * offset); +static int heci_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long data); +static ssize_t heci_write(struct file *file, const char __user * ubuf, + size_t length, loff_t * offset); +static unsigned int heci_poll(struct file *file, poll_table * wait); +#ifdef CONFIG_PM +static int heci_suspend(struct pci_dev* pdev, pm_message_t state); +static int heci_resume(struct pci_dev* pdev); +static __u16 g_sus_wd_timeout; +#endif +/** + * PCI driver structure + */ +static struct pci_driver heci_driver = { + .name = heci_driver_name, + .id_table = heci_pci_tbl, + .probe = heci_probe, + .remove = heci_remove, + SHUTDOWN_METHOD(heci_remove) +#ifdef CONFIG_PM + .suspend = heci_suspend, + .resume = heci_resume +#endif +}; + +/** + * file operations structure will be use heci char device. + */ +static struct file_operations heci_fops = { + .owner = THIS_MODULE, + .read = heci_read, + .ioctl = heci_ioctl, + .open = heci_open, + .release = heci_release, + .write = heci_write, + .poll = heci_poll, +}; + +/** + * file operations structure will be use iamt legacy char device. + */ +static struct file_operations iamt_legacy_fops = { + .owner = THIS_MODULE, + .ioctl = heci_ioctl, + .open = heci_open, + .release = heci_release, + .poll = heci_legacy_poll, +}; + +/** + * For kernels withouth PCI shutdown support reboot notifier is essential + */ +HECI_REBOOT_NOTIFIER(heci_reboot_notifier, heci_driver, heci_remove) + +/** + * Set up the cdev structure for heci device. + * @dev - char device struct + * @minor - minor number for registration char device + * @fops - file operations structure + * @return : + * 0 on success, + * negative on failure + */ +static int heci_registration_cdev(struct cdev *dev, int minor, + struct file_operations *fops) +{ + int ret = ESUCCESS, devno = MKDEV(heci_major, minor); + + cdev_init(dev, fops); + dev->owner = THIS_MODULE; + dev->ops = fops; + ret = cdev_add(dev, devno, 1); + /* Fail gracefully if need be */ + if (ret) { + kobject_put(&dev->kobj); + HECI_ERR("Error %d registering heci device %d", ret, minor); + } + return ret; +} + + + +/** + * heci_init_module - Driver Registration Routine + * + * heci_init_module is the first routine called when the driver is + * loaded. All it does is register with the PCI subsystem. + * + * @return : + * 0 on success, + * negative on failure + */ +static int __init heci_init_module(void) +{ + int ret = ESUCCESS; + dev_t dev; + HECI_INFO("%s - version %s\n", heci_driver_string, heci_driver_version); + HECI_INFO("%s\n", heci_copyright); + + /* init pci module */ + ret = pci_register_driver(&heci_driver); + if (ret < 0) + goto end; + + REGISTER_REBOOT_NOTIFIER(heci_reboot_notifier); + /* registration char devices */ + ret = alloc_chrdev_region(&dev, 0, MINORS_COUNT, "heci"); + + heci_major = MAJOR(dev); + /* Now registration two cdevs. */ + ret = heci_registration_cdev(&iamt_legacy_cdev, LEGACY_MINOR_NUMBER, + &iamt_legacy_fops); + if (ret) + goto unregister; + + ret = heci_registration_cdev(&heci_cdev, HECI_MINOR_NUMBER, + &heci_fops); + if (ret) { + cdev_del(&iamt_legacy_cdev); + goto unregister; + } + return ret; + +unregister: + pci_unregister_driver(&heci_driver); + unregister_chrdev_region(MKDEV(heci_major, 0), MINORS_COUNT); +end: + return ret; +} + +module_init(heci_init_module); + + +/** + * heci_exit_module - Driver Exit Cleanup Routine + * + * heci_exit_module is called just before the driver is removed + * from memory. + * + * @return : + * none; + */ + +static void __exit heci_exit_module(void) +{ + UNREGISTER_REBOOT_NOTIFIER(heci_reboot_notifier); + pci_unregister_driver(&heci_driver); + /* Now unregister two cdevs. */ + cdev_del(&iamt_legacy_cdev); + cdev_del(&heci_cdev); + unregister_chrdev_region(MKDEV(heci_major, 0), MINORS_COUNT); +} + +module_exit(heci_exit_module); + + +/** + * heci_probe - Device Initialization Routine + * + * @pdev: PCI device information struct + * @ent: entry in kcs_pci_tbl + * + * @return : + * 0 on success, + * negative on failure + */ +static int __devinit heci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct iamt_heci_device *device = NULL; + int i, err = 0; + if (heci_device) { + err = -EEXIST; + goto end; + } + /* enable pci device */ + err = pci_enable_device(pdev); + if (err) { + HECI_ERR("Failed to enable pci device\n"); + goto end; + } + /* set PCI host mastering */ + pci_set_master(pdev); + /* pci request regions for heci driver */ + err = pci_request_regions(pdev, heci_driver_name); + if (err) { + HECI_ERR("Failed to get pci regions\n"); + goto disable_device; + } + /* allocates and initializes the heci device structure */ + device = init_heci_device(pdev); + if (!device) { + err = -ENOMEM; + goto release_regions; + } + /* mapping IO device memory */ + for (i = BAR_0; i <= BAR_5; i++) { + if (pci_resource_len(pdev, i) == 0) { + continue; + } + if (pci_resource_flags(pdev, i) & IORESOURCE_IO) { + HECI_ERR("heci has an IO ports.\n"); + goto free_device; + } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) { + if (device->mem_base) { + HECI_ERR("Too many mem addresses.\n"); + goto free_device; + } + device->mem_base = pci_resource_start(pdev, i); + device->mem_length = pci_resource_len(pdev, i); + } + } + if (!device->mem_base) { + HECI_ERR("No address to use.\n"); + err = -ENODEV; + goto free_device; + } + device->mem_addr = ioremap_nocache(device->mem_base, device->mem_length); + if (!device->mem_addr) { + HECI_ERR(" Remap IO device memory failure.\n"); + err = -ENOMEM; + goto free_device; + } + /* request and enable interrupt */ + device->irq = pdev->irq; + err = request_irq(device->irq, heci_isr_interrupt, IRQF_SHARED, + heci_driver_name, device); + if (err) { + HECI_ERR("Request_irq failure. irq = %d \n", device->irq); + goto unmap_memory; + } + + if (heci_hw_init(device)) { + HECI_ERR("init hw failure.\n"); + err = -ENODEV; + goto release_irq; + } + init_timer(&device->wd_timer); + heci_initialize_clients(device); + if (device->heci_state != HECI_ENABLED) { + err = -ENODEV; + goto release_hw; + } + spin_lock_bh(&device->device_lock); + heci_device = pdev; + pci_set_drvdata(pdev, device); + spin_unlock_bh(&device->device_lock); + if (device->wd_timeout) { + mod_timer(&device->wd_timer, jiffies); + } +#ifdef CONFIG_PM + g_sus_wd_timeout = 0; +#endif + HECI_INFO("heci driver initialization successful.\n"); + return ESUCCESS; + +release_hw: + /* disable interrupts */ + device->host_hw_state = read_heci_register(device, H_CSR); + device->host_hw_state &= ~H_IE; + /* acknowledge interrupt and stop interupts */ + write_heci_register(device, H_CSR, device->host_hw_state); + + del_timer_sync(&device->wd_timer); + + + flush_scheduled_work(); + +release_irq: + free_irq(pdev->irq, device); +unmap_memory: + if (device->mem_addr) + iounmap(device->mem_addr); +free_device: + kfree(device); +release_regions: + pci_release_regions(pdev); +disable_device: + pci_disable_device(pdev); +end: + HECI_ERR("heci driver initialization failed.\n"); + return err; +} + +/** + * heci_remove - Device Removal Routine + * @pdev: PCI device information struct + * + * heci_remove is called by the PCI subsystem to alert the driver + * that it should release a PCI device. + * + * @return : + * none; + */ +static void __devexit heci_remove(struct pci_dev *pdev) +{ + struct iamt_heci_device *device = pci_get_drvdata(pdev); + int err = 0; + + if (heci_device != pdev) + return; + del_timer_sync(&device->wd_timer); + if (device->wd_file_extension.state == HECI_FILE_CONNECTED + && device->wd_timeout) { + spin_lock_bh(&device->device_lock); + device->wd_timeout = 0; + device->wd_due_counter = 0; + memcpy(device->wd_data, stop_wd_params, HECI_WD_PARAMS_SIZE); + device->stop = TRUE; + if (device->host_buffer_is_empty && + flow_control_credentials(device, &device->wd_file_extension)) { + device->host_buffer_is_empty = FALSE; + + if (!heci_send_wd(device)) + DBG("Send stop WD failed\n"); + else + flow_control_reduce(device, &device->wd_file_extension); + device->wd_pending = FALSE; + + } else { + device->wd_pending = TRUE; + } + spin_unlock_bh(&device->device_lock); + device->wd_stoped = FALSE; + + err = + wait_event_interruptible_timeout(device->wait_stop_wd, + (TRUE == + device->wd_stoped), + 10 * HZ); + if (!device->wd_stoped) + DBG("stop wd failed to complete.\n"); + else + DBG("stop wd complete.\n"); + } + + heci_device = NULL; + if (device->legacy_file_extension.status == HECI_FILE_CONNECTED) { + device->legacy_file_extension.status = HECI_FILE_DISCONNECTING; + heci_disconnect_host_client(device, + &device->legacy_file_extension); + } + if (device->wd_file_extension.status == HECI_FILE_CONNECTED) { + device->wd_file_extension.status = HECI_FILE_DISCONNECTING; + heci_disconnect_host_client(device, + &device->wd_file_extension); + } + /* remove entry if already in list */ + DBG("list del legacy and wd file list.\n"); + heci_remove_client_from_file_list(device, device->wd_file_extension. + host_client_id); + heci_remove_client_from_file_list(device, device->legacy_file_extension. + host_client_id); + flush_scheduled_work(); + /* disable interrupts */ + device->host_hw_state &= ~H_IE; + /* acknowledge interrupt and stop interupts */ + write_heci_register(device, H_CSR, device->host_hw_state); + free_irq(pdev->irq, device); + pci_set_drvdata(pdev, NULL); + + if (device->mem_addr) + iounmap(device->mem_addr); + kfree(device); + + pci_release_regions(pdev); + pci_disable_device(pdev); +} +/** + * heci_clear_list - remove all callbacks associated with file + * from heci_cb_list + * @file: file informtion struct + * @heci_cb_list: callbacks list + * heci_clear_list is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * @return :true if callback removed from the list, false otherwise + */ +static int heci_clear_list(struct iamt_heci_device *device, struct file *file, struct list_head *heci_cb_list) { + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + struct file *file_temp = NULL; + int return_status = FALSE; + + /* list all list member */ + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, heci_cb_list, cb_list){ + file_temp = (struct file *)kernel_priv_cb_pos->file_object; + /* check if list member associated with a file */ + if (file_temp == file) { + /* remove member from the list */ + list_del(&kernel_priv_cb_pos->cb_list); + /* check if cb equal to current legacy cb */ + if (device->legacy_current_cb == kernel_priv_cb_pos) { + device->legacy_current_cb = NULL; + /* send flow control to legacy client */ + heci_send_flow_control(device, &device->legacy_file_extension); + } + /* free all allocated buffers */ + kfree (kernel_priv_cb_pos->request_buffer.data); + kernel_priv_cb_pos->request_buffer.data = NULL; + kfree (kernel_priv_cb_pos->response_buffer.data); + kernel_priv_cb_pos->response_buffer.data = NULL; + kfree(kernel_priv_cb_pos); + return_status = TRUE; + } + } + return return_status; +} + +/** + * heci_clear_lists - remove all callbacks associated with file + * @device: device informtion struct + * @file: file informtion struct + * heci_clear_lists is called to clear resources associated with file + * when application calls close function or Ctrl-C was pressed + * + * @return :true if callback removed from the list, false otherwise + */ +static int heci_clear_lists(struct iamt_heci_device *device, struct file *file) +{ + int return_status = FALSE; + + /* remove callbacks associated with a file */ + heci_clear_list(device, file, &device->pthi_cmd_list.heci_cb.cb_list); + if (heci_clear_list(device, file, &device->pthi_read_complete_list.heci_cb.cb_list)) + return_status = TRUE; + heci_clear_list(device, file, &device->control_read_list.heci_cb.cb_list); + if (heci_clear_list(device, file, &device->control_write_list.heci_cb.cb_list)) + return_status = TRUE; + if (heci_clear_list(device, file, &device->write_waiting_list.heci_cb.cb_list)) + return_status = TRUE; + if (heci_clear_list(device, file, &device->write_list.heci_cb.cb_list)) + return_status = TRUE; + /* check if legacy_current_cb not NULL */ + if (device->legacy_current_cb && (!return_status)) { + /* check file and legacy current cb association */ + if (device->legacy_current_cb->file_object == file) { + /* remove cb */ + kfree (device->legacy_current_cb->request_buffer.data); + device->legacy_current_cb->request_buffer.data = NULL; + kfree (device->legacy_current_cb->response_buffer.data); + device->legacy_current_cb->response_buffer.data = NULL; + kfree(device->legacy_current_cb); + device->legacy_current_cb = NULL; + return_status = TRUE; + } + } + return return_status; +} + +/** + * heci_open - the open function + */ +static int heci_open(struct inode *inode, struct file *file) +{ + struct heci_file_private *file_extension = NULL; + int if_num = MINOR(inode->i_rdev); + struct iamt_heci_device *device = NULL; + if (!heci_device) + return -ENODEV; + device = pci_get_drvdata(heci_device); + if (((if_num != LEGACY_MINOR_NUMBER) + && (if_num != HECI_MINOR_NUMBER)) || (!device)) + return -ENODEV; + + if (if_num != LEGACY_MINOR_NUMBER) { + file_extension = alloc_priv(file); + if (!file_extension) + return -ENOMEM; + } else { + file->private_data = + (void *) &device->legacy_file_extension; + return ESUCCESS; + } + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + kfree(file_extension); + file_extension = NULL; + return -ENODEV; + } + if (device->open_handle_count >= MAX_OPEN_HANDLE_COUNT) { + spin_unlock_bh(&device->device_lock); + kfree(file_extension); + file_extension = NULL; + return -ENFILE; + }; + device->open_handle_count++; + list_add_tail(&file_extension->link, &device->file_list); + while ((device->heci_host_clients[device->current_host_client_id / 8] + & (1 << (device->current_host_client_id % 8))) != 0) { + device->current_host_client_id++; /* allow overflow */ + DBG("current_host_client_id = %d\n", device->current_host_client_id); + DBG("device->open_handle_count = %lu\n", device->open_handle_count); + } + DBG("current_host_client_id = %d\n", device->current_host_client_id); + file_extension->host_client_id = device->current_host_client_id; + device->heci_host_clients[file_extension->host_client_id / 8] |= + (1 << (file_extension->host_client_id % 8)); + spin_unlock_bh(&device->device_lock); + spin_lock(&file_extension->file_lock); + file_extension->state = HECI_FILE_INITIALIZING; + file_extension->sm_state = 0; + + file->private_data = file_extension; + spin_unlock(&file_extension->file_lock); + + return ESUCCESS; +} + +/** + * heci_release - the release function + */ +static int heci_release(struct inode *inode, struct file *file) +{ + int return_status = ESUCCESS; + int if_num = MINOR(inode->i_rdev); + struct heci_file_private *file_extension = file->private_data; + struct heci_cb_private *kernel_priv_cb = NULL; + struct iamt_heci_device *device = NULL; + + if (!heci_device) + return -ENODEV; + + device = pci_get_drvdata(heci_device); + if (((if_num != LEGACY_MINOR_NUMBER) + && (if_num != HECI_MINOR_NUMBER)) || (!device) + || (!file_extension)) + return -ENODEV; + if (file_extension != &device->legacy_file_extension) { + + spin_lock(&file_extension->file_lock); + if (file_extension->state == HECI_FILE_CONNECTED) { + file_extension->state = HECI_FILE_DISCONNECTING; + spin_unlock(&file_extension->file_lock); + DBG("disconnecting client host client = %d, ME client = %d\n", + file_extension->host_client_id, + file_extension->me_client_id); + return_status = + heci_disconnect_host_client(device, + file_extension); + spin_lock(&file_extension->file_lock); + } + spin_lock_bh(&device->device_lock); + heci_flush_queues(device, file_extension); + DBG("remove client host client = %d, ME client = %d\n", + file_extension->host_client_id, + file_extension->me_client_id); + device->heci_host_clients[file_extension->host_client_id / 8] &= ~(1 << (file_extension->host_client_id % 8)); + device->open_handle_count--; + heci_remove_client_from_file_list(device, file_extension->host_client_id); + spin_unlock_bh(&device->device_lock); + + /* free read cb */ + if (file_extension->read_cb != NULL) { + spin_unlock(&file_extension->file_lock); + kernel_priv_cb = file_extension->read_cb; + kfree(kernel_priv_cb->response_buffer.data); + kernel_priv_cb->response_buffer.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + + file_extension->read_cb = NULL; + spin_lock(&file_extension->file_lock); + } + spin_unlock(&file_extension->file_lock); + kfree(file_extension); + file->private_data = NULL; + } else { + spin_lock_bh(&device->device_lock); + if (if_num != LEGACY_MINOR_NUMBER) { + device->open_handle_count--; + } + if (device->legacy_file_object == file + && device->legacy_state != HECI_LEGACY_IDLE) { + + DBG("pthi canceled legacy state %d\n", + device->legacy_state); + device->legacy_canceled = TRUE; + if (device->legacy_state == HECI_LEGACY_READ_COMPLETE) { + DBG("run next pthi legacy cb\n"); + run_next_legacy_cmd(device); + } + } + + if (heci_clear_lists(device, file)) { + device->legacy_state = HECI_LEGACY_IDLE; + } + spin_unlock_bh(&device->device_lock); + } + return return_status; +} + + +static struct heci_cb_private *find_read_list_entry(struct iamt_heci_device* device, + struct heci_file_private *file_extension) +{ + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + struct heci_file_private *file_extension_list_temp = NULL; + + if (device->read_list.status == ESUCCESS + && !list_empty(&device->read_list.heci_cb.cb_list)) { + DBG("remove read_list CB \n"); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->read_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) + return kernel_priv_cb_pos; + } + } + } + return NULL; +} +/** + * heci_read - the read client message function. + */ +static ssize_t heci_read(struct file *file, char __user * ubuf, + size_t length, loff_t * offset) +{ + int i; + int return_status = ESUCCESS, err = ESUCCESS; + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + struct heci_file_private *file_extension = file->private_data; + struct heci_cb_private *kernel_priv_cb_pos = NULL; + struct heci_cb_private *kernel_priv_cb = NULL; + struct iamt_heci_device *device = NULL; + + if (!heci_device) + return -ENODEV; + + device = pci_get_drvdata(heci_device); + if ((if_num != HECI_MINOR_NUMBER) || (!device) || (!file_extension)) + return -ENODEV; + + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + spin_unlock_bh(&device->device_lock); + if (!file_extension) + return -ENODEV; + + spin_lock(&file_extension->file_lock); + if((file_extension->sm_state & HECI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) { + spin_unlock(&file_extension->file_lock); + /* Do not allow to read watchdog client */ + for (i = 0; i < device->num_heci_me_clients; i++) { + if (0 == memcmp(&heci_wd_guid, &device->me_clients[i].properteis.protocol_name, sizeof(struct guid))) { + if (file_extension->me_client_id == device->me_clients[i].client_id) + return -EBADF; + } + } + } else { + file_extension->sm_state &= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT; + spin_unlock(&file_extension->file_lock); + } + if (file_extension == &device->legacy_file_extension) { + return_status = pthi_read(device, if_num, file, ubuf, length, offset); + goto out; + } + + if (file_extension->read_cb && file_extension->read_cb->information > *offset) { + kernel_priv_cb = file_extension->read_cb; + goto copy_buffer; + } + else if (file_extension->read_cb && file_extension->read_cb->information > 0 && + file_extension->read_cb->information <= *offset) { + kernel_priv_cb = file_extension->read_cb; + return_status = 0; + goto free; + } + else if ((!file_extension->read_cb || file_extension->read_cb->information == 0) && + *offset > 0) { + *offset = 0; /*Offset needs to be cleaned for contingous reads*/ + return_status = 0; + goto out; + } + + spin_lock(&file_extension->read_io_lock); + err = heci_start_read(device, if_num, file_extension); + if (err != ESUCCESS && err != -EBUSY) { + DBG("heci start read failure with status = %d\n", err); + spin_unlock(&file_extension->read_io_lock); + return_status = err; + goto out; + } + if (HECI_READ_COMPLETE != file_extension->reading_state && !waitqueue_active (&file_extension->rx_wait)) { + if (file->f_flags & O_NONBLOCK) { + return_status = -EAGAIN; + spin_unlock(&file_extension->read_io_lock); + goto out; + } + spin_unlock(&file_extension->read_io_lock); + + if (wait_event_interruptible(file_extension->rx_wait, + (HECI_READ_COMPLETE == file_extension->reading_state || + HECI_FILE_INITIALIZING == file_extension->state || + HECI_FILE_DISCONNECTED == file_extension->state || + HECI_FILE_DISCONNECTING == file_extension->state))) { + if (signal_pending (current)) { + return_status = -EINTR; + goto out; + } + return -ERESTARTSYS; + } + + if (HECI_FILE_INITIALIZING == file_extension->state || + HECI_FILE_DISCONNECTED == file_extension->state || + HECI_FILE_DISCONNECTING == file_extension->state) { + return_status = -EBUSY; + goto out; + } + spin_lock(&file_extension->read_io_lock); + } + + kernel_priv_cb = file_extension->read_cb; + + if (!kernel_priv_cb) { + spin_unlock(&file_extension->read_io_lock); + return -ENODEV; + } + if (file_extension->reading_state != HECI_READ_COMPLETE) { + spin_unlock(&file_extension->read_io_lock); + return ESUCCESS; + } + spin_unlock(&file_extension->read_io_lock); + /* now copy the data to user space */ +copy_buffer: + DBG("kernel_priv_cb->response_buffer size - %d\n", kernel_priv_cb->response_buffer.size); + DBG("kernel_priv_cb->information - %lu\n", kernel_priv_cb->information); + if (length == 0 || ubuf == NULL || *offset > kernel_priv_cb->information) { + return_status = -EMSGSIZE; + goto free; + } + + /* length is being turncated to PAGE_SIZE, however, information size may be longer */ + length = (length < (kernel_priv_cb->information - *offset) ? + length : (kernel_priv_cb->information - *offset)); + + if (copy_to_user(ubuf, kernel_priv_cb->response_buffer.data + *offset, length)) { + return_status = -EFAULT; + goto free; + } + else { + return_status = length; + *offset += length; + if ((unsigned long)*offset < kernel_priv_cb->information) { + goto out; + } + } +free: + spin_lock_bh(&device->device_lock); + kernel_priv_cb_pos = find_read_list_entry(device, file_extension); + /* Remove entry from read list */ + if (kernel_priv_cb_pos != NULL) + list_del(&kernel_priv_cb_pos->cb_list); + spin_unlock_bh(&device->device_lock); + kfree(kernel_priv_cb->response_buffer.data); + kernel_priv_cb->response_buffer.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + spin_lock(&file_extension->read_io_lock); + file_extension->reading_state = HECI_IDLE; + file_extension->read_cb = NULL; + file_extension->read_pending = FALSE; + spin_unlock(&file_extension->read_io_lock); +out: DBG("end heci read return_status= %d\n", return_status); + return return_status; +} + +/** + * heci_write - the write function. + */ +static ssize_t heci_write(struct file *file, const char __user * ubuf, + size_t length, loff_t * offset) +{ + int return_status = ESUCCESS; + __u8 i; + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + struct heci_file_private *file_extension = file->private_data; + struct heci_cb_private *priv_write_cb = NULL; + struct heci_message_header heci_header; + struct iamt_heci_device *device = NULL; + unsigned long currtime = get_seconds(); + + if (!heci_device) + return -ENODEV; + device = pci_get_drvdata(heci_device); + + if ((if_num != HECI_MINOR_NUMBER) || (!device) || (!file_extension)) + return -ENODEV; + spin_lock_bh(&device->device_lock); + + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + if (file_extension == &device->legacy_file_extension) { + priv_write_cb = find_pthi_read_list_entry(device, file, file_extension); + if ((priv_write_cb && currtime - priv_write_cb->read_time > LEGACY_READ_TIMER) || + (priv_write_cb && file_extension->reading_state == HECI_READ_COMPLETE)) { + *offset = 0; + list_del(&priv_write_cb->cb_list); + kfree(priv_write_cb->request_buffer.data); + kfree(priv_write_cb->response_buffer.data); + kfree(priv_write_cb); + } + } + + //free entry used in read + if (file_extension->reading_state == HECI_READ_COMPLETE) + { + *offset = 0; + priv_write_cb = find_read_list_entry(device, file_extension); + if ( priv_write_cb != NULL) { + list_del(&priv_write_cb->cb_list); + kfree(priv_write_cb->response_buffer.data); + priv_write_cb->response_buffer.data = NULL; + kfree(priv_write_cb); + priv_write_cb = NULL; + spin_lock(&file_extension->read_io_lock); + file_extension->reading_state = HECI_IDLE; + file_extension->read_cb = NULL; + file_extension->read_pending = FALSE; + spin_unlock(&file_extension->read_io_lock); + } + } + else if (file_extension->reading_state == HECI_IDLE && + file_extension->read_pending == FALSE){ + *offset = 0; + } + + spin_unlock_bh(&device->device_lock); + + priv_write_cb = kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!priv_write_cb) + return -ENOMEM; + spin_lock(&file_extension->file_lock); + priv_write_cb->request_buffer.data = NULL; + priv_write_cb->response_buffer.data = NULL; + priv_write_cb->file_object = file; + priv_write_cb->file_private = file_extension; + spin_unlock(&file_extension->file_lock); + priv_write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL); + if (!priv_write_cb->request_buffer.data) { + kfree(priv_write_cb); + return -ENOMEM; + } + DBG("length =%d\n", (int) length); + + if (copy_from_user(priv_write_cb->request_buffer.data, + ubuf, length)) { + return_status = -EFAULT; + goto fail; + } + + spin_lock(&file_extension->file_lock); + file_extension->sm_state = 0; + if (length == 4 && + ((memcmp(heci_wd_state_independence_msg[0], ubuf, 4) == 0) || + (memcmp(heci_wd_state_independence_msg[1], ubuf, 4) == 0))) { + file_extension->sm_state |= HECI_WD_STATE_INDEPENDENCE_MSG_SENT; + } + spin_unlock(&file_extension->file_lock); + + INIT_LIST_HEAD(&priv_write_cb->cb_list); + if (file_extension == &device->legacy_file_extension) { + priv_write_cb->response_buffer.data = + kmalloc(LEGACY_MTU, GFP_KERNEL); + if (!priv_write_cb->response_buffer.data) { + return_status = -ENOMEM; + goto fail; + } + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return_status = -ENODEV; + goto fail; + } + for (i = 0; i < device->num_heci_me_clients; i++) { + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + } + + BUG_ON(device->me_clients[i].client_id != + file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != device->legacy_file_extension.me_client_id)) { + spin_unlock_bh(&device->device_lock); + return_status = -ENODEV; + goto fail; + } else if (length > device->me_clients[i].properteis.max_message_length || length <= 0) { + spin_unlock_bh(&device->device_lock); + return_status = -EMSGSIZE; + goto fail; + } + + + priv_write_cb->response_buffer.size = LEGACY_MTU; + priv_write_cb->major_file_operations = HECI_IOCTL; + priv_write_cb->information = 0; + priv_write_cb->request_buffer.size = length; + if (device->legacy_file_extension.state != HECI_FILE_CONNECTED) { + spin_unlock_bh(&device->device_lock); + return_status = -ENODEV; + goto fail; + } + + if (!list_empty(&device->pthi_cmd_list.heci_cb.cb_list) + || device->legacy_state != HECI_LEGACY_IDLE) { + DBG("pthi_state = %d\n", (int) device->legacy_state); + DBG("add PTHI cb to pthi cmd waiting list\n"); + list_add_tail(&priv_write_cb->cb_list, + &device->pthi_cmd_list.heci_cb. + cb_list); + return_status = length; + } else { + DBG("call pthi write"); + return_status = pthi_write(device, priv_write_cb); + + if (ESUCCESS != return_status) { + DBG("pthi write failed with status = %d\n", + return_status); + spin_unlock_bh(&device->device_lock); + goto fail; + }; + return_status = length; + } + spin_unlock_bh(&device->device_lock); + return return_status; + } + + priv_write_cb->major_file_operations = HECI_WRITE; + /* make sure information is zero before we start */ + + priv_write_cb->information = 0; + priv_write_cb->request_buffer.size = length; + + spin_lock(&file_extension->write_io_lock); + DBG("host client = %d, ME client = %d\n", + file_extension->host_client_id, file_extension->me_client_id); + if (file_extension->state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + DBG("host client = %d, is not connected to ME client = %d", + file_extension->host_client_id, + file_extension->me_client_id); + + goto unlock; + } + for (i = 0; i < device->num_heci_me_clients; i++) { + if (device->me_clients[i].client_id == + file_extension->me_client_id) + break; + } + BUG_ON(device->me_clients[i].client_id != file_extension->me_client_id); + if (i == device->num_heci_me_clients) { + return_status = -ENODEV; + goto unlock; + } + if (length > device->me_clients[i].properteis.max_message_length + || length <= 0) { + return_status = -EINVAL; + goto unlock; + } + priv_write_cb->file_private = file_extension; + + spin_lock_bh(&device->device_lock); + if (flow_control_credentials(device, file_extension) && + device->host_buffer_is_empty) { + spin_unlock_bh(&device->device_lock); + device->host_buffer_is_empty = FALSE; + if (length > ((((device->host_hw_state & H_CBD) >> 24) * sizeof(__u32)) - sizeof(struct heci_message_header))) { + heci_header.length = (((device->host_hw_state & H_CBD) >> 24) + * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header.message_complete = 0; + } else { + heci_header.length = length; + heci_header.message_complete = 1; + } + heci_header.host_address = file_extension->host_client_id; + heci_header.me_address = file_extension->me_client_id; + heci_header.reserved = 0; + DBG("call heci_write_message header=%08x.\n", + *((__u32 *) & heci_header)); + spin_unlock(&file_extension->write_io_lock); + /* protect heci low level write */ + spin_lock_bh(&device->device_lock); + if (!heci_write_message(device, &heci_header, (unsigned char *) (priv_write_cb->request_buffer.data), + heci_header.length)) { + spin_unlock_bh(&device->device_lock); + kfree(priv_write_cb->request_buffer.data); + priv_write_cb->request_buffer.data = NULL; + kfree(priv_write_cb); + return_status = -ENODEV; + priv_write_cb->information = 0; + return return_status; + } + file_extension->writing_state = HECI_WRITING; + priv_write_cb->information = heci_header.length; + if (heci_header.message_complete) { + flow_control_reduce(device, file_extension); + list_add_tail(&priv_write_cb->cb_list, + &device->write_waiting_list.heci_cb. + cb_list); + } else { + list_add_tail(&priv_write_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device->device_lock); + + } else { + + spin_unlock_bh(&device->device_lock); + priv_write_cb->information = 0; + file_extension->writing_state = HECI_WRITING; + spin_unlock(&file_extension->write_io_lock); + list_add_tail(&priv_write_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + return length; + +unlock: + spin_unlock(&file_extension->write_io_lock); +fail: + kfree(priv_write_cb->request_buffer.data); + priv_write_cb->request_buffer.data = NULL; + kfree(priv_write_cb->response_buffer.data); + priv_write_cb->response_buffer.data = NULL; + kfree(priv_write_cb); + return return_status; + +} + +/** + * heci_ioctl - the IOCTL function + */ +static int heci_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long data) +{ + + int return_status = ESUCCESS; + int if_num = MINOR(inode->i_rdev); + struct heci_file_private *file_extension = file->private_data; + struct heci_message_data *u_msg = (struct heci_message_data *) data; /* in user space */ + struct heci_message_data k_msg; /* all in kernel on the stack */ + struct iamt_heci_device *device = NULL; + + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (!heci_device) + return -ENODEV; + device = pci_get_drvdata(heci_device); + if (((if_num != LEGACY_MINOR_NUMBER) + && (if_num != HECI_MINOR_NUMBER)) || (!device) + || (!file_extension)) + return -ENODEV; + if (device->heci_state != HECI_ENABLED) + return -ENODEV; + /* first copy from user all data needed */ + if (copy_from_user(&k_msg, u_msg, sizeof(k_msg))) { + DBG("first copy from user all data needed filed\n"); + return -EFAULT; + } + DBG("user message size is %d\n", k_msg.size); + + switch (cmd) { + case IOCTL_HECI_GET_VERSION: + DBG(": IOCTL_HECI_GET_VERSION\n"); + return_status = + heci_ioctl_get_version(device, if_num, u_msg, k_msg, + file_extension); + break; + case IOCTL_HECI_CONNECT_CLIENT: + DBG(": IOCTL_HECI_CONNECT_CLIENT.\n"); + return_status = + heci_ioctl_connect_client(device, if_num, u_msg, k_msg, + file); + break; + case IOCTL_HECI_WD: + DBG(": IOCTL_HECI_WD.\n"); + return_status = + heci_ioctl_wd(device, if_num, k_msg, file_extension); + break; + case IOCTL_HECI_BYPASS_WD: + DBG(":IOCTL_HECI_BYPASS_WD.\n"); + return_status = + heci_ioctl_bypass_wd(device,if_num,k_msg,file_extension); + break; + case IAMT_KCS_SEND_MESSAGE_COMMAND: + DBG(": IAMT_KCS_SEND_MESSAGE_COMMAND.\n"); + return_status = + legacy_ioctl_send_message(device, if_num, k_msg, file); + break; + case IAMT_KCS_RECEIVE_MESSAGE_COMMAND: + DBG(": IAMT_KCS_RECEIVE_MESSAGE_COMMAND.\n"); + return_status = + legacy_ioctl_receive_message(device, if_num, u_msg, + k_msg, file); + break; + + default: + return_status = -EINVAL; + break; + } + return return_status; +} + +/** + * heci_legacy_poll - the poll function + */ +static unsigned int heci_legacy_poll(struct file *file, poll_table * wait) +{ + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + unsigned int mask = 0; + struct iamt_heci_device *device = NULL; + struct heci_file_private *file_extension = file->private_data; + + + if (!heci_device || !file_extension) + return mask; + + device = pci_get_drvdata(heci_device); + + if ((if_num != LEGACY_MINOR_NUMBER) || (!device)) + return mask; + + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED){ + spin_unlock_bh(&device->device_lock); + return mask; + } + spin_unlock_bh(&device->device_lock); + if (file_extension == &device->legacy_file_extension) { + + poll_wait(file, &device->legacy_file_extension.wait, wait); + spin_lock(&device->legacy_file_extension.file_lock); + if (device->legacy_state == HECI_LEGACY_READ_COMPLETE + && device->legacy_file_object == file) { + mask |= (POLLIN | POLLRDNORM); + spin_lock_bh(&device->device_lock); + DBG("run next pthi legacy cb\n"); + run_next_legacy_cmd(device); + spin_unlock_bh(&device->device_lock); + } + spin_unlock(&device->legacy_file_extension.file_lock); + } + return mask; +} + +/** + * heci_poll - the poll function + */ +static unsigned int heci_poll(struct file *file, poll_table * wait) +{ + int if_num = MINOR((file->f_dentry->d_inode->i_rdev)); + unsigned int mask = 0; + struct heci_file_private *file_extension = file->private_data; + struct iamt_heci_device *device = NULL; + + if (!heci_device) + return mask; + + + device = pci_get_drvdata(heci_device); + + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file_extension)) + return mask; + + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED){ + spin_unlock_bh(&device->device_lock); + return mask; + + } + spin_unlock_bh(&device->device_lock); + if (file_extension == &device->legacy_file_extension) { + + + poll_wait(file, &device->legacy_file_extension.wait, wait); + spin_lock(&device->legacy_file_extension.file_lock); + if (device->legacy_state == HECI_LEGACY_READ_COMPLETE + && device->legacy_file_object == file) { + mask |= (POLLIN | POLLRDNORM); + spin_lock_bh(&device->device_lock); + DBG("run next pthi cb"); + run_next_legacy_cmd(device); + spin_unlock_bh(&device->device_lock); + } + spin_unlock(&device->legacy_file_extension.file_lock); + + } else{ + poll_wait(file, &file_extension->tx_wait, wait); + spin_lock(&file_extension->write_io_lock); + if (HECI_WRITE_COMPLETE == file_extension->writing_state) + mask |= (POLLIN | POLLRDNORM); + spin_unlock(&file_extension->write_io_lock); + } + return mask; +} + +#ifdef CONFIG_PM +static int heci_suspend(struct pci_dev* pdev, pm_message_t state) +{ + struct iamt_heci_device *device = pci_get_drvdata(pdev); + int err = 0; + + //Stop watchdog if exists + del_timer_sync(&device->wd_timer); + if (device->wd_file_extension.state == HECI_FILE_CONNECTED + && device->wd_timeout) { + spin_lock_bh(&device->device_lock); + g_sus_wd_timeout = device->wd_timeout; + device->wd_timeout = 0; + device->wd_due_counter = 0; + memcpy(device->wd_data, stop_wd_params, HECI_WD_PARAMS_SIZE); + device->stop = TRUE; + if (device->host_buffer_is_empty && + flow_control_credentials(device, &device->wd_file_extension)) { + device->host_buffer_is_empty = FALSE; + + if (!heci_send_wd(device)) + DBG("Send stop WD failed\n"); + else + flow_control_reduce(device, &device->wd_file_extension); + device->wd_pending = FALSE; + } else { + device->wd_pending = TRUE; + } + spin_unlock_bh(&device->device_lock); + device->wd_stoped = FALSE; + + err = + wait_event_interruptible_timeout(device->wait_stop_wd, + (TRUE == device->wd_stoped), 10 * HZ); + if (!device->wd_stoped) + DBG("stop wd failed to complete.\n"); + else { + DBG("stop wd complete %d.\n", err); + err = 0; + } + } + //Set new heci state + spin_lock_bh(&device->device_lock); + if (device->heci_state == HECI_ENABLED || + device->heci_state == HECI_RECOVERING_FROM_RESET) { + device->heci_state = HECI_POWER_DOWN; + heci_reset(device, FALSE); + } + spin_unlock_bh(&device->device_lock); + + pci_save_state(pdev); + + + pci_disable_device(pdev); + free_irq(pdev->irq, device); + + pci_set_power_state(pdev, PCI_D3hot); + + return err; +} + +static int heci_resume(struct pci_dev* pdev) +{ + struct iamt_heci_device *device = NULL; + int err = 0; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + + device = pci_get_drvdata(pdev); + if (!device) { + return -ENODEV; + } + + /* request and enable interrupt */ + device->irq = pdev->irq; + err = request_irq(device->irq, heci_isr_interrupt, IRQF_SHARED, + heci_driver_name, device); + if (err) { + HECI_ERR("Request_irq failure. irq = %d \n", device->irq); + return err; + } + + spin_lock_bh(&device->device_lock); + device->heci_state = HECI_POWER_UP; + heci_reset(device, TRUE); + spin_unlock_bh(&device->device_lock); + + //Start watchdog if stopped in suspend + if (g_sus_wd_timeout != 0) { + device->wd_timeout = g_sus_wd_timeout; + + memcpy(device->wd_data, start_wd_params, HECI_WD_PARAMS_SIZE); + memcpy(device->wd_data + HECI_WD_PARAMS_SIZE, &device->wd_timeout, + sizeof(__u16)); + device->wd_due_counter = 1; + + if (device->wd_timeout) + mod_timer(&device->wd_timer, jiffies); + g_sus_wd_timeout = 0; + } + return err; +} +#endif +MODULE_AUTHOR("Intel Corporation"); /* FIXME: Add email address here */ +MODULE_DESCRIPTION("Intel(R) AMT Management Interface"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_VERSION(DRIVER_VERSION); --- linux-2.6.28.orig/ubuntu/heci/kcompat.h +++ linux-2.6.28/ubuntu/heci/kcompat.h @@ -0,0 +1,165 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + +#ifndef _KCOMPAT_H_ +#define _KCOMPAT_H_ + +#include +#include +#include +#include +#include +#include +#include + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) ) +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,28) ) +#undef INIT_WORK +#define INIT_WORK(_work, _func) \ +do { \ + INIT_LIST_HEAD(&(_work)->entry); \ + (_work)->pending = 0; \ + (_work)->func = (void (*)(void *))_func; \ + (_work)->data = _work; \ + init_timer(&(_work)->timer); \ +} while (0) +#undef PREPARE_WORK +#define PREPARE_WORK(_work, _func) \ + do { \ + (_work)->func = (void (*)(void *))_func;\ + (_work)->data = _work;\ + } while (0) + + +#endif + +#ifndef round_jiffies +#define round_jiffies(x) x +#endif + +#endif /* < 2.6.20 */ + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ) + +#ifndef IRQF_PROBE_SHARED +#ifdef SA_PROBEIRQ +#define IRQF_PROBE_SHARED SA_PROBEIRQ +#else +#define IRQF_PROBE_SHARED 0 +#endif +#endif + +#ifndef IRQF_SHARED +#define IRQF_SHARED SA_SHIRQ +#endif + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +#endif /* < 2.6.18 */ + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) ) + +#ifndef RHEL_VERSION +#define RHEL_VERSION 0 +#endif +#if (!(( RHEL_VERSION == 4 ) && ( RHEL_UPDATE >= 5 ))) +typedef irqreturn_t (*irq_handler_t)(int, void*, struct pt_regs *); +#endif +typedef irqreturn_t (*new_handler_t)(int, void*); +static inline irqreturn_t _kc_request_irq(unsigned int irq, new_handler_t handler, unsigned long flags, const char *devname, void *dev_id) +{ + irq_handler_t new_handler = (irq_handler_t) handler; + return request_irq(irq, new_handler, flags, devname, dev_id); +} + +#undef request_irq +#define request_irq(irq, handler, flags, devname, dev_id) _kc_request_irq((irq), (handler), (flags), (devname), (dev_id)) + +#endif + + +/*****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) ) +#define SHUTDOWN_METHOD(method) +#define HECI_REBOOT_NOTIFIER(reboot_notifier, driver, reboot_function) \ +static int heci_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) \ +{ \ + struct pci_dev *pdev = NULL; \ +\ + switch(event){ \ + case SYS_DOWN: \ + case SYS_HALT: \ + case SYS_POWER_OFF: \ + while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev))) { \ + if (pci_dev_driver(pdev) == &driver) { \ + reboot_function(pdev); \ + } \ + } \ + } \ + return NOTIFY_DONE; \ +};\ +static struct notifier_block reboot_notifier = { \ + .notifier_call = heci_notify_reboot, \ + .next = NULL, \ + .priority = 0 \ +}; + +#define REGISTER_REBOOT_NOTIFIER(reboot_notifier) \ + register_reboot_notifier(&reboot_notifier); +#define UNREGISTER_REBOOT_NOTIFIER(reboot_notifier) \ + unregister_reboot_notifier(&reboot_notifier); +#else +#define SHUTDOWN_METHOD(method) .shutdown = method, +#define HECI_REBOOT_NOTIFIER(reboot_notifier, driver, reboot_function) +#define REGISTER_REBOOT_NOTIFIER(reboot_notifier) +#define UNREGISTER_REBOOT_NOTIFIER(reboot_notifier) +#define heci_reboot_notifier +#endif //( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) ) + + +#endif --- linux-2.6.28.orig/ubuntu/heci/Kconfig +++ linux-2.6.28/ubuntu/heci/Kconfig @@ -0,0 +1,3 @@ +config HECI + tristate "Intel(R) Manageability Engine Interface Driver" + default m --- linux-2.6.28.orig/ubuntu/heci/heci_data_structures.h +++ linux-2.6.28/ubuntu/heci/heci_data_structures.h @@ -0,0 +1,538 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + +#ifndef _HECI_DATA_STRUCTURES_H_ +#define _HECI_DATA_STRUCTURES_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * error code definition + */ +#define ESUCCESS 0 +#define ESLOTS_OVERFLOW 1 +#define ECORRUPTED_MESSAGE_HEADER 1000 +#define ECOMPLETE_MESSAGE 1001 +#define FC_MESSAGE_RESERVED_LENGTH 5 + +/** + * Number of queue lists used by this driver + */ +#define NUMBER_OF_LISTS 7 + +#define LEGACY_MTU 4160 +#pragma pack(1) + + +/** + * HECI HW Section + */ + +/* HECI addresses and defines */ +#define H_CB_WW 0 +#define H_CSR 4 +#define ME_CB_RW 8 +#define ME_CSR_HA 0xC + + +/* register bits - H_CSR */ + +#define H_CBD 0xFF000000 +#define H_CBWP 0x00FF0000 +#define H_CBRP 0x0000FF00 +#define H_RST 0x00000010 +#define H_RDY 0x00000008 +#define H_IG 0x00000004 +#define H_IS 0x00000002 +#define H_IE 0x00000001 + + +/* register bits - ME_CSR_HA */ +#define ME_CBD_HRA 0xFF000000 +#define ME_CBWP_HRA 0x00FF0000 +#define ME_CBRP_HRA 0x0000FF00 +#define ME_RST_HRA 0x00000010 +#define ME_RDY_HRA 0x00000008 +#define ME_IG_HRA 0x00000004 +#define ME_IS_HRA 0x00000002 +#define ME_IE_HRA 0x00000001 + +/** + * heci driver use additional char device for legacy mode + */ +#define MINORS_COUNT 2 + +#define LEGACY_MINOR_NUMBER 0 +#define HECI_MINOR_NUMBER 1 +#define MAX_OPEN_HANDLE_COUNT 253 +/** + * debug kernel print macro define + */ +#define HECI_INFO(format, arg...) printk(KERN_INFO "%s: " format, THIS_MODULE->name, ## arg) +#define HECI_ERR(format, arg...) printk(KERN_ERR "%s: " format, THIS_MODULE->name, ## arg) +#define HECI_WARN(format, arg...) printk(KERN_WARNING "%s: " format, THIS_MODULE->name, ## arg) + + +/* Module Parameters */ +#define DEF_PARM(type, name, init, perm, desc) \ + type name = (init); \ + MODULE_PARM_DESC(name, desc); \ + module_param(name, type, perm) + +extern int debug; + +#define DBG(format, arg...) do {if (debug) \ +printk(KERN_ERR "%s: " format , __func__ , ## arg); \ +} while (0) + +#ifdef HECI_DEBUG +#define assert(expr) do {} while (0) +#else +#define assert(expr) \ + if (!(expr)) { \ + printk("Assertion failed! %s, %s, %s, line=%d\n", \ + #expr, __FILE__, __func__, __LINE__); \ + } +#endif + +/** + * time to wait event + */ +#define HECI_INTEROP_TIMEOUT (HZ * 7) + +/** + * watch dog definition + */ +#define HECI_WATCHDOG_DATA_SIZE 16 +#define HECI_START_WD_DATA_SIZE 20 +#define HECI_WD_PARAMS_SIZE 4 + +#define HECI_NO_MSG_SENT 0 +#define HECI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0) + + +#define HECI_WD_HOST_CLIENT_ID 1 +#define HECI_LEGACY_HOST_CLIENT_ID 2 + +#undef FALSE +#undef TRUE +#define TRUE 1 +#define FALSE 0 + +struct guid { + __u32 data1; + __u16 data2; + __u16 data3; + __u8 data4[8]; +}; + +/* File state */ +enum file_state { + HECI_FILE_INITIALIZING = 0, + HECI_FILE_CONNECTING, + HECI_FILE_CONNECTED, + HECI_FILE_DISCONNECTING, + HECI_FILE_DISCONNECTED +}; + +/* HECI states */ +enum heci_states{ + HECI_INITIALIZING = 0, + HECI_ENABLED, + HECI_RESETING, + HECI_DISABLED, + HECI_RECOVERING_FROM_RESET, + HECI_POWER_DOWN, + HECI_POWER_UP +}; + +enum legacy_states { + HECI_LEGACY_IDLE, + HECI_LEGACY_WRITING, + HECI_LEGACY_FLOW_CONTROL, + HECI_LEGACY_READING, + HECI_LEGACY_READ_COMPLETE +}; + +enum heci_file_transaction_states { + HECI_IDLE, + HECI_WRITING, + HECI_WRITE_COMPLETE, + HECI_FLOW_CONTROL, + HECI_READING, + HECI_READ_COMPLETE +}; + +/* HECI CB */ +enum heci_cb_major_types { + HECI_READ = 0, + HECI_WRITE, + HECI_IOCTL, + HECI_OPEN, + HECI_CLOSE +}; + +/* HECI user data struct */ +struct heci_message_data { + __u32 size; + char *data; +}; +#define SECOND_TO_MILLI 1000 +#define SECOND_TO_MICRO SECOND_TO_MILLI * 1000 +#define SECOND_TO_100NANO SECOND_TO_MICRO * 10 + +#define CONNECT_TIMEOUT 3 /* at least 2 seconds */ + +#define LEGACY_STALL_TIMER 12 /* seconds */ +#define LEGACY_READ_TIMER 15 /* seconds */ + +struct heci_cb_private { + struct list_head cb_list; + enum heci_cb_major_types major_file_operations; + void *file_private; + struct heci_message_data request_buffer; + struct heci_message_data response_buffer; + unsigned long information; + unsigned long read_time; + struct file *file_object; +}; + +/* Private file struct */ +struct heci_file_private { + struct list_head link; + struct file *file; + enum file_state state; + wait_queue_head_t tx_wait; + wait_queue_head_t rx_wait; + wait_queue_head_t wait; + spinlock_t file_lock; + spinlock_t read_io_lock; + spinlock_t write_io_lock; + int read_pending; + int status; + /* ID of client connected */ + __u8 host_client_id; + __u8 me_client_id; + __u8 flow_control_credentials; + __u8 timer_count; + enum heci_file_transaction_states reading_state; + enum heci_file_transaction_states writing_state; + int sm_state; + struct heci_cb_private *read_cb; +}; + +struct io_heci_list { + struct heci_cb_private heci_cb; + int status; + struct iamt_heci_device *device_extension; +}; + +struct heci_driver_version { + __u8 major; + __u8 minor; + __u8 hotfix; + __u16 build; +}; + + +struct heci_client { + __u32 max_message_length; + __u8 protocol_version; +}; +/* + * HECI BUS Interface Section + */ +struct heci_message_header { + __u32 me_address:8; + __u32 host_address:8; + __u32 length:9; + __u32 reserved:6; + __u32 message_complete:1; +}; + + +struct hbm_command { + __u8 command:7; + __u8 is_response:1; +}; + + +struct heci_bus_message { + struct hbm_command command; + __u8 command_specific_data[]; +}; + +struct hbm_version { + __u8 minor_version; + __u8 major_version; +}; + +struct hbm_host_version_request { + struct hbm_command command; + __u8 reserved; + struct hbm_version host_version; +}; + +struct hbm_host_version_response { + struct hbm_command command; + int host_version_supported; + struct hbm_version me_max_version; +}; + +struct hbm_host_stop_request { + struct hbm_command command; + __u8 reason; + __u8 reserved[2]; +}; + +struct hbm_host_stop_response { + struct hbm_command command; + __u8 reserved[3]; +}; + +struct hbm_me_stop_request { + struct hbm_command command; + __u8 reason; + __u8 reserved[2]; +}; + +struct hbm_host_enumeration_request { + struct hbm_command command; + __u8 reserved[3]; +}; + +struct hbm_host_enumeration_response { + struct hbm_command command; + __u8 reserved[3]; + __u8 valid_addresses[32]; +}; + +struct heci_client_properties { + struct guid protocol_name; + __u8 protocol_version; + __u8 max_number_of_connections; + __u8 fixed_address; + __u8 single_receive_buffer; + __u32 max_message_length; +}; + +struct hbm_host_client_properties_request { + struct hbm_command command; + __u8 address; + __u8 reserved[2]; +}; + + +struct hbm_host_client_properties_response { + struct hbm_command command; + __u8 address; + __u8 status; + __u8 reserved[1]; + struct heci_client_properties client_properties; +}; + +struct hbm_client_connect_request { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 reserved; +}; + +struct hbm_client_connect_response { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 status; +}; + +struct hbm_client_disconnect_request { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 reserved[1]; +}; + +struct hbm_flow_control { + struct hbm_command command; + __u8 me_address; + __u8 host_address; + __u8 reserved[FC_MESSAGE_RESERVED_LENGTH]; +}; + +struct heci_me_client { + struct heci_client_properties properteis; + __u8 client_id; + __u8 flow_control_credentials; +}; + +/* private device struct */ +struct iamt_heci_device { + struct pci_dev *pdev; /* pointer to pci device struct */ + /* + * lists of queues + */ + struct io_heci_list *io_list_array[NUMBER_OF_LISTS]; /* array of pointers to aio lists */ + struct io_heci_list read_list; /* driver read queue */ + struct io_heci_list write_list; /* driver write queue */ + struct io_heci_list write_waiting_list; /* driver write waiting queue */ + struct io_heci_list control_write_list; /* driver managed write IOCTL list */ + struct io_heci_list control_read_list; /* driver managed read IOCTL list */ + struct io_heci_list pthi_cmd_list; /* driver managed PTHI list for cmd waiting */ + struct io_heci_list pthi_read_complete_list; /* driver managed PTHI list for read completed pthi command data */ + /* + * list of files + */ + struct list_head file_list; + /* + * memory of device + */ + unsigned int mem_base; + unsigned int mem_length; + char *mem_addr; + /* + * lock for the device + */ + spinlock_t device_lock; + spinlock_t extra_lock; + /* + * intterupts + */ + int irq; + struct work_struct work; + int received_message; + + struct timer_list timer; + struct timer_list wd_timer; + /* + * hw states of host and fw(ME) + */ + __u32 host_hw_state; + __u32 me_hw_state; + /* + * waiting queue for receive message from FW + */ + wait_queue_head_t wait_received_message; + wait_queue_head_t wait_stop_wd; + /* + * heci device states + */ + enum heci_states heci_state; + int stop; + /** + * virtual void GetParam(const char* UserParam); + * read write messages to/from heci fw + */ + __u32 extra_write_index; + __u32 read_message_buffer[128]; /* used for control messages */ + __u32 write_message_buffer[128]; /* used for control messages */ + __u32 extra_message_buffer[8]; /* for control responses */ + __u32 read_message_header; + + struct hbm_version version; + + int host_buffer_is_empty; + struct heci_file_private wd_file_extension; + struct heci_me_client *me_clients; /* Note: memory has to be allocated */ + __u8 heci_me_clients[32]; /* list of existing clients */ + __u8 num_heci_me_clients; + __u8 heci_host_clients[32]; /* list of existing clients */ + __u8 current_host_client_id; + + int wd_pending; + int wd_stoped; + __u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */ + unsigned char wd_data[HECI_START_WD_DATA_SIZE]; + + + __u16 wd_due_counter; + int asf_mode; + int wd_bypass; /* if true,don't refresh watchdog ME client */ + + /* maybe this is not required */ + struct file *legacy_file_object; + struct heci_file_private legacy_file_extension; + int legacy_ioctl; + int legacy_canceled; + __u32 legacy_timer; + __u32 legacy_stall_timer; + unsigned char legacy_message_buffer[LEGACY_MTU]; + __u32 legacy_message_buffer_size; + __u32 legacy_message_buffer_index; + int legacy_flow_control_pending; + enum legacy_states legacy_state; + + struct heci_cb_private *legacy_current_cb; + __u8 write_hang; + int need_reset; + long open_handle_count; + +}; + +/** + * read_heci_register - Read a byte from the heci device + * @device: the device structure + * @offset: offset from which to read the data + * + * Return: + * the byte read. + */ +__u32 read_heci_register(struct iamt_heci_device * device, + unsigned long offset); + +/** + * write_heci_register - Write 4 bytes to the heci device + * @device: the device structure + * @offset: offset from which to write the data + * + * @value: the byte to write + */ +void write_heci_register(struct iamt_heci_device * device, unsigned long offset, + __u32 value); + +#endif /* _HECI_DATA_STRUCTURES_H_ */ --- linux-2.6.28.orig/ubuntu/heci/interrupt.c +++ linux-2.6.28/ubuntu/heci/interrupt.c @@ -0,0 +1,1413 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2006-2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + +#include +#include +#include "kcompat.h" +#include "heci.h" +#include "heci_interface.h" + +/** + * interrupt function prototypes + */ + +void heci_bh_handler(struct work_struct *work); +int heci_bh_read_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots); +int heci_bh_write_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots); +void heci_bh_read_bus_message(struct iamt_heci_device * device_object, + struct heci_message_header * heci_header); +int heci_bh_read_pthi_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header); +int heci_bh_read_client_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header); +void heci_client_connect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + connect_res); +void heci_client_disconnect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + disconnect_res); +void heci_client_flow_control_response(struct iamt_heci_device * device_object, + struct hbm_flow_control * flow_control); +void heci_client_disconnect_request(struct iamt_heci_device * device_object, + struct hbm_client_disconnect_request * + disconnect_req); + + +/** + * heci_isr_interrupt - The ISR of the HECI device + * @irq: The irq number + * @dev_id: pointer to the device structure + * @regs: the register values + * + * @return : + * irqreturn_t + */ +irqreturn_t heci_isr_interrupt(int irq, void *dev_id) +{ + int err; + struct iamt_heci_device *device = (struct iamt_heci_device *) dev_id; + device->host_hw_state = read_heci_register(device, H_CSR); + + if ((device->host_hw_state & H_IS) != H_IS) + return IRQ_NONE; + + /* disable interrupts */ + device->host_hw_state &= ~H_IE; + /* acknowledge interrupt and stop interupts */ + write_heci_register(device, H_CSR, device->host_hw_state); + /** + * Our device interrupted, schedule work the heci_bh_handler + * to handle the interrupt processing. This needs to be a + * workqueue item since the handler can sleep. + */ + PREPARE_WORK(&device->work, heci_bh_handler); + DBG("schedule work the heci_bh_handler \n"); + err = schedule_work(&device->work); + if (!err) + HECI_ERR("schedule work the heci_bh_handler failed error=%x\n", + err); + return IRQ_HANDLED; +} + +/** + * heci_bh_handler - function called after ISR to handle the interrupt processing. + * @data: pointer to the device structure + * + * NOTE: This function is called by schedule work + * @return : + * none; + */ +void heci_bh_handler(struct work_struct *work) +{ + struct iamt_heci_device *device = container_of(work, struct iamt_heci_device, work); + struct io_heci_list complete_list; + __s32 slots; + int return_status; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + struct heci_file_private *file_extension = NULL; + int bus_message_received = FALSE; + struct task_struct *tsk; + + DBG("function called after ISR to handle the interrupt processing.\n"); + /* initialize our complete list */ + spin_lock_bh(&device->device_lock); + heci_initialize_list(&complete_list, device); + device->host_hw_state = read_heci_register(device, H_CSR); + device->me_hw_state = read_heci_register(device, ME_CSR_HA); + + /* check if ME wants a reset */ + if (((device->me_hw_state & ME_RDY_HRA) == 0) && + (device->heci_state != HECI_RESETING) + && (device->heci_state != HECI_INITIALIZING)) { + DBG("FW not ready.\n"); + heci_reset(device, TRUE); + spin_unlock_bh(&device->device_lock); + return; + } + + /* check if we need to start the device */ + if ((device->host_hw_state & H_RDY) == 0) { + + if ((device->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) { + DBG("we need to start the device.\n"); + device->host_hw_state |= (H_IE | H_IG | H_RDY); + write_heci_register(device, H_CSR, + device->host_hw_state); + if (device->heci_state == HECI_INITIALIZING) { + + device->received_message = TRUE; + spin_unlock_bh(&device->device_lock); + wake_up_interruptible(&device-> + wait_received_message); + return; + + } else { + spin_unlock_bh(&device->device_lock); + tsk = kthread_run(heci_initialize_clients, + device, "heci"); + if (IS_ERR(tsk)) { + int rc = PTR_ERR(tsk); + printk(KERN_WARNING "heci: " + "Unable to start the thread for heci: %d\n", + rc); + } + return; + } + + + } else { + DBG("Enable interrupt FW not ready \n"); + device->host_hw_state |= (H_IE); + write_heci_register(device, H_CSR, + device->host_hw_state); + spin_unlock_bh(&device->device_lock); + return; + } + } + /* check slots avalable for reading */ + slots = count_full_read_slots(device); + DBG("slots =%08x extra_write_index =%08x.\n", slots, + device->extra_write_index); + while ((slots > 0) && (!device->extra_write_index)) { + DBG("slots =%08x extra_write_index =%08x.\n", slots, + device->extra_write_index); + DBG("call heci_bh_read_handler.\n"); + return_status = + heci_bh_read_handler(&complete_list, device, &slots); + if (return_status != ESUCCESS) + goto end; + } + return_status = + heci_bh_write_handler(&complete_list, device, &slots); +end: + DBG("end of bottom half function.\n"); + device->host_hw_state = read_heci_register(device, H_CSR); + device->host_buffer_is_empty = host_buffer_is_empty(device); + + if ((device->host_hw_state & H_IS) == H_IS) { + PREPARE_WORK(&device->work, heci_bh_handler); + DBG("schedule work the heci_bh_handler.\n"); + return_status = schedule_work(&device->work); + if (!return_status) + HECI_ERR("schedule work the heci_bh_handler failed error=%x\n", return_status); + } else { + device->host_hw_state |= H_IE; + } + + write_heci_register(device, H_CSR, device->host_hw_state); + + + if (device->received_message + && waitqueue_active(&device->wait_received_message)) { + DBG("received waiting bus message\n"); + bus_message_received = TRUE; + } + spin_unlock_bh(&device->device_lock); + if (bus_message_received) { + DBG("wake up device->wait_received_message\n"); + wake_up_interruptible(&device->wait_received_message); + bus_message_received = FALSE; + } + if (complete_list.status != ESUCCESS || list_empty(&complete_list.heci_cb.cb_list)){ + return; + } + + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &complete_list.heci_cb.cb_list, cb_list){ + + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + list_del(&kernel_priv_cb_pos->cb_list); + if (file_extension && file_extension != &device->legacy_file_extension) { + DBG("completing call back.\n"); + if (kernel_priv_cb_pos->major_file_operations == HECI_WRITE) { + + kfree(kernel_priv_cb_pos-> request_buffer.data); + kernel_priv_cb_pos->request_buffer.data = NULL; + kfree(kernel_priv_cb_pos); + kernel_priv_cb_pos = NULL; + DBG("completing write call back.\n"); + file_extension->writing_state = + HECI_WRITE_COMPLETE; + if (&file_extension->tx_wait && + waitqueue_active (&file_extension->tx_wait)) { + wake_up_interruptible + (&file_extension->tx_wait); + } + } else if (kernel_priv_cb_pos->major_file_operations == HECI_READ + && HECI_READING == file_extension->reading_state) { + DBG("completing read call back information= %lu\n", + kernel_priv_cb_pos->information); + file_extension->reading_state = HECI_READ_COMPLETE; + if (&file_extension->rx_wait + && waitqueue_active (&file_extension->rx_wait)) { + wake_up_interruptible + (&file_extension->rx_wait); + } + + } + } else if (file_extension == &device->legacy_file_extension) { + if (device->legacy_canceled != TRUE) { + device->legacy_state = HECI_LEGACY_READ_COMPLETE; + device->legacy_stall_timer = 0; + memcpy(kernel_priv_cb_pos->response_buffer. + data, + device-> + legacy_message_buffer, + device-> + legacy_message_buffer_index); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device-> + pthi_read_complete_list. + heci_cb.cb_list); + DBG("pthi read completed\n"); + } else { + run_next_legacy_cmd(device); + } + if (&device->legacy_file_extension.wait) { + DBG("completing pthi call back.\n"); + wake_up_interruptible(&device-> + legacy_file_extension. + wait); + + } + + } + } + return; +} + + +/** + * heci_bh_read_handler - bottom half read routine after ISR to handle the read processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @slots - slots to read. + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_read_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots) +{ + struct heci_message_header *heci_header; + int ret = ESUCCESS; + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + if (!device_object->read_message_header) { + device_object->read_message_header = + read_heci_register(device_object, ME_CB_RW); + DBG("slots=%08x.\n", *slots); + (*slots)--; + DBG("slots=%08x.\n", *slots); + } + heci_header = + (struct heci_message_header *) & device_object->read_message_header; + DBG("heci_header->length =%d\n", heci_header->length); + + if ((heci_header->reserved) + || !(device_object->read_message_header)) { + DBG("corrupted message header.\n"); + ret = -ECORRUPTED_MESSAGE_HEADER; + goto end; + } + if (heci_header->host_address || heci_header->me_address) { + + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + DBG("list_for_each_entry_safe read host client = %d, ME client = %d\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + if ((file_extension_pos->host_client_id == heci_header->host_address) + && (file_extension_pos->me_client_id == heci_header->me_address)) + break; + } + + if (&file_extension_pos->link==&device_object->file_list) { + DBG("corrupted message header\n"); + ret = -ECORRUPTED_MESSAGE_HEADER; + goto end; + + } + } + if (((*slots) * sizeof(__u32)) < heci_header->length) { + DBG("we can't read the message slots=%08x.\n", *slots); + /* we can't read the message */ + ret = -ERANGE; + goto end; + } + + + /* decide where to read the message too */ + if (!heci_header->host_address) { + DBG("call heci_bh_read_bus_message.\n"); + heci_bh_read_bus_message(device_object, heci_header); + DBG("end heci_bh_read_bus_message.\n"); + } else if (heci_header->host_address == + device_object->legacy_file_extension.host_client_id + && HECI_FILE_CONNECTED == + device_object->legacy_file_extension.state + && device_object->legacy_state == HECI_LEGACY_READING) { + DBG("call heci_bh_read_legacy_message.\n"); + DBG("heci_header->length =%d\n", heci_header->length); + ret = + heci_bh_read_pthi_message(complete_list, device_object, + heci_header); + if (ret != ESUCCESS) + goto end; + } else { + DBG("call heci_bh_read_client_message.\n"); + ret = heci_bh_read_client_message(complete_list, + device_object, + heci_header); + if (ret != ESUCCESS) + goto end; + } + + /* reset the number of slots and header */ + *slots = count_full_read_slots(device_object); + device_object->read_message_header = 0; + + if (*slots == -ESLOTS_OVERFLOW) { /* overflow - reset */ + DBG("reseting due to slots overflow\n"); + /* set the event since message has been read */ + ret = -ERANGE; + goto end; + } +end: + + return ret; + +} + + +/** + * heci_bh_read_bus_message - bottom half read routine after ISR to handle the read bus message + * command processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @buffer - message buffer will be filled + * @heci_header - header of bus message + * + * @return : + * none; + */ +void heci_bh_read_bus_message(struct iamt_heci_device * device_object, + struct heci_message_header * heci_header) +{ + struct heci_bus_message *heci_message; + struct hbm_host_version_response *version_res; + struct hbm_client_connect_response *connect_res; + struct hbm_client_connect_response *disconnect_res; + struct hbm_flow_control *flow_control; + struct hbm_host_client_properties_response *properteis_res; + struct hbm_host_enumeration_response *enum_res; + struct hbm_client_disconnect_request *disconnect_req; + struct hbm_host_stop_request *h_stop_req; + int i; + unsigned char *buffer; + buffer = NULL; + /* read the message to our buffer */ + buffer = (unsigned char *) device_object->read_message_buffer; + BUG_ON(heci_header->length >= + sizeof(device_object->read_message_buffer)); + heci_read_slots(device_object, buffer, heci_header->length); + heci_message = (struct heci_bus_message *) buffer; + + switch (*(__u8 *) heci_message) { + case HOST_START_RES_CMD: + version_res = (struct hbm_host_version_response *) heci_message; + if (version_res->host_version_supported) { + device_object->version.major_version = + HBM_MAJOR_VERSION; + device_object->version.minor_version = + HBM_MINOR_VERSION; + } else { + device_object->version = + version_res->me_max_version; + } + device_object->received_message = TRUE; + DBG("host start response message received.\n"); + break; + + case CLIENT_CONNECT_RES_CMD: + connect_res = + (struct hbm_client_connect_response *) heci_message; + heci_client_connect_response(device_object, connect_res); + DBG("client connect response message received.\n"); + wake_up(&device_object->wait_received_message); + break; + + case CLIENT_DISCONNECT_RES_CMD: + disconnect_res = + (struct hbm_client_connect_response *) heci_message; + heci_client_disconnect_response(device_object, + disconnect_res); + DBG("client disconnect response message received.\n"); + wake_up(&device_object->wait_received_message); + break; + + case FLOW_CONTROL_CMD: + flow_control = (struct hbm_flow_control *) heci_message; + heci_client_flow_control_response(device_object, + flow_control); + DBG("client flow control response message received.\n"); + break; + case HOST_CLIENT_PROPERTEIS_RES_CMD: + properteis_res = + (struct hbm_host_client_properties_response *) heci_message; + + + if (properteis_res->status != 0) { + BUG_ON(1); + break; + } + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (device_object->me_clients[i].client_id == + properteis_res->address) { + device_object->me_clients[i].properteis = + properteis_res->client_properties; + break; + } + + } + device_object->received_message = TRUE; + break; + case HOST_ENUM_RES_CMD: + enum_res = + (struct hbm_host_enumeration_response *) heci_message; + memcpy(device_object->heci_me_clients, + enum_res->valid_addresses, 32); + device_object->received_message = TRUE; + break; + case HOST_STOP_RES_CMD: + device_object->heci_state = HECI_DISABLED; + DBG("Reseting becase of FW stop response\n"); + heci_reset(device_object, TRUE); + break; + case CLIENT_DISCONNECT_REQ_CMD: + /* search for client */ + disconnect_req = + (struct hbm_client_disconnect_request *) heci_message; + heci_client_disconnect_request(device_object, + disconnect_req); + break; + case ME_STOP_REQ_CMD: + /* prepare stop request */ + heci_header = + (struct heci_message_header *) & device_object-> + extra_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_stop_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + h_stop_req = + (struct hbm_host_stop_request *) & device_object-> + extra_message_buffer[1]; + memset(h_stop_req, 0, sizeof(struct hbm_host_stop_request)); + h_stop_req->command.command = HOST_STOP_REQ_CMD; + h_stop_req->reason = DRIVER_STOP_REQUEST; + h_stop_req->reserved[0] = 0; + h_stop_req->reserved[1] = 0; + device_object->extra_write_index = 2; + break; + + default: + BUG_ON(1); + break; + + } + + return; + +} + +/** + * heci_bh_read_legacy_message - bottom half read routine after ISR to handle the read legacy message + * data processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @buffer - message buffer will be filled + * @heci_header - header of legacy message + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_read_pthi_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header) +{ + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *priv_cb = NULL; + int return_status = ESUCCESS; + unsigned char *buffer = NULL; + BUG_ON(heci_header->me_address != + device_object->legacy_file_extension.me_client_id); + BUG_ON(device_object->legacy_state != HECI_LEGACY_READING); + buffer = + (unsigned char *) (device_object->legacy_message_buffer + + device_object->legacy_message_buffer_index); + BUG_ON(sizeof(device_object->legacy_message_buffer) < + (device_object->legacy_message_buffer_index + + heci_header->length)); + heci_read_slots(device_object, buffer, heci_header->length); + + device_object->legacy_message_buffer_index += heci_header->length; + + if (heci_header->message_complete) { + DBG("pthi_message_buffer_index=%d\n", heci_header->length); + DBG("completed pthi read.\n "); + if (!device_object->legacy_current_cb) + return -ENODEV; + priv_cb = device_object->legacy_current_cb; + device_object->legacy_current_cb = NULL; + file_extension = + (struct heci_file_private *) priv_cb->file_private; + if (!file_extension) + return -ENODEV; + device_object->legacy_stall_timer = 0; + priv_cb->information = + device_object->legacy_message_buffer_index; + priv_cb->read_time = get_seconds(); + if (device_object->legacy_ioctl + && file_extension == &device_object->legacy_file_extension) { + /* found the legacy cb */ + DBG("complete the pthi read cb.\n "); + if (&device_object->legacy_file_extension) { + DBG("add the pthi read cb to complete.\n "); + list_add_tail(&priv_cb->cb_list, + &complete_list->heci_cb. + cb_list); + + } + } + } + return return_status; + +} + +/** + * heci_bh_read_client_message - bottom half read routine after ISR to handle the read heci client message + * data processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @buffer - message buffer will be filled + * @heci_header - header of heci client message + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_read_client_message(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + struct heci_message_header * heci_header) +{ + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + unsigned char *buffer = NULL; + DBG ("Start client msg \n"); + if (device_object->read_list.status == ESUCCESS + && !list_empty(&device_object->read_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + read_list.heci_cb.cb_list, cb_list){ + file_extension = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + if ((file_extension->host_client_id == heci_header->host_address) + && (file_extension->me_client_id == heci_header->me_address) + && (file_extension->state == HECI_FILE_CONNECTED) + && (HECI_READ_COMPLETE != file_extension->reading_state)) { + spin_lock(&file_extension->read_io_lock); + file_extension->reading_state = + HECI_READING; + buffer = (unsigned char *) (kernel_priv_cb_pos->response_buffer.data + + kernel_priv_cb_pos->information); + BUG_ON(kernel_priv_cb_pos->response_buffer.size < heci_header->length + + kernel_priv_cb_pos->information); + + if (kernel_priv_cb_pos->response_buffer.size < heci_header->length + + kernel_priv_cb_pos->information) { + DBG(" message overflow.\n"); + list_del(&kernel_priv_cb_pos->cb_list); + spin_unlock(&file_extension-> + read_io_lock); + return -ENOMEM; + } + if (buffer) + heci_read_slots(device_object, + buffer, + heci_header-> + length); + kernel_priv_cb_pos->information += + heci_header->length; + if (heci_header->message_complete) { + file_extension->status = ESUCCESS; + list_del(&kernel_priv_cb_pos->cb_list); + spin_unlock(&file_extension-> + read_io_lock); + DBG("completed read host client = %d, ME client = %d, data length = %lu\n", + file_extension->host_client_id, + file_extension->me_client_id, + kernel_priv_cb_pos->information); + *(kernel_priv_cb_pos->response_buffer.data + kernel_priv_cb_pos->information) = '\0'; + DBG("kernel_priv_cb_pos->response_buffer - %s\n", + kernel_priv_cb_pos->response_buffer.data); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb.cb_list); + } else { + spin_unlock(&file_extension-> + read_io_lock); + } + + break; + } + + } + + } + DBG ("Message read\n"); + if (!buffer) { + heci_read_slots(device_object, + (unsigned char *) device_object-> + read_message_buffer, heci_header->length); + DBG("discarding message, header=%08x.\n", + *(__u32 *) device_object->read_message_buffer); + } + + return ESUCCESS; +} + + +/** + * heci_bh_write_handler - bottom half write routine after ISR to handle the write processing. + * + * + * @complete_list - An instance of our list structure + * @device_object - Device object for our driver + * @slots - slots to write. + * @return : + * 0 on success, + * negative on failure. + */ +int heci_bh_write_handler(struct io_heci_list *complete_list, + struct iamt_heci_device * device_object, + __s32 * slots) +{ + + struct heci_message_header *heci_header = NULL; + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + + if (!host_buffer_is_empty(device_object)) { + DBG("host buffer is not empty.\n"); + return ESUCCESS; + } + device_object->write_hang = -1; + *slots = count_empty_write_slots(device_object); + /* complete all waiting for write CB */ + DBG("complete all waiting for write CB.\n"); + if (device_object->write_waiting_list.status == ESUCCESS + && !list_empty(&device_object->write_waiting_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + write_waiting_list.heci_cb.cb_list, cb_list){ + file_extension = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + file_extension->status = ESUCCESS; + list_del(&kernel_priv_cb_pos->cb_list); + if (HECI_WRITING == file_extension->writing_state + && kernel_priv_cb_pos->major_file_operations == HECI_WRITING + && file_extension != &device_object->legacy_file_extension) { + DBG("HECI WRITE COMPLETE\n"); + file_extension->writing_state = HECI_WRITE_COMPLETE; + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + } + if (file_extension == &device_object->legacy_file_extension) { + DBG("check legacy flow control\n"); + if (device_object-> legacy_flow_control_pending) { + if (((*slots) * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control))) { + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (!heci_send_flow_control (device_object, + &device_object->legacy_file_extension)) { + DBG("legacy flow control failed\n"); + } else { + DBG("legacy flow control success\n"); + device_object->legacy_state = HECI_LEGACY_READING; + device_object->legacy_flow_control_pending = FALSE; + device_object->legacy_message_buffer_index = 0; + device_object->legacy_message_buffer_size = 0; + device_object->legacy_stall_timer = LEGACY_STALL_TIMER; + device_object->host_buffer_is_empty = + host_buffer_is_empty(device_object); + } + } else { + return -ECOMPLETE_MESSAGE; + } + } + } + + } + } + + if (device_object->stop && !device_object->wd_pending) { + device_object->wd_stoped = TRUE; + wake_up_interruptible(&device_object->wait_stop_wd); + return ESUCCESS; + } + + if (device_object->extra_write_index != 0) { + DBG("extra_write_index =%d\n", + device_object->extra_write_index); + heci_write_message(device_object, + (struct heci_message_header *) & + device_object->extra_message_buffer[0], + (unsigned char *) &device_object-> + extra_message_buffer[1], + (device_object->extra_write_index - + 1) * sizeof(__u32)); + *slots -= device_object->extra_write_index; + device_object->extra_write_index = 0; + } + if (device_object->heci_state == HECI_ENABLED){ + if (device_object->wd_pending + && flow_control_credentials(device_object, + &device_object->wd_file_extension)) { + if (!heci_send_wd(device_object)) + DBG("Wd send failed\n"); + else + flow_control_reduce(device_object, + &device_object-> + wd_file_extension); + device_object->wd_pending = 0; + + if (device_object->wd_timeout != 0) { + *slots -= + (sizeof(struct heci_message_header) + + HECI_START_WD_DATA_SIZE + 3) / 4; + device_object->wd_due_counter = 2; + } else { + *slots -= + (sizeof(struct heci_message_header) + + HECI_WD_PARAMS_SIZE + 3) / 4; + device_object->wd_due_counter = 0; + } + + } + } + if (device_object->stop) + return ~ENODEV; + + /* complete control write list CB */ + if (device_object->control_write_list.status == ESUCCESS) { + /* complete control write list CB */ + DBG("complete control write list CB\n "); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + control_write_list.heci_cb.cb_list, cb_list){ + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + if (!file_extension) { + list_del(&kernel_priv_cb_pos->cb_list); + return -ENODEV; + } + switch (kernel_priv_cb_pos->major_file_operations) { + case HECI_CLOSE: + /* send disconnect message */ + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_disconnect_request))) { + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_disconnect_request) + 3) / 4; + if (!heci_disconnect(device_object, + file_extension)) { + file_extension->status = ESUCCESS; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + return -ECOMPLETE_MESSAGE; + } else { + file_extension->state = HECI_FILE_DISCONNECTING; + file_extension->status = ESUCCESS; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->control_read_list. + heci_cb.cb_list); + file_extension->timer_count = CONNECT_TIMEOUT; + } + } else { + /* return the cancel routine */ + return -ECORRUPTED_MESSAGE_HEADER; + } + break; + case HECI_READ: + /* send flow control message */ + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control))) { + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_flow_control) + 3) / 4; + if (!heci_send_flow_control(device_object, file_extension)) { + file_extension->status = -ENODEV; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + return -ENODEV; + + } else { + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->read_list. + heci_cb.cb_list); + } + } else { + /* return the cancel routine */ + list_del(&kernel_priv_cb_pos->cb_list); + return -ECORRUPTED_MESSAGE_HEADER; + } + break; + case HECI_IOCTL: + /* connect message */ + if (!other_client_is_connecting(device_object, file_extension)) { + continue; + } + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_connect_request))) { + file_extension->state = HECI_FILE_CONNECTING; + *slots -= (sizeof(struct heci_message_header) + + sizeof(struct hbm_client_connect_request) + 3) / 4; + if (!heci_connect(device_object, file_extension)) { + file_extension->status = -ENODEV; + kernel_priv_cb_pos->information = 0; + list_del(&kernel_priv_cb_pos->cb_list); + return -ENODEV; + } else { + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->control_read_list. + heci_cb.cb_list); + file_extension->timer_count = CONNECT_TIMEOUT; + } + } else { + /* return the cancel routine */ + list_del(&kernel_priv_cb_pos->cb_list); + return -ECORRUPTED_MESSAGE_HEADER; + } + break; + + default: + BUG_ON(1); + } + + } + } + /* complete write list CB */ + if (device_object->write_list.status == ESUCCESS + && !list_empty(&device_object->write_list.heci_cb.cb_list)) { + DBG("complete write list CB \n"); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object-> + write_list.heci_cb.cb_list, cb_list){ + file_extension = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + + if ((file_extension != NULL) + && (file_extension != &device_object->legacy_file_extension)) { + if (!flow_control_credentials(device_object, + file_extension)) { + DBG("No flow control credentials for client %d, not sending\n", + file_extension->host_client_id); + continue; + } + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + (kernel_priv_cb_pos->request_buffer.size - kernel_priv_cb_pos->information))) { + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = ((kernel_priv_cb_pos->request_buffer.size) - + (kernel_priv_cb_pos->information)); + heci_header->message_complete = 1; + heci_header->reserved = 0; + DBG("kernel_priv_cb_pos->request_buffer.size =%d heci_header->message_complete= %d\n", + kernel_priv_cb_pos->request_buffer.size, + heci_header->message_complete); + DBG("kernel_priv_cb_pos->information =%lu\n", + kernel_priv_cb_pos->information); + DBG("heci_header->length =%d\n", + heci_header->length); + *slots -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + if (!heci_write_message (device_object, heci_header, + (unsigned char *) (kernel_priv_cb_pos-> request_buffer.data + kernel_priv_cb_pos->information), + heci_header->length)) { + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &complete_list->heci_cb. + cb_list); + return -ENODEV; + } else { + flow_control_reduce + (device_object, file_extension); + file_extension->status = ESUCCESS; + kernel_priv_cb_pos->information += heci_header->length; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->write_waiting_list. + heci_cb.cb_list); + } + } else if (*slots == ((device_object->host_hw_state & H_CBD) >> 24)) { /* buffer is still empty */ + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = (*slots * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header->message_complete = 0; + heci_header->reserved = 0; + + (*slots) -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (kernel_priv_cb_pos->request_buffer. data + kernel_priv_cb_pos->information), + heci_header->length)) { + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + list_add_tail(&kernel_priv_cb_pos->cb_list, &complete_list->heci_cb.cb_list); + return -ENODEV; + } else { + kernel_priv_cb_pos->information += heci_header->length; + DBG("kernel_priv_cb_pos->request_buffer.size =%d heci_header->message_complete= %d\n", + kernel_priv_cb_pos->request_buffer.size, + heci_header->message_complete); + DBG("kernel_priv_cb_pos->information =%lu\n", kernel_priv_cb_pos->information); + DBG("heci_header->length =%d\n", heci_header->length); + } + return -ECOMPLETE_MESSAGE; + } else { + return -ECORRUPTED_MESSAGE_HEADER; + } + } else if (file_extension == &device_object->legacy_file_extension) { /* LEGACY IOCTL */ + DBG("complete pthi write cb\n"); + if (!flow_control_credentials(device_object, file_extension)) { + DBG("No flow control credentials for pthi client %d, not sending\n", + file_extension->host_client_id); + continue; + } + if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_message_header) + + device_object->legacy_message_buffer_size - device_object->legacy_message_buffer_index)) { + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = device_object->legacy_message_buffer_size - + device_object->legacy_message_buffer_index; + heci_header->message_complete = 1; + heci_header->reserved = 0; + + *slots -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + + if (!heci_write_message (device_object, heci_header, + (device_object->legacy_message_buffer + device_object->legacy_message_buffer_index), + heci_header->length)) { + device_object->legacy_state = HECI_LEGACY_IDLE; + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + return -ENODEV; + } else { + flow_control_reduce (device_object, file_extension); + device_object->legacy_message_buffer_index += heci_header->length; + list_del(&kernel_priv_cb_pos->cb_list); + kernel_priv_cb_pos->information = device_object->legacy_message_buffer_index; + file_extension->status = ESUCCESS; + device_object->legacy_state = HECI_LEGACY_FLOW_CONTROL; + device_object->legacy_flow_control_pending = TRUE; + /* save legacy cb sent to pthi client */ + device_object->legacy_current_cb = kernel_priv_cb_pos; + list_add_tail(&kernel_priv_cb_pos->cb_list, + &device_object->write_waiting_list.heci_cb. cb_list); + + } + } else if (*slots == ((device_object->host_hw_state & H_CBD) >> 24)) { /* buffer is still empty */ + heci_header = (struct heci_message_header *) & device_object->write_message_buffer[0]; + heci_header->host_address = file_extension->host_client_id; + heci_header->me_address = file_extension->me_client_id; + heci_header->length = (*slots * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header->message_complete = 0; + heci_header->reserved = 0; + + *slots -= (sizeof(struct heci_message_header) + heci_header->length + 3) / 4; + + if (!heci_write_message (device_object, heci_header, (device_object->legacy_message_buffer + + device_object->legacy_message_buffer_index), heci_header->length)) { + file_extension->status = -ENODEV; + list_del(&kernel_priv_cb_pos->cb_list); + } else { + device_object->legacy_message_buffer_index += heci_header->length; + } + return -ECOMPLETE_MESSAGE; + } else { + return -ECORRUPTED_MESSAGE_HEADER;; + } + } + + } + + } + return ESUCCESS; +} + + +/** + * is_treat_specially_client - check if the message belong + * to the file extension . + * @file_extension -extension of the file object + * @connect_res -connect response bus message + * @device_object -Device object for our driver + * + * @return : + * TRUE if empty + * FALSE - otherwise. + */ +int is_treat_specially_client(struct heci_file_private * file_extension, + struct hbm_client_connect_response * + connect_res) +{ + int ret = FALSE; + if ((file_extension->host_client_id == connect_res->host_address) + && (file_extension->me_client_id == connect_res->me_address)) { + + if (connect_res->status == 0) { + DBG("client connect status = 0x%08x.\n", + connect_res->status); + file_extension->state = HECI_FILE_CONNECTED; + file_extension->status = ESUCCESS; + } else { + DBG("client connect status = 0x%08x.\n", + connect_res->status); + file_extension->state = HECI_FILE_DISCONNECTED; + file_extension->status = -ENODEV; + } + ret = TRUE; + } + DBG("client state = %d.\n", file_extension->state); + return ret; + +} + +/** + * heci_client_connect_response - connect response bh routine + * + * @device_object -Device object for our driver + * @connect_res -connect response bus message + * @complete_list - An instance of our list structure + * + * @return : + * none; + */ +void heci_client_connect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + connect_res) +{ + + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + /* if WD or legacy client treat specially */ + + if ((is_treat_specially_client(&(device_object->wd_file_extension), + connect_res)) + || (is_treat_specially_client(& + (device_object-> + legacy_file_extension), + connect_res))) { + return; + } + + if (device_object->control_read_list.status == ESUCCESS + && !list_empty(&device_object->control_read_list.heci_cb. + cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->control_read_list.heci_cb.cb_list, cb_list){ + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + if (!file_extension) { + list_del(&kernel_priv_cb_pos->cb_list); + return; + } + if (HECI_IOCTL == kernel_priv_cb_pos->major_file_operations) { + + if (is_treat_specially_client (file_extension, connect_res)) { + list_del(&kernel_priv_cb_pos->cb_list); + file_extension->status = ESUCCESS; + file_extension->timer_count = 0; + break; + } + } + } + } + return; +} + +/** + * heci_client_disconnect_response - disconnect response bh routine + * + * @device_object -Device object for our driver + * @disconnect_res -disconnect response bus message + * @complete_list - An instance of our list structure + * + * @return : + * none; + */ +void heci_client_disconnect_response(struct iamt_heci_device * device_object, + struct hbm_client_connect_response * + disconnect_res) +{ + struct heci_file_private *file_extension = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + if (device_object->control_read_list.status == ESUCCESS + && !list_empty(&device_object->control_read_list.heci_cb. + cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->control_read_list.heci_cb.cb_list, cb_list){ + file_extension = + (struct heci_file_private *) kernel_priv_cb_pos-> + file_private; + + if (!file_extension) { + list_del(&kernel_priv_cb_pos->cb_list); + return; + } + + DBG("list_for_each_entry_safe in control_read_list.\n"); + if ((file_extension->host_client_id == disconnect_res->host_address) + && (file_extension->me_client_id == disconnect_res->me_address)) { + list_del(&kernel_priv_cb_pos->cb_list); + if (disconnect_res->status == 0) + file_extension->state = HECI_FILE_DISCONNECTED; + file_extension->status = ESUCCESS; + file_extension->timer_count = 0; + break; + } + } + } + return; +} + +/** + * heci_client_flow_control_response - flow control response bh routine + * + * @device_object -Device object for our driver + * @flow_control -flow control response bus message + * + * @return : + * none; + */ +void heci_client_flow_control_response(struct iamt_heci_device * device_object, + struct hbm_flow_control * flow_control) +{ + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + int i; + if (flow_control->host_address == 0) { /* single receive buffer */ + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (flow_control->me_address == + device_object->me_clients[i].client_id) { + if (device_object->me_clients[i].properteis.single_receive_buffer != 0) { + device_object->me_clients[i]. + flow_control_credentials++; + DBG("received flow control message for ME client %d (single receive buffer).\n", + flow_control->me_address); + DBG("flow control credentials=%d.\n", + device_object->me_clients[i].flow_control_credentials); + } else { + BUG_ON(1); /* error in flow control */ + } + } + } + } else { /* normal connection */ + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + DBG("list_for_each_entry_safe in file_list\n"); + + DBG("file_extension of host client %d ME client %d.\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + DBG("flow control message for host client %d ME client %d.\n", + flow_control->host_address, + flow_control->me_address); + if ((file_extension_pos->host_client_id == flow_control->host_address) + && (file_extension_pos->me_client_id == flow_control->me_address)) { + DBG("received flow control message for host client %d ME client %d.\n", + flow_control->host_address, + flow_control->me_address); + file_extension_pos->flow_control_credentials++; + DBG("flow control credentials=%d.\n", + file_extension_pos->flow_control_credentials); + break; + } + } + } + return; +} + +/** + * heci_client_disconnect_request - disconnect request bh routine + * + * @device_object -Device object for our driver + * @disconnect_req -disconnect request bus message + * + * @return : + * none; + */ +void heci_client_disconnect_request(struct iamt_heci_device * device_object, + struct hbm_client_disconnect_request * + disconnect_req) +{ + struct heci_message_header *heci_header; + struct hbm_client_connect_response *disconnect_res; + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + if ((file_extension_pos->host_client_id == disconnect_req->host_address) + && (file_extension_pos->me_client_id == disconnect_req->me_address)) { + DBG("received disconnect request for host client %d ME client %d.\n", + disconnect_req->host_address, + disconnect_req->me_address); + file_extension_pos->state = HECI_FILE_DISCONNECTED; + file_extension_pos->timer_count = 0; + if (file_extension_pos == &device_object->wd_file_extension) { + device_object->wd_due_counter = 0; + device_object->wd_pending = FALSE; + } else if (file_extension_pos == + &device_object->legacy_file_extension) { + device_object->legacy_timer = 0; + } + + /* prepare disconnect response */ + heci_header = (struct heci_message_header *) & device_object->extra_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_client_connect_response); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + disconnect_res = (struct hbm_client_connect_response *) & + device_object->extra_message_buffer[1]; + disconnect_res->host_address = + file_extension_pos->host_client_id; + disconnect_res->me_address = file_extension_pos->me_client_id; + *(__u8 *) (&disconnect_res->command) = CLIENT_DISCONNECT_RES_CMD; + disconnect_res->status = 0; + device_object->extra_write_index = 2; + break; + } + } + return; +} + + +/** + * heci_timer - timer function . + * @data: pointer to the device structure + * + * NOTE: This function is called by timer interrupt work + * @return : + * none; + */ +void heci_wd_timer(unsigned long data) +{ + struct iamt_heci_device *device = (struct iamt_heci_device *) data; + DBG("send watchdog.\n"); + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + mod_timer(&device->wd_timer, round_jiffies(jiffies + 2 * HZ)); + spin_unlock_bh(&device->device_lock); + return; + } + if (device->wd_file_extension.state != HECI_FILE_CONNECTED) { + mod_timer(&device->wd_timer, round_jiffies(jiffies + 2 * HZ)); + spin_unlock_bh(&device->device_lock); + return; + } + /*** Watchdog ***/ + if (device->wd_due_counter != 0 && FALSE == device->wd_bypass) { + if (--device->wd_due_counter == 0) { + if (device->host_buffer_is_empty && + flow_control_credentials(device, + &device-> + wd_file_extension)) { + device->host_buffer_is_empty = FALSE; + + if (!heci_send_wd(device)) + DBG("Wd send failed\n"); + else + flow_control_reduce(device, + &device-> + wd_file_extension); + if (device->wd_timeout != 0) + device->wd_due_counter = 2; + else + device->wd_due_counter = 0; + } else { + device->wd_pending = TRUE; + } + } + } + if (device->legacy_stall_timer != 0) { + if (--device->legacy_stall_timer == 0) { + DBG("Reseting because of hang to PTHI\n"); + heci_reset(device, TRUE); + device->legacy_message_buffer_size = 0; + device->legacy_message_buffer_index = 0; + device->legacy_canceled = FALSE; + device->legacy_ioctl = TRUE; + device->legacy_state = HECI_LEGACY_IDLE; + device->legacy_timer = 0; + spin_unlock_bh(&device->device_lock); + + if (device->legacy_current_cb) { + kfree(device->legacy_current_cb->request_buffer.data); + device->legacy_current_cb->request_buffer.data = NULL; + kfree(device->legacy_current_cb->response_buffer.data); + device->legacy_current_cb->response_buffer.data = NULL; + kfree(device->legacy_current_cb); + } + spin_lock_bh(&device->device_lock); + device->legacy_file_object = NULL; + device->legacy_current_cb = NULL; + run_next_legacy_cmd(device); + } + } + mod_timer(&device->wd_timer, round_jiffies(jiffies + 2 * HZ)); + spin_unlock_bh(&device->device_lock); + return; +} --- linux-2.6.28.orig/ubuntu/heci/io_heci.c +++ linux-2.6.28/ubuntu/heci/io_heci.c @@ -0,0 +1,1138 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "heci_data_structures.h" +#include "heci.h" +#include "heci_interface.h" +#include "version.h" + + +/** + * heci_ioctl_get_version - the get driver version IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_get_version(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct heci_file_private * file_extension) +{ + + int return_status = ESUCCESS; + struct heci_driver_version *version; + struct heci_message_data res_msg; + res_msg.data = NULL; + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file_extension)) + return -ENODEV; + + + if (k_msg.size < (sizeof(struct heci_driver_version) - 2)) { + DBG("user buffer less than heci_driver_version.\n"); + return -EMSGSIZE; + } + + res_msg.data = kmalloc(sizeof(struct heci_driver_version), GFP_KERNEL); + if (!res_msg.data) { + DBG("failed allocation response buffer size = %d.\n", + (int) sizeof(struct heci_driver_version)); + return -ENOMEM; + + } + version = (struct heci_driver_version *) res_msg.data; + version->major = MAJOR_VERSION; + version->minor = MINOR_VERSION; + version->hotfix = QUICK_FIX_NUMBER; + if (k_msg.size < sizeof(struct heci_driver_version)) { + res_msg.size = sizeof(struct heci_driver_version) - 2; + } else { + version->build = VER_BUILD; + res_msg.size = sizeof(struct heci_driver_version); + } + return_status = file_extension->status; + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + return_status = -EFAULT; + goto end; + } + if (put_user(res_msg.size, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } +end: + kfree(res_msg.data); + return return_status; +} + +/** + * heci_ioctl_connect_client - the connect to fw client IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_connect_client(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file) +{ + + int return_status = ESUCCESS; + struct heci_message_data req_msg, res_msg; + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_client *client; + struct heci_file_private *file_extension = NULL; + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + struct heci_file_private *file_extension_list_temp = NULL; + + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + long timeout = 15; /*15 second */ + __u8 i; + int err = 0; + res_msg.data = NULL; + req_msg.data = NULL; + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file)) + return -ENODEV; + file_extension = file->private_data; + if (!file_extension) + return -ENODEV; + if (k_msg.size != sizeof(struct guid)) { + DBG("user buffer size is not equal to size of struct guid(16).\n"); + return -EMSGSIZE; + } + req_msg.data = kmalloc(sizeof(struct guid), GFP_KERNEL); + res_msg.data = kmalloc(sizeof(struct heci_client), GFP_KERNEL); + + + if (!res_msg.data) { + DBG("failed allocation response buffer size = %d.\n", + (int) sizeof(struct heci_client)); + if (req_msg.data) { + kfree(req_msg.data); + req_msg.data = NULL; + goto fail; + } + } + if (!req_msg.data) { + DBG("failed allocation request buffer size = %d.\n", + (int) sizeof(struct guid)); + if (res_msg.data) { + kfree(res_msg.data); + res_msg.data = NULL; + goto fail; + } + fail: + return -ENOMEM; + } + req_msg.size = sizeof(struct guid); + res_msg.size = sizeof(struct heci_client); + if (!k_msg.data) { + return_status = -EIO; + goto end; + } + + /* copy the message to kernel space - use a pointer already copied into kernel space */ + if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) { + return_status = -EFAULT; + goto end; + } + /* buffered ioctl cb */ + kernel_priv_cb = + kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!kernel_priv_cb) { + return_status = -ENOMEM; + goto end; + } + INIT_LIST_HEAD(&kernel_priv_cb->cb_list); + kernel_priv_cb->response_buffer.data = res_msg.data; + kernel_priv_cb->response_buffer.size = res_msg.size; + kernel_priv_cb->request_buffer.data = req_msg.data; + kernel_priv_cb->request_buffer.size = req_msg.size; + kernel_priv_cb->major_file_operations = HECI_IOCTL; + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + if ((file_extension->state != HECI_FILE_INITIALIZING) && + (file_extension->state != HECI_FILE_DISCONNECTED)) { + return_status = -EBUSY; + spin_unlock_bh(&device->device_lock); + goto end; + } + + /* find ME client we're trying to connect to */ + for (i = 0; i < device->num_heci_me_clients; i++) { + if (0 == memcmp((struct guid *) req_msg.data, + &device->me_clients[i].properteis.protocol_name, + sizeof(struct guid))) { + if (device->me_clients[i].properteis.fixed_address == 0) { + file_extension->me_client_id = + device->me_clients[i].client_id; + file_extension->state = + HECI_FILE_CONNECTING; + } + break; + } + } + /*if we're connecting to PTHI client so we will use the exist connection */ + if (0 == memcmp((struct guid *) req_msg.data, &heci_pthi_guid, + sizeof(struct guid))) { + + if (device->legacy_file_extension.state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + device->heci_host_clients[file_extension->host_client_id / 8] &= + ~(1 << (file_extension->host_client_id % 8)); + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device->file_list, link) { + if ((file_extension->host_client_id == + file_extension_pos->host_client_id) + && (file_extension->me_client_id == + file_extension_pos->me_client_id)) { + + DBG("remove file extension node host client = %d, ME client = %d\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + list_del(&file_extension_pos->link); + } + + } + DBG("free file extension memory\n"); + kfree(file_extension); + file_extension = NULL; + file->private_data = &device->legacy_file_extension; + client = (struct heci_client *) res_msg.data; + client->max_message_length = + device->me_clients[i].properteis.max_message_length; + client->protocol_version = + device->me_clients[i].properteis.protocol_version; + return_status = device->legacy_file_extension.status; + spin_unlock_bh(&device->device_lock); + + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + return_status = -EFAULT; + goto end; + } + if (put_user(res_msg.size, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } + goto end; + } + spin_lock(&file_extension->file_lock); + if (file_extension->state != HECI_FILE_CONNECTING) { + return_status = -ENODEV; + spin_unlock(&file_extension->file_lock); + spin_unlock_bh(&device->device_lock); + goto end; + } + spin_unlock(&file_extension->file_lock); + /* prepare the output buffer */ + client = (struct heci_client *) res_msg.data; + client->max_message_length = + device->me_clients[i].properteis.max_message_length; + client->protocol_version = + device->me_clients[i].properteis.protocol_version; + if (device->host_buffer_is_empty + && !other_client_is_connecting(device, file_extension)) { + device->host_buffer_is_empty = FALSE; + if (!heci_connect(device, file_extension)) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } else { + file_extension->timer_count = CONNECT_TIMEOUT; + kernel_priv_cb->file_private = file_extension; + list_add_tail(&kernel_priv_cb->cb_list, + &device->control_read_list.heci_cb. + cb_list); + } + + + } else { + kernel_priv_cb->file_private = file_extension; + DBG("add connect cb to control write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->control_write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device->device_lock); + err = + wait_event_timeout(device->wait_received_message, + (HECI_FILE_CONNECTED == file_extension->state || HECI_FILE_DISCONNECTED == file_extension->state), + timeout * HZ); + if (HECI_FILE_CONNECTED == file_extension->state) { + DBG("successfully to connect to FW client.\n"); + return_status = file_extension->status; + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + return_status = -EFAULT; + goto end; + } + if (put_user(res_msg.size, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } + goto end; + } else { + DBG("failed to connect to FW client.file_extension->state = %d\n", file_extension->state); + if (!err) + DBG("wait_event_interruptible_timeout failed on client connect message fw response message\n"); + + return_status = -EFAULT; + goto remove_list; + } + +remove_list: + if (kernel_priv_cb) { + spin_lock_bh(&device->device_lock); + if (device->control_read_list.status == ESUCCESS + && !list_empty(&device->control_read_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->control_read_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) + list_del(&kernel_priv_cb_pos->cb_list); + + } + + } + } + if (device->control_write_list.status == ESUCCESS + && !list_empty(&device->control_write_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->control_write_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) + list_del(&kernel_priv_cb_pos->cb_list); + + } + + } + } + spin_unlock_bh(&device->device_lock); + } +end: + DBG("free connect cb memory"); + kfree(req_msg.data); + req_msg.data = NULL; + kfree(res_msg.data); + res_msg.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + return return_status; +} + +/** + * heci_ioctl_wd - the wd IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension) +{ + int return_status = ESUCCESS; + struct heci_message_data req_msg; /*in kernel on the stack */ + if (if_num != HECI_MINOR_NUMBER) + return -ENODEV; + spin_lock(&file_extension->file_lock); + if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) { + DBG("User buffer has invalid size.\n"); + spin_unlock(&file_extension->file_lock); + return -EMSGSIZE; + } + spin_unlock(&file_extension->file_lock); + req_msg.data = kmalloc(HECI_WATCHDOG_DATA_SIZE, GFP_KERNEL); + if (!req_msg.data) { + DBG("failed allocation request buffer size = %d.\n", + HECI_WATCHDOG_DATA_SIZE); + return -ENOMEM; + } + req_msg.size = HECI_WATCHDOG_DATA_SIZE; + + /* copy the message to kernel space - use a pointer already copied into kernel space */ + if (copy_from_user(req_msg.data, k_msg.data, req_msg.size)) { + return_status = -EFAULT; + goto end; + } + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + + if (device->wd_file_extension.state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + if (!device->asf_mode) { + return_status = -EIO; + spin_unlock_bh(&device->device_lock); + goto end; + } + + memcpy(&device->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data, + HECI_WATCHDOG_DATA_SIZE); + + device->wd_timeout = (req_msg.data[1] << 8) + + req_msg.data[0]; + if (device->wd_timeout == 0) { + memcpy(device->wd_data, &stop_wd_params, + HECI_WD_PARAMS_SIZE); + device->wd_pending = FALSE; + device->wd_due_counter = 1; /* next timer */ + } else { + memcpy(device->wd_data, &start_wd_params, + HECI_WD_PARAMS_SIZE); + device->wd_pending = FALSE; + device->wd_due_counter = 1; + } + spin_unlock_bh(&device->device_lock); +end: + kfree(req_msg.data); + req_msg.data = NULL; + return return_status; +} + + +/** + * heci_ioctl_bypass_wd - the bypass_wd IOCTL function + * @device_object -Device object for our driver + * @if_num minor number + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_ioctl_bypass_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension) +{ + __u8 flag=0; + int return_status = ESUCCESS; + + if (if_num != HECI_MINOR_NUMBER) + return -ENODEV; + spin_lock(&file_extension->file_lock); + if (k_msg.size < 1) { + DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE .\n"); + spin_unlock(&file_extension->file_lock); + return -EMSGSIZE; + } + spin_unlock(&file_extension->file_lock); + if (copy_from_user(&flag,k_msg.data,1)) { + return_status = -EFAULT; + goto end; + } + + spin_lock_bh(&device->device_lock); + flag = flag ?(TRUE):(FALSE); + device->wd_bypass = flag; + spin_unlock_bh(&device->device_lock); +end: + return return_status; +} + + +/** + * legacy_ioctl_send_message - send command data to pthi client + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int legacy_ioctl_send_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct file *file) +{ + + int return_status = ESUCCESS; + struct heci_message_data req_msg, res_msg; /*in kernel on the stack */ + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_file_private *file_extension = file->private_data; + __u8 i; + req_msg.data = NULL; + res_msg.data = NULL; + if ((if_num != LEGACY_MINOR_NUMBER) || (!device)) + return -ENODEV; + if (!file_extension) + return -ENODEV; + spin_lock_bh(&device->device_lock); + for (i = 0; i < device->num_heci_me_clients; i++) { + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + } + + BUG_ON(device->me_clients[i].client_id != file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != + device->legacy_file_extension.me_client_id)) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } else if (k_msg.size > + device->me_clients[i].properteis.max_message_length + || k_msg.size <= 0) { + spin_unlock_bh(&device->device_lock); + return -EMSGSIZE; + } + + + spin_unlock_bh(&device->device_lock); + req_msg.data = kmalloc(k_msg.size, GFP_KERNEL); + res_msg.data = kmalloc(LEGACY_MTU, GFP_KERNEL); + + if (!res_msg.data) { + DBG("failed allocation response buffer size = %d.\n", + (int) sizeof(struct heci_client)); + if (req_msg.data) { + + kfree(req_msg.data); + req_msg.data = NULL; + return -ENOMEM; + } + } + if (!req_msg.data) { + DBG("failed allocation request buffer size = %d.\n", + (int) sizeof(struct guid)); + if (res_msg.data) { + kfree(res_msg.data); + res_msg.data = NULL; + return -ENOMEM; + } + } + req_msg.size = k_msg.size; + res_msg.size = LEGACY_MTU; + if (!k_msg.data) { + return_status = -EIO; + goto end; + } + + /* copy the message to kernel space - use a pointer already copied into kernel space */ + if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) { + return_status = -EFAULT; + goto end; + } + /* buffered ioctl cb */ + kernel_priv_cb = + kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!kernel_priv_cb) { + return_status = -ENOMEM; + goto end; + } + INIT_LIST_HEAD(&kernel_priv_cb->cb_list); + + kernel_priv_cb->request_buffer.data = req_msg.data; + kernel_priv_cb->request_buffer.size = req_msg.size; + kernel_priv_cb->response_buffer.data = res_msg.data; + kernel_priv_cb->response_buffer.size = res_msg.size; + kernel_priv_cb->major_file_operations = HECI_IOCTL; + kernel_priv_cb->information = 0; + kernel_priv_cb->file_object = file; + kernel_priv_cb->file_private = file_extension; + spin_lock_bh(&device->device_lock); + + if (device->heci_state != HECI_ENABLED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + if (device->legacy_file_extension.state != HECI_FILE_CONNECTED) { + return_status = -ENODEV; + spin_unlock_bh(&device->device_lock); + goto end; + } + + + if (!list_empty(&device->pthi_cmd_list.heci_cb.cb_list) + || device->legacy_state != HECI_LEGACY_IDLE) { + DBG("pthi_state = %d\n", (int) device->legacy_state); + DBG("add PTHI cb to pthi cmd waiting list"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->pthi_cmd_list.heci_cb.cb_list); + + } else { + DBG("call pthi write\n"); + return_status = pthi_write(device, kernel_priv_cb); + + if (ESUCCESS != return_status) { + DBG("pthi write failed with status = %d\n", + return_status); + spin_unlock_bh(&device->device_lock); + goto end; + } + } + spin_unlock_bh(&device->device_lock); + return return_status; +end: + kfree(req_msg.data); + req_msg.data = NULL; + kfree(res_msg.data); + res_msg.data = NULL; + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + return return_status; +} + + +/** + * legacy_ioctl_receive_message - receive command data from pthi client + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data struct in user space + * @k_msg data in kernel on the stack + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int legacy_ioctl_receive_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file) +{ + + int return_status = ESUCCESS; + struct heci_message_data req_msg, res_msg; + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_file_private *file_extension = file->private_data; + __u8 i; + struct heci_file_private *file_extension_list_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + + res_msg.data = NULL; + req_msg.data = NULL; + + if ((if_num != LEGACY_MINOR_NUMBER) || (!device)) + return -ENODEV; + spin_lock_bh(&device->device_lock); + if (!file_extension) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + for (i = 0; i < device->num_heci_me_clients; i++) + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + + BUG_ON(device->me_clients[i].client_id != + file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != + device->legacy_file_extension.me_client_id)) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + + if (device->pthi_read_complete_list.status == ESUCCESS) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->pthi_read_complete_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension == &device->legacy_file_extension) + && (kernel_priv_cb_pos->file_object == file)) { + list_del(&kernel_priv_cb_pos->cb_list); + kernel_priv_cb = + kernel_priv_cb_pos; + break; + } + } + + } + } + if (!kernel_priv_cb) { + spin_unlock_bh(&device->device_lock); + return -EAGAIN; + } + + + res_msg.data = kernel_priv_cb->response_buffer.data; + res_msg.size = kernel_priv_cb->response_buffer.size; + req_msg.data = kernel_priv_cb->request_buffer.data; + req_msg.size = kernel_priv_cb->request_buffer.size; + DBG("pthi kernel_priv_cb->response_buffer size - %d\n", + kernel_priv_cb->response_buffer.size); + DBG("pthi kernel_priv_cb->information - %lu\n", + kernel_priv_cb->information); + spin_unlock_bh(&device->device_lock); + + if (res_msg.size < kernel_priv_cb->information) { + return_status = -EMSGSIZE; + goto end; + } + /* now copy the data to user space */ + if (copy_to_user(k_msg.data, + res_msg.data, + kernel_priv_cb->information)) { + return_status = -EFAULT; + goto end; + } + if (put_user(kernel_priv_cb->information, &u_msg->size)) { + return_status = -EFAULT; + goto end; + } +end: + kfree(req_msg.data); + kfree(res_msg.data); + kfree(kernel_priv_cb); + return return_status; +} + +/** + * find_pthi_read_list_entry - finds a PTHIlist entry for current file + * @device_object -Device object for our driver + * + * @return : + * returned a list entry on success, + * NULL on failure. + */ +struct heci_cb_private* find_pthi_read_list_entry(struct iamt_heci_device* device, + struct file* file, struct heci_file_private* file_extension) +{ + struct heci_file_private *file_extension_list_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + if (device->pthi_read_complete_list.status == ESUCCESS + && !list_empty(&device->pthi_read_complete_list.heci_cb. + cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->pthi_read_complete_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension == &device->legacy_file_extension) + && (kernel_priv_cb_pos->file_object == file)) { + return kernel_priv_cb_pos; + } + } + } + } + return NULL; +} +/** + * pthi_read - read data from pthi client + * @device_object -Device object for our driver + * @if_num minor number + * @*u_msg pointer to user data in user space + * @length-user data length + * + * @return : + * returned data length on success, + * zero if no data to read, + * negative on failure. + */ +int pthi_read(struct iamt_heci_device * device, int if_num, struct file *file, + char *ubuf, size_t length, loff_t * offset) +{ + + int return_status = ESUCCESS; + struct heci_cb_private *kernel_priv_cb = NULL; + struct heci_file_private *file_extension = file->private_data; + __u8 i; + unsigned long currtime = get_seconds(); + + if ((if_num != HECI_MINOR_NUMBER) || (!device)) + return -ENODEV; + + if (!file_extension) + return -ENODEV; + + spin_lock_bh(&device->device_lock); + for (i = 0; i < device->num_heci_me_clients; i++) + if (device->me_clients[i].client_id == + device->legacy_file_extension.me_client_id) + break; + BUG_ON(device->me_clients[i].client_id != file_extension->me_client_id); + if ((i == device->num_heci_me_clients) + || (device->me_clients[i].client_id != + device->legacy_file_extension.me_client_id)) { + DBG("PTHI client not found\n"); + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + kernel_priv_cb = find_pthi_read_list_entry(device, file, file_extension); + if (!kernel_priv_cb) { + spin_unlock_bh(&device->device_lock); + return 0; /* No more data to read */ + } + else { + /* 15 sec for the message has expired */ + if (kernel_priv_cb && currtime - kernel_priv_cb->read_time > LEGACY_READ_TIMER) { + list_del(&kernel_priv_cb->cb_list); + spin_unlock_bh(&device->device_lock); + return_status = -ETIMEDOUT; + goto free; + } + /* if the whole message will fit remove it from the list */ + if ((kernel_priv_cb->information >= *offset) && + (length >= (kernel_priv_cb->information - *offset))) { + list_del(&kernel_priv_cb->cb_list); + } + /* end of the message has been reached */ + else if ((kernel_priv_cb->information > 0) && + (kernel_priv_cb->information <= *offset)) { + list_del(&kernel_priv_cb->cb_list); + return_status = 0; + spin_unlock_bh(&device->device_lock); + goto free; + } + /* else means that not full buffer will be read and do not remove message from deletion list */ + } + DBG("pthi kernel_priv_cb->response_buffer size - %d\n", + kernel_priv_cb->response_buffer.size); + DBG("pthi kernel_priv_cb->information - %lu\n", + kernel_priv_cb->information); + spin_unlock_bh(&device->device_lock); + + /* length is being turncated to PAGE_SIZE, however, the information may be longer */ + length = length < (kernel_priv_cb->information - *offset) ? + length : (kernel_priv_cb->information - *offset); + + if (copy_to_user + (ubuf, kernel_priv_cb->response_buffer.data + *offset, length)) { + return_status = -EFAULT; + } else { + return_status = length; + if ((*offset + length) < kernel_priv_cb->information) { + *offset += length; + goto out; + } + } + DBG("free pthi cb memory\n"); +free: + *offset = 0; + kfree(kernel_priv_cb->request_buffer.data); + kfree(kernel_priv_cb->response_buffer.data); + kfree(kernel_priv_cb); +out: + return return_status; +} + +/** + * heci_start_read - the start read client message function. + * @device_object -Device object for our driver + * @if_num minor number + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_start_read(struct iamt_heci_device * device, int if_num, + struct heci_file_private * file_extension) +{ + int return_status = ESUCCESS; + __u8 i; + struct heci_cb_private *priv_cb = NULL; + if ((if_num != HECI_MINOR_NUMBER) || (!device) + || (!file_extension)) { + DBG("receive wrong function input param\n."); + return -ENODEV; + } + if (file_extension->state != HECI_FILE_CONNECTED) + return -ENODEV; + spin_lock_bh(&device->device_lock); + if (device->heci_state != HECI_ENABLED) { + spin_unlock_bh(&device->device_lock); + return -ENODEV; + } + spin_unlock_bh(&device->device_lock); + DBG("check if read is pending\n"); + if (file_extension->read_pending + || file_extension->read_cb != NULL) { + DBG("read is pending"); + return -EBUSY; + } + priv_cb = kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!priv_cb) + return -ENOMEM; + + DBG("allocation call back success\n"); + DBG("host client = %d, ME client = %d\n", + file_extension->host_client_id, file_extension->me_client_id); + spin_lock_bh(&device->device_lock); + for (i = 0; i < device->num_heci_me_clients; i++) + if (device->me_clients[i].client_id == + file_extension->me_client_id) + break; + + BUG_ON(device->me_clients[i].client_id != + file_extension->me_client_id); + if ((i == device->num_heci_me_clients)) { + return_status = -ENODEV; + goto unlock; + } + + priv_cb->response_buffer.size = + device->me_clients[i].properteis.max_message_length; + spin_unlock_bh(&device->device_lock); + priv_cb->response_buffer.data = + kmalloc(priv_cb->response_buffer.size, GFP_KERNEL); + if (!priv_cb->response_buffer.data) { + return_status = -ENOMEM; + goto fail; + } + DBG("allocation call back data success\n"); + priv_cb->major_file_operations = HECI_READ; + /* make sure information is zero before we start */ + priv_cb->information = 0; + priv_cb->file_private = (void *) file_extension; + file_extension->read_cb = priv_cb; + spin_lock_bh(&device->device_lock); + if (device->host_buffer_is_empty) { + device->host_buffer_is_empty = FALSE; + if (!heci_send_flow_control(device, file_extension)) { + return_status = -ENODEV; + goto unlock; + } else { + list_add_tail(&priv_cb->cb_list, + &device->read_list.heci_cb.cb_list); + } + } else { + list_add_tail(&priv_cb->cb_list, + &device->control_write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device->device_lock); + return return_status; +unlock: + spin_unlock_bh(&device->device_lock); +fail: + kfree(priv_cb->response_buffer.data); + priv_cb->response_buffer.data = NULL; + priv_cb->file_private = NULL; + kfree(priv_cb); + return return_status; +} + +/** + * pthi_write - write legacy data to pthi client + * @device -Device object for our driver + * @kernel_priv_cb - heci call back struct + * @return : + * 0 on success, + * negative on failure. + */ +int pthi_write(struct iamt_heci_device * device, + struct heci_cb_private *kernel_priv_cb) +{ + int return_status = ESUCCESS; + struct heci_message_header heci_header; + + if ((!device) || (!kernel_priv_cb)) + return -ENODEV; + + DBG("write data to pthi client\n"); + + device->legacy_state = HECI_LEGACY_WRITING; + device->legacy_current_cb = kernel_priv_cb; + device->legacy_file_object = kernel_priv_cb->file_object; + device->legacy_canceled = FALSE; + device->legacy_ioctl = TRUE; + device->legacy_message_buffer_size = + kernel_priv_cb->request_buffer.size; + memcpy(device->legacy_message_buffer, + kernel_priv_cb->request_buffer.data, + kernel_priv_cb->request_buffer.size); + if (flow_control_credentials + (device, &device->legacy_file_extension) + && device->host_buffer_is_empty) { + device->host_buffer_is_empty = FALSE; + if (kernel_priv_cb->request_buffer.size > + (((device->host_hw_state & H_CBD) >> 24) * sizeof(__u32)) - sizeof(struct heci_message_header)) { + heci_header.length = + (((device->host_hw_state & H_CBD) >> 24) * sizeof(__u32)) - sizeof(struct heci_message_header); + heci_header.message_complete = 0; + } else { + heci_header.length = + kernel_priv_cb->request_buffer.size; + heci_header.message_complete = 1; + } + + heci_header.host_address = + device->legacy_file_extension.host_client_id; + heci_header.me_address = + device->legacy_file_extension.me_client_id; + heci_header.reserved = 0; + device->legacy_message_buffer_index += heci_header.length; + if (!heci_write_message(device, &heci_header, + (unsigned char *) (device->legacy_message_buffer), + heci_header.length)) + return -ENODEV; + + if (heci_header.message_complete) { + + flow_control_reduce(device, + &device-> + legacy_file_extension); + device->legacy_flow_control_pending = TRUE; + device->legacy_state = HECI_LEGACY_FLOW_CONTROL; + DBG("add pthi cb to write waiting list\n"); + device->legacy_current_cb = kernel_priv_cb; + device->legacy_file_object = kernel_priv_cb->file_object; + list_add_tail(&kernel_priv_cb->cb_list, + &device->write_waiting_list.heci_cb. + cb_list); + + } else { + DBG("message does not complete, so add pthi cb to write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + + + + } else { + if (TRUE != device->host_buffer_is_empty) + DBG("host buffer is not empty"); + DBG("No flow control credentials, so add legacy cb to write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device->write_list.heci_cb.cb_list); + } + return return_status; +} + +/** + * legacy_ioctl_send_message - send command data to pthi client + * @device -Device object for our driver + * @return : + * 0 on success, + * negative on failure. + */ +void run_next_legacy_cmd(struct iamt_heci_device * device) +{ + struct heci_file_private *file_extension_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + int legacy_write_status = ESUCCESS; + + if (!device) + return; + device->legacy_message_buffer_size = 0; + device->legacy_message_buffer_index = 0; + device->legacy_canceled = FALSE; + device->legacy_ioctl = TRUE; + device->legacy_state = HECI_LEGACY_IDLE; + device->legacy_timer = 0; + device->legacy_file_object = NULL; + + if (device->pthi_cmd_list.status == ESUCCESS + && !list_empty(&device->pthi_cmd_list.heci_cb.cb_list)) { + DBG("complete pthi cmd_list CB\n "); + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device->pthi_cmd_list.heci_cb.cb_list, cb_list){ + list_del(&kernel_priv_cb_pos->cb_list); + file_extension_temp = (struct heci_file_private *) kernel_priv_cb_pos->file_private; + + if ((file_extension_temp) + && (file_extension_temp == &device->legacy_file_extension)) { + legacy_write_status = + pthi_write(device, kernel_priv_cb_pos); + if (legacy_write_status != ESUCCESS) { + DBG("pthi write failed with status = %d\n", + legacy_write_status); + return; + } + break; + } + } + } + return; +} --- linux-2.6.28.orig/ubuntu/heci/Makefile +++ linux-2.6.28/ubuntu/heci/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_HECI) += heci.o + +heci-objs := heci_init.o interrupt.o heci_interface.o io_heci.o heci_main.o --- linux-2.6.28.orig/ubuntu/heci/heci_interface.h +++ linux-2.6.28/ubuntu/heci/heci_interface.h @@ -0,0 +1,177 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + + +#ifndef _HECI_INTERFACE_H_ +#define _HECI_INTERFACE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "heci_data_structures.h" + + +#define HBM_MINOR_VERSION 0 +#define HBM_MAJOR_VERSION 1 +#define HBM_TIMEOUT 1 /* 1 second */ + + +#define HOST_START_REQ_CMD 0x01 +#define HOST_START_RES_CMD 0x81 + +#define HOST_STOP_REQ_CMD 0x02 +#define HOST_STOP_RES_CMD 0x82 + +#define ME_STOP_REQ_CMD 0x03 + +#define HOST_ENUM_REQ_CMD 0x04 +#define HOST_ENUM_RES_CMD 0x84 + +#define HOST_CLIENT_PROPERTEIS_REQ_CMD 0x05 +#define HOST_CLIENT_PROPERTEIS_RES_CMD 0x85 + +#define CLIENT_CONNECT_REQ_CMD 0x06 +#define CLIENT_CONNECT_RES_CMD 0x86 + +#define CLIENT_DISCONNECT_REQ_CMD 0x07 +#define CLIENT_DISCONNECT_RES_CMD 0x87 + +#define FLOW_CONTROL_CMD 0x08 + + +#define AMT_WD_VALUE 120 /* seconds */ + +#define HECI_WATCHDOG_DATA_SIZE 16 +#define HECI_START_WD_DATA_SIZE 20 +#define HECI_WD_PARAMS_SIZE 4 + +/* IOCTL commands */ +#define HECI_IOCTL_LETTER 'H' + + +#define IOCTL_HECI_GET_VERSION \ + _IOWR(HECI_IOCTL_LETTER , 0x800, struct heci_message_data) +#define IOCTL_HECI_CONNECT_CLIENT \ + _IOWR(HECI_IOCTL_LETTER , 0x801, struct heci_message_data) +#define IOCTL_HECI_WD \ + _IOWR(HECI_IOCTL_LETTER , 0x802, struct heci_message_data) +#define IOCTL_HECI_BYPASS_WD \ + _IOWR(HECI_IOCTL_LETTER , 0x810, struct heci_message_data) + +#define IAMT_IOC_MAGIC 'i' +#define IAMT_KCS_SEND_MESSAGE_COMMAND _IOR(IAMT_IOC_MAGIC, 1, struct heci_message_data) +#define IAMT_KCS_RECEIVE_MESSAGE_COMMAND _IOW(IAMT_IOC_MAGIC, 2, struct heci_message_data) + + +#pragma pack(1) + + +enum heci_stop_reason_types{ + DRIVER_STOP_REQUEST = 0x00, + DEVICE_D1_ENTRY = 0x01, + DEVICE_D2_ENTRY = 0x02, + DEVICE_D3_ENTRY = 0x03, + SYSTEM_S1_ENTRY = 0x04, + SYSTEM_S2_ENTRY = 0x05, + SYSTEM_S3_ENTRY = 0x06, + SYSTEM_S4_ENTRY = 0x07, + SYSTEM_S5_ENTRY = 0x08 +}; + +enum me_stop_reason_types{ + FW_UPDATE = 0x00 +}; + +enum client_connect_status_types{ + CCS_SUCCESS = 0x00, + CCS_NOT_FOUND = 0x01, + CCS_ALREADY_STARTED = 0x02, + CCS_OUT_OF_RESOURCES = 0x03, + CCS_MESSAGE_SMALL = 0x04 +}; + +enum client_disconnect_status_types{ + CDS_SUCCESS = 0x00 +}; + + +/** + * heci interface function prototypes + */ +void heci_read_slots(struct iamt_heci_device * device_object, + unsigned char *buffer, unsigned long buffer_length); + +int heci_write_message(struct iamt_heci_device * device_object, + struct heci_message_header * header, + unsigned char *write_buffer, + unsigned long write_length); + +int host_buffer_is_empty(struct iamt_heci_device * device_object); + +__s32 count_full_read_slots(struct iamt_heci_device * device_object); + +__s32 count_empty_write_slots(struct iamt_heci_device * device_object); + +int flow_control_credentials(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +int heci_send_wd(struct iamt_heci_device * device_object); + +void flow_control_reduce(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +int heci_send_flow_control(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +int heci_disconnect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); +int other_client_is_connecting(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); +int heci_connect(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +#endif /* _HECI_INTERFACE_H_ */ --- linux-2.6.28.orig/ubuntu/heci/heci_init.c +++ linux-2.6.28/ubuntu/heci/heci_init.c @@ -0,0 +1,1121 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kcompat.h" +#include "heci_data_structures.h" +#include "heci_interface.h" +#include "heci.h" + + +const __u8 watch_dog_data[] = + { 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; +const __u8 start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 }; +const __u8 stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 }; +const __u8 heci_wd_state_independence_msg[2][4] = { + {0x05, 0x02, 0x51, 0x10}, + {0x05, 0x02, 0x52, 0x10} }; +const struct guid heci_asf_guid = + { 0x75B30CD6, 0xA29E, 0x4AF7, {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, + 0xC8, 0xA6} }; +const struct guid heci_wd_guid = + { 0x05B79A6F, 0x4628, 0x4D7F, {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, + 0x32, 0xAB} }; +const struct guid heci_pthi_guid = + { 0x12f80028, 0xb4b7, 0x4b2d, {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, + 0x81, 0x4c} }; + + +/** + * heci init function prototypes + */ +int host_start_message(struct iamt_heci_device * device_object); +int host_enum_clients_message(struct iamt_heci_device * device_object); +int allocate_me_clents_storage(struct iamt_heci_device * device_object); +void heci_disable(struct iamt_heci_device * device_object); +void host_init_wd(struct iamt_heci_device * device_object); +void host_init_legacy(struct iamt_heci_device * device_object); + + +/** + * heci_initialize_list - Sets up a queue list. + * + * @list - An instance of our list structure + * @device_object -Device object for our driver + * + * @return : + * none; + */ +void heci_initialize_list(struct io_heci_list *list, + struct iamt_heci_device * device_object) +{ + /* initialize our queue list */ + INIT_LIST_HEAD(&list->heci_cb.cb_list); + list->status = ESUCCESS; + list->device_extension = device_object; + return; +} + +/** + * heci_flush_queues - flush our queues list belong to file_extension. + * + * @device_object -Device object for our driver + * + * @return : + * none; + */ +void heci_flush_queues(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + int i; + if (!device_object || !file_extension) + return; + /* flush our queue list belong to file_extension */ + for (i = 0; i < NUMBER_OF_LISTS; i++) { + DBG("remove list etnry belong to file_extension\n"); + heci_flush_list(device_object->io_list_array[i], + file_extension); + } + +} + + +/** + * heci_flush_list - remove list etnry belong to file_extension. + * + * @list - An instance of our list structure + * @file_extension -extension of the file object + + * @return : + * none; + */ +void heci_flush_list(struct io_heci_list *list, + struct heci_file_private * file_extension) +{ + struct heci_file_private *file_extension_temp = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + if (!list || !file_extension) + return; + if (list->status == ESUCCESS + && !list_empty(&list->heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &list->heci_cb.cb_list, cb_list){ + + if (kernel_priv_cb_pos) { + file_extension_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + } + if (file_extension_temp) { + if ((file_extension->host_client_id == file_extension_temp-> host_client_id) + && (file_extension->me_client_id == file_extension_temp-> me_client_id)) + list_del(&kernel_priv_cb_pos->cb_list); + } + + } + } + return; +} + +/** + * init_heci_device - allocates and initializes the heci device structure + * @pdev: The pci device structure + * + * @return : + * The heci_device_device pointer on success, NULL on failure. + */ +struct iamt_heci_device *init_heci_device(struct pci_dev * pdev) +{ + int i; + struct iamt_heci_device *device; + device = kmalloc(sizeof(struct iamt_heci_device), GFP_KERNEL); + if (!device) { + return NULL; + } + + /* setup our list array */ + device->io_list_array[0] = &device->read_list; + device->io_list_array[1] = &device->write_list; + device->io_list_array[2] = &device->write_waiting_list; + device->io_list_array[3] = &device->control_write_list; + device->io_list_array[4] = &device->control_read_list; + device->io_list_array[5] = &device->pthi_cmd_list; + device->io_list_array[6] = &device->pthi_read_complete_list; + INIT_LIST_HEAD(&device->file_list); + INIT_LIST_HEAD(&device->wd_file_extension.link); + INIT_LIST_HEAD(&device->legacy_file_extension.link); + spin_lock_init(&device->device_lock); + init_waitqueue_head(&device->wait_received_message); + init_waitqueue_head(&device->wait_stop_wd); + device->open_handle_count = 0; + device->num_heci_me_clients = 0; + device->mem_base = 0; + device->mem_length = 0; + device->extra_write_index = 0; + device->read_message_header = 0; + device->mem_addr = NULL; + device->asf_mode = FALSE; + device->need_reset = FALSE; + device->received_message = FALSE; + device->heci_state = HECI_INITIALIZING; + + device->num_heci_me_clients = 0; + device->legacy_current_cb = NULL; + device->legacy_file_object = NULL; + device->legacy_canceled = FALSE; + device->legacy_flow_control_pending = FALSE; + device->legacy_state = HECI_LEGACY_IDLE; + device->legacy_message_buffer_index = 0; + device->wd_pending = FALSE; + device->wd_stoped = FALSE; + device->wd_bypass = FALSE; + + device->me_clients = NULL; + /* init work for schedule work */ + INIT_WORK(&device->work, NULL); + for (i = 0; i < NUMBER_OF_LISTS; i++) + heci_initialize_list(device->io_list_array[i], device); + device->pdev = pdev; + return device; +} + +/** + * heci_hw_init - init host and fw to start work. + * + * @device_object -Device object for our driver + * + *@return: + * 0 on success. + * negative on failure + */ +int heci_hw_init(struct iamt_heci_device * device_object) +{ + int err = 0; + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + device_object->me_hw_state = + read_heci_register(device_object, ME_CSR_HA); + DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + + if ((device_object->host_hw_state & H_IS) == H_IS) { + /* acknowledge interrupt and stop interupts */ + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + } + device_object->received_message = FALSE; + DBG("reset in start the heci device.\n"); + + heci_reset(device_object, TRUE); + + DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + + /* wait for ME to turn on ME_RDY */ + if (!device_object->received_message) { + err = + wait_event_interruptible_timeout(device_object-> + wait_received_message, + (device_object-> + received_message), + HECI_INTEROP_TIMEOUT); + } + + if (!err && !device_object->received_message) { + device_object->heci_state = HECI_DISABLED; + DBG("wait_event_interruptible_timeout failed on wait for ME to turn on ME_RDY.\n"); + return -ENODEV; + } else { + if (!(((device_object->host_hw_state & H_RDY) == H_RDY) + && ((device_object->me_hw_state & ME_RDY_HRA) == + ME_RDY_HRA))) { + device_object->heci_state = HECI_DISABLED; + DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, + device_object->me_hw_state); + + if (!(device_object->host_hw_state & H_RDY) != H_RDY) + DBG("host turn off H_RDY.\n"); + if (!(device_object->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA) + DBG("ME turn off ME_RDY.\n"); + HECI_ERR("link layer initialization failed.\n"); + return -ENODEV; + } + } + device_object->received_message = FALSE; + DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + DBG("ME turn on ME_RDY and host turn on H_RDY.\n"); + HECI_INFO("link layer has been established.\n"); + return ESUCCESS; +} + +/** + * heci_reset - reset host and fw. + * + * @device_object -Device object for our driver + * @interrupts - if interrupt should be enable after reset. + * + * @return: + * none; + */ +void heci_reset(struct iamt_heci_device * device_object, int interrupts) +{ + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + int unexpected = 0; + + if (device_object->heci_state == HECI_RECOVERING_FROM_RESET) { + device_object->need_reset = TRUE; + return; + } + + if (device_object->heci_state != HECI_INITIALIZING && + device_object->heci_state != HECI_DISABLED && + device_object->heci_state != HECI_POWER_DOWN && + device_object->heci_state != HECI_POWER_UP) + unexpected = 1; + + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + + DBG("before reset host_hw_state = 0x%08x.\n", + device_object->host_hw_state); + + device_object->host_hw_state |= (H_RST | H_IG); + + if (interrupts) + device_object->host_hw_state |= (H_IE); + else + device_object->host_hw_state &= ~(H_IE); + + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + BUG_ON((device_object->host_hw_state & H_RST) != H_RST); + BUG_ON((device_object->host_hw_state & H_RDY) != 0); + + device_object->host_hw_state &= ~H_RST; + device_object->host_hw_state |= H_IG; + + write_heci_register(device_object, H_CSR, + device_object->host_hw_state); + + DBG("currently saved host_hw_state = 0x%08x.\n", + device_object->host_hw_state); + + device_object->need_reset = FALSE; + + if (device_object->heci_state != HECI_INITIALIZING) { + if (device_object->heci_state != HECI_DISABLED && + device_object->heci_state != HECI_POWER_DOWN) { + device_object->heci_state = HECI_RESETING; + } + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + file_extension_pos->state =HECI_FILE_DISCONNECTED; + file_extension_pos->flow_control_credentials =0; + file_extension_pos->read_cb = NULL; + file_extension_pos->timer_count = 0; + } + /* remove entry if already in list */ + DBG("list del legacy and wd file list.\n"); + heci_remove_client_from_file_list(device_object, + device_object-> + wd_file_extension. + host_client_id); + + heci_remove_client_from_file_list(device_object, + device_object-> + legacy_file_extension. + host_client_id); + /* reset legacy parameters. */ + device_object->legacy_current_cb = NULL; + device_object->legacy_message_buffer_size = 0; + device_object->legacy_message_buffer_index = 0; + device_object->legacy_canceled = FALSE; + device_object->legacy_file_extension.file = NULL; + device_object->legacy_ioctl = FALSE; + device_object->legacy_state = HECI_LEGACY_IDLE; + device_object->legacy_timer = 0; + device_object->wd_due_counter = 0; + device_object->extra_write_index = 0; + device_object->wd_pending = FALSE; + } + + device_object->num_heci_me_clients = 0; + device_object->read_message_header = 0; + device_object->stop = FALSE; + device_object->wd_pending = 0; + + /* update the state of the registers after reset */ + device_object->host_hw_state = + read_heci_register(device_object, H_CSR); + device_object->me_hw_state = + read_heci_register(device_object, ME_CSR_HA); + + DBG("after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n", + device_object->host_hw_state, device_object->me_hw_state); + + if (unexpected) + HECI_ERR("unexpected heci reset.\n"); + //Wake up all readings so they can be interrupted + list_for_each_entry_safe(file_extension_pos,file_extension_next, &device_object->file_list,link) { + if (&file_extension_pos->rx_wait && + waitqueue_active (&file_extension_pos->rx_wait)) { + HECI_INFO("Waking up client!\n"); + wake_up_interruptible(&file_extension_pos->rx_wait); + } + } + // remove all waiting requests + if (device_object->write_list.status == ESUCCESS && !list_empty(&device_object->write_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->write_list.heci_cb.cb_list, cb_list){ + if (kernel_priv_cb_pos) { + list_del(&kernel_priv_cb_pos->cb_list); + kfree(kernel_priv_cb_pos->request_buffer.data); + kernel_priv_cb_pos->request_buffer.data = NULL; + kfree(kernel_priv_cb_pos->response_buffer.data); + kernel_priv_cb_pos->response_buffer.data = NULL; + kfree(kernel_priv_cb_pos); + kernel_priv_cb_pos = NULL; + } + } + } +} + +/** + * heci_disable - reseting in disable routine. + * + * @device_object -Device object for our driver + * + * @return: + * none; + */ +void heci_disable(struct iamt_heci_device * device_object) +{ + if (device_object->heci_state != HECI_INITIALIZING) + HECI_ERR("driver stop request heci state is disable.\n"); + device_object->heci_state = HECI_DISABLED; +} + +/** + * heci_initialize_clients - routine. + * + * @device_object -Device object for our driver + * + * @return: + * none; + */ +int heci_initialize_clients(void *data) +{ + + int status; + struct iamt_heci_device *device_object = (struct iamt_heci_device *) data; + DBG("link is established start sending messages.\n"); + /* link is established start sending messages. */ + status = host_start_message(device_object); + if (status) { + DBG("start sending messages failed.\n"); + return -ENODEV; + } + /* enumerate clients */ + + status = host_enum_clients_message(device_object); + if (status) { + DBG("enum clients failed.\n"); + return -ENODEV; + } + /* allocate storage for ME clients representation */ + status = allocate_me_clents_storage(device_object); + if (status) { + DBG("allocate clients failed.\n"); + return -ENODEV; + } + /*heci initialization wd */ + host_init_wd(device_object); + /*heci initialization legacy client */ + host_init_legacy(device_object); + if (device_object->need_reset) { + device_object->need_reset = FALSE; + device_object->heci_state = HECI_DISABLED; + return -ENODEV; + } + + memset(device_object->heci_host_clients, 0, + sizeof(device_object->heci_host_clients)); + device_object->open_handle_count = 0; + device_object->heci_host_clients[0] |= 7; + device_object->current_host_client_id = 3; + device_object->heci_state = HECI_ENABLED; + DBG("initialization heci clients successful.\n"); + return ESUCCESS; +} + +/** + * host_start_message - heci host send start message. + * + * @device_object - Device object for our driver + * + * @return : + * 0 on success, + * negative on failure. + */ +int host_start_message(struct iamt_heci_device * device_object) +{ + long timeout = 60; /* 60 second */ + + struct heci_message_header *heci_header; + struct hbm_host_version_request *host_start_req; + struct hbm_host_stop_request *host_stop_req; + int err = 0; + /* host start message */ + msleep(100); + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_version_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_start_req = + (struct hbm_host_version_request *) & device_object-> + write_message_buffer[1]; + memset(host_start_req, 0, sizeof(host_start_req)); + host_start_req->command.command = HOST_START_REQ_CMD; + host_start_req->reserved = 0; + host_start_req->host_version.major_version = HBM_MAJOR_VERSION; + host_start_req->host_version.minor_version = HBM_MINOR_VERSION; + device_object->received_message = FALSE; + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (host_start_req), + heci_header->length)) { + device_object->heci_state = HECI_DISABLED; + DBG("send version to fw fail.\n"); + return -ENODEV; + } + DBG("call wait_event_interruptible_timeout for response message. \n"); + /* wait for response */ + err = + wait_event_interruptible_timeout(device_object-> + wait_received_message, + (device_object-> + received_message), + timeout * HZ); + if (!err && !device_object->received_message) { + device_object->heci_state = HECI_DISABLED; + DBG("wait_event_interruptible_timeout failed on host start response message. \n"); + return -ENODEV; + } + device_object->received_message = FALSE; + DBG("wait_event_interruptible_timeout successful on host start response message. \n"); + if ((device_object->version.major_version != HBM_MAJOR_VERSION) || + (device_object->version.minor_version != HBM_MINOR_VERSION)) { + /* send stop message */ + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_stop_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_stop_req = + (struct hbm_host_stop_request *) & device_object-> + write_message_buffer[1]; + + memset(host_stop_req, 0, sizeof(host_stop_req)); + host_stop_req->command.command = HOST_STOP_REQ_CMD; + host_stop_req->reason = DRIVER_STOP_REQUEST; + memset(host_stop_req->reserved, 0, + sizeof(host_stop_req->reserved)); + heci_write_message(device_object, heci_header, + (unsigned char *) (host_stop_req), + heci_header->length); + DBG("version mismatch.\n"); + return -ENODEV; + } + + return ESUCCESS; +} + +/** + * host_enum_clients_message - host send enumeration client request message. + * + * @device_object - Device object for our driver + * + * @return : + * 0 on success, + * negative on failure. + */ +int host_enum_clients_message(struct iamt_heci_device * device_object) +{ + long timeout = 5; /*5 second */ + + struct heci_message_header *heci_header; + struct hbm_host_enumeration_request *host_enum_req; + int err = 0; + __u8 i, j; + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + /* enumerate clients */ + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_enumeration_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_enum_req = + (struct hbm_host_enumeration_request *) & device_object-> + write_message_buffer[1]; + memset(host_enum_req, 0, sizeof(host_enum_req)); + host_enum_req->command.command = HOST_ENUM_REQ_CMD; + memset(host_enum_req->reserved, 0, + sizeof(host_enum_req->reserved)); + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (host_enum_req), + heci_header->length)) { + device_object->heci_state = HECI_DISABLED; + DBG("send enumeration request fail.\n"); + return -ENODEV; + } + /* wait for response */ + device_object->received_message = FALSE; + err = + wait_event_interruptible_timeout(device_object-> + wait_received_message, + (device_object-> + received_message), + timeout * HZ); + if (!err && !device_object->received_message) { + + device_object->heci_state = HECI_DISABLED; + + DBG("wait_event_interruptible_timeout failed on enumeration cients response message. \n"); + return -ENODEV; + } + device_object->received_message = FALSE; + /* count how many ME clients we have */ + for (i = 0; i < sizeof(device_object->heci_me_clients); i++) + for (j = 0; j < 8; j++) + if ((device_object->heci_me_clients[i] & (1 << j)) != 0) + device_object->num_heci_me_clients++; + return ESUCCESS; +} + +/** + * allocate_me_clents_storage - allocate storage for me clients + * + * @device_object - Device object for our driver + * + * @return : + * 0 on success, + * negative on failure. + */ +int allocate_me_clents_storage(struct iamt_heci_device * device_object) +{ + long timeout = 10; /*10 second */ + struct heci_message_header *heci_header; + struct hbm_host_client_properties_request *host_cli_req; + __u8 client_num, i, j; + int err; + heci_header = + (struct heci_message_header *) & device_object-> + write_message_buffer[0]; + /* allocate storage for ME clients representation */ + if (device_object->num_heci_me_clients > 0) { + kfree(device_object->me_clients); + device_object->me_clients = + kcalloc(device_object->num_heci_me_clients, + sizeof(struct heci_me_client), + GFP_KERNEL); + if (!device_object->me_clients) { + device_object->heci_state = HECI_DISABLED; + DBG("allocate me clents memory failed.\n"); + return -ENOMEM; + } + + client_num = 0; + + for (i = 0; i < sizeof(device_object->heci_me_clients); + i++) { + for (j = 0; j < 8; j++) { + if ((device_object->heci_me_clients[i] & (1 << j)) != 0) { + device_object->me_clients[client_num].client_id = (i * 8) + j; + device_object->me_clients[client_num].flow_control_credentials = 0; + heci_header->host_address = 0; + heci_header->me_address = 0; + heci_header->length = sizeof(struct hbm_host_client_properties_request); + heci_header->message_complete = 1; + heci_header->reserved = 0; + + host_cli_req = (struct hbm_host_client_properties_request *)& device_object->write_message_buffer[1]; + memset(host_cli_req, 0, sizeof(struct hbm_host_client_properties_request)); + host_cli_req->command.command = HOST_CLIENT_PROPERTEIS_REQ_CMD; + host_cli_req->address = device_object->me_clients[client_num].client_id; + memset(host_cli_req->reserved, 0, sizeof(host_cli_req->reserved)); + if (!heci_write_message(device_object, heci_header, + (unsigned char *) (host_cli_req), heci_header->length)) { + DBG("send client properteis request fail.\n"); + device_object->heci_state = HECI_DISABLED; + kfree(device_object->me_clients); + return -ENODEV; + } + /* wait for response */ + device_object->received_message = FALSE; + err = wait_event_interruptible_timeout (device_object->wait_received_message, + (device_object->received_message), timeout * HZ); + if (!err && !device_object->received_message) { + DBG("wait_event_interruptible_timeout failed on client properteis response message.\n"); + device_object->heci_state = HECI_DISABLED; + kfree(device_object->me_clients); + return -ENODEV; + } + device_object->received_message = FALSE; + client_num++; + } + } + } + } + return ESUCCESS; +} + +/** + * host_init_wd - heci initialization wd. + * + * @device_object - Device object for our driver + * + * @return : + * none; + */ +void host_init_wd(struct iamt_heci_device * device_object) +{ + long timeout = 15; /*15 second */ + __u8 i; + int err = 0; + /*look for WD client and connect to it */ + spin_lock_init(&device_object->wd_file_extension.file_lock); + init_waitqueue_head(&device_object->wd_file_extension.wait); + device_object->wd_file_extension.file = NULL; + device_object->wd_file_extension.state = HECI_FILE_DISCONNECTED; + device_object->wd_timeout = 0; + device_object->asf_mode = FALSE; + /*find ME ASF client - otherwise assume AMT mode */ + DBG("find ME ASF client - otherwise assume AMT mode.\n"); + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (memcmp(&heci_asf_guid, + &device_object->me_clients[i].properteis. + protocol_name, sizeof(struct guid))==0) { + device_object->asf_mode = TRUE; + DBG("found ME ASF client.\n"); + } + } + if (device_object->asf_mode) { + memcpy(device_object->wd_data, + stop_wd_params, HECI_WD_PARAMS_SIZE); + + } + else { /* AMT mode */ + + DBG("assume AMT mode.\n"); + device_object->wd_timeout = AMT_WD_VALUE; + DBG("device_object->wd_timeout=%d.\n", + device_object->wd_timeout); + memcpy(device_object->wd_data, start_wd_params, HECI_WD_PARAMS_SIZE); + memcpy(device_object->wd_data + HECI_WD_PARAMS_SIZE, + &device_object->wd_timeout, sizeof(__u16)); + } + + /* find ME WD client */ + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (0 == memcmp(&heci_wd_guid, &device_object->me_clients[i].properteis.protocol_name, sizeof(struct guid))) { + + spin_lock_bh(&device_object->device_lock); + device_object->wd_file_extension.me_client_id = + device_object->me_clients[i].client_id; + device_object->wd_file_extension.state = + HECI_FILE_CONNECTING; + + device_object->wd_file_extension.host_client_id = + HECI_WD_HOST_CLIENT_ID; + + device_object->wd_file_extension. + flow_control_credentials = 0; + device_object->wd_file_extension.timer_count = 0; + list_add_tail(&device_object->wd_file_extension. + link, &device_object->file_list); + spin_unlock_bh(&device_object->device_lock); + break; + } + } + DBG("check wd_file_ext\n"); + if (HECI_FILE_CONNECTING == device_object->wd_file_extension.state) { + if (heci_connect(device_object, + &device_object->wd_file_extension)) { + + err = + wait_event_timeout + (device_object->wait_received_message, + (HECI_FILE_CONNECTED == device_object->wd_file_extension.state ||HECI_FILE_DISCONNECTED == device_object->wd_file_extension.state), + timeout * HZ); + if (HECI_FILE_CONNECTED == device_object->wd_file_extension.state) { + DBG("device_object->wd_timeout=%d.\n", + device_object->wd_timeout); + if (device_object->wd_timeout != 0) + device_object->wd_due_counter = 1; + else + device_object->wd_due_counter = 0; + DBG("successfully to connect to WD client.\n"); + } else { + + heci_remove_client_from_file_list + (device_object, + device_object->wd_file_extension. + host_client_id); + if (HECI_FILE_CONNECTED != + device_object->wd_file_extension.state) + DBG("wrong status received for WD client.\n"); + if (!err) + DBG("wait_event_interruptible_timeout failed on client connect message fw response message err=%08x\n", err); + DBG("failed to connect to WD client.\n"); + device_object->wd_file_extension.state = + HECI_FILE_DISCONNECTED; + } + } else { + DBG("failed to call heci_connect for wd_file_extension.\n"); + heci_remove_client_from_file_list(device_object, + device_object-> + wd_file_extension. + host_client_id); + device_object->wd_file_extension.state = + HECI_FILE_DISCONNECTED; + } + } else { + DBG("failed to find WD client.\n"); + } + + device_object->wd_timer.function = &heci_wd_timer; + device_object->wd_timer.data = (unsigned long) device_object; + return; +} + + +/** + * host_init_legacy - heci initialization legacy client. + * + * @device_object - Device object for our driver + * + * @return : + * none; + */ +void host_init_legacy(struct iamt_heci_device * device_object) +{ + long timeout = 15; /*15 second */ + __u8 i; + int err; + + + spin_lock_init(&device_object->legacy_file_extension.file_lock); + init_waitqueue_head(&device_object->legacy_file_extension.wait); + spin_lock_init(&device_object->legacy_file_extension.read_io_lock); + spin_lock_init(&device_object->legacy_file_extension. + write_io_lock); + init_waitqueue_head(&device_object->legacy_file_extension.rx_wait); + init_waitqueue_head(&device_object->legacy_file_extension.tx_wait); + device_object->legacy_file_extension.reading_state = HECI_IDLE; + device_object->legacy_file_extension.writing_state = HECI_IDLE; + device_object->legacy_file_extension.read_pending = FALSE; + device_object->legacy_file_extension.flow_control_credentials = 0; + device_object->legacy_file_extension.read_cb = NULL; + /* look for legacy client and connect to it */ + device_object->legacy_file_extension.file = NULL; + device_object->legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + + /* find ME PTHI client */ + for (i = 0; i < device_object->num_heci_me_clients; i++) { + if (0 == memcmp(&heci_pthi_guid, &device_object->me_clients[i].properteis. protocol_name, sizeof(struct guid))) { + spin_lock_bh(&device_object->device_lock); + device_object->legacy_file_extension.me_client_id = + device_object->me_clients[i].client_id; + device_object->legacy_file_extension.state = + HECI_FILE_CONNECTING; + device_object->legacy_file_extension. + host_client_id = HECI_LEGACY_HOST_CLIENT_ID; + device_object->legacy_file_extension. + flow_control_credentials = 0; + device_object->legacy_file_extension.timer_count = 0; + list_add_tail(&device_object-> + legacy_file_extension.link, + &device_object->file_list); + spin_unlock_bh(&device_object->device_lock); + break; + } + } + if (device_object->asf_mode){ + device_object->legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + heci_remove_client_from_file_list(device_object, + device_object-> + legacy_file_extension. + host_client_id); + return; + + } + if (device_object->legacy_file_extension.state == HECI_FILE_CONNECTING) { + BUG_ON(device_object->me_clients[i].properteis.max_message_length != LEGACY_MTU); + + if (device_object->me_clients[i].properteis.max_message_length < LEGACY_MTU) { + device_object->legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + DBG("legacy client buffer too small.\n"); + } else { + if (heci_connect(device_object, &device_object-> legacy_file_extension)) { + err = wait_event_timeout (device_object->wait_received_message, + (device_object->legacy_file_extension.state == HECI_FILE_CONNECTED || + device_object->legacy_file_extension.state == HECI_FILE_DISCONNECTED), timeout * HZ); + if ((device_object->legacy_file_extension.state != HECI_FILE_CONNECTED)) { + heci_remove_client_from_file_list + (device_object, + device_object-> + legacy_file_extension. + host_client_id); + DBG("failed to connect to legacy client.\n"); + device_object-> + legacy_file_extension.state = + HECI_FILE_DISCONNECTED; + } else { + DBG("successfully to connect to legacy client.\n"); + device_object->legacy_state = + HECI_LEGACY_IDLE; + } + } else { + DBG("failed to call heci_connect for legacy_file_extension.\n"); + heci_remove_client_from_file_list + (device_object, + device_object->legacy_file_extension. + host_client_id); + device_object->legacy_file_extension. + state = HECI_FILE_DISCONNECTED; + } + } + } else { + if (!device_object->asf_mode) + DBG("failed to find legacy client.\n"); + } + return; +} + +/** + * alloc_priv - allocates a private file structure and set it up. + * @file: the file structure + * + * @return : + * The allocated file or NULL on failure + */ +struct heci_file_private *alloc_priv(struct file * file) +{ + struct heci_file_private *priv; + + priv = kmalloc(sizeof(struct heci_file_private), GFP_KERNEL); + if (!priv) + return NULL; + + spin_lock_init(&priv->file_lock); + spin_lock_init(&priv->read_io_lock); + spin_lock_init(&priv->write_io_lock); + init_waitqueue_head(&priv->wait); + init_waitqueue_head(&priv->rx_wait); + DBG("priv->rx_wait =%p\n", &priv->rx_wait); + init_waitqueue_head(&priv->tx_wait); + INIT_LIST_HEAD(&priv->link); + priv->reading_state = HECI_IDLE; + priv->writing_state = HECI_IDLE; + priv->file = file; + priv->flow_control_credentials = 0; + priv->timer_count = 0; + priv->me_client_id = 0; + priv->read_cb = NULL; + priv->status = ESUCCESS; + priv->read_pending = FALSE; + return priv; +} + + + +/** + * heci_disconnect_host_client - send disconnect message to fw from host client. + * + * @device_object -Device object for our driver + * @file_extension -extension of the file object + * + * @return : + * 0 on success, + * negative on failure. + */ +int heci_disconnect_host_client(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension) +{ + int return_status = ESUCCESS, err = 0; + long timeout = 15; /*15 second */ + + struct heci_cb_private *kernel_priv_cb = NULL; + + struct heci_file_private *file_extension_list_temp = NULL; + + struct heci_cb_private *kernel_priv_cb_pos = NULL, *kernel_priv_cb_next = NULL; + + if ((!device_object) || (!file_extension)) + return -ENODEV; + kernel_priv_cb = kmalloc(sizeof(struct heci_cb_private), GFP_KERNEL); + if (!kernel_priv_cb) + return -ENOMEM; + if (file_extension->state == HECI_FILE_DISCONNECTING) { + INIT_LIST_HEAD(&kernel_priv_cb->cb_list); + kernel_priv_cb->file_private = file_extension; + kernel_priv_cb->major_file_operations = HECI_CLOSE; + spin_lock_bh(&device_object->device_lock); + if (device_object->host_buffer_is_empty){ + device_object->host_buffer_is_empty =FALSE; + if (heci_disconnect(device_object, file_extension)) { + list_add_tail(&kernel_priv_cb->cb_list, + &device_object->control_read_list. + heci_cb.cb_list); + } + else{ + spin_unlock_bh(&device_object->device_lock); + return_status = -ENODEV; + DBG("failed to call heci_disconnect for file_extension.\n"); + goto free; + } + } + else{ + kernel_priv_cb->file_private = file_extension; + DBG("add disconnect cb to control write list\n"); + list_add_tail(&kernel_priv_cb->cb_list, + &device_object->control_write_list.heci_cb.cb_list); + } + spin_unlock_bh(&device_object->device_lock); + + err = + wait_event_timeout + (device_object->wait_received_message, + (HECI_FILE_DISCONNECTED == file_extension->state), + timeout * HZ); + if (HECI_FILE_DISCONNECTED == file_extension->state) { + return_status = ESUCCESS; + DBG("successfully to disconnect from fw client.\n"); + } else { + return_status = -ENODEV; + if (HECI_FILE_DISCONNECTED != file_extension->state) + DBG("wrong status received for client disconnect.\n"); + if (!err) + DBG("wait_event_interruptible_timeout failed on client disconnect message fw response message err=%08x\n", err); + DBG("failed to diconnect to fw client.\n"); + } + + } + if (kernel_priv_cb) { + spin_lock_bh(&device_object->device_lock); + if (device_object->control_read_list.status == ESUCCESS + && !list_empty(&device_object->control_read_list.heci_cb.cb_list)) { + list_for_each_entry_safe(kernel_priv_cb_pos, kernel_priv_cb_next, &device_object->control_read_list.heci_cb.cb_list, cb_list){ + file_extension_list_temp = + (struct heci_file_private *) + kernel_priv_cb_pos->file_private; + if (file_extension_list_temp) { + if ((file_extension->host_client_id == file_extension_list_temp->host_client_id) + && (file_extension->me_client_id == file_extension_list_temp->me_client_id)) { + list_del(&kernel_priv_cb_pos->cb_list); + } + } + + } + } + spin_unlock_bh(&device_object->device_lock); +free: + kfree(kernel_priv_cb); + kernel_priv_cb = NULL; + + + } + + return return_status; +} + + +/** + * heci_remove_client_from_file_list - remove file extension from device file list + * + * @device_object -Device object for our driver + * @host_client_id -host client id to be removed + * + * @return : + * none; + */ +void heci_remove_client_from_file_list(struct iamt_heci_device * device_object, + __u8 host_client_id) +{ + struct heci_file_private *file_extension_pos = NULL; + struct heci_file_private *file_extension_next = NULL; + list_for_each_entry_safe(file_extension_pos, file_extension_next, &device_object->file_list, link) { + if (host_client_id == file_extension_pos->host_client_id) { + DBG("remove file extension node host client = %d, ME client = %d\n", + file_extension_pos->host_client_id, + file_extension_pos->me_client_id); + list_del(&file_extension_pos->link); + break; + } + + + } +} --- linux-2.6.28.orig/ubuntu/heci/heci.h +++ linux-2.6.28/ubuntu/heci/heci.h @@ -0,0 +1,141 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2003 - 2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + +#ifndef _HECI_H_ +#define _HECI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "heci_data_structures.h" + + +extern const struct guid heci_pthi_guid; +extern const struct guid heci_wd_guid; +extern const __u8 start_wd_params[]; +extern const __u8 stop_wd_params[]; +extern const __u8 heci_wd_state_independence_msg[2][4]; + +/** + * memory IO BAR definition + */ +#define BAR_0 0 +#define BAR_1 1 +#define BAR_5 5 +/** + * Number of queue lists used by this driver + */ +#define PCI_HECI_DEVICE_ID1 0x2974 +#define PCI_HECI_DEVICE_ID2 0x2984 +#define PCI_HECI_DEVICE_ID3 0x2994 +#define PCI_HECI_DEVICE_ID4 0x29A4 +#define PCI_HECI_DEVICE_ID5 0x29B4 +#define PCI_HECI_DEVICE_ID6 0x29C4 +#define PCI_HECI_DEVICE_ID7 0x29E4 +#define PCI_HECI_DEVICE_ID8 0x29F4 + +/** + * heci init function prototypes + */ +struct iamt_heci_device *init_heci_device(struct pci_dev *pdev); +void heci_reset(struct iamt_heci_device * device_object, int interrupts); +int heci_hw_init(struct iamt_heci_device * device_object); +int heci_initialize_clients(void *data); +struct heci_file_private *alloc_priv(struct file *file); +int heci_disconnect_host_client(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); +void heci_initialize_list(struct io_heci_list *list, + struct iamt_heci_device * device_object); +void heci_flush_list(struct io_heci_list *list, + struct heci_file_private * file_extension); +void heci_flush_queues(struct iamt_heci_device * device_object, + struct heci_file_private * file_extension); + +void heci_remove_client_from_file_list(struct iamt_heci_device * device_object, + __u8 host_client_id); + +/** + * interrupt function prototype + */ +irqreturn_t heci_isr_interrupt(int irq, void *dev_id); +void heci_wd_timer(unsigned long data); +void heci_bh_handler(struct work_struct *work); +/** + * input output function prototype + */ +int heci_ioctl_get_version(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct heci_file_private * file_extension); +int heci_ioctl_connect_client(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file); +int heci_ioctl_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension); +int heci_ioctl_bypass_wd(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct heci_file_private * file_extension); +int legacy_ioctl_send_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data k_msg, + struct file *file); +int legacy_ioctl_receive_message(struct iamt_heci_device * device, int if_num, + struct heci_message_data *u_msg, + struct heci_message_data k_msg, + struct file *file); +int heci_start_read(struct iamt_heci_device * device, int if_num, + struct heci_file_private * file_extension); +int pthi_write(struct iamt_heci_device * device, + struct heci_cb_private *kernel_priv_cb); +int pthi_read(struct iamt_heci_device * device, int if_num, struct file *file, + char *ubuf, size_t length, loff_t* offset); +struct heci_cb_private* find_pthi_read_list_entry(struct iamt_heci_device* device, + struct file* file, struct heci_file_private* file_extension); +void run_next_legacy_cmd(struct iamt_heci_device * device); + +#endif /* _HECI_H_ */ --- linux-2.6.28.orig/ubuntu/heci/BOM +++ linux-2.6.28/ubuntu/heci/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=193428 +Current Version: 3.2.0.24 --- linux-2.6.28.orig/ubuntu/heci/version.h +++ linux-2.6.28/ubuntu/heci/version.h @@ -0,0 +1,53 @@ +/* + * Part of Intel(R) Manageability Engine Interface Linux driver + * + * Copyright (c) 2006-2007 Intel Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + */ + +#ifndef HECI_VERSION_H +#define HECI_VERSION_H + +#define MAJOR_VERSION 3 +#define MINOR_VERSION 2 +#define QUICK_FIX_NUMBER 0 +#define VER_BUILD 24 + +#define str(s) name(s) +#define name(s) #s +#define DRIVER_VERSION str(MAJOR_VERSION) "." str(MINOR_VERSION) "." str(QUICK_FIX_NUMBER) "." str(VER_BUILD) + +#endif --- linux-2.6.28.orig/ubuntu/squashfs/squashfs2_0.c +++ linux-2.6.28/ubuntu/squashfs/squashfs2_0.c @@ -0,0 +1,740 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs2_0.c + */ + +#include +#include +#include +#include +#include +#include + +#include "squashfs.h" +static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir); +static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *, + struct nameidata *); + +static struct file_operations squashfs_dir_ops_2 = { + .read = generic_read_dir, + .readdir = squashfs_readdir_2 +}; + +static struct inode_operations squashfs_dir_inode_ops_2 = { + .lookup = squashfs_lookup_2 +}; + +static unsigned char squashfs_filetype_table[] = { + DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK +}; + +static int read_fragment_index_table_2(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + + if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2 + (sblk->fragments), GFP_KERNEL))) { + ERROR("Failed to allocate uid/gid table\n"); + return 0; + } + + if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) && + !squashfs_read_data(s, (char *) + msblk->fragment_index_2, + sblk->fragment_table_start, + SQUASHFS_FRAGMENT_INDEX_BYTES_2 + (sblk->fragments) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) { + ERROR("unable to read fragment index table\n"); + return 0; + } + + if (msblk->swap) { + int i; + unsigned int fragment; + + for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments); + i++) { + SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment), + &msblk->fragment_index_2[i], 1); + msblk->fragment_index_2[i] = fragment; + } + } + + return 1; +} + + +static int get_fragment_location_2(struct super_block *s, unsigned int fragment, + long long *fragment_start_block, + unsigned int *fragment_size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + long long start_block = + msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)]; + int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment); + struct squashfs_fragment_entry_2 fragment_entry; + + if (msblk->swap) { + struct squashfs_fragment_entry_2 sfragment_entry; + + if (!squashfs_get_cached_block(s, (char *) &sfragment_entry, + start_block, offset, + sizeof(sfragment_entry), &start_block, + &offset)) + goto out; + SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry); + } else + if (!squashfs_get_cached_block(s, (char *) &fragment_entry, + start_block, offset, + sizeof(fragment_entry), &start_block, + &offset)) + goto out; + + *fragment_start_block = fragment_entry.start_block; + *fragment_size = fragment_entry.size; + + return 1; + +out: + return 0; +} + + +static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, + struct squashfs_base_inode_header_2 *inodeb, unsigned int ino) +{ + struct squashfs_super_block *sblk = &msblk->sblk; + + i->i_ino = ino; + i->i_mtime.tv_sec = sblk->mkfs_time; + i->i_atime.tv_sec = sblk->mkfs_time; + i->i_ctime.tv_sec = sblk->mkfs_time; + i->i_uid = msblk->uid[inodeb->uid]; + i->i_mode = inodeb->mode; + i->i_nlink = 1; + i->i_size = 0; + if (inodeb->guid == SQUASHFS_GUIDS) + i->i_gid = i->i_uid; + else + i->i_gid = msblk->guid[inodeb->guid]; +} + + +static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode) +{ + struct super_block *s = i->i_sb; + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned int block = SQUASHFS_INODE_BLK(inode) + + sblk->inode_table_start; + unsigned int offset = SQUASHFS_INODE_OFFSET(inode); + unsigned int ino = SQUASHFS_MK_VFS_INODE(block - + sblk->inode_table_start, offset); + long long next_block; + unsigned int next_offset; + union squashfs_inode_header_2 id, sid; + struct squashfs_base_inode_header_2 *inodeb = &id.base, + *sinodeb = &sid.base; + + TRACE("Entered squashfs_read_inode_2\n"); + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) sinodeb, block, + offset, sizeof(*sinodeb), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb, + sizeof(*sinodeb)); + } else + if (!squashfs_get_cached_block(s, (char *) inodeb, block, + offset, sizeof(*inodeb), &next_block, + &next_offset)) + goto failed_read; + + squashfs_new_inode(msblk, i, inodeb, ino); + + switch(inodeb->inode_type) { + case SQUASHFS_FILE_TYPE: { + struct squashfs_reg_inode_header_2 *inodep = &id.reg; + struct squashfs_reg_inode_header_2 *sinodep = &sid.reg; + long long frag_blk; + unsigned int frag_size = 0; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + frag_blk = SQUASHFS_INVALID_BLK; + if (inodep->fragment != SQUASHFS_INVALID_FRAG && + !get_fragment_location_2(s, + inodep->fragment, &frag_blk, &frag_size)) + goto failed_read; + + i->i_size = inodep->file_size; + i->i_fop = &generic_ro_fops; + i->i_mode |= S_IFREG; + i->i_mtime.tv_sec = inodep->mtime; + i->i_atime.tv_sec = inodep->mtime; + i->i_ctime.tv_sec = inodep->mtime; + i->i_blocks = ((i->i_size - 1) >> 9) + 1; + SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; + SQUASHFS_I(i)->u.s1.fragment_size = frag_size; + SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->u.s1.block_list_start = next_block; + SQUASHFS_I(i)->offset = next_offset; + i->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %x, " + "block_list_start %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, next_block, + next_offset); + break; + } + case SQUASHFS_DIR_TYPE: { + struct squashfs_dir_inode_header_2 *inodep = &id.dir; + struct squashfs_dir_inode_header_2 *sinodep = &sid.dir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops_2; + i->i_fop = &squashfs_dir_ops_2; + i->i_mode |= S_IFDIR; + i->i_mtime.tv_sec = inodep->mtime; + i->i_atime.tv_sec = inodep->mtime; + i->i_ctime.tv_sec = inodep->mtime; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_count = 0; + SQUASHFS_I(i)->u.s2.parent_inode = 0; + + TRACE("Directory inode %x:%x, start_block %x, offset " + "%x\n", SQUASHFS_INODE_BLK(inode), + offset, inodep->start_block, + inodep->offset); + break; + } + case SQUASHFS_LDIR_TYPE: { + struct squashfs_ldir_inode_header_2 *inodep = &id.ldir; + struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep, + sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops_2; + i->i_fop = &squashfs_dir_ops_2; + i->i_mode |= S_IFDIR; + i->i_mtime.tv_sec = inodep->mtime; + i->i_atime.tv_sec = inodep->mtime; + i->i_ctime.tv_sec = inodep->mtime; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_start = next_block; + SQUASHFS_I(i)->u.s2.directory_index_offset = + next_offset; + SQUASHFS_I(i)->u.s2.directory_index_count = + inodep->i_count; + SQUASHFS_I(i)->u.s2.parent_inode = 0; + + TRACE("Long directory inode %x:%x, start_block %x, " + "offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, inodep->offset); + break; + } + case SQUASHFS_SYMLINK_TYPE: { + struct squashfs_symlink_inode_header_2 *inodep = + &id.symlink; + struct squashfs_symlink_inode_header_2 *sinodep = + &sid.symlink; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep, + sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_size = inodep->symlink_size; + i->i_op = &page_symlink_inode_operations; + i->i_data.a_ops = &squashfs_symlink_aops; + i->i_mode |= S_IFLNK; + SQUASHFS_I(i)->start_block = next_block; + SQUASHFS_I(i)->offset = next_offset; + + TRACE("Symbolic link inode %x:%x, start_block %llx, " + "offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + next_block, next_offset); + break; + } + case SQUASHFS_BLKDEV_TYPE: + case SQUASHFS_CHRDEV_TYPE: { + struct squashfs_dev_inode_header_2 *inodep = &id.dev; + struct squashfs_dev_inode_header_2 *sinodep = &sid.dev; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, (char *) + sinodep, block, offset, + sizeof(*sinodep), &next_block, + &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, (char *) + inodep, block, offset, + sizeof(*inodep), &next_block, + &next_offset)) + goto failed_read; + + i->i_mode |= (inodeb->inode_type == + SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : + S_IFBLK; + init_special_inode(i, i->i_mode, + old_decode_dev(inodep->rdev)); + + TRACE("Device inode %x:%x, rdev %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->rdev); + break; + } + case SQUASHFS_FIFO_TYPE: + case SQUASHFS_SOCKET_TYPE: { + + i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) + ? S_IFIFO : S_IFSOCK; + init_special_inode(i, i->i_mode, 0); + break; + } + default: + ERROR("Unknown inode type %d in squashfs_iget!\n", + inodeb->inode_type); + goto failed_read1; + } + + return 1; + +failed_read: + ERROR("Unable to read inode [%x:%x]\n", block, offset); + +failed_read1: + return 0; +} + + +static int get_dir_index_using_offset(struct super_block *s, long long + *next_block, unsigned int *next_offset, + long long index_start, + unsigned int index_offset, int i_count, + long long f_pos) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index_2 index; + + TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", + i_count, (unsigned int) f_pos); + + if (f_pos == 0) + goto finish; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index_2 sindex; + squashfs_get_cached_block(s, (char *) &sindex, + index_start, index_offset, + sizeof(sindex), &index_start, + &index_offset); + SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex); + } else + squashfs_get_cached_block(s, (char *) &index, + index_start, index_offset, + sizeof(index), &index_start, + &index_offset); + + if (index.index > f_pos) + break; + + squashfs_get_cached_block(s, NULL, index_start, index_offset, + index.size + 1, &index_start, + &index_offset); + + length = index.index; + *next_block = index.start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + +finish: + return length; +} + + +static int get_dir_index_using_name(struct super_block *s, long long + *next_block, unsigned int *next_offset, + long long index_start, + unsigned int index_offset, int i_count, + const char *name, int size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index_2 *index; + char *str; + + TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); + + if (!(str = kmalloc(sizeof(struct squashfs_dir_index) + + (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_index\n"); + goto failure; + } + + index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1); + strncpy(str, name, size); + str[size] = '\0'; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index_2 sindex; + squashfs_get_cached_block(s, (char *) &sindex, + index_start, index_offset, + sizeof(sindex), &index_start, + &index_offset); + SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex); + } else + squashfs_get_cached_block(s, (char *) index, + index_start, index_offset, + sizeof(struct squashfs_dir_index_2), + &index_start, &index_offset); + + squashfs_get_cached_block(s, index->name, index_start, + index_offset, index->size + 1, + &index_start, &index_offset); + + index->name[index->size + 1] = '\0'; + + if (strcmp(index->name, str) > 0) + break; + + length = index->index; + *next_block = index->start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + kfree(str); +failure: + return length; +} + + +static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir) +{ + struct inode *i = file->f_dentry->d_inode; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, + dir_count; + struct squashfs_dir_header_2 dirh; + struct squashfs_dir_entry_2 *dire; + + TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset); + + if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto finish; + } + + length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, + file->f_pos); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header_2 sdirh; + + if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, + next_block, next_offset, sizeof(sdirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, + next_block, next_offset, sizeof(dirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry_2 sdire; + if (!squashfs_get_cached_block(i->i_sb, (char *) + &sdire, next_block, next_offset, + sizeof(sdire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) + dire, next_block, next_offset, + sizeof(*dire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, + next_block, next_offset, + dire->size + 1, &next_block, + &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (file->f_pos >= length) + continue; + + dire->name[dire->size + 1] = '\0'; + + TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", + (unsigned int) dirent, dire->name, + dire->size + 1, (int) file->f_pos, + dirh.start_block, dire->offset, + squashfs_filetype_table[dire->type]); + + if (filldir(dirent, dire->name, dire->size + 1, + file->f_pos, SQUASHFS_MK_VFS_INODE( + dirh.start_block, dire->offset), + squashfs_filetype_table[dire->type]) + < 0) { + TRACE("Filldir returned less than 0\n"); + goto finish; + } + file->f_pos = length; + } + } + +finish: + kfree(dire); + return 0; + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + kfree(dire); + return 0; +} + + +static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry, + struct nameidata *nd) +{ + const unsigned char *name = dentry->d_name.name; + int len = dentry->d_name.len; + struct inode *inode = NULL; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, + dir_count; + struct squashfs_dir_header_2 dirh; + struct squashfs_dir_entry_2 *dire; + int sorted = sblk->s_major == 2 && sblk->s_minor >= 1; + + TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset); + + if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto exit_loop; + } + + if (len > SQUASHFS_NAME_LEN) + goto exit_loop; + + length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, name, + len); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header_2 sdirh; + if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, + next_block, next_offset, sizeof(sdirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh, + next_block, next_offset, sizeof(dirh), + &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry_2 sdire; + if (!squashfs_get_cached_block(i->i_sb, (char *) + &sdire, next_block,next_offset, + sizeof(sdire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, (char *) + dire, next_block,next_offset, + sizeof(*dire), &next_block, + &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, + next_block, next_offset, dire->size + 1, + &next_block, &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (sorted && name[0] < dire->name[0]) + goto exit_loop; + + if ((len == dire->size + 1) && !strncmp(name, + dire->name, len)) { + squashfs_inode_t ino = + SQUASHFS_MKINODE(dirh.start_block, + dire->offset); + unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block, + dire->offset); + + TRACE("calling squashfs_iget for directory " + "entry %s, inode %x:%x, %lld\n", name, + dirh.start_block, dire->offset, ino); + + inode = squashfs_iget(i->i_sb, ino, inode_number); + + goto exit_loop; + } + } + } + +exit_loop: + kfree(dire); + d_add(dentry, inode); + return ERR_PTR(0); + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + goto exit_loop; +} + + +int squashfs_2_0_supported(struct squashfs_sb_info *msblk) +{ + struct squashfs_super_block *sblk = &msblk->sblk; + + msblk->read_inode = squashfs_read_inode_2; + msblk->read_fragment_index_table = read_fragment_index_table_2; + + sblk->bytes_used = sblk->bytes_used_2; + sblk->uid_start = sblk->uid_start_2; + sblk->guid_start = sblk->guid_start_2; + sblk->inode_table_start = sblk->inode_table_start_2; + sblk->directory_table_start = sblk->directory_table_start_2; + sblk->fragment_table_start = sblk->fragment_table_start_2; + + return 1; +} --- linux-2.6.28.orig/ubuntu/squashfs/squashfs.h +++ linux-2.6.28/ubuntu/squashfs/squashfs.h @@ -0,0 +1,86 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs.h + */ + +#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY +#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY +#endif + +#ifdef SQUASHFS_TRACE +#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) +#else +#define TRACE(s, args...) {} +#endif + +#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) + +#define SERROR(s, args...) do { \ + if (!silent) \ + printk(KERN_ERR "SQUASHFS error: "s, ## args);\ + } while(0) + +#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) + +static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode) +{ + return list_entry(inode, struct squashfs_inode_info, vfs_inode); +} + +#if defined(CONFIG_SQUASHFS_1_0_COMPATIBILITY ) || defined(CONFIG_SQUASHFS_2_0_COMPATIBILITY) +#define SQSH_EXTERN +extern unsigned int squashfs_read_data(struct super_block *s, char *buffer, + long long index, unsigned int length, + long long *next_index, int srclength); +extern int squashfs_get_cached_block(struct super_block *s, void *buffer, + long long block, unsigned int offset, + int length, long long *next_block, + unsigned int *next_offset); +extern void release_cached_fragment(struct squashfs_sb_info *msblk, struct + squashfs_fragment_cache *fragment); +extern struct squashfs_fragment_cache *get_cached_fragment(struct super_block + *s, long long start_block, + int length); +extern struct inode *squashfs_iget(struct super_block *s, squashfs_inode_t inode, unsigned int inode_number); +extern const struct address_space_operations squashfs_symlink_aops; +extern const struct address_space_operations squashfs_aops; +extern struct inode_operations squashfs_dir_inode_ops; +#else +#define SQSH_EXTERN static +#endif + +#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY +extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk); +#else +static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk) +{ + return 0; +} +#endif + +#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY +extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk); +#else +static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk) +{ + return 0; +} +#endif --- linux-2.6.28.orig/ubuntu/squashfs/Kconfig +++ linux-2.6.28/ubuntu/squashfs/Kconfig @@ -0,0 +1,50 @@ +config SQUASHFS + tristate "SquashFS 3.3 - Squashed file system support" + select ZLIB_INFLATE + help + Saying Y here includes support for SquashFS 3.3 (a Compressed + Read-Only File System). Squashfs is a highly compressed read-only + filesystem for Linux. It uses zlib compression to compress both + files, inodes and directories. Inodes in the system are very small + and all blocks are packed to minimise data overhead. Block sizes + greater than 4K are supported up to a maximum of 1 Mbytes (default + block size 128K). SquashFS 3.3 supports 64 bit filesystems and files + (larger than 4GB), full uid/gid information, hard links and timestamps. + + Squashfs is intended for general read-only filesystem use, for + archival use (i.e. in cases where a .tar.gz file may be used), and in + embedded systems where low overhead is needed. Further information + and filesystem tools are available from http://squashfs.sourceforge.net. + + If you want to compile this as a module ( = code which can be + inserted in and removed from the running kernel whenever you want), + say M here and read . The module + will be called squashfs. Note that the root file system (the one + containing the directory /) cannot be compiled as a module. + + If unsure, say N. + +config SQUASHFS_EMBEDDED + + bool "Additional option for memory-constrained systems" + depends on SQUASHFS + default n + help + Saying Y here allows you to specify cache size. + + If unsure, say N. + +config SQUASHFS_FRAGMENT_CACHE_SIZE + int "Number of fragments cached" if SQUASHFS_EMBEDDED + depends on SQUASHFS + default "3" + help + By default SquashFS caches the last 3 fragments read from + the filesystem. Increasing this amount may mean SquashFS + has to re-read fragments less often from disk, at the expense + of extra system memory. Decreasing this amount will mean + SquashFS uses less memory at the expense of extra reads from disk. + + Note there must be at least one cached fragment. Anything + much more than three will probably not make much difference. + --- linux-2.6.28.orig/ubuntu/squashfs/Makefile +++ linux-2.6.28/ubuntu/squashfs/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the linux squashfs routines. +# + +obj-$(CONFIG_SQUASHFS) += squashfs.o +squashfs-objs := inode.o squashfs2_0.o --- linux-2.6.28.orig/ubuntu/squashfs/inode.c +++ linux-2.6.28/ubuntu/squashfs/inode.c @@ -0,0 +1,2187 @@ +/* + * Squashfs - a compressed read only filesystem for Linux + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * inode.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "squashfs.h" + +int squashfs_cached_blks; + +#ifdef USE_EXPORT +static struct dentry *squashfs_get_parent(struct dentry *child); +#endif + +static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode); +static int squashfs_statfs(struct dentry *, struct kstatfs *); +static int squashfs_symlink_readpage(struct file *file, struct page *page); +static long long read_blocklist(struct inode *inode, int index, + int readahead_blks, char *block_list, + unsigned short **block_p, unsigned int *bsize); +static int squashfs_readpage(struct file *file, struct page *page); +static int squashfs_readdir(struct file *, void *, filldir_t); +static struct dentry *squashfs_lookup(struct inode *, struct dentry *, + struct nameidata *); +static int squashfs_remount(struct super_block *s, int *flags, char *data); +static void squashfs_put_super(struct super_block *); +static int squashfs_get_sb(struct file_system_type *,int, const char *, void *, + struct vfsmount *); +static struct inode *squashfs_alloc_inode(struct super_block *sb); +static void squashfs_destroy_inode(struct inode *inode); +static int init_inodecache(void); +static void destroy_inodecache(void); + +static struct file_system_type squashfs_fs_type = { + .owner = THIS_MODULE, + .name = "squashfs", + .get_sb = squashfs_get_sb, + .kill_sb = kill_block_super, + .fs_flags = FS_REQUIRES_DEV +}; + +static const unsigned char squashfs_filetype_table[] = { + DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK +}; + +static struct super_operations squashfs_super_ops = { + .alloc_inode = squashfs_alloc_inode, + .destroy_inode = squashfs_destroy_inode, + .statfs = squashfs_statfs, + .put_super = squashfs_put_super, + .remount_fs = squashfs_remount +}; + +static struct super_operations squashfs_export_super_ops = { + .alloc_inode = squashfs_alloc_inode, + .destroy_inode = squashfs_destroy_inode, + .statfs = squashfs_statfs, + .put_super = squashfs_put_super, +}; + +#ifdef USE_EXPORT +static struct export_operations squashfs_export_ops = { + .get_parent = squashfs_get_parent +}; +#endif + +SQSH_EXTERN const struct address_space_operations squashfs_symlink_aops = { + .readpage = squashfs_symlink_readpage +}; + +SQSH_EXTERN const struct address_space_operations squashfs_aops = { + .readpage = squashfs_readpage +}; + +static const struct file_operations squashfs_dir_ops = { + .read = generic_read_dir, + .readdir = squashfs_readdir +}; + +SQSH_EXTERN struct inode_operations squashfs_dir_inode_ops = { + .lookup = squashfs_lookup +}; + + +static struct buffer_head *get_block_length(struct super_block *s, + int *cur_index, int *offset, int *c_byte) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + unsigned short temp; + struct buffer_head *bh; + + if (!(bh = sb_bread(s, *cur_index))) + goto out; + + if (msblk->devblksize - *offset == 1) { + if (msblk->swap) + ((unsigned char *) &temp)[1] = *((unsigned char *) + (bh->b_data + *offset)); + else + ((unsigned char *) &temp)[0] = *((unsigned char *) + (bh->b_data + *offset)); + brelse(bh); + if (!(bh = sb_bread(s, ++(*cur_index)))) + goto out; + if (msblk->swap) + ((unsigned char *) &temp)[0] = *((unsigned char *) + bh->b_data); + else + ((unsigned char *) &temp)[1] = *((unsigned char *) + bh->b_data); + *c_byte = temp; + *offset = 1; + } else { + if (msblk->swap) { + ((unsigned char *) &temp)[1] = *((unsigned char *) + (bh->b_data + *offset)); + ((unsigned char *) &temp)[0] = *((unsigned char *) + (bh->b_data + *offset + 1)); + } else { + ((unsigned char *) &temp)[0] = *((unsigned char *) + (bh->b_data + *offset)); + ((unsigned char *) &temp)[1] = *((unsigned char *) + (bh->b_data + *offset + 1)); + } + *c_byte = temp; + *offset += 2; + } + + if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) { + if (*offset == msblk->devblksize) { + brelse(bh); + if (!(bh = sb_bread(s, ++(*cur_index)))) + goto out; + *offset = 0; + } + if (*((unsigned char *) (bh->b_data + *offset)) != + SQUASHFS_MARKER_BYTE) { + ERROR("Metadata block marker corrupt @ %x\n", + *cur_index); + brelse(bh); + goto out; + } + (*offset)++; + } + return bh; + +out: + return NULL; +} + + +SQSH_EXTERN unsigned int squashfs_read_data(struct super_block *s, char *buffer, + long long index, unsigned int length, + long long *next_index, int srclength) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + struct buffer_head **bh; + unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1); + unsigned int cur_index = index >> msblk->devblksize_log2; + int bytes, avail_bytes, b = 0, k = 0; + unsigned int compressed; + unsigned int c_byte = length; + + bh = kmalloc(((sblk->block_size >> msblk->devblksize_log2) + 1) * + sizeof(struct buffer_head *), GFP_KERNEL); + if (bh == NULL) + goto read_failure; + + if (c_byte) { + bytes = msblk->devblksize - offset; + compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte); + c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); + + TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index, + compressed ? "" : "un", (unsigned int) c_byte, srclength); + + if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used) + goto read_failure; + + bh[0] = sb_getblk(s, cur_index); + if (bh[0] == NULL) + goto block_release; + + for (b = 1; bytes < c_byte; b++) { + bh[b] = sb_getblk(s, ++cur_index); + if (bh[b] == NULL) + goto block_release; + bytes += msblk->devblksize; + } + ll_rw_block(READ, b, bh); + } else { + if (index < 0 || (index + 2) > sblk->bytes_used) + goto read_failure; + + bh[0] = get_block_length(s, &cur_index, &offset, &c_byte); + if (bh[0] == NULL) + goto read_failure; + + bytes = msblk->devblksize - offset; + compressed = SQUASHFS_COMPRESSED(c_byte); + c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); + + TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed + ? "" : "un", (unsigned int) c_byte); + + if (c_byte > srclength || (index + c_byte) > sblk->bytes_used) + goto read_failure; + + for (b = 1; bytes < c_byte; b++) { + bh[b] = sb_getblk(s, ++cur_index); + if (bh[b] == NULL) + goto block_release; + bytes += msblk->devblksize; + } + ll_rw_block(READ, b - 1, bh + 1); + } + + if (compressed) { + int zlib_err = 0; + + /* + * uncompress block + */ + + mutex_lock(&msblk->read_data_mutex); + + msblk->stream.next_out = buffer; + msblk->stream.avail_out = srclength; + + for (bytes = 0; k < b; k++) { + avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); + + wait_on_buffer(bh[k]); + if (!buffer_uptodate(bh[k])) + goto release_mutex; + + msblk->stream.next_in = bh[k]->b_data + offset; + msblk->stream.avail_in = avail_bytes; + + if (k == 0) { + zlib_err = zlib_inflateInit(&msblk->stream); + if (zlib_err != Z_OK) { + ERROR("zlib_inflateInit returned unexpected result 0x%x," + " srclength %d\n", zlib_err, srclength); + goto release_mutex; + } + + if (avail_bytes == 0) { + offset = 0; + brelse(bh[k]); + continue; + } + } + + zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH); + if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) { + ERROR("zlib_inflate returned unexpected result 0x%x," + " srclength %d, avail_in %d, avail_out %d\n", zlib_err, + srclength, msblk->stream.avail_in, msblk->stream.avail_out); + goto release_mutex; + } + + bytes += avail_bytes; + offset = 0; + brelse(bh[k]); + } + + if (zlib_err != Z_STREAM_END) + goto release_mutex; + + zlib_err = zlib_inflateEnd(&msblk->stream); + if (zlib_err != Z_OK) { + ERROR("zlib_inflateEnd returned unexpected result 0x%x," + " srclength %d\n", zlib_err, srclength); + goto release_mutex; + } + bytes = msblk->stream.total_out; + mutex_unlock(&msblk->read_data_mutex); + } else { + int i; + + for(i = 0; i < b; i++) { + wait_on_buffer(bh[i]); + if (!buffer_uptodate(bh[i])) + goto block_release; + } + + for (bytes = 0; k < b; k++) { + avail_bytes = min(c_byte - bytes, msblk->devblksize - offset); + + memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes); + bytes += avail_bytes; + offset = 0; + brelse(bh[k]); + } + } + + if (next_index) + *next_index = index + c_byte + (length ? 0 : + (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ? 3 : 2)); + + kfree(bh); + return bytes; + +release_mutex: + mutex_unlock(&msblk->read_data_mutex); + +block_release: + for (; k < b; k++) + brelse(bh[k]); + +read_failure: + ERROR("sb_bread failed reading block 0x%x\n", cur_index); + kfree(bh); + return 0; +} + + +SQSH_EXTERN int squashfs_get_cached_block(struct super_block *s, void *buffer, + long long block, unsigned int offset, + int length, long long *next_block, + unsigned int *next_offset) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + int n, i, bytes, return_length = length; + long long next_index; + + TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset); + + while (1) { + for (i = 0; i < squashfs_cached_blks; i++) + if (msblk->block_cache[i].block == block) + break; + + mutex_lock(&msblk->block_cache_mutex); + + if (i == squashfs_cached_blks) { + /* read inode header block */ + if (msblk->unused_cache_blks == 0) { + mutex_unlock(&msblk->block_cache_mutex); + wait_event(msblk->waitq, msblk->unused_cache_blks); + continue; + } + + i = msblk->next_cache; + for (n = 0; n < squashfs_cached_blks; n++) { + if (msblk->block_cache[i].block != SQUASHFS_USED_BLK) + break; + i = (i + 1) % squashfs_cached_blks; + } + + msblk->next_cache = (i + 1) % squashfs_cached_blks; + + if (msblk->block_cache[i].block == SQUASHFS_INVALID_BLK) { + msblk->block_cache[i].data = vmalloc(SQUASHFS_METADATA_SIZE); + if (msblk->block_cache[i].data == NULL) { + ERROR("Failed to allocate cache block\n"); + mutex_unlock(&msblk->block_cache_mutex); + goto out; + } + } + + msblk->block_cache[i].block = SQUASHFS_USED_BLK; + msblk->unused_cache_blks --; + mutex_unlock(&msblk->block_cache_mutex); + + msblk->block_cache[i].length = squashfs_read_data(s, + msblk->block_cache[i].data, block, 0, &next_index, + SQUASHFS_METADATA_SIZE); + + if (msblk->block_cache[i].length == 0) { + ERROR("Unable to read cache block [%llx:%x]\n", block, offset); + mutex_lock(&msblk->block_cache_mutex); + msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; + msblk->unused_cache_blks ++; + smp_mb(); + vfree(msblk->block_cache[i].data); + wake_up(&msblk->waitq); + mutex_unlock(&msblk->block_cache_mutex); + goto out; + } + + mutex_lock(&msblk->block_cache_mutex); + msblk->block_cache[i].block = block; + msblk->block_cache[i].next_index = next_index; + msblk->unused_cache_blks ++; + smp_mb(); + wake_up(&msblk->waitq); + TRACE("Read cache block [%llx:%x]\n", block, offset); + } + + if (msblk->block_cache[i].block != block) { + mutex_unlock(&msblk->block_cache_mutex); + continue; + } + + bytes = msblk->block_cache[i].length - offset; + + if (bytes < 1) { + mutex_unlock(&msblk->block_cache_mutex); + goto out; + } else if (bytes >= length) { + if (buffer) + memcpy(buffer, msblk->block_cache[i].data + offset, length); + if (msblk->block_cache[i].length - offset == length) { + *next_block = msblk->block_cache[i].next_index; + *next_offset = 0; + } else { + *next_block = block; + *next_offset = offset + length; + } + mutex_unlock(&msblk->block_cache_mutex); + goto finish; + } else { + if (buffer) { + memcpy(buffer, msblk->block_cache[i].data + offset, bytes); + buffer = (char *) buffer + bytes; + } + block = msblk->block_cache[i].next_index; + mutex_unlock(&msblk->block_cache_mutex); + length -= bytes; + offset = 0; + } + } + +finish: + return return_length; +out: + return 0; +} + + +static int get_fragment_location(struct super_block *s, unsigned int fragment, + long long *fragment_start_block, + unsigned int *fragment_size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + long long start_block = + msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; + int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); + struct squashfs_fragment_entry fragment_entry; + + if (msblk->swap) { + struct squashfs_fragment_entry sfragment_entry; + + if (!squashfs_get_cached_block(s, &sfragment_entry, start_block, offset, + sizeof(sfragment_entry), &start_block, &offset)) + goto out; + SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); + } else + if (!squashfs_get_cached_block(s, &fragment_entry, start_block, offset, + sizeof(fragment_entry), &start_block, &offset)) + goto out; + + *fragment_start_block = fragment_entry.start_block; + *fragment_size = fragment_entry.size; + + return 1; + +out: + return 0; +} + + +SQSH_EXTERN void release_cached_fragment(struct squashfs_sb_info *msblk, + struct squashfs_fragment_cache *fragment) +{ + mutex_lock(&msblk->fragment_mutex); + fragment->locked --; + if (fragment->locked == 0) { + msblk->unused_frag_blks ++; + smp_mb(); + wake_up(&msblk->fragment_wait_queue); + } + mutex_unlock(&msblk->fragment_mutex); +} + + +SQSH_EXTERN +struct squashfs_fragment_cache *get_cached_fragment(struct super_block *s, + long long start_block, int length) +{ + int i, n; + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + + while (1) { + mutex_lock(&msblk->fragment_mutex); + + for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS && + msblk->fragment[i].block != start_block; i++); + + if (i == SQUASHFS_CACHED_FRAGMENTS) { + if (msblk->unused_frag_blks == 0) { + mutex_unlock(&msblk->fragment_mutex); + wait_event(msblk->fragment_wait_queue, msblk->unused_frag_blks); + continue; + } + + i = msblk->next_fragment; + for (n = 0; n < SQUASHFS_CACHED_FRAGMENTS; n++) { + if (msblk->fragment[i].locked == 0) + break; + i = (i + 1) % SQUASHFS_CACHED_FRAGMENTS; + } + + msblk->next_fragment = (msblk->next_fragment + 1) % + SQUASHFS_CACHED_FRAGMENTS; + + if (msblk->fragment[i].data == NULL) { + msblk->fragment[i].data = vmalloc(sblk->block_size); + if (msblk->fragment[i].data == NULL) { + ERROR("Failed to allocate fragment cache block\n"); + mutex_unlock(&msblk->fragment_mutex); + goto out; + } + } + + msblk->unused_frag_blks --; + msblk->fragment[i].block = SQUASHFS_INVALID_BLK; + msblk->fragment[i].locked = 1; + mutex_unlock(&msblk->fragment_mutex); + + msblk->fragment[i].length = squashfs_read_data(s, + msblk->fragment[i].data, start_block, length, NULL, + sblk->block_size); + + if (msblk->fragment[i].length == 0) { + ERROR("Unable to read fragment cache block [%llx]\n", start_block); + msblk->fragment[i].locked = 0; + msblk->unused_frag_blks ++; + smp_mb(); + wake_up(&msblk->fragment_wait_queue); + goto out; + } + + mutex_lock(&msblk->fragment_mutex); + msblk->fragment[i].block = start_block; + TRACE("New fragment %d, start block %lld, locked %d\n", + i, msblk->fragment[i].block, msblk->fragment[i].locked); + mutex_unlock(&msblk->fragment_mutex); + break; + } + + if (msblk->fragment[i].locked == 0) + msblk->unused_frag_blks --; + msblk->fragment[i].locked++; + mutex_unlock(&msblk->fragment_mutex); + TRACE("Got fragment %d, start block %lld, locked %d\n", i, + msblk->fragment[i].block, msblk->fragment[i].locked); + break; + } + + return &msblk->fragment[i]; + +out: + return NULL; +} + + +static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i, + struct squashfs_base_inode_header *inodeb) +{ + i->i_ino = inodeb->inode_number; + i->i_mtime.tv_sec = inodeb->mtime; + i->i_atime.tv_sec = inodeb->mtime; + i->i_ctime.tv_sec = inodeb->mtime; + i->i_uid = msblk->uid[inodeb->uid]; + i->i_mode = inodeb->mode; + i->i_size = 0; + + if (inodeb->guid == SQUASHFS_GUIDS) + i->i_gid = i->i_uid; + else + i->i_gid = msblk->guid[inodeb->guid]; +} + +#ifdef USE_EXPORT +static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)]; + int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1); + squashfs_inode_t inode; + + TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino); + + if (msblk->swap) { + squashfs_inode_t sinode; + + if (!squashfs_get_cached_block(s, &sinode, start, offset, + sizeof(sinode), &start, &offset)) + goto out; + SQUASHFS_SWAP_INODE_T((&inode), &sinode); + } else if (!squashfs_get_cached_block(s, &inode, start, offset, + sizeof(inode), &start, &offset)) + goto out; + + TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode); + + return inode; + +out: + return SQUASHFS_INVALID_BLK; +} + +static struct dentry *squashfs_get_parent(struct dentry *child) +{ + struct inode *i = child->d_inode; + struct inode *parent = iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode); + struct dentry *rv; + + TRACE("Entered squashfs_get_parent\n"); + + if(parent == NULL) { + rv = ERR_PTR(-EACCES); + goto out; + } + + rv = d_alloc_anon(parent); + if(rv == NULL) + rv = ERR_PTR(-ENOMEM); + +out: + return rv; +} +#endif + +SQSH_EXTERN struct inode *squashfs_iget(struct super_block *s, + squashfs_inode_t inode, unsigned int inode_number) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct inode *i = iget_locked(s, inode_number); + + TRACE("Entered squashfs_iget\n"); + + if (!i) + return ERR_PTR(-ENOMEM); + + if (i->i_state & I_NEW) { + (msblk->read_inode)(i, inode); + unlock_new_inode(i); + } + + return i; +} + + +static int squashfs_read_inode(struct inode *i, squashfs_inode_t inode) +{ + struct super_block *s = i->i_sb; + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long block = SQUASHFS_INODE_BLK(inode) + sblk->inode_table_start; + unsigned int offset = SQUASHFS_INODE_OFFSET(inode); + long long next_block; + unsigned int next_offset; + union squashfs_inode_header id, sid; + struct squashfs_base_inode_header *inodeb = &id.base, *sinodeb = &sid.base; + + TRACE("Entered squashfs_read_inode\n"); + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodeb, block, offset, + sizeof(*sinodeb), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, sizeof(*sinodeb)); + } else + if (!squashfs_get_cached_block(s, inodeb, block, offset, + sizeof(*inodeb), &next_block, &next_offset)) + goto failed_read; + + squashfs_new_inode(msblk, i, inodeb); + + switch(inodeb->inode_type) { + case SQUASHFS_FILE_TYPE: { + unsigned int frag_size; + long long frag_blk; + struct squashfs_reg_inode_header *inodep = &id.reg; + struct squashfs_reg_inode_header *sinodep = &sid.reg; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + frag_blk = SQUASHFS_INVALID_BLK; + + if (inodep->fragment != SQUASHFS_INVALID_FRAG) + if(!get_fragment_location(s, inodep->fragment, &frag_blk, + &frag_size)) + goto failed_read; + + i->i_nlink = 1; + i->i_size = inodep->file_size; + i->i_fop = &generic_ro_fops; + i->i_mode |= S_IFREG; + i->i_blocks = ((i->i_size - 1) >> 9) + 1; + SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; + SQUASHFS_I(i)->u.s1.fragment_size = frag_size; + SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->u.s1.block_list_start = next_block; + SQUASHFS_I(i)->offset = next_offset; + i->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %llx, " + "block_list_start %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, next_block, + next_offset); + break; + } + case SQUASHFS_LREG_TYPE: { + unsigned int frag_size; + long long frag_blk; + struct squashfs_lreg_inode_header *inodep = &id.lreg; + struct squashfs_lreg_inode_header *sinodep = &sid.lreg; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + frag_blk = SQUASHFS_INVALID_BLK; + + if (inodep->fragment != SQUASHFS_INVALID_FRAG) + if (!get_fragment_location(s, inodep->fragment, &frag_blk, + &frag_size)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->file_size; + i->i_fop = &generic_ro_fops; + i->i_mode |= S_IFREG; + i->i_blocks = ((i->i_size - 1) >> 9) + 1; + SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk; + SQUASHFS_I(i)->u.s1.fragment_size = frag_size; + SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->u.s1.block_list_start = next_block; + SQUASHFS_I(i)->offset = next_offset; + i->i_data.a_ops = &squashfs_aops; + + TRACE("File inode %x:%x, start_block %llx, " + "block_list_start %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, next_block, + next_offset); + break; + } + case SQUASHFS_DIR_TYPE: { + struct squashfs_dir_inode_header *inodep = &id.dir; + struct squashfs_dir_inode_header *sinodep = &sid.dir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops; + i->i_fop = &squashfs_dir_ops; + i->i_mode |= S_IFDIR; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_count = 0; + SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; + + TRACE("Directory inode %x:%x, start_block %x, offset " + "%x\n", SQUASHFS_INODE_BLK(inode), + offset, inodep->start_block, + inodep->offset); + break; + } + case SQUASHFS_LDIR_TYPE: { + struct squashfs_ldir_inode_header *inodep = &id.ldir; + struct squashfs_ldir_inode_header *sinodep = &sid.ldir; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->file_size; + i->i_op = &squashfs_dir_inode_ops; + i->i_fop = &squashfs_dir_ops; + i->i_mode |= S_IFDIR; + SQUASHFS_I(i)->start_block = inodep->start_block; + SQUASHFS_I(i)->offset = inodep->offset; + SQUASHFS_I(i)->u.s2.directory_index_start = next_block; + SQUASHFS_I(i)->u.s2.directory_index_offset = next_offset; + SQUASHFS_I(i)->u.s2.directory_index_count = inodep->i_count; + SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode; + + TRACE("Long directory inode %x:%x, start_block %x, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + inodep->start_block, inodep->offset); + break; + } + case SQUASHFS_SYMLINK_TYPE: { + struct squashfs_symlink_inode_header *inodep = &id.symlink; + struct squashfs_symlink_inode_header *sinodep = &sid.symlink; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_size = inodep->symlink_size; + i->i_op = &page_symlink_inode_operations; + i->i_data.a_ops = &squashfs_symlink_aops; + i->i_mode |= S_IFLNK; + SQUASHFS_I(i)->start_block = next_block; + SQUASHFS_I(i)->offset = next_offset; + + TRACE("Symbolic link inode %x:%x, start_block %llx, offset %x\n", + SQUASHFS_INODE_BLK(inode), offset, + next_block, next_offset); + break; + } + case SQUASHFS_BLKDEV_TYPE: + case SQUASHFS_CHRDEV_TYPE: { + struct squashfs_dev_inode_header *inodep = &id.dev; + struct squashfs_dev_inode_header *sinodep = &sid.dev; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ? + S_IFCHR : S_IFBLK; + init_special_inode(i, i->i_mode, old_decode_dev(inodep->rdev)); + + TRACE("Device inode %x:%x, rdev %x\n", + SQUASHFS_INODE_BLK(inode), offset, inodep->rdev); + break; + } + case SQUASHFS_FIFO_TYPE: + case SQUASHFS_SOCKET_TYPE: { + struct squashfs_ipc_inode_header *inodep = &id.ipc; + struct squashfs_ipc_inode_header *sinodep = &sid.ipc; + + if (msblk->swap) { + if (!squashfs_get_cached_block(s, sinodep, block, offset, + sizeof(*sinodep), &next_block, &next_offset)) + goto failed_read; + SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep); + } else + if (!squashfs_get_cached_block(s, inodep, block, offset, + sizeof(*inodep), &next_block, &next_offset)) + goto failed_read; + + i->i_nlink = inodep->nlink; + i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE) + ? S_IFIFO : S_IFSOCK; + init_special_inode(i, i->i_mode, 0); + break; + } + default: + ERROR("Unknown inode type %d in squashfs_iget!\n", + inodeb->inode_type); + goto failed_read1; + } + + return 1; + +failed_read: + ERROR("Unable to read inode [%llx:%x]\n", block, offset); + +failed_read1: + make_bad_inode(i); + return 0; +} + + +static int read_inode_lookup_table(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes); + + TRACE("In read_inode_lookup_table, length %d\n", length); + + /* Allocate inode lookup table */ + msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL); + if (msblk->inode_lookup_table == NULL) { + ERROR("Failed to allocate inode lookup table\n"); + return 0; + } + + if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table, + sblk->lookup_table_start, length | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { + ERROR("unable to read inode lookup table\n"); + return 0; + } + + if (msblk->swap) { + int i; + long long block; + + for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) { + /* XXX */ + SQUASHFS_SWAP_LOOKUP_BLOCKS((&block), + &msblk->inode_lookup_table[i], 1); + msblk->inode_lookup_table[i] = block; + } + } + + return 1; +} + + +static int read_fragment_index_table(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments); + + if(length == 0) + return 1; + + /* Allocate fragment index table */ + msblk->fragment_index = kmalloc(length, GFP_KERNEL); + if (msblk->fragment_index == NULL) { + ERROR("Failed to allocate fragment index table\n"); + return 0; + } + + if (!squashfs_read_data(s, (char *) msblk->fragment_index, + sblk->fragment_table_start, length | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) { + ERROR("unable to read fragment index table\n"); + return 0; + } + + if (msblk->swap) { + int i; + long long fragment; + + for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) { + /* XXX */ + SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), + &msblk->fragment_index[i], 1); + msblk->fragment_index[i] = fragment; + } + } + + return 1; +} + + +static int readahead_metadata(struct super_block *s) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + int i; + + squashfs_cached_blks = SQUASHFS_CACHED_BLKS; + + /* Init inode_table block pointer array */ + msblk->block_cache = kmalloc(sizeof(struct squashfs_cache) * + squashfs_cached_blks, GFP_KERNEL); + if (msblk->block_cache == NULL) { + ERROR("Failed to allocate block cache\n"); + goto failed; + } + + for (i = 0; i < squashfs_cached_blks; i++) + msblk->block_cache[i].block = SQUASHFS_INVALID_BLK; + + msblk->next_cache = 0; + msblk->unused_cache_blks = squashfs_cached_blks; + + return 1; + +failed: + return 0; +} + + +static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent) +{ + struct squashfs_super_block *sblk = &msblk->sblk; + + msblk->read_inode = squashfs_read_inode; + msblk->read_blocklist = read_blocklist; + msblk->read_fragment_index_table = read_fragment_index_table; + + if (sblk->s_major == 1) { + if (!squashfs_1_0_supported(msblk)) { + SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems " + "are unsupported\n"); + SERROR("Please recompile with Squashfs 1.0 support enabled\n"); + return 0; + } + } else if (sblk->s_major == 2) { + if (!squashfs_2_0_supported(msblk)) { + SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems " + "are unsupported\n"); + SERROR("Please recompile with Squashfs 2.0 support enabled\n"); + return 0; + } + } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor > + SQUASHFS_MINOR) { + SERROR("Major/Minor mismatch, trying to mount newer %d.%d " + "filesystem\n", sblk->s_major, sblk->s_minor); + SERROR("Please update your kernel\n"); + return 0; + } + + return 1; +} + + +static int squashfs_fill_super(struct super_block *s, void *data, int silent) +{ + struct squashfs_sb_info *msblk; + struct squashfs_super_block *sblk; + int i; + char b[BDEVNAME_SIZE]; + struct inode *root; + + TRACE("Entered squashfs_fill_superblock\n"); + + s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL); + if (s->s_fs_info == NULL) { + ERROR("Failed to allocate superblock\n"); + goto failure; + } + msblk = s->s_fs_info; + + msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize()); + if (msblk->stream.workspace == NULL) { + ERROR("Failed to allocate zlib workspace\n"); + goto failure; + } + sblk = &msblk->sblk; + + msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE); + msblk->devblksize_log2 = ffz(~msblk->devblksize); + + mutex_init(&msblk->read_data_mutex); + mutex_init(&msblk->read_page_mutex); + mutex_init(&msblk->block_cache_mutex); + mutex_init(&msblk->fragment_mutex); + mutex_init(&msblk->meta_index_mutex); + + init_waitqueue_head(&msblk->waitq); + init_waitqueue_head(&msblk->fragment_wait_queue); + + /* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not + * beyond filesystem end. As we're using squashfs_read_data to read sblk here, + * first set sblk->bytes_used to a useful value */ + sblk->bytes_used = sizeof(struct squashfs_super_block); + if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START, + sizeof(struct squashfs_super_block) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) { + SERROR("unable to read superblock\n"); + goto failed_mount; + } + + /* Check it is a SQUASHFS superblock */ + if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) { + if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) { + struct squashfs_super_block ssblk; + + WARNING("Mounting a different endian SQUASHFS filesystem on %s\n", + bdevname(s->s_bdev, b)); + + SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk); + memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block)); + msblk->swap = 1; + } else { + SERROR("Can't find a SQUASHFS superblock on %s\n", + bdevname(s->s_bdev, b)); + goto failed_mount; + } + } + + /* Check the MAJOR & MINOR versions */ + if(!supported_squashfs_filesystem(msblk, silent)) + goto failed_mount; + + /* Check the filesystem does not extend beyond the end of the + block device */ + if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode)) + goto failed_mount; + + /* Check the root inode for sanity */ + if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE) + goto failed_mount; + + TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b)); + TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sblk->flags) + ? "un" : ""); + TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sblk->flags) + ? "un" : ""); + TRACE("Check data is %spresent in the filesystem\n", + SQUASHFS_CHECK_DATA(sblk->flags) ? "" : "not "); + TRACE("Filesystem size %lld bytes\n", sblk->bytes_used); + TRACE("Block size %d\n", sblk->block_size); + TRACE("Number of inodes %d\n", sblk->inodes); + if (sblk->s_major > 1) + TRACE("Number of fragments %d\n", sblk->fragments); + TRACE("Number of uids %d\n", sblk->no_uids); + TRACE("Number of gids %d\n", sblk->no_guids); + TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start); + TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start); + if (sblk->s_major > 1) + TRACE("sblk->fragment_table_start %llx\n", sblk->fragment_table_start); + TRACE("sblk->uid_start %llx\n", sblk->uid_start); + + s->s_maxbytes = MAX_LFS_FILESIZE; + s->s_flags |= MS_RDONLY; + s->s_op = &squashfs_super_ops; + + if (readahead_metadata(s) == 0) + goto failed_mount; + + /* Allocate read_page block */ + msblk->read_page = vmalloc(sblk->block_size); + if (msblk->read_page == NULL) { + ERROR("Failed to allocate read_page block\n"); + goto failed_mount; + } + + /* Allocate uid and gid tables */ + msblk->uid = kmalloc((sblk->no_uids + sblk->no_guids) * + sizeof(unsigned int), GFP_KERNEL); + if (msblk->uid == NULL) { + ERROR("Failed to allocate uid/gid table\n"); + goto failed_mount; + } + msblk->guid = msblk->uid + sblk->no_uids; + + if (msblk->swap) { + unsigned int suid[sblk->no_uids + sblk->no_guids]; + + if (!squashfs_read_data(s, (char *) &suid, sblk->uid_start, + ((sblk->no_uids + sblk->no_guids) * + sizeof(unsigned int)) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { + ERROR("unable to read uid/gid table\n"); + goto failed_mount; + } + + SQUASHFS_SWAP_DATA(msblk->uid, suid, (sblk->no_uids + + sblk->no_guids), (sizeof(unsigned int) * 8)); + } else + if (!squashfs_read_data(s, (char *) msblk->uid, sblk->uid_start, + ((sblk->no_uids + sblk->no_guids) * + sizeof(unsigned int)) | + SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, (sblk->no_uids + sblk->no_guids) * sizeof(unsigned int))) { + ERROR("unable to read uid/gid table\n"); + goto failed_mount; + } + + + if (sblk->s_major == 1 && squashfs_1_0_supported(msblk)) + goto allocate_root; + + msblk->fragment = kzalloc(sizeof(struct squashfs_fragment_cache) * + SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL); + if (msblk->fragment == NULL) { + ERROR("Failed to allocate fragment block cache\n"); + goto failed_mount; + } + + for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) { + msblk->fragment[i].block = SQUASHFS_INVALID_BLK; + } + + msblk->next_fragment = 0; + msblk->unused_frag_blks = SQUASHFS_CACHED_FRAGMENTS; + + /* Allocate and read fragment index table */ + if (msblk->read_fragment_index_table(s) == 0) + goto failed_mount; + + if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK) + goto allocate_root; + + /* Allocate and read inode lookup table */ + if (read_inode_lookup_table(s) == 0) + goto failed_mount; + + s->s_op = &squashfs_export_super_ops; +#ifdef USE_EXPORT + s->s_export_op = &squashfs_export_ops; +#endif + +allocate_root: + root = new_inode(s); + if ((msblk->read_inode)(root, sblk->root_inode) == 0) + goto failed_mount; + insert_inode_hash(root); + + s->s_root = d_alloc_root(root); + if (s->s_root == NULL) { + ERROR("Root inode create failed\n"); + iput(root); + goto failed_mount; + } + + TRACE("Leaving squashfs_fill_super\n"); + return 0; + +failed_mount: + kfree(msblk->inode_lookup_table); + kfree(msblk->fragment_index); + kfree(msblk->fragment); + kfree(msblk->uid); + vfree(msblk->read_page); + kfree(msblk->block_cache); + kfree(msblk->fragment_index_2); + vfree(msblk->stream.workspace); + kfree(s->s_fs_info); + s->s_fs_info = NULL; + return -EINVAL; + +failure: + return -ENOMEM; +} + + +static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + + TRACE("Entered squashfs_statfs\n"); + + buf->f_type = SQUASHFS_MAGIC; + buf->f_bsize = sblk->block_size; + buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1; + buf->f_bfree = buf->f_bavail = 0; + buf->f_files = sblk->inodes; + buf->f_ffree = 0; + buf->f_namelen = SQUASHFS_NAME_LEN; + + return 0; +} + + +static int squashfs_symlink_readpage(struct file *file, struct page *page) +{ + struct inode *inode = page->mapping->host; + int index = page->index << PAGE_CACHE_SHIFT, length, bytes, avail_bytes; + long long block = SQUASHFS_I(inode)->start_block; + int offset = SQUASHFS_I(inode)->offset; + void *pageaddr = kmap(page); + + TRACE("Entered squashfs_symlink_readpage, page index %ld, start block " + "%llx, offset %x\n", page->index, + SQUASHFS_I(inode)->start_block, + SQUASHFS_I(inode)->offset); + + for (length = 0; length < index; length += bytes) { + bytes = squashfs_get_cached_block(inode->i_sb, NULL, block, + offset, PAGE_CACHE_SIZE, &block, &offset); + if (bytes == 0) { + ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset); + goto skip_read; + } + } + + if (length != index) { + ERROR("(squashfs_symlink_readpage) length != index\n"); + bytes = 0; + goto skip_read; + } + + avail_bytes = min_t(int, i_size_read(inode) - length, PAGE_CACHE_SIZE); + + bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset, + avail_bytes, &block, &offset); + if (bytes == 0) + ERROR("Unable to read symbolic link [%llx:%x]\n", block, offset); + +skip_read: + memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); + kunmap(page); + flush_dcache_page(page); + SetPageUptodate(page); + unlock_page(page); + + return 0; +} + + +struct meta_index *locate_meta_index(struct inode *inode, int index, int offset) +{ + struct meta_index *meta = NULL; + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + int i; + + mutex_lock(&msblk->meta_index_mutex); + + TRACE("locate_meta_index: index %d, offset %d\n", index, offset); + + if (msblk->meta_index == NULL) + goto not_allocated; + + for (i = 0; i < SQUASHFS_META_NUMBER; i ++) { + if (msblk->meta_index[i].inode_number == inode->i_ino && + msblk->meta_index[i].offset >= offset && + msblk->meta_index[i].offset <= index && + msblk->meta_index[i].locked == 0) { + TRACE("locate_meta_index: entry %d, offset %d\n", i, + msblk->meta_index[i].offset); + meta = &msblk->meta_index[i]; + offset = meta->offset; + } + } + + if (meta) + meta->locked = 1; + +not_allocated: + mutex_unlock(&msblk->meta_index_mutex); + + return meta; +} + + +struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip) +{ + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + struct meta_index *meta = NULL; + int i; + + mutex_lock(&msblk->meta_index_mutex); + + TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip); + + if (msblk->meta_index == NULL) { + msblk->meta_index = kmalloc(sizeof(struct meta_index) * + SQUASHFS_META_NUMBER, GFP_KERNEL); + if (msblk->meta_index == NULL) { + ERROR("Failed to allocate meta_index\n"); + goto failed; + } + for (i = 0; i < SQUASHFS_META_NUMBER; i++) { + msblk->meta_index[i].inode_number = 0; + msblk->meta_index[i].locked = 0; + } + msblk->next_meta_index = 0; + } + + for (i = SQUASHFS_META_NUMBER; i && + msblk->meta_index[msblk->next_meta_index].locked; i --) + msblk->next_meta_index = (msblk->next_meta_index + 1) % + SQUASHFS_META_NUMBER; + + if (i == 0) { + TRACE("empty_meta_index: failed!\n"); + goto failed; + } + + TRACE("empty_meta_index: returned meta entry %d, %p\n", + msblk->next_meta_index, + &msblk->meta_index[msblk->next_meta_index]); + + meta = &msblk->meta_index[msblk->next_meta_index]; + msblk->next_meta_index = (msblk->next_meta_index + 1) % + SQUASHFS_META_NUMBER; + + meta->inode_number = inode->i_ino; + meta->offset = offset; + meta->skip = skip; + meta->entries = 0; + meta->locked = 1; + +failed: + mutex_unlock(&msblk->meta_index_mutex); + return meta; +} + + +void release_meta_index(struct inode *inode, struct meta_index *meta) +{ + meta->locked = 0; + smp_mb(); +} + + +static int read_block_index(struct super_block *s, int blocks, char *block_list, + long long *start_block, int *offset) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + unsigned int *block_listp; + int block = 0; + + if (msblk->swap) { + char sblock_list[blocks << 2]; + + if (!squashfs_get_cached_block(s, sblock_list, *start_block, + *offset, blocks << 2, start_block, offset)) { + ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); + goto failure; + } + SQUASHFS_SWAP_INTS(((unsigned int *)block_list), + ((unsigned int *)sblock_list), blocks); + } else { + if (!squashfs_get_cached_block(s, block_list, *start_block, + *offset, blocks << 2, start_block, offset)) { + ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset); + goto failure; + } + } + + for (block_listp = (unsigned int *) block_list; blocks; + block_listp++, blocks --) + block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); + + return block; + +failure: + return -1; +} + + +#define SIZE 256 + +static inline int calculate_skip(int blocks) { + int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES); + return skip >= 7 ? 7 : skip + 1; +} + + +static int get_meta_index(struct inode *inode, int index, + long long *index_block, int *index_offset, + long long *data_block, char *block_list) +{ + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int skip = calculate_skip(i_size_read(inode) >> sblk->block_log); + int offset = 0; + struct meta_index *meta; + struct meta_entry *meta_entry; + long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start; + int cur_offset = SQUASHFS_I(inode)->offset; + long long cur_data_block = SQUASHFS_I(inode)->start_block; + int i; + + index /= SQUASHFS_META_INDEXES * skip; + + while (offset < index) { + meta = locate_meta_index(inode, index, offset + 1); + + if (meta == NULL) { + meta = empty_meta_index(inode, offset + 1, skip); + if (meta == NULL) + goto all_done; + } else { + if(meta->entries == 0) + goto failed; + /* XXX */ + offset = index < meta->offset + meta->entries ? index : + meta->offset + meta->entries - 1; + /* XXX */ + meta_entry = &meta->meta_entry[offset - meta->offset]; + cur_index_block = meta_entry->index_block + sblk->inode_table_start; + cur_offset = meta_entry->offset; + cur_data_block = meta_entry->data_block; + TRACE("get_meta_index: offset %d, meta->offset %d, " + "meta->entries %d\n", offset, meta->offset, meta->entries); + TRACE("get_meta_index: index_block 0x%llx, offset 0x%x" + " data_block 0x%llx\n", cur_index_block, + cur_offset, cur_data_block); + } + + for (i = meta->offset + meta->entries; i <= index && + i < meta->offset + SQUASHFS_META_ENTRIES; i++) { + int blocks = skip * SQUASHFS_META_INDEXES; + + while (blocks) { + int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : blocks; + int res = read_block_index(inode->i_sb, block, block_list, + &cur_index_block, &cur_offset); + + if (res == -1) + goto failed; + + cur_data_block += res; + blocks -= block; + } + + meta_entry = &meta->meta_entry[i - meta->offset]; + meta_entry->index_block = cur_index_block - sblk->inode_table_start; + meta_entry->offset = cur_offset; + meta_entry->data_block = cur_data_block; + meta->entries ++; + offset ++; + } + + TRACE("get_meta_index: meta->offset %d, meta->entries %d\n", + meta->offset, meta->entries); + + release_meta_index(inode, meta); + } + +all_done: + *index_block = cur_index_block; + *index_offset = cur_offset; + *data_block = cur_data_block; + + return offset * SQUASHFS_META_INDEXES * skip; + +failed: + release_meta_index(inode, meta); + return -1; +} + + +static long long read_blocklist(struct inode *inode, int index, + int readahead_blks, char *block_list, + unsigned short **block_p, unsigned int *bsize) +{ + long long block_ptr; + int offset; + long long block; + int res = get_meta_index(inode, index, &block_ptr, &offset, &block, + block_list); + + TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset" + " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, block); + + if(res == -1) + goto failure; + + index -= res; + + while (index) { + int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index; + int res = read_block_index(inode->i_sb, blocks, block_list, + &block_ptr, &offset); + if (res == -1) + goto failure; + block += res; + index -= blocks; + } + + if (read_block_index(inode->i_sb, 1, block_list, &block_ptr, &offset) == -1) + goto failure; + *bsize = *((unsigned int *) block_list); + + return block; + +failure: + return 0; +} + + +static int squashfs_readpage(struct file *file, struct page *page) +{ + struct inode *inode = page->mapping->host; + struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + unsigned char *block_list = NULL; + long long block; + unsigned int bsize, i; + int bytes; + int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT); + void *pageaddr; + struct squashfs_fragment_cache *fragment = NULL; + char *data_ptr = msblk->read_page; + + int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1; + int start_index = page->index & ~mask; + int end_index = start_index | mask; + int file_end = i_size_read(inode) >> sblk->block_log; + int sparse = 0; + + TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n", + page->index, SQUASHFS_I(inode)->start_block); + + if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT)) + goto out; + + if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK + || index < file_end) { + block_list = kmalloc(SIZE, GFP_KERNEL); + if (block_list == NULL) { + ERROR("Failed to allocate block_list\n"); + goto error_out; + } + + block = (msblk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize); + if (block == 0) + goto error_out; + + if (bsize == 0) { /* hole */ + bytes = index == file_end ? + (i_size_read(inode) & (sblk->block_size - 1)) : sblk->block_size; + sparse = 1; + } else { + mutex_lock(&msblk->read_page_mutex); + + bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block, + bsize, NULL, sblk->block_size); + + if (bytes == 0) { + ERROR("Unable to read page, block %llx, size %x\n", block, bsize); + mutex_unlock(&msblk->read_page_mutex); + goto error_out; + } + } + } else { + fragment = get_cached_fragment(inode->i_sb, + SQUASHFS_I(inode)-> u.s1.fragment_start_block, + SQUASHFS_I(inode)->u.s1.fragment_size); + + if (fragment == NULL) { + ERROR("Unable to read page, block %llx, size %x\n", + SQUASHFS_I(inode)->u.s1.fragment_start_block, + (int) SQUASHFS_I(inode)->u.s1.fragment_size); + goto error_out; + } + bytes = i_size_read(inode) & (sblk->block_size - 1); + data_ptr = fragment->data + SQUASHFS_I(inode)->u.s1.fragment_offset; + } + + for (i = start_index; i <= end_index && bytes > 0; i++, + bytes -= PAGE_CACHE_SIZE, data_ptr += PAGE_CACHE_SIZE) { + struct page *push_page; + int avail = sparse ? 0 : min_t(unsigned int, bytes, PAGE_CACHE_SIZE); + + TRACE("bytes %d, i %d, available_bytes %d\n", bytes, i, avail); + + push_page = (i == page->index) ? page : + grab_cache_page_nowait(page->mapping, i); + + if (!push_page) + continue; + + if (PageUptodate(push_page)) + goto skip_page; + + pageaddr = kmap_atomic(push_page, KM_USER0); + memcpy(pageaddr, data_ptr, avail); + memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail); + kunmap_atomic(pageaddr, KM_USER0); + flush_dcache_page(push_page); + SetPageUptodate(push_page); +skip_page: + unlock_page(push_page); + if(i != page->index) + page_cache_release(push_page); + } + + if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK + || index < file_end) { + if (!sparse) + mutex_unlock(&msblk->read_page_mutex); + kfree(block_list); + } else + release_cached_fragment(msblk, fragment); + + return 0; + +error_out: + SetPageError(page); +out: + pageaddr = kmap_atomic(page, KM_USER0); + memset(pageaddr, 0, PAGE_CACHE_SIZE); + kunmap_atomic(pageaddr, KM_USER0); + flush_dcache_page(page); + if (!PageError(page)) + SetPageUptodate(page); + unlock_page(page); + + kfree(block_list); + return 0; +} + + +static int get_dir_index_using_offset(struct super_block *s, + long long *next_block, unsigned int *next_offset, + long long index_start, unsigned int index_offset, int i_count, + long long f_pos) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index index; + + TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n", + i_count, (unsigned int) f_pos); + + f_pos =- 3; + if (f_pos == 0) + goto finish; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index sindex; + squashfs_get_cached_block(s, &sindex, index_start, index_offset, + sizeof(sindex), &index_start, &index_offset); + SQUASHFS_SWAP_DIR_INDEX(&index, &sindex); + } else + squashfs_get_cached_block(s, &index, index_start, index_offset, + sizeof(index), &index_start, &index_offset); + + if (index.index > f_pos) + break; + + squashfs_get_cached_block(s, NULL, index_start, index_offset, + index.size + 1, &index_start, &index_offset); + + length = index.index; + *next_block = index.start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + +finish: + return length + 3; +} + + +static int get_dir_index_using_name(struct super_block *s, + long long *next_block, unsigned int *next_offset, + long long index_start, unsigned int index_offset, int i_count, + const char *name, int size) +{ + struct squashfs_sb_info *msblk = s->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + int i, length = 0; + struct squashfs_dir_index *index; + char *str; + + TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); + + str = kmalloc(sizeof(struct squashfs_dir_index) + + (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL); + if (str == NULL) { + ERROR("Failed to allocate squashfs_dir_index\n"); + goto failure; + } + + index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1); + strncpy(str, name, size); + str[size] = '\0'; + + for (i = 0; i < i_count; i++) { + if (msblk->swap) { + struct squashfs_dir_index sindex; + squashfs_get_cached_block(s, &sindex, index_start, index_offset, + sizeof(sindex), &index_start, &index_offset); + SQUASHFS_SWAP_DIR_INDEX(index, &sindex); + } else + squashfs_get_cached_block(s, index, index_start, index_offset, + sizeof(struct squashfs_dir_index), &index_start, &index_offset); + + squashfs_get_cached_block(s, index->name, index_start, index_offset, + index->size + 1, &index_start, &index_offset); + + index->name[index->size + 1] = '\0'; + + if (strcmp(index->name, str) > 0) + break; + + length = index->index; + *next_block = index->start_block + sblk->directory_table_start; + } + + *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + kfree(str); + +failure: + return length + 3; +} + + +static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + struct inode *i = file->f_dentry->d_inode; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; + struct squashfs_dir_header dirh; + struct squashfs_dir_entry *dire; + + TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset); + + dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); + if (dire == NULL) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto finish; + } + + while(file->f_pos < 3) { + char *name; + int size, i_ino; + + if(file->f_pos == 0) { + name = "."; + size = 1; + i_ino = i->i_ino; + } else { + name = ".."; + size = 2; + i_ino = SQUASHFS_I(i)->u.s2.parent_inode; + } + TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n", + (unsigned int) dirent, name, size, (int) + file->f_pos, i_ino, squashfs_filetype_table[1]); + + if (filldir(dirent, name, size, file->f_pos, i_ino, + squashfs_filetype_table[1]) < 0) { + TRACE("Filldir returned less than 0\n"); + goto finish; + } + file->f_pos += size; + } + + length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, file->f_pos); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header sdirh; + + if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block, + next_offset, sizeof(sdirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block, + next_offset, sizeof(dirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry sdire; + if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block, + next_offset, sizeof(sdire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, dire, next_block, + next_offset, sizeof(*dire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block, + next_offset, dire->size + 1, &next_block, &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (file->f_pos >= length) + continue; + + dire->name[dire->size + 1] = '\0'; + + TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n", + (unsigned int) dirent, dire->name, dire->size + 1, + (int) file->f_pos, dirh.start_block, dire->offset, + dirh.inode_number + dire->inode_number, + squashfs_filetype_table[dire->type]); + + if (filldir(dirent, dire->name, dire->size + 1, file->f_pos, + dirh.inode_number + dire->inode_number, + squashfs_filetype_table[dire->type]) < 0) { + TRACE("Filldir returned less than 0\n"); + goto finish; + } + file->f_pos = length; + } + } + +finish: + kfree(dire); + return 0; + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + kfree(dire); + return 0; +} + + +static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry, + struct nameidata *nd) +{ + const unsigned char *name = dentry->d_name.name; + int len = dentry->d_name.len; + struct inode *inode = NULL; + struct squashfs_sb_info *msblk = i->i_sb->s_fs_info; + struct squashfs_super_block *sblk = &msblk->sblk; + long long next_block = SQUASHFS_I(i)->start_block + + sblk->directory_table_start; + int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count; + struct squashfs_dir_header dirh; + struct squashfs_dir_entry *dire; + + TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset); + + dire = kmalloc(sizeof(struct squashfs_dir_entry) + + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); + if (dire == NULL) { + ERROR("Failed to allocate squashfs_dir_entry\n"); + goto exit_lookup; + } + + if (len > SQUASHFS_NAME_LEN) + goto exit_lookup; + + length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset, + SQUASHFS_I(i)->u.s2.directory_index_start, + SQUASHFS_I(i)->u.s2.directory_index_offset, + SQUASHFS_I(i)->u.s2.directory_index_count, name, len); + + while (length < i_size_read(i)) { + /* read directory header */ + if (msblk->swap) { + struct squashfs_dir_header sdirh; + if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block, + next_offset, sizeof(sdirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdirh); + SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); + } else { + if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block, + next_offset, sizeof(dirh), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(dirh); + } + + dir_count = dirh.count + 1; + while (dir_count--) { + if (msblk->swap) { + struct squashfs_dir_entry sdire; + if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block, + next_offset, sizeof(sdire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(sdire); + SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); + } else { + if (!squashfs_get_cached_block(i->i_sb, dire, next_block, + next_offset, sizeof(*dire), &next_block, &next_offset)) + goto failed_read; + + length += sizeof(*dire); + } + + if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block, + next_offset, dire->size + 1, &next_block, &next_offset)) + goto failed_read; + + length += dire->size + 1; + + if (name[0] < dire->name[0]) + goto exit_lookup; + + if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) { + squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block, + dire->offset); + + TRACE("calling squashfs_iget for directory entry %s, inode" + " %x:%x, %d\n", name, dirh.start_block, dire->offset, + dirh.inode_number + dire->inode_number); + + inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number); + + goto exit_lookup; + } + } + } + +exit_lookup: + kfree(dire); + if (inode) + return d_splice_alias(inode, dentry); + d_add(dentry, inode); + return ERR_PTR(0); + +failed_read: + ERROR("Unable to read directory block [%llx:%x]\n", next_block, + next_offset); + goto exit_lookup; +} + + +static int squashfs_remount(struct super_block *s, int *flags, char *data) +{ + *flags |= MS_RDONLY; + return 0; +} + + +static void squashfs_put_super(struct super_block *s) +{ + int i; + + if (s->s_fs_info) { + struct squashfs_sb_info *sbi = s->s_fs_info; + if (sbi->block_cache) + for (i = 0; i < squashfs_cached_blks; i++) + if (sbi->block_cache[i].block != SQUASHFS_INVALID_BLK) + vfree(sbi->block_cache[i].data); + if (sbi->fragment) + for (i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) + vfree(sbi->fragment[i].data); + kfree(sbi->fragment); + kfree(sbi->block_cache); + vfree(sbi->read_page); + kfree(sbi->uid); + kfree(sbi->fragment_index); + kfree(sbi->fragment_index_2); + kfree(sbi->meta_index); + vfree(sbi->stream.workspace); + kfree(s->s_fs_info); + s->s_fs_info = NULL; + } +} + + +static int squashfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super, + mnt); +} + + +static int __init init_squashfs_fs(void) +{ + int err = init_inodecache(); + if (err) + goto out; + + printk(KERN_INFO "squashfs: version 3.3 (2007/10/31) " + "Phillip Lougher\n"); + + err = register_filesystem(&squashfs_fs_type); + if (err) + destroy_inodecache(); + +out: + return err; +} + + +static void __exit exit_squashfs_fs(void) +{ + unregister_filesystem(&squashfs_fs_type); + destroy_inodecache(); +} + + +static struct kmem_cache * squashfs_inode_cachep; + + +static struct inode *squashfs_alloc_inode(struct super_block *sb) +{ + struct squashfs_inode_info *ei; + ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL); + return ei ? &ei->vfs_inode : NULL; +} + + +static void squashfs_destroy_inode(struct inode *inode) +{ + kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode)); +} + + +static void init_once(void *foo) +{ + struct squashfs_inode_info *ei = foo; + + inode_init_once(&ei->vfs_inode); +} + + +static int __init init_inodecache(void) +{ + squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache", + sizeof(struct squashfs_inode_info), 0, + SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once); + if (squashfs_inode_cachep == NULL) + return -ENOMEM; + return 0; +} + + +static void destroy_inodecache(void) +{ + kmem_cache_destroy(squashfs_inode_cachep); +} + + +module_init(init_squashfs_fs); +module_exit(exit_squashfs_fs); +MODULE_DESCRIPTION("squashfs 3.2-r2-CVS, a compressed read-only filesystem"); +MODULE_AUTHOR("Phillip Lougher "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/squashfs/BOM +++ linux-2.6.28/ubuntu/squashfs/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=63835 +Current Version: 3.3 --- linux-2.6.28.orig/ubuntu/et131x/et131x_version.h +++ linux-2.6.28/ubuntu/et131x/et131x_version.h @@ -0,0 +1,124 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_version.h - This file provides system and device version information. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/31 20:58:43 $ + $Revision: 1.16 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_VERSION_H__ +#define __ET131X_VERSION_H__ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include +#include + + + + +/****************************************************************************** + Constant Definitions + *****************************************************************************/ +#define DRIVER_AUTHOR "Victor Soriano (vjsoriano@agere.com)" +#define DRIVER_LICENSE "BSD" +#define DRIVER_DEVICE_STRING "ET1310" +#define DRIVER_NAME "et131x" +#define DRIVER_MAJOR_VERSION 1 +#define DRIVER_MINOR_VERSION 2 +#define DRIVER_PATCH_VERSION 3 +#define DRIVER_VERSION_STRING "1.2.3" +#define DRIVER_VENDOR "Agere Systems, http://www.agere.com" +#define DRIVER_BUILD_DATE "01/31/2006 15:40:00" +#define DRIVER_DESC "10/100/1000 Base-T Ethernet Driver" + +#define STRUCT_MODULE "net" // blux: missed by the kernel + +#define DRIVER_INFO DRIVER_DESC " for the "\ + DRIVER_DEVICE_STRING ", v" \ + DRIVER_VERSION_STRING " " \ + DRIVER_BUILD_DATE " by " \ + DRIVER_VENDOR + + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#define DRIVER_NAME_EXT "et131x.o" +#else +#define DRIVER_NAME_EXT "et131x.ko" +#endif + + + + +#endif /* __ET131X_VERSION_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_address_map.h +++ linux-2.6.28/ubuntu/et131x/ET1310_address_map.h @@ -0,0 +1,3216 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_address_map.h - Contains the register mapping for the ET1310 + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:43 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_ADDRESS_MAP_H_ +#define _ET1310_ADDRESS_MAP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + some typedefs for compiler + *****************************************************************************/ +typedef s8 INT8, *PINT8; +typedef s16 INT16, *PINT16; +typedef s32 INT32, *PINT32; +typedef s64 INT64, *PINT64; + +typedef u8 UINT8, *PUINT8; +typedef u16 UINT16, *PUINT16; +typedef u32 UINT32, *PUINT32; +typedef u64 UINT64, *PUINT64; + +typedef u8 UCHAR, *PUCHAR; + + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF GLOBAL REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for tx queue start address reg in global address map + located at address 0x0000 + *****************************************************************************/ +typedef union _TXQ_START_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 txq_start:10; //bits 0-9 + #else + UINT32 txq_start:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +TXQ_START_ADDR_t, *PTXQ_START_ADDR_t; + + +/****************************************************************************** + structure for tx queue end address reg in global address map + located at address 0x0004 + *****************************************************************************/ +typedef union _TXQ_END_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 txq_end:10; //bits 0-9 + #else + UINT32 txq_end:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +TXQ_END_ADDR_t, *PTXQ_END_ADDR_t; + + +/****************************************************************************** + structure for rx queue start address reg in global address map + located at address 0x0008 + *****************************************************************************/ +typedef union _RXQ_START_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 rxq_start_addr:10; //bits 0-9 + #else + UINT32 rxq_start_addr:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXQ_START_ADDR_t, *PRXQ_START_ADDR_t; + + +/****************************************************************************** + structure for rx queue end address reg in global address map + located at address 0x000C + *****************************************************************************/ +typedef union _RXQ_END_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 rxq_end_addr:10; //bits 0-9 + #else + UINT32 rxq_end_addr:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXQ_END_ADDR_t, *PRXQ_END_ADDR_t; + + +/****************************************************************************** + structure for power management control status reg in global address map + located at address 0x0010 + *****************************************************************************/ +typedef union _PM_CSR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 pm_jagcore_rx_rdy:1; //bit 9 + UINT32 pm_jagcore_tx_rdy:1; //bit 8 + UINT32 pm_phy_lped_en:1; //bit 7 + UINT32 pm_phy_sw_coma:1; //bit 6 + UINT32 pm_rxclk_gate:1; //bit 5 + UINT32 pm_txclk_gate:1; //bit 4 + UINT32 pm_sysclk_gate:1; //bit 3 + UINT32 pm_jagcore_rx_en:1; //bit 2 + UINT32 pm_jagcore_tx_en:1; //bit 1 + UINT32 pm_gigephy_en:1; //bit 0 + #else + UINT32 pm_gigephy_en:1; //bit 0 + UINT32 pm_jagcore_tx_en:1; //bit 1 + UINT32 pm_jagcore_rx_en:1; //bit 2 + UINT32 pm_sysclk_gate:1; //bit 3 + UINT32 pm_txclk_gate:1; //bit 4 + UINT32 pm_rxclk_gate:1; //bit 5 + UINT32 pm_phy_sw_coma:1; //bit 6 + UINT32 pm_phy_lped_en:1; //bit 7 + UINT32 pm_jagcore_tx_rdy:1; //bit 8 + UINT32 pm_jagcore_rx_rdy:1; //bit 9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +PM_CSR_t, *PPM_CSR_t; + + +/****************************************************************************** + structure for interrupt status reg in global address map + located at address 0x0018 + *****************************************************************************/ +typedef union _INT_STATUS_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 unused4:4; //bits 10-13 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:4; //bits 10-13 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_STATUS_t, *PINT_STATUS_t; + + +/****************************************************************************** + structure for interrupt mask reg in global address map + located at address 0x001C + *****************************************************************************/ +typedef union _INT_MASK_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 unused4:5; //bits 10-14 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:5; //bits 10-14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_MASK_t, *PINT_MASK_t; + + +/****************************************************************************** + structure for interrupt alias clear mask reg in global address map + located at address 0x0020 + *****************************************************************************/ +typedef union _INT_ALIAS_CLR_EN_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 unused4:4; //bits 10-13 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:4; //bits 10-13 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_ALIAS_CLR_EN_t, *PINT_ALIAS_CLR_EN_t; + + +/****************************************************************************** + structure for interrupt status alias reg in global address map + located at address 0x0024 + *****************************************************************************/ +typedef union _INT_STATUS_ALIAS_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused5:11; //bits 21-31 + UINT32 slv_timeout:1; //bit 20 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 phy_interrupt:1; //bit 16 + UINT32 wake_on_lan:1; //bit 15 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 unused4:4; //bits 10-13 + UINT32 rxdma_err:1; //bit 9 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 txdma_err:1; //bit 4 + UINT32 txdma_isr:1; //bit 3 + UINT32 unused3:1; //bit 2 + UINT32 unused2:1; //bit 1 + UINT32 unused1:1; //bit 0 + #else + UINT32 unused1:1; //bit 0 + UINT32 unused2:1; //bit 1 + UINT32 unused3:1; //bit 2 + UINT32 txdma_isr:1; //bit 3 + UINT32 txdma_err:1; //bit 4 + UINT32 rxdma_xfr_done:1; //bit 5 + UINT32 rxdma_fb_ring0_low:1; //bit 6 + UINT32 rxdma_fb_ring1_low:1; //bit 7 + UINT32 rxdma_pkt_stat_ring_low:1; //bit 8 + UINT32 rxdma_err:1; //bit 9 + UINT32 unused4:4; //bits 10-13 + UINT32 watchdog_interrupt:1; //bit 14 + UINT32 wake_on_lan:1; //bit 15 + UINT32 phy_interrupt:1; //bit 16 + UINT32 txmac_interrupt:1; //bit 17 + UINT32 rxmac_interrupt:1; //bit 18 + UINT32 mac_stat_interrupt:1; //bit 19 + UINT32 slv_timeout:1; //bit 20 + UINT32 unused5:11; //bits 21-31 + #endif + } bits; +} +INT_STATUS_ALIAS_t, *PINT_STATUS_ALIAS_t; + + +/****************************************************************************** + structure for software reset reg in global address map + located at address 0x0028 + *****************************************************************************/ +typedef union _SW_RESET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 selfclr_disable:1; //bit 31 + UINT32 unused:24; //bits 7-30 + UINT32 mmc_sw_reset:1; //bit 6 + UINT32 mac_stat_sw_reset:1; //bit 5 + UINT32 mac_sw_reset:1; //bit 4 + UINT32 rxmac_sw_reset:1; //bit 3 + UINT32 txmac_sw_reset:1; //bit 2 + UINT32 rxdma_sw_reset:1; //bit 1 + UINT32 txdma_sw_reset:1; //bit 0 + #else + UINT32 txdma_sw_reset:1; //bit 0 + UINT32 rxdma_sw_reset:1; //bit 1 + UINT32 txmac_sw_reset:1; //bit 2 + UINT32 rxmac_sw_reset:1; //bit 3 + UINT32 mac_sw_reset:1; //bit 4 + UINT32 mac_stat_sw_reset:1; //bit 5 + UINT32 mmc_sw_reset:1; //bit 6 + UINT32 unused:24; //bits 7-30 + UINT32 selfclr_disable:1; //bit 31 + #endif + } bits; +} +SW_RESET_t, *PSW_RESET_t; + + +/****************************************************************************** + structure for SLV Timer reg in global address map + located at address 0x002C + *****************************************************************************/ +typedef union _SLV_TIMER_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:8; //bits 24-31 + UINT32 timer_ini:24; //bits 0-23 + #else + UINT32 timer_ini:24; //bits 0-23 + UINT32 unused:8; //bits 24-31 + #endif + } bits; +} +SLV_TIMER_t, *PSLV_TIMER_t; + + +/****************************************************************************** + structure for MSI Configuration reg in global address map + located at address 0x0030 + *****************************************************************************/ +typedef union _MSI_CONFIG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused1:13; //bits 19-31 + UINT32 msi_tc:3; //bits 16-18 + UINT32 unused2:11; //bits 5-15 + UINT32 msi_vector:5; //bits 0-4 + #else + UINT32 msi_vector:5; //bits 0-4 + UINT32 unused2:11; //bits 5-15 + UINT32 msi_tc:3; //bits 16-18 + UINT32 unused1:13; //bits 19-31 + #endif + } bits; +} +MSI_CONFIG_t, *PMSI_CONFIG_t; + + +/****************************************************************************** + structure for Loopback reg in global address map + located at address 0x0034 + *****************************************************************************/ +typedef union _LOOPBACK_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:30; //bits 2-31 + UINT32 dma_loopback:1; //bit 1 + UINT32 mac_loopback:1; //bit 0 + #else + UINT32 mac_loopback:1; //bit 0 + UINT32 dma_loopback:1; //bit 1 + UINT32 unused:30; //bits 2-31 + #endif + } bits; +} +LOOPBACK_t, *PLOOPBACK_t; + + +/****************************************************************************** + GLOBAL Module of JAGCore Address Mapping + Located at address 0x0000 + *****************************************************************************/ +typedef struct _GLOBAL_t +{ //Location: + TXQ_START_ADDR_t txq_start_addr; // 0x0000 + TXQ_END_ADDR_t txq_end_addr; // 0x0004 + RXQ_START_ADDR_t rxq_start_addr; // 0x0008 + RXQ_END_ADDR_t rxq_end_addr; // 0x000C + PM_CSR_t pm_csr; // 0x0010 + UINT32 unused; // 0x0014 + INT_STATUS_t int_status; // 0x0018 + INT_MASK_t int_mask; // 0x001C + INT_ALIAS_CLR_EN_t int_alias_clr_en; // 0x0020 + INT_STATUS_ALIAS_t int_status_alias; // 0x0024 + SW_RESET_t sw_reset; // 0x0028 + SLV_TIMER_t slv_timer; // 0x002C + MSI_CONFIG_t msi_config; // 0x0030 + LOOPBACK_t loopback; // 0x0034 + UINT32 watchdog_timer; // 0x0038 +} +GLOBAL_t, *PGLOBAL_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF GLOBAL REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF TXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for txdma control status reg in txdma address map + located at address 0x1000 + *****************************************************************************/ +typedef union _TXDMA_CSR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:19; //bits 13-31 + UINT32 traffic_class:4; //bits 9-12 + UINT32 sngl_epkt_mode:1; //bit 8 + UINT32 cache_thrshld:4; //bits 4-7 + UINT32 unused1:2; //bits 2-3 + UINT32 drop_TLP_disable:1; //bit 1 + UINT32 halt:1; //bit 0 + #else + UINT32 halt:1; //bit 0 + UINT32 drop_TLP_disable:1; //bit 1 + UINT32 unused1:2; //bits 2-3 + UINT32 cache_thrshld:4; //bits 4-7 + UINT32 sngl_epkt_mode:1; //bit 8 + UINT32 traffic_class:4; //bits 9-12 + UINT32 unused2:19; //bits 13-31 + #endif + } bits; +} +TXDMA_CSR_t, *PTXDMA_CSR_t; + + +/****************************************************************************** + structure for txdma packet ring base address hi reg in txdma address map + located at address 0x1004 + *****************************************************************************/ +typedef struct _TXDMA_PR_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +TXDMA_PR_BASE_HI_t, *PTXDMA_PR_BASE_HI_t; + + +/****************************************************************************** + structure for txdma packet ring base address low reg in txdma address map + located at address 0x1008 + *****************************************************************************/ +typedef struct _TXDMA_PR_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +TXDMA_PR_BASE_LO_t, *PTXDMA_PR_BASE_LO_t; + + +/****************************************************************************** + structure for txdma packet ring number of descriptor reg in txdma address + map. Located at address 0x100C + *****************************************************************************/ +typedef union _TXDMA_PR_NUM_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 pr_ndes:10; //bits 0-9 + #else + UINT32 pr_ndes:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +TXDMA_PR_NUM_DES_t, *PTXDMA_PR_NUM_DES_t; + + +/****************************************************************************** + structure for txdma tx queue write address reg in txdma address map + located at address 0x1010 + *****************************************************************************/ +typedef union _TXDMA_TXQ_WR_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 txq_wr_wrap:1; //bit 10 + UINT32 txq_wr:10; //bits 0-9 + #else + UINT32 txq_wr:10; //bits 0-9 + UINT32 txq_wr_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_TXQ_WR_ADDR_t, *PTXDMA_TXQ_WR_ADDR_t; + + +/****************************************************************************** + structure for txdma tx queue write address external reg in txdma address map + located at address 0x1014 + *****************************************************************************/ +typedef union _TXDMA_TXQ_WR_ADDR_EXT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 txq_wr_ext_wrap:1; //bit 10 + UINT32 txq_wr_ext:10; //bits 0-9 + #else + UINT32 txq_wr_ext:10; //bits 0-9 + UINT32 txq_wr_ext_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_TXQ_WR_ADDR_EXT_t, *PTXDMA_TXQ_WR_ADDR_EXT_t; + + +/****************************************************************************** + structure for txdma tx queue read address reg in txdma address map + located at address 0x1018 + *****************************************************************************/ +typedef union _TXDMA_TXQ_RD_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 txq_rd_wrap:1; //bit 10 + UINT32 txq_rd:10; //bits 0-9 + #else + UINT32 txq_rd:10; //bits 0-9 + UINT32 txq_rd_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_TXQ_RD_ADDR_t, *PTXDMA_TXQ_RD_ADDR_t; + + +/****************************************************************************** + structure for txdma status writeback address hi reg in txdma address map + located at address 0x101C + *****************************************************************************/ +typedef struct _TXDMA_DMA_WB_ADDR_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +TXDMA_DMA_WB_ADDR_HI_t, *PTXDMA_DMA_WB_ADDR_HI_t; + + +/****************************************************************************** + structure for txdma status writeback address lo reg in txdma address map + located at address 0x1020 + *****************************************************************************/ +typedef struct _TXDMA_DMA_WB_ADDR_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +TXDMA_DMA_WB_ADDR_LO_t, *PTXDMA_DMA_WB_ADDR_LO_t; + + +/****************************************************************************** + structure for txdma service request reg in txdma address map + located at address 0x1024 + *****************************************************************************/ +typedef union _TXDMA_SERVICE_REQUEST_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 serv_req_wrap:1; //bit 10 + UINT32 serv_req:10; //bits 0-9 + #else + UINT32 serv_req:10; //bits 0-9 + UINT32 serv_req_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_SERVICE_REQUEST_t, *PTXDMA_SERVICE_REQUEST_t; + + +/****************************************************************************** + structure for txdma service complete reg in txdma address map + located at address 0x1028 + *****************************************************************************/ +typedef union _TXDMA_SERVICE_COMPLETE_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 serv_cpl:10; //bits 0-9 + #else + UINT32 serv_cpl:10; //bits 0-9 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TXDMA_SERVICE_COMPLETE_t, *PTXDMA_SERVICE_COMPLETE_t; + + +/****************************************************************************** + structure for txdma tx descriptor cache read index reg in txdma address map + located at address 0x102C + *****************************************************************************/ +typedef union _TXDMA_CACHE_RD_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 rdi_wrap:1; //bit 4 + UINT32 rdi:4; //bit 0-3 + #else + UINT32 rdi:4; //bits 0-3 + UINT32 rdi_wrap:1; //bit 4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +TXDMA_CACHE_RD_INDEX_t, *PTXDMA_CACHE_RD_INDEX_t; + + +/****************************************************************************** + structure for txdma tx descriptor cache write index reg in txdma address map + located at address 0x1030 + *****************************************************************************/ +typedef union _TXDMA_CACHE_WR_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 wri_wrap:1; //bit 4 + UINT32 wri:4; //bit 0-3 + #else + UINT32 wri:4; //bits 0-3 + UINT32 wri_wrap:1; //bit 4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +TXDMA_CACHE_WR_INDEX_t, *PTXDMA_CACHE_WR_INDEX_t; + + +/****************************************************************************** + structure for txdma error reg in txdma address map + located at address 0x1034 + *****************************************************************************/ +typedef union _TXDMA_ERROR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused3:22; //bits 10-31 + UINT32 WrbkRewind:1; //bit 9 + UINT32 WrbkResend:1; //bit 8 + UINT32 unused2:2; //bits 6-7 + UINT32 DescrRewind:1; //bit 5 + UINT32 DescrResend:1; //bit 4 + UINT32 unused1:2; //bits 2-3 + UINT32 PyldRewind:1; //bit 1 + UINT32 PyldResend:1; //bit 0 + #else + UINT32 PyldResend:1; //bit 0 + UINT32 PyldRewind:1; //bit 1 + UINT32 unused1:2; //bits 2-3 + UINT32 DescrResend:1; //bit 4 + UINT32 DescrRewind:1; //bit 5 + UINT32 unused2:2; //bits 6-7 + UINT32 WrbkResend:1; //bit 8 + UINT32 WrbkRewind:1; //bit 9 + UINT32 unused3:22; //bits 10-31 + #endif + } bits; +} +TXDMA_ERROR_t, *PTXDMA_ERROR_t; + + +/****************************************************************************** + Tx DMA Module of JAGCore Address Mapping + Located at address 0x1000 + *****************************************************************************/ +typedef struct _TXDMA_t +{ //Location: + TXDMA_CSR_t csr; // 0x1000 + TXDMA_PR_BASE_HI_t pr_base_hi; // 0x1004 + TXDMA_PR_BASE_LO_t pr_base_lo; // 0x1008 + TXDMA_PR_NUM_DES_t pr_num_des; // 0x100C + TXDMA_TXQ_WR_ADDR_t txq_wr_addr; // 0x1010 + TXDMA_TXQ_WR_ADDR_EXT_t txq_wr_addr_ext; // 0x1014 + TXDMA_TXQ_RD_ADDR_t txq_rd_addr; // 0x1018 + TXDMA_DMA_WB_ADDR_HI_t dma_wb_base_hi; // 0x101C + TXDMA_DMA_WB_ADDR_LO_t dma_wb_base_lo; // 0x1020 + TXDMA_SERVICE_REQUEST_t service_request; // 0x1024 + TXDMA_SERVICE_COMPLETE_t service_complete; // 0x1028 + TXDMA_CACHE_RD_INDEX_t cache_rd_index; // 0x102C + TXDMA_CACHE_WR_INDEX_t cache_wr_index; // 0x1030 + TXDMA_ERROR_t TxDmaError; // 0x1034 + UINT32 DescAbortCount; // 0x1038 + UINT32 PayloadAbortCnt; // 0x103c + UINT32 WriteBackAbortCnt; // 0x1040 + UINT32 DescTimeoutCnt; // 0x1044 + UINT32 PayloadTimeoutCnt; // 0x1048 + UINT32 WriteBackTimeoutCnt;// 0x104c + UINT32 DescErrorCount; // 0x1050 + UINT32 PayloadErrorCnt; // 0x1054 + UINT32 WriteBackErrorCnt; // 0x1058 + UINT32 DroppedTLPCount; // 0x105c + TXDMA_SERVICE_COMPLETE_t NewServiceComplete; // 0x1060 + UINT32 EthernetPacketCount;// 0x1064 +} +TXDMA_t, *PTXDMA_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF TXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF RXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for control status reg in rxdma address map + Located at address 0x2000 + *****************************************************************************/ +typedef union _RXDMA_CSR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:14; //bits 18-31 + UINT32 halt_status:1; //bit 17 + UINT32 pkt_done_flush:1; //bit 16 + UINT32 pkt_drop_disable:1; //bit 15 + UINT32 unused1:1; //bit 14 + UINT32 fbr1_enable:1; //bit 13 + UINT32 fbr1_size:2; //bits 11-12 + UINT32 fbr0_enable:1; //bit 10 + UINT32 fbr0_size:2; //bits 8-9 + UINT32 dma_big_endian:1; //bit 7 + UINT32 pkt_big_endian:1; //bit 6 + UINT32 psr_big_endian:1; //bit 5 + UINT32 fbr_big_endian:1; //bit 4 + UINT32 tc:3; //bits 1-3 + UINT32 halt:1; //bit 0 + #else + UINT32 halt:1; //bit 0 + UINT32 tc:3; //bits 1-3 + UINT32 fbr_big_endian:1; //bit 4 + UINT32 psr_big_endian:1; //bit 5 + UINT32 pkt_big_endian:1; //bit 6 + UINT32 dma_big_endian:1; //bit 7 + UINT32 fbr0_size:2; //bits 8-9 + UINT32 fbr0_enable:1; //bit 10 + UINT32 fbr1_size:2; //bits 11-12 + UINT32 fbr1_enable:1; //bit 13 + UINT32 unused1:1; //bit 14 + UINT32 pkt_drop_disable:1; //bit 15 + UINT32 pkt_done_flush:1; //bit 16 + UINT32 halt_status:1; //bit 17 + UINT32 unused2:14; //bits 18-31 + #endif + } bits; +} +RXDMA_CSR_t, *PRXDMA_CSR_t; + + +/****************************************************************************** + structure for dma writeback lo reg in rxdma address map + located at address 0x2004 + *****************************************************************************/ +typedef struct _RXDMA_DMA_WB_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +RXDMA_DMA_WB_BASE_LO_t, *PRXDMA_DMA_WB_BASE_LO_t; + + +/****************************************************************************** + structure for dma writeback hi reg in rxdma address map + located at address 0x2008 + *****************************************************************************/ +typedef struct _RXDMA_DMA_WB_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +RXDMA_DMA_WB_BASE_HI_t, *PRXDMA_DMA_WB_BASE_HI_t; + + +/****************************************************************************** + structure for number of packets done reg in rxdma address map + located at address 0x200C + *****************************************************************************/ +typedef union _RXDMA_NUM_PKT_DONE_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:24; //bits 8-31 + UINT32 num_done:8; //bits 0-7 + #else + UINT32 num_done:8; //bits 0-7 + UINT32 unused:24; //bits 8-31 + #endif + } bits; +} +RXDMA_NUM_PKT_DONE_t, *PRXDMA_NUM_PKT_DONE_t; + + +/****************************************************************************** + structure for max packet time reg in rxdma address map + located at address 0x2010 + *****************************************************************************/ +typedef union _RXDMA_MAX_PKT_TIME_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:14; //bits 18-31 + UINT32 time_done:18; //bits 0-17 + #else + UINT32 time_done:18; //bits 0-17 + UINT32 unused:14; //bits 18-31 + #endif + } bits; +} +RXDMA_MAX_PKT_TIME_t, *PRXDMA_MAX_PKT_TIME_t; + + +/****************************************************************************** + structure for rx queue read address reg in rxdma address map + located at address 0x2014 + *****************************************************************************/ +typedef union _RXDMA_RXQ_RD_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 rxq_rd_wrap:1; //bit 10 + UINT32 rxq_rd:10; //bits 0-9 + #else + UINT32 rxq_rd:10; //bits 0-9 + UINT32 rxq_rd_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_RXQ_RD_ADDR_t, *PRXDMA_RXQ_RD_ADDR_t; + + +/****************************************************************************** + structure for rx queue read address external reg in rxdma address map + located at address 0x2018 + *****************************************************************************/ +typedef union _RXDMA_RXQ_RD_ADDR_EXT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 rxq_rd_ext_wrap:1; //bit 10 + UINT32 rxq_rd_ext:10; //bits 0-9 + #else + UINT32 rxq_rd_ext:10; //bits 0-9 + UINT32 rxq_rd_ext_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_RXQ_RD_ADDR_EXT_t, *PRXDMA_RXQ_RD_ADDR_EXT_t; + + +/****************************************************************************** + structure for rx queue write address reg in rxdma address map + located at address 0x201C + *****************************************************************************/ +typedef union _RXDMA_RXQ_WR_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 rxq_wr_wrap:1; //bit 10 + UINT32 rxq_wr:10; //bits 0-9 + #else + UINT32 rxq_wr:10; //bits 0-9 + UINT32 rxq_wr_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_RXQ_WR_ADDR_t, *PRXDMA_RXQ_WR_ADDR_t; + + +/****************************************************************************** + structure for packet status ring base address lo reg in rxdma address map + located at address 0x2020 + *****************************************************************************/ +typedef struct _RXDMA_PSR_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +RXDMA_PSR_BASE_LO_t, *PRXDMA_PSR_BASE_LO_t; + + +/****************************************************************************** + structure for packet status ring base address hi reg in rxdma address map + located at address 0x2024 + *****************************************************************************/ +typedef struct _RXDMA_PSR_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +RXDMA_PSR_BASE_HI_t, *PRXDMA_PSR_BASE_HI_t; + + +/****************************************************************************** + structure for packet status ring number of descriptors reg in rxdma address + map. Located at address 0x2028 + *****************************************************************************/ +typedef union _RXDMA_PSR_NUM_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 psr_ndes:12; //bit 0-11 + #else + UINT32 psr_ndes:12; //bit 0-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} +RXDMA_PSR_NUM_DES_t, *PRXDMA_PSR_NUM_DES_t; + + +/****************************************************************************** + structure for packet status ring available offset reg in rxdma address map + located at address 0x202C + *****************************************************************************/ +typedef union _RXDMA_PSR_AVAIL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:19; //bits 13-31 + UINT32 psr_avail_wrap:1; //bit 12 + UINT32 psr_avail:12; //bit 0-11 + #else + UINT32 psr_avail:12; //bit 0-11 + UINT32 psr_avail_wrap:1; //bit 12 + UINT32 unused:19; //bits 13-31 + #endif + } bits; +} +RXDMA_PSR_AVAIL_OFFSET_t, *PRXDMA_PSR_AVAIL_OFFSET_t; + + +/****************************************************************************** + structure for packet status ring full offset reg in rxdma address map + located at address 0x2030 + *****************************************************************************/ +typedef union _RXDMA_PSR_FULL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:19; //bits 13-31 + UINT32 psr_full_wrap:1; //bit 12 + UINT32 psr_full:12; //bit 0-11 + #else + UINT32 psr_full:12; //bit 0-11 + UINT32 psr_full_wrap:1; //bit 12 + UINT32 unused:19; //bits 13-31 + #endif + } bits; +} +RXDMA_PSR_FULL_OFFSET_t, *PRXDMA_PSR_FULL_OFFSET_t; + + +/****************************************************************************** + structure for packet status ring access index reg in rxdma address map + located at address 0x2034 + *****************************************************************************/ +typedef union _RXDMA_PSR_ACCESS_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 psr_ai:5; //bits 0-4 + #else + UINT32 psr_ai:5; //bits 0-4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +RXDMA_PSR_ACCESS_INDEX_t, *PRXDMA_PSR_ACCESS_INDEX_t; + + +/****************************************************************************** + structure for packet status ring minimum descriptors reg in rxdma address + map. Located at address 0x2038 + *****************************************************************************/ +typedef union _RXDMA_PSR_MIN_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 psr_min:12; //bits 0-11 + #else + UINT32 psr_min:12; //bits 0-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} +RXDMA_PSR_MIN_DES_t, *PRXDMA_PSR_MIN_DES_t; + + +/****************************************************************************** + structure for free buffer ring base lo address reg in rxdma address map + located at address 0x203C + *****************************************************************************/ +typedef struct _RXDMA_FBR_BASE_LO_t +{ + UINT32 addr_lo; //bits 0-31 +} +RXDMA_FBR_BASE_LO_t, *PRXDMA_FBR_BASE_LO_t; + + +/****************************************************************************** + structure for free buffer ring base hi address reg in rxdma address map + located at address 0x2040 + *****************************************************************************/ +typedef struct _RXDMA_FBR_BASE_HI_t +{ + UINT32 addr_hi; //bits 0-31 +} +RXDMA_FBR_BASE_HI_t, *PRXDMA_FBR_BASE_HI_t; + + +/****************************************************************************** + structure for free buffer ring number of descriptors reg in rxdma address + map. Located at address 0x2044 + *****************************************************************************/ +typedef union _RXDMA_FBR_NUM_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 fbr_ndesc:10; //bits 0-9 + #else + UINT32 fbr_ndesc:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXDMA_FBR_NUM_DES_t, *PRXDMA_FBR_NUM_DES_t; + + +/****************************************************************************** + structure for free buffer ring 0 available offset reg in rxdma address map + located at address 0x2048 + *****************************************************************************/ +typedef union _RXDMA_FBR_AVAIL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 fbr_avail_wrap:1; //bit 10 + UINT32 fbr_avail:10; //bit 0-9 + #else + UINT32 fbr_avail:10; //bit 0-9 + UINT32 fbr_avail_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_FBR_AVAIL_OFFSET_t, *PRXDMA_FBR_AVAIL_OFFSET_t; + + +/****************************************************************************** + structure for free buffer ring 0 full offset reg in rxdma address map + located at address 0x204C + *****************************************************************************/ +typedef union _RXDMA_FBR_FULL_OFFSET_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 fbr_full_wrap:1; //bit 10 + UINT32 fbr_full:10; //bit 0-9 + #else + UINT32 fbr_full:10; //bit 0-9 + UINT32 fbr_full_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +RXDMA_FBR_FULL_OFFSET_t, *PRXDMA_FBR_FULL_OFFSET_t; + + +/****************************************************************************** + structure for free buffer cache 0 full offset reg in rxdma address map + located at address 0x2050 + *****************************************************************************/ +typedef union _RXDMA_FBC_RD_INDEX_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:27; //bits 5-31 + UINT32 fbc_rdi:5; //bit 0-4 + #else + UINT32 fbc_rdi:5; //bit 0-4 + UINT32 unused:27; //bits 5-31 + #endif + } bits; +} +RXDMA_FBC_RD_INDEX_t, *PRXDMA_FBC_RD_INDEX_t; + + +/****************************************************************************** + structure for free buffer ring 0 minimum descriptor reg in rxdma address map + located at address 0x2054 + *****************************************************************************/ +typedef union _RXDMA_FBR_MIN_DES_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:22; //bits 10-31 + UINT32 fbr_min:10; //bits 0-9 + #else + UINT32 fbr_min:10; //bits 0-9 + UINT32 unused:22; //bits 10-31 + #endif + } bits; +} +RXDMA_FBR_MIN_DES_t, *PRXDMA_FBR_MIN_DES_t; + + +/****************************************************************************** + structure for free buffer ring 1 base address lo reg in rxdma address map + located at address 0x2058 - 0x205C + Defined earlier (RXDMA_FBR_BASE_LO_t and RXDMA_FBR_BASE_HI_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 number of descriptors reg in rxdma address + map. Located at address 0x2060 + Defined earlier (RXDMA_FBR_NUM_DES_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 available offset reg in rxdma address map + located at address 0x2064 + Defined Earlier (RXDMA_FBR_AVAIL_OFFSET_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 full offset reg in rxdma address map + located at address 0x2068 + Defined Earlier (RXDMA_FBR_FULL_OFFSET_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer cache 1 read index reg in rxdma address map + located at address 0x206C + Defined Earlier (RXDMA_FBC_RD_INDEX_t) + *****************************************************************************/ + +/****************************************************************************** + structure for free buffer ring 1 minimum descriptor reg in rxdma address map + located at address 0x2070 + Defined Earlier (RXDMA_FBR_MIN_DES_t) + *****************************************************************************/ + + +/****************************************************************************** + Rx DMA Module of JAGCore Address Mapping + Located at address 0x2000 + *****************************************************************************/ +typedef struct _RXDMA_t +{ //Location: + RXDMA_CSR_t csr; // 0x2000 + RXDMA_DMA_WB_BASE_LO_t dma_wb_base_lo; // 0x2004 + RXDMA_DMA_WB_BASE_HI_t dma_wb_base_hi; // 0x2008 + RXDMA_NUM_PKT_DONE_t num_pkt_done; // 0x200C + RXDMA_MAX_PKT_TIME_t max_pkt_time; // 0x2010 + RXDMA_RXQ_RD_ADDR_t rxq_rd_addr; // 0x2014 + RXDMA_RXQ_RD_ADDR_EXT_t rxq_rd_addr_ext; // 0x2018 + RXDMA_RXQ_WR_ADDR_t rxq_wr_addr; // 0x201C + RXDMA_PSR_BASE_LO_t psr_base_lo; // 0x2020 + RXDMA_PSR_BASE_HI_t psr_base_hi; // 0x2024 + RXDMA_PSR_NUM_DES_t psr_num_des; // 0x2028 + RXDMA_PSR_AVAIL_OFFSET_t psr_avail_offset; // 0x202C + RXDMA_PSR_FULL_OFFSET_t psr_full_offset; // 0x2030 + RXDMA_PSR_ACCESS_INDEX_t psr_access_index; // 0x2034 + RXDMA_PSR_MIN_DES_t psr_min_des; // 0x2038 + RXDMA_FBR_BASE_LO_t fbr0_base_lo; // 0x203C + RXDMA_FBR_BASE_HI_t fbr0_base_hi; // 0x2040 + RXDMA_FBR_NUM_DES_t fbr0_num_des; // 0x2044 + RXDMA_FBR_AVAIL_OFFSET_t fbr0_avail_offset; // 0x2048 + RXDMA_FBR_FULL_OFFSET_t fbr0_full_offset; // 0x204C + RXDMA_FBC_RD_INDEX_t fbr0_rd_index; // 0x2050 + RXDMA_FBR_MIN_DES_t fbr0_min_des; // 0x2054 + RXDMA_FBR_BASE_LO_t fbr1_base_lo; // 0x2058 + RXDMA_FBR_BASE_HI_t fbr1_base_hi; // 0x205C + RXDMA_FBR_NUM_DES_t fbr1_num_des; // 0x2060 + RXDMA_FBR_AVAIL_OFFSET_t fbr1_avail_offset; // 0x2064 + RXDMA_FBR_FULL_OFFSET_t fbr1_full_offset; // 0x2068 + RXDMA_FBC_RD_INDEX_t fbr1_rd_index; // 0x206C + RXDMA_FBR_MIN_DES_t fbr1_min_des; // 0x2070 +} +RXDMA_t, *PRXDMA_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF RXDMA REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF TXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for control reg in txmac address map + located at address 0x3000 + *****************************************************************************/ +typedef union _TXMAC_CTL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:24; //bits 8-31 + UINT32 cklseg_diable:1; //bit 7 + UINT32 ckbcnt_disable:1; //bit 6 + UINT32 cksegnum:1; //bit 5 + UINT32 async_disable:1; //bit 4 + UINT32 fc_disable:1; //bit 3 + UINT32 mcif_disable:1; //bit 2 + UINT32 mif_disable:1; //bit 1 + UINT32 txmac_en:1; //bit 0 + #else + UINT32 txmac_en:1; //bit 0 + UINT32 mif_disable:1; //bit 1 mac interface + UINT32 mcif_disable:1; //bit 2 memory controller interface + UINT32 fc_disable:1; //bit 3 + UINT32 async_disable:1; //bit 4 + UINT32 cksegnum:1; //bit 5 + UINT32 ckbcnt_disable:1; //bit 6 + UINT32 cklseg_diable:1; //bit 7 + UINT32 unused:24; //bits 8-31 + #endif + } bits; +} +TXMAC_CTL_t, *PTXMAC_CTL_t; + + +/****************************************************************************** + structure for shadow pointer reg in txmac address map + located at address 0x3004 + *****************************************************************************/ +typedef union _TXMAC_SHADOW_PTR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:5; //bits 27-31 + UINT32 txq_rd_ptr:11; //bits 16-26 + UINT32 reserved:5; //bits 11-15 + UINT32 txq_wr_ptr:11; //bits 0-10 + #else + UINT32 txq_wr_ptr:11; //bits 0-10 + UINT32 reserved:5; //bits 11-15 + UINT32 txq_rd_ptr:11; //bits 16-26 + UINT32 reserved2:5; //bits 27-31 + #endif + } bits; +} +TXMAC_SHADOW_PTR_t, *PTXMAC_SHADOW_PTR_t; + + +/****************************************************************************** + structure for error count reg in txmac address map + located at address 0x3008 + *****************************************************************************/ +typedef union _TXMAC_ERR_CNT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 reserved:4; //bits 8-11 + UINT32 txq_underrun:4; //bits 4-7 + UINT32 fifo_underrun:4; //bits 0-3 + #else + UINT32 fifo_underrun:4; //bits 0-3 + UINT32 txq_underrun:4; //bits 4-7 + UINT32 reserved:4; //bits 8-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} TXMAC_ERR_CNT_t, *PTXMAC_ERR_CNT_t; + + +/****************************************************************************** + structure for max fill reg in txmac address map + located at address 0x300C + *****************************************************************************/ +typedef union _TXMAC_MAX_FILL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:20; //bits 12-31 + UINT32 max_fill:12; //bits 0-11 + #else + UINT32 max_fill:12; //bits 0-11 + UINT32 unused:20; //bits 12-31 + #endif + } bits; +} +TXMAC_MAX_FILL_t, *PTXMAC_MAX_FILL_t; + + +/****************************************************************************** + structure for cf parameter reg in txmac address map + located at address 0x3010 + *****************************************************************************/ +typedef union _TXMAC_CF_PARAM_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 cfep:16; //bits 16-31 + UINT32 cfpt:16; //bits 0-15 + #else + UINT32 cfpt:16; //bits 0-15 + UINT32 cfep:16; //bits 16-31 + #endif + } bits; +} +TXMAC_CF_PARAM_t, *PTXMAC_CF_PARAM_t; + + +/****************************************************************************** + structure for tx test reg in txmac address map + located at address 0x3014 + *****************************************************************************/ +typedef union _TXMAC_TXTEST_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:15; //bits 17-31 + UINT32 reserved1:1; //bit 16 + UINT32 txtest_en:1; //bit 15 + UINT32 unused1:4; //bits 11-14 + UINT32 txqtest_ptr:11; //bits 0-11 + #else + UINT32 txqtest_ptr:11; //bits 0-10 + UINT32 unused1:4; //bits 11-14 + UINT32 txtest_en:1; //bit 15 + UINT32 reserved1:1; //bit 16 + UINT32 unused2:15; //bits 17-31 + #endif + } bits; +} +TXMAC_TXTEST_t, *PTXMAC_TXTEST_t; + + +/****************************************************************************** + structure for error reg in txmac address map + located at address 0x3018 + *****************************************************************************/ +typedef union _TXMAC_ERR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:23; //bits 9-31 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused1:2; //bits 6-7 + UINT32 ctrl2_err:1; //bit 5 + UINT32 txq_underrun:1; //bit 4 + UINT32 bcnt_err:1; //bit 3 + UINT32 lseg_err:1; //bit 2 + UINT32 segnum_err:1; //bit 1 + UINT32 seg0_err:1; //bit 0 + #else + UINT32 seg0_err:1; //bit 0 + UINT32 segnum_err:1; //bit 1 + UINT32 lseg_err:1; //bit 2 + UINT32 bcnt_err:1; //bit 3 + UINT32 txq_underrun:1; //bit 4 + UINT32 ctrl2_err:1; //bit 5 + UINT32 unused1:2; //bits 6-7 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused2:23; //bits 9-31 + #endif + } bits; +} +TXMAC_ERR_t, *PTXMAC_ERR_t; + + +/****************************************************************************** + structure for error interrupt reg in txmac address map + located at address 0x301C + *****************************************************************************/ +typedef union _TXMAC_ERR_INT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:23; //bits 9-31 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused1:2; //bits 6-7 + UINT32 ctrl2_err:1; //bit 5 + UINT32 txq_underrun:1; //bit 4 + UINT32 bcnt_err:1; //bit 3 + UINT32 lseg_err:1; //bit 2 + UINT32 segnum_err:1; //bit 1 + UINT32 seg0_err:1; //bit 0 + #else + UINT32 seg0_err:1; //bit 0 + UINT32 segnum_err:1; //bit 1 + UINT32 lseg_err:1; //bit 2 + UINT32 bcnt_err:1; //bit 3 + UINT32 txq_underrun:1; //bit 4 + UINT32 ctrl2_err:1; //bit 5 + UINT32 unused1:2; //bits 6-7 + UINT32 fifo_underrun:1; //bit 8 + UINT32 unused2:23; //bits 9-31 + #endif + } bits; +} +TXMAC_ERR_INT_t, *PTXMAC_ERR_INT_t; + + +/****************************************************************************** + structure for error interrupt reg in txmac address map + located at address 0x3020 + *****************************************************************************/ +typedef union _TXMAC_CP_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:30; //bits 2-31 + UINT32 bp_req:1; //bit 1 + UINT32 bp_xonxoff:1; //bit 0 + #else + UINT32 bp_xonxoff:1; //bit 0 + UINT32 bp_req:1; //bit 1 + UINT32 unused:30; //bits 2-31 + #endif + } bits; +} +TXMAC_BP_CTRL_t, *PTXMAC_BP_CTRL_t; + + +/****************************************************************************** + Tx MAC Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _TXMAC_t +{ //Location: + TXMAC_CTL_t ctl; // 0x3000 + TXMAC_SHADOW_PTR_t shadow_ptr; // 0x3004 + TXMAC_ERR_CNT_t err_cnt; // 0x3008 + TXMAC_MAX_FILL_t max_fill; // 0x300C + TXMAC_CF_PARAM_t cf_param; // 0x3010 + TXMAC_TXTEST_t tx_test; // 0x3014 + TXMAC_ERR_t err; // 0x3018 + TXMAC_ERR_INT_t err_int; // 0x301C + TXMAC_BP_CTRL_t bp_ctrl; // 0x3020 +} +TXMAC_t, *PTXMAC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF TXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF RXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for rxmac control reg in rxmac address map + located at address 0x4000 + *****************************************************************************/ +typedef union _RXMAC_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:25; //bits 7-31 + UINT32 rxmac_int_disable:1; //bit 6 + UINT32 async_disable:1; //bit 5 + UINT32 mif_disable:1; //bit 4 + UINT32 wol_disable:1; //bit 3 + UINT32 pkt_filter_disable:1; //bit 2 + UINT32 mcif_disable:1; //bit 1 + UINT32 rxmac_en:1; //bit 0 + #else + UINT32 rxmac_en:1; //bit 0 + UINT32 mcif_disable:1; //bit 1 + UINT32 pkt_filter_disable:1; //bit 2 + UINT32 wol_disable:1; //bit 3 + UINT32 mif_disable:1; //bit 4 + UINT32 async_disable:1; //bit 5 + UINT32 rxmac_int_disable:1; //bit 6 + UINT32 reserved:25; //bits 7-31 + #endif + } bits; +} +RXMAC_CTRL_t, *PRXMAC_CTRL_t; + + +/****************************************************************************** + structure for Wake On Lan Control and CRC 0 reg in rxmac address map + located at address 0x4004 + *****************************************************************************/ +typedef union _RXMAC_WOL_CTL_CRC0_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 crc0:16; //bits 16-31 + UINT32 reserve:4; //bits 12-15 + UINT32 ignore_pp:1; //bit 11 + UINT32 ignore_mp:1; //bit 10 + UINT32 clr_intr:1; //bit 9 + UINT32 ignore_link_chg:1; //bit 8 + UINT32 ignore_uni:1; //bit 7 + UINT32 ignore_multi:1; //bit 6 + UINT32 ignore_broad:1; //bit 5 + UINT32 valid_crc4:1; //bit 4 + UINT32 valid_crc3:1; //bit 3 + UINT32 valid_crc2:1; //bit 2 + UINT32 valid_crc1:1; //bit 1 + UINT32 valid_crc0:1; //bit 0 + #else + UINT32 valid_crc0:1; //bit 0 + UINT32 valid_crc1:1; //bit 1 + UINT32 valid_crc2:1; //bit 2 + UINT32 valid_crc3:1; //bit 3 + UINT32 valid_crc4:1; //bit 4 + UINT32 ignore_broad:1; //bit 5 + UINT32 ignore_multi:1; //bit 6 + UINT32 ignore_uni:1; //bit 7 + UINT32 ignore_link_chg:1; //bit 8 + UINT32 clr_intr:1; //bit 9 + UINT32 ignore_mp:1; //bit 10 + UINT32 ignore_pp:1; //bit 11 + UINT32 reserve:4; //bits 12-15 + UINT32 crc0:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_CTL_CRC0_t, *PRXMAC_WOL_CTL_CRC0_t; + + +/****************************************************************************** + structure for CRC 1 and CRC 2 reg in rxmac address map + located at address 0x4008 + *****************************************************************************/ +typedef union _RXMAC_WOL_CRC12_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 crc2:16; //bits 16-31 + UINT32 crc1:16; //bits 0-15 + #else + UINT32 crc1:16; //bits 0-15 + UINT32 crc2:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_CRC12_t, *PRXMAC_WOL_CRC12_t; + + +/****************************************************************************** + structure for CRC 3 and CRC 4 reg in rxmac address map + located at address 0x400C + *****************************************************************************/ +typedef union _RXMAC_WOL_CRC34_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 crc4:16; //bits 16-31 + UINT32 crc3:16; //bits 0-15 + #else + UINT32 crc3:16; //bits 0-15 + UINT32 crc4:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_CRC34_t, *PRXMAC_WOL_CRC34_t; + + +/****************************************************************************** + structure for Wake On Lan Source Address Lo reg in rxmac address map + located at address 0x4010 + *****************************************************************************/ +typedef union _RXMAC_WOL_SA_LO_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 sa3:8; //bits 24-31 + UINT32 sa4:8; //bits 16-23 + UINT32 sa5:8; //bits 8-15 + UINT32 sa6:8; //bits 0-7 + #else + UINT32 sa6:8; //bits 0-7 + UINT32 sa5:8; //bits 8-15 + UINT32 sa4:8; //bits 16-23 + UINT32 sa3:8; //bits 24-31 + #endif + } bits; +} +RXMAC_WOL_SA_LO_t, *PRXMAC_WOL_SA_LO_t; + + +/****************************************************************************** + structure for Wake On Lan Source Address Hi reg in rxmac address map + located at address 0x4014 + *****************************************************************************/ +typedef union _RXMAC_WOL_SA_HI_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 sa1:8; //bits 8-15 + UINT32 sa2:8; //bits 0-7 + #else + UINT32 sa2:8; //bits 0-7 + UINT32 sa1:8; //bits 8-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +RXMAC_WOL_SA_HI_t, *PRXMAC_WOL_SA_HI_t; + + +/****************************************************************************** + structure for Wake On Lan mask reg in rxmac address map + located at address 0x4018 - 0x4064 + *****************************************************************************/ +typedef struct _RXMAC_WOL_MASK_t +{ + UINT32 mask; //bits 0-31 +} +RXMAC_WOL_MASK_t, *PRXMAC_WOL_MASK_t; + + +/****************************************************************************** + structure for Unicast Paket Filter Address 1 reg in rxmac address map + located at address 0x4068 + *****************************************************************************/ +typedef union _RXMAC_UNI_PF_ADDR1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 addr1_3:8; //bits 24-31 + UINT32 addr1_4:8; //bits 16-23 + UINT32 addr1_5:8; //bits 8-15 + UINT32 addr1_6:8; //bits 0-7 + #else + UINT32 addr1_6:8; //bits 0-7 + UINT32 addr1_5:8; //bits 8-15 + UINT32 addr1_4:8; //bits 16-23 + UINT32 addr1_3:8; //bits 24-31 + #endif + } bits; +} +RXMAC_UNI_PF_ADDR1_t, *PRXMAC_UNI_PF_ADDR1_t; + + +/****************************************************************************** + structure for Unicast Paket Filter Address 2 reg in rxmac address map + located at address 0x406C + *****************************************************************************/ +typedef union _RXMAC_UNI_PF_ADDR2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 addr2_3:8; //bits 24-31 + UINT32 addr2_4:8; //bits 16-23 + UINT32 addr2_5:8; //bits 8-15 + UINT32 addr2_6:8; //bits 0-7 + #else + UINT32 addr2_6:8; //bits 0-7 + UINT32 addr2_5:8; //bits 8-15 + UINT32 addr2_4:8; //bits 16-23 + UINT32 addr2_3:8; //bits 24-31 + #endif + } bits; +} +RXMAC_UNI_PF_ADDR2_t, *PRXMAC_UNI_PF_ADDR2_t; + + +/****************************************************************************** + structure for Unicast Paket Filter Address 1 & 2 reg in rxmac address map + located at address 0x4070 + *****************************************************************************/ +typedef union _RXMAC_UNI_PF_ADDR3_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 addr2_1:8; //bits 24-31 + UINT32 addr2_2:8; //bits 16-23 + UINT32 addr1_1:8; //bits 8-15 + UINT32 addr1_2:8; //bits 0-7 + #else + UINT32 addr1_2:8; //bits 0-7 + UINT32 addr1_1:8; //bits 8-15 + UINT32 addr2_2:8; //bits 16-23 + UINT32 addr2_1:8; //bits 24-31 + #endif + } bits; +} +RXMAC_UNI_PF_ADDR3_t, *PRXMAC_UNI_PF_ADDR3_t; + + +/****************************************************************************** + structure for Multicast Hash reg in rxmac address map + located at address 0x4074 - 0x4080 + *****************************************************************************/ +typedef struct _RXMAC_MULTI_HASH_t +{ + UINT32 hash; //bits 0-31 +} +RXMAC_MULTI_HASH_t, *PRXMAC_MULTI_HASH_t; + + +/****************************************************************************** + structure for Packet Filter Control reg in rxmac address map + located at address 0x4084 + *****************************************************************************/ +typedef union _RXMAC_PF_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused2:9; //bits 23-31 + UINT32 min_pkt_size:7; //bits 16-22 + UINT32 unused1:12; //bits 4-15 + UINT32 filter_frag_en:1; //bit 3 + UINT32 filter_uni_en:1; //bit 2 + UINT32 filter_multi_en:1; //bit 1 + UINT32 filter_broad_en:1; //bit 0 + #else + UINT32 filter_broad_en:1; //bit 0 + UINT32 filter_multi_en:1; //bit 1 + UINT32 filter_uni_en:1; //bit 2 + UINT32 filter_frag_en:1; //bit 3 + UINT32 unused1:12; //bits 4-15 + UINT32 min_pkt_size:7; //bits 16-22 + UINT32 unused2:9; //bits 23-31 + #endif + } bits; +} +RXMAC_PF_CTRL_t, *PRXMAC_PF_CTRL_t; + + +/****************************************************************************** + structure for Memory Controller Interface Control Max Segment reg in rxmac + address map. Located at address 0x4088 + *****************************************************************************/ +typedef union _RXMAC_MCIF_CTRL_MAX_SEG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:22; //bits 10-31 + UINT32 max_size:8; //bits 2-9 + UINT32 fc_en:1; //bit 1 + UINT32 seg_en:1; //bit 0 + #else + UINT32 seg_en:1; //bit 0 + UINT32 fc_en:1; //bit 1 + UINT32 max_size:8; //bits 2-9 + UINT32 reserved:22; //bits 10-31 + #endif + } bits; +} +RXMAC_MCIF_CTRL_MAX_SEG_t, *PRXMAC_MCIF_CTRL_MAX_SEG_t; + + +/****************************************************************************** + structure for Memory Controller Interface Water Mark reg in rxmac address + map. Located at address 0x408C + *****************************************************************************/ +typedef union _RXMAC_MCIF_WATER_MARK_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:6; //bits 26-31 + UINT32 mark_hi:10; //bits 16-25 + UINT32 reserved1:6; //bits 10-15 + UINT32 mark_lo:10; //bits 0-9 + #else + UINT32 mark_lo:10; //bits 0-9 + UINT32 reserved1:6; //bits 10-15 + UINT32 mark_hi:10; //bits 16-25 + UINT32 reserved2:6; //bits 26-31 + #endif + } bits; +} +RXMAC_MCIF_WATER_MARK_t, *PRXMAC_MCIF_WATER_MARK_t; + + +/****************************************************************************** + structure for Rx Queue Dialog reg in rxmac address map. + located at address 0x4090 + *****************************************************************************/ +typedef union _RXMAC_RXQ_DIAG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:6; //bits 26-31 + UINT32 rd_ptr:10; //bits 16-25 + UINT32 reserved1:6; //bits 10-15 + UINT32 wr_ptr:10; //bits 0-9 + #else + UINT32 wr_ptr:10; //bits 0-9 + UINT32 reserved1:6; //bits 10-15 + UINT32 rd_ptr:10; //bits 16-25 + UINT32 reserved2:6; //bits 26-31 + #endif + } bits; +} +RXMAC_RXQ_DIAG_t, *PRXMAC_RXQ_DIAG_t; + + +/****************************************************************************** + structure for space availiable reg in rxmac address map. + located at address 0x4094 + *****************************************************************************/ +typedef union _RXMAC_SPACE_AVAIL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:15; //bits 17-31 + UINT32 space_avail_en:1; //bit 16 + UINT32 reserved1:6; //bits 10-15 + UINT32 space_avail:10; //bits 0-9 + #else + UINT32 space_avail:10; //bits 0-9 + UINT32 reserved1:6; //bits 10-15 + UINT32 space_avail_en:1; //bit 16 + UINT32 reserved2:15; //bits 17-31 + #endif + } bits; +} +RXMAC_SPACE_AVAIL_t, *PRXMAC_SPACE_AVAIL_t; + + +/****************************************************************************** + structure for management interface reg in rxmac address map. + located at address 0x4098 + *****************************************************************************/ +typedef union _RXMAC_MIF_CTL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserve:14; //bits 18-31 + UINT32 drop_pkt_en:1; //bit 17 + UINT32 drop_pkt_mask:17; //bits 0-16 + #else + UINT32 drop_pkt_mask:17; //bits 0-16 + UINT32 drop_pkt_en:1; //bit 17 + UINT32 reserve:14; //bits 18-31 + #endif + } bits; +} +RXMAC_MIF_CTL_t, *PRXMAC_MIF_CTL_t; + + +/****************************************************************************** + structure for Error reg in rxmac address map. + located at address 0x409C + *****************************************************************************/ +typedef union _RXMAC_ERROR_REG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserve:28; //bits 4-31 + UINT32 mif:1; //bit 3 + UINT32 async:1; //bit 2 + UINT32 pkt_filter:1; //bit 1 + UINT32 mcif:1; //bit 0 + #else + UINT32 mcif:1; //bit 0 + UINT32 pkt_filter:1; //bit 1 + UINT32 async:1; //bit 2 + UINT32 mif:1; //bit 3 + UINT32 reserve:28; //bits 4-31 + #endif + } bits; +} +RXMAC_ERROR_REG_t, *PRXMAC_ERROR_REG_t; + + +/****************************************************************************** + Rx MAC Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _RXMAC_t +{ //Location: + RXMAC_CTRL_t ctrl; // 0x4000 + RXMAC_WOL_CTL_CRC0_t crc0; // 0x4004 + RXMAC_WOL_CRC12_t crc12; // 0x4008 + RXMAC_WOL_CRC34_t crc34; // 0x400C + RXMAC_WOL_SA_LO_t sa_lo; // 0x4010 + RXMAC_WOL_SA_HI_t sa_hi; // 0x4014 + RXMAC_WOL_MASK_t mask0_word0; // 0x4018 + RXMAC_WOL_MASK_t mask0_word1; // 0x401C + RXMAC_WOL_MASK_t mask0_word2; // 0x4020 + RXMAC_WOL_MASK_t mask0_word3; // 0x4024 + RXMAC_WOL_MASK_t mask1_word0; // 0x4028 + RXMAC_WOL_MASK_t mask1_word1; // 0x402C + RXMAC_WOL_MASK_t mask1_word2; // 0x4030 + RXMAC_WOL_MASK_t mask1_word3; // 0x4034 + RXMAC_WOL_MASK_t mask2_word0; // 0x4038 + RXMAC_WOL_MASK_t mask2_word1; // 0x403C + RXMAC_WOL_MASK_t mask2_word2; // 0x4040 + RXMAC_WOL_MASK_t mask2_word3; // 0x4044 + RXMAC_WOL_MASK_t mask3_word0; // 0x4048 + RXMAC_WOL_MASK_t mask3_word1; // 0x404C + RXMAC_WOL_MASK_t mask3_word2; // 0x4050 + RXMAC_WOL_MASK_t mask3_word3; // 0x4054 + RXMAC_WOL_MASK_t mask4_word0; // 0x4058 + RXMAC_WOL_MASK_t mask4_word1; // 0x405C + RXMAC_WOL_MASK_t mask4_word2; // 0x4060 + RXMAC_WOL_MASK_t mask4_word3; // 0x4064 + RXMAC_UNI_PF_ADDR1_t uni_pf_addr1; // 0x4068 + RXMAC_UNI_PF_ADDR2_t uni_pf_addr2; // 0x406C + RXMAC_UNI_PF_ADDR3_t uni_pf_addr3; // 0x4070 + RXMAC_MULTI_HASH_t multi_hash1; // 0x4074 + RXMAC_MULTI_HASH_t multi_hash2; // 0x4078 + RXMAC_MULTI_HASH_t multi_hash3; // 0x407C + RXMAC_MULTI_HASH_t multi_hash4; // 0x4080 + RXMAC_PF_CTRL_t pf_ctrl; // 0x4084 + RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; // 0x4088 + RXMAC_MCIF_WATER_MARK_t mcif_water_mark; // 0x408C + RXMAC_RXQ_DIAG_t rxq_diag; // 0x4090 + RXMAC_SPACE_AVAIL_t space_avail; // 0x4094 + + RXMAC_MIF_CTL_t mif_ctrl; // 0x4098 + RXMAC_ERROR_REG_t err_reg; // 0x409C +} +RXMAC_t, *PRXMAC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF TXMAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF MAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for configuration #1 reg in mac address map. + located at address 0x5000 + *****************************************************************************/ +typedef union _MAC_CFG1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 soft_reset:1; //bit 31 + UINT32 sim_reset:1; //bit 30 + UINT32 reserved3:10; //bits 20-29 + UINT32 reset_rx_mc:1; //bit 19 + UINT32 reset_tx_mc:1; //bit 18 + UINT32 reset_rx_fun:1; //bit 17 + UINT32 reset_tx_fun:1; //bit 16 + UINT32 reserved2:7; //bits 9-15 + UINT32 loop_back:1; //bit 8 + UINT32 reserved1:2; //bits 6-7 + UINT32 rx_flow:1; //bit 5 + UINT32 tx_flow:1; //bit 4 + UINT32 syncd_rx_en:1; //bit 3 + UINT32 rx_enable:1; //bit 2 + UINT32 syncd_tx_en:1; //bit 1 + UINT32 tx_enable:1; //bit 0 + #else + UINT32 tx_enable:1; //bit 0 + UINT32 syncd_tx_en:1; //bit 1 + UINT32 rx_enable:1; //bit 2 + UINT32 syncd_rx_en:1; //bit 3 + UINT32 tx_flow:1; //bit 4 + UINT32 rx_flow:1; //bit 5 + UINT32 reserved1:2; //bits 6-7 + UINT32 loop_back:1; //bit 8 + UINT32 reserved2:7; //bits 9-15 + UINT32 reset_tx_fun:1; //bit 16 + UINT32 reset_rx_fun:1; //bit 17 + UINT32 reset_tx_mc:1; //bit 18 + UINT32 reset_rx_mc:1; //bit 19 + UINT32 reserved3:10; //bits 20-29 + UINT32 sim_reset:1; //bit 30 + UINT32 soft_reset:1; //bit 31 + #endif + } bits; +} +MAC_CFG1_t, *PMAC_CFG1_t; + + +/****************************************************************************** + structure for configuration #2 reg in mac address map. + located at address 0x5004 + *****************************************************************************/ +typedef union _MAC_CFG2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved3:16; //bits 16-31 + UINT32 preamble_len:4; //bits 12-15 + UINT32 reserved2:2; //bits 10-11 + UINT32 if_mode:2; //bits 8-9 + UINT32 reserved1:2; //bits 6-7 + UINT32 huge_frame:1; //bit 5 + UINT32 len_check:1; //bit 4 + UINT32 undefined:1; //bit 3 + UINT32 pad_crc:1; //bit 2 + UINT32 crc_enable:1; //bit 1 + UINT32 full_duplex:1; //bit 0 + #else + UINT32 full_duplex:1; //bit 0 + UINT32 crc_enable:1; //bit 1 + UINT32 pad_crc:1; //bit 2 + UINT32 undefined:1; //bit 3 + UINT32 len_check:1; //bit 4 + UINT32 huge_frame:1; //bit 5 + UINT32 reserved1:2; //bits 6-7 + UINT32 if_mode:2; //bits 8-9 + UINT32 reserved2:2; //bits 10-11 + UINT32 preamble_len:4; //bits 12-15 + UINT32 reserved3:16; //bits 16-31 + #endif + } bits; +} +MAC_CFG2_t, *PMAC_CFG2_t; + + +/****************************************************************************** + structure for Interpacket gap reg in mac address map. + located at address 0x5008 + *****************************************************************************/ +typedef union _MAC_IPG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:1; //bit 31 + UINT32 non_B2B_ipg_1:7; //bits 24-30 + UINT32 undefined2:1; //bit 23 + UINT32 non_B2B_ipg_2:7; //bits 16-22 + UINT32 min_ifg_enforce:8; //bits 8-15 + UINT32 undefined1:1; //bit 7 + UINT32 B2B_ipg:7; //bits 0-6 + #else + UINT32 B2B_ipg:7; //bits 0-6 + UINT32 undefined1:1; //bit 7 + UINT32 min_ifg_enforce:8; //bits 8-15 + UINT32 non_B2B_ipg_2:7; //bits 16-22 + UINT32 undefined2:1; //bit 23 + UINT32 non_B2B_ipg_1:7; //bits 24-30 + UINT32 reserved:1; //bit 31 + #endif + } bits; +} +MAC_IPG_t, *PMAC_IPG_t; + + +/****************************************************************************** + structure for half duplex reg in mac address map. + located at address 0x500C + *****************************************************************************/ +typedef union _MAC_HFDP_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:8; //bits 24-31 + UINT32 alt_beb_trunc:4; //bits 23-20 + UINT32 alt_beb_enable:1; //bit 19 + UINT32 bp_no_backoff:1; //bit 18 + UINT32 no_backoff:1; //bit 17 + UINT32 excess_defer:1; //bit 16 + UINT32 rexmit_max:4; //bits 12-15 + UINT32 reserved1:2; //bits 10-11 + UINT32 coll_window:10; //bits 0-9 + #else + UINT32 coll_window:10; //bits 0-9 + UINT32 reserved1:2; //bits 10-11 + UINT32 rexmit_max:4; //bits 12-15 + UINT32 excess_defer:1; //bit 16 + UINT32 no_backoff:1; //bit 17 + UINT32 bp_no_backoff:1; //bit 18 + UINT32 alt_beb_enable:1; //bit 19 + UINT32 alt_beb_trunc:4; //bits 23-20 + UINT32 reserved2:8; //bits 24-31 + #endif + } bits; +} +MAC_HFDP_t, *PMAC_HFDP_t; + + +/****************************************************************************** + structure for Maximum Frame Length reg in mac address map. + located at address 0x5010 + *****************************************************************************/ +typedef union _MAC_MAX_FM_LEN_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 max_len:16; //bits 0-15 + #else + UINT32 max_len:16; //bits 0-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +MAC_MAX_FM_LEN_t, *PMAC_MAX_FM_LEN_t; + + +/****************************************************************************** + structure for Reserve 1 reg in mac address map. + located at address 0x5014 - 0x5018 + *****************************************************************************/ +typedef struct _MAC_RSV_t +{ + UINT32 value; //bits 0-31 +} +MAC_RSV_t, *PMAC_RSV_t; + + +/****************************************************************************** + structure for Test reg in mac address map. + located at address 0x501C + *****************************************************************************/ +typedef union _MAC_TEST_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:29; //bits 3-31 + UINT32 mac_test:3; //bits 0-2 + #else + UINT32 mac_test:3; //bits 0-2 + UINT32 unused:29; //bits 3-31 + #endif + } bits; +} +MAC_TEST_t, *PMAC_TEST_t; + + +/****************************************************************************** + structure for MII Management Configuration reg in mac address map. + located at address 0x5020 + *****************************************************************************/ +typedef union _MII_MGMT_CFG_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reset_mii_mgmt:1; //bit 31 + UINT32 reserved:25; //bits 6-30 + UINT32 scan_auto_incremt:1; //bit 5 + UINT32 preamble_suppress:1; //bit 4 + UINT32 undefined:1; //bit 3 + UINT32 mgmt_clk_reset:3; //bits 0-2 + #else + UINT32 mgmt_clk_reset:3; //bits 0-2 + UINT32 undefined:1; //bit 3 + UINT32 preamble_suppress:1; //bit 4 + UINT32 scan_auto_incremt:1; //bit 5 + UINT32 reserved:25; //bits 6-30 + UINT32 reset_mii_mgmt:1; //bit 31 + #endif + } bits; +} +MII_MGMT_CFG_t, *PMII_MGMT_CFG_t; + + +/****************************************************************************** + structure for MII Management Command reg in mac address map. + located at address 0x5024 + *****************************************************************************/ +typedef union _MII_MGMT_CMD_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:30; //bits 2-31 + UINT32 scan_cycle:1; //bit 1 + UINT32 read_cycle:1; //bit 0 + #else + UINT32 read_cycle:1; //bit 0 + UINT32 scan_cycle:1; //bit 1 + UINT32 reserved:30; //bits 2-31 + #endif + } bits; +} +MII_MGMT_CMD_t, *PMII_MGMT_CMD_t; + + +/****************************************************************************** + structure for MII Management Address reg in mac address map. + located at address 0x5028 + *****************************************************************************/ +typedef union _MII_MGMT_ADDR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved2:19; //bit 13-31 + UINT32 phy_addr:5; //bits 8-12 + UINT32 reserved1:3; //bits 5-7 + UINT32 reg_addr:5; //bits 0-4 + #else + UINT32 reg_addr:5; //bits 0-4 + UINT32 reserved1:3; //bits 5-7 + UINT32 phy_addr:5; //bits 8-12 + UINT32 reserved2:19; //bit 13-31 + #endif + } bits; +} +MII_MGMT_ADDR_t, *PMII_MGMT_ADDR_t; + + +/****************************************************************************** + structure for MII Management Control reg in mac address map. + located at address 0x502C + *****************************************************************************/ +typedef union _MII_MGMT_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 phy_ctrl:16; //bits 0-15 + #else + UINT32 phy_ctrl:16; //bits 0-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +MII_MGMT_CTRL_t, *PMII_MGMT_CTRL_t; + + +/****************************************************************************** + structure for MII Management Status reg in mac address map. + located at address 0x5030 + *****************************************************************************/ +typedef union _MII_MGMT_STAT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:16; //bits 16-31 + UINT32 phy_stat:16; //bits 0-15 + #else + UINT32 phy_stat:16; //bits 0-15 + UINT32 reserved:16; //bits 16-31 + #endif + } bits; +} +MII_MGMT_STAT_t, *PMII_MGMT_STAT_t; + + +/****************************************************************************** + structure for MII Management Indicators reg in mac address map. + located at address 0x5034 + *****************************************************************************/ +typedef union _MII_MGMT_INDICATOR_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:29; //bits 3-31 + UINT32 not_valid:1; //bit 2 + UINT32 scanning:1; //bit 1 + UINT32 busy:1; //bit 0 + #else + UINT32 busy:1; //bit 0 + UINT32 scanning:1; //bit 1 + UINT32 not_valid:1; //bit 2 + UINT32 reserved:29; //bits 3-31 + #endif + } bits; +} +MII_MGMT_INDICATOR_t, *PMII_MGMT_INDICATOR_t; + + +/****************************************************************************** + structure for Interface Control reg in mac address map. + located at address 0x5038 + *****************************************************************************/ +typedef union _MAC_IF_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reset_if_module:1; //bit 31 + UINT32 reserved4:3; //bit 28-30 + UINT32 tbi_mode:1; //bit 27 + UINT32 ghd_mode:1; //bit 26 + UINT32 lhd_mode:1; //bit 25 + UINT32 phy_mode:1; //bit 24 + UINT32 reset_per_mii:1; //bit 23 + UINT32 reserved3:6; //bits 17-22 + UINT32 speed:1; //bit 16 + UINT32 reset_pe100x:1; //bit 15 + UINT32 reserved2:4; //bits 11-14 + UINT32 force_quiet:1; //bit 10 + UINT32 no_cipher:1; //bit 9 + UINT32 disable_link_fail:1; //bit 8 + UINT32 reset_gpsi:1; //bit 7 + UINT32 reserved1:6; //bits 1-6 + UINT32 enab_jab_protect:1; //bit 0 + #else + UINT32 enab_jab_protect:1; //bit 0 + UINT32 reserved1:6; //bits 1-6 + UINT32 reset_gpsi:1; //bit 7 + UINT32 disable_link_fail:1; //bit 8 + UINT32 no_cipher:1; //bit 9 + UINT32 force_quiet:1; //bit 10 + UINT32 reserved2:4; //bits 11-14 + UINT32 reset_pe100x:1; //bit 15 + UINT32 speed:1; //bit 16 + UINT32 reserved3:6; //bits 17-22 + UINT32 reset_per_mii:1; //bit 23 + UINT32 phy_mode:1; //bit 24 + UINT32 lhd_mode:1; //bit 25 + UINT32 ghd_mode:1; //bit 26 + UINT32 tbi_mode:1; //bit 27 + UINT32 reserved4:3; //bit 28-30 + UINT32 reset_if_module:1; //bit 31 + #endif + } bits; +} +MAC_IF_CTRL_t, *PMAC_IF_CTRL_t; + + +/****************************************************************************** + structure for Interface Status reg in mac address map. + located at address 0x503C + *****************************************************************************/ +typedef union _MAC_IF_STAT_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:22; //bits 10-31 + UINT32 excess_defer:1; //bit 9 + UINT32 clash:1; //bit 8 + UINT32 phy_jabber:1; //bit 7 + UINT32 phy_link_ok:1; //bit 6 + UINT32 phy_full_duplex:1; //bit 5 + UINT32 phy_speed:1; //bit 4 + UINT32 pe100x_link_fail:1; //bit 3 + UINT32 pe10t_loss_carrie:1; //bit 2 + UINT32 pe10t_sqe_error:1; //bit 1 + UINT32 pe10t_jabber:1; //bit 0 + #else + UINT32 pe10t_jabber:1; //bit 0 + UINT32 pe10t_sqe_error:1; //bit 1 + UINT32 pe10t_loss_carrie:1; //bit 2 + UINT32 pe100x_link_fail:1; //bit 3 + UINT32 phy_speed:1; //bit 4 + UINT32 phy_full_duplex:1; //bit 5 + UINT32 phy_link_ok:1; //bit 6 + UINT32 phy_jabber:1; //bit 7 + UINT32 clash:1; //bit 8 + UINT32 excess_defer:1; //bit 9 + UINT32 reserved:22; //bits 10-31 + #endif + } bits; +} +MAC_IF_STAT_t, *PMAC_IF_STAT_t; + + +/****************************************************************************** + structure for Mac Station Address, Part 1 reg in mac address map. + located at address 0x5040 + *****************************************************************************/ +typedef union _MAC_STATION_ADDR1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 Octet6:8; //bits 24-31 + UINT32 Octet5:8; //bits 16-23 + UINT32 Octet4:8; //bits 8-15 + UINT32 Octet3:8; //bits 0-7 + #else + UINT32 Octet3:8; //bits 0-7 + UINT32 Octet4:8; //bits 8-15 + UINT32 Octet5:8; //bits 16-23 + UINT32 Octet6:8; //bits 24-31 + #endif + } bits; +} +MAC_STATION_ADDR1_t, *PMAC_STATION_ADDR1_t; + + +/****************************************************************************** + structure for Mac Station Address, Part 2 reg in mac address map. + located at address 0x5044 + *****************************************************************************/ +typedef union _MAC_STATION_ADDR2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 Octet2:8; //bits 24-31 + UINT32 Octet1:8; //bits 16-23 + UINT32 reserved:16; //bits 0-15 + #else + UINT32 reserved:16; //bit 0-15 + UINT32 Octet1:8; //bits 16-23 + UINT32 Octet2:8; //bits 24-31 + #endif + } bits; +} +MAC_STATION_ADDR2_t, *PMAC_STATION_ADDR2_t; + + +/****************************************************************************** + MAC Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _MAC_t +{ //Location: + MAC_CFG1_t cfg1; // 0x5000 + MAC_CFG2_t cfg2; // 0x5004 + MAC_IPG_t ipg; // 0x5008 + MAC_HFDP_t hfdp; // 0x500C + MAC_MAX_FM_LEN_t max_fm_len; // 0x5010 + MAC_RSV_t rsv1; // 0x5014 + MAC_RSV_t rsv2; // 0x5018 + MAC_TEST_t mac_test; // 0x501C + MII_MGMT_CFG_t mii_mgmt_cfg; // 0x5020 + MII_MGMT_CMD_t mii_mgmt_cmd; // 0x5024 + MII_MGMT_ADDR_t mii_mgmt_addr; // 0x5028 + MII_MGMT_CTRL_t mii_mgmt_ctrl; // 0x502C + MII_MGMT_STAT_t mii_mgmt_stat; // 0x5030 + MII_MGMT_INDICATOR_t mii_mgmt_indicator; // 0x5034 + MAC_IF_CTRL_t if_ctrl; // 0x5038 + MAC_IF_STAT_t if_stat; // 0x503C + MAC_STATION_ADDR1_t station_addr_1; // 0x5040 + MAC_STATION_ADDR2_t station_addr_2; // 0x5044 +} +MAC_t, *PMAC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF MAC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF MAC STAT REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for Carry Register One and it's Mask Register reg located in mac + stat address map address 0x6130 and 0x6138. + *****************************************************************************/ +typedef union _MAC_STAT_REG_1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 tr64:1; //bit 31 + UINT32 tr127:1; //bit 30 + UINT32 tr255:1; //bit 29 + UINT32 tr511:1; //bit 28 + UINT32 tr1k:1; //bit 27 + UINT32 trmax:1; //bit 26 + UINT32 trmgv:1; //bit 25 + UINT32 unused:8; //bits 17-24 + UINT32 rbyt:1; //bit 16 + UINT32 rpkt:1; //bit 15 + UINT32 rfcs:1; //bit 14 + UINT32 rmca:1; //bit 13 + UINT32 rbca:1; //bit 12 + UINT32 rxcf:1; //bit 11 + UINT32 rxpf:1; //bit 10 + UINT32 rxuo:1; //bit 9 + UINT32 raln:1; //bit 8 + UINT32 rflr:1; //bit 7 + UINT32 rcde:1; //bit 6 + UINT32 rcse:1; //bit 5 + UINT32 rund:1; //bit 4 + UINT32 rovr:1; //bit 3 + UINT32 rfrg:1; //bit 2 + UINT32 rjbr:1; //bit 1 + UINT32 rdrp:1; //bit 0 + #else + UINT32 rdrp:1; //bit 0 + UINT32 rjbr:1; //bit 1 + UINT32 rfrg:1; //bit 2 + UINT32 rovr:1; //bit 3 + UINT32 rund:1; //bit 4 + UINT32 rcse:1; //bit 5 + UINT32 rcde:1; //bit 6 + UINT32 rflr:1; //bit 7 + UINT32 raln:1; //bit 8 + UINT32 rxuo:1; //bit 9 + UINT32 rxpf:1; //bit 10 + UINT32 rxcf:1; //bit 11 + UINT32 rbca:1; //bit 12 + UINT32 rmca:1; //bit 13 + UINT32 rfcs:1; //bit 14 + UINT32 rpkt:1; //bit 15 + UINT32 rbyt:1; //bit 16 + UINT32 unused:8; //bits 17-24 + UINT32 trmgv:1; //bit 25 + UINT32 trmax:1; //bit 26 + UINT32 tr1k:1; //bit 27 + UINT32 tr511:1; //bit 28 + UINT32 tr255:1; //bit 29 + UINT32 tr127:1; //bit 30 + UINT32 tr64:1; //bit 31 + #endif + } bits; +} +MAC_STAT_REG_1_t, *PMAC_STAT_REG_1_t; + + +/****************************************************************************** + structure for Carry Register Two Mask Register reg in mac stat address map. + located at address 0x613C + *****************************************************************************/ +typedef union _MAC_STAT_REG_2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:12; //bit 20-31 + UINT32 tjbr:1; //bit 19 + UINT32 tfcs:1; //bit 18 + UINT32 txcf:1; //bit 17 + UINT32 tovr:1; //bit 16 + UINT32 tund:1; //bit 15 + UINT32 tfrg:1; //bit 14 + UINT32 tbyt:1; //bit 13 + UINT32 tpkt:1; //bit 12 + UINT32 tmca:1; //bit 11 + UINT32 tbca:1; //bit 10 + UINT32 txpf:1; //bit 9 + UINT32 tdfr:1; //bit 8 + UINT32 tedf:1; //bit 7 + UINT32 tscl:1; //bit 6 + UINT32 tmcl:1; //bit 5 + UINT32 tlcl:1; //bit 4 + UINT32 txcl:1; //bit 3 + UINT32 tncl:1; //bit 2 + UINT32 tpfh:1; //bit 1 + UINT32 tdrp:1; //bit 0 + #else + UINT32 tdrp:1; //bit 0 + UINT32 tpfh:1; //bit 1 + UINT32 tncl:1; //bit 2 + UINT32 txcl:1; //bit 3 + UINT32 tlcl:1; //bit 4 + UINT32 tmcl:1; //bit 5 + UINT32 tscl:1; //bit 6 + UINT32 tedf:1; //bit 7 + UINT32 tdfr:1; //bit 8 + UINT32 txpf:1; //bit 9 + UINT32 tbca:1; //bit 10 + UINT32 tmca:1; //bit 11 + UINT32 tpkt:1; //bit 12 + UINT32 tbyt:1; //bit 13 + UINT32 tfrg:1; //bit 14 + UINT32 tund:1; //bit 15 + UINT32 tovr:1; //bit 16 + UINT32 txcf:1; //bit 17 + UINT32 tfcs:1; //bit 18 + UINT32 tjbr:1; //bit 19 + UINT32 unused:12; //bit 20-31 + #endif + } bits; +} +MAC_STAT_REG_2_t, *PMAC_STAT_REG_2_t; + + + + +/****************************************************************************** + MAC STATS Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _MAC_STAT_t +{ //Location: + UINT32 pad[32]; // 0x6000 - 607C + + //Tx/Rx 0-64 Byte Frame Counter + UINT32 TR64; // 0x6080 + + //Tx/Rx 65-127 Byte Frame Counter + UINT32 TR127; // 0x6084 + + //Tx/Rx 128-255 Byte Frame Counter + UINT32 TR255; // 0x6088 + + //Tx/Rx 256-511 Byte Frame Counter + UINT32 TR511; // 0x608C + + //Tx/Rx 512-1023 Byte Frame Counter + UINT32 TR1K; // 0x6090 + + //Tx/Rx 1024-1518 Byte Frame Counter + UINT32 TRMax; // 0x6094 + + //Tx/Rx 1519-1522 Byte Good VLAN Frame Count + UINT32 TRMgv; // 0x6098 + + //Rx Byte Counter + UINT32 RByt; // 0x609C + + //Rx Packet Counter + UINT32 RPkt; // 0x60A0 + + //Rx FCS Error Counter + UINT32 RFcs; // 0x60A4 + + //Rx Multicast Packet Counter + UINT32 RMca; // 0x60A8 + + //Rx Broadcast Packet Counter + UINT32 RBca; // 0x60AC + + //Rx Control Frame Packet Counter + UINT32 RxCf; // 0x60B0 + + //Rx Pause Frame Packet Counter + UINT32 RxPf; // 0x60B4 + + //Rx Unknown OP Code Counter + UINT32 RxUo; // 0x60B8 + + //Rx Alignment Error Counter + UINT32 RAln; // 0x60BC + + //Rx Frame Length Error Counter + UINT32 RFlr; // 0x60C0 + + //Rx Code Error Counter + UINT32 RCde; // 0x60C4 + + //Rx Carrier Sense Error Counter + UINT32 RCse; // 0x60C8 + + //Rx Undersize Packet Counter + UINT32 RUnd; // 0x60CC + + //Rx Oversize Packet Counter + UINT32 ROvr; // 0x60D0 + + //Rx Fragment Counter + UINT32 RFrg; // 0x60D4 + + //Rx Jabber Counter + UINT32 RJbr; // 0x60D8 + + //Rx Drop + UINT32 RDrp; // 0x60DC + + //Tx Byte Counter + UINT32 TByt; // 0x60E0 + + //Tx Packet Counter + UINT32 TPkt; // 0x60E4 + + //Tx Multicast Packet Counter + UINT32 TMca; // 0x60E8 + + //Tx Broadcast Packet Counter + UINT32 TBca; // 0x60EC + + //Tx Pause Control Frame Counter + UINT32 TxPf; // 0x60F0 + + //Tx Deferral Packet Counter + UINT32 TDfr; // 0x60F4 + + //Tx Excessive Deferral Packet Counter + UINT32 TEdf; // 0x60F8 + + //Tx Single Collision Packet Counter + UINT32 TScl; // 0x60FC + + //Tx Multiple Collision Packet Counter + UINT32 TMcl; // 0x6100 + + //Tx Late Collision Packet Counter + UINT32 TLcl; // 0x6104 + + //Tx Excessive Collision Packet Counter + UINT32 TXcl; // 0x6108 + + //Tx Total Collision Packet Counter + UINT32 TNcl; // 0x610C + + //Tx Pause Frame Honored Counter + UINT32 TPfh; // 0x6110 + + //Tx Drop Frame Counter + UINT32 TDrp; // 0x6114 + + //Tx Jabber Frame Counter + UINT32 TJbr; // 0x6118 + + //Tx FCS Error Counter + UINT32 TFcs; // 0x611C + + //Tx Control Frame Counter + UINT32 TxCf; // 0x6120 + + //Tx Oversize Frame Counter + UINT32 TOvr; // 0x6124 + + //Tx Undersize Frame Counter + UINT32 TUnd; // 0x6128 + + //Tx Fragments Frame Counter + UINT32 TFrg; // 0x612C + + //Carry Register One Register + MAC_STAT_REG_1_t Carry1; // 0x6130 + + //Carry Register Two Register + MAC_STAT_REG_2_t Carry2; // 0x6134 + + //Carry Register One Mask Register + MAC_STAT_REG_1_t Carry1M; // 0x6138 + + //Carry Register Two Mask Register + MAC_STAT_REG_2_t Carry2M; // 0x613C +} +MAC_STAT_t, *PMAC_STAT_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF MAC STAT REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF MMC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + structure for Main Memory Controller Control reg in mmc address map. + located at address 0x7000 + *****************************************************************************/ +typedef union _MMC_CTRL_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:25; //bits 7-31 + UINT32 force_ce:1; //bit 6 + UINT32 rxdma_disable:1; //bit 5 + UINT32 txdma_disable:1; //bit 4 + UINT32 txmac_disable:1; //bit 3 + UINT32 rxmac_disable:1; //bit 2 + UINT32 arb_disable:1; //bit 1 + UINT32 mmc_enable:1; //bit 0 + #else + UINT32 mmc_enable:1; //bit 0 + UINT32 arb_disable:1; //bit 1 + UINT32 rxmac_disable:1; //bit 2 + UINT32 txmac_disable:1; //bit 3 + UINT32 txdma_disable:1; //bit 4 + UINT32 rxdma_disable:1; //bit 5 + UINT32 force_ce:1; //bit 6 + UINT32 reserved:25; //bits 7-31 + #endif + } bits; +} +MMC_CTRL_t, *PMMC_CTRL_t; + + +/****************************************************************************** + structure for Main Memory Controller Host Memory Access Address reg in mmc + address map. Located at address 0x7004 + *****************************************************************************/ +typedef union _MMC_SRAM_ACCESS_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 byte_enable:16; //bits 16-31 + UINT32 reserved2:2; //bits 14-15 + UINT32 req_addr:10; //bits 4-13 + UINT32 reserved1:1; //bit 3 + UINT32 is_ctrl_word:1; //bit 2 + UINT32 wr_access:1; //bit 1 + UINT32 req_access:1; //bit 0 + #else + UINT32 req_access:1; //bit 0 + UINT32 wr_access:1; //bit 1 + UINT32 is_ctrl_word:1; //bit 2 + UINT32 reserved1:1; //bit 3 + UINT32 req_addr:10; //bits 4-13 + UINT32 reserved2:2; //bits 14-15 + UINT32 byte_enable:16; //bits 16-31 + #endif + } bits; +} +MMC_SRAM_ACCESS_t, *PMMC_SRAM_ACCESS_t; + + +/****************************************************************************** + structure for Main Memory Controller Host Memory Access Data reg in mmc + address map. Located at address 0x7008 - 0x7014 + *****************************************************************************/ +typedef struct _MMC_SRAM_WORD_t +{ + UINT32 data; //bits 0-31 +} MMC_SRAM_WORD_t, *PMMC_SRAM_WORD_t; + + +/****************************************************************************** + Memory Control Module of JAGCore Address Mapping + *****************************************************************************/ +typedef struct _MMC_t +{ //Location: + MMC_CTRL_t mmc_ctrl; // 0x7000 + MMC_SRAM_ACCESS_t sram_access; // 0x7004 + MMC_SRAM_WORD_t sram_word1; // 0x7008 + MMC_SRAM_WORD_t sram_word2; // 0x700C + MMC_SRAM_WORD_t sram_word3; // 0x7010 + MMC_SRAM_WORD_t sram_word4; // 0x7014 +} +MMC_t, *PMMC_t; +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF MMC REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + +/*===========================================================================*/ +/*===========================================================================*/ +/*=== START OF EXP ROM REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ +/****************************************************************************** + Expansion ROM Module of JAGCore Address Mapping + *****************************************************************************/ + +/* Take this out until it is not empty */ +#if 0 +typedef struct _EXP_ROM_t +{ + +} +EXP_ROM_t, *PEXP_ROM_t; +#endif +/*===========================================================================*/ +/*===========================================================================*/ +/*=== END OF EXP ROM REGISTER ADDRESS MAP ===*/ +/*===========================================================================*/ +/*===========================================================================*/ + + + + +/****************************************************************************** + JAGCore Address Mapping + *****************************************************************************/ +typedef struct _ADDRESS_MAP_t +{ + GLOBAL_t global; + UCHAR unused_global[4096 - sizeof (GLOBAL_t)]; //unused section of global address map + TXDMA_t txdma; + UCHAR unused_txdma[4096 - sizeof (TXDMA_t)]; //unused section of txdma address map + RXDMA_t rxdma; + UCHAR unused_rxdma[4096 - sizeof (RXDMA_t)]; //unused section of rxdma address map + TXMAC_t txmac; + UCHAR unused_txmac[4096 - sizeof (TXMAC_t)]; //unused section of txmac address map + RXMAC_t rxmac; + UCHAR unused_rxmac[4096 - sizeof (RXMAC_t)]; //unused section of rxmac address map + MAC_t mac; + UCHAR unused_mac[4096 - sizeof (MAC_t)]; //unused section of mac address map + MAC_STAT_t macStat; + UCHAR unused_mac_stat[4096 - sizeof (MAC_STAT_t)]; //unused section of mac stat address map + MMC_t mmc; + UCHAR unused_mmc[4096 - sizeof (MMC_t)]; //unused section of mmc address map + UCHAR unused_[1015808]; //unused section of address map + +/* Take this out until it is not empty */ +#if 0 + EXP_ROM_t exp_rom; +#endif + + UCHAR unused_exp_rom[4096]; //MGS-size TBD + UCHAR unused__[524288]; //unused section of address map +} +ADDRESS_MAP_t, *PADDRESS_MAP_t; +/*===========================================================================*/ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_ADDRESS_MAP_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_pm.c +++ linux-2.6.28/ubuntu/et131x/ET1310_pm.c @@ -0,0 +1,1723 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_pm.c - All power management related code (not completely implemented) + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" +#include "ET1310_rx.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE: CalculateCCITCRC16 + ****************************************************************************** + DESCRIPTION: + This routine calculates the CCIT CRC-16 value required for power + management. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +UINT16 CalculateCCITCRC16( PUCHAR Pattern, PUCHAR Mask, UINT32 MaskSize ) +{ + UINT32 i, j, k, HitBit; + UINT16 RemainderCRC = 0xFFFF; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "CalculateCCITCRC16" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + There is one bit in the mask for every byte in the pattern. Therefore, + this first loop (the "i" loop) iterates over every byte in the mask, + the inner "j" loop iterates over every bit in each byte. If that bit + in the mask is clear, then we skip over this byte of packet date (the + "continue"). + *************************************************************************/ + for( i = 0; i < MaskSize; i++ ) + { + for( j = 0; j < 8; j++ ) + { + if(( Mask[i] & ( 1 << j )) == 0 ) + { + continue; + } + + /****************************************************************** + Following 10 lines iterates over every bit in this byte of the + pattern, and applies the CRC-16 calculation as defined by CCIT. + It could be optimized using a look-up-table, but this function + will be called infrequently, so the memory overhead of + optimization can be avoided. + *****************************************************************/ + for( k = 0; k < 8; k++ ) + { + HitBit = (( RemainderCRC >> 15 ) & 1 ); + HitBit ^= ( Pattern[(i*8)+j] >> k ) & 1; + + RemainderCRC <<= 1; + + if( HitBit ) + { + RemainderCRC ^= CRC16_POLY; + } + } + } + } + + DBG_LEAVE( et131x_dbginfo ); + return( RemainderCRC ); +} + +/*===========================================================================*/ + + + +#if 0 +/****************************************************************************** + ROUTINE: MPSetPowerD0 + ****************************************************************************** + DESCRIPTION: + Used to set the power state to D0, Updated for the ET1310 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD0( IN PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + NDIS_DEVICE_POWER_STATE ComingBackFrom; + PM_CSR_t pm_csr = pAdapter->CSRAddress->global.pm_csr; + RXMAC_CTRL_t ctrl; + MI_ISR_t isr; + MI_BMSR_t Bmsr, BmsrInts; + UINT32 delay = 0; + + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD0\n" )); + + /************************************************************************** + Archive the power-state we are returning from, and then set the + "current" power state back to fully operational + *************************************************************************/ + ComingBackFrom = pAdapter->PoMgmt.PowerState; + pAdapter->PoMgmt.PowerState = NdisDeviceStateD0; + + + /********************************************************************** + Allow disabling of Non-Maskable Interrupts in I/O space, to + support validation. + *********************************************************************/ + if( pAdapter->RegistryNMIDisable ) + { + UCHAR RegisterVal; + + NdisRawReadPortUchar( ET1310_NMI_DISABLE, &RegisterVal ); + + RegisterVal &= 0xf3; + + if( pAdapter->RegistryNMIDisable == 2 ) + { + RegisterVal |= 0xc; + } + + NdisRawWritePortUchar( ET1310_NMI_DISABLE, RegisterVal ); + } + + { + UCHAR read_size_reg; + + /****************************************************************** + Change the max read size to 2k + *****************************************************************/ + NdisReadPciSlotInformation( pAdapter->AdapterHandle, + 0, // not used + 0x51, + (PVOID)&read_size_reg, + sizeof( UCHAR )); + + read_size_reg &= 0x8f; + read_size_reg |= 0x40; + + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, + 0x51, + &read_size_reg, + sizeof( UCHAR )); + } + + + /************************************************************************** + Sample read of pmcsr to aid validation. Will be catured by PCI-e + analyzer + *************************************************************************/ + NdisReadPciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + (PVOID)&uPmCsr, + sizeof( UINT32 )); + + /************************************************************************** + we now need to set the JAGCore gating control registers for this power + state. Bypass this for nonwake device since in that case the JAGCore + and gigE PHY have been reset + + This is only supposeto be for wake mode, when in non-wake mode, the + device enters L1 which causes a reset of the jagcore which basically + clears the PM_STATE. But due to issue with system not staying in L1 the + hardware reset is not happening. So we take care of it here. + *************************************************************************/ + if( TRUE ) //pAdapter->PoMgmt.WOLEnabled ) + { + pm_csr.bits.pm_gigephy_en = 0; + pm_csr.bits.pm_jagcore_rx_en = 0; + pm_csr.bits.pm_jagcore_tx_en = 0; + pm_csr.bits.pm_phy_lped_en = 0; + pm_csr.bits.pm_phy_sw_coma = 0; + + /********************************************************************** + enable clock first + *********************************************************************/ + pm_csr.bits.pm_sysclk_gate = 1; + pm_csr.bits.pm_txclk_gate = 1; + pm_csr.bits.pm_rxclk_gate = 1; + + /********************************************************************** + tx_en and rx_en should remain the same as in power down + *********************************************************************/ + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /********************************************************************** + poll the PMSTATE until JAGCore is in normal state + *********************************************************************/ + while(( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_rx_rdy != 0 ) && + ( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_tx_rdy != 0 ) && + ( delay < 100 )) + { + NdisStallExecution( 10 ); + delay++; + } + + if( delay >= 100 ) + { + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_jagcore_rx_en = 0; + pm_csr.bits.pm_jagcore_tx_en = 0; + pAdapter->CSRAddress->global.pm_csr.value = pm_csr.value; + } + } + + /************************************************************************** + now lets set up JAGcore pm control for D0 + *************************************************************************/ + pm_csr.bits.pm_gigephy_en = 0; + + pm_csr.bits.pm_jagcore_rx_en = pAdapter->PoMgmt.rx_en; + pm_csr.bits.pm_jagcore_tx_en = pAdapter->PoMgmt.tx_en; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /************************************************************************** + we also need to read and clear the phy_interrupt register in case of + wakeup on link status change + *************************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &isr.value ); + + /************************************************************************** + disable WOL + *************************************************************************/ + ctrl = pAdapter->CSRAddress->rxmac.ctrl; + + ctrl.bits.wol_disable = 1; + ctrl.bits.mif_disable = 0; + ctrl.bits.async_disable = 0; + + pAdapter->CSRAddress->rxmac.ctrl = ctrl; + + /************************************************************************** + Set the power state to 0 (d0), and flip the PME status pin. Clear the + PME Enable pin, if it were set. + *************************************************************************/ + uPmCsr = 0x00008000; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + /************************************************************************** + When the adapter is placed in D3 wake, it is set in 10 Base-T + half-duplex mode. However, we archived the speed and duplex settings + that were current prior to that, so restore them now and then tell + the phy to do it's thing. + *************************************************************************/ + if(( ComingBackFrom == NdisDeviceStateD3 ) || + ( ComingBackFrom == NdisDeviceStateD1 && !pAdapter->PoMgmt.WOLEnabledByCurrentState )) + { + pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed; + pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex; + + /********************************************************************** + Re-initialize the send structures + **********************************************************************/ + MPInitSend( pAdapter ); + + /********************************************************************** + Reset the RFD list and re-start RU + *********************************************************************/ + NICResetRecv( pAdapter ); + + /********************************************************************** + Bring the device back to the state it was during init prior + to autonegotiation being complete. This way, when we get the + auto-neg complete interrupt, we can complete init by calling + ConfigMacREGS2. + *********************************************************************/ + HwSoftwareReset( pAdapter ); + + /********************************************************************** + setup et1310 as per the documentation + *********************************************************************/ + NICSetAdapterUp( pAdapter ); + } + + /************************************************************************** + Allow Tx to restart + *************************************************************************/ + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + /************************************************************************** + Check to see if the link status bit is set in the BMSR register, if it + is not, this means we had a cable pull when at a lower power state and + need to indicate that we are disconnected to NDIS + *************************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, bmsr ), &Bmsr.value ); + + if( !Bmsr.bits.link_status ) + { + + pAdapter->Bmsr.value = Bmsr.value; + + NdisAcquireSpinLock( &pAdapter->Lock ); + MP_SET_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION ); + pAdapter->MediaState = 0; + + NdisReleaseSpinLock( &pAdapter->Lock ); + + // get timer going again... + NdisMSetPeriodicTimer( &pAdapter->PeriodicTimer, + TX_ERROR_PERIOD ); + + // setup for possible disconnect + NdisMSetTimer( &pAdapter->LinkDetectionTimer, + LINK_DETECTION_TIMER ); + + pAdapter->bLinkTimerActive = TRUE; + + if( pAdapter->RegistryPhyComa ) + { + MPSetPhyComa( pAdapter ); + } + /********************************************************************** + In the case of link-in before sleep, link-out after sleep, we need + to re-start the start-of-day timer so that we eventually flop + into PhyComa. In this case, the above state change gets overwritten + since we get a PHY interrupt almost straight away, and PHY interrupt + handling pulls us out of PHY coma mode. + *********************************************************************/ + pAdapter->PoMgmt.TransPhyComaModeOnBoot = 0; + } + + /************************************************************************** + we need to enable interrupts + *************************************************************************/ + NdisMSynchronizeWithInterrupt( &pAdapter->Interrupt, + (PVOID)NICEnableInterrupts, + pAdapter ); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD0\n" )); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPSetLowPower + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to any + state other than d0. Most of the common stuff for setting to a lower + power state should be handled in here. + + PARAMETERS : + pAdapter - pointer to our adapter structure + PowerState - NewPowerState + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetLowPower( IN PMP_ADAPTER pAdapter, + IN NDIS_DEVICE_POWER_STATE PowerState ) +{ + PM_CSR_t GlobalPmCSR; + RXMAC_CTRL_t ctrl; + MI_ISR_t isr; + MI_BMSR_t lBmsr; + BOOLEAN bDummy; + /*-----------------------------------------------------------------------*/ + + /************************************************************************** + if we are in coma mode when we get this request, we need to disable it + *************************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 1 ) + { + /********************************************************************** + check to see if we are in coma mode and if so, disable it because + we will not be able to read phy values until we are out. + *********************************************************************/ + MPDisablePhyComa( pAdapter ); + } + + /************************************************************************** + interrupts will be queued until after this routine completes. May as + well disable them now, since we do not want any of the queued interrupts. + *************************************************************************/ + NdisMSynchronizeWithInterrupt( &pAdapter->Interrupt, + (PVOID)NICDisableInterrupts, + pAdapter ); + + /************************************************************************** + Set the adapter power state to requested, lower state + *************************************************************************/ + pAdapter->PoMgmt.PowerState = PowerState; + + /************************************************************************** + Cancel timers - start them again when power restored + *************************************************************************/ + NdisMCancelTimer( &pAdapter->PeriodicTimer, &bDummy ); + + if( pAdapter->bLinkTimerActive == TRUE ){ + NdisMCancelTimer( &pAdapter->LinkDetectionTimer, &bDummy ); + } + + /************************************************************************** + Save the GbE PHY speed and duplex modes + + Need to restore this for: D1 nonwake, D3 wake and nonwake modes + *************************************************************************/ + pAdapter->PoMgmt.PowerDownSpeed = pAdapter->AiForceSpeed; + pAdapter->PoMgmt.PowerDownDuplex = pAdapter->AiForceDpx; + + NdisAcquireSpinLock( &pAdapter->SendHWLock ); + + /************************************************************************** + Stop sending packets. + *************************************************************************/ + MP_SET_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + NdisReleaseSpinLock( &pAdapter->SendHWLock ); + + /************************************************************************** + Free the packets being actively sent & stopped + **************************************************************************/ + MpFreeBusySendPackets( pAdapter ); + + /************************************************************************** + Save Rx/Tx enable condition. Used during restore to D0 state. + *************************************************************************/ + pAdapter->PoMgmt.tx_en = pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_tx_en; + pAdapter->PoMgmt.rx_en = pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_rx_en; + + /************************************************************************** + set the JAGCore gating control registers for this power state + *************************************************************************/ + GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + GlobalPmCSR.bits.pm_gigephy_en = 0; + } + else + { + GlobalPmCSR.bits.pm_gigephy_en = 1; + } + + /************************************************************************** + only exercise the PM state machine when the link is up + *************************************************************************/ + if( pAdapter->Bmsr.bits.link_status ) + { + GlobalPmCSR.bits.pm_jagcore_tx_en = 1; + GlobalPmCSR.bits.pm_jagcore_rx_en = 1; + + } + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + ctrl = pAdapter->CSRAddress->rxmac.ctrl; + + /************************************************************************** + only exercise the PM state machine when the link is up + *************************************************************************/ + if( pAdapter->Bmsr.bits.link_status ) + { + /********************************************************************** + disable MIF so power state can transition + *********************************************************************/ + ctrl.bits.mif_disable = 1; + pAdapter->CSRAddress->rxmac.ctrl = ctrl; + + while(( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_rx_rdy != 1 ) + && ( pAdapter->CSRAddress->global.pm_csr.bits.pm_jagcore_tx_rdy != 1 )) + { + NdisStallExecution( 10 ); + } + } + + /************************************************************************** + Stop hardware from receiving packets - Set the RU to idle + *************************************************************************/ + NICRxDmaDisable( pAdapter ); + + /************************************************************************** + Wait for outstanding Receive packets + *************************************************************************/ + while( MP_GET_RCV_REF( pAdapter ) != 0 ) + { + /********************************************************************** + Sleep for 2 Ms; + *********************************************************************/ + NdisStallExecution( 2000 ); + } + + /************************************************************************** + D3Wake only - set the MAC and Phy to 10BaseT half-duplex operation. + Archive the current settings in the pAdapter structure so we can + restore them when done. + *************************************************************************/ + if(( PowerState == NdisDeviceStateD3 ) && pAdapter->PoMgmt.WOLEnabledByCurrentState && + pAdapter->Bmsr.bits.link_status ) + { + /********************************************************************** + initialize variable for testing if we failed to go to specific link + *********************************************************************/ + pAdapter->PoMgmt.Failed10Half = FALSE; + + /********************************************************************** + set the phy properly + *********************************************************************/ + pAdapter->AiForceSpeed = 10; + pAdapter->AiForceDpx = 1; + + TPAL_SetPhy10HalfDuplex( pAdapter ); + + /********************************************************************** + get the link status here, we need to wait until the link comes back + after reconfiguring it. + *********************************************************************/ + TPAL_GetLinkStatusInfo( pAdapter ); + + if( pAdapter->PoMgmt.Failed10Half ) + { + /****************************************************************** + re-initialize variable for testing if we failed to go to + specific link speed + *****************************************************************/ + pAdapter->PoMgmt.Failed10Half = FALSE; + + /****************************************************************** + set the phy properly + *****************************************************************/ + pAdapter->AiForceSpeed = 100; + pAdapter->AiForceDpx = 1; + + TPAL_SetPhy100HalfDuplex( pAdapter ); + + /****************************************************************** + get the link status here, we need to wait until the link comes + back after reconfiguring it. + *****************************************************************/ + TPAL_GetLinkStatusInfo( pAdapter ); + } + + // SetRxDmaTimer( pAdapter ); + ConfigMACRegs2( pAdapter ); + } + + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + RXMAC_WOL_CTL_CRC0_t rxmac_ctl_crc0 = pAdapter->CSRAddress->rxmac.crc0; + RXMAC_WOL_CRC12_t crc12; + RXMAC_WOL_CRC34_t crc34; + ULONG ulResult; + UINT32 SerdesPhyControl; + UINT mask; + + ulResult = NdisReadPciSlotInformation( pAdapter->AdapterHandle, + 0, // not used + ET1310_PCI_PHY_INDEX_REG, + (PVOID)&SerdesPhyControl, + sizeof( UINT32 )); + + if( pAdapter->RegistryPMWOL ) + { + SerdesPhyControl |= 0x00010000; + } + else + { + SerdesPhyControl &= 0xfffeffff; + } + + ulResult = NdisWritePciSlotInformation( + pAdapter->AdapterHandle, + 0, + ET1310_PCI_PHY_INDEX_REG, + (PVOID)&SerdesPhyControl, + sizeof( UINT32 )); + + if( pAdapter->Bmsr.bits.link_status ) + { + /********************************************************************** + need to do this for all wake devices + make sure all ignore bits are set + *********************************************************************/ + rxmac_ctl_crc0.bits.ignore_broad = 1; + rxmac_ctl_crc0.bits.ignore_multi = 1; + rxmac_ctl_crc0.bits.ignore_uni = 1; + + if( pAdapter->RegistryWOLMatch & 0x1 ) + { + rxmac_ctl_crc0.bits.ignore_mp = 0; + } + else + { + rxmac_ctl_crc0.bits.ignore_mp = 1; + } + + if( pAdapter->RegistryWOLMatch & 0x2 ) + { + rxmac_ctl_crc0.bits.ignore_pp = 0; + } + else + { + rxmac_ctl_crc0.bits.ignore_pp = 1; + } + + if( pAdapter->RegistryWOLLink & 0x1 ) + { + rxmac_ctl_crc0.bits.ignore_link_chg = 0; + } + else + { + rxmac_ctl_crc0.bits.ignore_link_chg = 1; + } + + /****************************************************************** + Clear the pattern match validity bits - i.e. make all patterns + invalid + *****************************************************************/ + rxmac_ctl_crc0.value &= ~0x1f; + + if(( pAdapter->RegistryWOLMatch & 0x2 ) && + ( pAdapter->PoMgmt.localWolAndCrc0 & 0x1f )) + { + /************************************************************** + set the validity bits based on what has been enabled in + the adapter + *************************************************************/ + rxmac_ctl_crc0.value |= (pAdapter->PoMgmt.localWolAndCrc0 & 0x1f); + + /************************************************************** + Copy the five CRCs from the adapter + *************************************************************/ + rxmac_ctl_crc0.bits.crc0 = pAdapter->PoMgmt.WOLPatternList [0]; + crc12.bits.crc1 = pAdapter->PoMgmt.WOLPatternList [1]; + crc12.bits.crc2 = pAdapter->PoMgmt.WOLPatternList [2]; + crc34.bits.crc3 = pAdapter->PoMgmt.WOLPatternList [3]; + crc34.bits.crc4 = pAdapter->PoMgmt.WOLPatternList [4]; + + for( mask = 0; mask < 5; mask++) + { + UINT i; + PUINT32 pDevicePatternMask = (PUINT32) + (&pAdapter->CSRAddress->rxmac.mask0_word0) + + (mask * MAX_WOL_MASK_SIZE / 4); + if(( pAdapter->PoMgmt.localWolAndCrc0 >> mask ) & 0x1 ) + { + UINT32 Temp[ MAX_WOL_MASK_SIZE / 4 ]; + PUCHAR pNdisPatternMask; + + pNdisPatternMask = (PUCHAR)&pAdapter->PoMgmt.WOLMaskList[ mask ][ 0 ]; + + NdisZeroMemory( Temp, sizeof( Temp )); + NdisMoveMemory( Temp, pNdisPatternMask, + pAdapter->PoMgmt.WOLMaskSize[ mask ] ); + + /************************************************************** + Write the mask to the device using the pointer calculated + above. + *************************************************************/ + for( i=0; i<( MAX_WOL_MASK_SIZE / 4 ); i++ ) + { + pDevicePatternMask[ i ] = Temp[ i ]; + } + } + } + } + + pAdapter->CSRAddress->rxmac.crc0 = rxmac_ctl_crc0; + pAdapter->CSRAddress->rxmac.crc12 = crc12; + pAdapter->CSRAddress->rxmac.crc34 = crc34; + + /****************************************************************** + we also need to read and clear the phy_interrupt register in + case of wakeup on link status change + *****************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &isr.value ); + + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, bmsr ), &lBmsr.value ); + + /****************************************************************** + disable mif and async + *****************************************************************/ + ctrl.bits.mif_disable = 1; + ctrl.bits.async_disable = 1; + ctrl.bits.wol_disable = 0; + pAdapter->CSRAddress->rxmac.ctrl = ctrl; + + rxmac_ctl_crc0.bits.clr_intr = 1; + pAdapter->CSRAddress->rxmac.crc0.value = rxmac_ctl_crc0.value; + + DBGPRINT( MP_SPEC, ("Going down - ctrl 0x%x, crc0_ctl 0x%x\n", + pAdapter->CSRAddress->rxmac.ctrl.value, + pAdapter->CSRAddress->rxmac.crc0.value )); + + pAdapter->Stats.InterruptStatus.value = pAdapter->CSRAddress->global.int_status.value; + + DBGPRINT( MP_SPEC, ("Going down - int stat was 0x%x, now 0x%x\n", + pAdapter->Stats.InterruptStatus.value, + pAdapter->CSRAddress->global.int_status.value )); + } + else if( pAdapter->RegistryWOLLink & 0x1 ) + { + GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + + /************************************************************************** + Gate off JAGCore 3 clock domains + *************************************************************************/ + GlobalPmCSR.bits.pm_sysclk_gate = 0; + GlobalPmCSR.bits.pm_txclk_gate = 0; + GlobalPmCSR.bits.pm_rxclk_gate = 0; + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + /************************************************************************** + Program gigE PHY in to Coma mode + *************************************************************************/ + GlobalPmCSR.bits.pm_phy_sw_coma = 1; + GlobalPmCSR.bits.pm_phy_lped_en = 1; + + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + } + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD1Wake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D1 PowerState, and there is a set of wake-up patterns programmed + in the adapter. The set could consist of a single wake-up pattern. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD1Wake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD1Wake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol while + it is being provisioned, archive Tx and Rx enable, and do some of the + gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD1 ); + + if((( pAdapter->RegistryWOLLink & 0x1) == 0 ) || ( pAdapter->Bmsr.bits.link_status )) + { + /********************************************************************** + gate off paths we do not want active and leave ones we do + *********************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_sysclk_gate = 0; + pm_csr.bits.pm_txclk_gate = 0; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + } + + /************************************************************************** + Set the power state to 1 (d1), and blip the PME status pin. Set the + PME Enable pin, which indicates wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008100; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD1Wake\n" )); + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD1NonWake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D1 PowerState, and there are no wake-up patterns programmed + in the adapter. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD1NonWake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD1NonWake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol, + archive Tx and Rx enable, and do some of the gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD1 ); + + /************************************************************************** + gate off paths we do not want active and leave ones we do + *************************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_sysclk_gate = 1; + pm_csr.bits.pm_txclk_gate = 1; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /************************************************************************** + Set the power state to 1 (d1), and blip the PME status pin. Leave the + PME Enable pin clear, which indicates non-wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008000; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD1NonWake\n" )); + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD3Wake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D3 PowerState, and there is a set of wake-up patterns programmed + in the adapter. The set could consist of a single wake-up pattern. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD3Wake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD3Wake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol while + it is being provisioned, archive Tx and Rx enable, and do some of the + gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD3 ); + + if((( pAdapter->RegistryWOLLink & 0x1) == 0 ) || ( pAdapter->Bmsr.bits.link_status )) + { + /********************************************************************** + gate off paths we do not want active and leave ones we do + *********************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + pm_csr.bits.pm_sysclk_gate = 0; + pm_csr.bits.pm_txclk_gate = 0; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + } + + /************************************************************************** + Set the power state to 3 (d3), and blip the PME status pin. Set the + PME Enable pin, which indicates wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008100; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD3Wake\n" )); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPSetPowerD3NonWake + ****************************************************************************** + DESCRIPTION: + This routine is called when the adapter receives a SetPower to + D3 PowerState, and there are no wake-up patterns programmed + in the adapter. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +VOID MPSetPowerD3NonWake( PMP_ADAPTER pAdapter ) +{ + UINT32 uPmCsr; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + DBGPRINT( MP_TRACE, ( "----> MPSetPowerD3NonWake\n" )); + + /************************************************************************** + common power down functionality; disable Tx & Rx, disable wol, + archive Tx and Rx enable, and do some of the gating into jagcore. + *************************************************************************/ + MPSetLowPower( pAdapter, NdisDeviceStateD3 ); + + /************************************************************************** + gate off paths we do not want active and leave ones we do + *************************************************************************/ + pm_csr = pAdapter->CSRAddress->global.pm_csr; + pm_csr.bits.pm_sysclk_gate = 1; + pm_csr.bits.pm_txclk_gate = 1; + pm_csr.bits.pm_rxclk_gate = 1; + + pAdapter->CSRAddress->global.pm_csr = pm_csr; + + /************************************************************************** + Set the power state to 3 (d3), and blip the PME status pin. Leave the + PME Enable pin clear, which indicates non-wake state to PCI. + *************************************************************************/ + uPmCsr = 0x00008000; + NdisWritePciSlotInformation( pAdapter->AdapterHandle, + 0, // Slot no. Reserved. Ndis ignores. + ET1310_PCI_PM_CSR, + &uPmCsr, + sizeof( UINT32 )); + + DBGPRINT( MP_TRACE, ( "<---- MPSetPowerD3NonWake\n" )); + + return; +} +/*===========================================================================*/ + +#endif + + +/****************************************************************************** + ROUTINE: EnablePhyComa + ****************************************************************************** + DESCRIPTION: + This routine is called when network cable is unplugged -- driver + receive an phy status change interrupt while in D0 and check that + phy_status is down. + + -- gate off JAGCore; + -- set gigE PHY in Coma mode + -- wake on phy_interrupt; Perform software reset JAGCore, + re-initialize jagcore and gigE PHY + + Add D0-ASPM-PhyLinkDown Support: + -- while in D0, when there is a phy_interrupt indicating phy link + down status, call the MPSetPhyComa routine to enter this active + state power saving mode + -- while in D0-ASPM-PhyLinkDown mode, when there is a phy_interrupt + indicating linkup status, call the MPDisablePhyComa routine to + restore JAGCore and gigE PHY + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void EnablePhyComa( ET131X_ADAPTER *pAdapter ) +{ + unsigned long lockflags; + PM_CSR_t GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + INT32 LoopCounter = 10; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "EnablePhyComa" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Save the GbE PHY speed and duplex modes + Need to restore this when cable is plugged back in + *************************************************************************/ + pAdapter->PoMgmt.PowerDownSpeed = pAdapter->AiForceSpeed; + pAdapter->PoMgmt.PowerDownDuplex = pAdapter->AiForceDpx; + + + /************************************************************************** + Stop sending packets. + *************************************************************************/ + spin_lock_irqsave( &pAdapter->SendHWLock, lockflags ); + + MP_SET_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags ); + + + /************************************************************************** + Wait for outstanding Receive packets + *************************************************************************/ + while(( MP_GET_RCV_REF( pAdapter ) != 0 ) && ( LoopCounter-- > 0 )) + { + /********************************************************************** + Sleep for 2 Ms; + *********************************************************************/ + mdelay( 2 ); + } + + + /************************************************************************** + Gate off JAGCore 3 clock domains + *************************************************************************/ + GlobalPmCSR.bits.pm_sysclk_gate = 0; + GlobalPmCSR.bits.pm_txclk_gate = 0; + GlobalPmCSR.bits.pm_rxclk_gate = 0; + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + + /************************************************************************** + Program gigE PHY in to Coma mode + *************************************************************************/ + GlobalPmCSR.bits.pm_phy_sw_coma = 1; + + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: DisablePhyComa + ****************************************************************************** + DESCRIPTION: + This routine is used to disable the Phy Coma Mode + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void DisablePhyComa( ET131X_ADAPTER *pAdapter ) +{ + PM_CSR_t GlobalPmCSR = pAdapter->CSRAddress->global.pm_csr; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "DisablePhyComa" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************* + Disable phy_sw_coma register and re-enable JAGCore clocks + ************************************************************************/ + GlobalPmCSR.bits.pm_sysclk_gate = 1; + GlobalPmCSR.bits.pm_txclk_gate = 1; + GlobalPmCSR.bits.pm_rxclk_gate = 1; + GlobalPmCSR.bits.pm_phy_sw_coma = 0; + + pAdapter->CSRAddress->global.pm_csr = GlobalPmCSR; + + + /************************************************************************** + Restore the GbE PHY speed and duplex modes; + Reset JAGCore; re-configure and initialize JAGCore and gigE PHY + *************************************************************************/ + pAdapter->AiForceSpeed = pAdapter->PoMgmt.PowerDownSpeed; + pAdapter->AiForceDpx = pAdapter->PoMgmt.PowerDownDuplex; + + + /************************************************************************** + Re-initialize the send structures + *************************************************************************/ + et131x_init_send( pAdapter ); + + + /************************************************************************** + Reset the RFD list and re-start RU + *************************************************************************/ + et131x_reset_recv( pAdapter ); + + + /************************************************************************** + Bring the device back to the state it was during init prior to + autonegotiation being complete. This way, when we get the auto-neg + complete interrupt, we can complete init by calling ConfigMacREGS2. + *************************************************************************/ + et131x_soft_reset( pAdapter ); + + + /************************************************************************** + setup et1310 as per the documentation ?? + *************************************************************************/ + et131x_adapter_setup( pAdapter ); + + + /************************************************************************** + Allow Tx to restart + *************************************************************************/ + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER ); + + + /************************************************************************** + Need to re-enable Rx. + *************************************************************************/ + et131x_rx_dma_enable( pAdapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + +#if 0 +/****************************************************************************** + ROUTINE: MPSetPower + ****************************************************************************** + + DESCRIPTION: + This routine is called when the adapter receives a SetPower + request. It redirects the call to an appropriate routine to + Set the New PowerState + + PARAMETERS : + pAdapter - pointer to the adapter structure + PowerState - NewPowerState + + RETURN : + NONE + + *****************************************************************************/ +VOID MPSetPower( IN PMP_ADAPTER pAdapter, + IN NDIS_DEVICE_POWER_STATE PowerState ) +{ + DBGPRINT( MP_TRACE, ( "====> MPSetPower()\n" )); + + /************************************************************************** + determine what power state we are going to and go there + *************************************************************************/ + pAdapter->PoMgmt.WOLEnabledByCurrentState = TRUE; + + if( !pAdapter->PoMgmt.WOLEnabledByNdis ) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = FALSE; + } + + if(( pAdapter->RegistryWOLMatch == 0 ) && ( pAdapter->RegistryWOLLink == 0 )) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = FALSE; + } + + if(( pAdapter->PoMgmt.localWolAndCrc0 & 0x1f ) == 0 ) + { + /********************************************************************** + There are no wake patterns programmed. + *********************************************************************/ + if( pAdapter->RegistryWOLLink == 0 ) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = FALSE; + } + } + + /************************************************************************** + If the link is pulled, then the only wake event that will wake us + up is wake on link state change. If this change is disabled (0), go + to a non-wake state. + *************************************************************************/ + if( !pAdapter->ucLinkStatus && ( pAdapter->RegistryWOLLink == 0 )) + { + pAdapter->PoMgmt.WOLEnabledByCurrentState = 0; + } + + if( PowerState == NdisDeviceStateD0 ) + { + MPSetPowerD0( pAdapter ); + } + else if( PowerState == NdisDeviceStateD1 ) + { + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + MPSetPowerD1Wake( pAdapter ); + } + else + { + MPSetPowerD1NonWake( pAdapter ); + } + } + else if( PowerState == NdisDeviceStateD3 ) + { + if( pAdapter->PoMgmt.WOLEnabledByCurrentState ) + { + MPSetPowerD3Wake( pAdapter ); + } + else + { + MPSetPowerD3NonWake( pAdapter ); + } + } + + DBGPRINT( MP_TRACE, ( "<==== MPSetPower()\n" )); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPFillPoMgmtCaps + ****************************************************************************** + + DESCRIPTION: + Fills in the Power Managment structure depending the capabilities of + the software driver and the card. MGS CURRENTLY NOT SUPPORTED + + + PARAMETERS : + pAdapter - pointer to the adapter structure + pPowManageCaps - power management struct as defined in the DDK, + pStatus - status to be returned by the request, + pulInfoLen - length of the pPowerManagmentCapabilites + + RETURN : + Success or failure + + NOTE: + If the driver returns NDIS_STATUS_SUCCESS in response to a query of + this OID, NDIS treats a miniport driver as power management-aware. + If the driver returns NDIS_STATUS_NOT_SUPPORTED, NDIS treats the + miniport driver as a legacy driver that is not power + management-aware. + + The Bus driver is the power policy owner here so we do not have to + perform our mapping of System States to Device states, that is + accomplished by NDIS, we need to worry more about our wake-up + capabilities + + *****************************************************************************/ +VOID MPFillPoMgmtCaps( IN PMP_ADAPTER pAdapter, + IN OUT PNDIS_PNP_CAPABILITIES pPowMgmtCaps, + IN OUT PNDIS_STATUS pStatus, + IN OUT PULONG pulInfoLen ) +{ + BOOLEAN bIsPoMgmtSupported = TRUE; + /*-----------------------------------------------------------------------*/ + + bIsPoMgmtSupported = MPIsPoMgmtSupported( pAdapter ); + + if( bIsPoMgmtSupported ) + { + /********************************************************************** + NDIS_DEVICE_WAKE_UP_ENABLE; + *********************************************************************/ + pPowMgmtCaps->Flags = 0; + + /********************************************************************** + Magic Packet wakeups + *********************************************************************/ + pPowMgmtCaps->WakeUpCapabilities.MinMagicPacketWakeUp = + NdisDeviceStateD3; + + /********************************************************************** + NdisDeviceStateD3; + *********************************************************************/ + pPowMgmtCaps->WakeUpCapabilities.MinPatternWakeUp = + NdisDeviceStateD3; + pPowMgmtCaps->WakeUpCapabilities.MinLinkChangeWakeUp = + NdisDeviceStateD3; + + *pulInfoLen = sizeof( *pPowMgmtCaps ); + *pStatus = NDIS_STATUS_SUCCESS; + } + else + { + NdisZeroMemory( pPowMgmtCaps, sizeof( *pPowMgmtCaps )); + + *pStatus = NDIS_STATUS_NOT_SUPPORTED; + *pulInfoLen = 0; + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPAddWakeUpPattern + ****************************************************************************** + + DESCRIPTION: + This routine will allocate a local memory structure, copy the pattern, + insert the pattern into a linked list and return success + + We are gauranteed that we wll get only one request at a time, so this + is implemented without locks. + + PARAMETERS : + pAdapter - pointer to the adapter structure + InformationBuffer - Wake up Pattern + InformationBufferLength - Wake Up Pattern Length + + RETURN : + Success - if successful + NDIS_STATUS_FAILURE - if memory allocation fails + + *****************************************************************************/ +NDIS_STATUS MPAddWakeUpPattern( IN PMP_ADAPTER pAdapter, + IN PVOID InfoBuf, + IN UINT InfoBufLen ) +{ + NDIS_STATUS Status; + PNDIS_PM_PACKET_PATTERN pPmPattern = NULL; + UINT Slot = 0, FreeSlot = 0xff; + PUCHAR pNdisPatternMask; + PUINT32 pDevicePatternMask; + UINT16 DevMagicNumber; + UINT i; + + PUCHAR TempBuf; + ULONG offset; + + /*-----------------------------------------------------------------------*/ + + pPmPattern = (PNDIS_PM_PACKET_PATTERN)InfoBuf; + + /************************************************************************** + Check that the wake-up pattern is not too large for us. Also, not + sure how to deal with a pattern whose mask is smaller than the pattern + *************************************************************************/ + if(( pPmPattern->MaskSize < (( pPmPattern->PatternSize / 8) + 1)) || + ( pPmPattern->PatternSize > MAX_WOL_PACKET_SIZE)) + { + return( NDIS_STATUS_RESOURCES ); + } + + NdisAcquireSpinLock( &pAdapter->Lock ); + + /************************************************************************** + Check to see if there is an empty slot on the device to store this + pattern. Store the slot number for later use. + *************************************************************************/ + while ((FreeSlot == 0xff) && (Slot < NUM_WOL_PATTERNS)) + { + if (!((pAdapter->PoMgmt.localWolAndCrc0 >> Slot) & 0x1)) + { + FreeSlot = Slot; + } + else + { + Slot++; + } + } + + if( FreeSlot == 0xff ) + { + /********************************************************************** + Failed to find a free slot. + *********************************************************************/ + NdisReleaseSpinLock( &pAdapter->Lock ); + return( NDIS_STATUS_RESOURCES ); + } + + pNdisPatternMask = (PUCHAR)InfoBuf + sizeof( NDIS_PM_PACKET_PATTERN ); + + /************************************************************************** + Make a copy of what Ndis sent us + *************************************************************************/ + for( i=0; iMaskSize; i++ ) + { + pAdapter->PoMgmt.WOLMaskList[ FreeSlot ][ i ] = pNdisPatternMask[ i ]; + } + + /************************************************************************** + Calculate the CRC that will be used by the device to identify this + packet + *************************************************************************/ + offset = 0; + TempBuf = (PUCHAR)( InfoBuf ) + pPmPattern->PatternOffset; + + DevMagicNumber = MPCalculateCCITCRC16( TempBuf, + (PUCHAR )( InfoBuf ) + + sizeof( NDIS_PM_PACKET_PATTERN ), + pPmPattern->MaskSize ); + + DBGPRINT( MP_SPEC, ( "DevMagicNumber 0x%08x\n", DevMagicNumber )); + DBGPRINT( MP_SPEC, ( "Pattern Size : 0x%08x, MaskSize : 0x%08x\n", + pPmPattern->PatternSize, pPmPattern->MaskSize )); + + pAdapter->PoMgmt.localWolAndCrc0 |= ( 1 << FreeSlot ); + + /************************************************************************** + Now handle storing the pattern in our adapter. Only store what makes + the pattern unique to our device. (the CRC, the mask and the mask + size. The pattern is irrelevant, since it is not stored in the + device). The mask is stored above. + *************************************************************************/ + pAdapter->PoMgmt.WOLPatternList[ FreeSlot ] = DevMagicNumber; + pAdapter->PoMgmt.WOLMaskSize[ FreeSlot ] = pPmPattern->MaskSize; + + NdisReleaseSpinLock( &pAdapter->Lock ); + return( NDIS_STATUS_SUCCESS ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPRemoveWakeUpPattern + ****************************************************************************** + + DESCRIPTION: + This routine will scan the array of wake up patterns and attempt to + match the wake up pattern. If it finds a copy , it will remove that + WakeUpPattern + + PARAMETERS: + pAdapter - pointer to the Adapter structure + InformationBuffer - Wake up Pattern + InformationBufferLength - Wake Up Pattern Length + + RETURN: + Success - if successful. + NDIS_STATUS_FAILURE - if memory allocation fails. + + *****************************************************************************/ +NDIS_STATUS MPRemoveWakeUpPattern( IN PMP_ADAPTER pAdapter, + IN PVOID InformationBuffer, + IN UINT InformationBufferLength ) +{ + + PNDIS_PM_PACKET_PATTERN pPmPattern = NULL; + UINT Slot = 0, FoundSlot = 0xff; + UINT16 DevMagicNumber; + /*-----------------------------------------------------------------------*/ + + pPmPattern = (PNDIS_PM_PACKET_PATTERN)InformationBuffer; + + /************************************************************************** + Check that the wake-up pattern is not too large for us. Also, not + sure how to deal with a pattern whose mask is not the same size + as the pattern. + *************************************************************************/ + if(( pPmPattern->MaskSize < (( pPmPattern->PatternSize / 8) + 1)) || + ( pPmPattern->PatternSize > MAX_WOL_PACKET_SIZE)) + { + return NDIS_STATUS_FAILURE; + } + + /************************************************************************** + Calculate the CRC that will be used by the device to identify this + packet + *************************************************************************/ + DevMagicNumber = MPCalculateCCITCRC16( (PUCHAR )( InformationBuffer ) + + pPmPattern->PatternOffset , + (PUCHAR )( InformationBuffer ) + + sizeof( NDIS_PM_PACKET_PATTERN ), + pPmPattern->MaskSize ); + + NdisAcquireSpinLock( &pAdapter->Lock ); + + while ((FoundSlot == 0xff) && (Slot < NUM_WOL_PATTERNS)) + { + if(( pAdapter->PoMgmt.WOLPatternList[ Slot ] == DevMagicNumber ) && + ( pAdapter->PoMgmt.WOLMaskSize[ Slot ] == pPmPattern->MaskSize ) && + (( pAdapter->PoMgmt.localWolAndCrc0 >> Slot ) & 0x1) ) + { + UINT i; + PUCHAR pIncomingMask = (PUCHAR)( InformationBuffer ) + + sizeof( NDIS_PM_PACKET_PATTERN ); + + for( i=0; iMaskSize; i++ ) + { + if( pAdapter->PoMgmt.WOLMaskList[ Slot ][ i ] != + pIncomingMask[ i ] ) + { + break; + } + } + if( i >= pPmPattern->MaskSize ) + { + FoundSlot = Slot; + } + } + + Slot++; + } + + if( FoundSlot == 0xff ) + { + /********************************************************************** + Failed to find this packet in the list coinciding with a valid + entry in the device. + *********************************************************************/ + NdisReleaseSpinLock( &pAdapter->Lock ); + return( NDIS_STATUS_FAILURE ); + } + + pAdapter->PoMgmt.localWolAndCrc0 &= ~( 1 << FoundSlot ); + + NdisReleaseSpinLock( &pAdapter->Lock ); + + return( NDIS_STATUS_SUCCESS ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MPRemoveAllWakeUpPatterns + ****************************************************************************** + + DESCRIPTION: + This routine disables all wake-up on the device. Probably not + required. + + PARAMETERS: + pAdapter - pointer to the adapter structure + + RETURN: + Nothing + + *****************************************************************************/ +VOID MPRemoveAllWakeUpPatterns( IN PMP_ADAPTER pAdapter ) +{ + RXMAC_WOL_CTL_CRC0_t crc0; + /*-----------------------------------------------------------------------*/ + + if( pAdapter ) + { + NdisAcquireSpinLock( &pAdapter->Lock ); + + pAdapter->PoMgmt.localWolAndCrc0 = 0; + + NdisReleaseSpinLock( &pAdapter->Lock ); + } +} +/*===========================================================================*/ + +#endif --- linux-2.6.28.orig/ubuntu/et131x/et131x_config.c +++ linux-2.6.28/ubuntu/et131x/et131x_config.c @@ -0,0 +1,383 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_config.c - Handles parsing of configuration data during + * initialization. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:46 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + +#include "ET1310_tx.h" + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Defines for Parameter Default/Min/Max vaules + *****************************************************************************/ +#define PARM_SPEED_DUPLEX_DEF 0 +#define PARM_SPEED_DUPLEX_MIN 0 +#define PARM_SPEED_DUPLEX_MAX 5 + +#define PARM_VLAN_TAG_DEF 0 +#define PARM_VLAN_TAG_MIN 0 +#define PARM_VLAN_TAG_MAX 4095 + +#define PARM_FLOW_CTL_DEF 0 +#define PARM_FLOW_CTL_MIN 0 +#define PARM_FLOW_CTL_MAX 3 + +#define PARM_WOL_LINK_DEF 3 +#define PARM_WOL_LINK_MIN 0 +#define PARM_WOL_LINK_MAX 3 + +#define PARM_WOL_MATCH_DEF 7 +#define PARM_WOL_MATCH_MIN 0 +#define PARM_WOL_MATCH_MAX 7 + +#define PARM_JUMBO_PKT_DEF 1514 +#define PARM_JUMBO_PKT_MIN 1514 +#define PARM_JUMBO_PKT_MAX 9216 + +#define PARM_PHY_COMA_DEF 0 +#define PARM_PHY_COMA_MIN 0 +#define PARM_PHY_COMA_MAX 1 + +#define PARM_RX_NUM_BUFS_DEF 4 +#define PARM_RX_NUM_BUFS_MIN 1 +#define PARM_RX_NUM_BUFS_MAX 64 + +#define PARM_RX_TIME_INT_DEF 10 +#define PARM_RX_TIME_INT_MIN 2 +#define PARM_RX_TIME_INT_MAX 320 + +#define PARM_TX_NUM_BUFS_DEF 4 +#define PARM_TX_NUM_BUFS_MIN 1 +#define PARM_TX_NUM_BUFS_MAX 40 + +#define PARM_TX_TIME_INT_DEF 40 +#define PARM_TX_TIME_INT_MIN 1 +#define PARM_TX_TIME_INT_MAX 140 + +#define PARM_RX_MEM_END_DEF 0x2bc +#define PARM_RX_MEM_END_MIN 0 +#define PARM_RX_MEM_END_MAX 0x3ff + +#define PARM_MAC_STAT_DEF 1 +#define PARM_MAC_STAT_MIN 0 +#define PARM_MAC_STAT_MAX 1 + +#define PARM_SC_GAIN_DEF 7 +#define PARM_SC_GAIN_MIN 0 +#define PARM_SC_GAIN_MAX 7 + +#define PARM_PM_WOL_DEF 0 +#define PARM_PM_WOL_MIN 0 +#define PARM_PM_WOL_MAX 1 + +#define PARM_NMI_DISABLE_DEF 0 +#define PARM_NMI_DISABLE_MIN 0 +#define PARM_NMI_DISABLE_MAX 2 + +#define PARM_DMA_CACHE_DEF 0 +#define PARM_DMA_CACHE_MIN 0 +#define PARM_DMA_CACHE_MAX 15 + +#define PARM_PHY_LOOPBK_DEF 0 +#define PARM_PHY_LOOPBK_MIN 0 +#define PARM_PHY_LOOPBK_MAX 1 + + +#define PARM_MAC_ADDRESS_DEF { 0x00, 0x05, 0x3d, 0x00, 0x02, 0x00 } + + + + +/****************************************************************************** + Module parameter for disabling NMI + *****************************************************************************/ +static u32 et131x_nmi_disable = PARM_NMI_DISABLE_DEF; + +module_param ( et131x_nmi_disable, uint, 0 ); +MODULE_PARM_DESC( et131x_nmi_disable, "Disable NMI (0-2) [0]" ); + + +/***************************************************************************** + Module parameter for manual speed setting + ****************************************************************************/ +static u32 et131x_speed_set = PARM_SPEED_DUPLEX_DEF; +module_param (et131x_speed_set, uint, 0); +MODULE_PARM_DESC( et131x_speed_set, "Set Link speed and dublex manually (0-5) [0] \n 1 : 10Mb Half-Duplex \n 2 : 10Mb Full-Duplex \n 3 : 100Mb Half-Duplex \n 4 : 100Mb Full-Duplex \n 5 : 1000Mb Full-Duplex \n 0 : Auto Speed Auto Dublex"); + + +/****************************************************************************** + ROUTINE : et131x_config_parse + ****************************************************************************** + + DESCRIPTION : Parses a configuration from some location (module + parameters, for example) into the private adapter struct + + PARAMETERS : pAdapter - pointer to the private adapter struct + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_config_parse( ET131X_ADAPTER *pAdapter ) +{ + UINT8 macAddrDef[] = PARM_MAC_ADDRESS_DEF; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_config_parse" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + The NDIS driver uses the registry to store persistent per-device + configuration, and reads this configuration into the appropriate + elements of the private adapter structure on initialization. Because + Linux has no analog to the registry, use this function to initialize the + private adapter structure with a default configuration. + + One other possibility is to use a series of module parameters which can + be passed in by the caller when the module is initialized. However, this + implementation does not allow for seperate configurations in the event + multiple devices are present, and hence will not suffice. + + If another method is derived which addresses this problem, this is where + it should be implemented. + *************************************************************************/ + + /************************************************************************** + Set the private adapter struct with default values for the corresponding + parameters + *************************************************************************/ + if( et131x_speed_set != PARM_SPEED_DUPLEX_DEF ) + { + DBG_VERBOSE( et131x_dbginfo, "Speed set manually to : %d \n",et131x_speed_set ); + pAdapter->SpeedDuplex = et131x_speed_set; + } + else + { + pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF; + } + + // pAdapter->SpeedDuplex = PARM_SPEED_DUPLEX_DEF; + + pAdapter->RegistryVlanTag = PARM_VLAN_TAG_DEF; + pAdapter->RegistryFlowControl = PARM_FLOW_CTL_DEF; + pAdapter->RegistryWOLLink = PARM_WOL_LINK_DEF; + pAdapter->RegistryWOLMatch = PARM_WOL_MATCH_DEF; + pAdapter->RegistryJumboPacket = PARM_JUMBO_PKT_DEF; + pAdapter->RegistryPhyComa = PARM_PHY_COMA_DEF; + pAdapter->RegistryRxNumBuffers = PARM_RX_NUM_BUFS_DEF; + pAdapter->RegistryRxTimeInterval = PARM_RX_TIME_INT_DEF; + pAdapter->RegistryTxNumBuffers = PARM_TX_NUM_BUFS_DEF; + pAdapter->RegistryTxTimeInterval = PARM_TX_TIME_INT_DEF; + pAdapter->RegistryRxMemEnd = PARM_RX_MEM_END_DEF; + pAdapter->RegistryMACStat = PARM_MAC_STAT_DEF; + pAdapter->RegistrySCGain = PARM_SC_GAIN_DEF; + pAdapter->RegistryPMWOL = PARM_PM_WOL_DEF; + + if( et131x_nmi_disable != PARM_NMI_DISABLE_DEF ) + { + pAdapter->RegistryNMIDisable = et131x_nmi_disable; + } + else + { + pAdapter->RegistryNMIDisable = PARM_NMI_DISABLE_DEF; + } + + pAdapter->RegistryDMACache = PARM_DMA_CACHE_DEF; + pAdapter->RegistryPhyLoopbk = PARM_PHY_LOOPBK_DEF; + + + /************************************************************************** + Set the MAC address to a default + *************************************************************************/ + memcpy( pAdapter->CurrentAddress, macAddrDef, ETH_ALEN ); + pAdapter->bOverrideAddress = FALSE; + + DBG_TRACE( et131x_dbginfo, + "Default MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n", + pAdapter->CurrentAddress[0], pAdapter->CurrentAddress[1], + pAdapter->CurrentAddress[2], pAdapter->CurrentAddress[3], + pAdapter->CurrentAddress[4], pAdapter->CurrentAddress[5] ); + + + /************************************************************************** + Decode SpeedDuplex + + Set up as if we are auto negotiating always and then change if we go + into force mode + *************************************************************************/ + pAdapter->AiForceSpeed = 0; // Auto speed + pAdapter->AiForceDpx = 0; // Auto FDX + + + /************************************************************************** + If we are the 10/100 device, and gigabit is somehow requested then + knock it down to 100 full. + *************************************************************************/ + if(( pAdapter->DeviceID == ET131X_PCI_DEVICE_ID_FAST ) && + ( pAdapter->SpeedDuplex == 5 )) + { + pAdapter->SpeedDuplex = 4; + } + + + switch( pAdapter->SpeedDuplex ) + { + case 1: // 10Mb Half-Duplex + pAdapter->AiForceSpeed = 10; + pAdapter->AiForceDpx = 1; + break; + + case 2: // 10Mb Full-Duplex + pAdapter->AiForceSpeed = 10; + pAdapter->AiForceDpx = 2; + break; + + case 3: // 100Mb Half-Duplex + pAdapter->AiForceSpeed = 100; + pAdapter->AiForceDpx = 1; + break; + + case 4: // 100Mb Full-Duplex + pAdapter->AiForceSpeed = 100; + pAdapter->AiForceDpx = 2; + break; + + case 5: // 1000Mb Full-Duplex + pAdapter->AiForceSpeed = 1000; + pAdapter->AiForceDpx = 2; + break; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + --- linux-2.6.28.orig/ubuntu/et131x/ET1310_common.h +++ linux-2.6.28/ubuntu/et131x/ET1310_common.h @@ -0,0 +1,97 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310.h - Common defines, structs, enums, prototypes, etc. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:10 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_COMMON_H__ +#define __ET1310_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_address_map.h" + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_COMMON_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_adapter.h +++ linux-2.6.28/ubuntu/et131x/et131x_adapter.h @@ -0,0 +1,508 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_adapter.h - Header which includes the private adapter structure, along + * with related support structures, macros, definitions, etc. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/25 20:48:56 $ + $Revision: 1.15 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_ADAPTER_H__ +#define __ET131X_ADAPTER_H__ + + + + +#include "ET1310_address_map.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" + + + + +/****************************************************************************** + Do not change these values: if changed, then change also in respective + TXdma and Rxdma engines + *****************************************************************************/ +#define NUM_DESC_PER_RING_TX 512 // TX Do not change these values +#define NUM_TCB 64 + + + + +/****************************************************************************** + These values are all superseded by registry entries to facilitate tuning. + Once the desired performance has been achieved, the optimal registry values + should be re-populated to these #defines: + *****************************************************************************/ +#define NUM_TRAFFIC_CLASSES 1 + + + + +/****************************************************************************** + There are three ways of counting errors - if there are more than X errors + in Y packets (represented by the "SAMPLE" macros), if there are more than + N errors in a S mSec time period (the "PERIOD" macros), or if there are + consecutive packets with errors (CONSEC_ERRORED_THRESH). This last covers + for "Bursty" errors, and the errored packets may well not be contiguous, + but several errors where the packet counter has changed by less than a + small amount will cause this count to increment. + *****************************************************************************/ +#define TX_PACKETS_IN_SAMPLE 10000 +#define TX_MAX_ERRORS_IN_SAMPLE 50 + +#define TX_ERROR_PERIOD 1000 +#define TX_MAX_ERRORS_IN_PERIOD 10 + +#define LINK_DETECTION_TIMER 5000 + +#define TX_CONSEC_RANGE 5 +#define TX_CONSEC_ERRORED_THRESH 10 + +#define LO_MARK_PERCENT_FOR_PSR 15 +#define LO_MARK_PERCENT_FOR_RX 15 + + + + +/****************************************************************************** + Macros for flag and ref count operations + *****************************************************************************/ +#define MP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F)) +#define MP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F)) +#define MP_CLEAR_FLAGS(_M) ((_M)->Flags = 0) +#define MP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0) +#define MP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F)) +#define MP_IS_FLAG_CLEAR(_M, _F) (((_M)->Flags & (_F)) == 0) + +#define MP_INC_RCV_REF(_A) atomic_inc(&(_A)->RcvRefCount) +#define MP_DEC_RCV_REF(_A) atomic_dec(&(_A)->RcvRefCount) +#define MP_GET_RCV_REF(_A) atomic_read(&(_A)->RcvRefCount) + + + + +/****************************************************************************** + Macros specific to the private adapter structure + *****************************************************************************/ +#define MP_TCB_RESOURCES_AVAILABLE(_M) ((_M)->TxRing.nBusySend < NUM_TCB) +#define MP_TCB_RESOURCES_NOT_AVAILABLE(_M) ((_M)->TxRing.nBusySend >= NUM_TCB) + +#define MP_SHOULD_FAIL_SEND(_M) ((_M)->Flags & fMP_ADAPTER_FAIL_SEND_MASK) +#define MP_IS_NOT_READY(_M) ((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK) +#define MP_IS_READY(_M) !((_M)->Flags & fMP_ADAPTER_NOT_READY_MASK) + +#define MP_HAS_CABLE(_M) !((_M)->Flags & fMP_ADAPTER_NO_CABLE) +#define MP_LINK_DETECTED(_M) !((_M)->Flags & fMP_ADAPTER_LINK_DETECTION) + + + + +/****************************************************************************** + Counters for error rate monitoring + *****************************************************************************/ +typedef struct _MP_ERR_COUNTERS +{ + UINT32 PktCountTxPackets; + UINT32 PktCountTxErrors; + UINT32 TimerBasedTxErrors; + UINT32 PktCountLastError; + UINT32 ErredConsecPackets; +} MP_ERR_COUNTERS, *PMP_ERR_COUNTERS; + + + + +/****************************************************************************** + RFD (Receive Frame Descriptor) + *****************************************************************************/ +typedef struct _MP_RFD +{ + struct list_head list_node; + struct sk_buff *Packet; + UINT32 PacketSize; // total size of receive frame + UINT16 iBufferIndex; + UINT8 iRingIndex; +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + BOOL_t bHasVLANTag; + UINT16 VLANTag; +#endif +} MP_RFD, *PMP_RFD; + + + + +/****************************************************************************** + Enum for Flow Control + *****************************************************************************/ +typedef enum _eflow_control_t { + Both = 0, + TxOnly = 1, + RxOnly = 2, + None = 3 +} eFLOW_CONTROL_t, *PeFLOW_CONTROL_t; + + + + +/****************************************************************************** + Struct to define some device statistics + *****************************************************************************/ +typedef struct _ce_stats_t +{ + /************************************************************************** + Link Input/Output stats + *************************************************************************/ + UINT64 ipackets; // # of in packets + UINT64 opackets; // # of out packets + + + /************************************************************************** + MIB II variables + *************************************************************************/ + /************************************************************************** + NOTE - atomic_t types are only guaranteed to store 24-bits; if we MUST + have 32, then we'll need another way to perform atomic operations + *************************************************************************/ + UINT32 unircv; // # multicast packets received + atomic_t unixmt; // # multicast packets for Tx + UINT32 multircv; // # multicast packets received + atomic_t multixmt; // # multicast packets for Tx + UINT32 brdcstrcv; // # broadcast packets received + atomic_t brdcstxmt; // # broadcast packets for Tx + UINT32 norcvbuf; // # Rx packets discarded + UINT32 noxmtbuf; // # Tx packets discarded + + + /************************************************************************** + Transciever state informations. + *************************************************************************/ + UINT32 xcvr_addr; + UINT32 xcvr_id; + + + /************************************************************************** + Tx Statistics. + *************************************************************************/ + UINT32 tx_uflo; //Tx Underruns + + UINT32 collisions; + UINT32 excessive_collisions; + UINT32 first_collision; + UINT32 late_collisions; + UINT32 max_pkt_error; + UINT32 tx_deferred; + + + /************************************************************************** + Rx Statistics. + *************************************************************************/ + UINT32 rx_ov_flow; //Rx Over Flow + + UINT32 length_err; + UINT32 alignment_err; + UINT32 crc_err; + UINT32 code_violations; + UINT32 other_errors; + +#ifdef ET131X_DBG + UINT32 UnhandledInterruptsPerSec; + UINT32 RxDmaInterruptsPerSec; + UINT32 TxDmaInterruptsPerSec; + UINT32 WatchDogInterruptsPerSec; +#endif /* ET131X_DBG */ + + UINT32 SynchrounousIterations; + INT_STATUS_t InterruptStatus; +} +CE_STATS_t, *PCE_STATS_t; + + + + +/****************************************************************************** + The private adapter structure + *****************************************************************************/ +typedef struct et131x_adapter +{ + struct net_device *netdev; + struct pci_dev *pdev; + + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + struct tq_struct task; +#else + struct work_struct task; +#endif + + + /************************************************************************** + Flags that indicate current state of the adapter + *************************************************************************/ + UINT32 Flags; + UINT32 HwErrCount; + + + /************************************************************************** + Configuration + *************************************************************************/ + UCHAR PermanentAddress[ETH_ALEN]; + UCHAR CurrentAddress[ETH_ALEN]; + BOOL_t bOverrideAddress; + BOOL_t bEepromPresent; + UCHAR eepromData[2]; + + + /************************************************************************** + Spinlocks + *************************************************************************/ + spinlock_t Lock; + + spinlock_t TCBSendQLock; + spinlock_t TCBReadyQLock; + spinlock_t SendHWLock; + spinlock_t SendWaitLock; + + spinlock_t RcvLock; + spinlock_t RcvPendLock; + spinlock_t FbrLock; + + spinlock_t PHYLock; + + + /************************************************************************** + Packet Filter and look ahead size + *************************************************************************/ + UINT32 PacketFilter; + UINT32 ulLookAhead; + UINT32 uiLinkSpeed; + UINT32 uiDuplexMode; + UINT32 uiAutoNegStatus; + UCHAR ucLinkStatus; + + + /************************************************************************** + multicast list + *************************************************************************/ + UINT32 MCAddressCount; + UCHAR MCList[NIC_MAX_MCAST_LIST][ETH_ALEN]; + + + /************************************************************************** + MAC test + *************************************************************************/ + TXMAC_TXTEST_t TxMacTest; + + + /************************************************************************** + Pointer to the device's PCI register space + *************************************************************************/ + ADDRESS_MAP_t *CSRAddress; + + + /************************************************************************** + PCI config space info, for debug purposes only. + *************************************************************************/ + UCHAR RevisionID; + UINT16 VendorID; + UINT16 DeviceID; + UINT16 SubVendorID; + UINT16 SubSystemID; + UINT32 CacheFillSize; + UINT16 PciXDevCtl; + UCHAR pci_lat_timer; + UCHAR pci_hdr_type; + UCHAR pci_bist; + UINT32 pci_cfg_state[64 / sizeof(u32)]; + + + /************************************************************************** + Registry parameters + *************************************************************************/ + UCHAR SpeedDuplex; // speed/duplex + eFLOW_CONTROL_t RegistryFlowControl; // for 802.3x flow control + UCHAR RegistryWOLMatch; // Enable WOL pattern-matching + UCHAR RegistryWOLLink; // Link state change is independant + UCHAR RegistryPhyComa; // Phy Coma mode enable/disable + + UINT32 RegistryRxMemEnd; // Size of internal rx memory + UCHAR RegistryMACStat; // If set, read MACSTAT, else don't + UINT32 RegistryVlanTag; // 802.1q Vlan TAG + UINT32 RegistryJumboPacket; // Max supported ethernet packet size + + UINT32 RegistryTxNumBuffers; + UINT32 RegistryTxTimeInterval; + + UINT32 RegistryRxNumBuffers; + UINT32 RegistryRxTimeInterval; + + + /************************************************************************** + Validation helpers + *************************************************************************/ + UCHAR RegistryPMWOL; + UCHAR RegistryNMIDisable; + UINT32 RegistryDMACache; + UINT32 RegistrySCGain; + UCHAR RegistryPhyLoopbk; // Enable Phy loopback + + + /************************************************************************** + Derived from the registry: + *************************************************************************/ + UCHAR AiForceDpx; // duplex setting + UINT16 AiForceSpeed; // 'Speed', user over-ride of line speed + eFLOW_CONTROL_t FlowControl; // flow control validated by the far-end + NETIF_STATUS MediaState; + UCHAR DriverNoPhyAccess; + + + /************************************************************************** + Minimize init-time + *************************************************************************/ + BOOL_t bQueryPending; + BOOL_t bSetPending; + BOOL_t bResetPending; + struct timer_list ErrorTimer; + BOOL_t bLinkTimerActive; + MP_POWER_MGMT PoMgmt; + INT_MASK_t CachedMaskValue; + + atomic_t RcvRefCount; // Num packets not yet returned + + + /************************************************************************** + Xcvr status at last poll + *************************************************************************/ + MI_BMSR_t Bmsr; + + + /************************************************************************** + Tx Memory Variables + *************************************************************************/ + TX_RING_t TxRing; + + + /************************************************************************** + Rx Memory Variables + *************************************************************************/ + RX_RING_t RxRing; + + + /************************************************************************** + ET1310 register Access + *************************************************************************/ + JAGCORE_ACCESS_REGS JagCoreRegs; + PCI_CFG_SPACE_REGS PciCfgRegs; + + + /************************************************************************** + Loopback specifics + *************************************************************************/ + UCHAR ReplicaPhyLoopbk; // Replica Enable + UCHAR ReplicaPhyLoopbkPF; // Replica Enable Pass/Fail + + + /************************************************************************** + Stats + *************************************************************************/ + CE_STATS_t Stats; + + struct net_device_stats net_stats; + struct net_device_stats net_stats_prev; + + + /************************************************************************** + VLAN + *************************************************************************/ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + struct vlan_group *vlgrp; +#endif + + /************************************************************************** + Data to support workaround for bad config space addresses; see + et131x_pci_setup() for more information + *************************************************************************/ + BOOL_t pci_bar_workaround; + unsigned long pci_bar_addr_orig; +} ET131X_ADAPTER, *PET131X_ADAPTER; + + + + +#define MPSendPacketsHandler MPSendPackets +#define MP_FREE_SEND_PACKET_FUN(Adapter, pMpTcb) et131x_free_send_packet(Adapter, pMpTcb) +#define MpSendPacketFun(Adapter,Packet) MpSendPacket(Adapter, Packet) + + + + +#endif /* __ET131X_ADAPTER_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_rx.c +++ linux-2.6.28/ubuntu/et131x/ET1310_rx.c @@ -0,0 +1,2056 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_rx.c - Routines used to perform data reception + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.21 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + +#include "ET1310_rx.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions local to this module + *****************************************************************************/ +void nic_return_rfd( ET131X_ADAPTER *pAdapter, PMP_RFD pMpRfd ); + + + + +/****************************************************************************** + ROUTINE : et131x_rx_dma_memory_alloc + ****************************************************************************** + + DESCRIPTION : Allocates Free buffer ring 1 for sure, free buffer ring + 0 if required, and the Packet Status Ring + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_rx_dma_memory_alloc( ET131X_ADAPTER *adapter ) +{ + UINT32 OuterLoop, InnerLoop; + UINT32 bufsize; + UINT32 pktStatRingSize, FBRChunkSize; + RX_RING_t *rx_ring; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_rx_dma_memory_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + rx_ring = (RX_RING_t *)&adapter->RxRing; + + + /************************************************************************** + Alloc memory for the lookup table + *************************************************************************/ +#ifdef USE_FBR0 + rx_ring->Fbr[0] = kmalloc( sizeof( FBRLOOKUPTABLE ), GFP_KERNEL ); +#endif + + rx_ring->Fbr[1] = kmalloc( sizeof( FBRLOOKUPTABLE ), GFP_KERNEL ); + + + /************************************************************************** + The first thing we will do is configure the sizes of the buffer rings. + These will change based on jumbo packet support. Larger jumbo packets + increases the size of each entry in FBR0, and the number of entries in + FBR0, while at the same time decreasing the number of entries in FBR1. + + FBR1 holds "large" frames, FBR0 holds "small" frames. If FBR1 entries + are huge in order to accomodate a "jumbo" frame, then it will have less + entries. Conversely, FBR1 will now be relied upon to carry more + "normal" frames, thus it's entry size also increases and the number + of entries goes up too (since it now carries "small" + "regular" + packets. + + In this scheme, we try to maintain 512 entries between the two rings. + Also, FBR1 remains a constant size - when it's size doubles the + number of entries halves. FBR0 increases in size, however. + *************************************************************************/ + + if( adapter->RegistryJumboPacket < 2048 ) + { +#ifdef USE_FBR0 + rx_ring->Fbr0BufferSize = 256; + rx_ring->Fbr0NumEntries = 512; +#endif + rx_ring->Fbr1BufferSize = 2048; + rx_ring->Fbr1NumEntries = 512; + } + else if( adapter->RegistryJumboPacket < 4096 ) + { +#ifdef USE_FBR0 + rx_ring->Fbr0BufferSize = 512; + rx_ring->Fbr0NumEntries = 1024; +#endif + rx_ring->Fbr1BufferSize = 4096; + rx_ring->Fbr1NumEntries = 512; + } + else + { +#ifdef USE_FBR0 + rx_ring->Fbr0BufferSize = 1024; + rx_ring->Fbr0NumEntries = 768; +#endif + rx_ring->Fbr1BufferSize = 16384; + rx_ring->Fbr1NumEntries = 128; + } + +#ifdef USE_FBR0 + adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr0NumEntries + + adapter->RxRing.Fbr1NumEntries; +#else + adapter->RxRing.PsrNumEntries = adapter->RxRing.Fbr1NumEntries; +#endif + + + /************************************************************************** + Allocate an area of memory for Free Buffer Ring 1 + *************************************************************************/ + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr1NumEntries) + 0xfff; + rx_ring->pFbr1RingVa = pci_alloc_consistent( adapter->pdev, + bufsize, + &rx_ring->pFbr1RingPa ); + if( !rx_ring->pFbr1RingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Free Buffer Ring 1\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + rx_ring->Fbr1Realpa = rx_ring->pFbr1RingPa; + + + /************************************************************************** + Align Free Buffer Ring 1 on a 4K boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->Fbr1Realpa, + &rx_ring->Fbr1offset, + 0x0FFF ); + + rx_ring->pFbr1RingVa = (void *)( (PUCHAR)rx_ring->pFbr1RingVa + + rx_ring->Fbr1offset ); + + +#ifdef USE_FBR0 + /************************************************************************** + Allocate an area of memory for Free Buffer Ring 0 + *************************************************************************/ + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr0NumEntries ) + 0xfff; + rx_ring->pFbr0RingVa = pci_alloc_consistent( adapter->pdev, + bufsize, + &rx_ring->pFbr0RingPa ); + if( !rx_ring->pFbr0RingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Free Buffer Ring 0\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + rx_ring->Fbr0Realpa = rx_ring->pFbr0RingPa; + + + /************************************************************************** + Align Free Buffer Ring 0 on a 4K boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->Fbr0Realpa, + &rx_ring->Fbr0offset, + 0x0FFF ); + + rx_ring->pFbr0RingVa = (void *)( (PUCHAR)rx_ring->pFbr0RingVa + + rx_ring->Fbr0offset ); + +#endif + + + for( OuterLoop = 0; OuterLoop < (rx_ring->Fbr1NumEntries / FBR_CHUNKS); OuterLoop++ ) + { + UINT64 Fbr1Offset; + UINT64 Fbr1TempPa; + UINT32 Fbr1Align; + + /********************************************************************** + This code allocates an area of memory big enough for N free + buffers + (buffer_size - 1) so that the buffers can be aligned + on 4k boundaries. If each buffer were aligned + to a buffer_size boundary, the effect would be to double the size + of FBR0. By allocating N buffers at once, we reduce this overhead. + *********************************************************************/ + if( rx_ring->Fbr1BufferSize > 4096 ) + { + Fbr1Align = 4096; + } + else + { + Fbr1Align = rx_ring->Fbr1BufferSize; + } + + FBRChunkSize = ( FBR_CHUNKS * rx_ring->Fbr1BufferSize ) + Fbr1Align - 1; + rx_ring->Fbr1MemVa[OuterLoop] = pci_alloc_consistent( adapter->pdev, + FBRChunkSize, + &rx_ring->Fbr1MemPa[OuterLoop] ); + + if( !rx_ring->Fbr1MemVa[OuterLoop] ) + { + DBG_ERROR( et131x_dbginfo, "Could not alloc memory\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /********************************************************************** + See NOTE in "Save Physical Address" comment above + *********************************************************************/ + Fbr1TempPa = rx_ring->Fbr1MemPa[OuterLoop]; + + et131x_align_allocated_memory( adapter, + &Fbr1TempPa, + &Fbr1Offset, + (Fbr1Align - 1)); + + + for( InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++ ) + { + UINT32 index = (OuterLoop * FBR_CHUNKS) + InnerLoop; + + + /****************************************************************** + Save the Virtual address of this index for quick access later + *****************************************************************/ + rx_ring->Fbr[1]->Va[index] = (PUCHAR)rx_ring->Fbr1MemVa[OuterLoop] + + ( InnerLoop * rx_ring->Fbr1BufferSize ) + + Fbr1Offset; + + + /****************************************************************** + now store the physical address in the descriptor so the device + can access it + *****************************************************************/ + rx_ring->Fbr[1]->PAHigh[index] = (UINT32)(Fbr1TempPa >> 32); + rx_ring->Fbr[1]->PALow[index] = (UINT32) Fbr1TempPa; + + Fbr1TempPa += rx_ring->Fbr1BufferSize; + + rx_ring->Fbr[1]->Buffer1[index] = rx_ring->Fbr[1]->Va[index]; + rx_ring->Fbr[1]->Buffer2[index] = rx_ring->Fbr[1]->Va[index] - 4; + } + } + +#ifdef USE_FBR0 + /************************************************************************** + Same for FBR0 (if in use) + *************************************************************************/ + for( OuterLoop = 0; OuterLoop < (rx_ring->Fbr0NumEntries / FBR_CHUNKS); OuterLoop++ ) + { + UINT64 Fbr0Offset; + UINT64 Fbr0TempPa; + + FBRChunkSize = (( FBR_CHUNKS + 1 ) * rx_ring->Fbr0BufferSize ) - 1; + rx_ring->Fbr0MemVa[OuterLoop] = pci_alloc_consistent( adapter->pdev, + FBRChunkSize, + &rx_ring->Fbr0MemPa[OuterLoop] ); + + if( !rx_ring->Fbr0MemVa[OuterLoop] ) + { + DBG_ERROR( et131x_dbginfo, "Could not alloc memory\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /********************************************************************** + See NOTE in "Save Physical Address" comment above + *********************************************************************/ + Fbr0TempPa = rx_ring->Fbr0MemPa[OuterLoop]; + + et131x_align_allocated_memory( adapter, + &Fbr0TempPa, + &Fbr0Offset, + rx_ring->Fbr0BufferSize - 1 ); + + + for( InnerLoop = 0; InnerLoop < FBR_CHUNKS; InnerLoop++ ) + { + UINT32 index = (OuterLoop * FBR_CHUNKS) + InnerLoop; + + rx_ring->Fbr[0]->Va[index] = (PUCHAR)rx_ring->Fbr0MemVa[OuterLoop] + + ( InnerLoop * rx_ring->Fbr0BufferSize ) + + Fbr0Offset; + + rx_ring->Fbr[0]->PAHigh[index] = (UINT32)(Fbr0TempPa >> 32); + rx_ring->Fbr[0]->PALow[index] = (UINT32) Fbr0TempPa; + + Fbr0TempPa += rx_ring->Fbr0BufferSize; + + rx_ring->Fbr[0]->Buffer1[index] = rx_ring->Fbr[0]->Va[index]; + rx_ring->Fbr[0]->Buffer2[index] = rx_ring->Fbr[0]->Va[index] - 4; + } + } +#endif + + /************************************************************************** + Allocate an area of memory for the FIFO of Packet Status ring entries + *************************************************************************/ + pktStatRingSize = sizeof( PKT_STAT_DESC_t ) * adapter->RxRing.PsrNumEntries; + + rx_ring->pPSRingVa = pci_alloc_consistent( adapter->pdev, + pktStatRingSize + 0x0fff, + &rx_ring->pPSRingPa ); + + if( !rx_ring->pPSRingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Packet Status Ring\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + rx_ring->pPSRingRealPa = rx_ring->pPSRingPa; + + + /************************************************************************** + Align Packet Status Ring on a 4K boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->pPSRingRealPa, + &rx_ring->pPSRingOffset, + 0x0FFF ); + + rx_ring->pPSRingVa = (void *)( (PUCHAR)rx_ring->pPSRingVa + + rx_ring->pPSRingOffset ); + + + /************************************************************************** + Allocate an area of memory for the writeback of status information + *************************************************************************/ + rx_ring->pRxStatusVa = pci_alloc_consistent( adapter->pdev, + sizeof( RX_STATUS_BLOCK_t ) + 0x7, + &rx_ring->pRxStatusPa ); + if( !rx_ring->pRxStatusVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Status Block\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + *************************************************************************/ + rx_ring->RxStatusRealPA = rx_ring->pRxStatusPa; + + + /************************************************************************** + Align write back on an 8 byte boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &rx_ring->RxStatusRealPA, + &rx_ring->RxStatusOffset, + 0x07 ); + + rx_ring->pRxStatusVa = (void *)( (PUCHAR)rx_ring->pRxStatusVa + + rx_ring->RxStatusOffset ); + rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; + + + /************************************************************************** + Recv + pci_pool_create initializes a lookaside list. + After successful creation, nonpaged fixed-size blocks can be + allocated from and freed to the lookaside list. + + RFDs will be allocated from this pool. + *************************************************************************/ + rx_ring->RecvLookaside = + #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + kmem_cache_create( adapter->netdev->name, + sizeof( MP_RFD ), + 0, + SLAB_CACHE_DMA | + SLAB_HWCACHE_ALIGN, + NULL, + NULL ); + #endif + #if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)) + kmem_cache_create( adapter->netdev->name, + sizeof( MP_RFD ), + 0, + SLAB_CACHE_DMA | + SLAB_HWCACHE_ALIGN, + NULL); + #endif + + MP_SET_FLAG( adapter, fMP_ADAPTER_RECV_LOOKASIDE ); + + + /************************************************************************** + The RFDs are going to be put on lists later on, so initialize the lists + now. + *************************************************************************/ + INIT_LIST_HEAD( &rx_ring->RecvList ); + INIT_LIST_HEAD( &rx_ring->RecvPendingList ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_rx_dma_memory_free + ****************************************************************************** + + DESCRIPTION : Should basically free all memory allocated within this + module. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_rx_dma_memory_free( ET131X_ADAPTER *adapter ) +{ + UINT32 index; + UINT32 bufsize; + UINT32 pktStatRingSize; + PMP_RFD pMpRfd; + RX_RING_t *rx_ring; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_rx_dma_memory_free" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + rx_ring = (RX_RING_t *)&adapter->RxRing; + + + /************************************************************************** + Free RFDs and associated packet descriptors + *************************************************************************/ + DBG_ASSERT( rx_ring->nReadyRecv == rx_ring->NumRfd ); + + while( !list_empty( &rx_ring->RecvList )) + { + pMpRfd = (MP_RFD *)list_entry( rx_ring->RecvList.next, + MP_RFD, + list_node ); + + list_del( &pMpRfd->list_node ); + et131x_rfd_resources_free( adapter, pMpRfd ); + } + + while( !list_empty( &rx_ring->RecvPendingList )) + { + pMpRfd = (MP_RFD *)list_entry( rx_ring->RecvPendingList.next, + MP_RFD, + list_node ); + list_del( &pMpRfd->list_node ); + et131x_rfd_resources_free( adapter, pMpRfd ); + } + + + /************************************************************************** + Free Free Buffer Ring 1 + *************************************************************************/ + if( rx_ring->pFbr1RingVa ) + { + /********************************************************************** + First the packet memory + *********************************************************************/ + for( index = 0; index < + (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++ ) + { + if( rx_ring->Fbr1MemVa[index] ) + { + UINT32 Fbr1Align; + + if( rx_ring->Fbr1BufferSize > 4096 ) + { + Fbr1Align = 4096; + } + else + { + Fbr1Align = rx_ring->Fbr1BufferSize; + } + + bufsize = ( rx_ring->Fbr1BufferSize * FBR_CHUNKS ) + + Fbr1Align - 1; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->Fbr1MemVa[index], + rx_ring->Fbr1MemPa[index] ); + + rx_ring->Fbr1MemVa[index] = 0; + } + } + + + /********************************************************************** + Now the FIFO itself + *********************************************************************/ + rx_ring->pFbr1RingVa = (void *)( (PUCHAR)rx_ring->pFbr1RingVa - + rx_ring->Fbr1offset ); + + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr1NumEntries ) + 0xfff; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->pFbr1RingVa, + rx_ring->pFbr1RingPa ); + + rx_ring->pFbr1RingVa = NULL; + } + + +#ifdef USE_FBR0 + /********************************************************************** + Now the same for Free Buffer Ring 0 + *********************************************************************/ + if( rx_ring->pFbr0RingVa ) + { + /********************************************************************** + First the packet memory + *********************************************************************/ + for( index = 0; index < + (rx_ring->Fbr0NumEntries / FBR_CHUNKS); index++ ) + { + if( rx_ring->Fbr0MemVa[index] ) + { + bufsize = ( rx_ring->Fbr0BufferSize * ( FBR_CHUNKS + 1 )) - 1; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->Fbr0MemVa[index], + rx_ring->Fbr0MemPa[index] ); + + rx_ring->Fbr0MemVa[index] = 0; + } + } + + + /********************************************************************** + Now the FIFO itself + *********************************************************************/ + rx_ring->pFbr0RingVa = (void *)( (PUCHAR)rx_ring->pFbr0RingVa - + rx_ring->Fbr0offset ); + + bufsize = ( sizeof( FBR_DESC_t ) * rx_ring->Fbr0NumEntries ) + 0xfff; + + pci_free_consistent( adapter->pdev, + bufsize, + rx_ring->pFbr0RingVa, + rx_ring->pFbr0RingPa ); + + rx_ring->pFbr0RingVa = NULL; + } +#endif + + + /************************************************************************** + Free Packet Status Ring + *************************************************************************/ + if( rx_ring->pPSRingVa ) + { + rx_ring->pPSRingVa = (void *)( (PUCHAR)rx_ring->pPSRingVa - + rx_ring->pPSRingOffset ); + + pktStatRingSize = sizeof( PKT_STAT_DESC_t ) * adapter->RxRing.PsrNumEntries; + + pci_free_consistent( adapter->pdev, + pktStatRingSize + 0x0fff, + rx_ring->pPSRingVa, + rx_ring->pPSRingPa ); + + rx_ring->pPSRingVa = NULL; + } + + + /********************************************************************** + Free area of memory for the writeback of status information + *********************************************************************/ + if( rx_ring->pRxStatusVa ) + { + rx_ring->pRxStatusVa = (void *)( (PUCHAR)rx_ring->pRxStatusVa - + rx_ring->RxStatusOffset ); + + pci_free_consistent( adapter->pdev, + sizeof( RX_STATUS_BLOCK_t ) + 0x7, + rx_ring->pRxStatusVa, + rx_ring->pRxStatusPa ); + + rx_ring->pRxStatusVa = NULL; + } + + + /************************************************************************** + Free receive buffer pool + *************************************************************************/ + + + /************************************************************************** + Free receive packet pool + *************************************************************************/ + + + /************************************************************************** + Destroy the lookaside (RFD) pool + *************************************************************************/ + if( MP_TEST_FLAG( adapter, fMP_ADAPTER_RECV_LOOKASIDE )) + { + kmem_cache_destroy( rx_ring->RecvLookaside ); + MP_CLEAR_FLAG( adapter, fMP_ADAPTER_RECV_LOOKASIDE ); + } + + + /************************************************************************** + Free the FBR Lookup Table + *************************************************************************/ +#ifdef USE_FBR0 + kfree( rx_ring->Fbr[0] ); +#endif + + kfree( rx_ring->Fbr[1] ); + + + /************************************************************************** + Reset Counters + *************************************************************************/ + rx_ring->nReadyRecv = 0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_init_recv + ****************************************************************************** + + DESCRIPTION : Initialize receive data structures. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_init_recv( ET131X_ADAPTER *adapter ) +{ + int status = -ENOMEM; + PMP_RFD pMpRfd = NULL; + UINT32 RfdCount; + UINT32 TotalNumRfd = 0; + RX_RING_t *rx_ring = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_init_recv" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + rx_ring = (RX_RING_t *)&adapter->RxRing; + + + /************************************************************************** + Setup each RFD + *************************************************************************/ + for( RfdCount = 0; RfdCount < rx_ring->NumRfd; RfdCount++ ) + { + pMpRfd = ( MP_RFD * )kmem_cache_alloc( rx_ring->RecvLookaside, + GFP_ATOMIC | GFP_DMA ); + + if( !pMpRfd ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc RFD out of kmem_cache\n" ); + + status = -ENOMEM; + continue; + } + + status = et131x_rfd_resources_alloc( adapter,pMpRfd ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc packet for RFD\n" ); + kmem_cache_free( rx_ring->RecvLookaside, pMpRfd ); + continue; + } + + + /********************************************************************** + Add this RFD to the RecvList + *********************************************************************/ + list_add_tail( &pMpRfd->list_node, &rx_ring->RecvList ); + + + /********************************************************************** + Increment both the available RFD's, and the total RFD's. + *********************************************************************/ + rx_ring->nReadyRecv++; + TotalNumRfd++; + } + + if( TotalNumRfd > NIC_MIN_NUM_RFD ) + { + status = 0; + } + + rx_ring->NumRfd = TotalNumRfd; + + if( status != 0 ) + { + kmem_cache_free( rx_ring->RecvLookaside, pMpRfd ); + DBG_ERROR( et131x_dbginfo, "Allocation problems in et131x_init_recv\n" ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_rfd_resources_alloc + ****************************************************************************** + + DESCRIPTION : + + PARAMETERS : adapter - pointer to our private adapter structure + pMpRfd - pointer to a RFD + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_rfd_resources_alloc( ET131X_ADAPTER *adapter, MP_RFD *pMpRfd ) +{ + pMpRfd->Packet = NULL; + + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_rfd_resources_free + ****************************************************************************** + + DESCRIPTION : Free the packet allocated for the given RFD + + PARAMETERS : adapter - pointer to our private adapter structure + pMpRfd - pointer to a RFD + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_rfd_resources_free( ET131X_ADAPTER *adapter, MP_RFD *pMpRfd ) +{ + pMpRfd->Packet = NULL; + kmem_cache_free( adapter->RxRing.RecvLookaside, pMpRfd ); + + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: ConfigRxDmaRegs + ****************************************************************************** + DESCRIPTION: + START OF Rx_DMA INIT SEQUENCE + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + + + *****************************************************************************/ +void ConfigRxDmaRegs( ET131X_ADAPTER *pAdapter ) +{ + PRXDMA_t pRxDma; + PFBR_DESC_t pFbrEntry; + UINT32 iEntry; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigRxDmaRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get our pointer to the RxDma section of regs + *************************************************************************/ + pRxDma = &pAdapter->CSRAddress->rxdma; + + + /************************************************************************** + Halt RXDMA to perform the reconfigure. + *************************************************************************/ + et131x_rx_dma_disable( pAdapter ); + + + /************************************************************************** + Load the completion writeback physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + pRxDma->dma_wb_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.RxStatusRealPA >> 32 ); + pRxDma->dma_wb_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.RxStatusRealPA ); + + memset( pAdapter->RxRing.pRxStatusVa, 0, sizeof( RX_STATUS_BLOCK_t )); + + + /************************************************************************** + Set the address and parameters of the packet status ring into the 1310's + registers + *************************************************************************/ + pRxDma->psr_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.pPSRingRealPa >> 32 ); + pRxDma->psr_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.pPSRingRealPa ); + + pRxDma->psr_num_des.value = pAdapter->RxRing.PsrNumEntries - 1; + + pRxDma->psr_full_offset.value = 0; + + pRxDma->psr_min_des.value = + ( pRxDma->psr_num_des.bits.psr_ndes * LO_MARK_PERCENT_FOR_PSR ) / 100; + + spin_lock_irqsave( &pAdapter->RcvLock, lockflags ); + + + /************************************************************************** + These local variables track the PSR in the adapter structure + *************************************************************************/ + pAdapter->RxRing.local_psr_full.bits.psr_full = 0; + pAdapter->RxRing.local_psr_full.bits.psr_full_wrap = 0; + + + /************************************************************************** + Now's the best time to initialize FBR1 contents + *************************************************************************/ + pFbrEntry = (PFBR_DESC_t) pAdapter->RxRing.pFbr1RingVa; + + for (iEntry=0; iEntry < pAdapter->RxRing.Fbr1NumEntries; iEntry++) + { + pFbrEntry->addr_hi = pAdapter->RxRing.Fbr[1]->PAHigh[ iEntry ]; + pFbrEntry->addr_lo = pAdapter->RxRing.Fbr[1]->PALow [ iEntry ]; + pFbrEntry->word2.bits.bi = iEntry; + pFbrEntry++; + } + + + /************************************************************************** + Set the address and parameters of Free buffer ring 1 (and 0 if required) + into the 1310's registers + *************************************************************************/ + pRxDma->fbr1_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.Fbr1Realpa >> 32 ); + pRxDma->fbr1_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.Fbr1Realpa ); + + pRxDma->fbr1_num_des.value = pAdapter->RxRing.Fbr1NumEntries - 1; + + { + RXDMA_FBR_FULL_OFFSET_t fbr1_full; + + fbr1_full.bits.fbr_full = 0; + fbr1_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr1_full_offset = fbr1_full; + } + + + /************************************************************************** + This variable tracks the free buffer ring 1 full position, so it has to + match the above. + *************************************************************************/ + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr1_min_des.bits.fbr_min = + (( pAdapter->RxRing.Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX ) / 100) - 1; + + +#ifdef USE_FBR0 + /************************************************************************** + Now's the best time to initialize FBR0 contents + *************************************************************************/ + pFbrEntry = (PFBR_DESC_t) pAdapter->RxRing.pFbr0RingVa; + + for (iEntry=0; iEntry < pAdapter->RxRing.Fbr0NumEntries; iEntry++) + { + pFbrEntry->addr_hi = pAdapter->RxRing.Fbr[0]->PAHigh[iEntry]; + pFbrEntry->addr_lo = pAdapter->RxRing.Fbr[0]->PALow [iEntry]; + pFbrEntry->word2.bits.bi = iEntry; + pFbrEntry++; + } + + pRxDma->fbr0_base_hi.addr_hi = (UINT32)( pAdapter->RxRing.Fbr0Realpa >> 32 ); + pRxDma->fbr0_base_lo.addr_lo = (UINT32)( pAdapter->RxRing.Fbr0Realpa ); + + pRxDma->fbr0_num_des.bits.fbr_ndesc = pAdapter->RxRing.Fbr0NumEntries - 1; + + { + RXDMA_FBR_FULL_OFFSET_t fbr0_full; + + fbr0_full.bits.fbr_full = 0; + fbr0_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr0_full_offset = fbr0_full; + } + + + /************************************************************************** + This variable tracks the free buffer ring 0 full position, so it has to + match the above. + *************************************************************************/ + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full_wrap = 1; + + pRxDma->fbr0_min_des.bits.fbr_min = + (( pAdapter->RxRing.Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX ) / 100) - 1; +#endif + + + /************************************************************************** + Program the number of packets we will receive before generating an + interrupt. + + For version B silicon, this value gets updated once autoneg is complete. + *************************************************************************/ + pRxDma->num_pkt_done.value = pAdapter->RegistryRxNumBuffers; + + + /************************************************************************** + The "time_done" is not working correctly to coalesce interrupts after + a given time period, but rather is giving us an interrupt regardless + of whether we have received packets. + + This value gets updated once autoneg is complete. + *************************************************************************/ + pRxDma->max_pkt_time.value = pAdapter->RegistryRxTimeInterval; + + spin_unlock_irqrestore( &pAdapter->RcvLock, lockflags ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: SetRxDmaTimer + ****************************************************************************** + DESCRIPTION: + SET the heartbeat timer according to line rate. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + N/A + + *****************************************************************************/ +void SetRxDmaTimer( ET131X_ADAPTER *pAdapter ) +{ + /************************************************************************** + For version B silicon, we do not use the RxDMA timer for 10 and 100 + Mbits/s line rates. We do not enable and RxDMA interrupt coalescing. + *************************************************************************/ + if(( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS ) || + ( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS )) + { + pAdapter->CSRAddress->rxdma.max_pkt_time.value = 0; + pAdapter->CSRAddress->rxdma.num_pkt_done.value = 1; + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_rx_dma_disable + ****************************************************************************** + DESCRIPTION: + Stop OF Rx_DMA on the ET1310 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + + + *****************************************************************************/ +void et131x_rx_dma_disable( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_rx_dma_disable" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup the receive dma configuration register + *************************************************************************/ + pAdapter->CSRAddress->rxdma.csr.value = 0x00002001; + + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 1 ) + { + udelay( 5 ); + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 1 ) + { + DBG_ERROR( et131x_dbginfo, + "RX Dma failed to enter halt state. CSR 0x%08x\n", + pAdapter->CSRAddress->rxdma.csr.value ); + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_rx_dma_enable + ****************************************************************************** + DESCRIPTION: + re-start OF Rx_DMA on the ET1310. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + + + *****************************************************************************/ +void et131x_rx_dma_enable( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_rx_dma_enable" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + if( pAdapter->RegistryPhyLoopbk ) + { + /********************************************************************** + RxDMA is disabled for loopback operation. + *********************************************************************/ + pAdapter->CSRAddress->rxdma.csr.value = 0x1; + } + else + { + /********************************************************************** + Setup the receive dma configuration register for normal operation. + *********************************************************************/ + { + RXDMA_CSR_t csr = {0}; + + csr.bits.fbr1_enable = 1; + + if( pAdapter->RxRing.Fbr1BufferSize == 4096 ) + { + csr.bits.fbr1_size = 1; + } + else if( pAdapter->RxRing.Fbr1BufferSize == 8192 ) + { + csr.bits.fbr1_size = 2; + } + else if( pAdapter->RxRing.Fbr1BufferSize == 16384 ) + { + csr.bits.fbr1_size = 3; + } +#ifdef USE_FBR0 + csr.bits.fbr0_enable = 1; + + if( pAdapter->RxRing.Fbr0BufferSize == 256 ) + { + csr.bits.fbr0_size = 1; + } + else if( pAdapter->RxRing.Fbr0BufferSize == 512 ) + { + csr.bits.fbr0_size = 2; + } + else if( pAdapter->RxRing.Fbr0BufferSize == 1024 ) + { + csr.bits.fbr0_size = 3; + } +#endif + pAdapter->CSRAddress->rxdma.csr = csr; + } + + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 0 ) + { + udelay( 5 ); + if( pAdapter->CSRAddress->rxdma.csr.bits.halt_status != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "RX Dma failed to exit halt state. CSR 0x%08x\n", + pAdapter->CSRAddress->rxdma.csr.value ); + } + } + } + + + DBG_RX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: nic_rx_pkts + ****************************************************************************** + DESCRIPTION: + Checks the hardware for available packets, using completion ring + If packets are available, it gets an RFD from the RecvList, attaches + the packet to it, puts the RFD in the RecvPendList, and also returns + the pointer to the RFD. + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + pMpRfd - pointer to our MPRFD + + *****************************************************************************/ +PMP_RFD nic_rx_pkts( ET131X_ADAPTER *pAdapter ) +{ + PRX_STATUS_BLOCK_t pRxStatusBlock; + PPKT_STAT_DESC_t pPSREntry; + PMP_RFD pMpRfd; + UINT32 nIndex; + PUCHAR pBufVa; + PUINT16 pShBufVa; + unsigned long lockflags; + struct list_head *element; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_rx_pkts" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + RX Status block is written by the DMA engine prior to every interrupt. + It contains the next to be used entry in the Packet Status Ring, and + also the two Free Buffer rings. + *************************************************************************/ + pRxStatusBlock = (PRX_STATUS_BLOCK_t)pAdapter->RxRing.pRxStatusVa; + + if(( pRxStatusBlock->Word1.bits.PSRoffset != + pAdapter->RxRing.local_psr_full.bits.psr_full ) || + ( pRxStatusBlock->Word1.bits.PSRwrap != + pAdapter->RxRing.local_psr_full.bits.psr_full_wrap )) + { + UINT8 ringIndex; + UINT16 bufferIndex; + UINT32 localLen; + PKT_STAT_DESC_WORD0_t Word0; + + + /********************************************************************** + The packet status ring indicates that data is available. + *********************************************************************/ + pPSREntry = (PPKT_STAT_DESC_t)( pAdapter->RxRing.pPSRingVa ) + + pAdapter->RxRing.local_psr_full.bits.psr_full; + + + /********************************************************************** + Grab any information that is required once the PSR is advanced, + since we can no longer rely on the memory being accurate + *********************************************************************/ + localLen = pPSREntry->word1.bits.length; + ringIndex = (UINT8)pPSREntry->word1.bits.ri; + bufferIndex = (UINT16)pPSREntry->word1.bits.bi; + Word0 = pPSREntry->word0; + + DBG_RX( et131x_dbginfo, "RX PACKET STATUS\n" ); + DBG_RX( et131x_dbginfo, "\tlength : %d\n", localLen ); + DBG_RX( et131x_dbginfo, "\tringIndex : %d\n", ringIndex ); + DBG_RX( et131x_dbginfo, "\tbufferIndex : %d\n", bufferIndex ); + DBG_RX( et131x_dbginfo, "\tword0 : 0x%08x\n", Word0.value ); + + +#if 0 + /********************************************************************** + Check the Status Word that the MAC has appended to the PSR entry in + case the MAC has detected errors. + *********************************************************************/ + if( Word0.value & ALCATEL_BAD_STATUS ) + { + DBG_ERROR( et131x_dbginfo, + "NICRxPkts >> Alcatel Status Word error." + "Value 0x%08x\n", + pPSREntry->word0.value ); + } +#endif + + + /********************************************************************** + Indicate that we have used this PSR entry. + *********************************************************************/ + if( ++pAdapter->RxRing.local_psr_full.bits.psr_full > + ( pAdapter->RxRing.PsrNumEntries - 1 )) + { + pAdapter->RxRing.local_psr_full.bits.psr_full = 0; + pAdapter->RxRing.local_psr_full.bits.psr_full_wrap ^= 1; + } + + pAdapter->CSRAddress->rxdma.psr_full_offset = + pAdapter->RxRing.local_psr_full; + +#ifndef USE_FBR0 + if( ringIndex != 1 ) + { + DBG_ERROR( et131x_dbginfo, + "NICRxPkts PSR Entry %d indicates " + "Buffer Ring 0 in use\n", + pAdapter->RxRing.local_psr_full.bits.psr_full ); + + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } +#endif + +#ifdef USE_FBR0 + if(( ringIndex > 1 ) || + (( ringIndex == 0 ) && ( bufferIndex > ( pAdapter->RxRing.Fbr0NumEntries - 1 ))) || + (( ringIndex == 1 ) && ( bufferIndex > ( pAdapter->RxRing.Fbr1NumEntries - 1 )))) +#else + if(( ringIndex != 1 ) || ( bufferIndex > ( pAdapter->RxRing.Fbr1NumEntries - 1 ))) +#endif + { + /****************************************************************** + Illegal buffer or ring index cannot be used by the S/W + *****************************************************************/ + DBG_ERROR( et131x_dbginfo, + "NICRxPkts PSR Entry %d indicates " + "length of %d and/or bad bi(%d)\n", + pAdapter->RxRing.local_psr_full.bits.psr_full, + localLen, + bufferIndex ); + + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } + + + /********************************************************************** + Get and fill the RFD. + *********************************************************************/ + spin_lock_irqsave( &pAdapter->RcvLock, lockflags ); + + pMpRfd = NULL; + element = pAdapter->RxRing.RecvList.next; + pMpRfd = (PMP_RFD)list_entry( element, MP_RFD, list_node ); + + if( pMpRfd == NULL ) + { + DBG_RX( et131x_dbginfo, + "NULL RFD returned from RecvList via list_entry()\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } + + list_del( &pMpRfd->list_node ); + pAdapter->RxRing.nReadyRecv--; + + spin_unlock_irqrestore( &pAdapter->RcvLock, lockflags ); + + pMpRfd->iBufferIndex = bufferIndex; + pMpRfd->iRingIndex = ringIndex; + + + /********************************************************************** + In V1 silicon, there is a bug which screws up filtering of runt + packets. Therefore runt packet filtering is disabled in the MAC + and the packets are dropped here. They are also counted here. + *********************************************************************/ + if( localLen < ( NIC_MIN_PACKET_SIZE + 4 )) + { + pAdapter->Stats.other_errors++; + localLen = 0; + } + + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + if( localLen ) + { + pShBufVa = pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex]; + + pMpRfd->bHasVLANTag = FALSE; + + + /****************************************************************** + The protocol value of 0x8100 means there is a VLAN tag in the + packet. Also the original protocol value will be present four + bytes further on. + *****************************************************************/ + if( pShBufVa[6] == 0x0081 ) + { + UINT16 LocalShort = (( pShBufVa[7] & 0xff00 ) >> 8 ) + + (( pShBufVa[7] & 0x00ff ) << 8 ); + UINT16 vlan_tag = LocalShort & 0x0fff; + + pMpRfd->bHasVLANTag = TRUE; + + DBG_RX( et131x_dbginfo, + "VLAN: RX packet Tag: %d\n", vlan_tag ); + + + /************************************************************** + The rules are: + - if our VLAN tag is zero we can pass anything up + - if our VLAN tag matches the incoming we can pass it + - If the packet is a protocol 802.3ad we pass it + regardless (802.3ad had protocol val of 0x8809. + proto val is now in ShBuf [8]) + - If the packet is a GARP VLAN Registration Protocol + (GVRP) packet, we pass it regardless. + 01:80:c2:00:00:21 is the GVRP address. + + NOTE: Because the ET1310 doesn't perform VLAN tagging + (it's done in the kernel) always pass packets up. + We'll leave this code in, however, just in case it's + needed in the future. + *************************************************************/ + if(( 1 ) || + ( pShBufVa[8] == 0x0988 ) || + (( pShBufVa[0] == 0x8001 ) && + ( pShBufVa[1] == 0x00c2 ) && + ( pShBufVa[2] == 0x2100 ))) + { + DBG_RX( et131x_dbginfo, + "VLAN: Passed test, send pkt up\n" ); + pMpRfd->VLANTag = vlan_tag; + } + else + { + /********************************************************* + Our VLAN tag is non-zero, AND the incoming tag does + not match it. Drop the packet. + ********************************************************/ + DBG_RX( et131x_dbginfo, + "VLAN: no match, drop pkt\n" ); + localLen = 0; + } + } + else if(( pShBufVa[6] == 0x0988 ) || + (( pShBufVa[0] == 0x8001 ) && + ( pShBufVa[1] == 0x00c2 ) && + ( pShBufVa[2] == 0x2100 ))) + { + /****************************************************************** + The protocol type (ethertype) of 0x8809 corresponds to 802.3ad + The MAC address of 01:80:c2:00:00:21 is the GARP VLAN + registration protocol (GVRP) address. + + Both of these message types should be passed up regardless + of their VLAN tagging. + *****************************************************************/ + DBG_RX( et131x_dbginfo, + "VLAN: No tag, but 802.3ad/GVRP, send pkt up\n" ); + } + else + { + /****************************************************************** + Our VLAN tag is non-zero. no VLAN header on incoming. + Packet is not GVRP or 802.3ad. Drop the packet. + *****************************************************************/ + DBG_RX( et131x_dbginfo, + "VLAN: No RX packet tag\n" ); + // NOTE: Same as the note above; never drop a packet for now. + // localLen = 0; + } + } +#endif + + if( localLen ) + { + if ( pAdapter->ReplicaPhyLoopbk == 1 ) + { + pBufVa = pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex]; + + if( memcmp( &pBufVa[6], &pAdapter->CurrentAddress[0], ETH_ALEN ) == 0 ) + { + if( memcmp( &pBufVa[42], "Replica packet", ETH_HLEN )) + { + pAdapter->ReplicaPhyLoopbkPF = 1; + } + } + DBG_WARNING( et131x_dbginfo, + "pBufVa:\t%02x:%02x:%02x:%02x:%02x:%02x\n", + pBufVa[6], + pBufVa[7], + pBufVa[8], + pBufVa[9], + pBufVa[10], + pBufVa[11] ); + + DBG_WARNING( et131x_dbginfo, + "CurrentAddr:\t%02x:%02x:%02x:%02x:%02x:%02x\n", + pAdapter->CurrentAddress[0], + pAdapter->CurrentAddress[1], + pAdapter->CurrentAddress[2], + pAdapter->CurrentAddress[3], + pAdapter->CurrentAddress[4], + pAdapter->CurrentAddress[5] ); + } + + /****************************************************************** + Determine if this is a multicast packet coming in + *****************************************************************/ + if(( Word0.value & ALCATEL_MULTICAST_PKT ) && + !( Word0.value & ALCATEL_BROADCAST_PKT )) + { + /************************************************************** + Promiscuous mode and Multicast mode are not mutually + exclusive as was first thought. I guess Promiscuous is + just considered a super-set of the other filters. + Generally filter is 0x2b when in promiscuous mode. + *************************************************************/ + if(( pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST ) && + !( pAdapter->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS ) && + !( pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST )) + { + pBufVa = pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex]; + + /********************************************************** + Loop through our list to see if the destination address + of this packet matches one in our list. + *********************************************************/ + for( nIndex = 0; nIndex < pAdapter->MCAddressCount; nIndex++ ) + { + if( pBufVa[0] == pAdapter->MCList[nIndex][0] && + pBufVa[1] == pAdapter->MCList[nIndex][1] && + pBufVa[2] == pAdapter->MCList[nIndex][2] && + pBufVa[3] == pAdapter->MCList[nIndex][3] && + pBufVa[4] == pAdapter->MCList[nIndex][4] && + pBufVa[5] == pAdapter->MCList[nIndex][5] ) + { + break; + } + } + + /********************************************************** + If our index is equal to the number of Multicast + address we have, then this means we did not find this + packet's matching address in our list. Set the + PacketSize to zero, so we free our RFD when we return + from this function. + *********************************************************/ + if( nIndex == pAdapter->MCAddressCount ) + { + localLen = 0; + } + } + + if( localLen > 0 ) + { + pAdapter->Stats.multircv++; + } + } + else if( Word0.value & ALCATEL_BROADCAST_PKT ) + { + pAdapter->Stats.brdcstrcv++; + } + else + { + /************************************************************** + Not sure what this counter measures in promiscuous mode. + Perhaps we should check the MAC address to see if it is + directed to us in promiscuous mode. + *************************************************************/ + pAdapter->Stats.unircv++; + } + } + + if( localLen > 0 ) + { + struct sk_buff *skb = NULL; + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#ifdef __vlan_get_tag + unsigned short vlan_tag = 0; +#endif +#endif + + //vlan_tag = 0; + + //pMpRfd->PacketSize = localLen - 4; + pMpRfd->PacketSize = localLen; + + skb = dev_alloc_skb( pMpRfd->PacketSize + 2 ); + if( !skb ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc an SKB for Rx\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } + + pAdapter->net_stats.rx_bytes += pMpRfd->PacketSize; + + memcpy( skb_put( skb, pMpRfd->PacketSize ), + pAdapter->RxRing.Fbr[ringIndex]->Va[bufferIndex], + pMpRfd->PacketSize ); + + skb->dev = pAdapter->netdev; + skb->protocol = eth_type_trans( skb, pAdapter->netdev ); + skb->ip_summed = CHECKSUM_NONE; + + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#if defined __vlan_get_tag + if( __vlan_get_tag( skb, &vlan_tag ) == -EINVAL ) + { + DBG_RX( et131x_dbginfo, + "VLAN: No Rx packet tag\n" ); + } + else + { + DBG_RX( et131x_dbginfo, + "VLAN: Rx packet tag: %d\n", vlan_tag ); + } +#endif +#endif + + netif_rx( skb ); + } + else + { + pMpRfd->PacketSize = 0; + } + + nic_return_rfd( pAdapter, pMpRfd ); + + + DBG_RX( et131x_dbginfo, "(1)\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return pMpRfd; + } + else + { + /********************************************************************** + Looks like this ring is not updated yet + *********************************************************************/ + DBG_RX( et131x_dbginfo, "(0)\n" ); + DBG_RX_LEAVE( et131x_dbginfo ); + return NULL; + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_reset_recv + ****************************************************************************** + DESCRIPTION: + Reset the receive list + + Assumption: Rcv spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_reset_recv( ET131X_ADAPTER *pAdapter ) +{ + PMP_RFD pMpRfd; + struct list_head *element; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_reset_recv" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_ASSERT( !list_empty( &pAdapter->RxRing.RecvList )); + + + /************************************************************************** + Take all the RFD's from the pending list, and stick them on the + RecvList. + *************************************************************************/ + while( !list_empty( &pAdapter->RxRing.RecvPendingList ) ) + { + element = pAdapter->RxRing.RecvPendingList.next; + + pMpRfd = (PMP_RFD)list_entry( element, MP_RFD, list_node ); + + list_del( &pMpRfd->list_node ); + list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvList ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_handle_recv_interrupt + ****************************************************************************** + DESCRIPTION: + Interrupt handler for receive processing + + Assumption: Rcv spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_handle_recv_interrupt( ET131X_ADAPTER *pAdapter ) +{ + PMP_RFD pMpRfd = NULL; + struct sk_buff *PacketArray [NUM_PACKETS_HANDLED]; + PMP_RFD RFDFreeArray[NUM_PACKETS_HANDLED]; + UINT32 PacketArrayCount = 0; + UINT32 PacketsToHandle; + UINT32 PacketFreeCount = 0; + BOOL_t TempUnfinishedRec = FALSE; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_handle_recv_interrupt" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + PacketsToHandle = NUM_PACKETS_HANDLED; + + + /************************************************************************** + Process up to available RFD's + *************************************************************************/ + while( PacketArrayCount < PacketsToHandle ) + { + if( list_empty( &pAdapter->RxRing.RecvList )) + { + DBG_ASSERT( pAdapter->RxRing.nReadyRecv == 0 ); + DBG_ERROR( et131x_dbginfo, "NO RFD's !!!!!!!!!!!!!\n" ); + TempUnfinishedRec = TRUE; + break; + } + + pMpRfd = nic_rx_pkts( pAdapter ); + + if( pMpRfd == NULL) + { + break; + } + + + /********************************************************************** + Do not receive any packets until a filter has been set. + Do not receive any packets until we are at D0. + Do not receive any packets until we have link. + If length is zero, return the RFD in order to advance the Free + buffer ring. + *********************************************************************/ + if(( !pAdapter->PacketFilter ) || + ( pAdapter->PoMgmt.PowerState != NdisDeviceStateD0 ) || + ( !MP_LINK_DETECTED( pAdapter )) || + ( pMpRfd->PacketSize == 0 )) + { + continue; + } + + + /********************************************************************** + Increment the number of packets we received + *********************************************************************/ + pAdapter->Stats.ipackets++; + + + /********************************************************************** + Set the status on the packet, either resources or success + *********************************************************************/ + if( pAdapter->RxRing.nReadyRecv >= RFD_LOW_WATER_MARK ) + { + /****************************************************************** + Put this RFD on the pending list + + NOTE - nic_rx_pkts() above is already returning the RFD to the + RecvList, so don't additionally do that here. + + Besides, we don't really need (at this point) the pending list + anyway. + *****************************************************************/ + //spin_lock_irqsave( &pAdapter->RcvPendLock, lockflags ); + //list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvPendingList ); + //spin_unlock_irqrestore( &pAdapter->RcvPendLock, lockflags ); + + + /****************************************************************** + Update the number of outstanding Recvs + *****************************************************************/ + //MP_INC_RCV_REF( pAdapter ); + } + else + { + RFDFreeArray[PacketFreeCount] = pMpRfd; + PacketFreeCount++; + + DBG_WARNING( et131x_dbginfo, "RFD's are running out !!!!!!!!!!!!!\n" ); + } + + PacketArray[PacketArrayCount] = pMpRfd->Packet; + PacketArrayCount++; + } + + + if(( PacketArrayCount == NUM_PACKETS_HANDLED ) || TempUnfinishedRec ) + { + pAdapter->RxRing.UnfinishedReceives = TRUE; + pAdapter->CSRAddress->global.watchdog_timer = + pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO; + } + else + { + /********************************************************************** + Watchdog timer will disable itself if appropriate. + *********************************************************************/ + pAdapter->RxRing.UnfinishedReceives = FALSE; + } + + + DBG_RX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: NICReturnRFD + ****************************************************************************** + DESCRIPTION: + Recycle a RFD and put it back onto the receive list + + PARAMETERS : + pAdapter - pointer to our adapter + pMpRfd - pointer to the RFD + + RETURNS : + NONE + + *****************************************************************************/ +void nic_return_rfd( ET131X_ADAPTER *pAdapter, PMP_RFD pMpRfd ) +{ + UINT16 ReturnedBI = pMpRfd->iBufferIndex; + UINT8 ReturnedRI = pMpRfd->iRingIndex; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_return_rfd" ); + DBG_RX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + We don't use any of the OOB data besides status + Otherwise, we need to clean up OOB data + *************************************************************************/ + if( +#ifdef USE_FBR0 + (( ReturnedRI == 0 ) && ( ReturnedBI < pAdapter->RxRing.Fbr0NumEntries )) || +#endif + (( ReturnedRI == 1 ) && ( ReturnedBI < pAdapter->RxRing.Fbr1NumEntries ))) + { + spin_lock_irqsave( &pAdapter->FbrLock, lockflags ); + + if( ReturnedRI == 1 ) + { + PFBR_DESC_t pNextDesc = (PFBR_DESC_t)(pAdapter->RxRing.pFbr1RingVa) + + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full; + + /****************************************************************** + Handle the Free Buffer Ring advancement here. Write the + PA / Buffer Index for the returned buffer into the oldest + (next to be freed)FBR entry + *****************************************************************/ + pNextDesc->addr_hi = pAdapter->RxRing.Fbr[1]->PAHigh[ReturnedBI]; + pNextDesc->addr_lo = pAdapter->RxRing.Fbr[1]->PALow[ReturnedBI]; + pNextDesc->word2.value = ReturnedBI; + + if( ++pAdapter->RxRing.local_Fbr1_full.bits.fbr_full > + ( pAdapter->RxRing.Fbr1NumEntries - 1 )) + { + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr1_full.bits.fbr_full_wrap ^= 1; + } + + pAdapter->CSRAddress->rxdma.fbr1_full_offset = + pAdapter->RxRing.local_Fbr1_full; + } +#ifdef USE_FBR0 + else + { + PFBR_DESC_t pNextDesc = (PFBR_DESC_t)(pAdapter->RxRing.pFbr0RingVa) + + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full; + + /****************************************************************** + Handle the Free Buffer Ring advancement here. Write the + PA / Buffer Index for the returned buffer into the oldest + (next to be freed) FBR entry + *****************************************************************/ + pNextDesc->addr_hi = pAdapter->RxRing.Fbr[0]->PAHigh[ReturnedBI]; + pNextDesc->addr_lo = pAdapter->RxRing.Fbr[0]->PALow[ReturnedBI]; + pNextDesc->word2.value = ReturnedBI; + + if( ++pAdapter->RxRing.local_Fbr0_full.bits.fbr_full > + (pAdapter->RxRing.Fbr0NumEntries - 1)) + { + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full = 0; + pAdapter->RxRing.local_Fbr0_full.bits.fbr_full_wrap ^= 1; + } + + pAdapter->CSRAddress->rxdma.fbr0_full_offset = + pAdapter->RxRing.local_Fbr0_full; + } +#endif + spin_unlock_irqrestore( &pAdapter->FbrLock, lockflags ); + } + else + { + DBG_ERROR( et131x_dbginfo, + "NICReturnRFD illegal Buffer Index returned\n" ); + } + + + /************************************************************************** + The processing on this RFD is done, so put it back on the tail of + our list + *************************************************************************/ + spin_lock_irqsave( &pAdapter->RcvLock, lockflags ); + + list_add_tail( &pMpRfd->list_node, &pAdapter->RxRing.RecvList ); + pAdapter->RxRing.nReadyRecv++; + + spin_unlock_irqrestore( &pAdapter->RcvLock, lockflags ); + + DBG_ASSERT( pAdapter->RxRing.nReadyRecv <= pAdapter->RxRing.NumRfd ); + + + DBG_RX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_phy.h +++ linux-2.6.28/ubuntu/et131x/ET1310_phy.h @@ -0,0 +1,1228 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_phy.h - Defines, structs, enums, prototypes, etc. pertaining to the + * PHY. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/18 22:18:33 $ + $Revision: 1.10 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_PHY_H_ +#define _ET1310_PHY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +#define TRUEPHY_SUCCESS 0 +#define TRUEPHY_FAILURE 1 +typedef void *TRUEPHY_HANDLE; +typedef void *TRUEPHY_PLATFORM_HANDLE; +typedef void *TRUEPHY_OSAL_HANDLE; + + + + +/****************************************************************************** + CONSTANTS for PHY Register + *****************************************************************************/ +/* MI Register Addresses */ +#define MI_CONTROL_REG 0 +#define MI_STATUS_REG 1 +#define MI_PHY_IDENTIFIER_1_REG 2 +#define MI_PHY_IDENTIFIER_2_REG 3 +#define MI_AUTONEG_ADVERTISEMENT_REG 4 +#define MI_AUTONEG_LINK_PARTNER_ABILITY_REG 5 +#define MI_AUTONEG_EXPANSION_REG 6 +#define MI_AUTONEG_NEXT_PAGE_TRANSMIT_REG 7 +#define MI_LINK_PARTNER_NEXT_PAGE_REG 8 +#define MI_1000BASET_CONTROL_REG 9 +#define MI_1000BASET_STATUS_REG 10 +#define MI_RESERVED11_REG 11 +#define MI_RESERVED12_REG 12 +#define MI_RESERVED13_REG 13 +#define MI_RESERVED14_REG 14 +#define MI_EXTENDED_STATUS_REG 15 + +/* VMI Register Addresses */ +#define VMI_RESERVED16_REG 16 +#define VMI_RESERVED17_REG 17 +#define VMI_RESERVED18_REG 18 +#define VMI_LOOPBACK_CONTROL_REG 19 +#define VMI_RESERVED20_REG 20 +#define VMI_MI_CONTROL_REG 21 +#define VMI_PHY_CONFIGURATION_REG 22 +#define VMI_PHY_CONTROL_REG 23 +#define VMI_INTERRUPT_MASK_REG 24 +#define VMI_INTERRUPT_STATUS_REG 25 +#define VMI_PHY_STATUS_REG 26 +#define VMI_LED_CONTROL_1_REG 27 +#define VMI_LED_CONTROL_2_REG 28 +#define VMI_RESERVED29_REG 29 +#define VMI_RESERVED30_REG 30 +#define VMI_RESERVED31_REG 31 + + + + +/****************************************************************************** + PHY Register Mapping(MI) Management Interface Regs + *****************************************************************************/ +typedef struct _MI_REGS_t +{ + UCHAR bmcr; // Basic mode control reg(Reg 0x00) + UCHAR bmsr; // Basic mode status reg(Reg 0x01) + UCHAR idr1; // Phy identifier reg 1(Reg 0x02) + UCHAR idr2; // Phy identifier reg 2(Reg 0x03) + UCHAR anar; // Auto-Negotiation advertisement(Reg 0x04) + UCHAR anlpar; // Auto-Negotiation link Partner Ability(Reg 0x05) + UCHAR aner; // Auto-Negotiation expansion reg(Reg 0x06) + UCHAR annptr; // Auto-Negotiation next page transmit reg(Reg 0x07) + UCHAR lpnpr; // link partner next page reg(Reg 0x08) + UCHAR gcr; // Gigabit basic mode control reg(Reg 0x09) + UCHAR gsr; // Gigabit basic mode status reg(Reg 0x0A) + UCHAR mi_res1[4]; // Future use by MI working group(Reg 0x0B - 0x0E) + UCHAR esr; // Extended status reg(Reg 0x0F) + UCHAR mi_res2[3]; // Future use by MI working group(Reg 0x10 - 0x12) + UCHAR loop_ctl; // Loopback Control Reg(Reg 0x13) + UCHAR mi_res3; // Future use by MI working group(Reg 0x14) + UCHAR mcr; // MI Control Reg(Reg 0x15) + UCHAR pcr; // Configuration Reg(Reg 0x16) + UCHAR phy_ctl; // PHY Control Reg(Reg 0x17) + UCHAR imr; // Interrupt Mask Reg(Reg 0x18) + UCHAR isr; // Interrupt Status Reg(Reg 0x19) + UCHAR psr; // PHY Status Reg(Reg 0x1A) + UCHAR lcr1; // LED Control 1 Reg(Reg 0x1B) + UCHAR lcr2; // LED Control 2 Reg(Reg 0x1C) + UCHAR mi_res4[3]; // Future use by MI working group(Reg 0x1D - 0x1F) +} +MI_REGS_t, *PMI_REGS_t; + + + + +/****************************************************************************** + MI Register 0: Basic mode control register + *****************************************************************************/ +typedef union _MI_BMCR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 reset:1; //bit 15 + UINT16 loopback:1; //bit 14 + UINT16 speed_sel:1; //bit 13 + UINT16 enable_autoneg:1; //bit 12 + UINT16 power_down:1; //bit 11 + UINT16 isolate:1; //bit 10 + UINT16 restart_autoneg:1; //bit 9 + UINT16 duplex_mode:1; //bit 8 + UINT16 col_test:1; //bit 7 + UINT16 speed_1000_sel:1; //bit 6 + UINT16 res1:6; //bits 0-5 + #else + UINT16 res1:6; //bits 0-5 + UINT16 speed_1000_sel:1; //bit 6 + UINT16 col_test:1; //bit 7 + UINT16 duplex_mode:1; //bit 8 + UINT16 restart_autoneg:1; //bit 9 + UINT16 isolate:1; //bit 10 + UINT16 power_down:1; //bit 11 + UINT16 enable_autoneg:1; //bit 12 + UINT16 speed_sel:1; //bit 13 + UINT16 loopback:1; //bit 14 + UINT16 reset:1; //bit 15 + #endif + } bits; +} +MI_BMCR_t, *PMI_BMCR_t; + + + + +/****************************************************************************** + MI Register 1: Basic mode status register + *****************************************************************************/ +typedef union _MI_BMSR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 link_100T4:1; //bit 15 + UINT16 link_100fdx:1; //bit 14 + UINT16 link_100hdx:1; //bit 13 + UINT16 link_10fdx:1; //bit 12 + UINT16 link_10hdx:1; //bit 11 + UINT16 link_100T2fdx:1; //bit 10 + UINT16 link_100T2hdx:1; //bit 9 + UINT16 extend_status:1; //bit 8 + UINT16 res1:1; //bit 7 + UINT16 preamble_supress:1; //bit 6 + UINT16 auto_neg_complete:1; //bit 5 + UINT16 remote_fault:1; //bit 4 + UINT16 auto_neg_able:1; //bit 3 + UINT16 link_status:1; //bit 2 + UINT16 jabber_detect:1; //bit 1 + UINT16 ext_cap:1; //bit 0 + #else + UINT16 ext_cap:1; //bit 0 + UINT16 jabber_detect:1; //bit 1 + UINT16 link_status:1; //bit 2 + UINT16 auto_neg_able:1; //bit 3 + UINT16 remote_fault:1; //bit 4 + UINT16 auto_neg_complete:1; //bit 5 + UINT16 preamble_supress:1; //bit 6 + UINT16 res1:1; //bit 7 + UINT16 extend_status:1; //bit 8 + UINT16 link_100T2hdx:1; //bit 9 + UINT16 link_100T2fdx:1; //bit 10 + UINT16 link_10hdx:1; //bit 11 + UINT16 link_10fdx:1; //bit 12 + UINT16 link_100hdx:1; //bit 13 + UINT16 link_100fdx:1; //bit 14 + UINT16 link_100T4:1; //bit 15 + #endif + } bits; +} +MI_BMSR_t, *PMI_BMSR_t; + + + + +/****************************************************************************** + MI Register 2: Physical Identifier 1 + *****************************************************************************/ +typedef union _MI_IDR1_t +{ + UINT16 value; + struct + { + UINT16 ieee_address:16; //0x0282 default(bits 0-15) + } bits; +} +MI_IDR1_t, *PMI_IDR1_t; + + + + +/****************************************************************************** + MI Register 3: Physical Identifier 2 + *****************************************************************************/ +typedef union _MI_IDR2_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 ieee_address:6; //111100 default(bits 10-15) + UINT16 model_no:6; //000001 default(bits 4-9) + UINT16 rev_no:4; //0010 default(bits 0-3) + #else + UINT16 rev_no:4; //0010 default(bits 0-3) + UINT16 model_no:6; //000001 default(bits 4-9) + UINT16 ieee_address:6; //111100 default(bits 10-15) + #endif + } bits; +} +MI_IDR2_t, *PMI_IDR2_t; + + + + +/****************************************************************************** + MI Register 4: Auto-negotiation advertisement register + *****************************************************************************/ +typedef union _MI_ANAR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np_indication:1; //bit 15 + UINT16 res2:1; //bit 14 + UINT16 remote_fault:1; //bit 13 + UINT16 res1:1; //bit 12 + UINT16 cap_asmpause:1; //bit 11 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_10hdx:1; //bit 5 + UINT16 selector:5; //bits 0-4 + #else + UINT16 selector:5; //bits 0-4 + UINT16 cap_10hdx:1; //bit 5 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_asmpause:1; //bit 11 + UINT16 res1:1; //bit 12 + UINT16 remote_fault:1; //bit 13 + UINT16 res2:1; //bit 14 + UINT16 np_indication:1; //bit 15 + #endif + } bits; +} +MI_ANAR_t, *PMI_ANAR_t; + + + + +/****************************************************************************** + MI Register 5: Auto-negotiation link partner advertisement register + *****************************************************************************/ +typedef struct _MI_ANLPAR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np_indication:1; //bit 15 + UINT16 acknowledge:1; //bit 14 + UINT16 remote_fault:1; //bit 13 + UINT16 res1:1; //bit 12 + UINT16 cap_asmpause:1; //bit 11 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_10hdx:1; //bit 5 + UINT16 selector:5; //bits 0-4 + #else + UINT16 selector:5; //bits 0-4 + UINT16 cap_10hdx:1; //bit 5 + UINT16 cap_10fdx:1; //bit 6 + UINT16 cap_100hdx:1; //bit 7 + UINT16 cap_100fdx:1; //bit 8 + UINT16 cap_100T4:1; //bit 9 + UINT16 cap_pause:1; //bit 10 + UINT16 cap_asmpause:1; //bit 11 + UINT16 res1:1; //bit 12 + UINT16 remote_fault:1; //bit 13 + UINT16 acknowledge:1; //bit 14 + UINT16 np_indication:1; //bit 15 + #endif + } bits; +} +MI_ANLPAR_t, *PMI_ANLPAR_t; + + + + +/****************************************************************************** + MI Register 6: Auto-negotiation expansion register + *****************************************************************************/ +typedef union _MI_ANER_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res:11; //bits 5-15 + UINT16 pdf:1; //bit 4 + UINT16 lp_np_able:1; //bit 3 + UINT16 np_able:1; //bit 2 + UINT16 page_rx:1; //bit 1 + UINT16 lp_an_able:1; //bit 0 + #else + UINT16 lp_an_able:1; //bit 0 + UINT16 page_rx:1; //bit 1 + UINT16 np_able:1; //bit 2 + UINT16 lp_np_able:1; //bit 3 + UINT16 pdf:1; //bit 4 + UINT16 res:11; //bits 5-15 + #endif + } bits; +} +MI_ANER_t, *PMI_ANER_t; + + + + +/****************************************************************************** + MI Register 7: Auto-negotiation next page transmit reg(0x07) + *****************************************************************************/ +typedef union _MI_ANNPTR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np:1; //bit 15 + UINT16 res1:1; //bit 14 + UINT16 msg_page:1; //bit 13 + UINT16 ack2:1; //bit 12 + UINT16 toggle:1; //bit 11 + UINT16 msg:11; //bits 0-10 + #else + UINT16 msg:11; //bits 0-10 + UINT16 toggle:1; //bit 11 + UINT16 ack2:1; //bit 12 + UINT16 msg_page:1; //bit 13 + UINT16 res1:1; //bit 14 + UINT16 np:1; //bit 15 + #endif + } bits; +} +MI_ANNPTR_t, *PMI_ANNPTR_t; + + + + +/****************************************************************************** + MI Register 8: Link Partner Next Page Reg(0x08) + *****************************************************************************/ +typedef union _MI_LPNPR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 np:1; //bit 15 + UINT16 ack:1; //bit 14 + UINT16 msg_page:1; //bit 13 + UINT16 ack2:1; //bit 12 + UINT16 toggle:1; //bit 11 + UINT16 msg:11; //bits 0-10 + #else + UINT16 msg:11; //bits 0-10 + UINT16 toggle:1; //bit 11 + UINT16 ack2:1; //bit 12 + UINT16 msg_page:1; //bit 13 + UINT16 ack:1; //bit 14 + UINT16 np:1; //bit 15 + #endif + } bits; +} +MI_LPNPR_t, *PMI_LPNPR_t; + + + + +/****************************************************************************** + MI Register 9: 1000BaseT Control Reg(0x09) + *****************************************************************************/ +typedef union _MI_GCR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 test_mode:3; //bits 13-15 + UINT16 ms_config_en:1; //bit 12 + UINT16 ms_value:1; //bit 11 + UINT16 port_type:1; //bit 10 + UINT16 link_1000fdx:1; //bit 9 + UINT16 link_1000hdx:1; //bit 8 + UINT16 res:8; //bit 0-7 + #else + UINT16 res:8; //bit 0-7 + UINT16 link_1000hdx:1; //bit 8 + UINT16 link_1000fdx:1; //bit 9 + UINT16 port_type:1; //bit 10 + UINT16 ms_value:1; //bit 11 + UINT16 ms_config_en:1; //bit 12 + UINT16 test_mode:3; //bits 13-15 + #endif + } bits; +} +MI_GCR_t, *PMI_GCR_t; + + + + +/****************************************************************************** + MI Register 10: 1000BaseT Status Reg(0x0A) + *****************************************************************************/ +typedef union _MI_GSR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 ms_config_fault:1; //bit 15 + UINT16 ms_resolve:1; //bit 14 + UINT16 local_rx_status:1; //bit 13 + UINT16 remote_rx_status:1; //bit 12 + UINT16 link_1000fdx:1; //bit 11 + UINT16 link_1000hdx:1; //bit 10 + UINT16 res:2; //bits 8-9 + UINT16 idle_err_cnt:8; //bits 0-7 + #else + UINT16 idle_err_cnt:8; //bits 0-7 + UINT16 res:2; //bits 8-9 + UINT16 link_1000hdx:1; //bit 10 + UINT16 link_1000fdx:1; //bit 11 + UINT16 remote_rx_status:1; //bit 12 + UINT16 local_rx_status:1; //bit 13 + UINT16 ms_resolve:1; //bit 14 + UINT16 ms_config_fault:1; //bit 15 + #endif + } bits; +} +MI_GSR_t, *PMI_GSR_t; + + + + +/****************************************************************************** + MI Register 11 - 14: Reserved Regs(0x0B - 0x0E) + *****************************************************************************/ +typedef union _MI_RES_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res15:1; //bit 15 + UINT16 res14:1; //bit 14 + UINT16 res13:1; //bit 13 + UINT16 res12:1; //bit 12 + UINT16 res11:1; //bit 11 + UINT16 res10:1; //bit 10 + UINT16 res9:1; //bit 9 + UINT16 res8:1; //bit 8 + UINT16 res7:1; //bit 7 + UINT16 res6:1; //bit 6 + UINT16 res5:1; //bit 5 + UINT16 res4:1; //bit 4 + UINT16 res3:1; //bit 3 + UINT16 res2:1; //bit 2 + UINT16 res1:1; //bit 1 + UINT16 res0:1; //bit 0 + #else + UINT16 res0:1; //bit 0 + UINT16 res1:1; //bit 1 + UINT16 res2:1; //bit 2 + UINT16 res3:1; //bit 3 + UINT16 res4:1; //bit 4 + UINT16 res5:1; //bit 5 + UINT16 res6:1; //bit 6 + UINT16 res7:1; //bit 7 + UINT16 res8:1; //bit 8 + UINT16 res9:1; //bit 9 + UINT16 res10:1; //bit 10 + UINT16 res11:1; //bit 11 + UINT16 res12:1; //bit 12 + UINT16 res13:1; //bit 13 + UINT16 res14:1; //bit 14 + UINT16 res15:1; //bit 15 + #endif + } bits; +} +MI_RES_t, *PMI_RES_t; + + + + +/****************************************************************************** + MI Register 15: Extended status Reg(0x0F) + *****************************************************************************/ +typedef union _MI_ESR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 link_1000Xfdx:1; //bit 15 + UINT16 link_1000Xhdx:1; //bit 14 + UINT16 link_1000fdx:1; //bit 13 + UINT16 link_1000hdx:1; //bit 12 + UINT16 res:12; //bit 0-11 + #else + UINT16 res:12; //bit 0-11 + UINT16 link_1000hdx:1; //bit 12 + UINT16 link_1000fdx:1; //bit 13 + UINT16 link_1000Xhdx:1; //bit 14 + UINT16 link_1000Xfdx:1; //bit 15 + #endif + } bits; +} +MI_ESR_t, *PMI_ESR_t; + + + + +/****************************************************************************** + MI Register 16 - 18: Reserved Reg(0x10-0x12) + *****************************************************************************/ + + + + +/****************************************************************************** + MI Register 19: Loopback Control Reg(0x13) + *****************************************************************************/ +typedef union _MI_LCR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 mii_en:1; //bit 15 + UINT16 pcs_en:1; //bit 14 + UINT16 pmd_en:1; //bit 13 + UINT16 all_digital_en:1; //bit 12 + UINT16 replica_en:1; //bit 11 + UINT16 line_driver_en:1; //bit 10 + UINT16 res:10; //bit 0-9 + #else + UINT16 res:10; //bit 0-9 + UINT16 line_driver_en:1; //bit 10 + UINT16 replica_en:1; //bit 11 + UINT16 all_digital_en:1; //bit 12 + UINT16 pmd_en:1; //bit 13 + UINT16 pcs_en:1; //bit 14 + UINT16 mii_en:1; //bit 15 + #endif + } bits; +} +MI_LCR_t, *PMI_LCR_t; + + + + +/****************************************************************************** + MI Register 20: Reserved Reg(0x14) + *****************************************************************************/ + + + + +/****************************************************************************** + MI Register 21: Management Interface Control Reg(0x15) + *****************************************************************************/ +typedef union _MI_MICR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:5; //bits 11-15 + UINT16 mi_error_count:7; //bits 4-10 + UINT16 res2:1; //bit 3 + UINT16 ignore_10g_fr:1; //bit 2 + UINT16 res3:1; //bit 1 + UINT16 preamble_supress_en:1; //bit 0 + #else + UINT16 preamble_supress_en:1; //bit 0 + UINT16 res3:1; //bit 1 + UINT16 ignore_10g_fr:1; //bit 2 + UINT16 res2:1; //bit 3 + UINT16 mi_error_count:7; //bits 4-10 + UINT16 res1:5; //bits 11-15 + #endif + } bits; +} +MI_MICR_t, *PMI_MICR_t; + + + + +/****************************************************************************** + MI Register 22: PHY Configuration Reg(0x16) + *****************************************************************************/ +typedef union _MI_PHY_CONFIG_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 crs_tx_en:1; //bit 15 + UINT16 res1:1; //bit 14 + UINT16 tx_fifo_depth:2; //bits 12-13 + UINT16 speed_downshift:2; //bits 10-11 + UINT16 pbi_detect:1; //bit 9 + UINT16 tbi_rate:1; //bit 8 + UINT16 alternate_np:1; //bit 7 + UINT16 group_mdio_en:1; //bit 6 + UINT16 tx_clock_en:1; //bit 5 + UINT16 sys_clock_en:1; //bit 4 + UINT16 res2:1; //bit 3 + UINT16 mac_if_mode:3; //bits 0-2 + #else + UINT16 mac_if_mode:3; //bits 0-2 + UINT16 res2:1; //bit 3 + UINT16 sys_clock_en:1; //bit 4 + UINT16 tx_clock_en:1; //bit 5 + UINT16 group_mdio_en:1; //bit 6 + UINT16 alternate_np:1; //bit 7 + UINT16 tbi_rate:1; //bit 8 + UINT16 pbi_detect:1; //bit 9 + UINT16 speed_downshift:2; //bits 10-11 + UINT16 tx_fifo_depth:2; //bits 12-13 + UINT16 res1:1; //bit 14 + UINT16 crs_tx_en:1; //bit 15 + #endif + } bits; +} +MI_PHY_CONFIG_t, *PMI_PHY_CONFIG_t; + + + + +/****************************************************************************** + MI Register 23: PHY CONTROL Reg(0x17) + *****************************************************************************/ +typedef union _MI_PHY_CONTROL_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:1; //bit 15 + UINT16 tdr_en:1; //bit 14 + UINT16 res2:1; //bit 13 + UINT16 downshift_attempts:2; //bits 11-12 + UINT16 res3:5; //bit 6-10 + UINT16 jabber_10baseT:1; //bit 5 + UINT16 sqe_10baseT:1; //bit 4 + UINT16 tp_loopback_10baseT:1; //bit 3 + UINT16 preamble_gen_en:1; //bit 2 + UINT16 res4:1; //bit 1 + UINT16 force_int:1; //bit 0 + #else + UINT16 force_int:1; //bit 0 + UINT16 res4:1; //bit 1 + UINT16 preamble_gen_en:1; //bit 2 + UINT16 tp_loopback_10baseT:1; //bit 3 + UINT16 sqe_10baseT:1; //bit 4 + UINT16 jabber_10baseT:1; //bit 5 + UINT16 res3:5; //bit 6-10 + UINT16 downshift_attempts:2; //bits 11-12 + UINT16 res2:1; //bit 13 + UINT16 tdr_en:1; //bit 14 + UINT16 res1:1; //bit 15 + #endif + } bits; +} +MI_PHY_CONTROL_t, *PMI_PHY_CONTROL_t; + + + + +/****************************************************************************** + MI Register 24: Interrupt Mask Reg(0x18) + *****************************************************************************/ +typedef union _MI_IMR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:6; //bits 10-15 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 autoneg_status:1; //bit 8 + UINT16 hi_bit_err:1; //bit 7 + UINT16 np_rx:1; //bit 6 + UINT16 err_counter_full:1; //bit 5 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 rx_status:1; //bit 3 + UINT16 link_status:1; //bit 2 + UINT16 automatic_speed:1; //bit 1 + UINT16 int_en:1; //bit 0 + #else + UINT16 int_en:1; //bit 0 + UINT16 automatic_speed:1; //bit 1 + UINT16 link_status:1; //bit 2 + UINT16 rx_status:1; //bit 3 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 err_counter_full:1; //bit 5 + UINT16 np_rx:1; //bit 6 + UINT16 hi_bit_err:1; //bit 7 + UINT16 autoneg_status:1; //bit 8 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 res1:6; //bits 10-15 + #endif + } bits; +} +MI_IMR_t, *PMI_IMR_t; + + + + +/****************************************************************************** + MI Register 25: Interrupt Status Reg(0x19) + *****************************************************************************/ +typedef union _MI_ISR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:6; //bits 10-15 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 autoneg_status:1; //bit 8 + UINT16 hi_bit_err:1; //bit 7 + UINT16 np_rx:1; //bit 6 + UINT16 err_counter_full:1; //bit 5 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 rx_status:1; //bit 3 + UINT16 link_status:1; //bit 2 + UINT16 automatic_speed:1; //bit 1 + UINT16 int_en:1; //bit 0 + #else + UINT16 int_en:1; //bit 0 + UINT16 automatic_speed:1; //bit 1 + UINT16 link_status:1; //bit 2 + UINT16 rx_status:1; //bit 3 + UINT16 fifo_over_underflow:1; //bit 4 + UINT16 err_counter_full:1; //bit 5 + UINT16 np_rx:1; //bit 6 + UINT16 hi_bit_err:1; //bit 7 + UINT16 autoneg_status:1; //bit 8 + UINT16 mdio_sync_lost:1; //bit 9 + UINT16 res1:6; //bits 10-15 + #endif + } bits; +} +MI_ISR_t, *PMI_ISR_t; + + + + +/****************************************************************************** + MI Register 26: PHY Status Reg(0x1A) + *****************************************************************************/ +typedef union _MI_PSR_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:1; //bit 15 + UINT16 autoneg_fault:2; //bit 13-14 + UINT16 autoneg_status:1; //bit 12 + UINT16 mdi_x_status:1; //bit 11 + UINT16 polarity_status:1; //bit 10 + UINT16 speed_status:2; //bits 8-9 + UINT16 duplex_status:1; //bit 7 + UINT16 link_status:1; //bit 6 + UINT16 tx_status:1; //bit 5 + UINT16 rx_status:1; //bit 4 + UINT16 collision_status:1; //bit 3 + UINT16 autoneg_en:1; //bit 2 + UINT16 pause_en:1; //bit 1 + UINT16 asymmetric_dir:1; //bit 0 + #else + UINT16 asymmetric_dir:1; //bit 0 + UINT16 pause_en:1; //bit 1 + UINT16 autoneg_en:1; //bit 2 + UINT16 collision_status:1; //bit 3 + UINT16 rx_status:1; //bit 4 + UINT16 tx_status:1; //bit 5 + UINT16 link_status:1; //bit 6 + UINT16 duplex_status:1; //bit 7 + UINT16 speed_status:2; //bits 8-9 + UINT16 polarity_status:1; //bit 10 + UINT16 mdi_x_status:1; //bit 11 + UINT16 autoneg_status:1; //bit 12 + UINT16 autoneg_fault:2; //bit 13-14 + UINT16 res1:1; //bit 15 + #endif + } bits; +} +MI_PSR_t, *PMI_PSR_t; + + + + +/****************************************************************************** + MI Register 27: LED Control Reg 1(0x1B) + *****************************************************************************/ +typedef union _MI_LCR1_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 res1:2; //bits 14-15 + UINT16 led_dup_indicate:2; //bits 12-13 + UINT16 led_10baseT:2; //bits 10-11 + UINT16 led_collision:2; //bits 8-9 + UINT16 res2:2; //bits 6-7 + UINT16 res3:2; //bits 4-5 + UINT16 pulse_dur:2; //bits 2-3 + UINT16 pulse_stretch1:1; //bit 1 + UINT16 pulse_stretch0:1; //bit 0 + #else + UINT16 pulse_stretch0:1; //bit 0 + UINT16 pulse_stretch1:1; //bit 1 + UINT16 pulse_dur:2; //bits 2-3 + UINT16 res3:2; //bits 4-5 + UINT16 res2:2; //bits 6-7 + UINT16 led_collision:2; //bits 8-9 + UINT16 led_10baseT:2; //bits 10-11 + UINT16 led_dup_indicate:2; //bits 12-13 + UINT16 res1:2; //bits 14-15 + #endif + } bits; +} +MI_LCR1_t, *PMI_LCR1_t; + + + + +/****************************************************************************** + MI Register 28: LED Control Reg 2(0x1C) + *****************************************************************************/ +typedef union _MI_LCR2_t +{ + UINT16 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT16 led_link:4; //bits 12-15 + UINT16 led_tx_rx:4; //bits 8-11 + UINT16 led_100BaseTX:4; //bits 4-7 + UINT16 led_1000BaseT:4; //bits 0-3 + #else + UINT16 led_1000BaseT:4; //bits 0-3 + UINT16 led_100BaseTX:4; //bits 4-7 + UINT16 led_tx_rx:4; //bits 8-11 + UINT16 led_link:4; //bits 12-15 + #endif + } bits; +} +MI_LCR2_t, *PMI_LCR2_t; + + + + +/****************************************************************************** + MI Register 29 - 31: Reserved Reg(0x1D - 0x1E) + *****************************************************************************/ + + + + +/****************************************************************************** + TruePHY headers + *****************************************************************************/ +typedef struct _TRUEPHY_ACCESS_MI_REGS_ +{ + TRUEPHY_HANDLE hTruePhy; + INT32 nPhyId; + UCHAR bReadWrite; + PUCHAR pbyRegs; + PUCHAR pwData; + INT32 nRegCount; +} +TRUEPHY_ACCESS_MI_REGS, *PTRUEPHY_ACCESS_MI_REGS; + + + + +/****************************************************************************** + TruePHY headers + *****************************************************************************/ +typedef struct _TAG_TPAL_ACCESS_MI_REGS_ +{ + UINT32 nPhyId; + UCHAR bReadWrite; + UINT32 nRegCount; + UINT16 Data[4096]; + UCHAR Regs[4096]; +} TPAL_ACCESS_MI_REGS, *PTPAL_ACCESS_MI_REGS; + + + + +/****************************************************************************** + Required TruePHY PROTOTYPES + *****************************************************************************/ +/****************************************************************************** + TYPE DEFINITIONS + *****************************************************************************/ +typedef TRUEPHY_HANDLE TPAL_HANDLE; + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + +/////////////////////////////////////////////////////////////////////////////// +//// TruePHY Platform Specific Functions //// +/////////////////////////////////////////////////////////////////////////////// +//TRUEPHY_HANDLE TPAL_PlatformInit( void * pPlatformInfo, +// PTRUEPHY_PLATFORM_FUNCTIONS pPlatFunctions ); + +INT32 TPAL_MiAccessRegs( TPAL_HANDLE hPlatform, + INT32 nPhyId, + PUCHAR pbyAccessFlags, + PUCHAR pbyRegisters, + PUINT16 pwData, + PUINT16 pwAndMasks, + PUINT16 pwOrMasks, + INT32 nRegCount ); + +void TPAL_PlatformExit( TRUEPHY_PLATFORM_HANDLE hPlatform ); + + + + +/////////////////////////////////////////////////////////////////////////////// +//// OS Specific Functions //// +/////////////////////////////////////////////////////////////////////////////// +void *TPAL_AllocMem( TRUEPHY_PLATFORM_HANDLE hPlatform, u_long ulNumBytes ); +void TPAL_FreeMem( TRUEPHY_PLATFORM_HANDLE hPlatform, void *pMemBlock ); +void TPAL_Sleep( TRUEPHY_PLATFORM_HANDLE hPlatform, u_long ulMsec ); +u_long TPAL_GetSystemUpTime( TRUEPHY_PLATFORM_HANDLE hPlatform ); +void TPAL_GetLinkStatusInfo( struct et131x_adapter *adapter ); + +INT32 TPAL_SetPhy10HalfDuplex( struct et131x_adapter *adapter ); +INT32 TPAL_SetPhy10FullDuplex( struct et131x_adapter *adapter ); +void TPAL_SetPhy10Force( struct et131x_adapter * pAdapter ); +INT32 TPAL_SetPhy100HalfDuplex( struct et131x_adapter *adapter ); +INT32 TPAL_SetPhy100FullDuplex( struct et131x_adapter *adapter ); +void TPAL_SetPhy100Force( struct et131x_adapter * pAdapter ); +INT32 TPAL_SetPhy1000FullDuplex( struct et131x_adapter *adapter); +INT32 TPAL_SetPhyAutoNeg( struct et131x_adapter *adapter ); + + + + +/****************************************************************************** + PROTOTYPES for ET1310_phy.c + *****************************************************************************/ +int et131x_xcvr_find( struct et131x_adapter *adapter ); + +int et131x_setphy_normal( struct et131x_adapter *adapter ); +INT32 et131x_xcvr_init( struct et131x_adapter *adapter ); + +INT32 MiRead( struct et131x_adapter *adapter, + UINT8 xcvrAddr, + UINT8 xcvrReg, + UINT16 *value ); + +INT32 MiWrite( struct et131x_adapter *adapter, + UINT8 xcvrAddr, + UINT8 xcvReg, + UINT16 value ); + +void et131x_Mii_check( struct et131x_adapter *pAdapter, + MI_BMSR_t bmsr, + MI_BMSR_t bmsr_ints ); + + + + +/****************************************************************************** + This last is not strictly required (the driver could call the TPAL + version instead), but this sets the adapter up correctly, and calls the + access routine indirectly. This protects the driver from changes in TPAL. + *****************************************************************************/ +void SetPhy_10BaseTHalfDuplex( struct et131x_adapter *adapter ); + + + + +/****************************************************************************** + Defines for PHY access routines + *****************************************************************************/ +// Define bit operation flags +#define TRUEPHY_BIT_CLEAR 0 +#define TRUEPHY_BIT_SET 1 +#define TRUEPHY_BIT_READ 2 + +// Define read/write operation flags +#ifndef TRUEPHY_READ +#define TRUEPHY_READ 0 +#define TRUEPHY_WRITE 1 +#define TRUEPHY_MASK 2 +#endif + +// Define speeds +#define TRUEPHY_SPEED_10MBPS 0 +#define TRUEPHY_SPEED_100MBPS 1 +#define TRUEPHY_SPEED_1000MBPS 2 + +// Define duplex modes +#define TRUEPHY_DUPLEX_HALF 0 +#define TRUEPHY_DUPLEX_FULL 1 + +// Define master/slave configuration values +#define TRUEPHY_CFG_SLAVE 0 +#define TRUEPHY_CFG_MASTER 1 + +// Define MDI/MDI-X settings +#define TRUEPHY_MDI 0 +#define TRUEPHY_MDIX 1 +#define TRUEPHY_AUTO_MDI_MDIX 2 + +// Define 10Base-T link polarities +#define TRUEPHY_POLARITY_NORMAL 0 +#define TRUEPHY_POLARITY_INVERTED 1 + +// Define auto-negotiation results +#define TRUEPHY_ANEG_NOT_COMPLETE 0 +#define TRUEPHY_ANEG_COMPLETE 1 +#define TRUEPHY_ANEG_DISABLED 2 + +/* Define duplex advertisment flags */ +#define TRUEPHY_ADV_DUPLEX_NONE 0x00 +#define TRUEPHY_ADV_DUPLEX_FULL 0x01 +#define TRUEPHY_ADV_DUPLEX_HALF 0x02 +#define TRUEPHY_ADV_DUPLEX_BOTH \ + (TRUEPHY_ADV_DUPLEX_FULL | TRUEPHY_ADV_DUPLEX_HALF) + +#define PHY_CONTROL 0x00 //#define TRU_MI_CONTROL_REGISTER 0 +#define PHY_STATUS 0x01 //#define TRU_MI_STATUS_REGISTER 1 +#define PHY_ID_1 0x02 //#define TRU_MI_PHY_IDENTIFIER_1_REGISTER 2 +#define PHY_ID_2 0x03 //#define TRU_MI_PHY_IDENTIFIER_2_REGISTER 3 +#define PHY_AUTO_ADVERTISEMENT 0x04 //#define TRU_MI_ADVERTISEMENT_REGISTER 4 +#define PHY_AUTO_LINK_PARTNER 0x05 //#define TRU_MI_LINK_PARTNER_ABILITY_REGISTER 5 +#define PHY_AUTO_EXPANSION 0x06 //#define TRU_MI_EXPANSION_REGISTER 6 +#define PHY_AUTO_NEXT_PAGE_TX 0x07 //#define TRU_MI_NEXT_PAGE_TRANSMIT_REGISTER 7 +#define PHY_LINK_PARTNER_NEXT_PAGE 0x08 //#define TRU_MI_LINK_PARTNER_NEXT_PAGE_REGISTER 8 +#define PHY_1000_CONTROL 0x09 //#define TRU_MI_1000BASET_CONTROL_REGISTER 9 +#define PHY_1000_STATUS 0x0A //#define TRU_MI_1000BASET_STATUS_REGISTER 10 + + +#define PHY_EXTENDED_STATUS 0x0F //#define TRU_MI_EXTENDED_STATUS_REGISTER 15 + +// some defines for modem registers that seem to be 'reserved' +#define PHY_INDEX_REG 0x10 +#define PHY_DATA_REG 0x11 + +#define PHY_MPHY_CONTROL_REG 0x12 //#define TRU_VMI_MPHY_CONTROL_REGISTER 18 + +#define PHY_LOOPBACK_CONTROL 0x13 //#define TRU_VMI_LOOPBACK_CONTROL_1_REGISTER 19 + //#define TRU_VMI_LOOPBACK_CONTROL_2_REGISTER 20 +#define PHY_REGISTER_MGMT_CONTROL 0x15 //#define TRU_VMI_MI_SEQ_CONTROL_REGISTER 21 +#define PHY_CONFIG 0x16 //#define TRU_VMI_CONFIGURATION_REGISTER 22 +#define PHY_PHY_CONTROL 0x17 //#define TRU_VMI_PHY_CONTROL_REGISTER 23 +#define PHY_INTERRUPT_MASK 0x18 //#define TRU_VMI_INTERRUPT_MASK_REGISTER 24 +#define PHY_INTERRUPT_STATUS 0x19 //#define TRU_VMI_INTERRUPT_STATUS_REGISTER 25 +#define PHY_PHY_STATUS 0x1A //#define TRU_VMI_PHY_STATUS_REGISTER 26 +#define PHY_LED_1 0x1B //#define TRU_VMI_LED_CONTROL_1_REGISTER 27 +#define PHY_LED_2 0x1C //#define TRU_VMI_LED_CONTROL_2_REGISTER 28 + //#define TRU_VMI_LINK_CONTROL_REGISTER 29 + //#define TRU_VMI_TIMING_CONTROL_REGISTER + + + + +/****************************************************************************** + Prototypes for PHY access routines + *****************************************************************************/ +void ET1310_PhyInit( struct et131x_adapter *pAdapter ); +void ET1310_PhyReset( struct et131x_adapter *pAdapter ); +void ET1310_PhyPowerDown( struct et131x_adapter *pAdapter, BOOL_t down ); +void ET1310_PhyAutoNeg( struct et131x_adapter *pAdapter, BOOL_t enable ); +void ET1310_PhyDuplexMode( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhySpeedSelect( struct et131x_adapter *pAdapter, UINT16 speed ); +void ET1310_PhyAdvertise1000BaseT( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhyAdvertise100BaseT( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhyAdvertise10BaseT( struct et131x_adapter *pAdapter, UINT16 duplex ); +void ET1310_PhyLinkStatus( struct et131x_adapter *pAdapter, + UCHAR *ucLinkStatus, + UINT32 *uiAutoNeg, + UINT32 *uiLinkSpeed, + UINT32 *uiDuplexMode, + UINT32 *uiMdiMdix, + UINT32 *uiMasterSlave, + UINT32 *uiPolarity ); +void ET1310_PhyAndOrReg( struct et131x_adapter *pAdapter, + UINT16 regnum, + UINT16 andMask, + UINT16 orMask ); +void ET1310_PhyAccessMiBit( struct et131x_adapter *pAdapter, + UINT16 action, + UINT16 regnum, + UINT16 bitnum, + UINT8 *value ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_PHY_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_netdev.h +++ linux-2.6.28/ubuntu/et131x/et131x_netdev.h @@ -0,0 +1,91 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_netdev.h - Defines, structs, enums, prototypes, etc. related to the + * driver's net_device support. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.3 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_NETDEV_H__ +#define __ET131X_NETDEV_H__ + + + + +struct net_device * et131x_device_alloc( void ); + +void et131x_device_free( struct net_device *netdev ); + + + + +#endif /* __ET131X_NETDEV_H__ */ + --- linux-2.6.28.orig/ubuntu/et131x/et131x_main.c +++ linux-2.6.28/ubuntu/et131x/et131x_main.c @@ -0,0 +1,258 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_main.c - This file contains the driver's main Linux entry points. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Modinfo parameters (filled out using defines from et131x_version.h) + *****************************************************************************/ +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_INFO ); +MODULE_LICENSE( DRIVER_LICENSE ); + + + + +/****************************************************************************** + Module Parameters and related data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG + +static u32 et131x_debug_level = DBG_LVL; +static u32 et131x_debug_flags = DBG_DEFAULTS; + +module_param( et131x_debug_level, uint, 0 ); +module_param( et131x_debug_flags, uint, 0 ); + +MODULE_PARM_DESC( et131x_debug_level, + "Level of debugging desired (0-7)" ); + +dbg_info_t et131x_info = { DRIVER_NAME_EXT, 0, 0 }; +dbg_info_t *et131x_dbginfo = &et131x_info; + +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE : et131x_init_module + ****************************************************************************** + + DESCRIPTION : The "main" entry point called on driver initialization + + PARAMETERS : N/A + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_init_module( void ) +{ + int result; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_init_module" ); + + +#ifdef ET131X_DBG + /************************************************************************** + Set the level of debug messages displayed using the module parameter + *************************************************************************/ + et131x_dbginfo->dbgFlags = et131x_debug_flags; + + switch( et131x_debug_level ) + { + case 7: + et131x_dbginfo->dbgFlags |= ( DBG_RX_ON | DBG_TX_ON ); + + case 6: + et131x_dbginfo->dbgFlags |= DBG_PARAM_ON; + + case 5: + et131x_dbginfo->dbgFlags |= DBG_VERBOSE_ON; + + case 4: + et131x_dbginfo->dbgFlags |= DBG_TRACE_ON; + + case 3: + et131x_dbginfo->dbgFlags |= DBG_NOTICE_ON; + + case 2: + case 1: + case 0: + default: + break; + } +#endif /* ET131X_DBG */ + + DBG_ENTER( et131x_dbginfo ); + DBG_PRINT( "%s\n", DRIVER_INFO ); + + + result = et131x_pci_register( ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_cleanup_module + ****************************************************************************** + + DESCRIPTION : The entry point called on driver cleanup + + PARAMETERS : N/A + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_cleanup_module( void ) +{ + DBG_FUNC( "et131x_cleanup_module" ); + DBG_ENTER( et131x_dbginfo ); + + + et131x_pci_unregister( ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + These macros map the driver-specific init_module() and cleanup_module() + routines so they can be called by the kernel. + *****************************************************************************/ +module_init(et131x_init_module); +module_exit(et131x_cleanup_module); --- linux-2.6.28.orig/ubuntu/et131x/ET1310_rx.h +++ linux-2.6.28/ubuntu/et131x/ET1310_rx.h @@ -0,0 +1,488 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_rx.h - Defines, structs, enums, prototypes, etc. pertaining to data + * reception. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:45 $ + $Revision: 1.10 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_RX_H__ +#define __ET1310_RX_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + +#define USE_FBR0 TRUE + +#ifdef USE_FBR0 +//#define FBR0_BUFFER_SIZE 256 +#endif + +//#define FBR1_BUFFER_SIZE 2048 + +#define FBR_CHUNKS 32 + +#define MAX_DESC_PER_RING_RX 1024 + + + + +/****************************************************************************** + number of RFDs - default and min + *****************************************************************************/ +#ifdef USE_FBR0 + #define RFD_LOW_WATER_MARK 40 + #define NIC_MIN_NUM_RFD 64 + #define NIC_DEFAULT_NUM_RFD 1024 +#else + #define RFD_LOW_WATER_MARK 20 + #define NIC_MIN_NUM_RFD 64 + #define NIC_DEFAULT_NUM_RFD 256 +#endif + +#define NUM_PACKETS_HANDLED 256 + +#define ALCATEL_BAD_STATUS 0xe47f0000 +#define ALCATEL_MULTICAST_PKT 0x01000000 +#define ALCATEL_BROADCAST_PKT 0x02000000 + + + + +/****************************************************************************** + typedefs for Free Buffer Descriptors + *****************************************************************************/ +typedef union _FBR_WORD2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 reserved:22; //bits 10-31 + UINT32 bi:10; //bits 0-9(Buffer Index) + #else + UINT32 bi:10; //bits 0-9(Buffer Index) + UINT32 reserved:22; //bit 10-31 + #endif + } bits; +} +FBR_WORD2_t, *PFBR_WORD2_t; + +typedef struct _FBR_DESC_t +{ + UINT32 addr_lo; + UINT32 addr_hi; + FBR_WORD2_t word2; +} +FBR_DESC_t, *PFBR_DESC_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + Typedefs for Packet Status Ring Descriptors + *****************************************************************************/ +typedef union _PKT_STAT_DESC_WORD0_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + // top 16 bits are from the Alcatel Status Word as enumerated in + // PE-MCXMAC Data Sheet IPD DS54 0210-1 (also IPD-DS80 0205-2) +#if 0 + UINT32 asw_trunc:1; //bit 31(Rx frame truncated) +#endif + UINT32 asw_long_evt:1; //bit 31(Rx long event) + UINT32 asw_VLAN_tag:1; //bit 30(VLAN tag detected) + UINT32 asw_unsupported_op:1; //bit 29(unsupported OP code) + UINT32 asw_pause_frame:1; //bit 28(is a pause frame) + UINT32 asw_control_frame:1; //bit 27(is a control frame) + UINT32 asw_dribble_nibble:1; //bit 26(spurious bits after EOP) + UINT32 asw_broadcast:1; //bit 25(has a broadcast address) + UINT32 asw_multicast:1; //bit 24(has a multicast address) + UINT32 asw_OK:1; //bit 23(valid CRC + no code error) + UINT32 asw_too_long:1; //bit 22(frame length > 1518 bytes) + UINT32 asw_len_chk_err:1; //bit 21(frame length field incorrect) + UINT32 asw_CRC_err:1; //bit 20(CRC error) + UINT32 asw_code_err:1; //bit 19(one or more nibbles signalled as errors) + UINT32 asw_false_carrier_event:1; //bit 18(bad carrier since last good packet) + UINT32 asw_RX_DV_event:1; //bit 17(short receive event detected) + UINT32 asw_prev_pkt_dropped:1; //bit 16(e.g. IFG too small on previous) + UINT32 unused:5; //bits 11-15 + UINT32 vp:1; //bit 10(VLAN Packet) + UINT32 jp:1; //bit 9(Jumbo Packet) + UINT32 ft:1; //bit 8(Frame Truncated) + UINT32 drop:1; //bit 7(Drop packet) + UINT32 rxmac_error:1; //bit 6(RXMAC Error Indicator) + UINT32 wol:1; //bit 5(WOL Event) + UINT32 tcpp:1; //bit 4(TCP checksum pass) + UINT32 tcpa:1; //bit 3(TCP checksum assist) + UINT32 ipp:1; //bit 2(IP checksum pass) + UINT32 ipa:1; //bit 1(IP checksum assist) + UINT32 hp:1; //bit 0(hash pass) + #else + UINT32 hp:1; //bit 0(hash pass) + UINT32 ipa:1; //bit 1(IP checksum assist) + UINT32 ipp:1; //bit 2(IP checksum pass) + UINT32 tcpa:1; //bit 3(TCP checksum assist) + UINT32 tcpp:1; //bit 4(TCP checksum pass) + UINT32 wol:1; //bit 5(WOL Event) + UINT32 rxmac_error:1; //bit 6(RXMAC Error Indicator) + UINT32 drop:1; //bit 7(Drop packet) + UINT32 ft:1; //bit 8(Frame Truncated) + UINT32 jp:1; //bit 9(Jumbo Packet) + UINT32 vp:1; //bit 10(VLAN Packet) + UINT32 unused:5; //bits 11-15 + UINT32 asw_prev_pkt_dropped:1; //bit 16(e.g. IFG too small on previous) + UINT32 asw_RX_DV_event:1; //bit 17(short receive event detected) + UINT32 asw_false_carrier_event:1; //bit 18(bad carrier since last good packet) + UINT32 asw_code_err:1; //bit 19(one or more nibbles signalled as errors) + UINT32 asw_CRC_err:1; //bit 20(CRC error) + UINT32 asw_len_chk_err:1; //bit 21(frame length field incorrect) + UINT32 asw_too_long:1; //bit 22(frame length > 1518 bytes) + UINT32 asw_OK:1; //bit 23(valid CRC + no code error) + UINT32 asw_multicast:1; //bit 24(has a multicast address) + UINT32 asw_broadcast:1; //bit 25(has a broadcast address) + UINT32 asw_dribble_nibble:1; //bit 26(spurious bits after EOP) + UINT32 asw_control_frame:1; //bit 27(is a control frame) + UINT32 asw_pause_frame:1; //bit 28(is a pause frame) + UINT32 asw_unsupported_op:1; //bit 29(unsupported OP code) + UINT32 asw_VLAN_tag:1; //bit 30(VLAN tag detected) + UINT32 asw_long_evt:1; //bit 31(Rx long event) +#if 0 + UINT32 asw_trunc:1; //bit 31(Rx frame truncated) +#endif + #endif + } bits; +} +PKT_STAT_DESC_WORD0_t, *PPKT_STAT_WORD0_t; + +typedef union _PKT_STAT_DESC_WORD1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:4; //bits 28-31 + UINT32 ri:2; //bits 26-27(Ring Index) + UINT32 bi:10; //bits 16-25(Buffer Index) + UINT32 length:16; //bit 0-15(length in bytes) + #else + UINT32 length:16; //bit 0-15(length in bytes) + UINT32 bi:10; //bits 16-25(Buffer Index) + UINT32 ri:2; //bits 26-27(Ring Index) + UINT32 unused:4; //bits 28-31 + #endif + } bits; +} +PKT_STAT_DESC_WORD1_t, *PPKT_STAT_WORD1_t; + +typedef struct _PKT_STAT_DESC_t +{ + PKT_STAT_DESC_WORD0_t word0; + PKT_STAT_DESC_WORD1_t word1; +} +PKT_STAT_DESC_t, *PPKT_STAT_DESC_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + Typedefs for the RX DMA status word + *****************************************************************************/ +/****************************************************************************** + RXSTAT_WORD0_t structure holds part of the status bits of the Rx DMA engine + that get copied out to memory by the ET-1310. Word 0 is a 32 bit word which + contains Free Buffer ring 0 and 1 available offset. + *****************************************************************************/ +typedef union _rxstat_word0_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 FBR1unused:5; //bits 27-31 + UINT32 FBR1wrap:1; //bit 26 + UINT32 FBR1offset:10; //bits 16-25 + UINT32 FBR0unused:5; //bits 11-15 + UINT32 FBR0wrap:1; //bit 10 + UINT32 FBR0offset:10; //bits 0-9 + #else + UINT32 FBR0offset:10; //bits 0-9 + UINT32 FBR0wrap:1; //bit 10 + UINT32 FBR0unused:5; //bits 11-15 + UINT32 FBR1offset:10; //bits 16-25 + UINT32 FBR1wrap:1; //bit 26 + UINT32 FBR1unused:5; //bits 27-31 + #endif + } bits; +}RXSTAT_WORD0_t, *PRXSTAT_WORD0_t; + + + + +/****************************************************************************** + RXSTAT_WORD1_t structure holds part of the status bits of the Rx DMA engine + that get copied out to memory by the ET-1310. Word 3 is a 32 bit word which + contains the Packet Status Ring available offset. + *****************************************************************************/ +typedef union _rxstat_word1_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 PSRunused:3; //bits 29-31 + UINT32 PSRwrap:1; //bit 28 + UINT32 PSRoffset:12; //bits 16-27 + UINT32 reserved:16; //bits 0-15 + #else + UINT32 reserved:16; //bits 0-15 + UINT32 PSRoffset:12; //bits 16-27 + UINT32 PSRwrap:1; //bit 28 + UINT32 PSRunused:3; //bits 29-31 + #endif + } bits; +}RXSTAT_WORD1_t, *PRXSTAT_WORD1_t; + + + + +/****************************************************************************** + RX_STATUS_BLOCK_t is sructure representing the status of the Rx DMA engine + it sits in free memory, and is pointed to by 0x101c / 0x1020 + *****************************************************************************/ + +typedef struct _rx_status_block_t +{ + RXSTAT_WORD0_t Word0; + RXSTAT_WORD1_t Word1; +} +RX_STATUS_BLOCK_t, *PRX_STATUS_BLOCK_t; + + + + +/****************************************************************************** + Structure for look-up table holding free buffer ring pointers + *****************************************************************************/ +typedef struct _FbrLookupTable +{ + void *Va [MAX_DESC_PER_RING_RX]; + void *Buffer1 [MAX_DESC_PER_RING_RX]; + void *Buffer2 [MAX_DESC_PER_RING_RX]; + UINT32 PAHigh [MAX_DESC_PER_RING_RX]; + UINT32 PALow [MAX_DESC_PER_RING_RX]; +} FBRLOOKUPTABLE, *PFBRLOOKUPTABLE; + +typedef enum { + ONE_PACKET_INTERRUPT, + FOUR_PACKET_INTERRUPT +} +eRX_INTERRUPT_STATE_t, *PeRX_INTERRUPT_STATE_t; + + + + +/****************************************************************************** + Structure to hold the skb's in a list + *****************************************************************************/ +typedef struct rx_skb_list_elem +{ + struct list_head skb_list_elem; + dma_addr_t dma_addr; + struct sk_buff *skb; +} RX_SKB_LIST_ELEM, *PRX_SKB_LIST_ELEM; + + + + +/****************************************************************************** + RX_RING_t is sructure representing the adaptor's local reference(s) to the + rings + *****************************************************************************/ +typedef struct _rx_ring_t +{ +#ifdef USE_FBR0 + void *pFbr0RingVa; + dma_addr_t pFbr0RingPa; + void *Fbr0MemVa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + dma_addr_t Fbr0MemPa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + UINT64 Fbr0Realpa; + UINT64 Fbr0offset; + RXDMA_FBR_FULL_OFFSET_t local_Fbr0_full; + UINT32 Fbr0NumEntries; + UINT32 Fbr0BufferSize; +#endif + void *pFbr1RingVa; + dma_addr_t pFbr1RingPa; + void *Fbr1MemVa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + dma_addr_t Fbr1MemPa[ MAX_DESC_PER_RING_RX / FBR_CHUNKS ]; + UINT64 Fbr1Realpa; + UINT64 Fbr1offset; + FBRLOOKUPTABLE *Fbr[2]; + RXDMA_FBR_FULL_OFFSET_t local_Fbr1_full; + UINT32 Fbr1NumEntries; + UINT32 Fbr1BufferSize; + + void *pPSRingVa; + dma_addr_t pPSRingPa; + UINT64 pPSRingRealPa; + UINT64 pPSRingOffset; + RXDMA_PSR_FULL_OFFSET_t local_psr_full; + UINT32 PsrNumEntries; + + void *pRxStatusVa; + dma_addr_t pRxStatusPa; + UINT64 RxStatusRealPA; + UINT64 RxStatusOffset; + + struct list_head RecvBufferPool; + + + /************************************************************************** + RECV + *************************************************************************/ + struct list_head RecvList; + struct list_head RecvPendingList; + UINT32 nReadyRecv; + + UINT32 NumRfd; + + BOOL_t UnfinishedReceives; + + struct list_head RecvPacketPool; + + + /************************************************************************** + lookaside lists + *************************************************************************/ + struct kmem_cache *RecvLookaside; +} +RX_RING_t, *PRX_RING_t; + + + + +/****************************************************************************** + Forward reference of RFD + *****************************************************************************/ +struct _MP_RFD; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for Initialization + *****************************************************************************/ +int et131x_rx_dma_memory_alloc( struct et131x_adapter *adapter ); +void et131x_rx_dma_memory_free( struct et131x_adapter *adapter ); +int et131x_rfd_resources_alloc( struct et131x_adapter *adapter, struct _MP_RFD *pMpRfd ); +void et131x_rfd_resources_free( struct et131x_adapter *adapter, struct _MP_RFD *pMpRfd ); +int et131x_init_recv( struct et131x_adapter *adapter ); + +void ConfigRxDmaRegs( struct et131x_adapter *pAdapter ); +void SetRxDmaTimer( struct et131x_adapter *pAdapter ); +void et131x_rx_dma_disable( struct et131x_adapter *pAdapter ); +void et131x_rx_dma_enable( struct et131x_adapter *pAdapter ); + +void et131x_reset_recv( struct et131x_adapter *pAdapter ); + +void et131x_handle_recv_interrupt( struct et131x_adapter *pAdapter ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_RX_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_defs.h +++ linux-2.6.28/ubuntu/et131x/et131x_defs.h @@ -0,0 +1,223 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_defs.h - Defines, structs, enums, prototypes, etc. to assist with OS + * compatibility + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:46 $ + $Revision: 1.8 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_DEFS_H__ +#define __ET131X_DEFS_H__ + + + + +/****************************************************************************** + Define a boolean type + *****************************************************************************/ +typedef enum { FALSE, TRUE } __attribute__ ((packed)) BOOL_t; + + + + +/****************************************************************************** + Packet and header sizes + *****************************************************************************/ +#define NIC_MIN_PACKET_SIZE 60 +#define NIC_HEADER_SIZE ETH_HLEN //14 + + + + +/****************************************************************************** + Multicast list size + *****************************************************************************/ +#define NIC_MAX_MCAST_LIST 128 + + + + +/****************************************************************************** + Supported Filters + *****************************************************************************/ +#define ET131X_PACKET_TYPE_DIRECTED 0x0001 +#define ET131X_PACKET_TYPE_MULTICAST 0x0002 +#define ET131X_PACKET_TYPE_BROADCAST 0x0004 +#define ET131X_PACKET_TYPE_PROMISCUOUS 0x0008 +#define ET131X_PACKET_TYPE_ALL_MULTICAST 0x0010 + + + + +/****************************************************************************** + Tx Timeout + *****************************************************************************/ +#define ET131X_TX_TIMEOUT (1 * HZ) +#define NIC_SEND_HANG_THRESHOLD 0 + + + + +/****************************************************************************** + MP_TCB flags + *****************************************************************************/ +#define fMP_DEST_MULTI 0x00000001 +#define fMP_DEST_BROAD 0x00000002 + + + + +/****************************************************************************** + MP_ADAPTER flags + *****************************************************************************/ +#define fMP_ADAPTER_RECV_LOOKASIDE 0x00000004 +#define fMP_ADAPTER_INTERRUPT_IN_USE 0x00000008 +#define fMP_ADAPTER_SECONDARY 0x00000010 + + + + +/****************************************************************************** + MP_SHARED flags + *****************************************************************************/ +#define fMP_ADAPTER_SHUTDOWN 0x00100000 +#define fMP_ADAPTER_LOWER_POWER 0x00200000 + +#define fMP_ADAPTER_NON_RECOVER_ERROR 0x00800000 +#define fMP_ADAPTER_RESET_IN_PROGRESS 0x01000000 +#define fMP_ADAPTER_NO_CABLE 0x02000000 +#define fMP_ADAPTER_HARDWARE_ERROR 0x04000000 +#define fMP_ADAPTER_REMOVE_IN_PROGRESS 0x08000000 +#define fMP_ADAPTER_HALT_IN_PROGRESS 0x10000000 +#define fMP_ADAPTER_LINK_DETECTION 0x20000000 + +#define fMP_ADAPTER_FAIL_SEND_MASK 0x3ff00000 +#define fMP_ADAPTER_NOT_READY_MASK 0x3ff00000 + + + + +/****************************************************************************** + Some offsets in PCI config space that are actually used. + *****************************************************************************/ +#define ET1310_PCI_PM_CAPABILITY (UINT32)0x40 +#define ET1310_PCI_PM_CSR (UINT32)0x44 +#define ET1310_PCI_MAX_PYLD (UINT32)0x4C +#define ET1310_PCI_DEV_CTRL (UINT32)0x50 +#define ET1310_PCI_DEV_STAT (UINT32)0x52 +#define ET1310_NMI_DISABLE (UINT32)0x61 +#define ET1310_PCI_MAC_ADDRESS (UINT32)0xA4 +#define ET1310_PCI_EEPROM_STATUS (UINT32)0xB2 +#define ET1310_PCI_PHY_INDEX_REG (UINT32)0xB4 +#define ET1310_PCI_ACK_NACK (UINT32)0xC0 +#define ET1310_PCI_REPLAY (UINT32)0xC2 +#define ET1310_PCI_L0L1LATENCY (UINT32)0xCF +#define ET1310_PCI_SEL_PHY_CTRL (UINT32)0xE4 +#define ET1310_PCI_ADVANCED_ERR (UINT32)0x100 + + + + +/****************************************************************************** + PCI Vendor/Product IDs + *****************************************************************************/ +#define ET131X_PCI_VENDOR_ID 0x11C1 // Agere Systems +#define ET131X_PCI_DEVICE_ID_GIG 0xED00 // ET1310 1000 Base-T +#define ET131X_PCI_DEVICE_ID_FAST 0xED01 // ET1310 100 Base-T + + + + +/****************************************************************************** + Define FIELD_OFFSET macro + *****************************************************************************/ +#define FIELD_OFFSET(type,field) ((int)(&((type *)0)->field)) + + + + +/****************************************************************************** + Handle name change of some regsiter bits + *****************************************************************************/ +#define phy_sw_coma pm_phy_sw_coma + + + + +/****************************************************************************** + Define order of magnitude converter + *****************************************************************************/ +#define NANO_IN_A_MICRO 1000 + + + + +#endif /* __ET131X_DEFS_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_netdev.c +++ linux-2.6.28/ubuntu/et131x/et131x_netdev.c @@ -0,0 +1,1624 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_netdev.c - Routines and data required by all Linux network devices. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2007/01/22 23:13:56 $ + $Revision: 1.21 $ + $Name: T_20060131_v1-2-3 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/******************************************************************************* + Includes + ******************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" +#include "ET1310_tx.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_isr.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +int et131x_init( struct net_device *netdev ); + +int et131x_config( struct net_device *netdev, struct ifmap *map ); + +struct net_device_stats *et131x_stats( struct net_device *netdev ); + +int et131x_open( struct net_device *netdev ); + +int et131x_close( struct net_device *netdev ); + +int et131x_ioctl( struct net_device *netdev, struct ifreq *reqbuf, int cmd ); + +void et131x_multicast( struct net_device *netdev ); + +int et131x_tx( struct sk_buff *skb, struct net_device *netdev ); + +void et131x_tx_timeout( struct net_device *netdev ); + +int et131x_change_mtu( struct net_device *netdev, int new_mtu ); + +int et131x_set_mac_addr( struct net_device *netdev, void *new_mac ); + +void et131x_vlan_rx_register( struct net_device *netdev, struct vlan_group *grp ); + +void et131x_vlan_rx_add_vid( struct net_device *netdev, UINT16 vid ); + +void et131x_vlan_rx_kill_vid( struct net_device *netdev, UINT16 vid ); + + + + +/****************************************************************************** + ROUTINE : et131x_device_alloc() + ****************************************************************************** + + DESCRIPTION : Create instances of net_device and wl_private for the + new adapter and register the device's entry points in + the net_device structure. + + PARAMETERS : N/A + + RETURNS : pointer to the allocated and initialized net_device + struct for this device. + + REUSE INFORMATION : + + *****************************************************************************/ +struct net_device * et131x_device_alloc( void ) +{ + struct net_device *netdev = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_device_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Alloc net_device and adapter structs + *************************************************************************/ + netdev = alloc_etherdev( sizeof( ET131X_ADAPTER )); + + if( netdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "Alloc of net_device struct failed\n" ); + DBG_LEAVE( et131x_dbginfo ); + return NULL; + } + + + /************************************************************************** + Setup the function registration table (and other data) for a net_device + *************************************************************************/ + //netdev->init = &et131x_init; + netdev->set_config = &et131x_config; + netdev->get_stats = &et131x_stats; + netdev->open = &et131x_open; + netdev->stop = &et131x_close; + netdev->do_ioctl = &et131x_ioctl; + netdev->set_multicast_list = &et131x_multicast; + netdev->hard_start_xmit = &et131x_tx; + netdev->tx_timeout = &et131x_tx_timeout; + netdev->watchdog_timeo = ET131X_TX_TIMEOUT; + netdev->change_mtu = &et131x_change_mtu; + netdev->set_mac_address = &et131x_set_mac_addr; + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + netdev->vlan_rx_register = &et131x_vlan_rx_register; + netdev->vlan_rx_add_vid = &et131x_vlan_rx_add_vid; + netdev->vlan_rx_kill_vid = &et131x_vlan_rx_kill_vid; +#endif + + //netdev->ethtool_ops = &et131x_ethtool_ops; + + // Poll? + //netdev->poll = &et131x_poll; + //netdev->poll_controller = &et131x_poll_controller; + + + DBG_LEAVE( et131x_dbginfo ); + return netdev; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_device_free() + ****************************************************************************** + + DESCRIPTION : Free the net_device and adapter private resources for + an adapter and perform basic cleanup. + + PARAMETERS : netdev - a pointer to the net_device structure + representing the device whose resources should + be freed. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_device_free( struct net_device *netdev ) +{ + + DBG_FUNC( "et131x_device_free" ); + DBG_ENTER( et131x_dbginfo ); + + if( netdev == NULL ) + { + DBG_WARNING( et131x_dbginfo, "Pointer to net_device == NULL\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + else + { + free_netdev( netdev ); + } + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_init + ****************************************************************************** + + DESCRIPTION : This function is called by the kernel to initialize a + device + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be initialized. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : At the moment, this routine does nothing, as most init + processing needs to be performed before this point. + + *****************************************************************************/ +int et131x_init( struct net_device *netdev ) +{ + + DBG_FUNC( "et131x_init" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_config + ****************************************************************************** + + DESCRIPTION : Implement the SIOCSIFMAP interface. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be configured. + map - a pointer to an ifmap struct + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_config( struct net_device *netdev, struct ifmap *map ) +{ + DBG_FUNC( "et131x_config" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_stats + ****************************************************************************** + + DESCRIPTION : Return the current device statistics. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device whose stats are being queried. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +struct net_device_stats *et131x_stats( struct net_device *netdev ) +{ + ET131X_ADAPTER *adapter = netdev_priv(netdev); + struct net_device_stats *stats = &adapter->net_stats; + CE_STATS_t *devstat = &adapter->Stats; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_stats" ); + DBG_ENTER( et131x_dbginfo ); + + + stats->rx_packets = devstat->ipackets; + stats->tx_packets = devstat->opackets; + stats->rx_errors = devstat->length_err + devstat->alignment_err + + devstat->crc_err + devstat->code_violations + + devstat->other_errors; + stats->tx_errors = devstat->max_pkt_error; + stats->multicast = devstat->multircv; + stats->collisions = devstat->collisions; + + stats->rx_length_errors = devstat->length_err; + stats->rx_over_errors = devstat->rx_ov_flow; + stats->rx_crc_errors = devstat->crc_err; + + // NOTE: These stats don't have corresponding values in CE_STATS, so we're + // going to have to update these directly from within the TX/RX code + //stats->rx_bytes = 20; //devstat->; + //stats->tx_bytes = 20; //devstat->; + //stats->rx_dropped = devstat->; + //stats->tx_dropped = devstat->; + + // NOTE: Not used, can't find analogous statistics + //stats->rx_frame_errors = devstat->; + //stats->rx_fifo_errors = devstat->; + //stats->rx_missed_errors = devstat->; + + //stats->tx_aborted_errors = devstat->; + //stats->tx_carrier_errors = devstat->; + //stats->tx_fifo_errors = devstat->; + //stats->tx_heartbeat_errors = devstat->; + //stats->tx_window_errors = devstat->; + + + DBG_LEAVE( et131x_dbginfo ); + return stats; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_open + ****************************************************************************** + + DESCRIPTION : Open the device for use. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be opened. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_open( struct net_device *netdev ) +{ + int result = 0; + ET131X_ADAPTER *adapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_open" ); + DBG_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + /************************************************************************** + Start the timer to track NIC errors + *************************************************************************/ + add_timer( &adapter->ErrorTimer ); + + + /************************************************************************** + Register our ISR + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Registering ISR...\n" ); + + result = request_irq( netdev->irq, et131x_isr, IRQF_SHARED, netdev->name, netdev ); + if( result ) + { + DBG_ERROR( et131x_dbginfo, "Could not register ISR\n" ); + DBG_LEAVE( et131x_dbginfo ); + return result; + } + + + /************************************************************************** + Enable the Tx and Rx DMA engines (if not already enabled) + *************************************************************************/ + et131x_rx_dma_enable( adapter ); + et131x_tx_dma_enable( adapter ); + + + /************************************************************************** + Enable device interrupts + *************************************************************************/ + et131x_enable_interrupts( adapter ); + + MP_SET_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE ); + + + /************************************************************************** + We're ready to move some data, so start the queue + *************************************************************************/ + netif_start_queue( netdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_close + ****************************************************************************** + + DESCRIPTION : Close the device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device to be opened. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_close( struct net_device *netdev ) +{ + ET131X_ADAPTER *adapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_close" ); + DBG_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + /************************************************************************** + First thing is to stop the queue + *************************************************************************/ + netif_stop_queue( netdev ); + + + /************************************************************************** + Stop the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_disable( adapter ); + et131x_tx_dma_disable( adapter ); + + + /************************************************************************** + Disable device interrupts + *************************************************************************/ + et131x_disable_interrupts( adapter ); + + + /************************************************************************** + Deregistering ISR + *************************************************************************/ + MP_CLEAR_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE ); + + DBG_TRACE( et131x_dbginfo, "Deregistering ISR...\n" ); + free_irq( netdev->irq, netdev ); + + + /************************************************************************** + Stop the error timer + *************************************************************************/ + del_timer_sync( &adapter->ErrorTimer ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_ioctl_mii + ****************************************************************************** + + DESCRIPTION : The function which handles MII IOCTLs + + PARAMETERS : netdev - the net_device struct corresponding to the + device on which the query is being made + reqbuf - the request-specific data buffer + cmd - the command request code + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_ioctl_mii( struct net_device *netdev, struct ifreq *reqbuf, int cmd ) +{ + int status = 0; + ET131X_ADAPTER *pAdapter = netdev_priv(netdev); + struct mii_ioctl_data *data = if_mii( reqbuf ); + UINT16 mii_reg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_ioctl_mii" ); + DBG_ENTER( et131x_dbginfo ); + + + switch( cmd ) + { + case SIOCGMIIPHY: + DBG_VERBOSE( et131x_dbginfo, "SIOCGMIIPHY\n" ); + data->phy_id = pAdapter->Stats.xcvr_addr; + break; + + + case SIOCGMIIREG: + DBG_VERBOSE( et131x_dbginfo, "SIOCGMIIREG\n" ); + if( !capable( CAP_NET_ADMIN )) + { + status = -EPERM; + } + else + { + status = MiRead( pAdapter, + pAdapter->Stats.xcvr_addr, + data->reg_num, + &data->val_out ); + } + + break; + + + case SIOCSMIIREG: + DBG_VERBOSE( et131x_dbginfo, "SIOCSMIIREG\n" ); + if( !capable( CAP_NET_ADMIN )) + { + status = -EPERM; + } + else + { + mii_reg = data->val_in; + + status = MiWrite( pAdapter, + pAdapter->Stats.xcvr_addr, + data->reg_num, + mii_reg ); + } + + break; + + + default: + status = -EOPNOTSUPP; + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_ioctl + ****************************************************************************** + + DESCRIPTION : The I/O Control handler for the driver. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which the control request is + being made. + reqbuf - a pointer to the IOCTL request buffer. + cmd - the IOCTL command code. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_ioctl( struct net_device *netdev, struct ifreq *reqbuf, int cmd ) +{ + int status = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_ioctl" ); + DBG_ENTER( et131x_dbginfo ); + + + switch( cmd ) + { + case SIOCGMIIPHY: + case SIOCGMIIREG: + case SIOCSMIIREG: + status = et131x_ioctl_mii( netdev, reqbuf, cmd ); + break; + + default: +/* DBG_WARNING( et131x_dbginfo, "Unhandled IOCTL Code: 0x%04x\n", cmd );*/ + status = -EOPNOTSUPP; + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_set_packet_filter + ****************************************************************************** + + DESCRIPTION : Configures the Rx Packet filtering on the device + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success, errno on failure + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_set_packet_filter( ET131X_ADAPTER *adapter ) +{ + int status = 0; + UINT32 filter = adapter->PacketFilter; + RXMAC_CTRL_t ctrl = adapter->CSRAddress->rxmac.ctrl; + RXMAC_PF_CTRL_t pf_ctrl = adapter->CSRAddress->rxmac.pf_ctrl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_set_packet_filter" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Default to disabled packet filtering. Enable it in the individual case + statements that require the device to filter something + *************************************************************************/ + ctrl.bits.pkt_filter_disable = 1; + + + /************************************************************************** + Set us to be in promiscuous mode so we receive everything, + this is also true when we get a packet filter of 0 + *************************************************************************/ + if(( filter & ET131X_PACKET_TYPE_PROMISCUOUS ) || filter == 0 ) + { + pf_ctrl.bits.filter_broad_en = 0; + pf_ctrl.bits.filter_multi_en = 0; + pf_ctrl.bits.filter_uni_en = 0; + } + else + { + /********************************************************************** + Set us up with Multicast packet filtering. Three cases are + possible - (1) we have a multi-cast list, (2) we receive ALL + multicast entries or (3) we receive none. + *********************************************************************/ + if( filter & ET131X_PACKET_TYPE_ALL_MULTICAST ) + { + DBG_VERBOSE( et131x_dbginfo, + "Multicast filtering OFF (Rx ALL MULTICAST)\n" ); + pf_ctrl.bits.filter_multi_en = 0; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Multicast filtering ON\n" ); + SetupDeviceForMulticast( adapter ); + pf_ctrl.bits.filter_multi_en = 1; + ctrl.bits.pkt_filter_disable = 0; + } + + + /********************************************************************** + Set us up with Unicast packet filtering + *********************************************************************/ + if( filter & ET131X_PACKET_TYPE_DIRECTED ) + { + DBG_VERBOSE( et131x_dbginfo, "Unicast Filtering ON\n" ); + SetupDeviceForUnicast( adapter ); + pf_ctrl.bits.filter_uni_en = 1; + ctrl.bits.pkt_filter_disable = 0; + } + + + /********************************************************************** + Set us up with Broadcast packet filtering + *********************************************************************/ + if( filter & ET131X_PACKET_TYPE_BROADCAST ) + { + DBG_VERBOSE( et131x_dbginfo, "Broadcast Filtering ON\n" ); + pf_ctrl.bits.filter_broad_en = 1; + ctrl.bits.pkt_filter_disable = 0; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Broadcast Filtering OFF\n" ); + pf_ctrl.bits.filter_broad_en = 0; + } + + + /********************************************************************** + Setup the receive mac configuration registers - Packet Filter + control + the enable / disable for packet filter in the control + reg. + *********************************************************************/ + adapter->CSRAddress->rxmac.pf_ctrl.value = pf_ctrl.value; + adapter->CSRAddress->rxmac.ctrl = ctrl; + } + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_multicast + ****************************************************************************** + + DESCRIPTION : The handler to configure multicasting on the interface. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_multicast( struct net_device *netdev ) +{ + ET131X_ADAPTER *adapter = NULL; + UINT32 PacketFilter = 0; + UINT32 count; + unsigned long lockflags; + struct dev_mc_list *mclist = netdev->mc_list; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_multicast" ); + DBG_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + spin_lock_irqsave( &adapter->Lock, lockflags ); + + + /************************************************************************** + Before we modify the platform-independent filter flags, store them + locally. This allows us to determine if anything's changed and if we + even need to bother the hardware + *************************************************************************/ + PacketFilter = adapter->PacketFilter; + + + /************************************************************************** + Clear the 'multicast' flag locally; becuase we only have a single flag + to check multicast, and multiple multicast addresses can be set, this is + the easiest way to determine if more than one multicast address is being + set. + *************************************************************************/ + PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; + + + /************************************************************************** + Check the net_device flags and set the device independent flags + accordingly + *************************************************************************/ + DBG_VERBOSE( et131x_dbginfo, + "MULTICAST ADDR COUNT: %d\n", + netdev->mc_count ); + + if( netdev->flags & IFF_PROMISC ) + { + DBG_VERBOSE( et131x_dbginfo, "Request: PROMISCUOUS MODE ON\n" ); + adapter->PacketFilter |= ET131X_PACKET_TYPE_PROMISCUOUS; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Request: PROMISCUOUS MODE OFF\n" ); + adapter->PacketFilter &= ~ET131X_PACKET_TYPE_PROMISCUOUS; + } + + + if( netdev->flags & IFF_ALLMULTI ) + { + DBG_VERBOSE( et131x_dbginfo, "Request: ACCEPT ALL MULTICAST\n" ); + adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; + } + + + if( netdev->mc_count > NIC_MAX_MCAST_LIST ) + { + DBG_WARNING( et131x_dbginfo, + "ACCEPT ALL MULTICAST for now, as there's more Multicast " + "addresses than the HW supports\n" ); + + adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; + } + + + if( netdev->mc_count < 1 ) + { + DBG_VERBOSE( et131x_dbginfo, "Request: REJECT ALL MULTICAST\n" ); + adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST; + adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; + } + else + { + DBG_VERBOSE( et131x_dbginfo, "Request: SET MULTICAST FILTER(S)\n" ); + adapter->PacketFilter |= ET131X_PACKET_TYPE_MULTICAST; + } + + + /************************************************************************** + Set values in the private adapter struct + *************************************************************************/ + adapter->MCAddressCount = netdev->mc_count; + + if( netdev->mc_count ) + { + if( mclist->dmi_addrlen != ETH_ALEN ) + { + DBG_WARNING( et131x_dbginfo, "Multicast addrs are not ETH_ALEN in size\n" ); + } + else + { + count = netdev->mc_count - 1; + memcpy( adapter->MCList[count], mclist->dmi_addr, ETH_ALEN ); + } + } + + + /************************************************************************** + Are the new flags different from the previous ones? If not, then no + action is required + + NOTE - This block will always update the MCList with the hardware, even + if the addresses aren't the same. + *************************************************************************/ + if( PacketFilter != adapter->PacketFilter ) + { + /********************************************************************** + Call the device's filter function + *********************************************************************/ + DBG_VERBOSE( et131x_dbginfo, + "UPDATE REQUIRED, FLAGS changed\n" ); + + et131x_set_packet_filter( adapter ); + } + else + { + DBG_VERBOSE( et131x_dbginfo, + "NO UPDATE REQUIRED, FLAGS didn't change\n" ); + } + + + spin_unlock_irqrestore( &adapter->Lock, lockflags ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_tx + ****************************************************************************** + + DESCRIPTION : The handler called when the Linux network layer wants + to a Tx a packet on the device. + + PARAMETERS : skb - a pointer to the sk_buff structure which + represents the data to be Tx'd. + netdev - a pointer to a net_device struct representing + the device on which data is to be Tx'd. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_tx( struct sk_buff *skb, struct net_device *netdev ) +{ + int status = 0; + ET131X_ADAPTER *adapter; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + adapter = netdev_priv( netdev ); + + + /************************************************************************** + Save the timestamp for the TX timeout watchdog + *************************************************************************/ + netdev->trans_start = jiffies; + + + /************************************************************************** + Call the device-specific data Tx routine + *************************************************************************/ + status = et131x_send_packets( skb, netdev ); + + + /************************************************************************** + Check status and manage the netif queue if necessary + *************************************************************************/ + if( status != 0 ) + { + if( status == -ENOMEM ) + { + DBG_VERBOSE( et131x_dbginfo, "OUT OF TCBs; STOP NETIF QUEUE\n" ); + + /* Put the queue to sleep until resources are available */ + netif_stop_queue( netdev ); + status = 1; + } + else + { + DBG_WARNING( et131x_dbginfo, "Misc error; drop packet\n" ); + status = 0; + } + } + + DBG_TX_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_tx_timeout + ****************************************************************************** + + DESCRIPTION : The handler called when a Tx request times out. The + timeout period is specified by the 'tx_timeo" element in + the net_device structure (see et131x_alloc_device() to + see how this value is set). + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_tx_timeout( struct net_device *netdev ) +{ + ET131X_ADAPTER *pAdapter = netdev_priv( netdev ); + PMP_TCB pMpTcb; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_timeout" ); + DBG_WARNING( et131x_dbginfo, "TX TIMEOUT\n" ); + + + /************************************************************************** + Just skip this part if the adapter is doing link detection + *************************************************************************/ + if( MP_TEST_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION )) + { + DBG_ERROR( et131x_dbginfo, "Still doing link detection\n" ); + return; + } + + + /************************************************************************** + Any nonrecoverable hardware error? + Checks adapter->flags for any failure in phy reading + *************************************************************************/ + if( MP_TEST_FLAG( pAdapter, fMP_ADAPTER_NON_RECOVER_ERROR )) + { + DBG_WARNING( et131x_dbginfo, "Non recoverable error - remove\n" ); + return; + } + + + /************************************************************************** + Hardware failure? + *************************************************************************/ + if( MP_TEST_FLAG( pAdapter, fMP_ADAPTER_HARDWARE_ERROR )) + { + DBG_WARNING( et131x_dbginfo, "hardware error - reset\n" ); + return; + } + + /************************************************************************** + Is send stuck? + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + + if( pMpTcb != NULL ) + { + pMpTcb->Count++; + + if( pMpTcb->Count > NIC_SEND_HANG_THRESHOLD ) + { +#ifdef ET131X_DBG + TX_STATUS_BLOCK_t txDmaComplete = *( pAdapter->TxRing.pTxStatusVa ); + PTX_DESC_ENTRY_t pDesc = pAdapter->TxRing.pTxDescRingVa + + pMpTcb->WrIndex.bits.serv_req; +#endif + TX_DESC_ENTRY_t StuckDescriptors[10]; + + if( pMpTcb->WrIndex.bits.serv_req > 7 ) + { + memcpy( StuckDescriptors, + pAdapter->TxRing.pTxDescRingVa + pMpTcb->WrIndex.bits.serv_req - 6, + sizeof( TX_DESC_ENTRY_t ) * 10 ); + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + + DBG_WARNING( et131x_dbginfo, + "Send stuck - reset. pMpTcb->WrIndex %x, Flags 0x%08x\n", + pMpTcb->WrIndex.bits.serv_req, pMpTcb->Flags ); + + DBG_WARNING( et131x_dbginfo, + "pDesc 0x%08x, 0x%08x, 0x%08x, 0x%08x\n", + pDesc->DataBufferPtrHigh, pDesc->DataBufferPtrLow, + pDesc->word2.value, pDesc->word3.value ); + + DBG_WARNING( et131x_dbginfo, + "WbStatus 0x%08x\n", + txDmaComplete.value ); + +#ifdef ET131X_DBG + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 0 ); + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 1 ); + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 3 ); + DumpDeviceBlock( DBG_WARNING_ON, pAdapter, 5 ); +#endif + et131x_close( netdev ); + et131x_open( netdev ); + + return; + } + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_change_mtu + ****************************************************************************** + + DESCRIPTION : The handler called to change the MTU for the device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device whose MTU is to be changed. + + new_mtu - the desired MTU. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_change_mtu( struct net_device *netdev, int new_mtu ) +{ + int result = 0; + ET131X_ADAPTER *adapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_change_mtu" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Get the private adapter structure + *************************************************************************/ + adapter = netdev_priv( netdev ); + + if( adapter == NULL ) + { + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + + /************************************************************************** + Make sure the requested MTU is valid + *************************************************************************/ + if( new_mtu == 0 || new_mtu > 9216 ) + { + DBG_LEAVE( et131x_dbginfo ); + return -EINVAL; + } + + + /************************************************************************** + Stop the netif queue + *************************************************************************/ + netif_stop_queue( netdev ); + + + /************************************************************************** + Stop the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_disable( adapter ); + et131x_tx_dma_disable( adapter ); + + + /************************************************************************** + Disable device interrupts + *************************************************************************/ + et131x_disable_interrupts( adapter ); + et131x_handle_send_interrupt( adapter ); + et131x_handle_recv_interrupt( adapter ); + + + /************************************************************************** + Set the new MTU + *************************************************************************/ + netdev->mtu = new_mtu; + + + /************************************************************************** + Free Rx DMA memory + *************************************************************************/ + et131x_adapter_memory_free( adapter ); + + + /************************************************************************** + Set the config parameter for Jumbo Packet support + *************************************************************************/ + adapter->RegistryJumboPacket = new_mtu + 14; + et131x_soft_reset( adapter ); + + + /************************************************************************** + Alloc and init Rx DMA memory + *************************************************************************/ + result = et131x_adapter_memory_alloc( adapter ); + if( result != 0 ) + { + DBG_WARNING( et131x_dbginfo, + "Change MTU failed; couldn't re-alloc DMA memory\n" ); + return result; + } + + et131x_init_send( adapter ); + + + et131x_setup_hardware_properties( adapter ); + memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); + et131x_init_enet_crc_calc( ); + + + /************************************************************************** + Init the device with the new settings + *************************************************************************/ + et131x_adapter_setup( adapter ); + + + /************************************************************************** + Enable interrupts + *************************************************************************/ + if( MP_TEST_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE )) + { + et131x_enable_interrupts( adapter ); + } + + + /************************************************************************** + Restart the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_enable( adapter ); + et131x_tx_dma_enable( adapter ); + + + /************************************************************************** + Restart the netif queue + *************************************************************************/ + netif_wake_queue( netdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_set_mac_addr + ****************************************************************************** + + DESCRIPTION : The handler called to change the MAC address for the + device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device whose MAC is to be changed. + + new_mac - a buffer containing a sock_addr struct in which + the desired MAC address is stored. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + IMPLEMENTED BY : blux http://berndlux.de 22.01.2007 21:14 + + *****************************************************************************/ +int et131x_set_mac_addr( struct net_device *netdev, void *new_mac ) +{ + int result = 0; + ET131X_ADAPTER *adapter = NULL; + struct sockaddr *address = new_mac; + + DBG_FUNC( "et131x_set_mac_addr" ); + DBG_ENTER( et131x_dbginfo ); + // begin blux + // DBG_VERBOSE( et131x_dbginfo, "Function not implemented!!\n" ); + + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Get the private adapter structure + *************************************************************************/ + adapter = netdev_priv( netdev ); + + if( adapter == NULL ) + { + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + + /************************************************************************** + Make sure the requested MAC is valid + *************************************************************************/ + if (!is_valid_ether_addr(address->sa_data)) + { + DBG_LEAVE( et131x_dbginfo ); + return -EINVAL; + } + + + /************************************************************************** + Stop the netif queue + *************************************************************************/ + netif_stop_queue( netdev ); + + + /************************************************************************** + Stop the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_disable( adapter ); + et131x_tx_dma_disable( adapter ); + + + /************************************************************************** + Disable device interrupts + *************************************************************************/ + et131x_disable_interrupts( adapter ); + et131x_handle_send_interrupt( adapter ); + et131x_handle_recv_interrupt( adapter ); + + + /************************************************************************** + Set the new MAC + *************************************************************************/ + // netdev->set_mac_address = &new_mac; + // netdev->mtu = new_mtu; + + + memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); + + printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", netdev->name, + netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], + netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); + + + /************************************************************************** + Free Rx DMA memory + *************************************************************************/ + et131x_adapter_memory_free( adapter ); + + + /************************************************************************** + Set the config parameter for Jumbo Packet support + *************************************************************************/ + //adapter->RegistryJumboPacket = new_mtu + 14; + // blux: not needet here, w'll change the MAC + + et131x_soft_reset( adapter ); + + + /************************************************************************** + Alloc and init Rx DMA memory + *************************************************************************/ + result = et131x_adapter_memory_alloc( adapter ); + if( result != 0 ) + { + DBG_WARNING( et131x_dbginfo, + "Change MAC failed; couldn't re-alloc DMA memory\n" ); + return result; + } + + et131x_init_send( adapter ); + + + et131x_setup_hardware_properties( adapter ); + // memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); + // blux: no, do not override our nice address + et131x_init_enet_crc_calc( ); + + + /************************************************************************** + Init the device with the new settings + *************************************************************************/ + et131x_adapter_setup( adapter ); + + + /************************************************************************** + Enable interrupts + *************************************************************************/ + if( MP_TEST_FLAG( adapter, fMP_ADAPTER_INTERRUPT_IN_USE )) + { + et131x_enable_interrupts( adapter ); + } + + + /************************************************************************** + Restart the Tx and Rx DMA engines + *************************************************************************/ + et131x_rx_dma_enable( adapter ); + et131x_tx_dma_enable( adapter ); + + + /************************************************************************** + Restart the netif queue + *************************************************************************/ + netif_wake_queue( netdev ); + + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + NOTE: The ET1310 doesn't support hardware VLAN tagging, so these functions + are currently not used; they are in place to eventually support the + feature if needed. + *****************************************************************************/ + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + +/****************************************************************************** + ROUTINE : et131x_vlan_rx_register + ****************************************************************************** + + DESCRIPTION : The handler called to enable or disable VLAN support on + the device. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which VLAN should be enabled or + disabled. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_vlan_rx_register( struct net_device *netdev, struct vlan_group *grp ) +{ + ET131X_ADAPTER *pAdapter = netdev_priv( netdev ); + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_vlan_rx_register" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Track the vlan_group struct in the adapter private structure; if this + element is NULL, then VLAN is disabled; otherwise, it is enabled. + *************************************************************************/ + if( grp ) + { + DBG_VERBOSE( et131x_dbginfo, "VLAN: Enable, 0x%p\n", grp ); + } + else + { + DBG_VERBOSE( et131x_dbginfo, "VLAN: Disable\n" ); + } + + pAdapter->vlgrp = grp; + + + /************************************************************************** + This is where any interfacing with the hardware to enable or disable + VLAN would be done. Since the ET1310 doesn't handle this in hardware, + nothing else needs to be done. + *************************************************************************/ + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_vlan_rx_add_vid + ****************************************************************************** + + DESCRIPTION : The handler called to register a VLAN tag. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which a VLAN tag should be added. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_vlan_rx_add_vid( struct net_device *netdev, UINT16 vid ) +{ + DBG_FUNC( "et131x_vlan_rx_add_vid" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_VERBOSE( et131x_dbginfo, "VLAN, Add VID: %d\n", vid ); + + + /************************************************************************** + This is where any interfacing with the hardware to register VLAN IDs + would take place. Since the ET1310 doesn't handle this in hardware, + nothing else needs to be done here; the vlan_group structure's + vlan_devices element can be used in the TX/RX routines to determine if + a VLAN tag has been 'registered' with the device. + *************************************************************************/ + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_vlan_rx_kill_vid + ****************************************************************************** + + DESCRIPTION : The handler called to deregister a VLAN tag. + + PARAMETERS : netdev - a pointer to a net_device struct representing + the device on which a VLAN tag should be + removed. + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_vlan_rx_kill_vid( struct net_device *netdev, UINT16 vid ) +{ + ET131X_ADAPTER *pAdapter = netdev_priv( netdev ); + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_vlan_rx_kill_vid" ); + DBG_ENTER( et131x_dbginfo ); + + + DBG_VERBOSE( et131x_dbginfo, "VLAN, Remove VID: %d\n", vid ); + + if( pAdapter->vlgrp ) + { + pAdapter->vlgrp->vlan_devices_arrays[vid] = NULL; + } + + + /************************************************************************** + This is where any interfacing with the hardware to deregister VLAN IDs + would take place. Since the ET1310 doesn't handle this in hardware, + nothing else needs to be done here. + *************************************************************************/ + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + +#endif --- linux-2.6.28.orig/ubuntu/et131x/ET1310_jagcore.c +++ linux-2.6.28/ubuntu/et131x/ET1310_jagcore.c @@ -0,0 +1,642 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_jagcore.c - All code pertaining to the ET1301/ET131x's JAGcore + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:44 $ + $Revision: 1.9 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE: ConfigGlobalRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the global registers on the JAGCore + + PARAMETERS : + pAdpater - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigGlobalRegs( ET131X_ADAPTER *pAdapter ) +{ + PGLOBAL_t pGbl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigGlobalRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Map a local pointer to the global section of the JAGCore + *************************************************************************/ + pGbl = &pAdapter->CSRAddress->global; + + if( pAdapter->RegistryPhyLoopbk == FALSE ) + { + if( pAdapter->RegistryJumboPacket < 2048 ) + { + /****************************************************************** + Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word block of RAM + that the driver can split between Tx and Rx as it desires. Our + default is to split it 50/50: + *****************************************************************/ + pGbl->rxq_start_addr.value = 0; + pGbl->rxq_end_addr.value = pAdapter->RegistryRxMemEnd; + pGbl->txq_start_addr.value = pGbl->rxq_end_addr.bits.rxq_end_addr + 1; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + } + else if( pAdapter->RegistryJumboPacket < 8192 ) + { + /****************************************************************** + For jumbo packets > 2k in length, but < 8k, split 50-50. + *****************************************************************/ + pGbl->rxq_start_addr.value = 0; + pGbl->rxq_end_addr.value = INTERNAL_MEM_RX_OFFSET; + pGbl->txq_start_addr.value = INTERNAL_MEM_RX_OFFSET + 1; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + } + else + { + /****************************************************************** + 9216 is the only packet size greater than 8k that is available. + The Tx buffer has to be big enough for one whole packet on the + Tx side. We'll make the Tx 9408, and give the rest to Rx + *****************************************************************/ + pGbl->rxq_start_addr.value = 0x0000; + pGbl->rxq_end_addr.value = 0x01b3; + pGbl->txq_start_addr.value = 0x01b4; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + } + + /********************************************************************** + Initialize the loopback register. Disable all loopbacks. + *********************************************************************/ + pGbl->loopback.value = 0x0; + } + else + { + /************************************************************************** + For PHY Line loopback, the memory is configured as if Tx and Rx both + have all the memory. This is because the RxMAC will write data into + the space, and the TxMAC will read it out. + *************************************************************************/ + pGbl->rxq_start_addr.value = 0; + pGbl->rxq_end_addr.value = INTERNAL_MEM_SIZE - 1; + pGbl->txq_start_addr.value = 0; + pGbl->txq_end_addr.value = INTERNAL_MEM_SIZE - 1; + + /************************************************************************** + Initialize the loopback register (MAC loopback). + *************************************************************************/ + pGbl->loopback.value = 0x1; + } + + /************************************************************************** + MSI Register + *************************************************************************/ + pGbl->msi_config.value = 0x0; + + + /************************************************************************** + By default, disable the watchdog timer. It will be enabled when + a packet is queued. + *************************************************************************/ + pGbl->watchdog_timer = 0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigMMCRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the main memory registers in the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMMCRegs( ET131X_ADAPTER *pAdapter ) +{ + MMC_CTRL_t mmc_ctrl = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMMCRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + All we need to do is initialize the Memory Control Register + *************************************************************************/ + mmc_ctrl.bits.force_ce = 0x0; + mmc_ctrl.bits.rxdma_disable = 0x0; + mmc_ctrl.bits.txdma_disable = 0x0; + mmc_ctrl.bits.txmac_disable = 0x0; + mmc_ctrl.bits.rxmac_disable = 0x0; + mmc_ctrl.bits.arb_disable = 0x0; + mmc_ctrl.bits.mmc_enable = 0x1; + + pAdapter->CSRAddress->mmc.mmc_ctrl.value = mmc_ctrl.value; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_enable_interrupts + ****************************************************************************** + + DESCRIPTION : Enable interupts on the ET131x + + PARAMETERS : adapter - a pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_enable_interrupts( ET131X_ADAPTER *adapter ) +{ + UINT32 MaskValue; + + + /************************************************************************** + Enable all global interrupts + *************************************************************************/ + if(( adapter->FlowControl == TxOnly ) || + ( adapter->FlowControl == Both )) + { + MaskValue = INT_MASK_ENABLE; + } + else + { + MaskValue = INT_MASK_ENABLE_NO_FLOW; + } + + if( adapter->DriverNoPhyAccess ) + { + MaskValue |= 0x10000; + } + + adapter->CachedMaskValue.value = MaskValue; + adapter->CSRAddress->global.int_mask.value = MaskValue; + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_disable_interrupts + ****************************************************************************** + + DESCRIPTION : Enable interrupts on the ET131x + + PARAMETERS : adapter - a pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ + +void et131x_disable_interrupts( ET131X_ADAPTER *adapter ) +{ + /************************************************************************** + Disable all global interrupts + *************************************************************************/ + adapter->CachedMaskValue.value = INT_MASK_DISABLE; + adapter->CSRAddress->global.int_mask.value = INT_MASK_DISABLE; + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: NICGetRegs + ****************************************************************************** + + DESCRIPTION: + function used to get register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing registers to get + ulBytesAvailable - + ulInfoLen - + + RETURN : + NONE + + *****************************************************************************/ +void * et131x_get_regs( ET131X_ADAPTER *pAdapter, void *InfoBuf, + PUINT32 ulBytesAvailable, PUINT32 ulInfoLen ) +{ + INT32 nRegCount; + PINT8 pJCBase; + INT32 x; + PUINT32 pReg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_get_regs" ); + DBG_ENTER( et131x_dbginfo ); + + + memset( (void *)&pAdapter->JagCoreRegs, 0, sizeof( JAGCORE_ACCESS_REGS )); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->JagCoreRegs = *(PJAGCORE_ACCESS_REGS)InfoBuf; + nRegCount = pAdapter->JagCoreRegs.nRegCount; + + pJCBase = (PINT8)&pAdapter->CSRAddress->global; + + for( x = 0; x < nRegCount; x++ ) + { + pReg = (PUINT32)( pJCBase+pAdapter->JagCoreRegs.nOffsets[x] ); + + pAdapter->JagCoreRegs.nData[x] = *pReg; + } + + *ulBytesAvailable = sizeof( JAGCORE_ACCESS_REGS ); + *ulInfoLen = sizeof( JAGCORE_ACCESS_REGS ); + + + DBG_LEAVE( et131x_dbginfo ); + return( (void *)&pAdapter->JagCoreRegs ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_set_regs + ****************************************************************************** + + DESCRIPTION: + function used to set register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing register offset and data + to set + RETURN : + N/A + + *****************************************************************************/ +void et131x_set_regs( ET131X_ADAPTER *pAdapter, void *InfoBuf ) +{ + INT32 nRegCount; + PINT8 pJCBase; + INT32 x; + PUINT32 pReg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_set_regs" ); + DBG_ENTER( et131x_dbginfo ); + + + memset( (void *)&pAdapter->JagCoreRegs, 0, sizeof( JAGCORE_ACCESS_REGS )); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->JagCoreRegs = *(PJAGCORE_ACCESS_REGS)InfoBuf; + + nRegCount = pAdapter->JagCoreRegs.nRegCount; + + pJCBase = (PINT8)&pAdapter->CSRAddress->global; + + for( x = 0; x < nRegCount; x++ ) + { + pReg = (PUINT32)(pJCBase+pAdapter->JagCoreRegs.nOffsets[x]); + *pReg = pAdapter->JagCoreRegs.nData[x]; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: GetPciCfgRegs + ****************************************************************************** + + DESCRIPTION: + function used to get register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing registers to get + ulBytesAvailable - + ulInfoLen - + + RETURN : + NONE + + *****************************************************************************/ +void * GetPciCfgRegs( ET131X_ADAPTER *pAdapter, void * InfoBuf, + PUINT32 ulBytesAvailable, PUINT32 ulInfoLen ) +{ + INT32 nRegCount; + UINT32 ByteLength = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "GetPciCfgRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->PciCfgRegs = *(PPCI_CFG_SPACE_REGS)InfoBuf; + nRegCount = pAdapter->PciCfgRegs.nRegCount; + + + /************************************************************************** + Support for 8,16,32 bit widths + *************************************************************************/ + ByteLength = pAdapter->PciCfgRegs.nDataWidth/8; + + pci_slot_information_read( pAdapter->pdev, + pAdapter->PciCfgRegs.nOffsets[0], + (UINT8 *)&pAdapter->PciCfgRegs.nData, + ByteLength * nRegCount ); + + *ulBytesAvailable = sizeof( PCI_CFG_SPACE_REGS ); + *ulInfoLen = sizeof( PCI_CFG_SPACE_REGS ); + + + DBG_LEAVE( et131x_dbginfo ); + return( (void *)&pAdapter->PciCfgRegs ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: SetPciCfgRegs + ****************************************************************************** + + DESCRIPTION: + function used to set register data + + PARAMETERS : + pAdapter - pointer to our adapter structure + InfoBuf - pointer to data struct containing register offset and data + to set + RETURN : + N/A + + *****************************************************************************/ +void SetPciCfgRegs( ET131X_ADAPTER *pAdapter, void * InfoBuf ) +{ + INT32 nRegCount; + INT32 x; + UINT32 ByteLength = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "SetPciCfgRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + memset( (void *)&pAdapter->PciCfgRegs, 0, sizeof( PCI_CFG_SPACE_REGS )); + + + /************************************************************************** + Get the user supplied data + *************************************************************************/ + pAdapter->PciCfgRegs = *(PPCI_CFG_SPACE_REGS)InfoBuf; + + nRegCount = pAdapter->PciCfgRegs.nRegCount; + ByteLength = pAdapter->PciCfgRegs.nDataWidth/8; + + for( x = 0; x < nRegCount; x++ ) + { + pci_slot_information_write( pAdapter->pdev, + pAdapter->PciCfgRegs.nOffsets[x], + (UINT8 *)&pAdapter->PciCfgRegs.nData[x * ByteLength], + ByteLength ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: MemTest + ****************************************************************************** + + DESCRIPTION: + function used to test rx/tx queue memory at 0x0 and 0x200 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURN : + TRUE or FALSE + + *****************************************************************************/ +BOOL_t MemTest( ET131X_ADAPTER *pAdapter, UINT32 addr ) +{ + UINT32 data; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "MemTest" ); + DBG_ENTER( et131x_dbginfo ); + + + // Read initial value + pAdapter->CSRAddress->mmc.sram_access.value = 1; + data = pAdapter->CSRAddress->mmc.sram_word1.data; + + + // Write test value + pAdapter->CSRAddress->mmc.sram_word1.data = 0xdeadbeef; + pAdapter->CSRAddress->mmc.sram_access.value = 0xf003; + + + // Read back test value + pAdapter->CSRAddress->mmc.sram_access.bits.req_access = 1; + if ( pAdapter->CSRAddress->mmc.sram_word1.data != 0xdeadbeef ) + { + DBG_LEAVE( et131x_dbginfo ); + return FALSE; + } + + // Restore initial value + pAdapter->CSRAddress->mmc.sram_word1.data = data; + pAdapter->CSRAddress->mmc.sram_access.value = 0xf003; + + + DBG_LEAVE( et131x_dbginfo ); + return TRUE; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_pm.h +++ linux-2.6.28/ubuntu/et131x/ET1310_pm.h @@ -0,0 +1,216 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_pm.h - Defines, structs, enums, prototypes, etc. pertaining to power + * management. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:11 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_PM_H_ +#define _ET1310_PM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +/****************************************************************************** + CONSTANTS FOR POWER MANAGEMENT + *****************************************************************************/ +#define MAX_WOL_PACKET_SIZE 0x80 +#define MAX_WOL_MASK_SIZE ( MAX_WOL_PACKET_SIZE / 8 ) +#define NUM_WOL_PATTERNS 0x5 +#define CRC16_POLY 0x1021 + + + + +/****************************************************************************** + Definition of NDIS_DEVICE_POWER_STATE + *****************************************************************************/ +typedef enum +{ + NdisDeviceStateUnspecified = 0, + NdisDeviceStateD0, + NdisDeviceStateD1, + NdisDeviceStateD2, + NdisDeviceStateD3 +} NDIS_DEVICE_POWER_STATE; + + + + +/****************************************************************************** + Structure for Power Management Info + *****************************************************************************/ +typedef struct _MP_PM_CONFIG_SPACE_INFO_t +{ + UCHAR capId; + UCHAR nextItemPtr; + UINT16 pmcr; + UINT16 pmcsr; + UCHAR pmscr_bse; + UCHAR pm_data_regs; +} +MP_PM_CONFIG_SPACE_INFO_t, *pMP_PM_CONFIG_SPACE_INFO_t; + + + + +typedef struct _MP_POWER_MGMT +{ + /************************************************************************** + variable putting the phy into coma mode when boot up with no cable + plugged in after 5 seconds + *************************************************************************/ + UCHAR TransPhyComaModeOnBoot; + + + /************************************************************************** + Array holding the five CRC values that the device is currently using + for WOL. This will be queried when a pattern is to be removed. + *************************************************************************/ + UINT32 localWolAndCrc0; + UINT16 WOLPatternList[ NUM_WOL_PATTERNS ]; + UCHAR WOLMaskList[ NUM_WOL_PATTERNS ][ MAX_WOL_MASK_SIZE ]; + UINT32 WOLMaskSize[ NUM_WOL_PATTERNS ]; + + + /************************************************************************** + IP address + *************************************************************************/ + union + { + UINT32 u32; + UCHAR u8[4]; + } IPAddress; + + + /************************************************************************** + Current Power state of the adapter. + *************************************************************************/ + NDIS_DEVICE_POWER_STATE PowerState; + BOOL_t WOLState; + BOOL_t WOLEnabled; + BOOL_t Failed10Half; + BOOL_t bFailedStateTransition; + + /************************************************************************** + Next two used to save power information at power down. + This information will be used during power up to set up parts of Power + Management in JAGCore + *************************************************************************/ + UINT32 tx_en; + UINT32 rx_en; + UINT16 PowerDownSpeed; + UCHAR PowerDownDuplex; + + MP_PM_CONFIG_SPACE_INFO_t pmConfigRegs; +} MP_POWER_MGMT, *PMP_POWER_MGMT; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + ( IS THERE A WAY TO DO THIS WITH A TYPEDEF??? ) + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for ET1310_pm.c + *****************************************************************************/ +UINT16 CalculateCCITCRC16( PUCHAR Pattern, PUCHAR Mask, UINT32 MaskSize ); + +void EnablePhyComa( struct et131x_adapter *pAdapter ); + +void DisablePhyComa( struct et131x_adapter *pAdapter ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_PM_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_phy.c +++ linux-2.6.28/ubuntu/et131x/ET1310_phy.c @@ -0,0 +1,2728 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_phy.c - Routines for configuring and accessing the PHY + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.13 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_netdev.h" +#include "et131x_initpci.h" + +#include "ET1310_address_map.h" +#include "ET1310_jagcore.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" +#include "ET1310_mac.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +int et131x_xcvr_init( ET131X_ADAPTER *adapter ); + + + + +/****************************************************************************** + ROUTINE : MiRead + ****************************************************************************** + + DESCRIPTION : Used to read from the PHY through the MII Interface on + the MAC. + + PARAMETERS : adapter - pointer to our private adapter structure + xcvrAddr - the address of the transciever + xcvrReg - the register to read + value - pointer to a 16-bit value in which the value + will be stored. + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int MiRead( ET131X_ADAPTER *adapter, UINT8 xcvrAddr, UINT8 xcvrReg, UINT16 *value ) +{ + int status = 0; + UINT32 delay; + MII_MGMT_ADDR_t miiAddr; + MII_MGMT_CMD_t miiCmd; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "MiRead" ); + + + /************************************************************************** + Save a local copy of the registers we are dealing with so we can set + them back + *************************************************************************/ + miiAddr.value = adapter->CSRAddress->mac.mii_mgmt_addr.value; + miiCmd.value = adapter->CSRAddress->mac.mii_mgmt_cmd.value; + + + /************************************************************************** + Stop the current operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + + /************************************************************************** + Set up the register we need to read from on the correct PHY + *************************************************************************/ + { + MII_MGMT_ADDR_t mii_mgmt_addr = {0}; + + mii_mgmt_addr.bits.phy_addr = xcvrAddr; + mii_mgmt_addr.bits.reg_addr = xcvrReg; + + adapter->CSRAddress->mac.mii_mgmt_addr = mii_mgmt_addr; + } + + + /************************************************************************** + Kick the read cycle off + *************************************************************************/ + delay = 0; + + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x1; + + do + { + udelay( 50 ); + delay++; + } while(( adapter->CSRAddress->mac.mii_mgmt_indicator.bits.not_valid || + adapter->CSRAddress->mac.mii_mgmt_indicator.bits.busy ) && + ( delay < 50 )); + + + /************************************************************************** + If we hit the max delay, we could not read the register + *************************************************************************/ + if( delay >= 50 ) + { + DBG_WARNING( et131x_dbginfo, "xcvrReg 0x%08x could not be read\n", xcvrReg ); + DBG_WARNING( et131x_dbginfo, "status is 0x%08x\n", + adapter->CSRAddress->mac.mii_mgmt_indicator.value ); + + status = -EIO; + } + + + /************************************************************************** + If we hit here we were able to read the register and we need to return + the value to the caller + *************************************************************************/ + *value = (UINT16)adapter->CSRAddress->mac.mii_mgmt_stat.bits.phy_stat; + + + /************************************************************************** + Stop the read operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + DBG_VERBOSE( et131x_dbginfo, " xcvr_addr = 0x%02x, " + "xcvr_reg = 0x%02x, " + "value = 0x%04x.\n", + xcvrAddr, xcvrReg, *value ); + + + /************************************************************************** + set the registers we touched back to the state at which we entered + this function + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_addr.value = miiAddr.value; + adapter->CSRAddress->mac.mii_mgmt_cmd.value = miiCmd.value; + + + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : MiWrite + ****************************************************************************** + + DESCRIPTION : Used to write to a PHY register through the MII + interface of the MAC. Updated for the ET1310. + + PARAMETERS : adapter - pointer to our private adapter structure + xcvrAddr - the address of the transciever + xcvrReg - the register to read + value - 16-bit value to write + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int MiWrite( ET131X_ADAPTER *adapter, UINT8 xcvrAddr, UINT8 xcvrReg, UINT16 value ) +{ + int status = 0; + UINT32 delay; + MII_MGMT_ADDR_t miiAddr; + MII_MGMT_CMD_t miiCmd; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "MiWrite" ); + + + /************************************************************************** + Save a local copy of the registers we are dealing with so we can set + them back + *************************************************************************/ + miiAddr.value = adapter->CSRAddress->mac.mii_mgmt_addr.value; + miiCmd.value = adapter->CSRAddress->mac.mii_mgmt_cmd.value; + + + /************************************************************************** + Stop the current operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + + /************************************************************************** + Set up the register we need to write to on the correct PHY + *************************************************************************/ + { + MII_MGMT_ADDR_t mii_mgmt_addr = {0}; + + mii_mgmt_addr.bits.phy_addr = xcvrAddr; + mii_mgmt_addr.bits.reg_addr = xcvrReg; + + adapter->CSRAddress->mac.mii_mgmt_addr = mii_mgmt_addr; + } + + + /************************************************************************** + Add the value to write to the registers to the mac + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_ctrl.value = value; + delay = 0; + + do + { + udelay( 50 ); + delay++; + } while(( adapter->CSRAddress->mac.mii_mgmt_indicator.bits.busy ) && + ( delay < 100 )); + + + /************************************************************************** + If we hit the max delay, we could not write the register + *************************************************************************/ + if( delay == 100 ) + { + UINT16 TempValue; + + DBG_WARNING( et131x_dbginfo, "xcvrReg 0x%08x could not be written", + xcvrReg ); + DBG_WARNING( et131x_dbginfo, "status is 0x%08x\n", + adapter->CSRAddress->mac.mii_mgmt_indicator.value ); + DBG_WARNING( et131x_dbginfo, "command is 0x%08x\n", + adapter->CSRAddress->mac.mii_mgmt_cmd.value ); + + MiRead( adapter, xcvrAddr, xcvrReg, &TempValue ); + + status = -EIO; + } + + + /************************************************************************** + Stop the write operation + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_cmd.value = 0x0; + + + /************************************************************************** + set the registers we touched back to the state at which we entered + this function + *************************************************************************/ + adapter->CSRAddress->mac.mii_mgmt_addr.value = miiAddr.value; + adapter->CSRAddress->mac.mii_mgmt_cmd.value = miiCmd.value; + + + DBG_VERBOSE( et131x_dbginfo, " xcvr_addr = 0x%02x, " + "xcvr_reg = 0x%02x, " + "value = 0x%04x.\n", + xcvrAddr, xcvrReg, value ); + + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_xcvr_find + ****************************************************************************** + + DESCRIPTION : Used to find the PHY ID + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_xcvr_find( ET131X_ADAPTER *adapter ) +{ + int status = -ENODEV; + UINT8 xcvr_addr; + MI_IDR1_t idr1; + MI_IDR2_t idr2; + UINT32 xcvr_id; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_xcvr_find" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + We need to get xcvr id and address we just get the first one + *************************************************************************/ + for( xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++ ) + { + /********************************************************************** + Read the ID from the PHY + *********************************************************************/ + MiRead( adapter, xcvr_addr, (UINT8)FIELD_OFFSET(MI_REGS_t, idr1), &idr1.value ); + MiRead( adapter, xcvr_addr, (UINT8)FIELD_OFFSET(MI_REGS_t, idr2), &idr2.value ); + + xcvr_id = (UINT32)(( idr1.value << 16 ) | idr2.value ); + + if(( idr1.value != 0) && ( idr1.value != 0xffff )) + { + DBG_TRACE( et131x_dbginfo, "Xcvr addr: 0x%02x\tXcvr_id: 0x%08x\n", + xcvr_addr, xcvr_id ); + + adapter->Stats.xcvr_id = xcvr_id; + adapter->Stats.xcvr_addr = (UINT32)xcvr_addr; + + status = 0; + break; + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_setphy_normal + ****************************************************************************** + + DESCRIPTION : Used by Power Management to force the PHY into 10 Base T + half-duplex mode, when going to D3 in WOL mode. Also + used during initialization to set the PHY for normal + operation. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_setphy_normal( ET131X_ADAPTER *adapter ) +{ + int status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_setphy_normal" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Make sure the PHY is powered up + *************************************************************************/ + ET1310_PhyPowerDown( adapter, 0 ); + status = et131x_xcvr_init( adapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_xcvr_init + ****************************************************************************** + + DESCRIPTION : Used to init the phy if we are setting it into force mode + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_xcvr_init( ET131X_ADAPTER *adapter ) +{ + int status = 0; + MI_IMR_t imr; + MI_ISR_t isr; + MI_LCR2_t lcr2; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_xcvr_init" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Zero out the adapter structure variable representing BMSR + *************************************************************************/ + adapter->Bmsr.value = 0; + + MiRead( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &isr.value ); + + MiRead( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, imr ), &imr.value ); + + + /************************************************************************** + Set the link status interrupt only. Bad behavior when link status and + auto neg are set, we run into a nested interrupt problem + *************************************************************************/ + imr.bits.int_en = 0x1; + imr.bits.link_status = 0x1; + imr.bits.autoneg_status = 0x1; + + MiWrite( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, imr ), imr.value ); + + + /************************************************************************** + Set the LED behavior such that LED 1 indicates speed (off = 10Mbits, + blink = 100Mbits, on = 1000Mbits) and LED 2 indicates link and + activity (on for link, blink off for activity). + + NOTE: Some customizations have been added here for specific vendors; + The LED behavior is now determined by vendor data in the EEPROM. However, + the above description is the default. + *************************************************************************/ + if(( adapter->eepromData[1] & 0x4 ) == 0 ) + { + MiRead( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, lcr2 ), &lcr2.value ); + + if(( adapter->eepromData[1] & 0x8 ) == 0 ) + { + lcr2.bits.led_tx_rx = 0x3; + } + else + { + lcr2.bits.led_tx_rx = 0x4; + } + + lcr2.bits.led_link = 0xa; + + MiWrite( adapter, (UINT8)adapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, lcr2 ), lcr2.value ); + } + + + /************************************************************************** + Determine if we need to go into a force mode and set it + *************************************************************************/ + if( adapter->AiForceSpeed == 0 && adapter->AiForceDpx == 0 ) + { + if(( adapter->RegistryFlowControl == TxOnly ) || + ( adapter->RegistryFlowControl == Both )) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 11, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL ); + } + + if( adapter->RegistryFlowControl == Both ) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 10, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL ); + } + + + /********************************************************************** + Set the phy to autonegotiation + *********************************************************************/ + ET1310_PhyAutoNeg( adapter, TRUE ); + + + /* NOTE - Do we need this? */ + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 0, 9, NULL ); + + DBG_LEAVE( et131x_dbginfo ); + return status; + } + else + { + ET1310_PhyAutoNeg( adapter, FALSE ); + + /********************************************************************** + Set to the correct force mode. + *********************************************************************/ + if( adapter->AiForceDpx != 1 ) + { + if(( adapter->RegistryFlowControl == TxOnly ) || + ( adapter->RegistryFlowControl == Both )) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 11, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL ); + } + + if( adapter->RegistryFlowControl == Both ) + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_SET, 4, 10, NULL ); + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL ); + } + } + else + { + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 10, NULL ); + ET1310_PhyAccessMiBit( adapter, + TRUEPHY_BIT_CLEAR, 4, 11, NULL ); + } + + switch( adapter->AiForceSpeed ) + { + case 10: + if( adapter->AiForceDpx == 1 ) + { + TPAL_SetPhy10HalfDuplex( adapter ); + } + else if( adapter->AiForceDpx == 2 ) + { + TPAL_SetPhy10FullDuplex( adapter ); + } + else + { + TPAL_SetPhy10Force( adapter ); + } + break; + + case 100: + if( adapter->AiForceDpx == 1 ) + { + TPAL_SetPhy100HalfDuplex( adapter ); + } + else if( adapter->AiForceDpx == 2 ) + { + TPAL_SetPhy100FullDuplex( adapter ); + } + else + { + TPAL_SetPhy100Force( adapter ); + } + break; + + case 1000: + TPAL_SetPhy1000FullDuplex( adapter ); + break; + } + + + DBG_LEAVE( et131x_dbginfo ); + return status; + } +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_Mii_check + ****************************************************************************** + + DESCRIPTION: + used to + + PARAMETERS : + pAdapter - pointer to our adapter + bmsr - + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_Mii_check( ET131X_ADAPTER *pAdapter, + MI_BMSR_t bmsr, + MI_BMSR_t bmsr_ints ) +{ + UCHAR ucLinkStatus; + INT32 nAutoNegStatus; + INT32 nSpeed; + INT32 nDuplex; + INT32 nMdiMdix; + INT32 nMasterSlave; + INT32 nPolarity; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_Mii_check" ); + DBG_ENTER( et131x_dbginfo ); + + + if( bmsr_ints.bits.link_status ) + { + if( bmsr.bits.link_status ) + { + pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20; + + + /****************************************************************** + Update our state variables and indicate the connected state + *****************************************************************/ + spin_lock_irqsave( &pAdapter->Lock, lockflags ); + + pAdapter->MediaState = NETIF_STATUS_MEDIA_CONNECT; + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION ); + + spin_unlock_irqrestore( &pAdapter->Lock, lockflags ); + + if( pAdapter->RegistryPhyLoopbk == FALSE ) + { + /************************************************************** + Don't indicate state if we're in loopback mode + *************************************************************/ + netif_indicate_status( pAdapter->netdev, pAdapter->MediaState ); + } + } + else + { + DBG_WARNING( et131x_dbginfo, "Link down cable problem\n" ); + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS ) + { + // NOTE - Is there a way to query this without TruePHY? + //if( TRU_QueryCoreType ( pAdapter->hTruePhy, 0 ) == EMI_TRUEPHY_A13O ) + { + UINT16 Register18; + + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, &Register18 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 | 0x4 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x10, Register18 | 0x8402 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x11, Register18 | 511 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 ); + } + } + + /****************************************************************** + For the first N seconds of life, we are in "link detection" + When we are in this state, we should only report "connected". + When the LinkDetection Timer expires, we can report + disconnected (handled in the LinkDetectionDPC). + *****************************************************************/ + if(( MP_IS_FLAG_CLEAR( pAdapter, fMP_ADAPTER_LINK_DETECTION )) || + ( pAdapter->MediaState == NETIF_STATUS_MEDIA_DISCONNECT )) + { + spin_lock_irqsave( &pAdapter->Lock, lockflags ); + pAdapter->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; + spin_unlock_irqrestore( &pAdapter->Lock, lockflags ); + + /************************************************************** + Only indicate state if we're in loopback mode + *************************************************************/ + if( pAdapter->RegistryPhyLoopbk == FALSE ) + { + netif_indicate_status( pAdapter->netdev, pAdapter->MediaState ); + } + } + + pAdapter->uiLinkSpeed = 0; + pAdapter->uiDuplexMode = 0; + + + /****************************************************************** + Free the packets being actively sent & stopped + *****************************************************************/ + et131x_free_busy_send_packets( pAdapter ); + + + /****************************************************************** + Re-initialize the send structures + *****************************************************************/ + et131x_init_send( pAdapter ); + + + /****************************************************************** + Reset the RFD list and re-start RU + *****************************************************************/ + et131x_reset_recv( pAdapter ); + + + /****************************************************************** + Bring the device back to the state it was during init prior + to autonegotiation being complete. This way, when we get the + auto-neg complete interrupt, we can complete init by calling + ConfigMacREGS2. + *****************************************************************/ + et131x_soft_reset( pAdapter ); + + + /****************************************************************** + Setup ET1310 as per the documentation + *****************************************************************/ + et131x_adapter_setup( pAdapter ); + + + /****************************************************************** + Setup the PHY into coma mode until the cable is plugged back in + *****************************************************************/ + if( pAdapter->RegistryPhyComa == 1 ) + { + EnablePhyComa( pAdapter ); + } + } + } + + if( bmsr_ints.bits.auto_neg_complete || + (( pAdapter->AiForceDpx == 3 ) && ( bmsr_ints.bits.link_status ))) + { + if( bmsr.bits.auto_neg_complete || + ( pAdapter->AiForceDpx == 3 )) + { + ET1310_PhyLinkStatus( pAdapter, + &ucLinkStatus, + &nAutoNegStatus, + &nSpeed, + &nDuplex, + &nMdiMdix, + &nMasterSlave, + &nPolarity ); + + + pAdapter->uiLinkSpeed = nSpeed; + pAdapter->uiDuplexMode = nDuplex; + + DBG_TRACE( et131x_dbginfo, + "pAdapter->uiLinkSpeed 0x%04x, pAdapter->uiDuplex 0x%08x\n", + pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode ); + + pAdapter->PoMgmt.TransPhyComaModeOnBoot = 20; + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_10MBPS ) + { + // NOTE - Is there a way to query this without TruePHY? + //if( TRU_QueryCoreType ( pAdapter->hTruePhy, 0 ) == EMI_TRUEPHY_A13O ) + { + UINT16 Register18; + + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, &Register18 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 | 0x4 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x10, Register18 | 0x8402 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x11, Register18 | 511 ); + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + 0x12, Register18 ); + } + } + + ConfigFlowControl( pAdapter ); + + + if(( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) && + ( pAdapter->RegistryJumboPacket > 2048 )) + + { + ET1310_PhyAndOrReg( pAdapter, 0x16, 0xcfff, 0x2000 ); + } + + SetRxDmaTimer( pAdapter ); + ConfigMACRegs2( pAdapter ); + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : TPAL_MiAccessRegs + ****************************************************************************** + + DESCRIPTION : Used to perform a single or series of MI Register + transactions on the specified PHY + + PARAMETERS : hPlatform - handle to platform resources + nPhyId - logical PHY ID (if >= 0) or + logical PHY group ID (if <0) + pbyAccessFlags - Pointer to a list of flags, which + specify the transaction type associated + with each register contained in the + 'pbyRegisters' array. Valid values: + TRUEPHY_READ + TRUEPHY_WRITE + TRUEPHY_MASK + If a logical PHY Group ID is specified + in 'nPhyId', the value of these flags + must be TRUEPHY_WRITE + pbyRegisters - Pointer to a list of MI registers + addressess (0-31), one of each register + specified by 'nRegCount' + pwData - Pointer to a buffer that contains the + data required by or resulting from each + transaction, the contents of which are + dependent upon the 'pbyAccessFlags' + parameter. Specifically: + + If 'pbyAccessFlags[i]' is TRUEPHY_READ, + the contents of the register specified + by 'pbyRegisters[i]' is read and stored + in 'pwData[i]'. + + If 'pbyAccessFlags[i]' is TRUEPHY_WRITE, + the contents of 'pwData[i]' is written + to the register specified by + 'pbyRegisters[i]'. + + If 'pbyAccessFlags[i]' is TRUEPHY_MASK, + the contents of the register specified + by 'pbyRegisters[i]' is read and stored + in 'pwData [i]', which is then + logically AND'ed with the contents of + 'pwAndMasks[i]' and logically OR'ed + with the contents of 'pwOrMasks[i]' + before it is written back to the + register specified by 'pbyRegisters[i]' + + This allows the calling function to + interleave a register read, logical + and/or, and write operation within a + single transaction. + + pwAndMasks - Pointer to buffer containing AND masks, + which is required if the corresponding + transaction type is TRUEPHY_MASK; + otherwise, this parameter is ignored. + pwOrMasks - Pointer to buffer containing OR masks, + which is required if the corresponding + transaction type is TRUEPHY_MASK; + otherwise, this parameter is ignored. + nRegCount - Specifies the number of register + transactions to be performed. + + RETURNS : TRUEPHY_SUCCESS + TRUEPHY_FAILURE + + REUSE INFORMATION : + + *****************************************************************************/ +INT32 TPAL_MiAccessRegs( TPAL_HANDLE hPlatform, + INT32 nPhyId, + PUCHAR pbyAccessFlags, + PUCHAR pbyRegisters, + PUINT16 pwData, + PUINT16 pwAndMasks, + PUINT16 pwOrMasks, + INT32 nRegCount ) +{ + INT32 nStatus = TRUEPHY_FAILURE; + INT32 index; + INT16 wTemp; + UINT8 xcvrAddr; + ET131X_ADAPTER *pAdapter = hPlatform; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_MiAccessRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Validate Input parameters. We are not worried about nPhyId because we + can only access the one we control + *************************************************************************/ + if( pbyAccessFlags != NULL && pwData != NULL ) + { + /********************************************************************** + Convert nPhyId into a PHY physical address(nPhyAddress) + *********************************************************************/ + + + /********************************************************************** + Convert nPhyId into a MI bus address (nBusAddress). + + NOTE: This is only needed for platforms that support multiple MI + buses + *********************************************************************/ + + + /********************************************************************** + Get the xcvr addr for all transactions to go to + *********************************************************************/ + xcvrAddr = (UINT8)pAdapter->Stats.xcvr_addr; + + + /********************************************************************** + Go through all registers performing specific transaction indicated + in the corresponding pbyAccessFlags array. + *********************************************************************/ + for( index = 0; index < nRegCount; index++ ) + { + /****************************************************************** + Validate MI register + *****************************************************************/ + if( pbyRegisters[index] > 31 ) + { + break; + } + + + /****************************************************************** + Is this a read? + *****************************************************************/ + if( pbyAccessFlags[index] == TRUEPHY_READ ) + { + /************************************************************** + Group reads are not allowed + *************************************************************/ + if( nPhyId < 0 ) + { + break; + } + + + /************************************************************** + Make sure we acquire the spin lock + *************************************************************/ + spin_lock_irqsave( &pAdapter->PHYLock, lockflags ); + + + /************************************************************** + Let's perform the read operation + *************************************************************/ + MiRead( pAdapter, xcvrAddr, pbyRegisters[index], + (PUINT16)&pwData[index] ); + + spin_unlock_irqrestore( &pAdapter->PHYLock, lockflags ); + + } + else if( pbyAccessFlags[index] == TRUEPHY_WRITE ) + { + /************************************************************** + Make sure we acquire the spin lock + *************************************************************/ + spin_lock_irqsave( &pAdapter->PHYLock, lockflags ); + + + /************************************************************** + Let's perform the write operation + *************************************************************/ + MiWrite( pAdapter, xcvrAddr, pbyRegisters[index], + (UINT16)pwData[index] ); + + spin_unlock_irqrestore( &pAdapter->PHYLock, lockflags ); + } + else if( pbyAccessFlags[index] == TRUEPHY_MASK ) + { + /************************************************************** + Group masks are not allowed + *************************************************************/ + if( nPhyId < 0 ) + { + break; + } + + /************************************************************** + Pointer to AND and OR masks must not be NULL + *************************************************************/ + if(( pwOrMasks == NULL ) || ( pwAndMasks == NULL )) + { + break; + } + + /************************************************************** + Make sure we acquire the spin lock + *************************************************************/ + spin_lock_irqsave( &pAdapter->PHYLock, lockflags ); + + + /************************************************************** + Perform read + *************************************************************/ + MiRead( pAdapter, xcvrAddr, pbyRegisters[index], + (PUINT16)&pwData[index] ); + + + /************************************************************** + Perform and/or masks and write it back + *************************************************************/ + wTemp = (( pwData[index] & pwAndMasks[index] ) | + pwOrMasks[index] ); + + MiWrite( pAdapter, xcvrAddr, pbyRegisters[index], + (UINT16)wTemp ); + + spin_unlock_irqrestore( &pAdapter->PHYLock, lockflags ); + } + else + { + /************************************************************** + Invalid transaction type, just break out of the loop + *************************************************************/ + break; + } + }//end for loop + + /********************************************************************** + If we completed all the transactions, indicate success + *********************************************************************/ + if( index == nRegCount ) + { + nStatus = TRUEPHY_SUCCESS; + } + }//end if + + + DBG_LEAVE( et131x_dbginfo ); + return nStatus; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : TPAL_PlatformExit + ****************************************************************************** + + DESCRIPTION : Used to exit the TRUEPHY library which will de-allocate + any system resources allocated. + + PARAMETERS : hPlatform - handle to the platform resources + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ + +void TPAL_PlatformExit( TRUEPHY_OSAL_HANDLE hPlatform ) +{ + DBG_FUNC( "TPAL_PlatformExit" ); + DBG_ENTER( et131x_dbginfo ); + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + +/////////////////////////////////////////////////////////////////////////////// +//// OS Specific Functions //// +/////////////////////////////////////////////////////////////////////////////// +/****************************************************************************** + ROUTINE : TPAL_AllocMem + ****************************************************************************** + + DESCRIPTION : Used so the TRUEPHY library can allocate memory + + PARAMETERS : ulNumBytes - number of bytes to allocate + + RETURNS : pointer to allocated memory block on success, or + NULL on failure + + REUSE INFORMATION : + + *****************************************************************************/ +void * TPAL_AllocMem( TRUEPHY_OSAL_HANDLE hPlatform, u_long ulNumBytes ) +{ + void *pBuffer = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_AllocMem" ); + DBG_ENTER( et131x_dbginfo ); + + + pBuffer = kmalloc( ulNumBytes, GFP_ATOMIC ); + + + DBG_LEAVE( et131x_dbginfo ); + return pBuffer; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : TPAL_FreeMem + ****************************************************************************** + + DESCRIPTION : Used to free a previously allocated block of memory + + PARAMETERS : pMemBlock - the pointer to the buffer to free + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void TPAL_FreeMem( TRUEPHY_OSAL_HANDLE hPlatform, void *pMemBlock ) +{ + DBG_FUNC( "TPAL_FreeMem" ); + DBG_ENTER( et131x_dbginfo ); + + + kfree( pMemBlock ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_Sleep + ****************************************************************************** + + DESCRIPTION: + Used to delay execution for a specified number of milliseconds + + PARAMETERS : + ulMsec - Number of milliseconds to delay. This parameter can be zero + + RETURNS : + NONE + + *****************************************************************************/ +void TPAL_Sleep( TRUEPHY_OSAL_HANDLE hPlatform, u_long ulMsec ) +{ + DBG_FUNC( "TPAL_Sleep" ); + DBG_ENTER( et131x_dbginfo ); + + + mdelay( ulMsec ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_GetSystemUpTime + ****************************************************************************** + + DESCRIPTION: + Used to get the numberr of milliseconds that have elapsed since the + system was started + + PARAMETERS : + NONE + + RETURNS : + number of milliseconds since system was started + + *****************************************************************************/ +u_long TPAL_GetSystemUpTime( TRUEPHY_OSAL_HANDLE hPlatform ) +{ + UINT32 uptime; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_GetSystemUpTime" ); + DBG_ENTER( et131x_dbginfo ); + + + uptime = 10 * jiffies / HZ; + + + DBG_LEAVE( et131x_dbginfo ); + return uptime; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_GetLinkStatusInfo + ****************************************************************************** + + DESCRIPTION: + used to determine what link speed and duplex the phy is set to + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void TPAL_GetLinkStatusInfo( ET131X_ADAPTER *pAdapter ) +{ + UINT32 index = 0; + INT32 MdiMdix; + INT32 MasterSlave; + INT32 Polarity; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_GetLinkStatusInfo" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Get the link status information from the phy. Loop until the + autonegstatus is complete or link status is up. + + If looping for 50 uSec, break out, we have a problem + *************************************************************************/ + do + { + ET1310_PhyLinkStatus( pAdapter, + &pAdapter->ucLinkStatus, + &pAdapter->uiAutoNegStatus, + &pAdapter->uiLinkSpeed, + &pAdapter->uiDuplexMode, + &MdiMdix, + &MasterSlave, + &Polarity ); + + DBG_VERBOSE( et131x_dbginfo, + "uiAutoNegStatus 0x%08x ucLinkStatus 0x%04x\n " + "uiLinkSpeed 0x%04x, uiDuplexMode 0x%08x\n", + pAdapter->uiAutoNegStatus, + pAdapter->ucLinkStatus, + pAdapter->uiLinkSpeed, + pAdapter->uiDuplexMode ); + + udelay( 100 ); + index++; + + if( index == 10000 ) + { + /****************************************************************** + We hit our limit, we need to set a variable so during power + management we know to try 100/half + *****************************************************************/ + pAdapter->PoMgmt.Failed10Half = TRUE; + break; + } + } while( pAdapter->uiAutoNegStatus != TRUEPHY_ANEG_COMPLETE || + pAdapter->ucLinkStatus == 0 ); + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy10HalfDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 10 Base T Half Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if something goes wrong + + *****************************************************************************/ +INT32 TPAL_SetPhy10HalfDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy10HalfDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + /************************************************************************** + First we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 100 BaseT " + "for forcing 10 BaseT Half Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_HALF ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 10 Half\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue ; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy10FullDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 10 Base T Full Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy10FullDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy10FullDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + First we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT " + "for Forcing 10 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 100 BaseT " + "for Forcing 10 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 10 Full\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up the phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy10Force + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 10 Base T Full Duplex mode WITHOUT using + autonegotiation. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + + *****************************************************************************/ +void TPAL_SetPhy10Force( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "TPAL_SetPhy10Force" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + + /************************************************************************** + Disable autoneg + *************************************************************************/ + ET1310_PhyAutoNeg( pAdapter, FALSE ); + + + /************************************************************************** + Disable all advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + /************************************************************************** + Force 10 Mbps + *************************************************************************/ + ET1310_PhySpeedSelect( pAdapter, TRUEPHY_SPEED_10MBPS ); + + + /************************************************************************** + Force Full duplex + *************************************************************************/ + ET1310_PhyDuplexMode( pAdapter, TRUEPHY_DUPLEX_FULL ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy100HalfDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 100 Base T Half Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy100HalfDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy100HalfDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + + DBG_ERROR( et131x_dbginfo, "Could not power down the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return( returnValue ); + } + + + /************************************************************************** + first we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT " + "for Forcing 100 BaseT Half Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 10 BaseT " + "for Forcing 100 BaseT Half Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_HALF ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 100 Half\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /* Set speed */ + ET1310_PhySpeedSelect( pAdapter, TRUEPHY_SPEED_100MBPS ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up the PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy100FullDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 100 Base T Full Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy100FullDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy100FullDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + First we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 1000 BaseT " + "for Forcing 100 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 10 BaseT " + "for Forcing 100 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 100 Full\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy100Force + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 100 Base T Full Duplex mode WITHOUT using + autonegotiation. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + + *****************************************************************************/ +void TPAL_SetPhy100Force( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "TPAL_SetPhy100Force" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + + /************************************************************************** + Disable autoneg + *************************************************************************/ + ET1310_PhyAutoNeg( pAdapter, FALSE ); + + + /************************************************************************** + Disable all advertisement + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + + /************************************************************************** + Force 100 Mbps + *************************************************************************/ + ET1310_PhySpeedSelect( pAdapter, TRUEPHY_SPEED_100MBPS ); + + + /************************************************************************** + Force Full duplex + *************************************************************************/ + ET1310_PhyDuplexMode( pAdapter, TRUEPHY_DUPLEX_FULL ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhy1000FullDuplex + ****************************************************************************** + + DESCRIPTION: + Used to force the phy into 1000 Base T Full Duplex mode. Also sets the + MAC so it is syncd up properly + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhy1000FullDuplex( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhy1000FullDuplex" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + first we need to turn off all other advertisement + *************************************************************************/ + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 100 BaseT " + "for Forcing 1000 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not turn off advertisement of 10 BaseT " + "for Forcing 1000 BaseT Full Duplex\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + set our advertise values accordingly + *************************************************************************/ + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not set Advertise of 1000 Full\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up PHY\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: TPAL_SetPhyAutoNeg + ****************************************************************************** + + DESCRIPTION: + Used to set phy to autonegotiation mode. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + TRUEPHY_SUCCESS - if everything goes according to plan + TRUEPHY_FALIURE -if somethign goes wrong during the procedures + + *****************************************************************************/ +INT32 TPAL_SetPhyAutoNeg( ET131X_ADAPTER *pAdapter ) +{ + INT32 returnValue = TRUEPHY_SUCCESS; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "TPAL_SetPhyAutoNeg" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power down phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Turn on advertisement of all capabilities + *************************************************************************/ + ET1310_PhyAdvertise10BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_BOTH ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not Turn on Advertisement of 10 BaseT " + "from Setting to Auto Negotiation\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + ET1310_PhyAdvertise100BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_BOTH ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not Turn on Advertisement of 100 BaseT " + "from Setting to Auto Negotiation\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + if( pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST ) + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + } + else + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + } + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, + "Could not Turn on Advertisement of 1000 BaseT " + "from Setting to Auto Negotiation\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + /************************************************************************** + Make sure auto-neg is ON (it is disabled in FORCE modes) + *************************************************************************/ + ET1310_PhyAutoNeg( pAdapter, TRUE ); + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + if( returnValue == TRUEPHY_FAILURE ) + { + /********************************************************************** + HANDLE ERROR HERE + *********************************************************************/ + DBG_ERROR( et131x_dbginfo, "Could not power up phy\n" ); + DBG_LEAVE( et131x_dbginfo ); + return returnValue; + } + + + DBG_LEAVE( et131x_dbginfo ); + return returnValue; +} +/*===========================================================================*/ + + + + +/****************************************************************************** +******************************************************************************* + + The routines which follow provide low-level access to the PHY, and are used + primarily by the routines above (although there are a few places elsewhere in + the driver where this level of access is required). + +******************************************************************************* +******************************************************************************/ + +static UINT16 ConfigPhy[25][2] = +{ + /* Reg Value Register */ + /* Addr */ + {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */ + {0x880C, 0x0926}, /* AfeIfCreg4B100Msbs */ + {0x880D, 0x0926}, /* AfeIfCreg4B10Msbs */ + + {0x880E, 0xB4D3}, /* AfeIfCreg4B1000Lsbs */ + {0x880F, 0xB4D3}, /* AfeIfCreg4B100Lsbs */ + {0x8810, 0xB4D3}, /* AfeIfCreg4B10Lsbs */ + + {0x8805, 0xB03E}, /* AfeIfCreg3B1000Msbs */ + {0x8806, 0xB03E}, /* AfeIfCreg3B100Msbs */ + {0x8807, 0xFF00}, /* AfeIfCreg3B10Msbs */ + + {0x8808, 0xE090}, /* AfeIfCreg3B1000Lsbs */ + {0x8809, 0xE110}, /* AfeIfCreg3B100Lsbs */ + {0x880A, 0x0000}, /* AfeIfCreg3B10Lsbs */ + + {0x300D, 1 }, /* DisableNorm */ + + {0x280C, 0x0180}, /* LinkHoldEnd */ + + {0x1C21, 0x0002}, /* AlphaM */ + + {0x3821, 6 }, /* FfeLkgTx0 */ + {0x381D, 1 }, /* FfeLkg1g4 */ + {0x381E, 1 }, /* FfeLkg1g5 */ + {0x381F, 1 }, /* FfeLkg1g6 */ + {0x3820, 1 }, /* FfeLkg1g7 */ + + {0x8402, 0x01F0}, /* Btinact */ + {0x800E, 20 }, /* LftrainTime */ + {0x800F, 24 }, /* DvguardTime */ + {0x8010, 46 }, /* IdlguardTime */ + + {0, 0 } + +}; +// +// condensed version of the phy initialization routine +// +void ET1310_PhyInit( ET131X_ADAPTER *pAdapter ) +{ + UINT16 usData, usIndex; + + + if( pAdapter == NULL ) + { + return; + } + + + // get the identity (again ?) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_1, &usData ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_2, &usData ); + + // what does this do/achieve ? + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0002 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0006 ); + + // read modem register 0402, should I do something with the return data ? + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, 0x0402 ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, &usData ); + + // what does this do/achieve ? + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0002 ); + + // get the identity (again ?) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_1, &usData ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_ID_2, &usData ); + + // what does this achieve ? + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0002 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0006 ); + + // read modem register 0402, should I do something with the return data ? + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, 0x0402 ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, &usData ); + + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0002 ); + + // what does this achieve (should return 0x1040) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0002 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, 0x1840 ); + + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0007 ); + + // here the writing of the array starts.... + usIndex = 0; + while( ConfigPhy[usIndex][0] != 0x0000 ) + { + // write value + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, ConfigPhy[usIndex][0] ); + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, ConfigPhy[usIndex][1] ); + + // read it back + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_INDEX_REG, ConfigPhy[usIndex][0] ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_DATA_REG, &usData ); + + // do a check on the value read back ? + usIndex++; + } + // here the writing of the array ends... + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); // 0x1840 + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, &usData ); // should read 0007 + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, 0x1040 ); + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_MPHY_CONTROL_REG, 0x0002 ); + + return; + +} + + + + +void ET1310_PhyReset( ET131X_ADAPTER *pAdapter ) +{ + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, 0x8000 ); + return; +} + + + + +void ET1310_PhyPowerDown( ET131X_ADAPTER *pAdapter, BOOL_t down ) +{ + UINT16 usData; + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + if( down == FALSE ) + { + // Power UP + usData &= ~0x0800; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + else + { + // Power DOWN + usData |= 0x0800; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + + return; +} + + +void ET1310_PhyAutoNeg( ET131X_ADAPTER *pAdapter, BOOL_t enable ) +{ + UINT16 usData; + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + if( enable == TRUE ) + { + // Autonegotiation ON + usData |= 0x1000; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + else + { + // Autonegotiation OFF + usData &= ~0x1000; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + + return; +} + +void ET1310_PhyDuplexMode( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + if( duplex == TRUEPHY_DUPLEX_FULL ) + { + // Set Full Duplex + usData |= 0x100; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + else + { + // Set Half Duplex + usData &= ~0x100; + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + } + + return; +} + + +void ET1310_PhySpeedSelect( ET131X_ADAPTER *pAdapter, UINT16 speed ) +{ + UINT16 usData; + + // Read the PHY control register + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usData ); + + // Clear all Speed settings (Bits 6, 13) + usData &= ~0x2040; + + // Reset the speed bits based on user selection + switch( speed ) + { + case TRUEPHY_SPEED_10MBPS: + // Bits already cleared above, do nothing + break; + + case TRUEPHY_SPEED_100MBPS: + // 100M == Set bit 13 + usData |= 0x2000; + break; + + case TRUEPHY_SPEED_1000MBPS: + default: + usData |= 0x0040; + break; + } + + // Write back the new speed + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, usData ); + + return; +} + + +void ET1310_PhyAdvertise1000BaseT( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + // Read the PHY 1000 Base-T Control Register + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_1000_CONTROL, &usData ); + + // Clear Bits 8,9 + usData &= ~0x0300; + + switch( duplex ) + { + case TRUEPHY_ADV_DUPLEX_NONE: + // Duplex already cleared, do nothing + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + // Set Bit 9 + usData |= 0x0200; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + // Set Bit 8 + usData |= 0x0100; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + usData |= 0x0300; + break; + } + + // Write back advertisement + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_1000_CONTROL, usData ); + + return; +} + + +void ET1310_PhyAdvertise100BaseT( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + // Read the Autonegotiation Register (10/100) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, &usData ); + + // Clear bits 7,8 + usData &= ~0x0180; + + switch( duplex ) + { + case TRUEPHY_ADV_DUPLEX_NONE: + // Duplex already cleared, do nothing + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + // Set Bit 8 + usData |= 0x0100; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + // Set Bit 7 + usData |= 0x0080; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + // Set Bits 7,8 + usData |= 0x0180; + break; + } + + // Write back advertisement + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, usData ); + + return; +} + + +void ET1310_PhyAdvertise10BaseT( ET131X_ADAPTER *pAdapter, UINT16 duplex ) +{ + UINT16 usData; + + // Read the Autonegotiation Register (10/100) + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, &usData ); + + // Clear bits 5,6 + usData &= ~0x0060; + + switch( duplex ) + { + case TRUEPHY_ADV_DUPLEX_NONE: + // Duplex already cleared, do nothing + break; + + case TRUEPHY_ADV_DUPLEX_FULL: + // Set Bit 6 + usData |= 0x0040; + break; + + case TRUEPHY_ADV_DUPLEX_HALF: + // Set Bit 5 + usData |= 0x0020; + break; + + case TRUEPHY_ADV_DUPLEX_BOTH: + default: + // Set Bits 5,6 + usData |= 0x0060; + break; + } + + // Write back advertisement + MiWrite( pAdapter, pAdapter->Stats.xcvr_addr, PHY_AUTO_ADVERTISEMENT, usData ); + + return; +} + + + + +void ET1310_PhyLinkStatus( ET131X_ADAPTER *pAdapter, + UCHAR *ucLinkStatus, + UINT32 *uiAutoNeg, + UINT32 *uiLinkSpeed, + UINT32 *uiDuplexMode, + UINT32 *uiMdiMdix, + UINT32 *uiMasterSlave, + UINT32 *uiPolarity ) +{ + UINT16 usMiStatus = 0; + UINT16 us1000BaseT = 0; + UINT16 usVmiPhyStatus = 0; + UINT16 usControl = 0; + + + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_STATUS, &usMiStatus ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_1000_STATUS, &us1000BaseT ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_PHY_STATUS, &usVmiPhyStatus ); + MiRead( pAdapter, pAdapter->Stats.xcvr_addr, PHY_CONTROL, &usControl ); + + if( ucLinkStatus ) + { + *ucLinkStatus = (unsigned char)(( usVmiPhyStatus & 0x0040 ) ? 1 : 0 ); + } + + if( uiAutoNeg ) + { + *uiAutoNeg = ( usControl & 0x1000 ) ? (( usVmiPhyStatus & 0x0020 ) ? TRUEPHY_ANEG_COMPLETE : TRUEPHY_ANEG_NOT_COMPLETE ) : TRUEPHY_ANEG_DISABLED; + } + + if( uiLinkSpeed ) + { + *uiLinkSpeed = ( usVmiPhyStatus & 0x0300 ) >> 8; + } + + if( uiDuplexMode ) + { + *uiDuplexMode = ( usVmiPhyStatus & 0x0080 ) >> 7; + } + + if( uiMdiMdix ) + { + /* NOTE: Need to complete this */ + *uiMdiMdix = 0; + } + + if( uiMasterSlave ) + { + *uiMasterSlave = ( us1000BaseT & 0x4000 ) ? TRUEPHY_CFG_MASTER : TRUEPHY_CFG_SLAVE; + } + + if( uiPolarity ) + { + *uiPolarity = ( usVmiPhyStatus & 0x0400 ) ? TRUEPHY_POLARITY_INVERTED : TRUEPHY_POLARITY_NORMAL; + } + + return; +} + + +void ET1310_PhyAndOrReg( ET131X_ADAPTER *pAdapter, + UINT16 regnum, + UINT16 andMask, + UINT16 orMask ) +{ + UINT16 reg; + + // Read the requested register + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + regnum, ® ); + + // Apply the AND mask + reg &= andMask; + + // Apply the OR mask + reg |= orMask; + + // Write the value back to the register + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + regnum, reg ); + + return; +} + + +void ET1310_PhyAccessMiBit( ET131X_ADAPTER *pAdapter, + UINT16 action, + UINT16 regnum, + UINT16 bitnum, + UINT8 *value ) +{ + UINT16 reg; + UINT16 mask = 0; + + // Create a mask to isolate the requested bit + mask = 0x0001 << bitnum; + + // Read the requested register + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + regnum, ® ); + + switch( action ) + { + case TRUEPHY_BIT_READ: + if( value != NULL ) + { + *value = ( reg & mask ) >> bitnum; + } + + break; + + case TRUEPHY_BIT_SET: + reg |= mask; + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, regnum, reg ); + break; + + case TRUEPHY_BIT_CLEAR: + reg &= ~mask; + MiWrite( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, regnum, reg ); + break; + + default: + break; + } + + return; +} + --- linux-2.6.28.orig/ubuntu/et131x/Kconfig +++ linux-2.6.28/ubuntu/et131x/Kconfig @@ -0,0 +1,3 @@ +config NET_ET131X + tristate "Agere Systems 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs" + depends on PCI && NET --- linux-2.6.28.orig/ubuntu/et131x/et131x_config.h +++ linux-2.6.28/ubuntu/et131x/et131x_config.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_config.h - Defines, structs, enums, prototypes, etc. to support + * et131x_config.c + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:12 $ + $Revision: 1.4 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_CONFIG_H__ +#define __ET131X_CONFIG_H__ + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for et131x_config.c + *****************************************************************************/ +void et131x_config_parse( struct et131x_adapter *pAdapter ); + + + + +#endif /* __ET131X_CONFIG_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_mac.h +++ linux-2.6.28/ubuntu/et131x/ET1310_mac.h @@ -0,0 +1,140 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_mac.h - Defines, structs, enums, prototypes, etc. pertaining to the + * MAC. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:11 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef _ET1310_MAC_H_ +#define _ET1310_MAC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +/****************************************************************************** + MACSTAT #defines + *****************************************************************************/ +#define COUNTER_WRAP_28_BIT 0x10000000 +#define COUNTER_WRAP_22_BIT 0x400000 +#define COUNTER_WRAP_16_BIT 0x10000 +#define COUNTER_WRAP_12_BIT 0x1000 + +#define COUNTER_MASK_28_BIT (COUNTER_WRAP_28_BIT - 1) +#define COUNTER_MASK_22_BIT (COUNTER_WRAP_22_BIT - 1) +#define COUNTER_MASK_16_BIT (COUNTER_WRAP_16_BIT - 1) +#define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1) + +#define UPDATE_COUNTER(HostCnt,DevCnt) \ + HostCnt = HostCnt + DevCnt; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + +/****************************************************************************** + PROTOTYPES + *****************************************************************************/ +void ConfigMACRegs1( struct et131x_adapter *pAdapter ); +void ConfigMACRegs2( struct et131x_adapter *pAdapter ); +void ConfigRxMacRegs( struct et131x_adapter *pAdapter ); +void ConfigTxMacRegs( struct et131x_adapter *pAdapter ); +void ConfigMacStatRegs( struct et131x_adapter *pAdapter ); +void ConfigFlowControl( struct et131x_adapter *pAdapter ); +void UpdateMacStatHostCounters( struct et131x_adapter *pAdapter ); +void HandleMacStatInterrupt( struct et131x_adapter *pAdapter ); +void SetupDeviceForMulticast( struct et131x_adapter *pAdapter ); +void SetupDeviceForUnicast( struct et131x_adapter *pAdapter ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _ET1310_MAC_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_isr.c +++ linux-2.6.28/ubuntu/et131x/et131x_isr.c @@ -0,0 +1,656 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_isr.c - File which contains the ISR, ISR handler, and related routines + * for processing interrupts from the device. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/31 20:58:43 $ + $Revision: 1.13 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ + + + + +/****************************************************************************** + Defines for 2.4 compatibility with the new 2.6 IRQ handler return values + *****************************************************************************/ +#ifndef IRQ_RETVAL + +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) + +#endif /* IRQ_RETVAL */ + + + + +/****************************************************************************** + ROUTINE : et131x_isr + ****************************************************************************** + + DESCRIPTION : The Interrupt Service Routine for the driver. + + PARAMETERS : irq - the IRQ on which the interrupt was received. + dev_id - a buffer containing device-specific info (in + this case, a pointer to a net_device struct) + regs - + + RETURNS : For 2.4.x kernels - N/A + For 2.6.x kernels - A value indicating if the interrupt + was handled. + + REUSE INFORMATION : + + *****************************************************************************/ +irqreturn_t et131x_isr( int irq, void *dev_id ) +{ + BOOL_t handled = TRUE; + struct net_device *netdev = (struct net_device *)dev_id; + ET131X_ADAPTER *adapter = NULL; + INT_STATUS_t status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_isr" ); + + + do + { + if(( netdev == NULL ) || ( !netif_device_present( netdev ))) + { + DBG_WARNING( et131x_dbginfo, + "No net_device struct or device not present\n" ); + handled = FALSE; + break; + } + + adapter = netdev_priv( netdev ); + + + /********************************************************************** + If the adapter is in low power state, then it should not recognize + any interrupt + + NOTE + *********************************************************************/ + + + /********************************************************************** + Disable Device Interrupts + *********************************************************************/ + et131x_disable_interrupts( adapter ); + + + /********************************************************************** + Get a copy of the value in the interrupt status register so we can + process the interrupting section + *********************************************************************/ + status.value = adapter->CSRAddress->global.int_status.value; + + if(( adapter->FlowControl == TxOnly ) || + ( adapter->FlowControl == Both )) + { + status.value &= ~INT_MASK_ENABLE; + } + else + { + status.value &= ~INT_MASK_ENABLE_NO_FLOW; + } + + + /********************************************************************** + Make sure this is our interrupt + *********************************************************************/ + if( !status.value ) + { +#ifdef ET131X_DBG + adapter->Stats.UnhandledInterruptsPerSec++; +#endif + handled = FALSE; + DBG_VERBOSE( et131x_dbginfo, "NOT OUR INTERRUPT\n" ); + et131x_enable_interrupts( adapter ); + break; + } + + /********************************************************************** + This is our interrupt, so process accordingly + *********************************************************************/ +#ifdef ET131X_DBG + if( status.bits.rxdma_xfr_done ) + { + adapter->Stats.RxDmaInterruptsPerSec++; + } + + if( status.bits.txdma_isr ) + { + adapter->Stats.TxDmaInterruptsPerSec++; + } +#endif + + if( status.bits.watchdog_interrupt ) + { + PMP_TCB pMpTcb = adapter->TxRing.CurrSendHead; + + if( pMpTcb ) + { + if( ++pMpTcb->PacketStaleCount > 1 ) + { + status.bits.txdma_isr = 1; + } + } + + if( adapter->RxRing.UnfinishedReceives ) + { + status.bits.rxdma_xfr_done = 1; + } + else if( pMpTcb == 0 ) + { + adapter->CSRAddress->global.watchdog_timer = 0; + } + + status.bits.watchdog_interrupt = 0; +#ifdef ET131X_DBG + adapter->Stats.WatchDogInterruptsPerSec++; +#endif + } + + if( status.value == 0 ) + { + /****************************************************************** + This interrupt has in some way been "handled" by the ISR. Either + it was a spurious Rx interrupt, or it was a Tx interrupt that + has been filtered by the ISR. + *****************************************************************/ + et131x_enable_interrupts( adapter ); + break; + } + + /********************************************************************** + We need to save the interrupt status value for use in our DPC. We + will clear the software copy of that in that routine. + *********************************************************************/ + adapter->Stats.InterruptStatus = status; + + + /********************************************************************** + Schedule the ISR handler as a bottom-half task in the kernel's + tq_immediate queue, and mark the queue for execution + *********************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + schedule_task( &adapter->task ); +#else + schedule_work( &adapter->task ); +#endif + + } while( 0 ); + + return IRQ_RETVAL( handled ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_isr_handler + ****************************************************************************** + + DESCRIPTION : The ISR handler, scheduled to run in a deferred context + by the ISR. This is where the ISR's work actually gets + done. + + PARAMETERS : p_adapter - a pointer to the device's private adapter + structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_isr_handler( struct work_struct *work ) +{ + ET131X_ADAPTER *pAdapter = container_of( work, ET131X_ADAPTER, task ); + + INT_STATUS_t GlobStatus = pAdapter->Stats.InterruptStatus; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_isr_handler" ); + + + /************************************************************************** + These first two are by far the most common. Once handled, we clear + their two bits in the status word. If the word is now zero, we exit. + *************************************************************************/ + /************************************************************************** + Handle all the completed Transmit interrupts + *************************************************************************/ + if( GlobStatus.bits.txdma_isr ) + { + DBG_TX( et131x_dbginfo, "TXDMA_ISR interrupt\n" ); + et131x_handle_send_interrupt( pAdapter ); + } + + + /************************************************************************** + Handle all the completed Receives interrupts + *************************************************************************/ + if( GlobStatus.bits.rxdma_xfr_done ) + { + DBG_RX( et131x_dbginfo, "RXDMA_XFR_DONE interrupt\n" ); + et131x_handle_recv_interrupt( pAdapter ); + } + + GlobStatus.value &= 0xffffffd7; + + if( GlobStatus.value ) + { + + /********************************************************************** + Handle the TXDMA Error interrupt + *********************************************************************/ + if( GlobStatus.bits.txdma_err ) + { + TXDMA_ERROR_t TxDmaErr; + + + /****************************************************************** + Following read also clears the register (COR register) + *****************************************************************/ + TxDmaErr.value = pAdapter->CSRAddress->txdma.TxDmaError.value; + + DBG_WARNING( et131x_dbginfo, "TXDMA_ERR interrupt, error = %d\n", + TxDmaErr.value ); + } + + + /********************************************************************** + Handle Free Buffer Ring 0 and 1 Low interrupt + *********************************************************************/ + if( GlobStatus.bits.rxdma_fb_ring0_low || + GlobStatus.bits.rxdma_fb_ring1_low ) + { + /****************************************************************** + This indicates the number of unused buffers in RXDMA free buffer + ring 0 is <= the limit you programmed. Free buffer resources + need to be returned. Free buffers are consumed as packets are + passed from the network to the host. The host becomes aware of + the packets from the contents of the packet status ring. This + ring is queried when the packet done interrupt occurs. Packets + are then passed to the OS. When the OS is done with the packets + the resources can be returned to the ET1310 for re-use. This + interrupt is one method of returning resources. + *****************************************************************/ + DBG_WARNING( et131x_dbginfo, + "RXDMA_FB_RING0_LOW or " + "RXDMA_FB_RING1_LOW interrupt\n" ); + + + /****************************************************************** + If the user has flow control on, then we will send a pause + packet, otherwise just exit + *****************************************************************/ + if(( pAdapter->FlowControl == TxOnly ) || + ( pAdapter->FlowControl == Both )) + { + /************************************************************** + Tell the device to send a pause packet via the back pressure + register + *************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 0 ) + { + TXMAC_BP_CTRL_t bp_ctrl; + + bp_ctrl.bits.bp_req = 1; + bp_ctrl.bits.bp_xonxoff = 1; + + pAdapter->CSRAddress->txmac.bp_ctrl.value = bp_ctrl.value; + } + } + } + + + /********************************************************************** + Handle Packet Status Ring Low Interrupt + *********************************************************************/ + if( GlobStatus.bits.rxdma_pkt_stat_ring_low ) + { + DBG_WARNING( et131x_dbginfo, + "RXDMA_PKT_STAT_RING_LOW interrupt\n" ); + + + /****************************************************************** + Same idea as with the two Free Buffer Rings. Packets going from + the network to the host each consume a free buffer resource and + a packet status resource. These resoures are passed to the OS. + When the OS is done with the resources, they need to be returned + to the ET1310. This is one method of returning the resources. + *****************************************************************/ + } + + + /********************************************************************** + Handle RXDMA Error Interrupt + *********************************************************************/ + if( GlobStatus.bits.rxdma_err ) + { + /****************************************************************** + The rxdma_error interrupt is sent when a time-out on a request + issued by the JAGCore has occurred or a completion is returned + with an un-successful status. In both cases the request is + considered complete. The JAGCore will automatically re-try the + request in question. Normally information on events like these + are sent to the host using the "Advanced Error Reporting" + capability. This interrupt is another way of getting similar + information. The only thing required is to clear the interrupt + by reading the ISR in the global resources. The JAGCore will do + a re-try on the request. Normally you should never see this + interrupt. If you start to see this interrupt occurring + frequently then something bad has occurred. + A reset might be the thing to do. + *****************************************************************/ + // TRAP(); + + pAdapter->TxMacTest = pAdapter->CSRAddress->txmac.tx_test; + DBG_WARNING( et131x_dbginfo, + "RxDMA_ERR interrupt, error %x\n", + pAdapter->TxMacTest.value ); + } + + + /********************************************************************** + Handle the Wake on LAN Event + *********************************************************************/ + if( GlobStatus.bits.wake_on_lan ) + { + /****************************************************************** + This is a secondary interrupt for wake on LAN. The driver + should never see this, if it does, something serious is wrong. + We will TRAP the message when we are in DBG mode, otherwise we + will ignore it. + *****************************************************************/ + DBG_ERROR( et131x_dbginfo, "WAKE_ON_LAN interrupt\n" ); + } + + + /********************************************************************** + Handle the PHY interrupt + *********************************************************************/ + if( GlobStatus.bits.phy_interrupt ) + { + MI_BMSR_t BmsrInts, BmsrData; + MI_ISR_t myIsr; + + DBG_VERBOSE( et131x_dbginfo, "PHY interrupt\n" ); + + /****************************************************************** + If we are in coma mode when we get this interrupt, we need to + disable it. + *****************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.phy_sw_coma == 1 ) + { + /************************************************************** + Check to see if we are in coma mode and if so, disable it + because we will not be able to read PHY values until we are + out. + *************************************************************/ + DBG_VERBOSE( et131x_dbginfo, "Device is in COMA mode, " + "need to wake up\n" ); + DisablePhyComa( pAdapter ); + } + + + /****************************************************************** + Read the PHY ISR to clear the reason for the interrupt. + *****************************************************************/ + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, isr ), &myIsr.value ); + + if( !pAdapter->ReplicaPhyLoopbk ) + { + MiRead( pAdapter, (UINT8)pAdapter->Stats.xcvr_addr, + (UINT8)FIELD_OFFSET( MI_REGS_t, bmsr ), &BmsrData.value ); + + BmsrInts.value = pAdapter->Bmsr.value ^ BmsrData.value; + pAdapter->Bmsr.value = BmsrData.value; + + DBG_VERBOSE( et131x_dbginfo, + "Bmsr.value = 0x%04x," + "Bmsr_ints.value = 0x%04x\n", + BmsrData.value, + BmsrInts.value ); + + + /************************************************************** + Do all the cable in / cable out stuff + *************************************************************/ + et131x_Mii_check( pAdapter, BmsrData, BmsrInts ); + } + } + + + /********************************************************************** + Let's move on to the TxMac + *********************************************************************/ + if( GlobStatus.bits.txmac_interrupt ) + { + pAdapter->TxRing.TxMacErr.value = pAdapter->CSRAddress->txmac.err.value; + + /****************************************************************** + When any of the errors occur and TXMAC generates an interrupt to + report these errors, it usually means that TXMAC has detected an + error in the data stream retrieved from the on-chip Tx Q. All of + these errors are catastrophic and TXMAC won’t be able to recover + data when these errors occur. In a nutshell, the whole Tx path + will have to be reset and re-configured afterwards. + *****************************************************************/ + DBG_WARNING( et131x_dbginfo, + "TXMAC interrupt, error 0x%08x\n", + pAdapter->TxRing.TxMacErr.value ); + + + /******************************************************************* + If we are debugging, we want to see this error, otherwise we just + want the device to be reset and continue + *****************************************************************/ + //DBG_TRAP(); + + } + + /********************************************************************** + Handle RXMAC Interrupt + *********************************************************************/ + if( GlobStatus.bits.rxmac_interrupt ) + { + /****************************************************************** + These interrupts are catastrophic to the device, what we need to + do is disable the interrupts and set the flag to cause us to + reset so we can solve this issue. + ******************************************************************/ + // MP_SET_FLAG( pAdapter, fMP_ADAPTER_HARDWARE_ERROR ); + + DBG_WARNING( et131x_dbginfo, + "RXMAC interrupt, error 0x%08x. Requesting reset\n", + pAdapter->CSRAddress->rxmac.err_reg.value ); + + DBG_WARNING( et131x_dbginfo, + "Enable 0x%08x, Diag 0x%p\n", + pAdapter->CSRAddress->rxmac.ctrl.value, + &pAdapter->CSRAddress->rxmac.rxq_diag ); + + + /******************************************************************* + If we are debugging, we want to see this error, otherwise we just + want the device to be reset and continue + *****************************************************************/ + // TRAP(); + } + + /********************************************************************** + Handle MAC_STAT Interrupt + *********************************************************************/ + if( GlobStatus.bits.mac_stat_interrupt ) + { + /****************************************************************** + This means at least one of the un-masked counters in the MAC_STAT + block has rolled over. Use this to maintain the top, software + managed bits of the counter(s). + *****************************************************************/ + DBG_VERBOSE( et131x_dbginfo, "MAC_STAT interrupt\n" ); + HandleMacStatInterrupt( pAdapter ); + } + + + /********************************************************************** + Handle SLV Timeout Interrupt + *********************************************************************/ + if( GlobStatus.bits.slv_timeout ) + { + /****************************************************************** + This means a timeout has occured on a read or write request to + one of the JAGCore registers. The Global Resources block has + terminated the request and on a read request, returned a "fake" + value. The most likely reasons are: Bad Address or the + addressed module is in a power-down state and can't respond. + *****************************************************************/ + DBG_VERBOSE( et131x_dbginfo, "SLV_TIMEOUT interrupt\n" ); + } + } + + + if( pAdapter->PoMgmt.PowerState == NdisDeviceStateD0 ) + { + et131x_enable_interrupts( pAdapter ); + } + + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/et131x_initpci.h +++ linux-2.6.28/ubuntu/et131x/et131x_initpci.h @@ -0,0 +1,103 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_initpci.h - Header which includes common data and function prototypes + * related to the driver's PCI (and PCI Express) information. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 17:31:23 $ + $Revision: 1.4 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_INITPCI_H__ +#define __ET131X_INITPCI_H__ + + + + +/****************************************************************************** + Function Prototypes + *****************************************************************************/ +int et131x_pci_register( void ); +void et131x_pci_unregister( void ); + +void et131x_align_allocated_memory( ET131X_ADAPTER *adapter, + UINT64 *phys_addr, + UINT64 *offset, + UINT64 mask ); + + + + +int et131x_adapter_setup( ET131X_ADAPTER *pAdapter ); +int et131x_adapter_memory_alloc( ET131X_ADAPTER *adapter ); +void et131x_adapter_memory_free( ET131X_ADAPTER *adapter ); +void et131x_setup_hardware_properties( ET131X_ADAPTER *adapter ); +void et131x_soft_reset( ET131X_ADAPTER *adapter ); + +#endif /* __ET131X_INITPCI_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/Makefile +++ linux-2.6.28/ubuntu/et131x/Makefile @@ -0,0 +1,6 @@ +obj-$(CONFIG_NET_ET131X) += et131x.o + +et131x-objs += et131x_main.o et131x_initpci.o et131x_isr.o et131x_netdev.o \ + et131x_supp.o et131x_config.o et131x_debug.o ET1310_jagcore.o \ + ET1310_tx.o ET1310_rx.o ET1310_phy.o ET1310_mac.o ET1310_pm.o \ + ET1310_eeprom.o --- linux-2.6.28.orig/ubuntu/et131x/ET1310_eeprom.c +++ linux-2.6.28/ubuntu/et131x/ET1310_eeprom.c @@ -0,0 +1,710 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_eeprom.c - Code used to access the device's EEPROM + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/18 22:18:33 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_eeprom.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" +#include "et131x_isr.h" + +#include "ET1310_tx.h" + + + + +/****************************************************************************** + EEPROM Defines + *****************************************************************************/ +/* LBCIF Register Groups (addressed via 32-bit offsets) */ +#define LBCIF_DWORD0_GROUP_OFFSET 0xAC +#define LBCIF_DWORD1_GROUP_OFFSET 0xB0 + +/* LBCIF Registers (addressed via 8-bit offsets) */ +#define LBCIF_ADDRESS_REGISTER_OFFSET 0xAC +#define LBCIF_DATA_REGISTER_OFFSET 0xB0 +#define LBCIF_CONTROL_REGISTER_OFFSET 0xB1 +#define LBCIF_STATUS_REGISTER_OFFSET 0xB2 + +/* LBCIF Control Register Bits */ +#define LBCIF_CONTROL_SEQUENTIAL_READ 0x01 +#define LBCIF_CONTROL_PAGE_WRITE 0x02 +#define LBCIF_CONTROL_UNUSED1 0x04 +#define LBCIF_CONTROL_EEPROM_RELOAD 0x08 +#define LBCIF_CONTROL_UNUSED2 0x10 +#define LBCIF_CONTROL_TWO_BYTE_ADDR 0x20 +#define LBCIF_CONTROL_I2C_WRITE 0x40 +#define LBCIF_CONTROL_LBCIF_ENABLE 0x80 + +/* LBCIF Status Register Bits */ +#define LBCIF_STATUS_PHY_QUEUE_AVAIL 0x01 +#define LBCIF_STATUS_I2C_IDLE 0x02 +#define LBCIF_STATUS_ACK_ERROR 0x04 +#define LBCIF_STATUS_GENERAL_ERROR 0x08 +#define LBCIF_STATUS_UNUSED 0x30 +#define LBCIF_STATUS_CHECKSUM_ERROR 0x40 +#define LBCIF_STATUS_EEPROM_PRESENT 0x80 + +/* Miscellaneous Constraints */ +#define MAX_NUM_REGISTER_POLLS 1000 +#define MAX_NUM_WRITE_RETRIES 2 + + + + +/****************************************************************************** + Define macros that allow individual register values to be extracted from a + DWORD1 register grouping + *****************************************************************************/ +#define EXTRACT_DATA_REGISTER(x) (UCHAR)(x & 0xFF) +#define EXTRACT_STATUS_REGISTER(x) (UCHAR)((x >> 16) & 0xFF) +#define EXTRACT_CONTROL_REG(x) (UCHAR)((x >> 8) & 0xFF) + + + + +static INT32 LbcifWriteByte( ET131X_ADAPTER *pAdapter, UINT32 unOffset, UCHAR bByte ) +{ + return EEPROM_access( pAdapter, WRITE, unOffset, 8, &bByte ); +} + + +static INT32 LbcifReadDword( ET131X_ADAPTER *pAdapter, UINT32 unOffset, PUINT32 punData ) +{ + return EEPROM_access( pAdapter, READ, unOffset, 32, punData ); +} + + +static INT32 LbcifWriteDword( ET131X_ADAPTER *pAdapter,UINT32 unOffset, UINT32 unData ) +{ + return EEPROM_access( pAdapter, WRITE, unOffset, 32, &unData ); +} + + + + +/****************************************************************************** + ROUTINE : EepromWriteByte + ****************************************************************************** + + DESCRIPTION : Write a byte to the ET1310's EEPROM + + PARAMETERS : pAdapter - pointer to our private adapter structure + unAddress - the address to write + bData - the value to write + unEepronId - the ID of the EEPROM + unAddressingMode - how the EEPROM is to be accessed + + RETURNS : SUCCESS or FAILURE + + REUSE INFORMATION : + + *****************************************************************************/ +INT32 EepromWriteByte( ET131X_ADAPTER *pAdapter, UINT32 unAddress, UCHAR bData, + UINT32 unEepromId, UINT32 unAddressingMode ) +{ + INT32 nIndex; + INT32 nRetries; + INT32 nError = FALSE; + INT32 nI2CWriteActive = 0; + INT32 nWriteSuccessful = 0; + UCHAR bControl; + UCHAR bStatus = 0; + UINT32 unDword1 = 0; + + UINT32 unData = 0; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + The following excerpt is from "Serial EEPROM HW Design Specification" + Version 0.92 (9/20/2004): + + Single Byte Writes + + For an EEPROM, an I2C single byte write is defined as a START + condition followed by the device address, EEPROM address, one byte + of data and a STOP condition. The STOP condition will trigger the + EEPROM's internally timed write cycle to the nonvolatile memory. + All inputs are disabled during this write cycle and the EEPROM will + not respond to any access until the internal write is complete. + The steps to execute a single byte write are as follows: + + 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and + bits 7,1:0 both equal to 1, at least once after reset. Subsequent + operations need only to check that bits 1:0 are equal to 1 prior + to starting a single byte write. + + 2. Write to the LBCIF Control Register: bit 7=1, bit 6=1, bit 3=0, + and bits 1:0 both =0. Bit 5 should be set according to the type + of EEPROM being accessed (1=two byte addressing, 0=one byte + addressing). + + 3. Write the address to the LBCIF Address Register. + + 4. Write the data to the LBCIF Data Register (the I2C write will + begin). + + 5. Monitor bit 1:0 of the LBCIF Status Register. When bits 1:0 are + both equal to 1, the I2C write has completed and the internal + write cycle of the EEPROM is about to start. (bits 1:0 = 01 is a + legal state while waiting from both equal to 1, but bits 1:0 = 10 + is invalid and implies that something is broken). + + 6. Check bit 3 of the LBCIF Status Register. If equal to 1, an + error has occurred. + + 7. Check bit 2 of the LBCIF Status Register. If equal to 1 an ACK + error has occurred on the address phase of the write. This could + be due to an actual hardware failure or the EEPROM may still be in + its internal write cycle from a previous write. This write oper- + ation was ignored and must be repeated later. + + 8. Set bit 6 of the LBCIF Control Register = 0. If another write is + required, go to step 1. + *************************************************************************/ + + + /************************************************************************** + Step 1: + *************************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) + { + /********************************************************************** + Read registers grouped in DWORD1 + *********************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && + bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /****************************************************************** + bits 1:0 are equal to 1 + *****************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 2: + *************************************************************************/ + bControl = 0; + bControl |= LBCIF_CONTROL_LBCIF_ENABLE | LBCIF_CONTROL_I2C_WRITE; + + if( unAddressingMode == DUAL_BYTE ) + { + bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR; + } + + if( LbcifWriteByte( pAdapter, LBCIF_CONTROL_REGISTER_OFFSET, bControl )) + { + return( FAILURE ); + } + + nI2CWriteActive = 1; + + + /************************************************************************** + Prepare EEPROM address for Step 3 + *************************************************************************/ + unAddress |= ( unAddressingMode == DUAL_BYTE ) ? + ( unEepromId << 16 ) : ( unEepromId << 8 ); + + for( nRetries = 0; nRetries < MAX_NUM_WRITE_RETRIES; nRetries++ ) + { + /********************************************************************** + Step 3: + *********************************************************************/ + if( LbcifWriteDword( pAdapter, LBCIF_ADDRESS_REGISTER_OFFSET, unAddress )) + { + break; + } + + /********************************************************************** + Step 4: + *********************************************************************/ + if( LbcifWriteByte( pAdapter, LBCIF_DATA_REGISTER_OFFSET, bData )) + { + break; + } + + /********************************************************************** + Step 5: + *********************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++ ) + { + /****************************************************************** + Read registers grouped in DWORD1 + *****************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, + &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && + bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /************************************************************** + I2C write complete + *************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + break; + } + + + /********************************************************************** + Step 6: Don't break here if we are revision 1, this is so we do a + blind write for load bug. + *********************************************************************/ + if( bStatus & LBCIF_STATUS_GENERAL_ERROR && pAdapter->RevisionID == 0 ) + { + break; + } + + + /********************************************************************** + Step 7: + *********************************************************************/ + if( bStatus & LBCIF_STATUS_ACK_ERROR ) + { + /****************************************************************** + This could be due to an actual hardware failure or the EEPROM + may still be in its internal write cycle from a previous write. + This write operation was ignored and must be repeated later. + *****************************************************************/ + udelay( 10 ); + continue; + } + + nWriteSuccessful = 1; + break; + } + + + /************************************************************************** + Step 8: + *************************************************************************/ + udelay( 10 ); + nIndex = 0; + while( nI2CWriteActive ) + { + bControl &= ~LBCIF_CONTROL_I2C_WRITE; + + if( LbcifWriteByte( pAdapter, LBCIF_CONTROL_REGISTER_OFFSET, bControl )) + { + nWriteSuccessful = 0; + } + + /* Do read until internal ACK_ERROR goes away meaning write completed */ + for( ;; ) + { + /* unAddress */ + LbcifWriteDword( pAdapter, LBCIF_ADDRESS_REGISTER_OFFSET, unAddress ); + + for( ;; ) + { + LbcifReadDword( pAdapter, LBCIF_DATA_REGISTER_OFFSET, &unData ); + + if( unData & 0x00010000 ) + { + break; + } + } + + if(( unData & 0x00040000 ) == 0x0 ) + { + break; + } + } + + bControl = EXTRACT_CONTROL_REG( unData ); + + if( bControl != 0xC0 || nIndex == 10000 ) + { + break; + } + + nIndex++; + } + + return(( nWriteSuccessful ) ? SUCCESS : FAILURE ); +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : EepromReadByte + ****************************************************************************** + + DESCRIPTION : Read a byte from the ET1310's EEPROM + + PARAMETERS : pAdapter - pointer to our private adapter structure + unAddress - the address from which to read + pbData - a pointer to a byte in which to store the + value of the read + unEepronId - the ID of the EEPROM + unAddressingMode - how the EEPROM is to be accessed + + RETURNS : SUCCESS or FAILURE + + REUSE INFORMATION : + + *****************************************************************************/ +INT32 EepromReadByte( ET131X_ADAPTER *pAdapter, UINT32 unAddress, PUCHAR pbData, + UINT32 unEepromId, UINT32 unAddressingMode ) +{ + INT32 nIndex; + INT32 nError = 0; + INT32 nReadSuccessful = 0; + UCHAR bControl; + UCHAR bStatus = 0; + UINT32 unDword1 = 0; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + The following excerpt is from "Serial EEPROM HW Design Specification" + Version 0.92 (9/20/2004): + + Single Byte Reads + + A single byte read is similar to the single byte write, with the + exception of the data flow: + + 1. Check LBCIF Status Register for bits 6 & 3:2 all equal to 0 and + bits 7,1:0 both equal to 1, at least once after reset. Subsequent + operations need only to check that bits 1:0 are equal to 1 prior + to starting a single byte read. + + 2. Write to the LBCIF Control Register: bit 7=1, bit 6=0, bit 3=0, + and bits 1:0 both =0. Bit 5 should be set according to the type + of EEPROM being accessed (1=two byte addressing, 0=one byte addr- + essing). + + 3. Write the address to the LBCIF Address Register (I2C read will + begin). + + 4. Monitor bit 0 of the LBCIF Status Register. When =1, I2C read is + complete. (if bit 1 =1 and bit 0 stays =0, a hardware failure has + occurred). + + 5. Check bit 2 of the LBCIF Status Register. If =1, then an error has + occurred. The data that has been returned from the PHY may be + invalid. + + 6. Regardless of error status, read data byte from LBCIF Data Register. + If another byte is required, go to step 1. + *************************************************************************/ + + + /************************************************************************** + Step 1: + *************************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++) + { + /********************************************************************** + Read registers grouped in DWORD1 + *********************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL && + bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /****************************************************************** + bits 1:0 are equal to 1 + *****************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 2: + *************************************************************************/ + bControl = 0; + bControl |= LBCIF_CONTROL_LBCIF_ENABLE; + + if( unAddressingMode == DUAL_BYTE ) + { + bControl |= LBCIF_CONTROL_TWO_BYTE_ADDR; + } + + if( LbcifWriteByte( pAdapter, LBCIF_CONTROL_REGISTER_OFFSET, bControl )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 3: + *************************************************************************/ + unAddress |= ( unAddressingMode == DUAL_BYTE ) ? + ( unEepromId << 16 ) : ( unEepromId << 8 ); + + if( LbcifWriteDword( pAdapter, LBCIF_ADDRESS_REGISTER_OFFSET, unAddress )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 4: + *************************************************************************/ + for( nIndex = 0; nIndex < MAX_NUM_REGISTER_POLLS; nIndex++ ) + { + /********************************************************************** + Read registers grouped in DWORD1 + *********************************************************************/ + if( LbcifReadDword( pAdapter, LBCIF_DWORD1_GROUP_OFFSET, &unDword1 )) + { + nError = 1; + break; + } + + bStatus = EXTRACT_STATUS_REGISTER( unDword1 ); + + if( bStatus & LBCIF_STATUS_PHY_QUEUE_AVAIL + && bStatus & LBCIF_STATUS_I2C_IDLE ) + { + /****************************************************************** + I2C read complete + *****************************************************************/ + break; + } + } + + if( nError || ( nIndex >= MAX_NUM_REGISTER_POLLS )) + { + return( FAILURE ); + } + + + /************************************************************************** + Step 5: + *************************************************************************/ + nReadSuccessful = ( bStatus & LBCIF_STATUS_ACK_ERROR ) ? 0 : 1; + + + /************************************************************************** + Step 6: + *************************************************************************/ + *pbData = EXTRACT_DATA_REGISTER( unDword1 ); + + return( nReadSuccessful ) ? SUCCESS : FAILURE; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : EEPROM_access + ****************************************************************************** + + DESCRIPTION : + Performs a read or write of a given data width at a specified offset + from EEPROM + + PARAMETERS : + pAdapter - [in] pointer to the adapter structure + bAccessFlag - [in] A flag indicating what type of transaction + READ/WRITE + unOffset - [in] Specifies the offset within the EEPROM + bWidth - [in] Defines the width (in bits) of the requested + access. Valid values are 8 or 32. + pData - [in/out] Pointer to a buffer that contains the data + requested by or resulting from the transaction + specified by 'bAccessFlag'. + Method in which this parameter is processed + (de-referenced) is determined by the value of + 'bWidth', i.e. 8-bit or 32-bit read/write + accesses. + + RETURNS : + result from PCI Config space access + + REUSE INFORMATION : + YES + + *****************************************************************************/ +UINT32 EEPROM_access( ET131X_ADAPTER *pAdapter, UCHAR bAccessFlag, + UINT32 unOffset, UCHAR bWidth, void *pData ) +{ + UINT32 ulResult; + /*-----------------------------------------------------------------------*/ + + if( bAccessFlag == WRITE ) + { + /********************************************************************** + we are doing a write + *********************************************************************/ + ulResult = pci_slot_information_write( pAdapter->pdev, + unOffset, + pData, + ( bWidth / 8 )); + } + else + { + /********************************************************************** + do the read read + *********************************************************************/ + ulResult = pci_slot_information_read( pAdapter->pdev, + unOffset, + pData, + ( bWidth / 8 )); + } + if( ulResult != 0 ) + { + return( 0 ); + } + else + { + return( ulResult ); + } +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/et131x_isr.h +++ linux-2.6.28/ubuntu/et131x/et131x_isr.h @@ -0,0 +1,95 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_isr.h - Defines, structs, enums, prototypes, etc. pertaining to the + * ISR processing code. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.3 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_ISR_H__ +#define __ET131X_ISR_H__ + + + + +/****************************************************************************** + Function Prototypes + *****************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +void et131x_isr( int irq, void *dev_id, struct pt_regs *regs ); +#else +irqreturn_t et131x_isr( int irq, void *dev_id ); +#endif + +void et131x_isr_handler( struct work_struct *work ); + + +#endif /* __ET131X_ISR_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_supp.h +++ linux-2.6.28/ubuntu/et131x/et131x_supp.h @@ -0,0 +1,133 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_supp.h - Misc. defines, structs, enums, prototypes, etc. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.5 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + +#ifndef __ET131X_SUPP_H__ +#define __ET131X_SUPP_H__ + + + + +/****************************************************************************** + Enum for use with netif_indicate_status + *****************************************************************************/ +typedef enum netif_status +{ + NETIF_STATUS_INVALID = 0, + NETIF_STATUS_MEDIA_CONNECT, + NETIF_STATUS_MEDIA_DISCONNECT, + NETIF_STATUS_MAX +} NETIF_STATUS; + + + + +/****************************************************************************** + Definitions to maintain compatibility with older versions of the kernel + *****************************************************************************/ +#ifndef netdev_priv +#define netdev_priv(x) (ET131X_ADAPTER *)netdev->priv +#endif + +#ifndef SET_NETDEV_DEV +#define SET_NETDEV_DEV(net, pdev) +#endif + +#ifndef free_netdev +#define free_netdev(x) kfree(x) +#endif + +#ifndef if_mii +#define if_mii(x) (struct mii_ioctl_data *)&x->ifr_ifru +#endif + + + + +/****************************************************************************** + PROTOTYPES + *****************************************************************************/ +void et131x_init_enet_crc_calc( void ); + +UINT32 et131x_calc_enet_crc( PUCHAR Message, UINT32 MessageSize ); + +UINT32 pci_slot_information_read( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ); + +UINT32 pci_slot_information_write( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ); + +void netif_indicate_status( struct net_device *netdev, NETIF_STATUS status ); + + + + +#endif /* __ET131X_SUPP_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_supp.c +++ linux-2.6.28/ubuntu/et131x/et131x_supp.c @@ -0,0 +1,440 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_supp.c - Misc. support routines. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:13 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" + +#include "et131x_supp.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Global look-up table used to calculate CRC. Preset with the appropriate + XORs from the 256 possible byte values that might be in the message. + *****************************************************************************/ +static UINT32 SynDrome [256]; + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +static UINT32 crc32byte( UINT32 remainder, UCHAR data ); + + + + +/****************************************************************************** + ROUTINE : et131x_init_enet_crc_calc + ****************************************************************************** + + DESCRIPTION : Initializes the look-up table (syndrome) for CRC + calculation. + + PARAMETERS : N/A + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_init_enet_crc_calc( void ) +{ + UINT32 EthernetKey = 0x04c11db7; + UINT32 i; + UINT32 j; + UINT32 reg; + BOOL_t topBit; + /*-----------------------------------------------------------------------*/ + + + for( i = 0; i < 256; i++ ) + { + reg = i << 24; + + for( j = 0; j < 8; j++ ) + { + topBit = ( reg & 0x80000000 ) != 0; + + reg <<= 1; + + if( topBit ) + { + reg ^= EthernetKey; + } + } + SynDrome[i] = reg; + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : crc32byte + ****************************************************************************** + + DESCRIPTION : + + PARAMETERS : + + RETURNS : + + REUSE INFORMATION : + + *****************************************************************************/ +#define CRC32_POLY 0x4C11DB7 + +static UINT32 crc32byte( UINT32 remainder, UCHAR data ) +{ + int index; + UINT32 remndr, hitbit; + /*-----------------------------------------------------------------------*/ + + + remndr = remainder; + + for( index = 0; index < 8; index++ ) + { + hitbit = (remndr >> 31) ^ (data & 0x01); + + data = data >> 1; // get the next data bit + remndr = remndr << 1; // get the next remainder bit + + if( hitbit ) + { + remndr = remndr ^ CRC32_POLY; + } + } + + return remndr; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_calc_enet_crc + ****************************************************************************** + + DESCRIPTION : Used to calculate the CRC of an ethernet message. Used + in the device's filtering of multi-cast packets. + + PARAMETERS : Message - A pointer to the Ethernet bytes to be encoded + MessageSize - The number of bytes in the message + + RETURNS : The computed CRC + + REUSE INFORMATION : + + *****************************************************************************/ +UINT32 et131x_calc_enet_crc( PUCHAR Message, UINT32 MessageSize ) +{ + UINT32 Result = 0xFFFFFFFF; + UINT32 i; + /*-----------------------------------------------------------------------*/ + + for( i = 0; i < MessageSize; i++ ) + { + Result = crc32byte( Result, *Message ); + Message++; + } + + return Result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : pci_slot_information_read + ****************************************************************************** + + DESCRIPTION : Reads a segment of the PCI configuration space for a + device. + + This is a port of the NDIS function + NdisReadPciSlotInformation + + This function does not begin with 'et131x_' in order to + remain consistent with other system pci_xxx() calls. + + PARAMETERS : pdev - pointer to a pci_dev structure for the device + whose PCI config space is to be read + where - the offset to read + buf - a pointer to a buffer in which the data will be + returned + len - the length of the above buffer + + RETURNS : The length of the buffer read + + REUSE INFORMATION : + + *****************************************************************************/ +UINT32 pci_slot_information_read( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ) +{ + int i; + int status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "pci_slot_information_read" ); + + + for( i = 0; i < len; i++ ) + { + status = pci_read_config_byte( pdev, where+i, &buf[i] ); + + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "Cannot Read PCI config space...\n" ); + break; + } + } + + return len; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : pci_slot_information_write + ****************************************************************************** + + DESCRIPTION : Writes a segment of the PCI configuration space for a + device. + + This is a port of the NDIS function + NdisWritePciSlotInformation + + This function does not begin with 'et131x_' in order to + remain consistent with other system pci_xxx() calls. + + PARAMETERS : pdev - pointer to a pci_dev structure for the device + whose PCI config space is to be written + where - the offset to write + buf - a pointer to a buffer containing the data to be + written + len - the length of the above buffer + + RETURNS : The length of the buffer written + + REUSE INFORMATION : + + *****************************************************************************/ +UINT32 pci_slot_information_write( struct pci_dev *pdev, UINT32 where, + UINT8 *buf, UINT32 len ) +{ + int i; + int status; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "pci_slot_information_write" ); + + + for( i = 0; i < len; i++ ) + { + status = pci_write_config_byte( pdev, where+i, buf[i] ); + + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "Cannot Write PCI config space...\n" ); + break; + } + } + + return len; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : netif_indicate_status + ****************************************************************************** + + DESCRIPTION : Provides the network stack with link status for the + given device. + + This is a port of the NDIS function + NdisMIndicateStatus. Unlike NDIS, there is no + corresponding status completion function. + + This function does not begin with 'et131x_' in order to + remain consistent with other system netif_xxx() calls. + + PARAMETERS : netdev - a pointer to the net_device struct representing + the device whose status we wosh to indicate. + status - the link status + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void netif_indicate_status( struct net_device *netdev, NETIF_STATUS status ) +{ + DBG_FUNC( "netif_indicate_status" ); + + + if( netdev != NULL ) + { + switch( status ) + { + case NETIF_STATUS_MEDIA_CONNECT: + DBG_VERBOSE( et131x_dbginfo, "Indicating Link UP\n" ); + netif_carrier_on( netdev ); + break; + + case NETIF_STATUS_MEDIA_DISCONNECT: + DBG_VERBOSE( et131x_dbginfo, "Indicating Link DOWN\n" ); + netif_carrier_off( netdev ); + break; + + default: + DBG_WARNING( et131x_dbginfo, + "Unknown link status code: %d\n", + status ); + break; + } + } + else + { + DBG_WARNING( et131x_dbginfo, "net_device pointer is NULL\n" ); + } + + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_eeprom.h +++ linux-2.6.28/ubuntu/et131x/ET1310_eeprom.h @@ -0,0 +1,127 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_eeprom.h - Defines, structs, enums, prototypes, etc. used for EEPROM + * access routines + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:10 $ + $Revision: 1.4 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_EEPROM_H__ +#define __ET1310_EEPROM_H__ + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + +#ifndef SUCCESS + #define SUCCESS 0 + #define FAILURE 1 +#endif + +#ifndef READ + #define READ 0 + #define WRITE 1 +#endif + +#ifndef SINGLE_BYTE + #define SINGLE_BYTE 0 + #define DUAL_BYTE 1 +#endif + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +UINT32 EEPROM_access( struct et131x_adapter *pAdapter, UCHAR bAccessFlag, + UINT32 unOffset, UCHAR bWidth, void *pData ); + +INT32 EepromWriteByte( struct et131x_adapter *pAdapter, UINT32 unAddress, + UCHAR bData, UINT32 unEepromId, UINT32 unAddressingMode ); + +INT32 EepromReadByte( struct et131x_adapter *pAdapter, UINT32 unAddress, + PUCHAR pbData, UINT32 unEepromId, UINT32 unAddressingMode ); + + + + +#endif /* _ET1310_EEPROM_H_ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_debug.h +++ linux-2.6.28/ubuntu/et131x/et131x_debug.h @@ -0,0 +1,267 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_debug.h - Defines, structs, enums, prototypes, etc. used for + * outputting debug messages to the system logging facility + * (ksyslogd) + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:12 $ + $Revision: 1.10 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET131X_DBG_H__ +#define __ET131X_DBG_H__ + + + + +/****************************************************************************** + Define Masks for debugging types/levels + *****************************************************************************/ +#define DBG_ERROR_ON 0x00000001L +#define DBG_WARNING_ON 0x00000002L +#define DBG_NOTICE_ON 0x00000004L +#define DBG_TRACE_ON 0x00000008L +#define DBG_VERBOSE_ON 0x00000010L +#define DBG_PARAM_ON 0x00000020L +#define DBG_BREAK_ON 0x00000040L +#define DBG_RX_ON 0x00000100L +#define DBG_TX_ON 0x00000200L + + + + +#ifdef ET131X_DBG + + +/****************************************************************************** + Set the level of debugging if not done with a preprocessor define. See + et131x_main.c, function et131x_init_module() for how the debug level + translates into the types of messages displayed. + *****************************************************************************/ +#ifndef DBG_LVL +#define DBG_LVL 3 +#endif /* DBG_LVL */ + + +#define DBG_DEFAULTS (DBG_ERROR_ON | DBG_WARNING_ON | DBG_BREAK_ON ) + +#define DBG_FLAGS(A) (A)->dbgFlags +#define DBG_NAME(A) (A)->dbgName +#define DBG_LEVEL(A) (A)->dbgLevel + + +#ifndef PRINTK +# define PRINTK(S...) printk(S) +#endif /* PRINTK */ + + +#ifndef DBG_PRINT +# define DBG_PRINT(S...) PRINTK(KERN_DEBUG S) +#endif /* DBG_PRINT */ + + +#ifndef DBG_PRINTC +# define DBG_PRINTC(S...) PRINTK(S) +#endif /* DBG_PRINTC */ + + +#ifndef DBG_TRAP +# define DBG_TRAP {} //BUG() +#endif /* DBG_TRAP */ + + +#define _ENTER_STR ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +#define _LEAVE_STR "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" + + +#define _DBG_ENTER(A) DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),++DBG_LEVEL(A),_ENTER_STR,__FUNC__) +#define _DBG_LEAVE(A) DBG_PRINT("%s:%.*s:%s\n",DBG_NAME(A),DBG_LEVEL(A)--,_LEAVE_STR,__FUNC__) + + +#define DBG_FUNC(F) static const char __FUNC__[] = F; + + +#define DBG_ENTER(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_ENTER(A);} + + +#define DBG_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + _DBG_LEAVE(A);} + + +#define DBG_PARAM(A,N,F,S...) {if (DBG_FLAGS(A) & DBG_PARAM_ON) \ + DBG_PRINT(" %s -- "F"\n",N,S);} + + +#define DBG_ERROR(A,S...) {if (DBG_FLAGS(A) & DBG_ERROR_ON) \ + {DBG_PRINT("%s:ERROR:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);DBG_TRAP;}} + + +#define DBG_WARNING(A,S...) {if (DBG_FLAGS(A) & DBG_WARNING_ON) \ + {DBG_PRINT("%s:WARNING:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + + +#define DBG_NOTICE(A,S...) {if (DBG_FLAGS(A) & DBG_NOTICE_ON) \ + {DBG_PRINT("%s:NOTICE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + + +#define DBG_TRACE(A,S...) {if (DBG_FLAGS(A) & DBG_TRACE_ON) \ + {DBG_PRINT("%s:TRACE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + +#define DBG_VERBOSE(A,S...) {if (DBG_FLAGS(A) & DBG_VERBOSE_ON) \ + {DBG_PRINT("%s:VERBOSE:%s ",DBG_NAME(A),__FUNC__);DBG_PRINTC(S);}} + + +#define DBG_RX(A,S...) {if (DBG_FLAGS(A) & DBG_RX_ON) \ + {DBG_PRINT(S);}} + +#define DBG_RX_ENTER(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ + _DBG_ENTER(A);} + +#define DBG_RX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_RX_ON) \ + _DBG_LEAVE(A);} + +#define DBG_TX(A,S...) {if (DBG_FLAGS(A) & DBG_TX_ON) \ + {DBG_PRINT(S);}} + +#define DBG_TX_ENTER(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ + _DBG_ENTER(A);} + +#define DBG_TX_LEAVE(A) {if (DBG_FLAGS(A) & DBG_TX_ON) \ + _DBG_LEAVE(A);} + + +#define DBG_ASSERT(C) {if (!(C)) \ + {DBG_PRINT("ASSERT(%s) -- %s#%d (%s)\n", \ + #C,__FILE__,__LINE__,__FUNC__); \ + DBG_TRAP;}} +#define STATIC + + +typedef struct +{ + char *dbgName; + int dbgLevel; + unsigned long dbgFlags; +} dbg_info_t; + + + + +#else /* ET131X_DBG */ + + + + +#define DBG_DEFN +#define DBG_TRAP +#define DBG_FUNC(F) +#define DBG_PRINT(S...) +#define DBG_ENTER(A) +#define DBG_LEAVE(A) +#define DBG_PARAM(A,N,F,S...) +#define DBG_ERROR(A,S...) +#define DBG_WARNING(A,S...) +#define DBG_NOTICE(A,S...) +#define DBG_TRACE(A,S...) +#define DBG_VERBOSE(A,S...) +#define DBG_RX(A,S...) +#define DBG_RX_ENTER(A) +#define DBG_RX_LEAVE(A) +#define DBG_TX(A,S...) +#define DBG_TX_ENTER(A) +#define DBG_TX_LEAVE(A) +#define DBG_ASSERT(C) +#define STATIC static + +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for et131x_debug.c + *****************************************************************************/ +void DumpTxQueueContents( int dbgLvl, struct et131x_adapter *pAdapter ); +void DumpDeviceBlock( int dbgLvl, struct et131x_adapter *pAdapter, unsigned int Block ); +void DumpDeviceReg( int dbgLvl, struct et131x_adapter *pAdapter ); + + + + +#endif /* __ET131X_DBG_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_jagcore.h +++ linux-2.6.28/ubuntu/et131x/ET1310_jagcore.h @@ -0,0 +1,180 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_jagcore.h - Defines, structs, enums, prototypes, etc. pertaining to + * the JAGCore + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:44 $ + $Revision: 1.7 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_JAGCORE_H__ +#define __ET1310_JAGCORE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + INCLUDES + *****************************************************************************/ +#include "ET1310_common.h" + + + + +/****************************************************************************** + CONSTANTS FOR JAGCORE + *****************************************************************************/ +#define INTERNAL_MEM_SIZE 0x400 //1024 of internal memory +#define INTERNAL_MEM_RX_OFFSET 0x1FF //50% Tx, 50% Rx + +#define REGS_MAX_ARRAY 4096 + + + + +/****************************************************************************** + For interrupts, normal running is: + rxdma_xfr_done, phy_interrupt, mac_stat_interrupt, + watchdog_interrupt & txdma_xfer_done + + In both cases, when flow control is enabled for either Tx or bi-direction, + we additional enable rx_fbr0_low and rx_fbr1_low, so we know when the + buffer rings are running low. + *****************************************************************************/ +#define INT_MASK_DISABLE 0xffffffff + +// NOTE: Masking out MAC_STAT Interrupt for now... +//#define INT_MASK_ENABLE 0xfff6bf17 +//#define INT_MASK_ENABLE_NO_FLOW 0xfff6bfd7 +#define INT_MASK_ENABLE 0xfffebf17 +#define INT_MASK_ENABLE_NO_FLOW 0xfffebfd7 + + + + +/****************************************************************************** + DATA STRUCTURES FOR DIRECT REGISTER ACCESS + *****************************************************************************/ +typedef struct +{ + u8 bReadWrite; + u32 nRegCount; + u32 nData [REGS_MAX_ARRAY]; + u32 nOffsets [REGS_MAX_ARRAY]; +} JAGCORE_ACCESS_REGS, *PJAGCORE_ACCESS_REGS; + + +typedef struct +{ + u8 bReadWrite; + u32 nDataWidth; + u32 nRegCount; + u32 nOffsets [REGS_MAX_ARRAY]; + u32 nData [REGS_MAX_ARRAY]; +} PCI_CFG_SPACE_REGS, *PPCI_CFG_SPACE_REGS; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES + *****************************************************************************/ +void ConfigGlobalRegs(struct et131x_adapter *pAdapter ); + +void ConfigMMCRegs( struct et131x_adapter *pAdapter ); + +void et131x_enable_interrupts( struct et131x_adapter *adapter ); + +void et131x_disable_interrupts( struct et131x_adapter *adapter ); + +void * et131x_get_regs( struct et131x_adapter *pAdapter, void *InfoBuf, + PUINT32 ulBytesAvailable, PUINT32 ulInfoLen ); + +void et131x_set_regs( struct et131x_adapter *pAdapter, void *InfoBuf ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_JAGCORE_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/et131x_debug.c +++ linux-2.6.28/ubuntu/et131x/et131x_debug.c @@ -0,0 +1,328 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_debug.c - Routines used for debugging. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/08/01 19:35:12 $ + $Revision: 1.6 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifdef ET131X_DBG + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_netdev.h" +#include "et131x_config.h" +#include "et131x_isr.h" + +#include "ET1310_address_map.h" +#include "ET1310_jagcore.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" +#include "ET1310_mac.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +extern dbg_info_t *et131x_dbginfo; + + + + +/****************************************************************************** + ROUTINE: DumpTxQueueContents + ****************************************************************************** + DESCRIPTION: + Used to dump out hte tx queue and the shadow pointers + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void DumpTxQueueContents( int dbgLvl, ET131X_ADAPTER *pAdapter ) +{ + UINT32 TxQueueAddr; + /*-----------------------------------------------------------------------*/ + + + if( DBG_FLAGS( et131x_dbginfo ) & dbgLvl ) + { + + for( TxQueueAddr = 0x200; TxQueueAddr< 0x3ff; TxQueueAddr++ ) + { + pAdapter->CSRAddress->mmc.sram_access.bits.req_addr = TxQueueAddr; + pAdapter->CSRAddress->mmc.sram_access.bits.req_access = 1; + + + DBG_PRINT( "Addr 0x%x, Access 0x%08x\t" + "Value 1 0x%08x, Value 2 0x%08x, " + "Value 3 0x%08x, Value 4 0x%08x, \n", + TxQueueAddr, + pAdapter->CSRAddress->mmc.sram_access.value, + pAdapter->CSRAddress->mmc.sram_word1.data, + pAdapter->CSRAddress->mmc.sram_word2.data, + pAdapter->CSRAddress->mmc.sram_word3.data, + pAdapter->CSRAddress->mmc.sram_word4.data ); + + } + + DBG_PRINT( "Shadow Pointers 0x%08x\n", + pAdapter->CSRAddress->txmac.shadow_ptr.value ); + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: DumpDeviceBlock + ****************************************************************************** + + DESCRIPTION: + Dumps the first 64 regs of each block of the et-1310 (each block is + mapped to a new page, each page is 4096 bytes). + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURN : + VOID + *****************************************************************************/ +#define NUM_BLOCKS 8 +void DumpDeviceBlock( int dbgLvl, ET131X_ADAPTER *pAdapter, UINT32 Block ) +{ + UINT32 Address1, Address2; + UINT32 *BigDevicePointer = (UINT32 *)pAdapter->CSRAddress; + /*-----------------------------------------------------------------------*/ + + + char* BlockNames[NUM_BLOCKS] = + {"Global", "Tx DMA", "Rx DMA", "Tx MAC", + "Rx MAC", "MAC", "MAC Stat", "MMC" }; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Output the debug counters to the debug terminal + *************************************************************************/ + if( DBG_FLAGS( et131x_dbginfo ) & dbgLvl ) + { + DBG_PRINT( "%s block\n", BlockNames[Block] ); + + for( Address1 = 0; Address1 < 8; Address1++ ) + { + for( Address2 = 0; Address2 < 8; Address2++ ) + { + if( Block == 0 ) + { + if((( Address1 * 8 ) + Address2 ) == 6 ) + { + DBG_PRINT( " ISR , " ); + } + else + { + DBG_PRINT( "0x%08x, ", + BigDevicePointer[( Block * 1024 ) + + ( Address1 * 8 ) + Address2] ); + + } + } + else + { + DBG_PRINT( "0x%08x, ", + BigDevicePointer[( Block * 1024 ) + + ( Address1 * 8 ) + Address2] ); + } + } + + DBG_PRINT( "\n" ); + } + + DBG_PRINT( "\n" ); + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: DumpDeviceReg + ****************************************************************************** + + DESCRIPTION: + Dumps the first 64 regs of each block of the et-1310 (each block is + mapped to a new page, each page is 4096 bytes). + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURN : + VOID + *****************************************************************************/ +void DumpDeviceReg( int dbgLvl, ET131X_ADAPTER *pAdapter ) +{ + UINT32 Address1, Address2; + UINT32 Block; + UINT32 *BigDevicePointer = (UINT32 *)pAdapter->CSRAddress; + + char* BlockNames[NUM_BLOCKS] = + {"Global", "Tx DMA", "Rx DMA", "Tx MAC", + "Rx MAC", "MAC", "MAC Stat", "MMC" }; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Output the debug counters to the debug terminal + *************************************************************************/ + if( DBG_FLAGS( et131x_dbginfo ) & dbgLvl ) + { + for( Block = 0; Block < NUM_BLOCKS; Block++ ) + { + DBG_PRINT( "%s block\n", BlockNames[Block] ); + + for( Address1 = 0; Address1 < 8; Address1++ ) + { + for( Address2 = 0; Address2 < 8; Address2++ ) + { + DBG_PRINT( "0x%08x, ", + BigDevicePointer[( Block * 1024 ) + + ( Address1 * 8 ) + Address2] ); + } + + DBG_PRINT( "\n" ); + } + + DBG_PRINT( "\n" ); + } + } + + return; +} +/*==========================================================================*/ + + + + +#endif // ET131X_DBG --- linux-2.6.28.orig/ubuntu/et131x/et131x_initpci.c +++ linux-2.6.28/ubuntu/et131x/et131x_initpci.c @@ -0,0 +1,1839 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * et131x_initpci.c - Routines and data used to register the driver with the + * PCI (and PCI Express) subsystem, as well as basic driver + * init and startup. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/25 20:48:56 $ + $Revision: 1.22 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_netdev.h" +#include "et131x_config.h" +#include "et131x_isr.h" + +#include "ET1310_address_map.h" +#include "ET1310_jagcore.h" +#include "ET1310_tx.h" +#include "ET1310_rx.h" +#include "ET1310_mac.h" +#include "ET1310_eeprom.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions with local scope + *****************************************************************************/ +int __devinit et131x_pci_probe( struct pci_dev *pdev, + const struct pci_device_id *ent ); + +void __devexit et131x_pci_remove( struct pci_dev *pdev ); + +int et131x_pci_setup( struct pci_dev *pdev ); + + + + +/****************************************************************************** + Data for PCI registration + *****************************************************************************/ +enum et131x_pci_versions +{ + Agere_Systems_PCI_V1 = 0, +}; + + +static struct pci_device_id et131x_pci_table[] __devinitdata = +{ + { ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_GIG, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { ET131X_PCI_VENDOR_ID, ET131X_PCI_DEVICE_ID_FAST, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL }, + { 0, } +}; + +MODULE_DEVICE_TABLE( pci, et131x_pci_table ); + + +static struct pci_driver et131x_driver = +{ + name: DRIVER_NAME, + id_table: et131x_pci_table, + probe: et131x_pci_probe, + remove: __devexit_p( et131x_pci_remove ), + suspend: NULL, //et131x_pci_suspend, + resume: NULL, //et131x_pci_resume, +}; + + + + +/****************************************************************************** + ROUTINE : et131x_find_adapter + ****************************************************************************** + + DESCRIPTION : Find the adapter and get all the assigned resources + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_find_adapter( ET131X_ADAPTER *adapter, struct pci_dev *pdev ) +{ + int result; + UCHAR eepromStat = 0; + UCHAR maxPayload = 0; + UCHAR latencyTimers = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_find_adapter" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Allow disabling of Non-Maskable Interrupts in I/O space, to + support validation. + *************************************************************************/ + if( adapter->RegistryNMIDisable ) + { + UCHAR RegisterVal; + + RegisterVal = inb( ET1310_NMI_DISABLE ); + RegisterVal &= 0xf3; + + if( adapter->RegistryNMIDisable == 2 ) + { + RegisterVal |= 0xc; + } + + outb( ET1310_NMI_DISABLE, RegisterVal ); + } + + + /************************************************************************** + We first need to check the EEPROM Status code located at offset 0xB2 + of config space + *************************************************************************/ + + result = pci_slot_information_read( pdev, + ET1310_PCI_EEPROM_STATUS, + &eepromStat, + sizeof( UCHAR )); + /************************************************************************* + THIS IS A WORKAROUND: + * I need to call this function twice to get my card in a + LG M1 Express Dual running. I tried also a msleep before this + function, because I thougth there could be some time condidions + but it didn't work. Call the whole function twice also work. + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_EEPROM_STATUS, + &eepromStat, + sizeof( UCHAR )); + + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, "Could not read PCI config space for " + "EEPROM Status\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Determine if the error(s) we care about are present. If they are + present, we need to fail. + *************************************************************************/ + if( eepromStat & 0x4C ) + { + result = pci_slot_information_read( pdev, + PCI_REVISION_ID, + &adapter->RevisionID, + sizeof( UCHAR )); + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for " + "Revision ID\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else if( adapter->RevisionID == 0x01 ) + { + INT32 nLoop; + UCHAR ucTemp[4] = {0xFE, 0x13, 0x10, 0xFF}; + + /****************************************************************** + Re-write the first 4 bytes if we have an eeprom present and + the revision id is 1, this fixes the corruption seen with + 1310 B Silicon + *****************************************************************/ + for( nLoop = 0; nLoop < 3; nLoop++ ) + { + EepromWriteByte( adapter, nLoop, ucTemp[nLoop], 0, SINGLE_BYTE ); + } + } + + DBG_ERROR( et131x_dbginfo, "Fatal EEPROM Status Error - 0x%04x\n", + eepromStat ); + + /********************************************************************** + This error could mean that there was an error reading the eeprom + or that the eeprom doesn't exist. We will treat each case the + same and not try to gather additional information that normally + would come from the eeprom, like MAC Address + *********************************************************************/ + adapter->bEepromPresent = FALSE; + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else + { + DBG_TRACE( et131x_dbginfo, "EEPROM Status Code - 0x%04x\n", eepromStat ); + adapter->bEepromPresent = TRUE; + } + + + /************************************************************************** + Read the EEPROM for information regarding LED behavior. Refer to + ET1310_phy.c, et131x_xcvr_init(), for its use. + *************************************************************************/ + EepromReadByte( adapter, 0x70, &adapter->eepromData [0], 0, SINGLE_BYTE ); + EepromReadByte( adapter, 0x71, &adapter->eepromData [1], 0, SINGLE_BYTE ); + + if( adapter->eepromData[0] != 0xcd ) + { + adapter->eepromData[1] = 0x00; // Disable all optional features + } + + + /************************************************************************** + Let's set up the PORT LOGIC Register. First we need to know what the + max_payload_size is + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_MAX_PYLD, + &maxPayload, + sizeof( UCHAR )); + + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, "Could not read PCI config space for " + "Max Payload Size\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else + { + UINT16 AckNak [2] = {0x76, 0xD0}; + UINT16 Replay [2] = {0x1E0, 0x2ED}; + + + /********************************************************************** + Program the Ack/Nak latency and replay timers + *********************************************************************/ + maxPayload &= 0x07; // Only the lower 3 bits are valid + + if( maxPayload < 2 ) + { + result = pci_slot_information_write( pdev, + ET1310_PCI_ACK_NACK, + (UINT8 *)&AckNak[maxPayload], + sizeof( UINT16 )); + if( result != sizeof( UINT16 )) + { + DBG_ERROR( et131x_dbginfo, "Could not write PCI config space " + "for ACK/NAK\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + result = pci_slot_information_write( pdev, + ET1310_PCI_REPLAY, + (UINT8 *)&Replay[maxPayload], + sizeof( UINT16 )); + if( result != sizeof( UINT16 )) + { + DBG_ERROR( et131x_dbginfo, "Could not write PCI config space " + "for Replay Timer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + } + } + + + /************************************************************************** + l0s and l1 latency timers. We are using default values. + *************************************************************************/ + latencyTimers = 0x11; // Representing 001 for L0s and 010 for L1 + + result = pci_slot_information_write( pdev, + ET1310_PCI_L0L1LATENCY, + (UINT8 *)&latencyTimers, + sizeof( UCHAR )); + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, "Could not write PCI config space for " + "Latency Timers\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Archive Power management capability values for later use + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_PM_CAPABILITY, + (UINT8 *)&adapter->PoMgmt.pmConfigRegs, + sizeof( MP_PM_CONFIG_SPACE_INFO_t )); + if( result != sizeof( MP_PM_CONFIG_SPACE_INFO_t )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for PM Capability\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + else + { + UCHAR read_size_reg; + + /****************************************************************** + Change the max read size to 2k + *****************************************************************/ + result = pci_slot_information_read( pdev, + 0x51, + (void *)&read_size_reg, + sizeof( UCHAR )); + + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for Max read size\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + read_size_reg &= 0x8f; + read_size_reg |= 0x40; + + result = pci_slot_information_write( pdev, + 0x51, + &read_size_reg, + sizeof( UCHAR )); + if( result != sizeof( UCHAR )) + { + DBG_ERROR( et131x_dbginfo, + "Could not write PCI config space for Max read size\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + } + + + /************************************************************************** + PCI Express Configuration registers 0x48-0x5B (Device Control) + *************************************************************************/ + result = pci_slot_information_read( pdev, + ET1310_PCI_DEV_CTRL, + (UINT8 *)&adapter->PciXDevCtl, + sizeof( UINT16 )); + + if( result != sizeof( UINT16 )) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for PCI Express Dev Ctl\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Get MAC address from config space if an eeprom exists, otherwise the + MAC address there will not be valid + *************************************************************************/ + if( adapter->bEepromPresent ) + { + result = pci_slot_information_read( pdev, + ET1310_PCI_MAC_ADDRESS, + (UINT8 *)adapter->PermanentAddress, + ETH_ALEN ); + if( result != ETH_ALEN ) + { + DBG_ERROR( et131x_dbginfo, + "Could not read PCI config space for MAC address\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_error_timer_handler + ****************************************************************************** + + DESCRIPTION : The routine called when the error timer expires, to + track the number of recurring errors. + + PARAMETERS : data - a timer-specific variable; in this case, a + pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_error_timer_handler( unsigned long data ) +{ + ET131X_ADAPTER *pAdapter = (ET131X_ADAPTER *)data; + PM_CSR_t pm_csr; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_error_timer_handler" ); + + + pm_csr = pAdapter->CSRAddress->global.pm_csr; + + if( pm_csr.bits.pm_phy_sw_coma == 0 ) + { + if( pAdapter->RegistryMACStat ) + { + UpdateMacStatHostCounters( pAdapter ); + } + } + else + { + DBG_VERBOSE( et131x_dbginfo, + "No interrupts, in PHY coma, pm_csr = 0x%x\n", + pm_csr.value ); + } + + + if( !pAdapter->Bmsr.bits.link_status && + pAdapter->RegistryPhyComa && + pAdapter->PoMgmt.TransPhyComaModeOnBoot < 11 ) + { + pAdapter->PoMgmt.TransPhyComaModeOnBoot++; + } + + if( pAdapter->PoMgmt.TransPhyComaModeOnBoot == 10 ) + { + if( !pAdapter->Bmsr.bits.link_status && pAdapter->RegistryPhyComa ) + { + if( pAdapter->CSRAddress->global.pm_csr.bits.phy_sw_coma == 0 ) + { + // NOTE - This was originally a 'sync with interrupt'. How + // to do that under Linux? + et131x_enable_interrupts( pAdapter ); + EnablePhyComa( pAdapter ); + } + } + } + + + /************************************************************************** + This is a periodic timer, so reschedule + *************************************************************************/ + add_timer( &pAdapter->ErrorTimer ); + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_link_detection_handler + ****************************************************************************** + DESCRIPTION: + Timer function for handling link up at driver load time + + PARAMETERS : + SystemSpecific1 Not used + FunctionContext Pointer to our adapter + SystemSpecific2 Not used + SystemSpecific3 Not used + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_link_detection_handler( unsigned long data ) +{ + ET131X_ADAPTER *pAdapter = (ET131X_ADAPTER *)data; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Let everyone know that we have run + *************************************************************************/ + pAdapter->bLinkTimerActive = FALSE; + + if( pAdapter->MediaState == 0 ) + { + spin_lock_irqsave( &pAdapter->Lock, lockflags ); + + pAdapter->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; + MP_CLEAR_FLAG( pAdapter, fMP_ADAPTER_LINK_DETECTION ); + + spin_unlock_irqrestore( &pAdapter->Lock, lockflags ); + + netif_indicate_status( pAdapter->netdev, pAdapter->MediaState ); + + if( pAdapter->bSetPending ) + { + pAdapter->bSetPending = FALSE; + } + } + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_adapter_setup + ****************************************************************************** + + DESCRIPTION : Used to set the adapter up as per cassini+ documentation + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_adapter_setup( ET131X_ADAPTER *pAdapter ) +{ + int status = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_adapter_setup" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Configure the JAGCore + *************************************************************************/ + ConfigGlobalRegs( pAdapter ); + + ConfigMACRegs1( pAdapter ); + ConfigMMCRegs( pAdapter ); + + ConfigRxMacRegs( pAdapter ); + ConfigTxMacRegs( pAdapter ); + + ConfigRxDmaRegs( pAdapter ); + ConfigTxDmaRegs( pAdapter ); + + ConfigMacStatRegs( pAdapter ); + + + /************************************************************************** + Move the following code to Timer function?? + *************************************************************************/ + status = et131x_xcvr_find( pAdapter ); + + if( status != 0 ) + { + DBG_WARNING( et131x_dbginfo, "Could not find the xcvr\n" ); + } + + + /********************************************************************** + Prepare the TRUEPHY library. + *********************************************************************/ + ET1310_PhyInit( pAdapter ); + + + /************************************************************************** + Reset the phy now so changes take place + *************************************************************************/ + ET1310_PhyReset( pAdapter ); + + + /************************************************************************** + Power down PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 1 ); + + + /************************************************************************** + We need to turn off 1000 base half dulplex, the mac does not + support it + For the 10/100 part, turn off all gig advertisement + *************************************************************************/ + if( pAdapter->DeviceID != ET131X_PCI_DEVICE_ID_FAST ) + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_FULL ); + } + else + { + ET1310_PhyAdvertise1000BaseT( pAdapter, TRUEPHY_ADV_DUPLEX_NONE ); + } + + + /************************************************************************** + Power up PHY + *************************************************************************/ + ET1310_PhyPowerDown( pAdapter, 0 ); + + et131x_setphy_normal( pAdapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_setup_hardware_properties + ****************************************************************************** + + DESCRIPTION : Used to set up the MAC Address on the ET1310 + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_setup_hardware_properties( ET131X_ADAPTER *adapter ) +{ + DBG_FUNC( "et131x_setup_hardware_properties" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + If have our default mac from registry and no mac address from EEPROM + then we need to generate the last octet and set it on the device + *************************************************************************/ + if( !adapter->bOverrideAddress ) + { + if (adapter->PermanentAddress[0] == 0x00 && + adapter->PermanentAddress[1] == 0x00 && + adapter->PermanentAddress[2] == 0x00 && + adapter->PermanentAddress[3] == 0x00 && + adapter->PermanentAddress[4] == 0x00 && + adapter->PermanentAddress[5] == 0x00 ) + { + /****************************************************************** + We need to randomly generate the last octet so we decrease our + chances of setting the mac address to same as another one of + our cards in the system + *****************************************************************/ + get_random_bytes( &adapter->CurrentAddress[5], 1 ); + + + /****************************************************************** + We have the default value in the register we are working with + so we need to copy the current address into the permanent + address + *****************************************************************/ + memcpy( adapter->PermanentAddress, + adapter->CurrentAddress, + ETH_ALEN ); + } + else + { + /****************************************************************** + We do not have an override address, so set the current address + to the permanent address and add it to the device + *****************************************************************/ + memcpy( adapter->CurrentAddress, + adapter->PermanentAddress, + ETH_ALEN ); + } + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_soft_reset + ****************************************************************************** + + DESCRIPTION : Issue a soft reset to the hardware, complete for ET1310. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_soft_reset( ET131X_ADAPTER *adapter ) +{ + DBG_FUNC( "et131x_soft_reset" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Disable MAC Core + *************************************************************************/ + adapter->CSRAddress->mac.cfg1.value = 0xc00f0000; + + + /************************************************************************** + Set everything to a reset value + *************************************************************************/ + adapter->CSRAddress->global.sw_reset.value = 0x7F; + adapter->CSRAddress->mac.cfg1.value = 0x000f0000; + adapter->CSRAddress->mac.cfg1.value = 0x00000000; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_align_allocated_memory + ****************************************************************************** + + DESCRIPTION : Align an allocated block of memory on a given boundary + + PARAMETERS : adapter - pointer to our adapter structure + phys_addr - pointer to Physical address + offset - pointer to the offset variable + mask - correct mask + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_align_allocated_memory( ET131X_ADAPTER *adapter, + UINT64 *phys_addr, + UINT64 *offset, + UINT64 mask ) +{ + UINT64 new_addr; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_align_allocated_memory" ); + DBG_ENTER( et131x_dbginfo ); + + + *offset = 0; + + new_addr = *phys_addr & ~mask; + + if( new_addr != *phys_addr ) + { + new_addr += mask+1; // Move to next aligned block + *offset = new_addr - *phys_addr; // Return offset for adjusting virt addr + *phys_addr = new_addr; // Return new physical address + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_adapter_memory_alloc + ****************************************************************************** + + DESCRIPTION : Allocate all the memory blocks for send, receive and + others. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_adapter_memory_alloc( ET131X_ADAPTER *adapter ) +{ + int status = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_adapter_memory_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + do + { + /********************************************************************** + Allocate memory for the Tx Ring + *********************************************************************/ + status = et131x_tx_dma_memory_alloc( adapter ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "et131x_tx_dma_memory_alloc FAILED\n" ); + break; + } + + + /********************************************************************** + Receive buffer memory allocation + *********************************************************************/ + status = et131x_rx_dma_memory_alloc( adapter ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "et131x_rx_dma_memory_alloc FAILED\n" ); + et131x_tx_dma_memory_free( adapter ); + break; + } + + + /********************************************************************** + Init receive data structures + *********************************************************************/ + status = et131x_init_recv( adapter ); + if( status != 0 ) + { + DBG_ERROR( et131x_dbginfo, "et131x_init_recv FAILED\n" ); + et131x_tx_dma_memory_free( adapter ); + et131x_rx_dma_memory_free( adapter ); + break; + } + } while( 0 ); + + + DBG_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_adapter_memory_free + ****************************************************************************** + + DESCRIPTION : Free all memory allocated for use by Tx & Rx code + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_adapter_memory_free( ET131X_ADAPTER *adapter ) +{ + DBG_FUNC( "et131x_adapter_memory_free" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Free DMA memory + *************************************************************************/ + et131x_tx_dma_memory_free( adapter ); + et131x_rx_dma_memory_free( adapter ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_register + ****************************************************************************** + + DESCRIPTION : This function uses the above data to regsiter the PCI + function table and PCI Vendor/Product ID(s) with the PCI + subsystem to match corresponding devices to this driver. + + PARAMETERS : N/A + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_pci_register( void ) +{ + int result; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_register" ); + DBG_ENTER( et131x_dbginfo ); + + + result = pci_register_driver( &et131x_driver ); + DBG_TRACE( et131x_dbginfo, + " pci_register_driver( ) returns %d \n", + result ); + + + DBG_LEAVE( et131x_dbginfo ); + return result; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_cleanup + ****************************************************************************** + + DESCRIPTION : This function deregisters the PCI function table and + related PCI Vendor/Product ID(s) with the PCI subsytem. + + PARAMETERS : N/A + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_pci_unregister( void ) +{ + DBG_FUNC( "et131x_pci_unregister" ); + DBG_ENTER( et131x_dbginfo ); + + + pci_unregister_driver( &et131x_driver ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_probe + ****************************************************************************** + + DESCRIPTION : Registered in the pci_driver structure, this function is + called when the PCI subsystem finds a new PCI device + which matches the information contained in the + pci_device_id table. This routine is the equivalent to + a device insertion routine. + + PARAMETERS : pdev - a pointer to the device's pci_dev structure + ent - this device's entry in the pci_device_id table + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int __devinit et131x_pci_probe( struct pci_dev *pdev, + const struct pci_device_id *ent ) +{ + int result; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_probe" ); + DBG_ENTER( et131x_dbginfo ); + + + result = et131x_pci_setup( pdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_remove + ****************************************************************************** + + DESCRIPTION : Registered in the pci_driver structure, this function is + called when the PCI subsystem detects that a PCI device + which matches the information contained in the + pci_device_id table has been removed. + + PARAMETERS : pdev - a pointer to the device's pci_dev structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void __devexit et131x_pci_remove( struct pci_dev *pdev ) +{ + struct net_device *netdev = NULL; + ET131X_ADAPTER *adapter = NULL; + BOOL_t bar_workaround; + unsigned long bar_addr_orig = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_remove" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Make sure the pci_dev pointer is valid + *************************************************************************/ + if( pdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "PCI subsys passed in an invalid pci_dev pointer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + + + /************************************************************************** + Retrieve the net_device pointer from the pci_dev struct, as well as the + private adapter struct + *************************************************************************/ + netdev = (struct net_device *)pci_get_drvdata( pdev ); + if( netdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "Could not retrieve net_device struct\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + + adapter = netdev_priv( netdev ); + if( adapter == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "Could not retrieve private adapter struct\n" ); + DBG_LEAVE( et131x_dbginfo ); + return; + } + + + /************************************************************************** + Retrieve config space workaround info before deleting the private + adapter struct + *************************************************************************/ + bar_workaround = adapter->pci_bar_workaround; + bar_addr_orig = adapter->pci_bar_addr_orig; + + + /************************************************************************** + Perform device cleanup + *************************************************************************/ + unregister_netdev( netdev ); + et131x_adapter_memory_free( adapter ); + iounmap( (void *)adapter->CSRAddress ); + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_pci_setup + ****************************************************************************** + + DESCRIPTION : Called by et131x_pci_probe() to perform device + initialization. + + PARAMETERS : pdev - a pointer to the device's pci_dev structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_pci_setup( struct pci_dev *pdev ) +{ + int result = 0; + int pm_cap; + BOOL_t pci_using_dac; + unsigned long et131x_reg_base; + unsigned long et131x_reg_len; + struct net_device *netdev = NULL; + ET131X_ADAPTER *adapter = NULL; + BOOL_t bar_workaround = FALSE; + unsigned long bar_addr_orig = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_pci_setup" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Make sure the device pointer is valid + *************************************************************************/ + if( pdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, + "PCI subsys passed in an invalid pci_dev pointer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + + /************************************************************************** + On some systems, the base address for a PCI device's config space which + is stored in the pci_dev structure is incorrect and different from + what's actually in the config space. If they're different, workaround + the issue by correcting the address. + *************************************************************************/ + pci_read_config_dword( pdev, PCI_BASE_ADDRESS_0, (u32 *)&et131x_reg_base ); + et131x_reg_base &= ~0x07; + + if( (u32)pdev->resource[0].start != (u32)et131x_reg_base ) + { + DBG_WARNING( et131x_dbginfo, "PCI CONFIG SPACE WORKAROUND REQUIRED\n" ); + DBG_WARNING( et131x_dbginfo, "pdev->resource[0].start : 0x%08x\n", + (unsigned int)pdev->resource[0].start ); + DBG_WARNING( et131x_dbginfo, "et131x_reg_base : 0x%08x\n", + (unsigned int)et131x_reg_base ); + bar_workaround = TRUE; + bar_addr_orig = pdev->resource[0].start; + pdev->resource[0].start = et131x_reg_base; + } + + + /************************************************************************** + Enable the device via the PCI subsystem + *************************************************************************/ + result = pci_enable_device( pdev ); + if( result != 0 ) + { + if( bar_workaround ) + { + pdev->resource[0].start = bar_addr_orig; + } + + DBG_ERROR( et131x_dbginfo, "pci_enable_device() failed\n" ); + DBG_LEAVE( et131x_dbginfo ); + return result; + } + + + /************************************************************************** + Perform some basic PCI checks + *************************************************************************/ + if( !( pci_resource_flags( pdev, 0 ) & IORESOURCE_MEM )) + { + if( bar_workaround ) + { + pdev->resource[0].start = bar_addr_orig; + } + + DBG_ERROR( et131x_dbginfo, + "Can't find PCI device's base address\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENODEV; + } + + if( bar_workaround == FALSE ) + { + result = pci_request_regions( pdev, DRIVER_NAME ); + if( result != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Can't get PCI resources\n" ); + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return result; + } + } + + + /************************************************************************** + Enable PCI bus mastering + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setting PCI Bus Mastering...\n" ); + pci_set_master( pdev ); + + + /************************************************************************** + Query PCI for Power Mgmt Capabilities + + NOTE: Now reading PowerMgmt in another location; is this still needed? + *************************************************************************/ + pm_cap = pci_find_capability( pdev, PCI_CAP_ID_PM ); + if( pm_cap == 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Cannot find Power Management capabilities\n" ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Check the DMA addressing support of this device + *************************************************************************/ + if( !pci_set_dma_mask( pdev, 0xffffffffffffffffULL )) + { + DBG_TRACE( et131x_dbginfo, + "64-bit DMA addressing supported\n" ); + pci_using_dac = TRUE; + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,0 )) + result = pci_set_consistent_dma_mask( pdev, 0xffffffffffffffffULL ); + if( result != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Unable to obtain 64 bit DMA for consistent allocations\n" ); + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } +#endif + } + else if( !pci_set_dma_mask( pdev, 0xffffffffULL )) + { + DBG_TRACE( et131x_dbginfo, + "64-bit DMA addressing NOT supported\n" ); + DBG_TRACE( et131x_dbginfo, + "32-bit DMA addressing will be used\n" ); + pci_using_dac = FALSE; + } + else + { + DBG_ERROR( et131x_dbginfo, "No usable DMA addressing method\n" ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Allocate netdev and private adapter structs + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Allocate netdev and private adapter structs...\n" ); + netdev = et131x_device_alloc( ); + + if( netdev == NULL ) + { + DBG_ERROR( et131x_dbginfo, "Couldn't alloc netdev struct\n" ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Setup the fundamental net_device and private adapter structure elements + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setting fundamental net_device info...\n" ); + + #if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + SET_MODULE_OWNER( netdev ); + #endif + #if ( LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20)) + SET_NETDEV_DEV( netdev, &pdev->dev ); + #endif + if( pci_using_dac ) + { + //netdev->features |= NETIF_F_HIGHDMA; + } + + + /************************************************************************** + NOTE - Turn this on when we're ready to deal with SG-DMA + + NOTE: According to "Linux Device Drivers", 3rd ed, Rubini et al, if + checksumming is not performed in HW, then the kernel will not use SG. + From pp 510-511: + + "Note that the kernel does not perform scatter/gather I/O to your device + if it does not also provide some form of checksumming as well. The + reason is that, if the kernel has to make a pass over a fragmented + ("nonlinear") packet to calculate the checksum, it might as well copy + the data and coalesce the packet at the same time." + + This has been verified by setting the flags below and still not + receiving a scattered buffer from the network stack, so leave it off + until checksums are calculated in HW. + *************************************************************************/ + //netdev->features |= NETIF_F_SG; + //netdev->features |= NETIF_F_NO_CSUM; + +#if ( LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,0 )) + //netdev->features |= NETIF_F_LLTX; +#endif + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + /************************************************************************** + The ET1310 does not perform VLAN tagging in hardware, so these flags are + not set. + *************************************************************************/ + /* + netdev->features |= NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; + */ +#endif + + /************************************************************************** + Allocate private adapter struct and copy in relevant information + *************************************************************************/ + adapter = netdev_priv( netdev ); + adapter->pdev = pdev; + adapter->netdev = netdev; + adapter->VendorID = pdev->vendor; + adapter->DeviceID = pdev->device; + + adapter->pci_bar_workaround = bar_workaround; + adapter->pci_bar_addr_orig = bar_addr_orig; + + + /************************************************************************** + Do the same for the netdev struct + *************************************************************************/ + netdev->irq = pdev->irq; + netdev->base_addr = pdev->resource[0].start; + + + /************************************************************************** + Initialize spinlocks here + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Initialize spinlocks...\n" ); + + spin_lock_init( &adapter->Lock ); + spin_lock_init( &adapter->TCBSendQLock ); + spin_lock_init( &adapter->TCBReadyQLock ); + spin_lock_init( &adapter->SendHWLock ); + spin_lock_init( &adapter->SendWaitLock ); + spin_lock_init( &adapter->RcvLock ); + spin_lock_init( &adapter->RcvPendLock ); + spin_lock_init( &adapter->FbrLock ); + spin_lock_init( &adapter->PHYLock ); + + + /************************************************************************** + Parse configuration parameters into the private adapter struct + *************************************************************************/ + et131x_config_parse( adapter ); + + + /************************************************************************** + Find the physical adapter + + NOTE: This is the equivalent of the MpFindAdapter() routine; can we + lump it's init with the device specific init below into a single + init function? + *************************************************************************/ + //while(et131x_find_adapter( adapter, pdev ) != 0); + et131x_find_adapter( adapter, pdev ); + + /************************************************************************** + Map the bus-relative registers to system virtual memory + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Mapping bus-relative registers to virtual memory...\n" ); + + if( bar_workaround == FALSE ) + { + et131x_reg_base = pci_resource_start( pdev, 0 ); + et131x_reg_len = pci_resource_len( pdev, 0 ); + } + else + { + et131x_reg_len = 0x00200000; + } + + adapter->CSRAddress = (ADDRESS_MAP_t *)ioremap_nocache( et131x_reg_base, + et131x_reg_len ); + if( adapter->CSRAddress == NULL ) + { + DBG_ERROR( et131x_dbginfo, "Cannot map device registers\n" ); + + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Perform device-specific initialization here (See code below) + *************************************************************************/ + + /************************************************************************** + If Phy COMA mode was enabled when we went down, disable it here. + *************************************************************************/ + { + PM_CSR_t GlobalPmCSR = {0}; + + GlobalPmCSR.bits.pm_sysclk_gate = 1; + GlobalPmCSR.bits.pm_txclk_gate = 1; + GlobalPmCSR.bits.pm_rxclk_gate = 1; + + adapter->CSRAddress->global.pm_csr = GlobalPmCSR; + } + + + /************************************************************************** + Issue a global reset to the et1310 + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Issuing soft reset...\n" ); + et131x_soft_reset( adapter ); + + + /************************************************************************** + Disable all interrupts (paranoid) + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Disable device interrupts...\n" ); + et131x_disable_interrupts( adapter ); + + + /************************************************************************** + Allocate DMA memory + *************************************************************************/ + result = et131x_adapter_memory_alloc( adapter ); + if( result != 0 ) + { + DBG_ERROR( et131x_dbginfo, + "Could not alloc adapater memory (DMA)\n" ); + + iounmap( (void *)adapter->CSRAddress ); + + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Init send data structures + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Init send data structures...\n" ); + et131x_init_send( adapter ); + + adapter->PoMgmt.PowerState = NdisDeviceStateD0; + + + /************************************************************************** + Register the interrupt + + NOTE - This is being done in the open routine, where most other Linux + drivers setup IRQ handlers. Make sure device interrupts are not + turned on before the IRQ is registered!!!! + + What we will do here is setup the task structure for the ISR's + deferred handler + *************************************************************************/ +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + adapter->task.routine = (void (*)(void *))et131x_isr_handler; + adapter->task.data = adapter; +#else + INIT_WORK( &adapter->task, et131x_isr_handler ); +#endif + + + /************************************************************************** + Determine MAC Address, and copy into the net_device struct + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Retrieve MAC address...\n" ); + et131x_setup_hardware_properties( adapter ); + + memcpy( netdev->dev_addr, adapter->CurrentAddress, ETH_ALEN ); + + + /************************************************************************** + Setup up our lookup table for CRC Calculations + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setup CRC lookup table...\n" ); + et131x_init_enet_crc_calc( ); + + + /************************************************************************** + Setup et1310 as per the documentation + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Setup the adapter...\n" ); + et131x_adapter_setup( adapter ); + + + /************************************************************************** + Create a timer to count errors received by the NIC + *************************************************************************/ + init_timer( &adapter->ErrorTimer ); + + adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; + adapter->ErrorTimer.function = et131x_error_timer_handler; + adapter->ErrorTimer.data = (unsigned long)adapter; + + + /************************************************************************** + Initialize link state + *************************************************************************/ + et131x_link_detection_handler( (unsigned long)adapter ); + + + /************************************************************************** + Intialize variable for counting how long we do not have link status + *************************************************************************/ + adapter->PoMgmt.TransPhyComaModeOnBoot = 0; + + + /************************************************************************** + We can enable interrupts now + + NOTE - Because registration of interrupt handler is done in the device's + open(), defer enabling device interrupts to that point + *************************************************************************/ + + + /************************************************************************** + Register the net_device struct with the Linux network layer + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, "Registering net_device...\n" ); + + + if(( result = register_netdev( netdev )) != 0 ) + { + DBG_ERROR( et131x_dbginfo, "register_netdev() failed\n" ); + + et131x_adapter_memory_free( adapter ); + + iounmap( (void *)adapter->CSRAddress ); + + et131x_device_free( netdev ); + + if( bar_workaround == FALSE ) + { + pci_release_regions( pdev ); + } + else + { + pdev->resource[0].start = bar_addr_orig; + } + + pci_disable_device( pdev ); + + DBG_LEAVE( et131x_dbginfo ); + return result; + } + + + /************************************************************************** + Register the net_device struct with the PCI subsystem. Save a copy + of the PCI config space for this device now that the device has been + initialized, just in case it needs to be quickly restored. + *************************************************************************/ + pci_set_drvdata( pdev, netdev ); + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,10 )) + pci_save_state( adapter->pdev, adapter->pci_cfg_state); +#else + pci_save_state( adapter->pdev ); +#endif + + + /************************************************************************** + Print out some information about this device + *************************************************************************/ + DBG_TRACE( et131x_dbginfo, + "DEVICE FOUND\n" ); + DBG_TRACE( et131x_dbginfo, + "------------------------------\n" ); + DBG_TRACE( et131x_dbginfo, + "Device Vendor ID : 0x%04x\n", + pdev->vendor ); + DBG_TRACE( et131x_dbginfo, + "Device Product ID : 0x%04x\n", + pdev->device ); + DBG_TRACE( et131x_dbginfo, + "Device SubVendor ID : 0x%04x\n", + pdev->subsystem_vendor ); + DBG_TRACE( et131x_dbginfo, + "Device SubProduct ID : 0x%04x\n", + pdev->subsystem_device ); + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) + DBG_TRACE( et131x_dbginfo, + "Device Name : %s\n", + pdev->name ); +#endif + + DBG_TRACE( et131x_dbginfo, + "Device on Bus # : %d\n", + pdev->bus->number ); + DBG_TRACE( et131x_dbginfo, + " Bus Name : %s\n", + pdev->bus->name ); + DBG_TRACE( et131x_dbginfo, + "Device in Slot # : %d\n", + PCI_SLOT( pdev->devfn )); + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,11 )) + DBG_TRACE( et131x_dbginfo, + " Slot Name : %s\n", + pdev->slot_name ); +#endif + + DBG_TRACE( et131x_dbginfo, + "Device Base Address : 0x%#03lx\n", + netdev->base_addr ); + DBG_TRACE( et131x_dbginfo, + "Device IRQ : %d\n", + netdev->irq ); + DBG_TRACE( et131x_dbginfo, + "Device MAC Address : %02x:%02x:%02x:%02x:%02x:%02x\n", + adapter->CurrentAddress[0], adapter->CurrentAddress[1], + adapter->CurrentAddress[2], adapter->CurrentAddress[3], + adapter->CurrentAddress[4], adapter->CurrentAddress[5] ); + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_tx.c +++ linux-2.6.28/ubuntu/et131x/ET1310_tx.c @@ -0,0 +1,2084 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_tx.c - Routines used to perform data transmission. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2006/01/20 21:29:44 $ + $Revision: 1.24 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#include +#endif + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" +#include "et131x_isr.h" + +#include "ET1310_tx.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + Prototypes for functions local to this module + *****************************************************************************/ +void et131x_update_tcb_list( ET131X_ADAPTER *pAdapter ); +void et131x_check_send_wait_list( ET131X_ADAPTER *pAdapter ); +__inline void et131x_free_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ); + +int et131x_send_packet( struct sk_buff *skb, ET131X_ADAPTER *pAdapter ); +int nic_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ); + + + + +/****************************************************************************** + ROUTINE : et131x_tx_dma_memory_alloc + ****************************************************************************** + + DESCRIPTION : Allocates memory that will be visible both to the device + and to the CPU. The OS will pass us packets, pointers to + which we will insert in the Tx Descriptor queue. The + device will read this queue to find the packets in + memory. The device will update the "status" in memory + each time it xmits a packet. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +int et131x_tx_dma_memory_alloc( ET131X_ADAPTER *adapter ) +{ + int desc_size = 0; + TX_RING_t *tx_ring; + MP_TCB *tcb; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_dma_memory_alloc" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Allocate memory for the TCB's (Transmit Control Block) + *************************************************************************/ + adapter->TxRing.MpTcbMem = kmalloc( NUM_TCB * sizeof( MP_TCB ), + GFP_ATOMIC | GFP_DMA ); + if( !adapter->TxRing.MpTcbMem ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for TCBs\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + memset( adapter->TxRing.MpTcbMem, 0, ( NUM_TCB * sizeof( MP_TCB ))); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + tx_ring = (TX_RING_t *)&adapter->TxRing; + tcb = (MP_TCB *)adapter->TxRing.MpTcbMem; + + + /************************************************************************** + Allocate enough memory for the Tx descriptor ring, and allocate some + extra so that the ring can be aligned on a 4k boundary. + *************************************************************************/ + desc_size = ( sizeof( TX_DESC_ENTRY_t ) * NUM_DESC_PER_RING_TX ) + 4096 - 1; + tx_ring->pTxDescRingVa = (PTX_DESC_ENTRY_t)pci_alloc_consistent( adapter->pdev, + desc_size, + &tx_ring->pTxDescRingPa ); + if( !adapter->TxRing.pTxDescRingVa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Tx Ring\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Save physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + tx_ring->pTxDescRingAdjustedPa = tx_ring->pTxDescRingPa; + + + /************************************************************************** + Align Tx Descriptor Ring on a 4k (0x1000) byte boundary + *************************************************************************/ + et131x_align_allocated_memory( adapter, + &tx_ring->pTxDescRingAdjustedPa, + &tx_ring->TxDescOffset, + 0x0FFF ); + + tx_ring->pTxDescRingVa += tx_ring->TxDescOffset; + + + /************************************************************************** + Allocate memory for the Tx status block + *************************************************************************/ + tx_ring->pTxStatusVa = pci_alloc_consistent( adapter->pdev, + sizeof( TX_STATUS_BLOCK_t ), + &tx_ring->pTxStatusPa ); + if( !adapter->TxRing.pTxStatusPa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Tx status block\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + /************************************************************************** + Allocate memory for a dummy buffer + *************************************************************************/ + tx_ring->pTxDummyBlkVa = pci_alloc_consistent( adapter->pdev, + NIC_MIN_PACKET_SIZE, + &tx_ring->pTxDummyBlkPa ); + if( !adapter->TxRing.pTxDummyBlkPa ) + { + DBG_ERROR( et131x_dbginfo, "Cannot alloc memory for Tx dummy buffer\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + + DBG_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_tx_dma_memory_free + ****************************************************************************** + + DESCRIPTION : Free all memory allocated within this module + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : 0 on success + errno on failure (as defined in errno.h) + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_tx_dma_memory_free( ET131X_ADAPTER *adapter ) +{ + int desc_size = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_dma_memory_free" ); + DBG_ENTER( et131x_dbginfo ); + + + if( adapter->TxRing.pTxDescRingVa ) + { + /********************************************************************** + Free memory relating to Tx rings here + *********************************************************************/ + adapter->TxRing.pTxDescRingVa -= adapter->TxRing.TxDescOffset; + + desc_size = ( sizeof( TX_DESC_ENTRY_t ) * NUM_DESC_PER_RING_TX ) + 4096 - 1; + + pci_free_consistent( adapter->pdev, + desc_size, + adapter->TxRing.pTxDescRingVa, + adapter->TxRing.pTxDescRingPa ); + + adapter->TxRing.pTxDescRingVa = NULL ; + } + + + /************************************************************************** + Free memory for the Tx status block + *************************************************************************/ + if( adapter->TxRing.pTxStatusVa ) + { + pci_free_consistent( adapter->pdev, + sizeof( TX_STATUS_BLOCK_t ), + adapter->TxRing.pTxStatusVa, + adapter->TxRing.pTxStatusPa ); + + adapter->TxRing.pTxStatusVa = NULL ; + } + + + /************************************************************************** + Free memory for the dummy buffer + *************************************************************************/ + if( adapter->TxRing.pTxDummyBlkVa ) + { + pci_free_consistent( adapter->pdev, + NIC_MIN_PACKET_SIZE, + adapter->TxRing.pTxDummyBlkVa, + adapter->TxRing.pTxDummyBlkPa ); + + adapter->TxRing.pTxDummyBlkVa = NULL ; + } + + + /************************************************************************** + Free the memory for MP_TCB structures + *************************************************************************/ + if( adapter->TxRing.MpTcbMem ) + { + kfree( adapter->TxRing.MpTcbMem ); + adapter->TxRing.MpTcbMem = NULL; + } + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : ConfigTxDmaRegs + ****************************************************************************** + + DESCRIPTION : Used to set up the tx dma section of the JAGCore. + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void ConfigTxDmaRegs( ET131X_ADAPTER *pAdapter ) +{ + PTXDMA_t pTxDma; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigTxDmaRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + First lets get a copy of the pointer + *************************************************************************/ + pTxDma = &pAdapter->CSRAddress->txdma; + + + /************************************************************************** + Load the hardware with the start of the transmit descriptor ring. + *************************************************************************/ + pTxDma->pr_base_hi.addr_hi = + (UINT32)( pAdapter->TxRing.pTxDescRingAdjustedPa >> 32 ); + pTxDma->pr_base_lo.addr_lo = + (UINT32)( pAdapter->TxRing.pTxDescRingAdjustedPa ); + + + /************************************************************************** + Initialise the transmit DMA engine + *************************************************************************/ + pTxDma->pr_num_des.value = NUM_DESC_PER_RING_TX - 1; + + + /************************************************************************** + Load the completion writeback physical address + + NOTE : pci_alloc_consistent(), used above to alloc DMA regions, ALWAYS + returns SAC (32-bit) addresses. If DAC (64-bit) addresses are + ever returned, make sure the high part is retrieved here before + storing the adjusted address. + *************************************************************************/ + pTxDma->dma_wb_base_hi.addr_hi = 0x0; + pTxDma->dma_wb_base_lo.addr_lo = pAdapter->TxRing.pTxStatusPa; + + memset( pAdapter->TxRing.pTxStatusVa, 0, sizeof( TX_STATUS_BLOCK_t )); + + + pTxDma->service_request.value = 0x0; + pAdapter->TxRing.txDmaReadyToSend.value = 0x0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_tx_dma_disable + ****************************************************************************** + DESCRIPTION: + Stop OF Tx_DMA on the ET1310 + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + N/A + + *****************************************************************************/ +void et131x_tx_dma_disable( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_tx_dma_disable" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup the tramsmit dma configuration register + *************************************************************************/ + pAdapter->CSRAddress->txdma.csr.value = 0x101; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_tx_dma_enable + ****************************************************************************** + DESCRIPTION: + re-start OF Tx_DMA on the ET1310. Mainly used after a return to the + D0 (full-power) state from a lower state. + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + N/A + + *****************************************************************************/ +void et131x_tx_dma_enable( ET131X_ADAPTER *pAdapter ) +{ + TXDMA_CSR_t csr = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_tx_dma_enable" ); + DBG_ENTER( et131x_dbginfo ); + + + if( pAdapter->RegistryPhyLoopbk ) + { + /********************************************************************** + TxDMA is disabled for loopback operation. + *********************************************************************/ + pAdapter->CSRAddress->txdma.csr.value = 0x101; + + } + else + { + /********************************************************************** + Setup the transmit dma configuration register for normal operation + *********************************************************************/ + csr.bits.sngl_epkt_mode = 1; + csr.bits.halt = 0; + csr.bits.cache_thrshld = pAdapter->RegistryDMACache; + + pAdapter->CSRAddress->txdma.csr.value = csr.value; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : et131x_init_send + ****************************************************************************** + + DESCRIPTION : Initialize send data structures + + PARAMETERS : adapter - pointer to our private adapter structure + + RETURNS : N/A + + REUSE INFORMATION : + + *****************************************************************************/ +void et131x_init_send( ET131X_ADAPTER *adapter ) +{ + PMP_TCB pMpTcb; + UINT32 TcbCount; + TX_RING_t *tx_ring; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_init_send" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Setup some convenience pointers + *************************************************************************/ + tx_ring = (TX_RING_t *)&adapter->TxRing; + pMpTcb = (PMP_TCB)adapter->TxRing.MpTcbMem; + + + tx_ring->TCBReadyQueueHead = pMpTcb; + + + /************************************************************************** + Go through and set up each TCB + *************************************************************************/ + for( TcbCount = 0; TcbCount < NUM_TCB; TcbCount++ ) + { + memset( pMpTcb, 0, sizeof( MP_TCB )); + + + /********************************************************************** + Set the link pointer in HW TCB to the next TCB in the chain. If + this is the last TCB in the chain, also set the tail pointer. + *********************************************************************/ + if( TcbCount < NUM_TCB - 1 ) + { + pMpTcb->Next = pMpTcb + 1; + } + else + { + tx_ring->TCBReadyQueueTail = pMpTcb; + pMpTcb->Next = (PMP_TCB)NULL; + } + + pMpTcb++; + } + + /************************************************************************** + Curr send queue should now be empty + *************************************************************************/ + tx_ring->CurrSendHead = (PMP_TCB)NULL; + tx_ring->CurrSendTail = (PMP_TCB)NULL; + + INIT_LIST_HEAD( &adapter->TxRing.SendWaitQueue ); + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_send_packets + ****************************************************************************** + + DESCRIPTION: + This function is called by the OS to send packets + + PARAMETERS : + skb - the packet(s) to send + netdev - the net_device struct corresponding to the device on which to + TX the above packet(s) + + RETURN : + 0 in almost all cases + non-zero value in extreme hard failure only + + *****************************************************************************/ +int et131x_send_packets( struct sk_buff *skb, struct net_device *netdev ) +{ + int status = 0; + ET131X_ADAPTER *pAdapter = NULL; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_send_packets" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + pAdapter = netdev_priv( netdev ); + + + /************************************************************************** + Send these packets + + NOTE: The Linux Tx entry point is only given one packet at a time + to Tx, so the PacketCount and it's array used makes no sense here + *************************************************************************/ + + /************************************************************************** + Queue is not empty or TCB is not available + *************************************************************************/ + if( !list_empty( &pAdapter->TxRing.SendWaitQueue ) || + MP_TCB_RESOURCES_NOT_AVAILABLE( pAdapter )) + { + /********************************************************************** + NOTE - If there's an error on send, no need to queue the + packet under Linux; if we just send an error up to the netif + layer, it will resend the skb to us. + *********************************************************************/ + DBG_VERBOSE( et131x_dbginfo, + "TCB Resources Not Available\n" ); + status = -ENOMEM; + } + else + { + /********************************************************************** + We need to see if the link is up; if it's not, make the netif layer + think we're good and drop the packet + *********************************************************************/ + //if( MP_SHOULD_FAIL_SEND( pAdapter ) || pAdapter->DriverNoPhyAccess ) + if( MP_SHOULD_FAIL_SEND( pAdapter ) || pAdapter->DriverNoPhyAccess || + !netif_carrier_ok( netdev )) + { + DBG_VERBOSE( et131x_dbginfo, + "Can't Tx, Link is DOWN; drop the packet\n" ); + + dev_kfree_skb_any( skb ); + skb = NULL; + + pAdapter->net_stats.tx_dropped++; + } + else + { + status = et131x_send_packet( skb, pAdapter ); + + if( status == -ENOMEM ) + { + + /************************************************************** + NOTE - If there's an error on send, no need to queue the + packet under Linux; if we just send an error up to the netif + layer, it will resend the skb to us. + *************************************************************/ + DBG_WARNING( et131x_dbginfo, + "Resources problem, Queue tx packet\n" ); + } + else if( status != 0 ) + { + /************************************************************** + On any other error, make netif think we're OK and drop the + packet + *************************************************************/ + DBG_WARNING( et131x_dbginfo, + "General error, drop packet\n" ); + + dev_kfree_skb_any( skb ); + skb = NULL; + + pAdapter->net_stats.tx_dropped++; + } + } + } + + + DBG_TX_LEAVE( et131x_dbginfo ); + return status; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_send_packet + ****************************************************************************** + DESCRIPTION: + Do the work to send a packet + + Assumption: Send spinlock has been acquired + + PARAMETERS : + skb - the packet(s) to send + pAdapter - a pointer to the device's private adapter structure + + RETURN : + 0 in almost all cases + non-zero value in extreme hard failure only + + *****************************************************************************/ +int et131x_send_packet( struct sk_buff *skb, ET131X_ADAPTER *pAdapter ) +{ + int status = 0; + PMP_TCB pMpTcb = NULL; + PUINT16 pShBufVa; + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_send_packet" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Is our buffer scattered, or continuous? + *************************************************************************/ + if( skb_shinfo( skb )->nr_frags == 0 ) + { + DBG_TX( et131x_dbginfo, "Scattered buffer: NO\n" ); + } + else + { + DBG_TX( et131x_dbginfo, "Scattered buffer: YES, Num Frags: %d\n", + skb_shinfo( skb )->nr_frags ); + } + + + /************************************************************************** + All packets must have at least a MAC address and a protocol type + *************************************************************************/ + if( skb->len < ETH_HLEN ) + { + DBG_ERROR( et131x_dbginfo, "Packet size < ETH_HLEN (14 bytes)\n" ); + DBG_LEAVE( et131x_dbginfo ); + return -EIO; + } + + + /************************************************************************** + Is this packet VLAN tagged? If so, is it a tag previously registered? + If not, drop the packet + + NOTE - We need not worry about the above note for now, as VLAN is handled + by the linux kernel (for the most part). + *************************************************************************/ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) +#if defined __vlan_get_tag + { + unsigned short vlan_tag; + + if( __vlan_get_tag( skb, &vlan_tag ) == -EINVAL ) + { + DBG_TX( et131x_dbginfo, + "VLAN: No TX packet tag\n" ); + } + else + { + DBG_TX( et131x_dbginfo, + "VLAN: TX packet tag: %d\n", vlan_tag ); + } + } +#endif +#endif + + + /************************************************************************** + Get a TCB for this packet + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBReadyQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.TCBReadyQueueHead; + + if( pMpTcb == NULL ) + { + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + DBG_WARNING( et131x_dbginfo, "Can't obtain a TCB\n" ); + DBG_TX_LEAVE( et131x_dbginfo ); + return -ENOMEM; + } + + pAdapter->TxRing.TCBReadyQueueHead = pMpTcb->Next; + + if( pAdapter->TxRing.TCBReadyQueueHead == NULL ) + { + pAdapter->TxRing.TCBReadyQueueTail = NULL; + } + + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + pMpTcb->PacketLength = skb->len; + pMpTcb->Packet = skb; + + if(( skb->data != NULL ) && (( skb->len - skb->data_len ) >= 6 )) + { + pShBufVa = (PUINT16)skb->data; + + if(( pShBufVa [0] == 0xffff ) && + ( pShBufVa [1] == 0xffff ) && + ( pShBufVa [2] == 0xffff )) + { + MP_SET_FLAG( pMpTcb, fMP_DEST_BROAD ); + } + else if(( pShBufVa [0] & 0x3 ) == 0x0001 ) + { + MP_SET_FLAG( pMpTcb, fMP_DEST_MULTI ); + } + } + + pMpTcb->Next = NULL; + + + /************************************************************************** + Call the NIC specific send handler. + *************************************************************************/ + if( status == 0 ) + { + status = nic_send_packet( pAdapter, pMpTcb ); + } + + if( status != 0 ) + { + spin_lock_irqsave( &pAdapter->TCBReadyQLock, lockflags ); + + if( pAdapter->TxRing.TCBReadyQueueTail ) + { + pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb; + } + else + { + /****************************************************************** + Apparently ready Q is empty. + *****************************************************************/ + pAdapter->TxRing.TCBReadyQueueHead = pMpTcb; + } + + pAdapter->TxRing.TCBReadyQueueTail = pMpTcb; + + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + DBG_TX_LEAVE( et131x_dbginfo ); + return status ; + } + + DBG_ASSERT( pAdapter->TxRing.nBusySend <= NUM_TCB ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: nic_send_packet + ****************************************************************************** + DESCRIPTION: + NIC specific send handler. This version of the send routine is designed + for version B silicon. + + PARAMETERS : + pAdapter - pointer to our adapter + pMpTcb - pointer to MP_TCB + + RETURNS : + 0 or errno + + *****************************************************************************/ +int nic_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ) +{ + UINT32 loopIndex; + TX_DESC_ENTRY_t CurDesc[24]; + UINT32 FragmentNumber = 0; + UINT32 iThisCopy, iRemainder; + struct sk_buff *pPacket = pMpTcb->Packet; + UINT32 FragListCount = skb_shinfo( pPacket )->nr_frags + 1; + struct skb_frag_struct *pFragList = &skb_shinfo( pPacket )->frags[0]; + unsigned long lockflags1, lockflags2; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_send_packet" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Part of the optimizations of this send routine restrict us to + sending 24 fragments at a pass. In practice we should never see more + than 5 fragments. + + NOTE: The older version of this function (below) can handle any number + of fragments. If needed, we can call this function, although it is less + efficient. + *************************************************************************/ + if( FragListCount > 23 ) + { + DBG_TX_LEAVE( et131x_dbginfo ); + return -EIO; + } + + memset( CurDesc, 0, sizeof( TX_DESC_ENTRY_t ) * ( FragListCount + 1 )); + + for( loopIndex = 0; loopIndex < FragListCount; loopIndex++ ) + { + /********************************************************************** + If there is something in this element, lets get a descriptor from + the ring and get the necessary data + *********************************************************************/ + if( loopIndex == 0 ) + { + /****************************************************************** + If the fragments are smaller than a standard MTU, then map them + to a single descriptor in the Tx Desc ring. However, if they're + larger, as is possible with support for jumbo packets, then + split them each across 2 descriptors. + + This will work until we determine why the hardware doesn't seem + to like large fragments. + *****************************************************************/ + if(( pPacket->len - pPacket->data_len ) <= 1514 ) + { + DBG_TX( et131x_dbginfo, + "Got packet of length %d, " + "filling desc entry %d, " + "TCB: 0x%p\n", + ( pPacket->len - pPacket->data_len ), + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + pMpTcb ); + + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + pPacket->len - pPacket->data_len; + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_single() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_single() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + pPacket->len - pPacket->data_len, + PCI_DMA_TODEVICE ); + } + else + { + DBG_TX( et131x_dbginfo, + "Got packet of length %d, " + "filling desc entry %d, " + "TCB: 0x%p\n", + ( pPacket->len - pPacket->data_len ), + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + pMpTcb ); + + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + (( pPacket->len - pPacket->data_len ) / 2 ); + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_single() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_single() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + (( pPacket->len - pPacket->data_len ) / 2 ), + PCI_DMA_TODEVICE ); + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + (( pPacket->len - pPacket->data_len ) / 2 ); + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_single() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_single() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data + (( pPacket->len - pPacket->data_len ) / 2 ), + (( pPacket->len - pPacket->data_len ) / 2 ), + PCI_DMA_TODEVICE ); + } + } + else + { + DBG_TX( et131x_dbginfo, + "Got packet of length %d," + "filling desc entry %d\n" + "TCB: 0x%p\n", + pFragList[loopIndex].size, + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + pMpTcb ); + + CurDesc[FragmentNumber].DataBufferPtrHigh = 0; + + + CurDesc[FragmentNumber].word2.bits.length_in_bytes = + pFragList[loopIndex - 1].size; + + /****************************************************************** + NOTE - Here, the dma_addr_t returned from pci_map_page() is + implicitly cast as a UINT32. Although dma_addr_t can be 64-bit, + the address returned by pci_map_page() is always 32-bit + addressable (as defined by the pci/dma subsystem) + ******************************************************************/ + CurDesc[FragmentNumber++].DataBufferPtrLow = pci_map_page( pAdapter->pdev, + pFragList[loopIndex - 1].page, + pFragList[loopIndex - 1].page_offset, + pFragList[loopIndex - 1].size, + PCI_DMA_TODEVICE ); + } + } + + if( FragmentNumber == 0 ) + { + DBG_WARNING( et131x_dbginfo, "No. frags is 0\n" ); + return -EIO; + } + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + if( ++pAdapter->TxRing.TxPacketsSinceLastinterrupt == + pAdapter->RegistryTxNumBuffers ) + { + CurDesc[FragmentNumber - 1].word3.value = 0x5; + pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0; + } + else + { + CurDesc[FragmentNumber - 1].word3.value = 0x1; + } + } + else + { + CurDesc[FragmentNumber - 1].word3.value = 0x5; + } + + CurDesc[0].word3.bits.f = 1; + + pMpTcb->WrIndexStart = pAdapter->TxRing.txDmaReadyToSend; + + pMpTcb->PacketStaleCount = 0; + + spin_lock_irqsave( &pAdapter->SendHWLock, lockflags1 ); + + iThisCopy = NUM_DESC_PER_RING_TX - pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + + if( iThisCopy >= FragmentNumber ) + { + iRemainder = 0; + iThisCopy = FragmentNumber; + } + else + { + iRemainder = FragmentNumber - iThisCopy; + } + + memcpy( pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + CurDesc, + sizeof( TX_DESC_ENTRY_t ) * iThisCopy ); + + + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req += iThisCopy; + + if(( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req == 0 ) || + ( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req == NUM_DESC_PER_RING_TX)) + { + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ) + { + pAdapter->TxRing.txDmaReadyToSend.value = 0; + } + else + { + pAdapter->TxRing.txDmaReadyToSend.value = 0x400; + } + } + + if( iRemainder ) + { + memcpy( pAdapter->TxRing.pTxDescRingVa, + CurDesc + iThisCopy, + sizeof( TX_DESC_ENTRY_t ) * iRemainder ); + + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req += iRemainder; + } + + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req == 0 ) + { + if( pAdapter->TxRing.txDmaReadyToSend.value ) + { + pMpTcb->WrIndex.value = NUM_DESC_PER_RING_TX - 1; + } + else + { + pMpTcb->WrIndex.value = 0x400 | ( NUM_DESC_PER_RING_TX - 1 ); + } + } + else + { + pMpTcb->WrIndex.value = pAdapter->TxRing.txDmaReadyToSend.value - 1; + } + + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags2 ); + + if( pAdapter->TxRing.CurrSendTail ) + { + pAdapter->TxRing.CurrSendTail->Next = pMpTcb; + } + else + { + pAdapter->TxRing.CurrSendHead = pMpTcb; + } + + pAdapter->TxRing.CurrSendTail = pMpTcb; + + DBG_ASSERT( pMpTcb->Next == NULL ); + + pAdapter->TxRing.nBusySend++; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags2 ); + + + /************************************************************************** + Write the new write pointer back to the device. + *************************************************************************/ + pAdapter->CSRAddress->txdma.service_request.value = + pAdapter->TxRing.txDmaReadyToSend.value; + + + /************************************************************************** + For Gig only, we use Tx Interrupt coalescing. Enable the software + timer to wake us up if this packet isn't followed by N more. + *************************************************************************/ + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + pAdapter->CSRAddress->global.watchdog_timer = + pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO; + } + + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags1 ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ + + + + +/* NOTE - For now, keep this older version of NICSendPacket around for + reference, even though it's not used */ +#if 0 + +/****************************************************************************** + ROUTINE: NICSendPacket + ****************************************************************************** + DESCRIPTION: + NIC specific send handler. This version of the send routine is designed + for version A silicon. + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + pMpTcb - pointer to MP_TCB + pFragList - pointer to the frag list to be filled + + RETURNS : + 0 on succes, errno on failure + + *****************************************************************************/ +int nic_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ) +{ + UINT32 loopIndex, fragIndex, loopEnd; + UINT32 iSplitFirstElement = 0; + UINT32 SegmentSize = 0; + TX_DESC_ENTRY_t CurDesc; + TX_DESC_ENTRY_t *CurDescPostCopy = NULL; + UINT32 SlotsAvailable; + TXDMA_SERVICE_COMPLETE_t ServiceComplete = pAdapter->CSRAddress->txdma.NewServiceComplete; + unsigned int lockflags1, lockflags2; + struct sk_buff *pPacket = pMpTcb->Packet; + UINT32 FragListCount = skb_shinfo( pPacket )->nr_frags + 1; + struct skb_frag_struct *pFragList = &skb_shinfo( pPacket )->frags[0]; + PGLOBAL_t pGbl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "nic_send_packet" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Attempt to fix TWO hardware bugs: + 1) NEVER write an odd number of descriptors. + 2) If packet length is less than NIC_MIN_PACKET_SIZE, then pad the + packet to NIC_MIN_PACKET_SIZE bytes by adding a new last + descriptor IN HALF DUPLEX MODE ONLY + NOTE that (2) interacts with (1). If the packet is less than + NIC_MIN_PACKET_SIZE bytes then we will append a descriptor. Therefore + if it is even now, it will eventually end up odd, and so will need + adjusting. + + VLAN tags get involved since VLAN tags add another one or two + segments. + *************************************************************************/ + DBG_TX( et131x_dbginfo, + "pMpTcb->PacketLength: %d\n", pMpTcb->PacketLength ); + + if(( pAdapter->uiDuplexMode == 0 ) && ( pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE )) + { + DBG_TX( et131x_dbginfo, + "HALF DUPLEX mode AND len < MIN_PKT_SIZE\n" ); + if(( FragListCount & 0x1 ) == 0 ) + { + DBG_TX( et131x_dbginfo, + "Even number of descs, split 1st elem\n" ); + iSplitFirstElement = 1; + //SegmentSize = pFragList[0].size / 2; + SegmentSize = ( pPacket->len - pPacket->data_len ) / 2; + } + } + else if( FragListCount & 0x1 ) + { + DBG_TX( et131x_dbginfo, + "Odd number of descs, split 1st elem\n" ); + + iSplitFirstElement = 1; + //SegmentSize = pFragList[0].size / 2; + SegmentSize = ( pPacket->len - pPacket->data_len ) / 2; + } + + spin_lock_irqsave( &pAdapter->SendHWLock, lockflags1 ); + + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap == + ServiceComplete.bits.serv_cpl_wrap ) + { + /********************************************************************** + The ring hasn't wrapped. Slots available should be (RING_SIZE) - + the difference between the two pointers. + *********************************************************************/ + SlotsAvailable = NUM_DESC_PER_RING_TX - + ( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req - ServiceComplete.bits.serv_cpl); + } + else + { + /********************************************************************** + The ring has wrapped. Slots available should be the difference + between the two pointers. + *********************************************************************/ + SlotsAvailable = ServiceComplete.bits.serv_cpl - + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + } + + if(( FragListCount + iSplitFirstElement ) > SlotsAvailable ) + { + DBG_WARNING( et131x_dbginfo, "Not Enough Space in Tx Desc Ring\n" ); + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags1 ); + return -ENOMEM; + } + + loopEnd = ( FragListCount ) + iSplitFirstElement; + fragIndex = 0; + + DBG_TX( et131x_dbginfo, + "TCB : 0x%p\n", pMpTcb ); + DBG_TX( et131x_dbginfo, + "Packet (SKB) : 0x%p\t Packet->len: %d\t Packet->data_len: %d\n", + pPacket, pPacket->len, pPacket->data_len ); + + DBG_TX( et131x_dbginfo, + "FragListCount : %d\t iSplitFirstElement: %d\t loopEnd:%d\n", + FragListCount, iSplitFirstElement, loopEnd ); + + for( loopIndex = 0; loopIndex < loopEnd; loopIndex++ ) + { + if( loopIndex > iSplitFirstElement ) + { + fragIndex++; + } + + DBG_TX( et131x_dbginfo, "In loop, loopIndex: %d\t fragIndex: %d\n", + loopIndex, fragIndex ); + + + /********************************************************************** + If there is something in this element, let's get a descriptor from + the ring and get the necessary data + *********************************************************************/ + DBG_TX( et131x_dbginfo, + "Packet Length %d," + "filling desc entry %d\n", + pPacket->len, + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req ); + + // NOTE - Should we do a paranoia check here to make sure the fragment + // actually has a length? It's HIGHLY unlikely the fragment would + // contain no data... + if( 1 ) + { + // NOTE - Currently always getting 32-bit addrs, and dma_addr_t is + // only 32-bit, so leave "high" ptr value out for now + CurDesc.DataBufferPtrHigh = 0; + + CurDesc.word2.value = 0; + CurDesc.word3.value = 0; + + + if( fragIndex == 0 ) + { + if( iSplitFirstElement ) + { + DBG_TX( et131x_dbginfo, "Split first element: YES\n" ); + + if( loopIndex == 0 ) + { + DBG_TX( et131x_dbginfo, + "Got fragment of length %d, fragIndex: %d\n", + pPacket->len - pPacket->data_len, + fragIndex ); + DBG_TX( et131x_dbginfo, + "SegmentSize: %d\n", SegmentSize ); + + + CurDesc.word2.bits.length_in_bytes = SegmentSize; + CurDesc.DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + SegmentSize, + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_single() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + else + { + DBG_TX( et131x_dbginfo, + "Got fragment of length %d, fragIndex: %d\n", + pPacket->len - pPacket->data_len, + fragIndex ); + DBG_TX( et131x_dbginfo, + "Leftover Size: %d\n", + ( pPacket->len - pPacket->data_len - SegmentSize )); + + CurDesc.word2.bits.length_in_bytes = (( pPacket->len - pPacket->data_len ) - + SegmentSize ); + CurDesc.DataBufferPtrLow = pci_map_single( pAdapter->pdev, + ( pPacket->data + SegmentSize ), + ( pPacket->len - pPacket->data_len - + SegmentSize ), + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_single() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + } + else + { + DBG_TX( et131x_dbginfo, "Split first element: NO\n" ); + + CurDesc.word2.bits.length_in_bytes = pPacket->len - + pPacket->data_len; + + CurDesc.DataBufferPtrLow = pci_map_single( pAdapter->pdev, + pPacket->data, + ( pPacket->len - + pPacket->data_len ), + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_single() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + } + else + { + + CurDesc.word2.bits.length_in_bytes = pFragList[fragIndex - 1].size; + CurDesc.DataBufferPtrLow = pci_map_page( pAdapter->pdev, + pFragList[fragIndex - 1].page, + pFragList[fragIndex - 1].page_offset, + pFragList[fragIndex - 1].size, + PCI_DMA_TODEVICE ); + DBG_TX( et131x_dbginfo, "pci_map_page() returns: 0x%08x\n", + CurDesc.DataBufferPtrLow ); + } + + if( loopIndex == 0 ) + { + /************************************************************** + This is the first descriptor of the packet + *************************************************************/ + /************************************************************** + Set the "f" bit to indicate this is the first descriptor in + the packet. + *************************************************************/ + DBG_TX( et131x_dbginfo, "This is our FIRST descriptor\n" ); + CurDesc.word3.bits.f = 1; + + pMpTcb->WrIndexStart = pAdapter->TxRing.txDmaReadyToSend; + } + + if(( loopIndex == (loopEnd - 1 )) && + ( pAdapter->uiDuplexMode || + ( pMpTcb->PacketLength >= NIC_MIN_PACKET_SIZE ))) + { + /************************************************************** + This is the Last descriptor of the packet + *************************************************************/ + DBG_TX( et131x_dbginfo, "THIS is our LAST descriptor\n" ); + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + if( ++pAdapter->TxRing.TxPacketsSinceLastinterrupt >= pAdapter->RegistryTxNumBuffers ) + { + CurDesc.word3.value = 0x5; + pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0; + } + else + { + CurDesc.word3.value = 0x1; + } + } + else + { + CurDesc.word3.value = 0x5; + } + + + /************************************************************** + Following index will be used during freeing of packet + *************************************************************/ + pMpTcb->WrIndex = pAdapter->TxRing.txDmaReadyToSend; + pMpTcb->PacketStaleCount = 0; + } + + /****************************************************************** + Copy the descriptor (filled above) into the descriptor ring + at the next free entry. Advance the "next free entry" variable + *****************************************************************/ + memcpy( pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + &CurDesc, + sizeof( TX_DESC_ENTRY_t )); + + CurDescPostCopy = pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + + DBG_TX( et131x_dbginfo, "CURRENT DESCRIPTOR\n" ); + DBG_TX( et131x_dbginfo, "\tAddress : 0x%p\n", CurDescPostCopy ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrHigh : 0x%08x\n", CurDescPostCopy->DataBufferPtrHigh ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrLow : 0x%08x\n", CurDescPostCopy->DataBufferPtrLow ); + DBG_TX( et131x_dbginfo, "\tword2 : 0x%08x\n", CurDescPostCopy->word2.value ); + DBG_TX( et131x_dbginfo, "\tword3 : 0x%08x\n", CurDescPostCopy->word3.value ); + + + if( ++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >= NUM_DESC_PER_RING_TX ) + { + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ) + { + pAdapter->TxRing.txDmaReadyToSend.value = 0; + } + else + { + pAdapter->TxRing.txDmaReadyToSend.value = 0x400; + } + } + } + } + + + if(( pAdapter->uiDuplexMode == 0 ) && ( pMpTcb->PacketLength < NIC_MIN_PACKET_SIZE )) + { + // NOTE - Same 32/64-bit issue as above... + CurDesc.DataBufferPtrHigh = 0x0; + CurDesc.DataBufferPtrLow = pAdapter->TxRing.pTxDummyBlkPa; + CurDesc.word2.value = 0; + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + if( ++pAdapter->TxRing.TxPacketsSinceLastinterrupt >= pAdapter->RegistryTxNumBuffers ) + { + CurDesc.word3.value = 0x5; + pAdapter->TxRing.TxPacketsSinceLastinterrupt = 0; + } + else + { + CurDesc.word3.value = 0x1; + } + } + else + { + CurDesc.word3.value = 0x5; + } + + CurDesc.word2.bits.length_in_bytes = NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength; + + pMpTcb->WrIndex = pAdapter->TxRing.txDmaReadyToSend; + + memcpy( pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + &CurDesc, + sizeof( TX_DESC_ENTRY_t )); + + CurDescPostCopy = pAdapter->TxRing.pTxDescRingVa + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req; + + DBG_TX( et131x_dbginfo, "CURRENT DESCRIPTOR\n" ); + DBG_TX( et131x_dbginfo, "\tAddress : 0x%p\n", CurDescPostCopy ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrHigh : 0x%08x\n", CurDescPostCopy->DataBufferPtrHigh ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrLow : 0x%08x\n", CurDescPostCopy->DataBufferPtrLow ); + DBG_TX( et131x_dbginfo, "\tword2 : 0x%08x\n", CurDescPostCopy->word2.value ); + DBG_TX( et131x_dbginfo, "\tword3 : 0x%08x\n", CurDescPostCopy->word3.value ); + + + if( ++pAdapter->TxRing.txDmaReadyToSend.bits.serv_req >= NUM_DESC_PER_RING_TX ) + { + if( pAdapter->TxRing.txDmaReadyToSend.bits.serv_req_wrap ) + { + pAdapter->TxRing.txDmaReadyToSend.value = 0; + } + else + { + pAdapter->TxRing.txDmaReadyToSend.value = 0x400; + } + } + + DBG_TX( et131x_dbginfo, "Padding descriptor %d by %d bytes\n", + //pAdapter->TxRing.txDmaReadyToSend.value, + pAdapter->TxRing.txDmaReadyToSend.bits.serv_req, + NIC_MIN_PACKET_SIZE - pMpTcb->PacketLength ); + } + + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags2 ); + + if( pAdapter->TxRing.CurrSendTail ) + { + pAdapter->TxRing.CurrSendTail->Next = pMpTcb; + } + else + { + pAdapter->TxRing.CurrSendHead = pMpTcb; + } + + pAdapter->TxRing.CurrSendTail = pMpTcb; + + DBG_ASSERT( pMpTcb->Next == NULL ); + + pAdapter->TxRing.nBusySend++; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags2 ); + + + /************************************************************************** + Write the new write pointer back to the device. + *************************************************************************/ + pAdapter->CSRAddress->txdma.service_request.value = pAdapter->TxRing.txDmaReadyToSend.value; + +#if ( ET131X_DBG == 1 ) + DumpDeviceBlock( DBG_TX_ON, pAdapter, 1 ); +#endif + + + /************************************************************************** + Map a local pointer to the global section of the JAGCore + *************************************************************************/ + pGbl = &pAdapter->CSRAddress->global; + + + /************************************************************************** + For Gig only, we use Tx Interrupt coalescing. Enable the software + timer to wake us up if this packet isn't followed by N more. + *************************************************************************/ + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + pAdapter->CSRAddress->global.watchdog_timer = + pAdapter->RegistryTxTimeInterval * NANO_IN_A_MICRO; + } + + spin_unlock_irqrestore( &pAdapter->SendHWLock, lockflags1 ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return 0; +} +/*===========================================================================*/ +#endif + + + + +/****************************************************************************** + ROUTINE: et131x_free_send_packet + ****************************************************************************** + DESCRIPTION: + Recycle a MP_TCB and complete the packet if necessary + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + pMpTcb - pointer to MP_TCB + + RETURNS : + NONE + + *****************************************************************************/ +__inline void et131x_free_send_packet( ET131X_ADAPTER *pAdapter, PMP_TCB pMpTcb ) +{ + unsigned long lockflags; + TX_DESC_ENTRY_t *desc = NULL; + struct net_device_stats *stats = &pAdapter->net_stats; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_free_send_packet" ); + + + if( MP_TEST_FLAG( pMpTcb, fMP_DEST_BROAD ) ) + { + atomic_inc( &pAdapter->Stats.brdcstxmt ); + } + else if( MP_TEST_FLAG( pMpTcb, fMP_DEST_MULTI )) + { + atomic_inc( &pAdapter->Stats.multixmt ); + } + else + { + atomic_inc( &pAdapter->Stats.unixmt ); + } + + if( pMpTcb->Packet ) + { + stats->tx_bytes += pMpTcb->Packet->len; + + + /********************************************************************** + Iterate through the TX descriptors on the ring corresponding to this + packet and umap the fragments they point to + *********************************************************************/ + DBG_TX( et131x_dbginfo, "Unmap descriptors Here\n" ); + + DBG_TX( et131x_dbginfo, + "TCB : 0x%p\n", pMpTcb ); + + DBG_TX( et131x_dbginfo, + "TCB Next : 0x%p\n", pMpTcb->Next ); + + DBG_TX( et131x_dbginfo, + "TCB PacketLength : %d\n", pMpTcb->PacketLength ); + + DBG_TX( et131x_dbginfo, + "TCB WrIndex.value : 0x%08x\n", pMpTcb->WrIndexStart.value ); + DBG_TX( et131x_dbginfo, + "TCB WrIndex.serv_req : %d\n", pMpTcb->WrIndexStart.bits.serv_req ); + + DBG_TX( et131x_dbginfo, + "TCB WrIndex.value : 0x%08x\n", pMpTcb->WrIndex.value ); + DBG_TX( et131x_dbginfo, + "TCB WrIndex.serv_req : %d\n", pMpTcb->WrIndex.bits.serv_req ); + + do + { + desc = (TX_DESC_ENTRY_t *)( pAdapter->TxRing.pTxDescRingVa + + pMpTcb->WrIndexStart.bits.serv_req ); + + DBG_TX( et131x_dbginfo, "CURRENT DESCRIPTOR\n" ); + DBG_TX( et131x_dbginfo, "\tAddress : 0x%p\n", desc ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrHigh : 0x%08x\n", desc->DataBufferPtrHigh ); + DBG_TX( et131x_dbginfo, "\tDataBufferPtrLow : 0x%08x\n", desc->DataBufferPtrLow ); + DBG_TX( et131x_dbginfo, "\tword2 : 0x%08x\n", desc->word2.value ); + DBG_TX( et131x_dbginfo, "\tword3 : 0x%08x\n", desc->word3.value ); + + pci_unmap_single( pAdapter->pdev, + desc->DataBufferPtrLow, + desc->word2.value, + PCI_DMA_TODEVICE ); + + if( ++pMpTcb->WrIndexStart.bits.serv_req >= NUM_DESC_PER_RING_TX ) + { + if( pMpTcb->WrIndexStart.bits.serv_req_wrap ) + { + pMpTcb->WrIndexStart.value = 0; + } + else + { + pMpTcb->WrIndexStart.value = 0x400; + } + } + } + while( desc != ( pAdapter->TxRing.pTxDescRingVa + + pMpTcb->WrIndex.bits.serv_req )); + + DBG_TX( et131x_dbginfo, + "Free Packet (SKB) : 0x%p\n", pMpTcb->Packet ); + + dev_kfree_skb_any( pMpTcb->Packet ); + } + + memset( pMpTcb, 0, sizeof( MP_TCB )); + + + /************************************************************************** + Add the TCB to the Ready Q + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBReadyQLock, lockflags ); + + pAdapter->Stats.opackets++; + + if( pAdapter->TxRing.TCBReadyQueueTail ) + { + pAdapter->TxRing.TCBReadyQueueTail->Next = pMpTcb; + } + else + { + /********************************************************************** + Apparently ready Q is empty. + *********************************************************************/ + pAdapter->TxRing.TCBReadyQueueHead = pMpTcb; + } + + pAdapter->TxRing.TCBReadyQueueTail = pMpTcb; + + spin_unlock_irqrestore( &pAdapter->TCBReadyQLock, lockflags ); + + + DBG_ASSERT( pAdapter->TxRing.nBusySend >= 0 ); + + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_free_busy_send_packets + ****************************************************************************** + DESCRIPTION: + Free and complete the stopped active sends + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + NONE + + *****************************************************************************/ +void et131x_free_busy_send_packets( ET131X_ADAPTER *pAdapter ) +{ + PMP_TCB pMpTcb; + struct list_head *pEntry; + struct sk_buff *pPacket = NULL; + unsigned long lockflags; + UINT32 FreeCounter = 0; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_free_busy_send_packets" ); + DBG_ENTER( et131x_dbginfo ); + + + while( !list_empty( &pAdapter->TxRing.SendWaitQueue )) + { + spin_lock_irqsave( &pAdapter->SendWaitLock, lockflags ); + + pAdapter->TxRing.nWaitSend--; + spin_unlock_irqrestore( &pAdapter->SendWaitLock, lockflags ); + + pEntry = pAdapter->TxRing.SendWaitQueue.next; + + pPacket = NULL; + } + + pAdapter->TxRing.nWaitSend = 0; + + + /************************************************************************** + Any packets being sent? Check the first TCB on the send list + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + + while(( pMpTcb != NULL ) && ( FreeCounter < NUM_TCB )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + + DBG_VERBOSE( et131x_dbginfo, + "pMpTcb = 0x%p\n", + pMpTcb ); + + FreeCounter++; + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + + if( FreeCounter == NUM_TCB ) + { + DBG_ERROR( et131x_dbginfo, + "MpFreeBusySendPackets exitted loop for a bad reason\n" ); + BUG(); + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + + pAdapter->TxRing.nBusySend = 0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_handle_send_interrupt + ****************************************************************************** + DESCRIPTION: + Interrupt handler for sending processing + Re-claim the send resources, complete sends and get more to send from + the send wait queue + + Assumption: Send spinlock has been acquired + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_handle_send_interrupt( ET131X_ADAPTER *pAdapter ) +{ + DBG_FUNC( "et131x_handle_send_interrupt" ); + DBG_TX_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Mark as completed any packets which have been sent by the device. + *************************************************************************/ + et131x_update_tcb_list( pAdapter ); + + + /************************************************************************** + If we queued any transmits because we didn't have any TCBs earlier, + dequeue and send those packets now, as long as we have free TCBs. + *************************************************************************/ + et131x_check_send_wait_list( pAdapter ); + + + DBG_TX_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_update_tcb_list + ****************************************************************************** + DESCRIPTION: + Helper routine for Send Interrupt handler. Re-claims the send + resources and completes sends. Can also be called as part of the NIC + send routine when the "ServiceComplete" indication has wrapped. + + Assumption: + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_update_tcb_list( ET131X_ADAPTER *pAdapter ) +{ + unsigned long lockflags; + TXDMA_SERVICE_COMPLETE_t ServiceComplete = pAdapter->CSRAddress->txdma.NewServiceComplete; + PMP_TCB pMpTcb; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Has the ring wrapped? Process any descriptors that do not have + the same "wrap" indicator as the current completion indicator + *************************************************************************/ + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + pMpTcb = pAdapter->TxRing.CurrSendHead; + + if( ServiceComplete.bits.serv_cpl_wrap ) + { + while( pMpTcb && + !pMpTcb->WrIndex.bits.serv_req_wrap && + ( pMpTcb->WrIndex.bits.serv_req > ServiceComplete.bits.serv_cpl )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + + /****************************************************************** + Goto the next packet + *****************************************************************/ + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + } + else + { + while( pMpTcb && + pMpTcb->WrIndex.bits.serv_req_wrap && + ( pMpTcb->WrIndex.bits.serv_req > ServiceComplete.bits.serv_cpl )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + + /****************************************************************** + Goto the next packet + *****************************************************************/ + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + } + + while( pMpTcb && + ( ServiceComplete.bits.serv_cpl_wrap == pMpTcb->WrIndex.bits.serv_req_wrap ) && + ( ServiceComplete.bits.serv_cpl > pMpTcb->WrIndex.bits.serv_req )) + { + PMP_TCB pNext = pMpTcb->Next; + + pAdapter->TxRing.CurrSendHead = pNext; + + if( pNext == NULL ) + { + pAdapter->TxRing.CurrSendTail = NULL; + } + + pAdapter->TxRing.nBusySend--; + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + MP_FREE_SEND_PACKET_FUN( pAdapter, pMpTcb ); + spin_lock_irqsave( &pAdapter->TCBSendQLock, lockflags ); + + + /********************************************************************** + Goto the next packet + *********************************************************************/ + pMpTcb = pAdapter->TxRing.CurrSendHead; + } + + + /* Wake up the queue when we hit a low-water mark */ + if( pAdapter->TxRing.nBusySend <= ( NUM_TCB / 3 )) + { + netif_wake_queue( pAdapter->netdev ); + } + + spin_unlock_irqrestore( &pAdapter->TCBSendQLock, lockflags ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: et131x_check_send_wait_list + ****************************************************************************** + DESCRIPTION: + Helper routine for the interrupt handler. Takes packets from the send + wait queue and posts them to the device (if room available). + + Assumption: + + PARAMETERS : + pAdapter - pointer to our adapter + + RETURNS : + Nothing + + *****************************************************************************/ +void et131x_check_send_wait_list( ET131X_ADAPTER *pAdapter ) +{ + unsigned long lockflags; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "et131x_check_send_wait_list" ); + + + spin_lock_irqsave( &pAdapter->SendWaitLock, lockflags ); + + while( !list_empty( &pAdapter->TxRing.SendWaitQueue ) && + MP_TCB_RESOURCES_AVAILABLE( pAdapter )) + { + struct list_head *pEntry; + + DBG_VERBOSE( et131x_dbginfo, + "Tx packets on the wait queue\n" ); + + pEntry = pAdapter->TxRing.SendWaitQueue.next; + + pAdapter->TxRing.nWaitSend--; + + DBG_WARNING( et131x_dbginfo, + "MpHandleSendInterrupt - sent a queued pkt. Waiting %d\n", + pAdapter->TxRing.nWaitSend ); + } + + spin_unlock_irqrestore( &pAdapter->SendWaitLock, lockflags ); + + return; +} +/*===========================================================================*/ + --- linux-2.6.28.orig/ubuntu/et131x/BOM +++ linux-2.6.28/ubuntu/et131x/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://sourceforge.net/project/platformdownload.php?group_id=179406 +Current Version: 1.2.3-3 --- linux-2.6.28.orig/ubuntu/et131x/ET1310_tx.h +++ linux-2.6.28/ubuntu/et131x/ET1310_tx.h @@ -0,0 +1,354 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_tx.h - Defines, structs, enums, prototypes, etc. pertaining to data + * transmission. + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/07 21:26:45 $ + $Revision: 1.9 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +#ifndef __ET1310_TX_H__ +#define __ET1310_TX_H__ + +#ifdef __cplusplus +extern "C" { +#endif + + + + +/****************************************************************************** + Typedefs for Tx Descriptor Ring + *****************************************************************************/ +/****************************************************************************** + TXDESC_WORD2_t structure holds part of the control bits in the Tx Descriptor + ring for the ET-1310 + *****************************************************************************/ +typedef union _txdesc_word2_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 vlan_prio:3; //bits 29-31(VLAN priority) + UINT32 vlan_cfi:1; //bit 28(cfi) + UINT32 vlan_tag:12; //bits 16-27(VLAN tag) + UINT32 length_in_bytes:16; //bits 0-15(packet length) + #else + UINT32 length_in_bytes:16; //bits 0-15(packet length) + UINT32 vlan_tag:12; //bits 16-27(VLAN tag) + UINT32 vlan_cfi:1; //bit 28(cfi) + UINT32 vlan_prio:3; //bits 29-31(VLAN priority) + #endif /* _BIT_FIELDS_HTOL */ + } bits; +}TXDESC_WORD2_t, *PTXDESC_WORD2_t; + + + + +/****************************************************************************** + TXDESC_WORD3_t structure holds part of the control bits in the Tx Descriptor + ring for the ET-1310 + *****************************************************************************/ +typedef union _txdesc_word3_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:17; //bits 15-31 + UINT32 udpa:1; //bit 14(UDP checksum assist) + UINT32 tcpa:1; //bit 13(TCP checksum assist) + UINT32 ipa:1; //bit 12(IP checksum assist) + UINT32 vlan:1; //bit 11(append VLAN tag) + UINT32 hp:1; //bit 10(Packet is a Huge packet) + UINT32 pp:1; //bit 9(pad packet) + UINT32 mac:1; //bit 8(MAC override) + UINT32 crc:1; //bit 7(append CRC) + UINT32 e:1; //bit 6(Tx frame has error) + UINT32 pf:1; //bit 5(send pause frame) + UINT32 bp:1; //bit 4(Issue half-duplex backpressure (XON/XOFF) + UINT32 cw:1; //bit 3(Control word - no packet data) + UINT32 ir:1; //bit 2(interrupt the processor when this pkt sent) + UINT32 f:1; //bit 1(first packet in the sequence) + UINT32 l:1; //bit 0(last packet in the sequence) + #else + UINT32 l:1; //bit 0(last packet in the sequence) + UINT32 f:1; //bit 1(first packet in the sequence) + UINT32 ir:1; //bit 2(interrupt the processor when this pkt sent) + UINT32 cw:1; //bit 3(Control word - no packet data) + UINT32 bp:1; //bit 4(Issue half-duplex backpressure (XON/XOFF) + UINT32 pf:1; //bit 5(send pause frame) + UINT32 e:1; //bit 6(Tx frame has error) + UINT32 crc:1; //bit 7(append CRC) + UINT32 mac:1; //bit 8(MAC override) + UINT32 pp:1; //bit 9(pad packet) + UINT32 hp:1; //bit 10(Packet is a Huge packet) + UINT32 vlan:1; //bit 11(append VLAN tag) + UINT32 ipa:1; //bit 12(IP checksum assist) + UINT32 tcpa:1; //bit 13(TCP checksum assist) + UINT32 udpa:1; //bit 14(UDP checksum assist) + UINT32 unused:17; //bits 15-31 + #endif /* _BIT_FIELDS_HTOL */ + } bits; +}TXDESC_WORD3_t, *PTXDESC_WORD3_t; + + + + +/****************************************************************************** + TX_DESC_ENTRY_t is sructure representing each descriptor on the ring + *****************************************************************************/ +typedef struct _tx_desc_entry_t +{ + UINT32 DataBufferPtrHigh; + UINT32 DataBufferPtrLow; + TXDESC_WORD2_t word2; // control words how to xmit the + TXDESC_WORD3_t word3; // data (detailed above) +} +TX_DESC_ENTRY_t, *PTX_DESC_ENTRY_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + Typedefs for Tx DMA engine status writeback + *****************************************************************************/ +/****************************************************************************** + TX_STATUS_BLOCK_t is sructure representing the status of the Tx DMA engine + it sits in free memory, and is pointed to by 0x101c / 0x1020 + *****************************************************************************/ + +typedef union _tx_status_block_t +{ + UINT32 value; + struct + { + #ifdef _BIT_FIELDS_HTOL + UINT32 unused:21; //bits 11-31 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 serv_cpl:10; //bits 0-9 + #else + UINT32 serv_cpl:10; //bits 0-9 + UINT32 serv_cpl_wrap:1; //bit 10 + UINT32 unused:21; //bits 11-31 + #endif + } bits; +} +TX_STATUS_BLOCK_t, *PTX_STATUS_BLOCK_t; +/*===========================================================================*/ + + + + +/****************************************************************************** + TCB (Transmit Control Block) + *****************************************************************************/ +typedef struct _MP_TCB +{ + struct _MP_TCB *Next; + UINT32 Flags; + UINT32 Count; + UINT32 PacketStaleCount; + struct sk_buff *Packet; + UINT32 PacketLength; + TXDMA_SERVICE_REQUEST_t WrIndex; + TXDMA_SERVICE_REQUEST_t WrIndexStart; +} MP_TCB, *PMP_TCB; + + + + +/****************************************************************************** + Structure to hold the skb's in a list + *****************************************************************************/ +typedef struct tx_skb_list_elem +{ + struct list_head skb_list_elem; + struct sk_buff *skb; +} TX_SKB_LIST_ELEM, *PTX_SKB_LIST_ELEM; + + + + +/****************************************************************************** + TX_RING_t is sructure representing our local reference(s) to the ring + *****************************************************************************/ +typedef struct _tx_ring_t +{ + /************************************************************************** + TCB (Transmit Control Block) memory and lists + *************************************************************************/ + PUCHAR MpTcbMem; + + + /************************************************************************** + List of TCBs that are ready to be used + *************************************************************************/ + PMP_TCB TCBReadyQueueHead; + PMP_TCB TCBReadyQueueTail; + + + /************************************************************************** + list of TCBs that are currently being sent. NOTE that access to all + three of these (including nBusySend) are controlled via the + TCBSendQLock. This lock should be secured prior to incementing / + decrementing nBusySend, or any queue manipulation on CurrSendHead / Tail + *************************************************************************/ + PMP_TCB CurrSendHead; + PMP_TCB CurrSendTail; + INT32 nBusySend; + + + /************************************************************************** + List of packets (not TCBs) that were queued for lack of resources + *************************************************************************/ + struct list_head SendWaitQueue; + INT32 nWaitSend; + + + /************************************************************************** + The actual descriptor ring + *************************************************************************/ + PTX_DESC_ENTRY_t pTxDescRingVa; + dma_addr_t pTxDescRingPa; + UINT64 pTxDescRingAdjustedPa; + UINT64 TxDescOffset; + + + /************************************************************************** + ReadyToSend indicates where we last wrote to in the descriptor ring. + *************************************************************************/ + TXDMA_SERVICE_REQUEST_t txDmaReadyToSend; + + + /************************************************************************** + The location of the write-back status block + *************************************************************************/ + PTX_STATUS_BLOCK_t pTxStatusVa; + dma_addr_t pTxStatusPa; + + + /************************************************************************** + A Block of zeroes, used to pad packets that are less than 60 bytes. + *************************************************************************/ + void *pTxDummyBlkVa; + dma_addr_t pTxDummyBlkPa; + + TXMAC_ERR_t TxMacErr; + + + /************************************************************************** + Variables to track the Tx interrupt coalescing features + *************************************************************************/ + INT32 TxPacketsSinceLastinterrupt; +} +TX_RING_t, *PTX_RING_t; + + + + +/****************************************************************************** + Forward declaration of the frag-list for the following prototypes + *****************************************************************************/ +typedef struct _MP_FRAG_LIST MP_FRAG_LIST, *PMP_FRAG_LIST; + + + + +/****************************************************************************** + Forward declaration of the private adapter structure + *****************************************************************************/ +struct et131x_adapter; + + + + +/****************************************************************************** + PROTOTYPES for et1310_tx.c + *****************************************************************************/ +int et131x_tx_dma_memory_alloc( struct et131x_adapter *adapter ); +void et131x_tx_dma_memory_free( struct et131x_adapter *adapter ); +void ConfigTxDmaRegs( struct et131x_adapter *pAdapter ); +void et131x_init_send( struct et131x_adapter *adapter ); +void et131x_tx_dma_disable( struct et131x_adapter *pAdapter ); +void et131x_tx_dma_enable( struct et131x_adapter *pAdapter ); +void et131x_handle_send_interrupt( struct et131x_adapter *pAdapter ); +void et131x_free_busy_send_packets( struct et131x_adapter *pAdapter ); +int et131x_send_packets( struct sk_buff *skb, struct net_device *netdev ); + + + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* __ET1310_TX_H__ */ --- linux-2.6.28.orig/ubuntu/et131x/ET1310_mac.c +++ linux-2.6.28/ubuntu/et131x/ET1310_mac.c @@ -0,0 +1,1247 @@ +/******************************************************************************* + * Agere Systems Inc. + * 10/100/1000 Base-T Ethernet Driver for the ET1301 and ET131x series MACs + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * http://www.agere.com + * + *------------------------------------------------------------------------------ + * + * ET1310_mac.c - All code and routines pertaining to the MAC + * + *------------------------------------------------------------------------------ + * + * SOFTWARE LICENSE + * + * This software is provided subject to the following terms and conditions, + * which you should read carefully before using the software. Using this + * software indicates your acceptance of these terms and conditions. If you do + * not agree with these terms and conditions, do not use the software. + * + * Copyright © 2005 Agere Systems Inc. + * All rights reserved. + * + * Redistribution and use in source or binary forms, with or without + * modifications, are permitted provided that the following conditions are met: + * + * . Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following Disclaimer as comments in the code as + * well as in the documentation and/or other materials provided with the + * distribution. + * + * . Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following Disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * . Neither the name of Agere Systems Inc. nor the names of the contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * Disclaimer + * + * THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY + * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN + * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + ******************************************************************************/ + + + + +/****************************************************************************** + * VERSION CONTROL INFORMATION + ****************************************************************************** + + $RCSFile: $ + $Date: 2005/10/28 18:43:44 $ + $Revision: 1.11 $ + $Name: T_20060131_v1-2-2 $ + $Author: vjs $ + + *****************************************************************************/ + + + + +/****************************************************************************** + Includes + *****************************************************************************/ +#include "et131x_version.h" +#include "et131x_debug.h" +#include "et131x_defs.h" + +#include +#include +#include +#include + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,0 )) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "ET1310_phy.h" +#include "ET1310_pm.h" +#include "ET1310_jagcore.h" +#include "ET1310_mac.h" + +#include "et131x_supp.h" +#include "et131x_adapter.h" +#include "et131x_initpci.h" +#include "et131x_supp.h" + + + + +/****************************************************************************** + Data for debugging facilities + *****************************************************************************/ +#ifdef ET131X_DBG +extern dbg_info_t *et131x_dbginfo; +#endif /* ET131X_DBG */ + + + + +/****************************************************************************** + ROUTINE: ConfigMacRegs1 + ****************************************************************************** + + DESCRIPTION: + Used to configure the first part of MAC regs to a known initialized + state + + PARAMETERS : + pAdpater - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMACRegs1( ET131X_ADAPTER *pAdapter ) +{ + PMAC_t pMac; + MAC_STATION_ADDR1_t station1; + MAC_STATION_ADDR2_t station2; + MAC_IPG_t ipg; + MAC_HFDP_t hfdp; + MII_MGMT_CFG_t mii_mgmt_cfg; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMACRegs1" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get our pointer to the MAC regs + *************************************************************************/ + pMac = &pAdapter->CSRAddress->mac; + + + /************************************************************************** + First we need to reset everything. Write to MAC configuration register + 1 to perform reset. + *************************************************************************/ + pMac->cfg1.value = 0xC00F0000; + + + /************************************************************************** + Next lets configure the MAC Inter-packet gap register + *************************************************************************/ + ipg.bits.non_B2B_ipg_1 = 0x38; //58d + ipg.bits.non_B2B_ipg_2 = 0x58; //88d + ipg.bits.min_ifg_enforce = 0x50; //80d + ipg.bits.B2B_ipg = 0x60; //96d + + pMac->ipg.value = ipg.value; + + + /************************************************************************** + Next lets configure the MAC Half Duplex register + *************************************************************************/ + hfdp.bits.alt_beb_trunc = 0xA; + hfdp.bits.alt_beb_enable = 0x0; + hfdp.bits.bp_no_backoff = 0x0; + hfdp.bits.no_backoff = 0x0; + hfdp.bits.excess_defer = 0x1; + hfdp.bits.rexmit_max = 0xF; + hfdp.bits.coll_window = 0x37; //55d + + pMac->hfdp.value = hfdp.value; + + + /************************************************************************** + Next lets configure the MAC Interface Control register + *************************************************************************/ + pMac->if_ctrl.value = 0x0; + + + /************************************************************************** + Let's move on to setting up the mii managment configuration + *************************************************************************/ + mii_mgmt_cfg.bits.reset_mii_mgmt = 0; + mii_mgmt_cfg.bits.scan_auto_incremt = 0; + mii_mgmt_cfg.bits.preamble_suppress = 0; + mii_mgmt_cfg.bits.mgmt_clk_reset = 0x7; + + pMac->mii_mgmt_cfg.value = mii_mgmt_cfg.value; + + + /************************************************************************** + Next lets configure the MAC Station Address register. These values are + read from the EEPROM during initialization and stored in the adapter + structure. We write what is stored in the adapter structure to the MAC + Station Address registers high and low. This station address is used + for generating and checking pause control packets. + *************************************************************************/ + station2.bits.Octet1 = pAdapter->CurrentAddress[0]; + station2.bits.Octet2 = pAdapter->CurrentAddress[1]; + station1.bits.Octet3 = pAdapter->CurrentAddress[2]; + station1.bits.Octet4 = pAdapter->CurrentAddress[3]; + station1.bits.Octet5 = pAdapter->CurrentAddress[4]; + station1.bits.Octet6 = pAdapter->CurrentAddress[5]; + + pMac->station_addr_1.value = station1.value; + pMac->station_addr_2.value = station2.value; + + + /************************************************************************** + Max ethernet packet in bytes that will passed by the mac without being + truncated. Allow the MAC to pass 8 more than our max packet size. This + is 4 for the Ethernet CRC and 4 for the VLAN ID. + + Packets larger than (RegistryJumboPacket) that do not contain a VLAN + ID will be dropped by the Rx function. + *************************************************************************/ +#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) + pMac->max_fm_len.value = pAdapter->RegistryJumboPacket + 8; +#else + pMac->max_fm_len.value = pAdapter->RegistryJumboPacket + 4; +#endif + + + /************************************************************************** + clear out MAC config reset + *************************************************************************/ + pAdapter->CSRAddress->mac.cfg1.value = 0x0; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigMacRegs2 + ****************************************************************************** + + DESCRIPTION: + Used to configure the second part of MAC regs to a known initialized + state + + PARAMETERS : + pAdpater - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMACRegs2( ET131X_ADAPTER *pAdapter ) +{ + INT32 delay = 0; + PMAC_t pMac; + MAC_CFG1_t cfg1; + MAC_CFG2_t cfg2; + MAC_IF_CTRL_t ifctrl; + TXMAC_CTL_t ctl = pAdapter->CSRAddress->txmac.ctl; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMACRegs2" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get our pointer to the MAC regs + *************************************************************************/ + pMac = &pAdapter->CSRAddress->mac; + + cfg1.value = pMac->cfg1.value; + cfg2.value = pMac->cfg2.value; + ifctrl.value = pMac->if_ctrl.value; + + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_1000MBPS ) + { + cfg2.bits.if_mode = 0x2; + ifctrl.bits.phy_mode = 0x0; + } + else + { + cfg2.bits.if_mode = 0x1; + ifctrl.bits.phy_mode = 0x1; + } + + + /************************************************************************** + We need to enable Rx/Tx + *************************************************************************/ + cfg1.bits.rx_enable = 0x1; + cfg1.bits.tx_enable = 0x1; + + + /************************************************************************** + Set up flow control + *************************************************************************/ + cfg1.bits.tx_flow = 0x1; + + if( ( pAdapter->FlowControl == RxOnly ) || + ( pAdapter->FlowControl == Both )) + { + cfg1.bits.rx_flow = 0x1; + } + else + { + cfg1.bits.rx_flow = 0x0; + } + + + /************************************************************************** + Initialize loop back to off + *************************************************************************/ + cfg1.bits.loop_back = 0; + + pAdapter->CSRAddress->mac.cfg1.value = cfg1.value; + + + /************************************************************************** + Now we need to initialize the MAC Configuration 2 register + *************************************************************************/ + cfg2.bits.preamble_len = 0x7; + cfg2.bits.huge_frame = 0x0; + /* LENGTH FIELD CHECKING bit4: Set this bit to cause the MAC to check the + * frame’s length field to ensure it matches the actual data field length. Clear this bit if no + * length field checking is desired. Its default is ‘0’. + */ + cfg2.bits.len_check = 0x1; + + if ( pAdapter->RegistryPhyLoopbk == FALSE ) + { + cfg2.bits.pad_crc = 0x1; + cfg2.bits.crc_enable = 0x1; + } + else + { + cfg2.bits.pad_crc = 0; + cfg2.bits.crc_enable = 0; + } + + + /************************************************************************** + 1 – full duplex, 0 – half-duplex + *************************************************************************/ + cfg2.bits.full_duplex = pAdapter->uiDuplexMode; + ifctrl.bits.ghd_mode = !pAdapter->uiDuplexMode; + + pAdapter->CSRAddress->mac.if_ctrl = ifctrl; + pAdapter->CSRAddress->mac.cfg2.value = cfg2.value; + + do + { + udelay( 10 ); + delay++; + } while(( !pAdapter->CSRAddress->mac.cfg1.bits.syncd_rx_en || + !pAdapter->CSRAddress->mac.cfg1.bits.syncd_tx_en ) && + ( delay < 100 )); + + if( delay == 100 ) + { + DBG_ERROR( et131x_dbginfo, + "Syncd bits did not respond correctly cfg1 word 0x%08x\n", + pAdapter->CSRAddress->mac.cfg1.value ); + } + + DBG_TRACE( et131x_dbginfo, + "Speed %d, Dup %d, CFG1 0x%08x, CFG2 0x%08x, if_ctrl 0x%08x\n", + pAdapter->uiLinkSpeed, pAdapter->uiDuplexMode, + pAdapter->CSRAddress->mac.cfg1.value, + pAdapter->CSRAddress->mac.cfg2.value, + pAdapter->CSRAddress->mac.if_ctrl.value ); + + + /************************************************************************** + Enable TXMAC + *************************************************************************/ + ctl.bits.txmac_en = 0x1; + ctl.bits.fc_disable = 0x1; + pAdapter->CSRAddress->txmac.ctl = ctl; + + + /************************************************************************** + Ready to start the RXDMA/TXDMA engine + *************************************************************************/ + if( !MP_TEST_FLAG( pAdapter, fMP_ADAPTER_LOWER_POWER )) + { + et131x_rx_dma_enable( pAdapter ); + et131x_tx_dma_enable( pAdapter ); + } + else + { + DBG_WARNING( et131x_dbginfo, + "Didn't enable Rx/Tx due to low-power mode\n" ); + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigRxMacRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the RX MAC registers in the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigRxMacRegs( ET131X_ADAPTER *pAdapter ) +{ + PRXMAC_t pRxMac; + RXMAC_WOL_SA_LO_t sa_lo; + RXMAC_WOL_SA_HI_t sa_hi; + RXMAC_PF_CTRL_t pf_ctrl = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigRxMacRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get a local pointer to the RX MAC Registers + *************************************************************************/ + pRxMac = &pAdapter->CSRAddress->rxmac; + + + /************************************************************************** + Disable the MAC while it is being configured (also disable WOL) + *************************************************************************/ + pRxMac->ctrl.value = 0x8; + + + /************************************************************************** + Initialize WOL to disabled. + *************************************************************************/ + + pRxMac->crc0.value = 0x0; + pRxMac->crc12.value = 0x0000; + pRxMac->crc34.value = 0x0000; + + + /************************************************************************** + We need to set the WOL mask0 – mask4 next. We initialize it to its + default Values of 0x00000000 because there are not WOL masks as of + this time. + *************************************************************************/ + pRxMac->mask0_word0.mask = 0x00000000; + pRxMac->mask0_word1.mask = 0x00000000; + pRxMac->mask0_word2.mask = 0x00000000; + pRxMac->mask0_word3.mask = 0x00000000; + + pRxMac->mask1_word0.mask = 0x00000000; + pRxMac->mask1_word1.mask = 0x00000000; + pRxMac->mask1_word2.mask = 0x00000000; + pRxMac->mask1_word3.mask = 0x00000000; + + pRxMac->mask2_word0.mask = 0x00000000; + pRxMac->mask2_word1.mask = 0x00000000; + pRxMac->mask2_word2.mask = 0x00000000; + pRxMac->mask2_word3.mask = 0x00000000; + + pRxMac->mask3_word0.mask = 0x00000000; + pRxMac->mask3_word1.mask = 0x00000000; + pRxMac->mask3_word2.mask = 0x00000000; + pRxMac->mask3_word3.mask = 0x00000000; + + pRxMac->mask4_word0.mask = 0x00000000; + pRxMac->mask4_word1.mask = 0x00000000; + pRxMac->mask4_word2.mask = 0x00000000; + pRxMac->mask4_word3.mask = 0x00000000; + + + /************************************************************************** + Lets setup the WOL Source Address + *************************************************************************/ + sa_lo.bits.sa3 = pAdapter->CurrentAddress[2]; + sa_lo.bits.sa4 = pAdapter->CurrentAddress[3]; + sa_lo.bits.sa5 = pAdapter->CurrentAddress[4]; + sa_lo.bits.sa6 = pAdapter->CurrentAddress[5]; + pRxMac->sa_lo.value = sa_lo.value; + + sa_hi.bits.sa1 = pAdapter->CurrentAddress[0]; + sa_hi.bits.sa2 = pAdapter->CurrentAddress[1]; + pRxMac->sa_hi.value = sa_hi.value; + + + /************************************************************************** + Disable all Packet Filtering + *************************************************************************/ + pRxMac->pf_ctrl.value = 0; + + + /************************************************************************** + Let's initialize the Unicast Packet filtering address + *************************************************************************/ + if( pAdapter->PacketFilter & ET131X_PACKET_TYPE_DIRECTED ) + { + SetupDeviceForUnicast( pAdapter ); + pf_ctrl.bits.filter_uni_en = 1; + } + else + { + pRxMac->uni_pf_addr1.value = 0x00000000; + pRxMac->uni_pf_addr2.value = 0x00000000; + pRxMac->uni_pf_addr3.value = 0x00000000; + } + + + /************************************************************************** + Let's initialize the Multicast hash + *************************************************************************/ + if( pAdapter->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST ) + { + pf_ctrl.bits.filter_multi_en = 0; + } + else + { + pf_ctrl.bits.filter_multi_en = 1; + SetupDeviceForMulticast( pAdapter ); + } + + + /************************************************************************** + Runt packet filtering. Didn't work in version A silicon. + *************************************************************************/ + pf_ctrl.bits.min_pkt_size = NIC_MIN_PACKET_SIZE + 4; + pf_ctrl.bits.filter_frag_en = 1; + + if( pAdapter->RegistryJumboPacket > 8192 ) + { + RXMAC_MCIF_CTRL_MAX_SEG_t mcif_ctrl_max_seg; + + + /********************************************************************** + In order to transmit jumbo packets greater than 8k, the FIFO + between RxMAC and RxDMA needs to be reduced in size to (16k - + Jumbo packet size). In order to implement this, we must use + "cut through" mode in the RxMAC, which chops packets down into + segments which are (max_size * 16). In this case we selected + 256 bytes, since this is the size of the PCI-Express TLP's that + the 1310 uses. + *********************************************************************/ + mcif_ctrl_max_seg.bits.seg_en = 0x1; + mcif_ctrl_max_seg.bits.fc_en = 0x0; + mcif_ctrl_max_seg.bits.max_size = 0x10; + + pRxMac->mcif_ctrl_max_seg.value = mcif_ctrl_max_seg.value; + } + else + { + pRxMac->mcif_ctrl_max_seg.value = 0x0; + } + + + /************************************************************************** + Initialize the MCIF water marks + *************************************************************************/ + pRxMac->mcif_water_mark.value = 0x0; + + + /************************************************************************** + Initialize the MIF control + *************************************************************************/ + pRxMac->mif_ctrl.value = 0x0; + + + /************************************************************************** + Initialize the Space Available Register + *************************************************************************/ + pRxMac->space_avail.value = 0x0; + + /* Initialize the the mif_ctrl register + * bit 3 - Receive code error. One or more nibbles were signaled as errors + during the reception of the packet. Clear this bit in Gigabit, + set it in 100Mbit. This was derived experimentally at UNH. + * bit 4 - Receive CRC error. The packet’s CRC did not match the + internally generated CRC. + * bit 5 - Receive length check error. Indicates that frame length field + value in the packet does not match the actual data byte length + and is not a type field. + * bit 16 - Receive frame truncated. + * bit 17 - Drop packet enable + */ + if( pAdapter->uiLinkSpeed == TRUEPHY_SPEED_100MBPS ) + { + pRxMac->mif_ctrl.value = 0x30038; + } + else + { + pRxMac->mif_ctrl.value = 0x30030; + } + + + /************************************************************************** + Finally we initialize RxMac to be enabled & WOL disabled. Packet filter + is always enabled since it is where the runt packets are supposed to be + dropped. For version A silicon, runt packet dropping doesn't work, so + it is disabled in the pf_ctrl register, but we still leave the packet + filter on. + *************************************************************************/ + pRxMac->pf_ctrl = pf_ctrl; + pRxMac->ctrl.value = 0x9; + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigTxMacRegs + ****************************************************************************** + + DESCRIPTION: + used to configure the TX MAC registers of the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigTxMacRegs( ET131X_ADAPTER *pAdapter ) +{ + PTXMAC_t pTxMac; + TXMAC_CF_PARAM_t Local; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigTxMacRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Let's get the pointer to tx mac section of regs + *************************************************************************/ + pTxMac = &pAdapter->CSRAddress->txmac; + + + /************************************************************************** + We need to update the Control Frame Parameters + cfpt - control frame pause timer set to 64 (0x40) + cfep - control frame extended pause timer set to 0x0 + *************************************************************************/ + if( pAdapter->FlowControl == None ) + { + pTxMac->cf_param.value = 0x0; + } + else + { + Local.bits.cfpt = 0x40; + Local.bits.cfep = 0x0; + pTxMac->cf_param.value = Local.value; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigMacStatRegs + ****************************************************************************** + + DESCRIPTION: + Used to configure the MAC STAT section of the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigMacStatRegs( ET131X_ADAPTER *pAdapter ) +{ + PMAC_STAT_t pDevMacStat; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "ConfigMacStatRegs" ); + DBG_ENTER( et131x_dbginfo ); + + + pDevMacStat = &pAdapter->CSRAddress->macStat; + + + /************************************************************************** + Next we need to initialize all the MAC_STAT registers to zero on the + device. + *************************************************************************/ + pDevMacStat->RFcs = 0x0; + pDevMacStat->RAln = 0x0; + pDevMacStat->RFlr = 0x0; + pDevMacStat->RDrp = 0x0; + pDevMacStat->RCde = 0x0; + pDevMacStat->ROvr = 0x0; + pDevMacStat->RFrg = 0x0; + + pDevMacStat->TScl = 0x0; + pDevMacStat->TDfr = 0x0; + pDevMacStat->TMcl = 0x0; + pDevMacStat->TLcl = 0x0; + pDevMacStat->TNcl = 0x0; + pDevMacStat->TOvr = 0x0; + pDevMacStat->TUnd = 0x0; + + + /*************************************************************************** + Unmask any counters that we want to track the overflow of. Initially + this will be all counters. It may become clear later that we do not + need to track all counters. + **************************************************************************/ + { + MAC_STAT_REG_1_t Carry1M = {0xffffffff}; + + Carry1M.bits.rdrp = 0x0; + Carry1M.bits.rjbr = 0x1; + Carry1M.bits.rfrg = 0x0; + Carry1M.bits.rovr = 0x0; + Carry1M.bits.rund = 0x1; + Carry1M.bits.rcse = 0x1; + Carry1M.bits.rcde = 0x0; + Carry1M.bits.rflr = 0x0; + Carry1M.bits.raln = 0x0; + Carry1M.bits.rxuo = 0x1; + Carry1M.bits.rxpf = 0x1; + Carry1M.bits.rxcf = 0x1; + Carry1M.bits.rbca = 0x1; + Carry1M.bits.rmca = 0x1; + Carry1M.bits.rfcs = 0x0; + Carry1M.bits.rpkt = 0x1; + Carry1M.bits.rbyt = 0x1; + Carry1M.bits.trmgv = 0x1; + Carry1M.bits.trmax = 0x1; + Carry1M.bits.tr1k = 0x1; + Carry1M.bits.tr511 = 0x1; + Carry1M.bits.tr255 = 0x1; + Carry1M.bits.tr127 = 0x1; + Carry1M.bits.tr64 = 0x1; + + pDevMacStat->Carry1M = Carry1M; + } + + { + MAC_STAT_REG_2_t Carry2M = {0xffffffff}; + + Carry2M.bits.tdrp = 0x1; + Carry2M.bits.tpfh = 0x1; + Carry2M.bits.tncl = 0x0; + Carry2M.bits.txcl = 0x1; + Carry2M.bits.tlcl = 0x0; + Carry2M.bits.tmcl = 0x0; + Carry2M.bits.tscl = 0x0; + Carry2M.bits.tedf = 0x1; + Carry2M.bits.tdfr = 0x0; + Carry2M.bits.txpf = 0x1; + Carry2M.bits.tbca = 0x1; + Carry2M.bits.tmca = 0x1; + Carry2M.bits.tpkt = 0x1; + Carry2M.bits.tbyt = 0x1; + Carry2M.bits.tfrg = 0x1; + Carry2M.bits.tund = 0x0; + Carry2M.bits.tovr = 0x0; + Carry2M.bits.txcf = 0x1; + Carry2M.bits.tfcs = 0x1; + Carry2M.bits.tjbr = 0x1; + + pDevMacStat->Carry2M = Carry2M; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE: ConfigFlowControl + ****************************************************************************** + + DESCRIPTION: + Used to configure the MAC STAT section of the JAGCore + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void ConfigFlowControl( ET131X_ADAPTER *pAdapter ) +{ + if( pAdapter->uiDuplexMode == 0 ) + { + pAdapter->FlowControl = None; + } + else + { + char RemotePause, RemoteAsyncPause; + + ET1310_PhyAccessMiBit( pAdapter, + TRUEPHY_BIT_READ, 5, 10, &RemotePause ); + ET1310_PhyAccessMiBit( pAdapter, + TRUEPHY_BIT_READ, 5, 11, &RemoteAsyncPause ); + + if(( RemotePause == TRUEPHY_BIT_SET ) && + ( RemoteAsyncPause == TRUEPHY_BIT_SET )) + { + pAdapter->FlowControl = pAdapter->RegistryFlowControl; + } + else if(( RemotePause == TRUEPHY_BIT_SET ) && + ( RemoteAsyncPause == TRUEPHY_BIT_CLEAR )) + { + if( pAdapter->RegistryFlowControl == Both ) + { + pAdapter->FlowControl = Both; + } + else + { + pAdapter->FlowControl = None; + } + } + else if(( RemotePause == TRUEPHY_BIT_CLEAR ) && + ( RemoteAsyncPause == TRUEPHY_BIT_CLEAR )) + { + pAdapter->FlowControl = None; + } + else /* if (( RemotePause == TRUEPHY_CLEAR_BIT ) && + ( RemoteAsyncPause == TRUEPHY_SET_BIT )) */ + { + if( pAdapter->RegistryFlowControl == Both ) + { + pAdapter->FlowControl = RxOnly; + } + else + { + pAdapter->FlowControl = None; + } + } + } +} +/*===========================================================================*/ + + + + + + +/****************************************************************************** + ROUTINE: UpdateMacStatHostCounters + ****************************************************************************** + + DESCRIPTION: + used to update the local copy of the statistics held in the adapter + structure + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void UpdateMacStatHostCounters( ET131X_ADAPTER *pAdapter ) +{ + PMAC_STAT_t pDevMacStat; + /*-----------------------------------------------------------------------*/ + + + /************************************************************************** + Get a local pointer to the adapter macstat regs and update stats + *************************************************************************/ + pDevMacStat = &pAdapter->CSRAddress->macStat; + + pAdapter->Stats.collisions += pDevMacStat->TNcl; + pAdapter->Stats.first_collision += pDevMacStat->TScl; + pAdapter->Stats.tx_deferred += pDevMacStat->TDfr; + pAdapter->Stats.excessive_collisions += pDevMacStat->TMcl; + pAdapter->Stats.late_collisions += pDevMacStat->TLcl; + pAdapter->Stats.tx_uflo += pDevMacStat->TUnd; + pAdapter->Stats.max_pkt_error += pDevMacStat->TOvr; + + pAdapter->Stats.alignment_err += pDevMacStat->RAln; + pAdapter->Stats.crc_err += pDevMacStat->RCde; + pAdapter->Stats.norcvbuf += pDevMacStat->RDrp; + pAdapter->Stats.rx_ov_flow += pDevMacStat->ROvr; + pAdapter->Stats.code_violations += pDevMacStat->RFcs; + pAdapter->Stats.length_err += pDevMacStat->RFlr; + + pAdapter->Stats.other_errors += pDevMacStat->RFrg; + + return; +} +/*===========================================================================*/ + + + + + +/****************************************************************************** + ROUTINE: HandleMacStatInterrupt + ****************************************************************************** + + DESCRIPTION: + One of the MACSTAT counters has wrapped. Update the local copy of + the statistics held in the adapter structure, checking the "wrap" + bit for each counter. + + PARAMETERS : + pAdapter - pointer to the adapter structure + + RETURNS : + NONE + + *****************************************************************************/ +void HandleMacStatInterrupt( ET131X_ADAPTER *pAdapter ) +{ + MAC_STAT_REG_1_t Carry1; + MAC_STAT_REG_2_t Carry2; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "HandleMacStatInterrupt" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Read the interrupt bits from the register(s). These are Clear On Write. + *************************************************************************/ + Carry1 = pAdapter->CSRAddress->macStat.Carry1; + Carry2 = pAdapter->CSRAddress->macStat.Carry2; + + pAdapter->CSRAddress->macStat.Carry1 = Carry1; + pAdapter->CSRAddress->macStat.Carry2 = Carry2; + + + /************************************************************************** + We need to do update the host copy of all the MAC_STAT counters. For + each counter, check it's overflow bit. If the overflow bit is set, then + increment the host version of the count by one complete revolution of the + counter. This routine is called when the counter block indicates that + one of the counters has wrapped. + *************************************************************************/ + if( Carry1.bits.rfcs ) + { + pAdapter->Stats.code_violations += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.raln ) + { + pAdapter->Stats.alignment_err += COUNTER_WRAP_12_BIT; + } + + if( Carry1.bits.rflr ) + { + pAdapter->Stats.length_err += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rfrg ) + { + pAdapter->Stats.other_errors += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rcde ) + { + pAdapter->Stats.crc_err += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rovr ) + { + pAdapter->Stats.rx_ov_flow += COUNTER_WRAP_16_BIT; + } + + if( Carry1.bits.rdrp ) + { + pAdapter->Stats.norcvbuf += COUNTER_WRAP_16_BIT; + } + + if( Carry2.bits.tovr ) + { + pAdapter->Stats.max_pkt_error += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tund ) + { + pAdapter->Stats.tx_uflo += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tscl ) + { + pAdapter->Stats.first_collision += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tdfr ) + { + pAdapter->Stats.tx_deferred += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tmcl ) + { + pAdapter->Stats.excessive_collisions += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tlcl ) + { + pAdapter->Stats.late_collisions += COUNTER_WRAP_12_BIT; + } + + if( Carry2.bits.tncl ) + { + pAdapter->Stats.collisions += COUNTER_WRAP_12_BIT; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : SetupDeviceForMulticast + ****************************************************************************** + + DESCRIPTION : + Use to set the ET1310 to do multicast filtering + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + REUSE INFORMATION : + NONE + + *****************************************************************************/ +void SetupDeviceForMulticast( ET131X_ADAPTER *pAdapter ) +{ + UINT32 nIndex; + UINT32 result; + RXMAC_MULTI_HASH_t hash1 = {0}; + RXMAC_MULTI_HASH_t hash2 = {0}; + RXMAC_MULTI_HASH_t hash3 = {0}; + RXMAC_MULTI_HASH_t hash4 = {0}; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "SetupDeviceForMulticast" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + If ET131X_PACKET_TYPE_MULTICAST is specified, then we provision the + multi-cast LIST. If it is NOT specified, (and "ALL" is not specified) + then we should pass NO multi-cast addresses to the driver. + *************************************************************************/ + if( pAdapter->PacketFilter & ET131X_PACKET_TYPE_MULTICAST ) + { + DBG_VERBOSE( et131x_dbginfo, "MULTICAST flag is set, MCCount: %d\n", + pAdapter->MCAddressCount ); + + + /********************************************************************** + Loop through our multicast array and set up the device + **********************************************************************/ + for( nIndex = 0; nIndex < pAdapter->MCAddressCount; nIndex++ ) + { + DBG_VERBOSE( et131x_dbginfo, + "MCList[%d]: %02x:%02x:%02x:%02x:%02x:%02x\n", + nIndex, + pAdapter->MCList[nIndex][0], + pAdapter->MCList[nIndex][1], + pAdapter->MCList[nIndex][2], + pAdapter->MCList[nIndex][3], + pAdapter->MCList[nIndex][4], + pAdapter->MCList[nIndex][5] ); + + result = et131x_calc_enet_crc( pAdapter->MCList[nIndex], 6 ); + + result = ( result & 0x3F800000 ) >> 23; + + if( result < 32 ) + { + hash1.hash |= ( 1 << result ); + } + else if(( 31 < result ) && ( result < 64 )) + { + result -= 32; + hash2.hash |= ( 1 << result ); + } + else if(( 63 < result ) && ( result < 96 )) + { + result -= 64; + hash3.hash |= ( 1 << result ); + } + else + { + result -= 96; + hash4.hash |= ( 1 << result ); + } + } + } + + + /************************************************************************** + Write out the new hash to the device + *************************************************************************/ + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 0 ) + { + pAdapter->CSRAddress->rxmac.multi_hash1.hash = hash1.hash; + pAdapter->CSRAddress->rxmac.multi_hash2.hash = hash2.hash; + pAdapter->CSRAddress->rxmac.multi_hash3.hash = hash3.hash; + pAdapter->CSRAddress->rxmac.multi_hash4.hash = hash4.hash; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ + + + + +/****************************************************************************** + ROUTINE : SetupDeviceForUnicast + ****************************************************************************** + + DESCRIPTION : + Use to set the ET1310 to do unicast filtering + + PARAMETERS : + pAdapter - pointer to our adapter structure + + RETURNS : + NONE + + REUSE INFORMATION : + NONE + + *****************************************************************************/ +void SetupDeviceForUnicast( ET131X_ADAPTER *pAdapter ) +{ + RXMAC_UNI_PF_ADDR1_t uni_pf1; + RXMAC_UNI_PF_ADDR2_t uni_pf2; + RXMAC_UNI_PF_ADDR3_t uni_pf3; + /*-----------------------------------------------------------------------*/ + + + DBG_FUNC( "SetupDeviceForUnicast" ); + DBG_ENTER( et131x_dbginfo ); + + + /************************************************************************** + Set up unicast packet filter reg 3 to be the first two octets of the + MAC address for both address + *************************************************************************/ + /************************************************************************** + Set up unicast packet filter reg 2 to be the octets 2 - 5 of the + MAC address for second address + *************************************************************************/ + /************************************************************************** + Set up unicast packet filter reg 3 to be the octets 2 - 5 of the + MAC address for first address + *************************************************************************/ + uni_pf3.bits.addr1_1 = pAdapter->CurrentAddress[0]; + uni_pf3.bits.addr1_2 = pAdapter->CurrentAddress[1]; + uni_pf3.bits.addr2_1 = pAdapter->CurrentAddress[0]; + uni_pf3.bits.addr2_2 = pAdapter->CurrentAddress[1]; + + uni_pf2.bits.addr2_3 = pAdapter->CurrentAddress[2]; + uni_pf2.bits.addr2_4 = pAdapter->CurrentAddress[3]; + uni_pf2.bits.addr2_5 = pAdapter->CurrentAddress[4]; + uni_pf2.bits.addr2_6 = pAdapter->CurrentAddress[5]; + + uni_pf1.bits.addr1_3 = pAdapter->CurrentAddress[2]; + uni_pf1.bits.addr1_4 = pAdapter->CurrentAddress[3]; + uni_pf1.bits.addr1_5 = pAdapter->CurrentAddress[4]; + uni_pf1.bits.addr1_6 = pAdapter->CurrentAddress[5]; + + if( pAdapter->CSRAddress->global.pm_csr.bits.pm_phy_sw_coma == 0 ) + { + pAdapter->CSRAddress->rxmac.uni_pf_addr1 = uni_pf1; + pAdapter->CSRAddress->rxmac.uni_pf_addr2 = uni_pf2; + pAdapter->CSRAddress->rxmac.uni_pf_addr3 = uni_pf3; + } + + + DBG_LEAVE( et131x_dbginfo ); + return; +} +/*===========================================================================*/ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-memory.h +++ linux-2.6.28/ubuntu/qc-usb/qc-memory.h @@ -0,0 +1,10 @@ +#ifndef _LINUX_QC_MEMORY_H +#define _LINUX_QC_MEMORY_H + +#include + +void *qc_mm_rvmalloc(unsigned long size); +void qc_mm_rvfree(void *mem, unsigned long size); +int qc_mm_remap(struct vm_area_struct *vma, void *src, unsigned long src_size, const void *dst, unsigned long dst_size); + +#endif --- linux-2.6.28.orig/ubuntu/qc-usb/qc-hdcs.c +++ linux-2.6.28/ubuntu/qc-usb/qc-hdcs.c @@ -0,0 +1,734 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qc-usb, linux V4L driver for the Logitech QuickCam USB camera family + * + * qc-hdcs.c - HDCS Sensor Implementation + * + * 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 "quickcam.h" + +/* LSB bit of I2C or register address signifies write (0) or read (1) */ + +/* I2C Address */ +#define HDCS_ADDR (0x55<<1) + +/* {{{ [fold] I2C registers */ +/* I2C Registers common for both HDCS-1000/1100 and HDCS-1020 */ +#define HDCS_IDENT (0x00<<1) /* Identifications Register */ +#define HDCS_STATUS (0x01<<1) /* Status Register */ +#define HDCS_IMASK (0x02<<1) /* Interrupt Mask Register */ +#define HDCS_PCTRL (0x03<<1) /* Pad Control Register */ +#define HDCS_PDRV (0x04<<1) /* Pad Drive Control Register */ +#define HDCS_ICTRL (0x05<<1) /* Interface Control Register */ +#define HDCS_ITMG (0x06<<1) /* Interface Timing Register */ +#define HDCS_BFRAC (0x07<<1) /* Baud Fraction Register */ +#define HDCS_BRATE (0x08<<1) /* Baud Rate Register */ +#define HDCS_ADCCTRL (0x09<<1) /* ADC Control Register */ +#define HDCS_FWROW (0x0A<<1) /* First Window Row Register */ +#define HDCS_FWCOL (0x0B<<1) /* First Window Column Register */ +#define HDCS_LWROW (0x0C<<1) /* Last Window Row Register */ +#define HDCS_LWCOL (0x0D<<1) /* Last Window Column Register */ +#define HDCS_TCTRL (0x0E<<1) /* Timing Control Register */ +#define HDCS_ERECPGA (0x0F<<1) /* PGA Gain Register: Even Row, Even Column */ +#define HDCS_EROCPGA (0x10<<1) /* PGA Gain Register: Even Row, Odd Column */ +#define HDCS_ORECPGA (0x11<<1) /* PGA Gain Register: Odd Row, Even Column */ +#define HDCS_OROCPGA (0x12<<1) /* PGA Gain Register: Odd Row, Odd Column */ +#define HDCS_ROWEXPL (0x13<<1) /* Row Exposure Low Register */ +#define HDCS_ROWEXPH (0x14<<1) /* Row Exposure High Register */ + +/* I2C Registers only for HDCS-1000/1100 */ +#define HDCS00_SROWEXPL (0x15<<1) /* Sub-Row Exposure Low Register */ +#define HDCS00_SROWEXPH (0x16<<1) /* Sub-Row Exposure High Register */ +#define HDCS00_CONFIG (0x17<<1) /* Configuration Register */ +#define HDCS00_CONTROL (0x18<<1) /* Control Register */ + +/* I2C Registers only for HDCS-1020 */ +#define HDCS20_SROWEXP (0x15<<1) /* Sub-Row Exposure Register */ +#define HDCS20_ERROR (0x16<<1) /* Error Control Register */ +#define HDCS20_ITMG2 (0x17<<1) /* Interface Timing 2 Register */ +#define HDCS20_ICTRL2 (0x18<<1) /* Interface Control 2 Register */ +#define HDCS20_HBLANK (0x19<<1) /* Horizontal Blank Register */ +#define HDCS20_VBLANK (0x1A<<1) /* Vertical Blank Register */ +#define HDCS20_CONFIG (0x1B<<1) /* Configuration Register */ +#define HDCS20_CONTROL (0x1C<<1) /* Control Register */ +/* }}} */ + +#define IS_870(qc) (GET_PRODUCTID(qc)==0x870) +#define IS_1020(qc) ((qc)->sensor_data.sensor->flag != 0) +#define GET_CONTROL (IS_1020(qc) ? HDCS20_CONTROL : HDCS00_CONTROL) +#define GET_CONFIG (IS_1020(qc) ? HDCS20_CONFIG : HDCS00_CONFIG) + +#define I2C_SET_CHECK(reg,val) if ((r = qc_i2c_set(qc,(reg),(val)))<0) goto fail +#define STV_SET_CHECK(reg,val) if ((r = qc_stv_set(qc,(reg),(val)))<0) goto fail +#define STV_SETW_CHECK(reg,val) if ((r = qc_stv_setw(qc,(reg),(val)))<0) goto fail + +/* Enables experimental compressed mode, works with HDCS-1000/0x840, + mode derived from USB logs obtained from HDCS-1020/0x870 + (should give 640x480), not tested with HDCS-1020. + On HDCS-1000, gives 30 fps but data is in unknown format, + observed image width 163 bytes (how many pixels?). + Frame length appears to vary, typically 3300-4550 bytes. + (apparently quite simple, however). + Use this with DUMPDATA mode. */ +#define HDCS_COMPRESS 0 + +#if HDCS_COMPRESS +/* {{{ [fold] hdcs_compress_init(struct quickcam *qc, int flags) */ +static int hdcs_compress_init(struct quickcam *qc, int flags) +{ + int r; + + if (flags & 1) { + /************************************** Plugin camera **************************************/ + + STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ + // if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870) /* ProductId */ + // PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r); + + STV_SET_CHECK(0x0423, 0x05); /* Unknown (sometimes 4, sometimes 5) */ + // Warning: I2C address 0xBA is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + + if ((r = qc_stv_get(qc, 0x1444)) != 0x10) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r); + if ((r = qc_stv_get(qc, 0x1444)) != 0x10) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r); + if ((r = qc_stv_get(qc, 0x1444)) != 0x10) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1444, should be 0x10", r); + + STV_SET_CHECK(0x0423, 0x05); /* Unknown (sometimes 4, sometimes 5) */ + // Warning: I2C address 0x20 is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + // Warning: I2C address 0x20 is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + // Warning: I2C address 0x20 is invalid + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x0a) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x0a", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + // if ((r = qc_get_i2c(qc, qc->sensor_data.sensor, HDCS_IDENT))<0) /* Identifications Register */ + // PDEBUG("error reading sensor reg HDCS_IDENT"); + // if ((r = qc_stv_get(qc, 0x0424)) != 0x02) /* Successfully transmitted I2C commands */ + // PDEBUG("Bad value 0x%02X in reg 0x0424, should be 0x02", r); + // if ((r = qc_stv_get(qc, 0x1410)) != 0x10) /* I2C area, first reg value */ + // PDEBUG("Bad value 0x%02X in reg 0x1410, should be 0x10", r); + + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + if ((r = qc_stv_get(qc, 0x1443)) != 0x00) /* Scan rate? */ + PDEBUG("Bad value 0x%02X in reg 0x1443, should be 0x00", r); + STV_SET_CHECK(0x1443, 0x01); /* Scan rate? */ + if ((r = qc_stv_get(qc, 0x1443)) != 0x01) /* Scan rate? */ + PDEBUG("Bad value 0x%02X in reg 0x1443, should be 0x01", r); + STV_SET_CHECK(0x1443, 0x00); /* Scan rate? */ + + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + I2C_SET_CHECK(HDCS_ERECPGA, 0x3B); /* PGA Gain Register: Even Row, Even Column */ + I2C_SET_CHECK(HDCS_EROCPGA, 0x3B); /* PGA Gain Register: Even Row, Odd Column */ + I2C_SET_CHECK(HDCS_ORECPGA, 0x3B); /* PGA Gain Register: Odd Row, Even Column */ + I2C_SET_CHECK(HDCS_OROCPGA, 0x3B); /* PGA Gain Register: Odd Row, Odd Column */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1504, 0x07); /* ? */ + STV_SET_CHECK(0x1503, 0x45); /* ? */ + if ((r = qc_stv_get(qc, 0x1500)) != 0x1d) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1500, should be 0x1d", r); + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + // if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870) /* ProductId */ + // PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r); + } + + if (flags & 2) { + /************************************** Start grabbing **************************************/ + + // if ((r = qc_stv_getw(qc, 0xE00A)) != 0x0870) /* ProductId */ + // PDEBUG("Bad value 0x%02X in reg 0xE00A, should be 0x0870", r); + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ + STV_SETW_CHECK(0x15C1, 0x027B); /* Max. ISO packet size */ + I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ + I2C_SET_CHECK(HDCS_FWCOL, 0x0B); /* First Window Column Register */ + I2C_SET_CHECK(HDCS_LWROW, 0x3D); /* Last Window Row Register */ + I2C_SET_CHECK(HDCS_LWCOL, 0x5A); /* Last Window Column Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ + I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCB : 0x6B); /* Timing Control Register */ + I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ + I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ + if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xD6); /* Horizontal Blank Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_ROWEXPL, 0x7B); /* Row Exposure Low Register */ + I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0x01); /* Sub-Row Exposure Register */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0x01<<2); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1501, 0xC2); /* ? */ + STV_SET_CHECK(0x1502, 0xB0); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Start isochronous streaming */ + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ + + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + + /* Stop isochronous streaming */ + STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ + I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ + STV_SETW_CHECK(0x15C1, 0x027B); /* Max. ISO packet size */ + I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ + I2C_SET_CHECK(HDCS_FWCOL, 0x0B); /* First Window Column Register */ + I2C_SET_CHECK(HDCS_LWROW, 0x3D); /* Last Window Row Register */ + I2C_SET_CHECK(HDCS_LWCOL, 0x5A); /* Last Window Column Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ + I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCB : 0x6B); /* Timing Control Register */ + I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ + I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ + if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xD6); /* Horizontal Blank Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_ROWEXPL, 0x7B); /* Row Exposure Low Register */ + I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0x01); /* Sub-Row Exposure Register */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0x01<<2); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1501, 0xC2); /* ? */ + STV_SET_CHECK(0x1502, 0xB0); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Start isochronous streaming */ + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ + + /* Stop isochronous streaming */ + STV_SET_CHECK(0x1440, 0x00); /* Turn on/off isochronous stream */ + I2C_SET_CHECK(GET_CONTROL, 0x00); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(0x0423, 0x04); /* Unknown (sometimes 4, sometimes 5) */ + STV_SET_CHECK(0x1500, 0x1D); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x15C3, 0x02); /* Y-Control, 1: 288 lines, 2: 144 lines */ + STV_SETW_CHECK(0x15C1, 0x0230); /* Max. ISO packet size */ + I2C_SET_CHECK(HDCS_FWROW, 0x00); /* First Window Row Register */ + I2C_SET_CHECK(HDCS_FWCOL, 0x07); /* First Window Column Register */ + I2C_SET_CHECK(HDCS_LWROW, 0x49); /* Last Window Row Register */ + I2C_SET_CHECK(HDCS_LWCOL, 0x5E); /* Last Window Column Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1680, 0x00); /* X-Control, 0xa: 352 columns, 6: 176 columns */ + I2C_SET_CHECK(HDCS_TCTRL, IS_1020(qc) ? 0xCE : 0x6E); /* Timing Control Register */ + I2C_SET_CHECK(HDCS_ICTRL, 0x00); /* Interface Control Register */ + I2C_SET_CHECK(HDCS_ITMG, 0x16); /* Interface Timing Register */ + if (IS_1020(qc)) I2C_SET_CHECK(HDCS20_HBLANK, 0xCF); /* Horizontal Blank Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1446, 0x00); /* ? */ + if ((r = qc_stv_get(qc, 0x1446)) != 0x00) /* ? */ + PDEBUG("Bad value 0x%02X in reg 0x1446, should be 0x00", r); + STV_SET_CHECK(0x1446, 0x00); /* ? */ + I2C_SET_CHECK(HDCS_ROWEXPL, 0x62); /* Row Exposure Low Register */ + I2C_SET_CHECK(HDCS_ROWEXPH, 0x00); /* Row Exposure High Register */ + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0x1A); /* Sub-Row Exposure Register */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0x1A<<2); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0x00); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1501, 0xB6); /* ? */ + STV_SET_CHECK(0x1502, 0xA8); /* ? */ + I2C_SET_CHECK(HDCS_PCTRL, 0x63); /* Pad Control Register */ + I2C_SET_CHECK(HDCS_PDRV, 0x00); /* Pad Drive Control Register */ + I2C_SET_CHECK(GET_CONFIG, 0x08); /* Configuration Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Start isochronous streaming */ + I2C_SET_CHECK(GET_CONTROL, 0x04); /* Control Register */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + STV_SET_CHECK(0x1440, 0x01); /* Turn on/off isochronous stream */ + + if ((r = qc_stv_get(qc, 0x1445)) != 0x04) /* Turn LED on/off? */ + PDEBUG("Bad value 0x%02X in reg 0x1445, should be 0x04", r); + } + + return 0; +fail: return r; +} +/* }}} */ +#endif +/* {{{ [fold] hdcs_init: Initialise parameters (from Georg Acher's user module for hdcs sensor) */ +static int hdcs_init(struct quickcam *qc) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned char control = GET_CONTROL; + unsigned char config = GET_CONFIG; + int r,tctrl,astrt,psmp; + + if (sd->compress) return -EINVAL; + sd->maxwidth = IS_1020(qc) ? 352 : 360; /* CIF */ + sd->maxheight = IS_1020(qc) ? 292 : 296; + if (sd->subsample) { + sd->maxwidth /= 2; /* QCIF */ + sd->maxheight /= 2; + } + if ((r = qc_i2c_break(qc))<0) goto fail; /* The following setting must go into same I2C packet */ +#if HDCS_COMPRESS +r = hdcs_compress_init(qc, 3); +qc_i2c_wait(qc); +qc_i2c_break(qc); +qc_stv_set(qc, 0x1440, 0x00); /* Turn on/off isochronous stream */ +qc_i2c_set(qc, GET_CONTROL, BIT(1)); /* Stop and enter sleep mode */ +qc_i2c_wait(qc); +if (r) PDEBUG("hdcs_compress_init(1) = %i", r); +return 0; +#endif + STV_SET_CHECK(STV_REG23, 0); + + /* Set the STV0602AA in STV0600 emulation mode */ + if (IS_870(qc)) STV_SET_CHECK(0x1446, 1); + + /* Reset the image sensor (keeping it to 1 is a problem) */ + I2C_SET_CHECK(control, 1); + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(control, 0); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + I2C_SET_CHECK(HDCS_STATUS, BIT(6)|BIT(5)|BIT(4)|BIT(3)|BIT(2)|BIT(1)); /* Clear status (writing 1 will clear the corresponding status bit) */ + + I2C_SET_CHECK(HDCS_IMASK, 0x00); /* Disable all interrupts */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(STV_REG00, 0x1D); + STV_SET_CHECK(STV_REG04, 0x07); + STV_SET_CHECK(STV_REG03, 0x95); + + STV_SET_CHECK(STV_REG23, 0); + + STV_SET_CHECK(STV_SCAN_RATE, 0x20); /* Larger -> slower */ + + STV_SETW_CHECK(STV_ISO_SIZE, 847); /* ISO-Size, 0x34F = 847 .. 0x284 = 644 */ + + /* Set mode */ + STV_SET_CHECK(STV_Y_CTRL, 0x01); /* 0x02: half, 0x01: full */ + STV_SET_CHECK(STV_X_CTRL, 0x0A); /* 0x06: half, 0x0A: full */ + + /* These are not good final values, which will be set in set_size */ + /* However, it looks like it's best to set some values at this point nevertheless */ + I2C_SET_CHECK(HDCS_FWROW, 0); /* Start at row 0 */ + I2C_SET_CHECK(HDCS_FWCOL, 0); /* Start at column 0 */ + I2C_SET_CHECK(HDCS_LWROW, 0x47); /* End at row 288 */ + I2C_SET_CHECK(HDCS_LWCOL, 0x57); /* End at column 352 */ + + /* 0x07 - 0x50 */ + astrt = 3; /* 0..3, doesn't seem to have any effect... hmm.. smaller is slower with subsampling */ + if (!IS_1020(qc)) { + /* HDCS-1000 (tctrl was 0x09, but caused some HDCS-1000 not to work) */ + /* Frame rate on HDCS-1000 0x46D:0x840 depending on PSMP: + * 4 = doesn't work at all + * 5 = 7.8 fps, + * 6 = 6.9 fps, + * 8 = 6.3 fps, + * 10 = 5.5 fps, + * 15 = 4.4 fps, + * 31 = 2.8 fps */ + /* Frame rate on HDCS-1000 0x46D:0x870 depending on PSMP: + * 15 = doesn't work at all + * 18 = doesn't work at all + * 19 = 7.3 fps + * 20 = 7.4 fps + * 21 = 7.4 fps + * 22 = 7.4 fps + * 24 = 6.3 fps + * 30 = 5.4 fps */ + psmp = IS_870(qc) ? 20 : 5; /* 4..31 (was 30, changed to 20) */ + tctrl = (astrt<<5) | psmp; + } else { + /* HDCS-1020 (tctrl was 0x7E, but causes slow frame rate on HDCS-1020) */ + /* Changed to 6 which should give 8.1 fps */ + psmp = 6; /* 4..31 (was 9, changed to 6 to improve fps */ + tctrl = (astrt<<6) | psmp; + } + I2C_SET_CHECK(HDCS_TCTRL, tctrl); /* Set PGA sample duration (was 0x7E for IS_870, but caused slow framerate with HDCS-1020) */ + + I2C_SET_CHECK(control, 0); /* FIXME:should not be anymore necessary (already done) */ + + I2C_SET_CHECK(HDCS_ROWEXPL, 0); + I2C_SET_CHECK(HDCS_ROWEXPH, 0); + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_SROWEXP, 0); + I2C_SET_CHECK(HDCS20_ERROR, BIT(0)|BIT(2)); /* Clear error conditions by writing 1 */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, 0); + I2C_SET_CHECK(HDCS00_SROWEXPH, 0); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(STV_REG01, 0xB5); + STV_SET_CHECK(STV_REG02, 0xA8); + + I2C_SET_CHECK(HDCS_PCTRL, BIT(6)|BIT(5)|BIT(1)|BIT(0)); + I2C_SET_CHECK(HDCS_PDRV, 0x00); + I2C_SET_CHECK(HDCS_ICTRL, (sd->subsample ? BIT(7) : 0) | BIT(5)); + I2C_SET_CHECK(HDCS_ITMG, BIT(4)|BIT(1)); + + /* CONFIG: Bit 3: continous frame capture, bit 2: stop when frame complete */ + I2C_SET_CHECK(config, (sd->subsample ? BIT(5) : 0) | BIT(3)); + I2C_SET_CHECK(HDCS_ADCCTRL, 10); /* ADC output resolution to 10 bits */ + if ((r = qc_i2c_wait(qc))<0) goto fail; +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_start: Start grabbing */ +static int hdcs_start(struct quickcam *qc) +{ + int r; +#if HDCS_COMPRESS +r = hdcs_compress_init(qc, 2); +qc_i2c_wait(qc); +if (r) PDEBUG("hdcs_compress_init(1) = %i", r); +return 0; +#endif + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, BIT(2)); /* Run enable */ + if ((r = qc_i2c_break(qc))<0) goto fail; +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_stop: Stop grabbing */ +static int hdcs_stop(struct quickcam *qc) +{ + int r; + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(GET_CONTROL, BIT(1)); /* Stop and enter sleep mode */ + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_set_exposure: Set exposure time, val=0..65535 */ +static int hdcs_set_exposure(struct quickcam *qc, unsigned int val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned char control = GET_CONTROL; + unsigned int rowexp; /* rowexp,srowexp = 15 bits (0..32767) */ + unsigned int srowexp; /* sub-row exposure (smaller is brighter) */ + unsigned int max_srowexp; /* Maximum srowexp value + 1 */ + int r; + + /* Absolute black at srowexp=2672,width=360; 2616, width=352; 1896, width=256 for hdcs1000 */ + + if (val==sd->exposure) return 0; + sd->exposure = val; + val *= 16; /* 16 seems to be the smallest change that actually affects brightness */ + max_srowexp = sd->width*15/2 - 104 + 1; + srowexp = max_srowexp - (val % max_srowexp) - 1; + rowexp = val / max_srowexp; + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("width=%i height=%i rowexp=%i srowexp=%i",sd->width,sd->height,rowexp,srowexp); + if ((r = qc_i2c_break(qc))<0) goto fail; /* The following setting must go into same I2C packet */ + I2C_SET_CHECK(control, 0); /* Stop grabbing */ + I2C_SET_CHECK(HDCS_ROWEXPL, rowexp & 0xFF); /* Number of rows to expose */ + I2C_SET_CHECK(HDCS_ROWEXPH, rowexp >> 8); + if (IS_1020(qc)) { + srowexp = 0; //FIXME:need formula to compute srowexp for HDCS1020! + srowexp >>= 2; /* Bits 0..1 are hardwired to 0 */ + I2C_SET_CHECK(HDCS20_SROWEXP, srowexp & 0xFF); /* Number of pixels to expose */ + } else { + I2C_SET_CHECK(HDCS00_SROWEXPL, srowexp & 0xFF); /* Number of pixels to expose */ + I2C_SET_CHECK(HDCS00_SROWEXPH, srowexp >> 8); + } + if (IS_1020(qc)) { + I2C_SET_CHECK(HDCS20_ERROR, BIT(0)); /* Reset exposure error flag */ + } else { + I2C_SET_CHECK(HDCS_STATUS, BIT(4)); /* Reset exposure error flag */ + } + I2C_SET_CHECK(control, BIT(2)); /* Restart grabbing */ + if ((r = qc_i2c_break(qc))<0) goto fail; +#if 0 + /* Warning: the code below will cause about 0.1 second delay and may cause lost frames */ + if (PARANOID) { + /* Check if the new exposure setting is valid */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + if (IS_1020(qc)) { + if ((r = qc_get_i2c(qc,qc->sensor_data.sensor, HDCS20_ERROR))<0) goto fail; + if (r & BIT(0)) PDEBUG("exposure error (1020)"); + } else { + if ((r = qc_get_i2c(qc,qc->sensor_data.sensor, HDCS_STATUS))<0) goto fail; + if (r & BIT(4)) PDEBUG("exposure error (1000)"); + } + } + if ((r = qc_i2c_wait(qc))<0) goto fail; +#endif + qc_frame_flush(qc); +fail: return (r<0) ? r : 0; +} +/* }}} */ +/* {{{ [fold] hdcs_set_gains: Set gains */ +static int hdcs_set_gains(struct quickcam *qc, unsigned int hue, unsigned int sat, unsigned int val) +{ + static const unsigned int min_gain = 8; + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int rgain, bgain, ggain; + int r; + qc_hsv2rgb(hue, sat, val, &rgain, &bgain, &ggain); + rgain >>= 8; /* After this the values are 0..255 */ + ggain >>= 8; + bgain >>= 8; + rgain = MAX(rgain, min_gain); /* Do not allow very small values, they cause bad (low-contrast) image */ + ggain = MAX(ggain, min_gain); + bgain = MAX(bgain, min_gain); + if (rgain==sd->rgain && ggain==sd->ggain && bgain==sd->bgain) return 0; + sd->rgain = rgain; + sd->ggain = ggain; + sd->bgain = bgain; + if (rgain > 127) rgain = rgain/2 | BIT(7); /* Bit 7 doubles the programmed values */ + if (ggain > 127) ggain = ggain/2 | BIT(7); /* Double programmed value if necessary */ + if (bgain > 127) bgain = bgain/2 | BIT(7); + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(HDCS_ERECPGA, ggain); + I2C_SET_CHECK(HDCS_EROCPGA, rgain); + I2C_SET_CHECK(HDCS_ORECPGA, bgain); + I2C_SET_CHECK(HDCS_OROCPGA, ggain); +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_set_levels() */ +static int hdcs_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat) +{ + int r = 0; +//#if !HDCS_COMPRESS + if ((r = hdcs_set_exposure(qc, gain))<0) goto fail; +//#endif + hdcs_set_gains(qc, hue, sat, exp); +fail: return r; +} +/* }}} */ +/* {{{ [fold] hdcs_set_size: Sets the size of the capture window */ +/* + * Sets the size (scaling) of the capture window. + * If subsample could return the image size we use subsample. + */ +static int hdcs_set_size(struct quickcam *qc, unsigned int width, unsigned int height) +{ + /* The datasheet doesn't seem to say this, but HDCS-1000 + * has visible windows size of 360x296 pixels, the first upper-left + * visible pixel is at 8,8. + * From Andrey's test image: looks like HDCS-1020 upper-left + * visible pixel is at 24,8 (y maybe even smaller?) and lower-right + * visible pixel at 375,299 (x maybe even larger?) + */ + unsigned int originx = IS_1020(qc) ? 24 : 8; /* First visible pixel */ + unsigned int maxwidth = IS_1020(qc) ? 352 : 360; /* Visible sensor size */ + unsigned int originy = 8; + unsigned int maxheight = IS_1020(qc) ? 292 : 296; + + unsigned char control = GET_CONTROL; + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + unsigned int x, y; + +#if HDCS_COMPRESS + return 0; +#endif + if (sd->subsample) { + width *= 2; + height *= 2; + width = (width + 3)/4*4; /* Width must be multiple of 4 */ + height = (height + 3)/4*4; /* Height must be multiple of 4 */ + sd->width = width / 2; + sd->height = height / 2; /* The image sent will be subsampled by 2 */ + } else { + sd->width = width = (width + 3)/4*4; /* Width must be multiple of 4 */ + sd->height = height = (height + 3)/4*4; /* Height must be multiple of 4 */ + } + x = (maxwidth - width)/2; /* Center image by computing upper-left corner */ + y = (maxheight - height)/2; + width /= 4; + height /= 4; + x = (x + originx)/4; /* Must be multiple of 4 (low bits wired to 0) */ + y = (y + originy)/4; + + if ((r = qc_i2c_break(qc))<0) goto fail; + I2C_SET_CHECK(control, 0); /* Stop grabbing */ + I2C_SET_CHECK(HDCS_FWROW, y); + I2C_SET_CHECK(HDCS_FWCOL, x); + I2C_SET_CHECK(HDCS_LWROW, y+height-1); + I2C_SET_CHECK(HDCS_LWCOL, x+width-1); + I2C_SET_CHECK(control, BIT(2)); /* Restart grabbing */ + + /* The exposure timings need to be recomputed when size is changed */ + x = sd->exposure; + sd->exposure = -1; + if ((r = hdcs_set_exposure(qc, x))<0) goto fail; +fail: return r; +} +/* }}} */ + +/* {{{ [fold] struct qc_sensor qc_sensor_hdcs1000 */ +const struct qc_sensor qc_sensor_hdcs1000 = { + name: "HDCS-1000/1100", + manufacturer: "Hewlett Packard", + init: hdcs_init, + start: hdcs_start, + stop: hdcs_stop, + set_size: hdcs_set_size, + set_levels: hdcs_set_levels, + /* Exposure and gain control information */ + autoexposure: FALSE, + adapt_gainlow: 20, + adapt_gainhigh: 20000, + /* Information needed to access the sensor via I2C */ + reg23: 0, + i2c_addr: HDCS_ADDR, + /* Identification information used for auto-detection */ + id_reg: HDCS_IDENT | 1, + id: 0x08, + length_id: 1, + flag: 0, +}; +/* }}} */ +/* {{{ [fold] struct qc_sensor qc_sensor_hdcs1020 */ +const struct qc_sensor qc_sensor_hdcs1020 = { + name: "HDCS-1020", + manufacturer: "Agilent Technologies", + init: hdcs_init, + start: hdcs_start, + stop: hdcs_stop, + set_size: hdcs_set_size, + set_levels: hdcs_set_levels, + /* Exposure and gain control information */ + autoexposure: FALSE, + adapt_gainlow: 20, + adapt_gainhigh: 20000, + /* Information needed to access the sensor via I2C */ + reg23: 0, + i2c_addr: HDCS_ADDR, + /* Identification information used for auto-detection */ + id_reg: HDCS_IDENT | 1, + id: 0x10, + length_id: 1, + flag: 1, +}; +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-memory.c +++ linux-2.6.28/ubuntu/qc-usb/qc-memory.c @@ -0,0 +1,252 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * memory.c - contains all needed memory management functions + * + * 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 + * + */ + +/* These routines have been derived from the ov511 driver, into which they + * were derived from the bttv driver. + */ +/* }}} */ +/* {{{ [fold] Includes */ +#include +#include + +#ifdef CONFIG_SMP +#define __SMP__ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif +#ifdef MODVERSIONS +#include +#endif +#endif + +#include "qc-memory.h" +#include +#include /* Required on Alpha, from Bob McElrath */ +#include /* Required on Alpha */ +#include /* Required on Alpha */ +#include /* pmd_offset requires this on SuSE supplied kernels */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) +#include /* For proper mem_map_(un)reserve define, the compatibility define below might not work */ +#endif +/* }}} */ +/* {{{ [fold] Compatibility wrappers */ +#ifndef HAVE_VMA +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,3) || (defined(RED_HAT_LINUX_KERNEL) && defined(pte_offset_map)) +#define HAVE_VMA 1 +#else +#define HAVE_VMA 0 +#endif +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +#if HAVE_VMA +#warning "HAVE_VMA=1" +/* remap_page_range is still emulated in 2.6.10, in 2.6.11 it's completely removed */ +static inline int qc_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long pfn, unsigned long size, pgprot_t prot) { return remap_page_range(vma, from, pfn<=KERNEL_VERSION(2,5,3) || defined(pte_offset_map) +#define pte_offset(pmd,adr) pte_offset_map(pmd,adr) /* Emulation for a kernel using the new rmap-vm */ +#endif /* Fix by Michele Balistreri */ + +/* }}} */ + +/* {{{ [fold] kvirt_to_pa(): obtain physical address from virtual address obtained by vmalloc() */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +/* {{{ [fold] kvirt_to_pa(), 2.4.x and 2.6.x */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19) +static struct page *vmalloc_to_page(void * vmalloc_addr); +#endif + +/* Here we want the physical address of the memory obtained by vmalloc(). + */ +static inline unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long kva, ret; + + kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); + kva |= adr & (PAGE_SIZE-1); /* restore the offset */ + ret = __pa(kva); + return ret; +} +/* }}} */ +#else +/* {{{ [fold] kvirt_to_pa() for 2.2.x */ +#define page_address(x) (x | PAGE_OFFSET) /* Damn ugly hack from kcomp.h; replaces original page_address() that made different thing! */ + +/* Given PGD from the address space's page table, return the kernel + * virtual mapping of the physical memory mapped at ADR. + */ +static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) +{ + unsigned long ret = 0UL; + pmd_t *pmd; + pte_t *ptep, pte; + + if (!pgd_none(*pgd)) { + pmd = pmd_offset(pgd, adr); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, adr); + pte = *ptep; + if (pte_present(pte)) { + ret = (unsigned long) page_address(pte_page(pte)); + ret |= (adr & (PAGE_SIZE - 1)); + } + } + } + + return ret; +} + +/* Here we want the physical address of the memory obtained by vmalloc(). + * This is used when initializing the contents of the + * area and marking the pages as reserved. + */ +static unsigned long kvirt_to_pa(unsigned long adr) +{ + unsigned long va, kva, ret; + + va = VMALLOC_VMADDR(adr); + kva = uvirt_to_kva(pgd_offset_k(va), va); + ret = __pa(kva); + return ret; +} +/* }}} */ +#endif +/* }}} */ +/* {{{ [fold] vmalloc_to_page(): obtain pointer to struct page from virtual address obtained by vmalloc() */ +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,4,0) && LINUX_VERSION_CODE 0) { + SetPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + return mem; +} +/* }}} */ +/* {{{ [fold] qc_mm_rvfree(mem, size) */ +void qc_mm_rvfree(void *mem, unsigned long size) +{ + unsigned long adr; + + if (!mem) + return; + + adr = (unsigned long) mem; + while ((long) size > 0) { + ClearPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + vfree(mem); +} +/* }}} */ +/* {{{ [fold] qc_mm_remap(vma, src, src_size, dst, dst_size) */ +int qc_mm_remap(struct vm_area_struct *vma, void *src, unsigned long src_size, const void *dst, unsigned long dst_size) +{ + unsigned long start = (unsigned long)dst; + unsigned long size = dst_size; + unsigned long physaddr, pos; + + pos = (unsigned long)src; + while ((long)size > 0) { + physaddr = kvirt_to_pa(pos); +#if 1 + if ((physaddr & ~PAGE_MASK)!=0) { + printk(KERN_CRIT "qc_mm_remap: physaddr=%08X not page aligned!\n", (int)physaddr); + return -EIO; + } +#endif + if (remap_pfn_range(vma, start, physaddr>>PAGE_SHIFT, PAGE_SIZE, PAGE_SHARED)) + return -EAGAIN; + start += PAGE_SIZE; + pos += PAGE_SIZE; + size -= PAGE_SIZE; + } + return 0; +} +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/quickcam.h +++ linux-2.6.28/ubuntu/qc-usb/quickcam.h @@ -0,0 +1,585 @@ +#ifndef _LINUX_QUICKCAM_H +#define _LINUX_QUICKCAM_H + +/* {{{ [fold] SECTION: common definitions with userspace applications */ +#define QC_LUT_SIZE (3*256) /* Lookup table definition for equalization */ +#define QC_LUT_RED 0 +#define QC_LUT_GREEN 256 +#define QC_LUT_BLUE 512 + +struct qc_userlut { + unsigned int flags; +#define QC_USERLUT_DEFAULT 1 /* If set, change default settings or the current camera otherwise */ +#define QC_USERLUT_ENABLE 2 /* If set, enable user-specified LUT, or otherwise disable it */ +#define QC_USERLUT_VALUES 4 /* Load new (or store old) values into the lookup-table */ + unsigned char lut[QC_LUT_SIZE]; /* Lookup table to set or read */ +}; + +#define VIDEO_PALETTE_BAYER (('q'<<8) | 1) /* Grab video in raw Bayer format */ +#define VIDEO_PALETTE_MJPEG (('q'<<8) | 2) /* Grab video in compressed MJPEG format */ +#define VID_HARDWARE_QCAM_USB (('q'<<8) | 50) /* Device type */ + +/* Private IOCTL calls */ +#define QC_IOCTLBASE 220 /* Don't use same numbers as Philips driver */ +#define VIDIOCQCGDEBUG _IOR ('v',QC_IOCTLBASE+0, int) /* Gets the debug output, bitfield */ +#define VIDIOCQCSDEBUG _IOWR('v',QC_IOCTLBASE+0, int) /* Sets the debug output, bitfield */ +#define VIDIOCQCGKEEPSETTINGS _IOR ('v',QC_IOCTLBASE+1, int) /* Get keep picture settings across one open to another (0-1) */ +#define VIDIOCQCSKEEPSETTINGS _IOWR('v',QC_IOCTLBASE+1, int) /* Set keep picture settings across one open to another (0-1) */ +#define VIDIOCQCGSETTLE _IOR ('v',QC_IOCTLBASE+2, int) /* Get if we let image brightness settle (0-1) */ +#define VIDIOCQCSSETTLE _IOWR('v',QC_IOCTLBASE+2, int) /* Set if we let image brightness settle (0-1) */ +#define VIDIOCQCGSUBSAMPLE _IOR ('v',QC_IOCTLBASE+3, int) /* Gets the speed (0-1) */ +#define VIDIOCQCSSUBSAMPLE _IOWR('v',QC_IOCTLBASE+3, int) /* Sets the speed (0-1) */ +#define VIDIOCQCGCOMPRESS _IOR ('v',QC_IOCTLBASE+4, int) /* Gets the compression mode (0-1) */ +#define VIDIOCQCSCOMPRESS _IOWR('v',QC_IOCTLBASE+4, int) /* Sets the compression mode (0-1) */ +#define VIDIOCQCGFRAMESKIP _IOR ('v',QC_IOCTLBASE+5, int) /* Get frame capture frequency (0-10) */ +#define VIDIOCQCSFRAMESKIP _IOWR('v',QC_IOCTLBASE+5, int) /* Set frame capture frequency (0-10) */ +#define VIDIOCQCGQUALITY _IOR ('v',QC_IOCTLBASE+6, int) /* Gets the interpolation mode (0-2) */ +#define VIDIOCQCSQUALITY _IOWR('v',QC_IOCTLBASE+6, int) /* Sets the interpolation mode (0-2) */ +#define VIDIOCQCGADAPTIVE _IOR ('v',QC_IOCTLBASE+7, int) /* Get automatic adaptive brightness control (0-1) */ +#define VIDIOCQCSADAPTIVE _IOWR('v',QC_IOCTLBASE+7, int) /* Set automatic adaptive brightness control (0-1) */ +#define VIDIOCQCGEQUALIZE _IOR ('v',QC_IOCTLBASE+8, int) /* Get equalize image (0-1) */ +#define VIDIOCQCSEQUALIZE _IOWR('v',QC_IOCTLBASE+8, int) /* Set equalize image (0-1) */ +#define VIDIOCQCGRETRYERRORS _IOR ('v',QC_IOCTLBASE+9, int) /* Get if we retry when capture fails (0-1) */ +#define VIDIOCQCSRETRYERRORS _IOWR('v',QC_IOCTLBASE+9, int) /* Set if we retry when capture fails (0-1) */ +#define VIDIOCQCGCOMPATIBLE _IOR ('v',QC_IOCTLBASE+10,int) /* Get enable workaround for bugs, bitfield */ +#define VIDIOCQCSCOMPATIBLE _IOWR('v',QC_IOCTLBASE+10,int) /* Set enable workaround for bugs, bitfield */ +#define VIDIOCQCGVIDEONR _IOR ('v',QC_IOCTLBASE+11,int) /* Get videodevice number (/dev/videoX) */ +#define VIDIOCQCSVIDEONR _IOWR('v',QC_IOCTLBASE+11,int) /* Set videodevice number (/dev/videoX) */ +#define VIDIOCQCGUSERLUT _IOR ('v',QC_IOCTLBASE+12,struct qc_userlut) /* Get user-specified lookup-table correction */ +#define VIDIOCQCSUSERLUT _IOWR('v',QC_IOCTLBASE+12,struct qc_userlut) /* Set user-specified lookup-table correction */ + +#define VIDIOCQCGSTV _IOWR('v',QC_IOCTLBASE+20,int) /* Read STV chip register */ +#define VIDIOCQCSSTV _IOW ('v',QC_IOCTLBASE+20,int) /* Write STV chip register */ +#define VIDIOCQCGI2C _IOWR('v',QC_IOCTLBASE+21,int) /* Read I2C chip register */ +#define VIDIOCQCSI2C _IOW ('v',QC_IOCTLBASE+21,int) /* Write I2C chip register */ + +/* Debugging message choices */ +#define QC_DEBUGUSER (1<<0) /* Messages for interaction with user space (system calls) */ +#define QC_DEBUGCAMERA (1<<1) /* Messages for interaction with the camera */ +#define QC_DEBUGINIT (1<<2) /* Messages for each submodule initialization/deinit */ +#define QC_DEBUGLOGIC (1<<3) /* Messages for entering and failing important functions */ +#define QC_DEBUGERRORS (1<<4) /* Messages for all error conditions */ +#define QC_DEBUGADAPTATION (1<<5) /* Messages for automatic exposure control workings */ +#define QC_DEBUGCONTROLURBS (1<<6) /* Messages for sending I2C control messages via USB */ +#define QC_DEBUGBITSTREAM (1<<7) /* Messages for finding chunk codes from camera bitstream */ +#define QC_DEBUGINTERRUPTS (1<<8) /* Messages for each interrupt */ +#define QC_DEBUGMUTEX (1<<9) /* Messages for acquiring/releasing the mutex */ +#define QC_DEBUGCOMMON (1<<10) /* Messages for some common warnings */ +#define QC_DEBUGFRAME (1<<11) /* Messages related to producer-consumer in qc_frame_* functions */ +#define QC_DEBUGALL (~0) /* Messages for everything */ + +/* Compatibility choices */ +#define QC_COMPAT_16X (1<<0) +#define QC_COMPAT_DBLBUF (1<<1) +#define QC_COMPAT_TORGB (1<<2) /* Video4Linux API is buggy and doesn't specify byte order for RGB images */ +/* }}} */ + +#ifdef __KERNEL__ + +#include +#include + +#ifdef CONFIG_SMP +#define __SMP__ +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +#if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) +#define MODVERSIONS +#endif +#ifdef MODVERSIONS +#include +#endif +#endif + +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +#include +#endif +#include +#include /* This is required for testing pte_offset_map */ +#include + +/* {{{ [fold] SECTION: user configuration */ +#define VERSION "QuickCam USB 0.6.6 $Date: 2006/11/04 08:38:14 $" +#ifndef COMPRESS +#define COMPRESS 1 /* 1=include compression support, 0=otherwise */ +#endif +#ifndef DEBUGLEVEL +#define DEBUGLEVEL QC_DEBUGCOMMON +#endif +#ifdef NDEBUG /* Enable debugging if DEBUG is defined; if (also) NDEBUG is defined, disable debugging */ +#undef DEBUG +#endif +//#define DEBUG /* Enable debug code */ +#ifdef DEBUG +#define PARANOID 1 /* Check consistency of driver state */ +#else +#define PARANOID 0 +#endif +/* Default (initial) values */ +#define DEFAULT_BGR TRUE /* Use BGR byte order by default (and torgb converts to RGB)? */ + +#define DUMPDATA 0 /* Dump data from camera to user, no conversion nor length checks (see show.c) */ +/* }}} */ +/* {{{ [fold] SECTION: general utility definitions and macros */ +#define FALSE 0 +#define TRUE (!FALSE) +typedef unsigned char Bool; +//#define BIT(x) (1<<(x)) +#define SIZE(a) (sizeof(a)/sizeof((a)[0])) +#define MAX(a,b) ((a)>(b)?(a):(b)) +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX3(a,b,c) (MAX(a,MAX(b,c))) +#define MIN3(a,b,c) (MIN(a,MIN(b,c))) +#define CLIP(a,low,high) MAX((low),MIN((high),(a))) +#define ABS(a) ((a)>0?(a):-(a)) +#define SGN(a) ((a)<0 ? -1 : ((a)>0 ? 1 : 0)) +#define CHECK_ERROR(cond,jump,msg,args...) if (cond) { PDEBUG(msg, ## args); goto jump; } +#define GET_VENDORID(qc) ((qc)->dev->descriptor.idVendor) +#define GET_PRODUCTID(qc) ((qc)->dev->descriptor.idProduct) +/* }}} */ +/* {{{ [fold] SECTION: compatibility */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) +#error "Too old kernel. At least Linux 2.2.18 is required." +#endif + +#if LINUX_VERSION_CODE==KERNEL_VERSION(2,4,19) || LINUX_VERSION_CODE==KERNEL_VERSION(2,4,20) +#warning "Kernels 2.4.19 and 2.4.20 are buggy! Be sure to install patch from:" +#warning "http://www.ee.oulu.fi/~tuukkat/quickcam/linux-2.4.20-videodevfix.patch" +#endif + +#if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,0) && LINUX_VERSION_CODE=KERNEL_VERSION(2,7,0) +#warning "Unsupported kernel, may or may not work. Good luck!" +#endif + +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,4,0) && defined(CONFIG_PROC_FS) +#define HAVE_PROCFS 1 /* FIXME: I don't think there's any reason to disable procfs with 2.2.x */ +#else +#define HAVE_PROCFS 0 +#warning "procfs support disabled" +#endif + +#ifndef HAVE_VMA +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,5,3) || (defined(RED_HAT_LINUX_KERNEL) && defined(pte_offset_map)) +/* Some RedHat 9 2.4.x patched-to-death kernels need this too */ +#define HAVE_VMA 1 +#else +#define HAVE_VMA 0 +#endif +#endif + +#if HAVE_VMA && LINUX_VERSION_CODE=KERNEL_VERSION(2,6,0) +/* Things come and go... */ +/* Used only for debugging, so this could be actually removed if needed */ +#define sem_getcount(sem) atomic_read(&(sem)->count) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +static inline int qc_usb_submit_urb(struct urb *urb) { return usb_submit_urb(urb); } +static inline struct urb *qc_usb_alloc_urb(int packets) { return usb_alloc_urb(packets); } +#undef usb_submit_urb +#undef usb_alloc_urb +#define usb_submit_urb(u,f) qc_usb_submit_urb(u) +#define usb_alloc_urb(u,f) qc_usb_alloc_urb(u) +#define URB_ISO_ASAP USB_ISO_ASAP +#endif + +#ifndef list_for_each_entry +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#undef MOD_INC_USE_COUNT +#undef MOD_DEC_USE_COUNT +#define MOD_INC_USE_COUNT +#define MOD_DEC_USE_COUNT +#define GET_USE_COUNT(module) 1 +#define EXPORT_NO_SYMBOLS +#endif + +/* }}} */ +/* {{{ [fold] SECTION: debugging */ +#undef PDEBUG /* undef it, just in case */ +#define POISON_VAL 0x5B + +#ifdef DEBUG + +#include +/* PDEBUG is rather heavyweight macro and should be used only for debugging--not for general messages */ +/* Based on timestamp by Roger Wolff */ +#define PDEBUG(fmt, args...) \ + do { \ + struct timeval __tv_val; \ + do_gettimeofday(&__tv_val); \ + printk(KERN_DEBUG "quickcam [%2ld.%06ld]: ", __tv_val.tv_sec%60, __tv_val.tv_usec); \ + printk(fmt, ## args); \ + printk("\n"); \ + } while(0) +#define IDEBUG_VAR char *idebug_var; +#define IDEBUG_INIT(x) do { \ + if ((x).idebug_var==((char*)&((x).idebug_var)) + 0xB967E57D) printk(KERN_CRIT __FILE__ ":%i: Init already done\n",__LINE__); \ + (x).idebug_var = ((char*)&((x).idebug_var)) + 0xB967E57D; \ +} while(0) +#define IDEBUG_TEST(x) do { \ + if ((x).idebug_var!=((char*)&((x).idebug_var)) + 0xB967E57D) printk(KERN_CRIT __FILE__ ":%i: Init missing\n",__LINE__); \ +} while(0) +#define IDEBUG_EXIT(x) do { \ + IDEBUG_TEST(x); \ + (x).idebug_var = NULL; \ + POISON(x); \ +} while(0) +#define IDEBUG_EXIT_NOPOISON(x) do { \ + IDEBUG_TEST(x); \ + (x).idebug_var = NULL; \ +} while(0) +#define TEST_BUG(condition) \ + do { \ + if ((condition)!=0) { \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return; \ + } \ + } while (0) +#define TEST_BUGR(condition) \ + do { \ + if ((condition)!=0) { \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return -EFAULT; \ + } \ + } while (0) +#define TEST_BUG_MSG(cond, fmt, args...) \ + do { \ + if ((cond)!=0) { \ + PDEBUG(fmt, ## args); \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return; \ + } \ + } while (0) +#define TEST_BUGR_MSG(cond, fmt, args...) \ + do { \ + if ((cond)!=0) { \ + PDEBUG(fmt, ## args); \ + PDEBUG("Badness in %s at %s:%d", __FUNCTION__, __FILE__, __LINE__); \ + return -EFAULT; \ + } \ + } while (0) +#define POISON(obj) do { memset(&(obj),POISON_VAL,sizeof(obj)); } while(0) + +#else + +#define PDEBUG(fmt, args...) +#define IDEBUG_VAR +#define IDEBUG_INIT(x) +#define IDEBUG_TEST(x) +#define IDEBUG_EXIT(x) +#define IDEBUG_EXIT_NOPOISON(x) +#define TEST_BUG(x) +#define TEST_BUGR(x) +#define TEST_BUG_MSG(cond, fmt, args...) +#define TEST_BUGR_MSG(cond, fmt, args...) +#define POISON(obj) + +#endif /* DEBUG */ + +//gcc is buggy? This doesn't work +//#define PRINTK(lvl, fmt, args...) printk(lvl "quickcam: " fmt "\n", ## args) +#define PRINTK(lvl, fmt, args...) do { printk(lvl "quickcam: " fmt, ## args); printk("\n"); } while (0) +/* }}} */ +/* {{{ [fold] SECTION: hardware related stuff */ +#define QUICKCAM_ISOPIPE 0x81 + +/* Control register of the STV0600 ASIC */ +#define STV_ISO_ENABLE 0x1440 +#define STV_SCAN_RATE 0x1443 +#define STV_ISO_SIZE 0x15C1 +#define STV_Y_CTRL 0x15C3 +#define STV_X_CTRL 0x1680 +#define STV_REG00 0x1500 +#define STV_REG01 0x1501 +#define STV_REG02 0x1502 +#define STV_REG03 0x1503 +#define STV_REG04 0x1504 +#define STV_REG23 0x0423 + +/* Maximum frame size that any sensor can deliver */ +#define MAX_FRAME_WIDTH 360 +#define MAX_FRAME_HEIGHT 296 +/* }}} */ +/* {{{ [fold] SECTION: struct quickcam datatype and related values */ + +/* {{{ [fold] qc_sensor_data: Sensor related data (unique to each camera) */ +struct qc_sensor_data { + const struct qc_sensor *sensor; /* Autodetected when camera is plugged in */ + int maxwidth; /* Maximum size the sensor can deliver */ + int maxheight; + int width; /* Size delivered by the sensor (-1=unknown) */ + int height; + int exposure; /* Current exposure in effect (sensor-specific value, -1=unknown) */ + int rgain, ggain, bgain; /* Current gains in effect (sensor-specific values, -1=unknown) */ + unsigned int subsample : 1; /* Set into subsampling mode? */ + unsigned int compress : 1; /* Set into compressed mode? */ +}; +/* }}} */ +/* {{{ [fold] qc_i2c_data: I2C command queue for writing commands to camera */ +#define I2C_MAXCOMMANDS 16 /* Should be about 1-2 times the size of transfer buffer (=16) for maximum performance */ +#define I2C_FLAG_WORD BIT(0) /* Set if a 16-bit value is sent, otherwise 8-bit value */ +#define I2C_FLAG_BREAK BIT(1) /* Set if this is the last command in a packet */ +struct qc_i2c_data { + struct urb *urb; + struct { + u8 loval; + u8 hival; + u8 regnum; + u8 flags; + } commands[I2C_MAXCOMMANDS]; + /* 2=URB scheduled, need to schedule extra packet for QuickCam Web at completion */ + volatile int packets; /* 0=no URBs scheduled, 1=URB scheduled */ + volatile unsigned int newhead; /* Points to first free buffer position */ + volatile unsigned int head; /* Points to oldest command which was not yet flushed */ + volatile unsigned int tail; /* Points to next position which needs to be send, modified from interrupt */ + wait_queue_head_t wq; /* Woken up when all pending data is sent */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_isoc_data: Isochronous transfer queue control data for reading from camera */ +#define ISOC_URBS 2 /* Number of URBs to use */ +#define ISOC_PACKETS 10 /* How many isochronous data packets per URB */ +#define ISOC_PACKET_SIZE 1023 /* Max size of one packet (shouldn't be hardcoded JFC was 960) */ +struct qc_isoc_data { + struct urb *urbs[ISOC_URBS]; + unsigned char *buffer; /* Isochronous data transfer buffers */ + int errorcount; + Bool streaming; /* TRUE if URBs are allocated and submitted */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_stream_data: Camera data stream control data */ +struct qc_stream_data { + Bool capturing; /* Are we capturing data for a frame? */ + int frameskip; /* How frequently to capture frames? 0=each frame, 1=every other */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_frame_data: Raw frame (bayer/mjpeg) buffers */ +#define FRAME_BUFFERS 2 /* We are double buffering */ +#define FRAME_DATASIZE (MAX_FRAME_WIDTH*MAX_FRAME_HEIGHT) /* About 101 kilobytes (assume that compressed frame is always smaller) */ +struct qc_frame_data { + struct { + int rawdatalen; /* Number of used bytes of this frame buffer */ + } buffers[FRAME_BUFFERS]; + unsigned char *rawdatabuf; /* vmalloc'd chunk containing the all raw frame data buffers concatenated */ + int maxrawdatalen; /* Maximum amount of data we are willing to accept in bytes, */ + /* zero indicates that we are not grabbing current frame (but just throwing data away) */ + volatile unsigned int head; /* The buffer to be captured next (empty or grabbing, if full, then whole buffer is full) */ + volatile unsigned int tail; /* The buffer to be consumed next (full, unless equals head, then it is empty/grabbing) */ + spinlock_t tail_lock; /* Protects tail changes */ + volatile Bool tail_in_use; /* TRUE, when consumer is processing the frame pointed to by tail */ + + wait_queue_head_t wq; /* Processes waiting for more data in the buffer */ + volatile int waiting; /* Number of processes waiting in the wait queues */ + volatile Bool exiting; /* Set to TRUE when we want to quit */ + volatile int lost_frames; /* Increased by one for every lost (non-captured by applications) frame, reset when a frame is captured */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_mjpeg_data: MJPEG decoding data */ +struct qc_mjpeg_data { + int depth; /* Bits per pixel in the final RGB image: 16 or 24 */ + u8 *encV; /* Temporary buffers for holding YUV image data */ + u8 *encU; + u8 *encY; + /* yuv2rgb private data */ + void *table; + void *table_rV[256]; + void *table_gU[256]; + int table_gV[256]; + void *table_bU[256]; + void (*yuv2rgb_func)(struct qc_mjpeg_data *, u8 *, u8 *, u8 *, u8 *, void *, void *, int); + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_fmt_data: Format conversion routines private data */ +struct qc_fmt_data { + unsigned char userlut[QC_LUT_SIZE]; /* User specified fixed look-up table, initialized when camera is plugged in */ + unsigned char lut[QC_LUT_SIZE]; /* Dynamically calculated LUT, for which userlut is applied to */ +#if COMPRESS + struct qc_mjpeg_data mjpeg_data; + Bool compress; /* Was compression subsystem initialized? */ +#endif + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_capt_data: Formatted image capturing control data */ +/* qc_capt_data: Formatted image capturing control data. */ +#define MAX_FRAME_SIZE (MAX_FRAME_WIDTH*MAX_FRAME_HEIGHT*4) /* Video Size 356x292x4 bytes for 0RGB 32 bpp mode */ +struct qc_capt_data { + unsigned char *frame; /* Final image data buffer given to application, size MAX_FRAME_SIZE (mmappable) */ + Bool settled; /* Has the picture settled after last open? */ + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_adapt_data: Automatic exposure control data */ +/* There are three different exposure control algorithms for different cases */ +struct qc_adapt_data { + int olddelta; + int oldmidvalue, midvaluesum; + int oldexposure, exposure; + int gain; + int framecounter; + enum { + EXPCONTROL_SATURATED, /* Picture is over/undersaturated, halve/double brightness */ + EXPCONTROL_NEWTON, /* Using Newton linear estimation */ + EXPCONTROL_FLOAT, /* Very near correct brightness, float exposure slightly */ + } controlalg; + IDEBUG_VAR +}; +/* }}} */ +/* {{{ [fold] qc_settings_data: User settings given by qcset or module parameters, initialized when camera is plugged in */ +struct qc_settings_data { + unsigned int keepsettings : 1; /* Keep all settings at each camera open (or reset most of them) */ + unsigned int subsample : 1; /* Normal or sub-sample (sub-sample to increase the speed) */ + unsigned int compress : 1; /* Enable compressed mode if available (higher framerate) */ + unsigned int frameskip : 4; /* How many frames to skip (higher=lower framerate) */ + unsigned int quality : 3; /* Quality of format conversion (higher=better but slower) */ + unsigned int adaptive : 1; /* Use automatic exposure control */ + unsigned int equalize : 1; /* Equalize images */ + unsigned int userlut : 1; /* Apply user-specified lookup-table */ + unsigned int retryerrors : 1; /* If errors happen when capturing an image, retry a few times? */ + unsigned int compat_16x : 1; /* Compatibility: force image size to multiple of 16 */ + unsigned int compat_dblbuf : 1; /* Compatibility: fake doublebuffering for applications */ + unsigned int compat_torgb : 1; /* Compatibility: use RGB data order, not BGR */ + unsigned int settle : 8; /* Maximum number of frames to wait image brightness to settle */ + /* Total: 25 bits */ +}; +/* }}} */ + +/* Main per-camera data structure, most important thing in whole driver */ +struct quickcam { + /* The following entries are initialized in qc_usb_init() when camera is plugged in */ + struct semaphore lock; /* Allow only one process to access quickcam at a time */ + struct list_head list; /* All cameras are in a doubly linked list */ + int users; /* User count (simultaneous open count) */ + struct usb_device *dev; /* USB device, set to NULL when camera disconnected and interrupts disabled */ + unsigned char iface; /* The interface number in the camera device we are bound to */ + Bool connected; /* Set to FALSE immediately when the camera is disconnected (even before interrupts are disabled) */ + struct video_device vdev; /* Used for registering the camera driver for Video4Linux */ + struct qc_settings_data settings; /* General user settings set with e.g. qcset */ +#if HAVE_PROCFS + struct proc_dir_entry *proc_entry; +#endif + /* The following entries are initialized in qc_v4l_init() when the camera device is opened */ + struct video_picture vpic; /* Contains the last values set by user (which is reported to user) */ + Bool vpic_pending; /* Settings in vpic were changed but are not yet in effect */ + struct video_window vwin; /* Contains the image size and position the user is expecting */ + + /* Private structures for each module, initialized in corresponding init-function */ + struct qc_i2c_data i2c_data; /* Filled when the camera is plugged in or driver loaded */ + struct qc_adapt_data adapt_data; /* Filled when the camera is plugged in or driver loaded */ + struct qc_sensor_data sensor_data; /* Mostly filled when the device is opened */ + struct qc_stream_data stream_data; /* Filled when the device is opened */ + struct qc_frame_data frame_data; /* Filled when the device is opened */ + struct qc_capt_data capt_data; /* Filled when the device is opened */ + struct qc_isoc_data isoc_data; /* Filled when the device is opened */ + struct qc_fmt_data fmt_data; /* Mostly filled when the device is opened, except for userlut */ + + u8 dmabuf[35]; /* Temporary buffer which may be used for DMA transfer */ +}; +/* }}} */ +/* {{{ [fold] SECTION: miscelleneous */ +/* Constant information related to a sensor type */ +struct qc_sensor { + char *name; + char *manufacturer; + int (*init)(struct quickcam *qc); /* Initialize sensor */ + int (*start)(struct quickcam *qc); /* Start sending image data */ + int (*stop)(struct quickcam *qc); /* Stop sending image data */ + int (*set_size)(struct quickcam *qc, unsigned int w, unsigned int h); /* Request camera to send the given image size */ + /* Set primary brightness value exp (usually exposure time) and HSV 0-65535 (usually gains) */ + int (*set_levels)(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat); + int (*set_target)(struct quickcam *qc, unsigned int val); /* Set target brightness for sensor autoexposure 0-65535 */ + /* Exposure and gain control information */ + Bool autoexposure; /* Sensor has automatic exposure control */ + int adapt_gainlow; /* (0-65535) How eagerly to decrease gain when necessary */ + int adapt_gainhigh; /* (0-65535) How eagerly to increase gain when necessary */ + /* Information needed to access the sensor via I2C */ + int reg23; + unsigned char i2c_addr; + /* Identification information used for auto-detection */ + int id_reg; + unsigned char id; + int length_id; + int flag; /* May be used by sensor driver for private purposes */ +}; +/* }}} */ +/* {{{ [fold] SECTION: function prototypes */ +/* USB interface chip control */ +int qc_i2c_break(struct quickcam *qc); +int qc_i2c_wait(struct quickcam *qc); +int qc_i2c_set(struct quickcam *qc, unsigned char reg, unsigned char val); +int qc_i2c_setw(struct quickcam *qc, unsigned char reg, unsigned short val); + +int qc_stv_set(struct quickcam *qc, unsigned short reg, unsigned char val); +int qc_stv_setw(struct quickcam *qc, unsigned short reg, unsigned short val); +int qc_stv_get(struct quickcam *qc, unsigned short reg); + +/* Image format conversion routines */ +int qc_fmt_convert(struct quickcam *qc, unsigned char *src, unsigned int src_len, unsigned char *dst, unsigned int dst_len, int *midvalue); +int qc_fmt_issupported(int format); +const char *qc_fmt_getname(int format); +int qc_fmt_getdepth(int format); +int qc_fmt_init(struct quickcam *qc); +void qc_fmt_exit(struct quickcam *qc); + +int qc_mjpeg_decode(struct qc_mjpeg_data *md, unsigned char *src, int src_len, unsigned char *dst); +int qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr); +void qc_mjpeg_exit(struct qc_mjpeg_data *md); + +void qc_hsv2rgb(s16 hue, u16 sat, u16 val, int *red, int *green, int *blue); +int qc_get_i2c(struct quickcam *qc, const struct qc_sensor *sensor, int reg); +void qc_frame_flush(struct quickcam *qc); + +void qc_usleep(unsigned long usec); +extern int qcdebug; /* Driver debuglevel */ +/* }}} */ + +#endif /* __KERNEL__ */ + +#endif /* __LINUX_QUICKCAM_H */ --- linux-2.6.28.orig/ubuntu/qc-usb/videodevfix.h +++ linux-2.6.28/ubuntu/qc-usb/videodevfix.h @@ -0,0 +1,15 @@ +#ifndef VIDEODEVFIX_H +#define VIDEODEVFIX_H + +#include + +typedef int8_t __s8; +typedef u_int8_t __u8; +typedef int16_t __s16; +typedef u_int16_t __u16; +typedef int32_t __s32; +typedef u_int32_t __u32; +typedef int64_t __s64; +typedef u_int64_t __u64; + +#endif --- linux-2.6.28.orig/ubuntu/qc-usb/qc-vv6410.c +++ linux-2.6.28/ubuntu/qc-usb/qc-vv6410.c @@ -0,0 +1,650 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * vv6410.c - VV6410 Sensor Implementation + * + * 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 "quickcam.h" + +#ifndef QCEGA_MODE +#define QCEGA_MODE 0 /* If the driver doesn't work for you, try changing this to "1" */ +#endif + +/* LSB bit of I2C address signifies write (0) or read (1) */ + +/* I2C Address */ +#define VV6410_ADDR (0x10<<1) + +/* {{{ [fold] I2C Registers */ +/* Status registers */ +#define VV6410_DEVICEH 0x00 /* Chip identification number including revision indicator */ +#define VV6410_DEVICEL 0x01 +#define VV6410_STATUS0 0x02 /* User can determine whether timed I2C data has been consumed by interrogating flag states */ +#define VV6410_LINECOUNTH 0x03 /* Current line counter value */ +#define VV6410_LINECOUNTL 0x04 +#define VV6410_XENDH 0x05 /* End x coordinate of image size */ +#define VV6410_XENDL 0x06 +#define VV6410_YENDH 0x07 /* End y coordinate of image size */ +#define VV6410_YENDL 0x08 +#define VV6410_DARKAVGH 0x09 /* This is the average pixel value returned from the dark line offset cancellation algorithm */ +#define VV6410_DARKAVGL 0x0A +#define VV6410_BLACKAVGH 0x0B /* This is the average pixel value returned from the black line offset cancellation algorithm */ +#define VV6410_BLACKAVGL 0x0C +#define VV6410_STATUS1 0x0D /* Flags to indicate whether the x or y image coordinates have been clipped */ + +/* Setup registers */ +#define VV6410_SETUP0 0x10 /* Low-power/sleep modes & video timing */ +#define VV6410_SETUP1 0x11 /* Various parameters */ +#define VV6410_SYNCVALUE 0x12 /* Contains pixel counter reset value used by external sync */ +#define VV6410_FGMODES 0x14 /* Frame grabbing modes (FST, LST and QCK) */ +#define VV6410_PINMAPPING 0x15 /* FST and QCK mapping modes. */ +#define VV6410_DATAFORMAT 0x16 /* Data resolution */ +#define VV6410_OPFORMAT 0x17 /* Output coding formats */ +#define VV6410_MODESELECT 0x18 /* Various mode select bits */ + +/* Exposure registers */ +#define VV6410_FINEH 0x20 /* Fine exposure. */ +#define VV6410_FINEL 0x21 +#define VV6410_COARSEH 0x22 /* Coarse exposure */ +#define VV6410_COARSEL 0x23 +#define VV6410_ANALOGGAIN 0x24 /* Analog gain setting */ +#define VV6410_CLKDIV 0x25 /* Clock division */ +#define VV6410_DARKOFFSETH 0x2C /* Dark line offset cancellation value */ +#define VV6410_DARKOFFSETL 0x2D +#define VV6410_DARKOFFSETSETUP 0x2E /* Dark line offset cancellation enable */ + +/* Colour registers (none on this camera!) */ + +/* Video timing registers */ +#define VV6410_LINELENGTHH 0x52 /* Line Length (Pixel Clocks) */ +#define VV6410_LINELENGTHL 0x53 +#define VV6410_XOFFSETH 0x57 /* X-co-ordinate of top left corner of region of interest (x-offset) */ +#define VV6410_XOFFSETL 0x58 +#define VV6410_YOFFSETH 0x59 /* Y-co-ordinate of top left corner of region of interest (y-offset) */ +#define VV6410_YOFFSETL 0x5A +#define VV6410_FIELDLENGTHH 0x61 /* Field length (Lines) */ +#define VV6410_FIELDLENGTHL 0x62 + +/* Text overlay registers (none on this camera!) */ + +/* I2C autoload registers (none on this camera!) */ + +/* System registers */ +#define VV6410_BLACKOFFSETH 0x70 /* Black offset cancellation default value */ +#define VV6410_BLACKOFFSETL 0x71 +#define VV6410_BLACKOFFSETSETUP 0x72 /* Black offset cancellation setup */ +#define VV6410_CR0 0x75 /* Analog Control Register 0 */ +#define VV6410_CR1 0x76 /* Analog Control Register 1 */ +#define VV6410_AS0 0x77 /* ADC Setup Register */ +#define VV6410_AT0 0x78 /* Analog Test Register */ +#define VV6410_AT1 0x79 /* Audio Amplifier Setup Register */ +/* }}} */ + +#define I2C_SET_CHECK(reg,val) if ((r = qc_i2c_set(qc,(reg),(val)))<0) goto fail +#define STV_SET_CHECK(reg,val) if ((r = qc_stv_set(qc,(reg),(val)))<0) goto fail +#define STV_SETW_CHECK(reg,val) if ((r = qc_stv_setw(qc,(reg),(val)))<0) goto fail +#define IS_850(qc) (GET_PRODUCTID(qc)==0x850) /* Is it QuickCam Web/Legocam? */ + +#if QCEGA_MODE +#warning "Using old compatible code (QCEGA_MODE=1)" +#warning "If this works but otherwise it doesn't work, let me know!" +static int mode = 0; +#define VV6410_CONTROL 0x10 // Setup0 +#define VV6410_GAIN 0x24 +/* {{{ [fold] vv6410_set_window() */ +static int vv6410_set_window(struct quickcam *qc, int x, int y,int width, int height) +{ + int r = 0; + + // x offset + x = MAX(1,x); + I2C_SET_CHECK(0x57,x >> 8); + I2C_SET_CHECK(0x58,x & 0xff); + + // y offset + y = MAX(1,y); + I2C_SET_CHECK(0x59,y >> 8); + I2C_SET_CHECK(0x5a,y & 0xff); + + // Set the real + if (qc->sensor_data.subsample) { + qc->sensor_data.width=180; + qc->sensor_data.height=148; + } else { + qc->sensor_data.width=356; + qc->sensor_data.height=292; + } + + // line length + if (qc->sensor_data.subsample) { + if (IS_850(qc)) + width=250; + else + width=360; /* 180 * 2 (CLK-DIV is 2) */ + } + else { + if (IS_850(qc)) + width=416; + else + width=712; /* 356 * 2 */ + } + + I2C_SET_CHECK(0x52, width >> 8); + I2C_SET_CHECK(0x53, width & 0xff); + + // field length (num lines) + if (qc->sensor_data.subsample) + height=160; /* nearest of 148 = 10 * 16 */ + else + height=320; // 304; /* nearest of 292 = 19 * 16 */ + + I2C_SET_CHECK(0x61,height >> 8); + I2C_SET_CHECK(0x62,height & 0xff); + + // usb_quickcam_i2c_add(&i2cbuff,0x25,0x02); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + return 0; +fail: + return -ENAMETOOLONG; //some silly code just for testing +} +/* }}} */ +#endif + +/* {{{ [fold] vv6410_set_size: Set window size */ +static int vv6410_set_size(struct quickcam *qc, unsigned int width, unsigned int height) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_size(qc=%p,width=%i,height=%i)",qc,width,height); + /* VV6410 appears to always give fixed 356*292 pixels */ + sd->width = sd->maxwidth; + sd->height = sd->maxheight; + return 0; +} +/* }}} */ +/* {{{ [fold] vv6410_start: Start grabbing */ +static int vv6410_start(struct quickcam *qc) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_start(qc=%p)",qc); + if (PARANOID && !qc) { PDEBUG("qc==NULL"); return -EINVAL; } + I2C_SET_CHECK(VV6410_SETUP0, sd->subsample ? (BIT(7)|BIT(6)) : 0x00); + if (IS_850(qc)) qc_stv_set(qc, 0x1445, 1); /* Turn on LED */ + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] vv6410_stop: Stop grabbing */ +static int vv6410_stop(struct quickcam *qc) +{ + static const int low_power_mode = 0; //1; + static const int sleep_mode = 1; + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned char cmd; + int r; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_stop(qc=%p)",qc); + if (IS_850(qc)) qc_stv_set(qc, 0x1445, 0); /* Turn off LED */ + cmd = (sleep_mode << 1) | low_power_mode; + if (sd->subsample) cmd |= BIT(7)|BIT(6); /* sub-sampled QCIF mode */ + I2C_SET_CHECK(VV6410_SETUP0, cmd); + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +#if COMPRESS +struct stv_init { + const u8 *data; /* If NULL, only single value to write, stored in len */ + u16 start; + u8 len; +}; +#endif +/* {{{ [fold] vv6410_init: Initialise parameters for vv6410 sensor. */ +/* Just try to send the same commands as Windoze QuickCam soft */ +static int vv6410_init(struct quickcam *qc) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + +#if COMPRESS + if (IS_850(qc)) { +/* {{{ [fold] Initialization with compression support */ + +/* {{{ [fold] [fold] stv_init[] */ + static const u8 x0540[] = { /* 0x0540 - 0x0551 */ + 0x97,0x0B,0x4C,0xFC,0x36,0x00,0x75,0x00,0x59,0x02,0x32,0x01,0x56,0xFD,0xEE,0xFF, + 0xB8,0x05 }; + static const u8 x0560[] = { /* 0x0560 - 0x0563 */ + 0x40,0xFF,0xBF,0xBF }; + static const u8 x1500[] = { /* 0x1500 - 0x150F */ + 0x0B,0xA7,0xB7,0x00,0x00,0x00,0x14,0x14,0x14,0x14,0x2B,0x02,0x2B,0x02,0x2B,0x02 }; + static const u8 x1520[] = { /* 0x1520 - 0x152A */ + 0x05,0x14,0x0F,0x0F,0x98,0x98,0x98,0x98,0x2D,0x00,0x01 }; + static const u8 x1530[] = { /* 0x1530 - 0x153B */ + 0x08,0x02,0x00,0x00,0x02,0x00,0x02,0x00,0x60,0x01,0x20,0x01 }; + static const u8 x1552[] = { /* 0x1552 - 0x1558 */ + 0x72,0x90,0x00,0xB0,0xF0,0x77,0x72 }; + static const u8 x1564[] = { /* 0x1564 - 0x1567 */ + 0x00,0xFF,0x0C,0x00 }; + static const u8 x1580[] = { /* 0x1580 - 0x158F */ + 0x02,0x40,0x01,0xF0,0x00,0xD1,0x01,0xAC,0x01,0x07,0x00,0x00,0x00,0x00,0x00,0x00 }; + static const u8 x1590[] = { /* 0x1590 - 0x15A5 */ + 0xA8,0x05,0x64,0x07,0x0F,0x03,0xD8,0x07,0xA6,0x06,0x71,0x04,0x8F,0x01,0xFF,0xFB, + 0xEC,0xE6,0xE0,0xD9,0xC4,0xB8 }; + static const u8 x15C1[] = { /* 0x15C1 - 0x15C2 */ + 0x4B, 0x02 }; /* Output word 0x024B=587 (ISO size) */ + static const struct stv_init stv_init[] = { + { NULL, 0x1620, 0x80 }, /* This reg is written twice. Some kind of reset? */ + { NULL, 0x1620, 0x00 }, + { x0540, 0x0540, SIZE(x0540) }, + { x0560, 0x0560, SIZE(x0560) }, + { NULL, 0x1423, 0x04 }, + { NULL, 0x1440, 0x00 }, + { NULL, 0x1443, 0x00 }, + { NULL, 0x1445, 0x01 }, + { x1500, 0x1500, SIZE(x1500) }, + { x1520, 0x1520, SIZE(x1520) }, + { x1530, 0x1530, SIZE(x1530) }, + { x1552, 0x1552, SIZE(x1552) }, + { x1564, 0x1564, SIZE(x1564) }, + { x1580, 0x1580, SIZE(x1580) }, + { x1590, 0x1590, SIZE(x1590) }, + { x15C1, 0x15C1, SIZE(x15C1) }, + { NULL, 0x15C3, 0x00 }, + { NULL, 0x15C9, 0x01 }, + { NULL, 0x1704, 0x00 }, + }; +/* }}} */ +/* {{{ [fold] vv_init[][2] */ + static const u8 vv_init[][2] = { + /* Setup registers */ + { VV6410_SETUP0, BIT(2) }, /* Soft reset */ + { VV6410_SETUP0, BIT(1)|BIT(0) }, /* 25 fps PAL (30 fps NTSC doesn't work!), sleep mode */ + { VV6410_SETUP1, BIT(6) }, /* Use unsuffled read-out mode */ + { VV6410_FGMODES, BIT(6)|BIT(4)|BIT(2)|BIT(0) }, /* All modes to 1 */ + { VV6410_PINMAPPING, 0x00 }, + { VV6410_DATAFORMAT, BIT(7)|BIT(0) }, /* Pre-clock generator divide off */ + { VV6410_OPFORMAT, BIT(3)|BIT(4) }, + /* Exposure registers */ + { VV6410_FINEH, 320 >> 8 }, /* Initial exposure */ + { VV6410_FINEL, 320 & 0xFF }, + { VV6410_COARSEH, 192 >> 8 }, + { VV6410_COARSEL, 192 & 0xFF }, + { VV6410_ANALOGGAIN, 0xF0 | 11 }, /* Gain to 11 */ + { VV6410_CLKDIV, 0x01 }, /* Pixel clock divisor 2 */ + /* Video timing registers */ + { VV6410_LINELENGTHH, (416-1) >> 8 }, /* Set line length (columns) to 417 */ + { VV6410_LINELENGTHL, (416-1) & 0xFF }, + { VV6410_FIELDLENGTHH, (320-1) >> 8 }, /* Set field length (rows) to 320 */ + { VV6410_FIELDLENGTHL, (320-1) & 0xFF }, + /* System registers */ + { VV6410_AS0, BIT(6)|BIT(4)|BIT(3)|BIT(2)|BIT(1) }, /* Enable voltage doubler */ + { VV6410_AT0, 0x00 }, + { VV6410_AT1, BIT(4)|BIT(0) }, /* Power up audio, differential */ + }; +/* }}} */ + + unsigned int cols = 416; + unsigned int rows = 320; + unsigned int x = 1; + unsigned int y = 1; + int i,j; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_init(qc=%p)",qc); + if (PARANOID && !qc) { PDEBUG("qc==NULL"); return -EINVAL; } + + sd->width = 320; /* Default to compressed mode */ + sd->height = 240; + + for (i=0; isubsample ? 0x10 : 0x20); /* Scan rate */ + STV_SET_CHECK(0x1446,1); + STV_SETW_CHECK(0x15C1,600); /* ISO size, 0x380|orig:600 */ + STV_SET_CHECK(0x1680,0x14); /* X ctrl */ + } + + for (i=0; icompress) { + /* Disable compression */ + STV_SET_CHECK(0x1443, sd->subsample ? 0x00 : 0x10); /* Scan rate: Larger -> slower */ + STV_SETW_CHECK(0x15C1, 1023); /* ISO-Size */ + STV_SET_CHECK(0x15C3, 1); /* Y control */ + sd->width = 356; + sd->height = 292; + if (qc->settings.subsample) { + //FIXME:subsampling (still) doesn't work yet + cols=250; + rows=160; + sd->width = 180; + sd->height = 148; + I2C_SET_CHECK(VV6410_SETUP0, BIT(7)|BIT(6)|BIT(1)|BIT(0)); /* Subsampled timing mode */ + } + } + I2C_SET_CHECK(VV6410_XOFFSETH, x >> 8); + I2C_SET_CHECK(VV6410_XOFFSETL, x & 0xFF); + I2C_SET_CHECK(VV6410_YOFFSETH, y >> 8); + I2C_SET_CHECK(VV6410_YOFFSETL, y & 0xFF); + I2C_SET_CHECK(VV6410_LINELENGTHH, (cols-1) >> 8); + I2C_SET_CHECK(VV6410_LINELENGTHL, (cols-1) & 0xFF); + I2C_SET_CHECK(VV6410_FIELDLENGTHH, (rows-1) >> 8); + I2C_SET_CHECK(VV6410_FIELDLENGTHL, (rows-1) & 0xFF); + sd->maxwidth = sd->width; + sd->maxheight = sd->height; + return 0; +/* }}} */ + } else { +#endif +/* {{{ [fold] Initialization without compression support */ + if (sd->compress) return -EINVAL; + if (sd->subsample) { + sd->maxwidth = 180; + sd->maxheight = 148; + } else { + sd->maxwidth = 356; + sd->maxheight = 292; + } + + +#if QCEGA_MODE +{ +int line_length = mode?250:416;//415; + + if (mode) { + sd->subsample=1; // quater. + sd->width = 180; + sd->height = 148; + } else { + sd->subsample=0; + sd->width = 356; + sd->height = 292; + } + + STV_SET_CHECK(STV_REG23, 5); // was 5. + + + if (!IS_850(qc)) { + /* logitech quickcam web has 0x850 as idProduct */ + STV_SET_CHECK(0x1446, 1); + } + + + STV_SET_CHECK(STV_SCAN_RATE, 0x00); + + + STV_SET_CHECK(0x1423, 0x04); + + + STV_SET_CHECK(STV_REG00, 0x1b); // 0x0b + + + + I2C_SET_CHECK(VV6410_CONTROL,0x04); // reset to defaults + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + + // CIF or QCIF and sleep. + if (IS_850(qc)) { + I2C_SET_CHECK(VV6410_CONTROL,(mode?0xa2:0x02)); + } else { + I2C_SET_CHECK(VV6410_CONTROL,(mode?0xc2:0x02)); + } + + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + I2C_SET_CHECK(VV6410_GAIN,0xfb); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + + + STV_SET_CHECK(STV_REG04, 0x07); + + + STV_SET_CHECK(STV_REG03, 0x45); + + + /* set window size */ + if ((r=vv6410_set_window(qc,0,0,48,64)) < 0) { + PRINTK(KERN_ERR, "vv6410_set_window failed"); + goto fail; + } + + + /* EXPERIMENTAL */ + /* + * line length default is 415 so it's the value we use to + * calculate values for registers 0x20-0x21 + * Ref. DS Pag. 67 + */ + I2C_SET_CHECK(0x20,mode? ((line_length-23)>>8):((line_length-51)>>8)); + + I2C_SET_CHECK(0x21,mode?((line_length-23)&0xff):((line_length-51)&0xff)); + + I2C_SET_CHECK(0x22,mode?0x00:0x01); + //usb_quickcam_i2c_add(&i2cbuff,0x23,mode?0x9e:0x3e); + I2C_SET_CHECK(0x23,mode?158:318&0xff); + I2C_SET_CHECK(0x24,0xfa); + // clock divisor. + I2C_SET_CHECK(0x25,0x01); + + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + /* + if (isaweb(dev)) + { + //EXPERIMENTAL: dark/black pixel cancellation + usb_quickcam_i2c_add(&i2cbuff,0x3e,0x01); + usb_quickcam_i2c_add(&i2cbuff,0x72,0x01); + if (usb_quickcam_i2c_send(dev,&i2cbuff,VV6410_ADDR) < 0) { + printk(KERN_ERR "usb_control_msg dark/black pixel failed"); + goto error; + } + } + */ + STV_SET_CHECK(STV_REG01, 0xb7); + + STV_SET_CHECK(STV_REG02, 0xa7); + + + + // setup + I2C_SET_CHECK(0x11,0x18); // 0x18 or Jochen 0x40 + I2C_SET_CHECK(0x14,0x55); // was 0x55 + I2C_SET_CHECK(0x15,0x10); // 0x10 or Jochen:0x00 + I2C_SET_CHECK(0x16,0x81); // Pre clock dividor. + I2C_SET_CHECK(0x17,0x18); // they are reserved. + I2C_SET_CHECK(0x18,0x00); + I2C_SET_CHECK(0x77,0x5e); + I2C_SET_CHECK(0x78,0x04);// 0x04 or Jochen:0x00 + if (IS_850(qc)) { + I2C_SET_CHECK(0x79,0x11);//audio init + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + + + + + STV_SETW_CHECK(STV_ISO_SIZE, IS_850(qc)?1023:600); // 0x380|orig:600 + + + + + STV_SET_CHECK(STV_Y_CTRL, 1); + + + STV_SET_CHECK(STV_SCAN_RATE, mode?0x00:0x10); + + + + if (!IS_850(qc)) { + /* logitech quickam web has 0x0850 as idProduct */ + STV_SET_CHECK(STV_X_CTRL, 0x14); + } +} + +#else + STV_SET_CHECK(0x0423,0x05); /* Unknown register, 0x04 or 0x05 */ + STV_SET_CHECK(0x1423,0x04); /* Unknown register, 0x04 or 0x05 */ + STV_SET_CHECK(0x1443,0x00); /* Scan rate */ + STV_SET_CHECK(0x1500,0x1B); /* 0x0B */ + STV_SET_CHECK(0x1501,0xB7); + STV_SET_CHECK(0x1502,0xA7); + STV_SET_CHECK(0x1503,0x45); + STV_SET_CHECK(0x1504,0x07); + STV_SET_CHECK(0x15C3,1); /* Y ctrl */ + if (IS_850(qc)) { + STV_SET_CHECK(0x1443, sd->subsample ? 0x20 : 0x10); /* Scan rate */ + STV_SETW_CHECK(0x15C1,1023); /* ISO size, 0x380|orig:600 */ + } else { + STV_SET_CHECK(0x1443, sd->subsample ? 0x10 : 0x20); /* Scan rate */ + STV_SET_CHECK(0x1446,1); + STV_SETW_CHECK(0x15C1,600); /* ISO size, 0x380|orig:600 */ + STV_SET_CHECK(0x1680,0x14); /* X ctrl */ + } + + I2C_SET_CHECK(0x10,0x04); /* Control register: reset to defaults */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(0x10,sd->subsample ? 0xC2 : 0x02);/* Control register: CIF or QCIF and sleep */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SET_CHECK(0x11,0x18); /* 0x18 or Jochen 0x40 */ + I2C_SET_CHECK(0x14,0x55); + I2C_SET_CHECK(0x15,0x10); /* 0x10 or Jochen:0x00 */ + I2C_SET_CHECK(0x16,0x81); /* Pre clock dividor. */ + I2C_SET_CHECK(0x17,0x18); /* they are reserved. */ + I2C_SET_CHECK(0x18,0x00); + I2C_SET_CHECK(0x24,0xFB); /* Set gain value */ + I2C_SET_CHECK(0x25,0x01); /* Clock divisor value */ + I2C_SET_CHECK(0x77,0x5E); + I2C_SET_CHECK(0x78,0x04); /* 0x04 or Jochen:0x00 */ + if (IS_850(qc)) { + I2C_SET_CHECK(0x3E,0x01); /* EXPERIMENTAL: dark/black pixel cancellation */ + I2C_SET_CHECK(0x72,0x01); + } + + if ((r = qc_i2c_wait(qc))<0) goto fail; +#endif + + return 0; +/* }}} */ +#if COMPRESS + } +#endif + +fail: return r; +} +/* }}} */ +/* {{{ [fold] vv6410_set_exposure() */ +static int vv6410_set_exposure(struct quickcam *qc, unsigned int val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + static const unsigned int linelength = 415; /* For CIF */ + unsigned int fine; + unsigned int coarse; + int r; + + val = (val*val >> 14) + val/4; + if (sd->exposure==val) return 0; + sd->exposure = val; + fine = val % linelength; + coarse = val / linelength; + if (coarse>=512) coarse = 512; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_exposure %d (%i,%i)",val,coarse,fine); + I2C_SET_CHECK(VV6410_FINEH, fine >> 8); + I2C_SET_CHECK(VV6410_FINEL, fine & 0xFF); + I2C_SET_CHECK(VV6410_COARSEH, coarse >> 8); + I2C_SET_CHECK(VV6410_COARSEL, coarse & 0xFF); +fail: return r; +} +/* }}} */ +/* {{{ [fold] vv6410_set_gains() */ +static int vv6410_set_gains(struct quickcam *qc, unsigned int hue, unsigned int sat, unsigned int val) +{ + static const int maxgain = 13; /* Absolute maximum is 14, recommended is 12 */ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int gain; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("vv6410_set_gains %d %d %d", hue, sat, val); + gain = val / 256; + gain >>= 4; + if (gain > maxgain) gain = maxgain; + if (sd->rgain==gain) return 0; + sd->rgain = gain; + r = qc_i2c_set(qc, VV6410_ANALOGGAIN, 0xF0 | gain); + return r; +} +/* }}} */ +/* {{{ [fold] vv6410_set_levels() */ +static int vv6410_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat) +{ + int r; + if ((r = vv6410_set_exposure(qc, exp))<0) goto fail; + vv6410_set_gains(qc, hue, sat, gain); +fail: return r; +} +/* }}} */ + +/* {{{ [fold] struct qc_sensor qc_sensor_vv6410 */ +const struct qc_sensor qc_sensor_vv6410 = { + name: "VV6410", + manufacturer: "ST Microelectronics", + init: vv6410_init, + start: vv6410_start, + stop: vv6410_stop, + set_size: vv6410_set_size, + set_levels: vv6410_set_levels, + /* Exposure and gain control information */ + autoexposure: FALSE, + adapt_gainlow: 40000, + adapt_gainhigh: 65535, + /* Information needed to access the sensor via I2C */ + reg23: 5, + i2c_addr: VV6410_ADDR, + /* Identification information used for auto-detection */ + id_reg: VV6410_DEVICEH, + id: 0x19, + length_id: 1, +}; +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-mjpeg.c +++ linux-2.6.28/ubuntu/qc-usb/qc-mjpeg.c @@ -0,0 +1,1936 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * MJPEG decompression routines are from mpeg2dec, + * Copyright (C) 1999-2001 Aaron Holtzman + * Modified by Tuukka Toivonen and Jochen Hoenicke. + * + * Portions of this code are from the MPEG software simulation group + * idct implementation. This code will be replaced with a new + * implementation soon. + * + * The MJPEG routines are from mpeg2dec, a free MPEG-2 video stream decoder. + * + * mpeg2dec 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. + * + * mpeg2dec 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 "quickcam.h" + +#ifdef __KERNEL__ /* show.c will include this file directly into compilation for userspace */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#include +#else +#include +#endif +#endif /* __KERNEL__ */ + +#if COMPRESS +/* {{{ [fold] **** qc_mjpeg_yuv2rgb: MJPEG decoding: YUV to RGB conversion routines *************** */ + +/* {{{ [fold] Macros */ +#define MODE_RGB 1 +#define MODE_BGR 2 + +#define RGB(i) \ + U = pu[i]; \ + V = pv[i]; \ + r = md->table_rV[V]; \ + g = (void *)(((u8 *)md->table_gU[U]) + md->table_gV[V]);\ + b = md->table_bU[U]; + +#define DST1(i) \ + Y = py_1[2*i]; \ + dst_1[2*i] = r[Y] + g[Y] + b[Y]; \ + Y = py_1[2*i+1]; \ + dst_1[2*i+1] = r[Y] + g[Y] + b[Y]; + +#define DST2(i) \ + Y = py_2[2*i]; \ + dst_2[2*i] = r[Y] + g[Y] + b[Y]; \ + Y = py_2[2*i+1]; \ + dst_2[2*i+1] = r[Y] + g[Y] + b[Y]; + +#define DST1RGB(i) \ + Y = py_1[2*i]; \ + dst_1[6*i] = r[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = b[Y]; \ + Y = py_1[2*i+1]; \ + dst_1[6*i+3] = r[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = b[Y]; + +#define DST2RGB(i) \ + Y = py_2[2*i]; \ + dst_2[6*i] = r[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = b[Y]; \ + Y = py_2[2*i+1]; \ + dst_2[6*i+3] = r[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = b[Y]; + +#define DST1BGR(i) \ + Y = py_1[2*i]; \ + dst_1[6*i] = b[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = r[Y]; \ + Y = py_1[2*i+1]; \ + dst_1[6*i+3] = b[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = r[Y]; + +#define DST2BGR(i) \ + Y = py_2[2*i]; \ + dst_2[6*i] = b[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = r[Y]; \ + Y = py_2[2*i+1]; \ + dst_2[6*i+3] = b[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = r[Y]; +/* }}} */ + +/* {{{ [fold] qc_mjpeg_yuv2rgb_32() */ +static void qc_mjpeg_yuv2rgb_32(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u32 *r, *g, *b; + u32 *dst_1, *dst_2; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_32(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1(0); + DST2(0); + + RGB(1); + DST2(1); + DST1(1); + + RGB(2); + DST1(2); + DST2(2); + + RGB(3); + DST2(3); + DST1(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 8; + dst_2 += 8; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_32() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_24rgb() */ +/* This is very near from the yuv2rgb_32 code */ +static void qc_mjpeg_yuv2rgb_24rgb(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u8 *r, *g, *b; + u8 *dst_1, *dst_2; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24rgb(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1RGB(0); + DST2RGB(0); + + RGB(1); + DST2RGB(1); + DST1RGB(1); + + RGB(2); + DST1RGB(2); + DST2RGB(2); + + RGB(3); + DST2RGB(3); + DST1RGB(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 24; + dst_2 += 24; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24rgb() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_24bgr() */ +/* only trivial mods from yuv2rgb_24rgb */ +static void qc_mjpeg_yuv2rgb_24bgr(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u8 *r, *g, *b; + u8 *dst_1, *dst_2; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24bgr(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1BGR(0); + DST2BGR(0); + + RGB(1); + DST2BGR(1); + DST1BGR(1); + + RGB(2); + DST1BGR(2); + DST2BGR(2); + + RGB(3); + DST2BGR(3); + DST1BGR(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 24; + dst_2 += 24; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_24bgr() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_16() */ +/* This is exactly the same code as yuv2rgb_32 except for the types of */ +/* r, g, b, dst_1, dst_2 */ +static void qc_mjpeg_yuv2rgb_16(struct qc_mjpeg_data *md, u8 *py_1, u8 *py_2, u8 *pu, u8 *pv, + void *_dst_1, void *_dst_2, int width) +{ + int U, V, Y; + u16 *r, *g, *b; + u16 *dst_1, *dst_2; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_16(md=%p, py_1=%p, py_2=%p, pu=%p, pv=%p, _dst_1=%p, _dst_2=%p, width=%i",md,py_1,py_2,pu,pv,_dst_1,_dst_2,width); + width >>= 3; + dst_1 = _dst_1; + dst_2 = _dst_2; + + do { + RGB(0); + DST1(0); + DST2(0); + + RGB(1); + DST2(1); + DST1(1); + + RGB(2); + DST1(2); + DST2(2); + + RGB(3); + DST2(3); + DST1(3); + + pu += 4; + pv += 4; + py_1 += 8; + py_2 += 8; + dst_1 += 8; + dst_2 += 8; + } while (--width); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_16() done"); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb() */ +/* Convert YUV image to RGB */ +static void qc_mjpeg_yuv2rgb(struct qc_mjpeg_data *md, void *dst, u8 *py, u8 *pu, u8 *pv, + int width, int height, int rgb_stride, int y_stride, int uv_stride) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb(md=%p, dst=%p, py=%p, pu=%p, pv=%p, width=%i, height=%i, rgb_stride=%i, y_stride=%i, uv_stride=%i",md,dst,py,pu,pv,width,height,rgb_stride,y_stride,uv_stride); + height >>= 1; + do { + md->yuv2rgb_func(md, py, py + y_stride, pu, pv, dst, ((u8 *)dst) + rgb_stride, width); + py += 2 * y_stride; + pu += uv_stride; + pv += uv_stride; + dst = ((u8 *)dst) + 2 * rgb_stride; + } while (--height); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb() done"); +} +/* }}} */ + +static const u32 matrix_coefficients = 6; +static const s32 Inverse_Table_6_9[8][4] = { + { 117504, 138453, 13954, 34903 }, /* 0: no sequence_display_extension */ + { 117504, 138453, 13954, 34903 }, /* 1: ITU-R Rec. 709 (1990) */ + { 104597, 132201, 25675, 53279 }, /* 2: unspecified */ + { 104597, 132201, 25675, 53279 }, /* 3: reserved */ + { 104448, 132798, 24759, 53109 }, /* 4: FCC */ + { 104597, 132201, 25675, 53279 }, /* 5: ITU-R Rec. 624-4 System B, G */ + { 104597, 132201, 25675, 53279 }, /* 6: SMPTE 170M */ + { 117579, 136230, 16907, 35559 } /* 7: SMPTE 240M (1987) */ +}; + +/* {{{ [fold] div_round(int dividend, int divisor) */ +static int div_round(int dividend, int divisor) +{ + if (dividend > 0) + return (dividend + (divisor>>1)) / divisor; + else + return -((-dividend + (divisor>>1)) / divisor); +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_init(struct qc_mjpeg_data *md, int bpp, int mode) */ +/* Initialization of yuv2rgb routines. Return error code if failure */ +static inline int qc_mjpeg_yuv2rgb_init(struct qc_mjpeg_data *md, int bpp, int mode) +{ + static const int table_Y_size = 1024; + u8 *table_Y; + int i, ret = -ENOMEM; + int entry_size = 0; + void *table_r = NULL, *table_g = NULL, *table_b = NULL; + int crv = Inverse_Table_6_9[matrix_coefficients][0]; + int cbu = Inverse_Table_6_9[matrix_coefficients][1]; + int cgu = -Inverse_Table_6_9[matrix_coefficients][2]; + int cgv = -Inverse_Table_6_9[matrix_coefficients][3]; + u32 *table_32; + u16 *table_16; + u8 *table_8; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_init(md=%p, bpp=%i, mode=%i)",md,bpp,mode); + table_Y = kmalloc(table_Y_size,GFP_KERNEL); /* Allocate with kmalloc(), it might not fit into stack */ + if (table_Y==NULL) return -ENOMEM; + + for (i=0; i<1024; i++) { + int j; + j = (76309 * (i - 384 - 16) + 32768) >> 16; + j = (j < 0) ? 0 : ((j > 255) ? 255 : j); + table_Y[i] = j; + } + + switch (bpp) { + case 32: + md->yuv2rgb_func = qc_mjpeg_yuv2rgb_32; + table_32 = md->table = kmalloc((197 + 2*682 + 256 + 132) * sizeof(u32), GFP_KERNEL); /* 0..1948 x 4 */ + if (!md->table) goto fail; + entry_size = sizeof(u32); + table_r = table_32 + 197; /* R: -197..1751 */ + table_b = table_32 + 197 + 685; /* B: -882..1066 */ + table_g = table_32 + 197 + 2*682; /* G: -1561..387 */ + for (i=-197; i<256+197; i++) /* Ri = -197...452 */ + ((u32 *) table_r)[i] = table_Y[i+384] << ((mode==MODE_RGB) ? 16 : 0); + for (i=-132; i<256+132; i++) /* Gi = -132...387 */ + ((u32 *) table_g)[i] = table_Y[i+384] << 8; + for (i=-232; i<256+232; i++) /* Bi = -232...487 */ + ((u32 *) table_b)[i] = table_Y[i+384] << ((mode==MODE_RGB) ? 0 : 16); + break; + case 24: + md->yuv2rgb_func = (mode==MODE_RGB) ? qc_mjpeg_yuv2rgb_24rgb : qc_mjpeg_yuv2rgb_24bgr; + table_8 = md->table = kmalloc((256 + 2*232) * sizeof(u8), GFP_KERNEL); /* 0..719 x 1 */ + if (!md->table) goto fail; + entry_size = sizeof(u8); + table_r = table_g = table_b = table_8 + 232; /* -232..487 */ + for (i=-232; i<256+232; i++) /* i = -232..487 */ + ((u8 *)table_b)[i] = table_Y[i+384]; + break; + case 15: + case 16: + md->yuv2rgb_func = qc_mjpeg_yuv2rgb_16; + table_16 = md->table = kmalloc((197 + 2*682 + 256 + 132) * sizeof(u16), GFP_KERNEL); /* 0..1948 x 2 */ + if (!md->table) goto fail; + entry_size = sizeof(u16); + table_r = table_16 + 197; /* R: -197..1751 */ + table_b = table_16 + 197 + 685; /* B: -882..1066 */ + table_g = table_16 + 197 + 2*682; /* G: -1561..387 */ + for (i=-197; i<256+197; i++) { /* Ri = -197..452 */ + int j = table_Y[i+384] >> 3; + if (mode == MODE_RGB) j <<= ((bpp==16) ? 11 : 10); + ((u16 *)table_r)[i] = j; + } + for (i=-132; i<256+132; i++) { /* Gi = -132..387 */ + int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3); + ((u16 *)table_g)[i] = j << 5; + } + for (i=-232; i<256+232; i++) { /* Bi = -232..487 */ + int j = table_Y[i+384] >> 3; + if (mode == MODE_BGR) j <<= ((bpp==16) ? 11 : 10); + ((u16 *)table_b)[i] = j; + } + break; + default: + PDEBUG("%i bpp not supported by yuv2rgb", bpp); + ret = -EINVAL; + goto fail; + } + for (i=0; i<256; i++) { + md->table_rV[i] = (((u8 *)table_r) + entry_size * div_round(crv * (i-128), 76309)); + md->table_gU[i] = (((u8 *)table_g) + entry_size * div_round(cgu * (i-128), 76309)); + md->table_gV[i] = entry_size * div_round(cgv * (i-128), 76309); + md->table_bU[i] = (((u8 *)table_b) + entry_size * div_round(cbu * (i-128), 76309)); + } + ret = 0; +fail: if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_init()=%i done", ret); + if (PARANOID) memset(table_Y, POISON_VAL, table_Y_size); + kfree(table_Y); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_yuv2rgb_exit(struct qc_mjpeg_data *md) */ +static inline void qc_mjpeg_yuv2rgb_exit(struct qc_mjpeg_data *md) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_exit(md=%p)",md); + kfree(md->table); + POISON(md->table); + POISON(md->yuv2rgb_func); + POISON(md->table_rV); + POISON(md->table_gU); + POISON(md->table_bU); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_yuv2rgb_exit() done"); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_mjpeg_idct: MJPEG decoding: Inverse DCT routines ************************* */ +/**********************************************************/ +/* inverse two dimensional DCT, Chen-Wang algorithm */ +/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ +/* 32-bit integer arithmetic (8 bit coefficients) */ +/* 11 mults, 29 adds per DCT */ +/* sE, 18.8.91 */ +/**********************************************************/ +/* coefficients extended to 12 bit for IEEE1180-1990 */ +/* compliance sE, 2.1.94 */ +/**********************************************************/ + +/* this code assumes >> to be a two's-complement arithmetic */ +/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ + +#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ +#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ +#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ +#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ +#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ +#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ + +/* {{{ [fold] qc_mjpeg_idct_row(s16 *block) */ +/* row (horizontal) IDCT + * + * 7 pi 1 + * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 128 + * c[1..7] = 128*sqrt (2) + */ +static void inline qc_mjpeg_idct_row(s16 *block) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + x1 = block[4] << 11; + x2 = block[6]; + x3 = block[2]; + x4 = block[1]; + x5 = block[7]; + x6 = block[5]; + x7 = block[3]; + + /* shortcut */ + if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7)) { + block[0] = block[1] = block[2] = block[3] = block[4] = + block[5] = block[6] = block[7] = block[0]<<3; + return; + } + + x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */ + + /* first stage */ + x8 = W7 * (x4 + x5); + x4 = x8 + (W1 - W7) * x4; + x5 = x8 - (W1 + W7) * x5; + x8 = W3 * (x6 + x7); + x6 = x8 - (W3 - W5) * x6; + x7 = x8 - (W3 + W5) * x7; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6 * (x3 + x2); + x2 = x1 - (W2 + W6) * x2; + x3 = x1 + (W2 - W6) * x3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181 * (x4 + x5) + 128) >> 8; + x4 = (181 * (x4 - x5) + 128) >> 8; + + /* fourth stage */ + block[0] = (x7 + x1) >> 8; + block[1] = (x3 + x2) >> 8; + block[2] = (x0 + x4) >> 8; + block[3] = (x8 + x6) >> 8; + block[4] = (x8 - x6) >> 8; + block[5] = (x0 - x4) >> 8; + block[6] = (x3 - x2) >> 8; + block[7] = (x7 - x1) >> 8; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_idct_col(s16 *block) */ +/* column (vertical) IDCT + * + * 7 pi 1 + * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l ) + * l=0 8 2 + * + * where: c[0] = 1/1024 + * c[1..7] = (1/1024)*sqrt (2) + */ +static void inline qc_mjpeg_idct_col(s16 *block) +{ + int x0, x1, x2, x3, x4, x5, x6, x7, x8; + + /* shortcut */ + x1 = block [8*4] << 8; + x2 = block [8*6]; + x3 = block [8*2]; + x4 = block [8*1]; + x5 = block [8*7]; + x6 = block [8*5]; + x7 = block [8*3]; +#if 0 + if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { + block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] = + block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6; + return; + } +#endif + x0 = (block[8*0] << 8) + 8192; + + /* first stage */ + x8 = W7 * (x4 + x5) + 4; + x4 = (x8 + (W1 - W7) * x4) >> 3; + x5 = (x8 - (W1 + W7) * x5) >> 3; + x8 = W3 * (x6 + x7) + 4; + x6 = (x8 - (W3 - W5) * x6) >> 3; + x7 = (x8 - (W3 + W5) * x7) >> 3; + + /* second stage */ + x8 = x0 + x1; + x0 -= x1; + x1 = W6 * (x3 + x2) + 4; + x2 = (x1 - (W2 + W6) * x2) >> 3; + x3 = (x1 + (W2 - W6) * x3) >> 3; + x1 = x4 + x6; + x4 -= x6; + x6 = x5 + x7; + x5 -= x7; + + /* third stage */ + x7 = x8 + x3; + x8 -= x3; + x3 = x0 + x2; + x0 -= x2; + x2 = (181 * (x4 + x5) + 128) >> 8; + x4 = (181 * (x4 - x5) + 128) >> 8; + + /* fourth stage */ + block[8*0] = (x7 + x1) >> 14; + block[8*1] = (x3 + x2) >> 14; + block[8*2] = (x0 + x4) >> 14; + block[8*3] = (x8 + x6) >> 14; + block[8*4] = (x8 - x6) >> 14; + block[8*5] = (x0 - x4) >> 14; + block[8*6] = (x3 - x2) >> 14; + block[8*7] = (x7 - x1) >> 14; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_idct(s16 *block, u8 *dest, int stride) */ +/* Inverse discrete cosine transform block, store result to dest */ +static void qc_mjpeg_idct(s16 *block, u8 *dest, int stride) +{ + int i; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_idct(block=%p,dest=%p,stride=%i)",block,dest,stride); + for (i=0; i<8; i++) qc_mjpeg_idct_row(block + 8*i); + for (i=0; i<8; i++) qc_mjpeg_idct_col(block + i); + i = 8; + do { + /* The original code used lookup-tables instead of explicit + * comparisons (as CLIP is doing here). However, sometimes + * the values pointed outside the LUT which caused problems + * in the kernel driver. Thus, the LUTs are removed here. */ + dest[0] = CLIP(block[0],0,255); + dest[1] = CLIP(block[1],0,255); + dest[2] = CLIP(block[2],0,255); + dest[3] = CLIP(block[3],0,255); + dest[4] = CLIP(block[4],0,255); + dest[5] = CLIP(block[5],0,255); + dest[6] = CLIP(block[6],0,255); + dest[7] = CLIP(block[7],0,255); + dest += stride; + block += 8; + } while (--i); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** MJPEG decoding: bitstream processing (structures and macros) * */ +/* the idea is taken from zlib, but the bits are ordered the other way, so + * I modified the code. + * Variables: + * p points to next unread byte in stream. + * k number of bits read but not processed. + * b contains the read but not processed bits in the k most significant bits. + */ +struct bitstream { + u32 b; + u8 *p; + u8 *end; + int k; +}; + +#define GETWORD(p) ((p)[0] << 8 | (p)[1]) +#define NEEDBITS(b,k,p) \ + do { \ + if ((k) > 0) { \ + (b) |= GETWORD(p) << (k); \ + (p) += 2; \ + (k) -= 16; \ + } \ + } while(0) +#define DUMPBITS(b,k,j) do { (k) += (j); (b) <<= (j); } while (0) +#define BITVALUE(b,j) ((b)>>(32-(j))) +/* }}} */ +/* {{{ [fold] **** qc_mjpeg_lvc: MJPEG decoding: variable length code decoding **************** */ + +/* {{{ [fold] u8 shiftTables[18][64] */ +static const u8 shiftTables[18][64] = { + {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }, + {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }, + {2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }, + {2,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }, + {2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 }, + {2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4 }, + {2,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }, + {2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 }, + {2,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6 }, + {2,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 }, +}; +/* }}} */ +/* {{{ [fold] u8 shiftTblIndex[] */ +static const u8 shiftTblIndex[] = { + 8, 17, 8, 16, 7, 16, 7, 15, + 6, 15, 6, 14, 5, 14, 5, 13, + 4, 13, 4, 12, 3, 12, 3, 11, + 2, 11, 2, 10, 1, 9, 0, 9 +}; +/* }}} */ +/* {{{ [fold] s16 scaleTable[64] */ +static const s16 scaleTable[64] = { + 8192, 16704, 16704, 17733, 17032, 17733, 18204, 18081, + 18081, 18204, 18724, 18561, 19195, 18561, 18724, 19265, + 19091, 19704, 19704, 19091, 19265, 21406, 19642, 20267, + 20228, 20267, 19642, 21406, 22725, 21826, 20852, 20805, + 20805, 20852, 21826, 22725, 23170, 23170, 21406, 21399, + 21406, 23170, 23170, 24597, 23785, 22017, 22017, 23785, + 24597, 25250, 24464, 22653, 24464, 25250, 25971, 25171, + 25171, 25971, 26722, 27969, 26722, 29691, 29691, 31520 +}; +/* }}} */ +/* {{{ [fold] u8 scan_norm[64] */ +static const u8 scan_norm[64] = { /* Octals */ + 000, 001, 010, 020, 011, 002, 003, 012, + 021, 030, 040, 031, 022, 013, 004, 005, + 014, 023, 032, 041, 050, 060, 051, 042, + 033, 024, 015, 006, 007, 016, 025, 034, + 043, 052, 061, 070, 071, 062, 053, 044, + 035, 026, 017, 027, 036, 045, 054, 063, + 072, 073, 064, 055, 046, 037, 047, 056, + 065, 074, 075, 066, 057, 067, 076, 077 +}; +/* }}} */ +/* {{{ [fold] hufftable[960] */ +struct hufftable_entry { + s16 value; + u8 bits; + u8 skip; +}; +static const struct hufftable_entry hufftable[960] = { + /* first level entries */ + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { 1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { -1, 3, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { 2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { -2, 4, 1 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 32767, 4, 255 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { 1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { -1, 5, 2 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { 3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { -3, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { 4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { -4, 5, 1 }, + { 1, 6, 3 }, + { 1, 6, 3 }, + { 1, 6, 3 }, + { 1, 6, 3 }, + { -1, 6, 3 }, + { -1, 6, 3 }, + { -1, 6, 3 }, + { -1, 6, 3 }, + { 2, 6, 2 }, + { 2, 6, 2 }, + { 2, 6, 2 }, + { 2, 6, 2 }, + { -2, 6, 2 }, + { -2, 6, 2 }, + { -2, 6, 2 }, + { -2, 6, 2 }, + { 5, 6, 1 }, + { 5, 6, 1 }, + { 5, 6, 1 }, + { 5, 6, 1 }, + { -5, 6, 1 }, + { -5, 6, 1 }, + { -5, 6, 1 }, + { -5, 6, 1 }, + { 6, 6, 1 }, + { 6, 6, 1 }, + { 6, 6, 1 }, + { 6, 6, 1 }, + { -6, 6, 1 }, + { -6, 6, 1 }, + { -6, 6, 1 }, + { -6, 6, 1 }, + { 1, 7, 4 }, + { 1, 7, 4 }, + { -1, 7, 4 }, + { -1, 7, 4 }, + { 1, 7, 5 }, + { 1, 7, 5 }, + { -1, 7, 5 }, + { -1, 7, 5 }, + { 7, 7, 1 }, + { 7, 7, 1 }, + { -7, 7, 1 }, + { -7, 7, 1 }, + { 8, 7, 1 }, + { 8, 7, 1 }, + { -8, 7, 1 }, + { -8, 7, 1 }, + { 1, 8, 6 }, + { -1, 8, 6 }, + { 1, 8, 7 }, + { -1, 8, 7 }, + { 2, 8, 3 }, + { -2, 8, 3 }, + { 3, 8, 2 }, + { -3, 8, 2 }, + { 4, 8, 2 }, + { -4, 8, 2 }, + { 9, 8, 1 }, + { -9, 8, 1 }, + { 10, 8, 1 }, + { -10, 8, 1 }, + { 11, 8, 1 }, + { -11, 8, 1 }, + { 256, 9, 99 }, + { 258, 9, 99 }, + { 260, 9, 99 }, + { 262, 9, 99 }, + { 264, 9, 99 }, + { 266, 9, 99 }, + { 268, 9, 99 }, + { 270, 9, 99 }, + { 272, 9, 99 }, + { 274, 9, 99 }, + { 276, 9, 99 }, + { 278, 9, 99 }, + { 280, 9, 99 }, + { 282, 9, 99 }, + { 284, 9, 99 }, + { 286, 9, 99 }, + { 288, 10, 99 }, + { 292, 10, 99 }, + { 296, 10, 99 }, + { 300, 10, 99 }, + { 304, 10, 99 }, + { 308, 10, 99 }, + { 312, 10, 99 }, + { 316, 10, 99 }, + { 320, 11, 99 }, + { 328, 11, 99 }, + { 336, 12, 99 }, + { 352, 13, 99 }, + { 384, 13, 99 }, + { 416, 13, 99 }, + { 448, 16, 99 }, + { 704, 16, 99 }, + /* indirect entries */ + { 1, 9, 8 }, + { -1, 9, 8 }, + { 1, 9, 9 }, + { -1, 9, 9 }, + { 1, 9, 10 }, + { -1, 9, 10 }, + { 1, 9, 11 }, + { -1, 9, 11 }, + { 2, 9, 4 }, + { -2, 9, 4 }, + { 2, 9, 5 }, + { -2, 9, 5 }, + { 3, 9, 3 }, + { -3, 9, 3 }, + { 5, 9, 2 }, + { -5, 9, 2 }, + { 6, 9, 2 }, + { -6, 9, 2 }, + { 7, 9, 2 }, + { -7, 9, 2 }, + { 12, 9, 1 }, + { -12, 9, 1 }, + { 13, 9, 1 }, + { -13, 9, 1 }, + { 14, 9, 1 }, + { -14, 9, 1 }, + { 15, 9, 1 }, + { -15, 9, 1 }, + { 16, 9, 1 }, + { -16, 9, 1 }, + { 17, 9, 1 }, + { -17, 9, 1 }, + { 1, 10, 12 }, + { -1, 10, 12 }, + { 1, 10, 13 }, + { -1, 10, 13 }, + { 1, 10, 14 }, + { -1, 10, 14 }, + { 1, 10, 15 }, + { -1, 10, 15 }, + { 2, 10, 6 }, + { -2, 10, 6 }, + { 2, 10, 7 }, + { -2, 10, 7 }, + { 3, 10, 4 }, + { -3, 10, 4 }, + { 3, 10, 5 }, + { -3, 10, 5 }, + { 4, 10, 3 }, + { -4, 10, 3 }, + { 5, 10, 3 }, + { -5, 10, 3 }, + { 8, 10, 2 }, + { -8, 10, 2 }, + { 18, 10, 1 }, + { -18, 10, 1 }, + { 19, 10, 1 }, + { -19, 10, 1 }, + { 20, 10, 1 }, + { -20, 10, 1 }, + { 21, 10, 1 }, + { -21, 10, 1 }, + { 22, 10, 1 }, + { -22, 10, 1 }, + { 3, 11, 6 }, + { -3, 11, 6 }, + { 4, 11, 4 }, + { -4, 11, 4 }, + { 5, 11, 4 }, + { -5, 11, 4 }, + { 6, 11, 3 }, + { -6, 11, 3 }, + { 9, 11, 2 }, + { -9, 11, 2 }, + { 10, 11, 2 }, + { -10, 11, 2 }, + { 11, 11, 2 }, + { -11, 11, 2 }, + { 0, 11, 1 }, + { 0, 11, 2 }, + { 3, 12, 7 }, + { -3, 12, 7 }, + { 4, 12, 5 }, + { -4, 12, 5 }, + { 6, 12, 4 }, + { -6, 12, 4 }, + { 12, 12, 2 }, + { -12, 12, 2 }, + { 13, 12, 2 }, + { -13, 12, 2 }, + { 14, 12, 2 }, + { -14, 12, 2 }, + { 0, 12, 3 }, + { 0, 12, 4 }, + { 0, 12, 5 }, + { 0, 12, 6 }, + { 2, 13, 8 }, + { -2, 13, 8 }, + { 2, 13, 9 }, + { -2, 13, 9 }, + { 2, 13, 10 }, + { -2, 13, 10 }, + { 2, 13, 11 }, + { -2, 13, 11 }, + { 3, 13, 8 }, + { -3, 13, 8 }, + { 3, 13, 9 }, + { -3, 13, 9 }, + { 5, 13, 5 }, + { -5, 13, 5 }, + { 7, 13, 4 }, + { -7, 13, 4 }, + { 7, 13, 3 }, + { -7, 13, 3 }, + { 8, 13, 3 }, + { -8, 13, 3 }, + { 9, 13, 3 }, + { -9, 13, 3 }, + { 10, 13, 3 }, + { -10, 13, 3 }, + { 11, 13, 3 }, + { -11, 13, 3 }, + { 15, 13, 2 }, + { -15, 13, 2 }, + { 16, 13, 2 }, + { -16, 13, 2 }, + { 17, 13, 2 }, + { -17, 13, 2 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 0, 13, 7 }, + { 0, 13, 8 }, + { 0, 13, 9 }, + { 0, 13, 10 }, + { 0, 13, 11 }, + { 0, 13, 12 }, + { 0, 13, 13 }, + { 0, 13, 14 }, + { 0, 13, 15 }, + { 0, 13, 16 }, + { 0, 13, 17 }, + { 0, 13, 18 }, + { 0, 13, 19 }, + { 0, 13, 20 }, + { 0, 13, 21 }, + { 0, 13, 22 }, + { 0, 13, 23 }, + { 0, 13, 24 }, + { 0, 13, 25 }, + { 0, 13, 26 }, + { 0, 13, 27 }, + { 0, 13, 28 }, + { 0, 13, 29 }, + { 0, 13, 30 }, + { 0, 13, 31 }, + { 0, 13, 32 }, + { 0, 13, 33 }, + { 0, 13, 34 }, + { 0, 13, 35 }, + { 0, 13, 36 }, + { 0, 13, 37 }, + { 0, 13, 38 }, + { 0, 13, 39 }, + { 0, 13, 40 }, + { 0, 13, 41 }, + { 0, 13, 42 }, + { 0, 13, 43 }, + { 0, 13, 44 }, + { 0, 13, 45 }, + { 0, 13, 46 }, + { 0, 13, 47 }, + { 0, 13, 48 }, + { 0, 13, 49 }, + { 0, 13, 50 }, + { 0, 13, 51 }, + { 0, 13, 52 }, + { 0, 13, 53 }, + { 0, 13, 54 }, + { 0, 13, 55 }, + { 0, 13, 56 }, + { 0, 13, 57 }, + { 0, 13, 58 }, + { 0, 13, 59 }, + { 0, 13, 60 }, + { 0, 13, 61 }, + { 0, 13, 62 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 32767, 0, 255 }, + { 23, 16, 1 }, + { -23, 16, 1 }, + { 24, 16, 1 }, + { -24, 16, 1 }, + { 25, 16, 1 }, + { -25, 16, 1 }, + { 26, 16, 1 }, + { -26, 16, 1 }, + { 27, 16, 1 }, + { -27, 16, 1 }, + { 28, 16, 1 }, + { -28, 16, 1 }, + { 29, 16, 1 }, + { -29, 16, 1 }, + { 30, 16, 1 }, + { -30, 16, 1 }, + { 31, 16, 1 }, + { -31, 16, 1 }, + { 32, 16, 1 }, + { -32, 16, 1 }, + { 33, 16, 1 }, + { -33, 16, 1 }, + { 34, 16, 1 }, + { -34, 16, 1 }, + { 35, 16, 1 }, + { -35, 16, 1 }, + { 36, 16, 1 }, + { -36, 16, 1 }, + { 37, 16, 1 }, + { -37, 16, 1 }, + { 38, 16, 1 }, + { -38, 16, 1 }, + { 39, 16, 1 }, + { -39, 16, 1 }, + { 40, 16, 1 }, + { -40, 16, 1 }, + { 41, 16, 1 }, + { -41, 16, 1 }, + { 42, 16, 1 }, + { -42, 16, 1 }, + { 43, 16, 1 }, + { -43, 16, 1 }, + { 44, 16, 1 }, + { -44, 16, 1 }, + { 45, 16, 1 }, + { -45, 16, 1 }, + { 46, 16, 1 }, + { -46, 16, 1 }, + { 47, 16, 1 }, + { -47, 16, 1 }, + { 48, 16, 1 }, + { -48, 16, 1 }, + { 49, 16, 1 }, + { -49, 16, 1 }, + { 50, 16, 1 }, + { -50, 16, 1 }, + { 51, 16, 1 }, + { -51, 16, 1 }, + { 52, 16, 1 }, + { -52, 16, 1 }, + { 53, 16, 1 }, + { -53, 16, 1 }, + { 54, 16, 1 }, + { -54, 16, 1 }, + { 55, 16, 1 }, + { -55, 16, 1 }, + { 56, 16, 1 }, + { -56, 16, 1 }, + { 57, 16, 1 }, + { -57, 16, 1 }, + { 58, 16, 1 }, + { -58, 16, 1 }, + { 59, 16, 1 }, + { -59, 16, 1 }, + { 60, 16, 1 }, + { -60, 16, 1 }, + { 61, 16, 1 }, + { -61, 16, 1 }, + { 62, 16, 1 }, + { -62, 16, 1 }, + { 63, 16, 1 }, + { -63, 16, 1 }, + { 64, 16, 1 }, + { -64, 16, 1 }, + { 65, 16, 1 }, + { -65, 16, 1 }, + { 66, 16, 1 }, + { -66, 16, 1 }, + { 67, 16, 1 }, + { -67, 16, 1 }, + { 68, 16, 1 }, + { -68, 16, 1 }, + { 69, 16, 1 }, + { -69, 16, 1 }, + { 70, 16, 1 }, + { -70, 16, 1 }, + { 71, 16, 1 }, + { -71, 16, 1 }, + { 72, 16, 1 }, + { -72, 16, 1 }, + { 73, 16, 1 }, + { -73, 16, 1 }, + { 74, 16, 1 }, + { -74, 16, 1 }, + { 75, 16, 1 }, + { -75, 16, 1 }, + { 76, 16, 1 }, + { -76, 16, 1 }, + { 77, 16, 1 }, + { -77, 16, 1 }, + { 78, 16, 1 }, + { -78, 16, 1 }, + { 79, 16, 1 }, + { -79, 16, 1 }, + { 80, 16, 1 }, + { -80, 16, 1 }, + { 81, 16, 1 }, + { -81, 16, 1 }, + { 82, 16, 1 }, + { -82, 16, 1 }, + { 83, 16, 1 }, + { -83, 16, 1 }, + { 84, 16, 1 }, + { -84, 16, 1 }, + { 85, 16, 1 }, + { -85, 16, 1 }, + { 86, 16, 1 }, + { -86, 16, 1 }, + { 87, 16, 1 }, + { -87, 16, 1 }, + { 88, 16, 1 }, + { -88, 16, 1 }, + { 89, 16, 1 }, + { -89, 16, 1 }, + { 90, 16, 1 }, + { -90, 16, 1 }, + { 91, 16, 1 }, + { -91, 16, 1 }, + { 92, 16, 1 }, + { -92, 16, 1 }, + { 93, 16, 1 }, + { -93, 16, 1 }, + { 94, 16, 1 }, + { -94, 16, 1 }, + { 95, 16, 1 }, + { -95, 16, 1 }, + { 96, 16, 1 }, + { -96, 16, 1 }, + { 97, 16, 1 }, + { -97, 16, 1 }, + { 98, 16, 1 }, + { -98, 16, 1 }, + { 99, 16, 1 }, + { -99, 16, 1 }, + { 100, 16, 1 }, + { -100, 16, 1 }, + { 101, 16, 1 }, + { -101, 16, 1 }, + { 102, 16, 1 }, + { -102, 16, 1 }, + { 103, 16, 1 }, + { -103, 16, 1 }, + { 104, 16, 1 }, + { -104, 16, 1 }, + { 105, 16, 1 }, + { -105, 16, 1 }, + { 106, 16, 1 }, + { -106, 16, 1 }, + { 107, 16, 1 }, + { -107, 16, 1 }, + { 108, 16, 1 }, + { -108, 16, 1 }, + { 109, 16, 1 }, + { -109, 16, 1 }, + { 110, 16, 1 }, + { -110, 16, 1 }, + { 111, 16, 1 }, + { -111, 16, 1 }, + { 112, 16, 1 }, + { -112, 16, 1 }, + { 113, 16, 1 }, + { -113, 16, 1 }, + { 114, 16, 1 }, + { -114, 16, 1 }, + { 115, 16, 1 }, + { -115, 16, 1 }, + { 116, 16, 1 }, + { -116, 16, 1 }, + { 117, 16, 1 }, + { -117, 16, 1 }, + { 118, 16, 1 }, + { -118, 16, 1 }, + { 119, 16, 1 }, + { -119, 16, 1 }, + { 120, 16, 1 }, + { -120, 16, 1 }, + { 121, 16, 1 }, + { -121, 16, 1 }, + { 122, 16, 1 }, + { -122, 16, 1 }, + { 123, 16, 1 }, + { -123, 16, 1 }, + { 124, 16, 1 }, + { -124, 16, 1 }, + { 125, 16, 1 }, + { -125, 16, 1 }, + { 126, 16, 1 }, + { -126, 16, 1 }, + { 127, 16, 1 }, + { -127, 16, 1 }, + { 128, 16, 1 }, + { -128, 16, 1 }, + { 129, 16, 1 }, + { -129, 16, 1 }, + { 130, 16, 1 }, + { -130, 16, 1 }, + { 131, 16, 1 }, + { -131, 16, 1 }, + { 132, 16, 1 }, + { -132, 16, 1 }, + { 133, 16, 1 }, + { -133, 16, 1 }, + { 134, 16, 1 }, + { -134, 16, 1 }, + { 135, 16, 1 }, + { -135, 16, 1 }, + { 136, 16, 1 }, + { -136, 16, 1 }, + { 137, 16, 1 }, + { -137, 16, 1 }, + { 138, 16, 1 }, + { -138, 16, 1 }, + { 139, 16, 1 }, + { -139, 16, 1 }, + { 140, 16, 1 }, + { -140, 16, 1 }, + { 141, 16, 1 }, + { -141, 16, 1 }, + { 142, 16, 1 }, + { -142, 16, 1 }, + { 143, 16, 1 }, + { -143, 16, 1 }, + { 144, 16, 1 }, + { -144, 16, 1 }, + { 145, 16, 1 }, + { -145, 16, 1 }, + { 146, 16, 1 }, + { -146, 16, 1 }, + { 147, 16, 1 }, + { -147, 16, 1 }, + { 148, 16, 1 }, + { -148, 16, 1 }, + { 149, 16, 1 }, + { -149, 16, 1 }, + { 150, 16, 1 }, + { -150, 16, 1 }, + { 151, 16, 1 }, + { -151, 16, 1 }, + { 152, 16, 1 }, + { -152, 16, 1 }, + { 153, 16, 1 }, + { -153, 16, 1 }, + { 154, 16, 1 }, + { -154, 16, 1 }, + { 155, 16, 1 }, + { -155, 16, 1 }, + { 156, 16, 1 }, + { -156, 16, 1 }, + { 157, 16, 1 }, + { -157, 16, 1 }, + { 158, 16, 1 }, + { -158, 16, 1 }, + { 159, 16, 1 }, + { -159, 16, 1 }, + { 160, 16, 1 }, + { -160, 16, 1 }, + { 161, 16, 1 }, + { -161, 16, 1 }, + { 162, 16, 1 }, + { -162, 16, 1 }, + { 163, 16, 1 }, + { -163, 16, 1 }, + { 164, 16, 1 }, + { -164, 16, 1 }, + { 165, 16, 1 }, + { -165, 16, 1 }, + { 166, 16, 1 }, + { -166, 16, 1 }, + { 167, 16, 1 }, + { -167, 16, 1 }, + { 168, 16, 1 }, + { -168, 16, 1 }, + { 169, 16, 1 }, + { -169, 16, 1 }, + { 170, 16, 1 }, + { -170, 16, 1 }, + { 171, 16, 1 }, + { -171, 16, 1 }, + { 172, 16, 1 }, + { -172, 16, 1 }, + { 173, 16, 1 }, + { -173, 16, 1 }, + { 174, 16, 1 }, + { -174, 16, 1 }, + { 175, 16, 1 }, + { -175, 16, 1 }, + { 176, 16, 1 }, + { -176, 16, 1 }, + { 177, 16, 1 }, + { -177, 16, 1 }, + { 178, 16, 1 }, + { -178, 16, 1 }, + { 179, 16, 1 }, + { -179, 16, 1 }, + { 180, 16, 1 }, + { -180, 16, 1 }, + { 181, 16, 1 }, + { -181, 16, 1 }, + { 182, 16, 1 }, + { -182, 16, 1 }, + { 183, 16, 1 }, + { -183, 16, 1 }, + { 184, 16, 1 }, + { -184, 16, 1 }, + { 185, 16, 1 }, + { -185, 16, 1 }, + { 186, 16, 1 }, + { -186, 16, 1 }, + { 187, 16, 1 }, + { -187, 16, 1 }, + { 188, 16, 1 }, + { -188, 16, 1 }, + { 189, 16, 1 }, + { -189, 16, 1 }, + { 190, 16, 1 }, + { -190, 16, 1 }, + { 191, 16, 1 }, + { -191, 16, 1 }, + { 192, 16, 1 }, + { -192, 16, 1 }, + { 193, 16, 1 }, + { -193, 16, 1 }, + { 194, 16, 1 }, + { -194, 16, 1 }, + { 195, 16, 1 }, + { -195, 16, 1 }, + { 196, 16, 1 }, + { -196, 16, 1 }, + { 197, 16, 1 }, + { -197, 16, 1 }, + { 198, 16, 1 }, + { -198, 16, 1 }, + { 199, 16, 1 }, + { -199, 16, 1 }, + { 200, 16, 1 }, + { -200, 16, 1 }, + { 201, 16, 1 }, + { -201, 16, 1 }, + { 202, 16, 1 }, + { -202, 16, 1 }, + { 203, 16, 1 }, + { -203, 16, 1 }, + { 204, 16, 1 }, + { -204, 16, 1 }, + { 205, 16, 1 }, + { -205, 16, 1 }, + { 206, 16, 1 }, + { -206, 16, 1 }, + { 207, 16, 1 }, + { -207, 16, 1 }, + { 208, 16, 1 }, + { -208, 16, 1 }, + { 209, 16, 1 }, + { -209, 16, 1 }, + { 210, 16, 1 }, + { -210, 16, 1 }, + { 211, 16, 1 }, + { -211, 16, 1 }, + { 212, 16, 1 }, + { -212, 16, 1 }, + { 213, 16, 1 }, + { -213, 16, 1 }, + { 214, 16, 1 }, + { -214, 16, 1 }, + { 215, 16, 1 }, + { -215, 16, 1 }, + { 216, 16, 1 }, + { -216, 16, 1 }, + { 217, 16, 1 }, + { -217, 16, 1 }, + { 218, 16, 1 }, + { -218, 16, 1 }, + { 219, 16, 1 }, + { -219, 16, 1 }, + { 220, 16, 1 }, + { -220, 16, 1 }, + { 221, 16, 1 }, + { -221, 16, 1 }, + { 222, 16, 1 }, + { -222, 16, 1 }, + { 223, 16, 1 }, + { -223, 16, 1 }, + { 224, 16, 1 }, + { -224, 16, 1 }, + { 225, 16, 1 }, + { -225, 16, 1 }, + { 226, 16, 1 }, + { -226, 16, 1 }, + { 227, 16, 1 }, + { -227, 16, 1 }, + { 228, 16, 1 }, + { -228, 16, 1 }, + { 229, 16, 1 }, + { -229, 16, 1 }, + { 230, 16, 1 }, + { -230, 16, 1 }, + { 231, 16, 1 }, + { -231, 16, 1 }, + { 232, 16, 1 }, + { -232, 16, 1 }, + { 233, 16, 1 }, + { -233, 16, 1 }, + { 234, 16, 1 }, + { -234, 16, 1 }, + { 235, 16, 1 }, + { -235, 16, 1 }, + { 236, 16, 1 }, + { -236, 16, 1 }, + { 237, 16, 1 }, + { -237, 16, 1 }, + { 238, 16, 1 }, + { -238, 16, 1 }, + { 239, 16, 1 }, + { -239, 16, 1 }, + { 240, 16, 1 }, + { -240, 16, 1 }, + { 241, 16, 1 }, + { -241, 16, 1 }, + { 242, 16, 1 }, + { -242, 16, 1 }, + { 243, 16, 1 }, + { -243, 16, 1 }, + { 244, 16, 1 }, + { -244, 16, 1 }, + { 245, 16, 1 }, + { -245, 16, 1 }, + { 246, 16, 1 }, + { -246, 16, 1 }, + { 247, 16, 1 }, + { -247, 16, 1 }, + { 248, 16, 1 }, + { -248, 16, 1 }, + { 249, 16, 1 }, + { -249, 16, 1 }, + { 250, 16, 1 }, + { -250, 16, 1 }, + { 251, 16, 1 }, + { -251, 16, 1 }, + { 252, 16, 1 }, + { -252, 16, 1 }, + { 253, 16, 1 }, + { -253, 16, 1 }, + { 254, 16, 1 }, + { -254, 16, 1 }, + { 255, 16, 1 }, + { -255, 16, 1 } +}; +/* }}} */ +/* {{{ [fold] qc_mjpeg_lvc_decode_block(struct bitstream *bitsrc, s16 *output, int blockval) */ +static inline void qc_mjpeg_lvc_decode_block(struct bitstream *bitsrc, s16 *output, int blockval) +{ + u32 b; + u8 *p; + int k; + int value, skip, bits; + struct hufftable_entry entry; + int offset = 0; + const u8 *shiftPtr; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode_block(bitsrc=%p, output=%p, blockval=%i)", bitsrc, output, blockval); + b = bitsrc->b; + k = bitsrc->k; + p = bitsrc->p; + memset(output, 0, 64 * sizeof(s16)); + if (blockval!=7) PDEBUG("blockval=%i",blockval); + NEEDBITS(b,k,p); + shiftPtr = shiftTables[shiftTblIndex[2*blockval+BITVALUE(b,1)]]; + DUMPBITS(b,k,1); + value = BITVALUE(((signed)b),10); + DUMPBITS(b,k,10); + do { + value = ((value << shiftPtr[offset]) * scaleTable[offset]) >> 14; + output[scan_norm[offset]] = value; + NEEDBITS(b,k,p); + entry = hufftable[BITVALUE(b,8)]; + bits = entry.bits; + if (bits > 8) { + entry = hufftable[entry.value + ((b & 0x00ffffff) >> (32 - bits))]; + if (PARANOID && entry.bits!=bits) { + PDEBUG("entry.bits!=bits shouldn't happen"); + bits = entry.bits; + } + } + DUMPBITS(b,k,bits); + skip = entry.skip; + value = entry.value; + offset += skip; + } while (offset < 64); + bitsrc->b = b; + bitsrc->k = k; + bitsrc->p = p; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode_block() exit"); +} +/* }}} */ + +/* {{{ [fold] struct blockorder */ +struct blockorder { + char widthPad; /* pad width to multiple of this */ + char heightPad; /* pad height to multiple of this */ + char uvWshift; /* shift width by this to get width of U/V image */ + char uvHshift; /* dito for height */ + char blockWidth[2]; /* width of a block for each pass*/ + char subblockCount[2]; /* number of sub block in a block for each pass */ + u32 subblockMap[2]; +}; +static const struct blockorder order_I420 = { + 32, 16, 1, 1, + { 32, 16 }, { 4, 4 }, + { 0x00, 0x90 } +}; +#if 0 +static const struct blockorder order_L422 = { + 16, 16, 1, 0, + { 16, 16 }, { 4, 4 }, + { 0x90, 0x90 } +}; + +static const struct blockorder order_L410 = { + 64, 16, 2, 1, + { 32, 64 }, { 4, 12 }, + { 0x00, 0x909000 } +}; +#endif +/* }}} */ +/* {{{ [fold] qc_mjpeg_lvc_decode() */ +/* Decode given compressed image to YUV image. Return error code if bad data */ +static int qc_mjpeg_lvc_decode(u8 *outY, u8 *outU, u8 *outV, + u8 *input, u32 length, unsigned int width, unsigned int height) +{ + struct bitstream stream; + const struct blockorder *blkorder; + + unsigned int blockx, blocky; + unsigned int pass, subblock, blockval = 0; + unsigned int blocknr = 0; + unsigned int uvWidth; + + s16 blockbuffer[64]; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode(outY=%p, outU=%p, outV=%p)", outY, outU, outV); + stream.b = 0; + stream.k = 16; + stream.p = input; + stream.end = input+length; + + blkorder = &order_I420; /* Select compression type */ + + uvWidth = (width >> blkorder->uvWshift); + + if ((width & (blkorder->widthPad - 1)) || (height & (blkorder->heightPad - 1))) { + PDEBUG("something's wrong"); + return -EILSEQ; + } + + for (blocky=0; blockyheightPad) { + for (pass = 0; pass < 2; pass++) { + int blockwidth = blkorder->blockWidth[pass]; + int subblockcount = blkorder->subblockCount[pass]; + u32 map = blkorder->subblockMap[pass]; + for (blockx=0; blockx stream.end) { + PDEBUG("p>stream.end"); + return -EILSEQ; + } + + blockval = BITVALUE(b, 4); + DUMPBITS(b,k,4); + stream.b = b; + stream.k = k; + stream.p = p; + } + qc_mjpeg_lvc_decode_block(&stream, blockbuffer, blockval); + blockbuffer[0] += 1024; + switch (subblkmap & 3) { + case 0: + qc_mjpeg_idct(blockbuffer, outY, width); + outY += 8; + break; + case 1: + qc_mjpeg_idct(blockbuffer, outU, uvWidth); + outU += 8; + break; + case 2: + qc_mjpeg_idct(blockbuffer, outV, uvWidth); + outV += 8; + break; + } + subblkmap >>= 2; + } /* for (subblock = 0; subblock < subblockcount; subblock++) */ + } /* for (blockx = 0; blockx < width; blockx += blockwidth) */ + outY += 7 * width; + if (map) { + outU += 7 * uvWidth; + outV += 7 * uvWidth; + } + } /* for (pass = 0; pass < 2; pass++) */ + + /* next block starts at next 4 byte boundary */ + stream.p -= (16 - stream.k) >> 3; /* push back unread bits */ + stream.p += (input - stream.p) & 3; + stream.k = 16; + stream.b = 0; + } /* for (blocky=0; blockyheightPad) */ + + if (stream.p != stream.end) { + PDEBUG("stream.p != stream.end"); + return -EILSEQ; + } + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_lvc_decode() done"); + return 0; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_mjpeg: Motion JPEG decoding main routines *************************** */ + +static const int qc_mjpeg_width = 320; /* Size of the compressed image */ +static const int qc_mjpeg_height = 240; + +/* {{{ [fold] qc_mjpeg_decode() */ +/* Decode and uncompress given data, return error code if failure + * src = points to compressed bitstream data + * src_len = compressed data length in bytes + * dst = decompressed image will be stored here, size 320x240 x bytes per pixel (2-4) + */ +int qc_mjpeg_decode(struct qc_mjpeg_data *md, unsigned char *src, int src_len, unsigned char *dst) +{ + int r; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_decode(src_len=%i,W=%i,H=%i,depth=%i)",src_len,qc_mjpeg_width,qc_mjpeg_height,md->depth); + IDEBUG_TEST(*md); + if (src_len >= 100000) { + PDEBUG("long frame, length=%i", src_len); + return -EILSEQ; + } + r = qc_mjpeg_lvc_decode(md->encY, md->encU, md->encV, src, src_len, qc_mjpeg_width, qc_mjpeg_height); + if (r<0) { + PRINTK(KERN_ERR,"frame corrupted, len=%i",src_len); + return r; + } + qc_mjpeg_yuv2rgb(md, dst, md->encY, md->encU, md->encV, + qc_mjpeg_width, qc_mjpeg_height, /* Image size */ + qc_mjpeg_width * ((md->depth+1)/8), /* RGB stride */ + qc_mjpeg_width, /* Y stride */ + qc_mjpeg_width/2); /* U and V stride */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_decode() done"); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr) */ +/* Initialize Motion JPEG decompression. + * depth = bit depth of the decoded image, either 15=16,24 or 32 + * tobgr = use blue in the lowest address (red otherwise) + */ +int qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr) +{ + int r = -ENOMEM; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_init(depth=%i)",depth); + md->depth = depth; + /* Temporary buffers used for decoding the image (FIXME:too big for stack?) */ + /* Note: originally this allocated one extra byte for encY/U/V. I removed that. */ + md->encY = kmalloc(qc_mjpeg_width*qc_mjpeg_height, GFP_KERNEL); + if (!md->encY) goto fail1; + md->encU = kmalloc(qc_mjpeg_width*qc_mjpeg_height/4, GFP_KERNEL); + if (!md->encU) goto fail2; + md->encV = kmalloc(qc_mjpeg_width*qc_mjpeg_height/4, GFP_KERNEL); + if (!md->encV) goto fail3; + if ((r=qc_mjpeg_yuv2rgb_init(md, depth, tobgr ? MODE_BGR : MODE_RGB))<0) goto fail4; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_init() done"); + IDEBUG_INIT(*md); + return 0; + +fail4: kfree(md->encV); +fail3: kfree(md->encU); +fail2: kfree(md->encY); +fail1: PDEBUG("failed qc_mjpeg_init() = %i", r); + POISON(*md); + return r; +} +/* }}} */ +/* {{{ [fold] qc_mjpeg_exit(struct qc_mjpeg_data *md) */ +/* Free up resources allocated for image decompression */ +void qc_mjpeg_exit(struct qc_mjpeg_data *md) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_exit()"); + IDEBUG_TEST(*md); + qc_mjpeg_yuv2rgb_exit(md); + kfree(md->encV); + kfree(md->encU); + kfree(md->encY); + POISON(md->encV); + POISON(md->encU); + POISON(md->encY); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_mjpeg_exit() done"); + IDEBUG_EXIT(*md); +} +/* }}} */ + +/* }}} */ + +#else /* COMPRESS=0 */ +int qc_mjpeg_decode(struct qc_mjpeg_data *md, unsigned char *src, int src_len, unsigned char *dst) { return -ENXIO; } +int qc_mjpeg_init(struct qc_mjpeg_data *md, int depth, Bool tobgr) { return -ENXIO; } +void qc_mjpeg_exit(struct qc_mjpeg_data *md) { } +#endif + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-formats.c +++ linux-2.6.28/ubuntu/qc-usb/qc-formats.c @@ -0,0 +1,1545 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qc-usb, linux V4L driver for the Logitech QuickCam family + * + * qc-formats.c - converts color formats + * + * Copyright (c) 2001 Jean-Frederic Clere (RGB->YUV conversion) + * 2001 Aaron Holtzman (YUV->RGB conversion, from mpeg2dec) + * 2003 Tuukka Toivonen (Bayer->RGB conversion) + * + * 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 "quickcam.h" +#include + +#ifndef v4l2_fourcc +/* Four-character-code (FOURCC) */ +#define v4l2_fourcc(a,b,c,d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) +#endif + +/* {{{ [fold] **** qc_yuv: Start of RGB to YUV conversion functions ******************** */ + +/* {{{ [fold] qc_yuv_interp[256][8] */ +static signed short qc_yuv_interp[256][8] = { +{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,1,0,0,0,1,0,0},{0,1,0,0,0,1,-1,0}, +{1,2,0,0,-1,2,-1,0},{1,2,0,0,-1,2,-2,0},{1,3,0,-1,-1,3,-2,0},{2,3,0,-1,-2,3,-2,0}, +{2,4,0,-1,-2,4,-3,0},{2,5,1,-1,-2,4,-3,0},{2,5,1,-1,-3,5,-4,0},{3,6,1,-1,-3,5,-4,0}, +{3,6,1,-2,-3,6,-5,0},{3,7,1,-2,-4,6,-5,-1},{4,7,1,-2,-4,7,-5,-1},{4,8,1,-2,-4,7,-6,-1}, +{4,9,1,-2,-5,8,-6,-1},{5,9,1,-2,-5,8,-7,-1},{5,10,2,-3,-5,9,-7,-1},{5,10,2,-3,-6,9,-7,-1}, +{5,11,2,-3,-6,10,-8,-1},{6,11,2,-3,-6,10,-8,-1},{6,12,2,-3,-7,11,-9,-1},{6,13,2,-3,-7,11,-9,-1}, +{7,13,2,-4,-7,12,-10,-1},{7,14,2,-4,-8,12,-10,-2},{7,14,2,-4,-8,13,-10,-2},{8,15,3,-4,-8,13,-11,-2}, +{8,15,3,-4,-9,14,-11,-2},{8,16,3,-4,-9,14,-12,-2},{8,17,3,-5,-9,15,-12,-2},{9,17,3,-5,-10,15,-12,-2}, +{9,18,3,-5,-10,16,-13,-2},{9,18,3,-5,-10,16,-13,-2},{10,19,3,-5,-11,17,-14,-2},{10,19,3,-5,-11,17,-14,-2}, +{10,20,4,-6,-11,18,-15,-2},{11,20,4,-6,-12,18,-15,-3},{11,21,4,-6,-12,19,-15,-3},{11,22,4,-6,-12,19,-16,-3}, +{11,22,4,-6,-13,20,-16,-3},{12,23,4,-6,-13,20,-17,-3},{12,23,4,-7,-13,21,-17,-3},{12,24,4,-7,-14,21,-18,-3}, +{13,24,5,-7,-14,22,-18,-3},{13,25,5,-7,-14,22,-18,-3},{13,26,5,-7,-15,23,-19,-3},{14,26,5,-7,-15,23,-19,-3}, +{14,27,5,-8,-15,24,-20,-3},{14,27,5,-8,-16,24,-20,-3},{14,28,5,-8,-16,25,-20,-4},{15,28,5,-8,-16,25,-21,-4}, +{15,29,5,-8,-17,26,-21,-4},{15,30,6,-8,-17,26,-22,-4},{16,30,6,-9,-17,27,-22,-4},{16,31,6,-9,-18,27,-23,-4}, +{16,31,6,-9,-18,28,-23,-4},{17,32,6,-9,-18,28,-23,-4},{17,32,6,-9,-19,29,-24,-4},{17,33,6,-9,-19,29,-24,-4}, +{17,34,6,-10,-19,30,-25,-4},{18,34,6,-10,-20,30,-25,-4},{18,35,7,-10,-20,31,-25,-5},{18,35,7,-10,-20,31,-26,-5}, +{19,36,7,-10,-21,32,-26,-5},{19,36,7,-10,-21,32,-27,-5},{19,37,7,-11,-21,33,-27,-5},{20,37,7,-11,-22,33,-28,-5}, +{20,38,7,-11,-22,34,-28,-5},{20,39,7,-11,-22,34,-28,-5},{20,39,7,-11,-23,35,-29,-5},{21,40,8,-11,-23,35,-29,-5}, +{21,40,8,-12,-23,36,-30,-5},{21,41,8,-12,-24,36,-30,-5},{22,41,8,-12,-24,37,-30,-6},{22,42,8,-12,-24,37,-31,-6}, +{22,43,8,-12,-25,38,-31,-6},{23,43,8,-12,-25,38,-32,-6},{23,44,8,-13,-25,39,-32,-6},{23,44,9,-13,-26,39,-33,-6}, +{23,45,9,-13,-26,40,-33,-6},{24,45,9,-13,-26,40,-33,-6},{24,46,9,-13,-27,41,-34,-6},{24,47,9,-14,-27,41,-34,-6}, +{25,47,9,-14,-27,42,-35,-6},{25,48,9,-14,-28,42,-35,-6},{25,48,9,-14,-28,43,-36,-6},{26,49,9,-14,-28,43,-36,-7}, +{26,49,10,-14,-29,44,-36,-7},{26,50,10,-15,-29,44,-37,-7},{26,51,10,-15,-29,45,-37,-7},{27,51,10,-15,-30,45,-38,-7}, +{27,52,10,-15,-30,46,-38,-7},{27,52,10,-15,-30,46,-38,-7},{28,53,10,-15,-31,47,-39,-7},{28,53,10,-16,-31,47,-39,-7}, +{28,54,10,-16,-31,48,-40,-7},{29,54,11,-16,-32,48,-40,-7},{29,55,11,-16,-32,49,-41,-7},{29,56,11,-16,-32,49,-41,-8}, +{29,56,11,-16,-33,50,-41,-8},{30,57,11,-17,-33,50,-42,-8},{30,57,11,-17,-33,51,-42,-8},{30,58,11,-17,-34,51,-43,-8}, +{31,58,11,-17,-34,52,-43,-8},{31,59,11,-17,-34,52,-43,-8},{31,60,12,-17,-35,53,-44,-8},{31,60,12,-18,-35,53,-44,-8}, +{32,61,12,-18,-35,54,-45,-8},{32,61,12,-18,-36,54,-45,-8},{32,62,12,-18,-36,55,-46,-8},{33,62,12,-18,-36,55,-46,-9}, +{33,63,12,-18,-37,56,-46,-9},{33,64,12,-19,-37,56,-47,-9},{34,64,12,-19,-37,57,-47,-9},{34,65,13,-19,-38,57,-48,-9}, +{34,65,13,-19,-38,58,-48,-9},{34,66,13,-19,-38,58,-48,-9},{35,66,13,-19,-39,59,-49,-9},{35,67,13,-20,-39,59,-49,-9}, +{35,68,13,-20,-39,60,-50,-9},{36,68,13,-20,-40,60,-50,-9},{36,69,13,-20,-40,61,-51,-9},{36,69,14,-20,-40,61,-51,-9}, +{37,70,14,-20,-41,62,-51,-10},{37,70,14,-21,-41,62,-52,-10},{37,71,14,-21,-41,63,-52,-10},{37,72,14,-21,-42,63,-53,-10}, +{38,72,14,-21,-42,64,-53,-10},{38,73,14,-21,-42,64,-54,-10},{38,73,14,-21,-43,65,-54,-10},{39,74,14,-22,-43,65,-54,-10}, +{39,74,15,-22,-43,66,-55,-10},{39,75,15,-22,-44,66,-55,-10},{40,75,15,-22,-44,67,-56,-10},{40,76,15,-22,-44,67,-56,-10}, +{40,77,15,-22,-45,68,-56,-11},{40,77,15,-23,-45,68,-57,-11},{41,78,15,-23,-45,69,-57,-11},{41,78,15,-23,-46,69,-58,-11}, +{41,79,15,-23,-46,70,-58,-11},{42,79,16,-23,-46,70,-59,-11},{42,80,16,-23,-47,71,-59,-11},{42,81,16,-24,-47,71,-59,-11}, +{43,81,16,-24,-47,72,-60,-11},{43,82,16,-24,-48,72,-60,-11},{43,82,16,-24,-48,73,-61,-11},{43,83,16,-24,-48,73,-61,-11}, +{44,83,16,-24,-49,74,-61,-12},{44,84,16,-25,-49,74,-62,-12},{44,85,17,-25,-49,75,-62,-12},{45,85,17,-25,-50,75,-63,-12}, +{45,86,17,-25,-50,76,-63,-12},{45,86,17,-25,-50,76,-64,-12},{46,87,17,-25,-51,77,-64,-12},{46,87,17,-26,-51,77,-64,-12}, +{46,88,17,-26,-51,78,-65,-12},{46,89,17,-26,-52,78,-65,-12},{47,89,18,-26,-52,79,-66,-12},{47,90,18,-26,-52,79,-66,-12}, +{47,90,18,-26,-53,80,-66,-13},{48,91,18,-27,-53,80,-67,-13},{48,91,18,-27,-53,81,-67,-13},{48,92,18,-27,-54,81,-68,-13}, +{49,92,18,-27,-54,82,-68,-13},{49,93,18,-27,-54,82,-69,-13},{49,94,18,-28,-54,83,-69,-13},{49,94,19,-28,-55,83,-69,-13}, +{50,95,19,-28,-55,84,-70,-13},{50,95,19,-28,-55,84,-70,-13},{50,96,19,-28,-56,85,-71,-13},{51,96,19,-28,-56,85,-71,-13}, +{51,97,19,-29,-56,86,-72,-13},{51,98,19,-29,-57,86,-72,-14},{52,98,19,-29,-57,87,-72,-14},{52,99,19,-29,-57,87,-73,-14}, +{52,99,20,-29,-58,88,-73,-14},{52,100,20,-29,-58,88,-74,-14},{53,100,20,-30,-58,89,-74,-14},{53,101,20,-30,-59,89,-74,-14}, +{53,102,20,-30,-59,90,-75,-14},{54,102,20,-30,-59,90,-75,-14},{54,103,20,-30,-60,91,-76,-14},{54,103,20,-30,-60,91,-76,-14}, +{55,104,20,-31,-60,92,-77,-14},{55,104,21,-31,-61,92,-77,-15},{55,105,21,-31,-61,93,-77,-15},{55,106,21,-31,-61,93,-78,-15}, +{56,106,21,-31,-62,94,-78,-15},{56,107,21,-31,-62,94,-79,-15},{56,107,21,-32,-62,95,-79,-15},{57,108,21,-32,-63,95,-79,-15}, +{57,108,21,-32,-63,96,-80,-15},{57,109,22,-32,-63,96,-80,-15},{58,109,22,-32,-64,97,-81,-15},{58,110,22,-32,-64,97,-81,-15}, +{58,111,22,-33,-64,98,-82,-15},{58,111,22,-33,-65,98,-82,-16},{59,112,22,-33,-65,99,-82,-16},{59,112,22,-33,-65,99,-83,-16}, +{59,113,22,-33,-66,100,-83,-16},{60,113,22,-33,-66,100,-84,-16},{60,114,23,-34,-66,101,-84,-16},{60,115,23,-34,-67,101,-84,-16}, +{60,115,23,-34,-67,102,-85,-16},{61,116,23,-34,-67,102,-85,-16},{61,116,23,-34,-68,103,-86,-16},{61,117,23,-34,-68,103,-86,-16}, +{62,117,23,-35,-68,104,-87,-16},{62,118,23,-35,-69,104,-87,-16},{62,119,23,-35,-69,105,-87,-17},{63,119,24,-35,-69,105,-88,-17}, +{63,120,24,-35,-70,106,-88,-17},{63,120,24,-35,-70,106,-89,-17},{63,121,24,-36,-70,107,-89,-17},{64,121,24,-36,-71,107,-90,-17}, +{64,122,24,-36,-71,108,-90,-17},{64,123,24,-36,-71,108,-90,-17},{65,123,24,-36,-72,109,-91,-17},{65,124,24,-36,-72,109,-91,-17}, +{65,124,25,-37,-72,110,-92,-17},{66,125,25,-37,-73,110,-92,-17},{66,125,25,-37,-73,111,-92,-18},{66,126,25,-37,-73,111,-93,-18}, +{66,127,25,-37,-74,112,-93,-18},{67,127,25,-37,-74,112,-94,-18},{67,128,25,-38,-74,113,-94,-18},{67,128,25,-38,-75,113,-95,-18}, +{68,129,25,-38,-75,114,-95,-18},{68,129,26,-38,-75,114,-95,-18},{68,130,26,-38,-76,115,-96,-18},{69,130,26,-38,-76,115,-96,-18}, +{69,131,26,-39,-76,116,-97,-18},{69,132,26,-39,-77,116,-97,-18},{69,132,26,-39,-77,117,-97,-19},{70,133,26,-39,-77,117,-98,-19}, +{70,133,26,-39,-78,118,-98,-19},{70,134,27,-39,-78,118,-99,-19},{71,134,27,-40,-78,119,-99,-19},{71,135,27,-40,-79,119,-100,-19}, +{71,136,27,-40,-79,120,-100,-19},{72,136,27,-40,-79,120,-100,-19},{72,137,27,-40,-80,121,-101,-19},{72,137,27,-40,-80,121,-101,-19}, +{72,138,27,-41,-80,122,-102,-19},{73,138,27,-41,-81,122,-102,-19},{73,139,28,-41,-81,123,-103,-19},{73,140,28,-41,-81,123,-103,-20}, +{74,140,28,-41,-82,124,-103,-20},{74,141,28,-42,-82,124,-104,-20},{74,141,28,-42,-82,125,-104,-20},{75,142,28,-42,-83,125,-105,-20}, +{75,142,28,-42,-83,126,-105,-20},{75,143,28,-42,-83,126,-105,-20},{75,144,28,-42,-84,127,-106,-20},{76,144,29,-43,-84,127,-106,-20}}; +/* }}} */ + +/* {{{ [fold] qc_yuv_toplanar(unsigned char *rgb24frame, int length, int format) */ +/* + * Convert to planar formats + * The input is an YCbYCr format. + * Input: len : 2/3 maxi. + * | YUYV | free | + * | 2/3 | 1/3 | + * 1th conversion: + * | YY | free | U|V | + * | 1/3 | 1/3 | 1/3 | + * 2d conversion: + * | YY | U | V | free | + * | 1/3 | 1/6|1/6 | 1/3 | + * That the Y422P conversion. + */ +static int qc_yuv_toplanar(unsigned char *rgb24frame, int length, int format) +{ + unsigned char *ptr; + int n = 0, l = 0, i; + unsigned char *cr; + unsigned char *cb; + unsigned char *crptr, *cbptr; + int mode = 0; + + l = length/2; + switch(format) { + case VIDEO_PALETTE_YUV411P: + n = length/8; + mode = 1; + break; + case VIDEO_PALETTE_YUV422P: + n = length/4; + break; + } + + ptr = rgb24frame; + crptr = &rgb24frame[length]; + cr = crptr; + cbptr = &rgb24frame[length+n]; + cb = cbptr; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_yuv_toplanar: %d (%d + 2 * %d)",length, l, n); + + /* separate Y , U and V */ + for (i=0; iscanlength = length/2+ (2 * n); + return length; +} +/* }}} */ +/* {{{ [fold] qc_yuv_rgb2yuv(unsigned char *rgb24frame, int length, int format) */ +/* + * Convert the RGB24 image to YUV422. + * return the size of the converted frame + */ +int qc_yuv_rgb2yuv(unsigned char *rgb24frame, int length, int format) +{ + int i; + int l; /* Data length */ + short Y; + short U; + short V; + unsigned char *ptr; + unsigned short w; + + //if (qcdebug&QC_DEBUGLOGIC)PDEBUG("qc_yuv_rgb2yuv(frame=%p,length=%i,palette=%s)",rgb24frame,length,qc_fmt_getname(format)); + ptr = rgb24frame; + l = 0; + + if (format==VIDEO_PALETTE_RGB32) { + /* we need to convert in reverse so as to not overwrite ourselves */ + for (ptr=ptr+length*4/3,i=length-3; i>=0; i-=3) { + *--ptr = 0; + *--ptr = (unsigned char) rgb24frame[i + 2]; + *--ptr = (unsigned char) rgb24frame[i + 1]; + *--ptr = (unsigned char) rgb24frame[i + 0]; + l += 4; + } + } else + for (i=0; i> 3))); + *ptr++ = (unsigned char) (w & 0xFF); + *ptr++ = (unsigned char) (w >> 8); + l += 2; + break; + case VIDEO_PALETTE_RGB555: + w = ((unsigned short) + ((unsigned short) (rgb24frame[i + 2] & 0xf8) << (10 - 3)) | + ((unsigned short) (rgb24frame[i + 1] & 0xf8) << (5 - 3)) | + ((unsigned short) (rgb24frame[i + 0] >> 3))); + *ptr++ = (unsigned char) (w & 0xFF); + *ptr++ = (unsigned char) (w >> 8); + l += 2; + break; + default: + *ptr++ = (219 * Y)/255 + 16; + l++; + *ptr = (112 * U)/127 + 128; /* Cb */ + ptr++; + l++; + *ptr = (112 * V)/127 + 128; /* Cr */ + ptr++; + l++; + } + } + if (format >= VIDEO_PALETTE_PLANAR) { + length = qc_yuv_toplanar(rgb24frame, l, format); + } else { + length = l; + } + return length; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_imag: Start of image processing functions ************************** */ + +/* {{{ [fold] qc_imag_bayer_midvalue(char *bay, int bay_line, int columns, int rows) */ +/* Compute and return the average pixel intensity from the bayer data. + * The result can be used for automatic software exposure/gain control. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + */ +static unsigned char qc_imag_bayer_midvalue(unsigned char *bay, int bay_line, + unsigned int columns, unsigned int rows) +{ + static const unsigned int stepsize = 8; /* Larger = faster and less accurate */ + unsigned char *cur_bay; + unsigned int sum = 0; + int column_cnt; + int row_cnt; + + /* Skip 1/4 of left, right, top, and bottom pixels (use only center pixels) */ + columns /= 2; + rows /= 2; + bay += rows/4*2*bay_line + columns/4*2; + + columns /= stepsize*2; + rows /= stepsize*2; + + row_cnt = rows; + do { + column_cnt = columns; + cur_bay = bay; + do { + sum += cur_bay[0] + cur_bay[1] + cur_bay[bay_line]; /* R + G + B */ + cur_bay += 2*stepsize; + } while (--column_cnt > 0); + bay += 2*stepsize*bay_line; + } while (--row_cnt > 0); + sum /= 3 * columns * rows; + return sum; +} +/* }}} */ +#if COMPRESS +/* {{{ [fold] qc_imag_rgb24_midvalue(char *rgb, int rgb_line, int columns, int rows) */ +/* Compute and return the average pixel intensity from the RGB/BGR24 data. + * The result can be used for automatic software exposure/gain control. + * rgb = points to the RGB image data + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = RGB image size + */ +static unsigned char qc_imag_rgb24_midvalue(unsigned char *rgb, int rgb_line, + unsigned int columns, unsigned int rows) +{ + static const unsigned int stepsize = 8; /* Larger = faster and less accurate */ + unsigned char *cur_rgb; + unsigned int sum = 0; + int column_cnt; + int row_cnt; + + /* Skip 1/4 of left, right, top, and bottom pixels (use only center pixels) */ + columns /= 2; + rows /= 2; + rgb += rows/2*rgb_line + columns/2*3; + + columns /= stepsize; + rows /= stepsize; + + row_cnt = rows; + do { + column_cnt = columns; + cur_rgb = rgb; + do { + sum += cur_rgb[0] + cur_rgb[1] + cur_rgb[2]; /* R + G + B */ + cur_rgb += 3*stepsize; + } while (--column_cnt > 0); + rgb += stepsize*rgb_line; + } while (--row_cnt > 0); + sum /= 3 * columns * rows; + return sum; +} +/* }}} */ +#endif +/* {{{ [fold] qc_imag_userlut(unsigned char (*userlut)[QC_LUT_SIZE], unsigned char (*lut)[QC_LUT_SIZE]) */ +/* Apply user-defined lookup-table to the given preinitialized lut */ +static inline void qc_imag_userlut(unsigned char (*userlut)[QC_LUT_SIZE], unsigned char (*lut)[QC_LUT_SIZE]) +{ + unsigned int i,p; + for (i=0; i<256; i++) { + p = (*lut)[QC_LUT_RED + i]; + p = (*userlut)[QC_LUT_RED + p]; + (*lut)[QC_LUT_RED + i] = p; + } + for (i=0; i<256; i++) { + p = (*lut)[QC_LUT_GREEN + i]; + p = (*userlut)[QC_LUT_GREEN + p]; + (*lut)[QC_LUT_GREEN + i] = p; + } + for (i=0; i<256; i++) { + p = (*lut)[QC_LUT_BLUE + i]; + p = (*userlut)[QC_LUT_BLUE + p]; + (*lut)[QC_LUT_BLUE + i] = p; + } +} +/* }}} */ +/* {{{ [fold] qc_imag_bayer_equalize(char *bay, int bay_line, int columns, int rows, char (*lut)[]) */ +/* Compute and fill a lookup table which will equalize the image. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * lut = lookup table to be filled, 3*256 char array + */ +static void qc_imag_bayer_equalize(unsigned char *bay, int bay_line, + unsigned int columns, unsigned int rows, unsigned char (*lut)[QC_LUT_SIZE]) +{ + static const unsigned int stepsize = 4; /* Larger = faster and less accurate */ + unsigned short red_cnt[256], green_cnt[256], blue_cnt[256]; /* FIXME: how much we can use stack? */ + unsigned int red_sum, green_sum, blue_sum; + unsigned int red_tot, green_tot, blue_tot; + unsigned char *cur_bay; + int i, column_cnt, row_cnt; + + memset(red_cnt, 0, sizeof(red_cnt)); + memset(green_cnt, 0, sizeof(green_cnt)); + memset(blue_cnt, 0, sizeof(blue_cnt)); + + columns /= 2*stepsize; + rows /= 2*stepsize; + + /* Compute histogram */ + row_cnt = rows; + do { + column_cnt = columns; + cur_bay = bay; + do { + green_cnt[cur_bay[0]]++; + red_cnt [cur_bay[1]]++; + blue_cnt [cur_bay[bay_line]]++; + green_cnt[cur_bay[bay_line+1]]++; + cur_bay += 2*stepsize; + } while (--column_cnt > 0); + bay += 2*stepsize*bay_line; + } while (--row_cnt > 0); + + /* Compute lookup table based on the histogram */ + red_tot = columns * rows; /* Total number of pixels of each primary color */ + green_tot = red_tot * 2; + blue_tot = red_tot; + red_sum = 0; + green_sum = 0; + blue_sum = 0; + for (i=0; i<256; i++) { + (*lut)[QC_LUT_RED + i] = 255 * red_sum / red_tot; + (*lut)[QC_LUT_GREEN + i] = 255 * green_sum / green_tot; + (*lut)[QC_LUT_BLUE + i] = 255 * blue_sum / blue_tot; + red_sum += red_cnt[i]; + green_sum += green_cnt[i]; + blue_sum += blue_cnt[i]; + } +} +/* }}} */ +/* {{{ [fold] qc_imag_bayer_lut(char *bay, int bay_line, int columns, int rows, char (*lut)[]) */ +/* Transform pixel values in a bayer image with a given lookup table. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * lut = lookup table to be used, 3*256 char array + */ +static void qc_imag_bayer_lut(unsigned char *bay, int bay_line, + unsigned int columns, unsigned int rows, unsigned char (*lut)[QC_LUT_SIZE]) +{ + unsigned char *cur_bay; + unsigned int total_columns; + + total_columns = columns / 2; /* Number of 2x2 bayer blocks */ + rows /= 2; + do { + columns = total_columns; + cur_bay = bay; + do { + cur_bay[0] = (*lut)[QC_LUT_GREEN + cur_bay[0]]; + cur_bay[1] = (*lut)[QC_LUT_RED + cur_bay[1]]; + cur_bay += 2; + } while (--columns); + bay += bay_line; + columns = total_columns; + cur_bay = bay; + do { + cur_bay[0] = (*lut)[QC_LUT_BLUE + cur_bay[0]]; + cur_bay[1] = (*lut)[QC_LUT_GREEN + cur_bay[1]]; + cur_bay += 2; + } while (--columns); + bay += bay_line; + } while (--rows); +} +/* }}} */ +/* {{{ [fold] qc_imag_writergb(void *addr, int bpp, unsigned char r, unsigned char g, unsigned char b) */ +/* Write RGB pixel value to the given address. + * addr = memory address, to which the pixel is written + * bpp = number of bytes in the pixel (should be 3 or 4) + * r, g, b = pixel component values to be written (red, green, blue) + * Looks horribly slow but the compiler should be able to inline optimize it. + */ +static inline void qc_imag_writergb(void *addr, int bpp, + unsigned char r, unsigned char g, unsigned char b) +{ + if (DEFAULT_BGR) { + /* Blue is first (in the lowest memory address */ + if (bpp==4) { +#if defined(__LITTLE_ENDIAN) + *(unsigned int *)addr = + (unsigned int)r << 16 | + (unsigned int)g << 8 | + (unsigned int)b; +#elif defined(__BIG_ENDIAN) + *(unsigned int *)addr = + (unsigned int)r << 8 | + (unsigned int)g << 16 | + (unsigned int)b << 24; +#else + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = b; + addr2[1] = g; + addr2[2] = r; + addr2[3] = 0; +#endif + } else { + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = b; + addr2[1] = g; + addr2[2] = r; + } + } else { + /* Red is first (in the lowest memory address */ + if (bpp==4) { +#if defined(__LITTLE_ENDIAN) + *(unsigned int *)addr = + (unsigned int)b << 16 | + (unsigned int)g << 8 | + (unsigned int)r; +#elif defined(__BIG_ENDIAN) + *(unsigned int *)addr = + (unsigned int)b << 8 | + (unsigned int)g << 16 | + (unsigned int)r << 24; +#else + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = r; + addr2[1] = g; + addr2[2] = b; + addr2[3] = 0; +#endif + } else { + unsigned char *addr2 = (unsigned char *)addr; + addr2[0] = r; + addr2[1] = g; + addr2[2] = b; + } + } +} +/* }}} */ + +/* + * Raw image data for Bayer-RGB-matrix: + * G R for even rows + * B G for odd rows + */ + +#if 0 +/* {{{ [fold] qc_imag_bay2rgb_noip(char *bay, int bay_line, char *rgb, int rgb_line, int columns, rows, bpp) */ +/* Convert bayer image to RGB image without using interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2391747-2653574 clock cycles for CIF image (Pentium II) */ +/* Do NOT use this routine: cottnoip is faster with better image quality */ +static inline void qc_imag_bay2rgb_noip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration */ + total_columns = columns >> 1; + rows >>= 1; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); +} +/* }}} */ +#endif +/* {{{ [fold] qc_imag_bay2rgb_horip(char *bay, int bay_line, char *rgb, int rgb_line, columns, rows, bpp) */ +/* Convert bayer image to RGB image using fast horizontal-only interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2735776-3095322 clock cycles for CIF image (Pentium II) */ +/* Not recommended: ip seems to be somewhat faster, probably with better image quality. + * cott is quite much faster, but possibly with slightly worse image quality */ +static inline void qc_imag_bay2rgb_horip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + unsigned int columns, unsigned int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + unsigned char red, green, blue; + unsigned int column_cnt, row_cnt; + + /* Process 2 lines and rows per each iteration */ + total_columns = (columns-2) / 2; + row_cnt = rows / 2; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + + do { + qc_imag_writergb(rgb+0, bpp, bay[1], bay[0], bay[bay_line]); + qc_imag_writergb(rgb+rgb_line, bpp, bay[1], bay[0], bay[bay_line]); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + green = ((unsigned int)cur_bay[-1]+cur_bay[1]) / 2; + blue = ((unsigned int)cur_bay[bay_line-1]+cur_bay[bay_line+1]) / 2; + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[0], green, blue); + red = ((unsigned int)cur_bay[0]+cur_bay[2]) / 2; + qc_imag_writergb(cur_rgb+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); + green = ((unsigned int)cur_bay[bay_line]+cur_bay[bay_line+2]) / 2; + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[0], cur_bay[bay_line], blue); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[0], cur_bay[-1], cur_bay[bay_line-1]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[0], cur_bay[bay_line], cur_bay[bay_line-1]); + bay += bay_line2; + rgb += rgb_line2; + } while (--row_cnt); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_ip(char *bay, int bay_line, char *rgb, int rgb_line, columns, rows, bpp) */ +/* Convert bayer image to RGB image using full (slow) linear interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2714077-2827455 clock cycles for CIF image (Pentium II) */ +static inline void qc_imag_bay2rgb_ip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + unsigned int columns, unsigned int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + unsigned char red, green, blue; + unsigned int column_cnt, row_cnt; + + /* Process 2 rows and columns each iteration */ + total_columns = (columns-2) / 2; + row_cnt = (rows-2) / 2; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + + /* First scanline is handled here as a special case */ + qc_imag_writergb(rgb, bpp, bay[1], bay[0], bay[bay_line]); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + green = ((unsigned int)cur_bay[-1] + cur_bay[1] + cur_bay[bay_line]) / 3; + blue = ((unsigned int)cur_bay[bay_line-1] + cur_bay[bay_line+1]) / 2; + qc_imag_writergb(cur_rgb, bpp, cur_bay[0], green, blue); + red = ((unsigned int)cur_bay[0] + cur_bay[2]) / 2; + qc_imag_writergb(cur_rgb+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + green = ((unsigned int)cur_bay[-1] + cur_bay[bay_line]) / 2; + qc_imag_writergb(cur_rgb, bpp, cur_bay[0], green, cur_bay[bay_line-1]); + + /* Process here all other scanlines except first and last */ + bay += bay_line; + rgb += rgb_line; + do { + red = ((unsigned int)bay[-bay_line+1] + bay[bay_line+1]) / 2; + green = ((unsigned int)bay[-bay_line] + bay[1] + bay[bay_line]) / 3; + qc_imag_writergb(rgb+0, bpp, red, green, bay[0]); + blue = ((unsigned int)bay[0] + bay[bay_line2]) / 2; + qc_imag_writergb(rgb+rgb_line, bpp, bay[bay_line+1], bay[bay_line], blue); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + red = ((unsigned int)cur_bay[-bay_line]+cur_bay[bay_line]) / 2; + blue = ((unsigned int)cur_bay[-1]+cur_bay[1]) / 2; + qc_imag_writergb(cur_rgb+0, bpp, red, cur_bay[0], blue); + red = ((unsigned int)cur_bay[-bay_line]+cur_bay[-bay_line+2]+cur_bay[bay_line]+cur_bay[bay_line+2]) / 4; + green = ((unsigned int)cur_bay[0]+cur_bay[2]+cur_bay[-bay_line+1]+cur_bay[bay_line+1]) / 4; + qc_imag_writergb(cur_rgb+bpp, bpp, red, green, cur_bay[1]); + green = ((unsigned int)cur_bay[0]+cur_bay[bay_line2]+cur_bay[bay_line-1]+cur_bay[bay_line+1]) / 4; + blue = ((unsigned int)cur_bay[-1]+cur_bay[1]+cur_bay[bay_line2-1]+cur_bay[bay_line2+1]) / 4; + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line], green, blue); + red = ((unsigned int)cur_bay[bay_line]+cur_bay[bay_line+2]) / 2; + blue = ((unsigned int)cur_bay[1]+cur_bay[bay_line2+1]) / 2; + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, red, cur_bay[bay_line+1], blue); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + red = ((unsigned int)cur_bay[-bay_line] + cur_bay[bay_line]) / 2; + qc_imag_writergb(cur_rgb, bpp, red, cur_bay[0], cur_bay[-1]); + green = ((unsigned int)cur_bay[0] + cur_bay[bay_line-1] + cur_bay[bay_line2]) / 3; + blue = ((unsigned int)cur_bay[-1] + cur_bay[bay_line2-1]) / 2; + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line], green, blue); + bay += bay_line2; + rgb += rgb_line2; + } while (--row_cnt); + + /* Last scanline is handled here as a special case */ + green = ((unsigned int)bay[-bay_line] + bay[1]) / 2; + qc_imag_writergb(rgb, bpp, bay[-bay_line+1], green, bay[0]); + cur_bay = bay + 1; + cur_rgb = rgb + bpp; + column_cnt = total_columns; + do { + blue = ((unsigned int)cur_bay[-1] + cur_bay[1]) / 2; + qc_imag_writergb(cur_rgb, bpp, cur_bay[-bay_line], cur_bay[0], blue); + red = ((unsigned int)cur_bay[-bay_line] + cur_bay[-bay_line+2]) / 2; + green = ((unsigned int)cur_bay[0] + cur_bay[-bay_line+1] + cur_bay[2]) / 3; + qc_imag_writergb(cur_rgb+bpp, bpp, red, green, cur_bay[1]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--column_cnt); + qc_imag_writergb(cur_rgb, bpp, cur_bay[-bay_line], cur_bay[0], cur_bay[-1]); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_cott(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp) */ +/* Convert bayer image to RGB image using 0.5 displaced light linear interpolation. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2167685 clock cycles for CIF image (Pentium II) */ +/* Original idea for this routine from Cagdas Ogut */ +static inline void qc_imag_bay2rgb_cott(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration, but process the last row and column separately */ + total_columns = (columns>>1) - 1; + rows = (rows>>1) - 1; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1]) /2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], ((unsigned int)cur_bay[2] + cur_bay[bay_line+1]) /2, cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], ((unsigned int)cur_bay[bay_line2] + cur_bay[bay_line+1]) /2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], ((unsigned int)cur_bay[bay_line2+2] + cur_bay[bay_line+1])/2, cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], ((unsigned int)cur_bay[bay_line2] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + /* Last scanline handled here as special case */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], ((unsigned int)cur_bay[2] + cur_bay[bay_line+1])/2, cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + /* Last lower-right pixel is handled here as special case */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], ((unsigned int)cur_bay[0] + cur_bay[bay_line+1])/2, cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_cottnoip(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp) */ +/* Convert bayer image to RGB image using 0.5 displaced nearest neighbor. + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + */ +/* Execution time: 2133302 clock cycles for CIF image (Pentium II), fastest */ +static inline void qc_imag_bay2rgb_cottnoip(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + unsigned char *cur_bay, *cur_rgb; + int bay_line2, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration, but process the last row and column separately */ + total_columns = (columns>>1) - 1; + rows = (rows>>1) - 1; + bay_line2 = 2*bay_line; + rgb_line2 = 2*rgb_line; + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[2], cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[bay_line2+1], cur_bay[bay_line+1], cur_bay[bay_line]); + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + /* Last scanline handled here as special case */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[2], cur_bay[bay_line+2]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line+2]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + /* Last lower-right pixel is handled here as special case */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_gptm_fast(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp) */ +/* Convert Bayer image to RGB image using Generalized Pei-Tam method + * Uses fixed weights */ +/* Execution time: 3795517 clock cycles */ +static inline void qc_imag_bay2rgb_gptm_fast(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp) +{ + int r,g,b,w; + unsigned char *cur_bay, *cur_rgb; + int bay_line2, bay_line3, rgb_line2; + int total_columns; + + /* Process 2 lines and rows per each iteration, but process the first and last two columns and rows separately */ + total_columns = (columns>>1) - 2; + rows = (rows>>1) - 2; + bay_line2 = 2*bay_line; + bay_line3 = 3*bay_line; + rgb_line2 = 2*rgb_line; + + /* Process first two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + bay += bay_line2; + rgb += rgb_line2; + + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + + /* Process first 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + + do { + w = 4*cur_bay[0] - (cur_bay[-bay_line-1] + cur_bay[-bay_line+1] + cur_bay[bay_line-1] + cur_bay[bay_line+1]); + r = (2*(cur_bay[-1] + cur_bay[1]) + w) >> 2; + b = (2*(cur_bay[-bay_line] + cur_bay[bay_line]) + w) >> 2; + qc_imag_writergb(cur_rgb+0, bpp, CLIP(r,0,255), cur_bay[0], CLIP(b,0,255)); + + w = 4*cur_bay[1] - (cur_bay[-bay_line2+1] + cur_bay[-1] + cur_bay[3] + cur_bay[bay_line2+1]); + g = (2*(cur_bay[-bay_line+1] + cur_bay[0] + cur_bay[2] + cur_bay[bay_line+1]) + w) >> 3; + b = (2*(cur_bay[-bay_line] + cur_bay[-bay_line+2] + cur_bay[bay_line] + cur_bay[bay_line+2]) + w) >> 3; + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], CLIP(g,0,255), CLIP(b,0,255)); + + w = 4*cur_bay[bay_line] - (cur_bay[-bay_line] + cur_bay[bay_line-2] + cur_bay[bay_line+2] + cur_bay[bay_line3]); + r = ((cur_bay[-1] + cur_bay[1] + cur_bay[bay_line2-1] + cur_bay[bay_line2+1]) + w) >> 2; + g = ((cur_bay[0] + cur_bay[bay_line-1] + cur_bay[bay_line+1] + cur_bay[bay_line2]) + w) >> 2; + qc_imag_writergb(cur_rgb+rgb_line, bpp, CLIP(r,0,255), CLIP(g,0,255), cur_bay[bay_line]); + + w = 4*cur_bay[bay_line+1] - (cur_bay[0] + cur_bay[2] + cur_bay[bay_line2] + cur_bay[bay_line2+2]); + r = (2*(cur_bay[1] + cur_bay[bay_line2+1]) + w) >> 2; + b = (2*(cur_bay[bay_line] + cur_bay[bay_line+2]) + w) >> 2; + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, CLIP(r,0,255), cur_bay[bay_line+1], CLIP(b,0,255)); + + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + + /* Process last 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + + /* Process last two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); +} +/* }}} */ +/* {{{ [fold] qc_imag_bay2rgb_gptm(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp, int sharpness) */ +/* Convert Bayer image to RGB image using Generalized Pei-Tam method (See: + * "Effective Color Interpolation in CCD Color Filter Arrays Using Signal Correlation" + * IEEE Transactions on Circuits and Systems for Video Technology, vol. 13, no. 6, June 2003. + * Note that this is much improved version of the algorithm described in the paper) + * bay = points to the bayer image data (upper left pixel is green) + * bay_line = bytes between the beginnings of two consecutive rows + * rgb = points to the rgb image data that is written + * rgb_line = bytes between the beginnings of two consecutive rows + * columns, rows = bayer image size (both must be even) + * bpp = number of bytes in each pixel in the RGB image (should be 3 or 4) + * sharpness = how sharp the image should be, between 0..65535 inclusive. + * 23170 gives in theory image that corresponds to the original + * best, but human eye likes slightly sharper picture... 32768 is a good bet. + * When sharpness = 0, this routine is same as bilinear interpolation. + */ +/* Execution time: 4344042 clock cycles for CIF image (Pentium II) */ +static inline void qc_imag_bay2rgb_gptm(unsigned char *bay, int bay_line, + unsigned char *rgb, int rgb_line, + int columns, int rows, int bpp, unsigned int sharpness) +{ + + /* 0.8 fixed point weights, should be between 0-256. Larger value = sharper, zero corresponds to bilinear interpolation. */ + /* Best PSNR with sharpness = 23170 */ + static const int wrg0 = 144; /* Weight for Red on Green */ + static const int wbg0 = 160; + static const int wgr0 = 120; + static const int wbr0 = 192; + static const int wgb0 = 120; + static const int wrb0 = 168; + + int wrg; + int wbg; + int wgr; + int wbr; + int wgb; + int wrb; + + unsigned int wu; + int r,g,b,w; + unsigned char *cur_bay, *cur_rgb; + int bay_line2, bay_line3, rgb_line2; + int total_columns; + + /* Compute weights */ + wu = (sharpness * sharpness) >> 16; + wu = (wu * wu) >> 16; + wrg = (wrg0 * wu) >> 10; + wbg = (wbg0 * wu) >> 10; + wgr = (wgr0 * wu) >> 10; + wbr = (wbr0 * wu) >> 10; + wgb = (wgb0 * wu) >> 10; + wrb = (wrb0 * wu) >> 10; + + /* Process 2 lines and rows per each iteration, but process the first and last two columns and rows separately */ + total_columns = (columns>>1) - 2; + rows = (rows>>1) - 2; + bay_line2 = 2*bay_line; + bay_line3 = 3*bay_line; + rgb_line2 = 2*rgb_line; + + /* Process first two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + bay += bay_line2; + rgb += rgb_line2; + + do { + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns; + + /* Process first 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + + do { + w = 4*cur_bay[0] - (cur_bay[-bay_line-1] + cur_bay[-bay_line+1] + cur_bay[bay_line-1] + cur_bay[bay_line+1]); + r = (512*(cur_bay[-1] + cur_bay[1]) + w*wrg) >> 10; + b = (512*(cur_bay[-bay_line] + cur_bay[bay_line]) + w*wbg) >> 10; + qc_imag_writergb(cur_rgb+0, bpp, CLIP(r,0,255), cur_bay[0], CLIP(b,0,255)); + + w = 4*cur_bay[1] - (cur_bay[-bay_line2+1] + cur_bay[-1] + cur_bay[3] + cur_bay[bay_line2+1]); + g = (256*(cur_bay[-bay_line+1] + cur_bay[0] + cur_bay[2] + cur_bay[bay_line+1]) + w*wgr) >> 10; + b = (256*(cur_bay[-bay_line] + cur_bay[-bay_line+2] + cur_bay[bay_line] + cur_bay[bay_line+2]) + w*wbr) >> 10; + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], CLIP(g,0,255), CLIP(b,0,255)); + + w = 4*cur_bay[bay_line] - (cur_bay[-bay_line] + cur_bay[bay_line-2] + cur_bay[bay_line+2] + cur_bay[bay_line3]); + r = (256*(cur_bay[-1] + cur_bay[1] + cur_bay[bay_line2-1] + cur_bay[bay_line2+1]) + w*wrb) >> 10; + g = (256*(cur_bay[0] + cur_bay[bay_line-1] + cur_bay[bay_line+1] + cur_bay[bay_line2]) + w*wgb) >> 10; + qc_imag_writergb(cur_rgb+rgb_line, bpp, CLIP(r,0,255), CLIP(g,0,255), cur_bay[bay_line]); + + w = 4*cur_bay[bay_line+1] - (cur_bay[0] + cur_bay[2] + cur_bay[bay_line2] + cur_bay[bay_line2+2]); + r = (512*(cur_bay[1] + cur_bay[bay_line2+1]) + w*wrg) >> 10; + b = (512*(cur_bay[bay_line] + cur_bay[bay_line+2]) + w*wbg) >> 10; + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, CLIP(r,0,255), cur_bay[bay_line+1], CLIP(b,0,255)); + + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); + + /* Process last 2x2 pixel block in a row here */ + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + + bay += bay_line2; + rgb += rgb_line2; + } while (--rows); + + /* Process last two pixel rows here */ + cur_bay = bay; + cur_rgb = rgb; + columns = total_columns + 2; + do { + qc_imag_writergb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + qc_imag_writergb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); + cur_bay += 2; + cur_rgb += 2*bpp; + } while (--columns); +} +/* }}} */ +/* {{{ [fold] qc_imag_rgbbgr(unsigned char *dst, int pixels, int bpp) */ +/* Convert RGB image to BGR or vice versa with the given number of pixels and + * bytes per pixel + */ +static void inline qc_imag_rgbbgr(unsigned char *dst, int pixels, int bpp) +{ + unsigned char r,b; + do { + r = dst[0]; + b = dst[2]; + dst[0] = b; + dst[2] = r; + dst += bpp; + } while (--pixels); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_fmt: Start of generic format query functions ********************** */ + +/* {{{ [fold] struct qc_fmt_format: a format definition */ +struct qc_fmt_format { + u32 fcc; /* M$ defined fourcc code, see http://www.fourcc.org */ + signed char bpp; /* 0=variable, -1=unknown (FIXME:what bpps do AVIs use here?) */ + char order; /* 'R' = RGB, 'B'=BGR, 0=not specified */ + unsigned char nr, ng, nb; /* Number of red, green, blue levels (0=256 levels) */ + char *name; /* Human-readable name */ + Bool supported; /* Can be converted to? */ + /* Here we could add a pointer to list containing conversion routines to other fourcc's */ + /* Then write code to create minimum spanning tree of format conversions */ + /* Include estimated cost per pixel to apply a conversion routine to weight edges */ +}; +/* }}} */ +/* {{{ [fold] List of supported formats */ +#define BF_RGB(r,g,b) 'R', (b)&0xFF, (g)&0xFF, (r)&0xFF +#define BF_BGR(r,g,b) 'B', (b)&0xFF, (g)&0xFF, (r)&0xFF +#define NO_BF 0, 0, 0, 0 +#define FORMAT(ID,FCC1,FCC2,FCC3,FCC4,BPP,BF,NAME,SUPP) \ +static const struct qc_fmt_format qc_fmt_formats_##ID = { v4l2_fourcc(FCC1,FCC2,FCC3,FCC4), BPP, BF, NAME, SUPP } +FORMAT(Y800, 'Y','8','0','0', 8, NO_BF, "GREY", TRUE); +FORMAT(RGB_HI, 'q','c','R','B', 8, BF_RGB(6, 6, 6), "HI240", FALSE); /* Not sure: BF_RGB or BF_BGR? Same as BT20? Don't think so */ +FORMAT(RGB_332, 3,0,0,0, 8, BF_RGB(8, 8, 4), "RGB332", FALSE); +/* Little endian RGB formats (least significant byte at lowest address) */ +FORMAT(RGB_555L, 3,0,0,0, 16, BF_RGB(32, 32, 32), "RGB555L",TRUE); /* Should this be 15 or 16 bpp? Is this same as RGB2? */ +FORMAT(RGB_565L, 3,0,0,0, 16, BF_RGB(32, 64, 32), "RGB565L",TRUE); /* Is this same as RGB2? */ +FORMAT(RGB_24L, 'R','G','B','2', 24, BF_RGB(256, 256, 256), "RGB24L", TRUE); +FORMAT(BGR_24L, 'R','G','B','2', 24, BF_BGR(256, 256, 256), "BGR24L", TRUE); +FORMAT(RGB_32L, 'R','G','B','2', 32, BF_RGB(256, 256, 256), "RGB32L", TRUE); +FORMAT(BGR_32L, 'R','G','B','2', 32, BF_BGR(256, 256, 256), "BGR32L", TRUE); +/* Big endian RGB formats (most significant byte at lowest address) */ +FORMAT(RGB_555B, 'q','c','R','B', 16, BF_RGB(32, 32, 32), "RGB555B",FALSE); +FORMAT(RGB_565B, 'q','c','R','B', 16, BF_RGB(32, 64, 32), "RGB565B",FALSE); +/* Component YUV formats */ +FORMAT(YUY2, 'Y','U','Y','2', 16, NO_BF, "YUV422", TRUE); /* 4:2:2 packed pixel YUYV */ +FORMAT(UYVY, 'U','Y','V','Y', 16, NO_BF, "UYVY", FALSE); +FORMAT(IYUV, 'I','Y','U','V', 12, NO_BF, "YUV420", FALSE); +/* Planar YUV formats */ +FORMAT(YV12, 'Y','V','1','2', 12, NO_BF, "YV12", FALSE); +FORMAT(YVU9, 'Y','V','U','9', 9, NO_BF, "YVU9", FALSE); +FORMAT(Y41P, 'Y','4','1','P', 12, NO_BF, "Y41P", FALSE); /* 4:1:1 packed pixel UYVY UYVY YYYY */ +FORMAT(qcY1, 'q','c','Y','1', 12, NO_BF, "YUV411P", FALSE); /* Like Y41P but planar and Y, U and V planes are in this order */ +FORMAT(qcY2, 'q','c','Y','2', 16, NO_BF, "YUV422P", TRUE); /* Like YUY2 but planar */ +FORMAT(qcV1, 'q','c','V','1', 12, NO_BF, "YVU411P", FALSE); /* Like qcY1 but V and U planes are in this order */ +FORMAT(qcV2, 'q','c','V','2', 16, NO_BF, "YVU422P", FALSE); /* Like qcY2 but V and U planes are in this order */ +FORMAT(qcU9, 'q','c','U','9', 9, NO_BF, "YUV410P", TRUE); /* Like YVU9 but U and V planes are in this order */ +FORMAT(qcYY, 'q','c','Y','Y', 12, NO_BF, "YYUV", FALSE); /* Packed 4:2:2 sampling, Y, Y, U, V */ +FORMAT(NV12, 'N','V','1','2', 12, NO_BF, "NV12", FALSE); +FORMAT(NV21, 'N','V','2','1', 12, NO_BF, "NV21", FALSE); +/* Special formats */ +FORMAT(qcBT, 'q','c','B','T', -1, NO_BF, "BT848 RAW", FALSE); /* RAW is raw scanline data sampled (before PAL decoding) */ +FORMAT(qcBR, 'q','c','B','R', 8, NO_BF, "BAYER", TRUE); /* Same as STVA? */ +FORMAT(qcMJ, 'q','c','M','J', 0, NO_BF, "MJPEG", TRUE); /* Same as MJPG? */ +FORMAT(qcWN, 'q','c','W','N', -1, NO_BF, "Winnov hw", FALSE); /* Same as WNV1 (or CHAM, WINX, YUV8)? */ +/* }}} */ +/* {{{ [fold] struct qc_fmt_alias: Alias fourcc codes for above formats */ +static struct qc_fmt_alias { + u32 fcc; + struct qc_fmt_format const *format; +} const qc_fmt_aliases[] = { + { v4l2_fourcc(0,0,0,0), &qc_fmt_formats_RGB_24L }, /* Could be any format with fourcc 'RGB2' */ + { v4l2_fourcc('Y','8',' ',' '), &qc_fmt_formats_Y800 }, + { v4l2_fourcc('Y','U','N','V'), &qc_fmt_formats_YUY2 }, + { v4l2_fourcc('V','4','2','2'), &qc_fmt_formats_YUY2 }, + { v4l2_fourcc('Y','4','2','2'), &qc_fmt_formats_UYVY }, + { v4l2_fourcc('U','Y','N','V'), &qc_fmt_formats_UYVY }, + { v4l2_fourcc('I','4','2','0'), &qc_fmt_formats_IYUV }, +}; +/* }}} */ +/* {{{ [fold] struct qc_fmt_palette: table to convert V4L code into fourcc, supported formats */ +static struct qc_fmt_palette { + int palette; /* V4L1 standard palette type */ + struct qc_fmt_format const *format; +} const qc_fmt_palettes[] = { + { VIDEO_PALETTE_GREY, &qc_fmt_formats_Y800 }, + { VIDEO_PALETTE_HI240, &qc_fmt_formats_RGB_HI }, + /* RGB formats */ + { VIDEO_PALETTE_RGB565, &qc_fmt_formats_RGB_565L }, + { VIDEO_PALETTE_RGB24, &qc_fmt_formats_BGR_24L }, + { VIDEO_PALETTE_RGB32, &qc_fmt_formats_BGR_32L }, + { VIDEO_PALETTE_RGB555, &qc_fmt_formats_RGB_555L }, + /* Component YUV formats */ + { VIDEO_PALETTE_YUV422, &qc_fmt_formats_YUY2 }, /* Assume this is YUY2, even though V4L1 docs say this is 8 bpp format */ + { VIDEO_PALETTE_YUYV, &qc_fmt_formats_YUY2 }, /* Benedict Bridgwater : Bt848 maps this to Y41P, but it is simply wrong--we follow V4L2 v4l_compat.c */ + { VIDEO_PALETTE_UYVY, &qc_fmt_formats_UYVY }, + { VIDEO_PALETTE_YUV420, &qc_fmt_formats_IYUV }, /* Assume this is planar, even though V4L1 header file indicates otherwise */ + { VIDEO_PALETTE_YUV411, &qc_fmt_formats_qcY1 }, /* Assume this is planar, even though V4L1 header file indicates otherwise (could be also fourcc 'Y41P') -from benedict */ + { VIDEO_PALETTE_RAW, &qc_fmt_formats_qcBT }, + /* Planar YUV formats */ + { VIDEO_PALETTE_YUV422P, &qc_fmt_formats_qcY2 }, + { VIDEO_PALETTE_YUV411P, &qc_fmt_formats_qcY1 }, + { VIDEO_PALETTE_YUV420P, &qc_fmt_formats_IYUV }, + { VIDEO_PALETTE_YUV410P, &qc_fmt_formats_qcU9 }, + /* Special formats */ + { VIDEO_PALETTE_BAYER, &qc_fmt_formats_qcBR }, + { VIDEO_PALETTE_MJPEG, &qc_fmt_formats_qcMJ }, +}; +/* }}} */ +/* {{{ [fold] struct qc_fmt_v4l2: V4L2 defines its own conflicting format codes */ +static struct qc_fmt_v4l2 { + u32 v4l2code; + struct qc_fmt_format const *format; +} const qc_fmt_v4l2s[] = { + { v4l2_fourcc('R','G','B','1'), &qc_fmt_formats_RGB_332 }, /* V4L2_PIX_FMT_RGB332 8 RGB-3-3-2 */ + { v4l2_fourcc('R','G','B','O'), &qc_fmt_formats_RGB_555L }, /* V4L2_PIX_FMT_RGB555 16 RGB-5-5-5 */ + { v4l2_fourcc('R','G','B','P'), &qc_fmt_formats_RGB_565L }, /* V4L2_PIX_FMT_RGB565 16 RGB-5-6-5 */ + { v4l2_fourcc('R','G','B','Q'), &qc_fmt_formats_RGB_555B }, /* V4L2_PIX_FMT_RGB555X 16 RGB-5-5-5 BE */ + { v4l2_fourcc('R','G','B','R'), &qc_fmt_formats_RGB_565B }, /* V4L2_PIX_FMT_RGB565X 16 RGB-5-6-5 BE */ + { v4l2_fourcc('B','G','R','3'), &qc_fmt_formats_BGR_24L }, /* V4L2_PIX_FMT_BGR24 24 BGR-8-8-8 */ + { v4l2_fourcc('R','G','B','3'), &qc_fmt_formats_RGB_24L }, /* V4L2_PIX_FMT_RGB24 24 RGB-8-8-8 */ + { v4l2_fourcc('B','G','R','4'), &qc_fmt_formats_BGR_32L }, /* V4L2_PIX_FMT_BGR32 32 BGR-8-8-8-8 */ + { v4l2_fourcc('R','G','B','4'), &qc_fmt_formats_RGB_32L }, /* V4L2_PIX_FMT_RGB32 32 RGB-8-8-8-8 */ + { v4l2_fourcc('G','R','E','Y'), &qc_fmt_formats_Y800 }, /* V4L2_PIX_FMT_GREY 8 Greyscale */ + { v4l2_fourcc('Y','V','U','9'), &qc_fmt_formats_YVU9 }, /* V4L2_PIX_FMT_YVU410 9 YVU 4:1:0 */ + { v4l2_fourcc('Y','V','1','2'), &qc_fmt_formats_YV12 }, /* V4L2_PIX_FMT_YVU420 12 YVU 4:2:0 */ + { v4l2_fourcc('Y','U','Y','V'), &qc_fmt_formats_YUY2 }, /* V4L2_PIX_FMT_YUYV 16 YUV 4:2:2 */ + { v4l2_fourcc('Y','U','Y','2'), &qc_fmt_formats_YUY2 }, /* V4L2_PIX_FMT_YUY2 16 YUV 4:2:2: undocumented, guess same as YUY2 */ + { v4l2_fourcc('U','Y','V','Y'), &qc_fmt_formats_UYVY }, /* V4L2_PIX_FMT_UYVY 16 YUV 4:2:2 */ + { v4l2_fourcc('Y','4','1','P'), &qc_fmt_formats_Y41P }, /* V4L2_PIX_FMT_Y41P 12 YUV 4:1:1 */ + { v4l2_fourcc('Y','U','V','9'), &qc_fmt_formats_qcU9 }, /* V4L2_PIX_FMT_YUV410 9 YUV 4:1:0 */ + { v4l2_fourcc('Y','U','1','2'), &qc_fmt_formats_IYUV }, /* V4L2_PIX_FMT_YUV420 12 YUV 4:2:0 */ + { v4l2_fourcc('P','4','2','2'), &qc_fmt_formats_qcY2 }, /* V4L2_PIX_FMT_YUV422P 16 YUV422 planar */ + { v4l2_fourcc('P','4','1','1'), &qc_fmt_formats_qcY1 }, /* V4L2_PIX_FMT_YUV411P 16 YUV411 planar: assume bpp should be 12 */ + { v4l2_fourcc('N','V','1','2'), &qc_fmt_formats_NV12 }, /* V4L2_PIX_FMT_NV12 12 Y/UV 4:2:0 */ + { v4l2_fourcc('4','2','2','P'), &qc_fmt_formats_qcV2 }, /* V4L2_PIX_FMT_YVU422P 16 YVU422 planar */ + { v4l2_fourcc('4','1','1','P'), &qc_fmt_formats_qcV1 }, /* V4L2_PIX_FMT_YVU411P 16 YVU411 planar: assume bpp should be 12 */ + { v4l2_fourcc('Y','Y','U','V'), &qc_fmt_formats_qcYY }, /* V4L2_PIX_FMT_YYUV 16 YUV 4:2:2: undocumented, guess this is qc YY */ + { v4l2_fourcc('H','I','2','4'), &qc_fmt_formats_RGB_HI }, /* V4L2_PIX_FMT_HI240 8 8-bit color */ + { v4l2_fourcc('N','V','2','1'), &qc_fmt_formats_NV21 }, /* V4L2_PIX_FMT_NV21 12 Y/UV 4:2:0 */ + { v4l2_fourcc('W','N','V','A'), &qc_fmt_formats_qcWN }, /* V4L2_PIX_FMT_WNVA Winnov hw compres */ +}; +/* }}} */ + +/* {{{ [fold] qc_fmt_issupported(int palette) */ +/* Check the format (can be called even before qc_fmt_init) */ +int qc_fmt_issupported(int palette) +{ + int i; + for (i=0; isupported) + return 0; + } + return -EINVAL; +} +/* }}} */ +/* {{{ [fold] qc_fmt_getname(int palette) */ +/* Return the format name (can be called even before qc_fmt_init) */ +const char *qc_fmt_getname(int palette) +{ + int i; + for (i=0; iname; + } + return "Unknown"; +} +/* }}} */ +/* {{{ [fold] qc_fmt_getdepth(int palette) */ +/* Return bits per pixel for the format, or + * 0=variable number (compressed formats), -1=unknown + * (can be called even before qc_fmt_init) */ +int qc_fmt_getdepth(int palette) +{ + int i; + for (i=0; ibpp; + } + return -1; /* Unknown bit depth */ +} +/* }}} */ +/* {{{ [fold] qc_fmt_init(struct quickcam *qc) */ +int qc_fmt_init(struct quickcam *qc) +{ + int r = 0; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_fmt_init(qc=%p/compr=%i)",qc,qc->settings.compress); +#if COMPRESS + if (qc->settings.compress) { + qc->fmt_data.compress = TRUE; + r = qc_mjpeg_init(&qc->fmt_data.mjpeg_data, 24, DEFAULT_BGR); + } else { + qc->fmt_data.compress = FALSE; + } +#endif + if (r>=0) IDEBUG_INIT(qc->fmt_data); + return r; +} +/* }}} */ +/* {{{ [fold] qc_fmt_exit(struct quickcam *qc) */ +void qc_fmt_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_fmt_exit(qc=%p)",qc); +#if COMPRESS + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_fmt_exit/compress=%i",qc->fmt_data.compress); + if (qc->fmt_data.compress) qc_mjpeg_exit(&qc->fmt_data.mjpeg_data); + POISON(qc->fmt_data.compress); + POISON(qc->fmt_data.mjpeg_data); +#endif + POISON(qc->fmt_data.lut); + IDEBUG_EXIT_NOPOISON(qc->fmt_data); +} +/* }}} */ +/* {{{ [fold] qc_fmt_convert(struct quickcam *qc, unsigned char *src, unsigned int src_len, unsigned char *dst, unsigned int dst_len, int *midvalue) */ +/* Called after each full frame of bayer or compressed image obtained */ +/* Convert camera data in src to the application requested palette in dst */ +/* Return negative error code if failure, otherwise data length stored in dst */ +/* src_len is the length of actual data in src, dst_len is the maximum data size storable in dst */ +/* Also src buffer may be modified */ +/* Return image average brightness in midvalue (or -1 if not computed) */ +int qc_fmt_convert(struct quickcam *qc, unsigned char *src, unsigned int src_len, unsigned char *dst, unsigned int dst_len, int *midvalue) +{ + signed int originx, originy; /* Upper-left corner coordinates of the capture window in the bayer image */ + unsigned char *bayerwin; + int length; /* Converted image data length in bytes */ + int r = 0; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_imag_convert(qc=%p,src=%p,src_len=%i,dst=%p,dst_len=%i)",qc,src,src_len,dst,dst_len); + if (PARANOID && (qc==NULL || src==NULL || dst==NULL)) { PRINTK(KERN_CRIT,"NULL"); return -EINVAL; } + if (PARANOID && midvalue==NULL) { PRINTK(KERN_CRIT,"NULL"); return -EINVAL; } + IDEBUG_TEST(qc->fmt_data); + *midvalue = -1; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("sensor_width=%i sensor_height=%i vwin.width=%i vwin.height=%i", + qc->sensor_data.width,qc->sensor_data.height,qc->vwin.width,qc->vwin.height); + + if (qc->sensor_data.width < qc->vwin.width || qc->sensor_data.height < qc->vwin.height) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("sensor window is smaller than requested"); + r = -ENOMSG; + goto fail; + } + +#if DUMPDATA + if (midvalue) *midvalue = -1; + memset(dst, 0, dst_len); + memcpy(dst, src, src_len>dst_len ? dst_len : src_len); + length = (int)qc->vwin.width * (int)qc->vwin.height * 3; + return length; +#endif + +#if COMPRESS + if (!qc->sensor_data.compress) { +#endif + /* src buffer contains fixed length data in bayer format */ + /* sensor_data.height/width = frame size that is captured from the camera */ + /* vwin.height/width = frame size that the application is expecting */ + + /* Check if src buffer contains enough data */ + if (src_len < qc->sensor_data.width * qc->sensor_data.height) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("too little data by %i (expected %i)", qc->sensor_data.width*qc->sensor_data.height - src_len, qc->sensor_data.width * qc->sensor_data.height); + r = -EBADE; + goto fail; + } + /* calculate view window origin inside the whole frame */ + originy = ((signed int)qc->sensor_data.height - (signed int)qc->vwin.height) / 2; + originx = ((signed int)qc->sensor_data.width - (signed int)qc->vwin.width) / 2; + originx &= ~1; /* Set upper-left corner to a even coordinate */ + originy &= ~1; /* so that the first bayer pixel is green */ + bayerwin = src + originy * qc->sensor_data.width + originx; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("originy=%i originx=%i", originy,originx); + + if (qc->settings.adaptive && midvalue!=NULL) + *midvalue = qc_imag_bayer_midvalue(bayerwin, qc->sensor_data.width, qc->vwin.width, qc->vwin.height); + if (qc->settings.equalize || qc->settings.userlut) { + if (qc->settings.equalize) { + qc_imag_bayer_equalize(bayerwin, qc->sensor_data.width, qc->vwin.width, qc->vwin.height, &qc->fmt_data.lut); + } else { + /* Initialize LUT */ + int i; + for (i=0; i<256; i++) qc->fmt_data.lut[QC_LUT_RED+i] = i; + for (i=0; i<256; i++) qc->fmt_data.lut[QC_LUT_GREEN+i] = i; + for (i=0; i<256; i++) qc->fmt_data.lut[QC_LUT_BLUE+i] = i; + } + if (qc->settings.userlut) { + qc_imag_userlut(&qc->fmt_data.userlut, &qc->fmt_data.lut); + } + /* Could do here other effects to the lookup table */ + qc_imag_bayer_lut(bayerwin, qc->sensor_data.width, qc->vwin.width, qc->vwin.height, &qc->fmt_data.lut); + } + + if (qc->vpic.palette==VIDEO_PALETTE_BAYER) { + int i; + length = (int)qc->vwin.width * (int)qc->vwin.height; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + /* It would be more efficient to capture data directly to the mmapped buffer, + * but more complex and hardly any application will use bayer palette anyway */ + for (i=0; ivwin.height; i++) { + memcpy(dst, bayerwin, qc->vwin.width); + bayerwin += qc->sensor_data.width; + dst += qc->vwin.width; + } + } else { + /* Convert the current frame to RGB */ + length = (int)qc->vwin.width * (int)qc->vwin.height * 3; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + switch (qc->settings.quality) { + case 0: + qc_imag_bay2rgb_cottnoip(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 1: + qc_imag_bay2rgb_cott(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 2: + qc_imag_bay2rgb_horip(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 3: + qc_imag_bay2rgb_ip(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + default: + case 4: + qc_imag_bay2rgb_gptm_fast(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3); + break; + case 5: + qc_imag_bay2rgb_gptm(bayerwin, qc->sensor_data.width, + dst, 3*qc->vwin.width, + qc->vwin.width, qc->vwin.height, 3, qc->vpic.whiteness); + break; + } + goto rgb24; + } + +#if COMPRESS + } else { + /* src buffer contains variable length data in mjpeg format */ + if (qc->vpic.palette==VIDEO_PALETTE_MJPEG) { + /* Directly copy data from src to dst, can not resize */ + length = src_len; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + memcpy(dst, src, src_len); + } else { + /* Decode compressed images */ + if (!qc->fmt_data.compress) { + r = -EINVAL; + goto fail; + } + length = qc->sensor_data.width * qc->sensor_data.height * 3; + if (length > dst_len) { + r = -ENOSPC; + goto fail; + } + r = qc_mjpeg_decode(&qc->fmt_data.mjpeg_data, src, src_len, dst); + if (r<0) goto fail; + + if ((int)qc->vwin.width < qc->sensor_data.width || (int)qc->vwin.height < qc->sensor_data.height) { + /* User requested smaller image than camera sent, so crop the image */ + unsigned char *s, *d = dst; + int i; + s = dst; + s += (qc->sensor_data.height - (int)qc->vwin.height)/2 * qc->sensor_data.width*3; + s += (qc->sensor_data.width - (int)qc->vwin.width)/2 * 3; + for (i=0; ivwin.height; i++) { + memcpy(d, s, (int)qc->vwin.width*3); + s += qc->sensor_data.width * 3; + d += (int)qc->vwin.width * 3; + } + /* vwin.width/height is always smaller or equal to sensor_data.width/height */ + length = (int)qc->vwin.width * (int)qc->vwin.height * 3; + } + if (qc->settings.adaptive && midvalue!=NULL) *midvalue = qc_imag_rgb24_midvalue(dst, 3*qc->sensor_data.width, (int)qc->vwin.width, (int)qc->vwin.height); + goto rgb24; + } + } +#endif + return length; + +rgb24: /* We have now RGB (24 bpp) data in dst. If some other format is desired, */ + /* convert the RGB image to it (e.g. YUV) */ + +#ifdef DEBUG +#if 1 +{ +/* Draw red rectangle around image (useful for debugging boundaries) */ +static const int R = 255; +static const int G = 0; +static const int B = 0; + int ty,tx; + for (tx=0; txvwin.width; tx++) { + ty=0; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + ty=qc->vwin.height-1; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + } + for (ty=0; tyvwin.height; ty++) { + tx=0; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + tx=qc->vwin.width-1; + dst[ty*qc->vwin.width*3+tx*3] = B; + dst[ty*qc->vwin.width*3+tx*3+1] = G; + dst[ty*qc->vwin.width*3+tx*3+2] = R; + } +} +#endif +#endif + + if (qc->vpic.palette != VIDEO_PALETTE_RGB24) { + // FIXME: should check here that dst_len <= resulted image length + length = qc_yuv_rgb2yuv(dst, length, qc->vpic.palette); + } else if (qc->settings.compat_torgb) { + qc_imag_rgbbgr(dst, length/3, 3); + } + return length; + +fail: if (qcdebug&(QC_DEBUGERRORS|QC_DEBUGLOGIC)) PDEBUG("failed qc_imag_convert()=%i",r); + return r; +} +/* }}} */ + +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/Kconfig +++ linux-2.6.28/ubuntu/qc-usb/Kconfig @@ -0,0 +1,4 @@ +config QC_USB + tristate "Quickcam USB Driver" + default m + depends on USB --- linux-2.6.28.orig/ubuntu/qc-usb/qc-pb0100.c +++ linux-2.6.28/ubuntu/qc-usb/qc-pb0100.c @@ -0,0 +1,377 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ +/* + * qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * pb0100.c - PB0100 Sensor Implementation + * + * 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 "quickcam.h" + +/* I2C Address */ +#define PB_ADDR 0xBA + +/* {{{ [fold] I2C Registers */ +#define PB_IDENT 0x00 /* R0 Chip Version */ +#define PB_RSTART 0x01 /* R1 Row Window Start */ +#define PB_CSTART 0x02 /* R2 Column Window Start */ +#define PB_RWSIZE 0x03 /* R3 Row Window Size */ +#define PB_CWSIZE 0x04 /* R4 Column Window Size */ +#define PB_CFILLIN 0x05 /* R5 Column Fill-In */ +#define PB_VBL 0x06 /* R6 Vertical Blank Count */ +#define PB_CONTROL 0x07 /* R7 Control Mode */ +#define PB_FINTTIME 0x08 /* R8 Integration Time/Frame Unit Count */ +#define PB_RINTTIME 0x09 /* R9 Integration Time/Row Unit Count */ +#define PB_ROWSPEED 0x0A /* R10 Row Speed Control */ +#define PB_ABORTFRAME 0x0B /* R11 Abort Frame */ +/* #define PB_R12 0x0C R12 Reserved */ +#define PB_RESET 0x0D /* R13 Reset */ +#define PB_EXPGAIN 0x0E /* R14 Exposure Gain Command */ +#define PB_R15 0x0F /* R15 Expose0 */ +#define PB_R16 0x10 /* R16 Expose1 */ +#define PB_R17 0x11 /* R17 Expose2 */ +#define PB_R18 0x12 /* R18 Low0_DAC */ +#define PB_R19 0x13 /* R19 Low1_DAC */ +#define PB_R20 0x14 /* R20 Low2_DAC */ +#define PB_R21 0x15 /* R21 Threshold11 */ +#define PB_R22 0x16 /* R22 Threshold0x */ +#define PB_UPDATEINT 0x17 /* R23 Update Interval */ +#define PB_R24 0x18 /* R24 High_DAC */ +#define PB_R25 0x19 /* R25 Trans0H */ +#define PB_R26 0x1A /* R26 Trans1L */ +#define PB_R27 0x1B /* R27 Trans1H */ +#define PB_R28 0x1C /* R28 Trans2L */ +/* #define PB_R29 0x1D R29 Reserved */ +/* #define PB_R30 0x1E R30 Reserved */ +#define PB_R31 0x1F /* R31 Wait to Read */ +#define PB_PREADCTRL 0x20 /* R32 Pixel Read Control Mode */ +#define PB_R33 0x21 /* R33 IREF_VLN */ +#define PB_R34 0x22 /* R34 IREF_VLP */ +#define PB_R35 0x23 /* R35 IREF_VLN_INTEG */ +#define PB_R36 0x24 /* R36 IREF_MASTER */ +#define PB_R37 0x25 /* R37 IDACP */ +#define PB_R38 0x26 /* R38 IDACN */ +#define PB_R39 0x27 /* R39 DAC_Control_Reg */ +#define PB_R40 0x28 /* R40 VCL */ +#define PB_R41 0x29 /* R41 IREF_VLN_ADCIN */ +/* #define PB_R42 0x2A R42 Reserved */ +#define PB_G1GAIN 0x2B /* R43 Green 1 Gain */ +#define PB_BGAIN 0x2C /* R44 Blue Gain */ +#define PB_RGAIN 0x2D /* R45 Red Gain */ +#define PB_G2GAIN 0x2E /* R46 Green 2 Gain */ +#define PB_R47 0x2F /* R47 Dark Row Address */ +#define PB_R48 0x30 /* R48 Dark Row Options */ +/* #define PB_R49 0x31 R49 Reserved */ +#define PB_R50 0x32 /* R50 Image Test Data */ +#define PB_ADCMAXGAIN 0x33 /* R51 Maximum Gain */ +#define PB_ADCMINGAIN 0x34 /* R52 Minimum Gain */ +#define PB_ADCGLOBALGAIN 0x35 /* R53 Global Gain */ +#define PB_R54 0x36 /* R54 Maximum Frame */ +#define PB_R55 0x37 /* R55 Minimum Frame */ +/* #define PB_R56 0x38 R56 Reserved */ +#define PB_VOFFSET 0x39 /* R57 VOFFSET */ +#define PB_R58 0x3A /* R58 Snap-Shot Sequence Trigger */ +#define PB_ADCGAINH 0x3B /* R59 VREF_HI */ +#define PB_ADCGAINL 0x3C /* R60 VREF_LO */ +/* #define PB_R61 0x3D R61 Reserved */ +/* #define PB_R62 0x3E R62 Reserved */ +/* #define PB_R63 0x3F R63 Reserved */ +#define PB_R64 0x40 /* R64 Red/Blue Gain */ +#define PB_R65 0x41 /* R65 Green 2/Green 1 Gain */ +#define PB_R66 0x42 /* R66 VREF_HI/LO */ +#define PB_R67 0x43 /* R67 Integration Time/Row Unit Count */ +#define PB_R240 0xF0 /* R240 ADC Test */ +#define PB_R241 0xF1 /* R241 Chip Enable */ +/* #define PB_R242 0xF2 R242 Reserved */ +/* }}} */ + +#define I2C_SETW_CHECK(reg,val) if ((r = qc_i2c_setw(qc,(reg),(val)))<0) goto fail +#define STV_SET_CHECK(reg,val) if ((r = qc_stv_set(qc,(reg),(val)))<0) goto fail +#define STV_SETW_CHECK(reg,val) if ((r = qc_stv_setw(qc,(reg),(val)))<0) goto fail + +/* + * The spec file for the PB-0100 suggests the following for best quality + * images after the sensor has been reset : + * + * PB_ADCGAINL = R60 = 0x03 (3 dec) : sets low reference of ADC to produce good black level + * PB_PREADCTRL = R32 = 0x1400 (5120 dec) : Enables global gain changes through R53 + * PB_ADCMINGAIN = R52 = 0x10 (16 dec) : Sets the minimum gain for auto-exposure + * PB_ADCGLOBALGAIN = R53 = 0x10 (16 dec) : Sets the global gain + * PB_EXPGAIN = R14 = 0x11 (17 dec) : Sets the auto-exposure value + * PB_UPDATEINT = R23 = 0x02 (2 dec) : Sets the speed on auto-exposure routine + * PB_CFILLIN = R5 = 0x0E (14 dec) : Sets the frame rate + */ + +/* {{{ [fold] pb0100_init: Initialise parameters of PB100 sensor */ +static int pb0100_init(struct quickcam *qc) +{ + static const Bool natural = TRUE; /* Disable flicker control for natural lighting? */ + struct qc_sensor_data *sd = &qc->sensor_data; + int r; + + if (sd->compress) return -EINVAL; + sd->maxwidth = 360; + sd->maxheight = 288; /* Sensor has 296 rows but top 8 are opaque */ + if (sd->subsample) { + sd->maxwidth /= 2; + sd->maxheight /= 2; + } + sd->exposure = 0; + + STV_SET_CHECK(STV_REG00, 1); + STV_SET_CHECK(STV_SCAN_RATE, 0); + + /* Reset sensor */ + I2C_SETW_CHECK(PB_RESET, 1); + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SETW_CHECK(PB_RESET, 0); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Disable chip */ + I2C_SETW_CHECK(PB_CONTROL, BIT(5)|BIT(3)); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Gain stuff...*/ + I2C_SETW_CHECK(PB_PREADCTRL, BIT(12)|BIT(10)|BIT(6)); + I2C_SETW_CHECK(PB_ADCGLOBALGAIN, 12); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Set up auto-exposure */ + I2C_SETW_CHECK(PB_R28, 12); /* ADC VREF_HI new setting for a transition from the Expose1 to the Expose2 setting */ + I2C_SETW_CHECK(PB_ADCMAXGAIN, 180); /* gain max for autoexposure */ + I2C_SETW_CHECK(PB_ADCMINGAIN, 12); /* gain min for autoexposure */ + I2C_SETW_CHECK(PB_R54, 3); /* Maximum frame integration time (programmed into R8) allowed for auto-exposure routine */ + I2C_SETW_CHECK(PB_R55, 0); /* Minimum frame integration time (programmed into R8) allowed for auto-exposure routine */ + I2C_SETW_CHECK(PB_UPDATEINT, 1); + I2C_SETW_CHECK(PB_R15, 800); /* R15 Expose0 (maximum that auto-exposure may use) */ + I2C_SETW_CHECK(PB_R17, 10); /* R17 Expose2 (minimum that auto-exposure may use) */ + + if (qc->settings.adaptive) { + I2C_SETW_CHECK(PB_EXPGAIN, (natural?BIT(6):0)|BIT(4)|BIT(0)); + } else { + I2C_SETW_CHECK(PB_EXPGAIN, 0); + } + if ((r = qc_i2c_wait(qc))<0) goto fail; + + I2C_SETW_CHECK(PB_VOFFSET, 0); /* 0x14 */ + I2C_SETW_CHECK(PB_ADCGAINH, 11); /* 0x0D */ + I2C_SETW_CHECK(PB_ADCGAINL, 0); /* Set black level (important!) */ + + /* ??? */ + STV_SET_CHECK(STV_REG04, 0x07); + STV_SET_CHECK(STV_REG03, 0x45); + STV_SET_CHECK(STV_REG00, 0x11); + + /* Set mode */ + STV_SET_CHECK(STV_Y_CTRL, sd->subsample ? 2 : 1); /* 0x02: half, 0x01: full FIXME: this doesn't work! */ + STV_SET_CHECK(STV_X_CTRL, sd->subsample ? 6 : 0x0A); /* 0x06: Half, 0x0A: Full */ + + /* ISO-Size (0x27b: 635... why? - HDCS uses 847) */ + STV_SETW_CHECK(STV_ISO_SIZE, 847); + + /* Setup sensor window */ + I2C_SETW_CHECK(PB_RSTART, 0); + I2C_SETW_CHECK(PB_CSTART, 0); + I2C_SETW_CHECK(PB_RWSIZE, 240-1); /* 0xF7: 240 */ + I2C_SETW_CHECK(PB_CWSIZE, 320-1); /* 0x13F: 320 */ + if ((r = qc_i2c_wait(qc))<0) goto fail; + + /* Scan rate? */ + STV_SET_CHECK(STV_SCAN_RATE, sd->subsample ? 0x10 : 0x20); /* larger -> slower */ + + /* Scan/timing for the sensor */ + I2C_SETW_CHECK(PB_ROWSPEED, BIT(4)|BIT(3)|BIT(1)); + I2C_SETW_CHECK(PB_CFILLIN, 14); + I2C_SETW_CHECK(PB_VBL, 0); + I2C_SETW_CHECK(PB_FINTTIME, 0); + I2C_SETW_CHECK(PB_RINTTIME, 123); + if ((r = qc_i2c_wait(qc))<0) goto fail; + + STV_SET_CHECK(STV_REG01, 0xC2); + STV_SET_CHECK(STV_REG02, 0xB0); + +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_exposure() */ +static int pb0100_set_exposure(struct quickcam *qc, unsigned int val) +{ + int r; + struct qc_sensor_data *sd = &qc->sensor_data; + val >>= 7; + if (val==sd->exposure) return 0; + sd->exposure = val; + I2C_SETW_CHECK(PB_RINTTIME, val); /* R9 */ +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_gains() */ +static int pb0100_set_gains(struct quickcam *qc, u16 hue, u16 sat, u16 val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int rgain, bgain, ggain; + int r; + qc_hsv2rgb(hue, sat, val, &rgain, &bgain, &ggain); + rgain >>= 8; /* After this the values are 0..255 */ + ggain >>= 8; + bgain >>= 8; + if (rgain==sd->rgain && ggain==sd->ggain && bgain==sd->bgain) return 0; + sd->rgain = rgain; + sd->ggain = ggain; + sd->bgain = bgain; + I2C_SETW_CHECK(PB_RGAIN, rgain); /* R43 */ + I2C_SETW_CHECK(PB_G1GAIN, ggain); /* R44 */ + I2C_SETW_CHECK(PB_G2GAIN, ggain); /* R45 */ + I2C_SETW_CHECK(PB_BGAIN, bgain); /* R46 */ +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_levels() */ +static int pb0100_set_levels(struct quickcam *qc, unsigned int exp, unsigned int gain, unsigned int hue, unsigned int sat) +{ + int r; + /* When automatic exposure control in Photobit is used, the exposure/gain + * registers shouldn't be touched. The sensor may update them only rarely + * and if they're changed they may be incorrect until the sensor updates + * the registers next time. + * FIXME: shouldn't qc-driver.c ensure this function isnt called when adaptive is used? + */ + if (qc->settings.adaptive) return 0; + if ((r = pb0100_set_exposure(qc, exp))<0) goto fail; + pb0100_set_gains(qc, hue, sat, gain); +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_target: Set target brightness for sensor autoexposure, val=0..65535 */ +static int pb0100_set_target(struct quickcam *qc, unsigned int val) +{ + struct qc_sensor_data *sd = &qc->sensor_data; + unsigned int totalpixels, brightpixels, darkpixels; + int r; + + val >>= 8; /* val = 0..255 (0-50% of bright pixels) */ + if (val==sd->exposure) return 0; + sd->exposure = val; + + /* Number of pixels counted by the sensor when subsampling the pixels. + * Slightly larger than the real value to avoid oscillation */ + totalpixels = sd->width * sd->height; + totalpixels = totalpixels/(8*8) + totalpixels/(64*64); + + brightpixels = (totalpixels * val) >> 8; + darkpixels = totalpixels - brightpixels; + I2C_SETW_CHECK(PB_R21, brightpixels); /* R21 */ + I2C_SETW_CHECK(PB_R22, darkpixels); /* R22 */ +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_set_size: Set window size */ +/* Window location and size are controlled by R1, R2, R3 and R4. + * The default size is CIF (352x288) with to right at (4,12) + * and bottom left at (355, 299) + * + * We try to ensure that the captured area is in the center of + * the camera purely because that's nicer. It would be better + * if the PB0100 sensor supported capture scaling! + * + * We do it in on step otherwise size change may take more + * than one frame (like xawtv who tests 64x48 and uses 352x288) + * 3072 = 64x48, 16896 = 352x48, 101376 = 352x288. + */ +static int pb0100_set_size(struct quickcam *qc, unsigned int w, unsigned int h) +{ + static const unsigned int originx = 0; /* First visible pixel */ + static const unsigned int originy = 8; + static const unsigned int maxwidth = 360; /* Visible sensor size */ + static const unsigned int maxheight = 288; + struct qc_sensor_data *sd = &qc->sensor_data; + int x, y; + int r; + + sd->width = w; + sd->height = h; + if (sd->subsample) { + w *= 2; + h *= 2; + } + x = (maxwidth - w)/2; /* Center image by computing upper-left corner */ + y = (maxheight - h)/2; + x = (x + originx) & ~1; /* Must be even to align to the Bayer pattern */ + y = (y + originy) & ~1; + I2C_SETW_CHECK(PB_RSTART, y); /* PB_RSTART = 12 + y */ + I2C_SETW_CHECK(PB_CSTART, x); /* PB_CSTART = 4 + x */ + I2C_SETW_CHECK(PB_RWSIZE, h - 1); /* PB_RWSIZE = h - 1 */ + I2C_SETW_CHECK(PB_CWSIZE, w - 1); /* PB_CWSIZE = w - 1 */ + + if (qc->settings.adaptive) { + /* The automatic exposure counts need to be recomputed when size is changed */ + x = sd->exposure << 8; + sd->exposure = -1; + if ((r = pb0100_set_target(qc, x))<0) goto fail; + } + + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_start: Start grabbing */ +static int pb0100_start(struct quickcam *qc) +{ + int r; + I2C_SETW_CHECK(PB_CONTROL, BIT(5)|BIT(3)|BIT(1)); + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ +/* {{{ [fold] pb0100_stop: Stop grabbing */ +static int pb0100_stop(struct quickcam *qc) +{ + int r; + I2C_SETW_CHECK(PB_ABORTFRAME, 1); + if ((r = qc_i2c_wait(qc))<0) goto fail; + I2C_SETW_CHECK(PB_CONTROL, BIT(5)|BIT(3)); /* Set bit 1 to zero */ + r = qc_i2c_wait(qc); +fail: return r; +} +/* }}} */ + +/* {{{ [fold] struct qc_sensor qc_sensor_pb0100 */ +const struct qc_sensor qc_sensor_pb0100 = { + name: "PB-0100/0101", + manufacturer: "Photobit", + init: pb0100_init, + start: pb0100_start, + stop: pb0100_stop, + set_size: pb0100_set_size, + set_levels: pb0100_set_levels, + set_target: pb0100_set_target, + /* Exposure and gain control information */ + autoexposure: TRUE, + /* Information needed to access the sensor via I2C */ + reg23: 1, + i2c_addr: PB_ADDR, + /* Identification information used for auto-detection */ + id_reg: PB_IDENT, + id: 0x64, + length_id: 2, +}; +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/Makefile +++ linux-2.6.28/ubuntu/qc-usb/Makefile @@ -0,0 +1,3 @@ +#obj-$(CONFIG_QC_USB) := quickcam.o + +quickcam-objs := qc-driver.o qc-hdcs.o qc-pb0100.o qc-vv6410.o qc-formats.o qc-mjpeg.o qc-memory.o --- linux-2.6.28.orig/ubuntu/qc-usb/videodev2.h +++ linux-2.6.28/ubuntu/qc-usb/videodev2.h @@ -0,0 +1,1156 @@ +/* + * Video for Linux Two + * + * Header file for V4L2 drivers and applications. + * + * Author: Bill Dirks + */ + +#ifndef __LINUX_VIDEODEV_H +#define __LINUX_VIDEODEV_H + +#define V4L2_MAJOR_VERSION 0 +#define V4L2_MINOR_VERSION 20 + +#include "videodevfix.h" + + +/* + * M I S C E L L A N E O U S + */ + +/* Four-character-code (FOURCC) */ +#define fourcc(a,b,c,d)\ + (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24)) + +/* Open flag for non-capturing opens on capture devices */ +#define O_NONCAP O_TRUNC +#define O_NOIO O_TRUNC + +/* Timestamp data type, 64-bit signed integer */ +/* Should be removed from here when UST is added to kernel */ +#ifndef STAMP_T +#define STAMP_T +typedef __s64 stamp_t; +#endif + +/* + * D R I V E R C A P A B I L I T I E S + */ +struct v4l2_capability +{ + char name[32]; /* Descriptive, and unique */ + int type; /* Device type, see below */ + int inputs; /* Num video inputs */ + int outputs; /* Num video outputs */ + int audios; /* Num audio devices */ + int maxwidth; + int maxheight; + int minwidth; + int minheight; + int maxframerate; + __u32 flags; /* Feature flags, see below */ + __u32 reserved[4]; +}; +/* Values for 'type' field */ +#define V4L2_TYPE_CAPTURE 0 /* Is a video capture device */ +#define V4L2_TYPE_CODEC 1 /* Is a CODEC device */ +#define V4L2_TYPE_OUTPUT 2 /* Is a video output device */ +#define V4L2_TYPE_FX 3 /* Is a video effects device */ +#define V4L2_TYPE_VBI 4 /* Is a VBI capture device */ +#define V4L2_TYPE_VTR 5 /* Is a tape recorder controller */ +#define V4L2_TYPE_VTX 6 /* Is a teletext device */ +#define V4L2_TYPE_RADIO 7 /* Is a radio device */ +#define V4L2_TYPE_PRIVATE 1000 /* Start of driver private types */ +/* Flags for 'flags' field */ +#define V4L2_FLAG_READ 0x00001 /* Can capture via read() call */ +#define V4L2_FLAG_WRITE 0x00002 /* Can accept data via write() */ +#define V4L2_FLAG_STREAMING 0x00004 /* Can capture streaming video */ +#define V4L2_FLAG_PREVIEW 0x00008 /* Can do automatic preview */ +#define V4L2_FLAG_SELECT 0x00010 /* Supports the select() call */ +#define V4L2_FLAG_TUNER 0x00020 /* Can tune */ +#define V4L2_FLAG_MONOCHROME 0x00040 /* Monochrome only */ +#define V4L2_FLAG_DATA_SERVICE 0x00080 /* Has a related data service dev. */ + + +/* + * V I D E O I M A G E F O R M A T + */ +struct v4l2_pix_format +{ + __u32 width; + __u32 height; + __u32 depth; + __u32 pixelformat; + __u32 flags; + __u32 bytesperline; /* only used when there are pad bytes */ + __u32 sizeimage; + __u32 priv; /* private data, depends on pixelformat */ +}; +/* Pixel format FOURCC depth Description */ +#define V4L2_PIX_FMT_RGB332 fourcc('R','G','B','1') /* 8 RGB-3-3-2 */ +#define V4L2_PIX_FMT_RGB555 fourcc('R','G','B','O') /* 16 RGB-5-5-5 */ +#define V4L2_PIX_FMT_RGB565 fourcc('R','G','B','P') /* 16 RGB-5-6-5 */ +#define V4L2_PIX_FMT_BGR24 fourcc('B','G','R','3') /* 24 BGR-8-8-8 */ +#define V4L2_PIX_FMT_RGB24 fourcc('R','G','B','3') /* 24 RGB-8-8-8 */ +#define V4L2_PIX_FMT_BGR32 fourcc('B','G','R','4') /* 32 BGR-8-8-8-8 */ +#define V4L2_PIX_FMT_RGB32 fourcc('R','G','B','4') /* 32 RGB-8-8-8-8 */ +#define V4L2_PIX_FMT_GREY fourcc('G','R','E','Y') /* 8 Greyscale */ +#define V4L2_PIX_FMT_YVU410 fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ +#define V4L2_PIX_FMT_YVU420 fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ +#define V4L2_PIX_FMT_YUYV fourcc('Y','U','Y','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_UYVY fourcc('U','Y','V','Y') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_YVU422P fourcc('4','2','2','P') /* 16 YVU422 planar */ +#define V4L2_PIX_FMT_YVU411P fourcc('4','1','1','P') /* 16 YVU411 planar */ + +/* The following formats are not defined in the V4L2 specification */ +#define V4L2_PIX_FMT_YUV410 fourcc('Y','U','V','9') /* 9 YUV 4:1:0 */ +#define V4L2_PIX_FMT_YUV420 fourcc('Y','U','1','2') /* 12 YUV 4:2:0 */ +#define V4L2_PIX_FMT_YYUV fourcc('Y','Y','U','V') /* 16 YUV 4:2:2 */ +#define V4L2_PIX_FMT_HI240 fourcc('H','I','2','4') /* 8 8-bit color */ + + +/* Flags */ +#define V4L2_FMT_FLAG_COMPRESSED 0x0001 /* Compressed format */ +#define V4L2_FMT_FLAG_BYTESPERLINE 0x0002 /* bytesperline field valid */ +#define V4L2_FMT_FLAG_INTERLACED 0x0004 /* Image is interlaced */ +#define V4L2_FMT_FLAG_TOPFIELD 0x0008 /* is a top field only */ +#define V4L2_FMT_FLAG_BOTFIELD 0x0010 /* is a bottom field only */ +#define V4L2_FMT_FLAG_ODDFIELD V4L2_FMT_FLAG_TOPFIELD +#define V4L2_FMT_FLAG_EVENFIELD V4L2_FMT_FLAG_BOTFIELD +#define V4L2_FMT_FLAG_COMBINED V4L2_FMT_FLAG_INTERLACED +#define V4L2_FMT_CS_field 0xF000 /* Color space field mask */ +#define V4L2_FMT_CS_601YUV 0x1000 /* ITU YCrCb color space */ +#define V4L2_FMT_FLAG_SWCONVERSION 0x0800 /* used only in format enum. */ +/* SWCONVERSION indicates the format is not natively supported by the */ +/* driver and the driver uses software conversion to support it */ + + +/* + * F O R M A T E N U M E R A T I O N + */ +struct v4l2_fmtdesc +{ + int index; /* Format number */ + char description[32]; /* Description string */ + __u32 pixelformat; /* Format fourcc */ + __u32 flags; /* Format flags */ + __u32 depth; /* Bits per pixel */ + __u32 reserved[2]; +}; + +struct v4l2_cvtdesc +{ + int index; + struct + { + __u32 pixelformat; + __u32 flags; + __u32 depth; + __u32 reserved[2]; + } in, out; +}; + +struct v4l2_fxdesc +{ + int index; + char name[32]; + __u32 flags; + __u32 inputs; + __u32 controls; + __u32 reserved[2]; +}; + + +/* + * T I M E C O D E + */ +struct v4l2_timecode +{ + __u8 frames; + __u8 seconds; + __u8 minutes; + __u8 hours; + __u8 userbits[4]; + __u32 flags; + __u32 type; +}; +/* Type */ +#define V4L2_TC_TYPE_24FPS 1 +#define V4L2_TC_TYPE_25FPS 2 +#define V4L2_TC_TYPE_30FPS 3 +#define V4L2_TC_TYPE_50FPS 4 +#define V4L2_TC_TYPE_60FPS 5 + + +/* Flags */ +#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */ +#define V4L2_TC_FLAG_COLORFRAME 0x0002 +#define V4L2_TC_USERBITS_field 0x000C +#define V4L2_TC_USERBITS_USERDEFINED 0x0000 +#define V4L2_TC_USERBITS_8BITCHARS 0x0008 +/* The above is based on SMPTE timecodes */ + + +/* + * C O M P R E S S I O N P A R A M E T E R S + */ +struct v4l2_compression +{ + int quality; + int keyframerate; + int pframerate; + __u32 reserved[5]; +}; + + +/* + * M E M O R Y - M A P P I N G B U F F E R S + */ +struct v4l2_requestbuffers +{ + int count; + __u32 type; + __u32 reserved[2]; +}; +struct v4l2_buffer +{ + int index; + __u32 type; + __u32 offset; + __u32 length; + __u32 bytesused; + __u32 flags; + stamp_t timestamp; + struct v4l2_timecode timecode; + __u32 sequence; + __u32 reserved[3]; +}; +/* Buffer type codes and flags for 'type' field */ +#define V4L2_BUF_TYPE_field 0x00001FFF /* Type field mask */ +#define V4L2_BUF_TYPE_CAPTURE 0x00000001 +#define V4L2_BUF_TYPE_CODECIN 0x00000002 +#define V4L2_BUF_TYPE_CODECOUT 0x00000003 +#define V4L2_BUF_TYPE_EFFECTSIN 0x00000004 +#define V4L2_BUF_TYPE_EFFECTSIN2 0x00000005 +#define V4L2_BUF_TYPE_EFFECTSOUT 0x00000006 +#define V4L2_BUF_TYPE_VIDEOOUT 0x00000007 +#define V4L2_BUF_TYPE_FXCONTROL 0x00000008 + +/* Starting value of driver private buffer types */ +#define V4L2_BUF_TYPE_PRIVATE 0x00001000 + +#define V4L2_BUF_ATTR_DEVICEMEM 0x00010000 /* Buffer is on device (flag) */ + +/* Flags used only in VIDIOC_REQBUFS */ +#define V4L2_BUF_REQ_field 0xF0000000 +#define V4L2_BUF_REQ_CONTIG 0x10000000 /* Map all buffers in one + contiguous mmap(). This flag + only used in VIDIOC_REQBUFS */ + +/* Flags for 'flags' field */ +#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */ +#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */ +#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */ +#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */ +#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */ +#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */ +#define V4L2_BUF_FLAG_TOPFIELD 0x0040 /* Image is a top field only */ +#define V4L2_BUF_FLAG_BOTFIELD 0x0080 /* Image is a bottom field only */ +#define V4L2_BUF_FLAG_ODDFIELD V4L2_BUF_FLAG_TOPFIELD +#define V4L2_BUF_FLAG_EVENFIELD V4L2_BUF_FLAG_BOTFIELD +#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */ + +/* + * O V E R L A Y P R E V I E W + */ +struct v4l2_framebuffer +{ + __u32 capability; + __u32 flags; + void *base[3]; + struct v4l2_pix_format fmt; +}; +/* Flags for the 'capability' field. Read only */ +#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001 +#define V4L2_FBUF_CAP_CHROMAKEY 0x0002 +#define V4L2_FBUF_CAP_CLIPPING 0x0004 +#define V4L2_FBUF_CAP_SCALEUP 0x0008 +#define V4L2_FBUF_CAP_SCALEDOWN 0x0010 +#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0020 +/* Flags for the 'flags' field. */ +#define V4L2_FBUF_FLAG_PRIMARY 0x0001 +#define V4L2_FBUF_FLAG_OVERLAY 0x0002 +#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004 + +struct v4l2_clip +{ + int x; + int y; + int width; + int height; + struct v4l2_clip *next; +}; +struct v4l2_window +{ + int x; + int y; + int width; + int height; + __u32 chromakey; + struct v4l2_clip *clips; + int clipcount; + void *bitmap; +}; + + +/* + * D E V I C E P E R F O R M A N C E + */ +struct v4l2_performance +{ + int frames; + int framesdropped; + __u64 bytesin; + __u64 bytesout; + __u32 reserved[4]; +}; + +/* + * C A P T U R E P A R A M E T E R S + */ +struct v4l2_captureparm +{ + __u32 capability; /* Supported modes */ + __u32 capturemode; /* Current mode */ + unsigned long timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 reserved[4]; +}; +/* Flags for 'capability' and 'capturemode' fields */ +#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */ +//#define V4L2_MODE_VFLIP 0x0002 /* Flip image vertically */ +//#define V4L2_MODE_HFLIP 0x0004 /* Flip image horizontally */ +#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */ + +struct v4l2_outputparm +{ + __u32 capability; /* Supported modes */ + __u32 outputmode; /* Current mode */ + unsigned long timeperframe; /* Time per frame in .1us units */ + __u32 extendedmode; /* Driver-specific extensions */ + __u32 reserved[4]; +}; + +/* + * I N P U T I M A G E C R O P P I N G + */ +struct v4l2_cropcap +{ + __u32 capability; + int min_x; + int min_y; + int max_x; + int max_y; + int default_left; + int default_top; + int default_right; + int default_bottom; + __u32 reserved[2]; +}; +struct v4l2_crop +{ + int left; + int top; + int right; + int bottom; + __u32 reserved; +}; + +/* + * D I G I T A L Z O O M + */ +struct v4l2_zoomcap +{ + __u32 capability; + __u32 maxwidth; + __u32 maxheight; + __u32 minwidth; + __u32 minheight; + __u32 reserved[2]; +}; +/* Flags for the capability field */ +#define V4L2_ZOOM_NONCAP 0x0001 +#define V4L2_ZOOM_WHILESTREAMING 0x0002 + +struct v4l2_zoom +{ + __u32 x; + __u32 y; + __u32 width; + __u32 height; + __u32 reserved; +}; + + +/* + * A N A L O G V I D E O S T A N D A R D + */ +struct v4l2_standard +{ + __u8 name[24]; + struct { + __u32 numerator; + __u32 denominator; /* >= 1 */ + } framerate; /* Frames, not fields */ + __u32 framelines; + __u32 reserved1; + __u32 colorstandard; + union { + struct { + __u32 colorsubcarrier; /* Hz */ + } pal; + struct { + __u32 colorsubcarrier; /* Hz */ + } ntsc; + struct { + __u32 f0b; /* Hz (blue) */ + __u32 f0r; /* Hz (red) */ + } secam; + __u8 reserved[12]; + } colorstandard_data; + __u32 transmission; /* Bit field. Must be zero for + non-modulators/demodulators. */ + __u32 reserved2; /* Must be set to zero */ +}; + +/* Values for the 'colorstandard' field */ +#define V4L2_COLOR_STD_PAL 1 +#define V4L2_COLOR_STD_NTSC 2 +#define V4L2_COLOR_STD_SECAM 3 + +/* Values for the color subcarrier fields */ +#define V4L2_COLOR_SUBC_PAL 4433619 /* PAL BGHI, NTSC-44 */ +#define V4L2_COLOR_SUBC_PAL_M 3575611 /* PAL M (Brazil) */ +#define V4L2_COLOR_SUBC_PAL_N 3582056 /* PAL N */ +#define V4L2_COLOR_SUBC_NTSC 3579545 /* NTSC M, NTSC-Japan */ +#define V4L2_COLOR_SUBC_SECAMB 4250000 /* SECAM B - Y carrier */ +#define V4L2_COLOR_SUBC_SECAMR 4406250 /* SECAM R - Y carrier */ + +/* Flags for the 'transmission' field */ +#define V4L2_TRANSM_STD_B (1<<1) +#define V4L2_TRANSM_STD_D (1<<3) +#define V4L2_TRANSM_STD_G (1<<6) +#define V4L2_TRANSM_STD_H (1<<7) +#define V4L2_TRANSM_STD_I (1<<8) +#define V4L2_TRANSM_STD_K (1<<10) +#define V4L2_TRANSM_STD_K1 (1<<11) +#define V4L2_TRANSM_STD_L (1<<12) +#define V4L2_TRANSM_STD_M (1<<13) +#define V4L2_TRANSM_STD_N (1<<14) + + +/* Used in the VIDIOC_ENUMSTD ioctl for querying supported standards */ +struct v4l2_enumstd +{ + int index; + struct v4l2_standard std; + __u32 inputs; /* set of inputs that */ + /* support this standard */ + __u32 outputs; /* set of outputs that */ + /* support this standard */ + __u32 reserved[2]; +}; + + +/* + * V I D E O I N P U T S + */ +struct v4l2_input +{ + int index; /* Which input */ + char name[32]; /* Label */ + int type; /* Type of input */ + __u32 capability; /* Capability flags */ + int assoc_audio; /* Associated audio input */ + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_INPUT_TYPE_TUNER 1 +#define V4L2_INPUT_TYPE_CAMERA 2 + +/* Flags for the 'capability' field */ +#define V4L2_INPUT_CAP_AUDIO 0x0001 /* assoc_audio */ + + +/* + * V I D E O O U T P U T S + */ +struct v4l2_output +{ + int index; /* Which output */ + char name[32]; /* Label */ + int type; /* Type of output */ + __u32 capability; /* Capability flags */ + int assoc_audio; /* Associated audio */ + __u32 reserved[4]; +}; +/* Values for the 'type' field */ +#define V4L2_OUTPUT_TYPE_MODULATOR 1 +#define V4L2_OUTPUT_TYPE_ANALOG 2 +#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3 + +/* Flags for the 'capability' field */ +#define V4L2_OUTPUT_CAP_AUDIO 0x0001 /* assoc_audio */ + + +/* + * C O N T R O L S + */ +struct v4l2_control +{ + __u32 id; + int value; +}; + +/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */ +struct v4l2_queryctrl +{ + __u32 id; + __u8 name[32]; /* Whatever */ + int minimum; /* Note signedness */ + int maximum; + unsigned int step; + int default_value; + __u32 type; + __u32 flags; + __u32 category; /* Automatically filled in by V4L2 */ + __u8 group[32]; /* for pre-defined controls */ + __u32 reserved[2]; +}; + +/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */ +struct v4l2_querymenu +{ + __u32 id; + int index; + __u8 name[32]; /* Whatever */ + int reserved; +}; + +/* Used in V4L2_BUF_TYPE_FXCONTROL buffers */ +struct v4l2_fxcontrol +{ + __u32 id; + __u32 value; +}; + +/* Control types */ +#define V4L2_CTRL_TYPE_INTEGER 0 +#define V4L2_CTRL_TYPE_BOOLEAN 1 +#define V4L2_CTRL_TYPE_MENU 2 +#define V4L2_CTRL_TYPE_BUTTON 3 + +/* Control flags */ +#define V4L2_CTRL_FLAG_DISABLED 0x0001 +#define V4L2_CTRL_FLAG_GRABBED 0x0002 + +/* Control categories */ +#define V4L2_CTRL_CAT_VIDEO 1 /* "Video" */ +#define V4L2_CTRL_CAT_AUDIO 2 /* "Audio" */ +#define V4L2_CTRL_CAT_EFFECT 3 /* "Effect" */ + +/* Control IDs defined by V4L2 */ +#define V4L2_CID_BASE 0x00980900 +/* IDs reserved for driver specific controls */ +#define V4L2_CID_PRIVATE_BASE 0x08000000 +/* IDs reserved for effect-specific controls on effects devices */ +#define V4L2_CID_EFFECT_BASE 0x0A00B000 + +#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0) +#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1) +#define V4L2_CID_SATURATION (V4L2_CID_BASE+2) +#define V4L2_CID_HUE (V4L2_CID_BASE+3) +#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5) +#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6) +#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7) +#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8) +#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9) +#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10) +#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) +#define V4l2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12) +#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13) +#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14) +#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15) +#define V4L2_CID_GAMMA (V4L2_CID_BASE+16) +#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* ? Not sure */ +#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17) +#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18) +#define V4L2_CID_GAIN (V4L2_CID_BASE+19) +#define V4L2_CID_HFLIP (V4L2_CID_BASE+20) +#define V4L2_CID_VFLIP (V4L2_CID_BASE+21) +#define V4L2_CID_HCENTER (V4L2_CID_BASE+22) +#define V4L2_CID_VCENTER (V4l2_CID_BASE+23) +#define V4L2_CID_LASTP1 (V4L2_CID_BASE+24) /* last CID + 1 */ +/* Remember to change fill_ctrl_category() in videodev.c */ + +/* + * T U N I N G + */ +struct v4l2_tuner +{ + int input; + char name[32]; + struct v4l2_standard std; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 rxsubchans; + __u32 audmode; + int signal; + int afc; + __u32 reserved[4]; +}; +struct v4l2_modulator +{ + int output; + char name[32]; + struct v4l2_standard std; + __u32 capability; + __u32 rangelow; + __u32 rangehigh; + __u32 txsubchans; + __u32 reserved[4]; +}; +/* Flags for the 'capability' field */ +#define V4L2_TUNER_CAP_LOW 0x0001 +#define V4L2_TUNER_CAP_NORM 0x0002 +#define V4L2_TUNER_CAP_STEREO 0x0010 +#define V4L2_TUNER_CAP_LANG2 0x0020 +#define V4L2_TUNER_CAP_SAP 0x0020 +#define V4L2_TUNER_CAP_LANG1 0x0040 + +/* Flags for the 'rxsubchans' field */ +#define V4L2_TUNER_SUB_MONO 0x0001 +#define V4L2_TUNER_SUB_STEREO 0x0002 +#define V4L2_TUNER_SUB_LANG2 0x0004 +#define V4L2_TUNER_SUB_SAP 0x0004 +#define V4L2_TUNER_SUB_LANG1 0x0008 + +/* Values for the 'audmode' field */ +#define V4L2_TUNER_MODE_MONO 0x0000 +#define V4L2_TUNER_MODE_STEREO 0x0001 +#define V4L2_TUNER_MODE_LANG2 0x0002 +#define V4L2_TUNER_MODE_SAP 0x0002 +#define V4L2_TUNER_MODE_LANG1 0x0003 + +struct v4l2_frequency +{ + int port; + __u32 frequency; + __u32 reserved[2]; +}; + +/* + * A U D I O + */ +struct v4l2_audio +{ + int audio; + char name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; +/* Flags for the 'capability' field */ +#define V4L2_AUDCAP_EFFECTS 0x0020 +#define V4L2_AUDCAP_LOUDNESS 0x0040 +#define V4L2_AUDCAP_AVL 0x0080 + +/* Flags for the 'mode' field */ +#define V4L2_AUDMODE_LOUDNESS 0x00002 +#define V4L2_AUDMODE_AVL 0x00004 +#define V4L2_AUDMODE_STEREO_field 0x0FF00 +#define V4L2_AUDMODE_STEREO_LINEAR 0x00100 +#define V4L2_AUDMODE_STEREO_PSEUDO 0x00200 +#define V4L2_AUDMODE_STEREO_SPATIAL30 0x00300 +#define V4L2_AUDMODE_STEREO_SPATIAL50 0x00400 + +struct v4l2_audioout +{ + int audio; + char name[32]; + __u32 capability; + __u32 mode; + __u32 reserved[2]; +}; + +/* + * D A T A S E R V I C E S ( V B I ) + */ + +struct v4l2_vbi_format +{ + __u32 sampling_rate; /* in 1 Hz */ + __u32 reserved1; /* must be zero */ + __u32 samples_per_line; + __u32 sample_format; /* V4L2_VBI_SF_* */ + __s32 start[2]; + __u32 count[2]; + __u32 flags; /* V4L2_VBI_* */ + __u32 reserved2; /* must be zero */ +}; + +/* VBI sampling formats */ +#define V4L2_VBI_SF_UBYTE 1 + +/* VBI flags */ +#define V4L2_VBI_UNSYNC (1<< 0) +#define V4L2_VBI_INTERLACED (1<< 1) + + +/* + * A G G R E G A T E S T R U C T U R E S + */ + +/* Stream data format + */ +struct v4l2_format +{ + __u32 type; + union + { + struct v4l2_pix_format pix; /* image format */ + struct v4l2_vbi_format vbi; /* VBI data */ + /* add more */ + __u8 raw_data[200]; /* user-defined */ + } fmt; +}; + + +/* Stream type-dependent parameters + */ +struct v4l2_streamparm +{ + __u32 type; + union + { + struct v4l2_captureparm capture; + struct v4l2_outputparm output; + /* add more */ + __u8 raw_data[200]; /* user-defined */ + } parm; +}; + + + +/* + * I O C T L C O D E S F O R V I D E O D E V I C E S + * + */ +#define VIDIOC_QUERYCAP _IOR ('V', 0, struct v4l2_capability) +#define VIDIOC_RESERVED _IO ('V', 1) +#define VIDIOC_ENUM_PIXFMT _IOWR ('V', 2, struct v4l2_fmtdesc) +#define VIDIOC_ENUM_FBUFFMT _IOWR ('V', 3, struct v4l2_fmtdesc) +#define VIDIOC_G_FMT _IOWR ('V', 4, struct v4l2_format) +#define VIDIOC_S_FMT _IOWR ('V', 5, struct v4l2_format) +#define VIDIOC_G_COMP _IOR ('V', 6, struct v4l2_compression) +#define VIDIOC_S_COMP _IOW ('V', 7, struct v4l2_compression) +#define VIDIOC_REQBUFS _IOWR ('V', 8, struct v4l2_requestbuffers) +#define VIDIOC_QUERYBUF _IOWR ('V', 9, struct v4l2_buffer) +#define VIDIOC_G_FBUF _IOR ('V', 10, struct v4l2_framebuffer) +#define VIDIOC_S_FBUF _IOW ('V', 11, struct v4l2_framebuffer) +#define VIDIOC_G_WIN _IOR ('V', 12, struct v4l2_window) +#define VIDIOC_S_WIN _IOW ('V', 13, struct v4l2_window) +#define VIDIOC_PREVIEW _IOWR ('V', 14, int) +#define VIDIOC_QBUF _IOWR ('V', 15, struct v4l2_buffer) +#define VIDIOC_DQBUF _IOWR ('V', 17, struct v4l2_buffer) +#define VIDIOC_STREAMON _IOW ('V', 18, int) +#define VIDIOC_STREAMOFF _IOW ('V', 19, int) +#define VIDIOC_G_PERF _IOR ('V', 20, struct v4l2_performance) +#define VIDIOC_G_PARM _IOWR ('V', 21, struct v4l2_streamparm) +#define VIDIOC_S_PARM _IOW ('V', 22, struct v4l2_streamparm) +#define VIDIOC_G_STD _IOR ('V', 23, struct v4l2_standard) +#define VIDIOC_S_STD _IOW ('V', 24, struct v4l2_standard) +#define VIDIOC_ENUMSTD _IOWR ('V', 25, struct v4l2_enumstd) +#define VIDIOC_ENUMINPUT _IOWR ('V', 26, struct v4l2_input) +#define VIDIOC_G_CTRL _IOWR ('V', 27, struct v4l2_control) +#define VIDIOC_S_CTRL _IOW ('V', 28, struct v4l2_control) +#define VIDIOC_G_TUNER _IOWR ('V', 29, struct v4l2_tuner) +#define VIDIOC_S_TUNER _IOW ('V', 30, struct v4l2_tuner) +#define VIDIOC_G_FREQ _IOR ('V', 31, int) +#define VIDIOC_S_FREQ _IOWR ('V', 32, int) +#define VIDIOC_G_AUDIO _IOWR ('V', 33, struct v4l2_audio) +#define VIDIOC_S_AUDIO _IOW ('V', 34, struct v4l2_audio) +#define VIDIOC_QUERYCTRL _IOWR ('V', 36, struct v4l2_queryctrl) +#define VIDIOC_QUERYMENU _IOWR ('V', 37, struct v4l2_querymenu) +#define VIDIOC_G_INPUT _IOR ('V', 38, int) +#define VIDIOC_S_INPUT _IOWR ('V', 39, int) +#define VIDIOC_ENUMCVT _IOWR ('V', 40, struct v4l2_cvtdesc) +#define VIDIOC_G_OUTPUT _IOR ('V', 46, int) +#define VIDIOC_S_OUTPUT _IOWR ('V', 47, int) +#define VIDIOC_ENUMOUTPUT _IOWR ('V', 48, struct v4l2_output) +#define VIDIOC_G_AUDOUT _IOWR ('V', 49, struct v4l2_audioout) +#define VIDIOC_S_AUDOUT _IOW ('V', 50, struct v4l2_audioout) +#define VIDIOC_ENUMFX _IOWR ('V', 51, struct v4l2_fxdesc) +#define VIDIOC_G_EFFECT _IOR ('V', 52, int) +#define VIDIOC_S_EFFECT _IOWR ('V', 53, int) +#define VIDIOC_G_MODULATOR _IOWR ('V', 54, struct v4l2_modulator) +#define VIDIOC_S_MODULATOR _IOW ('V', 55, struct v4l2_modulator) + +#define VIDIOC_ENUM_CAPFMT VIDIOC_ENUM_PIXFMT +#define VIDIOC_ENUM_OUTFMT VIDIOC_ENUM_PIXFMT +#define VIDIOC_ENUM_SRCFMT VIDIOC_ENUM_PIXFMT +#define VIDIOC_ENUMFMT VIDIOC_ENUM_PIXFMT + +#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ + + +#ifdef __KERNEL__ +/* + * These things are used only by drivers. + */ + +extern int videodev_init(void); + +/* + * + * V 4 L 2 D R I V E R H E L P E R A P I + * + * Some commonly needed functions for drivers. + */ + +extern void v4l2_version(int *major, int *minor); +extern int v4l2_major_number(void); + +/* Memory management */ +extern unsigned long v4l2_vmalloc_to_bus(void *virt); +extern unsigned long v4l2_vmalloc_to_page(void *virt); + +/* Simple queue management */ +struct v4l2_q_node +{ + struct v4l2_q_node *forw, *back; +}; +struct v4l2_queue +{ + struct v4l2_q_node *forw, *back; + rwlock_t qlock; +}; +extern void v4l2_q_init(struct v4l2_queue *q); +extern void v4l2_q_add_head(struct v4l2_queue *q, struct v4l2_q_node *node); +extern void v4l2_q_add_tail(struct v4l2_queue *q, struct v4l2_q_node *node); +extern void *v4l2_q_del_head(struct v4l2_queue *q); +extern void *v4l2_q_del_tail(struct v4l2_queue *q); +extern void *v4l2_q_peek_head(struct v4l2_queue *q); +extern void *v4l2_q_peek_tail(struct v4l2_queue *q); +extern void *v4l2_q_yank_node(struct v4l2_queue *q, struct v4l2_q_node *node); + +/* Math functions */ +extern u32 v4l2_math_div6432(u64 a, u32 d, u32 *r); + +/* Time functions */ +extern unsigned long v4l2_timestamp_divide(stamp_t t, + unsigned long p_100ns); +extern unsigned long v4l2_timestamp_correct(stamp_t *t, + unsigned long p_100ns); + +/* Master Clock functions */ +struct v4l2_clock +{ + void (*gettime)(stamp_t *); +}; +extern int v4l2_masterclock_register(struct v4l2_clock *clock); +extern void v4l2_masterclock_unregister(struct v4l2_clock *clock); +extern void v4l2_masterclock_gettime(stamp_t *curr); + +/* Video standard functions */ +extern unsigned int v4l2_video_std_fps(struct v4l2_standard *vs); +extern unsigned long v4l2_video_std_tpf(struct v4l2_standard *vs); +extern int v4l2_video_std_confirm(struct v4l2_standard *vs); +extern int v4l2_video_std_construct(struct v4l2_standard *vs, + int id, __u32 transmission); + +#define V4L2_STD_PAL 1 /* PAL B, G, H, I (...) */ +#define V4L2_STD_PAL_M 5 /* (Brazil) */ +#define V4L2_STD_PAL_N 6 /* (Argentina, Paraguay, Uruguay) */ +#define V4L2_STD_PAL_60 10 /* PAL/NTSC hybrid */ +#define V4L2_STD_NTSC 11 /* NTSC M (USA, ...) */ +#define V4L2_STD_NTSC_N 12 /* (Barbados, Bolivia, Colombia, + S. Korea) */ +#define V4L2_STD_NTSC_44 15 /* PAL/NTSC hybrid */ +#define V4L2_STD_SECAM 21 /* SECAM B, D, G, K, K1 (...) */ +//#define V4L2_STD_SECAM_H 27 /* (Greece, Iran, Morocco) */ +//#define V4L2_STD_SECAM_L 28 /* (France, Luxembourg, Monaco) */ +//#define V4L2_STD_SECAM_M 29 /* (Jamaica) */ + +/* + * D E V I C E D R I V E R R E G I S T R A T I O N + * + */ +struct v4l2_device +{ + char name[32]; + int type; + int minor; + + int (*open)(struct v4l2_device *v, + int flags, void **idptr); + void (*close)(void *id); + long (*read)(void *id, + char *buf, unsigned long count, int noblock); + long (*write)(void *id, + const char *buf, unsigned long count, int noblock); + int (*ioctl)(void *id, + unsigned int cmd, void *arg); + int (*mmap)(void *id, + struct vm_area_struct *vma); + int (*poll)(void *id, + struct file *file, poll_table *table); + + int (*initialize)(struct v4l2_device *v); + void *priv; /* may be used by the driver */ + + int busy; /* open count maintained by videodev.c */ + void *v4l2_priv; /* for V4L2 use */ + int v4l2_reserved[4]; /* for V4L2 use */ +}; + +/* Size of kernel ioctl arg buffer used in ioctl handler */ +#define V4L2_MAX_IOCTL_SIZE 256 + +extern int v4l2_register_device(struct v4l2_device *); +extern void v4l2_unregister_device(struct v4l2_device *); + +/* V4L2 structures */ +extern struct v4l2_device *v4l2_device_from_file(struct file *file); +extern void *v4l2_openid_from_file(struct file *file); + +#endif/*ifdef __KERNEL__ */ + + +/*---------------------------------------------------------------------- + Old Video for Linux backward compatibility below this line. + ---------------------------------------------------------------------- + + All new applications should use the new API calls. + + (These definitions taken from 2.2.1.) + + */ + + +#define VID_TYPE_CAPTURE 1 /* Can capture */ +#define VID_TYPE_TUNER 2 /* Can tune */ +#define VID_TYPE_TELETEXT 4 /* Does teletext */ +#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */ +#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */ +#define VID_TYPE_CLIPPING 32 /* Can clip */ +#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */ +#define VID_TYPE_SCALES 128 /* Scalable */ +#define VID_TYPE_MONOCHROME 256 /* Monochrome only */ +#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */ + +struct video_capability +{ + char name[32]; + int type; + int channels; /* Num channels */ + int audios; /* Num audio devices */ + int maxwidth; /* Supported width */ + int maxheight; /* And height */ + int minwidth; /* Supported width */ + int minheight; /* And height */ +}; + + +struct video_channel +{ + int channel; + char name[32]; + int tuners; + __u32 flags; +#define VIDEO_VC_TUNER 1 /* Channel has a tuner */ +#define VIDEO_VC_AUDIO 2 /* Channel has audio */ + __u16 type; +#define VIDEO_TYPE_TV 1 +#define VIDEO_TYPE_CAMERA 2 + __u16 norm; /* Norm set by channel */ +}; + +struct video_tuner +{ + int tuner; + char name[32]; + ulong rangelow, rangehigh; /* Tuner range */ + __u32 flags; +#define VIDEO_TUNER_PAL 1 +#define VIDEO_TUNER_NTSC 2 +#define VIDEO_TUNER_SECAM 4 +#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */ +#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */ +#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */ +#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */ +#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */ + __u16 mode; /* PAL/NTSC/SECAM/OTHER */ +#define VIDEO_MODE_PAL 0 +#define VIDEO_MODE_NTSC 1 +#define VIDEO_MODE_SECAM 2 +#define VIDEO_MODE_AUTO 3 + __u16 signal; /* Signal strength 16bit scale */ +}; + +struct video_picture +{ + __u16 brightness; + __u16 hue; + __u16 colour; + __u16 contrast; + __u16 whiteness; /* Black and white only */ + __u16 depth; /* Capture depth */ + __u16 palette; /* Palette in use */ +#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */ +#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */ +#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */ +#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */ +#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */ +#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */ +#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */ +#define VIDEO_PALETTE_YUYV 8 +#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */ +#define VIDEO_PALETTE_YUV420 10 +#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */ +#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */ +#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */ +#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */ +#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */ +#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */ +#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */ +#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */ +}; + +struct video_audio +{ + int audio; /* Audio channel */ + __u16 volume; /* If settable */ + __u16 bass, treble; + __u32 flags; +#define VIDEO_AUDIO_MUTE 1 +#define VIDEO_AUDIO_MUTABLE 2 +#define VIDEO_AUDIO_VOLUME 4 +#define VIDEO_AUDIO_BASS 8 +#define VIDEO_AUDIO_TREBLE 16 +#define VIDEO_AUDIO_BALANCE 32 + char name[16]; +#define VIDEO_SOUND_MONO 1 +#define VIDEO_SOUND_STEREO 2 +#define VIDEO_SOUND_LANG1 4 +#define VIDEO_SOUND_LANG2 8 + __u16 mode; + __u16 balance; /* Stereo balance */ + __u16 step; /* Step actual volume uses */ +}; + +struct video_clip +{ + __s32 x,y; + __s32 width, height; + struct video_clip *next; /* For user use/driver use only */ +}; + +struct video_window +{ + __u32 x,y; /* Position of window */ + __u32 width,height; /* Its size */ + __u32 chromakey; + __u32 flags; + struct video_clip *clips; /* Set only */ + int clipcount; +#define VIDEO_WINDOW_INTERLACE 1 +#define VIDEO_CLIP_BITMAP -1 +/* bitmap is 1024x625, a '1' bit represents a clipped pixel */ +#define VIDEO_CLIPMAP_SIZE (128 * 625) +}; + +struct video_capture +{ + __u32 x,y; /* Offsets into image */ + __u32 width, height; /* Area to capture */ + __u16 decimation; /* Decimation divder */ + __u16 flags; /* Flags for capture */ +#define VIDEO_CAPTURE_ODD 0 /* Temporal */ +#define VIDEO_CAPTURE_EVEN 1 +}; + +struct video_buffer +{ + void *base; + int height,width; + int depth; + int bytesperline; +}; + +struct video_mmap +{ + unsigned int frame; /* Frame (0 - n) for double buffer */ + int height,width; + unsigned int format; /* should be VIDEO_PALETTE_* */ +}; + +struct video_key +{ + __u8 key[8]; + __u32 flags; +}; + + +#define VIDEO_MAX_FRAME 32 + +struct video_mbuf +{ + int size; /* Total memory to map */ + int frames; /* Frames */ + int offsets[VIDEO_MAX_FRAME]; +}; + + +#define VIDEO_NO_UNIT (-1) + + +struct video_unit +{ + int video; /* Video minor */ + int vbi; /* VBI minor */ + int radio; /* Radio minor */ + int audio; /* Audio minor */ + int teletext; /* Teletext minor */ +}; + +#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */ +#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */ +#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */ +#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */ +#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */ +#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */ +#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */ +#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */ +#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Set the video overlay window */ +#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */ +#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */ +#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */ +#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */ +#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */ +#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */ +#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */ +#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */ +#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */ +#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */ +#define VIDIOCGMBUF _IOR('v', 20, struct video_mbuf) /* Memory map buffer info */ +#define VIDIOCGUNIT _IOR('v', 21, struct video_unit) /* Get attached units */ +#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get frame buffer */ +#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set frame buffer - root only */ +#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */ + + + +#endif/*ifndef __LINUX_VIDEODEV_H*/ --- linux-2.6.28.orig/ubuntu/qc-usb/qc-driver.c +++ linux-2.6.28/ubuntu/qc-usb/qc-driver.c @@ -0,0 +1,3410 @@ +/* Start of file */ + +/* {{{ [fold] Comments */ + +/* + * qc-usb, Logitech QuickCam video driver with V4L support + * Derived from qce-ga, linux V4L driver for the QuickCam Express and Dexxa QuickCam + * + * qc-driver.c - main driver part + * + * Copyright (C) 2001 Jean-Fredric Clere, Nikolas Zimmermann, Georg Acher + * Mark Cave-Ayland, Carlo E Prelz, Dick Streefland + * Copyright (C) 2002,2003 Tuukka Toivonen + * + * 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 + * + */ + +/* Cam variations of Logitech QuickCam: + P/N 861037: Sensor HDCS1000 ASIC STV0600 + P/N 861050-0010: Sensor HDCS1000 ASIC STV0600 + P/N 861050-0020: Sensor Photobit PB100 ASIC STV0600-1 ("QuickCam Express") + P/N 861055: Sensor ST VV6410 ASIC STV0610 ("LEGO cam") + P/N 861075-0040: Sensor HDCS1000 ASIC + P/N 961179-0700: Sensor ST VV6410 ASIC STV0602 (Dexxa WebCam USB) + P/N 861040-0000: Sensor ST VV6410 ASIC STV0610 ("QuickCam Web") + + For any questions ask + qce-ga-devel@lists.sourceforge.net - about code + qce-ga-discussion@lists.sourceforge.net - about usage +*/ +/* }}} */ +/* {{{ [fold] Includes */ +#include "quickcam.h" + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +#include +#endif +#include + +#include "qc-memory.h" + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#include +#endif +/* }}} */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +/* Make this a bit backwards compatible... hack hack... */ +#ifndef module_param +#define module_param(a, b, c) MODULE_PARM(a, "i") +#endif +#endif + +/* {{{ [fold] Module parameters */ +MODULE_PARM_DESC(qcdebug, "Sets the debug output (bitfield)"); +int qcdebug = DEBUGLEVEL; +module_param(qcdebug, int, 0444); + +MODULE_PARM_DESC(keepsettings, "Keep picture settings across one open to another (0-1)"); +static int keepsettings = 0; +module_param(keepsettings, int, 0444); + +MODULE_PARM_DESC(settle, "Maximum number of frames to wait picture brightness to settle (0-255)"); +static int settle = 0; +module_param(settle, int, 0444); + +/* Subsampling is used to allow higher scan rate with smaller images. */ +MODULE_PARM_DESC(subsample, "Sets subsampling (0-1)"); +static int subsample = 0; /* normal or sub-sample (sub-sample to increase the speed) */ +module_param(subsample, int, 0444); + +MODULE_PARM_DESC(compress, "Enable compressed mode (0-1)"); +static int compress = 0; /* Enable compressed mode if available (higher framerate) */ +module_param(compress, int, 0444); + +MODULE_PARM_DESC(frameskip, "How frequently capture frames (0-10)"); +static int frameskip = 0; +module_param(frameskip, int, 0444); + +MODULE_PARM_DESC(quality, "Sets the picture quality (0-5)"); +static int quality = 5; /* 5 = generalized adjustable Pei-Tam method */ +module_param(quality, int, 0444); + +MODULE_PARM_DESC(adaptive, "Automatic adaptive brightness control (0-1)"); +static int adaptive = 1; +module_param(adaptive, int, 0444); + +MODULE_PARM_DESC(equalize, "Equalize image (0-1)"); +static int equalize = 0; /* Disabled by default */ +module_param(equalize, int, 0444); + +MODULE_PARM_DESC(userlut, "Apply user-specified lookup-table (0-1)"); +static int userlut = 0; /* Disabled by default */ +module_param(userlut, int, 0444); + +MODULE_PARM_DESC(retryerrors, "Retry if image capture fails, otherwise return error code (0-1)"); +static int retryerrors = 1; /* Enabled by default */ +module_param(retryerrors, int, 0444); + +/* Bug in Xvideo(?): if the width is not divisible by 8 and Xvideo is used, the frame is shown wrongly */ +MODULE_PARM_DESC(compatible, "Enable workaround for bugs in application programs (bitfield)"); +static int compatible = 0; /* Disabled by default */ +module_param(compatible, int, 0444); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5) +MODULE_PARM_DESC(video_nr, "Set videodevice number (/dev/videoX)"); +static int video_nr = -1; +module_param(video_nr, int, 0444); +/* video_nr option allows to specify a certain /dev/videoX device */ +/* (like /dev/video0 or /dev/video1 ...) */ +/* for autodetect first available use video_nr=-1 (defaultvalue) */ +#endif +/* }}} */ +/* {{{ [fold] Miscellaneous data */ +#ifndef MODULE_LICENSE /* Appeared in 2.4.10 */ +#ifdef MODULE +#define MODULE_LICENSE(license) \ +static const char __module_license[] __attribute__((section(".modinfo"))) = \ + "license=" license +#else +#define MODULE_LICENSE(license) +#endif +#endif + +MODULE_SUPPORTED_DEVICE("video"); +MODULE_DESCRIPTION("Logitech QuickCam USB driver"); +MODULE_AUTHOR("See README"); +MODULE_LICENSE("GPL"); +EXPORT_NO_SYMBOLS; + +static const int min_framewidth = 32; /* Minimum image size we allow delivering to user application */ +static const int min_frameheight = 32; + +static const char qc_proc_name[] = "video/quickcam"; +#define qc_name (&qc_proc_name[6]) + +static struct usb_device_id qc_device_table[] = { + { USB_DEVICE(0x046D, 0x0840) }, /* QuickCam Express */ + { USB_DEVICE(0x046D, 0x0850) }, /* LEGO cam / QuickCam Web */ + { USB_DEVICE(0x046D, 0x0870) }, /* Dexxa WebCam USB */ + { USB_DEVICE(0x046D, 0x08F6) }, /* Logitech QuickCam Messenger */ + { } +}; +MODULE_DEVICE_TABLE(usb, qc_device_table); + +extern const struct qc_sensor qc_sensor_pb0100; +extern const struct qc_sensor qc_sensor_hdcs1000; +extern const struct qc_sensor qc_sensor_hdcs1020; +extern const struct qc_sensor qc_sensor_vv6410; + +static const struct qc_sensor *sensors[] = { + &qc_sensor_hdcs1000, + &qc_sensor_hdcs1020, + &qc_sensor_pb0100, + &qc_sensor_vv6410, +}; + +static LIST_HEAD(quickcam_list); /* Linked list containing all QuickCams */ +static DECLARE_MUTEX(quickcam_list_lock); /* Always lock first quickcam_list_lock, then qc->lock */ + +/* Default values for user-specified lookup-table; may be overwritten by user */ +static unsigned char userlut_contents[QC_LUT_SIZE] = { + /* Red */ + 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 25, 30, 35, 38, 42, + 44, 47, 50, 53, 54, 57, 59, 61, 63, 65, 67, 69, + 71, 71, 73, 75, 77, 78, 80, 81, 82, 84, 85, 87, + 88, 89, 90, 91, 93, 94, 95, 97, 98, 98, 99, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 125, 126, 127, 128, 129, 129, 130, 131, 132, 133, 134, + 134, 135, 135, 136, 137, 138, 139, 140, 140, 141, 142, 143, + 143, 143, 144, 145, 146, 147, 147, 148, 149, 150, 150, 151, + 152, 152, 152, 153, 154, 154, 155, 156, 157, 157, 158, 159, + 159, 160, 161, 161, 161, 162, 163, 163, 164, 165, 165, 166, + 167, 167, 168, 168, 169, 170, 170, 170, 171, 171, 172, 173, + 173, 174, 174, 175, 176, 176, 177, 178, 178, 179, 179, 179, + 180, 180, 181, 181, 182, 183, 183, 184, 184, 185, 185, 186, + 187, 187, 188, 188, 188, 188, 189, 190, 190, 191, 191, 192, + 192, 193, 193, 194, 195, 195, 196, 196, 197, 197, 197, 197, + 198, 198, 199, 199, 200, 201, 201, 202, 202, 203, 203, 204, + 204, 205, 205, 206, 206, 206, 206, 207, 207, 208, 208, 209, + 209, 210, 210, 211, 211, 212, 212, 213, 213, 214, 214, 215, + 215, 215, 215, 216, 216, 217, 217, 218, 218, 218, 219, 219, + 220, 220, 221, 221, + + /* Green */ + 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 28, 34, 39, 43, 47, + 50, 53, 56, 59, 61, 64, 66, 68, 71, 73, 75, 77, + 79, 80, 82, 84, 86, 87, 89, 91, 92, 94, 95, 97, + 98, 100, 101, 102, 104, 105, 106, 108, 109, 110, 111, 113, + 114, 115, 116, 117, 118, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 144, 145, 146, 147, 148, 149, + 150, 151, 151, 152, 153, 154, 155, 156, 156, 157, 158, 159, + 160, 160, 161, 162, 163, 164, 164, 165, 166, 167, 167, 168, + 169, 170, 170, 171, 172, 172, 173, 174, 175, 175, 176, 177, + 177, 178, 179, 179, 180, 181, 182, 182, 183, 184, 184, 185, + 186, 186, 187, 187, 188, 189, 189, 190, 191, 191, 192, 193, + 193, 194, 194, 195, 196, 196, 197, 198, 198, 199, 199, 200, + 201, 201, 202, 202, 203, 204, 204, 205, 205, 206, 206, 207, + 208, 208, 209, 209, 210, 210, 211, 212, 212, 213, 213, 214, + 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 220, + 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, + 227, 228, 228, 229, 229, 230, 230, 231, 231, 232, 232, 233, + 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, 239, + 239, 240, 240, 241, 241, 242, 242, 243, 243, 243, 244, 244, + 245, 245, 246, 246, + + /* Blue */ + 0, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 30, 37, 42, 47, 51, + 55, 58, 61, 64, 67, 70, 72, 74, 78, 80, 82, 84, + 86, 88, 90, 92, 94, 95, 97, 100, 101, 103, 104, 106, + 107, 110, 111, 112, 114, 115, 116, 118, 119, 121, 122, 124, + 125, 126, 127, 128, 129, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 143, 144, 145, 146, 147, 148, 149, 150, 151, + 152, 154, 155, 156, 157, 158, 158, 159, 160, 161, 162, 163, + 165, 166, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, + 176, 176, 177, 178, 179, 180, 180, 181, 182, 183, 183, 184, + 185, 187, 187, 188, 189, 189, 190, 191, 192, 192, 193, 194, + 194, 195, 196, 196, 198, 199, 200, 200, 201, 202, 202, 203, + 204, 204, 205, 205, 206, 207, 207, 209, 210, 210, 211, 212, + 212, 213, 213, 214, 215, 215, 216, 217, 217, 218, 218, 220, + 221, 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, + 228, 228, 229, 229, 231, 231, 232, 233, 233, 234, 234, 235, + 235, 236, 236, 237, 238, 238, 239, 239, 240, 240, 242, 242, + 243, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, + 249, 250, 250, 251, 251, 253, 253, 254, 254, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255 +}; + +static void qc_usb_exit(struct quickcam *qc); +static int qc_capt_init(struct quickcam *qc); +static void qc_capt_exit(struct quickcam *qc); +static int qc_capt_get(struct quickcam *qc, unsigned char **frame); +static int qc_isoc_init(struct quickcam *qc); +static void qc_isoc_exit(struct quickcam *qc); +/* }}} */ + +/* {{{ [fold] **** Miscellaneous functions ************************************** */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) +/* {{{ [fold] usb_kill_urb(struct urb *urb) */ +/* Unlink URB synchronously (usb_unlink_urb may not be synchronous). + * Note: at this moment the URB completion handler must not resubmit the same URB. + */ +static void qc_usb_kill_urb(struct urb *urb) { + int r; + while ((r=usb_unlink_urb(urb)) == -EBUSY) { + /* The URB is not anymore linked (status!=-EINPROGRESS) but + * usb_unlink_urb() was asynchronous and URB's completion handler still will run */ + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout( (HZ/100)==0 ? 1 : HZ/100); + } + /* if (r!=-EBUSY), + * usb_unlink_urb() called synchronously the completion handler and + * there's no need to wait or anything else */ + if (r) PDEBUG("qc_usb_kill_urb(%p): r=%i", urb, r); +} +#undef usb_kill_urb +#define usb_kill_urb(urb) qc_usb_kill_urb(urb) +/* }}} */ +#endif +/* {{{ [fold] qc_usleep(long usec) */ +void qc_usleep(unsigned long usec) +{ + wait_queue_head_t wq; + init_waitqueue_head(&wq); + interruptible_sleep_on_timeout(&wq, usec*HZ/1000000); +} +/* }}} */ +/* {{{ [fold] int qc_get_i2c(struct quickcam *qc, const struct qc_sensor *sensor, int reg) */ +/* Read a sensor byte or word wide register value via STV0600 I2C bus + * qc_i2c_init() must be called first! + */ +int qc_get_i2c(struct quickcam *qc, const struct qc_sensor *sensor, int reg) +{ + struct usb_device *dev = qc->dev; + int ret; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_get_i2c(qc=%p,sensor=%p,reg=0x%04X)",qc,sensor,reg); + TEST_BUGR(dev==NULL); + if (sizeof(qc->dmabuf)<35) BUG(); + + /* We need here extra write to the STV register before reading the I2C register */ + /* Also wait until there are no pending control URB requests */ + if ((ret = qc_stv_set(qc, STV_REG23, sensor->reg23))<0) goto fail; + + memset(qc->dmabuf, 0, 35); + qc->dmabuf[0] = reg; + qc->dmabuf[0x20] = sensor->i2c_addr; + qc->dmabuf[0x21] = 0; /* 0+1 = 1 value, one byte or word wide register */ + qc->dmabuf[0x22] = 3; /* Read I2C register */ + ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), + 0x04, + 0x40, + 0x1400, 0, /* Write I2C register address, 35 bytes */ + qc->dmabuf, 0x23, 3*HZ); + if (ret < 0) goto fail; + ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), + 0x04, + 0xC0, + 0x1410, 0, /* Read register contents from I2C, 1 or 2 bytes */ + qc->dmabuf, sensor->length_id, 3*HZ); + if (ret < 0) goto fail; + ret = qc->dmabuf[0]; + if (sensor->length_id>1) ret |= qc->dmabuf[1]<<8; /* Assume LSB is always first from data received via USB */ + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_get_i2c(reg=0x%04X) = %04X", reg, ret); + return ret; + +fail: PDEBUG("qc_get_i2c failed, code=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] int qc_stv_set(struct quickcam *qc, unsigned short reg, unsigned char val) */ +/* + * Set one byte register in the STV-chip. qc_i2c_init() must be called first! + */ +int qc_stv_set(struct quickcam *qc, unsigned short reg, unsigned char val) +{ + int ret; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_set(qc=%p,reg=0x%04X,val=%u)",qc,(int)reg,(int)val); + TEST_BUGR(qc==NULL); + if (sizeof(qc->dmabuf)<1) BUG(); + qc_i2c_wait(qc); /* Wait until no pending commands from qc_i2c_* */ + qc->dmabuf[0] = val; + ret = usb_control_msg(qc->dev, usb_sndctrlpipe(qc->dev, 0), + 0x04, /* Request */ + 0x40, /* RequestType */ + reg, 0, /* Value, Index */ + qc->dmabuf, 1, 3*HZ); + if ((qcdebug&QC_DEBUGERRORS || qcdebug&QC_DEBUGLOGIC) && ret<0) PDEBUG("Failed qc_stv_set()=%i", ret); + if (ret<0) return ret; + return 0; +} +/* }}} */ +/* {{{ [fold] int qc_stv_get(struct quickcam *qc, unsigned short reg) */ +/* + * Read one byte register in the STV-chip. qc_i2c_init() must be called first! + * Return the unsigned register value or negative error code on error. + */ +int qc_stv_get(struct quickcam *qc, unsigned short reg) +{ + int ret; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_get(qc=%p,reg=0x%04X)",qc,(int)reg); + TEST_BUGR(qc==NULL); + if (sizeof(qc->dmabuf)<1) BUG(); + qc_i2c_wait(qc); /* Wait until no pending commands from qc_i2c_* */ + ret = usb_control_msg(qc->dev, usb_rcvctrlpipe(qc->dev, 0), + 0x04, /* Request */ + 0xC0, /* RequestType */ + reg, 0, /* Value, Index */ + qc->dmabuf, 1, 3*HZ); + if ((qcdebug&QC_DEBUGERRORS || qcdebug&QC_DEBUGLOGIC) && ret<0) PDEBUG("Failed qc_stv_get()=%i", ret); + if (ret<0) return ret; + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_get(reg=0x%04X)=%02X", reg, qc->dmabuf[0]); + return qc->dmabuf[0]; +} +/* }}} */ +/* {{{ [fold] int qc_stv_setw(struct quickcam *qc, unsigned short reg, unsigned short val) */ +/* + * Set two byte register in the STV-chip. qc_i2c_init() must be called first! + * "w" means either "word" or "wide", depending on your religion ;) + */ +int qc_stv_setw(struct quickcam *qc, unsigned short reg, unsigned short val) +{ + int ret; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_stv_setw(qc=%p,reg=0x%04X,val=%i)",qc,(int)reg,(int)val); + TEST_BUGR(qc==NULL); + if (sizeof(qc->dmabuf)<2) BUG(); + qc_i2c_wait(qc); + qc->dmabuf[0] = val & 0xFF; + qc->dmabuf[1] = (val >> 8) & 0xFF; + ret = usb_control_msg(qc->dev, usb_sndctrlpipe(qc->dev, 0), + 0x04, + 0x40, + reg, 0, + qc->dmabuf, 2, 3*HZ); + if ((qcdebug&QC_DEBUGERRORS || qcdebug&QC_DEBUGLOGIC) && ret<0) PDEBUG("Failed qc_stv_setw()=%i", ret); + if (ret<0) return ret; + return 0; +} +/* }}} */ +/* {{{ [fold] void qc_hsv2rgb(s16 hue, u16 sat, u16 val, int *red, int *green, int *blue) */ +/* Convert HSI (hue, saturation, intensity) to RGB (red, green, blue). + * All input and output values are 0..65535. + * Hue is actually signed, so it is -32768..32767, but this is equivalent + * since it is the angle around full circle (0=Red, 21845=Green, 43690=Blue). + * Based on libgimp, converted to 16.16 fixed point by tuukkat. + */ +void qc_hsv2rgb(s16 hue, u16 sat, u16 val, int *red, int *green, int *blue) +{ + unsigned int segment, valsat; + signed int h = (u16)hue; + unsigned int s = (sat<32768) ? 0 : (sat-32768)*2; /* 32768 or less = no saturation */ + unsigned int v = val; /* value = intensity */ + unsigned int p; + +#if 1 /* Make common case more efficient */ + if (s == 0) { + *red = v; + *green = v; + *blue = v; + return; + } +#endif + segment = (h + 10923) & 0xFFFF; + segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */ + hue -= segment * 21845; /* -10923..10923 */ + h = hue; + h *= 3; + valsat = v*s >> 16; /* 0..65534 */ + p = v - valsat; + if (h>=0) { + unsigned int t = v - (valsat * (32769 - h) >> 15); + switch (segment) { + default: + PDEBUG("hsi2rgb: this can never happen!"); + case 0: /* R-> */ + *red = v; + *green = t; + *blue = p; + break; + case 1: /* G-> */ + *red = p; + *green = v; + *blue = t; + break; + case 2: /* B-> */ + *red = t; + *green = p; + *blue = v; + break; + } + } else { + unsigned int q = v - (valsat * (32769 + h) >> 15); + switch (segment) { + default: + PDEBUG("hsi2rgb: this can never happen!"); + case 0: /* ->R */ + *red = v; + *green = p; + *blue = q; + break; + case 1: /* ->G */ + *red = q; + *green = v; + *blue = p; + break; + case 2: /* ->B */ + *red = p; + *green = q; + *blue = v; + break; + } + } + //PDEBUG("hue=%i sat=%i val=%i segment=%i h=%i r=%i g=%i b=%i",hue,sat,val, segment,h, *red,*green,*blue); +} + +/* }}} */ +/* {{{ [fold] int qc_lock(struct quickcam *qc) */ +/* Takes a lock on quickcam_list_lock and verifies that the given qc is available */ +/* Returns 0 on success in which case the lock must be freed later or negative error code */ +static int qc_lock(struct quickcam *qc) +{ + struct quickcam *q; + + if (down_interruptible(&quickcam_list_lock)) return -ERESTARTSYS; + + /* Search for the device in the list of plugged quickcams (this prevents a race condition) */ + list_for_each_entry(q, &quickcam_list, list) { + if (q == qc) break; /* Found it? */ + } + if (q != qc) { + PDEBUG("can not find the device to open"); + up(&quickcam_list_lock); + return -ENODEV; + } + return 0; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_i2c: I2C URB messaging routines (qc_i2c_*) ************* */ + +/* We have here a quite typical producer-consumer scheme: + * URB interrupt handler routine consumes i2c data, while + * kernel mode processes create more of it. + * Ref: Linux Device Drivers, Alessandro Rubini et al, 2nd edition, pg. 279 + * "Using Circular Buffers" + */ + +static const int qc_i2c_maxbufsize = 0x23; + +/* {{{ [fold] (private) qc_i2c_nextpacket(struct quickcam *qc) */ +/* Fill URB and submit it, if there are more data to send + * Consume data from "commands" array. May be called from interrupt context. + * Return standard error code. + */ +static int qc_i2c_nextpacket(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + struct urb *urb = id->urb; + u8 *tb = urb->transfer_buffer, flags; + struct usb_ctrlrequest *cr = (struct usb_ctrlrequest *)urb->setup_packet; + unsigned int newtail, length, regnum, i, j; + signed int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_nextpacket(quickcam=%p), tail=%i, head=%i, interrupt=%i",qc,id->tail,id->head,(int)in_interrupt()); + IDEBUG_TEST(*id); + + if (!qc->connected) { + /* Device was disconnected, cancel all pending packets and return */ + id->tail = id->head = id->newhead = 0; + id->packets = 0; + return -ENODEV; + } + + newtail = id->tail; /* First data to fetch */ + if (id->packets<=1 && newtail==id->head) { /* packets==0 or 1: no extra URB need to be scheduled */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("No more control URBs to send"); + r = 0; + goto nourbs; + } + if (id->packets<=1) { + /* Collect data from circular buffer to URB transfer buffer */ + /* Now id->tail!=id->head: there's at least one packet to send */ + TEST_BUGR(newtail==id->head); + id->packets = 1; + if (GET_PRODUCTID(qc)==0x0850) id->packets = 2; + regnum = 0x0400; + length = qc_i2c_maxbufsize; + + i = 0; /* Transfer buffer position */ + if (!(id->commands[newtail].flags & I2C_FLAG_WORD)) { + /* Normal byte-wide register write */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("Setting byte-wide registers"); + do { + tb[i] = id->commands[newtail].regnum; + tb[i+0x10] = id->commands[newtail].loval; + flags = id->commands[newtail].flags; + i++; + newtail = (newtail + 1) % I2C_MAXCOMMANDS; /* Next data to fetch */ + if (flags & I2C_FLAG_BREAK) break; /* Start new packet */ + if (newtail == id->head) break; /* No more data? */ + if (i > 0x0F) break; /* Transfer buffer full? */ + if (id->commands[newtail].flags & I2C_FLAG_WORD) break; + } while (TRUE); +/*if (flags&I2C_FLAG_BREAK) PDEBUG("breaking!!!!!!!!!!"); +{ +int mm; +for(mm=0;mmcommands[newtail].regnum; + tb[i*2+0x10] = id->commands[newtail].loval; + tb[i*2+0x11] = id->commands[newtail].hival; + flags = id->commands[newtail].flags; + i++; + newtail = (newtail + 1) % I2C_MAXCOMMANDS; /* Next data to fetch */ + if (flags & I2C_FLAG_BREAK) break; /* Start new packet */ + if (newtail == id->head) break; /* No more data? */ + if (i > 0x07) break; /* Transfer buffer full? */ + if (!(id->commands[newtail].flags & I2C_FLAG_WORD)) break; + } while (TRUE); + for (j=i*2; j<0x10; j++) tb[j+0x10] = 0; /* Zero out unused register values just to be sure */ + } + for (j=i; j<0x10; j++) tb[j] = 0; /* Zero out unused register addresses just to be sure */ + tb[0x20] = qc->sensor_data.sensor->i2c_addr; + tb[0x21] = i-1; /* Number of commands to send - 1 */ + tb[0x22] = 1; /* Write cmd, 03 would be read. */ + id->tail = newtail; + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("sending i2c packet, cmds=%i, reg0=%02X, val0=%02X",tb[0x21]+1,tb[0],tb[0x10]); + } else { + /* id->packets==2: send extra packet for QuickCam Web */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("sending finalization packet"); + id->packets = 1; + regnum = 0x1704; + length = 1; + tb[0] = 1; + } + urb->dev = qc->dev; /* 2.4.x zeroes urb->dev after submission */ + urb->pipe = usb_sndctrlpipe(qc->dev, 0); + urb->transfer_buffer_length = length; + cr->wValue = cpu_to_le16(regnum); + cr->wLength = cpu_to_le16(length); + r = usb_submit_urb(urb,GFP_ATOMIC); + CHECK_ERROR(r<0, nourbs, "Failed qc_i2c_nextpacket()=%i", r); + return 0; + +nourbs: id->packets = 0; /* No more URBs are scheduled */ + wake_up(&id->wq); //FIXME: race condition: now packets=0, so id could be freed and wake_up do oops + return r; +} +/* }}} */ +/* {{{ [fold] (private) qc_i2c_handler(struct urb *urb) */ +/* This is URB completion handler and is called in interrupt context. + * For each submitted URB, this function is guaranteed to be called exactly once. + * This function may not be called reentrantly for the same qc (should be ok, IRQs don't nest). + * It will resubmit the same URB, if + * - The previous URB completed without error + * - Camera is still connected (qc->connected == TRUE) + * - There is still commands to be sent in commands buffer or pid=0x850 and finalization packet is not yet sent. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void qc_i2c_handler(struct urb *urb, struct pt_regs *ptregs) +#else +static void qc_i2c_handler(struct urb *urb) +#endif +{ + struct quickcam *qc = urb->context; + + if (qcdebug&QC_DEBUGINTERRUPTS) PDEBUG("[INTR] qc_i2c_handler(urb=%p)",urb); + TEST_BUG(urb==NULL); + TEST_BUG(qc==NULL); + IDEBUG_TEST(qc->i2c_data); + if (urb->status<0) { + switch (urb->status) { + default: + /* Seen here: ECONNABORTED 103 Software caused connection abort */ + PRINTK(KERN_ERR,"Unhandled control URB error %i",urb->status); + case -EPROTO: /* Bitstuff error or unknown USB error */ + case -EILSEQ: /* CRC mismatch */ + case -ETIMEDOUT: /* Transfer timed out */ + case -EREMOTEIO: /* Short packet detected */ + case -EPIPE: /* Babble detect or endpoint stalled */ + /* We could try resubmitting the URB here */ + case -ENOENT: /* URB was unlinked */ + case -ENODEV: /* Device was removed */ + case -ECONNRESET: /* Asynchronous unlink, should not happen */ + PRINTK(KERN_ERR,"Control URB error %i",urb->status); + qc->i2c_data.packets = 0; /* Don't schedule more URBs */ + wake_up(&qc->i2c_data.wq); + return; + } + } + qc_i2c_nextpacket(qc); +} +/* }}} */ +/* {{{ [fold] qc_i2c_flush(struct quickcam *qc) */ +/* Allow all register settings set earlier to be scheduled and sent to camera */ +static int qc_i2c_flush(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + int r = 0; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_flush(quickcam=%p,regs=%i)",qc, + (id->newhead+I2C_MAXCOMMANDS-id->head)%I2C_MAXCOMMANDS); + IDEBUG_TEST(*id); + id->head = id->newhead; + if (id->packets==0) /* Schedule URB if there aren't any in progress */ + r = qc_i2c_nextpacket(qc); + return r; +} +/* }}} */ +/* {{{ [fold] qc_i2c_wait(struct quickcam *qc) */ +/* Wait until all previosly set registers are set or abort all transmissions + * and return error code. + * After this function returns, there will not be uncompleted I2C URBs. + */ +int qc_i2c_wait(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_wait(quickcam=%p)",qc); + TEST_BUGR(in_interrupt()); + TEST_BUGR(qc==NULL); + IDEBUG_TEST(*id); + + if (!qc->connected) goto cancel; + r = qc_i2c_flush(qc); + if (r>=0) r = wait_event_interruptible(id->wq, id->packets==0); + if (r<0) goto cancel; + return 0; + +cancel: if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Canceling pending URB %p, packets=%i", id->urb, id->packets); + PDEBUG("i2c_cancel: qc=%p, id=%p",qc,id); + PDEBUG("i2c_cancel: id->urb=%p", id->urb); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (qc->connected) { + PDEBUG("i2c_cancel: id->urb->dev=%p", id->urb->dev); + if (id->urb->dev!=NULL) { + PDEBUG("i2c_cancel: id->urb->dev->bus=%p", id->urb->dev->bus); + if (id->urb->dev->bus!=NULL) { + PDEBUG("i2c_cancel: id->urb->dev->bus->op=%p", id->urb->dev->bus->op); + //PDEBUG("id->urb->dev->bus->op->unlink=%p", id->urb->dev->bus->op->unlink); + } + } + } +#endif + /* Cancel URB if it is in progress or in completion handler */ + if (id->packets > 0) usb_kill_urb(id->urb); + TEST_BUGR_MSG(id->packets!=0, "i2c_wait: packets=%i", id->packets); + return 0; +} +/* }}} */ +/* {{{ [fold] (private) qc_i2c_set0(struct quickcam *qc, unsigned char regnum, unsigned char loval, unsigned char hival, int flags) */ +/* Called from qc_i2c_set and qc_i2c_setw, should not be called elsewhere */ +static int qc_i2c_set0(struct quickcam *qc, unsigned char regnum, unsigned char loval, unsigned char hival, int flags) +{ + struct qc_i2c_data *id = &qc->i2c_data; + unsigned int newhead; + signed int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_set0(quickcam=%p,reg=%02X,val=%02X%02X)",qc,regnum,hival,loval); + TEST_BUGR(qc==NULL); + IDEBUG_TEST(*id); + newhead = id->newhead; + id->commands[newhead].loval = loval; + id->commands[newhead].hival = hival; + id->commands[newhead].regnum = regnum; + id->commands[newhead].flags = flags; + newhead = (newhead + 1) % I2C_MAXCOMMANDS; + if (newhead == id->tail) { /* If buffer is full, wait until it's empty */ + if (qcdebug&QC_DEBUGCONTROLURBS) PDEBUG("i2c buffer is full, waiting"); + r = qc_i2c_wait(qc); + if (r<0) return r; + } + TEST_BUGR(newhead==id->tail); /* no i2c buffer space but nothing to send!!! */ + id->newhead = newhead; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_i2c_set(struct quickcam *qc, unsigned char reg, unsigned char val) */ +/* Set an I2C register to desired value */ +/* (queue setting to be sent later when qc_i2c_flush() is called) */ +inline int qc_i2c_set(struct quickcam *qc, unsigned char reg, unsigned char val) +{ + return qc_i2c_set0(qc, reg, val, 0, 0); +} +/* }}} */ +/* {{{ [fold] qc_i2c_setw(struct quickcam *qc, unsigned char reg, unsigned short val) */ +/* Set a two-byte (word length) I2C register to desired value (queue setting to be sent later) */ +/* (queue setting to be sent later when qc_i2c_flush() is called) */ +inline int qc_i2c_setw(struct quickcam *qc, unsigned char reg, unsigned short val) +{ + return qc_i2c_set0(qc, reg, val & 0xFF, (val >> 8) & 0xFF, I2C_FLAG_WORD); +} +/* }}} */ +/* {{{ [fold] qc_i2c_break(struct quickcam *qc) */ +/* The next register written will be sent in another packet */ +int qc_i2c_break(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + unsigned int prevhead; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_i2c_break(quickcam=%p)",qc); + TEST_BUGR(qc==NULL); + IDEBUG_TEST(*id); + /* We access an entry that may be already submitted and even finished */ + /* But it should not harm */ + prevhead = (id->newhead + I2C_MAXCOMMANDS - 1) % I2C_MAXCOMMANDS; + id->commands[prevhead].flags |= I2C_FLAG_BREAK; + barrier(); + return qc_i2c_flush(qc); +} +/* }}} */ +/* {{{ [fold] qc_i2c_init(struct quickcam *qc) */ +/* Initialize structures and hardware for I2C communication */ +static int qc_i2c_init(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + struct urb *urb; + struct usb_ctrlrequest *cr; + int r = -ENOMEM; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_i2c_init(quickcam=%p)",qc); + TEST_BUGR(qc==NULL); + + id->tail = id->head = id->newhead = 0; /* Next position to be filled and sent is 0 */ + id->packets = 0; + init_waitqueue_head(&id->wq); + + /* Allocate an URB and associated buffers and fill them */ + urb = id->urb = usb_alloc_urb(0,GFP_KERNEL); + if (!urb) goto fail1; + cr = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + urb->setup_packet = (unsigned char *)cr; + if (!cr) goto fail2; + urb->transfer_buffer = kmalloc(qc_i2c_maxbufsize*sizeof(u8), GFP_KERNEL); /* Allocate maximum ever needed */ + if (!urb->transfer_buffer) goto fail3; + urb->complete = qc_i2c_handler; + urb->context = qc; +#if (LINUX_VERSION_CODEtimeout = 3*HZ; /* 1 s */ +#endif + cr->bRequestType = 0x40; + cr->bRequest = 0x04; + cr->wIndex = 0; + IDEBUG_INIT(*id); + return 0; + +fail3: kfree(cr); +fail2: usb_free_urb(urb); + POISON(id->urb); +fail1: return r; +} +/* }}} */ +/* {{{ [fold] qc_i2c_exit(struct quickcam *qc) */ +/* Close messaging, free up memory, stop messaging */ +static void qc_i2c_exit(struct quickcam *qc) +{ + struct qc_i2c_data *id = &qc->i2c_data; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_i2c_exit(qc=%p)",qc); + TEST_BUG(qc==NULL); + qc_i2c_wait(qc); + kfree(id->urb->setup_packet); + kfree(id->urb->transfer_buffer); + POISON(id->urb->setup_packet); + POISON(id->urb->transfer_buffer); + usb_free_urb(id->urb); + IDEBUG_EXIT(*id); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_proc: /proc interface *********************************** */ +#if HAVE_PROCFS + +static struct proc_dir_entry *qc_proc_entry = NULL; /* Initialization should not be necessary, but just in case... */ + +/* {{{ [fold] qc_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) */ +static inline const char *qc_proc_yesno(Bool b) +{ + return b ? "Yes" : "No"; +} + +static int qc_proc_read(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + struct quickcam *qc = data; + char *out = page; + int len; + + if (qc_lock(qc) < 0) return 0; + + out += sprintf(out, "\tGeneral driver status\n"); + out += sprintf(out, "Driver version : %s\n", VERSION); + out += sprintf(out, "Kernel version : %s\n", UTS_RELEASE); + if (qc->dev!=NULL) { + out += sprintf(out, "Device Id : %04X:%04X\n", (int)GET_VENDORID(qc), (int)GET_PRODUCTID(qc)); + out += sprintf(out, "USB bus number : %i\n", qc->dev->bus->busnum); + } + out += sprintf(out, "Users : %i\n", qc->users); + out += sprintf(out, "Connected : %s\n", qc_proc_yesno(qc->connected)); + + out += sprintf(out, "\n\tPicture settings set by user\n"); + out += sprintf(out, "Brightness : %d\n", (int)qc->vpic.brightness); + out += sprintf(out, "Hue : %d\n", (int)qc->vpic.hue); + out += sprintf(out, "Color : %d\n", (int)qc->vpic.colour); + out += sprintf(out, "Contrast : %d\n", (int)qc->vpic.contrast); + out += sprintf(out, "Whiteness : %d\n", (int)qc->vpic.whiteness); + if (qc->users > 0) { + out += sprintf(out, "Depth : %d\n", (int)qc->vpic.depth); + out += sprintf(out, "Palette : %s\n", qc_fmt_getname(qc->vpic.palette)); + } + + if (qc->users > 0) { + out += sprintf(out, "\n\tOutput window\n"); + out += sprintf(out, "Width : %d\n", (int)qc->vwin.width); + out += sprintf(out, "Height : %d\n", (int)qc->vwin.height); + } + + out += sprintf(out, "\n\tSensor\n"); + out += sprintf(out, "Type : %s\n", qc->sensor_data.sensor->name); + out += sprintf(out, "Manufacturer : %s\n", qc->sensor_data.sensor->manufacturer); + if (qc->users > 0) { + out += sprintf(out, "Maximum width : %d\n", qc->sensor_data.maxwidth); + out += sprintf(out, "Maximum height : %d\n", qc->sensor_data.maxheight); + out += sprintf(out, "Current width : %d\n", qc->sensor_data.width); + out += sprintf(out, "Current height : %d\n", qc->sensor_data.height); + } + + out += sprintf(out, "\n\tI2C command stream\n"); + out += sprintf(out, "Scheduled packets: %d\n", qc->i2c_data.packets); + out += sprintf(out, "Packets on queue : %d\n", (I2C_MAXCOMMANDS + qc->i2c_data.head - qc->i2c_data.tail) % I2C_MAXCOMMANDS); + + if (qc->users > 0) { + out += sprintf(out, "\n\tIsochronous data stream\n"); + out += sprintf(out, "Stream enabled : %s\n", qc_proc_yesno(qc->isoc_data.streaming)); + out += sprintf(out, "Transfer errors : %d\n", qc->isoc_data.errorcount); + + out += sprintf(out, "\n\tFrame buffering\n"); + out += sprintf(out, "Frames on queue : %d\n", (FRAME_BUFFERS + qc->frame_data.head - qc->frame_data.tail) % FRAME_BUFFERS); + out += sprintf(out, "Capturing : %s\n", qc_proc_yesno(qc->stream_data.capturing)); + out += sprintf(out, "Waiting processes: %d\n", qc->frame_data.waiting); + } + + out += sprintf(out, "\n\tAutomatic exposure control\n"); + out += sprintf(out, "Picture intensity: %d\n", qc->adapt_data.oldmidvalue); + out += sprintf(out, "Exposure setting : %d\n", qc->adapt_data.exposure); + out += sprintf(out, "Gain setting : %d\n", qc->adapt_data.gain); + out += sprintf(out, "Delta value : %d\n", qc->adapt_data.olddelta); + out += sprintf(out, "Control algorithm: "); + switch (qc->adapt_data.controlalg) { + case EXPCONTROL_SATURATED: out += sprintf(out, "Saturated\n"); break; + case EXPCONTROL_NEWTON: out += sprintf(out, "Newton\n"); break; + case EXPCONTROL_FLOAT: out += sprintf(out, "Float\n"); break; + default: out += sprintf(out, "?\n"); break; + } + + out += sprintf(out, "\n\tDefault settings\n"); + out += sprintf(out, "Debug : 0x%02X\n", qcdebug); + out += sprintf(out, "Keep settings : %s\n", qc_proc_yesno(qc->settings.keepsettings)); + out += sprintf(out, "Settle max frames: %i\n", qc->settings.settle); + out += sprintf(out, "Subsampling : %s\n", qc_proc_yesno(qc->settings.subsample)); + out += sprintf(out, "Compress : %s\n", qc_proc_yesno(qc->settings.compress)); + out += sprintf(out, "Frame skipping : %i\n", qc->settings.frameskip); + out += sprintf(out, "Image quality : %i\n", qc->settings.quality); + out += sprintf(out, "Adaptive : %s\n", qc_proc_yesno(qc->settings.adaptive)); + out += sprintf(out, "Equalize : %s\n", qc_proc_yesno(qc->settings.equalize)); + out += sprintf(out, "User lookup-table: %s\n", qc_proc_yesno(qc->settings.userlut)); + out += sprintf(out, "Retryerrors : %s\n", qc_proc_yesno(qc->settings.retryerrors)); + out += sprintf(out, "Compatible 16x : %s\n", qc_proc_yesno(qc->settings.compat_16x)); + out += sprintf(out, "Compatible DblBuf: %s\n", qc_proc_yesno(qc->settings.compat_dblbuf)); + out += sprintf(out, "Compatible ToRgb : %s\n", qc_proc_yesno(qc->settings.compat_torgb)); + + up(&quickcam_list_lock); + + len = out - page; + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) return 0; + } else + len = count; + *start = page + off; + return len; +} +/* }}} */ +/* {{{ [fold] qc_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) */ +static int qc_proc_write(struct file *file, const char *buffer, unsigned long count, void *data) +{ + /* we don't support this....yet? Might replace qcset some day */ + return -EINVAL; +} +/* }}} */ +/* {{{ [fold] qc_proc_create(struct quickcam *qc) */ +/* Called for each camera plugged in, create file containing information of the camera */ +static int qc_proc_create(struct quickcam *qc) +{ + char name[9]; + struct proc_dir_entry *entry; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_create(quickcam=%p)",qc); + TEST_BUGR(!qc); + qc->proc_entry = NULL; + if (qc_proc_entry==NULL) return -ENOTDIR; + sprintf(name, "video%d", qc->vdev.minor); + entry = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR, qc_proc_entry); + if (!entry) { + PRINTK(KERN_WARNING,"Could not register procfs file entry"); + return -ENXIO; + } + entry->owner = THIS_MODULE; + entry->data = qc; + entry->read_proc = qc_proc_read; + entry->write_proc = qc_proc_write; + qc->proc_entry = entry; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_proc_destroy(struct quickcam *qc) */ +/* qc_proc_destroy may be called after qc_proc_create for given quickcam even if it failed */ +static void qc_proc_destroy(struct quickcam *qc) +{ + char name[9]; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_destroy(quickcam=%p)",qc); + TEST_BUG(!qc); + if (!qc->proc_entry) return; + TEST_BUG(!qc_proc_entry); + sprintf(name, "video%d", qc->vdev.minor); + remove_proc_entry(name, qc_proc_entry); + POISON(qc->proc_entry); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_proc_destroy() done"); +} +/* }}} */ +/* {{{ [fold] qc_proc_init(void) */ +/* Called when the driver is initially loaded, creates "/proc/video/quickcam" subdirectory */ +static int qc_proc_init(void) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_init()"); + qc_proc_entry = create_proc_entry(qc_proc_name, S_IFDIR, NULL); /* Create /proc/video/quickcam */ + if (!qc_proc_entry) { + /* create_proc_entry failed, possibly because /proc/video is missing (patch by aceJacek ) */ + proc_mkdir("video", NULL); /* Might fail, if the directory already exists, but we don't care */ + qc_proc_entry = create_proc_entry(qc_proc_name, S_IFDIR, NULL); + if (!qc_proc_entry) { + PRINTK(KERN_WARNING,"Could not register procfs dir entry"); + return -ENXIO; + } + } + qc_proc_entry->owner = THIS_MODULE; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_proc_exit(void) */ +/* Can be called after qc_proc_init() even if it has failed, in which case this does nothing */ +static void qc_proc_exit(void) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_proc_exit()"); + if (!qc_proc_entry) return; + remove_proc_entry(qc_proc_name, NULL); + POISON(qc_proc_entry); +} +/* }}} */ + +#else +static inline int qc_proc_create(struct quickcam *qc) { return 0; } +static inline void qc_proc_destroy(struct quickcam *qc) { } +static inline int qc_proc_init(void) { return 0; } +static inline void qc_proc_exit(void) { } +#endif /* HAVE_PROCFS */ +/* }}} */ +/* {{{ [fold] **** qc_adapt: Automatic exposure control ************************ */ + +#define MEASURE_ADAPT_DELAY 0 /* Measure adaptation delay, only for test purposes */ + +/* {{{ [fold] qc_adapt_init(struct quickcam *qc) */ +/* Initialize automatic exposure control structure. */ +static int qc_adapt_init(struct quickcam *qc) +{ + struct qc_adapt_data *ctrl = &qc->adapt_data; + ctrl->gain = 32768; + ctrl->olddelta = 4*256; /* best guess */ + ctrl->exposure = 32768; + ctrl->oldexposure = ctrl->exposure + 1; /* Slightly different for _issettled() */ + ctrl->midvaluesum = ctrl->oldmidvalue = 0; + ctrl->framecounter = 0; + ctrl->controlalg = EXPCONTROL_SATURATED; + IDEBUG_INIT(*ctrl); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_adapt_exit(struct quickcam *qc) */ + +static inline void qc_adapt_exit(struct quickcam *qc) +{ +#ifdef DEBUG + struct qc_adapt_data *ctrl = &qc->adapt_data; + if (qcdebug&QC_DEBUGINIT) PDEBUG("qc_adapt_exit(ctrl=%p)",ctrl); + IDEBUG_EXIT(*ctrl); +#endif +} + +/* }}} */ +/* {{{ [fold] qc_adapt_reset(struct quickcam *qc) */ +/* Must be called each time just before starting video adaptation */ +static inline void qc_adapt_reset(struct quickcam *qc) +{ + IDEBUG_TEST(qc->adapt_data); + if (!qc->settings.keepsettings) { + IDEBUG_EXIT(qc->adapt_data); + qc_adapt_init(qc); + } +} +/* }}} */ +/* {{{ [fold] qc_adapt_hassettled(struct quickcam *qc) */ +/* Return TRUE if the image brightness has settled */ +static inline Bool qc_adapt_hassettled(struct quickcam *qc) +{ + struct qc_adapt_data *ctrl = &qc->adapt_data; + IDEBUG_TEST(*ctrl); + if (ctrl->framecounter != 0) return FALSE; +//PDEBUG("control=%i oldexp=%i exp=%i",ctrl->controlalg,ctrl->oldexposure,ctrl->exposure); + return ctrl->controlalg==EXPCONTROL_FLOAT || ctrl->oldexposure==ctrl->exposure; +} +/* }}} */ +/* {{{ [fold] qc_adapt(struct quickcam *qc, int midvalue, int target, int *ret_exposure, int *ret_gain) */ + +/* Set image exposure and gain so that computed midvalue approaches the target value. + * midvalue = average pixel intensity on image 0..255 + * target = user settable preferable intensity 0..255 + * *ret_exposure = the exposure value to use for the camera, 0..65535 + * *ret_gain = the gain to use for the camera, 0..65535. + */ +static void qc_adapt(struct quickcam *qc, int midvalue, int target, int *ret_exposure, int *ret_gain) +{ +#if !MEASURE_ADAPT_DELAY + struct qc_adapt_data *ctrl = &qc->adapt_data; + /* Here are some constant for controlling the adaptation algorithm. You may play with them. */ + static const int saturation_min = 32; /* (0-127) If midvalue is out of this range, image is */ + static const int saturation_max = 256 - 8; /* (128-255) considered saturated and no Newton is used */ + + static const int adaptation_min = 5; /* (0-128) For small variations, do not change exposure */ + + static const int delta_min = 256/2; /* (2-16*256) Minimum and maximum value for delta */ + static const int delta_max = 256*256; /* (4*256-1024*256) */ + + static const int dmidvalue_min = 400; /* (1-128) Minimum differences, under which delta estimation (FIXME:disabled by changing values very big) */ + static const int dexposure_min = 400; /* (1-32000) will not be done due to inaccuracies */ + + static const int delta_speed = 256; /* (0-256) How fast or slowly delta can change */ + static const int small_adapt = 4; /* (0-1024) When very near optimal, exposure change size */ + static const int underestimate = 16; /* (0-250) Underestimation, may prevent oscillation */ + static const int bestguess = 256/2; /* (2-1024*256) If delta can not be computed, guess this */ + static const int midvalueaccum = 2; /* (1-100) How many frames to use for midvalue averaging */ + static const int framedelay = 5; /* (0-8) How many frames there are before a new exposure setting in effect */ + /* With QuickCam Web: if set at frame #0, it will be in effect at frame #4; skip 3 frames #1,#2,#3 */ + /* -> should be 3 with QuickCam Web, but it oscillates, FIXME:why? Setting to 4 fixes this */ + static const int gainstep = 256; /* (0-32768) Amount to change gain at one step */ + static const int gainneeded = 10; /* (0-255) How eagerly to change brightness with gain */ + /* End of tunable constants */ + + int newexposure, delta=0; + int dexposure=0, dmidvalue=0; + int deviation=0; /* Deviation of actual brightness from target brightness */ + int smoothdelta=0; /* Final, smoothed, value of delta */ + + TEST_BUG(ctrl==NULL || ret_gain==NULL || ret_exposure==NULL); + IDEBUG_TEST(*ctrl); + + if (ctrl->framecounter >= framedelay) + ctrl->midvaluesum += midvalue; + ctrl->framecounter++; + if (ctrl->framecounter < framedelay+midvalueaccum) { + *ret_exposure = ctrl->exposure; + *ret_gain = ctrl->gain; + return; + } + + midvalue = ctrl->midvaluesum / midvalueaccum; + ctrl->framecounter = 0; + ctrl->midvaluesum = 0; + + if (ctrl->exposure >= qc->sensor_data.sensor->adapt_gainhigh && + ctrl->oldexposure >= qc->sensor_data.sensor->adapt_gainhigh && + target - ctrl->oldmidvalue > gainneeded && + target - midvalue > gainneeded) + { + /* Exposure is at maximum, but image is still too dark. Increase gain.*/ + ctrl->gain = ctrl->gain + ctrl->gain/2 + gainstep; + if (ctrl->gain > 65535) ctrl->gain = 65535; + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("increasing gain to %i", ctrl->gain); + } else + if (ctrl->exposure <= qc->sensor_data.sensor->adapt_gainlow && + ctrl->oldexposure <= qc->sensor_data.sensor->adapt_gainlow && + target - ctrl->oldmidvalue <= gainneeded && + target - midvalue <= gainneeded) + { + /* Decrease gain if unnecessarily high */ + ctrl->gain = ctrl->gain - ctrl->gain/2 - gainstep; + if (ctrl->gain < 0) ctrl->gain = 0; + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("decreasing gain to %i", ctrl->gain); + } + + if (ctrl->oldmidvaluecontrolalg = EXPCONTROL_SATURATED; + newexposure = ctrl->exposure * 2; + } else + if (ctrl->oldmidvalue>=saturation_max || midvalue>=saturation_max) { + /* Image is oversaturated, Newton method would give inaccurate results */ + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Decreasing exposure"); + ctrl->controlalg = EXPCONTROL_SATURATED; + newexposure = ctrl->exposure / 2; + } else { + deviation = target - midvalue; + if (ABS(deviation) < adaptation_min) { + /* For small variations, adapt linearly */ + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Small deviation %i",deviation); + ctrl->controlalg = EXPCONTROL_FLOAT; + newexposure = small_adapt * SGN(deviation) + ctrl->exposure; + } else { + /* Try using Newton method for estimating correct exposure value */ + ctrl->controlalg = EXPCONTROL_NEWTON; + dmidvalue = midvalue - ctrl->oldmidvalue; + dexposure = ctrl->exposure - ctrl->oldexposure; + if (ABS(dmidvalue) < dmidvalue_min || + ABS(dexposure) < dexposure_min || + SGN(dmidvalue) != SGN(dexposure)) + { + /* Can not estimate delta with Newton method, just guess */ + if (ctrl->olddelta < 2) { + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Best guessing"); + smoothdelta = bestguess; + } else { + Bool cross = SGN(midvalue-target) != SGN(ctrl->oldmidvalue-target); + smoothdelta = cross ? (ctrl->olddelta / 2) : (ctrl->olddelta * 3 / 2); + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Change more exposure, smoothdelta=%i",smoothdelta); + } + } else { + /* Everything is well, use here actual Newton method */ + delta = (256 - underestimate) * dexposure / dmidvalue; + smoothdelta = (delta_speed*delta + (256-delta_speed)*ctrl->olddelta) / 256; + if (qcdebug&QC_DEBUGADAPTATION) PDEBUG("Using Newton, delta=%i",delta); + } + } + /* Compute new exposure based on guessed/computed delta */ + smoothdelta = CLIP(smoothdelta, delta_min,delta_max); + dexposure = deviation * smoothdelta / 256; + /* Newton works linearly, but exposure/brightness are not linearly related */ + /* The following test fixes the worst deficiencies due to that (I hope) */ + if (-dexposure > ctrl->exposure/2) + dexposure = -ctrl->exposure/2; + newexposure = dexposure + ctrl->exposure; + ctrl->olddelta = smoothdelta; + } + + newexposure = CLIP(newexposure, 2,65535); + + if (qcdebug&QC_DEBUGADAPTATION) + PDEBUG("midval=%i dev=%i dmidv=%i dexp=%i smdelta=%i olddelta=%i newexp=%i gain=%i", + midvalue,deviation,dmidvalue,dexposure,smoothdelta,ctrl->olddelta,newexposure,ctrl->gain); + + ctrl->oldexposure = ctrl->exposure; + ctrl->exposure = newexposure; + ctrl->oldmidvalue = midvalue; + *ret_exposure = newexposure; + *ret_gain = ctrl->gain; +#else + /* This code is for measuring the delay between an exposure settings and until + * it becomes in effect. Only useful for developing the adaptation algorithm. */ + /* Some delays: when a setting is changed at frame number #0, + * it becomes in effect in frame xx for exposure gain + * QuickCam Web/0850/normal mode 4 4 + * QuickCam Web/0850/compressed mode 5 5 + * QuickCam Express/840 2 1-5 + * + */ + static int exp = 0; + static int gain = 0; + static const int changedel = 20; + static int state = 0; + static int framenum = 0; + PRINTK(KERN_CRIT,"Measuring: framenum=%i, midvalue=%i",framenum,midvalue); + if ((framenum%changedel)==0) { + switch (state) { + default: + case 0: + PRINTK(KERN_CRIT,"Measuring: set to black"); + exp = 0; + gain = 0; + break; + case 1: + PRINTK(KERN_CRIT,"Measuring: changing exposure"); + exp = 65535; + break; + case 2: + PRINTK(KERN_CRIT,"Measuring: changing gain"); + gain = 32535; + break; + } + state = ((state+1) % 3); + } + *ret_exposure = exp; + *ret_gain = gain; + framenum++; +#endif +} + +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_frame: Frame capturing functions ************************* */ + +/* From /usr/src/linux/Documentation/smp.tex: + * + Kernel mode process (e.g. system calls): + * - No other kernel mode processes may run simultaneously/pre-empt + * (kernel mode processes are atomic with respect to each other) + * (Does not hold for 2.6.x) + * - Exception is voluntary sleeping, in which case re-entry is allowed + * (Does not hold for 2.6.x) + * - Interrupts may pre-empt (but return to same process) + * (interrupts can be disabled if necessary) + * + Interrupt mode execution + * - Kernel mode process may not pre-empt/execute simultaneously + * - Other interrupts may pre-empt, however same interrupt is not nested + */ + +/* We have here a quite typical producer-consumer scheme: + * Interrupt routine produces more frame data, while + * kernel mode processes consume it + * Read: Linux Device Drivers, Alessandro Rubini et al, 2nd edition, pg. 279 + * "Using Circular Buffers" + */ + +/* Initialization and cleanup routines, called from kernel mode processes */ +/* {{{ [fold] qc_frame_init(struct quickcam *qc) */ +static int qc_frame_init(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + int n; + + if (qcdebug&QC_DEBUGFRAME || qcdebug&QC_DEBUGINIT) PDEBUG("qc_frame_init(qc=%p)",qc); + TEST_BUGR(qc==NULL || fd==NULL); + TEST_BUGR(in_interrupt()); + fd->rawdatabuf = vmalloc(FRAME_DATASIZE * FRAME_BUFFERS); + if (!fd->rawdatabuf) return -ENOMEM; + memset(fd->rawdatabuf, 0, FRAME_DATASIZE * FRAME_BUFFERS); /* Never let user access random kernel data */ + fd->head = 0; /* First buffer to fill */ + fd->tail = 0; /* First buffer to get */ + spin_lock_init(&fd->tail_lock); + fd->tail_in_use= FALSE; + init_waitqueue_head(&fd->wq); + fd->waiting = 0; + fd->exiting = FALSE; + for (n=0; nbuffers[n].rawdatalen = 0; + fd->lost_frames = 0; + IDEBUG_INIT(*fd); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_frame_exit(struct quickcam *qc) */ +/* This function must be called with qc->lock acquired + * (it may release it temporarily and sleep) */ +static void qc_frame_exit(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; +#if PARANOID + unsigned long startjiffy = jiffies; +#endif + if (qcdebug&QC_DEBUGFRAME || qcdebug&QC_DEBUGINIT) PDEBUG("qc_frame_exit(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + TEST_BUG(in_interrupt()); + TEST_BUG(qc==NULL || fd==NULL); + fd->exiting = TRUE; + fd->maxrawdatalen = 0; /* Hopefully stops all ongoing captures, might need locking though */ + wake_up(&fd->wq); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("waiting=%i",fd->waiting); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_frame_exit() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); /* The lock was down when entering this function */ + while (fd->waiting > 0) { + schedule(); +#if PARANOID + if (jiffies-startjiffy > 60*HZ) { + PRINTK(KERN_CRIT,"Wait queue never completing!! (waiting=%i)",fd->waiting); + break; + } +#endif + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_frame_exit() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); + vfree(fd->rawdatabuf); + POISON(fd->rawdatabuf); + IDEBUG_EXIT(*fd); +} +/* }}} */ + +/* Consumer routines, called from kernel mode processes */ +/* {{{ [fold] qc_frame_get(struct quickcam *qc, unsigned char **buf) */ +/* Wait until next frame is ready and return the frame length + * and set buf to point to the frame. If error happens, + * return standard Linux negative error number. + * qc_frame_free() must be called after the frame is not needed anymore. + * qc->lock must be acquired when entering this routine + * (it may release it temporarily and sleep). + */ +static int qc_frame_get(struct quickcam *qc, unsigned char **buf) +{ + struct qc_frame_data *fd = &qc->frame_data; + int ret; + + TEST_BUGR(qc==NULL || fd==NULL || fd->tail_in_use); + TEST_BUGR(in_interrupt()); + IDEBUG_TEST(*fd); + + /* Wait until the next frame is available */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_get/consume(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + fd->waiting++; + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_frame_get() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); /* Release lock while waiting */ + + ret = wait_event_interruptible(fd->wq, fd->head!=fd->tail || fd->exiting); //FIXME:What if we get -ERESTARTSYS? + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_frame_get() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); + if (!ret) { + if (!fd->exiting) { + unsigned int t; + unsigned long flags; + spin_lock_irqsave(&fd->tail_lock, flags); + fd->tail_in_use = TRUE; + t = fd->tail; + spin_unlock_irqrestore(&fd->tail_lock, flags); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_get/consume(qc=%p,tail=%i,head=%i,tail->rawdatalen=%i), got frame",qc,t,fd->head,fd->buffers[t].rawdatalen); + *buf = fd->rawdatabuf + t*FRAME_DATASIZE; + ret = fd->buffers[t].rawdatalen; + } else { + ret = -ENODATA; + } + } + fd->waiting--; + fd->lost_frames = 0; + if (ret<0 && (qcdebug&(QC_DEBUGERRORS|QC_DEBUGFRAME))) PDEBUG("failed qc_frame_get()=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_frame_free(struct quickcam *qc) */ +/* Free up the last frame returned from qc_frame_get() (it must be called first) */ +static inline void qc_frame_free(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + unsigned long flags; + TEST_BUG(qc==NULL || fd==NULL); + TEST_BUG(in_interrupt()); + TEST_BUG(fd->head==fd->tail); /* The current fd->tail is not available to be freed! */ + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_free/consume(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + /* Free up previous frame and advance to next */ + spin_lock_irqsave(&fd->tail_lock, flags); + fd->tail_in_use = FALSE; + fd->tail = (fd->tail + 1) % FRAME_BUFFERS; + spin_unlock_irqrestore(&fd->tail_lock, flags); +} +/* }}} */ +/* {{{ [fold] qc_frame_test(struct quickcam *qc) */ +/* Return TRUE if next frame is immediately available, FALSE otherwise. */ +static inline Bool qc_frame_test(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_test/consume(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + return fd->head != fd->tail; +} +/* }}} */ + +/* Producer routines, called from interrupt context */ +/* {{{ [fold] qc_frame_begin(struct quickcam *qc) */ +/* Begin capturing next frame from camera. If buffer is full, the frame will be lost */ +static void qc_frame_begin(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + int framesize, h; + TEST_BUG(qc==NULL || fd==NULL); + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_begin/produce(qc=%p,tail=%i,head=%i)",qc,fd->tail,fd->head); + if (fd->exiting) return; + TEST_BUG(fd->rawdatabuf==NULL); + h = fd->head; + fd->buffers[h].rawdatalen = 0; + + /* Use sensor information to get the framesize (i.e. how much we expect to receive bytes per image) */ + /* FIXME: should compute data size differently in compressed mode */ + framesize = qc->sensor_data.width * qc->sensor_data.height; + fd->maxrawdatalen = MIN(framesize, FRAME_DATASIZE); +} +/* }}} */ +/* {{{ [fold] qc_frame_add(struct quickcam *qc, unsigned char *data, int datalen) */ +/* Store more data for a frame, return nonzero if too much data or other error */ +static int qc_frame_add(struct quickcam *qc, unsigned char *data, int datalen) +{ + struct qc_frame_data *fd = &qc->frame_data; + int h = fd->head; + int bytes; + + TEST_BUGR(qc==NULL || fd==NULL); + IDEBUG_TEST(*fd); + TEST_BUGR(fd->rawdatabuf==NULL); + if (fd->maxrawdatalen <= fd->buffers[h].rawdatalen) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("buffer disabled, maxrawdatalen=%i rawdatalen=%i datalen=%i",fd->maxrawdatalen,fd->buffers[h].rawdatalen, datalen); + return -EBUSY; + } + bytes = MIN(datalen, fd->maxrawdatalen - fd->buffers[h].rawdatalen); + memcpy(fd->rawdatabuf + h*FRAME_DATASIZE + fd->buffers[h].rawdatalen, data, bytes); + fd->buffers[h].rawdatalen += bytes; + if (bytes < datalen) { + if (qcdebug&QC_DEBUGERRORS) PRINTK(KERN_ERR,"out of buffer space by %i, maxrawdatalen=%i rawdatalen=%i datalen=%i", datalen-bytes,fd->maxrawdatalen,fd->buffers[h].rawdatalen, datalen); + return -ENOSPC; + } + return 0; +} +/* }}} */ +/* {{{ [fold] qc_frame_end(struct quickcam *qc) */ +/* Finished capturing most recent frame from camera */ +/* (may be premature end, in which case some data is missing) */ +static void qc_frame_end(struct quickcam *qc) +{ + static const int minrawdatalen = 32*32; /* If frame length is less than this many bytes, discard it */ + struct qc_frame_data *fd = &qc->frame_data; + unsigned int t, h; + unsigned long flags; + Bool lost_frame; + TEST_BUG(qc==NULL || fd==NULL); + h = fd->head; + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_end/produce(qc=%p,tail=%i,head=%i), got %i bytes",qc,fd->tail,h,fd->buffers[h].rawdatalen); + IDEBUG_TEST(*fd); + fd->maxrawdatalen = 0; /* Stop frame data capturing */ +#if DUMPDATA + PDEBUG("frame_end: got %i bytes", fd->buffers[h].rawdatalen); +#endif + if (fd->buffers[h].rawdatalen < minrawdatalen) { + /* No enough data in buffer, don't advance index */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("discarding frame with only %u bytes", fd->buffers[h].rawdatalen); + return; + } + h = (h + 1) % FRAME_BUFFERS; /* Select next frame buffer to fill */ + + lost_frame = FALSE; + spin_lock_irqsave(&fd->tail_lock, flags); + t = fd->tail; + if (t == h) { + lost_frame = TRUE; + /* FIXME: the below should work fine for two buffers, but not so well for more. It should be possible + * to drop oldest frame even when the current tail is in use. */ + if (fd->tail_in_use) { + /* Can not drop the oldest frame, it is in use. Drop the newest frame */ + h = (h + FRAME_BUFFERS - 1) % FRAME_BUFFERS; /* Decrease head by one back to the original */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("dropping newest frame"); + } else { + /* Drop the oldest frame */ + fd->tail = (t + 1) % FRAME_BUFFERS; /* Drop the oldest frame away */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("dropping oldest frame"); + } + } + spin_unlock_irqrestore(&fd->tail_lock, flags); + if (lost_frame) { + if (qcdebug&QC_DEBUGCOMMON || qcdebug&QC_DEBUGFRAME) PRINTK(KERN_NOTICE,"frame lost"); + fd->lost_frames++; + if (fd->lost_frames > 10) { + /* Here we should call qc_isoc_stop() to stop isochronous + * streaming since the application is clearly not reading frames at all. + * However, we are now in interrupt context but qc_isoc_stop() has + * to be in process context... so we can't do that. + * FIXME: add tasklet/bottomhalf/whatever needed to do it. + */ + if (qcdebug&QC_DEBUGFRAME) PDEBUG("too many lost frames: %i", fd->lost_frames); + } + } + fd->head = h; + wake_up(&fd->wq); +} +/* }}} */ +/* {{{ [fold] qc_frame_flush(struct quickcam *qc) */ +/* Reject the current data already captured into buffer and end frame */ +void qc_frame_flush(struct quickcam *qc) +{ + struct qc_frame_data *fd = &qc->frame_data; + unsigned int h = fd->head; + TEST_BUG(qc==NULL || fd==NULL); + IDEBUG_TEST(*fd); + if (qcdebug&QC_DEBUGFRAME) PDEBUG("qc_frame_flush/produce(qc=%p,tail=%i,head=%i), flush %i bytes",qc,fd->tail,h,fd->buffers[h].rawdatalen); + fd->buffers[h].rawdatalen = 0; /* Empty buffer */ + fd->maxrawdatalen = 0; /* Stop frame data capturing */ +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_stream: USB datastream processing functions *************** */ + +/* {{{ [fold] qc_stream_init(struct quickcam *qc) */ +/* Initialize datastream processing */ +static int qc_stream_init(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_stream_init(quickcam=%p)",qc); + qc->stream_data.capturing = FALSE; + qc->stream_data.frameskip = qc->settings.frameskip; + IDEBUG_INIT(qc->stream_data); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_stream_exit(struct quickcam *qc) */ +/* Stop datastream processing, after this qc_stream_add should not be called */ +static void qc_stream_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_stream_exit(quickcam=%p)",qc); + if (qc->stream_data.capturing) + qc_frame_end(qc); + IDEBUG_EXIT(qc->stream_data); +} +/* }}} */ +/* {{{ [fold] qc_stream_error(struct quickcam *qc) */ +/* This is called when there are data lost due to errors in the stream */ +static void qc_stream_error(struct quickcam *qc) +{ + /* Skip rest of data for this frame */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("qc_stream_error(qc=%p)", qc); + if (qc->stream_data.capturing) + qc_frame_end(qc); + IDEBUG_EXIT(qc->stream_data); + qc_stream_init(qc); +} +/* }}} */ +/* {{{ [fold] qc_stream_add(struct quickcam *qc, unsigned char *data, int datalen) */ +/* + * Analyse an USB packet of the data stream and store it appropriately. + * Each packet contains an integral number of chunks. Each chunk has + * 2-bytes identification, followed by 2-bytes that describe the chunk + * length. Known/guessed chunk identifications are: + * 8001/8005/C001/C005 - Begin new frame + * 8002/8006/C002/C006 - End frame + * 0200/4200 - Contains actual image data, bayer or compressed + * 0005 - 11 bytes of unknown data + * 0100 - 2 bytes of unknown data + * The 0005 and 0100 chunks seem to appear only in compressed stream. + * Return the amount of image data received or negative value on error. + */ +static int qc_stream_add(struct quickcam *qc, unsigned char *data, int datalen) +{ + struct qc_stream_data *sd = &qc->stream_data; + int id, len, error, totaldata = 0; + + IDEBUG_TEST(*sd); + while (datalen) { + if (datalen < 4) { + if (qcdebug&QC_DEBUGBITSTREAM) PRINTK(KERN_ERR,"missing chunk header"); + break; + } + id = (data[0]<<8) | data[1]; + len = (data[2]<<8) | data[3]; + data += 4; + datalen -= 4; + if (datalen < len) { + if (qcdebug&QC_DEBUGBITSTREAM) PRINTK(KERN_ERR,"missing chunk contents"); + break; + } + switch (id) { + case 0x8001: + case 0x8005: + case 0xC001: + case 0xC005: + /* Begin new frame, len should be zero */ + if (PARANOID && len!=0) PDEBUG("New frame: len!=0"); + if (sd->capturing) { + if (qcdebug&QC_DEBUGBITSTREAM) PDEBUG("Missing frame end mark in stream"); + qc_frame_end(qc); + } + sd->capturing = TRUE; + if (--sd->frameskip < 0) sd->frameskip = qc->settings.frameskip; + if (sd->frameskip==0) qc_frame_begin(qc); + break; + case 0x8002: + case 0x8006: + case 0xC002: + case 0xC006: + /* End frame, len should be zero */ + if (PARANOID && len!=0) PDEBUG("End frame: len!=0"); + if (sd->capturing) { + if (sd->frameskip==0) qc_frame_end(qc); + } else { + if (qcdebug&QC_DEBUGBITSTREAM) PDEBUG("Missing frame begin mark in stream"); + } + sd->capturing = FALSE; + break; + case 0x0200: + case 0x4200: + /* Image data */ + if (!sd->capturing && (qcdebug&QC_DEBUGBITSTREAM)) PDEBUG("Chunk of data outside frames!"); + if (sd->capturing && sd->frameskip==0) { + error = qc_frame_add(qc, data, len); + } else { + error = 0; + } + if (error) { + /* If qc_frame_add returns error, there is more data than the frame may have, + * in which case we assume stream is corrupted and skip rest packet */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("qc_frame_add error %i",error); + } else { + totaldata += len; + } + break; + case 0x0005: + /* Unknown chunk with 11 bytes of data, occurs just before end of each frame in compressed mode */ + if (len==11) break; + case 0x0100: + /* Unknown chunk with 2 bytes of data, occurs 2-3 times per USB interrupt */ + if (len==2) break; + default: + /* Unknown chunk */ + #ifdef DEBUG + if (qcdebug&QC_DEBUGBITSTREAM) { + static char dump[4*1024]; + char *dump_p = dump; + int i; + for (i=0; i= KERNEL_VERSION(2,6,0) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +static void qc_isoc_handler(struct urb *urb, struct pt_regs *ptregs) +#else +static void qc_isoc_handler(struct urb *urb) +#endif +{ + struct quickcam *qc; + int payload = 0; /* Amount of all data camera sent */ + int totaldata = 0; /* Amount of image data camera sent */ + int i; +#ifdef DEBUG + /* Check for nested interrupts, shouldn't happen */ + volatile static Bool in_progress = FALSE; + TEST_BUG(in_progress); + in_progress = TRUE; +#endif + + if (qcdebug&QC_DEBUGINTERRUPTS) PDEBUG("[INTR] qc_isoc_handler(urb=%p)",urb); + TEST_BUG(urb==NULL); + qc = urb->context; + TEST_BUG(qc==NULL); + IDEBUG_TEST(qc->isoc_data); + + if (!qc->connected || !qc->isoc_data.streaming) { + /* Camera was disconnected or isochronous stream just disabled--must not resubmit urb */ + PDEBUG("Ignoring isoc interrupt, dev=%p streaming=%i status=%i", qc->dev, qc->isoc_data.streaming, urb->status); + goto out; + } + + if (urb->status<0) { + qc->isoc_data.errorcount++; + switch (urb->status) { + case -EXDEV: /* Partially completed, look at individual frame status */ + break; + default: + /* Seen here: -EOVERFLOW (75): Value too large for defined data type */ + case -EPROTO: /* Bitstuff error or unknown USB error */ + case -EILSEQ: /* CRC mismatch */ + case -ETIMEDOUT: /* Transfer timed out */ + case -EREMOTEIO: /* Short packet detected */ + case -EPIPE: /* Babble detect or endpoint stalled */ + case -ECONNRESET: /* Asynchronous unlink, should not happen, but does with 2.6.x */ + if (qcdebug&QC_DEBUGERRORS) PRINTK(KERN_ERR,"isoc URB error %i, resubmitting",urb->status); + goto resubmit; + case -ESHUTDOWN: + case -ENOENT: /* URB was unlinked */ + case -ENODEV: /* Device was removed */ + if (qcdebug&QC_DEBUGERRORS) PRINTK(KERN_ERR,"isoc URB error %i, returning",urb->status); + goto out; + } + } + + for (i=0; inumber_of_packets; i++) { + if ((int)urb->iso_frame_desc[i].status<0) { /* Note that the cast to int MUST be here! */ + if (qcdebug&QC_DEBUGERRORS) PDEBUG("USB transfer error %i", urb->iso_frame_desc[i].status); + qc->isoc_data.errorcount++; + qc_stream_error(qc); + continue; + } + qc->isoc_data.errorcount = 0; + payload += urb->iso_frame_desc[i].actual_length; +#if PARANOID +{ +int xx = urb->iso_frame_desc[i].actual_length; +if (xx>2000) { +PDEBUG("i=%i status=%i transfer_buffer=%p transfer_buffer_length=%i actual_length=%i number_of_packets=%i", + i, urb->status, urb->transfer_buffer, urb->transfer_buffer_length, urb->actual_length, urb->number_of_packets); +PDEBUG("offset=%i length=%i actual_length=%i pstatus=%i", +urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].length, urb->iso_frame_desc[i].actual_length, urb->iso_frame_desc[i].status); +goto out; +} +} +#endif + totaldata += qc_stream_add(qc, urb->transfer_buffer + urb->iso_frame_desc[i].offset, + urb->iso_frame_desc[i].actual_length); + } + if (qcdebug&QC_DEBUGBITSTREAM) PDEBUG("payload=%i totaldata=%i",payload,totaldata); + if (qcdebug&(QC_DEBUGBITSTREAM|QC_DEBUGERRORS)) if (payload==0) PDEBUG("USB interrupt, but no data received!"); +resubmit: + /* Resubmit URB */ + if (qc->isoc_data.errorcount < ISOC_PACKETS*ISOC_URBS*8) { + urb->dev = qc->dev; /* Required for 2.4.x */ + i = usb_submit_urb(urb,GFP_ATOMIC); + if (i) PDEBUG("failed to resubmit URB, code=%i, dev=%p",i,urb->dev); + } else { + PDEBUG("Too many errors, giving up"); + } +out: +#ifdef DEBUG + in_progress = FALSE; +#endif + return; +} +/* }}} */ +/* {{{ [fold] qc_isoc_start(struct quickcam *qc) */ +/* + * Start USB isochronous image transfer from camera to computer + * (Set USB camera interface and allocate URBs and submit them) + * Sensor must be initialized beforehand (qc_init_sensor) + */ +static int qc_isoc_start(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + int ret = -ENOMEM; /* Return value on error */ + struct urb *urb; + int i, b; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_start(qc=%p)",qc); + TEST_BUGR_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_TEST(*id); + + if (id->streaming) return 0; /* Already started */ + id->streaming = TRUE; + id->errorcount = 0; + + /* Allocate transfer buffer */ + id->buffer = kmalloc(ISOC_URBS * ISOC_PACKETS * ISOC_PACKET_SIZE, GFP_KERNEL); + CHECK_ERROR(!id->buffer, fail1, "Out of memory allocating id->buffer"); + + /* Allocate URBs, fill them, and put them in the URB array */ + for (b=0; burbs[b] = usb_alloc_urb(ISOC_PACKETS,GFP_KERNEL); /* Zeroes the allocated data up to iso_frame_desc[], *not* including the last! */ + CHECK_ERROR(!urb, fail2, "Out of memory allocating urbs"); + urb->dev = qc->dev; + urb->context = qc; + urb->pipe = usb_rcvisocpipe(qc->dev, QUICKCAM_ISOPIPE); + urb->transfer_flags = URB_ISO_ASAP; /* Leave URB_ASYNC_UNLINK clear and never call usb_unlink_urb() */ + urb->complete = qc_isoc_handler; + urb->number_of_packets = ISOC_PACKETS; + urb->transfer_buffer = id->buffer; + urb->transfer_buffer_length = ISOC_URBS * ISOC_PACKETS * ISOC_PACKET_SIZE; + urb->interval = 1; /* See Table 9-10 of the USB 1.1 specification */ + for (i=0; iiso_frame_desc[i].offset = b*ISOC_PACKETS*ISOC_PACKET_SIZE + i*ISOC_PACKET_SIZE; + urb->iso_frame_desc[i].length = ISOC_PACKET_SIZE; + } + } + + /* Alternate interface 3 is the biggest frame size */ + /* JFC use 1: but do not know why */ + /* QuickCam Web: Interface 0, alternate 1, endpoint 0x81 -tuukkat */ + qc_i2c_wait(qc); /* There must not be control URBs going when calling set_interface() */ + ret = usb_set_interface(qc->dev, qc->iface, 1); + CHECK_ERROR(ret<0, fail3, "set_interface failed"); + + /* Submit URBs */ + for (b=0; burbs[b],GFP_KERNEL); + CHECK_ERROR(ret<0, fail4, "submit urbs failed"); + } + + /* Tell camera to start sending data */ + ret = qc->sensor_data.sensor->start(qc); /* Start current frame */ + CHECK_ERROR(ret<0, fail5, "sensor_data.start failed"); + ret = qc_stv_set(qc, STV_ISO_ENABLE, 1); /* Start isochronous streaming */ + CHECK_ERROR(ret<0, fail6, "qc_stv_set() failed"); + return 0; + + /* Cleanup and return error code on failure */ +fail6: qc->sensor_data.sensor->stop(qc); /* stop current frame. */ +fail5: b = ISOC_URBS; +fail4: while (--b >= 0) usb_kill_urb(id->urbs[b]); + usb_set_interface(qc->dev, qc->iface, 0); /* Set packet size to 0 (Interface 0, alternate 0, endpoint 0x81 -tuukkat) */ +fail3: b = ISOC_URBS; +fail2: while (--b >= 0) usb_free_urb(id->urbs[b]); + kfree(id->buffer); +fail1: if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_isoc_init()=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_isoc_stop(struct quickcam *qc) */ +/* + * Stop USB isochronous image transfer from camera to computer + * (Tell camera to stop sending images, set idle USB interface and free URBs) + * There must be no more isochronous transfer interrupts after this returns + * nor any running handlers anymore. + */ +static void qc_isoc_stop(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + int b, r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_stop(quickcam=%p)",qc); + TEST_BUG_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_TEST(*id); + + if (!id->streaming) return; /* Already stopped */ + if (qc->connected) { + if ((r=qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) /* stop ISO-streaming. */ + PRINTK(KERN_ERR,"qc_stv_set error %i",r); + if ((r=qc->sensor_data.sensor->stop(qc))<0) /* stop current frame. */ + PRINTK(KERN_ERR,"sensor_data.stop error %i",r); + qc_i2c_wait(qc); /* When calling set_interface(), there must not be control URBs on way */ + if (usb_set_interface(qc->dev, qc->iface, 0) < 0) /* Set packet size to 0 (Interface 0, alternate 0, endpoint 0x81 -tuukkat) */ + PRINTK(KERN_ERR,"usb_set_interface error"); + } + id->streaming = FALSE; /* Ensure that no more isochronous URBs will be submitted from the interrupt handler */ + mb(); + for (b=0; bstatus = %i", b, id->urbs[b]->status); + usb_kill_urb(id->urbs[b]); + usb_free_urb(id->urbs[b]); + POISON(id->urbs[b]); + } + + kfree(id->buffer); + POISON(id->buffer); + return; +} +/* }}} */ +/* {{{ [fold] qc_isoc_init(struct quickcam *qc) */ +/* + * Initialize isochronous streaming functions + */ +static int qc_isoc_init(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_init(quickcam=%p)",qc); + TEST_BUGR_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_INIT(*id); + id->streaming = FALSE; + return 0; +} +/* }}} */ +/* {{{ [fold] qc_isoc_exit(struct quickcam *qc) */ +/* + * Uninitialize isochronous streaming functions + */ +static inline void qc_isoc_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_isoc_exit(quickcam=%p)",qc); + qc_isoc_stop(qc); + IDEBUG_EXIT(qc->isoc_data); +} +/* }}} */ +/* {{{ [fold] Bool qc_isoc_streaming(struct quickcam *qc) */ +static inline Bool qc_isoc_streaming(struct quickcam *qc) +{ + struct qc_isoc_data *id = &qc->isoc_data; + + TEST_BUGR_MSG(qc==NULL || id==NULL, "qc||id==NULL"); + IDEBUG_TEST(*id); + return id->streaming; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_sensor: Common routines for all sensors ******************* */ + +/* {{{ [fold] qc_sensor_setsize0(struct quickcam *qc, unsigned int width, unsigned int height) */ +/* Called when the application requests a specific image size. Should set the + * actual delivered image size to as close to the requested as possible. + * The image size, as delivered from the camera, can be also set to reduce + * required bandwidth, if possible, but it is not necessary. + * This is a private function to qc_sensor_*, other modules should use qc_sensor_setsize() + * If capt is TRUE, then qc_capt_get may be called (and qc_capt_init must be called before). + */ +static int qc_sensor_setsize0(struct quickcam *qc, unsigned int width, unsigned int height, Bool capt) +{ + unsigned char *f; + int r; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_sensor_setsize(qc=%p,width=%i,height=%i)",qc,width,height); + TEST_BUGR_MSG(qc==NULL, "qc==NULL!"); + + if (width < min_framewidth || width > qc->sensor_data.maxwidth) return -EINVAL; + if (height < min_frameheight || height > qc->sensor_data.maxheight) return -EINVAL; + + /* Applications require, when using Xvideo extension, that the + * frame size is multiple of 8. This is a bug in apps or Xvideo. -tuukkat */ + if (qc->settings.compat_16x) { + width = (width /16)*16; + height = (height/16)*16; + } + /* Set the size only if changed */ + if (qc->vwin.width==width && qc->vwin.height==height) return 0; + + /* For HDCS-1000 we must wait for frame before setting size */ + if (capt) qc_capt_get(qc, &f); + + qc->sensor_data.width = width; /* The sensor-specific code may modify these if not suitable */ + qc->sensor_data.height = height; + if ((r = qc->sensor_data.sensor->set_size(qc, width, height))<0) { + PDEBUG("set_size sensor failed"); + return r; + } + + /* Set the closest size we can actually deliver to application */ + qc->vwin.width = width; + qc->vwin.height = height; + if ((r = qc_i2c_wait(qc))<0) return r; + qc_frame_flush(qc); + return 0; +} +/* }}} */ +/* {{{ [fold] qc_sensor_setsize(struct quickcam *qc, unsigned int width, unsigned int height) */ +/* Called when the application requests a specific image size. Should set the + * actual delivered image size to as close to the requested as possible. + * The image size, as delivered from the camera, can be also set to reduce + * required bandwidth, if possible, but it is not necessary. + * qc_isoc_init() and qc_capt_init() have to be called before this function. + */ +static inline int qc_sensor_setsize(struct quickcam *qc, unsigned int width, unsigned int height) +{ + int r; + r = qc_sensor_setsize0(qc, width, height, qc_isoc_streaming(qc)); + return r; +} +/* }}} */ +/* {{{ [fold] qc_sensor_init(struct quickcam *qc) */ +/* + * Initialise sensor. Initializes all data in qc->sensor which is common to all + * types of sensors and calls the sensor-specific initialization routine. + * The Photobit starts the pixel integration immediately after the reset. + * Note: must call qc_i2c_init() and qc_frame_init() before this function! + */ +static int qc_sensor_init(struct quickcam *qc) +{ + int r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_init_sensor(qc=%p)",qc); + TEST_BUGR_MSG(qc==NULL, "qc==NULL!"); + + qc->sensor_data.width = -1; + qc->sensor_data.height = -1; + qc->sensor_data.exposure = -1; + qc->sensor_data.rgain = -1; + qc->sensor_data.ggain = -1; + qc->sensor_data.bgain = -1; + qc->sensor_data.subsample = qc->settings.subsample; + qc->sensor_data.compress = qc->settings.compress; + + if ((r = qc->sensor_data.sensor->init(qc))<0) goto fail; + if ((r = qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) goto fail; /* Stop isochronous streaming */ + if ((r = qc->sensor_data.sensor->stop(qc))<0) goto fail; /* Stop current frame */ + + /* Set capture size */ + qc->vwin.width = 0; /* Set to illegal value (ensures resetting) */ + qc->vwin.height = 0; + if ((r = qc_sensor_setsize0(qc, qc->sensor_data.maxwidth, qc->sensor_data.maxheight, FALSE))<0) goto fail; + + /* Set brightness settings */ + if ((r = qc->sensor_data.sensor->set_levels(qc, qc->vpic.brightness, qc->vpic.contrast, qc->vpic.hue, qc->vpic.colour))<0) goto fail; + if (qc->sensor_data.sensor->set_target!=NULL) + if ((r = qc->sensor_data.sensor->set_target(qc, qc->vpic.brightness))<0) goto fail; + return 0; + +fail: PRINTK(KERN_ERR,"sensor initialization failed: %i",r); + return r; +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_capt: User image capturing functions ******************** */ + +/* {{{ [fold] qc_capt_get(struct quickcam *qc, unsigned char **frame) */ +/* Wait until next image is ready and return the image length in bytes + * and set "frame" to point to the image. If error happens, + * return standard Linux negative error number. The image will be in + * palette and size requested by the user (quickcam->vpic,vwin). + */ +static int qc_capt_get(struct quickcam *qc, unsigned char **frame) +{ + struct qc_capt_data *cd = &qc->capt_data; + unsigned char *rawdata=NULL; /* Raw data from camera */ + int rawdatalen; + int retrycount = qc->settings.retryerrors ? 8 : 0; + int settlecount = cd->settled ? 0 : qc->settings.settle; /* If the picture has already settled, do not wait for it again */ + int midvalue; + int r; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_capt_get(quickcam=%p)",qc); + IDEBUG_TEST(*cd); + if ((r = qc_isoc_start(qc))<0) goto fail; /* Start receiving data */ + + do { + r = qc_frame_get(qc, &rawdata); + if (r < 0) goto error; + rawdatalen = r; + r = qc_fmt_convert(qc, rawdata, rawdatalen, cd->frame, MAX_FRAME_SIZE, &midvalue); + if (r < 0) { + qc_frame_free(qc); + goto error; + } + + if (qc->vpic_pending) { + qc->vpic_pending = FALSE; + if (!qc->settings.adaptive) { + /* Set new values now */ + qc->sensor_data.sensor->set_levels(qc, qc->vpic.brightness, qc->vpic.contrast, qc->vpic.hue, qc->vpic.colour); + } else { + if (qc->sensor_data.sensor->set_target!=NULL) + qc->sensor_data.sensor->set_target(qc, qc->vpic.brightness); + } + } + + if (qc->settings.adaptive && !qc->sensor_data.sensor->autoexposure && r>=0 && midvalue>=0) { + int ex, gn; + qc_adapt(qc, midvalue, qc->vpic.brightness>>8, &ex, &gn); + qc->sensor_data.sensor->set_levels(qc, ex, gn, qc->vpic.hue, qc->vpic.colour); + } + qc_frame_free(qc); + + if (qc_adapt_hassettled(qc) || settlecount<=0) break; + settlecount--; + +error: if (r < 0) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("retrying failed qc_frame_get... rounds=%i", retrycount); + if (r==-ERESTARTSYS || retrycount<=0) break; + retrycount--; + } + qc_i2c_flush(qc); /* Send all pending I2C transfers */ + schedule(); + } while (TRUE); + if (r<0) goto fail; + qc_i2c_flush(qc); /* Send all pending I2C transfers */ + cd->settled = TRUE; + if (frame) *frame = cd->frame; + return r; + +fail: if (qcdebug&(QC_DEBUGERRORS|QC_DEBUGLOGIC)) PDEBUG("failed qc_capt_get()=%i", r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_capt_frameaddr(struct quickcam *qc, unsigned char **frame) */ +/* Return size and address of the capture buffer that is suitable for mmapping, + * Standard Linux errno on error */ +static inline int qc_capt_frameaddr(struct quickcam *qc, unsigned char **frame) +{ + IDEBUG_TEST(qc->capt_data); + if (frame!=NULL) *frame = qc->capt_data.frame; + return MAX_FRAME_SIZE; +} +/* }}} */ +/* {{{ [fold] qc_capt_test(struct quickcam *qc) */ +/* Return TRUE if next image is immediately available, FALSE otherwise. + * Also starts streaming video from camera if not already done so. + * Before calling this function, qc_isoc_init() must be called first. */ +static inline Bool qc_capt_test(struct quickcam *qc) +{ + int e; + IDEBUG_TEST(qc->capt_data); + e = qc_isoc_start(qc); + if (qcdebug&QC_DEBUGERRORS && e<0) PDEBUG("qc_capt_test: qc_isoc_start failed"); + return qc_frame_test(qc); +} +/* }}} */ +/* {{{ [fold] qc_capt_init(struct quickcam *qc) */ +static int qc_capt_init(struct quickcam *qc) +{ + struct qc_capt_data *cd = &qc->capt_data; + int r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_capt_init(quickcam=%p)",qc); + + cd->settled = !(qc->settings.settle>0 && qc->settings.adaptive); + + /* Allocate memory for the (mmappable) capture buffer */ + cd->frame = qc_mm_rvmalloc(MAX_FRAME_SIZE); + if (!cd->frame) { + PRINTK(KERN_ERR, "unable to allocate frame"); + r = -ENOMEM; + goto fail1; + } + + /* Initialize submodules */ + if ((r=qc_frame_init(qc))<0) goto fail2; /* Must be before sensor_init() */ + r = qc_sensor_init(qc); /* Start the sensor (must be after qc_i2c_init but before qc_adapt_init) */ + if (r<0 && qc->settings.compress) { + /* Sensor init failed with compression. Try again without compression */ + PRINTK(KERN_NOTICE, "sensor init failed, disabling compression"); + qc->settings.compress = 0; + r = qc_sensor_init(qc); + } + if (r<0) goto fail3; + if ((r=qc_stream_init(qc))<0) goto fail3; + if ((r=qc_fmt_init(qc))<0) goto fail4; + if ((r=qc_isoc_init(qc))<0) goto fail5; + IDEBUG_INIT(*cd); + return 0; + +fail5: qc_fmt_exit(qc); +fail4: qc_stream_exit(qc); +fail3: qc_frame_exit(qc); +fail2: qc_mm_rvfree(cd->frame, MAX_FRAME_SIZE); +fail1: PDEBUG("failed qc_capt_init()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_capt_exit(struct quickcam *qc) */ +static void qc_capt_exit(struct quickcam *qc) +{ + struct qc_capt_data *cd = &qc->capt_data; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_capt_exit(quickcam=%p)",qc); + qc_isoc_exit(qc); + qc_fmt_exit(qc); + qc_stream_exit(qc); + qc_frame_exit(qc); + qc_mm_rvfree(cd->frame, MAX_FRAME_SIZE); + POISON(cd->frame); + IDEBUG_EXIT(*cd); +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc_v4l: Start of Video 4 Linux API ************************ */ + +/* {{{ [fold] qc_v4l_poll(struct video_device *dev, struct file *file, poll_table *wait) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static unsigned int qc_v4l_poll(struct file *file, poll_table *wait) +#else +static unsigned int qc_v4l_poll(struct video_device *dev, struct file *file, poll_table *wait) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); +#endif + struct quickcam *qc = (struct quickcam *)dev->priv; + struct qc_frame_data *fd = &qc->frame_data; + int mask; + + if (qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_poll(dev=%p,file=%p,wait=%p)",dev,file,wait); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + poll_wait(file, &fd->wq, wait); + mask = qc_capt_test(qc) ? (POLLIN | POLLRDNORM) : 0; + up(&qc->lock); + return mask; +} +/* }}} */ +/* {{{ [fold] qc_v4l_init(struct quickcam *qc) */ +/* Called when the device is opened */ +static int qc_v4l_init(struct quickcam *qc) +{ + int r, fps; + + if (!qc->settings.keepsettings) { + /* Reset brightness settings */ + qc->vpic.brightness = 32768; + qc->vpic.hue = 32768; + qc->vpic.colour = 32768; + qc->vpic.contrast = 32768; + qc->vpic.whiteness = 32768; + qc_adapt_reset(qc); /* qc_adapt_init() is called from qc_usb_init() */ + } + qc->vpic.palette = VIDEO_PALETTE_RGB24; + qc->vpic.depth = qc_fmt_getdepth(qc->vpic.palette); + qc->vpic_pending = FALSE; + + fps = qc->settings.subsample ? 30 : 8; /* May actually vary depending on image size */ + fps = qc->settings.compress ? 15 : fps; /* Actually 7.5 fps, but we must round it */ + qc->vwin.flags = fps << 16; /* Bits 22..16 contain framerate in Philips driver. We do the same. */ + + if ((r = qc_capt_init(qc))<0) goto fail; + return 0; + +fail: if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_v4l_init()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_v4l_open(struct video_device *dev, int flags) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_open(struct inode *inode, struct file *file) +#else +static int qc_v4l_open(struct video_device *dev, int flags) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); +#endif + struct quickcam *qc = dev->priv; + int r; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_open(qc=%p)", qc); +//PDEBUG("sleeping 10 sec..."); +//qc_usleep(1000000*10); +//PDEBUG("sleep done"); + // FIXME: if the module is tried to be unloaded at this point, + // v4l_close() and MOD_DEC_USE_COUNT will never be called + // According to "Linux Device drivers" pg.70, it's ok if called before sleeping? + // 2.2 will crash, 2.4 will hang and show "quickcam 1 (deleted)" if sleeping + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_INC_USE_COUNT in qc_v4l_open() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_INC_USE_COUNT; + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(quickcam_list) in qc_v4l_open() : %i", sem_getcount(&quickcam_list_lock)); + + r = qc_lock(qc); + if (r<0) goto fail1; + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_v4l_open() : %i", qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) { + r = -ERESTARTSYS; + goto fail2; + } + if (!qc->connected) { + r = -ENODEV; + goto fail3; + } + qc->users++; + PDEBUG("open users=%i", qc->users); + if (qc->users == 1) { + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("First user, initializing"); + if ((r = qc_v4l_init(qc))<0) goto fail4; + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_open() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + up(&quickcam_list_lock); + return 0; + +fail4: qc->users--; +fail3: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_open()=failed : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); +fail2: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_v4l_open()=failed : %i", sem_getcount(&qc->lock)); + up(&quickcam_list_lock); +fail1: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_v4l_open() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_v4l_open()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_v4l_exit(struct quickcam *qc) */ +/* Release all resources allocated at qc_v4l_init() */ +static inline void qc_v4l_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_v4l_cleanup(%p)", qc); + qc_capt_exit(qc); +} +/* }}} */ +/* {{{ [fold] qc_v4l_close(struct video_device *dev) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_close(struct inode *inode, struct file *file) +#else +static void qc_v4l_close(struct video_device *dev) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); +#endif + struct quickcam *qc = (struct quickcam *)dev->priv; + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_close(dev=%p,qc=%p)",dev,qc); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + TEST_BUGR_MSG(qc==NULL, "qc==NULL"); +#else + TEST_BUG_MSG(qc==NULL, "qc==NULL"); +#endif + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(quickcam_list) in qc_v4l_close() : %i", sem_getcount(&quickcam_list_lock)); + down(&quickcam_list_lock); /* Can not interrupt, we must success */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_v4l_close() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); /* Can not interrupt, we must success */ + qc->users--; + PDEBUG("close users=%i", qc->users); + if (qc->users == 0) { + /* No more users, device is deallocated */ + qc_v4l_exit(qc); + if (qc->dev == NULL) { /* Test qc->dev instead of qc->connected because disconnection routine sets the latter before locking camera */ + /* Camera was unplugged and freeing was postponed: free resources now here */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Performing postponed free"); + qc_usb_exit(qc); + qc = NULL; + } + } + if (qc) { + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_close() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_v4l_close() : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_v4l_close() : %i", GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("v4l_close() ok"); +#if LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,0) + return 0; +#endif +} +/* }}} */ +/* {{{ [fold] qc_v4l_read(struct video_device *dev, char *buf, unsigned long count, int noblock) */ +static ssize_t qc_v4l_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); + int noblock = file->f_flags & O_NONBLOCK; +#endif + struct quickcam *qc = (struct quickcam *)dev->priv; + int frame_len; + unsigned char *frame; + long r = 0; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) + PDEBUG("qc_v4l_read(dev=%p,buf=%p,count=%li,noblock=%i,qc=%p)",dev,buf,(long)count,noblock,qc); + if (!qc || !buf) { + PDEBUG("qc_read: no video_device available or no buffer attached :( EFAULT"); + return -EFAULT; + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_v4l_read() : %i", qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + if (!qc->connected) { + r = -ENODEV; + goto fail; + } + if (noblock && !qc_capt_test(qc)) { + r = -EAGAIN; + goto fail; + } + frame_len = qc_capt_get(qc, &frame); + if (frame_len < 0) { + r = frame_len; + goto fail; + } + if (count > frame_len) count = frame_len; + if (copy_to_user(buf, frame, count)) { + r = -EFAULT; + goto fail; + } + r = count; + +fail: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_read() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) if (r<0) PDEBUG("failed qc_v4l_read()=%i", (int)r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_v4l_mmap(struct vm_area_struct *vma, struct video_device *dev, const char *adr, unsigned long size) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_mmap(struct file *file, struct vm_area_struct *vma) +#else +static int qc_v4l_mmap( +#if HAVE_VMA + struct vm_area_struct *vma, +#endif + struct video_device *dev, const char *start, unsigned long size) +#endif /* 2.6.x */ +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); + const void *start = (void *)vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; +#endif + struct quickcam *qc = (struct quickcam *)dev->priv; + unsigned char *frame; + int ret = 0, frame_size; +#if !HAVE_VMA && LINUX_VERSION_CODElock)); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + if (!qc->connected) { ret = -ENODEV; goto fail; } + frame_size = qc_capt_frameaddr(qc, &frame); + if (frame_size<0) { ret = frame_size; goto fail; } /* Should never happen */ + ret = qc_mm_remap(vma, frame, frame_size, start, size); + +fail: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_mmap() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (ret<0) if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_v4l_mmap()=%i",ret); + return ret; +} +/* }}} */ +/* {{{ [fold] qc_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *arg) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_v4l_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +#else +static int qc_v4l_ioctl(struct video_device *dev, unsigned int cmd, void *argp) +#endif +{ + static const Bool ignore_channel = TRUE; /* RealProducer is reported to fail if driver doesn't accept channel change */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct video_device *dev = video_devdata(file); + void *argp = (void *)arg; +#endif + struct quickcam *qc = (struct quickcam *)dev->priv; + int i, retval = 0; + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGUSER) PDEBUG("qc_v4l_ioctl(dev=%p,cmd=%u,arg=%p,qc=%p)",dev,cmd,argp,qc); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_v4l_ioctl() : %i", qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) return -ERESTARTSYS; + if (!qc->connected) { + retval = -ENODEV; + goto fail; + } + switch (cmd) { +/* {{{ [fold] VIDIOCGCAP: Capability query */ + case VIDIOCGCAP: /* Capability query */ + { + struct video_capability b; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGCAP"); + memset(&b, 0, sizeof(b)); + strcpy(b.name, "Logitech QuickCam USB"); /* Max 31 characters */ + b.type = qc->vdev.vfl_type; + b.channels = 1; + b.audios = 0; + b.maxwidth = qc->sensor_data.maxwidth; + b.maxheight = qc->sensor_data.maxheight; + if (qc->settings.compat_16x) { + b.maxwidth = (b.maxwidth /16)*16; + b.maxheight = (b.maxheight/16)*16; + } + b.minwidth = min_framewidth; + b.minheight = min_frameheight; + if (copy_to_user(argp, &b, sizeof(b))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGCHAN: Get properties of the specified channel */ + case VIDIOCGCHAN: /* Get properties of the specified channel */ + { + struct video_channel v; + if (copy_from_user(&v, argp, sizeof(v))) { + retval = -EFAULT; + break; + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGCHAN channel:%i",v.channel); + if (!ignore_channel && v.channel != 0) { + retval = -EINVAL; + break; + } + v.flags = 0; + v.tuners = 0; + v.type = VIDEO_TYPE_CAMERA; + strcpy(v.name, "Camera"); + if (copy_to_user(argp, &v, sizeof(v))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSCHAN: Select channel to capture */ + case VIDIOCSCHAN: /* Select channel to capture */ + { + if (copy_from_user(&i, argp, sizeof(i))) { + retval = -EFAULT; + break; + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSCHAN channel:%i",i); + if (!ignore_channel && i!=0) retval = -EINVAL; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGPICT: Get image properties (brightness, palette, etc.) */ + case VIDIOCGPICT: /* Get image properties */ + { + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGPICT"); + if (copy_to_user(argp, &qc->vpic, sizeof(qc->vpic))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSPICT: Set image properties */ + case VIDIOCSPICT: /* Set image properties */ + { + struct video_picture p; + if (copy_from_user(&p, argp, sizeof(p))) { + retval = -EFAULT; + break; + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSPICT depth:%d palette:%s(%i) bright=%i",p.depth,qc_fmt_getname(p.palette),p.palette,p.brightness); + + if (p.palette != 0) { /* 0 = do not change palette */ + retval = qc_fmt_issupported(p.palette); + if (retval<0) break; + qc->vpic.palette = p.palette; + qc->vpic.depth = qc_fmt_getdepth(p.palette); + if (qc->vpic.depth != p.depth) PDEBUG("warning: palette depth mismatch"); + } + qc->vpic.brightness = p.brightness; + qc->vpic.hue = p.hue; + qc->vpic.colour = p.colour; + qc->vpic.contrast = p.contrast; + qc->vpic.whiteness = p.whiteness; /* Used for sharpness */ + qc->vpic_pending = TRUE; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSWIN: Set capture area width and height */ + case VIDIOCSWIN: /* Set capture area width and height */ + { + struct video_window vw; + int fps; + if (copy_from_user(&vw, argp, sizeof(vw))) { + retval = -EFAULT; + break; + } + fps = (vw.flags>>16) & 0x3F; /* 6 bits for framerate */ + if (fps && ((qc->vwin.flags>>16)&0x3F)!=fps) { + PDEBUG("Application tries to change framerate"); + } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSWIN width:%i height:%i flags:%d clipcount:%d",vw.width,vw.height,vw.flags,vw.clipcount); + retval = qc_sensor_setsize(qc, vw.width, vw.height); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGWIN: Get current capture area */ + case VIDIOCGWIN: /* Get current capture area */ + { + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGWIN"); + if (copy_to_user(argp, &qc->vwin, sizeof(qc->vwin))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGMBUF: Get mmap buffer size and frame offsets */ + case VIDIOCGMBUF: /* Get mmap buffer size and frame offsets */ + { + struct video_mbuf vm; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGMBUF"); + memset(&vm, 0, sizeof(vm)); + vm.size = qc_capt_frameaddr(qc, NULL); + if (vm.size<0) { /* Negative value denotes error */ + retval = vm.size; + break; + } + vm.frames = 1; + vm.offsets[0] = 0; + if (qc->settings.compat_dblbuf) { + /* Really many applications are broken and don't work with a single buffer */ + vm.frames = 2; + vm.offsets[1] = 0; + } + if (copy_to_user(argp, &vm, sizeof(vm))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCMCAPTURE: Start capturing specified frame in the mmap buffer with specified size */ + case VIDIOCMCAPTURE: /* Start capturing specified frame in the mmap buffer with specified size */ + { + struct video_mmap vm; + if (copy_from_user(&vm, argp, sizeof(vm))) { + retval = -EFAULT; + break; + } + /* Bug in V4L: sometimes it's called palette, sometimes format. We'll stick with palette */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCMCAPTURE frame:%d size:%dx%d palette:%s", vm.frame, vm.width, vm.height, qc_fmt_getname(vm.format)); + if (vm.frame!=0 && !(qc->settings.compat_dblbuf)) { + PRINTK(KERN_NOTICE,"Bug detected in user program, use qcset compat=dblbuf"); + retval = -EINVAL; + break; + } + if (vm.format!=0 && qc->vpic.palette!=vm.format) { /* 0 = do not change palette */ + retval = qc_fmt_issupported(vm.format); + if (retval) { + if (qcdebug&QC_DEBUGERRORS) PDEBUG("unsupported image format"); + break; + } + qc->vpic.palette = vm.format; + qc->vpic.depth = qc_fmt_getdepth(vm.format); + } + retval = qc_sensor_setsize(qc, vm.width, vm.height); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCSYNC: Wait until specified frame in the mmap buffer has been captured */ + case VIDIOCSYNC: /* Wait until specified frame in the mmap buffer has been captured */ + { + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSYNC"); + retval = qc_capt_get(qc, NULL); + if (retval>0) retval = 0; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCGFBUF: Get currently used frame buffer parameters */ + case VIDIOCGFBUF: /* Get currently used frame buffer parameters */ + { + struct video_buffer vb; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGFBUF"); + memset(&vb, 0, sizeof(vb)); + if (copy_to_user(argp, &vb, sizeof(vb))) retval = -EFAULT; + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCKEY: Undocumented? */ + case VIDIOCKEY: /* Undocumented? */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCKEY"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCCAPTURE: Activate overlay capturing directly to framebuffer */ + case VIDIOCCAPTURE: /* Activate overlay capturing directly to framebuffer */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCCAPTURE"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCSFBUF: Set frame buffer parameters for the capture card */ + case VIDIOCSFBUF: /* Set frame buffer parameters for the capture card */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSFBUF"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCxTUNER: Get properties of the specified tuner / Select tuner to use */ + case VIDIOCGTUNER: /* Get properties of the specified tuner */ + case VIDIOCSTUNER: /* Select tuner to use */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxTUNER"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCxFREQ: Get current tuner frequency / Set tuner frequency */ + case VIDIOCGFREQ: /* Get current tuner frequency */ + case VIDIOCSFREQ: /* Set tuner frequency */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxFREQ"); + retval = -EINVAL; + break; +/* }}} */ +/* {{{ [fold] VIDIOCxAUDIO: Get/Set audio properties */ + case VIDIOCGAUDIO: /* Get audio properties */ + case VIDIOCSAUDIO: /* Set audio properties */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxAUDIO"); + retval = -EINVAL; + break; +/* }}} */ + /********** Private IOCTLs ***********/ +/* {{{ [fold] VIDIOCQCxDEBUG: Sets/gets the qcdebug output (1,2,4,8,16,32) */ + case VIDIOCQCSDEBUG: /* Sets the qcdebug output (1,2,4,8,16,32) */ + if (get_user(qcdebug, (int *)argp)) { retval=-EFAULT; break; } + case VIDIOCQCGDEBUG: /* Gets the qcdebug output (1,2,4,8,16,32) */ + if (put_user(qcdebug, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxDEBUG"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxKEEPSETTINGS: Set/get keep gain settings across one open to another (0-1) */ + case VIDIOCQCSKEEPSETTINGS: /* Set keep gain settings across one open to another (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.keepsettings = i; + case VIDIOCQCGKEEPSETTINGS: /* Get keep gain settings across one open to another (0-1) */ + i = qc->settings.keepsettings; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxKEEPSETTINGS"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxSETTLE: Set/get if we let image brightness to settle (0-1) */ + case VIDIOCQCSSETTLE: /* Set if we let image brightness to settle (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.settle = i; + case VIDIOCQCGSETTLE: /* Get if we let image brightness to settle (0-1) */ + i = qc->settings.settle; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxSETTLE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxSUBSAMPLE: Sets/gets the speed (0-1) */ + case VIDIOCQCSSUBSAMPLE: /* Sets the speed (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.subsample = i; + case VIDIOCQCGSUBSAMPLE: /* Gets the speed (0-1) */ + i = qc->settings.subsample; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxSUBSAMPLE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxCOMPRESS: Sets/gets the compression mode (0-1) */ + case VIDIOCQCSCOMPRESS: /* Sets the compression mode (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.compress = i; + case VIDIOCQCGCOMPRESS: /* Gets the compression mode (0-1) */ + i = qc->settings.compress; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxCOMPRESS"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxFRAMESKIP: Set/get frame capture frequency (0-10) */ + case VIDIOCQCSFRAMESKIP: /* Set frame capture frequency (0-10) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.frameskip = i; + case VIDIOCQCGFRAMESKIP: /* Get frame capture frequency (0-10) */ + i = qc->settings.frameskip; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxFRAMESKIP"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxQUALITY: Sets/gets the interpolation mode (0-2) */ + case VIDIOCQCSQUALITY: /* Sets the interpolation mode (0-5) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.quality = i; + case VIDIOCQCGQUALITY: /* Gets the interpolation mode (0-5) */ + i = qc->settings.quality; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxQUALITY"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxADAPTIVE: Set/get automatic adaptive brightness control (0-1) */ + case VIDIOCQCSADAPTIVE: /* Set automatic adaptive brightness control (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.adaptive = i; + case VIDIOCQCGADAPTIVE: /* Get automatic adaptive brightness control (0-1) */ + i = qc->settings.adaptive; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxADAPTIVE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxEQUALIZE: Set/get equalize image (0-1) */ + case VIDIOCQCSEQUALIZE: /* Set equalize image (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.equalize = i; + case VIDIOCQCGEQUALIZE: /* Get equalize image (0-1) */ + i = qc->settings.equalize; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxEQUALIZE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxUSERLUT: Set/get user-specified lookup-table */ + case VIDIOCQCSUSERLUT: /* Set user-specified lookup-table [struct qc_userlut] */ + { + unsigned int flags; + retval = -EFAULT; + if (get_user(flags, &(((struct qc_userlut*)argp)->flags))) break; + if (flags & QC_USERLUT_DEFAULT) { + userlut = ((flags & QC_USERLUT_ENABLE) != 0); + } else { + qc->settings.userlut = ((flags & QC_USERLUT_ENABLE) != 0); + } + if (flags & QC_USERLUT_VALUES) { + for (i=0; ilut[i]))) break; + if (flags & QC_USERLUT_DEFAULT) { + userlut_contents[i] = p; + } else { + qc->fmt_data.userlut[i] = p; + } + } + if (i < QC_LUT_SIZE) break; + } + retval = 0; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSUSERLUT"); + break; + } + case VIDIOCQCGUSERLUT: /* Get user-specified lookup-table [struct qc_userlut] */ + { + unsigned int flags; + retval = -EFAULT; + if (get_user(flags, &(((struct qc_userlut*)argp)->flags))) break; + flags &= (~QC_USERLUT_ENABLE); + if ((flags & QC_USERLUT_DEFAULT) ? userlut : qc->settings.userlut) flags |= QC_USERLUT_ENABLE; + if (put_user(flags, &(((struct qc_userlut*)argp)->flags))) break; + if (flags & QC_USERLUT_VALUES) { + for (i=0; ifmt_data.userlut[i]; + } + if (put_user(p, &(((struct qc_userlut*)argp)->lut[i]))) break; + } + if (i < QC_LUT_SIZE) break; + } + retval = 0; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGUSERLUT"); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCQCxRETRYERRORS: Set/get if we retry when error happen in capture (0-1) */ + case VIDIOCQCSRETRYERRORS: /* Set if we retry when error happen in capture (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.retryerrors = i; + case VIDIOCQCGRETRYERRORS: /* Get if we retry when error happen in capture (0-1) */ + i = qc->settings.retryerrors; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxRETRYERRORS"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxCOMPATIBLE: Set enable workaround for Xawtv/Motv bugs (0-1) */ + case VIDIOCQCSCOMPATIBLE: /* Set enable workaround for Xawtv/Motv bugs (0-1) */ + if (get_user(i, (int *)argp)) { retval=-EFAULT; break; } + qc->settings.compat_16x = (i & QC_COMPAT_16X) != 0; + qc->settings.compat_dblbuf = (i & QC_COMPAT_DBLBUF) != 0; + qc->settings.compat_torgb = (i & QC_COMPAT_TORGB) != 0; + case VIDIOCQCGCOMPATIBLE: /* Get enable workaround for Xawtv/Motv bugs (0-1) */ + i = ~(qc->settings.compat_16x -1) & QC_COMPAT_16X; + i |= ~(qc->settings.compat_dblbuf-1) & QC_COMPAT_DBLBUF; + i |= ~(qc->settings.compat_torgb -1) & QC_COMPAT_TORGB; + if (put_user(i, (int *)argp)) { retval=-EFAULT; break; } + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCxCOMPATIBLE"); + break; +/* }}} */ +/* {{{ [fold] VIDIOCQCxVIDEONR: Set videodevice number (/dev/videoX) */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,5) + case VIDIOCQCSVIDEONR: /* Set videodevice number (/dev/videoX) */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCSVIDEONR"); + retval = -EINVAL; /* Can not set after the module is loaded */ + break; + case VIDIOCQCGVIDEONR: /* Get videodevice number (/dev/videoX) */ + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCGVIDEONR"); + if (put_user(video_nr, (int *)argp)) { retval=-EFAULT; break; } + break; +#endif +/* }}} */ +/* {{{ [fold] VIDIOCQCxSTV: Read/write STV chip register value */ + /* Encoding: bits 31..16 of the int argument contain register value, 15..0 the reg number */ + case VIDIOCQCGSTV: /* Read STV chip register value */ + { + int reg, val; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCGSTV"); + if (get_user(reg, (int *)argp)) { retval=-EFAULT; break; } + reg &= 0xFFFF; + val = qc_stv_get(qc, reg); + if (val<0) { retval=val; break; } + val = (val<<16) | reg; + if (put_user(val, (int *)argp)) { retval=-EFAULT; break; } + break; + } + case VIDIOCQCSSTV: /* Write STV chip register value */ + { + int regval; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCSSTV"); + if (!capable(CAP_SYS_RAWIO)) { retval=-EPERM; break; } + if (get_user(regval, (int *)argp)) { retval=-EFAULT; break; } + retval = qc_stv_set(qc, regval & 0xFFFF, regval >> 16); + break; + } +/* }}} */ +/* {{{ [fold] VIDIOCQCxI2C: Read/write sensor chip register value via I2C */ + case VIDIOCQCGI2C: /* Read sensor chip register value via I2C */ + { + int reg, val; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCGI2C"); + if (get_user(reg, (int *)argp)) { retval=-EFAULT; break; } + reg &= 0xFFFF; + val = qc_get_i2c(qc, qc->sensor_data.sensor, reg); + if (val<0) { retval=val; break; } + val = (val<<16) | reg; + if (put_user(val, (int *)argp)) { retval=-EFAULT; break; } + break; + } + case VIDIOCQCSI2C: /* Write sensor chip register value via I2C */ + { + int regval; + if (qcdebug&QC_DEBUGUSER) PDEBUG("VIDIOCQCSI2C"); + if (!capable(CAP_SYS_RAWIO)) { retval=-EPERM; break; } + if (get_user(regval, (int *)argp)) { retval=-EFAULT; break; } + retval = qc_i2c_set(qc, regval & 0xFFFF, regval >> 16); + if (retval<0) break; + retval = qc_i2c_wait(qc); + break; + } +/* }}} */ + default: + if (qcdebug&QC_DEBUGUSER) PDEBUG("Unknown IOCTL %08X",cmd); + retval = -ENOIOCTLCMD; + break; + } +fail: if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_v4l_ioctl() : %i", qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (retval<0) if (qcdebug&(QC_DEBUGLOGIC|QC_DEBUGUSER|QC_DEBUGERRORS)) PDEBUG("failed qc_v4l_ioctl()=%i",retval); + return retval; +} +/* }}} */ +/* {{{ [fold] qc_v4l_write(struct video_device *dev, const char *buf, unsigned long count, int noblock) */ +#if LINUX_VERSION_CODE= KERNEL_VERSION(2,6,0) +static void qc_v4l_release(struct video_device *vfd) { } +static struct file_operations qc_v4l_fops = { + owner: THIS_MODULE, + open: qc_v4l_open, + release: qc_v4l_close, + read: qc_v4l_read, +// write: qc_v4l_write, + ioctl: qc_v4l_ioctl, + mmap: qc_v4l_mmap, + poll: qc_v4l_poll, +}; +#endif + +static struct video_device qc_v4l_template = { + name: "QuickCam USB", + minor: -1, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + release: qc_v4l_release, + fops: &qc_v4l_fops, +#else + initialize: NULL, + open: qc_v4l_open, + close: qc_v4l_close, + read: qc_v4l_read, + write: qc_v4l_write, + ioctl: qc_v4l_ioctl, + mmap: qc_v4l_mmap, + poll: qc_v4l_poll, +#endif +}; +/* }}} */ +/* {{{ [fold] **** qc_usb: Start of USB API ********************************** */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id); +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static void *qc_usb_probe(struct usb_device *dev, unsigned int iface, const struct usb_device_id *id); +#else +static void *qc_usb_probe(struct usb_device *dev, unsigned int iface); +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static void qc_usb_disconnect(struct usb_interface *intf); +#else +static void qc_usb_disconnect(struct usb_device *dev, void *ptr); +#endif + +static struct usb_driver qc_usb_driver = { + name: qc_name, + probe: qc_usb_probe, + disconnect: qc_usb_disconnect, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) \ + && LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,15) + owner: THIS_MODULE, +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) + id_table: qc_device_table, +#endif +}; + +/* {{{ [fold] qc_usb_init(struct usb_device *dev, unsigned int ifacenum) */ +/* Detect sensor, initialize the quickcam structure, register V4L device, create /proc entry. + * Return pointer to the allocated quickcam structure or NULL on error. + * If there is some camera already open but disconnected, reuse the quickcam structure. */ +static struct quickcam *qc_usb_init(struct usb_device *usbdev, unsigned int ifacenum) +{ + struct quickcam *qc; + Bool reuse_qc; + int i, r = 0; + + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_usb_init(usbdev=%p)", usbdev); + if (PARANOID && usbdev==NULL) { PRINTK(KERN_CRIT,"usbdev==NULL"); return NULL; } + + /* Check if there is already a suitable quickcam struct that can be reused */ + reuse_qc = FALSE; + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(quickcam_list_lock) in qc_usb_init() : %i", sem_getcount(&quickcam_list_lock)); + if (down_interruptible(&quickcam_list_lock)) return NULL; + list_for_each_entry(qc, &quickcam_list, list) { + if (qc->dev!=NULL) continue; /* quickcam_list_lock protects this test */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down_intr(%p) in qc_usb_init() : %i",qc, sem_getcount(&qc->lock)); + if (down_interruptible(&qc->lock)) { + /* Failed to lock the camera. Move on in the list, skipping this camera */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("failed locking the camera %p in qc_usb_init() : %i",qc,sem_getcount(&qc->lock)); + continue; + } + if (qc->users<=0) { + PRINTK(KERN_NOTICE, "Unplugged unused camera detected!"); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_init() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + continue; + } + /* Found and locked unplugged but used camera */ + reuse_qc = TRUE; + break; + } + + if (reuse_qc) { + /* Reuse existing quickcam (which is already opened) */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Reusing existing quickcam"); + if (PARANOID && qc->users<=0) PRINTK(KERN_CRIT, "Unplugged JUST closed camera detected!"); + qc_isoc_stop(qc); + qc_i2c_wait(qc); + qc_frame_flush(qc); + } else { + /* Allocate and initialize some members of the new qc */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Allocating new quickcam"); + qc = kmalloc(sizeof(*qc), GFP_KERNEL); + CHECK_ERROR(qc==NULL, fail1, "couldn't kmalloc quickcam struct"); + memset(qc, 0, sizeof(*qc)); /* No garbage to user */ +PDEBUG("poisoning qc in qc_usb_init"); + POISON(*qc); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("init down(%p) in qc_usb_init()", qc); +#ifdef CONFIG_PREEMPT_RT + init_MUTEX(&qc->lock); + down(&qc->lock); +#else + init_MUTEX_LOCKED(&qc->lock); +#endif + qc->users = 0; + if ((r=qc_i2c_init(qc))<0) goto fail2; + } + qc->dev = usbdev; + qc->iface = ifacenum; + qc->connected = TRUE; + + /* Probe for the sensor type */ + qc_i2c_wait(qc); /* Necessary before set_interface() */ + if ((r=usb_set_interface(usbdev, qc->iface, 0))<0) goto fail3; /* Set altsetting 0 */ + if ((r=qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) goto fail3; /* Disable isochronous stream */ + for (i=0; iid_reg))<0) goto fail3; + r = (r >> (sensors[i]->length_id-1) * 8) & 0xFF; /* Get MSB of received value */ + if (qcdebug&QC_DEBUGCAMERA) PDEBUG("Probing %s: expecting %02X, got %02X", sensors[i]->name, sensors[i]->id, r); + if (r == sensors[i]->id) break; + } + if (i>=SIZE(sensors)) { + PRINTK(KERN_INFO,"unsupported sensor"); + goto fail3; + } + qc->sensor_data.sensor = sensors[i]; + PRINTK(KERN_INFO,"Sensor %s detected", sensors[i]->name); + + if ((r=qc_stv_set(qc, STV_ISO_ENABLE, 0))<0) goto fail3; /* Disable isochronous streaming */ + if ((r=qc_stv_set(qc, STV_REG23, 1))<0) goto fail3; + + if (!reuse_qc) { + /* Set default settings */ + qc->vpic.brightness = 32768; + qc->vpic.hue = 32768; + qc->vpic.colour = 32768; + qc->vpic.contrast = 32768; + qc->vpic.whiteness = 32768; /* Used for sharpness at quality=5 */ + qc->settings.keepsettings = keepsettings; + qc->settings.settle = settle; + qc->settings.subsample = subsample; + qc->settings.compress = compress; + qc->settings.frameskip = frameskip; + qc->settings.quality = quality; + qc->settings.adaptive = adaptive; + qc->settings.equalize = equalize; + qc->settings.userlut = userlut; + qc->settings.retryerrors = retryerrors; + qc->settings.compat_16x = compatible & QC_COMPAT_16X ? 1 : 0; + qc->settings.compat_dblbuf = compatible & QC_COMPAT_DBLBUF ? 1 : 0; + qc->settings.compat_torgb = compatible & QC_COMPAT_TORGB ? 1 : 0; + memcpy(&qc->fmt_data.userlut, userlut_contents, sizeof(qc->fmt_data.userlut)); + + /* Register V4L video device */ + memcpy(&qc->vdev, &qc_v4l_template, sizeof(qc_v4l_template)); + qc->vdev.priv = qc; + r = video_register_device(&qc->vdev, VFL_TYPE_GRABBER, video_nr); + if (r<0) goto fail3; + PRINTK(KERN_INFO, "Registered device: /dev/video%i", qc->vdev.minor); + if ((r=qc_adapt_init(qc))<0) goto fail4; + qc_proc_create(qc); /* Create /proc entry, ignore if it fails */ + list_add(&qc->list, &quickcam_list); + } + + if (reuse_qc && qc->frame_data.waiting>0) { + /* Restart capturing */ + int width = qc->vwin.width; + int height = qc->vwin.height; +//qc_usleep(1000000); + qc_isoc_stop(qc); + r = qc_sensor_init(qc); + r = qc_isoc_start(qc); + r = qc_sensor_setsize(qc, width, height); + /* Ignore return codes for now, if it fails, too bad, but shouldn't crash */ + /* FIXME: proper error handling */ + +/*qc_usleep(1000000); + qc_sensor_setsize(qc, width, height); +qc_usleep(1000000); + qc_sensor_setsize(qc, 32, 32); +qc_usleep(1000000); + qc_sensor_setsize(qc, width, height); +qc_usleep(1000000);*/ + +#if 0 +/* The following tries to initialize VV6410 really hard. still doesn't work */ +{ +int r,c; +for(c=0;c<10;c++) { +//r = qc_sensor_init(qc); +//PDEBUG("c=%i init=%i",c,r); +//r = qc_sensor_setsize(qc, width, height); +//PDEBUG("size=%i",r); +//r = usb_set_interface(qc->dev, qc->iface, 1); +//PDEBUG("set_interf=%i",r); +//r = qc->sensor_data.sensor->start(qc); /* Start current frame */ +//PDEBUG("start=%i",r); +//r = qc_stv_set(qc, STV_ISO_ENABLE, 1); +//PDEBUG("stv_set=%i",r); +//qc_isoc_stop(qc); +//qc_usleep(1000000); +//qc_isoc_start(qc); +//qc_usleep(1000000); +}} +#endif + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_init() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_usb_init() : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + return qc; + +fail4: video_unregister_device(&qc->vdev); +fail3: if (!reuse_qc) qc_i2c_exit(qc); + qc->dev = NULL; + qc->connected = FALSE; + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_init()=failed : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); +fail2: if (!reuse_qc) kfree(qc); +fail1: if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_usb_init()=%i",r); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_usb_init()=failed : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + return NULL; +} +/* }}} */ +/* FIXME: can usb_disconnect and usb_probe pre-empt other kernel mode processes? Assume no */ +/* {{{ [fold] qc_usb_probe(...) */ +/* Called when any USB device is connected, check if it is a supported camera */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static int qc_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) +static void *qc_usb_probe(struct usb_device *usbdev, unsigned int ifacenum, const struct usb_device_id *id) +#else /* 2.2.x */ +static void *qc_usb_probe(struct usb_device *usbdev, unsigned int ifacenum) +#endif +{ + struct quickcam *qc; + struct usb_interface_descriptor *ifacedesc; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + unsigned int ifacenum; + struct usb_device *usbdev = interface_to_usbdev(interface); + static const int ERROR_CODE = -ENODEV; +#else + static void * const ERROR_CODE = NULL; +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) + /* Check if the device has a product number that we support */ + struct usb_device_id *i; + for (i=qc_device_table; i->idVendor; i++) { + if (usbdev->descriptor.idVendor == i->idVendor && + usbdev->descriptor.idProduct == i->idProduct) break; + } + if (!i->idVendor) return ERROR_CODE; +#endif + if (PARANOID && usbdev==NULL) { PRINTK(KERN_CRIT,"usbdev==NULL"); return ERROR_CODE; } + + /* We don't handle multi-config cameras */ + if (usbdev->descriptor.bNumConfigurations != 1) return ERROR_CODE; + + /* + * Checking vendor/product is not enough + * In case on QuickCam Web the audio is at class 1 and subclass 1/2. + * one /dev/dsp and one /dev/mixer + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + ifacedesc = &interface->altsetting[0].desc; + ifacenum = ifacedesc->bInterfaceNumber; +#else + ifacedesc = &usbdev->actconfig->interface[ifacenum].altsetting[0]; +#endif + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_usb_probe(usbdev=%p,ifacenum=%i)", usbdev, ifacenum); + if (PARANOID && ifacedesc->bInterfaceNumber!=ifacenum) PRINTK(KERN_CRIT,"bInterfaceNumber(%i)!=ifacenum(%i)!!",ifacedesc->bInterfaceNumber,ifacenum); + if (ifacedesc->bInterfaceClass != 0xFF) return ERROR_CODE; + if (ifacedesc->bInterfaceSubClass != 0xFF) return ERROR_CODE; + + /* We found a QuickCam */ + PRINTK(KERN_INFO,"QuickCam USB camera found (driver version %s)", VERSION); + PRINTK(KERN_INFO,"Kernel:%s bus:%i class:%02X subclass:%02X vendor:%04X product:%04X", + UTS_RELEASE, usbdev->bus->busnum, ifacedesc->bInterfaceClass, ifacedesc->bInterfaceSubClass, + usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); + + /* The interface is claimed (bound) automatically to us when we return from this function (without error code) */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_INC_USE_COUNT in qc_usb_probe() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_INC_USE_COUNT; /* Increase count to 1, which locks the module--it can't be removed */ + qc = qc_usb_init(usbdev, ifacenum); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_usb_probe() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; /* Release lock: module can be now removed again */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + if (!qc) return ERROR_CODE; + usb_set_intfdata(interface, qc); /* FIXME: why? */ + return 0; +#else + return qc; +#endif +} +/* }}} */ +/* {{{ [fold] qc_usb_exit(struct quickcam *qc) */ +/* Free up resources allocated in qc_usb_init() when not needed anymore + * Note: quickcam_list_lock and qc->lock must be acquired before entering this function! + * qc may not be accessed after this function returns! + */ +static void qc_usb_exit(struct quickcam *qc) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_usb_exit(qc=%p)",qc); + TEST_BUG_MSG(qc==NULL, "qc==NULL"); + + qc_proc_destroy(qc); + qc_adapt_exit(qc); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("video_unregister_device(%p)", &qc->vdev); + video_unregister_device(&qc->vdev); + qc_i2c_exit(qc); + list_del(&qc->list); +PDEBUG("poisoning qc in qc_usb_exit"); + POISON(*qc); + kfree(qc); + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("qc_usb_exit() done"); +} +/* }}} */ +/* {{{ [fold] qc_usb_disconnect(...) */ +/* Called when the camera is disconnected. We might not free struct quickcam here, + * because the camera might be in use (open() called). In that case, the freeing is + * postponed to the last close() call. However, all submitted URBs must be unlinked. + */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +static void qc_usb_disconnect(struct usb_interface *interface) +#else +static void qc_usb_disconnect(struct usb_device *usbdev, void *ptr) +#endif +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + struct quickcam *qc = usb_get_intfdata(interface); +#ifdef DEBUG + struct usb_device *usbdev = interface_to_usbdev(interface); +#endif +#else + struct quickcam *qc = (struct quickcam *)ptr; +#endif + + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGCAMERA) PDEBUG("qc_usb_disconnect(qc=%p)",qc); + TEST_BUG_MSG(qc==NULL, "qc==NULL in qc_usb_disconnect!"); + TEST_BUG_MSG(qc->dev==NULL || qc->connected==FALSE, "disconnecting disconnected device!!"); + TEST_BUG_MSG(usbdev!=qc->dev, "disconnecting not our device!!"); + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_INC_USE_COUNT in qc_usb_disconnect() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_INC_USE_COUNT; /* Increase count to 1, which locks the module--it can't be removed */ + + /* + * When the camera is unplugged (maybe even when it is capturing), quickcam->connected is set to FALSE. + * All functions called from user mode and all _exit functions must check for this. + */ + qc->connected = FALSE; + + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(quickcam_list) in qc_usb_disconnect() : %i", sem_getcount(&quickcam_list_lock)); + down(&quickcam_list_lock); /* Also avoids race condition with open() */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("down(%p) in qc_usb_disconnect() : %i", qc, sem_getcount(&qc->lock)); + down(&qc->lock); /* Can not interrupt, we must success */ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) + usb_set_intfdata(interface, NULL); /* FIXME: why? */ +#endif + if (qc->users <= 0) { + /* Free resources */ + qc_usb_exit(qc); + } else { + /* Can not free resources if device is open: postpone to when it is closed */ + if (qcdebug&QC_DEBUGLOGIC) PDEBUG("Disconnect while device open: postponing cleanup"); + qc_isoc_stop(qc); /* Unlink and free isochronous URBs */ + qc_i2c_wait(qc); /* Wait until there are no more I2C packets on way */ + qc->dev = NULL; /* Must be set to NULL only after interrupts are guaranteed to be disabled! */ + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(%p) in qc_usb_disconnect() : %i",qc, sem_getcount(&qc->lock)); + up(&qc->lock); + } + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("up(quickcam_list) in qc_usb_disconnect() : %i", sem_getcount(&quickcam_list_lock)); + up(&quickcam_list_lock); + if (qcdebug&QC_DEBUGMUTEX) PDEBUG("MOD_DEC_USE_COUNT in qc_usb_disconnect() : %i",GET_USE_COUNT(THIS_MODULE)); + MOD_DEC_USE_COUNT; /* Release lock--if device is not open, module can be now freed */ + /* The interface is released automatically when we return from this function */ +} +/* }}} */ + +/* }}} */ +/* {{{ [fold] **** qc: Start of module API ******************************* */ + +/* {{{ [fold] qc_init(void) */ +static int __init qc_init(void) +{ + int r; + if (qcdebug) PDEBUG("----------LOADING QUICKCAM MODULE------------"); + if (qcdebug) PDEBUG("struct quickcam size: %i", (int)sizeof(struct quickcam)); + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_init()"); + qc_proc_init(); /* Ignore if procfs entry creation fails */ + r = usb_register(&qc_usb_driver); + if (r<0) qc_proc_exit(); + if (r<0) if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGERRORS) PDEBUG("failed qc_init()=%i",r); + return r; +} +/* }}} */ +/* {{{ [fold] qc_exit(void) */ +static void __exit qc_exit(void) +{ + if (qcdebug&QC_DEBUGLOGIC || qcdebug&QC_DEBUGINIT) PDEBUG("qc_exit()"); + usb_deregister(&qc_usb_driver); /* Will also call qc_usb_disconnect() if necessary */ + qc_proc_exit(); +} +/* }}} */ + +module_init(qc_init); +module_exit(qc_exit); +/* }}} */ + +/* End of file */ --- linux-2.6.28.orig/ubuntu/qc-usb/BOM +++ linux-2.6.28/ubuntu/qc-usb/BOM @@ -0,0 +1,4 @@ +Downloaded from: http://sourceforge.net/project/showfiles.php?group_id=12924 +Current Version: 0.6.6 + +Took a bit of forward porting. Upstream project seems dead anyway. --- linux-2.6.28.orig/ubuntu/dm-loop/dm-loop.c +++ linux-2.6.28/ubuntu/dm-loop/dm-loop.c @@ -0,0 +1,1036 @@ +/* + * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. + * + * This file is part of device-mapper. + * + * Extent mapping implementation heavily influenced by mm/swapfile.c + * Bryn Reeves + * + * File mapping and block lookup algorithms support by + * Heinz Mauelshagen . + * + * This file is released under the GPL. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm.h" +#include "dm-bio-list.h" + +#define DM_LOOP_DAEMON "kloopd" +#define DM_MSG_PREFIX "loop" + +enum flags { DM_LOOP_BMAP, DM_LOOP_FSIO }; + +/*-------------------------------------------------------------------- + * Loop context + *--------------------------------------------------------------------*/ + +struct loop_c { + unsigned long flags; + + /* Backing store */ + + struct file *filp; + char *path; + loff_t offset; + struct block_device *bdev; + unsigned blkbits; /* file system block size shift bits */ + + loff_t size; /* size of entire file in bytes */ + loff_t blocks; /* blocks allocated to loop file */ + sector_t mapped_sectors; /* size of mapped area in sectors */ + + int (*map_fn)(struct dm_target *, struct bio *); + void *map_data; +}; + +/* + * Block map extent + */ +struct dm_loop_extent { + sector_t start; /* start sector in mapped device */ + sector_t to; /* start sector on target device */ + sector_t len; /* length in sectors */ +}; + +/* + * Temporary extent list + */ +struct extent_list { + struct dm_loop_extent *extent; + struct list_head list; +}; + +static struct kmem_cache *dm_loop_extent_cache; + +/* + * Block map private context + */ +struct block_map_c { + int nr_extents; /* number of extents in map */ + struct dm_loop_extent **map; /* linear map of extent pointers */ + struct dm_loop_extent **mru; /* pointer to mru entry */ + spinlock_t mru_lock; /* protects mru */ +}; + +/* + * File map private context + */ +struct file_map_c { + spinlock_t lock; /* protects in */ + struct bio_list in; /* new bios for processing */ + struct bio_list work; /* bios queued for processing */ + struct workqueue_struct *wq; /* workqueue */ + struct work_struct ws; /* loop work */ + struct loop_c *loop; /* for filp & offset */ +}; + +/*-------------------------------------------------------------------- + * Generic helpers + *--------------------------------------------------------------------*/ + +static sector_t blk2sect(struct loop_c *lc, blkcnt_t block) +{ + return block << (lc->blkbits - SECTOR_SHIFT); +} + +static blkcnt_t sec2blk(struct loop_c *lc, sector_t sector) +{ + return sector >> (lc->blkbits - SECTOR_SHIFT); +} + +/*-------------------------------------------------------------------- + * File I/O helpers + *--------------------------------------------------------------------*/ + +/* + * transfer data to/from file using the read/write file_operations. + */ +static int fs_io(int rw, struct file *filp, loff_t *pos, struct bio_vec *bv) +{ + ssize_t r; + void __user *ptr = (void __user __force *) kmap(bv->bv_page) + bv->bv_offset; + mm_segment_t old_fs = get_fs(); + + set_fs(get_ds()); + r = (rw == READ) ? filp->f_op->read(filp, ptr, bv->bv_len, pos) : + filp->f_op->write(filp, ptr, bv->bv_len, pos); + set_fs(old_fs); + kunmap(bv->bv_page); + + return (r == bv->bv_len) ? 0 : -EIO; +} + +/* + * Handle I/O for one bio + */ +static void do_one_bio(struct file_map_c *fc, struct bio *bio) +{ + int r = 0, rw = bio_data_dir(bio); + loff_t start = (bio->bi_sector << 9) + fc->loop->offset, pos = start; + struct bio_vec *bv, *bv_end = bio->bi_io_vec + bio->bi_vcnt; + + for (bv = bio->bi_io_vec; bv < bv_end; bv++) { + r = fs_io(rw, fc->loop->filp, &pos, bv); + if (r) { + DMERR("%s error %d", rw ? "write" : "read", r); + break; + } + } + + bio_endio(bio, r); +} + +/* + * Worker thread for a 'file' type loop device + */ +static void do_loop_work(struct work_struct *ws) +{ + struct file_map_c *fc = container_of(ws, struct file_map_c, ws); + struct bio *bio; + + /* quickly grab all new bios queued and add them to the work list */ + spin_lock_irq(&fc->lock); + bio_list_merge(&fc->work, &fc->in); + bio_list_init(&fc->in); + spin_unlock_irq(&fc->lock); + + /* work the list and do file I/O on all bios */ + while ((bio = bio_list_pop(&fc->work))) + do_one_bio(fc, bio); +} + +/* + * Create work queue and initialize work + */ +static int loop_work_init(struct loop_c *lc) +{ + struct file_map_c *fc = lc->map_data; + + fc->wq = create_singlethread_workqueue(DM_LOOP_DAEMON); + if (!fc->wq) + return -ENOMEM; + + return 0; +} + +/* + * Destroy work queue + */ +static void loop_work_exit(struct loop_c *lc) +{ + struct file_map_c *fc = lc->map_data; + + if (fc->wq) + destroy_workqueue(fc->wq); +} + +/* + * DM_LOOP_FSIO map_fn. Mapping just queues bios to the file map + * context and lets the daemon deal with them. + */ +static int loop_file_map(struct dm_target *ti, struct bio *bio) +{ + int wake; + struct loop_c *lc = ti->private; + struct file_map_c *fc = lc->map_data; + + spin_lock_irq(&fc->lock); + wake = bio_list_empty(&fc->in); + bio_list_add(&fc->in, bio); + spin_unlock_irq(&fc->lock); + + /* + * Only call queue_work() if necessary to avoid + * superfluous preempt_{disable/enable}() overhead. + */ + if (wake) + queue_work(fc->wq, &fc->ws); + + /* Handling bio - will submit later. */ + return 0; +} + +/* + * Shutdown the workqueue and free a file mapping + */ +static void destroy_file_map(struct loop_c *lc) +{ + loop_work_exit(lc); + kfree(lc->map_data); +} + +/* + * Set up a file map context and workqueue + */ +static int setup_file_map(struct loop_c *lc) +{ + struct file_map_c *fc = kzalloc(sizeof(*fc), GFP_KERNEL); + + if (!fc) + return -ENOMEM; + + spin_lock_init(&fc->lock); + bio_list_init(&fc->in); + bio_list_init(&fc->work); + INIT_WORK(&fc->ws, do_loop_work); + fc->loop = lc; + + lc->map_data = fc; + lc->map_fn = loop_file_map; + + return loop_work_init(lc); +} + +/*-------------------------------------------------------------------- + * Block I/O helpers + *--------------------------------------------------------------------*/ + +static int contains_sector(struct dm_loop_extent *e, sector_t s) +{ + if (likely(e)) + return s < (e->start + (e->len)) && s >= e->start; + + return 0; +} + +/* + * Walk over a linked list of extent_list structures, freeing them as + * we go. Does not free el->extent. + */ +static void destroy_extent_list(struct list_head *head) +{ + struct list_head *curr, *n; + struct extent_list *el; + + if (list_empty(head)) + return; + + list_for_each_safe(curr, n, head) { + el = list_entry(curr, struct extent_list, list); + list_del(curr); + kfree(el); + } +} + +/* + * Add a new extent to the tail of the list at *head with + * start/to/len parameters. Allocates from the extent cache. + */ +static int list_add_extent(struct list_head *head, sector_t start, + sector_t to, sector_t len) +{ + struct dm_loop_extent *extent; + struct extent_list *list; + + extent = kmem_cache_alloc(dm_loop_extent_cache, GFP_KERNEL); + if (!extent) + goto out; + + list = kmalloc(sizeof(*list), GFP_KERNEL); + if (!list) + goto out; + + extent->start = start; + extent->to = to; + extent->len = len; + + list->extent = extent; + list_add_tail(&list->list, head); + + return 0; +out: + if (extent) + kmem_cache_free(dm_loop_extent_cache, extent); + return -ENOMEM; +} + +/* + * Return an extent range (i.e. beginning and ending physical block numbers). + */ +static int extent_range(struct inode *inode, + blkcnt_t logical_blk, blkcnt_t last_blk, + blkcnt_t *begin_blk, blkcnt_t *end_blk) +{ + sector_t dist = 0, phys_blk, probe_blk = logical_blk; + + /* Find beginning physical block of extent starting at logical_blk. */ + *begin_blk = phys_blk = bmap(inode, probe_blk); + if (!phys_blk) + return -ENXIO; + + for (; phys_blk == *begin_blk + dist; dist++) { + *end_blk = phys_blk; + if (++probe_blk > last_blk) + break; + + phys_blk = bmap(inode, probe_blk); + if (unlikely(!phys_blk)) + return -ENXIO; + } + + return 0; +} + +/* + * Create a sequential list of extents from an inode and return + * it in *head. On success return the number of extents found or + * -ERRNO on failure. + */ +static int loop_extents(struct loop_c *lc, struct inode *inode, + struct list_head *head) +{ + sector_t start = 0; + int r, nr_extents = 0; + blkcnt_t nr_blks = 0, begin_blk = 0, end_blk = 0; + blkcnt_t after_last_blk = sec2blk(lc, + (lc->mapped_sectors + (lc->offset >> 9))); + blkcnt_t logical_blk = sec2blk(lc, (lc->offset >> 9)); + + /* for each block in the mapped region */ + while (logical_blk < after_last_blk) { + r = extent_range(inode, logical_blk, after_last_blk - 1, + &begin_blk, &end_blk); + + /* sparse file fallback */ + if (unlikely(r)) { + DMWARN("%s has a hole; sparse file detected - " + "switching to filesystem I/O", lc->path); + clear_bit(DM_LOOP_BMAP, &lc->flags); + set_bit(DM_LOOP_FSIO, &lc->flags); + return r; + } + + nr_blks = 1 + end_blk - begin_blk; + + if (unlikely(!nr_blks)) + continue; + + r = list_add_extent(head, start, blk2sect(lc, begin_blk), + blk2sect(lc, nr_blks)); + if (unlikely(r)) + return r; + + /* advance to next extent */ + nr_extents++; + start += blk2sect(lc, nr_blks); + logical_blk += nr_blks; + } + + return nr_extents; +} + +/* + * Walk over the extents in a block_map_c, returning them to the cache and + * freeing bc->map and bc. + */ +static void destroy_block_map(struct block_map_c *bc) +{ + unsigned i; + + if (!bc) + return; + + for (i = 0; i < bc->nr_extents; i++) + kmem_cache_free(dm_loop_extent_cache, bc->map[i]); + + DMDEBUG("destroying block map of %d entries", i); + + vfree(bc->map); + kfree(bc); +} + +/* + * Find an extent in *bc using binary search. Returns a pointer into the + * extent map. Calculate index as (extent - bc->map). + */ +static struct dm_loop_extent **extent_binary_lookup(struct block_map_c *bc, + struct dm_loop_extent **extent_mru, sector_t sector) +{ + unsigned nr_extents = bc->nr_extents; + unsigned delta, dist, prev_dist = 0; + struct dm_loop_extent **eptr; + + /* Optimize lookup range based on MRU extent. */ + dist = extent_mru - bc->map; + if ((*extent_mru)->start >= sector) + delta = dist = dist / 2; + else { + delta = (nr_extents - dist) / 2; + dist += delta; + } + + eptr = bc->map + dist; + while (*eptr && !contains_sector(*eptr, sector)) { + if (sector >= (*eptr)->start + (*eptr)->len) { + prev_dist = dist; + if (delta > 1) + delta /= 2; + dist += delta; + } else { + delta = (dist - prev_dist) / 2; + if (!delta) + delta = 1; + dist -= delta; + } + eptr = bc->map + dist; + } + + return eptr; +} + +/* + * Lookup an extent for a sector using the mru cache and binary search. + */ +static struct dm_loop_extent *extent_lookup(struct block_map_c *bc, sector_t sector) +{ + struct dm_loop_extent **eptr; + + spin_lock_irq(&bc->mru_lock); + eptr = bc->mru; + spin_unlock_irq(&bc->mru_lock); + + if (contains_sector(*eptr, sector)) + return *eptr; + + eptr = extent_binary_lookup(bc, eptr, sector); + if (!eptr) + return NULL; + + spin_lock_irq(&bc->mru_lock); + bc->mru = eptr; + spin_unlock_irq(&bc->mru_lock); + + return *eptr; +} + +/* + * DM_LOOP_BMAP map_fn. Looks up the sector in the extent map and + * rewrites the bio device and bi_sector fields. + */ +static int loop_block_map(struct dm_target *ti, struct bio *bio) +{ + struct loop_c *lc = ti->private; + struct dm_loop_extent *extent = extent_lookup(lc->map_data, bio->bi_sector); + + if (likely(extent)) { + bio->bi_bdev = lc->bdev; + bio->bi_sector = extent->to + (bio->bi_sector - extent->start); + return 1; /* Done with bio -> submit */ + } + + DMERR("no matching extent in map for sector %llu", + (unsigned long long) bio->bi_sector + ti->begin); + BUG(); + + return -EIO; +} + +/* + * Turn an extent_list into a linear pointer map of nr_extents + 1 entries + * and set the final entry to NULL. + */ +static struct dm_loop_extent **build_extent_map(struct list_head *head, int nr_extents, + unsigned long *flags) +{ + unsigned map_size, cache_size; + struct dm_loop_extent **map, **curr; + struct list_head *pos; + struct extent_list *el; + + map_size = 1 + (sizeof(*map) * nr_extents); + cache_size = kmem_cache_size(dm_loop_extent_cache) * nr_extents; + + map = vmalloc(map_size); + curr = map; + + DMDEBUG("allocated extent map of %u %s for %d extents (%u %s)", + (map_size < 8192) ? map_size : map_size >> 10, + (map_size < 8192) ? "bytes" : "kilobytes", nr_extents, + (cache_size < 8192) ? cache_size : cache_size >> 10, + (cache_size < 8192) ? "bytes" : "kilobytes"); + + list_for_each(pos, head) { + el = list_entry(pos, struct extent_list, list); + *(curr++) = el->extent; + } + *curr = NULL; + + return map; +} + +/* + * Set up a block map context and extent map + */ +static int setup_block_map(struct loop_c *lc, struct inode *inode) +{ + int r, nr_extents; + struct block_map_c *bc; + LIST_HEAD(head); + + if (!inode || !inode->i_sb || !inode->i_sb->s_bdev) + return -ENXIO; + + /* build a linked list of extents in linear order */ + r = nr_extents = loop_extents(lc, inode, &head); + if (nr_extents < 1) + goto out; + + r = -ENOMEM; + bc = kzalloc(sizeof(*bc), GFP_KERNEL); + if (!bc) + goto out; + + /* create a linear map of pointers into the extent cache */ + bc->map = build_extent_map(&head, nr_extents, &lc->flags); + destroy_extent_list(&head); + + if (IS_ERR(bc->map)) { + r = PTR_ERR(bc->map); + goto out; + } + + spin_lock_init(&bc->mru_lock); + bc->mru = bc->map; + bc->nr_extents = nr_extents; + lc->bdev = inode->i_sb->s_bdev; + lc->map_data = bc; + lc->map_fn = loop_block_map; + + return 0; + +out: + return r; +} + +/*-------------------------------------------------------------------- + * Generic helpers + *--------------------------------------------------------------------*/ + +/* + * Invalidate all unlocked loop file pages + */ +static int loop_invalidate_file(struct file *filp) +{ + int r; + + /* Same as generic_file_direct_IO() */ + unmap_mapping_range(filp->f_mapping, 0, ~0UL, 0); + + r = filemap_write_and_wait(filp->f_mapping); + if (r) + return r; + + /* + * This will remove all pages except dirty ones. + * If there are dirty pages at this point, it means that the user + * is writing to the file and the coherency is lost anyway. + * If the user was writing to the file simultaneously, this + * returns non-zero, but we ignore that. + */ + invalidate_inode_pages2_range(filp->f_mapping, 0, ~0UL); + + return 0; +} + +/* + * Acquire or release a "no-truncate" lock on *filp. + * We overload the S_SWAPFILE flag for loop targets because + * it provides the same no-truncate semantics we require, and + * holding onto i_sem is no longer an option. + */ +static void file_truncate_lock(struct file *filp) +{ + struct inode *inode = filp->f_mapping->host; + + mutex_lock(&inode->i_mutex); + inode->i_flags |= S_SWAPFILE; + mutex_unlock(&inode->i_mutex); +} + +static void file_truncate_unlock(struct file *filp) +{ + struct inode *inode = filp->f_mapping->host; + + mutex_lock(&inode->i_mutex); + inode->i_flags &= ~S_SWAPFILE; + mutex_unlock(&inode->i_mutex); +} + +/* + * Fill out split_io for taget backing store + */ +static void set_split_io(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + + if (test_bit(DM_LOOP_BMAP, &lc->flags)) + /* Split I/O at block boundaries */ + ti->split_io = 1 << (lc->blkbits - SECTOR_SHIFT); + else + ti->split_io = 64; + + DMDEBUG("splitting io at %llu sector boundaries", + (unsigned long long) ti->split_io); +} + +/* + * Check that the loop file is regular and available. + */ +static int loop_check_file(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + struct file *filp = lc->filp; + struct inode *inode = filp->f_mapping->host; + + if (!inode) + return -ENXIO; + + ti->error = "backing file must be a regular file"; + if (!S_ISREG(inode->i_mode)) + return -EINVAL; + + ti->error = "backing file is mapped into userspace for writing"; + if (mapping_writably_mapped(filp->f_mapping)) + return -EBUSY; + + if (mapping_mapped(filp->f_mapping)) + DMWARN("%s is mapped into userspace", lc->path); + + if (!inode->i_sb || !inode->i_sb->s_bdev) { + DMWARN("%s has no blockdevice - switching to filesystem I/O", + lc->path); + clear_bit(DM_LOOP_BMAP, &lc->flags); + set_bit(DM_LOOP_FSIO, &lc->flags); + } + + ti->error = "backing file already in use"; + if (IS_SWAPFILE(inode)) + return -EBUSY; + + return 0; +} + +/* + * Check loop file size and store it in the loop context + */ +static int loop_setup_size(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + struct inode *inode = lc->filp->f_mapping->host; + int r = -EINVAL; + + lc->size = i_size_read(inode); + lc->blkbits = inode->i_blkbits; + + ti->error = "backing file is empty"; + if (!lc->size) + goto out; + + DMDEBUG("set backing file size to %llu", (unsigned long long) lc->size); + + ti->error = "backing file cannot be less than one block in size"; + if (lc->size < (blk2sect(lc, 1) << 9)) + goto out; + + ti->error = "loop file offset must be a multiple of fs blocksize"; + if (lc->offset & ((1 << lc->blkbits) - 1)) + goto out; + + ti->error = "loop file offset too large"; + if (lc->offset > (lc->size - (1 << 9))) + goto out; + + lc->mapped_sectors = (lc->size - lc->offset) >> 9; + DMDEBUG("set mapped sectors to %llu (%llu bytes)", + (unsigned long long) lc->mapped_sectors, + (lc->size - lc->offset)); + + if ((lc->offset + (lc->mapped_sectors << 9)) < lc->size) + DMWARN("not using %llu bytes in incomplete block at EOF", + lc->size - (lc->offset + (lc->mapped_sectors << 9))); + + ti->error = "mapped region cannot be smaller than target size"; + if (lc->size - lc->offset < (ti->len << 9)) + goto out; + + r = 0; + +out: + return r; +} + +/* + * release a loop file + */ +static void loop_put_file(struct file *filp) +{ + if (!filp) + return; + + file_truncate_unlock(filp); + filp_close(filp, NULL); +} + +/* + * Open loop file and perform type, availability and size checks. + */ +static int loop_get_file(struct dm_target *ti) +{ + int flags = ((dm_table_get_mode(ti->table) & FMODE_WRITE) ? + O_RDWR : O_RDONLY) | O_LARGEFILE; + struct loop_c *lc = ti->private; + struct file *filp; + int r = 0; + + ti->error = "could not open backing file"; + filp = filp_open(lc->path, flags, 0); + if (IS_ERR(filp)) + return PTR_ERR(filp); + lc->filp = filp; + r = loop_check_file(ti); + if (r) + goto err; + + r = loop_setup_size(ti); + if (r) + goto err; + + file_truncate_lock(filp); + return 0; + +err: + fput(filp); + return r; +} + +/* + * invalidate mapped pages belonging to the loop file + */ +static void loop_flush(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + + loop_invalidate_file(lc->filp); +} + +/*-------------------------------------------------------------------- + * Device-mapper target methods + *--------------------------------------------------------------------*/ + +/* + * Generic loop map function. Re-base I/O to target begin and submit + */ +static int loop_map(struct dm_target *ti, struct bio *bio, + union map_info *context) +{ + struct loop_c *lc = ti->private; + + if (unlikely(bio_barrier(bio))) + return -EOPNOTSUPP; + + bio->bi_sector -= ti->begin; + + if (lc->map_fn) + return lc->map_fn(ti, bio); + + return -EIO; +} + +/* + * Block status helper + */ +static ssize_t loop_file_status(struct loop_c *lc, char *result, + unsigned maxlen) +{ + ssize_t sz = 0; + struct file_map_c *fc = lc->map_data; + int qlen; + + spin_lock_irq(&fc->lock); + qlen = bio_list_size(&fc->work); + qlen += bio_list_size(&fc->in); + spin_unlock_irq(&fc->lock); + + DMEMIT("file %d", qlen); + + return sz; +} + +/* + * File status helper + */ +static ssize_t loop_block_status(struct loop_c *lc, char *result, + unsigned maxlen) +{ + ssize_t sz = 0; + struct block_map_c *bc = lc->map_data; + int mru; + + spin_lock_irq(&bc->mru_lock); + mru = bc->mru - bc->map; + spin_unlock_irq(&bc->mru_lock); + + DMEMIT("block %d %d", bc->nr_extents, mru); + + return sz; +} + +/* + * This needs some thought on handling unlinked backing files. some parts of + * the kernel return a cached name (now invalid), while others return a dcache + * "/path/to/foo (deleted)" name (never was/is valid). Which is "better" is + * debatable. + * + * On the one hand, using a cached name gives table output which is directly + * usable assuming the user re-creates the unlinked image file, on the other + * it is more consistent with e.g. swap to use the dcache name. + * +*/ +static int loop_status(struct dm_target *ti, status_type_t type, char *result, + unsigned maxlen) +{ + struct loop_c *lc = ti->private; + ssize_t sz = 0; + + switch (type) { + case STATUSTYPE_INFO: + if (test_bit(DM_LOOP_BMAP, &lc->flags)) + sz += loop_block_status(lc, result, maxlen - sz); + else if (test_bit(DM_LOOP_FSIO, &lc->flags)) + sz += loop_file_status(lc, result, maxlen - sz); + break; + + case STATUSTYPE_TABLE: + DMEMIT("%s %llu", lc->path, lc->offset); + break; + } + return 0; +} + +/* + * Destroy a loopback mapping + */ +static void loop_dtr(struct dm_target *ti) +{ + struct loop_c *lc = ti->private; + + if ((dm_table_get_mode(ti->table) & FMODE_WRITE)) + loop_invalidate_file(lc->filp); + + if (test_bit(DM_LOOP_BMAP, &lc->flags) && lc->map_data) + destroy_block_map((struct block_map_c *)lc->map_data); + if (test_bit(DM_LOOP_FSIO, &lc->flags) && lc->map_data) + destroy_file_map(lc); + + loop_put_file(lc->filp); + DMINFO("released file %s", lc->path); + + kfree(lc); +} + +/* + * Construct a loopback mapping: + */ +static int loop_ctr(struct dm_target *ti, unsigned argc, char **argv) +{ + struct loop_c *lc = NULL; + int r = -EINVAL; + + ti->error = "invalid argument count"; + if (argc != 2) + goto err; + + r = -ENOMEM; + ti->error = "cannot allocate loop context"; + lc = kzalloc(sizeof(*lc), GFP_KERNEL); + if (!lc) + goto err; + + /* default */ + set_bit(DM_LOOP_BMAP, &lc->flags); + ti->error = "cannot allocate loop path"; + lc->path = kstrdup(argv[0], GFP_KERNEL); + if (!lc->path) + goto err; + + ti->private = lc; + + r = -EINVAL; + ti->error = "invalid file offset"; + if (sscanf(argv[1], "%lld", &lc->offset) != 1) + goto err; + + if (lc->offset) + DMDEBUG("setting file offset to %lld", lc->offset); + + /* open & check file and set size parameters */ + r = loop_get_file(ti); + + /* ti->error has been set by loop_get_file */ + if (r) + goto err; + + ti->error = "could not create loop mapping"; + if (test_bit(DM_LOOP_BMAP, &lc->flags)) + r = setup_block_map(lc, lc->filp->f_mapping->host); + if (test_bit(DM_LOOP_FSIO, &lc->flags)) + r = setup_file_map(lc); + + if (r) + goto err_putf; + + loop_invalidate_file(lc->filp); + + set_split_io(ti); + if (lc->bdev) + dm_set_device_limits(ti, lc->bdev); + + DMDEBUG("constructed loop target on %s " + "(%lldk, %llu sectors)", lc->path, + (lc->size >> 10), (unsigned long long)lc->mapped_sectors); + ti->error = NULL; + + return 0; + +err_putf: + loop_put_file(lc->filp); +err: + if (lc) + kfree(lc); + return r; +} + +static struct target_type loop_target = { + .name = "loop", + .version = {0, 0, 2}, + .module = THIS_MODULE, + .ctr = loop_ctr, + .dtr = loop_dtr, + .map = loop_map, + .presuspend = loop_flush, + .flush = loop_flush, + .status = loop_status, +}; + +/*-------------------------------------------------------------------- + * Module bits + *--------------------------------------------------------------------*/ +static int __init dm_loop_init(void) +{ + int r; + + r = dm_register_target(&loop_target); + if (r < 0) { + DMERR("register failed %d", r); + goto err; + } + + r = -ENOMEM; + dm_loop_extent_cache = KMEM_CACHE(dm_loop_extent, SLAB_HWCACHE_ALIGN); + if (!dm_loop_extent_cache) + goto err; + + DMINFO("version %u.%u.%u loaded", + loop_target.version[0], loop_target.version[1], + loop_target.version[2]); + + return 0; + +err: + if (dm_loop_extent_cache) + kmem_cache_destroy(dm_loop_extent_cache); + + return r; +} + +static void __exit dm_loop_exit(void) +{ + int r; + + r = dm_unregister_target(&loop_target); + kmem_cache_destroy(dm_loop_extent_cache); + + if (r < 0) + DMERR("target unregister failed %d", r); + else + DMINFO("version %u.%u.%u unloaded", + loop_target.version[0], loop_target.version[1], + loop_target.version[2]); +} + +module_init(dm_loop_init); +module_exit(dm_loop_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Bryn Reeves "); +MODULE_DESCRIPTION("device-mapper loop target"); --- linux-2.6.28.orig/ubuntu/dm-loop/Kconfig +++ linux-2.6.28/ubuntu/dm-loop/Kconfig @@ -0,0 +1,9 @@ +config DM_LOOP + tristate "Loop target (EXPERIMENTAL)" + depends on BLK_DEV_DM && EXPERIMENTAL + ---help--- + This device-mapper target allows you to treat a regular file as + a block device. + + If unsure, say N. + --- linux-2.6.28.orig/ubuntu/dm-loop/Makefile +++ linux-2.6.28/ubuntu/dm-loop/Makefile @@ -0,0 +1,5 @@ +EXTRA_CFLAGS += -I$(srctree)/drivers/md + +obj-$(CONFIG_DM_LOOP) += dm-loop.o + + --- linux-2.6.28.orig/ubuntu/dm-loop/BOM +++ linux-2.6.28/ubuntu/dm-loop/BOM @@ -0,0 +1,4 @@ +Downloaded from: http://sources.redhat.com/lvm2/wiki/DMLoop +Current Version: Tues, 10 Jun 2008 09:10:03 -0000 +Comments: Fairly easy to integrate in + --- linux-2.6.28.orig/ubuntu/misc/dm-bbr.h +++ linux-2.6.28/ubuntu/misc/dm-bbr.h @@ -0,0 +1,132 @@ +/* + * (C) Copyright IBM Corp. 2002, 2004 + * + * 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 + * + * linux/drivers/md/dm-bbr.h + * + * Bad-block-relocation (BBR) target for device-mapper. + * + * The BBR target is designed to remap I/O write failures to another safe + * location on disk. Note that most disk drives have BBR built into them, + * this means that our software BBR will be only activated when all hardware + * BBR replacement sectors have been used. + */ + +#include +#include +#include + +#define BBR_TABLE_SIGNATURE 0x42627254 /* BbrT */ +#define BBR_ENTRIES_PER_SECT 31 +#define INITIAL_CRC 0xFFFFFFFF +#define CRC_POLYNOMIAL 0xEDB88320L + +/** + * Macros to cleanly print 64-bit numbers on both 32-bit and 64-bit machines. + * Use these in place of %Ld, %Lu, and %Lx. + **/ +#if BITS_PER_LONG > 32 +#define PFU64 "%lu" +#else +#define PFU64 "%Lu" +#endif + +/** + * struct bbr_table_entry + * @bad_sect: LBA of bad location. + * @replacement_sect: LBA of new location. + * + * Structure to describe one BBR remap. + **/ +struct bbr_table_entry { + u64 bad_sect; + u64 replacement_sect; +}; + +/** + * struct bbr_table + * @signature: Signature on each BBR table sector. + * @crc: CRC for this table sector. + * @sequence_number: Used to resolve conflicts when primary and secondary + * tables do not match. + * @in_use_cnt: Number of in-use table entries. + * @entries: Actual table of remaps. + * + * Structure to describe each sector of the metadata table. Each sector in this + * table can describe 31 remapped sectors. + **/ +struct bbr_table { + u32 signature; + u32 crc; + u32 sequence_number; + u32 in_use_cnt; + struct bbr_table_entry entries[BBR_ENTRIES_PER_SECT]; +}; + +/** + * struct bbr_runtime_remap + * + * Node in the binary tree used to keep track of remaps. + **/ +struct bbr_runtime_remap { + struct bbr_table_entry remap; + struct bbr_runtime_remap *left; + struct bbr_runtime_remap *right; +}; + +/** + * struct bbr_private + * @dev: Info about underlying device. + * @bbr_table: Copy of metadata table. + * @remap_root: Binary tree containing all remaps. + * @remap_root_lock: Lock for the binary tree. + * @remap_work: For adding work items to the work-queue. + * @remap_ios: List of I/Os for the work-queue to handle. + * @remap_ios_lock: Lock for the remap_ios list. + * @offset: LBA of data area. + * @lba_table1: LBA of primary BBR table. + * @lba_table2: LBA of secondary BBR table. + * @nr_sects_bbr_table: Size of each BBR table. + * @nr_replacement_blks: Number of replacement blocks. + * @start_replacement_sect: LBA of start of replacement blocks. + * @blksize_in_sects: Size of each block. + * @in_use_replacement_blks: Current number of remapped blocks. + * + * Private data for each BBR target. + **/ +struct bbr_private { + struct dm_dev *dev; + struct bbr_table *bbr_table; + struct bbr_runtime_remap *remap_root; + spinlock_t remap_root_lock; + + struct dm_io_request vma_io_req; + struct dm_io_request page_io_req; + + struct work_struct remap_work; + struct bio_list remap_ios; + spinlock_t remap_ios_lock; + + u64 offset; + u64 lba_table1; + u64 lba_table2; + u64 nr_sects_bbr_table; + u64 start_replacement_sect; + u64 nr_replacement_blks; + u32 blksize_in_sects; + atomic_t in_use_replacement_blks; +}; + --- linux-2.6.28.orig/ubuntu/misc/thinkpad_ec.c +++ linux-2.6.28/ubuntu/misc/thinkpad_ec.c @@ -0,0 +1,489 @@ +/* + * thinkpad_ec.c - ThinkPad embedded controller LPC3 functions + * + * The embedded controller on ThinkPad laptops has a non-standard interface, + * where LPC channel 3 of the H8S EC chip is hooked up to IO ports + * 0x1600-0x161F and implements (a special case of) the H8S LPC protocol. + * The EC LPC interface provides various system management services (currently + * known: battery information and accelerometer readouts). This driver + * provides access and mutual exclusion for the EC interface. +* + * The LPC protocol and terminology is documented here: + * "H8S/2104B Group Hardware Manual", + * http://documentation.renesas.com/eng/products/mpumcu/rej09b0300_2140bhm.pdf + * + * Copyright (C) 2006-2007 Shem Multinymous + * + * 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 "thinkpad_ec.h" +#include +#include +#include + +#define TP_VERSION "0.37" + +MODULE_AUTHOR("Shem Multinymous"); +MODULE_DESCRIPTION("ThinkPad embedded controller hardware access"); +MODULE_VERSION(TP_VERSION); +MODULE_LICENSE("GPL"); + +/* IO ports used by embedded controller LPC channel 3: */ +#define TPC_BASE_PORT 0x1600 +#define TPC_NUM_PORTS 0x20 +#define TPC_STR3_PORT 0x1604 /* Reads H8S EC register STR3 */ +#define TPC_TWR0_PORT 0x1610 /* Mapped to H8S EC register TWR0MW/SW */ +#define TPC_TWR15_PORT 0x161F /* Mapped to H8S EC register TWR15. */ + /* (and port TPC_TWR0_PORT+i is mapped to H8S reg TWRi for 00x%02x", \ + msg, args->val[0x0], args->val[0xF], code) + +/* State of request prefetching: */ +static u8 prefetch_arg0, prefetch_argF; /* Args of last prefetch */ +static u64 prefetch_jiffies; /* time of prefetch, or: */ +#define TPC_PREFETCH_NONE INITIAL_JIFFIES /* No prefetch */ +#define TPC_PREFETCH_JUNK (INITIAL_JIFFIES+1) /* Ignore prefetch */ + +/* Locking: */ + +static DECLARE_MUTEX(thinkpad_ec_mutex); + +/** + * thinkpad_ec_lock - get lock on the ThinkPad EC + * + * Get exclusive lock for accesing the ThinkPad embedded controller LPC3 + * interface. Returns 0 iff lock acquired. + */ +int thinkpad_ec_lock(void) +{ + int ret; + ret = down_interruptible(&thinkpad_ec_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_lock); + +/** + * thinkpad_ec_try_lock - try getting lock on the ThinkPad EC + * + * Try getting an exclusive lock for accesing the ThinkPad embedded + * controller LPC3. Returns immediately if lock is not available; neither + * blocks nor sleeps. Returns 0 iff lock acquired . + */ +int thinkpad_ec_try_lock(void) +{ + return down_trylock(&thinkpad_ec_mutex); +} +EXPORT_SYMBOL_GPL(thinkpad_ec_try_lock); + +/** + * thinkpad_ec_unlock - release lock on ThinkPad EC + * + * Release a previously acquired exclusive lock on the ThinkPad ebmedded + * controller LPC3 interface. + */ +void thinkpad_ec_unlock(void) +{ + up(&thinkpad_ec_mutex); +} +EXPORT_SYMBOL_GPL(thinkpad_ec_unlock); + +/** + * thinkpad_ec_request_row - tell embedded controller to prepare a row + * @args Input register arguments + * + * Requests a data row by writing to H8S LPC registers TRW0 through TWR15 (or + * a subset thereof) following the protocol prescribed by the "H8S/2104B Group + * Hardware Manual". Does sanity checks via status register STR3. + */ +static int thinkpad_ec_request_row(const struct thinkpad_ec_row *args) +{ + u8 str3; + int i; + + /* EC protocol requires write to TWR0 (function code): */ + if (!(args->mask & 0x0001)) { + printk(KERN_ERR MSG_FMT("bad args->mask=0x%02x", args->mask)); + return -EINVAL; + } + + /* Check initial STR3 status: */ + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 & H8S_STR3_OBF3B) { /* data already pending */ + inb(TPC_TWR15_PORT); /* marks end of previous transaction */ + if (prefetch_jiffies == TPC_PREFETCH_NONE) + printk(KERN_WARNING REQ_FMT( + "EC has result from unrequested transaction", + str3)); + return -EBUSY; /* EC will be ready in a few usecs */ + } else if (str3 == H8S_STR3_SWMF) { /* busy with previous request */ + if (prefetch_jiffies == TPC_PREFETCH_NONE) + printk(KERN_WARNING REQ_FMT( + "EC is busy with unrequested transaction", + str3)); + return -EBUSY; /* data will be pending in a few usecs */ + } else if (str3 != 0x00) { /* unexpected status? */ + printk(KERN_WARNING REQ_FMT("unexpected initial STR3", str3)); + return -EIO; + } + + /* Send TWR0MW: */ + outb(args->val[0], TPC_TWR0_PORT); + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 != H8S_STR3_MWMF) { /* not accepted? */ + printk(KERN_WARNING REQ_FMT("arg0 rejected", str3)); + return -EIO; + } + + /* Send TWR1 through TWR14: */ + for (i = 1; i < TP_CONTROLLER_ROW_LEN-1; i++) + if ((args->mask>>i)&1) + outb(args->val[i], TPC_TWR0_PORT+i); + + /* Send TWR15 (default to 0x01). This marks end of command. */ + outb((args->mask & 0x8000) ? args->val[0xF] : 0x01, TPC_TWR15_PORT); + + /* Wait until EC starts writing its reply (~60ns on average). + * Releasing locks before this happens may cause an EC hang + * due to firmware bug! + */ + for (i = 0; i < TPC_REQUEST_RETRIES; i++) { + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 & H8S_STR3_SWMF) /* EC started replying */ + return 0; + else if (!(str3 & ~(H8S_STR3_IBF3B|H8S_STR3_MWMF))) + /* Normal progress (the EC hasn't seen the request + * yet, or is processing it). Wait it out. */ + ndelay(TPC_REQUEST_NDELAY); + else { /* weird EC status */ + printk(KERN_WARNING + REQ_FMT("bad end STR3", str3)); + return -EIO; + } + } + printk(KERN_WARNING REQ_FMT("EC is mysteriously silent", str3)); + return -EIO; +} + +/** + * thinkpad_ec_read_data - read pre-requested row-data from EC + * @args Input register arguments of pre-requested rows + * @data Output register values + * + * Reads current row data from the controller, assuming it's already + * requested. Follows the H8S spec for register access and status checks. + */ +static int thinkpad_ec_read_data(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data) +{ + int i; + u8 str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + /* Once we make a request, STR3 assumes the sequence of values listed + * in the following 'if' as it reads the request and writes its data. + * It takes about a few dozen nanosecs total, with very high variance. + */ + if (str3 == (H8S_STR3_IBF3B|H8S_STR3_MWMF) || + str3 == 0x00 || /* the 0x00 is indistinguishable from idle EC! */ + str3 == H8S_STR3_SWMF) + return -EBUSY; /* not ready yet */ + /* Finally, the EC signals output buffer full: */ + if (str3 != (H8S_STR3_OBF3B|H8S_STR3_SWMF)) { + printk(KERN_WARNING + REQ_FMT("bad initial STR3", str3)); + return -EIO; + } + + /* Read first byte (signals start of read transactions): */ + data->val[0] = inb(TPC_TWR0_PORT); + /* Optionally read 14 more bytes: */ + for (i = 1; i < TP_CONTROLLER_ROW_LEN-1; i++) + if ((data->mask >> i)&1) + data->val[i] = inb(TPC_TWR0_PORT+i); + /* Read last byte from 0x161F (signals end of read transaction): */ + data->val[0xF] = inb(TPC_TWR15_PORT); + + /* Readout still pending? */ + str3 = inb(TPC_STR3_PORT) & H8S_STR3_MASK; + if (str3 & H8S_STR3_OBF3B) + printk(KERN_WARNING + REQ_FMT("OBF3B=1 after read", str3)); + /* If port 0x161F returns 0x80 too often, the EC may lock up. Warn: */ + if (data->val[0xF] == 0x80) + printk(KERN_WARNING + REQ_FMT("0x161F reports error", data->val[0xF])); + return 0; +} + +/** + * thinkpad_ec_is_row_fetched - is the given row currently prefetched? + * + * To keep things simple we compare only the first and last args; + * this suffices for all known cases. + */ +static int thinkpad_ec_is_row_fetched(const struct thinkpad_ec_row *args) +{ + return (prefetch_jiffies != TPC_PREFETCH_NONE) && + (prefetch_jiffies != TPC_PREFETCH_JUNK) && + (prefetch_arg0 == args->val[0]) && + (prefetch_argF == args->val[0xF]) && + (get_jiffies_64() < prefetch_jiffies + TPC_PREFETCH_TIMEOUT); +} + +/** + * thinkpad_ec_read_row - request and read data from ThinkPad EC + * @args Input register arguments + * @data Output register values + * + * Read a data row from the ThinkPad embedded controller LPC3 interface. + * Does fetching and retrying if needed. The row is specified by an + * array of 16 bytes, some of which may be undefined (but the first is + * mandatory). These bytes are given in @args->val[], where @args->val[i] is + * used iff (@args->mask>>i)&1). The resulting row data is stored in + * @data->val[], but is only guaranteed to be valid for indices corresponding + * to set bit in @data->mask. That is, if @data->mask&(1<val[i] is undefined. + * + * Returns -EBUSY on transient error and -EIO on abnormal condition. + * Caller must hold controller lock. + */ +int thinkpad_ec_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data) +{ + int retries, ret; + + if (thinkpad_ec_is_row_fetched(args)) + goto read_row; /* already requested */ + + /* Request the row */ + for (retries = 0; retries < TPC_READ_RETRIES; ++retries) { + ret = thinkpad_ec_request_row(args); + if (!ret) + goto read_row; + if (ret != -EBUSY) + break; + ndelay(TPC_READ_NDELAY); + } + printk(KERN_ERR REQ_FMT("failed requesting row", ret)); + goto out; + +read_row: + /* Read the row's data */ + for (retries = 0; retries < TPC_READ_RETRIES; ++retries) { + ret = thinkpad_ec_read_data(args, data); + if (!ret) + goto out; + if (ret != -EBUSY) + break; + ndelay(TPC_READ_NDELAY); + } + + printk(KERN_ERR REQ_FMT("failed waiting for data", ret)); + +out: + prefetch_jiffies = TPC_PREFETCH_JUNK; + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_read_row); + +/** + * thinkpad_ec_try_read_row - try reading prefetched data from ThinkPad EC + * @args Input register arguments + * @data Output register values + * + * Try reading a data row from the ThinkPad embedded controller LPC3 + * interface, if this raw was recently prefetched using + * thinkpad_ec_prefetch_row(). Does not fetch, retry or block. + * The parameters have the same meaning as in thinkpad_ec_read_row(). + * + * Returns -EBUSY is data not ready and -ENODATA if row not prefetched. + * Caller must hold controller lock. + */ +int thinkpad_ec_try_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data) +{ + int ret; + if (!thinkpad_ec_is_row_fetched(args)) { + ret = -ENODATA; + } else { + ret = thinkpad_ec_read_data(args, data); + if (!ret) + prefetch_jiffies = TPC_PREFETCH_NONE; /* eaten up */ + } + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_try_read_row); + +/** + * thinkpad_ec_prefetch_row - prefetch data from ThinkPad EC + * @args Input register arguments + * + * Prefetch a data row from the ThinkPad embedded controller LCP3 + * interface. A subsequent call to thinkpad_ec_read_row() with the + * same arguments will be faster, and a subsequent call to + * thinkpad_ec_try_read_row() stands a good chance of succeeding if + * done neither too soon nor too late. See + * thinkpad_ec_read_row() for the meaning of @args. + * + * Returns -EBUSY on transient error and -EIO on abnormal condition. + * Caller must hold controller lock. + */ +int thinkpad_ec_prefetch_row(const struct thinkpad_ec_row *args) +{ + int ret; + ret = thinkpad_ec_request_row(args); + if (ret) { + prefetch_jiffies = TPC_PREFETCH_JUNK; + } else { + prefetch_jiffies = get_jiffies_64(); + prefetch_arg0 = args->val[0x0]; + prefetch_argF = args->val[0xF]; + } + return ret; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_prefetch_row); + +/** + * thinkpad_ec_invalidate - invalidate prefetched ThinkPad EC data + * + * Invalidate the data prefetched via thinkpad_ec_prefetch_row() from the + * ThinkPad embedded controller LPC3 interface. + * Must be called before unlocking by any code that accesses the controller + * ports directly. + */ +void thinkpad_ec_invalidate(void) +{ + prefetch_jiffies = TPC_PREFETCH_JUNK; +} +EXPORT_SYMBOL_GPL(thinkpad_ec_invalidate); + + +/*** Checking for EC hardware ***/ + +/** + * thinkpad_ec_test - verify the EC is present and follows protocol + * + * Ensure the EC LPC3 channel really works on this machine by making + * an EC request and seeing if the EC follows the documented H8S protocol. + * The requested row just reads battery status, so it should be harmless to + * access it (on a correct EC). + * This test writes to IO ports, so execute only after checking DMI. + */ +static int __init thinkpad_ec_test(void) +{ + int ret; + const struct thinkpad_ec_row args = /* battery 0 basic status */ + { .mask = 0x8001, .val = {0x01,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x00} }; + struct thinkpad_ec_row data = { .mask = 0x0000 }; + ret = thinkpad_ec_lock(); + if (ret) + return ret; + ret = thinkpad_ec_read_row(&args, &data); + thinkpad_ec_unlock(); + return ret; +} + +/* Search all DMI device names of a given type for a substring */ +static int __init dmi_find_substring(int type, const char *substr) +{ + const struct dmi_device *dev = NULL; + while ((dev = dmi_find_device(type, NULL, dev))) { + if (strstr(dev->name, substr)) + return 1; + } + return 0; +} + +#define TP_DMI_MATCH(vendor,model) { \ + .ident = vendor " " model, \ + .matches = { \ + DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ + DMI_MATCH(DMI_PRODUCT_VERSION, model) \ + } \ +} + +/* Check DMI for existence of ThinkPad embedded controller */ +static int __init check_dmi_for_ec(void) +{ + /* A few old models that have a good EC but don't report it in DMI */ + struct dmi_system_id tp_whitelist[] = { + TP_DMI_MATCH("IBM", "ThinkPad A30"), + TP_DMI_MATCH("IBM", "ThinkPad T23"), + TP_DMI_MATCH("IBM", "ThinkPad X24"), + { .ident = NULL } + }; + return dmi_find_substring(DMI_DEV_TYPE_OEM_STRING, + "IBM ThinkPad Embedded Controller") || + dmi_check_system(tp_whitelist); +} + +/*** Init and cleanup ***/ + +static int __init thinkpad_ec_init(void) +{ + if (!check_dmi_for_ec()) { + printk(KERN_WARNING + "thinkpad_ec: no ThinkPad embedded controller!\n"); + return -ENODEV; + } + + if (!request_region(TPC_BASE_PORT, TPC_NUM_PORTS, + "thinkpad_ec")) { + printk(KERN_ERR "thinkpad_ec: cannot claim io ports %#x-%#x\n", + TPC_BASE_PORT, + TPC_BASE_PORT + TPC_NUM_PORTS - 1); + return -ENXIO; + } + prefetch_jiffies = TPC_PREFETCH_JUNK; + if (thinkpad_ec_test()) { + printk(KERN_ERR "thinkpad_ec: initial ec test failed\n"); + release_region(TPC_BASE_PORT, TPC_NUM_PORTS); + return -ENXIO; + } + printk(KERN_INFO "thinkpad_ec: thinkpad_ec " TP_VERSION " loaded.\n"); + return 0; +} + +static void __exit thinkpad_ec_exit(void) +{ + release_region(TPC_BASE_PORT, TPC_NUM_PORTS); + printk(KERN_INFO "thinkpad_ec: unloaded.\n"); +} + +module_init(thinkpad_ec_init); +module_exit(thinkpad_ec_exit); --- linux-2.6.28.orig/ubuntu/misc/dm-bbr.c +++ linux-2.6.28/ubuntu/misc/dm-bbr.c @@ -0,0 +1,1012 @@ +/* + * (C) Copyright IBM Corp. 2002, 2004 + * + * 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 + * + * linux/drivers/md/dm-bbr.c + * + * Bad-block-relocation (BBR) target for device-mapper. + * + * The BBR target is designed to remap I/O write failures to another safe + * location on disk. Note that most disk drives have BBR built into them, + * this means that our software BBR will be only activated when all hardware + * BBR replacement sectors have been used. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dm-bio-record.h" +#include "dm.h" +#include "dm-bbr.h" + +#define DM_MSG_PREFIX "bbr" +#define SECTOR_SIZE (1 << SECTOR_SHIFT) + +static struct workqueue_struct *dm_bbr_wq = NULL; +static void bbr_remap_handler(struct work_struct *work); +static struct kmem_cache *bbr_remap_cache; +static struct kmem_cache *bbr_io_cache; +static mempool_t *bbr_io_pool; + +/** + * bbr_binary_tree_destroy + * + * Destroy the binary tree. + **/ +static void bbr_binary_tree_destroy(struct bbr_runtime_remap *root) +{ + struct bbr_runtime_remap **link = NULL; + struct bbr_runtime_remap *node = root; + + while (node) { + if (node->left) { + link = &node->left; + node = node->left; + continue; + } + if (node->right) { + link = &node->right; + node = node->right; + continue; + } + + kmem_cache_free(bbr_remap_cache, node); + if (node == root) { + /* If root is deleted, we're done. */ + break; + } + + /* Back to root. */ + node = root; + *link = NULL; + } +} + +static void bbr_free_remap(struct bbr_private *bbr_id) +{ + spin_lock_irq(&bbr_id->remap_root_lock); + bbr_binary_tree_destroy(bbr_id->remap_root); + bbr_id->remap_root = NULL; + spin_unlock_irq(&bbr_id->remap_root_lock); +} + +static struct bbr_private *bbr_alloc_private(void) +{ + struct bbr_private *bbr_id; + + bbr_id = kzalloc(sizeof(*bbr_id), GFP_KERNEL); + if (bbr_id == NULL) + return NULL; + + INIT_WORK(&bbr_id->remap_work, bbr_remap_handler); + spin_lock_init(&bbr_id->remap_root_lock); + spin_lock_init(&bbr_id->remap_ios_lock); + bbr_id->in_use_replacement_blks = (atomic_t) ATOMIC_INIT(0); + + return bbr_id; +} + +static void bbr_free_private(struct bbr_private *bbr_id) +{ + vfree(bbr_id->bbr_table); + bbr_free_remap(bbr_id); + kfree(bbr_id); +} + +static u32 crc_table[256]; +static u32 crc_table_built = 0; + +static void build_crc_table(void) +{ + u32 i, j, crc; + + for (i = 0; i <= 255; i++) { + crc = i; + for (j = 8; j > 0; j--) { + if (crc & 1) + crc = (crc >> 1) ^ CRC_POLYNOMIAL; + else + crc >>= 1; + } + crc_table[i] = crc; + } + crc_table_built = 1; +} + +static u32 calculate_crc(u32 crc, void *buffer, u32 buffersize) +{ + unsigned char *current_byte; + u32 temp1, temp2, i; + + current_byte = (unsigned char *) buffer; + /* Make sure the crc table is available */ + if (!crc_table_built) + build_crc_table(); + /* Process each byte in the buffer. */ + for (i = 0; i < buffersize; i++) { + temp1 = (crc >> 8) & 0x00FFFFFF; + temp2 = crc_table[(crc ^ (u32) * current_byte) & + (u32) 0xff]; + current_byte++; + crc = temp1 ^ temp2; + } + return crc; +} + +/** + * le_bbr_table_sector_to_cpu + * + * Convert bbr meta data from on-disk (LE) format + * to the native cpu endian format. + **/ +static void le_bbr_table_sector_to_cpu(struct bbr_table *p) +{ + int i; + p->signature = le32_to_cpup(&p->signature); + p->crc = le32_to_cpup(&p->crc); + p->sequence_number = le32_to_cpup(&p->sequence_number); + p->in_use_cnt = le32_to_cpup(&p->in_use_cnt); + for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) { + p->entries[i].bad_sect = + le64_to_cpup(&p->entries[i].bad_sect); + p->entries[i].replacement_sect = + le64_to_cpup(&p->entries[i].replacement_sect); + } +} + +/** + * cpu_bbr_table_sector_to_le + * + * Convert bbr meta data from cpu endian format to on-disk (LE) format + **/ +static void cpu_bbr_table_sector_to_le(struct bbr_table *p, + struct bbr_table *le) +{ + int i; + le->signature = cpu_to_le32p(&p->signature); + le->crc = cpu_to_le32p(&p->crc); + le->sequence_number = cpu_to_le32p(&p->sequence_number); + le->in_use_cnt = cpu_to_le32p(&p->in_use_cnt); + for (i = 0; i < BBR_ENTRIES_PER_SECT; i++) { + le->entries[i].bad_sect = + cpu_to_le64p(&p->entries[i].bad_sect); + le->entries[i].replacement_sect = + cpu_to_le64p(&p->entries[i].replacement_sect); + } +} + +/** + * validate_bbr_table_sector + * + * Check the specified BBR table sector for a valid signature and CRC. If it's + * valid, endian-convert the table sector. + **/ +static int validate_bbr_table_sector(struct bbr_table *p) +{ + int org_crc, final_crc; + + if (le32_to_cpup(&p->signature) != BBR_TABLE_SIGNATURE) { + DMERR("BBR table signature doesn't match!"); + DMERR("Found 0x%x. Expecting 0x%x", + le32_to_cpup(&p->signature), BBR_TABLE_SIGNATURE); + return -EINVAL; + } + + if (!p->crc) { + DMERR("BBR table sector has no CRC!"); + return -EINVAL; + } + + org_crc = le32_to_cpup(&p->crc); + p->crc = 0; + final_crc = calculate_crc(INITIAL_CRC, (void *)p, sizeof(*p)); + if (final_crc != org_crc) { + DMERR("CRC failed!"); + DMERR("Found 0x%x. Expecting 0x%x", + org_crc, final_crc); + return -EINVAL; + } + + p->crc = cpu_to_le32p(&org_crc); + le_bbr_table_sector_to_cpu(p); + + return 0; +} + +/** + * bbr_binary_tree_insert + * + * Insert a node into the binary tree. + **/ +static void bbr_binary_tree_insert(struct bbr_runtime_remap **root, + struct bbr_runtime_remap *newnode) +{ + struct bbr_runtime_remap **node = root; + while (node && *node) { + node = (newnode->remap.bad_sect > (*node)->remap.bad_sect) ? + &(*node)->right : &(*node)->left; + } + + newnode->left = newnode->right = NULL; + *node = newnode; +} + +/** + * bbr_binary_search + * + * Search for a node that contains bad_sect == lsn. + **/ +static struct bbr_runtime_remap *bbr_binary_search( + struct bbr_runtime_remap *root, + u64 lsn) +{ + struct bbr_runtime_remap *node = root; + while (node) { + if (node->remap.bad_sect == lsn) + break; + + node = (lsn > node->remap.bad_sect) ? node->right : node->left; + } + return node; +} + +/** + * bbr_insert_remap_entry + * + * Create a new remap entry and add it to the binary tree for this node. + **/ +static int bbr_insert_remap_entry(struct bbr_private *bbr_id, + struct bbr_table_entry *new_bbr_entry) +{ + struct bbr_runtime_remap *newnode; + + newnode = kmem_cache_alloc(bbr_remap_cache, GFP_NOIO); + if (!newnode) { + DMERR("Could not allocate from remap cache!"); + return -ENOMEM; + } + newnode->remap.bad_sect = new_bbr_entry->bad_sect; + newnode->remap.replacement_sect = new_bbr_entry->replacement_sect; + spin_lock_irq(&bbr_id->remap_root_lock); + bbr_binary_tree_insert(&bbr_id->remap_root, newnode); + spin_unlock_irq(&bbr_id->remap_root_lock); + return 0; +} + +/** + * bbr_table_to_remap_list + * + * The on-disk bbr table is sorted by the replacement sector LBA. In order to + * improve run time performance, the in memory remap list must be sorted by + * the bad sector LBA. This function is called at discovery time to initialize + * the remap list. This function assumes that at least one copy of meta data + * is valid. + **/ +static u32 bbr_table_to_remap_list(struct bbr_private *bbr_id) +{ + u32 in_use_blks = 0; + int i, j; + struct bbr_table *p; + + for (i = 0, p = bbr_id->bbr_table; + i < bbr_id->nr_sects_bbr_table; + i++, p++) { + if (!p->in_use_cnt) + break; + + in_use_blks += p->in_use_cnt; + for (j = 0; j < p->in_use_cnt; j++) + bbr_insert_remap_entry(bbr_id, &p->entries[j]); + } + if (in_use_blks) { + char b[32]; + DMWARN("There are %u BBR entries for device %s", + in_use_blks, format_dev_t(b, bbr_id->dev->bdev->bd_dev)); + } + + return in_use_blks; +} + +/** + * bbr_search_remap_entry + * + * Search remap entry for the specified sector. If found, return a pointer to + * the table entry. Otherwise, return NULL. + **/ +static struct bbr_table_entry *bbr_search_remap_entry( + struct bbr_private *bbr_id, + u64 lsn) +{ + struct bbr_runtime_remap *p; + + spin_lock_irq(&bbr_id->remap_root_lock); + p = bbr_binary_search(bbr_id->remap_root, lsn); + spin_unlock_irq(&bbr_id->remap_root_lock); + return (p) ? &p->remap : NULL; +} + +/** + * bbr_remap + * + * If *lsn is in the remap table, return TRUE and modify *lsn, + * else, return FALSE. + **/ +static int bbr_remap(struct bbr_private *bbr_id, + u64 *lsn) +{ + struct bbr_table_entry *e; + + if (atomic_read(&bbr_id->in_use_replacement_blks)) { + e = bbr_search_remap_entry(bbr_id, *lsn); + if (e) { + *lsn = e->replacement_sect; + return 1; + } + } + return 0; +} + +/** + * bbr_remap_probe + * + * If any of the sectors in the range [lsn, lsn+nr_sects] are in the remap + * table return TRUE, Else, return FALSE. + **/ +static int bbr_remap_probe(struct bbr_private *bbr_id, + u64 lsn, u64 nr_sects) +{ + u64 tmp, cnt; + + if (atomic_read(&bbr_id->in_use_replacement_blks)) { + for (cnt = 0, tmp = lsn; + cnt < nr_sects; + cnt += bbr_id->blksize_in_sects, tmp = lsn + cnt) { + if (bbr_remap(bbr_id,&tmp)) + return 1; + } + } + return 0; +} + +static int rw_table(struct bbr_private *bbr_id, void *vma, + struct dm_io_region *ptr, int rw) +{ + bbr_id->vma_io_req.bi_rw = rw; + bbr_id->vma_io_req.mem.ptr.vma = vma; + bbr_id->vma_io_req.notify.fn = NULL; + + return dm_io(&bbr_id->vma_io_req, 1, ptr, NULL); +} + +static int io_sync(struct bbr_private *bbr_id, struct page_list *pl, + unsigned offset, struct dm_io_region *ptr, int rw) +{ + bbr_id->page_io_req.bi_rw = rw; + bbr_id->page_io_req.mem.ptr.pl = pl; + bbr_id->page_io_req.mem.offset = offset; + bbr_id->page_io_req.notify.fn = NULL; + + return dm_io(&bbr_id->page_io_req, 1, ptr, NULL); +} + +/** + * bbr_setup + * + * Read the remap tables from disk and set up the initial remap tree. + **/ +static int bbr_setup(struct bbr_private *bbr_id) +{ + struct bbr_table *table = bbr_id->bbr_table; + struct dm_io_region job; + int i, rc = 0; + + job.bdev = bbr_id->dev->bdev; + job.count = 1; + + /* Read and verify each BBR table sector individually. */ + for (i = 0; i < bbr_id->nr_sects_bbr_table; i++, table++) { + job.sector = bbr_id->lba_table1 + i; + rc = rw_table(bbr_id, table, &job, READ); + if (rc && bbr_id->lba_table2) { + job.sector = bbr_id->lba_table2 + i; + rc = rw_table(bbr_id, table, &job, READ); + } + if (rc) { + goto out; + } + + rc = validate_bbr_table_sector(table); + if (rc) { + goto out; + } + } + atomic_set(&bbr_id->in_use_replacement_blks, + bbr_table_to_remap_list(bbr_id)); + +out: + if (rc) + DMERR("error during device setup: %d", rc); + return rc; +} + +/** + * bbr_io_remap_error + * @bbr_id: Private data for the BBR node. + * @rw: READ or WRITE. + * @starting_lsn: Starting sector of request to remap. + * @count: Number of sectors in the request. + * @page: Page containing the data for the request. + * @offset: Byte-offset of the data within the page. + * + * For the requested range, try to write each sector individually. For each + * sector that fails, find the next available remap location and write the + * data to that new location. Then update the table and write both copies + * of the table to disk. Finally, update the in-memory mapping and do any + * other necessary bookkeeping. + **/ +static int bbr_io_remap_error(struct bbr_private *bbr_id, + int rw, + u64 starting_lsn, + u64 count, + struct page *page, + unsigned int offset) +{ + struct bbr_table *bbr_table; + struct dm_io_region job; + struct page_list pl; + unsigned long table_sector_index; + unsigned long table_sector_offset; + unsigned long index; + u64 lsn, new_lsn; + char b[32]; + int rc; + + job.bdev = bbr_id->dev->bdev; + job.count = 1; + pl.page = page; + pl.next = NULL; + + /* For each sector in the request. */ + for (lsn = 0; lsn < count; lsn++, offset += SECTOR_SIZE) { + job.sector = starting_lsn + lsn; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + while (rc) { + /* Find the next available relocation sector. */ + new_lsn = atomic_read(&bbr_id->in_use_replacement_blks); + if (new_lsn >= bbr_id->nr_replacement_blks) { + /* No more replacement sectors available. */ + return -EIO; + } + new_lsn += bbr_id->start_replacement_sect; + + /* Write the data to its new location. */ + DMWARN("device %s: Trying to remap bad sector "PFU64" to sector "PFU64, + format_dev_t(b, bbr_id->dev->bdev->bd_dev), + starting_lsn + lsn, new_lsn); + job.sector = new_lsn; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* This replacement sector is bad. + * Try the next one. + */ + DMERR("device %s: replacement sector "PFU64" is bad. Skipping.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev), new_lsn); + atomic_inc(&bbr_id->in_use_replacement_blks); + continue; + } + + /* Add this new entry to the on-disk table. */ + table_sector_index = new_lsn - + bbr_id->start_replacement_sect; + table_sector_offset = table_sector_index / + BBR_ENTRIES_PER_SECT; + index = table_sector_index % BBR_ENTRIES_PER_SECT; + + bbr_table = &bbr_id->bbr_table[table_sector_offset]; + bbr_table->entries[index].bad_sect = starting_lsn + lsn; + bbr_table->entries[index].replacement_sect = new_lsn; + bbr_table->in_use_cnt++; + bbr_table->sequence_number++; + bbr_table->crc = 0; + bbr_table->crc = calculate_crc(INITIAL_CRC, + bbr_table, + sizeof(struct bbr_table)); + + /* Write the table to disk. */ + cpu_bbr_table_sector_to_le(bbr_table, bbr_table); + if (bbr_id->lba_table1) { + job.sector = bbr_id->lba_table1 + table_sector_offset; + rc = rw_table(bbr_id, bbr_table, &job, WRITE); + } + if (bbr_id->lba_table2) { + job.sector = bbr_id->lba_table2 + table_sector_offset; + rc |= rw_table(bbr_id, bbr_table, &job, WRITE); + } + le_bbr_table_sector_to_cpu(bbr_table); + + if (rc) { + /* Error writing one of the tables to disk. */ + DMERR("device %s: error updating BBR tables on disk.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev)); + return rc; + } + + /* Insert a new entry in the remapping binary-tree. */ + rc = bbr_insert_remap_entry(bbr_id, + &bbr_table->entries[index]); + if (rc) { + DMERR("device %s: error adding new entry to remap tree.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev)); + return rc; + } + + atomic_inc(&bbr_id->in_use_replacement_blks); + } + } + + return 0; +} + +/** + * bbr_io_process_request + * + * For each sector in this request, check if the sector has already + * been remapped. If so, process all previous sectors in the request, + * followed by the remapped sector. Then reset the starting lsn and + * count, and keep going with the rest of the request as if it were + * a whole new request. If any of the sync_io's return an error, + * call the remapper to relocate the bad sector(s). + * + * 2.5 Note: When switching over to bio's for the I/O path, we have made + * the assumption that the I/O request described by the bio is one + * virtually contiguous piece of memory (even though the bio vector + * describes it using a series of physical page addresses). + **/ +static int bbr_io_process_request(struct bbr_private *bbr_id, + struct bio *bio) +{ + struct dm_io_region job; + u64 starting_lsn = bio->bi_sector; + u64 count, lsn, remapped_lsn; + struct page_list pl; + unsigned int offset; + int i, rw = bio_data_dir(bio); + int rc = 0; + + job.bdev = bbr_id->dev->bdev; + pl.next = NULL; + + /* Each bio can contain multiple vectors, each with a different page. + * Treat each vector as a separate request. + */ + /* KMC: Is this the right way to walk the bvec list? */ + for (i = 0; + i < bio->bi_vcnt; + i++, bio->bi_idx++, starting_lsn += count) { + + /* Bvec info: number of sectors, page, + * and byte-offset within page. + */ + count = bio_iovec(bio)->bv_len >> SECTOR_SHIFT; + pl.page = bio_iovec(bio)->bv_page; + offset = bio_iovec(bio)->bv_offset; + + /* For each sector in this bvec, check if the sector has + * already been remapped. If so, process all previous sectors + * in this request, followed by the remapped sector. Then reset + * the starting lsn and count and keep going with the rest of + * the request as if it were a whole new request. + */ + for (lsn = 0; lsn < count; lsn++) { + remapped_lsn = starting_lsn + lsn; + rc = bbr_remap(bbr_id, &remapped_lsn); + if (!rc) { + /* This sector is fine. */ + continue; + } + + /* Process all sectors in the request up to this one. */ + if (lsn > 0) { + job.sector = starting_lsn; + job.count = lsn; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* If this I/O failed, then one of the + * sectors in this request needs to be + * relocated. + */ + rc = bbr_io_remap_error(bbr_id, rw, + starting_lsn, + lsn, pl.page, + offset); + if (rc) { + /* KMC: Return? Or continue to next bvec? */ + return rc; + } + } + offset += (lsn << SECTOR_SHIFT); + } + + /* Process the remapped sector. */ + job.sector = remapped_lsn; + job.count = 1; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* BUGBUG - Need more processing if this caused + * an error. If this I/O failed, then the + * existing remap is now bad, and we need to + * find a new remap. Can't use + * bbr_io_remap_error(), because the existing + * map entry needs to be changed, not added + * again, and the original table entry also + * needs to be changed. + */ + return rc; + } + + starting_lsn += (lsn + 1); + count -= (lsn + 1); + lsn = -1; + offset += SECTOR_SIZE; + } + + /* Check for any remaining sectors after the last split. This + * could potentially be the whole request, but that should be a + * rare case because requests should only be processed by the + * thread if we know an error occurred or they contained one or + * more remapped sectors. + */ + if (count) { + job.sector = starting_lsn; + job.count = count; + rc = io_sync(bbr_id, &pl, offset, &job, rw); + if (rc) { + /* If this I/O failed, then one of the sectors + * in this request needs to be relocated. + */ + rc = bbr_io_remap_error(bbr_id, rw, starting_lsn, + count, pl.page, offset); + if (rc) { + /* KMC: Return? Or continue to next bvec? */ + return rc; + } + } + } + } + + return 0; +} + +static void bbr_io_process_requests(struct bbr_private *bbr_id, + struct bio *bio) +{ + struct bio *next; + int rc; + + while (bio) { + next = bio->bi_next; + bio->bi_next = NULL; + + rc = bbr_io_process_request(bbr_id, bio); + + bio_endio(bio, rc); + + bio = next; + } +} + +/** + * bbr_remap_handler + * + * This is the handler for the bbr work-queue. + * + * I/O requests should only be sent to this handler if we know that: + * a) the request contains at least one remapped sector. + * or + * b) the request caused an error on the normal I/O path. + * + * This function uses synchronous I/O, so sending a request to this + * thread that doesn't need special processing will cause severe + * performance degredation. + **/ +static void bbr_remap_handler(struct work_struct *work) +{ + struct bbr_private *bbr_id = + container_of(work, struct bbr_private, remap_work); + struct bio *bio; + unsigned long flags; + + spin_lock_irqsave(&bbr_id->remap_ios_lock, flags); + bio = bio_list_get(&bbr_id->remap_ios); + spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags); + + bbr_io_process_requests(bbr_id, bio); +} + +/** + * bbr_endio + * + * This is the callback for normal write requests. Check for an error + * during the I/O, and send to the thread for processing if necessary. + **/ +static int bbr_endio(struct dm_target *ti, struct bio *bio, + int error, union map_info *map_context) +{ + struct bbr_private *bbr_id = ti->private; + struct dm_bio_details *bbr_io = map_context->ptr; + + if (error && bbr_io) { + unsigned long flags; + char b[32]; + + dm_bio_restore(bbr_io, bio); + map_context->ptr = NULL; + + DMERR("device %s: I/O failure on sector %lu. " + "Scheduling for retry.", + format_dev_t(b, bbr_id->dev->bdev->bd_dev), + (unsigned long)bio->bi_sector); + + spin_lock_irqsave(&bbr_id->remap_ios_lock, flags); + bio_list_add(&bbr_id->remap_ios, bio); + spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags); + + queue_work(dm_bbr_wq, &bbr_id->remap_work); + + error = 1; + } + + if (bbr_io) + mempool_free(bbr_io, bbr_io_pool); + + return error; +} + +/** + * Construct a bbr mapping + **/ +static int bbr_ctr(struct dm_target *ti, unsigned int argc, char **argv) +{ + struct bbr_private *bbr_id; + unsigned long block_size; + char *end; + int rc = -EINVAL; + + if (argc != 8) { + ti->error = "dm-bbr requires exactly 8 arguments: " + "device offset table1_lsn table2_lsn table_size start_replacement nr_replacement_blks block_size"; + goto out1; + } + + bbr_id = bbr_alloc_private(); + if (!bbr_id) { + ti->error = "dm-bbr: Error allocating bbr private data."; + goto out1; + } + + bbr_id->offset = simple_strtoull(argv[1], &end, 10); + bbr_id->lba_table1 = simple_strtoull(argv[2], &end, 10); + bbr_id->lba_table2 = simple_strtoull(argv[3], &end, 10); + bbr_id->nr_sects_bbr_table = simple_strtoull(argv[4], &end, 10); + bbr_id->start_replacement_sect = simple_strtoull(argv[5], &end, 10); + bbr_id->nr_replacement_blks = simple_strtoull(argv[6], &end, 10); + block_size = simple_strtoul(argv[7], &end, 10); + bbr_id->blksize_in_sects = (block_size >> SECTOR_SHIFT); + + bbr_id->vma_io_req.mem.type = DM_IO_VMA; + bbr_id->vma_io_req.client = dm_io_client_create(1); + if (IS_ERR(bbr_id->vma_io_req.client)) { + rc = PTR_ERR(bbr_id->vma_io_req.client); + DMWARN("couldn't allocate disk VMA io client"); + goto out2; + } + + bbr_id->page_io_req.mem.type = DM_IO_PAGE_LIST; + bbr_id->page_io_req.client = dm_io_client_create(1); + if (IS_ERR(bbr_id->page_io_req.client)) { + rc = PTR_ERR(bbr_id->page_io_req.client); + DMWARN("couldn't allocate pagelist io client"); + goto out3; + } + + bbr_id->bbr_table = vmalloc(bbr_id->nr_sects_bbr_table << SECTOR_SHIFT); + if (!bbr_id->bbr_table) { + ti->error = "dm-bbr: Error allocating bbr table."; + goto out4; + } + + if (dm_get_device(ti, argv[0], 0, ti->len, + dm_table_get_mode(ti->table), &bbr_id->dev)) { + ti->error = "dm-bbr: Device lookup failed"; + goto out4; + } + + rc = bbr_setup(bbr_id); + if (rc) { + ti->error = "dm-bbr: Device setup failed"; + goto out5; + } + + ti->private = bbr_id; + return 0; + +out5: + dm_put_device(ti, bbr_id->dev); +out4: + dm_io_client_destroy(bbr_id->page_io_req.client); +out3: + dm_io_client_destroy(bbr_id->vma_io_req.client); +out2: + bbr_free_private(bbr_id); +out1: + return rc; +} + +static void bbr_dtr(struct dm_target *ti) +{ + struct bbr_private *bbr_id = ti->private; + + dm_put_device(ti, bbr_id->dev); + dm_io_client_destroy(bbr_id->page_io_req.client); + dm_io_client_destroy(bbr_id->vma_io_req.client); + bbr_free_private(bbr_id); +} + +static int bbr_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + struct bbr_private *bbr_id = ti->private; + struct dm_bio_details *bbr_io; + unsigned long flags; + int rc = 1; + + bio->bi_sector += bbr_id->offset; + + if (atomic_read(&bbr_id->in_use_replacement_blks) == 0 || + !bbr_remap_probe(bbr_id, bio->bi_sector, bio_sectors(bio))) { + /* No existing remaps or this request doesn't + * contain any remapped sectors. + */ + bio->bi_bdev = bbr_id->dev->bdev; + + bbr_io = mempool_alloc(bbr_io_pool, GFP_NOIO); + dm_bio_record(bbr_io, bio); + map_context->ptr = bbr_io; + } else { + /* This request has at least one remapped sector. + * Give it to the work-queue for processing. + */ + map_context->ptr = NULL; + spin_lock_irqsave(&bbr_id->remap_ios_lock, flags); + bio_list_add(&bbr_id->remap_ios, bio); + spin_unlock_irqrestore(&bbr_id->remap_ios_lock, flags); + + queue_work(dm_bbr_wq, &bbr_id->remap_work); + rc = 0; + } + + return rc; +} + +static int bbr_status(struct dm_target *ti, status_type_t type, + char *result, unsigned int maxlen) +{ + struct bbr_private *bbr_id = ti->private; + char b[BDEVNAME_SIZE]; + + switch (type) { + case STATUSTYPE_INFO: + result[0] = '\0'; + break; + + case STATUSTYPE_TABLE: + snprintf(result, maxlen, "%s "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" "PFU64" %u", + format_dev_t(b, bbr_id->dev->bdev->bd_dev), + bbr_id->offset, bbr_id->lba_table1, bbr_id->lba_table2, + bbr_id->nr_sects_bbr_table, + bbr_id->start_replacement_sect, + bbr_id->nr_replacement_blks, + bbr_id->blksize_in_sects << SECTOR_SHIFT); + break; + } + return 0; +} + +static struct target_type bbr_target = { + .name = "bbr", + .version= {1, 0, 1}, + .module = THIS_MODULE, + .ctr = bbr_ctr, + .dtr = bbr_dtr, + .map = bbr_map, + .end_io = bbr_endio, + .status = bbr_status, +}; + +int __init dm_bbr_init(void) +{ + int rc; + + rc = dm_register_target(&bbr_target); + if (rc) { + DMERR("error registering target."); + goto err1; + } + + bbr_remap_cache = kmem_cache_create("bbr-remap", + sizeof(struct bbr_runtime_remap), + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!bbr_remap_cache) { + DMERR("error creating remap cache."); + rc = ENOMEM; + goto err2; + } + + bbr_io_cache = kmem_cache_create("bbr-io", sizeof(struct dm_bio_details), + 0, SLAB_HWCACHE_ALIGN, NULL); + if (!bbr_io_cache) { + DMERR("error creating io cache."); + rc = ENOMEM; + goto err3; + } + + bbr_io_pool = mempool_create(256, mempool_alloc_slab, + mempool_free_slab, bbr_io_cache); + if (!bbr_io_pool) { + DMERR("error creating io mempool."); + rc = ENOMEM; + goto err4; + } + + dm_bbr_wq = create_workqueue("dm-bbr"); + if (!dm_bbr_wq) { + DMERR("error creating work-queue."); + rc = ENOMEM; + goto err5; + } + + return 0; + +err5: + mempool_destroy(bbr_io_pool); +err4: + kmem_cache_destroy(bbr_io_cache); +err3: + kmem_cache_destroy(bbr_remap_cache); +err2: + dm_unregister_target(&bbr_target); +err1: + return rc; +} + +void __exit dm_bbr_exit(void) +{ + destroy_workqueue(dm_bbr_wq); + mempool_destroy(bbr_io_pool); + kmem_cache_destroy(bbr_io_cache); + kmem_cache_destroy(bbr_remap_cache); + dm_unregister_target(&bbr_target); +} + +module_init(dm_bbr_init); +module_exit(dm_bbr_exit); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/misc/Kconfig +++ linux-2.6.28/ubuntu/misc/Kconfig @@ -0,0 +1,35 @@ +config USB_APPLEIR + tristate "Apple USB Infrared Receiver" + default m + depends on USB + +config BLK_DEV_DM_BBR + tristate "Bad-block-relocation target for device-mapper" + default m + depends on BLK_DEV_DM + +config INPUT_ACERHK + tristate "Acer Travelmate laptop special key support" + default m + depends on X86_32 + +config FSAM7400 + tristate "SW RF kill switch for Fujitsu Siemens Amilo M 7400" + default m + +config LMPCM_USB + tristate "USB Logitech MediaPlay Cordless Mouse driver" + default m + depends on USB + +config TP_SMAPI + tristate "ThinkPad SMAPI Support" + default m + +config TP_SMAPI_EC + tristate "ThinkPad embedded controller LPC3 functions" + default m + +source "ubuntu/misc/media/Kconfig" + +source "ubuntu/misc/wireless/Kconfig" --- linux-2.6.28.orig/ubuntu/misc/acerhk.h +++ linux-2.6.28/ubuntu/misc/acerhk.h @@ -0,0 +1,91 @@ +#ifndef __ACERHK_H__ +#define __ACERHK_H__ + +#include + +#define ACERHK_MINOR MISC_DYNAMIC_MINOR + +#define ACERHK_GET_KEYCOUNT _IOR('p', 0x01, char) /* Get number of cached key presses */ +#define ACERHK_GET_KEYID _IOR('p', 0x02, char) /* Get first key in queue */ +#define ACERHK_CONNECT _IO('p', 0x03) /* ? */ +#define ACERHK_DISCONNECT _IO('p', 0x04) /* ? */ +#define ACERHK_GET_THERMAL_EVENT _IOR('p', 0x05, short) /* ? */ +#define ACERHK_MAIL_LED_OFF _IO('p', 0x10) /* switch mail LED off */ +#define ACERHK_MAIL_LED_ON _IO('p', 0x11) /* switch mail LED on (blinking) */ +#define ACERHK_START_POLLING _IO('p', 0x12) /* poll keys in kernel, send real key events */ +#define ACERHK_STOP_POLLING _IO('p', 0x13) /* stop key polling in kernel */ +#define ACERHK_GET_KEY_MAP _IOR('p', 0x20, int) /* Get mapping of key names to key events, */ +#define ACERHK_SET_KEY_MAP _IOW('p', 0x21, int) /* Set mapping of key names to key events */ + +/* all possible keys (known to me) */ +typedef enum e_key_names { + k_none = 0, + k_help = 1, /* Fn+F1 */ + k_setup = 2, /* Fn+F2 */ + k_p1 = 3, + k_p2 = 4, + k_p3 = 5, + k_www = 6, + k_mail = 7, + k_wireless = 8, + k_power = 9, /* Fn+F3 */ + k_mute = 10, /* Fn+F8 */ + k_volup = 11, /* Fn+Up */ + k_voldn = 12, /* Fn+Down */ + k_res = 13, /* resolution change on Medion MD 40100 */ + k_close = 14, /* if lid is closed in tablet mode */ + k_open = 15, /* if lid is opend in tablet mode */ + k_wireless2 = 16, /* second wireless button on TM 243LC */ + k_play = 17, /* Play/Pause found on AOpen */ + k_stop = 18, /* Stop/Eject found on AOpen */ + k_prev = 19, /* Prev found on AOpen */ + k_next = 20, /* Next found on AOpen */ + k_display = 21 /* Change internal/external display on MD 42200 */ +} t_key_names; +#define NR_KEY_NAMES 22 +typedef unsigned int t_map_name2event[NR_KEY_NAMES]; + +#ifdef __KERNEL__ + +/* available features */ +#define TM_F_WLAN_EC1 0x00000010 +#define TM_F_BLUE_EC1 0x00000020 +#define TM_F_WLAN_EC2 0x00000040 +#define TM_F_BLUE_EC2 0x00000080 +#define TM_F_MUTE_LED_EC 0x00001000 +#define TM_F_MAIL_LED 0x00010000 +#define TM_F_MAIL_LED_EC 0x00020000 +#define TM_F_MAIL_LED_EC2 0x00040000 +#define TM_F_MAIL_LED_EC3 0x00080000 + +#define TM_F_CONNECT 0x00100000 +#define TM_F_THERMAL 0x00200000 +#define TM_F_PBUTTON 0x00400000 +#define TM_F_WBUTTON 0x00800000 + +typedef enum acer_type { + TM_unknown, + /* 200, 210, 520, 600 and 730 series, Medion MD42200 */ + TM_old, + /* C100, C110, 220, 230, 240, 260, 350, 360, 610, 620, 630, 740 series + Medion MD40100, Aspire 1600, FS Amilo */ + TM_new, + /* Aspire 13xx, 14xx, 1700, TM 290, 650, 660, 800 */ + TM_dritek +} t_acer_type; + +struct register_buffer { + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + unsigned int edi; + unsigned int esi; + unsigned int ebp; +}; + +typedef asmlinkage void (*bios_call) (struct register_buffer *); + +#endif + +#endif --- linux-2.6.28.orig/ubuntu/misc/lmpcm_usb.c +++ linux-2.6.28/ubuntu/misc/lmpcm_usb.c @@ -0,0 +1,469 @@ +/* + * Copyright (c) 2004-2005 David Oliveira + * + * USB Logitech MediaPlay Cordless Mouse driver + * + */ + +/* + * 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 + * + * If you need to contact me, you can do it by e-mail, sending a mail + * message to + */ + +#include +#include +#include +#include +#include +#include + +#ifdef BIT +#undef BIT +#endif +#define BIT(x) (1UL<<((x)%BITS_PER_LONG)) +#define LONG(x) ((x)/BITS_PER_LONG) + +#define DRIVER_VERSION "v0.5.5" +#define DRIVER_AUTHOR "David Oliveira " +#define DRIVER_DESC "USB Logitech MediaPlay Cordless Mouse driver" +#define DRIVER_LICENSE "GPL" + +#define GETBIT(v,n) ((v>>(n))&0x01) +#define SETBIT(v,n) (v |= (0x01<<(n))) + +#ifdef SLAB_ATOMIC +# define ATOMIC SLAB_ATOMIC +#else +# define ATOMIC GFP_ATOMIC +#endif + + +/* Module properties */ + +MODULE_AUTHOR ( DRIVER_AUTHOR ); +MODULE_DESCRIPTION ( DRIVER_DESC ); +MODULE_LICENSE ( DRIVER_LICENSE ); + + +/* Own type */ + +typedef struct usb_lmpcm { + + // Device name + + char name[128]; + + // USB interrupt data + + signed char *data; + + char phys[64]; + + dma_addr_t data_dma; + + // USB device + + struct usb_device *usbdev; + + // Input device + + struct input_dev *inputdev; + + // USB Request block + + struct urb *urb; + + // Number of openned times + + int open; + +} lmpcm_t; + + +// Initialize lmpcm structure + +void lmpcm_init ( lmpcm_t *lmpcm ) { + + memset(lmpcm, 0, sizeof(lmpcm_t)); + lmpcm->inputdev = NULL; + lmpcm->urb = NULL; + lmpcm->data = NULL; + +} + + +// Free lmpcm buffers + +void lmpcm_free ( lmpcm_t *lmpcm ) { + + if ( lmpcm->urb ) + usb_free_urb(lmpcm->urb); + + if ( lmpcm->data ) + usb_buffer_free(lmpcm->usbdev,8,lmpcm->data,lmpcm->data_dma); + + kfree(lmpcm); + +} + + +// Create new lmpcm (buffer allocation + +lmpcm_t *lmpcm_new ( struct usb_device *dev ) { + + lmpcm_t *lmpcm; + + // Create object + + if (!(lmpcm = kmalloc(sizeof(lmpcm_t), GFP_KERNEL))) + return NULL; + + // Initialize + + lmpcm_init(lmpcm); + + + // Input device + + if ( (lmpcm->inputdev = input_allocate_device()) == NULL ) { + lmpcm_free(lmpcm); + return NULL; + } + + + // Create urb handler + + if (!(lmpcm->urb = usb_alloc_urb(0, GFP_KERNEL))) { + lmpcm_free(lmpcm); + return NULL; + } + + + // Create data required for urb transfer + + if (!(lmpcm->data = usb_buffer_alloc(dev,8,ATOMIC,&lmpcm->data_dma))) { + lmpcm_free(lmpcm); + return NULL; + } + + + // Set lmpcm usb device + + lmpcm->usbdev = dev; + + + return lmpcm; + +} + + + + + +// Get data from urb and send to input API + +void input_send_data ( struct input_dev *dev, char *data ) { + + char + btn = data[0], // Basic buttons (left, right, middle, side and extra) + mbtn = data[6], // Media buttons + x = data[1], // X movement + y = data[2], // Y movement + w = data[3]; // Wheel movement + + + input_report_key(dev, BTN_LEFT, GETBIT(btn,0)); + input_report_key(dev, BTN_RIGHT, GETBIT(btn,1)); + input_report_key(dev, BTN_MIDDLE, GETBIT(btn,2)); + input_report_key(dev, BTN_SIDE, GETBIT(btn,3)); + input_report_key(dev, BTN_EXTRA, GETBIT(btn,4)); + input_report_key(dev, KEY_PLAYCD, GETBIT(btn,5)); + input_report_key(dev, KEY_BACK, GETBIT(btn,6)); + input_report_key(dev, KEY_FORWARD, GETBIT(btn,7)); + + input_report_key(dev, KEY_VOLUMEUP, GETBIT(mbtn,0)); + input_report_key(dev, KEY_VOLUMEDOWN, GETBIT(mbtn,1)); + input_report_key(dev, KEY_NEXTSONG, GETBIT(mbtn,2)); + input_report_key(dev, KEY_PREVIOUSSONG, GETBIT(mbtn,3)); + input_report_key(dev, KEY_PLAYPAUSE, GETBIT(mbtn,4)); + + input_report_rel(dev, REL_X, x); + input_report_rel(dev, REL_Y, y); + input_report_rel(dev, REL_WHEEL, w); + +} + +static void usb_lmpcm_handle(struct urb *urb) { + + lmpcm_t *mouse = urb->context; + signed char *data = mouse->data; + struct input_dev *inputdev = mouse->inputdev; + + + // Check returned status + + if (urb->status) return ; + + + // Send data to input interface + + input_send_data(inputdev,data); + + input_sync(inputdev); + usb_submit_urb(urb,ATOMIC); + +} + +static int usb_lmpcm_open(struct input_dev *dev) { + + lmpcm_t *mouse = (lmpcm_t *)input_get_drvdata(dev); + + if (mouse->open++) + return 0; + + mouse->urb->dev = mouse->usbdev; + + if (usb_submit_urb(mouse->urb, GFP_KERNEL)) { + mouse->open--; + return -EIO; + } + + return 0; + +} + +static void usb_lmpcm_close(struct input_dev *dev) { + + lmpcm_t *mouse = (lmpcm_t *)input_get_drvdata(dev); + + if (!--mouse->open) + usb_kill_urb(mouse->urb); + +} + +static void input_device_init ( struct input_dev *inputdev, struct usb_interface *intf, void *private, struct usb_device *dev ) { + + char path[64]; + + lmpcm_t *mouse = (lmpcm_t *) private; + + int + x, + keys[] = { KEY_PLAYPAUSE, KEY_BACK, KEY_FORWARD, KEY_PLAYCD, KEY_VOLUMEUP, KEY_VOLUMEDOWN, + KEY_NEXTSONG, KEY_PREVIOUSSONG, 0 }; + + + // Events + + inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); + + // Add special keys + + for ( x = 0 ; keys[x] ; x++ ) + set_bit(keys[x],inputdev->keybit); + + // Add basic buttons + + inputdev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT) | BIT(BTN_MIDDLE) | + BIT(BTN_SIDE) | BIT(BTN_EXTRA); + + // Add move mouse movement (X/Y) + + inputdev->relbit[0] = BIT(REL_X) | BIT(REL_Y); + + // Add wheel + + inputdev->relbit[0] |= BIT(REL_WHEEL); + + + // Private data structure + + input_set_drvdata(inputdev, mouse); + + // Input file operations + + inputdev->open = usb_lmpcm_open; + inputdev->close = usb_lmpcm_close; + + // Device + + inputdev->name = mouse->name; + + usb_make_path(dev,path,64); + snprintf(mouse->phys,64,"%s/input0",path); + + inputdev->phys = mouse->phys; + inputdev->id.bustype = BUS_USB; + inputdev->id.vendor = dev->descriptor.idVendor; + inputdev->id.product = dev->descriptor.idProduct; + inputdev->id.version = dev->descriptor.bcdDevice; + +} + +static int usb_lmpcm_probe(struct usb_interface *intf, const struct usb_device_id *id) { + + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_host_interface *interface; + + + struct usb_endpoint_descriptor *endpoint; + lmpcm_t *mouse; + int pipe, maxp; + char *buf; + + + // Get mouse endpoint + + interface = intf->cur_altsetting; + + if ( interface->desc.bNumEndpoints != 1 ) return -ENODEV; + endpoint = &interface->endpoint[0].desc; + + + // Check endpoint + + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) + return -ENODEV; + + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) + return -ENODEV; + + + // Create endpoint pipe + + pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); + maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); + + + // Create lmpcm object + + if (!(mouse = lmpcm_new(dev))) + return -ENOMEM; + + // Initialize input device + + input_device_init(mouse->inputdev,intf,mouse,dev); + + + // Set device name + + if (!(buf = kmalloc(63, GFP_KERNEL))) { + lmpcm_free(mouse); + return -ENOMEM; + } + + + if (dev->descriptor.iManufacturer && + usb_string(dev, dev->descriptor.iManufacturer, buf, 63) > 0) + strcat(mouse->name, buf); + + if (dev->descriptor.iProduct && + usb_string(dev, dev->descriptor.iProduct, buf, 63) > 0) + sprintf(mouse->name, "%s %s", mouse->name, buf); + + if (!strlen(mouse->name)) + sprintf(mouse->name, "lmpcm_usb.c: Logitech MediaPlay Mouse on usb%04x:%04x", + mouse->inputdev->id.vendor, mouse->inputdev->id.product); + + kfree(buf); + + + // Initialize interrupt transfer + + usb_fill_int_urb(mouse->urb,dev,pipe,mouse->data,((maxp > 8)?8:maxp),usb_lmpcm_handle,mouse,endpoint->bInterval); + mouse->urb->transfer_dma = mouse->data_dma; + mouse->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + + // Register input device + + input_register_device(mouse->inputdev); + + + printk(KERN_INFO "lmpcm_usb.c: Detected device: %s\n", mouse->name); + + // Set usb handler interface data + + usb_set_intfdata(intf,mouse); + + + return 0; + +} + + +static void usb_lmpcm_disconnect(struct usb_interface *intf) { + + lmpcm_t *mouse = usb_get_intfdata(intf); + + usb_set_intfdata(intf,NULL); + if (mouse) { + usb_kill_urb(mouse->urb); + input_unregister_device(mouse->inputdev); + lmpcm_free(mouse); + } + +} + + + + +/* Module structures */ + +static struct usb_device_id usb_lmpcm_id_table [] = { + { USB_DEVICE(0x46d, 0xc50e) }, + { } +}; + +MODULE_DEVICE_TABLE (usb, usb_lmpcm_id_table); + +static struct usb_driver usb_lmpcm_driver = { + + .name = "lmpcm_usb", + .probe = usb_lmpcm_probe, + .disconnect = usb_lmpcm_disconnect, + .id_table = usb_lmpcm_id_table + +}; + + + +/* Module main functions */ + +static int __init usb_lmpcm_init(void) { + + int rv; + + // Register usb driver + + rv = usb_register(&usb_lmpcm_driver); + + info(DRIVER_VERSION ":" DRIVER_DESC); + + return rv; +} + +static void __exit usb_lmpcm_exit(void) { + + usb_deregister(&usb_lmpcm_driver); + +} + +// Set + +module_init(usb_lmpcm_init); +module_exit(usb_lmpcm_exit); --- linux-2.6.28.orig/ubuntu/misc/tp_smapi.c +++ linux-2.6.28/ubuntu/misc/tp_smapi.c @@ -0,0 +1,1477 @@ +/* + * tp_smapi.c - ThinkPad SMAPI support + * + * This driver exposes some features of the System Management Application + * Program Interface (SMAPI) BIOS found on ThinkPad laptops. It works on + * models in which the SMAPI BIOS runs in SMM and is invoked by writing + * to the APM control port 0xB2. Older models use a different interface; + * for those, try the out-of-tree "thinkpad" module from "tpctl". + * It also exposes battery status information, obtained from the ThinkPad + * embedded controller (via the thinkpad_ec module). + * + * Many of the battery status values obtained from the EC simply mirror + * values provided by the battery's Smart Battery System (SBS) interface, so + * their meaning is defined by the Smart Battery Data Specification. + * References to this SBS spec are given in the code where relevant. + * + * Copyright (C) 2006 Shem Multinymous . + * SMAPI access code based on the mwave driver by Mike Sullivan. + * + * 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 /* CMOS defines */ +#include +#include +#include "thinkpad_ec.h" +#include +#include +#include + +#define TP_VERSION "0.37" +#define TP_DESC "ThinkPad SMAPI Support" +#define TP_DIR "smapi" + +MODULE_AUTHOR("Shem Multinymous"); +MODULE_DESCRIPTION(TP_DESC); +MODULE_VERSION(TP_VERSION); +MODULE_LICENSE("GPL"); + +static struct platform_device *pdev; + +static int tp_debug; +module_param_named(debug, tp_debug, int, 0600); +MODULE_PARM_DESC(debug, "Debug level (0=off, 1=on)"); + +/* A few macros for printk()ing: */ +#define TPRINTK(level, fmt, args...) \ + dev_printk(level, &(pdev->dev), "%s: " fmt "\n", __func__, ## args) +#define DPRINTK(fmt, args...) \ + do { if (tp_debug) TPRINTK(KERN_DEBUG, fmt, ## args); } while (0) + +/********************************************************************* + * SMAPI interface + */ + +/* SMAPI functions (register BX when making the SMM call). */ +#define SMAPI_GET_INHIBIT_CHARGE 0x2114 +#define SMAPI_SET_INHIBIT_CHARGE 0x2115 +#define SMAPI_GET_THRESH_START 0x2116 +#define SMAPI_SET_THRESH_START 0x2117 +#define SMAPI_GET_FORCE_DISCHARGE 0x2118 +#define SMAPI_SET_FORCE_DISCHARGE 0x2119 +#define SMAPI_GET_THRESH_STOP 0x211a +#define SMAPI_SET_THRESH_STOP 0x211b + +/* SMAPI error codes (see ThinkPad 770 Technical Reference Manual p.83 at + http://www-307.ibm.com/pc/support/site.wss/document.do?lndocid=PFAN-3TUQQD */ +#define SMAPI_RETCODE_EOF 0xff +static struct { u8 rc; char *msg; int ret; } smapi_retcode[] = +{ + {0x00, "OK", 0}, + {0x53, "SMAPI fuction is not available", -ENXIO}, + {0x81, "Invalid parameter", -EINVAL}, + {0x86, "Function is not supported by SMAPI BIOS", -EOPNOTSUPP}, + {0x90, "System error", -EIO}, + {0x91, "System is invalid", -EIO}, + {0x92, "System is busy, -EBUSY"}, + {0xa0, "Device error (disk read error)", -EIO}, + {0xa1, "Device is busy", -EBUSY}, + {0xa2, "Device is not attached", -ENXIO}, + {0xa3, "Device is disbled", -EIO}, + {0xa4, "Request parameter is out of range", -EINVAL}, + {0xa5, "Request parameter is not accepted", -EINVAL}, + {0xa6, "Transient error", -EBUSY}, /* ? */ + {SMAPI_RETCODE_EOF, "Unknown error code", -EIO} +}; + + +#define SMAPI_MAX_RETRIES 10 +#define SMAPI_PORT2 0x4F /* fixed port, meaning unclear */ +static unsigned short smapi_port; /* APM control port, normally 0xB2 */ + +static DECLARE_MUTEX(smapi_mutex); + +/** + * find_smapi_port - read SMAPI port from NVRAM + */ +static int __init find_smapi_port(void) +{ + u16 smapi_id = 0; + unsigned short port = 0; + unsigned long flags; + + spin_lock_irqsave(&rtc_lock, flags); + smapi_id = CMOS_READ(0x7C); + smapi_id |= (CMOS_READ(0x7D) << 8); + spin_unlock_irqrestore(&rtc_lock, flags); + + if (smapi_id != 0x5349) { + printk(KERN_ERR "SMAPI not supported (ID=0x%x)\n", smapi_id); + return -ENXIO; + } + spin_lock_irqsave(&rtc_lock, flags); + port = CMOS_READ(0x7E); + port |= (CMOS_READ(0x7F) << 8); + spin_unlock_irqrestore(&rtc_lock, flags); + if (port == 0) { + printk(KERN_ERR "unable to read SMAPI port number\n"); + return -ENXIO; + } + return port; +} + +/** + * smapi_request - make a SMAPI call + * @inEBX, @inECX, @inEDI, @inESI: input registers + * @outEBX, @outECX, @outEDX, @outEDI, @outESI: outputs registers + * @msg: textual error message + * Invokes the SMAPI SMBIOS with the given input and outpu args. + * All outputs are optional (can be %NULL). + * Returns 0 when successful, and a negative errno constant + * (see smapi_retcode above) upon failure. + */ +static int smapi_request(u32 inEBX, u32 inECX, + u32 inEDI, u32 inESI, + u32 *outEBX, u32 *outECX, u32 *outEDX, + u32 *outEDI, u32 *outESI, const char **msg) +{ + int ret = 0; + int i; + int retries; + u8 rc; + /* Must use local vars for output regs, due to reg pressure. */ + u32 tmpEAX, tmpEBX, tmpECX, tmpEDX, tmpEDI, tmpESI; + + for (retries = 0; retries < SMAPI_MAX_RETRIES; ++retries) { + DPRINTK("req_in: BX=%x CX=%x DI=%x SI=%x", + inEBX, inECX, inEDI, inESI); + + /* SMAPI's SMBIOS call and thinkpad_ec end up using use + * different interfaces to the same chip, so play it safe. */ + ret = thinkpad_ec_lock(); + if (ret) + return ret; + + __asm__ __volatile__( + "movl $0x00005380,%%eax\n\t" + "movl %6,%%ebx\n\t" + "movl %7,%%ecx\n\t" + "movl %8,%%edi\n\t" + "movl %9,%%esi\n\t" + "xorl %%edx,%%edx\n\t" + "movw %10,%%dx\n\t" + "out %%al,%%dx\n\t" /* trigger SMI to SMBIOS */ + "out %%al,$0x4F\n\t" + "movl %%eax,%0\n\t" + "movl %%ebx,%1\n\t" + "movl %%ecx,%2\n\t" + "movl %%edx,%3\n\t" + "movl %%edi,%4\n\t" + "movl %%esi,%5\n\t" + :"=m"(tmpEAX), + "=m"(tmpEBX), + "=m"(tmpECX), + "=m"(tmpEDX), + "=m"(tmpEDI), + "=m"(tmpESI) + :"m"(inEBX), "m"(inECX), "m"(inEDI), "m"(inESI), + "m"((u16)smapi_port) + :"%eax", "%ebx", "%ecx", "%edx", "%edi", + "%esi"); + + thinkpad_ec_invalidate(); + thinkpad_ec_unlock(); + + /* Don't let the next SMAPI access happen too quickly, + * may case problems. (We're hold smapi_mutex). */ + msleep(50); + + if (outEBX) *outEBX = tmpEBX; + if (outECX) *outECX = tmpECX; + if (outEDX) *outEDX = tmpEDX; + if (outESI) *outESI = tmpESI; + if (outEDI) *outEDI = tmpEDI; + + /* Look up error code */ + rc = (tmpEAX>>8)&0xFF; + for (i = 0; smapi_retcode[i].rc != SMAPI_RETCODE_EOF && + smapi_retcode[i].rc != rc; ++i) {} + ret = smapi_retcode[i].ret; + if (msg) + *msg = smapi_retcode[i].msg; + + DPRINTK("req_out: AX=%x BX=%x CX=%x DX=%x DI=%x SI=%x r=%d", + tmpEAX, tmpEBX, tmpECX, tmpEDX, tmpEDI, tmpESI, ret); + if (ret) + TPRINTK(KERN_NOTICE, "SMAPI error: %s (func=%x)", + smapi_retcode[i].msg, inEBX); + + if (ret != -EBUSY) + return ret; + } + return ret; +} + +/* Convenience wrapper: discard output arguments */ +static int smapi_write(u32 inEBX, u32 inECX, + u32 inEDI, u32 inESI, const char **msg) +{ + return smapi_request(inEBX, inECX, inEDI, inESI, + NULL, NULL, NULL, NULL, NULL, msg); +} + + +/********************************************************************* + * Specific SMAPI services + * All of these functions return 0 upon success, and a negative errno + * constant (see smapi_retcode) on failure. + */ + +enum thresh_type { + THRESH_STOP = 0, /* the code assumes this is 0 for brevity */ + THRESH_START +}; +#define THRESH_NAME(which) ((which == THRESH_START) ? "start" : "stop") + +/** + * __get_real_thresh - read battery charge start/stop threshold from SMAPI + * @bat: battery number (0 or 1) + * @which: THRESH_START or THRESH_STOP + * @thresh: 1..99, 0=default 1..99, 0=default (pass this as-is to SMAPI) + * @outEDI: some additional state that needs to be preserved, meaning unknown + * @outESI: some additional state that needs to be preserved, meaning unknown + */ +static int __get_real_thresh(int bat, enum thresh_type which, int *thresh, + u32 *outEDI, u32 *outESI) +{ + u32 ebx = (which == THRESH_START) ? SMAPI_GET_THRESH_START + : SMAPI_GET_THRESH_STOP; + u32 ecx = (bat+1)<<8; + const char *msg; + int ret = smapi_request(ebx, ecx, 0, 0, NULL, + &ecx, NULL, outEDI, outESI, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "cannot get %s_thresh of bat=%d: %s", + THRESH_NAME(which), bat, msg); + return ret; + } + if (!(ecx&0x00000100)) { + TPRINTK(KERN_NOTICE, "cannot get %s_thresh of bat=%d: ecx=0%x", + THRESH_NAME(which), bat, ecx); + return -EIO; + } + if (thresh) + *thresh = ecx&0xFF; + return 0; +} + +/** + * get_real_thresh - read battery charge start/stop threshold from SMAPI + * @bat: battery number (0 or 1) + * @which: THRESH_START or THRESH_STOP + * @thresh: 1..99, 0=default (passes as-is to SMAPI) + */ +static int get_real_thresh(int bat, enum thresh_type which, int *thresh) +{ + return __get_real_thresh(bat, which, thresh, NULL, NULL); +} + +/** + * set_real_thresh - write battery start/top charge threshold to SMAPI + * @bat: battery number (0 or 1) + * @which: THRESH_START or THRESH_STOP + * @thresh: 1..99, 0=default (passes as-is to SMAPI) + */ +static int set_real_thresh(int bat, enum thresh_type which, int thresh) +{ + u32 ebx = (which == THRESH_START) ? SMAPI_SET_THRESH_START + : SMAPI_SET_THRESH_STOP; + u32 ecx = ((bat+1)<<8) + thresh; + u32 getDI, getSI; + const char *msg; + int ret; + + /* verify read before writing */ + ret = __get_real_thresh(bat, which, NULL, &getDI, &getSI); + if (ret) + return ret; + + ret = smapi_write(ebx, ecx, getDI, getSI, &msg); + if (ret) + TPRINTK(KERN_NOTICE, "set %s to %d for bat=%d failed: %s", + THRESH_NAME(which), thresh, bat, msg); + else + TPRINTK(KERN_INFO, "set %s to %d for bat=%d", + THRESH_NAME(which), thresh, bat); + return ret; +} + +/** + * __get_inhibit_charge_minutes - get inhibit charge period from SMAPI + * @bat: battery number (0 or 1) + * @minutes: period in minutes (1..65535 minutes, 0=disabled) + * @outECX: some additional state that needs to be preserved, meaning unknown + * Note that @minutes is the originally set value, it does not count down. + */ +static int __get_inhibit_charge_minutes(int bat, int *minutes, u32 *outECX) +{ + u32 ecx = (bat+1)<<8; + u32 esi; + const char *msg; + int ret = smapi_request(SMAPI_GET_INHIBIT_CHARGE, ecx, 0, 0, + NULL, &ecx, NULL, NULL, &esi, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "failed for bat=%d: %s", bat, msg); + return ret; + } + if (!(ecx&0x0100)) { + TPRINTK(KERN_NOTICE, "bad ecx=0x%x for bat=%d", ecx, bat); + return -EIO; + } + if (minutes) + *minutes = (ecx&0x0001)?esi:0; + if (outECX) + *outECX = ecx; + return 0; +} + +/** + * get_inhibit_charge_minutes - get inhibit charge period from SMAPI + * @bat: battery number (0 or 1) + * @minutes: period in minutes (1..65535 minutes, 0=disabled) + * Note that @minutes is the originally set value, it does not count down. + */ +static int get_inhibit_charge_minutes(int bat, int *minutes) +{ + return __get_inhibit_charge_minutes(bat, minutes, NULL); +} + +/** + * set_inhibit_charge_minutes - write inhibit charge period to SMAPI + * @bat: battery number (0 or 1) + * @minutes: period in minutes (1..65535 minutes, 0=disabled) + */ +static int set_inhibit_charge_minutes(int bat, int minutes) +{ + u32 ecx; + const char *msg; + int ret; + + /* verify read before writing */ + ret = __get_inhibit_charge_minutes(bat, NULL, &ecx); + if (ret) + return ret; + + ecx = ((bat+1)<<8) | (ecx&0x00FE) | (minutes > 0 ? 0x0001 : 0x0000); + if (minutes > 0xFFFF) + minutes = 0xFFFF; + ret = smapi_write(SMAPI_SET_INHIBIT_CHARGE, ecx, 0, minutes, &msg); + if (ret) + TPRINTK(KERN_NOTICE, + "set to %d failed for bat=%d: %s", minutes, bat, msg); + else + TPRINTK(KERN_INFO, "set to %d for bat=%d\n", minutes, bat); + return ret; +} + + +/** + * get_force_discharge - get status of forced discharging from SMAPI + * @bat: battery number (0 or 1) + * @enabled: 1 if forced discharged is enabled, 0 if not + */ +static int get_force_discharge(int bat, int *enabled) +{ + u32 ecx = (bat+1)<<8; + const char *msg; + int ret = smapi_request(SMAPI_GET_FORCE_DISCHARGE, ecx, 0, 0, + NULL, &ecx, NULL, NULL, NULL, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "failed for bat=%d: %s", bat, msg); + return ret; + } + *enabled = (!(ecx&0x00000100) && (ecx&0x00000001))?1:0; + return 0; +} + +/** + * set_force_discharge - write status of forced discharging to SMAPI + * @bat: battery number (0 or 1) + * @enabled: 1 if forced discharged is enabled, 0 if not + */ +static int set_force_discharge(int bat, int enabled) +{ + u32 ecx = (bat+1)<<8; + const char *msg; + int ret = smapi_request(SMAPI_GET_FORCE_DISCHARGE, ecx, 0, 0, + NULL, &ecx, NULL, NULL, NULL, &msg); + if (ret) { + TPRINTK(KERN_NOTICE, "get failed for bat=%d: %s", bat, msg); + return ret; + } + if (ecx&0x00000100) { + TPRINTK(KERN_NOTICE, "cannot force discharge bat=%d", bat); + return -EIO; + } + + ecx = ((bat+1)<<8) | (ecx&0x000000FA) | (enabled?0x00000001:0); + ret = smapi_write(SMAPI_SET_FORCE_DISCHARGE, ecx, 0, 0, &msg); + if (ret) + TPRINTK(KERN_NOTICE, "set to %d failed for bat=%d: %s", + enabled, bat, msg); + else + TPRINTK(KERN_INFO, "set to %d for bat=%d", enabled, bat); + return ret; +} + + +/********************************************************************* + * Wrappers to threshold-related SMAPI functions, which handle default + * thresholds and related quirks. + */ + +/* Minimum, default and minimum difference for battery charging thresholds: */ +#define MIN_THRESH_DELTA 4 /* Min delta between start and stop thresh */ +#define MIN_THRESH_START 2 +#define MAX_THRESH_START (100-MIN_THRESH_DELTA) +#define MIN_THRESH_STOP (MIN_THRESH_START + MIN_THRESH_DELTA) +#define MAX_THRESH_STOP 100 +#define DEFAULT_THRESH_START MAX_THRESH_START +#define DEFAULT_THRESH_STOP MAX_THRESH_STOP + +/* The GUI of IBM's Battery Maximizer seems to show a start threshold that + * is 1 more than the value we set/get via SMAPI. Since the threshold is + * maintained across reboot, this can be confusing. So we kludge our + * interface for interoperability: */ +#define BATMAX_FIX 1 + +/* Get charge start/stop threshold (1..100), + * substituting default values if needed and applying BATMAT_FIX. */ +static int get_thresh(int bat, enum thresh_type which, int *thresh) +{ + int ret = get_real_thresh(bat, which, thresh); + if (ret) + return ret; + if (*thresh == 0) + *thresh = (which == THRESH_START) ? DEFAULT_THRESH_START + : DEFAULT_THRESH_STOP; + else if (which == THRESH_START) + *thresh += BATMAX_FIX; + return 0; +} + + +/* Set charge start/stop threshold (1..100), + * substituting default values if needed and applying BATMAT_FIX. */ +static int set_thresh(int bat, enum thresh_type which, int thresh) +{ + if (which == THRESH_STOP && thresh == DEFAULT_THRESH_STOP) + thresh = 0; /* 100 is out of range, but default means 100 */ + if (which == THRESH_START) + thresh -= BATMAX_FIX; + return set_real_thresh(bat, which, thresh); +} + +/********************************************************************* + * ThinkPad embedded controller readout and basic functions + */ + +/** + * read_tp_ec_row - read data row from the ThinkPad embedded controller + * @arg0: EC command code + * @bat: battery number, 0 or 1 + * @j: the byte value to be used for "junk" (unused) input/outputs + * @dataval: result vector + */ +static int read_tp_ec_row(u8 arg0, int bat, u8 j, u8 *dataval) +{ + int ret; + const struct thinkpad_ec_row args = { .mask = 0xFFFF, + .val = {arg0, j,j,j,j,j,j,j,j,j,j,j,j,j,j, (u8)bat} }; + struct thinkpad_ec_row data = { .mask = 0xFFFF }; + + ret = thinkpad_ec_lock(); + if (ret) + return ret; + ret = thinkpad_ec_read_row(&args, &data); + thinkpad_ec_unlock(); + memcpy(dataval, &data.val, TP_CONTROLLER_ROW_LEN); + return ret; +} + +/** + * power_device_present - check for presence of battery or AC power + * @bat: 0 for battery 0, 1 for battery 1, otherwise AC power + * Returns 1 if present, 0 if not present, negative if error. + */ +static int power_device_present(int bat) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + u8 test; + int ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + switch (bat) { + case 0: test = 0x40; break; /* battery 0 */ + case 1: test = 0x20; break; /* battery 1 */ + default: test = 0x80; /* AC power */ + } + return (row[0] & test) ? 1 : 0; +} + +/** + * bat_has_status - check if battery can report detailed status + * @bat: 0 for battery 0, 1 for battery 1 + * Returns 1 if yes, 0 if no, negative if error. + */ +static int bat_has_status(int bat) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + int ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + if ((row[0] & (bat?0x20:0x40)) == 0) /* no battery */ + return 0; + if ((row[1] & (0x60)) == 0) /* no status */ + return 0; + return 1; +} + +/** + * get_tp_ec_bat_16 - read a 16-bit value from EC battery status data + * @arg0: first argument to EC + * @off: offset in row returned from EC + * @bat: battery (0 or 1) + * @val: the 16-bit value obtained + * Returns nonzero on error. + */ +static int get_tp_ec_bat_16(u8 arg0, int offset, int bat, u16 *val) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + int ret; + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(arg0, bat, 0, row); + if (ret) + return ret; + *val = *(u16 *)(row+offset); + return 0; +} + +/********************************************************************* + * sysfs attributes for batteries - + * definitions and helper functions + */ + +/* A custom device attribute struct which holds a battery number */ +struct bat_device_attribute { + struct device_attribute dev_attr; + int bat; +}; + +/** + * attr_get_bat - get the battery to which the attribute belongs + */ +static int attr_get_bat(struct device_attribute *attr) +{ + return container_of(attr, struct bat_device_attribute, dev_attr)->bat; +} + +/** + * show_tp_ec_bat_u16 - show an unsigned 16-bit battery attribute + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @mul: correction factor to multiply by + * @na_msg: string to output is value not available (0xFFFFFFFF) + * @attr: battery attribute + * @buf: output buffer + * The 16-bit value is read from the EC, treated as unsigned, + * transformed as x->mul*x, and printed to the buffer. + * If the value is 0xFFFFFFFF and na_msg!=%NULL, na_msg is printed instead. + */ +static ssize_t show_tp_ec_bat_u16(u8 arg0, int offset, int mul, + const char *na_msg, + struct device_attribute *attr, char *buf) +{ + u16 val; + int ret = get_tp_ec_bat_16(arg0, offset, attr_get_bat(attr), &val); + if (ret) + return ret; + if (na_msg && val == 0xFFFF) + return sprintf(buf, "%s\n", na_msg); + else + return sprintf(buf, "%u\n", mul*(unsigned int)val); +} + +/** + * show_tp_ec_bat_s16 - show an signed 16-bit battery attribute + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @mul: correction factor to multiply by + * @add: correction term to add after multiplication + * @attr: battery attribute + * @buf: output buffer + * The 16-bit value is read from the EC, treated as signed, + * transformed as x->mul*x+add, and printed to the buffer. + */ +static ssize_t show_tp_ec_bat_s16(u8 arg0, int offset, int mul, int add, + struct device_attribute *attr, char *buf) +{ + u16 val; + int ret = get_tp_ec_bat_16(arg0, offset, attr_get_bat(attr), &val); + if (ret) + return ret; + return sprintf(buf, "%d\n", mul*(s16)val+add); +} + +/** + * show_tp_ec_bat_str - show a string from EC battery status data + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @maxlen: maximum string length + * @attr: battery attribute + * @buf: output buffer + */ +static ssize_t show_tp_ec_bat_str(u8 arg0, int offset, int maxlen, + struct device_attribute *attr, char *buf) +{ + int bat = attr_get_bat(attr); + u8 row[TP_CONTROLLER_ROW_LEN]; + int ret; + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(arg0, bat, 0, row); + if (ret) + return ret; + strncpy(buf, (char *)row+offset, maxlen); + buf[maxlen] = 0; + strcat(buf, "\n"); + return strlen(buf); +} + +/** + * show_tp_ec_bat_power - show a power readout from EC battery status data + * @arg0: specified 1st argument of EC raw to read + * @offV: byte offset of voltage in EC raw data + * @offI: byte offset of current in EC raw data + * @attr: battery attribute + * @buf: output buffer + * Computes the power as current*voltage from the two given readout offsets. + */ +static ssize_t show_tp_ec_bat_power(u8 arg0, int offV, int offI, + struct device_attribute *attr, char *buf) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + int milliamp, millivolt, ret; + int bat = attr_get_bat(attr); + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + millivolt = *(u16 *)(row+offV); + milliamp = *(s16 *)(row+offI); + return sprintf(buf, "%d\n", milliamp*millivolt/1000); /* units: mW */ +} + +/** + * show_tp_ec_bat_date - decode and show a date from EC battery status data + * @arg0: specified 1st argument of EC raw to read + * @offset: byte offset in EC raw data + * @attr: battery attribute + * @buf: output buffer + */ +static ssize_t show_tp_ec_bat_date(u8 arg0, int offset, + struct device_attribute *attr, char *buf) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + u16 v; + int ret; + int day, month, year; + int bat = attr_get_bat(attr); + if (bat_has_status(bat) != 1) + return -ENXIO; + ret = read_tp_ec_row(arg0, bat, 0, row); + if (ret) + return ret; + + /* Decode bit-packed: v = day | (month<<5) | ((year-1980)<<9) */ + v = *(u16 *)(row+offset); + day = v & 0x1F; + month = (v >> 5) & 0xF; + year = (v >> 9) + 1980; + + return sprintf(buf, "%04d-%02d-%02d\n", year, month, day); +} + + +/********************************************************************* + * sysfs attribute I/O for batteries - + * the actual attribute show/store functions + */ + +static ssize_t show_battery_start_charge_thresh(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int thresh; + int bat = attr_get_bat(attr); + int ret = get_thresh(bat, THRESH_START, &thresh); + if (ret) + return ret; + return sprintf(buf, "%d\n", thresh); /* units: percent */ +} + +static ssize_t show_battery_stop_charge_thresh(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int thresh; + int bat = attr_get_bat(attr); + int ret = get_thresh(bat, THRESH_STOP, &thresh); + if (ret) + return ret; + return sprintf(buf, "%d\n", thresh); /* units: percent */ +} + +/** + * store_battery_start_charge_thresh - store battery_start_charge_thresh attr + * Since this is a kernel<->user interface, we ensure a valid state for + * the hardware. We do this by clamping the requested threshold to the + * valid range and, if necessary, moving the other threshold so that + * it's MIN_THRESH_DELTA away from this one. + */ +static ssize_t store_battery_start_charge_thresh(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int thresh, other_thresh, ret; + int bat = attr_get_bat(attr); + + if (sscanf(buf, "%d", &thresh) != 1 || thresh < 1 || thresh > 100) + return -EINVAL; + + if (thresh < MIN_THRESH_START) /* clamp up to MIN_THRESH_START */ + thresh = MIN_THRESH_START; + if (thresh > MAX_THRESH_START) /* clamp down to MAX_THRESH_START */ + thresh = MAX_THRESH_START; + + down(&smapi_mutex); + ret = get_thresh(bat, THRESH_STOP, &other_thresh); + if (ret != -EOPNOTSUPP) { + if (ret) /* other threshold is set? */ + goto out; + ret = get_real_thresh(bat, THRESH_START, NULL); + if (ret) /* this threshold is set? */ + goto out; + if (other_thresh < thresh+MIN_THRESH_DELTA) { + /* move other thresh to keep it above this one */ + ret = set_thresh(bat, THRESH_STOP, + thresh+MIN_THRESH_DELTA); + if (ret) + goto out; + } + } + ret = set_thresh(bat, THRESH_START, thresh); +out: + up(&smapi_mutex); + return count; + +} + +/** + * store_battery_stop_charge_thresh - store battery_stop_charge_thresh attr + * Since this is a kernel<->user interface, we ensure a valid state for + * the hardware. We do this by clamping the requested threshold to the + * valid range and, if necessary, moving the other threshold so that + * it's MIN_THRESH_DELTA away from this one. + */ +static ssize_t store_battery_stop_charge_thresh(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int thresh, other_thresh, ret; + int bat = attr_get_bat(attr); + + if (sscanf(buf, "%d", &thresh) != 1 || thresh < 1 || thresh > 100) + return -EINVAL; + + if (thresh < MIN_THRESH_STOP) /* clamp up to MIN_THRESH_STOP */ + thresh = MIN_THRESH_STOP; + + down(&smapi_mutex); + ret = get_thresh(bat, THRESH_START, &other_thresh); + if (ret != -EOPNOTSUPP) { /* other threshold exists? */ + if (ret) + goto out; + /* this threshold exists? */ + ret = get_real_thresh(bat, THRESH_STOP, NULL); + if (ret) + goto out; + if (other_thresh >= thresh-MIN_THRESH_DELTA) { + /* move other thresh to be below this one */ + ret = set_thresh(bat, THRESH_START, + thresh-MIN_THRESH_DELTA); + if (ret) + goto out; + } + } + ret = set_thresh(bat, THRESH_STOP, thresh); +out: + up(&smapi_mutex); + return count; +} + +static ssize_t show_battery_inhibit_charge_minutes(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int minutes; + int bat = attr_get_bat(attr); + int ret = get_inhibit_charge_minutes(bat, &minutes); + if (ret) + return ret; + return sprintf(buf, "%d\n", minutes); /* units: minutes */ +} + +static ssize_t store_battery_inhibit_charge_minutes(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int ret; + int minutes; + int bat = attr_get_bat(attr); + if (sscanf(buf, "%d", &minutes) != 1 || minutes < 0) { + TPRINTK(KERN_ERR, "inhibit_charge_minutes: " + "must be a non-negative integer"); + return -EINVAL; + } + ret = set_inhibit_charge_minutes(bat, minutes); + if (ret) + return ret; + return count; +} + +static ssize_t show_battery_force_discharge(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int enabled; + int bat = attr_get_bat(attr); + int ret = get_force_discharge(bat, &enabled); + if (ret) + return ret; + return sprintf(buf, "%d\n", enabled); /* type: boolean */ +} + +static ssize_t store_battery_force_discharge(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + int ret; + int enabled; + int bat = attr_get_bat(attr); + if (sscanf(buf, "%d", &enabled) != 1 || enabled < 0 || enabled > 1) + return -EINVAL; + ret = set_force_discharge(bat, enabled); + if (ret) + return ret; + return count; +} + +static ssize_t show_battery_installed( + struct device *dev, struct device_attribute *attr, char *buf) +{ + int bat = attr_get_bat(attr); + int ret = power_device_present(bat); + if (ret < 0) + return ret; + return sprintf(buf, "%d\n", ret); /* type: boolean */ +} + +static ssize_t show_battery_state( + struct device *dev, struct device_attribute *attr, char *buf) +{ + u8 row[TP_CONTROLLER_ROW_LEN]; + const char *txt; + int ret; + int bat = attr_get_bat(attr); + if (bat_has_status(bat) != 1) + return sprintf(buf, "none\n"); + ret = read_tp_ec_row(1, bat, 0, row); + if (ret) + return ret; + switch (row[1] & 0xf0) { + case 0xc0: txt = "idle"; break; + case 0xd0: txt = "discharging"; break; + case 0xe0: txt = "charging"; break; + default: return sprintf(buf, "unknown (0x%x)\n", row[1]); + } + return sprintf(buf, "%s\n", txt); /* type: string from fixed set */ +} + +static ssize_t show_battery_manufacturer( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string. SBS spec v1.1 p34: ManufacturerName() */ + return show_tp_ec_bat_str(4, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf); +} + +static ssize_t show_battery_model( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string. SBS spec v1.1 p34: DeviceName() */ + return show_tp_ec_bat_str(5, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf); +} + +static ssize_t show_battery_barcoding( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string */ + return show_tp_ec_bat_str(7, 2, TP_CONTROLLER_ROW_LEN-2, attr, buf); +} + +static ssize_t show_battery_chemistry( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: string. SBS spec v1.1 p34-35: DeviceChemistry() */ + return show_tp_ec_bat_str(6, 2, 5, attr, buf); +} + +static ssize_t show_battery_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV. SBS spec v1.1 p24: Voltage() */ + return show_tp_ec_bat_u16(1, 6, 1, NULL, attr, buf); +} + +static ssize_t show_battery_design_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV. SBS spec v1.1 p32: DesignVoltage() */ + return show_tp_ec_bat_u16(3, 4, 1, NULL, attr, buf); +} + +static ssize_t show_battery_charging_max_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV. SBS spec v1.1 p37,39: ChargingVoltage() */ + return show_tp_ec_bat_u16(9, 8, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group0_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 12, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group1_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 10, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group2_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 8, 1, NULL, attr, buf); +} + +static ssize_t show_battery_group3_voltage( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mV */ + return show_tp_ec_bat_u16(0xA, 6, 1, NULL, attr, buf); +} + +static ssize_t show_battery_current_now( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mA. SBS spec v1.1 p24: Current() */ + return show_tp_ec_bat_s16(1, 8, 1, 0, attr, buf); +} + +static ssize_t show_battery_current_avg( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mA. SBS spec v1.1 p24: AverageCurrent() */ + return show_tp_ec_bat_s16(1, 10, 1, 0, attr, buf); +} + +static ssize_t show_battery_charging_max_current( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mA. SBS spec v1.1 p36,38: ChargingCurrent() */ + return show_tp_ec_bat_s16(9, 6, 1, 0, attr, buf); +} + +static ssize_t show_battery_power_now( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mW. SBS spec v1.1: Voltage()*Current() */ + return show_tp_ec_bat_power(1, 6, 8, attr, buf); +} + +static ssize_t show_battery_power_avg( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mW. SBS spec v1.1: Voltage()*AverageCurrent() */ + return show_tp_ec_bat_power(1, 6, 10, attr, buf); +} + +static ssize_t show_battery_remaining_percent( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: percent. SBS spec v1.1 p25: RelativeStateOfCharge() */ + return show_tp_ec_bat_u16(1, 12, 1, NULL, attr, buf); +} + +static ssize_t show_battery_remaining_charging_time( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: minutes. SBS spec v1.1 p27: AverageTimeToFull() */ + return show_tp_ec_bat_u16(2, 8, 1, "not_charging", attr, buf); +} + +static ssize_t show_battery_remaining_running_time( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */ + return show_tp_ec_bat_u16(2, 6, 1, "not_discharging", attr, buf); +} + +static ssize_t show_battery_remaining_running_time_now( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: minutes. SBS spec v1.1 p27: RunTimeToEmpty() */ + return show_tp_ec_bat_u16(2, 4, 1, "not_discharging", attr, buf); +} + +static ssize_t show_battery_remaining_capacity( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mWh. SBS spec v1.1 p26. */ + return show_tp_ec_bat_u16(1, 14, 10, "", attr, buf); +} + +static ssize_t show_battery_last_full_capacity( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mWh. SBS spec v1.1 p26: FullChargeCapacity() */ + return show_tp_ec_bat_u16(2, 2, 10, "", attr, buf); +} + +static ssize_t show_battery_design_capacity( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: mWh. SBS spec v1.1 p32: DesignCapacity() */ + return show_tp_ec_bat_u16(3, 2, 10, "", attr, buf); +} + +static ssize_t show_battery_cycle_count( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: ordinal. SBS spec v1.1 p32: CycleCount() */ + return show_tp_ec_bat_u16(2, 12, 1, "", attr, buf); +} + +static ssize_t show_battery_temperature( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* units: millicelsius. SBS spec v1.1: Temperature()*10 */ + return show_tp_ec_bat_s16(1, 4, 100, -273100, attr, buf); +} + +static ssize_t show_battery_serial( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: int. SBS spec v1.1 p34: SerialNumber() */ + return show_tp_ec_bat_u16(3, 10, 1, "", attr, buf); +} + +static ssize_t show_battery_manufacture_date( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: YYYY-MM-DD. SBS spec v1.1 p34: ManufactureDate() */ + return show_tp_ec_bat_date(3, 8, attr, buf); +} + +static ssize_t show_battery_first_use_date( + struct device *dev, struct device_attribute *attr, char *buf) +{ + /* type: YYYY-MM-DD */ + return show_tp_ec_bat_date(8, 2, attr, buf); +} + +/** + * show_battery_dump - show the battery's dump attribute + * The dump attribute gives a hex dump of all EC readouts related to a + * battery. Some of the enumerated values don't really exist (i.e., the + * EC function just leaves them untouched); we use a kludge to detect and + * denote these. + */ +#define MIN_DUMP_ARG0 0x00 +#define MAX_DUMP_ARG0 0x0a /* 0x0b is useful too but hangs old EC firmware */ +static ssize_t show_battery_dump( + struct device *dev, struct device_attribute *attr, char *buf) +{ + int i; + char *p = buf; + int bat = attr_get_bat(attr); + u8 arg0; /* first argument to EC */ + u8 rowa[TP_CONTROLLER_ROW_LEN], + rowb[TP_CONTROLLER_ROW_LEN]; + const u8 junka = 0xAA, + junkb = 0x55; /* junk values for testing changes */ + int ret; + + for (arg0 = MIN_DUMP_ARG0; arg0 <= MAX_DUMP_ARG0; ++arg0) { + if ((p-buf) > PAGE_SIZE-TP_CONTROLLER_ROW_LEN*5) + return -ENOMEM; /* don't overflow sysfs buf */ + /* Read raw twice with different junk values, + * to detect unused output bytes which are left unchaged: */ + ret = read_tp_ec_row(arg0, bat, junka, rowa); + if (ret) + return ret; + ret = read_tp_ec_row(arg0, bat, junkb, rowb); + if (ret) + return ret; + for (i = 0; i < TP_CONTROLLER_ROW_LEN; i++) { + if (rowa[i] == junka && rowb[i] == junkb) + p += sprintf(p, "-- "); /* unused by EC */ + else + p += sprintf(p, "%02x ", rowa[i]); + } + p += sprintf(p, "\n"); + } + return p-buf; +} + + +/********************************************************************* + * sysfs attribute I/O, other than batteries + */ + +static ssize_t show_ac_connected( + struct device *dev, struct device_attribute *attr, char *buf) +{ + int ret = power_device_present(0xFF); + if (ret < 0) + return ret; + return sprintf(buf, "%d\n", ret); /* type: boolean */ +} + +/********************************************************************* + * The the "smapi_request" sysfs attribute executes a raw SMAPI call. + * You write to make a request and read to get the result. The state + * is saved globally rather than per fd (sysfs limitation), so + * simultaenous requests may get each other's results! So this is for + * development and debugging only. + */ +#define MAX_SMAPI_ATTR_ANSWER_LEN 128 +static char smapi_attr_answer[MAX_SMAPI_ATTR_ANSWER_LEN] = ""; + +static ssize_t show_smapi_request(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = snprintf(buf, PAGE_SIZE, "%s", smapi_attr_answer); + smapi_attr_answer[0] = '\0'; + return ret; +} + +static ssize_t store_smapi_request(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int inEBX, inECX, inEDI, inESI; + u32 outEBX, outECX, outEDX, outEDI, outESI; + const char *msg; + int ret; + if (sscanf(buf, "%x %x %x %x", &inEBX, &inECX, &inEDI, &inESI) != 4) { + smapi_attr_answer[0] = '\0'; + return -EINVAL; + } + ret = smapi_request( + inEBX, inECX, inEDI, inESI, + &outEBX, &outECX, &outEDX, &outEDI, &outESI, &msg); + snprintf(smapi_attr_answer, MAX_SMAPI_ATTR_ANSWER_LEN, + "%x %x %x %x %x %d '%s'\n", + (unsigned int)outEBX, (unsigned int)outECX, + (unsigned int)outEDX, (unsigned int)outEDI, + (unsigned int)outESI, ret, msg); + if (ret) + return ret; + else + return count; +} + +/********************************************************************* + * Power management: the embedded controller forgets the battery + * thresholds when the system is suspended to disk and unplugged from + * AC and battery, so we restore it upon resume. + */ + +static int saved_threshs[4] = {-1, -1, -1, -1}; /* -1 = don't know */ + +static int tp_suspend(struct platform_device *dev, pm_message_t state) +{ + if (get_real_thresh(0, THRESH_STOP , &saved_threshs[0])) + saved_threshs[0] = -1; + if (get_real_thresh(0, THRESH_START, &saved_threshs[1])) + saved_threshs[1] = -1; + if (get_real_thresh(1, THRESH_STOP , &saved_threshs[2])) + saved_threshs[2] = -1; + if (get_real_thresh(1, THRESH_START, &saved_threshs[3])) + saved_threshs[3] = -1; + DPRINTK("suspend saved: %d %d %d %d", saved_threshs[0], + saved_threshs[1], saved_threshs[2], saved_threshs[3]); + return 0; +} + +static int tp_resume(struct platform_device *dev) +{ + DPRINTK("resume restoring: %d %d %d %d", saved_threshs[0], + saved_threshs[1], saved_threshs[2], saved_threshs[3]); + if (saved_threshs[0] >= 0) + set_real_thresh(0, THRESH_STOP , saved_threshs[0]); + if (saved_threshs[1] >= 0) + set_real_thresh(0, THRESH_START, saved_threshs[1]); + if (saved_threshs[2] >= 0) + set_real_thresh(1, THRESH_STOP , saved_threshs[2]); + if (saved_threshs[3] >= 0) + set_real_thresh(1, THRESH_START, saved_threshs[3]); + return 0; +} + + +/********************************************************************* + * Driver model + */ + +static struct platform_driver tp_driver = { + .suspend = tp_suspend, + .resume = tp_resume, + .driver = { + .name = "smapi", + .owner = THIS_MODULE + }, +}; + + +/********************************************************************* + * Sysfs device model + */ + +/* Attributes in /sys/devices/platform/smapi/ */ + +static DEVICE_ATTR(ac_connected, 0444, show_ac_connected, NULL); +static DEVICE_ATTR(smapi_request, 0600, show_smapi_request, + store_smapi_request); + +static struct attribute *tp_root_attributes[] = { + &dev_attr_ac_connected.attr, + &dev_attr_smapi_request.attr, + NULL +}; +static struct attribute_group tp_root_attribute_group = { + .attrs = tp_root_attributes +}; + +/* Attributes under /sys/devices/platform/smapi/BAT{0,1}/ : + * Every attribute needs to be defined (i.e., statically allocated) for + * each battery, and then referenced in the attribute list of each battery. + * We use preprocessor voodoo to avoid duplicating the list of attributes 4 + * times. The preprocessor output is just normal sysfs attributes code. + */ + +/** + * FOREACH_BAT_ATTR - invoke the given macros on all our battery attributes + * @_BAT: battery number (0 or 1) + * @_ATTR_RW: macro to invoke for each read/write attribute + * @_ATTR_R: macro to invoke for each read-only attribute + */ +#define FOREACH_BAT_ATTR(_BAT, _ATTR_RW, _ATTR_R) \ + _ATTR_RW(_BAT, start_charge_thresh) \ + _ATTR_RW(_BAT, stop_charge_thresh) \ + _ATTR_RW(_BAT, inhibit_charge_minutes) \ + _ATTR_RW(_BAT, force_discharge) \ + _ATTR_R(_BAT, installed) \ + _ATTR_R(_BAT, state) \ + _ATTR_R(_BAT, manufacturer) \ + _ATTR_R(_BAT, model) \ + _ATTR_R(_BAT, barcoding) \ + _ATTR_R(_BAT, chemistry) \ + _ATTR_R(_BAT, voltage) \ + _ATTR_R(_BAT, group0_voltage) \ + _ATTR_R(_BAT, group1_voltage) \ + _ATTR_R(_BAT, group2_voltage) \ + _ATTR_R(_BAT, group3_voltage) \ + _ATTR_R(_BAT, current_now) \ + _ATTR_R(_BAT, current_avg) \ + _ATTR_R(_BAT, charging_max_current) \ + _ATTR_R(_BAT, power_now) \ + _ATTR_R(_BAT, power_avg) \ + _ATTR_R(_BAT, remaining_percent) \ + _ATTR_R(_BAT, remaining_charging_time) \ + _ATTR_R(_BAT, remaining_running_time) \ + _ATTR_R(_BAT, remaining_running_time_now) \ + _ATTR_R(_BAT, remaining_capacity) \ + _ATTR_R(_BAT, last_full_capacity) \ + _ATTR_R(_BAT, design_voltage) \ + _ATTR_R(_BAT, charging_max_voltage) \ + _ATTR_R(_BAT, design_capacity) \ + _ATTR_R(_BAT, cycle_count) \ + _ATTR_R(_BAT, temperature) \ + _ATTR_R(_BAT, serial) \ + _ATTR_R(_BAT, manufacture_date) \ + _ATTR_R(_BAT, first_use_date) \ + _ATTR_R(_BAT, dump) + +/* Define several macros we will feed into FOREACH_BAT_ATTR: */ + +#define DEFINE_BAT_ATTR_RW(_BAT,_NAME) \ + static struct bat_device_attribute dev_attr_##_NAME##_##_BAT = { \ + .dev_attr = __ATTR(_NAME, 0644, show_battery_##_NAME, \ + store_battery_##_NAME), \ + .bat = _BAT \ + }; + +#define DEFINE_BAT_ATTR_R(_BAT,_NAME) \ + static struct bat_device_attribute dev_attr_##_NAME##_##_BAT = { \ + .dev_attr = __ATTR(_NAME, 0644, show_battery_##_NAME, 0), \ + .bat = _BAT \ + }; + +#define REF_BAT_ATTR(_BAT,_NAME) \ + &dev_attr_##_NAME##_##_BAT.dev_attr.attr, + +/* This provide all attributes for one battery: */ + +#define PROVIDE_BAT_ATTRS(_BAT) \ + FOREACH_BAT_ATTR(_BAT, DEFINE_BAT_ATTR_RW, DEFINE_BAT_ATTR_R) \ + static struct attribute *tp_bat##_BAT##_attributes[] = { \ + FOREACH_BAT_ATTR(_BAT, REF_BAT_ATTR, REF_BAT_ATTR) \ + NULL \ + }; \ + static struct attribute_group tp_bat##_BAT##_attribute_group = { \ + .name = "BAT" #_BAT, \ + .attrs = tp_bat##_BAT##_attributes \ + }; + +/* Finally genereate the attributes: */ + +PROVIDE_BAT_ATTRS(0) +PROVIDE_BAT_ATTRS(1) + +/* List of attribute groups */ + +static struct attribute_group *attr_groups[] = { + &tp_root_attribute_group, + &tp_bat0_attribute_group, + &tp_bat1_attribute_group, + NULL +}; + + +/********************************************************************* + * Init and cleanup + */ + +static struct attribute_group **next_attr_group; /* next to register */ + +static int __init tp_init(void) +{ + int ret; + printk(KERN_INFO "tp_smapi " TP_VERSION " loading...\n"); + + ret = find_smapi_port(); + if (ret < 0) + goto err; + else + smapi_port = ret; + + if (!request_region(smapi_port, 1, "smapi")) { + printk(KERN_ERR "tp_smapi cannot claim port 0x%x\n", + smapi_port); + ret = -ENXIO; + goto err; + } + + if (!request_region(SMAPI_PORT2, 1, "smapi")) { + printk(KERN_ERR "tp_smapi cannot claim port 0x%x\n", + SMAPI_PORT2); + ret = -ENXIO; + goto err_port1; + } + + ret = platform_driver_register(&tp_driver); + if (ret) + goto err_port2; + + pdev = platform_device_alloc("smapi", -1); + if (!pdev) { + ret = -ENOMEM; + goto err_driver; + } + + ret = platform_device_add(pdev); + if (ret) + goto err_device_free; + + for (next_attr_group = attr_groups; *next_attr_group; + ++next_attr_group) { + ret = sysfs_create_group(&pdev->dev.kobj, *next_attr_group); + if (ret) + goto err_attr; + } + + printk(KERN_INFO "tp_smapi successfully loaded (smapi_port=0x%x).\n", + smapi_port); + return 0; + +err_attr: + while (--next_attr_group >= attr_groups) + sysfs_remove_group(&pdev->dev.kobj, *next_attr_group); + platform_device_unregister(pdev); +err_device_free: + platform_device_put(pdev); +err_driver: + platform_driver_unregister(&tp_driver); +err_port2: + release_region(SMAPI_PORT2, 1); +err_port1: + release_region(smapi_port, 1); +err: + printk(KERN_ERR "tp_smapi init failed (ret=%d)!\n", ret); + return ret; +} + +static void __exit tp_exit(void) +{ + while (next_attr_group && --next_attr_group >= attr_groups) + sysfs_remove_group(&pdev->dev.kobj, *next_attr_group); + platform_device_unregister(pdev); + platform_driver_unregister(&tp_driver); + release_region(SMAPI_PORT2, 1); + if (smapi_port) + release_region(smapi_port, 1); + + printk(KERN_INFO "tp_smapi unloaded.\n"); +} + +module_init(tp_init); +module_exit(tp_exit); --- linux-2.6.28.orig/ubuntu/misc/acerhk.c +++ linux-2.6.28/ubuntu/misc/acerhk.c @@ -0,0 +1,3001 @@ +/********************************************************************* + * Filename: acerhk.c + * Version: 0.5 + * + * Copyright (C) 2002-2006, Olaf Tauber (olaf-tauber@versanet.de) + * + * Description: kernel driver for Acer Travelmate and similar + * laptops special keys + * Author: Olaf Tauber + * Created at: Mon Apr 29 22:16:42 2002 + * Modified at: Tue Feb 28 21:38:41 2006 + * Modified by: Olaf Tauber + * Modified at: Thu Nov 24 13:03:01 2005 + * Modified by: Antonio Cuni + * Modified at: Wed Oct 27 19:47:11 CEST 2004 + * Modified by: Joachim Fenkes + * + * 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 + * + * + */ + +/* This driver is heavily dependent on the architecture, don't let anyone + * without an X86 machine use it. I doubt that there are laptops out there + * which would need this driver and are not X86, so it doesn't matter anyway. + */ +#ifdef CONFIG_X86 + +#include + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) +#define KERNEL26 +#include +#else +#include +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) +#define STATIC_INPUT_DEV +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acerhk.h" + +/* #define ACERDEBUG */ +/* #define DUMMYHW */ + +#define ACERHK_VERSION "0.5.34" +#define MODULE_NAME "acerhk" + +/* maximum number of polling loops, adjust it if needed to values between + * 1 and 32 + */ +#define MAX_POLLING_LOOPS 16U + +/* maximum length for model string */ +#define ACERHK_MODEL_STRLEN 16 +/* size of mapped areas */ +#define AREA_SIZE 0xffff +/* needed for colussi algorithm */ +#define XSIZE 20 + +/* Module parameters */ +static int poll=1; +static int autowlan; +static int usedritek=1; +static int wlan_state=-1; +static int bluetooth_state=-1; +static int verbose; +static unsigned int force_series; +#ifdef KERNEL26 +module_param(poll, int, 0444); +module_param(autowlan, int, 0444); +module_param(usedritek, int, 0444); +module_param(verbose, int, 0444); +module_param(wlan_state, int, 0444); +module_param(bluetooth_state, int, 0444); +module_param(force_series, uint, 0444); +#else +MODULE_PARM(poll, "i"); +MODULE_PARM(autowlan, "i"); +MODULE_PARM(wlan_state, "i"); +MODULE_PARM(bluetooth_state, "i"); +MODULE_PARM(usedritek, "i"); +MODULE_PARM(verbose, "i"); +MODULE_PARM(force_series, "i"); +#endif +MODULE_PARM_DESC(poll, "start polling timer"); +MODULE_PARM_DESC(autowlan, "automatic switching of wlan hardware"); +MODULE_PARM_DESC(wlan_state, "(assumed) initial state of WLAN LED/hardware"); +MODULE_PARM_DESC(bluetooth_state, "(assumed) initial state of Bluetooth LED/hardware"); +MODULE_PARM_DESC(usedritek, "enable dritek keyboard extension"); +MODULE_PARM_DESC(verbose, "output additional information"); +MODULE_PARM_DESC(force_series, "force laptop series, skip autodetection"); + +/* input device */ +static struct input_dev *acerhk_input_dev_ptr; +#ifdef STATIC_INPUT_DEV +static struct input_dev acerhk_input_dev; +#endif + +/* mapped IO area from 0xf0000 */ +static void *reg1; +/* mapped IO area from 0xe0000 */ +static void *reg2; +/* Pointer to mapped area at 0x400 on 520 series */ +static void *preg400; +/* location of IO routine in mapped area */ +static unsigned int bios_routine; +/* index of CMOS port to get key event */ +static unsigned int cmos_index; +/* function for bios call */ +static bios_call call_bios; +/* address of model string */ +static char *acerhk_model_addr; +/* copied string, maximum length 16 ('TravelMate xxx') */ +static char acerhk_model_string[ACERHK_MODEL_STRLEN]; +/* type of hardware access */ +static t_acer_type acerhk_type; +/* travelmate series */ +static unsigned int acerhk_series; +/* supported features for this model */ +static unsigned int acerhk_model_features; +/* map of acer key codes to acer key names */ +static unsigned char acerhk_key2name[0xff]; +/* map of acer key names to key events */ +static t_map_name2event acerhk_name2event; +/* timer for polling key presses */ +static struct timer_list acerhk_timer_poll; +/* polling active */ +static int acerhk_polling_state; +/* polling delay */ +static unsigned acerhk_polling_delay = HZ/5; +/* wlan hardware toggle */ +static int acerhk_wlan_state; +/* bluetooth hardware toggle */ +static int acerhk_bluetooth_state; + +/* bluetooth blinking state; added by Antonio Cuni + possible values: + -1: blinking disabled (default) + 0: blinking enabled, led currently off + 1: blinking enabled, led currently on +*/ +static int acerhk_blueled_blinking = -1; +/* delay between two changes of state, in jiffies */ +static unsigned acerhk_blueled_blinking_delay; +/* timer for blinking */ +static struct timer_list acerhk_timer_blinking; + +/* function prototypes */ +static void start_polling(void); +static void stop_polling(void); + +/* Added by Antonio Cuni */ +static void start_blinking(void); +static void stop_blinking(void); + +/* {{{ Experimental use of dritek keyboard extension */ + +#define EC_STATUS_REG 0x66 /* Status register of EC (R) */ +#define EC_CNTL_REG 0x66 /* Controller command register of EC (W) */ +#define EC_DATA_REG 0x62 /* EC data register (R/W) */ + +#ifdef KERNEL26 + +#include + +#define KBD_STATUS_REG 0x64 /* Status register (R) */ +#define KBD_CNTL_REG 0x64 /* Controller command register (W) */ +#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */ + +#else + +#ifndef KEY_MEDIA +#define KEY_MEDIA 226 +#endif + +#define preempt_disable() do { } while (0) +#define preempt_enable_no_resched() do { } while (0) +#define preempt_enable() do { } while (0) +#define preempt_check_resched() do { } while (0) +#include + +#endif + +static inline int my_i8042_read_status(void) +{ + return inb(KBD_STATUS_REG); +} +static int my_i8042_wait_write(void) +{ + int i = 0; + while ((my_i8042_read_status() & 0x02) && (i < 10000)) { + udelay(50); + i++; + } + return -(i == 10000); +} +static void send_kbd_cmd(unsigned char cmd, unsigned char val) +{ + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_write()) + outb(cmd, KBD_CNTL_REG); + if (!my_i8042_wait_write()) + outb(val, KBD_DATA_REG); + preempt_enable_no_resched(); + } else { + printk(KERN_INFO"acerhk: request for accessing EC ignored\n" + KERN_INFO"acerhk: Use of dritek keyboard extension not enabled, use module\n" + KERN_INFO"acerhk: parameter usedritek=1 to do that (possibly dangerous)\n"); + } +} +#ifdef ACERDEBUG +static inline int my_i8042_read_ecstatus(void) +{ + return inb(EC_STATUS_REG); +} +static int my_i8042_wait_ecwrite(void) +{ + int i = 0; + while ((my_i8042_read_ecstatus() & 0x02) && (i < 10000)) { + udelay(50); + i++; + } + return -(i == 10000); +} +static void send_ec_cmd(unsigned char cmd, unsigned char val) +{ + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_ecwrite()) + outb(cmd, EC_CNTL_REG); + if (!my_i8042_wait_ecwrite()) + outb(val, EC_DATA_REG); + preempt_enable_no_resched(); + } else { + printk(KERN_INFO"acerhk: request for accessing EC ignored\n" + KERN_INFO"acerhk: Use of dritek keyboard extension not enabled, use module\n" + KERN_INFO"acerhk: parameter usedritek=1 to do that (possibly dangerous)\n"); + } +} +#endif +#ifdef ACERDEBUG +static void enable_mute_led_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mute led via EC\n"); + send_kbd_cmd(0x59, 0x94); +} +static void disable_mute_led_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mute led via EC\n"); + send_kbd_cmd(0x59, 0x95); +} +static void enable_dmm_function(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling WLAN via EC variant 2\n"); + send_kbd_cmd(0x45, 0xd3); +} +#endif +static void enable_wlan_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling WLAN via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x01); + acerhk_wlan_state = 1; +} +static void disable_wlan_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling WLAN via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x00); + acerhk_wlan_state = 0; +} +static void enable_bluetooth_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling Bluetooth via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x03); + acerhk_bluetooth_state = 1; +} +static void disable_bluetooth_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling Bluetooth via EC variant 1\n"); + send_kbd_cmd(0xe7, 0x02); + acerhk_bluetooth_state = 0; +} +static void enable_wlan_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling WLAN via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_bluetooth_state ? 0xa2 : 0xa0); + acerhk_wlan_state = 1; +} +static void disable_wlan_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling WLAN via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_bluetooth_state ? 0xa1 : 0xa3); + acerhk_wlan_state = 0; +} +static void enable_bluetooth_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling Bluetooth via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_wlan_state ? 0xa2 : 0xa1); + acerhk_bluetooth_state = 1; +} +static void disable_bluetooth_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling Bluetooth via EC variant 2\n"); + send_kbd_cmd(0x45, acerhk_wlan_state ? 0xa0 : 0xa3); + acerhk_bluetooth_state = 0; +} +#ifdef ACERDEBUG +static void enable_wireless_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling wireless hardware\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_ecwrite()) + outb(0x4d, EC_CNTL_REG); + if (!my_i8042_wait_ecwrite()) + outb(0xd2, EC_DATA_REG); + if (!my_i8042_wait_ecwrite()) + outb(0x01, EC_DATA_REG); + preempt_enable_no_resched(); + } + acerhk_wlan_state = 1; +} +static void disable_wireless_ec(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling wireless hardware\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_ecwrite()) + outb(0x4d, EC_CNTL_REG); + if (!my_i8042_wait_ecwrite()) + outb(0xd2, EC_DATA_REG); + if (!my_i8042_wait_ecwrite()) + outb(0x00, EC_DATA_REG); + preempt_enable_no_resched(); + } + acerhk_wlan_state = 0; +} +#endif +static void enable_dritek_keyboard(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling dritek keyboard extension\n"); + send_kbd_cmd(0x59, 0x90); +} +static void disable_dritek_keyboard(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling dritek keyboard extension\n"); + send_kbd_cmd(0x59, 0x91); +} +static void enable_mail_led_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mail led via EC variant 1\n"); + send_kbd_cmd(0xe8, 0x01); +} +static void disable_mail_led_ec_1(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mail led via EC variant 1\n"); + send_kbd_cmd(0xe8, 0x00); +} + +static void enable_mail_led_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mail led via EC variant 2\n"); + send_kbd_cmd(0x59, 0x92); +} +static void disable_mail_led_ec_2(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mail led via EC variant 2\n"); + send_kbd_cmd(0x59, 0x93); +} +static void enable_mail_led_ec_3(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: enabling mail led via EC variant 3\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_write()) + outl(0x80008894, 0xCF8); + if (!my_i8042_wait_write()) + outw(0xC061, 0xCFC); + preempt_enable_no_resched(); + } +} +static void disable_mail_led_ec_3(void) +{ + if (verbose) + printk(KERN_INFO "acerhk: disabling mail led via EC variant 3\n"); + if (usedritek) { + preempt_disable(); + if (!my_i8042_wait_write()) + outl(0x80008894, 0xCF8); + if (!my_i8042_wait_write()) + outw(0xC060, 0xCFC); + preempt_enable_no_resched(); + } +} + +/* }}} */ + +/* {{{ string search functions */ + +/* This is the Colussi algorithm, the code is taken from + http://www-igm.univ-mlv.fr/~lecroq/string +*/ +int preColussi(char *x, int m, int *h, int *next, int *shift) +{ + int i, k, nd, q, r, s; + int hmax[XSIZE], kmin[XSIZE], nhd0[XSIZE], rmin[XSIZE]; + /* Computation of hmax */ + i = k = 1; + do { + while (x[i] == x[i - k]) + i++; + hmax[k] = i; + q = k + 1; + while (hmax[q - k] + k < i) { + hmax[q] = hmax[q - k] + k; + q++; + } + k = q; + if (k == i + 1) + i = k; + } while (k <= m); /* Computation of kmin */ + memset(kmin, 0, m*sizeof(int)); + r = 0; + for (i = m; i >= 1; --i) + if (hmax[i] < m) + kmin[hmax[i]] = i; /* Computation of rmin */ + for (i = m - 1; i >= 0; --i) { + if (hmax[i + 1] == m) + r = i + 1; + if (kmin[i] == 0) + rmin[i] = r; + else + rmin[i] = 0; + } /* Computation of h */ + s = -1; + r = m; + for (i = 0; i < m; ++i) + if (kmin[i] == 0) + h[--r] = i; + else + h[++s] = i; + nd = s; /* Computation of shift */ + for (i = 0; i <= nd; ++i) + shift[i] = kmin[h[i]]; + for (i = nd + 1; i < m; ++i) + shift[i] = rmin[h[i]]; + shift[m] = rmin[0]; /* Computation of nhd0 */ + s = 0; + for (i = 0; i < m; ++i) { + nhd0[i] = s; + if (kmin[i] > 0) + ++s; + } /* Computation of next */ + for (i = 0; i <= nd; ++i) + next[i] = nhd0[h[i] - kmin[h[i]]]; + for (i = nd + 1; i < m; ++i) + next[i] = nhd0[m - rmin[h[i]]]; + next[m] = nhd0[m - rmin[h[m - 1]]]; return(nd); +} + +int COLUSSI(char *x, int m, char *y, int n) { + int i, j, last, nd, + h[XSIZE], next[XSIZE], shift[XSIZE]; /* Processing */ + int match_pos; /* position of first match */ + nd = preColussi(x, m, h, next, shift); /* Searching */ + i = j = 0; + last = -1; + match_pos = -1; + while ( (match_pos == -1) + && (j <= n - m) ) { + while (i < m && last < j + h[i] && + x[h[i]] == y[j + h[i]]) + i++; + if (i >= m || last >= j + h[i]) { + /* Match found, bail out */ + match_pos = j; + i = m; + } + if (i > nd) + last = j + m - 1; + j += shift[i]; + i = next[i]; + } + return match_pos; +} + +/* }}} */ + +/* {{{ hardware access functions */ + +/* call_bios_ + * + * call request handler in mapped system rom + * + * the request is handed over via all 6 general purpose registers, results are + * taken from them and copied back to buf + */ +static asmlinkage void call_bios_6xx(struct register_buffer *buf) +{ + if (bios_routine) { + local_irq_disable(); + __asm__ __volatile__( + "movl %1,%%edx\n\t" + "pusha\n\t" + "movl %%edx,%%ebp\n\t" + "movl (%%ebp),%%eax\n\t" + "movl 4(%%ebp),%%ebx\n\t" + "movl 8(%%ebp),%%ecx\n\t" + "movl 12(%%ebp),%%edx\n\t" + "movl 16(%%ebp),%%edi\n\t" + "movl 20(%%ebp),%%esi\n\t" + "pushl %%ebp\n\t" + "call *%0\n\t" + "popl %%ebp\n\t" + "movl %%eax, (%%ebp)\n\t" + "movl %%ebx, 4(%%ebp)\n\t" + "movl %%ecx, 8(%%ebp)\n\t" + "movl %%edx, 12(%%ebp)\n\t" + "movl %%edi, 16(%%ebp)\n\t" + "movl %%esi, 20(%%ebp)\n\t" + "popa\n\t" + : + :"m" (bios_routine), "m" (buf) + :"%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi"//, "%ebp" + ); + local_irq_enable(); + } +} + +static asmlinkage void call_bios_52x(struct register_buffer *buf) +{ + if (bios_routine) { + local_irq_disable(); + __asm__ __volatile__( + "movl %2,%%edx\n\t" + "pusha\n\t" + "movl %%edx,%%ebp\n\t" + "movl (%%ebp),%%eax\n\t" + "movl 4(%%ebp),%%ebx\n\t" + "movl 8(%%ebp),%%ecx\n\t" + "movl 12(%%ebp),%%edx\n\t" + "movl 16(%%ebp),%%edi\n\t" + "movl 20(%%ebp),%%esi\n\t" + "pushl %%ebp\n\t" + "movl %1, %%ebp\n\t" + "call *%0\n\t" + "popl %%ebp\n\t" + "movl %%eax, (%%ebp)\n\t" + "movl %%ebx, 4(%%ebp)\n\t" + "movl %%ecx, 8(%%ebp)\n\t" + "movl %%edx, 12(%%ebp)\n\t" + "movl %%edi, 16(%%ebp)\n\t" + "movl %%esi, 20(%%ebp)\n\t" + "popa\n\t" + : + :"m" (bios_routine), "m" (preg400), "m" (buf) + :"%eax", "%ebx", "%ecx", "%edx", "%edi", "%esi"//, "%ebp" + ); + local_irq_enable(); + } +} + +#define PRINT_BUFFER(x) \ + printk(KERN_INFO"acerhk: eax=0x%x ebx=0x%x ecx=0x%x edx=0x%x\n" \ + "acerhk: edi=0x%x esi=0x%x ebp=0x%x\n", \ + x.eax, x.ebx, x.ecx, x.edx, x.edi, x.esi, x.ebp); + +/* get_fnkey_event + * + * gets the first (oldest) key id from the queue of events + * + * return value: id of key + */ +static int get_fnkey_event(void) +{ + struct register_buffer regs; + regs.eax = 0x9610; + regs.ebx = 0x61C; + /* clear other registers, some models need this */ + regs.ecx = 0; + regs.edx = 0; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + return regs.eax & 0xffff; +} + +/* get_thermal_event + * + * does what? + * + * return value: event ? + */ +static int get_thermal_event(void) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_THERMAL) { + regs.eax = 0x9612; + regs.ebx = 0x12e; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: thermal event = 0x%x\n", regs.eax); + } else { + regs.eax = 0x00; + if (verbose > 3) + printk(KERN_INFO"acerhk: thermal event not supported\n"); + } + return regs.eax & 0xffff; +} + +#ifdef ACERDEBUG +/* pbutton_fct + * + * does what? + * + * return value: ? + */ +static int pbutton_fct(void) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_PBUTTON) { + regs.eax = 0x9612; + regs.ebx = 0x10b; + regs.ecx = 0x2; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: pbutton = 0x%x\n", regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: pbutton function not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} +#endif + +/* wbutton_fct_1 + * + * turn on installed Bluetooth hardware together with the corresponding LED + * + * val: 0 turns off the LED + * 1 turns the LED to green/blue + * + * return value: ? + */ +static int wbutton_fct_1(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_WBUTTON) { + acerhk_bluetooth_state = val; + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x34; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton1 = 0x%x\n", regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton function 1 not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* wbutton_fct_2 + * + * turn on installed WLAN hardware together with the corresponding LED + * + * val: 0 turns off the LED + * 1 turns the LED to orange + * + * return value: ? + */ +static int wbutton_fct_2(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_WBUTTON) { + acerhk_wlan_state = val; + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x35; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton2 = 0x%x\n", regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: wbutton function 2 not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* get_cmos_index + * + * gets index of CMOS port from ROM. The number of events is monitored + * in this port. + * + * return value: index of CMOS port + */ +static int get_cmos_index(void) +{ + struct register_buffer regs; + regs.eax = 0x9610; + regs.ebx = 0x51C; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + cmos_index = regs.ecx & 0xff; + if (verbose) + printk(KERN_INFO"acerhk: cmos index set to 0x%x\n", cmos_index); + return cmos_index; +} + +/* get_nr_events + * + * gets the number of cached events (keys pressed) in queue. Up to 31 events + * are cached. + * + * return value: number of events in queue + */ +static int get_nr_events(void) +{ + unsigned long flags; + unsigned char c = 0; + + spin_lock_irqsave (&rtc_lock, flags); +#ifndef DUMMYHW + if (cmos_index) + c = CMOS_READ(cmos_index); + else if (verbose > 3) + printk(KERN_INFO"acerhk: get_nr_events - no valid cmos index set\n"); +#endif + spin_unlock_irqrestore (&rtc_lock, flags); + return c; +} + +/* set_mail_led + * + * change state of mail led + * + * val: 0 - switch led off + * 1 - switch led on (blinking) + * + * return value: 1 - action succesfull (val valid) + * 0 - no action taken (val invalid) + */ +static int set_mail_led(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_MAIL_LED) { + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x31; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: mail led set to = 0x%x\n", val); + } else if (acerhk_model_features & TM_F_MAIL_LED_EC) { + if (val == 1) + enable_mail_led_ec_1(); + else if (val == 0) + disable_mail_led_ec_1(); + } else if (acerhk_model_features & TM_F_MAIL_LED_EC2) { + if (val == 1) + enable_mail_led_ec_2(); + else if (val == 0) + disable_mail_led_ec_2(); + } else if (acerhk_model_features & TM_F_MAIL_LED_EC3) { + if (val == 1) + enable_mail_led_ec_3(); + else if (val == 0) + disable_mail_led_ec_3(); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: mail led not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* launch_connect + * + * does what? + * val: 1 - only known value from windows driver + */ +static int launch_connect(int val) +{ + struct register_buffer regs; + if (acerhk_model_features & TM_F_CONNECT) { + regs.eax = 0x9610; + regs.ebx = ((val & 0xff) << 8) | 0x2e; + preempt_disable(); + call_bios(®s); + preempt_enable_no_resched(); + if (verbose > 3) + printk(KERN_INFO"acerhk: connect(%d) = 0x%x\n", val, regs.eax); + } else { + if (verbose > 3) + printk(KERN_INFO"acerhk: connect not supported\n"); + regs.eax = 0x00; + } + return regs.eax & 0xffff; +} + +/* }}} */ + +/* {{{ hardware probing */ + +static struct proc_dir_entry *proc_acer_dir; + +static unsigned int __init find_hk_area(void) +{ + int offset, sig; + unsigned int fkt; + fkt = 0; + sig = -1; /* offset to signature in io area */ + /* Look for signature, start at 0xf0000, search until 0xffff0 */ + for (offset = 0;offset < 0xfffd; offset += 16) { + if (readl(reg1 + offset) == 0x30552142) { + sig = offset; + offset = 0xffff; + } + } + if (sig < 0) + printk(KERN_WARNING"acerhk: could not find request handler, possibly not all functions available\n"); + else { + /* compute location of bios routine */ + fkt = readl(reg1 + sig + 5); + /* adjust fkt to address of mapped IO area */ + if (fkt >= 0xf0000) + fkt = (unsigned int)reg1 + fkt - 0xf0000; + else if (fkt >= 0xe0000) + fkt = (unsigned int)reg1 + fkt - 0xe0000; + else + fkt = 0; + } + return fkt; +} + +static void print_features(void) +{ + int i; + printk(KERN_INFO"acerhk: supported keys:"); + for (i = 0; i < 255; i++) { + switch (acerhk_key2name[i]) { + case k_help: printk(" help"); break; + case k_setup: printk(" setup"); break; + case k_p1: printk(" p1"); break; + case k_p2: printk(" p2"); break; + case k_p3: printk(" p3"); break; + case k_www: printk(" www"); break; + case k_mail: printk(" mail"); break; + case k_wireless: printk(" wireless"); break; + case k_power: printk(" power"); break; + case k_mute: printk(" mute"); break; + case k_volup: printk(" volup"); break; + case k_voldn: printk(" voldn"); break; + case k_res: printk(" res"); break; + case k_close: printk(" close"); break; + case k_open: printk(" open"); break; + case k_wireless2: printk(" wireless2"); break; + case k_play: printk(" play"); break; + case k_stop: printk(" stop"); break; + case k_prev: printk(" prev"); break; + case k_next: printk(" next"); break; + case k_display: printk(" display"); break; + default: break; + } + } + printk("\n"); + if (acerhk_model_features & TM_F_MUTE_LED_EC) + printk(KERN_INFO"acerhk: mute led is supported\n"); + if (acerhk_model_features & TM_F_MAIL_LED) + printk(KERN_INFO"acerhk: mail led is supported\n"); + else if (acerhk_model_features & TM_F_MAIL_LED_EC) + printk(KERN_INFO"acerhk: mail led (EC) is supported\n"); + else if (acerhk_model_features & TM_F_MAIL_LED_EC2) + printk(KERN_INFO"acerhk: mail led (EC2) is supported\n"); + else if (acerhk_model_features & TM_F_MAIL_LED_EC3) + printk(KERN_INFO"acerhk: mail led (EC3) is supported\n"); + printk(KERN_INFO"acerhk: supported functions:"); + if (acerhk_model_features & TM_F_CONNECT) + printk(" connect"); + if (acerhk_model_features & TM_F_THERMAL) + printk(" thermal"); + if (acerhk_model_features & TM_F_PBUTTON) + printk(" pbutton"); + if (acerhk_model_features & TM_F_WBUTTON) + printk(" wbutton"); + printk("\n"); +} + +static void __init setup_keymap_model(unsigned int series) +{ + /* clear mapping keycode -> keyname, */ + memset(&acerhk_key2name[0], k_none, sizeof(acerhk_key2name)); + /* first set the common keys, namely FnF1 and FnF2, */ + acerhk_key2name[1] = k_help; + acerhk_key2name[2] = k_setup; + /* then set known keycodes according to model */ + switch (series) { + case 110: + acerhk_key2name[48] = k_wireless; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[3] = k_power; + acerhk_key2name[8] = k_mute; + acerhk_key2name[32] = k_volup; + acerhk_key2name[33] = k_voldn; + /* C110 generates 2 extra codes when opening/closing the lid */ + acerhk_key2name[74] = k_close; + acerhk_key2name[75] = k_open; + break; + case 300: /* treat C300 like C100 with Bluetooth button */ + acerhk_key2name[68] = k_wireless2; + case 100: + acerhk_key2name[48] = k_wireless; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[49] = k_www; + acerhk_key2name[54] = k_mail; + acerhk_key2name[3] = k_power; + acerhk_key2name[8] = k_mute; + acerhk_key2name[32] = k_volup; + acerhk_key2name[33] = k_voldn; + break; + default: + /* only the two common keys are supported */ + break; + case 210: + acerhk_key2name[19] = k_p1; + acerhk_key2name[20] = k_p2; + acerhk_key2name[17] = k_www; + acerhk_key2name[18] = k_mail; + break; + case 220: + case 260: /* 260 with same keys? */ + acerhk_key2name[49] = k_p1; + acerhk_key2name[19] = k_p2; + acerhk_key2name[18] = k_www; + acerhk_key2name[17] = k_mail; + break; + case 230: + case 280: /* 280 with same keys? */ + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + break; + case 1500: + acerhk_key2name[0x49] = k_setup; + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x31] = k_mail; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x30] = k_wireless; + acerhk_key2name[0x44] = k_wireless2; + acerhk_key2name[0x03] = k_power; + break; + case 240: + acerhk_key2name[0x31] = k_www; + acerhk_key2name[0x36] = k_mail; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x44] = k_wireless; + acerhk_key2name[0x30] = k_wireless2; + acerhk_key2name[0x03] = k_power; + acerhk_key2name[0x08] = k_mute; + // acerhk_key2name[] = k_volup; + // acerhk_key2name[] = k_voldn; + break; + case 2900: + acerhk_key2name[0x31] = k_mail; /* with led */ + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x30] = k_wireless; /* wireless, with led, related with autowlan=1 */ + break; + case 250: /* enriqueg@altern.org */ + /* TravelMate 254LMi_DT manual common for 240/250 series, but key order + differ from 240 already present on acerhk driver */ + /* TravelMate 254LMi_DT: 6 buttons: left to right: mail, www, p1, p2, bluetooth, wireless */ + acerhk_key2name[0x31] = k_mail; /* with led */ + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x44] = k_wireless2; /* bluetooth, hw optional */ + acerhk_key2name[0x30] = k_wireless; /* wireless, with led, related with autowlan=1 */ + acerhk_key2name[0x03] = k_power; /* Fn+F3 */ + acerhk_key2name[0x08] = k_mute; /* Fn+F8 */ + break; + case 380: + /* TM 380 has same codes as TM 370, with an additional one */ + acerhk_key2name[0x03] = k_power; + case 370: + acerhk_key2name[0x30] = k_wireless; + acerhk_key2name[0x11] = k_p1; + acerhk_key2name[0x12] = k_p2; + acerhk_key2name[0x13] = k_p3; + acerhk_key2name[0x36] = k_www; + acerhk_key2name[0x31] = k_mail; + break; + case 360: + /* 360 series has the same layout as 350, with an + additional wireless key */ + acerhk_key2name[64] = k_wireless; + case 350: + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[20] = k_p3; + acerhk_key2name[21] = k_www; + acerhk_key2name[19] = k_mail; + break; + case 520: + acerhk_key2name[19] = k_p1; + acerhk_key2name[20] = k_p2; + acerhk_key2name[17] = k_www; + acerhk_key2name[18] = k_mail; + break; + case 610: + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[21] = k_www; + acerhk_key2name[20] = k_mail; + acerhk_key2name[64] = k_wireless; + break; + case 630: + /* 630 has all keys of 620 plus one */ + acerhk_key2name[8] = k_mute; + case 620: + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[3] = k_power; + acerhk_key2name[32] = k_volup; + acerhk_key2name[33] = k_voldn; + break; + case 290: + case 420: + case 430: + case 530: + case 540: + case 650: + case 660: + case 800: + case 1450: + case 2300: + case 2350: + case 4000: + case 4050: + case 6000: + case 8000: + case 4100: + case 4150: + case 4500: + case 4600: + case 4650: + case 1680: + case 1690: + /* keys are handled by dritek EC */ + acerhk_key2name[1] = k_none; + acerhk_key2name[2] = k_none; + break; + case 1300: + case 1310: + case 1350: + case 1360: + case 1400: + case 1700: + case 1800: + case 2000: + case 2010: + case 2020: + /* Aspire 13xx series laptops use dritek hardware, no + acerhk-mapping needed + VolUp and VolDown are managed as normal keys + 1300/1310 series should have P1, P2, Mail, WWW, Mute buttons + 1353 has bluetooth, wifi, p1, p2, www, mail, help, setup, power + and mute + Aspire 1400/1450/Ferrari use dritek EC, too + 1450 should have bluetooth, wifi, p1, p2, www, mail, help, + setup, power and mute + Aspire 1700 uses dritek EC, too + 1700 should have bluetooth, wifi, p1, p2, www, mail, help, + setup, power and mute + need the MM-buttons Activation? (forward, shuffle, ...) + 2000 hast lots of MM buttons + 2010 should have bluetooth, wifi, p1, p2, www, mail, help, + setup, power and mute + */ + acerhk_key2name[1] = k_none; + acerhk_key2name[2] = k_none; + break; + case 1600: + /* Aspire 1600 has acer keycode 0x49 for FnF2 */ + acerhk_key2name[73] = k_setup; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[3] = k_power; + acerhk_key2name[8] = k_mute; + /* VolUp and VolDown keys doesn't seem to be managed as special keys + but as normal keys ! */ + break; + case 5020: /* Aspire 5020 has 0x6a for Fn+F2 */ + acerhk_key2name[2] = k_none; + acerhk_key2name[106] = k_setup; + acerhk_key2name[3] = k_power; + acerhk_key2name[5] = k_display; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[68] = k_wireless2; + break; + case 2410: /* TM 2410 is very similar to Aspire 5020, but has 0x6s for Fn-F3 */ + acerhk_key2name[2] = k_none; + acerhk_key2name[106] = k_setup; + acerhk_key2name[109] = k_power; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[68] = k_wireless2; + break; + case 40100: + /* Medion MD40100, 4 keys */ + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[55] = k_res; + break; + case 96500: + case 95400: + /* Medion MD95400, many keys */ + acerhk_key2name[49] = k_mail; /* 1 */ + acerhk_key2name[54] = k_www; /* 2 */ + acerhk_key2name[48] = k_wireless; /* 3 */ + acerhk_key2name[68] = k_wireless2; /* 4 (Bluetooth) */ + + acerhk_key2name[17] = k_p1; /* 5 */ + acerhk_key2name[18] = k_p2; /* 6 */ + acerhk_key2name[36] = k_play; /* 7 */ + acerhk_key2name[37] = k_stop; /* 8 */ + acerhk_key2name[34] = k_prev; /* 9 */ + acerhk_key2name[35] = k_next; /* 10 */ + acerhk_key2name[33] = k_voldn; /* 11 */ + acerhk_key2name[32] = k_volup; /* 12 */ + acerhk_key2name[38] = k_p3; /* 13 */ + acerhk_key2name[8] = k_mute; /* 14 */ + + acerhk_key2name[1] = k_help; /* FN+F1 (Help) */ + acerhk_key2name[5] = k_display; /* FN+F3 (Display switch) */ + acerhk_key2name[6] = k_res; /* FN+F4 (Display ein/ausschalten) */ + break; + case 42200: + /* Medion MD42200, 7 keys, no setup */ + acerhk_key2name[2] = k_none; + acerhk_key2name[5] = k_display; + acerhk_key2name[54] = k_www; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + break; + case 9783: + /* Medion MD9783, 6 keys + info, no setup */ + acerhk_key2name[2] = k_none; + acerhk_key2name[54] = k_www; + acerhk_key2name[49] = k_mail; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[8] = k_mute; + break; + case 7400: + /* Amilo Pro V2000 does not have Help and Setup key (?) + Amilo M 7400 has Help key, disabling only setup + */ + acerhk_key2name[2] = k_none; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + break; + case 1559: + acerhk_key2name[6] = k_display; /* FN+F4 (Display ein/ausschalten) */ + case 1555: + /* AOpen (Ahtec Signal 1555M) is similar to FS Amilo M */ + acerhk_key2name[2] = k_none; + acerhk_key2name[48] = k_wireless; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[34] = k_prev; + acerhk_key2name[35] = k_next; + acerhk_key2name[36] = k_play; + acerhk_key2name[37] = k_stop; + break; + case 6800: + case 7820: + /* Amilo D does not have Setup key */ + acerhk_key2name[2] = k_none; + acerhk_key2name[49] = k_mail; + acerhk_key2name[54] = k_www; + acerhk_key2name[17] = k_p1; + acerhk_key2name[18] = k_p2; + acerhk_key2name[19] = k_p3; + acerhk_key2name[8] = k_mute; + break; + case 6805: /* Added by damagedspline@aim.com */ + /* Amilo A1xxx does not have Setup key nor a mail key */ + acerhk_key2name[2] = k_none; + acerhk_key2name[54] = k_www; + acerhk_key2name[5] = k_display; + acerhk_key2name[110] = k_setup; //This is the Fancy Fan (cool-n'-quiet) key on A1650g + acerhk_key2name[48] = k_wireless; + break; + } +} + +static void __init setup_model_features(unsigned int series) +{ + switch (series) { + case 200: + case 210: + case 520: + /* nothing special */ + acerhk_model_features = 0; + acerhk_type = TM_old; + break; + case 220: + case 230: + case 260: + case 280: + case 360: + case 40100: /* Medion MD40100 */ + case 95400: /* Medion MD95400 */ + case 96500: /* Medion MD96500 */ + /* all special functions, no mail led */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_new; + break; + case 42200: /* Medion MD42200 */ + /* has WLAN button, should call connect() */ + acerhk_model_features = TM_F_WBUTTON | TM_F_CONNECT; + acerhk_type = TM_old; + break; + case 9783: /* Medion MD9783 */ + /* only email led */ + acerhk_model_features = TM_F_MAIL_LED; + acerhk_type = TM_new; + break; + case 1600: + acerhk_type = TM_new; + /* Do Aspire 1600 series have special functions or not ? I enable + them, perhaps it helps with problems Francois Valenduc has */ + acerhk_model_features = 0x00f00000; + break; + case 300: + case 100: + case 110: + case 240: + case 350: + case 610: + case 620: + case 630: + /* all special functions, mail led */ + acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; + acerhk_type = TM_new; + break; + case 370: + case 380: + case 2410: + case 2900: /* Medion MD2900 */ + case 2100: /* TM 2100 uses same driver as 5020 */ + case 5020: /* Aspire 5020 is still old hardware */ + acerhk_model_features = TM_F_MAIL_LED | TM_F_CONNECT| TM_F_WBUTTON; + acerhk_type = TM_new; + break; + case 7400: + case 1555: + case 1559: + /* all special functions for Fujitsu-Siemens Amilo M7400, Pro V2000; AOpen */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_new; + break; + case 6805: /* Added by damagedspline@aim.com */ + /* Amilo A1xxx does not have a mail led */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_new; + break; + case 6800: + case 7820: + /* mail led and all special functions for FS Amilo D */ + acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; + acerhk_type = TM_new; + break; + case 2350: + case 4050: + acerhk_wlan_state = 1; // Default state is on + case 290: + /* no special functions, wireless hardware controlled by EC */ + acerhk_model_features = TM_F_WLAN_EC2 | TM_F_BLUE_EC2; + acerhk_type = TM_dritek; + break; + case 650: + case 1300: + case 1310: + case 1400: + case 1700: + /* all special functions, wireless hardware can be controlled */ + acerhk_model_features = 0x00f00000; + acerhk_type = TM_dritek; + break; + case 4100: + case 4600: + case 1680: + case 1690: /* Aspire 1680/1690 should be similar to TM 4100/4600 */ + /* mail led, wireless and bluetooth controlled the old way, but keys are + controlled by normal keyboard controller, so mark as dritek and + deactivate dritek use */ + acerhk_model_features = TM_F_MAIL_LED | TM_F_WBUTTON; + acerhk_type = TM_dritek; + usedritek=0; + break; + case 660: + case 800: + /* all special functions, mail led */ + acerhk_model_features = TM_F_MAIL_LED | 0x00f00000; + acerhk_type = TM_dritek; + break; + case 1350: + case 1360: + /* mail led, handled by EC, wireless HW is not (yet) controllable ? */ + acerhk_model_features = TM_F_MAIL_LED_EC|TM_F_WLAN_EC1; + acerhk_type = TM_dritek; + break; + case 1450: + /* Bluetooth/Wlan led, Mail led handled by EC (variant 3) */ + acerhk_model_features = TM_F_MAIL_LED_EC3|TM_F_WBUTTON; + acerhk_type = TM_dritek; + break; + case 1500: + /* Bluetooth/Wlan led */ + acerhk_model_features = TM_F_WBUTTON; + acerhk_type = TM_new; + break; + case 420: + case 430: + /* all functions and dritek EC, mail LED is handled by EC, second + variant. An additional led is available, mute. (really?) + */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MUTE_LED_EC|TM_F_MAIL_LED_EC2; + break; + case 2300: + case 4000: + case 4500: + /* wireless hardware, hopefully under control of my driver */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_BLUE_EC1|TM_F_WLAN_EC1; + break; + case 3200: + /* test, if this model uses old style wlan control */ + acerhk_model_features = TM_F_WBUTTON; + acerhk_type = TM_dritek; + break; + case 6000: + case 8000: + /* 6000 and 8000 have wireless hardware, but I don't know how to handle, + so I choose no features */ + acerhk_type = TM_dritek; + break; + case 530: + case 540: + case 2000: + /* No features (?) dritek EC, mail LED is handled by EC but + different from other Aspire series */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MAIL_LED_EC2; + break; + case 4150: + case 4650: + /* Dritek EC, bluetooth, wifi, mail */ + /* According to Andreas Stumpfl his TM 4652LMi does also work as series + 3200, which might mean that the BIOS function accesses the EC */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MAIL_LED_EC2 | TM_F_WLAN_EC2 | TM_F_BLUE_EC2; + break; + case 1800: + case 2010: + case 2020: + /* Dritek EC, bluetooth, wifi, mail */ + acerhk_type = TM_dritek; + acerhk_model_features = TM_F_MAIL_LED_EC2 | TM_F_WLAN_EC2 | TM_F_BLUE_EC2; + acerhk_wlan_state = 1; // Default state is on + break; + case 250: /* enriqueg@altern.org */ + /* TravelMate254LMi_DT : mail led, bluetooth (button present, hw optional), wifi (with led) */ + acerhk_model_features = TM_F_MAIL_LED| + TM_F_WBUTTON ; + acerhk_type = TM_new; + acerhk_wlan_state = 0; //Initial state is off on 254LMi_DT + break; + default: + /* nothing special */ + acerhk_model_features = 0; + acerhk_type = TM_unknown; + break; + } + /* set the correct bios call function according to type */ + if ((acerhk_type == TM_new) || (acerhk_type == TM_dritek)) { + call_bios = call_bios_6xx; + if (verbose > 2) + printk(KERN_INFO"acerhk: using call_bios_6xx mode\n"); + } else { + call_bios = call_bios_52x; + if (verbose > 2) + printk(KERN_INFO"acerhk: using call_bios_52x mode\n"); + } + /* remove key file on dritek hardware */ + if (acerhk_type == TM_dritek) { + remove_proc_entry("key", proc_acer_dir); + } + /* setup available keys */ + setup_keymap_model(acerhk_series); + if (verbose > 1) + print_features(); +} + +static unsigned int __init determine_laptop_series(char * str) +{ + /* 0 means unknown series, handled like TM 200 */ + unsigned int series = 0; + if (strncmp(str, "TravelMate ", 11) == 0) { + switch (str[11]) { + case 'C': + if (str[12] == '1') { + if (str[13] == '0') { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM C100 series\n"); + series = 100; + } else if (str[13] == '1') { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM C110 series\n"); + series = 110; + } + } else if (str[12] == '3') { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM C300 series\n"); + series = 300; + } + break; + case 'F': + if (str[12] == '4') { + series = 230; + } + break; + case '2': + if (str[14] == '0') { + /* newer Travelmate 2xxx series */ + switch (str[12]) { + case '0': + case '5': + series = 2000; // 2000 and 2500 are the same + break; + case '1': + if (str[13] == '0') + series = 2100; + break; + case '2': + case '7': + series = 2200; // 2200 and 2700 are the same + break; + case '3': + if (str[13] == '0') + series = 4000; // 2300 is the same as 4000 + else if (str[13] == '5') + series = 4050; // 2350 is the same as 4050 + break; + case '4': + if (str[13] == '1') + series = 2410; + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 2xxx series\n"); + break; + } + } else { + /* older Travelmate 2xx series */ + switch (str[12]) { + case '0': series = 200; break; + case '1': series = 210; break; + case '2': series = 220; break; + case '4': series = 240; break; + case '5': series = 250; break; /* enriqueg@altern.org */ + case '6': series = 260; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 2xx series\n"); + break; + } + } + break; + case '3': + switch (str[12]) { + case '0': series = 3200; break; /* TM 3000 works like TM 3200 */ + /* Travelmate 3xx series */ + case '5': series = 350; break; + case '6': series = 360; break; + case '7': series = 370; break; + case '8': series = 380; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 3xx series\n"); + break; + } + break; + case '4': + if ( (strnlen(str, ACERHK_MODEL_STRLEN-1) == 15) && + (str[14] == '0') ) { /* Travelmate 4xxx series */ + switch (str[12]) { + case '0': /* 4000 and 4500 are the same */ + case '5': + series = 4000; + break; + case '1': + case '6': /* 4100 and 4600 are the same */ + series = 4100; + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 4xxx series\n"); + break; + } + } else { /* Travelmate 4xx series */ + switch (str[12]) { + case '2': series = 420; break; + case '3': series = 430; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 4xx series\n"); + break; + } + } + break; + case '5': /* Travelmate 5xx series */ + if (str[12] == '2') + series = 520; + else if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 5xx series\n"); + break; + case '6': /* older Travelmate 6xx series */ + switch (str[12]) { + case '1': series = 610; break; + case '2': series = 620; break; + case '3': series = 630; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM 6xx series\n"); + break; + } + break; + default: + printk(KERN_INFO"acerhk: model string indicates unknown TM xxx series\n"); + break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM %d series\n", series); + } + /* newer Travelmate series do not have a space after 'TravelMate' */ + else if (strncmp(str, "TravelMate", 10) == 0) { + switch (str[10]) { + case '2': + if (str[11] == '9') { + series = 290; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM2xx series\n"); + } + break; + case '3': + if (str[11] == '2' && str[14] == '3') { + // TM 3200 uses "TravelMate32003" + series = 3200; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM3xxx series\n"); + } + break; + case '4': + switch (str[11]) { + case '3': series = 430; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM4xx series\n"); + break; + } + break; + case '5': + switch (str[11]) { + case '3': series = 530; break; + case '4': series = 540; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM5xx series\n"); + break; + } + break; + case '6': + switch (str[11]) { + case '5': series = 650; break; + case '6': series = 660; break; + case '0': + if (strncmp(str, "TravelMate60003", 15) == 0) { + series = 6000; break; + } + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM6xx series\n"); + break; + } + break; + case '8': + if (strncmp(str, "TravelMate80003", 15) == 0) { + series = 8000; + } else if (str[11] == '0') { + series = 800; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown TM8xx series\n"); + } + break; + default: + printk(KERN_INFO"acerhk: model string indicates unknown TMxxx series\n"); + break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates TM%d series\n", series); + } + else if (strncmp(str, "Aspire ", 7) == 0) { + switch(str[7]) { + case '1': /* Aspire 1xxx series */ + switch(str[8]) { + case '3': /* Aspire 13xx series */ + switch (str[9]) { + case '0': series = 1300; break; + case '1': series = 1310; break; + case '5': series = 1350; break; + case '6': series = 1360; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 13xx series\n"); + break; + } + break; + case '4': /* Aspire 14xx series */ + switch (str[9]) { + case '0': series = 1400; break; + case '5': series = 1450; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 14xx series\n"); + break; + } + break; + case '5': series = 1500; break; + case '6': /* Aspire 14xx series */ + switch (str[9]) { + case '0': series = 1600; break; + case '8': + case '9': series = 1680; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 16xx series\n"); + break; + } + break; + case '7': series = 1700; break; + case '8': series = 1800; break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 1xxx series\n"); + break; + } + break; + case '2': /* Aspire 2xxx series */ + if (str[8] == '0') { + switch (str[9]) { + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 20xx series\n"); + break; + case '0': series = 2000; break; + case '1': series = 2010; break; + case '2': series = 2020; break; + } + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 2xxx series\n"); + } + break; + case '3': /* Aspire 3xxx series */ + if (str[8] == '0') { + switch (str[9]) { + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 30xx series\n"); + break; + case '2': series = 5020; break; /* Aspire 3020/5020 are identical */ + } + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 3xxx series\n"); + } + break; + case '5': /* Aspire 5xxx series */ + if (str[8] == '0') { + switch (str[9]) { + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 50xx series\n"); + break; + case '2': series = 5020; break; + } + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire 5xxx series\n"); + } + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Aspire series\n"); + break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates Aspire %d series\n", series); + } + else if (strncmp(str, "Extensa ", 8) == 0) { + /* Extensa series */ + switch (str[8]) { + case '3': + switch (str[9]) { + case '0': + series = 3000; break; + default: break; + } + break; + default: break; + } + if (series && verbose > 1) + printk(KERN_INFO"acerhk: model string indicates Extensa %d series\n", series); + else if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown Extensa series\n"); + } + else if (strncmp(str, "Amilo ", 6) == 0) { + switch (str[6]) { + case 'D': /* complete string is "Amilo D-Series", there seems to be no model number */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS Amilo D series\n"); + /* this is the model number of my Amilo */ + series = 7820; + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown FS Amilo XX series\n"); + series = 7820; + } + } + else if (strncmp(str, "AMILO ", 6) == 0) { + switch (str[6]) { + case 'D': /* AMILO D 6800 P4-2000 */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO D series\n"); + series = 6800; + break; + case 'M': + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO M(7400) series\n"); + series = 7400; + break; + case 'P': + /* it is assumed, that 'AMILO P' appears only on Amilo Pro Series */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO Pro (V2000) series\n"); + series = 7400; + break; + case 'A': /* AMILO Axxxx - added by damagedspline@aim.com */ + switch (str[7]) { + case '1': /* AMILO A1xxx */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates FS AMILO A1xxx series\n"); + series = 6805; + break; + } + break; + default: + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates unknown FS AMILO XX series\n"); + series = 6800; + } + } + else if (strncmp(str, "MEDIONPC", 8) == 0) { + uint medionmodel; + if ((medionmodel = COLUSSI("WIM 2040", 4, reg1, AREA_SIZE)) >= 0) { + printk(KERN_INFO"acerhk: found Medion model string:'%s'\n", (char*)reg1+medionmodel); + series = 96500; + } else { + if ((medionmodel = COLUSSI("MD 9", 4, reg1, AREA_SIZE)) >= 0) { + printk(KERN_INFO"acerhk: found Medion model string:'%s'\n", (char*)reg1+medionmodel); + } + series = 95400; + } + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a medion MD %d\n", series); + } + else if (strncmp(str, "MEDIONNB", 8) == 0) { + /* Search for the Product string of the MD9783. */ + if (COLUSSI("MD 42200", 8, reg1, AREA_SIZE) >= 0) { + if (verbose>1) + printk(KERN_INFO"acerhk: model string indicates a Medion MD 42200\n"); + series = 42200; + } else if (COLUSSI("MD 9783", 7, reg1, AREA_SIZE) >= 0){ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a medion MD 9783\n"); + series = 9783; + } else if (COLUSSI("WIM 2000", 7, reg1, AREA_SIZE) >= 0){ + if (verbose>1) + printk(KERN_INFO"acerhk: model string indicates a Medion MD 2900\n"); + series = 2900; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a medion MD40100\n"); + series = 40100; + } + } else if (strncmp(str, "AOpen", 5) == 0) { + if (strncmp(str, "AOpen*EzRestore", 15) == 0) { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a AOpen 1559\n"); + series = 1559; + } else { + /* Unless I know of other models no further differentiation, + although there is a second part of the model string */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a AOpen\n"); + series = 1555; + } + } else if (strncmp(str, "CL56", 4) == 0) { + /* Unless I know of other models no further differentiation, + although there are strings with more numbers ("CL561" on a Compal + CL56/Zepto 4200, reported by Stian B. Barmen) + It has the same functions as Acer Aspire 2010 + */ + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates a Compal CL56 (or similar)\n"); + series = 2010; + } else { + if (verbose > 1) + printk(KERN_INFO"acerhk: model string indicates no supported hardware\n"); + } + return (series); +} + +static void __init probe_model(void) { + int offset; /* offset from beginning of reg1 to Model string */ + if (verbose) + printk(KERN_INFO"acerhk: start search for model string at %p\n", reg1); + /* first we look for Travelmate, if it isn't one we try to identify other + laptops, such as Medion or Aspire */ + offset = COLUSSI("Travel", 6, reg1, AREA_SIZE); + /* Try to detect Aspire laptops */ + if (offset < 0) + offset = COLUSSI("Aspire", 6, reg1, AREA_SIZE); + /* Try to detect Extensa laptops */ + if (offset < 0) + offset = COLUSSI("Extensa", 7, reg1, AREA_SIZE); + /* Try to detect Medion laptops */ + if (offset < 0) + offset = COLUSSI("MEDION", 6, reg1, AREA_SIZE); + /* Try to detect AOpen laptops */ + if (offset < 0) + offset = COLUSSI("AOpen", 5, reg1, AREA_SIZE); + /* Try to detect Fujitsu Siemens Amilo laptops */ + if (offset < 0) + offset = COLUSSI("Amilo", 5, reg1, AREA_SIZE); + if (offset < 0) + offset = COLUSSI("AMILO", 5, reg1, AREA_SIZE); + /* Try to detect Compal */ + if (offset < 0) + offset = COLUSSI("CL56", 4, reg1, AREA_SIZE); + if (offset >= 0) { + acerhk_model_addr = reg1 + offset; + /* copy the string, but not more than 15 characters */ + strncpy(acerhk_model_string, acerhk_model_addr, ACERHK_MODEL_STRLEN-1); + if (verbose) + printk(KERN_INFO"acerhk: found model string '%s' at %p\n", + acerhk_model_string, acerhk_model_addr); + if (bios_routine && verbose > 2) + printk(KERN_INFO"acerhk: offset from model string to function address: 0x%lx\n", + bios_routine - (unsigned long)acerhk_model_addr); + acerhk_series = determine_laptop_series(acerhk_model_string); + } else { + printk(KERN_WARNING"acerhk: Could not find model string, will assume type 200 series\n"); + acerhk_series = 200; + } +} + +/* }}} */ + +/* {{{ key polling and translation */ + +static void print_mapping(void) +{ + printk(KERN_INFO"acerhk: key mapping:\n"); + printk("acerhk: help 0x%x\n", acerhk_name2event[k_help]); + printk("acerhk: setup 0x%x\n", acerhk_name2event[k_setup]); + printk("acerhk: p1 0x%x\n", acerhk_name2event[k_p1]); + printk("acerhk: p2 0x%x\n", acerhk_name2event[k_p2]); + printk("acerhk: p3 0x%x\n", acerhk_name2event[k_p3]); + printk("acerhk: www 0x%x\n", acerhk_name2event[k_www]); + printk("acerhk: mail 0x%x\n", acerhk_name2event[k_mail]); + printk("acerhk: wireless 0x%x\n", acerhk_name2event[k_wireless]); + printk("acerhk: power 0x%x\n", acerhk_name2event[k_power]); + printk("acerhk: mute 0x%x\n", acerhk_name2event[k_mute]); + printk("acerhk: volup 0x%x\n", acerhk_name2event[k_volup]); + printk("acerhk: voldn 0x%x\n", acerhk_name2event[k_voldn]); + printk("acerhk: res 0x%x\n", acerhk_name2event[k_res]); + printk("acerhk: close 0x%x\n", acerhk_name2event[k_close]); + printk("acerhk: open 0x%x\n", acerhk_name2event[k_open]); + printk("acerhk: wireless2 0x%x\n", acerhk_name2event[k_wireless2]); + printk("acerhk: play 0x%x\n", acerhk_name2event[k_play]); + printk("acerhk: stop 0x%x\n", acerhk_name2event[k_stop]); + printk("acerhk: prev 0x%x\n", acerhk_name2event[k_prev]); + printk("acerhk: next 0x%x\n", acerhk_name2event[k_next]); + printk("acerhk: display 0x%x\n", acerhk_name2event[k_display]); +} + +static void set_keymap_name(t_key_names name, unsigned int key) +{ + acerhk_name2event[name] = key; +} + +static void init_keymap_input(void) +{ + /* these values for input keys are chosen to match the key names on the + actual Acer laptop */ + set_keymap_name(k_none, KEY_RESERVED); + set_keymap_name(k_help, KEY_HELP); + set_keymap_name(k_setup, KEY_CONFIG); + set_keymap_name(k_p1, KEY_PROG1); + set_keymap_name(k_p2, KEY_PROG2); + set_keymap_name(k_p3, KEY_PROG3); + set_keymap_name(k_www, KEY_WWW); + set_keymap_name(k_mail, KEY_MAIL); + set_keymap_name(k_wireless, KEY_XFER); + set_keymap_name(k_power, KEY_POWER); + set_keymap_name(k_mute, KEY_MUTE); + set_keymap_name(k_volup, KEY_VOLUMEUP); + set_keymap_name(k_voldn, KEY_VOLUMEDOWN); + set_keymap_name(k_res, KEY_CONFIG); + set_keymap_name(k_close, KEY_CLOSE); + set_keymap_name(k_open, KEY_OPEN); + /* I am not really happy with the selections for wireless and wireless2, + but coffee looks good. Michal Veselenyi proposed this value */ + set_keymap_name(k_wireless2, KEY_COFFEE); + set_keymap_name(k_play, KEY_PLAYPAUSE); + set_keymap_name(k_stop, KEY_STOPCD); + set_keymap_name(k_prev, KEY_PREVIOUSSONG); + set_keymap_name(k_next, KEY_NEXTSONG); + set_keymap_name(k_display, KEY_MEDIA); /* also not happy with this */ + if (verbose > 1) + print_mapping(); +} + +static int filter_idle_value(int keycode) +{ + int validkey = 0; + if (keycode != 0x0 && + keycode != 0x9610 && + keycode != 0xc100 && /* Francois Valenduc, Aspire 1601 LC */ + keycode != 0x8610 && + keycode != 0x861 && + keycode != 0x8650 && + keycode != 0x865) + validkey = keycode; + if (verbose > 4 && !validkey) + printk(KERN_INFO"acerhk: throw away idle value 0x%x\n", keycode); + return validkey; +} + +static void send_key_event(t_key_names key) +{ + unsigned int input_key; + if (key != k_none) { + /* convert key name to kernel keycode */ + input_key = acerhk_name2event[key]; + if (verbose > 2) + printk(KERN_INFO"acerhk: translated acer key name 0x%x to input key 0x%x\n", + key, input_key); + /* send press and release together, as there is no such event from acer as 'release' */ + input_report_key(acerhk_input_dev_ptr, input_key, 1); + input_report_key(acerhk_input_dev_ptr, input_key, 0); + } +} + +static t_key_names transl8_key_code(int keycode) +{ + t_key_names keyname = k_none; + /* first filter out idle values */ + if ( (keycode = filter_idle_value(keycode)) ) { + if (verbose > 3) + printk(KERN_INFO"acerhk: received key code 0x%x\n", keycode); + /* translate keycode to key name */ + if (keycode >= 0 && keycode <= 255) + keyname = acerhk_key2name[keycode]; + else { + if (verbose > 3) + printk(KERN_INFO"acerhk: keycode 0x%x too big, will use only 8 bits\n", keycode); + /* use only lower 8 bits of value to distinguish keys */ + keyname = acerhk_key2name[keycode&0xff]; + } + /* produce some log information for higher verbosity levels */ + if (keyname != k_none && verbose > 2) + printk(KERN_INFO"acerhk: translated acer key code 0x%x to key name 0x%x\n", + keycode, keyname); + else if (keyname == k_none && verbose > 3) + printk(KERN_INFO"acerhk: translated acer key code 0x%x to no key\n", + keycode); + if (autowlan) { + /* if automatic switching of wlan hardware is enabled, do it here + on wireless key press */ + if (keyname == k_wireless2) { + if (acerhk_bluetooth_state) + wbutton_fct_1(0); + else + wbutton_fct_1(1); + } + if (keyname == k_wireless) { + if (acerhk_wlan_state) + wbutton_fct_2(0); + else + wbutton_fct_2(1); + } + } + } + return keyname; +} + +/* polling timer handler */ +static void acerhk_poll_event(unsigned long save_size) +{ +#ifndef DUMMYHW + unsigned int max = MAX_POLLING_LOOPS; + /* make sure not to loop more then 32 times */ + if (!max || max > 32) + max = 32; + if (acerhk_type != TM_dritek) { + while (get_nr_events() && max--) { + send_key_event(transl8_key_code(get_fnkey_event())); + } + } else { + send_key_event(transl8_key_code(get_fnkey_event())); + } +#endif + acerhk_timer_poll.expires = jiffies + acerhk_polling_delay; + add_timer(&acerhk_timer_poll); +} + +/* blinking timer handler; added by Antonio Cuni */ +static void acerhk_blink_event(unsigned long not_used) +{ + if (acerhk_blueled_blinking != -1) { + acerhk_blueled_blinking = !acerhk_blueled_blinking; +#ifndef DUMMYHW + wbutton_fct_1(acerhk_blueled_blinking); +#endif + acerhk_timer_blinking.expires = jiffies + acerhk_blueled_blinking_delay; + add_timer(&acerhk_timer_blinking); + } + else + printk(KERN_WARNING "acerhk: blinking event called, but blinking not active\n"); +} + +static void init_input(void) +{ + int i; + +#ifndef KERNEL26 + /* request keyboard input module */ + request_module("keybdev"); + if (verbose > 3) + printk(KERN_INFO"requested keyboard input driver\n"); +#endif + +#ifndef STATIC_INPUT_DEV + /* allocate acerhk input device */ + acerhk_input_dev_ptr=input_allocate_device(); + /* enter some name */ + acerhk_input_dev_ptr->name = "Acer hotkey driver"; +#else + acerhk_input_dev_ptr=&acerhk_input_dev; +#endif + + /* some laptops have a mail led, should I announce it here? */ + acerhk_input_dev_ptr->evbit[0] = BIT(EV_KEY); + /* announce keys to input system + * the generated keys can be changed on runtime, + * but to publish those changes the device needs to + * get reconnected (I dont't know any other way) + * Therefore I enable all possible keys */ + for (i = KEY_RESERVED; i < BTN_MISC; i++) + set_bit(i, acerhk_input_dev_ptr->keybit); + /* set mapping keyname -> input event */ + init_keymap_input(); + if (verbose) + printk(KERN_INFO"acerhk: registered input device\n"); + input_register_device(acerhk_input_dev_ptr); + init_timer(&acerhk_timer_poll); + acerhk_polling_state = 0; +} + +static void stop_polling(void) +{ + if (acerhk_polling_state == 1) { + del_timer(&acerhk_timer_poll); + if (verbose) + printk(KERN_INFO"acerhk: key polling stopped\n"); + acerhk_polling_state = 0; + } else + if (verbose) + printk(KERN_INFO"acerhk: key polling not active\n"); +} + +static void start_polling(void) +{ + if (acerhk_polling_state != 1) { + acerhk_timer_poll.function = acerhk_poll_event; + acerhk_timer_poll.expires = jiffies + acerhk_polling_delay; + acerhk_timer_poll.data = get_nr_events(); + add_timer(&acerhk_timer_poll); + acerhk_polling_state = 1; + if (acerhk_type == TM_dritek) { + printk(KERN_INFO"acerhk: Your hardware does not need polling enabled for hotkeys to work, " + "you can safely disable polling by using the module parameter poll=0 (unless you " + "want to play around with the driver and see if there are buttons which need polling).\n"); + } + if (verbose) + printk(KERN_INFO"acerhk: starting key polling, every %d ms\n", acerhk_polling_delay); + } else + if (verbose) + printk(KERN_INFO"acerhk: key polling already active\n"); +} + +/* addedd by Antonio Cuni */ +static void start_blinking(void) +{ + if (acerhk_blueled_blinking == -1) { + // blinking was disabled... enable it! + acerhk_timer_blinking.function = acerhk_blink_event; + acerhk_timer_blinking.expires = jiffies + acerhk_blueled_blinking_delay; + acerhk_timer_blinking.data = 0; // not used + add_timer(&acerhk_timer_blinking); + acerhk_blueled_blinking = 0; + if (verbose) + printk(KERN_INFO "acerhk: starting blueled blinking\n"); + } else + if (verbose) + printk(KERN_INFO "acerhk: blueled already blinking\n"); +} + +/* Added by Antonio Cuni */ +static void stop_blinking(void) +{ + if (acerhk_blueled_blinking != -1) { + del_timer(&acerhk_timer_blinking); + if (verbose) + printk(KERN_INFO "acerhk: blueled blinking stopped\n"); + acerhk_blueled_blinking = -1; + } +} + +static void release_input(void) +{ + stop_polling(); + input_unregister_device(acerhk_input_dev_ptr); +} + +/* }}} */ + +/* {{{ procfs functions */ + +#ifndef CONFIG_PROC_FS + +static int acerhk_proc_init(void) +{ + return 1; +} +#else + +/* This macro frees the machine specific function from bounds checking and + * things like that... */ +#define PRINT_PROC(fmt,args...) \ + do { \ + *len += sprintf( buffer+*len, fmt, ##args ); \ + if (*begin + *len > offset + size) \ + return( 0 ); \ + if (*begin + *len < offset) { \ + *begin += *len; \ + *len = 0; \ + } \ + } while(0) + +static int pc_proc_infos( char *buffer, int *len, + off_t *begin, off_t offset, int size ) +{ + PRINT_PROC( "Acer hotkeys version %s\n", ACERHK_VERSION); + PRINT_PROC( "Model(Type)\t: %s(", acerhk_model_string); + switch(acerhk_type) { + default: + PRINT_PROC( "unknown)\n"); + break; + case TM_old: + PRINT_PROC( "old)\n"); + break; + case TM_new: + PRINT_PROC( "new)\n"); + break; + case TM_dritek: + PRINT_PROC( "Dritek)\n"); + break; + } + if (bios_routine != 0) { + PRINT_PROC( "request handler\t: 0x%x\n", bios_routine); + if (cmos_index) { + PRINT_PROC( "CMOS index\t: 0x%x\n", cmos_index); + PRINT_PROC( "events pending\t: %u\n", get_nr_events()); + } else { + PRINT_PROC( "CMOS index\t: not available\n"); + } + if (acerhk_polling_state == 1) + PRINT_PROC( "kernel polling\t: active\n"); + else + PRINT_PROC( "kernel polling\t: inactive\n"); + PRINT_PROC( "autoswitch wlan\t: "); + if (autowlan == 1) + PRINT_PROC( "enabled\n"); + else + PRINT_PROC( "disabled\n"); + } else { + PRINT_PROC( "request handler\t: not found\n"); + PRINT_PROC( "kernel polling\t: not possible\n"); + } + /* model specific infos */ + if (acerhk_type == TM_dritek) { + PRINT_PROC( "use of Dritek EC: "); + if (usedritek) + PRINT_PROC( "enabled\n"); + else + PRINT_PROC( "disabled\n"); + } + if (acerhk_type == TM_old) + PRINT_PROC( "preg400\t\t: 0x%p\n", preg400); + return (1); +} + +static int acerhk_proc_info( char *buffer, char **start, off_t offset, + int size, int *eof, void *data ) +{ + int len = 0; + off_t begin = 0; + + *eof = pc_proc_infos( buffer, &len, &begin, offset, size ); + + if (offset >= begin + len) + return( 0 ); + *start = buffer + (offset - begin); + return( size < begin + len - offset ? size : begin + len - offset ); + +} + +static int acerhk_proc_key( char *buffer, char **start, off_t offset, + int size, int *eof, void *data ) +{ + if (size >= 5 && offset == 0) { + if (acerhk_type == TM_dritek || acerhk_polling_state == 1) { + snprintf(buffer+offset, size, "n/a\n"); + } else { + snprintf(buffer+offset, size, "0x%02x\n", filter_idle_value(get_fnkey_event())); + } + *eof = 1; + return 5; + } + *eof = 1; + return 0; +} + +static int acerhk_proc_led(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + char str[4]; + int len; + if (count > 4) + len = 4; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[3] = '\0'; + if ( ( (len >= 2) && (!strncmp(str, "on", 2) || !strncmp(str, "an", 2)) ) + || str[0] == '1') + set_mail_led(1); + else + set_mail_led(0); + return len; +} + +static int acerhk_proc_wirelessled(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + char str[4]; + int len; + if (count > 4) + len = 4; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[3] = '\0'; + if ( ( (len >= 2) && (!strncmp(str, "on", 2) || !strncmp(str, "an", 2)) ) + || str[0] == '1') { + if (acerhk_model_features & TM_F_WLAN_EC1) + enable_wlan_ec_1(); + else if (acerhk_model_features & TM_F_WLAN_EC2) + enable_wlan_ec_2(); + else + wbutton_fct_2(1); + } + else { + if (acerhk_model_features & TM_F_WLAN_EC1) + disable_wlan_ec_1(); + else if (acerhk_model_features & TM_F_WLAN_EC2) + disable_wlan_ec_2(); + else + wbutton_fct_2(0); + } + return len; +} + + +/* Modified by Antonio Cuni: added support for blinking + possible values: + - off, 0: led always off + - on, an, 1: led alway on + - n (a number): led blinking; n is the delay between + two changes of state, in jiffies; n must + be > 50, to prevent the user from overloading + the kernel. + + */ +static int acerhk_proc_blueled(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + const int MAXLEN=11; + char str[MAXLEN]; + int len; + int isNumber; + + if (count > MAXLEN) + len = MAXLEN; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[MAXLEN - 1] = '\0'; + + /* try to parse a number */ + isNumber = sscanf(str, "%u", &acerhk_blueled_blinking_delay); + /* if the delay is 0, turn off the led */ + if (isNumber && acerhk_blueled_blinking_delay != 0 && acerhk_blueled_blinking_delay != 1) { + if (acerhk_blueled_blinking_delay < 50) + printk(KERN_INFO"acerhk: blinking request rejected. The delay must be > 50.\n"); + else { + if (verbose) + printk(KERN_INFO"acerhk: blinking delay set to %u.\n", acerhk_blueled_blinking_delay); + start_blinking(); + } + } else if (acerhk_blueled_blinking_delay == 1 || !strncmp(str, "on", 2) || !strncmp(str, "an", 2)) { + stop_blinking(); + if (acerhk_model_features & TM_F_BLUE_EC1) + enable_bluetooth_ec_1(); + else if (acerhk_model_features & TM_F_BLUE_EC2) + enable_bluetooth_ec_2(); + else + wbutton_fct_1(1); + } else { + /* it's 0 or everything else */ + stop_blinking(); + if (acerhk_model_features & TM_F_BLUE_EC1) + disable_bluetooth_ec_1(); + else if (acerhk_model_features & TM_F_BLUE_EC2) + disable_bluetooth_ec_2(); + else + wbutton_fct_1(0); + } + return len; +} + +#ifdef ACERDEBUG +static void do_debug(const char* buffer, unsigned long len) +{ + unsigned int h, i; + switch (buffer[0]) { + case 'b': + /* test WLAN on TM 4001 */ + switch (buffer[1]) { + case '0': + disable_wlan_ec_1(); + break; + case '1': + default: + enable_wlan_ec_1(); + } + break; + case 'B': + /* test BLUETOOTH on TM 4001 */ + switch (buffer[1]) { + case '0': + disable_bluetooth_ec_1(); + break; + case '1': + default: + enable_bluetooth_ec_1(); + } + break; + case 'D': + /* test "DMM Function Enabled" entry of TM 4150/4650 */ + enable_dmm_function(); + break; + case 'i': + case '1': +#ifndef KERNEL26 + MOD_INC_USE_COUNT; +#endif + break; + case 'e': + switch (buffer[1]) { + case '1': + start_polling(); + break; + default: + stop_polling(); + } + break; + case 'k': + for (i = 0; i <= 255;i++) { + input_report_key(acerhk_input_dev_ptr, i, 1); + input_report_key(acerhk_input_dev_ptr, i, 0); + } + break; + case 'm': + /* set mapping key names -> input events */ + sscanf(&buffer[2],"%x", &i); + h = buffer[1] - '0' + 1; + printk("acerhk: key name %x maps to %x\n", h, i); + acerhk_name2event[h] = i; + break; + case 'M': + /* test mute LED on dritek hardware */ + switch (buffer[1]) { + case '0': + disable_mute_led_ec(); + break; + case '1': + default: + enable_mute_led_ec(); + } + break; + case 'p': + printk("acerhk: pbutton = 0x%x\n", pbutton_fct()); + break; + case 's': + /* send key event to test the key translation in input system */ + sscanf(&buffer[1],"%x", &h); + printk("acerhk: sending key event 0x%x\n", h); + input_report_key(acerhk_input_dev_ptr, h, 1); + input_report_key(acerhk_input_dev_ptr, h, 0); + break; + case 'S': + /* simulate key codes to test the key translation in acerhk */ + sscanf(&buffer[1],"%x", &h); + send_key_event(transl8_key_code(h)); + break; + case 't': + printk("acerhk: thermal event = 0x%x\n", get_thermal_event()); + break; + case 'w': + /* test the wbutton functions, someone really needs to have another look + at the windows driver */ + switch (buffer[1]) { + case '2': + printk("acerhk: wbutton_2(%d) = 0x%x\n", buffer[2]-'0', wbutton_fct_2(buffer[2]-'0')); + break; + case '1': + default: + printk("acerhk: wbutton_1(%d) = 0x%x\n", buffer[2]-'0', wbutton_fct_1(buffer[2]-'0')); + } + break; + case 'W': + /* test wireless HW/LED on some models using dritek hardware */ + switch (buffer[1]) { + case '0': + disable_wireless_ec(); + break; + case '1': + default: + enable_wireless_ec(); + } + break; + case 'v': + verbose = buffer[1]-'0'; + printk("acerhk: verbosity level changed to %d\n", verbose); + break; + case 'd': + case '0': + default: +#ifndef KERNEL26 + MOD_DEC_USE_COUNT; +#endif + break; + } +} + +static int acerhk_proc_debug(struct file* file, const char* buffer, + unsigned long count, void* data) +{ + char str[5]; + int len; + if (count > 5) + len = 5; + else + len = count; + if (copy_from_user(str, buffer, len)) + return -EFAULT; + str[4] = '\0'; + do_debug(str, len); + return len; +} +#endif + +static int acerhk_proc_init(void) +{ + int retval; + struct proc_dir_entry *entry; + /* create own directory */ + proc_acer_dir = proc_mkdir("driver/acerhk", NULL); + if (proc_acer_dir == NULL) { + retval = 0; + printk(KERN_INFO"acerhk: could not create /proc/driver/acerhk\n"); + } + else { + proc_acer_dir->owner = THIS_MODULE; + /* now create several files, first general info ... */ + entry = create_proc_read_entry("info", + 0444, proc_acer_dir, acerhk_proc_info, NULL); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create info file\n"); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { + entry->owner = THIS_MODULE; + /* ... last pressed key ... */ + entry = create_proc_read_entry("key", + 0444, proc_acer_dir, acerhk_proc_key, NULL); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create key file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { + entry->owner = THIS_MODULE; + /* ... and led control file */ + entry = create_proc_entry("led", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create LED file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } + else { + entry->write_proc = acerhk_proc_led; + entry->owner = THIS_MODULE; + /* ... and wireless led controll file */ + entry = create_proc_entry("wirelessled", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create wirelessled file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } + else { + entry->write_proc = acerhk_proc_wirelessled; + entry->owner = THIS_MODULE; + /* ... and bluetooth led controll file */ + entry = create_proc_entry("blueled", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create blueled file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("wirelessled", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } else { + entry->write_proc = acerhk_proc_blueled; + entry->owner = THIS_MODULE; + retval = 1; +#ifdef ACERDEBUG + /* add extra file for debugging purposes */ + entry = create_proc_entry("debug", 0222, proc_acer_dir); + if (entry == NULL) { + printk(KERN_INFO"acerhk: cannot create debug file\n"); + remove_proc_entry("info", proc_acer_dir); + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("wirelessled", proc_acer_dir); + remove_proc_entry("blueled", proc_acer_dir); + remove_proc_entry("driver/acerhk", NULL); + retval = 0; + } + else { + entry->write_proc = acerhk_proc_debug; + entry->owner = THIS_MODULE; + retval = 1; + } +#endif + } + } + } + } + } + } + return retval; +} + +static void acerhk_proc_cleanup(void) +{ + if (proc_acer_dir) { + remove_proc_entry("info", proc_acer_dir); + /* On dritek type hardware key file is already removed */ + if (acerhk_type != TM_dritek) + remove_proc_entry("key", proc_acer_dir); + remove_proc_entry("led", proc_acer_dir); + remove_proc_entry("wirelessled", proc_acer_dir); + remove_proc_entry("blueled", proc_acer_dir); +#ifdef ACERDEBUG + remove_proc_entry("debug", proc_acer_dir); +#endif + remove_proc_entry("driver/acerhk", NULL); + proc_acer_dir = NULL; + } +} + +#endif /* CONFIG_PROC_FS */ + +/* }}} */ + +/* {{{ file operations */ + +static int acerhk_ioctl( struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg ) +{ + int retval; + switch( cmd ) { + case ACERHK_GET_KEYCOUNT: + { + char nr; + nr = get_nr_events(); + put_user(nr, (char*)arg); + retval = 0; + break; + } + case ACERHK_GET_KEYID: + { + char id; + id = get_fnkey_event(); + put_user(id, (char*)arg); + retval = 0; + break; + } + case ACERHK_CONNECT: + launch_connect(1); + retval = 0; + break; + case ACERHK_START_POLLING: + start_polling(); + retval = 0; + break; + case ACERHK_STOP_POLLING: + stop_polling(); + retval = 0; + break; + case ACERHK_DISCONNECT: + launch_connect(0); + retval = 0; + break; + case ACERHK_GET_THERMAL_EVENT: + { + short event; + event = get_thermal_event(); + put_user(event, (short*)arg); + retval = 0; + break; + } + case ACERHK_MAIL_LED_OFF: + set_mail_led(0); + retval = 0; + break; + case ACERHK_MAIL_LED_ON: + set_mail_led(1); + retval = 0; + break; + case ACERHK_GET_KEY_MAP: + if (copy_to_user((t_map_name2event*)arg, &acerhk_name2event, sizeof(acerhk_name2event))) + retval = -EFAULT; + else + retval = 0; + break; + case ACERHK_SET_KEY_MAP: + if (copy_from_user(&acerhk_name2event, (t_map_name2event*)arg, sizeof(acerhk_name2event))) + retval = -EFAULT; + else { + if (verbose) { + printk(KERN_INFO"acerhk: changed key mapping\n"); + print_mapping(); + } + retval = 0; + } + break; + default: + retval = -EINVAL; + } + return retval; +} + +#ifdef ACERDEBUG +static ssize_t acerhk_write (struct file* file, const char* buffer, size_t length, loff_t* offset) +{ + if (length) + do_debug(buffer, length); + return length; +} +#endif + +static int acerhk_open( struct inode *inode, struct file *file ) +{ + return 0; +} + +static int acerhk_release( struct inode *inode, struct file *file ) +{ + return 0; +} + +static struct file_operations acerhk_fops = { + owner: THIS_MODULE, + ioctl: acerhk_ioctl, + open: acerhk_open, +#ifdef ACERDEBUG + write: acerhk_write, +#endif + release: acerhk_release, +}; + +static struct miscdevice acerhk_dev = { + MISC_DYNAMIC_MINOR, + "acerhk", + &acerhk_fops +}; + +/* }}} */ + +static void __init model_init(void) +{ + /* set callroutine, features and keymap for model */ + setup_model_features(acerhk_series); + /* override initial state of wireless hardware if specified by module options */ + if (wlan_state >= 0) acerhk_wlan_state = wlan_state; + if (bluetooth_state >= 0) acerhk_bluetooth_state = bluetooth_state; + /* Launch connect only if available */ + if (acerhk_model_features & TM_F_CONNECT) { + if (verbose) + printk(KERN_INFO"acerhk: Model type %d, calling launch_connect(1)\n", + acerhk_type); + launch_connect(1); + } + if ( acerhk_type != TM_dritek ) { + get_cmos_index(); + } + if ( acerhk_type == TM_dritek ) { + enable_dritek_keyboard(); + } + /* added by Antonio Cuni */ + init_timer(&acerhk_timer_blinking); +} + + +static void __exit acerhk_cleanup_module (void); +static int __init acerhk_init(void) +{ + int ret; + + ret = misc_register( &acerhk_dev ); + if (ret) { + printk(KERN_ERR "acerhk: can't misc_register on minor=%d\n", ACERHK_MINOR); + ret = -EAGAIN; + } + else if (!acerhk_proc_init()) { + printk(KERN_ERR "acerhk: can't create procfs entries\n"); + ret = -ENOMEM; + misc_deregister( &acerhk_dev ); + } + else { + reg1 = ioremap(0xf0000, 0xffff); + if (verbose > 1) + printk(KERN_INFO"acerhk: area from 0xf000 to 0xffff mapped to %p\n", reg1); + reg2 = ioremap(0xe0000, 0xffff); + if (verbose > 1) + printk(KERN_INFO"acerhk: area from 0xe000 to 0xffff mapped to %p\n", reg2); + /* the area 0x400 is used as data area by earlier (520) series */ + preg400 = ioremap(0x400, 0xfff); + if (verbose > 1) + printk(KERN_INFO"acerhk: area from 0x400 to 0x13ff mapped to %p\n", preg400); + /* attach to input system */ + init_input(); + memset(acerhk_model_string, 0x00, ACERHK_MODEL_STRLEN); +#ifdef DUMMYHW + acerhk_model_addr = (void*)0x12345678; + /* copy the string, but not more than 15 characters */ + strncpy(acerhk_model_string, "TravelmateDummy", ACERHK_MODEL_STRLEN-1); + /* set callroutine for model */ + if (force_series) + acerhk_series = force_series; + else + acerhk_series = 2000; + setup_model_features(acerhk_series); + printk(KERN_INFO "Acer Travelmate hotkey driver v" ACERHK_VERSION " dummy\n"); + if ( acerhk_type == TM_dritek ) + enable_dritek_keyboard(); + if (poll) + start_polling(); + init_timer(&acerhk_timer_blinking); +#else + bios_routine = find_hk_area(); + if (!force_series) + probe_model(); + else { + if (verbose) + printk(KERN_INFO"acerhk: forced laptop series to %d\n", force_series); + acerhk_series = force_series; + } + /* do model specific initialization */ + model_init(); + /* Without a bios routine we cannot do anything except on dritek + type HW, unload on other types */ + if (bios_routine || (acerhk_type == TM_dritek)) { + ret = 0; + if (verbose && bios_routine) + printk(KERN_INFO"acerhk: bios routine found at 0x%x\n", bios_routine); + printk(KERN_INFO "Acer Travelmate hotkey driver v" ACERHK_VERSION "\n"); + /* If automatic switching of wlan is wanted but polling is disabled, + automatically enable it */ + if (!poll && autowlan) { + printk(KERN_INFO "Automatic switching of wireless hardware needs polling, enabling it\n"); + poll = 1; + } + /* start automatic polling of key presses if wanted and bios routine found */ + if (poll && bios_routine) + start_polling(); + } else { + printk(KERN_ERR "acerhk: can't find bios routine, cannot do anything for you, sorry!\n"); + ret = -ENOMEM; + acerhk_cleanup_module(); + } +#endif + } + return ret; +} + +static void __exit acerhk_cleanup_module (void) +{ + acerhk_proc_cleanup(); + stop_blinking(); + if (reg1) + iounmap(reg1); + if (reg2) + iounmap(reg2); + if (preg400) + iounmap(preg400); + release_input(); + misc_deregister( &acerhk_dev ); + if ( acerhk_type == TM_dritek ) { + disable_dritek_keyboard(); + } + if (verbose > 2) + printk(KERN_INFO "acerhk: unloaded\n"); +} + +module_init(acerhk_init); +module_exit(acerhk_cleanup_module); + +MODULE_AUTHOR("Olaf Tauber"); +MODULE_DESCRIPTION("AcerHotkeys extra buttons keyboard driver"); +MODULE_LICENSE("GPL"); + +#ifndef KERNEL26 +EXPORT_NO_SYMBOLS; +#endif + +#else +#error This driver is only available for X86 architecture +#endif +/* + * Local variables: + * c-indent-level: 4 + * tab-width: 4 + * End: + */ + --- linux-2.6.28.orig/ubuntu/misc/fsam7400.c +++ linux-2.6.28/ubuntu/misc/fsam7400.c @@ -0,0 +1,373 @@ +/******************************************************************************* + + 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. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Author: + Marcel Naziri + + Based on: + pbe5.c by Pedro Ramalhais + + Many thanks to: + Pedro Ramalhais for spending several nights with me on IRC disassembling + the structure of the windows driver files... :) + +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_NAME "fsam7400" +#define DRV_VERSION "0.4.0" +#define DRV_DESCRIPTION "SW RF kill switch for Fujitsu Siemens Amilo M 7400" +#define DRV_COPYRIGHT "Copyright(c) 2004 zwobbl ;)" +#define DRV_AUTHOR "Marcel Naziri" +#define DRV_LICENSE "GPL" + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_AUTHOR(DRV_AUTHOR); +MODULE_LICENSE(DRV_LICENSE); + +#define RADIO_NONE 0xFFFFFFFF +#define RADIO_OFF 0x00000000 +#define RADIO_ON 0x00000010 + +static int radio = RADIO_NONE; +module_param(radio, uint, 0400); +MODULE_PARM_DESC(radio, "desired radio state when loading module"); + +static int autooff = 1; +module_param(autooff, uint, 0400); +MODULE_PARM_DESC(autooff, "turns radio off when unloading module " + "(default)"); + +static int uid = 0; +module_param(uid, uint, 0400); +MODULE_PARM_DESC(uid, "user ID for proc entry"); + +static int gid = 0; +module_param(gid, uint, 0400); +MODULE_PARM_DESC(gid, "group ID for proc entry"); + +/* some more or less useful macros */ +#ifdef CONFIG_IPW2100_DEBUG +#define DEBUG_OUT0(a) printk(KERN_INFO DRV_NAME ": " a) +#define DEBUG_OUT1(a,b) printk(KERN_INFO DRV_NAME ": " a,b) +#define DEBUG_OUT2(a,b,c) printk(KERN_INFO DRV_NAME ": " a,b,c) +#define DEBUG_OUT3(a,b,c,d) printk(KERN_INFO DRV_NAME ": " a,b,c,d) +#else +#define DEBUG_OUT0(a) +#define DEBUG_OUT1(a,b) +#define DEBUG_OUT2(a,b,c) +#define DEBUG_OUT3(a,b,c,d) +#endif + +#define ONOFF(x) (x) ? "ON" : "OFF" +#define RADIO_ONOFF(x) (x) == RADIO_ON ? "ON" : "OFF" +#define TOUL(x) (unsigned long) (x) + +/* + * NOTE: These values were obtained from disassembling the wbutton.sys driver + * installed in the Fujitsu Siemens Amilo M 7400 laptop. The names were guessed, + * so don't rely on them. + */ + +/*** hardware dependant stuff ***/ + +#define BIOS_CODE_ADDR 0x000F0000 +#define BIOS_CODE_ALT_MASK 0xFFFFC000 + +#define BIOS_CODE_MAPSIZE 0x010000 +#define BIOS_CODE_ALT_MAPSIZE 0x004000 + +#define BIOS_MAGIC_COMMAND 0x9610 +#define BIOS_MAGIC_OFF 0x0035 +#define BIOS_MAGIC_ON 0x0135 +#define BIOS_MAGIC_CHECK 0x0235 + +#define PTR_POSITION 5 +#define ALLIGNED_STEP 0x10 + +#define BIOS_SIGN_SIZE 4 +static const char bios_sign[] = { + 0x42, 0x21, 0x55, 0x30 +}; + +#define WLAN_DISABLED_IN_BIOS 0x01 +#define WLAN_ENABLED_IN_BIOS 0x03 + +static unsigned long bios_code = 0; + +static int fsam_bios_routine(int eax, int ebx) +{ + __asm__ __volatile__( + "call *%3 \t\n" + : "=a"(eax) + : "a"(eax), "b"(ebx), "c"(bios_code) + ); + return (eax & 0xFF); +} + +static int fsam_call_bios(int value) +{ + if (bios_code) { + int command = BIOS_MAGIC_COMMAND; + + DEBUG_OUT2("bios routine gets parameter eax=%X and ebx=%X\n", + command, value); + + value = fsam_bios_routine(command, value); + + DEBUG_OUT1("bios routine results %X\n", value); + return value; + } + return ~0; +} + +/* pointer to mapped memory*/ +static void *mem_code = NULL; + +static inline void fsam_unmap_memory(void) +{ + bios_code = 0; + if (mem_code) { + iounmap(mem_code); + } +} + +static inline int fsam_map_memory(void) +{ + const unsigned long max_offset = BIOS_CODE_MAPSIZE - BIOS_SIGN_SIZE - PTR_POSITION; + unsigned long offset; + unsigned int addr; + + mem_code = ioremap(BIOS_CODE_ADDR, BIOS_CODE_MAPSIZE); + if (!mem_code) + goto fail; + + DEBUG_OUT3("physical memory %x-%x mapped to virtual address %p\n", + BIOS_CODE_ADDR, BIOS_CODE_ADDR+BIOS_CODE_MAPSIZE, mem_code); + + for ( offset = 0; offset < max_offset; offset += ALLIGNED_STEP ) + if (check_signature(mem_code + offset, bios_sign, BIOS_SIGN_SIZE)) + break; + + if (offset >= max_offset) + goto fail; + + DEBUG_OUT1("bios signature found at offset %lx\n", offset); + + addr = readl(mem_code + offset + PTR_POSITION); + + if (addr < BIOS_CODE_ADDR) + { + DEBUG_OUT0("bios routine out of memory range, " + "doing some new memory mapping...\n"); + iounmap(mem_code); + mem_code = NULL; + + addr &= BIOS_CODE_ALT_MASK; + + mem_code = ioremap(addr, BIOS_CODE_ALT_MAPSIZE); + if (!mem_code) + goto fail; + + DEBUG_OUT3("physical memory %x-%x mapped to virtual address %p\n", + addr, addr+BIOS_CODE_ALT_MAPSIZE, mem_code); + + addr &= 0x3FFF; + } + else + addr &= 0xFFFF; + + bios_code = addr + TOUL(mem_code); + DEBUG_OUT1("supposed address of bios routine is %lx\n", bios_code); + + return 1; + + fail: + fsam_unmap_memory(); + return 0; +} + +/*** interface stuff ***/ + +static void rfkill_set_radio(int value) +{ + radio = value == RADIO_ON ? fsam_call_bios(BIOS_MAGIC_ON) : + fsam_call_bios(BIOS_MAGIC_OFF); +} + +static inline int rfkill_get_radio(void) +{ + return radio; +} + +static inline int rfkill_supported(void) +{ + return bios_code != 0; +} + +static inline void rfkill_initialize(void) { + fsam_map_memory(); + + if (rfkill_supported()) { + radio = radio != RADIO_NONE + ? ( radio ? RADIO_ON : RADIO_OFF ) /*module parameter*/ + : ( fsam_call_bios(BIOS_MAGIC_CHECK) == WLAN_ENABLED_IN_BIOS + ? RADIO_ON : RADIO_OFF ); + } +} + +static inline void rfkill_uninitialize(void) { + fsam_unmap_memory(); +} + +/*** proc stuff ***/ + +static inline int common_proc_set_radio(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + unsigned long len = 4; + char newstate[len]; + + len = count < len ? count : len; + + if ( copy_from_user(newstate, buffer, len) != 0 ) + return -EFAULT; + + if ( (*newstate == '1' || *newstate == '0') && + (count == 1 || isspace(newstate[1])) ) + rfkill_set_radio(*newstate == '1' ? RADIO_ON : RADIO_OFF); + else + if ( !strncmp(newstate, "on", 2) && + (count == 2 || isspace(newstate[2])) ) + rfkill_set_radio(RADIO_ON); + else + if ( !strncmp(newstate, "off", 3) && + (count == 3 || isspace(newstate[3])) ) + rfkill_set_radio(RADIO_OFF); + + return count; +} + +static inline int common_proc_get_radio(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + int len = snprintf(page, count, DRV_DESCRIPTION ", v" DRV_VERSION "\n" + " auto-off is %s\n", + ONOFF(autooff)); + len += snprintf(page+len, count-len, " radio state is %s\n", + RADIO_ONOFF(rfkill_get_radio())); + *eof = 1; + + return len; +} + +#define PROC_DIR "driver/wireless" +#define PROC_RADIO "radio" + +static struct proc_dir_entry *dir_base = NULL; + +static inline void common_proc_cleanup(void) +{ + if (dir_base) { + remove_proc_entry(PROC_RADIO, dir_base); + remove_proc_entry(PROC_DIR, NULL); + dir_base = NULL; + } +} + +static inline int common_proc_init(void) +{ + struct proc_dir_entry *ent; + int err = 0; + + dir_base = proc_mkdir(PROC_DIR, NULL); + if (dir_base == NULL) { + printk(KERN_ERR DRV_NAME ": Unable to initialize /proc/" PROC_DIR "\n"); + err = -ENOMEM; + goto fail; + } + + ent = create_proc_entry(PROC_RADIO, + S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP, + dir_base); + ent->uid = uid; + ent->gid = gid; + if (ent) { + ent->read_proc = common_proc_get_radio; + ent->write_proc = common_proc_set_radio; + } else { + printk(KERN_ERR DRV_NAME ": Unable to initialize /proc/" + PROC_DIR "/" PROC_RADIO "\n"); + err = -ENOMEM; + goto fail; + } + return 0; + + fail: + common_proc_cleanup(); + return err; +} + +/*** module stuff ***/ + +static int __init common_init(void) +{ + printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", v" DRV_VERSION "\n"); + printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n"); + + rfkill_initialize(); + + if (rfkill_supported()) { + common_proc_init(); + if (radio != RADIO_NONE) + rfkill_set_radio(radio); + } else + printk(KERN_INFO DRV_NAME ": no supported wireless hardware found\n"); + + return 0; +} + +static void __exit common_exit(void) +{ + if (rfkill_supported() && autooff) + rfkill_set_radio(RADIO_OFF); + + common_proc_cleanup(); + rfkill_uninitialize(); + + printk(KERN_INFO DRV_NAME ": module removed successfully\n"); +} + +module_init(common_init); +module_exit(common_exit); + +/* + 1 2 3 4 5 6 7 +12345678901234567890123456789012345678901234567890123456789012345678901234567890 +*/ --- linux-2.6.28.orig/ubuntu/misc/Makefile +++ linux-2.6.28/ubuntu/misc/Makefile @@ -0,0 +1,15 @@ +# +# Makefile for Ubuntu additional drivers +# + +obj-$(CONFIG_USB_APPLEIR) += appleir.o +obj-$(CONFIG_BLK_DEV_DM_BBR) += dm-bbr.o +obj-$(CONFIG_INPUT_ACERHK) += acerhk.o +obj-$(CONFIG_LMPCM_USB) += lmpcm_usb.o +obj-$(CONFIG_TP_SMAPI) += tp_smapi.o +obj-$(CONFIG_TP_SMAPI_EC) += thinkpad_ec.o +obj-$(CONFIG_FSAM7400) += fsam7400.o + +obj-m += media/ wireless/ + +CFLAGS_dm-bbr.o += -I$(srctree)/drivers/md --- linux-2.6.28.orig/ubuntu/misc/appleir.c +++ linux-2.6.28/ubuntu/misc/appleir.c @@ -0,0 +1,401 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Version Information + * + */ + +#if 0 +#define DUMP_PACKETS +#else +#undef DUMP_PACKETS +#endif + +#define DRIVER_VERSION "v1.1" +#define DRIVER_AUTHOR "James McKenzie" +#define DRIVER_DESC "USB Apple MacMini IR Receiver driver" +#define DRIVER_LICENSE "GPL" + +MODULE_AUTHOR (DRIVER_AUTHOR); +MODULE_DESCRIPTION (DRIVER_DESC); +MODULE_LICENSE (DRIVER_LICENSE); + +#ifndef USB_VENDOR_ID_APPLE +#define USB_VENDOR_ID_APPLE 0x05ac +#endif +#ifndef USB_DEVICE_ID_APPLE_IR +#define USB_DEVICE_ID_APPLE_IR 0x8240 +#endif +#ifndef USB_DEVICE_ID_APPLE_IR2 +#define USB_DEVICE_ID_APPLE_IR2 0x8242 +#endif + +#define URB_SIZE 32 + +#define MAX_KEYS 8 +#define MAX_KEYS_MASK (MAX_KEYS - 1 ) + +struct appleir +{ + struct input_dev *dev; + uint8_t *data; + dma_addr_t dma_buf; + struct usb_device *usbdev; + struct urb *urb; + int timer_initted; + struct timer_list key_up_timer; + int current_key; + char phys[32]; +}; + + +static struct usb_device_id appleir_ids[] = { + {USB_DEVICE (USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR),.driver_info = 0}, + {USB_DEVICE (USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR2),.driver_info = 0}, + {} +}; + +MODULE_DEVICE_TABLE (usb, appleir_ids); + + +/* I have two devices both of which report the following */ +/* 25 87 ee 83 0a + */ +/* 25 87 ee 83 0c - */ +/* 25 87 ee 83 09 << */ +/* 25 87 ee 83 06 >> */ +/* 25 87 ee 83 05 >" */ +/* 25 87 ee 83 03 menu */ +/* 26 00 00 00 00 for key repeat*/ + +/* Thomas Glanzmann reports the following responses */ +/* 25 87 ee ca 0b + */ +/* 25 87 ee ca 0d - */ +/* 25 87 ee ca 08 << */ +/* 25 87 ee ca 07 >> */ +/* 25 87 ee ca 04 >" */ +/* 25 87 ee ca 02 menu */ +/* 26 00 00 00 00 for key repeat*/ +/* He also observes the following event sometimes */ +/* sent after a key is release, which I interpret */ +/* as a flat battery message */ +/* 25 87 e0 ca 06 flat battery */ + +/* Alexandre Karpenko reports the following responses for Device ID 0x8242 */ +/* 25 87 ee 47 0b + */ +/* 25 87 ee 47 0d - */ +/* 25 87 ee 47 08 << */ +/* 25 87 ee 47 07 >> */ +/* 25 87 ee 47 04 >" */ +/* 25 87 ee 47 02 menu */ +/* 26 87 ee 47 ** for key repeat (** is the code of the key being held) */ + + +static int keymap[MAX_KEYS] = { + KEY_RESERVED, KEY_MENU, + KEY_PLAYPAUSE, KEY_FORWARD, + KEY_BACK, KEY_VOLUMEUP, + KEY_VOLUMEDOWN, KEY_RESERVED +}; + +static void +dump_packet (struct appleir *appleir, char *msg, uint8_t * data, int len) +{ + int i; + + printk (KERN_ERR "appleir: %s (%d bytes)", msg, len); + + for (i = 0; i < len; ++i) + { + printk (" %02x", data[i]); + } + + printk ("\n"); +} + + +static void +key_up (struct appleir *appleir, int key) +{ + //printk (KERN_ERR "key %d up\n", key); + input_report_key (appleir->dev, key, 0); + input_sync (appleir->dev); +} + +static void +key_down (struct appleir *appleir, int key) +{ + //printk (KERN_ERR "key %d down\n", key); + input_report_key (appleir->dev, key, 1); + input_sync (appleir->dev); +} + +static void +battery_flat (struct appleir *appleir) +{ + printk (KERN_ERR "appleir: possible flat battery?\n"); +} + +static void +key_up_tick (unsigned long data) +{ + struct appleir *appleir = (struct appleir *) data; + + if (appleir->current_key) + { + key_up (appleir, appleir->current_key); + appleir->current_key = 0; + } +} + +static void +new_data (struct appleir *appleir, uint8_t * data, int len) +{ + static const uint8_t keydown[] = { 0x25, 0x87, 0xee }; + static const uint8_t keyrepeat[] = { 0x26 }; + static const uint8_t flatbattery[] = { 0x25, 0x87, 0xe0 }; + +#ifdef DUMP_PACKETS + dump_packet (appleir, "received", data, len); +#endif + + if (len != 5) + return; + + if (!memcmp (data, keydown, sizeof (keydown))) + { + /*If we already have a key down, take it up before marking */ + /*this one down */ + if (appleir->current_key) + key_up (appleir, appleir->current_key); + appleir->current_key = keymap[(data[4] >> 1) & MAX_KEYS_MASK]; + + key_down (appleir, appleir->current_key); + /*remote doesn't do key up, either pull them up, in the test */ + /*above, or here set a timer which pulls them up after 1/8 s */ + mod_timer (&appleir->key_up_timer, jiffies + HZ / 8); + + return; + } + + if (!memcmp (data, keyrepeat, sizeof (keyrepeat))) + { + key_down (appleir, appleir->current_key); + /*remote doesn't do key up, either pull them up, in the test */ + /*above, or here set a timer which pulls them up after 1/8 s */ + mod_timer (&appleir->key_up_timer, jiffies + HZ / 8); + return; + } + + if (!memcmp (data, flatbattery, sizeof (flatbattery))) + { + battery_flat (appleir); + /*Fall through */ + } + + dump_packet (appleir, "unknown packet", data, len); +} + +static void +appleir_urb (struct urb *urb) +{ + struct appleir *appleir = urb->context; + int retval; + + switch (urb->status) + { + case 0: + new_data (appleir, urb->transfer_buffer, urb->actual_length); + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + /* this urb is terminated, clean up */ + dbg ("%s - urb shutting down with status: %d", __FUNCTION__, + urb->status); + return; + default: + dbg ("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); + } + + retval = usb_submit_urb (urb, GFP_ATOMIC); + if (retval) + err ("%s - usb_submit_urb failed with result %d", __FUNCTION__, retval); +} + + +static int +appleir_open (struct input_dev *dev) +{ + struct appleir *appleir = (struct appleir *)input_get_drvdata(dev); + + if (usb_submit_urb (appleir->urb, GFP_KERNEL)) + return -EIO; + + return 0; +} + +static void +appleir_close (struct input_dev *dev) +{ + struct appleir *appleir = (struct appleir *)input_get_drvdata(dev); + usb_kill_urb (appleir->urb); + del_timer_sync (&appleir->key_up_timer); +} + + + + +static int +appleir_probe (struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev (intf); + struct usb_endpoint_descriptor *endpoint; + struct appleir *appleir = NULL; + struct input_dev *input_dev; + int i; + + appleir = kzalloc (sizeof (struct appleir), GFP_KERNEL); + if (!appleir) + goto fail; + + memset (appleir, 0, sizeof (struct appleir)); + + + appleir->data = + usb_buffer_alloc (dev, URB_SIZE, GFP_KERNEL, &appleir->dma_buf); + if (!appleir->data) + goto fail; + + appleir->urb = usb_alloc_urb (0, GFP_KERNEL); + if (!appleir->urb) + goto fail; + + appleir->usbdev = dev; + + input_dev = input_allocate_device (); + if (!input_dev) + goto fail; + + appleir->dev = input_dev; + + + usb_make_path (dev, appleir->phys, sizeof (appleir->phys)); + strlcpy (appleir->phys, "/input0", sizeof (appleir->phys)); + + input_dev->name = "Apple Mac mini infrared remote control driver"; + input_dev->phys = appleir->phys; + usb_to_input_id (dev, &input_dev->id); + input_dev->dev.parent = &intf->dev; + input_set_drvdata(input_dev, appleir); + + input_dev->evbit[0] = BIT (EV_KEY) | BIT (EV_REP); + input_dev->ledbit[0] = 0; + + for (i = 0; i < MAX_KEYS; i++) + { + set_bit (keymap[i], input_dev->keybit); + } + + clear_bit (0, input_dev->keybit); + + input_dev->open = appleir_open; + input_dev->close = appleir_close; + + endpoint = &intf->cur_altsetting->endpoint[0].desc; + + usb_fill_int_urb (appleir->urb, dev, + usb_rcvintpipe (dev, endpoint->bEndpointAddress), + appleir->data, 8, + appleir_urb, appleir, endpoint->bInterval); + + appleir->urb->transfer_dma = appleir->dma_buf; + appleir->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + usb_set_intfdata (intf, appleir); + + init_timer (&appleir->key_up_timer); + + appleir->key_up_timer.function = key_up_tick; + appleir->key_up_timer.data = (unsigned long) appleir; + + appleir->timer_initted++; + + input_register_device (appleir->dev); + + return 0; + +fail: + + if (appleir) + { + + + if (appleir->data) + usb_buffer_free (dev, URB_SIZE, appleir->data, appleir->dma_buf); + + if (appleir->timer_initted) + del_timer_sync (&appleir->key_up_timer); + + if (appleir->dev) + input_free_device (appleir->dev); + + kfree (appleir); + } + + return -ENOMEM; +} + +static void +appleir_disconnect (struct usb_interface *intf) +{ + struct appleir *appleir = usb_get_intfdata (intf); + + usb_set_intfdata (intf, NULL); + if (appleir) + { + input_unregister_device (appleir->dev); + if (appleir->timer_initted) + del_timer_sync (&appleir->key_up_timer); + usb_kill_urb (appleir->urb); + usb_free_urb (appleir->urb); + usb_buffer_free (interface_to_usbdev (intf), URB_SIZE, appleir->data, + appleir->dma_buf); + kfree (appleir); + } +} + +static struct usb_driver appleir_driver = { + .name = "appleir", + .probe = appleir_probe, + .disconnect = appleir_disconnect, + .id_table = appleir_ids, +}; + +static int __init +appleir_init (void) +{ + int retval; + retval = usb_register (&appleir_driver); + if (retval) + goto out; + info (DRIVER_VERSION ":" DRIVER_DESC); +out: + return retval; +} + +static void __exit +appleir_exit (void) +{ + usb_deregister (&appleir_driver); +} + +module_init (appleir_init); +module_exit (appleir_exit); --- linux-2.6.28.orig/ubuntu/misc/thinkpad_ec.h +++ linux-2.6.28/ubuntu/misc/thinkpad_ec.h @@ -0,0 +1,47 @@ +/* + * thinkpad_ec.h - interface to ThinkPad embedded controller LPC3 functions + * + * Copyright (C) 2005 Shem Multinymous + * + * 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 _THINKPAD_EC_H +#define _THINKPAD_EC_H + +#ifdef __KERNEL__ + +#define TP_CONTROLLER_ROW_LEN 16 + +/* EC transactions input and output (possibly partial) vectors of 16 bytes. */ +struct thinkpad_ec_row { + u16 mask; /* bitmap of which entries of val[] are meaningful */ + u8 val[TP_CONTROLLER_ROW_LEN]; +}; + +extern int __must_check thinkpad_ec_lock(void); +extern int __must_check thinkpad_ec_try_lock(void); +extern void thinkpad_ec_unlock(void); + +extern int thinkpad_ec_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *data); +extern int thinkpad_ec_try_read_row(const struct thinkpad_ec_row *args, + struct thinkpad_ec_row *mask); +extern int thinkpad_ec_prefetch_row(const struct thinkpad_ec_row *args); +extern void thinkpad_ec_invalidate(void); + + +#endif /* __KERNEL */ +#endif /* _THINKPAD_EC_H */ --- linux-2.6.28.orig/ubuntu/misc/BOM +++ linux-2.6.28/ubuntu/misc/BOM @@ -0,0 +1,3 @@ +Module: dm-bbr +Downloaded from: http://dev.gentoo.org/~dsd/gentoo-sources/patches-2.6.25-2.htm +Comments: Changes in md headers for 2.6.26 required some munging. --- linux-2.6.28.orig/ubuntu/misc/wireless/Kconfig +++ linux-2.6.28/ubuntu/misc/wireless/Kconfig @@ -0,0 +1,24 @@ +menu "Wireless Drivers" + +config WIRELESS_ACX + tristate "TI ACX1xx based wireless cards (CardBus/PCI/USB)" + default m + depends on NET && IEEE80211 + +config P80211 + tristate + default n + depends on NET + +config PRISM2_USB + tristate "Prism2 based USB devices" + default m + depends on NET + select P80211 + +config WIRELESS_AT76 + tristate "Wireless devices based on Atmel AT76C503A/505/505A" + default m + depends on NET && IEEE80211 + +endmenu --- linux-2.6.28.orig/ubuntu/misc/wireless/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/Makefile @@ -0,0 +1,8 @@ +# +# Makefile for Ubuntu additional drivers +# + +obj-$(CONFIG_WIRELESS_ACX) += acx/ +obj-$(CONFIG_P80211) += p80211/ +obj-$(CONFIG_PRISM2_USB) += prism2_usb/ +obj-$(CONFIG_WIRELESS_AT76) += at76/ --- linux-2.6.28.orig/ubuntu/misc/wireless/at76/at76c503.c +++ linux-2.6.28/ubuntu/misc/wireless/at76/at76c503.c @@ -0,0 +1,7138 @@ +/* -*- linux-c -*- */ +/* + * USB at76c503/at76c505 driver + * + * Copyright (c) 2002 - 2003 Oliver Kurth + * Copyright (c) 2004 Joerg Albert + * Copyright (c) 2004 Nick Jones + * Copyright (c) 2004 Balint Seeber + * + * 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 file is part of the Berlios driver for WLAN USB devices based on the + * Atmel AT76C503A/505/505A. See at76c503.h for details. + * + * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for rtnl_lock() */ +#include + +#ifdef CONFIG_IPAQ_HANDHELD +#include +#include +#include +#include +#endif + +#include "at76c503.h" + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_UPDATED 0x01 +#define IW_QUAL_LEVEL_UPDATED 0x02 +#define IW_QUAL_NOISE_UPDATED 0x04 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#endif + +#if WIRELESS_EXT < 19 +#define IW_QUAL_ALL_UPDATED 0x07 +#define IW_QUAL_DBM 0x08 +#define IW_QUAL_ALL_INVALID 0x70 +#endif + +/* timeout in seconds for the usb_control_msg in get_cmd_status + * and set_card_command + */ +#ifndef USB_CTRL_GET_TIMEOUT +# define USB_CTRL_GET_TIMEOUT 5 +#endif + +/* number of endpoints of an interface */ +#define NUM_EP(intf) (intf)->altsetting[0].desc.bNumEndpoints +#define EP(intf,nr) (intf)->altsetting[0].endpoint[(nr)].desc +#define GET_DEV(udev) usb_get_dev((udev)) +#define PUT_DEV(udev) usb_put_dev((udev)) +#define SET_NETDEV_OWNER(ndev,owner) /* not needed anymore ??? */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14) +#define gfp_t int +#endif + +/* Backwards compatibility for usb_kill_urb() */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10) +# define usb_kill_urb usb_unlink_urb +#endif + +/* wireless extension level this source currently supports */ +#define WIRELESS_EXT_SUPPORTED 16 + +#ifndef USB_ASYNC_UNLINK +#ifdef URB_ASYNC_UNLINK +#define USB_ASYNC_UNLINK URB_ASYNC_UNLINK +#else +#define USB_ASYNC_UNLINK 0 +#endif +#endif + +#ifndef FILL_BULK_URB +#define FILL_BULK_URB(a,b,c,d,e,f,g) usb_fill_bulk_urb(a,b,c,d,e,f,g) +#endif + +int at76_debug = DBG_DEFAULTS; + +/* uncond. debug output */ +#define dbg_uc(format, arg...) \ + printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg) + +#ifndef min +#define min(x,y) ((x) < (y) ? (x) : (y)) +#endif + +#define assert(x) \ + do {\ + if (!(x)) \ + err("%d: assertion " #x " failed", __LINE__);\ + } while (0) + +/* how often do we re-try these packets ? */ +#define AUTH_RETRIES 3 +#define ASSOC_RETRIES 3 +#define DISASSOC_RETRIES 3 + + + +static unsigned long spin_l_istate_flags; +#define LOCK_ISTATE() spin_lock_irqsave(&dev->istate_spinlock,spin_l_istate_flags); +#define UNLOCK_ISTATE() spin_unlock_irqrestore(&dev->istate_spinlock,spin_l_istate_flags); + + +#define NEW_STATE(dev,newstate) \ + do {\ + scan_hook(newstate == SCANNING); \ + LOCK_ISTATE() \ + dbg(DBG_PROGRESS, "%s: state %d -> %d (" #newstate ")",\ + dev->netdev->name, dev->istate, newstate);\ + dev->istate = newstate;\ + UNLOCK_ISTATE() \ + } while (0) + +/* the beacon timeout in infra mode when we are connected (in seconds) */ +#define BEACON_TIMEOUT 10 + +/* the interval in ticks we poll if scan is completed */ +#define SCAN_POLL_INTERVAL (HZ/4) + + +/* Version Information */ +#define DRIVER_NAME "at76_usb" +#define DRIVER_AUTHOR \ +"Oliver Kurth , Joerg Albert , " \ +"Alex , Nick Jones, Balint Seeber " +#define DRIVER_DESC "Atmel at76c50x USB Wireless LAN Driver" + + +/* Module paramaters */ +module_param_named(debug, at76_debug, int, 0600); +MODULE_PARM_DESC(debug, "Debugging level"); + +static int rx_copybreak = 200; +module_param(rx_copybreak, int, 0400); +MODULE_PARM_DESC(rx_copybreak, "rx packet copy threshold"); + +static int scan_min_time = 10; +module_param(scan_min_time, int, 0400); +MODULE_PARM_DESC(scan_min_time, "scan min channel time (default: 10)"); + +static int scan_max_time = 120; +module_param(scan_max_time, int, 0400); +MODULE_PARM_DESC(scan_max_time, "scan max channel time (default: 120)"); + +static int scan_mode = SCAN_TYPE_ACTIVE; +module_param(scan_mode, int, 0400); +MODULE_PARM_DESC(scan_mode, "scan mode: 0 active (with ProbeReq, default), 1 passive"); + +static int preamble_type = PREAMBLE_TYPE_LONG; +module_param(preamble_type, int, 0400); +MODULE_PARM_DESC(preamble_type, "preamble type: 0 long (default), 1 short"); + +static int auth_mode = 0; +module_param(auth_mode, int, 0400); +MODULE_PARM_DESC(auth_mode, "authentication mode: 0 open system (default), " + "1 shared secret"); + +static int pm_mode = PM_ACTIVE; +module_param(pm_mode, int, 0400); +MODULE_PARM_DESC(pm_mode, "power management mode: 1 active (def.), 2 powersave, 3 smart save"); + +static int pm_period = 0; +module_param(pm_period, int, 0400); +MODULE_PARM_DESC(pm_period, "period of waking up the device in usec"); + +static int international_roaming = IR_OFF; +module_param(international_roaming, int, 0400); +MODULE_PARM_DESC(international_roaming, "enable international roaming: 0 (no, default), 1 (yes)"); + +static int default_iw_mode = IW_MODE_INFRA; +module_param(default_iw_mode, int, 0400); +MODULE_PARM_DESC(default_iw_mode, "default IW mode for a new device: " + "1 (ad-hoc), 2 (infrastructure, def.), 6 (monitor mode)"); + +static int monitor_scan_min_time = 50; +module_param(monitor_scan_min_time, int, 0400); +MODULE_PARM_DESC(monitor_scan_min_time, "scan min channel time in MONITOR MODE (default: 50)"); + +static int monitor_scan_max_time = 600; +module_param(monitor_scan_max_time, int, 0400); +MODULE_PARM_DESC(monitor_scan_max_time, "scan max channel time in MONITOR MODE (default: 600)"); + +static char* netdev_name = "wlan%d"; +module_param(netdev_name, charp, 0400); +MODULE_PARM_DESC(netdev_name, "network device name (default is wlan%d)"); + + +#define DEF_RTS_THRESHOLD 1536 +#define DEF_FRAG_THRESHOLD 1536 +#define DEF_SHORT_RETRY_LIMIT 8 +//#define DEF_LONG_RETRY_LIMIT 4 +#define DEF_CHANNEL 10 + +#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1) + +/* The frequency of each channel in MHz */ +static const long channel_frequency[] = { + 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 +}; +#define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) ) + +/* the broadcast address */ +static const u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; +static const u8 off_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +/* the supported rates of this hardware, bit7 marks a basic rate */ +static const u8 hw_rates[4] = {0x82,0x84,0x0b,0x16}; + +/* the max padding size for tx in bytes (see calc_padding)*/ +#define MAX_PADDING_SIZE 53 + +/* the size of the ieee802.11 header (excl. the at76c503 tx header) */ +#define IEEE802_11_MGMT_HEADER_SIZE offsetof(struct ieee80211_hdr_3addr, payload) + +#define BEACON_MAX_DATA_LENGTH 1500 +/* beacon in ieee80211_hdr_3addr.payload */ +struct ieee802_11_beacon_data { + u8 timestamp[8]; // TSFTIMER + __le16 beacon_interval; // Kms between TBTTs (Target Beacon Transmission Times) + __le16 capability_information; + u8 data[BEACON_MAX_DATA_LENGTH]; /* contains: SSID (tag,length,value), + Supported Rates (tlv), channel */ +} __attribute__ ((packed)); + +/* disassoc frame in ieee80211_hdr_3addr.payload */ +struct ieee802_11_disassoc_frame { + __le16 reason; +} __attribute__ ((packed)); +#define DISASSOC_FRAME_SIZE \ + (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\ + sizeof(struct ieee802_11_disassoc_frame)) + +/* assoc request in ieee80211_hdr_3addr.payload */ +struct ieee802_11_assoc_req { + __le16 capability; + __le16 listen_interval; + u8 data[1]; /* variable number of bytes for SSID + and supported rates (tlv coded) */ +}; +/* the maximum size of an AssocReq packet */ +#define ASSOCREQ_MAX_SIZE \ + (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\ + offsetof(struct ieee802_11_assoc_req,data) +\ + 1+1+IW_ESSID_MAX_SIZE + 1+1+4) + +/* reassoc request in ieee80211_hdr_3addr.payload */ +struct ieee802_11_reassoc_req { + __le16 capability; + __le16 listen_interval; + u8 curr_ap[ETH_ALEN]; /* the bssid of the AP we are + currently associated to */ + u8 data[1]; /* variable number of bytes for SSID + and supported rates (tlv coded) */ +} __attribute__ ((packed)); + +/* the maximum size of an AssocReq packet */ +#define REASSOCREQ_MAX_SIZE \ + (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\ + offsetof(struct ieee802_11_reassoc_req,data) +\ + 1+1+IW_ESSID_MAX_SIZE + 1+1+4) + + +/* assoc/reassoc response */ +struct ieee802_11_assoc_resp { + __le16 capability; + __le16 status; + __le16 assoc_id; + u8 data[1]; /* variable number of bytes for + supported rates (tlv coded) */ +} __attribute__ ((packed)); + +/* auth. request/response in ieee80211_hdr_3addr.payload */ +struct ieee802_11_auth_frame { + __le16 algorithm; + __le16 seq_nr; + __le16 status; + u8 challenge[0]; +} __attribute__ ((packed)); +/* for shared secret auth, add the challenge text size */ +#define AUTH_FRAME_SIZE \ + (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\ + sizeof(struct ieee802_11_auth_frame)) + +/* deauth frame in ieee80211_hdr_3addr.payload */ +struct ieee802_11_deauth_frame { + __le16 reason; +} __attribute__ ((packed)); +#define DEAUTH_FRAME_SIZE \ + (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\ + sizeof(struct ieee802_11_disauth_frame)) + + +#define KEVENT_CTRL_HALT 1 +#define KEVENT_NEW_BSS 2 +#define KEVENT_SET_PROMISC 3 +#define KEVENT_MGMT_TIMEOUT 4 +#define KEVENT_SCAN 5 +#define KEVENT_JOIN 6 +#define KEVENT_STARTIBSS 7 +#define KEVENT_SUBMIT_RX 8 +#define KEVENT_RESTART 9 /* restart the device */ +#define KEVENT_ASSOC_DONE 10 /* execute the power save settings: + listen interval, pm mode, assoc id */ +#define KEVENT_EXTERNAL_FW 11 +#define KEVENT_INTERNAL_FW 12 +#define KEVENT_RESET_DEVICE 13 + + +static u8 snapsig[] = {0xaa, 0xaa, 0x03}; +//#ifdef COLLAPSE_RFC1042 +/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with + * a SNAP OID of 0 (0x00, 0x00, 0x00) */ +static u8 rfc1042sig[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; +//#endif /* COLLAPSE_RFC1042 */ + +/* local function prototypes */ +static void iwspy_update(struct at76c503 *dev, struct at76c503_rx_buffer *buf); + +static void at76c503_read_bulk_callback (struct urb *urb); +static void at76c503_write_bulk_callback(struct urb *urb); +static void defer_kevent (struct at76c503 *dev, int flag); +static struct bss_info *find_matching_bss(struct at76c503 *dev, + struct bss_info *curr); +static int auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr, + u8 *challenge); +static int disassoc_req(struct at76c503 *dev, struct bss_info *bss); +static int assoc_req(struct at76c503 *dev, struct bss_info *bss); +static int reassoc_req(struct at76c503 *dev, struct bss_info *curr, + struct bss_info *new); +static void dump_bss_table(struct at76c503 *dev, int force_output); +static int submit_rx_urb(struct at76c503 *dev); +static int startup_device(struct at76c503 *dev); + +static int set_iroaming(struct at76c503 *dev, int onoff); +static void set_monitor_mode(struct at76c503 *dev, int use_prism); + +/* second step of initialization (after fw download) */ +static int init_new_device(struct at76c503 *dev); + +/* some abbrev. for wireless events */ +static inline void iwevent_scan_complete(struct net_device *dev) +{ + union iwreq_data wrqu; + wrqu.data.length = 0; + wrqu.data.flags = 0; + wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); + dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", dev->name); +} +static inline void iwevent_bss_connect(struct net_device *dev, u8 *bssid) +{ + union iwreq_data wrqu; + wrqu.data.length = 0; + wrqu.data.flags = 0; + memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); + dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", dev->name, __FUNCTION__); +} + +static inline void iwevent_bss_disconnect(struct net_device *dev) +{ + union iwreq_data wrqu; + wrqu.data.length = 0; + wrqu.data.flags = 0; + memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); + dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", dev->name, __FUNCTION__); +} + + +/* hexdump len many bytes from buf into obuf, separated by delim, + add a trailing \0 into obuf */ +static char *hex2str(char *obuf, u8 *buf, int len, char delim) +{ +#define BIN2HEX(x) ((x) < 10 ? '0'+(x) : (x)+'A'-10) + + char *ret = obuf; + while (len--) { + *obuf++ = BIN2HEX(*buf>>4); + *obuf++ = BIN2HEX(*buf&0xf); + if (delim != '\0') + *obuf++ = delim; + buf++; + } + if (delim != '\0' && obuf > ret) + obuf--; // remove last inserted delimiter + *obuf = '\0'; + + return ret; +} + +/* == PROC is_cloaked_ssid == + returns != 0, if the given SSID is a cloaked one: + - length 0 + - length > 0, all bytes are \0 + - length == 1, SSID ' ' +*/ +static inline int is_cloaked_ssid(u8 *ssid, int length) +{ + static const u8 zeros[32]; + + return (length == 0) || + (length == 1 && *ssid == ' ') || + (length > 0 && !memcmp(ssid,zeros,length)); +} + +static inline void free_bss_list(struct at76c503 *dev) +{ + struct list_head *next, *ptr; + unsigned long flags; + + spin_lock_irqsave(&dev->bss_list_spinlock, flags); + + dev->curr_bss = dev->new_bss = NULL; + + list_for_each_safe(ptr, next, &dev->bss_list) { + list_del(ptr); + kfree(list_entry(ptr, struct bss_info, list)); + } + + spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); +} + +static inline char *mac2str(u8 *mac) +{ + static char str [6*3]; + + sprintf(str, "%02x:%02x:%02x:%02x:%02x:%02x", + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + return str; +} + +static void scan_hook(int blink) +{ +#ifdef CONFIG_IPAQ_HANDHELD + if (machine_is_h5400()) { + if (blink) + ipaq_led_blink (RED_LED, 1, 2); + else + ipaq_led_off (RED_LED); + } +#endif +} + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) + +/* == PROC analyze_usb_config == + This procedure analyzes the configuration after the + USB device got reset and find the start of the interface and the + two endpoint descriptors. + Returns < 0 if the descriptors seems to be wrong. */ +static int analyze_usb_config(u8 *cfgd, int cfgd_len, + int *intf_idx, int *ep0_idx, int *ep1_idx) +{ + u8 *cfgd_start = cfgd; + u8 *cfgd_end = cfgd + cfgd_len; /* first byte after config descriptor */ + int nr_intf=0, nr_ep=0; /* number of interface, number of endpoint descr. + found */ + + assert(cfgd_len >= 2); + if (cfgd_len < 2) + return -1; + + if (*(cfgd+1) != USB_DT_CONFIG) { + err("not a config descriptor"); + return -2; + } + + if (*cfgd != USB_DT_CONFIG_SIZE) { + err("invalid length for config descriptor: %d", *cfgd); + return -3; + } + + /* scan the config descr */ + while ((cfgd+1) < cfgd_end) { + + switch (*(cfgd+1)) { + + case USB_DT_INTERFACE: + nr_intf++; + if (nr_intf == 1) + *intf_idx = cfgd - cfgd_start; + break; + + case USB_DT_ENDPOINT: + nr_ep++; + if (nr_ep == 1) + *ep0_idx = cfgd - cfgd_start; + else + if (nr_ep == 2) + *ep1_idx = cfgd - cfgd_start; + break; + default: + ; + } + cfgd += *cfgd; + } /* while ((cfgd+1) < cfgd_end) */ + + if (nr_ep != 2 || nr_intf != 1) { + err("unexpected nr of intf (%d) or endpoints (%d)", + nr_intf, nr_ep); + return -4; + } + + return 0; +} /* end of analyze_usb_config */ + + + +/* == PROC update_usb_intf_descr == + currently (2.6.0-test2) usb_reset_device() does not recognize that + the interface descr. are changed. + This procedure reads the configuration and does a limited parsing of + the interface and endpoint descriptors. + This is IMHO needed until usb_reset_device() is changed inside the + kernel's USB subsystem. + Copied from usb/core/config.c:usb_get_configuration() + + THIS IS VERY UGLY CODE - DO NOT COPY IT ! */ + +#define AT76C503A_USB_CONFDESCR_LEN 0x20 +/* the short configuration descriptor before reset */ +//#define AT76C503A_USB_SHORT_CONFDESCR_LEN 0x19 + +static int update_usb_intf_descr(struct at76c503 *dev) +{ + int intf0; /* begin of intf descriptor in configuration */ + int ep0, ep1; /* begin of endpoint descriptors */ + + struct usb_device *udev = dev->udev; + struct usb_config_descriptor *cfg_desc; + int result = 0, size; + u8 *buffer; + struct usb_host_interface *ifp; + int i; + + dbg(DBG_DEVSTART, "%s: ENTER", __FUNCTION__); + + cfg_desc = (struct usb_config_descriptor *) + kmalloc(AT76C503A_USB_CONFDESCR_LEN, GFP_KERNEL); + if (!cfg_desc) { + err("cannot kmalloc config desc"); + return -ENOMEM; + } + + result = usb_get_descriptor(udev, USB_DT_CONFIG, 0, + cfg_desc, AT76C503A_USB_CONFDESCR_LEN); + if (result < AT76C503A_USB_CONFDESCR_LEN) { + if (result < 0) + err("unable to get descriptor"); + else { + err("config descriptor too short (expected >= %i, got %i)", + AT76C503A_USB_CONFDESCR_LEN, result); + result = -EINVAL; + } + goto err; + } + + /* now check the config descriptor */ + le16_to_cpus(&cfg_desc->wTotalLength); + size = cfg_desc->wTotalLength; + buffer = (u8 *)cfg_desc; + + if (cfg_desc->bNumInterfaces > 1) { + err("found %d interfaces", cfg_desc->bNumInterfaces); + result = - EINVAL; + goto err; + } + + if ((result=analyze_usb_config(buffer, size, &intf0, &ep0, &ep1))) { + + err("analyze_usb_config returned %d for config desc %s", + result, + hex2str(dev->obuf, (u8 *)cfg_desc, + min((int)(sizeof(dev->obuf)-1)/2,size), '\0')); + result=-EINVAL; + goto err; + } + + /* we got the correct config descriptor - update the interface's endpoints */ + ifp = &udev->actconfig->interface[0]->altsetting[0]; + + if (ifp->endpoint) + kfree(ifp->endpoint); + + memcpy(&ifp->desc, buffer+intf0, USB_DT_INTERFACE_SIZE); + + if (!(ifp->endpoint = kmalloc(2 * sizeof(struct usb_host_endpoint), + GFP_KERNEL))) { + result = -ENOMEM; + goto err; + } + memset(ifp->endpoint, 0, 2 * sizeof(struct usb_host_endpoint)); + memcpy(&ifp->endpoint[0].desc, buffer+ep0, USB_DT_ENDPOINT_SIZE); + le16_to_cpus(&ifp->endpoint[0].desc.wMaxPacketSize); + memcpy(&ifp->endpoint[1].desc, buffer+ep1, USB_DT_ENDPOINT_SIZE); + le16_to_cpus(&ifp->endpoint[1].desc.wMaxPacketSize); + + /* we must set the max packet for the new ep (see usb_set_maxpacket() ) */ + +#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN)) + for(i=0; i < ifp->desc.bNumEndpoints; i++) { + struct usb_endpoint_descriptor *d = &ifp->endpoint[i].desc; + int b = d->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; + if (usb_endpoint_out(d->bEndpointAddress)) { + if (d->wMaxPacketSize > udev->epmaxpacketout[b]) + udev->epmaxpacketout[b] = d->wMaxPacketSize; + } else { + if (d->wMaxPacketSize > udev->epmaxpacketin[b]) + udev->epmaxpacketin[b] = d->wMaxPacketSize; + } + } + + dbg(DBG_DEVSTART, "%s: ifp %p num_altsetting %d " + "endpoint addr x%x, x%x", __FUNCTION__, + ifp, udev->actconfig->interface[0]->num_altsetting, + ifp->endpoint[0].desc.bEndpointAddress, + ifp->endpoint[1].desc.bEndpointAddress); + result = 0; +err: + kfree(cfg_desc); + dbg(DBG_DEVSTART, "%s: EXIT with %d", __FUNCTION__, result); + return result; +} /* update_usb_intf_descr */ + +#endif /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) */ + + +static int at76c503_remap(struct usb_device *udev) +{ + int ret; + ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0x0a, INTERFACE_VENDOR_REQUEST_OUT, + 0, 0, + NULL, 0, HZ * USB_CTRL_GET_TIMEOUT); + if (ret < 0) + return ret; + + return 0; +} + + +static int get_op_mode(struct usb_device *udev) +{ + int ret; + u8 op_mode; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 0x33, INTERFACE_VENDOR_REQUEST_IN, + 0x01, 0, + &op_mode, 1, HZ * USB_CTRL_GET_TIMEOUT); + if(ret < 0) + return ret; + return op_mode; +} + +/* this loads a block of the second part of the firmware */ +static inline int load_ext_fw_block(struct usb_device *udev, + int i, unsigned char *buf, int bsize) +{ + return usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0x0e, DEVICE_VENDOR_REQUEST_OUT, + 0x0802, i, + buf, bsize, HZ * USB_CTRL_GET_TIMEOUT); +} + +static inline int get_hw_cfg_rfmd(struct usb_device *udev, + unsigned char *buf, int buf_size) +{ + return usb_control_msg(udev, usb_rcvctrlpipe(udev,0), + 0x33, INTERFACE_VENDOR_REQUEST_IN, + ((0x0a << 8) | 0x02), 0, + buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT); +} + +/* Intersil boards use a different "value" for GetHWConfig requests */ +static inline +int get_hw_cfg_intersil(struct usb_device *udev, + unsigned char *buf, int buf_size) +{ + return usb_control_msg(udev, usb_rcvctrlpipe(udev,0), + 0x33, INTERFACE_VENDOR_REQUEST_IN, + ((0x09 << 8) | 0x02), 0, + buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT); +} + +/* Get the hardware configuration for the adapter and place the appropriate + * data in the appropriate fields of 'dev' (the GetHWConfig request and + * interpretation of the result depends on the type of board we're dealing + * with) */ +static int get_hw_config(struct at76c503 *dev) +{ + int ret; + union { + struct hwcfg_intersil i; + struct hwcfg_rfmd r3; + struct hwcfg_r505 r5; + } *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL); + + if (!hwcfg) + return -ENOMEM; + + switch (dev->board_type) { + + case BOARDTYPE_503_INTERSIL_3861: + case BOARDTYPE_503_INTERSIL_3863: + ret = get_hw_cfg_intersil(dev->udev, (unsigned char *)&hwcfg->i, sizeof(hwcfg->i)); + if (ret < 0) break; + memcpy(dev->mac_addr, hwcfg->i.mac_addr, ETH_ALEN); + memcpy(dev->cr31_values, hwcfg->i.cr31_values, 14); + memcpy(dev->cr58_values, hwcfg->i.cr58_values, 14); + memcpy(dev->pidvid, hwcfg->i.pidvid, 4); + dev->regulatory_domain = hwcfg->i.regulatory_domain; + break; + + case BOARDTYPE_503_RFMD: + case BOARDTYPE_503_RFMD_ACC: + ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r3, sizeof(hwcfg->r3)); + if (ret < 0) break; + memcpy(dev->cr20_values, hwcfg->r3.cr20_values, 14); + memcpy(dev->cr21_values, hwcfg->r3.cr21_values, 14); + memcpy(dev->bb_cr, hwcfg->r3.bb_cr, 14); + memcpy(dev->pidvid, hwcfg->r3.pidvid, 4); + memcpy(dev->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN); + dev->regulatory_domain = hwcfg->r3.regulatory_domain; + memcpy(dev->low_power_values, hwcfg->r3.low_power_values, 14); + memcpy(dev->normal_power_values, hwcfg->r3.normal_power_values, 14); + break; + + case BOARDTYPE_505_RFMD: + case BOARDTYPE_505_RFMD_2958: + case BOARDTYPE_505A_RFMD_2958: + ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r5, sizeof(hwcfg->r5)); + if (ret < 0) break; + memcpy(dev->cr39_values, hwcfg->r5.cr39_values, 14); + memcpy(dev->bb_cr, hwcfg->r5.bb_cr, 14); + memcpy(dev->pidvid, hwcfg->r5.pidvid, 4); + memcpy(dev->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN); + dev->regulatory_domain = hwcfg->r5.regulatory_domain; + memcpy(dev->cr15_values, hwcfg->r5.cr15_values, 14); + break; + + default: + err("Bad board type set (%d). Unable to get hardware config.", dev->board_type); + ret = -EINVAL; + } + + kfree(hwcfg); + + if (ret < 0) { + err("Get HW Config failed (%d)", ret); + } + return ret; +} + +/* == PROC getRegDomain == */ +static struct reg_domain const *getRegDomain(u16 code) +{ + static struct reg_domain const fd_tab[] = { + {0x10, "FCC (U.S)", 0x7ff}, /* ch 1-11 */ + {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */ + {0x30, "ETSI (Europe - (Spain+France)", 0x1fff}, /* ch 1-13 */ + {0x31, "Spain", 0x600}, /* ch 10,11 */ + {0x32, "France", 0x1e00}, /* ch 10-13 */ + {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */ + {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */ + {0x50, "Israel", 0x3fc}, /* ch 3-9 */ + }; + static int const tab_len = sizeof(fd_tab) / sizeof(struct reg_domain); + + /* use this if an unknown code comes in */ + static struct reg_domain const unknown = + {0, "", 0xffffffff}; + + int i; + + for(i=0; i < tab_len; i++) + if (code == fd_tab[i].code) + break; + + return (i >= tab_len) ? &unknown : &fd_tab[i]; +} /* getFreqDomain */ + +static inline int get_mib(struct usb_device *udev, + u16 mib, u8 *buf, int buf_size) +{ + return usb_control_msg(udev, usb_rcvctrlpipe(udev,0), + 0x33, INTERFACE_VENDOR_REQUEST_IN, + mib << 8, 0, + buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT); +} + +static inline int get_cmd_status(struct usb_device *udev, + u8 cmd, u8 *cmd_status) +{ + return usb_control_msg(udev, usb_rcvctrlpipe(udev,0), + 0x22, INTERFACE_VENDOR_REQUEST_IN, + cmd, 0, + cmd_status, 40, HZ * USB_CTRL_GET_TIMEOUT); +} + +#define EXT_FW_BLOCK_SIZE 1024 +static int download_external_fw(struct usb_device *udev, u8 *buf, int size) +{ + int i = 0, ret = 0; + u8 *block; + + if (size < 0) return -EINVAL; + if ((size > 0) && (buf == NULL)) return -EFAULT; + + block = kmalloc(EXT_FW_BLOCK_SIZE, GFP_KERNEL); + if (block == NULL) return -ENOMEM; + + dbg(DBG_DEVSTART, "downloading external firmware"); + + while(size > 0){ + int bsize = size > EXT_FW_BLOCK_SIZE ? EXT_FW_BLOCK_SIZE : size; + + memcpy(block, buf, bsize); + dbg(DBG_DEVSTART, + "ext fw, size left = %5d, bsize = %4d, i = %2d", size, bsize, i); + if((ret = load_ext_fw_block(udev, i, block, bsize)) < 0){ + err("load_ext_fw_block failed: %d, i = %d", ret, i); + goto exit; + } + buf += bsize; + size -= bsize; + i++; + } + + /* for fw >= 0.100, the device needs + an extra empty block: */ + if((ret = load_ext_fw_block(udev, i, block, 0)) < 0){ + err("load_ext_fw_block failed: %d, i = %d", ret, i); + goto exit; + } + + exit: + kfree(block); + return ret; +} + +static int set_card_command(struct usb_device *udev, int cmd, + unsigned char *buf, int buf_size) +{ + int ret; + struct at76c503_command *cmd_buf = + (struct at76c503_command *)kmalloc( + sizeof(struct at76c503_command) + buf_size, + GFP_KERNEL); + + if(cmd_buf){ + cmd_buf->cmd = cmd; + cmd_buf->reserved = 0; + cmd_buf->size = cpu_to_le16(buf_size); + if(buf_size > 0) + memcpy(&(cmd_buf[1]), buf, buf_size); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0x0e, DEVICE_VENDOR_REQUEST_OUT, + 0, 0, + cmd_buf, + sizeof(struct at76c503_command) + buf_size, + HZ * USB_CTRL_GET_TIMEOUT); + kfree(cmd_buf); + return ret; + } + + return -ENOMEM; +} + +#define MAKE_CMD_STATUS_CASE(c) case (c): return #c + +static const char* get_cmd_status_string(u8 cmd_status) +{ + switch (cmd_status) + { + MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE); + MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE); + MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN); + MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER); + MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED); + MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT); + MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS); + MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE); + MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED); + } + + return "UNKNOWN"; +} + +/* TODO: should timeout */ +static int wait_completion(struct at76c503 *dev, int cmd) +{ + u8 *cmd_status = kmalloc(40, GFP_KERNEL); + struct net_device *netdev = dev->netdev; + int ret = 0; + + do{ + ret = get_cmd_status(dev->udev, cmd, cmd_status); + if(ret < 0){ + err("%s: get_cmd_status failed: %d", netdev->name, ret); + break; + } + + dbg(DBG_WAIT_COMPLETE, "%s: Waiting on cmd %d, cmd_status[5] = %d (%s)", + dev->netdev->name, cmd, cmd_status[5], get_cmd_status_string(cmd_status[5])); + + if(cmd_status[5] == CMD_STATUS_IN_PROGRESS || + cmd_status[5] == CMD_STATUS_IDLE){ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/10); // 100 ms + }else break; + }while(1); + + if (ret >= 0) + /* if get_cmd_status did not fail, return the status + retrieved */ + ret = cmd_status[5]; + kfree(cmd_status); + return ret; +} + +static int set_mib(struct at76c503 *dev, struct set_mib_buffer *buf) +{ + struct usb_device *udev = dev->udev; + int ret; + struct at76c503_command *cmd_buf = + (struct at76c503_command *)kmalloc( + sizeof(struct at76c503_command) + buf->size + 4, + GFP_KERNEL); + + if(cmd_buf){ + cmd_buf->cmd = CMD_SET_MIB; + cmd_buf->reserved = 0; + cmd_buf->size = cpu_to_le16(buf->size + 4); + memcpy(&(cmd_buf[1]), buf, buf->size + 4); + ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0x0e, DEVICE_VENDOR_REQUEST_OUT, + 0, 0, + cmd_buf, + sizeof(struct at76c503_command) + buf->size + 4, + HZ * USB_CTRL_GET_TIMEOUT); + if (ret >= 0) + if ((ret=wait_completion(dev, CMD_SET_MIB)) != + CMD_STATUS_COMPLETE) { + info("%s: set_mib: wait_completion failed with %d", + dev->netdev->name, ret); + ret = -156; /* ??? */ + } + kfree(cmd_buf); + return ret; + } + + return -ENOMEM; +} + +/* return < 0 on error, == 0 if no command sent, == 1 if cmd sent */ +static int set_radio(struct at76c503 *dev, int on_off) +{ + int ret; + + if(dev->radio_on != on_off){ + ret = set_card_command(dev->udev, CMD_RADIO, NULL, 0); + if(ret < 0){ + err("%s: set_card_command(CMD_RADIO) failed: %d", dev->netdev->name, ret); + } else + ret = 1; + dev->radio_on = on_off; + } else + ret = 0; + return ret; +} + + +/* == PROC set_pm_mode == + sets power save modi (PM_ACTIVE/PM_SAVE/PM_SMART_SAVE) */ +static int set_pm_mode(struct at76c503 *dev, u8 mode) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_MGMT; + dev->mib_buf.size = 1; + dev->mib_buf.index = POWER_MGMT_MODE_OFFSET; + + dev->mib_buf.data[0] = mode; + + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (pm_mode) failed: %d", dev->netdev->name, ret); + } + return ret; +} + +/* == PROC set_associd == + sets the assoc id for power save mode */ +static int set_associd(struct at76c503 *dev, u16 id) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_MGMT; + dev->mib_buf.size = 2; + dev->mib_buf.index = STATION_ID_OFFSET; + + dev->mib_buf.data[0] = id & 0xff; + dev->mib_buf.data[1] = id >> 8; + + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (associd) failed: %d", dev->netdev->name, ret); + } + return ret; +} + +/* == PROC set_listen_interval == + sets the listen interval for power save mode. + really needed, as we have a similar parameter in the assocreq ??? */ +static int set_listen_interval(struct at76c503 *dev, u16 interval) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC; + dev->mib_buf.size = 2; + dev->mib_buf.index = STATION_ID_OFFSET; + + dev->mib_buf.data[0] = interval & 0xff; + dev->mib_buf.data[1] = interval >> 8; + + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (listen_interval) failed: %d", + dev->netdev->name, ret); + } + return ret; +} + +static int set_preamble(struct at76c503 *dev, u8 type) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_LOCAL; + dev->mib_buf.size = 1; + dev->mib_buf.index = PREAMBLE_TYPE_OFFSET; + dev->mib_buf.data[0] = type; + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (preamble) failed: %d", dev->netdev->name, ret); + } + return ret; +} + +static int set_frag(struct at76c503 *dev, u16 size) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC; + dev->mib_buf.size = 2; + dev->mib_buf.index = FRAGMENTATION_OFFSET; + *(__le16*)dev->mib_buf.data = cpu_to_le16(size); + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (frag threshold) failed: %d", dev->netdev->name, ret); + } + return ret; +} + +static int set_rts(struct at76c503 *dev, u16 size) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC; + dev->mib_buf.size = 2; + dev->mib_buf.index = RTS_OFFSET; + *(__le16*)dev->mib_buf.data = cpu_to_le16(size); + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (rts) failed: %d", dev->netdev->name, ret); + } + return ret; +} + +static int set_autorate_fallback(struct at76c503 *dev, int onoff) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_LOCAL; + dev->mib_buf.size = 1; + dev->mib_buf.index = TX_AUTORATE_FALLBACK_OFFSET; + dev->mib_buf.data[0] = onoff; + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (autorate fallback) failed: %d", dev->netdev->name, ret); + } + return ret; +} + +static int set_mac_address(struct at76c503 *dev, void *addr) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_ADD; + dev->mib_buf.size = ETH_ALEN; + dev->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr); + memcpy(dev->mib_buf.data, addr, ETH_ALEN); + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (MAC_ADDR, mac_addr) failed: %d", + dev->netdev->name, ret); + } + return ret; +} + +#if 0 +/* implemented to get promisc. mode working, but does not help. + May still be useful for multicast eventually. */ +static int set_group_address(struct at76c503 *dev, u8 *addr, int n) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_ADD; + dev->mib_buf.size = ETH_ALEN; + dev->mib_buf.index = offsetof(struct mib_mac_addr, group_addr) + n*ETH_ALEN; + memcpy(dev->mib_buf.data, addr, ETH_ALEN); + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (MIB_MAC_ADD, group_addr) failed: %d", + dev->netdev->name, ret); + } + +#if 1 + /* I do not know anything about the group_addr_status field... (oku) */ + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_ADD; + dev->mib_buf.size = 1; + dev->mib_buf.index = offsetof(struct mib_mac_addr, group_addr_status) + n; + dev->mib_buf.data[0] = 1; + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (MIB_MAC_ADD, group_addr_status) failed: %d", + dev->netdev->name, ret); + } +#endif + return ret; +} +#endif + +static int set_promisc(struct at76c503 *dev, int onoff) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_LOCAL; + dev->mib_buf.size = 1; + dev->mib_buf.index = offsetof(struct mib_local, promiscuous_mode); + dev->mib_buf.data[0] = onoff ? 1 : 0; + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (promiscuous_mode) failed: %d", dev->netdev->name, ret); + } + return ret; +} + +static int dump_mib_mac_addr(struct at76c503 *dev) +{ + int ret = 0; + struct mib_mac_addr *mac_addr = + kmalloc(sizeof(struct mib_mac_addr), GFP_KERNEL); + + if(!mac_addr){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_MAC_ADD, + (u8*)mac_addr, sizeof(struct mib_mac_addr)); + if(ret < 0){ + err("%s: get_mib (MAC_ADDR) failed: %d", dev->netdev->name, ret); + goto err; + } + + dbg_uc("%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x group_addr %s status %d %d %d %d", + dev->netdev->name, mac2str(mac_addr->mac_addr), + mac_addr->res[0], mac_addr->res[1], + hex2str(dev->obuf, (u8 *)mac_addr->group_addr, + min((int)(sizeof(dev->obuf)-1)/2, 4*ETH_ALEN), '\0'), + mac_addr->group_addr_status[0], mac_addr->group_addr_status[1], + mac_addr->group_addr_status[2], mac_addr->group_addr_status[3]); + + err: + kfree(mac_addr); + exit: + return ret; +} + +static int dump_mib_mac_wep(struct at76c503 *dev) +{ + int ret = 0; + struct mib_mac_wep *mac_wep = + kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL); + + if(!mac_wep){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_MAC_WEP, + (u8*)mac_wep, sizeof(struct mib_mac_wep)); + if(ret < 0){ + err("%s: get_mib (MAC_WEP) failed: %d", dev->netdev->name, ret); + goto err; + } + + dbg_uc("%s: MIB MAC_WEP: priv_invoked %u def_key_id %u key_len %u " + "excl_unencr %u wep_icv_err %u wep_excluded %u encr_level %u key %d: %s", + dev->netdev->name, mac_wep->privacy_invoked, + mac_wep->wep_default_key_id, mac_wep->wep_key_mapping_len, + mac_wep->exclude_unencrypted,le32_to_cpu( mac_wep->wep_icv_error_count), + le32_to_cpu(mac_wep->wep_excluded_count), + mac_wep->encryption_level, mac_wep->wep_default_key_id, + mac_wep->wep_default_key_id < 4 ? + hex2str(dev->obuf, + mac_wep->wep_default_keyvalue[mac_wep->wep_default_key_id], + min((int)(sizeof(dev->obuf)-1)/2, + mac_wep->encryption_level == 2 ? 13 : 5), '\0') : + ""); + + err: + kfree(mac_wep); + exit: + return ret; +} + +static int dump_mib_mac_mgmt(struct at76c503 *dev) +{ + int ret = 0; + struct mib_mac_mgmt *mac_mgmt = + kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); + char country_string[4]; + + if(!mac_mgmt){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_MAC_MGMT, + (u8*)mac_mgmt, sizeof(struct mib_mac_mgmt)); + if(ret < 0){ + err("%s: get_mib failed: %d", dev->netdev->name, ret); + goto err; + } + + memcpy(&country_string, mac_mgmt->country_string, 3); + country_string[3] = '\0'; + + dbg_uc("%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration %d " + "medium_occupancy_limit %d station_id 0x%x ATIM_window %d " + "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d " + "current_bssid %s current_essid %s current_bss_type %d " + "pm_mode %d ibss_change %d res %d " + "multi_domain_capability_implemented %d " + "international_roaming %d country_string %s", + dev->netdev->name, + le16_to_cpu(mac_mgmt->beacon_period), + le16_to_cpu(mac_mgmt->CFP_max_duration), + le16_to_cpu(mac_mgmt->medium_occupancy_limit), + le16_to_cpu(mac_mgmt->station_id), + le16_to_cpu(mac_mgmt->ATIM_window), + mac_mgmt->CFP_mode, + mac_mgmt->privacy_option_implemented, + mac_mgmt->DTIM_period, + mac_mgmt->CFP_period, + mac2str(mac_mgmt->current_bssid), + hex2str(dev->obuf, (u8 *)mac_mgmt->current_essid, + min((int)(sizeof(dev->obuf)-1)/2, + IW_ESSID_MAX_SIZE), '\0'), + mac_mgmt->current_bss_type, + mac_mgmt->power_mgmt_mode, + mac_mgmt->ibss_change, + mac_mgmt->res, + mac_mgmt->multi_domain_capability_implemented, + mac_mgmt->multi_domain_capability_enabled, + country_string); + err: + kfree(mac_mgmt); + exit: + return ret; +} + +static int dump_mib_mac(struct at76c503 *dev) +{ + int ret = 0; + struct mib_mac *mac = + kmalloc(sizeof(struct mib_mac), GFP_KERNEL); + + if(!mac){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_MAC, + (u8*)mac, sizeof(struct mib_mac)); + if(ret < 0){ + err("%s: get_mib failed: %d", dev->netdev->name, ret); + goto err; + } + + dbg_uc("%s: MIB MAC: max_tx_msdu_lifetime %d max_rx_lifetime %d " + "frag_threshold %d rts_threshold %d cwmin %d cwmax %d " + "short_retry_time %d long_retry_time %d scan_type %d " + "scan_channel %d probe_delay %u min_channel_time %d " + "max_channel_time %d listen_int %d desired_ssid %s " + "desired_bssid %s desired_bsstype %d", + dev->netdev->name, + le32_to_cpu(mac->max_tx_msdu_lifetime), + le32_to_cpu(mac->max_rx_lifetime), + le16_to_cpu(mac->frag_threshold), + le16_to_cpu(mac->rts_threshold), + le16_to_cpu(mac->cwmin), + le16_to_cpu(mac->cwmax), + mac->short_retry_time, + mac->long_retry_time, + mac->scan_type, + mac->scan_channel, + le16_to_cpu(mac->probe_delay), + le16_to_cpu(mac->min_channel_time), + le16_to_cpu(mac->max_channel_time), + le16_to_cpu(mac->listen_interval), + hex2str(dev->obuf, mac->desired_ssid, + min((int)(sizeof(dev->obuf)-1)/2, + IW_ESSID_MAX_SIZE), '\0'), + mac2str(mac->desired_bssid), + mac->desired_bsstype); + err: + kfree(mac); + exit: + return ret; +} + +static int dump_mib_phy(struct at76c503 *dev) +{ + int ret = 0; + struct mib_phy *phy = + kmalloc(sizeof(struct mib_phy), GFP_KERNEL); + + if(!phy){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_PHY, + (u8*)phy, sizeof(struct mib_phy)); + if(ret < 0){ + err("%s: get_mib failed: %d", dev->netdev->name, ret); + goto err; + } + + dbg_uc("%s: MIB PHY: ed_threshold %d slot_time %d sifs_time %d " + "preamble_length %d plcp_header_length %d mpdu_max_length %d " + "cca_mode_supported %d operation_rate_set " + "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d " + "phy_type %d current_reg_domain %d", + dev->netdev->name, + le32_to_cpu(phy->ed_threshold), + le16_to_cpu(phy->slot_time), + le16_to_cpu(phy->sifs_time), + le16_to_cpu(phy->preamble_length), + le16_to_cpu(phy->plcp_header_length), + le16_to_cpu(phy->mpdu_max_length), + le16_to_cpu(phy->cca_mode_supported), + phy->operation_rate_set[0], phy->operation_rate_set[1], + phy->operation_rate_set[2], phy->operation_rate_set[3], + phy->channel_id, + phy->current_cca_mode, + phy->phy_type, + phy->current_reg_domain); + err: + kfree(phy); + exit: + return ret; +} + +static int dump_mib_local(struct at76c503 *dev) +{ + int ret = 0; + struct mib_local *local = + kmalloc(sizeof(struct mib_phy), GFP_KERNEL); + + if(!local){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_LOCAL, + (u8*)local, sizeof(struct mib_local)); + if(ret < 0){ + err("%s: get_mib failed: %d", dev->netdev->name, ret); + goto err; + } + + dbg_uc("%s: MIB PHY: beacon_enable %d txautorate_fallback %d " + "ssid_size %d promiscuous_mode %d preamble_type %d", + dev->netdev->name, + local->beacon_enable, + local->txautorate_fallback, + local->ssid_size, + local->promiscuous_mode, + local->preamble_type); + err: + kfree(local); + exit: + return ret; +} + + +static int get_mib_mdomain(struct at76c503 *dev, struct mib_mdomain *val) +{ + int ret = 0; + struct mib_mdomain *mdomain = + kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL); + + if(!mdomain){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_MDOMAIN, + (u8*)mdomain, sizeof(struct mib_mdomain)); + if(ret < 0){ + err("%s: get_mib failed: %d", dev->netdev->name, ret); + goto err; + } + + memcpy(val, mdomain, sizeof(*val)); + + err: + kfree(mdomain); + exit: + return ret; +} + +static void dump_mib_mdomain(struct at76c503 *dev) +{ + char obuf1[2*14+1], obuf2[2*14+1]; /* to hexdump tx_powerlevel, + channel_list */ + int ret; + struct mib_mdomain mdomain; + + if ((ret=get_mib_mdomain(dev, &mdomain)) < 0) { + err("%s: get_mib_mdomain returned %d", __FUNCTION__, ret); + return; + } + + dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s tx_powerlevel %s", + dev->netdev->name, + hex2str(obuf1, mdomain.channel_list, + (sizeof(obuf1)-1)/2,'\0'), + hex2str(obuf2, mdomain.tx_powerlevel, + (sizeof(obuf2)-1)/2,'\0')); +} + +static +int get_current_bssid(struct at76c503 *dev) +{ + int ret = 0; + struct mib_mac_mgmt *mac_mgmt = + kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); + + if(!mac_mgmt){ + ret = -ENOMEM; + goto exit; + } + + ret = get_mib(dev->udev, MIB_MAC_MGMT, + (u8*)mac_mgmt, sizeof(struct mib_mac_mgmt)); + if(ret < 0){ + err("%s: get_mib failed: %d", dev->netdev->name, ret); + goto err; + } + memcpy(dev->bssid, mac_mgmt->current_bssid, ETH_ALEN); + info("using BSSID %s", mac2str(dev->bssid)); + err: + kfree(mac_mgmt); + exit: + return ret; +} + +static int get_current_channel(struct at76c503 *dev) +{ + int ret = 0; + struct mib_phy *phy = + kmalloc(sizeof(struct mib_phy), GFP_KERNEL); + + if(!phy){ + ret = -ENOMEM; + goto exit; + } + ret = get_mib(dev->udev, MIB_PHY, (u8*)phy, + sizeof(struct mib_phy)); + if(ret < 0){ + err("%s: get_mib(MIB_PHY) failed: %d", dev->netdev->name, ret); + goto err; + } + dev->channel = phy->channel_id; + err: + kfree(phy); + exit: + return ret; +} + +/* == PROC start_scan == + start a scan. use_essid is != 0 if any probe_delay (if scan mode is not + passive) should contain the ESSID configured. ir_step describes the + international roaming step (0, 1) */ +static int start_scan(struct at76c503 *dev, int use_essid, int ir_step) +{ + struct at76c503_start_scan scan; + + memset(&scan, 0, sizeof(struct at76c503_start_scan)); + memset(scan.bssid, 0xff, ETH_ALEN); + + if (use_essid) { + memcpy(scan.essid, dev->essid, IW_ESSID_MAX_SIZE); + scan.essid_size = dev->essid_size; + } else + scan.essid_size = 0; + + //jal: why should we start at a certain channel? we do scan the whole range + //allowed by reg domain. + scan.channel = dev->channel; + + /* atmelwlandriver differs between scan type 0 and 1 (active/passive) + For ad-hoc mode, it uses type 0 only.*/ + if ((dev->international_roaming == IR_ON && ir_step == 0) || + dev->iw_mode == IW_MODE_MONITOR) + scan.scan_type = SCAN_TYPE_PASSIVE; + else + scan.scan_type = dev->scan_mode; + + /* INFO: For probe_delay, not multiplying by 1024 as this will be + slightly less than min_channel_time + (per spec: probe delay < min. channel time) */ + LOCK_ISTATE() + if (dev->istate == MONITORING) { + scan.min_channel_time = cpu_to_le16(dev->monitor_scan_min_time); + scan.max_channel_time = cpu_to_le16(dev->monitor_scan_max_time); + scan.probe_delay = cpu_to_le16(dev->monitor_scan_min_time * 1000); + } else { + scan.min_channel_time = cpu_to_le16(dev->scan_min_time); + scan.max_channel_time = cpu_to_le16(dev->scan_max_time); + scan.probe_delay = cpu_to_le16(dev->scan_min_time * 1000); + } + UNLOCK_ISTATE() + if (dev->international_roaming == IR_ON && ir_step == 1) + scan.international_scan = 0; + else + scan.international_scan = dev->international_roaming; + + /* other values are set to 0 for type 0 */ + + dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, " + "channel = %d, probe_delay = %d, scan_min_time = %d, " + "scan_max_time = %d)", + dev->netdev->name, use_essid, + scan.international_scan, scan.channel, + le16_to_cpu(scan.probe_delay), + le16_to_cpu(scan.min_channel_time), + le16_to_cpu(scan.max_channel_time)); + + return set_card_command(dev->udev, CMD_SCAN, + (unsigned char*)&scan, sizeof(scan)); +} + +static int start_ibss(struct at76c503 *dev) +{ + struct at76c503_start_bss bss; + + memset(&bss, 0, sizeof(struct at76c503_start_bss)); + memset(bss.bssid, 0xff, ETH_ALEN); + memcpy(bss.essid, dev->essid, IW_ESSID_MAX_SIZE); + bss.essid_size = dev->essid_size; + bss.bss_type = ADHOC_MODE; + bss.channel = dev->channel; + + return set_card_command(dev->udev, CMD_START_IBSS, + (unsigned char*)&bss, sizeof(struct at76c503_start_bss)); +} + +/* idx points into dev->bss */ +static int join_bss(struct at76c503 *dev, struct bss_info *ptr) +{ + struct at76c503_join join; + + assert(ptr != NULL); + + memset(&join, 0, sizeof(struct at76c503_join)); + memcpy(join.bssid, ptr->bssid, ETH_ALEN); + memcpy(join.essid, ptr->ssid, ptr->ssid_len); + join.essid_size = ptr->ssid_len; + join.bss_type = (dev->iw_mode == IW_MODE_ADHOC ? 1 : 2); + join.channel = ptr->channel; + join.timeout = cpu_to_le16(2000); + + dbg(DBG_PROGRESS, "%s join addr %s ssid %s type %d ch %d timeout %d", + dev->netdev->name, mac2str(join.bssid), + join.essid, join.bss_type, join.channel, le16_to_cpu(join.timeout)); + return set_card_command(dev->udev, CMD_JOIN, + (unsigned char*)&join, + sizeof(struct at76c503_join)); +} /* join_bss */ + +/* the firmware download timeout (after remap) */ +static void fw_dl_timeout(unsigned long par) +{ + struct at76c503 *dev = (struct at76c503 *)par; + defer_kevent(dev, KEVENT_RESET_DEVICE); +} + + +/* the restart timer timed out */ +static void restart_timeout(unsigned long par) +{ + struct at76c503 *dev = (struct at76c503 *)par; + defer_kevent(dev, KEVENT_RESTART); +} + +/* we got to check the bss_list for old entries */ +static void bss_list_timeout(unsigned long par) +{ + struct at76c503 *dev = (struct at76c503 *)par; + unsigned long flags; + struct list_head *lptr, *nptr; + struct bss_info *ptr; + + spin_lock_irqsave(&dev->bss_list_spinlock, flags); + + list_for_each_safe(lptr, nptr, &dev->bss_list) { + + ptr = list_entry(lptr, struct bss_info, list); + + if (ptr != dev->curr_bss && ptr != dev->new_bss && + time_after(jiffies, ptr->last_rx+BSS_LIST_TIMEOUT)) { + dbg(DBG_BSS_TABLE_RM, + "%s: bss_list: removing old BSS %s ch %d", + dev->netdev->name, mac2str(ptr->bssid), ptr->channel); + list_del(&ptr->list); + kfree(ptr); + } + } + spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); + /* restart the timer */ + mod_timer(&dev->bss_list_timer, jiffies+BSS_LIST_TIMEOUT); + +} + +/* we got a timeout for a infrastructure mgmt packet */ +static void mgmt_timeout(unsigned long par) +{ + struct at76c503 *dev = (struct at76c503 *)par; + defer_kevent(dev, KEVENT_MGMT_TIMEOUT); +} + +/* == PROC handle_mgmt_timeout_scan == */ +/* called in istate SCANNING on expiry of the mgmt_timer, when a scan was run before + (dev->scan_runs > 0) */ +static void handle_mgmt_timeout_scan(struct at76c503 *dev) +{ + + u8 *cmd_status; + int ret; + struct mib_mdomain mdomain; + + cmd_status = kmalloc(40, GFP_KERNEL); + if (cmd_status == NULL) { + err("%s: %s: cmd_status kmalloc returned NULL", + dev->netdev->name, __FUNCTION__); + return; + } + + + if ((ret=get_cmd_status(dev->udev, CMD_SCAN, cmd_status)) < 0) { + err("%s: %s: get_cmd_status failed with %d", + dev->netdev->name, __FUNCTION__, ret); + cmd_status[5] = CMD_STATUS_IN_PROGRESS; + /* INFO: Hope it was a one off error - if not, scanning + further down the line and stop this cycle */ + } + LOCK_ISTATE() + dbg(DBG_PROGRESS, "%s %s:%d got cmd_status %d (istate %d, " + "scan_runs %d)", + dev->netdev->name, __FUNCTION__, __LINE__, cmd_status[5], + dev->istate, dev->scan_runs); + UNLOCK_ISTATE() + if (cmd_status[5] == CMD_STATUS_COMPLETE) { + LOCK_ISTATE() + if (dev->istate == SCANNING) { + UNLOCK_ISTATE() + dump_bss_table(dev,0); + switch (dev->scan_runs) { + + case 1: + assert(dev->international_roaming); + if ((ret=get_mib_mdomain(dev, &mdomain)) < 0) { + err("get_mib_mdomain returned %d", ret); + } else { + char obuf1[2*14+1], obuf2[2*14+1]; + + dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s " + "tx_powerlevel %s", + dev->netdev->name, + hex2str(obuf1, mdomain.channel_list, + (sizeof(obuf1)-1)/2,'\0'), + hex2str(obuf2, mdomain.tx_powerlevel, + (sizeof(obuf2)-1)/2,'\0')); + } + if ((ret = start_scan(dev, 0, 1)) < 0) { + err("%s: %s: start_scan (ANY) failed with %d", + dev->netdev->name, __FUNCTION__, ret); + } + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", + __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); + mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + break; + + case 2: + if ((ret = start_scan(dev, 1, 1)) < 0) { + err("%s: %s: start_scan (SSID) failed with %d", + dev->netdev->name, __FUNCTION__, ret); + } + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", + __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); + mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + break; + + case 3: + dev->site_survey_state = SITE_SURVEY_COMPLETED; + /* report the end of scan to user space */ + iwevent_scan_complete(dev->netdev); + NEW_STATE(dev,JOINING); + assert(dev->curr_bss == NULL); /* done in free_bss_list, + find_bss will start with first bss */ + /* call join_bss immediately after + re-run of all other threads in kevent */ + defer_kevent(dev,KEVENT_JOIN); + break; + + default: + err("unexpected dev->scan_runs %d", dev->scan_runs); + } /* switch (dev->scan_runs)*/ + dev->scan_runs++; + } else { + + assert(dev->istate == MONITORING); + UNLOCK_ISTATE() + dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE: restart scan", + dev->netdev->name); + start_scan(dev, 0, 0); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", + __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); + mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + } + + } else { + if ((cmd_status[5] != CMD_STATUS_IN_PROGRESS) && + (cmd_status[5] != CMD_STATUS_IDLE)) + err("%s: %s: Bad scan status: %s", + dev->netdev->name, __FUNCTION__, + get_cmd_status_string(cmd_status[5])); + + /* the first cmd status after scan start is always a IDLE -> + start the timer to poll again until COMPLETED */ + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", + __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); + mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + } + + kfree(cmd_status); +} + +/* the deferred procedure called from kevent() */ +static void handle_mgmt_timeout(struct at76c503 *dev) +{ + LOCK_ISTATE() + if ((dev->istate != SCANNING && dev->istate != MONITORING) || + (at76_debug & DBG_MGMT_TIMER)) + /* this is normal behavior in states MONITORING, SCANNING ... */ + dbg(DBG_PROGRESS, "%s: timeout, state %d", dev->netdev->name, + dev->istate); + + switch(dev->istate) { + + case MONITORING: + case SCANNING: + UNLOCK_ISTATE() + handle_mgmt_timeout_scan(dev); + break; + + case JOINING: + UNLOCK_ISTATE() + assert(0); + break; + + case CONNECTED: /* we haven't received the beacon of this BSS for + BEACON_TIMEOUT seconds */ + UNLOCK_ISTATE() + info("%s: lost beacon bssid %s", + dev->netdev->name, mac2str(dev->curr_bss->bssid)); + /* jal: starting mgmt_timer in ad-hoc mode is questionable, + but I'll leave it here to track down another lockup problem */ + if (dev->iw_mode != IW_MODE_ADHOC) { + netif_carrier_off(dev->netdev); + netif_stop_queue(dev->netdev); + iwevent_bss_disconnect(dev->netdev); + NEW_STATE(dev,SCANNING); + defer_kevent(dev,KEVENT_SCAN); + } + break; + + case AUTHENTICATING: + UNLOCK_ISTATE() + if (dev->retries-- >= 0) { + auth_req(dev, dev->curr_bss, 1, NULL); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", + __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer, jiffies+HZ); + } else { + /* try to get next matching BSS */ + NEW_STATE(dev,JOINING); + defer_kevent(dev,KEVENT_JOIN); + } + break; + + case ASSOCIATING: + UNLOCK_ISTATE() + if (dev->retries-- >= 0) { + assoc_req(dev,dev->curr_bss); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", + __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer, jiffies+HZ); + } else { + /* jal: TODO: we may be authenticated to several + BSS and may try to associate to the next of them here + in the future ... */ + + /* try to get next matching BSS */ + NEW_STATE(dev,JOINING); + defer_kevent(dev,KEVENT_JOIN); + } + break; + + case REASSOCIATING: + UNLOCK_ISTATE() + if (dev->retries-- >= 0) + reassoc_req(dev, dev->curr_bss, dev->new_bss); + else { + /* we disassociate from the curr_bss and + scan again ... */ + NEW_STATE(dev,DISASSOCIATING); + dev->retries = DISASSOC_RETRIES; + disassoc_req(dev, dev->curr_bss); + } + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", + __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer, jiffies+HZ); + break; + + case DISASSOCIATING: + UNLOCK_ISTATE() + if (dev->retries-- >= 0) { + disassoc_req(dev, dev->curr_bss); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", + __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer,jiffies+HZ); + } else { + /* we scan again ... */ + NEW_STATE(dev,SCANNING); + defer_kevent(dev,KEVENT_SCAN); + } + break; + + case INIT: + UNLOCK_ISTATE() + break; + + default: + UNLOCK_ISTATE() + assert(0); + } /* switch (dev->istate) */ + +}/* handle_mgmt_timeout */ + +/* calc. the padding from txbuf->wlength (which excludes the USB TX header) + guess this is needed to compensate a flaw in the AT76C503A USB part ... */ +static inline int calc_padding(int wlen) +{ + /* add the USB TX header */ + wlen += AT76C503_TX_HDRLEN; + + wlen = wlen % 64; + + if (wlen < 50) + return 50 - wlen; + + if (wlen >=61) + return 64 + 50 - wlen; + + return 0; +} + +/* send a management frame on bulk-out. + txbuf->wlength must be set (in LE format !) */ +static int send_mgmt_bulk(struct at76c503 *dev, struct at76c503_tx_buffer *txbuf) +{ + unsigned long flags; + int ret = 0; + int urb_status; + void *oldbuf = NULL; + + netif_carrier_off(dev->netdev); /* disable running netdev watchdog */ + netif_stop_queue(dev->netdev); /* stop tx data packets */ + + spin_lock_irqsave(&dev->mgmt_spinlock, flags); + + if ((urb_status=dev->write_urb->status) == -EINPROGRESS) { + oldbuf=dev->next_mgmt_bulk; /* to kfree below */ + dev->next_mgmt_bulk = txbuf; + txbuf = NULL; + } + spin_unlock_irqrestore(&dev->mgmt_spinlock, flags); + + if (oldbuf) { + /* a data/mgmt tx is already pending in the URB - + if this is no error in some situations we must + implement a queue or silently modify the old msg */ + err("%s: %s removed pending mgmt buffer %s", + dev->netdev->name, __FUNCTION__, + hex2str(dev->obuf, (u8 *)dev->next_mgmt_bulk, + min((int)(sizeof(dev->obuf))/3, 64),' ')); + kfree(dev->next_mgmt_bulk); + } + + if (txbuf) { + + txbuf->tx_rate = 0; +// txbuf->padding = 0; + txbuf->padding = calc_padding(le16_to_cpu(txbuf->wlength)); + + if (dev->next_mgmt_bulk) { + err("%s: %s URB status %d, but mgmt is pending", + dev->netdev->name, __FUNCTION__, urb_status); + } + + dbg(DBG_TX_MGMT, "%s: tx mgmt: wlen %d tx_rate %d pad %d %s", + dev->netdev->name, le16_to_cpu(txbuf->wlength), + txbuf->tx_rate, txbuf->padding, + hex2str(dev->obuf, txbuf->packet, + min((sizeof(dev->obuf)-1)/2, + (size_t)le16_to_cpu(txbuf->wlength)),'\0')); + + /* txbuf was not consumed above -> send mgmt msg immediately */ + memcpy(dev->bulk_out_buffer, txbuf, + le16_to_cpu(txbuf->wlength) + AT76C503_TX_HDRLEN); + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, + dev->bulk_out_endpointAddr), + dev->bulk_out_buffer, + le16_to_cpu(txbuf->wlength) + + txbuf->padding + + AT76C503_TX_HDRLEN, + (usb_complete_t)at76c503_write_bulk_callback, dev); + ret = usb_submit_urb(dev->write_urb, GFP_ATOMIC); + if (ret) { + err("%s: %s error in tx submit urb: %d", + dev->netdev->name, __FUNCTION__, ret); + } + kfree(txbuf); + } /* if (txbuf) */ + + return ret; + +} /* send_mgmt_bulk */ + +static int disassoc_req(struct at76c503 *dev, struct bss_info *bss) +{ + struct at76c503_tx_buffer *tx_buffer; + struct ieee80211_hdr_3addr *mgmt; + struct ieee802_11_disassoc_frame *req; + + assert(bss != NULL); + if (bss == NULL) + return -EFAULT; + + tx_buffer = kmalloc(DISASSOC_FRAME_SIZE + MAX_PADDING_SIZE, + GFP_ATOMIC); + if (!tx_buffer) + return -ENOMEM; + + mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet); + req = (struct ieee802_11_disassoc_frame *)&(mgmt->payload); + + /* make wireless header */ + mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_AUTH); + mgmt->duration_id = cpu_to_le16(0x8000); + memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); + memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN); + memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); + mgmt->seq_ctl = cpu_to_le16(0); + + req->reason = 0; + + /* init. at76c503 tx header */ + tx_buffer->wlength = cpu_to_le16(DISASSOC_FRAME_SIZE - + AT76C503_TX_HDRLEN); + + dbg(DBG_TX_MGMT, "%s: DisAssocReq bssid %s", + dev->netdev->name, mac2str(mgmt->addr3)); + + /* either send immediately (if no data tx is pending + or put it in pending list */ + return send_mgmt_bulk(dev, tx_buffer); + +} /* disassoc_req */ + +/* challenge is the challenge string (in TLV format) + we got with seq_nr 2 for shared secret authentication only and + send in seq_nr 3 WEP encrypted to prove we have the correct WEP key; + otherwise it is NULL */ +static int auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr, u8 *challenge) +{ + struct at76c503_tx_buffer *tx_buffer; + struct ieee80211_hdr_3addr *mgmt; + struct ieee802_11_auth_frame *req; + + int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE : + AUTH_FRAME_SIZE + 1 + 1 + challenge[1]); + + assert(bss != NULL); + assert(seq_nr != 3 || challenge != NULL); + + tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC); + if (!tx_buffer) + return -ENOMEM; + + mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet); + req = (struct ieee802_11_auth_frame *)&(mgmt->payload); + + /* make wireless header */ + /* first auth msg is not encrypted, only the second (seq_nr == 3) */ + mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH | + (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0)); + + mgmt->duration_id = cpu_to_le16(0x8000); + memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); + memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN); + memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); + mgmt->seq_ctl = cpu_to_le16(0); + + req->algorithm = cpu_to_le16(dev->auth_mode); + req->seq_nr = cpu_to_le16(seq_nr); + req->status = cpu_to_le16(0); + + if (seq_nr == 3) + memcpy(req->challenge, challenge, 1+1+challenge[1]); + + /* init. at76c503 tx header */ + tx_buffer->wlength = cpu_to_le16(buf_len - AT76C503_TX_HDRLEN); + + dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d", + dev->netdev->name, mac2str(mgmt->addr3), + le16_to_cpu(req->algorithm), le16_to_cpu(req->seq_nr)); + if (seq_nr == 3) { + dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...", + dev->netdev->name, + hex2str(dev->obuf, req->challenge, + min((int)sizeof(dev->obuf)/3, 18),' ')); + } + + /* either send immediately (if no data tx is pending + or put it in pending list */ + return send_mgmt_bulk(dev, tx_buffer); + +} /* auth_req */ + +static int assoc_req(struct at76c503 *dev, struct bss_info *bss) +{ + struct at76c503_tx_buffer *tx_buffer; + struct ieee80211_hdr_3addr *mgmt; + struct ieee802_11_assoc_req *req; + u8 *tlv; + + assert(bss != NULL); + + tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, + GFP_ATOMIC); + if (!tx_buffer) + return -ENOMEM; + + mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet); + req = (struct ieee802_11_assoc_req *)&(mgmt->payload); + tlv = req->data; + + /* make wireless header */ + mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_ASSOC_REQ); + + mgmt->duration_id = cpu_to_le16(0x8000); + memcpy(mgmt->addr1, bss->bssid, ETH_ALEN); + memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN); + memcpy(mgmt->addr3, bss->bssid, ETH_ALEN); + mgmt->seq_ctl = cpu_to_le16(0); + + /* we must set the Privacy bit in the capabilities to assure an + Agere-based AP with optional WEP transmits encrypted frames + to us. AP only set the Privacy bit in their capabilities + if WEP is mandatory in the BSS! */ + req->capability = cpu_to_le16(bss->capa | + (dev->wep_enabled ? WLAN_CAPABILITY_PRIVACY : 0) | + (dev->preamble_type == PREAMBLE_TYPE_SHORT ? + WLAN_CAPABILITY_SHORT_PREAMBLE : 0)); + + req->listen_interval = cpu_to_le16(2 * bss->beacon_interval); + + /* write TLV data elements */ + + *tlv++ = MFIE_TYPE_SSID; + *tlv++ = bss->ssid_len; + memcpy(tlv, bss->ssid, bss->ssid_len); + tlv += bss->ssid_len; + + *tlv++ = MFIE_TYPE_RATES; + *tlv++ = sizeof(hw_rates); + memcpy(tlv, hw_rates, sizeof(hw_rates)); + tlv += sizeof(hw_rates); /* tlv points behind the supp_rates field */ + + /* init. at76c503 tx header */ + tx_buffer->wlength = cpu_to_le16(tlv-(u8 *)mgmt); + + { + /* output buffer for ssid and rates */ + char orates[4*2+1]; + int len; + + tlv = req->data; + len = min(IW_ESSID_MAX_SIZE, (int)*(tlv+1)); + memcpy(dev->obuf, tlv+2, len); + dev->obuf[len] = '\0'; + tlv += (1 + 1 + *(tlv+1)); /* points to IE of rates now */ + dbg(DBG_TX_MGMT, "%s: AssocReq bssid %s capa x%04x ssid %s rates %s", + dev->netdev->name, mac2str(mgmt->addr3), + le16_to_cpu(req->capability), dev->obuf, + hex2str(orates,tlv+2,min((sizeof(orates)-1)/2,(size_t)*(tlv+1)), + '\0')); + } + + /* either send immediately (if no data tx is pending + or put it in pending list */ + return send_mgmt_bulk(dev, tx_buffer); + +} /* assoc_req */ + +/* we are currently associated to curr_bss and + want to reassoc to new_bss */ +static int reassoc_req(struct at76c503 *dev, struct bss_info *curr_bss, + struct bss_info *new_bss) +{ + struct at76c503_tx_buffer *tx_buffer; + struct ieee80211_hdr_3addr *mgmt; + struct ieee802_11_reassoc_req *req; + + u8 *tlv; + + assert(curr_bss != NULL); + assert(new_bss != NULL); + if (curr_bss == NULL || new_bss == NULL) + return -EFAULT; + + tx_buffer = kmalloc(REASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, + GFP_ATOMIC); + if (!tx_buffer) + return -ENOMEM; + + mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet); + req = (struct ieee802_11_reassoc_req *)&(mgmt->payload); + tlv = req->data; + + /* make wireless header */ + /* jal: encrypt this packet if wep_enabled is TRUE ??? */ + mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_REASSOC_REQ); + mgmt->duration_id = cpu_to_le16(0x8000); + memcpy(mgmt->addr1, new_bss->bssid, ETH_ALEN); + memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN); + memcpy(mgmt->addr3, new_bss->bssid, ETH_ALEN); + mgmt->seq_ctl = cpu_to_le16(0); + + /* we must set the Privacy bit in the capabilities to assure an + Agere-based AP with optional WEP transmits encrypted frames + to us. AP only set the Privacy bit in their capabilities + if WEP is mandatory in the BSS! */ + req->capability = cpu_to_le16(new_bss->capa | + (dev->wep_enabled ? WLAN_CAPABILITY_PRIVACY : 0) | + (dev->preamble_type == PREAMBLE_TYPE_SHORT ? + WLAN_CAPABILITY_SHORT_PREAMBLE : 0)); + + req->listen_interval = cpu_to_le16(2 * new_bss->beacon_interval); + + memcpy(req->curr_ap, curr_bss->bssid, ETH_ALEN); + + /* write TLV data elements */ + + *tlv++ = MFIE_TYPE_SSID; + *tlv++ = new_bss->ssid_len; + memcpy(tlv,new_bss->ssid, new_bss->ssid_len); + tlv += new_bss->ssid_len; + + *tlv++ = MFIE_TYPE_RATES; + *tlv++ = sizeof(hw_rates); + memcpy(tlv, hw_rates, sizeof(hw_rates)); + tlv += sizeof(hw_rates); /* tlv points behind the supp_rates field */ + + /* init. at76c503 tx header */ + tx_buffer->wlength = cpu_to_le16(tlv-(u8 *)mgmt); + + { + /* output buffer for rates and bssid */ + char orates[4*2+1]; + char ocurr[6*3+1]; + tlv = req->data; + memcpy(dev->obuf, tlv+2, min(sizeof(dev->obuf),(size_t)*(tlv+1))); + dev->obuf[IW_ESSID_MAX_SIZE] = '\0'; + tlv += (1 + 1 + *(tlv+1)); /* points to IE of rates now */ + dbg(DBG_TX_MGMT, "%s: ReAssocReq curr %s new %s capa x%04x ssid %s rates %s", + dev->netdev->name, + hex2str(ocurr, req->curr_ap, ETH_ALEN, ':'), + mac2str(mgmt->addr3), le16_to_cpu(req->capability), dev->obuf, + hex2str(orates,tlv+2,min((sizeof(orates)-1)/2,(size_t)*(tlv+1)), + '\0')); + } + + /* either send immediately (if no data tx is pending + or put it in pending list */ + return send_mgmt_bulk(dev, tx_buffer); + +} /* reassoc_req */ + + +/* shamelessly copied from usbnet.c (oku) */ +static void defer_kevent (struct at76c503 *dev, int flag) +{ + set_bit (flag, &dev->kevent_flags); + if (!schedule_work (&dev->kevent)) + dbg(DBG_KEVENT, "%s: kevent %d may have been dropped", + dev->netdev->name, flag); + else + dbg(DBG_KEVENT, "%s: kevent %d scheduled", + dev->netdev->name, flag); +} + +static void kevent(struct work_struct *ws) +{ + struct at76c503 *dev = container_of(ws, struct at76c503, kevent); + int ret; + unsigned long flags; + + /* on errors, bits aren't cleared, but no reschedule + is done. So work will be done next time something + else has to be done. This is ugly. TODO! (oku) */ + + dbg(DBG_KEVENT, "%s: kevent entry flags: 0x%lx", dev->netdev->name, + dev->kevent_flags); + + down(&dev->sem); + + if(test_bit(KEVENT_CTRL_HALT, &dev->kevent_flags)){ + /* this never worked... but it seems + that it's rarely necessary, if at all (oku) */ + ret = usb_clear_halt(dev->udev, + usb_sndctrlpipe (dev->udev, 0)); + if(ret < 0) + err("usb_clear_halt() failed: %d", ret); + else{ + clear_bit(KEVENT_CTRL_HALT, &dev->kevent_flags); + info("usb_clear_halt() successful"); + } + } + if(test_bit(KEVENT_NEW_BSS, &dev->kevent_flags)){ + struct net_device *netdev = dev->netdev; + struct mib_mac_mgmt *mac_mgmt = kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL); + + ret = get_mib(dev->udev, MIB_MAC_MGMT, (u8*)mac_mgmt, + sizeof(struct mib_mac_mgmt)); + if(ret < 0){ + err("%s: get_mib failed: %d", netdev->name, ret); + goto new_bss_clean; + } + + dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt->ibss_change); + memcpy(dev->bssid, mac_mgmt->current_bssid, ETH_ALEN); + dbg(DBG_PROGRESS, "using BSSID %s", mac2str(dev->bssid)); + + iwevent_bss_connect(dev->netdev, dev->bssid); + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_MGMT; + dev->mib_buf.size = 1; + dev->mib_buf.index = IBSS_CHANGE_OK_OFFSET; + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (ibss change ok) failed: %d", netdev->name, ret); + goto new_bss_clean; + } + clear_bit(KEVENT_NEW_BSS, &dev->kevent_flags); + new_bss_clean: + kfree(mac_mgmt); + } + + if(test_bit(KEVENT_SET_PROMISC, &dev->kevent_flags)){ + info("%s: KEVENT_SET_PROMISC", dev->netdev->name); + + set_promisc(dev, dev->promisc); + clear_bit(KEVENT_SET_PROMISC, &dev->kevent_flags); + } + + /* check this _before_ KEVENT_JOIN, 'cause _JOIN sets _STARTIBSS bit */ + if (test_bit(KEVENT_STARTIBSS, &dev->kevent_flags)) { + clear_bit(KEVENT_STARTIBSS, &dev->kevent_flags); + LOCK_ISTATE() + assert(dev->istate == STARTIBSS); + UNLOCK_ISTATE() + ret = start_ibss(dev); + if(ret < 0){ + err("%s: start_ibss failed: %d", dev->netdev->name, ret); + goto end_startibss; + } + + ret = wait_completion(dev, CMD_START_IBSS); + if (ret != CMD_STATUS_COMPLETE) { + err("%s start_ibss failed to complete,%d", + dev->netdev->name, ret); + goto end_startibss; + } + + ret = get_current_bssid(dev); + if(ret < 0) goto end_startibss; + + ret = get_current_channel(dev); + if(ret < 0) goto end_startibss; + + /* not sure what this is good for ??? */ + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_MGMT; + dev->mib_buf.size = 1; + dev->mib_buf.index = IBSS_CHANGE_OK_OFFSET; + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (ibss change ok) failed: %d", dev->netdev->name, ret); + goto end_startibss; + } + + netif_carrier_on(dev->netdev); + netif_start_queue(dev->netdev); + } +end_startibss: + + /* check this _before_ KEVENT_SCAN, 'cause _SCAN sets _JOIN bit */ + if (test_bit(KEVENT_JOIN, &dev->kevent_flags)) { + clear_bit(KEVENT_JOIN, &dev->kevent_flags); + LOCK_ISTATE() + if (dev->istate == INIT){ + UNLOCK_ISTATE() + goto end_join; + } + assert(dev->istate == JOINING); + UNLOCK_ISTATE() + /* dev->curr_bss == NULL signals a new round, + starting with list_entry(dev->bss_list.next, ...) */ + + /* secure the access to dev->curr_bss ! */ + spin_lock_irqsave(&dev->bss_list_spinlock, flags); + dev->curr_bss=find_matching_bss(dev, dev->curr_bss); + spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); + + if (dev->curr_bss != NULL) { + if ((ret=join_bss(dev,dev->curr_bss)) < 0) { + err("%s: join_bss failed with %d", + dev->netdev->name, ret); + goto end_join; + } + + ret=wait_completion(dev,CMD_JOIN); + if (ret != CMD_STATUS_COMPLETE) { + if (ret != CMD_STATUS_TIME_OUT) + err("%s join_bss completed with %d", + dev->netdev->name, ret); + else + info("%s join_bss ssid %s timed out", + dev->netdev->name, + mac2str(dev->curr_bss->bssid)); + + /* retry next BSS immediately */ + defer_kevent(dev,KEVENT_JOIN); + goto end_join; + } + + /* here we have joined the (I)BSS */ + if (dev->iw_mode == IW_MODE_ADHOC) { + struct bss_info *bptr = dev->curr_bss; + NEW_STATE(dev,CONNECTED); + /* get ESSID, BSSID and channel for dev->curr_bss */ + dev->essid_size = bptr->ssid_len; + memcpy(dev->essid, bptr->ssid, bptr->ssid_len); + memcpy(dev->bssid, bptr->bssid, ETH_ALEN); + dev->channel = bptr->channel; + iwevent_bss_connect(dev->netdev,bptr->bssid); + netif_carrier_on(dev->netdev); + netif_start_queue(dev->netdev); + /* just to be sure */ + del_timer_sync(&dev->mgmt_timer); + } else { + /* send auth req */ + NEW_STATE(dev,AUTHENTICATING); + auth_req(dev, dev->curr_bss, 1, NULL); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", + __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer, jiffies+HZ); + } + goto end_join; + } /* if (dev->curr_bss != NULL) */ + + /* here we haven't found a matching (i)bss ... */ + if (dev->iw_mode == IW_MODE_ADHOC) { + NEW_STATE(dev,STARTIBSS); + defer_kevent(dev,KEVENT_STARTIBSS); + goto end_join; + } + /* haven't found a matching BSS in infra mode - try again */ + NEW_STATE(dev,SCANNING); + defer_kevent(dev, KEVENT_SCAN); + } /* if (test_bit(KEVENT_JOIN, &dev->kevent_flags)) */ +end_join: + + if(test_bit(KEVENT_MGMT_TIMEOUT, &dev->kevent_flags)){ + clear_bit(KEVENT_MGMT_TIMEOUT, &dev->kevent_flags); + handle_mgmt_timeout(dev); + } + + if (test_bit(KEVENT_SCAN, &dev->kevent_flags)) { + clear_bit(KEVENT_SCAN, &dev->kevent_flags); + LOCK_ISTATE() + assert(dev->istate == SCANNING); + + /* only clear the bss list when a scan is actively initiated, + * otherwise simply rely on bss_list_timeout */ + if( dev->site_survey_state == SITE_SURVEY_IN_PROGRESS) + free_bss_list(dev); + UNLOCK_ISTATE() + + dev->scan_runs=3; + if ((ret=start_scan(dev, 0, 1)) < 0) { + err("%s: %s: start_scan failed with %d", + dev->netdev->name, __FUNCTION__, ret); + } else { + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", + __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); + mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + } + + } /* if (test_bit(KEVENT_SCAN, &dev->kevent_flags)) */ + + + if (test_bit(KEVENT_SUBMIT_RX, &dev->kevent_flags)) { + clear_bit(KEVENT_SUBMIT_RX, &dev->kevent_flags); + submit_rx_urb(dev); + } + + + if (test_bit(KEVENT_RESTART, &dev->kevent_flags)) { + clear_bit(KEVENT_RESTART, &dev->kevent_flags); + LOCK_ISTATE() + assert(dev->istate == INIT); + UNLOCK_ISTATE() + startup_device(dev); + + /* call it here for default_iw_mode == IW_MODE_MONITOR and + no subsequent "iwconfig wlanX mode monitor" or + "iwpriv wlanX monitor 1|2 C" to set dev->netdev->type + correctly */ + set_monitor_mode(dev, dev->monitor_prism_header); + + + netif_carrier_off(dev->netdev); /* disable running netdev watchdog */ + netif_stop_queue(dev->netdev); /* stop tx data packets */ + if (dev->iw_mode != IW_MODE_MONITOR) { + NEW_STATE(dev,SCANNING); + defer_kevent(dev,KEVENT_SCAN); + } else { + NEW_STATE(dev,MONITORING); + start_scan(dev,0,0); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks", + __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL); + mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL); + } + } + + if (test_bit(KEVENT_ASSOC_DONE, &dev->kevent_flags)) { + clear_bit(KEVENT_ASSOC_DONE, &dev->kevent_flags); + LOCK_ISTATE() + assert(dev->istate == ASSOCIATING || + dev->istate == REASSOCIATING); + UNLOCK_ISTATE() + if (dev->iw_mode == IW_MODE_INFRA) { + assert(dev->curr_bss != NULL); + if (dev->curr_bss != NULL && + dev->pm_mode != PM_ACTIVE) { + /* calc the listen interval in units of + beacon intervals of the curr_bss */ + dev->pm_period_beacon = (dev->pm_period_us >> 10) / + dev->curr_bss->beacon_interval; + +#ifdef DEBUG /* only to check if we need to set the listen interval here + or could do it in the (re)assoc_req parameter */ + dump_mib_mac(dev); +#endif + + if (dev->pm_period_beacon < 2) + dev->pm_period_beacon = 2; + else + if ( dev->pm_period_beacon > 0xffff) + dev->pm_period_beacon = 0xffff; + + dbg(DBG_PM, "%s: pm_mode %d assoc id x%x listen int %d", + dev->netdev->name, dev->pm_mode, + dev->curr_bss->assoc_id, dev->pm_period_beacon); + + set_associd(dev, dev->curr_bss->assoc_id); + set_listen_interval(dev, (u16)dev->pm_period_beacon); + set_pm_mode(dev, dev->pm_mode); +#ifdef DEBUG + dump_mib_mac(dev); + dump_mib_mac_mgmt(dev); +#endif + } + } + + netif_carrier_on(dev->netdev); + netif_wake_queue(dev->netdev); /* _start_queue ??? */ + NEW_STATE(dev,CONNECTED); + iwevent_bss_connect(dev->netdev,dev->curr_bss->bssid); + dbg(DBG_PROGRESS, "%s: connected to BSSID %s", + dev->netdev->name, mac2str(dev->curr_bss->bssid)); + } + + + if (test_bit(KEVENT_RESET_DEVICE, &dev->kevent_flags)) { + + clear_bit(KEVENT_RESET_DEVICE, &dev->kevent_flags); + + dbg(DBG_DEVSTART, "resetting the device"); + + usb_reset_device(dev->udev); + +/* with 2.6.8 the reset above will cause a disconnect as the USB subsys + recognizes the change in the config descriptors. Subsequently the device + will be registered again. */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) + + //jal: patch the state (patch by Dmitri) + dev->udev->state = USB_STATE_CONFIGURED; + + /* jal: currently (2.6.0-test2 and 2.4.23) + usb_reset_device() does not recognize that + the interface descr. are changed. + This procedure reads the configuration and does a limited parsing of + the interface and endpoint descriptors */ + update_usb_intf_descr(dev); + + /* continue immediately with external fw download */ + set_bit (KEVENT_EXTERNAL_FW, &dev->kevent_flags); +#else + /* kernel >= 2.6.8 */ + NEW_STATE(dev, WAIT_FOR_DISCONNECT); +#endif + } + + if (test_bit(KEVENT_EXTERNAL_FW, &dev->kevent_flags)) { + u8 op_mode; + + clear_bit(KEVENT_EXTERNAL_FW, &dev->kevent_flags); + + op_mode = get_op_mode(dev->udev); + dbg(DBG_DEVSTART, "opmode %d", op_mode); + + if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { + err("unexpected opmode %d", op_mode); + goto end_external_fw; + } + + if (dev->extfw && dev->extfw_size) { + ret = download_external_fw(dev->udev, dev->extfw, + dev->extfw_size); + if (ret < 0) { + err("Downloading external firmware failed: %d", ret); + goto end_external_fw; + } + if (dev->board_type == BOARDTYPE_505A_RFMD_2958) { + info("200 ms delay for board type 7"); + /* jal: can I do this in kevent ??? */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/5+1); + } + } + NEW_STATE(dev,INIT); + init_new_device(dev); + } +end_external_fw: + + if (test_bit(KEVENT_INTERNAL_FW, &dev->kevent_flags)) { + clear_bit(KEVENT_INTERNAL_FW, &dev->kevent_flags); + + dbg(DBG_DEVSTART, "downloading internal firmware"); + + ret=usbdfu_download(dev->udev, dev->intfw, + dev->intfw_size, + dev->board_type == BOARDTYPE_505A_RFMD_2958 ? 2000: 0); + + if (ret < 0) { + err("downloading internal fw failed with %d",ret); + goto end_internal_fw; + } + + dbg(DBG_DEVSTART, "sending REMAP"); + + /* no REMAP for 505A (see SF driver) */ + if (dev->board_type != BOARDTYPE_505A_RFMD_2958) + if ((ret=at76c503_remap(dev->udev)) < 0) { + err("sending REMAP failed with %d",ret); + goto end_internal_fw; + } + + dbg(DBG_DEVSTART, "sleeping for 2 seconds"); + NEW_STATE(dev,EXTFW_DOWNLOAD); + mod_timer(&dev->fw_dl_timer, jiffies+2*HZ+1); + } +end_internal_fw: + + up(&dev->sem); + + dbg(DBG_KEVENT, "%s: kevent exit flags: 0x%lx", dev->netdev->name, + dev->kevent_flags); + + return; +} + +static int essid_matched(struct at76c503 *dev, struct bss_info *ptr) +{ + /* common criteria for both modi */ + + int retval = (dev->essid_size == 0 /* ANY ssid */ || + (dev->essid_size == ptr->ssid_len && + !memcmp(dev->essid, ptr->ssid, ptr->ssid_len))); + if (!retval) + dbg(DBG_BSS_MATCH, "%s bss table entry %p: essid didn't match", + dev->netdev->name, ptr); + return retval; +} + +static inline int mode_matched(struct at76c503 *dev, struct bss_info *ptr) +{ + int retval; + + if (dev->iw_mode == IW_MODE_ADHOC) + retval = ptr->capa & WLAN_CAPABILITY_IBSS; + else + retval = ptr->capa & WLAN_CAPABILITY_ESS; + if (!retval) + dbg(DBG_BSS_MATCH, "%s bss table entry %p: mode didn't match", + dev->netdev->name, ptr); + return retval; +} + +static int rates_matched(struct at76c503 *dev, struct bss_info *ptr) +{ + int i; + u8 *rate; + + for(i=0,rate=ptr->rates; i < ptr->rates_len; i++,rate++) + if (*rate & 0x80) { + /* this is a basic rate we have to support + (see IEEE802.11, ch. 7.3.2.2) */ + if (*rate != (0x80|hw_rates[0]) && *rate != (0x80|hw_rates[1]) && + *rate != (0x80|hw_rates[2]) && *rate != (0x80|hw_rates[3])) { + dbg(DBG_BSS_MATCH, + "%s: bss table entry %p: basic rate %02x not supported", + dev->netdev->name, ptr, *rate); + return 0; + } + } + /* if we use short preamble, the bss must support it */ + if (dev->preamble_type == PREAMBLE_TYPE_SHORT && + !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) { + dbg(DBG_BSS_MATCH, "%s: %p does not support short preamble", + dev->netdev->name, ptr); + return 0; + } else + return 1; +} + +static inline int wep_matched(struct at76c503 *dev, struct bss_info *ptr) +{ + if (!dev->wep_enabled && + ptr->capa & WLAN_CAPABILITY_PRIVACY) { + /* we have disabled WEP, but the BSS signals privacy */ + dbg(DBG_BSS_MATCH, "%s: bss table entry %p: requires encryption", + dev->netdev->name, ptr); + return 0; + } + /* otherwise if the BSS does not signal privacy it may well + accept encrypted packets from us ... */ + return 1; +} + +static inline int bssid_matched(struct at76c503 *dev, struct bss_info *ptr) +{ + if (!dev->wanted_bssid_valid || + !memcmp(ptr->bssid, dev->wanted_bssid, ETH_ALEN)) { + return 1; + } else { + if (at76_debug & DBG_BSS_MATCH) { + dbg_uc("%s: requested bssid - %s does not match", + dev->netdev->name, mac2str(dev->wanted_bssid)); + dbg_uc(" AP bssid - %s of bss table entry %p", + mac2str(ptr->bssid), ptr); + } + return 0; + } +} + +static void dump_bss_table(struct at76c503 *dev, int force_output) +{ + struct bss_info *ptr; + /* hex dump output buffer for debug */ + unsigned long flags; + struct list_head *lptr; + + if ((at76_debug & DBG_BSS_TABLE) || (force_output)) { + spin_lock_irqsave(&dev->bss_list_spinlock, flags); + + dbg_uc("%s BSS table (curr=%p, new=%p):", dev->netdev->name, + dev->curr_bss, dev->new_bss); + + list_for_each(lptr, &dev->bss_list) { + ptr = list_entry(lptr, struct bss_info, list); + dbg_uc("0x%p: bssid %s channel %d ssid %s (%s)" + " capa x%04x rates %s rssi %d link %d noise %d", + ptr, mac2str(ptr->bssid), + ptr->channel, + ptr->ssid, + hex2str(dev->obuf, ptr->ssid, + min((sizeof(dev->obuf)-1)/2, + (size_t)ptr->ssid_len),'\0'), + ptr->capa, + hex2str(dev->obuf_s, ptr->rates, + min(sizeof(dev->obuf_s)/3, + (size_t)ptr->rates_len), ' '), + ptr->rssi, ptr->link_qual, ptr->noise_level); + } + + spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); + } +} + +/* try to find a matching bss in dev->bss, starting at position start. + returns the ptr to a matching bss in the list or + NULL if none found */ +/* last is the last bss tried, last == NULL signals a new round, + starting with list_entry(dev->bss_list.next, ...) */ +/* this proc must be called inside an acquired dev->bss_list_spinlock + otherwise the timeout on bss may remove the newly chosen entry ! */ +static struct bss_info *find_matching_bss(struct at76c503 *dev, + struct bss_info *last) +{ + struct bss_info *ptr = NULL; + struct list_head *curr; + + curr = last != NULL ? last->list.next : dev->bss_list.next; + while (curr != &dev->bss_list) { + ptr = list_entry(curr, struct bss_info, list); + if (essid_matched(dev,ptr) && + mode_matched(dev,ptr) && + wep_matched(dev,ptr) && + rates_matched(dev,ptr) && + bssid_matched(dev,ptr)) + break; + curr = curr->next; + } + + if (curr == &dev->bss_list) + ptr = NULL; + /* otherwise ptr points to the struct bss_info we have chosen */ + + dbg(DBG_BSS_TABLE, "%s %s: returned %p", dev->netdev->name, + __FUNCTION__, ptr); + return ptr; +} /* find_matching_bss */ + + +/* we got an association response */ +static void rx_mgmt_assoc(struct at76c503 *dev, + struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *mgmt = + (struct ieee80211_hdr_3addr *)buf->packet; + struct ieee802_11_assoc_resp *resp = + (struct ieee802_11_assoc_resp *)mgmt->payload; + u16 assoc_id = le16_to_cpu(resp->assoc_id); + u16 status = le16_to_cpu(resp->status); + u16 capa = le16_to_cpu(resp->capability); + dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa x%04x status x%04x " + "assoc_id x%04x rates %s", + dev->netdev->name, mac2str(mgmt->addr3), capa, status, assoc_id, + hex2str(dev->obuf, resp->data+2, + min((size_t)*(resp->data+1),(sizeof(dev->obuf)-1)/2), '\0')); + LOCK_ISTATE() + if (dev->istate == ASSOCIATING) { + UNLOCK_ISTATE() + assert(dev->curr_bss != NULL); + if (dev->curr_bss == NULL) + return; + + if (status == WLAN_STATUS_SUCCESS) { + struct bss_info *ptr = dev->curr_bss; + ptr->assoc_id = assoc_id & 0x3fff; + /* update iwconfig params */ + memcpy(dev->bssid, ptr->bssid, ETH_ALEN); + memcpy(dev->essid, ptr->ssid, ptr->ssid_len); + dev->essid_size = ptr->ssid_len; + dev->channel = ptr->channel; + defer_kevent(dev,KEVENT_ASSOC_DONE); + } else { + NEW_STATE(dev,JOINING); + defer_kevent(dev,KEVENT_JOIN); + } + del_timer_sync(&dev->mgmt_timer); + } else { + UNLOCK_ISTATE() + info("%s: AssocResp in state %d ignored", + dev->netdev->name, dev->istate); + } +} /* rx_mgmt_assoc */ + +static void rx_mgmt_reassoc(struct at76c503 *dev, + struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *mgmt = + (struct ieee80211_hdr_3addr *)buf->packet; + struct ieee802_11_assoc_resp *resp = + (struct ieee802_11_assoc_resp *)mgmt->payload; + unsigned long flags; + u16 capa = le16_to_cpu(resp->capability); + u16 status = le16_to_cpu(resp->status); + u16 assoc_id = le16_to_cpu(resp->assoc_id); + + dbg(DBG_RX_MGMT, "%s: rx ReAssocResp bssid %s capa x%04x status x%04x " + "assoc_id x%04x rates %s", + dev->netdev->name, mac2str(mgmt->addr3), capa, status, assoc_id, + hex2str(dev->obuf, resp->data+2, + min((size_t)*(resp->data+1),(sizeof(dev->obuf)-1)/2), '\0')); + LOCK_ISTATE() + if (dev->istate == REASSOCIATING) { + UNLOCK_ISTATE() + assert(dev->new_bss != NULL); + if (dev->new_bss == NULL) + return; + + if (status == WLAN_STATUS_SUCCESS) { + struct bss_info *bptr = dev->new_bss; + bptr->assoc_id = assoc_id; + NEW_STATE(dev,CONNECTED); + + iwevent_bss_connect(dev->netdev,bptr->bssid); + + spin_lock_irqsave(&dev->bss_list_spinlock, flags); + dev->curr_bss = dev->new_bss; + dev->new_bss = NULL; + spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); + + /* get ESSID, BSSID and channel for dev->curr_bss */ + dev->essid_size = bptr->ssid_len; + memcpy(dev->essid, bptr->ssid, bptr->ssid_len); + memcpy(dev->bssid, bptr->bssid, ETH_ALEN); + dev->channel = bptr->channel; + dbg(DBG_PROGRESS, "%s: reassociated to BSSID %s", + dev->netdev->name, mac2str(dev->bssid)); + defer_kevent(dev, KEVENT_ASSOC_DONE); + } else { + del_timer_sync(&dev->mgmt_timer); + NEW_STATE(dev,JOINING); + defer_kevent(dev,KEVENT_JOIN); + } + } else { + info("%s: ReAssocResp in state %d ignored", + dev->netdev->name, dev->istate); + UNLOCK_ISTATE() + } +} /* rx_mgmt_reassoc */ + +static void rx_mgmt_disassoc(struct at76c503 *dev, + struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *mgmt = + (struct ieee80211_hdr_3addr *)buf->packet; + struct ieee802_11_disassoc_frame *resp = + (struct ieee802_11_disassoc_frame *)mgmt->payload; + + dbg(DBG_RX_MGMT, "%s: rx DisAssoc bssid %s reason x%04x destination %s", + dev->netdev->name, mac2str(mgmt->addr3), + le16_to_cpu(resp->reason), + hex2str(dev->obuf, mgmt->addr1, + min((int)sizeof(dev->obuf)/3, ETH_ALEN), ':')); + LOCK_ISTATE() + if (dev->istate == SCANNING || dev->istate == INIT) { + UNLOCK_ISTATE() + return; + } + UNLOCK_ISTATE() + + assert(dev->curr_bss != NULL); + if (dev->curr_bss == NULL) + return; + LOCK_ISTATE() + if (dev->istate == REASSOCIATING) { + UNLOCK_ISTATE() + assert(dev->new_bss != NULL); + if (dev->new_bss == NULL) + return; + } else + UNLOCK_ISTATE() + if (!memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN) && + (!memcmp(dev->netdev->dev_addr, mgmt->addr1, ETH_ALEN) || + !memcmp(bc_addr, mgmt->addr1, ETH_ALEN))) { + /* this is a DisAssoc from the BSS we are connected or + trying to connect to, directed to us or broadcasted */ + /* jal: TODO: can the DisAssoc also come from the BSS + we've sent a ReAssocReq to (i.e. from dev->new_bss) ? */ + LOCK_ISTATE() + if (dev->istate == DISASSOCIATING || + dev->istate == ASSOCIATING || + dev->istate == REASSOCIATING || + dev->istate == CONNECTED || + dev->istate == JOINING) + { + if (dev->istate == CONNECTED) { + UNLOCK_ISTATE() + netif_carrier_off(dev->netdev); + netif_stop_queue(dev->netdev); + iwevent_bss_disconnect(dev->netdev); + } else UNLOCK_ISTATE() + del_timer_sync(&dev->mgmt_timer); + NEW_STATE(dev,JOINING); + defer_kevent(dev,KEVENT_JOIN); + } else { + + /* ignore DisAssoc in states AUTH, ASSOC */ + info("%s: DisAssoc in state %d ignored", + dev->netdev->name, dev->istate); + UNLOCK_ISTATE() + } + } + /* ignore DisAssoc to other STA or from other BSSID */ +} /* rx_mgmt_disassoc */ + +static void rx_mgmt_auth(struct at76c503 *dev, + struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *mgmt = + (struct ieee80211_hdr_3addr *)buf->packet; + struct ieee802_11_auth_frame *resp = + (struct ieee802_11_auth_frame *)mgmt->payload; + int seq_nr = le16_to_cpu(resp->seq_nr); + int alg = le16_to_cpu(resp->algorithm); + int status = le16_to_cpu(resp->status); + + dbg(DBG_RX_MGMT, "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d " + "destination %s", + dev->netdev->name, mac2str(mgmt->addr3), + alg, seq_nr, status, + hex2str(dev->obuf, mgmt->addr1, + min((int)sizeof(dev->obuf)/3, ETH_ALEN), ':')); + + if (alg == WLAN_AUTH_SHARED_KEY && + seq_nr == 2) { + dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...", + dev->netdev->name, + hex2str(dev->obuf, resp->challenge, + min((int)sizeof(dev->obuf)/3,18), ' ')); + } + LOCK_ISTATE() + if (dev->istate != AUTHENTICATING) { + info("%s: ignored AuthFrame in state %d", + dev->netdev->name, dev->istate); + UNLOCK_ISTATE() + return; + } + UNLOCK_ISTATE() + if (dev->auth_mode != alg) { + info("%s: ignored AuthFrame for alg %d", + dev->netdev->name, alg); + return; + } + + assert(dev->curr_bss != NULL); + if (dev->curr_bss == NULL) + return; + + if (!memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN) && + !memcmp(dev->netdev->dev_addr, mgmt->addr1, ETH_ALEN)) { + /* this is a AuthFrame from the BSS we are connected or + trying to connect to, directed to us */ + if (status != WLAN_STATUS_SUCCESS) { + del_timer_sync(&dev->mgmt_timer); + /* try to join next bss */ + NEW_STATE(dev,JOINING); + defer_kevent(dev,KEVENT_JOIN); + return; + } + + if (dev->auth_mode == WLAN_AUTH_OPEN || + seq_nr == 4) { + dev->retries = ASSOC_RETRIES; + NEW_STATE(dev,ASSOCIATING); + assoc_req(dev, dev->curr_bss); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", + __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer,jiffies+HZ); + return; + } + + assert(seq_nr == 2); + auth_req(dev, dev->curr_bss, seq_nr+1, resp->challenge); + dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", + __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer,jiffies+HZ); + } + /* else: ignore AuthFrames to other recipients */ +} /* rx_mgmt_auth */ + +static void rx_mgmt_deauth(struct at76c503 *dev, + struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *mgmt = + (struct ieee80211_hdr_3addr *)buf->packet; + struct ieee802_11_deauth_frame *resp = + (struct ieee802_11_deauth_frame *)mgmt->payload; + + dbg(DBG_RX_MGMT|DBG_PROGRESS, + "%s: rx DeAuth bssid %s reason x%04x destination %s", + dev->netdev->name, mac2str(mgmt->addr3), + le16_to_cpu(resp->reason), + hex2str(dev->obuf, mgmt->addr1, + min((int)sizeof(dev->obuf)/3,ETH_ALEN), ':')); + LOCK_ISTATE() + if (dev->istate == DISASSOCIATING || + dev->istate == AUTHENTICATING || + dev->istate == ASSOCIATING || + dev->istate == REASSOCIATING || + dev->istate == CONNECTED) { + UNLOCK_ISTATE() + assert(dev->curr_bss != NULL); + if (dev->curr_bss == NULL) + return; + + if (!memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN) && + (!memcmp(dev->netdev->dev_addr, mgmt->addr1, ETH_ALEN) || + !memcmp(bc_addr, mgmt->addr1, ETH_ALEN))) { + /* this is a DeAuth from the BSS we are connected or + trying to connect to, directed to us or broadcasted */ + LOCK_ISTATE() + if (dev->istate == CONNECTED) { + UNLOCK_ISTATE() + iwevent_bss_disconnect(dev->netdev); + } else UNLOCK_ISTATE() + NEW_STATE(dev,JOINING); + defer_kevent(dev,KEVENT_JOIN); + del_timer_sync(&dev->mgmt_timer); + } + /* ignore DeAuth to other STA or from other BSSID */ + } else { + /* ignore DeAuth in states SCANNING */ + info("%s: DeAuth in state %d ignored", + dev->netdev->name, dev->istate); + UNLOCK_ISTATE() + } +} /* rx_mgmt_deauth */ + +static void rx_mgmt_beacon(struct at76c503 *dev, + struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *mgmt = + (struct ieee80211_hdr_3addr *)buf->packet; + + /* beacon content */ + struct ieee802_11_beacon_data *bdata = + (struct ieee802_11_beacon_data *)mgmt->payload; + + /* length of var length beacon parameters */ + int varpar_len = min(le16_to_cpu(buf->wlength) - + (int)(IEEE802_11_MGMT_HEADER_SIZE + + offsetof(struct ieee802_11_beacon_data, data)), + BEACON_MAX_DATA_LENGTH); + + struct list_head *lptr; + struct bss_info *match; /* entry matching addr3 with its bssid */ + int new_entry = 0; + int len; + struct data_element { + u8 type; + u8 length; + u8 data_head; + } *element; + int have_ssid = 0; + int have_rates = 0; + int have_channel = 0; + int keep_going = 1; + unsigned long flags; + + spin_lock_irqsave(&dev->bss_list_spinlock, flags); + LOCK_ISTATE() + if (dev->istate == CONNECTED) { + UNLOCK_ISTATE() + /* in state CONNECTED we use the mgmt_timer to control + the beacon of the BSS */ + assert(dev->curr_bss != NULL); + if (dev->curr_bss == NULL) + goto rx_mgmt_beacon_end; + if (!memcmp(dev->curr_bss->bssid, mgmt->addr3, ETH_ALEN)) { + //dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer " + // "+BEACON_TIMEOUT*HZ", __FUNCTION__, __LINE__); + mod_timer(&dev->mgmt_timer, jiffies+BEACON_TIMEOUT*HZ); + dev->curr_bss->rssi = buf->rssi; + dev->beacons_received++; + goto rx_mgmt_beacon_end; + } + } else + UNLOCK_ISTATE() + + /* look if we have this BSS already in the list */ + match = NULL; + + if (!list_empty(&dev->bss_list)) { + list_for_each(lptr, &dev->bss_list) { + struct bss_info *bss_ptr = + list_entry(lptr, struct bss_info, list); + if (!memcmp(bss_ptr->bssid, mgmt->addr3, ETH_ALEN)) { + match = bss_ptr; + break; + } + } + } + + if (match == NULL) { + /* haven't found the bss in the list */ + if ((match=kmalloc(sizeof(struct bss_info), GFP_ATOMIC)) == NULL) { + dbg(DBG_BSS_TABLE, "%s: cannot kmalloc new bss info (%zd byte)", + dev->netdev->name, sizeof(struct bss_info)); + goto rx_mgmt_beacon_end; + } + memset(match,0,sizeof(*match)); + new_entry = 1; + /* append new struct into list */ + list_add_tail(&match->list, &dev->bss_list); + } + + /* we either overwrite an existing entry or append a new one + match points to the entry in both cases */ + + match->capa = le16_to_cpu(bdata->capability_information); + + /* while beacon_interval is not (!) */ + match->beacon_interval = le16_to_cpu(bdata->beacon_interval); + + match->rssi = buf->rssi; + match->link_qual = buf->link_quality; + match->noise_level = buf->noise_level; + + memcpy(match->mac,mgmt->addr2,ETH_ALEN); //just for info + memcpy(match->bssid,mgmt->addr3,ETH_ALEN); + dbg(DBG_RX_BEACON, "%s: bssid %s", dev->netdev->name, + mac2str(match->bssid)); + + element = (struct data_element*)bdata->data; + +#define data_end(element) (&(element->data_head) + element->length) + + // This routine steps through the bdata->data array to try and get + // some useful information about the access point. + // Currently, this implementation supports receipt of: SSID, + // supported transfer rates and channel, in any order, with some + // tolerance for intermittent unknown codes (although this + // functionality may not be necessary as the useful information will + // usually arrive in consecutively, but there have been some + // reports of some of the useful information fields arriving in a + // different order). + // It does not support any more IE types although MFIE_TYPE_TIM may + // be supported (on my AP at least). + // The bdata->data array is about 1500 bytes long but only ~36 of those + // bytes are useful, hence the have_ssid etc optimizations. + + while (keep_going && + ((int)(data_end(element) - bdata->data) <= varpar_len)) { + + switch (element->type) { + + case MFIE_TYPE_SSID: + len = min(IW_ESSID_MAX_SIZE, (int)element->length); + if (!have_ssid && ((new_entry) || + !is_cloaked_ssid(&(element->data_head), len))) { + /* we copy only if this is a new entry, + or the incoming SSID is not a cloaked SSID. This + will protect us from overwriting a real SSID read + in a ProbeResponse with a cloaked one from a + following beacon. */ + + match->ssid_len = len; + memcpy(match->ssid, &(element->data_head), len); + match->ssid[len] = '\0'; /* terminate the + string for + printing */ + dbg(DBG_RX_BEACON, "%s: SSID - %s", + dev->netdev->name, match->ssid); + } + have_ssid = 1; + break; + + case MFIE_TYPE_RATES: + if (!have_rates) { + match->rates_len = + min((int)sizeof(match->rates), + (int)element->length); + memcpy(match->rates, &(element->data_head), + match->rates_len); + have_rates = 1; + dbg(DBG_RX_BEACON, + "%s: SUPPORTED RATES %s", + dev->netdev->name, + hex2str(dev->obuf, &(element->data_head), + min((sizeof(dev->obuf)-1)/2, + (size_t)element->length), '\0')); + } + break; + + case MFIE_TYPE_DS_SET: + if (!have_channel) { + match->channel = element->data_head; + have_channel = 1; + dbg(DBG_RX_BEACON, "%s: CHANNEL - %d", + dev->netdev->name, match->channel); + } + break; + + case MFIE_TYPE_CF_SET: + case MFIE_TYPE_TIM: + case MFIE_TYPE_IBSS_SET: + default: + { + dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s", + dev->netdev->name, element->type, element->length, + hex2str(dev->obuf,&(element->data_head), + min((sizeof(dev->obuf)-1)/2, + (size_t)element->length),'\0')); + break; + } + + } // switch (element->type) + + // advance to the next 'element' of data + element = (struct data_element*)data_end(element); + + // Optimization: after all, the bdata->data array is + // varpar_len bytes long, whereas we get all of the useful + // information after only ~36 bytes, this saves us a lot of + // time (and trouble as the remaining portion of the array + // could be full of junk) + // Comment this out if you want to see what other information + // comes from the AP - although little of it may be useful + + //if (have_ssid && have_rates && have_channel) + // keep_going = 0; + } + + dbg(DBG_RX_BEACON, "%s: Finished processing beacon data", + dev->netdev->name); + + match->last_rx = jiffies; /* record last rx of beacon */ + +rx_mgmt_beacon_end: + spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); +} /* rx_mgmt_beacon */ + + +/* calc the link level from a given rx_buffer */ +static void calc_level(struct at76c503 *dev, struct at76c503_rx_buffer *buf, struct iw_quality* qual) +{ int max_rssi = 42; /* just a gues for now, might be different for other chips */ + + qual->level = (buf->rssi * 100 / max_rssi); + if (qual->level > 100) + qual->level = 100; + qual->updated |= IW_QUAL_LEVEL_UPDATED; +} + + +/* calc the link quality from a given rx_buffer */ +static void calc_qual(struct at76c503 *dev, struct at76c503_rx_buffer *buf, struct iw_quality* qual) +{ + if((dev->board_type == BOARDTYPE_503_INTERSIL_3861) || + (dev->board_type == BOARDTYPE_503_INTERSIL_3863)) { + qual->qual=buf->link_quality; + } else { + qual->qual = qual->level * dev->beacons_received * + dev->beacon_period / + (jiffies_to_msecs(jiffies) - dev->beacons_last_qual); + + dev->beacons_last_qual = jiffies_to_msecs(jiffies); + dev->beacons_received = 0; + } + qual->qual = (qual->qual > 100) ? 100 : qual->qual; + qual->updated |= IW_QUAL_QUAL_UPDATED; +} + + +/* calc the noise quality from a given rx_buffer */ +static void calc_noise(struct at76c503 *dev, struct at76c503_rx_buffer *buf, struct iw_quality* qual) +{ + qual->noise = 0; + qual->updated |= IW_QUAL_NOISE_INVALID; +} + + +static void update_wstats(struct at76c503 *dev, struct at76c503_rx_buffer *buf) +{ + struct iw_quality *qual = &dev->wstats.qual; + + if (buf->rssi && dev->istate == CONNECTED) { + qual->updated = 0; + calc_level(dev, buf, qual); + calc_qual(dev, buf, qual); + calc_noise(dev, buf, qual); + } else { + qual->qual = 0; + qual->level = 0; + qual->noise = 0; + qual->updated = IW_QUAL_ALL_INVALID; + } +} + +static void rx_mgmt(struct at76c503 *dev, struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *mgmt = + (struct ieee80211_hdr_3addr *)buf->packet; + u16 subtype = le16_to_cpu(mgmt->frame_ctl) & IEEE80211_FCTL_STYPE; + + /* update wstats */ + LOCK_ISTATE() + if (dev->istate != INIT && dev->istate != SCANNING) { + UNLOCK_ISTATE() + /* jal: this is a dirty hack needed by Tim in ad-hoc mode */ + if (dev->iw_mode == IW_MODE_ADHOC || + (dev->curr_bss != NULL && + !memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN))) { + /* Data packets always seem to have a 0 link level, so we + only read link quality info from management packets. + Atmel driver actually averages the present, and previous + values, we just present the raw value at the moment - TJS */ + + update_wstats(dev, buf); + } + } else UNLOCK_ISTATE() + + if (at76_debug & DBG_RX_MGMT_CONTENT) { + dbg_uc("%s rx mgmt subtype x%x %s", + dev->netdev->name, subtype, + hex2str(dev->obuf, (u8 *)mgmt, + min((sizeof(dev->obuf)-1)/2, + (size_t)le16_to_cpu(buf->wlength)), '\0')); + } + + switch (subtype) { + case IEEE80211_STYPE_BEACON: + case IEEE80211_STYPE_PROBE_RESP: + rx_mgmt_beacon(dev,buf); + break; + + case IEEE80211_STYPE_ASSOC_RESP: + rx_mgmt_assoc(dev,buf); + break; + + case IEEE80211_STYPE_REASSOC_RESP: + rx_mgmt_reassoc(dev,buf); + break; + + case IEEE80211_STYPE_DISASSOC: + rx_mgmt_disassoc(dev,buf); + break; + + case IEEE80211_STYPE_AUTH: + rx_mgmt_auth(dev,buf); + break; + + case IEEE80211_STYPE_DEAUTH: + rx_mgmt_deauth(dev,buf); + break; + + default: + info("%s: mgmt, but not beacon, subtype = %x", + dev->netdev->name, subtype); + } + + return; +} + +static void dbg_dumpbuf(const char *tag, const u8 *buf, int size) +{ + int i; + + if (!at76_debug) return; + + for (i=0; i <-- 6 --> <-- 2 --> <-46-1500-> + + Type 0x80 0x00 = TCP/IP + Type 0x06 0x00 = XNS + Type 0x81 0x37 = Novell NetWare + + +802.3 + + +---------+---------+---------+---------- + | Dst | Src | Length | Data... + +---------+---------+---------+---------- + + <-- 6 --> <-- 6 --> <-- 2 --> <-46-1500-> + +802.2 (802.3 with 802.2 header) + + +---------+---------+---------+-------+-------+-------+---------- + | Dst | Src | Length | DSAP | SSAP |Control| Data... + +---------+---------+---------+-------+-------+-------+---------- + + <- 1 -> <- 1 -> <- 1 -> <-43-1497-> + +SNAP (802.3 with 802.2 and SNAP headers) + + +---------+---------+---------+-------+-------+-------+-----------+---------+----------- + | Dst | Src | Length | 0xAA | 0xAA | 0x03 | Org Code | Type | Data... + +---------+---------+---------+-------+-------+-------+-----------+---------+----------- + + <-- 3 --> <-- 2 --> <-38-1492-> + +*/ + +/* Convert the 802.11 header on a packet into an ethernet-style header + * (basically, pretend we're an ethernet card receiving ethernet packets) + * + * This routine returns with the skbuff pointing to the actual data (just past + * the end of the newly-created ethernet header). + */ +static void ieee80211_to_eth(struct sk_buff *skb, int iw_mode) +{ + struct ieee80211_hdr_3addr *i802_11_hdr; + struct ethhdr *eth_hdr_p; + u8 *src_addr; + u8 *dest_addr; + __be16 proto = 0; + int build_ethhdr = 1; + + i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; + +#ifdef DEBUG + { + dbg_uc("%s: ENTRY skb len %d data %s", __FUNCTION__, + skb->len, hex2str(dev->obuf, skb->data, + min((int)sizeof(dev->obuf)/3,64), ' ')); + } +#endif + + skb_pull(skb, sizeof(struct ieee80211_hdr_3addr)); +// skb_trim(skb, skb->len - 4); /* Trim CRC */ + + src_addr = iw_mode == IW_MODE_ADHOC ? i802_11_hdr->addr2 + : i802_11_hdr->addr3; + dest_addr = i802_11_hdr->addr1; + + eth_hdr_p = (struct ethhdr *)skb->data; + if (!memcmp(eth_hdr_p->h_source, src_addr, ETH_ALEN) && + !memcmp(eth_hdr_p->h_dest, dest_addr, ETH_ALEN)) { + /* An ethernet frame is encapsulated within the data portion. + * Just use its header instead. */ + skb_pull(skb, sizeof(struct ethhdr)); + build_ethhdr = 0; + } else if (!memcmp(skb->data, snapsig, sizeof(snapsig))) { + /* SNAP frame - collapse it */ + skb_pull(skb, sizeof(rfc1042sig)+2); + proto = *(__be16 *)(skb->data - 2); + } else { +#ifdef IEEE_STANDARD + /* According to all standards, we should assume the data + * portion contains 802.2 LLC information, so we should give it + * an 802.3 header (which has the same implications) */ + proto = htons(skb->len); +#else /* IEEE_STANDARD */ + /* Unfortunately, it appears no actual 802.11 implementations + * follow any standards specs. They all appear to put a + * 16-bit ethertype after the 802.11 header instead, so we take + * that value and make it into an Ethernet-II packet. */ + /* Note that this means we can never support non-SNAP 802.2 + * frames (because we can't tell when we get one) */ + + /* jal: This isn't true. My WRT54G happily sends SNAP. + Difficult to speak for all APs, so I don't dare to define + IEEE_STANDARD ... */ + proto = *(__be16 *)(skb->data); + skb_pull(skb, 2); +#endif /* IEEE_STANDARD */ + } + + skb_reset_mac_header(skb); + eth_hdr_p = eth_hdr(skb); + if (build_ethhdr) { + /* This needs to be done in this order (eth_hdr_p->h_dest may + * overlap src_addr) */ + memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN); + memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN); + /* make an 802.3 header (proto = length) */ + eth_hdr_p->h_proto = proto; + } + + if (ntohs(eth_hdr_p->h_proto) > 1518) { + skb->protocol = eth_hdr_p->h_proto; + } else if (*(unsigned short *)skb->data == 0xFFFF) { + /* Magic hack for Novell IPX-in-802.3 packets */ + skb->protocol = htons(ETH_P_802_3); + } else { + /* Assume it's an 802.2 packet (it should be, and we have no + * good way to tell if it isn't) */ + skb->protocol = htons(ETH_P_802_2); + } + +#ifdef DEBUG + { + char da[3*ETH_ALEN], sa[3*ETH_ALEN]; + dbg_uc("%s: EXIT skb da %s sa %s proto x%04x len %d data %s", __FUNCTION__, + hex2str(da, eth_hdr(skb)->h_dest, ETH_ALEN, ':'), + hex2str(sa, eth_hdr(skb)->h_source, ETH_ALEN, ':'), + ntohs(skb->protocol), skb->len, + hex2str(dev->obuf, skb->data, + min((int)sizeof(dev->obuf)/3,64), ' ')); + } +#endif + +} + +/* Adjust the skb to trim the hardware header and CRC, and set up skb->mac, + * skb->protocol, etc. + */ +static void ieee80211_fixup(struct sk_buff *skb, int iw_mode) +{ + struct ieee80211_hdr_3addr *i802_11_hdr; + struct ethhdr *eth_hdr_p; + u8 *src_addr; + u8 *dest_addr; + __be16 proto = 0; + + i802_11_hdr = (struct ieee80211_hdr_3addr *)eth_hdr(skb); + skb_pull(skb, sizeof(struct ieee80211_hdr_3addr)); +// skb_trim(skb, skb->len - 4); /* Trim CRC */ + + src_addr = iw_mode == IW_MODE_ADHOC ? i802_11_hdr->addr2 + : i802_11_hdr->addr3; + dest_addr = i802_11_hdr->addr1; + + skb_reset_mac_header(skb); + eth_hdr_p = eth_hdr(skb); + if (!memcmp(eth_hdr_p->h_source, src_addr, ETH_ALEN) && + !memcmp(eth_hdr_p->h_dest, dest_addr, ETH_ALEN)) { + /* There's an ethernet header encapsulated within the data + * portion, count it as part of the hardware header */ + skb_pull(skb, sizeof(struct ethhdr)); + proto = eth_hdr_p->h_proto; + } else if (!memcmp(skb->data, snapsig, sizeof(snapsig))) { + /* SNAP frame - collapse it */ + /* RFC1042/802.1h encapsulated packet. Treat the SNAP header + * as part of the HW header and note the protocol. */ + /* NOTE: prism2 doesn't collapse Appletalk frames (why?). */ + skb_pull(skb, sizeof(rfc1042sig) + 2); + proto = *(__be16 *)(skb->data - 2); + } + + if (ntohs(proto) > 1518) { + skb->protocol = proto; + } else { +#ifdef IEEE_STANDARD + /* According to all standards, we should assume the data + * portion contains 802.2 LLC information */ + skb->protocol = htons(ETH_P_802_2); +#else /* IEEE_STANDARD */ + /* Unfortunately, it appears no actual 802.11 implementations + * follow any standards specs. They all appear to put a + * 16-bit ethertype after the 802.11 header instead, so we'll + * use that (and consider it part of the hardware header). */ + /* Note that this means we can never support non-SNAP 802.2 + * frames (because we can't tell when we get one) */ + skb->protocol = *(__be16 *)skb->data; + skb_pull(skb, 2); +#endif /* IEEE_STANDARD */ + } +} + +/* check for fragmented data in dev->rx_skb. If the packet was no fragment + or it was the last of a fragment set a skb containing the whole packet + is returned for further processing. Otherwise we get NULL and are + done and the packet is either stored inside the fragment buffer + or thrown away. The check for rx_copybreak is moved here. + Every returned skb starts with the ieee802_11 header and contains + _no_ FCS at the end */ +static struct sk_buff *check_for_rx_frags(struct at76c503 *dev) +{ + struct sk_buff *skb = (struct sk_buff *)dev->rx_skb; + struct at76c503_rx_buffer *buf = (struct at76c503_rx_buffer *)skb->data; + struct ieee80211_hdr_3addr *i802_11_hdr = + (struct ieee80211_hdr_3addr *)buf->packet; + /* seq_ctrl, fragment_number, sequence number of new packet */ + u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl); + u16 fragnr = sctl & 0xf; + u16 seqnr = sctl>>4; + u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); + + /* length including the IEEE802.11 header, excl. the trailing FCS, + excl. the struct at76c503_rx_buffer */ + int length = le16_to_cpu(buf->wlength) - dev->rx_data_fcs_len; + + /* where does the data payload start in skb->data ? */ + u8 *data = (u8 *)i802_11_hdr + sizeof(struct ieee80211_hdr_3addr); + + /* length of payload, excl. the trailing FCS */ + int data_len = length - (data - (u8 *)i802_11_hdr); + + int i; + struct rx_data_buf *bptr, *optr; + unsigned long oldest = ~0UL; + + dbg(DBG_RX_FRAGS, "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d " + "length %d data %d: %s ...", + dev->netdev->name, frame_ctl, + mac2str(i802_11_hdr->addr2), + seqnr, fragnr, length, data_len, + hex2str(dev->obuf, data, + min((int)(sizeof(dev->obuf)-1)/2,32), '\0')); + + dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p " + "tail %lu end %lu len %d", + dev->netdev->name, skb->head, skb->data, (unsigned long)skb->tail, + (unsigned long)skb->end, skb->len); + + if (data_len <= 0) { + /* buffers contains no data */ + info("%s: rx skb without data", dev->netdev->name); + return NULL; + } + + if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { + /* unfragmented packet received */ + if (length < rx_copybreak && (skb = dev_alloc_skb(length)) != NULL) { + memcpy(skb_put(skb, length), + dev->rx_skb->data + AT76C503_RX_HDRLEN, length); + } else { + skb_pull(skb, AT76C503_RX_HDRLEN); + skb_trim(skb, length); + /* Use a new skb for the next receive */ + dev->rx_skb = NULL; + } + + dbg(DBG_RX_FRAGS, "%s: unfragmented", dev->netdev->name); + + return skb; + } + + /* remove the at76c503_rx_buffer header - we don't need it anymore */ + /* we need the IEEE802.11 header (for the addresses) if this packet + is the first of a chain */ + + assert(length > AT76C503_RX_HDRLEN); + skb_pull(skb, AT76C503_RX_HDRLEN); + /* remove FCS at end */ + skb_trim(skb, length); + + dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %lu " + "end %lu len %d data %p data_len %d", + dev->netdev->name, skb->head, skb->data, (unsigned long)skb->tail, + (unsigned long)skb->end, skb->len, data, data_len); + + /* look if we've got a chain for the sender address. + afterwards optr points to first free or the oldest entry, + or, if i < NR_RX_DATA_BUF, bptr points to the entry for the + sender address */ + /* determining the oldest entry doesn't cope with jiffies wrapping + but I don't care to delete a young entry at these rare moments ... */ + + for(i=0,bptr=dev->rx_data,optr=NULL; i < NR_RX_DATA_BUF; i++,bptr++) { + if (bptr->skb != NULL) { + if (!memcmp(i802_11_hdr->addr2, bptr->sender,ETH_ALEN)) + break; + else + if (optr == NULL) { + optr = bptr; + oldest = bptr->last_rx; + } else { + if (bptr->last_rx < oldest) + optr = bptr; + } + } else { + optr = bptr; + oldest = 0UL; + } + } + + if (i < NR_RX_DATA_BUF) { + + dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag=%d/%d) " + "matched sender addr", + dev->netdev->name, i, bptr->seqnr, bptr->fragnr); + + /* bptr points to an entry for the sender address */ + if (bptr->seqnr == seqnr) { + int left; + /* the fragment has the current sequence number */ + if (((bptr->fragnr+1)&0xf) == fragnr) { + bptr->last_rx = jiffies; + /* the next following fragment number -> + add the data at the end */ + /* is & 0xf necessary above ??? */ + + // for test only ??? + if ((left=skb_tailroom(bptr->skb)) < data_len) { + info("%s: only %d byte free (need %d)", + dev->netdev->name, left, data_len); + } else + memcpy(skb_put(bptr->skb, data_len), + data, data_len); + bptr->fragnr = fragnr; + if (!(frame_ctl & + IEEE80211_FCTL_MOREFRAGS)) { + /* this was the last fragment - send it */ + skb = bptr->skb; + bptr->skb = NULL; /* free the entry */ + dbg(DBG_RX_FRAGS, "%s: last frag of seq %d", + dev->netdev->name, seqnr); + return skb; + } else + return NULL; + } else { + /* wrong fragment number -> ignore it */ + dbg(DBG_RX_FRAGS, "%s: frag nr does not match: %d+1 != %d", + dev->netdev->name, bptr->fragnr, fragnr); + return NULL; + } + } else { + /* got another sequence number */ + if (fragnr == 0) { + /* it's the start of a new chain - replace the + old one by this */ + /* bptr->sender has the correct value already */ + dbg(DBG_RX_FRAGS, "%s: start of new seq %d, " + "removing old seq %d", dev->netdev->name, + seqnr, bptr->seqnr); + bptr->seqnr = seqnr; + bptr->fragnr = 0; + bptr->last_rx = jiffies; + /* swap bptr->skb and dev->rx_skb */ + skb = bptr->skb; + bptr->skb = dev->rx_skb; + dev->rx_skb = skb; + } else { + /* it from the middle of a new chain -> + delete the old entry and skip the new one */ + dbg(DBG_RX_FRAGS, "%s: middle of new seq %d (%d) " + "removing old seq %d", dev->netdev->name, + seqnr, fragnr, bptr->seqnr); + dev_kfree_skb(bptr->skb); + bptr->skb = NULL; + } + return NULL; + } + } else { + /* if we didn't find a chain for the sender address optr + points either to the first free or the oldest entry */ + + if (fragnr != 0) { + /* this is not the begin of a fragment chain ... */ + dbg(DBG_RX_FRAGS, "%s: no chain for non-first fragment (%d)", + dev->netdev->name, fragnr); + return NULL; + } + assert(optr != NULL); + if (optr == NULL) + return NULL; + + if (optr->skb != NULL) { + /* swap the skb's */ + skb = optr->skb; + optr->skb = dev->rx_skb; + dev->rx_skb = skb; + + dbg(DBG_RX_FRAGS, "%s: free old contents: sender %s seq/frag %d/%d", + dev->netdev->name, mac2str(optr->sender), + optr->seqnr, optr->fragnr); + + } else { + /* take the skb from dev->rx_skb */ + optr->skb = dev->rx_skb; + dev->rx_skb = NULL; /* let submit_rx_urb() allocate a new skb */ + + dbg(DBG_RX_FRAGS, "%s: use a free entry", dev->netdev->name); + } + memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN); + optr->seqnr = seqnr; + optr->fragnr = 0; + optr->last_rx = jiffies; + + return NULL; + } +} /* check_for_rx_frags */ + +/* rx interrupt: we expect the complete data buffer in dev->rx_skb */ +static void rx_data(struct at76c503 *dev) +{ + struct net_device *netdev = (struct net_device *)dev->netdev; + struct net_device_stats *stats = &dev->stats; + struct sk_buff *skb = dev->rx_skb; + struct at76c503_rx_buffer *buf = (struct at76c503_rx_buffer *)skb->data; + struct ieee80211_hdr_3addr *i802_11_hdr; + int length = le16_to_cpu(buf->wlength); + + if (at76_debug & DBG_RX_DATA) { + dbg_uc("%s received data packet:", netdev->name); + dbg_dumpbuf(" rxhdr", skb->data, AT76C503_RX_HDRLEN); + } + if (at76_debug & DBG_RX_DATA_CONTENT) + dbg_dumpbuf("packet", skb->data + AT76C503_RX_HDRLEN, + length); + + if ((skb=check_for_rx_frags(dev)) == NULL) + return; + + /* if an skb is returned, the at76c503a_rx_header and the FCS is already removed */ + i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data; + + skb->dev = netdev; + skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */ + + if (i802_11_hdr->addr1[0] & 1) { + if (!memcmp(i802_11_hdr->addr1, netdev->broadcast, ETH_ALEN)) + skb->pkt_type = PACKET_BROADCAST; + else + skb->pkt_type = PACKET_MULTICAST; + } else if (memcmp(i802_11_hdr->addr1, netdev->dev_addr, ETH_ALEN)) { + skb->pkt_type=PACKET_OTHERHOST; + } + + if (netdev->type == ARPHRD_ETHER) { + ieee80211_to_eth(skb, dev->iw_mode); + } else { + ieee80211_fixup(skb, dev->iw_mode); + } + + netdev->last_rx = jiffies; + netif_rx(skb); + stats->rx_packets++; + stats->rx_bytes += length; + + return; +} + +static int submit_rx_urb(struct at76c503 *dev) +{ + int ret, size; + struct sk_buff *skb = dev->rx_skb; + + if (dev->read_urb == NULL) { + err("%s: dev->read_urb is NULL", __FUNCTION__); + return -EFAULT; + } + + if (skb == NULL) { + skb = dev_alloc_skb(sizeof(struct at76c503_rx_buffer)); + if (skb == NULL) { + err("%s: unable to allocate rx skbuff.", dev->netdev->name); + ret = -ENOMEM; + goto exit; + } + dev->rx_skb = skb; + } else { + skb_push(skb, skb_headroom(skb)); + skb_trim(skb, 0); + } + + size = skb_tailroom(skb); + FILL_BULK_URB(dev->read_urb, dev->udev, + usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr), + skb_put(skb, size), size, + (usb_complete_t)at76c503_read_bulk_callback, dev); + ret = usb_submit_urb(dev->read_urb, GFP_ATOMIC); + if (ret < 0) { + if (ret == -ENODEV) + dbg(DBG_DEVSTART, "usb_submit_urb returned -ENODEV"); + else + err("%s: rx, usb_submit_urb failed: %d", dev->netdev->name, ret); + } + +exit: + if (ret < 0) { + if (ret != -ENODEV) { + /* If we can't submit the URB, the adapter becomes completely + * useless, so try again later */ + if (--dev->nr_submit_rx_tries > 0) + defer_kevent(dev, KEVENT_SUBMIT_RX); + else { + err("%s: giving up to submit rx urb after %d failures -" + " please unload the driver and/or power cycle the device", + dev->netdev->name, NR_SUBMIT_RX_TRIES); + } + } + } else + /* reset counter to initial value */ + dev->nr_submit_rx_tries = NR_SUBMIT_RX_TRIES; + return ret; +} + + +/* we are doing a lot of things here in an interrupt. Need + a bh handler (Watching TV with a TV card is probably + a good test: if you see flickers, we are doing too much. + Currently I do see flickers... even with our tasklet :-( ) + Maybe because the bttv driver and usb-uhci use the same interrupt +*/ +/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't + * solve everything.. (alex) */ +static void at76c503_read_bulk_callback (struct urb *urb) +{ + struct at76c503 *dev = (struct at76c503 *)urb->context; + + dev->rx_urb = urb; + tasklet_schedule(&dev->tasklet); + + return; +} + +static void rx_monitor_mode(struct at76c503 *dev) +{ + struct net_device *netdev = (struct net_device *)dev->netdev; + struct at76c503_rx_buffer *buf = + (struct at76c503_rx_buffer *)dev->rx_skb->data; + /* length including the IEEE802.11 header, excl. the trailing FCS, + excl. the struct at76c503_rx_buffer */ + int length = le16_to_cpu(buf->wlength) - dev->rx_data_fcs_len; + struct sk_buff *skb = dev->rx_skb; + struct net_device_stats *stats = &dev->stats; + struct iw_statistics *wstats = &dev->wstats; + + update_wstats(dev, buf); + + if (length < 0) { + /* buffer contains no data */ + dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE: rx skb without data", + dev->netdev->name); + return; + } + + if (netdev->type == ARPHRD_IEEE80211_PRISM) { + int skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + length; + p80211msg_lnxind_wlansniffrm_t *prism; + u8* payload; + + if ((skb = dev_alloc_skb(skblen)) == NULL) { + err("%s: MONITOR MODE: dev_alloc_skb for Prism header " + "returned NULL", dev->netdev->name); + return; + } + + skb_put(skb, skblen); + + prism = (p80211msg_lnxind_wlansniffrm_t*)skb->data; + payload = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t); + + prism->msgcode = DIDmsg_lnxind_wlansniffrm; + prism->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t); + strcpy(prism->devname, netdev->name); + + prism->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; + prism->hosttime.status = 0; + prism->hosttime.len = 4; + prism->hosttime.data = jiffies; + + prism->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; + prism->mactime.status = 0; + prism->mactime.len = 4; + memcpy(&prism->mactime.data, buf->rx_time, 4); + + prism->channel.did = DIDmsg_lnxind_wlansniffrm_channel; + prism->channel.status = P80211ENUM_msgitem_status_no_value; + prism->channel.len = 4; + /* INFO: The channel is encoded in the beacon info. + (Kismet can figure it out, so less processing here) */ + prism->channel.data = 0; + + prism->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; + prism->rssi.status = 0; + prism->rssi.len = 4; + prism->rssi.data = buf->rssi; + + prism->sq.did = DIDmsg_lnxind_wlansniffrm_sq; + prism->sq.status = 0; + prism->sq.len = 4; + prism->sq.data = wstats->qual.qual; + + prism->signal.did = DIDmsg_lnxind_wlansniffrm_signal; + prism->signal.status = 0; + prism->signal.len = 4; + prism->signal.data = wstats->qual.level; + + prism->noise.did = DIDmsg_lnxind_wlansniffrm_noise; + prism->noise.status = 0; + prism->noise.len = 4; + prism->noise.data = wstats->qual.noise; + + prism->rate.did = DIDmsg_lnxind_wlansniffrm_rate; + prism->rate.status = 0; + prism->rate.len = 4; + prism->rate.data = hw_rates[buf->rx_rate] & (~0x80); + + prism->istx.did = DIDmsg_lnxind_wlansniffrm_istx; + prism->istx.status = 0; + prism->istx.len = 4; + prism->istx.data = P80211ENUM_truth_false; + + prism->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; + prism->frmlen.status = 0; + prism->frmlen.len = 4; + prism->frmlen.data = length; + + memcpy(payload, buf->packet, length); + } else { + /* netdev->type != ARPHRD_IEEE80211_PRISM */ + skb_pull(skb, AT76C503_RX_HDRLEN); + skb_trim(skb, length); + dev->rx_skb = NULL; + } + + skb->dev = netdev; + skb->ip_summed = CHECKSUM_NONE; + skb_reset_mac_header(skb); + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_80211_RAW); + + netdev->last_rx = jiffies; + netif_rx(skb); + stats->rx_packets++; + stats->rx_bytes += length; +} /* end of rx_monitor_mode */ + + +static void rx_tasklet(unsigned long param) +{ + struct at76c503 *dev = (struct at76c503 *)param; + struct urb *urb; + struct net_device *netdev; + struct at76c503_rx_buffer *buf; + struct ieee80211_hdr_3addr *i802_11_hdr; + u16 frame_ctl; + + if (!dev) return; + urb = dev->rx_urb; + netdev = (struct net_device *)dev->netdev; + + if (dev->device_unplugged) { + dbg(DBG_DEVSTART, "device unplugged"); + if (urb) + dbg(DBG_DEVSTART, "urb status %d", urb->status); + return; + } + + + if(!urb || !dev->rx_skb || !netdev || !dev->rx_skb->data) return; + + buf = (struct at76c503_rx_buffer *)dev->rx_skb->data; + + if (!buf) return; + + i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet; + if (!i802_11_hdr) return; + + frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl); + + if(urb->status != 0){ + if ((urb->status != -ENOENT) && + (urb->status != -ECONNRESET)) { + dbg(DBG_URB,"%s %s: - nonzero read bulk status received: %d", + __FUNCTION__, netdev->name, urb->status); + goto no_more_urb; + } + return; + } + + if (at76_debug & DBG_RX_ATMEL_HDR) { + dbg_uc("%s: rx frame: rate %d rssi %d noise %d link %d %s", + dev->netdev->name, + buf->rx_rate, buf->rssi, buf->noise_level, + buf->link_quality, + hex2str(dev->obuf,(u8 *)i802_11_hdr, + min((int)(sizeof(dev->obuf)-1)/2,48),'\0')); + } + LOCK_ISTATE() + if (dev->istate == MONITORING) { + UNLOCK_ISTATE() + rx_monitor_mode(dev); + goto finish; + } + UNLOCK_ISTATE() + + /* there is a new bssid around, accept it: */ + if(buf->newbss && dev->iw_mode == IW_MODE_ADHOC) { + dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name); + defer_kevent(dev, KEVENT_NEW_BSS); + } + + switch (frame_ctl & IEEE80211_FCTL_FTYPE) { + case IEEE80211_FTYPE_DATA: + rx_data(dev); + break; + + case IEEE80211_FTYPE_MGMT: + /* jal: TODO: find out if we can update iwspy also on + other frames than management (might depend on the + radio chip / firmware version !) */ + + iwspy_update(dev, buf); + + rx_mgmt(dev, buf); + break; + + case IEEE80211_FTYPE_CTL: + dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x", dev->netdev->name, + frame_ctl); + break; + + default: + info("%s: it's a frame from mars: %2x", dev->netdev->name, + frame_ctl); + } /* switch (frame_ctl & IEEE80211_FCTL_FTYPE) */ +finish: + submit_rx_urb(dev); + no_more_urb: + return; +} + +static void at76c503_write_bulk_callback (struct urb *urb) +{ + struct at76c503 *dev = (struct at76c503 *)urb->context; + struct net_device_stats *stats = &dev->stats; + unsigned long flags; + struct at76c503_tx_buffer *mgmt_buf; + int ret; + + if(urb->status != 0){ + if((urb->status != -ENOENT) && + (urb->status != -ECONNRESET)) { + dbg(DBG_URB, "%s - nonzero write bulk status received: %d", + __FUNCTION__, urb->status); + }else + return; /* urb has been unlinked */ + stats->tx_errors++; + }else + stats->tx_packets++; + + spin_lock_irqsave(&dev->mgmt_spinlock, flags); + mgmt_buf = dev->next_mgmt_bulk; + dev->next_mgmt_bulk = NULL; + spin_unlock_irqrestore(&dev->mgmt_spinlock, flags); + + if (mgmt_buf) { + /* we don't copy the padding bytes, but add them + to the length */ + memcpy(dev->bulk_out_buffer, mgmt_buf, + le16_to_cpu(mgmt_buf->wlength) + + offsetof(struct at76c503_tx_buffer,packet)); + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, + dev->bulk_out_endpointAddr), + dev->bulk_out_buffer, + le16_to_cpu(mgmt_buf->wlength) + + mgmt_buf->padding + AT76C503_TX_HDRLEN, + (usb_complete_t)at76c503_write_bulk_callback, dev); + ret = usb_submit_urb(dev->write_urb, GFP_ATOMIC); + if (ret) { + err("%s: %s error in tx submit urb: %d", + dev->netdev->name, __FUNCTION__, ret); + } + kfree(mgmt_buf); + } else + netif_wake_queue(dev->netdev); + +} + +#ifdef CONFIG_IPAQ_HANDHELD + +static struct timer_list led_timer; + +static void +ipaq_clear_led (unsigned long time) +{ + ipaq_led_off (RED_LED_2); +} + +static void +ipaq_blink_led (void) +{ + ipaq_led_on (RED_LED_2); + + mod_timer (&led_timer, jiffies + (HZ / 25)); +} + +static void +ipaq_init_led (void) +{ + led_timer.function = ipaq_clear_led; + + init_timer (&led_timer); +} + +#endif + +static int at76c503_tx(struct sk_buff *skb, struct net_device *netdev) +{ + struct at76c503 *dev = (struct at76c503 *)(netdev->priv); + struct net_device_stats *stats = &dev->stats; + int ret = 0; + int wlen; + int submit_len; + struct at76c503_tx_buffer *tx_buffer = + (struct at76c503_tx_buffer *)dev->bulk_out_buffer; + struct ieee80211_hdr_3addr *i802_11_hdr = + (struct ieee80211_hdr_3addr *)&(tx_buffer->packet); + u8 *payload = tx_buffer->packet + sizeof(struct ieee80211_hdr_3addr); + + if (netif_queue_stopped(netdev)) { + err("%s: %s called while netdev is stopped", netdev->name, + __FUNCTION__); + //skip this packet + dev_kfree_skb(skb); + return 0; + } + + if (dev->write_urb->status == -EINPROGRESS) { + err("%s: %s called while dev->write_urb is pending for tx", + netdev->name, __FUNCTION__); + //skip this packet + dev_kfree_skb(skb); + return 0; + } + + if (skb->len < 2*ETH_ALEN) { + err("%s: %s: skb too short (%d)", dev->netdev->name, + __FUNCTION__, skb->len); + dev_kfree_skb(skb); + return 0; + } + +#ifdef CONFIG_IPAQ_HANDHELD + if (machine_is_h5400 ()) + ipaq_blink_led (); +#endif + + /* we can get rid of memcpy, if we set netdev->hard_header_len + to 8 + sizeof(struct ieee80211_hdr_3addr), because then we have + enough space */ + // dbg(DBG_TX, "skb->data - skb->head = %d", skb->data - skb->head); + + if (ntohs(*(__be16 *)(skb->data + 2*ETH_ALEN)) <= 1518) { + /* this is a 802.3 packet */ + if (skb->data[2*ETH_ALEN+2] == rfc1042sig[0] && + skb->data[2*ETH_ALEN+2+1] == rfc1042sig[1]) { + /* higher layer delivered SNAP header - keep it */ + memcpy(payload, skb->data + 2*ETH_ALEN+2, skb->len - 2*ETH_ALEN -2); + wlen = sizeof(struct ieee80211_hdr_3addr) + skb->len - 2*ETH_ALEN -2; + } else { + err("%s: %s: no support for non-SNAP 802.2 packets " + "(DSAP x%02x SSAP x%02x cntrl x%02x)", + dev->netdev->name, __FUNCTION__, + skb->data[2*ETH_ALEN+2], skb->data[2*ETH_ALEN+2+1], + skb->data[2*ETH_ALEN+2+2]); + dev_kfree_skb(skb); + return 0; + } + } else { + /* add RFC 1042 header in front */ + memcpy(payload, rfc1042sig, sizeof(rfc1042sig)); + memcpy(payload + sizeof(rfc1042sig), + skb->data + 2*ETH_ALEN, skb->len - 2*ETH_ALEN); + wlen = sizeof(struct ieee80211_hdr_3addr) + sizeof(rfc1042sig) + + skb->len - 2*ETH_ALEN; + } + + /* make wireless header */ + i802_11_hdr->frame_ctl = + cpu_to_le16(IEEE80211_FTYPE_DATA | + (dev->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) | + (dev->iw_mode == IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0)); + + if(dev->iw_mode == IW_MODE_ADHOC){ + memcpy(i802_11_hdr->addr1, skb->data, ETH_ALEN); /* destination */ + memcpy(i802_11_hdr->addr2, skb->data+ETH_ALEN, ETH_ALEN); /* source */ + memcpy(i802_11_hdr->addr3, dev->bssid, ETH_ALEN); + }else if(dev->iw_mode == IW_MODE_INFRA){ + memcpy(i802_11_hdr->addr1, dev->bssid, ETH_ALEN); + memcpy(i802_11_hdr->addr2, skb->data+ETH_ALEN, ETH_ALEN); /* source */ + memcpy(i802_11_hdr->addr3, skb->data, ETH_ALEN); /* destination */ + } + + i802_11_hdr->duration_id = cpu_to_le16(0); + i802_11_hdr->seq_ctl = cpu_to_le16(0); + + /* setup 'Atmel' header */ + tx_buffer->wlength = cpu_to_le16(wlen); + tx_buffer->tx_rate = dev->txrate; + /* for broadcast destination addresses, the firmware 0.100.x + seems to choose the highest rate set with CMD_STARTUP in + basic_rate_set replacing this value */ + + memset(tx_buffer->reserved, 0, 4); + + tx_buffer->padding = calc_padding(wlen); + submit_len = wlen + AT76C503_TX_HDRLEN + tx_buffer->padding; + + { + dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", dev->netdev->name, + hex2str(dev->obuf, skb->data, + min((int)(sizeof(dev->obuf)-1)/2,32),'\0')); + dbg(DBG_TX_DATA, "%s tx wlen x%x pad x%x rate %d hdr %s", + dev->netdev->name, + le16_to_cpu(tx_buffer->wlength), + tx_buffer->padding, tx_buffer->tx_rate, + hex2str(dev->obuf, (u8 *)i802_11_hdr, + min((sizeof(dev->obuf)-1)/2, + sizeof(struct ieee80211_hdr_3addr)),'\0')); + dbg(DBG_TX_DATA_CONTENT, "%s payload %s", dev->netdev->name, + hex2str(dev->obuf, payload, + min((int)(sizeof(dev->obuf)-1)/2,48),'\0')); + } + + /* send stuff */ + netif_stop_queue(netdev); + netdev->trans_start = jiffies; + + FILL_BULK_URB(dev->write_urb, dev->udev, + usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), + tx_buffer, submit_len, + (usb_complete_t)at76c503_write_bulk_callback, dev); + ret = usb_submit_urb(dev->write_urb, GFP_ATOMIC); + if(ret){ + stats->tx_errors++; + err("%s: error in tx submit urb: %d", netdev->name, ret); + if (ret == -EINVAL) + err("-EINVAL: urb %p urb->hcpriv %p urb->complete %p", + dev->write_urb, + dev->write_urb ? dev->write_urb->hcpriv : (void *)-1, + dev->write_urb ? dev->write_urb->complete : (void *)-1); + goto err; + } + + stats->tx_bytes += skb->len; + + dev_kfree_skb(skb); + return 0; + + err: + return ret; +} + + +static void at76c503_tx_timeout(struct net_device *netdev) +{ + struct at76c503 *dev = (struct at76c503 *)(netdev->priv); + + if (!dev) + return; + warn("%s: tx timeout.", netdev->name); +#if WIRELESS_EXT < 17 + dev->write_urb->transfer_flags |= USB_ASYNC_UNLINK; +#endif + usb_unlink_urb(dev->write_urb); + dev->stats.tx_errors++; +} + +static int startup_device(struct at76c503 *dev) +{ + struct at76c503_card_config *ccfg = &dev->card_config; + int ret; + + if (at76_debug & DBG_PARAMS) { + char ossid[IW_ESSID_MAX_SIZE+1]; + + /* make dev->essid printable */ + assert(dev->essid_size <= IW_ESSID_MAX_SIZE); + memcpy(ossid, dev->essid, dev->essid_size); + ossid[dev->essid_size] = '\0'; + + dbg_uc("%s param: ssid %s (%s) mode %s ch %d wep %s key %d keylen %d", + dev->netdev->name, ossid, + hex2str(dev->obuf, dev->essid, + min((int)(sizeof(dev->obuf)-1)/2, + IW_ESSID_MAX_SIZE), '\0'), + dev->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra", + dev->channel, + dev->wep_enabled ? "enabled" : "disabled", + dev->wep_key_id, dev->wep_keys_len[dev->wep_key_id]); + dbg_uc("%s param: preamble %s rts %d retry %d frag %d " + "txrate %s auth_mode %d", + dev->netdev->name, + dev->preamble_type == PREAMBLE_TYPE_SHORT ? "short" : "long", + dev->rts_threshold, dev->short_retry_limit, + dev->frag_threshold, + dev->txrate == TX_RATE_1MBIT ? "1MBit" : + dev->txrate == TX_RATE_2MBIT ? "2MBit" : + dev->txrate == TX_RATE_5_5MBIT ? "5.5MBit" : + dev->txrate == TX_RATE_11MBIT ? "11MBit" : + dev->txrate == TX_RATE_AUTO ? "auto" : "", + dev->auth_mode); + dbg_uc("%s param: pm_mode %d pm_period %d auth_mode %s " + "scan_times %d %d scan_mode %s international_roaming %d", + dev->netdev->name, + dev->pm_mode, dev->pm_period_us, + dev->auth_mode == WLAN_AUTH_OPEN ? + "open" : "shared_secret", + dev->scan_min_time, dev->scan_max_time, + dev->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive", + dev->international_roaming); + } + + memset(ccfg, 0, sizeof(struct at76c503_card_config)); + ccfg->promiscuous_mode = 0; + ccfg->short_retry_limit = dev->short_retry_limit; + //ccfg->long_retry_limit = dev->long_retry_limit; + + if (dev->wep_enabled) { + if (dev->wep_keys_len[dev->wep_key_id] > WEP_SMALL_KEY_LEN) + ccfg->encryption_type = 2; + else + ccfg->encryption_type = 1; + + /* jal: always exclude unencrypted if WEP is active */ + ccfg->exclude_unencrypted = 1; + } else { + ccfg->exclude_unencrypted = 0; + ccfg->encryption_type = 0; + } + + ccfg->rts_threshold = cpu_to_le16(dev->rts_threshold); + ccfg->fragmentation_threshold = cpu_to_le16(dev->frag_threshold); + + memcpy(ccfg->basic_rate_set, hw_rates, 4); + /* jal: really needed, we do a set_mib for autorate later ??? */ + ccfg->auto_rate_fallback = (dev->txrate == TX_RATE_AUTO ? 1 : 0); + ccfg->channel = dev->channel; + ccfg->privacy_invoked = dev->wep_enabled; + memcpy(ccfg->current_ssid, dev->essid, IW_ESSID_MAX_SIZE); + ccfg->ssid_len = dev->essid_size; + + ccfg->wep_default_key_id = dev->wep_key_id; + memcpy(ccfg->wep_default_key_value, dev->wep_keys, 4 * WEP_KEY_LEN); + + ccfg->short_preamble = dev->preamble_type; + ccfg->beacon_period = cpu_to_le16(dev->beacon_period); + + ret = set_card_command(dev->udev, CMD_STARTUP, (unsigned char *)&dev->card_config, + sizeof(struct at76c503_card_config)); + if(ret < 0){ + err("%s: set_card_command failed: %d", dev->netdev->name, ret); + return ret; + } + + wait_completion(dev, CMD_STARTUP); + + /* remove BSSID from previous run */ + memset(dev->bssid, 0, ETH_ALEN); + + if (set_radio(dev, 1) == 1) + wait_completion(dev, CMD_RADIO); + + if ((ret=set_preamble(dev, dev->preamble_type)) < 0) + return ret; + if ((ret=set_frag(dev, dev->frag_threshold)) < 0) + return ret; + + if ((ret=set_rts(dev, dev->rts_threshold)) < 0) + return ret; + + if ((ret=set_autorate_fallback(dev, dev->txrate == TX_RATE_AUTO ? 1 : 0)) < 0) + return ret; + + if ((ret=set_pm_mode(dev, dev->pm_mode)) < 0) + return ret; + + if ((ret=set_iroaming(dev, dev->international_roaming)) < 0) + return ret; + + if (at76_debug & DBG_MIB) + { + dump_mib_mac(dev); + dump_mib_mac_addr(dev); + dump_mib_mac_mgmt(dev); + dump_mib_mac_wep(dev); + dump_mib_mdomain(dev); + dump_mib_phy(dev); + dump_mib_local(dev); + } + + return 0; +} + +static int at76c503_open(struct net_device *netdev) +{ + struct at76c503 *dev = (struct at76c503 *)(netdev->priv); + int ret = 0; + + dbg(DBG_PROC_ENTRY, "at76c503_open entry"); + + if(down_interruptible(&dev->sem)) + return -EINTR; + + /* if netdev->dev_addr != dev->mac_addr we must + set the mac address in the device ! */ + if (memcmp(netdev->dev_addr, dev->mac_addr, ETH_ALEN)) { + if (set_mac_address(dev,netdev->dev_addr) >= 0) + dbg(DBG_PROGRESS, "%s: set new MAC addr %s", + netdev->name, mac2str(netdev->dev_addr)); + } + +#ifdef DEBUG //test only !!! + dump_mib_mac_addr(dev); +#endif + + dev->site_survey_state=SITE_SURVEY_IDLE; + dev->last_survey = jiffies; + dev->nr_submit_rx_tries = NR_SUBMIT_RX_TRIES; /* init counter */ + + if((ret=submit_rx_urb(dev)) < 0){ + err("%s: open: submit_rx_urb failed: %d", netdev->name, ret); + goto err; + } + + dev->open_count++; + + defer_kevent(dev, KEVENT_RESTART); + + dbg(DBG_PROC_ENTRY, "at76c503_open end"); + err: + up(&dev->sem); + return ret < 0 ? ret : 0; +} + +static int at76c503_stop(struct net_device *netdev) +{ + struct at76c503 *dev = (struct at76c503 *)(netdev->priv); + unsigned long flags; + + dbg(DBG_DEVSTART, "%s: ENTER", __FUNCTION__); + + if (down_interruptible(&dev->sem)) + return -EINTR; + + netif_stop_queue(netdev); + + NEW_STATE(dev,INIT); + + if (!(dev->device_unplugged)) { + /* we are called by "ifconfig wlanX down", not because the + device isn't avail. anymore */ + set_radio(dev, 0); + + /* we unlink the read urb, because the _open() + submits it again. _delete_device() takes care of the + read_urb otherwise. */ + usb_kill_urb(dev->read_urb); + } + + del_timer_sync(&dev->mgmt_timer); + + spin_lock_irqsave(&dev->mgmt_spinlock,flags); + if (dev->next_mgmt_bulk) { + kfree(dev->next_mgmt_bulk); + dev->next_mgmt_bulk = NULL; + } + spin_unlock_irqrestore(&dev->mgmt_spinlock,flags); + + /* free the bss_list */ + free_bss_list(dev); + + assert(dev->open_count > 0); + dev->open_count--; + + up(&dev->sem); + + dbg(DBG_DEVSTART, "%s: EXIT", __FUNCTION__); + + return 0; +} + +static struct net_device_stats *at76c503_get_stats(struct net_device *netdev) +{ + struct at76c503 *dev = (struct at76c503 *)netdev->priv; + + return &dev->stats; +} + +static struct iw_statistics *at76c503_get_wireless_stats(struct net_device *netdev) +{ + struct at76c503 *dev = (struct at76c503 *)netdev->priv; + + dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d", + dev->wstats.qual.qual, dev->wstats.qual.level, + dev->wstats.qual.noise, dev->wstats.qual.updated); + + return &dev->wstats; +} + +static void at76c503_set_multicast(struct net_device *netdev) +{ + struct at76c503 *dev = (struct at76c503 *)netdev->priv; + int promisc; + + promisc = ((netdev->flags & IFF_PROMISC) != 0); + if(promisc != dev->promisc){ + /* grmbl. This gets called in interrupt. */ + dev->promisc = promisc; + defer_kevent(dev, KEVENT_SET_PROMISC); + } +} + +/* we only store the new mac address in netdev struct, + it got set when the netdev gets opened. */ +static int at76c503_set_mac_address(struct net_device *netdev, void *addr) +{ + struct sockaddr *mac = addr; + memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN); + return 1; +} + +/* == PROC iwspy_update == + check if we spy on the sender address of buf and update statistics */ +static void iwspy_update(struct at76c503 *dev, struct at76c503_rx_buffer *buf) +{ + struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)buf->packet; + struct iw_quality qual; + + /* We can only set the level here */ + qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID; + qual.level = 0; + qual.noise = 0; + calc_level(dev, buf, &qual); + + spin_lock_bh(&(dev->spy_spinlock)); + + if (dev->spy_data.spy_number > 0) { + wireless_spy_update(dev->netdev, hdr->addr2, &qual); + } + spin_unlock_bh(&(dev->spy_spinlock)); +} /* iwspy_update */ + + +/******************************************************************************* + * structure that describes the private ioctls/iw handlers of this driver + */ +static const struct iw_priv_args at76c503_priv_args[] = { + { PRIV_IOCTL_SET_SHORT_PREAMBLE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "short_preamble" }, // 0 - long, 1 -short + + { PRIV_IOCTL_SET_DEBUG, + // we must pass the new debug mask as a string, + // 'cause iwpriv cannot parse hex numbers + // starting with 0x :-( + IW_PRIV_TYPE_CHAR | 10, 0, + "set_debug"}, // set debug value + + { PRIV_IOCTL_SET_POWERSAVE_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "powersave_mode"}, // 1 - active, 2 - power save, + // 3 - smart power save + { PRIV_IOCTL_SET_SCAN_TIMES, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, + "scan_times"}, // min_channel_time, + // max_channel_time + { PRIV_IOCTL_SET_SCAN_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "scan_mode"}, // 0 - active, 1 - passive scan + + { PRIV_IOCTL_SET_INTL_ROAMING, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, + "intl_roaming"}, + + /* needed for Kismet, orinoco mode */ + { PRIV_IOCTL_SET_MONITOR_MODE, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, + "monitor"}, /* param1: monitor mode: 0 (off), 1 (on,Prism header), + 2 (on, no Prism header) + param2: channel (to start scan at) */ +}; + + +/******************************************************************************* + * at76c503 implementations of iw_handler functions: + */ +static int at76c503_iw_handler_commit(struct net_device *netdev, + struct iw_request_info *info, + void *null, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + unsigned long flags; + + dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name, + __FUNCTION__); + + // stop any pending tx bulk urb + //TODO + + // jal: TODO: protect access to dev->istate by a spinlock + // (ISR's on other processors may read/write it) + LOCK_ISTATE() + if (dev->istate != INIT) { + UNLOCK_ISTATE() + NEW_STATE(dev,INIT); + // stop pending management stuff + del_timer_sync(&dev->mgmt_timer); + + spin_lock_irqsave(&dev->mgmt_spinlock,flags); + if (dev->next_mgmt_bulk) { + kfree(dev->next_mgmt_bulk); + dev->next_mgmt_bulk = NULL; + } + spin_unlock_irqrestore(&dev->mgmt_spinlock,flags); + + netif_carrier_off(dev->netdev); + netif_stop_queue(dev->netdev); + } else UNLOCK_ISTATE() + + // do the restart after two seconds to catch + // following ioctl's (from more params of iwconfig) + // in _one_ restart + mod_timer(&dev->restart_timer, jiffies+2*HZ); + + return 0; +} + +static int at76c503_iw_handler_get_name(struct net_device *netdev, + struct iw_request_info *info, + char *name, + char *extra) +{ + strcpy(name, "IEEE 802.11b"); + + dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name); + + return 0; +} + +static int at76c503_iw_handler_set_freq(struct net_device *netdev, + struct iw_request_info *info, + struct iw_freq *freq, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int chan = -1; + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d", netdev->name, + freq->m, freq->e); + + // modelled on orinoco.c + if ((freq->e == 0) && (freq->m <= 1000)) + { + // Setting by channel number + chan = freq->m; + } + else + { + // Setting by frequency - search the table + int mult = 1; + int i; + + for (i = 0; i < (6 - freq->e); i++) { + mult *= 10; + } + + for (i = 0; i < NUM_CHANNELS; i++) { + if (freq->m == (channel_frequency[i] * mult)) + chan = i + 1; + } + } + + if (chan < 1 || !dev->domain ) { + // non-positive channels are invalid + // we need a domain info to set the channel + // either that or an invalid frequency was + // provided by the user + ret = -EINVAL; + } else if (!dev->international_roaming) { + if (!(dev->domain->channel_map & (1 << (chan-1)))) { + info("%s: channel %d not allowed for domain %s " + "(and international_roaming is OFF)", + dev->netdev->name, chan, dev->domain->name); + ret = -EINVAL; + } + } + + if (ret == -EIWCOMMIT) { + dev->channel = chan; + dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name, chan); + } + + return ret; +} + +static int at76c503_iw_handler_get_freq(struct net_device *netdev, + struct iw_request_info *info, + struct iw_freq *freq, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + freq->m = dev->channel; + freq->e = 0; + + if (dev->channel) + { + dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d", netdev->name, + channel_frequency[dev->channel - 1], 6); + } + dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name, dev->channel); + + return 0; +} + +static int at76c503_iw_handler_set_mode(struct net_device *netdev, + struct iw_request_info *info, + __u32 *mode, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode); + + if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) && + (*mode != IW_MODE_MONITOR)) { + ret = -EINVAL; + } else { + dev->iw_mode = *mode; + } + return ret; +} + +static int at76c503_iw_handler_get_mode(struct net_device *netdev, + struct iw_request_info *info, + __u32 *mode, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + *mode = dev->iw_mode; + + dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode); + + return 0; +} + +static int at76c503_iw_handler_get_range(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + // inspired by atmel.c + struct at76c503 *dev = (struct at76c503*)netdev->priv; + struct iw_range *range = (struct iw_range*)extra; + int i; + + data->length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + + + //TODO: range->throughput = xxxxxx; + + range->min_nwid = 0x0000; + range->max_nwid = 0x0000; + + // this driver doesn't maintain sensitivity information + range->sensitivity = 0; + + range->max_qual.qual = 100; + range->max_qual.level = 100; + range->max_qual.noise = 0; + range->max_qual.updated = IW_QUAL_NOISE_INVALID; + + range->avg_qual.qual = 50; + range->avg_qual.level = 50; + range->avg_qual.noise = 0; + range->avg_qual.updated = IW_QUAL_NOISE_INVALID; + + range->bitrate[0] = 1000000; + range->bitrate[1] = 2000000; + range->bitrate[2] = 5500000; + range->bitrate[3] = 11000000; + range->num_bitrates = 4; + + + range->min_rts = 0; + range->max_rts = MAX_RTS_THRESHOLD; + + range->min_frag = MIN_FRAG_THRESHOLD; + range->max_frag = MAX_FRAG_THRESHOLD; + + + //range->min_pmp = 0; + //range->max_pmp = 5000000; + //range->min_pmt = 0; + //range->max_pnt = 0; + //range->pmp_flags = IW_POWER_PERIOD; + //range->pmt_flags = 0; + //range->pm_capa = IW_POWER_PERIOD; + //TODO: find out what values we can use to describe PM capabilities + range->pmp_flags = IW_POWER_ON; + range->pmt_flags = IW_POWER_ON; + range->pm_capa = 0; + + + range->encoding_size[0] = WEP_SMALL_KEY_LEN; + range->encoding_size[1] = WEP_LARGE_KEY_LEN; + range->num_encoding_sizes = 2; + range->max_encoding_tokens = WEP_KEYS; + //TODO: do we need this? what is a valid value if we don't support? + //range->encoding_login_index = -1; + + /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power + - take this for all (ignore antenna gains) */ + range->txpower[0] = 15; + range->num_txpower = 1; + range->txpower_capa = IW_TXPOW_DBM; + + // at time of writing (22/Feb/2004), version we intend to support + // is v16, + range->we_version_source = WIRELESS_EXT_SUPPORTED; + range->we_version_compiled = WIRELESS_EXT; + + // same as the values used in atmel.c + range->retry_capa = IW_RETRY_LIMIT ; + range->retry_flags = IW_RETRY_LIMIT; + range->r_time_flags = 0; + range->min_retry = 1; + range->max_retry = 255; + + + range->num_channels = NUM_CHANNELS; + range->num_frequency = 0; + + for (i = 0; + i < 32; //number of bits in reg_domain.channel_map + i++) + { + // test if channel map bit is raised + if (dev->domain->channel_map & (0x1 << i)) + { + range->num_frequency += 1; + + range->freq[i].i = i + 1; + range->freq[i].m = channel_frequency[i] * 100000; + range->freq[i].e = 1; // channel frequency*100000 * 10^1 + } + } + + dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name); + + return 0; +} + +static int at76c503_iw_handler_set_spy(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = 0; + + dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d", + netdev->name, data->length); + + spin_lock_bh(&(dev->spy_spinlock)); + ret = iw_handler_set_spy(dev->netdev, info, (union iwreq_data *)data, + extra); + spin_unlock_bh(&(dev->spy_spinlock)); + + return ret; +} + +static int at76c503_iw_handler_get_spy(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = 0; + + spin_lock_bh(&(dev->spy_spinlock)); + ret = iw_handler_get_spy(dev->netdev, info, + (union iwreq_data *)data, extra); + spin_unlock_bh(&(dev->spy_spinlock)); + + dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d", + netdev->name, data->length); + + return ret; +} + +static int at76c503_iw_handler_set_thrspy(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret; + + dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)", + netdev->name, data->length); + + spin_lock_bh(&(dev->spy_spinlock)); + ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data, + extra); + spin_unlock_bh(&(dev->spy_spinlock)); + + return ret; +} + +static int at76c503_iw_handler_get_thrspy(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret; + + spin_lock_bh(&(dev->spy_spinlock)); + ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data, + extra); + spin_unlock_bh(&(dev->spy_spinlock)); + + dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)", + netdev->name, data->length); + + return ret; +} + +static int at76c503_iw_handler_set_wap(struct net_device *netdev, + struct iw_request_info *info, + struct sockaddr *ap_addr, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name, + mac2str(ap_addr->sa_data)); + + // if the incoming address == ff:ff:ff:ff:ff:ff, the user has + // chosen any or auto AP preference + if (!memcmp(ap_addr->sa_data, bc_addr, ETH_ALEN) + || !memcmp(ap_addr->sa_data, off_addr, ETH_ALEN)) { + dev->wanted_bssid_valid = 0; + } else { + // user wants to set a preferred AP address + dev->wanted_bssid_valid = 1; + memcpy(dev->wanted_bssid, ap_addr->sa_data, ETH_ALEN); + } + + return -EIWCOMMIT; +} + +static int at76c503_iw_handler_get_wap(struct net_device *netdev, + struct iw_request_info *info, + struct sockaddr *ap_addr, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + ap_addr->sa_family = ARPHRD_ETHER; + memcpy(ap_addr->sa_data, dev->bssid, ETH_ALEN); + + dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name, + mac2str(ap_addr->sa_data)); + + return 0; +} + + +static int at76c503_iw_handler_set_scan(struct net_device *netdev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + unsigned long flags; + int ret = 0; +#if WIRELESS_EXT > 19 + struct iw_scan_req *req = NULL; +#endif + + dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name); + + if (!netif_running(netdev)) + return -ENETDOWN; + + /* jal: we don't allow "iwlist wlanX scan" while we are + in monitor mode */ + if (dev->iw_mode == IW_MODE_MONITOR) + return -EBUSY; + + /* Timeout old surveys. */ + if ((jiffies - dev->last_survey) > (20 * HZ)) + dev->site_survey_state = SITE_SURVEY_IDLE; + dev->last_survey = jiffies; + + /* Initiate a scan command */ + if (dev->site_survey_state == SITE_SURVEY_IN_PROGRESS) + return -EBUSY; + + dev->site_survey_state = SITE_SURVEY_IN_PROGRESS; + + // stop pending management stuff + del_timer_sync(&(dev->mgmt_timer)); + + spin_lock_irqsave(&(dev->mgmt_spinlock), flags); + if (dev->next_mgmt_bulk) { + kfree(dev->next_mgmt_bulk); + dev->next_mgmt_bulk = NULL; + } + spin_unlock_irqrestore(&(dev->mgmt_spinlock), flags); + + if (netif_running(dev->netdev)) { + // pause network activity + netif_carrier_off(dev->netdev); + netif_stop_queue(dev->netdev); + } +// Try to do passive or active scan if WE asks as. +#if WIRELESS_EXT > 19 + if (wrqu->data.length + && wrqu->data.length == sizeof(struct iw_scan_req)) { + req = (struct iw_scan_req *)extra; + + if (req->scan_type == IW_SCAN_TYPE_PASSIVE) + dev->scan_mode = SCAN_TYPE_PASSIVE; + else if (req->scan_type == IW_SCAN_TYPE_ACTIVE) + dev->scan_mode = SCAN_TYPE_ACTIVE; + + /* Sanity check values? */ + LOCK_ISTATE() + if (req->min_channel_time > 0) { + if (dev->istate == MONITORING) + dev->monitor_scan_min_time = req->min_channel_time; + else + dev->scan_min_time = req->min_channel_time; + } + if (req->max_channel_time > 0) { + if (dev->istate == MONITORING) + dev->monitor_scan_max_time = req->max_channel_time; + else + dev->scan_max_time = req->max_channel_time; + } + UNLOCK_ISTATE() + } +#endif + + // change to scanning state + NEW_STATE(dev, SCANNING); + defer_kevent(dev, KEVENT_SCAN); + + return ret; +} + +static int at76c503_iw_handler_get_scan(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + unsigned long flags; + struct list_head *lptr, *nptr; + struct bss_info *curr_bss; + struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL); + char *curr_val, *curr_pos = extra; + int i; + + dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name); + + if (!iwe) + return -ENOMEM; + + if (dev->site_survey_state != SITE_SURVEY_COMPLETED) + /* scan not yet finished */ + return -EAGAIN; + + spin_lock_irqsave(&(dev->bss_list_spinlock), flags); + + list_for_each_safe(lptr, nptr, &(dev->bss_list)) { + curr_bss = list_entry(lptr, struct bss_info, list); + + iwe->cmd = SIOCGIWAP; + iwe->u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6); + curr_pos = iwe_stream_add_event(info, curr_pos, + extra + IW_SCAN_MAX_DATA, iwe, IW_EV_ADDR_LEN); + + iwe->u.data.length = curr_bss->ssid_len; + iwe->cmd = SIOCGIWESSID; + iwe->u.data.flags = 1; + + curr_pos = iwe_stream_add_point(info, curr_pos, + extra + IW_SCAN_MAX_DATA, iwe, curr_bss->ssid); + + iwe->cmd = SIOCGIWMODE; + iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ? + IW_MODE_ADHOC : + (curr_bss->capa & WLAN_CAPABILITY_ESS) ? + IW_MODE_MASTER : + IW_MODE_AUTO; + // IW_MODE_AUTO = 0 which I thought is + // the most logical value to return in this case + curr_pos = iwe_stream_add_event(info, curr_pos, + extra + IW_SCAN_MAX_DATA, iwe, IW_EV_UINT_LEN); + + iwe->cmd = SIOCGIWFREQ; + iwe->u.freq.m = curr_bss->channel; + iwe->u.freq.e = 0; + curr_pos = iwe_stream_add_event(info, curr_pos, + extra + IW_SCAN_MAX_DATA, iwe, IW_EV_FREQ_LEN); + + iwe->cmd = SIOCGIWENCODE; + if (curr_bss->capa & 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; + curr_pos = iwe_stream_add_point(info, curr_pos, + extra + IW_SCAN_MAX_DATA, iwe, NULL); + + /* Add quality statistics */ + iwe->cmd = IWEVQUAL; + iwe->u.qual.noise=0; + iwe->u.qual.updated=IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED; + iwe->u.qual.level = (curr_bss->rssi * 100 / 42); + if (iwe->u.qual.level > 100) + iwe->u.qual.level = 100; + if((dev->board_type == BOARDTYPE_503_INTERSIL_3861) || + (dev->board_type == BOARDTYPE_503_INTERSIL_3863)) { + iwe->u.qual.qual=curr_bss->link_qual; + } else { + iwe->u.qual.qual=0; + iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID; + } + /* Add new value to event */ + curr_pos = iwe_stream_add_event(info, curr_pos, + extra + IW_SCAN_MAX_DATA, iwe, IW_EV_QUAL_LEN); + + /* Rate : stuffing multiple values in a single event require a bit + * more of magic - Jean II */ + curr_val = curr_pos + IW_EV_LCP_LEN; + + iwe->cmd = SIOCGIWRATE; + /* Those two flags are ignored... */ + iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0; + /* Max 8 values */ + for(i=0; i < curr_bss->rates_len; i++) { + /* Bit rate given in 500 kb/s units (+ 0x80) */ + iwe->u.bitrate.value = + ((curr_bss->rates[i] & 0x7f) * 500000); + /* Add new value to event */ + curr_val = iwe_stream_add_value(info, curr_pos, curr_val, + extra + IW_SCAN_MAX_DATA, + iwe, IW_EV_PARAM_LEN); + } + + /* Check if we added any event */ + if ((curr_val - curr_pos) > IW_EV_LCP_LEN) + curr_pos = curr_val; + + + // more information may be sent back using IWECUSTOM + + } + + spin_unlock_irqrestore(&(dev->bss_list_spinlock), flags); + + data->length = (curr_pos - extra); + data->flags = 0; + + kfree(iwe); + return 0; +} + + +static int at76c503_iw_handler_set_essid(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra); + + if (data->flags) + { + memcpy(dev->essid, extra, data->length); + dev->essid_size = data->length; +#if WIRELESS_EXT < 21 + /* For historic reasons, the SSID length used to include one + * extra character, C string nul termination, even though SSID is + * really an octet string that should not be presented as a C + * string. WE-21 changes this to explicitly require the length + * _not_ to include nul termination, but for WE < 21, decrement + * the length count here to remove the nul termination. */ + dev->essid_size = max(dev->essid_size - 1, 0); +#endif + } + else + { + /* Use any SSID */ + dev->essid_size = 0; + } + + return -EIWCOMMIT; +} + +static int at76c503_iw_handler_get_essid(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + if (dev->essid_size) { + // not the ANY ssid in dev->essid + data->flags = 1; + data->length = dev->essid_size; + memcpy(extra, dev->essid, data->length); + extra[data->length] = '\0'; + data->length += 1; + } else { + // the ANY ssid was specified + LOCK_ISTATE() + if (dev->istate == CONNECTED && + dev->curr_bss != NULL) { + UNLOCK_ISTATE() + // report the SSID we have found + data->flags = 1; + data->length = dev->curr_bss->ssid_len; + memcpy(extra, dev->curr_bss->ssid, data->length); + extra[dev->curr_bss->ssid_len] = '\0'; + data->length += 1; + } else { + UNLOCK_ISTATE() + // report ANY back + data->flags=0; + data->length=0; + } + } + + dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %s", netdev->name, extra); + + return 0; +} + +static int at76c503_iw_handler_set_nickname(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + dbg(DBG_IOCTL, "%s: SIOCSIWNICKN - %s", netdev->name, extra); + + // iwconfig gives length including 0 byte like in the case of essid + memcpy(dev->nickn, extra, data->length); + + return 0; +} + +static int at76c503_iw_handler_get_nickname(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *data, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + data->length = strlen(dev->nickn); + memcpy(extra, dev->nickn, data->length); + extra[data->length] = '\0'; + data->length += 1; + + dbg(DBG_IOCTL, "%s: SIOCGIWNICKN - %s", netdev->name, extra); + + return 0; +} + +static int at76c503_iw_handler_set_rate(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *bitrate, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name, + bitrate->value); + + switch (bitrate->value) + { + case -1: dev->txrate = TX_RATE_AUTO; break; // auto rate + case 1000000: dev->txrate = TX_RATE_1MBIT; break; + case 2000000: dev->txrate = TX_RATE_2MBIT; break; + case 5500000: dev->txrate = TX_RATE_5_5MBIT; break; + case 11000000: dev->txrate = TX_RATE_11MBIT; break; + default: ret = -EINVAL; + } + + return ret; +} + +static int at76c503_iw_handler_get_rate(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *bitrate, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = 0; + + switch (dev->txrate) + { + // return max rate if RATE_AUTO + case TX_RATE_AUTO: bitrate->value = 11000000; break; + case TX_RATE_1MBIT: bitrate->value = 1000000; break; + case TX_RATE_2MBIT: bitrate->value = 2000000; break; + case TX_RATE_5_5MBIT: bitrate->value = 5500000; break; + case TX_RATE_11MBIT: bitrate->value = 11000000; break; + default: ret = -EINVAL; + } + + bitrate->fixed = (dev->txrate != TX_RATE_AUTO); + bitrate->disabled = 0; + + dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name, + bitrate->value); + + return ret; +} + +static int at76c503_iw_handler_set_rts(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *rts, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = -EIWCOMMIT; + int rthr = rts->value; + + dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s", + netdev->name, rts->value, + (rts->disabled) ? "true" : "false"); + + if (rts->disabled) + rthr = MAX_RTS_THRESHOLD; + + if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD)) { + ret = -EINVAL; + } else { + dev->rts_threshold = rthr; + } + + return ret; +} + +static int at76c503_iw_handler_get_rts(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *rts, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + rts->value = dev->rts_threshold; + rts->disabled = (rts->value >= MAX_RTS_THRESHOLD); + rts->fixed = 1; + + dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s", + netdev->name, rts->value, + (rts->disabled) ? "true" : "false"); + + return 0; +} + +static int at76c503_iw_handler_set_frag(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *frag, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = -EIWCOMMIT; + int fthr = frag->value; + + dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s", + netdev->name, frag->value, + (frag->disabled) ? "true" : "false"); + + if(frag->disabled) + fthr = MAX_FRAG_THRESHOLD; + + if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD)) { + ret = -EINVAL; + } else { + dev->frag_threshold = fthr & ~0x1; // get an even value + } + + return ret; +} + +static int at76c503_iw_handler_get_frag(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *frag, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + frag->value = dev->frag_threshold; + frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD); + frag->fixed = 1; + + dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s", + netdev->name, frag->value, + (frag->disabled) ? "true" : "false"); + + return 0; +} + +static int at76c503_iw_handler_get_txpow(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *power, + char *extra) +{ + power->value = 15; + power->fixed = 1; /* No power control */ + power->disabled = 0; + power->flags = IW_TXPOW_DBM; + + dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name, + power->value); + + return 0; +} + +/* jal: short retry is handled by the firmware (at least 0.90.x), + while long retry is not (?) */ +static int at76c503_iw_handler_set_retry(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *retry, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags x%x val %d", + netdev->name, retry->disabled, retry->flags, retry->value); + + if(!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) { + if ((retry->flags & IW_RETRY_MIN) || + !(retry->flags & IW_RETRY_MAX)) { + dev->short_retry_limit = retry->value; + } else + ret = -EINVAL; + } else { + ret = -EINVAL; + } + + return ret; +} + +// adapted (ripped) from atmel.c +static int at76c503_iw_handler_get_retry(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *retry, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name); + + retry->disabled = 0; // Can't be disabled + + // Note : by default, display the min retry number + //if((retry->flags & IW_RETRY_MAX)) { + // retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; + // retry->value = dev->long_retry_limit; + //} else { + retry->flags = IW_RETRY_LIMIT; + retry->value = dev->short_retry_limit; + + //if(dev->long_retry_limit != dev->short_retry_limit) { + // dev->retry.flags |= IW_RETRY_MIN; + //} + //} + + return 0; +} + +static int at76c503_iw_handler_set_encode(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *encoding, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int index = (encoding->flags & IW_ENCODE_INDEX) - 1; + int len = encoding->length; + + dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x " + "pointer %p len %d", netdev->name, encoding->flags, + encoding->pointer, encoding->length); + dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d " + "auth_mode %s", + netdev->name, (dev->wep_enabled) ? "true" : "false", + dev->wep_key_id, + (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ? + "restricted" : "open"); + + // take the old default key if index is invalid + if ((index < 0) || (index >= WEP_KEYS)) + index = dev->wep_key_id; + + if (len > 0) + { + if (len > WEP_LARGE_KEY_LEN) + len = WEP_LARGE_KEY_LEN; + + memset(dev->wep_keys[index], 0, WEP_KEY_LEN); + memcpy(dev->wep_keys[index], extra, len); + dev->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ? + WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN; + dev->wep_enabled = 1; + } + + dev->wep_key_id = index; + dev->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0); + + if (encoding->flags & IW_ENCODE_RESTRICTED) + dev->auth_mode = WLAN_AUTH_SHARED_KEY; + if (encoding->flags & IW_ENCODE_OPEN) + dev->auth_mode = WLAN_AUTH_OPEN; + + dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d " + "key_len %d auth_mode %s", + netdev->name, (dev->wep_enabled) ? "true" : "false", + dev->wep_key_id + 1, dev->wep_keys_len[dev->wep_key_id], + (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ? + "restricted" : "open"); + + return -EIWCOMMIT; +} + +static int at76c503_iw_handler_get_encode(struct net_device *netdev, + struct iw_request_info *info, + struct iw_point *encoding, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int index = (encoding->flags & IW_ENCODE_INDEX) - 1; + + if ((index < 0) || (index >= WEP_KEYS)) + index = dev->wep_key_id; + + encoding->flags = + (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ? + IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN; + + if (!dev->wep_enabled) + encoding->flags |= IW_ENCODE_DISABLED; + + if (encoding->pointer) + { + encoding->length = dev->wep_keys_len[index]; + + memcpy(extra, dev->wep_keys[index], dev->wep_keys_len[index]); + + encoding->flags |= (index + 1); + } + + dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x " + "pointer %p len %d", netdev->name, encoding->flags, + encoding->pointer, encoding->length); + dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d " + "key_len %d auth_mode %s", + netdev->name, (dev->wep_enabled) ? "true" : "false", + dev->wep_key_id + 1, dev->wep_keys_len[dev->wep_key_id], + (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ? + "restricted" : "open"); + + return 0; +} + +static int at76c503_iw_handler_set_power(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *power, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + dbg(DBG_IOCTL, "%s: SIOCSIWPOWER - disabled %s flags x%x value x%x", + netdev->name, (power->disabled) ? "true" : "false", + power->flags, power->value); + + if (power->disabled) + { + dev->pm_mode = PM_ACTIVE; + } + else + { + // we set the listen_interval based on the period given + // no idea how to handle the timeout of iwconfig ??? + if (power->flags & IW_POWER_PERIOD) + { + dev->pm_period_us = power->value; + } + + dev->pm_mode = PM_SAVE; // use iw_priv to select SMART_SAVE + } + + return -EIWCOMMIT; +} + +static int at76c503_iw_handler_get_power(struct net_device *netdev, + struct iw_request_info *info, + struct iw_param *power, + char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + + power->disabled = dev->pm_mode == PM_ACTIVE; + + if ((power->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) + { + power->flags = IW_POWER_TIMEOUT; + power->value = 0; + } + else + { + unsigned long flags; + u16 beacon_int; // of the current bss + + power->flags = IW_POWER_PERIOD; + + spin_lock_irqsave(&dev->bss_list_spinlock, flags); + beacon_int = dev->curr_bss != NULL ? + dev->curr_bss->beacon_interval : 0; + spin_unlock_irqrestore(&dev->bss_list_spinlock, flags); + + if (beacon_int != 0) + { + power->value = + (beacon_int * dev->pm_period_beacon) << 10; + } + else + { + power->value = dev->pm_period_us; + } + } + + power->flags |= IW_POWER_ALL_R; + + dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - disabled %s flags x%x value x%x", + netdev->name, (power->disabled) ? "true" : "false", + power->flags, power->value); + + return 0; +} + + +/******************************************************************************* + * Private IOCTLS + */ +static int at76c503_iw_handler_PRIV_IOCTL_SET_SHORT_PREAMBLE + (struct net_device *netdev, struct iw_request_info *info, + char *name, char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int val = *((int *)name); + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_SHORT_PREAMBLE, %d", + netdev->name, val); + + if (val < 0 || val > 2) { + //allow value of 2 - in the win98 driver it stands + //for "auto preamble" ...? + ret = -EINVAL; + } else { + dev->preamble_type = val; + } + + return ret; +} + +static int at76c503_iw_handler_PRIV_IOCTL_SET_DEBUG + (struct net_device *netdev, struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + char *ptr; + u32 val; + + if (data->length > 0) { + val = simple_strtol(extra, &ptr, 0); + + if (ptr == extra) { + val = DBG_DEFAULTS; + } + + dbg_uc("%s: PRIV_IOCTL_SET_DEBUG input %d: %s -> x%x", + netdev->name, data->length, extra, val); + } else { + val = DBG_DEFAULTS; + } + + dbg_uc("%s: PRIV_IOCTL_SET_DEBUG, old 0x%x new 0x%x", + netdev->name, at76_debug, val); + + /* jal: some more output to pin down lockups */ + dbg_uc("%s: netif running %d queue_stopped %d carrier_ok %d", + netdev->name, + netif_running(netdev), + netif_queue_stopped(netdev), + netif_carrier_ok(netdev)); + + at76_debug = val; + + return 0; +} + +static int at76c503_iw_handler_PRIV_IOCTL_SET_POWERSAVE_MODE + (struct net_device *netdev, struct iw_request_info *info, + char *name, char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int val = *((int *)name); + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_POWERSAVE_MODE, %d (%s)", + netdev->name, val, + val == PM_ACTIVE ? "active" : val == PM_SAVE ? "save" : + val == PM_SMART_SAVE ? "smart save" : ""); + if (val < PM_ACTIVE || val > PM_SMART_SAVE) { + ret = -EINVAL; + } else { + dev->pm_mode = val; + } + + return ret; +} + +static int at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_TIMES + (struct net_device *netdev, struct iw_request_info *info, + char *name, char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int mint = *((int *)name); + int maxt = *((int *)name + 1); + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_SCAN_TIMES - min %d max %d", + netdev->name, mint, maxt); + if (mint <= 0 || maxt <= 0 || mint > maxt) { + ret = -EINVAL; + } else { + LOCK_ISTATE() + if (dev->istate == MONITORING) { + dev->monitor_scan_min_time = mint; + dev->monitor_scan_max_time = maxt; + ret = 0; + } else { + dev->scan_min_time = mint; + dev->scan_max_time = maxt; + } + UNLOCK_ISTATE() + } + + return ret; +} + +static int at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_MODE + (struct net_device *netdev, struct iw_request_info *info, + char *name, char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int val = *((int *)name); + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_SCAN_MODE - mode %s", + netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" : + (val = SCAN_TYPE_PASSIVE) ? "passive" : ""); + + if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE) { + ret = -EINVAL; + } else { + dev->scan_mode = val; + } + + return ret; +} + +static int set_iroaming(struct at76c503 *dev, int onoff) +{ + int ret = 0; + + memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer)); + dev->mib_buf.type = MIB_MAC_MGMT; + dev->mib_buf.size = 1; + dev->mib_buf.index = IROAMING_OFFSET; + dev->mib_buf.data[0] = (dev->international_roaming ? 1 : 0); + ret = set_mib(dev, &dev->mib_buf); + if(ret < 0){ + err("%s: set_mib (intl_roaming_enable) failed: %d", dev->netdev->name, ret); + } + + return ret; +} + +static int at76c503_iw_handler_PRIV_IOCTL_SET_INTL_ROAMING + (struct net_device *netdev, struct iw_request_info *info, + char *name, char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int val = *((int *)name); + int ret = -EIWCOMMIT; + + dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_INTL_ROAMING - mode %s", + netdev->name, (val == IR_OFF) ? "off" : + (val == IR_ON) ? "on" : ""); + + if (val != IR_OFF && val != IR_ON) { + ret = -EINVAL; + } else { + if (dev->international_roaming != val) { + dev->international_roaming = val; + set_iroaming(dev, val); + } + } + + return ret; +} + +/* == PROC set_monitor_mode == + sets dev->netdev->type */ +static void set_monitor_mode(struct at76c503 *dev, int use_prism) +{ + if (dev->iw_mode == IW_MODE_MONITOR) { + if (use_prism) { + dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE ON: " + "Prism headers ARE used", dev->netdev->name); + dev->netdev->type = ARPHRD_IEEE80211_PRISM; + } else { + dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE ON: " + "Prism headers NOT used", dev->netdev->name); + dev->netdev->type = ARPHRD_IEEE80211; + } + } else { + dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE OFF", + dev->netdev->name); + dev->netdev->type = ARPHRD_ETHER; + } +} /* set_monitor_mode */ + +static int at76c503_iw_handler_PRIV_IOCTL_SET_MONITOR_MODE + (struct net_device *netdev, struct iw_request_info *info, + char *name, char *extra) +{ + struct at76c503 *dev = (struct at76c503*)netdev->priv; + int *params = ((int *)name); + int mode = params[0]; + int channel = params[1]; + int ret = 0; + + dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_MONITOR_MODE - mode %d ch %d", + netdev->name, mode, channel); + + if (mode != MM_OFF && mode != MM_ON && mode != MM_ON_NO_PRISM) + ret = -EINVAL; + else { + if (mode != MM_OFF) { + if ((channel >= 1) && + (channel <= (sizeof(channel_frequency) / + sizeof(channel_frequency[0])))) + // INFO: This doesn't actually affect the scan + dev->channel = channel; + + dev->monitor_prism_header = (mode == MM_ON); + + if (dev->iw_mode != IW_MODE_MONITOR) { + ret = -EIWCOMMIT; + dev->iw_mode = IW_MODE_MONITOR; + } + } else { + /* mode == MM_OFF */ + if (dev->iw_mode == IW_MODE_MONITOR) { + ret = -EIWCOMMIT; + dev->iw_mode = IW_MODE_INFRA; + } + } + set_monitor_mode(dev, dev->monitor_prism_header); + } + + return ret; +} + +/******************************************************************************* + * structure that advertises the iw handlers of this driver + */ +static const iw_handler at76c503_handlers[] = +{ + [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_commit, + [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_name, + [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_freq, + [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_freq, + [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_mode, + [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_mode, + [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_range, + [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_spy, + [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_spy, + [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_thrspy, + [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_thrspy, + [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_wap, + [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_wap, + [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_scan, + [SIOCGIWSCAN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_scan, + [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_essid, + [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_essid, + [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_nickname, + [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_nickname, + [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_rate, + [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_rate, + [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_rts, + [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_rts, + [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_frag, + [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_frag, + [SIOCGIWTXPOW -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_txpow, + [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_retry, + [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_retry, + [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_encode, + [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_encode, + [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_power, + [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_power, +}; + +/******************************************************************************* + * structure that advertises the private iw handlers of this driver + */ +static const iw_handler at76c503_priv_handlers[] = +{ + (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_SHORT_PREAMBLE, + (iw_handler) NULL, + (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_DEBUG, + (iw_handler) NULL, + (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_POWERSAVE_MODE, + (iw_handler) NULL, + (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_TIMES, + (iw_handler) NULL, + (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_MODE, + (iw_handler) NULL, + (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_INTL_ROAMING, + (iw_handler) NULL, + (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_MONITOR_MODE, + (iw_handler) NULL, +}; + +static const struct iw_handler_def at76c503_handler_def = +{ + .num_standard = sizeof(at76c503_handlers)/sizeof(iw_handler), + .num_private = sizeof(at76c503_priv_handlers)/sizeof(iw_handler), + .num_private_args = sizeof(at76c503_priv_args)/ + sizeof(struct iw_priv_args), + .standard = (iw_handler *) at76c503_handlers, + .private = (iw_handler *) at76c503_priv_handlers, + .private_args = (struct iw_priv_args *) at76c503_priv_args, +#if WIRELESS_EXT > 16 + .get_wireless_stats = at76c503_get_wireless_stats, +#endif +#if WIRELESS_EXT == 15 || WIRELESS_EXT == 16 + .spy_offset = offsetof(struct at76c503, spy_data), +#endif +}; + + +static void at76c503_get_drvinfo(struct net_device *netdev, + struct ethtool_drvinfo *info) +{ + struct at76c503 *dev = (struct at76c503 *)netdev->priv; + + strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1); + + strncpy(info->version, DRIVER_VERSION, sizeof(info->version)); + info->version[sizeof(info->version)-1] = '\0'; + + snprintf(info->bus_info, sizeof(info->bus_info) - 1, "usb%d:%d", + dev->udev->bus->busnum, dev->udev->devnum); + + snprintf(info->fw_version, sizeof(info->fw_version) - 1, + "%d.%d.%d-%d", + dev->fw_version.major, dev->fw_version.minor, + dev->fw_version.patch, dev->fw_version.build); +} + +static struct ethtool_ops at76c503_ethtool_ops = { + .get_drvinfo = at76c503_get_drvinfo, +}; + + +static void at76c503_delete_device(struct at76c503 *dev) +{ + int i; + + if (!dev) + return; + + /* signal to _stop() that the device is gone */ + dev->device_unplugged = 1; + + dbg(DBG_PROC_ENTRY, "%s: ENTER",__FUNCTION__); + + if (dev->netdev_registered) { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17) + if (down_trylock(&rtnl_sem) != 0) { +#else + if (rtnl_trylock() == 0) { +#endif + info("%s: rtnl_sem already down'ed", __FUNCTION__); + } else { + /* synchronously calls at76c503_stop() */ + unregister_netdevice(dev->netdev); + rtnl_unlock(); + } + } + + PUT_DEV(dev->udev); + + // assuming we used keventd, it must quiesce too + flush_scheduled_work (); + + if(dev->bulk_out_buffer != NULL) + kfree(dev->bulk_out_buffer); + + kfree(dev->ctrl_buffer); + + if(dev->write_urb != NULL) { + usb_kill_urb(dev->write_urb); + usb_free_urb(dev->write_urb); + } + if(dev->read_urb != NULL) { + usb_kill_urb(dev->read_urb); + usb_free_urb(dev->read_urb); + } + if(dev->ctrl_buffer != NULL) { + usb_kill_urb(dev->ctrl_urb); + usb_free_urb(dev->ctrl_urb); + } + + dbg(DBG_PROC_ENTRY,"%s: unlinked urbs",__FUNCTION__); + + if(dev->rx_skb != NULL) + kfree_skb(dev->rx_skb); + + free_bss_list(dev); + del_timer_sync(&dev->bss_list_timer); + + LOCK_ISTATE() + if (dev->istate == CONNECTED) { + UNLOCK_ISTATE() + iwevent_bss_disconnect(dev->netdev); + } else UNLOCK_ISTATE() + + for(i=0; i < NR_RX_DATA_BUF; i++) + if (dev->rx_data[i].skb != NULL) { + dev_kfree_skb(dev->rx_data[i].skb); + dev->rx_data[i].skb = NULL; + } + dbg(DBG_PROC_ENTRY, "%s: before freeing dev/netdev", __FUNCTION__); + free_netdev(dev->netdev); /* dev is in net_dev */ +#ifdef CONFIG_IPAQ_HANDHELD + if (machine_is_h5400()) { + ipaq_led_off (RED_LED); + ipaq_led_off (RED_LED_2); + } +#endif + dbg(DBG_PROC_ENTRY, "%s: EXIT", __FUNCTION__); +} + +static int at76c503_alloc_urbs(struct at76c503 *dev) +{ + struct usb_interface *interface = dev->interface; +// struct usb_host_interface *iface_desc = &interface->altsetting[0]; + struct usb_endpoint_descriptor *endpoint; + struct usb_device *udev = dev->udev; + int i, buffer_size; + + dbg(DBG_PROC_ENTRY, "%s: ENTER", __FUNCTION__); + + dbg(DBG_URB, "%s: NumEndpoints %d ", __FUNCTION__, NUM_EP(interface)); + + for(i = 0; i < NUM_EP(interface); i++) { + endpoint = &EP(interface,i); + + dbg(DBG_URB, "%s: %d. endpoint: addr x%x attr x%x", + __FUNCTION__, + i, + endpoint->bEndpointAddress, + endpoint->bmAttributes); + + if ((endpoint->bEndpointAddress & 0x80) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk in endpoint */ + + dev->read_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->read_urb) { + err("No free urbs available"); + return -1; + } + dev->bulk_in_endpointAddr = endpoint->bEndpointAddress; + } + + if (((endpoint->bEndpointAddress & 0x80) == 0x00) && + ((endpoint->bmAttributes & 3) == 0x02)) { + /* we found a bulk out endpoint */ + dev->write_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->write_urb) { + err("no free urbs available"); + return -1; + } + buffer_size = sizeof(struct at76c503_tx_buffer) + + MAX_PADDING_SIZE; + dev->bulk_out_size = buffer_size; + dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; + dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL); + if (!dev->bulk_out_buffer) { + err("couldn't allocate bulk_out_buffer"); + return -1; + } + FILL_BULK_URB(dev->write_urb, udev, + usb_sndbulkpipe(udev, + endpoint->bEndpointAddress), + dev->bulk_out_buffer, buffer_size, + (usb_complete_t)at76c503_write_bulk_callback, dev); + } + } + + dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!dev->ctrl_urb) { + err("no free urbs available"); + return -1; + } + dev->ctrl_buffer = kmalloc(1024, GFP_KERNEL); + if (!dev->ctrl_buffer) { + err("couldn't allocate ctrl_buffer"); + return -1; + } + + dbg(DBG_PROC_ENTRY, "%s: EXIT", __FUNCTION__); + + return 0; +} + +static struct at76c503 *alloc_new_device(struct usb_device *udev, + int board_type, + const char *netdev_name) +{ + struct net_device *netdev; + struct at76c503 *dev = NULL; + int i; + + /* allocate memory for our device state and initialize it */ + netdev = alloc_etherdev(sizeof(struct at76c503)); + if (netdev == NULL) { + err("out of memory"); + return NULL; + } + + dev = (struct at76c503 *)netdev->priv; + memset(dev, 0, sizeof(*dev)); + + dev->udev = udev; + dev->netdev = netdev; + + init_MUTEX (&dev->sem); + INIT_WORK (&dev->kevent, kevent); + + dev->open_count = 0; + + init_timer(&dev->restart_timer); + dev->restart_timer.data = (unsigned long)dev; + dev->restart_timer.function = restart_timeout; + + init_timer(&dev->mgmt_timer); + dev->mgmt_timer.data = (unsigned long)dev; + dev->mgmt_timer.function = mgmt_timeout; + + init_timer(&dev->fw_dl_timer); + dev->fw_dl_timer.data = (unsigned long)dev; + dev->fw_dl_timer.function = fw_dl_timeout; + + + spin_lock_init(&dev->mgmt_spinlock); + spin_lock_init(&dev->istate_spinlock); + dev->next_mgmt_bulk = NULL; + dev->istate = INTFW_DOWNLOAD; + + /* initialize empty BSS list */ + dev->curr_bss = dev->new_bss = NULL; + INIT_LIST_HEAD(&dev->bss_list); + spin_lock_init(&dev->bss_list_spinlock); + + init_timer(&dev->bss_list_timer); + dev->bss_list_timer.data = (unsigned long)dev; + dev->bss_list_timer.function = bss_list_timeout; + + spin_lock_init(&dev->spy_spinlock); + + /* mark all rx data entries as unused */ + for(i=0; i < NR_RX_DATA_BUF; i++) + dev->rx_data[i].skb = NULL; + + dev->tasklet.func = rx_tasklet; + dev->tasklet.data = (unsigned long)dev; + + dev->board_type = board_type; + + dev->pm_mode = pm_mode; + dev->pm_period_us = pm_period; + + dev_alloc_name(netdev, netdev_name); + + return dev; +} /* alloc_new_device */ + +/* == PROC init_new_device == + firmware got downloaded, we can continue with init */ +/* We may have to move the register_netdev into alloc_new_device, + because hotplug may try to configure the netdev _before_ + (or parallel to) the download of firmware */ +static int init_new_device(struct at76c503 *dev) +{ + struct net_device *netdev = dev->netdev; + int ret; + + /* set up the endpoint information */ + /* check out the endpoints */ + + dev->interface = dev->udev->actconfig->interface[0]; + + dbg(DBG_DEVSTART, "USB interface: %d endpoints", + NUM_EP(dev->interface)); + + /* we let this timer run the whole time this driver instance lives */ + mod_timer(&dev->bss_list_timer, jiffies+BSS_LIST_TIMEOUT); + +#ifdef CONFIG_IPAQ_HANDHELD + if (machine_is_h5400 ()) + ipaq_init_led (); +#endif + + if(at76c503_alloc_urbs(dev) < 0) + goto error; + + /* get firmware version */ + ret = get_mib(dev->udev, MIB_FW_VERSION, (u8*)&dev->fw_version, sizeof(dev->fw_version)); + if((ret < 0) || ((dev->fw_version.major == 0) && + (dev->fw_version.minor == 0) && + (dev->fw_version.patch == 0) && + (dev->fw_version.build == 0))){ + err("getting firmware failed with %d, or version is 0", ret); + err("this probably means that the ext. fw was not loaded correctly"); + goto error; + } + + /* fw 0.84 doesn't send FCS with rx data */ + if (dev->fw_version.major == 0 && dev->fw_version.minor <= 84) + dev->rx_data_fcs_len = 0; + else + dev->rx_data_fcs_len = 4; + + info("firmware version %d.%d.%d #%d (fcs_len %d)", + dev->fw_version.major, dev->fw_version.minor, + dev->fw_version.patch, dev->fw_version.build, + dev->rx_data_fcs_len); + + /* MAC address */ + ret = get_hw_config(dev); + if(ret < 0){ + err("could not get MAC address"); + goto error; + } + + dev->domain = getRegDomain(dev->regulatory_domain); + /* init. netdev->dev_addr */ + memcpy(netdev->dev_addr, dev->mac_addr, ETH_ALEN); + info("device's MAC %s, regulatory domain %s (id %d)", + mac2str(dev->mac_addr), dev->domain->name, + dev->regulatory_domain); + + /* initializing */ + dev->international_roaming = international_roaming; + dev->channel = DEF_CHANNEL; + dev->iw_mode = default_iw_mode; + dev->monitor_prism_header = 1; + memset(dev->essid, 0, IW_ESSID_MAX_SIZE); + memset(dev->nickn, 0, sizeof(dev->nickn)); + dev->rts_threshold = DEF_RTS_THRESHOLD; + dev->frag_threshold = DEF_FRAG_THRESHOLD; + dev->short_retry_limit = DEF_SHORT_RETRY_LIMIT; + //dev->long_retr_limit = DEF_LONG_RETRY_LIMIT; + dev->txrate = TX_RATE_AUTO; + dev->preamble_type = preamble_type; + dev->beacon_period = 100; + dev->beacons_last_qual=jiffies_to_msecs(jiffies); + dev->auth_mode = auth_mode ? WLAN_AUTH_SHARED_KEY : + WLAN_AUTH_OPEN; + dev->scan_min_time = scan_min_time; + dev->scan_max_time = scan_max_time; + dev->scan_mode = scan_mode; + dev->monitor_scan_min_time = monitor_scan_min_time; + dev->monitor_scan_max_time = monitor_scan_max_time; + + netdev->flags &= ~IFF_MULTICAST; /* not yet or never */ + netdev->open = at76c503_open; + netdev->stop = at76c503_stop; + netdev->get_stats = at76c503_get_stats; + netdev->ethtool_ops = &at76c503_ethtool_ops; + +#if WIRELESS_EXT > 16 + /* Add pointers to enable iwspy support. */ + dev->wireless_data.spy_data = &dev->spy_data; + netdev->wireless_data = &dev->wireless_data; +#else /* WIRELESS_EXT > 16 */ + netdev->get_wireless_stats = at76c503_get_wireless_stats; +#endif /* WIRELESS_EXT > 16 */ + + netdev->hard_start_xmit = at76c503_tx; + netdev->tx_timeout = at76c503_tx_timeout; + netdev->watchdog_timeo = 2 * HZ; + netdev->wireless_handlers = + (struct iw_handler_def*)&at76c503_handler_def; + netdev->set_multicast_list = at76c503_set_multicast; + netdev->set_mac_address = at76c503_set_mac_address; + // netdev->hard_header_len = 8 + sizeof(struct ieee80211_hdr_3addr); + /* +// netdev->hard_header = at76c503_header; +*/ + + /* putting this inside rtnl_lock() - rtnl_unlock() hangs modprobe ...? */ + ret = register_netdev(dev->netdev); + if (ret) { + err("unable to register netdevice %s (status %d)!", + dev->netdev->name, ret); + return -1; + } + info("registered %s", dev->netdev->name); + dev->netdev_registered = 1; + + return 0; + + error: + at76c503_delete_device(dev); + return -1; + +} /* init_new_device */ + + +/* == PROC at76c503_get_fw_info == + disassembles the firmware image into version, str, + internal and external fw part. returns 0 on success, < 0 on error */ +static int at76c503_get_fw_info(u8 *fw_data, int fw_size, + u32 *board, u32 *version, char **str, + u8 **int_fw, int *int_fw_size, + u8 **ext_fw, int *ext_fw_size) +{ +/* fw structure (all numbers are little_endian) + offset length description + 0 4 crc 32 (seed ~0, no post, all gaps are zeros, header included) + 4 4 board type (see at76c503.h) + 8 4 version (major<<24|middle<<16|minor<<8|build) + c 4 offset of printable string (id) area from begin of image + (must be \0 terminated !) + 10 4 offset of internal fw part area + 14 4 length of internal fw part + 18 4 offset of external fw part area (may be first byte _behind_ + image in case we have no external part) + 1c 4 length of external fw part +*/ + + __le32 val; + + if (fw_size < 0x21) { + err("fw too short (x%x)",fw_size); + return -EFAULT; + } + + /* crc currently not checked */ + + memcpy(&val,fw_data+4,4); + *board = le32_to_cpu(val); + + memcpy(&val,fw_data+8,4); + *version = le32_to_cpu(val); + + memcpy(&val,fw_data+0xc,4); + *str = fw_data + le32_to_cpu(val); + + memcpy(&val,fw_data+0x10,4); + *int_fw = fw_data + le32_to_cpu(val); + memcpy(&val,fw_data+0x14,4); + *int_fw_size = le32_to_cpu(val); + + memcpy(&val,fw_data+0x18,4); + *ext_fw = fw_data + le32_to_cpu(val); + memcpy(&val,fw_data+0x1c,4); + *ext_fw_size = le32_to_cpu(val); + + return 0; +} + +/* == PROC at76c503_do_probe == */ +static int at76c503_do_probe(struct module *mod, struct usb_device *udev, + const u8 *fw_data, int fw_size, u32 board_type, + const char *netdev_name) +{ + struct usb_interface *intf = udev->actconfig->interface[0]; + int ret; + struct at76c503 *dev = NULL; + int op_mode; + char *id_str; + u32 version; + + GET_DEV(udev); + + if ((dev=alloc_new_device(udev, (u8)board_type, netdev_name)) == NULL) { + ret = -ENOMEM; + goto error; + } + + op_mode = get_op_mode(udev); + + usb_set_intfdata(intf, dev); + dev->interface = intf; + + dbg(DBG_DEVSTART, "opmode %d", op_mode); + + /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ??? + we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */ + + if (op_mode == OPMODE_HW_CONFIG_MODE) { + err("cannot handle a device in HW_CONFIG_MODE (opmode %d)", op_mode); + ret = -ENODEV; + goto error; + } + + if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH && + op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) { + + dbg(DBG_DEVSTART, "need to download firmware"); + + /* disassem. the firmware */ + if ((ret=at76c503_get_fw_info(fw_data, fw_size, &dev->board_type, + &version, &id_str, + &dev->intfw, &dev->intfw_size, + &dev->extfw, &dev->extfw_size))) { + goto error; + } + + dbg(DBG_DEVSTART, "firmware board %u version %u.%u.%u#%u " + "(int %x:%tx, ext %x:%tx)", + dev->board_type, version>>24,(version>>16)&0xff, + (version>>8)&0xff, version&0xff, + dev->intfw_size, dev->intfw-fw_data, + dev->extfw_size, dev->extfw-fw_data); + if (*id_str) + dbg(DBG_DEVSTART, "firmware id %s",id_str); + + if (dev->board_type != board_type) { + err("inconsistent board types %u != %u", + board_type, dev->board_type); + at76c503_delete_device(dev); + goto error; + } + + /* download internal firmware part */ + dbg(DBG_DEVSTART, "downloading internal firmware"); + NEW_STATE(dev,INTFW_DOWNLOAD); + defer_kevent(dev,KEVENT_INTERNAL_FW); + + } else { + /* internal firmware already inside the device */ + /* get firmware version to test if external firmware is loaded */ + /* This works only for newer firmware, e.g. the Intersil 0.90.x + says "control timeout on ep0in" and subsequent get_op_mode() fail + too :-( */ + int force_fw_dwl = 0; + + /* disassem. the firmware */ + if ((ret=at76c503_get_fw_info(fw_data, fw_size, &dev->board_type, + &version, &id_str, + &dev->intfw, &dev->intfw_size, + &dev->extfw, &dev->extfw_size))) { + goto error; + } + + /* if version >= 0.100.x.y or device with built-in flash we can query the device + * for the fw version */ + if (version >= ((0<<24)|(100<<16)) || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) { + ret = get_mib(udev, MIB_FW_VERSION, (u8*)&dev->fw_version, + sizeof(dev->fw_version)); + } else { + /* force fw download only if the device has no flash inside */ + force_fw_dwl = 1; + } + + if ((force_fw_dwl) || (ret < 0) || ((dev->fw_version.major == 0) && + (dev->fw_version.minor == 0) && + (dev->fw_version.patch == 0) && + (dev->fw_version.build == 0))) { + if (force_fw_dwl) + dbg(DBG_DEVSTART, "forced download of external firmware part"); + else + dbg(DBG_DEVSTART, "cannot get firmware (ret %d) or all zeros " + "- download external firmware", ret); + dbg(DBG_DEVSTART, "firmware board %u version %u.%u.%u#%u " + "(int %x:%tx, ext %x:%tx)", + dev->board_type, version>>24,(version>>16)&0xff, + (version>>8)&0xff, version&0xff, + dev->intfw_size, dev->intfw-fw_data, + dev->extfw_size, dev->extfw-fw_data); + if (*id_str) + dbg(DBG_DEVSTART, "firmware id %s",id_str); + + if (dev->board_type != board_type) { + err("inconsistent board types %u != %u", + board_type, dev->board_type); + at76c503_delete_device(dev); + goto error; + } + + NEW_STATE(dev,EXTFW_DOWNLOAD); + defer_kevent(dev,KEVENT_EXTERNAL_FW); + } else { + NEW_STATE(dev,INIT); + if (init_new_device(dev) < 0) { + ret = -ENODEV; + goto error; + } + } + } + + SET_NETDEV_DEV(dev->netdev, &intf->dev); + return 0; + +error: + PUT_DEV(udev); + return ret; +} + + +/* Firmware names - this must be in sync with boardtype definitions */ +static struct fwentry { + const char *const fwname; + const struct firmware *fw; +} firmwares[] = { + { "" }, + { "atmel_at76c503-i3861.bin" }, + { "atmel_at76c503-i3863.bin" }, + { "atmel_at76c503-rfmd.bin" }, + { "atmel_at76c503-rfmd-acc.bin" }, + { "atmel_at76c505-rfmd.bin" }, + { "atmel_at76c505-rfmd2958.bin" }, + { "atmel_at76c505a-rfmd2958.bin" }, + { "atmel_at76c505amx-rfmd.bin" } +}; + +/* USB Device IDs supported by this driver */ + +/* at76c503-i3861 */ +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_503I 0x7603 /* Generic AT76C503/3861 device */ + +#define VENDOR_ID_LINKSYS_OLD 0x066b +#define PRODUCT_ID_LINKSYS_WUSB11_V21 0x2211 /* Linksys WUSB11 v2.1/v2.6 */ + +#define VENDOR_ID_NETGEAR 0x0864 +#define PRODUCT_ID_NETGEAR_MA101A 0x4100 /* Netgear MA 101 Rev. A */ + +#define VENDOR_ID_TEKRAM 0x0b3b +#define PRODUCT_ID_TEKRAM_U300C 0x1612 /* Tekram U-300C / Allnet ALL0193 */ + +#define VENDOR_ID_HP 0x03f0 +#define PRODUCT_ID_HP_HN210W 0x011c /* HP HN210W PKW-J7801A */ + +#define VENDOR_ID_M4Y750 0x0cde /* Unknown Vendor ID! */ +#define PRODUCT_ID_M4Y750 0x0001 /* Sitecom/Z-Com/Zyxel M4Y-750 */ + +#define VENDOR_ID_DYNALINK 0x069a +#define PRODUCT_ID_DYNALINK_WLL013_I 0x0320 /* Dynalink/Askey WLL013 (intersil) */ + +#define VENDOR_ID_SMC_OLD 0x0d5c +#define PRODUCT_ID_SMC2662W_V1 0xa001 /* EZ connect 11Mpbs +Wireless USB Adapter SMC2662W (v1) */ + +#define VENDOR_ID_BENQ 0x04a5 /* BenQ (Acer) */ +#define PRODUCT_ID_BENQ_AWL_300 0x9000 /* AWL-300 */ + +/* this adapter contains flash */ +#define VENDOR_ID_ADDTRON 0x05dd /* Addtron */ +#define PRODUCT_ID_ADDTRON_AWU120 0xff31 /* AWU-120 */ +/* also Compex WLU11 */ + +#define VENDOR_ID_INTEL 0x8086 /* Intel */ +#define PRODUCT_ID_INTEL_AP310 0x0200 /* AP310 AnyPoint II USB */ + +#define VENDOR_ID_CONCEPTRONIC 0x0d8e +#define PRODUCT_ID_CONCEPTRONIC_C11U 0x7100 /* also Dynalink L11U */ + +#define VENDOR_ID_ARESCOM 0xd8e +#define PRODUCT_ID_WL_210 0x7110 /* Arescom WL-210, + FCC id 07J-GL2411USB */ +#define VENDOR_ID_IO_DATA 0x04bb +#define PRODUCT_ID_IO_DATA_WN_B11_USB 0x0919 /* IO-DATA WN-B11/USB */ + +#define VENDOR_ID_BT 0x069a +#define PRODUCT_ID_BT_VOYAGER_1010 0x0821 /* BT Voyager 1010 */ + + +/* at76c503-i3863 */ +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_503_I3863 0x7604 /* Generic AT76C503/3863 device */ + +#define VENDOR_ID_SAMSUNG 0x055d +#define PRODUCT_ID_SAMSUNG_SWL2100U 0xa000 /* Samsung SWL-2100U */ + + +/* at76c503-rfmd */ +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_503R 0x7605 /* Generic AT76C503/RFMD device */ +#define PRODUCT_ID_W_BUDDIE_WN210 0x4102 /* AirVast W-Buddie WN210 */ + +#define VENDOR_ID_DYNALINK 0x069a +#define PRODUCT_ID_DYNALINK_WLL013_R 0x0321 /* Dynalink/Askey WLL013 (rfmd) */ + +#define VENDOR_ID_LINKSYS 0x077b +#define PRODUCT_ID_LINKSYS_WUSB11_V26 0x2219 /* Linksys WUSB11 v2.6 */ +#define PRODUCT_ID_NE_NWU11B 0x2227 /* Network Everywhere NWU11B */ + +#define VENDOR_ID_NETGEAR 0x0864 +#define PRODUCT_ID_NETGEAR_MA101B 0x4102 /* Netgear MA 101 Rev. B */ + +#define VENDOR_ID_ACTIONTEC 0x1668 +#define PRODUCT_ID_ACTIONTEC_802UAT1 0x7605 /* Actiontec 802UAT1, HWU01150-01UK */ + +#define VENDOR_ID_DLINK 0x2001 /* D-Link */ +#define PRODUCT_ID_DLINK_DWL120 0x3200 /* DWL-120 rev. E */ + +#define VENDOR_ID_DICK_SMITH_ELECTR 0x1371 /* Dick Smith Electronics */ +#define PRODUCT_ID_DSE_XH1153 0x5743 /* XH1153 802.11b USB adapter */ + /* also: CNet CNUSB611 (D) */ +#define PRODUCT_ID_WL_200U 0x0002 /* WL-200U */ + +#define VENDOR_ID_BENQ 0x04a5 /* BenQ (Acer) */ +#define PRODUCT_ID_BENQ_AWL_400 0x9001 /* BenQ AWL-400 USB stick */ + +#define VENDOR_ID_3COM 0x506 +#define PRODUCT_ID_3COM_3CRSHEW696 0xa01 /* 3COM 3CRSHEW696 */ + +#define VENDOR_ID_SIEMENS 0x681 +#define PRODUCT_ID_SIEMENS_SANTIS_WLL013 0x1b /* Siemens Santis ADSL WLAN + USB adapter WLL 013 */ + +#define VENDOR_ID_BELKIN_2 0x50d +#define PRODUCT_ID_BELKIN_F5D6050_V2 0x50 /* Belkin F5D6050, version 2 */ + +#define VENDOR_ID_BLITZ 0x07b8 +#define PRODUCT_ID_BLITZ_NETWAVE_BWU613 0xb000 /* iBlitzz, BWU613 (not *B or *SB !) */ + +#define VENDOR_ID_GIGABYTE 0x1044 +#define PRODUCT_ID_GIGABYTE_GN_WLBM101 0x8003 /* Gigabyte GN-WLBM101 */ + +#define VENDOR_ID_PLANEX 0x2019 +#define PRODUCT_ID_PLANEX_GW_US11S 0x3220 /* Planex GW-US11S */ + +#define VENDOR_ID_COMPAQ 0x049f +#define PRODUCT_ID_IPAQ_INT_WLAN 0x0032 /* internal WLAN adapter in h5[4,5]xx series iPAQs */ + + +/* at76c503-rfmd-acc */ +#define VENDOR_ID_BELKIN 0x0d5c +#define PRODUCT_ID_BELKIN_F5D6050 0xa002 /* Belkin F5D6050 / SMC 2662W v2 / SMC 2662W-AR */ + +#define VENDOR_ID_SMC 0x083a +#define PRODUCT_ID_SMC_2664W 0x3501 + + +/* at76c505-rfmd */ +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_505R 0x7606 /* Generic AT76C505/RFMD device */ + + +/* at76c505-rfmd2958 */ +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_505R2958 0x7613 /* Generic AT76C505/RFMD device + also OvisLink WL-1130USB */ + +#define VENDOR_ID_CNET 0x1371 +#define PRODUCT_ID_CNET_CNUSB611G 0x0013 /* CNet CNUSB 611G */ +#define PRODUCT_ID_FL_WL240U 0x0014 /* Fiberline WL-240U with the + CNet vendor id */ + +#define VENDOR_ID_LINKSYS_1915 0x1915 +#define PRODUCT_ID_LINKSYS_WUSB11V28 0x2233 /* Linksys WUSB11 v2.8 */ + +#define VENDOR_ID_XTERASYS 0x12fd +#define PRODUCT_ID_XTERASYS_XN_2122B 0x1001 /* Xterasys XN-2122B, also + IBlitzz BWU613B / BWU613SB */ + +#define VENDOR_ID_COREGA 0x07aa +#define PRODUCT_ID_COREGA_USB_STICK_11_KK 0x7613 /* Corega WLAN USB Stick 11 (K.K.) */ + +#define VENDOR_ID_MSI 0x0db0 +#define PRODUCT_ID_MSI_MS6978_WLAN_BOX_PC2PC 0x1020 + + +/* at76c505a-rfmd2958 */ +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_505A 0x7614 /* Generic AT76C505A device */ +#define PRODUCT_ID_ATMEL_505AS 0x7617 /* Generic AT76C505AS device */ + +#define VENDOR_ID_GIGASET 0x1690 +#define PRODUCT_ID_GIGASET_11 0x0701 + + +/* at76c505amx-rfmd */ +#define VENDOR_ID_ATMEL 0x03eb +#define PRODUCT_ID_ATMEL_505AMX 0x7615 /* Generic AT76C505AMX device */ + + +static struct usb_device_id dev_table[] = { + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503I ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_LINKSYS_OLD, PRODUCT_ID_LINKSYS_WUSB11_V21), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_NETGEAR, PRODUCT_ID_NETGEAR_MA101A ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_TEKRAM, PRODUCT_ID_TEKRAM_U300C ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_HP, PRODUCT_ID_HP_HN210W ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_M4Y750, PRODUCT_ID_M4Y750 ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_DYNALINK, PRODUCT_ID_DYNALINK_WLL013_I ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_SMC_OLD, PRODUCT_ID_SMC2662W_V1 ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_BENQ, PRODUCT_ID_BENQ_AWL_300 ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_ADDTRON, PRODUCT_ID_ADDTRON_AWU120 ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_INTEL, PRODUCT_ID_INTEL_AP310 ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_CONCEPTRONIC,PRODUCT_ID_CONCEPTRONIC_C11U), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_ARESCOM, PRODUCT_ID_WL_210), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_IO_DATA, PRODUCT_ID_IO_DATA_WN_B11_USB), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + { USB_DEVICE(VENDOR_ID_BT, PRODUCT_ID_BT_VOYAGER_1010 ), + .driver_info = BOARDTYPE_503_INTERSIL_3861 }, + + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503_I3863 ), + .driver_info = BOARDTYPE_503_INTERSIL_3863 }, + { USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG_SWL2100U), + .driver_info = BOARDTYPE_503_INTERSIL_3863 }, + + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503R ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_DYNALINK, PRODUCT_ID_DYNALINK_WLL013_R ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_LINKSYS, PRODUCT_ID_LINKSYS_WUSB11_V26), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_LINKSYS, PRODUCT_ID_NE_NWU11B ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_NETGEAR, PRODUCT_ID_NETGEAR_MA101B ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_DLINK, PRODUCT_ID_DLINK_DWL120 ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_ACTIONTEC,PRODUCT_ID_ACTIONTEC_802UAT1 ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_W_BUDDIE_WN210 ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_DICK_SMITH_ELECTR, PRODUCT_ID_DSE_XH1153), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_DICK_SMITH_ELECTR, PRODUCT_ID_WL_200U), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_BENQ, PRODUCT_ID_BENQ_AWL_400), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_3COM, PRODUCT_ID_3COM_3CRSHEW696), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_SIEMENS, PRODUCT_ID_SIEMENS_SANTIS_WLL013), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_BELKIN_2, PRODUCT_ID_BELKIN_F5D6050_V2 ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_BLITZ, PRODUCT_ID_BLITZ_NETWAVE_BWU613 ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_GIGABYTE, PRODUCT_ID_GIGABYTE_GN_WLBM101 ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_PLANEX, PRODUCT_ID_PLANEX_GW_US11S ), + .driver_info = BOARDTYPE_503_RFMD }, + { USB_DEVICE(VENDOR_ID_COMPAQ, PRODUCT_ID_IPAQ_INT_WLAN), + .driver_info = BOARDTYPE_503_RFMD }, + + { USB_DEVICE(VENDOR_ID_SMC, PRODUCT_ID_SMC_2664W), + .driver_info = BOARDTYPE_503_RFMD_ACC }, + { USB_DEVICE(VENDOR_ID_BELKIN, PRODUCT_ID_BELKIN_F5D6050 ), + .driver_info = BOARDTYPE_503_RFMD_ACC }, + + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505R ), + .driver_info = BOARDTYPE_505_RFMD }, + + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505R2958 ), + .driver_info = BOARDTYPE_505_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_CNET, PRODUCT_ID_FL_WL240U ), + .driver_info = BOARDTYPE_505_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_CNET, PRODUCT_ID_CNET_CNUSB611G ), + .driver_info = BOARDTYPE_505_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_LINKSYS_1915, PRODUCT_ID_LINKSYS_WUSB11V28 ), + .driver_info = BOARDTYPE_505_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_XTERASYS, PRODUCT_ID_XTERASYS_XN_2122B ), + .driver_info = BOARDTYPE_505_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_COREGA, PRODUCT_ID_COREGA_USB_STICK_11_KK ), + .driver_info = BOARDTYPE_505_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_MSI, PRODUCT_ID_MSI_MS6978_WLAN_BOX_PC2PC), + .driver_info = BOARDTYPE_505_RFMD_2958 }, + + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505A ), + .driver_info = BOARDTYPE_505A_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505AS ), + .driver_info = BOARDTYPE_505A_RFMD_2958 }, + { USB_DEVICE(VENDOR_ID_GIGASET, PRODUCT_ID_GIGASET_11 ), + .driver_info = BOARDTYPE_505A_RFMD_2958 }, + + { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505AMX ), + .driver_info = BOARDTYPE_505AMX_RFMD }, + + { } +}; + +MODULE_DEVICE_TABLE (usb, dev_table); + + +static int at76c50x_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + int retval; + + struct usb_device *udev; + int boardtype = (int)id->driver_info; + const char *const fw_name = firmwares[boardtype].fwname; + const struct firmware *fw = firmwares[boardtype].fw; + udev = interface_to_usbdev(interface); + + if (fw == NULL) { + dbg(DBG_FW, "downloading firmware %s", fw_name); + retval = request_firmware(&fw, fw_name, &udev->dev); + if (retval == 0) { + dbg(DBG_FW, "got it."); + } else { + err("firmware %s not found.", fw_name); + err("You may need to download the firmware from " + "https://developer.berlios.de/projects/at76c503a/"); + return retval; + } + } else + dbg(DBG_FW, "re-using previously loaded fw"); + + retval = at76c503_do_probe(THIS_MODULE, udev, + fw->data, fw->size, + boardtype, netdev_name); + return retval; +} + +static void at76c50x_disconnect(struct usb_interface *interface) +{ + struct at76c503 *ptr; + + ptr = usb_get_intfdata (interface); + usb_set_intfdata(interface, NULL); + + info("%s disconnecting", ((struct at76c503 *)ptr)->netdev->name); + at76c503_delete_device(ptr); + info(DRIVER_NAME " disconnected"); +} + +/* structure for registering this driver with the USB subsystem */ +static struct usb_driver module_usb = { +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) + .owner = THIS_MODULE, +#endif + .name = DRIVER_NAME, + .probe = at76c50x_probe, + .disconnect = at76c50x_disconnect, + .id_table = dev_table, +}; + + +static int __init mod_init(void) +{ + int result; + + info(DRIVER_DESC " " DRIVER_VERSION " loading"); + +#ifdef CONFIG_IPAQ_HANDHELD + if (machine_is_h5400()) { + /* turn WLAN power on */ + /* both needed? */ + SET_H5400_ASIC_GPIO (GPB, RF_POWER_ON, 1); + SET_H5400_ASIC_GPIO (GPB, WLAN_POWER_ON, 1); + } +#endif + + /* register this driver with the USB subsystem */ + result = usb_register(&module_usb); + if (result < 0) { + err("usb_register failed (status %d)", result); + return -1; + } + + return 0; +} + +static void __exit mod_exit(void) +{ + int i; + + info(DRIVER_DESC " " DRIVER_VERSION " unloading"); + usb_deregister(&module_usb); + for (i = 0; i < ARRAY_SIZE(firmwares); i++) { + if (firmwares[i].fw) + release_firmware(firmwares[i].fw); + } + +#ifdef CONFIG_IPAQ_HANDHELD + if (machine_is_h5400()) { + /* turn WLAN power off */ + SET_H5400_ASIC_GPIO (GPB, RF_POWER_ON, 0); + SET_H5400_ASIC_GPIO (GPB, WLAN_POWER_ON, 0); + } +#endif +} + +module_init(mod_init); +module_exit(mod_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/misc/wireless/at76/at76_usbdfu.c +++ linux-2.6.28/ubuntu/misc/wireless/at76/at76_usbdfu.c @@ -0,0 +1,315 @@ +/* -*- linux-c -*- */ +/* + * USB Device Firmware Upgrade (DFU) handler + * + * Copyright (c) 2003 Oliver Kurth + * Copyright (c) 2004 Jörg Albert + * + * This file is part of the driver for WLAN USB devices based on the Atmel + * AT76C503A/505/505A. See at76c503.h for 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; either version 2 of + * the License, or (at your option) any later version. + * + * 2003_01_19 0.1: + * - initial release + * + * TODO: + * (someday) + * - make a way for drivers to feed firmware data at download time (instead of + * providing it all at once during register) + * - procfs support for userland firmware downloaders + * - Firmware upload (device-to-host) support + */ + +#include +#include +#include "at76c503.h" + +/* DFU states */ + +#define STATE_IDLE 0x00 +#define STATE_DETACH 0x01 +#define STATE_DFU_IDLE 0x02 +#define STATE_DFU_DOWNLOAD_SYNC 0x03 +#define STATE_DFU_DOWNLOAD_BUSY 0x04 +#define STATE_DFU_DOWNLOAD_IDLE 0x05 +#define STATE_DFU_MANIFEST_SYNC 0x06 +#define STATE_DFU_MANIFEST 0x07 +#define STATE_DFU_MANIFEST_WAIT_RESET 0x08 +#define STATE_DFU_UPLOAD_IDLE 0x09 +#define STATE_DFU_ERROR 0x0a + +/* DFU commands */ +#define DFU_DETACH 0 +#define DFU_DNLOAD 1 +#define DFU_UPLOAD 2 +#define DFU_GETSTATUS 3 +#define DFU_CLRSTATUS 4 +#define DFU_GETSTATE 5 +#define DFU_ABORT 6 + +struct dfu_status { + unsigned char bStatus; + unsigned char bwPollTimeout[3]; + unsigned char bState; + unsigned char iString; +} __attribute__ ((packed)); + + +/* driver independent download context */ +struct dfu_ctx { + struct usb_device *udev; + u8 dfu_state; + struct dfu_status dfu_status; + u8 *buf; +}; + +#define USB_SUCCESS(a) ((a) >= 0) + +#define DFU_PACKETSIZE 1024 + +static +int dfu_download_block(struct dfu_ctx *ctx, u8 *buffer, + int bytes, int block) +{ + int result; + u8 *tmpbuf = ctx->buf; + struct usb_device *udev = ctx->udev; + + dbg(DBG_DFU, "dfu_download_block(): buffer=%p, bytes=%d, block=%d", buffer, bytes, block); + + if(tmpbuf == NULL) + return -ENOMEM; + + memcpy(tmpbuf, buffer, bytes); + + result = usb_control_msg(udev, usb_sndctrlpipe(udev,0), + DFU_DNLOAD, + USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE, + block, /* Value */ + 0, /* Index */ + tmpbuf, /* Buffer */ + bytes, /* Size */ + HZ); + return result; +} + +static +int dfu_get_status(struct dfu_ctx *ctx, struct dfu_status *status) +{ + int result; + struct usb_device *udev = ctx->udev; + +// dbg(DBG_DFU, "dfu_get_status()"); + + result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + DFU_GETSTATUS, + USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + 0, /* Value */ + 0, /* Index */ + status, /* Buffer */ + sizeof(struct dfu_status), /* Size */ + HZ); + + return result; +} + +static +u8 dfu_get_state(struct usb_device *udev, u8 *state) +{ + int result; + +// dbg(DBG_DFU, "dfu_get_state()"); + + result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + DFU_GETSTATE, /* Request */ + USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE, + 0, /* Value */ + 0, /* Index */ + state, /* Buffer */ + 1, /* Size */ + HZ); + + return result; +} + +static inline +u32 __get_timeout(struct dfu_status *s) +{ + unsigned long ret = 0; + + ret = (unsigned long) (s->bwPollTimeout[2] << 16); + ret |= (unsigned long) (s->bwPollTimeout[1] << 8); + ret |= (unsigned long) (s->bwPollTimeout[0]); + + return ret; +} + +static +struct dfu_ctx *dfu_alloc_ctx(struct usb_device *udev) +{ + struct dfu_ctx *ctx; + + ctx = kmalloc(sizeof(struct dfu_ctx) + DFU_PACKETSIZE, GFP_KERNEL|GFP_DMA); + if(ctx){ + ctx->udev = udev; + ctx->buf = (u8 *)&(ctx[1]); + } + return ctx; +} + +/* == PROC usbdfu_download == + if manifest_sync_timeout > 0 use this timeout (in msec) instead of the + one reported by the device in state MANIFEST_SYNC */ +int usbdfu_download(struct usb_device *udev, u8 *dfu_buffer, u32 dfu_len, + int manifest_sync_timeout) +{ + struct dfu_ctx *ctx; + struct dfu_status *dfu_stat_buf; + int status = 0; + int need_dfu_state = 1; + int is_done = 0; + u8 dfu_state = 0; + u32 dfu_timeout = 0; + int dfu_block_bytes = 0, dfu_bytes_left = dfu_len, dfu_buffer_offset = 0; + int dfu_block_cnt = 0; + + dbg(DBG_DFU, "%s( %p, %u, %d)", __FUNCTION__, dfu_buffer, + dfu_len, manifest_sync_timeout); + + if (dfu_len == 0) { + err("FW Buffer length invalid!"); + return -EINVAL; + } + + ctx = dfu_alloc_ctx(udev); + if(ctx == NULL) + return -ENOMEM; + + dfu_stat_buf = &ctx->dfu_status; + + do { + if (need_dfu_state) { + status = dfu_get_state(ctx->udev, &ctx->dfu_state); + if (!USB_SUCCESS(status)) { + err("DFU: Failed to get DFU state: %d", status); + goto exit; + } + dfu_state = ctx->dfu_state; + need_dfu_state = 0; + } + + switch (dfu_state) { + case STATE_DFU_DOWNLOAD_SYNC: + dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC"); + status = dfu_get_status(ctx, dfu_stat_buf); + if (USB_SUCCESS(status)) { + dfu_state = dfu_stat_buf->bState; + dfu_timeout = __get_timeout(dfu_stat_buf); + need_dfu_state = 0; + } else + err("dfu_get_status failed with %d", status); + break; + + case STATE_DFU_DOWNLOAD_BUSY: + dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY"); + need_dfu_state = 1; + + if (dfu_timeout >= 0){ + dbg(DBG_DFU, "DFU: Resetting device"); + set_current_state( TASK_INTERRUPTIBLE ); + schedule_timeout(1+dfu_timeout*HZ/1000); + }else + dbg(DBG_DFU, "DFU: In progress"); + + break; + + case STATE_DFU_DOWNLOAD_IDLE: + dbg(DBG_DFU, "DOWNLOAD..."); + /* fall through */ + case STATE_DFU_IDLE: + dbg(DBG_DFU, "DFU IDLE"); + + if (dfu_bytes_left <= DFU_PACKETSIZE) + dfu_block_bytes = dfu_bytes_left; + else + dfu_block_bytes = DFU_PACKETSIZE; + + dfu_bytes_left -= dfu_block_bytes; + status = dfu_download_block(ctx, + dfu_buffer + + dfu_buffer_offset, + dfu_block_bytes, + dfu_block_cnt); + dfu_buffer_offset += dfu_block_bytes; + dfu_block_cnt++; + + if (!USB_SUCCESS(status)) + err("dfu_download_block failed with %d", status); + need_dfu_state = 1; + break; + + case STATE_DFU_MANIFEST_SYNC: + dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC"); + + status = dfu_get_status(ctx, dfu_stat_buf); + + if (USB_SUCCESS(status)) { + dfu_state = dfu_stat_buf->bState; + dfu_timeout = __get_timeout(dfu_stat_buf); + need_dfu_state = 0; + + /* override the timeout from the status response, + needed for AT76C505A */ + if (manifest_sync_timeout > 0) + dfu_timeout = manifest_sync_timeout; + + if (dfu_timeout >= 0){ + dbg(DBG_DFU, "DFU: Waiting for manifest phase"); + + set_current_state( TASK_INTERRUPTIBLE ); + schedule_timeout((dfu_timeout*HZ+999)/1000); + }else + dbg(DBG_DFU, "DFU: In progress"); + } + break; + + case STATE_DFU_MANIFEST: + dbg(DBG_DFU, "STATE_DFU_MANIFEST"); + is_done = 1; + break; + + case STATE_DFU_MANIFEST_WAIT_RESET: + dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET"); +// usb_reset_device(udev); + is_done = 1; + break; + + case STATE_DFU_UPLOAD_IDLE: + dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE"); + break; + + case STATE_DFU_ERROR: + dbg(DBG_DFU, "STATE_DFU_ERROR"); +// usb_reset_device(udev); + status = -EPIPE; + break; + + default: + dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state); + status = -EINVAL; + break; + } + } while (!is_done && USB_SUCCESS(status)); + + exit: + kfree(ctx); + if (status < 0) + return status; + else + return 0; +} + --- linux-2.6.28.orig/ubuntu/misc/wireless/at76/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/at76/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_WIRELESS_AT76) += at76_usb.o + +at76_usb-objs := at76c503.o at76_usbdfu.o --- linux-2.6.28.orig/ubuntu/misc/wireless/at76/at76c503.h +++ linux-2.6.28/ubuntu/misc/wireless/at76/at76c503.h @@ -0,0 +1,729 @@ +/* -*- linux-c -*- */ +/* + * Copyright (c) 2002 - 2003 Oliver Kurth + * (c) 2003 - 2004 Jörg Albert + * + * 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 driver was based on information from the Sourceforge driver + * released and maintained by Atmel: + * + * http://sourceforge.net/projects/atmelwlandriver/ + * + * Although the code was completely re-written, + * it would have been impossible without Atmel's decision to + * release an Open Source driver (unfortunately the firmware was + * kept binary only). Thanks for that decision to Atmel! + * + * For the latest version of this driver, mailinglists + * and other info, please check + * http://at76c503a.berlios.de/ + */ + +#ifndef _AT76C503_H +#define _AT76C503_H + +#include + +/* current driver version */ +#define DRIVER_VERSION "0.14beta1" + + +/* our private ioctl's */ +/* set preamble length*/ +#define PRIV_IOCTL_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0x0) +/* set debug parameter */ +#define PRIV_IOCTL_SET_DEBUG (SIOCIWFIRSTPRIV + 0x2) +/* set power save mode (incl. the Atmel proprietary smart save mode */ +#define PRIV_IOCTL_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 0x4) +/* set min and max channel times for scan */ +#define PRIV_IOCTL_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 0x6) +/* set scan mode */ +#define PRIV_IOCTL_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 0x8) +/* set international roaming */ +#define PRIV_IOCTL_SET_INTL_ROAMING (SIOCIWFIRSTPRIV + 0x10) +/* set monitor mode */ +#define PRIV_IOCTL_SET_MONITOR_MODE (SIOCIWFIRSTPRIV + 0x12) + +#define DEVICE_VENDOR_REQUEST_OUT 0x40 +#define DEVICE_VENDOR_REQUEST_IN 0xc0 +#define INTERFACE_VENDOR_REQUEST_OUT 0x41 +#define INTERFACE_VENDOR_REQUEST_IN 0xc1 +#define CLASS_REQUEST_OUT 0x21 +#define CLASS_REQUEST_IN 0xa1 + +#define CMD_STATUS_IDLE 0x00 +#define CMD_STATUS_COMPLETE 0x01 +#define CMD_STATUS_UNKNOWN 0x02 +#define CMD_STATUS_INVALID_PARAMETER 0x03 +#define CMD_STATUS_FUNCTION_NOT_SUPPORTED 0x04 +#define CMD_STATUS_TIME_OUT 0x07 +#define CMD_STATUS_IN_PROGRESS 0x08 +#define CMD_STATUS_HOST_FAILURE 0xff +#define CMD_STATUS_SCAN_FAILED 0xf0 + +/* answers to get op mode */ +#define OPMODE_NONE 0x00 +#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01 +#define OPMODE_HW_CONFIG_MODE 0x02 +#define OPMODE_DFU_MODE_WITH_FLASH 0x03 +#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04 + +#define CMD_SET_MIB 0x01 +#define CMD_GET_MIB 0x02 +#define CMD_SCAN 0x03 +#define CMD_JOIN 0x04 +#define CMD_START_IBSS 0x05 +#define CMD_RADIO 0x06 +#define CMD_STARTUP 0x0B +#define CMD_GETOPMODE 0x33 + +#define MIB_LOCAL 0x01 +#define MIB_MAC_ADD 0x02 +#define MIB_MAC 0x03 +#define MIB_MAC_MGMT 0x05 +#define MIB_MAC_WEP 0x06 +#define MIB_PHY 0x07 +#define MIB_FW_VERSION 0x08 +#define MIB_MDOMAIN 0x09 + +#define ADHOC_MODE 1 +#define INFRASTRUCTURE_MODE 2 + +/* values for struct mib_local, field preamble_type */ +#define PREAMBLE_TYPE_SHORT 1 +#define PREAMBLE_TYPE_LONG 0 + +/* values for tx_rate */ +#define TX_RATE_1MBIT 0 +#define TX_RATE_2MBIT 1 +#define TX_RATE_5_5MBIT 2 +#define TX_RATE_11MBIT 3 +#define TX_RATE_AUTO 4 + +/* power management modes */ +#define PM_ACTIVE 1 +#define PM_SAVE 2 +#define PM_SMART_SAVE 3 + +/* international roaming state */ +#define IR_OFF 0 +#define IR_ON 1 + +/* monitor mode - param of private ioctl */ +#define MM_OFF 0 +#define MM_ON 1 +#define MM_ON_NO_PRISM 2 + + +/* offsets into the MIBs we use to configure the device */ +#define TX_AUTORATE_FALLBACK_OFFSET offsetof(struct mib_local,txautorate_fallback) +#define FRAGMENTATION_OFFSET offsetof(struct mib_mac,frag_threshold) +#define PREAMBLE_TYPE_OFFSET offsetof(struct mib_local,preamble_type) +#define RTS_OFFSET offsetof(struct mib_mac, rts_threshold) + +/* valid only for rfmd and 505 !*/ +#define IBSS_CHANGE_OK_OFFSET offsetof(struct mib_mac_mgmt, ibss_change) +#define IROAMING_IMPL_OFFSET offsetof(struct mib_mac_mgmt, multi_domain_capability_implemented) +#define IROAMING_OFFSET \ + offsetof(struct mib_mac_mgmt, multi_domain_capability_enabled) +/* the AssocID */ +#define STATION_ID_OFFSET offsetof(struct mib_mac_mgmt, station_id) +#define POWER_MGMT_MODE_OFFSET offsetof(struct mib_mac_mgmt, power_mgmt_mode) +#define LISTEN_INTERVAL_OFFSET offsetof(struct mib_mac, listen_interval) + +#define PRIVACY_OPT_IMPL offsetof(struct mib_mac_mgmt, privacy_option_implemented) + +#define BOARDTYPE_503_INTERSIL_3861 1 +#define BOARDTYPE_503_INTERSIL_3863 2 +#define BOARDTYPE_503_RFMD 3 +#define BOARDTYPE_503_RFMD_ACC 4 +#define BOARDTYPE_505_RFMD 5 +#define BOARDTYPE_505_RFMD_2958 6 +#define BOARDTYPE_505A_RFMD_2958 7 +#define BOARDTYPE_505AMX_RFMD 8 + +struct hwcfg_r505 { + u8 cr39_values[14]; + u8 reserved1[14]; + u8 bb_cr[14]; + u8 pidvid[4]; + u8 mac_addr[ETH_ALEN]; + u8 regulatory_domain; + u8 reserved2[14]; + u8 cr15_values[14]; + u8 reserved3[3]; +} __attribute__ ((packed)); + +struct hwcfg_rfmd { + u8 cr20_values[14]; + u8 cr21_values[14]; + u8 bb_cr[14]; + u8 pidvid[4]; + u8 mac_addr[ETH_ALEN]; + u8 regulatory_domain; + u8 low_power_values[14]; + u8 normal_power_values[14]; + u8 reserved1[3]; +} __attribute__ ((packed)); + +struct hwcfg_intersil { + u8 mac_addr[ETH_ALEN]; + u8 cr31_values[14]; + u8 cr58_values[14]; + u8 pidvid[4]; + u8 regulatory_domain; + u8 reserved[1]; +} __attribute__ ((packed)); + +#define WEP_SMALL_KEY_LEN (40/8) +#define WEP_LARGE_KEY_LEN (104/8) + +struct at76c503_card_config{ + u8 exclude_unencrypted; + u8 promiscuous_mode; + u8 short_retry_limit; + u8 encryption_type; + __le16 rts_threshold; + __le16 fragmentation_threshold; // 256..2346 + u8 basic_rate_set[4]; + u8 auto_rate_fallback; //0,1 + u8 channel; + u8 privacy_invoked; + u8 wep_default_key_id; // 0..3 + u8 current_ssid[32]; + u8 wep_default_key_value[4][WEP_KEY_LEN]; + u8 ssid_len; + u8 short_preamble; + __le16 beacon_period; +} __attribute__ ((packed)); + +struct at76c503_command{ + u8 cmd; + u8 reserved; + __le16 size; +} __attribute__ ((packed)); + +/* the length of the Atmel firmware specific rx header before IEEE 802.11 starts */ +#define AT76C503_RX_HDRLEN offsetof(struct at76c503_rx_buffer, packet) + +struct at76c503_rx_buffer { + __le16 wlength; + u8 rx_rate; + u8 newbss; + u8 fragmentation; + u8 rssi; + u8 link_quality; + u8 noise_level; + u8 rx_time[4]; + u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; +} __attribute__ ((packed)); + +/* the length of the Atmel firmware specific tx header before IEEE 802.11 starts */ +#define AT76C503_TX_HDRLEN offsetof(struct at76c503_tx_buffer, packet) + +struct at76c503_tx_buffer { + __le16 wlength; + u8 tx_rate; + u8 padding; + u8 reserved[4]; + u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN]; +} __attribute__ ((packed)); + +/* defines for scan_type below */ +#define SCAN_TYPE_ACTIVE 0 +#define SCAN_TYPE_PASSIVE 1 + +struct at76c503_start_scan { + u8 bssid[ETH_ALEN]; + u8 essid[32]; + u8 scan_type; + u8 channel; + __le16 probe_delay; + __le16 min_channel_time; + __le16 max_channel_time; + u8 essid_size; + u8 international_scan; +} __attribute__ ((packed)); + +struct at76c503_start_bss { + u8 bssid[ETH_ALEN]; + u8 essid[32]; + u8 bss_type; + u8 channel; + u8 essid_size; + u8 reserved[3]; +} __attribute__ ((packed)); + +struct at76c503_join { + u8 bssid[ETH_ALEN]; + u8 essid[32]; + u8 bss_type; + u8 channel; + __le16 timeout; + u8 essid_size; + u8 reserved; +} __attribute__ ((packed)); + +struct set_mib_buffer { + u8 type; + u8 size; + u8 index; + u8 reserved; + u8 data[72]; +} __attribute__ ((packed)); + +struct mib_local { + u16 reserved0; + u8 beacon_enable; + u8 txautorate_fallback; + u8 reserved1; + u8 ssid_size; + u8 promiscuous_mode; + u16 reserved2; + u8 preamble_type; + u16 reserved3; +} __attribute__ ((packed)); + +struct mib_mac_addr { + u8 mac_addr[ETH_ALEN]; + u8 res[2]; /* ??? */ + u8 group_addr[4][ETH_ALEN]; + u8 group_addr_status[4]; +} __attribute__ ((packed)); + +struct mib_mac { + __le32 max_tx_msdu_lifetime; + __le32 max_rx_lifetime; + __le16 frag_threshold; + __le16 rts_threshold; + __le16 cwmin; + __le16 cwmax; + u8 short_retry_time; + u8 long_retry_time; + u8 scan_type; /* active or passive */ + u8 scan_channel; + __le16 probe_delay; /* delay before sending a ProbeReq in active scan, RO */ + __le16 min_channel_time; + __le16 max_channel_time; + __le16 listen_interval; + u8 desired_ssid[32]; + u8 desired_bssid[ETH_ALEN]; + u8 desired_bsstype; /* ad-hoc or infrastructure */ + u8 reserved2; +} __attribute__ ((packed)); + +struct mib_mac_mgmt { + __le16 beacon_period; + __le16 CFP_max_duration; + __le16 medium_occupancy_limit; + __le16 station_id; /* assoc id */ + __le16 ATIM_window; + u8 CFP_mode; + u8 privacy_option_implemented; + u8 DTIM_period; + u8 CFP_period; + u8 current_bssid[ETH_ALEN]; + u8 current_essid[32]; + u8 current_bss_type; + u8 power_mgmt_mode; + /* rfmd and 505 */ + u8 ibss_change; + u8 res; + u8 multi_domain_capability_implemented; + u8 multi_domain_capability_enabled; + u8 country_string[3]; + u8 reserved[3]; +} __attribute__ ((packed)); + +struct mib_mac_wep { + u8 privacy_invoked; /* 0 disable encr., 1 enable encr */ + u8 wep_default_key_id; + u8 wep_key_mapping_len; + u8 exclude_unencrypted; + __le32 wep_icv_error_count; + __le32 wep_excluded_count; + u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN]; + u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */ +} __attribute__ ((packed)); + +struct mib_phy { + __le32 ed_threshold; + + __le16 slot_time; + __le16 sifs_time; + __le16 preamble_length; + __le16 plcp_header_length; + __le16 mpdu_max_length; + __le16 cca_mode_supported; + + u8 operation_rate_set[4]; + u8 channel_id; + u8 current_cca_mode; + u8 phy_type; + u8 current_reg_domain; +} __attribute__ ((packed)); + +struct mib_fw_version { + u8 major; + u8 minor; + u8 patch; + u8 build; +} __attribute__ ((packed)); + +struct mib_mdomain { + u8 tx_powerlevel[14]; + u8 channel_list[14]; /* 0 for invalid channels */ +} __attribute__ ((packed)); + +/* states in infrastructure mode */ +enum infra_state { + INIT, + SCANNING, + AUTHENTICATING, + ASSOCIATING, + REASSOCIATING, + DISASSOCIATING, + JOINING, + CONNECTED, + STARTIBSS, + INTFW_DOWNLOAD, + EXTFW_DOWNLOAD, + WAIT_FOR_DISCONNECT, + MONITORING, +}; + +/* a description of a regulatory domain and the allowed channels */ +struct reg_domain { + u16 code; + char const *name; + u32 channel_map; /* if bit N is set, channel (N+1) is allowed */ +}; + +/* how long do we keep a (I)BSS in the bss_list in jiffies + this should be long enough for the user to retrieve the table + (by iwlist ?) after the device started, because all entries from + other channels than the one the device locks on get removed, too */ +#define BSS_LIST_TIMEOUT (120*HZ) + +/* struct to store BSS info found during scan */ +#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */ + +struct bss_info{ + struct list_head list; + + u8 mac[ETH_ALEN]; /* real mac address, differs + for ad-hoc from bssid */ + u8 bssid[ETH_ALEN]; /* bssid */ + u8 ssid[IW_ESSID_MAX_SIZE+1]; /* ssid, +1 for trailing \0 + to make it printable */ + u8 ssid_len; /* length of ssid above */ + u8 channel; + u16 capa; /* the capabilities of the BSS (in original endianess - + we only check IEEE802_11 bits in it) */ + u16 beacon_interval; /* the beacon interval in units of TU (1.024 ms) + (in CPU endianess - we must calc. values from it) */ + u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates (list of bytes: + (basic_rate ? 0x80 : 0) + rate/(500 Kbit/s); e.g. + x82,x84,x8b,x96 for basic rates 1,2,5.5,11 MBit/s) */ + u8 rates_len; + + /* quality of received beacon */ + u8 rssi; + u8 link_qual; + u8 noise_level; + + unsigned long last_rx; /* time (jiffies) of last beacon received */ + u16 assoc_id; /* if this is dev->curr_bss this is the assoc id we got + in a successful AssocResponse */ +}; + +/* a rx data buffer to collect rx fragments */ +struct rx_data_buf { + u8 sender[ETH_ALEN]; /* sender address */ + u16 seqnr; /* sequence number */ + u16 fragnr; /* last fragment received */ + unsigned long last_rx; /* jiffies of last rx */ + struct sk_buff *skb; /* == NULL if entry is free */ +}; + +#define NR_RX_DATA_BUF 8 + +/* how often do we try to submit a rx urb until giving up */ +#define NR_SUBMIT_RX_TRIES 8 + +struct at76c503 { + struct usb_device *udev; /* USB device pointer */ + struct net_device *netdev; /* net device pointer */ + struct net_device_stats stats; + struct iw_statistics wstats; + struct usb_interface *interface; /* the interface for this device */ + +// unsigned char num_ports; /* the number of ports this device has */ +// char num_interrupt_in; /* number of interrupt in endpoints we have */ +// char num_bulk_in; /* number of bulk in endpoints we have */ +// char num_bulk_out; /* number of bulk out endpoints we have */ + + struct sk_buff * rx_skb; /* skbuff for receiving packets */ + __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ + + unsigned char * bulk_out_buffer; /* the buffer to send data */ + int bulk_out_size; /* the size of the send buffer */ + struct urb * write_urb; /* the urb used to send data */ + struct urb * read_urb; + __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ + +// struct work_struct tqueue; /* task queue for line discipline waking up */ + int open_count; /* number of times this port has been opened */ + struct semaphore sem; /* locks this structure */ + + + unsigned long kevent_flags; + struct work_struct kevent; + int nr_submit_rx_tries; /* number of tries to submit an rx urb left */ + struct tasklet_struct tasklet; + struct urb *rx_urb; /* tmp urb pointer for rx_tasklet */ + + unsigned char *ctrl_buffer; + struct urb *ctrl_urb; + + u8 op_mode; + + /* the WEP stuff */ + int wep_enabled; /* 1 if WEP is enabled */ + int wep_key_id; /* key id to be used */ + u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys, + 5 or 13 bytes are used */ + u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */ + + int channel; + int iw_mode; + int curr_ap; + u8 bssid[ETH_ALEN]; + u8 essid[IW_ESSID_MAX_SIZE]; + char nickn[IW_ESSID_MAX_SIZE+1]; /* nickname, only used in the iwconfig i/f */ + int essid_size; + int radio_on; + int promisc; + + int preamble_type; /* 0 - long preamble, 1 - short preamble */ + int auth_mode; /* authentication type: 0 open, 1 shared key */ + int txrate; /* 0,1,2,3 = 1,2,5.5,11 MBit, 4 is auto-fallback */ + int frag_threshold; /* threshold for fragmentation of tx packets */ + int rts_threshold; /* threshold for RTS mechanism */ + int short_retry_limit; + //int long_retry_limit; + + int scan_min_time; /* scan min channel time */ + int scan_max_time; /* scan max channel time */ + int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */ + int scan_runs; /* counts how many scans are started */ + + /* the list we got from scanning */ + spinlock_t bss_list_spinlock; /* protects bss_list operations and setting + curr_bss and new_bss */ + struct list_head bss_list; /* the list of bss we received beacons from */ + struct timer_list bss_list_timer; /* a timer removing old entries from + the bss_list. It must acquire bss_list_spinlock + before and must not remove curr_bss nor + new_bss ! */ + struct bss_info *curr_bss; /* if istate == AUTH, ASSOC, REASSOC, JOIN or CONN + dev->bss[curr_bss] is the currently selected BSS + we operate on */ + struct bss_info *new_bss; /* if istate == REASSOC dev->new_bss + is the new bss we want to reassoc to */ + + u8 wanted_bssid[ETH_ALEN]; + int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */ + + /* some data for infrastructure mode only */ + spinlock_t mgmt_spinlock; /* this spinlock protects access to + next_mgmt_bulk */ + spinlock_t istate_spinlock; /* this spinlock protects access to + istate */ + + + struct at76c503_tx_buffer *next_mgmt_bulk; /* pending management msg to + send via bulk out */ + enum infra_state istate; + enum { + SITE_SURVEY_IDLE, + SITE_SURVEY_IN_PROGRESS, + SITE_SURVEY_COMPLETED + } site_survey_state; + time_t last_survey; + + struct timer_list restart_timer; /* the timer we use to delay the restart a bit */ + + struct timer_list mgmt_timer; /* the timer we use to repeat auth_req etc. */ + int retries; /* counts backwards while re-trying to send auth/assoc_req's */ + u16 assoc_id; /* the assoc_id for states JOINING, REASSOCIATING, CONNECTED */ + u8 pm_mode ; /* power management mode: ACTIVE, SAVE, SMART_SAVE */ + u32 pm_period_us; /* power manag. period (in us ?) - set by iwconfig */ + u32 pm_period_beacon; /* power manag. period (in beacon intervals + of the curr_bss) */ + u32 board_type; /* BOARDTYPE_* defined above*/ + + struct reg_domain const *domain; /* the description of the regulatory domain */ + + /* iwspy support */ + spinlock_t spy_spinlock; + struct iw_spy_data spy_data; + +#if WIRELESS_EXT > 16 + struct iw_public_data wireless_data; +#endif /* WIRELESS_EXT > 16 */ + + /* These fields contain HW config provided by the device (not all of + * these fields are used by all board types) */ + u8 mac_addr[ETH_ALEN]; + u8 bb_cr[14]; + u8 pidvid[4]; + u8 regulatory_domain; + u8 cr15_values[14]; + u8 cr20_values[14]; + u8 cr21_values[14]; + u8 cr31_values[14]; + u8 cr39_values[14]; + u8 cr58_values[14]; + u8 low_power_values[14]; + u8 normal_power_values[14]; + + struct at76c503_card_config card_config; + struct mib_fw_version fw_version; + + int rx_data_fcs_len; /* length of the trailing FCS + (0 for fw <= 0.84.x, 4 otherwise) */ + + /* store rx fragments until complete */ + struct rx_data_buf rx_data[NR_RX_DATA_BUF]; + + /* firmware downloading stuff */ + struct timer_list fw_dl_timer; /* timer used to wait after REMAP + until device is reset */ + int extfw_size; + int intfw_size; + /* these point into a buffer managed by at76c503-xxx.o, no need to dealloc */ + u8 *extfw; /* points to external firmware part, extfw_size bytes long */ + u8 *intfw; /* points to internal firmware part, intfw_size bytes long */ + struct usb_driver *calling_driver; /* the calling driver: at76c503-{rfmd,i3861,i3863,...} */ + unsigned int device_unplugged:1; + unsigned int netdev_registered:1; + char obuf[2*256+1]; /* global debug output buffer to reduce stack usage */ + char obuf_s[3*32]; /* small global debug output buffer to reduce stack usage */ + struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */ + + /* new whiz-bang feature flags */ + int international_roaming; + int monitor_prism_header; /* if iw_mode == IW_MODE_MONITOR, + use Prism header */ + int monitor_scan_min_time; + int monitor_scan_max_time; + + int beacon_period; /* period of mgmt beacons */ + int beacons_received; + unsigned long beacons_last_qual; /* last time we reset beacons_received = 0 */ +}; + +/* Quasi-monitor mode defs (copied from /drivers/net/wireless/orinoco.h) */ + +/* message data item for INT, BOUNDEDINT, ENUMINT */ +typedef struct p80211item_uint32 +{ + uint32_t did __attribute__ ((packed)); + uint16_t status __attribute__ ((packed)); + uint16_t len __attribute__ ((packed)); + uint32_t data __attribute__ ((packed)); +} __attribute__ ((packed)) p80211item_uint32_t; + +typedef struct p80211msg +{ + uint32_t msgcode __attribute__ ((packed)); + uint32_t msglen __attribute__ ((packed)); + uint8_t devname[IFNAMSIZ]; +} __attribute__ ((packed)) p80211msg_t; + +#define P80211ENUM_msgitem_status_data_ok 0 +#define P80211ENUM_msgitem_status_no_value 1 +#define P80211ENUM_truth_false 0 +#define P80211ENUM_truth_true 1 + +#define DIDmsg_lnxind_wlansniffrm 0x0041 +#define DIDmsg_lnxind_wlansniffrm_hosttime 0x1041 +#define DIDmsg_lnxind_wlansniffrm_mactime 0x2041 +#define DIDmsg_lnxind_wlansniffrm_channel 0x3041 +#define DIDmsg_lnxind_wlansniffrm_rssi 0x4041 +#define DIDmsg_lnxind_wlansniffrm_sq 0x5041 +#define DIDmsg_lnxind_wlansniffrm_signal 0x6041 +#define DIDmsg_lnxind_wlansniffrm_noise 0x7041 +#define DIDmsg_lnxind_wlansniffrm_rate 0x8041 +#define DIDmsg_lnxind_wlansniffrm_istx 0x9041 +#define DIDmsg_lnxind_wlansniffrm_frmlen 0xA041 + +typedef struct p80211msg_lnxind_wlansniffrm +{ + uint32_t msgcode; + uint32_t msglen; + uint8_t devname[IFNAMSIZ]; + p80211item_uint32_t hosttime; + p80211item_uint32_t mactime; + p80211item_uint32_t channel; + p80211item_uint32_t rssi; + p80211item_uint32_t sq; + p80211item_uint32_t signal; + p80211item_uint32_t noise; + p80211item_uint32_t rate; + p80211item_uint32_t istx; + p80211item_uint32_t frmlen; +} __attribute__ ((packed)) p80211msg_lnxind_wlansniffrm_t; + +/* at76_debug bits */ +#define DBG_PROGRESS 0x00000001 /* progress of scan-join-(auth-assoc)-connected */ +#define DBG_BSS_TABLE 0x00000002 /* show the bss table after scans */ +#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */ +#define DBG_KEVENT 0x00000008 /* kevents */ +#define DBG_TX_DATA 0x00000010 /* tx header */ +#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */ +#define DBG_TX_MGMT 0x00000040 +#define DBG_RX_DATA 0x00000080 /* rx data header */ +#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */ +#define DBG_RX_MGMT 0x00000200 /* rx mgmt header except beacon and probe responses */ +#define DBG_RX_BEACON 0x00000400 /* rx beacon */ +#define DBG_RX_CTRL 0x00000800 /* rx control */ +#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */ +#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */ +#define DBG_DEVSTART 0x00004000 /* fw download, device start */ +#define DBG_URB 0x00008000 /* rx urb status, ... */ +#define DBG_RX_ATMEL_HDR 0x00010000 /* the Atmel specific header of each rx packet */ +#define DBG_PROC_ENTRY 0x00020000 /* procedure entries and exits */ +#define DBG_PM 0x00040000 /* power management settings */ +#define DBG_BSS_MATCH 0x00080000 /* show why a certain bss did not match */ +#define DBG_PARAMS 0x00100000 /* show the configured parameters */ +#define DBG_WAIT_COMPLETE 0x00200000 /* show the wait_completion progress */ +#define DBG_RX_FRAGS_SKB 0x00400000 /* show skb header for incoming rx fragments */ +#define DBG_BSS_TABLE_RM 0x00800000 /* inform on removal of old bss table entries */ +#define DBG_MONITOR_MODE 0x01000000 /* debugs from monitor mode */ +#define DBG_MIB 0x02000000 /* dump all MIBs in startup_device */ +#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */ +#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */ +#define DBG_FW 0x10000000 /* firmware download */ +#define DBG_DFU 0x20000000 /* device firmware upgrade */ + +#define DBG_DEFAULTS 0 +extern int at76_debug; + +/* Use our own dbg macro */ +#undef dbg +#define dbg(bits, format, arg...) \ + do { \ + if (at76_debug & (bits)) \ + printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg);\ + } while (0) + +int usbdfu_download(struct usb_device *udev, u8 *fw_buf, u32 fw_len, + int manifest_sync_timeout); + +#endif /* _AT76C503_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211conv.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211conv.c @@ -0,0 +1,691 @@ +/* src/p80211/p80211conv.c +* +* Ether/802.11 conversions and packet buffer routines +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file defines the functions that perform Ethernet to/from +* 802.11 frame conversions. +* +* -------------------------------------------------------------------- +*/ +/*================================================================*/ +/* System Includes */ + +#define __NO_VERSION__ /* prevent the static definition */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +/*================================================================*/ +/* Local Constants */ + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + +static UINT8 oui_rfc1042[] = {0x00, 0x00, 0x00}; +static UINT8 oui_8021h[] = {0x00, 0x00, 0xf8}; + +/*================================================================*/ +/* Local Function Declarations */ + + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* p80211pb_ether_to_80211 +* +* Uses the contents of the ether frame and the etherconv setting +* to build the elements of the 802.11 frame. +* +* We don't actually set +* up the frame header here. That's the MAC's job. We're only handling +* conversion of DIXII or 802.3+LLC frames to something that works +* with 802.11. +* +* Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11 +* FCS is also not present and will need to be added elsewhere. +* +* Arguments: +* ethconv Conversion type to perform +* skb skbuff containing the ether frame +* p80211_hdr 802.11 header +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int skb_ether_to_p80211( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep) +{ + + UINT16 fc; + UINT16 proto; + wlan_ethhdr_t e_hdr; + wlan_llc_t *e_llc; + wlan_snap_t *e_snap; + int foo; + + DBFENTER; + memcpy(&e_hdr, skb->data, sizeof(e_hdr)); + + if (skb->len <= 0) { + WLAN_LOG_DEBUG(1, "zero-length skb!\n"); + return 1; + } + + if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */ + WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len); + /* here, we don't care what kind of ether frm. Just stick it */ + /* in the 80211 payload */ + /* which is to say, leave the skb alone. */ + } else { + /* step 1: classify ether frame, DIX or 802.3? */ + proto = ntohs(e_hdr.type); + if ( proto <= 1500 ) { + WLAN_LOG_DEBUG(3, "802.3 len: %d\n", skb->len); + /* codes <= 1500 reserved for 802.3 lengths */ + /* it's 802.3, pass ether payload unchanged, */ + + /* trim off ethernet header */ + skb_pull(skb, WLAN_ETHHDR_LEN); + + /* leave off any PAD octets. */ + skb_trim(skb, proto); + } else { + WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len); + /* it's DIXII, time for some conversion */ + + /* trim off ethernet header */ + skb_pull(skb, WLAN_ETHHDR_LEN); + + /* tack on SNAP */ + e_snap = (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t)); + e_snap->type = htons(proto); + if ( ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto) ) { + memcpy( e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN); + } else { + memcpy( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN); + } + + /* tack on llc */ + e_llc = (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t)); + e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */ + e_llc->ssap = 0xAA; + e_llc->ctl = 0x03; + + } + } + + /* Set up the 802.11 header */ + /* It's a data frame */ + fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY)); + + switch ( wlandev->macmode ) { + case WLAN_MACMODE_IBSS_STA: + memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a3, wlandev->bssid, WLAN_ADDR_LEN); + break; + case WLAN_MACMODE_ESS_STA: + fc |= host2ieee16(WLAN_SET_FC_TODS(1)); + memcpy(p80211_hdr->a3.a1, wlandev->bssid, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, WLAN_ADDR_LEN); + break; + case WLAN_MACMODE_ESS_AP: + fc |= host2ieee16(WLAN_SET_FC_FROMDS(1)); + memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a2, wlandev->bssid, WLAN_ADDR_LEN); + memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, WLAN_ADDR_LEN); + break; + default: + WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n"); + return 1; + break; + } + + p80211_wep->data = NULL; + + if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) { + // XXXX need to pick keynum other than default? + +#if 1 + p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); +#else + p80211_wep->data = skb->data; +#endif + + if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, + skb->len, + (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK), + p80211_wep->iv, p80211_wep->icv))) { + WLAN_LOG_WARNING("Host en-WEP failed, dropping frame (%d).\n", foo); + return 2; + } + fc |= host2ieee16(WLAN_SET_FC_ISWEP(1)); + } + + + // skb->nh.raw = skb->data; + + p80211_hdr->a3.fc = fc; + p80211_hdr->a3.dur = 0; + p80211_hdr->a3.seq = 0; + + DBFEXIT; + return 0; +} + +/* jkriegl: from orinoco, modified */ +static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac, + p80211_rxmeta_t *rxmeta) +{ + int i; + + /* Gather wireless spy statistics: for each packet, compare the + * source address with out list, and if match, get the stats... */ + + for (i = 0; i < wlandev->spy_number; i++) { + + if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) { + memcpy(wlandev->spy_address[i], mac, ETH_ALEN); + wlandev->spy_stat[i].level = rxmeta->signal; + wlandev->spy_stat[i].noise = rxmeta->noise; + wlandev->spy_stat[i].qual = (rxmeta->signal > rxmeta->noise) ? \ + (rxmeta->signal - rxmeta->noise) : 0; + wlandev->spy_stat[i].updated = 0x7; + } + } +} + +/*---------------------------------------------------------------- +* p80211pb_80211_to_ether +* +* Uses the contents of a received 802.11 frame and the etherconv +* setting to build an ether frame. +* +* This function extracts the src and dest address from the 802.11 +* frame to use in the construction of the eth frame. +* +* Arguments: +* ethconv Conversion type to perform +* skb Packet buffer containing the 802.11 frame +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int skb_p80211_to_ether( wlandevice_t *wlandev, UINT32 ethconv, struct sk_buff *skb) +{ + netdevice_t *netdev = wlandev->netdev; + UINT16 fc; + UINT payload_length; + UINT payload_offset; + UINT8 daddr[WLAN_ETHADDR_LEN]; + UINT8 saddr[WLAN_ETHADDR_LEN]; + p80211_hdr_t *w_hdr; + wlan_ethhdr_t *e_hdr; + wlan_llc_t *e_llc; + wlan_snap_t *e_snap; + + int foo; + + DBFENTER; + + payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN; + payload_offset = WLAN_HDR_A3_LEN; + + w_hdr = (p80211_hdr_t *) skb->data; + + /* setup some vars for convenience */ + fc = ieee2host16(w_hdr->a3.fc); + if ( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0) ) { + memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN); + } else if( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1) ) { + memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN); + } else if( (WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0) ) { + memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN); + } else { + payload_offset = WLAN_HDR_A4_LEN; + payload_length -= ( WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN ); + if (payload_length < 0 ) { + WLAN_LOG_ERROR("A4 frame too short!\n"); + return 1; + } + memcpy(daddr, w_hdr->a4.a3, WLAN_ETHADDR_LEN); + memcpy(saddr, w_hdr->a4.a4, WLAN_ETHADDR_LEN); + } + + /* perform de-wep if necessary.. */ + if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) { + if (payload_length <= 8) { + WLAN_LOG_ERROR("WEP frame too short (%u).\n", + skb->len); + return 1; + } + if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4, + payload_length - 8, -1, + skb->data + payload_offset, + skb->data + payload_offset + payload_length - 4))) { + /* de-wep failed, drop skb. */ + WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo); + wlandev->rx.decrypt_err++; + return 2; + } + + /* subtract the IV+ICV length off the payload */ + payload_length -= 8; + /* chop off the IV */ + skb_pull(skb, 4); + /* chop off the ICV. */ + skb_trim(skb, skb->len - 4); + + wlandev->rx.decrypt++; + } + + e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset); + + e_llc = (wlan_llc_t *) (skb->data + payload_offset); + e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t)); + + /* Test for the various encodings */ + if ( (payload_length >= sizeof(wlan_ethhdr_t)) && + ( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) && + ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) || + (memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) { + WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length); + /* 802.3 Encapsulated */ + /* Test for an overlength frame */ + if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) { + /* A bogus length ethfrm has been encap'd. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n", + payload_length, netdev->mtu + WLAN_ETHHDR_LEN); + return 1; + } + + /* Chop off the 802.11 header. it's already sane. */ + skb_pull(skb, payload_offset); + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + + } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) && + (e_llc->dsap == 0xaa) && + (e_llc->ssap == 0xaa) && + (e_llc->ctl == 0x03) && + (((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) && + (ethconv == WLAN_ETHCONV_8021h) && + (p80211_stt_findproto(ieee2host16(e_snap->type)))) || + (memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0))) + { + WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length); + /* it's a SNAP + RFC1042 frame && protocol is in STT */ + /* build 802.3 + RFC1042 */ + + /* Test for an overlength frame */ + if ( payload_length > netdev->mtu ) { + /* A bogus length ethfrm has been sent. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n", + payload_length, netdev->mtu); + return 1; + } + + /* chop 802.11 header from skb. */ + skb_pull(skb, payload_offset); + + /* create 802.3 header at beginning of skb. */ + e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN); + memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN); + memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); + e_hdr->type = htons(payload_length); + + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + + } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) && + (e_llc->dsap == 0xaa) && + (e_llc->ssap == 0xaa) && + (e_llc->ctl == 0x03) ) { + WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length); + /* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */ + /* build a DIXII + RFC894 */ + + /* Test for an overlength frame */ + if ((payload_length - sizeof(wlan_llc_t) - sizeof(wlan_snap_t)) + > netdev->mtu) { + /* A bogus length ethfrm has been sent. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n", + (long int) (payload_length - sizeof(wlan_llc_t) - + sizeof(wlan_snap_t)), + netdev->mtu); + return 1; + } + + /* chop 802.11 header from skb. */ + skb_pull(skb, payload_offset); + + /* chop llc header from skb. */ + skb_pull(skb, sizeof(wlan_llc_t)); + + /* chop snap header from skb. */ + skb_pull(skb, sizeof(wlan_snap_t)); + + /* create 802.3 header at beginning of skb. */ + e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN); + e_hdr->type = e_snap->type; + memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN); + memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); + + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + } else { + WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length); + /* any NON-ENCAP */ + /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ + /* build an 802.3 frame */ + /* allocate space and setup hostbuf */ + + /* Test for an overlength frame */ + if ( payload_length > netdev->mtu ) { + /* A bogus length ethfrm has been sent. */ + /* Is someone trying an oflow attack? */ + WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n", + payload_length, + netdev->mtu); + return 1; + } + + /* Chop off the 802.11 header. */ + skb_pull(skb, payload_offset); + + /* create 802.3 header at beginning of skb. */ + e_hdr = (wlan_ethhdr_t *) skb_push(skb, WLAN_ETHHDR_LEN); + memcpy(e_hdr->daddr, daddr, WLAN_ETHADDR_LEN); + memcpy(e_hdr->saddr, saddr, WLAN_ETHADDR_LEN); + e_hdr->type = htons(payload_length); + + /* chop off the 802.11 CRC */ + skb_trim(skb, skb->len - WLAN_CRC_LEN); + + } + + /* + * Note that eth_type_trans() expects an skb w/ skb->data pointing + * at the MAC header, it then sets the following skb members: + * skb->mac_header, + * skb->data, and + * skb->pkt_type. + * It then _returns_ the value that _we're_ supposed to stuff in + * skb->protocol. This is nuts. + */ + skb->protocol = eth_type_trans(skb, netdev); + + /* jkriegl: process signal and noise as set in hfa384x_int_rx() */ + /* jkriegl: only process signal/noise if requested by iwspy */ + if (wlandev->spy_number) + orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb)); + + /* Free the metadata */ + p80211skb_rxmeta_detach(skb); + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* p80211_stt_findproto +* +* Searches the 802.1h Selective Translation Table for a given +* protocol. +* +* Arguments: +* proto protocl number (in host order) to search for. +* +* Returns: +* 1 - if the table is empty or a match is found. +* 0 - if the table is non-empty and a match is not found. +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int p80211_stt_findproto(UINT16 proto) +{ + /* Always return found for now. This is the behavior used by the */ + /* Zoom Win95 driver when 802.1h mode is selected */ + /* TODO: If necessary, add an actual search we'll probably + need this to match the CMAC's way of doing things. + Need to do some testing to confirm. + */ + + if (proto == 0x80f3) /* APPLETALK */ + return 1; + + return 0; +} + +/*---------------------------------------------------------------- +* p80211skb_rxmeta_detach +* +* Disconnects the frmmeta and rxmeta from an skb. +* +* Arguments: +* wlandev The wlandev this skb belongs to. +* skb The skb we're attaching to. +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +void +p80211skb_rxmeta_detach(struct sk_buff *skb) +{ + p80211_rxmeta_t *rxmeta; + p80211_frmmeta_t *frmmeta; + + DBFENTER; + /* Sanity checks */ + if ( skb==NULL ) { /* bad skb */ + WLAN_LOG_DEBUG(1, "Called w/ null skb.\n"); + goto exit; + } + frmmeta = P80211SKB_FRMMETA(skb); + if ( frmmeta == NULL ) { /* no magic */ + WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n"); + goto exit; + } + rxmeta = frmmeta->rx; + if ( rxmeta == NULL ) { /* bad meta ptr */ + WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n"); + goto exit; + } + + /* Free rxmeta */ + kfree(rxmeta); + + /* Clear skb->cb */ + memset(skb->cb, 0, sizeof(skb->cb)); +exit: + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* p80211skb_rxmeta_attach +* +* Allocates a p80211rxmeta structure, initializes it, and attaches +* it to an skb. +* +* Arguments: +* wlandev The wlandev this skb belongs to. +* skb The skb we're attaching to. +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +int +p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb) +{ + int result = 0; + p80211_rxmeta_t *rxmeta; + p80211_frmmeta_t *frmmeta; + + DBFENTER; + + /* If these already have metadata, we error out! */ + if (P80211SKB_RXMETA(skb) != NULL) { + WLAN_LOG_ERROR("%s: RXmeta already attached!\n", + wlandev->name); + result = 0; + goto exit; + } + + /* Allocate the rxmeta */ + rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC); + + if ( rxmeta == NULL ) { + WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n", + wlandev->name); + result = 1; + goto exit; + } + + /* Initialize the rxmeta */ + memset(rxmeta, 0, sizeof(p80211_rxmeta_t)); + rxmeta->wlandev = wlandev; + rxmeta->hosttime = jiffies; + + /* Overlay a frmmeta_t onto skb->cb */ + memset(skb->cb, 0, sizeof(p80211_frmmeta_t)); + frmmeta = (p80211_frmmeta_t*)(skb->cb); + frmmeta->magic = P80211_FRMMETA_MAGIC; + frmmeta->rx = rxmeta; +exit: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* p80211skb_free +* +* Frees an entire p80211skb by checking and freeing the meta struct +* and then freeing the skb. +* +* Arguments: +* wlandev The wlandev this skb belongs to. +* skb The skb we're attaching to. +* +* Returns: +* 0 on success, non-zero otherwise +* +* Call context: +* May be called in interrupt or non-interrupt context +----------------------------------------------------------------*/ +void +p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb) +{ + p80211_frmmeta_t *meta; + DBFENTER; + meta = P80211SKB_FRMMETA(skb); + if ( meta && meta->rx) { + p80211skb_rxmeta_detach(skb); + } else { + WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb); + } + + dev_kfree_skb(skb); + DBFEXIT; + return; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211mod.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211mod.c @@ -0,0 +1,219 @@ +/* src/p80211/p80211mod.c +* +* Module entry and exit for p80211 +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file contains the p80211.o entry and exit points defined for linux +* kernel modules. +* +* Notes: +* - all module parameters for p80211.o should be defined here. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25)) +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + +static char *version = "p80211.o: " WLAN_RELEASE; + + +/*----------------------------------------------------------------*/ +/* --Module Parameters */ + +int wlan_watchdog = 5000; +module_param(wlan_watchdog, int, 0644); +MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds"); + +int wlan_wext_write = 1; +#if WIRELESS_EXT > 12 +module_param(wlan_wext_write, int, 0644); +MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions"); +#endif + +#ifdef WLAN_INCLUDE_DEBUG +int wlan_debug=0; +module_param(wlan_debug, int, 0644); +MODULE_PARM_DESC(wlan_debug, "p80211 debug level"); +#endif + +MODULE_LICENSE("Dual MPL/GPL"); + +/*================================================================*/ +/* Local Function Declarations */ + +int init_module(void); +void cleanup_module(void); + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* init_module +* +* Module initialization routine, called once at module load time. +* +* Arguments: +* none +* +* Returns: +* 0 - success +* ~0 - failure, module is unloaded. +* +* Side effects: +* TODO: define +* +* Call context: +* process thread (insmod or modprobe) +----------------------------------------------------------------*/ +int init_module(void) +{ + DBFENTER; + +#if 0 + printk(KERN_NOTICE "%s (%s) Loaded\n", version, WLAN_BUILD_DATE); +#endif + + p80211netdev_startup(); +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_STARTUP); +#endif + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* cleanup_module +* +* Called at module unload time. This is our last chance to +* clean up after ourselves. +* +* Arguments: +* none +* +* Returns: +* nothing +* +* Side effects: +* TODO: define +* +* Call context: +* process thread +* +----------------------------------------------------------------*/ +void cleanup_module(void) +{ + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(NULL, WLAN_HOTPLUG_SHUTDOWN); +#endif + p80211netdev_shutdown(); + printk(KERN_NOTICE "%s Unloaded\n", version); + + DBFEXIT; + return; +} + +EXPORT_SYMBOL(p80211netdev_hwremoved); +EXPORT_SYMBOL(register_wlandev); +EXPORT_SYMBOL(p80211netdev_rx); +EXPORT_SYMBOL(unregister_wlandev); +EXPORT_SYMBOL(wlan_setup); +EXPORT_SYMBOL(wlan_unsetup); +EXPORT_SYMBOL(p80211_suspend); +EXPORT_SYMBOL(p80211_resume); + +EXPORT_SYMBOL(p80211skb_free); +EXPORT_SYMBOL(p80211skb_rxmeta_attach); + +EXPORT_SYMBOL(p80211wext_event_associated); + +EXPORT_SYMBOL(wlan_wext_write); +EXPORT_SYMBOL(p80211_allow_ioctls); --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/p80211/Makefile @@ -0,0 +1,11 @@ +obj-$(CONFIG_P80211) := p80211.o + +p80211-objs := p80211mod.o \ + p80211conv.o \ + p80211req.o \ + p80211wep.o \ + p80211wext.o \ + p80211netdev.o + +EXTRA_CFLAGS += -DWLAN_TXMGMT_MINBRATE -DRSN_INTERNAL_ROAM \ + -DWLAN_HOSTIF=WLAN_NONE -I$(src) --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211req.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211req.c @@ -0,0 +1,329 @@ +/* src/p80211/p80211req.c +* +* Request/Indication/MacMgmt interface handling functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file contains the functions, types, and macros to support the +* MLME request interface that's implemented via the device ioctls. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +/* Maximum amount of time we'll wait for a request to complete */ +#define P80211REQ_MAXTIME 3*HZ /* 3 seconds */ + +/*================================================================*/ +/* Local Macros */ + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ + +/*================================================================*/ +/* Local Function Declarations */ + +static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg); +static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mibget_t *mib_msg, int isget); + +/*================================================================*/ +/* Function Definitions */ + + +/*---------------------------------------------------------------- +* p80211req_dorequest +* +* Handles an MLME reqest/confirm message. +* +* Arguments: +* wlandev WLAN device struct +* msgbuf Buffer containing a request message +* +* Returns: +* 0 on success, an errno otherwise +* +* Call context: +* Potentially blocks the caller, so it's a good idea to +* not call this function from an interrupt context. +----------------------------------------------------------------*/ +int p80211req_dorequest( wlandevice_t *wlandev, UINT8 *msgbuf) +{ + int result = 0; + p80211msg_t *msg = (p80211msg_t*)msgbuf; + + DBFENTER; + + /* Check to make sure the MSD is running */ + if ( + !((wlandev->msdstate == WLAN_MSD_HWPRESENT && + msg->msgcode == DIDmsg_lnxreq_ifstate) || + wlandev->msdstate == WLAN_MSD_RUNNING || + wlandev->msdstate == WLAN_MSD_FWLOAD) ) { + return -ENODEV; + } + + /* Check Permissions */ + if (!capable(CAP_NET_ADMIN) && + (msg->msgcode != DIDmsg_dot11req_mibget)) { + WLAN_LOG_ERROR("%s: only dot11req_mibget allowed for non-root.\n", wlandev->name); + return -EPERM; + } + + /* Check for busy status */ + if ( test_and_set_bit(1, &(wlandev->request_pending))) { + return -EBUSY; + } + + /* Allow p80211 to look at msg and handle if desired. */ + /* So far, all p80211 msgs are immediate, no waitq/timer necessary */ + /* This may change. */ + p80211req_handlemsg(wlandev, msg); + + /* Pass it down to wlandev via wlandev->mlmerequest */ + if ( wlandev->mlmerequest != NULL ) + wlandev->mlmerequest(wlandev, msg); + + clear_bit( 1, &(wlandev->request_pending)); + DBFEXIT; + return result; /* if result==0, msg->status still may contain an err */ +} + +/*---------------------------------------------------------------- +* p80211req_handlemsg +* +* p80211 message handler. Primarily looks for messages that +* belong to p80211 and then dispatches the appropriate response. +* TODO: we don't do anything yet. Once the linuxMIB is better +* defined we'll need a get/set handler. +* +* Arguments: +* wlandev WLAN device struct +* msg message structure +* +* Returns: +* nothing (any results are set in the status field of the msg) +* +* Call context: +* Process thread +----------------------------------------------------------------*/ +static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg) +{ + DBFENTER; + + switch (msg->msgcode) { + + case DIDmsg_lnxreq_hostwep: { + p80211msg_lnxreq_hostwep_t *req = (p80211msg_lnxreq_hostwep_t*) msg; + wlandev->hostwep &= ~(HOSTWEP_DECRYPT|HOSTWEP_ENCRYPT); + if (req->decrypt.data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_DECRYPT; + if (req->encrypt.data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_ENCRYPT; + + break; + } + case DIDmsg_dot11req_mibget: + case DIDmsg_dot11req_mibset: { + int isget = (msg->msgcode == DIDmsg_dot11req_mibget); + p80211msg_dot11req_mibget_t *mib_msg = (p80211msg_dot11req_mibget_t *) msg; + p80211req_mibset_mibget (wlandev, mib_msg, isget); + } + default: + // XXX do nothing! + ; + } /* switch msg->msgcode */ + + DBFEXIT; + + return; +} + +static int p80211req_mibset_mibget(wlandevice_t *wlandev, + p80211msg_dot11req_mibget_t *mib_msg, + int isget) +{ + p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data; + p80211pstrd_t *pstr = (p80211pstrd_t*) mibitem->data; + UINT8 *key = mibitem->data + sizeof(p80211pstrd_t); + + DBFENTER; + + switch (mibitem->did) { + case DIDmib_dot11smt_p80211Table_p80211_ifstate: { + UINT32 *data = (UINT32 *) mibitem->data; + if (isget) + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + *data = P80211ENUM_ifstate_disable; + break; + case WLAN_MSD_FWLOAD: + *data = P80211ENUM_ifstate_fwload; + break; + case WLAN_MSD_RUNNING: + *data = P80211ENUM_ifstate_enable; + break; + default: + *data = P80211ENUM_ifstate_enable; + } + break; + } + case DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) + *data = wlandev->shortpreamble; + else + wlandev->shortpreamble = *data; + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0: { + if (!isget) + wep_change_key(wlandev, 0, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1: { + if (!isget) + wep_change_key(wlandev, 1, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2: { + if (!isget) + wep_change_key(wlandev, 2, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3: { + if (!isget) + wep_change_key(wlandev, 3, key, pstr->len); + break; + } + case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) { + *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; + } else { + wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK); + + wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK); + } + break; + } + case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) { + if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) + *data = P80211ENUM_truth_true; + else + *data = P80211ENUM_truth_false; + } else { + wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED); + if (*data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED; + } + break; + } + case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: { + UINT32 *data = (UINT32 *) mibitem->data; + + if (isget) { + if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) + *data = P80211ENUM_truth_true; + else + *data = P80211ENUM_truth_false; + } else { + wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED); + if (*data == P80211ENUM_truth_true) + wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED; + } + break; + } + default: + // XXXX do nothing! + ; + } + + DBFEXIT; + return 0; +} + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211netdev.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211netdev.c @@ -0,0 +1,1558 @@ +/* src/p80211/p80211knetdev.c +* +* Linux Kernel net device interface +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* The functions required for a Linux network device are defined here. +* +* -------------------------------------------------------------------- +*/ + + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef SIOCETHTOOL +#include +#endif + +#if WIRELESS_EXT > 12 +#include +#endif + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ + +#define __NO_VERSION__ /* prevent the static definition */ + +#ifdef CONFIG_PROC_FS +static struct proc_dir_entry *proc_p80211; +#endif + +/*================================================================*/ +/* Local Function Declarations */ + +/* Support functions */ +static void p80211netdev_rx_bh(unsigned long arg); + +/* netdevice method functions */ +static int p80211knetdev_init( netdevice_t *netdev); +static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev); +static int p80211knetdev_open( netdevice_t *netdev); +static int p80211knetdev_stop( netdevice_t *netdev ); +static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev); +static void p80211knetdev_set_multicast_list(netdevice_t *dev); +static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); +static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr); +static void p80211knetdev_tx_timeout(netdevice_t *netdev); +static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc); + +#ifdef CONFIG_PROC_FS +static int +p80211netdev_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data); +#endif + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* p80211knetdev_startup +* +* Initialize the wlandevice/netdevice part of 802.11 services at +* load time. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +void p80211netdev_startup(void) +{ + DBFENTER; + +#ifdef CONFIG_PROC_FS + if (PROC_NET != NULL) { + proc_p80211 = create_proc_entry( + "p80211", + (S_IFDIR|S_IRUGO|S_IXUGO), + PROC_NET); + } +#endif + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* p80211knetdev_shutdown +* +* Shutdown the wlandevice/netdevice part of 802.11 services at +* unload time. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +void +p80211netdev_shutdown(void) +{ + DBFENTER; +#ifdef CONFIG_PROC_FS + if (proc_p80211 != NULL) { + remove_proc_entry("p80211", PROC_NET); + } +#endif + DBFEXIT; +} + +/*---------------------------------------------------------------- +* p80211knetdev_init +* +* Init method for a Linux netdevice. Called in response to +* register_netdev. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +static int p80211knetdev_init( netdevice_t *netdev) +{ + DBFENTER; + /* Called in response to register_netdev */ + /* This is usually the probe function, but the probe has */ + /* already been done by the MSD and the create_kdev */ + /* function. All we do here is return success */ + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_get_stats +* +* Statistics retrieval for linux netdevices. Here we're reporting +* the Linux i/f level statistics. Hence, for the primary numbers, +* we don't want to report the numbers from the MIB. Eventually, +* it might be useful to collect some of the error counters though. +* +* Arguments: +* netdev Linux netdevice +* +* Returns: +* the address of the statistics structure +----------------------------------------------------------------*/ +static struct net_device_stats* +p80211knetdev_get_stats(netdevice_t *netdev) +{ + wlandevice_t *wlandev = (wlandevice_t*)netdev->priv; + DBFENTER; + + /* TODO: review the MIB stats for items that correspond to + linux stats */ + + DBFEXIT; + return &(wlandev->linux_stats); +} + + +/*---------------------------------------------------------------- +* p80211knetdev_open +* +* Linux netdevice open method. Following a successful call here, +* the device is supposed to be ready for tx and rx. In our +* situation that may not be entirely true due to the state of the +* MAC below. +* +* Arguments: +* netdev Linux network device structure +* +* Returns: +* zero on success, non-zero otherwise +----------------------------------------------------------------*/ +static int p80211knetdev_open( netdevice_t *netdev ) +{ + int result = 0; /* success */ + wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv); + + DBFENTER; + + /* Check to make sure the MSD is running */ + if ( wlandev->msdstate != WLAN_MSD_RUNNING ) { + return -ENODEV; + } + + /* Tell the MSD to open */ + if ( wlandev->open != NULL) { + result = wlandev->open(wlandev); + if ( result == 0 ) { +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43) ) + netdev->interrupt = 0; +#endif + p80211netdev_start_queue(wlandev); + wlandev->state = WLAN_DEVICE_OPEN; + } + } else { + result = -EAGAIN; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_stop +* +* Linux netdevice stop (close) method. Following this call, +* no frames should go up or down through this interface. +* +* Arguments: +* netdev Linux network device structure +* +* Returns: +* zero on success, non-zero otherwise +----------------------------------------------------------------*/ +static int p80211knetdev_stop( netdevice_t *netdev ) +{ + int result = 0; + wlandevice_t *wlandev = (wlandevice_t*)(netdev->priv); + + DBFENTER; + + if ( wlandev->close != NULL ) { + result = wlandev->close(wlandev); + } + + p80211netdev_stop_queue(wlandev); + wlandev->state = WLAN_DEVICE_CLOSED; + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* p80211netdev_rx +* +* Frame receive function called by the mac specific driver. +* +* Arguments: +* wlandev WLAN network device structure +* skb skbuff containing a full 802.11 frame. +* Returns: +* nothing +* Side effects: +* +----------------------------------------------------------------*/ +void +p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb ) +{ + DBFENTER; + + /* Enqueue for post-irq processing */ + skb_queue_tail(&wlandev->nsd_rxq, skb); + + tasklet_schedule(&wlandev->rx_bh); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* p80211netdev_rx_bh +* +* Deferred processing of all received frames. +* +* Arguments: +* wlandev WLAN network device structure +* skb skbuff containing a full 802.11 frame. +* Returns: +* nothing +* Side effects: +* +----------------------------------------------------------------*/ +static void p80211netdev_rx_bh(unsigned long arg) +{ + wlandevice_t *wlandev = (wlandevice_t *) arg; + struct sk_buff *skb = NULL; + netdevice_t *dev = wlandev->netdev; + p80211_hdr_a3_t *hdr; + UINT16 fc; + + DBFENTER; + + /* Let's empty our our queue */ + while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) { + if (wlandev->state == WLAN_DEVICE_OPEN) { + + if (dev->type != ARPHRD_ETHER) { + /* RAW frame; we shouldn't convert it */ + // XXX Append the Prism Header here instead. + + /* set up various data fields */ + skb->dev = dev; + skb_reset_mac_header(skb); + + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_80211_RAW); + dev->last_rx = jiffies; + + wlandev->linux_stats.rx_packets++; + wlandev->linux_stats.rx_bytes += skb->len; + netif_rx_ni(skb); + continue; + } else { + hdr = (p80211_hdr_a3_t *)skb->data; + fc = ieee2host16(hdr->fc); + if (p80211_rx_typedrop(wlandev, fc)) { + dev_kfree_skb(skb); + continue; + } + + /* perform mcast filtering */ + if (wlandev->netdev->flags & IFF_ALLMULTI) { + /* allow my local address through */ + if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) { + /* but reject anything else that isn't multicast */ + if (!(hdr->a1[0] & 0x01)) { + dev_kfree_skb(skb); + continue; + } + } + } + + if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) { + skb->dev->last_rx = jiffies; + wlandev->linux_stats.rx_packets++; + wlandev->linux_stats.rx_bytes += skb->len; + netif_rx_ni(skb); + continue; + } + WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n"); + } + } + dev_kfree_skb(skb); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_hard_start_xmit +* +* Linux netdevice method for transmitting a frame. +* +* Arguments: +* skb Linux sk_buff containing the frame. +* netdev Linux netdevice. +* +* Side effects: +* If the lower layers report that buffers are full. netdev->tbusy +* will be set to prevent higher layers from sending more traffic. +* +* Note: If this function returns non-zero, higher layers retain +* ownership of the skb. +* +* Returns: +* zero on success, non-zero on failure. +----------------------------------------------------------------*/ +static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev) +{ + int result = 0; + int txresult = -1; + wlandevice_t *wlandev = (wlandevice_t*)netdev->priv; + p80211_hdr_t p80211_hdr; + p80211_metawep_t p80211_wep; + + DBFENTER; + + if (skb == NULL) { + return 0; + } + + if (wlandev->state != WLAN_DEVICE_OPEN) { + result = 1; + goto failed; + } + + memset(&p80211_hdr, 0, sizeof(p80211_hdr_t)); + memset(&p80211_wep, 0, sizeof(p80211_metawep_t)); + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + if ( test_and_set_bit(0, (void*)&(netdev->tbusy)) != 0 ) { + /* We've been called w/ tbusy set, has the tx */ + /* path stalled? */ + WLAN_LOG_DEBUG(1, "called when tbusy set\n"); + result = 1; + goto failed; + } +#else + if ( netif_queue_stopped(netdev) ) { + WLAN_LOG_DEBUG(1, "called when queue stopped.\n"); + result = 1; + goto failed; + } + + netif_stop_queue(netdev); + + /* No timeout handling here, 2.3.38+ kernels call the + * timeout function directly. + * TODO: Add timeout handling. + */ +#endif + + /* Check to see that a valid mode is set */ + switch( wlandev->macmode ) { + case WLAN_MACMODE_IBSS_STA: + case WLAN_MACMODE_ESS_STA: + case WLAN_MACMODE_ESS_AP: + break; + default: + /* Mode isn't set yet, just drop the frame + * and return success . + * TODO: we need a saner way to handle this + */ + if(skb->protocol != ETH_P_80211_RAW) { + p80211netdev_start_queue(wlandev); + WLAN_LOG_NOTICE( + "Tx attempt prior to association, frame dropped.\n"); + wlandev->linux_stats.tx_dropped++; + result = 0; + goto failed; + } + break; + } + + /* Check for raw transmits */ + if(skb->protocol == ETH_P_80211_RAW) { + if (!capable(CAP_NET_ADMIN)) { + result = 1; + goto failed; + } + /* move the header over */ + memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t)); + skb_pull(skb, sizeof(p80211_hdr_t)); + } else { + if ( skb_ether_to_p80211(wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0 ) { + /* convert failed */ + WLAN_LOG_DEBUG(1, "ether_to_80211(%d) failed.\n", + wlandev->ethconv); + result = 1; + goto failed; + } + } + if ( wlandev->txframe == NULL ) { + result = 1; + goto failed; + } + + netdev->trans_start = jiffies; + + wlandev->linux_stats.tx_packets++; + /* count only the packet payload */ + wlandev->linux_stats.tx_bytes += skb->len; + + txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep); + + if ( txresult == 0) { + /* success and more buf */ + /* avail, re: hw_txdata */ + p80211netdev_wake_queue(wlandev); + result = 0; + } else if ( txresult == 1 ) { + /* success, no more avail */ + WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n"); + /* netdev->tbusy = 1; don't set here, irqhdlr */ + /* may have already cleared it */ + result = 0; + } else if ( txresult == 2 ) { + /* alloc failure, drop frame */ + WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n"); + result = 1; + } else { + /* buffer full or queue busy, drop frame. */ + WLAN_LOG_DEBUG(3, "txframe returned full or busy\n"); + result = 1; + } + + failed: + /* Free up the WEP buffer if it's not the same as the skb */ + if ((p80211_wep.data) && (p80211_wep.data != skb->data)) + kfree(p80211_wep.data); + + /* we always free the skb here, never in a lower level. */ + if (!result) + dev_kfree_skb(skb); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* p80211knetdev_set_multicast_list +* +* Called from higher lavers whenever there's a need to set/clear +* promiscuous mode or rewrite the multicast list. +* +* Arguments: +* none +* +* Returns: +* nothing +----------------------------------------------------------------*/ +static void p80211knetdev_set_multicast_list(netdevice_t *dev) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + /* TODO: real multicast support as well */ + + if (wlandev->set_multicast_list) + wlandev->set_multicast_list(wlandev, dev); + + DBFEXIT; +} + +#ifdef SIOCETHTOOL + +static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr) +{ + UINT32 ethcmd; + struct ethtool_drvinfo info; + struct ethtool_value edata; + + memset(&info, 0, sizeof(info)); + memset(&edata, 0, sizeof(edata)); + + if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd))) + return -EFAULT; + + switch (ethcmd) { + case ETHTOOL_GDRVINFO: + info.cmd = ethcmd; + snprintf(info.driver, sizeof(info.driver), "p80211_%s", + wlandev->nsdname); + snprintf(info.version, sizeof(info.version), "%s", + WLAN_RELEASE); + + // info.fw_version + // info.bus_info + + if (copy_to_user(useraddr, &info, sizeof(info))) + return -EFAULT; + return 0; +#ifdef ETHTOOL_GLINK + case ETHTOOL_GLINK: + edata.cmd = ethcmd; + + if (wlandev->linkstatus && + (wlandev->macmode != WLAN_MACMODE_NONE)) { + edata.data = 1; + } else { + edata.data = 0; + } + + if (copy_to_user(useraddr, &edata, sizeof(edata))) + return -EFAULT; + return 0; + } +#endif + + return -EOPNOTSUPP; +} + +#endif + +/*---------------------------------------------------------------- +* p80211knetdev_do_ioctl +* +* Handle an ioctl call on one of our devices. Everything Linux +* ioctl specific is done here. Then we pass the contents of the +* ifr->data to the request message handler. +* +* Arguments: +* dev Linux kernel netdevice +* ifr Our private ioctl request structure, typed for the +* generic struct ifreq so we can use ptr to func +* w/o cast. +* +* Returns: +* zero on success, a negative errno on failure. Possible values: +* -ENETDOWN Device isn't up. +* -EBUSY cmd already in progress +* -ETIME p80211 cmd timed out (MSD may have its own timers) +* -EFAULT memory fault copying msg from user buffer +* -ENOMEM unable to allocate kernel msg buffer +* -ENOSYS bad magic, it the cmd really for us? +* -EINTR sleeping on cmd, awakened by signal, cmd cancelled. +* +* Call Context: +* Process thread (ioctl caller). TODO: SMP support may require +* locks. +----------------------------------------------------------------*/ +static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +{ + int result = 0; + p80211ioctl_req_t *req = (p80211ioctl_req_t*)ifr; + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + UINT8 *msgbuf; + DBFENTER; + + WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len); + + mutex_lock(&wlandev->ioctl_lock); +#if WIRELESS_EXT < 13 + /* Is this a wireless extensions ioctl? */ + if ((cmd >= SIOCIWFIRST) && (cmd <= SIOCIWLAST)) { + if ((result = p80211wext_support_ioctl(dev, ifr, cmd)) + != (-EOPNOTSUPP)) { + goto bail; + } + } +#endif + +#ifdef SIOCETHTOOL + if (cmd == SIOCETHTOOL) { + result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data); + goto bail; + } +#endif + + /* Test the magic, assume ifr is good if it's there */ + if ( req->magic != P80211_IOCTL_MAGIC ) { + result = -ENOSYS; + goto bail; + } + + if ( cmd == P80211_IFTEST ) { + result = 0; + goto bail; + } else if ( cmd != P80211_IFREQ ) { + result = -ENOSYS; + goto bail; + } + + /* Allocate a buf of size req->len */ + if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) { + if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) { + result = -EFAULT; + } else { + result = p80211req_dorequest( wlandev, msgbuf); + } + + if ( result == 0 ) { + if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) { + result = -EFAULT; + } + } + kfree(msgbuf); + } else { + result = -ENOMEM; + } +bail: + mutex_unlock(&wlandev->ioctl_lock); + + DBFEXIT; + + return result; /* If allocate,copyfrom or copyto fails, return errno */ +} + +/*---------------------------------------------------------------- +* p80211knetdev_set_mac_address +* +* Handles the ioctl for changing the MACAddress of a netdevice +* +* references: linux/netdevice.h and drivers/net/net_init.c +* +* NOTE: [MSM] We only prevent address changes when the netdev is +* up. We don't control anything based on dot11 state. If the +* address is changed on a STA that's currently associated, you +* will probably lose the ability to send and receive data frames. +* Just be aware. Therefore, this should usually only be done +* prior to scan/join/auth/assoc. +* +* Arguments: +* dev netdevice struct +* addr the new MACAddress (a struct) +* +* Returns: +* zero on success, a negative errno on failure. Possible values: +* -EBUSY device is bussy (cmd not possible) +* -and errors returned by: p80211req_dorequest(..) +* +* by: Collin R. Mulliner +----------------------------------------------------------------*/ +static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr) +{ + struct sockaddr *new_addr = addr; + p80211msg_dot11req_mibset_t dot11req; + p80211item_unk392_t *mibattr; + p80211item_pstr6_t *macaddr; + p80211item_uint32_t *resultcode; + int result = 0; + + DBFENTER; + /* If we're running, we don't allow MAC address changes */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + if ( dev->start) { + return -EBUSY; + } +#else + if (netif_running(dev)) { + return -EBUSY; + } +#endif + + /* Set up some convenience pointers. */ + mibattr = &dot11req.mibattribute; + macaddr = (p80211item_pstr6_t*)&mibattr->data; + resultcode = &dot11req.resultcode; + + /* Set up a dot11req_mibset */ + memset(&dot11req, 0, sizeof(p80211msg_dot11req_mibset_t)); + dot11req.msgcode = DIDmsg_dot11req_mibset; + dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t); + memcpy(dot11req.devname, + ((wlandevice_t*)(dev->priv))->name, + WLAN_DEVNAMELEN_MAX - 1); + + /* Set up the mibattribute argument */ + mibattr->did = DIDmsg_dot11req_mibset_mibattribute; + mibattr->status = P80211ENUM_msgitem_status_data_ok; + mibattr->len = sizeof(mibattr->data); + + macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress; + macaddr->status = P80211ENUM_msgitem_status_data_ok; + macaddr->len = sizeof(macaddr->data); + macaddr->data.len = WLAN_ADDR_LEN; + memcpy(&macaddr->data.data, new_addr->sa_data, WLAN_ADDR_LEN); + + /* Set up the resultcode argument */ + resultcode->did = DIDmsg_dot11req_mibset_resultcode; + resultcode->status = P80211ENUM_msgitem_status_no_value; + resultcode->len = sizeof(resultcode->data); + resultcode->data = 0; + + /* now fire the request */ + result = p80211req_dorequest(dev->priv, (UINT8*)&dot11req); + + /* If the request wasn't successful, report an error and don't + * change the netdev address + */ + if ( result != 0 || resultcode->data != P80211ENUM_resultcode_success) { + WLAN_LOG_ERROR( + "Low-level driver failed dot11req_mibset(dot11MACAddress).\n"); + result = -EADDRNOTAVAIL; + } else { + /* everything's ok, change the addr in netdev */ + memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len); + } + + DBFEXIT; + return result; +} + +static int wlan_change_mtu(netdevice_t *dev, int new_mtu) +{ + DBFENTER; + // 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap) + // and another 8 for wep. + if ( (new_mtu < 68) || (new_mtu > (2312 - 20 - 8))) + return -EINVAL; + + dev->mtu = new_mtu; + + DBFEXIT; + + return 0; +} + +/*--------------------------------------------------------- + * wlan_alloc_netdev + * + * create a netdev properly over different kernel versions + * this should work with kernels earlier than 2.6.26, and if + * anyone cares they can change it +----------------------------------------------------------*/ + +static inline netdevice_t * wlan_alloc_netdev() { + netdevice_t *dev; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ) + dev = alloc_netdev(0,"wlan%d",ether_setup); +#else + dev = kmalloc(sizeof(netdevice_t), GFP_ATOMIC); + if ( dev ) { + memset( dev, 0, sizeof(netdevice_t)); + ether_setup(dev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) ) + dev->nd_net = &init_net; +#endif + } +#endif + return dev; +} + + +/*---------------------------------------------------------------- +* wlan_setup +* +* Roughly matches the functionality of ether_setup. Here +* we set up any members of the wlandevice structure that are common +* to all devices. Additionally, we allocate a linux 'struct device' +* and perform the same setup as ether_setup. +* +* Note: It's important that the caller have setup the wlandev->name +* ptr prior to calling this function. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Should be process thread. We'll assume it might be +* interrupt though. When we add support for statically +* compiled drivers, this function will be called in the +* context of the kernel startup code. +----------------------------------------------------------------*/ +int wlan_setup(wlandevice_t *wlandev) +{ + int result = 0; + netdevice_t *dev; + + DBFENTER; + + /* Set up the wlandev */ + wlandev->state = WLAN_DEVICE_CLOSED; + wlandev->ethconv = WLAN_ETHCONV_8021h; + wlandev->macmode = WLAN_MACMODE_NONE; + + /* Set up the rx queue */ + skb_queue_head_init(&wlandev->nsd_rxq); + tasklet_init(&wlandev->rx_bh, + p80211netdev_rx_bh, + (unsigned long)wlandev); + + /* Allocate and initialize the struct net device */ + dev = wlan_alloc_netdev(); + if ( dev == NULL ) { + WLAN_LOG_ERROR("Failed to alloc netdev.\n"); + result = 1; + } else { + wlandev->netdev = dev; + dev->priv = wlandev; + dev->hard_start_xmit = p80211knetdev_hard_start_xmit; + dev->get_stats = p80211knetdev_get_stats; + + mutex_init(&wlandev->ioctl_lock); + /* block ioctls until fully initialised. Don't forget to call allow_ioctls at some point!*/ + mutex_lock(&wlandev->ioctl_lock); + +#ifdef HAVE_PRIVATE_IOCTL + dev->do_ioctl = p80211knetdev_do_ioctl; +#endif +#ifdef HAVE_MULTICAST + dev->set_multicast_list = p80211knetdev_set_multicast_list; +#endif + dev->init = p80211knetdev_init; + dev->open = p80211knetdev_open; + dev->stop = p80211knetdev_stop; + +#if defined(CONFIG_NET_WIRELESS) || defined(WIRELESS_EXT) +#if (WIRELESS_EXT < 17) + dev->get_wireless_stats = p80211wext_get_wireless_stats; +#endif +#if WIRELESS_EXT > 12 + dev->wireless_handlers = &p80211wext_handler_def; +#endif +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + dev->tbusy = 1; + dev->start = 0; +#else + netif_stop_queue(dev); +#endif +#ifdef HAVE_CHANGE_MTU + dev->change_mtu = wlan_change_mtu; +#endif +#ifdef HAVE_SET_MAC_ADDR + dev->set_mac_address = p80211knetdev_set_mac_address; +#endif +#ifdef HAVE_TX_TIMEOUT + dev->tx_timeout = &p80211knetdev_tx_timeout; + dev->watchdog_timeo = (wlan_watchdog * HZ) / 1000; +#endif + netif_carrier_off(dev); + } + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* wlan_unsetup +* +* This function is paired with the wlan_setup routine. It should +* be called after unregister_wlandev. Basically, all it does is +* free the 'struct device' that's associated with the wlandev. +* We do it here because the 'struct device' isn't allocated +* explicitly in the driver code, it's done in wlan_setup. To +* do the free in the driver might seem like 'magic'. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Should be process thread. We'll assume it might be +* interrupt though. When we add support for statically +* compiled drivers, this function will be called in the +* context of the kernel startup code. +----------------------------------------------------------------*/ +int wlan_unsetup(wlandevice_t *wlandev) +{ + int result = 0; + + DBFENTER; + + tasklet_kill(&wlandev->rx_bh); + + if (wlandev->netdev == NULL ) { + WLAN_LOG_ERROR("called without wlandev->netdev set.\n"); + result = 1; + } else { + free_netdev(wlandev->netdev); + wlandev->netdev = NULL; + } + + DBFEXIT; + return 0; +} + + + +/*---------------------------------------------------------------- +* register_wlandev +* +* Roughly matches the functionality of register_netdev. This function +* is called after the driver has successfully probed and set up the +* resources for the device. It's now ready to become a named device +* in the Linux system. +* +* First we allocate a name for the device (if not already set), then +* we call the Linux function register_netdevice. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Can be either interrupt or not. +----------------------------------------------------------------*/ +int register_wlandev(wlandevice_t *wlandev) +{ + int i = 0; + netdevice_t *dev = wlandev->netdev; + + DBFENTER; +/* alloc_netdev already sets up the name */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) ) + i = register_netdev(dev); + if (i) + return i; +#else + i = dev_alloc_name(wlandev->netdev, "wlan%d"); + if (i >= 0) { + i = register_netdev(wlandev->netdev); + } + if (i != 0) { + return -EIO; + } + +#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) ) + dev->name = wlandev->name; +#else + strcpy(wlandev->name, dev->name); +#endif +#endif + + +#ifdef CONFIG_PROC_FS + if (proc_p80211) { + wlandev->procdir = proc_mkdir(wlandev->name, proc_p80211); + if ( wlandev->procdir ) + wlandev->procwlandev = + create_proc_read_entry("wlandev", 0, + wlandev->procdir, + p80211netdev_proc_read, + wlandev); + if (wlandev->nsd_proc_read) + create_proc_read_entry("nsd", 0, + wlandev->procdir, + wlandev->nsd_proc_read, + wlandev); + } +#endif + + if (wlan_wext_write) { +/* + // fake out a call to ifstate_enable! + p80211msg_lnxreq_ifstate_t msg; + memset(&msg, 0, sizeof(msg)); + msg.msgcode = DIDmsg_lnxreq_ifstate; + msg.msglen = sizeof(msg); + msg.ifstate.status = P80211ENUM_msgitem_status_data_ok; + msg.ifstate.data = P80211ENUM_ifstate_enable; + + p80211req_dorequest(wlandev, &msg); +*/ + } else { +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REGISTER); +#endif + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* unregister_wlandev +* +* Roughly matches the functionality of unregister_netdev. This +* function is called to remove a named device from the system. +* +* First we tell linux that the device should no longer exist. +* Then we remove it from the list of known wlan devices. +* +* Arguments: +* wlandev ptr to the wlandev structure for the +* interface. +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Can be either interrupt or not. +----------------------------------------------------------------*/ +int unregister_wlandev(wlandevice_t *wlandev) +{ + struct sk_buff *skb; + + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_REMOVE); +#endif + +#ifdef CONFIG_PROC_FS + if ( wlandev->procwlandev ) { + remove_proc_entry("wlandev", wlandev->procdir); + } + if ( wlandev->nsd_proc_read ) { + remove_proc_entry("nsd", wlandev->procdir); + } + if (wlandev->procdir) { + remove_proc_entry(wlandev->name, proc_p80211); + } +#endif + + unregister_netdev(wlandev->netdev); + + /* Now to clean out the rx queue */ + while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) { + dev_kfree_skb(skb); + } + + DBFEXIT; + return 0; +} + +#ifdef CONFIG_PROC_FS +/*---------------------------------------------------------------- +* proc_read +* +* Read function for /proc/net/p80211//wlandev +* +* Arguments: +* buf +* start +* offset +* count +* eof +* data +* Returns: +* zero on success, non-zero otherwise. +* Call Context: +* Can be either interrupt or not. +----------------------------------------------------------------*/ +static int +p80211netdev_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data) +{ + char *p = page; + wlandevice_t *wlandev = (wlandevice_t *) data; + + DBFENTER; + if (offset != 0) { + *eof = 1; + goto exit; + } + + p += sprintf(p, "p80211 version: %s (%s)\n\n", + WLAN_RELEASE, WLAN_BUILD_DATE); + p += sprintf(p, "name : %s\n", wlandev->name); + p += sprintf(p, "nsd name : %s\n", wlandev->nsdname); + p += sprintf(p, "address : %02x:%02x:%02x:%02x:%02x:%02x\n", + wlandev->netdev->dev_addr[0], wlandev->netdev->dev_addr[1], wlandev->netdev->dev_addr[2], + wlandev->netdev->dev_addr[3], wlandev->netdev->dev_addr[4], wlandev->netdev->dev_addr[5]); + p += sprintf(p, "nsd caps : %s%s%s%s%s%s%s%s%s%s\n", + (wlandev->nsdcaps & P80211_NSDCAP_HARDWAREWEP) ? "wep_hw " : "", + (wlandev->nsdcaps & P80211_NSDCAP_TIEDWEP) ? "wep_tied " : "", + (wlandev->nsdcaps & P80211_NSDCAP_NOHOSTWEP) ? "wep_hw_only " : "", + (wlandev->nsdcaps & P80211_NSDCAP_PBCC) ? "pbcc " : "", + (wlandev->nsdcaps & P80211_NSDCAP_SHORT_PREAMBLE) ? "short_preamble " : "", + (wlandev->nsdcaps & P80211_NSDCAP_AGILITY) ? "agility " : "", + (wlandev->nsdcaps & P80211_NSDCAP_AP_RETRANSMIT) ? "ap_retransmit " : "", + (wlandev->nsdcaps & P80211_NSDCAP_HWFRAGMENT) ? "hw_frag " : "", + (wlandev->nsdcaps & P80211_NSDCAP_AUTOJOIN) ? "autojoin " : "", + (wlandev->nsdcaps & P80211_NSDCAP_NOSCAN) ? "" : "scan "); + + + p += sprintf(p, "bssid : %02x:%02x:%02x:%02x:%02x:%02x\n", + wlandev->bssid[0], wlandev->bssid[1], wlandev->bssid[2], + wlandev->bssid[3], wlandev->bssid[4], wlandev->bssid[5]); + + p += sprintf(p, "Enabled : %s%s\n", + (wlandev->shortpreamble) ? "short_preamble " : "", + (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) ? "privacy" : ""); + p += sprintf(p, "msdstate=%d\n", wlandev->msdstate); + + + exit: + DBFEXIT; + return (p - page); +} +#endif + +/*---------------------------------------------------------------- +* p80211netdev_hwremoved +* +* Hardware removed notification. This function should be called +* immediately after an MSD has detected that the underlying hardware +* has been yanked out from under us. The primary things we need +* to do are: +* - Mark the wlandev +* - Prevent any further traffic from the knetdev i/f +* - Prevent any further requests from mgmt i/f +* - If there are any waitq'd mgmt requests or mgmt-frame exchanges, +* shut them down. +* - Call the MSD hwremoved function. +* +* The remainder of the cleanup will be handled by unregister(). +* Our primary goal here is to prevent as much tickling of the MSD +* as possible since the MSD is already in a 'wounded' state. +* +* TODO: As new features are added, this function should be +* updated. +* +* Arguments: +* wlandev WLAN network device structure +* Returns: +* nothing +* Side effects: +* +* Call context: +* Usually interrupt. +----------------------------------------------------------------*/ +void p80211netdev_hwremoved(wlandevice_t *wlandev) +{ + DBFENTER; + wlandev->hwremoved = 1; + if ( wlandev->state == WLAN_DEVICE_OPEN) { + p80211netdev_stop_queue(wlandev); + } + + netif_device_detach(wlandev->netdev); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* p80211_rx_typedrop +* +* Classifies the frame, increments the appropriate counter, and +* returns 0|1|2 indicating whether the driver should handle, ignore, or +* drop the frame +* +* Arguments: +* wlandev wlan device structure +* fc frame control field +* +* Returns: +* zero if the frame should be handled by the driver, +* one if the frame should be ignored +* anything else means we drop it. +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static int p80211_rx_typedrop( wlandevice_t *wlandev, UINT16 fc) +{ + UINT16 ftype; + UINT16 fstype; + int drop = 0; + /* Classify frame, increment counter */ + ftype = WLAN_GET_FC_FTYPE(fc); + fstype = WLAN_GET_FC_FSTYPE(fc); +#if 0 + WLAN_LOG_DEBUG(4, + "rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype); +#endif + switch ( ftype ) { + case WLAN_FTYPE_MGMT: + if ((wlandev->netdev->flags & IFF_PROMISC) || + (wlandev->netdev->flags & IFF_ALLMULTI)) { + drop = 1; + break; + } + WLAN_LOG_DEBUG(3, "rx'd mgmt:\n"); + wlandev->rx.mgmt++; + switch( fstype ) { + case WLAN_FSTYPE_ASSOCREQ: + /* printk("assocreq"); */ + wlandev->rx.assocreq++; + break; + case WLAN_FSTYPE_ASSOCRESP: + /* printk("assocresp"); */ + wlandev->rx.assocresp++; + break; + case WLAN_FSTYPE_REASSOCREQ: + /* printk("reassocreq"); */ + wlandev->rx.reassocreq++; + break; + case WLAN_FSTYPE_REASSOCRESP: + /* printk("reassocresp"); */ + wlandev->rx.reassocresp++; + break; + case WLAN_FSTYPE_PROBEREQ: + /* printk("probereq"); */ + wlandev->rx.probereq++; + break; + case WLAN_FSTYPE_PROBERESP: + /* printk("proberesp"); */ + wlandev->rx.proberesp++; + break; + case WLAN_FSTYPE_BEACON: + /* printk("beacon"); */ + wlandev->rx.beacon++; + break; + case WLAN_FSTYPE_ATIM: + /* printk("atim"); */ + wlandev->rx.atim++; + break; + case WLAN_FSTYPE_DISASSOC: + /* printk("disassoc"); */ + wlandev->rx.disassoc++; + break; + case WLAN_FSTYPE_AUTHEN: + /* printk("authen"); */ + wlandev->rx.authen++; + break; + case WLAN_FSTYPE_DEAUTHEN: + /* printk("deauthen"); */ + wlandev->rx.deauthen++; + break; + default: + /* printk("unknown"); */ + wlandev->rx.mgmt_unknown++; + break; + } + /* printk("\n"); */ + drop = 2; + break; + + case WLAN_FTYPE_CTL: + if ((wlandev->netdev->flags & IFF_PROMISC) || + (wlandev->netdev->flags & IFF_ALLMULTI)) { + drop = 1; + break; + } + WLAN_LOG_DEBUG(3, "rx'd ctl:\n"); + wlandev->rx.ctl++; + switch( fstype ) { + case WLAN_FSTYPE_PSPOLL: + /* printk("pspoll"); */ + wlandev->rx.pspoll++; + break; + case WLAN_FSTYPE_RTS: + /* printk("rts"); */ + wlandev->rx.rts++; + break; + case WLAN_FSTYPE_CTS: + /* printk("cts"); */ + wlandev->rx.cts++; + break; + case WLAN_FSTYPE_ACK: + /* printk("ack"); */ + wlandev->rx.ack++; + break; + case WLAN_FSTYPE_CFEND: + /* printk("cfend"); */ + wlandev->rx.cfend++; + break; + case WLAN_FSTYPE_CFENDCFACK: + /* printk("cfendcfack"); */ + wlandev->rx.cfendcfack++; + break; + default: + /* printk("unknown"); */ + wlandev->rx.ctl_unknown++; + break; + } + /* printk("\n"); */ + drop = 2; + break; + + case WLAN_FTYPE_DATA: + wlandev->rx.data++; + switch( fstype ) { + case WLAN_FSTYPE_DATAONLY: + wlandev->rx.dataonly++; + break; + case WLAN_FSTYPE_DATA_CFACK: + wlandev->rx.data_cfack++; + break; + case WLAN_FSTYPE_DATA_CFPOLL: + wlandev->rx.data_cfpoll++; + break; + case WLAN_FSTYPE_DATA_CFACK_CFPOLL: + wlandev->rx.data__cfack_cfpoll++; + break; + case WLAN_FSTYPE_NULL: + WLAN_LOG_DEBUG(3, "rx'd data:null\n"); + wlandev->rx.null++; + break; + case WLAN_FSTYPE_CFACK: + WLAN_LOG_DEBUG(3, "rx'd data:cfack\n"); + wlandev->rx.cfack++; + break; + case WLAN_FSTYPE_CFPOLL: + WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n"); + wlandev->rx.cfpoll++; + break; + case WLAN_FSTYPE_CFACK_CFPOLL: + WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n"); + wlandev->rx.cfack_cfpoll++; + break; + default: + /* printk("unknown"); */ + wlandev->rx.data_unknown++; + break; + } + + break; + } + return drop; +} + +#ifdef CONFIG_HOTPLUG +/* Notify userspace when a netdevice event occurs, + * by running '/sbin/hotplug net' with certain + * environment variables set. + */ +int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action) +{ + char *argv[3], *envp[7], ifname[12 + IFNAMSIZ], action_str[32]; + char nsdname[32], wlan_wext[32]; + int i; + + if (wlandev) { + sprintf(ifname, "INTERFACE=%s", wlandev->name); + sprintf(nsdname, "NSDNAME=%s", wlandev->nsdname); + } else { + sprintf(ifname, "INTERFACE=null"); + sprintf(nsdname, "NSDNAME=null"); + } + + sprintf(wlan_wext, "WLAN_WEXT=%s", wlan_wext_write ? "y" : ""); + sprintf(action_str, "ACTION=%s", action); + + i = 0; + argv[i++] = hotplug_path; + argv[i++] = "wlan"; + argv[i] = NULL; + + i = 0; + /* minimal command environment */ + envp [i++] = "HOME=/"; + envp [i++] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin"; + envp [i++] = ifname; + envp [i++] = action_str; + envp [i++] = nsdname; + envp [i++] = wlan_wext; + envp [i] = NULL; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,62)) + return call_usermodehelper(argv [0], argv, envp); +#else + return call_usermodehelper(argv [0], argv, envp, 0); +#endif +} + +#endif + + +void p80211_suspend(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_SUSPEND); +#endif + + DBFEXIT; +} + +void p80211_resume(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef CONFIG_HOTPLUG + p80211_run_sbin_hotplug(wlandev, WLAN_HOTPLUG_RESUME); +#endif + + DBFEXIT; +} + +static void p80211knetdev_tx_timeout( netdevice_t *netdev) +{ + wlandevice_t *wlandev = (wlandevice_t*)netdev->priv; + DBFENTER; + + if (wlandev->tx_timeout) { + wlandev->tx_timeout(wlandev); + } else { + WLAN_LOG_WARNING("Implement tx_timeout for %s\n", + wlandev->nsdname); + p80211netdev_wake_queue(wlandev); + } + + DBFEXIT; +} + +void p80211_allow_ioctls(wlandevice_t *wlandev) { + mutex_unlock(&wlandev->ioctl_lock); +} --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211wep.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211wep.c @@ -0,0 +1,317 @@ +/* src/p80211/p80211wep.c +* +* WEP encode/decode for P80211. +* +* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include + +#include +#include + +// #define WEP_DEBUG + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +#define SSWAP(a,b) {UINT8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;} +#define WEP_KEY(x) (((x) & 0xC0) >> 6) + +/*================================================================*/ +/* Local Macros */ + + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + +static const UINT32 wep_crc32_table[256] = { + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +}; + +/*================================================================*/ +/* Local Function Declarations */ + +/*================================================================*/ +/* Function Definitions */ + +/* keylen in bytes! */ + +int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen) +{ + if (keylen < 0) return -1; + if (keylen >= MAX_KEYLEN) return -1; + if (key == NULL) return -1; + if (keynum < 0) return -1; + if (keynum >= NUM_WEPKEYS) return -1; + + +#ifdef WEP_DEBUG + printk(KERN_DEBUG "WEP key %d len %d = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]); +#endif + + wlandev->wep_keylens[keynum] = keylen; + memcpy(wlandev->wep_keys[keynum], key, keylen); + + return 0; +} + +/* + 4-byte IV at start of buffer, 4-byte ICV at end of buffer. + if successful, buf start is payload begin, length -= 8; + */ +int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv) +{ + UINT32 i, j, k, crc, keylen; + UINT8 s[256], key[64], c_crc[4]; + UINT8 keyidx; + + /* Needs to be at least 8 bytes of payload */ + if (len <= 0) return -1; + + /* initialize the first bytes of the key from the IV */ + key[0] = iv[0]; + key[1] = iv[1]; + key[2] = iv[2]; + keyidx = WEP_KEY(iv[3]); + + if (key_override >= 0) + keyidx = key_override; + + if (keyidx >= NUM_WEPKEYS) return -2; + + keylen = wlandev->wep_keylens[keyidx]; + + if (keylen == 0) return -3; + + /* copy the rest of the key over from the designated key */ + memcpy(key+3, wlandev->wep_keys[keyidx], keylen); + + keylen+=3; /* add in IV bytes */ + +#ifdef WEP_DEBUG + printk(KERN_DEBUG "D %d: %02x %02x %02x (%d %d) %02x:%02x:%02x:%02x:%02x\n", len, key[0], key[1], key[2], keyidx, keylen, key[3], key[4], key[5], key[6], key[7]); +#endif + + /* set up the RC4 state */ + for (i = 0; i < 256; i++) + s[i] = i; + j = 0; + for (i = 0; i < 256; i++) { + j = (j + s[i] + key[i % keylen]) & 0xff; + SSWAP(i,j); + } + + /* Apply the RC4 to the data, update the CRC32 */ + crc = ~0; + i = j = 0; + for (k = 0; k < len; k++) { + i = (i+1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + buf[k] ^= s[(s[i] + s[j]) & 0xff]; + crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8); + } + crc = ~crc; + + /* now let's check the crc */ + c_crc[0] = crc; + c_crc[1] = crc >> 8; + c_crc[2] = crc >> 16; + c_crc[3] = crc >> 24; + + for (k = 0; k < 4; k++) { + i = (i + 1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k]) + return -(4 | (k << 4)) ; /* ICV mismatch */ + } + + return 0; +} + +/* encrypts in-place. */ +int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv) +{ + UINT32 i, j, k, crc, keylen; + UINT8 s[256], key[64]; + + /* no point in WEPping an empty frame */ + if (len <= 0) return -1; + + /* we need to have a real key.. */ + if (keynum >= NUM_WEPKEYS) return -2; + keylen = wlandev->wep_keylens[keynum]; + if (keylen <= 0) return -3; + + /* use a random IV. And skip known weak ones. */ + get_random_bytes(iv, 3); + while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen)) + get_random_bytes(iv, 3); + + iv[3] = (keynum & 0x03) << 6; + + key[0] = iv[0]; + key[1] = iv[1]; + key[2] = iv[2]; + + /* copy the rest of the key over from the designated key */ + memcpy(key+3, wlandev->wep_keys[keynum], keylen); + + keylen+=3; /* add in IV bytes */ + +#ifdef WEP_DEBUG + printk(KERN_DEBUG "E %d (%d/%d %d) %02x %02x %02x %02x:%02x:%02x:%02x:%02x\n", len, iv[3], keynum, keylen, key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]); +#endif + + /* set up the RC4 state */ + for (i = 0; i < 256; i++) + s[i] = i; + j = 0; + for (i = 0; i < 256; i++) { + j = (j + s[i] + key[i % keylen]) & 0xff; + SSWAP(i,j); + } + + /* Update CRC32 then apply RC4 to the data */ + crc = ~0; + i = j = 0; + for (k = 0; k < len; k++) { + crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8); + i = (i+1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff]; + } + crc = ~crc; + + /* now let's encrypt the crc */ + icv[0] = crc; + icv[1] = crc >> 8; + icv[2] = crc >> 16; + icv[3] = crc >> 24; + + for (k = 0; k < 4; k++) { + i = (i + 1) & 0xff; + j = (j+s[i]) & 0xff; + SSWAP(i,j); + icv[k] ^= s[(s[i] + s[j]) & 0xff]; + } + + return 0; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/p80211wext.c +++ linux-2.6.28/ubuntu/misc/wireless/p80211/p80211wext.c @@ -0,0 +1,2174 @@ +/* src/p80211/p80211wext.c +* +* Glue code to make linux-wlan-ng a happy wireless extension camper. +* +* original author: Reyk Floeter +* Completely re-written by Solomon Peachy +* +* Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#if WIRELESS_EXT > 12 +#include +#endif +#include +#include +#include +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int p80211wext_giwrate(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra); +static int p80211wext_giwessid(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid); +/* compatibility to wireless extensions */ +#ifdef WIRELESS_EXT + +static UINT8 p80211_mhz_to_channel(UINT16 mhz) +{ + if (mhz >= 5000) { + return ((mhz - 5000) / 5); + } + + if (mhz == 2482) + return 14; + + if (mhz >= 2407) { + return ((mhz - 2407) / 5); + } + + return 0; +} + +static UINT16 p80211_channel_to_mhz(UINT8 ch, int dot11a) +{ + + if (ch == 0) + return 0; + if (ch > 200) + return 0; + + /* 5G */ + + if (dot11a) { + return (5000 + (5 * ch)); + } + + /* 2.4G */ + + if (ch == 14) + return 2484; + + if ((ch < 14) && (ch > 0)) { + return (2407 + (5 * ch)); + } + + return 0; +} + +/* taken from orinoco.c ;-) */ +static const long p80211wext_channel_freq[] = { + 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 +}; +#define NUM_CHANNELS (sizeof(p80211wext_channel_freq) / sizeof(p80211wext_channel_freq[0])) + +/* steal a spare bit to store the shared/opensystems state. should default to open if not set */ +#define HOSTWEP_SHAREDKEY BIT3 + + +/** function declarations =============== */ + +static int qual_as_percent(int snr ) { + if ( snr <= 0 ) + return 0; + if ( snr <= 40 ) + return snr*5/2; + return 100; +} + +static inline int invalid_state(wlandevice_t *wlandev ) { + return wlandev->msdstate != WLAN_MSD_RUNNING; +} + +static int p80211wext_dorequest(wlandevice_t *wlandev, UINT32 did, UINT32 data) +{ + p80211msg_dot11req_mibset_t msg; + p80211item_uint32_t mibitem; + int result; + + DBFENTER; + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = did; + mibitem.data = data; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + DBFEXIT; + return result; +} + +static int p80211wext_autojoin(wlandevice_t *wlandev) +{ + p80211msg_lnxreq_autojoin_t msg; + struct iw_point data; + char ssid[IW_ESSID_MAX_SIZE]; + + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + /* Get ESSID */ + result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid); + + if (result) { + err = -EFAULT; + goto exit; + } + + if ( wlandev->hostwep & HOSTWEP_SHAREDKEY ) + msg.authtype.data = P80211ENUM_authalg_sharedkey; + else + msg.authtype.data = P80211ENUM_authalg_opensystem; + + msg.msgcode = DIDmsg_lnxreq_autojoin; + + /* Trim the last '\0' to fit the SSID format */ + + if (data.length && ssid[data.length-1] == '\0') { + data.length = data.length - 1; + } + + memcpy(msg.ssid.data.data, ssid, data.length); + msg.ssid.data.len = data.length; + + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + +exit: + + DBFEXIT; + return err; + +} + +/* called by /proc/net/wireless */ +struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev) +{ + p80211msg_lnxreq_commsquality_t quality; + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_statistics* wstats = &wlandev->wstats; + int retval; + + DBFENTER; + /* Check */ + if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) ) + return NULL; + + /* XXX Only valid in station mode */ + wstats->status = 0; + + /* build request message */ + quality.msgcode = DIDmsg_lnxreq_commsquality; + quality.dbm.data = P80211ENUM_truth_true; + quality.dbm.status = P80211ENUM_msgitem_status_data_ok; + + /* send message to nsd */ + if ( wlandev->mlmerequest == NULL ) + return NULL; + + retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality); + + wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */ + wstats->qual.level = quality.level.data; /* instant signal level */ + wstats->qual.noise = quality.noise.data; /* instant noise level */ + +#if WIRELESS_EXT > 18 + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; +#else + wstats->qual.updated = 7; +#endif + wstats->discard.code = wlandev->rx.decrypt_err; + wstats->discard.nwid = 0; + wstats->discard.misc = 0; + +#if WIRELESS_EXT > 11 + wstats->discard.fragment = 0; // incomplete fragments + wstats->discard.retries = 0; // tx retries. + wstats->miss.beacon = 0; +#endif + + DBFEXIT; + + return wstats; +} + +static int p80211wext_giwname(netdevice_t *dev, + struct iw_request_info *info, + char *name, char *extra) +{ + struct iw_param rate; + int result; + int err = 0; + + DBFENTER; + + result = p80211wext_giwrate(dev, NULL, &rate, NULL); + + if (result) { + err = -EFAULT; + goto exit; + } + + switch (rate.value) { + case 1000000: + case 2000000: + strcpy(name, "IEEE 802.11-DS"); + break; + case 5500000: + case 11000000: + strcpy(name, "IEEE 802.11-b"); + break; + } +exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwfreq(netdevice_t *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + if (mibitem.data > NUM_CHANNELS) { + err = -EFAULT; + goto exit; + } + + /* convert into frequency instead of a channel */ + freq->e = 1; + freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000; + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_siwfreq(netdevice_t *dev, + struct iw_request_info *info, + struct iw_freq *freq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel; + mibitem.status = P80211ENUM_msgitem_status_data_ok; + + if ( (freq->e == 0) && (freq->m <= 1000) ) + mibitem.data = freq->m; + else + mibitem.data = p80211_mhz_to_channel(freq->m); + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +#if WIRELESS_EXT > 8 + +static int p80211wext_giwmode(netdevice_t *dev, + struct iw_request_info *info, + __u32 *mode, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + switch (wlandev->macmode) { + case WLAN_MACMODE_IBSS_STA: + *mode = IW_MODE_ADHOC; + break; + case WLAN_MACMODE_ESS_STA: + *mode = IW_MODE_INFRA; + break; + case WLAN_MACMODE_ESS_AP: + *mode = IW_MODE_MASTER; + break; + default: + /* Not set yet. */ + *mode = IW_MODE_AUTO; + } + + DBFEXIT; + return 0; +} + +static int p80211wext_siwmode(netdevice_t *dev, + struct iw_request_info *info, + __u32 *mode, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA && + *mode != IW_MODE_MASTER) { + err = (-EOPNOTSUPP); + goto exit; + } + + /* Operation mode is the same with current mode */ + if (*mode == wlandev->macmode) + goto exit; + + switch (*mode) { + case IW_MODE_ADHOC: + wlandev->macmode = WLAN_MACMODE_IBSS_STA; + break; + case IW_MODE_INFRA: + wlandev->macmode = WLAN_MACMODE_ESS_STA; + break; + case IW_MODE_MASTER: + wlandev->macmode = WLAN_MACMODE_ESS_AP; + break; + default: + /* Not set yet. */ + WLAN_LOG_INFO("Operation mode: %d not support\n", *mode); + return -EOPNOTSUPP; + } + + /* Set Operation mode to the PORT TYPE RID */ + +#warning "get rid of p2mib here" + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = DIDmib_p2_p2Static_p2CnfPortType; + mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) + err = -EFAULT; + + exit: + DBFEXIT; + + return err; +} + + +static int p80211wext_giwrange(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *extra) +{ + struct iw_range *range = (struct iw_range *) extra; + int i, val; + + DBFENTER; + + // for backward compatability set size & zero everything we don't understand + data->length = sizeof(*range); + memset(range,0,sizeof(*range)); + +#if WIRELESS_EXT > 9 + range->txpower_capa = IW_TXPOW_DBM; + // XXX what about min/max_pmp, min/max_pmt, etc. +#endif + +#if WIRELESS_EXT > 10 + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 13; + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->min_retry = 0; + range->max_retry = 255; +#endif /* WIRELESS_EXT > 10 */ + +#if WIRELESS_EXT > 16 + range->event_capa[0] = (IW_EVENT_CAPA_K_0 | //mode/freq/ssid + IW_EVENT_CAPA_MASK(SIOCGIWAP) | + IW_EVENT_CAPA_MASK(SIOCGIWSCAN)); + range->event_capa[1] = IW_EVENT_CAPA_K_1; //encode + range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) | + IW_EVENT_CAPA_MASK(IWEVCUSTOM) ); +#endif + + range->num_channels = NUM_CHANNELS; + + /* XXX need to filter against the regulatory domain &| active set */ + val = 0; + for (i = 0; i < NUM_CHANNELS ; i++) { + range->freq[val].i = i + 1; + range->freq[val].m = p80211wext_channel_freq[i] * 100000; + range->freq[val].e = 1; + val++; + } + + range->num_frequency = val; + + /* Max of /proc/net/wireless */ + range->max_qual.qual = 100; + range->max_qual.level = 0; + range->max_qual.noise = 0; + range->sensitivity = 3; + // XXX these need to be nsd-specific! + + range->min_rts = 0; + range->max_rts = 2347; + range->min_frag = 256; + range->max_frag = 2346; + + range->max_encoding_tokens = NUM_WEPKEYS; + range->num_encoding_sizes = 2; + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + + // XXX what about num_bitrates/throughput? + range->num_bitrates = 0; + + /* estimated max throughput */ + // XXX need to cap it if we're running at ~2Mbps.. + range->throughput = 5500000; + + DBFEXIT; + return 0; +} +#endif + +static int p80211wext_giwap(netdevice_t *dev, + struct iw_request_info *info, + struct sockaddr *ap_addr, char *extra) +{ + + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN); + ap_addr->sa_family = ARPHRD_ETHER; + + DBFEXIT; + return 0; +} + +#if WIRELESS_EXT > 8 +static int p80211wext_giwencode(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *erq, char *key) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + int err = 0; + int i; + + DBFENTER; + + i = (erq->flags & IW_ENCODE_INDEX) - 1; + erq->flags = 0; + + if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) + erq->flags |= IW_ENCODE_ENABLED; + else + erq->flags |= IW_ENCODE_DISABLED; + + if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) + erq->flags |= IW_ENCODE_RESTRICTED; + else + erq->flags |= IW_ENCODE_OPEN; + + if (i == -1) + i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; + + if ((i < 0) || (i >= NUM_WEPKEYS)) { + err = -EINVAL; + goto exit; + } + + erq->flags |= i + 1; + + /* copy the key from the driver cache as the keys are read-only MIBs */ + erq->length = wlandev->wep_keylens[i]; + memcpy(key, wlandev->wep_keys[i], erq->length); + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_siwencode(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *erq, char *key) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_dot11req_mibset_t msg; + p80211item_pstr32_t pstr; + + int err = 0; + int result = 0; + int i; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + /* Check the Key index first. */ + if((i = (erq->flags & IW_ENCODE_INDEX))) { + + if ((i < 1) || (i > NUM_WEPKEYS)) { + err = -EINVAL; + goto exit; + } else { + i--; + } + + /* Set current key number only if no keys are given */ + if (erq->flags & IW_ENCODE_NOKEY) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i); + + if (result) { + err = -EFAULT; + goto exit; + } + } + + } else { + // Use defaultkey if no Key Index + i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; + } + + /* Check if there is no key information in the iwconfig request */ + if((erq->flags & IW_ENCODE_NOKEY) == 0 ) { + + /*------------------------------------------------------------ + * If there is WEP Key for setting, check the Key Information + * and then set it to the firmware. + -------------------------------------------------------------*/ + + if (erq->length > 0) { + + /* copy the key from the driver cache as the keys are read-only MIBs */ + wlandev->wep_keylens[i] = erq->length; + memcpy(wlandev->wep_keys[i], key, erq->length); + + /* Prepare data struture for p80211req_dorequest. */ + memcpy(pstr.data.data, key, erq->length); + pstr.data.len = erq->length; + + switch(i) + { + case 0: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0; + break; + + case 1: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1; + break; + + case 2: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2; + break; + + case 3: + pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3; + break; + + default: + err = -EINVAL; + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } + + } + + /* Check the PrivacyInvoked flag */ + if (erq->flags & IW_ENCODE_DISABLED) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); + } else { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); + } + + if (result) { + err = -EFAULT; + goto exit; + } + + /* The security mode may be open or restricted, and its meaning + depends on the card used. With most cards, in open mode no + authentication is used and the card may also accept non- + encrypted sessions, whereas in restricted mode only encrypted + sessions are accepted and the card will use authentication if + available. + */ + if (erq->flags & IW_ENCODE_RESTRICTED) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); + // wlandev->hostwep |= HOSTWEP_SHAREDKEY; + } else if (erq->flags & IW_ENCODE_OPEN) { + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); + // wlandev->hostwep &= ~HOSTWEP_SHAREDKEY; + } + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + + DBFEXIT; + return err; +} + +static int p80211wext_giwessid(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + DBFENTER; + + if (wlandev->ssid.len) { + data->length = wlandev->ssid.len; + data->flags = 1; + memcpy(essid, wlandev->ssid.data, data->length); + essid[data->length] = 0; +#if (WIRELESS_EXT < 21) + data->length++; +#endif + } else { + memset(essid, 0, sizeof(wlandev->ssid.data)); + data->length = 0; + data->flags = 0; + } + + DBFEXIT; + return 0; +} + +static int p80211wext_siwessid(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_lnxreq_autojoin_t msg; + + int result; + int err = 0; + int length = data->length; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + + if ( wlandev->hostwep & HOSTWEP_SHAREDKEY ) + msg.authtype.data = P80211ENUM_authalg_sharedkey; + else + msg.authtype.data = P80211ENUM_authalg_opensystem; + + msg.msgcode = DIDmsg_lnxreq_autojoin; + +#if (WIRELESS_EXT < 21) + if (length) length--; +#endif + + /* Trim the last '\0' to fit the SSID format */ + + if (length && essid[length-1] == '\0') { + length--; + } + + memcpy(msg.ssid.data.data, essid, length); + msg.ssid.data.len = length; + + WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + + +static int p80211wext_siwcommit(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *data, char *essid) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + /* Auto Join */ + err = p80211wext_autojoin(wlandev); + + exit: + DBFEXIT; + return err; +} + + +static int p80211wext_giwrate(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + rrq->fixed = 0; /* can it change? */ + rrq->disabled = 0; + rrq->value = 0; + +#define HFA384x_RATEBIT_1 ((UINT16)1) +#define HFA384x_RATEBIT_2 ((UINT16)2) +#define HFA384x_RATEBIT_5dot5 ((UINT16)4) +#define HFA384x_RATEBIT_11 ((UINT16)8) + + switch (mibitem.data) { + case HFA384x_RATEBIT_1: + rrq->value = 1000000; + break; + case HFA384x_RATEBIT_2: + rrq->value = 2000000; + break; + case HFA384x_RATEBIT_5dot5: + rrq->value = 5500000; + break; + case HFA384x_RATEBIT_11: + rrq->value = 11000000; + break; + default: + err = -EINVAL; + } + exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwrts(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + rts->value = mibitem.data; + rts->disabled = (rts->value == 2347); + rts->fixed = 1; + + exit: + DBFEXIT; + return err; +} + + +static int p80211wext_siwrts(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rts, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold; + if (rts->disabled) + mibitem.data = 2347; + else + mibitem.data = rts->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwfrag(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + frag->value = mibitem.data; + frag->disabled = (frag->value == 2346); + frag->fixed = 1; + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_siwfrag(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *frag, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold; + + if (frag->disabled) + mibitem.data = 2346; + else + mibitem.data = frag->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +#endif /* WIRELESS_EXT > 8 */ + +#if WIRELESS_EXT > 10 + +#ifndef IW_RETRY_LONG +#define IW_RETRY_LONG IW_RETRY_MAX +#endif + +#ifndef IW_RETRY_SHORT +#define IW_RETRY_SHORT IW_RETRY_MIN +#endif + +static int p80211wext_giwretry(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + UINT16 shortretry, longretry, lifetime; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + shortretry = mibitem.data; + + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + longretry = mibitem.data; + + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + lifetime = mibitem.data; + + rrq->disabled = 0; + + if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { + rrq->flags = IW_RETRY_LIFETIME; + rrq->value = lifetime * 1024; + } else { + if (rrq->flags & IW_RETRY_LONG) { + rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG; + rrq->value = longretry; + } else { + rrq->flags = IW_RETRY_LIMIT; + rrq->value = shortretry; + if (shortretry != longretry) + rrq->flags |= IW_RETRY_SHORT; + } + } + + exit: + DBFEXIT; + return err; + +} + +static int p80211wext_siwretry(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + if (rrq->disabled) { + err = -EINVAL; + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + + if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) { + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime; + mibitem.data = rrq->value /= 1024; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } else { + if (rrq->flags & IW_RETRY_LONG) { + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit; + mibitem.data = rrq->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } + + if (rrq->flags & IW_RETRY_SHORT) { + mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit; + mibitem.data = rrq->value; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + } + } + + exit: + DBFEXIT; + return err; + +} + +#endif /* WIRELESS_EXT > 10 */ + +#if WIRELESS_EXT > 9 +static int p80211wext_siwtxpow(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (!wlan_wext_write) { + err = (-EOPNOTSUPP); + goto exit; + } + + msg.msgcode = DIDmsg_dot11req_mibset; + + switch (rrq->value) { + + case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break; + case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break; + case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break; + case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break; + case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break; + case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break; + case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break; + case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break; + default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break; + } + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + exit: + DBFEXIT; + return err; +} + +static int p80211wext_giwtxpow(netdevice_t *dev, + struct iw_request_info *info, + struct iw_param *rrq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211item_uint32_t mibitem; + p80211msg_dot11req_mibset_t msg; + int result; + int err = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + msg.msgcode = DIDmsg_dot11req_mibget; + mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel; + + memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem)); + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + + if (result) { + err = -EFAULT; + goto exit; + } + + memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem)); + + // XXX handle OFF by setting disabled = 1; + + rrq->flags = 0; // IW_TXPOW_DBM; + rrq->disabled = 0; + rrq->fixed = 0; + rrq->value = mibitem.data; + + exit: + DBFEXIT; + return err; +} +#endif /* WIRELESS_EXT > 9 */ + +static int p80211wext_siwspy(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct sockaddr address[IW_MAX_SPY]; + int number = srq->length; + int i; + + DBFENTER; + + /* Copy the data from the input buffer */ + memcpy(address, extra, sizeof(struct sockaddr)*number); + + wlandev->spy_number = 0; + + if (number > 0) { + + /* extract the addresses */ + for (i = 0; i < number; i++) { + + memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN); + } + + /* reset stats */ + memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY); + + /* set number of addresses */ + wlandev->spy_number = number; + } + + DBFEXIT; + return 0; +} + +/* jkriegl: from orinoco, modified */ +static int p80211wext_giwspy(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + + struct sockaddr address[IW_MAX_SPY]; + struct iw_quality spy_stat[IW_MAX_SPY]; + int number; + int i; + + DBFENTER; + + number = wlandev->spy_number; + + if (number > 0) { + + /* populate address and spy struct's */ + for (i = 0; i < number; i++) { + memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN); + address[i].sa_family = AF_UNIX; + memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality)); + } + + /* reset update flag */ + for (i=0; i < number; i++) + wlandev->spy_stat[i].updated = 0; + } + + /* push stuff to user space */ + srq->length = number; + memcpy(extra, address, sizeof(struct sockaddr)*number); + memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number); + + DBFEXIT; + return 0; +} + +static int prism2_result2err (int prism2_result) +{ + int err = 0; + + switch (prism2_result) { + case P80211ENUM_resultcode_invalid_parameters: + err = -EINVAL; + break; + case P80211ENUM_resultcode_implementation_failure: + err = -EIO; + break; + case P80211ENUM_resultcode_not_supported: + err = -EOPNOTSUPP; + break; + default: + err = 0; + break; + } + + return err; +} + +#if WIRELESS_EXT > 13 +static int p80211wext_siwscan(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_dot11req_scan_t msg; + int result; + int err = 0; + int i = 0; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + if (wlandev->macmode == WLAN_MACMODE_ESS_AP) { + WLAN_LOG_ERROR("Can't scan in AP mode\n"); + err = (-EOPNOTSUPP); + goto exit; + } + + memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t)); + msg.msgcode = DIDmsg_dot11req_scan; + msg.bsstype.data = P80211ENUM_bsstype_any; + + memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t)); + msg.bssid.data.len = 6; + + msg.scantype.data = P80211ENUM_scantype_active; + msg.probedelay.data = 0; + + for (i = 1; i <= 14; i++) + msg.channellist.data.data[i-1] = i; + msg.channellist.data.len = 14; + + msg.maxchanneltime.data = 250; + msg.minchanneltime.data = 200; + + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + if (result) + err = prism2_result2err (msg.resultcode.data); + + exit: + DBFEXIT; + return err; +} + + +/* Helper to translate scan into Wireless Extensions scan results. + * Inspired by the prism54 code, which was in turn inspired by the + * airo driver code. + */ +static char * +wext_translate_bss(char *current_ev, char *end_buf, p80211msg_dot11req_scan_results_t *bss, + struct iw_request_info *info) +{ + struct iw_event iwe; /* Temporary buffer */ + + /* The first entry must be the MAC address */ + memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN); + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + iwe.cmd = SIOCGIWAP; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* The following entries will be displayed in the same order we give them */ + + /* The ESSID. */ + if (bss->ssid.data.len > 0) { + char essid[IW_ESSID_MAX_SIZE + 1]; + int size; + + size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len); + memset(&essid, 0, sizeof (essid)); + memcpy(&essid, bss->ssid.data.data, size); + WLAN_LOG_DEBUG(1, " essid size = %d\n", size); + iwe.u.data.length = size; + iwe.u.data.flags = 1; + iwe.cmd = SIOCGIWESSID; + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]); + WLAN_LOG_DEBUG(1, " essid size OK.\n"); + } + + switch (bss->bsstype.data) { + case P80211ENUM_bsstype_infrastructure: + iwe.u.mode = IW_MODE_MASTER; + break; + + case P80211ENUM_bsstype_independent: + iwe.u.mode = IW_MODE_ADHOC; + break; + + default: + iwe.u.mode = 0; + break; + } + iwe.cmd = SIOCGIWMODE; + if (iwe.u.mode) + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN); + + /* Encryption capability */ + if (bss->privacy.data == P80211ENUM_truth_true) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + iwe.cmd = SIOCGIWENCODE; + current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL); + + /* Add frequency. (short) bss->channel is the frequency in MHz */ + iwe.u.freq.m = bss->dschannel.data; + iwe.u.freq.e = 0; + iwe.cmd = SIOCGIWFREQ; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* Add quality statistics */ + iwe.u.qual.level = bss->signal.data; + iwe.u.qual.noise = bss->noise.data; + /* do a simple SNR for quality */ + iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data); + iwe.cmd = IWEVQUAL; + current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); + + return current_ev; +} + + +static int p80211wext_giwscan(netdevice_t *dev, + struct iw_request_info *info, + struct iw_point *srq, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + p80211msg_dot11req_scan_results_t msg; + int result = 0; + int err = 0; + int i = 0; + int scan_good = 0; + char *current_ev = extra; + + DBFENTER; + + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + err = -EBUSY; + goto exit; + } + + /* Since wireless tools doesn't really have a way of passing how + * many scan results results there were back here, keep grabbing them + * until we fail. + */ + do { + memset(&msg, 0, sizeof(msg)); + msg.msgcode = DIDmsg_dot11req_scan_results; + msg.bssindex.data = i; + + result = p80211req_dorequest(wlandev, (UINT8*)&msg); + if ((result != 0) || + (msg.resultcode.data != P80211ENUM_resultcode_success)) { + break; + } + + current_ev = wext_translate_bss(current_ev, extra + IW_SCAN_MAX_DATA, &msg, info); + scan_good = 1; + i++; + } while (i < IW_MAX_AP); + + srq->length = (current_ev - extra); + srq->flags = 0; /* todo */ + + if (result && !scan_good) + err = prism2_result2err (msg.resultcode.data); + exit: + DBFEXIT; + return err; +} +#endif + +/*****************************************************/ +//extra wireless extensions stuff to support NetworkManager (I hope) + +#if WIRELESS_EXT > 17 +/* SIOCSIWENCODEEXT */ +static int p80211wext_set_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + p80211msg_dot11req_mibset_t msg; + p80211item_pstr32_t *pstr; + + int result = 0; + struct iw_point *encoding = &wrqu->encoding; + int idx = encoding->flags & IW_ENCODE_INDEX; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + result = -EBUSY; + goto exit; + } + + WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len); + + + if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) { + // set default key ? I'm not sure if this the the correct thing to do here + + if ( idx ) { + if (idx < 1 || idx > NUM_WEPKEYS) { + return -EINVAL; + } else + idx--; + } + WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx); + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx); + if ( result ) + return -EFAULT; + } + + + if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) { + if ( ! ext->alg & IW_ENCODE_ALG_WEP) { + WLAN_LOG_DEBUG(1,"asked to set a non wep key :("); + return -EINVAL; + } + if (idx) { + if (idx <1 || idx > NUM_WEPKEYS) + return -EINVAL; + else + idx--; + } + WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx); + wlandev->wep_keylens[idx] = ext->key_len; + memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len); + + memset( &msg,0,sizeof(msg)); + pstr = (p80211item_pstr32_t*)&msg.mibattribute.data; + memcpy(pstr->data.data, ext->key,ext->key_len); + pstr->data.len = ext->key_len; + switch (idx) { + case 0: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0; + break; + case 1: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1; + break; + case 2: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2; + break; + case 3: + pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3; + break; + default: + break; + } + msg.msgcode = DIDmsg_dot11req_mibset; + result = p80211req_dorequest(wlandev,(UINT8*)&msg); + WLAN_LOG_DEBUG(1,"result (%d)\n",result); + } + exit: + DBFEXIT; + return result; +} + +/* SIOCGIWENCODEEXT */ +static int p80211wext_get_encodeext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) + +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + + struct iw_point *encoding = &wrqu->encoding; + int result = 0; + int max_len; + int idx; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + result = -EBUSY; + goto exit; + } + + + WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len); + + + max_len = encoding->length - sizeof(*ext); + if ( max_len <= 0) { + WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len); + result = -EINVAL; + goto exit; + } + idx = encoding->flags & IW_ENCODE_INDEX; + + WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx); + + if (idx) { + if (idx < 1 || idx > NUM_WEPKEYS ) { + WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx); + result = -EINVAL; + goto exit; + } + idx--; + } else { + /* default key ? not sure what to do */ + /* will just use key[0] for now ! FIX ME */ + } + + encoding->flags = idx + 1; + memset(ext,0,sizeof(*ext)); + + ext->alg = IW_ENCODE_ALG_WEP; + ext->key_len = wlandev->wep_keylens[idx]; + memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len ); + + encoding->flags |= IW_ENCODE_ENABLED; +exit: + DBFEXIT; + + return result; +} + + +/* SIOCSIWAUTH */ +static int p80211_wext_set_iwauth (struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_param *param = &wrqu->param; + int result =0; + + DBFENTER; + if ( invalid_state(wlandev) ) { + WLAN_LOG_DEBUG(1,"called from invalid state [%d]\n",wlandev->msdstate); + result = -EBUSY; + goto exit; + } + + + WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX ); + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_DROP_UNENCRYPTED: + WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value); + if (param->value) + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true); + else + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false); + break; + + case IW_AUTH_PRIVACY_INVOKED: + WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value); + if ( param->value) + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true); + else + result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false); + + break; + + case IW_AUTH_80211_AUTH_ALG: + if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) { + WLAN_LOG_DEBUG(1,"set open_system\n"); + wlandev->hostwep &= ~HOSTWEP_SHAREDKEY; + } else if ( param->value & IW_AUTH_ALG_SHARED_KEY) { + WLAN_LOG_DEBUG(1,"set shared key\n"); + wlandev->hostwep |= HOSTWEP_SHAREDKEY; + } else { + /* don't know what to do know :( */ + WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value); + result = -EINVAL; + } + break; + + default: + break; + } + + exit: + DBFEXIT; + return result; +} + +/* SIOCSIWAUTH */ +static int p80211_wext_get_iwauth (struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + struct iw_param *param = &wrqu->param; + int result =0; + + DBFENTER; + WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX ); + + switch (param->flags & IW_AUTH_INDEX) { + case IW_AUTH_DROP_UNENCRYPTED: + param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0; + break; + + case IW_AUTH_PRIVACY_INVOKED: + param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0; + break; + + case IW_AUTH_80211_AUTH_ALG: + param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM; + break; + + + default: + break; + } + + DBFEXIT; + + return result; +} + + +#endif + + + + + + +/*****************************************************/ + + + + + +/* +typedef int (*iw_handler)(netdevice_t *dev, struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +*/ + +#if WIRELESS_EXT > 12 +static iw_handler p80211wext_handlers[] = { + (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */ + (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */ + (iw_handler) NULL, /* SIOCSIWNWID */ + (iw_handler) NULL, /* SIOCGIWNWID */ + (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */ + (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */ + (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */ + (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */ + (iw_handler) NULL, /* SIOCSIWSENS */ + (iw_handler) NULL, /* SIOCGIWSENS */ + (iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */ + (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */ + (iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */ + (iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */ + (iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */ + (iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */ + (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */ + (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWAP */ + (iw_handler) p80211wext_giwap, /* SIOCGIWAP */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCGIWAPLIST */ +#if WIRELESS_EXT > 13 + (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */ + (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */ +#else /* WIRELESS_EXT > 13 */ + (iw_handler) NULL, /* null */ /* SIOCSIWSCAN */ + (iw_handler) NULL, /* null */ /* SIOCGIWSCAN */ +#endif /* WIRELESS_EXT > 13 */ + (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */ + (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */ + (iw_handler) NULL, /* SIOCSIWNICKN */ + (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWRATE */ + (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */ + (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */ + (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */ + (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */ + (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */ + (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */ + (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */ + (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */ + (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */ + (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */ + (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */ + (iw_handler) NULL, /* SIOCSIWPOWER */ + (iw_handler) NULL, /* SIOCGIWPOWER */ +#if WIRELESS_EXT > 17 +/* WPA operations */ + + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* -- hole -- */ + (iw_handler) NULL, /* SIOCSIWGENIE set generic IE */ + (iw_handler) NULL, /* SIOCGIWGENIE get generic IE */ + (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */ + (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */ + + (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */ + (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */ + (iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */ +#endif +}; + +struct iw_handler_def p80211wext_handler_def = { + .num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler), + .num_private = 0, + .num_private_args = 0, + .standard = p80211wext_handlers, + .private = NULL, + .private_args = NULL, +#if WIRELESS_EXT > 16 + .get_wireless_stats = p80211wext_get_wireless_stats +#endif +}; + +#endif + +/* wireless extensions' ioctls */ +int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd) +{ + wlandevice_t *wlandev = (wlandevice_t*)dev->priv; + +#if WIRELESS_EXT < 13 + struct iwreq *iwr = (struct iwreq*)ifr; +#endif + + p80211item_uint32_t mibitem; + int err = 0; + + DBFENTER; + + mibitem.status = P80211ENUM_msgitem_status_data_ok; + + if ( wlandev->msdstate != WLAN_MSD_RUNNING ) { + err = -ENODEV; + goto exit; + } + + WLAN_LOG_DEBUG(1, "Received wireless extension ioctl #%d.\n", cmd); + + switch (cmd) { +#if WIRELESS_EXT < 13 + case SIOCSIWNAME: /* unused */ + err = (-EOPNOTSUPP); + break; + case SIOCGIWNAME: /* get name == wireless protocol */ + err = p80211wext_giwname(dev, NULL, (char *) &iwr->u, NULL); + break; + case SIOCSIWNWID: + case SIOCGIWNWID: + err = (-EOPNOTSUPP); + break; + case SIOCSIWFREQ: /* set channel */ + err = p80211wext_siwfreq(dev, NULL, &(iwr->u.freq), NULL); + break; + case SIOCGIWFREQ: /* get channel */ + err = p80211wext_giwfreq(dev, NULL, &(iwr->u.freq), NULL); + break; + case SIOCSIWRANGE: + case SIOCSIWPRIV: + case SIOCSIWAP: /* set access point MAC addresses (BSSID) */ + err = (-EOPNOTSUPP); + break; + + case SIOCGIWAP: /* get access point MAC addresses (BSSID) */ + err = p80211wext_giwap(dev, NULL, &(iwr->u.ap_addr), NULL); + break; + +#if WIRELESS_EXT > 8 + case SIOCSIWMODE: /* set operation mode */ + case SIOCSIWESSID: /* set SSID (network name) */ + case SIOCSIWRATE: /* set default bit rate (bps) */ + err = (-EOPNOTSUPP); + break; + + case SIOCGIWMODE: /* get operation mode */ + err = p80211wext_giwmode(dev, NULL, &iwr->u.mode, NULL); + + break; + case SIOCGIWNICKN: /* get node name/nickname */ + case SIOCGIWESSID: /* get SSID */ + if(iwr->u.essid.pointer) { + char ssid[IW_ESSID_MAX_SIZE+1]; + memset(ssid, 0, sizeof(ssid)); + + err = p80211wext_giwessid(dev, NULL, &iwr->u.essid, ssid); + if(copy_to_user(iwr->u.essid.pointer, ssid, sizeof(ssid))) + err = (-EFAULT); + } + break; + case SIOCGIWRATE: + err = p80211wext_giwrate(dev, NULL, &iwr->u.bitrate, NULL); + break; + case SIOCGIWRTS: + err = p80211wext_giwrts(dev, NULL, &iwr->u.rts, NULL); + break; + case SIOCGIWFRAG: + err = p80211wext_giwfrag(dev, NULL, &iwr->u.rts, NULL); + break; + case SIOCGIWENCODE: + if (!capable(CAP_NET_ADMIN)) + err = -EPERM; + else if (iwr->u.encoding.pointer) { + char keybuf[MAX_KEYLEN]; + err = p80211wext_giwencode(dev, NULL, + &iwr->u.encoding, keybuf); + if (copy_to_user(iwr->u.encoding.pointer, keybuf, + iwr->u.encoding.length)) + err = -EFAULT; + } + break; + case SIOCGIWAPLIST: + case SIOCSIWRTS: + case SIOCSIWFRAG: + case SIOCSIWSENS: + case SIOCGIWSENS: + case SIOCSIWNICKN: /* set node name/nickname */ + case SIOCSIWENCODE: /* set encoding token & mode */ + case SIOCSIWSPY: + case SIOCGIWSPY: + case SIOCSIWPOWER: + case SIOCGIWPOWER: + case SIOCGIWPRIV: + err = (-EOPNOTSUPP); + break; + case SIOCGIWRANGE: + if(iwr->u.data.pointer != NULL) { + struct iw_range range; + err = p80211wext_giwrange(dev, NULL, &iwr->u.data, + (char *) &range); + /* Push that up to the caller */ + if (copy_to_user(iwr->u.data.pointer, &range, sizeof(range))) + err = -EFAULT; + } + break; +#endif /* WIRELESS_EXT > 8 */ +#if WIRELESS_EXT > 9 + case SIOCSIWTXPOW: + err = (-EOPNOTSUPP); + break; + case SIOCGIWTXPOW: + err = p80211wext_giwtxpow(dev, NULL, &iwr->u.txpower, NULL); + break; +#endif /* WIRELESS_EXT > 9 */ +#if WIRELESS_EXT > 10 + case SIOCSIWRETRY: + err = (-EOPNOTSUPP); + break; + case SIOCGIWRETRY: + err = p80211wext_giwretry(dev, NULL, &iwr->u.retry, NULL); + break; +#endif /* WIRELESS_EXT > 10 */ + +#endif /* WIRELESS_EXT <= 12 */ + + default: + err = (-EOPNOTSUPP); + break; + } + + exit: + DBFEXIT; + return (err); +} + +int p80211wext_event_associated(wlandevice_t *wlandev, int assoc) +{ + union iwreq_data data; + + DBFENTER; + +#if WIRELESS_EXT > 13 + /* Send the association state first */ + data.ap_addr.sa_family = ARPHRD_ETHER; + if (assoc) { + memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN); + } else { + memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN); + } + + if (wlan_wext_write) + wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL); + + if (!assoc) goto done; + + // XXX send association data, like IEs, etc etc. +#endif + done: + DBFEXIT; + return 0; +} + + +#endif /* compatibility to wireless extensions */ + + + + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211hdr.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211hdr.h @@ -0,0 +1,299 @@ +/* src/include/wlan/p80211hdr.h +* +* Macros, types, and functions for handling 802.11 MAC headers +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the constants and types used in the interface +* between a wlan driver and the user mode utilities. +* +* Note: +* - Constant values are always in HOST byte order. To assign +* values to multi-byte fields they _must_ be converted to +* ieee byte order. To retrieve multi-byte values from incoming +* frames, they must be converted to host order. +* +* All functions declared here are implemented in p80211.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211HDR_H +#define _P80211HDR_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + + +/*================================================================*/ +/* Constants */ + +/*--- Sizes -----------------------------------------------*/ +#define WLAN_ADDR_LEN 6 +#define WLAN_CRC_LEN 4 +#define WLAN_BSSID_LEN 6 +#define WLAN_BSS_TS_LEN 8 +#define WLAN_HDR_A3_LEN 24 +#define WLAN_HDR_A4_LEN 30 +#define WLAN_SSID_MAXLEN 32 +#define WLAN_DATA_MAXLEN 2312 +#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) +#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) +#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334) +#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0) +#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48) +#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54) +#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44) +#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78) +#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261) +#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_WEP_NKEYS 4 +#define WLAN_WEP_MAXKEYLEN 13 +#define WLAN_CHALLENGE_IE_LEN 130 +#define WLAN_CHALLENGE_LEN 128 +#define WLAN_WEP_IV_LEN 4 +#define WLAN_WEP_ICV_LEN 4 + +/*--- Frame Control Field -------------------------------------*/ +/* Frame Types */ +#define WLAN_FTYPE_MGMT 0x00 +#define WLAN_FTYPE_CTL 0x01 +#define WLAN_FTYPE_DATA 0x02 + +/* Frame subtypes */ +/* Management */ +#define WLAN_FSTYPE_ASSOCREQ 0x00 +#define WLAN_FSTYPE_ASSOCRESP 0x01 +#define WLAN_FSTYPE_REASSOCREQ 0x02 +#define WLAN_FSTYPE_REASSOCRESP 0x03 +#define WLAN_FSTYPE_PROBEREQ 0x04 +#define WLAN_FSTYPE_PROBERESP 0x05 +#define WLAN_FSTYPE_BEACON 0x08 +#define WLAN_FSTYPE_ATIM 0x09 +#define WLAN_FSTYPE_DISASSOC 0x0a +#define WLAN_FSTYPE_AUTHEN 0x0b +#define WLAN_FSTYPE_DEAUTHEN 0x0c + +/* Control */ +#define WLAN_FSTYPE_BLOCKACKREQ 0x8 +#define WLAN_FSTYPE_BLOCKACK 0x9 +#define WLAN_FSTYPE_PSPOLL 0x0a +#define WLAN_FSTYPE_RTS 0x0b +#define WLAN_FSTYPE_CTS 0x0c +#define WLAN_FSTYPE_ACK 0x0d +#define WLAN_FSTYPE_CFEND 0x0e +#define WLAN_FSTYPE_CFENDCFACK 0x0f + +/* Data */ +#define WLAN_FSTYPE_DATAONLY 0x00 +#define WLAN_FSTYPE_DATA_CFACK 0x01 +#define WLAN_FSTYPE_DATA_CFPOLL 0x02 +#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03 +#define WLAN_FSTYPE_NULL 0x04 +#define WLAN_FSTYPE_CFACK 0x05 +#define WLAN_FSTYPE_CFPOLL 0x06 +#define WLAN_FSTYPE_CFACK_CFPOLL 0x07 + + +/*================================================================*/ +/* Macros */ + +/*--- FC Macros ----------------------------------------------*/ +/* Macros to get/set the bitfields of the Frame Control Field */ +/* GET_FC_??? - takes the host byte-order value of an FC */ +/* and retrieves the value of one of the */ +/* bitfields and moves that value so its lsb is */ +/* in bit 0. */ +/* SET_FC_??? - takes a host order value for one of the FC */ +/* bitfields and moves it to the proper bit */ +/* location for ORing into a host order FC. */ +/* To send the FC produced from SET_FC_???, */ +/* one must put the bytes in IEEE order. */ +/* e.g. */ +/* printf("the frame subtype is %x", */ +/* GET_FC_FTYPE( ieee2host( rx.fc ))) */ +/* */ +/* tx.fc = host2ieee( SET_FC_FTYPE(WLAN_FTYP_CTL) | */ +/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */ +/*------------------------------------------------------------*/ + +#define WLAN_GET_FC_PVER(n) (((UINT16)(n)) & (BIT0 | BIT1)) +#define WLAN_GET_FC_FTYPE(n) ((((UINT16)(n)) & (BIT2 | BIT3)) >> 2) +#define WLAN_GET_FC_FSTYPE(n) ((((UINT16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4) +#define WLAN_GET_FC_TODS(n) ((((UINT16)(n)) & (BIT8)) >> 8) +#define WLAN_GET_FC_FROMDS(n) ((((UINT16)(n)) & (BIT9)) >> 9) +#define WLAN_GET_FC_MOREFRAG(n) ((((UINT16)(n)) & (BIT10)) >> 10) +#define WLAN_GET_FC_RETRY(n) ((((UINT16)(n)) & (BIT11)) >> 11) +#define WLAN_GET_FC_PWRMGT(n) ((((UINT16)(n)) & (BIT12)) >> 12) +#define WLAN_GET_FC_MOREDATA(n) ((((UINT16)(n)) & (BIT13)) >> 13) +#define WLAN_GET_FC_ISWEP(n) ((((UINT16)(n)) & (BIT14)) >> 14) +#define WLAN_GET_FC_ORDER(n) ((((UINT16)(n)) & (BIT15)) >> 15) + +#define WLAN_SET_FC_PVER(n) ((UINT16)(n)) +#define WLAN_SET_FC_FTYPE(n) (((UINT16)(n)) << 2) +#define WLAN_SET_FC_FSTYPE(n) (((UINT16)(n)) << 4) +#define WLAN_SET_FC_TODS(n) (((UINT16)(n)) << 8) +#define WLAN_SET_FC_FROMDS(n) (((UINT16)(n)) << 9) +#define WLAN_SET_FC_MOREFRAG(n) (((UINT16)(n)) << 10) +#define WLAN_SET_FC_RETRY(n) (((UINT16)(n)) << 11) +#define WLAN_SET_FC_PWRMGT(n) (((UINT16)(n)) << 12) +#define WLAN_SET_FC_MOREDATA(n) (((UINT16)(n)) << 13) +#define WLAN_SET_FC_ISWEP(n) (((UINT16)(n)) << 14) +#define WLAN_SET_FC_ORDER(n) (((UINT16)(n)) << 15) + +/*--- Duration Macros ----------------------------------------*/ +/* Macros to get/set the bitfields of the Duration Field */ +/* - the duration value is only valid when bit15 is zero */ +/* - the firmware handles these values, so I'm not going */ +/* these macros right now. */ +/*------------------------------------------------------------*/ + +/*--- Sequence Control Macros -------------------------------*/ +/* Macros to get/set the bitfields of the Sequence Control */ +/* Field. */ +/*------------------------------------------------------------*/ +#define WLAN_GET_SEQ_FRGNUM(n) (((UINT16)(n)) & (BIT0|BIT1|BIT2|BIT3)) +#define WLAN_GET_SEQ_SEQNUM(n) ((((UINT16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4) + +/*--- Data ptr macro -----------------------------------------*/ +/* Creates a UINT8* to the data portion of a frame */ +/* Assumes you're passing in a ptr to the beginning of the hdr*/ +/*------------------------------------------------------------*/ +#define WLAN_HDR_A3_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A3_LEN) +#define WLAN_HDR_A4_DATAP(p) (((UINT8*)(p)) + WLAN_HDR_A4_LEN) + +#define DOT11_RATE5_ISBASIC_GET(r) (((UINT8)(r)) & BIT7) + +/*================================================================*/ +/* Types */ + +/* BSS Timestamp */ +typedef UINT8 wlan_bss_ts_t[WLAN_BSS_TS_LEN]; + +/* Generic 802.11 Header types */ + +typedef struct p80211_hdr_a3 +{ + UINT16 fc; + UINT16 dur; + UINT8 a1[WLAN_ADDR_LEN]; + UINT8 a2[WLAN_ADDR_LEN]; + UINT8 a3[WLAN_ADDR_LEN]; + UINT16 seq; +} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t; + +typedef struct p80211_hdr_a4 +{ + UINT16 fc; + UINT16 dur; + UINT8 a1[WLAN_ADDR_LEN]; + UINT8 a2[WLAN_ADDR_LEN]; + UINT8 a3[WLAN_ADDR_LEN]; + UINT16 seq; + UINT8 a4[WLAN_ADDR_LEN]; +} __WLAN_ATTRIB_PACK__ p80211_hdr_a4_t; + +typedef union p80211_hdr +{ + p80211_hdr_a3_t a3; + p80211_hdr_a4_t a4; +} __WLAN_ATTRIB_PACK__ p80211_hdr_t; + + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + +/* Frame and header lenght macros */ + +#define WLAN_CTL_FRAMELEN(fstype) (\ + (fstype) == WLAN_FSTYPE_BLOCKACKREQ ? 24 : \ + (fstype) == WLAN_FSTYPE_BLOCKACK ? 152 : \ + (fstype) == WLAN_FSTYPE_PSPOLL ? 20 : \ + (fstype) == WLAN_FSTYPE_RTS ? 20 : \ + (fstype) == WLAN_FSTYPE_CTS ? 14 : \ + (fstype) == WLAN_FSTYPE_ACK ? 14 : \ + (fstype) == WLAN_FSTYPE_CFEND ? 20 : \ + (fstype) == WLAN_FSTYPE_CFENDCFACK ? 20 : 4) + +#define WLAN_FCS_LEN 4 + +/* ftcl in HOST order */ +inline static UINT16 p80211_headerlen(UINT16 fctl) +{ + UINT16 hdrlen = 0; + + switch ( WLAN_GET_FC_FTYPE(fctl) ) { + case WLAN_FTYPE_MGMT: + hdrlen = WLAN_HDR_A3_LEN; + break; + case WLAN_FTYPE_DATA: + hdrlen = WLAN_HDR_A3_LEN; + if ( WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl) ) { + hdrlen += WLAN_ADDR_LEN; + } + break; + case WLAN_FTYPE_CTL: + hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) - + WLAN_FCS_LEN; + break; + default: + hdrlen = WLAN_HDR_A3_LEN; + } + + return hdrlen; +} + +#endif /* _P80211HDR_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211meta.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211meta.h @@ -0,0 +1,169 @@ +/* src/include/wlan/p80211meta.h +* +* Macros, constants, types, and funcs for p80211 metadata +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211META_H +#define _P80211META_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Macros */ + +/*----------------------------------------------------------------*/ +/* The following macros are used to ensure consistent naming */ +/* conventions for all the different metadata lists. */ + +#define MKREQMETANAME(name) p80211meta_ ## req ## _ ## name +#define MKINDMETANAME(name) p80211meta_ ## ind ## _ ## name +#define MKMIBMETANAME(name) p80211meta_ ## mib ## _ ## name +#define MKGRPMETANAME(name) p80211meta_ ## grp ## _ ## name + +#define MKREQMETASIZE(name) p80211meta_ ## req ## _ ## name ## _ ## size +#define MKINDMETASIZE(name) p80211meta_ ## ind ## _ ## name ## _ ## size +#define MKMIBMETASIZE(name) p80211meta_ ## mib ## _ ## name ## _ ## size +#define MKGRPMETASIZE(name) p80211meta_ ## grp ## _ ## name ## _ ## size + +#define GETMETASIZE(aptr) (**((UINT32**)(aptr))) + +/*----------------------------------------------------------------*/ +/* The following ifdef depends on the following defines: */ +/* P80211_NOINCLUDESTRINGS - if defined, all metadata name fields */ +/* are empty strings */ + +#ifdef P80211_NOINCLUDESTRINGS + #define MKITEMNAME(s) ("") +#else + #define MKITEMNAME(s) (s) +#endif + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* The following structure types are used for the metadata */ +/* representation of category list metadata, group list metadata, */ +/* and data item metadata for both Mib and Messages. */ + +typedef struct p80211meta +{ + char *name; /* data item name */ + UINT32 did; /* partial did */ + UINT32 flags; /* set of various flag bits */ + UINT32 min; /* min value of a BOUNDEDINT */ + UINT32 max; /* max value of a BOUNDEDINT */ + + UINT32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */ + UINT32 minlen; /* minlen of a OCTETSTR or DISPLAYSTR */ + p80211enum_t *enumptr; /* ptr to the enum type for ENUMINT */ + p80211_totext_t totextptr; /* ptr to totext conversion function */ + p80211_fromtext_t fromtextptr; /* ptr to totext conversion function */ + p80211_valid_t validfunptr; /* ptr to totext conversion function */ +} p80211meta_t; + +typedef struct grplistitem +{ + char *name; + p80211meta_t *itemlist; +} grplistitem_t; + +typedef struct catlistitem +{ + char *name; + grplistitem_t *grplist; +} catlistitem_t; + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* */ +UINT32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname); +UINT32 p80211_text2catdid(catlistitem_t *list, char *name ); +UINT32 p80211_text2grpdid(grplistitem_t *list, char *name ); +UINT32 p80211_text2itemdid(p80211meta_t *list, char *name ); +UINT32 p80211_isvalid_did( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211_isvalid_catdid( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211_isvalid_grpdid( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211_isvalid_itemdid( catlistitem_t *catlist, UINT32 did ); +catlistitem_t *p80211_did2cat( catlistitem_t *catlist, UINT32 did ); +grplistitem_t *p80211_did2grp( catlistitem_t *catlist, UINT32 did ); +p80211meta_t *p80211_did2item( catlistitem_t *catlist, UINT32 did ); +UINT32 p80211item_maxdatalen( struct catlistitem *metalist, UINT32 did ); +UINT32 p80211_metaname2did(struct catlistitem *metalist, char *itemname); +UINT32 p80211item_getoffset( struct catlistitem *metalist, UINT32 did ); +int p80211item_gettype(p80211meta_t *meta); + +#endif /* _P80211META_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211conv.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211conv.h @@ -0,0 +1,186 @@ +/* src/include/wlan/p80211conv.h +* +* Ether/802.11 conversions and packet buffer routines +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the functions, types and macros that perform +* Ethernet to/from 802.11 frame conversions. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _LINUX_P80211CONV_H +#define _LINUX_P80211CONV_H + +/*================================================================*/ +/* Constants */ + +#define WLAN_ETHADDR_LEN 6 +#define WLAN_IEEE_OUI_LEN 3 + +#define WLAN_ETHCONV_ENCAP 1 +#define WLAN_ETHCONV_RFC1042 2 +#define WLAN_ETHCONV_8021h 3 + +#define WLAN_MIN_ETHFRM_LEN 60 +#define WLAN_MAX_ETHFRM_LEN 1514 +#define WLAN_ETHHDR_LEN 14 + +#define P80211CAPTURE_VERSION 0x80211001 + +/*================================================================*/ +/* Macros */ + +#define P80211_FRMMETA_MAGIC 0x802110 + +#define P80211SKB_FRMMETA(s) \ + (((((p80211_frmmeta_t*)((s)->cb))->magic)==P80211_FRMMETA_MAGIC) ? \ + ((p80211_frmmeta_t*)((s)->cb)) : \ + (NULL)) + +#define P80211SKB_RXMETA(s) \ + (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t*)(NULL))) + +typedef struct p80211_rxmeta +{ + struct wlandevice *wlandev; + + UINT64 mactime; /* Hi-rez MAC-supplied time value */ + UINT64 hosttime; /* Best-rez host supplied time value */ + + UINT rxrate; /* Receive data rate in 100kbps */ + UINT priority; /* 0-15, 0=contention, 6=CF */ + INT signal; /* An SSI, see p80211netdev.h */ + INT noise; /* An SSI, see p80211netdev.h */ + UINT channel; /* Receive channel (mostly for snifs) */ + UINT preamble; /* P80211ENUM_preambletype_* */ + UINT encoding; /* P80211ENUM_encoding_* */ + +} p80211_rxmeta_t; + +typedef struct p80211_frmmeta +{ + UINT magic; + p80211_rxmeta_t *rx; +} p80211_frmmeta_t; + +void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb); +int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb); +void p80211skb_rxmeta_detach(struct sk_buff *skb); + +/*================================================================*/ +/* Types */ + +/* + * Frame capture header. (See doc/capturefrm.txt) + */ +typedef struct p80211_caphdr +{ + UINT32 version; + UINT32 length; + UINT64 mactime; + UINT64 hosttime; + UINT32 phytype; + UINT32 channel; + UINT32 datarate; + UINT32 antenna; + UINT32 priority; + UINT32 ssi_type; + INT32 ssi_signal; + INT32 ssi_noise; + UINT32 preamble; + UINT32 encoding; +} p80211_caphdr_t; + +/* buffer free method pointer type */ +typedef void (* freebuf_method_t)(void *buf, int size); + +typedef struct p80211_metawep { + void *data; + UINT8 iv[4]; + UINT8 icv[4]; +} p80211_metawep_t; + +/* local ether header type */ +typedef struct wlan_ethhdr +{ + UINT8 daddr[WLAN_ETHADDR_LEN]; + UINT8 saddr[WLAN_ETHADDR_LEN]; + UINT16 type; +} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t; + +/* local llc header type */ +typedef struct wlan_llc +{ + UINT8 dsap; + UINT8 ssap; + UINT8 ctl; +} __WLAN_ATTRIB_PACK__ wlan_llc_t; + +/* local snap header type */ +typedef struct wlan_snap +{ + UINT8 oui[WLAN_IEEE_OUI_LEN]; + UINT16 type; +} __WLAN_ATTRIB_PACK__ wlan_snap_t; + +/* Circular include trick */ +struct wlandevice; + +/*================================================================*/ +/* Externs */ + +/*================================================================*/ +/*Function Declarations */ + +int skb_p80211_to_ether( struct wlandevice *wlandev, UINT32 ethconv, + struct sk_buff *skb); +int skb_ether_to_p80211( struct wlandevice *wlandev, UINT32 ethconv, + struct sk_buff *skb, p80211_hdr_t *p80211_hdr, + p80211_metawep_t *p80211_wep ); + +int p80211_stt_findproto(UINT16 proto); +int p80211_stt_addproto(UINT16 proto); + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metamsg.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metamsg.h @@ -0,0 +1,105 @@ +/* src/include/wlan/p80211metamsg.h +* +* Macros, const, types, and funcs for p80211 msg metadata +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211METAMSG_H +#define _P80211METAMSG_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Macros */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* The following is the external declaration for the message */ +/* category metadata list */ + +extern catlistitem_t msg_catlist[]; +extern UINT32 msg_catlist_size; + + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* */ + +#endif /* _P80211METAMSG_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211msg.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211msg.h @@ -0,0 +1,102 @@ +/* src/include/wlan/p80211msg.h +* +* Macros, constants, types, and funcs for req and ind messages +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MSG_H +#define _P80211MSG_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +#define MSG_BUFF_LEN 4000 +#define WLAN_DEVNAMELEN_MAX 16 + +/*================================================================*/ +/* Macros */ + +/*================================================================*/ +/* Types */ + +/*--------------------------------------------------------------------*/ +/*----- Message Structure Types --------------------------------------*/ + +/*--------------------------------------------------------------------*/ +/* Prototype msg type */ + +typedef struct p80211msg +{ + UINT32 msgcode; + UINT32 msglen; + UINT8 devname[WLAN_DEVNAMELEN_MAX]; +} __WLAN_ATTRIB_PACK__ p80211msg_t; + +typedef struct p80211msgd +{ + UINT32 msgcode; + UINT32 msglen; + UINT8 devname[WLAN_DEVNAMELEN_MAX]; + UINT8 args[0]; +} __WLAN_ATTRIB_PACK__ p80211msgd_t; + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + +#endif /* _P80211MSG_H */ + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211mgmt.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211mgmt.h @@ -0,0 +1,575 @@ +/* src/include/wlan/p80211mgmt.h +* +* Macros, types, and functions to handle 802.11 mgmt frames +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the constants and types used in the interface +* between a wlan driver and the user mode utilities. +* +* Notes: +* - Constant values are always in HOST byte order. To assign +* values to multi-byte fields they _must_ be converted to +* ieee byte order. To retrieve multi-byte values from incoming +* frames, they must be converted to host order. +* +* - The len member of the frame structure does NOT!!! include +* the MAC CRC. Therefore, the len field on rx'd frames should +* have 4 subtracted from it. +* +* All functions declared here are implemented in p80211.c +* +* The types, macros, and functions defined here are primarily +* used for encoding and decoding management frames. They are +* designed to follow these patterns of use: +* +* DECODE: +* 1) a frame of length len is received into buffer b +* 2) using the hdr structure and macros, we determine the type +* 3) an appropriate mgmt frame structure, mf, is allocated and zeroed +* 4) mf.hdr = b +* mf.buf = b +* mf.len = len +* 5) call mgmt_decode( mf ) +* 6) the frame field pointers in mf are now set. Note that any +* multi-byte frame field values accessed using the frame field +* pointers are in ieee byte order and will have to be converted +* to host order. +* +* ENCODE: +* 1) Library client allocates buffer space for maximum length +* frame of the desired type +* 2) Library client allocates a mgmt frame structure, called mf, +* of the desired type +* 3) Set the following: +* mf.type = +* mf.buf = +* 4) call mgmt_encode( mf ) +* 5) all of the fixed field pointers and fixed length information element +* pointers in mf are now set to their respective locations in the +* allocated space (fortunately, all variable length information elements +* fall at the end of their respective frames). +* 5a) The length field is set to include the last of the fixed and fixed +* length fields. It may have to be updated for optional or variable +* length information elements. +* 6) Optional and variable length information elements are special cases +* and must be handled individually by the client code. +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MGMT_H +#define _P80211MGMT_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +#ifndef _P80211HDR_H +#include +#endif + + +/*================================================================*/ +/* Constants */ + +/*-- Information Element IDs --------------------*/ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARMS 2 +#define WLAN_EID_DS_PARMS 3 +#define WLAN_EID_CF_PARMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARMS 6 +/*-- values 7-15 reserved --*/ +#define WLAN_EID_CHALLENGE 16 +/*-- values 17-31 reserved for challenge text extension --*/ +/*-- values 32-255 reserved --*/ + +/*-- Reason Codes -------------------------------*/ +#define WLAN_MGMT_REASON_RSVD 0 +#define WLAN_MGMT_REASON_UNSPEC 1 +#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2 +#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3 +#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4 +#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6 +#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7 +#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8 +#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9 + +/*-- Status Codes -------------------------------*/ +#define WLAN_MGMT_STATUS_SUCCESS 0 +#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1 +#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13 +#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14 +#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15 +#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18 + /* p80211b additions */ +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21 + + + +/*-- Auth Algorithm Field ---------------------------*/ +#define WLAN_AUTH_ALG_OPENSYSTEM 0 +#define WLAN_AUTH_ALG_SHAREDKEY 1 + +/*-- Management Frame Field Offsets -------------*/ +/* Note: Not all fields are listed because of variable lengths, */ +/* see the code in p80211.c to see how we search for fields */ +/* Note: These offsets are from the start of the frame data */ + +#define WLAN_BEACON_OFF_TS 0 +#define WLAN_BEACON_OFF_BCN_INT 8 +#define WLAN_BEACON_OFF_CAPINFO 10 +#define WLAN_BEACON_OFF_SSID 12 + +#define WLAN_DISASSOC_OFF_REASON 0 + +#define WLAN_ASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_ASSOCREQ_OFF_SSID 4 + +#define WLAN_ASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_ASSOCRESP_OFF_STATUS 2 +#define WLAN_ASSOCRESP_OFF_AID 4 +#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_REASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_REASSOCREQ_OFF_CURR_AP 4 +#define WLAN_REASSOCREQ_OFF_SSID 10 + +#define WLAN_REASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_REASSOCRESP_OFF_STATUS 2 +#define WLAN_REASSOCRESP_OFF_AID 4 +#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_PROBEREQ_OFF_SSID 0 + +#define WLAN_PROBERESP_OFF_TS 0 +#define WLAN_PROBERESP_OFF_BCN_INT 8 +#define WLAN_PROBERESP_OFF_CAP_INFO 10 +#define WLAN_PROBERESP_OFF_SSID 12 + +#define WLAN_AUTHEN_OFF_AUTH_ALG 0 +#define WLAN_AUTHEN_OFF_AUTH_SEQ 2 +#define WLAN_AUTHEN_OFF_STATUS 4 +#define WLAN_AUTHEN_OFF_CHALLENGE 6 + +#define WLAN_DEAUTHEN_OFF_REASON 0 + + +/*================================================================*/ +/* Macros */ + +/*-- Capability Field ---------------------------*/ +#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT0) +#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1) +#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2) +#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3) +#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4) + /* p80211b additions */ +#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT5) >> 5) +#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6) +#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7) + +#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n) +#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1) +#define WLAN_SET_MGMT_CAP_INFO_CFPOLLABLE(n) ((n) << 2) +#define WLAN_SET_MGMT_CAP_INFO_CFPOLLREQ(n) ((n) << 3) +#define WLAN_SET_MGMT_CAP_INFO_PRIVACY(n) ((n) << 4) + /* p80211b additions */ +#define WLAN_SET_MGMT_CAP_INFO_SHORT(n) ((n) << 5) +#define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6) +#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7) + + +/*================================================================*/ +/* Types */ + +/*-- Information Element Types --------------------*/ +/* prototype structure, all IEs start with these members */ + +typedef struct wlan_ie +{ + UINT8 eid; + UINT8 len; +} __WLAN_ATTRIB_PACK__ wlan_ie_t; + +/*-- Service Set Identity (SSID) -----------------*/ +typedef struct wlan_ie_ssid +{ + UINT8 eid; + UINT8 len; + UINT8 ssid[1]; /* may be zero, ptrs may overlap */ +} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t; + +/*-- Supported Rates -----------------------------*/ +typedef struct wlan_ie_supp_rates +{ + UINT8 eid; + UINT8 len; + UINT8 rates[1]; /* had better be at LEAST one! */ +} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t; + +/*-- FH Parameter Set ----------------------------*/ +typedef struct wlan_ie_fh_parms +{ + UINT8 eid; + UINT8 len; + UINT16 dwell; + UINT8 hopset; + UINT8 hoppattern; + UINT8 hopindex; +} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t; + +/*-- DS Parameter Set ----------------------------*/ +typedef struct wlan_ie_ds_parms +{ + UINT8 eid; + UINT8 len; + UINT8 curr_ch; +} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t; + +/*-- CF Parameter Set ----------------------------*/ + +typedef struct wlan_ie_cf_parms +{ + UINT8 eid; + UINT8 len; + UINT8 cfp_cnt; + UINT8 cfp_period; + UINT16 cfp_maxdur; + UINT16 cfp_durremaining; +} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t; + +/*-- TIM ------------------------------------------*/ +typedef struct wlan_ie_tim +{ + UINT8 eid; + UINT8 len; + UINT8 dtim_cnt; + UINT8 dtim_period; + UINT8 bitmap_ctl; + UINT8 virt_bm[1]; +} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t; + +/*-- IBSS Parameter Set ---------------------------*/ +typedef struct wlan_ie_ibss_parms +{ + UINT8 eid; + UINT8 len; + UINT16 atim_win; +} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t; + +/*-- Challenge Text ------------------------------*/ +typedef struct wlan_ie_challenge +{ + UINT8 eid; + UINT8 len; + UINT8 challenge[1]; +} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t; + +/*-------------------------------------------------*/ +/* Frame Types */ + +/* prototype structure, all mgmt frame types will start with these members */ +typedef struct wlan_fr_mgmt +{ + UINT16 type; + UINT16 len; /* DOES NOT include CRC !!!!*/ + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ +} wlan_fr_mgmt_t; + +/*-- Beacon ---------------------------------------*/ +typedef struct wlan_fr_beacon +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT64 *ts; + UINT16 *bcn_int; + UINT16 *cap_info; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_fh_parms_t *fh_parms; + wlan_ie_ds_parms_t *ds_parms; + wlan_ie_cf_parms_t *cf_parms; + wlan_ie_ibss_parms_t *ibss_parms; + wlan_ie_tim_t *tim; + +} wlan_fr_beacon_t; + + +/*-- IBSS ATIM ------------------------------------*/ +typedef struct wlan_fr_ibssatim +{ + UINT16 type; + UINT16 len; + UINT8* buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + + /* this frame type has a null body */ + +} wlan_fr_ibssatim_t; + +/*-- Disassociation -------------------------------*/ +typedef struct wlan_fr_disassoc +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *reason; + + /*-- info elements ----------*/ + +} wlan_fr_disassoc_t; + +/*-- Association Request --------------------------*/ +typedef struct wlan_fr_assocreq +{ + UINT16 type; + UINT16 len; + UINT8* buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *listen_int; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_assocreq_t; + +/*-- Association Response -------------------------*/ +typedef struct wlan_fr_assocresp +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *status; + UINT16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_assocresp_t; + +/*-- Reassociation Request ------------------------*/ +typedef struct wlan_fr_reassocreq +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *listen_int; + UINT8 *curr_ap; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_reassocreq_t; + +/*-- Reassociation Response -----------------------*/ +typedef struct wlan_fr_reassocresp +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *cap_info; + UINT16 *status; + UINT16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_reassocresp_t; + +/*-- Probe Request --------------------------------*/ +typedef struct wlan_fr_probereq +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + +} wlan_fr_probereq_t; + +/*-- Probe Response -------------------------------*/ +typedef struct wlan_fr_proberesp +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT64 *ts; + UINT16 *bcn_int; + UINT16 *cap_info; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_fh_parms_t *fh_parms; + wlan_ie_ds_parms_t *ds_parms; + wlan_ie_cf_parms_t *cf_parms; + wlan_ie_ibss_parms_t *ibss_parms; +} wlan_fr_proberesp_t; + +/*-- Authentication -------------------------------*/ +typedef struct wlan_fr_authen +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *auth_alg; + UINT16 *auth_seq; + UINT16 *status; + /*-- info elements ----------*/ + wlan_ie_challenge_t *challenge; + +} wlan_fr_authen_t; + +/*-- Deauthenication -----------------------------*/ +typedef struct wlan_fr_deauthen +{ + UINT16 type; + UINT16 len; + UINT8 *buf; + p80211_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + void *priv; + /*-- fixed fields -----------*/ + UINT16 *reason; + + /*-- info elements ----------*/ + +} wlan_fr_deauthen_t; + + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + +void wlan_mgmt_encode_beacon( wlan_fr_beacon_t *f ); +void wlan_mgmt_decode_beacon( wlan_fr_beacon_t *f ); +void wlan_mgmt_encode_disassoc( wlan_fr_disassoc_t *f ); +void wlan_mgmt_decode_disassoc( wlan_fr_disassoc_t *f ); +void wlan_mgmt_encode_assocreq( wlan_fr_assocreq_t *f ); +void wlan_mgmt_decode_assocreq( wlan_fr_assocreq_t *f ); +void wlan_mgmt_encode_assocresp( wlan_fr_assocresp_t *f ); +void wlan_mgmt_decode_assocresp( wlan_fr_assocresp_t *f ); +void wlan_mgmt_encode_reassocreq( wlan_fr_reassocreq_t *f ); +void wlan_mgmt_decode_reassocreq( wlan_fr_reassocreq_t *f ); +void wlan_mgmt_encode_reassocresp( wlan_fr_reassocresp_t *f ); +void wlan_mgmt_decode_reassocresp( wlan_fr_reassocresp_t *f ); +void wlan_mgmt_encode_probereq( wlan_fr_probereq_t *f ); +void wlan_mgmt_decode_probereq( wlan_fr_probereq_t *f ); +void wlan_mgmt_encode_proberesp( wlan_fr_proberesp_t *f ); +void wlan_mgmt_decode_proberesp( wlan_fr_proberesp_t *f ); +void wlan_mgmt_encode_authen( wlan_fr_authen_t *f ); +void wlan_mgmt_decode_authen( wlan_fr_authen_t *f ); +void wlan_mgmt_encode_deauthen( wlan_fr_deauthen_t *f ); +void wlan_mgmt_decode_deauthen( wlan_fr_deauthen_t *f ); + + +#endif /* _P80211MGMT_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metastruct.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metastruct.h @@ -0,0 +1,644 @@ +/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY. +* -------------------------------------------------------------------- +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MKMETASTRUCT_H +#define _P80211MKMETASTRUCT_H + + +typedef struct p80211msg_dot11req_mibget +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk392_t mibattribute ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t; + +typedef struct p80211msg_dot11req_mibset +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk392_t mibattribute ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t; + +typedef struct p80211msg_dot11req_powermgmt +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t powermgmtmode ; + p80211item_uint32_t wakeup ; + p80211item_uint32_t receivedtims ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_powermgmt_t; + +typedef struct p80211msg_dot11req_scan +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t bsstype ; + p80211item_pstr6_t bssid ; + UINT8 pad_0C[1] ; + p80211item_pstr32_t ssid ; + UINT8 pad_1D[3] ; + p80211item_uint32_t scantype ; + p80211item_uint32_t probedelay ; + p80211item_pstr14_t channellist ; + UINT8 pad_2C[1] ; + p80211item_uint32_t minchanneltime ; + p80211item_uint32_t maxchanneltime ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t numbss ; + p80211item_uint32_t append ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_t; + +typedef struct p80211msg_dot11req_scan_results +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t bssindex ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t signal ; + p80211item_uint32_t noise ; + p80211item_pstr6_t bssid ; + UINT8 pad_3C[1] ; + p80211item_pstr32_t ssid ; + UINT8 pad_4D[3] ; + p80211item_uint32_t bsstype ; + p80211item_uint32_t beaconperiod ; + p80211item_uint32_t dtimperiod ; + p80211item_uint32_t timestamp ; + p80211item_uint32_t localtime ; + p80211item_uint32_t fhdwelltime ; + p80211item_uint32_t fhhopset ; + p80211item_uint32_t fhhoppattern ; + p80211item_uint32_t fhhopindex ; + p80211item_uint32_t dschannel ; + p80211item_uint32_t cfpcount ; + p80211item_uint32_t cfpperiod ; + p80211item_uint32_t cfpmaxduration ; + p80211item_uint32_t cfpdurremaining ; + p80211item_uint32_t ibssatimwindow ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t privacy ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t supprate1 ; + p80211item_uint32_t supprate2 ; + p80211item_uint32_t supprate3 ; + p80211item_uint32_t supprate4 ; + p80211item_uint32_t supprate5 ; + p80211item_uint32_t supprate6 ; + p80211item_uint32_t supprate7 ; + p80211item_uint32_t supprate8 ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_results_t; + +typedef struct p80211msg_dot11req_join +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t bssid ; + UINT8 pad_5C[1] ; + p80211item_uint32_t joinfailuretimeout ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t operationalrate1 ; + p80211item_uint32_t operationalrate2 ; + p80211item_uint32_t operationalrate3 ; + p80211item_uint32_t operationalrate4 ; + p80211item_uint32_t operationalrate5 ; + p80211item_uint32_t operationalrate6 ; + p80211item_uint32_t operationalrate7 ; + p80211item_uint32_t operationalrate8 ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_join_t; + +typedef struct p80211msg_dot11req_authenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_6C[1] ; + p80211item_uint32_t authenticationtype ; + p80211item_uint32_t authenticationfailuretimeout ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_authenticate_t; + +typedef struct p80211msg_dot11req_deauthenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_7C[1] ; + p80211item_uint32_t reasoncode ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_deauthenticate_t; + +typedef struct p80211msg_dot11req_associate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_8C[1] ; + p80211item_uint32_t associatefailuretimeout ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t privacy ; + p80211item_uint32_t listeninterval ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_associate_t; + +typedef struct p80211msg_dot11req_reassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t newapaddress ; + UINT8 pad_9C[1] ; + p80211item_uint32_t reassociatefailuretimeout ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t privacy ; + p80211item_uint32_t listeninterval ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reassociate_t; + +typedef struct p80211msg_dot11req_disassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_10C[1] ; + p80211item_uint32_t reasoncode ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_disassociate_t; + +typedef struct p80211msg_dot11req_reset +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t setdefaultmib ; + p80211item_pstr6_t macaddress ; + UINT8 pad_11C[1] ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_reset_t; + +typedef struct p80211msg_dot11req_start +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr32_t ssid ; + UINT8 pad_12D[3] ; + p80211item_uint32_t bsstype ; + p80211item_uint32_t beaconperiod ; + p80211item_uint32_t dtimperiod ; + p80211item_uint32_t cfpperiod ; + p80211item_uint32_t cfpmaxduration ; + p80211item_uint32_t fhdwelltime ; + p80211item_uint32_t fhhopset ; + p80211item_uint32_t fhhoppattern ; + p80211item_uint32_t dschannel ; + p80211item_uint32_t ibssatimwindow ; + p80211item_uint32_t probedelay ; + p80211item_uint32_t cfpollable ; + p80211item_uint32_t cfpollreq ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t operationalrate1 ; + p80211item_uint32_t operationalrate2 ; + p80211item_uint32_t operationalrate3 ; + p80211item_uint32_t operationalrate4 ; + p80211item_uint32_t operationalrate5 ; + p80211item_uint32_t operationalrate6 ; + p80211item_uint32_t operationalrate7 ; + p80211item_uint32_t operationalrate8 ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_start_t; + +typedef struct p80211msg_dot11ind_authenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_13C[1] ; + p80211item_uint32_t authenticationtype ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_authenticate_t; + +typedef struct p80211msg_dot11ind_deauthenticate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_14C[1] ; + p80211item_uint32_t reasoncode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_deauthenticate_t; + +typedef struct p80211msg_dot11ind_associate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_15C[1] ; + p80211item_uint32_t aid ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_associate_t; + +typedef struct p80211msg_dot11ind_reassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_16C[1] ; + p80211item_uint32_t aid ; + p80211item_pstr6_t oldapaddress ; + UINT8 pad_17C[1] ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_reassociate_t; + +typedef struct p80211msg_dot11ind_disassociate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t peerstaaddress ; + UINT8 pad_18C[1] ; + p80211item_uint32_t reasoncode ; +} __WLAN_ATTRIB_PACK__ p80211msg_dot11ind_disassociate_t; + +typedef struct p80211msg_lnxreq_ifstate +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t ifstate ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t; + +typedef struct p80211msg_lnxreq_wlansniff +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t channel ; + p80211item_uint32_t prismheader ; + p80211item_uint32_t wlanheader ; + p80211item_uint32_t keepwepflags ; + p80211item_uint32_t stripfcs ; + p80211item_uint32_t packet_trunc ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_wlansniff_t; + +typedef struct p80211msg_lnxreq_hostwep +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t decrypt ; + p80211item_uint32_t encrypt ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_hostwep_t; + +typedef struct p80211msg_lnxreq_commsquality +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t dbm ; + p80211item_uint32_t link ; + p80211item_uint32_t level ; + p80211item_uint32_t noise ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_commsquality_t; + +typedef struct p80211msg_lnxreq_autojoin +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr32_t ssid ; + UINT8 pad_19D[3] ; + p80211item_uint32_t authtype ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t; + +typedef struct p80211msg_lnxind_wlansniffrm +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t hosttime ; + p80211item_uint32_t mactime ; + p80211item_uint32_t channel ; + p80211item_uint32_t rssi ; + p80211item_uint32_t sq ; + p80211item_uint32_t signal ; + p80211item_uint32_t noise ; + p80211item_uint32_t rate ; + p80211item_uint32_t istx ; + p80211item_uint32_t frmlen ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_wlansniffrm_t; + +typedef struct p80211msg_lnxind_roam +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t reason ; +} __WLAN_ATTRIB_PACK__ p80211msg_lnxind_roam_t; + +typedef struct p80211msg_p2req_join +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_pstr6_t bssid ; + UINT8 pad_20C[1] ; + p80211item_uint32_t basicrate1 ; + p80211item_uint32_t basicrate2 ; + p80211item_uint32_t basicrate3 ; + p80211item_uint32_t basicrate4 ; + p80211item_uint32_t basicrate5 ; + p80211item_uint32_t basicrate6 ; + p80211item_uint32_t basicrate7 ; + p80211item_uint32_t basicrate8 ; + p80211item_uint32_t operationalrate1 ; + p80211item_uint32_t operationalrate2 ; + p80211item_uint32_t operationalrate3 ; + p80211item_uint32_t operationalrate4 ; + p80211item_uint32_t operationalrate5 ; + p80211item_uint32_t operationalrate6 ; + p80211item_uint32_t operationalrate7 ; + p80211item_uint32_t operationalrate8 ; + p80211item_pstr32_t ssid ; + UINT8 pad_21D[3] ; + p80211item_uint32_t channel ; + p80211item_uint32_t authtype ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_join_t; + +typedef struct p80211msg_p2req_readpda +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk1024_t pda ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t; + +typedef struct p80211msg_p2req_readcis +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_unk1024_t cis ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readcis_t; + +typedef struct p80211msg_p2req_auxport_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_state_t; + +typedef struct p80211msg_p2req_auxport_read +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk1024_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_read_t; + +typedef struct p80211msg_p2req_auxport_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk1024_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_auxport_write_t; + +typedef struct p80211msg_p2req_low_level +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t command ; + p80211item_uint32_t param0 ; + p80211item_uint32_t param1 ; + p80211item_uint32_t param2 ; + p80211item_uint32_t resp0 ; + p80211item_uint32_t resp1 ; + p80211item_uint32_t resp2 ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_low_level_t; + +typedef struct p80211msg_p2req_test_command +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t testcode ; + p80211item_uint32_t testparam ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t status ; + p80211item_uint32_t resp0 ; + p80211item_uint32_t resp1 ; + p80211item_uint32_t resp2 ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_test_command_t; + +typedef struct p80211msg_p2req_mmi_read +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t value ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_read_t; + +typedef struct p80211msg_p2req_mmi_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mmi_write_t; + +typedef struct p80211msg_p2req_ramdl_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t exeaddr ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_state_t; + +typedef struct p80211msg_p2req_ramdl_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk4096_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_write_t; + +typedef struct p80211msg_p2req_flashdl_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_state_t; + +typedef struct p80211msg_p2req_flashdl_write +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t addr ; + p80211item_uint32_t len ; + p80211item_unk4096_t data ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_write_t; + +typedef struct p80211msg_p2req_mm_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t enable ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_mm_state_t; + +typedef struct p80211msg_p2req_dump_state +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t level ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_dump_state_t; + +typedef struct p80211msg_p2req_channel_info +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t channellist ; + p80211item_uint32_t channeldwelltime ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t numchinfo ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_t; + +typedef struct p80211msg_p2req_channel_info_results +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t channel ; + p80211item_uint32_t resultcode ; + p80211item_uint32_t avgnoiselevel ; + p80211item_uint32_t peaknoiselevel ; + p80211item_uint32_t bssactive ; + p80211item_uint32_t pcfactive ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_channel_info_results_t; + +typedef struct p80211msg_p2req_enable +{ + UINT32 msgcode ; + UINT32 msglen ; + UINT8 devname[WLAN_DEVNAMELEN_MAX] ; + p80211item_uint32_t resultcode ; +} __WLAN_ATTRIB_PACK__ p80211msg_p2req_enable_t; + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211netdev.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211netdev.h @@ -0,0 +1,339 @@ +/* src/include/wlan/p80211netdev.h +* +* WLAN net device structure and functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares the structure type that represents each wlan +* interface. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _LINUX_P80211NETDEV_H +#define _LINUX_P80211NETDEV_H + +#include +#include + +/*================================================================*/ +/* Constants */ + +#define WLAN_DEVICE_CLOSED 0 +#define WLAN_DEVICE_OPEN 1 + +#define WLAN_MACMODE_NONE 0 +#define WLAN_MACMODE_IBSS_STA 1 +#define WLAN_MACMODE_ESS_STA 2 +#define WLAN_MACMODE_ESS_AP 3 + +/* MSD States */ +#define WLAN_MSD_START -1 +#define WLAN_MSD_DRIVERLOADED 0 +#define WLAN_MSD_HWPRESENT_PENDING 1 +#define WLAN_MSD_HWFAIL 2 +#define WLAN_MSD_HWPRESENT 3 +#define WLAN_MSD_FWLOAD_PENDING 4 +#define WLAN_MSD_FWLOAD 5 +#define WLAN_MSD_RUNNING_PENDING 6 +#define WLAN_MSD_RUNNING 7 + +#ifndef ETH_P_ECONET +#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */ +#endif + +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) + +#ifndef ARPHRD_IEEE80211 +#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */ +#endif + +#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */ +#define ARPHRD_IEEE80211_PRISM 802 +#endif + +/*--- NSD Capabilities Flags ------------------------------*/ +#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */ +#define P80211_NSDCAP_TIEDWEP 0x02 /* can't decouple en/de */ +#define P80211_NSDCAP_NOHOSTWEP 0x04 /* must use hardware wep */ +#define P80211_NSDCAP_PBCC 0x08 /* hardware supports PBCC */ +#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */ +#define P80211_NSDCAP_AGILITY 0x20 /* hardware supports */ +#define P80211_NSDCAP_AP_RETRANSMIT 0x40 /* nsd handles retransmits */ +#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */ +#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */ +#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */ + +/*================================================================*/ +/* Macros */ + +/*================================================================*/ +/* Types */ + +/* Received frame statistics */ +typedef struct p80211_frmrx_t +{ + UINT32 mgmt; + UINT32 assocreq; + UINT32 assocresp; + UINT32 reassocreq; + UINT32 reassocresp; + UINT32 probereq; + UINT32 proberesp; + UINT32 beacon; + UINT32 atim; + UINT32 disassoc; + UINT32 authen; + UINT32 deauthen; + UINT32 mgmt_unknown; + UINT32 ctl; + UINT32 pspoll; + UINT32 rts; + UINT32 cts; + UINT32 ack; + UINT32 cfend; + UINT32 cfendcfack; + UINT32 ctl_unknown; + UINT32 data; + UINT32 dataonly; + UINT32 data_cfack; + UINT32 data_cfpoll; + UINT32 data__cfack_cfpoll; + UINT32 null; + UINT32 cfack; + UINT32 cfpoll; + UINT32 cfack_cfpoll; + UINT32 data_unknown; + UINT32 decrypt; + UINT32 decrypt_err; +} p80211_frmrx_t; + +#ifdef WIRELESS_EXT +/* called by /proc/net/wireless */ +struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev); +/* wireless extensions' ioctls */ +int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd); +#if WIRELESS_EXT > 12 +extern struct iw_handler_def p80211wext_handler_def; +#endif + +int p80211wext_event_associated(struct wlandevice *wlandev, int assoc); + +#endif /* wireless extensions */ + +/* WEP stuff */ +#define NUM_WEPKEYS 4 +#define MAX_KEYLEN 32 + +#define HOSTWEP_DEFAULTKEY_MASK (BIT1|BIT0) +#define HOSTWEP_DECRYPT BIT4 +#define HOSTWEP_ENCRYPT BIT5 +#define HOSTWEP_PRIVACYINVOKED BIT6 +#define HOSTWEP_EXCLUDEUNENCRYPTED BIT7 + +extern int wlan_watchdog; +extern int wlan_wext_write; + +/* WLAN device type */ +typedef struct wlandevice +{ + struct wlandevice *next; /* link for list of devices */ + void *priv; /* private data for MSD */ + + /* Subsystem State */ + char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev()*/ + char *nsdname; + + UINT32 state; /* Device I/F state (open/closed) */ + UINT32 msdstate; /* state of underlying driver */ + UINT32 hwremoved; /* Has the hw been yanked out? */ + + /* Hardware config */ + UINT irq; + UINT iobase; + UINT membase; + UINT32 nsdcaps; /* NSD Capabilities flags */ + + /* Config vars */ + UINT ethconv; + + /* device methods (init by MSD, used by p80211 */ + int (*open)(struct wlandevice *wlandev); + int (*close)(struct wlandevice *wlandev); + void (*reset)(struct wlandevice *wlandev ); + int (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep); + int (*mlmerequest)(struct wlandevice *wlandev, p80211msg_t *msg); + int (*set_multicast_list)(struct wlandevice *wlandev, + netdevice_t *dev); + void (*tx_timeout)(struct wlandevice *wlandev); + +#ifdef CONFIG_PROC_FS + int (*nsd_proc_read)(char *page, char **start, off_t offset, int count, int *eof, void *data); +#endif + + /* 802.11 State */ + UINT8 bssid[WLAN_BSSID_LEN]; + p80211pstr32_t ssid; + UINT32 macmode; + int linkstatus; + int shortpreamble; /* C bool */ + + /* WEP State */ + UINT8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN]; + UINT8 wep_keylens[NUM_WEPKEYS]; + int hostwep; + + /* Request/Confirm i/f state (used by p80211) */ + unsigned long request_pending; /* flag, access atomically */ + + /* netlink socket */ + /* queue for indications waiting for cmd completion */ + /* Linux netdevice and support */ + netdevice_t *netdev; /* ptr to linux netdevice */ + struct net_device_stats linux_stats; + +#ifdef CONFIG_PROC_FS + /* Procfs support */ + struct proc_dir_entry *procdir; + struct proc_dir_entry *procwlandev; +#endif + + /* Rx bottom half */ + struct tasklet_struct rx_bh; + + struct sk_buff_head nsd_rxq; + + /* 802.11 device statistics */ + struct p80211_frmrx_t rx; + +/* compatibility to wireless extensions */ +#ifdef WIRELESS_EXT + struct iw_statistics wstats; + + /* jkriegl: iwspy fields */ + UINT8 spy_number; + char spy_address[IW_MAX_SPY][ETH_ALEN]; + struct iw_quality spy_stat[IW_MAX_SPY]; + +#endif + + struct mutex ioctl_lock; +} wlandevice_t; + +/* WEP stuff */ +int wep_change_key(wlandevice_t *wlandev, int keynum, UINT8* key, int keylen); +int wep_decrypt(wlandevice_t *wlandev, UINT8 *buf, UINT32 len, int key_override, UINT8 *iv, UINT8 *icv); +int wep_encrypt(wlandevice_t *wlandev, UINT8 *buf, UINT8 *dst, UINT32 len, int keynum, UINT8 *iv, UINT8 *icv); + +/*================================================================*/ +/* Externs */ + +/*================================================================*/ +/* Function Declarations */ + +void p80211netdev_startup(void); +void p80211netdev_shutdown(void); +int wlan_setup(wlandevice_t *wlandev); +int wlan_unsetup(wlandevice_t *wlandev); +int register_wlandev(wlandevice_t *wlandev); +int unregister_wlandev(wlandevice_t *wlandev); +void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb); +void p80211netdev_hwremoved(wlandevice_t *wlandev); +void p80211_suspend(wlandevice_t *wlandev); +void p80211_resume(wlandevice_t *wlandev); + +void p80211_allow_ioctls(wlandevice_t *wlandev); + +/*================================================================*/ +/* Function Definitions */ + +static inline void +p80211netdev_stop_queue(wlandevice_t *wlandev) +{ + if ( !wlandev ) return; + if ( !wlandev->netdev ) return; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + wlandev->netdev->tbusy = 1; + wlandev->netdev->start = 0; +#else + netif_stop_queue(wlandev->netdev); +#endif +} + +static inline void +p80211netdev_start_queue(wlandevice_t *wlandev) +{ + if ( !wlandev ) return; + if ( !wlandev->netdev ) return; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + wlandev->netdev->tbusy = 0; + wlandev->netdev->start = 1; +#else + netif_start_queue(wlandev->netdev); +#endif +} + +static inline void +p80211netdev_wake_queue(wlandevice_t *wlandev) +{ + if ( !wlandev ) return; + if ( !wlandev->netdev ) return; +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38) ) + wlandev->netdev->tbusy = 0; + mark_bh(NET_BH); +#else + netif_wake_queue(wlandev->netdev); +#endif +} + +#ifdef CONFIG_HOTPLUG +#define WLAN_HOTPLUG_REGISTER "register" +#define WLAN_HOTPLUG_REMOVE "remove" +#define WLAN_HOTPLUG_STARTUP "startup" +#define WLAN_HOTPLUG_SHUTDOWN "shutdown" +#define WLAN_HOTPLUG_SUSPEND "suspend" +#define WLAN_HOTPLUG_RESUME "resume" +int p80211_run_sbin_hotplug(wlandevice_t *wlandev, char *action); +#endif + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metadef.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metadef.h @@ -0,0 +1,2524 @@ +/* This file is GENERATED AUTOMATICALLY. DO NOT EDIT OR MODIFY. +* -------------------------------------------------------------------- +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211MKMETADEF_H +#define _P80211MKMETADEF_H + + +#define DIDmsg_cat_dot11req \ + P80211DID_MKSECTION(1) +#define DIDmsg_dot11req_mibget \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_dot11req_mibget_mibattribute \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_mibget_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_mibset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_dot11req_mibset_mibattribute \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_mibset_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_powermgmt \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_dot11req_powermgmt_powermgmtmode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_powermgmt_wakeup \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_powermgmt_receivedtims \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_powermgmt_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_scan \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_dot11req_scan_bsstype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_scan_bssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_scan_ssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_scan_scantype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_scan_probedelay \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_scan_channellist \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_scan_minchanneltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_scan_maxchanneltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_scan_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_scan_numbss \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_scan_append \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_scan_results \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_dot11req_scan_results_bssindex \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_scan_results_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_scan_results_signal \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_scan_results_noise \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_scan_results_bssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_scan_results_ssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_scan_results_bsstype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_scan_results_beaconperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_scan_results_dtimperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_scan_results_timestamp \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_scan_results_localtime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhdwelltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhhopset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhhoppattern \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_dot11req_scan_results_fhhopindex \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_dot11req_scan_results_dschannel \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpcount \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpmaxduration \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpdurremaining \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(20) | 0x00000000) +#define DIDmsg_dot11req_scan_results_ibssatimwindow \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(21) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(22) | 0x00000000) +#define DIDmsg_dot11req_scan_results_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(23) | 0x00000000) +#define DIDmsg_dot11req_scan_results_privacy \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(24) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(25) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(26) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(27) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(28) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(29) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(30) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(31) | 0x00000000) +#define DIDmsg_dot11req_scan_results_basicrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(32) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(33) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(34) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(35) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(36) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(37) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(38) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(39) | 0x00000000) +#define DIDmsg_dot11req_scan_results_supprate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(40) | 0x00000000) +#define DIDmsg_dot11req_join \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6)) +#define DIDmsg_dot11req_join_bssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_join_joinfailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_join_basicrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_dot11req_join_operationalrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_dot11req_join_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_dot11req_authenticate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7)) +#define DIDmsg_dot11req_authenticate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_authenticate_authenticationtype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_authenticate_authenticationfailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_authenticate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_deauthenticate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8)) +#define DIDmsg_dot11req_deauthenticate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_deauthenticate_reasoncode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_deauthenticate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_associate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9)) +#define DIDmsg_dot11req_associate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_associate_associatefailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_associate_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_associate_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_associate_privacy \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_associate_listeninterval \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_associate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_reassociate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10)) +#define DIDmsg_dot11req_reassociate_newapaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_reassociate_reassociatefailuretimeout \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_reassociate_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_reassociate_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_reassociate_privacy \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_reassociate_listeninterval \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_reassociate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_disassociate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11)) +#define DIDmsg_dot11req_disassociate_peerstaaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_disassociate_reasoncode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_disassociate_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_reset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12)) +#define DIDmsg_dot11req_reset_setdefaultmib \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_reset_macaddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_reset_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_start \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13)) +#define DIDmsg_dot11req_start_ssid \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11req_start_bsstype \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11req_start_beaconperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11req_start_dtimperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_dot11req_start_cfpperiod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_dot11req_start_cfpmaxduration \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_dot11req_start_fhdwelltime \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_dot11req_start_fhhopset \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_dot11req_start_fhhoppattern \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_dot11req_start_dschannel \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_dot11req_start_ibssatimwindow \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_dot11req_start_probedelay \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_dot11req_start_cfpollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_dot11req_start_cfpollreq \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(20) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(21) | 0x00000000) +#define DIDmsg_dot11req_start_basicrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(22) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(23) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(24) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(25) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(26) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(27) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(28) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate7 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(29) | 0x00000000) +#define DIDmsg_dot11req_start_operationalrate8 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(30) | 0x00000000) +#define DIDmsg_dot11req_start_resultcode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(31) | 0x00000000) +#define DIDmsg_cat_dot11ind \ + P80211DID_MKSECTION(2) +#define DIDmsg_dot11ind_authenticate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_dot11ind_authenticate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_authenticate_authenticationtype \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_deauthenticate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_dot11ind_deauthenticate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_deauthenticate_reasoncode \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_associate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_dot11ind_associate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_associate_aid \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_reassociate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_dot11ind_reassociate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_reassociate_aid \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_dot11ind_reassociate_oldapaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_dot11ind_disassociate \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_dot11ind_disassociate_peerstaaddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_dot11ind_disassociate_reasoncode \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_cat_lnxreq \ + P80211DID_MKSECTION(3) +#define DIDmsg_lnxreq_ifstate \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_lnxreq_ifstate_ifstate \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_ifstate_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_lnxreq_wlansniff_enable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_channel \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_prismheader \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_wlanheader \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_keepwepflags \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_stripfcs \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_packet_trunc \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_lnxreq_wlansniff_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_lnxreq_hostwep \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_lnxreq_hostwep_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_hostwep_decrypt \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_hostwep_encrypt \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxreq_commsquality \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_lnxreq_commsquality_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_dbm \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_link \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_level \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_lnxreq_commsquality_noise \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_lnxreq_autojoin \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_lnxreq_autojoin_ssid \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxreq_autojoin_authtype \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxreq_autojoin_resultcode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_cat_lnxind \ + P80211DID_MKSECTION(4) +#define DIDmsg_lnxind_wlansniffrm \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_lnxind_wlansniffrm_hosttime \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_mactime \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_channel \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_rssi \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_sq \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_signal \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_noise \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_rate \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_istx \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_lnxind_wlansniffrm_frmlen \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_lnxind_roam \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_lnxind_roam_reason \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_cat_p2req \ + P80211DID_MKSECTION(5) +#define DIDmsg_p2req_join \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1)) +#define DIDmsg_p2req_join_bssid \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_join_basicrate1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_join_basicrate2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_join_basicrate3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_join_basicrate4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_join_basicrate5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_join_basicrate6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_p2req_join_basicrate7 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_p2req_join_basicrate8 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(10) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(11) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(12) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(13) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(14) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(15) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate7 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(16) | 0x00000000) +#define DIDmsg_p2req_join_operationalrate8 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(17) | 0x00000000) +#define DIDmsg_p2req_join_ssid \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(18) | 0x00000000) +#define DIDmsg_p2req_join_channel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(19) | 0x00000000) +#define DIDmsg_p2req_join_authtype \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(20) | 0x00000000) +#define DIDmsg_p2req_join_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(21) | 0x00000000) +#define DIDmsg_p2req_readpda \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2)) +#define DIDmsg_p2req_readpda_pda \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_readpda_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_readcis \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3)) +#define DIDmsg_p2req_readcis_cis \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_readcis_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4)) +#define DIDmsg_p2req_auxport_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_auxport_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_read \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5)) +#define DIDmsg_p2req_auxport_read_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_auxport_read_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_read_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_auxport_read_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_auxport_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6)) +#define DIDmsg_p2req_auxport_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_auxport_write_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_auxport_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_auxport_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_low_level \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7)) +#define DIDmsg_p2req_low_level_command \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_low_level_param0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_low_level_param1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_low_level_param2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_low_level_resp0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_low_level_resp1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_low_level_resp2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_p2req_low_level_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(8) | 0x00000000) +#define DIDmsg_p2req_test_command \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8)) +#define DIDmsg_p2req_test_command_testcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_test_command_testparam \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_test_command_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_test_command_status \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_test_command_resp0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_test_command_resp1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_test_command_resp2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(7) | 0x00000000) +#define DIDmsg_p2req_mmi_read \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9)) +#define DIDmsg_p2req_mmi_read_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_mmi_read_value \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_mmi_read_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_mmi_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10)) +#define DIDmsg_p2req_mmi_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_mmi_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_mmi_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_ramdl_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11)) +#define DIDmsg_p2req_ramdl_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_ramdl_state_exeaddr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_ramdl_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(11) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_ramdl_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12)) +#define DIDmsg_p2req_ramdl_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_ramdl_write_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_ramdl_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_ramdl_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(12) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_flashdl_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(13)) +#define DIDmsg_p2req_flashdl_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_flashdl_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(13) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_flashdl_write \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14)) +#define DIDmsg_p2req_flashdl_write_addr \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_flashdl_write_len \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_flashdl_write_data \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_flashdl_write_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(14) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_mm_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(15)) +#define DIDmsg_p2req_mm_state_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(15) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_mm_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(15) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_dump_state \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(16)) +#define DIDmsg_p2req_dump_state_level \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(16) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_dump_state_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(16) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_channel_info \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17)) +#define DIDmsg_p2req_channel_info_channellist \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_channel_info_channeldwelltime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_channel_info_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_channel_info_numchinfo \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(17) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_channel_info_results \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18)) +#define DIDmsg_p2req_channel_info_results_channel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(2) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_avgnoiselevel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(3) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_peaknoiselevel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(4) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_bssactive \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(5) | 0x00000000) +#define DIDmsg_p2req_channel_info_results_pcfactive \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(18) | \ + P80211DID_MKITEM(6) | 0x00000000) +#define DIDmsg_p2req_enable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(19)) +#define DIDmsg_p2req_enable_resultcode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(19) | \ + P80211DID_MKITEM(1) | 0x00000000) +#define DIDmib_cat_dot11smt \ + P80211DID_MKSECTION(1) +#define DIDmib_dot11smt_p80211Table \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_dot11smt_p80211Table_p80211_ifstate \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11StationID \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(12) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(13) | 0x18000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateReason \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(15) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DisassociateStation \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(16) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateReason \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(17) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11DeauthenticateStation \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(18) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStatus \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(19) | 0x10000000) +#define DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticateFailStation \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(20) | 0x10000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x1c000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(11) | 0x14000000) +#define DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(12) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4)) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3 \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x0c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5)) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x1c000000) +#define DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11smt_dot11PrivacyTable \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6)) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount \ + (P80211DID_MKSECTION(1) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_cat_dot11mac \ + P80211DID_MKSECTION(2) +#define DIDmib_dot11mac_dot11OperationTable \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_dot11mac_dot11OperationTable_dot11MACAddress \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_dot11mac_dot11OperationTable_dot11ProductID \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11FailedCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11RetryCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(10) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(11) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(13) | 0x10000000) +#define DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(11) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(12) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(13) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(14) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(15) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(16) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(17) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(18) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(19) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(20) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(21) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(22) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(23) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(24) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(25) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(26) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(27) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(28) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(29) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(30) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(31) | 0x1c000000) +#define DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32 \ + (P80211DID_MKSECTION(2) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(32) | 0x1c000000) +#define DIDmib_cat_dot11phy \ + P80211DID_MKSECTION(3) +#define DIDmib_dot11phy_dot11PhyOperationTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11CurrentRegDomain \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyAntennaTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8 \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4)) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(7) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5)) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_dot11phy_dot11PhyIRTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6)) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_dot11phy_dot11RegDomainsSupportedTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(7)) +#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x14000000) +#define DIDmib_dot11phy_dot11AntennasListTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8)) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(2) | 0x1c000000) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(3) | 0x1c000000) +#define DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(8) | \ + P80211DID_MKITEM(4) | 0x1c000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(9)) +#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(9) | \ + P80211DID_MKITEM(2) | 0x14000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(10)) +#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(1) | 0x1c000000) +#define DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue \ + (P80211DID_MKSECTION(3) | \ + P80211DID_MKGROUP(10) | \ + P80211DID_MKITEM(2) | 0x14000000) +#define DIDmib_cat_lnx \ + P80211DID_MKSECTION(4) +#define DIDmib_lnx_lnxConfigTable \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_lnx_lnxConfigTable_lnxRSNAIE \ + (P80211DID_MKSECTION(4) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_cat_p2 \ + P80211DID_MKSECTION(5) +#define DIDmib_p2_p2Table \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1)) +#define DIDmib_p2_p2Table_p2MMTx \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2Table_p2EarlyBeacon \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_p2_p2Table_p2ReceivedFrameStatistics \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2Table_p2CommunicationTallies \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2Table_p2Authenticated \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2Table_p2Associated \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_p2_p2Table_p2PowerSaveUserCount \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_p2_p2Table_p2Comment \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_p2_p2Table_p2AccessMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_p2_p2Table_p2AccessAllow \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_p2_p2Table_p2AccessDeny \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_p2_p2Table_p2ChannelInfoResults \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(1) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_p2_p2Static \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2)) +#define DIDmib_p2_p2Static_p2CnfPortType \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnMACAddress \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfDesiredSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnChannel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnATIMWindow \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfSystemScale \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(7) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMaxDataLength \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPMEnabled \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPMEPS \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMulticastReceive \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(12) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMaxSleepDuration \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(13) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPMHoldoverDuration \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(14) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnName \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(15) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(16) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(17) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(18) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(19) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(20) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(21) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWDSAddress6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(22) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMulticastPMBuffering \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(23) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(24) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(25) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(26) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(27) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPDefaultKey3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(28) | 0x08000000) +#define DIDmib_p2_p2Static_p2CnfWEPFlags \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(29) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfAuthentication \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(30) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMaxAssociatedStations \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(31) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfTxControl \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(32) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfRoamingMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(33) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfHostAuthentication \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(34) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfRcvCrcError \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(35) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfAltRetryCount \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(36) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfBeaconInterval \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(37) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(38) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfCFPPeriod \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(39) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfCFPMaxDuration \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(40) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfCFPFlags \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(41) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfSTAPCFInfo \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(42) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfPriorityQUsage \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(43) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfTIMCtrl \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(44) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfThirty2Tally \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(45) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfEnhSecurity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(46) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfShortPreamble \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(47) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfExcludeLongPreamble \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(48) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfAuthenticationRspTO \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(49) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfBasicRates \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(50) | 0x18000000) +#define DIDmib_p2_p2Static_p2CnfSupportedRates \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(2) | \ + P80211DID_MKITEM(51) | 0x18000000) +#define DIDmib_p2_p2Dynamic \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3)) +#define DIDmib_p2_p2Dynamic_p2CreateIBSS \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(2) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(3) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(4) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2PromiscuousMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(5) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(6) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(7) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(8) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(9) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(10) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(11) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2FragmentationThreshold6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(12) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(13) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(14) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(15) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(16) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(17) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(18) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2RTSThreshold6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(19) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl0 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(20) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(21) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(22) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(23) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(24) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(25) | 0x18000000) +#define DIDmib_p2_p2Dynamic_p2TxRateControl6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(3) | \ + P80211DID_MKITEM(26) | 0x18000000) +#define DIDmib_p2_p2Behavior \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4)) +#define DIDmib_p2_p2Behavior_p2TickTime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(4) | \ + P80211DID_MKITEM(1) | 0x18000000) +#define DIDmib_p2_p2NIC \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5)) +#define DIDmib_p2_p2NIC_p2MaxLoadTime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_p2_p2NIC_p2DLBufferPage \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_p2_p2NIC_p2DLBufferOffset \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2NIC_p2DLBufferLength \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2NIC_p2PRIIdentity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2NIC_p2PRISupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_p2_p2NIC_p2CFIActRanges \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_p2_p2NIC_p2NICSerialNumber \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_p2_p2NIC_p2NICIdentity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_p2_p2NIC_p2MFISupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(10) | 0x10000000) +#define DIDmib_p2_p2NIC_p2CFISupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(11) | 0x10000000) +#define DIDmib_p2_p2NIC_p2ChannelList \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_p2_p2NIC_p2RegulatoryDomains \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(13) | 0x10000000) +#define DIDmib_p2_p2NIC_p2TempType \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_p2_p2NIC_p2STAIdentity \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(15) | 0x10000000) +#define DIDmib_p2_p2NIC_p2STASupRange \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(16) | 0x10000000) +#define DIDmib_p2_p2NIC_p2MFIActRanges \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(17) | 0x10000000) +#define DIDmib_p2_p2NIC_p2STACFIActRanges \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(18) | 0x10000000) +#define DIDmib_p2_p2NIC_p2BuildSequence \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(19) | 0x10000000) +#define DIDmib_p2_p2NIC_p2PrimaryFWID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(20) | 0x10000000) +#define DIDmib_p2_p2NIC_p2SecondaryFWID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(21) | 0x10000000) +#define DIDmib_p2_p2NIC_p2TertiaryFWID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(5) | \ + P80211DID_MKITEM(22) | 0x10000000) +#define DIDmib_p2_p2MAC \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6)) +#define DIDmib_p2_p2MAC_p2PortStatus \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentBSSID \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQuality \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQualityCQ \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQualityASL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(6) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CommsQualityANL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(7) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQuality \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(8) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQualityCQ \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(9) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQualityASL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(10) | 0x10000000) +#define DIDmib_p2_p2MAC_p2dbmCommsQualityANL \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(11) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(12) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentBeaconInterval \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(13) | 0x10000000) +#define DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(14) | 0x10000000) +#define DIDmib_p2_p2MAC_p2APCurrentScaleThresholds \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(15) | 0x10000000) +#define DIDmib_p2_p2MAC_p2ProtocolRspTime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(16) | 0x10000000) +#define DIDmib_p2_p2MAC_p2ShortRetryLimit \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(17) | 0x10000000) +#define DIDmib_p2_p2MAC_p2LongRetryLimit \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(18) | 0x10000000) +#define DIDmib_p2_p2MAC_p2MaxTransmitLifetime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(19) | 0x10000000) +#define DIDmib_p2_p2MAC_p2MaxReceiveLifetime \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(20) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CFPollable \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(21) | 0x10000000) +#define DIDmib_p2_p2MAC_p2AuthenticationAlgorithms \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(22) | 0x10000000) +#define DIDmib_p2_p2MAC_p2PrivacyOptionImplemented \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(23) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate1 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(24) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate2 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(25) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate3 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(26) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate4 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(27) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate5 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(28) | 0x10000000) +#define DIDmib_p2_p2MAC_p2CurrentTxRate6 \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(29) | 0x10000000) +#define DIDmib_p2_p2MAC_p2OwnMACAddress \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(6) | \ + P80211DID_MKITEM(30) | 0x10000000) +#define DIDmib_p2_p2Modem \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7)) +#define DIDmib_p2_p2Modem_p2PHYType \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(1) | 0x10000000) +#define DIDmib_p2_p2Modem_p2CurrentChannel \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(2) | 0x10000000) +#define DIDmib_p2_p2Modem_p2CurrentPowerState \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(3) | 0x10000000) +#define DIDmib_p2_p2Modem_p2CCAMode \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(4) | 0x10000000) +#define DIDmib_p2_p2Modem_p2SupportedDataRates \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(5) | 0x10000000) +#define DIDmib_p2_p2Modem_p2TxPowerMax \ + (P80211DID_MKSECTION(5) | \ + P80211DID_MKGROUP(7) | \ + P80211DID_MKITEM(6) | 0x18000000) +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211metamib.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211metamib.h @@ -0,0 +1,105 @@ +/* src/include/wlan/p80211metamib.h +* +* Macros, const, types, and funcs for p80211 mib metadata +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211METAMIB_H +#define _P80211METAMIB_H + +/*================================================================*/ +/* System Includes */ + +/*================================================================*/ +/* Project Includes */ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Macros */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* */ + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* The following is the external declaration for the mib */ +/* category metadata list */ + +extern catlistitem_t mib_catlist[]; +extern UINT32 mib_catlist_size; + + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* */ + +#endif /* _P80211METAMIB_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211types.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211types.h @@ -0,0 +1,675 @@ +/* src/include/wlan/p80211types.h +* +* Macros, constants, types, and funcs for p80211 data types +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file declares some of the constants and types used in various +* parts of the linux-wlan system. +* +* Notes: +* - Constant values are always in HOST byte order. +* +* All functions and statics declared here are implemented in p80211types.c +* -------------------------------------------------------------------- +*/ + +#ifndef _P80211TYPES_H +#define _P80211TYPES_H + +/*================================================================*/ +/* System Includes */ +/*================================================================*/ + +/*================================================================*/ +/* Project Includes */ +/*================================================================*/ + +#ifndef _WLAN_COMPAT_H +#include +#endif + +/*================================================================*/ +/* Constants */ +/*================================================================*/ + +/*----------------------------------------------------------------*/ +/* p80211 data type codes used for MIB items and message */ +/* arguments. The various metadata structures provide additional */ +/* information about these types. */ + +#define P80211_TYPE_OCTETSTR 1 /* pascal array of bytes */ +#define P80211_TYPE_DISPLAYSTR 2 /* pascal array of bytes containing ascii */ +#define P80211_TYPE_INT 4 /* UINT32 min and max limited by 32 bits */ +#define P80211_TYPE_ENUMINT 5 /* UINT32 holding a numeric + code that can be mapped + to a textual name */ +#define P80211_TYPE_UNKDATA 6 /* Data item containing an + unknown data type */ +#define P80211_TYPE_INTARRAY 7 /* Array of 32-bit integers. */ +#define P80211_TYPE_BITARRAY 8 /* Array of bits. */ +#define P80211_TYPE_MACARRAY 9 /* Array of MAC addresses. */ + +/*----------------------------------------------------------------*/ +/* The following constants are indexes into the Mib Category List */ +/* and the Message Category List */ + +/* Mib Category List */ +#define P80211_MIB_CAT_DOT11SMT 1 +#define P80211_MIB_CAT_DOT11MAC 2 +#define P80211_MIB_CAT_DOT11PHY 3 + +#define P80211SEC_DOT11SMT P80211_MIB_CAT_DOT11SMT +#define P80211SEC_DOT11MAC P80211_MIB_CAT_DOT11MAC +#define P80211SEC_DOT11PHY P80211_MIB_CAT_DOT11PHY + +/* Message Category List */ +#define P80211_MSG_CAT_DOT11REQ 1 +#define P80211_MSG_CAT_DOT11IND 2 +/* #define P80211_MSG_CAT_DOT11CFM 3 (doesn't exist at this time) */ + +#define P80211SEC_DOT11REQ P80211_MSG_CAT_DOT11REQ +#define P80211SEC_DOT11IND P80211_MSG_CAT_DOT11IND +/* #define P80211SEC_DOT11CFM P80211_MSG_CAT_DOT11CFM (doesn't exist at this time */ + + + +/*----------------------------------------------------------------*/ +/* p80211 DID field codes that represent access type and */ +/* is_table status. */ + +#define P80211DID_ACCESS_READ 0x10000000 +#define P80211DID_ACCESS_WRITE 0x08000000 +#define P80211DID_WRITEONLY 0x00000001 +#define P80211DID_READONLY 0x00000002 +#define P80211DID_READWRITE 0x00000003 +#define P80211DID_ISTABLE_FALSE 0 +#define P80211DID_ISTABLE_TRUE 1 + +/*----------------------------------------------------------------*/ +/* p80211 enumeration constants. The value to text mappings for */ +/* these is in p80211types.c. These defines were generated */ +/* from the mappings. */ + +/* error codes for lookups */ +#define P80211ENUM_BAD 0xffffffffUL +#define P80211ENUM_BADSTR "P80211ENUM_BAD" + +#define P80211ENUM_truth_false 0 +#define P80211ENUM_truth_true 1 +#define P80211ENUM_ifstate_disable 0 +#define P80211ENUM_ifstate_fwload 1 +#define P80211ENUM_ifstate_enable 2 +#define P80211ENUM_powermgmt_active 1 +#define P80211ENUM_powermgmt_powersave 2 +#define P80211ENUM_bsstype_infrastructure 1 +#define P80211ENUM_bsstype_independent 2 +#define P80211ENUM_bsstype_any 3 +#define P80211ENUM_authalg_opensystem 1 +#define P80211ENUM_authalg_sharedkey 2 +#define P80211ENUM_phytype_fhss 1 +#define P80211ENUM_phytype_dsss 2 +#define P80211ENUM_phytype_irbaseband 3 +#define P80211ENUM_temptype_commercial 1 +#define P80211ENUM_temptype_industrial 2 +#define P80211ENUM_regdomain_fcc 16 +#define P80211ENUM_regdomain_doc 32 +#define P80211ENUM_regdomain_etsi 48 +#define P80211ENUM_regdomain_spain 49 +#define P80211ENUM_regdomain_france 50 +#define P80211ENUM_regdomain_mkk 64 +#define P80211ENUM_ccamode_edonly 1 +#define P80211ENUM_ccamode_csonly 2 +#define P80211ENUM_ccamode_edandcs 4 +#define P80211ENUM_ccamode_cswithtimer 8 +#define P80211ENUM_ccamode_hrcsanded 16 +#define P80211ENUM_diversity_fixedlist 1 +#define P80211ENUM_diversity_notsupported 2 +#define P80211ENUM_diversity_dynamic 3 +#define P80211ENUM_scantype_active 1 +#define P80211ENUM_scantype_passive 2 +#define P80211ENUM_scantype_both 3 +#define P80211ENUM_resultcode_success 1 +#define P80211ENUM_resultcode_invalid_parameters 2 +#define P80211ENUM_resultcode_not_supported 3 +#define P80211ENUM_resultcode_timeout 4 +#define P80211ENUM_resultcode_too_many_req 5 +#define P80211ENUM_resultcode_refused 6 +#define P80211ENUM_resultcode_bss_already 7 +#define P80211ENUM_resultcode_invalid_access 8 +#define P80211ENUM_resultcode_invalid_mibattribute 9 +#define P80211ENUM_resultcode_cant_set_readonly_mib 10 +#define P80211ENUM_resultcode_implementation_failure 11 +#define P80211ENUM_resultcode_cant_get_writeonly_mib 12 +#define P80211ENUM_reason_unspec_reason 1 +#define P80211ENUM_reason_auth_not_valid 2 +#define P80211ENUM_reason_deauth_lv_ss 3 +#define P80211ENUM_reason_inactivity 4 +#define P80211ENUM_reason_ap_overload 5 +#define P80211ENUM_reason_class23_err 6 +#define P80211ENUM_reason_class3_err 7 +#define P80211ENUM_reason_disas_lv_ss 8 +#define P80211ENUM_reason_asoc_not_auth 9 +#define P80211ENUM_status_successful 0 +#define P80211ENUM_status_unspec_failure 1 +#define P80211ENUM_status_unsup_cap 10 +#define P80211ENUM_status_reasoc_no_asoc 11 +#define P80211ENUM_status_fail_other 12 +#define P80211ENUM_status_unspt_alg 13 +#define P80211ENUM_status_auth_seq_fail 14 +#define P80211ENUM_status_chlng_fail 15 +#define P80211ENUM_status_auth_timeout 16 +#define P80211ENUM_status_ap_full 17 +#define P80211ENUM_status_unsup_rate 18 +#define P80211ENUM_status_unsup_shortpreamble 19 +#define P80211ENUM_status_unsup_pbcc 20 +#define P80211ENUM_status_unsup_agility 21 +#define P80211ENUM_msgitem_status_data_ok 0 +#define P80211ENUM_msgitem_status_no_value 1 +#define P80211ENUM_msgitem_status_invalid_itemname 2 +#define P80211ENUM_msgitem_status_invalid_itemdata 3 +#define P80211ENUM_msgitem_status_missing_itemdata 4 +#define P80211ENUM_msgitem_status_incomplete_itemdata 5 +#define P80211ENUM_msgitem_status_invalid_msg_did 6 +#define P80211ENUM_msgitem_status_invalid_mib_did 7 +#define P80211ENUM_msgitem_status_missing_conv_func 8 +#define P80211ENUM_msgitem_status_string_too_long 9 +#define P80211ENUM_msgitem_status_data_out_of_range 10 +#define P80211ENUM_msgitem_status_string_too_short 11 +#define P80211ENUM_msgitem_status_missing_valid_func 12 +#define P80211ENUM_msgitem_status_unknown 13 +#define P80211ENUM_msgitem_status_invalid_did 14 +#define P80211ENUM_msgitem_status_missing_print_func 15 + +#define P80211ENUM_lnxroam_reason_unknown 0 +#define P80211ENUM_lnxroam_reason_beacon 1 +#define P80211ENUM_lnxroam_reason_signal 2 +#define P80211ENUM_lnxroam_reason_txretry 3 +#define P80211ENUM_lnxroam_reason_notjoined 4 + +#define P80211ENUM_p2preamble_long 0 +#define P80211ENUM_p2preamble_short 2 +#define P80211ENUM_p2preamble_mixed 3 + +/*----------------------------------------------------------------*/ +/* p80211 max length constants for the different pascal strings. */ + +#define MAXLEN_PSTR6 (6) /* pascal array of 6 bytes */ +#define MAXLEN_PSTR14 (14) /* pascal array of 14 bytes */ +#define MAXLEN_PSTR32 (32) /* pascal array of 32 bytes */ +#define MAXLEN_PSTR255 (255) /* pascal array of 255 bytes */ +#define MAXLEN_MIBATTRIBUTE (392) /* maximum mibattribute */ + /* where the size of the DATA itself */ + /* is a DID-LEN-DATA triple */ + /* with a max size of 4+4+384 */ + +#define P80211_SET_INT(item, value) do { \ + (item).data = (value); \ + (item).status = P80211ENUM_msgitem_status_data_ok; \ + } while(0) +/*----------------------------------------------------------------*/ +/* string constants */ + +#define NOT_SET "NOT_SET" +#define NOT_SUPPORTED "NOT_SUPPORTED" +#define UNKNOWN_DATA "UNKNOWN_DATA" + + +/*--------------------------------------------------------------------*/ +/* Metadata flags */ + +/* MSM: Do these belong in p80211meta.h? I'm not sure. */ + +#define ISREQUIRED (0x80000000UL) +#define ISREQUEST (0x40000000UL) +#define ISCONFIRM (0x20000000UL) + + +/*================================================================*/ +/* Macros */ + +/*--------------------------------------------------------------------*/ +/* The following macros are used to manipulate the 'flags' field in */ +/* the metadata. These are only used when the metadata is for */ +/* command arguments to determine if the data item is required, and */ +/* whether the metadata item is for a request command, confirm */ +/* command or both. */ +/*--------------------------------------------------------------------*/ +/* MSM: Do these belong in p80211meta.h? I'm not sure */ + +#define P80211ITEM_SETFLAGS(q, r, c) ( q | r | c ) + +#define P80211ITEM_ISREQUIRED(flags) (((UINT32)(flags & ISREQUIRED)) >> 31 ) +#define P80211ITEM_ISREQUEST(flags) (((UINT32)(flags & ISREQUEST)) >> 30 ) +#define P80211ITEM_ISCONFIRM(flags) (((UINT32)(flags & ISCONFIRM)) >> 29 ) + +/*----------------------------------------------------------------*/ +/* The following macro creates a name for an enum */ + +#define MKENUMNAME(name) p80211enum_ ## name + +/*---------------------------------------------------------------- +* The following constants and macros are used to construct and +* deconstruct the Data ID codes. The coding is as follows: +* +* ...rwtnnnnnnnniiiiiiggggggssssss s - Section +* g - Group +* i - Item +* n - Index +* t - Table flag +* w - Write flag +* r - Read flag +* . - Unused +*/ + +#define P80211DID_INVALID 0xffffffffUL +#define P80211DID_VALID 0x00000000UL + +#define P80211DID_LSB_SECTION (0) +#define P80211DID_LSB_GROUP (6) +#define P80211DID_LSB_ITEM (12) +#define P80211DID_LSB_INDEX (18) +#define P80211DID_LSB_ISTABLE (26) +#define P80211DID_LSB_ACCESS (27) + +#define P80211DID_MASK_SECTION (0x0000003fUL) +#define P80211DID_MASK_GROUP (0x0000003fUL) +#define P80211DID_MASK_ITEM (0x0000003fUL) +#define P80211DID_MASK_INDEX (0x000000ffUL) +#define P80211DID_MASK_ISTABLE (0x00000001UL) +#define P80211DID_MASK_ACCESS (0x00000003UL) + + +#define P80211DID_MK(a,m,l) ((((UINT32)(a)) & (m)) << (l)) + +#define P80211DID_MKSECTION(a) P80211DID_MK(a, \ + P80211DID_MASK_SECTION, \ + P80211DID_LSB_SECTION ) +#define P80211DID_MKGROUP(a) P80211DID_MK(a, \ + P80211DID_MASK_GROUP, \ + P80211DID_LSB_GROUP ) +#define P80211DID_MKITEM(a) P80211DID_MK(a, \ + P80211DID_MASK_ITEM, \ + P80211DID_LSB_ITEM ) +#define P80211DID_MKINDEX(a) P80211DID_MK(a, \ + P80211DID_MASK_INDEX, \ + P80211DID_LSB_INDEX ) +#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \ + P80211DID_MASK_ISTABLE, \ + P80211DID_LSB_ISTABLE ) + + +#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \ + P80211DID_MKGROUP(g) | \ + P80211DID_MKITEM(i) | \ + P80211DID_MKINDEX(n) | \ + P80211DID_MKISTABLE(t) | \ + (a) ) + + +#define P80211DID_GET(a,m,l) ((((UINT32)(a)) >> (l)) & (m)) + +#define P80211DID_SECTION(a) P80211DID_GET(a, \ + P80211DID_MASK_SECTION, \ + P80211DID_LSB_SECTION) +#define P80211DID_GROUP(a) P80211DID_GET(a, \ + P80211DID_MASK_GROUP, \ + P80211DID_LSB_GROUP) +#define P80211DID_ITEM(a) P80211DID_GET(a, \ + P80211DID_MASK_ITEM, \ + P80211DID_LSB_ITEM) +#define P80211DID_INDEX(a) P80211DID_GET(a, \ + P80211DID_MASK_INDEX, \ + P80211DID_LSB_INDEX) +#define P80211DID_ISTABLE(a) P80211DID_GET(a, \ + P80211DID_MASK_ISTABLE, \ + P80211DID_LSB_ISTABLE) +#define P80211DID_ACCESS(a) P80211DID_GET(a, \ + P80211DID_MASK_ACCESS, \ + P80211DID_LSB_ACCESS) + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* The following structure types are used for the represenation */ +/* of ENUMINT type metadata. */ + +typedef struct p80211enumpair +{ + UINT32 val; + char *name; +} p80211enumpair_t; + +typedef struct p80211enum +{ + INT nitems; + p80211enumpair_t *list; +} p80211enum_t; + +/*----------------------------------------------------------------*/ +/* The following structure types are used to store data items in */ +/* messages. */ + +/* Template pascal string */ +typedef struct p80211pstr +{ + UINT8 len; +} __WLAN_ATTRIB_PACK__ p80211pstr_t; + +typedef struct p80211pstrd +{ + UINT8 len; + UINT8 data[0]; +} __WLAN_ATTRIB_PACK__ p80211pstrd_t; + +/* Maximum pascal string */ +typedef struct p80211pstr255 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR255]; +} __WLAN_ATTRIB_PACK__ p80211pstr255_t; + +/* pascal string for macaddress and bssid */ +typedef struct p80211pstr6 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR6]; +} __WLAN_ATTRIB_PACK__ p80211pstr6_t; + +/* pascal string for channel list */ +typedef struct p80211pstr14 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR14]; +} __WLAN_ATTRIB_PACK__ p80211pstr14_t; + +/* pascal string for ssid */ +typedef struct p80211pstr32 +{ + UINT8 len; + UINT8 data[MAXLEN_PSTR32]; +} __WLAN_ATTRIB_PACK__ p80211pstr32_t; + +/* MAC address array */ +typedef struct p80211macarray +{ + UINT32 cnt; + UINT8 data[1][MAXLEN_PSTR6]; +} __WLAN_ATTRIB_PACK__ p80211macarray_t; + +/* prototype template */ +typedef struct p80211item +{ + UINT32 did; + UINT16 status; + UINT16 len; +} __WLAN_ATTRIB_PACK__ p80211item_t; + +/* prototype template w/ data item */ +typedef struct p80211itemd +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[0]; +} __WLAN_ATTRIB_PACK__ p80211itemd_t; + +/* message data item for INT, BOUNDEDINT, ENUMINT */ +typedef struct p80211item_uint32 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT32 data; +} __WLAN_ATTRIB_PACK__ p80211item_uint32_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr6 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr6_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr14 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr14_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr32 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr32_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t; + +/* message data item for OCTETSTR, DISPLAYSTR */ +typedef struct p80211item_pstr255 +{ + UINT32 did; + UINT16 status; + UINT16 len; + p80211pstr255_t data; +} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t; + +/* message data item for UNK 392, namely mib items */ +typedef struct p80211item_unk392 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[MAXLEN_MIBATTRIBUTE]; +} __WLAN_ATTRIB_PACK__ p80211item_unk392_t; + +/* message data item for UNK 1025, namely p2 pdas */ +typedef struct p80211item_unk1024 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[1024]; +} __WLAN_ATTRIB_PACK__ p80211item_unk1024_t; + +/* message data item for UNK 4096, namely p2 download chunks */ +typedef struct p80211item_unk4096 +{ + UINT32 did; + UINT16 status; + UINT16 len; + UINT8 data[4096]; +} __WLAN_ATTRIB_PACK__ p80211item_unk4096_t; + +struct catlistitem; + +/*----------------------------------------------------------------*/ +/* The following structure type is used to represent all of the */ +/* metadata items. Some components may choose to use more, */ +/* less or different metadata items. */ + +typedef void (*p80211_totext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf); +typedef void (*p80211_fromtext_t)( struct catlistitem *, UINT32 did, UINT8* itembuf, char *textbuf); +typedef UINT32 (*p80211_valid_t)( struct catlistitem *, UINT32 did, UINT8* itembuf); + + +/*================================================================*/ +/* Extern Declarations */ + +/*----------------------------------------------------------------*/ +/* Enumeration Lists */ +/* The following are the external declarations */ +/* for all enumerations */ + +extern p80211enum_t MKENUMNAME(truth); +extern p80211enum_t MKENUMNAME(ifstate); +extern p80211enum_t MKENUMNAME(powermgmt); +extern p80211enum_t MKENUMNAME(bsstype); +extern p80211enum_t MKENUMNAME(authalg); +extern p80211enum_t MKENUMNAME(phytype); +extern p80211enum_t MKENUMNAME(temptype); +extern p80211enum_t MKENUMNAME(regdomain); +extern p80211enum_t MKENUMNAME(ccamode); +extern p80211enum_t MKENUMNAME(diversity); +extern p80211enum_t MKENUMNAME(scantype); +extern p80211enum_t MKENUMNAME(resultcode); +extern p80211enum_t MKENUMNAME(reason); +extern p80211enum_t MKENUMNAME(status); +extern p80211enum_t MKENUMNAME(msgcode); +extern p80211enum_t MKENUMNAME(msgitem_status); + +extern p80211enum_t MKENUMNAME(lnxroam_reason); + +extern p80211enum_t MKENUMNAME(p2preamble); + +/*================================================================*/ +/* Function Declarations */ + +/*----------------------------------------------------------------*/ +/* The following declare some utility functions for use with the */ +/* p80211enum_t type. */ + +UINT32 p80211enum_text2int(p80211enum_t *ep, char *text); +UINT32 p80211enum_int2text(p80211enum_t *ep, UINT32 val, char *text); +void p80211_error2text(int err_code, char *err_str); + +/*----------------------------------------------------------------*/ +/* The following declare some utility functions for use with the */ +/* p80211item_t and p80211meta_t types. */ + +/*----------------------------------------------------------------*/ +/* The following declare functions that perform validation and */ +/* text to binary conversions based on the metadata for interface */ +/* and MIB data items. */ +/*----------------------------------------------------------------*/ + +/*-- DISPLAYSTR ------------------------------------------------------*/ +/* pstr ==> cstr */ +void p80211_totext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* cstr ==> pstr */ +void p80211_fromtext_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a displaystr binary value */ +UINT32 p80211_isvalid_displaystr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- OCTETSTR --------------------------------------------------------*/ +/* pstr ==> "xx:xx:...." */ +void p80211_totext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* "xx:xx:...." ==> pstr */ +void p80211_fromtext_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an octetstr binary value */ +UINT32 p80211_isvalid_octetstr( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- INT -------------------------------------------------------------*/ +/* UINT32 ==> %d */ +void p80211_totext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* %d ==> UINT32 */ +void p80211_fromtext_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an int's binary value (always successful) */ +UINT32 p80211_isvalid_int( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- ENUMINT ---------------------------------------------------------*/ +/* UINT32 ==> */ +void p80211_totext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* ==> UINT32 */ +void p80211_fromtext_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an enum's binary value */ +UINT32 p80211_isvalid_enumint( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- INTARRAY --------------------------------------------------------*/ +/* UINT32[] => %d,%d,%d,... */ +void p80211_totext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* %d,%d,%d,... ==> UINT32[] */ +void p80211_fromtext_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of an integer array's value */ +UINT32 p80211_isvalid_intarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- BITARRAY --------------------------------------------------------*/ +/* UINT32 ==> %d,%d,%d,... */ +void p80211_totext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* %d,%d,%d,... ==> UINT32 */ +void p80211_fromtext_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a bit array's value */ +UINT32 p80211_isvalid_bitarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- MACARRAY --------------------------------------------------------*/ +void p80211_totext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +void p80211_fromtext_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a MAC address array's value */ +UINT32 p80211_isvalid_macarray( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +/*-- MIBATTRIUBTE ------------------------------------------------------*/ +/* ==> */ +void p80211_totext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); +void p80211_totext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + + +/* ==> */ +void p80211_fromtext_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); +void p80211_fromtext_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf, char *textbuf ); + +/* function that checks validity of a mibitem's binary value */ +UINT32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); +UINT32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, UINT32 did, UINT8 *itembuf ); + +#endif /* _P80211TYPES_H */ + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211req.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211req.h @@ -0,0 +1,68 @@ +/* src/include/wlan/p80211req.h +* +* Request handling functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _LINUX_P80211REQ_H +#define _LINUX_P80211REQ_H + +/*================================================================*/ +/* Constants */ + +/*================================================================*/ +/* Macros */ + +/*================================================================*/ +/* Types */ + +/*================================================================*/ +/* Externs */ + +/*================================================================*/ +/* Function Declarations */ + +int p80211req_dorequest(wlandevice_t *wlandev, UINT8 *msgbuf); + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/p80211ioctl.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/p80211ioctl.h @@ -0,0 +1,123 @@ +/* src/include/wlan/p80211ioctl.h +* +* Declares constants and types for the p80211 ioctls +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* While this file is called 'ioctl' is purpose goes a little beyond +* that. This file defines the types and contants used to implement +* the p80211 request/confirm/indicate interfaces on Linux. The +* request/confirm interface is, in fact, normally implemented as an +* ioctl. The indicate interface on the other hand, is implemented +* using the Linux 'netlink' interface. +* +* The reason I say that request/confirm is 'normally' implemented +* via ioctl is that we're reserving the right to be able to send +* request commands via the netlink interface. This will be necessary +* if we ever need to send request messages when there aren't any +* wlan network devices present (i.e. sending a message that only p80211 +* cares about. +* -------------------------------------------------------------------- +*/ + + +#ifndef _P80211IOCTL_H +#define _P80211IOCTL_H + +/*================================================================*/ +/* Constants */ + +/*----------------------------------------------------------------*/ +/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */ + +#define P80211_IFTEST (SIOCDEVPRIVATE + 0) +#define P80211_IFREQ (SIOCDEVPRIVATE + 1) + +/*----------------------------------------------------------------*/ +/* Magic number, a quick test to see we're getting the desired struct */ + +#define P80211_IOCTL_MAGIC (0x4a2d464dUL) + +/*----------------------------------------------------------------*/ +/* Netlink protocol numbers for the indication interface */ + +#define P80211_NL_SOCK_IND NETLINK_USERSOCK + +/*----------------------------------------------------------------*/ +/* Netlink multicast bits for different types of messages */ + +#define P80211_NL_MCAST_GRP_MLME BIT0 /* Local station messages */ +#define P80211_NL_MCAST_GRP_SNIFF BIT1 /* Sniffer messages */ +#define P80211_NL_MCAST_GRP_DIST BIT2 /* Distribution system messages */ + +/*================================================================*/ +/* Macros */ + + +/*================================================================*/ +/* Types */ + +/*----------------------------------------------------------------*/ +/* A ptr to the following structure type is passed as the third */ +/* argument to the ioctl system call when issuing a request to */ +/* the p80211 module. */ + +typedef struct p80211ioctl_req +{ + char name[WLAN_DEVNAMELEN_MAX]; + caddr_t data; + UINT32 magic; + UINT16 len; + UINT32 result; +} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t; + + +/*================================================================*/ +/* Extern Declarations */ + + +/*================================================================*/ +/* Function Declarations */ + + +#endif /* _P80211IOCTL_H */ --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/wlan_compat.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/wlan_compat.h @@ -0,0 +1,784 @@ +/* src/include/wlan/wlan_compat.h +* +* Types and macros to aid in portability +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ + +#ifndef _WLAN_COMPAT_H +#define _WLAN_COMPAT_H + +/*=============================================================*/ +/*------ Establish Platform Identity --------------------------*/ +/*=============================================================*/ +/* Key macros: */ +/* WLAN_CPU_FAMILY */ + #define WLAN_Ix86 1 + #define WLAN_PPC 2 + #define WLAN_Ix96 3 + #define WLAN_ARM 4 + #define WLAN_ALPHA 5 + #define WLAN_MIPS 6 + #define WLAN_HPPA 7 + #define WLAN_SPARC 8 + #define WLAN_SH 9 + #define WLAN_x86_64 10 +/* WLAN_SYSARCH */ + #define WLAN_PCAT 1 + #define WLAN_MBX 2 + #define WLAN_RPX 3 + #define WLAN_LWARCH 4 + #define WLAN_PMAC 5 + #define WLAN_SKIFF 6 + #define WLAN_BITSY 7 + #define WLAN_ALPHAARCH 7 + #define WLAN_MIPSARCH 9 + #define WLAN_HPPAARCH 10 + #define WLAN_SPARCARCH 11 + #define WLAN_SHARCH 12 + +/* Note: the PLX HOSTIF above refers to some vendors implementations for */ +/* PCI. It's a PLX chip that is a PCI to PCMCIA adapter, but it */ +/* isn't a real PCMCIA host interface adapter providing all the */ +/* card&socket services. */ + +#if (defined(CONFIG_PPC) || defined(CONFIG_8xx) || defined(__powerpc__)) +#ifndef __ppc__ +#define __ppc__ +#endif +#endif + +#if defined(__KERNEL__) + +#ifndef AUTOCONF_INCLUDED +#include +#endif + +#if defined(__x86_64__) + #define WLAN_CPU_FAMILY WLAN_x86_64 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) + #define WLAN_CPU_FAMILY WLAN_Ix86 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__ppc__) + #define WLAN_CPU_FAMILY WLAN_PPC + #if defined(CONFIG_MBX) + #define WLAN_SYSARCH WLAN_MBX + #elif defined(CONFIG_RPXLITE) + #define WLAN_SYSARCH WLAN_RPX + #elif defined(CONFIG_RPXCLASSIC) + #define WLAN_SYSARCH WLAN_RPX + #else + #define WLAN_SYSARCH WLAN_PMAC + #endif +#elif defined(__arm__) + #define WLAN_CPU_FAMILY WLAN_ARM + #define WLAN_SYSARCH WLAN_SKIFF +#elif defined(__alpha__) + #define WLAN_CPU_FAMILY WLAN_ALPHA + #define WLAN_SYSARCH WLAN_ALPHAARCH +#elif defined(__mips__) + #define WLAN_CPU_FAMILY WLAN_MIPS + #define WLAN_SYSARCH WLAN_MIPSARCH +#elif defined(__hppa__) + #define WLAN_CPU_FAMILY WLAN_HPPA + #define WLAN_SYSARCH WLAN_HPPAARCH +#elif defined(__sparc__) + #define WLAN_CPU_FAMILY WLAN_SPARC + #define WLAN_SYSARCH WLAN_SPARC +#elif defined(__sh__) + #define WLAN_CPU_FAMILY WLAN_SH + #define WLAN_SYSARCH WLAN_SHARCH + #ifndef __LITTLE_ENDIAN__ + #define __LITTLE_ENDIAN__ + #endif +#else + #error "No CPU identified!" +#endif +#endif /* __KERNEL__ */ + +/* + Some big endian machines implicitly do all I/O in little endian mode. + + In particular: + Linux/PPC on PowerMacs (PCI) + Arm/Intel Xscale (PCI) + + This may also affect PLX boards and other BE &| PPC platforms; + as new ones are discovered, add them below. +*/ + +#if defined(WLAN_HOSTIF) +#if ((WLAN_HOSTIF == WLAN_PCI) || (WLAN_HOSTIF == WLAN_PLX)) +#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC) || (WLAN_SYSARCH == WLAN_SPARC)) +#define REVERSE_ENDIAN +#endif +#endif +#endif + +/*=============================================================*/ +/*------ Bit settings -----------------------------------------*/ +/*=============================================================*/ + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#include + +typedef u_int8_t UINT8; +typedef u_int16_t UINT16; +typedef u_int32_t UINT32; + +typedef int8_t INT8; +typedef int16_t INT16; +typedef int32_t INT32; + +typedef unsigned int UINT; +typedef signed int INT; + +typedef u_int64_t UINT64; +typedef int64_t INT64; + +#define UINT8_MAX (0xffUL) +#define UINT16_MAX (0xffffUL) +#define UINT32_MAX (0xffffffffUL) + +#define INT8_MAX (0x7fL) +#define INT16_MAX (0x7fffL) +#define INT32_MAX (0x7fffffffL) + +/*=============================================================*/ +/*------ Compiler Portability Macros --------------------------*/ +/*=============================================================*/ +#define __WLAN_ATTRIB_PACK__ __attribute__ ((packed)) + +/*=============================================================*/ +/*------ OS Portability Macros --------------------------------*/ +/*=============================================================*/ + +#ifndef WLAN_DBVAR +#define WLAN_DBVAR wlan_debug +#endif + +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) +# if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,8)) +# include +# else +# include +# endif +#elif defined(__KERNEL__) +# define PREEMPT_MASK (0x000000FFUL) +# define preempt_count() (0UL) +#endif + +#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __FUNCTION__ , ##args); + +#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __FUNCTION__ , ##args); + +#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __FUNCTION__ , ##args); + +#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args) + +#if defined(WLAN_INCLUDE_DEBUG) + #define WLAN_ASSERT(c) if ((!(c)) && WLAN_DBVAR >= 1) { \ + WLAN_LOG_DEBUG(1, "Assertion failure!\n"); } + #define WLAN_HEX_DUMP( l, x, p, n) if( WLAN_DBVAR >= (l) ){ \ + int __i__; \ + printk(KERN_DEBUG x ":"); \ + for( __i__=0; __i__ < (n); __i__++) \ + printk( " %02x", ((UINT8*)(p))[__i__]); \ + printk("\n"); } + #define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } } + #define DBFEXIT { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } } + + #define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x , __FUNCTION__, (preempt_count() & PREEMPT_MASK), ##args ); +#else + #define WLAN_ASSERT(c) + #define WLAN_HEX_DUMP( l, s, p, n) + #define DBFENTER + #define DBFEXIT + + #define WLAN_LOG_DEBUG(l, s, args...) +#endif + +#ifdef CONFIG_SMP +#define __SMP__ 1 +#endif + +#if defined(__KERNEL__) + +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) || (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))) +#define URB_ONLY_CALLBACK +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) +#define PT_REGS , struct pt_regs *regs +#else +#define PT_REGS +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) +# define del_singleshot_timer_sync(a) del_timer_sync(a) +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17)) +#define CONFIG_NETLINK 1 +#endif + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) +#define kfree_s(a, b) kfree((a)) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) +#ifndef init_waitqueue_head +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,0,16)) +#define init_waitqueue_head(p) (*(p) = NULL) +#else +#define init_waitqueue_head(p) init_waitqueue(p) +#endif +typedef struct wait_queue *wait_queue_head_t; +typedef struct wait_queue wait_queue_t; +#define set_current_state(b) { current->state = (b); mb(); } +#define init_waitqueue_entry(a, b) { (a)->task = current; } +#endif +#endif + +#ifndef wait_event_interruptible_timeout +// retval == 0; signal met; we're good. +// retval < 0; interrupted by signal. +// retval > 0; timed out. + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) // fixme? + +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret) ; \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + set_current_state(TASK_RUNNING); \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#else // 2.2 + + +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + struct wait_queue __wait; \ + \ + __wait.task = current; \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + current->state = TASK_INTERRUPTIBLE; \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#endif // version >= 2.4 + +#define wait_event_interruptible_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __wait_event_interruptible_timeout(wq, condition, __ret); \ + __ret; \ +}) + +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20)) +#ifdef _LINUX_LIST_H + +static inline void list_move_tail(struct list_head *list, + struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add_tail(list, head); +} + +static inline void __list_splice(struct list_head *list, + struct list_head *head) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; +} + +static inline void list_move(struct list_head *list, struct list_head *head) +{ + __list_del(list->prev, list->next); + list_add(list, head); +} + +static inline void list_splice_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head); + INIT_LIST_HEAD(list); + } +} + + +#endif // LIST_H +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#define SET_MODULE_OWNER(x) do { } while (0) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,90)) +#define spin_lock(l) do { } while (0) +#define spin_unlock(l) do { } while (0) +#define spin_lock_irqsave(l,f) do { save_flags(f); cli(); } while (0) +#define spin_unlock_irqrestore(l,f) do { restore_flags(f); } while (0) +#define spin_lock_init(s) do { } while (0) +#define spin_trylock(l) (1) +typedef int spinlock_t; +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) // XXX ??? +#define spin_lock_bh spin_lock +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#ifdef CONFIG_SMP +#define spin_is_locked(x) (*(volatile char *)(&(x)->lock) <= 0) +#else +#define spin_is_locked(l) (0) +#endif +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,28)) +#define __user +#define __iomem +#endif + +#ifdef _LINUX_PROC_FS_H + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +#define PROC_NET proc_net +#else +#define PROC_NET init_net.proc_net +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,25)) + +extern inline struct proc_dir_entry * +create_proc_read_entry(const char *name, mode_t mode, + struct proc_dir_entry *base, + read_proc_t *read_proc, void *data) +{ + struct proc_dir_entry *res = create_proc_entry(name, mode, base); + if (res) { + res->read_proc = read_proc; + res->data = data; + } + return res; +} +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,29)) +#ifndef proc_mkdir +#define proc_mkdir(name, root) create_proc_entry(name, S_IFDIR, root) +#endif +#endif +#endif /* _LINUX_PROC_FS_H */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) +#define skb_reset_mac_header(__a) (__a)->mac.raw = (__a)->data +#define SKB_MAC_HEADER(__a) (__a)->mac.raw +#else +#define SKB_MAC_HEADER(__a) (__a)->mac_header +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#define IRQF_DISABLED SA_INTERRUPT +#define IRQF_SHARED SA_SHIRQ +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#ifndef INIT_TQUEUE +#define PREPARE_TQUEUE(_tq, _routine, _data) \ + do { \ + (_tq)->routine = _routine; \ + (_tq)->data = _data; \ + } while (0) +#define INIT_TQUEUE(_tq, _routine, _data) \ + do { \ + INIT_LIST_HEAD(&(_tq)->list); \ + (_tq)->sync = 0; \ + PREPARE_TQUEUE((_tq), (_routine), (_data)); \ + } while (0) +#endif + +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) +#endif + +#ifndef INIT_WORK +#define work_struct tq_struct + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#define schedule_work(a) queue_task(a, &tq_scheduler) +#else +#define schedule_work(a) schedule_task(a) +#endif + +#define flush_scheduled_work flush_scheduled_tasks +#define INIT_WORK2(_wq, _routine) INIT_TQUEUE(_wq, (void (*)(void *))_routine, _wq) +#endif + +#else // >= 2.5 kernel + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, (void (*)(void *))_routine, _wq) +#else +#define INIT_WORK2(_wq, _routine) INIT_WORK(_wq, _routine) +#endif + +#endif // >= 2.5 kernel + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,38)) +typedef struct device netdevice_t; +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)) +typedef struct net_device netdevice_t; +#else +#undef netdevice_t +typedef struct net_device netdevice_t; +#endif + +#ifdef WIRELESS_EXT +#if (WIRELESS_EXT < 13) +struct iw_request_info +{ + __u16 cmd; /* Wireless Extension command */ + __u16 flags; /* More to come ;-) */ +}; +#endif +#endif + + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18)) +#define MODULE_PARM(a,b) extern int __bogus_decl +#define MODULE_AUTHOR(a) extern int __bogus_decl +#define MODULE_DESCRIPTION(a) extern int __bogus_decl +#define MODULE_SUPPORTED_DEVICE(a) extern int __bogus_decl +#undef GET_USE_COUNT +#define GET_USE_COUNT(m) mod_use_count_ +#endif + +#ifndef MODULE_OWNER +#define MODULE_OWNER(a) extern int __bogus_decl +#define ANCIENT_MODULE_CODE +#endif + +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(m) extern int __bogus_decl +#endif + +/* TODO: Do we care about this? */ +#ifndef MODULE_DEVICE_TABLE +#define MODULE_DEVICE_TABLE(foo,bar) +#endif + +#define wlan_minutes2ticks(a) ((a)*(wlan_ticks_per_sec * 60)) +#define wlan_seconds2ticks(a) ((a)*(wlan_ticks_per_sec)) + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47)) +#define NEW_MODULE_CODE +#ifdef ANCIENT_MODULE_CODE +#undef ANCIENT_MODULE_CODE +#endif +#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,25)) +#define module_param(name, type, perm) \ + static inline void *__check_existence_##name(void) { return &name; } \ + MODULE_PARM(name, _MODULE_PARM_STRING_ ## type) + +#define _MODULE_PARM_STRING_byte "b" +#define _MODULE_PARM_STRING_short "h" +#define _MODULE_PARM_STRING_ushort "h" +#define _MODULE_PARM_STRING_int "i" +#define _MODULE_PARM_STRING_uint "i" +#define _MODULE_PARM_STRING_long "l" +#define _MODULE_PARM_STRING_ulong "l" +#define _MODULE_PARM_STRING_bool "i" +#endif + +/* linux < 2.5.69 */ +#ifndef IRQ_NONE +typedef void irqreturn_t; +#define IRQ_NONE +#define IRQ_HANDLED +#define IRQ_RETVAL(x) +#endif + +#ifndef in_atomic +#define in_atomic() 0 +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) +#define URB_ASYNC_UNLINK 0 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)) +#define URB_ASYNC_UNLINK USB_ASYNC_UNLINK +#define usb_fill_bulk_urb FILL_BULK_URB +#define usb_kill_urb usb_unlink_urb +#else +#define USB_QUEUE_BULK 0 +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)) +typedef u32 pm_message_t; +#endif + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)) +#define hotplug_path "/etc/hotplug/wlan.agent" +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) +#define free_netdev(x) kfree(x) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)) +#define eth_hdr(x) (x)->mac.ethernet +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#define del_timer_sync(a) del_timer(a) +#endif + +#ifndef might_sleep +#define might_sleep(a) do { } while (0) +#endif + +/* Apparently 2.4.2 ethtool is quite different, maybe newer too? */ +#if (defined(SIOETHTOOL) && !defined(ETHTOOL_GDRVINFO)) +#undef SIOETHTOOL +#endif + +// pcmcia-cs stuff +#if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68)) && \ + !defined(pcmcia_access_configuration_register)) +#define pcmcia_access_configuration_register(handle, reg) \ + CardServices(AccessConfigurationRegister, handle, reg) +#define pcmcia_register_client(handle, reg) \ + CardServices(RegisterClient, handle, reg) +#define pcmcia_deregister_client(handle) \ + CardServices(DeregisterClient, handle) +#define pcmcia_get_first_tuple(handle, tuple) \ + CardServices(GetFirstTuple, handle, tuple) +#define pcmcia_get_next_tuple(handle, tuple) \ + CardServices(GetNextTuple, handle, tuple) +#define pcmcia_get_tuple_data(handle, tuple) \ + CardServices(GetTupleData, handle, tuple) +#define pcmcia_parse_tuple(handle, tuple, parse) \ + CardServices(ParseTuple, handle, tuple, parse) +#define pcmcia_get_configuration_info(handle, config) \ + CardServices(GetConfigurationInfo, handle, config) +#define pcmcia_request_io(handle, req) \ + CardServices(RequestIO, handle, req) +#define pcmcia_request_irq(handle, req) \ + CardServices(RequestIRQ, handle, req) +#define pcmcia_request_configuration(handle, req) \ + CardServices(RequestConfiguration, handle, req) +#define pcmcia_release_configuration(handle) \ + CardServices(ReleaseConfiguration, handle) +#define pcmcia_release_io(handle, req) \ + CardServices(ReleaseIO, handle, req) +#define pcmcia_release_irq(handle, req) \ + CardServices(ReleaseIRQ, handle, req) +#define pcmcia_release_window(win) \ + CardServices(ReleaseWindow, win) +#define pcmcia_get_card_services_info(info) \ + CardServices(GetCardServicesInfo, info) +#define pcmcia_report_error(handle, err) \ + CardServices(ReportError, handle, err) +#endif + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) +#define round_jiffies(a) (a) +#endif + +#endif /* __KERNEL__ */ + +/*=============================================================*/ +/*------ Hardware Portability Macros --------------------------*/ +/*=============================================================*/ + +#define ieee2host16(n) __le16_to_cpu(n) +#define ieee2host32(n) __le32_to_cpu(n) +#define host2ieee16(n) __cpu_to_le16(n) +#define host2ieee32(n) __cpu_to_le32(n) + +#if (WLAN_CPU_FAMILY != WLAN_MIPS) +typedef UINT32 phys_t; +#endif + +#if (WLAN_CPU_FAMILY == WLAN_PPC) + #define wlan_inw(a) in_be16((unsigned short *)((a)+_IO_BASE)) + #define wlan_inw_le16_to_cpu(a) inw((a)) + #define wlan_outw(v,a) out_be16((unsigned short *)((a)+_IO_BASE), (v)) + #define wlan_outw_cpu_to_le16(v,a) outw((v),(a)) +#else + #define wlan_inw(a) inw((a)) + #define wlan_inw_le16_to_cpu(a) __cpu_to_le16(inw((a))) + #define wlan_outw(v,a) outw((v),(a)) + #define wlan_outw_cpu_to_le16(v,a) outw(__cpu_to_le16((v)),(a)) +#endif + +/*=============================================================*/ +/*--- General Macros ------------------------------------------*/ +/*=============================================================*/ + +#define wlan_max(a, b) (((a) > (b)) ? (a) : (b)) +#define wlan_min(a, b) (((a) < (b)) ? (a) : (b)) + +#define wlan_isprint(c) (((c) > (0x19)) && ((c) < (0x7f))) + +#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a))) + +/* Create a string of printable chars from something that might not be */ +/* It's recommended that the str be 4*len + 1 bytes long */ +#define wlan_mkprintstr(buf, buflen, str, strlen) \ +{ \ + int i = 0; \ + int j = 0; \ + memset(str, 0, (strlen)); \ + for (i = 0; i < (buflen); i++) { \ + if ( wlan_isprint((buf)[i]) ) { \ + (str)[j] = (buf)[i]; \ + j++; \ + } else { \ + (str)[j] = '\\'; \ + (str)[j+1] = 'x'; \ + (str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \ + (str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \ + j += 4; \ + } \ + } \ +} + +/*=============================================================*/ +/*--- Variables -----------------------------------------------*/ +/*=============================================================*/ + +#ifdef WLAN_INCLUDE_DEBUG +extern int wlan_debug; +#endif + +extern int wlan_ethconv; /* What's the default ethconv? */ + +/*=============================================================*/ +/*--- Functions -----------------------------------------------*/ +/*=============================================================*/ +#endif /* _WLAN_COMPAT_H */ + --- linux-2.6.28.orig/ubuntu/misc/wireless/p80211/wlan/version.h +++ linux-2.6.28/ubuntu/misc/wireless/p80211/wlan/version.h @@ -0,0 +1,64 @@ +/* src/include/wlan/version.h +* +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +*/ +#ifndef _WLAN_VERSION_H +#define _WLAN_VERSION_H +#ifndef KERNEL_VERSION +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) +#endif + +/* WLAN_HOSTIF (generally set on the command line, not detected) */ +#define WLAN_NONE 0 +#define WLAN_PCMCIA 1 +#define WLAN_ISA 2 +#define WLAN_PCI 3 +#define WLAN_USB 4 +#define WLAN_PLX 5 +#define WLAN_SLAVE 6 +#define WLAN_RELEASE "0.2.9" +#define WLAN_RELEASE_CODE 0x000209 +#define WLAN_BUILD_DATE "Sun Jul 27 23:23:32 CEST 2008" + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan.c @@ -0,0 +1,421 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +#define LOG_BAD_EID(hdr,len,ie_ptr) acx_log_bad_eid(hdr, len, ((wlan_ie_t*)ie_ptr)) + +#define IE_EID(ie_ptr) (((wlan_ie_t*)(ie_ptr))->eid) +#define IE_LEN(ie_ptr) (((wlan_ie_t*)(ie_ptr))->len) +#define OFFSET(hdr,off) (WLAN_HDR_A3_DATAP(hdr) + (off)) + + +/*********************************************************************** +** wlan_mgmt_decode_XXX +** +** Given a complete frame in f->hdr, sets the pointers in f to +** the areas that correspond to the parts of the frame. +** +** Assumptions: +** 1) f->len and f->hdr are already set +** 2) f->len is the length of the MAC header + data, the FCS +** is NOT included +** 3) all members except len and hdr are zero +** Arguments: +** f frame structure +** +** Returns: +** nothing +** +** Side effects: +** frame structure members are pointing at their +** respective portions of the frame buffer. +*/ +void +wlan_mgmt_decode_beacon(wlan_fr_beacon_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_BEACON; + + /*-- Fixed Fields ----*/ + f->ts = (u64 *) OFFSET(f->hdr, WLAN_BEACON_OFF_TS); + f->bcn_int = (u16 *) OFFSET(f->hdr, WLAN_BEACON_OFF_BCN_INT); + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_BEACON_OFF_CAPINFO); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_BEACON_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_FH_PARMS: + f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr; + break; + case WLAN_EID_DS_PARMS: + f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr; + break; + case WLAN_EID_CF_PARMS: + f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr; + break; + case WLAN_EID_IBSS_PARMS: + f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr; + break; + case WLAN_EID_TIM: + f->tim = (wlan_ie_tim_t *) ie_ptr; + break; + case WLAN_EID_ERP_INFO: + f->erp = (wlan_ie_erp_t *) ie_ptr; + break; + + case WLAN_EID_COUNTRY: + /* was seen: 07 06 47 42 20 01 0D 14 */ + case WLAN_EID_PWR_CONSTRAINT: + /* was seen by Ashwin Mansinghka from + Atheros-based PCI card in AP mode using madwifi drivers: */ + /* 20 01 00 */ + case WLAN_EID_NONERP: + /* was seen from WRT54GS with OpenWrt: 2F 01 07 */ + case WLAN_EID_UNKNOWN128: + /* was seen by Jacek Jablonski from Orinoco AP */ + /* 80 06 00 60 1D 2C 3B 00 */ + case WLAN_EID_UNKNOWN133: + /* was seen by David Bronaugh from ???? */ + /* 85 1E 00 00 84 12 07 00 FF 00 11 00 61 70 63 31 */ + /* 63 73 72 30 34 32 00 00 00 00 00 00 00 00 00 25 */ + case WLAN_EID_UNKNOWN223: + /* was seen by Carlos Martin from ???? */ + /* DF 20 01 1E 04 00 00 00 06 63 09 02 FF 0F 30 30 */ + /* 30 42 36 42 33 34 30 39 46 31 00 00 00 00 00 00 00 00 */ + case WLAN_EID_GENERIC: + /* WPA: hostap code: + if (pos[1] >= 4 && + pos[2] == 0x00 && pos[3] == 0x50 && + pos[4] == 0xf2 && pos[5] == 1) { + wpa = pos; + wpa_len = pos[1] + 2; + } + TI x4 mode: seen DD 04 08 00 28 00 + (08 00 28 is TI's OUI) + last byte is probably 0/1 - disabled/enabled + */ + case WLAN_EID_RSN: + /* hostap does something with it: + rsn = pos; + rsn_len = pos[1] + 2; + */ + break; + + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +#ifdef UNUSED +void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t * f) +{ + f->type = WLAN_FSTYPE_ATIM; + /*-- Fixed Fields ----*/ + /*-- Information elements */ +} +#endif /* UNUSED */ + +void +wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t * f) +{ + f->type = WLAN_FSTYPE_DISASSOC; + + /*-- Fixed Fields ----*/ + f->reason = (u16 *) OFFSET(f->hdr, WLAN_DISASSOC_OFF_REASON); + + /*-- Information elements */ +} + + +void +wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + + f->type = WLAN_FSTYPE_ASSOCREQ; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_CAP_INFO); + f->listen_int = (u16 *) OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_LISTEN_INT); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_ASSOCREQ_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +void +wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t * f) +{ + f->type = WLAN_FSTYPE_ASSOCRESP; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_CAP_INFO); + f->status = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_STATUS); + f->aid = (u16 *) OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_AID); + + /*-- Information elements */ + f->supp_rates = (wlan_ie_supp_rates_t *) + OFFSET(f->hdr, WLAN_ASSOCRESP_OFF_SUPP_RATES); +} + + +#ifdef UNUSED +void +wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_REASSOCREQ; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_CAP_INFO); + f->listen_int = (u16 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_LISTEN_INT); + f->curr_ap = (u8 *) OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_CURR_AP); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_REASSOCREQ_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +void +wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t * f) +{ + f->type = WLAN_FSTYPE_REASSOCRESP; + + /*-- Fixed Fields ----*/ + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_CAP_INFO); + f->status = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_STATUS); + f->aid = (u16 *) OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_AID); + + /*-- Information elements */ + f->supp_rates = (wlan_ie_supp_rates_t *) + OFFSET(f->hdr, WLAN_REASSOCRESP_OFF_SUPP_RATES); +} + + +void +wlan_mgmt_decode_probereq(wlan_fr_probereq_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_PROBEREQ; + + /*-- Fixed Fields ----*/ + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_PROBEREQ_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} +#endif /* UNUSED */ + + +/* TODO: decoding of beacon and proberesp can be merged (similar structure) */ +void +wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_PROBERESP; + + /*-- Fixed Fields ----*/ + f->ts = (u64 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_TS); + f->bcn_int = (u16 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_BCN_INT); + f->cap_info = (u16 *) OFFSET(f->hdr, WLAN_PROBERESP_OFF_CAP_INFO); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_PROBERESP_OFF_SSID); + while (ie_ptr < end) { + switch (IE_EID(ie_ptr)) { + case WLAN_EID_SSID: + f->ssid = (wlan_ie_ssid_t *) ie_ptr; + break; + case WLAN_EID_SUPP_RATES: + f->supp_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_EXT_RATES: + f->ext_rates = (wlan_ie_supp_rates_t *) ie_ptr; + break; + case WLAN_EID_FH_PARMS: + f->fh_parms = (wlan_ie_fh_parms_t *) ie_ptr; + break; + case WLAN_EID_DS_PARMS: + f->ds_parms = (wlan_ie_ds_parms_t *) ie_ptr; + break; + case WLAN_EID_CF_PARMS: + f->cf_parms = (wlan_ie_cf_parms_t *) ie_ptr; + break; + case WLAN_EID_IBSS_PARMS: + f->ibss_parms = (wlan_ie_ibss_parms_t *) ie_ptr; + break; +#ifdef DONT_DO_IT_ADD_REAL_HANDLING_INSTEAD + case WLAN_EID_COUNTRY: + break; + ... +#endif +#ifdef SENT_HERE_BY_OPENWRT + /* should those be trapped or handled?? */ + case WLAN_EID_ERP_INFO: + break; + case WLAN_EID_NONERP: + break; + case WLAN_EID_GENERIC: + break; +#endif + default: + LOG_BAD_EID(f->hdr, f->len, ie_ptr); + break; + } + + ie_ptr = ie_ptr + 2 + IE_LEN(ie_ptr); + } +} + + +void +wlan_mgmt_decode_authen(wlan_fr_authen_t * f) +{ + u8 *ie_ptr; + u8 *end = (u8*)f->hdr + f->len; + + f->type = WLAN_FSTYPE_AUTHEN; + + /*-- Fixed Fields ----*/ + f->auth_alg = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_AUTH_ALG); + f->auth_seq = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_AUTH_SEQ); + f->status = (u16 *) OFFSET(f->hdr, WLAN_AUTHEN_OFF_STATUS); + + /*-- Information elements */ + ie_ptr = OFFSET(f->hdr, WLAN_AUTHEN_OFF_CHALLENGE); + if ((ie_ptr < end) && (IE_EID(ie_ptr) == WLAN_EID_CHALLENGE)) { + f->challenge = (wlan_ie_challenge_t *) ie_ptr; + } +} + + +void +wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t * f) +{ + f->type = WLAN_FSTYPE_DEAUTHEN; + + /*-- Fixed Fields ----*/ + f->reason = (u16 *) OFFSET(f->hdr, WLAN_DEAUTHEN_OFF_REASON); + + /*-- Information elements */ +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/setrate.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/setrate.c @@ -0,0 +1,213 @@ +/* TODO: stop #including, move into wireless.c + * until then, keep in sync copies in prism54/ and acx/ dirs + * code+data size: less than 1k */ + +enum { + DOT11_RATE_1, + DOT11_RATE_2, + DOT11_RATE_5, + DOT11_RATE_11, + DOT11_RATE_22, + DOT11_RATE_33, + DOT11_RATE_6, + DOT11_RATE_9, + DOT11_RATE_12, + DOT11_RATE_18, + DOT11_RATE_24, + DOT11_RATE_36, + DOT11_RATE_48, + DOT11_RATE_54 +}; +enum { + DOT11_MOD_DBPSK, + DOT11_MOD_DQPSK, + DOT11_MOD_CCK, + DOT11_MOD_OFDM, + DOT11_MOD_CCKOFDM, + DOT11_MOD_PBCC +}; +static const u8 ratelist[] = { 1,2,5,11,22,33,6,9,12,18,24,36,48,54 }; +static const u8 dot11ratebyte[] = { 1*2,2*2,11,11*2,22*2,33*2,6*2,9*2,12*2,18*2,24*2,36*2,48*2,54*2 }; +static const u8 default_modulation[] = { + DOT11_MOD_DBPSK, + DOT11_MOD_DQPSK, + DOT11_MOD_CCK, + DOT11_MOD_CCK, + DOT11_MOD_PBCC, + DOT11_MOD_PBCC, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM, + DOT11_MOD_OFDM +}; + +static /* TODO: remove 'static' when moved to wireless.c */ +int +rate_mbit2enum(int n) { + int i=0; + while(i=DOT11_RATE_6) return DOT11_MOD_OFDM; */ + return default_modulation[r_enum]; + } + if(suffix=='c') { + if(r_enumDOT11_RATE_11) return -EINVAL; + return DOT11_MOD_CCK; + } + if(suffix=='p') { + if(r_enumDOT11_RATE_33) return -EINVAL; + return DOT11_MOD_PBCC; + } + if(suffix=='o') { + if(r_enumINT_MAX) return -EINVAL; + + rate_enum = rate_mbit2enum(rate_mbit); + if(rate_enum<0) return rate_enum; + + c = *str; + mod = get_modulation(rate_enum, c); + if(mod<0) return mod; + + if(c>='a' && c<='z') c = *++str; + if(c!=',' && c!=' ' && c!='\0') return -EINVAL; + + if(supported) { + int r = supported(rate_mbit, mod, opaque); + if(r) return r; + } + + *vector++ = dot11ratebyte[rate_enum] | or_mask; + + size--; + str++; + } while(size>0 && c==','); + + if(size<1) return -E2BIG; + *vector=0; /* TODO: sort, remove dups? */ + + *pstr = str-1; + return 0; +} + +static /* TODO: remove 'static' when moved to wireless.c */ +int +fill_ratevectors(const char *str, u8 *brate, u8 *orate, int size, + int (*supported)(int mbit, int mod, void *opaque), void *opaque) +{ + int r; + + r = fill_ratevector(&str, brate, size, supported, opaque, 0x80); + if(r) return r; + + orate[0] = 0; + if(*str==' ') { + str++; + r = fill_ratevector(&str, orate, size, supported, opaque, 0); + if(r) return r; + /* TODO: sanitize, e.g. remove/error on rates already in basic rate set? */ + } + if(*str) + return -EINVAL; + + return 0; +} +#endif + +/* TODO: use u64 masks? */ + +static int +fill_ratemask(const char **pstr, u32* mask, + int (*supported)(int mbit, int mod,void *opaque), + u32 (*gen_mask)(int mbit, int mod,void *opaque), + void *opaque) +{ + unsigned long rate_mbit; + int rate_enum,mod; + u32 m = 0; + const char *str = *pstr; + char c; + + do { + rate_mbit = simple_strtoul(str, (char**)&str, 10); + if(rate_mbit>INT_MAX) return -EINVAL; + + rate_enum = rate_mbit2enum(rate_mbit); + if(rate_enum<0) return rate_enum; + + c = *str; + mod = get_modulation(rate_enum, c); + if(mod<0) return mod; + + if(c>='a' && c<='z') c = *++str; + if(c!=',' && c!=' ' && c!='\0') return -EINVAL; + + if(supported) { + int r = supported(rate_mbit, mod, opaque); + if(r) return r; + } + + m |= gen_mask(rate_mbit, mod, opaque); + str++; + } while(c==','); + + *pstr = str-1; + *mask |= m; + return 0; +} + +static /* TODO: remove 'static' when moved to wireless.c */ +int +fill_ratemasks(const char *str, u32 *bmask, u32 *omask, + int (*supported)(int mbit, int mod,void *opaque), + u32 (*gen_mask)(int mbit, int mod,void *opaque), + void *opaque) +{ + int r; + + r = fill_ratemask(&str, bmask, supported, gen_mask, opaque); + if(r) return r; + + if(*str==' ') { + str++; + r = fill_ratemask(&str, omask, supported, gen_mask, opaque); + if(r) return r; + } + if(*str) + return -EINVAL; + return 0; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/usb.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/usb.c @@ -0,0 +1,1725 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** USB support for TI ACX100 based devices. Many parts are taken from +** the PCI driver. +** +** Authors: +** Martin Wawro +** Andreas Mohr +** +** LOCKING +** callback functions called by USB core are running in interrupt context +** and thus have names with _i_. +*/ +#define ACX_USB 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +/* number of endpoints of an interface */ +#define NUM_EP(intf) (intf)->altsetting[0].desc.bNumEndpoints +#define EP(intf, nr) (intf)->altsetting[0].endpoint[(nr)].desc +#define GET_DEV(udev) usb_get_dev((udev)) +#define PUT_DEV(udev) usb_put_dev((udev)) +#define SET_NETDEV_OWNER(ndev, owner) /* not needed anymore ??? */ + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,14) +/* removed in 2.6.14. We will use fake value for now */ +#define URB_ASYNC_UNLINK 0 +#endif + + +/*********************************************************************** +*/ +/* ACX100 (TNETW1100) USB device: D-Link DWL-120+ */ +#define ACX100_VENDOR_ID 0x2001 +#define ACX100_PRODUCT_ID_UNBOOTED 0x3B01 +#define ACX100_PRODUCT_ID_BOOTED 0x3B00 + +/* TNETW1450 USB devices */ +#define VENDOR_ID_DLINK 0x07b8 /* D-Link Corp. */ +#define PRODUCT_ID_WUG2400 0xb21a /* AboCom WUG2400 or SafeCom SWLUT-54125 */ +#define VENDOR_ID_AVM_GMBH 0x057c +#define PRODUCT_ID_AVM_WLAN_USB 0x5601 +#define PRODUCT_ID_AVM_WLAN_USB_si 0x6201 /* "self install" named Version: driver kills kernel on inbound scans from fritz box ??? */ +#define VENDOR_ID_ZCOM 0x0cde +#define PRODUCT_ID_ZCOM_XG750 0x0017 /* not tested yet */ +#define VENDOR_ID_TI 0x0451 +#define PRODUCT_ID_TI_UNKNOWN 0x60c5 /* not tested yet */ + +#define ACX_USB_CTRL_TIMEOUT 5500 /* steps in ms */ + +/* Buffer size for fw upload, same for both ACX100 USB and TNETW1450 */ +#define ACX_USB_RWMEM_MAXLEN 2048 + +/* The number of bulk URBs to use */ +#define ACX_TX_URB_CNT 8 +#define ACX_RX_URB_CNT 2 + +/* Should be sent to the bulkout endpoint */ +#define ACX_USB_REQ_UPLOAD_FW 0x10 +#define ACX_USB_REQ_ACK_CS 0x11 +#define ACX_USB_REQ_CMD 0x12 + +/*********************************************************************** +** Prototypes +*/ +static int acxusb_e_probe(struct usb_interface *, const struct usb_device_id *); +static void acxusb_e_disconnect(struct usb_interface *); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) +static void acxusb_i_complete_tx(struct urb *); +static void acxusb_i_complete_rx(struct urb *); +#else +static void acxusb_i_complete_tx(struct urb *, struct pt_regs *); +static void acxusb_i_complete_rx(struct urb *, struct pt_regs *); +#endif +static int acxusb_e_open(struct net_device *); +static int acxusb_e_close(struct net_device *); +static void acxusb_i_set_rx_mode(struct net_device *); +static int acxusb_boot(struct usb_device *); + +static void acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx); + +static void acxusb_i_tx_timeout(struct net_device *); + +/* static void dump_device(struct usb_device *); */ +/* static void dump_device_descriptor(struct usb_device_descriptor *); */ +/* static void dump_config_descriptor(struct usb_config_descriptor *); */ + +/*********************************************************************** +** Module Data +*/ +#define TXBUFSIZE sizeof(usb_txbuffer_t) +/* + * Now, this is just plain lying, but the device insists in giving us + * huge packets. We supply extra space after rxbuffer. Need to understand + * it better... + */ +#define RXBUFSIZE (sizeof(rxbuffer_t) + \ + (sizeof(usb_rx_t) - sizeof(struct usb_rx_plain))) + +static const struct usb_device_id +acxusb_ids[] = { + { USB_DEVICE(ACX100_VENDOR_ID, ACX100_PRODUCT_ID_BOOTED) }, + { USB_DEVICE(ACX100_VENDOR_ID, ACX100_PRODUCT_ID_UNBOOTED) }, + {} +}; +MODULE_DEVICE_TABLE(usb, acxusb_ids); + +/* USB driver data structure as required by the kernel's USB core */ +static struct usb_driver +acxusb_driver = { + .name = "acx_usb", + .probe = acxusb_e_probe, + .disconnect = acxusb_e_disconnect, + .id_table = acxusb_ids +}; + + +/*********************************************************************** +** USB helper +** +** ldd3 ch13 says: +** When the function is usb_kill_urb, the urb lifecycle is stopped. This +** function is usually used when the device is disconnected from the system, +** in the disconnect callback. For some drivers, the usb_unlink_urb function +** should be used to tell the USB core to stop an urb. This function does not +** wait for the urb to be fully stopped before returning to the caller. +** This is useful for stoppingthe urb while in an interrupt handler or when +** a spinlock is held, as waiting for a urb to fully stop requires the ability +** for the USB core to put the calling process to sleep. This function requires +** that the URB_ASYNC_UNLINK flag value be set in the urb that is being asked +** to be stopped in order to work properly. +** +** (URB_ASYNC_UNLINK is obsolete, usb_unlink_urb will always be +** asynchronous while usb_kill_urb is synchronous and should be called +** directly (drivers/usb/core/urb.c)) +** +** In light of this, timeout is just for paranoid reasons... +* +* Actually, it's useful for debugging. If we reach timeout, we're doing +* something wrong with the urbs. +*/ +static void +acxusb_unlink_urb(struct urb* urb) +{ + if (!urb) + return; + + if (urb->status == -EINPROGRESS) { + int timeout = 10; + + usb_unlink_urb(urb); + while (--timeout && urb->status == -EINPROGRESS) { + mdelay(1); + } + if (!timeout) { + printk("acx_usb: urb unlink timeout!\n"); + } + } +} + + +/*********************************************************************** +** EEPROM and PHY read/write helpers +*/ +/*********************************************************************** +** acxusb_s_read_phy_reg +*/ +int +acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) +{ + /* mem_read_write_t mem; */ + + FN_ENTER; + + printk("%s doesn't seem to work yet, disabled.\n", __func__); + + /* + mem.addr = cpu_to_le16(reg); + mem.type = cpu_to_le16(0x82); + mem.len = cpu_to_le32(4); + acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_READ, &mem, sizeof(mem)); + *charbuf = mem.data; + log(L_DEBUG, "read radio PHY[0x%04X]=0x%02X\n", reg, *charbuf); + */ + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +*/ +int +acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) +{ + mem_read_write_t mem; + + FN_ENTER; + + mem.addr = cpu_to_le16(reg); + mem.type = cpu_to_le16(0x82); + mem.len = cpu_to_le32(4); + mem.data = value; + acx_s_issue_cmd(adev, ACX1xx_CMD_MEM_WRITE, &mem, sizeof(mem)); + log(L_DEBUG, "write radio PHY[0x%04X]=0x%02X\n", reg, value); + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acxusb_s_issue_cmd_timeo +** Excecutes a command in the command mailbox +** +** buffer = a pointer to the data. +** The data must not include 4 byte command header +*/ + +/* TODO: ideally we shall always know how much we need +** and this shall be 0 */ +#define BOGUS_SAFETY_PADDING 0x40 + +#undef FUNC +#define FUNC "issue_cmd" + +#if !ACX_DEBUG +int +acxusb_s_issue_cmd_timeo( + acx_device_t *adev, + unsigned cmd, + void *buffer, + unsigned buflen, + unsigned timeout) +{ +#else +int +acxusb_s_issue_cmd_timeo_debug( + acx_device_t *adev, + unsigned cmd, + void *buffer, + unsigned buflen, + unsigned timeout, + const char* cmdstr) +{ +#endif + /* USB ignores timeout param */ + + struct usb_device *usbdev; + struct { + u16 cmd; + u16 status; + u8 data[1]; + } ACX_PACKED *loc; + const char *devname; + int acklen, blocklen, inpipe, outpipe; + int cmd_status; + int result; + + FN_ENTER; + + devname = adev->ndev->name; + /* no "wlan%%d: ..." please */ + if (!devname || !devname[0] || devname[4]=='%') + devname = "acx"; + + log(L_CTL, FUNC"(cmd:%s,buflen:%u,type:0x%04X)\n", + cmdstr, buflen, + buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1); + + loc = kmalloc(buflen + 4 + BOGUS_SAFETY_PADDING, GFP_KERNEL); + if (!loc) { + printk("%s: "FUNC"(): no memory for data buffer\n", devname); + goto bad; + } + + /* get context from acx_device */ + usbdev = adev->usbdev; + + /* check which kind of command was issued */ + loc->cmd = cpu_to_le16(cmd); + loc->status = 0; + +/* NB: buflen == frmlen + 4 +** +** Interrogate: write 8 bytes: (cmd,status,rid,frmlen), then +** read (cmd,status,rid,frmlen,data[frmlen]) back +** +** Configure: write (cmd,status,rid,frmlen,data[frmlen]) +** +** Possibly bogus special handling of ACX1xx_IE_SCAN_STATUS removed +*/ + + /* now write the parameters of the command if needed */ + acklen = buflen + 4 + BOGUS_SAFETY_PADDING; + blocklen = buflen; + if (buffer && buflen) { + /* if it's an INTERROGATE command, just pass the length + * of parameters to read, as data */ + if (cmd == ACX1xx_CMD_INTERROGATE) { + blocklen = 4; + acklen = buflen + 4; + } + memcpy(loc->data, buffer, blocklen); + } + blocklen += 4; /* account for cmd,status */ + + /* obtain the I/O pipes */ + outpipe = usb_sndctrlpipe(usbdev, 0); + inpipe = usb_rcvctrlpipe(usbdev, 0); + log(L_CTL, "ctrl inpipe=0x%X outpipe=0x%X\n", inpipe, outpipe); + log(L_CTL, "sending USB control msg (out) (blocklen=%d)\n", blocklen); + if (acx_debug & L_DATA) + acx_dump_bytes(loc, blocklen); + + result = usb_control_msg(usbdev, outpipe, + ACX_USB_REQ_CMD, /* request */ + USB_TYPE_VENDOR|USB_DIR_OUT, /* requesttype */ + 0, /* value */ + 0, /* index */ + loc, /* dataptr */ + blocklen, /* size */ + ACX_USB_CTRL_TIMEOUT /* timeout in ms */ + ); + + if (result == -ENODEV) { + log(L_CTL, "no device present (unplug?)\n"); + goto good; + } + + log(L_CTL, "wrote %d bytes\n", result); + if (result < 0) { + goto bad; + } + + /* check for device acknowledge */ + log(L_CTL, "sending USB control msg (in) (acklen=%d)\n", acklen); + loc->status = 0; /* delete old status flag -> set to IDLE */ + /* shall we zero out the rest? */ + result = usb_control_msg(usbdev, inpipe, + ACX_USB_REQ_CMD, /* request */ + USB_TYPE_VENDOR|USB_DIR_IN, /* requesttype */ + 0, /* value */ + 0, /* index */ + loc, /* dataptr */ + acklen, /* size */ + ACX_USB_CTRL_TIMEOUT /* timeout in ms */ + ); + if (result < 0) { + printk("%s: "FUNC"(): USB read error %d\n", devname, result); + goto bad; + } + if (acx_debug & L_CTL) { + printk("read %d bytes: ", result); + acx_dump_bytes(loc, result); + } + +/* + check for result==buflen+4? Was seen: + +interrogate(type:ACX100_IE_DOT11_ED_THRESHOLD,len:4) +issue_cmd(cmd:ACX1xx_CMD_INTERROGATE,buflen:8,type:4111) +ctrl inpipe=0x80000280 outpipe=0x80000200 +sending USB control msg (out) (blocklen=8) +01 00 00 00 0F 10 04 00 +wrote 8 bytes +sending USB control msg (in) (acklen=12) sizeof(loc->data +read 4 bytes <==== MUST BE 12!! +*/ + + cmd_status = le16_to_cpu(loc->status); + if (cmd_status != 1) { + printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s)\n", + devname, cmd_status, acx_cmd_status_str(cmd_status)); + /* TODO: goto bad; ? */ + } + if ((cmd == ACX1xx_CMD_INTERROGATE) && buffer && buflen) { + memcpy(buffer, loc->data, buflen); + log(L_CTL, "response frame: cmd=0x%04X status=%d\n", + le16_to_cpu(loc->cmd), + cmd_status); + } +good: + kfree(loc); + FN_EXIT1(OK); + return OK; +bad: + /* Give enough info so that callers can avoid + ** printing their own diagnostic messages */ +#if ACX_DEBUG + printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr); +#else + printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd); +#endif + dump_stack(); + kfree(loc); + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acxusb_boot() +** Inputs: +** usbdev -> Pointer to kernel's usb_device structure +** +** Returns: +** (int) Errorcode or 0 on success +** +** This function triggers the loading of the firmware image from harddisk +** and then uploads the firmware to the USB device. After uploading the +** firmware and transmitting the checksum, the device resets and appears +** as a new device on the USB bus (the device we can finally deal with) +*/ +static int +acxusb_boot(struct usb_device *usbdev) +{ + char filename[256]; + char *firmware = NULL; + char *usbbuf; + unsigned int offset; + unsigned int len, inpipe, outpipe; + u32 checksum; + u32 size; + int result; + + FN_ENTER; + + usbbuf = kmalloc(ACX_USB_RWMEM_MAXLEN, GFP_KERNEL); + if (!usbbuf) { + printk(KERN_ERR "acx: no memory for USB transfer buffer (" + STRING(ACX_USB_RWMEM_MAXLEN)" bytes)\n"); + result = -ENOMEM; + goto end; + } + + snprintf(filename, sizeof(filename), "acx/%s/tiacx100usb", firmware_ver); + firmware = (char *)acx_s_read_fw(&usbdev->dev, filename, &size); + if (!firmware) { + result = -EIO; + goto end; + } + log(L_INIT, "firmware size: %d bytes\n", size); + + /* Obtain the I/O pipes */ + outpipe = usb_sndctrlpipe(usbdev, 0); + inpipe = usb_rcvctrlpipe(usbdev, 0); + + /* now upload the firmware, slice the data into blocks */ + offset = 8; + while (offset < size) { + len = size - offset; + if (len >= ACX_USB_RWMEM_MAXLEN) { + len = ACX_USB_RWMEM_MAXLEN; + } + log(L_INIT, "uploading firmware (%d bytes, offset=%d)\n", + len, offset); + result = 0; + memcpy(usbbuf, firmware + offset, len); + result = usb_control_msg(usbdev, outpipe, + ACX_USB_REQ_UPLOAD_FW, + USB_TYPE_VENDOR|USB_DIR_OUT, + size - 8, /* value */ + 0, /* index */ + usbbuf, /* dataptr */ + len, /* size */ + 3000 /* timeout in ms */ + ); + offset += len; + if (result < 0) { + printk(KERN_ERR "acx: error %d during upload " + "of firmware, aborting\n", result); + goto end; + } + } + + /* finally, send the checksum and reboot the device */ + /* does this trigger the reboot? */ + checksum = le32_to_cpu(*(u32 *)firmware); + result = usb_control_msg(usbdev, outpipe, + ACX_USB_REQ_UPLOAD_FW, + USB_TYPE_VENDOR|USB_DIR_OUT, + checksum & 0xffff, /* value */ + checksum >> 16, /* index */ + NULL, /* dataptr */ + 0, /* size */ + 3000 /* timeout in ms */ + ); + if (result < 0) { + printk(KERN_ERR "acx: error %d during tx of checksum, " + "aborting\n", result); + goto end; + } + result = usb_control_msg(usbdev, inpipe, + ACX_USB_REQ_ACK_CS, + USB_TYPE_VENDOR|USB_DIR_IN, + checksum & 0xffff, /* value */ + checksum >> 16, /* index */ + usbbuf, /* dataptr */ + 8, /* size */ + 3000 /* timeout in ms */ + ); + if (result < 0) { + printk(KERN_ERR "acx: error %d during ACK of checksum, " + "aborting\n", result); + goto end; + } + if (*usbbuf != 0x10) { + kfree(usbbuf); + printk(KERN_ERR "acx: invalid checksum?\n"); + result = -EINVAL; + goto end; + } + result = 0; + +end: + vfree(firmware); + kfree(usbbuf); + + FN_EXIT1(result); + return result; +} + + +/* FIXME: maybe merge it with usual eeprom reading, into common code? */ +static void +acxusb_s_read_eeprom_version(acx_device_t *adev) +{ + u8 eeprom_ver[0x8]; + + memset(eeprom_ver, 0, sizeof(eeprom_ver)); + acx_s_interrogate(adev, &eeprom_ver, ACX1FF_IE_EEPROM_VER); + + /* FIXME: which one of those values to take? */ + adev->eeprom_version = eeprom_ver[5]; +} + + +/* + * temporary helper function to at least fill important cfgopt members with + * useful replacement values until we figure out how one manages to fetch + * the configoption struct in the USB device case... + */ +static int +acxusb_s_fill_configoption(acx_device_t *adev) +{ + adev->cfgopt_probe_delay = 200; + adev->cfgopt_dot11CCAModes = 4; + adev->cfgopt_dot11Diversity = 1; + adev->cfgopt_dot11ShortPreambleOption = 1; + adev->cfgopt_dot11PBCCOption = 1; + adev->cfgopt_dot11ChannelAgility = 0; + adev->cfgopt_dot11PhyType = 5; + adev->cfgopt_dot11TempType = 1; + return OK; +} + + +/*********************************************************************** +** acxusb_e_probe() +** +** This function is invoked by the kernel's USB core whenever a new device is +** attached to the system or the module is loaded. It is presented a usb_device +** structure from which information regarding the device is obtained and evaluated. +** In case this driver is able to handle one of the offered devices, it returns +** a non-null pointer to a driver context and thereby claims the device. +*/ + +static void +dummy_netdev_init(struct net_device *ndev) {} + +static int +acxusb_e_probe(struct usb_interface *intf, const struct usb_device_id *devID) +{ + struct usb_device *usbdev = interface_to_usbdev(intf); + acx_device_t *adev = NULL; + struct net_device *ndev = NULL; + struct usb_config_descriptor *config; + struct usb_endpoint_descriptor *epdesc; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + struct usb_host_endpoint *ep; +#endif + struct usb_interface_descriptor *ifdesc; + const char* msg; + int numconfigs, numfaces, numep; + int result = OK; + int i; + + FN_ENTER; + + /* First check if this is the "unbooted" hardware */ + if ((usbdev->descriptor.idVendor == ACX100_VENDOR_ID) + && (usbdev->descriptor.idProduct == ACX100_PRODUCT_ID_UNBOOTED)) { + /* Boot the device (i.e. upload the firmware) */ + acxusb_boot(usbdev); + + /* OK, we are done with booting. Normally, the + ** ID for the unbooted device should disappear + ** and it will not need a driver anyway...so + ** return a NULL + */ + log(L_INIT, "finished booting, returning from probe()\n"); + result = OK; /* success */ + goto end; + } + + if ((usbdev->descriptor.idVendor != ACX100_VENDOR_ID) + || (usbdev->descriptor.idProduct != ACX100_PRODUCT_ID_BOOTED)) { + goto end_nodev; + } + +/* Ok, so it's our device and it has already booted */ + + /* Allocate memory for a network device */ + + ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init); + /* (NB: memsets to 0 entire area) */ + if (!ndev) { + msg = "acx: no memory for netdev\n"; + goto end_nomem; + } + + /* Register the callbacks for the network device functions */ + + ether_setup(ndev); + ndev->open = &acxusb_e_open; + ndev->stop = &acxusb_e_close; + ndev->hard_start_xmit = (void *)&acx_i_start_xmit; + ndev->get_stats = (void *)&acx_e_get_stats; + ndev->set_multicast_list = (void *)&acxusb_i_set_rx_mode; +#ifdef HAVE_TX_TIMEOUT + ndev->tx_timeout = &acxusb_i_tx_timeout; + ndev->watchdog_timeo = 4 * HZ; +#endif + ndev->change_mtu = &acx_e_change_mtu; + + /* Setup private driver context */ + + adev = netdev_priv(ndev); + adev->ndev = ndev; + + adev->dev_type = DEVTYPE_USB; + adev->chip_type = CHIPTYPE_ACX100; + + /* FIXME: should be read from register (via firmware) using standard ACX code */ + adev->radio_type = RADIO_MAXIM_0D; + + adev->usbdev = usbdev; + spin_lock_init(&adev->lock); /* initial state: unlocked */ + sema_init(&adev->sem, 1); /* initial state: 1 (upped) */ + + /* Check that this is really the hardware we know about. + ** If not sure, at least notify the user that he + ** may be in trouble... + */ + numconfigs = (int)usbdev->descriptor.bNumConfigurations; + if (numconfigs != 1) + printk("acx: number of configurations is %d, " + "this driver only knows how to handle 1, " + "be prepared for surprises\n", numconfigs); + + config = &usbdev->config->desc; + numfaces = config->bNumInterfaces; + if (numfaces != 1) + printk("acx: number of interfaces is %d, " + "this driver only knows how to handle 1, " + "be prepared for surprises\n", numfaces); + + ifdesc = &intf->altsetting->desc; + numep = ifdesc->bNumEndpoints; + log(L_DEBUG, "# of endpoints: %d\n", numep); + + /* obtain information about the endpoint + ** addresses, begin with some default values + */ + adev->bulkoutep = 1; + adev->bulkinep = 1; + for (i = 0; i < numep; i++) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + ep = usbdev->ep_in[i]; + if (!ep) + continue; + epdesc = &ep->desc; +#else + epdesc = usb_epnum_to_ep_desc(usbdev, i); + if (!epdesc) + continue; +#endif + if (epdesc->bmAttributes & USB_ENDPOINT_XFER_BULK) { + if (epdesc->bEndpointAddress & 0x80) + adev->bulkinep = epdesc->bEndpointAddress & 0xF; + else + adev->bulkoutep = epdesc->bEndpointAddress & 0xF; + } + } + log(L_DEBUG, "bulkout ep: 0x%X\n", adev->bulkoutep); + log(L_DEBUG, "bulkin ep: 0x%X\n", adev->bulkinep); + + /* already done by memset: adev->rxtruncsize = 0; */ + log(L_DEBUG, "TXBUFSIZE=%d RXBUFSIZE=%d\n", + (int) TXBUFSIZE, (int) RXBUFSIZE); + + /* Allocate the RX/TX containers. */ + adev->usb_tx = kmalloc(sizeof(usb_tx_t) * ACX_TX_URB_CNT, GFP_KERNEL); + if (!adev->usb_tx) { + msg = "acx: no memory for tx container"; + goto end_nomem; + } + adev->usb_rx = kmalloc(sizeof(usb_rx_t) * ACX_RX_URB_CNT, GFP_KERNEL); + if (!adev->usb_rx) { + msg = "acx: no memory for rx container"; + goto end_nomem; + } + + /* Setup URBs for bulk-in/out messages */ + for (i = 0; i < ACX_RX_URB_CNT; i++) { + adev->usb_rx[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!adev->usb_rx[i].urb) { + msg = "acx: no memory for input URB\n"; + goto end_nomem; + } + adev->usb_rx[i].urb->status = 0; + adev->usb_rx[i].adev = adev; + adev->usb_rx[i].busy = 0; + } + + for (i = 0; i< ACX_TX_URB_CNT; i++) { + adev->usb_tx[i].urb = usb_alloc_urb(0, GFP_KERNEL); + if (!adev->usb_tx[i].urb) { + msg = "acx: no memory for output URB\n"; + goto end_nomem; + } + adev->usb_tx[i].urb->status = 0; + adev->usb_tx[i].adev = adev; + adev->usb_tx[i].busy = 0; + } + adev->tx_free = ACX_TX_URB_CNT; + + usb_set_intfdata(intf, adev); + SET_NETDEV_DEV(ndev, &intf->dev); + + /* TODO: move all of fw cmds to open()? But then we won't know our MAC addr + until ifup (it's available via reading ACX1xx_IE_DOT11_STATION_ID)... */ + + /* put acx out of sleep mode and initialize it */ + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); + + result = acx_s_init_mac(adev); + if (result) + goto end; + + /* TODO: see similar code in pci.c */ + acxusb_s_read_eeprom_version(adev); + acxusb_s_fill_configoption(adev); + acx_s_set_defaults(adev); + acx_s_get_firmware_version(adev); + acx_display_hardware_details(adev); + + /* Register the network device */ + log(L_INIT, "registering network device\n"); + result = register_netdev(ndev); + if (result) { + msg = "acx: failed to register USB network device " + "(error %d)\n"; + goto end_nomem; + } + + acx_proc_register_entries(ndev); + + acx_stop_queue(ndev, "on probe"); + acx_carrier_off(ndev, "on probe"); + + printk("acx: USB module " ACX_RELEASE " loaded successfully\n"); + +#if CMD_DISCOVERY + great_inquisitor(adev); +#endif + + /* Everything went OK, we are happy now */ + result = OK; + goto end; + +end_nomem: + printk(msg, result); + + if (ndev) { + if (adev->usb_rx) { + for (i = 0; i < ACX_RX_URB_CNT; i++) + usb_free_urb(adev->usb_rx[i].urb); + kfree(adev->usb_rx); + } + if (adev->usb_tx) { + for (i = 0; i < ACX_TX_URB_CNT; i++) + usb_free_urb(adev->usb_tx[i].urb); + kfree(adev->usb_tx); + } + free_netdev(ndev); + } + + result = -ENOMEM; + goto end; + +end_nodev: + /* no device we could handle, return error. */ + result = -EIO; + +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxusb_e_disconnect() +** +** This function is invoked whenever the user pulls the plug from the USB +** device or the module is removed from the kernel. In these cases, the +** network devices have to be taken down and all allocated memory has +** to be freed. +*/ +static void +acxusb_e_disconnect(struct usb_interface *intf) +{ + acx_device_t *adev = usb_get_intfdata(intf); + unsigned long flags; + int i; + + FN_ENTER; + + /* No WLAN device... no sense */ + if (!adev) + goto end; + + /* Unregister network device + * + * If the interface is up, unregister_netdev() will take + * care of calling our close() function, which takes + * care of unlinking the urbs, sending the device to + * sleep, etc... + * This can't be called with sem or lock held because + * _close() will try to grab it as well if it's called, + * deadlocking the machine. + */ + unregister_netdev(adev->ndev); + + acx_sem_lock(adev); + acx_lock(adev, flags); + /* This device exists no more */ + usb_set_intfdata(intf, NULL); + acx_proc_unregister_entries(adev->ndev); + + /* + * Here we only free them. _close() took care of + * unlinking them. + */ + for (i = 0; i < ACX_RX_URB_CNT; ++i) { + usb_free_urb(adev->usb_rx[i].urb); + } + for (i = 0; i< ACX_TX_URB_CNT; ++i) { + usb_free_urb(adev->usb_tx[i].urb); + } + + /* Freeing containers */ + kfree(adev->usb_rx); + kfree(adev->usb_tx); + + acx_unlock(adev, flags); + acx_sem_unlock(adev); + + free_netdev(adev->ndev); +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acxusb_e_open() +** This function is called when the user sets up the network interface. +** It initializes a management timer, sets up the USB card and starts +** the network tx queue and USB receive. +*/ +static int +acxusb_e_open(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int i; + + FN_ENTER; + + acx_sem_lock(adev); + + /* put the ACX100 out of sleep mode */ + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); + + acx_init_task_scheduler(adev); + + init_timer(&adev->mgmt_timer); + adev->mgmt_timer.function = acx_i_timer; + adev->mgmt_timer.data = (unsigned long)adev; + + /* acx_s_start needs it */ + SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + acx_s_start(adev); + + /* don't acx_start_queue() here, we need to associate first */ + + acx_lock(adev, flags); + for (i = 0; i < ACX_RX_URB_CNT; i++) { + adev->usb_rx[i].urb->status = 0; + } + + acxusb_l_poll_rx(adev, &adev->usb_rx[0]); + + acx_unlock(adev, flags); + + acx_sem_unlock(adev); + + FN_EXIT0; + return 0; +} + + +/*********************************************************************** +** acxusb_e_close() +** +** This function stops the network functionality of the interface (invoked +** when the user calls ifconfig down). The tx queue is halted and +** the device is marked as down. In case there were any pending USB bulk +** transfers, these are unlinked (asynchronously). The module in-use count +** is also decreased in this function. +*/ +static int +acxusb_e_close(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int i; + + FN_ENTER; + +#ifdef WE_STILL_DONT_CARE_ABOUT_IT + /* Transmit a disassociate frame */ + lock + acx_l_transmit_disassoc(adev, &client); + unlock +#endif + + acx_sem_lock(adev); + + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + +/* Code below is remarkably similar to acxpci_s_down(). Maybe we can merge them? */ + + /* Make sure we don't get any more rx requests */ + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); + + /* + * We must do FLUSH *without* holding sem to avoid a deadlock. + * See pci.c:acxpci_s_down() for deails. + */ + acx_sem_unlock(adev); + FLUSH_SCHEDULED_WORK(); + acx_sem_lock(adev); + + /* Power down the device */ + acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0); + + /* Stop the transmit queue, mark the device as DOWN */ + acx_lock(adev, flags); + acx_stop_queue(ndev, "on ifdown"); + acx_set_status(adev, ACX_STATUS_0_STOPPED); + /* stop pending rx/tx urb transfers */ + for (i = 0; i < ACX_TX_URB_CNT; i++) { + acxusb_unlink_urb(adev->usb_tx[i].urb); + adev->usb_tx[i].busy = 0; + } + for (i = 0; i < ACX_RX_URB_CNT; i++) { + acxusb_unlink_urb(adev->usb_rx[i].urb); + adev->usb_rx[i].busy = 0; + } + adev->tx_free = ACX_TX_URB_CNT; + acx_unlock(adev, flags); + + /* Must do this outside of lock */ + del_timer_sync(&adev->mgmt_timer); + + acx_sem_unlock(adev); + + FN_EXIT0; + return 0; +} + + +/*********************************************************************** +** acxusb_l_poll_rx +** This function (re)initiates a bulk-in USB transfer on a given urb +*/ +static void +acxusb_l_poll_rx(acx_device_t *adev, usb_rx_t* rx) +{ + struct usb_device *usbdev; + struct urb *rxurb; + int errcode, rxnum; + unsigned int inpipe; + + FN_ENTER; + + rxurb = rx->urb; + usbdev = adev->usbdev; + + rxnum = rx - adev->usb_rx; + + inpipe = usb_rcvbulkpipe(usbdev, adev->bulkinep); + if (unlikely(rxurb->status == -EINPROGRESS)) { + printk(KERN_ERR "acx: error, rx triggered while rx urb in progress\n"); + /* FIXME: this is nasty, receive is being cancelled by this code + * on the other hand, this should not happen anyway... + */ + usb_unlink_urb(rxurb); + } else + if (unlikely(rxurb->status == -ECONNRESET)) { + log(L_USBRXTX, "acx_usb: _poll_rx: connection reset\n"); + goto end; + } + rxurb->actual_length = 0; + usb_fill_bulk_urb(rxurb, usbdev, inpipe, + &rx->bulkin, /* dataptr */ + RXBUFSIZE, /* size */ + acxusb_i_complete_rx, /* handler */ + rx /* handler param */ + ); + rxurb->transfer_flags = URB_ASYNC_UNLINK; + + /* ATOMIC: we may be called from complete_rx() usb callback */ + errcode = usb_submit_urb(rxurb, GFP_ATOMIC); + /* FIXME: evaluate the error code! */ + log(L_USBRXTX, "SUBMIT RX (%d) inpipe=0x%X size=%d errcode=%d\n", + rxnum, inpipe, (int) RXBUFSIZE, errcode); +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acxusb_i_complete_rx() +** Inputs: +** urb -> pointer to USB request block +** regs -> pointer to register-buffer for syscalls (see asm/ptrace.h) +** +** This function is invoked by USB subsystem whenever a bulk receive +** request returns. +** The received data is then committed to the network stack and the next +** USB receive is triggered. +*/ +static void +acxusb_i_complete_rx(struct urb *urb) +{ + acx_device_t *adev; + rxbuffer_t *ptr; + rxbuffer_t *inbuf; + usb_rx_t *rx; + unsigned long flags; + int size, remsize, packetsize, rxnum; + + FN_ENTER; + + BUG_ON(!urb->context); + + rx = (usb_rx_t *)urb->context; + adev = rx->adev; + + acx_lock(adev, flags); + + /* + * Happens on disconnect or close. Don't play with the urb. + * Don't resubmit it. It will get unlinked by close() + */ + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { + log(L_USBRXTX, "rx: device is down, not doing anything\n"); + goto end_unlock; + } + + inbuf = &rx->bulkin; + size = urb->actual_length; + remsize = size; + rxnum = rx - adev->usb_rx; + + log(L_USBRXTX, "RETURN RX (%d) status=%d size=%d\n", + rxnum, urb->status, size); + + /* Send the URB that's waiting. */ + log(L_USBRXTX, "rxnum=%d, sending=%d\n", rxnum, rxnum^1); + acxusb_l_poll_rx(adev, &adev->usb_rx[rxnum^1]); + + if (unlikely(size > sizeof(rxbuffer_t))) + printk("acx_usb: rx too large: %d, please report\n", size); + + /* check if the transfer was aborted */ + switch (urb->status) { + case 0: /* No error */ + break; + case -EOVERFLOW: + printk(KERN_ERR "acx: rx data overrun\n"); + adev->rxtruncsize = 0; /* Not valid anymore. */ + goto end_unlock; + case -ECONNRESET: + adev->rxtruncsize = 0; + goto end_unlock; + case -ESHUTDOWN: /* rmmod */ + adev->rxtruncsize = 0; + goto end_unlock; + default: + adev->rxtruncsize = 0; + adev->stats.rx_errors++; + printk("acx: rx error (urb status=%d)\n", urb->status); + goto end_unlock; + } + + if (unlikely(!size)) + printk("acx: warning, encountered zerolength rx packet\n"); + + if (urb->transfer_buffer != inbuf) + goto end_unlock; + + /* check if previous frame was truncated + ** FIXME: this code can only handle truncation + ** of consecutive packets! + */ + ptr = inbuf; + if (adev->rxtruncsize) { + int tail_size; + + ptr = &adev->rxtruncbuf; + packetsize = RXBUF_BYTES_USED(ptr); + if (acx_debug & L_USBRXTX) { + printk("handling truncated frame (truncsize=%d size=%d " + "packetsize(from trunc)=%d)\n", + adev->rxtruncsize, size, packetsize); + acx_dump_bytes(ptr, RXBUF_HDRSIZE); + acx_dump_bytes(inbuf, RXBUF_HDRSIZE); + } + + /* bytes needed for rxtruncbuf completion: */ + tail_size = packetsize - adev->rxtruncsize; + + if (size < tail_size) { + /* there is not enough data to complete this packet, + ** simply append the stuff to the truncation buffer + */ + memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, size); + adev->rxtruncsize += size; + remsize = 0; + } else { + /* ok, this data completes the previously + ** truncated packet. copy it into a descriptor + ** and give it to the rest of the stack */ + + /* append tail to previously truncated part + ** NB: adev->rxtruncbuf (pointed to by ptr) can't + ** overflow because this is already checked before + ** truncation buffer was filled. See below, + ** "if (packetsize > sizeof(rxbuffer_t))..." code */ + memcpy(((char *)ptr) + adev->rxtruncsize, inbuf, tail_size); + + if (acx_debug & L_USBRXTX) { + printk("full trailing packet + 12 bytes:\n"); + acx_dump_bytes(inbuf, tail_size + RXBUF_HDRSIZE); + } + acx_l_process_rxbuf(adev, ptr); + adev->rxtruncsize = 0; + ptr = (rxbuffer_t *) (((char *)inbuf) + tail_size); + remsize -= tail_size; + } + log(L_USBRXTX, "post-merge size=%d remsize=%d\n", + size, remsize); + } + + /* size = USB data block size + ** remsize = unprocessed USB bytes left + ** ptr = current pos in USB data block + */ + while (remsize) { + if (remsize < RXBUF_HDRSIZE) { + printk("acx: truncated rx header (%d bytes)!\n", + remsize); + if (ACX_DEBUG) + acx_dump_bytes(ptr, remsize); + break; + } + + packetsize = RXBUF_BYTES_USED(ptr); + log(L_USBRXTX, "packet with packetsize=%d\n", packetsize); + + if (RXBUF_IS_TXSTAT(ptr)) { + /* do rate handling */ + usb_txstatus_t *stat = (void*)ptr; + u16 client_no = (u16)stat->hostdata; + + log(L_USBRXTX, "tx: stat: mac_cnt_rcvd:%04X " + "queue_index:%02X mac_status:%02X hostdata:%08X " + "rate:%u ack_failures:%02X rts_failures:%02X " + "rts_ok:%02X\n", + stat->mac_cnt_rcvd, + stat->queue_index, stat->mac_status, stat->hostdata, + stat->rate, stat->ack_failures, stat->rts_failures, + stat->rts_ok); + + if (adev->rate_auto && client_no < VEC_SIZE(adev->sta_list)) { + client_t *clt = &adev->sta_list[client_no]; + u16 cur = stat->hostdata >> 16; + + if (clt && clt->rate_cur == cur) { + acx_l_handle_txrate_auto(adev, clt, + cur, /* intended rate */ + stat->rate, 0, /* actually used rate */ + stat->mac_status, /* error? */ + ACX_TX_URB_CNT - adev->tx_free); + } + } + goto next; + } + + if (packetsize > sizeof(rxbuffer_t)) { + printk("acx: packet exceeds max wlan " + "frame size (%d > %d). size=%d\n", + packetsize, (int) sizeof(rxbuffer_t), size); + if (ACX_DEBUG) + acx_dump_bytes(ptr, 16); + /* FIXME: put some real error-handling in here! */ + break; + } + + if (packetsize > remsize) { + /* frame truncation handling */ + if (acx_debug & L_USBRXTX) { + printk("need to truncate packet, " + "packetsize=%d remsize=%d " + "size=%d bytes:", + packetsize, remsize, size); + acx_dump_bytes(ptr, RXBUF_HDRSIZE); + } + memcpy(&adev->rxtruncbuf, ptr, remsize); + adev->rxtruncsize = remsize; + break; + } + + /* packetsize <= remsize */ + /* now handle the received data */ + acx_l_process_rxbuf(adev, ptr); +next: + ptr = (rxbuffer_t *)(((char *)ptr) + packetsize); + remsize -= packetsize; + if ((acx_debug & L_USBRXTX) && remsize) { + printk("more than one packet in buffer, " + "second packet hdr:"); + acx_dump_bytes(ptr, RXBUF_HDRSIZE); + } + } + +end_unlock: + acx_unlock(adev, flags); +/* end: */ + FN_EXIT0; +} + + +/*********************************************************************** +** acxusb_i_complete_tx() +** Inputs: +** urb -> pointer to USB request block +** regs -> pointer to register-buffer for syscalls (see asm/ptrace.h) +** +** This function is invoked upon termination of a USB transfer. +*/ +static void +acxusb_i_complete_tx(struct urb *urb) +{ + acx_device_t *adev; + usb_tx_t *tx; + unsigned long flags; + int txnum; + + FN_ENTER; + + BUG_ON(!urb->context); + + tx = (usb_tx_t *)urb->context; + adev = tx->adev; + + txnum = tx - adev->usb_tx; + + acx_lock(adev, flags); + + /* + * If the iface isn't up, we don't have any right + * to play with them. The urb may get unlinked. + */ + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { + log(L_USBRXTX, "tx: device is down, not doing anything\n"); + goto end_unlock; + } + + log(L_USBRXTX, "RETURN TX (%d): status=%d size=%d\n", + txnum, urb->status, urb->actual_length); + + /* handle USB transfer errors */ + switch (urb->status) { + case 0: /* No error */ + break; + case -ESHUTDOWN: + goto end_unlock; + break; + case -ECONNRESET: + goto end_unlock; + break; + /* FIXME: real error-handling code here please */ + default: + printk(KERN_ERR "acx: tx error, urb status=%d\n", urb->status); + /* FIXME: real error-handling code here please */ + } + + /* free the URB and check for more data */ + tx->busy = 0; + adev->tx_free++; + if ((adev->tx_free >= TX_START_QUEUE) + && (adev->status == ACX_STATUS_4_ASSOCIATED) + && (acx_queue_stopped(adev->ndev)) + ) { + log(L_BUF, "tx: wake queue (%u free txbufs)\n", + adev->tx_free); + acx_wake_queue(adev->ndev, NULL); + } + +end_unlock: + acx_unlock(adev, flags); +/* end: */ + FN_EXIT0; +} + + +/*************************************************************** +** acxusb_l_alloc_tx +** Actually returns a usb_tx_t* ptr +*/ +tx_t* +acxusb_l_alloc_tx(acx_device_t *adev) +{ + usb_tx_t *tx; + unsigned head; + + FN_ENTER; + + head = adev->tx_head; + do { + head = (head + 1) % ACX_TX_URB_CNT; + if (!adev->usb_tx[head].busy) { + log(L_USBRXTX, "allocated tx %d\n", head); + tx = &adev->usb_tx[head]; + tx->busy = 1; + adev->tx_free--; + /* Keep a few free descs between head and tail of tx ring. + ** It is not absolutely needed, just feels safer */ + if (adev->tx_free < TX_STOP_QUEUE) { + log(L_BUF, "tx: stop queue " + "(%u free txbufs)\n", adev->tx_free); + acx_stop_queue(adev->ndev, NULL); + } + goto end; + } + } while (likely(head!=adev->tx_head)); + tx = NULL; + printk_ratelimited("acx: tx buffers full\n"); +end: + adev->tx_head = head; + FN_EXIT0; + return (tx_t*)tx; +} + + +/*************************************************************** +** Used if alloc_tx()'ed buffer needs to be cancelled without doing tx +*/ +void +acxusb_l_dealloc_tx(tx_t *tx_opaque) +{ + usb_tx_t* tx = (usb_tx_t*)tx_opaque; + tx->busy = 0; +} + + +/*************************************************************** +*/ +void* +acxusb_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque) +{ + usb_tx_t* tx = (usb_tx_t*)tx_opaque; + return &tx->bulkout.data; +} + + +/*************************************************************** +** acxusb_l_tx_data +** +** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx). +** Can be called from acx_i_start_xmit (data frames from net core). +*/ +void +acxusb_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int wlanpkt_len) +{ + struct usb_device *usbdev; + struct urb* txurb; + usb_tx_t* tx; + usb_txbuffer_t* txbuf; + client_t *clt; + wlan_hdr_t* whdr; + unsigned int outpipe; + int ucode, txnum; + + FN_ENTER; + + tx = ((usb_tx_t *)tx_opaque); + txurb = tx->urb; + txbuf = &tx->bulkout; + whdr = (wlan_hdr_t *)txbuf->data; + txnum = tx - adev->usb_tx; + + log(L_DEBUG, "using buf#%d free=%d len=%d\n", + txnum, adev->tx_free, wlanpkt_len); + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + clt = acx_l_sta_list_get(adev, whdr->a1); + break; + case ACX_MODE_2_STA: + clt = adev->ap_client; + break; + default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */ + clt = NULL; + break; + } + + if (unlikely(clt && !clt->rate_cur)) { + printk("acx: driver bug! bad ratemask\n"); + goto end; + } + + /* fill the USB transfer header */ + txbuf->desc = cpu_to_le16(USB_TXBUF_TXDESC); + txbuf->mpdu_len = cpu_to_le16(wlanpkt_len); + txbuf->queue_index = 1; + if (clt) { + txbuf->rate = clt->rate_100; + txbuf->hostdata = (clt - adev->sta_list) | (clt->rate_cur << 16); + } else { + txbuf->rate = adev->rate_bcast100; + txbuf->hostdata = ((u16)-1) | (adev->rate_bcast << 16); + } + txbuf->ctrl1 = DESC_CTL_FIRSTFRAG; + if (1 == adev->preamble_cur) + SET_BIT(txbuf->ctrl1, DESC_CTL_SHORT_PREAMBLE); + txbuf->ctrl2 = 0; + txbuf->data_len = cpu_to_le16(wlanpkt_len); + + if (unlikely(acx_debug & L_DATA)) { + printk("dump of bulk out urb:\n"); + acx_dump_bytes(txbuf, wlanpkt_len + USB_TXBUF_HDRSIZE); + } + + if (unlikely(txurb->status == -EINPROGRESS)) { + printk("acx: trying to submit tx urb while already in progress\n"); + } + + /* now schedule the USB transfer */ + usbdev = adev->usbdev; + outpipe = usb_sndbulkpipe(usbdev, adev->bulkoutep); + + usb_fill_bulk_urb(txurb, usbdev, outpipe, + txbuf, /* dataptr */ + wlanpkt_len + USB_TXBUF_HDRSIZE, /* size */ + acxusb_i_complete_tx, /* handler */ + tx /* handler param */ + ); + + txurb->transfer_flags = URB_ASYNC_UNLINK|URB_ZERO_PACKET; + ucode = usb_submit_urb(txurb, GFP_ATOMIC); + log(L_USBRXTX, "SUBMIT TX (%d): outpipe=0x%X buf=%p txsize=%d " + "rate=%u errcode=%d\n", txnum, outpipe, txbuf, + wlanpkt_len + USB_TXBUF_HDRSIZE, txbuf->rate, ucode); + + if (unlikely(ucode)) { + printk(KERN_ERR "acx: submit_urb() error=%d txsize=%d\n", + ucode, wlanpkt_len + USB_TXBUF_HDRSIZE); + + /* on error, just mark the frame as done and update + ** the statistics + */ + adev->stats.tx_errors++; + tx->busy = 0; + adev->tx_free++; + /* needed? if (adev->tx_free > TX_START_QUEUE) acx_wake_queue(...) */ + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +*/ +static void +acxusb_i_set_rx_mode(struct net_device *ndev) +{ +} + + +/*********************************************************************** +*/ +#ifdef HAVE_TX_TIMEOUT +static void +acxusb_i_tx_timeout(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int i; + + FN_ENTER; + + acx_lock(adev, flags); + /* unlink the URBs */ + for (i = 0; i < ACX_TX_URB_CNT; i++) { + acxusb_unlink_urb(adev->usb_tx[i].urb); + adev->usb_tx[i].busy = 0; + } + adev->tx_free = ACX_TX_URB_CNT; + /* TODO: stats update */ + acx_unlock(adev, flags); + + FN_EXIT0; +} +#endif + + +/*********************************************************************** +** init_module() +** +** This function is invoked upon loading of the kernel module. +** It registers itself at the kernel's USB subsystem. +** +** Returns: Errorcode on failure, 0 on success +*/ +int __init +acxusb_e_init_module(void) +{ + log(L_INIT, "USB module " ACX_RELEASE " initialized, " + "probing for devices...\n"); + return usb_register(&acxusb_driver); +} + + + +/*********************************************************************** +** cleanup_module() +** +** This function is invoked as last step of the module unloading. It simply +** deregisters this module at the kernel's USB subsystem. +*/ +void __exit +acxusb_e_cleanup_module() +{ + usb_deregister(&acxusb_driver); +} + + +/*********************************************************************** +** DEBUG STUFF +*/ +#if ACX_DEBUG + +#ifdef UNUSED +static void +dump_device(struct usb_device *usbdev) +{ + int i; + struct usb_config_descriptor *cd; + + printk("acx device dump:\n"); + printk(" devnum: %d\n", usbdev->devnum); + printk(" speed: %d\n", usbdev->speed); + printk(" tt: 0x%X\n", (unsigned int)(usbdev->tt)); + printk(" ttport: %d\n", (unsigned int)(usbdev->ttport)); + printk(" toggle[0]: 0x%X toggle[1]: 0x%X\n", (unsigned int)(usbdev->toggle[0]), (unsigned int)(usbdev->toggle[1])); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) + /* This saw a change after 2.6.10 */ + printk(" ep_in wMaxPacketSize: "); + for (i = 0; i < 16; ++i) + if (usbdev->ep_in[i] != NULL) + printk("%d:%d ", i, usbdev->ep_in[i]->desc.wMaxPacketSize); + printk("\n"); + printk(" ep_out wMaxPacketSize: "); + for (i = 0; i < VEC_SIZE(usbdev->ep_out); ++i) + if (usbdev->ep_out[i] != NULL) + printk("%d:%d ", i, usbdev->ep_out[i]->desc.wMaxPacketSize); + printk("\n"); +#else + printk(" epmaxpacketin: "); + for (i = 0; i < 16; i++) + printk("%d ", usbdev->epmaxpacketin[i]); + printk("\n"); + printk(" epmaxpacketout: "); + for (i = 0; i < 16; i++) + printk("%d ", usbdev->epmaxpacketout[i]); + printk("\n"); +#endif + printk(" parent: 0x%X\n", (unsigned int)usbdev->parent); + printk(" bus: 0x%X\n", (unsigned int)usbdev->bus); +#ifdef NO_DATATYPE + printk(" configs: "); + for (i = 0; i < usbdev->descriptor.bNumConfigurations; i++) + printk("0x%X ", usbdev->config[i]); + printk("\n"); +#endif + printk(" actconfig: %p\n", usbdev->actconfig); + dump_device_descriptor(&usbdev->descriptor); + + cd = &usbdev->config->desc; + dump_config_descriptor(cd); +} + + +/*********************************************************************** +*/ +static void +dump_config_descriptor(struct usb_config_descriptor *cd) +{ + printk("Configuration Descriptor:\n"); + if (!cd) { + printk("NULL\n"); + return; + } + printk(" bLength: %d (0x%X)\n", cd->bLength, cd->bLength); + printk(" bDescriptorType: %d (0x%X)\n", cd->bDescriptorType, cd->bDescriptorType); + printk(" bNumInterfaces: %d (0x%X)\n", cd->bNumInterfaces, cd->bNumInterfaces); + printk(" bConfigurationValue: %d (0x%X)\n", cd->bConfigurationValue, cd->bConfigurationValue); + printk(" iConfiguration: %d (0x%X)\n", cd->iConfiguration, cd->iConfiguration); + printk(" bmAttributes: %d (0x%X)\n", cd->bmAttributes, cd->bmAttributes); + /* printk(" MaxPower: %d (0x%X)\n", cd->bMaxPower, cd->bMaxPower); */ +} + + +static void +dump_device_descriptor(struct usb_device_descriptor *dd) +{ + printk("Device Descriptor:\n"); + if (!dd) { + printk("NULL\n"); + return; + } + printk(" bLength: %d (0x%X)\n", dd->bLength, dd->bLength); + printk(" bDescriptortype: %d (0x%X)\n", dd->bDescriptorType, dd->bDescriptorType); + printk(" bcdUSB: %d (0x%X)\n", dd->bcdUSB, dd->bcdUSB); + printk(" bDeviceClass: %d (0x%X)\n", dd->bDeviceClass, dd->bDeviceClass); + printk(" bDeviceSubClass: %d (0x%X)\n", dd->bDeviceSubClass, dd->bDeviceSubClass); + printk(" bDeviceProtocol: %d (0x%X)\n", dd->bDeviceProtocol, dd->bDeviceProtocol); + printk(" bMaxPacketSize0: %d (0x%X)\n", dd->bMaxPacketSize0, dd->bMaxPacketSize0); + printk(" idVendor: %d (0x%X)\n", dd->idVendor, dd->idVendor); + printk(" idProduct: %d (0x%X)\n", dd->idProduct, dd->idProduct); + printk(" bcdDevice: %d (0x%X)\n", dd->bcdDevice, dd->bcdDevice); + printk(" iManufacturer: %d (0x%X)\n", dd->iManufacturer, dd->iManufacturer); + printk(" iProduct: %d (0x%X)\n", dd->iProduct, dd->iProduct); + printk(" iSerialNumber: %d (0x%X)\n", dd->iSerialNumber, dd->iSerialNumber); + printk(" bNumConfigurations: %d (0x%X)\n", dd->bNumConfigurations, dd->bNumConfigurations); +} +#endif /* UNUSED */ + +#endif /* ACX_DEBUG */ --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/pci.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/pci.c @@ -0,0 +1,4260 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ +#define ACX_PCI 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +#define PCI_TYPE (PCI_USES_MEM | PCI_ADDR0 | PCI_NO_ACPI_WAKE) +#define PCI_ACX100_REGION1 0x01 +#define PCI_ACX100_REGION1_SIZE 0x1000 /* Memory size - 4K bytes */ +#define PCI_ACX100_REGION2 0x02 +#define PCI_ACX100_REGION2_SIZE 0x10000 /* Memory size - 64K bytes */ + +#define PCI_ACX111_REGION1 0x00 +#define PCI_ACX111_REGION1_SIZE 0x2000 /* Memory size - 8K bytes */ +#define PCI_ACX111_REGION2 0x01 +#define PCI_ACX111_REGION2_SIZE 0x20000 /* Memory size - 128K bytes */ + +/* Texas Instruments Vendor ID */ +#define PCI_VENDOR_ID_TI 0x104c + +/* ACX100 22Mb/s WLAN controller */ +#define PCI_DEVICE_ID_TI_TNETW1100A 0x8400 +#define PCI_DEVICE_ID_TI_TNETW1100B 0x8401 + +/* ACX111 54Mb/s WLAN controller */ +#define PCI_DEVICE_ID_TI_TNETW1130 0x9066 + +/* PCI Class & Sub-Class code, Network-'Other controller' */ +#define PCI_CLASS_NETWORK_OTHERS 0x0280 + +#define CARD_EEPROM_ID_SIZE 6 + +#ifndef PCI_D0 +/* From include/linux/pci.h */ +#define PCI_D0 0 +#define PCI_D1 1 +#define PCI_D2 2 +#define PCI_D3hot 3 +#define PCI_D3cold 4 +#define PCI_UNKNOWN 5 +#define PCI_POWER_ERROR -1 +#endif + + +/*********************************************************************** +*/ +static void acxpci_i_tx_timeout(struct net_device *ndev); +static irqreturn_t acxpci_i_interrupt(int irq, void *dev_id); +static void acxpci_i_set_multicast_list(struct net_device *ndev); + +static int acxpci_e_open(struct net_device *ndev); +static int acxpci_e_close(struct net_device *ndev); +static void acxpci_s_up(struct net_device *ndev); +static void acxpci_s_down(struct net_device *ndev); + + +/*********************************************************************** +** Register access +*/ + +/* Pick one */ +/* #define INLINE_IO static */ +#define INLINE_IO static inline + +INLINE_IO u32 +read_reg32(acx_device_t *adev, unsigned int offset) +{ +#if ACX_IO_WIDTH == 32 + return readl((u8 *)adev->iobase + adev->io[offset]); +#else + return readw((u8 *)adev->iobase + adev->io[offset]) + + (readw((u8 *)adev->iobase + adev->io[offset] + 2) << 16); +#endif +} + +INLINE_IO u16 +read_reg16(acx_device_t *adev, unsigned int offset) +{ + return readw((u8 *)adev->iobase + adev->io[offset]); +} + +INLINE_IO u8 +read_reg8(acx_device_t *adev, unsigned int offset) +{ + return readb((u8 *)adev->iobase + adev->io[offset]); +} + +INLINE_IO void +write_reg32(acx_device_t *adev, unsigned int offset, u32 val) +{ +#if ACX_IO_WIDTH == 32 + writel(val, (u8 *)adev->iobase + adev->io[offset]); +#else + writew(val & 0xffff, (u8 *)adev->iobase + adev->io[offset]); + writew(val >> 16, (u8 *)adev->iobase + adev->io[offset] + 2); +#endif +} + +INLINE_IO void +write_reg16(acx_device_t *adev, unsigned int offset, u16 val) +{ + writew(val, (u8 *)adev->iobase + adev->io[offset]); +} + +INLINE_IO void +write_reg8(acx_device_t *adev, unsigned int offset, u8 val) +{ + writeb(val, (u8 *)adev->iobase + adev->io[offset]); +} + +/* Handle PCI posting properly: + * Make sure that writes reach the adapter in case they require to be executed + * *before* the next write, by reading a random (and safely accessible) register. + * This call has to be made if there is no read following (which would flush the data + * to the adapter), yet the written data has to reach the adapter immediately. */ +INLINE_IO void +write_flush(acx_device_t *adev) +{ + /* readb(adev->iobase + adev->io[IO_ACX_INFO_MAILBOX_OFFS]); */ + /* faster version (accesses the first register, IO_ACX_SOFT_RESET, + * which should also be safe): */ + readb(adev->iobase); +} + +INLINE_IO int +adev_present(acx_device_t *adev) +{ + /* fast version (accesses the first register, IO_ACX_SOFT_RESET, + * which should be safe): */ + return readl(adev->iobase) != 0xffffffff; +} + + +/*********************************************************************** +*/ +static inline txdesc_t* +get_txdesc(acx_device_t *adev, int index) +{ + return (txdesc_t*) (((u8*)adev->txdesc_start) + index * adev->txdesc_size); +} + +static inline txdesc_t* +advance_txdesc(acx_device_t *adev, txdesc_t* txdesc, int inc) +{ + return (txdesc_t*) (((u8*)txdesc) + inc * adev->txdesc_size); +} + +static txhostdesc_t* +get_txhostdesc(acx_device_t *adev, txdesc_t* txdesc) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + return &adev->txhostdesc_start[index*2]; +} + +static inline client_t* +get_txc(acx_device_t *adev, txdesc_t* txdesc) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { + printk("bad txdesc ptr %p\n", txdesc); + return NULL; + } + return adev->txc[index]; +} + +static inline u16 +get_txr(acx_device_t *adev, txdesc_t* txdesc) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + index /= adev->txdesc_size; + return adev->txr[index]; +} + +static inline void +put_txcr(acx_device_t *adev, txdesc_t* txdesc, client_t* c, u16 r111) +{ + int index = (u8*)txdesc - (u8*)adev->txdesc_start; + if (unlikely(ACX_DEBUG && (index % adev->txdesc_size))) { + printk("bad txdesc ptr %p\n", txdesc); + return; + } + index /= adev->txdesc_size; + if (unlikely(ACX_DEBUG && (index >= TX_CNT))) { + printk("bad txdesc ptr %p\n", txdesc); + return; + } + adev->txc[index] = c; + adev->txr[index] = r111; +} + + +/*********************************************************************** +** EEPROM and PHY read/write helpers +*/ +/*********************************************************************** +** acxpci_read_eeprom_byte +** +** Function called to read an octet in the EEPROM. +** +** This function is used by acxpci_e_probe to check if the +** connected card is a legal one or not. +** +** Arguments: +** adev ptr to acx_device structure +** addr address to read in the EEPROM +** charbuf ptr to a char. This is where the read octet +** will be stored +*/ +int +acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf) +{ + int result; + int count; + + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 2); + + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { + /* scheduling away instead of CPU burning loop + * doesn't seem to work here at all: + * awful delay, sometimes also failure. + * Doesn't matter anyway (only small delay). */ + if (unlikely(!--count)) { + printk("%s: timeout waiting for EEPROM read\n", + adev->ndev->name); + result = NOT_OK; + goto fail; + } + cpu_relax(); + } + + *charbuf = read_reg8(adev, IO_ACX_EEPROM_DATA); + log(L_DEBUG, "EEPROM at 0x%04X = 0x%02X\n", addr, *charbuf); + result = OK; + +fail: + return result; +} + + +/*********************************************************************** +** We don't lock hw accesses here since we never r/w eeprom in IRQ +** Note: this function sleeps only because of GFP_KERNEL alloc +*/ +#ifdef UNUSED +int +acxpci_s_write_eeprom(acx_device_t *adev, u32 addr, u32 len, const u8 *charbuf) +{ + u8 *data_verify = NULL; + unsigned long flags; + int count, i; + int result = NOT_OK; + u16 gpio_orig; + + printk("acx: WARNING! I would write to EEPROM now. " + "Since I really DON'T want to unless you know " + "what you're doing (THIS CODE WILL PROBABLY " + "NOT WORK YET!), I will abort that now. And " + "definitely make sure to make a " + "/proc/driver/acx_wlan0_eeprom backup copy first!!! " + "(the EEPROM content includes the PCI config header!! " + "If you kill important stuff, then you WILL " + "get in trouble and people DID get in trouble already)\n"); + return OK; + + FN_ENTER; + + data_verify = kmalloc(len, GFP_KERNEL); + if (!data_verify) { + goto end; + } + + /* first we need to enable the OE (EEPROM Output Enable) GPIO line + * to be able to write to the EEPROM. + * NOTE: an EEPROM writing success has been reported, + * but you probably have to modify GPIO_OUT, too, + * and you probably need to activate a different GPIO + * line instead! */ + gpio_orig = read_reg16(adev, IO_ACX_GPIO_OE); + write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig & ~1); + write_flush(adev); + + /* ok, now start writing the data out */ + for (i = 0; i < len; i++) { + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i); + write_reg32(adev, IO_ACX_EEPROM_DATA, *(charbuf + i)); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 1); + + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { + if (unlikely(!--count)) { + printk("WARNING, DANGER!!! " + "Timeout waiting for EEPROM write\n"); + goto end; + } + cpu_relax(); + } + } + + /* disable EEPROM writing */ + write_reg16(adev, IO_ACX_GPIO_OE, gpio_orig); + write_flush(adev); + + /* now start a verification run */ + for (i = 0; i < len; i++) { + write_reg32(adev, IO_ACX_EEPROM_CFG, 0); + write_reg32(adev, IO_ACX_EEPROM_ADDR, addr + i); + write_flush(adev); + write_reg32(adev, IO_ACX_EEPROM_CTL, 2); + + count = 0xffff; + while (read_reg16(adev, IO_ACX_EEPROM_CTL)) { + if (unlikely(!--count)) { + printk("timeout waiting for EEPROM read\n"); + goto end; + } + cpu_relax(); + } + + data_verify[i] = read_reg16(adev, IO_ACX_EEPROM_DATA); + } + + if (0 == memcmp(charbuf, data_verify, len)) + result = OK; /* read data matches, success */ + +end: + kfree(data_verify); + FN_EXIT1(result); + return result; +} +#endif /* UNUSED */ + + +/*********************************************************************** +** acxpci_s_read_phy_reg +** +** Messing with rx/tx disabling and enabling here +** (write_reg32(adev, IO_ACX_ENABLE, 0b000000xx)) kills traffic +*/ +int +acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) +{ + int result = NOT_OK; + int count; + + FN_ENTER; + + write_reg32(adev, IO_ACX_PHY_ADDR, reg); + write_flush(adev); + write_reg32(adev, IO_ACX_PHY_CTL, 2); + + count = 0xffff; + while (read_reg32(adev, IO_ACX_PHY_CTL)) { + /* scheduling away instead of CPU burning loop + * doesn't seem to work here at all: + * awful delay, sometimes also failure. + * Doesn't matter anyway (only small delay). */ + if (unlikely(!--count)) { + printk("%s: timeout waiting for phy read\n", + adev->ndev->name); + *charbuf = 0; + goto fail; + } + cpu_relax(); + } + + log(L_DEBUG, "count was %u\n", count); + *charbuf = read_reg8(adev, IO_ACX_PHY_DATA); + + log(L_DEBUG, "radio PHY at 0x%04X = 0x%02X\n", *charbuf, reg); + result = OK; + goto fail; /* silence compiler warning */ +fail: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +int +acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) +{ + FN_ENTER; + + /* mprusko said that 32bit accesses result in distorted sensitivity + * on his card. Unconfirmed, looks like it's not true (most likely since we + * now properly flush writes). */ + write_reg32(adev, IO_ACX_PHY_DATA, value); + write_reg32(adev, IO_ACX_PHY_ADDR, reg); + write_flush(adev); + write_reg32(adev, IO_ACX_PHY_CTL, 1); + write_flush(adev); + log(L_DEBUG, "radio PHY write 0x%02X at 0x%04X\n", value, reg); + + FN_EXIT1(OK); + return OK; +} + + +#define NO_AUTO_INCREMENT 1 + +/*********************************************************************** +** acxpci_s_write_fw +** +** Write the firmware image into the card. +** +** Arguments: +** adev wlan device structure +** fw_image firmware image. +** +** Returns: +** 1 firmware image corrupted +** 0 success +*/ +static int +acxpci_s_write_fw(acx_device_t *adev, const firmware_image_t *fw_image, u32 offset) +{ + int len, size; + u32 sum, v32; + /* we skip the first four bytes which contain the control sum */ + const u8 *p = (u8*)fw_image + 4; + + /* start the image checksum by adding the image size value */ + sum = p[0]+p[1]+p[2]+p[3]; + p += 4; + + write_reg32(adev, IO_ACX_SLV_END_CTL, 0); + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ +#else + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ + write_flush(adev); +#endif + + len = 0; + size = le32_to_cpu(fw_image->size) & (~3); + + while (likely(len < size)) { + v32 = be32_to_cpu(*(u32*)p); + sum += p[0]+p[1]+p[2]+p[3]; + p += 4; + len += 4; + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4); + write_flush(adev); +#endif + write_reg32(adev, IO_ACX_SLV_MEM_DATA, v32); + } + + log(L_DEBUG, "firmware written, size:%d sum1:%x sum2:%x\n", + size, sum, le32_to_cpu(fw_image->chksum)); + + /* compare our checksum with the stored image checksum */ + return (sum != le32_to_cpu(fw_image->chksum)); +} + + +/*********************************************************************** +** acxpci_s_validate_fw +** +** Compare the firmware image given with +** the firmware image written into the card. +** +** Arguments: +** adev wlan device structure +** fw_image firmware image. +** +** Returns: +** NOT_OK firmware image corrupted or not correctly written +** OK success +*/ +static int +acxpci_s_validate_fw(acx_device_t *adev, const firmware_image_t *fw_image, + u32 offset) +{ + u32 sum, v32, w32; + int len, size; + int result = OK; + /* we skip the first four bytes which contain the control sum */ + const u8 *p = (u8*)fw_image + 4; + + /* start the image checksum by adding the image size value */ + sum = p[0]+p[1]+p[2]+p[3]; + p += 4; + + write_reg32(adev, IO_ACX_SLV_END_CTL, 0); + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 0); /* use basic mode */ +#else + write_reg32(adev, IO_ACX_SLV_MEM_CTL, 1); /* use autoincrement mode */ + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset); /* configure start address */ +#endif + + len = 0; + size = le32_to_cpu(fw_image->size) & (~3); + + while (likely(len < size)) { + v32 = be32_to_cpu(*(u32*)p); + p += 4; + len += 4; + +#if NO_AUTO_INCREMENT + write_reg32(adev, IO_ACX_SLV_MEM_ADDR, offset + len - 4); +#endif + w32 = read_reg32(adev, IO_ACX_SLV_MEM_DATA); + + if (unlikely(w32 != v32)) { + printk("acx: FATAL: firmware upload: " + "data parts at offset %d don't match (0x%08X vs. 0x%08X)! " + "I/O timing issues or defective memory, with DWL-xx0+? " + "ACX_IO_WIDTH=16 may help. Please report\n", + len, v32, w32); + result = NOT_OK; + break; + } + + sum += (u8)w32 + (u8)(w32>>8) + (u8)(w32>>16) + (u8)(w32>>24); + } + + /* sum control verification */ + if (result != NOT_OK) { + if (sum != le32_to_cpu(fw_image->chksum)) { + printk("acx: FATAL: firmware upload: " + "checksums don't match!\n"); + result = NOT_OK; + } + } + + return result; +} + +struct fw_match { + unsigned short vendor; + unsigned short device; + unsigned short subvendor; + unsigned short subdevice; + const char *verstr; + int announced; +}; + +/* NOTE: This is NOT the module device table. We're just abusing the + * pci_device_id struct for our own purposes */ +static struct fw_match fw_ver_table[] = { + { /* Abocom WG24500, reported by Franz Pletz */ + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1130, + .subvendor = 0x13d1, + .subdevice = 0xab80, + .verstr = "1.2.0.30", + }, + { /* Texas Instruments ACX 111 54Mbps Wireless Interface */ + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1130, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .verstr = "1.2.1.34", + }, + { 0 } +}; + +#define PCI_MATCH(a,b) (a == b || a == (unsigned short)PCI_ANY_ID) + +/* Returns an alternate version of the firmware for specific devices. The + * above table will _always_ be overriden by module param. */ +static const char *get_firmware_ver(struct pci_dev *dev) +{ + struct fw_match *dev_match; + + if (!dev || strcmp(firmware_ver, "default")) + goto use_default; + + for (dev_match = fw_ver_table; dev_match->vendor; dev_match++) { + if (PCI_MATCH(dev_match->vendor, dev->vendor) && + PCI_MATCH(dev_match->device, dev->device) && + PCI_MATCH(dev_match->subvendor, dev->subsystem_vendor) && + PCI_MATCH(dev_match->subdevice, dev->subsystem_device)) + return dev_match->verstr; + } + +use_default: + return firmware_ver; +} + + +/*********************************************************************** +** acxpci_s_upload_fw +** +** Called from acx_reset_dev +*/ +static int +acxpci_s_upload_fw(acx_device_t *adev) +{ + firmware_image_t *fw_image = NULL; + int res = NOT_OK; + int try; + u32 file_size; + char filename[256]; + + FN_ENTER; + + printk(KERN_INFO "acx: loading firmware for acx1%02d chipset with radio" + " ID %02X\n", IS_ACX111(adev)*111, adev->radio_type); + + /* Try combined, then main image */ + adev->need_radio_fw = 0; + snprintf(filename, sizeof(filename), "acx/%s/tiacx1%02dc%02X", + get_firmware_ver(adev->pdev), + IS_ACX111(adev)*11, adev->radio_type); + + fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size); + if (!fw_image) { + adev->need_radio_fw = 1; + filename[strlen(filename) - 3] = '\0'; + fw_image = acx_s_read_fw(&adev->pdev->dev, filename, &file_size); + if (!fw_image) { + FN_EXIT1(NOT_OK); + return NOT_OK; + } + } + + for (try = 1; try <= 5; try++) { + res = acxpci_s_write_fw(adev, fw_image, 0); + log(L_DEBUG|L_INIT, "acx_write_fw (main/combined): %d\n", res); + if (OK == res) { + res = acxpci_s_validate_fw(adev, fw_image, 0); + log(L_DEBUG|L_INIT, "acx_validate_fw " + "(main/combined): %d\n", res); + } + + if (OK == res) { + SET_BIT(adev->dev_state_mask, ACX_STATE_FW_LOADED); + break; + } + printk("acx: firmware upload attempt #%d FAILED, " + "retrying...\n", try); + acx_s_msleep(1000); /* better wait for a while... */ + } + + vfree(fw_image); + + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acxpci_s_upload_radio +** +** Uploads the appropriate radio module firmware into the card. +*/ +int +acxpci_s_upload_radio(acx_device_t *adev) +{ + acx_ie_memmap_t mm; + firmware_image_t *radio_image; + acx_cmd_radioinit_t radioinit; + int res = NOT_OK; + int try; + u32 offset; + u32 size; + char filename[256]; + + if (!adev->need_radio_fw) return OK; + + FN_ENTER; + + printk(KERN_INFO "acx: loading radio image for radio %02X\n", + adev->radio_type); + + acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP); + offset = le32_to_cpu(mm.CodeEnd); + + snprintf(filename, sizeof(filename), "acx/%s/tiacx1%02dr%02X", + get_firmware_ver(adev->pdev), IS_ACX111(adev)*11, + adev->radio_type); + radio_image = acx_s_read_fw(&adev->pdev->dev, filename, &size); + if (!radio_image) { + printk("acx: can't load radio module '%s'\n", filename); + goto fail; + } + + acx_s_issue_cmd(adev, ACX1xx_CMD_SLEEP, NULL, 0); + + for (try = 1; try <= 5; try++) { + res = acxpci_s_write_fw(adev, radio_image, offset); + log(L_DEBUG|L_INIT, "acx_write_fw (radio): %d\n", res); + if (OK == res) { + res = acxpci_s_validate_fw(adev, radio_image, offset); + log(L_DEBUG|L_INIT, "acx_validate_fw (radio): %d\n", res); + } + + if (OK == res) + break; + printk("acx: radio firmware upload attempt #%d FAILED, " + "retrying...\n", try); + acx_s_msleep(1000); /* better wait for a while... */ + } + + acx_s_issue_cmd(adev, ACX1xx_CMD_WAKE, NULL, 0); + radioinit.offset = cpu_to_le32(offset); + /* no endian conversion needed, remains in card CPU area: */ + radioinit.len = radio_image->size; + + vfree(radio_image); + + if (OK != res) + goto fail; + + /* will take a moment so let's have a big timeout */ + acx_s_issue_cmd_timeo(adev, ACX1xx_CMD_RADIOINIT, + &radioinit, sizeof(radioinit), CMD_TIMEOUT_MS(1000)); + + res = acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP); +fail: + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acxpci_l_reset_mac +** +** MAC will be reset +** Call context: reset_dev +*/ +static void +acxpci_l_reset_mac(acx_device_t *adev) +{ + u16 temp; + + FN_ENTER; + + /* halt eCPU */ + temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1; + write_reg16(adev, IO_ACX_ECPU_CTRL, temp); + + /* now do soft reset of eCPU, set bit */ + temp = read_reg16(adev, IO_ACX_SOFT_RESET) | 0x1; + log(L_DEBUG, "%s: enable soft reset...\n", __func__); + write_reg16(adev, IO_ACX_SOFT_RESET, temp); + write_flush(adev); + + /* now clear bit again: deassert eCPU reset */ + log(L_DEBUG, "%s: disable soft reset and go to init mode...\n", __func__); + write_reg16(adev, IO_ACX_SOFT_RESET, temp & ~0x1); + + /* now start a burst read from initial EEPROM */ + temp = read_reg16(adev, IO_ACX_EE_START) | 0x1; + write_reg16(adev, IO_ACX_EE_START, temp); + write_flush(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_verify_init +*/ +static int +acxpci_s_verify_init(acx_device_t *adev) +{ + int result = NOT_OK; + unsigned long timeout; + + FN_ENTER; + + timeout = jiffies + 2*HZ; + for (;;) { + u16 irqstat = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES); + if (irqstat & HOST_INT_FCS_THRESHOLD) { + result = OK; + write_reg16(adev, IO_ACX_IRQ_ACK, HOST_INT_FCS_THRESHOLD); + break; + } + if (time_after(jiffies, timeout)) + break; + /* Init may take up to ~0.5 sec total */ + acx_s_msleep(50); + } + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** A few low-level helpers +** +** Note: these functions are not protected by lock +** and thus are never allowed to be called from IRQ. +** Also they must not race with fw upload which uses same hw regs +*/ + +/*********************************************************************** +** acxpci_write_cmd_type_status +*/ + +static inline void +acxpci_write_cmd_type_status(acx_device_t *adev, u16 type, u16 status) +{ + writel(type | (status << 16), adev->cmd_area); + write_flush(adev); +} + + +/*********************************************************************** +** acxpci_read_cmd_type_status +*/ +static u32 +acxpci_read_cmd_type_status(acx_device_t *adev) +{ + u32 cmd_type, cmd_status; + + cmd_type = readl(adev->cmd_area); + cmd_status = (cmd_type >> 16); + cmd_type = (u16)cmd_type; + + log(L_CTL, "cmd_type:%04X cmd_status:%04X [%s]\n", + cmd_type, cmd_status, + acx_cmd_status_str(cmd_status)); + + return cmd_status; +} + + +/*********************************************************************** +** acxpci_s_reset_dev +** +** Arguments: +** netdevice that contains the adev variable +** Returns: +** NOT_OK on fail +** OK on success +** Side effects: +** device is hard reset +** Call context: +** acxpci_e_probe +** Comment: +** This resets the device using low level hardware calls +** as well as uploads and verifies the firmware to the card +*/ + +static inline void +init_mboxes(acx_device_t *adev) +{ + u32 cmd_offs, info_offs; + + cmd_offs = read_reg32(adev, IO_ACX_CMD_MAILBOX_OFFS); + info_offs = read_reg32(adev, IO_ACX_INFO_MAILBOX_OFFS); + adev->cmd_area = (u8 *)adev->iobase2 + cmd_offs; + adev->info_area = (u8 *)adev->iobase2 + info_offs; + log(L_DEBUG, "iobase2=%p\n" + "cmd_mbox_offset=%X cmd_area=%p\n" + "info_mbox_offset=%X info_area=%p\n", + adev->iobase2, + cmd_offs, adev->cmd_area, + info_offs, adev->info_area); +} + + +static inline void +read_eeprom_area(acx_device_t *adev) +{ +#if ACX_DEBUG > 1 + int offs; + u8 tmp; + + for (offs = 0x8c; offs < 0xb9; offs++) + acxpci_read_eeprom_byte(adev, offs, &tmp); +#endif +} + + +static int +acxpci_s_reset_dev(acx_device_t *adev) +{ + const char* msg = ""; + unsigned long flags; + int result = NOT_OK; + u16 hardware_info; + u16 ecpu_ctrl; + int count; + + FN_ENTER; + + /* reset the device to make sure the eCPU is stopped + * to upload the firmware correctly */ + + acx_lock(adev, flags); + + acxpci_l_reset_mac(adev); + + ecpu_ctrl = read_reg16(adev, IO_ACX_ECPU_CTRL) & 1; + if (!ecpu_ctrl) { + msg = "eCPU is already running. "; + goto end_unlock; + } + +#ifdef WE_DONT_NEED_THAT_DO_WE + if (read_reg16(adev, IO_ACX_SOR_CFG) & 2) { + /* eCPU most likely means "embedded CPU" */ + msg = "eCPU did not start after boot from flash. "; + goto end_unlock; + } + + /* check sense on reset flags */ + if (read_reg16(adev, IO_ACX_SOR_CFG) & 0x10) { + printk("%s: eCPU did not start after boot (SOR), " + "is this fatal?\n", adev->ndev->name); + } +#endif + /* scan, if any, is stopped now, setting corresponding IRQ bit */ + adev->irq_status |= HOST_INT_SCAN_COMPLETE; + + acx_unlock(adev, flags); + + /* need to know radio type before fw load */ + /* Need to wait for arrival of this information in a loop, + * most probably since eCPU runs some init code from EEPROM + * (started burst read in reset_mac()) which also + * sets the radio type ID */ + + count = 0xffff; + do { + hardware_info = read_reg16(adev, IO_ACX_EEPROM_INFORMATION); + if (!--count) { + msg = "eCPU didn't indicate radio type"; + goto end_fail; + } + cpu_relax(); + } while (!(hardware_info & 0xff00)); /* radio type still zero? */ + + /* printk("DEBUG: count %d\n", count); */ + adev->form_factor = hardware_info & 0xff; + adev->radio_type = hardware_info >> 8; + + /* load the firmware */ + if (OK != acxpci_s_upload_fw(adev)) + goto end_fail; + + /* acx_s_msleep(10); this one really shouldn't be required */ + + /* now start eCPU by clearing bit */ + write_reg16(adev, IO_ACX_ECPU_CTRL, ecpu_ctrl & ~0x1); + log(L_DEBUG, "booted eCPU up and waiting for completion...\n"); + + /* wait for eCPU bootup */ + if (OK != acxpci_s_verify_init(adev)) { + msg = "timeout waiting for eCPU. "; + goto end_fail; + } + log(L_DEBUG, "eCPU has woken up, card is ready to be configured\n"); + + init_mboxes(adev); + acxpci_write_cmd_type_status(adev, 0, 0); + + /* test that EEPROM is readable */ + read_eeprom_area(adev); + + result = OK; + goto end; + +/* Finish error message. Indicate which function failed */ +end_unlock: + acx_unlock(adev, flags); +end_fail: + printk("acx: %sreset_dev() FAILED\n", msg); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxpci_s_issue_cmd_timeo +** +** Sends command to fw, extract result +** +** NB: we do _not_ take lock inside, so be sure to not touch anything +** which may interfere with IRQ handler operation +** +** TODO: busy wait is a bit silly, so: +** 1) stop doing many iters - go to sleep after first +** 2) go to waitqueue based approach: wait, not poll! +*/ +#undef FUNC +#define FUNC "issue_cmd" + +#if !ACX_DEBUG +int +acxpci_s_issue_cmd_timeo( + acx_device_t *adev, + unsigned int cmd, + void *buffer, + unsigned buflen, + unsigned cmd_timeout) +{ +#else +int +acxpci_s_issue_cmd_timeo_debug( + acx_device_t *adev, + unsigned cmd, + void *buffer, + unsigned buflen, + unsigned cmd_timeout, + const char* cmdstr) +{ + unsigned long start = jiffies; +#endif + const char *devname; + unsigned counter; + u16 irqtype; + u16 cmd_status; + unsigned long timeout; + + FN_ENTER; + + devname = adev->ndev->name; + if (!devname || !devname[0] || devname[4]=='%') + devname = "acx"; + + log(L_CTL, FUNC"(cmd:%s,buflen:%u,timeout:%ums,type:0x%04X)\n", + cmdstr, buflen, cmd_timeout, + buffer ? le16_to_cpu(((acx_ie_generic_t *)buffer)->type) : -1); + + if (!(adev->dev_state_mask & ACX_STATE_FW_LOADED)) { + printk("%s: "FUNC"(): firmware is not loaded yet, " + "cannot execute commands!\n", devname); + goto bad; + } + + if ((acx_debug & L_DEBUG) && (cmd != ACX1xx_CMD_INTERROGATE)) { + printk("input buffer (len=%u):\n", buflen); + acx_dump_bytes(buffer, buflen); + } + + /* wait for firmware to become idle for our command submission */ + timeout = HZ/5; + counter = (timeout * 1000 / HZ) - 1; /* in ms */ + timeout += jiffies; + do { + cmd_status = acxpci_read_cmd_type_status(adev); + /* Test for IDLE state */ + if (!cmd_status) + break; + if (counter % 8 == 0) { + if (time_after(jiffies, timeout)) { + counter = 0; + break; + } + /* we waited 8 iterations, no luck. Sleep 8 ms */ + acx_s_msleep(8); + } + } while (likely(--counter)); + + if (!counter) { + /* the card doesn't get idle, we're in trouble */ + printk("%s: "FUNC"(): cmd_status is not IDLE: 0x%04X!=0\n", + devname, cmd_status); + goto bad; + } else if (counter < 190) { /* if waited >10ms... */ + log(L_CTL|L_DEBUG, FUNC"(): waited for IDLE %dms. " + "Please report\n", 199 - counter); + } + + /* now write the parameters of the command if needed */ + if (buffer && buflen) { + /* if it's an INTERROGATE command, just pass the length + * of parameters to read, as data */ +#if CMD_DISCOVERY + if (cmd == ACX1xx_CMD_INTERROGATE) + memset_io(adev->cmd_area + 4, 0xAA, buflen); +#endif + /* adev->cmd_area points to PCI device's memory, not to RAM! */ + memcpy_toio(adev->cmd_area + 4, buffer, + (cmd == ACX1xx_CMD_INTERROGATE) ? 4 : buflen); + } + /* now write the actual command type */ + acxpci_write_cmd_type_status(adev, cmd, 0); + /* execute command */ + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_CMD); + write_flush(adev); + + /* wait for firmware to process command */ + + /* Ensure nonzero and not too large timeout. + ** Also converts e.g. 100->99, 200->199 + ** which is nice but not essential */ + cmd_timeout = (cmd_timeout-1) | 1; + if (unlikely(cmd_timeout > 1199)) + cmd_timeout = 1199; + /* clear CMD_COMPLETE bit. can be set only by IRQ handler: */ + adev->irq_status &= ~HOST_INT_CMD_COMPLETE; + + /* we schedule away sometimes (timeout can be large) */ + counter = cmd_timeout; + timeout = jiffies + cmd_timeout * HZ / 1000; + do { + if (!adev->irqs_active) { /* IRQ disabled: poll */ + irqtype = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES); + if (irqtype & HOST_INT_CMD_COMPLETE) { + write_reg16(adev, IO_ACX_IRQ_ACK, + HOST_INT_CMD_COMPLETE); + break; + } + } else { /* Wait when IRQ will set the bit */ + irqtype = adev->irq_status; + if (irqtype & HOST_INT_CMD_COMPLETE) + break; + } + + if (counter % 8 == 0) { + if (time_after(jiffies, timeout)) { + counter = 0; + break; + } + /* we waited 8 iterations, no luck. Sleep 8 ms */ + acx_s_msleep(8); + } + } while (likely(--counter)); + + /* save state for debugging */ + cmd_status = acxpci_read_cmd_type_status(adev); + + /* put the card in IDLE state */ + acxpci_write_cmd_type_status(adev, 0, 0); + + if (!counter) { /* timed out! */ + printk("%s: "FUNC"(): timed out %s for CMD_COMPLETE. " + "irq bits:0x%04X irq_status:0x%04X timeout:%dms " + "cmd_status:%d (%s)\n", + devname, (adev->irqs_active) ? "waiting" : "polling", + irqtype, adev->irq_status, cmd_timeout, + cmd_status, acx_cmd_status_str(cmd_status)); + goto bad; + } else if (cmd_timeout - counter > 30) { /* if waited >30ms... */ + log(L_CTL|L_DEBUG, FUNC"(): %s for CMD_COMPLETE %dms. " + "count:%d. Please report\n", + (adev->irqs_active) ? "waited" : "polled", + cmd_timeout - counter, counter); + } + + if (1 != cmd_status) { /* it is not a 'Success' */ + printk("%s: "FUNC"(): cmd_status is not SUCCESS: %d (%s). " + "Took %dms of %d\n", + devname, cmd_status, acx_cmd_status_str(cmd_status), + cmd_timeout - counter, cmd_timeout); + /* zero out result buffer + * WARNING: this will trash stack in case of illegally large input + * length! */ + if (buffer && buflen) + memset(buffer, 0, buflen); + goto bad; + } + + /* read in result parameters if needed */ + if (buffer && buflen && (cmd == ACX1xx_CMD_INTERROGATE)) { + /* adev->cmd_area points to PCI device's memory, not to RAM! */ + memcpy_fromio(buffer, adev->cmd_area + 4, buflen); + if (acx_debug & L_DEBUG) { + printk("output buffer (len=%u): ", buflen); + acx_dump_bytes(buffer, buflen); + } + } +/* ok: */ + log(L_CTL, FUNC"(%s): took %ld jiffies to complete\n", + cmdstr, jiffies - start); + FN_EXIT1(OK); + return OK; + +bad: + /* Give enough info so that callers can avoid + ** printing their own diagnostic messages */ +#if ACX_DEBUG + printk("%s: "FUNC"(cmd:%s) FAILED\n", devname, cmdstr); +#else + printk("%s: "FUNC"(cmd:0x%04X) FAILED\n", devname, cmd); +#endif + dump_stack(); + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +*/ +#ifdef NONESSENTIAL_FEATURES +typedef struct device_id { + unsigned char id[6]; + char *descr; + char *type; +} device_id_t; + +static const device_id_t +device_ids[] = +{ + { + {'G', 'l', 'o', 'b', 'a', 'l'}, + NULL, + NULL, + }, + { + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + "uninitialized", + "SpeedStream SS1021 or Gigafast WF721-AEX" + }, + { + {0x80, 0x81, 0x82, 0x83, 0x84, 0x85}, + "non-standard", + "DrayTek Vigor 520" + }, + { + {'?', '?', '?', '?', '?', '?'}, + "non-standard", + "Level One WPC-0200" + }, + { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + "empty", + "DWL-650+ variant" + } +}; + +static void +acx_show_card_eeprom_id(acx_device_t *adev) +{ + unsigned char buffer[CARD_EEPROM_ID_SIZE]; + int i; + + memset(&buffer, 0, CARD_EEPROM_ID_SIZE); + /* use direct EEPROM access */ + for (i = 0; i < CARD_EEPROM_ID_SIZE; i++) { + if (OK != acxpci_read_eeprom_byte(adev, + ACX100_EEPROM_ID_OFFSET + i, + &buffer[i])) { + printk("acx: reading EEPROM FAILED\n"); + break; + } + } + + for (i = 0; i < VEC_SIZE(device_ids); i++) { + if (!memcmp(&buffer, device_ids[i].id, CARD_EEPROM_ID_SIZE)) { + if (device_ids[i].descr) { + printk("acx: EEPROM card ID string check " + "found %s card ID: is this %s?\n", + device_ids[i].descr, device_ids[i].type); + } + break; + } + } + if (i == VEC_SIZE(device_ids)) { + printk("acx: EEPROM card ID string check found " + "unknown card: expected 'Global', got '%.*s\'. " + "Please report\n", CARD_EEPROM_ID_SIZE, buffer); + } +} +#endif /* NONESSENTIAL_FEATURES */ + + +/*********************************************************************** +** acxpci_free_desc_queues +** +** Releases the queues that have been allocated, the +** others have been initialised to NULL so this +** function can be used if only part of the queues were allocated. +*/ + +static inline void +free_coherent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + dma_free_coherent(hwdev == NULL ? NULL : &hwdev->dev, + size, vaddr, dma_handle); +} + +void +acxpci_free_desc_queues(acx_device_t *adev) +{ +#define ACX_FREE_QUEUE(size, ptr, phyaddr) \ + if (ptr) { \ + free_coherent(0, size, ptr, phyaddr); \ + ptr = NULL; \ + size = 0; \ + } + + FN_ENTER; + + ACX_FREE_QUEUE(adev->txhostdesc_area_size, adev->txhostdesc_start, adev->txhostdesc_startphy); + ACX_FREE_QUEUE(adev->txbuf_area_size, adev->txbuf_start, adev->txbuf_startphy); + + adev->txdesc_start = NULL; + + ACX_FREE_QUEUE(adev->rxhostdesc_area_size, adev->rxhostdesc_start, adev->rxhostdesc_startphy); + ACX_FREE_QUEUE(adev->rxbuf_area_size, adev->rxbuf_start, adev->rxbuf_startphy); + + adev->rxdesc_start = NULL; + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_delete_dma_regions +*/ +static void +acxpci_s_delete_dma_regions(acx_device_t *adev) +{ + unsigned long flags; + + FN_ENTER; + /* disable radio Tx/Rx. Shouldn't we use the firmware commands + * here instead? Or are we that much down the road that it's no + * longer possible here? */ + write_reg16(adev, IO_ACX_ENABLE, 0); + + acx_s_msleep(100); + + acx_lock(adev, flags); + acxpci_free_desc_queues(adev); + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_e_probe +** +** Probe routine called when a PCI device w/ matching ID is found. +** Here's the sequence: +** - Allocate the PCI resources. +** - Read the PCMCIA attribute memory to make sure we have a WLAN card +** - Reset the MAC +** - Initialize the dev and wlan data +** - Initialize the MAC +** +** pdev - ptr to pci device structure containing info about pci configuration +** id - ptr to the device id entry that matched this device +*/ +static const u16 +IO_ACX100[] = +{ + 0x0000, /* IO_ACX_SOFT_RESET */ + + 0x0014, /* IO_ACX_SLV_MEM_ADDR */ + 0x0018, /* IO_ACX_SLV_MEM_DATA */ + 0x001c, /* IO_ACX_SLV_MEM_CTL */ + 0x0020, /* IO_ACX_SLV_END_CTL */ + + 0x0034, /* IO_ACX_FEMR */ + + 0x007c, /* IO_ACX_INT_TRIG */ + 0x0098, /* IO_ACX_IRQ_MASK */ + 0x00a4, /* IO_ACX_IRQ_STATUS_NON_DES */ + 0x00a8, /* IO_ACX_IRQ_STATUS_CLEAR */ + 0x00ac, /* IO_ACX_IRQ_ACK */ + 0x00b0, /* IO_ACX_HINT_TRIG */ + + 0x0104, /* IO_ACX_ENABLE */ + + 0x0250, /* IO_ACX_EEPROM_CTL */ + 0x0254, /* IO_ACX_EEPROM_ADDR */ + 0x0258, /* IO_ACX_EEPROM_DATA */ + 0x025c, /* IO_ACX_EEPROM_CFG */ + + 0x0268, /* IO_ACX_PHY_ADDR */ + 0x026c, /* IO_ACX_PHY_DATA */ + 0x0270, /* IO_ACX_PHY_CTL */ + + 0x0290, /* IO_ACX_GPIO_OE */ + + 0x0298, /* IO_ACX_GPIO_OUT */ + + 0x02a4, /* IO_ACX_CMD_MAILBOX_OFFS */ + 0x02a8, /* IO_ACX_INFO_MAILBOX_OFFS */ + 0x02ac, /* IO_ACX_EEPROM_INFORMATION */ + + 0x02d0, /* IO_ACX_EE_START */ + 0x02d4, /* IO_ACX_SOR_CFG */ + 0x02d8 /* IO_ACX_ECPU_CTRL */ +}; + +static const u16 +IO_ACX111[] = +{ + 0x0000, /* IO_ACX_SOFT_RESET */ + + 0x0014, /* IO_ACX_SLV_MEM_ADDR */ + 0x0018, /* IO_ACX_SLV_MEM_DATA */ + 0x001c, /* IO_ACX_SLV_MEM_CTL */ + 0x0020, /* IO_ACX_SLV_END_CTL */ + + 0x0034, /* IO_ACX_FEMR */ + + 0x00b4, /* IO_ACX_INT_TRIG */ + 0x00d4, /* IO_ACX_IRQ_MASK */ + /* we do mean NON_DES (0xf0), not NON_DES_MASK which is at 0xe0: */ + 0x00f0, /* IO_ACX_IRQ_STATUS_NON_DES */ + 0x00e4, /* IO_ACX_IRQ_STATUS_CLEAR */ + 0x00e8, /* IO_ACX_IRQ_ACK */ + 0x00ec, /* IO_ACX_HINT_TRIG */ + + 0x01d0, /* IO_ACX_ENABLE */ + + 0x0338, /* IO_ACX_EEPROM_CTL */ + 0x033c, /* IO_ACX_EEPROM_ADDR */ + 0x0340, /* IO_ACX_EEPROM_DATA */ + 0x0344, /* IO_ACX_EEPROM_CFG */ + + 0x0350, /* IO_ACX_PHY_ADDR */ + 0x0354, /* IO_ACX_PHY_DATA */ + 0x0358, /* IO_ACX_PHY_CTL */ + + 0x0374, /* IO_ACX_GPIO_OE */ + + 0x037c, /* IO_ACX_GPIO_OUT */ + + 0x0388, /* IO_ACX_CMD_MAILBOX_OFFS */ + 0x038c, /* IO_ACX_INFO_MAILBOX_OFFS */ + 0x0390, /* IO_ACX_EEPROM_INFORMATION */ + + 0x0100, /* IO_ACX_EE_START */ + 0x0104, /* IO_ACX_SOR_CFG */ + 0x0108, /* IO_ACX_ECPU_CTRL */ +}; + +static void +dummy_netdev_init(struct net_device *ndev) {} + +static int __devinit +acxpci_e_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + acx111_ie_configoption_t co; + unsigned long mem_region1 = 0; + unsigned long mem_region2 = 0; + unsigned long mem_region1_size; + unsigned long mem_region2_size; + unsigned long phymem1; + unsigned long phymem2; + void *mem1 = NULL; + void *mem2 = NULL; + acx_device_t *adev = NULL; + struct net_device *ndev = NULL; + const char *chip_name; + int result = -EIO; + int err; + u8 chip_type; + + FN_ENTER; + + /* Enable the PCI device */ + if (pci_enable_device(pdev)) { + printk("acx: pci_enable_device() FAILED\n"); + result = -ENODEV; + goto fail_pci_enable_device; + } + + /* enable busmastering (required for CardBus) */ + pci_set_master(pdev); + + /* FIXME: prism54 calls pci_set_mwi() here, + * should we do/support the same? */ + + /* chiptype is u8 but id->driver_data is ulong + ** Works for now (possible values are 1 and 2) */ + chip_type = (u8)id->driver_data; + /* acx100 and acx111 have different PCI memory regions */ + if (chip_type == CHIPTYPE_ACX100) { + chip_name = "ACX100"; + mem_region1 = PCI_ACX100_REGION1; + mem_region1_size = PCI_ACX100_REGION1_SIZE; + + mem_region2 = PCI_ACX100_REGION2; + mem_region2_size = PCI_ACX100_REGION2_SIZE; + } else if (chip_type == CHIPTYPE_ACX111) { + chip_name = "ACX111"; + mem_region1 = PCI_ACX111_REGION1; + mem_region1_size = PCI_ACX111_REGION1_SIZE; + + mem_region2 = PCI_ACX111_REGION2; + mem_region2_size = PCI_ACX111_REGION2_SIZE; + } else { + printk("acx: unknown chip type 0x%04X\n", chip_type); + goto fail_unknown_chiptype; + } + + /* Figure out our resources */ + phymem1 = pci_resource_start(pdev, mem_region1); + phymem2 = pci_resource_start(pdev, mem_region2); + if (!request_mem_region(phymem1, pci_resource_len(pdev, mem_region1), "acx_1")) { + printk("acx: cannot reserve PCI memory region 1 (are you sure " + "you have CardBus support in kernel?)\n"); + goto fail_request_mem_region1; + } + if (!request_mem_region(phymem2, pci_resource_len(pdev, mem_region2), "acx_2")) { + printk("acx: cannot reserve PCI memory region 2\n"); + goto fail_request_mem_region2; + } + + /* this used to be ioremap(), but ioremap_nocache() + * is much less risky, right? (and slower?) + * FIXME: we may want to go back to cached variant if it's + * certain that our code really properly handles + * cached operation (memory barriers, volatile?, ...) + * (but always keep this comment here regardless!) + * Possibly make this a driver config setting? */ + + mem1 = ioremap(phymem1, mem_region1_size); + if (!mem1) { + printk("acx: ioremap() FAILED\n"); + goto fail_ioremap1; + } + mem2 = ioremap(phymem2, mem_region2_size); + if (!mem2) { + printk("acx: ioremap() #2 FAILED\n"); + goto fail_ioremap2; + } + + printk("acx: found %s-based wireless network card at %s, irq:%d, " + "phymem1:0x%lX, phymem2:0x%lX, mem1:0x%p, mem1_size:%ld, " + "mem2:0x%p, mem2_size:%ld\n", + chip_name, pci_name(pdev), pdev->irq, phymem1, phymem2, + mem1, mem_region1_size, + mem2, mem_region2_size); + log(L_ANY, "initial debug setting is 0x%04X\n", acx_debug); + + if (0 == pdev->irq) { + printk("acx: can't use IRQ 0\n"); + goto fail_irq; + } + + ndev = alloc_netdev(sizeof(*adev), "wlan%d", dummy_netdev_init); + /* (NB: memsets to 0 entire area) */ + if (!ndev) { + printk("acx: no memory for netdevice struct\n"); + goto fail_alloc_netdev; + } + + ether_setup(ndev); + ndev->open = &acxpci_e_open; + ndev->stop = &acxpci_e_close; + ndev->hard_start_xmit = &acx_i_start_xmit; + ndev->get_stats = &acx_e_get_stats; +#if IW_HANDLER_VERSION <= 5 + ndev->get_wireless_stats = &acx_e_get_wireless_stats; +#endif + ndev->wireless_handlers = (struct iw_handler_def *)&acx_ioctl_handler_def; + ndev->set_multicast_list = &acxpci_i_set_multicast_list; + ndev->tx_timeout = &acxpci_i_tx_timeout; + ndev->change_mtu = &acx_e_change_mtu; + ndev->watchdog_timeo = 4 * HZ; + ndev->irq = pdev->irq; + ndev->base_addr = pci_resource_start(pdev, 0); + + adev = ndev2adev(ndev); + spin_lock_init(&adev->lock); /* initial state: unlocked */ + /* We do not start with downed sem: we want PARANOID_LOCKING to work */ + sema_init(&adev->sem, 1); /* initial state: 1 (upped) */ + /* since nobody can see new netdev yet, we can as well + ** just _presume_ that we're under sem (instead of actually taking it): */ + /* acx_sem_lock(adev); */ + adev->pdev = pdev; + adev->ndev = ndev; + adev->dev_type = DEVTYPE_PCI; + adev->chip_type = chip_type; + adev->chip_name = chip_name; + adev->io = (CHIPTYPE_ACX100 == chip_type) ? IO_ACX100 : IO_ACX111; + adev->membase = phymem1; + adev->iobase = mem1; + adev->membase2 = phymem2; + adev->iobase2 = mem2; + /* to find crashes due to weird driver access + * to unconfigured interface (ifup) */ + adev->mgmt_timer.function = (void (*)(unsigned long))0x0000dead; + +#ifdef NONESSENTIAL_FEATURES + acx_show_card_eeprom_id(adev); +#endif /* NONESSENTIAL_FEATURES */ + +#ifdef SET_MODULE_OWNER + SET_MODULE_OWNER(ndev); +#endif + SET_NETDEV_DEV(ndev, &pdev->dev); + + log(L_IRQ|L_INIT, "using IRQ %d\n", pdev->irq); + + /* need to be able to restore PCI state after a suspend */ + pci_save_state(pdev); + pci_set_drvdata(pdev, ndev); + + /* ok, pci setup is finished, now start initializing the card */ + + /* NB: read_reg() reads may return bogus data before reset_dev(), + * since the firmware which directly controls large parts of the I/O + * registers isn't initialized yet. + * acx100 seems to be more affected than acx111 */ + if (OK != acxpci_s_reset_dev(adev)) + goto fail_reset; + + if (IS_ACX100(adev)) { + /* ACX100: configopt struct in cmd mailbox - directly after reset */ + memcpy_fromio(&co, adev->cmd_area, sizeof(co)); + } + + if (OK != acx_s_init_mac(adev)) + goto fail_init_mac; + + if (IS_ACX111(adev)) { + /* ACX111: configopt struct needs to be queried after full init */ + acx_s_interrogate(adev, &co, ACX111_IE_CONFIG_OPTIONS); + } + +/* TODO: merge them into one function, they are called just once and are the same for pci & usb */ + if (OK != acxpci_read_eeprom_byte(adev, 0x05, &adev->eeprom_version)) + goto fail_read_eeprom_version; + + acx_s_parse_configoption(adev, &co); + acx_s_set_defaults(adev); + acx_s_get_firmware_version(adev); /* needs to be after acx_s_init_mac() */ + acx_display_hardware_details(adev); + + /* Register the card, AFTER everything else has been set up, + * since otherwise an ioctl could step on our feet due to + * firmware operations happening in parallel or uninitialized data */ + err = register_netdev(ndev); + if (OK != err) { + printk("acx: register_netdev() FAILED: %d\n", err); + goto fail_register_netdev; + } + + acx_proc_register_entries(ndev); + + /* Now we have our device, so make sure the kernel doesn't try + * to send packets even though we're not associated to a network yet */ + acx_stop_queue(ndev, "on probe"); + acx_carrier_off(ndev, "on probe"); + + /* after register_netdev() userspace may start working with dev + * (in particular, on other CPUs), we only need to up the sem */ + /* acx_sem_unlock(adev); */ + + printk("acx "ACX_RELEASE": net device %s, driver compiled " + "against wireless extensions %d and Linux %s\n", + ndev->name, WIRELESS_EXT, UTS_RELEASE); + +#if CMD_DISCOVERY + great_inquisitor(adev); +#endif + + result = OK; + goto done; + + /* error paths: undo everything in reverse order... */ + +fail_register_netdev: + + acxpci_s_delete_dma_regions(adev); + pci_set_drvdata(pdev, NULL); + +fail_init_mac: +fail_read_eeprom_version: +fail_reset: + + free_netdev(ndev); +fail_alloc_netdev: +fail_irq: + + iounmap(mem2); +fail_ioremap2: + + iounmap(mem1); +fail_ioremap1: + + release_mem_region(pci_resource_start(pdev, mem_region2), + pci_resource_len(pdev, mem_region2)); +fail_request_mem_region2: + + release_mem_region(pci_resource_start(pdev, mem_region1), + pci_resource_len(pdev, mem_region1)); +fail_request_mem_region1: +fail_unknown_chiptype: + + pci_disable_device(pdev); +fail_pci_enable_device: + + pci_set_power_state(pdev, PCI_D3hot); + +done: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxpci_e_remove +** +** Shut device down (if not hot unplugged) +** and deallocate PCI resources for the acx chip. +** +** pdev - ptr to PCI device structure containing info about pci configuration +*/ +static void __devexit +acxpci_e_remove(struct pci_dev *pdev) +{ + struct net_device *ndev; + acx_device_t *adev; + unsigned long mem_region1, mem_region2; + unsigned long flags; + + FN_ENTER; + + ndev = (struct net_device*) pci_get_drvdata(pdev); + if (!ndev) { + log(L_DEBUG, "%s: card is unused. Skipping any release code\n", + __func__); + goto end; + } + + adev = ndev2adev(ndev); + + /* If device wasn't hot unplugged... */ + if (adev_present(adev)) { + + acx_sem_lock(adev); + + /* disable both Tx and Rx to shut radio down properly */ + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0); + +#ifdef REDUNDANT + /* put the eCPU to sleep to save power + * Halting is not possible currently, + * since not supported by all firmware versions */ + acx_s_issue_cmd(adev, ACX100_CMD_SLEEP, NULL, 0); +#endif + acx_lock(adev, flags); + /* disable power LED to save power :-) */ + log(L_INIT, "switching off power LED to save power\n"); + acxpci_l_power_led(adev, 0); + /* stop our eCPU */ + if (IS_ACX111(adev)) { + /* FIXME: does this actually keep halting the eCPU? + * I don't think so... + */ + acxpci_l_reset_mac(adev); + } else { + u16 temp; + /* halt eCPU */ + temp = read_reg16(adev, IO_ACX_ECPU_CTRL) | 0x1; + write_reg16(adev, IO_ACX_ECPU_CTRL, temp); + write_flush(adev); + } + acx_unlock(adev, flags); + + acx_sem_unlock(adev); + } + + /* unregister the device to not let the kernel + * (e.g. ioctls) access a half-deconfigured device + * NB: this will cause acxpci_e_close() to be called, + * thus we shouldn't call it under sem! */ + log(L_INIT, "removing device %s\n", ndev->name); + unregister_netdev(ndev); + + /* unregister_netdev ensures that no references to us left. + * For paranoid reasons we continue to follow the rules */ + acx_sem_lock(adev); + + if (adev->dev_state_mask & ACX_STATE_IFACE_UP) { + acxpci_s_down(ndev); + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + } + + acx_proc_unregister_entries(ndev); + + if (IS_ACX100(adev)) { + mem_region1 = PCI_ACX100_REGION1; + mem_region2 = PCI_ACX100_REGION2; + } else { + mem_region1 = PCI_ACX111_REGION1; + mem_region2 = PCI_ACX111_REGION2; + } + + /* finally, clean up PCI bus state */ + acxpci_s_delete_dma_regions(adev); + if (adev->iobase) iounmap(adev->iobase); + if (adev->iobase2) iounmap(adev->iobase2); + release_mem_region(pci_resource_start(pdev, mem_region1), + pci_resource_len(pdev, mem_region1)); + release_mem_region(pci_resource_start(pdev, mem_region2), + pci_resource_len(pdev, mem_region2)); + pci_disable_device(pdev); + + /* remove dev registration */ + pci_set_drvdata(pdev, NULL); + + acx_sem_unlock(adev); + + /* Free netdev (quite late, + * since otherwise we might get caught off-guard + * by a netdev timeout handler execution + * expecting to see a working dev...) */ + free_netdev(ndev); + + /* put device into ACPI D3 mode (shutdown) */ + pci_set_power_state(pdev, PCI_D3hot); + +end: + FN_EXIT0; +} + + +/*********************************************************************** +** TODO: PM code needs to be fixed / debugged / tested. +*/ +#ifdef CONFIG_PM +static int +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 11) +acxpci_e_suspend(struct pci_dev *pdev, pm_message_t state) +#else +acxpci_e_suspend(struct pci_dev *pdev, u32 state) +#endif +{ + struct net_device *ndev = pci_get_drvdata(pdev); + acx_device_t *adev; + + FN_ENTER; + printk("acx: suspend handler is experimental!\n"); + printk("sus: dev %p\n", ndev); + + if (!netif_running(ndev)) + goto end; + + adev = ndev2adev(ndev); + printk("sus: adev %p\n", adev); + + acx_sem_lock(adev); + + netif_device_detach(ndev); /* this one cannot sleep */ + acxpci_s_down(ndev); + /* down() does not set it to 0xffff, but here we really want that */ + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + write_reg16(adev, IO_ACX_FEMR, 0x0); + acxpci_s_delete_dma_regions(adev); + pci_save_state(pdev); + pci_set_power_state(pdev, PCI_D3hot); + + acx_sem_unlock(adev); +end: + FN_EXIT0; + return OK; +} + + +static int +acxpci_e_resume(struct pci_dev *pdev) +{ + struct net_device *ndev = pci_get_drvdata(pdev); + acx_device_t *adev; + + FN_ENTER; + + printk("acx: resume handler is experimental!\n"); + printk("rsm: got dev %p\n", ndev); + + if (!netif_running(ndev)) + goto end; + + adev = ndev2adev(ndev); + printk("rsm: got adev %p\n", adev); + + acx_sem_lock(adev); + + pci_set_power_state(pdev, PCI_D0); + printk("rsm: power state PCI_D0 set\n"); + pci_restore_state(pdev); + printk("rsm: PCI state restored\n"); + + if (OK != acxpci_s_reset_dev(adev)) + goto end_unlock; + printk("rsm: device reset done\n"); + if (OK != acx_s_init_mac(adev)) + goto end_unlock; + printk("rsm: init MAC done\n"); + + acxpci_s_up(ndev); + printk("rsm: acx up done\n"); + + /* now even reload all card parameters as they were before suspend, + * and possibly be back in the network again already :-) */ + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) { + adev->set_mask = GETSET_ALL; + acx_s_update_card_settings(adev); + printk("rsm: settings updated\n"); + } + netif_device_attach(ndev); + printk("rsm: device attached\n"); + +end_unlock: + acx_sem_unlock(adev); +end: + /* we need to return OK here anyway, right? */ + FN_EXIT0; + return OK; +} +#endif /* CONFIG_PM */ + + +/*********************************************************************** +** acxpci_s_up +** +** This function is called by acxpci_e_open (when ifconfig sets the device as up) +** +** Side effects: +** - Enables on-card interrupt requests +** - calls acx_s_start +*/ + +static void +enable_acx_irq(acx_device_t *adev) +{ + FN_ENTER; + write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask); + write_reg16(adev, IO_ACX_FEMR, 0x8000); + adev->irqs_active = 1; + FN_EXIT0; +} + +static void +acxpci_s_up(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + + FN_ENTER; + + acx_lock(adev, flags); + enable_acx_irq(adev); + acx_unlock(adev, flags); + + /* acx fw < 1.9.3.e has a hardware timer, and older drivers + ** used to use it. But we don't do that anymore, our OS + ** has reliable software timers */ + init_timer(&adev->mgmt_timer); + adev->mgmt_timer.function = acx_i_timer; + adev->mgmt_timer.data = (unsigned long)adev; + + /* Need to set ACX_STATE_IFACE_UP first, or else + ** timer won't be started by acx_set_status() */ + SET_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + /* actual scan cmd will happen in start() */ + acx_set_status(adev, ACX_STATUS_1_SCANNING); break; + case ACX_MODE_3_AP: + case ACX_MODE_MONITOR: + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); break; + } + + acx_s_start(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_down +** +** NB: device may be already hot unplugged if called from acxpci_e_remove() +** +** Disables on-card interrupt request, stops softirq and timer, stops queue, +** sets status == STOPPED +*/ + +static void +disable_acx_irq(acx_device_t *adev) +{ + FN_ENTER; + + /* I guess mask is not 0xffff because acx100 won't signal + ** cmd completion then (needed for ifup). + ** Someone with acx100 please confirm */ + write_reg16(adev, IO_ACX_IRQ_MASK, adev->irq_mask_off); + write_reg16(adev, IO_ACX_FEMR, 0x0); + adev->irqs_active = 0; + FN_EXIT0; +} + +static void +acxpci_s_down(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + + FN_ENTER; + + /* Disable IRQs first, so that IRQs cannot race with us */ + /* then wait until interrupts have finished executing on other CPUs */ + acx_lock(adev, flags); + disable_acx_irq(adev); + synchronize_irq(adev->pdev->irq); + acx_unlock(adev, flags); + + /* we really don't want to have an asynchronous tasklet disturb us + ** after something vital for its job has been shut down, so + ** end all remaining work now. + ** + ** NB: carrier_off (done by set_status below) would lead to + ** not yet fully understood deadlock in FLUSH_SCHEDULED_WORK(). + ** That's why we do FLUSH first. + ** + ** NB2: we have a bad locking bug here: FLUSH_SCHEDULED_WORK() + ** waits for acx_e_after_interrupt_task to complete if it is running + ** on another CPU, but acx_e_after_interrupt_task + ** will sleep on sem forever, because it is taken by us! + ** Work around that by temporary sem unlock. + ** This will fail miserably if we'll be hit by concurrent + ** iwconfig or something in between. TODO! */ + acx_sem_unlock(adev); + FLUSH_SCHEDULED_WORK(); + acx_sem_lock(adev); + + /* This is possible: + ** FLUSH_SCHEDULED_WORK -> acx_e_after_interrupt_task -> + ** -> set_status(ASSOCIATED) -> wake_queue() + ** That's why we stop queue _after_ FLUSH_SCHEDULED_WORK + ** lock/unlock is just paranoia, maybe not needed */ + acx_lock(adev, flags); + acx_stop_queue(ndev, "on ifdown"); + acx_set_status(adev, ACX_STATUS_0_STOPPED); + acx_unlock(adev, flags); + + /* kernel/timer.c says it's illegal to del_timer_sync() + ** a timer which restarts itself. We guarantee this cannot + ** ever happen because acx_i_timer() never does this if + ** status is ACX_STATUS_0_STOPPED */ + del_timer_sync(&adev->mgmt_timer); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_e_open +** +** Called as a result of SIOCSIFFLAGS ioctl changing the flags bit IFF_UP +** from clear to set. In other words: ifconfig up. +** +** Returns: +** 0 success +** >0 f/w reported error +** <0 driver reported error +*/ +static int +acxpci_e_open(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + int result = OK; + + FN_ENTER; + + acx_sem_lock(adev); + + acx_init_task_scheduler(adev); + +/* TODO: pci_set_power_state(pdev, PCI_D0); ? */ + + /* request shared IRQ handler */ + if (request_irq(ndev->irq, acxpci_i_interrupt, IRQF_SHARED, ndev->name, ndev)) { + printk("%s: request_irq FAILED\n", ndev->name); + result = -EAGAIN; + goto done; + } + log(L_DEBUG|L_IRQ, "request_irq %d successful\n", ndev->irq); + + /* ifup device */ + acxpci_s_up(ndev); + + /* We don't currently have to do anything else. + * The setup of the MAC should be subsequently completed via + * the mlme commands. + * Higher layers know we're ready from dev->start==1 and + * dev->tbusy==0. Our rx path knows to pass up received/ + * frames because of dev->flags&IFF_UP is true. + */ +done: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acxpci_e_close +** +** Called as a result of SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP +** from set to clear. I.e. called by "ifconfig DEV down" +** +** Returns: +** 0 success +** >0 f/w reported error +** <0 driver reported error +*/ +static int +acxpci_e_close(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + acx_sem_lock(adev); + + /* ifdown device */ + CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); + if (netif_device_present(ndev)) { + acxpci_s_down(ndev); + } + + /* disable all IRQs, release shared IRQ handler */ + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + write_reg16(adev, IO_ACX_FEMR, 0x0); + free_irq(ndev->irq, ndev); + +/* TODO: pci_set_power_state(pdev, PCI_D3hot); ? */ + + /* We currently don't have to do anything else. + * Higher layers know we're not ready from dev->start==0 and + * dev->tbusy==1. Our rx path knows to not pass up received + * frames because of dev->flags&IFF_UP is false. + */ + acx_sem_unlock(adev); + + log(L_INIT, "closed device\n"); + FN_EXIT0; + return OK; +} + + +/*********************************************************************** +** acxpci_i_tx_timeout +** +** Called from network core. Must not sleep! +*/ +static void +acxpci_i_tx_timeout(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + unsigned int tx_num_cleaned; + + FN_ENTER; + + acx_lock(adev, flags); + + /* clean processed tx descs, they may have been completely full */ + tx_num_cleaned = acxpci_l_clean_txdesc(adev); + + /* nothing cleaned, yet (almost) no free buffers available? + * --> clean all tx descs, no matter which status!! + * Note that I strongly suspect that doing emergency cleaning + * may confuse the firmware. This is a last ditch effort to get + * ANYTHING to work again... + * + * TODO: it's best to simply reset & reinit hw from scratch... + */ + if ((adev->tx_free <= TX_EMERG_CLEAN) && (tx_num_cleaned == 0)) { + printk("%s: FAILED to free any of the many full tx buffers. " + "Switching to emergency freeing. " + "Please report!\n", ndev->name); + acxpci_l_clean_txdesc_emergency(adev); + } + + if (acx_queue_stopped(ndev) && (ACX_STATUS_4_ASSOCIATED == adev->status)) + acx_wake_queue(ndev, "after tx timeout"); + + /* stall may have happened due to radio drift, so recalib radio */ + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + + /* do unimportant work last */ + printk("%s: tx timeout!\n", ndev->name); + adev->stats.tx_errors++; + + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_i_set_multicast_list +** FIXME: most likely needs refinement +*/ +static void +acxpci_i_set_multicast_list(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + + FN_ENTER; + + acx_lock(adev, flags); + + /* firmwares don't have allmulti capability, + * so just use promiscuous mode instead in this case. */ + if (ndev->flags & (IFF_PROMISC|IFF_ALLMULTI)) { + SET_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); + CLEAR_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); + SET_BIT(adev->set_mask, SET_RXCONFIG); + /* let kernel know in case *we* needed to set promiscuous */ + ndev->flags |= (IFF_PROMISC|IFF_ALLMULTI); + } else { + CLEAR_BIT(adev->rx_config_1, RX_CFG1_RCV_PROMISCUOUS); + SET_BIT(adev->rx_config_1, RX_CFG1_FILTER_ALL_MULTI); + SET_BIT(adev->set_mask, SET_RXCONFIG); + ndev->flags &= ~(IFF_PROMISC|IFF_ALLMULTI); + } + + /* cannot update card settings directly here, atomic context */ + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*************************************************************** +** acxpci_l_process_rxdesc +** +** Called directly and only from the IRQ handler +*/ + +#if !ACX_DEBUG +static inline void log_rxbuffer(const acx_device_t *adev) {} +#else +static void +log_rxbuffer(const acx_device_t *adev) +{ + register const struct rxhostdesc *rxhostdesc; + int i; + /* no FN_ENTER here, we don't want that */ + + rxhostdesc = adev->rxhostdesc_start; + if (unlikely(!rxhostdesc)) return; + for (i = 0; i < RX_CNT; i++) { + if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL))) + printk("rx: buf %d full\n", i); + rxhostdesc++; + } +} +#endif + +static void +acxpci_l_process_rxdesc(acx_device_t *adev) +{ + register rxhostdesc_t *hostdesc; + unsigned count, tail; + + FN_ENTER; + + if (unlikely(acx_debug & L_BUFR)) + log_rxbuffer(adev); + + /* First, have a loop to determine the first descriptor that's + * full, just in case there's a mismatch between our current + * rx_tail and the full descriptor we're supposed to handle. */ + tail = adev->rx_tail; + count = RX_CNT; + while (1) { + hostdesc = &adev->rxhostdesc_start[tail]; + /* advance tail regardless of outcome of the below test */ + tail = (tail + 1) % RX_CNT; + + if ((hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + && (hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL))) + break; /* found it! */ + + if (unlikely(!--count)) /* hmm, no luck: all descs empty, bail out */ + goto end; + } + + /* now process descriptors, starting with the first we figured out */ + while (1) { + log(L_BUFR, "rx: tail=%u Ctl_16=%04X Status=%08X\n", + tail, hostdesc->Ctl_16, hostdesc->Status); + + acx_l_process_rxbuf(adev, hostdesc->data); + + hostdesc->Status = 0; + /* flush all writes before adapter sees CTL_HOSTOWN change */ + wmb(); + /* Host no longer owns this, needs to be LAST */ + CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + + /* ok, descriptor is handled, now check the next descriptor */ + hostdesc = &adev->rxhostdesc_start[tail]; + + /* if next descriptor is empty, then bail out */ + if (!(hostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + || !(hostdesc->Status & cpu_to_le32(DESC_STATUS_FULL))) + break; + + tail = (tail + 1) % RX_CNT; + } +end: + adev->rx_tail = tail; + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_i_interrupt +** +** IRQ handler (atomic context, must not sleep, blah, blah) +*/ + +/* scan is complete. all frames now on the receive queue are valid */ +#define INFO_SCAN_COMPLETE 0x0001 +#define INFO_WEP_KEY_NOT_FOUND 0x0002 +/* hw has been reset as the result of a watchdog timer timeout */ +#define INFO_WATCH_DOG_RESET 0x0003 +/* failed to send out NULL frame from PS mode notification to AP */ +/* recommended action: try entering 802.11 PS mode again */ +#define INFO_PS_FAIL 0x0004 +/* encryption/decryption process on a packet failed */ +#define INFO_IV_ICV_FAILURE 0x0005 + +/* Info mailbox format: +2 bytes: type +2 bytes: status +more bytes may follow + rumors say about status: + 0x0000 info available (set by hw) + 0x0001 information received (must be set by host) + 0x1000 info available, mailbox overflowed (messages lost) (set by hw) + but in practice we've seen: + 0x9000 when we did not set status to 0x0001 on prev message + 0x1001 when we did set it + 0x0000 was never seen + conclusion: this is really a bitfield: + 0x1000 is 'info available' bit + 'mailbox overflowed' bit is 0x8000, not 0x1000 + value of 0x0000 probably means that there are no messages at all + P.S. I dunno how in hell hw is supposed to notice that messages are lost - + it does NOT clear bit 0x0001, and this bit will probably stay forever set + after we set it once. Let's hope this will be fixed in firmware someday +*/ + +static void +handle_info_irq(acx_device_t *adev) +{ +#if ACX_DEBUG + static const char * const info_type_msg[] = { + "(unknown)", + "scan complete", + "WEP key not found", + "internal watchdog reset was done", + "failed to send powersave (NULL frame) notification to AP", + "encrypt/decrypt on a packet has failed", + "TKIP tx keys disabled", + "TKIP rx keys disabled", + "TKIP rx: key ID not found", + "???", + "???", + "???", + "???", + "???", + "???", + "???", + "TKIP IV value exceeds thresh" + }; +#endif + u32 info_type, info_status; + + info_type = readl(adev->info_area); + info_status = (info_type >> 16); + info_type = (u16)info_type; + + /* inform fw that we have read this info message */ + writel(info_type | 0x00010000, adev->info_area); + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_INFOACK); + write_flush(adev); + + log(L_CTL, "info_type:%04X info_status:%04X\n", + info_type, info_status); + + log(L_IRQ, "got Info IRQ: status %04X type %04X: %s\n", + info_status, info_type, + info_type_msg[(info_type >= VEC_SIZE(info_type_msg)) ? + 0 : info_type] + ); +} + + +static void +log_unusual_irq(u16 irqtype) { + /* + if (!printk_ratelimit()) + return; + */ + + printk("acx: got"); + if (irqtype & HOST_INT_RX_DATA) { + printk(" Rx_Data"); + } + /* HOST_INT_TX_COMPLETE */ + if (irqtype & HOST_INT_TX_XFER) { + printk(" Tx_Xfer"); + } + /* HOST_INT_RX_COMPLETE */ + if (irqtype & HOST_INT_DTIM) { + printk(" DTIM"); + } + if (irqtype & HOST_INT_BEACON) { + printk(" Beacon"); + } + if (irqtype & HOST_INT_TIMER) { + log(L_IRQ, " Timer"); + } + if (irqtype & HOST_INT_KEY_NOT_FOUND) { + printk(" Key_Not_Found"); + } + if (irqtype & HOST_INT_IV_ICV_FAILURE) { + printk(" IV_ICV_Failure (crypto)"); + } + /* HOST_INT_CMD_COMPLETE */ + /* HOST_INT_INFO */ + if (irqtype & HOST_INT_OVERFLOW) { + printk(" Overflow"); + } + if (irqtype & HOST_INT_PROCESS_ERROR) { + printk(" Process_Error"); + } + /* HOST_INT_SCAN_COMPLETE */ + if (irqtype & HOST_INT_FCS_THRESHOLD) { + printk(" FCS_Threshold"); + } + if (irqtype & HOST_INT_UNKNOWN) { + printk(" Unknown"); + } + printk(" IRQ(s)\n"); +} + + +static void +update_link_quality_led(acx_device_t *adev) +{ + int qual; + + qual = acx_signal_determine_quality(adev->wstats.qual.level, adev->wstats.qual.noise); + if (qual > adev->brange_max_quality) + qual = adev->brange_max_quality; + + if (time_after(jiffies, adev->brange_time_last_state_change + + (HZ/2 - HZ/2 * (unsigned long)qual / adev->brange_max_quality ) )) { + acxpci_l_power_led(adev, (adev->brange_last_state == 0)); + adev->brange_last_state ^= 1; /* toggle */ + adev->brange_time_last_state_change = jiffies; + } +} + + +#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* a la orinoco.c */ + +static irqreturn_t +acxpci_i_interrupt(int irq, void *dev_id) +{ + acx_device_t *adev; + unsigned long flags; + unsigned int irqcount = MAX_IRQLOOPS_PER_JIFFY; + register u16 irqtype; + u16 unmasked; + + adev = ndev2adev((struct net_device*)dev_id); + + /* LOCKING: can just spin_lock() since IRQs are disabled anyway. + * I am paranoid */ + acx_lock(adev, flags); + + unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR); + if (unlikely(0xffff == unmasked)) { + /* 0xffff value hints at missing hardware, + * so don't do anything. + * Not very clean, but other drivers do the same... */ + log(L_IRQ, "IRQ type:FFFF - device removed? IRQ_NONE\n"); + goto none; + } + + /* We will check only "interesting" IRQ types */ + irqtype = unmasked & ~adev->irq_mask; + if (!irqtype) { + /* We are on a shared IRQ line and it wasn't our IRQ */ + log(L_IRQ, "IRQ type:%04X, mask:%04X - all are masked, IRQ_NONE\n", + unmasked, adev->irq_mask); + goto none; + } + + /* Done here because IRQ_NONEs taking three lines of log + ** drive me crazy */ + FN_ENTER; + +#define IRQ_ITERATE 1 +#if IRQ_ITERATE +if (jiffies != adev->irq_last_jiffies) { + adev->irq_loops_this_jiffy = 0; + adev->irq_last_jiffies = jiffies; +} + +/* safety condition; we'll normally abort loop below + * in case no IRQ type occurred */ +while (likely(--irqcount)) { +#endif + /* ACK all IRQs ASAP */ + write_reg16(adev, IO_ACX_IRQ_ACK, 0xffff); + + log(L_IRQ, "IRQ type:%04X, mask:%04X, type & ~mask:%04X\n", + unmasked, adev->irq_mask, irqtype); + + /* Handle most important IRQ types first */ + if (irqtype & HOST_INT_RX_COMPLETE) { + log(L_IRQ, "got Rx_Complete IRQ\n"); + acxpci_l_process_rxdesc(adev); + } + if (irqtype & HOST_INT_TX_COMPLETE) { + log(L_IRQ, "got Tx_Complete IRQ\n"); + /* don't clean up on each Tx complete, wait a bit + * unless we're going towards full, in which case + * we do it immediately, too (otherwise we might lockup + * with a full Tx buffer if we go into + * acxpci_l_clean_txdesc() at a time when we won't wakeup + * the net queue in there for some reason...) */ + if (adev->tx_free <= TX_START_CLEAN) { +#if TX_CLEANUP_IN_SOFTIRQ + acx_schedule_task(adev, ACX_AFTER_IRQ_TX_CLEANUP); +#else + acxpci_l_clean_txdesc(adev); +#endif + } + } + + /* Less frequent ones */ + if (irqtype & (0 + | HOST_INT_CMD_COMPLETE + | HOST_INT_INFO + | HOST_INT_SCAN_COMPLETE + )) { + if (irqtype & HOST_INT_CMD_COMPLETE) { + log(L_IRQ, "got Command_Complete IRQ\n"); + /* save the state for the running issue_cmd() */ + SET_BIT(adev->irq_status, HOST_INT_CMD_COMPLETE); + } + if (irqtype & HOST_INT_INFO) { + handle_info_irq(adev); + } + if (irqtype & HOST_INT_SCAN_COMPLETE) { + log(L_IRQ, "got Scan_Complete IRQ\n"); + /* need to do that in process context */ + acx_schedule_task(adev, ACX_AFTER_IRQ_COMPLETE_SCAN); + /* remember that fw is not scanning anymore */ + SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); + } + } + + /* These we just log, but either they happen rarely + * or we keep them masked out */ + if (irqtype & (0 + | HOST_INT_RX_DATA + /* | HOST_INT_TX_COMPLETE */ + | HOST_INT_TX_XFER + /* | HOST_INT_RX_COMPLETE */ + | HOST_INT_DTIM + | HOST_INT_BEACON + | HOST_INT_TIMER + | HOST_INT_KEY_NOT_FOUND + | HOST_INT_IV_ICV_FAILURE + /* | HOST_INT_CMD_COMPLETE */ + /* | HOST_INT_INFO */ + | HOST_INT_OVERFLOW + | HOST_INT_PROCESS_ERROR + /* | HOST_INT_SCAN_COMPLETE */ + | HOST_INT_FCS_THRESHOLD + | HOST_INT_UNKNOWN + )) { + log_unusual_irq(irqtype); + } + +#if IRQ_ITERATE + unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR); + irqtype = unmasked & ~adev->irq_mask; + /* Bail out if no new IRQ bits or if all are masked out */ + if (!irqtype) + break; + + if (unlikely(++adev->irq_loops_this_jiffy > MAX_IRQLOOPS_PER_JIFFY)) { + printk(KERN_ERR "acx: too many interrupts per jiffy!\n"); + /* Looks like card floods us with IRQs! Try to stop that */ + write_reg16(adev, IO_ACX_IRQ_MASK, 0xffff); + /* This will short-circuit all future attempts to handle IRQ. + * We cant do much more... */ + adev->irq_mask = 0; + break; + } +} +#endif + /* Routine to perform blink with range */ + if (unlikely(adev->led_power == 2)) + update_link_quality_led(adev); + +/* handled: */ + /* write_flush(adev); - not needed, last op was read anyway */ + acx_unlock(adev, flags); + FN_EXIT0; + return IRQ_HANDLED; + +none: + acx_unlock(adev, flags); + return IRQ_NONE; +} + + +/*********************************************************************** +** acxpci_l_power_led +*/ +void +acxpci_l_power_led(acx_device_t *adev, int enable) +{ + u16 gpio_pled = IS_ACX111(adev) ? 0x0040 : 0x0800; + + /* A hack. Not moving message rate limiting to adev->xxx + * (it's only a debug message after all) */ + static int rate_limit = 0; + + if (rate_limit++ < 3) + log(L_IOCTL, "Please report in case toggling the power " + "LED doesn't work for your card!\n"); + if (enable) + write_reg16(adev, IO_ACX_GPIO_OUT, + read_reg16(adev, IO_ACX_GPIO_OUT) & ~gpio_pled); + else + write_reg16(adev, IO_ACX_GPIO_OUT, + read_reg16(adev, IO_ACX_GPIO_OUT) | gpio_pled); +} + + +/*********************************************************************** +** Ioctls +*/ + +/*********************************************************************** +*/ +int +acx111pci_ioctl_info( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ +#if ACX_DEBUG > 1 + acx_device_t *adev = ndev2adev(ndev); + rxdesc_t *rxdesc; + txdesc_t *txdesc; + rxhostdesc_t *rxhostdesc; + txhostdesc_t *txhostdesc; + struct acx111_ie_memoryconfig memconf; + struct acx111_ie_queueconfig queueconf; + unsigned long flags; + int i; + char memmap[0x34]; + char rxconfig[0x8]; + char fcserror[0x8]; + char ratefallback[0x5]; + + if ( !(acx_debug & (L_IOCTL|L_DEBUG)) ) + return OK; + /* using printk() since we checked debug flag already */ + + acx_sem_lock(adev); + + if (!IS_ACX111(adev)) { + printk("acx111-specific function called " + "with non-acx111 chip, aborting\n"); + goto end_ok; + } + + /* get Acx111 Memory Configuration */ + memset(&memconf, 0, sizeof(memconf)); + /* BTW, fails with 12 (Write only) error code. + ** Retained for easy testing of issue_cmd error handling :) */ + acx_s_interrogate(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG); + + /* get Acx111 Queue Configuration */ + memset(&queueconf, 0, sizeof(queueconf)); + acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); + + /* get Acx111 Memory Map */ + memset(memmap, 0, sizeof(memmap)); + acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP); + + /* get Acx111 Rx Config */ + memset(rxconfig, 0, sizeof(rxconfig)); + acx_s_interrogate(adev, &rxconfig, ACX1xx_IE_RXCONFIG); + + /* get Acx111 fcs error count */ + memset(fcserror, 0, sizeof(fcserror)); + acx_s_interrogate(adev, &fcserror, ACX1xx_IE_FCS_ERROR_COUNT); + + /* get Acx111 rate fallback */ + memset(ratefallback, 0, sizeof(ratefallback)); + acx_s_interrogate(adev, &ratefallback, ACX1xx_IE_RATE_FALLBACK); + + /* force occurrence of a beacon interrupt */ + /* TODO: comment why is this necessary */ + write_reg16(adev, IO_ACX_HINT_TRIG, HOST_INT_BEACON); + + /* dump Acx111 Mem Configuration */ + printk("dump mem config:\n" + "data read: %d, struct size: %d\n" + "Number of stations: %1X\n" + "Memory block size: %1X\n" + "tx/rx memory block allocation: %1X\n" + "count rx: %X / tx: %X queues\n" + "options %1X\n" + "fragmentation %1X\n" + "Rx Queue 1 Count Descriptors: %X\n" + "Rx Queue 1 Host Memory Start: %X\n" + "Tx Queue 1 Count Descriptors: %X\n" + "Tx Queue 1 Attributes: %X\n", + memconf.len, (int) sizeof(memconf), + memconf.no_of_stations, + memconf.memory_block_size, + memconf.tx_rx_memory_block_allocation, + memconf.count_rx_queues, memconf.count_tx_queues, + memconf.options, + memconf.fragmentation, + memconf.rx_queue1_count_descs, + acx2cpu(memconf.rx_queue1_host_rx_start), + memconf.tx_queue1_count_descs, + memconf.tx_queue1_attributes); + + /* dump Acx111 Queue Configuration */ + printk("dump queue head:\n" + "data read: %d, struct size: %d\n" + "tx_memory_block_address (from card): %X\n" + "rx_memory_block_address (from card): %X\n" + "rx1_queue address (from card): %X\n" + "tx1_queue address (from card): %X\n" + "tx1_queue attributes (from card): %X\n", + queueconf.len, (int) sizeof(queueconf), + queueconf.tx_memory_block_address, + queueconf.rx_memory_block_address, + queueconf.rx1_queue_address, + queueconf.tx1_queue_address, + queueconf.tx1_attributes); + + /* dump Acx111 Mem Map */ + printk("dump mem map:\n" + "data read: %d, struct size: %d\n" + "Code start: %X\n" + "Code end: %X\n" + "WEP default key start: %X\n" + "WEP default key end: %X\n" + "STA table start: %X\n" + "STA table end: %X\n" + "Packet template start: %X\n" + "Packet template end: %X\n" + "Queue memory start: %X\n" + "Queue memory end: %X\n" + "Packet memory pool start: %X\n" + "Packet memory pool end: %X\n" + "iobase: %p\n" + "iobase2: %p\n", + *((u16 *)&memmap[0x02]), (int) sizeof(memmap), + *((u32 *)&memmap[0x04]), + *((u32 *)&memmap[0x08]), + *((u32 *)&memmap[0x0C]), + *((u32 *)&memmap[0x10]), + *((u32 *)&memmap[0x14]), + *((u32 *)&memmap[0x18]), + *((u32 *)&memmap[0x1C]), + *((u32 *)&memmap[0x20]), + *((u32 *)&memmap[0x24]), + *((u32 *)&memmap[0x28]), + *((u32 *)&memmap[0x2C]), + *((u32 *)&memmap[0x30]), + adev->iobase, + adev->iobase2); + + /* dump Acx111 Rx Config */ + printk("dump rx config:\n" + "data read: %d, struct size: %d\n" + "rx config: %X\n" + "rx filter config: %X\n", + *((u16 *)&rxconfig[0x02]), (int) sizeof(rxconfig), + *((u16 *)&rxconfig[0x04]), + *((u16 *)&rxconfig[0x06])); + + /* dump Acx111 fcs error */ + printk("dump fcserror:\n" + "data read: %d, struct size: %d\n" + "fcserrors: %X\n", + *((u16 *)&fcserror[0x02]), (int) sizeof(fcserror), + *((u32 *)&fcserror[0x04])); + + /* dump Acx111 rate fallback */ + printk("dump rate fallback:\n" + "data read: %d, struct size: %d\n" + "ratefallback: %X\n", + *((u16 *)&ratefallback[0x02]), (int) sizeof(ratefallback), + *((u8 *)&ratefallback[0x04])); + + /* protect against IRQ */ + acx_lock(adev, flags); + + /* dump acx111 internal rx descriptor ring buffer */ + rxdesc = adev->rxdesc_start; + + /* loop over complete receive pool */ + if (rxdesc) for (i = 0; i < RX_CNT; i++) { + printk("\ndump internal rxdesc %d:\n" + "mem pos %p\n" + "next 0x%X\n" + "acx mem pointer (dynamic) 0x%X\n" + "CTL (dynamic) 0x%X\n" + "Rate (dynamic) 0x%X\n" + "RxStatus (dynamic) 0x%X\n" + "Mod/Pre (dynamic) 0x%X\n", + i, + rxdesc, + acx2cpu(rxdesc->pNextDesc), + acx2cpu(rxdesc->ACXMemPtr), + rxdesc->Ctl_8, + rxdesc->rate, + rxdesc->error, + rxdesc->SNR); + rxdesc++; + } + + /* dump host rx descriptor ring buffer */ + + rxhostdesc = adev->rxhostdesc_start; + + /* loop over complete receive pool */ + if (rxhostdesc) for (i = 0; i < RX_CNT; i++) { + printk("\ndump host rxdesc %d:\n" + "mem pos %p\n" + "buffer mem pos 0x%X\n" + "buffer mem offset 0x%X\n" + "CTL 0x%X\n" + "Length 0x%X\n" + "next 0x%X\n" + "Status 0x%X\n", + i, + rxhostdesc, + acx2cpu(rxhostdesc->data_phy), + rxhostdesc->data_offset, + le16_to_cpu(rxhostdesc->Ctl_16), + le16_to_cpu(rxhostdesc->length), + acx2cpu(rxhostdesc->desc_phy_next), + rxhostdesc->Status); + rxhostdesc++; + } + + /* dump acx111 internal tx descriptor ring buffer */ + txdesc = adev->txdesc_start; + + /* loop over complete transmit pool */ + if (txdesc) for (i = 0; i < TX_CNT; i++) { + printk("\ndump internal txdesc %d:\n" + "size 0x%X\n" + "mem pos %p\n" + "next 0x%X\n" + "acx mem pointer (dynamic) 0x%X\n" + "host mem pointer (dynamic) 0x%X\n" + "length (dynamic) 0x%X\n" + "CTL (dynamic) 0x%X\n" + "CTL2 (dynamic) 0x%X\n" + "Status (dynamic) 0x%X\n" + "Rate (dynamic) 0x%X\n", + i, + (int) sizeof(struct txdesc), + txdesc, + acx2cpu(txdesc->pNextDesc), + acx2cpu(txdesc->AcxMemPtr), + acx2cpu(txdesc->HostMemPtr), + le16_to_cpu(txdesc->total_length), + txdesc->Ctl_8, + txdesc->Ctl2_8, txdesc->error, + txdesc->u.r1.rate); + txdesc = advance_txdesc(adev, txdesc, 1); + } + + /* dump host tx descriptor ring buffer */ + + txhostdesc = adev->txhostdesc_start; + + /* loop over complete host send pool */ + if (txhostdesc) for (i = 0; i < TX_CNT * 2; i++) { + printk("\ndump host txdesc %d:\n" + "mem pos %p\n" + "buffer mem pos 0x%X\n" + "buffer mem offset 0x%X\n" + "CTL 0x%X\n" + "Length 0x%X\n" + "next 0x%X\n" + "Status 0x%X\n", + i, + txhostdesc, + acx2cpu(txhostdesc->data_phy), + txhostdesc->data_offset, + le16_to_cpu(txhostdesc->Ctl_16), + le16_to_cpu(txhostdesc->length), + acx2cpu(txhostdesc->desc_phy_next), + le32_to_cpu(txhostdesc->Status)); + txhostdesc++; + } + + /* write_reg16(adev, 0xb4, 0x4); */ + + acx_unlock(adev, flags); +end_ok: + + acx_sem_unlock(adev); +#endif /* ACX_DEBUG */ + return OK; +} + + +/*********************************************************************** +*/ +int +acx100pci_ioctl_set_phy_amp_bias( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + u16 gpio_old; + + if (!IS_ACX100(adev)) { + /* WARNING!!! + * Removing this check *might* damage + * hardware, since we're tweaking GPIOs here after all!!! + * You've been warned... + * WARNING!!! */ + printk("acx: sorry, setting bias level for non-acx100 " + "is not supported yet\n"); + return OK; + } + + if (*extra > 7) { + printk("acx: invalid bias parameter, range is 0-7\n"); + return -EINVAL; + } + + acx_sem_lock(adev); + + /* Need to lock accesses to [IO_ACX_GPIO_OUT]: + * IRQ handler uses it to update LED */ + acx_lock(adev, flags); + gpio_old = read_reg16(adev, IO_ACX_GPIO_OUT); + write_reg16(adev, IO_ACX_GPIO_OUT, (gpio_old & 0xf8ff) | ((u16)*extra << 8)); + acx_unlock(adev, flags); + + log(L_DEBUG, "gpio_old: 0x%04X\n", gpio_old); + printk("%s: PHY power amplifier bias: old:%d, new:%d\n", + ndev->name, + (gpio_old & 0x0700) >> 8, (unsigned char)*extra); + + acx_sem_unlock(adev); + + return OK; +} + + +/*************************************************************** +** acxpci_l_alloc_tx +** Actually returns a txdesc_t* ptr +** +** FIXME: in case of fragments, should allocate multiple descrs +** after figuring out how many we need and whether we still have +** sufficiently many. +*/ +tx_t* +acxpci_l_alloc_tx(acx_device_t *adev) +{ + struct txdesc *txdesc; + unsigned head; + u8 ctl8; + + FN_ENTER; + + if (unlikely(!adev->tx_free)) { + printk("acx: BUG: no free txdesc left\n"); + txdesc = NULL; + goto end; + } + + head = adev->tx_head; + txdesc = get_txdesc(adev, head); + ctl8 = txdesc->Ctl_8; + + /* 2005-10-11: there were several bug reports on this happening + ** but now cause seems to be understood & fixed */ + if (unlikely(DESC_CTL_HOSTOWN != (ctl8 & DESC_CTL_ACXDONE_HOSTOWN))) { + /* whoops, descr at current index is not free, so probably + * ring buffer already full */ + printk("acx: BUG: tx_head:%d Ctl8:0x%02X - failed to find " + "free txdesc\n", head, ctl8); + txdesc = NULL; + goto end; + } + + /* Needed in case txdesc won't be eventually submitted for tx */ + txdesc->Ctl_8 = DESC_CTL_ACXDONE_HOSTOWN; + + adev->tx_free--; + log(L_BUFT, "tx: got desc %u, %u remain\n", + head, adev->tx_free); + /* Keep a few free descs between head and tail of tx ring. + ** It is not absolutely needed, just feels safer */ + if (adev->tx_free < TX_STOP_QUEUE) { + log(L_BUF, "stop queue (%u tx desc left)\n", + adev->tx_free); + acx_stop_queue(adev->ndev, NULL); + } + + /* returning current descriptor, so advance to next free one */ + adev->tx_head = (head + 1) % TX_CNT; +end: + FN_EXIT0; + + return (tx_t*)txdesc; +} + + +/*********************************************************************** +*/ +void* +acxpci_l_get_txbuf(acx_device_t *adev, tx_t* tx_opaque) +{ + return get_txhostdesc(adev, (txdesc_t*)tx_opaque)->data; +} + + +/*********************************************************************** +** acxpci_l_tx_data +** +** Can be called from IRQ (rx -> (AP bridging or mgmt response) -> tx). +** Can be called from acx_i_start_xmit (data frames from net core). +** +** FIXME: in case of fragments, should loop over the number of +** pre-allocated tx descrs, properly setting up transfer data and +** CTL_xxx flags according to fragment number. +*/ +void +acxpci_l_tx_data(acx_device_t *adev, tx_t* tx_opaque, int len) +{ + txdesc_t *txdesc = (txdesc_t*)tx_opaque; + txhostdesc_t *hostdesc1, *hostdesc2; + client_t *clt; + u16 rate_cur; + u8 Ctl_8, Ctl2_8; + + FN_ENTER; + + /* fw doesn't tx such packets anyhow */ + if (unlikely(len < WLAN_HDR_A3_LEN)) + goto end; + + hostdesc1 = get_txhostdesc(adev, txdesc); + /* modify flag status in separate variable to be able to write it back + * in one big swoop later (also in order to have less device memory + * accesses) */ + Ctl_8 = txdesc->Ctl_8; + Ctl2_8 = 0; /* really need to init it to 0, not txdesc->Ctl2_8, it seems */ + + hostdesc2 = hostdesc1 + 1; + + /* DON'T simply set Ctl field to 0 here globally, + * it needs to maintain a consistent flag status (those are state flags!!), + * otherwise it may lead to severe disruption. Only set or reset particular + * flags at the exact moment this is needed... */ + + /* let chip do RTS/CTS handshaking before sending + * in case packet size exceeds threshold */ + if (len > adev->rts_threshold) + SET_BIT(Ctl2_8, DESC_CTL2_RTS); + else + CLEAR_BIT(Ctl2_8, DESC_CTL2_RTS); + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + clt = acx_l_sta_list_get(adev, ((wlan_hdr_t*)hostdesc1->data)->a1); + break; + case ACX_MODE_2_STA: + clt = adev->ap_client; + break; +#if 0 +/* testing was done on acx111: */ + case ACX_MODE_MONITOR: + SET_BIT(Ctl2_8, 0 +/* sends CTS to self before packet */ + + DESC_CTL2_SEQ /* don't increase sequence field */ +/* not working (looks like good fcs is still added) */ + + DESC_CTL2_FCS /* don't add the FCS */ +/* not tested */ + + DESC_CTL2_MORE_FRAG +/* not tested */ + + DESC_CTL2_RETRY /* don't increase retry field */ +/* not tested */ + + DESC_CTL2_POWER /* don't increase power mgmt. field */ +/* no effect */ + + DESC_CTL2_WEP /* encrypt this frame */ +/* not tested */ + + DESC_CTL2_DUR /* don't increase duration field */ + ); + /* fallthrough */ +#endif + default: /* ACX_MODE_OFF, ACX_MODE_MONITOR */ + clt = NULL; + break; + } + + rate_cur = clt ? clt->rate_cur : adev->rate_bcast; + if (unlikely(!rate_cur)) { + printk("acx: driver bug! bad ratemask\n"); + goto end; + } + + /* used in tx cleanup routine for auto rate and accounting: */ + put_txcr(adev, txdesc, clt, rate_cur); + + txdesc->total_length = cpu_to_le16(len); + hostdesc2->length = cpu_to_le16(len - WLAN_HDR_A3_LEN); + if (IS_ACX111(adev)) { + /* note that if !txdesc->do_auto, txrate->cur + ** has only one nonzero bit */ + txdesc->u.r2.rate111 = cpu_to_le16( + rate_cur + /* WARNING: I was never able to make it work with prism54 AP. + ** It was falling down to 1Mbit where shortpre is not applicable, + ** and not working at all at "5,11 basic rates only" setting. + ** I even didn't see tx packets in radio packet capture. + ** Disabled for now --vda */ + /*| ((clt->shortpre && clt->cur!=RATE111_1) ? RATE111_SHORTPRE : 0) */ + ); +#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS + /* should add this to rate111 above as necessary */ + | (clt->pbcc511 ? RATE111_PBCC511 : 0) +#endif + hostdesc1->length = cpu_to_le16(len); + } else { /* ACX100 */ + u8 rate_100 = clt ? clt->rate_100 : adev->rate_bcast100; + txdesc->u.r1.rate = rate_100; +#ifdef TODO_FIGURE_OUT_WHEN_TO_SET_THIS + if (clt->pbcc511) { + if (n == RATE100_5 || n == RATE100_11) + n |= RATE100_PBCC511; + } + + if (clt->shortpre && (clt->cur != RATE111_1)) + SET_BIT(Ctl_8, DESC_CTL_SHORT_PREAMBLE); /* set Short Preamble */ +#endif + /* set autodma and reclaim and 1st mpdu */ + SET_BIT(Ctl_8, DESC_CTL_AUTODMA | DESC_CTL_RECLAIM | DESC_CTL_FIRSTFRAG); +#if ACX_FRAGMENTATION + /* SET_BIT(Ctl2_8, DESC_CTL2_MORE_FRAG); cannot set it unconditionally, needs to be set for all non-last fragments */ +#endif + hostdesc1->length = cpu_to_le16(WLAN_HDR_A3_LEN); + } + /* don't need to clean ack/rts statistics here, already + * done on descr cleanup */ + + /* clears HOSTOWN and ACXDONE bits, thus telling that the descriptors + * are now owned by the acx100; do this as LAST operation */ + CLEAR_BIT(Ctl_8, DESC_CTL_ACXDONE_HOSTOWN); + /* flush writes before we release hostdesc to the adapter here */ + wmb(); + CLEAR_BIT(hostdesc1->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + CLEAR_BIT(hostdesc2->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + + /* write back modified flags */ + txdesc->Ctl2_8 = Ctl2_8; + txdesc->Ctl_8 = Ctl_8; + /* unused: txdesc->tx_time = cpu_to_le32(jiffies); */ + + /* flush writes before we tell the adapter that it's its turn now */ + mmiowb(); + write_reg16(adev, IO_ACX_INT_TRIG, INT_TRIG_TXPRC); + write_flush(adev); + + /* log the packet content AFTER sending it, + * in order to not delay sending any further than absolutely needed + * Do separate logs for acx100/111 to have human-readable rates */ + if (unlikely(acx_debug & (L_XFER|L_DATA))) { + u16 fc = ((wlan_hdr_t*)hostdesc1->data)->fc; + if (IS_ACX111(adev)) + printk("tx: pkt (%s): len %d " + "rate %04X%s status %u\n", + acx_get_packet_type_string(le16_to_cpu(fc)), len, + le16_to_cpu(txdesc->u.r2.rate111), + (le16_to_cpu(txdesc->u.r2.rate111) & RATE111_SHORTPRE) ? "(SPr)" : "", + adev->status); + else + printk("tx: pkt (%s): len %d rate %03u%s status %u\n", + acx_get_packet_type_string(fc), len, + txdesc->u.r1.rate, + (Ctl_8 & DESC_CTL_SHORT_PREAMBLE) ? "(SPr)" : "", + adev->status); + + if (acx_debug & L_DATA) { + printk("tx: 802.11 [%d]: ", len); + acx_dump_bytes(hostdesc1->data, len); + } + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_l_clean_txdesc +** +** This function resets the txdescs' status when the ACX100 +** signals the TX done IRQ (txdescs have been processed), starting with +** the pool index of the descriptor which we would use next, +** in order to make sure that we can be as fast as possible +** in filling new txdescs. +** Everytime we get called we know where the next packet to be cleaned is. +*/ + +#if !ACX_DEBUG +static inline void log_txbuffer(const acx_device_t *adev) {} +#else +static void +log_txbuffer(acx_device_t *adev) +{ + txdesc_t *txdesc; + int i; + + /* no FN_ENTER here, we don't want that */ + /* no locks here, since it's entirely non-critical code */ + txdesc = adev->txdesc_start; + if (unlikely(!txdesc)) return; + printk("tx: desc->Ctl8's:"); + for (i = 0; i < TX_CNT; i++) { + printk(" %02X", txdesc->Ctl_8); + txdesc = advance_txdesc(adev, txdesc, 1); + } + printk("\n"); +} +#endif + + +static void +handle_tx_error(acx_device_t *adev, u8 error, unsigned int finger) +{ + const char *err = "unknown error"; + + /* hmm, should we handle this as a mask + * of *several* bits? + * For now I think only caring about + * individual bits is ok... */ + switch (error) { + case 0x01: + err = "no Tx due to error in other fragment"; + adev->wstats.discard.fragment++; + break; + case 0x02: + err = "Tx aborted"; + adev->stats.tx_aborted_errors++; + break; + case 0x04: + err = "Tx desc wrong parameters"; + adev->wstats.discard.misc++; + break; + case 0x08: + err = "WEP key not found"; + adev->wstats.discard.misc++; + break; + case 0x10: + err = "MSDU lifetime timeout? - try changing " + "'iwconfig retry lifetime XXX'"; + adev->wstats.discard.misc++; + break; + case 0x20: + err = "excessive Tx retries due to either distance " + "too high or unable to Tx or Tx frame error - " + "try changing 'iwconfig txpower XXX' or " + "'sens'itivity or 'retry'"; + adev->wstats.discard.retries++; + /* Tx error 0x20 also seems to occur on + * overheating, so I'm not sure whether we + * actually want to do aggressive radio recalibration, + * since people maybe won't notice then that their hardware + * is slowly getting cooked... + * Or is it still a safe long distance from utter + * radio non-functionality despite many radio recalibs + * to final destructive overheating of the hardware? + * In this case we really should do recalib here... + * I guess the only way to find out is to do a + * potentially fatal self-experiment :-\ + * Or maybe only recalib in case we're using Tx + * rate auto (on errors switching to lower speed + * --> less heat?) or 802.11 power save mode? + * + * ok, just do it. */ + if (++adev->retry_errors_msg_ratelimit % 4 == 0) { + if (adev->retry_errors_msg_ratelimit <= 20) { + printk("%s: several excessive Tx " + "retry errors occurred, attempting " + "to recalibrate radio. Radio " + "drift might be caused by increasing " + "card temperature, please check the card " + "before it's too late!\n", + adev->ndev->name); + if (adev->retry_errors_msg_ratelimit == 20) + printk("disabling above message\n"); + } + + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + } + break; + case 0x40: + err = "Tx buffer overflow"; + adev->stats.tx_fifo_errors++; + break; + case 0x80: + /* possibly ACPI C-state powersaving related!!! + * (DMA timeout due to excessively high wakeup + * latency after C-state activation!?) + * Disable C-State powersaving and try again, + * then PLEASE REPORT, I'm VERY interested in + * whether my theory is correct that this is + * actually the problem here. + * In that case, use new Linux idle wakeup latency + * requirements kernel API to prevent this issue. */ + err = "DMA error"; + adev->wstats.discard.misc++; + break; + } + adev->stats.tx_errors++; + if (adev->stats.tx_errors <= 20) + printk("%s: tx error 0x%02X, buf %02u! (%s)\n", + adev->ndev->name, error, finger, err); + else + printk("%s: tx error 0x%02X, buf %02u!\n", + adev->ndev->name, error, finger); +} + + +unsigned int +acxpci_l_clean_txdesc(acx_device_t *adev) +{ + txdesc_t *txdesc; + unsigned finger; + int num_cleaned; + u16 r111; + u8 error, ack_failures, rts_failures, rts_ok, r100; + + FN_ENTER; + + if (unlikely(acx_debug & L_DEBUG)) + log_txbuffer(adev); + + log(L_BUFT, "tx: cleaning up bufs from %u\n", adev->tx_tail); + + /* We know first descr which is not free yet. We advance it as far + ** as we see correct bits set in following descs (if next desc + ** is NOT free, we shouldn't advance at all). We know that in + ** front of tx_tail may be "holes" with isolated free descs. + ** We will catch up when all intermediate descs will be freed also */ + + finger = adev->tx_tail; + num_cleaned = 0; + while (likely(finger != adev->tx_head)) { + txdesc = get_txdesc(adev, finger); + + /* If we allocated txdesc on tx path but then decided + ** to NOT use it, then it will be left as a free "bubble" + ** in the "allocated for tx" part of the ring. + ** We may meet it on the next ring pass here. */ + + /* stop if not marked as "tx finished" and "host owned" */ + if ((txdesc->Ctl_8 & DESC_CTL_ACXDONE_HOSTOWN) + != DESC_CTL_ACXDONE_HOSTOWN) { + if (unlikely(!num_cleaned)) { /* maybe remove completely */ + log(L_BUFT, "clean_txdesc: tail isn't free. " + "tail:%d head:%d\n", + adev->tx_tail, adev->tx_head); + } + break; + } + + /* remember desc values... */ + error = txdesc->error; + ack_failures = txdesc->ack_failures; + rts_failures = txdesc->rts_failures; + rts_ok = txdesc->rts_ok; + r100 = txdesc->u.r1.rate; + r111 = le16_to_cpu(txdesc->u.r2.rate111); + + /* need to check for certain error conditions before we + * clean the descriptor: we still need valid descr data here */ + if (unlikely(0x30 & error)) { + /* only send IWEVTXDROP in case of retry or lifetime exceeded; + * all other errors mean we screwed up locally */ + union iwreq_data wrqu; + wlan_hdr_t *hdr; + txhostdesc_t *hostdesc; + + hostdesc = get_txhostdesc(adev, txdesc); + hdr = (wlan_hdr_t *)hostdesc->data; + MAC_COPY(wrqu.addr.sa_data, hdr->a1); + wireless_send_event(adev->ndev, IWEVTXDROP, &wrqu, NULL); + } + + /* ...and free the desc */ + txdesc->error = 0; + txdesc->ack_failures = 0; + txdesc->rts_failures = 0; + txdesc->rts_ok = 0; + /* signal host owning it LAST, since ACX already knows that this + ** descriptor is finished since it set Ctl_8 accordingly. */ + txdesc->Ctl_8 = DESC_CTL_HOSTOWN; + + adev->tx_free++; + num_cleaned++; + + if ((adev->tx_free >= TX_START_QUEUE) + && (adev->status == ACX_STATUS_4_ASSOCIATED) + && (acx_queue_stopped(adev->ndev)) + ) { + log(L_BUF, "tx: wake queue (avail. Tx desc %u)\n", + adev->tx_free); + acx_wake_queue(adev->ndev, NULL); + } + + /* do error checking, rate handling and logging + * AFTER having done the work, it's faster */ + + /* do rate handling */ + if (adev->rate_auto) { + struct client *clt = get_txc(adev, txdesc); + if (clt) { + u16 cur = get_txr(adev, txdesc); + if (clt->rate_cur == cur) { + acx_l_handle_txrate_auto(adev, clt, + cur, /* intended rate */ + r100, r111, /* actually used rate */ + (error & 0x30), /* was there an error? */ + TX_CNT + TX_CLEAN_BACKLOG - adev->tx_free); + } + } + } + + if (unlikely(error)) + handle_tx_error(adev, error, finger); + + if (IS_ACX111(adev)) + log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u r111=%04X\n", + finger, ack_failures, rts_failures, rts_ok, r111); + else + log(L_BUFT, "tx: cleaned %u: !ACK=%u !RTS=%u RTS=%u rate=%u\n", + finger, ack_failures, rts_failures, rts_ok, r100); + + /* update pointer for descr to be cleaned next */ + finger = (finger + 1) % TX_CNT; + } + + /* remember last position */ + adev->tx_tail = finger; +/* end: */ + FN_EXIT1(num_cleaned); + return num_cleaned; +} + +/* clean *all* Tx descriptors, and regardless of their previous state. + * Used for brute-force reset handling. */ +void +acxpci_l_clean_txdesc_emergency(acx_device_t *adev) +{ + txdesc_t *txdesc; + int i; + + FN_ENTER; + + for (i = 0; i < TX_CNT; i++) { + txdesc = get_txdesc(adev, i); + + /* free it */ + txdesc->ack_failures = 0; + txdesc->rts_failures = 0; + txdesc->rts_ok = 0; + txdesc->error = 0; + txdesc->Ctl_8 = DESC_CTL_HOSTOWN; + } + + adev->tx_free = TX_CNT; + + FN_EXIT0; +} + + +/*********************************************************************** +** acxpci_s_create_tx_host_desc_queue +*/ + +static void* +allocate(acx_device_t *adev, size_t size, dma_addr_t *phy, const char *msg) +{ + void *ptr; + + ptr = dma_alloc_coherent(adev->pdev ? &adev->pdev->dev : NULL, + size, phy, GFP_KERNEL); + + if (ptr) { + log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n", + msg, (int)size, ptr, (unsigned long long)*phy); + memset(ptr, 0, size); + return ptr; + } + printk(KERN_ERR "acx: %s allocation FAILED (%d bytes)\n", + msg, (int)size); + return NULL; +} + + +static int +acxpci_s_create_tx_host_desc_queue(acx_device_t *adev) +{ + txhostdesc_t *hostdesc; + u8 *txbuf; + dma_addr_t hostdesc_phy; + dma_addr_t txbuf_phy; + int i; + + FN_ENTER; + + /* allocate TX buffer */ + adev->txbuf_area_size = TX_CNT * WLAN_A4FR_MAXLEN_WEP_FCS; + adev->txbuf_start = allocate(adev, adev->txbuf_area_size, + &adev->txbuf_startphy, "txbuf_start"); + if (!adev->txbuf_start) + goto fail; + + /* allocate the TX host descriptor queue pool */ + adev->txhostdesc_area_size = TX_CNT * 2*sizeof(*hostdesc); + adev->txhostdesc_start = allocate(adev, adev->txhostdesc_area_size, + &adev->txhostdesc_startphy, "txhostdesc_start"); + if (!adev->txhostdesc_start) + goto fail; + /* check for proper alignment of TX host descriptor pool */ + if ((long) adev->txhostdesc_start & 3) { + printk("acx: driver bug: dma alloc returns unaligned address\n"); + goto fail; + } + + hostdesc = adev->txhostdesc_start; + hostdesc_phy = adev->txhostdesc_startphy; + txbuf = adev->txbuf_start; + txbuf_phy = adev->txbuf_startphy; + +#if 0 +/* Each tx buffer is accessed by hardware via +** txdesc -> txhostdesc(s) -> txbuffer(s). +** We use only one txhostdesc per txdesc, but it looks like +** acx111 is buggy: it accesses second txhostdesc +** (via hostdesc.desc_phy_next field) even if +** txdesc->length == hostdesc->length and thus +** entire packet was placed into first txhostdesc. +** Due to this bug acx111 hangs unless second txhostdesc +** has le16_to_cpu(hostdesc.length) = 3 (or larger) +** Storing NULL into hostdesc.desc_phy_next +** doesn't seem to help. +** +** Update: although it worked on Xterasys XN-2522g +** with len=3 trick, WG311v2 is even more bogus, doesn't work. +** Keeping this code (#ifdef'ed out) for documentational purposes. +*/ + for (i = 0; i < TX_CNT*2; i++) { + hostdesc_phy += sizeof(*hostdesc); + if (!(i & 1)) { + hostdesc->data_phy = cpu2acx(txbuf_phy); + /* hostdesc->data_offset = ... */ + /* hostdesc->reserved = ... */ + hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN); + /* hostdesc->length = ... */ + hostdesc->desc_phy_next = cpu2acx(hostdesc_phy); + hostdesc->pNext = ptr2acx(NULL); + /* hostdesc->Status = ... */ + /* below: non-hardware fields */ + hostdesc->data = txbuf; + + txbuf += WLAN_A4FR_MAXLEN_WEP_FCS; + txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS; + } else { + /* hostdesc->data_phy = ... */ + /* hostdesc->data_offset = ... */ + /* hostdesc->reserved = ... */ + /* hostdesc->Ctl_16 = ... */ + hostdesc->length = cpu_to_le16(3); /* bug workaround */ + /* hostdesc->desc_phy_next = ... */ + /* hostdesc->pNext = ... */ + /* hostdesc->Status = ... */ + /* below: non-hardware fields */ + /* hostdesc->data = ... */ + } + hostdesc++; + } +#endif +/* We initialize two hostdescs so that they point to adjacent +** memory areas. Thus txbuf is really just a contiguous memory area */ + for (i = 0; i < TX_CNT*2; i++) { + hostdesc_phy += sizeof(*hostdesc); + + hostdesc->data_phy = cpu2acx(txbuf_phy); + /* done by memset(0): hostdesc->data_offset = 0; */ + /* hostdesc->reserved = ... */ + hostdesc->Ctl_16 = cpu_to_le16(DESC_CTL_HOSTOWN); + /* hostdesc->length = ... */ + hostdesc->desc_phy_next = cpu2acx(hostdesc_phy); + /* done by memset(0): hostdesc->pNext = ptr2acx(NULL); */ + /* hostdesc->Status = ... */ + /* ->data is a non-hardware field: */ + hostdesc->data = txbuf; + + if (!(i & 1)) { + txbuf += WLAN_HDR_A3_LEN; + txbuf_phy += WLAN_HDR_A3_LEN; + } else { + txbuf += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN; + txbuf_phy += WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN; + } + hostdesc++; + } + hostdesc--; + hostdesc->desc_phy_next = cpu2acx(adev->txhostdesc_startphy); + + FN_EXIT1(OK); + return OK; +fail: + printk("acx: create_tx_host_desc_queue FAILED\n"); + /* dealloc will be done by free function on error case */ + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*************************************************************** +** acxpci_s_create_rx_host_desc_queue +*/ +/* the whole size of a data buffer (header plus data body) + * plus 32 bytes safety offset at the end */ +#define RX_BUFFER_SIZE (sizeof(rxbuffer_t) + 32) + +static int +acxpci_s_create_rx_host_desc_queue(acx_device_t *adev) +{ + rxhostdesc_t *hostdesc; + rxbuffer_t *rxbuf; + dma_addr_t hostdesc_phy; + dma_addr_t rxbuf_phy; + int i; + + FN_ENTER; + + /* allocate the RX host descriptor queue pool */ + adev->rxhostdesc_area_size = RX_CNT * sizeof(*hostdesc); + adev->rxhostdesc_start = allocate(adev, adev->rxhostdesc_area_size, + &adev->rxhostdesc_startphy, "rxhostdesc_start"); + if (!adev->rxhostdesc_start) + goto fail; + /* check for proper alignment of RX host descriptor pool */ + if ((long) adev->rxhostdesc_start & 3) { + printk("acx: driver bug: dma alloc returns unaligned address\n"); + goto fail; + } + + /* allocate Rx buffer pool which will be used by the acx + * to store the whole content of the received frames in it */ + adev->rxbuf_area_size = RX_CNT * RX_BUFFER_SIZE; + adev->rxbuf_start = allocate(adev, adev->rxbuf_area_size, + &adev->rxbuf_startphy, "rxbuf_start"); + if (!adev->rxbuf_start) + goto fail; + + rxbuf = adev->rxbuf_start; + rxbuf_phy = adev->rxbuf_startphy; + hostdesc = adev->rxhostdesc_start; + hostdesc_phy = adev->rxhostdesc_startphy; + + /* don't make any popular C programming pointer arithmetic mistakes + * here, otherwise I'll kill you... + * (and don't dare asking me why I'm warning you about that...) */ + for (i = 0; i < RX_CNT; i++) { + hostdesc->data = rxbuf; + hostdesc->data_phy = cpu2acx(rxbuf_phy); + hostdesc->length = cpu_to_le16(RX_BUFFER_SIZE); + CLEAR_BIT(hostdesc->Ctl_16, cpu_to_le16(DESC_CTL_HOSTOWN)); + rxbuf++; + rxbuf_phy += sizeof(*rxbuf); + hostdesc_phy += sizeof(*hostdesc); + hostdesc->desc_phy_next = cpu2acx(hostdesc_phy); + hostdesc++; + } + hostdesc--; + hostdesc->desc_phy_next = cpu2acx(adev->rxhostdesc_startphy); + FN_EXIT1(OK); + return OK; +fail: + printk("acx: create_rx_host_desc_queue FAILED\n"); + /* dealloc will be done by free function on error case */ + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*************************************************************** +** acxpci_s_create_hostdesc_queues +*/ +int +acxpci_s_create_hostdesc_queues(acx_device_t *adev) +{ + int result; + result = acxpci_s_create_tx_host_desc_queue(adev); + if (OK != result) return result; + result = acxpci_s_create_rx_host_desc_queue(adev); + return result; +} + + +/*************************************************************** +** acxpci_create_tx_desc_queue +*/ +static void +acxpci_create_tx_desc_queue(acx_device_t *adev, u32 tx_queue_start) +{ + txdesc_t *txdesc; + txhostdesc_t *hostdesc; + dma_addr_t hostmemptr; + u32 mem_offs; + int i; + + FN_ENTER; + + if (IS_ACX100(adev)) + adev->txdesc_size = sizeof(*txdesc); + else + /* the acx111 txdesc is 4 bytes larger */ + adev->txdesc_size = sizeof(*txdesc) + 4; + + adev->txdesc_start = (txdesc_t *) (adev->iobase2 + tx_queue_start); + + log(L_DEBUG, "adev->iobase2=%p\n" + "tx_queue_start=%08X\n" + "adev->txdesc_start=%p\n", + adev->iobase2, + tx_queue_start, + adev->txdesc_start); + + adev->tx_free = TX_CNT; + /* done by memset: adev->tx_head = 0; */ + /* done by memset: adev->tx_tail = 0; */ + txdesc = adev->txdesc_start; + mem_offs = tx_queue_start; + hostmemptr = adev->txhostdesc_startphy; + hostdesc = adev->txhostdesc_start; + + if (IS_ACX111(adev)) { + /* ACX111 has a preinitialized Tx buffer! */ + /* loop over whole send pool */ + /* FIXME: do we have to do the hostmemptr stuff here?? */ + for (i = 0; i < TX_CNT; i++) { + txdesc->HostMemPtr = ptr2acx(hostmemptr); + txdesc->Ctl_8 = DESC_CTL_HOSTOWN; + /* reserve two (hdr desc and payload desc) */ + hostdesc += 2; + hostmemptr += 2 * sizeof(*hostdesc); + txdesc = advance_txdesc(adev, txdesc, 1); + } + } else { + /* ACX100 Tx buffer needs to be initialized by us */ + /* clear whole send pool. sizeof is safe here (we are acx100) */ + memset(adev->txdesc_start, 0, TX_CNT * sizeof(*txdesc)); + + /* loop over whole send pool */ + for (i = 0; i < TX_CNT; i++) { + log(L_DEBUG, "configure card tx descriptor: 0x%p, " + "size: 0x%X\n", txdesc, adev->txdesc_size); + + /* pointer to hostdesc memory */ + txdesc->HostMemPtr = ptr2acx(hostmemptr); + /* initialise ctl */ + txdesc->Ctl_8 = ( DESC_CTL_HOSTOWN | DESC_CTL_RECLAIM + | DESC_CTL_AUTODMA | DESC_CTL_FIRSTFRAG); + /* done by memset(0): txdesc->Ctl2_8 = 0; */ + /* point to next txdesc */ + txdesc->pNextDesc = cpu2acx(mem_offs + adev->txdesc_size); + /* reserve two (hdr desc and payload desc) */ + hostdesc += 2; + hostmemptr += 2 * sizeof(*hostdesc); + /* go to the next one */ + mem_offs += adev->txdesc_size; + /* ++ is safe here (we are acx100) */ + txdesc++; + } + /* go back to the last one */ + txdesc--; + /* and point to the first making it a ring buffer */ + txdesc->pNextDesc = cpu2acx(tx_queue_start); + } + FN_EXIT0; +} + + +/*************************************************************** +** acxpci_create_rx_desc_queue +*/ +static void +acxpci_create_rx_desc_queue(acx_device_t *adev, u32 rx_queue_start) +{ + rxdesc_t *rxdesc; + u32 mem_offs; + int i; + + FN_ENTER; + + /* done by memset: adev->rx_tail = 0; */ + + /* ACX111 doesn't need any further config: preconfigures itself. + * Simply print ring buffer for debugging */ + if (IS_ACX111(adev)) { + /* rxdesc_start already set here */ + + adev->rxdesc_start = (rxdesc_t *) ((u8 *)adev->iobase2 + rx_queue_start); + + rxdesc = adev->rxdesc_start; + for (i = 0; i < RX_CNT; i++) { + log(L_DEBUG, "rx descriptor %d @ 0x%p\n", i, rxdesc); + rxdesc = adev->rxdesc_start = (rxdesc_t *) + (adev->iobase2 + acx2cpu(rxdesc->pNextDesc)); + } + } else { + /* we didn't pre-calculate rxdesc_start in case of ACX100 */ + /* rxdesc_start should be right AFTER Tx pool */ + adev->rxdesc_start = (rxdesc_t *) + ((u8 *) adev->txdesc_start + (TX_CNT * sizeof(txdesc_t))); + /* NB: sizeof(txdesc_t) above is valid because we know + ** we are in if (acx100) block. Beware of cut-n-pasting elsewhere! + ** acx111's txdesc is larger! */ + + memset(adev->rxdesc_start, 0, RX_CNT * sizeof(*rxdesc)); + + /* loop over whole receive pool */ + rxdesc = adev->rxdesc_start; + mem_offs = rx_queue_start; + for (i = 0; i < RX_CNT; i++) { + log(L_DEBUG, "rx descriptor @ 0x%p\n", rxdesc); + rxdesc->Ctl_8 = DESC_CTL_RECLAIM | DESC_CTL_AUTODMA; + /* point to next rxdesc */ + rxdesc->pNextDesc = cpu2acx(mem_offs + sizeof(*rxdesc)); + /* go to the next one */ + mem_offs += sizeof(*rxdesc); + rxdesc++; + } + /* go to the last one */ + rxdesc--; + + /* and point to the first making it a ring buffer */ + rxdesc->pNextDesc = cpu2acx(rx_queue_start); + } + FN_EXIT0; +} + + +/*************************************************************** +** acxpci_create_desc_queues +*/ +void +acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start) +{ + acxpci_create_tx_desc_queue(adev, tx_queue_start); + acxpci_create_rx_desc_queue(adev, rx_queue_start); +} + + +/*************************************************************** +** acxpci_s_proc_diag_output +*/ +char* +acxpci_s_proc_diag_output(char *p, acx_device_t *adev) +{ + const char *rtl, *thd, *ttl; + rxhostdesc_t *rxhostdesc; + txdesc_t *txdesc; + int i; + + FN_ENTER; + + p += sprintf(p, "** Rx buf **\n"); + rxhostdesc = adev->rxhostdesc_start; + if (rxhostdesc) for (i = 0; i < RX_CNT; i++) { + rtl = (i == adev->rx_tail) ? " [tail]" : ""; + if ((rxhostdesc->Ctl_16 & cpu_to_le16(DESC_CTL_HOSTOWN)) + && (rxhostdesc->Status & cpu_to_le32(DESC_STATUS_FULL)) ) + p += sprintf(p, "%02u FULL%s\n", i, rtl); + else + p += sprintf(p, "%02u empty%s\n", i, rtl); + rxhostdesc++; + } + p += sprintf(p, "** Tx buf (free %d, Linux netqueue %s) **\n", adev->tx_free, + acx_queue_stopped(adev->ndev) ? "STOPPED" : "running"); + txdesc = adev->txdesc_start; + if (txdesc) for (i = 0; i < TX_CNT; i++) { + thd = (i == adev->tx_head) ? " [head]" : ""; + ttl = (i == adev->tx_tail) ? " [tail]" : ""; + if (txdesc->Ctl_8 & DESC_CTL_ACXDONE) + p += sprintf(p, "%02u free (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl); + else + p += sprintf(p, "%02u tx (%02X)%s%s\n", i, txdesc->Ctl_8, thd, ttl); + txdesc = advance_txdesc(adev, txdesc, 1); + } + p += sprintf(p, + "\n" + "** PCI data **\n" + "txbuf_start %p, txbuf_area_size %u, txbuf_startphy %08llx\n" + "txdesc_size %u, txdesc_start %p\n" + "txhostdesc_start %p, txhostdesc_area_size %u, txhostdesc_startphy %08llx\n" + "rxdesc_start %p\n" + "rxhostdesc_start %p, rxhostdesc_area_size %u, rxhostdesc_startphy %08llx\n" + "rxbuf_start %p, rxbuf_area_size %u, rxbuf_startphy %08llx\n", + adev->txbuf_start, adev->txbuf_area_size, + (unsigned long long)adev->txbuf_startphy, + adev->txdesc_size, adev->txdesc_start, + adev->txhostdesc_start, adev->txhostdesc_area_size, + (unsigned long long)adev->txhostdesc_startphy, + adev->rxdesc_start, + adev->rxhostdesc_start, adev->rxhostdesc_area_size, + (unsigned long long)adev->rxhostdesc_startphy, + adev->rxbuf_start, adev->rxbuf_area_size, + (unsigned long long)adev->rxbuf_startphy); + + FN_EXIT0; + return p; +} + + +/*********************************************************************** +*/ +int +acxpci_proc_eeprom_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + int i; + + FN_ENTER; + + for (i = 0; i < 0x400; i++) { + acxpci_read_eeprom_byte(adev, i, p++); + } + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +*/ +void +acxpci_set_interrupt_mask(acx_device_t *adev) +{ + if (IS_ACX111(adev)) { + adev->irq_mask = (u16) ~(0 + /* | HOST_INT_RX_DATA */ + | HOST_INT_TX_COMPLETE + /* | HOST_INT_TX_XFER */ + | HOST_INT_RX_COMPLETE + /* | HOST_INT_DTIM */ + /* | HOST_INT_BEACON */ + /* | HOST_INT_TIMER */ + /* | HOST_INT_KEY_NOT_FOUND */ + | HOST_INT_IV_ICV_FAILURE + | HOST_INT_CMD_COMPLETE + | HOST_INT_INFO + /* | HOST_INT_OVERFLOW */ + /* | HOST_INT_PROCESS_ERROR */ + | HOST_INT_SCAN_COMPLETE + | HOST_INT_FCS_THRESHOLD + /* | HOST_INT_UNKNOWN */ + ); + /* Or else acx100 won't signal cmd completion, right? */ + adev->irq_mask_off = (u16)~( HOST_INT_CMD_COMPLETE ); /* 0xfdff */ + } else { + adev->irq_mask = (u16) ~(0 + /* | HOST_INT_RX_DATA */ + | HOST_INT_TX_COMPLETE + /* | HOST_INT_TX_XFER */ + | HOST_INT_RX_COMPLETE + /* | HOST_INT_DTIM */ + /* | HOST_INT_BEACON */ + /* | HOST_INT_TIMER */ + /* | HOST_INT_KEY_NOT_FOUND */ + /* | HOST_INT_IV_ICV_FAILURE */ + | HOST_INT_CMD_COMPLETE + | HOST_INT_INFO + /* | HOST_INT_OVERFLOW */ + /* | HOST_INT_PROCESS_ERROR */ + | HOST_INT_SCAN_COMPLETE + /* | HOST_INT_FCS_THRESHOLD */ + /* | HOST_INT_UNKNOWN */ + ); + adev->irq_mask_off = (u16)~( HOST_INT_UNKNOWN ); /* 0x7fff */ + } +} + + +/*********************************************************************** +*/ +int +acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm) +{ + /* since it can be assumed that at least the Maxim radio has a + * maximum power output of 20dBm and since it also can be + * assumed that these values drive the DAC responsible for + * setting the linear Tx level, I'd guess that these values + * should be the corresponding linear values for a dBm value, + * in other words: calculate the values from that formula: + * Y [dBm] = 10 * log (X [mW]) + * then scale the 0..63 value range onto the 1..100mW range (0..20 dBm) + * and you're done... + * Hopefully that's ok, but you never know if we're actually + * right... (especially since Windows XP doesn't seem to show + * actual Tx dBm values :-P) */ + + /* NOTE: on Maxim, value 30 IS 30mW, and value 10 IS 10mW - so the + * values are EXACTLY mW!!! Not sure about RFMD and others, + * though... */ + static const u8 dbm2val_maxim[21] = { + 63, 63, 63, 62, + 61, 61, 60, 60, + 59, 58, 57, 55, + 53, 50, 47, 43, + 38, 31, 23, 13, + 0 + }; + static const u8 dbm2val_rfmd[21] = { + 0, 0, 0, 1, + 2, 2, 3, 3, + 4, 5, 6, 8, + 10, 13, 16, 20, + 25, 32, 41, 50, + 63 + }; + const u8 *table; + + switch (adev->radio_type) { + case RADIO_MAXIM_0D: + table = &dbm2val_maxim[0]; + break; + case RADIO_RFMD_11: + case RADIO_RALINK_15: + table = &dbm2val_rfmd[0]; + break; + default: + printk("%s: unknown/unsupported radio type, " + "cannot modify tx power level yet!\n", + adev->ndev->name); + return NOT_OK; + } + printk("%s: changing radio power level to %u dBm (%u)\n", + adev->ndev->name, level_dbm, table[level_dbm]); + acxpci_s_write_phy_reg(adev, 0x11, table[level_dbm]); + return OK; +} + + +/*********************************************************************** +** Data for init_module/cleanup_module +*/ +static DEFINE_PCI_DEVICE_TABLE(acxpci_id_tbl) = { + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1100A, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = CHIPTYPE_ACX100, + }, + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1100B, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = CHIPTYPE_ACX100, + }, + { + .vendor = PCI_VENDOR_ID_TI, + .device = PCI_DEVICE_ID_TI_TNETW1130, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .driver_data = CHIPTYPE_ACX111, + }, + { + .vendor = 0, + .device = 0, + .subvendor = 0, + .subdevice = 0, + .driver_data = 0, + } +}; + +MODULE_DEVICE_TABLE(pci, acxpci_id_tbl); + +static struct pci_driver acxpci_driver = { + .name = "acx_pci", + .id_table = acxpci_id_tbl, + .probe = acxpci_e_probe, + .remove = __devexit_p(acxpci_e_remove), +#ifdef CONFIG_PM + .suspend = acxpci_e_suspend, + .resume = acxpci_e_resume +#endif /* CONFIG_PM */ +}; + + +/*********************************************************************** +** acxpci_e_init_module +** +** Module initialization routine, called once at module load time +*/ +int __init +acxpci_e_init_module(void) +{ + int res; + + FN_ENTER; + +#if (ACX_IO_WIDTH==32) + printk("acx: compiled to use 32bit I/O access. " + "I/O timing issues might occur, such as " + "non-working firmware upload. Report them\n"); +#else + printk("acx: compiled to use 16bit I/O access only " + "(compatibility mode)\n"); +#endif + +#ifdef __LITTLE_ENDIAN +#define ENDIANNESS_STRING "running on a little-endian CPU\n" +#else +#define ENDIANNESS_STRING "running on a BIG-ENDIAN CPU\n" +#endif + log(L_INIT, + ENDIANNESS_STRING + "PCI module " ACX_RELEASE " initialized, " + "waiting for cards to probe...\n" + ); + + res = pci_register_driver(&acxpci_driver); + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acxpci_e_cleanup_module +** +** Called at module unload time. This is our last chance to +** clean up after ourselves. +*/ +void __exit +acxpci_e_cleanup_module(void) +{ + FN_ENTER; + + pci_unregister_driver(&acxpci_driver); + + FN_EXIT0; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx_struct.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx_struct.h @@ -0,0 +1,2049 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** Forward declarations of types +*/ +typedef struct tx tx_t; +typedef struct acx_device acx_device_t; +typedef struct client client_t; +typedef struct rxdesc rxdesc_t; +typedef struct txdesc txdesc_t; +typedef struct rxhostdesc rxhostdesc_t; +typedef struct txhostdesc txhostdesc_t; + + +/*********************************************************************** +** Debug / log functionality +*/ +enum { + L_LOCK = (ACX_DEBUG>1)*0x0001, /* locking debug log */ + L_INIT = (ACX_DEBUG>0)*0x0002, /* special card initialization logging */ + L_IRQ = (ACX_DEBUG>0)*0x0004, /* interrupt stuff */ + L_ASSOC = (ACX_DEBUG>0)*0x0008, /* assocation (network join) and station log */ + L_FUNC = (ACX_DEBUG>1)*0x0020, /* logging of function enter / leave */ + L_XFER = (ACX_DEBUG>1)*0x0080, /* logging of transfers and mgmt */ + L_DATA = (ACX_DEBUG>1)*0x0100, /* logging of transfer data */ + L_DEBUG = (ACX_DEBUG>1)*0x0200, /* log of debug info */ + L_IOCTL = (ACX_DEBUG>0)*0x0400, /* log ioctl calls */ + L_CTL = (ACX_DEBUG>1)*0x0800, /* log of low-level ctl commands */ + L_BUFR = (ACX_DEBUG>1)*0x1000, /* debug rx buffer mgmt (ring buffer etc.) */ + L_XFER_BEACON = (ACX_DEBUG>1)*0x2000, /* also log beacon packets */ + L_BUFT = (ACX_DEBUG>1)*0x4000, /* debug tx buffer mgmt (ring buffer etc.) */ + L_USBRXTX = (ACX_DEBUG>0)*0x8000, /* debug USB rx/tx operations */ + L_BUF = L_BUFR + L_BUFT, + L_ANY = 0xffff +}; + +#if ACX_DEBUG +extern unsigned int acx_debug; +#else +enum { acx_debug = 0 }; +#endif + +extern char firmware_ver[]; + + +/*********************************************************************** +** Random helpers +*/ +#define ACX_PACKED __attribute__ ((packed)) + +#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0])) + +/* Use worker_queues for 2.5/2.6 kernels and queue tasks for 2.4 kernels + (used for the 'bottom half' of the interrupt routine) */ + +#include +#define USE_WORKER_TASKS +#define WORK_STRUCT struct work_struct +#define SCHEDULE_WORK schedule_work +#define FLUSH_SCHEDULED_WORK flush_scheduled_work + + +/*********************************************************************** +** Constants +*/ +#define OK 0 +#define NOT_OK 1 + +/* The supported chip models */ +#define CHIPTYPE_ACX100 1 +#define CHIPTYPE_ACX111 2 + +#define IS_ACX100(adev) ((adev)->chip_type == CHIPTYPE_ACX100) +#define IS_ACX111(adev) ((adev)->chip_type == CHIPTYPE_ACX111) + +/* Supported interfaces */ +#define DEVTYPE_PCI 0 +#define DEVTYPE_USB 1 + +#if defined(CONFIG_NET_ACX_PCI) + #if !defined(CONFIG_NET_ACX_USB) + #define IS_PCI(adev) 1 + #else + #define IS_PCI(adev) ((adev)->dev_type == DEVTYPE_PCI) + #endif +#else + #define IS_PCI(adev) 0 +#endif + +#if defined(CONFIG_NET_ACX_USB) + #if !defined(CONFIG_NET_ACX_PCI) + #define IS_USB(adev) 1 + #else + #define IS_USB(adev) ((adev)->dev_type == DEVTYPE_USB) + #endif +#else + #define IS_USB(adev) 0 +#endif + +/* Driver defaults */ +#define DEFAULT_DTIM_INTERVAL 10 +/* used to be 2048, but FreeBSD driver changed it to 4096 to work properly +** in noisy wlans */ +#define DEFAULT_MSDU_LIFETIME 4096 +#define DEFAULT_RTS_THRESHOLD 2312 /* max. size: disable RTS mechanism */ +#define DEFAULT_BEACON_INTERVAL 100 + +#define ACX100_BAP_DATALEN_MAX 4096 +#define ACX100_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ +#define ACX100_RIDDATA_MAXLEN ACX100_RID_GUESSING_MAXLEN + +/* Support Constants */ +/* Radio type names, found in Win98 driver's TIACXLN.INF */ +#define RADIO_MAXIM_0D 0x0d +#define RADIO_RFMD_11 0x11 +#define RADIO_RALINK_15 0x15 +/* used in ACX111 cards (WG311v2, WL-121, ...): */ +#define RADIO_RADIA_16 0x16 +/* most likely *sometimes* used in ACX111 cards: */ +#define RADIO_UNKNOWN_17 0x17 +/* FwRad19.bin was found in a Safecom driver; must be an ACX111 radio: */ +#define RADIO_UNKNOWN_19 0x19 +#define RADIO_UNKNOWN_1B 0x1b /* radio in SafeCom SWLUT-54125 USB adapter; entirely unknown!! */ + +/* Controller Commands */ +/* can be found in table cmdTable in firmware "Rev. 1.5.0" (FW150) */ +#define ACX1xx_CMD_RESET 0x00 +#define ACX1xx_CMD_INTERROGATE 0x01 +#define ACX1xx_CMD_CONFIGURE 0x02 +#define ACX1xx_CMD_ENABLE_RX 0x03 +#define ACX1xx_CMD_ENABLE_TX 0x04 +#define ACX1xx_CMD_DISABLE_RX 0x05 +#define ACX1xx_CMD_DISABLE_TX 0x06 +#define ACX1xx_CMD_FLUSH_QUEUE 0x07 +#define ACX1xx_CMD_SCAN 0x08 +#define ACX1xx_CMD_STOP_SCAN 0x09 +#define ACX1xx_CMD_CONFIG_TIM 0x0a +#define ACX1xx_CMD_JOIN 0x0b +#define ACX1xx_CMD_WEP_MGMT 0x0c +#ifdef OLD_FIRMWARE_VERSIONS +#define ACX100_CMD_HALT 0x0e /* mapped to unknownCMD in FW150 */ +#else +#define ACX1xx_CMD_MEM_READ 0x0d +#define ACX1xx_CMD_MEM_WRITE 0x0e +#endif +#define ACX1xx_CMD_SLEEP 0x0f +#define ACX1xx_CMD_WAKE 0x10 +#define ACX1xx_CMD_UNKNOWN_11 0x11 /* mapped to unknownCMD in FW150 */ +#define ACX100_CMD_INIT_MEMORY 0x12 +#define ACX1FF_CMD_DISABLE_RADIO 0x12 /* new firmware? TNETW1450? */ +#define ACX1xx_CMD_CONFIG_BEACON 0x13 +#define ACX1xx_CMD_CONFIG_PROBE_RESPONSE 0x14 +#define ACX1xx_CMD_CONFIG_NULL_DATA 0x15 +#define ACX1xx_CMD_CONFIG_PROBE_REQUEST 0x16 +#define ACX1xx_CMD_FCC_TEST 0x17 +#define ACX1xx_CMD_RADIOINIT 0x18 +#define ACX111_CMD_RADIOCALIB 0x19 +#define ACX1FF_CMD_NOISE_HISTOGRAM 0x1c /* new firmware? TNETW1450? */ +#define ACX1FF_CMD_RX_RESET 0x1d /* new firmware? TNETW1450? */ +#define ACX1FF_CMD_LNA_CONTROL 0x20 /* new firmware? TNETW1450? */ +#define ACX1FF_CMD_CONTROL_DBG_TRACE 0x21 /* new firmware? TNETW1450? */ + +/* 'After Interrupt' Commands */ +#define ACX_AFTER_IRQ_CMD_STOP_SCAN 0x01 +#define ACX_AFTER_IRQ_CMD_ASSOCIATE 0x02 +#define ACX_AFTER_IRQ_CMD_RADIO_RECALIB 0x04 +#define ACX_AFTER_IRQ_UPDATE_CARD_CFG 0x08 +#define ACX_AFTER_IRQ_TX_CLEANUP 0x10 +#define ACX_AFTER_IRQ_COMPLETE_SCAN 0x20 +#define ACX_AFTER_IRQ_RESTART_SCAN 0x40 + +/*********************************************************************** +** Tx/Rx buffer sizes and watermarks +** +** This will alloc and use DMAable buffers of +** WLAN_A4FR_MAXLEN_WEP_FCS * (RX_CNT + TX_CNT) bytes +** RX/TX_CNT=32 -> ~150k DMA buffers +** RX/TX_CNT=16 -> ~75k DMA buffers +** +** 2005-10-10: reduced memory usage by lowering both to 16 +*/ +#define RX_CNT 16 +#define TX_CNT 16 + +/* we clean up txdescs when we have N free txdesc: */ +#define TX_CLEAN_BACKLOG (TX_CNT/4) +#define TX_START_CLEAN (TX_CNT - TX_CLEAN_BACKLOG) +#define TX_EMERG_CLEAN 2 +/* we stop queue if we have < N free txbufs: */ +#define TX_STOP_QUEUE 3 +/* we start queue if we have >= N free txbufs: */ +#define TX_START_QUEUE 5 + +/*********************************************************************** +** Interrogate/Configure cmd constants +** +** NB: length includes JUST the data part of the IE +** (does not include size of the (type,len) pair) +** +** TODO: seems that acx100, acx100usb, acx111 have some differences, +** fix code with regard to this! +*/ + +#define DEF_IE(name, val, len) enum { ACX##name=val, ACX##name##_LEN=len } + +/* Information Elements: Network Parameters, Static Configuration Entities */ +/* these are handled by real_cfgtable in firmware "Rev 1.5.0" (FW150) */ +DEF_IE(1xx_IE_UNKNOWN_00 ,0x0000, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(100_IE_ACX_TIMER ,0x0001, 0x10); +DEF_IE(1xx_IE_POWER_MGMT ,0x0002, 0x06); /* TNETW1450: length 0x18!! */ +DEF_IE(1xx_IE_QUEUE_CONFIG ,0x0003, 0x1c); +DEF_IE(100_IE_BLOCK_SIZE ,0x0004, 0x02); +DEF_IE(1FF_IE_SLOT_TIME ,0x0004, 0x08); /* later firmware versions only? */ +DEF_IE(1xx_IE_MEMORY_CONFIG_OPTIONS ,0x0005, 0x14); +DEF_IE(1FF_IE_QUEUE_HEAD ,0x0005, 0x14 /* FIXME: length? */); +DEF_IE(1xx_IE_RATE_FALLBACK ,0x0006, 0x01); /* TNETW1450: length 2 */ +DEF_IE(100_IE_WEP_OPTIONS ,0x0007, 0x03); +DEF_IE(111_IE_RADIO_BAND ,0x0007, -1); +DEF_IE(1FF_IE_TIMING_CFG ,0x0007, -1); /* later firmware versions; TNETW1450 only? */ +DEF_IE(100_IE_SSID ,0x0008, 0x20); /* huh? */ +DEF_IE(1xx_IE_MEMORY_MAP ,0x0008, 0x28); /* huh? TNETW1450 has length 0x40!! */ +DEF_IE(1xx_IE_SCAN_STATUS ,0x0009, 0x04); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1xx_IE_ASSOC_ID ,0x000a, 0x02); +DEF_IE(1xx_IE_UNKNOWN_0B ,0x000b, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1FF_IE_TX_POWER_LEVEL_TABLE ,0x000b, 0x18); /* later firmware versions; TNETW1450 only? */ +DEF_IE(100_IE_UNKNOWN_0C ,0x000c, -1); /* very small implementation in FW150! */ +/* ACX100 has an equivalent struct in the cmd mailbox directly after reset. + * 0x14c seems extremely large, will trash stack on failure (memset!) + * in case of small input struct --> OOPS! */ +DEF_IE(111_IE_CONFIG_OPTIONS ,0x000c, 0x14c); +DEF_IE(1xx_IE_FWREV ,0x000d, 0x18); +DEF_IE(1xx_IE_FCS_ERROR_COUNT ,0x000e, 0x04); +DEF_IE(1xx_IE_MEDIUM_USAGE ,0x000f, 0x08); +DEF_IE(1xx_IE_RXCONFIG ,0x0010, 0x04); +DEF_IE(100_IE_UNKNOWN_11 ,0x0011, -1); /* NONBINARY: large implementation in FW150! link quality readings or so? */ +DEF_IE(111_IE_QUEUE_THRESH ,0x0011, -1); +DEF_IE(100_IE_UNKNOWN_12 ,0x0012, -1); /* NONBINARY: VERY large implementation in FW150!! */ +DEF_IE(111_IE_BSS_POWER_SAVE ,0x0012, /* -1 */ 2); +DEF_IE(1xx_IE_FIRMWARE_STATISTICS ,0x0013, 0x9c); /* TNETW1450: length 0x134!! */ +DEF_IE(1FF_IE_RX_INTR_CONFIG ,0x0014, 0x14); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1xx_IE_FEATURE_CONFIG ,0x0015, 0x08); +DEF_IE(111_IE_KEY_CHOOSE ,0x0016, 0x04); /* for rekeying. really len=4?? */ +DEF_IE(1FF_IE_MISC_CONFIG_TABLE ,0x0017, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_WONE_CONFIG ,0x0018, -1); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_TID_CONFIG ,0x001a, 0x2c); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_CALIB_ASSESSMENT ,0x001e, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_BEACON_FILTER_OPTIONS ,0x001f, 0x02); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_LOW_RSSI_THRESH_OPT ,0x0020, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_NOISE_HISTOGRAM_RESULTS ,0x0021, 0x30); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_PACKET_DETECT_THRESH ,0x0023, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_TX_CONFIG_OPTIONS ,0x0024, 0x04); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_CCA_THRESHOLD ,0x0025, 0x02); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_EVENT_MASK ,0x0026, 0x08); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_DTIM_PERIOD ,0x0027, 0x02); /* later firmware versions, TNETW1450 only? */ +DEF_IE(1FF_IE_ACI_CONFIG_SET ,0x0029, 0x06); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(1FF_IE_EEPROM_VER ,0x0030, 0x04); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(1xx_IE_DOT11_STATION_ID ,0x1001, 0x06); +DEF_IE(100_IE_DOT11_UNKNOWN_1002 ,0x1002, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(111_IE_DOT11_FRAG_THRESH ,0x1002, -1); /* mapped to cfgInvalid in FW150; TNETW1450 has length 2!! */ +DEF_IE(100_IE_DOT11_BEACON_PERIOD ,0x1003, 0x02); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1xx_IE_DOT11_DTIM_PERIOD ,0x1004, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1FF_IE_DOT11_MAX_RX_LIFETIME ,0x1004, -1); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(1xx_IE_DOT11_SHORT_RETRY_LIMIT ,0x1005, 0x01); /* TNETW1450: length 2 */ +DEF_IE(1xx_IE_DOT11_LONG_RETRY_LIMIT ,0x1006, 0x01); /* TNETW1450: length 2 */ +DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE ,0x1007, 0x20); /* configure default keys; TNETW1450 has length 0x24!! */ +DEF_IE(1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME ,0x1008, 0x04); +DEF_IE(1xx_IE_DOT11_GROUP_ADDR ,0x1009, -1); +DEF_IE(1xx_IE_DOT11_CURRENT_REG_DOMAIN ,0x100a, 0x02); +/* It's harmless to have larger struct. Use USB case always. */ +DEF_IE(1xx_IE_DOT11_CURRENT_ANTENNA ,0x100b, 0x02); /* in fact len=1 for PCI */ +DEF_IE(1xx_IE_DOT11_UNKNOWN_100C ,0x100c, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1xx_IE_DOT11_TX_POWER_LEVEL ,0x100d, 0x01); /* TNETW1450 has length 2!! */ +DEF_IE(1xx_IE_DOT11_CURRENT_CCA_MODE ,0x100e, 0x02); /* in fact len=1 for PCI */ +/* USB doesn't return anything - len==0?! */ +DEF_IE(100_IE_DOT11_ED_THRESHOLD ,0x100f, 0x04); +DEF_IE(1xx_IE_DOT11_WEP_DEFAULT_KEY_SET ,0x1010, 0x01); /* set default key ID; TNETW1450: length 2 */ +DEF_IE(100_IE_DOT11_UNKNOWN_1011 ,0x1011, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(1FF_IE_DOT11_CURR_5GHZ_REGDOM ,0x1011, -1); /* later firmware versions; maybe TNETW1450 only? */ +DEF_IE(100_IE_DOT11_UNKNOWN_1012 ,0x1012, -1); /* mapped to cfgInvalid in FW150 */ +DEF_IE(100_IE_DOT11_UNKNOWN_1013 ,0x1013, -1); /* mapped to cfgInvalid in FW150 */ + +#if 0 +/* Experimentally obtained on acx100, fw 1.9.8.b +** -1 means that fw returned 'invalid IE' +** 0200 FC00 nnnn... are test read contents: u16 type, u16 len, data +** (AA are poison bytes marking bytes not written by fw) +** +** Looks like acx100 fw does not update len field (thus len=256-4=FC here) +** A number of IEs seem to trash type,len fields +** IEs marked 'huge' return gobs of data (no poison bytes remain) +*/ +DEF_IE(100_IE_INVAL_00, 0x0000, -1); +DEF_IE(100_IE_INVAL_01, 0x0001, -1); /* IE_ACX_TIMER, len=16 on older fw */ +DEF_IE(100_IE_POWER_MGMT, 0x0002, 4); /* 0200FC00 00040000 AAAAAAAA */ +DEF_IE(100_IE_QUEUE_CONFIG, 0x0003, 28); /* 0300FC00 48060000 9CAD0000 0101AAAA DCB00000 E4B00000 9CAA0000 00AAAAAA */ +DEF_IE(100_IE_BLOCK_SIZE, 0x0004, 2); /* 0400FC00 0001AAAA AAAAAAAA AAAAAAAA */ +/* write only: */ +DEF_IE(100_IE_MEMORY_CONFIG_OPTIONS, 0x0005, 20); +DEF_IE(100_IE_RATE_FALLBACK, 0x0006, 1); /* 0600FC00 00AAAAAA AAAAAAAA AAAAAAAA */ +/* write only: */ +DEF_IE(100_IE_WEP_OPTIONS, 0x0007, 3); +DEF_IE(100_IE_MEMORY_MAP, 0x0008, 40); /* huge: 0800FC00 30000000 6CA20000 70A20000... */ +/* gives INVAL on read: */ +DEF_IE(100_IE_SCAN_STATUS, 0x0009, -1); +DEF_IE(100_IE_ASSOC_ID, 0x000a, 2); /* huge: 0A00FC00 00000000 01040800 00000000... */ +DEF_IE(100_IE_INVAL_0B, 0x000b, -1); +/* 'command rejected': */ +DEF_IE(100_IE_CONFIG_OPTIONS, 0x000c, -3); +DEF_IE(100_IE_FWREV, 0x000d, 24); /* 0D00FC00 52657620 312E392E 382E6200 AAAAAAAA AAAAAAAA 05050201 AAAAAAAA */ +DEF_IE(100_IE_FCS_ERROR_COUNT, 0x000e, 4); +DEF_IE(100_IE_MEDIUM_USAGE, 0x000f, 8); /* E41F0000 2D780300 FCC91300 AAAAAAAA */ +DEF_IE(100_IE_RXCONFIG, 0x0010, 4); /* 1000FC00 00280000 AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_QUEUE_THRESH, 0x0011, 12); /* 1100FC00 AAAAAAAA 00000000 00000000 */ +DEF_IE(100_IE_BSS_POWER_SAVE, 0x0012, 1); /* 1200FC00 00AAAAAA AAAAAAAA AAAAAAAA */ +/* read only, variable len */ +DEF_IE(100_IE_FIRMWARE_STATISTICS, 0x0013, 256); /* 0000AC00 00000000 ... */ +DEF_IE(100_IE_INT_CONFIG, 0x0014, 20); /* 00000000 00000000 00000000 00000000 5D74D105 00000000 AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_FEATURE_CONFIG, 0x0015, 8); /* 1500FC00 16000000 AAAAAAAA AAAAAAAA */ +/* returns 'invalid MAC': */ +DEF_IE(100_IE_KEY_CHOOSE, 0x0016, -4); +DEF_IE(100_IE_INVAL_17, 0x0017, -1); +DEF_IE(100_IE_UNKNOWN_18, 0x0018, 0); /* null len?! 1800FC00 AAAAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_UNKNOWN_19, 0x0019, 256); /* huge: 1900FC00 9C1F00EA FEFFFFEA FEFFFFEA... */ +DEF_IE(100_IE_INVAL_1A, 0x001A, -1); + +DEF_IE(100_IE_DOT11_INVAL_1000, 0x1000, -1); +DEF_IE(100_IE_DOT11_STATION_ID, 0x1001, 6); /* huge: 0110FC00 58B10E2F 03000000 00000000... */ +DEF_IE(100_IE_DOT11_INVAL_1002, 0x1002, -1); +DEF_IE(100_IE_DOT11_INVAL_1003, 0x1003, -1); +DEF_IE(100_IE_DOT11_INVAL_1004, 0x1004, -1); +DEF_IE(100_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1); +DEF_IE(100_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1); +/* write only: */ +DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, 32); +DEF_IE(100_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4); /* huge: 0810FC00 00020000 F4010000 00000000... */ +/* undoc but returns something */ +DEF_IE(100_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* huge: 0910FC00 00000000 00000000 00000000... */ +DEF_IE(100_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1); /* 0A10FC00 30AAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_CURRENT_ANTENNA, 0x100b, 1); /* 0B10FC00 8FAAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_INVAL_100C, 0x100c, -1); +DEF_IE(100_IE_DOT11_TX_POWER_LEVEL, 0x100d, 2); /* 00000000 0100AAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_CURRENT_CCA_MODE, 0x100e, 1); /* 0E10FC00 0DAAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_ED_THRESHOLD, 0x100f, 4); /* 0F10FC00 70000000 AAAAAAAA AAAAAAAA */ +/* set default key ID */ +DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1); /* 1010FC00 00AAAAAA AAAAAAAA AAAAAAAA */ +DEF_IE(100_IE_DOT11_INVAL_1011, 0x1011, -1); +DEF_IE(100_IE_DOT11_INVAL_1012, 0x1012, -1); +DEF_IE(100_IE_DOT11_INVAL_1013, 0x1013, -1); +DEF_IE(100_IE_DOT11_UNKNOWN_1014, 0x1014, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1015, 0x1015, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1016, 0x1016, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1017, 0x1017, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1018, 0x1018, 256); /* huge */ +DEF_IE(100_IE_DOT11_UNKNOWN_1019, 0x1019, 256); /* huge */ +#endif + +#if 0 +/* Experimentally obtained on PCI acx111 Xterasys XN-2522g, fw 1.2.1.34 +** -1 means that fw returned 'invalid IE' +** 0400 0800 nnnn... are test read contents: u16 type, u16 len, data +** (AA are poison bytes marking bytes not written by fw) +** +** Looks like acx111 fw reports real len! +*/ +DEF_IE(111_IE_INVAL_00, 0x0000, -1); +DEF_IE(111_IE_INVAL_01, 0x0001, -1); +DEF_IE(111_IE_POWER_MGMT, 0x0002, 12); +/* write only, variable len: 12 + rxqueue_cnt*8 + txqueue_cnt*4: */ +DEF_IE(111_IE_MEMORY_CONFIG, 0x0003, 24); +DEF_IE(111_IE_BLOCK_SIZE, 0x0004, 8); /* 04000800 AA00AAAA AAAAAAAA */ +/* variable len: 8 + rxqueue_cnt*8 + txqueue_cnt*8: */ +DEF_IE(111_IE_QUEUE_HEAD, 0x0005, 24); +DEF_IE(111_IE_RATE_FALLBACK, 0x0006, 1); +/* acx100 name:WEP_OPTIONS */ +/* said to have len:1 (not true, actually returns 12 bytes): */ +DEF_IE(111_IE_RADIO_BAND, 0x0007, 12); /* 07000C00 AAAA1F00 FF03AAAA AAAAAAAA */ +DEF_IE(111_IE_MEMORY_MAP, 0x0008, 48); +/* said to have len:4, but gives INVAL on read: */ +DEF_IE(111_IE_SCAN_STATUS, 0x0009, -1); +DEF_IE(111_IE_ASSOC_ID, 0x000a, 2); +/* write only, len is not known: */ +DEF_IE(111_IE_UNKNOWN_0B, 0x000b, 0); +/* read only, variable len. I see 67 byte reads: */ +DEF_IE(111_IE_CONFIG_OPTIONS, 0x000c, 67); /* 0C004300 01160500 ... */ +DEF_IE(111_IE_FWREV, 0x000d, 24); +DEF_IE(111_IE_FCS_ERROR_COUNT, 0x000e, 4); +DEF_IE(111_IE_MEDIUM_USAGE, 0x000f, 8); +DEF_IE(111_IE_RXCONFIG, 0x0010, 4); +DEF_IE(111_IE_QUEUE_THRESH, 0x0011, 12); +DEF_IE(111_IE_BSS_POWER_SAVE, 0x0012, 1); +/* read only, variable len. I see 240 byte reads: */ +DEF_IE(111_IE_FIRMWARE_STATISTICS, 0x0013, 240); /* 1300F000 00000000 ... */ +/* said to have len=17. looks like fw pads it to 20: */ +DEF_IE(111_IE_INT_CONFIG, 0x0014, 20); /* 14001400 00000000 00000000 00000000 00000000 00000000 */ +DEF_IE(111_IE_FEATURE_CONFIG, 0x0015, 8); +/* said to be name:KEY_INDICATOR, len:4, but gives INVAL on read: */ +DEF_IE(111_IE_KEY_CHOOSE, 0x0016, -1); +/* said to have len:4, but in fact returns 8: */ +DEF_IE(111_IE_MAX_USB_XFR, 0x0017, 8); /* 17000800 00014000 00000000 */ +DEF_IE(111_IE_INVAL_18, 0x0018, -1); +DEF_IE(111_IE_INVAL_19, 0x0019, -1); +/* undoc but returns something: */ +/* huh, fw indicates len=20 but uses 4 more bytes in buffer??? */ +DEF_IE(111_IE_UNKNOWN_1A, 0x001A, 20); /* 1A001400 AA00AAAA 0000020F FF030000 00020000 00000007 04000000 */ + +DEF_IE(111_IE_DOT11_INVAL_1000, 0x1000, -1); +DEF_IE(111_IE_DOT11_STATION_ID, 0x1001, 6); +DEF_IE(111_IE_DOT11_FRAG_THRESH, 0x1002, 2); +/* acx100 only? gives INVAL on read: */ +DEF_IE(111_IE_DOT11_BEACON_PERIOD, 0x1003, -1); +/* said to be MAX_RECV_MSDU_LIFETIME: */ +DEF_IE(111_IE_DOT11_DTIM_PERIOD, 0x1004, 4); +DEF_IE(111_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1); +DEF_IE(111_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1); +/* acx100 only? gives INVAL on read: */ +DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, -1); +DEF_IE(111_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4); +/* undoc but returns something. maybe it's 2 multicast MACs to listen to? */ +DEF_IE(111_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* 09100C00 00000000 00000000 00000000 */ +DEF_IE(111_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1); +DEF_IE(111_IE_DOT11_CURRENT_ANTENNA, 0x100b, 2); +DEF_IE(111_IE_DOT11_INVAL_100C, 0x100c, -1); +DEF_IE(111_IE_DOT11_TX_POWER_LEVEL, 0x100d, 1); +/* said to have len=1 but gives INVAL on read: */ +DEF_IE(111_IE_DOT11_CURRENT_CCA_MODE, 0x100e, -1); +/* said to have len=4 but gives INVAL on read: */ +DEF_IE(111_IE_DOT11_ED_THRESHOLD, 0x100f, -1); +/* set default key ID. write only: */ +DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1); +/* undoc but returns something: */ +DEF_IE(111_IE_DOT11_UNKNOWN_1011, 0x1011, 1); /* 11100100 20 */ +DEF_IE(111_IE_DOT11_INVAL_1012, 0x1012, -1); +DEF_IE(111_IE_DOT11_INVAL_1013, 0x1013, -1); +#endif + + +/*********************************************************************** +**Information Frames Structures +*/ + +/* Used in beacon frames and the like */ +#define DOT11RATEBYTE_1 (1*2) +#define DOT11RATEBYTE_2 (2*2) +#define DOT11RATEBYTE_5_5 (5*2+1) +#define DOT11RATEBYTE_11 (11*2) +#define DOT11RATEBYTE_22 (22*2) +#define DOT11RATEBYTE_6_G (6*2) +#define DOT11RATEBYTE_9_G (9*2) +#define DOT11RATEBYTE_12_G (12*2) +#define DOT11RATEBYTE_18_G (18*2) +#define DOT11RATEBYTE_24_G (24*2) +#define DOT11RATEBYTE_36_G (36*2) +#define DOT11RATEBYTE_48_G (48*2) +#define DOT11RATEBYTE_54_G (54*2) +#define DOT11RATEBYTE_BASIC 0x80 /* flags rates included in basic rate set */ + + +/*********************************************************************** +** rxbuffer_t +** +** This is the format of rx data returned by acx +*/ + +/* I've hoped it's a 802.11 PHY header, but no... + * so far, I've seen on acx111: + * 0000 3a00 0000 0000 IBSS Beacons + * 0000 3c00 0000 0000 ESS Beacons + * 0000 2700 0000 0000 Probe requests + * --vda + */ +typedef struct phy_hdr { + u8 unknown[4]; + u8 acx111_unknown[4]; +} ACX_PACKED phy_hdr_t; + +/* seems to be a bit similar to hfa384x_rx_frame. + * These fields are still not quite obvious, though. + * Some seem to have different meanings... */ + +#define RXBUF_HDRSIZE 12 +#define RXBUF_BYTES_RCVD(adev, rxbuf) \ + ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) - (adev)->phy_header_len) +#define RXBUF_BYTES_USED(rxbuf) \ + ((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) + RXBUF_HDRSIZE) +/* USBism */ +#define RXBUF_IS_TXSTAT(rxbuf) (le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0x8000) +/* +mac_cnt_rcvd: + 12 bits: length of frame from control field to first byte of FCS + 3 bits: reserved + 1 bit: 1 = it's a tx status info, not a rx packet (USB only) + +mac_cnt_mblks: + 6 bits: number of memory block used to store frame in adapter memory + 1 bit: Traffic Indicator bit in TIM of received Beacon was set + +mac_status: 1 byte (bitmap): + 7 Matching BSSID + 6 Matching SSID + 5 BDCST Address 1 field is a broadcast + 4 VBM received beacon frame has more than one set bit (?!) + 3 TIM Set bit representing this station is set in TIM of received beacon + 2 GROUP Address 1 is a multicast + 1 ADDR1 Address 1 matches our MAC + 0 FCSGD FSC is good + +phy_stat_baseband: 1 byte (bitmap): + 7 Preamble frame had a long preamble + 6 PLCP Error CRC16 error in PLCP header + 5 Unsup_Mod unsupported modulation + 4 Selected Antenna antenna 1 was used to receive this frame + 3 PBCC/CCK frame used: 1=PBCC, 0=CCK modulation + 2 OFDM frame used OFDM modulation + 1 TI Protection protection frame was detected + 0 Reserved + +phy_plcp_signal: 1 byte: + Receive PLCP Signal field from the Baseband Processor + +phy_level: 1 byte: + receive AGC gain level (can be used to measure receive signal strength) + +phy_snr: 1 byte: + estimated noise power of equalized receive signal + at input of FEC decoder (can be used to measure receive signal quality) + +time: 4 bytes: + timestamp sampled from either the Access Manager TSF counter + or free-running microsecond counter when the MAC receives + first byte of PLCP header. +*/ + +typedef struct rxbuffer { + u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */ + u8 mac_cnt_mblks; + u8 mac_status; + u8 phy_stat_baseband; /* bit 0x80: used LNA (Low-Noise Amplifier) */ + u8 phy_plcp_signal; + u8 phy_level; /* PHY stat */ + u8 phy_snr; /* PHY stat */ + u32 time; /* timestamp upon MAC rcv first byte */ +/* 4-byte (acx100) or 8-byte (acx111) phy header will be here +** if RX_CFG1_INCLUDE_PHY_HDR is in effect: +** phy_hdr_t phy */ + wlan_hdr_a3_t hdr_a3; + /* maximally sized data part of wlan packet */ + u8 data_a3[WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN]; + /* can add hdr/data_a4 if needed */ +} ACX_PACKED rxbuffer_t; + + +/*--- Firmware statistics ----------------------------------------------------*/ + +/* define a random 100 bytes more to catch firmware versions which + * provide a bigger struct */ +#define FW_STATS_FUTURE_EXTENSION 100 + +typedef struct fw_stats_tx { + u32 tx_desc_of; +} ACX_PACKED fw_stats_tx_t; + +typedef struct fw_stats_rx { + u32 rx_oom; + u32 rx_hdr_of; + u32 rx_hw_stuck; /* old: u32 rx_hdr_use_next */ + u32 rx_dropped_frame; + u32 rx_frame_ptr_err; + u32 rx_xfr_hint_trig; + u32 rx_aci_events; /* later versions only */ + u32 rx_aci_resets; /* later versions only */ +} ACX_PACKED fw_stats_rx_t; + +typedef struct fw_stats_dma { + u32 rx_dma_req; + u32 rx_dma_err; + u32 tx_dma_req; + u32 tx_dma_err; +} ACX_PACKED fw_stats_dma_t; + +typedef struct fw_stats_irq { + u32 cmd_cplt; + u32 fiq; + u32 rx_hdrs; + u32 rx_cmplt; + u32 rx_mem_of; + u32 rx_rdys; + u32 irqs; + u32 tx_procs; + u32 decrypt_done; + u32 dma_0_done; + u32 dma_1_done; + u32 tx_exch_complet; + u32 commands; + u32 rx_procs; + u32 hw_pm_mode_changes; + u32 host_acks; + u32 pci_pm; + u32 acm_wakeups; +} ACX_PACKED fw_stats_irq_t; + +typedef struct fw_stats_wep { + u32 wep_key_count; + u32 wep_default_key_count; + u32 dot11_def_key_mib; + u32 wep_key_not_found; + u32 wep_decrypt_fail; + u32 wep_pkt_decrypt; + u32 wep_decrypt_irqs; +} ACX_PACKED fw_stats_wep_t; + +typedef struct fw_stats_pwr { + u32 tx_start_ctr; + u32 no_ps_tx_too_short; + u32 rx_start_ctr; + u32 no_ps_rx_too_short; + u32 lppd_started; + u32 no_lppd_too_noisy; + u32 no_lppd_too_short; + u32 no_lppd_matching_frame; +} ACX_PACKED fw_stats_pwr_t; + +typedef struct fw_stats_mic { + u32 mic_rx_pkts; + u32 mic_calc_fail; +} ACX_PACKED fw_stats_mic_t; + +typedef struct fw_stats_aes { + u32 aes_enc_fail; + u32 aes_dec_fail; + u32 aes_enc_pkts; + u32 aes_dec_pkts; + u32 aes_enc_irq; + u32 aes_dec_irq; +} ACX_PACKED fw_stats_aes_t; + +typedef struct fw_stats_event { + u32 heartbeat; + u32 calibration; + u32 rx_mismatch; + u32 rx_mem_empty; + u32 rx_pool; + u32 oom_late; + u32 phy_tx_err; + u32 tx_stuck; +} ACX_PACKED fw_stats_event_t; + +/* mainly for size calculation only */ +typedef struct fw_stats { + u16 type; + u16 len; + fw_stats_tx_t tx; + fw_stats_rx_t rx; + fw_stats_dma_t dma; + fw_stats_irq_t irq; + fw_stats_wep_t wep; + fw_stats_pwr_t pwr; + fw_stats_mic_t mic; + fw_stats_aes_t aes; + fw_stats_event_t evt; + u8 _padding[FW_STATS_FUTURE_EXTENSION]; +} fw_stats_t; + +/* Firmware version struct */ + +typedef struct fw_ver { + u16 cmd; + u16 size; + char fw_id[20]; + u32 hw_id; +} ACX_PACKED fw_ver_t; + +#define FW_ID_SIZE 20 + + +/*--- WEP stuff --------------------------------------------------------------*/ +#define DOT11_MAX_DEFAULT_WEP_KEYS 4 + +/* non-firmware struct, no packing necessary */ +typedef struct wep_key { + size_t size; /* most often used member first */ + u8 index; + u8 key[29]; + u16 strange_filler; +} wep_key_t; /* size = 264 bytes (33*8) */ +/* FIXME: We don't have size 264! Or is there 2 bytes beyond the key + * (strange_filler)? */ + +/* non-firmware struct, no packing necessary */ +typedef struct key_struct { + u8 addr[ETH_ALEN]; /* 0x00 */ + u16 filler1; /* 0x06 */ + u32 filler2; /* 0x08 */ + u32 index; /* 0x0c */ + u16 len; /* 0x10 */ + u8 key[29]; /* 0x12; is this long enough??? */ +} key_struct_t; /* size = 276. FIXME: where is the remaining space?? */ + + +/*--- Client (peer) info -----------------------------------------------------*/ +/* adev->sta_list[] is used for: +** accumulating and processing of scan results +** keeping client info in AP mode +** keeping AP info in STA mode (AP is the only one 'client') +** keeping peer info in ad-hoc mode +** non-firmware struct --> no packing necessary */ +enum { + CLIENT_EMPTY_SLOT_0 = 0, + CLIENT_EXIST_1 = 1, + CLIENT_AUTHENTICATED_2 = 2, + CLIENT_ASSOCIATED_3 = 3, + CLIENT_JOIN_CANDIDATE = 4 +}; +struct client { + /* most frequent access first */ + u8 used; /* misnamed, more like 'status' */ + struct client* next; + unsigned long mtime; /* last time we heard it, in jiffies */ + size_t essid_len; /* length of ESSID (without '\0') */ + u32 sir; /* Standard IR */ + u32 snr; /* Signal to Noise Ratio */ + u16 aid; /* association ID */ + u16 seq; /* from client's auth req */ + u16 auth_alg; /* from client's auth req */ + u16 cap_info; /* from client's assoc req */ + u16 rate_cap; /* what client supports (all rates) */ + u16 rate_bas; /* what client supports (basic rates) */ + u16 rate_cfg; /* what is allowed (by iwconfig etc) */ + u16 rate_cur; /* currently used rate mask */ + u8 rate_100; /* currently used rate byte (acx100 only) */ + u8 address[ETH_ALEN]; + u8 bssid[ETH_ALEN]; /* ad-hoc hosts can have bssid != mac */ + u8 channel; + u8 auth_step; + u8 ignore_count; + u8 fallback_count; + u8 stepup_count; + char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID and trailing '\0' */ +/* FIXME: this one is too damn big */ + char challenge_text[WLAN_CHALLENGE_LEN]; +}; + + +/*********************************************************************** +** Hardware structures +*/ + +/* An opaque typesafe helper type + * + * Some hardware fields are actually pointers, + * but they have to remain u32, since using ptr instead + * (8 bytes on 64bit systems!) would disrupt the fixed descriptor + * format the acx firmware expects in the non-user area. + * Since we cannot cram an 8 byte ptr into 4 bytes, we need to + * enforce that pointed to data remains in low memory + * (address value needs to fit in 4 bytes) on 64bit systems. + * + * This is easy to get wrong, thus we are using a small struct + * and special macros to access it. Macros will check for + * attempts to overflow an acx_ptr with value > 0xffffffff. + * + * Attempts to use acx_ptr without macros result in compile-time errors */ + +typedef struct { + u32 v; +} ACX_PACKED acx_ptr; + +#if ACX_DEBUG +#define CHECK32(n) BUG_ON(sizeof(n)>4 && (long)(n)>0xffffff00) +#else +#define CHECK32(n) ((void)0) +#endif + +/* acx_ptr <-> integer conversion */ +#define cpu2acx(n) ({ CHECK32(n); ((acx_ptr){ .v = cpu_to_le32(n) }); }) +#define acx2cpu(a) (le32_to_cpu(a.v)) + +/* acx_ptr <-> pointer conversion */ +#define ptr2acx(p) ({ CHECK32(p); ((acx_ptr){ .v = cpu_to_le32((u32)(long)(p)) }); }) +#define acx2ptr(a) ((void*)le32_to_cpu(a.v)) + +/* Values for rate field (acx100 only) */ +#define RATE100_1 10 +#define RATE100_2 20 +#define RATE100_5 55 +#define RATE100_11 110 +#define RATE100_22 220 +/* This bit denotes use of PBCC: +** (PBCC encoding is usable with 11 and 22 Mbps speeds only) */ +#define RATE100_PBCC511 0x80 + +/* Bit values for rate111 field */ +#define RATE111_1 0x0001 /* DBPSK */ +#define RATE111_2 0x0002 /* DQPSK */ +#define RATE111_5 0x0004 /* CCK or PBCC */ +#define RATE111_6 0x0008 /* CCK-OFDM or OFDM */ +#define RATE111_9 0x0010 /* CCK-OFDM or OFDM */ +#define RATE111_11 0x0020 /* CCK or PBCC */ +#define RATE111_12 0x0040 /* CCK-OFDM or OFDM */ +#define RATE111_18 0x0080 /* CCK-OFDM or OFDM */ +#define RATE111_22 0x0100 /* PBCC */ +#define RATE111_24 0x0200 /* CCK-OFDM or OFDM */ +#define RATE111_36 0x0400 /* CCK-OFDM or OFDM */ +#define RATE111_48 0x0800 /* CCK-OFDM or OFDM */ +#define RATE111_54 0x1000 /* CCK-OFDM or OFDM */ +#define RATE111_RESERVED 0x2000 +#define RATE111_PBCC511 0x4000 /* PBCC mod at 5.5 or 11Mbit (else CCK) */ +#define RATE111_SHORTPRE 0x8000 /* short preamble */ +/* Special 'try everything' value */ +#define RATE111_ALL 0x1fff +/* These bits denote acx100 compatible settings */ +#define RATE111_ACX100_COMPAT 0x0127 +/* These bits denote 802.11b compatible settings */ +#define RATE111_80211B_COMPAT 0x0027 + +/* Descriptor Ctl field bits + * init value is 0x8e, "idle" value is 0x82 (in idle tx descs) + */ +#define DESC_CTL_SHORT_PREAMBLE 0x01 /* preamble type: 0 = long; 1 = short */ +#define DESC_CTL_FIRSTFRAG 0x02 /* this is the 1st frag of the frame */ +#define DESC_CTL_AUTODMA 0x04 +#define DESC_CTL_RECLAIM 0x08 /* ready to reuse */ +#define DESC_CTL_HOSTDONE 0x20 /* host has finished processing */ +#define DESC_CTL_ACXDONE 0x40 /* acx has finished processing */ +/* host owns the desc [has to be released last, AFTER modifying all other desc fields!] */ +#define DESC_CTL_HOSTOWN 0x80 +#define DESC_CTL_ACXDONE_HOSTOWN (DESC_CTL_ACXDONE | DESC_CTL_HOSTOWN) + +/* Descriptor Status field + */ +#define DESC_STATUS_FULL (1 << 31) + +/* NB: some bits may be interesting for Monitor mode tx (aka Raw tx): */ +#define DESC_CTL2_SEQ 0x01 /* don't increase sequence field */ +#define DESC_CTL2_FCS 0x02 /* don't add the FCS */ +#define DESC_CTL2_MORE_FRAG 0x04 +#define DESC_CTL2_RETRY 0x08 /* don't increase retry field */ +#define DESC_CTL2_POWER 0x10 /* don't increase power mgmt. field */ +#define DESC_CTL2_RTS 0x20 /* do RTS/CTS magic before sending */ +#define DESC_CTL2_WEP 0x40 /* encrypt this frame */ +#define DESC_CTL2_DUR 0x80 /* don't increase duration field */ + +/*********************************************************************** +** PCI structures +*/ +/* IRQ Constants +** (outside of "#ifdef PCI" because USB (mis)uses HOST_INT_SCAN_COMPLETE) */ +#define HOST_INT_RX_DATA 0x0001 +#define HOST_INT_TX_COMPLETE 0x0002 +#define HOST_INT_TX_XFER 0x0004 +#define HOST_INT_RX_COMPLETE 0x0008 +#define HOST_INT_DTIM 0x0010 +#define HOST_INT_BEACON 0x0020 +#define HOST_INT_TIMER 0x0040 +#define HOST_INT_KEY_NOT_FOUND 0x0080 +#define HOST_INT_IV_ICV_FAILURE 0x0100 +#define HOST_INT_CMD_COMPLETE 0x0200 +#define HOST_INT_INFO 0x0400 +#define HOST_INT_OVERFLOW 0x0800 +#define HOST_INT_PROCESS_ERROR 0x1000 +#define HOST_INT_SCAN_COMPLETE 0x2000 +#define HOST_INT_FCS_THRESHOLD 0x4000 +#define HOST_INT_UNKNOWN 0x8000 + +/* Outside of "#ifdef PCI" because USB needs to know sizeof() +** of txdesc and rxdesc: */ +struct txdesc { + acx_ptr pNextDesc; /* pointer to next txdesc */ + acx_ptr HostMemPtr; /* 0x04 */ + acx_ptr AcxMemPtr; /* 0x08 */ + u32 tx_time; /* 0x0c */ + u16 total_length; /* 0x10 */ + u16 Reserved; /* 0x12 */ + +/* The following 16 bytes do not change when acx100 owns the descriptor */ +/* BUG: fw clears last byte of this area which is supposedly reserved +** for driver use. amd64 blew up. We dare not use it now */ + u32 dummy[4]; + + u8 Ctl_8; /* 0x24, 8bit value */ + u8 Ctl2_8; /* 0x25, 8bit value */ + u8 error; /* 0x26 */ + u8 ack_failures; /* 0x27 */ + u8 rts_failures; /* 0x28 */ + u8 rts_ok; /* 0x29 */ + union { + struct { + u8 rate; /* 0x2a */ + u8 queue_ctrl; /* 0x2b */ + } ACX_PACKED r1; + struct { + u16 rate111; /* 0x2a */ + } ACX_PACKED r2; + } ACX_PACKED u; + u32 queue_info; /* 0x2c (acx100, reserved on acx111) */ +} ACX_PACKED; /* size : 48 = 0x30 */ +/* NB: acx111 txdesc structure is 4 byte larger */ +/* All these 4 extra bytes are reserved. tx alloc code takes them into account */ + +struct rxdesc { + acx_ptr pNextDesc; /* 0x00 */ + acx_ptr HostMemPtr; /* 0x04 */ + acx_ptr ACXMemPtr; /* 0x08 */ + u32 rx_time; /* 0x0c */ + u16 total_length; /* 0x10 */ + u16 WEP_length; /* 0x12 */ + u32 WEP_ofs; /* 0x14 */ + +/* the following 16 bytes do not change when acx100 owns the descriptor */ + u8 driverWorkspace[16]; /* 0x18 */ + + u8 Ctl_8; + u8 rate; + u8 error; + u8 SNR; /* Signal-to-Noise Ratio */ + u8 RxLevel; + u8 queue_ctrl; + u16 unknown; + u32 unknown2; +} ACX_PACKED; /* size 52 = 0x34 */ + +#ifdef ACX_PCI + +/* Register I/O offsets */ +#define ACX100_EEPROM_ID_OFFSET 0x380 + +/* please add further ACX hardware register definitions only when + it turns out you need them in the driver, and please try to use + firmware functionality instead, since using direct I/O access instead + of letting the firmware do it might confuse the firmware's state + machine */ + +/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION +** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */ +enum { + IO_ACX_SOFT_RESET = 0, + + IO_ACX_SLV_MEM_ADDR, + IO_ACX_SLV_MEM_DATA, + IO_ACX_SLV_MEM_CTL, + IO_ACX_SLV_END_CTL, + + IO_ACX_FEMR, /* Function Event Mask */ + + IO_ACX_INT_TRIG, + IO_ACX_IRQ_MASK, + IO_ACX_IRQ_STATUS_NON_DES, + IO_ACX_IRQ_STATUS_CLEAR, /* CLEAR = clear on read */ + IO_ACX_IRQ_ACK, + IO_ACX_HINT_TRIG, + + IO_ACX_ENABLE, + + IO_ACX_EEPROM_CTL, + IO_ACX_EEPROM_ADDR, + IO_ACX_EEPROM_DATA, + IO_ACX_EEPROM_CFG, + + IO_ACX_PHY_ADDR, + IO_ACX_PHY_DATA, + IO_ACX_PHY_CTL, + + IO_ACX_GPIO_OE, + + IO_ACX_GPIO_OUT, + + IO_ACX_CMD_MAILBOX_OFFS, + IO_ACX_INFO_MAILBOX_OFFS, + IO_ACX_EEPROM_INFORMATION, + + IO_ACX_EE_START, + IO_ACX_SOR_CFG, + IO_ACX_ECPU_CTRL +}; +/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION +** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */ + +/* Values for IO_ACX_INT_TRIG register: */ +/* inform hw that rxdesc in queue needs processing */ +#define INT_TRIG_RXPRC 0x08 +/* inform hw that txdesc in queue needs processing */ +#define INT_TRIG_TXPRC 0x04 +/* ack that we received info from info mailbox */ +#define INT_TRIG_INFOACK 0x02 +/* inform hw that we have filled command mailbox */ +#define INT_TRIG_CMD 0x01 + +struct txhostdesc { + acx_ptr data_phy; /* 0x00 [u8 *] */ + u16 data_offset; /* 0x04 */ + u16 reserved; /* 0x06 */ + u16 Ctl_16; /* 16bit value, endianness!! */ + u16 length; /* 0x0a */ + acx_ptr desc_phy_next; /* 0x0c [txhostdesc *] */ + acx_ptr pNext; /* 0x10 [txhostdesc *] */ + u32 Status; /* 0x14, unused on Tx */ +/* From here on you can use this area as you want (variable length, too!) */ + u8 *data; +} ACX_PACKED; + +struct rxhostdesc { + acx_ptr data_phy; /* 0x00 [rxbuffer_t *] */ + u16 data_offset; /* 0x04 */ + u16 reserved; /* 0x06 */ + u16 Ctl_16; /* 0x08; 16bit value, endianness!! */ + u16 length; /* 0x0a */ + acx_ptr desc_phy_next; /* 0x0c [rxhostdesc_t *] */ + acx_ptr pNext; /* 0x10 [rxhostdesc_t *] */ + u32 Status; /* 0x14 */ +/* From here on you can use this area as you want (variable length, too!) */ + rxbuffer_t *data; +} ACX_PACKED; + +#endif /* ACX_PCI */ + +/*********************************************************************** +** USB structures and constants +*/ +#ifdef ACX_USB + +/* Used for usb_txbuffer.desc field */ +#define USB_TXBUF_TXDESC 0xA +/* Size of header (everything up to data[]) */ +#define USB_TXBUF_HDRSIZE 14 +typedef struct usb_txbuffer { + u16 desc; + u16 mpdu_len; + u8 queue_index; + u8 rate; + u32 hostdata; + u8 ctrl1; + u8 ctrl2; + u16 data_len; + /* wlan packet content is placed here: */ + u8 data[WLAN_A4FR_MAXLEN_WEP_FCS]; +} ACX_PACKED usb_txbuffer_t; + +/* USB returns either rx packets (see rxbuffer) or +** these "tx status" structs: */ +typedef struct usb_txstatus { + u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */ + u8 queue_index; + u8 mac_status; /* seen 0x20 on tx failure */ + u32 hostdata; + u8 rate; + u8 ack_failures; + u8 rts_failures; + u8 rts_ok; +} ACX_PACKED usb_txstatus_t; + +typedef struct usb_tx { + unsigned busy:1; + struct urb *urb; + acx_device_t *adev; + /* actual USB bulk output data block is here: */ + usb_txbuffer_t bulkout; +} usb_tx_t; + +struct usb_rx_plain { + unsigned busy:1; + struct urb *urb; + acx_device_t *adev; + rxbuffer_t bulkin; +}; + +typedef struct usb_rx { + unsigned busy:1; + struct urb *urb; + acx_device_t *adev; + rxbuffer_t bulkin; + /* Make entire structure 4k. Report if it breaks something. */ + u8 padding[4*1024 - sizeof(struct usb_rx_plain)]; +} usb_rx_t; +#endif /* ACX_USB */ + + +/* Config Option structs */ + +typedef struct co_antennas { + u8 type; + u8 len; + u8 list[2]; +} ACX_PACKED co_antennas_t; + +typedef struct co_powerlevels { + u8 type; + u8 len; + u16 list[8]; +} ACX_PACKED co_powerlevels_t; + +typedef struct co_datarates { + u8 type; + u8 len; + u8 list[8]; +} ACX_PACKED co_datarates_t; + +typedef struct co_domains { + u8 type; + u8 len; + u8 list[6]; +} ACX_PACKED co_domains_t; + +typedef struct co_product_id { + u8 type; + u8 len; + u8 list[128]; +} ACX_PACKED co_product_id_t; + +typedef struct co_manuf_id { + u8 type; + u8 len; + u8 list[128]; +} ACX_PACKED co_manuf_t; + +typedef struct co_fixed { + char NVSv[8]; +/* u16 NVS_vendor_offs; ACX111-only */ +/* u16 unknown; ACX111-only */ + u8 MAC[6]; /* ACX100-only */ + u16 probe_delay; /* ACX100-only */ + u32 eof_memory; + u8 dot11CCAModes; + u8 dot11Diversity; + u8 dot11ShortPreambleOption; + u8 dot11PBCCOption; + u8 dot11ChannelAgility; + u8 dot11PhyType; /* FIXME: does 802.11 call it "dot11PHYType"? */ + u8 dot11TempType; + u8 table_count; +} ACX_PACKED co_fixed_t; + +typedef struct acx111_ie_configoption { + u16 type; + u16 len; +/* Do not access below members directly, they are in fact variable length */ + co_fixed_t fixed; + co_antennas_t antennas; + co_powerlevels_t power_levels; + co_datarates_t data_rates; + co_domains_t domains; + co_product_id_t product_id; + co_manuf_t manufacturer; + u8 _padding[4]; +} ACX_PACKED acx111_ie_configoption_t; + + +/*********************************************************************** +** Main acx per-device data structure +*/ +#define ACX_STATE_FW_LOADED 0x01 +#define ACX_STATE_IFACE_UP 0x02 + +/* MAC mode (BSS type) defines + * Note that they shouldn't be redefined, since they are also used + * during communication with firmware */ +#define ACX_MODE_0_ADHOC 0 +#define ACX_MODE_1_UNUSED 1 +#define ACX_MODE_2_STA 2 +#define ACX_MODE_3_AP 3 +/* These are our own inventions. Sending these to firmware +** makes it stop emitting beacons, which is exactly what we want +** for these modes */ +#define ACX_MODE_MONITOR 0xfe +#define ACX_MODE_OFF 0xff +/* 'Submode': identifies exact status of ADHOC/STA host */ +#define ACX_STATUS_0_STOPPED 0 +#define ACX_STATUS_1_SCANNING 1 +#define ACX_STATUS_2_WAIT_AUTH 2 +#define ACX_STATUS_3_AUTHENTICATED 3 +#define ACX_STATUS_4_ASSOCIATED 4 + +/* FIXME: this should be named something like struct acx_priv (typedef'd to + * acx_priv_t) */ + +/* non-firmware struct, no packing necessary */ +struct acx_device { + /* most frequent accesses first (dereferencing and cache line!) */ + + /*** Locking ***/ + /* FIXME: try to convert semaphore to more efficient mutex according + to Ingo Molnar's docs (but not before driver is in mainline or + pre-mutex Linux 2.6.10 is very outdated). */ + struct semaphore sem; + spinlock_t lock; +#if defined(PARANOID_LOCKING) /* Lock debugging */ + const char *last_sem; + const char *last_lock; + unsigned long sem_time; + unsigned long lock_time; +#endif + + /*** Linux network device ***/ + struct net_device *ndev; /* pointer to linux netdevice */ + + /*** Device statistics ***/ + struct net_device_stats stats; /* net device statistics */ +#ifdef WIRELESS_EXT + struct iw_statistics wstats; /* wireless statistics */ +#endif + /*** Power managment ***/ + struct pm_dev *pm; /* PM crap */ + + /*** Management timer ***/ + struct timer_list mgmt_timer; + + /*** Hardware identification ***/ + const char *chip_name; + u8 dev_type; + u8 chip_type; + u8 form_factor; + u8 radio_type; + u8 eeprom_version; + + /*** Config retrieved from EEPROM ***/ + char cfgopt_NVSv[8]; + u16 cfgopt_NVS_vendor_offs; + u8 cfgopt_MAC[6]; + u16 cfgopt_probe_delay; + u32 cfgopt_eof_memory; + u8 cfgopt_dot11CCAModes; + u8 cfgopt_dot11Diversity; + u8 cfgopt_dot11ShortPreambleOption; + u8 cfgopt_dot11PBCCOption; + u8 cfgopt_dot11ChannelAgility; + u8 cfgopt_dot11PhyType; + u8 cfgopt_dot11TempType; + co_antennas_t cfgopt_antennas; + co_powerlevels_t cfgopt_power_levels; + co_datarates_t cfgopt_data_rates; + co_domains_t cfgopt_domains; + co_product_id_t cfgopt_product_id; + co_manuf_t cfgopt_manufacturer; + + /*** Firmware identification ***/ + char firmware_version[FW_ID_SIZE+1]; + u32 firmware_numver; + u32 firmware_id; + const u16 *ie_len; + const u16 *ie_len_dot11; + + /*** Device state ***/ + u16 dev_state_mask; + u8 led_power; /* power LED status */ + u32 get_mask; /* mask of settings to fetch from the card */ + u32 set_mask; /* mask of settings to write to the card */ + + /* Barely used in USB case */ + u16 irq_status; + + u8 after_interrupt_jobs; /* mini job list for doing actions after an interrupt occurred */ + WORK_STRUCT after_interrupt_task; /* our task for after interrupt actions */ + + /*** scanning ***/ + u16 scan_count; /* number of times to do channel scan */ + u8 scan_mode; /* 0 == active, 1 == passive, 2 == background */ + u8 scan_rate; + u16 scan_duration; + u16 scan_probe_delay; +#if WIRELESS_EXT > 15 + struct iw_spy_data spy_data; /* FIXME: needs to be implemented! */ +#endif + + /*** Wireless network settings ***/ + /* copy of the device address (ifconfig hw ether) that we actually use + ** for 802.11; copied over from the network device's MAC address + ** (ifconfig) when it makes sense only */ + u8 dev_addr[MAX_ADDR_LEN]; + u8 bssid[ETH_ALEN]; /* the BSSID after having joined */ + u8 ap[ETH_ALEN]; /* The AP we want, FF:FF:FF:FF:FF:FF is any */ + u16 aid; /* The Association ID sent from the AP / last used AID if we're an AP */ + u16 mode; /* mode from iwconfig */ + int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */ + u16 status; /* 802.11 association status */ + u8 essid_active; /* specific ESSID active, or select any? */ + u8 essid_len; /* to avoid dozens of strlen() */ + /* INCLUDES \0 termination for easy printf - but many places + ** simply want the string data memcpy'd plus a length indicator! + ** Keep that in mind... */ + char essid[IW_ESSID_MAX_SIZE+1]; + /* essid we are going to use for association, in case of "essid 'any'" + ** and in case of hidden ESSID (use configured ESSID then) */ + char essid_for_assoc[IW_ESSID_MAX_SIZE+1]; + char nick[IW_ESSID_MAX_SIZE+1]; /* see essid! */ + u8 channel; + u8 reg_dom_id; /* reg domain setting */ + u16 reg_dom_chanmask; + u16 auth_or_assoc_retries; + u16 scan_retries; + unsigned long scan_start; /* YES, jiffies is defined as "unsigned long" */ + + /* stations known to us (if we're an ap) */ + client_t sta_list[32]; /* tab is larger than list, so that */ + client_t *sta_hash_tab[64]; /* hash collisions are not likely */ + client_t *ap_client; /* this one is our AP (STA mode only) */ + + int dup_count; + int nondup_count; + unsigned long dup_msg_expiry; + u16 last_seq_ctrl; /* duplicate packet detection */ + + /* 802.11 power save mode */ + u8 ps_wakeup_cfg; + u8 ps_listen_interval; + u8 ps_options; + u8 ps_hangover_period; + u32 ps_enhanced_transition_time; + u32 ps_beacon_rx_time; + + /*** PHY settings ***/ + u8 fallback_threshold; + u8 stepup_threshold; + u16 rate_basic; + u16 rate_oper; + u16 rate_bcast; + u16 rate_bcast100; + u8 rate_auto; /* false if "iwconfig rate N" (WITHOUT 'auto'!) */ + u8 preamble_mode; /* 0 == Long Preamble, 1 == Short, 2 == Auto */ + u8 preamble_cur; + + u8 tx_disabled; + u8 tx_level_dbm; + /* u8 tx_level_val; */ + /* u8 tx_level_auto; whether to do automatic power adjustment */ + + unsigned long recalib_time_last_success; + unsigned long recalib_time_last_attempt; + int recalib_failure_count; + int recalib_msg_ratelimit; + int retry_errors_msg_ratelimit; + + unsigned long brange_time_last_state_change; /* time the power LED was last changed */ + u8 brange_last_state; /* last state of the LED */ + u8 brange_max_quality; /* maximum quality that equates to full speed */ + + u8 sensitivity; + u8 antenna; /* antenna settings */ + u8 ed_threshold; /* energy detect threshold */ + u8 cca; /* clear channel assessment */ + + u16 rts_threshold; + u16 frag_threshold; + u32 short_retry; + u32 long_retry; + u16 msdu_lifetime; + u16 listen_interval; /* given in units of beacon interval */ + u32 beacon_interval; + + u16 capabilities; + u8 rate_supported_len; + u8 rate_supported[13]; + + /*** Encryption settings (WEP) ***/ + u32 auth_alg; /* used in transmit_authen1 */ + u8 wep_enabled; + u8 wep_restricted; + u8 wep_current_index; + wep_key_t wep_keys[DOT11_MAX_DEFAULT_WEP_KEYS]; /* the default WEP keys */ + key_struct_t wep_key_struct[10]; + + /*** Unknown ***/ + u8 dtim_interval; + + /*** Card Rx/Tx management ***/ + u16 rx_config_1; + u16 rx_config_2; + u16 memblocksize; + unsigned int tx_free; + unsigned int tx_head; /* keep as close as possible to Tx stuff below (cache line) */ + u16 phy_header_len; + +/************************************************************************* + *** PCI/USB/... must be last or else hw agnostic code breaks horribly *** + *************************************************************************/ + + /* hack to let common code compile. FIXME */ + dma_addr_t rxhostdesc_startphy; + + /*** PCI stuff ***/ +#ifdef ACX_PCI + /* pointers to tx buffers, tx host descriptors (in host memory) + ** and tx descs in device memory */ + unsigned int tx_tail; + u8 *txbuf_start; + txhostdesc_t *txhostdesc_start; + txdesc_t *txdesc_start; /* points to PCI-mapped memory */ + dma_addr_t txbuf_startphy; + dma_addr_t txhostdesc_startphy; + /* sizes of above host memory areas */ + unsigned int txbuf_area_size; + unsigned int txhostdesc_area_size; + + unsigned int txdesc_size; /* size of txdesc; ACX111 = ACX100 + 4 */ + client_t *txc[TX_CNT]; + u16 txr[TX_CNT]; + + /* same for rx */ + unsigned int rx_tail; + rxbuffer_t *rxbuf_start; + rxhostdesc_t *rxhostdesc_start; + rxdesc_t *rxdesc_start; + /* physical addresses of above host memory areas */ + dma_addr_t rxbuf_startphy; + /* dma_addr_t rxhostdesc_startphy; */ + unsigned int rxbuf_area_size; + unsigned int rxhostdesc_area_size; + + u8 need_radio_fw; + u8 irqs_active; /* whether irq sending is activated */ + + const u16 *io; /* points to ACX100 or ACX111 PCI I/O register address set */ + + struct pci_dev *pdev; + + unsigned long membase; + unsigned long membase2; + void __iomem *iobase; + void __iomem *iobase2; + /* command interface */ + u8 __iomem *cmd_area; + u8 __iomem *info_area; + + u16 irq_mask; /* interrupt types to mask out (not wanted) with many IRQs activated */ + u16 irq_mask_off; /* interrupt types to mask out (not wanted) with IRQs off */ + unsigned int irq_loops_this_jiffy; + unsigned long irq_last_jiffies; +#endif + + /*** USB stuff ***/ +#ifdef ACX_USB + struct usb_device *usbdev; + + rxbuffer_t rxtruncbuf; + + usb_tx_t *usb_tx; + usb_rx_t *usb_rx; + + int bulkinep; /* bulk-in endpoint */ + int bulkoutep; /* bulk-out endpoint */ + int rxtruncsize; +#endif + +}; + +static inline acx_device_t* +ndev2adev(struct net_device *ndev) +{ + return netdev_priv(ndev); +} + + +/* For use with ACX1xx_IE_RXCONFIG */ +/* bit description + * 13 include additional header (length etc.) *required* + * struct is defined in 'struct rxbuffer' + * is this bit acx100 only? does acx111 always put the header, + * and bit setting is irrelevant? --vda + * 10 receive frames only with SSID used in last join cmd + * 9 discard broadcast + * 8 receive packets for multicast address 1 + * 7 receive packets for multicast address 0 + * 6 discard all multicast packets + * 5 discard frames from foreign BSSID + * 4 discard frames with foreign destination MAC address + * 3 promiscuous mode (receive ALL frames, disable filter) + * 2 include FCS + * 1 include phy header + * 0 ??? + */ +#define RX_CFG1_INCLUDE_RXBUF_HDR 0x2000 /* ACX100 only */ +#define RX_CFG1_FILTER_SSID 0x0400 +#define RX_CFG1_FILTER_BCAST 0x0200 +#define RX_CFG1_RCV_MC_ADDR1 0x0100 +#define RX_CFG1_RCV_MC_ADDR0 0x0080 +#define RX_CFG1_FILTER_ALL_MULTI 0x0040 +#define RX_CFG1_FILTER_BSSID 0x0020 +#define RX_CFG1_FILTER_MAC 0x0010 +#define RX_CFG1_RCV_PROMISCUOUS 0x0008 +#define RX_CFG1_INCLUDE_FCS 0x0004 +#define RX_CFG1_INCLUDE_PHY_HDR (WANT_PHY_HDR ? 0x0002 : 0) +/* bit description + * 11 receive association requests etc. + * 10 receive authentication frames + * 9 receive beacon frames + * 8 receive contention free packets + * 7 receive control frames + * 6 receive data frames + * 5 receive broken frames + * 4 receive management frames + * 3 receive probe requests + * 2 receive probe responses + * 1 receive RTS/CTS/ACK frames + * 0 receive other + */ +#define RX_CFG2_RCV_ASSOC_REQ 0x0800 +#define RX_CFG2_RCV_AUTH_FRAMES 0x0400 +#define RX_CFG2_RCV_BEACON_FRAMES 0x0200 +#define RX_CFG2_RCV_CONTENTION_FREE 0x0100 +#define RX_CFG2_RCV_CTRL_FRAMES 0x0080 +#define RX_CFG2_RCV_DATA_FRAMES 0x0040 +#define RX_CFG2_RCV_BROKEN_FRAMES 0x0020 +#define RX_CFG2_RCV_MGMT_FRAMES 0x0010 +#define RX_CFG2_RCV_PROBE_REQ 0x0008 +#define RX_CFG2_RCV_PROBE_RESP 0x0004 +#define RX_CFG2_RCV_ACK_FRAMES 0x0002 +#define RX_CFG2_RCV_OTHER 0x0001 + +/* For use with ACX1xx_IE_FEATURE_CONFIG */ +#define FEATURE1_80MHZ_CLOCK 0x00000040L +#define FEATURE1_4X 0x00000020L +#define FEATURE1_LOW_RX 0x00000008L +#define FEATURE1_EXTRA_LOW_RX 0x00000001L + +#define FEATURE2_SNIFFER 0x00000080L +#define FEATURE2_NO_TXCRYPT 0x00000001L + +/*-- get and set mask values --*/ +#define GETSET_LED_POWER 0x00000001L +#define GETSET_STATION_ID 0x00000002L +#define SET_TEMPLATES 0x00000004L +#define SET_STA_LIST 0x00000008L +#define GETSET_TX 0x00000010L +#define GETSET_RX 0x00000020L +#define SET_RXCONFIG 0x00000040L +#define GETSET_ANTENNA 0x00000080L +#define GETSET_SENSITIVITY 0x00000100L +#define GETSET_TXPOWER 0x00000200L +#define GETSET_ED_THRESH 0x00000400L +#define GETSET_CCA 0x00000800L +#define GETSET_POWER_80211 0x00001000L +#define GETSET_RETRY 0x00002000L +#define GETSET_REG_DOMAIN 0x00004000L +#define GETSET_CHANNEL 0x00008000L +/* Used when ESSID changes etc and we need to scan for AP anew */ +#define GETSET_RESCAN 0x00010000L +#define GETSET_MODE 0x00020000L +#define GETSET_WEP 0x00040000L +#define SET_WEP_OPTIONS 0x00080000L +#define SET_MSDU_LIFETIME 0x00100000L +#define SET_RATE_FALLBACK 0x00200000L + +/* keep in sync with the above */ +#define GETSET_ALL (0 \ +/* GETSET_LED_POWER */ | 0x00000001L \ +/* GETSET_STATION_ID */ | 0x00000002L \ +/* SET_TEMPLATES */ | 0x00000004L \ +/* SET_STA_LIST */ | 0x00000008L \ +/* GETSET_TX */ | 0x00000010L \ +/* GETSET_RX */ | 0x00000020L \ +/* SET_RXCONFIG */ | 0x00000040L \ +/* GETSET_ANTENNA */ | 0x00000080L \ +/* GETSET_SENSITIVITY */| 0x00000100L \ +/* GETSET_TXPOWER */ | 0x00000200L \ +/* GETSET_ED_THRESH */ | 0x00000400L \ +/* GETSET_CCA */ | 0x00000800L \ +/* GETSET_POWER_80211 */| 0x00001000L \ +/* GETSET_RETRY */ | 0x00002000L \ +/* GETSET_REG_DOMAIN */ | 0x00004000L \ +/* GETSET_CHANNEL */ | 0x00008000L \ +/* GETSET_RESCAN */ | 0x00010000L \ +/* GETSET_MODE */ | 0x00020000L \ +/* GETSET_WEP */ | 0x00040000L \ +/* SET_WEP_OPTIONS */ | 0x00080000L \ +/* SET_MSDU_LIFETIME */ | 0x00100000L \ +/* SET_RATE_FALLBACK */ | 0x00200000L \ + ) + + +/*********************************************************************** +** Firmware loading +*/ +#include /* request_firmware() */ +#include /* struct pci_device */ + + +/*********************************************************************** +*/ +typedef struct acx100_ie_memblocksize { + u16 type; + u16 len; + u16 size; +} ACX_PACKED acx100_ie_memblocksize_t; + +typedef struct acx100_ie_queueconfig { + u16 type; + u16 len; + u32 AreaSize; + u32 RxQueueStart; + u8 QueueOptions; + u8 NumTxQueues; + u8 NumRxDesc; /* for USB only */ + u8 pad1; + u32 QueueEnd; + u32 HostQueueEnd; /* QueueEnd2 */ + u32 TxQueueStart; + u8 TxQueuePri; + u8 NumTxDesc; + u16 pad2; +} ACX_PACKED acx100_ie_queueconfig_t; + +typedef struct acx111_ie_queueconfig { + u16 type; + u16 len; + u32 tx_memory_block_address; + u32 rx_memory_block_address; + u32 rx1_queue_address; + u32 reserved1; + u32 tx1_queue_address; + u8 tx1_attributes; + u16 reserved2; + u8 reserved3; +} ACX_PACKED acx111_ie_queueconfig_t; + +typedef struct acx100_ie_memconfigoption { + u16 type; + u16 len; + u32 DMA_config; + acx_ptr pRxHostDesc; + u32 rx_mem; + u32 tx_mem; + u16 RxBlockNum; + u16 TxBlockNum; +} ACX_PACKED acx100_ie_memconfigoption_t; + +typedef struct acx111_ie_memoryconfig { + u16 type; + u16 len; + u16 no_of_stations; + u16 memory_block_size; + u8 tx_rx_memory_block_allocation; + u8 count_rx_queues; + u8 count_tx_queues; + u8 options; + u8 fragmentation; + u16 reserved1; + u8 reserved2; + + /* start of rx1 block */ + u8 rx_queue1_count_descs; + u8 rx_queue1_reserved1; + u8 rx_queue1_type; /* must be set to 7 */ + u8 rx_queue1_prio; /* must be set to 0 */ + acx_ptr rx_queue1_host_rx_start; + /* end of rx1 block */ + + /* start of tx1 block */ + u8 tx_queue1_count_descs; + u8 tx_queue1_reserved1; + u8 tx_queue1_reserved2; + u8 tx_queue1_attributes; + /* end of tx1 block */ +} ACX_PACKED acx111_ie_memoryconfig_t; + +typedef struct acx_ie_memmap { + u16 type; + u16 len; + u32 CodeStart; + u32 CodeEnd; + u32 WEPCacheStart; + u32 WEPCacheEnd; + u32 PacketTemplateStart; + u32 PacketTemplateEnd; + u32 QueueStart; + u32 QueueEnd; + u32 PoolStart; + u32 PoolEnd; +} ACX_PACKED acx_ie_memmap_t; + +typedef struct acx111_ie_feature_config { + u16 type; + u16 len; + u32 feature_options; + u32 data_flow_options; +} ACX_PACKED acx111_ie_feature_config_t; + +typedef struct acx111_ie_tx_level { + u16 type; + u16 len; + u8 level; +} ACX_PACKED acx111_ie_tx_level_t; + +#define PS_CFG_ENABLE 0x80 +#define PS_CFG_PENDING 0x40 /* status flag when entering PS */ +#define PS_CFG_WAKEUP_MODE_MASK 0x07 +#define PS_CFG_WAKEUP_BY_HOST 0x03 +#define PS_CFG_WAKEUP_EACH_ITVL 0x02 +#define PS_CFG_WAKEUP_ON_DTIM 0x01 +#define PS_CFG_WAKEUP_ALL_BEAC 0x00 + +/* Enhanced PS mode: sleep until Rx Beacon w/ the STA's AID bit set +** in the TIM; newer firmwares only(?) */ +#define PS_OPT_ENA_ENHANCED_PS 0x04 +#define PS_OPT_TX_PSPOLL 0x02 /* send PSPoll frame to fetch waiting frames from AP (on frame with matching AID) */ +#define PS_OPT_STILL_RCV_BCASTS 0x01 + +typedef struct acx100_ie_powersave { + u16 type; + u16 len; + u8 wakeup_cfg; + u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */ + u8 options; + u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */ + u16 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */ +} ACX_PACKED acx100_ie_powersave_t; + +typedef struct acx111_ie_powersave { + u16 type; + u16 len; + u8 wakeup_cfg; + u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */ + u8 options; + u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */ + u32 beacon_rx_time; + u32 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */ +} ACX_PACKED acx111_ie_powersave_t; + + +/*********************************************************************** +** Commands and template structures +*/ + +/* +** SCAN command structure +** +** even though acx100 scan rates match RATE100 constants, +** acx111 ones do not match! Therefore we do not use RATE100 #defines */ +#define ACX_SCAN_RATE_1 10 +#define ACX_SCAN_RATE_2 20 +#define ACX_SCAN_RATE_5 55 +#define ACX_SCAN_RATE_11 110 +#define ACX_SCAN_RATE_22 220 +#define ACX_SCAN_RATE_PBCC 0x80 /* OR with this if needed */ +#define ACX_SCAN_OPT_ACTIVE 0x00 /* a bit mask */ +#define ACX_SCAN_OPT_PASSIVE 0x01 +/* Background scan: we go into Power Save mode (by transmitting +** NULL data frame to AP with the power mgmt bit set), do the scan, +** and then exit Power Save mode. A plus is that AP buffers frames +** for us while we do background scan. Thus we avoid frame losses. +** Background scan can be active or passive, just like normal one */ +#define ACX_SCAN_OPT_BACKGROUND 0x02 +typedef struct acx100_scan { + u16 count; /* number of scans to do, 0xffff == continuous */ + u16 start_chan; + u16 flags; /* channel list mask; 0x8000 == all channels? */ + u8 max_rate; /* max. probe rate */ + u8 options; /* bit mask, see defines above */ + u16 chan_duration; + u16 max_probe_delay; +} ACX_PACKED acx100_scan_t; /* length 0xc */ + +#define ACX111_SCAN_RATE_6 0x0B +#define ACX111_SCAN_RATE_9 0x0F +#define ACX111_SCAN_RATE_12 0x0A +#define ACX111_SCAN_RATE_18 0x0E +#define ACX111_SCAN_RATE_24 0x09 +#define ACX111_SCAN_RATE_36 0x0D +#define ACX111_SCAN_RATE_48 0x08 +#define ACX111_SCAN_RATE_54 0x0C +#define ACX111_SCAN_OPT_5GHZ 0x04 /* else 2.4GHZ */ +#define ACX111_SCAN_MOD_SHORTPRE 0x01 /* you can combine SHORTPRE and PBCC */ +#define ACX111_SCAN_MOD_PBCC 0x80 +#define ACX111_SCAN_MOD_OFDM 0x40 +typedef struct acx111_scan { + u16 count; /* number of scans to do */ + u8 channel_list_select; /* 0: scan all channels, 1: from chan_list only */ + u16 reserved1; + u8 reserved2; + u8 rate; /* rate for probe requests (if active scan) */ + u8 options; /* bit mask, see defines above */ + u16 chan_duration; /* min time to wait for reply on one channel (in TU) */ + /* (active scan only) (802.11 section 11.1.3.2.2) */ + u16 max_probe_delay; /* max time to wait for reply on one channel (active scan) */ + /* time to listen on a channel (passive scan) */ + u8 modulation; + u8 channel_list[26]; /* bits 7:0 first byte: channels 8:1 */ + /* bits 7:0 second byte: channels 16:9 */ + /* 26 bytes is enough to cover 802.11a */ +} ACX_PACKED acx111_scan_t; + + +/* +** Radio calibration command structure +*/ +typedef struct acx111_cmd_radiocalib { +/* 0x80000000 == automatic calibration by firmware, according to interval; + * bits 0..3: select calibration methods to go through: + * calib based on DC, AfeDC, Tx mismatch, Tx equilization */ + u32 methods; + u32 interval; +} ACX_PACKED acx111_cmd_radiocalib_t; + + +/* +** Packet template structures +** +** Packet templates store contents of Beacon, Probe response, Probe request, +** Null data frame, and TIM data frame. Firmware automatically transmits +** contents of template at appropriate time: +** - Beacon: when configured as AP or Ad-hoc +** - Probe response: when configured as AP or Ad-hoc, whenever +** a Probe request frame is received +** - Probe request: when host issues SCAN command (active) +** - Null data frame: when entering 802.11 power save mode +** - TIM data: at the end of Beacon frames (if no TIM template +** is configured, then transmits default TIM) +** NB: +** - size field must be set to size of actual template +** (NOT sizeof(struct) - templates are variable in length), +** size field is not itself counted. +** - members flagged with an asterisk must be initialized with host, +** rest must be zero filled. +** - variable length fields shown only in comments */ +typedef struct acx_template_tim { + u16 size; + u8 tim_eid; /* 00 1 TIM IE ID * */ + u8 len; /* 01 1 Length * */ + u8 dtim_cnt; /* 02 1 DTIM Count */ + u8 dtim_period; /* 03 1 DTIM Period */ + u8 bitmap_ctrl; /* 04 1 Bitmap Control * (except bit0) */ + /* 05 n Partial Virtual Bitmap * */ + u8 variable[0x100 - 1-1-1-1-1]; +} ACX_PACKED acx_template_tim_t; + +typedef struct acx_template_probereq { + u16 size; + u16 fc; /* 00 2 fc * */ + u16 dur; /* 02 2 Duration */ + u8 da[6]; /* 04 6 Destination Address * */ + u8 sa[6]; /* 0A 6 Source Address * */ + u8 bssid[6]; /* 10 6 BSSID * */ + u16 seq; /* 16 2 Sequence Control */ + /* 18 n SSID * */ + /* nn n Supported Rates * */ + u8 variable[0x44 - 2-2-6-6-6-2]; +} ACX_PACKED acx_template_probereq_t; + +typedef struct acx_template_proberesp { + u16 size; + u16 fc; /* 00 2 fc * (bits [15:12] and [10:8] per 802.11 section 7.1.3.1) */ + u16 dur; /* 02 2 Duration */ + u8 da[6]; /* 04 6 Destination Address */ + u8 sa[6]; /* 0A 6 Source Address */ + u8 bssid[6]; /* 10 6 BSSID */ + u16 seq; /* 16 2 Sequence Control */ + u8 timestamp[8];/* 18 8 Timestamp */ + u16 beacon_interval; /* 20 2 Beacon Interval * */ + u16 cap; /* 22 2 Capability Information * */ + /* 24 n SSID * */ + /* nn n Supported Rates * */ + /* nn 1 DS Parameter Set * */ + u8 variable[0x54 - 2-2-6-6-6-2-8-2-2]; +} ACX_PACKED acx_template_proberesp_t; +#define acx_template_beacon_t acx_template_proberesp_t +#define acx_template_beacon acx_template_proberesp + +typedef struct acx_template_nullframe { + u16 size; + struct wlan_hdr_a3 hdr; +} ACX_PACKED acx_template_nullframe_t; + + +/* +** JOIN command structure +** +** as opposed to acx100, acx111 dtim interval is AFTER rates_basic111. +** NOTE: took me about an hour to get !@#$%^& packing right --> struct packing is eeeeevil... */ +typedef struct acx_joinbss { + u8 bssid[ETH_ALEN]; + u16 beacon_interval; + union { + struct { + u8 dtim_interval; + u8 rates_basic; + u8 rates_supported; + } ACX_PACKED acx100; + struct { + u16 rates_basic; + u8 dtim_interval; + } ACX_PACKED acx111; + } ACX_PACKED u; + u8 genfrm_txrate; /* generated frame (bcn, proberesp, RTS, PSpoll) tx rate */ + u8 genfrm_mod_pre; /* generated frame modulation/preamble: + ** bit7: PBCC, bit6: OFDM (else CCK/DQPSK/DBPSK) + ** bit5: short pre */ + u8 macmode; /* BSS Type, must be one of ACX_MODE_xxx */ + u8 channel; + u8 essid_len; + char essid[IW_ESSID_MAX_SIZE]; +} ACX_PACKED acx_joinbss_t; + +#define JOINBSS_RATES_1 0x01 +#define JOINBSS_RATES_2 0x02 +#define JOINBSS_RATES_5 0x04 +#define JOINBSS_RATES_11 0x08 +#define JOINBSS_RATES_22 0x10 + +/* Looks like missing bits are used to indicate 11g rates! +** (it follows from the fact that constants below match 1:1 to RATE111_nn) +** This was actually seen! Look at that Assoc Request sent by acx111, +** it _does_ contain 11g rates in basic set: +01:30:20.070772 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1 +01:30:20.074425 Authentication (Open System)-1: Succesful +01:30:20.076539 Authentication (Open System)-2: +01:30:20.076620 Acknowledgment +01:30:20.088546 Assoc Request (xxx) [1.0* 2.0* 5.5* 6.0* 9.0* 11.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] +01:30:20.122413 Assoc Response AID(1) :: Succesful +01:30:20.122679 Acknowledgment +01:30:20.173204 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1 +*/ +#define JOINBSS_RATES_BASIC111_1 0x0001 +#define JOINBSS_RATES_BASIC111_2 0x0002 +#define JOINBSS_RATES_BASIC111_5 0x0004 +#define JOINBSS_RATES_BASIC111_11 0x0020 +#define JOINBSS_RATES_BASIC111_22 0x0100 + + +/*********************************************************************** +*/ +typedef struct mem_read_write { + u16 addr; + u16 type; /* 0x0 int. RAM / 0xffff MAC reg. / 0x81 PHY RAM / 0x82 PHY reg.; or maybe it's actually 0x30 for MAC? Better verify it by writing and reading back and checking whether the value holds! */ + u32 len; + u32 data; +} ACX_PACKED mem_read_write_t; + +typedef struct firmware_image { + u32 chksum; + u32 size; + u8 data[1]; /* the byte array of the actual firmware... */ +} ACX_PACKED firmware_image_t; + +typedef struct acx_cmd_radioinit { + u32 offset; + u32 len; +} ACX_PACKED acx_cmd_radioinit_t; + +typedef struct acx100_ie_wep_options { + u16 type; + u16 len; + u16 NumKeys; /* max # of keys */ + u8 WEPOption; /* 0 == decrypt default key only, 1 == override decrypt */ + u8 Pad; /* used only for acx111 */ +} ACX_PACKED acx100_ie_wep_options_t; + +typedef struct ie_dot11WEPDefaultKey { + u16 type; + u16 len; + u8 action; + u8 keySize; + u8 defaultKeyNum; + u8 key[29]; /* check this! was Key[19] */ +} ACX_PACKED ie_dot11WEPDefaultKey_t; + +typedef struct acx111WEPDefaultKey { + u8 MacAddr[ETH_ALEN]; + u16 action; /* NOTE: this is a u16, NOT a u8!! */ + u16 reserved; + u8 keySize; + u8 type; + u8 index; + u8 defaultKeyNum; + u8 counter[6]; + u8 key[32]; /* up to 32 bytes (for TKIP!) */ +} ACX_PACKED acx111WEPDefaultKey_t; + +typedef struct ie_dot11WEPDefaultKeyID { + u16 type; + u16 len; + u8 KeyID; +} ACX_PACKED ie_dot11WEPDefaultKeyID_t; + +typedef struct acx100_cmd_wep_mgmt { + u8 MacAddr[ETH_ALEN]; + u16 Action; + u16 KeySize; + u8 Key[29]; /* 29*8 == 232bits == WEP256 */ +} ACX_PACKED acx100_cmd_wep_mgmt_t; + +typedef struct acx_ie_generic { + u16 type; + u16 len; + union { + /* Association ID IE: just a 16bit value: */ + u16 aid; + /* generic member for quick implementation of commands */ + u8 bytes[32]; + } ACX_PACKED m; +} ACX_PACKED acx_ie_generic_t; + +/*********************************************************************** +*/ +#define CHECK_SIZEOF(type,size) { \ + extern void BUG_bad_size_for_##type(void); \ + if (sizeof(type)!=(size)) BUG_bad_size_for_##type(); \ +} + +static inline void +acx_struct_size_check(void) +{ + CHECK_SIZEOF(txdesc_t, 0x30); + CHECK_SIZEOF(acx100_ie_memconfigoption_t, 24); + CHECK_SIZEOF(acx100_ie_queueconfig_t, 0x20); + CHECK_SIZEOF(acx_joinbss_t, 0x30); + /* IEs need 4 bytes for (type,len) tuple */ + CHECK_SIZEOF(acx111_ie_configoption_t, ACX111_IE_CONFIG_OPTIONS_LEN + 4); +} + + +/*********************************************************************** +** Global data +*/ +extern const u8 acx_bitpos2ratebyte[]; +extern const u8 acx_bitpos2rate100[]; + +extern const u8 acx_reg_domain_ids[]; +extern const char * const acx_reg_domain_strings[]; +enum { + acx_reg_domain_ids_len = 8 +}; + +extern const struct iw_handler_def acx_ioctl_handler_def; --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan_hdr.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan_hdr.h @@ -0,0 +1,497 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +/* mini-doc + +Here are all 11b/11g/11a rates and modulations: + + 11b 11g 11a + --- --- --- + 1 |B |B | + 2 |Q |Q | + 5.5|Cp |C p| + 6 | |Od |O + 9 | |od |o +11 |Cp |C p| +12 | |Od |O +18 | |od |o +22 | | p| +24 | |Od |O +33 | | p| +36 | |od |o +48 | |od |o +54 | |od |o + +Mandatory: + B - DBPSK (Differential Binary Phase Shift Keying) + Q - DQPSK (Differential Quaternary Phase Shift Keying) + C - CCK (Complementary Code Keying, a form of DSSS + (Direct Sequence Spread Spectrum) modulation) + O - OFDM (Orthogonal Frequency Division Multiplexing) +Optional: + o - OFDM + d - CCK-OFDM (also known as DSSS-OFDM) + p - PBCC (Packet Binary Convolutional Coding) + +The term CCK-OFDM may be used interchangeably with DSSS-OFDM +(the IEEE 802.11g-2003 standard uses the latter terminology). +In the CCK-OFDM, the PLCP header of the frame uses the CCK form of DSSS, +while the PLCP payload (the MAC frame) is modulated using OFDM. + +Basically, you must use CCK-OFDM if you have mixed 11b/11g environment, +or else (pure OFDM) 11b equipment may not realize that AP +is sending a packet and start sending its own one. +Sadly, looks like acx111 does not support CCK-OFDM, only pure OFDM. + +Re PBCC: avoid using it. It makes sense only if you have +TI "11b+" hardware. You _must_ use PBCC in order to reach 22Mbps on it. + +Preambles: + +Long preamble (at 1Mbit rate, takes 144 us): + 16 bytes ones + 2 bytes 0xF3A0 (lsb sent first) +PLCP header follows (at 1Mbit also): + 1 byte Signal: speed, in 0.1Mbit units, except for: + 33Mbit: 33 (instead of 330 - doesn't fit in octet) + all CCK-OFDM rates: 30 + 1 byte Service + 0,1,4: reserved + 2: 1=locked clock + 3: 1=PBCC + 5: Length Extension (PBCC 22,33Mbit (11g only)) <- + 6: Length Extension (PBCC 22,33Mbit (11g only)) <- BLACK MAGIC HERE + 7: Length Extension <- + 2 bytes Length (time needed to tx this frame) + a) 5.5 Mbit/s CCK + Length = octets*8/5.5, rounded up to integer + b) 11 Mbit/s CCK + Length = octets*8/11, rounded up to integer + Service bit 7: + 0 = rounding took less than 8/11 + 1 = rounding took more than or equal to 8/11 + c) 5.5 Mbit/s PBCC + Length = (octets+1)*8/5.5, rounded up to integer + d) 11 Mbit/s PBCC + Length = (octets+1)*8/11, rounded up to integer + Service bit 7: + 0 = rounding took less than 8/11 + 1 = rounding took more than or equal to 8/11 + e) 22 Mbit/s PBCC + Length = (octets+1)*8/22, rounded up to integer + Service bits 6,7: + 00 = rounding took less than 8/22ths + 01 = rounding took 8/22...15/22ths + 10 = rounding took 16/22ths or more. + f) 33 Mbit/s PBCC + Length = (octets+1)*8/33, rounded up to integer + Service bits 5,6,7: + 000 rounding took less than 8/33 + 001 rounding took 8/33...15/33 + 010 rounding took 16/33...23/33 + 011 rounding took 24/33...31/33 + 100 rounding took 32/33 or more + 2 bytes CRC + +PSDU follows (up to 2346 bytes at selected rate) + +While Signal value alone is not enough to determine rate and modulation, +Signal+Service is always sufficient. + +Short preamble (at 1Mbit rate, takes 72 us): + 7 bytes zeroes + 2 bytes 0x05CF (lsb sent first) +PLCP header follows *at 2Mbit/s*. Format is the same as in long preamble. +PSDU follows (up to 2346 bytes at selected rate) + +OFDM preamble is completely different, uses OFDM +modulation from the start and thus easily identifiable. +Not shown here. +*/ + + +/*********************************************************************** +** Constants +*/ + +#define WLAN_HDR_A3_LEN 24 +#define WLAN_HDR_A4_LEN 30 +/* IV structure: +** 3 bytes: Initialization Vector (24 bits) +** 1 byte: 0..5: padding, must be 0; 6..7: key selector (0-3) +*/ +#define WLAN_WEP_IV_LEN 4 +/* 802.11 says 2312 but looks like 2312 is a max size of _WEPed data_ */ +#define WLAN_DATA_MAXLEN 2304 +#define WLAN_WEP_ICV_LEN 4 +#define WLAN_FCS_LEN 4 +#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN) +#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN) +#define WLAN_A3FR_MAXLEN_FCS (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + 4) +#define WLAN_A4FR_MAXLEN_FCS (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + 4) +#define WLAN_A3FR_MAXLEN_WEP (WLAN_A3FR_MAXLEN + 8) +#define WLAN_A4FR_MAXLEN_WEP (WLAN_A4FR_MAXLEN + 8) +#define WLAN_A3FR_MAXLEN_WEP_FCS (WLAN_A3FR_MAXLEN_FCS + 8) +#define WLAN_A4FR_MAXLEN_WEP_FCS (WLAN_A4FR_MAXLEN_FCS + 8) + +#define WLAN_BSS_TS_LEN 8 +#define WLAN_SSID_MAXLEN 32 +#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334) +#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0) +#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48) +#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54) +#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16) +#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44) +#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78) +#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261) +#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2) +#define WLAN_CHALLENGE_IE_LEN 130 +#define WLAN_CHALLENGE_LEN 128 +#define WLAN_WEP_MAXKEYLEN 13 +#define WLAN_WEP_NKEYS 4 + +/*--- Frame Control Field -------------------------------------*/ +/* Frame Types */ +#define WLAN_FTYPE_MGMT 0x00 +#define WLAN_FTYPE_CTL 0x01 +#define WLAN_FTYPE_DATA 0x02 + +/* Frame subtypes */ +/* Management */ +#define WLAN_FSTYPE_ASSOCREQ 0x00 +#define WLAN_FSTYPE_ASSOCRESP 0x01 +#define WLAN_FSTYPE_REASSOCREQ 0x02 +#define WLAN_FSTYPE_REASSOCRESP 0x03 +#define WLAN_FSTYPE_PROBEREQ 0x04 +#define WLAN_FSTYPE_PROBERESP 0x05 +#define WLAN_FSTYPE_BEACON 0x08 +#define WLAN_FSTYPE_ATIM 0x09 +#define WLAN_FSTYPE_DISASSOC 0x0a +#define WLAN_FSTYPE_AUTHEN 0x0b +#define WLAN_FSTYPE_DEAUTHEN 0x0c + +/* Control */ +#define WLAN_FSTYPE_PSPOLL 0x0a +#define WLAN_FSTYPE_RTS 0x0b +#define WLAN_FSTYPE_CTS 0x0c +#define WLAN_FSTYPE_ACK 0x0d +#define WLAN_FSTYPE_CFEND 0x0e +#define WLAN_FSTYPE_CFENDCFACK 0x0f + +/* Data */ +#define WLAN_FSTYPE_DATAONLY 0x00 +#define WLAN_FSTYPE_DATA_CFACK 0x01 +#define WLAN_FSTYPE_DATA_CFPOLL 0x02 +#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03 +#define WLAN_FSTYPE_NULL 0x04 +#define WLAN_FSTYPE_CFACK 0x05 +#define WLAN_FSTYPE_CFPOLL 0x06 +#define WLAN_FSTYPE_CFACK_CFPOLL 0x07 + +/*--- FC Constants v. 2.0 ------------------------------------*/ +/* Each constant is defined twice: WF_CONST is in host */ +/* byteorder, WF_CONSTi is in ieee byteorder. */ +/* Usage: */ +/* printf("the frame subtype is %X", WF_FC_FTYPEi & rx.fc); */ +/* tx.fc = WF_FTYPE_CTLi | WF_FSTYPE_RTSi; */ +/*------------------------------------------------------------*/ + +enum { +/*--- Frame Control Field -------------------------------------*/ +/* Protocol version: always 0 for current 802.11 standards */ +IEEE16(WF_FC_PVER, 0x0003) +IEEE16(WF_FC_FTYPE, 0x000c) +IEEE16(WF_FC_FSTYPE, 0x00f0) +IEEE16(WF_FC_TODS, 0x0100) +IEEE16(WF_FC_FROMDS, 0x0200) +IEEE16(WF_FC_FROMTODS, 0x0300) +IEEE16(WF_FC_MOREFRAG, 0x0400) +IEEE16(WF_FC_RETRY, 0x0800) +/* Indicates PS mode in which STA will be after successful completion +** of current frame exchange sequence. Always 0 for AP frames */ +IEEE16(WF_FC_PWRMGT, 0x1000) +/* What MoreData=1 means: +** From AP to STA in PS mode: don't sleep yet, I have more frames for you +** From Contention-Free (CF) Pollable STA in response to a CF-Poll: +** STA has buffered frames for transmission in response to next CF-Poll +** Bcast/mcast frames transmitted from AP: +** when additional bcast/mcast frames remain to be transmitted by AP +** during this beacon interval +** In all other cases MoreData=0 */ +IEEE16(WF_FC_MOREDATA, 0x2000) +IEEE16(WF_FC_ISWEP, 0x4000) +IEEE16(WF_FC_ORDER, 0x8000) + +/* Frame Types */ +IEEE16(WF_FTYPE_MGMT, 0x00) +IEEE16(WF_FTYPE_CTL, 0x04) +IEEE16(WF_FTYPE_DATA, 0x08) + +/* Frame subtypes */ +/* Management */ +IEEE16(WF_FSTYPE_ASSOCREQ, 0x00) +IEEE16(WF_FSTYPE_ASSOCRESP, 0x10) +IEEE16(WF_FSTYPE_REASSOCREQ, 0x20) +IEEE16(WF_FSTYPE_REASSOCRESP, 0x30) +IEEE16(WF_FSTYPE_PROBEREQ, 0x40) +IEEE16(WF_FSTYPE_PROBERESP, 0x50) +IEEE16(WF_FSTYPE_BEACON, 0x80) +IEEE16(WF_FSTYPE_ATIM, 0x90) +IEEE16(WF_FSTYPE_DISASSOC, 0xa0) +IEEE16(WF_FSTYPE_AUTHEN, 0xb0) +IEEE16(WF_FSTYPE_DEAUTHEN, 0xc0) + +/* Control */ +IEEE16(WF_FSTYPE_PSPOLL, 0xa0) +IEEE16(WF_FSTYPE_RTS, 0xb0) +IEEE16(WF_FSTYPE_CTS, 0xc0) +IEEE16(WF_FSTYPE_ACK, 0xd0) +IEEE16(WF_FSTYPE_CFEND, 0xe0) +IEEE16(WF_FSTYPE_CFENDCFACK, 0xf0) + +/* Data */ +IEEE16(WF_FSTYPE_DATAONLY, 0x00) +IEEE16(WF_FSTYPE_DATA_CFACK, 0x10) +IEEE16(WF_FSTYPE_DATA_CFPOLL, 0x20) +IEEE16(WF_FSTYPE_DATA_CFACK_CFPOLL, 0x30) +IEEE16(WF_FSTYPE_NULL, 0x40) +IEEE16(WF_FSTYPE_CFACK, 0x50) +IEEE16(WF_FSTYPE_CFPOLL, 0x60) +IEEE16(WF_FSTYPE_CFACK_CFPOLL, 0x70) +}; + + +/*********************************************************************** +** Macros +*/ + +/*--- Duration Macros ----------------------------------------*/ +/* Macros to get/set the bitfields of the Duration Field */ +/* - the duration value is only valid when bit15 is zero */ +/* - the firmware handles these values, so I'm not going */ +/* to use these macros right now. */ +/*------------------------------------------------------------*/ + +/*--- Sequence Control Macros -------------------------------*/ +/* Macros to get/set the bitfields of the Sequence Control */ +/* Field. */ +/*------------------------------------------------------------*/ +#define WLAN_GET_SEQ_FRGNUM(n) ((u16)(n) & 0x000f) +#define WLAN_GET_SEQ_SEQNUM(n) (((u16)(n) & 0xfff0) >> 4) + +/*--- Data ptr macro -----------------------------------------*/ +/* Creates a u8* to the data portion of a frame */ +/* Assumes you're passing in a ptr to the beginning of the hdr*/ +/*------------------------------------------------------------*/ +#define WLAN_HDR_A3_DATAP(p) (((u8*)(p)) + WLAN_HDR_A3_LEN) +#define WLAN_HDR_A4_DATAP(p) (((u8*)(p)) + WLAN_HDR_A4_LEN) + + +/*********************************************************************** +** Types +*/ + +/* 802.11 header type +** +** Note the following: +** a1 *always* is receiver's mac or bcast/mcast +** a2 *always* is transmitter's mac, if a2 exists +** seq: [0:3] frag#, [4:15] seq# - used for dup detection +** (dups from retries have same seq#) */ +typedef struct wlan_hdr { + u16 fc; + u16 dur; + u8 a1[ETH_ALEN]; + u8 a2[ETH_ALEN]; + u8 a3[ETH_ALEN]; + u16 seq; + u8 a4[ETH_ALEN]; +} WLAN_PACKED wlan_hdr_t; + +/* Separate structs for use if frame type is known */ +typedef struct wlan_hdr_a3 { + u16 fc; + u16 dur; + u8 a1[ETH_ALEN]; + u8 a2[ETH_ALEN]; + u8 a3[ETH_ALEN]; + u16 seq; +} WLAN_PACKED wlan_hdr_a3_t; + +typedef struct wlan_hdr_mgmt { + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u16 seq; +} WLAN_PACKED wlan_hdr_mgmt_t; + +#ifdef NOT_NEEDED_YET +typedef struct { /* ad-hoc peer->peer (to/from DS = 0/0) */ + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u16 seq; +} WLAN_PACKED ibss; +typedef struct { /* ap->sta (to/from DS = 0/1) */ + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u16 seq; +} WLAN_PACKED fromap; +typedef struct { /* sta->ap (to/from DS = 1/0) */ + u16 fc; + u16 dur; + u8 bssid[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 da[ETH_ALEN]; + u16 seq; +} WLAN_PACKED toap; +typedef struct { /* wds->wds (to/from DS = 1/1), the only 4addr pkt */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 ta[ETH_ALEN]; + u8 da[ETH_ALEN]; + u16 seq; + u8 sa[ETH_ALEN]; +} WLAN_PACKED wds; +typedef struct { /* all management packets */ + u16 fc; + u16 dur; + u8 da[ETH_ALEN]; + u8 sa[ETH_ALEN]; + u8 bssid[ETH_ALEN]; + u16 seq; +} WLAN_PACKED mgmt; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} WLAN_PACKED rts; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; +} WLAN_PACKED cts; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; +} WLAN_PACKED ack; +typedef struct { /* has no body, just a FCS */ + u16 fc; + /* NB: this one holds Assoc ID in dur field: */ + u16 aid; + u8 bssid[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} WLAN_PACKED pspoll; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 bssid[ETH_ALEN]; +} WLAN_PACKED cfend; +typedef struct { /* has no body, just a FCS */ + u16 fc; + u16 dur; + u8 ra[ETH_ALEN]; + u8 bssid[ETH_ALEN]; +} WLAN_PACKED cfendcfack; +#endif + +/* Prism header emulation (monitor mode) */ +typedef struct wlanitem_u32 { + u32 did; + u16 status; + u16 len; + u32 data; +} WLAN_PACKED wlanitem_u32_t; +#define WLANITEM_STATUS_data_ok 0 +#define WLANITEM_STATUS_no_value 1 +#define WLANITEM_STATUS_invalid_itemname 2 +#define WLANITEM_STATUS_invalid_itemdata 3 +#define WLANITEM_STATUS_missing_itemdata 4 +#define WLANITEM_STATUS_incomplete_itemdata 5 +#define WLANITEM_STATUS_invalid_msg_did 6 +#define WLANITEM_STATUS_invalid_mib_did 7 +#define WLANITEM_STATUS_missing_conv_func 8 +#define WLANITEM_STATUS_string_too_long 9 +#define WLANITEM_STATUS_data_out_of_range 10 +#define WLANITEM_STATUS_string_too_short 11 +#define WLANITEM_STATUS_missing_valid_func 12 +#define WLANITEM_STATUS_unknown 13 +#define WLANITEM_STATUS_invalid_did 14 +#define WLANITEM_STATUS_missing_print_func 15 + +#define WLAN_DEVNAMELEN_MAX 16 +typedef struct wlansniffrm { + u32 msgcode; + u32 msglen; + u8 devname[WLAN_DEVNAMELEN_MAX]; + wlanitem_u32_t hosttime; + wlanitem_u32_t mactime; + wlanitem_u32_t channel; + wlanitem_u32_t rssi; + wlanitem_u32_t sq; + wlanitem_u32_t signal; + wlanitem_u32_t noise; + wlanitem_u32_t rate; + wlanitem_u32_t istx; /* tx? 0:no 1:yes */ + wlanitem_u32_t frmlen; +} WLAN_PACKED wlansniffrm_t; +#define WLANSNIFFFRM 0x0041 +#define WLANSNIFFFRM_hosttime 0x1041 +#define WLANSNIFFFRM_mactime 0x2041 +#define WLANSNIFFFRM_channel 0x3041 +#define WLANSNIFFFRM_rssi 0x4041 +#define WLANSNIFFFRM_sq 0x5041 +#define WLANSNIFFFRM_signal 0x6041 +#define WLANSNIFFFRM_noise 0x7041 +#define WLANSNIFFFRM_rate 0x8041 +#define WLANSNIFFFRM_istx 0x9041 +#define WLANSNIFFFRM_frmlen 0xA041 --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/conv.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/conv.c @@ -0,0 +1,504 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) +#include +#endif +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +** proto_is_stt +** +** Searches the 802.1h Selective Translation Table for a given +** protocol. +** +** prottype - protocol number (in host order) to search for. +** +** Returns: +** 1 - if the table is empty or a match is found. +** 0 - if the table is non-empty and a match is not found. +** +** Based largely on p80211conv.c of the linux-wlan-ng project +*/ +static inline int +proto_is_stt(unsigned int proto) +{ + /* Always return found for now. This is the behavior used by the */ + /* Zoom Win95 driver when 802.1h mode is selected */ + /* TODO: If necessary, add an actual search we'll probably + need this to match the CMAC's way of doing things. + Need to do some testing to confirm. + */ + + if (proto == 0x80f3) /* APPLETALK */ + return 1; + + return 0; +/* return ((prottype == ETH_P_AARP) || (prottype == ETH_P_IPX)); */ +} + +/* Helpers */ + +static inline void +store_llc_snap(struct wlan_llc *llc) +{ + llc->dsap = 0xaa; /* SNAP, see IEEE 802 */ + llc->ssap = 0xaa; + llc->ctl = 0x03; +} +static inline int +llc_is_snap(const struct wlan_llc *llc) +{ + return (llc->dsap == 0xaa) + && (llc->ssap == 0xaa) + && (llc->ctl == 0x03); +} +static inline void +store_oui_rfc1042(struct wlan_snap *snap) +{ + snap->oui[0] = 0; + snap->oui[1] = 0; + snap->oui[2] = 0; +} +static inline int +oui_is_rfc1042(const struct wlan_snap *snap) +{ + return (snap->oui[0] == 0) + && (snap->oui[1] == 0) + && (snap->oui[2] == 0); +} +static inline void +store_oui_8021h(struct wlan_snap *snap) +{ + snap->oui[0] = 0; + snap->oui[1] = 0; + snap->oui[2] = 0xf8; +} +static inline int +oui_is_8021h(const struct wlan_snap *snap) +{ + return (snap->oui[0] == 0) + && (snap->oui[1] == 0) + && (snap->oui[2] == 0xf8); +} + + +/*********************************************************************** +** acx_ether_to_txbuf +** +** Uses the contents of the ether frame to build the elements of +** the 802.11 frame. +** +** We don't actually set up the frame header here. That's the +** MAC's job. We're only handling conversion of DIXII or 802.3+LLC +** frames to something that works with 802.11. +** +** Based largely on p80211conv.c of the linux-wlan-ng project +*/ +int +acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb) +{ + struct wlan_hdr_a3 *w_hdr; + struct wlan_ethhdr *e_hdr; + struct wlan_llc *e_llc; + struct wlan_snap *e_snap; + const u8 *a1, *a3; + int header_len, payload_len = -1; + /* protocol type or data length, depending on whether + * DIX or 802.3 ethernet format */ + u16 proto; + u16 fc; + + FN_ENTER; + + if (unlikely(!skb->len)) { + log(L_DEBUG, "zero-length skb!\n"); + goto end; + } + + w_hdr = (struct wlan_hdr_a3*)txbuf; + + switch (adev->mode) { + case ACX_MODE_MONITOR: + /* NB: one day we might want to play with DESC_CTL2_FCS + ** Will need to stop doing "- WLAN_FCS_LEN" here then */ + if (unlikely(skb->len >= WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_FCS_LEN)) { + printk("%s: can't tx oversized frame (%d bytes)\n", + adev->ndev->name, skb->len); + goto end; + } + memcpy(w_hdr, skb->data, skb->len); + payload_len = skb->len; + goto end; + } + + /* step 1: classify ether frame, DIX or 802.3? */ + e_hdr = (wlan_ethhdr_t *)skb->data; + proto = ntohs(e_hdr->type); + if (proto <= 1500) { + log(L_DEBUG, "tx: 802.3 len: %d\n", skb->len); + /* codes <= 1500 reserved for 802.3 lengths */ + /* it's 802.3, pass ether payload unchanged, */ + /* trim off ethernet header and copy payload to txdesc */ + header_len = WLAN_HDR_A3_LEN; + } else { + /* it's DIXII, time for some conversion */ + /* Create 802.11 packet. Header also contains llc and snap. */ + + log(L_DEBUG, "tx: DIXII len: %d\n", skb->len); + + /* size of header is 802.11 header + llc + snap */ + header_len = WLAN_HDR_A3_LEN + sizeof(wlan_llc_t) + sizeof(wlan_snap_t); + /* llc is located behind the 802.11 header */ + e_llc = (wlan_llc_t*)(w_hdr + 1); + /* snap is located behind the llc */ + e_snap = (wlan_snap_t*)(e_llc + 1); + + /* setup the LLC header */ + store_llc_snap(e_llc); + + /* setup the SNAP header */ + e_snap->type = htons(proto); + if (proto_is_stt(proto)) { + store_oui_8021h(e_snap); + } else { + store_oui_rfc1042(e_snap); + } + } + /* trim off ethernet header and copy payload to txbuf */ + payload_len = skb->len - sizeof(wlan_ethhdr_t); + /* TODO: can we just let acx DMA payload from skb instead? */ + memcpy((u8*)txbuf + header_len, skb->data + sizeof(wlan_ethhdr_t), payload_len); + payload_len += header_len; + + /* Set up the 802.11 header */ + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi); + a1 = e_hdr->daddr; + a3 = adev->bssid; + break; + case ACX_MODE_2_STA: + fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_TODSi); + a1 = adev->bssid; + a3 = e_hdr->daddr; + break; + case ACX_MODE_3_AP: + fc = (WF_FTYPE_DATAi | WF_FSTYPE_DATAONLYi | WF_FC_FROMDSi); + a1 = e_hdr->daddr; + a3 = e_hdr->saddr; + break; + default: + printk("%s: error - converting eth to wlan in unknown mode\n", + adev->ndev->name); + payload_len = -1; + goto end; + } + if (adev->wep_enabled) + SET_BIT(fc, WF_FC_ISWEPi); + + w_hdr->fc = fc; + w_hdr->dur = 0; + MAC_COPY(w_hdr->a1, a1); + MAC_COPY(w_hdr->a2, adev->dev_addr); + MAC_COPY(w_hdr->a3, a3); + w_hdr->seq = 0; + +#ifdef DEBUG_CONVERT + if (acx_debug & L_DATA) { + printk("original eth frame [%d]: ", skb->len); + acx_dump_bytes(skb->data, skb->len); + printk("802.11 frame [%d]: ", payload_len); + acx_dump_bytes(w_hdr, payload_len); + } +#endif + +end: + FN_EXIT1(payload_len); + return payload_len; +} + + +/*********************************************************************** +** acx_rxbuf_to_ether +** +** Uses the contents of a received 802.11 frame to build an ether +** frame. +** +** This function extracts the src and dest address from the 802.11 +** frame to use in the construction of the eth frame. +** +** Based largely on p80211conv.c of the linux-wlan-ng project +*/ +struct sk_buff* +acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + struct wlan_hdr *w_hdr; + struct wlan_ethhdr *e_hdr; + struct wlan_llc *e_llc; + struct wlan_snap *e_snap; + struct sk_buff *skb; + const u8 *daddr; + const u8 *saddr; + const u8 *e_payload; + int buflen, payload_length; + unsigned int payload_offset, mtu; + u16 fc; + + FN_ENTER; + + /* This looks complex because it must handle possible + ** phy header in rxbuff */ + w_hdr = acx_get_wlan_hdr(adev, rxbuf); + payload_offset = WLAN_HDR_A3_LEN; /* it is relative to w_hdr */ + payload_length = RXBUF_BYTES_USED(rxbuf) /* entire rxbuff... */ + - ((u8*)w_hdr - (u8*)rxbuf) /* minus space before 802.11 frame */ + - WLAN_HDR_A3_LEN; /* minus 802.11 header */ + + /* setup some vars for convenience */ + fc = w_hdr->fc; + switch (WF_FC_FROMTODSi & fc) { + case 0: + daddr = w_hdr->a1; + saddr = w_hdr->a2; + break; + case WF_FC_FROMDSi: + daddr = w_hdr->a1; + saddr = w_hdr->a3; + break; + case WF_FC_TODSi: + daddr = w_hdr->a3; + saddr = w_hdr->a2; + break; + default: /* WF_FC_FROMTODSi */ + payload_offset += (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); + payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); + daddr = w_hdr->a3; + saddr = w_hdr->a4; + } + + if ((WF_FC_ISWEPi & fc) && IS_ACX100(adev)) { + /* chop off the IV+ICV WEP header and footer */ + log(L_DATA|L_DEBUG, "rx: WEP packet, " + "chopping off IV and ICV\n"); + payload_offset += WLAN_WEP_IV_LEN; + payload_length -= WLAN_WEP_IV_LEN + WLAN_WEP_ICV_LEN; + } + + if (unlikely(payload_length < 0)) { + printk("%s: rx frame too short, ignored\n", adev->ndev->name); + goto ret_null; + } + + e_hdr = (wlan_ethhdr_t*) ((u8*) w_hdr + payload_offset); + e_llc = (wlan_llc_t*) e_hdr; + e_snap = (wlan_snap_t*) (e_llc + 1); + mtu = adev->ndev->mtu; + e_payload = (u8*) (e_snap + 1); + + log(L_DATA, "rx: payload_offset %d, payload_length %d\n", + payload_offset, payload_length); + log(L_XFER|L_DATA, + "rx: frame info: llc=%02X%02X%02X " + "snap.oui=%02X%02X%02X snap.type=%04X\n", + e_llc->dsap, e_llc->ssap, e_llc->ctl, + e_snap->oui[0], e_snap->oui[1], e_snap->oui[2], + ntohs(e_snap->type)); + + /* Test for the various encodings */ + if ((payload_length >= sizeof(wlan_ethhdr_t)) + && ((e_llc->dsap != 0xaa) || (e_llc->ssap != 0xaa)) + && ( (mac_is_equal(daddr, e_hdr->daddr)) + || (mac_is_equal(saddr, e_hdr->saddr)) + ) + ) { + /* 802.3 Encapsulated: */ + /* wlan frame body contains complete eth frame (header+body) */ + log(L_DEBUG|L_DATA, "rx: 802.3 ENCAP len=%d\n", payload_length); + + if (unlikely(payload_length > (mtu + ETH_HLEN))) { + printk("%s: rx: ENCAP frame too large (%d > %d)\n", + adev->ndev->name, + payload_length, mtu + ETH_HLEN); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length; + /* Attempt to align IP header (14 bytes eth header + 2 = 16) */ + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* now copy the data from the 80211 frame */ + memcpy(skb->data, e_hdr, payload_length); + + } else if ( (payload_length >= sizeof(wlan_llc_t)+sizeof(wlan_snap_t)) + && llc_is_snap(e_llc) ) { + /* wlan frame body contains: AA AA 03 ... (it's a SNAP) */ + + if ( !oui_is_rfc1042(e_snap) + || (proto_is_stt(ieee2host16(e_snap->type)) /* && (ethconv == WLAN_ETHCONV_8021h) */)) { + log(L_DEBUG|L_DATA, "rx: SNAP+RFC1042 len=%d\n", payload_length); + /* wlan frame body contains: AA AA 03 !(00 00 00) ... -or- */ + /* wlan frame body contains: AA AA 03 00 00 00 0x80f3 ... */ + /* build eth hdr, type = len, copy AA AA 03... as eth body */ + /* it's a SNAP + RFC1042 frame && protocol is in STT */ + + if (unlikely(payload_length > mtu)) { + printk("%s: rx: SNAP frame too large (%d > %d)\n", + adev->ndev->name, + payload_length, mtu); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length + ETH_HLEN; + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* create 802.3 header */ + e_hdr = (wlan_ethhdr_t*) skb->data; + MAC_COPY(e_hdr->daddr, daddr); + MAC_COPY(e_hdr->saddr, saddr); + e_hdr->type = htons(payload_length); + + /* Now copy the data from the 80211 frame. + Make room in front for the eth header, and keep the + llc and snap from the 802.11 payload */ + memcpy(skb->data + ETH_HLEN, + e_llc, payload_length); + + } else { + /* wlan frame body contains: AA AA 03 00 00 00 [type] [tail] */ + /* build eth hdr, type=[type], copy [tail] as eth body */ + log(L_DEBUG|L_DATA, "rx: 802.1h/RFC1042 len=%d\n", + payload_length); + /* it's an 802.1h frame (an RFC1042 && protocol is not in STT) */ + /* build a DIXII + RFC894 */ + + payload_length -= sizeof(wlan_llc_t) + sizeof(wlan_snap_t); + if (unlikely(payload_length > mtu)) { + printk("%s: rx: DIXII frame too large (%d > %d)\n", + adev->ndev->name, + payload_length, mtu); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length + ETH_HLEN; + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* create 802.3 header */ + e_hdr = (wlan_ethhdr_t *) skb->data; + MAC_COPY(e_hdr->daddr, daddr); + MAC_COPY(e_hdr->saddr, saddr); + e_hdr->type = e_snap->type; + + /* Now copy the data from the 80211 frame. + Make room in front for the eth header, and cut off the + llc and snap from the 802.11 payload */ + memcpy(skb->data + ETH_HLEN, + e_payload, payload_length); + } + + } else { + log(L_DEBUG|L_DATA, "rx: NON-ENCAP len=%d\n", payload_length); + /* build eth hdr, type=len, copy wlan body as eth body */ + /* any NON-ENCAP */ + /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ + /* build an 802.3 frame */ + + if (unlikely(payload_length > mtu)) { + printk("%s: rx: OTHER frame too large (%d > %d)\n", + adev->ndev->name, payload_length, mtu); + goto ret_null; + } + + /* allocate space and setup host buffer */ + buflen = payload_length + ETH_HLEN; + skb = dev_alloc_skb(buflen + 2); + if (unlikely(!skb)) + goto no_skb; + skb_reserve(skb, 2); + skb_put(skb, buflen); /* make room */ + + /* set up the 802.3 header */ + e_hdr = (wlan_ethhdr_t *) skb->data; + MAC_COPY(e_hdr->daddr, daddr); + MAC_COPY(e_hdr->saddr, saddr); + e_hdr->type = htons(payload_length); + + /* now copy the data from the 80211 frame */ + memcpy(skb->data + ETH_HLEN, e_llc, payload_length); + } + + skb->dev = adev->ndev; + skb->protocol = eth_type_trans(skb, adev->ndev); + +#ifdef DEBUG_CONVERT + if (acx_debug & L_DATA) { + int len = RXBUF_BYTES_RCVD(adev, rxbuf); + printk("p802.11 frame [%d]: ", len); + acx_dump_bytes(w_hdr, len); + printk("eth frame [%d]: ", skb->len); + acx_dump_bytes(skb->data, skb->len); + } +#endif + + FN_EXIT0; + return skb; + +no_skb: + printk("%s: rx: no memory for skb (%d bytes)\n", + adev->ndev->name, buflen + 2); +ret_null: + FN_EXIT1((int)NULL); + return NULL; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx_func.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx_func.h @@ -0,0 +1,651 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + + +/*********************************************************************** +** LOGGING +** +** - Avoid SHOUTING needlessly. Avoid excessive verbosity. +** Gradually remove messages which are old debugging aids. +** +** - Use printk() for messages which are to be always logged. +** Supply either 'acx:' or ':' prefix so that user +** can figure out who's speaking among other kernel chatter. +** acx: is for general issues (e.g. "acx: no firmware image!") +** while : is related to a particular device +** (think about multi-card setup). Double check that message +** is not confusing to the average user. +** +** - use printk KERN_xxx level only if message is not a WARNING +** but is INFO, ERR etc. +** +** - Use printk_ratelimited() for messages which may flood +** (e.g. "rx DUP pkt!"). +** +** - Use log() for messages which may be omitted (and they +** _will_ be omitted in non-debug builds). Note that +** message levels may be disabled at compile-time selectively, +** thus select them wisely. Example: L_DEBUG is the lowest +** (most likely to be compiled out) -> use for less important stuff. +** +** - Do not print important stuff with log(), or else people +** will never build non-debug driver. +** +** Style: +** hex: capital letters, zero filled (e.g. 0x02AC) +** str: dont start from capitals, no trailing periods ("tx: queue is stopped") +*/ +#if ACX_DEBUG > 1 + +void log_fn_enter(const char *funcname); +void log_fn_exit(const char *funcname); +void log_fn_exit_v(const char *funcname, int v); + +#define FN_ENTER \ + do { \ + if (unlikely(acx_debug & L_FUNC)) { \ + log_fn_enter(__func__); \ + } \ + } while (0) + +#define FN_EXIT1(v) \ + do { \ + if (unlikely(acx_debug & L_FUNC)) { \ + log_fn_exit_v(__func__, v); \ + } \ + } while (0) +#define FN_EXIT0 \ + do { \ + if (unlikely(acx_debug & L_FUNC)) { \ + log_fn_exit(__func__); \ + } \ + } while (0) + +#else + +#define FN_ENTER +#define FN_EXIT1(v) +#define FN_EXIT0 + +#endif /* ACX_DEBUG > 1 */ + + +#if ACX_DEBUG + +#define log(chan, args...) \ + do { \ + if (acx_debug & (chan)) \ + printk(args); \ + } while (0) +#define printk_ratelimited(args...) printk(args) + +#else /* Non-debug build: */ + +#define log(chan, args...) +/* Standard way of log flood prevention */ +#define printk_ratelimited(args...) \ +do { \ + if (printk_ratelimit()) \ + printk(args); \ +} while (0) + +#endif /* ACX_DEBUG */ + +void acx_print_mac(const char *head, const u8 *mac, const char *tail); + +/* Optimized out to nothing in non-debug build */ +static inline void +acxlog_mac(int level, const char *head, const u8 *mac, const char *tail) +{ + if (acx_debug & level) { + acx_print_mac(head, mac, tail); + } +} + + +/*********************************************************************** +** MAC address helpers +*/ +static inline void +MAC_COPY(u8 *mac, const u8 *src) +{ + *(u32*)mac = *(u32*)src; + ((u16*)mac)[2] = ((u16*)src)[2]; + /* kernel's memcpy will do the same: memcpy(dst, src, ETH_ALEN); */ +} + +static inline void +MAC_FILL(u8 *mac, u8 val) +{ + memset(mac, val, ETH_ALEN); +} + +static inline void +MAC_BCAST(u8 *mac) +{ + ((u16*)mac)[2] = *(u32*)mac = -1; +} + +static inline void +MAC_ZERO(u8 *mac) +{ + ((u16*)mac)[2] = *(u32*)mac = 0; +} + +static inline int +mac_is_equal(const u8 *a, const u8 *b) +{ + /* can't beat this */ + return memcmp(a, b, ETH_ALEN) == 0; +} + +static inline int +mac_is_bcast(const u8 *mac) +{ + /* AND together 4 first bytes with sign-extended 2 last bytes + ** Only bcast address gives 0xffffffff. +1 gives 0 */ + return ( *(s32*)mac & ((s16*)mac)[2] ) + 1 == 0; +} + +static inline int +mac_is_zero(const u8 *mac) +{ + return ( *(u32*)mac | ((u16*)mac)[2] ) == 0; +} + +static inline int +mac_is_directed(const u8 *mac) +{ + return (mac[0] & 1)==0; +} + +static inline int +mac_is_mcast(const u8 *mac) +{ + return (mac[0] & 1) && !mac_is_bcast(mac); +} + +#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X" +#define MAC(bytevector) \ + ((unsigned char *)bytevector)[0], \ + ((unsigned char *)bytevector)[1], \ + ((unsigned char *)bytevector)[2], \ + ((unsigned char *)bytevector)[3], \ + ((unsigned char *)bytevector)[4], \ + ((unsigned char *)bytevector)[5] + + +/*********************************************************************** +** Random helpers +*/ +#define TO_STRING(x) #x +#define STRING(x) TO_STRING(x) + +#define CLEAR_BIT(val, mask) ((val) &= ~(mask)) +#define SET_BIT(val, mask) ((val) |= (mask)) + +/* undefined if v==0 */ +static inline unsigned int +lowest_bit(u16 v) +{ + unsigned int n = 0; + while (!(v & 0xf)) { v>>=4; n+=4; } + while (!(v & 1)) { v>>=1; n++; } + return n; +} + +/* undefined if v==0 */ +static inline unsigned int +highest_bit(u16 v) +{ + unsigned int n = 0; + while (v>0xf) { v>>=4; n+=4; } + while (v>1) { v>>=1; n++; } + return n; +} + +/* undefined if v==0 */ +static inline int +has_only_one_bit(u16 v) +{ + return ((v-1) ^ v) >= v; +} + + +static inline int +is_hidden_essid(char *essid) +{ + return (('\0' == essid[0]) || + ((' ' == essid[0]) && ('\0' == essid[1]))); +} + +/*********************************************************************** +** LOCKING +** We have adev->sem and adev->lock. +** +** We employ following naming convention in order to get locking right: +** +** acx_e_xxxx - external entry points called from process context. +** It is okay to sleep. adev->sem is to be taken on entry. +** acx_i_xxxx - external entry points possibly called from atomic context. +** Sleeping is not allowed (and thus down(sem) is not legal!) +** acx_s_xxxx - potentially sleeping functions. Do not ever call under lock! +** acx_l_xxxx - functions which expect lock to be already taken. +** rest - non-sleeping functions which do not require locking +** but may be run under lock +** +** A small number of local helpers do not have acx_[eisl]_ prefix. +** They are always close to caller and are to be reviewed locally. +** +** Theory of operation: +** +** All process-context entry points (_e_ functions) take sem +** immediately. IRQ handler and other 'atomic-context' entry points +** (_i_ functions) take lock immediately on entry, but dont take sem +** because that might sleep. +** +** Thus *all* code is either protected by sem or lock, or both. +** +** Code which must not run concurrently with IRQ takes lock. +** Such code is marked with _l_. +** +** This results in the following rules of thumb useful in code review: +** +** + If a function calls _s_ fn, it must be an _s_ itself. +** + You can call _l_ fn only (a) from another _l_ fn +** or (b) from _s_, _e_ or _i_ fn by taking lock, calling _l_, +** and dropping lock. +** + All IRQ code runs under lock. +** + Any _s_ fn is running under sem. +** + Code under sem can race only with IRQ code. +** + Code under sem+lock cannot race with anything. +*/ + +/* These functions *must* be inline or they will break horribly on SPARC, due + * to its weird semantics for save/restore flags */ + +#if defined(PARANOID_LOCKING) /* Lock debugging */ + +void acx_lock_debug(acx_device_t *adev, const char* where); +void acx_unlock_debug(acx_device_t *adev, const char* where); +void acx_down_debug(acx_device_t *adev, const char* where); +void acx_up_debug(acx_device_t *adev, const char* where); +void acx_lock_unhold(void); +void acx_sem_unhold(void); + +static inline void +acx_lock_helper(acx_device_t *adev, unsigned long *fp, const char* where) +{ + acx_lock_debug(adev, where); + spin_lock_irqsave(&adev->lock, *fp); +} +static inline void +acx_unlock_helper(acx_device_t *adev, unsigned long *fp, const char* where) +{ + acx_unlock_debug(adev, where); + spin_unlock_irqrestore(&adev->lock, *fp); +} +static inline void +acx_down_helper(acx_device_t *adev, const char* where) +{ + acx_down_debug(adev, where); +} +static inline void +acx_up_helper(acx_device_t *adev, const char* where) +{ + acx_up_debug(adev, where); +} +#define acx_lock(adev, flags) acx_lock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__)) +#define acx_unlock(adev, flags) acx_unlock_helper(adev, &(flags), __FILE__ ":" STRING(__LINE__)) +#define acx_sem_lock(adev) acx_down_helper(adev, __FILE__ ":" STRING(__LINE__)) +#define acx_sem_unlock(adev) acx_up_helper(adev, __FILE__ ":" STRING(__LINE__)) + +#elif defined(DO_LOCKING) + +#define acx_lock(adev, flags) spin_lock_irqsave(&adev->lock, flags) +#define acx_unlock(adev, flags) spin_unlock_irqrestore(&adev->lock, flags) +#define acx_sem_lock(adev) down(&adev->sem) +#define acx_sem_unlock(adev) up(&adev->sem) +#define acx_lock_unhold() ((void)0) +#define acx_sem_unhold() ((void)0) + +#else /* no locking! :( */ + +#define acx_lock(adev, flags) ((void)0) +#define acx_unlock(adev, flags) ((void)0) +#define acx_sem_lock(adev) ((void)0) +#define acx_sem_unlock(adev) ((void)0) +#define acx_lock_unhold() ((void)0) +#define acx_sem_unhold() ((void)0) + +#endif + + +/*********************************************************************** +*/ + +/* Can race with rx path (which is not protected by sem): +** rx -> process_[re]assocresp() -> set_status(ASSOCIATED) -> wake_queue() +** Can race with tx_complete IRQ: +** IRQ -> acxpci_l_clean_txdesc -> acx_wake_queue +** Review carefully all callsites */ +static inline void +acx_stop_queue(struct net_device *ndev, const char *msg) +{ + if (netif_queue_stopped(ndev)) + return; + + netif_stop_queue(ndev); + if (msg) + log(L_BUFT, "tx: stop queue %s\n", msg); +} + +static inline int +acx_queue_stopped(struct net_device *ndev) +{ + return netif_queue_stopped(ndev); +} + +/* +static inline void +acx_start_queue(struct net_device *ndev, const char *msg) +{ + netif_start_queue(ndev); + if (msg) + log(L_BUFT, "tx: start queue %s\n", msg); +} +*/ + +static inline void +acx_wake_queue(struct net_device *ndev, const char *msg) +{ + netif_wake_queue(ndev); + if (msg) + log(L_BUFT, "tx: wake queue %s\n", msg); +} + +static inline void +acx_carrier_off(struct net_device *ndev, const char *msg) +{ + netif_carrier_off(ndev); + if (msg) + log(L_BUFT, "tx: carrier off %s\n", msg); +} + +static inline void +acx_carrier_on(struct net_device *ndev, const char *msg) +{ + netif_carrier_on(ndev); + if (msg) + log(L_BUFT, "tx: carrier on %s\n", msg); +} + +/* This function does not need locking UNLESS you call it +** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can +** wake queue. This can race with stop_queue elsewhere. */ +void acx_set_status(acx_device_t *adev, u16 status); + + +/*********************************************************************** +** Communication with firmware +*/ +#define CMD_TIMEOUT_MS(n) (n) +#define ACX_CMD_TIMEOUT_DEFAULT CMD_TIMEOUT_MS(50) + +#if ACX_DEBUG + +/* We want to log cmd names */ +int acxpci_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); +int acxusb_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr); +static inline int +acx_s_issue_cmd_timeo_debug(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout, const char* cmdstr) +{ + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr); + return acxusb_s_issue_cmd_timeo_debug(adev, cmd, param, len, timeout, cmdstr); +} +#define acx_s_issue_cmd(adev,cmd,param,len) \ + acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,ACX_CMD_TIMEOUT_DEFAULT,#cmd) +#define acx_s_issue_cmd_timeo(adev,cmd,param,len,timeo) \ + acx_s_issue_cmd_timeo_debug(adev,cmd,param,len,timeo,#cmd) +int acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* str); +#define acx_s_configure(adev,pdr,type) \ + acx_s_configure_debug(adev,pdr,type,#type) +int acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type, const char* str); +#define acx_s_interrogate(adev,pdr,type) \ + acx_s_interrogate_debug(adev,pdr,type,#type) + +#else + +int acxpci_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout); +int acxusb_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout); +static inline int +acx_s_issue_cmd_timeo(acx_device_t *adev, unsigned cmd, void *param, unsigned len, unsigned timeout) +{ + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, timeout); + return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, timeout); +} +static inline int +acx_s_issue_cmd(acx_device_t *adev, unsigned cmd, void *param, unsigned len) +{ + if (IS_PCI(adev)) + return acxpci_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); + return acxusb_s_issue_cmd_timeo(adev, cmd, param, len, ACX_CMD_TIMEOUT_DEFAULT); +} +int acx_s_configure(acx_device_t *adev, void *pdr, int type); +int acx_s_interrogate(acx_device_t *adev, void *pdr, int type); + +#endif + +void acx_s_cmd_start_scan(acx_device_t *adev); + + +/*********************************************************************** +** Ioctls +*/ +int +acx111pci_ioctl_info( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra); +int +acx100pci_ioctl_set_phy_amp_bias( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra); + + +/*********************************************************************** +** /proc +*/ +#ifdef CONFIG_PROC_FS +int acx_proc_register_entries(const struct net_device *ndev); +int acx_proc_unregister_entries(const struct net_device *ndev); +#else +static inline int +acx_proc_register_entries(const struct net_device *ndev) { return OK; } +static inline int +acx_proc_unregister_entries(const struct net_device *ndev) { return OK; } +#endif + + +/*********************************************************************** +*/ +firmware_image_t *acx_s_read_fw(struct device *dev, const char *file, u32 *size); +int acxpci_s_upload_radio(acx_device_t *adev); + + +/*********************************************************************** +** Unsorted yet :) +*/ +int acxpci_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf); +int acxusb_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf); +static inline int +acx_s_read_phy_reg(acx_device_t *adev, u32 reg, u8 *charbuf) +{ + if (IS_PCI(adev)) + return acxpci_s_read_phy_reg(adev, reg, charbuf); + return acxusb_s_read_phy_reg(adev, reg, charbuf); +} + +int acxpci_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value); +int acxusb_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value); +static inline int +acx_s_write_phy_reg(acx_device_t *adev, u32 reg, u8 value) +{ + if (IS_PCI(adev)) + return acxpci_s_write_phy_reg(adev, reg, value); + return acxusb_s_write_phy_reg(adev, reg, value); +} + +tx_t* acxpci_l_alloc_tx(acx_device_t *adev); +tx_t* acxusb_l_alloc_tx(acx_device_t *adev); +static inline tx_t* +acx_l_alloc_tx(acx_device_t *adev) +{ + if (IS_PCI(adev)) + return acxpci_l_alloc_tx(adev); + return acxusb_l_alloc_tx(adev); +} + +void acxusb_l_dealloc_tx(tx_t *tx_opaque); +static inline void +acx_l_dealloc_tx(acx_device_t *adev, tx_t *tx_opaque) +{ + if (IS_USB(adev)) + acxusb_l_dealloc_tx(tx_opaque); +} + +void* acxpci_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque); +void* acxusb_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque); +static inline void* +acx_l_get_txbuf(acx_device_t *adev, tx_t *tx_opaque) +{ + if (IS_PCI(adev)) + return acxpci_l_get_txbuf(adev, tx_opaque); + return acxusb_l_get_txbuf(adev, tx_opaque); +} + +void acxpci_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len); +void acxusb_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len); +static inline void +acx_l_tx_data(acx_device_t *adev, tx_t *tx_opaque, int len) +{ + if (IS_PCI(adev)) + acxpci_l_tx_data(adev, tx_opaque, len); + else + acxusb_l_tx_data(adev, tx_opaque, len); +} + +static inline wlan_hdr_t* +acx_get_wlan_hdr(acx_device_t *adev, const rxbuffer_t *rxbuf) +{ + return (wlan_hdr_t*)((u8*)&rxbuf->hdr_a3 + adev->phy_header_len); +} + +void acxpci_l_power_led(acx_device_t *adev, int enable); +int acxpci_read_eeprom_byte(acx_device_t *adev, u32 addr, u8 *charbuf); +unsigned int acxpci_l_clean_txdesc(acx_device_t *adev); +void acxpci_l_clean_txdesc_emergency(acx_device_t *adev); +int acxpci_s_create_hostdesc_queues(acx_device_t *adev); +void acxpci_create_desc_queues(acx_device_t *adev, u32 tx_queue_start, u32 rx_queue_start); +void acxpci_free_desc_queues(acx_device_t *adev); +char* acxpci_s_proc_diag_output(char *p, acx_device_t *adev); +int acxpci_proc_eeprom_output(char *p, acx_device_t *adev); +void acxpci_set_interrupt_mask(acx_device_t *adev); +int acx100pci_s_set_tx_level(acx_device_t *adev, u8 level_dbm); + +void acx_s_msleep(int ms); +int acx_s_init_mac(acx_device_t *adev); +void acx_set_reg_domain(acx_device_t *adev, unsigned char reg_dom_id); +void acx_set_timer(acx_device_t *adev, int timeout_us); +void acx_update_capabilities(acx_device_t *adev); +void acx_s_start(acx_device_t *adev); + +void acx_s_update_card_settings(acx_device_t *adev); +void acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg); +void acx_l_update_ratevector(acx_device_t *adev); + +void acx_init_task_scheduler(acx_device_t *adev); +void acx_schedule_task(acx_device_t *adev, unsigned int set_flag); + +int acx_e_ioctl_old(struct net_device *ndev, struct ifreq *ifr, int cmd); + +client_t *acx_l_sta_list_get(acx_device_t *adev, const u8 *address); +void acx_l_sta_list_del(acx_device_t *adev, client_t *clt); + +int acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt); +void acx_i_timer(unsigned long a); +int acx_s_complete_scan(acx_device_t *adev); + +struct sk_buff *acx_rxbuf_to_ether(acx_device_t *adev, rxbuffer_t *rxbuf); +int acx_ether_to_txbuf(acx_device_t *adev, void *txbuf, const struct sk_buff *skb); + +u8 acx_signal_determine_quality(u8 signal, u8 noise); + +void acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf); +void acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc, + u16 intended_rate, u8 rate100, u16 rate111, u8 error, + int pkts_to_ignore); + +void acx_dump_bytes(const void *, int); +void acx_log_bad_eid(wlan_hdr_t* hdr, int len, wlan_ie_t* ie_ptr); + +u8 acx_rate111to100(u16); + +void acx_s_set_defaults(acx_device_t *adev); + +#if !ACX_DEBUG +static inline const char* acx_get_packet_type_string(u16 fc) { return ""; } +#else +const char* acx_get_packet_type_string(u16 fc); +#endif +const char* acx_cmd_status_str(unsigned int state); + +int acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev); + +void great_inquisitor(acx_device_t *adev); + +void acx_s_get_firmware_version(acx_device_t *adev); +void acx_display_hardware_details(acx_device_t *adev); + +int acx_e_change_mtu(struct net_device *ndev, int mtu); +struct net_device_stats* acx_e_get_stats(struct net_device *ndev); +struct iw_statistics* acx_e_get_wireless_stats(struct net_device *ndev); + +int __init acxpci_e_init_module(void); +int __init acxusb_e_init_module(void); +void __exit acxpci_e_cleanup_module(void); +void __exit acxusb_e_cleanup_module(void); --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan_mgmt.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan_mgmt.h @@ -0,0 +1,582 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +/*********************************************************************** +** Constants +*/ + +/*-- Information Element IDs --------------------*/ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_FH_PARMS 2 +#define WLAN_EID_DS_PARMS 3 +#define WLAN_EID_CF_PARMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARMS 6 +#define WLAN_EID_COUNTRY 7 /* 802.11d */ +#define WLAN_EID_FH_HOP_PARMS 8 /* 802.11d */ +#define WLAN_EID_FH_TABLE 9 /* 802.11d */ +#define WLAN_EID_REQUEST 10 /* 802.11d */ +/*-- values 11-15 reserved --*/ +#define WLAN_EID_CHALLENGE 16 +/*-- values 17-31 reserved for challenge text extension --*/ +#define WLAN_EID_PWR_CONSTRAINT 32 /* 11h PowerConstraint */ +#define WLAN_EID_ERP_INFO 42 /* was seen from WRT54GS with OpenWrt */ +#define WLAN_EID_NONERP 47 /* was seen from WRT54GS with OpenWrt */ +#define WLAN_EID_RSN 48 +#define WLAN_EID_EXT_RATES 50 +#define WLAN_EID_UNKNOWN128 128 +#define WLAN_EID_UNKNOWN133 133 +#define WLAN_EID_GENERIC 221 /* was seen from WRT54GS with OpenWrt */ +#define WLAN_EID_UNKNOWN223 223 + +#if 0 +#define WLAN_EID_PWR_CAP 33 /* 11h PowerCapability */ +#define WLAN_EID_TPC_REQUEST 34 /* 11h TPC Request */ +#define WLAN_EID_TPC_REPORT 35 /* 11h TPC Report */ +#define WLAN_EID_SUPP_CHANNELS 36 /* 11h Supported Channels */ +#define WLAN_EID_CHANNEL_SWITCH 37 /* 11h ChannelSwitch */ +#define WLAN_EID_MEASURE_REQUEST 38 /* 11h MeasurementRequest */ +#define WLAN_EID_MEASURE_REPORT 39 /* 11h MeasurementReport */ +#define WLAN_EID_QUIET_ID 40 /* 11h Quiet */ +#define WLAN_EID_IBSS_DFS_ID 41 /* 11h IBSS_DFS */ +#endif + +/*-- Reason Codes -------------------------------*/ +#define WLAN_MGMT_REASON_RSVD 0 +#define WLAN_MGMT_REASON_UNSPEC 1 +#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2 +#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3 +#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4 +#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6 +#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7 +#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8 +#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9 + +/*-- Status Codes -------------------------------*/ +#define WLAN_MGMT_STATUS_SUCCESS 0 +#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1 +#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13 +#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14 +#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15 +#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18 +/* p80211b additions */ +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20 +#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21 + +/*-- Auth Algorithm Field ---------------------------*/ +#define WLAN_AUTH_ALG_OPENSYSTEM 0 +#define WLAN_AUTH_ALG_SHAREDKEY 1 + +/*-- Management Frame Field Offsets -------------*/ +/* Note: Not all fields are listed because of variable lengths */ +/* Note: These offsets are from the start of the frame data */ + +#define WLAN_BEACON_OFF_TS 0 +#define WLAN_BEACON_OFF_BCN_INT 8 +#define WLAN_BEACON_OFF_CAPINFO 10 +#define WLAN_BEACON_OFF_SSID 12 + +#define WLAN_DISASSOC_OFF_REASON 0 + +#define WLAN_ASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_ASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_ASSOCREQ_OFF_SSID 4 + +#define WLAN_ASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_ASSOCRESP_OFF_STATUS 2 +#define WLAN_ASSOCRESP_OFF_AID 4 +#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_REASSOCREQ_OFF_CAP_INFO 0 +#define WLAN_REASSOCREQ_OFF_LISTEN_INT 2 +#define WLAN_REASSOCREQ_OFF_CURR_AP 4 +#define WLAN_REASSOCREQ_OFF_SSID 10 + +#define WLAN_REASSOCRESP_OFF_CAP_INFO 0 +#define WLAN_REASSOCRESP_OFF_STATUS 2 +#define WLAN_REASSOCRESP_OFF_AID 4 +#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6 + +#define WLAN_PROBEREQ_OFF_SSID 0 + +#define WLAN_PROBERESP_OFF_TS 0 +#define WLAN_PROBERESP_OFF_BCN_INT 8 +#define WLAN_PROBERESP_OFF_CAP_INFO 10 +#define WLAN_PROBERESP_OFF_SSID 12 + +#define WLAN_AUTHEN_OFF_AUTH_ALG 0 +#define WLAN_AUTHEN_OFF_AUTH_SEQ 2 +#define WLAN_AUTHEN_OFF_STATUS 4 +#define WLAN_AUTHEN_OFF_CHALLENGE 6 + +#define WLAN_DEAUTHEN_OFF_REASON 0 + +enum { +IEEE16(WF_MGMT_CAP_ESS, 0x0001) +IEEE16(WF_MGMT_CAP_IBSS, 0x0002) +/* In (re)assoc request frames by STA: +** Pollable=0, PollReq=0: STA is not CF-Pollable +** 0 1: STA is CF-Pollable, not requesting to be placed on the CF-Polling list +** 1 0: STA is CF-Pollable, requesting to be placed on the CF-Polling list +** 1 1: STA is CF-Pollable, requesting never to be polled +** In beacon, proberesp, (re)assoc resp frames by AP: +** 0 0: No point coordinator at AP +** 0 1: Point coordinator at AP for delivery only (no polling) +** 1 0: Point coordinator at AP for delivery and polling +** 1 1: Reserved */ +IEEE16(WF_MGMT_CAP_CFPOLLABLE, 0x0004) +IEEE16(WF_MGMT_CAP_CFPOLLREQ, 0x0008) +/* 1=non-WEP data frames are disallowed */ +IEEE16(WF_MGMT_CAP_PRIVACY, 0x0010) +/* In beacon, proberesp, (re)assocresp by AP/AdHoc: +** 1=use of shortpre is allowed ("I can receive shortpre") */ +IEEE16(WF_MGMT_CAP_SHORT, 0x0020) +IEEE16(WF_MGMT_CAP_PBCC, 0x0040) +IEEE16(WF_MGMT_CAP_AGILITY, 0x0080) +/* In (re)assoc request frames by STA: +** 1=short slot time implemented and enabled +** NB: AP shall use long slot time beginning at the next Beacon after assoc +** of STA with this bit set to 0 +** In beacon, proberesp, (re)assoc resp frames by AP: +** currently used slot time value: 0/1 - long/short */ +IEEE16(WF_MGMT_CAP_SHORTSLOT, 0x0400) +/* In (re)assoc request frames by STA: 1=CCK-OFDM is implemented and enabled +** In beacon, proberesp, (re)assoc resp frames by AP/AdHoc: +** 1=CCK-OFDM is allowed */ +IEEE16(WF_MGMT_CAP_CCKOFDM, 0x2000) +}; + + +/*********************************************************************** +** Types +*/ + +/* Information Element types */ + +/* prototype structure, all IEs start with these members */ +typedef struct wlan_ie { + u8 eid; + u8 len; +} WLAN_PACKED wlan_ie_t; + +/*-- Service Set Identity (SSID) -----------------*/ +typedef struct wlan_ie_ssid { + u8 eid; + u8 len; + u8 ssid[1]; /* may be zero */ +} WLAN_PACKED wlan_ie_ssid_t; + +/*-- Supported Rates -----------------------------*/ +typedef struct wlan_ie_supp_rates { + u8 eid; + u8 len; + u8 rates[1]; /* had better be at LEAST one! */ +} WLAN_PACKED wlan_ie_supp_rates_t; + +/*-- FH Parameter Set ----------------------------*/ +typedef struct wlan_ie_fh_parms { + u8 eid; + u8 len; + u16 dwell; + u8 hopset; + u8 hoppattern; + u8 hopindex; +} WLAN_PACKED wlan_ie_fh_parms_t; + +/*-- DS Parameter Set ----------------------------*/ +typedef struct wlan_ie_ds_parms { + u8 eid; + u8 len; + u8 curr_ch; +} WLAN_PACKED wlan_ie_ds_parms_t; + +/*-- CF Parameter Set ----------------------------*/ +typedef struct wlan_ie_cf_parms { + u8 eid; + u8 len; + u8 cfp_cnt; + u8 cfp_period; + u16 cfp_maxdur; + u16 cfp_durremaining; +} WLAN_PACKED wlan_ie_cf_parms_t; + +/*-- TIM ------------------------------------------*/ +typedef struct wlan_ie_tim { + u8 eid; + u8 len; + u8 dtim_cnt; + u8 dtim_period; + u8 bitmap_ctl; + u8 virt_bm[1]; +} WLAN_PACKED wlan_ie_tim_t; + +/*-- IBSS Parameter Set ---------------------------*/ +typedef struct wlan_ie_ibss_parms { + u8 eid; + u8 len; + u16 atim_win; +} WLAN_PACKED wlan_ie_ibss_parms_t; + +/*-- Challenge Text ------------------------------*/ +typedef struct wlan_ie_challenge { + u8 eid; + u8 len; + u8 challenge[1]; +} WLAN_PACKED wlan_ie_challenge_t; + +/*-- ERP (42) -------------------------------------*/ +typedef struct wlan_ie_erp { + u8 eid; + u8 len; + /* bit 0:Non ERP present + ** 1:Use Protection + ** 2:Barker Preamble mode + ** 3-7:reserved */ + u8 erp; +} WLAN_PACKED wlan_ie_erp_t; + +/* Types for parsing mgmt frames */ + +/* prototype structure, all mgmt frame types will start with these members */ +typedef struct wlan_fr_mgmt { + u16 type; + u16 len; /* DOES NOT include FCS */ + wlan_hdr_t *hdr; + /* used for target specific data, skb in Linux */ + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ +} WLAN_PACKED wlan_fr_mgmt_t; + +/*-- Beacon ---------------------------------------*/ +typedef struct wlan_fr_beacon { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u64 *ts; + u16 *bcn_int; + u16 *cap_info; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; + wlan_ie_fh_parms_t *fh_parms; + wlan_ie_ds_parms_t *ds_parms; + wlan_ie_cf_parms_t *cf_parms; + wlan_ie_ibss_parms_t *ibss_parms; + wlan_ie_tim_t *tim; /* in beacon only, not proberesp */ + wlan_ie_erp_t *erp; /* in beacon only, not proberesp */ +} wlan_fr_beacon_t; +#define wlan_fr_proberesp wlan_fr_beacon +#define wlan_fr_proberesp_t wlan_fr_beacon_t + +/*-- IBSS ATIM ------------------------------------*/ +typedef struct wlan_fr_ibssatim { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + /* this frame type has a null body */ +} wlan_fr_ibssatim_t; + +/*-- Disassociation -------------------------------*/ +typedef struct wlan_fr_disassoc { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *reason; + /*-- info elements ----------*/ +} wlan_fr_disassoc_t; + +/*-- Association Request --------------------------*/ +typedef struct wlan_fr_assocreq { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *listen_int; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_assocreq_t; + +/*-- Association Response -------------------------*/ +typedef struct wlan_fr_assocresp { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *status; + u16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_assocresp_t; + +/*-- Reassociation Request ------------------------*/ +typedef struct wlan_fr_reassocreq { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *listen_int; + u8 *curr_ap; + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_reassocreq_t; + +/*-- Reassociation Response -----------------------*/ +typedef struct wlan_fr_reassocresp { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *cap_info; + u16 *status; + u16 *aid; + /*-- info elements ----------*/ + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_reassocresp_t; + +/*-- Probe Request --------------------------------*/ +typedef struct wlan_fr_probereq { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + /*-- info elements ----------*/ + wlan_ie_ssid_t *ssid; + wlan_ie_supp_rates_t *supp_rates; + wlan_ie_supp_rates_t *ext_rates; +} wlan_fr_probereq_t; + +/*-- Authentication -------------------------------*/ +typedef struct wlan_fr_authen { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *auth_alg; + u16 *auth_seq; + u16 *status; + /*-- info elements ----------*/ + wlan_ie_challenge_t *challenge; +} wlan_fr_authen_t; + +/*-- Deauthenication -----------------------------*/ +typedef struct wlan_fr_deauthen { + u16 type; + u16 len; + wlan_hdr_t *hdr; + /*-- fixed fields -----------*/ + u16 *reason; + /*-- info elements ----------*/ +} wlan_fr_deauthen_t; + +/* Types for building mgmt frames */ + +/* Warning. Several types used in below structs are +** in fact variable length. Use structs with such fields with caution */ +typedef struct auth_frame_body { + u16 auth_alg; + u16 auth_seq; + u16 status; + wlan_ie_challenge_t challenge; +} WLAN_PACKED auth_frame_body_t; + +typedef struct assocresp_frame_body { + u16 cap_info; + u16 status; + u16 aid; + wlan_ie_supp_rates_t rates; +} WLAN_PACKED assocresp_frame_body_t; + +typedef struct reassocreq_frame_body { + u16 cap_info; + u16 listen_int; + u8 current_ap[ETH_ALEN]; + wlan_ie_ssid_t ssid; +/* access to this one is disabled since ssid_t is variable length: */ + /* wlan_ie_supp_rates_t rates; */ +} WLAN_PACKED reassocreq_frame_body_t; + +typedef struct reassocresp_frame_body { + u16 cap_info; + u16 status; + u16 aid; + wlan_ie_supp_rates_t rates; +} WLAN_PACKED reassocresp_frame_body_t; + +typedef struct deauthen_frame_body { + u16 reason; +} WLAN_PACKED deauthen_frame_body_t; + +typedef struct disassoc_frame_body { + u16 reason; +} WLAN_PACKED disassoc_frame_body_t; + +typedef struct probereq_frame_body { + wlan_ie_ssid_t ssid; + wlan_ie_supp_rates_t rates; +} WLAN_PACKED probereq_frame_body_t; + +typedef struct proberesp_frame_body { + u8 timestamp[8]; + u16 beacon_int; + u16 cap_info; + wlan_ie_ssid_t ssid; +/* access to these is disabled since ssid_t is variable length: */ + /* wlan_ie_supp_rates_t rates; */ + /* fhps_t fhps; */ + /* dsps_t dsps; */ + /* cfps_t cfps; */ +} WLAN_PACKED proberesp_frame_body_t; + + +/*********************************************************************** +** Functions +*/ + +/* Helpers for parsing mgmt frames */ +void wlan_mgmt_decode_ibssatim(wlan_fr_ibssatim_t *f); +void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f); +void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f); +void wlan_mgmt_decode_authen(wlan_fr_authen_t *f); +void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f); +void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f); +void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f); +void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f); +void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f); +void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f); +void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f); + +/* Helpers for building mgmt frames */ +static inline u8* +wlan_fill_ie_ssid(u8 *p, int len, const char *ssid) +{ + struct wlan_ie_ssid *ie = (void*)p; + ie->eid = WLAN_EID_SSID; + ie->len = len; + memcpy(ie->ssid, ssid, len); + return p + len + 2; +} +/* This controls whether we create 802.11g 'ext supported rates' IEs +** or just create overlong 'supported rates' IEs instead +** (non-11g compliant) */ +#define WE_OBEY_802_11G 1 +static inline u8* +wlan_fill_ie_rates(u8 *p, int len, const u8 *rates) +{ + struct wlan_ie_supp_rates *ie = (void*)p; +#if WE_OBEY_802_11G + if (len > 8 ) len = 8; +#endif + /* supported rates (1 to 8 octets) */ + ie->eid = WLAN_EID_SUPP_RATES; + ie->len = len; + memcpy(ie->rates, rates, len); + return p + len + 2; +} +/* This one wouldn't create an IE at all if not needed */ +static inline u8* +wlan_fill_ie_rates_ext(u8 *p, int len, const u8 *rates) +{ + struct wlan_ie_supp_rates *ie = (void*)p; +#if !WE_OBEY_802_11G + return p; +#endif + len -= 8; + if (len <= 0) return p; + /* ext supported rates */ + ie->eid = WLAN_EID_EXT_RATES; + ie->len = len; + memcpy(ie->rates, rates+8, len); + return p + len + 2; +} +static inline u8* +wlan_fill_ie_ds_parms(u8 *p, int channel) +{ + struct wlan_ie_ds_parms *ie = (void*)p; + ie->eid = WLAN_EID_DS_PARMS; + ie->len = 1; + ie->curr_ch = channel; + return p + sizeof(*ie); +} +static inline u8* +wlan_fill_ie_ibss_parms(u8 *p, int atim_win) +{ + struct wlan_ie_ibss_parms *ie = (void*)p; + ie->eid = WLAN_EID_IBSS_PARMS; + ie->len = 2; + ie->atim_win = atim_win; + return p + sizeof(*ie); +} +static inline u8* +wlan_fill_ie_tim(u8 *p, int rem, int period, int bcast, + int ofs, int len, const u8 *vbm) +{ + struct wlan_ie_tim *ie = (void*)p; + ie->eid = WLAN_EID_TIM; + ie->len = len + 3; + ie->dtim_cnt = rem; + ie->dtim_period = period; + ie->bitmap_ctl = ofs | (bcast!=0); + if (vbm) + memcpy(ie->virt_bm, vbm, len); /* min 1 byte */ + else + ie->virt_bm[0] = 0; + return p + len + 3 + 2; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/common.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/common.c @@ -0,0 +1,7220 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ +static client_t *acx_l_sta_list_alloc(acx_device_t *adev); +static client_t *acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address); + +static int acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf); +static int acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf); +/* static int acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala); */ +static int acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf); +static void acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req); +static void acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req); +static void acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req); +static void acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req); +static int acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req, const rxbuffer_t *rxbuf); +static int acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req); +static int acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req); +static int acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req); +static int acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req); +static int acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason); +static int acx_l_transmit_authen1(acx_device_t *adev); +static int acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req, client_t *clt); +static int acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req); +static int acx_l_transmit_assoc_req(acx_device_t *adev); + + +/*********************************************************************** +*/ +#if ACX_DEBUG +unsigned int acx_debug = ACX_DEFAULT_MSG; +#endif + +char firmware_ver[33] = "default"; +module_param_string(firmware_ver, firmware_ver, sizeof(firmware_ver), 0444); +MODULE_PARM_DESC(firmware_ver, "Alternate firmware version."); + +#if ACX_DEBUG +module_param_named(debug, acx_debug, uint, 0); +#endif + +#if ACX_DEBUG +MODULE_PARM_DESC(debug, "Debug level mask (see L_xxx constants)"); +#endif + +#ifdef MODULE_LICENSE +MODULE_LICENSE("Dual MPL/GPL"); +#endif +/* USB had this: MODULE_AUTHOR("Martin Wawro "); */ +MODULE_AUTHOR("ACX100 Open Source Driver development team"); +MODULE_DESCRIPTION("Driver for TI ACX1xx based wireless cards (CardBus/PCI/USB)"); + + +/*********************************************************************** +*/ +/* Probably a number of acx's intermediate buffers for USB transfers, +** not to be confused with number of descriptors in tx/rx rings +** (which are not directly accessible to host in USB devices) */ +#define USB_RX_CNT 10 +#define USB_TX_CNT 10 + + +/*********************************************************************** +*/ + +/* minutes to wait until next radio recalibration: */ +#define RECALIB_PAUSE 5 + +/* Please keep acx_reg_domain_ids_len in sync... */ +const u8 acx_reg_domain_ids[acx_reg_domain_ids_len] = + { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40, 0x41, 0x51 }; +static const u16 reg_domain_channel_masks[acx_reg_domain_ids_len] = + { 0x07ff, 0x07ff, 0x1fff, 0x0600, 0x1e00, 0x2000, 0x3fff, 0x01fc }; +const char * const +acx_reg_domain_strings[] = { + /* 0 */ " 1-11 FCC (USA)", + /* 1 */ " 1-11 DOC/IC (Canada)", +/* BTW: WLAN use in ETSI is regulated by ETSI standard EN 300 328-2 V1.1.2 */ + /* 2 */ " 1-13 ETSI (Europe)", + /* 3 */ "10-11 Spain", + /* 4 */ "10-13 France", + /* 5 */ " 14 MKK (Japan)", + /* 6 */ " 1-14 MKK1", + /* 7 */ " 3-9 Israel (not all firmware versions)", + NULL /* needs to remain as last entry */ +}; + + + +/*********************************************************************** +** Debugging support +*/ +#ifdef PARANOID_LOCKING +static unsigned max_lock_time; +static unsigned max_sem_time; + +void +acx_lock_unhold() { max_lock_time = 0; } +void +acx_sem_unhold() { max_sem_time = 0; } + +static inline const char* +sanitize_str(const char *s) +{ + const char* t = strrchr(s, '/'); + if (t) return t + 1; + return s; +} + +void +acx_lock_debug(acx_device_t *adev, const char* where) +{ + unsigned int count = 100*1000*1000; + where = sanitize_str(where); + while (--count) { + if (!spin_is_locked(&adev->lock)) break; + cpu_relax(); + } + if (!count) { + printk(KERN_EMERG "LOCKUP: already taken at %s!\n", adev->last_lock); + BUG(); + } + adev->last_lock = where; + rdtscl(adev->lock_time); +} +void +acx_unlock_debug(acx_device_t *adev, const char* where) +{ +#ifdef SMP + if (!spin_is_locked(&adev->lock)) { + where = sanitize_str(where); + printk(KERN_EMERG "STRAY UNLOCK at %s!\n", where); + BUG(); + } +#endif + if (acx_debug & L_LOCK) { + unsigned long diff; + rdtscl(diff); + diff -= adev->lock_time; + if (diff > max_lock_time) { + where = sanitize_str(where); + printk("max lock hold time %ld CPU ticks from %s " + "to %s\n", diff, adev->last_lock, where); + max_lock_time = diff; + } + } +} +void +acx_down_debug(acx_device_t *adev, const char* where) +{ + int sem_count; + unsigned long timeout = jiffies + 5*HZ; + + where = sanitize_str(where); + + for (;;) { + sem_count = atomic_read(&adev->sem.count); + if (sem_count) break; + if (time_after(jiffies, timeout)) + break; + msleep(5); + } + if (!sem_count) { + printk(KERN_EMERG "D STATE at %s! last sem at %s\n", + where, adev->last_sem); + dump_stack(); + } + adev->last_sem = where; + adev->sem_time = jiffies; + down(&adev->sem); + if (acx_debug & L_LOCK) { + printk("%s: sem_down %d -> %d\n", + where, sem_count, atomic_read(&adev->sem.count)); + } +} +void +acx_up_debug(acx_device_t *adev, const char* where) +{ + int sem_count = atomic_read(&adev->sem.count); + if (sem_count) { + where = sanitize_str(where); + printk(KERN_EMERG "STRAY UP at %s! sem.count=%d\n", where, sem_count); + dump_stack(); + } + if (acx_debug & L_LOCK) { + unsigned long diff = jiffies - adev->sem_time; + if (diff > max_sem_time) { + where = sanitize_str(where); + printk("max sem hold time %ld jiffies from %s " + "to %s\n", diff, adev->last_sem, where); + max_sem_time = diff; + } + } + up(&adev->sem); + if (acx_debug & L_LOCK) { + where = sanitize_str(where); + printk("%s: sem_up %d -> %d\n", + where, sem_count, atomic_read(&adev->sem.count)); + } +} +#endif /* PARANOID_LOCKING */ + + +/*********************************************************************** +*/ +#if ACX_DEBUG > 1 + +static int acx_debug_func_indent; +#define DEBUG_TSC 0 +#define FUNC_INDENT_INCREMENT 2 + +#if DEBUG_TSC +#define TIMESTAMP(d) unsigned long d; rdtscl(d) +#else +#define TIMESTAMP(d) unsigned long d = jiffies +#endif + +static const char +spaces[] = " " " "; /* Nx10 spaces */ + +void +log_fn_enter(const char *funcname) +{ + int indent; + TIMESTAMP(d); + + indent = acx_debug_func_indent; + if (indent >= sizeof(spaces)) + indent = sizeof(spaces)-1; + + printk("%08ld %s==> %s\n", + d % 100000000, + spaces + (sizeof(spaces)-1) - indent, + funcname + ); + + acx_debug_func_indent += FUNC_INDENT_INCREMENT; +} +void +log_fn_exit(const char *funcname) +{ + int indent; + TIMESTAMP(d); + + acx_debug_func_indent -= FUNC_INDENT_INCREMENT; + + indent = acx_debug_func_indent; + if (indent >= sizeof(spaces)) + indent = sizeof(spaces)-1; + + printk("%08ld %s<== %s\n", + d % 100000000, + spaces + (sizeof(spaces)-1) - indent, + funcname + ); +} +void +log_fn_exit_v(const char *funcname, int v) +{ + int indent; + TIMESTAMP(d); + + acx_debug_func_indent -= FUNC_INDENT_INCREMENT; + + indent = acx_debug_func_indent; + if (indent >= sizeof(spaces)) + indent = sizeof(spaces)-1; + + printk("%08ld %s<== %s: %08X\n", + d % 100000000, + spaces + (sizeof(spaces)-1) - indent, + funcname, + v + ); +} +#endif /* ACX_DEBUG > 1 */ + + +/*********************************************************************** +** Basically a msleep with logging +*/ +void +acx_s_msleep(int ms) +{ + FN_ENTER; + msleep(ms); + FN_EXIT0; +} + + +/*********************************************************************** +** Not inlined: it's larger than it seems +*/ +void +acx_print_mac(const char *head, const u8 *mac, const char *tail) +{ + printk("%s"MACSTR"%s", head, MAC(mac), tail); +} + + +/*********************************************************************** +** acx_get_status_name +*/ +static const char* +acx_get_status_name(u16 status) +{ + static const char * const str[] = { + "STOPPED", "SCANNING", "WAIT_AUTH", + "AUTHENTICATED", "ASSOCIATED", "INVALID??" + }; + if (status > VEC_SIZE(str)-1) + status = VEC_SIZE(str)-1; + + return str[status]; +} + + +/*********************************************************************** +** acx_get_packet_type_string +*/ +#if ACX_DEBUG +const char* +acx_get_packet_type_string(u16 fc) +{ + static const char * const mgmt_arr[] = { + "MGMT/AssocReq", "MGMT/AssocResp", "MGMT/ReassocReq", + "MGMT/ReassocResp", "MGMT/ProbeReq", "MGMT/ProbeResp", + "MGMT/UNKNOWN", "MGMT/UNKNOWN", "MGMT/Beacon", "MGMT/ATIM", + "MGMT/Disassoc", "MGMT/Authen", "MGMT/Deauthen" + }; + static const char * const ctl_arr[] = { + "CTL/PSPoll", "CTL/RTS", "CTL/CTS", "CTL/Ack", "CTL/CFEnd", + "CTL/CFEndCFAck" + }; + static const char * const data_arr[] = { + "DATA/DataOnly", "DATA/Data CFAck", "DATA/Data CFPoll", + "DATA/Data CFAck/CFPoll", "DATA/Null", "DATA/CFAck", + "DATA/CFPoll", "DATA/CFAck/CFPoll" + }; + const char *str; + u8 fstype = (WF_FC_FSTYPE & fc) >> 4; + u8 ctl; + + switch (WF_FC_FTYPE & fc) { + case WF_FTYPE_MGMT: + if (fstype < VEC_SIZE(mgmt_arr)) + str = mgmt_arr[fstype]; + else + str = "MGMT/UNKNOWN"; + break; + case WF_FTYPE_CTL: + ctl = fstype - 0x0a; + if (ctl < VEC_SIZE(ctl_arr)) + str = ctl_arr[ctl]; + else + str = "CTL/UNKNOWN"; + break; + case WF_FTYPE_DATA: + if (fstype < VEC_SIZE(data_arr)) + str = data_arr[fstype]; + else + str = "DATA/UNKNOWN"; + break; + default: + str = "UNKNOWN"; + break; + } + return str; +} +#endif + + +/*********************************************************************** +** acx_wlan_reason_str +*/ +static inline const char* +acx_wlan_reason_str(u16 reason) +{ + static const char* const reason_str[] = { + /* 0 */ "?", + /* 1 */ "unspecified", + /* 2 */ "prev auth is not valid", + /* 3 */ "leaving BBS", + /* 4 */ "due to inactivity", + /* 5 */ "AP is busy", + /* 6 */ "got class 2 frame from non-auth'ed STA", + /* 7 */ "got class 3 frame from non-assoc'ed STA", + /* 8 */ "STA has left BSS", + /* 9 */ "assoc without auth is not allowed", + /* 10 */ "bad power setting (802.11h)", + /* 11 */ "bad channel (802.11i)", + /* 12 */ "?", + /* 13 */ "invalid IE", + /* 14 */ "MIC failure", + /* 15 */ "four-way handshake timeout", + /* 16 */ "group key handshake timeout", + /* 17 */ "IE is different", + /* 18 */ "invalid group cipher", + /* 19 */ "invalid pairwise cipher", + /* 20 */ "invalid AKMP", + /* 21 */ "unsupported RSN version", + /* 22 */ "invalid RSN IE cap", + /* 23 */ "802.1x failed", + /* 24 */ "cipher suite rejected" + }; + return reason < VEC_SIZE(reason_str) ? reason_str[reason] : "?"; +} + + +/*********************************************************************** +** acx_cmd_status_str +*/ +const char* +acx_cmd_status_str(unsigned int state) +{ + static const char * const cmd_error_strings[] = { + "Idle", + "Success", + "Unknown Command", + "Invalid Information Element", + "Channel rejected", + "Channel invalid in current regulatory domain", + "MAC invalid", + "Command rejected (read-only information element)", + "Command rejected", + "Already asleep", + "TX in progress", + "Already awake", + "Write only", + "RX in progress", + "Invalid parameter", + "Scan in progress", + "Failed" + }; + return state < VEC_SIZE(cmd_error_strings) ? + cmd_error_strings[state] : "?"; +} + + +/*********************************************************************** +** get_status_string +*/ +static inline const char* +get_status_string(unsigned int status) +{ + /* A bit shortened, but hopefully still understandable */ + static const char * const status_str[] = { + /* 0 */ "Successful", + /* 1 */ "Unspecified failure", + /* 2 */ "reserved", + /* 3 */ "reserved", + /* 4 */ "reserved", + /* 5 */ "reserved", + /* 6 */ "reserved", + /* 7 */ "reserved", + /* 8 */ "reserved", + /* 9 */ "reserved", + /*10 */ "Cannot support all requested capabilities in Capability Information field", + /*11 */ "Reassoc denied (reason outside of 802.11b scope)", + /*12 */ "Assoc denied (reason outside of 802.11b scope) -- maybe MAC filtering by peer?", + /*13 */ "Responding station doesnt support specified auth algorithm -- maybe WEP auth Open vs. Restricted?", + /*14 */ "Auth rejected: wrong transaction sequence number", + /*15 */ "Auth rejected: challenge failure", + /*16 */ "Auth rejected: timeout for next frame in sequence", + /*17 */ "Assoc denied: too many STAs on this AP", + /*18 */ "Assoc denied: requesting STA doesnt support all data rates in basic set", + /*19 */ "Assoc denied: requesting STA doesnt support Short Preamble", + /*20 */ "Assoc denied: requesting STA doesnt support PBCC Modulation", + /*21 */ "Assoc denied: requesting STA doesnt support Channel Agility" + /*22 */ "reserved", + /*23 */ "reserved", + /*24 */ "reserved", + /*25 */ "Assoc denied: requesting STA doesnt support Short Slot Time", + /*26 */ "Assoc denied: requesting STA doesnt support DSSS-OFDM" + }; + + return status_str[status < VEC_SIZE(status_str) ? status : 2]; +} + + +/*********************************************************************** +*/ +void +acx_log_bad_eid(wlan_hdr_t* hdr, int len, wlan_ie_t* ie_ptr) +{ + if (acx_debug & L_ASSOC) { + int offset = (u8*)ie_ptr - (u8*)hdr; + printk("acx: unknown EID %d in mgmt frame at offset %d. IE: ", + ie_ptr->eid, offset); + /* IE len can be bogus, IE can extend past packet end. Oh well... */ + acx_dump_bytes(ie_ptr, ie_ptr->len + 2); + if (acx_debug & L_DATA) { + printk("frame (%s): ", + acx_get_packet_type_string(le16_to_cpu(hdr->fc))); + acx_dump_bytes(hdr, len); + } + } +} + + +/*********************************************************************** +*/ +#if ACX_DEBUG +void +acx_dump_bytes(const void *data, int num) +{ + const u8* ptr = (const u8*)data; + + if (num <= 0) { + printk("\n"); + return; + } + + while (num >= 16) { + printk( "%02X %02X %02X %02X %02X %02X %02X %02X " + "%02X %02X %02X %02X %02X %02X %02X %02X\n", + ptr[0], ptr[1], ptr[2], ptr[3], + ptr[4], ptr[5], ptr[6], ptr[7], + ptr[8], ptr[9], ptr[10], ptr[11], + ptr[12], ptr[13], ptr[14], ptr[15]); + num -= 16; + ptr += 16; + } + if (num > 0) { + while (--num > 0) + printk("%02X ", *ptr++); + printk("%02X\n", *ptr); + } +} +#endif + + +/*********************************************************************** +** acx_s_get_firmware_version +*/ +void +acx_s_get_firmware_version(acx_device_t *adev) +{ + fw_ver_t fw; + u8 hexarr[4] = { 0, 0, 0, 0 }; + int hexidx = 0, val = 0; + const char *num; + char c; + + FN_ENTER; + + memset(fw.fw_id, 'E', FW_ID_SIZE); + acx_s_interrogate(adev, &fw, ACX1xx_IE_FWREV); + memcpy(adev->firmware_version, fw.fw_id, FW_ID_SIZE); + adev->firmware_version[FW_ID_SIZE] = '\0'; + + log(L_DEBUG, "fw_ver: fw_id='%s' hw_id=%08X\n", + adev->firmware_version, fw.hw_id); + + if (strncmp(fw.fw_id, "Rev ", 4) != 0) { + printk("acx: strange firmware version string " + "'%s', please report\n", adev->firmware_version); + adev->firmware_numver = 0x01090407; /* assume 1.9.4.7 */ + } else { + num = &fw.fw_id[4]; + while (1) { + c = *num++; + if ((c == '.') || (c == '\0')) { + hexarr[hexidx++] = val; + if ((hexidx > 3) || (c == '\0')) /* end? */ + break; + val = 0; + continue; + } + if ((c >= '0') && (c <= '9')) + c -= '0'; + else + c = c - 'a' + (char)10; + val = val*16 + c; + } + + adev->firmware_numver = (u32)( + (hexarr[0] << 24) | (hexarr[1] << 16) + | (hexarr[2] << 8) | hexarr[3]); + log(L_DEBUG, "firmware_numver 0x%08X\n", adev->firmware_numver); + } + if (IS_ACX111(adev)) { + if (adev->firmware_numver == 0x00010011) { + /* This one does not survive floodpinging */ + printk("acx: firmware '%s' is known to be buggy, " + "please upgrade\n", adev->firmware_version); + } + } + + adev->firmware_id = le32_to_cpu(fw.hw_id); + + /* we're able to find out more detailed chip names now */ + switch (adev->firmware_id & 0xffff0000) { + case 0x01010000: + case 0x01020000: + adev->chip_name = "TNETW1100A"; + break; + case 0x01030000: + adev->chip_name = "TNETW1100B"; + break; + case 0x03000000: + case 0x03010000: + adev->chip_name = "TNETW1130"; + break; + case 0x04030000: /* 0x04030101 is TNETW1450 */ + adev->chip_name = "TNETW1450"; + break; + default: + printk("acx: unknown chip ID 0x%08X, " + "please report\n", adev->firmware_id); + break; + } + + FN_EXIT0; +} + + +/*********************************************************************** +** acx_display_hardware_details +** +** Displays hw/fw version, radio type etc... +*/ +void +acx_display_hardware_details(acx_device_t *adev) +{ + const char *radio_str, *form_str; + + FN_ENTER; + + switch (adev->radio_type) { + case RADIO_MAXIM_0D: + radio_str = "Maxim"; + break; + case RADIO_RFMD_11: + radio_str = "RFMD"; + break; + case RADIO_RALINK_15: + radio_str = "Ralink"; + break; + case RADIO_RADIA_16: + radio_str = "Radia"; + break; + case RADIO_UNKNOWN_17: + /* TI seems to have a radio which is + * additionally 802.11a capable, too */ + radio_str = "802.11a/b/g radio?! Please report"; + break; + case RADIO_UNKNOWN_19: + radio_str = "A radio used by Safecom cards?! Please report"; + break; + case RADIO_UNKNOWN_1B: + radio_str = "An unknown radio used by TNETW1450 USB adapters"; + break; + default: + radio_str = "UNKNOWN, please report radio type name!"; + break; + } + + switch (adev->form_factor) { + case 0x00: + form_str = "unspecified"; + break; + case 0x01: + form_str = "(mini-)PCI / CardBus"; + break; + case 0x02: + form_str = "USB"; + break; + case 0x03: + form_str = "Compact Flash"; + break; + default: + form_str = "UNKNOWN, please report"; + break; + } + + printk("acx: === chipset %s, radio type 0x%02X (%s), " + "form factor 0x%02X (%s), EEPROM version 0x%02X: " + "uploaded firmware '%s' ===\n", + adev->chip_name, adev->radio_type, radio_str, + adev->form_factor, form_str, adev->eeprom_version, + adev->firmware_version); + + FN_EXIT0; +} + + +/*********************************************************************** +*/ +int +acx_e_change_mtu(struct net_device *ndev, int mtu) +{ + enum { + MIN_MTU = 256, + MAX_MTU = WLAN_DATA_MAXLEN - (ETH_HLEN) + }; + + if (mtu < MIN_MTU || mtu > MAX_MTU) + return -EINVAL; + + ndev->mtu = mtu; + return 0; +} + + +/*********************************************************************** +** acx_e_get_stats, acx_e_get_wireless_stats +*/ +struct net_device_stats* +acx_e_get_stats(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + return &adev->stats; +} + +struct iw_statistics* +acx_e_get_wireless_stats(struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + return &adev->wstats; +} + + +/*********************************************************************** +** maps acx111 tx descr rate field to acx100 one +*/ +const u8 +acx_bitpos2rate100[] = { + RATE100_1 ,/* 0 */ + RATE100_2 ,/* 1 */ + RATE100_5 ,/* 2 */ + RATE100_2 ,/* 3, should not happen */ + RATE100_2 ,/* 4, should not happen */ + RATE100_11 ,/* 5 */ + RATE100_2 ,/* 6, should not happen */ + RATE100_2 ,/* 7, should not happen */ + RATE100_22 ,/* 8 */ + RATE100_2 ,/* 9, should not happen */ + RATE100_2 ,/* 10, should not happen */ + RATE100_2 ,/* 11, should not happen */ + RATE100_2 ,/* 12, should not happen */ + RATE100_2 ,/* 13, should not happen */ + RATE100_2 ,/* 14, should not happen */ + RATE100_2 ,/* 15, should not happen */ +}; + +u8 +acx_rate111to100(u16 r) { + return acx_bitpos2rate100[highest_bit(r)]; +} + + +/*********************************************************************** +** Calculate level like the feb 2003 windows driver seems to do +*/ +static u8 +acx_signal_to_winlevel(u8 rawlevel) +{ + /* u8 winlevel = (u8) (0.5 + 0.625 * rawlevel); */ + u8 winlevel = ((4 + (rawlevel * 5)) / 8); + + if (winlevel > 100) + winlevel = 100; + return winlevel; +} + +u8 +acx_signal_determine_quality(u8 signal, u8 noise) +{ + int qual; + + qual = (((signal - 30) * 100 / 70) + (100 - noise * 4)) / 2; + + if (qual > 100) + return 100; + if (qual < 0) + return 0; + return qual; +} + + +/*********************************************************************** +** Interrogate/configure commands +*/ + +/* FIXME: the lengths given here probably aren't always correct. + * They should be gradually replaced by proper "sizeof(acx1XX_ie_XXXX)-4", + * unless the firmware actually expects a different length than the struct length */ +static const u16 +acx100_ie_len[] = { + 0, + ACX100_IE_ACX_TIMER_LEN, + sizeof(acx100_ie_powersave_t)-4, /* is that 6 or 8??? */ + ACX1xx_IE_QUEUE_CONFIG_LEN, + ACX100_IE_BLOCK_SIZE_LEN, + ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN, + ACX1xx_IE_RATE_FALLBACK_LEN, + ACX100_IE_WEP_OPTIONS_LEN, + ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */ + 0, + ACX1xx_IE_ASSOC_ID_LEN, + 0, + ACX111_IE_CONFIG_OPTIONS_LEN, + ACX1xx_IE_FWREV_LEN, + ACX1xx_IE_FCS_ERROR_COUNT_LEN, + ACX1xx_IE_MEDIUM_USAGE_LEN, + ACX1xx_IE_RXCONFIG_LEN, + 0, + 0, + sizeof(fw_stats_t)-4, + 0, + ACX1xx_IE_FEATURE_CONFIG_LEN, + ACX111_IE_KEY_CHOOSE_LEN, + ACX1FF_IE_MISC_CONFIG_TABLE_LEN, + ACX1FF_IE_WONE_CONFIG_LEN, + 0, + ACX1FF_IE_TID_CONFIG_LEN, + 0, + 0, + 0, + ACX1FF_IE_CALIB_ASSESSMENT_LEN, + ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN, + ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN, + ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN, + 0, + ACX1FF_IE_PACKET_DETECT_THRESH_LEN, + ACX1FF_IE_TX_CONFIG_OPTIONS_LEN, + ACX1FF_IE_CCA_THRESHOLD_LEN, + ACX1FF_IE_EVENT_MASK_LEN, + ACX1FF_IE_DTIM_PERIOD_LEN, + 0, + ACX1FF_IE_ACI_CONFIG_SET_LEN, + 0, + 0, + 0, + 0, + 0, + 0, + ACX1FF_IE_EEPROM_VER_LEN, +}; + +static const u16 +acx100_ie_len_dot11[] = { + 0, + ACX1xx_IE_DOT11_STATION_ID_LEN, + 0, + ACX100_IE_DOT11_BEACON_PERIOD_LEN, + ACX1xx_IE_DOT11_DTIM_PERIOD_LEN, + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN, + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN, + ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN, + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN, + 0, + ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN, + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN, + 0, + ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN, + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN, + ACX100_IE_DOT11_ED_THRESHOLD_LEN, + ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN, + 0, + 0, + 0, +}; + +static const u16 +acx111_ie_len[] = { + 0, + ACX100_IE_ACX_TIMER_LEN, + sizeof(acx111_ie_powersave_t)-4, + ACX1xx_IE_QUEUE_CONFIG_LEN, + ACX100_IE_BLOCK_SIZE_LEN, + ACX1xx_IE_MEMORY_CONFIG_OPTIONS_LEN, + ACX1xx_IE_RATE_FALLBACK_LEN, + ACX100_IE_WEP_OPTIONS_LEN, + ACX1xx_IE_MEMORY_MAP_LEN, /* ACX1xx_IE_SSID_LEN, */ + 0, + ACX1xx_IE_ASSOC_ID_LEN, + 0, + ACX111_IE_CONFIG_OPTIONS_LEN, + ACX1xx_IE_FWREV_LEN, + ACX1xx_IE_FCS_ERROR_COUNT_LEN, + ACX1xx_IE_MEDIUM_USAGE_LEN, + ACX1xx_IE_RXCONFIG_LEN, + 0, + 0, + sizeof(fw_stats_t)-4, + 0, + ACX1xx_IE_FEATURE_CONFIG_LEN, + ACX111_IE_KEY_CHOOSE_LEN, + ACX1FF_IE_MISC_CONFIG_TABLE_LEN, + ACX1FF_IE_WONE_CONFIG_LEN, + 0, + ACX1FF_IE_TID_CONFIG_LEN, + 0, + 0, + 0, + ACX1FF_IE_CALIB_ASSESSMENT_LEN, + ACX1FF_IE_BEACON_FILTER_OPTIONS_LEN, + ACX1FF_IE_LOW_RSSI_THRESH_OPT_LEN, + ACX1FF_IE_NOISE_HISTOGRAM_RESULTS_LEN, + 0, + ACX1FF_IE_PACKET_DETECT_THRESH_LEN, + ACX1FF_IE_TX_CONFIG_OPTIONS_LEN, + ACX1FF_IE_CCA_THRESHOLD_LEN, + ACX1FF_IE_EVENT_MASK_LEN, + ACX1FF_IE_DTIM_PERIOD_LEN, + 0, + ACX1FF_IE_ACI_CONFIG_SET_LEN, + 0, + 0, + 0, + 0, + 0, + 0, + ACX1FF_IE_EEPROM_VER_LEN, +}; + +static const u16 +acx111_ie_len_dot11[] = { + 0, + ACX1xx_IE_DOT11_STATION_ID_LEN, + 0, + ACX100_IE_DOT11_BEACON_PERIOD_LEN, + ACX1xx_IE_DOT11_DTIM_PERIOD_LEN, + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN, + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN, + ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE_LEN, + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN, + 0, + ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN_LEN, + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN, + 0, + ACX1xx_IE_DOT11_TX_POWER_LEVEL_LEN, + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN, + ACX100_IE_DOT11_ED_THRESHOLD_LEN, + ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET_LEN, + 0, + 0, + 0, +}; + + +#undef FUNC +#define FUNC "configure" +#if !ACX_DEBUG +int +acx_s_configure(acx_device_t *adev, void *pdr, int type) +{ +#else +int +acx_s_configure_debug(acx_device_t *adev, void *pdr, int type, const char* typestr) +{ +#endif + u16 len; + int res; + + if (type < 0x1000) + len = adev->ie_len[type]; + else + len = adev->ie_len_dot11[type - 0x1000]; + + log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len); + if (unlikely(!len)) { + log(L_DEBUG, "zero-length type %s?!\n", typestr); + } + + ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type); + ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len); + res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIGURE, pdr, len + 4); + if (unlikely(OK != res)) { +#if ACX_DEBUG + printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr); +#else + printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type); +#endif + /* dump_stack() is already done in issue_cmd() */ + } + return res; +} + +#undef FUNC +#define FUNC "interrogate" +#if !ACX_DEBUG +int +acx_s_interrogate(acx_device_t *adev, void *pdr, int type) +{ +#else +int +acx_s_interrogate_debug(acx_device_t *adev, void *pdr, int type, + const char* typestr) +{ +#endif + u16 len; + int res; + + /* FIXME: no check whether this exceeds the array yet. + * We should probably remember the number of entries... */ + if (type < 0x1000) + len = adev->ie_len[type]; + else + len = adev->ie_len_dot11[type-0x1000]; + + log(L_CTL, FUNC"(type:%s,len:%u)\n", typestr, len); + + ((acx_ie_generic_t *)pdr)->type = cpu_to_le16(type); + ((acx_ie_generic_t *)pdr)->len = cpu_to_le16(len); + res = acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, pdr, len + 4); + if (unlikely(OK != res)) { +#if ACX_DEBUG + printk("%s: "FUNC"(type:%s) FAILED\n", adev->ndev->name, typestr); +#else + printk("%s: "FUNC"(type:0x%X) FAILED\n", adev->ndev->name, type); +#endif + /* dump_stack() is already done in issue_cmd() */ + } + return res; +} + +#if CMD_DISCOVERY +void +great_inquisitor(acx_device_t *adev) +{ + static struct { + u16 type; + u16 len; + /* 0x200 was too large here: */ + u8 data[0x100 - 4]; + } ACX_PACKED ie; + u16 type; + + FN_ENTER; + + /* 0..0x20, 0x1000..0x1020 */ + for (type = 0; type <= 0x1020; type++) { + if (type == 0x21) + type = 0x1000; + ie.type = cpu_to_le16(type); + ie.len = cpu_to_le16(sizeof(ie) - 4); + acx_s_issue_cmd(adev, ACX1xx_CMD_INTERROGATE, &ie, sizeof(ie)); + } + FN_EXIT0; +} +#endif + + +#ifdef CONFIG_PROC_FS +/*********************************************************************** +** /proc files +*/ +/*********************************************************************** +** acx_l_proc_output +** Generate content for our /proc entry +** +** Arguments: +** buf is a pointer to write output to +** adev is the usual pointer to our private struct acx_device +** Returns: +** number of bytes actually written to buf +** Side effects: +** none +*/ +static int +acx_l_proc_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + int i; + + FN_ENTER; + + p += sprintf(p, + "acx driver version:\t\t" ACX_RELEASE "\n" + "Wireless extension version:\t" STRING(WIRELESS_EXT) "\n" + "chip name:\t\t\t%s (0x%08X)\n" + "radio type:\t\t\t0x%02X\n" + "form factor:\t\t\t0x%02X\n" + "EEPROM version:\t\t\t0x%02X\n" + "firmware version:\t\t%s (0x%08X)\n", + adev->chip_name, adev->firmware_id, + adev->radio_type, + adev->form_factor, + adev->eeprom_version, + adev->firmware_version, adev->firmware_numver); + + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; + if (!bss->used) continue; + p += sprintf(p, "BSS %u BSSID "MACSTR" ESSID %s channel %u " + "Cap 0x%X SIR %u SNR %u\n", + i, MAC(bss->bssid), (char*)bss->essid, bss->channel, + bss->cap_info, bss->sir, bss->snr); + } + p += sprintf(p, "status:\t\t\t%u (%s)\n", + adev->status, acx_get_status_name(adev->status)); + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +*/ +static int +acx_s_proc_diag_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + unsigned long flags; + unsigned int len = 0, partlen; + u32 temp1, temp2; + u8 *st, *st_end; +#ifdef __BIG_ENDIAN + u8 *st2; +#endif + fw_stats_t *fw_stats; + char *part_str = NULL; + fw_stats_tx_t *tx = NULL; + fw_stats_rx_t *rx = NULL; + fw_stats_dma_t *dma = NULL; + fw_stats_irq_t *irq = NULL; + fw_stats_wep_t *wep = NULL; + fw_stats_pwr_t *pwr = NULL; + fw_stats_mic_t *mic = NULL; + fw_stats_aes_t *aes = NULL; + fw_stats_event_t *evt = NULL; + + FN_ENTER; + + acx_lock(adev, flags); + + if (IS_PCI(adev)) + p = acxpci_s_proc_diag_output(p, adev); + + p += sprintf(p, + "\n" + "** network status **\n" + "dev_state_mask 0x%04X\n" + "status %u (%s), " + "mode %u, channel %u, " + "reg_dom_id 0x%02X, reg_dom_chanmask 0x%04X, ", + adev->dev_state_mask, + adev->status, acx_get_status_name(adev->status), + adev->mode, adev->channel, + adev->reg_dom_id, adev->reg_dom_chanmask + ); + p += sprintf(p, + "ESSID \"%s\", essid_active %d, essid_len %d, " + "essid_for_assoc \"%s\", nick \"%s\"\n" + "WEP ena %d, restricted %d, idx %d\n", + adev->essid, adev->essid_active, (int)adev->essid_len, + adev->essid_for_assoc, adev->nick, + adev->wep_enabled, adev->wep_restricted, + adev->wep_current_index); + p += sprintf(p, "dev_addr "MACSTR"\n", MAC(adev->dev_addr)); + p += sprintf(p, "bssid "MACSTR"\n", MAC(adev->bssid)); + p += sprintf(p, "ap_filter "MACSTR"\n", MAC(adev->ap)); + + p += sprintf(p, + "\n" + "** PHY status **\n" + "tx_disabled %d, tx_level_dbm %d\n" /* "tx_level_val %d, tx_level_auto %d\n" */ + "sensitivity %d, antenna 0x%02X, ed_threshold %d, cca %d, preamble_mode %d\n" + "rate_basic 0x%04X, rate_oper 0x%04X\n" + "rts_threshold %d, frag_threshold %d, short_retry %d, long_retry %d\n" + "msdu_lifetime %d, listen_interval %d, beacon_interval %d\n", + adev->tx_disabled, adev->tx_level_dbm, /* adev->tx_level_val, adev->tx_level_auto, */ + adev->sensitivity, adev->antenna, adev->ed_threshold, adev->cca, adev->preamble_mode, + adev->rate_basic, adev->rate_oper, + adev->rts_threshold, adev->frag_threshold, adev->short_retry, adev->long_retry, + adev->msdu_lifetime, adev->listen_interval, adev->beacon_interval); + + acx_unlock(adev, flags); + + p += sprintf(p, + "\n" + "** Firmware **\n" + "NOTE: version dependent statistics layout, " + "please report if you suspect wrong parsing!\n" + "\n" + "version \"%s\"\n", adev->firmware_version); + + /* TODO: may replace kmalloc/memset with kzalloc once + * Linux 2.6.14 is widespread */ + fw_stats = kmalloc(sizeof(*fw_stats), GFP_KERNEL); + if (!fw_stats) { + FN_EXIT1(0); + return 0; + } + memset(fw_stats, 0, sizeof(*fw_stats)); + + st = (u8 *)fw_stats; + + part_str = "statistics query command"; + + if (OK != acx_s_interrogate(adev, st, ACX1xx_IE_FIRMWARE_STATISTICS)) + goto fw_stats_end; + + st += sizeof(u16); + len = *(u16 *)st; + + if (len > sizeof(*fw_stats)) { + p += sprintf(p, + "firmware version with bigger fw_stats struct detected\n" + "(%u vs. %zu), please report\n", len, sizeof(fw_stats_t)); + if (len > sizeof(*fw_stats)) { + p += sprintf(p, "struct size exceeded allocation!\n"); + len = sizeof(*fw_stats); + } + } + st += sizeof(u16); + st_end = st - 2*sizeof(u16) + len; + +#ifdef __BIG_ENDIAN + /* let's make one bold assumption here: + * (hopefully!) *all* statistics fields are u32 only, + * thus if we need to make endianness corrections + * we can simply do them in one go, in advance */ + st2 = (u8 *)fw_stats; + for (temp1 = 0; temp1 < len; temp1 += 4, st2 += 4) + *(u32 *)st2 = le32_to_cpu(*(u32 *)st2); +#endif + + part_str = "Rx/Tx"; + + /* directly at end of a struct part? --> no error! */ + if (st == st_end) + goto fw_stats_end; + + tx = (fw_stats_tx_t *)st; + st += sizeof(fw_stats_tx_t); + rx = (fw_stats_rx_t *)st; + st += sizeof(fw_stats_rx_t); + partlen = sizeof(fw_stats_tx_t) + sizeof(fw_stats_rx_t); + + if (IS_ACX100(adev)) { + /* at least ACX100 PCI F/W 1.9.8.b + * and ACX100 USB F/W 1.0.7-USB + * don't have those two fields... */ + st -= 2*sizeof(u32); + + /* our parsing doesn't quite match this firmware yet, + * log failure */ + if (st > st_end) + goto fw_stats_fail; + temp1 = temp2 = 999999999; + } else { + if (st > st_end) + goto fw_stats_fail; + temp1 = rx->rx_aci_events; + temp2 = rx->rx_aci_resets; + } + + p += sprintf(p, + "%s:\n" + " tx_desc_overfl %u\n" + " rx_OutOfMem %u, rx_hdr_overfl %u, rx_hw_stuck %u\n" + " rx_dropped_frame %u, rx_frame_ptr_err %u, rx_xfr_hint_trig %u\n" + " rx_aci_events %u, rx_aci_resets %u\n", + part_str, + tx->tx_desc_of, + rx->rx_oom, + rx->rx_hdr_of, + rx->rx_hw_stuck, + rx->rx_dropped_frame, + rx->rx_frame_ptr_err, + rx->rx_xfr_hint_trig, + temp1, + temp2); + + part_str = "DMA"; + + if (st == st_end) + goto fw_stats_end; + + dma = (fw_stats_dma_t *)st; + partlen = sizeof(fw_stats_dma_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " rx_dma_req %u, rx_dma_err %u, tx_dma_req %u, tx_dma_err %u\n", + part_str, + dma->rx_dma_req, + dma->rx_dma_err, + dma->tx_dma_req, + dma->tx_dma_err); + + part_str = "IRQ"; + + if (st == st_end) + goto fw_stats_end; + + irq = (fw_stats_irq_t *)st; + partlen = sizeof(fw_stats_irq_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " cmd_cplt %u, fiq %u\n" + " rx_hdrs %u, rx_cmplt %u, rx_mem_overfl %u, rx_rdys %u\n" + " irqs %u, tx_procs %u, decrypt_done %u\n" + " dma_0_done %u, dma_1_done %u, tx_exch_complet %u\n" + " commands %u, rx_procs %u, hw_pm_mode_changes %u\n" + " host_acks %u, pci_pm %u, acm_wakeups %u\n", + part_str, + irq->cmd_cplt, + irq->fiq, + irq->rx_hdrs, + irq->rx_cmplt, + irq->rx_mem_of, + irq->rx_rdys, + irq->irqs, + irq->tx_procs, + irq->decrypt_done, + irq->dma_0_done, + irq->dma_1_done, + irq->tx_exch_complet, + irq->commands, + irq->rx_procs, + irq->hw_pm_mode_changes, + irq->host_acks, + irq->pci_pm, + irq->acm_wakeups); + + part_str = "WEP"; + + if (st == st_end) + goto fw_stats_end; + + wep = (fw_stats_wep_t *)st; + partlen = sizeof(fw_stats_wep_t); + st += partlen; + + if ( + (IS_PCI(adev) && IS_ACX100(adev)) + || (IS_USB(adev) && IS_ACX100(adev)) + ) { + /* at least ACX100 PCI F/W 1.9.8.b + * and ACX100 USB F/W 1.0.7-USB + * don't have those two fields... */ + st -= 2*sizeof(u32); + if (st > st_end) + goto fw_stats_fail; + temp1 = temp2 = 999999999; + } else { + if (st > st_end) + goto fw_stats_fail; + temp1 = wep->wep_pkt_decrypt; + temp2 = wep->wep_decrypt_irqs; + } + + p += sprintf(p, + "%s:\n" + " wep_key_count %u, wep_default_key_count %u, dot11_def_key_mib %u\n" + " wep_key_not_found %u, wep_decrypt_fail %u\n" + " wep_pkt_decrypt %u, wep_decrypt_irqs %u\n", + part_str, + wep->wep_key_count, + wep->wep_default_key_count, + wep->dot11_def_key_mib, + wep->wep_key_not_found, + wep->wep_decrypt_fail, + temp1, + temp2); + + part_str = "power"; + + if (st == st_end) + goto fw_stats_end; + + pwr = (fw_stats_pwr_t *)st; + partlen = sizeof(fw_stats_pwr_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " tx_start_ctr %u, no_ps_tx_too_short %u\n" + " rx_start_ctr %u, no_ps_rx_too_short %u\n" + " lppd_started %u\n" + " no_lppd_too_noisy %u, no_lppd_too_short %u, no_lppd_matching_frame %u\n", + part_str, + pwr->tx_start_ctr, + pwr->no_ps_tx_too_short, + pwr->rx_start_ctr, + pwr->no_ps_rx_too_short, + pwr->lppd_started, + pwr->no_lppd_too_noisy, + pwr->no_lppd_too_short, + pwr->no_lppd_matching_frame); + + part_str = "MIC"; + + if (st == st_end) + goto fw_stats_end; + + mic = (fw_stats_mic_t *)st; + partlen = sizeof(fw_stats_mic_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " mic_rx_pkts %u, mic_calc_fail %u\n", + part_str, + mic->mic_rx_pkts, + mic->mic_calc_fail); + + part_str = "AES"; + + if (st == st_end) + goto fw_stats_end; + + aes = (fw_stats_aes_t *)st; + partlen = sizeof(fw_stats_aes_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " aes_enc_fail %u, aes_dec_fail %u\n" + " aes_enc_pkts %u, aes_dec_pkts %u\n" + " aes_enc_irq %u, aes_dec_irq %u\n", + part_str, + aes->aes_enc_fail, + aes->aes_dec_fail, + aes->aes_enc_pkts, + aes->aes_dec_pkts, + aes->aes_enc_irq, + aes->aes_dec_irq); + + part_str = "event"; + + if (st == st_end) + goto fw_stats_end; + + evt = (fw_stats_event_t *)st; + partlen = sizeof(fw_stats_event_t); + st += partlen; + + if (st > st_end) + goto fw_stats_fail; + + p += sprintf(p, + "%s:\n" + " heartbeat %u, calibration %u\n" + " rx_mismatch %u, rx_mem_empty %u, rx_pool %u\n" + " oom_late %u\n" + " phy_tx_err %u, tx_stuck %u\n", + part_str, + evt->heartbeat, + evt->calibration, + evt->rx_mismatch, + evt->rx_mem_empty, + evt->rx_pool, + evt->oom_late, + evt->phy_tx_err, + evt->tx_stuck); + + if (st < st_end) + goto fw_stats_bigger; + + goto fw_stats_end; + +fw_stats_fail: + st -= partlen; + p += sprintf(p, + "failed at %s part (size %u), offset %lu (struct size %u), " + "please report\n", part_str, partlen, + (unsigned long)st - (unsigned long)fw_stats, len); + +fw_stats_bigger: + for (; st < st_end; st += 4) + p += sprintf(p, + "UNKN%3lu: %u\n", (unsigned long)st - (unsigned long)fw_stats, *(u32 *)st); + +fw_stats_end: + kfree(fw_stats); + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +*/ +static int +acx_s_proc_phy_output(char *buf, acx_device_t *adev) +{ + char *p = buf; + int i; + + FN_ENTER; + + /* + if (RADIO_RFMD_11 != adev->radio_type) { + printk("sorry, not yet adapted for radio types " + "other than RFMD, please verify " + "PHY size etc. first!\n"); + goto end; + } + */ + + /* The PHY area is only 0x80 bytes long; further pages after that + * only have some page number registers with altered value, + * all other registers remain the same. */ + for (i = 0; i < 0x80; i++) { + acx_s_read_phy_reg(adev, i, p++); + } + + FN_EXIT1(p - buf); + return p - buf; +} + + +/*********************************************************************** +** acx_e_read_proc_XXXX +** Handle our /proc entry +** +** Arguments: +** standard kernel read_proc interface +** Returns: +** number of bytes written to buf +** Side effects: +** none +*/ +static int +acx_e_read_proc(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + unsigned long flags; + int length; + + FN_ENTER; + + acx_sem_lock(adev); + acx_lock(adev, flags); + /* fill buf */ + length = acx_l_proc_output(buf, adev); + acx_unlock(adev, flags); + acx_sem_unlock(adev); + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + +static int +acx_e_read_proc_diag(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + int length; + + FN_ENTER; + + acx_sem_lock(adev); + /* fill buf */ + length = acx_s_proc_diag_output(buf, adev); + acx_sem_unlock(adev); + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + +static int +acx_e_read_proc_eeprom(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + int length; + + FN_ENTER; + + /* fill buf */ + length = 0; + if (IS_PCI(adev)) { + acx_sem_lock(adev); + length = acxpci_proc_eeprom_output(buf, adev); + acx_sem_unlock(adev); + } + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + +static int +acx_e_read_proc_phy(char *buf, char **start, off_t offset, int count, + int *eof, void *data) +{ + acx_device_t *adev = (acx_device_t*)data; + int length; + + FN_ENTER; + + acx_sem_lock(adev); + /* fill buf */ + length = acx_s_proc_phy_output(buf, adev); + acx_sem_unlock(adev); + + /* housekeeping */ + if (length <= offset + count) + *eof = 1; + *start = buf + offset; + length -= offset; + if (length > count) + length = count; + if (length < 0) + length = 0; + FN_EXIT1(length); + return length; +} + + +/*********************************************************************** +** /proc files registration +*/ +static const char * const +proc_files[] = { "", "_diag", "_eeprom", "_phy" }; + +static read_proc_t * const +proc_funcs[] = { + acx_e_read_proc, + acx_e_read_proc_diag, + acx_e_read_proc_eeprom, + acx_e_read_proc_phy +}; + +static int +manage_proc_entries(const struct net_device *ndev, int remove) +{ + acx_device_t *adev = ndev2adev((struct net_device *)ndev); + char procbuf[80]; + int i; + + for (i = 0; i < VEC_SIZE(proc_files); i++) { + snprintf(procbuf, sizeof(procbuf), + "driver/acx_%s%s", ndev->name, proc_files[i]); + log(L_INIT, "%sing /proc entry %s\n", + remove ? "remov" : "creat", procbuf); + if (!remove) { + if (!create_proc_read_entry(procbuf, 0, 0, proc_funcs[i], adev)) { + printk("acx: cannot register /proc entry %s\n", procbuf); + return NOT_OK; + } + } else { + remove_proc_entry(procbuf, NULL); + } + } + return OK; +} + +int +acx_proc_register_entries(const struct net_device *ndev) +{ + return manage_proc_entries(ndev, 0); +} + +int +acx_proc_unregister_entries(const struct net_device *ndev) +{ + return manage_proc_entries(ndev, 1); +} +#endif /* CONFIG_PROC_FS */ + + +/*********************************************************************** +** acx_cmd_join_bssid +** +** Common code for both acx100 and acx111. +*/ +/* NB: does NOT match RATE100_nn but matches ACX[111]_SCAN_RATE_n */ +static const u8 +bitpos2genframe_txrate[] = { + 10, /* 0. 1 Mbit/s */ + 20, /* 1. 2 Mbit/s */ + 55, /* 2. 5.5 Mbit/s */ + 0x0B, /* 3. 6 Mbit/s */ + 0x0F, /* 4. 9 Mbit/s */ + 110, /* 5. 11 Mbit/s */ + 0x0A, /* 6. 12 Mbit/s */ + 0x0E, /* 7. 18 Mbit/s */ + 220, /* 8. 22 Mbit/s */ + 0x09, /* 9. 24 Mbit/s */ + 0x0D, /* 10. 36 Mbit/s */ + 0x08, /* 11. 48 Mbit/s */ + 0x0C, /* 12. 54 Mbit/s */ + 10, /* 13. 1 Mbit/s, should never happen */ + 10, /* 14. 1 Mbit/s, should never happen */ + 10, /* 15. 1 Mbit/s, should never happen */ +}; + +/* Looks scary, eh? +** Actually, each one compiled into one AND and one SHIFT, +** 31 bytes in x86 asm (more if uints are replaced by u16/u8) */ +static inline unsigned int +rate111to5bits(unsigned int rate) +{ + return (rate & 0x7) + | ( (rate & RATE111_11) / (RATE111_11/JOINBSS_RATES_11) ) + | ( (rate & RATE111_22) / (RATE111_22/JOINBSS_RATES_22) ) + ; +} + +static void +acx_s_cmd_join_bssid(acx_device_t *adev, const u8 *bssid) +{ + acx_joinbss_t tmp; + int dtim_interval; + int i; + + if (mac_is_zero(bssid)) + return; + + FN_ENTER; + + dtim_interval = (ACX_MODE_0_ADHOC == adev->mode) ? + 1 : adev->dtim_interval; + + memset(&tmp, 0, sizeof(tmp)); + + for (i = 0; i < ETH_ALEN; i++) { + tmp.bssid[i] = bssid[ETH_ALEN-1 - i]; + } + + tmp.beacon_interval = cpu_to_le16(adev->beacon_interval); + + /* Basic rate set. Control frame responses (such as ACK or CTS frames) + ** are sent with one of these rates */ + if (IS_ACX111(adev)) { + /* It was experimentally determined that rates_basic + ** can take 11g rates as well, not only rates + ** defined with JOINBSS_RATES_BASIC111_nnn. + ** Just use RATE111_nnn constants... */ + tmp.u.acx111.dtim_interval = dtim_interval; + tmp.u.acx111.rates_basic = cpu_to_le16(adev->rate_basic); + log(L_ASSOC, "rates_basic:%04X, rates_supported:%04X\n", + adev->rate_basic, adev->rate_oper); + } else { + tmp.u.acx100.dtim_interval = dtim_interval; + tmp.u.acx100.rates_basic = rate111to5bits(adev->rate_basic); + tmp.u.acx100.rates_supported = rate111to5bits(adev->rate_oper); + log(L_ASSOC, "rates_basic:%04X->%02X, " + "rates_supported:%04X->%02X\n", + adev->rate_basic, tmp.u.acx100.rates_basic, + adev->rate_oper, tmp.u.acx100.rates_supported); + } + + /* Setting up how Beacon, Probe Response, RTS, and PS-Poll frames + ** will be sent (rate/modulation/preamble) */ + tmp.genfrm_txrate = bitpos2genframe_txrate[lowest_bit(adev->rate_basic)]; + tmp.genfrm_mod_pre = 0; /* FIXME: was = adev->capab_short (which was always 0); */ + /* we can use short pre *if* all peers can understand it */ + /* FIXME #2: we need to correctly set PBCC/OFDM bits here too */ + + /* we switch fw to STA mode in MONITOR mode, it seems to be + ** the only mode where fw does not emit beacons by itself + ** but allows us to send anything (we really want to retain + ** ability to tx arbitrary frames in MONITOR mode) + */ + tmp.macmode = (adev->mode != ACX_MODE_MONITOR ? adev->mode : ACX_MODE_2_STA); + tmp.channel = adev->channel; + tmp.essid_len = adev->essid_len; + /* NOTE: the code memcpy'd essid_len + 1 before, which is WRONG! */ + memcpy(tmp.essid, adev->essid, tmp.essid_len); + acx_s_issue_cmd(adev, ACX1xx_CMD_JOIN, &tmp, tmp.essid_len + 0x11); + + log(L_ASSOC|L_DEBUG, "BSS_Type = %u\n", tmp.macmode); + acxlog_mac(L_ASSOC|L_DEBUG, "JoinBSSID MAC:", adev->bssid, "\n"); + + acx_update_capabilities(adev); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_s_cmd_start_scan +** +** Issue scan command to the hardware +** +** unified function for both ACX111 and ACX100 +*/ +static void +acx_s_scan_chan(acx_device_t *adev) +{ + union { + acx111_scan_t acx111; + acx100_scan_t acx100; + } s; + + FN_ENTER; + + memset(&s, 0, sizeof(s)); + + /* first common positions... */ + + s.acx111.count = cpu_to_le16(adev->scan_count); + s.acx111.rate = adev->scan_rate; + s.acx111.options = adev->scan_mode; + s.acx111.chan_duration = cpu_to_le16(adev->scan_duration); + s.acx111.max_probe_delay = cpu_to_le16(adev->scan_probe_delay); + + /* ...then differences */ + + if (IS_ACX111(adev)) { + s.acx111.channel_list_select = 0; /* scan every allowed channel */ + /*s.acx111.channel_list_select = 1;*/ /* scan given channels */ + /*s.acx111.modulation = 0x40;*/ /* long preamble? OFDM? -> only for active scan */ + s.acx111.modulation = 0; + /*s.acx111.channel_list[0] = 6; + s.acx111.channel_list[1] = 4;*/ + } else { + s.acx100.start_chan = cpu_to_le16(1); + s.acx100.flags = cpu_to_le16(0x8000); + } + + acx_s_issue_cmd(adev, ACX1xx_CMD_SCAN, &s, sizeof(s)); + FN_EXIT0; +} + + +void +acx_s_cmd_start_scan(acx_device_t *adev) +{ + /* time_before check is 'just in case' thing */ + if (!(adev->irq_status & HOST_INT_SCAN_COMPLETE) + && time_before(jiffies, adev->scan_start + 10*HZ) + ) { + log(L_INIT, "start_scan: seems like previous scan " + "is still running. Not starting anew. Please report\n"); + return; + } + + log(L_INIT, "starting radio scan\n"); + /* remember that fw is commanded to do scan */ + adev->scan_start = jiffies; + CLEAR_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); + /* issue it */ + acx_s_scan_chan(adev); +} + + +/*********************************************************************** +** acx111 feature config +*/ +static int +acx111_s_get_feature_config(acx_device_t *adev, + u32 *feature_options, u32 *data_flow_options) +{ + struct acx111_ie_feature_config feat; + + if (!IS_ACX111(adev)) { + return NOT_OK; + } + + memset(&feat, 0, sizeof(feat)); + + if (OK != acx_s_interrogate(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) { + return NOT_OK; + } + log(L_DEBUG, + "got Feature option:0x%X, DataFlow option: 0x%X\n", + feat.feature_options, + feat.data_flow_options); + + if (feature_options) + *feature_options = le32_to_cpu(feat.feature_options); + if (data_flow_options) + *data_flow_options = le32_to_cpu(feat.data_flow_options); + + return OK; +} + +static int +acx111_s_set_feature_config(acx_device_t *adev, + u32 feature_options, u32 data_flow_options, + unsigned int mode /* 0 == remove, 1 == add, 2 == set */) +{ + struct acx111_ie_feature_config feat; + + if (!IS_ACX111(adev)) { + return NOT_OK; + } + + if ((mode < 0) || (mode > 2)) + return NOT_OK; + + if (mode != 2) + /* need to modify old data */ + acx111_s_get_feature_config(adev, &feat.feature_options, &feat.data_flow_options); + else { + /* need to set a completely new value */ + feat.feature_options = 0; + feat.data_flow_options = 0; + } + + if (mode == 0) { /* remove */ + CLEAR_BIT(feat.feature_options, cpu_to_le32(feature_options)); + CLEAR_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options)); + } else { /* add or set */ + SET_BIT(feat.feature_options, cpu_to_le32(feature_options)); + SET_BIT(feat.data_flow_options, cpu_to_le32(data_flow_options)); + } + + log(L_DEBUG, + "old: feature 0x%08X dataflow 0x%08X. mode: %u\n" + "new: feature 0x%08X dataflow 0x%08X\n", + feature_options, data_flow_options, mode, + le32_to_cpu(feat.feature_options), + le32_to_cpu(feat.data_flow_options)); + + if (OK != acx_s_configure(adev, &feat, ACX1xx_IE_FEATURE_CONFIG)) { + return NOT_OK; + } + + return OK; +} + +static inline int +acx111_s_feature_off(acx_device_t *adev, u32 f, u32 d) +{ + return acx111_s_set_feature_config(adev, f, d, 0); +} +static inline int +acx111_s_feature_on(acx_device_t *adev, u32 f, u32 d) +{ + return acx111_s_set_feature_config(adev, f, d, 1); +} +static inline int +acx111_s_feature_set(acx_device_t *adev, u32 f, u32 d) +{ + return acx111_s_set_feature_config(adev, f, d, 2); +} + + +/*********************************************************************** +** acx100_s_init_memory_pools +*/ +static int +acx100_s_init_memory_pools(acx_device_t *adev, const acx_ie_memmap_t *mmt) +{ + acx100_ie_memblocksize_t MemoryBlockSize; + acx100_ie_memconfigoption_t MemoryConfigOption; + int TotalMemoryBlocks; + int RxBlockNum; + int TotalRxBlockSize; + int TxBlockNum; + int TotalTxBlockSize; + + FN_ENTER; + + /* Let's see if we can follow this: + first we select our memory block size (which I think is + completely arbitrary) */ + MemoryBlockSize.size = cpu_to_le16(adev->memblocksize); + + /* Then we alert the card to our decision of block size */ + if (OK != acx_s_configure(adev, &MemoryBlockSize, ACX100_IE_BLOCK_SIZE)) { + goto bad; + } + + /* We figure out how many total blocks we can create, using + the block size we chose, and the beginning and ending + memory pointers, i.e.: end-start/size */ + TotalMemoryBlocks = (le32_to_cpu(mmt->PoolEnd) - le32_to_cpu(mmt->PoolStart)) / adev->memblocksize; + + log(L_DEBUG, "TotalMemoryBlocks=%u (%u bytes)\n", + TotalMemoryBlocks, TotalMemoryBlocks*adev->memblocksize); + + /* MemoryConfigOption.DMA_config bitmask: + access to ACX memory is to be done: + 0x00080000 using PCI conf space?! + 0x00040000 using IO instructions? + 0x00000000 using memory access instructions + 0x00020000 using local memory block linked list (else what?) + 0x00010000 using host indirect descriptors (else host must access ACX memory?) + */ + if (IS_PCI(adev)) { + MemoryConfigOption.DMA_config = cpu_to_le32(0x30000); + /* Declare start of the Rx host pool */ + MemoryConfigOption.pRxHostDesc = cpu2acx(adev->rxhostdesc_startphy); + log(L_DEBUG, "pRxHostDesc 0x%08X, rxhostdesc_startphy 0x%lX\n", + acx2cpu(MemoryConfigOption.pRxHostDesc), + (long)adev->rxhostdesc_startphy); + } else { + MemoryConfigOption.DMA_config = cpu_to_le32(0x20000); + } + + /* 50% of the allotment of memory blocks go to tx descriptors */ + TxBlockNum = TotalMemoryBlocks / 2; + MemoryConfigOption.TxBlockNum = cpu_to_le16(TxBlockNum); + + /* and 50% go to the rx descriptors */ + RxBlockNum = TotalMemoryBlocks - TxBlockNum; + MemoryConfigOption.RxBlockNum = cpu_to_le16(RxBlockNum); + + /* size of the tx and rx descriptor queues */ + TotalTxBlockSize = TxBlockNum * adev->memblocksize; + TotalRxBlockSize = RxBlockNum * adev->memblocksize; + log(L_DEBUG, "TxBlockNum %u RxBlockNum %u TotalTxBlockSize %u " + "TotalTxBlockSize %u\n", TxBlockNum, RxBlockNum, + TotalTxBlockSize, TotalRxBlockSize); + + + /* align the tx descriptor queue to an alignment of 0x20 (32 bytes) */ + MemoryConfigOption.rx_mem = + cpu_to_le32((le32_to_cpu(mmt->PoolStart) + 0x1f) & ~0x1f); + + /* align the rx descriptor queue to units of 0x20 + * and offset it by the tx descriptor queue */ + MemoryConfigOption.tx_mem = + cpu_to_le32((le32_to_cpu(mmt->PoolStart) + TotalRxBlockSize + 0x1f) & ~0x1f); + log(L_DEBUG, "rx_mem %08X rx_mem %08X\n", + MemoryConfigOption.tx_mem, MemoryConfigOption.rx_mem); + + /* alert the device to our decision */ + if (OK != acx_s_configure(adev, &MemoryConfigOption, ACX1xx_IE_MEMORY_CONFIG_OPTIONS)) { + goto bad; + } + + /* and tell the device to kick it into gear */ + if (OK != acx_s_issue_cmd(adev, ACX100_CMD_INIT_MEMORY, NULL, 0)) { + goto bad; + } + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx100_s_create_dma_regions +** +** Note that this fn messes up heavily with hardware, but we cannot +** lock it (we need to sleep). Not a problem since IRQs can't happen +*/ +static int +acx100_s_create_dma_regions(acx_device_t *adev) +{ + acx100_ie_queueconfig_t queueconf; + acx_ie_memmap_t memmap; + int res = NOT_OK; + u32 tx_queue_start, rx_queue_start; + + FN_ENTER; + + /* read out the acx100 physical start address for the queues */ + if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + tx_queue_start = le32_to_cpu(memmap.QueueStart); + rx_queue_start = tx_queue_start + TX_CNT * sizeof(txdesc_t); + + log(L_DEBUG, "initializing Queue Indicator\n"); + + memset(&queueconf, 0, sizeof(queueconf)); + + /* Not needed for PCI, so we can avoid setting them altogether */ + if (IS_USB(adev)) { + queueconf.NumTxDesc = USB_TX_CNT; + queueconf.NumRxDesc = USB_RX_CNT; + } + + /* calculate size of queues */ + queueconf.AreaSize = cpu_to_le32( + TX_CNT * sizeof(txdesc_t) + + RX_CNT * sizeof(rxdesc_t) + 8 + ); + queueconf.NumTxQueues = 1; /* number of tx queues */ + /* sets the beginning of the tx descriptor queue */ + queueconf.TxQueueStart = memmap.QueueStart; + /* done by memset: queueconf.TxQueuePri = 0; */ + queueconf.RxQueueStart = cpu_to_le32(rx_queue_start); + queueconf.QueueOptions = 1; /* auto reset descriptor */ + /* sets the end of the rx descriptor queue */ + queueconf.QueueEnd = cpu_to_le32( + rx_queue_start + RX_CNT * sizeof(rxdesc_t) + ); + /* sets the beginning of the next queue */ + queueconf.HostQueueEnd = cpu_to_le32(le32_to_cpu(queueconf.QueueEnd) + 8); + if (OK != acx_s_configure(adev, &queueconf, ACX1xx_IE_QUEUE_CONFIG)) { + goto fail; + } + + if (IS_PCI(adev)) { + /* sets the beginning of the rx descriptor queue, after the tx descrs */ + if (OK != acxpci_s_create_hostdesc_queues(adev)) + goto fail; + acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start); + } + + if (OK != acx_s_interrogate(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + memmap.PoolStart = cpu_to_le32( + (le32_to_cpu(memmap.QueueEnd) + 4 + 0x1f) & ~0x1f + ); + + if (OK != acx_s_configure(adev, &memmap, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + if (OK != acx100_s_init_memory_pools(adev, &memmap)) { + goto fail; + } + + res = OK; + goto end; + +fail: + acx_s_msleep(1000); /* ? */ + if (IS_PCI(adev)) + acxpci_free_desc_queues(adev); +end: + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acx111_s_create_dma_regions +** +** Note that this fn messes heavily with hardware, but we cannot +** lock it (we need to sleep). Not a problem since IRQs can't happen +*/ +#define ACX111_PERCENT(percent) ((percent)/5) + +static int +acx111_s_create_dma_regions(acx_device_t *adev) +{ + struct acx111_ie_memoryconfig memconf; + struct acx111_ie_queueconfig queueconf; + u32 tx_queue_start, rx_queue_start; + + FN_ENTER; + + /* Calculate memory positions and queue sizes */ + + /* Set up our host descriptor pool + data pool */ + if (IS_PCI(adev)) { + if (OK != acxpci_s_create_hostdesc_queues(adev)) + goto fail; + } + + memset(&memconf, 0, sizeof(memconf)); + /* the number of STAs (STA contexts) to support + ** NB: was set to 1 and everything seemed to work nevertheless... */ + memconf.no_of_stations = cpu_to_le16(VEC_SIZE(adev->sta_list)); + /* specify the memory block size. Default is 256 */ + memconf.memory_block_size = cpu_to_le16(adev->memblocksize); + /* let's use 50%/50% for tx/rx (specify percentage, units of 5%) */ + memconf.tx_rx_memory_block_allocation = ACX111_PERCENT(50); + /* set the count of our queues + ** NB: struct acx111_ie_memoryconfig shall be modified + ** if we ever will switch to more than one rx and/or tx queue */ + memconf.count_rx_queues = 1; + memconf.count_tx_queues = 1; + /* 0 == Busmaster Indirect Memory Organization, which is what we want + * (using linked host descs with their allocated mem). + * 2 == Generic Bus Slave */ + /* done by memset: memconf.options = 0; */ + /* let's use 25% for fragmentations and 75% for frame transfers + * (specified in units of 5%) */ + memconf.fragmentation = ACX111_PERCENT(75); + /* Rx descriptor queue config */ + memconf.rx_queue1_count_descs = RX_CNT; + memconf.rx_queue1_type = 7; /* must be set to 7 */ + /* done by memset: memconf.rx_queue1_prio = 0; low prio */ + if (IS_PCI(adev)) { + memconf.rx_queue1_host_rx_start = cpu2acx(adev->rxhostdesc_startphy); + } + /* Tx descriptor queue config */ + memconf.tx_queue1_count_descs = TX_CNT; + /* done by memset: memconf.tx_queue1_attributes = 0; lowest priority */ + + /* NB1: this looks wrong: (memconf,ACX1xx_IE_QUEUE_CONFIG), + ** (queueconf,ACX1xx_IE_MEMORY_CONFIG_OPTIONS) look swapped, eh? + ** But it is actually correct wrt IE numbers. + ** NB2: sizeof(memconf) == 28 == 0x1c but configure(ACX1xx_IE_QUEUE_CONFIG) + ** writes 0x20 bytes (because same IE for acx100 uses struct acx100_ie_queueconfig + ** which is 4 bytes larger. what a mess. TODO: clean it up) */ + if (OK != acx_s_configure(adev, &memconf, ACX1xx_IE_QUEUE_CONFIG)) { + goto fail; + } + + acx_s_interrogate(adev, &queueconf, ACX1xx_IE_MEMORY_CONFIG_OPTIONS); + + tx_queue_start = le32_to_cpu(queueconf.tx1_queue_address); + rx_queue_start = le32_to_cpu(queueconf.rx1_queue_address); + + log(L_INIT, "dump queue head (from card):\n" + "len: %u\n" + "tx_memory_block_address: %X\n" + "rx_memory_block_address: %X\n" + "tx1_queue address: %X\n" + "rx1_queue address: %X\n", + le16_to_cpu(queueconf.len), + le32_to_cpu(queueconf.tx_memory_block_address), + le32_to_cpu(queueconf.rx_memory_block_address), + tx_queue_start, + rx_queue_start); + + if (IS_PCI(adev)) + acxpci_create_desc_queues(adev, tx_queue_start, rx_queue_start); + + FN_EXIT1(OK); + return OK; +fail: + if (IS_PCI(adev)) + acxpci_free_desc_queues(adev); + + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +*/ +static void +acx_s_initialize_rx_config(acx_device_t *adev) +{ + struct { + u16 id; + u16 len; + u16 rx_cfg1; + u16 rx_cfg2; + } ACX_PACKED cfg; + + switch (adev->mode) { + case ACX_MODE_OFF: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + /* | RX_CFG1_FILTER_MAC */ + /* | RX_CFG1_RCV_PROMISCUOUS */ + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + /*| RX_CFG2_RCV_ASSOC_REQ */ + /*| RX_CFG2_RCV_AUTH_FRAMES */ + /*| RX_CFG2_RCV_BEACON_FRAMES */ + /*| RX_CFG2_RCV_CONTENTION_FREE */ + /*| RX_CFG2_RCV_CTRL_FRAMES */ + /*| RX_CFG2_RCV_DATA_FRAMES */ + /*| RX_CFG2_RCV_BROKEN_FRAMES */ + /*| RX_CFG2_RCV_MGMT_FRAMES */ + /*| RX_CFG2_RCV_PROBE_REQ */ + /*| RX_CFG2_RCV_PROBE_RESP */ + /*| RX_CFG2_RCV_ACK_FRAMES */ + /*| RX_CFG2_RCV_OTHER */ + ); + break; + case ACX_MODE_MONITOR: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + /* | RX_CFG1_FILTER_MAC */ + | RX_CFG1_RCV_PROMISCUOUS + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + | RX_CFG2_RCV_ASSOC_REQ + | RX_CFG2_RCV_AUTH_FRAMES + | RX_CFG2_RCV_BEACON_FRAMES + | RX_CFG2_RCV_CONTENTION_FREE + | RX_CFG2_RCV_CTRL_FRAMES + | RX_CFG2_RCV_DATA_FRAMES + | RX_CFG2_RCV_BROKEN_FRAMES + | RX_CFG2_RCV_MGMT_FRAMES + | RX_CFG2_RCV_PROBE_REQ + | RX_CFG2_RCV_PROBE_RESP + | RX_CFG2_RCV_ACK_FRAMES + | RX_CFG2_RCV_OTHER + ); + break; + default: + adev->rx_config_1 = (u16) (0 + /* | RX_CFG1_INCLUDE_RXBUF_HDR */ + /* | RX_CFG1_FILTER_SSID */ + /* | RX_CFG1_FILTER_BCAST */ + /* | RX_CFG1_RCV_MC_ADDR1 */ + /* | RX_CFG1_RCV_MC_ADDR0 */ + /* | RX_CFG1_FILTER_ALL_MULTI */ + /* | RX_CFG1_FILTER_BSSID */ + | RX_CFG1_FILTER_MAC + /* | RX_CFG1_RCV_PROMISCUOUS */ + /* | RX_CFG1_INCLUDE_FCS */ + /* | RX_CFG1_INCLUDE_PHY_HDR */ + ); + adev->rx_config_2 = (u16) (0 + | RX_CFG2_RCV_ASSOC_REQ + | RX_CFG2_RCV_AUTH_FRAMES + | RX_CFG2_RCV_BEACON_FRAMES + | RX_CFG2_RCV_CONTENTION_FREE + | RX_CFG2_RCV_CTRL_FRAMES + | RX_CFG2_RCV_DATA_FRAMES + /*| RX_CFG2_RCV_BROKEN_FRAMES */ + | RX_CFG2_RCV_MGMT_FRAMES + | RX_CFG2_RCV_PROBE_REQ + | RX_CFG2_RCV_PROBE_RESP + /*| RX_CFG2_RCV_ACK_FRAMES */ + | RX_CFG2_RCV_OTHER + ); + break; + } + adev->rx_config_1 |= RX_CFG1_INCLUDE_RXBUF_HDR; + + if ((adev->rx_config_1 & RX_CFG1_INCLUDE_PHY_HDR) + || (adev->firmware_numver >= 0x02000000)) + adev->phy_header_len = IS_ACX111(adev) ? 8 : 4; + else + adev->phy_header_len = 0; + + log(L_INIT, "setting RXconfig to %04X:%04X\n", + adev->rx_config_1, adev->rx_config_2); + cfg.rx_cfg1 = cpu_to_le16(adev->rx_config_1); + cfg.rx_cfg2 = cpu_to_le16(adev->rx_config_2); + acx_s_configure(adev, &cfg, ACX1xx_IE_RXCONFIG); +} + + +/*********************************************************************** +** acx_s_set_defaults +*/ +void +acx_s_set_defaults(acx_device_t *adev) +{ + unsigned long flags; + + FN_ENTER; + + /* do it before getting settings, prevent bogus channel 0 warning */ + adev->channel = 1; + + /* query some settings from the card. + * NOTE: for some settings, e.g. CCA and ED (ACX100!), an initial + * query is REQUIRED, otherwise the card won't work correctly! */ + adev->get_mask = GETSET_ANTENNA|GETSET_SENSITIVITY|GETSET_STATION_ID|GETSET_REG_DOMAIN; + /* Only ACX100 supports ED and CCA */ + if (IS_ACX100(adev)) + adev->get_mask |= GETSET_CCA|GETSET_ED_THRESH; + + acx_s_update_card_settings(adev); + + acx_lock(adev, flags); + + /* set our global interrupt mask */ + if (IS_PCI(adev)) + acxpci_set_interrupt_mask(adev); + + adev->led_power = 1; /* LED is active on startup */ + adev->brange_max_quality = 60; /* LED blink max quality is 60 */ + adev->brange_time_last_state_change = jiffies; + + /* copy the MAC address we just got from the card + * into our MAC address used during current 802.11 session */ + MAC_COPY(adev->dev_addr, adev->ndev->dev_addr); + MAC_BCAST(adev->ap); + + adev->essid_len = + snprintf(adev->essid, sizeof(adev->essid), "STA%02X%02X%02X", + adev->dev_addr[3], adev->dev_addr[4], adev->dev_addr[5]); + adev->essid_active = 1; + + /* we have a nick field to waste, so why not abuse it + * to announce the driver version? ;-) */ + strncpy(adev->nick, "acx " ACX_RELEASE, IW_ESSID_MAX_SIZE); + + if (IS_PCI(adev)) { /* FIXME: this should be made to apply to USB, too! */ + /* first regulatory domain entry in EEPROM == default reg. domain */ + adev->reg_dom_id = adev->cfgopt_domains.list[0]; + } + + /* 0xffff would be better, but then we won't get a "scan complete" + * interrupt, so our current infrastructure will fail: */ + adev->scan_count = 1; + adev->scan_mode = ACX_SCAN_OPT_ACTIVE; + adev->scan_duration = 100; + adev->scan_probe_delay = 200; + /* reported to break scanning: adev->scan_probe_delay = adev->cfgopt_probe_delay; */ + adev->scan_rate = ACX_SCAN_RATE_1; + + adev->mode = ACX_MODE_2_STA; + adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; + adev->listen_interval = 100; + adev->beacon_interval = DEFAULT_BEACON_INTERVAL; + adev->dtim_interval = DEFAULT_DTIM_INTERVAL; + + adev->msdu_lifetime = DEFAULT_MSDU_LIFETIME; + + adev->rts_threshold = DEFAULT_RTS_THRESHOLD; + adev->frag_threshold = 2346; + + /* use standard default values for retry limits */ + adev->short_retry = 7; /* max. retries for (short) non-RTS packets */ + adev->long_retry = 4; /* max. retries for long (RTS) packets */ + + adev->preamble_mode = 2; /* auto */ + adev->fallback_threshold = 3; + adev->stepup_threshold = 10; + adev->rate_bcast = RATE111_1; + adev->rate_bcast100 = RATE100_1; + adev->rate_basic = RATE111_1 | RATE111_2; + adev->rate_auto = 1; + if (IS_ACX111(adev)) { + adev->rate_oper = RATE111_ALL; + } else { + adev->rate_oper = RATE111_ACX100_COMPAT; + } + + /* Supported Rates element - the rates here are given in units of + * 500 kbit/s, plus 0x80 added. See 802.11-1999.pdf item 7.3.2.2 */ + acx_l_update_ratevector(adev); + + /* set some more defaults */ + if (IS_ACX111(adev)) { + /* 30mW (15dBm) is default, at least in my acx111 card: */ + adev->tx_level_dbm = 15; + } else { + /* don't use max. level, since it might be dangerous + * (e.g. WRT54G people experience + * excessive Tx power damage!) */ + adev->tx_level_dbm = 18; + } + /* adev->tx_level_auto = 1; */ + if (IS_ACX111(adev)) { + /* start with sensitivity level 1 out of 3: */ + adev->sensitivity = 1; + } + +/* #define ENABLE_POWER_SAVE */ +#ifdef ENABLE_POWER_SAVE + adev->ps_wakeup_cfg = PS_CFG_ENABLE | PS_CFG_WAKEUP_ALL_BEAC; + adev->ps_listen_interval = 1; + adev->ps_options = PS_OPT_ENA_ENHANCED_PS | PS_OPT_TX_PSPOLL | PS_OPT_STILL_RCV_BCASTS; + adev->ps_hangover_period = 30; + adev->ps_enhanced_transition_time = 0; +#else + adev->ps_wakeup_cfg = 0; + adev->ps_listen_interval = 0; + adev->ps_options = 0; + adev->ps_hangover_period = 0; + adev->ps_enhanced_transition_time = 0; +#endif + + /* These settings will be set in fw on ifup */ + adev->set_mask = 0 + | GETSET_RETRY + | SET_MSDU_LIFETIME + /* configure card to do rate fallback when in auto rate mode */ + | SET_RATE_FALLBACK + | SET_RXCONFIG + | GETSET_TXPOWER + /* better re-init the antenna value we got above */ + | GETSET_ANTENNA +#if POWER_SAVE_80211 + | GETSET_POWER_80211 +#endif + ; + + acx_unlock(adev, flags); + acx_lock_unhold(); /* hold time 844814 CPU ticks @2GHz */ + + acx_s_initialize_rx_config(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** FIXME: this should be solved in a general way for all radio types +** by decoding the radio firmware module, +** since it probably has some standard structure describing how to +** set the power level of the radio module which it controls. +** Or maybe not, since the radio module probably has a function interface +** instead which then manages Tx level programming :-\ +*/ +static int +acx111_s_set_tx_level(acx_device_t *adev, u8 level_dbm) +{ + struct acx111_ie_tx_level tx_level; + + /* my acx111 card has two power levels in its configoptions (== EEPROM): + * 1 (30mW) [15dBm] + * 2 (10mW) [10dBm] + * For now, just assume all other acx111 cards have the same. + * FIXME: Ideally we would query it here, but we first need a + * standard way to query individual configoptions easily. + * Well, now we have proper cfgopt txpower variables, but this still + * hasn't been done yet, since it also requires dBm <-> mW conversion here... */ + if (level_dbm <= 12) { + tx_level.level = 2; /* 10 dBm */ + adev->tx_level_dbm = 10; + } else { + tx_level.level = 1; /* 15 dBm */ + adev->tx_level_dbm = 15; + } + if (level_dbm != adev->tx_level_dbm) + log(L_INIT, "acx111 firmware has specific " + "power levels only: adjusted %d dBm to %d dBm!\n", + level_dbm, adev->tx_level_dbm); + + return acx_s_configure(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); +} + +static int +acx_s_set_tx_level(acx_device_t *adev, u8 level_dbm) +{ + if (IS_ACX111(adev)) { + return acx111_s_set_tx_level(adev, level_dbm); + } + if (IS_PCI(adev)) { + return acx100pci_s_set_tx_level(adev, level_dbm); + } + return OK; +} + + +/*********************************************************************** +*/ +#ifdef UNUSED +/* Returns the current tx level (ACX111) */ +static u8 +acx111_s_get_tx_level(acx_device_t *adev) +{ + struct acx111_ie_tx_level tx_level; + + tx_level.level = 0; + acx_s_interrogate(adev, &tx_level, ACX1xx_IE_DOT11_TX_POWER_LEVEL); + return tx_level.level; +} +#endif + + +/*********************************************************************** +** acx_l_rxmonitor +** Called from IRQ context only +*/ +static void +acx_l_rxmonitor(acx_device_t *adev, const rxbuffer_t *rxbuf) +{ + wlansniffrm_t *msg; + struct sk_buff *skb; + void *datap; + unsigned int skb_len; + int payload_offset; + + FN_ENTER; + + /* we are in big luck: the acx100 doesn't modify any of the fields */ + /* in the 802.11 frame. just pass this packet into the PF_PACKET */ + /* subsystem. yeah. */ + payload_offset = ((u8*)acx_get_wlan_hdr(adev, rxbuf) - (u8*)rxbuf); + skb_len = RXBUF_BYTES_USED(rxbuf) - payload_offset; + + /* sanity check */ + if (unlikely(skb_len > WLAN_A4FR_MAXLEN_WEP)) { + printk("%s: monitor mode panic: oversized frame!\n", + adev->ndev->name); + goto end; + } + + if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) + skb_len += sizeof(*msg); + + /* allocate skb */ + skb = dev_alloc_skb(skb_len); + if (unlikely(!skb)) { + printk("%s: no memory for skb (%u bytes)\n", + adev->ndev->name, skb_len); + goto end; + } + + skb_put(skb, skb_len); + + if (adev->ndev->type == ARPHRD_IEEE80211) { + /* when in raw 802.11 mode, just copy frame as-is */ + datap = skb->data; + } else if (adev->ndev->type == ARPHRD_IEEE80211_PRISM) { + /* emulate prism header */ + msg = (wlansniffrm_t*)skb->data; + datap = msg + 1; + + msg->msgcode = WLANSNIFFFRM; + msg->msglen = sizeof(*msg); + strncpy(msg->devname, adev->ndev->name, sizeof(msg->devname)-1); + msg->devname[sizeof(msg->devname)-1] = '\0'; + + msg->hosttime.did = WLANSNIFFFRM_hosttime; + msg->hosttime.status = WLANITEM_STATUS_data_ok; + msg->hosttime.len = 4; + msg->hosttime.data = jiffies; + + msg->mactime.did = WLANSNIFFFRM_mactime; + msg->mactime.status = WLANITEM_STATUS_data_ok; + msg->mactime.len = 4; + msg->mactime.data = rxbuf->time; + + msg->channel.did = WLANSNIFFFRM_channel; + msg->channel.status = WLANITEM_STATUS_data_ok; + msg->channel.len = 4; + msg->channel.data = adev->channel; + + msg->rssi.did = WLANSNIFFFRM_rssi; + msg->rssi.status = WLANITEM_STATUS_no_value; + msg->rssi.len = 4; + msg->rssi.data = 0; + + msg->sq.did = WLANSNIFFFRM_sq; + msg->sq.status = WLANITEM_STATUS_no_value; + msg->sq.len = 4; + msg->sq.data = 0; + + msg->signal.did = WLANSNIFFFRM_signal; + msg->signal.status = WLANITEM_STATUS_data_ok; + msg->signal.len = 4; + msg->signal.data = rxbuf->phy_snr; + + msg->noise.did = WLANSNIFFFRM_noise; + msg->noise.status = WLANITEM_STATUS_data_ok; + msg->noise.len = 4; + msg->noise.data = rxbuf->phy_level; + + msg->rate.did = WLANSNIFFFRM_rate; + msg->rate.status = WLANITEM_STATUS_data_ok; + msg->rate.len = 4; + msg->rate.data = rxbuf->phy_plcp_signal / 5; + + msg->istx.did = WLANSNIFFFRM_istx; + msg->istx.status = WLANITEM_STATUS_data_ok; + msg->istx.len = 4; + msg->istx.data = 0; /* tx=0: it's not a tx packet */ + + skb_len -= sizeof(*msg); + + msg->frmlen.did = WLANSNIFFFRM_signal; + msg->frmlen.status = WLANITEM_STATUS_data_ok; + msg->frmlen.len = 4; + msg->frmlen.data = skb_len; + } else { + printk("acx: unsupported netdev type %d!\n", adev->ndev->type); + dev_kfree_skb(skb); + return; + } + + /* sanity check (keep it here) */ + if (unlikely((int)skb_len < 0)) { + printk("acx: skb_len=%d. Driver bug, please report\n", (int)skb_len); + dev_kfree_skb(skb); + return; + } + memcpy(datap, ((unsigned char*)rxbuf)+payload_offset, skb_len); + + skb->dev = adev->ndev; + skb->dev->last_rx = jiffies; + + skb_reset_mac_header(skb); + skb->ip_summed = CHECKSUM_NONE; + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = htons(ETH_P_80211_RAW); + netif_rx(skb); + + adev->stats.rx_packets++; + adev->stats.rx_bytes += skb->len; + +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_rx_ieee802_11_frame +** +** Called from IRQ context only +*/ + +/* All these contortions are for saner dup logging +** +** We want: (a) to know about excessive dups +** (b) to not spam kernel log about occasional dups +** +** 1/64 threshold was chosen by running "ping -A" +** It gave "rx: 59 DUPs in 2878 packets" only with 4 parallel +** "ping -A" streams running. */ +/* 2005-10-11: bumped up to 1/8 +** subtract a $smallint from dup_count in order to +** avoid "2 DUPs in 19 packets" messages */ +static inline int +acx_l_handle_dup(acx_device_t *adev, u16 seq) +{ + if (adev->dup_count) { + adev->nondup_count++; + if (time_after(jiffies, adev->dup_msg_expiry)) { + /* Log only if more than 1 dup in 64 packets */ + if (adev->nondup_count/8 < adev->dup_count-5) { + printk(KERN_INFO "%s: rx: %d DUPs in " + "%d packets received in 10 secs\n", + adev->ndev->name, + adev->dup_count, + adev->nondup_count); + } + adev->dup_count = 0; + adev->nondup_count = 0; + } + } + if (unlikely(seq == adev->last_seq_ctrl)) { + if (!adev->dup_count++) + adev->dup_msg_expiry = jiffies + 10*HZ; + adev->stats.rx_errors++; + return 1; /* a dup */ + } + adev->last_seq_ctrl = seq; + return 0; +} + +static int +acx_l_rx_ieee802_11_frame(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + unsigned int ftype, fstype; + const wlan_hdr_t *hdr; + int result = NOT_OK; + + FN_ENTER; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + /* see IEEE 802.11-1999.pdf chapter 7 "MAC frame formats" */ + if (unlikely((hdr->fc & WF_FC_PVERi) != 0)) { + printk_ratelimited(KERN_INFO "rx: unsupported 802.11 protocol\n"); + goto end; + } + + ftype = hdr->fc & WF_FC_FTYPEi; + fstype = hdr->fc & WF_FC_FSTYPEi; + + switch (ftype) { + /* check data frames first, for speed */ + case WF_FTYPE_DATAi: + switch (fstype) { + case WF_FSTYPE_DATAONLYi: + if (acx_l_handle_dup(adev, hdr->seq)) + break; /* a dup, simply discard it */ + + /* TODO: + if (WF_FC_FROMTODSi == (hdr->fc & WF_FC_FROMTODSi)) { + result = acx_l_process_data_frame_wds(adev, rxbuf); + break; + } + */ + + switch (adev->mode) { + case ACX_MODE_3_AP: + result = acx_l_process_data_frame_master(adev, rxbuf); + break; + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + result = acx_l_process_data_frame_client(adev, rxbuf); + break; + } + case WF_FSTYPE_DATA_CFACKi: + case WF_FSTYPE_DATA_CFPOLLi: + case WF_FSTYPE_DATA_CFACK_CFPOLLi: + case WF_FSTYPE_CFPOLLi: + case WF_FSTYPE_CFACK_CFPOLLi: + /* see above. + acx_process_class_frame(adev, rxbuf, 3); */ + break; + case WF_FSTYPE_NULLi: + /* acx_l_process_NULL_frame(adev, rxbuf, 3); */ + break; + /* FIXME: same here, see above */ + case WF_FSTYPE_CFACKi: + default: + break; + } + break; + case WF_FTYPE_MGMTi: + result = acx_l_process_mgmt_frame(adev, rxbuf); + break; + case WF_FTYPE_CTLi: + if (fstype == WF_FSTYPE_PSPOLLi) + result = OK; + /* this call is irrelevant, since + * acx_process_class_frame is a stub, so return + * immediately instead. + * return acx_process_class_frame(adev, rxbuf, 3); */ + break; + default: + break; + } +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_rxbuf +** +** NB: used by USB code also +*/ +void +acx_l_process_rxbuf(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + struct wlan_hdr *hdr; + unsigned int qual; + int buf_len; + u16 fc; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + fc = le16_to_cpu(hdr->fc); + /* length of frame from control field to first byte of FCS */ + buf_len = RXBUF_BYTES_RCVD(adev, rxbuf); + + if ( ((WF_FC_FSTYPE & fc) != WF_FSTYPE_BEACON) + || (acx_debug & L_XFER_BEACON) + ) { + log(L_XFER|L_DATA, "rx: %s " + "time:%u len:%u signal:%u SNR:%u macstat:%02X " + "phystat:%02X phyrate:%u status:%u\n", + acx_get_packet_type_string(fc), + le32_to_cpu(rxbuf->time), + buf_len, + acx_signal_to_winlevel(rxbuf->phy_level), + acx_signal_to_winlevel(rxbuf->phy_snr), + rxbuf->mac_status, + rxbuf->phy_stat_baseband, + rxbuf->phy_plcp_signal, + adev->status); + } + + if (unlikely(acx_debug & L_DATA)) { + printk("rx: 802.11 buf[%u]: ", buf_len); + acx_dump_bytes(hdr, buf_len); + } + + /* FIXME: should check for Rx errors (rxbuf->mac_status? + * discard broken packets - but NOT for monitor!) + * and update Rx packet statistics here */ + + if (unlikely(adev->mode == ACX_MODE_MONITOR)) { + acx_l_rxmonitor(adev, rxbuf); + } else if (likely(buf_len >= WLAN_HDR_A3_LEN)) { + acx_l_rx_ieee802_11_frame(adev, rxbuf); + } else { + log(L_DEBUG|L_XFER|L_DATA, + "rx: NOT receiving packet (%s): " + "size too small (%u)\n", + acx_get_packet_type_string(fc), + buf_len); + } + + /* Now check Rx quality level, AFTER processing packet. + * I tried to figure out how to map these levels to dBm + * values, but for the life of me I really didn't + * manage to get it. Either these values are not meant to + * be expressed in dBm, or it's some pretty complicated + * calculation. */ + +#ifdef FROM_SCAN_SOURCE_ONLY + /* only consider packets originating from the MAC + * address of the device that's managing our BSSID. + * Disable it for now, since it removes information (levels + * from different peers) and slows the Rx path. */ + if (adev->ap_client + && mac_is_equal(hdr->a2, adev->ap_client->address)) { +#endif + adev->wstats.qual.level = acx_signal_to_winlevel(rxbuf->phy_level); + adev->wstats.qual.noise = acx_signal_to_winlevel(rxbuf->phy_snr); +#ifndef OLD_QUALITY + qual = acx_signal_determine_quality(adev->wstats.qual.level, + adev->wstats.qual.noise); +#else + qual = (adev->wstats.qual.noise <= 100) ? + 100 - adev->wstats.qual.noise : 0; +#endif + adev->wstats.qual.qual = qual; + adev->wstats.qual.updated = 7; /* all 3 indicators updated */ +#ifdef FROM_SCAN_SOURCE_ONLY + } +#endif +} + + +/*********************************************************************** +** acx_l_handle_txrate_auto +** +** Theory of operation: +** client->rate_cap is a bitmask of rates client is capable of. +** client->rate_cfg is a bitmask of allowed (configured) rates. +** It is set as a result of iwconfig rate N [auto] +** or iwpriv set_rates "N,N,N N,N,N" commands. +** It can be fixed (e.g. 0x0080 == 18Mbit only), +** auto (0x00ff == 18Mbit or any lower value), +** and code handles any bitmask (0x1081 == try 54Mbit,18Mbit,1Mbit _only_). +** +** client->rate_cur is a value for rate111 field in tx descriptor. +** It is always set to txrate_cfg sans zero or more most significant +** bits. This routine handles selection of new rate_cur value depending on +** outcome of last tx event. +** +** client->rate_100 is a precalculated rate value for acx100 +** (we can do without it, but will need to calculate it on each tx). +** +** You cannot configure mixed usage of 5.5 and/or 11Mbit rate +** with PBCC and CCK modulation. Either both at CCK or both at PBCC. +** In theory you can implement it, but so far it is considered not worth doing. +** +** 22Mbit, of course, is PBCC always. */ + +/* maps acx100 tx descr rate field to acx111 one */ +static u16 +rate100to111(u8 r) +{ + switch (r) { + case RATE100_1: return RATE111_1; + case RATE100_2: return RATE111_2; + case RATE100_5: + case (RATE100_5 | RATE100_PBCC511): return RATE111_5; + case RATE100_11: + case (RATE100_11 | RATE100_PBCC511): return RATE111_11; + case RATE100_22: return RATE111_22; + default: + printk("acx: unexpected acx100 txrate: %u! " + "Please report\n", r); + return RATE111_1; + } +} + + +void +acx_l_handle_txrate_auto(acx_device_t *adev, struct client *txc, + u16 cur, u8 rate100, u16 rate111, + u8 error, int pkts_to_ignore) +{ + u16 sent_rate; + int slower_rate_was_used; + + /* vda: hmm. current code will do this: + ** 1. send packets at 11 Mbit, stepup++ + ** 2. will try to send at 22Mbit. hardware will see no ACK, + ** retries at 11Mbit, success. code notes that used rate + ** is lower. stepup = 0, fallback++ + ** 3. repeat step 2 fallback_count times. Fall back to + ** 11Mbit. go to step 1. + ** If stepup_count is large (say, 16) and fallback_count + ** is small (3), this wouldn't be too bad wrt throughput */ + + if (unlikely(!cur)) { + printk("acx: BUG! ratemask is empty\n"); + return; /* or else we may lock up the box */ + } + + /* do some preparations, i.e. calculate the one rate that was + * used to send this packet */ + if (IS_ACX111(adev)) { + sent_rate = 1 << highest_bit(rate111 & RATE111_ALL); + } else { + sent_rate = rate100to111(rate100); + } + /* sent_rate has only one bit set now, corresponding to tx rate + * which was used by hardware to tx this particular packet */ + + /* now do the actual auto rate management */ + log(L_XFER, "tx: %sclient=%p/"MACSTR" used=%04X cur=%04X cfg=%04X " + "__=%u/%u ^^=%u/%u\n", + (txc->ignore_count > 0) ? "[IGN] " : "", + txc, MAC(txc->address), sent_rate, cur, txc->rate_cfg, + txc->fallback_count, adev->fallback_threshold, + txc->stepup_count, adev->stepup_threshold + ); + + /* we need to ignore old packets already in the tx queue since + * they use older rate bytes configured before our last rate change, + * otherwise our mechanism will get confused by interpreting old data. + * Do it after logging above */ + if (txc->ignore_count) { + txc->ignore_count--; + return; + } + + /* true only if the only nonzero bit in sent_rate is + ** less significant than highest nonzero bit in cur */ + slower_rate_was_used = ( cur > ((sent_rate<<1)-1) ); + + if (slower_rate_was_used || error) { + txc->stepup_count = 0; + if (++txc->fallback_count <= adev->fallback_threshold) + return; + txc->fallback_count = 0; + + /* clear highest 1 bit in cur */ + sent_rate = RATE111_54; + while (!(cur & sent_rate)) sent_rate >>= 1; + CLEAR_BIT(cur, sent_rate); + if (!cur) /* we can't disable all rates! */ + cur = sent_rate; + log(L_XFER, "tx: falling back to ratemask %04X\n", cur); + + } else { /* there was neither lower rate nor error */ + txc->fallback_count = 0; + if (++txc->stepup_count <= adev->stepup_threshold) + return; + txc->stepup_count = 0; + + /* Sanitize. Sort of not needed, but I dont trust hw that much... + ** what if it can report bogus tx rates sometimes? */ + while (!(cur & sent_rate)) sent_rate >>= 1; + + /* try to find a higher sent_rate that isn't yet in our + * current set, but is an allowed cfg */ + while (1) { + sent_rate <<= 1; + if (sent_rate > txc->rate_cfg) + /* no higher rates allowed by config */ + return; + if (!(cur & sent_rate) && (txc->rate_cfg & sent_rate)) + /* found */ + break; + /* not found, try higher one */ + } + SET_BIT(cur, sent_rate); + log(L_XFER, "tx: stepping up to ratemask %04X\n", cur); + } + + txc->rate_cur = cur; + txc->ignore_count = pkts_to_ignore; + /* calculate acx100 style rate byte if needed */ + if (IS_ACX100(adev)) { + txc->rate_100 = acx_bitpos2rate100[highest_bit(cur)]; + } +} + + +/*********************************************************************** +** acx_i_start_xmit +** +** Called by network core. Can be called outside of process context. +*/ +int +acx_i_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + acx_device_t *adev = ndev2adev(ndev); + tx_t *tx; + void *txbuf; + unsigned long flags; + int txresult = NOT_OK; + int len; + + FN_ENTER; + + if (unlikely(!skb)) { + /* indicate success */ + txresult = OK; + goto end_no_unlock; + } + if (unlikely(!adev)) { + goto end_no_unlock; + } + + acx_lock(adev, flags); + + if (unlikely(!(adev->dev_state_mask & ACX_STATE_IFACE_UP))) { + goto end; + } + if (unlikely(adev->mode == ACX_MODE_OFF)) { + goto end; + } + if (unlikely(acx_queue_stopped(ndev))) { + log(L_DEBUG, "%s: called when queue stopped\n", __func__); + goto end; + } + if (unlikely(ACX_STATUS_4_ASSOCIATED != adev->status)) { + log(L_XFER, "trying to xmit, but not associated yet: " + "aborting...\n"); + /* silently drop the packet, since we're not connected yet */ + txresult = OK; + /* ...but indicate an error nevertheless */ + adev->stats.tx_errors++; + goto end; + } + + tx = acx_l_alloc_tx(adev); + if (unlikely(!tx)) { + printk_ratelimited("%s: start_xmit: txdesc ring is full, " + "dropping tx\n", ndev->name); + txresult = NOT_OK; + goto end; + } + + txbuf = acx_l_get_txbuf(adev, tx); + if (unlikely(!txbuf)) { + /* Card was removed */ + txresult = NOT_OK; + acx_l_dealloc_tx(adev, tx); + goto end; + } + len = acx_ether_to_txbuf(adev, txbuf, skb); + if (unlikely(len < 0)) { + /* Error in packet conversion */ + txresult = NOT_OK; + acx_l_dealloc_tx(adev, tx); + goto end; + } + acx_l_tx_data(adev, tx, len); + ndev->trans_start = jiffies; + + txresult = OK; + adev->stats.tx_packets++; + adev->stats.tx_bytes += skb->len; + +end: + acx_unlock(adev, flags); + +end_no_unlock: + if ((txresult == OK) && skb) + dev_kfree_skb_any(skb); + + FN_EXIT1(txresult); + return txresult; +} + + +/*********************************************************************** +** acx_l_update_ratevector +** +** Updates adev->rate_supported[_len] according to rate_{basic,oper} +*/ +const u8 +acx_bitpos2ratebyte[] = { + DOT11RATEBYTE_1, + DOT11RATEBYTE_2, + DOT11RATEBYTE_5_5, + DOT11RATEBYTE_6_G, + DOT11RATEBYTE_9_G, + DOT11RATEBYTE_11, + DOT11RATEBYTE_12_G, + DOT11RATEBYTE_18_G, + DOT11RATEBYTE_22, + DOT11RATEBYTE_24_G, + DOT11RATEBYTE_36_G, + DOT11RATEBYTE_48_G, + DOT11RATEBYTE_54_G, +}; + +void +acx_l_update_ratevector(acx_device_t *adev) +{ + u16 bcfg = adev->rate_basic; + u16 ocfg = adev->rate_oper; + u8 *supp = adev->rate_supported; + const u8 *dot11 = acx_bitpos2ratebyte; + + FN_ENTER; + + while (ocfg) { + if (ocfg & 1) { + *supp = *dot11; + if (bcfg & 1) { + *supp |= 0x80; + } + supp++; + } + dot11++; + ocfg >>= 1; + bcfg >>= 1; + } + adev->rate_supported_len = supp - adev->rate_supported; + if (acx_debug & L_ASSOC) { + printk("new ratevector: "); + acx_dump_bytes(adev->rate_supported, adev->rate_supported_len); + } + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_sta_list_init +*/ +static void +acx_l_sta_list_init(acx_device_t *adev) +{ + FN_ENTER; + memset(adev->sta_hash_tab, 0, sizeof(adev->sta_hash_tab)); + memset(adev->sta_list, 0, sizeof(adev->sta_list)); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_sta_list_get_from_hash +*/ +static inline client_t* +acx_l_sta_list_get_from_hash(acx_device_t *adev, const u8 *address) +{ + return adev->sta_hash_tab[address[5] % VEC_SIZE(adev->sta_hash_tab)]; +} + + +/*********************************************************************** +** acx_l_sta_list_get +*/ +client_t* +acx_l_sta_list_get(acx_device_t *adev, const u8 *address) +{ + client_t *client; + FN_ENTER; + client = acx_l_sta_list_get_from_hash(adev, address); + while (client) { + if (mac_is_equal(address, client->address)) { + client->mtime = jiffies; + break; + } + client = client->next; + } + FN_EXIT0; + return client; +} + + +/*********************************************************************** +** acx_l_sta_list_del +*/ +void +acx_l_sta_list_del(acx_device_t *adev, client_t *victim) +{ + client_t *client, *next; + + client = acx_l_sta_list_get_from_hash(adev, victim->address); + next = client; + /* tricky. next = client on first iteration only, + ** on all other iters next = client->next */ + while (next) { + if (next == victim) { + client->next = victim->next; + /* Overkill */ + memset(victim, 0, sizeof(*victim)); + break; + } + client = next; + next = client->next; + } +} + + +/*********************************************************************** +** acx_l_sta_list_alloc +** +** Never fails - will evict oldest client if needed +*/ +static client_t* +acx_l_sta_list_alloc(acx_device_t *adev) +{ + int i; + unsigned long age, oldest_age; + client_t *client, *oldest; + + FN_ENTER; + + oldest = &adev->sta_list[0]; + oldest_age = 0; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client = &adev->sta_list[i]; + + if (!client->used) { + goto found; + } else { + age = jiffies - client->mtime; + if (oldest_age < age) { + oldest_age = age; + oldest = client; + } + } + } + acx_l_sta_list_del(adev, oldest); + client = oldest; +found: + memset(client, 0, sizeof(*client)); + FN_EXIT0; + return client; +} + + +/*********************************************************************** +** acx_l_sta_list_add +** +** Never fails - will evict oldest client if needed +*/ +/* In case we will reimplement it differently... */ +#define STA_LIST_ADD_CAN_FAIL 0 + +static client_t* +acx_l_sta_list_add(acx_device_t *adev, const u8 *address) +{ + client_t *client; + int index; + + FN_ENTER; + + client = acx_l_sta_list_alloc(adev); + + client->mtime = jiffies; + MAC_COPY(client->address, address); + client->used = CLIENT_EXIST_1; + client->auth_alg = WLAN_AUTH_ALG_SHAREDKEY; + client->auth_step = 1; + /* give some tentative peer rate values + ** (needed because peer may do auth without probing us first, + ** thus we'll have no idea of peer's ratevector yet). + ** Will be overwritten by scanning or assoc code */ + client->rate_cap = adev->rate_basic; + client->rate_cfg = adev->rate_basic; + client->rate_cur = 1 << lowest_bit(adev->rate_basic); + + index = address[5] % VEC_SIZE(adev->sta_hash_tab); + client->next = adev->sta_hash_tab[index]; + adev->sta_hash_tab[index] = client; + + acxlog_mac(L_ASSOC, "sta_list_add: sta=", address, "\n"); + + FN_EXIT0; + return client; +} + + +/*********************************************************************** +** acx_l_sta_list_get_or_add +** +** Never fails - will evict oldest client if needed +*/ +static client_t* +acx_l_sta_list_get_or_add(acx_device_t *adev, const u8 *address) +{ + client_t *client = acx_l_sta_list_get(adev, address); + if (!client) + client = acx_l_sta_list_add(adev, address); + return client; +} + + +/*********************************************************************** +** acx_set_status +** +** This function is called in many atomic regions, must not sleep +** +** This function does not need locking UNLESS you call it +** as acx_set_status(ACX_STATUS_4_ASSOCIATED), bacause this can +** wake queue. This can race with stop_queue elsewhere. +** See acx_stop_queue comment. */ +void +acx_set_status(acx_device_t *adev, u16 new_status) +{ +#define QUEUE_OPEN_AFTER_ASSOC 1 /* this really seems to be needed now */ + u16 old_status = adev->status; + + FN_ENTER; + + log(L_ASSOC, "%s(%d):%s\n", + __func__, new_status, acx_get_status_name(new_status)); + + /* wireless_send_event never sleeps */ + if (ACX_STATUS_4_ASSOCIATED == new_status) { + union iwreq_data wrqu; + + wrqu.data.length = 0; + wrqu.data.flags = 0; + wireless_send_event(adev->ndev, SIOCGIWSCAN, &wrqu, NULL); + + wrqu.data.length = 0; + wrqu.data.flags = 0; + MAC_COPY(wrqu.ap_addr.sa_data, adev->bssid); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL); + } else { + union iwreq_data wrqu; + + /* send event with empty BSSID to indicate we're not associated */ + MAC_ZERO(wrqu.ap_addr.sa_data); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + wireless_send_event(adev->ndev, SIOCGIWAP, &wrqu, NULL); + } + + adev->status = new_status; + + switch (new_status) { + case ACX_STATUS_1_SCANNING: + adev->scan_retries = 0; + /* 1.0 s initial scan time */ + acx_set_timer(adev, 1000000); + break; + case ACX_STATUS_2_WAIT_AUTH: + case ACX_STATUS_3_AUTHENTICATED: + adev->auth_or_assoc_retries = 0; + acx_set_timer(adev, 1500000); /* 1.5 s */ + break; + } + +#if QUEUE_OPEN_AFTER_ASSOC + if (new_status == ACX_STATUS_4_ASSOCIATED) { + if (old_status < ACX_STATUS_4_ASSOCIATED) { + /* ah, we're newly associated now, + * so let's indicate carrier */ + acx_carrier_on(adev->ndev, "after association"); + acx_wake_queue(adev->ndev, "after association"); + } + } else { + /* not associated any more, so let's kill carrier */ + if (old_status >= ACX_STATUS_4_ASSOCIATED) { + acx_carrier_off(adev->ndev, "after losing association"); + acx_stop_queue(adev->ndev, "after losing association"); + } + } +#endif + FN_EXIT0; +} + + +/*********************************************************************** +** acx_i_timer +** +** Fires up periodically. Used to kick scan/auth/assoc if something goes wrong +*/ +void +acx_i_timer(unsigned long address) +{ + unsigned long flags; + acx_device_t *adev = (acx_device_t*)address; + + FN_ENTER; + + acx_lock(adev, flags); + + log(L_DEBUG|L_ASSOC, "%s: adev->status=%d (%s)\n", + __func__, adev->status, acx_get_status_name(adev->status)); + + switch (adev->status) { + case ACX_STATUS_1_SCANNING: + /* was set to 0 by set_status() */ + if (++adev->scan_retries < 7) { + acx_set_timer(adev, 1000000); + /* used to interrogate for scan status. + ** We rely on SCAN_COMPLETE IRQ instead */ + log(L_ASSOC, "continuing scan (%d sec)\n", + adev->scan_retries); + } else { + log(L_ASSOC, "stopping scan\n"); + /* send stop_scan cmd when we leave the interrupt context, + * and make a decision what to do next (COMPLETE_SCAN) */ + acx_schedule_task(adev, + ACX_AFTER_IRQ_CMD_STOP_SCAN + ACX_AFTER_IRQ_COMPLETE_SCAN); + } + break; + case ACX_STATUS_2_WAIT_AUTH: + /* was set to 0 by set_status() */ + if (++adev->auth_or_assoc_retries < 10) { + log(L_ASSOC, "resend authen1 request (attempt %d)\n", + adev->auth_or_assoc_retries + 1); + acx_l_transmit_authen1(adev); + } else { + /* time exceeded: fall back to scanning mode */ + log(L_ASSOC, + "authen1 request reply timeout, giving up\n"); + /* we are a STA, need to find AP anyhow */ + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN); + } + /* used to be 1500000, but some other driver uses 2.5s */ + acx_set_timer(adev, 2500000); + break; + case ACX_STATUS_3_AUTHENTICATED: + /* was set to 0 by set_status() */ + if (++adev->auth_or_assoc_retries < 10) { + log(L_ASSOC, "resend assoc request (attempt %d)\n", + adev->auth_or_assoc_retries + 1); + acx_l_transmit_assoc_req(adev); + } else { + /* time exceeded: give up */ + log(L_ASSOC, + "association request reply timeout, giving up\n"); + /* we are a STA, need to find AP anyhow */ + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_schedule_task(adev, ACX_AFTER_IRQ_RESTART_SCAN); + } + acx_set_timer(adev, 2500000); /* see above */ + break; + case ACX_STATUS_4_ASSOCIATED: + default: + break; + } + + acx_unlock(adev, flags); + + FN_EXIT0; +} + + +/*********************************************************************** +** acx_set_timer +** +** Sets the 802.11 state management timer's timeout. +*/ +void +acx_set_timer(acx_device_t *adev, int timeout_us) +{ + FN_ENTER; + + log(L_DEBUG|L_IRQ, "%s(%u ms)\n", __func__, timeout_us/1000); + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + printk("attempt to set the timer " + "when the card interface is not up!\n"); + goto end; + } + + /* first check if the timer was already initialized, THEN modify it */ + if (adev->mgmt_timer.function) { + mod_timer(&adev->mgmt_timer, + jiffies + (timeout_us * HZ / 1000000)); + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_transmit_assocresp +** +** We are an AP here +*/ +static const u8 +dot11ratebyte[] = { + DOT11RATEBYTE_1, + DOT11RATEBYTE_2, + DOT11RATEBYTE_5_5, + DOT11RATEBYTE_6_G, + DOT11RATEBYTE_9_G, + DOT11RATEBYTE_11, + DOT11RATEBYTE_12_G, + DOT11RATEBYTE_18_G, + DOT11RATEBYTE_22, + DOT11RATEBYTE_24_G, + DOT11RATEBYTE_36_G, + DOT11RATEBYTE_48_G, + DOT11RATEBYTE_54_G, +}; + +static inline int +find_pos(const u8 *p, int size, u8 v) +{ + int i; + for (i = 0; i < size; i++) + if (p[i] == v) + return i; + /* printk a message about strange byte? */ + return 0; +} + +static void +add_bits_to_ratemasks(u8* ratevec, int len, u16* brate, u16* orate) +{ + while (len--) { + int n = 1 << find_pos(dot11ratebyte, + sizeof(dot11ratebyte), *ratevec & 0x7f); + if (*ratevec & 0x80) + *brate |= n; + *orate |= n; + ratevec++; + } +} + +static int +acx_l_transmit_assocresp(acx_device_t *adev, const wlan_fr_assocreq_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct assocresp_frame_body *body; + u8 *p; + const u8 *da; + /* const u8 *sa; */ + const u8 *bssid; + client_t *clt; + + FN_ENTER; + + /* sa = req->hdr->a1; */ + da = req->hdr->a2; + bssid = req->hdr->a3; + + clt = acx_l_sta_list_get(adev, da); + if (!clt) + goto ok; + + /* Assoc without auth is a big no-no */ + /* Let's be liberal: if already assoc'ed STA sends assoc req again, + ** we won't be rude */ + if (clt->used != CLIENT_AUTHENTICATED_2 + && clt->used != CLIENT_ASSOCIATED_3) { + acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); + goto bad; + } + + clt->used = CLIENT_ASSOCIATED_3; + + if (clt->aid == 0) + clt->aid = ++adev->aid; + clt->cap_info = ieee2host16(*(req->cap_info)); + + /* We cheat here a bit. We don't really care which rates are flagged + ** as basic by the client, so we stuff them in single ratemask */ + clt->rate_cap = 0; + if (req->supp_rates) + add_bits_to_ratemasks(req->supp_rates->rates, + req->supp_rates->len, &clt->rate_cap, &clt->rate_cap); + if (req->ext_rates) + add_bits_to_ratemasks(req->ext_rates->rates, + req->ext_rates->len, &clt->rate_cap, &clt->rate_cap); + /* We can check that client supports all basic rates, + ** and deny assoc if not. But let's be liberal, right? ;) */ + clt->rate_cfg = clt->rate_cap & adev->rate_oper; + if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper); + clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); + if (IS_ACX100(adev)) + clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)]; + clt->fallback_count = clt->stepup_count = 0; + clt->ignore_count = 16; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_ASSOCRESPi; + head->dur = req->hdr->dur; + MAC_COPY(head->da, da); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, bssid); + head->seq = req->hdr->seq; + + body->cap_info = host2ieee16(adev->capabilities); + body->status = host2ieee16(0); + body->aid = host2ieee16(clt->aid); + p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len, + adev->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, + adev->rate_supported); + + acx_l_tx_data(adev, tx, p - (u8*)head); +ok: + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +* acx_l_transmit_reassocresp + +You may be wondering, just like me, what the hell ReAuth is. +In practice it was seen sent by STA when STA feels like losing connection. + +[802.11] + +5.4.2.3 Reassociation + +Association is sufficient for no-transition message delivery between +IEEE 802.11 stations. Additional functionality is needed to support +BSS-transition mobility. The additional required functionality +is provided by the reassociation service. Reassociation is a DSS. +The reassociation service is invoked to 'move' a current association +from one AP to another. This keeps the DS informed of the current +mapping between AP and STA as the station moves from BSS to BSS within +an ESS. Reassociation also enables changing association attributes +of an established association while the STA remains associated with +the same AP. Reassociation is always initiated by the mobile STA. + +5.4.3.1 Authentication +... +A STA may be authenticated with many other STAs at any given instant. + +5.4.3.1.1 Preauthentication + +Because the authentication process could be time-consuming (depending +on the authentication protocol in use), the authentication service can +be invoked independently of the association service. Preauthentication +is typically done by a STA while it is already associated with an AP +(with which it previously authenticated). IEEE 802.11 does not require +that STAs preauthenticate with APs. However, authentication is required +before an association can be established. If the authentication is left +until reassociation time, this may impact the speed with which a STA can +reassociate between APs, limiting BSS-transition mobility performance. +The use of preauthentication takes the authentication service overhead +out of the time-critical reassociation process. + +5.7.3 Reassociation + +For a STA to reassociate, the reassociation service causes the following +message to occur: + + Reassociation request + +* Message type: Management +* Message subtype: Reassociation request +* Information items: + - IEEE address of the STA + - IEEE address of the AP with which the STA will reassociate + - IEEE address of the AP with which the STA is currently associated + - ESSID +* Direction of message: From STA to 'new' AP + +The address of the current AP is included for efficiency. The inclusion +of the current AP address facilitates MAC reassociation to be independent +of the DS implementation. + + Reassociation response +* Message type: Management +* Message subtype: Reassociation response +* Information items: + - Result of the requested reassociation. (success/failure) + - If the reassociation is successful, the response shall include the AID. +* Direction of message: From AP to STA + +7.2.3.6 Reassociation Request frame format + +The frame body of a management frame of subtype Reassociation Request +contains the information shown in Table 9. + +Table 9 Reassociation Request frame body +Order Information +1 Capability information +2 Listen interval +3 Current AP address +4 SSID +5 Supported rates + +7.2.3.7 Reassociation Response frame format + +The frame body of a management frame of subtype Reassociation Response +contains the information shown in Table 10. + +Table 10 Reassociation Response frame body +Order Information +1 Capability information +2 Status code +3 Association ID (AID) +4 Supported rates + +*/ +static int +acx_l_transmit_reassocresp(acx_device_t *adev, const wlan_fr_reassocreq_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct reassocresp_frame_body *body; + u8 *p; + const u8 *da; + /* const u8 *sa; */ + const u8 *bssid; + client_t *clt; + + FN_ENTER; + + /* sa = req->hdr->a1; */ + da = req->hdr->a2; + bssid = req->hdr->a3; + + /* Must be already authenticated, so it must be in the list */ + clt = acx_l_sta_list_get(adev, da); + if (!clt) + goto ok; + + /* Assoc without auth is a big no-no */ + /* Already assoc'ed STAs sending ReAssoc req are ok per 802.11 */ + if (clt->used != CLIENT_AUTHENTICATED_2 + && clt->used != CLIENT_ASSOCIATED_3) { + acx_l_transmit_deauthen(adev, da, WLAN_MGMT_REASON_CLASS2_NONAUTH); + goto bad; + } + + clt->used = CLIENT_ASSOCIATED_3; + if (clt->aid == 0) { + clt->aid = ++adev->aid; + } + if (req->cap_info) + clt->cap_info = ieee2host16(*(req->cap_info)); + + /* We cheat here a bit. We don't really care which rates are flagged + ** as basic by the client, so we stuff them in single ratemask */ + clt->rate_cap = 0; + if (req->supp_rates) + add_bits_to_ratemasks(req->supp_rates->rates, + req->supp_rates->len, &clt->rate_cap, &clt->rate_cap); + if (req->ext_rates) + add_bits_to_ratemasks(req->ext_rates->rates, + req->ext_rates->len, &clt->rate_cap, &clt->rate_cap); + /* We can check that client supports all basic rates, + ** and deny assoc if not. But let's be liberal, right? ;) */ + clt->rate_cfg = clt->rate_cap & adev->rate_oper; + if (!clt->rate_cfg) clt->rate_cfg = 1 << lowest_bit(adev->rate_oper); + clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); + if (IS_ACX100(adev)) + clt->rate_100 = acx_bitpos2rate100[lowest_bit(clt->rate_cfg)]; + + clt->fallback_count = clt->stepup_count = 0; + clt->ignore_count = 16; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto ok; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto ok; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_REASSOCRESPi; + head->dur = req->hdr->dur; + MAC_COPY(head->da, da); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, bssid); + head->seq = req->hdr->seq; + + /* IEs: 1. caps */ + body->cap_info = host2ieee16(adev->capabilities); + /* 2. status code */ + body->status = host2ieee16(0); + /* 3. AID */ + body->aid = host2ieee16(clt->aid); + /* 4. supp rates */ + p = wlan_fill_ie_rates((u8*)&body->rates, adev->rate_supported_len, + adev->rate_supported); + /* 5. ext supp rates */ + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, + adev->rate_supported); + + acx_l_tx_data(adev, tx, p - (u8*)head); +ok: + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_process_disassoc_from_sta +*/ +static void +acx_l_process_disassoc_from_sta(acx_device_t *adev, const wlan_fr_disassoc_t *req) +{ + const u8 *ta; + client_t *clt; + + FN_ENTER; + + ta = req->hdr->a2; + clt = acx_l_sta_list_get(adev, ta); + if (!clt) + goto end; + + if (clt->used != CLIENT_ASSOCIATED_3 + && clt->used != CLIENT_AUTHENTICATED_2) { + /* it's disassociating, but it's + ** not even authenticated! Let it know that */ + acxlog_mac(L_ASSOC|L_XFER, "peer ", ta, "has sent disassoc " + "req but it is not even auth'ed! sending deauth\n"); + acx_l_transmit_deauthen(adev, ta, + WLAN_MGMT_REASON_CLASS2_NONAUTH); + clt->used = CLIENT_EXIST_1; + } else { + /* mark it as auth'ed only */ + clt->used = CLIENT_AUTHENTICATED_2; + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_deauthen_from_sta +*/ +static void +acx_l_process_deauth_from_sta(acx_device_t *adev, const wlan_fr_deauthen_t *req) +{ + const wlan_hdr_t *hdr; + client_t *client; + + FN_ENTER; + + hdr = req->hdr; + + if (acx_debug & L_ASSOC) { + acx_print_mac("got deauth from sta:", hdr->a2, " "); + acx_print_mac("a1:", hdr->a1, " "); + acx_print_mac("a3:", hdr->a3, " "); + acx_print_mac("adev->addr:", adev->dev_addr, " "); + acx_print_mac("adev->bssid:", adev->bssid, "\n"); + } + + if (!mac_is_equal(adev->dev_addr, hdr->a1)) { + goto end; + } + + client = acx_l_sta_list_get(adev, hdr->a2); + if (!client) { + goto end; + } + client->used = CLIENT_EXIST_1; +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_disassoc_from_ap +*/ +static void +acx_l_process_disassoc_from_ap(acx_device_t *adev, const wlan_fr_disassoc_t *req) +{ + FN_ENTER; + + if (!adev->ap_client) { + /* Hrm, we aren't assoc'ed yet anyhow... */ + goto end; + } + + printk("%s: got disassoc frame with reason %d (%s)\n", + adev->ndev->name, *req->reason, + acx_wlan_reason_str(*req->reason)); + + if (mac_is_equal(adev->dev_addr, req->hdr->a1)) { + acx_l_transmit_deauthen(adev, adev->bssid, + WLAN_MGMT_REASON_DEAUTH_LEAVING); + SET_BIT(adev->set_mask, GETSET_RESCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_deauth_from_ap +*/ +static void +acx_l_process_deauth_from_ap(acx_device_t *adev, const wlan_fr_deauthen_t *req) +{ + FN_ENTER; + + if (!adev->ap_client) { + /* Hrm, we aren't assoc'ed yet anyhow... */ + goto end; + } + + printk("%s: got deauth frame with reason %d (%s)\n", + adev->ndev->name, *req->reason, + acx_wlan_reason_str(*req->reason)); + + /* Chk: is ta verified to be from our AP? */ + if (mac_is_equal(adev->dev_addr, req->hdr->a1)) { + log(L_DEBUG, "AP sent us deauth packet\n"); + SET_BIT(adev->set_mask, GETSET_RESCAN); + acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + } +end: + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_rx +** +** The end of the Rx path. Pulls data from a rxhostdesc into a socket +** buffer and feeds it to the network stack via netif_rx(). +*/ +static void +acx_l_rx(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + FN_ENTER; + if (likely(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + struct sk_buff *skb; + skb = acx_rxbuf_to_ether(adev, rxbuf); + if (likely(skb)) { + netif_rx(skb); + adev->ndev->last_rx = jiffies; + adev->stats.rx_packets++; + adev->stats.rx_bytes += skb->len; + } + } + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_process_data_frame_master +*/ +static int +acx_l_process_data_frame_master(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + struct wlan_hdr *hdr; + struct tx *tx; + void *txbuf; + int len; + int result = NOT_OK; + + FN_ENTER; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + switch (WF_FC_FROMTODSi & hdr->fc) { + case 0: + case WF_FC_FROMDSi: + log(L_DEBUG, "ap->sta or adhoc->adhoc data frame ignored\n"); + goto done; + case WF_FC_TODSi: + break; + default: /* WF_FC_FROMTODSi */ + log(L_DEBUG, "wds data frame ignored (TODO)\n"); + goto done; + } + + /* check if it is our BSSID, if not, leave */ + if (!mac_is_equal(adev->bssid, hdr->a1)) { + goto done; + } + + if (mac_is_equal(adev->dev_addr, hdr->a3)) { + /* this one is for us */ + acx_l_rx(adev, rxbuf); + } else { + if (mac_is_bcast(hdr->a3)) { + /* this one is bcast, rx it too */ + acx_l_rx(adev, rxbuf); + } + tx = acx_l_alloc_tx(adev); + if (!tx) { + goto fail; + } + /* repackage, tx, and hope it someday reaches its destination */ + /* order is important, we do it in-place */ + MAC_COPY(hdr->a1, hdr->a3); + MAC_COPY(hdr->a3, hdr->a2); + MAC_COPY(hdr->a2, adev->bssid); + /* To_DS = 0, From_DS = 1 */ + hdr->fc = WF_FC_FROMDSi + WF_FTYPE_DATAi; + + txbuf = acx_l_get_txbuf(adev, tx); + if (txbuf) { + len = RXBUF_BYTES_RCVD(adev, rxbuf); + memcpy(txbuf, hdr, len); + acx_l_tx_data(adev, tx, len); + } else { + acx_l_dealloc_tx(adev, tx); + } + } +done: + result = OK; +fail: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_data_frame_client +*/ +static int +acx_l_process_data_frame_client(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + const u8 *da, *bssid; + const wlan_hdr_t *hdr; + struct net_device *ndev = adev->ndev; + int result = NOT_OK; + + FN_ENTER; + + if (ACX_STATUS_4_ASSOCIATED != adev->status) + goto drop; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + switch (WF_FC_FROMTODSi & hdr->fc) { + case 0: + if (adev->mode != ACX_MODE_0_ADHOC) { + log(L_DEBUG, "adhoc->adhoc data frame ignored\n"); + goto drop; + } + bssid = hdr->a3; + break; + case WF_FC_FROMDSi: + if (adev->mode != ACX_MODE_2_STA) { + log(L_DEBUG, "ap->sta data frame ignored\n"); + goto drop; + } + bssid = hdr->a2; + break; + case WF_FC_TODSi: + log(L_DEBUG, "sta->ap data frame ignored\n"); + goto drop; + default: /* WF_FC_FROMTODSi: wds->wds */ + log(L_DEBUG, "wds data frame ignored (todo)\n"); + goto drop; + } + + da = hdr->a1; + + if (unlikely(acx_debug & L_DEBUG)) { + acx_print_mac("rx: da=", da, ""); + acx_print_mac(" bssid=", bssid, ""); + acx_print_mac(" adev->bssid=", adev->bssid, ""); + acx_print_mac(" adev->addr=", adev->dev_addr, "\n"); + } + + /* promiscuous mode --> receive all packets */ + if (unlikely(ndev->flags & IFF_PROMISC)) + goto process; + + /* FIRST, check if it is our BSSID */ + if (!mac_is_equal(adev->bssid, bssid)) { + /* is not our BSSID, so bail out */ + goto drop; + } + + /* then, check if it is our address */ + if (mac_is_equal(adev->dev_addr, da)) { + goto process; + } + + /* then, check if it is broadcast */ + if (mac_is_bcast(da)) { + goto process; + } + + if (mac_is_mcast(da)) { + /* unconditionally receive all multicasts */ + if (ndev->flags & IFF_ALLMULTI) + goto process; + + /* FIXME: need to check against the list of + * multicast addresses that are configured + * for the interface (ifconfig) */ + log(L_XFER, "FIXME: multicast packet, need to check " + "against a list of multicast addresses " + "(to be created!); accepting packet for now\n"); + /* for now, just accept it here */ + goto process; + } + + log(L_DEBUG, "rx: foreign packet, dropping\n"); + goto drop; +process: + /* receive packet */ + acx_l_rx(adev, rxbuf); + + result = OK; +drop: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_mgmt_frame +** +** Theory of operation: mgmt packet gets parsed (to make it easy +** to access variable-sized IEs), results stored in 'parsed'. +** Then we react to the packet. +*/ +typedef union parsed_mgmt_req { + wlan_fr_mgmt_t mgmt; + wlan_fr_assocreq_t assocreq; + wlan_fr_reassocreq_t reassocreq; + wlan_fr_assocresp_t assocresp; + wlan_fr_reassocresp_t reassocresp; + wlan_fr_beacon_t beacon; + wlan_fr_disassoc_t disassoc; + wlan_fr_authen_t authen; + wlan_fr_deauthen_t deauthen; + wlan_fr_proberesp_t proberesp; +} parsed_mgmt_req_t; + +void BUG_excessive_stack_usage(void); + +static int +acx_l_process_mgmt_frame(acx_device_t *adev, rxbuffer_t *rxbuf) +{ + parsed_mgmt_req_t parsed; /* takes ~100 bytes of stack */ + wlan_hdr_t *hdr; + int adhoc, sta_scan, sta, ap; + int len; + + if (sizeof(parsed) > 256) + BUG_excessive_stack_usage(); + + FN_ENTER; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + /* Management frames never have these set */ + if (WF_FC_FROMTODSi & hdr->fc) { + FN_EXIT1(NOT_OK); + return NOT_OK; + } + + len = RXBUF_BYTES_RCVD(adev, rxbuf); + if (WF_FC_ISWEPi & hdr->fc) + len -= 0x10; + + adhoc = (adev->mode == ACX_MODE_0_ADHOC); + sta_scan = ((adev->mode == ACX_MODE_2_STA) + && (adev->status != ACX_STATUS_4_ASSOCIATED)); + sta = ((adev->mode == ACX_MODE_2_STA) + && (adev->status == ACX_STATUS_4_ASSOCIATED)); + ap = (adev->mode == ACX_MODE_3_AP); + + switch (WF_FC_FSTYPEi & hdr->fc) { + /* beacons first, for speed */ + case WF_FSTYPE_BEACONi: + memset(&parsed.beacon, 0, sizeof(parsed.beacon)); + parsed.beacon.hdr = hdr; + parsed.beacon.len = len; + if (acx_debug & L_DATA) { + printk("beacon len:%d fc:%04X dur:%04X seq:%04X", + len, hdr->fc, hdr->dur, hdr->seq); + acx_print_mac(" a1:", hdr->a1, ""); + acx_print_mac(" a2:", hdr->a2, ""); + acx_print_mac(" a3:", hdr->a3, "\n"); + } + wlan_mgmt_decode_beacon(&parsed.beacon); + /* beacon and probe response are very similar, so... */ + acx_l_process_probe_response(adev, &parsed.beacon, rxbuf); + break; + case WF_FSTYPE_ASSOCREQi: + if (!ap) + break; + memset(&parsed.assocreq, 0, sizeof(parsed.assocreq)); + parsed.assocreq.hdr = hdr; + parsed.assocreq.len = len; + wlan_mgmt_decode_assocreq(&parsed.assocreq); + if (mac_is_equal(hdr->a1, adev->bssid) + && mac_is_equal(hdr->a3, adev->bssid)) { + acx_l_transmit_assocresp(adev, &parsed.assocreq); + } + break; + case WF_FSTYPE_REASSOCREQi: + if (!ap) + break; + memset(&parsed.assocreq, 0, sizeof(parsed.assocreq)); + parsed.assocreq.hdr = hdr; + parsed.assocreq.len = len; + wlan_mgmt_decode_assocreq(&parsed.assocreq); + /* reassocreq and assocreq are equivalent */ + acx_l_transmit_reassocresp(adev, &parsed.reassocreq); + break; + case WF_FSTYPE_ASSOCRESPi: + if (!sta_scan) + break; + memset(&parsed.assocresp, 0, sizeof(parsed.assocresp)); + parsed.assocresp.hdr = hdr; + parsed.assocresp.len = len; + wlan_mgmt_decode_assocresp(&parsed.assocresp); + acx_l_process_assocresp(adev, &parsed.assocresp); + break; + case WF_FSTYPE_REASSOCRESPi: + if (!sta_scan) + break; + memset(&parsed.assocresp, 0, sizeof(parsed.assocresp)); + parsed.assocresp.hdr = hdr; + parsed.assocresp.len = len; + wlan_mgmt_decode_assocresp(&parsed.assocresp); + acx_l_process_reassocresp(adev, &parsed.reassocresp); + break; + case WF_FSTYPE_PROBEREQi: + if (ap || adhoc) { + /* FIXME: since we're supposed to be an AP, + ** we need to return a Probe Response packet. + ** Currently firmware is doing it for us, + ** but firmware is buggy! See comment elsewhere --vda */ + } + break; + case WF_FSTYPE_PROBERESPi: + memset(&parsed.proberesp, 0, sizeof(parsed.proberesp)); + parsed.proberesp.hdr = hdr; + parsed.proberesp.len = len; + wlan_mgmt_decode_proberesp(&parsed.proberesp); + acx_l_process_probe_response(adev, &parsed.proberesp, rxbuf); + break; + case 6: + case 7: + /* exit */ + break; + case WF_FSTYPE_ATIMi: + /* exit */ + break; + case WF_FSTYPE_DISASSOCi: + if (!sta && !ap) + break; + memset(&parsed.disassoc, 0, sizeof(parsed.disassoc)); + parsed.disassoc.hdr = hdr; + parsed.disassoc.len = len; + wlan_mgmt_decode_disassoc(&parsed.disassoc); + if (sta) + acx_l_process_disassoc_from_ap(adev, &parsed.disassoc); + else + acx_l_process_disassoc_from_sta(adev, &parsed.disassoc); + break; + case WF_FSTYPE_AUTHENi: + if (!sta_scan && !ap) + break; + memset(&parsed.authen, 0, sizeof(parsed.authen)); + parsed.authen.hdr = hdr; + parsed.authen.len = len; + wlan_mgmt_decode_authen(&parsed.authen); + acx_l_process_authen(adev, &parsed.authen); + break; + case WF_FSTYPE_DEAUTHENi: + if (!sta && !ap) + break; + memset(&parsed.deauthen, 0, sizeof(parsed.deauthen)); + parsed.deauthen.hdr = hdr; + parsed.deauthen.len = len; + wlan_mgmt_decode_deauthen(&parsed.deauthen); + if (sta) + acx_l_process_deauth_from_ap(adev, &parsed.deauthen); + else + acx_l_process_deauth_from_sta(adev, &parsed.deauthen); + break; + } + + FN_EXIT1(OK); + return OK; +} + + +#ifdef UNUSED +/*********************************************************************** +** acx_process_class_frame +** +** Called from IRQ context only +*/ +static int +acx_process_class_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala) +{ + return OK; +} +#endif + + +/*********************************************************************** +** acx_l_process_NULL_frame +*/ +#ifdef BOGUS_ITS_NOT_A_NULL_FRAME_HANDLER_AT_ALL +static int +acx_l_process_NULL_frame(acx_device_t *adev, rxbuffer_t *rxbuf, int vala) +{ + const signed char *esi; + const u8 *ebx; + const wlan_hdr_t *hdr; + const client_t *client; + int result = NOT_OK; + + hdr = acx_get_wlan_hdr(adev, rxbuf); + + switch (WF_FC_FROMTODSi & hdr->fc) { + case 0: + esi = hdr->a1; + ebx = hdr->a2; + break; + case WF_FC_FROMDSi: + esi = hdr->a1; + ebx = hdr->a3; + break; + case WF_FC_TODSi: + esi = hdr->a1; + ebx = hdr->a2; + break; + default: /* WF_FC_FROMTODSi */ + esi = hdr->a1; /* added by me! --vda */ + ebx = hdr->a2; + } + + if (esi[0x0] < 0) { + result = OK; + goto done; + } + + client = acx_l_sta_list_get(adev, ebx); + if (client) + result = NOT_OK; + else { +#ifdef IS_IT_BROKEN + log(L_DEBUG|L_XFER, "\n"); + acx_l_transmit_deauthen(adev, ebx, + WLAN_MGMT_REASON_CLASS2_NONAUTH); +#else + log(L_DEBUG, "received NULL frame from unknown client! " + "We really shouldn't send deauthen here, right?\n"); +#endif + result = OK; + } +done: + return result; +} +#endif + + +/*********************************************************************** +** acx_l_process_probe_response +*/ +static int +acx_l_process_probe_response(acx_device_t *adev, wlan_fr_proberesp_t *req, + const rxbuffer_t *rxbuf) +{ + struct client *bss; + wlan_hdr_t *hdr; + + FN_ENTER; + + hdr = req->hdr; + + if (mac_is_equal(hdr->a3, adev->dev_addr)) { + log(L_ASSOC, "huh, scan found our own MAC!?\n"); + goto ok; /* just skip this one silently */ + } + + bss = acx_l_sta_list_get_or_add(adev, hdr->a2); + + /* NB: be careful modifying bss data! It may be one + ** of the already known clients (like our AP if we are a STA) + ** Thus do not blindly modify e.g. current ratemask! */ + + if (STA_LIST_ADD_CAN_FAIL && !bss) { + /* uh oh, we found more sites/stations than we can handle with + * our current setup: pull the emergency brake and stop scanning! */ + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_STOP_SCAN); + /* TODO: a nice comment what below call achieves --vda */ + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); + goto ok; + } + /* NB: get_or_add already filled bss->address = hdr->a2 */ + MAC_COPY(bss->bssid, hdr->a3); + + /* copy the ESSID element */ + if (req->ssid && req->ssid->len <= IW_ESSID_MAX_SIZE) { + bss->essid_len = req->ssid->len; + memcpy(bss->essid, req->ssid->ssid, req->ssid->len); + bss->essid[req->ssid->len] = '\0'; + } else { + /* Either no ESSID IE or oversized one */ + printk("%s: received packet has bogus ESSID\n", + adev->ndev->name); + } + + if (req->ds_parms) + bss->channel = req->ds_parms->curr_ch; + if (req->cap_info) + bss->cap_info = ieee2host16(*req->cap_info); + + bss->sir = acx_signal_to_winlevel(rxbuf->phy_level); + bss->snr = acx_signal_to_winlevel(rxbuf->phy_snr); + + bss->rate_cap = 0; /* operational mask */ + bss->rate_bas = 0; /* basic mask */ + if (req->supp_rates) + add_bits_to_ratemasks(req->supp_rates->rates, + req->supp_rates->len, &bss->rate_bas, &bss->rate_cap); + if (req->ext_rates) + add_bits_to_ratemasks(req->ext_rates->rates, + req->ext_rates->len, &bss->rate_bas, &bss->rate_cap); + /* Fix up any possible bogosity - code elsewhere + * is not expecting empty masks */ + if (!bss->rate_cap) + bss->rate_cap = adev->rate_basic; + if (!bss->rate_bas) + bss->rate_bas = 1 << lowest_bit(bss->rate_cap); + if (!bss->rate_cur) + bss->rate_cur = 1 << lowest_bit(bss->rate_bas); + + /* People moan about this being too noisy at L_ASSOC */ + log(L_DEBUG, + "found %s: ESSID=\"%s\" ch=%d " + "BSSID="MACSTR" caps=0x%04X SIR=%d SNR=%d\n", + (bss->cap_info & WF_MGMT_CAP_IBSS) ? "Ad-Hoc peer" : "AP", + bss->essid, bss->channel, MAC(bss->bssid), bss->cap_info, + bss->sir, bss->snr); +ok: + FN_EXIT0; + return OK; +} + + +/*********************************************************************** +** acx_l_process_assocresp +*/ +static int +acx_l_process_assocresp(acx_device_t *adev, const wlan_fr_assocresp_t *req) +{ + const wlan_hdr_t *hdr; + int res = OK; + + FN_ENTER; + + hdr = req->hdr; + + if ((ACX_MODE_2_STA == adev->mode) + && mac_is_equal(adev->dev_addr, hdr->a1)) { + u16 st = ieee2host16(*(req->status)); + if (WLAN_MGMT_STATUS_SUCCESS == st) { + adev->aid = ieee2host16(*(req->aid)); + /* tell the card we are associated when + ** we are out of interrupt context */ + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_ASSOCIATE); + } else { + + /* TODO: we shall delete peer from sta_list, and try + ** other candidates... */ + + printk("%s: association FAILED: peer sent " + "Status Code %d (%s)\n", + adev->ndev->name, st, get_status_string(st)); + res = NOT_OK; + } + } + + FN_EXIT1(res); + return res; +} + + +/*********************************************************************** +** acx_l_process_reassocresp +*/ +static int +acx_l_process_reassocresp(acx_device_t *adev, const wlan_fr_reassocresp_t *req) +{ + const wlan_hdr_t *hdr; + int result = NOT_OK; + u16 st; + + FN_ENTER; + + hdr = req->hdr; + + if (!mac_is_equal(adev->dev_addr, hdr->a1)) { + goto end; + } + st = ieee2host16(*(req->status)); + if (st == WLAN_MGMT_STATUS_SUCCESS) { + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + result = OK; + } else { + printk("%s: reassociation FAILED: peer sent " + "response code %d (%s)\n", + adev->ndev->name, st, get_status_string(st)); + } +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_l_process_authen +** +** Called only in STA_SCAN or AP mode +*/ +static int +acx_l_process_authen(acx_device_t *adev, const wlan_fr_authen_t *req) +{ + const wlan_hdr_t *hdr; + client_t *clt; + wlan_ie_challenge_t *chal; + u16 alg, seq, status; + int ap, result; + + FN_ENTER; + + hdr = req->hdr; + + if (acx_debug & L_ASSOC) { + acx_print_mac("AUTHEN adev->addr=", adev->dev_addr, " "); + acx_print_mac("a1=", hdr->a1, " "); + acx_print_mac("a2=", hdr->a2, " "); + acx_print_mac("a3=", hdr->a3, " "); + acx_print_mac("adev->bssid=", adev->bssid, "\n"); + } + + if (!mac_is_equal(adev->dev_addr, hdr->a1) + || !mac_is_equal(adev->bssid, hdr->a3)) { + result = OK; + goto end; + } + + alg = ieee2host16(*(req->auth_alg)); + seq = ieee2host16(*(req->auth_seq)); + status = ieee2host16(*(req->status)); + + log(L_ASSOC, "auth algorithm %d, auth sequence %d, status %d\n", alg, seq, status); + + ap = (adev->mode == ACX_MODE_3_AP); + + if (adev->auth_alg <= 1) { + if (adev->auth_alg != alg) { + log(L_ASSOC, "auth algorithm mismatch: " + "our:%d peer:%d\n", adev->auth_alg, alg); + result = NOT_OK; + goto end; + } + } + if (ap) { + clt = acx_l_sta_list_get_or_add(adev, hdr->a2); + if (STA_LIST_ADD_CAN_FAIL && !clt) { + log(L_ASSOC, "could not allocate room for client\n"); + result = NOT_OK; + goto end; + } + } else { + clt = adev->ap_client; + if (!mac_is_equal(clt->address, hdr->a2)) { + printk("%s: malformed auth frame from AP?!\n", + adev->ndev->name); + result = NOT_OK; + goto end; + } + } + + /* now check which step in the authentication sequence we are + * currently in, and act accordingly */ + switch (seq) { + case 1: + if (!ap) + break; + acx_l_transmit_authen2(adev, req, clt); + break; + case 2: + if (ap) + break; + if (status == WLAN_MGMT_STATUS_SUCCESS) { + if (alg == WLAN_AUTH_ALG_OPENSYSTEM) { + acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED); + acx_l_transmit_assoc_req(adev); + } else + if (alg == WLAN_AUTH_ALG_SHAREDKEY) { + acx_l_transmit_authen3(adev, req); + } + } else { + printk("%s: auth FAILED: peer sent " + "response code %d (%s), " + "still waiting for authentication\n", + adev->ndev->name, + status, get_status_string(status)); + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); + } + break; + case 3: + if (!ap) + break; + if ((clt->auth_alg != WLAN_AUTH_ALG_SHAREDKEY) + || (alg != WLAN_AUTH_ALG_SHAREDKEY) + || (clt->auth_step != 2)) + break; + chal = req->challenge; + if (!chal + || memcmp(chal->challenge, clt->challenge_text, WLAN_CHALLENGE_LEN) + || (chal->eid != WLAN_EID_CHALLENGE) + || (chal->len != WLAN_CHALLENGE_LEN) + ) + break; + acx_l_transmit_authen4(adev, req); + MAC_COPY(clt->address, hdr->a2); + clt->used = CLIENT_AUTHENTICATED_2; + clt->auth_step = 4; + clt->seq = ieee2host16(hdr->seq); + break; + case 4: + if (ap) + break; + /* ok, we're through: we're authenticated. Woohoo!! */ + acx_set_status(adev, ACX_STATUS_3_AUTHENTICATED); + log(L_ASSOC, "Authenticated!\n"); + /* now that we're authenticated, request association */ + acx_l_transmit_assoc_req(adev); + break; + } + result = OK; +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_gen_challenge +*/ +static inline void +acx_gen_challenge(wlan_ie_challenge_t* d) +{ + FN_ENTER; + d->eid = WLAN_EID_CHALLENGE; + d->len = WLAN_CHALLENGE_LEN; + get_random_bytes(d->challenge, WLAN_CHALLENGE_LEN); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_l_transmit_deauthen +*/ +static int +acx_l_transmit_deauthen(acx_device_t *adev, const u8 *addr, u16 reason) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct deauthen_frame_body *body; + + FN_ENTER; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = (WF_FTYPE_MGMTi | WF_FSTYPE_DEAUTHENi); + head->dur = 0; + MAC_COPY(head->da, addr); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + head->seq = 0; + + log(L_DEBUG|L_ASSOC|L_XFER, + "sending deauthen to "MACSTR" for %d\n", + MAC(addr), reason); + + body->reason = host2ieee16(reason); + + /* body is fixed size here, but beware of cutting-and-pasting this - + ** do not use sizeof(*body) for variable sized mgmt packets! */ + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body)); + + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen1 +*/ +static int +acx_l_transmit_authen1(acx_device_t *adev) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + + FN_ENTER; + + log(L_ASSOC, "sending authentication1 request (auth algo %d), " + "awaiting response\n", adev->auth_alg); + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_AUTHENi; + /* duration should be 0 instead of 0x8000 to have + * the firmware calculate the value, right? */ + head->dur = 0; + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + head->seq = 0; + + body->auth_alg = host2ieee16(adev->auth_alg); + body->auth_seq = host2ieee16(1); + body->status = host2ieee16(0); + + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); + + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen2 +*/ +static int +acx_l_transmit_authen2(acx_device_t *adev, const wlan_fr_authen_t *req, + client_t *clt) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + unsigned int packet_len; + + FN_ENTER; + + if (!clt) + goto ok; + + MAC_COPY(clt->address, req->hdr->a2); +#ifdef UNUSED + clt->ps = ((WF_FC_PWRMGTi & req->hdr->fc) != 0); +#endif + clt->auth_alg = ieee2host16(*(req->auth_alg)); + clt->auth_step = 2; + clt->seq = ieee2host16(req->hdr->seq); + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_AUTHENi; + head->dur = 0 /* req->hdr->dur */; + MAC_COPY(head->da, req->hdr->a2); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, req->hdr->a3); + head->seq = 0 /* req->hdr->seq */; + + /* already in IEEE format, no endianness conversion */ + body->auth_alg = *(req->auth_alg); + body->auth_seq = host2ieee16(2); + body->status = host2ieee16(0); + + packet_len = WLAN_HDR_A3_LEN + 2 + 2 + 2; + if (ieee2host16(*(req->auth_alg)) == WLAN_AUTH_ALG_OPENSYSTEM) { + clt->used = CLIENT_AUTHENTICATED_2; + } else { /* shared key */ + acx_gen_challenge(&body->challenge); + memcpy(&clt->challenge_text, body->challenge.challenge, WLAN_CHALLENGE_LEN); + packet_len += 2 + 2 + 2 + 1+1+WLAN_CHALLENGE_LEN; + } + + acxlog_mac(L_ASSOC|L_XFER, + "transmit_auth2: BSSID=", head->bssid, "\n"); + + acx_l_tx_data(adev, tx, packet_len); +ok: + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen3 +*/ +static int +acx_l_transmit_authen3(acx_device_t *adev, const wlan_fr_authen_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + unsigned int packet_len; + + FN_ENTER; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto ok; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto ok; + } + body = (void*)(head + 1); + + /* add WF_FC_ISWEPi: auth step 3 needs to be encrypted */ + head->fc = WF_FC_ISWEPi + WF_FSTYPE_AUTHENi; + /* FIXME: is this needed?? authen4 does it... + * I think it's even wrong since we shouldn't re-use old + * values but instead let the firmware calculate proper ones + head->dur = req->hdr->dur; + head->seq = req->hdr->seq; + */ + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + + /* already in IEEE format, no endianness conversion */ + body->auth_alg = *(req->auth_alg); + body->auth_seq = host2ieee16(3); + body->status = host2ieee16(0); + memcpy(&body->challenge, req->challenge, req->challenge->len + 2); + packet_len = WLAN_HDR_A3_LEN + 8 + req->challenge->len; + + log(L_ASSOC|L_XFER, "transmit_authen3!\n"); + + acx_l_tx_data(adev, tx, packet_len); +ok: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_l_transmit_authen4 +*/ +static int +acx_l_transmit_authen4(acx_device_t *adev, const wlan_fr_authen_t *req) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct auth_frame_body *body; + + FN_ENTER; + + tx = acx_l_alloc_tx(adev); + if (!tx) + goto ok; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto ok; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_AUTHENi; /* 0xb0 */ + head->dur = 0 /* req->hdr->dur */; + MAC_COPY(head->da, req->hdr->a2); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, req->hdr->a3); + head->seq = 0 /* req->hdr->seq */; + + /* already in IEEE format, no endianness conversion */ + body->auth_alg = *(req->auth_alg); + body->auth_seq = host2ieee16(4); + body->status = host2ieee16(0); + + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + 2 + 2 + 2); +ok: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_l_transmit_assoc_req +** +** adev->ap_client is a current candidate AP here +*/ +static int +acx_l_transmit_assoc_req(acx_device_t *adev) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + u8 *body, *p, *prate; + unsigned int packet_len; + u16 cap; + + FN_ENTER; + + log(L_ASSOC, "sending association request, " + "awaiting response. NOT ASSOCIATED YET\n"); + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + + head->fc = WF_FSTYPE_ASSOCREQi; + head->dur = host2ieee16(0x8000); + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->bssid); + head->seq = 0; + + p = body; + /* now start filling the AssocReq frame body */ + + /* since this assoc request will most likely only get + * sent in the STA to AP case (and not when Ad-Hoc IBSS), + * the cap combination indicated here will thus be + * WF_MGMT_CAP_ESSi *always* (no IBSS ever) + * The specs are more than non-obvious on all that: + * + * 802.11 7.3.1.4 Capability Information field + ** APs set the ESS subfield to 1 and the IBSS subfield to 0 within + ** Beacon or Probe Response management frames. STAs within an IBSS + ** set the ESS subfield to 0 and the IBSS subfield to 1 in transmitted + ** Beacon or Probe Response management frames + ** + ** APs set the Privacy subfield to 1 within transmitted Beacon, + ** Probe Response, Association Response, and Reassociation Response + ** if WEP is required for all data type frames within the BSS. + ** STAs within an IBSS set the Privacy subfield to 1 in Beacon + ** or Probe Response management frames if WEP is required + ** for all data type frames within the IBSS */ + + /* note that returning 0 will be refused by several APs... + * (so this indicates that you're probably supposed to + * "confirm" the ESS mode) */ + cap = WF_MGMT_CAP_ESSi; + + /* this one used to be a check on wep_restricted, + * but more likely it's wep_enabled instead */ + if (adev->wep_enabled) + SET_BIT(cap, WF_MGMT_CAP_PRIVACYi); + + /* Probably we can just set these always, because our hw is + ** capable of shortpre and PBCC --vda */ + /* only ask for short preamble if the peer station supports it */ + if (adev->ap_client->cap_info & WF_MGMT_CAP_SHORT) + SET_BIT(cap, WF_MGMT_CAP_SHORTi); + /* only ask for PBCC support if the peer station supports it */ + if (adev->ap_client->cap_info & WF_MGMT_CAP_PBCC) + SET_BIT(cap, WF_MGMT_CAP_PBCCi); + + /* IEs: 1. caps */ + *(u16*)p = cap; p += 2; + /* 2. listen interval */ + *(u16*)p = host2ieee16(adev->listen_interval); p += 2; + /* 3. ESSID */ + p = wlan_fill_ie_ssid(p, + strlen(adev->essid_for_assoc), adev->essid_for_assoc); + /* 4. supp rates */ + prate = p; + p = wlan_fill_ie_rates(p, + adev->rate_supported_len, adev->rate_supported); + /* 5. ext supp rates */ + p = wlan_fill_ie_rates_ext(p, + adev->rate_supported_len, adev->rate_supported); + + if (acx_debug & L_DEBUG) { + printk("association: rates element\n"); + acx_dump_bytes(prate, p - prate); + } + + /* calculate lengths */ + packet_len = WLAN_HDR_A3_LEN + (p - body); + + log(L_ASSOC, "association: requesting caps 0x%04X, ESSID \"%s\"\n", + cap, adev->essid_for_assoc); + + acx_l_tx_data(adev, tx, packet_len); + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} + + +/*********************************************************************** +** acx_l_transmit_disassoc +** +** FIXME: looks like incomplete implementation of a helper: +** acx_l_transmit_disassoc(adev, clt) - kick this client (we're an AP) +** acx_l_transmit_disassoc(adev, NULL) - leave BSSID (we're a STA) +*/ +#ifdef BROKEN +int +acx_l_transmit_disassoc(acx_device_t *adev, client_t *clt) +{ + struct tx *tx; + struct wlan_hdr_mgmt *head; + struct disassoc_frame_body *body; + + FN_ENTER; +/* if (clt != NULL) { */ + tx = acx_l_alloc_tx(adev); + if (!tx) + goto bad; + head = acx_l_get_txbuf(adev, tx); + if (!head) { + acx_l_dealloc_tx(adev, tx); + goto bad; + } + body = (void*)(head + 1); + +/* clt->used = CLIENT_AUTHENTICATED_2; - not (yet?) associated */ + + head->fc = WF_FSTYPE_DISASSOCi; + head->dur = 0; + /* huh? It muchly depends on whether we're STA or AP... + ** sta->ap: da=bssid, sa=own, bssid=bssid + ** ap->sta: da=sta, sa=bssid, bssid=bssid. FIXME! */ + MAC_COPY(head->da, adev->bssid); + MAC_COPY(head->sa, adev->dev_addr); + MAC_COPY(head->bssid, adev->dev_addr); + head->seq = 0; + + /* "Class 3 frame received from nonassociated station." */ + body->reason = host2ieee16(7); + + /* fixed size struct, ok to sizeof */ + acx_l_tx_data(adev, tx, WLAN_HDR_A3_LEN + sizeof(*body)); +/* } */ + FN_EXIT1(OK); + return OK; +bad: + FN_EXIT1(NOT_OK); + return NOT_OK; +} +#endif + + +/*********************************************************************** +** acx_s_complete_scan +** +** Called either from after_interrupt_task() if: +** 1) there was Scan_Complete IRQ, or +** 2) scanning expired in timer() +** We need to decide which ESS or IBSS to join. +** Iterates thru adev->sta_list: +** if adev->ap is not bcast, will join only specified +** ESS or IBSS with this bssid +** checks peers' caps for ESS/IBSS bit +** checks peers' SSID, allows exact match or hidden SSID +** If station to join is chosen: +** points adev->ap_client to the chosen struct client +** sets adev->essid_for_assoc for future assoc attempt +** Auth/assoc is not yet performed +** Returns OK if there is no need to restart scan +*/ +int +acx_s_complete_scan(acx_device_t *adev) +{ + struct client *bss; + unsigned long flags; + u16 needed_cap; + int i; + int idx_found = -1; + int result = OK; + + FN_ENTER; + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + needed_cap = WF_MGMT_CAP_IBSS; /* 2, we require Ad-Hoc */ + break; + case ACX_MODE_2_STA: + needed_cap = WF_MGMT_CAP_ESS; /* 1, we require Managed */ + break; + default: + printk("acx: driver bug: mode=%d in complete_scan()\n", adev->mode); + dump_stack(); + goto end; + } + + acx_lock(adev, flags); + + /* TODO: sta_iterator hiding implementation would be nice here... */ + + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + bss = &adev->sta_list[i]; + if (!bss->used) continue; + + log(L_ASSOC, "scan table: SSID=\"%s\" CH=%d SIR=%d SNR=%d\n", + bss->essid, bss->channel, bss->sir, bss->snr); + + if (!mac_is_bcast(adev->ap)) + if (!mac_is_equal(bss->bssid, adev->ap)) + continue; /* keep looking */ + + /* broken peer with no mode flags set? */ + if (unlikely(!(bss->cap_info & (WF_MGMT_CAP_ESS | WF_MGMT_CAP_IBSS)))) { + printk("%s: strange peer "MACSTR" found with " + "neither ESS (AP) nor IBSS (Ad-Hoc) " + "capability - skipped\n", + adev->ndev->name, MAC(bss->address)); + continue; + } + log(L_ASSOC, "peer_cap 0x%04X, needed_cap 0x%04X\n", + bss->cap_info, needed_cap); + + /* does peer station support what we need? */ + if ((bss->cap_info & needed_cap) != needed_cap) + continue; /* keep looking */ + + /* strange peer with NO basic rates?! */ + if (unlikely(!bss->rate_bas)) { + printk("%s: strange peer "MACSTR" with empty rate set " + "- skipped\n", + adev->ndev->name, MAC(bss->address)); + continue; + } + + /* do we support all basic rates of this peer? */ + if ((bss->rate_bas & adev->rate_oper) != bss->rate_bas) { +/* we probably need to have all rates as operational rates, + even in case of an 11M-only configuration */ +#ifdef THIS_IS_TROUBLESOME + printk("%s: peer "MACSTR": incompatible basic rates " + "(AP requests 0x%04X, we have 0x%04X) " + "- skipped\n", + adev->ndev->name, MAC(bss->address), + bss->rate_bas, adev->rate_oper); + continue; +#else + printk("%s: peer "MACSTR": incompatible basic rates " + "(AP requests 0x%04X, we have 0x%04X). " + "Considering anyway...\n", + adev->ndev->name, MAC(bss->address), + bss->rate_bas, adev->rate_oper); +#endif + } + + if ( !(adev->reg_dom_chanmask & (1<<(bss->channel-1))) ) { + printk("%s: warning: peer "MACSTR" is on channel %d " + "outside of channel range of current " + "regulatory domain - couldn't join " + "even if other settings match. " + "You might want to adapt your config\n", + adev->ndev->name, MAC(bss->address), + bss->channel); + continue; /* keep looking */ + } + + if (!adev->essid_active || !strcmp(bss->essid, adev->essid)) { + log(L_ASSOC, + "found station with matching ESSID! ('%s' " + "station, '%s' config)\n", + bss->essid, + (adev->essid_active) ? adev->essid : "[any]"); + /* TODO: continue looking for peer with better SNR */ + bss->used = CLIENT_JOIN_CANDIDATE; + idx_found = i; + + /* stop searching if this station is + * on the current channel, otherwise + * keep looking for an even better match */ + if (bss->channel == adev->channel) + break; + } else + if (is_hidden_essid(bss->essid)) { + /* hmm, station with empty or single-space SSID: + * using hidden SSID broadcast? + */ + /* This behaviour is broken: which AP from zillion + ** of APs with hidden SSID you'd try? + ** We should use Probe requests to get Probe responses + ** and check for real SSID (are those never hidden?) */ + bss->used = CLIENT_JOIN_CANDIDATE; + if (idx_found == -1) + idx_found = i; + log(L_ASSOC, "found station with empty or " + "single-space (hidden) SSID, considering " + "for assoc attempt\n"); + /* ...and keep looking for better matches */ + } else { + log(L_ASSOC, "ESSID doesn't match! ('%s' " + "station, '%s' config)\n", + bss->essid, + (adev->essid_active) ? adev->essid : "[any]"); + } + } + + /* TODO: iterate thru join candidates instead */ + /* TODO: rescan if not associated within some timeout */ + if (idx_found != -1) { + char *essid_src; + size_t essid_len; + + bss = &adev->sta_list[idx_found]; + adev->ap_client = bss; + + if (is_hidden_essid(bss->essid)) { + /* if the ESSID of the station we found is empty + * (no broadcast), then use user-configured ESSID + * instead */ + essid_src = adev->essid; + essid_len = adev->essid_len; + } else { + essid_src = bss->essid; + essid_len = strlen(bss->essid); + } + + acx_update_capabilities(adev); + + memcpy(adev->essid_for_assoc, essid_src, essid_len); + adev->essid_for_assoc[essid_len] = '\0'; + adev->channel = bss->channel; + MAC_COPY(adev->bssid, bss->bssid); + + bss->rate_cfg = (bss->rate_cap & adev->rate_oper); + bss->rate_cur = 1 << lowest_bit(bss->rate_cfg); + bss->rate_100 = acx_rate111to100(bss->rate_cur); + + acxlog_mac(L_ASSOC, + "matching station found: ", adev->bssid, ", joining\n"); + + /* TODO: do we need to switch to the peer's channel first? */ + + if (ACX_MODE_0_ADHOC == adev->mode) { + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + } else { + acx_l_transmit_authen1(adev); + acx_set_status(adev, ACX_STATUS_2_WAIT_AUTH); + } + } else { /* idx_found == -1 */ + /* uh oh, no station found in range */ + if (ACX_MODE_0_ADHOC == adev->mode) { + printk("%s: no matching station found in range, " + "generating our own IBSS instead\n", + adev->ndev->name); + /* we do it the HostAP way: */ + MAC_COPY(adev->bssid, adev->dev_addr); + adev->bssid[0] |= 0x02; /* 'local assigned addr' bit */ + /* add IBSS bit to our caps... */ + acx_update_capabilities(adev); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + /* In order to cmd_join be called below */ + idx_found = 0; + } else { + /* we shall scan again, AP can be + ** just temporarily powered off */ + log(L_ASSOC, + "no matching station found in range yet\n"); + acx_set_status(adev, ACX_STATUS_1_SCANNING); + result = NOT_OK; + } + } + + acx_unlock(adev, flags); + + if (idx_found != -1) { + if (ACX_MODE_0_ADHOC == adev->mode) { + /* need to update channel in beacon template */ + SET_BIT(adev->set_mask, SET_TEMPLATES); + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + } + /* Inform firmware on our decision to start or join BSS */ + acx_s_cmd_join_bssid(adev, adev->bssid); + } + +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_read_fw +** +** Loads a firmware image +** +** Returns: +** 0 unable to load file +** pointer to firmware success +*/ +firmware_image_t* +acx_s_read_fw(struct device *dev, const char *file, u32 *size) +{ + firmware_image_t *res; + const struct firmware *fw_entry; + + res = NULL; + log(L_INIT, "requesting firmware image '%s'\n", file); + if (!request_firmware(&fw_entry, file, dev)) { + *size = 8; + if (fw_entry->size >= 8) + *size = 8 + le32_to_cpu(*(u32 *)(fw_entry->data + 4)); + if (fw_entry->size != *size) { + printk("acx: firmware size does not match " + "firmware header: %d != %d, " + "aborting fw upload\n", + (int) fw_entry->size, (int) *size); + goto release_ret; + } + res = vmalloc(*size); + if (!res) { + printk("acx: no memory for firmware " + "(%u bytes)\n", *size); + goto release_ret; + } + memcpy(res, fw_entry->data, fw_entry->size); +release_ret: + release_firmware(fw_entry); + return res; + } + printk("acx: firmware image '%s' was not provided. " + "Check your hotplug scripts\n", file); + + /* checksum will be verified in write_fw, so don't bother here */ + return res; +} + + +/*********************************************************************** +** acx_s_set_wepkey +*/ +static void +acx100_s_set_wepkey(acx_device_t *adev) +{ + ie_dot11WEPDefaultKey_t dk; + int i; + + for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) { + if (adev->wep_keys[i].size != 0) { + log(L_INIT, "setting WEP key: %d with " + "total size: %d\n", i, (int) adev->wep_keys[i].size); + dk.action = 1; + dk.keySize = adev->wep_keys[i].size; + dk.defaultKeyNum = i; + memcpy(dk.key, adev->wep_keys[i].key, dk.keySize); + acx_s_configure(adev, &dk, ACX100_IE_DOT11_WEP_DEFAULT_KEY_WRITE); + } + } +} + +static void +acx111_s_set_wepkey(acx_device_t *adev) +{ + acx111WEPDefaultKey_t dk; + int i; + + for (i = 0; i < DOT11_MAX_DEFAULT_WEP_KEYS; i++) { + if (adev->wep_keys[i].size != 0) { + log(L_INIT, "setting WEP key: %d with " + "total size: %d\n", i, (int) adev->wep_keys[i].size); + memset(&dk, 0, sizeof(dk)); + dk.action = cpu_to_le16(1); /* "add key"; yes, that's a 16bit value */ + dk.keySize = adev->wep_keys[i].size; + + /* are these two lines necessary? */ + dk.type = 0; /* default WEP key */ + dk.index = 0; /* ignored when setting default key */ + + dk.defaultKeyNum = i; + memcpy(dk.key, adev->wep_keys[i].key, dk.keySize); + acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &dk, sizeof(dk)); + } + } +} + +static void +acx_s_set_wepkey(acx_device_t *adev) +{ + if (IS_ACX111(adev)) + acx111_s_set_wepkey(adev); + else + acx100_s_set_wepkey(adev); +} + + +/*********************************************************************** +** acx100_s_init_wep +** +** FIXME: this should probably be moved into the new card settings +** management, but since we're also modifying the memory map layout here +** due to the WEP key space we want, we should take care... +*/ +static int +acx100_s_init_wep(acx_device_t *adev) +{ + acx100_ie_wep_options_t options; + ie_dot11WEPDefaultKeyID_t dk; + acx_ie_memmap_t pt; + int res = NOT_OK; + + FN_ENTER; + + if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + log(L_DEBUG, "CodeEnd:%X\n", pt.CodeEnd); + + pt.WEPCacheStart = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4); + pt.WEPCacheEnd = cpu_to_le32(le32_to_cpu(pt.CodeEnd) + 0x4); + + if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + goto fail; + } + + /* let's choose maximum setting: 4 default keys, plus 10 other keys: */ + options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10); + options.WEPOption = 0x00; + + log(L_ASSOC, "%s: writing WEP options\n", __func__); + acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS); + + acx100_s_set_wepkey(adev); + + if (adev->wep_keys[adev->wep_current_index].size != 0) { + log(L_ASSOC, "setting active default WEP key number: %d\n", + adev->wep_current_index); + dk.KeyID = adev->wep_current_index; + acx_s_configure(adev, &dk, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); /* 0x1010 */ + } + /* FIXME!!! wep_key_struct is filled nowhere! But adev + * is initialized to 0, and we don't REALLY need those keys either */ +/* for (i = 0; i < 10; i++) { + if (adev->wep_key_struct[i].len != 0) { + MAC_COPY(wep_mgmt.MacAddr, adev->wep_key_struct[i].addr); + wep_mgmt.KeySize = cpu_to_le16(adev->wep_key_struct[i].len); + memcpy(&wep_mgmt.Key, adev->wep_key_struct[i].key, le16_to_cpu(wep_mgmt.KeySize)); + wep_mgmt.Action = cpu_to_le16(1); + log(L_ASSOC, "writing WEP key %d (len %d)\n", i, le16_to_cpu(wep_mgmt.KeySize)); + if (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_WEP_MGMT, &wep_mgmt, sizeof(wep_mgmt))) { + adev->wep_key_struct[i].index = i; + } + } + } +*/ + + /* now retrieve the updated WEPCacheEnd pointer... */ + if (OK != acx_s_interrogate(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + printk("%s: ACX1xx_IE_MEMORY_MAP read #2 FAILED\n", + adev->ndev->name); + goto fail; + } + /* ...and tell it to start allocating templates at that location */ + /* (no endianness conversion needed) */ + pt.PacketTemplateStart = pt.WEPCacheEnd; + + if (OK != acx_s_configure(adev, &pt, ACX1xx_IE_MEMORY_MAP)) { + printk("%s: ACX1xx_IE_MEMORY_MAP write #2 FAILED\n", + adev->ndev->name); + goto fail; + } + res = OK; + +fail: + FN_EXIT1(res); + return res; +} + + +static int +acx_s_init_max_template_generic(acx_device_t *adev, unsigned int len, unsigned int cmd) +{ + int res; + union { + acx_template_nullframe_t null; + acx_template_beacon_t b; + acx_template_tim_t tim; + acx_template_probereq_t preq; + acx_template_proberesp_t presp; + } templ; + + memset(&templ, 0, len); + templ.null.size = cpu_to_le16(len - 2); + res = acx_s_issue_cmd(adev, cmd, &templ, len); + return res; +} + +static inline int +acx_s_init_max_null_data_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_nullframe_t), ACX1xx_CMD_CONFIG_NULL_DATA + ); +} + +static inline int +acx_s_init_max_beacon_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_beacon_t), ACX1xx_CMD_CONFIG_BEACON + ); +} + +static inline int +acx_s_init_max_tim_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_tim_t), ACX1xx_CMD_CONFIG_TIM + ); +} + +static inline int +acx_s_init_max_probe_response_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_proberesp_t), ACX1xx_CMD_CONFIG_PROBE_RESPONSE + ); +} + +static inline int +acx_s_init_max_probe_request_template(acx_device_t *adev) +{ + return acx_s_init_max_template_generic( + adev, sizeof(acx_template_probereq_t), ACX1xx_CMD_CONFIG_PROBE_REQUEST + ); +} + +/*********************************************************************** +** acx_s_set_tim_template +** +** FIXME: In full blown driver we will regularly update partial virtual bitmap +** by calling this function +** (it can be done by irq handler on each DTIM irq or by timer...) + +[802.11 7.3.2.6] TIM information element: +- 1 EID +- 1 Length +1 1 DTIM Count + indicates how many beacons (including this) appear before next DTIM + (0=this one is a DTIM) +2 1 DTIM Period + number of beacons between successive DTIMs + (0=reserved, 1=all TIMs are DTIMs, 2=every other, etc) +3 1 Bitmap Control + bit0: Traffic Indicator bit associated with Assoc ID 0 (Bcast AID?) + set to 1 in TIM elements with a value of 0 in the DTIM Count field + when one or more broadcast or multicast frames are buffered at the AP. + bit1-7: Bitmap Offset (logically Bitmap_Offset = Bitmap_Control & 0xFE). +4 n Partial Virtual Bitmap + Visible part of traffic-indication bitmap. + Full bitmap consists of 2008 bits (251 octets) such that bit number N + (0<=N<=2007) in the bitmap corresponds to bit number (N mod 8) + in octet number N/8 where the low-order bit of each octet is bit0, + and the high order bit is bit7. + Each set bit in virtual bitmap corresponds to traffic buffered by AP + for a specific station (with corresponding AID?). + Partial Virtual Bitmap shows a part of bitmap which has non-zero. + Bitmap Offset is a number of skipped zero octets (see above). + 'Missing' octets at the tail are also assumed to be zero. + Example: Length=6, Bitmap_Offset=2, Partial_Virtual_Bitmap=55 55 55 + This means that traffic-indication bitmap is: + 00000000 00000000 01010101 01010101 01010101 00000000 00000000... + (is bit0 in the map is always 0 and real value is in Bitmap Control bit0?) +*/ +static int +acx_s_set_tim_template(acx_device_t *adev) +{ +/* For now, configure smallish test bitmap, all zero ("no pending data") */ + enum { bitmap_size = 5 }; + + acx_template_tim_t t; + int result; + + FN_ENTER; + + memset(&t, 0, sizeof(t)); + t.size = 5 + bitmap_size; /* eid+len+count+period+bmap_ctrl + bmap */ + t.tim_eid = WLAN_EID_TIM; + t.len = 3 + bitmap_size; /* count+period+bmap_ctrl + bmap */ + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_TIM, &t, sizeof(t)); + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_fill_beacon_or_proberesp_template +** +** For frame format info, please see 802.11-1999.pdf item 7.2.3.9 and below!! +** +** NB: we use the fact that +** struct acx_template_proberesp and struct acx_template_beacon are the same +** (well, almost...) +** +** [802.11] Beacon's body consist of these IEs: +** 1 Timestamp +** 2 Beacon interval +** 3 Capability information +** 4 SSID +** 5 Supported rates (up to 8 rates) +** 6 FH Parameter Set (frequency-hopping PHYs only) +** 7 DS Parameter Set (direct sequence PHYs only) +** 8 CF Parameter Set (only if PCF is supported) +** 9 IBSS Parameter Set (ad-hoc only) +** +** Beacon only: +** 10 TIM (AP only) (see 802.11 7.3.2.6) +** 11 Country Information (802.11d) +** 12 FH Parameters (802.11d) +** 13 FH Pattern Table (802.11d) +** ... (?!! did not yet find relevant PDF file... --vda) +** 19 ERP Information (extended rate PHYs) +** 20 Extended Supported Rates (if more than 8 rates) +** +** Proberesp only: +** 10 Country information (802.11d) +** 11 FH Parameters (802.11d) +** 12 FH Pattern Table (802.11d) +** 13-n Requested information elements (802.11d) +** ???? +** 18 ERP Information (extended rate PHYs) +** 19 Extended Supported Rates (if more than 8 rates) +*/ +static int +acx_fill_beacon_or_proberesp_template(acx_device_t *adev, + struct acx_template_beacon *templ, + u16 fc /* in host order! */) +{ + int len; + u8 *p; + + FN_ENTER; + + memset(templ, 0, sizeof(*templ)); + MAC_BCAST(templ->da); + MAC_COPY(templ->sa, adev->dev_addr); + MAC_COPY(templ->bssid, adev->bssid); + + templ->beacon_interval = cpu_to_le16(adev->beacon_interval); + acx_update_capabilities(adev); + templ->cap = cpu_to_le16(adev->capabilities); + + p = templ->variable; + p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid); + p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported); + p = wlan_fill_ie_ds_parms(p, adev->channel); + /* NB: should go AFTER tim, but acx seem to keep tim last always */ + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported); + + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + /* ATIM window */ + p = wlan_fill_ie_ibss_parms(p, 0); break; + case ACX_MODE_3_AP: + /* TIM IE is set up as separate template */ + break; + } + + len = p - (u8*)templ; + templ->fc = cpu_to_le16(WF_FTYPE_MGMT | fc); + /* - 2: do not count 'u16 size' field */ + templ->size = cpu_to_le16(len - 2); + + FN_EXIT1(len); + return len; +} + + +#if POWER_SAVE_80211 +/*********************************************************************** +** acx_s_set_null_data_template +*/ +static int +acx_s_set_null_data_template(acx_device_t *adev) +{ + struct acx_template_nullframe b; + int result; + + FN_ENTER; + + /* memset(&b, 0, sizeof(b)); not needed, setting all members */ + + b.size = cpu_to_le16(sizeof(b) - 2); + b.hdr.fc = WF_FTYPE_MGMTi | WF_FSTYPE_NULLi; + b.hdr.dur = 0; + MAC_BCAST(b.hdr.a1); + MAC_COPY(b.hdr.a2, adev->dev_addr); + MAC_COPY(b.hdr.a3, adev->bssid); + b.hdr.seq = 0; + + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_NULL_DATA, &b, sizeof(b)); + + FN_EXIT1(result); + return result; +} +#endif + + +/*********************************************************************** +** acx_s_set_beacon_template +*/ +static int +acx_s_set_beacon_template(acx_device_t *adev) +{ + struct acx_template_beacon bcn; + int len, result; + + FN_ENTER; + + len = acx_fill_beacon_or_proberesp_template(adev, &bcn, WF_FSTYPE_BEACON); + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_BEACON, &bcn, len); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_set_probe_response_template +*/ +static int +acx_s_set_probe_response_template(acx_device_t *adev) +{ + struct acx_template_proberesp pr; + int len, result; + + FN_ENTER; + + len = acx_fill_beacon_or_proberesp_template(adev, &pr, WF_FSTYPE_PROBERESP); + result = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_RESPONSE, &pr, len); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_init_packet_templates() +** +** NOTE: order is very important here, to have a correct memory layout! +** init templates: max Probe Request (station mode), max NULL data, +** max Beacon, max TIM, max Probe Response. +*/ +static int +acx_s_init_packet_templates(acx_device_t *adev) +{ + acx_ie_memmap_t mm; /* ACX100 only */ + int result = NOT_OK; + + FN_ENTER; + + log(L_DEBUG|L_INIT, "initializing max packet templates\n"); + + if (OK != acx_s_init_max_probe_request_template(adev)) + goto failed; + + if (OK != acx_s_init_max_null_data_template(adev)) + goto failed; + + if (OK != acx_s_init_max_beacon_template(adev)) + goto failed; + + if (OK != acx_s_init_max_tim_template(adev)) + goto failed; + + if (OK != acx_s_init_max_probe_response_template(adev)) + goto failed; + + if (IS_ACX111(adev)) { + /* ACX111 doesn't need the memory map magic below, + * and the other templates will be set later (acx_start) */ + result = OK; + goto success; + } + + /* ACX100 will have its TIM template set, + * and we also need to update the memory map */ + + if (OK != acx_s_set_tim_template(adev)) + goto failed_acx100; + + log(L_DEBUG, "sizeof(memmap)=%d bytes\n", (int)sizeof(mm)); + + if (OK != acx_s_interrogate(adev, &mm, ACX1xx_IE_MEMORY_MAP)) + goto failed_acx100; + + mm.QueueStart = cpu_to_le32(le32_to_cpu(mm.PacketTemplateEnd) + 4); + if (OK != acx_s_configure(adev, &mm, ACX1xx_IE_MEMORY_MAP)) + goto failed_acx100; + + result = OK; + goto success; + +failed_acx100: + log(L_DEBUG|L_INIT, + /* "cb=0x%X\n" */ + "ACXMemoryMap:\n" + ".CodeStart=0x%X\n" + ".CodeEnd=0x%X\n" + ".WEPCacheStart=0x%X\n" + ".WEPCacheEnd=0x%X\n" + ".PacketTemplateStart=0x%X\n" + ".PacketTemplateEnd=0x%X\n", + /* len, */ + le32_to_cpu(mm.CodeStart), + le32_to_cpu(mm.CodeEnd), + le32_to_cpu(mm.WEPCacheStart), + le32_to_cpu(mm.WEPCacheEnd), + le32_to_cpu(mm.PacketTemplateStart), + le32_to_cpu(mm.PacketTemplateEnd)); + +failed: + printk("%s: %s() FAILED\n", adev->ndev->name, __func__); + +success: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_s_set_probe_request_template(acx_device_t *adev) +{ + struct acx_template_probereq probereq; + char *p; + int res; + int frame_len; + + FN_ENTER; + + memset(&probereq, 0, sizeof(probereq)); + + probereq.fc = WF_FTYPE_MGMTi | WF_FSTYPE_PROBEREQi; + MAC_BCAST(probereq.da); + MAC_COPY(probereq.sa, adev->dev_addr); + MAC_BCAST(probereq.bssid); + + p = probereq.variable; + p = wlan_fill_ie_ssid(p, adev->essid_len, adev->essid); + p = wlan_fill_ie_rates(p, adev->rate_supported_len, adev->rate_supported); + p = wlan_fill_ie_rates_ext(p, adev->rate_supported_len, adev->rate_supported); + frame_len = p - (char*)&probereq; + probereq.size = cpu_to_le16(frame_len - 2); + + res = acx_s_issue_cmd(adev, ACX1xx_CMD_CONFIG_PROBE_REQUEST, &probereq, frame_len); + FN_EXIT0; + return res; +} + + +/*********************************************************************** +** acx_s_init_mac +*/ +int +acx_s_init_mac(acx_device_t *adev) +{ + int result = NOT_OK; + + FN_ENTER; + + if (IS_ACX111(adev)) { + adev->ie_len = acx111_ie_len; + adev->ie_len_dot11 = acx111_ie_len_dot11; + } else { + adev->ie_len = acx100_ie_len; + adev->ie_len_dot11 = acx100_ie_len_dot11; + } + + if (IS_PCI(adev)) { + adev->memblocksize = 256; /* 256 is default */ + /* try to load radio for both ACX100 and ACX111, since both + * chips have at least some firmware versions making use of an + * external radio module */ + acxpci_s_upload_radio(adev); + } else { + adev->memblocksize = 128; + } + + if (IS_ACX111(adev)) { + /* for ACX111, the order is different from ACX100 + 1. init packet templates + 2. create station context and create dma regions + 3. init wep default keys + */ + if (OK != acx_s_init_packet_templates(adev)) + goto fail; + if (OK != acx111_s_create_dma_regions(adev)) { + printk("%s: acx111_create_dma_regions FAILED\n", + adev->ndev->name); + goto fail; + } + } else { + if (OK != acx100_s_init_wep(adev)) + goto fail; + if (OK != acx_s_init_packet_templates(adev)) + goto fail; + if (OK != acx100_s_create_dma_regions(adev)) { + printk("%s: acx100_create_dma_regions FAILED\n", + adev->ndev->name); + goto fail; + } + } + + MAC_COPY(adev->ndev->dev_addr, adev->dev_addr); + result = OK; + +fail: + if (result) + printk("acx: init_mac() FAILED\n"); + FN_EXIT1(result); + return result; +} + + +void +acx_s_set_sane_reg_domain(acx_device_t *adev, int do_set) +{ + unsigned mask; + + unsigned int i; + + for (i = 0; i < sizeof(acx_reg_domain_ids); i++) + if (acx_reg_domain_ids[i] == adev->reg_dom_id) + break; + + if (sizeof(acx_reg_domain_ids) == i) { + log(L_INIT, "Invalid or unsupported regulatory domain" + " 0x%02X specified, falling back to FCC (USA)!" + " Please report if this sounds fishy!\n", + adev->reg_dom_id); + i = 0; + adev->reg_dom_id = acx_reg_domain_ids[i]; + + /* since there was a mismatch, we need to force updating */ + do_set = 1; + } + + if (do_set) { + acx_ie_generic_t dom; + dom.m.bytes[0] = adev->reg_dom_id; + acx_s_configure(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); + } + + adev->reg_dom_chanmask = reg_domain_channel_masks[i]; + + mask = (1 << (adev->channel - 1)); + if (!(adev->reg_dom_chanmask & mask)) { + /* hmm, need to adjust our channel to reside within domain */ + mask = 1; + for (i = 1; i <= 14; i++) { + if (adev->reg_dom_chanmask & mask) { + printk("%s: adjusting selected channel from %d " + "to %d due to new regulatory domain\n", + adev->ndev->name, adev->channel, i); + adev->channel = i; + break; + } + mask <<= 1; + } + } +} + + +#if POWER_SAVE_80211 +static void +acx_s_update_80211_powersave_mode(acx_device_t *adev) +{ + /* merge both structs in a union to be able to have common code */ + union { + acx111_ie_powersave_t acx111; + acx100_ie_powersave_t acx100; + } pm; + + /* change 802.11 power save mode settings */ + log(L_INIT, "updating 802.11 power save mode settings: " + "wakeup_cfg 0x%02X, listen interval %u, " + "options 0x%02X, hangover period %u, " + "enhanced_ps_transition_time %u\n", + adev->ps_wakeup_cfg, adev->ps_listen_interval, + adev->ps_options, adev->ps_hangover_period, + adev->ps_enhanced_transition_time); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "Previous PS mode settings: wakeup_cfg 0x%02X, " + "listen interval %u, options 0x%02X, " + "hangover period %u, " + "enhanced_ps_transition_time %u, beacon_rx_time %u\n", + pm.acx111.wakeup_cfg, + pm.acx111.listen_interval, + pm.acx111.options, + pm.acx111.hangover_period, + IS_ACX111(adev) ? + pm.acx111.enhanced_ps_transition_time + : pm.acx100.enhanced_ps_transition_time, + IS_ACX111(adev) ? + pm.acx111.beacon_rx_time + : (u32)-1 + ); + pm.acx111.wakeup_cfg = adev->ps_wakeup_cfg; + pm.acx111.listen_interval = adev->ps_listen_interval; + pm.acx111.options = adev->ps_options; + pm.acx111.hangover_period = adev->ps_hangover_period; + if (IS_ACX111(adev)) { + pm.acx111.beacon_rx_time = cpu_to_le32(adev->ps_beacon_rx_time); + pm.acx111.enhanced_ps_transition_time = cpu_to_le32(adev->ps_enhanced_transition_time); + } else { + pm.acx100.enhanced_ps_transition_time = cpu_to_le16(adev->ps_enhanced_transition_time); + } + acx_s_configure(adev, &pm, ACX1xx_IE_POWER_MGMT); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg); + acx_s_msleep(40); + acx_s_interrogate(adev, &pm, ACX1xx_IE_POWER_MGMT); + log(L_INIT, "wakeup_cfg: 0x%02X\n", pm.acx111.wakeup_cfg); + log(L_INIT, "power save mode change %s\n", + (pm.acx111.wakeup_cfg & PS_CFG_PENDING) ? "FAILED" : "was successful"); + /* FIXME: maybe verify via PS_CFG_PENDING bit here + * that power save mode change was successful. */ + /* FIXME: we shouldn't trigger a scan immediately after + * fiddling with power save mode (since the firmware is sending + * a NULL frame then). */ +} +#endif + + +/*********************************************************************** +** acx_s_update_card_settings +** +** Applies accumulated changes in various adev->xxxx members +** Called by ioctl commit handler, acx_start, acx_set_defaults, +** acx_s_after_interrupt_task (if IRQ_CMD_UPDATE_CARD_CFG), +*/ +static void +acx111_s_sens_radio_16_17(acx_device_t *adev) +{ + u32 feature1, feature2; + + if ((adev->sensitivity < 1) || (adev->sensitivity > 3)) { + printk("%s: invalid sensitivity setting (1..3), " + "setting to 1\n", adev->ndev->name); + adev->sensitivity = 1; + } + acx111_s_get_feature_config(adev, &feature1, &feature2); + CLEAR_BIT(feature1, FEATURE1_LOW_RX|FEATURE1_EXTRA_LOW_RX); + if (adev->sensitivity > 1) + SET_BIT(feature1, FEATURE1_LOW_RX); + if (adev->sensitivity > 2) + SET_BIT(feature1, FEATURE1_EXTRA_LOW_RX); + acx111_s_feature_set(adev, feature1, feature2); +} + + +void +acx_s_update_card_settings(acx_device_t *adev) +{ + unsigned long flags; + unsigned int start_scan = 0; + int i; + + FN_ENTER; + + log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X\n", + adev->get_mask, adev->set_mask); + + /* Track dependencies betweed various settings */ + + if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_WEP)) { + log(L_INIT, "important setting has been changed. " + "Need to update packet templates, too\n"); + SET_BIT(adev->set_mask, SET_TEMPLATES); + } + if (adev->set_mask & GETSET_CHANNEL) { + /* This will actually tune RX/TX to the channel */ + SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + /* Beacons contain channel# - update them */ + SET_BIT(adev->set_mask, SET_TEMPLATES); + } + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + start_scan = 1; + } + } + + /* Apply settings */ + +#ifdef WHY_SHOULD_WE_BOTHER /* imagine we were just powered off */ + /* send a disassoc request in case it's required */ + if (adev->set_mask & (GETSET_MODE|GETSET_RESCAN|GETSET_CHANNEL|GETSET_WEP)) { + if (ACX_MODE_2_STA == adev->mode) { + if (ACX_STATUS_4_ASSOCIATED == adev->status) { + log(L_ASSOC, "we were ASSOCIATED - " + "sending disassoc request\n"); + acx_lock(adev, flags); + acx_l_transmit_disassoc(adev, NULL); + /* FIXME: deauth? */ + acx_unlock(adev, flags); + } + /* need to reset some other stuff as well */ + log(L_DEBUG, "resetting bssid\n"); + MAC_ZERO(adev->bssid); + SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST); + start_scan = 1; + } + } +#endif + + if (adev->get_mask & GETSET_STATION_ID) { + u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN]; + const u8 *paddr; + + acx_s_interrogate(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID); + paddr = &stationID[4]; + for (i = 0; i < ETH_ALEN; i++) { + /* we copy the MAC address (reversed in + * the card) to the netdevice's MAC + * address, and on ifup it will be + * copied into iwadev->dev_addr */ + adev->ndev->dev_addr[ETH_ALEN - 1 - i] = paddr[i]; + } + CLEAR_BIT(adev->get_mask, GETSET_STATION_ID); + } + + if (adev->get_mask & GETSET_SENSITIVITY) { + if ((RADIO_RFMD_11 == adev->radio_type) + || (RADIO_MAXIM_0D == adev->radio_type) + || (RADIO_RALINK_15 == adev->radio_type)) { + acx_s_read_phy_reg(adev, 0x30, &adev->sensitivity); + } else { + log(L_INIT, "don't know how to get sensitivity " + "for radio type 0x%02X\n", adev->radio_type); + adev->sensitivity = 0; + } + log(L_INIT, "got sensitivity value %u\n", adev->sensitivity); + + CLEAR_BIT(adev->get_mask, GETSET_SENSITIVITY); + } + + if (adev->get_mask & GETSET_ANTENNA) { + u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN]; + + memset(antenna, 0, sizeof(antenna)); + acx_s_interrogate(adev, antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); + adev->antenna = antenna[4]; + log(L_INIT, "got antenna value 0x%02X\n", adev->antenna); + CLEAR_BIT(adev->get_mask, GETSET_ANTENNA); + } + + if (adev->get_mask & GETSET_ED_THRESH) { + if (IS_ACX100(adev)) { + u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN]; + + memset(ed_threshold, 0, sizeof(ed_threshold)); + acx_s_interrogate(adev, ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); + adev->ed_threshold = ed_threshold[4]; + } else { + log(L_INIT, "acx111 doesn't support ED\n"); + adev->ed_threshold = 0; + } + log(L_INIT, "got Energy Detect (ED) threshold %u\n", adev->ed_threshold); + CLEAR_BIT(adev->get_mask, GETSET_ED_THRESH); + } + + if (adev->get_mask & GETSET_CCA) { + if (IS_ACX100(adev)) { + u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN]; + + memset(cca, 0, sizeof(adev->cca)); + acx_s_interrogate(adev, cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); + adev->cca = cca[4]; + } else { + log(L_INIT, "acx111 doesn't support CCA\n"); + adev->cca = 0; + } + log(L_INIT, "got Channel Clear Assessment (CCA) value %u\n", adev->cca); + CLEAR_BIT(adev->get_mask, GETSET_CCA); + } + + if (adev->get_mask & GETSET_REG_DOMAIN) { + acx_ie_generic_t dom; + + acx_s_interrogate(adev, &dom, ACX1xx_IE_DOT11_CURRENT_REG_DOMAIN); + adev->reg_dom_id = dom.m.bytes[0]; + acx_s_set_sane_reg_domain(adev, 0); + log(L_INIT, "got regulatory domain 0x%02X\n", adev->reg_dom_id); + CLEAR_BIT(adev->get_mask, GETSET_REG_DOMAIN); + } + + if (adev->set_mask & GETSET_STATION_ID) { + u8 stationID[4 + ACX1xx_IE_DOT11_STATION_ID_LEN]; + u8 *paddr; + + paddr = &stationID[4]; + memcpy(adev->dev_addr, adev->ndev->dev_addr, ETH_ALEN); + for (i = 0; i < ETH_ALEN; i++) { + /* copy the MAC address we obtained when we noticed + * that the ethernet iface's MAC changed + * to the card (reversed in + * the card!) */ + paddr[i] = adev->dev_addr[ETH_ALEN - 1 - i]; + } + acx_s_configure(adev, &stationID, ACX1xx_IE_DOT11_STATION_ID); + CLEAR_BIT(adev->set_mask, GETSET_STATION_ID); + } + + if (adev->set_mask & SET_TEMPLATES) { + log(L_INIT, "updating packet templates\n"); + switch (adev->mode) { + case ACX_MODE_2_STA: + acx_s_set_probe_request_template(adev); +#if POWER_SAVE_80211 + acx_s_set_null_data_template(adev); +#endif + break; + case ACX_MODE_0_ADHOC: + acx_s_set_probe_request_template(adev); +#if POWER_SAVE_80211 + /* maybe power save functionality is somehow possible + * for Ad-Hoc mode, too... FIXME: verify it somehow? firmware debug fields? */ + acx_s_set_null_data_template(adev); +#endif + /* fall through */ + case ACX_MODE_3_AP: + acx_s_set_beacon_template(adev); + acx_s_set_tim_template(adev); + /* BTW acx111 firmware would not send probe responses + ** if probe request does not have all basic rates flagged + ** by 0x80! Thus firmware does not conform to 802.11, + ** it should ignore 0x80 bit in ratevector from STA. + ** We can 'fix' it by not using this template and + ** sending probe responses by hand. TODO --vda */ + acx_s_set_probe_response_template(adev); + } + /* Needed if generated frames are to be emitted at different tx rate now */ + log(L_IRQ, "redoing cmd_join_bssid() after template cfg\n"); + acx_s_cmd_join_bssid(adev, adev->bssid); + CLEAR_BIT(adev->set_mask, SET_TEMPLATES); + } + if (adev->set_mask & SET_STA_LIST) { + acx_lock(adev, flags); + acx_l_sta_list_init(adev); + CLEAR_BIT(adev->set_mask, SET_STA_LIST); + acx_unlock(adev, flags); + } + if (adev->set_mask & SET_RATE_FALLBACK) { + u8 rate[4 + ACX1xx_IE_RATE_FALLBACK_LEN]; + + /* configure to not do fallbacks when not in auto rate mode */ + rate[4] = (adev->rate_auto) ? /* adev->txrate_fallback_retries */ 1 : 0; + log(L_INIT, "updating Tx fallback to %u retries\n", rate[4]); + acx_s_configure(adev, &rate, ACX1xx_IE_RATE_FALLBACK); + CLEAR_BIT(adev->set_mask, SET_RATE_FALLBACK); + } + if (adev->set_mask & GETSET_TXPOWER) { + log(L_INIT, "updating transmit power: %u dBm\n", + adev->tx_level_dbm); + acx_s_set_tx_level(adev, adev->tx_level_dbm); + CLEAR_BIT(adev->set_mask, GETSET_TXPOWER); + } + + if (adev->set_mask & GETSET_SENSITIVITY) { + log(L_INIT, "updating sensitivity value: %u\n", + adev->sensitivity); + switch (adev->radio_type) { + case RADIO_RFMD_11: + case RADIO_MAXIM_0D: + case RADIO_RALINK_15: + acx_s_write_phy_reg(adev, 0x30, adev->sensitivity); + break; + case RADIO_RADIA_16: + case RADIO_UNKNOWN_17: + acx111_s_sens_radio_16_17(adev); + break; + default: + log(L_INIT, "don't know how to modify sensitivity " + "for radio type 0x%02X\n", adev->radio_type); + } + CLEAR_BIT(adev->set_mask, GETSET_SENSITIVITY); + } + + if (adev->set_mask & GETSET_ANTENNA) { + /* antenna */ + u8 antenna[4 + ACX1xx_IE_DOT11_CURRENT_ANTENNA_LEN]; + + memset(antenna, 0, sizeof(antenna)); + antenna[4] = adev->antenna; + log(L_INIT, "updating antenna value: 0x%02X\n", + adev->antenna); + acx_s_configure(adev, &antenna, ACX1xx_IE_DOT11_CURRENT_ANTENNA); + CLEAR_BIT(adev->set_mask, GETSET_ANTENNA); + } + + if (adev->set_mask & GETSET_ED_THRESH) { + /* ed_threshold */ + log(L_INIT, "updating Energy Detect (ED) threshold: %u\n", + adev->ed_threshold); + if (IS_ACX100(adev)) { + u8 ed_threshold[4 + ACX100_IE_DOT11_ED_THRESHOLD_LEN]; + + memset(ed_threshold, 0, sizeof(ed_threshold)); + ed_threshold[4] = adev->ed_threshold; + acx_s_configure(adev, &ed_threshold, ACX100_IE_DOT11_ED_THRESHOLD); + } + else + log(L_INIT, "acx111 doesn't support ED!\n"); + CLEAR_BIT(adev->set_mask, GETSET_ED_THRESH); + } + + if (adev->set_mask & GETSET_CCA) { + /* CCA value */ + log(L_INIT, "updating Channel Clear Assessment " + "(CCA) value: 0x%02X\n", adev->cca); + if (IS_ACX100(adev)) { + u8 cca[4 + ACX1xx_IE_DOT11_CURRENT_CCA_MODE_LEN]; + + memset(cca, 0, sizeof(cca)); + cca[4] = adev->cca; + acx_s_configure(adev, &cca, ACX1xx_IE_DOT11_CURRENT_CCA_MODE); + } + else + log(L_INIT, "acx111 doesn't support CCA!\n"); + CLEAR_BIT(adev->set_mask, GETSET_CCA); + } + + if (adev->set_mask & GETSET_LED_POWER) { + /* Enable Tx */ + log(L_INIT, "updating power LED status: %u\n", adev->led_power); + + acx_lock(adev, flags); + if (IS_PCI(adev)) + acxpci_l_power_led(adev, adev->led_power); + CLEAR_BIT(adev->set_mask, GETSET_LED_POWER); + acx_unlock(adev, flags); + } + + if (adev->set_mask & GETSET_POWER_80211) { +#if POWER_SAVE_80211 + acx_s_update_80211_powersave_mode(adev); +#endif + CLEAR_BIT(adev->set_mask, GETSET_POWER_80211); + } + + if (adev->set_mask & GETSET_CHANNEL) { + /* channel */ + log(L_INIT, "updating channel to: %u\n", adev->channel); + CLEAR_BIT(adev->set_mask, GETSET_CHANNEL); + } + + if (adev->set_mask & GETSET_TX) { + /* set Tx */ + log(L_INIT, "updating: %s Tx\n", + adev->tx_disabled ? "disable" : "enable"); + if (adev->tx_disabled) + acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0); + else + acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1); + CLEAR_BIT(adev->set_mask, GETSET_TX); + } + + if (adev->set_mask & GETSET_RX) { + /* Enable Rx */ + log(L_INIT, "updating: enable Rx on channel: %u\n", + adev->channel); + acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1); + CLEAR_BIT(adev->set_mask, GETSET_RX); + } + + if (adev->set_mask & GETSET_RETRY) { + u8 short_retry[4 + ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT_LEN]; + u8 long_retry[4 + ACX1xx_IE_DOT11_LONG_RETRY_LIMIT_LEN]; + + log(L_INIT, "updating short retry limit: %u, long retry limit: %u\n", + adev->short_retry, adev->long_retry); + short_retry[0x4] = adev->short_retry; + long_retry[0x4] = adev->long_retry; + acx_s_configure(adev, &short_retry, ACX1xx_IE_DOT11_SHORT_RETRY_LIMIT); + acx_s_configure(adev, &long_retry, ACX1xx_IE_DOT11_LONG_RETRY_LIMIT); + CLEAR_BIT(adev->set_mask, GETSET_RETRY); + } + + if (adev->set_mask & SET_MSDU_LIFETIME) { + u8 xmt_msdu_lifetime[4 + ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME_LEN]; + + log(L_INIT, "updating tx MSDU lifetime: %u\n", + adev->msdu_lifetime); + *(u32 *)&xmt_msdu_lifetime[4] = cpu_to_le32((u32)adev->msdu_lifetime); + acx_s_configure(adev, &xmt_msdu_lifetime, ACX1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME); + CLEAR_BIT(adev->set_mask, SET_MSDU_LIFETIME); + } + + if (adev->set_mask & GETSET_REG_DOMAIN) { + log(L_INIT, "updating regulatory domain: 0x%02X\n", + adev->reg_dom_id); + acx_s_set_sane_reg_domain(adev, 1); + CLEAR_BIT(adev->set_mask, GETSET_REG_DOMAIN); + } + + if (adev->set_mask & GETSET_MODE) { + adev->ndev->type = (adev->mode == ACX_MODE_MONITOR) ? + adev->monitor_type : ARPHRD_ETHER; + + switch (adev->mode) { + case ACX_MODE_3_AP: + + acx_lock(adev, flags); + acx_l_sta_list_init(adev); + adev->aid = 0; + adev->ap_client = NULL; + MAC_COPY(adev->bssid, adev->dev_addr); + /* this basically says "we're connected" */ + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + acx_unlock(adev, flags); + + acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + /* start sending beacons */ + acx_s_cmd_join_bssid(adev, adev->bssid); + break; + case ACX_MODE_MONITOR: + acx111_s_feature_on(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + /* this stops beacons */ + acx_s_cmd_join_bssid(adev, adev->bssid); + /* this basically says "we're connected" */ + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + SET_BIT(adev->set_mask, SET_RXCONFIG|SET_WEP_OPTIONS); + break; + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + acx111_s_feature_off(adev, 0, FEATURE2_NO_TXCRYPT|FEATURE2_SNIFFER); + + acx_lock(adev, flags); + adev->aid = 0; + adev->ap_client = NULL; + acx_unlock(adev, flags); + + /* we want to start looking for peer or AP */ + start_scan = 1; + break; + case ACX_MODE_OFF: + /* TODO: disable RX/TX, stop any scanning activity etc: */ + /* adev->tx_disabled = 1; */ + /* SET_BIT(adev->set_mask, GETSET_RX|GETSET_TX); */ + + /* This stops beacons (invalid macmode...) */ + acx_s_cmd_join_bssid(adev, adev->bssid); + acx_set_status(adev, ACX_STATUS_0_STOPPED); + break; + } + CLEAR_BIT(adev->set_mask, GETSET_MODE); + } + + if (adev->set_mask & SET_RXCONFIG) { + acx_s_initialize_rx_config(adev); + CLEAR_BIT(adev->set_mask, SET_RXCONFIG); + } + + if (adev->set_mask & GETSET_RESCAN) { + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + start_scan = 1; + break; + } + CLEAR_BIT(adev->set_mask, GETSET_RESCAN); + } + + if (adev->set_mask & GETSET_WEP) { + /* encode */ + + ie_dot11WEPDefaultKeyID_t dkey; +#ifdef DEBUG_WEP + struct { + u16 type; + u16 len; + u8 val; + } ACX_PACKED keyindic; +#endif + log(L_INIT, "updating WEP key settings\n"); + + acx_s_set_wepkey(adev); + + dkey.KeyID = adev->wep_current_index; + log(L_INIT, "setting WEP key %u as default\n", dkey.KeyID); + acx_s_configure(adev, &dkey, ACX1xx_IE_DOT11_WEP_DEFAULT_KEY_SET); +#ifdef DEBUG_WEP + keyindic.val = 3; + acx_s_configure(adev, &keyindic, ACX111_IE_KEY_CHOOSE); +#endif + start_scan = 1; + CLEAR_BIT(adev->set_mask, GETSET_WEP); + } + + if (adev->set_mask & SET_WEP_OPTIONS) { + acx100_ie_wep_options_t options; + + if (IS_ACX111(adev)) { + log(L_DEBUG, "setting WEP Options for acx111 is not supported\n"); + } else { + log(L_INIT, "setting WEP Options\n"); + + /* let's choose maximum setting: 4 default keys, + * plus 10 other keys: */ + options.NumKeys = cpu_to_le16(DOT11_MAX_DEFAULT_WEP_KEYS + 10); + /* don't decrypt default key only, + * don't override decryption: */ + options.WEPOption = 0; + if (adev->mode == ACX_MODE_MONITOR) { + /* don't decrypt default key only, + * override decryption mechanism: */ + options.WEPOption = 2; + } + + acx_s_configure(adev, &options, ACX100_IE_WEP_OPTIONS); + } + CLEAR_BIT(adev->set_mask, SET_WEP_OPTIONS); + } + + /* Rescan was requested */ + if (start_scan) { + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + /* We can avoid clearing list if join code + ** will be a bit more clever about not picking + ** 'bad' AP over and over again */ + acx_lock(adev, flags); + adev->ap_client = NULL; + acx_l_sta_list_init(adev); + acx_set_status(adev, ACX_STATUS_1_SCANNING); + acx_unlock(adev, flags); + + acx_s_cmd_start_scan(adev); + } + } + + /* debug, rate, and nick don't need any handling */ + /* what about sniffing mode?? */ + + log(L_INIT, "get_mask 0x%08X, set_mask 0x%08X - after update\n", + adev->get_mask, adev->set_mask); + +/* end: */ + FN_EXIT0; +} + + +/*********************************************************************** +** acx_e_after_interrupt_task +*/ +static int +acx_s_recalib_radio(acx_device_t *adev) +{ + if (IS_ACX111(adev)) { + acx111_cmd_radiocalib_t cal; + + printk("%s: recalibrating radio\n", adev->ndev->name); + /* automatic recalibration, choose all methods: */ + cal.methods = cpu_to_le32(0x8000000f); + /* automatic recalibration every 60 seconds (value in TUs) + * I wonder what the firmware default here is? */ + cal.interval = cpu_to_le32(58594); + return acx_s_issue_cmd_timeo(adev, ACX111_CMD_RADIOCALIB, + &cal, sizeof(cal), CMD_TIMEOUT_MS(100)); + } else { + /* On ACX100, we need to recalibrate the radio + * by issuing a GETSET_TX|GETSET_RX */ + if (/* (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_TX, NULL, 0)) && + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_DISABLE_RX, NULL, 0)) && */ + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_TX, &adev->channel, 1)) && + (OK == acx_s_issue_cmd(adev, ACX1xx_CMD_ENABLE_RX, &adev->channel, 1)) ) + return OK; + return NOT_OK; + } +} + +static void +acx_s_after_interrupt_recalib(acx_device_t *adev) +{ + int res; + + /* this helps with ACX100 at least; + * hopefully ACX111 also does a + * recalibration here */ + + /* clear flag beforehand, since we want to make sure + * it's cleared; then only set it again on specific circumstances */ + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + + /* better wait a bit between recalibrations to + * prevent overheating due to torturing the card + * into working too long despite high temperature + * (just a safety measure) */ + if (adev->recalib_time_last_success + && time_before(jiffies, adev->recalib_time_last_success + + RECALIB_PAUSE * 60 * HZ)) { + if (adev->recalib_msg_ratelimit <= 4) { + printk("%s: less than " STRING(RECALIB_PAUSE) + " minutes since last radio recalibration, " + "not recalibrating (maybe card is too hot?)\n", + adev->ndev->name); + adev->recalib_msg_ratelimit++; + if (adev->recalib_msg_ratelimit == 5) + printk("disabling above message until next recalib\n"); + } + return; + } + + adev->recalib_msg_ratelimit = 0; + + /* note that commands sometimes fail (card busy), + * so only clear flag if we were fully successful */ + res = acx_s_recalib_radio(adev); + if (res == OK) { + printk("%s: successfully recalibrated radio\n", + adev->ndev->name); + adev->recalib_time_last_success = jiffies; + adev->recalib_failure_count = 0; + } else { + /* failed: resubmit, but only limited + * amount of times within some time range + * to prevent endless loop */ + + adev->recalib_time_last_success = 0; /* we failed */ + + /* if some time passed between last + * attempts, then reset failure retry counter + * to be able to do next recalib attempt */ + if (time_after(jiffies, adev->recalib_time_last_attempt + 5*HZ)) + adev->recalib_failure_count = 0; + + if (adev->recalib_failure_count < 5) { + /* increment inside only, for speedup of outside path */ + adev->recalib_failure_count++; + adev->recalib_time_last_attempt = jiffies; + acx_schedule_task(adev, ACX_AFTER_IRQ_CMD_RADIO_RECALIB); + } + } +} + +static void +acx_e_after_interrupt_task(struct work_struct *work) +{ + acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task); + + FN_ENTER; + + acx_sem_lock(adev); + + if (!adev->after_interrupt_jobs) + goto end; /* no jobs to do */ + +#if TX_CLEANUP_IN_SOFTIRQ + /* can happen only on PCI */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_TX_CLEANUP) { + acx_lock(adev, flags); + acxpci_l_clean_txdesc(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_TX_CLEANUP); + acx_unlock(adev, flags); + } +#endif + /* we see lotsa tx errors */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_RADIO_RECALIB) { + acx_s_after_interrupt_recalib(adev); + } + + /* a poor interrupt code wanted to do update_card_settings() */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) { + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_UPDATE_CARD_CFG); + } + + /* 1) we detected that no Scan_Complete IRQ came from fw, or + ** 2) we found too many STAs */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) { + log(L_IRQ, "sending a stop scan cmd...\n"); + acx_s_issue_cmd(adev, ACX1xx_CMD_STOP_SCAN, NULL, 0); + /* HACK: set the IRQ bit, since we won't get a + * scan complete IRQ any more on ACX111 (works on ACX100!), + * since _we_, not a fw, have stopped the scan */ + SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_STOP_SCAN); + } + + /* either fw sent Scan_Complete or we detected that + ** no Scan_Complete IRQ came from fw. Finish scanning, + ** pick join partner if any */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_COMPLETE_SCAN) { + if (adev->status == ACX_STATUS_1_SCANNING) { + if (OK != acx_s_complete_scan(adev)) { + SET_BIT(adev->after_interrupt_jobs, + ACX_AFTER_IRQ_RESTART_SCAN); + } + } else { + /* + scan kills current join status - restore it + ** (do we need it for STA?) */ + /* + does it happen only with active scans? + ** active and passive scans? ALL scans including + ** background one? */ + /* + was not verified that everything is restored + ** (but at least we start to emit beacons again) */ + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_3_AP: + log(L_IRQ, "redoing cmd_join_bssid() after scan\n"); + acx_s_cmd_join_bssid(adev, adev->bssid); + } + } + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_COMPLETE_SCAN); + } + + /* STA auth or assoc timed out, start over again */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_RESTART_SCAN) { + log(L_IRQ, "sending a start_scan cmd...\n"); + acx_s_cmd_start_scan(adev); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_RESTART_SCAN); + } + + /* whee, we got positive assoc response! 8) */ + if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_ASSOCIATE) { + acx_ie_generic_t pdr; + /* tiny race window exists, checking that we still a STA */ + switch (adev->mode) { + case ACX_MODE_2_STA: + pdr.m.aid = cpu_to_le16(adev->aid); + acx_s_configure(adev, &pdr, ACX1xx_IE_ASSOC_ID); + acx_set_status(adev, ACX_STATUS_4_ASSOCIATED); + log(L_ASSOC|L_DEBUG, "ASSOCIATED!\n"); + CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_CMD_ASSOCIATE); + } + } +end: + acx_sem_unlock(adev); + FN_EXIT0; +} + + +/*********************************************************************** +** acx_schedule_task +** +** Schedule the call of the after_interrupt method after leaving +** the interrupt context. +*/ +void +acx_schedule_task(acx_device_t *adev, unsigned int set_flag) +{ + SET_BIT(adev->after_interrupt_jobs, set_flag); + SCHEDULE_WORK(&adev->after_interrupt_task); +} + + +/*********************************************************************** +*/ +void +acx_init_task_scheduler(acx_device_t *adev) +{ + /* configure task scheduler */ + INIT_WORK(&adev->after_interrupt_task, acx_e_after_interrupt_task); +} + + +/*********************************************************************** +** acx_s_start +*/ +void +acx_s_start(acx_device_t *adev) +{ + FN_ENTER; + + /* + * Ok, now we do everything that can possibly be done with ioctl + * calls to make sure that when it was called before the card + * was up we get the changes asked for + */ + + SET_BIT(adev->set_mask, SET_TEMPLATES|SET_STA_LIST|GETSET_WEP + |GETSET_TXPOWER|GETSET_ANTENNA|GETSET_ED_THRESH|GETSET_CCA + |GETSET_REG_DOMAIN|GETSET_MODE|GETSET_CHANNEL + |GETSET_TX|GETSET_RX|GETSET_STATION_ID); + + log(L_INIT, "updating initial settings on iface activation\n"); + acx_s_update_card_settings(adev); + + FN_EXIT0; +} + + +/*********************************************************************** +** acx_update_capabilities +*/ +void +acx_update_capabilities(acx_device_t *adev) +{ + u16 cap = 0; + + switch (adev->mode) { + case ACX_MODE_3_AP: + SET_BIT(cap, WF_MGMT_CAP_ESS); break; + case ACX_MODE_0_ADHOC: + SET_BIT(cap, WF_MGMT_CAP_IBSS); break; + /* other types of stations do not emit beacons */ + } + + if (adev->wep_restricted) { + SET_BIT(cap, WF_MGMT_CAP_PRIVACY); + } + if (adev->cfgopt_dot11ShortPreambleOption) { + SET_BIT(cap, WF_MGMT_CAP_SHORT); + } + if (adev->cfgopt_dot11PBCCOption) { + SET_BIT(cap, WF_MGMT_CAP_PBCC); + } + if (adev->cfgopt_dot11ChannelAgility) { + SET_BIT(cap, WF_MGMT_CAP_AGILITY); + } + log(L_DEBUG, "caps updated from 0x%04X to 0x%04X\n", + adev->capabilities, cap); + adev->capabilities = cap; +} + +/*********************************************************************** +** Common function to parse ALL configoption struct formats +** (ACX100 and ACX111; FIXME: how to make it work with ACX100 USB!?!?). +** FIXME: logging should be removed here and added to a /proc file instead +*/ +void +acx_s_parse_configoption(acx_device_t *adev, const acx111_ie_configoption_t *pcfg) +{ + const u8 *pEle; + int i; + int is_acx111 = IS_ACX111(adev); + + if (acx_debug & L_DEBUG) { + printk("configoption struct content:\n"); + acx_dump_bytes(pcfg, sizeof(*pcfg)); + } + + if (( is_acx111 && (adev->eeprom_version == 5)) + || (!is_acx111 && (adev->eeprom_version == 4)) + || (!is_acx111 && (adev->eeprom_version == 5))) { + /* these versions are known to be supported */ + } else { + printk("unknown chip and EEPROM version combination (%s, v%d), " + "don't know how to parse config options yet. " + "Please report\n", is_acx111 ? "ACX111" : "ACX100", + adev->eeprom_version); + return; + } + + /* first custom-parse the first part which has chip-specific layout */ + + pEle = (const u8 *) pcfg; + + pEle += 4; /* skip (type,len) header */ + + memcpy(adev->cfgopt_NVSv, pEle, sizeof(adev->cfgopt_NVSv)); + pEle += sizeof(adev->cfgopt_NVSv); + + if (is_acx111) { + adev->cfgopt_NVS_vendor_offs = le16_to_cpu(*(u16 *)pEle); + pEle += sizeof(adev->cfgopt_NVS_vendor_offs); + + adev->cfgopt_probe_delay = 200; /* good default value? */ + pEle += 2; /* FIXME: unknown, value 0x0001 */ + } else { + memcpy(adev->cfgopt_MAC, pEle, sizeof(adev->cfgopt_MAC)); + pEle += sizeof(adev->cfgopt_MAC); + + adev->cfgopt_probe_delay = le16_to_cpu(*(u16 *)pEle); + pEle += sizeof(adev->cfgopt_probe_delay); + if ((adev->cfgopt_probe_delay < 100) || (adev->cfgopt_probe_delay > 500)) { + printk("strange probe_delay value %d, " + "tweaking to 200\n", adev->cfgopt_probe_delay); + adev->cfgopt_probe_delay = 200; + } + } + + adev->cfgopt_eof_memory = le32_to_cpu(*(u32 *)pEle); + pEle += sizeof(adev->cfgopt_eof_memory); + + printk("NVS_vendor_offs:%04X probe_delay:%d eof_memory:%d\n", + adev->cfgopt_NVS_vendor_offs, + adev->cfgopt_probe_delay, + adev->cfgopt_eof_memory); + + adev->cfgopt_dot11CCAModes = *pEle++; + adev->cfgopt_dot11Diversity = *pEle++; + adev->cfgopt_dot11ShortPreambleOption = *pEle++; + adev->cfgopt_dot11PBCCOption = *pEle++; + adev->cfgopt_dot11ChannelAgility = *pEle++; + adev->cfgopt_dot11PhyType = *pEle++; + adev->cfgopt_dot11TempType = *pEle++; + printk("CCAModes:%02X Diversity:%02X ShortPreOpt:%02X " + "PBCC:%02X ChanAgil:%02X PHY:%02X Temp:%02X\n", + adev->cfgopt_dot11CCAModes, + adev->cfgopt_dot11Diversity, + adev->cfgopt_dot11ShortPreambleOption, + adev->cfgopt_dot11PBCCOption, + adev->cfgopt_dot11ChannelAgility, + adev->cfgopt_dot11PhyType, + adev->cfgopt_dot11TempType); + + /* then use common parsing for next part which has common layout */ + + pEle++; /* skip table_count (6) */ + + adev->cfgopt_antennas.type = pEle[0]; + adev->cfgopt_antennas.len = pEle[1]; + printk("AntennaID:%02X Len:%02X Data:", + adev->cfgopt_antennas.type, adev->cfgopt_antennas.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_antennas.list[i] = pEle[i+2]; + printk("%02X ", pEle[i+2]); + } + printk("\n"); + + pEle += pEle[1] + 2; + adev->cfgopt_power_levels.type = pEle[0]; + adev->cfgopt_power_levels.len = pEle[1]; + printk("PowerLevelID:%02X Len:%02X Data:", + adev->cfgopt_power_levels.type, adev->cfgopt_power_levels.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_power_levels.list[i] = le16_to_cpu(*(u16 *)&pEle[i*2+2]); + printk("%04X ", adev->cfgopt_power_levels.list[i]); + } + printk("\n"); + + pEle += pEle[1]*2 + 2; + adev->cfgopt_data_rates.type = pEle[0]; + adev->cfgopt_data_rates.len = pEle[1]; + printk("DataRatesID:%02X Len:%02X Data:", + adev->cfgopt_data_rates.type, adev->cfgopt_data_rates.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_data_rates.list[i] = pEle[i+2]; + printk("%02X ", pEle[i+2]); + } + printk("\n"); + + pEle += pEle[1] + 2; + adev->cfgopt_domains.type = pEle[0]; + adev->cfgopt_domains.len = pEle[1]; + printk("DomainID:%02X Len:%02X Data:", + adev->cfgopt_domains.type, adev->cfgopt_domains.len); + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_domains.list[i] = pEle[i+2]; + printk("%02X ", pEle[i+2]); + } + printk("\n"); + + pEle += pEle[1] + 2; + adev->cfgopt_product_id.type = pEle[0]; + adev->cfgopt_product_id.len = pEle[1]; + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_product_id.list[i] = pEle[i+2]; + } + printk("ProductID:%02X Len:%02X Data:%.*s\n", + adev->cfgopt_product_id.type, adev->cfgopt_product_id.len, + adev->cfgopt_product_id.len, (char *)adev->cfgopt_product_id.list); + + pEle += pEle[1] + 2; + adev->cfgopt_manufacturer.type = pEle[0]; + adev->cfgopt_manufacturer.len = pEle[1]; + for (i = 0; i < pEle[1]; i++) { + adev->cfgopt_manufacturer.list[i] = pEle[i+2]; + } + printk("ManufacturerID:%02X Len:%02X Data:%.*s\n", + adev->cfgopt_manufacturer.type, adev->cfgopt_manufacturer.len, + adev->cfgopt_manufacturer.len, (char *)adev->cfgopt_manufacturer.list); +/* + printk("EEPROM part:\n"); + for (i=0; i<58; i++) { + printk("%02X =======> 0x%02X\n", + i, (u8 *)adev->cfgopt_NVSv[i-2]); + } +*/ +} + + +/*********************************************************************** +*/ +static int __init +acx_e_init_module(void) +{ + int r1,r2; + + acx_struct_size_check(); +#if 0 + printk("acx: this driver is still EXPERIMENTAL\n" + "acx: reading README file and/or Craig's HOWTO is " + "recommended, visit http://acx100.sf.net in case " + "of further questions/discussion\n"); +#endif + printk(KERN_INFO "acx: Loaded combined PCI/USB driver, firmware_ver=%s\n", + firmware_ver); +#if defined(CONFIG_NET_ACX_PCI) + r1 = acxpci_e_init_module(); +#else + r1 = -EINVAL; +#endif +#if defined(CONFIG_NET_ACX_USB) + r2 = acxusb_e_init_module(); +#else + r2 = -EINVAL; +#endif + if (r2 && r1) /* both failed! */ + return r2 ? r2 : r1; + /* return success if at least one succeeded */ + return 0; +} + +static void __exit +acx_e_cleanup_module(void) +{ +#if defined(CONFIG_NET_ACX_PCI) + acxpci_e_cleanup_module(); +#endif +#if defined(CONFIG_NET_ACX_USB) + acxusb_e_cleanup_module(); +#endif +} + +module_init(acx_e_init_module) +module_exit(acx_e_cleanup_module) --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/acx/Makefile @@ -0,0 +1,5 @@ +EXTRA_CFLAGS = -DCONFIG_NET_ACX_PCI -DCONFIG_NET_ACX_USB + +obj-$(CONFIG_WIRELESS_ACX) += acx.o + +acx-objs := wlan.o conv.o ioctl.o common.o pci.o usb.o --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/ioctl.c +++ linux-2.6.28/ubuntu/misc/wireless/acx/ioctl.c @@ -0,0 +1,2745 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +#include +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 18) +#include +#endif +#include +#include +#include +/* #include */ /* required for 2.4.x kernels; verify_write() */ +#include +#include +#include + +#include "acx.h" + + +/*********************************************************************** +*/ + +/* channel frequencies + * TODO: Currently, every other 802.11 driver keeps its own copy of this. In + * the long run this should be integrated into ieee802_11.h or wireless.h or + * whatever IEEE802.11x framework evolves */ +static const u16 acx_channel_freq[] = { + 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484, +}; + + +/*********************************************************************** +** acx_ioctl_commit +*/ +static int +acx_ioctl_commit(struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + acx_sem_lock(adev); + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + acx_s_update_card_settings(adev); + acx_sem_unlock(adev); + + FN_EXIT0; + return OK; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_name( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + static const char * const names[] = { "IEEE 802.11b+/g+", "IEEE 802.11b+" }; + + strcpy(wrqu->name, names[IS_ACX111(adev) ? 0 : 1]); + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_freq +*/ +static int +acx_ioctl_set_freq( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int channel = -1; + unsigned int mult = 1; + int result; + + FN_ENTER; + + if (wrqu->freq.e == 0 && wrqu->freq.m <= 1000) { + /* Setting by channel number */ + channel = wrqu->freq.m; + } else { + /* If setting by frequency, convert to a channel */ + int i; + + for (i = 0; i < (6 - wrqu->freq.e); i++) + mult *= 10; + + for (i = 1; i <= 14; i++) + if (wrqu->freq.m == acx_channel_freq[i - 1] * mult) + channel = i; + } + + if (channel > 14) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + adev->channel = channel; + /* hmm, the following code part is strange, but this is how + * it was being done before... */ + log(L_IOCTL, "Changing to channel %d\n", channel); + SET_BIT(adev->set_mask, GETSET_CHANNEL); + + result = -EINPROGRESS; /* need to call commit handler */ + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static inline int +acx_ioctl_get_freq( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + wrqu->freq.e = 0; + wrqu->freq.m = adev->channel; + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_mode +*/ +static int +acx_ioctl_set_mode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + switch (wrqu->mode) { + case IW_MODE_AUTO: + adev->mode = ACX_MODE_OFF; + break; + case IW_MODE_MONITOR: + adev->mode = ACX_MODE_MONITOR; + break; + case IW_MODE_ADHOC: + adev->mode = ACX_MODE_0_ADHOC; + break; + case IW_MODE_INFRA: + adev->mode = ACX_MODE_2_STA; + break; + case IW_MODE_MASTER: + printk("acx: master mode (HostAP) is very, very " + "experimental! It might work partially, but " + "better get prepared for nasty surprises " + "at any time\n"); + adev->mode = ACX_MODE_3_AP; + break; + case IW_MODE_REPEAT: + case IW_MODE_SECOND: + default: + result = -EOPNOTSUPP; + goto end_unlock; + } + + log(L_ASSOC, "new adev->mode=%d\n", adev->mode); + SET_BIT(adev->set_mask, GETSET_MODE); + result = -EINPROGRESS; + +end_unlock: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_mode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result = 0; + + switch (adev->mode) { + case ACX_MODE_OFF: + wrqu->mode = IW_MODE_AUTO; break; + case ACX_MODE_MONITOR: + wrqu->mode = IW_MODE_MONITOR; break; + case ACX_MODE_0_ADHOC: + wrqu->mode = IW_MODE_ADHOC; break; + case ACX_MODE_2_STA: + wrqu->mode = IW_MODE_INFRA; break; + case ACX_MODE_3_AP: + wrqu->mode = IW_MODE_MASTER; break; + default: + result = -EOPNOTSUPP; + } + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_set_sens( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->sens; + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + adev->sensitivity = (1 == vwrq->disabled) ? 0 : vwrq->value; + SET_BIT(adev->set_mask, GETSET_SENSITIVITY); + + acx_sem_unlock(adev); + + return -EINPROGRESS; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_sens( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->sens; + acx_device_t *adev = ndev2adev(ndev); + + if (IS_USB(adev)) + /* setting the PHY reg via fw cmd doesn't work yet */ + return -EOPNOTSUPP; + + /* acx_sem_lock(adev); */ + + vwrq->value = adev->sensitivity; + vwrq->disabled = (vwrq->value == 0); + vwrq->fixed = 1; + + /* acx_sem_unlock(adev); */ + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_ap +** +** Sets the MAC address of the AP to associate with +*/ +static int +acx_ioctl_set_ap( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct sockaddr *awrq = &wrqu->ap_addr; + acx_device_t *adev = ndev2adev(ndev); + int result = 0; + const u8 *ap; + + FN_ENTER; + if (NULL == awrq) { + result = -EFAULT; + goto end; + } + if (ARPHRD_ETHER != awrq->sa_family) { + result = -EINVAL; + goto end; + } + + ap = awrq->sa_data; + acxlog_mac(L_IOCTL, "set AP=", ap, "\n"); + + MAC_COPY(adev->ap, ap); + + /* We want to start rescan in managed or ad-hoc mode, + ** otherwise just set adev->ap. + ** "iwconfig ap mode managed": we must be able + ** to set ap _first_ and _then_ set mode */ + switch (adev->mode) { + case ACX_MODE_0_ADHOC: + case ACX_MODE_2_STA: + /* FIXME: if there is a convention on what zero AP means, + ** please add a comment about that. I don't know of any --vda */ + if (mac_is_zero(ap)) { + /* "off" == 00:00:00:00:00:00 */ + MAC_BCAST(adev->ap); + log(L_IOCTL, "Not reassociating\n"); + } else { + log(L_IOCTL, "Forcing reassociation\n"); + SET_BIT(adev->set_mask, GETSET_RESCAN); + } + break; + } + result = -EINPROGRESS; +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_ap( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct sockaddr *awrq = &wrqu->ap_addr; + acx_device_t *adev = ndev2adev(ndev); + + if (ACX_STATUS_4_ASSOCIATED == adev->status) { + /* as seen in Aironet driver, airo.c */ + MAC_COPY(awrq->sa_data, adev->bssid); + } else { + MAC_ZERO(awrq->sa_data); + } + awrq->sa_family = ARPHRD_ETHER; + return OK; +} + + +/*********************************************************************** +** acx_ioctl_get_aplist +** +** Deprecated in favor of iwscan. +** We simply return the list of currently available stations in range, +** don't do a new scan. +*/ +static int +acx_ioctl_get_aplist( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + struct sockaddr *address = (struct sockaddr *) extra; + struct iw_quality qual[IW_MAX_AP]; + int i, cur; + int result = OK; + + FN_ENTER; + + /* we have AP list only in STA mode */ + if (ACX_MODE_2_STA != adev->mode) { + result = -EOPNOTSUPP; + goto end; + } + + cur = 0; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; + if (!bss->used) continue; + MAC_COPY(address[cur].sa_data, bss->bssid); + address[cur].sa_family = ARPHRD_ETHER; + qual[cur].level = bss->sir; + qual[cur].noise = bss->snr; +#ifndef OLD_QUALITY + qual[cur].qual = acx_signal_determine_quality(qual[cur].level, + qual[cur].noise); +#else + qual[cur].qual = (qual[cur].noise <= 100) ? + 100 - qual[cur].noise : 0; +#endif + /* no scan: level/noise/qual not updated: */ + qual[cur].updated = 0; + cur++; + } + if (cur) { + dwrq->flags = 1; + memcpy(extra + sizeof(struct sockaddr)*cur, &qual, + sizeof(struct iw_quality)*cur); + } + dwrq->length = cur; +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_set_scan( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + /* don't start scan if device is not up yet */ + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + result = -EAGAIN; + goto end_unlock; + } + + /* This is NOT a rescan for new AP! + ** Do not use SET_BIT(GETSET_RESCAN); */ + acx_s_cmd_start_scan(adev); + result = OK; + +end_unlock: + acx_sem_unlock(adev); +/* end: */ + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_s_scan_add_station +*/ +/* helper. not sure whether it's really a _s_leeping fn */ +static char* +acx_s_scan_add_station( + acx_device_t *adev, + char *ptr, + char *end_buf, + struct client *bss, + struct iw_request_info *info) +{ + struct iw_event iwe; + char *ptr_rate; + + FN_ENTER; + + /* MAC address has to be added first */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + MAC_COPY(iwe.u.ap_addr.sa_data, bss->bssid); + acxlog_mac(L_IOCTL, "scan, station address: ", bss->bssid, "\n"); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_ADDR_LEN); + + /* Add ESSID */ + iwe.cmd = SIOCGIWESSID; + iwe.u.data.length = bss->essid_len; + iwe.u.data.flags = 1; + log(L_IOCTL, "scan, essid: %s\n", bss->essid); + ptr = iwe_stream_add_point(info, ptr, end_buf, &iwe, bss->essid); + + /* Add mode */ + iwe.cmd = SIOCGIWMODE; + if (bss->cap_info & (WF_MGMT_CAP_ESS | WF_MGMT_CAP_IBSS)) { + if (bss->cap_info & WF_MGMT_CAP_ESS) + iwe.u.mode = IW_MODE_MASTER; + else + iwe.u.mode = IW_MODE_ADHOC; + log(L_IOCTL, "scan, mode: %d\n", iwe.u.mode); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_UINT_LEN); + } + + /* Add frequency */ + iwe.cmd = SIOCGIWFREQ; + iwe.u.freq.m = acx_channel_freq[bss->channel - 1] * 100000; + iwe.u.freq.e = 1; + log(L_IOCTL, "scan, frequency: %d\n", iwe.u.freq.m); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_FREQ_LEN); + + /* Add link quality */ + iwe.cmd = IWEVQUAL; + /* FIXME: these values should be expressed in dBm, but we don't know + * how to calibrate it yet */ + iwe.u.qual.level = bss->sir; + iwe.u.qual.noise = bss->snr; +#ifndef OLD_QUALITY + iwe.u.qual.qual = acx_signal_determine_quality(iwe.u.qual.level, + iwe.u.qual.noise); +#else + iwe.u.qual.qual = (iwe.u.qual.noise <= 100) ? + 100 - iwe.u.qual.noise : 0; +#endif + iwe.u.qual.updated = 7; + log(L_IOCTL, "scan, link quality: %d/%d/%d\n", + iwe.u.qual.level, iwe.u.qual.noise, iwe.u.qual.qual); + ptr = iwe_stream_add_event(info, ptr, end_buf, &iwe, IW_EV_QUAL_LEN); + + /* Add encryption */ + iwe.cmd = SIOCGIWENCODE; + if (bss->cap_info & WF_MGMT_CAP_PRIVACY) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + log(L_IOCTL, "scan, encryption flags: %X\n", iwe.u.data.flags); + ptr = iwe_stream_add_point(info, ptr, end_buf, &iwe, bss->essid); + + /* add rates */ + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + ptr_rate = ptr + IW_EV_LCP_LEN; + + { + u16 rate = bss->rate_cap; + const u8* p = acx_bitpos2ratebyte; + while (rate) { + if (rate & 1) { + iwe.u.bitrate.value = *p * 500000; /* units of 500kb/s */ + log(L_IOCTL, "scan, rate: %d\n", iwe.u.bitrate.value); + ptr_rate = iwe_stream_add_value(info, ptr, ptr_rate, end_buf, + &iwe, IW_EV_PARAM_LEN); + } + rate >>= 1; + p++; + }} + + if ((ptr_rate - ptr) > (ptrdiff_t)IW_EV_LCP_LEN) + ptr = ptr_rate; + + /* drop remaining station data items for now */ + + FN_EXIT0; + return ptr; +} + + +/*********************************************************************** + * acx_ioctl_get_scan + */ +static int +acx_ioctl_get_scan( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + char *ptr = extra; + int i; + int result = OK; + + FN_ENTER; + + acx_sem_lock(adev); + + /* no scan available if device is not up yet */ + if (!(adev->dev_state_mask & ACX_STATE_IFACE_UP)) { + log(L_IOCTL, "iface not up yet\n"); + result = -EAGAIN; + goto end_unlock; + } + +#ifdef ENODATA_TO_BE_USED_AFTER_SCAN_ERROR_ONLY + if (adev->bss_table_count == 0) { + /* no stations found */ + result = -ENODATA; + goto end_unlock; + } +#endif + + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + struct client *bss = &adev->sta_list[i]; + if (!bss->used) continue; + ptr = acx_s_scan_add_station(adev, ptr, + extra + IW_SCAN_MAX_DATA, bss, info); + } + dwrq->length = ptr - extra; + dwrq->flags = 0; + +end_unlock: + acx_sem_unlock(adev); +/* end: */ + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_essid +*/ +static int +acx_ioctl_set_essid( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->essid; + acx_device_t *adev = ndev2adev(ndev); + int len = dwrq->length; + int result; + + FN_ENTER; + + if (len < 0) { + result = -EINVAL; + goto end; + } + + log(L_IOCTL, "set ESSID '%*s', length %d, flags 0x%04X\n", + len, extra, len, dwrq->flags); + +#if WIRELESS_EXT >= 21 + /* WE 21 gives real ESSID strlen, not +1 (trailing zero): + * see LKML "[patch] drivers/net/wireless: correct reported ssid lengths" */ + len += 1; +#endif + + acx_sem_lock(adev); + + /* ESSID disabled? */ + if (0 == dwrq->flags) { + adev->essid_active = 0; + + } else { + if (dwrq->length > IW_ESSID_MAX_SIZE+1) { + result = -E2BIG; + goto end_unlock; + } + + if (len > sizeof(adev->essid)) + len = sizeof(adev->essid); + memcpy(adev->essid, extra, len-1); + adev->essid[len-1] = '\0'; + /* Paranoia: just in case there is a '\0'... */ + adev->essid_len = strlen(adev->essid); + adev->essid_active = 1; + } + + SET_BIT(adev->set_mask, GETSET_RESCAN); + + result = -EINPROGRESS; + +end_unlock: + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_essid( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->essid; + acx_device_t *adev = ndev2adev(ndev); + + dwrq->flags = adev->essid_active; + if (adev->essid_active) { + memcpy(extra, adev->essid, adev->essid_len); + extra[adev->essid_len] = '\0'; + dwrq->length = adev->essid_len + 1; + dwrq->flags = 1; + } + return OK; +} + + +/*********************************************************************** +** acx_l_update_client_rates +*/ +static void +acx_l_update_client_rates(acx_device_t *adev, u16 rate) +{ + int i; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; + if (!clt->used) continue; + clt->rate_cfg = (clt->rate_cap & rate); + if (!clt->rate_cfg) { + /* no compatible rates left: kick client */ + acxlog_mac(L_ASSOC, "client ",clt->address," kicked: " + "rates are not compatible anymore\n"); + acx_l_sta_list_del(adev, clt); + continue; + } + clt->rate_cur &= clt->rate_cfg; + if (!clt->rate_cur) { + /* current rate become invalid, choose a valid one */ + clt->rate_cur = 1 << lowest_bit(clt->rate_cfg); + } + if (IS_ACX100(adev)) + clt->rate_100 = acx_bitpos2rate100[highest_bit(clt->rate_cur)]; + clt->fallback_count = clt->stepup_count = 0; + clt->ignore_count = 16; + } + switch (adev->mode) { + case ACX_MODE_2_STA: + if (adev->ap_client && !adev->ap_client->used) { + /* Owwww... we kicked our AP!! :) */ + SET_BIT(adev->set_mask, GETSET_RESCAN); + } + } +} + + +/*********************************************************************** +*/ +/* maps bits from acx111 rate to rate in Mbits */ +static const unsigned int +acx111_rate_tbl[] = { + 1000000, /* 0 */ + 2000000, /* 1 */ + 5500000, /* 2 */ + 6000000, /* 3 */ + 9000000, /* 4 */ + 11000000, /* 5 */ + 12000000, /* 6 */ + 18000000, /* 7 */ + 22000000, /* 8 */ + 24000000, /* 9 */ + 36000000, /* 10 */ + 48000000, /* 11 */ + 54000000, /* 12 */ + 500000, /* 13, should not happen */ + 500000, /* 14, should not happen */ + 500000, /* 15, should not happen */ +}; + +/*********************************************************************** + * acx_ioctl_set_rate + */ +static int +acx_ioctl_set_rate( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); + u16 txrate_cfg = 1; + unsigned long flags; + int autorate; + int result = -EINVAL; + + FN_ENTER; + log(L_IOCTL, "rate %d fixed 0x%X disabled 0x%X flags 0x%X\n", + vwrq->value, vwrq->fixed, vwrq->disabled, vwrq->flags); + + if ((0 == vwrq->fixed) || (1 == vwrq->fixed)) { + int i = VEC_SIZE(acx111_rate_tbl)-1; + if (vwrq->value == -1) + /* "iwconfig rate auto" --> choose highest */ + vwrq->value = IS_ACX100(adev) ? 22000000 : 54000000; + while (i >= 0) { + if (vwrq->value == acx111_rate_tbl[i]) { + txrate_cfg <<= i; + i = 0; + break; + } + i--; + } + if (i == -1) { /* no matching rate */ + result = -EINVAL; + goto end; + } + } else { /* rate N, N<1000 (driver specific): we don't use this */ + result = -EOPNOTSUPP; + goto end; + } + /* now: only one bit is set in txrate_cfg, corresponding to + ** indicated rate */ + + autorate = (vwrq->fixed == 0) && (RATE111_1 != txrate_cfg); + if (autorate) { + /* convert 00100000 -> 00111111 */ + txrate_cfg = (txrate_cfg<<1)-1; + } + + if (IS_ACX100(adev)) { + txrate_cfg &= RATE111_ACX100_COMPAT; + if (!txrate_cfg) { + result = -ENOTSUPP; /* rate is not supported by acx100 */ + goto end; + } + } + + acx_sem_lock(adev); + acx_lock(adev, flags); + + adev->rate_auto = autorate; + adev->rate_oper = txrate_cfg; + adev->rate_basic = txrate_cfg; + /* only do that in auto mode, non-auto will be able to use + * one specific Tx rate only anyway */ + if (autorate) { + /* only use 802.11b base rates, for standard 802.11b H/W + * compatibility */ + adev->rate_basic &= RATE111_80211B_COMPAT; + } + adev->rate_bcast = 1 << lowest_bit(txrate_cfg); + if (IS_ACX100(adev)) + adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast); + acx_l_update_ratevector(adev); + acx_l_update_client_rates(adev, txrate_cfg); + + /* Do/don't do tx rate fallback; beacon contents and rate */ + SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); + result = -EINPROGRESS; + + acx_unlock(adev, flags); + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_rate +*/ +static int +acx_ioctl_get_rate( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + u16 rate; + + acx_lock(adev, flags); + rate = adev->rate_oper; + if (adev->ap_client) + rate = adev->ap_client->rate_cur; + vwrq->value = acx111_rate_tbl[highest_bit(rate)]; + vwrq->fixed = !adev->rate_auto; + vwrq->disabled = 0; + acx_unlock(adev, flags); + + return OK; +} + +static int +acx_ioctl_set_rts( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->rts; + acx_device_t *adev = ndev2adev(ndev); + int val = vwrq->value; + + if (vwrq->disabled) + val = 2312; + if ((val < 0) || (val > 2312)) + return -EINVAL; + + adev->rts_threshold = val; + return OK; +} + +static inline int +acx_ioctl_get_rts( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->rts; + acx_device_t *adev = ndev2adev(ndev); + + vwrq->value = adev->rts_threshold; + vwrq->disabled = (vwrq->value >= 2312); + vwrq->fixed = 1; + return OK; +} + + +#if ACX_FRAGMENTATION +static int +acx_ioctl_set_frag( + struct net_device *ndev, + struct iw_request_info *info, + struct iw_param *vwrq, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int val = vwrq->value; + + if (vwrq->disabled) + val = 32767; + else + if ((val < 256) || (val > 2347)) + return -EINVAL; + + adev->frag_threshold = val; + return OK; +} + +static inline int +acx_ioctl_get_frag( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->frag; + acx_device_t *adev = ndev2adev(ndev); + + vwrq->value = adev->frag_threshold; + vwrq->disabled = (vwrq->value >= 2347); + vwrq->fixed = 1; + return OK; +} +#endif + + +/*********************************************************************** +** acx_ioctl_set_encode +*/ +static int +acx_ioctl_set_encode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->encoding; + acx_device_t *adev = ndev2adev(ndev); + int index; + int result; + + FN_ENTER; + + log(L_IOCTL, "set encoding flags=0x%04X, size=%d, key: %s\n", + dwrq->flags, dwrq->length, extra ? "set" : "No key"); + + acx_sem_lock(adev); + + index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + + if (dwrq->length > 0) { + /* if index is 0 or invalid, use default key */ + if ((index < 0) || (index > 3)) + index = (int)adev->wep_current_index; + + if (0 == (dwrq->flags & IW_ENCODE_NOKEY)) { + if (dwrq->length > 29) + dwrq->length = 29; /* restrict it */ + + if (dwrq->length > 13) { + /* 29*8 == 232, WEP256 */ + adev->wep_keys[index].size = 29; + } else if (dwrq->length > 5) { + /* 13*8 == 104bit, WEP128 */ + adev->wep_keys[index].size = 13; + } else if (dwrq->length > 0) { + /* 5*8 == 40bit, WEP64 */ + adev->wep_keys[index].size = 5; + } else { + /* disable key */ + adev->wep_keys[index].size = 0; + } + + memset(adev->wep_keys[index].key, 0, + sizeof(adev->wep_keys[index].key)); + memcpy(adev->wep_keys[index].key, extra, dwrq->length); + } + } else { + /* set transmit key */ + if ((index >= 0) && (index <= 3)) + adev->wep_current_index = index; + else if (0 == (dwrq->flags & IW_ENCODE_MODE)) { + /* complain if we were not just setting + * the key mode */ + result = -EINVAL; + goto end_unlock; + } + } + + adev->wep_enabled = !(dwrq->flags & IW_ENCODE_DISABLED); + + if (dwrq->flags & IW_ENCODE_OPEN) { + adev->auth_alg = WLAN_AUTH_ALG_OPENSYSTEM; + adev->wep_restricted = 0; + + } else if (dwrq->flags & IW_ENCODE_RESTRICTED) { + adev->auth_alg = WLAN_AUTH_ALG_SHAREDKEY; + adev->wep_restricted = 1; + } + + /* set flag to make sure the card WEP settings get updated */ + SET_BIT(adev->set_mask, GETSET_WEP); + + log(L_IOCTL, "len=%d, key at 0x%p, flags=0x%X\n", + dwrq->length, extra, dwrq->flags); + + for (index = 0; index <= 3; index++) { + if (adev->wep_keys[index].size) { + log(L_IOCTL, "index=%d, size=%d, key at 0x%p\n", + adev->wep_keys[index].index, + (int) adev->wep_keys[index].size, + adev->wep_keys[index].key); + } + } + result = -EINPROGRESS; + +end_unlock: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_encode +*/ +static int +acx_ioctl_get_encode( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->encoding; + acx_device_t *adev = ndev2adev(ndev); + int index = (dwrq->flags & IW_ENCODE_INDEX) - 1; + + FN_ENTER; + + if (adev->wep_enabled == 0) { + dwrq->flags = IW_ENCODE_DISABLED; + } else { + if ((index < 0) || (index > 3)) + index = (int)adev->wep_current_index; + + dwrq->flags = (adev->wep_restricted == 1) ? + IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN; + dwrq->length = adev->wep_keys[index].size; + + memcpy(extra, adev->wep_keys[index].key, + adev->wep_keys[index].size); + } + + /* set the current index */ + SET_BIT(dwrq->flags, index + 1); + + log(L_IOCTL, "len=%d, key=%p, flags=0x%X\n", + dwrq->length, dwrq->pointer, + dwrq->flags); + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_set_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + int result = -EINPROGRESS; + + FN_ENTER; + + log(L_IOCTL, "set 802.11 powersave flags=0x%04X\n", vwrq->flags); + + acx_sem_lock(adev); + + if (vwrq->disabled) { + CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE); + SET_BIT(adev->set_mask, GETSET_POWER_80211); + goto end; + } + if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { + u16 ps_timeout = (vwrq->value * 1024) / 1000; + + if (ps_timeout > 255) + ps_timeout = 255; + log(L_IOCTL, "setting PS timeout value to %d time units " + "due to %dus\n", ps_timeout, vwrq->value); + adev->ps_hangover_period = ps_timeout; + } else if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_PERIOD) { + u16 ps_periods = vwrq->value / 1000000; + + if (ps_periods > 255) + ps_periods = 255; + log(L_IOCTL, "setting PS period value to %d periods " + "due to %dus\n", ps_periods, vwrq->value); + adev->ps_listen_interval = ps_periods; + CLEAR_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_MODE_MASK); + SET_BIT(adev->ps_wakeup_cfg, PS_CFG_WAKEUP_EACH_ITVL); + } + + switch (vwrq->flags & IW_POWER_MODE) { + /* FIXME: are we doing the right thing here? */ + case IW_POWER_UNICAST_R: + CLEAR_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); + break; + case IW_POWER_MULTICAST_R: + SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); + break; + case IW_POWER_ALL_R: + SET_BIT(adev->ps_options, PS_OPT_STILL_RCV_BCASTS); + break; + case IW_POWER_ON: + break; + default: + log(L_IOCTL, "unknown PS mode\n"); + result = -EINVAL; + goto end; + } + + SET_BIT(adev->ps_wakeup_cfg, PS_CFG_ENABLE); + SET_BIT(adev->set_mask, GETSET_POWER_80211); +end: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +*/ +static int +acx_ioctl_get_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + log(L_IOCTL, "Get 802.11 Power Save flags = 0x%04X\n", vwrq->flags); + vwrq->disabled = ((adev->ps_wakeup_cfg & PS_CFG_ENABLE) == 0); + if (vwrq->disabled) + goto end; + + if ((vwrq->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) { + vwrq->value = adev->ps_hangover_period * 1000 / 1024; + vwrq->flags = IW_POWER_TIMEOUT; + } else { + vwrq->value = adev->ps_listen_interval * 1000000; + vwrq->flags = IW_POWER_PERIOD|IW_POWER_RELATIVE; + } + if (adev->ps_options & PS_OPT_STILL_RCV_BCASTS) + SET_BIT(vwrq->flags, IW_POWER_ALL_R); + else + SET_BIT(vwrq->flags, IW_POWER_UNICAST_R); +end: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_ioctl_get_txpow +*/ +static inline int +acx_ioctl_get_txpow( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + + FN_ENTER; + + vwrq->flags = IW_TXPOW_DBM; + vwrq->disabled = 0; + vwrq->fixed = 1; + vwrq->value = adev->tx_level_dbm; + + log(L_IOCTL, "get txpower:%d dBm\n", adev->tx_level_dbm); + + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_txpow +*/ +static int +acx_ioctl_set_txpow( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->power; + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + log(L_IOCTL, "set txpower:%d, disabled:%d, flags:0x%04X\n", + vwrq->value, vwrq->disabled, vwrq->flags); + + acx_sem_lock(adev); + + if (vwrq->disabled != adev->tx_disabled) { + SET_BIT(adev->set_mask, GETSET_TX); + } + + adev->tx_disabled = vwrq->disabled; + if (vwrq->value == -1) { + if (vwrq->disabled) { + adev->tx_level_dbm = 0; + log(L_IOCTL, "disable radio tx\n"); + } else { + /* adev->tx_level_auto = 1; */ + log(L_IOCTL, "set tx power auto (NIY)\n"); + } + } else { + adev->tx_level_dbm = vwrq->value <= 20 ? vwrq->value : 20; + /* adev->tx_level_auto = 0; */ + log(L_IOCTL, "set txpower=%d dBm\n", adev->tx_level_dbm); + } + SET_BIT(adev->set_mask, GETSET_TXPOWER); + + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_range +*/ +static int +acx_ioctl_get_range( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + struct iw_range *range = (struct iw_range *)extra; + acx_device_t *adev = ndev2adev(ndev); + int i,n; + + FN_ENTER; + + if (!dwrq->pointer) + goto end; + + dwrq->length = sizeof(struct iw_range); + memset(range, 0, sizeof(struct iw_range)); + n = 0; + for (i = 1; i <= 14; i++) { + if (adev->reg_dom_chanmask & (1 << (i - 1))) { + range->freq[n].i = i; + range->freq[n].m = acx_channel_freq[i - 1] * 100000; + range->freq[n].e = 1; /* units are MHz */ + n++; + } + } + range->num_channels = n; + range->num_frequency = n; + + range->min_rts = 0; + range->max_rts = 2312; + +#if ACX_FRAGMENTATION + range->min_frag = 256; + range->max_frag = 2312; +#endif + + range->encoding_size[0] = 5; + range->encoding_size[1] = 13; + range->encoding_size[2] = 29; + range->num_encoding_sizes = 3; + range->max_encoding_tokens = 4; + + range->min_pmp = 0; + range->max_pmp = 5000000; + range->min_pmt = 0; + range->max_pmt = 65535 * 1000; + range->pmp_flags = IW_POWER_PERIOD; + range->pmt_flags = IW_POWER_TIMEOUT; + range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; + + if (IS_ACX100(adev)) { /* ACX100 has direct radio programming - arbitrary levels, so offer a lot */ + for (i = 0; i <= IW_MAX_TXPOWER - 1; i++) + range->txpower[i] = 20 * i / (IW_MAX_TXPOWER - 1); + range->num_txpower = IW_MAX_TXPOWER; + range->txpower_capa = IW_TXPOW_DBM; + } + else { + int count = min(IW_MAX_TXPOWER, (int)adev->cfgopt_power_levels.len); + for (i = 0; i <= count; i++) + range->txpower[i] = adev->cfgopt_power_levels.list[i]; + range->num_txpower = count; + /* this list is given in mW */ + range->txpower_capa = IW_TXPOW_MWATT; + } + + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 0x9; + + range->retry_capa = IW_RETRY_LIMIT; + range->retry_flags = IW_RETRY_LIMIT; + range->min_retry = 1; + range->max_retry = 255; + + range->r_time_flags = IW_RETRY_LIFETIME; + range->min_r_time = 0; + /* FIXME: lifetime ranges and orders of magnitude are strange?? */ + range->max_r_time = 65535; + + if (IS_USB(adev)) + range->sensitivity = 0; + else if (IS_ACX111(adev)) + range->sensitivity = 3; + else + range->sensitivity = 255; + + for (i=0; i < adev->rate_supported_len; i++) { + range->bitrate[i] = (adev->rate_supported[i] & ~0x80) * 500000; + /* never happens, but keep it, to be safe: */ + if (range->bitrate[i] == 0) + break; + } + range->num_bitrates = i; + + range->max_qual.qual = 100; + range->max_qual.level = 100; + range->max_qual.noise = 100; + /* TODO: better values */ + range->avg_qual.qual = 90; + range->avg_qual.level = 80; + range->avg_qual.noise = 2; + +end: + FN_EXIT1(OK); + return OK; +} + + +/*********************************************************************** +** Private functions +*/ + +/*********************************************************************** +** acx_ioctl_get_nick +*/ +static inline int +acx_ioctl_get_nick( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + + strcpy(extra, adev->nick); + dwrq->length = strlen(extra) + 1; + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_nick +*/ +static int +acx_ioctl_set_nick( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_point *dwrq = &wrqu->data; + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + if (dwrq->length > IW_ESSID_MAX_SIZE + 1) { + result = -E2BIG; + goto end_unlock; + } + + /* extra includes trailing \0, so it's ok */ + strcpy(adev->nick, extra); + result = OK; + +end_unlock: + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_retry +*/ +static int +acx_ioctl_get_retry( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->retry; + acx_device_t *adev = ndev2adev(ndev); + unsigned int type = vwrq->flags & IW_RETRY_TYPE; + unsigned int modifier = vwrq->flags & IW_RETRY_MODIFIER; + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + /* return the short retry number by default */ + if (type == IW_RETRY_LIFETIME) { + vwrq->flags = IW_RETRY_LIFETIME; + vwrq->value = adev->msdu_lifetime; + } else if (modifier == IW_RETRY_MAX) { + vwrq->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; + vwrq->value = adev->long_retry; + } else { + vwrq->flags = IW_RETRY_LIMIT; + if (adev->long_retry != adev->short_retry) + SET_BIT(vwrq->flags, IW_RETRY_MIN); + vwrq->value = adev->short_retry; + } + + /* can't be disabled */ + vwrq->disabled = (u8)0; + result = OK; + + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_retry +*/ +static int +acx_ioctl_set_retry( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->retry; + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if (!vwrq) { + result = -EFAULT; + goto end; + } + if (vwrq->disabled) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + result = -EINVAL; + if (IW_RETRY_LIMIT == (vwrq->flags & IW_RETRY_TYPE)) { + printk("old retry limits: short %d long %d\n", + adev->short_retry, adev->long_retry); + if (vwrq->flags & IW_RETRY_MAX) { + adev->long_retry = vwrq->value; + } else if (vwrq->flags & IW_RETRY_MIN) { + adev->short_retry = vwrq->value; + } else { + /* no modifier: set both */ + adev->long_retry = vwrq->value; + adev->short_retry = vwrq->value; + } + printk("new retry limits: short %d long %d\n", + adev->short_retry, adev->long_retry); + SET_BIT(adev->set_mask, GETSET_RETRY); + result = -EINPROGRESS; + } + else if (vwrq->flags & IW_RETRY_LIFETIME) { + adev->msdu_lifetime = vwrq->value; + printk("new MSDU lifetime: %d\n", adev->msdu_lifetime); + SET_BIT(adev->set_mask, SET_MSDU_LIFETIME); + result = -EINPROGRESS; + } + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/************************ private ioctls ******************************/ + + +/*********************************************************************** +** acx_ioctl_set_debug +*/ +#if ACX_DEBUG +static int +acx_ioctl_set_debug( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + unsigned int debug_new = *((unsigned int *)extra); + int result = -EINVAL; + + log(L_ANY, "setting debug from %04X to %04X\n", acx_debug, debug_new); + acx_debug = debug_new; + + result = OK; + return result; + +} +#endif + + +/*********************************************************************** +** acx_ioctl_list_reg_domain +*/ +static int +acx_ioctl_list_reg_domain( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + int i = 1; + const char * const *entry = acx_reg_domain_strings; + + printk("dom# chan# domain/country\n"); + while (*entry) + printk("%4d %s\n", i++, *entry++); + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_reg_domain +*/ +static int +acx_ioctl_set_reg_domain( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if ((*extra < 1) || ((size_t)*extra > acx_reg_domain_ids_len)) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + adev->reg_dom_id = acx_reg_domain_ids[*extra - 1]; + SET_BIT(adev->set_mask, GETSET_REG_DOMAIN); + + result = -EINPROGRESS; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_reg_domain +*/ +static int +acx_ioctl_get_reg_domain( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int dom,i; + + /* no locking */ + dom = adev->reg_dom_id; + + for (i = 1; i <= acx_reg_domain_ids_len; i++) { + if (acx_reg_domain_ids[i-1] == dom) { + log(L_IOCTL, "regulatory domain is currently set " + "to %d (0x%X): %s\n", i, dom, + acx_reg_domain_strings[i-1]); + *extra = i; + break; + } + } + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_short_preamble +*/ +static const char * const +preamble_modes[] = { + "off", + "on", + "auto (peer capability dependent)", + "unknown mode, error" +}; + +static int +acx_ioctl_set_short_preamble( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int i; + int result; + + FN_ENTER; + + if ((unsigned char)*extra > 2) { + result = -EINVAL; + goto end; + } + + acx_sem_lock(adev); + + adev->preamble_mode = (u8)*extra; + switch (adev->preamble_mode) { + case 0: /* long */ + adev->preamble_cur = 0; + break; + case 1: + /* short, kick incapable peers */ + adev->preamble_cur = 1; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; + if (!clt->used) continue; + if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) { + clt->used = CLIENT_EMPTY_SLOT_0; + } + } + switch (adev->mode) { + case ACX_MODE_2_STA: + if (adev->ap_client && !adev->ap_client->used) { + /* We kicked our AP :) */ + SET_BIT(adev->set_mask, GETSET_RESCAN); + } + } + break; + case 2: /* auto. short only if all peers are short-capable */ + adev->preamble_cur = 1; + for (i = 0; i < VEC_SIZE(adev->sta_list); i++) { + client_t *clt = &adev->sta_list[i]; + if (!clt->used) continue; + if (!(clt->cap_info & WF_MGMT_CAP_SHORT)) { + adev->preamble_cur = 0; + break; + } + } + break; + } + printk("new short preamble setting: configured %s, active %s\n", + preamble_modes[adev->preamble_mode], + preamble_modes[adev->preamble_cur]); + result = OK; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_short_preamble +*/ +static int +acx_ioctl_get_short_preamble( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + printk("current short preamble setting: configured %s, active %s\n", + preamble_modes[adev->preamble_mode], + preamble_modes[adev->preamble_cur]); + + *extra = (char)adev->preamble_mode; + + acx_sem_unlock(adev); + + return OK; +} + + +/*********************************************************************** +** acx_ioctl_set_antenna +** +** TX and RX antenna can be set separately but this function good +** for testing 0-4 bits +*/ +static int +acx_ioctl_set_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + printk("old antenna value: 0x%02X (COMBINED bit mask)\n" + "Rx antenna selection:\n" + "0x00 ant. 1\n" + "0x40 ant. 2\n" + "0x80 full diversity\n" + "0xc0 partial diversity\n" + "0x0f dwell time mask (in units of us)\n" + "Tx antenna selection:\n" + "0x00 ant. 2\n" /* yep, those ARE reversed! */ + "0x20 ant. 1\n" + "new antenna value: 0x%02X\n", + adev->antenna, (u8)*extra); + + adev->antenna = (u8)*extra; + SET_BIT(adev->set_mask, GETSET_ANTENNA); + + acx_sem_unlock(adev); + + return -EINPROGRESS; +} + + +/*********************************************************************** +** acx_ioctl_get_antenna +*/ +static int +acx_ioctl_get_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + /* no locking. it's pointless to lock a single load */ + printk("current antenna value: 0x%02X (COMBINED bit mask)\n" + "Rx antenna selection:\n" + "0x00 ant. 1\n" + "0x40 ant. 2\n" + "0x80 full diversity\n" + "0xc0 partial diversity\n" + "Tx antenna selection:\n" + "0x00 ant. 2\n" /* yep, those ARE reversed! */ + "0x20 ant. 1\n", adev->antenna); + + return 0; +} + + +/*********************************************************************** +** acx_ioctl_set_rx_antenna +** +** 0 = antenna1; 1 = antenna2; 2 = full diversity; 3 = partial diversity +** Could anybody test which antenna is the external one? +*/ +static int +acx_ioctl_set_rx_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if (*extra > 3) { + result = -EINVAL; + goto end; + } + + printk("old antenna value: 0x%02X\n", adev->antenna); + + acx_sem_lock(adev); + + adev->antenna &= 0x3f; + SET_BIT(adev->antenna, (*extra << 6)); + SET_BIT(adev->set_mask, GETSET_ANTENNA); + printk("new antenna value: 0x%02X\n", adev->antenna); + result = -EINPROGRESS; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_tx_antenna +** +** Arguments: 0 == antenna2; 1 == antenna1; +** Could anybody test which antenna is the external one? +*/ +static int +acx_ioctl_set_tx_antenna( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + FN_ENTER; + + if (*extra > 1) { + result = -EINVAL; + goto end; + } + + printk("old antenna value: 0x%02X\n", adev->antenna); + + acx_sem_lock(adev); + + adev->antenna &= ~0x30; + SET_BIT(adev->antenna, ((*extra & 0x01) << 5)); + SET_BIT(adev->set_mask, GETSET_ANTENNA); + printk("new antenna value: 0x%02X\n", adev->antenna); + result = -EINPROGRESS; + + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_wlansniff +** +** can we just remove this in favor of monitor mode? --vda +*/ +static int +acx_ioctl_wlansniff( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned int *params = (unsigned int*)extra; + unsigned int enable = (unsigned int)(params[0] > 0); + int result; + + FN_ENTER; + + acx_sem_lock(adev); + + /* not using printk() here, since it distorts kismet display + * when printk messages activated */ + log(L_IOCTL, "setting monitor to: 0x%02X\n", params[0]); + + switch (params[0]) { + case 0: + /* no monitor mode. hmm, should we simply ignore it + * or go back to enabling adev->netdev->type ARPHRD_ETHER? */ + break; + case 1: + adev->monitor_type = ARPHRD_IEEE80211_PRISM; + break; + case 2: + adev->monitor_type = ARPHRD_IEEE80211; + break; + } + + if (params[0]) { + adev->mode = ACX_MODE_MONITOR; + SET_BIT(adev->set_mask, GETSET_MODE); + } + + if (enable) { + adev->channel = params[1]; + SET_BIT(adev->set_mask, GETSET_RX); + } + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_unknown11 +** FIXME: looks like some sort of "iwpriv kick_sta MAC" but it's broken +*/ +static int +acx_ioctl_unknown11( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ +#ifdef BROKEN + struct iw_param *vwrq = &wrqu->param; + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + client_t client; + int result; + + acx_sem_lock(adev); + acx_lock(adev, flags); + + acx_l_transmit_disassoc(adev, &client); + result = OK; + + acx_unlock(adev, flags); + acx_sem_unlock(adev); + + return result; +#endif + return -EINVAL; +} + + +/*********************************************************************** +** debug helper function to be able to debug various issues relatively easily +*/ +static int +acx_ioctl_dbg_set_masks( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + const unsigned int *params = (unsigned int*)extra; + int result; + + acx_sem_lock(adev); + + log(L_IOCTL, "setting flags in settings mask: " + "get_mask %08X set_mask %08X\n" + "before: get_mask %08X set_mask %08X\n", + params[0], params[1], + adev->get_mask, adev->set_mask); + SET_BIT(adev->get_mask, params[0]); + SET_BIT(adev->set_mask, params[1]); + log(L_IOCTL, "after: get_mask %08X set_mask %08X\n", + adev->get_mask, adev->set_mask); + result = -EINPROGRESS; /* immediately call commit handler */ + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +* acx_ioctl_set_rates +* +* This ioctl takes string parameter. Examples: +* iwpriv wlan0 SetRates "1,2" +* use 1 and 2 Mbit rates, both are in basic rate set +* iwpriv wlan0 SetRates "1,2 5,11" +* use 1,2,5.5,11 Mbit rates. 1 and 2 are basic +* iwpriv wlan0 SetRates "1,2 5c,11c" +* same ('c' means 'CCK modulation' and it is a default for 5 and 11) +* iwpriv wlan0 SetRates "1,2 5p,11p" +* use 1,2,5.5,11 Mbit, 1,2 are basic. 5 and 11 are using PBCC +* iwpriv wlan0 SetRates "1,2,5,11 22p" +* use 1,2,5.5,11,22 Mbit. 1,2,5.5 and 11 are basic. 22 is using PBCC +* (this is the maximum acx100 can do (modulo x4 mode)) +* iwpriv wlan0 SetRates "1,2,5,11 22" +* same. 802.11 defines only PBCC modulation +* for 22 and 33 Mbit rates, so there is no ambiguity +* iwpriv wlan0 SetRates "1,2,5,11 6o,9o,12o,18o,24o,36o,48o,54o" +* 1,2,5.5 and 11 are basic. 11g OFDM rates are enabled but +* they are not in basic rate set. 22 Mbit is disabled. +* iwpriv wlan0 SetRates "1,2,5,11 6,9,12,18,24,36,48,54" +* same. OFDM is default for 11g rates except 22 and 33 Mbit, +* thus 'o' is optional +* iwpriv wlan0 SetRates "1,2,5,11 6d,9d,12d,18d,24d,36d,48d,54d" +* 1,2,5.5 and 11 are basic. 11g CCK-OFDM rates are enabled +* (acx111 does not support CCK-OFDM, driver will reject this cmd) +* iwpriv wlan0 SetRates "6,9,12 18,24,36,48,54" +* 6,9,12 are basic, rest of 11g rates is enabled. Using OFDM +*/ +#include "setrate.c" + +/* disallow: 33Mbit (unsupported by hw) */ +/* disallow: CCKOFDM (unsupported by hw) */ +static int +acx111_supported(int mbit, int modulation, void *opaque) +{ + if (mbit==33) return -ENOTSUPP; + if (modulation==DOT11_MOD_CCKOFDM) return -ENOTSUPP; + return OK; +} + +static const u16 +acx111mask[] = { + [DOT11_RATE_1 ] = RATE111_1 , + [DOT11_RATE_2 ] = RATE111_2 , + [DOT11_RATE_5 ] = RATE111_5 , + [DOT11_RATE_11] = RATE111_11, + [DOT11_RATE_22] = RATE111_22, + /* [DOT11_RATE_33] = */ + [DOT11_RATE_6 ] = RATE111_6 , + [DOT11_RATE_9 ] = RATE111_9 , + [DOT11_RATE_12] = RATE111_12, + [DOT11_RATE_18] = RATE111_18, + [DOT11_RATE_24] = RATE111_24, + [DOT11_RATE_36] = RATE111_36, + [DOT11_RATE_48] = RATE111_48, + [DOT11_RATE_54] = RATE111_54, +}; + +static u32 +acx111_gen_mask(int mbit, int modulation, void *opaque) +{ + /* lower 16 bits show selected 1, 2, CCK and OFDM rates */ + /* upper 16 bits show selected PBCC rates */ + u32 m = acx111mask[rate_mbit2enum(mbit)]; + if (modulation==DOT11_MOD_PBCC) + return m<<16; + return m; +} + +static int +verify_rate(u32 rate, int chip_type) +{ + /* never happens. be paranoid */ + if (!rate) return -EINVAL; + + /* disallow: mixing PBCC and CCK at 5 and 11Mbit + ** (can be supported, but needs complicated handling in tx code) */ + if (( rate & ((RATE111_11+RATE111_5)<<16) ) + && ( rate & (RATE111_11+RATE111_5) ) + ) { + return -ENOTSUPP; + } + if (CHIPTYPE_ACX100 == chip_type) { + if ( rate & ~(RATE111_ACX100_COMPAT+(RATE111_ACX100_COMPAT<<16)) ) + return -ENOTSUPP; + } + return 0; +} + +static int +acx_ioctl_set_rates(struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + unsigned long flags; + int result; + u32 brate = 0, orate = 0; /* basic, operational rate set */ + + FN_ENTER; + + log(L_IOCTL, "set_rates %s\n", extra); + result = fill_ratemasks(extra, &brate, &orate, + acx111_supported, acx111_gen_mask, 0); + if (result) goto end; + SET_BIT(orate, brate); + log(L_IOCTL, "brate %08X orate %08X\n", brate, orate); + + result = verify_rate(brate, adev->chip_type); + if (result) goto end; + result = verify_rate(orate, adev->chip_type); + if (result) goto end; + + acx_sem_lock(adev); + acx_lock(adev, flags); + + adev->rate_basic = brate; + adev->rate_oper = orate; + /* TODO: ideally, we shall monitor highest basic rate + ** which was successfully sent to every peer + ** (say, last we checked, everybody could hear 5.5 Mbits) + ** and use that for bcasts when we want to reach all peers. + ** For beacons, we probably shall use lowest basic rate + ** because we want to reach all *potential* new peers too */ + adev->rate_bcast = 1 << lowest_bit(brate); + if (IS_ACX100(adev)) + adev->rate_bcast100 = acx_rate111to100(adev->rate_bcast); + adev->rate_auto = !has_only_one_bit(orate); + acx_l_update_client_rates(adev, orate); + /* TODO: get rid of ratevector, build it only when needed */ + acx_l_update_ratevector(adev); + + /* Do/don't do tx rate fallback; beacon contents and rate */ + SET_BIT(adev->set_mask, SET_RATE_FALLBACK|SET_TEMPLATES); + result = -EINPROGRESS; + + acx_unlock(adev, flags); + acx_sem_unlock(adev); +end: + FN_EXIT1(result); + return result; +} + + +/*********************************************************************** +** acx_ioctl_get_phy_chan_busy_percentage +*/ +static int +acx_ioctl_get_phy_chan_busy_percentage( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + struct { + u16 type; + u16 len; + u32 busytime; + u32 totaltime; + } ACX_PACKED usage; + int result; + + acx_sem_lock(adev); + + if (OK != acx_s_interrogate(adev, &usage, ACX1xx_IE_MEDIUM_USAGE)) { + result = NOT_OK; + goto end_unlock; + } + + usage.busytime = le32_to_cpu(usage.busytime); + usage.totaltime = le32_to_cpu(usage.totaltime); + + /* yes, this is supposed to be "Medium" (singular of media), + not "average"! OK, reword the message to make it obvious... */ + printk("%s: busy percentage of medium (since last invocation): %d%% " + "(%u of %u microseconds)\n", + ndev->name, + usage.busytime / ((usage.totaltime / 100) + 1), + usage.busytime, usage.totaltime); + + result = OK; + +end_unlock: + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +** acx_ioctl_set_ed_threshold +*/ +static inline int +acx_ioctl_set_ed_threshold( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + printk("old ED threshold value: %d\n", adev->ed_threshold); + adev->ed_threshold = (unsigned char)*extra; + printk("new ED threshold value: %d\n", (unsigned char)*extra); + SET_BIT(adev->set_mask, GETSET_ED_THRESH); + + acx_sem_unlock(adev); + + return -EINPROGRESS; +} + + +/*********************************************************************** +** acx_ioctl_set_cca +*/ +static inline int +acx_ioctl_set_cca( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + + acx_sem_lock(adev); + + printk("old CCA value: 0x%02X\n", adev->cca); + adev->cca = (unsigned char)*extra; + printk("new CCA value: 0x%02X\n", (unsigned char)*extra); + SET_BIT(adev->set_mask, GETSET_CCA); + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +*/ +static const char * const +scan_modes[] = { "active", "passive", "background" }; + +static void +acx_print_scan_params(acx_device_t *adev, const char* head) +{ + printk("%s: %smode %d (%s), min chan time %dTU, " + "max chan time %dTU, max scan rate byte: %d\n", + adev->ndev->name, head, + adev->scan_mode, scan_modes[adev->scan_mode], + adev->scan_probe_delay, adev->scan_duration, adev->scan_rate); +} + +static int +acx_ioctl_set_scan_params( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + const int *params = (int *)extra; + + acx_sem_lock(adev); + + acx_print_scan_params(adev, "old scan parameters: "); + if ((params[0] != -1) && (params[0] >= 0) && (params[0] <= 2)) + adev->scan_mode = params[0]; + if (params[1] != -1) + adev->scan_probe_delay = params[1]; + if (params[2] != -1) + adev->scan_duration = params[2]; + if ((params[3] != -1) && (params[3] <= 255)) + adev->scan_rate = params[3]; + acx_print_scan_params(adev, "new scan parameters: "); + SET_BIT(adev->set_mask, GETSET_RESCAN); + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + return result; +} + +static int +acx_ioctl_get_scan_params( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + int result; + int *params = (int *)extra; + + acx_sem_lock(adev); + + acx_print_scan_params(adev, "current scan parameters: "); + params[0] = adev->scan_mode; + params[1] = adev->scan_probe_delay; + params[2] = adev->scan_duration; + params[3] = adev->scan_rate; + result = OK; + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +*/ +static int +acx100_ioctl_set_led_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + static const char * const led_modes[] = { "off", "on", "LinkQuality" }; + + acx_device_t *adev = ndev2adev(ndev); + int result; + + acx_sem_lock(adev); + + printk("%s: power LED status: old %d (%s), ", + ndev->name, + adev->led_power, + led_modes[adev->led_power]); + adev->led_power = extra[0]; + if (adev->led_power > 2) adev->led_power = 2; + printk("new %d (%s)\n", + adev->led_power, + led_modes[adev->led_power]); + + if (adev->led_power == 2) { + printk("%s: max link quality setting: old %d, ", + ndev->name, adev->brange_max_quality); + if (extra[1]) + adev->brange_max_quality = extra[1]; + printk("new %d\n", adev->brange_max_quality); + } + + SET_BIT(adev->set_mask, GETSET_LED_POWER); + + result = -EINPROGRESS; + + acx_sem_unlock(adev); + + return result; +} + + +/*********************************************************************** +*/ +static inline int +acx100_ioctl_get_led_power( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + acx_device_t *adev = ndev2adev(ndev); + + acx_sem_lock(adev); + + extra[0] = adev->led_power; + if (adev->led_power == 2) + extra[1] = adev->brange_max_quality; + else + extra[1] = -1; + + acx_sem_unlock(adev); + + return OK; +} + + +/*********************************************************************** +*/ +static int +acx111_ioctl_info( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + if (!IS_PCI(ndev2adev(ndev))) + return OK; + return acx111pci_ioctl_info(ndev, info, vwrq, extra); +} + + +/*********************************************************************** +*/ +static int +acx100_ioctl_set_phy_amp_bias( + struct net_device *ndev, + struct iw_request_info *info, + union iwreq_data *wrqu, + char *extra) +{ + struct iw_param *vwrq = &wrqu->param; + if (!IS_PCI(ndev2adev(ndev))) { + printk("acx: set_phy_amp_bias() is not supported on USB\n"); + return OK; + } + return acx100pci_ioctl_set_phy_amp_bias(ndev, info, vwrq, extra); +} + + +/*********************************************************************** +*/ +static const iw_handler acx_ioctl_handler[] = +{ + acx_ioctl_commit, /* SIOCSIWCOMMIT */ + acx_ioctl_get_name, /* SIOCGIWNAME */ + NULL, /* SIOCSIWNWID */ + NULL, /* SIOCGIWNWID */ + acx_ioctl_set_freq, /* SIOCSIWFREQ */ + acx_ioctl_get_freq, /* SIOCGIWFREQ */ + acx_ioctl_set_mode, /* SIOCSIWMODE */ + acx_ioctl_get_mode, /* SIOCGIWMODE */ + acx_ioctl_set_sens, /* SIOCSIWSENS */ + acx_ioctl_get_sens, /* SIOCGIWSENS */ + NULL, /* SIOCSIWRANGE */ + acx_ioctl_get_range, /* SIOCGIWRANGE */ + NULL, /* SIOCSIWPRIV */ + NULL, /* SIOCGIWPRIV */ + NULL, /* SIOCSIWSTATS */ + NULL, /* SIOCGIWSTATS */ +#if IW_HANDLER_VERSION > 4 + iw_handler_set_spy, /* SIOCSIWSPY */ + iw_handler_get_spy, /* SIOCGIWSPY */ + iw_handler_set_thrspy, /* SIOCSIWTHRSPY */ + iw_handler_get_thrspy, /* SIOCGIWTHRSPY */ +#else /* IW_HANDLER_VERSION > 4 */ +#ifdef WIRELESS_SPY + NULL /* acx_ioctl_set_spy FIXME */, /* SIOCSIWSPY */ + NULL /* acx_ioctl_get_spy */, /* SIOCGIWSPY */ +#else /* WSPY */ + NULL, /* SIOCSIWSPY */ + NULL, /* SIOCGIWSPY */ +#endif /* WSPY */ + NULL, /* [nothing] */ + NULL, /* [nothing] */ +#endif /* IW_HANDLER_VERSION > 4 */ + acx_ioctl_set_ap, /* SIOCSIWAP */ + acx_ioctl_get_ap, /* SIOCGIWAP */ + NULL, /* [nothing] */ + acx_ioctl_get_aplist, /* SIOCGIWAPLIST */ + acx_ioctl_set_scan, /* SIOCSIWSCAN */ + acx_ioctl_get_scan, /* SIOCGIWSCAN */ + acx_ioctl_set_essid, /* SIOCSIWESSID */ + acx_ioctl_get_essid, /* SIOCGIWESSID */ + acx_ioctl_set_nick, /* SIOCSIWNICKN */ + acx_ioctl_get_nick, /* SIOCGIWNICKN */ + NULL, /* [nothing] */ + NULL, /* [nothing] */ + acx_ioctl_set_rate, /* SIOCSIWRATE */ + acx_ioctl_get_rate, /* SIOCGIWRATE */ + acx_ioctl_set_rts, /* SIOCSIWRTS */ + acx_ioctl_get_rts, /* SIOCGIWRTS */ +#if ACX_FRAGMENTATION + acx_ioctl_set_frag, /* SIOCSIWFRAG */ + acx_ioctl_get_frag, /* SIOCGIWFRAG */ +#else + NULL, /* SIOCSIWFRAG */ + NULL, /* SIOCGIWFRAG */ +#endif + acx_ioctl_set_txpow, /* SIOCSIWTXPOW */ + acx_ioctl_get_txpow, /* SIOCGIWTXPOW */ + acx_ioctl_set_retry, /* SIOCSIWRETRY */ + acx_ioctl_get_retry, /* SIOCGIWRETRY */ + acx_ioctl_set_encode, /* SIOCSIWENCODE */ + acx_ioctl_get_encode, /* SIOCGIWENCODE */ + acx_ioctl_set_power, /* SIOCSIWPOWER */ + acx_ioctl_get_power, /* SIOCGIWPOWER */ +}; + + +/*********************************************************************** +*/ + +/* if you plan to reorder something, make sure to reorder all other places + * accordingly! */ +/* SET/GET convention: SETs must have even position, GETs odd */ +#define ACX100_IOCTL SIOCIWFIRSTPRIV +enum { + ACX100_IOCTL_DEBUG = ACX100_IOCTL, + ACX100_IOCTL_GET__________UNUSED1, + ACX100_IOCTL_SET_PLED, + ACX100_IOCTL_GET_PLED, + ACX100_IOCTL_SET_RATES, + ACX100_IOCTL_LIST_DOM, + ACX100_IOCTL_SET_DOM, + ACX100_IOCTL_GET_DOM, + ACX100_IOCTL_SET_SCAN_PARAMS, + ACX100_IOCTL_GET_SCAN_PARAMS, + ACX100_IOCTL_SET_PREAMB, + ACX100_IOCTL_GET_PREAMB, + ACX100_IOCTL_SET_ANT, + ACX100_IOCTL_GET_ANT, + ACX100_IOCTL_RX_ANT, + ACX100_IOCTL_TX_ANT, + ACX100_IOCTL_SET_PHY_AMP_BIAS, + ACX100_IOCTL_GET_PHY_CHAN_BUSY, + ACX100_IOCTL_SET_ED, + ACX100_IOCTL_GET__________UNUSED3, + ACX100_IOCTL_SET_CCA, + ACX100_IOCTL_GET__________UNUSED4, + ACX100_IOCTL_MONITOR, + ACX100_IOCTL_TEST, + ACX100_IOCTL_DBG_SET_MASKS, + ACX111_IOCTL_INFO, + ACX100_IOCTL_DBG_SET_IO, + ACX100_IOCTL_DBG_GET_IO +}; + + +static const iw_handler acx_ioctl_private_handler[] = +{ +#if ACX_DEBUG +[ACX100_IOCTL_DEBUG - ACX100_IOCTL] = acx_ioctl_set_debug, +#endif +[ACX100_IOCTL_SET_PLED - ACX100_IOCTL] = acx100_ioctl_set_led_power, +[ACX100_IOCTL_GET_PLED - ACX100_IOCTL] = acx100_ioctl_get_led_power, +[ACX100_IOCTL_SET_RATES - ACX100_IOCTL] = acx_ioctl_set_rates, +[ACX100_IOCTL_LIST_DOM - ACX100_IOCTL] = acx_ioctl_list_reg_domain, +[ACX100_IOCTL_SET_DOM - ACX100_IOCTL] = acx_ioctl_set_reg_domain, +[ACX100_IOCTL_GET_DOM - ACX100_IOCTL] = acx_ioctl_get_reg_domain, +[ACX100_IOCTL_SET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_set_scan_params, +[ACX100_IOCTL_GET_SCAN_PARAMS - ACX100_IOCTL] = acx_ioctl_get_scan_params, +[ACX100_IOCTL_SET_PREAMB - ACX100_IOCTL] = acx_ioctl_set_short_preamble, +[ACX100_IOCTL_GET_PREAMB - ACX100_IOCTL] = acx_ioctl_get_short_preamble, +[ACX100_IOCTL_SET_ANT - ACX100_IOCTL] = acx_ioctl_set_antenna, +[ACX100_IOCTL_GET_ANT - ACX100_IOCTL] = acx_ioctl_get_antenna, +[ACX100_IOCTL_RX_ANT - ACX100_IOCTL] = acx_ioctl_set_rx_antenna, +[ACX100_IOCTL_TX_ANT - ACX100_IOCTL] = acx_ioctl_set_tx_antenna, +[ACX100_IOCTL_SET_PHY_AMP_BIAS - ACX100_IOCTL] = acx100_ioctl_set_phy_amp_bias, +[ACX100_IOCTL_GET_PHY_CHAN_BUSY - ACX100_IOCTL] = acx_ioctl_get_phy_chan_busy_percentage, +[ACX100_IOCTL_SET_ED - ACX100_IOCTL] = acx_ioctl_set_ed_threshold, +[ACX100_IOCTL_SET_CCA - ACX100_IOCTL] = acx_ioctl_set_cca, +[ACX100_IOCTL_MONITOR - ACX100_IOCTL] = acx_ioctl_wlansniff, +[ACX100_IOCTL_TEST - ACX100_IOCTL] = acx_ioctl_unknown11, +[ACX100_IOCTL_DBG_SET_MASKS - ACX100_IOCTL] = acx_ioctl_dbg_set_masks, +[ACX111_IOCTL_INFO - ACX100_IOCTL] = acx111_ioctl_info, +}; + + +static const struct iw_priv_args acx_ioctl_private_args[] = { +#if ACX_DEBUG +{ cmd : ACX100_IOCTL_DEBUG, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetDebug" }, +#endif +{ cmd : ACX100_IOCTL_SET_PLED, + set_args : IW_PRIV_TYPE_BYTE | 2, + get_args : 0, + name : "SetLEDPower" }, +{ cmd : ACX100_IOCTL_GET_PLED, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 2, + name : "GetLEDPower" }, +{ cmd : ACX100_IOCTL_SET_RATES, + set_args : IW_PRIV_TYPE_CHAR | 256, + get_args : 0, + name : "SetRates" }, +{ cmd : ACX100_IOCTL_LIST_DOM, + set_args : 0, + get_args : 0, + name : "ListRegDomain" }, +{ cmd : ACX100_IOCTL_SET_DOM, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetRegDomain" }, +{ cmd : ACX100_IOCTL_GET_DOM, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + name : "GetRegDomain" }, +{ cmd : ACX100_IOCTL_SET_SCAN_PARAMS, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + get_args : 0, + name : "SetScanParams" }, +{ cmd : ACX100_IOCTL_GET_SCAN_PARAMS, + set_args : 0, + get_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + name : "GetScanParams" }, +{ cmd : ACX100_IOCTL_SET_PREAMB, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetSPreamble" }, +{ cmd : ACX100_IOCTL_GET_PREAMB, + set_args : 0, + get_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + name : "GetSPreamble" }, +{ cmd : ACX100_IOCTL_SET_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetAntenna" }, +{ cmd : ACX100_IOCTL_GET_ANT, + set_args : 0, + get_args : 0, + name : "GetAntenna" }, +{ cmd : ACX100_IOCTL_RX_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetRxAnt" }, +{ cmd : ACX100_IOCTL_TX_ANT, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetTxAnt" }, +{ cmd : ACX100_IOCTL_SET_PHY_AMP_BIAS, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetPhyAmpBias"}, +{ cmd : ACX100_IOCTL_GET_PHY_CHAN_BUSY, + set_args : 0, + get_args : 0, + name : "GetPhyChanBusy" }, +{ cmd : ACX100_IOCTL_SET_ED, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetED" }, +{ cmd : ACX100_IOCTL_SET_CCA, + set_args : IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, + get_args : 0, + name : "SetCCA" }, +{ cmd : ACX100_IOCTL_MONITOR, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + get_args : 0, + name : "monitor" }, +{ cmd : ACX100_IOCTL_TEST, + set_args : 0, + get_args : 0, + name : "Test" }, +{ cmd : ACX100_IOCTL_DBG_SET_MASKS, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, + get_args : 0, + name : "DbgSetMasks" }, +{ cmd : ACX111_IOCTL_INFO, + set_args : 0, + get_args : 0, + name : "GetAcx111Info" }, +{ cmd : ACX100_IOCTL_DBG_SET_IO, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 4, + get_args : 0, + name : "DbgSetIO" }, +{ cmd : ACX100_IOCTL_DBG_GET_IO, + set_args : IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, + get_args : 0, + name : "DbgGetIO" }, +}; + + +const struct iw_handler_def acx_ioctl_handler_def = +{ + .num_standard = VEC_SIZE(acx_ioctl_handler), + .num_private = VEC_SIZE(acx_ioctl_private_handler), + .num_private_args = VEC_SIZE(acx_ioctl_private_args), + .standard = (iw_handler *) acx_ioctl_handler, + .private = (iw_handler *) acx_ioctl_private_handler, + .private_args = (struct iw_priv_args *) acx_ioctl_private_args, +#if IW_HANDLER_VERSION > 5 + .get_wireless_stats = acx_e_get_wireless_stats +#endif /* IW > 5 */ +}; --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx.h @@ -0,0 +1,6 @@ +#include "acx_config.h" +#include "wlan_compat.h" +#include "wlan_hdr.h" +#include "wlan_mgmt.h" +#include "acx_struct.h" +#include "acx_func.h" --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/acx_config.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/acx_config.h @@ -0,0 +1,41 @@ +/* Driver version */ +#define ACX_RELEASE "v0.3.36" + +/* set to 0 if you don't want any debugging code to be compiled in */ +/* set to 1 if you want some debugging */ +/* set to 2 if you want extensive debug log */ +#define ACX_DEBUG 0 +#define ACX_DEFAULT_MSG (L_ASSOC|L_INIT) + +/* assume 32bit I/O width + * (16bit is also compatible with Compact Flash) */ +#define ACX_IO_WIDTH 32 + +/* Set this to 1 if you want monitor mode to use + * phy header. Currently it is not useful anyway since we + * don't know what useful info (if any) is in phy header. + * If you want faster/smaller code, say 0 here */ +#define WANT_PHY_HDR 0 + +/* whether to do Tx descriptor cleanup in softirq (i.e. not in IRQ + * handler) or not. Note that doing it later does slightly increase + * system load, so still do that stuff in the IRQ handler for now, + * even if that probably means worse latency */ +#define TX_CLEANUP_IN_SOFTIRQ 0 + +/* if you want very experimental 802.11 power save mode features */ +#define POWER_SAVE_80211 0 + +/* if you want very early packet fragmentation bits and pieces */ +#define ACX_FRAGMENTATION 0 + +/* Locking: */ +/* very talkative */ +/* #define PARANOID_LOCKING 1 */ +/* normal (use when bug-free) */ +#define DO_LOCKING 1 +/* else locking is disabled! */ + +/* 0 - normal mode */ +/* 1 - development/debug: probe for IEs on modprobe */ +#define CMD_DISCOVERY 0 --- linux-2.6.28.orig/ubuntu/misc/wireless/acx/wlan_compat.h +++ linux-2.6.28/ubuntu/misc/wireless/acx/wlan_compat.h @@ -0,0 +1,264 @@ +/*********************************************************************** +** Copyright (C) 2003 ACX100 Open Source Project +** +** The contents of this file are subject to the Mozilla Public +** License Version 1.1 (the "License"); you may not use this file +** except in compliance with the License. You may obtain a copy of +** the License at http://www.mozilla.org/MPL/ +** +** Software distributed under the License is distributed on an "AS +** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +** implied. See the License for the specific language governing +** rights and limitations under the License. +** +** Alternatively, the contents of this file may be used under the +** terms of the GNU Public License version 2 (the "GPL"), in which +** case the provisions of the GPL are applicable instead of the +** above. If you wish to allow the use of your version of this file +** only under the terms of the GPL and not to allow others to use +** your version of this file under the MPL, indicate your decision +** by deleting the provisions above and replace them with the notice +** and other provisions required by the GPL. If you do not delete +** the provisions above, a recipient may use your version of this +** file under either the MPL or the GPL. +** --------------------------------------------------------------------- +** Inquiries regarding the ACX100 Open Source Project can be +** made directly to: +** +** acx100-users@lists.sf.net +** http://acx100.sf.net +** --------------------------------------------------------------------- +*/ + +/*********************************************************************** +** This code is based on elements which are +** Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +** info@linux-wlan.com +** http://www.linux-wlan.com +*/ + +/*=============================================================*/ +/*------ Establish Platform Identity --------------------------*/ +/*=============================================================*/ +/* Key macros: */ +/* WLAN_CPU_FAMILY */ +#define WLAN_Ix86 1 +#define WLAN_PPC 2 +#define WLAN_Ix96 3 +#define WLAN_ARM 4 +#define WLAN_ALPHA 5 +#define WLAN_MIPS 6 +#define WLAN_HPPA 7 +#define WLAN_SPARC 8 +#define WLAN_SH 9 +#define WLAN_x86_64 10 +#define WLAN_IA64 11 +/* WLAN_CPU_CORE */ +#define WLAN_I386CORE 1 +#define WLAN_PPCCORE 2 +#define WLAN_I296 3 +#define WLAN_ARMCORE 4 +#define WLAN_ALPHACORE 5 +#define WLAN_MIPSCORE 6 +#define WLAN_HPPACORE 7 +/* WLAN_CPU_PART */ +#define WLAN_I386PART 1 +#define WLAN_MPC860 2 +#define WLAN_MPC823 3 +#define WLAN_I296SA 4 +#define WLAN_PPCPART 5 +#define WLAN_ARMPART 6 +#define WLAN_ALPHAPART 7 +#define WLAN_MIPSPART 8 +#define WLAN_HPPAPART 9 +/* WLAN_SYSARCH */ +#define WLAN_PCAT 1 +#define WLAN_MBX 2 +#define WLAN_RPX 3 +#define WLAN_LWARCH 4 +#define WLAN_PMAC 5 +#define WLAN_SKIFF 6 +#define WLAN_BITSY 7 +#define WLAN_ALPHAARCH 7 +#define WLAN_MIPSARCH 9 +#define WLAN_HPPAARCH 10 +/* WLAN_HOSTIF (generally set on the command line, not detected) */ +#define WLAN_PCMCIA 1 +#define WLAN_ISA 2 +#define WLAN_PCI 3 +#define WLAN_USB 4 +#define WLAN_PLX 5 + +/* Note: the PLX HOSTIF above refers to some vendors implementations for */ +/* PCI. It's a PLX chip that is a PCI to PCMCIA adapter, but it */ +/* isn't a real PCMCIA host interface adapter providing all the */ +/* card&socket services. */ + +#ifdef __powerpc__ +#ifndef __ppc__ +#define __ppc__ +#endif +#endif + +#if (defined(CONFIG_PPC) || defined(CONFIG_8xx)) +#ifndef __ppc__ +#define __ppc__ +#endif +#endif + +#if defined(__x86_64__) + #define WLAN_CPU_FAMILY WLAN_x86_64 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined (__ia64__) + #define WLAN_CPU_FAMILY WLAN_IA64 + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) + #define WLAN_CPU_FAMILY WLAN_Ix86 + #define WLAN_CPU_CORE WLAN_I386CORE + #define WLAN_CPU_PART WLAN_I386PART + #define WLAN_SYSARCH WLAN_PCAT +#elif defined(__ppc__) + #define WLAN_CPU_FAMILY WLAN_PPC + #define WLAN_CPU_CORE WLAN_PPCCORE + #if defined(CONFIG_MBX) + #define WLAN_CPU_PART WLAN_MPC860 + #define WLAN_SYSARCH WLAN_MBX + #elif defined(CONFIG_RPXLITE) + #define WLAN_CPU_PART WLAN_MPC823 + #define WLAN_SYSARCH WLAN_RPX + #elif defined(CONFIG_RPXCLASSIC) + #define WLAN_CPU_PART WLAN_MPC860 + #define WLAN_SYSARCH WLAN_RPX + #else + #define WLAN_CPU_PART WLAN_PPCPART + #define WLAN_SYSARCH WLAN_PMAC + #endif +#elif defined(__arm__) + #define WLAN_CPU_FAMILY WLAN_ARM + #define WLAN_CPU_CORE WLAN_ARMCORE + #define WLAN_CPU_PART WLAN_ARM_PART + #define WLAN_SYSARCH WLAN_SKIFF +#elif defined(__alpha__) + #define WLAN_CPU_FAMILY WLAN_ALPHA + #define WLAN_CPU_CORE WLAN_ALPHACORE + #define WLAN_CPU_PART WLAN_ALPHAPART + #define WLAN_SYSARCH WLAN_ALPHAARCH +#elif defined(__mips__) + #define WLAN_CPU_FAMILY WLAN_MIPS + #define WLAN_CPU_CORE WLAN_MIPSCORE + #define WLAN_CPU_PART WLAN_MIPSPART + #define WLAN_SYSARCH WLAN_MIPSARCH +#elif defined(__hppa__) + #define WLAN_CPU_FAMILY WLAN_HPPA + #define WLAN_CPU_CORE WLAN_HPPACORE + #define WLAN_CPU_PART WLAN_HPPAPART + #define WLAN_SYSARCH WLAN_HPPAARCH +#elif defined(__sparc__) + #define WLAN_CPU_FAMILY WLAN_SPARC + #define WLAN_SYSARCH WLAN_SPARC +#elif defined(__sh__) + #define WLAN_CPU_FAMILY WLAN_SH + #define WLAN_SYSARCH WLAN_SHARCH + #ifndef __LITTLE_ENDIAN__ + #define __LITTLE_ENDIAN__ + #endif +#else + #error "No CPU identified!" +#endif + +/* + Some big endian machines implicitly do all I/O in little endian mode. + + In particular: + Linux/PPC on PowerMacs (PCI) + Arm/Intel Xscale (PCI) + + This may also affect PLX boards and other BE &| PPC platforms; + as new ones are discovered, add them below. +*/ + +#if ((WLAN_SYSARCH == WLAN_SKIFF) || (WLAN_SYSARCH == WLAN_PMAC)) +#define REVERSE_ENDIAN +#endif + +/*=============================================================*/ +/*------ Hardware Portability Macros --------------------------*/ +/*=============================================================*/ +#if (WLAN_CPU_FAMILY == WLAN_PPC) +#define wlan_inw(a) in_be16((unsigned short *)((a)+_IO_BASE)) +#define wlan_inw_le16_to_cpu(a) inw((a)) +#define wlan_outw(v,a) out_be16((unsigned short *)((a)+_IO_BASE), (v)) +#define wlan_outw_cpu_to_le16(v,a) outw((v),(a)) +#else +#define wlan_inw(a) inw((a)) +#define wlan_inw_le16_to_cpu(a) __cpu_to_le16(inw((a))) +#define wlan_outw(v,a) outw((v),(a)) +#define wlan_outw_cpu_to_le16(v,a) outw(__cpu_to_le16((v)),(a)) +#endif + +/*=============================================================*/ +/*------ Bit settings -----------------------------------------*/ +/*=============================================================*/ +#define ieee2host16(n) __le16_to_cpu(n) +#define ieee2host32(n) __le32_to_cpu(n) +#define host2ieee16(n) __cpu_to_le16(n) +#define host2ieee32(n) __cpu_to_le32(n) + +/* for constants */ +#ifdef __LITTLE_ENDIAN + #define IEEE16(a,n) a = n, a##i = n, +#else + #ifdef __BIG_ENDIAN + /* shifts would produce gcc warnings. Oh well... */ + #define IEEE16(a,n) a = n, a##i = ((n&0xff)*256 + ((n&0xff00)/256)), + #else + #error give me endianness or give me death + #endif +#endif + +/*=============================================================*/ +/*------ Compiler Portability Macros --------------------------*/ +/*=============================================================*/ +#define WLAN_PACKED __attribute__ ((packed)) + +/* Interrupt handler backwards compatibility stuff */ +#ifndef IRQ_NONE +#define IRQ_NONE +#define IRQ_HANDLED +typedef void irqreturn_t; +#endif + +#ifndef ARPHRD_IEEE80211_PRISM +#define ARPHRD_IEEE80211_PRISM 802 +#endif + +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) + +/*============================================================================* + * Constants * + *============================================================================*/ +#define WLAN_IEEE_OUI_LEN 3 + +/*============================================================================* + * Types * + *============================================================================*/ + +/* local ether header type */ +typedef struct wlan_ethhdr { + u8 daddr[ETH_ALEN]; + u8 saddr[ETH_ALEN]; + u16 type; +} WLAN_PACKED wlan_ethhdr_t; + +/* local llc header type */ +typedef struct wlan_llc { + u8 dsap; + u8 ssap; + u8 ctl; +} WLAN_PACKED wlan_llc_t; + +/* local snap header type */ +typedef struct wlan_snap { + u8 oui[WLAN_IEEE_OUI_LEN]; + u16 type; +} WLAN_PACKED wlan_snap_t; --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2_usb.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2_usb.c @@ -0,0 +1,367 @@ +#define WLAN_HOSTIF WLAN_USB +#include "hfa384x_usb.c" +#include "prism2mgmt.c" +#include "prism2mib.c" +#include "prism2sta.c" + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) +#error "prism2_usb requires at least a 2.4.x kernel!" +#endif + +#define PRISM_USB_DEVICE(vid, pid, name) \ + USB_DEVICE(vid, pid), \ + .driver_info = (unsigned long) name + +static struct usb_device_id usb_prism_tbl[] = { + {PRISM_USB_DEVICE(0x0707, 0xee04, "Intersil Americas USB 802.11b WLAN DEVICE")}, + {PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")}, + {PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")}, + {PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x049f, 0x0033, "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")}, + {PRISM_USB_DEVICE(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")}, + {PRISM_USB_DEVICE(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")}, + {PRISM_USB_DEVICE(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")}, + {PRISM_USB_DEVICE(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")}, + {PRISM_USB_DEVICE(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")}, + {PRISM_USB_DEVICE(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")}, + {PRISM_USB_DEVICE(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")}, + {PRISM_USB_DEVICE(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")}, + {PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")}, + {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")}, +// {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")}, + {PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")}, + {PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")}, + {PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")}, + {PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")}, + {PRISM_USB_DEVICE(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")}, + {PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")}, + {PRISM_USB_DEVICE(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")}, + {PRISM_USB_DEVICE(0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")}, + { /* terminator */ } +}; + +MODULE_DEVICE_TABLE(usb, usb_prism_tbl); + +/*---------------------------------------------------------------- +* prism2sta_probe_usb +* +* Probe routine called by the USB subsystem. +* +* Arguments: +* dev ptr to the usb_device struct +* ifnum interface number being offered +* +* Returns: +* NULL - we're not claiming the device+interface +* non-NULL - we are claiming the device+interface and +* this is a ptr to the data we want back +* when disconnect is called. +* +* Side effects: +* +* Call context: +* I'm not sure, assume it's interrupt. +* +----------------------------------------------------------------*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static void __devinit *prism2sta_probe_usb( + struct usb_device *dev, + unsigned int ifnum, + const struct usb_device_id *id) +#else +static int prism2sta_probe_usb( + struct usb_interface *interface, + const struct usb_device_id *id) +#endif +{ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct usb_interface *interface; +#else + struct usb_device *dev; +#endif + + wlandevice_t *wlandev = NULL; + hfa384x_t *hw = NULL; + int result = 0; + + DBFENTER; + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + interface = &dev->actconfig->interface[ifnum]; +#else + dev = interface_to_usbdev(interface); +#endif + + + if ((wlandev = create_wlan()) == NULL) { + WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info); + result = -EIO; + goto failed; + } + hw = wlandev->priv; + + if ( wlan_setup(wlandev) != 0 ) { + WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info); + result = -EIO; + goto failed; + } + + /* Initialize the hw data */ + hfa384x_create(hw, dev); + hw->wlandev = wlandev; + + SET_MODULE_OWNER(wlandev->netdev); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) + SET_NETDEV_DEV(wlandev->netdev, &(interface->dev)); +#endif + + /* Do a chip-level reset on the MAC */ + if (prism2_doreset) { + result = hfa384x_corereset(hw, + prism2_reset_holdtime, + prism2_reset_settletime, 0); + if (result != 0) { + hfa384x_destroy(hw); + result = -EIO; + WLAN_LOG_ERROR( + "%s: hfa384x_corereset() failed.\n", + dev_info); + goto failed; + } + } + +#ifndef NEW_MODULE_CODE + usb_inc_dev_use(dev); +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + usb_get_dev(dev); +#endif + + wlandev->msdstate = WLAN_MSD_HWPRESENT; + + /* Register the wlandev, this gets us a name and registers the + * linux netdevice. + */ + if ( register_wlandev(wlandev) != 0 ) { + WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info); + result = -EIO; + goto failed; + } + + if (wlan_wext_write) + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable); + + goto done; + + failed: + if (wlandev) kfree(wlandev); + if (hw) kfree(hw); + wlandev = NULL; + + done: + DBFEXIT; + + p80211_allow_ioctls(wlandev); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + return wlandev; +#else + usb_set_intfdata(interface, wlandev); + return result; +#endif +} + + +/*---------------------------------------------------------------- +* prism2sta_disconnect_usb +* +* Called when a device previously claimed by probe is removed +* from the USB. +* +* Arguments: +* dev ptr to the usb_device struct +* ptr ptr returned by probe() when the device +* was claimed. +* +* Returns: +* Nothing +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +static void __devexit +prism2sta_disconnect_usb(struct usb_device *dev, void *ptr) +#else +static void +prism2sta_disconnect_usb(struct usb_interface *interface) +#endif +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + wlandevice_t *wlandev; +#else + wlandevice_t *wlandev = (wlandevice_t*)ptr; +#endif + + DBFENTER; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + wlandev = (wlandevice_t *) usb_get_intfdata(interface); +#endif + + if ( wlandev != NULL ) { + LIST_HEAD(cleanlist); + struct list_head *entry; + struct list_head *temp; + unsigned long flags; + + hfa384x_t *hw = wlandev->priv; + + if (!hw) + goto exit; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + p80211netdev_hwremoved(wlandev); + list_splice_init(&hw->ctlxq.reapable, &cleanlist); + list_splice_init(&hw->ctlxq.completing, &cleanlist); + list_splice_init(&hw->ctlxq.pending, &cleanlist); + list_splice_init(&hw->ctlxq.active, &cleanlist); + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + /* There's no hardware to shutdown, but the driver + * might have some tasks or tasklets that must be + * stopped before we can tear everything down. + */ + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); + + del_singleshot_timer_sync(&hw->throttle); + del_singleshot_timer_sync(&hw->reqtimer); + del_singleshot_timer_sync(&hw->resptimer); + + /* Unlink all the URBs. This "removes the wheels" + * from the entire CTLX handling mechanism. + */ + usb_kill_urb(&hw->rx_urb); + usb_kill_urb(&hw->tx_urb); + usb_kill_urb(&hw->ctlx_urb); + + tasklet_kill(&hw->completion_bh); + tasklet_kill(&hw->reaper_bh); + + flush_scheduled_work(); + + /* Now we complete any outstanding commands + * and tell everyone who is waiting for their + * responses that we have shut down. + */ + list_for_each(entry, &cleanlist) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + complete(&ctlx->done); + } + + /* Give any outstanding synchronous commands + * a chance to complete. All they need to do + * is "wake up", so that's easy. + * (I'd like a better way to do this, really.) + */ + msleep(100); + + /* Now delete the CTLXs, because no-one else can now. */ + list_for_each_safe(entry, temp, &cleanlist) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + kfree(ctlx); + } + + /* Unhook the wlandev */ + unregister_wlandev(wlandev); + wlan_unsetup(wlandev); + +#ifndef NEW_MODULE_CODE + usb_dec_dev_use(hw->usb); +#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) + usb_put_dev(hw->usb); +#endif + + hfa384x_destroy(hw); + kfree(hw); + + kfree(wlandev); + } + + exit: + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)) + usb_set_intfdata(interface, NULL); +#endif + DBFEXIT; +} + + +static struct usb_driver prism2_usb_driver = { +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) + .owner = THIS_MODULE, +#endif + .name = "prism2_usb", + .probe = prism2sta_probe_usb, + .disconnect = prism2sta_disconnect_usb, + .id_table = usb_prism_tbl, + /* fops, minor? */ +}; + +#ifdef MODULE + +static int __init prism2usb_init(void) +{ + DBFENTER; + + WLAN_LOG_NOTICE("%s Loaded\n", version); + WLAN_LOG_NOTICE("dev_info is: %s\n", dev_info); + + /* This call will result in calls to prism2sta_probe_usb. */ + return usb_register(&prism2_usb_driver); + + DBFEXIT; +}; + +static void __exit prism2usb_cleanup(void) +{ + DBFENTER; + + usb_deregister(&prism2_usb_driver); + + printk(KERN_NOTICE "%s Unloaded\n", version); + + DBFEXIT; +}; + +module_init(prism2usb_init); +module_exit(prism2usb_cleanup); + +#endif // module --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/hfa384x_usb.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/hfa384x_usb.c @@ -0,0 +1,5068 @@ +/* src/prism2/driver/hfa384x_usb.c +* +* Functions that talk to the USB variantof the Intersil hfa384x MAC +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file implements functions that correspond to the prism2/hfa384x +* 802.11 MAC hardware and firmware host interface. +* +* The functions can be considered to represent several levels of +* abstraction. The lowest level functions are simply C-callable wrappers +* around the register accesses. The next higher level represents C-callable +* prism2 API functions that match the Intersil documentation as closely +* as is reasonable. The next higher layer implements common sequences +* of invokations of the API layer (e.g. write to bap, followed by cmd). +* +* Common sequences: +* hfa384x_drvr_xxx Highest level abstractions provided by the +* hfa384x code. They are driver defined wrappers +* for common sequences. These functions generally +* use the services of the lower levels. +* +* hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These +* functions are wrappers for the RID get/set +* sequence. They call copy_[to|from]_bap() and +* cmd_access(). These functions operate on the +* RIDs and buffers without validation. The caller +* is responsible for that. +* +* API wrapper functions: +* hfa384x_cmd_xxx functions that provide access to the f/w commands. +* The function arguments correspond to each command +* argument, even command arguments that get packed +* into single registers. These functions _just_ +* issue the command by setting the cmd/parm regs +* & reading the status/resp regs. Additional +* activities required to fully use a command +* (read/write from/to bap, get/set int status etc.) +* are implemented separately. Think of these as +* C-callable prism2 commands. +* +* Lowest Layer Functions: +* hfa384x_docmd_xxx These functions implement the sequence required +* to issue any prism2 command. Primarily used by the +* hfa384x_cmd_xxx functions. +* +* hfa384x_bap_xxx BAP read/write access functions. +* Note: we usually use BAP0 for non-interrupt context +* and BAP1 for interrupt context. +* +* hfa384x_dl_xxx download related functions. +* +* Driver State Issues: +* Note that there are two pairs of functions that manage the +* 'initialized' and 'running' states of the hw/MAC combo. The four +* functions are create(), destroy(), start(), and stop(). create() +* sets up the data structures required to support the hfa384x_* +* functions and destroy() cleans them up. The start() function gets +* the actual hardware running and enables the interrupts. The stop() +* function shuts the hardware down. The sequence should be: +* create() +* start() +* . +* . Do interesting things w/ the hardware +* . +* stop() +* destroy() +* +* Note that destroy() can be called without calling stop() first. +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if (WLAN_HOSTIF != WLAN_USB) +#error "This file is specific to USB" +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +static int +wait_for_completion_interruptible(struct completion *x) +{ + int ret = 0; + + might_sleep(); + + spin_lock_irq(&x->wait.lock); + if (!x->done) { + DECLARE_WAITQUEUE(wait, current); + + wait.flags |= WQ_FLAG_EXCLUSIVE; + __add_wait_queue_tail(&x->wait, &wait); + do { + if (signal_pending(current)) { + ret = -ERESTARTSYS; + __remove_wait_queue(&x->wait, &wait); + goto out; + } + __set_current_state(TASK_INTERRUPTIBLE); + spin_unlock_irq(&x->wait.lock); + schedule(); + spin_lock_irq(&x->wait.lock); + } while (!x->done); + __remove_wait_queue(&x->wait, &wait); + } + x->done--; +out: + spin_unlock_irq(&x->wait.lock); + + return ret; +} +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69) +static void +usb_init_urb(struct urb *urb) +{ + memset(urb, 0, sizeof(*urb)); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */ + urb->count = (atomic_t)ATOMIC_INIT(1); +#endif + spin_lock_init(&urb->lock); +} +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* tune me! */ +# define SUBMIT_URB(u,f) usb_submit_urb(u,f) +#else +# define SUBMIT_URB(u,f) usb_submit_urb(u) +#endif + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +enum cmd_mode +{ + DOWAIT = 0, + DOASYNC +}; +typedef enum cmd_mode CMD_MODE; + +#define THROTTLE_JIFFIES (HZ/8) + +/*================================================================*/ +/* Local Macros */ + +#define ROUNDUP64(a) (((a)+63)&~63) + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ +extern int prism2_debug; + +/*================================================================*/ +/* Local Function Declarations */ + +#ifdef DEBUG_USB +static void +dbprint_urb(struct urb* urb); +#endif + +static void +hfa384x_int_rxmonitor( + wlandevice_t *wlandev, + hfa384x_usb_rxfrm_t *rxfrm); + +static void +hfa384x_usb_defer(struct work_struct *data); + +static int +submit_rx_urb(hfa384x_t *hw, gfp_t flags); + +static int +submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags); + +/*---------------------------------------------------*/ +/* Callbacks */ +#ifdef URB_ONLY_CALLBACK +static void +hfa384x_usbout_callback(struct urb *urb); +static void +hfa384x_ctlxout_callback(struct urb *urb); +static void +hfa384x_usbin_callback(struct urb *urb); +#else +static void +hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs); +static void +hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs); +static void +hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs); +#endif + +static void +hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin); + +static void +hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb); + +static void +hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin); + +static void +hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout); + +static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin, + int urb_status); + +/*---------------------------------------------------*/ +/* Functions to support the prism2 usb command queue */ + +static void +hfa384x_usbctlxq_run(hfa384x_t *hw); + +static void +hfa384x_usbctlx_reqtimerfn(unsigned long data); + +static void +hfa384x_usbctlx_resptimerfn(unsigned long data); + +static void +hfa384x_usb_throttlefn(unsigned long data); + +static void +hfa384x_usbctlx_completion_task(unsigned long data); + +static void +hfa384x_usbctlx_reaper_task(unsigned long data); + +static int +hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); + +static void +unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); + +struct usbctlx_completor +{ + int (*complete)(struct usbctlx_completor*); +}; +typedef struct usbctlx_completor usbctlx_completor_t; + +static int +hfa384x_usbctlx_complete_sync(hfa384x_t *hw, + hfa384x_usbctlx_t *ctlx, + usbctlx_completor_t *completor); + +static int +unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx); + +static void +hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx); + +static void +hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx); + +static int +usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp, + hfa384x_cmdresult_t *result); + +static void +usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp, + hfa384x_rridresult_t *result); + +/*---------------------------------------------------*/ +/* Low level req/resp CTLX formatters and submitters */ +static int +hfa384x_docmd( + hfa384x_t *hw, + CMD_MODE mode, + hfa384x_metacmd_t *cmd, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dorrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dowrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dormem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_dowmem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data); + +static int +hfa384x_isgood_pdrcode(UINT16 pdrcode); + +/*================================================================*/ +/* Function Definitions */ +static inline const char* ctlxstr(CTLX_STATE s) +{ + static const char* ctlx_str[] = { + "Initial state", + "Complete", + "Request failed", + "Request pending", + "Request packet submitted", + "Request packet completed", + "Response packet completed" + }; + + return ctlx_str[s]; +}; + + +static inline hfa384x_usbctlx_t* +get_active_ctlx(hfa384x_t *hw) +{ + return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list); +} + + +#ifdef DEBUG_USB +void +dbprint_urb(struct urb* urb) +{ + WLAN_LOG_DEBUG(3,"urb->pipe=0x%08x\n", urb->pipe); + WLAN_LOG_DEBUG(3,"urb->status=0x%08x\n", urb->status); + WLAN_LOG_DEBUG(3,"urb->transfer_flags=0x%08x\n", urb->transfer_flags); + WLAN_LOG_DEBUG(3,"urb->transfer_buffer=0x%08x\n", (UINT)urb->transfer_buffer); + WLAN_LOG_DEBUG(3,"urb->transfer_buffer_length=0x%08x\n", urb->transfer_buffer_length); + WLAN_LOG_DEBUG(3,"urb->actual_length=0x%08x\n", urb->actual_length); + WLAN_LOG_DEBUG(3,"urb->bandwidth=0x%08x\n", urb->bandwidth); + WLAN_LOG_DEBUG(3,"urb->setup_packet(ctl)=0x%08x\n", (UINT)urb->setup_packet); + WLAN_LOG_DEBUG(3,"urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame); + WLAN_LOG_DEBUG(3,"urb->interval(irq)=0x%08x\n", urb->interval); + WLAN_LOG_DEBUG(3,"urb->error_count(iso)=0x%08x\n", urb->error_count); + WLAN_LOG_DEBUG(3,"urb->timeout=0x%08x\n", urb->timeout); + WLAN_LOG_DEBUG(3,"urb->context=0x%08x\n", (UINT)urb->context); + WLAN_LOG_DEBUG(3,"urb->complete=0x%08x\n", (UINT)urb->complete); +} +#endif + + +/*---------------------------------------------------------------- +* submit_rx_urb +* +* Listen for input data on the BULK-IN pipe. If the pipe has +* stalled then schedule it to be reset. +* +* Arguments: +* hw device struct +* memflags memory allocation flags +* +* Returns: +* error code from submission +* +* Call context: +* Any +----------------------------------------------------------------*/ +static int +submit_rx_urb(hfa384x_t *hw, gfp_t memflags) +{ + struct sk_buff *skb; + int result; + + DBFENTER; + + skb = dev_alloc_skb(sizeof(hfa384x_usbin_t)); + if (skb == NULL) { + result = -ENOMEM; + goto done; + } + + /* Post the IN urb */ + usb_fill_bulk_urb(&hw->rx_urb, hw->usb, + hw->endp_in, + skb->data, sizeof(hfa384x_usbin_t), + hfa384x_usbin_callback, hw->wlandev); + + hw->rx_urb_skb = skb; + + result = -ENOLINK; + if ( !hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) { + result = SUBMIT_URB(&hw->rx_urb, memflags); + + /* Check whether we need to reset the RX pipe */ + if (result == -EPIPE) { + WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n", + hw->wlandev->netdev->name); + if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) + schedule_work(&hw->usb_work); + } + } + + /* Don't leak memory if anything should go wrong */ + if (result != 0) { + dev_kfree_skb(skb); + hw->rx_urb_skb = NULL; + } + + done: + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* submit_tx_urb +* +* Prepares and submits the URB of transmitted data. If the +* submission fails then it will schedule the output pipe to +* be reset. +* +* Arguments: +* hw device struct +* tx_urb URB of data for tranmission +* memflags memory allocation flags +* +* Returns: +* error code from submission +* +* Call context: +* Any +----------------------------------------------------------------*/ +static int +submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags) +{ + struct net_device *netdev = hw->wlandev->netdev; + int result; + + DBFENTER; + + result = -ENOLINK; + if ( netif_running(netdev) ) { + + if ( !hw->wlandev->hwremoved && !test_bit(WORK_TX_HALT, &hw->usb_flags) ) { + result = SUBMIT_URB(tx_urb, memflags); + + /* Test whether we need to reset the TX pipe */ + if (result == -EPIPE) { + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + netdev->name); + set_bit(WORK_TX_HALT, &hw->usb_flags); + schedule_work(&hw->usb_work); + } else if (result == 0) { + netif_stop_queue(netdev); + } + } + } + + DBFEXIT; + + return result; +} + +/*---------------------------------------------------------------- +* hfa394x_usb_defer +* +* There are some things that the USB stack cannot do while +* in interrupt context, so we arrange this function to run +* in process context. +* +* Arguments: +* hw device structure +* +* Returns: +* nothing +* +* Call context: +* process (by design) +----------------------------------------------------------------*/ +static void +hfa384x_usb_defer(struct work_struct *data) +{ + hfa384x_t *hw = container_of(data, struct hfa384x, usb_work); + struct net_device *netdev = hw->wlandev->netdev; + + DBFENTER; + + /* Don't bother trying to reset anything if the plug + * has been pulled ... + */ + if ( hw->wlandev->hwremoved ) { + DBFEXIT; + return; + } + + /* Reception has stopped: try to reset the input pipe */ + if (test_bit(WORK_RX_HALT, &hw->usb_flags)) { + int ret; + + usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */ + + ret = usb_clear_halt(hw->usb, hw->endp_in); + if (ret != 0) { + printk(KERN_ERR + "Failed to clear rx pipe for %s: err=%d\n", + netdev->name, ret); + } else { + printk(KERN_INFO "%s rx pipe reset complete.\n", + netdev->name); + clear_bit(WORK_RX_HALT, &hw->usb_flags); + set_bit(WORK_RX_RESUME, &hw->usb_flags); + } + } + + /* Resume receiving data back from the device. */ + if ( test_bit(WORK_RX_RESUME, &hw->usb_flags) ) { + int ret; + + ret = submit_rx_urb(hw, GFP_KERNEL); + if (ret != 0) { + printk(KERN_ERR + "Failed to resume %s rx pipe.\n", netdev->name); + } else { + clear_bit(WORK_RX_RESUME, &hw->usb_flags); + } + } + + /* Transmission has stopped: try to reset the output pipe */ + if (test_bit(WORK_TX_HALT, &hw->usb_flags)) { + int ret; + + usb_kill_urb(&hw->tx_urb); + ret = usb_clear_halt(hw->usb, hw->endp_out); + if (ret != 0) { + printk(KERN_ERR + "Failed to clear tx pipe for %s: err=%d\n", + netdev->name, ret); + } else { + printk(KERN_INFO "%s tx pipe reset complete.\n", + netdev->name); + clear_bit(WORK_TX_HALT, &hw->usb_flags); + set_bit(WORK_TX_RESUME, &hw->usb_flags); + + /* Stopping the BULK-OUT pipe also blocked + * us from sending any more CTLX URBs, so + * we need to re-run our queue ... + */ + hfa384x_usbctlxq_run(hw); + } + } + + /* Resume transmitting. */ + if ( test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags) ) { + p80211netdev_wake_queue(hw->wlandev); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_create +* +* Sets up the hfa384x_t data structure for use. Note this +* does _not_ intialize the actual hardware, just the data structures +* we use to keep track of its state. +* +* Arguments: +* hw device structure +* irq device irq number +* iobase i/o base address for register access +* membase memory base address for register access +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +void +hfa384x_create( hfa384x_t *hw, struct usb_device *usb) +{ + DBFENTER; + + memset(hw, 0, sizeof(hfa384x_t)); + hw->usb = usb; + + /* set up the endpoints */ + hw->endp_in = usb_rcvbulkpipe(usb, 1); + hw->endp_out = usb_sndbulkpipe(usb, 2); + + /* Set up the waitq */ + init_waitqueue_head(&hw->cmdq); + + /* Initialize the command queue */ + spin_lock_init(&hw->ctlxq.lock); + INIT_LIST_HEAD(&hw->ctlxq.pending); + INIT_LIST_HEAD(&hw->ctlxq.active); + INIT_LIST_HEAD(&hw->ctlxq.completing); + INIT_LIST_HEAD(&hw->ctlxq.reapable); + + /* Initialize the authentication queue */ + skb_queue_head_init(&hw->authq); + + tasklet_init(&hw->reaper_bh, + hfa384x_usbctlx_reaper_task, + (unsigned long)hw); + tasklet_init(&hw->completion_bh, + hfa384x_usbctlx_completion_task, + (unsigned long)hw); + INIT_WORK2(&hw->link_bh, prism2sta_processing_defer); + INIT_WORK2(&hw->usb_work, hfa384x_usb_defer); + + init_timer(&hw->throttle); + hw->throttle.function = hfa384x_usb_throttlefn; + hw->throttle.data = (unsigned long)hw; + + init_timer(&hw->resptimer); + hw->resptimer.function = hfa384x_usbctlx_resptimerfn; + hw->resptimer.data = (unsigned long)hw; + + init_timer(&hw->reqtimer); + hw->reqtimer.function = hfa384x_usbctlx_reqtimerfn; + hw->reqtimer.data = (unsigned long)hw; + + usb_init_urb(&hw->rx_urb); + usb_init_urb(&hw->tx_urb); + usb_init_urb(&hw->ctlx_urb); + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer); + init_timer(&hw->commsqual_timer); + hw->commsqual_timer.data = (unsigned long) hw; + hw->commsqual_timer.function = prism2sta_commsqual_timer; + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_destroy +* +* Partner to hfa384x_create(). This function cleans up the hw +* structure so that it can be freed by the caller using a simple +* kfree. Currently, this function is just a placeholder. If, at some +* point in the future, an hw in the 'shutdown' state requires a 'deep' +* kfree, this is where it should be done. Note that if this function +* is called on a _running_ hw structure, the drvr_stop() function is +* called. +* +* Arguments: +* hw device structure +* +* Returns: +* nothing, this function is not allowed to fail. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +void +hfa384x_destroy( hfa384x_t *hw) +{ + struct sk_buff *skb; + + DBFENTER; + + if ( hw->state == HFA384x_STATE_RUNNING ) { + hfa384x_drvr_stop(hw); + } + hw->state = HFA384x_STATE_PREINIT; + + if (hw->scanresults) { + kfree(hw->scanresults); + hw->scanresults = NULL; + } + + /* Now to clean out the auth queue */ + while ( (skb = skb_dequeue(&hw->authq)) ) { + dev_kfree_skb(skb); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- + */ +static hfa384x_usbctlx_t* usbctlx_alloc(void) +{ + hfa384x_usbctlx_t *ctlx; + + ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); + if (ctlx != NULL) + { + memset(ctlx, 0, sizeof(*ctlx)); + init_completion(&ctlx->done); + } + + return ctlx; +} + + +/*---------------------------------------------------------------- + * +----------------------------------------------------------------*/ +static int +usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp, + hfa384x_cmdresult_t *result) +{ + DBFENTER; + + result->status = hfa384x2host_16(cmdresp->status); + result->resp0 = hfa384x2host_16(cmdresp->resp0); + result->resp1 = hfa384x2host_16(cmdresp->resp1); + result->resp2 = hfa384x2host_16(cmdresp->resp2); + + WLAN_LOG_DEBUG(4, "cmdresult:status=0x%04x " + "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n", + result->status, + result->resp0, + result->resp1, + result->resp2); + + DBFEXIT; + return (result->status & HFA384x_STATUS_RESULT); +} + +static void +usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp, + hfa384x_rridresult_t *result) +{ + DBFENTER; + + result->rid = hfa384x2host_16(rridresp->rid); + result->riddata = rridresp->data; + result->riddata_len = ((hfa384x2host_16(rridresp->frmlen) - 1) * 2); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* Completor object: +* This completor must be passed to hfa384x_usbctlx_complete_sync() +* when processing a CTLX that returns a hfa384x_cmdresult_t structure. +----------------------------------------------------------------*/ +struct usbctlx_cmd_completor +{ + usbctlx_completor_t head; + + const hfa384x_usb_cmdresp_t *cmdresp; + hfa384x_cmdresult_t *result; +}; +typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t; + +static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head) +{ + usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t*)head; + return usbctlx_get_status(complete->cmdresp, complete->result); +} + +static inline usbctlx_completor_t* +init_cmd_completor(usbctlx_cmd_completor_t *completor, + const hfa384x_usb_cmdresp_t *cmdresp, + hfa384x_cmdresult_t *result) +{ + completor->head.complete = usbctlx_cmd_completor_fn; + completor->cmdresp = cmdresp; + completor->result = result; + return &(completor->head); +} + +/*---------------------------------------------------------------- +* Completor object: +* This completor must be passed to hfa384x_usbctlx_complete_sync() +* when processing a CTLX that reads a RID. +----------------------------------------------------------------*/ +struct usbctlx_rrid_completor +{ + usbctlx_completor_t head; + + const hfa384x_usb_rridresp_t *rridresp; + void *riddata; + UINT riddatalen; +}; +typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t; + +static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head) +{ + usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t*)head; + hfa384x_rridresult_t rridresult; + + usbctlx_get_rridresult(complete->rridresp, &rridresult); + + /* Validate the length, note body len calculation in bytes */ + if ( rridresult.riddata_len != complete->riddatalen ) { + WLAN_LOG_WARNING( + "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n", + rridresult.rid, + complete->riddatalen, + rridresult.riddata_len); + return -ENODATA; + } + + memcpy(complete->riddata, + rridresult.riddata, + complete->riddatalen); + return 0; +} + +static inline usbctlx_completor_t* +init_rrid_completor(usbctlx_rrid_completor_t *completor, + const hfa384x_usb_rridresp_t *rridresp, + void *riddata, + UINT riddatalen) +{ + completor->head.complete = usbctlx_rrid_completor_fn; + completor->rridresp = rridresp; + completor->riddata = riddata; + completor->riddatalen = riddatalen; + return &(completor->head); +} + +/*---------------------------------------------------------------- +* Completor object: +* Interprets the results of a synchronous RID-write +----------------------------------------------------------------*/ +typedef usbctlx_cmd_completor_t usbctlx_wrid_completor_t; +#define init_wrid_completor init_cmd_completor + +/*---------------------------------------------------------------- +* Completor object: +* Interprets the results of a synchronous memory-write +----------------------------------------------------------------*/ +typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t; +#define init_wmem_completor init_cmd_completor + +/*---------------------------------------------------------------- +* Completor object: +* Interprets the results of a synchronous memory-read +----------------------------------------------------------------*/ +struct usbctlx_rmem_completor +{ + usbctlx_completor_t head; + + const hfa384x_usb_rmemresp_t *rmemresp; + void *data; + UINT len; +}; +typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t; + +static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head) +{ + usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t*)head; + + WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", complete->rmemresp->frmlen); + memcpy(complete->data, complete->rmemresp->data, complete->len); + return 0; +} + +static inline usbctlx_completor_t* +init_rmem_completor(usbctlx_rmem_completor_t *completor, + hfa384x_usb_rmemresp_t *rmemresp, + void *data, + UINT len) +{ + completor->head.complete = usbctlx_rmem_completor_fn; + completor->rmemresp = rmemresp; + completor->data = data; + completor->len = len; + return &(completor->head); +} + +/*---------------------------------------------------------------- +* hfa384x_cb_status +* +* Ctlx_complete handler for async CMD type control exchanges. +* mark the hw struct as such. +* +* Note: If the handling is changed here, it should probably be +* changed in docmd as well. +* +* Arguments: +* hw hw struct +* ctlx completed CTLX +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx) +{ + DBFENTER; + + if ( ctlx->usercb != NULL ) { + hfa384x_cmdresult_t cmdresult; + + if (ctlx->state != CTLX_COMPLETE) { + memset(&cmdresult, 0, sizeof(cmdresult)); + cmdresult.status = HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR); + } else { + usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult); + } + + ctlx->usercb(hw, &cmdresult, ctlx->usercb_data); + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_cb_rrid +* +* CTLX completion handler for async RRID type control exchanges. +* +* Note: If the handling is changed here, it should probably be +* changed in dorrid as well. +* +* Arguments: +* hw hw struct +* ctlx completed CTLX +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx) +{ + DBFENTER; + + if ( ctlx->usercb != NULL ) { + hfa384x_rridresult_t rridresult; + + if (ctlx->state != CTLX_COMPLETE) { + memset(&rridresult, 0, sizeof(rridresult)); + rridresult.rid = hfa384x2host_16(ctlx->outbuf.rridreq.rid); + } else { + usbctlx_get_rridresult(&ctlx->inbuf.rridresp, &rridresult); + } + + ctlx->usercb(hw, &rridresult, ctlx->usercb_data); + } + + DBFEXIT; +} + +static inline int +hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL); +} + +static inline int +hfa384x_docmd_async(hfa384x_t *hw, + hfa384x_metacmd_t *cmd, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_docmd(hw, DOASYNC, cmd, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dorrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen) +{ + return hfa384x_dorrid(hw, DOWAIT, + rid, riddata, riddatalen, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dorrid_async(hfa384x_t *hw, + UINT16 rid, void *riddata, UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dorrid(hw, DOASYNC, + rid, riddata, riddatalen, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dowrid_wait(hfa384x_t *hw, UINT16 rid, void *riddata, UINT riddatalen) +{ + return hfa384x_dowrid(hw, DOWAIT, + rid, riddata, riddatalen, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dowrid_async(hfa384x_t *hw, + UINT16 rid, void *riddata, UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dowrid(hw, DOASYNC, + rid, riddata, riddatalen, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dormem_wait(hfa384x_t *hw, + UINT16 page, UINT16 offset, void *data, UINT len) +{ + return hfa384x_dormem(hw, DOWAIT, + page, offset, data, len, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dormem_async(hfa384x_t *hw, + UINT16 page, UINT16 offset, void *data, UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dormem(hw, DOASYNC, + page, offset, data, len, + cmdcb, usercb, usercb_data); +} + +static inline int +hfa384x_dowmem_wait( + hfa384x_t *hw, + UINT16 page, + UINT16 offset, + void *data, + UINT len) +{ + return hfa384x_dowmem(hw, DOWAIT, + page, offset, data, len, + NULL, NULL, NULL); +} + +static inline int +hfa384x_dowmem_async( + hfa384x_t *hw, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dowmem(hw, DOASYNC, + page, offset, data, len, + cmdcb, usercb, usercb_data); +} + +/*---------------------------------------------------------------- +* hfa384x_cmd_initialize +* +* Issues the initialize command and sets the hw->state based +* on the result. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_cmd_initialize(hfa384x_t *hw) +{ + int result = 0; + int i; + hfa384x_metacmd_t cmd; + + DBFENTER; + + + cmd.cmd = HFA384x_CMDCODE_INIT; + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + + WLAN_LOG_DEBUG(3,"cmdresp.init: " + "status=0x%04x, resp0=0x%04x, " + "resp1=0x%04x, resp2=0x%04x\n", + cmd.result.status, + cmd.result.resp0, + cmd.result.resp1, + cmd.result.resp2); + if ( result == 0 ) { + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + } + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_disable +* +* Issues the disable command to stop communications on one of +* the MACs 'ports'. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_enable +* +* Issues the enable command to enable communications on one of +* the MACs 'ports'. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_notify +* +* Sends an info frame to the firmware to alter the behavior +* of the f/w asynch processes. Can only be called when the MAC +* is in the enabled state. +* +* Arguments: +* hw device structure +* reclaim [0|1] indicates whether the given FID will +* be handed back (via Alloc event) for reuse. +* (host order) +* fid FID of buffer containing the frame that was +* previously copied to MAC memory via the bap. +* (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* hw->resp0 will contain the FID being used by async notify +* process. If reclaim==0, resp0 will be the same as the fid +* argument. If reclaim==1, resp0 will be the different. +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, + void *buf, UINT16 len) +{ +#if 0 + int result = 0; + UINT16 cmd; + DBFENTER; + cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) | + HFA384x_CMD_RECL_SET(reclaim); + result = hfa384x_docmd_wait(hw, cmd); + + DBFEXIT; + return result; +#endif +return 0; +} + + +#if 0 +/*---------------------------------------------------------------- +* hfa384x_cmd_inquiry +* +* Requests an info frame from the firmware. The info frame will +* be delivered asynchronously via the Info event. +* +* Arguments: +* hw device structure +* fid FID of the info frame requested. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} +#endif + + +/*---------------------------------------------------------------- +* hfa384x_cmd_monitor +* +* Enables the 'monitor mode' of the MAC. Here's the description of +* monitor mode that I've received thus far: +* +* "The "monitor mode" of operation is that the MAC passes all +* frames for which the PLCP checks are correct. All received +* MPDUs are passed to the host with MAC Port = 7, with a +* receive status of good, FCS error, or undecryptable. Passing +* certain MPDUs is a violation of the 802.11 standard, but useful +* for a debugging tool." Normal communication is not possible +* while monitor mode is enabled. +* +* Arguments: +* hw device structure +* enable a code (0x0b|0x0f) that enables/disables +* monitor mode. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | + HFA384x_CMD_AINFO_SET(enable); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_download +* +* Sets the controls for the MAC controller code/data download +* process. The arguments set the mode and address associated +* with a download. Note that the aux registers should be enabled +* prior to setting one of the download enable modes. +* +* Arguments: +* hw device structure +* mode 0 - Disable programming and begin code exec +* 1 - Enable volatile mem programming +* 2 - Enable non-volatile mem programming +* 3 - Program non-volatile section from NV download +* buffer. +* (host order) +* lowaddr +* highaddr For mode 1, sets the high & low order bits of +* the "destination address". This address will be +* the execution start address when download is +* subsequently disabled. +* For mode 2, sets the high & low order bits of +* the destination in NV ram. +* For modes 0 & 3, should be zero. (host order) +* NOTE: these are CMD format. +* codelen Length of the data to write in mode 2, +* zero otherwise. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr, + UINT16 highaddr, UINT16 codelen) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + WLAN_LOG_DEBUG(5, + "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n", + mode, lowaddr, highaddr, codelen); + + cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) | + HFA384x_CMD_PROGMODE_SET(mode)); + + cmd.parm0 = lowaddr; + cmd.parm1 = highaddr; + cmd.parm2 = codelen; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_from_aux +* +* Copies a collection of bytes from the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* buf contains the data copied +* +* Call context: +* process +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_from_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + DBFENTER; + WLAN_LOG_ERROR("not used in USB.\n"); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_to_aux +* +* Copies a collection of bytes to the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* Controller memory now contains a copy of buf +* +* Call context: +* process +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_to_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + DBFENTER; + WLAN_LOG_ERROR("not used in USB.\n"); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_corereset +* +* Perform a reset of the hfa38xx MAC core. We assume that the hw +* structure is in its "created" state. That is, it is initialized +* with proper values. Note that if a reset is done after the +* device has been active for awhile, the caller might have to clean +* up some leftover cruft in the hw structure. +* +* Arguments: +* hw device structure +* holdtime how long (in ms) to hold the reset +* settletime how long (in ms) to wait after releasing +* the reset +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis) +{ +#if 0 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + struct usb_device *parent = hw->usb->parent; + int i; + int port = -1; +#endif +#endif + int result = 0; + + +#define P2_USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER) +#define P2_USB_FEAT_RESET 4 +#define P2_USB_FEAT_C_RESET 20 + + DBFENTER; + +#if 0 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) + /* Find the hub port */ + for ( i = 0; i < parent->maxchild; i++) { + if (parent->children[i] == hw->usb) { + port = i; + break; + } + } + if (port < 0) return -ENOENT; + + /* Set and clear the reset */ + usb_control_msg(parent, usb_sndctrlpipe(parent, 0), + USB_REQ_SET_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_RESET, + port+1, NULL, 0, 1*HZ); + wait_ms(holdtime); + usb_control_msg(parent, usb_sndctrlpipe(parent, 0), + USB_REQ_CLEAR_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_C_RESET, + port+1, NULL, 0, 1*HZ); + wait_ms(settletime); + + /* Set the device address */ + result=usb_set_address(hw->usb); + if (result < 0) { + WLAN_LOG_ERROR("reset_usbdev: Dev not accepting address, " + "result=%d\n", result); + clear_bit(hw->usb->devnum, &hw->usb->bus->devmap.devicemap); + hw->usb->devnum = -1; + goto done; + } + /* Let the address settle */ + wait_ms(20); + + /* Assume we're reusing the original descriptor data */ + + /* Set the configuration. */ + WLAN_LOG_DEBUG(3, "Setting Configuration %d\n", + hw->usb->config[0].bConfigurationValue); + result=usb_set_configuration(hw->usb, hw->usb->config[0].bConfigurationValue); + if ( result ) { + WLAN_LOG_ERROR("usb_set_configuration() failed, result=%d.\n", + result); + goto done; + } + /* Let the configuration settle */ + wait_ms(20); + + done: +#else + result=usb_reset_device(hw->usb); + if(result<0) { + WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result); + } +#endif +#endif + + result=usb_reset_device(hw->usb); + if(result<0) { + WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result); + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_complete_sync +* +* Waits for a synchronous CTLX object to complete, +* and then handles the response. +* +* Arguments: +* hw device structure +* ctlx CTLX ptr +* completor functor object to decide what to +* do with the CTLX's result. +* +* Returns: +* 0 Success +* -ERESTARTSYS Interrupted by a signal +* -EIO CTLX failed +* -ENODEV Adapter was unplugged +* ??? Result from completor +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw, + hfa384x_usbctlx_t *ctlx, + usbctlx_completor_t *completor) +{ + unsigned long flags; + int result; + + DBFENTER; + + result = wait_for_completion_interruptible(&ctlx->done); + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* + * We can only handle the CTLX if the USB disconnect + * function has not run yet ... + */ + cleanup: + if ( hw->wlandev->hwremoved ) + { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + result = -ENODEV; + } + else if ( result != 0 ) + { + int runqueue = 0; + + /* + * We were probably interrupted, so delete + * this CTLX asynchronously, kill the timers + * and the URB, and then start the next + * pending CTLX. + * + * NOTE: We can only delete the timers and + * the URB if this CTLX is active. + */ + if (ctlx == get_active_ctlx(hw)) + { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + del_singleshot_timer_sync(&hw->reqtimer); + del_singleshot_timer_sync(&hw->resptimer); + hw->req_timer_done = 1; + hw->resp_timer_done = 1; + usb_kill_urb(&hw->ctlx_urb); + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + runqueue = 1; + + /* + * This scenario is so unlikely that I'm + * happy with a grubby "goto" solution ... + */ + if ( hw->wlandev->hwremoved ) + goto cleanup; + } + + /* + * The completion task will send this CTLX + * to the reaper the next time it runs. We + * are no longer in a hurry. + */ + ctlx->reapable = 1; + ctlx->state = CTLX_REQ_FAILED; + list_move_tail(&ctlx->list, &hw->ctlxq.completing); + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if (runqueue) + hfa384x_usbctlxq_run(hw); + } else { + if (ctlx->state == CTLX_COMPLETE) { + result = completor->complete(completor); + } else { + WLAN_LOG_WARNING("CTLX[%d] error: state(%s)\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state)); + result = -EIO; + } + + list_del(&ctlx->list); + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + kfree(ctlx); + } + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_docmd +* +* Constructs a command CTLX and submits it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbcmd() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* cmd cmd structure. Includes all arguments and result +* data points. All in host order. in host order +* cmdcb command-specific callback +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls, NULL +* for DOASYNC calls +* +* Returns: +* 0 success +* -EIO CTLX failure +* -ERESTARTSYS Awakened on signal +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* +* Call context: +* process +----------------------------------------------------------------*/ +static int +hfa384x_docmd( + hfa384x_t *hw, + CMD_MODE mode, + hfa384x_metacmd_t *cmd, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.cmdreq.type = host2hfa384x_16(HFA384x_USB_CMDREQ); + ctlx->outbuf.cmdreq.cmd = host2hfa384x_16(cmd->cmd); + ctlx->outbuf.cmdreq.parm0 = host2hfa384x_16(cmd->parm0); + ctlx->outbuf.cmdreq.parm1 = host2hfa384x_16(cmd->parm1); + ctlx->outbuf.cmdreq.parm2 = host2hfa384x_16(cmd->parm2); + + ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq); + + WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x " + "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n", + cmd->cmd, + cmd->parm0, + cmd->parm1, + cmd->parm2); + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if (mode == DOWAIT) { + usbctlx_cmd_completor_t completor; + + result = hfa384x_usbctlx_complete_sync( + hw, ctlx, init_cmd_completor(&completor, + &ctlx->inbuf.cmdresp, + &cmd->result) ); + } + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_dorrid +* +* Constructs a read rid CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbrrid() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* rid Read RID number (host order) +* riddata Caller supplied buffer that MAC formatted RID.data +* record will be written to for DOWAIT calls. Should +* be NULL for DOASYNC calls. +* riddatalen Buffer length for DOWAIT calls. Zero for DOASYNC calls. +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls, NULL +* for DOWAIT calls +* +* Returns: +* 0 success +* -EIO CTLX failure +* -ERESTARTSYS Awakened on signal +* -ENODATA riddatalen != macdatalen +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOASYNC) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dorrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.rridreq.type = host2hfa384x_16(HFA384x_USB_RRIDREQ); + ctlx->outbuf.rridreq.frmlen = + host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid)); + ctlx->outbuf.rridreq.rid = host2hfa384x_16(rid); + + ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq); + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + /* Submit the CTLX */ + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if (mode == DOWAIT) { + usbctlx_rrid_completor_t completor; + + result = hfa384x_usbctlx_complete_sync( + hw, ctlx, init_rrid_completor(&completor, + &ctlx->inbuf.rridresp, + riddata, + riddatalen) ); + } + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_dowrid +* +* Constructs a write rid CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbwrid() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* CMD_MODE DOWAIT or DOASYNC +* rid RID code +* riddata Data portion of RID formatted for MAC +* riddatalen Length of the data portion in bytes +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOASYNC) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dowrid( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 rid, + void *riddata, + UINT riddatalen, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.wridreq.type = host2hfa384x_16(HFA384x_USB_WRIDREQ); + ctlx->outbuf.wridreq.frmlen = host2hfa384x_16( + (sizeof(ctlx->outbuf.wridreq.rid) + + riddatalen + 1) / 2); + ctlx->outbuf.wridreq.rid = host2hfa384x_16(rid); + memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen); + + ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) + + sizeof(ctlx->outbuf.wridreq.frmlen) + + sizeof(ctlx->outbuf.wridreq.rid) + + riddatalen; + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + /* Submit the CTLX */ + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if (mode == DOWAIT) { + usbctlx_wrid_completor_t completor; + hfa384x_cmdresult_t wridresult; + + result = hfa384x_usbctlx_complete_sync( + hw, + ctlx, + init_wrid_completor(&completor, + &ctlx->inbuf.wridresp, + &wridresult) ); + } + +done: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_dormem +* +* Constructs a readmem CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbrmem() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* page MAC address space page (CMD format) +* offset MAC address space offset +* data Ptr to data buffer to receive read +* len Length of the data to read (max == 2048) +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOASYNC) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dormem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.rmemreq.type = host2hfa384x_16(HFA384x_USB_RMEMREQ); + ctlx->outbuf.rmemreq.frmlen = host2hfa384x_16( + sizeof(ctlx->outbuf.rmemreq.offset) + + sizeof(ctlx->outbuf.rmemreq.page) + + len); + ctlx->outbuf.rmemreq.offset = host2hfa384x_16(offset); + ctlx->outbuf.rmemreq.page = host2hfa384x_16(page); + + ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq); + + WLAN_LOG_DEBUG(4, + "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n", + ctlx->outbuf.rmemreq.type, + ctlx->outbuf.rmemreq.frmlen, + ctlx->outbuf.rmemreq.offset, + ctlx->outbuf.rmemreq.page); + + WLAN_LOG_DEBUG(4,"pktsize=%zd\n", + ROUNDUP64(sizeof(ctlx->outbuf.rmemreq))); + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if ( mode == DOWAIT ) { + usbctlx_rmem_completor_t completor; + + result = hfa384x_usbctlx_complete_sync( + hw, ctlx, init_rmem_completor(&completor, + &ctlx->inbuf.rmemresp, + data, + len) ); + } + +done: + DBFEXIT; + return result; +} + + + +/*---------------------------------------------------------------- +* hfa384x_dowmem +* +* Constructs a writemem CTLX and issues it. +* +* NOTE: Any changes to the 'post-submit' code in this function +* need to be carried over to hfa384x_cbwmem() since the handling +* is virtually identical. +* +* Arguments: +* hw device structure +* mode DOWAIT or DOASYNC +* page MAC address space page (CMD format) +* offset MAC address space offset +* data Ptr to data buffer containing write data +* len Length of the data to read (max == 2048) +* cmdcb command callback for async calls, NULL for DOWAIT calls +* usercb user callback for async calls, NULL for DOWAIT calls +* usercb_data user supplied data pointer for async calls. +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* Call context: +* interrupt (DOWAIT) +* process (DOWAIT or DOASYNC) +----------------------------------------------------------------*/ +static int +hfa384x_dowmem( + hfa384x_t *hw, + CMD_MODE mode, + UINT16 page, + UINT16 offset, + void *data, + UINT len, + ctlx_cmdcb_t cmdcb, + ctlx_usercb_t usercb, + void *usercb_data) +{ + int result; + hfa384x_usbctlx_t *ctlx; + + DBFENTER; + WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n", + page,offset,len); + + ctlx = usbctlx_alloc(); + if ( ctlx == NULL ) { + result = -ENOMEM; + goto done; + } + + /* Initialize the command */ + ctlx->outbuf.wmemreq.type = host2hfa384x_16(HFA384x_USB_WMEMREQ); + ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16( + sizeof(ctlx->outbuf.wmemreq.offset) + + sizeof(ctlx->outbuf.wmemreq.page) + + len); + ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset); + ctlx->outbuf.wmemreq.page = host2hfa384x_16(page); + memcpy(ctlx->outbuf.wmemreq.data, data, len); + + ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) + + sizeof(ctlx->outbuf.wmemreq.frmlen) + + sizeof(ctlx->outbuf.wmemreq.offset) + + sizeof(ctlx->outbuf.wmemreq.page) + + len; + + ctlx->reapable = mode; + ctlx->cmdcb = cmdcb; + ctlx->usercb = usercb; + ctlx->usercb_data = usercb_data; + + result = hfa384x_usbctlx_submit(hw, ctlx); + if (result != 0) { + kfree(ctlx); + } else if ( mode == DOWAIT ) { + usbctlx_wmem_completor_t completor; + hfa384x_cmdresult_t wmemresult; + + result = hfa384x_usbctlx_complete_sync( + hw, + ctlx, + init_wmem_completor(&completor, + &ctlx->inbuf.wmemresp, + &wmemresult) ); + } + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_commtallies +* +* Send a commtallies inquiry to the MAC. Note that this is an async +* call that will result in an info frame arriving sometime later. +* +* Arguments: +* hw device structure +* +* Returns: +* zero success. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_commtallies( hfa384x_t *hw ) +{ + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMDCODE_INQ; + cmd.parm0 = HFA384x_IT_COMMTALLIES; + cmd.parm1 = 0; + cmd.parm2 = 0; + + hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL); + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_disable +* +* Issues the disable command to stop communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also disable macports 1-6. Only ports that have been +* previously enabled may be disabled. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + !(hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_disable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 0; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_enable +* +* Issues the enable command to enable communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also enable macports 1-6. Only ports that are currently +* disabled may be enabled. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + (hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_enable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 1; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_enable +* +* Begins the flash download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and retrieves the flash download +* buffer location, buffer size, and timeout length. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_enable(hfa384x_t *hw) +{ + int result = 0; + int i; + + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_DEBUG(1,"called when port enabled.\n"); + return -EINVAL; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + return -EINVAL; + } + + /* Retrieve the buffer loc&size and timeout */ + if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, + &(hw->bufinfo), sizeof(hw->bufinfo))) ) { + return result; + } + hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page); + hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset); + hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len); + if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, + &(hw->dltimeout))) ) { + return result; + } + hw->dltimeout = hfa384x2host_16(hw->dltimeout); + + WLAN_LOG_DEBUG(1,"flashdl_enable\n"); + + hw->dlstate = HFA384x_DLSTATE_FLASHENABLED; + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_disable +* +* Ends the flash download state. Note that this will cause the MAC +* firmware to restart. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + WLAN_LOG_DEBUG(1,"flashdl_enable\n"); + + /* There isn't much we can do at this point, so I don't */ + /* bother w/ the return value */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + hw->dlstate = HFA384x_DLSTATE_DISABLED; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_write +* +* Performs a FLASH download of a chunk of data. First checks to see +* that we're in the FLASH download state, then sets the download +* mode, uses the aux functions to 1) copy the data to the flash +* buffer, 2) sets the download 'write flash' mode, 3) readback and +* compare. Lather rinse, repeat as many times an necessary to get +* all the given data into flash. +* When all data has been written using this function (possibly +* repeatedly), call drvr_flashdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_flashdl_write( + hfa384x_t *hw, + UINT32 daddr, + void *buf, + UINT32 len) +{ + int result = 0; + UINT32 dlbufaddr; + int nburns; + UINT32 burnlen; + UINT32 burndaddr; + UINT16 burnlo; + UINT16 burnhi; + int nwrites; + UINT8 *writebuf; + UINT16 writepage; + UINT16 writeoffset; + UINT32 writelen; + int i; + int j; + + DBFENTER; + WLAN_LOG_DEBUG(5,"daddr=0x%08x len=%d\n", daddr, len); + + /* Check that we're in the flash download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr); + + /* Convert to flat address for arithmetic */ + /* NOTE: dlbuffer RID stores the address in AUX format */ + dlbufaddr = HFA384x_ADDR_AUX_MKFLAT( + hw->bufinfo.page, hw->bufinfo.offset); + WLAN_LOG_DEBUG(5, + "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n", + hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr); + +#if 0 +WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout); +#endif + /* Calculations to determine how many fills of the dlbuffer to do + * and how many USB wmemreq's to do for each fill. At this point + * in time, the dlbuffer size and the wmemreq size are the same. + * Therefore, nwrites should always be 1. The extra complexity + * here is a hedge against future changes. + */ + + /* Figure out how many times to do the flash programming */ + nburns = len / hw->bufinfo.len; + nburns += (len % hw->bufinfo.len) ? 1 : 0; + + /* For each flash program cycle, how many USB wmemreq's are needed? */ + nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN; + nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0; + + /* For each burn */ + for ( i = 0; i < nburns; i++) { + /* Get the dest address and len */ + burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ? + hw->bufinfo.len : + (len - (hw->bufinfo.len * i)); + burndaddr = daddr + (hw->bufinfo.len * i); + burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr); + burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr); + + WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", + burnlen, burndaddr); + + /* Set the download mode */ + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, + burnlo, burnhi, burnlen); + if ( result ) { + WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + burnlo, burnhi, burnlen, result); + goto exit_proc; + } + + /* copy the data to the flash download buffer */ + for ( j=0; j < nwrites; j++) { + writebuf = buf + + (i*hw->bufinfo.len) + + (j*HFA384x_USB_RWMEM_MAXLEN); + + writepage = HFA384x_ADDR_CMD_MKPAGE( + dlbufaddr + + (j*HFA384x_USB_RWMEM_MAXLEN)); + writeoffset = HFA384x_ADDR_CMD_MKOFF( + dlbufaddr + + (j*HFA384x_USB_RWMEM_MAXLEN)); + + writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN); + writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ? + HFA384x_USB_RWMEM_MAXLEN : + writelen; + + result = hfa384x_dowmem_wait( hw, + writepage, + writeoffset, + writebuf, + writelen ); +#if 0 + +Comment out for debugging, assume the write was successful. + if (result) { + WLAN_LOG_ERROR( + "Write to dl buffer failed, " + "result=0x%04x. Aborting.\n", + result); + goto exit_proc; + } +#endif + + } + + /* set the download 'write flash' mode */ + result = hfa384x_cmd_download(hw, + HFA384x_PROGMODE_NVWRITE, + 0,0,0); + if ( result ) { + WLAN_LOG_ERROR( + "download(NVWRITE,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + burnlo, burnhi, burnlen, result); + goto exit_proc; + } + + /* TODO: We really should do a readback and compare. */ + } + +exit_proc: + + /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */ + /* actually disable programming mode. Remember, that will cause the */ + /* the firmware to effectively reset itself. */ + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_getconfig +* +* Performs the sequence necessary to read a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (host order) +* buf host side record buffer. Upon return it will +* contain the body portion of the record (minus the +* RID and len). +* len buffer length (in bytes, should match record length) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ENODATA length mismatch between argument and retrieved +* record. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + int result; + DBFENTER; + + result = hfa384x_dorrid_wait(hw, rid, buf, len); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- + * hfa384x_drvr_getconfig_async + * + * Performs the sequence necessary to perform an async read of + * of a config/info item. + * + * Arguments: + * hw device structure + * rid config/info record id (host order) + * buf host side record buffer. Upon return it will + * contain the body portion of the record (minus the + * RID and len). + * len buffer length (in bytes, should match record length) + * cbfn caller supplied callback, called when the command + * is done (successful or not). + * cbfndata pointer to some caller supplied data that will be + * passed in as an argument to the cbfn. + * + * Returns: + * nothing the cbfn gets a status argument identifying if + * any errors occur. + * Side effects: + * Queues an hfa384x_usbcmd_t for subsequent execution. + * + * Call context: + * Any + ----------------------------------------------------------------*/ +int +hfa384x_drvr_getconfig_async( + hfa384x_t *hw, + UINT16 rid, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dorrid_async(hw, rid, NULL, 0, + hfa384x_cb_rrid, usercb, usercb_data); +} + +/*---------------------------------------------------------------- + * hfa384x_drvr_setconfig_async + * + * Performs the sequence necessary to write a config/info item. + * + * Arguments: + * hw device structure + * rid config/info record id (in host order) + * buf host side record buffer + * len buffer length (in bytes) + * usercb completion callback + * usercb_data completion callback argument + * + * Returns: + * 0 success + * >0 f/w reported error - f/w status code + * <0 driver reported error + * + * Side effects: + * + * Call context: + * process + ----------------------------------------------------------------*/ +int +hfa384x_drvr_setconfig_async( + hfa384x_t *hw, + UINT16 rid, + void *buf, + UINT16 len, + ctlx_usercb_t usercb, + void *usercb_data) +{ + return hfa384x_dowrid_async(hw, rid, buf, len, + hfa384x_cb_status, usercb, usercb_data); +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_handover +* +* Sends a handover notification to the MAC. +* +* Arguments: +* hw device structure +* addr address of station that's left +* +* Returns: +* zero success. +* -ERESTARTSYS received signal while waiting for semaphore. +* -EIO failed to write to bap, or failed in cmd. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr) +{ + DBFENTER; + WLAN_LOG_ERROR("Not currently supported in USB!\n"); + DBFEXIT; + return -EIO; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_low_level +* +* Write test commands to the card. Some test commands don't make +* sense without prior set-up. For example, continous TX isn't very +* useful until you set the channel. That functionality should be +* +* Side effects: +* +* Call context: +* process thread +* -----------------------------------------------------------------*/ +int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result; + DBFENTER; + + /* Do i need a host2hfa... conversion ? */ + + result = hfa384x_docmd_wait(hw, cmd); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_read +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* register The test register to be accessed (must be even #). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp) +{ +#if 0 + int result = 0; + UINT16 cmd_code = (UINT16) 0x30; + UINT16 param = (UINT16) addr; + DBFENTER; + + /* Do i need a host2hfa... conversion ? */ + result = hfa384x_docmd_wait(hw, cmd_code); + + DBFEXIT; + return result; +#endif +return 0; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_write +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* addr The test register to be accessed (must be even #). +* data The data value to write to the register. +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ + +int +hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data) +{ +#if 0 + int result = 0; + UINT16 cmd_code = (UINT16) 0x31; + UINT16 param0 = (UINT16) addr; + UINT16 param1 = (UINT16) data; + DBFENTER; + + WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08lx\n", addr); + WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08lx\n", data); + + /* Do i need a host2hfa... conversion ? */ + result = hfa384x_docmd_wait(hw, cmd_code); + + DBFEXIT; + return result; +#endif +return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_disable +* +* Ends the ram download state. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_ramdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) { + return -EINVAL; + } + + WLAN_LOG_DEBUG(3,"ramdl_disable()\n"); + + /* There isn't much we can do at this point, so I don't */ + /* bother w/ the return value */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + hw->dlstate = HFA384x_DLSTATE_DISABLED; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_enable +* +* Begins the ram download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and calls cmd_download with the +* ENABLE_VOLATILE subcommand and the exeaddr argument. +* +* Arguments: +* hw device structure +* exeaddr the card execution address that will be +* jumped to when ramdl_disable() is called +* (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr) +{ + int result = 0; + UINT16 lowaddr; + UINT16 hiaddr; + int i; + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_ERROR( + "Can't download with a macport enabled.\n"); + return -EINVAL; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + WLAN_LOG_ERROR( + "Download state not disabled.\n"); + return -EINVAL; + } + + WLAN_LOG_DEBUG(3,"ramdl_enable, exeaddr=0x%08x\n", exeaddr); + + /* Call the download(1,addr) function */ + lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr); + hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr); + + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM, + lowaddr, hiaddr, 0); + + if ( result == 0) { + /* Set the download state */ + hw->dlstate = HFA384x_DLSTATE_RAMENABLED; + } else { + WLAN_LOG_DEBUG(1, + "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n", + lowaddr, + hiaddr, + result); + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_write +* +* Performs a RAM download of a chunk of data. First checks to see +* that we're in the RAM download state, then uses the [read|write]mem USB +* commands to 1) copy the data, 2) readback and compare. The download +* state is unaffected. When all data has been written using +* this function, call drvr_ramdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len) +{ + int result = 0; + int nwrites; + UINT8 *data = buf; + int i; + UINT32 curraddr; + UINT16 currpage; + UINT16 curroffset; + UINT16 currlen; + DBFENTER; + /* Check that we're in the ram download state */ + if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr); + + /* How many dowmem calls? */ + nwrites = len / HFA384x_USB_RWMEM_MAXLEN; + nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0; + + /* Do blocking wmem's */ + for(i=0; i < nwrites; i++) { + /* make address args */ + curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN); + currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr); + curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr); + currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN); + if ( currlen > HFA384x_USB_RWMEM_MAXLEN) { + currlen = HFA384x_USB_RWMEM_MAXLEN; + } + + /* Do blocking ctlx */ + result = hfa384x_dowmem_wait( hw, + currpage, + curroffset, + data + (i*HFA384x_USB_RWMEM_MAXLEN), + currlen ); + + if (result) break; + + /* TODO: We really should have a readback. */ + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_readpda +* +* Performs the sequence to read the PDA space. Note there is no +* drvr_writepda() function. Writing a PDA is +* generally implemented by a calling component via calls to +* cmd_download and writing to the flash download buffer via the +* aux regs. +* +* Arguments: +* hw device structure +* buf buffer to store PDA in +* len buffer length +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ETIMEOUT timout waiting for the cmd regs to become +* available, or waiting for the control reg +* to indicate the Aux port is enabled. +* -ENODATA the buffer does NOT contain a valid PDA. +* Either the card PDA is bad, or the auxdata +* reads are giving us garbage. + +* +* Side effects: +* +* Call context: +* process or non-card interrupt. +----------------------------------------------------------------*/ +int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len) +{ + int result = 0; + UINT16 *pda = buf; + int pdaok = 0; + int morepdrs = 1; + int currpdr = 0; /* word offset of the current pdr */ + size_t i; + UINT16 pdrlen; /* pdr length in bytes, host order */ + UINT16 pdrcode; /* pdr code, host order */ + UINT16 currpage; + UINT16 curroffset; + struct pdaloc { + UINT32 cardaddr; + UINT16 auxctl; + } pdaloc[] = + { + { HFA3842_PDA_BASE, 0}, + { HFA3841_PDA_BASE, 0}, + { HFA3841_PDA_BOGUS_BASE, 0} + }; + + DBFENTER; + + /* Read the pda from each known address. */ + for ( i = 0; i < ARRAY_SIZE(pdaloc); i++) { + /* Make address */ + currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr); + curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr); + + result = hfa384x_dormem_wait(hw, + currpage, + curroffset, + buf, + len); /* units of bytes */ + + if (result) { + WLAN_LOG_WARNING( + "Read from index %zd failed, continuing\n", + i ); + continue; + } + + /* Test for garbage */ + pdaok = 1; /* initially assume good */ + morepdrs = 1; + while ( pdaok && morepdrs ) { + pdrlen = hfa384x2host_16(pda[currpdr]) * 2; + pdrcode = hfa384x2host_16(pda[currpdr+1]); + /* Test the record length */ + if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) { + WLAN_LOG_ERROR("pdrlen invalid=%d\n", + pdrlen); + pdaok = 0; + break; + } + /* Test the code */ + if ( !hfa384x_isgood_pdrcode(pdrcode) ) { + WLAN_LOG_ERROR("pdrcode invalid=%d\n", + pdrcode); + pdaok = 0; + break; + } + /* Test for completion */ + if ( pdrcode == HFA384x_PDR_END_OF_PDA) { + morepdrs = 0; + } + + /* Move to the next pdr (if necessary) */ + if ( morepdrs ) { + /* note the access to pda[], need words here */ + currpdr += hfa384x2host_16(pda[currpdr]) + 1; + } + } + if ( pdaok ) { + WLAN_LOG_INFO( + "PDA Read from 0x%08x in %s space.\n", + pdaloc[i].cardaddr, + pdaloc[i].auxctl == 0 ? "EXTDS" : + pdaloc[i].auxctl == 1 ? "NV" : + pdaloc[i].auxctl == 2 ? "PHY" : + pdaloc[i].auxctl == 3 ? "ICSRAM" : + ""); + break; + } + } + result = pdaok ? 0 : -ENODATA; + + if ( result ) { + WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n"); + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_setconfig +* +* Performs the sequence necessary to write a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (in host order) +* buf host side record buffer +* len buffer length (in bytes) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + return hfa384x_dowrid_wait(hw, rid, buf, len); +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_start +* +* Issues the MAC initialize command, sets up some data structures, +* and enables the interrupts. After this function completes, the +* low-level stuff should be ready for any/all commands. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_start(hfa384x_t *hw) +{ + int result, result1, result2; + u16 status; + DBFENTER; + + might_sleep(); + + /* Clear endpoint stalls - but only do this if the endpoint + * is showing a stall status. Some prism2 cards seem to behave + * badly if a clear_halt is called when the endpoint is already + * ok + */ + result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status); + if (result < 0) { + WLAN_LOG_ERROR( + "Cannot get bulk in endpoint status.\n"); + goto done; + } + if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in)) { + WLAN_LOG_ERROR( + "Failed to reset bulk in endpoint.\n"); + } + + result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status); + if (result < 0) { + WLAN_LOG_ERROR( + "Cannot get bulk out endpoint status.\n"); + goto done; + } + if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out)) { + WLAN_LOG_ERROR( + "Failed to reset bulk out endpoint.\n"); + } + + /* Synchronous unlink, in case we're trying to restart the driver */ + usb_kill_urb(&hw->rx_urb); + + /* Post the IN urb */ + result = submit_rx_urb(hw, GFP_KERNEL); + if (result != 0) { + WLAN_LOG_ERROR( + "Fatal, failed to submit RX URB, result=%d\n", + result); + goto done; + } + + /* Call initialize twice, with a 1 second sleep in between. + * This is a nasty work-around since many prism2 cards seem to + * need time to settle after an init from cold. The second + * call to initialize in theory is not necessary - but we call + * it anyway as a double insurance policy: + * 1) If the first init should fail, the second may well succeed + * and the card can still be used + * 2) It helps ensures all is well with the card after the first + * init and settle time. + */ + result1 = hfa384x_cmd_initialize(hw); + msleep(1000); + result = result2 = hfa384x_cmd_initialize(hw); + if (result1 != 0) { + if (result2 != 0) { + WLAN_LOG_ERROR( + "cmd_initialize() failed on two attempts, results %d and %d\n", + result1, result2); + usb_kill_urb(&hw->rx_urb); + goto done; + } else { + WLAN_LOG_DEBUG(0, "First cmd_initialize() failed (result %d),\n", + result1); + WLAN_LOG_DEBUG(0, "but second attempt succeeded. All should be ok\n"); + } + } else if (result2 != 0) { + WLAN_LOG_WARNING( + "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n", + result2); + WLAN_LOG_WARNING("Most likely the card will be functional\n"); + goto done; + } + + hw->state = HFA384x_STATE_RUNNING; + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_stop +* +* Shuts down the MAC to the point where it is safe to unload the +* driver. Any subsystem that may be holding a data or function +* ptr into the driver must be cleared/deinitialized. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int +hfa384x_drvr_stop(hfa384x_t *hw) +{ + int result = 0; + int i; + DBFENTER; + + might_sleep(); + + /* There's no need for spinlocks here. The USB "disconnect" + * function sets this "removed" flag and then calls us. + */ + if ( !hw->wlandev->hwremoved ) { + /* Call initialize to leave the MAC in its 'reset' state */ + hfa384x_cmd_initialize(hw); + + /* Cancel the rxurb */ + usb_kill_urb(&hw->rx_urb); + } + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + del_timer_sync(&hw->commsqual_timer); + + /* Clear all the port status */ + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_txframe +* +* Takes a frame from prism2sta and queues it for transmission. +* +* Arguments: +* hw device structure +* skb packet buffer struct. Contains an 802.11 +* data frame. +* p80211_hdr points to the 802.11 header for the packet. +* Returns: +* 0 Success and more buffs available +* 1 Success but no more buffs +* 2 Allocation failure +* 4 Buffer full or queue busy +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep) + +{ + int usbpktlen = sizeof(hfa384x_tx_frame_t); + int result; + int ret; + char *ptr; + + DBFENTER; + + if (hw->tx_urb.status == -EINPROGRESS) { + WLAN_LOG_WARNING("TX URB already in use\n"); + result = 3; + goto exit; + } + + /* Build Tx frame structure */ + /* Set up the control field */ + memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc)); + + /* Setup the usb type field */ + hw->txbuff.type = host2hfa384x_16(HFA384x_USB_TXFRM); + + /* Set up the sw_support field to identify this frame */ + hw->txbuff.txfrm.desc.sw_support = 0x0123; + +/* Tx complete and Tx exception disable per dleach. Might be causing + * buf depletion + */ +//#define DOEXC SLP -- doboth breaks horribly under load, doexc less so. +#if defined(DOBOTH) + hw->txbuff.txfrm.desc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1); +#elif defined(DOEXC) + hw->txbuff.txfrm.desc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0); +#else + hw->txbuff.txfrm.desc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0); +#endif + hw->txbuff.txfrm.desc.tx_control = + host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control); + + /* copy the header over to the txdesc */ + memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, sizeof(p80211_hdr_t)); + + /* if we're using host WEP, increase size by IV+ICV */ + if (p80211_wep->data) { + hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8); + // hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); + usbpktlen+=8; + } else { + hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len); + } + + usbpktlen += skb->len; + + /* copy over the WEP IV if we are using host WEP */ + ptr = hw->txbuff.txfrm.data; + if (p80211_wep->data) { + memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv)); + ptr+= sizeof(p80211_wep->iv); + memcpy(ptr, p80211_wep->data, skb->len); + } else { + memcpy(ptr, skb->data, skb->len); + } + /* copy over the packet data */ + ptr+= skb->len; + + /* copy over the WEP ICV if we are using host WEP */ + if (p80211_wep->data) { + memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv)); + } + + /* Send the USB packet */ + usb_fill_bulk_urb( &(hw->tx_urb), hw->usb, + hw->endp_out, + &(hw->txbuff), ROUNDUP64(usbpktlen), + hfa384x_usbout_callback, hw->wlandev ); + hw->tx_urb.transfer_flags |= USB_QUEUE_BULK; + + result = 1; + ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC); + if ( ret != 0 ) { + WLAN_LOG_ERROR( + "submit_tx_urb() failed, error=%d\n", ret); + result = 3; + } + + exit: + DBFEXIT; + return result; +} + +void hfa384x_tx_timeout(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + if ( !hw->wlandev->hwremoved && + /* Note the bitwise OR, not the logical OR. */ + ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) | + !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) ) + { + schedule_work(&hw->usb_work); + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_reaper_task +* +* Tasklet to delete dead CTLX objects +* +* Arguments: +* data ptr to a hfa384x_t +* +* Returns: +* +* Call context: +* Interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbctlx_reaper_task(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + struct list_head *entry; + struct list_head *temp; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* This list is guaranteed to be empty if someone + * has unplugged the adapter. + */ + list_for_each_safe(entry, temp, &hw->ctlxq.reapable) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + list_del(&ctlx->list); + kfree(ctlx); + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_completion_task +* +* Tasklet to call completion handlers for returned CTLXs +* +* Arguments: +* data ptr to hfa384x_t +* +* Returns: +* Nothing +* +* Call context: +* Interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbctlx_completion_task(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + struct list_head *entry; + struct list_head *temp; + unsigned long flags; + + int reap = 0; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* This list is guaranteed to be empty if someone + * has unplugged the adapter ... + */ + list_for_each_safe(entry, temp, &hw->ctlxq.completing) { + hfa384x_usbctlx_t *ctlx; + + ctlx = list_entry(entry, hfa384x_usbctlx_t, list); + + /* Call the completion function that this + * command was assigned, assuming it has one. + */ + if ( ctlx->cmdcb != NULL ) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + ctlx->cmdcb(hw, ctlx); + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* Make sure we don't try and complete + * this CTLX more than once! + */ + ctlx->cmdcb = NULL; + + /* Did someone yank the adapter out + * while our list was (briefly) unlocked? + */ + if ( hw->wlandev->hwremoved ) + { + reap = 0; + break; + } + } + + /* + * "Reapable" CTLXs are ones which don't have any + * threads waiting for them to die. Hence they must + * be delivered to The Reaper! + */ + if ( ctlx->reapable ) { + /* Move the CTLX off the "completing" list (hopefully) + * on to the "reapable" list where the reaper task + * can find it. And "reapable" means that this CTLX + * isn't sitting on a wait-queue somewhere. + */ + list_move_tail(&ctlx->list, &hw->ctlxq.reapable); + reap = 1; + } + + complete(&ctlx->done); + } + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if (reap) + tasklet_schedule(&hw->reaper_bh); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* unlocked_usbctlx_cancel_async +* +* Mark the CTLX dead asynchronously, and ensure that the +* next command on the queue is run afterwards. +* +* Arguments: +* hw ptr to the hfa384x_t structure +* ctlx ptr to a CTLX structure +* +* Returns: +* 0 the CTLX's URB is inactive +* -EINPROGRESS the URB is currently being unlinked +* +* Call context: +* Either process or interrupt, but presumably interrupt +----------------------------------------------------------------*/ +static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx) +{ + int ret; + + DBFENTER; + + /* + * Try to delete the URB containing our request packet. + * If we succeed, then its completion handler will be + * called with a status of -ECONNRESET. + */ + hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK; + ret = usb_unlink_urb(&hw->ctlx_urb); + + if (ret != -EINPROGRESS) { + /* + * The OUT URB had either already completed + * or was still in the pending queue, so the + * URB's completion function will not be called. + * We will have to complete the CTLX ourselves. + */ + ctlx->state = CTLX_REQ_FAILED; + unlocked_usbctlx_complete(hw, ctlx); + ret = 0; + } + + DBFEXIT; + + return ret; +} + +/*---------------------------------------------------------------- +* unlocked_usbctlx_complete +* +* A CTLX has completed. It may have been successful, it may not +* have been. At this point, the CTLX should be quiescent. The URBs +* aren't active and the timers should have been stopped. +* +* The CTLX is migrated to the "completing" queue, and the completing +* tasklet is scheduled. +* +* Arguments: +* hw ptr to a hfa384x_t structure +* ctlx ptr to a ctlx structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* Either, assume interrupt +----------------------------------------------------------------*/ +static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx) +{ + DBFENTER; + + /* Timers have been stopped, and ctlx should be in + * a terminal state. Retire it from the "active" + * queue. + */ + list_move_tail(&ctlx->list, &hw->ctlxq.completing); + tasklet_schedule(&hw->completion_bh); + + switch (ctlx->state) { + case CTLX_COMPLETE: + case CTLX_REQ_FAILED: + /* This are the correct terminating states. */ + break; + + default: + WLAN_LOG_ERROR("CTLX[%d] not in a terminating state(%s)\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state)); + break; + } /* switch */ + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usbctlxq_run +* +* Checks to see if the head item is running. If not, starts it. +* +* Arguments: +* hw ptr to hfa384x_t +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* any +----------------------------------------------------------------*/ +static void +hfa384x_usbctlxq_run(hfa384x_t *hw) +{ + unsigned long flags; + DBFENTER; + + /* acquire lock */ + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* Only one active CTLX at any one time, because there's no + * other (reliable) way to match the response URB to the + * correct CTLX. + * + * Don't touch any of these CTLXs if the hardware + * has been removed or the USB subsystem is stalled. + */ + if ( !list_empty(&hw->ctlxq.active) || + test_bit(WORK_TX_HALT, &hw->usb_flags) || + hw->wlandev->hwremoved ) + goto unlock; + + while ( !list_empty(&hw->ctlxq.pending) ) { + hfa384x_usbctlx_t *head; + int result; + + /* This is the first pending command */ + head = list_entry(hw->ctlxq.pending.next, + hfa384x_usbctlx_t, + list); + + /* We need to split this off to avoid a race condition */ + list_move_tail(&head->list, &hw->ctlxq.active); + + /* Fill the out packet */ + usb_fill_bulk_urb( &(hw->ctlx_urb), hw->usb, + hw->endp_out, + &(head->outbuf), ROUNDUP64(head->outbufsize), + hfa384x_ctlxout_callback, hw); + hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK; + + /* Now submit the URB and update the CTLX's state + */ + if ((result = SUBMIT_URB(&hw->ctlx_urb, GFP_ATOMIC)) == 0) { + /* This CTLX is now running on the active queue */ + head->state = CTLX_REQ_SUBMITTED; + + /* Start the OUT wait timer */ + hw->req_timer_done = 0; + hw->reqtimer.expires = jiffies + HZ; + add_timer(&hw->reqtimer); + + /* Start the IN wait timer */ + hw->resp_timer_done = 0; + hw->resptimer.expires = jiffies + 2*HZ; + add_timer(&hw->resptimer); + + break; + } + + if (result == -EPIPE) { + /* The OUT pipe needs resetting, so put + * this CTLX back in the "pending" queue + * and schedule a reset ... + */ + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + hw->wlandev->netdev->name); + list_move(&head->list, &hw->ctlxq.pending); + set_bit(WORK_TX_HALT, &hw->usb_flags); + schedule_work(&hw->usb_work); + break; + } + + if (result == -ESHUTDOWN) { + WLAN_LOG_WARNING("%s urb shutdown!\n", + hw->wlandev->netdev->name); + break; + } + + WLAN_LOG_ERROR("Failed to submit CTLX[%d]: error=%d\n", + hfa384x2host_16(head->outbuf.type), result); + unlocked_usbctlx_complete(hw, head); + } /* while */ + + unlock: + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_callback +* +* Callback for URBs on the BULKIN endpoint. +* +* Arguments: +* urb ptr to the completed urb +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +#ifdef URB_ONLY_CALLBACK +static void hfa384x_usbin_callback(struct urb *urb) +#else +static void hfa384x_usbin_callback(struct urb *urb, struct pt_regs *regs) +#endif +{ + wlandevice_t *wlandev = urb->context; + hfa384x_t *hw; + hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) urb->transfer_buffer; + struct sk_buff *skb = NULL; + int result; + int urb_status; + UINT16 type; + + enum USBIN_ACTION { + HANDLE, + RESUBMIT, + ABORT + } action; + + DBFENTER; + + if ( !wlandev || + !wlandev->netdev || + wlandev->hwremoved ) + goto exit; + + hw = wlandev->priv; + if (!hw) + goto exit; + + skb = hw->rx_urb_skb; + if (!skb || (skb->data != urb->transfer_buffer)) { + BUG(); + } + hw->rx_urb_skb = NULL; + + /* Check for error conditions within the URB */ + switch (urb->status) { + case 0: + action = HANDLE; + + /* Check for short packet */ + if ( urb->actual_length == 0 ) { + ++(wlandev->linux_stats.rx_errors); + ++(wlandev->linux_stats.rx_length_errors); + action = RESUBMIT; + } + break; + + case -EPIPE: + WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n", + wlandev->netdev->name); + if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) + schedule_work(&hw->usb_work); + ++(wlandev->linux_stats.rx_errors); + action = ABORT; + break; + + case -EILSEQ: + case -ETIMEDOUT: + case -EPROTO: + if ( !test_and_set_bit(THROTTLE_RX, &hw->usb_flags) && + !timer_pending(&hw->throttle) ) { + mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES); + } + ++(wlandev->linux_stats.rx_errors); + action = ABORT; + break; + + case -EOVERFLOW: + ++(wlandev->linux_stats.rx_over_errors); + action = RESUBMIT; + break; + + case -ENODEV: + case -ESHUTDOWN: + WLAN_LOG_DEBUG(3,"status=%d, device removed.\n", urb->status); + action = ABORT; + break; + + case -ENOENT: + case -ECONNRESET: + WLAN_LOG_DEBUG(3,"status=%d, urb explicitly unlinked.\n", urb->status); + action = ABORT; + break; + + default: + WLAN_LOG_DEBUG(3,"urb status=%d, transfer flags=0x%x\n", + urb->status, urb->transfer_flags); + ++(wlandev->linux_stats.rx_errors); + action = RESUBMIT; + break; + } + + urb_status = urb->status; + + if (action != ABORT) { + /* Repost the RX URB */ + result = submit_rx_urb(hw, GFP_ATOMIC); + + if (result != 0) { + WLAN_LOG_ERROR( + "Fatal, failed to resubmit rx_urb. error=%d\n", + result); + } + } + + /* Handle any USB-IN packet */ + /* Note: the check of the sw_support field, the type field doesn't + * have bit 12 set like the docs suggest. + */ + type = hfa384x2host_16(usbin->type); + if (HFA384x_USB_ISRXFRM(type)) { + if (action == HANDLE) { + if (usbin->txfrm.desc.sw_support == 0x0123) { + hfa384x_usbin_txcompl(wlandev, usbin); + } else { + skb_put(skb, sizeof(*usbin)); + hfa384x_usbin_rx(wlandev, skb); + skb = NULL; + } + } + goto exit; + } + if (HFA384x_USB_ISTXFRM(type)) { + if (action == HANDLE) + hfa384x_usbin_txcompl(wlandev, usbin); + goto exit; + } + switch (type) { + case HFA384x_USB_INFOFRM: + if (action == ABORT) + goto exit; + if (action == HANDLE) + hfa384x_usbin_info(wlandev, usbin); + break; + + case HFA384x_USB_CMDRESP: + case HFA384x_USB_WRIDRESP: + case HFA384x_USB_RRIDRESP: + case HFA384x_USB_WMEMRESP: + case HFA384x_USB_RMEMRESP: + /* ALWAYS, ALWAYS, ALWAYS handle this CTLX!!!! */ + hfa384x_usbin_ctlx(hw, usbin, urb_status); + break; + + case HFA384x_USB_BUFAVAIL: + WLAN_LOG_DEBUG(3,"Received BUFAVAIL packet, frmlen=%d\n", + usbin->bufavail.frmlen); + break; + + case HFA384x_USB_ERROR: + WLAN_LOG_DEBUG(3,"Received USB_ERROR packet, errortype=%d\n", + usbin->usberror.errortype); + break; + + default: + WLAN_LOG_DEBUG(3,"Unrecognized USBIN packet, type=%x, status=%d\n", + usbin->type, urb_status); + break; + } /* switch */ + +exit: + + if (skb) + dev_kfree_skb(skb); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_ctlx +* +* We've received a URB containing a Prism2 "response" message. +* This message needs to be matched up with a CTLX on the active +* queue and our state updated accordingly. +* +* Arguments: +* hw ptr to hfa384x_t +* usbin ptr to USB IN packet +* urb_status status of this Bulk-In URB +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin, + int urb_status) +{ + hfa384x_usbctlx_t *ctlx; + int run_queue = 0; + unsigned long flags; + + DBFENTER; + +retry: + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* There can be only one CTLX on the active queue + * at any one time, and this is the CTLX that the + * timers are waiting for. + */ + if ( list_empty(&hw->ctlxq.active) ) { + goto unlock; + } + + /* Remove the "response timeout". It's possible that + * we are already too late, and that the timeout is + * already running. And that's just too bad for us, + * because we could lose our CTLX from the active + * queue here ... + */ + if (del_timer(&hw->resptimer) == 0) { + if (hw->resp_timer_done == 0) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + goto retry; + } + } + else { + hw->resp_timer_done = 1; + } + + ctlx = get_active_ctlx(hw); + + if (urb_status != 0) { + /* + * Bad CTLX, so get rid of it. But we only + * remove it from the active queue if we're no + * longer expecting the OUT URB to complete. + */ + if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) + run_queue = 1; + } else { + const UINT16 intype = (usbin->type&~host2hfa384x_16(0x8000)); + + /* + * Check that our message is what we're expecting ... + */ + if (ctlx->outbuf.type != intype) { + WLAN_LOG_WARNING("Expected IN[%d], received IN[%d] - ignored.\n", + hfa384x2host_16(ctlx->outbuf.type), + hfa384x2host_16(intype)); + goto unlock; + } + + /* This URB has succeeded, so grab the data ... */ + memcpy(&ctlx->inbuf, usbin, sizeof(ctlx->inbuf)); + + switch (ctlx->state) { + case CTLX_REQ_SUBMITTED: + /* + * We have received our response URB before + * our request has been acknowledged. Odd, + * but our OUT URB is still alive... + */ + WLAN_LOG_DEBUG(0, "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n"); + ctlx->state = CTLX_RESP_COMPLETE; + break; + + case CTLX_REQ_COMPLETE: + /* + * This is the usual path: our request + * has already been acknowledged, and + * now we have received the reply too. + */ + ctlx->state = CTLX_COMPLETE; + unlocked_usbctlx_complete(hw, ctlx); + run_queue = 1; + break; + + default: + /* + * Throw this CTLX away ... + */ + WLAN_LOG_ERROR("Matched IN URB, CTLX[%d] in invalid state(%s)." + " Discarded.\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state)); + if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) + run_queue = 1; + break; + } /* switch */ + } + +unlock: + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if (run_queue) + hfa384x_usbctlxq_run(hw); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_txcompl +* +* At this point we have the results of a previous transmit. +* +* Arguments: +* wlandev wlan device +* usbin ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin) +{ + UINT16 status; + DBFENTER; + + status = hfa384x2host_16(usbin->type); /* yeah I know it says type...*/ + + /* Was there an error? */ + if (HFA384x_TXSTATUS_ISERROR(status)) { + prism2sta_ev_txexc(wlandev, status); + } else { + prism2sta_ev_tx(wlandev, status); + } + // prism2sta_ev_alloc(wlandev); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbin_rx +* +* At this point we have a successful received a rx frame packet. +* +* Arguments: +* wlandev wlan device +* usbin ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb) +{ + hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data; + hfa384x_t *hw = wlandev->priv; + int hdrlen; + p80211_rxmeta_t *rxmeta; + UINT16 data_len; + UINT16 fc; + + DBFENTER; + + /* Byte order convert once up front. */ + usbin->rxfrm.desc.status = + hfa384x2host_16(usbin->rxfrm.desc.status); + usbin->rxfrm.desc.time = + hfa384x2host_32(usbin->rxfrm.desc.time); + + /* Now handle frame based on port# */ + switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) ) + { + case 0: + fc = ieee2host16(usbin->rxfrm.desc.frame_control); + + /* If exclude and we receive an unencrypted, drop it */ + if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) && + !WLAN_GET_FC_ISWEP(fc)){ + goto done; + } + + data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len); + + /* How much header data do we have? */ + hdrlen = p80211_headerlen(fc); + + /* Pull off the descriptor */ + skb_pull(skb, sizeof(hfa384x_rx_frame_t)); + + /* Now shunt the header block up against the data block + * with an "overlapping" copy + */ + memmove(skb_push(skb, hdrlen), + &usbin->rxfrm.desc.frame_control, + hdrlen); + + skb->dev = wlandev->netdev; + skb->dev->last_rx = jiffies; + + /* And set the frame length properly */ + skb_trim(skb, data_len + hdrlen); + + /* The prism2 series does not return the CRC */ + memset(skb_put(skb, WLAN_CRC_LEN), 0xff, WLAN_CRC_LEN); + + skb_reset_mac_header(skb); + + /* Attach the rxmeta, set some stuff */ + p80211skb_rxmeta_attach(wlandev, skb); + rxmeta = P80211SKB_RXMETA(skb); + rxmeta->mactime = usbin->rxfrm.desc.time; + rxmeta->rxrate = usbin->rxfrm.desc.rate; + rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust; + rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust; + + prism2sta_ev_rx(wlandev, skb); + + break; + + case 7: + if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) { + /* Copy to wlansnif skb */ + hfa384x_int_rxmonitor( wlandev, &usbin->rxfrm); + dev_kfree_skb(skb); + } else { + WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n"); + } + break; + + default: + WLAN_LOG_WARNING("Received frame on unsupported port=%d\n", + HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) ); + goto done; + break; + } + +done: + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_int_rxmonitor +* +* Helper function for int_rx. Handles monitor frames. +* Note that this function allocates space for the FCS and sets it +* to 0xffffffff. The hfa384x doesn't give us the FCS value but the +* higher layers expect it. 0xffffffff is used as a flag to indicate +* the FCS is bogus. +* +* Arguments: +* wlandev wlan device structure +* rxfrm rx descriptor read from card in int_rx +* +* Returns: +* nothing +* +* Side effects: +* Allocates an skb and passes it up via the PF_PACKET interface. +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm) +{ + hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc); + UINT hdrlen = 0; + UINT datalen = 0; + UINT skblen = 0; + p80211msg_lnxind_wlansniffrm_t *msg; + UINT8 *datap; + UINT16 fc; + struct sk_buff *skb; + hfa384x_t *hw = wlandev->priv; + + + DBFENTER; + /* Don't forget the status, time, and data_len fields are in host order */ + /* Figure out how big the frame is */ + fc = ieee2host16(rxdesc->frame_control); + hdrlen = p80211_headerlen(fc); + datalen = hfa384x2host_16(rxdesc->data_len); + + /* Allocate an ind message+framesize skb */ + skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + + hdrlen + datalen + WLAN_CRC_LEN; + + /* sanity check the length */ + if ( skblen > + (sizeof(p80211msg_lnxind_wlansniffrm_t) + + WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) { + WLAN_LOG_DEBUG(1, "overlen frm: len=%zd\n", + skblen - sizeof(p80211msg_lnxind_wlansniffrm_t)); + } + + if ( (skb = dev_alloc_skb(skblen)) == NULL ) { + WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen); + return; + } + + /* only prepend the prism header if in the right mode */ + if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr == 0)) { + datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t)); + msg = (p80211msg_lnxind_wlansniffrm_t*) datap; + + /* Initialize the message members */ + msg->msgcode = DIDmsg_lnxind_wlansniffrm; + msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t); + strcpy(msg->devname, wlandev->name); + + msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; + msg->hosttime.status = 0; + msg->hosttime.len = 4; + msg->hosttime.data = jiffies; + + msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; + msg->mactime.status = 0; + msg->mactime.len = 4; + msg->mactime.data = rxdesc->time; + + msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel; + msg->channel.status = 0; + msg->channel.len = 4; + msg->channel.data = hw->sniff_channel; + + msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; + msg->rssi.status = P80211ENUM_msgitem_status_no_value; + msg->rssi.len = 4; + msg->rssi.data = 0; + + msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq; + msg->sq.status = P80211ENUM_msgitem_status_no_value; + msg->sq.len = 4; + msg->sq.data = 0; + + msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal; + msg->signal.status = 0; + msg->signal.len = 4; + msg->signal.data = rxdesc->signal; + + msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise; + msg->noise.status = 0; + msg->noise.len = 4; + msg->noise.data = rxdesc->silence; + + msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate; + msg->rate.status = 0; + msg->rate.len = 4; + msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */ + + msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx; + msg->istx.status = 0; + msg->istx.len = 4; + msg->istx.data = P80211ENUM_truth_false; + + msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; + msg->frmlen.status = 0; + msg->frmlen.len = 4; + msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN; + } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr != 0)) { + p80211_caphdr_t *caphdr; + /* The NEW header format! */ + datap = skb_put(skb, sizeof(p80211_caphdr_t)); + caphdr = (p80211_caphdr_t*) datap; + + caphdr->version = htonl(P80211CAPTURE_VERSION); + caphdr->length = htonl(sizeof(p80211_caphdr_t)); + caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000; + caphdr->hosttime = __cpu_to_be64(jiffies); + caphdr->phytype = htonl(4); /* dss_dot11_b */ + caphdr->channel = htonl(hw->sniff_channel); + caphdr->datarate = htonl(rxdesc->rate); + caphdr->antenna = htonl(0); /* unknown */ + caphdr->priority = htonl(0); /* unknown */ + caphdr->ssi_type = htonl(3); /* rssi_raw */ + caphdr->ssi_signal = htonl(rxdesc->signal); + caphdr->ssi_noise = htonl(rxdesc->silence); + caphdr->preamble = htonl(0); /* unknown */ + caphdr->encoding = htonl(1); /* cck */ + } + + /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */ + datap = skb_put(skb, hdrlen); + memcpy( datap, &(rxdesc->frame_control), hdrlen); + + /* If any, copy the data from the card to the skb */ + if ( datalen > 0 ) + { + datap = skb_put(skb, datalen); + memcpy(datap, rxfrm->data, datalen); + + /* check for unencrypted stuff if WEP bit set. */ + if (*(datap - hdrlen + 1) & 0x40) // wep set + if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa)) + *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header! + } + + if (hw->sniff_fcs) { + /* Set the FCS */ + datap = skb_put(skb, WLAN_CRC_LEN); + memset( datap, 0xff, WLAN_CRC_LEN); + } + + /* pass it back up */ + prism2sta_ev_rx(wlandev, skb); + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* hfa384x_usbin_info +* +* At this point we have a successful received a Prism2 info frame. +* +* Arguments: +* wlandev wlan device +* usbin ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin) +{ + DBFENTER; + + usbin->infofrm.info.framelen = hfa384x2host_16(usbin->infofrm.info.framelen); + prism2sta_ev_info(wlandev, &usbin->infofrm.info); + + DBFEXIT; +} + + + +/*---------------------------------------------------------------- +* hfa384x_usbout_callback +* +* Callback for URBs on the BULKOUT endpoint. +* +* Arguments: +* urb ptr to the completed urb +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +#ifdef URB_ONLY_CALLBACK +static void hfa384x_usbout_callback(struct urb *urb) +#else +static void hfa384x_usbout_callback(struct urb *urb, struct pt_regs *regs) +#endif +{ + wlandevice_t *wlandev = urb->context; + hfa384x_usbout_t *usbout = urb->transfer_buffer; + DBFENTER; + +#ifdef DEBUG_USB + dbprint_urb(urb); +#endif + + if ( wlandev && + wlandev->netdev ) { + + switch(urb->status) { + case 0: + hfa384x_usbout_tx(wlandev, usbout); + break; + + case -EPIPE: + { + hfa384x_t *hw = wlandev->priv; + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + wlandev->netdev->name); + if ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) + schedule_work(&hw->usb_work); + ++(wlandev->linux_stats.tx_errors); + break; + } + + case -EPROTO: + case -ETIMEDOUT: + case -EILSEQ: + { + hfa384x_t *hw = wlandev->priv; + + if ( !test_and_set_bit(THROTTLE_TX, &hw->usb_flags) + && !timer_pending(&hw->throttle) ) { + mod_timer(&hw->throttle, + jiffies + THROTTLE_JIFFIES); + } + ++(wlandev->linux_stats.tx_errors); + netif_stop_queue(wlandev->netdev); + break; + } + + case -ENOENT: + case -ESHUTDOWN: + /* Ignorable errors */ + break; + + default: + WLAN_LOG_INFO("unknown urb->status=%d\n", urb->status); + ++(wlandev->linux_stats.tx_errors); + break; + } /* switch */ + } + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_ctlxout_callback +* +* Callback for control data on the BULKOUT endpoint. +* +* Arguments: +* urb ptr to the completed urb +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +#ifdef URB_ONLY_CALLBACK +static void hfa384x_ctlxout_callback(struct urb *urb) +#else +static void hfa384x_ctlxout_callback(struct urb *urb, struct pt_regs *regs) +#endif +{ + hfa384x_t *hw = urb->context; + int delete_resptimer = 0; + int timer_ok = 1; + int run_queue = 0; + hfa384x_usbctlx_t *ctlx; + unsigned long flags; + + DBFENTER; + + WLAN_LOG_DEBUG(3,"urb->status=%d\n", urb->status); +#ifdef DEBUG_USB + dbprint_urb(urb); +#endif + if ( (urb->status == -ESHUTDOWN) || + (urb->status == -ENODEV) || + (hw == NULL) ) + goto done; + +retry: + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* + * Only one CTLX at a time on the "active" list, and + * none at all if we are unplugged. However, we can + * rely on the disconnect function to clean everything + * up if someone unplugged the adapter. + */ + if ( list_empty(&hw->ctlxq.active) ) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + goto done; + } + + /* + * Having something on the "active" queue means + * that we have timers to worry about ... + */ + if (del_timer(&hw->reqtimer) == 0) { + if (hw->req_timer_done == 0) { + /* + * This timer was actually running while we + * were trying to delete it. Let it terminate + * gracefully instead. + */ + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + goto retry; + } + } + else { + hw->req_timer_done = 1; + } + + ctlx = get_active_ctlx(hw); + + if ( urb->status == 0 ) { + /* Request portion of a CTLX is successful */ + switch ( ctlx->state ) { + case CTLX_REQ_SUBMITTED: + /* This OUT-ACK received before IN */ + ctlx->state = CTLX_REQ_COMPLETE; + break; + + case CTLX_RESP_COMPLETE: + /* IN already received before this OUT-ACK, + * so this command must now be complete. + */ + ctlx->state = CTLX_COMPLETE; + unlocked_usbctlx_complete(hw, ctlx); + run_queue = 1; + break; + + default: + /* This is NOT a valid CTLX "success" state! */ + WLAN_LOG_ERROR( + "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n", + hfa384x2host_16(ctlx->outbuf.type), + ctlxstr(ctlx->state), urb->status); + break; + } /* switch */ + } else { + /* If the pipe has stalled then we need to reset it */ + if ( (urb->status == -EPIPE) && + !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) { + WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n", + hw->wlandev->netdev->name); + schedule_work(&hw->usb_work); + } + + /* If someone cancels the OUT URB then its status + * should be either -ECONNRESET or -ENOENT. + */ + ctlx->state = CTLX_REQ_FAILED; + unlocked_usbctlx_complete(hw, ctlx); + delete_resptimer = 1; + run_queue = 1; + } + + delresp: + if (delete_resptimer) { + if ((timer_ok = del_timer(&hw->resptimer)) != 0) { + hw->resp_timer_done = 1; + } + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + if ( !timer_ok && (hw->resp_timer_done == 0) ) { + spin_lock_irqsave(&hw->ctlxq.lock, flags); + goto delresp; + } + + if (run_queue) + hfa384x_usbctlxq_run(hw); + + done: + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_reqtimerfn +* +* Timer response function for CTLX request timeouts. If this +* function is called, it means that the callback for the OUT +* URB containing a Prism2.x XXX_Request was never called. +* +* Arguments: +* data a ptr to the hfa384x_t +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_usbctlx_reqtimerfn(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + unsigned long flags; + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + hw->req_timer_done = 1; + + /* Removing the hardware automatically empties + * the active list ... + */ + if ( !list_empty(&hw->ctlxq.active) ) + { + /* + * We must ensure that our URB is removed from + * the system, if it hasn't already expired. + */ + hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK; + if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) + { + hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw); + + ctlx->state = CTLX_REQ_FAILED; + + /* This URB was active, but has now been + * cancelled. It will now have a status of + * -ECONNRESET in the callback function. + * + * We are cancelling this CTLX, so we're + * not going to need to wait for a response. + * The URB's callback function will check + * that this timer is truly dead. + */ + if (del_timer(&hw->resptimer) != 0) + hw->resp_timer_done = 1; + } + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_resptimerfn +* +* Timer response function for CTLX response timeouts. If this +* function is called, it means that the callback for the IN +* URB containing a Prism2.x XXX_Response was never called. +* +* Arguments: +* data a ptr to the hfa384x_t +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void +hfa384x_usbctlx_resptimerfn(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + hw->resp_timer_done = 1; + + /* The active list will be empty if the + * adapter has been unplugged ... + */ + if ( !list_empty(&hw->ctlxq.active) ) + { + hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw); + + if ( unlocked_usbctlx_cancel_async(hw, ctlx) == 0 ) + { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + hfa384x_usbctlxq_run(hw); + goto done; + } + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + done: + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_usb_throttlefn +* +* +* Arguments: +* data ptr to hw +* +* Returns: +* Nothing +* +* Side effects: +* +* Call context: +* Interrupt +----------------------------------------------------------------*/ +static void +hfa384x_usb_throttlefn(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t*)data; + unsigned long flags; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + /* + * We need to check BOTH the RX and the TX throttle controls, + * so we use the bitwise OR instead of the logical OR. + */ + WLAN_LOG_DEBUG(3, "flags=0x%lx\n", hw->usb_flags); + if ( !hw->wlandev->hwremoved && + ( + (test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) && + !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags)) + | + (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) && + !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags)) + ) ) + { + schedule_work(&hw->usb_work); + } + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbctlx_submit +* +* Called from the doxxx functions to submit a CTLX to the queue +* +* Arguments: +* hw ptr to the hw struct +* ctlx ctlx structure to enqueue +* +* Returns: +* -ENODEV if the adapter is unplugged +* 0 +* +* Side effects: +* +* Call context: +* process or interrupt +----------------------------------------------------------------*/ +static int +hfa384x_usbctlx_submit( + hfa384x_t *hw, + hfa384x_usbctlx_t *ctlx) +{ + unsigned long flags; + int ret; + + DBFENTER; + + spin_lock_irqsave(&hw->ctlxq.lock, flags); + + if (hw->wlandev->hwremoved) { + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + ret = -ENODEV; + } else { + ctlx->state = CTLX_PENDING; + list_add_tail(&ctlx->list, &hw->ctlxq.pending); + + spin_unlock_irqrestore(&hw->ctlxq.lock, flags); + hfa384x_usbctlxq_run(hw); + ret = 0; + } + + DBFEXIT; + return ret; +} + + +/*---------------------------------------------------------------- +* hfa384x_usbout_tx +* +* At this point we have finished a send of a frame. Mark the URB +* as available and call ev_alloc to notify higher layers we're +* ready for more. +* +* Arguments: +* wlandev wlan device +* usbout ptr to the usb transfer buffer +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout) +{ + DBFENTER; + + prism2sta_ev_alloc(wlandev); + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_isgood_pdrcore +* +* Quick check of PDR codes. +* +* Arguments: +* pdrcode PDR code number (host order) +* +* Returns: +* zero not good. +* one is good. +* +* Side effects: +* +* Call context: +----------------------------------------------------------------*/ +static int +hfa384x_isgood_pdrcode(UINT16 pdrcode) +{ + switch(pdrcode) { + case HFA384x_PDR_END_OF_PDA: + case HFA384x_PDR_PCB_PARTNUM: + case HFA384x_PDR_PDAVER: + case HFA384x_PDR_NIC_SERIAL: + case HFA384x_PDR_MKK_MEASUREMENTS: + case HFA384x_PDR_NIC_RAMSIZE: + case HFA384x_PDR_MFISUPRANGE: + case HFA384x_PDR_CFISUPRANGE: + case HFA384x_PDR_NICID: + case HFA384x_PDR_MAC_ADDRESS: + case HFA384x_PDR_REGDOMAIN: + case HFA384x_PDR_ALLOWED_CHANNEL: + case HFA384x_PDR_DEFAULT_CHANNEL: + case HFA384x_PDR_TEMPTYPE: + case HFA384x_PDR_IFR_SETTING: + case HFA384x_PDR_RFR_SETTING: + case HFA384x_PDR_HFA3861_BASELINE: + case HFA384x_PDR_HFA3861_SHADOW: + case HFA384x_PDR_HFA3861_IFRF: + case HFA384x_PDR_HFA3861_CHCALSP: + case HFA384x_PDR_HFA3861_CHCALI: + case HFA384x_PDR_3842_NIC_CONFIG: + case HFA384x_PDR_USB_ID: + case HFA384x_PDR_PCI_ID: + case HFA384x_PDR_PCI_IFCONF: + case HFA384x_PDR_PCI_PMCONF: + case HFA384x_PDR_RFENRGY: + case HFA384x_PDR_HFA3861_MANF_TESTSP: + case HFA384x_PDR_HFA3861_MANF_TESTI: + /* code is OK */ + return 1; + break; + default: + if ( pdrcode < 0x1000 ) { + /* code is OK, but we don't know exactly what it is */ + WLAN_LOG_DEBUG(3, + "Encountered unknown PDR#=0x%04x, " + "assuming it's ok.\n", + pdrcode); + return 1; + } else { + /* bad code */ + WLAN_LOG_DEBUG(3, + "Encountered unknown PDR#=0x%04x, " + "(>=0x1000), assuming it's bad.\n", + pdrcode); + return 0; + } + break; + } + return 0; /* avoid compiler warnings */ +} + --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2mgmt.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2mgmt.c @@ -0,0 +1,2956 @@ +/* src/prism2/driver/prism2mgmt.c +* +* Management request handler functions. +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* The functions in this file handle management requests sent from +* user mode. +* +* Most of these functions have two separate blocks of code that are +* conditional on whether this is a station or an AP. This is used +* to separate out the STA and AP responses to these management primitives. +* It's a choice (good, bad, indifferent?) to have the code in the same +* place so it's clear that the same primitive is implemented in both +* cases but has different behavior. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (WLAN_HOSTIF == WLAN_USB) +#include +#endif + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#include +#include +#include +#include +#include +#include +#endif + +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + + +/*================================================================*/ +/* Local Macros */ + +/* Converts 802.11 format rate specifications to prism2 */ +#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \ + (((n)&~BIT7) == 4) ? BIT1 : \ + (((n)&~BIT7) == 11) ? BIT2 : \ + (((n)&~BIT7) == 22) ? BIT3 : 0) + +/*================================================================*/ +/* Local Types */ + + +/*================================================================*/ +/* Local Static Definitions */ + + +/*================================================================*/ +/* Local Function Declarations */ + + +/*================================================================*/ +/* Function Definitions */ + + +/*---------------------------------------------------------------- +* prism2mgmt_powermgmt +* +* Set the power management state of this station's MAC. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_powermgmt_t *msg = msgp; + + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* + * Set CNFPMENABLED (on or off) + * Set CNFMULTICASTRX (if PM on, otherwise clear) + * Spout a notice stating that SleepDuration and + * HoldoverDuration and PMEPS also have an impact. + */ + /* Powermgmt is currently unsupported for STA */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Powermgmt is never supported for AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_scan +* +* Initiate a scan for BSSs. +* +* This function corresponds to MLME-scan.request and part of +* MLME-scan.confirm. As far as I can tell in the standard, there +* are no restrictions on when a scan.request may be issued. We have +* to handle in whatever state the driver/MAC happen to be. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_scan_t *msg = msgp; + UINT16 roamingmode, word; + int i, timeout; + int istmpenable = 0; + + hfa384x_HostScanRequest_data_t scanreq; + + DBFENTER; + + if (hw->ap) { + WLAN_LOG_ERROR("Prism2 in AP mode cannot perform scans.\n"); + result = 1; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto exit; + } + + /* gatekeeper check */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) < + HFA384x_FIRMWARE_VERSION(1,3,2)) { + WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n"); + result = 1; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto exit; + } + + memset(&scanreq, 0, sizeof(scanreq)); + + /* save current roaming mode */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_CNFROAMINGMODE, &roamingmode); + if ( result ) { + WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + /* drop into mode 3 for the scan */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFROAMINGMODE, + HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); + if ( result ) { + WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + /* active or passive? */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) > + HFA384x_FIRMWARE_VERSION(1,5,0)) { + if (msg->scantype.data != P80211ENUM_scantype_active) { + word = host2hfa384x_16(msg->maxchanneltime.data); + } else { + word = 0; + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word); + if ( result ) { + WLAN_LOG_WARNING("Passive scan not supported with " + "current firmware. (<1.5.1)\n"); + } + } + + /* set up the txrate to be 2MBPS. Should be fastest basicrate... */ + word = HFA384x_RATEBIT_2; + scanreq.txRate = host2hfa384x_16(word); + + /* set up the channel list */ + word = 0; + for (i = 0; i < msg->channellist.data.len; i++) { + UINT8 channel = msg->channellist.data.data[i]; + if (channel > 14) continue; + /* channel 1 is BIT0 ... channel 14 is BIT13 */ + word |= (1 << (channel-1)); + } + scanreq.channelList = host2hfa384x_16(word); + + /* set up the ssid, if present. */ + scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len); + memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len); + + /* Enable the MAC port if it's not already enabled */ + result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word); + if ( result ) { + WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. " + "result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + if (word == HFA384x_PORTSTATUS_DISABLED) { + UINT16 wordbuf[17]; + + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFROAMINGMODE, + HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); + if ( result ) { + WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + /* Construct a bogus SSID and assign it to OwnSSID and + * DesiredSSID + */ + wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN); + get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN); + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID, + wordbuf, HFA384x_RID_CNFOWNSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set OwnSSID.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID, + wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set DesiredSSID.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + /* bsstype */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFPORTTYPE, + HFA384x_PORTTYPE_IBSS); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + /* ibss options */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CREATEIBSS, + HFA384x_CREATEIBSS_JOINCREATEIBSS); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("drvr_enable(0) failed. " + "result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + istmpenable = 1; + } + + /* Figure out our timeout first Kus, then HZ */ + timeout = msg->channellist.data.len * msg->maxchanneltime.data; + timeout = (timeout * HZ)/1000; + + /* Issue the scan request */ + hw->scanflag = 0; + + WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq)); + + result = hfa384x_drvr_setconfig( hw, + HFA384x_RID_HOSTSCAN, &scanreq, + sizeof(hfa384x_HostScanRequest_data_t)); + if ( result ) { + WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + /* sleep until info frame arrives */ + wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout); + + msg->numbss.status = P80211ENUM_msgitem_status_data_ok; + if (hw->scanflag == -1) + hw->scanflag = 0; + + msg->numbss.data = hw->scanflag; + + hw->scanflag = 0; + + /* Disable port if we temporarily enabled it. */ + if (istmpenable) { + result = hfa384x_drvr_disable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("drvr_disable(0) failed. " + "result=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + } + + /* restore original roaming mode */ + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, + roamingmode); + if ( result ) { + WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + goto exit; + } + + result = 0; + msg->resultcode.data = P80211ENUM_resultcode_success; + + exit: + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_scan_results +* +* Retrieve the BSS description for one of the BSSs identified in +* a scan. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + p80211msg_dot11req_scan_results_t *req; + hfa384x_t *hw = wlandev->priv; + hfa384x_HScanResultSub_t *item = NULL; + + int count; + + DBFENTER; + + req = (p80211msg_dot11req_scan_results_t *) msgp; + + req->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + if (hw->ap) { + result = 1; + req->resultcode.data = P80211ENUM_resultcode_not_supported; + goto exit; + } + + if (! hw->scanresults) { + WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n"); + result = 2; + req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + goto exit; + } + + count = (hw->scanresults->framelen - 3) / 32; + if (count > 32) count = 32; + + if (req->bssindex.data >= count) { + WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n", + req->bssindex.data, count); + result = 2; + req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + goto exit; + } + + item = &(hw->scanresults->info.hscanresult.result[req->bssindex.data]); + /* signal and noise */ + req->signal.status = P80211ENUM_msgitem_status_data_ok; + req->noise.status = P80211ENUM_msgitem_status_data_ok; + req->signal.data = hfa384x2host_16(item->sl); + req->noise.data = hfa384x2host_16(item->anl); + + /* BSSID */ + req->bssid.status = P80211ENUM_msgitem_status_data_ok; + req->bssid.data.len = WLAN_BSSID_LEN; + memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN); + + /* SSID */ + req->ssid.status = P80211ENUM_msgitem_status_data_ok; + req->ssid.data.len = hfa384x2host_16(item->ssid.len); + memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len); + + /* supported rates */ + for (count = 0; count < 10 ; count++) + if (item->supprates[count] == 0) + break; + +#define REQBASICRATE(N) \ + if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \ + req->basicrate ## N .data = item->supprates[(N)-1]; \ + req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \ + } + + REQBASICRATE(1); + REQBASICRATE(2); + REQBASICRATE(3); + REQBASICRATE(4); + REQBASICRATE(5); + REQBASICRATE(6); + REQBASICRATE(7); + REQBASICRATE(8); + +#define REQSUPPRATE(N) \ + if (count >= N) { \ + req->supprate ## N .data = item->supprates[(N)-1]; \ + req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \ + } + + REQSUPPRATE(1); + REQSUPPRATE(2); + REQSUPPRATE(3); + REQSUPPRATE(4); + REQSUPPRATE(5); + REQSUPPRATE(6); + REQSUPPRATE(7); + REQSUPPRATE(8); + + /* beacon period */ + req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok; + req->beaconperiod.data = hfa384x2host_16(item->bcnint); + + /* timestamps */ + req->timestamp.status = P80211ENUM_msgitem_status_data_ok; + req->timestamp.data = jiffies; + req->localtime.status = P80211ENUM_msgitem_status_data_ok; + req->localtime.data = jiffies; + + /* atim window */ + req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok; + req->ibssatimwindow.data = hfa384x2host_16(item->atim); + + /* Channel */ + req->dschannel.status = P80211ENUM_msgitem_status_data_ok; + req->dschannel.data = hfa384x2host_16(item->chid); + + /* capinfo bits */ + count = hfa384x2host_16(item->capinfo); + + /* privacy flag */ + req->privacy.status = P80211ENUM_msgitem_status_data_ok; + req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count); + + /* cfpollable */ + req->cfpollable.status = P80211ENUM_msgitem_status_data_ok; + req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count); + + /* cfpollreq */ + req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok; + req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count); + + /* bsstype */ + req->bsstype.status = P80211ENUM_msgitem_status_data_ok; + req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ? + P80211ENUM_bsstype_infrastructure : + P80211ENUM_bsstype_independent; + + // item->proberesp_rate +/* + req->fhdwelltime + req->fhhopset + req->fhhoppattern + req->fhhopindex + req->cfpdurremaining +*/ + + result = 0; + req->resultcode.data = P80211ENUM_resultcode_success; + + exit: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_join +* +* Join a BSS whose BSS description was previously obtained with +* a scan. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_join(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_join_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Implement after scan */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Never supported by APs */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_p2_join +* +* Join a specific BSS +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_join_t *msg = msgp; + UINT16 reg; + p80211pstrd_t *pstr; + UINT8 bytebuf[256]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf; + hfa384x_JoinRequest_data_t joinreq; + DBFENTER; + + if (!hw->ap) { + + wlandev->macmode = WLAN_MACMODE_NONE; + + /*** STATION ***/ + /* Set the PortType */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + /* ess port */ + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1); + if ( result ) { + WLAN_LOG_ERROR("Failed to set Port Type\n"); + goto failed; + } + + /* Set the auth type */ + if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) { + reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY; + } else { + reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set Authentication\n"); + goto failed; + } + + /* Turn off all roaming */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, 3); + if ( result ) { + WLAN_LOG_ERROR("Failed to Turn off Roaming\n"); + goto failed; + } + + /* Basic rates */ + reg = 0; + if ( msg->basicrate1.status == P80211ENUM_msgitem_status_data_ok ) { + reg = p80211rate_to_p2bit(msg->basicrate1.data); + } + if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate2.data); + } + if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate3.data); + } + if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate4.data); + } + if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate5.data); + } + if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate6.data); + } + if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate7.data); + } + if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->basicrate8.data); + } + if( reg == 0) + reg = 0x03; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", reg); + goto failed; + } + + /* Operational rates (supprates and txratecontrol) */ + reg = 0; + if ( msg->operationalrate1.status == P80211ENUM_msgitem_status_data_ok ) { + reg = p80211rate_to_p2bit(msg->operationalrate1.data); + } + if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate2.data); + } + if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate3.data); + } + if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate4.data); + } + if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate5.data); + } + if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate6.data); + } + if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate7.data); + } + if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) { + reg |= p80211rate_to_p2bit(msg->operationalrate8.data); + } + if( reg == 0) + reg = 0x0f; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set supprates=%d.\n", reg); + goto failed; + } + + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg); + if ( result ) { + WLAN_LOG_ERROR("Failed to set txrates=%d.\n", reg); + goto failed; + } + + /* Set the ssid */ + memset(bytebuf, 0, 256); + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( + hw, HFA384x_RID_CNFDESIREDSSID, + bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set SSID\n"); + goto failed; + } + + /* Enable the Port */ + result = hfa384x_cmd_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + /* Fill in the join request */ + joinreq.channel = msg->channel.data; + memcpy( joinreq.bssid, ((unsigned char *) &msg->bssid.data) + 1, WLAN_BSSID_LEN); + hw->joinreq = joinreq; + hw->join_ap = 1; + + /* Send the join request */ + result = hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + if(result != 0) { + WLAN_LOG_ERROR("Join request failed, result=%d.\n", result); + goto failed; + } + + } else { + + /*** ACCESS POINT ***/ + + /* Never supported by APs */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + goto done; +failed: + WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result); + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + +done: + result = 0; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_authenticate +* +* Station should be begin an authentication exchange. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_authenticate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Decide how we're going to handle this one w/ Prism2 */ + /* It could be entertaining since Prism2 doesn't have */ + /* an explicit way to control this */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Never supported by APs */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_deauthenticate +* +* Send a deauthenticate notification. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_deauthenticate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Decide how we're going to handle this one w/ Prism2 */ + /* It could be entertaining since Prism2 doesn't have */ + /* an explicit way to control this */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data); + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_associate +* +* Associate with an ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + int result = 0; + p80211msg_dot11req_associate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + +#if 0 + /* Set the TxRates */ + reg = 0x000f; + hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, reg); +#endif + + /* Set the PortType */ + /* ess port */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 1); + + /* Enable the Port */ + hfa384x_drvr_enable(hw, 0); + + /* Set the resultcode */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + } else { + + /*** ACCESS POINT ***/ + + /* Never supported on AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_reassociate +* +* Renew association because of a BSS change. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_reassociate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Not supported yet...not sure how we're going to do it */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + + /* Never supported on AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_disassociate +* +* Send a disassociation notification. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_disassociate_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* TODO: Not supported yet...not sure how to do it */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } else { + + /*** ACCESS POINT ***/ + hfa384x_drvr_handover(hw, msg->peerstaaddress.data.data); + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_reset +* +* Reset the MAC and MSD. The p80211 layer has it's own handling +* that should be done before and after this function. +* Procedure: +* - disable system interrupts ?? +* - disable MAC interrupts +* - restore system interrupts +* - issue the MAC initialize command +* - clear any MSD level state (including timers, queued events, +* etc.). Note that if we're removing timer'd/queue events, we may +* need to have remained in the system interrupt disabled state. +* We should be left in the same state that we're in following +* driver initialization. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer, MAY BE NULL! for a driver local +* call. +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread, commonly wlanctl, but might be rmmod/pci_close. +----------------------------------------------------------------*/ +int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_reset_t *msg = msgp; + DBFENTER; + + /* + * This is supported on both AP and STA and it's not allowed + * to fail. + */ + if ( msgp ) { + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + WLAN_LOG_INFO("dot11req_reset: the macaddress and " + "setdefaultmib arguments are currently unsupported.\n"); + } + + /* + * If we got this far, the MSD must be in the MSDRUNNING state + * therefore, we must stop and then restart the hw/MAC combo. + */ + hfa384x_drvr_stop(hw); + result = hfa384x_drvr_start(hw); + if (result != 0) { + WLAN_LOG_ERROR("dot11req_reset: Initialize command failed," + " bad things will happen from here.\n"); + return 0; + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_start +* +* Start a BSS. Any station can do this for IBSS, only AP for ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_start(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_dot11req_start_t *msg = msgp; + + p80211pstrd_t *pstr; + UINT8 bytebuf[80]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf; + hfa384x_PCFInfo_data_t *pcfinfo = (hfa384x_PCFInfo_data_t*)bytebuf; + UINT16 word; + DBFENTER; + + wlandev->macmode = WLAN_MACMODE_NONE; + + /* Set the SSID */ + memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); + + if (!hw->ap) { + /*** ADHOC IBSS ***/ + /* see if current f/w is less than 8c3 */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) < + HFA384x_FIRMWARE_VERSION(0,8,3)) { + /* Ad-Hoc not quite supported on Prism2 */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /*** STATION ***/ + /* Set the REQUIRED config items */ + /* SSID */ + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID, + bytebuf, HFA384x_RID_CNFOWNSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n"); + goto failed; + } + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID, + bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n"); + goto failed; + } + + /* bsstype - we use the default in the ap firmware */ + /* IBSS port */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0); + + /* beacon period */ + word = msg->beaconperiod.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word); + goto failed; + } + + /* dschannel */ + word = msg->dschannel.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set channel=%d.\n", word); + goto failed; + } + /* Basic rates */ + word = p80211rate_to_p2bit(msg->basicrate1.data); + if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate2.data); + } + if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate3.data); + } + if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate4.data); + } + if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate5.data); + } + if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate6.data); + } + if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate7.data); + } + if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word); + goto failed; + } + + /* Operational rates (supprates and txratecontrol) */ + word = p80211rate_to_p2bit(msg->operationalrate1.data); + if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate2.data); + } + if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate3.data); + } + if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate4.data); + } + if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate5.data); + } + if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate6.data); + } + if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate7.data); + } + if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word); + goto failed; + } + + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word); + goto failed; + } + + /* Set the macmode so the frame setup code knows what to do */ + if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) { + wlandev->macmode = WLAN_MACMODE_IBSS_STA; + /* lets extend the data length a bit */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304); + } + + /* Enable the Port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + + goto done; + } + + /*** ACCESS POINT ***/ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* Validate the command, if BSStype=infra is the tertiary loaded? */ + if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) { + WLAN_LOG_ERROR("AP driver cannot create IBSS.\n"); + goto failed; + } else if ( hw->cap_sup_sta.id != 5) { + WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n"); + goto failed; + } + + /* Set the REQUIRED config items */ + /* SSID */ + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID, + bytebuf, HFA384x_RID_CNFOWNSSID_LEN); + if ( result ) { + WLAN_LOG_ERROR("Failed to set SSID, result=0x%04x\n", result); + goto failed; + } + + /* bsstype - we use the default in the ap firmware */ + + /* beacon period */ + word = msg->beaconperiod.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word); + goto failed; + } + + /* dschannel */ + word = msg->dschannel.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set channel=%d.\n", word); + goto failed; + } + /* Basic rates */ + word = p80211rate_to_p2bit(msg->basicrate1.data); + if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate2.data); + } + if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate3.data); + } + if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate4.data); + } + if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate5.data); + } + if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate6.data); + } + if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate7.data); + } + if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->basicrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word); + goto failed; + } + + /* Operational rates (supprates and txratecontrol) */ + word = p80211rate_to_p2bit(msg->operationalrate1.data); + if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate2.data); + } + if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate3.data); + } + if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate4.data); + } + if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate5.data); + } + if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate6.data); + } + if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate7.data); + } + if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) { + word |= p80211rate_to_p2bit(msg->operationalrate8.data); + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word); + goto failed; + } + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL0, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word); + goto failed; + } + + /* ibssatimwindow */ + if (msg->ibssatimwindow.status == P80211ENUM_msgitem_status_data_ok) { + WLAN_LOG_INFO("prism2mgmt_start: atimwindow not used in " + "Infrastructure mode, ignored.\n"); + } + + /* DTIM period */ + word = msg->dtimperiod.data; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNDTIMPER, word); + if ( result ) { + WLAN_LOG_ERROR("Failed to set dtim period=%d.\n", word); + goto failed; + } + + /* probedelay */ + if (msg->probedelay.status == P80211ENUM_msgitem_status_data_ok) { + WLAN_LOG_INFO("prism2mgmt_start: probedelay not " + "supported in prism2, ignored.\n"); + } + + /* cfpollable, cfpollreq, cfpperiod, cfpmaxduration */ + if (msg->cfpollable.data == P80211ENUM_truth_true && + msg->cfpollreq.data == P80211ENUM_truth_true ) { + WLAN_LOG_ERROR("cfpollable=cfpollreq=true is illegal.\n"); + result = -1; + goto failed; + } + + /* read the PCFInfo and update */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO, + pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN); + if ( result ) { + WLAN_LOG_INFO("prism2mgmt_start: read(pcfinfo) failed, " + "assume it's " + "not supported, pcf settings ignored.\n"); + goto pcf_skip; + } + if ((msg->cfpollable.data == P80211ENUM_truth_false && + msg->cfpollreq.data == P80211ENUM_truth_false) ) { + pcfinfo->MediumOccupancyLimit = 0; + pcfinfo->CFPPeriod = 0; + pcfinfo->CFPMaxDuration = 0; + pcfinfo->CFPFlags &= host2hfa384x_16((UINT16)~BIT0); + + if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok || + msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok ) { + WLAN_LOG_WARNING( + "Setting cfpperiod or cfpmaxduration when " + "cfpollable and cfreq are false is pointless.\n"); + } + } + if ((msg->cfpollable.data == P80211ENUM_truth_true || + msg->cfpollreq.data == P80211ENUM_truth_true) ) { + if ( msg->cfpollable.data == P80211ENUM_truth_true) { + pcfinfo->CFPFlags |= host2hfa384x_16((UINT16)BIT0); + } + + if ( msg->cfpperiod.status == P80211ENUM_msgitem_status_data_ok) { + pcfinfo->CFPPeriod = msg->cfpperiod.data; + pcfinfo->CFPPeriod = host2hfa384x_16(pcfinfo->CFPPeriod); + } + + if ( msg->cfpmaxduration.status == P80211ENUM_msgitem_status_data_ok) { + pcfinfo->CFPMaxDuration = msg->cfpmaxduration.data; + pcfinfo->CFPMaxDuration = host2hfa384x_16(pcfinfo->CFPMaxDuration); + pcfinfo->MediumOccupancyLimit = pcfinfo->CFPMaxDuration; + } + } + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO, + pcfinfo, HFA384x_RID_CNFAPPCFINFO_LEN); + if ( result ) { + WLAN_LOG_ERROR("write(pcfinfo) failed.\n"); + goto failed; + } + +pcf_skip: + /* Set the macmode so the frame setup code knows what to do */ + if ( msg->bsstype.data == P80211ENUM_bsstype_infrastructure ) { + wlandev->macmode = WLAN_MACMODE_ESS_AP; + /* lets extend the data length a bit */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304); + } + + /* Set the BSSID to the same as our MAC */ + memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN); + + /* Enable the Port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + + goto done; +failed: + WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result); + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + +done: + result = 0; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_enable +* +* Start a BSS. Any station can do this for IBSS, only AP for ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_enable_t *msg = msgp; + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* Ad-Hoc not quite supported on Prism2 */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + /*** ACCESS POINT ***/ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* Is the tertiary loaded? */ + if ( hw->cap_sup_sta.id != 5) { + WLAN_LOG_ERROR("AP driver failed to detect AP firmware.\n"); + goto failed; + } + + /* Set the macmode so the frame setup code knows what to do */ + wlandev->macmode = WLAN_MACMODE_ESS_AP; + + /* Set the BSSID to the same as our MAC */ + memcpy( wlandev->bssid, wlandev->netdev->dev_addr, WLAN_BSSID_LEN); + + /* Enable the Port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result); + goto failed; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + + goto done; +failed: + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + +done: + result = 0; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_readpda +* +* Collect the PDA data and put it in the message. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_readpda_t *msg = msgp; + int result; + DBFENTER; + + /* We only support collecting the PDA when in the FWLOAD + * state. + */ + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "PDA may only be read " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + } else { + /* Call drvr_readpda(), it handles the auxport enable + * and validating the returned PDA. + */ + result = hfa384x_drvr_readpda( + hw, + msg->pda.data, + HFA384x_PDA_LEN_MAX); + if (result) { + WLAN_LOG_ERROR( + "hfa384x_drvr_readpda() failed, " + "result=%d\n", + result); + + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = + P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + msg->pda.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + } + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_readcis +* +* Collect the CIS data and put it in the message. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp) +{ + int result; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_readcis_t *msg = msgp; + + DBFENTER; + + memset(msg->cis.data, 0, sizeof(msg->cis.data)); + + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CIS, + msg->cis.data, HFA384x_RID_CIS_LEN); + if ( result ) { + WLAN_LOG_INFO("prism2mgmt_readcis: read(cis) failed.\n"); + msg->cis.status = P80211ENUM_msgitem_status_no_value; + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + + } + else { + msg->cis.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_auxport_state +* +* Enables/Disables the card's auxiliary port. Should be called +* before and after a sequence of auxport_read()/auxport_write() +* calls. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp) +{ + p80211msg_p2req_auxport_state_t *msg = msgp; + +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + if (msg->enable.data == P80211ENUM_truth_true) { + if ( hfa384x_cmd_aux_enable(hw, 0) ) { + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } else { + msg->resultcode.data = P80211ENUM_resultcode_success; + } + } else { + hfa384x_cmd_aux_disable(hw); + msg->resultcode.data = P80211ENUM_resultcode_success; + } + +#else /* !USB */ + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + +#endif /* WLAN_HOSTIF != WLAN_USB */ + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_auxport_read +* +* Copies data from the card using the auxport. The auxport must +* have previously been enabled. Note: this is not the way to +* do downloads, see the [ram|flash]dl functions. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp) +{ +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_auxport_read_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8* buf; + UINT32 maxlen = sizeof(msg->data.data); + DBFENTER; + + if ( hw->auxen ) { + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( len <= maxlen ) { /* max read/write size */ + hfa384x_copy_from_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len); + msg->resultcode.data = P80211ENUM_resultcode_success; + } else { + WLAN_LOG_DEBUG(1,"Attempt to read > maxlen from auxport.\n"); + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + + } else { + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + msg->data.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return 0; +#else + DBFENTER; + + WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n"); + + DBFEXIT; + return 0; +#endif +} + + +/*---------------------------------------------------------------- +* prism2mgmt_auxport_write +* +* Copies data to the card using the auxport. The auxport must +* have previously been enabled. Note: this is not the way to +* do downloads, see the [ram|flash]dl functions. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp) +{ +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_auxport_write_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8* buf; + UINT32 maxlen = sizeof(msg->data.data); + DBFENTER; + + if ( hw->auxen ) { + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( len <= maxlen ) { /* max read/write size */ + hfa384x_copy_to_aux(hw, addr, HFA384x_AUX_CTL_EXTDS, buf, len); + } else { + WLAN_LOG_DEBUG(1,"Attempt to write > maxlen from auxport.\n"); + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + + } else { + msg->resultcode.data = P80211ENUM_resultcode_refused; + } + msg->data.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + DBFEXIT; + return 0; +#else + DBFENTER; + WLAN_LOG_ERROR("prism2mgmt_auxport_read: Not supported on USB.\n"); + DBFEXIT; + return 0; +#endif +} + +/*---------------------------------------------------------------- +* prism2mgmt_low_level +* +* Puts the card into the desired test mode. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_low_level_t *msg = msgp; + hfa384x_metacmd_t cmd; + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* call some routine to execute the test command */ + cmd.cmd = (UINT16) msg->command.data; + cmd.parm0 = (UINT16) msg->param0.data; + cmd.parm1 = (UINT16) msg->param1.data; + cmd.parm2 = (UINT16) msg->param2.data; + + hfa384x_drvr_low_level(hw,&cmd); + + msg->resp0.data = (UINT32) cmd.result.resp0; + msg->resp1.data = (UINT32) cmd.result.resp1; + msg->resp2.data = (UINT32) cmd.result.resp2; + + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_test_command +* +* Puts the card into the desired test mode. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_test_command_t *msg = msgp; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = ((UINT16) msg->testcode.data) << 8 | 0x38; + cmd.parm0 = (UINT16) msg->testparam.data; + cmd.parm1 = 0; + cmd.parm2 = 0; + + /* call some routine to execute the test command */ + + hfa384x_drvr_low_level(hw,&cmd); + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + msg->status.status = P80211ENUM_msgitem_status_data_ok; + msg->status.data = cmd.result.status; + msg->resp0.status = P80211ENUM_msgitem_status_data_ok; + msg->resp0.data = cmd.result.resp0; + msg->resp1.status = P80211ENUM_msgitem_status_data_ok; + msg->resp1.data = cmd.result.resp1; + msg->resp2.status = P80211ENUM_msgitem_status_data_ok; + msg->resp2.data = cmd.result.resp2; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_mmi_read +* +* Read from one of the MMI registers. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_mmi_read_t *msg = msgp; + UINT32 resp = 0; + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* call some routine to execute the test command */ + + hfa384x_drvr_mmi_read(hw, msg->addr.data, &resp); + + /* I'm not sure if this is "architecturally" correct, but it + is expedient. */ + + msg->value.status = P80211ENUM_msgitem_status_data_ok; + msg->value.data = resp; + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_mmi_write +* +* Write a data value to one of the MMI registers. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_mmi_write_t *msg = msgp; + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + /* call some routine to execute the test command */ + + hfa384x_drvr_mmi_write(hw, msg->addr.data, msg->data.data); + + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_ramdl_state +* +* Establishes the beginning/end of a card RAM download session. +* +* It is expected that the ramdl_write() function will be called +* one or more times between the 'enable' and 'disable' calls to +* this function. +* +* Note: This function should not be called when a mac comm port +* is active. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_ramdl_state_t *msg = msgp; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "ramdl_state(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + /* + ** Note: Interrupts are locked out if this is an AP and are NOT + ** locked out if this is a station. + */ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + if ( msg->enable.data == P80211ENUM_truth_true ) { + if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) { + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } else { + msg->resultcode.data = P80211ENUM_resultcode_success; + } + } else { + hfa384x_drvr_ramdl_disable(hw); + msg->resultcode.data = P80211ENUM_resultcode_success; + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_ramdl_write +* +* Writes a buffer to the card RAM using the download state. This +* is for writing code to card RAM. To just read or write raw data +* use the aux functions. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_ramdl_write_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8 *buf; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "ramdl_write(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + /* first validate the length */ + if ( msg->len.data > sizeof(msg->data.data) ) { + msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters; + return 0; + } + /* call the hfa384x function to do the write */ + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) { + msg->resultcode.data = P80211ENUM_resultcode_refused; + + } + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_flashdl_state +* +* Establishes the beginning/end of a card Flash download session. +* +* It is expected that the flashdl_write() function will be called +* one or more times between the 'enable' and 'disable' calls to +* this function. +* +* Note: This function should not be called when a mac comm port +* is active. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_flashdl_state_t *msg = msgp; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "flashdl_state(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + /* + ** Note: Interrupts are locked out if this is an AP and are NOT + ** locked out if this is a station. + */ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + if ( msg->enable.data == P80211ENUM_truth_true ) { + if ( hfa384x_drvr_flashdl_enable(hw) ) { + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } else { + msg->resultcode.data = P80211ENUM_resultcode_success; + } + } else { + hfa384x_drvr_flashdl_disable(hw); + msg->resultcode.data = P80211ENUM_resultcode_success; + /* NOTE: At this point, the MAC is in the post-reset + * state and the driver is in the fwload state. + * We need to get the MAC back into the fwload + * state. To do this, we set the nsdstate to HWPRESENT + * and then call the ifstate function to redo everything + * that got us into the fwload state. + */ + wlandev->msdstate = WLAN_MSD_HWPRESENT; + result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload); + if (result != P80211ENUM_resultcode_success) { + WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed," + "P80211ENUM_resultcode=%d\n", result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + result = -1; + } + } + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_flashdl_write +* +* +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + p80211msg_p2req_flashdl_write_t *msg = msgp; + UINT32 addr; + UINT32 len; + UINT8 *buf; + DBFENTER; + + if (wlandev->msdstate != WLAN_MSD_FWLOAD) { + WLAN_LOG_ERROR( + "flashdl_write(): may only be called " + "in the fwload state.\n"); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + DBFEXIT; + return 0; + } + + /* + ** Note: Interrupts are locked out if this is an AP and are NOT + ** locked out if this is a station. + */ + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + /* first validate the length */ + if ( msg->len.data > sizeof(msg->data.data) ) { + msg->resultcode.status = + P80211ENUM_resultcode_invalid_parameters; + return 0; + } + /* call the hfa384x function to do the write */ + addr = msg->addr.data; + len = msg->len.data; + buf = msg->data.data; + if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) { + msg->resultcode.data = P80211ENUM_resultcode_refused; + + } + msg->resultcode.data = P80211ENUM_resultcode_success; + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_dump_state +* +* Dumps the driver's and hardware's current state via the kernel +* log at KERN_NOTICE level. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp) +{ + p80211msg_p2req_dump_state_t *msg = msgp; + int result = 0; + +#if (WLAN_HOSTIF != WLAN_USB) + hfa384x_t *hw = wlandev->priv; + UINT16 auxbuf[15]; + DBFENTER; + + WLAN_LOG_NOTICE("prism2 driver and hardware state:\n"); + if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) { + WLAN_LOG_ERROR("aux_enable failed, result=%d\n", result); + goto failed; + } + hfa384x_copy_from_aux(hw, + 0x01e2, + HFA384x_AUX_CTL_EXTDS, + auxbuf, + sizeof(auxbuf)); + hfa384x_cmd_aux_disable(hw); + WLAN_LOG_NOTICE(" cmac: FreeBlocks=%d\n", auxbuf[5]); + WLAN_LOG_NOTICE(" cmac: IntEn=0x%02x EvStat=0x%02x\n", + hfa384x_getreg(hw, HFA384x_INTEN), + hfa384x_getreg(hw, HFA384x_EVSTAT)); + + #ifdef USE_FID_STACK + WLAN_LOG_NOTICE(" drvr: txfid_top=%d stacksize=%d\n", + hw->txfid_top,HFA384x_DRVR_FIDSTACKLEN_MAX); + #else + WLAN_LOG_NOTICE(" drvr: txfid_head=%d txfid_tail=%d txfid_N=%d\n", + hw->txfid_head, hw->txfid_tail, hw->txfid_N); + #endif + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + +#else /* (WLAN_HOSTIF == WLAN_USB) */ + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto failed; + +#endif /* (WLAN_HOSTIF != WLAN_USB) */ + +failed: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* prism2mgmt_channel_info +* +* Issues a ChannelInfoRequest. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp) +{ + p80211msg_p2req_channel_info_t *msg=msgp; + hfa384x_t *hw = wlandev->priv; + int result, i, n=0; + UINT16 channel_mask=0; + hfa384x_ChannelInfoRequest_data_t chinforeq; + // unsigned long now; + + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* Not supported in STA f/w */ + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported); + goto done; + } + + /*** ACCESS POINT ***/ + +#define CHINFO_TIMEOUT 2 + + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success); + + /* setting default value for channellist = all channels */ + if (!msg->channellist.data) { + P80211_SET_INT(msg->channellist, 0x00007FFE); + } + /* setting default value for channeldwelltime = 100 ms */ + if (!msg->channeldwelltime.data) { + P80211_SET_INT(msg->channeldwelltime, 100); + } + channel_mask = (UINT16) (msg->channellist.data >> 1); + for (i=0, n=0; i < 14; i++) { + if (channel_mask & (1<numchinfo, n); + chinforeq.channelList = host2hfa384x_16(channel_mask); + chinforeq.channelDwellTime = host2hfa384x_16(msg->channeldwelltime.data); + + atomic_set(&hw->channel_info.done, 1); + + result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CHANNELINFOREQUEST, + &chinforeq, HFA384x_RID_CHANNELINFOREQUEST_LEN); + if ( result ) { + WLAN_LOG_ERROR("setconfig(CHANNELINFOREQUEST) failed. result=%d\n", + result); + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + /* + now = jiffies; + while (atomic_read(&hw->channel_info.done) != 1) { + if ((jiffies - now) > CHINFO_TIMEOUT*HZ) { + WLAN_LOG_NOTICE("ChannelInfo results not received in %d seconds, aborting.\n", + CHINFO_TIMEOUT); + msg->resultcode.data = P80211ENUM_resultcode_timeout; + goto done; + } + current->state = TASK_INTERRUPTIBLE; + schedule_timeout(HZ/4); + current->state = TASK_RUNNING; + } + */ + +done: + + DBFEXIT; + return 0; +} + +/*---------------------------------------------------------------- +* prism2mgmt_channel_info_results +* +* Returns required ChannelInfo result. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +----------------------------------------------------------------*/ +int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + + p80211msg_p2req_channel_info_results_t *msg=msgp; + int result=0; + int channel; + + DBFENTER; + + if (!hw->ap) { + + /*** STATION ***/ + + /* Not supported in STA f/w */ + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_not_supported); + goto done; + } + + /*** ACCESS POINT ***/ + + switch (atomic_read(&hw->channel_info.done)) { + case 0: msg->resultcode.status = P80211ENUM_msgitem_status_no_value; + goto done; + case 1: msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata; + goto done; + } + + P80211_SET_INT(msg->resultcode, P80211ENUM_resultcode_success); + channel=msg->channel.data-1; + + if (channel < 0 || ! (hw->channel_info.results.scanchannels & 1<resultcode.data = P80211ENUM_resultcode_invalid_parameters; + goto done; + } + WLAN_LOG_DEBUG(2, "chinfo_results: channel %d, avg/peak level=%d/%d dB, active=%d\n", + channel+1, + hw->channel_info.results.result[channel].anl, + hw->channel_info.results.result[channel].pnl, + hw->channel_info.results.result[channel].active + ); + P80211_SET_INT(msg->avgnoiselevel, hw->channel_info.results.result[channel].anl); + P80211_SET_INT(msg->peaknoiselevel, hw->channel_info.results.result[channel].pnl); + P80211_SET_INT(msg->bssactive, hw->channel_info.results.result[channel].active & + HFA384x_CHINFORESULT_BSSACTIVE + ? P80211ENUM_truth_true + : P80211ENUM_truth_false) ; + P80211_SET_INT(msg->pcfactive, hw->channel_info.results.result[channel].active & + HFA384x_CHINFORESULT_PCFACTIVE + ? P80211ENUM_truth_true + : P80211ENUM_truth_false) ; + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_autojoin +* +* Associate with an ESS. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + int result = 0; + UINT16 reg; + UINT16 port_type; + p80211msg_lnxreq_autojoin_t *msg = msgp; + p80211pstrd_t *pstr; + UINT8 bytebuf[256]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf; + DBFENTER; + + wlandev->macmode = WLAN_MACMODE_NONE; + + /* Set the SSID */ + memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); + + if (hw->ap) { + + /*** ACCESS POINT ***/ + + /* Never supported on AP */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + /* Disable the Port */ + hfa384x_drvr_disable(hw, 0); + + /*** STATION ***/ + /* Set the TxRates */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f); + + /* Set the auth type */ + if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) { + reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY; + } else { + reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; + } + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg); + + /* Set the ssid */ + memset(bytebuf, 0, 256); + pstr = (p80211pstrd_t*)&(msg->ssid.data); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig( + hw, HFA384x_RID_CNFDESIREDSSID, + bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN); +#if 0 + /* we can use the new-fangled auto-unknown mode if the firmware + is 1.3.3 or newer */ + if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) >= + HFA384x_FIRMWARE_VERSION(1,3,3)) { + /* Set up the IBSS options */ + reg = HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS; + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg); + + /* Set the PortType */ + port_type = HFA384x_PORTTYPE_IBSS; + } else { + port_type = HFA384x_PORTTYPE_BSS; + } +#else + port_type = HFA384x_PORTTYPE_BSS; +#endif + /* Set the PortType */ + hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type); + + /* Enable the Port */ + hfa384x_drvr_enable(hw, 0); + + /* Set the resultcode */ + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_wlansniff +* +* Start or stop sniffing. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) +{ + int result = 0; + p80211msg_lnxreq_wlansniff_t *msg = msgp; + + hfa384x_t *hw = wlandev->priv; + UINT16 word; + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + switch (msg->enable.data) + { + case P80211ENUM_truth_false: + /* Confirm that we're in monitor mode */ + if ( wlandev->netdev->type == ARPHRD_ETHER ) { + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + result = 0; + goto exit; + } + /* Disable monitor mode */ + result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to disable monitor mode, result=%d\n", + result); + goto failed; + } + /* Disable port 0 */ + result = hfa384x_drvr_disable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to disable port 0 after sniffing, result=%d\n", + result); + goto failed; + } + /* Clear the driver state */ + wlandev->netdev->type = ARPHRD_ETHER; + + /* Restore the wepflags */ + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFWEPFLAGS, + hw->presniff_wepflags); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to restore wepflags=0x%04x, result=%d\n", + hw->presniff_wepflags, + result); + goto failed; + } + + /* Set the port to its prior type and enable (if necessary) */ + if (hw->presniff_port_type != 0 ) { + word = hw->presniff_port_type; + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFPORTTYPE, word); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to restore porttype, result=%d\n", + result); + goto failed; + } + + /* Enable the port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result); + goto failed; + } + } else { + result = hfa384x_drvr_disable(hw, 0); + + } + + WLAN_LOG_INFO("monitor mode disabled\n"); + msg->resultcode.data = P80211ENUM_resultcode_success; + result = 0; + goto exit; + break; + case P80211ENUM_truth_true: + /* Disable the port (if enabled), only check Port 0 */ + if ( hw->port_enabled[0]) { + if (wlandev->netdev->type == ARPHRD_ETHER) { + /* Save macport 0 state */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_CNFPORTTYPE, + &(hw->presniff_port_type)); + if ( result ) { + WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result); + goto failed; + } + /* Save the wepflags state */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_CNFWEPFLAGS, + &(hw->presniff_wepflags)); + if ( result ) { + WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result); + goto failed; + } + hfa384x_drvr_stop(hw); + result = hfa384x_drvr_start(hw); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to restart the card for sniffing, result=%d\n", + result); + goto failed; + } + } else { + /* Disable the port */ + result = hfa384x_drvr_disable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to enable port for sniffing, result=%d\n", + result); + goto failed; + } + } + } else { + hw->presniff_port_type = 0; + } + + /* Set the channel we wish to sniff */ + word = msg->channel.data; + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFOWNCHANNEL, word); + hw->sniff_channel=word; + + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to set channel %d, result=%d\n", + word, + result); + goto failed; + } + + /* Now if we're already sniffing, we can skip the rest */ + if (wlandev->netdev->type != ARPHRD_ETHER) { + /* Set the port type to pIbss */ + word = HFA384x_PORTTYPE_PSUEDOIBSS; + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_CNFPORTTYPE, word); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to set porttype %d, result=%d\n", + word, + result); + goto failed; + } + if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) { + /* Set the wepflags for no decryption */ + word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | + HFA384x_WEPFLAGS_DISABLE_RXCRYPT; + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word); + } + + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to set wepflags=0x%04x, result=%d\n", + word, + result); + goto failed; + } + } + + /* Do we want to strip the FCS in monitor mode? */ + if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) { + hw->sniff_fcs = 0; + } else { + hw->sniff_fcs = 1; + } + + /* Do we want to truncate the packets? */ + if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) { + hw->sniff_truncate = msg->packet_trunc.data; + } else { + hw->sniff_truncate = 0; + } + + /* Enable the port */ + result = hfa384x_drvr_enable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to enable port for sniffing, result=%d\n", + result); + goto failed; + } + /* Enable monitor mode */ + result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE); + if ( result ) { + WLAN_LOG_DEBUG(1, + "failed to enable monitor mode, result=%d\n", + result); + goto failed; + } + + if (wlandev->netdev->type == ARPHRD_ETHER) { + WLAN_LOG_INFO("monitor mode enabled\n"); + } + + /* Set the driver state */ + /* Do we want the prism2 header? */ + if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) { + hw->sniffhdr = 0; + wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; + } else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) { + hw->sniffhdr = 1; + wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; + } else { + wlandev->netdev->type = ARPHRD_IEEE80211; + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + result = 0; + goto exit; + break; + default: + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + result = 0; + goto exit; + break; + } + +failed: + msg->resultcode.data = P80211ENUM_resultcode_refused; + result = 0; +exit: + + DBFEXIT; + return result; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/hfa384x.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/hfa384x.c @@ -0,0 +1,4018 @@ +/* src/prism2/driver/hfa384x.c +* +* Implements the functions of the Intersil hfa384x MAC +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file implements functions that correspond to the prism2/hfa384x +* 802.11 MAC hardware and firmware host interface. +* +* The functions can be considered to represent several levels of +* abstraction. The lowest level functions are simply C-callable wrappers +* around the register accesses. The next higher level represents C-callable +* prism2 API functions that match the Intersil documentation as closely +* as is reasonable. The next higher layer implements common sequences +* of invokations of the API layer (e.g. write to bap, followed by cmd). +* +* Common sequences: +* hfa384x_drvr_xxx Highest level abstractions provided by the +* hfa384x code. They are driver defined wrappers +* for common sequences. These functions generally +* use the services of the lower levels. +* +* hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These +* functions are wrappers for the RID get/set +* sequence. They call copy_[to|from]_bap() and +* cmd_access(). These functions operate on the +* RIDs and buffers without validation. The caller +* is responsible for that. +* +* API wrapper functions: +* hfa384x_cmd_xxx functions that provide access to the f/w commands. +* The function arguments correspond to each command +* argument, even command arguments that get packed +* into single registers. These functions _just_ +* issue the command by setting the cmd/parm regs +* & reading the status/resp regs. Additional +* activities required to fully use a command +* (read/write from/to bap, get/set int status etc.) +* are implemented separately. Think of these as +* C-callable prism2 commands. +* +* Lowest Layer Functions: +* hfa384x_docmd_xxx These functions implement the sequence required +* to issue any prism2 command. Primarily used by the +* hfa384x_cmd_xxx functions. +* +* hfa384x_bap_xxx BAP read/write access functions. +* Note: we usually use BAP0 for non-interrupt context +* and BAP1 for interrupt context. +* +* hfa384x_dl_xxx download related functions. +* +* Driver State Issues: +* Note that there are two pairs of functions that manage the +* 'initialized' and 'running' states of the hw/MAC combo. The four +* functions are create(), destroy(), start(), and stop(). create() +* sets up the data structures required to support the hfa384x_* +* functions and destroy() cleans them up. The start() function gets +* the actual hardware running and enables the interrupts. The stop() +* function shuts the hardware down. The sequence should be: +* create() +* . +* . Self contained test routines can run here, particularly +* . corereset() and test_hostif(). +* . +* start() +* . +* . Do interesting things w/ the hardware +* . +* stop() +* destroy() +* +* Note that destroy() can be called without calling stop() first. +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ + +/* System Includes */ +#define WLAN_DBVAR prism2_debug +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include +#else +#include +#endif + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13) ) +#include +#endif +#include +#include +#include +#include +#include +#endif + +#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI)) +#include +#include +#endif + +#include + +// XXXX #define CMD_IRQ + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +static const UINT16 crc16tab[256] = +{ + 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, + 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, + 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, + 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, + 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, + 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, + 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, + 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, + 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, + 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, + 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, + 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, + 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, + 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, + 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, + 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, + 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, + 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, + 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, + 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, + 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, + 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, + 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, + 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, + 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, + 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, + 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, + 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 +}; + +/*================================================================*/ +/* Local Macros */ + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ +extern int prism2_debug; + +/*================================================================*/ +/* Local Function Declarations */ + +static void hfa384x_int_dtim(wlandevice_t *wlandev); +static void hfa384x_int_infdrop(wlandevice_t *wlandev); + +static void hfa384x_bap_tasklet(unsigned long data); + +static void hfa384x_int_info(wlandevice_t *wlandev); +static void hfa384x_int_txexc(wlandevice_t *wlandev); +static void hfa384x_int_tx(wlandevice_t *wlandev); +static void hfa384x_int_rx(wlandevice_t *wlandev); + +#ifdef CMD_IRQ +static void hfa384x_int_cmd(wlandevice_t *wlandev); +#endif +static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, + UINT16 rxfid, hfa384x_rx_frame_t *rxdesc); +static void hfa384x_int_alloc(wlandevice_t *wlandev); + +static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd); + +static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd); + +static UINT16 +hfa384x_mkcrc16(UINT8 *p, int len); + +int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len, void* buf2, UINT len2, + void *buf3, UINT len3, void* buf4, UINT len4); + +/*================================================================*/ +/* Function Definitions */ + +static UINT16 +txfid_queue_empty(hfa384x_t *hw) +{ + return (hw->txfid_head == hw->txfid_tail) ? 1 : 0; +} + +static UINT16 +txfid_queue_remove(hfa384x_t *hw) +{ + UINT16 result= 0; + + if (txfid_queue_empty(hw)) { + WLAN_LOG_DEBUG(3,"queue empty.\n"); + } else { + result = hw->txfid_queue[hw->txfid_head]; + hw->txfid_head = (hw->txfid_head + 1) % hw->txfid_N; + } + + return (UINT16)result; +} + +static INT16 +txfid_queue_add(hfa384x_t *hw, UINT16 val) +{ + INT16 result = 0; + + if (hw->txfid_head == ((hw->txfid_tail + 1) % hw->txfid_N)) { + result = -1; + WLAN_LOG_DEBUG(3,"queue full.\n"); + } else { + hw->txfid_queue[hw->txfid_tail] = val; + result = hw->txfid_tail; + hw->txfid_tail = (hw->txfid_tail + 1) % hw->txfid_N; + } + + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_create +* +* Initializes the hfa384x_t data structure for use. Note this +* does _not_ intialize the actual hardware, just the data structures +* we use to keep track of its state. +* +* Arguments: +* hw device structure +* irq device irq number +* iobase [pcmcia] i/o base address for register access +* [pci] zero +* [plx] i/o base address for register access +* membase [pcmcia] pcmcia_cs "link" pointer +* [pci] memory base address for register access +* [plx] memory base address for card attribute memory +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +void hfa384x_create(hfa384x_t *hw, UINT irq, UINT32 iobase, + UINT8 __iomem *membase) +{ + DBFENTER; + memset(hw, 0, sizeof(hfa384x_t)); + hw->irq = irq; + hw->iobase = iobase; + hw->membase = membase; + spin_lock_init(&(hw->cmdlock)); + + /* BAP setup */ + spin_lock_init(&(hw->baplock)); + tasklet_init(&hw->bap_tasklet, + hfa384x_bap_tasklet, + (unsigned long) hw); + + init_waitqueue_head(&hw->cmdq); + sema_init(&hw->infofid_sem, 1); + + hw->txfid_head = 0; + hw->txfid_tail = 0; + hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX; + memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue)); + + hw->isram16 = 1; + + /* Init the auth queue head */ + skb_queue_head_init(&hw->authq); + + INIT_WORK2(&hw->link_bh, prism2sta_processing_defer); + + INIT_WORK2(&hw->commsqual_bh, prism2sta_commsqual_defer); + + init_timer(&hw->commsqual_timer); + hw->commsqual_timer.data = (unsigned long) hw; + hw->commsqual_timer.function = prism2sta_commsqual_timer; + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + DBFEXIT; +} + +/*---------------------------------------------------------------- +* hfa384x_destroy +* +* Partner to hfa384x_create(). This function cleans up the hw +* structure so that it can be freed by the caller using a simple +* kfree. Currently, this function is just a placeholder. If, at some +* point in the future, an hw in the 'shutdown' state requires a 'deep' +* kfree, this is where it should be done. Note that if this function +* is called on a _running_ hw structure, the drvr_stop() function is +* called. +* +* Arguments: +* hw device structure +* +* Returns: +* nothing, this function is not allowed to fail. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +void +hfa384x_destroy( hfa384x_t *hw) +{ + struct sk_buff *skb; + + DBFENTER; + + if ( hw->state == HFA384x_STATE_RUNNING ) { + hfa384x_drvr_stop(hw); + } + hw->state = HFA384x_STATE_PREINIT; + + if (hw->scanresults) { + kfree(hw->scanresults); + hw->scanresults = NULL; + } + + /* Now to clean out the auth queue */ + while ( (skb = skb_dequeue(&hw->authq)) ) { + dev_kfree_skb(skb); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_getconfig +* +* Performs the sequence necessary to read a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (host order) +* buf host side record buffer. Upon return it will +* contain the body portion of the record (minus the +* RID and len). +* len buffer length (in bytes, should match record length) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ENODATA length mismatch between argument and retrieved +* record. +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + int result = 0; + DBFENTER; + + result = hfa384x_cmd_access( hw, 0, rid, buf, len); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_setconfig +* +* Performs the sequence necessary to write a config/info item. +* +* Arguments: +* hw device structure +* rid config/info record id (in host order) +* buf host side record buffer +* len buffer length (in bytes) +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len) +{ + int result = 0; + DBFENTER; + + result = hfa384x_cmd_access( hw, 1, rid, buf, len); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_readpda +* +* Performs the sequence to read the PDA space. Note there is no +* drvr_writepda() function. Writing a PDA is +* generally implemented by a calling component via calls to +* cmd_download and writing to the flash download buffer via the +* aux regs. +* +* Arguments: +* hw device structure +* buf buffer to store PDA in +* len buffer length +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* -ETIMEOUT timout waiting for the cmd regs to become +* available, or waiting for the control reg +* to indicate the Aux port is enabled. +* -ENODATA the buffer does NOT contain a valid PDA. +* Either the card PDA is bad, or the auxdata +* reads are giving us garbage. + +* +* Side effects: +* +* Call context: +* process thread or non-card interrupt. +----------------------------------------------------------------*/ +int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len) +{ + int result = 0; + UINT16 *pda = buf; + int pdaok = 0; + int morepdrs = 1; + int currpdr = 0; /* word offset of the current pdr */ + int i; + UINT16 pdrlen; /* pdr length in bytes, host order */ + UINT16 pdrcode; /* pdr code, host order */ + UINT16 crc; + UINT16 pdacrc; + struct pdaloc { + UINT32 cardaddr; + UINT16 auxctl; + } pdaloc[] = + { + { HFA3842_PDA_BASE, HFA384x_AUX_CTL_NV}, + { HFA3842_PDA_BASE, HFA384x_AUX_CTL_EXTDS}, + { HFA3841_PDA_BASE, HFA384x_AUX_CTL_NV}, + { HFA3841_PDA_BASE, HFA384x_AUX_CTL_EXTDS}, + { HFA3841_PDA_BOGUS_BASE, HFA384x_AUX_CTL_NV} + }; + + DBFENTER; + /* Check for aux available */ + result = hfa384x_cmd_aux_enable(hw, 0); + if ( result ) { + WLAN_LOG_DEBUG(1,"aux_enable() failed. result=%d\n", result); + goto failed; + } + + /* Read the pda from each known address. */ + for ( i = 0; i < (sizeof(pdaloc)/sizeof(pdaloc[0])); i++) { + WLAN_LOG_DEBUG( 3, "Checking PDA@(0x%08x,%s)\n", + pdaloc[i].cardaddr, + pdaloc[i].auxctl == HFA384x_AUX_CTL_NV ? + "CTL_NV" : "CTL_EXTDS"); + + /* Copy bufsize bytes from our current pdaloc */ + hfa384x_copy_from_aux(hw, + pdaloc[i].cardaddr, + pdaloc[i].auxctl, + buf, + len); + + /* Test for garbage */ + /* Traverse the PDR list Looking for PDA-END */ + pdaok = 1; /* intially assume good */ + morepdrs = 1; + currpdr = 0; + while ( pdaok && morepdrs ) { + pdrlen = hfa384x2host_16(pda[currpdr]) * 2; + pdrcode = hfa384x2host_16(pda[currpdr+1]); + + /* Test for completion at END record */ + if ( pdrcode == HFA384x_PDR_END_OF_PDA ) { + if ( pdrlen == 4 ) { + morepdrs = 0; + /* Calculate CRC-16 and compare to PDA + * value. Note the addition of 2 words + * for ENDREC.len and ENDREC.code + * fields. + */ + crc = hfa384x_mkcrc16( (UINT8*)pda, + (currpdr + 2) * sizeof(UINT16)); + pdacrc =hfa384x2host_16(pda[currpdr+2]); + if ( crc != pdacrc ) { + WLAN_LOG_DEBUG(3, + "PDA crc failed:" + "calc_crc=0x%04x," + "pdr_crc=0x%04x.\n", + crc, pdacrc); + pdaok = 0; + } + } else { + WLAN_LOG_DEBUG(3, + "END record detected w/ " + "len(%d) != 2, assuming bad PDA\n", + pdrlen); + pdaok = 0; + + } + break; + } + + /* Test the record length */ + if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) { + WLAN_LOG_DEBUG(3, + "pdrlen for address #%d " + "at %#x:%#x:%d\n", + i, pdaloc[i].cardaddr, + pdaloc[i].auxctl, pdrlen); + WLAN_LOG_DEBUG(3,"pdrlen invalid=%d\n", + pdrlen); + pdaok = 0; + break; + } + + /* Move to the next pdr */ + if ( morepdrs ) { + /* note the access to pda[], we need words */ + currpdr += hfa384x2host_16(pda[currpdr]) + 1; + if (currpdr*sizeof(UINT16) > len) { + WLAN_LOG_DEBUG(3, + "Didn't find PDA_END in buffer, " + "trying next location.\n"); + pdaok = 0; + break; + } + } + } + if ( pdaok ) { + WLAN_LOG_INFO( + "PDA Read from 0x%08x in %s space.\n", + pdaloc[i].cardaddr, + pdaloc[i].auxctl == 0 ? "EXTDS" : + pdaloc[i].auxctl == 1 ? "NV" : + pdaloc[i].auxctl == 2 ? "PHY" : + pdaloc[i].auxctl == 3 ? "ICSRAM" : + ""); + break; + } + } + result = pdaok ? 0 : -ENODATA; + + if ( result ) { + WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n"); + } + + hfa384x_cmd_aux_disable(hw); +failed: + DBFEXIT; + return result; +} + + + +/*---------------------------------------------------------------- +* mkpda_crc +* +* Calculates the CRC16 for the given PDA and inserts the value +* into the end record. +* +* Arguments: +* pda ptr to the PDA data structure. +* +* Returns: +* 0 - success +* ~0 - failure (probably an errno) +----------------------------------------------------------------*/ +static UINT16 +hfa384x_mkcrc16(UINT8 *p, int len) +{ + UINT16 crc = 0; + UINT8 *lim = p + len; + + while (p < lim) { + crc = (crc >> 8 ) ^ crc16tab[(crc & 0xff) ^ *p++]; + } + + return crc; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_enable +* +* Begins the ram download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and calls cmd_download with the +* ENABLE_VOLATILE subcommand and the exeaddr argument. +* +* Arguments: +* hw device structure +* exeaddr the card execution address that will be +* jumped to when ramdl_disable() is called +* (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr) +{ + int result = 0; + UINT16 lowaddr; + UINT16 hiaddr; + int i; + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_DEBUG(1,"Can't download with a port enabled.\n"); + result = -EINVAL; + goto done; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + WLAN_LOG_DEBUG(1,"Download state not disabled.\n"); + result = -EINVAL; + goto done; + } + + /* Are we supposed to go into genesis mode? */ + if (exeaddr == 0x3f0000) { + UINT16 initseq[2] = { 0xe100, 0xffa1 }; + UINT16 readbuf[2]; + UINT8 hcr = 0x0f; /* Default to x16 SRAM */ + hw->isram16 = 1; + + WLAN_LOG_DEBUG(1, "Dropping into Genesis mode\n"); + + /* Issue card reset and enable aux port */ + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, 0); + hfa384x_cmd_aux_enable(hw, 1); + + /* Genesis set */ + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, hcr); + + /* Validate memory config */ + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + readbuf, sizeof(initseq)); + WLAN_HEX_DUMP(3, "readback", readbuf, sizeof(readbuf)); + + if (memcmp(initseq, readbuf, sizeof(readbuf))) { + hcr = 0x1f; /* x8 SRAM */ + hw->isram16 = 0; + + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, hcr); + + hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + initseq, sizeof(initseq)); + hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, + readbuf, sizeof(initseq)); + WLAN_HEX_DUMP(2, "readback", readbuf, sizeof(readbuf)); + + if (memcmp(initseq, readbuf, sizeof(readbuf))) { + WLAN_LOG_ERROR("Genesis mode failed\n"); + result = -1; + goto done; + } + } + + /* Now we're in genesis mode */ + hw->dlstate = HFA384x_DLSTATE_GENESIS; + goto done; + } + + /* Retrieve the buffer loc&size and timeout */ + if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, + &(hw->bufinfo), sizeof(hw->bufinfo))) ) { + goto done; + } + hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page); + hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset); + hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len); + if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, + &(hw->dltimeout))) ) { + goto done; + } + hw->dltimeout = hfa384x2host_16(hw->dltimeout); + + /* Enable the aux port */ + if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) { + WLAN_LOG_DEBUG(1,"Aux enable failed, result=%d.\n", result); + goto done; + } + + /* Call the download(1,addr) function */ + lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr); + hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr); + + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM, + lowaddr, hiaddr, 0); + if ( result == 0) { + /* Set the download state */ + hw->dlstate = HFA384x_DLSTATE_RAMENABLED; + } else { + WLAN_LOG_DEBUG(1,"cmd_download(0x%04x, 0x%04x) failed, result=%d.\n", + lowaddr,hiaddr, result); + /* Disable the aux port */ + hfa384x_cmd_aux_disable(hw); + } + + done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_disable +* +* Ends the ram download state. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_ramdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) && + ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) { + return -EINVAL; + } + + if (hw->dlstate == HFA384x_DLSTATE_GENESIS) { + hfa384x_corereset(hw, prism2_reset_holdtime, + prism2_reset_settletime, + hw->isram16 ? 0x07: 0x17); + goto done; + } + + /* Disable the aux port */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + + done: + hw->dlstate = HFA384x_DLSTATE_DISABLED; + hfa384x_cmd_aux_disable(hw); + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_ramdl_write +* +* Performs a RAM download of a chunk of data. First checks to see +* that we're in the RAM download state, then uses the aux functions +* to 1) copy the data, 2) readback and compare. The download +* state is unaffected. When all data has been written using +* this function, call drvr_ramdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len) +{ + int result = 0; + UINT8 *verbuf; + DBFENTER; + /* Check that we're in the ram download state */ + if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) && + ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr); +#if 0 +WLAN_HEX_DUMP(1, "dldata", buf, len); +#endif + /* Copy the data via the aux port */ + hfa384x_copy_to_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, buf, len); + + /* Create a buffer for the verify */ + verbuf = kmalloc(len, GFP_KERNEL); + if (verbuf == NULL ) return 1; + + /* Read back and compare */ + hfa384x_copy_from_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, verbuf, len); + + if ( memcmp(buf, verbuf, len) ) { + WLAN_LOG_DEBUG(1,"ramdl verify failed!\n"); + result = -EINVAL; + } + + kfree_s(verbuf, len); + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_enable +* +* Begins the flash download state. Checks to see that we're not +* already in a download state and that a port isn't enabled. +* Sets the download state and retrieves the flash download +* buffer location, buffer size, and timeout length. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_enable(hfa384x_t *hw) +{ + int result = 0; + int i; + + DBFENTER; + /* Check that a port isn't active */ + for ( i = 0; i < HFA384x_PORTID_MAX; i++) { + if ( hw->port_enabled[i] ) { + WLAN_LOG_DEBUG(1,"called when port enabled.\n"); + return -EINVAL; + } + } + + /* Check that we're not already in a download state */ + if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { + return -EINVAL; + } + + /* Retrieve the buffer loc&size and timeout */ + if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, + &(hw->bufinfo), sizeof(hw->bufinfo))) ) { + return result; + } + hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page); + hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset); + hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len); + if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, + &(hw->dltimeout))) ) { + return result; + } + hw->dltimeout = hfa384x2host_16(hw->dltimeout); + + /* Enable the aux port */ + if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) { + return result; + } + + hw->dlstate = HFA384x_DLSTATE_FLASHENABLED; + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_disable +* +* Ends the flash download state. Note that this will cause the MAC +* firmware to restart. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_disable(hfa384x_t *hw) +{ + DBFENTER; + /* Check that we're already in the download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + /* There isn't much we can do at this point, so I don't */ + /* bother w/ the return value */ + hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); + hw->dlstate = HFA384x_DLSTATE_DISABLED; + + /* Disable the aux port */ + hfa384x_cmd_aux_disable(hw); + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_flashdl_write +* +* Performs a FLASH download of a chunk of data. First checks to see +* that we're in the FLASH download state, then sets the download +* mode, uses the aux functions to 1) copy the data to the flash +* buffer, 2) sets the download 'write flash' mode, 3) readback and +* compare. Lather rinse, repeat as many times an necessary to get +* all the given data into flash. +* When all data has been written using this function (possibly +* repeatedly), call drvr_flashdl_disable() to end the download state +* and restart the MAC. +* +* Arguments: +* hw device structure +* daddr Card address to write to. (host order) +* buf Ptr to data to write. +* len Length of data (host order). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len) +{ + int result = 0; + UINT8 *verbuf; + UINT32 dlbufaddr; + UINT32 currlen; + UINT32 currdaddr; + UINT16 destlo; + UINT16 desthi; + int nwrites; + int i; + + DBFENTER; + /* Check that we're in the flash download state */ + if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { + return -EINVAL; + } + + WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr); + + /* Need a flat address for arithmetic */ + dlbufaddr = HFA384x_ADDR_AUX_MKFLAT( + hw->bufinfo.page, + hw->bufinfo.offset); + verbuf = kmalloc(hw->bufinfo.len, GFP_KERNEL); + +#if 0 +WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout); +#endif + /* Figure out how many times to to the flash prog */ + nwrites = len / hw->bufinfo.len; + nwrites += (len % hw->bufinfo.len) ? 1 : 0; + + if ( verbuf == NULL ) { + WLAN_LOG_ERROR("Failed to allocate flash verify buffer\n"); + return 1; + } + /* For each */ + for ( i = 0; i < nwrites; i++) { + /* Get the dest address and len */ + currlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ? + hw->bufinfo.len : + (len - (hw->bufinfo.len * i)); + currdaddr = daddr + (hw->bufinfo.len * i); + destlo = HFA384x_ADDR_CMD_MKOFF(currdaddr); + desthi = HFA384x_ADDR_CMD_MKPAGE(currdaddr); + WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", currlen, currdaddr); +#if 0 +WLAN_HEX_DUMP(1, "dldata", buf+(hw->bufinfo.len*i), currlen); +#endif + /* Set the download mode */ + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, + destlo, desthi, currlen); + if ( result ) { + WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + destlo, desthi, currlen, result); + goto exit_proc; + } + /* copy the data to the flash buffer */ + hfa384x_copy_to_aux(hw, dlbufaddr, HFA384x_AUX_CTL_EXTDS, + buf+(hw->bufinfo.len*i), currlen); + /* set the download 'write flash' mode */ + result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0); + if ( result ) { + WLAN_LOG_ERROR( + "download(NVWRITE,lo=%x,hi=%x,len=%x) " + "cmd failed, result=%d. Aborting d/l\n", + destlo, desthi, currlen, result); + goto exit_proc; + } + /* readback and compare, if fail...bail */ + hfa384x_copy_from_aux(hw, + currdaddr, HFA384x_AUX_CTL_NV, + verbuf, currlen); + + if ( memcmp(buf+(hw->bufinfo.len*i), verbuf, currlen) ) { + return -EINVAL; + } + } + +exit_proc: + /* DOH! This kfree's for you Mark :-) My forehead hurts... */ + kfree(verbuf); + + /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */ + /* actually disable programming mode. Remember, that will cause the */ + /* the firmware to effectively reset itself. */ + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_initialize +* +* Issues the initialize command and sets the hw->state based +* on the result. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_initialize(hfa384x_t *hw) +{ + int result = 0; + int i; + hfa384x_metacmd_t cmd; + + DBFENTER; + + /* we don't want to be interrupted during the reset */ + hfa384x_setreg(hw, 0, HFA384x_INTEN); + hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); + + cmd.cmd = HFA384x_CMDCODE_INIT; + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + if ( result == 0 ) { + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + } + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_commtallies +* +* Send a commtallies inquiry to the MAC. Note that this is an async +* call that will result in an info frame arriving sometime later. +* +* Arguments: +* hw device structure +* +* Returns: +* zero success. +* +* Side effects: +* +* Call context: +* process +----------------------------------------------------------------*/ +int hfa384x_drvr_commtallies( hfa384x_t *hw ) +{ + hfa384x_metacmd_t cmd; + int result; + + DBFENTER; + + cmd.cmd = HFA384x_CMDCODE_INQ; + cmd.parm0 = HFA384x_IT_COMMTALLIES; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_enable +* +* Issues the enable command to enable communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also enable macports 1-6. Only ports that are currently +* disabled may be enabled. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + (hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_enable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 1; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_enable +* +* Issues the the enable command to enable communications on one of the +* MACs 'ports'. +* +* Arguments: +* hw device structure +* macport MAC port number +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_disable +* +* Issues the disable command to stop communications on one of +* the MACs 'ports'. Only macport 0 is valid for stations. +* APs may also disable macports 1-6. Only ports that have been +* previously enabled may be disabled. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + + DBFENTER; + if ((!hw->isap && macport != 0) || + (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || + !(hw->port_enabled[macport]) ){ + result = -EINVAL; + } else { + result = hfa384x_cmd_disable(hw, macport); + if ( result == 0 ) { + hw->port_enabled[macport] = 0; + } + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_disable +* +* Issues the command to disable a port. +* +* Arguments: +* hw device structure +* macport MAC port number (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) | + HFA384x_CMD_MACPORT_SET(macport); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_diagnose +* +* Issues the diagnose command to test the: register interface, +* MAC controller (including loopback), External RAM, Non-volatile +* memory integrity, and synthesizers. Following execution of this +* command, MAC/firmware are in the 'initial state'. Therefore, +* the Initialize command should be issued after successful +* completion of this command. This function may only be called +* when the MAC is in the 'communication disabled' state. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +#define DIAG_PATTERNA ((UINT16)0xaaaa) +#define DIAG_PATTERNB ((UINT16)0x5555) + +int hfa384x_cmd_diagnose(hfa384x_t *hw) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DIAG); + cmd.parm0 = DIAG_PATTERNA; + cmd.parm1 = DIAG_PATTERNB; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_allocate +* +* Issues the allocate command instructing the firmware to allocate +* a 'frame structure buffer' in MAC controller RAM. This command +* does not provide the result, it only initiates one of the f/w's +* asynchronous processes to construct the buffer. When the +* allocation is complete, it will be indicated via the Alloc +* bit in the EvStat register and the FID identifying the allocated +* space will be available from the AllocFID register. Some care +* should be taken when waiting for the Alloc event. If a Tx or +* Notify command w/ Reclaim has been previously executed, it's +* possible the first Alloc event after execution of this command +* will be for the reclaimed buffer and not the one you asked for. +* This case must be handled in the Alloc event handler. +* +* Arguments: +* hw device structure +* len allocation length, must be an even value +* in the range [4-2400]. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + if ( (len % 2) || + len < HFA384x_CMD_ALLOC_LEN_MIN || + len > HFA384x_CMD_ALLOC_LEN_MAX ) { + result = -EINVAL; + } else { + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC); + cmd.parm0 = len; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_transmit +* +* Instructs the firmware to transmit a frame previously copied +* to a given buffer. This function returns immediately, the Tx +* results are available via the Tx or TxExc events (if the frame +* control bits are set). The reclaim argument specifies if the +* FID passed will be used by the f/w tx process or returned for +* use w/ another transmit command. If reclaim is set, expect an +* Alloc event signalling the availibility of the FID for reuse. +* +* NOTE: hw->cmdlock MUST BE HELD before calling this function! +* +* Arguments: +* hw device structure +* reclaim [0|1] indicates whether the given FID will +* be handed back (via Alloc event) for reuse. +* (host order) +* qos [0-3] Value to put in the QoS field of the +* tx command, identifies a queue to place the +* outgoing frame in. +* (host order) +* fid FID of buffer containing the frame that was +* previously copied to MAC memory via the bap. +* (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* hw->resp0 will contain the FID being used by async tx +* process. If reclaim==0, resp0 will be the same as the fid +* argument. If reclaim==1, resp0 will be the different and +* is the value to watch for in the Tx|TxExc to indicate completion +* of the frame passed in fid. +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX) | + HFA384x_CMD_RECL_SET(reclaim) | + HFA384x_CMD_QOS_SET(qos); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_clearpersist +* +* Instructs the firmware to clear the persistence bit in a given +* FID. This has the effect of telling the firmware to drop the +* persistent frame. The FID must be one that was previously used +* to transmit a PRST frame. +* +* Arguments: +* hw device structure +* fid FID of the persistent frame (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_CLRPRST); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_cmd_notify +* +* Sends an info frame to the firmware to alter the behavior +* of the f/w asynch processes. Can only be called when the MAC +* is in the enabled state. +* +* Arguments: +* hw device structure +* reclaim [0|1] indicates whether the given FID will +* be handed back (via Alloc event) for reuse. +* (host order) +* fid FID of buffer containing the frame that was +* previously copied to MAC memory via the bap. +* (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* hw->resp0 will contain the FID being used by async notify +* process. If reclaim==0, resp0 will be the same as the fid +* argument. If reclaim==1, resp0 will be the different. +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, + void *buf, UINT16 len) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) | + HFA384x_CMD_RECL_SET(reclaim); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + + /* Copy the record to FID */ + result = hfa384x_copy_to_bap(hw, HFA384x_BAP_PROC, hw->infofid, 0, buf, len); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_to_bap(%04x, 0, %d) failed, result=0x%x\n", + hw->infofid, len, result); + result = -EIO; + goto failed; + } + + result = hfa384x_docmd_wait(hw, &cmd); + + failed: + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +#if 0 +/*---------------------------------------------------------------- +* hfa384x_cmd_inquiry +* +* Requests an info frame from the firmware. The info frame will +* be delivered asynchronously via the Info event. +* +* Arguments: +* hw device structure +* fid FID of the info frame requested. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ); + cmd.parm0 = fid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} +#endif + + +/*---------------------------------------------------------------- +* hfa384x_cmd_access +* +* Requests that a given record be copied to/from the record +* buffer. If we're writing from the record buffer, the contents +* must previously have been written to the record buffer via the +* bap. If we're reading into the record buffer, the record can +* be read out of the record buffer after this call. +* +* Arguments: +* hw device structure +* write [0|1] copy the record buffer to the given +* configuration record. (host order) +* rid RID of the record to read/write. (host order) +* buf host side record buffer. Upon return it will +* contain the body portion of the record (minus the +* RID and len). +* len buffer length (in bytes, should match record length) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid, + void* buf, UINT16 len) +{ + int result = 0; + hfa384x_metacmd_t cmd; + hfa384x_rec_t rec; + + DBFENTER; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)) + /* This should NOT be called in interrupt context! */ + if (in_irq()) { + WLAN_LOG_ERROR("Krap, in Interrupt context!"); +#ifdef WLAN_INCLUDE_DEBUG + BUG(); +#endif + } +#endif + spin_lock_bh(&hw->cmdlock); + + if (write) { + rec.rid = host2hfa384x_16(rid); + rec.reclen = host2hfa384x_16((len/2) + 1); /* note conversion to words, +1 for rid field */ + /* write the record */ + result = hfa384x_copy_to_bap4( hw, HFA384x_BAP_PROC, rid, 0, + &rec, sizeof(rec), + buf, len, + NULL, 0, NULL, 0); + if ( result ) { + WLAN_LOG_DEBUG(3,"Failure writing record header+data\n"); + goto fail; + } + + } + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ACCESS) | + HFA384x_CMD_WRITE_SET(write); + cmd.parm0 = rid; + cmd.parm1 = 0; + cmd.parm2 = 0; + + result = hfa384x_docmd_wait(hw, &cmd); + if ( result ) { + WLAN_LOG_ERROR("Call to hfa384x_docmd_wait failed (%d %d)\n", + result, cmd.result.resp0); + goto fail; + } + + if (!write) { + result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, 0, &rec, sizeof(rec)); + if ( result ) { + WLAN_LOG_DEBUG(3,"Call to hfa384x_copy_from_bap failed\n"); + goto fail; + } + + /* Validate the record length */ + if ( ((hfa384x2host_16(rec.reclen)-1)*2) != len ) { /* note body len calculation in bytes */ + WLAN_LOG_DEBUG(1, "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n", + rid, len, (hfa384x2host_16(rec.reclen)-1)*2); + result = -ENODATA; + goto fail; + } + + result = hfa384x_copy_from_bap( hw, HFA384x_BAP_PROC, rid, sizeof(rec), buf, len); + + } + + fail: + spin_unlock_bh(&hw->cmdlock); + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_monitor +* +* Enables the 'monitor mode' of the MAC. Here's the description of +* monitor mode that I've received thus far: +* +* "The "monitor mode" of operation is that the MAC passes all +* frames for which the PLCP checks are correct. All received +* MPDUs are passed to the host with MAC Port = 7, with a +* receive status of good, FCS error, or undecryptable. Passing +* certain MPDUs is a violation of the 802.11 standard, but useful +* for a debugging tool." Normal communication is not possible +* while monitor mode is enabled. +* +* Arguments: +* hw device structure +* enable a code (0x0b|0x0f) that enables/disables +* monitor mode. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | + HFA384x_CMD_AINFO_SET(enable); + cmd.parm0 = 0; + cmd.parm1 = 0; + cmd.parm2 = 0; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_download +* +* Sets the controls for the MAC controller code/data download +* process. The arguments set the mode and address associated +* with a download. Note that the aux registers should be enabled +* prior to setting one of the download enable modes. +* +* Arguments: +* hw device structure +* mode 0 - Disable programming and begin code exec +* 1 - Enable volatile mem programming +* 2 - Enable non-volatile mem programming +* 3 - Program non-volatile section from NV download +* buffer. +* (host order) +* lowaddr +* highaddr For mode 1, sets the high & low order bits of +* the "destination address". This address will be +* the execution start address when download is +* subsequently disabled. +* For mode 2, sets the high & low order bits of +* the destination in NV ram. +* For modes 0 & 3, should be zero. (host order) +* NOTE: these address args are in CMD format +* codelen Length of the data to write in mode 2, +* zero otherwise. (host order) +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr, + UINT16 highaddr, UINT16 codelen) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + + cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) | + HFA384x_CMD_PROGMODE_SET(mode); + cmd.parm0 = lowaddr; + cmd.parm1 = highaddr; + cmd.parm2 = codelen; + + spin_lock_bh(&hw->cmdlock); + result = hfa384x_dl_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_aux_enable +* +* Goes through the process of enabling the auxilary port. This +* is necessary prior to raw reads/writes to card data space. +* Direct access to the card data space is only used for downloading +* code and debugging. +* Note that a call to this function is required before attempting +* a download. +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_aux_enable(hfa384x_t *hw, int force) +{ + int result = -ETIMEDOUT; + unsigned long flags; + UINT32 retries_remaining; + UINT16 reg; + UINT auxen_mirror = hw->auxen; + + DBFENTER; + + /* Check for existing enable */ + if ( hw->auxen ) { + hw->auxen++; + return 0; + } + + /* acquire the lock */ + spin_lock_irqsave( &(hw->cmdlock), flags); + /* wait for cmd register busy bit to clear */ + retries_remaining = 100000; + do { + reg = hfa384x_getreg(hw, HFA384x_CMD); + udelay(10); + } + while (HFA384x_CMD_ISBUSY(reg) && --retries_remaining); + if (retries_remaining != 0) { + /* busy bit clear, it's OK to write to ParamX regs */ + hfa384x_setreg(hw, HFA384x_AUXPW0, + HFA384x_PARAM0); + hfa384x_setreg(hw, HFA384x_AUXPW1, + HFA384x_PARAM1); + hfa384x_setreg(hw, HFA384x_AUXPW2, + HFA384x_PARAM2); + + /* Set the aux enable in the Control register */ + hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DOENABLE, + HFA384x_CONTROL); + + /* Now wait for completion */ + retries_remaining = 100000; + do { + reg = hfa384x_getreg(hw, HFA384x_CONTROL); + udelay(10); + } + while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISENABLED) && + --retries_remaining ); + if (retries_remaining != 0) { + result = 0; + hw->auxen++; + } + } + + /* Force it enabled even if the command failed, if told.. */ + if ((hw->auxen == auxen_mirror) && force) + hw->auxen++; + + spin_unlock_irqrestore( &(hw->cmdlock), flags); + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_aux_disable +* +* Goes through the process of disabling the auxilary port +* enabled with aux_enable(). +* +* Arguments: +* hw device structure +* +* Returns: +* 0 success +* >0 f/w reported failure - f/w status code +* <0 driver reported error (timeout) +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_cmd_aux_disable(hfa384x_t *hw) +{ + int result = -ETIMEDOUT; + unsigned long timeout; + UINT16 reg = 0; + + DBFENTER; + + /* See if there's more than one enable */ + if (hw->auxen) hw->auxen--; + if (hw->auxen) return 0; + + /* Clear the aux enable in the Control register */ + hfa384x_setreg(hw, 0, HFA384x_PARAM0); + hfa384x_setreg(hw, 0, HFA384x_PARAM1); + hfa384x_setreg(hw, 0, HFA384x_PARAM2); + hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DODISABLE, + HFA384x_CONTROL); + + /* Now wait for completion */ + timeout = jiffies + 1*HZ; + reg = hfa384x_getreg(hw, HFA384x_CONTROL); + while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISDISABLED) && + time_before(jiffies,timeout) ){ + udelay(10); + reg = hfa384x_getreg(hw, HFA384x_CONTROL); + } + if ((reg & (BIT14|BIT15)) == HFA384x_CONTROL_AUX_ISDISABLED ) { + result = 0; + } + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_low_level +* +* Write test commands to the card. Some test commands don't make +* sense without prior set-up. For example, continous TX isn't very +* useful until you set the channel. That functionality should be +* +* Side effects: +* +* Call context: +* process thread +* -----------------------------------------------------------------*/ +int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result = 0; + DBFENTER; + + /* Do i need a host2hfa... conversion ? */ +#if 0 + printk(KERN_INFO "%#x %#x %#x %#x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2); +#endif + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/* TODO: determine if these will ever be needed */ +#if 0 +int hfa384x_cmd_readmif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} + + +int hfa384x_cmd_writemif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} +#endif + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_read +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* register The test register to be accessed (must be even #). +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr, UINT32 *resp) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = (UINT16) 0x30; + cmd.parm0 = (UINT16) addr; + cmd.parm1 = 0; + cmd.parm2 = 0; + + /* Do i need a host2hfa... conversion ? */ + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + *resp = (UINT32) cmd.result.resp0; + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_mmi_write +* +* Read mmi registers. mmi is intersil-speak for the baseband +* processor registers. +* +* Arguments: +* hw device structure +* addr The test register to be accessed (must be even #). +* data The data value to write to the register. +* +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ + +int +hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data) +{ + int result = 0; + hfa384x_metacmd_t cmd; + + DBFENTER; + cmd.cmd = (UINT16) 0x31; + cmd.parm0 = (UINT16) addr; + cmd.parm1 = (UINT16) data; + cmd.parm2 = 0; + + WLAN_LOG_DEBUG(1,"mmi write : addr = 0x%08x\n", addr); + WLAN_LOG_DEBUG(1,"mmi write : data = 0x%08x\n", data); + + /* Do i need a host2hfa... conversion ? */ + spin_lock_bh(&hw->cmdlock); + result = hfa384x_docmd_wait(hw, &cmd); + spin_unlock_bh(&hw->cmdlock); + + DBFEXIT; + return result; +} + + +/* TODO: determine if these will ever be needed */ +#if 0 +int hfa384x_cmd_readmif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} + + +int hfa384x_cmd_writemif(hfa384x_t *hw) +{ + DBFENTER; + DBFEXIT; + return 0; +} +#endif + + + +/*---------------------------------------------------------------- +* hfa384x_copy_from_bap +* +* Copies a collection of bytes from the MAC controller memory via +* one set of BAP registers. +* +* Arguments: +* hw device structure +* bap [0|1] which BAP to use +* id FID or RID, destined for the select register (host order) +* offset An _even_ offset into the buffer for the given +* FID/RID. We haven't the means to validate this, +* so be careful. (host order) +* buf ptr to array of bytes +* len length of data to transfer in bytes +* +* Returns: +* 0 success +* >0 f/w reported failure - value of offset reg. +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len) +{ + int result = 0; + unsigned long flags = 0; + UINT8 *d = (UINT8*)buf; + UINT selectreg; + UINT offsetreg; + UINT datareg; + UINT i; + UINT16 reg = 0; + + DBFENTER; + + /* Validate bap, offset, buf, and len */ + if ( (bap > 1) || + (offset > HFA384x_BAP_OFFSET_MAX) || + (offset % 2) || + (buf == NULL) || + (len > HFA384x_BAP_DATALEN_MAX) ){ + result = -EINVAL; + } else { + selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0 ; + offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0 ; + datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0 ; + + /* Obtain lock */ + spin_lock_irqsave( &(hw->baplock), flags); + + /* Write id to select reg */ + hfa384x_setreg(hw, id, selectreg); + /* Write offset to offset reg */ + hfa384x_setreg(hw, offset, offsetreg); + /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */ + i = 0; + do { + reg = hfa384x_getreg(hw, offsetreg); + if ( i > 0 ) udelay(10); + i++; + } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg)); +#if (WLAN_HOSTIF != WLAN_PCI) + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + if ( HFA384x_OFFSET_ISBUSY(reg) ){ + /* If timeout, return -ETIMEDOUT */ + result = reg; + } else if ( HFA384x_OFFSET_ISERR(reg) ){ + /* If offset[err] == 1, return -EINVAL */ + result = reg; + } else { + /* Read even(len) buf contents from data reg */ + for ( i = 0; i < (len & 0xfffe); i+=2 ) { + *(UINT16*)(&(d[i])) = + hfa384x_getreg_noswap(hw, datareg); + } + /* If len odd, handle last byte */ + if ( len % 2 ){ + reg = hfa384x_getreg_noswap(hw, datareg); + d[len-1] = ((UINT8*)(®))[0]; + } + } + + /* According to Intersil errata dated 9/16/02: + + "In PRISM PCI MAC host interface, if both BAPs are concurrently + requesing memory access, both will accept the Ack. There is no + firmware workaround possible. To prevent BAP access failures or + hang conditions the host MUST NOT access both BAPs in sucession + unless at least 5us elapses between accesses. The safest choice + is to USE ONLY ONE BAP for all data movement operations." + + What this means: + + We have to serialize ALL BAP accesses, and furthermore, add a 5us + delay after access if we're using a PCI platform. + + Unfortunately, this means we have to lock out interrupts througout + the entire BAP copy. + + It remains to be seen if "BAP access" means "BAP setup" or the more + literal definition of "copying data back and forth" I'm erring for + the latter, safer definition. -- SLP. + + */ + +#if (WLAN_HOSTIF == WLAN_PCI) + udelay(5); + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + } + + if (result) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + reg, len, result); + } + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_to_bap +* +* Copies a collection of bytes to the MAC controller memory via +* one set of BAP registers. +* +* Arguments: +* hw device structure +* bap [0|1] which BAP to use +* id FID or RID, destined for the select register (host order) +* offset An _even_ offset into the buffer for the given +* FID/RID. We haven't the means to validate this, +* so be careful. (host order) +* buf ptr to array of bytes +* len length of data to transfer (in bytes) +* +* Returns: +* 0 success +* >0 f/w reported failure - value of offset reg. +* <0 driver reported error (timeout|bad arg) +* +* Side effects: +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len) +{ + return hfa384x_copy_to_bap4(hw, bap, id, offset, buf, len, NULL, 0, NULL, 0, NULL, 0); +} + +int hfa384x_copy_to_bap4(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, + void *buf, UINT len1, void* buf2, UINT len2, + void *buf3, UINT len3, void *buf4, UINT len4) +{ + int result = 0; + unsigned long flags = 0; + UINT8 *d; + UINT selectreg; + UINT offsetreg; + UINT datareg; + UINT i; + UINT16 reg; + + DBFENTER; + +// printk(KERN_DEBUG "ctb1 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4); + + /* Validate bap, offset, buf, and len */ + if ( (bap > 1) || + (offset > HFA384x_BAP_OFFSET_MAX) || + (offset % 2) || + (buf == NULL) || + (len1+len2+len3+len4 > HFA384x_BAP_DATALEN_MAX) ){ + result = -EINVAL; + } else { + selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0; + offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0; + datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0; + /* Obtain lock */ + spin_lock_irqsave( &(hw->baplock), flags); + + /* Write id to select reg */ + hfa384x_setreg(hw, id, selectreg); + udelay(10); + /* Write offset to offset reg */ + hfa384x_setreg(hw, offset, offsetreg); + /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */ + i = 0; + do { + reg = hfa384x_getreg(hw, offsetreg); + if ( i > 0 ) udelay(10); + i++; + } while ( i < prism2_bap_timeout && HFA384x_OFFSET_ISBUSY(reg)); + +#if (WLAN_HOSTIF != WLAN_PCI) + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + if ( HFA384x_OFFSET_ISBUSY(reg) ){ + /* If timeout, return reg */ + result = reg; + } else if ( HFA384x_OFFSET_ISERR(reg) ){ + /* If offset[err] == 1, return reg */ + result = reg; + } else { + d = (UINT8*)buf; + /* Write even(len1) buf contents to data reg */ + for ( i = 0; i < (len1 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, + *(UINT16*)(&(d[i])), datareg); + } + if (len1 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len1-1]; + if (buf2 != NULL) { + d = (UINT8*)buf2; + b[1] = d[0]; + len2--; + buf2++; + } + hfa384x_setreg_noswap(hw, data, datareg); + } + if ((buf2 != NULL) && (len2 > 0)) { + /* Write even(len2) buf contents to data reg */ + d = (UINT8*)buf2; + for ( i = 0; i < (len2 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg); + } + if (len2 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len2-1]; + if (buf3 != NULL) { + d = (UINT8*)buf3; + b[1] = d[0]; + len3--; + buf3++; + } + hfa384x_setreg_noswap(hw, data, datareg); + } + } + + if ((buf3 != NULL) && (len3 > 0)) { + /* Write even(len3) buf contents to data reg */ + d = (UINT8*)buf3; + for ( i = 0; i < (len3 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg); + } + if (len3 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len3-1]; + if (buf4 != NULL) { + d = (UINT8*)buf4; + b[1] = d[0]; + len4--; + buf4++; + } + hfa384x_setreg_noswap(hw, data, datareg); + } + } + if ((buf4 != NULL) && (len4 > 0)) { + /* Write even(len4) buf contents to data reg */ + d = (UINT8*)buf4; + for ( i = 0; i < (len4 & 0xfffe); i+=2 ) { + hfa384x_setreg_noswap(hw, *(UINT16*)(&(d[i])), datareg); + } + if (len4 & 1) { + UINT16 data; + UINT8 *b = (UINT8 *) &data; + b[0] = d[len4-1]; + b[1] = 0; + + hfa384x_setreg_noswap(hw, data, datareg); + } + } +// printk(KERN_DEBUG "ctb2 %d id %04x o %d %d %d %d %d\n", bap, id, offset, len1, len2, len3, len4); + + } + +#if (WLAN_HOSTIF == WLAN_PCI) + udelay(5); + /* Release lock */ + spin_unlock_irqrestore( &(hw->baplock), flags); +#endif + + } + + if (result) + WLAN_LOG_ERROR("copy_to_bap() failed.\n"); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_from_aux +* +* Copies a collection of bytes from the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* buf contains the data copied +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_from_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + UINT16 currpage; + UINT16 curroffset; + UINT i = 0; + + DBFENTER; + + if ( !(hw->auxen) ) { + WLAN_LOG_DEBUG(1, + "Attempt to read 0x%04x when aux not enabled\n", + cardaddr); + return; + + } + /* Build appropriate aux page and offset */ + currpage = HFA384x_AUX_MKPAGE(cardaddr); + curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl); + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + + /* read the data */ + while ( i < len) { + *((UINT16*)(buf+i)) = hfa384x_getreg_noswap(hw, HFA384x_AUXDATA); + i+=2; + curroffset+=2; + if ( (curroffset&HFA384x_ADDR_AUX_OFF_MASK) > + HFA384x_ADDR_AUX_OFF_MAX ) { + currpage++; + curroffset = 0; + curroffset = HFA384x_AUX_MKOFF(curroffset, auxctl); + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + } + } + /* Make sure the auxctl bits are clear */ + hfa384x_setreg(hw, 0, HFA384x_AUXOFFSET); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_copy_to_aux +* +* Copies a collection of bytes to the controller memory. The +* Auxiliary port MUST be enabled prior to calling this function. +* We _might_ be in a download state. +* +* Arguments: +* hw device structure +* cardaddr address in hfa384x data space to read +* auxctl address space select +* buf ptr to destination host buffer +* len length of data to transfer (in bytes) +* +* Returns: +* nothing +* +* Side effects: +* Controller memory now contains a copy of buf +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +void +hfa384x_copy_to_aux( + hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len) +{ + UINT16 currpage; + UINT16 curroffset; + UINT i = 0; + + DBFENTER; + + if ( !(hw->auxen) ) { + WLAN_LOG_DEBUG(1, + "Attempt to read 0x%04x when aux not enabled\n", + cardaddr); + return; + + } + /* Build appropriate aux page and offset */ + currpage = HFA384x_AUX_MKPAGE(cardaddr); + curroffset = HFA384x_AUX_MKOFF(cardaddr, auxctl); + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + + /* write the data */ + while ( i < len) { + hfa384x_setreg_noswap(hw, + *((UINT16*)(buf+i)), HFA384x_AUXDATA); + i+=2; + curroffset+=2; + if ( curroffset > HFA384x_ADDR_AUX_OFF_MAX ) { + currpage++; + curroffset = 0; + hfa384x_setreg(hw, currpage, HFA384x_AUXPAGE); + hfa384x_setreg(hw, curroffset, HFA384x_AUXOFFSET); + udelay(5); /* beat */ + } + } + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* hfa384x_cmd_wait +* +* Waits for availability of the Command register, then +* issues the given command. Then polls the Evstat register +* waiting for command completion. Timeouts shouldn't be +* possible since we're preventing overlapping commands and all +* commands should be cleared and acknowledged. +* +* Arguments: +* wlandev device structure +* cmd cmd structure. Includes all arguments and result +* data points. All in host order. +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int hfa384x_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result = -ETIMEDOUT; + UINT16 reg = 0; + UINT16 counter; + + DBFENTER; + + hw->cmdflag = 0; + hw->cmddata = cmd; + + /* wait for the busy bit to clear */ + counter = 0; + reg = hfa384x_getreg(hw, HFA384x_CMD); + while ( HFA384x_CMD_ISBUSY(reg) && + (counter < 10)) { + reg = hfa384x_getreg(hw, HFA384x_CMD); + counter++; + udelay(10); + } + + if (HFA384x_CMD_ISBUSY(reg)) { + WLAN_LOG_ERROR("hfa384x_cmd timeout(1), reg=0x%0hx.\n", reg); + goto failed; + } + if (!HFA384x_CMD_ISBUSY(reg)) { + /* busy bit clear, write command */ + hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0); + hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1); + hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2); + hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD); + +#ifdef CMD_IRQ + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)) + while (! hw->cmdflag) + interruptible_sleep_on(&hw->cmdq); +#else + wait_event_interruptible(hw->cmdq, hw->cmdflag); +#endif + result = HFA384x_STATUS_RESULT_GET(cmd->status); +#else // CMD_IRQ + /* Now wait for completion */ + counter = 0; + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + /* Initialization is the problem. It takes about + 100ms. "normal" commands are typically is about + 200-400 us (I've never seen less than 200). Longer + is better so that we're not hammering the bus. */ + while ( !HFA384x_EVSTAT_ISCMD(reg) && + (counter < 5000)) { + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + counter++; + udelay(200); + } + + if ( HFA384x_EVSTAT_ISCMD(reg) ) { + result = 0; + cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS); + cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0); + cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1); + cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2); + hfa384x_setreg(hw, HFA384x_EVACK_CMD, + HFA384x_EVACK); + result = HFA384x_STATUS_RESULT_GET(cmd->result.status); + } else { + WLAN_LOG_ERROR("hfa384x_cmd timeout(2), reg=0x%0hx.\n", reg); + } +#endif /* CMD_IRQ */ + } + + failed: + hw->cmdflag = 0; + hw->cmddata = NULL; + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_dl_docmd_wait +* +* Waits for availability of the Command register, then +* issues the given command. Then polls the Evstat register +* waiting for command completion. Timeouts shouldn't be +* possible since we're preventing overlapping commands and all +* commands should be cleared and acknowledged. +* +* This routine is only used for downloads. Since it doesn't lock out +* interrupts the system response is much better. +* +* Arguments: +* wlandev device structure +* cmd cmd structure. Includes all arguments and result +* data points. All in host order. +* +* Returns: +* 0 success +* -ETIMEDOUT timed out waiting for register ready or +* command completion +* >0 command indicated error, Status and Resp0-2 are +* in hw structure. +* +* Side effects: +* +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int hfa384x_dl_docmd_wait( hfa384x_t *hw, hfa384x_metacmd_t *cmd) +{ + int result = -ETIMEDOUT; + unsigned long timeout; + UINT16 reg = 0; + + DBFENTER; + /* wait for the busy bit to clear */ + timeout = jiffies + 1*HZ; + reg = hfa384x_getreg(hw, HFA384x_CMD); + while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) { + reg = hfa384x_getreg(hw, HFA384x_CMD); + udelay(10); + } + if (HFA384x_CMD_ISBUSY(reg)) { + WLAN_LOG_WARNING("Timed out waiting for cmd register.\n"); + goto failed; + } + + if (!HFA384x_CMD_ISBUSY(reg)) { + /* busy bit clear, write command */ + hfa384x_setreg(hw, cmd->parm0, HFA384x_PARAM0); + hfa384x_setreg(hw, cmd->parm1, HFA384x_PARAM1); + hfa384x_setreg(hw, cmd->parm2, HFA384x_PARAM2); + hfa384x_setreg(hw, cmd->cmd, HFA384x_CMD); + + /* Now wait for completion */ + if ( (HFA384x_CMD_CMDCODE_GET(cmd->cmd) == HFA384x_CMDCODE_DOWNLD) ) { + /* dltimeout is in ms */ + timeout = (((UINT32)hw->dltimeout) / 1000UL) * HZ; + if ( timeout > 0 ) { + timeout += jiffies; + } else { + timeout = jiffies + 1*HZ; + } + } else { + timeout = jiffies + 1*HZ; + } + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + while ( !HFA384x_EVSTAT_ISCMD(reg) && time_before(jiffies,timeout) ) { + udelay(100); + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + } + if ( HFA384x_EVSTAT_ISCMD(reg) ) { + result = 0; + cmd->result.status = hfa384x_getreg(hw, HFA384x_STATUS); + cmd->result.resp0 = hfa384x_getreg(hw, HFA384x_RESP0); + cmd->result.resp1 = hfa384x_getreg(hw, HFA384x_RESP1); + cmd->result.resp2 = hfa384x_getreg(hw, HFA384x_RESP2); + hfa384x_setreg(hw, HFA384x_EVACK_CMD, HFA384x_EVACK); + result = HFA384x_STATUS_RESULT_GET(cmd->result.status); + } + } + +failed: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_drvr_start +* +* Issues the MAC initialize command, sets up some data structures, +* and enables the interrupts. After this function completes, the +* low-level stuff should be ready for any/all commands. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_start(hfa384x_t *hw) +{ + int result = 0; + UINT16 reg; + int i; + int j; + DBFENTER; + + /* call initialize */ + result = hfa384x_cmd_initialize(hw); + if (result != 0) { + WLAN_LOG_ERROR("Initialize command failed.\n"); + goto failed; + } + + /* make sure interrupts are disabled and any layabout events cleared */ + hfa384x_setreg(hw, 0, HFA384x_INTEN); + hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); + + hw->txfid_head = 0; + hw->txfid_tail = 0; + hw->txfid_N = HFA384x_DRVR_FIDSTACKLEN_MAX; + memset(hw->txfid_queue, 0, sizeof(hw->txfid_queue)); + + /* Allocate tx and notify FIDs */ + /* First, tx */ + for ( i = 0; i < HFA384x_DRVR_FIDSTACKLEN_MAX-1; i++) { + result = hfa384x_cmd_allocate(hw, HFA384x_DRVR_TXBUF_MAX); + if (result != 0) { + WLAN_LOG_ERROR("Allocate(tx) command failed.\n"); + goto failed; + } + j = 0; + do { + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + udelay(10); + j++; + } while ( !HFA384x_EVSTAT_ISALLOC(reg) && j < 50); /* 50 is timeout */ + if ( j >= 50 ) { + WLAN_LOG_ERROR("Timed out waiting for evalloc(tx).\n"); + result = -ETIMEDOUT; + goto failed; + } + reg = hfa384x_getreg(hw, HFA384x_ALLOCFID); + + txfid_queue_add(hw, reg); + + WLAN_LOG_DEBUG(4,"hw->txfid_queue[%d]=0x%04x\n",i,reg); + + reg = HFA384x_EVACK_ALLOC_SET(1); + hfa384x_setreg(hw, reg, HFA384x_EVACK); + + } + + /* Now, the info frame fid */ + result = hfa384x_cmd_allocate(hw, HFA384x_INFOFRM_MAXLEN); + if (result != 0) { + WLAN_LOG_ERROR("Allocate(tx) command failed.\n"); + goto failed; + } + i = 0; + do { + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + udelay(10); + i++; + } while ( !HFA384x_EVSTAT_ISALLOC(reg) && i < 50); /* 50 is timeout */ + if ( i >= 50 ) { + WLAN_LOG_ERROR("Timed out waiting for evalloc(info).\n"); + result = -ETIMEDOUT; + goto failed; + } + hw->infofid = hfa384x_getreg(hw, HFA384x_ALLOCFID); + reg = HFA384x_EVACK_ALLOC_SET(1); + hfa384x_setreg(hw, reg, HFA384x_EVACK); + WLAN_LOG_DEBUG(4,"hw->infofid=0x%04x\n", hw->infofid); + + /* Set swsupport regs to magic # for card presence detection */ + hfa384x_setreg(hw, HFA384x_DRVR_MAGIC, HFA384x_SWSUPPORT0); + + /* Now enable the interrupts and set the running state */ + hfa384x_setreg(hw, 0xffff, HFA384x_EVSTAT); + hfa384x_events_all(hw); + + hw->state = HFA384x_STATE_RUNNING; + + goto done; +failed: + WLAN_LOG_ERROR("Failed, result=%d\n", result); +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_stop +* +* Issues the initialize command to leave us in the 'reset' state. +* +* Arguments: +* hw device structure +* Returns: +* 0 success +* >0 f/w reported error - f/w status code +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_stop(hfa384x_t *hw) +{ + int result = 0; + int i; + DBFENTER; + + del_timer_sync(&hw->commsqual_timer); + + if ( hw->wlandev->hwremoved ) { + /* only flush when we're shutting down for good */ + flush_scheduled_work(); + } + + if (hw->state == HFA384x_STATE_RUNNING) { + /* + * Send the MAC initialize cmd. + */ + hfa384x_cmd_initialize(hw); + + /* + * Make absolutely sure interrupts are disabled and any + * layabout events cleared + */ + hfa384x_setreg(hw, 0, HFA384x_INTEN); + hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); + } + + tasklet_kill(&hw->bap_tasklet); + + hw->link_status = HFA384x_LINK_NOTCONNECTED; + hw->state = HFA384x_STATE_INIT; + + /* Clear all the port status */ + for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { + hw->port_enabled[i] = 0; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_txframe +* +* Takes a frame from prism2sta and queues it for transmission. +* +* Arguments: +* hw device structure +* skb packet buffer struct. Contains an 802.11 +* data frame. +* p80211_hdr points to the 802.11 header for the packet. +* Returns: +* 0 Success and more buffs available +* 1 Success but no more buffs +* 2 Allocation failure +* 3 MAC Tx command failed +* 4 Buffer full or queue busy +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep) +{ + hfa384x_tx_frame_t txdesc; + UINT16 macq = 0; + UINT16 fid; + int result; + + DBFENTER; + + /* Build Tx frame structure */ + /* Set up the control field */ + memset(&txdesc, 0, sizeof(txdesc)); + +/* Tx complete and Tx exception disable per dleach. Might be causing + * buf depletion + */ +#define DOBOTH 1 +#if DOBOTH + txdesc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1); +#elif DOEXC + txdesc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0); +#else + txdesc.tx_control = + HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | + HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0); +#endif + + /* if we're using host WEP, increase size by IV+ICV */ + if (p80211_wep->data) { + txdesc.data_len = host2hfa384x_16(skb->len+8); + // txdesc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1); + } else { + txdesc.data_len = host2hfa384x_16(skb->len); + } + + txdesc.tx_control = host2hfa384x_16(txdesc.tx_control); + /* copy the header over to the txdesc */ + memcpy(&(txdesc.frame_control), p80211_hdr, sizeof(p80211_hdr_t)); + + /* Since tbusy is set whenever the stack is empty, there should + * always be something on the stack if we get to this point. + * [MSM]: NOT TRUE!!!!! so I added the test of fid below. + */ + + /* Allocate FID */ + + fid = txfid_queue_remove(hw); + + if ( fid == 0 ) { /* stack or queue was empty */ + return 4; + } + + /* now let's get the cmdlock */ + spin_lock(&hw->cmdlock); + + /* Copy descriptor+payload to FID */ + if (p80211_wep->data) { + result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0, + &txdesc, sizeof(txdesc), + p80211_wep->iv, sizeof(p80211_wep->iv), + p80211_wep->data, skb->len, + p80211_wep->icv, sizeof(p80211_wep->icv)); + } else { + result = hfa384x_copy_to_bap4(hw, HFA384x_BAP_PROC, fid, 0, + &txdesc, sizeof(txdesc), + skb->data, skb->len, + NULL, 0, NULL, 0); + } + + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_to_bap(%04x, %d, %d) failed, result=0x%x\n", + fid, + sizeof(txdesc), + skb->len, + result); + + /* put the fid back in the queue */ + txfid_queue_add(hw, fid); + + result = 3; + goto failed; + } + + /* Issue Tx command */ + result = hfa384x_cmd_transmit(hw, HFA384x_TXCMD_RECL, macq, fid); + + if ( result != 0 ) { + txfid_queue_add(hw, fid); + + WLAN_LOG_DEBUG(1,"cmd_tx(%04x) failed, result=%d\n", + fid, result); + result = 3; + goto failed; + } + + /* indicate we haven't any buffers, int_alloc will clear */ + result = txfid_queue_empty(hw); +failed: + + spin_unlock(&hw->cmdlock); + + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* hfa384x_interrupt +* +* Driver interrupt handler. +* +* Arguments: +* irq irq number +* dev_id pointer to the device +* regs registers +* +* Returns: +* nothing +* +* Side effects: +* May result in a frame being passed up the stack or an info +* frame being handled. +* +* Call context: +* Ummm, could it be interrupt? +----------------------------------------------------------------*/ +irqreturn_t hfa384x_interrupt(int irq, void *dev_id PT_REGS) +{ + int reg; + wlandevice_t *wlandev = (wlandevice_t*)dev_id; + hfa384x_t *hw = wlandev->priv; + int ev_read = 0; + DBFENTER; + + if (!wlandev || wlandev->hwremoved) + return IRQ_NONE; /* Not much we can do w/o hardware */ +#if (WLAN_HOSTIF == WLAN_PCMCIA) + if (hw->iobase == 0) /* XXX FIXME Properly */ + return IRQ_NONE; +#endif + + for (;;ev_read++) { + if (ev_read >= prism2_irq_evread_max) + break; + + /* Check swsupport reg magic # for card presence */ + reg = hfa384x_getreg(hw, HFA384x_SWSUPPORT0); + if ( reg != HFA384x_DRVR_MAGIC) { + WLAN_LOG_DEBUG(2, "irq=%d, no magic. Card removed?.\n", irq); + break; + } + + /* read the EvStat register for interrupt enabled events */ + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + + /* AND with the enabled interrupts */ + reg &= hfa384x_getreg(hw, HFA384x_INTEN); + + /* Handle the events */ + if ( HFA384x_EVSTAT_ISWTERR(reg) ){ + WLAN_LOG_ERROR( + "Error: WTERR interrupt received (unhandled).\n"); + hfa384x_setreg(hw, HFA384x_EVACK_WTERR_SET(1), + HFA384x_EVACK); + } + + if ( HFA384x_EVSTAT_ISINFDROP(reg) ){ + hfa384x_int_infdrop(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_INFDROP_SET(1), + HFA384x_EVACK); + } + + if (HFA384x_EVSTAT_ISBAP_OP(reg)) { + /* Disable the BAP interrupts */ + hfa384x_events_nobap(hw); + tasklet_schedule(&hw->bap_tasklet); + } + + if ( HFA384x_EVSTAT_ISALLOC(reg) ){ + hfa384x_int_alloc(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_ALLOC_SET(1), + HFA384x_EVACK); + } + + if ( HFA384x_EVSTAT_ISDTIM(reg) ){ + hfa384x_int_dtim(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_DTIM_SET(1), + HFA384x_EVACK); + } +#ifdef CMD_IRQ + if ( HFA384x_EVSTAT_ISCMD(reg) ){ + hfa384x_int_cmd(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_CMD_SET(1), + HFA384x_EVACK); + } +#endif + + /* allow the evstat to be updated after the evack */ + udelay(20); + } + + DBFEXIT; + return IRQ_HANDLED; +} + +#ifdef CMD_IRQ +/*---------------------------------------------------------------- +* hfa384x_int_cmd +* +* Handles command completion event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void hfa384x_int_cmd(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + DBFENTER; + + // check to make sure it's the right command? + if (hw->cmddata) { + hw->cmddata->status = hfa384x_getreg(hw, HFA384x_STATUS); + hw->cmddata->resp0 = hfa384x_getreg(hw, HFA384x_RESP0); + hw->cmddata->resp1 = hfa384x_getreg(hw, HFA384x_RESP1); + hw->cmddata->resp2 = hfa384x_getreg(hw, HFA384x_RESP2); + } + hw->cmdflag = 1; + + printk(KERN_INFO "um. int_cmd\n"); + + wake_up_interruptible(&hw->cmdq); + + // XXXX perform a bap copy too? + + DBFEXIT; + return; +} +#endif + +/*---------------------------------------------------------------- +* hfa384x_int_dtim +* +* Handles the DTIM early warning event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_dtim(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = wlandev->priv; +#endif + DBFENTER; + prism2sta_ev_dtim(wlandev); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_infdrop +* +* Handles the InfDrop event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_infdrop(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = wlandev->priv; +#endif + DBFENTER; + prism2sta_ev_infdrop(wlandev); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_info +* +* Handles the Info event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_info(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 reg; + hfa384x_InfFrame_t inf; + int result; + DBFENTER; + /* Retrieve the FID */ + reg = hfa384x_getreg(hw, HFA384x_INFOFID); + + /* Retrieve the length */ + result = hfa384x_copy_from_bap( hw, + HFA384x_BAP_INT, reg, 0, &inf.framelen, sizeof(UINT16)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + reg, sizeof(inf), result); + goto failed; + } + inf.framelen = hfa384x2host_16(inf.framelen); + + /* Retrieve the rest */ + result = hfa384x_copy_from_bap( hw, + HFA384x_BAP_INT, reg, sizeof(UINT16), + &(inf.infotype), inf.framelen * sizeof(UINT16)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + reg, sizeof(inf), result); + goto failed; + } + + prism2sta_ev_info(wlandev, &inf); +failed: + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_txexc +* +* Handles the TxExc event. A Transmit Exception event indicates +* that the MAC's TX process was unsuccessful - so the packet did +* not get transmitted. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_txexc(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 status; + UINT16 fid; + int result = 0; + DBFENTER; + /* Collect the status and display */ + fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID); + result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + fid, sizeof(status), result); + goto failed; + } + status = hfa384x2host_16(status); + prism2sta_ev_txexc(wlandev, status); +failed: + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_tx +* +* Handles the Tx event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_tx(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 fid; + UINT16 status; + int result = 0; + DBFENTER; + fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID); + result = hfa384x_copy_from_bap(hw, HFA384x_BAP_INT, fid, 0, &status, sizeof(status)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", + fid, sizeof(status), result); + goto failed; + } + status = hfa384x2host_16(status); + prism2sta_ev_tx(wlandev, status); +failed: + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_int_rx +* +* Handles the Rx event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* tasklet +----------------------------------------------------------------*/ +static void hfa384x_int_rx(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 rxfid; + hfa384x_rx_frame_t rxdesc; + int result; + int hdrlen; + UINT16 fc; + p80211_rxmeta_t *rxmeta; + struct sk_buff *skb = NULL; + UINT8 *datap; + + DBFENTER; + + /* Get the FID */ + rxfid = hfa384x_getreg(hw, HFA384x_RXFID); + /* Get the descriptor (including headers) */ + result = hfa384x_copy_from_bap(hw, + HFA384x_BAP_INT, + rxfid, + 0, + &rxdesc, + sizeof(rxdesc)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n", + rxfid, + 0, + sizeof(rxdesc), + result); + goto done; + } + + /* Byte order convert once up front. */ + rxdesc.status = hfa384x2host_16(rxdesc.status); + rxdesc.time = hfa384x2host_32(rxdesc.time); + + /* drop errors and whatnot in promisc mode */ + if (( wlandev->netdev->flags & IFF_PROMISC ) && + (HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) || + HFA384x_RXSTATUS_ISUNDECR(rxdesc.status))) + goto done; + + /* Now handle frame based on port# */ + switch( HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) ) + { + case 0: + + fc = ieee2host16(rxdesc.frame_control); + + /* If exclude and we receive an unencrypted, drop it */ + if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) && + !WLAN_GET_FC_ISWEP(fc)) { + goto done; + } + + hdrlen = p80211_headerlen(fc); + + /* Allocate the buffer, note CRC (aka FCS). pballoc */ + /* assumes there needs to be space for one */ + skb = dev_alloc_skb(hfa384x2host_16(rxdesc.data_len) + hdrlen + WLAN_CRC_LEN + 2); /* a little extra */ + + if ( ! skb ) { + WLAN_LOG_ERROR("alloc_skb failed.\n"); + goto done; + } + + skb->dev = wlandev->netdev; + + /* theoretically align the IP header on a 32-bit word. */ + if ( hdrlen == WLAN_HDR_A4_LEN ) + skb_reserve(skb, 2); + + /* Copy the 802.11 hdr to the buffer */ + datap = skb_put(skb, WLAN_HDR_A3_LEN); + memcpy(datap, &rxdesc.frame_control, WLAN_HDR_A3_LEN); + + /* Snag the A4 address if present */ + if (hdrlen == WLAN_HDR_A4_LEN) { + datap = skb_put(skb, WLAN_ADDR_LEN); + memcpy(datap, &rxdesc.address4, WLAN_HDR_A3_LEN); + } + + /* we can convert the data_len as we passed the original on */ + rxdesc.data_len = hfa384x2host_16(rxdesc.data_len); + + /* Copy the payload data to the buffer */ + if ( rxdesc.data_len > 0 ) { + datap = skb_put(skb, rxdesc.data_len); + result = hfa384x_copy_from_bap(hw, + HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF, + datap, rxdesc.data_len); + if ( result ) { + WLAN_LOG_DEBUG(1, + "copy_from_bap(0x%04x, %d, %d) failed, result=0x%x\n", + rxfid, + HFA384x_RX_DATA_OFF, + rxdesc.data_len, + result); + goto failed; + } + } + /* the prism2 cards don't return the FCS */ + datap = skb_put(skb, WLAN_CRC_LEN); + memset (datap, 0xff, WLAN_CRC_LEN); + skb_reset_mac_header(skb); + + /* Attach the rxmeta, set some stuff */ + p80211skb_rxmeta_attach(wlandev, skb); + rxmeta = P80211SKB_RXMETA(skb); + rxmeta->mactime = rxdesc.time; + rxmeta->rxrate = rxdesc.rate; + rxmeta->signal = rxdesc.signal - hw->dbmadjust; + rxmeta->noise = rxdesc.silence - hw->dbmadjust; + + prism2sta_ev_rx(wlandev, skb); + goto done; + case 7: + + if ( ! HFA384x_RXSTATUS_ISFCSERR(rxdesc.status) ) { + hfa384x_int_rxmonitor( wlandev, rxfid, &rxdesc); + } else { + WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n"); + } + goto done; + + default: + + WLAN_LOG_WARNING("Received frame on unsupported port=%d\n", + HFA384x_RXSTATUS_MACPORT_GET(rxdesc.status) ); + goto done; + } + + failed: + dev_kfree_skb(skb); + + done: + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_int_rxmonitor +* +* Helper function for int_rx. Handles monitor frames. +* Note that this function allocates space for the FCS and sets it +* to 0xffffffff. The hfa384x doesn't give us the FCS value but the +* higher layers expect it. 0xffffffff is used as a flag to indicate +* the FCS is bogus. +* +* Arguments: +* wlandev wlan device structure +* rxfid received FID +* rxdesc rx descriptor read from card in int_rx +* +* Returns: +* nothing +* +* Side effects: +* Allocates an skb and passes it up via the PF_PACKET interface. +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, UINT16 rxfid, + hfa384x_rx_frame_t *rxdesc) +{ + hfa384x_t *hw = wlandev->priv; + UINT hdrlen = 0; + UINT datalen = 0; + UINT skblen = 0; + UINT truncated = 0; + UINT8 *datap; + UINT16 fc; + struct sk_buff *skb; + + DBFENTER; + /* Don't forget the status, time, and data_len fields are in host order */ + /* Figure out how big the frame is */ + fc = ieee2host16(rxdesc->frame_control); + hdrlen = p80211_headerlen(fc); + datalen = hfa384x2host_16(rxdesc->data_len); + + /* Allocate an ind message+framesize skb */ + skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + + hdrlen + datalen + WLAN_CRC_LEN; + + /* sanity check the length */ + if ( skblen > + (sizeof(p80211msg_lnxind_wlansniffrm_t) + + WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) { + WLAN_LOG_DEBUG(1, "overlen frm: len=%d\n", + skblen - sizeof(p80211msg_lnxind_wlansniffrm_t)); + } + + if ( (skb = dev_alloc_skb(skblen)) == NULL ) { + WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen); + return; + } + + /* only prepend the prism header if in the right mode */ + if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr == 0)) { + p80211msg_lnxind_wlansniffrm_t *msg; + datap = skb_put(skb, sizeof(p80211msg_lnxind_wlansniffrm_t)); + msg = (p80211msg_lnxind_wlansniffrm_t*) datap; + + /* Initialize the message members */ + msg->msgcode = DIDmsg_lnxind_wlansniffrm; + msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t); + strcpy(msg->devname, wlandev->name); + + msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime; + msg->hosttime.status = 0; + msg->hosttime.len = 4; + msg->hosttime.data = jiffies; + + msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime; + msg->mactime.status = 0; + msg->mactime.len = 4; + msg->mactime.data = rxdesc->time * 1000; + + msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel; + msg->channel.status = 0; + msg->channel.len = 4; + msg->channel.data = hw->sniff_channel; + + msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; + msg->rssi.status = P80211ENUM_msgitem_status_no_value; + msg->rssi.len = 4; + msg->rssi.data = 0; + + msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq; + msg->sq.status = P80211ENUM_msgitem_status_no_value; + msg->sq.len = 4; + msg->sq.data = 0; + + msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal; + msg->signal.status = 0; + msg->signal.len = 4; + msg->signal.data = rxdesc->signal; + + msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise; + msg->noise.status = 0; + msg->noise.len = 4; + msg->noise.data = rxdesc->silence; + + msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate; + msg->rate.status = 0; + msg->rate.len = 4; + msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */ + + msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx; + msg->istx.status = 0; + msg->istx.len = 4; + msg->istx.data = P80211ENUM_truth_false; + + msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen; + msg->frmlen.status = 0; + msg->frmlen.len = 4; + msg->frmlen.data = hdrlen + datalen + WLAN_CRC_LEN; + } else if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && + (hw->sniffhdr != 0)) { + p80211_caphdr_t *caphdr; + /* The NEW header format! */ + datap = skb_put(skb, sizeof(p80211_caphdr_t)); + caphdr = (p80211_caphdr_t*) datap; + + caphdr->version = htonl(P80211CAPTURE_VERSION); + caphdr->length = htonl(sizeof(p80211_caphdr_t)); + caphdr->mactime = __cpu_to_be64(rxdesc->time); + caphdr->hosttime = __cpu_to_be64(jiffies); + caphdr->phytype = htonl(4); /* dss_dot11_b */ + caphdr->channel = htonl(hw->sniff_channel); + caphdr->datarate = htonl(rxdesc->rate); + caphdr->antenna = htonl(0); /* unknown */ + caphdr->priority = htonl(0); /* unknown */ + caphdr->ssi_type = htonl(3); /* rssi_raw */ + caphdr->ssi_signal = htonl(rxdesc->signal); + caphdr->ssi_noise = htonl(rxdesc->silence); + caphdr->preamble = htonl(0); /* unknown */ + caphdr->encoding = htonl(1); /* cck */ + } + /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */ + datap = skb_put(skb, hdrlen); + memcpy( datap, &(rxdesc->frame_control), hdrlen); + + /* If any, copy the data from the card to the skb */ + if ( datalen > 0 ) + { + /* Truncate the packet if the user wants us to */ + UINT dataread = datalen; + if(hw->sniff_truncate > 0 && dataread > hw->sniff_truncate) { + dataread = hw->sniff_truncate; + truncated = 1; + } + + datap = skb_put(skb, dataread); + hfa384x_copy_from_bap(hw, + HFA384x_BAP_INT, rxfid, HFA384x_RX_DATA_OFF, + datap, dataread); + + /* check for unencrypted stuff if WEP bit set. */ + if (*(datap - hdrlen + 1) & 0x40) // wep set + if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa)) + *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header! + } + + if (!truncated && hw->sniff_fcs) { + /* Set the FCS */ + datap = skb_put(skb, WLAN_CRC_LEN); + memset( datap, 0xff, WLAN_CRC_LEN); + } + + /* pass it back up */ + prism2sta_ev_rx(wlandev, skb); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* hfa384x_int_alloc +* +* Handles the Alloc event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void hfa384x_int_alloc(wlandevice_t *wlandev) +{ + hfa384x_t *hw = wlandev->priv; + UINT16 fid; + INT16 result; + + DBFENTER; + + /* Handle the reclaimed FID */ + /* collect the FID and push it onto the stack */ + fid = hfa384x_getreg(hw, HFA384x_ALLOCFID); + + if ( fid != hw->infofid ) { /* It's a transmit fid */ + WLAN_LOG_DEBUG(5, "int_alloc(%#x)\n", fid); + result = txfid_queue_add(hw, fid); + if (result != -1) { + prism2sta_ev_alloc(wlandev); + WLAN_LOG_DEBUG(5, "q_add.\n"); + } else { + WLAN_LOG_DEBUG(5, "q_full.\n"); + } + } else { + /* unlock the info fid */ + up(&hw->infofid_sem); + } + + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* hfa384x_drvr_handover +* +* Sends a handover notification to the MAC. +* +* Arguments: +* hw device structure +* addr address of station that's left +* +* Returns: +* zero success. +* -ERESTARTSYS received signal while waiting for semaphore. +* -EIO failed to write to bap, or failed in cmd. +* +* Side effects: +* +* Call context: +* process thread, NOTE: this call may block on a semaphore! +----------------------------------------------------------------*/ +int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr) +{ + int result = 0; + hfa384x_HandoverAddr_t rec; + UINT len; + DBFENTER; + + /* Acquire the infofid */ + if ( down_interruptible(&hw->infofid_sem) ) { + result = -ERESTARTSYS; + goto failed; + } + + /* Set up the record */ + len = sizeof(hfa384x_HandoverAddr_t); + rec.framelen = host2hfa384x_16(len/2 - 1); + rec.infotype = host2hfa384x_16(HFA384x_IT_HANDOVERADDR); + memcpy(rec.handover_addr, addr, sizeof(rec.handover_addr)); + + /* Issue the command */ + result = hfa384x_cmd_notify(hw, 1, hw->infofid, &rec, len); + + if ( result != 0 ) { + WLAN_LOG_DEBUG(1,"cmd_notify(%04x) failed, result=%d", + hw->infofid, result); + result = -EIO; + goto failed; + } + +failed: + DBFEXIT; + return result; +} + +void hfa384x_tx_timeout(wlandevice_t *wlandev) +{ + DBFENTER; + + WLAN_LOG_WARNING("Implement me.\n"); + + DBFEXIT; +} + +/* Handles all "rx" BAP operations */ +static void hfa384x_bap_tasklet(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t *) data; + wlandevice_t *wlandev = hw->wlandev; + int counter = prism2_irq_evread_max; + int reg; + + DBFENTER; + + while (counter-- > 0) { + /* Get interrupt register */ + reg = hfa384x_getreg(hw, HFA384x_EVSTAT); + + if ((reg == 0xffff) || + !(reg & HFA384x_INT_BAP_OP)) { + break; + } + + if ( HFA384x_EVSTAT_ISINFO(reg) ){ + hfa384x_int_info(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_INFO_SET(1), + HFA384x_EVACK); + } + if ( HFA384x_EVSTAT_ISTXEXC(reg) ){ + hfa384x_int_txexc(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_TXEXC_SET(1), + HFA384x_EVACK); + } + if ( HFA384x_EVSTAT_ISTX(reg) ){ + hfa384x_int_tx(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_TX_SET(1), + HFA384x_EVACK); + } + if ( HFA384x_EVSTAT_ISRX(reg) ){ + hfa384x_int_rx(wlandev); + hfa384x_setreg(hw, HFA384x_EVACK_RX_SET(1), + HFA384x_EVACK); + } + } + + /* re-enable interrupts */ + hfa384x_events_all(hw); + + DBFEXIT; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/Makefile +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_PRISM2_USB) += prism2_usb.o + +EXTRA_CFLAGS += -I$(src)/../p80211 -I$(src) --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2sta.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2sta.c @@ -0,0 +1,2502 @@ +/* src/prism2/driver/prism2sta.c +* +* Implements the station functionality for prism2 +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file implements the module and linux pcmcia routines for the +* prism2 driver. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,25)) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) +#include +#else +#include +#endif + +#include +#include +#include +#include + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#include +#include +#include +#include +#include +#include +#endif + +#include + +#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI)) +#include +#include +#endif + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +/*================================================================*/ +/* Local Macros */ + +/*================================================================*/ +/* Local Types */ + +/*================================================================*/ +/* Local Static Definitions */ + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#define DRIVER_SUFFIX "_cs" +#elif (WLAN_HOSTIF == WLAN_PLX) +#define DRIVER_SUFFIX "_plx" +typedef char* dev_info_t; +#elif (WLAN_HOSTIF == WLAN_PCI) +#define DRIVER_SUFFIX "_pci" +typedef char* dev_info_t; +#elif (WLAN_HOSTIF == WLAN_USB) +#define DRIVER_SUFFIX "_usb" +typedef char* dev_info_t; +#else +#error "HOSTIF unsupported or undefined!" +#endif + +static char *version = "prism2" DRIVER_SUFFIX ".o: " WLAN_RELEASE; +static dev_info_t dev_info = "prism2" DRIVER_SUFFIX; + +#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI) +#ifdef CONFIG_PM +static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state); +static int prism2sta_resume_pci(struct pci_dev *pdev); +#endif +#endif + +#if (WLAN_HOSTIF == WLAN_PCI) + +#endif /* WLAN_PCI */ + +static wlandevice_t *create_wlan(void); + +/*----------------------------------------------------------------*/ +/* --Module Parameters */ + +int prism2_reset_holdtime=30; /* Reset hold time in ms */ +int prism2_reset_settletime=100; /* Reset settle time in ms */ + +#if (WLAN_HOSTIF == WLAN_USB) +static int prism2_doreset=0; /* Do a reset at init? */ +#else +static int prism2_doreset=1; /* Do a reset at init? */ +int prism2_bap_timeout=1000; /* BAP timeout */ +int prism2_irq_evread_max=20; /* Maximum number of + * ev_reads (loops) + * in irq handler + */ +#endif + +#ifdef WLAN_INCLUDE_DEBUG +int prism2_debug=0; +module_param( prism2_debug, int, 0644); +MODULE_PARM_DESC(prism2_debug, "prism2 debugging"); +#endif + +module_param( prism2_doreset, int, 0644); +MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization"); + +module_param( prism2_reset_holdtime, int, 0644); +MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms"); +module_param( prism2_reset_settletime, int, 0644); +MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms"); + +#if (WLAN_HOSTIF != WLAN_USB) +module_param( prism2_bap_timeout, int, 0644); +MODULE_PARM_DESC(prism2_bap_timeout, "BufferAccessPath Timeout in 10*n us"); +module_param( prism2_irq_evread_max, int, 0644); +MODULE_PARM_DESC( prism2_irq_evread_max, "Maximim number of event reads in interrupt handler"); +#endif + +MODULE_LICENSE("Dual MPL/GPL"); + +/*================================================================*/ +/* Local Function Declarations */ + +static int prism2sta_open(wlandevice_t *wlandev); +static int prism2sta_close(wlandevice_t *wlandev); +static void prism2sta_reset(wlandevice_t *wlandev ); +static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep); +static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg); +static int prism2sta_getcardinfo(wlandevice_t *wlandev); +static int prism2sta_globalsetup(wlandevice_t *wlandev); +static int prism2sta_setmulticast(wlandevice_t *wlandev, + netdevice_t *dev); + +static void prism2sta_inf_handover( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_tallies( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_hostscanresults( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_scanresults( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_chinforesults( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_linkstatus( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_assocstatus( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_authreq( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_authreq_defer( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +static void prism2sta_inf_psusercnt( + wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); + +#ifdef CONFIG_PROC_FS +static int +prism2sta_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data); +#endif + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* dmpmem +* +* Debug utility function to dump memory to the kernel debug log. +* +* Arguments: +* buf ptr data we want dumped +* len length of data +* +* Returns: +* nothing +* Side effects: +* +* Call context: +* process thread +* interrupt +----------------------------------------------------------------*/ +inline void dmpmem(void *buf, int n) +{ + int c; + for ( c= 0; c < n; c++) { + if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c); + printk("%02x ", ((UINT8*)buf)[c]); + if ( (c % 16) == 15 ) printk("\n"); + } + if ( (c % 16) != 0 ) printk("\n"); +} + + +/*---------------------------------------------------------------- +* prism2sta_open +* +* WLAN device open method. Called from p80211netdev when kernel +* device open (start) method is called in response to the +* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP +* from clear to set. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_open(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef ANCIENT_MODULE_CODE + MOD_INC_USE_COUNT; +#endif + + /* We don't currently have to do anything else. + * The setup of the MAC should be subsequently completed via + * the mlme commands. + * Higher layers know we're ready from dev->start==1 and + * dev->tbusy==0. Our rx path knows to pass up received/ + * frames because of dev->flags&IFF_UP is true. + */ + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2sta_close +* +* WLAN device close method. Called from p80211netdev when kernel +* device close method is called in response to the +* SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP +* from set to clear. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_close(wlandevice_t *wlandev) +{ + DBFENTER; + +#ifdef ANCIENT_MODULE_CODE + MOD_DEC_USE_COUNT; +#endif + + /* We don't currently have to do anything else. + * Higher layers know we're not ready from dev->start==0 and + * dev->tbusy==1. Our rx path knows to not pass up received + * frames because of dev->flags&IFF_UP is false. + */ + + DBFEXIT; + return 0; +} + + +/*---------------------------------------------------------------- +* prism2sta_reset +* +* Not currently implented. +* +* Arguments: +* wlandev wlan device structure +* none +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static void prism2sta_reset(wlandevice_t *wlandev ) +{ + DBFENTER; + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_txframe +* +* Takes a frame from p80211 and queues it for transmission. +* +* Arguments: +* wlandev wlan device structure +* pb packet buffer struct. Contains an 802.11 +* data frame. +* p80211_hdr points to the 802.11 header for the packet. +* Returns: +* 0 Success and more buffs available +* 1 Success but no more buffs +* 2 Allocation failure +* 4 Buffer full or queue busy +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, + p80211_hdr_t *p80211_hdr, + p80211_metawep_t *p80211_wep) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + int result; + DBFENTER; + + /* If necessary, set the 802.11 WEP bit */ + if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) { + p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1)); + } + + result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep); + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_mlmerequest +* +* wlan command message handler. All we do here is pass the message +* over to the prism2sta_mgmt_handler. +* +* Arguments: +* wlandev wlan device structure +* msg wlan command message +* Returns: +* 0 success +* <0 successful acceptance of message, but we're +* waiting for an async process to finish before +* we're done with the msg. When the asynch +* process is done, we'll call the p80211 +* function p80211req_confirm() . +* >0 An error occurred while we were handling +* the message. +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + int result = 0; + DBFENTER; + + switch( msg->msgcode ) + { + case DIDmsg_dot11req_mibget : + WLAN_LOG_DEBUG(2,"Received mibget request\n"); + result = prism2mgmt_mibset_mibget(wlandev, msg); + break; + case DIDmsg_dot11req_mibset : + WLAN_LOG_DEBUG(2,"Received mibset request\n"); + result = prism2mgmt_mibset_mibget(wlandev, msg); + break; + case DIDmsg_dot11req_powermgmt : + WLAN_LOG_DEBUG(2,"Received powermgmt request\n"); + result = prism2mgmt_powermgmt(wlandev, msg); + break; + case DIDmsg_dot11req_scan : + WLAN_LOG_DEBUG(2,"Received scan request\n"); + result = prism2mgmt_scan(wlandev, msg); + break; + case DIDmsg_dot11req_scan_results : + WLAN_LOG_DEBUG(2,"Received scan_results request\n"); + result = prism2mgmt_scan_results(wlandev, msg); + break; + case DIDmsg_dot11req_join : + WLAN_LOG_DEBUG(2,"Received join request\n"); + result = prism2mgmt_join(wlandev, msg); + break; + case DIDmsg_dot11req_authenticate : + WLAN_LOG_DEBUG(2,"Received authenticate request\n"); + result = prism2mgmt_authenticate(wlandev, msg); + break; + case DIDmsg_dot11req_deauthenticate : + WLAN_LOG_DEBUG(2,"Received mlme deauthenticate request\n"); + result = prism2mgmt_deauthenticate(wlandev, msg); + break; + case DIDmsg_dot11req_associate : + WLAN_LOG_DEBUG(2,"Received mlme associate request\n"); + result = prism2mgmt_associate(wlandev, msg); + break; + case DIDmsg_dot11req_reassociate : + WLAN_LOG_DEBUG(2,"Received mlme reassociate request\n"); + result = prism2mgmt_reassociate(wlandev, msg); + break; + case DIDmsg_dot11req_disassociate : + WLAN_LOG_DEBUG(2,"Received mlme disassociate request\n"); + result = prism2mgmt_disassociate(wlandev, msg); + break; + case DIDmsg_dot11req_reset : + WLAN_LOG_DEBUG(2,"Received mlme reset request\n"); + result = prism2mgmt_reset(wlandev, msg); + break; + case DIDmsg_dot11req_start : + WLAN_LOG_DEBUG(2,"Received mlme start request\n"); + result = prism2mgmt_start(wlandev, msg); + break; + /* + * Prism2 specific messages + */ + case DIDmsg_p2req_join : + WLAN_LOG_DEBUG(2,"Received p2 join request\n"); + result = prism2mgmt_p2_join(wlandev, msg); + break; + case DIDmsg_p2req_readpda : + WLAN_LOG_DEBUG(2,"Received mlme readpda request\n"); + result = prism2mgmt_readpda(wlandev, msg); + break; + case DIDmsg_p2req_readcis : + WLAN_LOG_DEBUG(2,"Received mlme readcis request\n"); + result = prism2mgmt_readcis(wlandev, msg); + break; + case DIDmsg_p2req_auxport_state : + WLAN_LOG_DEBUG(2,"Received mlme auxport_state request\n"); + result = prism2mgmt_auxport_state(wlandev, msg); + break; + case DIDmsg_p2req_auxport_read : + WLAN_LOG_DEBUG(2,"Received mlme auxport_read request\n"); + result = prism2mgmt_auxport_read(wlandev, msg); + break; + case DIDmsg_p2req_auxport_write : + WLAN_LOG_DEBUG(2,"Received mlme auxport_write request\n"); + result = prism2mgmt_auxport_write(wlandev, msg); + break; + case DIDmsg_p2req_low_level : + WLAN_LOG_DEBUG(2,"Received mlme low_level request\n"); + result = prism2mgmt_low_level(wlandev, msg); + break; + case DIDmsg_p2req_test_command : + WLAN_LOG_DEBUG(2,"Received mlme test_command request\n"); + result = prism2mgmt_test_command(wlandev, msg); + break; + case DIDmsg_p2req_mmi_read : + WLAN_LOG_DEBUG(2,"Received mlme mmi_read request\n"); + result = prism2mgmt_mmi_read(wlandev, msg); + break; + case DIDmsg_p2req_mmi_write : + WLAN_LOG_DEBUG(2,"Received mlme mmi_write request\n"); + result = prism2mgmt_mmi_write(wlandev, msg); + break; + case DIDmsg_p2req_ramdl_state : + WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n"); + result = prism2mgmt_ramdl_state(wlandev, msg); + break; + case DIDmsg_p2req_ramdl_write : + WLAN_LOG_DEBUG(2,"Received mlme ramdl_write request\n"); + result = prism2mgmt_ramdl_write(wlandev, msg); + break; + case DIDmsg_p2req_flashdl_state : + WLAN_LOG_DEBUG(2,"Received mlme flashdl_state request\n"); + result = prism2mgmt_flashdl_state(wlandev, msg); + break; + case DIDmsg_p2req_flashdl_write : + WLAN_LOG_DEBUG(2,"Received mlme flashdl_write request\n"); + result = prism2mgmt_flashdl_write(wlandev, msg); + break; + case DIDmsg_p2req_dump_state : + WLAN_LOG_DEBUG(2,"Received mlme dump_state request\n"); + result = prism2mgmt_dump_state(wlandev, msg); + break; + case DIDmsg_p2req_channel_info : + WLAN_LOG_DEBUG(2,"Received mlme channel_info request\n"); + result = prism2mgmt_channel_info(wlandev, msg); + break; + case DIDmsg_p2req_channel_info_results : + WLAN_LOG_DEBUG(2,"Received mlme channel_info_results request\n"); + result = prism2mgmt_channel_info_results(wlandev, msg); + break; + /* + * Linux specific messages + */ + case DIDmsg_lnxreq_hostwep : + break; // ignore me. + case DIDmsg_lnxreq_ifstate : + { + p80211msg_lnxreq_ifstate_t *ifstatemsg; + WLAN_LOG_DEBUG(2,"Received mlme ifstate request\n"); + ifstatemsg = (p80211msg_lnxreq_ifstate_t*)msg; + result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data); + ifstatemsg->resultcode.status = + P80211ENUM_msgitem_status_data_ok; + ifstatemsg->resultcode.data = result; + result = 0; + } + break; + case DIDmsg_lnxreq_wlansniff : + WLAN_LOG_DEBUG(2,"Received mlme wlansniff request\n"); + result = prism2mgmt_wlansniff(wlandev, msg); + break; + case DIDmsg_lnxreq_autojoin : + WLAN_LOG_DEBUG(2,"Received mlme autojoin request\n"); + result = prism2mgmt_autojoin(wlandev, msg); + break; + case DIDmsg_p2req_enable : + WLAN_LOG_DEBUG(2,"Received mlme enable request\n"); + result = prism2mgmt_enable(wlandev, msg); + break; + case DIDmsg_lnxreq_commsquality: { + p80211msg_lnxreq_commsquality_t *qualmsg; + + WLAN_LOG_DEBUG(2,"Received commsquality request\n"); + + if (hw->ap) + break; + + qualmsg = (p80211msg_lnxreq_commsquality_t*) msg; + + qualmsg->link.status = P80211ENUM_msgitem_status_data_ok; + qualmsg->level.status = P80211ENUM_msgitem_status_data_ok; + qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok; + + + qualmsg->link.data = hfa384x2host_16(hw->qual.CQ_currBSS); + qualmsg->level.data = hfa384x2host_16(hw->qual.ASL_currBSS); + qualmsg->noise.data = hfa384x2host_16(hw->qual.ANL_currFC); + + break; + } + default: + WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode); + break; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_ifstate +* +* Interface state. This is the primary WLAN interface enable/disable +* handler. Following the driver/load/deviceprobe sequence, this +* function must be called with a state of "enable" before any other +* commands will be accepted. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* A p80211 message resultcode value. +* +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ +UINT32 prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + UINT32 result; + DBFENTER; + + result = P80211ENUM_resultcode_implementation_failure; + + WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n", + wlandev->msdstate, ifstate); + switch (ifstate) + { + case P80211ENUM_ifstate_fwload: + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING; + /* + * Initialize the device+driver sufficiently + * for firmware loading. + */ +#if (WLAN_HOSTIF != WLAN_USB) + result=hfa384x_cmd_initialize(hw); +#else + if ((result=hfa384x_drvr_start(hw))) { + WLAN_LOG_ERROR( + "hfa384x_drvr_start() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } +#endif + wlandev->msdstate = WLAN_MSD_FWLOAD; + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_FWLOAD: + hfa384x_cmd_initialize(hw); + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_RUNNING: + WLAN_LOG_WARNING( + "Cannot enter fwload state from enable state," + "you must disable first.\n"); + result = P80211ENUM_resultcode_invalid_parameters; + break; + case WLAN_MSD_HWFAIL: + default: + /* probe() had a problem or the msdstate contains + * an unrecognized value, there's nothing we can do. + */ + result = P80211ENUM_resultcode_implementation_failure; + break; + } + break; + case P80211ENUM_ifstate_enable: + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + case WLAN_MSD_FWLOAD: + wlandev->msdstate = WLAN_MSD_RUNNING_PENDING; + /* Initialize the device+driver for full + * operation. Note that this might me an FWLOAD to + * to RUNNING transition so we must not do a chip + * or board level reset. Note that on failure, + * the MSD state is set to HWPRESENT because we + * can't make any assumptions about the state + * of the hardware or a previous firmware load. + */ + if ((result=hfa384x_drvr_start(hw))) { + WLAN_LOG_ERROR( + "hfa384x_drvr_start() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } + + if ((result=prism2sta_getcardinfo(wlandev))) { + WLAN_LOG_ERROR( + "prism2sta_getcardinfo() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + hfa384x_drvr_stop(hw); + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } + if ((result=prism2sta_globalsetup(wlandev))) { + WLAN_LOG_ERROR( + "prism2sta_globalsetup() failed," + "result=%d\n", (int)result); + result = + P80211ENUM_resultcode_implementation_failure; + hfa384x_drvr_stop(hw); + wlandev->msdstate = WLAN_MSD_HWPRESENT; + break; + } + wlandev->msdstate = WLAN_MSD_RUNNING; + hw->join_ap = 0; + hw->join_retries = 60; + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_RUNNING: + /* Do nothing, we're already in this state.*/ + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_HWFAIL: + default: + /* probe() had a problem or the msdstate contains + * an unrecognized value, there's nothing we can do. + */ + result = P80211ENUM_resultcode_implementation_failure; + break; + } + break; + case P80211ENUM_ifstate_disable: + switch (wlandev->msdstate) { + case WLAN_MSD_HWPRESENT: + /* Do nothing, we're already in this state.*/ + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_FWLOAD: + case WLAN_MSD_RUNNING: + wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; + /* + * TODO: Shut down the MAC completely. Here a chip + * or board level reset is probably called for. + * After a "disable" _all_ results are lost, even + * those from a fwload. + */ + if (!wlandev->hwremoved) + netif_carrier_off(wlandev->netdev); + + hfa384x_drvr_stop(hw); + + wlandev->macmode = WLAN_MACMODE_NONE; + wlandev->msdstate = WLAN_MSD_HWPRESENT; + result = P80211ENUM_resultcode_success; + break; + case WLAN_MSD_HWFAIL: + default: + /* probe() had a problem or the msdstate contains + * an unrecognized value, there's nothing we can do. + */ + result = P80211ENUM_resultcode_implementation_failure; + break; + } + break; + default: + result = P80211ENUM_resultcode_invalid_parameters; + break; + } + + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_getcardinfo +* +* Collect the NICID, firmware version and any other identifiers +* we'd like to have in host-side data structures. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* Either. +----------------------------------------------------------------*/ +static int prism2sta_getcardinfo(wlandevice_t *wlandev) +{ + int result = 0; + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + UINT16 temp; + UINT8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; + char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1]; + + DBFENTER; + + /* Collect version and compatibility info */ + /* Some are critical, some are not */ + /* NIC identity */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY, + &hw->ident_nic, sizeof(hfa384x_compident_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve NICIDENTITY\n"); + goto failed; + } + + /* get all the nic id fields in host byte order */ + hw->ident_nic.id = hfa384x2host_16(hw->ident_nic.id); + hw->ident_nic.variant = hfa384x2host_16(hw->ident_nic.variant); + hw->ident_nic.major = hfa384x2host_16(hw->ident_nic.major); + hw->ident_nic.minor = hfa384x2host_16(hw->ident_nic.minor); + + WLAN_LOG_INFO( "ident: nic h/w: id=0x%02x %d.%d.%d\n", + hw->ident_nic.id, hw->ident_nic.major, + hw->ident_nic.minor, hw->ident_nic.variant); + + /* Primary f/w identity */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY, + &hw->ident_pri_fw, sizeof(hfa384x_compident_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve PRIIDENTITY\n"); + goto failed; + } + + /* get all the private fw id fields in host byte order */ + hw->ident_pri_fw.id = hfa384x2host_16(hw->ident_pri_fw.id); + hw->ident_pri_fw.variant = hfa384x2host_16(hw->ident_pri_fw.variant); + hw->ident_pri_fw.major = hfa384x2host_16(hw->ident_pri_fw.major); + hw->ident_pri_fw.minor = hfa384x2host_16(hw->ident_pri_fw.minor); + + WLAN_LOG_INFO( "ident: pri f/w: id=0x%02x %d.%d.%d\n", + hw->ident_pri_fw.id, hw->ident_pri_fw.major, + hw->ident_pri_fw.minor, hw->ident_pri_fw.variant); + + /* Station (Secondary?) f/w identity */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY, + &hw->ident_sta_fw, sizeof(hfa384x_compident_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STAIDENTITY\n"); + goto failed; + } + + if (hw->ident_nic.id < 0x8000) { + WLAN_LOG_ERROR("FATAL: Card is not an Intersil Prism2/2.5/3\n"); + result = -1; + goto failed; + } + + /* get all the station fw id fields in host byte order */ + hw->ident_sta_fw.id = hfa384x2host_16(hw->ident_sta_fw.id); + hw->ident_sta_fw.variant = hfa384x2host_16(hw->ident_sta_fw.variant); + hw->ident_sta_fw.major = hfa384x2host_16(hw->ident_sta_fw.major); + hw->ident_sta_fw.minor = hfa384x2host_16(hw->ident_sta_fw.minor); + + /* strip out the 'special' variant bits */ + hw->mm_mods = hw->ident_sta_fw.variant & (BIT14 | BIT15); + hw->ident_sta_fw.variant &= ~((UINT16)(BIT14 | BIT15)); + + if ( hw->ident_sta_fw.id == 0x1f ) { + hw->ap = 0; + WLAN_LOG_INFO( + "ident: sta f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } else { + hw->ap = 1; + WLAN_LOG_INFO( + "ident: ap f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } + + /* Compatibility range, Modem supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE, + &hw->cap_sup_mfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve MFISUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, modem interface supplier + fields in byte order */ + hw->cap_sup_mfi.role = hfa384x2host_16(hw->cap_sup_mfi.role); + hw->cap_sup_mfi.id = hfa384x2host_16(hw->cap_sup_mfi.id); + hw->cap_sup_mfi.variant = hfa384x2host_16(hw->cap_sup_mfi.variant); + hw->cap_sup_mfi.bottom = hfa384x2host_16(hw->cap_sup_mfi.bottom); + hw->cap_sup_mfi.top = hfa384x2host_16(hw->cap_sup_mfi.top); + + WLAN_LOG_INFO( + "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_mfi.role, hw->cap_sup_mfi.id, + hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom, + hw->cap_sup_mfi.top); + + /* Compatibility range, Controller supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE, + &hw->cap_sup_cfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve CFISUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, controller interface supplier + fields in byte order */ + hw->cap_sup_cfi.role = hfa384x2host_16(hw->cap_sup_cfi.role); + hw->cap_sup_cfi.id = hfa384x2host_16(hw->cap_sup_cfi.id); + hw->cap_sup_cfi.variant = hfa384x2host_16(hw->cap_sup_cfi.variant); + hw->cap_sup_cfi.bottom = hfa384x2host_16(hw->cap_sup_cfi.bottom); + hw->cap_sup_cfi.top = hfa384x2host_16(hw->cap_sup_cfi.top); + + WLAN_LOG_INFO( + "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_cfi.role, hw->cap_sup_cfi.id, + hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom, + hw->cap_sup_cfi.top); + + /* Compatibility range, Primary f/w supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE, + &hw->cap_sup_pri, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve PRISUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, primary firmware supplier + fields in byte order */ + hw->cap_sup_pri.role = hfa384x2host_16(hw->cap_sup_pri.role); + hw->cap_sup_pri.id = hfa384x2host_16(hw->cap_sup_pri.id); + hw->cap_sup_pri.variant = hfa384x2host_16(hw->cap_sup_pri.variant); + hw->cap_sup_pri.bottom = hfa384x2host_16(hw->cap_sup_pri.bottom); + hw->cap_sup_pri.top = hfa384x2host_16(hw->cap_sup_pri.top); + + WLAN_LOG_INFO( + "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_pri.role, hw->cap_sup_pri.id, + hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom, + hw->cap_sup_pri.top); + + /* Compatibility range, Station f/w supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE, + &hw->cap_sup_sta, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STASUPRANGE\n"); + goto failed; + } + + /* get all the Compatibility range, station firmware supplier + fields in byte order */ + hw->cap_sup_sta.role = hfa384x2host_16(hw->cap_sup_sta.role); + hw->cap_sup_sta.id = hfa384x2host_16(hw->cap_sup_sta.id); + hw->cap_sup_sta.variant = hfa384x2host_16(hw->cap_sup_sta.variant); + hw->cap_sup_sta.bottom = hfa384x2host_16(hw->cap_sup_sta.bottom); + hw->cap_sup_sta.top = hfa384x2host_16(hw->cap_sup_sta.top); + + if ( hw->cap_sup_sta.id == 0x04 ) { + WLAN_LOG_INFO( + "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_sta.role, hw->cap_sup_sta.id, + hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, + hw->cap_sup_sta.top); + } else { + WLAN_LOG_INFO( + "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_sup_sta.role, hw->cap_sup_sta.id, + hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, + hw->cap_sup_sta.top); + } + + /* Compatibility range, primary f/w actor, CFI supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES, + &hw->cap_act_pri_cfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve PRI_CFIACTRANGES\n"); + goto failed; + } + + /* get all the Compatibility range, primary f/w actor, CFI supplier + fields in byte order */ + hw->cap_act_pri_cfi.role = hfa384x2host_16(hw->cap_act_pri_cfi.role); + hw->cap_act_pri_cfi.id = hfa384x2host_16(hw->cap_act_pri_cfi.id); + hw->cap_act_pri_cfi.variant = hfa384x2host_16(hw->cap_act_pri_cfi.variant); + hw->cap_act_pri_cfi.bottom = hfa384x2host_16(hw->cap_act_pri_cfi.bottom); + hw->cap_act_pri_cfi.top = hfa384x2host_16(hw->cap_act_pri_cfi.top); + + WLAN_LOG_INFO( + "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id, + hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom, + hw->cap_act_pri_cfi.top); + + /* Compatibility range, sta f/w actor, CFI supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES, + &hw->cap_act_sta_cfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STA_CFIACTRANGES\n"); + goto failed; + } + + /* get all the Compatibility range, station f/w actor, CFI supplier + fields in byte order */ + hw->cap_act_sta_cfi.role = hfa384x2host_16(hw->cap_act_sta_cfi.role); + hw->cap_act_sta_cfi.id = hfa384x2host_16(hw->cap_act_sta_cfi.id); + hw->cap_act_sta_cfi.variant = hfa384x2host_16(hw->cap_act_sta_cfi.variant); + hw->cap_act_sta_cfi.bottom = hfa384x2host_16(hw->cap_act_sta_cfi.bottom); + hw->cap_act_sta_cfi.top = hfa384x2host_16(hw->cap_act_sta_cfi.top); + + WLAN_LOG_INFO( + "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id, + hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom, + hw->cap_act_sta_cfi.top); + + /* Compatibility range, sta f/w actor, MFI supplier */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES, + &hw->cap_act_sta_mfi, sizeof(hfa384x_caplevel_t)); + if ( result ) { + WLAN_LOG_ERROR("Failed to retrieve STA_MFIACTRANGES\n"); + goto failed; + } + + /* get all the Compatibility range, station f/w actor, MFI supplier + fields in byte order */ + hw->cap_act_sta_mfi.role = hfa384x2host_16(hw->cap_act_sta_mfi.role); + hw->cap_act_sta_mfi.id = hfa384x2host_16(hw->cap_act_sta_mfi.id); + hw->cap_act_sta_mfi.variant = hfa384x2host_16(hw->cap_act_sta_mfi.variant); + hw->cap_act_sta_mfi.bottom = hfa384x2host_16(hw->cap_act_sta_mfi.bottom); + hw->cap_act_sta_mfi.top = hfa384x2host_16(hw->cap_act_sta_mfi.top); + + WLAN_LOG_INFO( + "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", + hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id, + hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom, + hw->cap_act_sta_mfi.top); + + /* Serial Number */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, + snum, HFA384x_RID_NICSERIALNUMBER_LEN); + if ( !result ) { + wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN, + pstr, sizeof(pstr)); + WLAN_LOG_INFO("Prism2 card SN: %s\n", pstr); + } else { + WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n"); + goto failed; + } + + /* Collect the MAC address */ + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR, + wlandev->netdev->dev_addr, WLAN_ADDR_LEN); + if ( result != 0 ) { + WLAN_LOG_ERROR("Failed to retrieve mac address\n"); + goto failed; + } + + /* short preamble is always implemented */ + wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE; + + /* find out if hardware wep is implemented */ + hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp); + if (temp) + wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP; + + /* get the dBm Scaling constant */ + hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp); + hw->dbmadjust = temp; + + /* Only enable scan by default on newer firmware */ + if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, + hw->ident_sta_fw.variant) < + HFA384x_FIRMWARE_VERSION(1,5,5)) { + wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN; + } + + /* TODO: Set any internally managed config items */ + + goto done; +failed: + WLAN_LOG_ERROR("Failed, result=%d\n", result); +done: + DBFEXIT; + return result; +} + + +/*---------------------------------------------------------------- +* prism2sta_globalsetup +* +* Set any global RIDs that we want to set at device activation. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* 0 success +* >0 f/w reported error +* <0 driver reported error +* +* Side effects: +* +* Call context: +* process thread +----------------------------------------------------------------*/ +static int prism2sta_globalsetup(wlandevice_t *wlandev) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + /* Set the maximum frame size */ + return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, + WLAN_DATA_MAXLEN); +} + +static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev) +{ + int result = 0; + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + UINT16 promisc; + + DBFENTER; + + /* If we're not ready, what's the point? */ + if ( hw->state != HFA384x_STATE_RUNNING ) + goto exit; + + /* If we're an AP, do nothing here */ + if (hw->ap) + goto exit; + + if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 ) + promisc = P80211ENUM_truth_true; + else + promisc = P80211ENUM_truth_false; + + result = hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, promisc); + + /* XXX TODO: configure the multicast list */ + // CLEAR_HW_MULTICAST_LIST + // struct dev_mc_list element = dev->mc_list; + // while (element != null) { + // HW_ADD_MULTICAST_ADDR(element->dmi_addr, dmi_addrlen) + // element = element->next; + // } + + exit: + DBFEXIT; + return result; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_handover +* +* Handles the receipt of a Handover info frame. Should only be present +* in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) +{ + DBFENTER; + WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n"); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_inf_tallies +* +* Handles the receipt of a CommTallies info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + UINT16 *src16; + UINT32 *dst; + UINT32 *src32; + int i; + int cnt; + + DBFENTER; + + /* + ** Determine if these are 16-bit or 32-bit tallies, based on the + ** record length of the info record. + */ + + cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(UINT32); + if (inf->framelen > 22) { + dst = (UINT32 *) &hw->tallies; + src32 = (UINT32 *) &inf->info.commtallies32; + for (i = 0; i < cnt; i++, dst++, src32++) + *dst += hfa384x2host_32(*src32); + } else { + dst = (UINT32 *) &hw->tallies; + src16 = (UINT16 *) &inf->info.commtallies16; + for (i = 0; i < cnt; i++, dst++, src16++) + *dst += hfa384x2host_16(*src16); + } + + DBFEXIT; + + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_scanresults +* +* Handles the receipt of a Scan Results info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_scanresults(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + int nbss; + hfa384x_ScanResult_t *sr = &(inf->info.scanresult); + int i; + hfa384x_JoinRequest_data_t joinreq; + int result; + DBFENTER; + + /* Get the number of results, first in bytes, then in results */ + nbss = (inf->framelen * sizeof(UINT16)) - + sizeof(inf->infotype) - + sizeof(inf->info.scanresult.scanreason); + nbss /= sizeof(hfa384x_ScanResultSub_t); + + /* Print em */ + WLAN_LOG_DEBUG(1,"rx scanresults, reason=%d, nbss=%d:\n", + inf->info.scanresult.scanreason, nbss); + for ( i = 0; i < nbss; i++) { + WLAN_LOG_DEBUG(1, "chid=%d anl=%d sl=%d bcnint=%d\n", + sr->result[i].chid, + sr->result[i].anl, + sr->result[i].sl, + sr->result[i].bcnint); + WLAN_LOG_DEBUG(1, " capinfo=0x%04x proberesp_rate=%d\n", + sr->result[i].capinfo, + sr->result[i].proberesp_rate); + } + /* issue a join request */ + joinreq.channel = sr->result[0].chid; + memcpy( joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN); + result = hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + if (result) { + WLAN_LOG_ERROR("setconfig(joinreq) failed, result=%d\n", result); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_hostscanresults +* +* Handles the receipt of a Scan Results info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + int nbss; + DBFENTER; + + nbss = (inf->framelen - 3) / 32; + WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss); + + if (nbss > 32) + nbss = 32; + + if (hw->scanresults) + kfree(hw->scanresults); + + hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC); + memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t)); + + if (nbss == 0) + nbss = -1; + + /* Notify/wake the sleeping caller. */ + hw->scanflag = nbss; + wake_up_interruptible(&hw->cmdq); + + DBFEXIT; +}; + +/*---------------------------------------------------------------- +* prism2sta_inf_chinforesults +* +* Handles the receipt of a Channel Info Results info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_chinforesults(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + unsigned int i, n; + + DBFENTER; + hw->channel_info.results.scanchannels = + hfa384x2host_16(inf->info.chinforesult.scanchannels); +#if 0 + memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t)); +#endif + + for (i=0, n=0; ichannel_info.results.scanchannels & (1<info.chinforesult.result[n].chid)-1; + hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel]; + chinforesult->chid = channel; + chinforesult->anl = hfa384x2host_16(inf->info.chinforesult.result[n].anl); + chinforesult->pnl = hfa384x2host_16(inf->info.chinforesult.result[n].pnl); + chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active); + WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", + channel+1, + chinforesult->active & + HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise", + chinforesult->anl, chinforesult->pnl, + chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0 + ); + n++; + } + } + atomic_set(&hw->channel_info.done, 2); + + hw->channel_info.count = n; + DBFEXIT; + return; +} + +void prism2sta_processing_defer(struct work_struct *data) +{ + hfa384x_t *hw = container_of(data, struct hfa384x, link_bh); + wlandevice_t *wlandev = hw->wlandev; + hfa384x_bytestr32_t ssid; + int result; + + DBFENTER; + /* First let's process the auth frames */ + { + struct sk_buff *skb; + hfa384x_InfFrame_t *inf; + + while ( (skb = skb_dequeue(&hw->authq)) ) { + inf = (hfa384x_InfFrame_t *) skb->data; + prism2sta_inf_authreq_defer(wlandev, inf); + } + + } + + /* Now let's handle the linkstatus stuff */ + if (hw->link_status == hw->link_status_new) + goto failed; + + hw->link_status = hw->link_status_new; + + switch(hw->link_status) { + case HFA384x_LINK_NOTCONNECTED: + /* I'm currently assuming that this is the initial link + * state. It should only be possible immediately + * following an Enable command. + * Response: + * Block Transmits, Ignore receives of data frames + */ + netif_carrier_off(wlandev->netdev); + + WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n"); + break; + + case HFA384x_LINK_CONNECTED: + /* This one indicates a successful scan/join/auth/assoc. + * When we have the full MLME complement, this event will + * signify successful completion of both mlme_authenticate + * and mlme_associate. State management will get a little + * ugly here. + * Response: + * Indicate authentication and/or association + * Enable Transmits, Receives and pass up data frames + */ + + netif_carrier_on(wlandev->netdev); + + /* If we are joining a specific AP, set our state and reset retries */ + if(hw->join_ap == 1) + hw->join_ap = 2; + hw->join_retries = 60; + + /* Don't call this in monitor mode */ + if ( wlandev->netdev->type == ARPHRD_ETHER ) { + UINT16 portstatus; + + WLAN_LOG_INFO("linkstatus=CONNECTED\n"); + + /* For non-usb devices, we can use the sync versions */ + /* Collect the BSSID, and set state to allow tx */ + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTBSSID, + wlandev->bssid, WLAN_BSSID_LEN); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); + goto failed; + } + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTSSID, + &ssid, sizeof(ssid)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); + goto failed; + } + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid, + (p80211pstrd_t *) &wlandev->ssid); + + /* Collect the port status */ + result = hfa384x_drvr_getconfig16(hw, + HFA384x_RID_PORTSTATUS, &portstatus); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_PORTSTATUS, result); + goto failed; + } + wlandev->macmode = + (portstatus == HFA384x_PSTATUS_CONN_IBSS) ? + WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA; + + /* Get the ball rolling on the comms quality stuff */ + prism2sta_commsqual_defer(&hw->commsqual_bh); + } + break; + + case HFA384x_LINK_DISCONNECTED: + /* This one indicates that our association is gone. We've + * lost connection with the AP and/or been disassociated. + * This indicates that the MAC has completely cleared it's + * associated state. We * should send a deauth indication + * (implying disassoc) up * to the MLME. + * Response: + * Indicate Deauthentication + * Block Transmits, Ignore receives of data frames + */ + if(hw->join_ap == 2) + { + hfa384x_JoinRequest_data_t joinreq; + joinreq = hw->joinreq; + /* Send the join request */ + hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n"); + } else { + if (wlandev->netdev->type == ARPHRD_ETHER) + WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n"); + } + wlandev->macmode = WLAN_MACMODE_NONE; + + netif_carrier_off(wlandev->netdev); + + break; + + case HFA384x_LINK_AP_CHANGE: + /* This one indicates that the MAC has decided to and + * successfully completed a change to another AP. We + * should probably implement a reassociation indication + * in response to this one. I'm thinking that the the + * p80211 layer needs to be notified in case of + * buffering/queueing issues. User mode also needs to be + * notified so that any BSS dependent elements can be + * updated. + * associated state. We * should send a deauth indication + * (implying disassoc) up * to the MLME. + * Response: + * Indicate Reassociation + * Enable Transmits, Receives and pass up data frames + */ + WLAN_LOG_INFO("linkstatus=AP_CHANGE\n"); + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTBSSID, + wlandev->bssid, WLAN_BSSID_LEN); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); + goto failed; + } + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTSSID, + &ssid, sizeof(ssid)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); + goto failed; + } + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid, + (p80211pstrd_t *) &wlandev->ssid); + + + hw->link_status = HFA384x_LINK_CONNECTED; + netif_carrier_on(wlandev->netdev); + + break; + + case HFA384x_LINK_AP_OUTOFRANGE: + /* This one indicates that the MAC has decided that the + * AP is out of range, but hasn't found a better candidate + * so the MAC maintains its "associated" state in case + * we get back in range. We should block transmits and + * receives in this state. Do we need an indication here? + * Probably not since a polling user-mode element would + * get this status from from p2PortStatus(FD40). What about + * p80211? + * Response: + * Block Transmits, Ignore receives of data frames + */ + WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n"); + + netif_carrier_off(wlandev->netdev); + + break; + + case HFA384x_LINK_AP_INRANGE: + /* This one indicates that the MAC has decided that the + * AP is back in range. We continue working with our + * existing association. + * Response: + * Enable Transmits, Receives and pass up data frames + */ + WLAN_LOG_INFO("linkstatus=AP_INRANGE\n"); + + hw->link_status = HFA384x_LINK_CONNECTED; + netif_carrier_on(wlandev->netdev); + + break; + + case HFA384x_LINK_ASSOCFAIL: + /* This one is actually a peer to CONNECTED. We've + * requested a join for a given SSID and optionally BSSID. + * We can use this one to indicate authentication and + * association failures. The trick is going to be + * 1) identifying the failure, and 2) state management. + * Response: + * Disable Transmits, Ignore receives of data frames + */ + if(hw->join_ap && --hw->join_retries > 0) + { + hfa384x_JoinRequest_data_t joinreq; + joinreq = hw->joinreq; + /* Send the join request */ + hfa384x_drvr_setconfig( hw, + HFA384x_RID_JOINREQUEST, + &joinreq, HFA384x_RID_JOINREQUEST_LEN); + WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n"); + } else { + WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n"); + } + + netif_carrier_off(wlandev->netdev); + + break; + + default: + /* This is bad, IO port problems? */ + WLAN_LOG_WARNING( + "unknown linkstatus=0x%02x\n", hw->link_status); + goto failed; + break; + } + + wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED); +#ifdef WIRELESS_EXT + p80211wext_event_associated(wlandev, wlandev->linkstatus); +#endif + + failed: + DBFEXIT; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_linkstatus +* +* Handles the receipt of a Link Status info frame. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_linkstatus(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + DBFENTER; + + hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus); + + schedule_work(&hw->link_bh); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_assocstatus +* +* Handles the receipt of an Association Status info frame. Should +* be present in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_assocstatus(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + hfa384x_AssocStatus_t rec; + int i; + + DBFENTER; + + memcpy(&rec, &inf->info.assocstatus, sizeof(rec)); + rec.assocstatus = hfa384x2host_16(rec.assocstatus); + rec.reason = hfa384x2host_16(rec.reason); + + /* + ** Find the address in the list of authenticated stations. If it wasn't + ** found, then this address has not been previously authenticated and + ** something weird has happened if this is anything other than an + ** "authentication failed" message. If the address was found, then + ** set the "associated" flag for that station, based on whether the + ** station is associating or losing its association. Something weird + ** has also happened if we find the address in the list of authenticated + ** stations but we are getting an "authentication failed" message. + */ + + for (i = 0; i < hw->authlist.cnt; i++) + if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0) + break; + + if (i >= hw->authlist.cnt) { + if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL) + WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n"); + } else { + hw->authlist.assoc[i] = + (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC || + rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC); + + if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL) + WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n"); + } + + DBFEXIT; + + return; +} + +/*---------------------------------------------------------------- +* prism2sta_inf_authreq +* +* Handles the receipt of an Authentication Request info frame. Should +* be present in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +* +----------------------------------------------------------------*/ +static void prism2sta_inf_authreq(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + struct sk_buff *skb; + + DBFENTER; + + skb = dev_alloc_skb(sizeof(*inf)); + if (skb) { + skb_put(skb, sizeof(*inf)); + memcpy(skb->data, inf, sizeof(*inf)); + skb_queue_tail(&hw->authq, skb); + schedule_work(&hw->link_bh); + } + + DBFEXIT; +} + +static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + hfa384x_authenticateStation_data_t rec; + + int i, added, result, cnt; + UINT8 *addr; + + DBFENTER; + + /* + ** Build the AuthenticateStation record. Initialize it for denying + ** authentication. + */ + + memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN); + rec.status = P80211ENUM_status_unspec_failure; + + /* + ** Authenticate based on the access mode. + */ + + switch (hw->accessmode) { + case WLAN_ACCESS_NONE: + + /* + ** Deny all new authentications. However, if a station + ** is ALREADY authenticated, then accept it. + */ + + for (i = 0; i < hw->authlist.cnt; i++) + if (memcmp(rec.address, hw->authlist.addr[i], + WLAN_ADDR_LEN) == 0) { + rec.status = P80211ENUM_status_successful; + break; + } + + break; + + case WLAN_ACCESS_ALL: + + /* + ** Allow all authentications. + */ + + rec.status = P80211ENUM_status_successful; + break; + + case WLAN_ACCESS_ALLOW: + + /* + ** Only allow the authentication if the MAC address + ** is in the list of allowed addresses. + ** + ** Since this is the interrupt handler, we may be here + ** while the access list is in the middle of being + ** updated. Choose the list which is currently okay. + ** See "prism2mib_priv_accessallow()" for details. + */ + + if (hw->allow.modify == 0) { + cnt = hw->allow.cnt; + addr = hw->allow.addr[0]; + } else { + cnt = hw->allow.cnt1; + addr = hw->allow.addr1[0]; + } + + for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN) + if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) { + rec.status = P80211ENUM_status_successful; + break; + } + + break; + + case WLAN_ACCESS_DENY: + + /* + ** Allow the authentication UNLESS the MAC address is + ** in the list of denied addresses. + ** + ** Since this is the interrupt handler, we may be here + ** while the access list is in the middle of being + ** updated. Choose the list which is currently okay. + ** See "prism2mib_priv_accessdeny()" for details. + */ + + if (hw->deny.modify == 0) { + cnt = hw->deny.cnt; + addr = hw->deny.addr[0]; + } else { + cnt = hw->deny.cnt1; + addr = hw->deny.addr1[0]; + } + + rec.status = P80211ENUM_status_successful; + + for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN) + if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) { + rec.status = P80211ENUM_status_unspec_failure; + break; + } + + break; + } + + /* + ** If the authentication is okay, then add the MAC address to the list + ** of authenticated stations. Don't add the address if it is already in + ** the list. (802.11b does not seem to disallow a station from issuing + ** an authentication request when the station is already authenticated. + ** Does this sort of thing ever happen? We might as well do the check + ** just in case.) + */ + + added = 0; + + if (rec.status == P80211ENUM_status_successful) { + for (i = 0; i < hw->authlist.cnt; i++) + if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0) + break; + + if (i >= hw->authlist.cnt) { + if (hw->authlist.cnt >= WLAN_AUTH_MAX) { + rec.status = P80211ENUM_status_ap_full; + } else { + memcpy(hw->authlist.addr[hw->authlist.cnt], + rec.address, WLAN_ADDR_LEN); + hw->authlist.cnt++; + added = 1; + } + } + } + + /* + ** Send back the results of the authentication. If this doesn't work, + ** then make sure to remove the address from the authenticated list if + ** it was added. + */ + + rec.status = host2hfa384x_16(rec.status); + rec.algorithm = inf->info.authreq.algorithm; + + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA, + &rec, sizeof(rec)); + if (result) { + if (added) hw->authlist.cnt--; + WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result); + } + + DBFEXIT; + + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_inf_psusercnt +* +* Handles the receipt of a PowerSaveUserCount info frame. Should +* be present in APs only. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to info frame (contents in hfa384x order) +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +static void prism2sta_inf_psusercnt(wlandevice_t *wlandev, + hfa384x_InfFrame_t *inf) +{ + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; + + DBFENTER; + + hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt); + + DBFEXIT; + + return; +} + +/*---------------------------------------------------------------- +* prism2sta_ev_dtim +* +* Handles the DTIM early warning event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_dtim(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; +#endif + DBFENTER; + WLAN_LOG_DEBUG(3, "DTIM event, currently unhandled.\n"); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_infdrop +* +* Handles the InfDrop event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_infdrop(wlandevice_t *wlandev) +{ +#if 0 + hfa384x_t *hw = (hfa384x_t *)wlandev->priv; +#endif + DBFENTER; + WLAN_LOG_DEBUG(3, "Info frame dropped due to card mem low.\n"); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_info +* +* Handles the Info event. +* +* Arguments: +* wlandev wlan device structure +* inf ptr to a generic info frame +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf) +{ + DBFENTER; + inf->infotype = hfa384x2host_16(inf->infotype); + /* Dispatch */ + switch ( inf->infotype ) { + case HFA384x_IT_HANDOVERADDR: + prism2sta_inf_handover(wlandev, inf); + break; + case HFA384x_IT_COMMTALLIES: + prism2sta_inf_tallies(wlandev, inf); + break; + case HFA384x_IT_HOSTSCANRESULTS: + prism2sta_inf_hostscanresults(wlandev, inf); + break; + case HFA384x_IT_SCANRESULTS: + prism2sta_inf_scanresults(wlandev, inf); + break; + case HFA384x_IT_CHINFORESULTS: + prism2sta_inf_chinforesults(wlandev, inf); + break; + case HFA384x_IT_LINKSTATUS: + prism2sta_inf_linkstatus(wlandev, inf); + break; + case HFA384x_IT_ASSOCSTATUS: + prism2sta_inf_assocstatus(wlandev, inf); + break; + case HFA384x_IT_AUTHREQ: + prism2sta_inf_authreq(wlandev, inf); + break; + case HFA384x_IT_PSUSERCNT: + prism2sta_inf_psusercnt(wlandev, inf); + break; + case HFA384x_IT_KEYIDCHANGED: + WLAN_LOG_WARNING("Unhandled IT_KEYIDCHANGED\n"); + break; + case HFA384x_IT_ASSOCREQ: + WLAN_LOG_WARNING("Unhandled IT_ASSOCREQ\n"); + break; + case HFA384x_IT_MICFAILURE: + WLAN_LOG_WARNING("Unhandled IT_MICFAILURE\n"); + break; + default: + WLAN_LOG_WARNING( + "Unknown info type=0x%02x\n", inf->infotype); + break; + } + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_txexc +* +* Handles the TxExc event. A Transmit Exception event indicates +* that the MAC's TX process was unsuccessful - so the packet did +* not get transmitted. +* +* Arguments: +* wlandev wlan device structure +* status tx frame status word +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status) +{ + DBFENTER; + + WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status); + + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_tx +* +* Handles the Tx event. +* +* Arguments: +* wlandev wlan device structure +* status tx frame status word +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status) +{ + DBFENTER; + WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status); + /* update linux network stats */ + wlandev->linux_stats.tx_packets++; + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2sta_ev_rx +* +* Handles the Rx event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb) +{ + DBFENTER; + + p80211netdev_rx(wlandev, skb); + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2sta_ev_alloc +* +* Handles the Alloc event. +* +* Arguments: +* wlandev wlan device structure +* +* Returns: +* nothing +* +* Side effects: +* +* Call context: +* interrupt +----------------------------------------------------------------*/ +void prism2sta_ev_alloc(wlandevice_t *wlandev) +{ + DBFENTER; + + p80211netdev_wake_queue(wlandev); + + DBFEXIT; + return; +} + +#if (WLAN_HOSTIF == WLAN_PLX || WLAN_HOSTIF == WLAN_PCI) +#ifdef CONFIG_PM +static int prism2sta_suspend_pci(struct pci_dev *pdev, pm_message_t state) +{ + wlandevice_t *wlandev; + + wlandev = (wlandevice_t *) pci_get_drvdata(pdev); + + /* reset hardware */ + if (wlandev) { + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); + p80211_suspend(wlandev); + } + + // call a netif_device_detach(wlandev->netdev) ? + + return 0; +} + +static int prism2sta_resume_pci (struct pci_dev *pdev) +{ + wlandevice_t *wlandev; + + wlandev = (wlandevice_t *) pci_get_drvdata(pdev); + + if (wlandev) { + p80211_resume(wlandev); + prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable); + } + + return 0; +} +#endif +#endif + +/*---------------------------------------------------------------- +* create_wlan +* +* Called at module init time. This creates the wlandevice_t structure +* and initializes it with relevant bits. +* +* Arguments: +* none +* +* Returns: +* the created wlandevice_t structure. +* +* Side effects: +* also allocates the priv/hw structures. +* +* Call context: +* process thread +* +----------------------------------------------------------------*/ +static wlandevice_t *create_wlan(void) +{ + wlandevice_t *wlandev = NULL; + hfa384x_t *hw = NULL; + + /* Alloc our structures */ + wlandev = kmalloc(sizeof(wlandevice_t), GFP_KERNEL); + hw = kmalloc(sizeof(hfa384x_t), GFP_KERNEL); + + if (!wlandev || !hw) { + WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info); + if (wlandev) kfree(wlandev); + if (hw) kfree(hw); + return NULL; + } + + /* Clear all the structs */ + memset(wlandev, 0, sizeof(wlandevice_t)); + memset(hw, 0, sizeof(hfa384x_t)); + + /* Initialize the network device object. */ + wlandev->nsdname = dev_info; + wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; + wlandev->priv = hw; + wlandev->open = prism2sta_open; + wlandev->close = prism2sta_close; + wlandev->reset = prism2sta_reset; +#ifdef CONFIG_PROC_FS + wlandev->nsd_proc_read = prism2sta_proc_read; +#endif + wlandev->txframe = prism2sta_txframe; + wlandev->mlmerequest = prism2sta_mlmerequest; + wlandev->set_multicast_list = prism2sta_setmulticast; + wlandev->tx_timeout = hfa384x_tx_timeout; + + wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | + P80211_NSDCAP_AUTOJOIN; + + /* Initialize the device private data stucture. */ + hw->dot11_desired_bss_type = 1; + + return wlandev; +} + +#ifdef CONFIG_PROC_FS +static int +prism2sta_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data) +{ + char *p = page; + wlandevice_t *wlandev = (wlandevice_t *) data; + hfa384x_t *hw = (hfa384x_t *) wlandev->priv; + + UINT16 hwtype = 0; + + DBFENTER; + if (offset != 0) { + *eof = 1; + goto exit; + } + + // XXX 0x0001 for prism2.5/3, 0x0000 for prism2. + hwtype = BIT0; + +#if (WLAN_HOSTIF != WLAN_USB) + if (hw->isram16) + hwtype |= BIT1; +#endif + +#if (WLAN_HOSTIF == WLAN_PCI) + hwtype |= BIT2; +#endif + +#define PRISM2_CVS_ID "$Id: prism2sta.c 1858 2008-03-24 18:49:31Z pizza $" + + p += sprintf(p, "# %s version %s (%s) '%s'\n\n", + dev_info, + WLAN_RELEASE, WLAN_BUILD_DATE, PRISM2_CVS_ID); + + p += sprintf(p, "# nic h/w: id=0x%02x %d.%d.%d\n", + hw->ident_nic.id, hw->ident_nic.major, + hw->ident_nic.minor, hw->ident_nic.variant); + + p += sprintf(p, "# pri f/w: id=0x%02x %d.%d.%d\n", + hw->ident_pri_fw.id, hw->ident_pri_fw.major, + hw->ident_pri_fw.minor, hw->ident_pri_fw.variant); + + if (hw->ident_sta_fw.id == 0x1f) { + p += sprintf(p, "# sta f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } else { + p += sprintf(p, "# ap f/w: id=0x%02x %d.%d.%d\n", + hw->ident_sta_fw.id, hw->ident_sta_fw.major, + hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); + } + +#if (WLAN_HOSTIF != WLAN_USB) + p += sprintf(p, "# initial nic hw type, needed for SSF ramdl\n"); + p += sprintf(p, "initnichw=%04x\n", hwtype); +#endif + + exit: + DBFEXIT; + return (p - page); +} +#endif + +void prism2sta_commsqual_defer(struct work_struct *data) +{ + hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh); + wlandevice_t *wlandev = hw->wlandev; + hfa384x_bytestr32_t ssid; + int result = 0; + + DBFENTER; + + if (hw->wlandev->hwremoved) + goto done; + + /* we don't care if we're in AP mode */ + if ((wlandev->macmode == WLAN_MACMODE_NONE) || + (wlandev->macmode == WLAN_MACMODE_ESS_AP)) { + goto done; + } + + /* It only makes sense to poll these in non-IBSS */ + if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) { + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY, + &hw->qual, + HFA384x_RID_DBMCOMMSQUALITY_LEN); + + if (result) { + WLAN_LOG_ERROR("error fetching commsqual\n"); + goto done; + } + + // qual.CQ_currBSS; // link + // ASL_currBSS; // level + // qual.ANL_currFC; // noise + + WLAN_LOG_DEBUG(3, "commsqual %d %d %d\n", + hfa384x2host_16(hw->qual.CQ_currBSS), + hfa384x2host_16(hw->qual.ASL_currBSS), + hfa384x2host_16(hw->qual.ANL_currFC)); + } + + /* Lastly, we need to make sure the BSSID didn't change on us */ + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTBSSID, + wlandev->bssid, WLAN_BSSID_LEN); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTBSSID, result); + goto done; + } + + result = hfa384x_drvr_getconfig(hw, + HFA384x_RID_CURRENTSSID, + &ssid, sizeof(ssid)); + if ( result ) { + WLAN_LOG_DEBUG(1, + "getconfig(0x%02x) failed, result = %d\n", + HFA384x_RID_CURRENTSSID, result); + goto done; + } + prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid, + (p80211pstrd_t *) &wlandev->ssid); + + + /* Reschedule timer */ + mod_timer(&hw->commsqual_timer, round_jiffies(jiffies + HZ)); + + done: + DBFEXIT; +} + +void prism2sta_commsqual_timer(unsigned long data) +{ + hfa384x_t *hw = (hfa384x_t *) data; + + DBFENTER; + + schedule_work(&hw->commsqual_bh); + + DBFEXIT; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2mib.c +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2mib.c @@ -0,0 +1,3794 @@ +/* src/prism2/driver/prism2mib.c +* +* Management request for mibset/mibget +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* The functions in this file handle the mibset/mibget management +* functions. +* +* -------------------------------------------------------------------- +*/ + +/*================================================================*/ +/* System Includes */ +#define WLAN_DBVAR prism2_debug + +#include + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#include +#include +#include +#include +#include +#include +#endif + +#if ((WLAN_HOSTIF == WLAN_PLX) || (WLAN_HOSTIF == WLAN_PCI)) +#include +#include +#endif + +#if (WLAN_HOSTIF == WLAN_USB) +#include +#endif + +#include + +/*================================================================*/ +/* Project Includes */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*================================================================*/ +/* Local Constants */ + +#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */ + +/*================================================================*/ +/* Local Types */ + +#define F_AP 0x1 /* MIB is supported on Access Points. */ +#define F_STA 0x2 /* MIB is supported on stations. */ +#define F_READ 0x4 /* MIB may be read. */ +#define F_WRITE 0x8 /* MIB may be written. */ + +typedef struct mibrec +{ + UINT32 did; + UINT16 flag; + UINT16 parm1; + UINT16 parm2; + UINT16 parm3; + int (*func)(struct mibrec *mib, + int isget, + wlandevice_t *wlandev, + hfa384x_t *hw, + p80211msg_dot11req_mibset_t *msg, + void *data); +} mibrec_t; + +/*================================================================*/ +/* Local Function Declarations */ + +static int prism2mib_bytestr2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_bytearea2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_uint32( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_uint32array( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_uint32offset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_truth( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_preamble( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_flag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_appcfinfoflag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_regulatorydomains( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_wepdefaultkey( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_powermanagement( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_privacyinvoked( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_excludeunencrypted( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_fragmentationthreshold( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_operationalrateset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_groupaddress( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_fwid( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_authalg( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_authalgenable( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static int prism2mib_priv( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data); + +static void prism2mib_priv_authlist( +hfa384x_t *hw, +prism2sta_authlist_t *list); + +static void prism2mib_priv_accessmode( +hfa384x_t *hw, +UINT32 mode); + +static void prism2mib_priv_accessallow( +hfa384x_t *hw, +p80211macarray_t *macarray); + +static void prism2mib_priv_accessdeny( +hfa384x_t *hw, +p80211macarray_t *macarray); + +static void prism2mib_priv_deauthenticate( +hfa384x_t *hw, +UINT8 *addr); + +/*================================================================*/ +/* Local Static Definitions */ + +static mibrec_t mibtab[] = { + + /* dot11smt MIB's */ + + { DIDmib_dot11smt_dot11StationConfigTable_dot11StationID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11MediumOccupancyLimit, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPollable, + F_STA | F_READ, + HFA384x_RID_CFPOLLABLE, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPPeriod, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11CFPMaxDuration, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11AuthenticationResponseTimeOut, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11PrivacyOptionImplemented, + F_AP | F_STA | F_READ, + HFA384x_RID_PRIVACYOPTIMP, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11PowerManagementMode, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMENABLED, 0, 0, + prism2mib_powermanagement }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredSSID, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet, + F_STA | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL, 0, 0, + prism2mib_operationalrateset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11OperationalRateSet, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL0, 0, 0, + prism2mib_operationalrateset }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11BeaconPeriod, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPBCNINT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11DTIMPeriod, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNDTIMPER, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11StationConfigTable_dot11AssociationResponseTimeOut, + F_AP | F_STA | F_READ, + HFA384x_RID_PROTOCOLRSPTIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm1, + F_AP | F_STA | F_READ, + 1, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm2, + F_AP | F_STA | F_READ, + 2, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm3, + F_AP | F_STA | F_READ, + 3, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm4, + F_AP | F_STA | F_READ, + 4, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm5, + F_AP | F_STA | F_READ, + 5, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithm6, + F_AP | F_STA | F_READ, + 6, 0, 0, + prism2mib_authalg }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable1, + F_AP | F_STA | F_READ | F_WRITE, + 1, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable2, + F_AP | F_STA | F_READ | F_WRITE, + 2, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable3, + F_AP | F_STA | F_READ | F_WRITE, + 3, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable4, + F_AP | F_STA | F_READ | F_WRITE, + 4, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable5, + F_AP | F_STA | F_READ | F_WRITE, + 5, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11AuthenticationAlgorithmsTable_dot11AuthenticationAlgorithmsEnable6, + F_AP | F_STA | F_READ | F_WRITE, + 6, 0, 0, + prism2mib_authalgenable }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0, + prism2mib_privacyinvoked }, + { DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0, + prism2mib_excludeunencrypted }, + { DIDmib_dot11phy_dot11PhyOperationTable_dot11ShortPreambleEnabled, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSHORTPREAMBLE, 0, 0, + prism2mib_preamble }, + + /* dot11mac MIB's */ + + { DIDmib_dot11mac_dot11OperationTable_dot11MACAddress, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH0, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_SHORTRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_LONGRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH0, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXTXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11OperationTable_dot11MaxReceiveLifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXRXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + { DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32, + F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_groupaddress }, + + /* dot11phy MIB's */ + + { DIDmib_dot11phy_dot11PhyOperationTable_dot11PHYType, + F_AP | F_STA | F_READ, + HFA384x_RID_PHYTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyOperationTable_dot11TempType, + F_AP | F_STA | F_READ, + HFA384x_RID_TEMPTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, + F_STA | F_READ, + HFA384x_RID_CURRENTCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel, + F_AP | F_READ, + HFA384x_RID_CNFOWNCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentCCAMode, + F_AP | F_STA | F_READ, + HFA384x_RID_CCAMODE, 0, 0, + prism2mib_uint32 }, + + /* p2Table MIB's */ + + { DIDmib_p2_p2Table_p2MMTx, + F_AP | F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2EarlyBeacon, + F_AP | F_READ | F_WRITE, + BIT7, 0, 0, + prism2mib_appcfinfoflag }, + { DIDmib_p2_p2Table_p2ReceivedFrameStatistics, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2CommunicationTallies, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2Authenticated, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2Associated, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2PowerSaveUserCount, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2Comment, + F_AP | F_STA | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2AccessMode, + F_AP | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2AccessAllow, + F_AP | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2AccessDeny, + F_AP | F_READ | F_WRITE, + 0, 0, 0, + prism2mib_priv }, + { DIDmib_p2_p2Table_p2ChannelInfoResults, + F_AP | F_READ, + 0, 0, 0, + prism2mib_priv }, + + /* p2Static MIB's */ + + { DIDmib_p2_p2Static_p2CnfPortType, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPORTTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfOwnMACAddress, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfDesiredSSID, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFDESIREDSSID, HFA384x_RID_CNFDESIREDSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2Static_p2CnfOwnChannel, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfOwnSSID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNSSID, HFA384x_RID_CNFOWNSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2Static_p2CnfOwnATIMWindow, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNATIMWIN, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfSystemScale, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSYSSCALE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfMaxDataLength, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFMAXDATALEN, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfWDSAddress, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR, HFA384x_RID_CNFWDSADDR_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfPMEnabled, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMENABLED, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfPMEPS, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMEPS, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfMulticastReceive, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFMULTICASTRX, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfMaxSleepDuration, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFMAXSLEEPDUR, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfPMHoldoverDuration, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPMHOLDDUR, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfOwnName, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNNAME, HFA384x_RID_CNFOWNNAME_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2Static_p2CnfOwnDTIMPeriod, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFOWNDTIMPER, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfWDSAddress1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR1, HFA384x_RID_CNFWDSADDR1_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR2, HFA384x_RID_CNFWDSADDR2_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR3, HFA384x_RID_CNFWDSADDR3_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR4, HFA384x_RID_CNFWDSADDR4_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR5, HFA384x_RID_CNFWDSADDR5_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfWDSAddress6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFWDSADDR6, HFA384x_RID_CNFWDSADDR6_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2Static_p2CnfMulticastPMBuffering, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFMCASTPMBUFF, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKeyID, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey0, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey1, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey2, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPDefaultKey3, + F_AP | F_STA | F_WRITE, + HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0, + prism2mib_wepdefaultkey }, + { DIDmib_p2_p2Static_p2CnfWEPFlags, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWEPFLAGS, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfAuthentication, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFAUTHENTICATION, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfMaxAssociatedStations, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFMAXASSOCSTATIONS, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfTxControl, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFTXCONTROL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfRoamingMode, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFROAMINGMODE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfHostAuthentication, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFHOSTAUTHASSOC, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfRcvCrcError, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFRCVCRCERROR, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfAltRetryCount, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFALTRETRYCNT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfBeaconInterval, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPBCNINT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfMediumOccupancyLimit, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfCFPPeriod, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfCFPMaxDuration, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfCFPFlags, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFAPPCFINFO, HFA384x_RID_CNFAPPCFINFO_LEN, 3, + prism2mib_uint32offset }, + { DIDmib_p2_p2Static_p2CnfSTAPCFInfo, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSTAPCFINFO, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfPriorityQUsage, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFPRIORITYQUSAGE, HFA384x_RID_CNFPRIOQUSAGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2Static_p2CnfTIMCtrl, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFTIMCTRL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfThirty2Tally, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFTHIRTY2TALLY, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfEnhSecurity, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFENHSECURITY, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfShortPreamble, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSHORTPREAMBLE, 0, 0, + prism2mib_preamble }, + { DIDmib_p2_p2Static_p2CnfExcludeLongPreamble, + F_AP | F_READ | F_WRITE, + HFA384x_RID_CNFEXCLONGPREAMBLE, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Static_p2CnfAuthenticationRspTO, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFAUTHRSPTIMEOUT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfBasicRates, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFBASICRATES, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Static_p2CnfSupportedRates, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFSUPPRATES, 0, 0, + prism2mib_uint32 }, + + /* p2Dynamic MIB's */ + + { DIDmib_p2_p2Dynamic_p2CreateIBSS, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CREATEIBSS, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold, + F_STA | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl, + F_STA | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2PromiscuousMode, + F_STA | F_READ | F_WRITE, + HFA384x_RID_PROMISCMODE, 0, 0, + prism2mib_truth }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold0, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH0, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH1, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH2, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH3, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH4, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH5, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2FragmentationThreshold6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_FRAGTHRESH6, 0, 0, + prism2mib_fragmentationthreshold }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold0, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH0, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH1, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH2, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH3, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH4, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH5, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2RTSThreshold6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_RTSTHRESH6, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl0, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL0, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl1, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL1, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl2, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL2, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl3, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL3, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl4, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL4, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl5, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL5, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Dynamic_p2TxRateControl6, + F_AP | F_READ | F_WRITE, + HFA384x_RID_TXRATECNTL6, 0, 0, + prism2mib_uint32 }, + + /* p2Behavior MIB's */ + + { DIDmib_p2_p2Behavior_p2TickTime, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_ITICKTIME, 0, 0, + prism2mib_uint32 }, + + /* p2NIC MIB's */ + + { DIDmib_p2_p2NIC_p2MaxLoadTime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXLOADTIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2NIC_p2DLBufferPage, + F_AP | F_STA | F_READ, + HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2NIC_p2DLBufferOffset, + F_AP | F_STA | F_READ, + HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2NIC_p2DLBufferLength, + F_AP | F_STA | F_READ, + HFA384x_RID_DOWNLOADBUFFER, HFA384x_RID_DOWNLOADBUFFER_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2NIC_p2PRIIdentity, + F_AP | F_STA | F_READ, + HFA384x_RID_PRIIDENTITY, HFA384x_RID_PRIIDENTITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2PRISupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_PRISUPRANGE, HFA384x_RID_PRISUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2CFIActRanges, + F_AP | F_STA | F_READ, + HFA384x_RID_PRI_CFIACTRANGES, HFA384x_RID_CFIACTRANGES_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2BuildSequence, + F_AP | F_STA | F_READ, + HFA384x_RID_BUILDSEQ, HFA384x_RID_BUILDSEQ_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2PrimaryFWID, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_fwid }, + { DIDmib_p2_p2NIC_p2SecondaryFWID, + F_AP | F_STA | F_READ, + 0, 0, 0, + prism2mib_fwid }, + { DIDmib_p2_p2NIC_p2TertiaryFWID, + F_AP | F_READ, + 0, 0, 0, + prism2mib_fwid }, + { DIDmib_p2_p2NIC_p2NICSerialNumber, + F_AP | F_STA | F_READ, + HFA384x_RID_NICSERIALNUMBER, HFA384x_RID_NICSERIALNUMBER_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2NIC_p2NICIdentity, + F_AP | F_STA | F_READ, + HFA384x_RID_NICIDENTITY, HFA384x_RID_NICIDENTITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2MFISupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_MFISUPRANGE, HFA384x_RID_MFISUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2CFISupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_CFISUPRANGE, HFA384x_RID_CFISUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2ChannelList, + F_AP | F_STA | F_READ, + HFA384x_RID_CHANNELLIST, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2NIC_p2RegulatoryDomains, + F_AP | F_STA | F_READ, + HFA384x_RID_REGULATORYDOMAINS, HFA384x_RID_REGULATORYDOMAINS_LEN, 0, + prism2mib_regulatorydomains }, + { DIDmib_p2_p2NIC_p2TempType, + F_AP | F_STA | F_READ, + HFA384x_RID_TEMPTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2NIC_p2STAIdentity, + F_AP | F_STA | F_READ, + HFA384x_RID_STAIDENTITY, HFA384x_RID_STAIDENTITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2STASupRange, + F_AP | F_STA | F_READ, + HFA384x_RID_STASUPRANGE, HFA384x_RID_STASUPRANGE_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2MFIActRanges, + F_AP | F_STA | F_READ, + HFA384x_RID_STA_MFIACTRANGES, HFA384x_RID_MFIACTRANGES_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2NIC_p2STACFIActRanges, + F_AP | F_STA | F_READ, + HFA384x_RID_STA_CFIACTRANGES, HFA384x_RID_CFIACTRANGES2_LEN, 0, + prism2mib_uint32array }, + + /* p2MAC MIB's */ + + { DIDmib_p2_p2MAC_p2PortStatus, + F_STA | F_READ, + HFA384x_RID_PORTSTATUS, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentSSID, + F_STA | F_READ, + HFA384x_RID_CURRENTSSID, HFA384x_RID_CURRENTSSID_LEN, 0, + prism2mib_bytestr2pstr }, + { DIDmib_p2_p2MAC_p2CurrentBSSID, + F_STA | F_READ, + HFA384x_RID_CURRENTBSSID, HFA384x_RID_CURRENTBSSID_LEN, 0, + prism2mib_bytearea2pstr }, + { DIDmib_p2_p2MAC_p2CommsQuality, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2CommsQualityCQ, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2CommsQualityASL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2CommsQualityANL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2dbmCommsQuality, + F_STA | F_READ, + HFA384x_RID_DBMCOMMSQUALITY, HFA384x_RID_DBMCOMMSQUALITY_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2dbmCommsQualityCQ, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 0, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2dbmCommsQualityASL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 1, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2dbmCommsQualityANL, + F_STA | F_READ, + HFA384x_RID_COMMSQUALITY, HFA384x_RID_COMMSQUALITY_LEN, 2, + prism2mib_uint32offset }, + { DIDmib_p2_p2MAC_p2CurrentTxRate, + F_STA | F_READ, + HFA384x_RID_CURRENTTXRATE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentBeaconInterval, + F_AP | F_STA | F_READ, + HFA384x_RID_CURRENTBCNINT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2StaCurrentScaleThresholds, + F_STA | F_READ, + HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_STACURSCALETHRESH_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2APCurrentScaleThresholds, + F_AP | F_READ, + HFA384x_RID_CURRENTSCALETHRESH, HFA384x_RID_APCURSCALETHRESH_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2ProtocolRspTime, + F_AP | F_STA | F_READ, + HFA384x_RID_PROTOCOLRSPTIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2ShortRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_SHORTRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2LongRetryLimit, + F_AP | F_STA | F_READ, + HFA384x_RID_LONGRETRYLIMIT, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2MaxTransmitLifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXTXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2MaxReceiveLifetime, + F_AP | F_STA | F_READ, + HFA384x_RID_MAXRXLIFETIME, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CFPollable, + F_STA | F_READ, + HFA384x_RID_CFPOLLABLE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2AuthenticationAlgorithms, + F_AP | F_STA | F_READ, + HFA384x_RID_AUTHALGORITHMS, HFA384x_RID_AUTHALGORITHMS_LEN, 0, + prism2mib_uint32array }, + { DIDmib_p2_p2MAC_p2PrivacyOptionImplemented, + F_AP | F_STA | F_READ, + HFA384x_RID_PRIVACYOPTIMP, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate1, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE1, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate2, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE2, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate3, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE3, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate4, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE4, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate5, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE5, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2CurrentTxRate6, + F_AP | F_READ, + HFA384x_RID_CURRENTTXRATE6, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2MAC_p2OwnMACAddress, + F_AP | F_READ, + HFA384x_RID_OWNMACADDRESS, HFA384x_RID_OWNMACADDRESS_LEN, 0, + prism2mib_bytearea2pstr }, + + /* p2Modem MIB's */ + + { DIDmib_p2_p2Modem_p2PHYType, + F_AP | F_STA | F_READ, + HFA384x_RID_PHYTYPE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2CurrentChannel, + F_AP | F_STA | F_READ, + HFA384x_RID_CURRENTCHANNEL, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2CurrentPowerState, + F_AP | F_STA | F_READ, + HFA384x_RID_CURRENTPOWERSTATE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2CCAMode, + F_AP | F_STA | F_READ, + HFA384x_RID_CCAMODE, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2TxPowerMax, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_TXPOWERMAX, 0, 0, + prism2mib_uint32 }, + { DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel, + F_AP | F_STA | F_READ | F_WRITE, + HFA384x_RID_TXPOWERMAX, 0, 0, + prism2mib_uint32 }, + { DIDmib_p2_p2Modem_p2SupportedDataRates, + F_AP | F_STA | F_READ, + HFA384x_RID_SUPPORTEDDATARATES, HFA384x_RID_SUPPORTEDDATARATES_LEN, 0, + prism2mib_bytestr2pstr }, + + /* And finally, lnx mibs */ + { DIDmib_lnx_lnxConfigTable_lnxRSNAIE, + F_STA | F_READ | F_WRITE, + HFA384x_RID_CNFWPADATA, 0, 0, + prism2mib_priv }, + { 0, 0, 0, 0, 0, NULL}}; + +/*---------------------------------------------------------------- +These MIB's are not supported at this time: + +DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityPresent +DIDmib_dot11phy_dot11PhyOperationTable_dot11ChannelAgilityEnabled +DIDmib_dot11phy_dot11PhyDSSSTable_dot11PBCCOptionImplemented +DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportIndex +DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxIndex +DIDmib_dot11phy_dot11SupportedDataRatesTxTable_dot11SupportedDataRatesTxValue +DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxIndex +DIDmib_dot11phy_dot11SupportedDataRatesRxTable_dot11SupportedDataRatesRxValue + +DIDmib_dot11phy_dot11RegDomainsSupportedTable_dot11RegDomainsSupportValue +TODO: need to investigate why wlan has this as enumerated and Prism2 has this + as btye str. + +DIDmib_dot11phy_dot11PhyDSSSTable_dot11ShortPreambleOptionImplemented +TODO: Find out the firmware version number(s) for identifying + whether the firmware is capable of short preamble. TRUE or FALSE + will be returned based on the version of the firmware. + +WEP Key mappings aren't supported in the f/w. +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingIndex +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingAddress +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingWEPOn +DIDmib_dot11smt_dot11WEPKeyMappingsTable_dot11WEPKeyMappingValue +DIDmib_dot11smt_dot11PrivacyTable_dot11WEPKeyMappingLength + +TODO: implement counters. +DIDmib_dot11smt_dot11PrivacyTable_dot11WEPICVErrorCount +DIDmib_dot11smt_dot11PrivacyTable_dot11WEPExcludedCount +DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFragmentCount +DIDmib_dot11mac_dot11CountersTable_dot11MulticastTransmittedFrameCount +DIDmib_dot11mac_dot11CountersTable_dot11FailedCount +DIDmib_dot11mac_dot11CountersTable_dot11RetryCount +DIDmib_dot11mac_dot11CountersTable_dot11MultipleRetryCount +DIDmib_dot11mac_dot11CountersTable_dot11FrameDuplicateCount +DIDmib_dot11mac_dot11CountersTable_dot11RTSSuccessCount +DIDmib_dot11mac_dot11CountersTable_dot11RTSFailureCount +DIDmib_dot11mac_dot11CountersTable_dot11ACKFailureCount +DIDmib_dot11mac_dot11CountersTable_dot11ReceivedFragmentCount +DIDmib_dot11mac_dot11CountersTable_dot11MulticastReceivedFrameCount +DIDmib_dot11mac_dot11CountersTable_dot11FCSErrorCount +DIDmib_dot11mac_dot11CountersTable_dot11TransmittedFrameCount +DIDmib_dot11mac_dot11CountersTable_dot11WEPUndecryptableCount + +TODO: implement sane values for these. +DIDmib_dot11mac_dot11OperationTable_dot11ManufacturerID +DIDmib_dot11mac_dot11OperationTable_dot11ProductID + +Not too worried about these at the moment. +DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentTxAntenna +DIDmib_dot11phy_dot11PhyAntennaTable_dot11DiversitySupport +DIDmib_dot11phy_dot11PhyAntennaTable_dot11CurrentRxAntenna +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11NumberSupportedPowerLevels +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8 +DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel + +Ummm, FH and IR don't apply +DIDmib_dot11phy_dot11PhyFHSSTable_dot11HopTime +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentChannelNumber +DIDmib_dot11phy_dot11PhyFHSSTable_dot11MaxDwellTime +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentDwellTime +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentSet +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentPattern +DIDmib_dot11phy_dot11PhyFHSSTable_dot11CurrentIndex +DIDmib_dot11phy_dot11PhyDSSSTable_dot11CCAModeSupported +DIDmib_dot11phy_dot11PhyDSSSTable_dot11EDThreshold +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMax +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMax +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogTimerMin +DIDmib_dot11phy_dot11PhyIRTable_dot11CCAWatchdogCountMin + +We just don't have enough antennas right now to worry about this. +DIDmib_dot11phy_dot11AntennasListTable_dot11AntennaListIndex +DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedTxAntenna +DIDmib_dot11phy_dot11AntennasListTable_dot11SupportedRxAntenna +DIDmib_dot11phy_dot11AntennasListTable_dot11DiversitySelectionRx + +------------------------------------------------------------------*/ + +/*================================================================*/ +/* Function Definitions */ + +/*---------------------------------------------------------------- +* prism2mgmt_mibset_mibget +* +* Set the value of a mib item. +* +* Arguments: +* wlandev wlan device structure +* msgp ptr to msg buffer +* +* Returns: +* 0 success and done +* <0 success, but we're waiting for something to finish. +* >0 an error occurred while handling the message. +* Side effects: +* +* Call context: +* process thread (usually) +* interrupt +----------------------------------------------------------------*/ + +int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp) +{ + hfa384x_t *hw = wlandev->priv; + int result, isget; + mibrec_t *mib; + UINT16 which; + + p80211msg_dot11req_mibset_t *msg = msgp; + p80211itemd_t *mibitem; + + DBFENTER; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + msg->resultcode.data = P80211ENUM_resultcode_success; + + /* + ** Determine if this is an Access Point or a station. + */ + + which = hw->ap ? F_AP : F_STA; + + /* + ** Find the MIB in the MIB table. Note that a MIB may be in the + ** table twice...once for an AP and once for a station. Make sure + ** to get the correct one. Note that DID=0 marks the end of the + ** MIB table. + */ + + mibitem = (p80211itemd_t *) msg->mibattribute.data; + + for (mib = mibtab; mib->did != 0; mib++) + if (mib->did == mibitem->did && (mib->flag & which)) + break; + + if (mib->did == 0) { + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + goto done; + } + + /* + ** Determine if this is a "mibget" or a "mibset". If this is a + ** "mibget", then make sure that the MIB may be read. Otherwise, + ** this is a "mibset" so make make sure that the MIB may be written. + */ + + isget = (msg->msgcode == DIDmsg_dot11req_mibget); + + if (isget) { + if (!(mib->flag & F_READ)) { + msg->resultcode.data = + P80211ENUM_resultcode_cant_get_writeonly_mib; + goto done; + } + } else { + if (!(mib->flag & F_WRITE)) { + msg->resultcode.data = + P80211ENUM_resultcode_cant_set_readonly_mib; + goto done; + } + } + + /* + ** Execute the MIB function. If things worked okay, then make + ** sure that the MIB function also worked okay. If so, and this + ** is a "mibget", then the status value must be set for both the + ** "mibattribute" parameter and the mib item within the data + ** portion of the "mibattribute". + */ + + result = mib->func(mib, isget, wlandev, hw, msg, + (void *) mibitem->data); + + if (msg->resultcode.data == P80211ENUM_resultcode_success) { + if (result != 0) { + WLAN_LOG_DEBUG(1, "get/set failure, result=%d\n", + result); + msg->resultcode.data = + P80211ENUM_resultcode_implementation_failure; + } else { + if (isget) { + msg->mibattribute.status = + P80211ENUM_msgitem_status_data_ok; + mibitem->status = + P80211ENUM_msgitem_status_data_ok; + } + } + } + +done: + DBFEXIT; + + return(0); +} + +/*---------------------------------------------------------------- +* prism2mib_bytestr2pstr +* +* Get/set pstr data to/from a byte string. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_bytestr2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2); + prism2mgmt_bytestr2pstr(p2bytestr, pstr); + } else { + memset(bytebuf, 0, mib->parm2); + prism2mgmt_pstr2bytestr(p2bytestr, pstr); + result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_bytearea2pstr +* +* Get/set pstr data to/from a byte area. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_bytearea2pstr( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2); + prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2); + } else { + memset(bytebuf, 0, mib->parm2); + prism2mgmt_pstr2bytearea(bytebuf, pstr); + result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_uint32 +* +* Get/set uint32 data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_uint32( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + *uint32 = *wordbuf; + /* [MSM] Removed, getconfig16 returns the value in host order. + * prism2mgmt_prism2int2p80211int(wordbuf, uint32); + */ + } else { + /* [MSM] Removed, setconfig16 expects host order. + * prism2mgmt_p80211int2prism2int(wordbuf, uint32); + */ + *wordbuf = *uint32; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_uint32array +* +* Get/set an array of uint32 data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_uint32array( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32 *) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + int i, cnt; + + DBFENTER; + + cnt = mib->parm2 / sizeof(UINT16); + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2); + for (i = 0; i < cnt; i++) + prism2mgmt_prism2int2p80211int(wordbuf+i, uint32+i); + } else { + for (i = 0; i < cnt; i++) + prism2mgmt_p80211int2prism2int(wordbuf+i, uint32+i); + result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_uint32offset +* +* Get/set a single element in an array of uint32 data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Element index. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_uint32offset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + UINT16 cnt; + + DBFENTER; + + cnt = mib->parm2 / sizeof(UINT16); + + result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2); + if (result == 0) { + if (isget) { + if (mib->parm3 < cnt) + prism2mgmt_prism2int2p80211int(wordbuf+mib->parm3, uint32); + else + *uint32 = 0; + } else { + if (mib->parm3 < cnt) { + prism2mgmt_p80211int2prism2int(wordbuf+mib->parm3, uint32); + result = hfa384x_drvr_setconfig(hw, mib->parm1, wordbuf, mib->parm2); + } + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_truth +* +* Get/set truth data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_truth( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + *uint32 = (*wordbuf) ? + P80211ENUM_truth_true : P80211ENUM_truth_false; + } else { + *wordbuf = ((*uint32) == P80211ENUM_truth_true) ? 1 : 0; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_flag +* +* Get/set a flag. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Bit to get/set. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_flag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + UINT32 flags; + + DBFENTER; + + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + if (result == 0) { + /* [MSM] Removed, getconfig16 returns the value in host order. + * prism2mgmt_prism2int2p80211int(wordbuf, &flags); + */ + flags = *wordbuf; + if (isget) { + *uint32 = (flags & mib->parm2) ? + P80211ENUM_truth_true : P80211ENUM_truth_false; + } else { + if ((*uint32) == P80211ENUM_truth_true) + flags |= mib->parm2; + else + flags &= ~mib->parm2; + /* [MSM] Removed, setconfig16 expects host order. + * prism2mgmt_p80211int2prism2int(wordbuf, &flags); + */ + *wordbuf = flags; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_appcfinfoflag +* +* Get/set a single flag in the APPCFINFO record. +* +* MIB record parameters: +* parm1 Bit to get/set. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_appcfinfoflag( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + UINT16 word; + + DBFENTER; + + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFAPPCFINFO, + bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN); + if (result == 0) { + if (isget) { + *uint32 = (hfa384x2host_16(wordbuf[3]) & mib->parm1) ? + P80211ENUM_truth_true : P80211ENUM_truth_false; + } else { + word = hfa384x2host_16(wordbuf[3]); + word = ((*uint32) == P80211ENUM_truth_true) ? + (word | mib->parm1) : (word & ~mib->parm1); + wordbuf[3] = host2hfa384x_16(word); + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFAPPCFINFO, + bytebuf, HFA384x_RID_CNFAPPCFINFO_LEN); + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_regulatorydomains +* +* Get regulatory domain data. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_regulatorydomains( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 cnt; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + result = 0; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, mib->parm1, wordbuf, mib->parm2); + prism2mgmt_prism2int2p80211int(wordbuf, &cnt); + pstr->len = (UINT8) cnt; + memcpy(pstr->data, &wordbuf[1], pstr->len); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_wepdefaultkey +* +* Get/set WEP default keys. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Number of bytes of RID data. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_wepdefaultkey( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 len; + + DBFENTER; + + if (isget) { + result = 0; /* Should never happen. */ + } else { + len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN : + HFA384x_RID_CNFWEPDEFAULTKEY_LEN; + memset(bytebuf, 0, len); + prism2mgmt_pstr2bytearea(bytebuf, pstr); + result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_powermanagement +* +* Get/set 802.11 power management value. Note that this is defined differently +* by 802.11 and Prism2: +* +* Meaning 802.11 Prism2 +* active 1 false +* powersave 2 true +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_powermanagement( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT32 value; + + DBFENTER; + + if (isget) { + result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value); + *uint32 = (value == 0) ? 1 : 2; + } else { + value = ((*uint32) == 1) ? 0 : 1; + result = prism2mib_uint32(mib, isget, wlandev, hw, msg, &value); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_preamble +* +* Get/set Prism2 short preamble +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_preamble( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + *uint32 = *wordbuf; + } else { + *wordbuf = *uint32; + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_privacyinvoked +* +* Get/set the dot11PrivacyInvoked value. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Bit value for PrivacyInvoked flag. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_privacyinvoked( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + + DBFENTER; + + if (wlandev->hostwep & HOSTWEP_DECRYPT) { + if (wlandev->hostwep & HOSTWEP_DECRYPT) + mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT; + if (wlandev->hostwep & HOSTWEP_ENCRYPT) + mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT; + } + + result = prism2mib_flag(mib, isget, wlandev, hw, msg, data); + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_excludeunencrypted +* +* Get/set the dot11ExcludeUnencrypted value. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Bit value for ExcludeUnencrypted flag. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_excludeunencrypted( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + + DBFENTER; + + result = prism2mib_flag(mib, isget, wlandev, hw, msg, data); + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_fragmentationthreshold +* +* Get/set the fragmentation threshold. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_fragmentationthreshold( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + + DBFENTER; + + if (!isget) + if ((*uint32) % 2) { + WLAN_LOG_WARNING("Attempt to set odd number " + "FragmentationThreshold\n"); + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + return(0); + } + + result = prism2mib_uint32(mib, isget, wlandev, hw, msg, data); + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_operationalrateset +* +* Get/set the operational rate set. +* +* MIB record parameters: +* parm1 Prism2 RID value. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_operationalrateset( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t *) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 *wordbuf = (UINT16*) bytebuf; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); + prism2mgmt_get_oprateset(wordbuf, pstr); + } else { + prism2mgmt_set_oprateset(wordbuf, pstr); + result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); + result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, *wordbuf); + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_groupaddress +* +* Get/set the dot11GroupAddressesTable. +* +* MIB record parameters: +* parm1 Not used. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_groupaddress( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t *) data; + UINT8 bytebuf[MIB_TMP_MAXLEN]; + UINT16 len; + + DBFENTER; + + /* TODO: fix this. f/w doesn't support mcast filters */ + + if (isget) { + prism2mgmt_get_grpaddr(mib->did, pstr, hw); + return(0); + } + + result = prism2mgmt_set_grpaddr(mib->did, bytebuf, pstr, hw); + if (result != 0) { + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + return(result); + } + + if (hw->dot11_grpcnt <= MAX_PRISM2_GRP_ADDR) { + len = hw->dot11_grpcnt * WLAN_ADDR_LEN; + memcpy(bytebuf, hw->dot11_grp_addr[0], len); + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR, bytebuf, len); + + /* + ** Turn off promiscuous mode if count is equal to MAX. We may + ** have been at a higher count in promiscuous mode and need to + ** turn it off. + */ + + /* but only if we're not already in promisc mode. :) */ + if ((hw->dot11_grpcnt == MAX_PRISM2_GRP_ADDR) && + !( wlandev->netdev->flags & IFF_PROMISC)) { + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_PROMISCMODE, 0); + } + } else { + + /* + ** Clear group addresses in card and set to promiscuous mode. + */ + + memset(bytebuf, 0, sizeof(bytebuf)); + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_GROUPADDR, + bytebuf, 0); + if (result == 0) { + result = hfa384x_drvr_setconfig16(hw, + HFA384x_RID_PROMISCMODE, 1); + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_fwid +* +* Get the firmware ID. +* +* MIB record parameters: +* parm1 Not used. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_fwid( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + p80211pstrd_t *pstr = (p80211pstrd_t *) data; + hfa384x_FWID_t fwid; + + DBFENTER; + + if (isget) { + result = hfa384x_drvr_getconfig(hw, HFA384x_RID_FWID, + &fwid, HFA384x_RID_FWID_LEN); + if (mib->did == DIDmib_p2_p2NIC_p2PrimaryFWID) { + fwid.primary[HFA384x_FWID_LEN - 1] = '\0'; + pstr->len = strlen(fwid.primary); + memcpy(pstr->data, fwid.primary, pstr->len); + } else { + fwid.secondary[HFA384x_FWID_LEN - 1] = '\0'; + pstr->len = strlen(fwid.secondary); + memcpy(pstr->data, fwid.secondary, pstr->len); + } + } else + result = 0; /* Should never happen. */ + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_authalg +* +* Get values from the AuhtenticationAlgorithmsTable. +* +* MIB record parameters: +* parm1 Table index (1-6). +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_authalg( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + UINT32 *uint32 = (UINT32*) data; + + DBFENTER; + + /* MSM: pkx supplied code that code queries RID FD4D....but the f/w's + * results are bogus. Therefore, we have to simulate the appropriate + * results here in the driver based on our knowledge of existing MAC + * features. That's the whole point behind this ugly function. + */ + + if (isget) { + msg->resultcode.data = P80211ENUM_resultcode_success; + switch (mib->parm1) { + case 1: /* Open System */ + *uint32 = P80211ENUM_authalg_opensystem; + break; + case 2: /* SharedKey */ + *uint32 = P80211ENUM_authalg_sharedkey; + break; + default: + *uint32 = 0; + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + break; + } + } + + DBFEXIT; + return(0); +} + +/*---------------------------------------------------------------- +* prism2mib_authalgenable +* +* Get/set the enable values from the AuhtenticationAlgorithmsTable. +* +* MIB record parameters: +* parm1 Table index (1-6). +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_authalgenable( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + int result; + UINT32 *uint32 = (UINT32*) data; + + int index; + UINT16 cnf_auth; + UINT16 mask; + + DBFENTER; + + index = mib->parm1 - 1; + + result = hfa384x_drvr_getconfig16( hw, + HFA384x_RID_CNFAUTHENTICATION, &cnf_auth); + WLAN_LOG_DEBUG(2,"cnfAuthentication0=%d, index=%d\n", cnf_auth, index); + + if (isget) { + if ( index == 0 || index == 1 ) { + *uint32 = (cnf_auth & (1<resultcode.data = P80211ENUM_resultcode_not_supported; + } + } else { + if ( index == 0 || index == 1 ) { + mask = 1 << index; + if (*uint32==P80211ENUM_truth_true ) { + cnf_auth |= mask; + } else { + cnf_auth &= ~mask; + } + result = hfa384x_drvr_setconfig16( hw, + HFA384x_RID_CNFAUTHENTICATION, cnf_auth); + WLAN_LOG_DEBUG(2,"cnfAuthentication:=%d\n", cnf_auth); + if ( result ) { + WLAN_LOG_DEBUG(1,"Unable to set p2cnfAuthentication to %d\n", cnf_auth); + msg->resultcode.data = P80211ENUM_resultcode_implementation_failure; + } + } else { + msg->resultcode.data = P80211ENUM_resultcode_not_supported; + } + } + + DBFEXIT; + return(result); +} + +/*---------------------------------------------------------------- +* prism2mib_priv +* +* Get/set values in the "priv" data structure. +* +* MIB record parameters: +* parm1 Not used. +* parm2 Not used. +* parm3 Not used. +* +* Arguments: +* mib MIB record. +* isget MIBGET/MIBSET flag. +* wlandev wlan device structure. +* priv "priv" structure. +* hw "hw" structure. +* msg Message structure. +* data Data buffer. +* +* Returns: +* 0 - Success. +* ~0 - Error. +* +----------------------------------------------------------------*/ + +static int prism2mib_priv( +mibrec_t *mib, +int isget, +wlandevice_t *wlandev, +hfa384x_t *hw, +p80211msg_dot11req_mibset_t *msg, +void *data) +{ + UINT32 *uint32 = (UINT32*) data; + p80211pstrd_t *pstr = (p80211pstrd_t*) data; + p80211macarray_t *macarray = (p80211macarray_t *) data; + + int i, cnt, result, done; + + DBFENTER; + + switch (mib->did) { + case DIDmib_p2_p2Table_p2ReceivedFrameStatistics: + + /* + ** Note: The values in this record are changed by the + ** interrupt handler and therefore cannot be guaranteed + ** to be stable while they are being copied. However, + ** the interrupt handler will take priority over this + ** code. Hence, if the same values are copied twice, + ** then we are ensured that the values have not been + ** changed. If they have, then just try again. Don't + ** try more than 10 times...if we still haven't got it, + ** then the values we do have are probably good enough. + ** This scheme for copying values is used in order to + ** prevent having to block the interrupt handler while + ** we copy the values. + */ + + if (isget) { + UINT8 test[sizeof(wlandev->rx)]; + for (i = 0; i < 10; i++) { + memcpy(data, &wlandev->rx, sizeof(wlandev->rx)); + memcpy(test, &wlandev->rx, sizeof(wlandev->rx)); + if (memcmp(data, test, sizeof(wlandev->rx)) == 0) break; + } + } + break; + + case DIDmib_p2_p2Table_p2CommunicationTallies: + + /* + ** Note: The values in this record are changed by the + ** interrupt handler and therefore cannot be guaranteed + ** to be stable while they are being copied. See the + ** note above about copying values. + */ + + if (isget) { + UINT8 test[sizeof(hw->tallies)]; + result = hfa384x_drvr_commtallies(hw); + + /* ?????? We need to wait a bit here for the */ + /* tallies to get updated. ?????? */ + /* MSM: TODO: The right way to do this is to + * add a "commtallie" wait queue to the + * priv structure that gets run every time + * we receive a commtally info frame. + * This process would sleep on that + * queue and get awakened when the + * the requested info frame arrives. + * Don't have time to do and test this + * right now. + */ + + /* Ugh, this is nasty. */ + for (i = 0; i < 10; i++) { + memcpy(data, + &hw->tallies, + sizeof(hw->tallies)); + memcpy(test, + &hw->tallies, + sizeof(hw->tallies)); + if ( memcmp(data, + test, + sizeof(hw->tallies)) == 0) + break; + } + } + + break; + + case DIDmib_p2_p2Table_p2Authenticated: + + if (isget) { + prism2sta_authlist_t old; + prism2mib_priv_authlist(hw, &old); + + macarray->cnt = 0; + for (i = 0; i < old.cnt; i++) { + if (!old.assoc[i]) { + memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN); + macarray->cnt++; + } + } + } + + break; + + case DIDmib_p2_p2Table_p2Associated: + + if (isget) { + prism2sta_authlist_t old; + prism2mib_priv_authlist(hw, &old); + + macarray->cnt = 0; + for (i = 0; i < old.cnt; i++) { + if (old.assoc[i]) { + memcpy(macarray->data[macarray->cnt], old.addr[i], WLAN_ADDR_LEN); + macarray->cnt++; + } + } + } + + break; + + case DIDmib_p2_p2Table_p2PowerSaveUserCount: + + if (isget) + *uint32 = hw->psusercount; + + break; + + case DIDmib_p2_p2Table_p2Comment: + + if (isget) { + pstr->len = strlen(hw->comment); + memcpy(pstr->data, hw->comment, pstr->len); + } else { + cnt = pstr->len; + if (cnt < 0) cnt = 0; + if (cnt >= sizeof(hw->comment)) + cnt = sizeof(hw->comment)-1; + memcpy(hw->comment, pstr->data, cnt); + pstr->data[cnt] = '\0'; + } + + break; + + case DIDmib_p2_p2Table_p2AccessMode: + + if (isget) + *uint32 = hw->accessmode; + else + prism2mib_priv_accessmode(hw, *uint32); + + break; + + case DIDmib_p2_p2Table_p2AccessAllow: + + if (isget) { + macarray->cnt = hw->allow.cnt; + memcpy(macarray->data, hw->allow.addr, + macarray->cnt*WLAN_ADDR_LEN); + } else { + prism2mib_priv_accessallow(hw, macarray); + } + + break; + + case DIDmib_p2_p2Table_p2AccessDeny: + + if (isget) { + macarray->cnt = hw->deny.cnt; + memcpy(macarray->data, hw->deny.addr, + macarray->cnt*WLAN_ADDR_LEN); + } else { + prism2mib_priv_accessdeny(hw, macarray); + } + + break; + + case DIDmib_p2_p2Table_p2ChannelInfoResults: + + if (isget) { + done = atomic_read(&hw->channel_info.done); + if (done == 0) { + msg->resultcode.status = P80211ENUM_msgitem_status_no_value; + break; + } + if (done == 1) { + msg->resultcode.status = P80211ENUM_msgitem_status_incomplete_itemdata; + break; + } + + for (i = 0; i < 14; i++, uint32 += 5) { + uint32[0] = i+1; + uint32[1] = hw->channel_info.results.result[i].anl; + uint32[2] = hw->channel_info.results.result[i].pnl; + uint32[3] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_BSSACTIVE) ? 1 : 0; + uint32[4] = (hw->channel_info.results.result[i].active & HFA384x_CHINFORESULT_PCFACTIVE) ? 1 : 0; + } + } + + break; + + case DIDmib_dot11smt_dot11StationConfigTable_dot11DesiredBSSType: + + if (isget) + *uint32 = hw->dot11_desired_bss_type; + else + hw->dot11_desired_bss_type = *uint32; + + break; + + case DIDmib_lnx_lnxConfigTable_lnxRSNAIE: { + hfa384x_WPAData_t wpa; + if (isget) { + hfa384x_drvr_getconfig( hw, HFA384x_RID_CNFWPADATA, + (UINT8 *) &wpa, sizeof(wpa)); + pstr->len = hfa384x2host_16(wpa.datalen); + memcpy(pstr->data, wpa.data, pstr->len); + } else { + wpa.datalen = host2hfa384x_16(pstr->len); + memcpy(wpa.data, pstr->data, pstr->len); + + result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFWPADATA, + (UINT8 *) &wpa, sizeof(wpa)); + } + break; + } + default: + WLAN_LOG_ERROR("Unhandled DID 0x%08x\n", mib->did); + } + + DBFEXIT; + return(0); +} + +/*---------------------------------------------------------------- +* prism2mib_priv_authlist +* +* Get a copy of the list of authenticated stations. +* +* Arguments: +* priv "priv" structure. +* list List of authenticated stations. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_authlist( +hfa384x_t *hw, +prism2sta_authlist_t *list) +{ + prism2sta_authlist_t test; + int i; + + DBFENTER; + + /* + ** Note: The values in this record are changed by the interrupt + ** handler and therefore cannot be guaranteed to be stable while + ** they are being copied. However, the interrupt handler will + ** take priority over this code. Hence, if the same values are + ** copied twice, then we are ensured that the values have not + ** been changed. If they have, then just try again. Don't try + ** more than 10 times...the list of authenticated stations is + ** unlikely to be changing frequently enough that we can't get + ** a snapshot in 10 tries. Don't try more than this so that we + ** don't risk locking-up for long periods of time. If we still + ** haven't got the snapshot, then generate an error message and + ** return an empty list (since this is the only valid list that + ** we can guarentee). This scheme for copying values is used in + ** order to prevent having to block the interrupt handler while + ** we copy the values. + */ + + for (i = 0; i < 10; i++) { + memcpy(list, &hw->authlist, sizeof(prism2sta_authlist_t)); + memcpy(&test, &hw->authlist, sizeof(prism2sta_authlist_t)); + if (memcmp(list, &test, sizeof(prism2sta_authlist_t)) == 0) + break; + } + + if (i >= 10) { + list->cnt = 0; + WLAN_LOG_ERROR("Could not obtain snapshot of authenticated stations.\n"); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_accessmode +* +* Set the Access Mode. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* mode New access mode. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_accessmode( +hfa384x_t *hw, +UINT32 mode) +{ + prism2sta_authlist_t old; + int i, j, deauth; + UINT8 *addr; + + DBFENTER; + + /* + ** If the mode is not changing or it is changing to "All", then it's + ** okay to go ahead without a lot of messing around. Otherwise, the + ** access mode is changing in a way that may leave some stations + ** authenticated which should not be authenticated. It will be + ** necessary to de-authenticate these stations. + */ + + if (mode == WLAN_ACCESS_ALL || mode == hw->accessmode) { + hw->accessmode = mode; + return; + } + + /* + ** Switch to the new access mode. Once this is done, then the interrupt + ** handler (which uses this value) will be prevented from authenticating + ** ADDITIONAL stations which should not be authenticated. Then get a + ** copy of the current list of authenticated stations. + */ + + hw->accessmode = mode; + + prism2mib_priv_authlist(hw, &old); + + /* + ** Now go through the list of previously authenticated stations (some + ** of which might de-authenticate themselves while we are processing it + ** but that is okay). Any station which no longer matches the access + ** mode, must be de-authenticated. + */ + + for (i = 0; i < old.cnt; i++) { + addr = old.addr[i]; + + if (mode == WLAN_ACCESS_NONE) + deauth = 1; + else { + if (mode == WLAN_ACCESS_ALLOW) { + for (j = 0; j < hw->allow.cnt; j++) + if (memcmp(addr, hw->allow.addr[j], + WLAN_ADDR_LEN) == 0) + break; + deauth = (j >= hw->allow.cnt); + } else { + for (j = 0; j < hw->deny.cnt; j++) + if (memcmp(addr, hw->deny.addr[j], + WLAN_ADDR_LEN) == 0) + break; + deauth = (j < hw->deny.cnt); + } + } + + if (deauth) prism2mib_priv_deauthenticate(hw, addr); + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_accessallow +* +* Change the list of allowed MAC addresses. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* macarray New array of MAC addresses. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_accessallow( +hfa384x_t *hw, +p80211macarray_t *macarray) +{ + prism2sta_authlist_t old; + int i, j; + + DBFENTER; + + /* + ** Change the access list. Note that the interrupt handler may be in + ** the middle of using the access list!!! Since the interrupt handler + ** will always have priority over this process and this is the only + ** process that will modify the list, this problem can be handled as + ** follows: + ** + ** 1. Set the "modify" flag. + ** 2. Change the first copy of the list. + ** 3. Clear the "modify" flag. + ** 4. Change the backup copy of the list. + ** + ** The interrupt handler will check the "modify" flag. If NOT set, then + ** the first copy of the list is valid and may be used. Otherwise, the + ** first copy is being changed but the backup copy is valid and may be + ** used. Doing things this way prevents having to have the interrupt + ** handler block while the list is being updated. + */ + + hw->allow.modify = 1; + + hw->allow.cnt = macarray->cnt; + memcpy(hw->allow.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + hw->allow.modify = 0; + + hw->allow.cnt1 = macarray->cnt; + memcpy(hw->allow.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + /* + ** If the current access mode is "Allow", then changing the access + ** list may leave some stations authenticated which should not be + ** authenticated. It will be necessary to de-authenticate these + ** stations. Otherwise, the list can be changed without a lot of fuss. + */ + + if (hw->accessmode == WLAN_ACCESS_ALLOW) { + + /* + ** Go through the list of authenticated stations (some of + ** which might de-authenticate themselves while we are + ** processing it but that is okay). Any station which is + ** no longer in the list of allowed stations, must be + ** de-authenticated. + */ + + prism2mib_priv_authlist(hw, &old); + + for (i = 0; i < old.cnt; i++) { + for (j = 0; j < hw->allow.cnt; j++) + if (memcmp(old.addr[i], hw->allow.addr[j], + WLAN_ADDR_LEN) == 0) + break; + if (j >= hw->allow.cnt) + prism2mib_priv_deauthenticate(hw, old.addr[i]); + } + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_accessdeny +* +* Change the list of denied MAC addresses. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* macarray New array of MAC addresses. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_accessdeny( +hfa384x_t *hw, +p80211macarray_t *macarray) +{ + prism2sta_authlist_t old; + int i, j; + + DBFENTER; + + /* + ** Change the access list. Note that the interrupt handler may be in + ** the middle of using the access list!!! Since the interrupt handler + ** will always have priority over this process and this is the only + ** process that will modify the list, this problem can be handled as + ** follows: + ** + ** 1. Set the "modify" flag. + ** 2. Change the first copy of the list. + ** 3. Clear the "modify" flag. + ** 4. Change the backup copy of the list. + ** + ** The interrupt handler will check the "modify" flag. If NOT set, then + ** the first copy of the list is valid and may be used. Otherwise, the + ** first copy is being changed but the backup copy is valid and may be + ** used. Doing things this way prevents having to have the interrupt + ** handler block while the list is being updated. + */ + + hw->deny.modify = 1; + + hw->deny.cnt = macarray->cnt; + memcpy(hw->deny.addr, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + hw->deny.modify = 0; + + hw->deny.cnt1 = macarray->cnt; + memcpy(hw->deny.addr1, macarray->data, macarray->cnt*WLAN_ADDR_LEN); + + /* + ** If the current access mode is "Deny", then changing the access + ** list may leave some stations authenticated which should not be + ** authenticated. It will be necessary to de-authenticate these + ** stations. Otherwise, the list can be changed without a lot of fuss. + */ + + if (hw->accessmode == WLAN_ACCESS_DENY) { + + /* + ** Go through the list of authenticated stations (some of + ** which might de-authenticate themselves while we are + ** processing it but that is okay). Any station which is + ** now in the list of denied stations, must be de-authenticated. + */ + + prism2mib_priv_authlist(hw, &old); + + for (i = 0; i < old.cnt; i++) + for (j = 0; j < hw->deny.cnt; j++) + if (memcmp(old.addr[i], hw->deny.addr[j], + WLAN_ADDR_LEN) == 0) { + prism2mib_priv_deauthenticate(hw, old.addr[i]); + break; + } + } + + DBFEXIT; + return; +} + +/*---------------------------------------------------------------- +* prism2mib_priv_deauthenticate +* +* De-authenticate a station. This is done by sending a HandoverAddress +* information frame to the firmware. This should work, according to +* Intersil. +* +* Arguments: +* priv "priv" structure. +* hw "hw" structure. +* addr MAC address of station to be de-authenticated. +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +static void prism2mib_priv_deauthenticate( +hfa384x_t *hw, +UINT8 *addr) +{ + DBFENTER; + hfa384x_drvr_handover(hw, addr); + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_pstr2bytestr +* +* Convert the pstr data in the WLAN message structure into an hfa384x +* byte string format. +* +* Arguments: +* bytestr hfa384x byte string data type +* pstr wlan message data +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr) +{ + DBFENTER; + + bytestr->len = host2hfa384x_16((UINT16)(pstr->len)); + memcpy(bytestr->data, pstr->data, pstr->len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_pstr2bytearea +* +* Convert the pstr data in the WLAN message structure into an hfa384x +* byte area format. +* +* Arguments: +* bytearea hfa384x byte area data type +* pstr wlan message data +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr) +{ + DBFENTER; + + memcpy(bytearea, pstr->data, pstr->len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_bytestr2pstr +* +* Convert the data in an hfa384x byte string format into a +* pstr in the WLAN message. +* +* Arguments: +* bytestr hfa384x byte string data type +* msg wlan message +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr) +{ + DBFENTER; + + pstr->len = (UINT8)(hfa384x2host_16((UINT16)(bytestr->len))); + memcpy(pstr->data, bytestr->data, pstr->len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_bytearea2pstr +* +* Convert the data in an hfa384x byte area format into a pstr +* in the WLAN message. +* +* Arguments: +* bytearea hfa384x byte area data type +* msg wlan message +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len) +{ + DBFENTER; + + pstr->len = (UINT8)len; + memcpy(pstr->data, bytearea, len); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_prism2int2p80211int +* +* Convert an hfa384x integer into a wlan integer +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint) +{ + DBFENTER; + + *wlanint = (UINT32)hfa384x2host_16(*prism2int); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_p80211int2prism2int +* +* Convert a wlan integer into an hfa384x integer +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ + +void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint) +{ + DBFENTER; + + *prism2int = host2hfa384x_16((UINT16)(*wlanint)); + DBFEXIT; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_prism2enum2p80211enum +* +* Convert the hfa384x enumerated int into a p80211 enumerated int +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* rid hfa384x record id +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid) +{ + DBFENTER; + + /* At the moment, the need for this functionality hasn't + presented itself. All the wlan enumerated values are + a 1-to-1 match against the Prism2 enumerated values*/ + DBFEXIT; + return; +} + + +/*---------------------------------------------------------------- +* prism2mgmt_p80211enum2prism2enum +* +* Convert the p80211 enumerated int into an hfa384x enumerated int +* +* Arguments: +* prism2enum pointer to hfa384x integer +* wlanenum pointer to p80211 integer +* rid hfa384x record id +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid) +{ + DBFENTER; + + /* At the moment, the need for this functionality hasn't + presented itself. All the wlan enumerated values are + a 1-to-1 match against the Prism2 enumerated values*/ + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_get_oprateset +* +* Convert the hfa384x bit area into a wlan octet string. +* +* Arguments: +* rate Prism2 bit area +* pstr wlan octet string +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr) +{ + UINT8 len; + UINT8 *datarate; + + DBFENTER; + + len = 0; + datarate = pstr->data; + + /* 1 Mbps */ + if ( BIT0 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)2; + datarate++; + } + + /* 2 Mbps */ + if ( BIT1 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)4; + datarate++; + } + + /* 5.5 Mbps */ + if ( BIT2 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)11; + datarate++; + } + + /* 11 Mbps */ + if ( BIT3 & (*rate) ) { + len += (UINT8)1; + *datarate = (UINT8)22; + datarate++; + } + + pstr->len = len; + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_set_oprateset +* +* Convert the wlan octet string into an hfa384x bit area. +* +* Arguments: +* rate Prism2 bit area +* pstr wlan octet string +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr) +{ + UINT8 *datarate; + int i; + + DBFENTER; + + *rate = 0; + + datarate = pstr->data; + + for ( i=0; i < pstr->len; i++, datarate++ ) { + switch (*datarate) { + case 2: /* 1 Mbps */ + *rate |= BIT0; + break; + case 4: /* 2 Mbps */ + *rate |= BIT1; + break; + case 11: /* 5.5 Mbps */ + *rate |= BIT2; + break; + case 22: /* 11 Mbps */ + *rate |= BIT3; + break; + default: + WLAN_LOG_DEBUG(1, "Unrecoginzed Rate of %d\n", + *datarate); + break; + } + } + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_get_grpaddr +* +* Retrieves a particular group address from the list of +* group addresses. +* +* Arguments: +* did mibitem did +* pstr wlan octet string +* priv prism2 driver private data structure +* +* Returns: +* Nothing +* +----------------------------------------------------------------*/ +void prism2mgmt_get_grpaddr(UINT32 did, p80211pstrd_t *pstr, + hfa384x_t *hw ) +{ + int index; + + DBFENTER; + + index = prism2mgmt_get_grpaddr_index(did); + + if ( index >= 0 ) { + pstr->len = WLAN_ADDR_LEN; + memcpy(pstr->data, hw->dot11_grp_addr[index], + WLAN_ADDR_LEN); + } + + DBFEXIT; + return; +} + + + +/*---------------------------------------------------------------- +* prism2mgmt_set_grpaddr +* +* Convert the wlan octet string into an hfa384x bit area. +* +* Arguments: +* did mibitem did +* buf +* groups +* +* Returns: +* 0 Success +* !0 Error +* +----------------------------------------------------------------*/ +int prism2mgmt_set_grpaddr(UINT32 did, UINT8 *prism2buf, + p80211pstrd_t *pstr, hfa384x_t *hw ) +{ + UINT8 no_addr[WLAN_ADDR_LEN]; + int index; + + DBFENTER; + + memset(no_addr, 0, WLAN_ADDR_LEN); + if (memcmp(no_addr, pstr->data, WLAN_ADDR_LEN) != 0) { + + /* + ** The address is NOT 0 so we are "adding" an address to the + ** group address list. Check to make sure we aren't trying + ** to add more than the maximum allowed number of group + ** addresses in the list. The new address is added to the + ** end of the list regardless of the DID used to add the + ** address. + */ + + if (hw->dot11_grpcnt >= MAX_GRP_ADDR) return(-1); + + memcpy(hw->dot11_grp_addr[hw->dot11_grpcnt], pstr->data, + WLAN_ADDR_LEN); + hw->dot11_grpcnt += 1; + } else { + + /* + ** The address is 0. Interpret this as "deleting" an address + ** from the group address list. Get the address index from + ** the DID. If this is within the range of used addresses, + ** then delete the specified address by shifting all following + ** addresses down. Then clear the last address (which should + ** now be unused). If the address index is NOT within the + ** range of used addresses, then just ignore the address. + */ + + index = prism2mgmt_get_grpaddr_index(did); + if (index >= 0 && index < hw->dot11_grpcnt) { + hw->dot11_grpcnt -= 1; + memmove(hw->dot11_grp_addr[index], + hw->dot11_grp_addr[index + 1], + ((hw->dot11_grpcnt)-index) * WLAN_ADDR_LEN); + memset(hw->dot11_grp_addr[hw->dot11_grpcnt], 0, + WLAN_ADDR_LEN); + } + } + + DBFEXIT; + return(0); +} + + +/*---------------------------------------------------------------- +* prism2mgmt_get_grpaddr_index +* +* Gets the index in the group address list based on the did. +* +* Arguments: +* did mibitem did +* +* Returns: +* >= 0 If valid did +* < 0 If not valid did +* +----------------------------------------------------------------*/ +int prism2mgmt_get_grpaddr_index( UINT32 did ) +{ + int index; + + DBFENTER; + + index = -1; + + switch (did) { + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address1: + index = 0; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address2: + index = 1; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address3: + index = 2; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address4: + index = 3; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address5: + index = 4; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address6: + index = 5; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address7: + index = 6; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address8: + index = 7; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address9: + index = 8; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address10: + index = 9; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address11: + index = 10; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address12: + index = 11; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address13: + index = 12; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address14: + index = 13; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address15: + index = 14; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address16: + index = 15; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address17: + index = 16; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address18: + index = 17; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address19: + index = 18; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address20: + index = 19; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address21: + index = 20; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address22: + index = 21; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address23: + index = 22; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address24: + index = 23; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address25: + index = 24; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address26: + index = 25; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address27: + index = 26; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address28: + index = 27; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address29: + index = 28; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address30: + index = 29; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address31: + index = 30; + break; + case DIDmib_dot11mac_dot11GroupAddressesTable_dot11Address32: + index = 31; + break; + } + + DBFEXIT; + return index; +} --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/BOM +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/BOM @@ -0,0 +1,15 @@ +# Jul 29, 2008 +# Copied from the linux-wlan-ng 0.2.9+dfsg source package + +Run "make config" then "make" in src/mkmeta + +cp -a src/prism2/driver $KERNEL/ubuntu/misc/wireless/prism2_usb +cp -a src/p80211 $KERNEL/ubuntu/misc/wireless/ +cp -a src/include/wlan $KERNEL/ubuntu/misc/wireless/p80211/ +cp -a src/prism2/include/prism2 $KERNEL/ubuntu/misc/wireless/prism2_usb/ + +Strip down prism2_usb/Makefile and p80211/Makefile +rm prism2_usb/prism2_{cs,pci,plx} + +Use dev_net_set() for 2.6.26 in p80211/p80211netdev.c:wlan_setup() + --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2/prism2mgmt.h +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2/prism2mgmt.h @@ -0,0 +1,182 @@ +/* src/prism2/include/prism2/prism2mgmt.h +* +* Declares the mgmt command handler functions +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* This file contains the constants and data structures for interaction +* with the hfa384x Wireless LAN (WLAN) Media Access Contoller (MAC). +* The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset. +* +* [Implementation and usage notes] +* +* [References] +* CW10 Programmer's Manual v1.5 +* IEEE 802.11 D10.0 +* +* -------------------------------------------------------------------- +*/ + +#ifndef _PRISM2MGMT_H +#define _PRISM2MGMT_H + + +/*=============================================================*/ +/*------ Constants --------------------------------------------*/ + +/*=============================================================*/ +/*------ Macros -----------------------------------------------*/ + +/*=============================================================*/ +/*------ Types and their related constants --------------------*/ + +/*=============================================================*/ +/*------ Static variable externs ------------------------------*/ + +#if (WLAN_HOSTIF != WLAN_USB) +extern int prism2_bap_timeout; +extern int prism2_irq_evread_max; +#endif +extern int prism2_debug; +extern int prism2_reset_holdtime; +extern int prism2_reset_settletime; +/*=============================================================*/ +/*--- Function Declarations -----------------------------------*/ +/*=============================================================*/ + +UINT32 +prism2sta_ifstate(wlandevice_t *wlandev, UINT32 ifstate); + +void +prism2sta_ev_dtim(wlandevice_t *wlandev); +void +prism2sta_ev_infdrop(wlandevice_t *wlandev); +void +prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf); +void +prism2sta_ev_txexc(wlandevice_t *wlandev, UINT16 status); +void +prism2sta_ev_tx(wlandevice_t *wlandev, UINT16 status); +void +prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb); +void +prism2sta_ev_alloc(wlandevice_t *wlandev); + + +int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_powermgmt(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_join(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_p2_join(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_authenticate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_deauthenticate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_associate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_reassociate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_disassociate(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_reset(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_start(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_readcis(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_auxport_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_auxport_read(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_auxport_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_low_level(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_test_command(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_mmi_read(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_mmi_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_mm_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_dump_state(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_enable(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_channel_info(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_channel_info_results(wlandevice_t *wlandev, void *msgp); +int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp); + +/*--------------------------------------------------------------- +* conversion functions going between wlan message data types and +* Prism2 data types +---------------------------------------------------------------*/ +/* byte area conversion functions*/ +void prism2mgmt_pstr2bytearea(UINT8 *bytearea, p80211pstrd_t *pstr); +void prism2mgmt_bytearea2pstr(UINT8 *bytearea, p80211pstrd_t *pstr, int len); + +/* byte string conversion functions*/ +void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); +void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr); + +/* integer conversion functions */ +void prism2mgmt_prism2int2p80211int(UINT16 *prism2int, UINT32 *wlanint); +void prism2mgmt_p80211int2prism2int(UINT16 *prism2int, UINT32 *wlanint); + +/* enumerated integer conversion functions */ +void prism2mgmt_prism2enum2p80211enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid); +void prism2mgmt_p80211enum2prism2enum(UINT16 *prism2enum, UINT32 *wlanenum, UINT16 rid); + +/* functions to convert a bit area to/from an Operational Rate Set */ +void prism2mgmt_get_oprateset(UINT16 *rate, p80211pstrd_t *pstr); +void prism2mgmt_set_oprateset(UINT16 *rate, p80211pstrd_t *pstr); + +/* functions to convert Group Addresses */ +void prism2mgmt_get_grpaddr(UINT32 did, + p80211pstrd_t *pstr, hfa384x_t *priv ); +int prism2mgmt_set_grpaddr(UINT32 did, + UINT8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv ); +int prism2mgmt_get_grpaddr_index( UINT32 did ); + +void prism2sta_processing_defer(struct work_struct *data); + +void prism2sta_commsqual_defer(struct work_struct *data); +void prism2sta_commsqual_timer(unsigned long data); + +/*=============================================================*/ +/*--- Inline Function Definitions (if supported) --------------*/ +/*=============================================================*/ + + + +#endif --- linux-2.6.28.orig/ubuntu/misc/wireless/prism2_usb/prism2/hfa384x.h +++ linux-2.6.28/ubuntu/misc/wireless/prism2_usb/prism2/hfa384x.h @@ -0,0 +1,3067 @@ +/* src/prism2/include/prism2/hfa384x.h +* +* Defines the constants and data structures for the hfa384x +* +* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. +* -------------------------------------------------------------------- +* +* linux-wlan +* +* The contents of this file are subject to the Mozilla Public +* License Version 1.1 (the "License"); you may not use this file +* except in compliance with the License. You may obtain a copy of +* the License at http://www.mozilla.org/MPL/ +* +* Software distributed under the License is distributed on an "AS +* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +* implied. See the License for the specific language governing +* rights and limitations under the License. +* +* Alternatively, the contents of this file may be used under the +* terms of the GNU Public License version 2 (the "GPL"), in which +* case the provisions of the GPL are applicable instead of the +* above. If you wish to allow the use of your version of this file +* only under the terms of the GPL and not to allow others to use +* your version of this file under the MPL, indicate your decision +* by deleting the provisions above and replace them with the notice +* and other provisions required by the GPL. If you do not delete +* the provisions above, a recipient may use your version of this +* file under either the MPL or the GPL. +* +* -------------------------------------------------------------------- +* +* Inquiries regarding the linux-wlan Open Source project can be +* made directly to: +* +* AbsoluteValue Systems Inc. +* info@linux-wlan.com +* http://www.linux-wlan.com +* +* -------------------------------------------------------------------- +* +* Portions of the development of this software were funded by +* Intersil Corporation as part of PRISM(R) chipset product development. +* +* -------------------------------------------------------------------- +* +* [Implementation and usage notes] +* +* [References] +* CW10 Programmer's Manual v1.5 +* IEEE 802.11 D10.0 +* +* -------------------------------------------------------------------- +*/ + +#ifndef _HFA384x_H +#define _HFA384x_H + +/*=============================================================*/ +#define HFA384x_FIRMWARE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) + +#define HFA384x_LEVEL_TO_dBm(v) (0x100 + (v) * 100 / 255 - 100) + +/*------ Constants --------------------------------------------*/ +/*--- Mins & Maxs -----------------------------------*/ +#define HFA384x_CMD_ALLOC_LEN_MIN ((UINT16)4) +#define HFA384x_CMD_ALLOC_LEN_MAX ((UINT16)2400) +#define HFA384x_BAP_DATALEN_MAX ((UINT16)4096) +#define HFA384x_BAP_OFFSET_MAX ((UINT16)4096) +#define HFA384x_PORTID_MAX ((UINT16)7) +#define HFA384x_NUMPORTS_MAX ((UINT16)(HFA384x_PORTID_MAX+1)) +#define HFA384x_PDR_LEN_MAX ((UINT16)512) /* in bytes, from EK */ +#define HFA384x_PDA_RECS_MAX ((UINT16)200) /* a guess */ +#define HFA384x_PDA_LEN_MAX ((UINT16)1024) /* in bytes, from EK */ +#define HFA384x_SCANRESULT_MAX ((UINT16)31) +#define HFA384x_HSCANRESULT_MAX ((UINT16)31) +#define HFA384x_CHINFORESULT_MAX ((UINT16)16) +#define HFA384x_DRVR_FIDSTACKLEN_MAX (10) +#define HFA384x_DRVR_TXBUF_MAX (sizeof(hfa384x_tx_frame_t) + \ + WLAN_DATA_MAXLEN - \ + WLAN_WEP_IV_LEN - \ + WLAN_WEP_ICV_LEN + 2) +#define HFA384x_DRVR_MAGIC (0x4a2d) +#define HFA384x_INFODATA_MAXLEN (sizeof(hfa384x_infodata_t)) +#define HFA384x_INFOFRM_MAXLEN (sizeof(hfa384x_InfFrame_t)) +#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ +#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN +#define HFA384x_USB_RWMEM_MAXLEN 2048 + +/*--- Support Constants -----------------------------*/ +#define HFA384x_BAP_PROC ((UINT16)0) +#define HFA384x_BAP_INT ((UINT16)1) +#define HFA384x_PORTTYPE_IBSS ((UINT16)0) +#define HFA384x_PORTTYPE_BSS ((UINT16)1) +#define HFA384x_PORTTYPE_WDS ((UINT16)2) +#define HFA384x_PORTTYPE_PSUEDOIBSS ((UINT16)3) +#define HFA384x_PORTTYPE_HOSTAP ((UINT16)6) +#define HFA384x_WEPFLAGS_PRIVINVOKED ((UINT16)BIT0) +#define HFA384x_WEPFLAGS_EXCLUDE ((UINT16)BIT1) +#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((UINT16)BIT4) +#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((UINT16)BIT7) +#define HFA384x_WEPFLAGS_DISALLOW_MIXED ((UINT16)BIT11) +#define HFA384x_WEPFLAGS_IV_INTERVAL1 ((UINT16)0) +#define HFA384x_WEPFLAGS_IV_INTERVAL10 ((UINT16)BIT5) +#define HFA384x_WEPFLAGS_IV_INTERVAL50 ((UINT16)BIT6) +#define HFA384x_WEPFLAGS_IV_INTERVAL100 ((UINT16)(BIT5 | BIT6)) +#define HFA384x_WEPFLAGS_FIRMWARE_WPA ((UINT16)BIT8) +#define HFA384x_WEPFLAGS_HOST_MIC ((UINT16)BIT9) +#define HFA384x_ROAMMODE_FWSCAN_FWROAM ((UINT16)1) +#define HFA384x_ROAMMODE_FWSCAN_HOSTROAM ((UINT16)2) +#define HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM ((UINT16)3) +#define HFA384x_PORTSTATUS_DISABLED ((UINT16)1) +#define HFA384x_PORTSTATUS_INITSRCH ((UINT16)2) +#define HFA384x_PORTSTATUS_CONN_IBSS ((UINT16)3) +#define HFA384x_PORTSTATUS_CONN_ESS ((UINT16)4) +#define HFA384x_PORTSTATUS_OOR_ESS ((UINT16)5) +#define HFA384x_PORTSTATUS_CONN_WDS ((UINT16)6) +#define HFA384x_PORTSTATUS_HOSTAP ((UINT16)8) +#define HFA384x_RATEBIT_1 ((UINT16)1) +#define HFA384x_RATEBIT_2 ((UINT16)2) +#define HFA384x_RATEBIT_5dot5 ((UINT16)4) +#define HFA384x_RATEBIT_11 ((UINT16)8) + +/*--- Just some symbolic names for legibility -------*/ +#define HFA384x_TXCMD_NORECL ((UINT16)0) +#define HFA384x_TXCMD_RECL ((UINT16)1) + +/*--- MAC Internal memory constants and macros ------*/ +/* masks and macros used to manipulate MAC internal memory addresses. */ +/* MAC internal memory addresses are 23 bit quantities. The MAC uses + * a paged address space where the upper 16 bits are the page number + * and the lower 7 bits are the offset. There are various Host API + * elements that require two 16-bit quantities to specify a MAC + * internal memory address. Unfortunately, some of the API's use a + * page/offset format where the offset value is JUST the lower seven + * bits and the page is the remaining 16 bits. Some of the API's + * assume that the 23 bit address has been split at the 16th bit. We + * refer to these two formats as AUX format and CMD format. The + * macros below help handle some of this. + */ + +/* Handy constant */ +#define HFA384x_ADDR_AUX_OFF_MAX ((UINT16)0x007f) + +/* Mask bits for discarding unwanted pieces in a flat address */ +#define HFA384x_ADDR_FLAT_AUX_PAGE_MASK (0x007fff80) +#define HFA384x_ADDR_FLAT_AUX_OFF_MASK (0x0000007f) +#define HFA384x_ADDR_FLAT_CMD_PAGE_MASK (0xffff0000) +#define HFA384x_ADDR_FLAT_CMD_OFF_MASK (0x0000ffff) + +/* Mask bits for discarding unwanted pieces in AUX format 16-bit address parts */ +#define HFA384x_ADDR_AUX_PAGE_MASK (0xffff) +#define HFA384x_ADDR_AUX_OFF_MASK (0x007f) + +/* Mask bits for discarding unwanted pieces in CMD format 16-bit address parts */ +#define HFA384x_ADDR_CMD_PAGE_MASK (0x007f) +#define HFA384x_ADDR_CMD_OFF_MASK (0xffff) + +/* Make a 32-bit flat address from AUX format 16-bit page and offset */ +#define HFA384x_ADDR_AUX_MKFLAT(p,o) \ + (((UINT32)(((UINT16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) <<7) | \ + ((UINT32)(((UINT16)(o))&HFA384x_ADDR_AUX_OFF_MASK)) + +/* Make a 32-bit flat address from CMD format 16-bit page and offset */ +#define HFA384x_ADDR_CMD_MKFLAT(p,o) \ + (((UINT32)(((UINT16)(p))&HFA384x_ADDR_CMD_PAGE_MASK)) <<16) | \ + ((UINT32)(((UINT16)(o))&HFA384x_ADDR_CMD_OFF_MASK)) + +/* Make AUX format offset and page from a 32-bit flat address */ +#define HFA384x_ADDR_AUX_MKPAGE(f) \ + ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_PAGE_MASK)>>7)) +#define HFA384x_ADDR_AUX_MKOFF(f) \ + ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_AUX_OFF_MASK)) + +/* Make CMD format offset and page from a 32-bit flat address */ +#define HFA384x_ADDR_CMD_MKPAGE(f) \ + ((UINT16)((((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16)) +#define HFA384x_ADDR_CMD_MKOFF(f) \ + ((UINT16)(((UINT32)(f))&HFA384x_ADDR_FLAT_CMD_OFF_MASK)) + +/*--- Aux register masks/tests ----------------------*/ +/* Some of the upper bits of the AUX offset register are used to */ +/* select address space. */ +#define HFA384x_AUX_CTL_EXTDS (0x00) +#define HFA384x_AUX_CTL_NV (0x01) +#define HFA384x_AUX_CTL_PHY (0x02) +#define HFA384x_AUX_CTL_ICSRAM (0x03) + +/* Make AUX register offset and page values from a flat address */ +#define HFA384x_AUX_MKOFF(f, c) \ + (HFA384x_ADDR_AUX_MKOFF(f) | (((UINT16)(c))<<12)) +#define HFA384x_AUX_MKPAGE(f) HFA384x_ADDR_AUX_MKPAGE(f) + + +/*--- Controller Memory addresses -------------------*/ +#define HFA3842_PDA_BASE (0x007f0000UL) +#define HFA3841_PDA_BASE (0x003f0000UL) +#define HFA3841_PDA_BOGUS_BASE (0x00390000UL) + +/*--- Driver Download states -----------------------*/ +#define HFA384x_DLSTATE_DISABLED 0 +#define HFA384x_DLSTATE_RAMENABLED 1 +#define HFA384x_DLSTATE_FLASHENABLED 2 +#define HFA384x_DLSTATE_FLASHWRITTEN 3 +#define HFA384x_DLSTATE_FLASHWRITEPENDING 4 +#define HFA384x_DLSTATE_GENESIS 5 + +/*--- Register I/O offsets --------------------------*/ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + +#define HFA384x_CMD_OFF (0x00) +#define HFA384x_PARAM0_OFF (0x02) +#define HFA384x_PARAM1_OFF (0x04) +#define HFA384x_PARAM2_OFF (0x06) +#define HFA384x_STATUS_OFF (0x08) +#define HFA384x_RESP0_OFF (0x0A) +#define HFA384x_RESP1_OFF (0x0C) +#define HFA384x_RESP2_OFF (0x0E) +#define HFA384x_INFOFID_OFF (0x10) +#define HFA384x_RXFID_OFF (0x20) +#define HFA384x_ALLOCFID_OFF (0x22) +#define HFA384x_TXCOMPLFID_OFF (0x24) +#define HFA384x_SELECT0_OFF (0x18) +#define HFA384x_OFFSET0_OFF (0x1C) +#define HFA384x_DATA0_OFF (0x36) +#define HFA384x_SELECT1_OFF (0x1A) +#define HFA384x_OFFSET1_OFF (0x1E) +#define HFA384x_DATA1_OFF (0x38) +#define HFA384x_EVSTAT_OFF (0x30) +#define HFA384x_INTEN_OFF (0x32) +#define HFA384x_EVACK_OFF (0x34) +#define HFA384x_CONTROL_OFF (0x14) +#define HFA384x_SWSUPPORT0_OFF (0x28) +#define HFA384x_SWSUPPORT1_OFF (0x2A) +#define HFA384x_SWSUPPORT2_OFF (0x2C) +#define HFA384x_AUXPAGE_OFF (0x3A) +#define HFA384x_AUXOFFSET_OFF (0x3C) +#define HFA384x_AUXDATA_OFF (0x3E) + +#elif (WLAN_HOSTIF == WLAN_PCI || WLAN_HOSTIF == WLAN_USB) + +#define HFA384x_CMD_OFF (0x00) +#define HFA384x_PARAM0_OFF (0x04) +#define HFA384x_PARAM1_OFF (0x08) +#define HFA384x_PARAM2_OFF (0x0c) +#define HFA384x_STATUS_OFF (0x10) +#define HFA384x_RESP0_OFF (0x14) +#define HFA384x_RESP1_OFF (0x18) +#define HFA384x_RESP2_OFF (0x1c) +#define HFA384x_INFOFID_OFF (0x20) +#define HFA384x_RXFID_OFF (0x40) +#define HFA384x_ALLOCFID_OFF (0x44) +#define HFA384x_TXCOMPLFID_OFF (0x48) +#define HFA384x_SELECT0_OFF (0x30) +#define HFA384x_OFFSET0_OFF (0x38) +#define HFA384x_DATA0_OFF (0x6c) +#define HFA384x_SELECT1_OFF (0x34) +#define HFA384x_OFFSET1_OFF (0x3c) +#define HFA384x_DATA1_OFF (0x70) +#define HFA384x_EVSTAT_OFF (0x60) +#define HFA384x_INTEN_OFF (0x64) +#define HFA384x_EVACK_OFF (0x68) +#define HFA384x_CONTROL_OFF (0x28) +#define HFA384x_SWSUPPORT0_OFF (0x50) +#define HFA384x_SWSUPPORT1_OFF (0x54) +#define HFA384x_SWSUPPORT2_OFF (0x58) +#define HFA384x_AUXPAGE_OFF (0x74) +#define HFA384x_AUXOFFSET_OFF (0x78) +#define HFA384x_AUXDATA_OFF (0x7c) +#define HFA384x_PCICOR_OFF (0x4c) +#define HFA384x_PCIHCR_OFF (0x5c) +#define HFA384x_PCI_M0_ADDRH_OFF (0x80) +#define HFA384x_PCI_M0_ADDRL_OFF (0x84) +#define HFA384x_PCI_M0_LEN_OFF (0x88) +#define HFA384x_PCI_M0_CTL_OFF (0x8c) +#define HFA384x_PCI_STATUS_OFF (0x98) +#define HFA384x_PCI_M1_ADDRH_OFF (0xa0) +#define HFA384x_PCI_M1_ADDRL_OFF (0xa4) +#define HFA384x_PCI_M1_LEN_OFF (0xa8) +#define HFA384x_PCI_M1_CTL_OFF (0xac) + +#endif + +/*--- Register Field Masks --------------------------*/ +#define HFA384x_CMD_BUSY ((UINT16)BIT15) +#define HFA384x_CMD_AINFO ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)) +#define HFA384x_CMD_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8)) +#define HFA384x_CMD_RECL ((UINT16)BIT8) +#define HFA384x_CMD_WRITE ((UINT16)BIT8) +#define HFA384x_CMD_PROGMODE ((UINT16)(BIT9 | BIT8)) +#define HFA384x_CMD_CMDCODE ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)) + +#define HFA384x_STATUS_RESULT ((UINT16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)) +#define HFA384x_STATUS_CMDCODE ((UINT16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)) + +#define HFA384x_OFFSET_BUSY ((UINT16)BIT15) +#define HFA384x_OFFSET_ERR ((UINT16)BIT14) +#define HFA384x_OFFSET_DATAOFF ((UINT16)(BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1)) + +#define HFA384x_EVSTAT_TICK ((UINT16)BIT15) +#define HFA384x_EVSTAT_WTERR ((UINT16)BIT14) +#define HFA384x_EVSTAT_INFDROP ((UINT16)BIT13) +#define HFA384x_EVSTAT_INFO ((UINT16)BIT7) +#define HFA384x_EVSTAT_DTIM ((UINT16)BIT5) +#define HFA384x_EVSTAT_CMD ((UINT16)BIT4) +#define HFA384x_EVSTAT_ALLOC ((UINT16)BIT3) +#define HFA384x_EVSTAT_TXEXC ((UINT16)BIT2) +#define HFA384x_EVSTAT_TX ((UINT16)BIT1) +#define HFA384x_EVSTAT_RX ((UINT16)BIT0) + +#define HFA384x_INT_BAP_OP (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC) + +#define HFA384x_INT_NORMAL (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC|HFA384x_EVSTAT_INFDROP|HFA384x_EVSTAT_ALLOC|HFA384x_EVSTAT_DTIM) + +#define HFA384x_INTEN_TICK ((UINT16)BIT15) +#define HFA384x_INTEN_WTERR ((UINT16)BIT14) +#define HFA384x_INTEN_INFDROP ((UINT16)BIT13) +#define HFA384x_INTEN_INFO ((UINT16)BIT7) +#define HFA384x_INTEN_DTIM ((UINT16)BIT5) +#define HFA384x_INTEN_CMD ((UINT16)BIT4) +#define HFA384x_INTEN_ALLOC ((UINT16)BIT3) +#define HFA384x_INTEN_TXEXC ((UINT16)BIT2) +#define HFA384x_INTEN_TX ((UINT16)BIT1) +#define HFA384x_INTEN_RX ((UINT16)BIT0) + +#define HFA384x_EVACK_TICK ((UINT16)BIT15) +#define HFA384x_EVACK_WTERR ((UINT16)BIT14) +#define HFA384x_EVACK_INFDROP ((UINT16)BIT13) +#define HFA384x_EVACK_INFO ((UINT16)BIT7) +#define HFA384x_EVACK_DTIM ((UINT16)BIT5) +#define HFA384x_EVACK_CMD ((UINT16)BIT4) +#define HFA384x_EVACK_ALLOC ((UINT16)BIT3) +#define HFA384x_EVACK_TXEXC ((UINT16)BIT2) +#define HFA384x_EVACK_TX ((UINT16)BIT1) +#define HFA384x_EVACK_RX ((UINT16)BIT0) + +#define HFA384x_CONTROL_AUXEN ((UINT16)(BIT15 | BIT14)) + + +/*--- Command Code Constants --------------------------*/ +/*--- Controller Commands --------------------------*/ +#define HFA384x_CMDCODE_INIT ((UINT16)0x00) +#define HFA384x_CMDCODE_ENABLE ((UINT16)0x01) +#define HFA384x_CMDCODE_DISABLE ((UINT16)0x02) +#define HFA384x_CMDCODE_DIAG ((UINT16)0x03) + +/*--- Buffer Mgmt Commands --------------------------*/ +#define HFA384x_CMDCODE_ALLOC ((UINT16)0x0A) +#define HFA384x_CMDCODE_TX ((UINT16)0x0B) +#define HFA384x_CMDCODE_CLRPRST ((UINT16)0x12) + +/*--- Regulate Commands --------------------------*/ +#define HFA384x_CMDCODE_NOTIFY ((UINT16)0x10) +#define HFA384x_CMDCODE_INQ ((UINT16)0x11) + +/*--- Configure Commands --------------------------*/ +#define HFA384x_CMDCODE_ACCESS ((UINT16)0x21) +#define HFA384x_CMDCODE_DOWNLD ((UINT16)0x22) + +/*--- Debugging Commands -----------------------------*/ +#define HFA384x_CMDCODE_MONITOR ((UINT16)(0x38)) +#define HFA384x_MONITOR_ENABLE ((UINT16)(0x0b)) +#define HFA384x_MONITOR_DISABLE ((UINT16)(0x0f)) + +/*--- Result Codes --------------------------*/ +#define HFA384x_SUCCESS ((UINT16)(0x00)) +#define HFA384x_CARD_FAIL ((UINT16)(0x01)) +#define HFA384x_NO_BUFF ((UINT16)(0x05)) +#define HFA384x_CMD_ERR ((UINT16)(0x7F)) + +/*--- Programming Modes -------------------------- + MODE 0: Disable programming + MODE 1: Enable volatile memory programming + MODE 2: Enable non-volatile memory programming + MODE 3: Program non-volatile memory section +--------------------------------------------------*/ +#define HFA384x_PROGMODE_DISABLE ((UINT16)0x00) +#define HFA384x_PROGMODE_RAM ((UINT16)0x01) +#define HFA384x_PROGMODE_NV ((UINT16)0x02) +#define HFA384x_PROGMODE_NVWRITE ((UINT16)0x03) + +/*--- AUX register enable --------------------------*/ +#define HFA384x_AUXPW0 ((UINT16)0xfe01) +#define HFA384x_AUXPW1 ((UINT16)0xdc23) +#define HFA384x_AUXPW2 ((UINT16)0xba45) + +#define HFA384x_CONTROL_AUX_ISDISABLED ((UINT16)0x0000) +#define HFA384x_CONTROL_AUX_ISENABLED ((UINT16)0xc000) +#define HFA384x_CONTROL_AUX_DOENABLE ((UINT16)0x8000) +#define HFA384x_CONTROL_AUX_DODISABLE ((UINT16)0x4000) + +/*--- Record ID Constants --------------------------*/ +/*-------------------------------------------------------------------- +Configuration RIDs: Network Parameters, Static Configuration Entities +--------------------------------------------------------------------*/ +#define HFA384x_RID_CNFPORTTYPE ((UINT16)0xFC00) +#define HFA384x_RID_CNFOWNMACADDR ((UINT16)0xFC01) +#define HFA384x_RID_CNFDESIREDSSID ((UINT16)0xFC02) +#define HFA384x_RID_CNFOWNCHANNEL ((UINT16)0xFC03) +#define HFA384x_RID_CNFOWNSSID ((UINT16)0xFC04) +#define HFA384x_RID_CNFOWNATIMWIN ((UINT16)0xFC05) +#define HFA384x_RID_CNFSYSSCALE ((UINT16)0xFC06) +#define HFA384x_RID_CNFMAXDATALEN ((UINT16)0xFC07) +#define HFA384x_RID_CNFWDSADDR ((UINT16)0xFC08) +#define HFA384x_RID_CNFPMENABLED ((UINT16)0xFC09) +#define HFA384x_RID_CNFPMEPS ((UINT16)0xFC0A) +#define HFA384x_RID_CNFMULTICASTRX ((UINT16)0xFC0B) +#define HFA384x_RID_CNFMAXSLEEPDUR ((UINT16)0xFC0C) +#define HFA384x_RID_CNFPMHOLDDUR ((UINT16)0xFC0D) +#define HFA384x_RID_CNFOWNNAME ((UINT16)0xFC0E) +#define HFA384x_RID_CNFOWNDTIMPER ((UINT16)0xFC10) +#define HFA384x_RID_CNFWDSADDR1 ((UINT16)0xFC11) +#define HFA384x_RID_CNFWDSADDR2 ((UINT16)0xFC12) +#define HFA384x_RID_CNFWDSADDR3 ((UINT16)0xFC13) +#define HFA384x_RID_CNFWDSADDR4 ((UINT16)0xFC14) +#define HFA384x_RID_CNFWDSADDR5 ((UINT16)0xFC15) +#define HFA384x_RID_CNFWDSADDR6 ((UINT16)0xFC16) +#define HFA384x_RID_CNFMCASTPMBUFF ((UINT16)0xFC17) + +/*-------------------------------------------------------------------- +Configuration RID lengths: Network Params, Static Config Entities + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +/* TODO: fill in the rest of these */ +#define HFA384x_RID_CNFPORTTYPE_LEN ((UINT16)2) +#define HFA384x_RID_CNFOWNMACADDR_LEN ((UINT16)6) +#define HFA384x_RID_CNFDESIREDSSID_LEN ((UINT16)34) +#define HFA384x_RID_CNFOWNCHANNEL_LEN ((UINT16)2) +#define HFA384x_RID_CNFOWNSSID_LEN ((UINT16)34) +#define HFA384x_RID_CNFOWNATIMWIN_LEN ((UINT16)2) +#define HFA384x_RID_CNFSYSSCALE_LEN ((UINT16)0) +#define HFA384x_RID_CNFMAXDATALEN_LEN ((UINT16)0) +#define HFA384x_RID_CNFWDSADDR_LEN ((UINT16)6) +#define HFA384x_RID_CNFPMENABLED_LEN ((UINT16)0) +#define HFA384x_RID_CNFPMEPS_LEN ((UINT16)0) +#define HFA384x_RID_CNFMULTICASTRX_LEN ((UINT16)0) +#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0) +#define HFA384x_RID_CNFPMHOLDDUR_LEN ((UINT16)0) +#define HFA384x_RID_CNFOWNNAME_LEN ((UINT16)34) +#define HFA384x_RID_CNFOWNDTIMPER_LEN ((UINT16)0) +#define HFA384x_RID_CNFWDSADDR1_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR2_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR3_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR4_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR5_LEN ((UINT16)6) +#define HFA384x_RID_CNFWDSADDR6_LEN ((UINT16)6) +#define HFA384x_RID_CNFMCASTPMBUFF_LEN ((UINT16)0) +#define HFA384x_RID_CNFAUTHENTICATION_LEN ((UINT16)sizeof(UINT16)) +#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((UINT16)0) + +/*-------------------------------------------------------------------- +Configuration RIDs: Network Parameters, Dynamic Configuration Entities +--------------------------------------------------------------------*/ +#define HFA384x_RID_GROUPADDR ((UINT16)0xFC80) +#define HFA384x_RID_CREATEIBSS ((UINT16)0xFC81) +#define HFA384x_RID_FRAGTHRESH ((UINT16)0xFC82) +#define HFA384x_RID_RTSTHRESH ((UINT16)0xFC83) +#define HFA384x_RID_TXRATECNTL ((UINT16)0xFC84) +#define HFA384x_RID_PROMISCMODE ((UINT16)0xFC85) +#define HFA384x_RID_FRAGTHRESH0 ((UINT16)0xFC90) +#define HFA384x_RID_FRAGTHRESH1 ((UINT16)0xFC91) +#define HFA384x_RID_FRAGTHRESH2 ((UINT16)0xFC92) +#define HFA384x_RID_FRAGTHRESH3 ((UINT16)0xFC93) +#define HFA384x_RID_FRAGTHRESH4 ((UINT16)0xFC94) +#define HFA384x_RID_FRAGTHRESH5 ((UINT16)0xFC95) +#define HFA384x_RID_FRAGTHRESH6 ((UINT16)0xFC96) +#define HFA384x_RID_RTSTHRESH0 ((UINT16)0xFC97) +#define HFA384x_RID_RTSTHRESH1 ((UINT16)0xFC98) +#define HFA384x_RID_RTSTHRESH2 ((UINT16)0xFC99) +#define HFA384x_RID_RTSTHRESH3 ((UINT16)0xFC9A) +#define HFA384x_RID_RTSTHRESH4 ((UINT16)0xFC9B) +#define HFA384x_RID_RTSTHRESH5 ((UINT16)0xFC9C) +#define HFA384x_RID_RTSTHRESH6 ((UINT16)0xFC9D) +#define HFA384x_RID_TXRATECNTL0 ((UINT16)0xFC9E) +#define HFA384x_RID_TXRATECNTL1 ((UINT16)0xFC9F) +#define HFA384x_RID_TXRATECNTL2 ((UINT16)0xFCA0) +#define HFA384x_RID_TXRATECNTL3 ((UINT16)0xFCA1) +#define HFA384x_RID_TXRATECNTL4 ((UINT16)0xFCA2) +#define HFA384x_RID_TXRATECNTL5 ((UINT16)0xFCA3) +#define HFA384x_RID_TXRATECNTL6 ((UINT16)0xFCA4) + +/*-------------------------------------------------------------------- +Configuration RID Lengths: Network Param, Dynamic Config Entities + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +/* TODO: fill in the rest of these */ +#define HFA384x_RID_GROUPADDR_LEN ((UINT16)16 * WLAN_ADDR_LEN) +#define HFA384x_RID_CREATEIBSS_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL_LEN ((UINT16)4) +#define HFA384x_RID_PROMISCMODE_LEN ((UINT16)2) +#define HFA384x_RID_FRAGTHRESH0_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH1_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH2_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH3_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH4_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH5_LEN ((UINT16)0) +#define HFA384x_RID_FRAGTHRESH6_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH0_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH1_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH2_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH3_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH4_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH5_LEN ((UINT16)0) +#define HFA384x_RID_RTSTHRESH6_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL0_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL1_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL2_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL3_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL4_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL5_LEN ((UINT16)0) +#define HFA384x_RID_TXRATECNTL6_LEN ((UINT16)0) + +/*-------------------------------------------------------------------- +Configuration RIDs: Behavior Parameters +--------------------------------------------------------------------*/ +#define HFA384x_RID_ITICKTIME ((UINT16)0xFCE0) + +/*-------------------------------------------------------------------- +Configuration RID Lengths: Behavior Parameters + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_ITICKTIME_LEN ((UINT16)2) + +/*---------------------------------------------------------------------- +Information RIDs: NIC Information +--------------------------------------------------------------------*/ +#define HFA384x_RID_MAXLOADTIME ((UINT16)0xFD00) +#define HFA384x_RID_DOWNLOADBUFFER ((UINT16)0xFD01) +#define HFA384x_RID_PRIIDENTITY ((UINT16)0xFD02) +#define HFA384x_RID_PRISUPRANGE ((UINT16)0xFD03) +#define HFA384x_RID_PRI_CFIACTRANGES ((UINT16)0xFD04) +#define HFA384x_RID_NICSERIALNUMBER ((UINT16)0xFD0A) +#define HFA384x_RID_NICIDENTITY ((UINT16)0xFD0B) +#define HFA384x_RID_MFISUPRANGE ((UINT16)0xFD0C) +#define HFA384x_RID_CFISUPRANGE ((UINT16)0xFD0D) +#define HFA384x_RID_CHANNELLIST ((UINT16)0xFD10) +#define HFA384x_RID_REGULATORYDOMAINS ((UINT16)0xFD11) +#define HFA384x_RID_TEMPTYPE ((UINT16)0xFD12) +#define HFA384x_RID_CIS ((UINT16)0xFD13) +#define HFA384x_RID_STAIDENTITY ((UINT16)0xFD20) +#define HFA384x_RID_STASUPRANGE ((UINT16)0xFD21) +#define HFA384x_RID_STA_MFIACTRANGES ((UINT16)0xFD22) +#define HFA384x_RID_STA_CFIACTRANGES ((UINT16)0xFD23) +#define HFA384x_RID_BUILDSEQ ((UINT16)0xFFFE) +#define HFA384x_RID_FWID ((UINT16)0xFFFF) + +/*---------------------------------------------------------------------- +Information RID Lengths: NIC Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_MAXLOADTIME_LEN ((UINT16)0) +#define HFA384x_RID_DOWNLOADBUFFER_LEN ((UINT16)sizeof(hfa384x_downloadbuffer_t)) +#define HFA384x_RID_PRIIDENTITY_LEN ((UINT16)8) +#define HFA384x_RID_PRISUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_CFIACTRANGES_LEN ((UINT16)10) +#define HFA384x_RID_NICSERIALNUMBER_LEN ((UINT16)12) +#define HFA384x_RID_NICIDENTITY_LEN ((UINT16)8) +#define HFA384x_RID_MFISUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_CFISUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_CHANNELLIST_LEN ((UINT16)0) +#define HFA384x_RID_REGULATORYDOMAINS_LEN ((UINT16)12) +#define HFA384x_RID_TEMPTYPE_LEN ((UINT16)0) +#define HFA384x_RID_CIS_LEN ((UINT16)480) +#define HFA384x_RID_STAIDENTITY_LEN ((UINT16)8) +#define HFA384x_RID_STASUPRANGE_LEN ((UINT16)10) +#define HFA384x_RID_MFIACTRANGES_LEN ((UINT16)10) +#define HFA384x_RID_CFIACTRANGES2_LEN ((UINT16)10) +#define HFA384x_RID_BUILDSEQ_LEN ((UINT16)sizeof(hfa384x_BuildSeq_t)) +#define HFA384x_RID_FWID_LEN ((UINT16)sizeof(hfa384x_FWID_t)) + +/*-------------------------------------------------------------------- +Information RIDs: MAC Information +--------------------------------------------------------------------*/ +#define HFA384x_RID_PORTSTATUS ((UINT16)0xFD40) +#define HFA384x_RID_CURRENTSSID ((UINT16)0xFD41) +#define HFA384x_RID_CURRENTBSSID ((UINT16)0xFD42) +#define HFA384x_RID_COMMSQUALITY ((UINT16)0xFD43) +#define HFA384x_RID_CURRENTTXRATE ((UINT16)0xFD44) +#define HFA384x_RID_CURRENTBCNINT ((UINT16)0xFD45) +#define HFA384x_RID_CURRENTSCALETHRESH ((UINT16)0xFD46) +#define HFA384x_RID_PROTOCOLRSPTIME ((UINT16)0xFD47) +#define HFA384x_RID_SHORTRETRYLIMIT ((UINT16)0xFD48) +#define HFA384x_RID_LONGRETRYLIMIT ((UINT16)0xFD49) +#define HFA384x_RID_MAXTXLIFETIME ((UINT16)0xFD4A) +#define HFA384x_RID_MAXRXLIFETIME ((UINT16)0xFD4B) +#define HFA384x_RID_CFPOLLABLE ((UINT16)0xFD4C) +#define HFA384x_RID_AUTHALGORITHMS ((UINT16)0xFD4D) +#define HFA384x_RID_PRIVACYOPTIMP ((UINT16)0xFD4F) +#define HFA384x_RID_DBMCOMMSQUALITY ((UINT16)0xFD51) +#define HFA384x_RID_CURRENTTXRATE1 ((UINT16)0xFD80) +#define HFA384x_RID_CURRENTTXRATE2 ((UINT16)0xFD81) +#define HFA384x_RID_CURRENTTXRATE3 ((UINT16)0xFD82) +#define HFA384x_RID_CURRENTTXRATE4 ((UINT16)0xFD83) +#define HFA384x_RID_CURRENTTXRATE5 ((UINT16)0xFD84) +#define HFA384x_RID_CURRENTTXRATE6 ((UINT16)0xFD85) +#define HFA384x_RID_OWNMACADDRESS ((UINT16)0xFD86) +// #define HFA384x_RID_PCFINFO ((UINT16)0xFD87) +#define HFA384x_RID_SCANRESULTS ((UINT16)0xFD88) // NEW +#define HFA384x_RID_HOSTSCANRESULTS ((UINT16)0xFD89) // NEW +#define HFA384x_RID_AUTHENTICATIONUSED ((UINT16)0xFD8A) // NEW +#define HFA384x_RID_ASSOCIATEFAILURE ((UINT16)0xFD8D) // 1.8.0 + +/*-------------------------------------------------------------------- +Information RID Lengths: MAC Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_PORTSTATUS_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTSSID_LEN ((UINT16)34) +#define HFA384x_RID_CURRENTBSSID_LEN ((UINT16)WLAN_BSSID_LEN) +#define HFA384x_RID_COMMSQUALITY_LEN ((UINT16)sizeof(hfa384x_commsquality_t)) +#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((UINT16)sizeof(hfa384x_dbmcommsquality_t)) +#define HFA384x_RID_CURRENTTXRATE_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTBCNINT_LEN ((UINT16)0) +#define HFA384x_RID_STACURSCALETHRESH_LEN ((UINT16)12) +#define HFA384x_RID_APCURSCALETHRESH_LEN ((UINT16)6) +#define HFA384x_RID_PROTOCOLRSPTIME_LEN ((UINT16)0) +#define HFA384x_RID_SHORTRETRYLIMIT_LEN ((UINT16)0) +#define HFA384x_RID_LONGRETRYLIMIT_LEN ((UINT16)0) +#define HFA384x_RID_MAXTXLIFETIME_LEN ((UINT16)0) +#define HFA384x_RID_MAXRXLIFETIME_LEN ((UINT16)0) +#define HFA384x_RID_CFPOLLABLE_LEN ((UINT16)0) +#define HFA384x_RID_AUTHALGORITHMS_LEN ((UINT16)4) +#define HFA384x_RID_PRIVACYOPTIMP_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE1_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE2_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE3_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE4_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE5_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTTXRATE6_LEN ((UINT16)0) +#define HFA384x_RID_OWNMACADDRESS_LEN ((UINT16)6) +#define HFA384x_RID_PCFINFO_LEN ((UINT16)6) +#define HFA384x_RID_CNFAPPCFINFO_LEN ((UINT16)sizeof(hfa384x_PCFInfo_data_t)) +#define HFA384x_RID_SCANREQUEST_LEN ((UINT16)sizeof(hfa384x_ScanRequest_data_t)) +#define HFA384x_RID_JOINREQUEST_LEN ((UINT16)sizeof(hfa384x_JoinRequest_data_t)) +#define HFA384x_RID_AUTHENTICATESTA_LEN ((UINT16)sizeof(hfa384x_authenticateStation_data_t)) +#define HFA384x_RID_CHANNELINFOREQUEST_LEN ((UINT16)sizeof(hfa384x_ChannelInfoRequest_data_t)) +/*-------------------------------------------------------------------- +Information RIDs: Modem Information +--------------------------------------------------------------------*/ +#define HFA384x_RID_PHYTYPE ((UINT16)0xFDC0) +#define HFA384x_RID_CURRENTCHANNEL ((UINT16)0xFDC1) +#define HFA384x_RID_CURRENTPOWERSTATE ((UINT16)0xFDC2) +#define HFA384x_RID_CCAMODE ((UINT16)0xFDC3) +#define HFA384x_RID_SUPPORTEDDATARATES ((UINT16)0xFDC6) +#define HFA384x_RID_LFOSTATUS ((UINT16)0xFDC7) // 1.7.1 + +/*-------------------------------------------------------------------- +Information RID Lengths: Modem Information + This is the length of JUST the DATA part of the RID (does not + include the len or code fields) +--------------------------------------------------------------------*/ +#define HFA384x_RID_PHYTYPE_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTCHANNEL_LEN ((UINT16)0) +#define HFA384x_RID_CURRENTPOWERSTATE_LEN ((UINT16)0) +#define HFA384x_RID_CCAMODE_LEN ((UINT16)0) +#define HFA384x_RID_SUPPORTEDDATARATES_LEN ((UINT16)10) + +/*-------------------------------------------------------------------- +API ENHANCEMENTS (NOT ALREADY IMPLEMENTED) +--------------------------------------------------------------------*/ +#define HFA384x_RID_CNFWEPDEFAULTKEYID ((UINT16)0xFC23) +#define HFA384x_RID_CNFWEPDEFAULTKEY0 ((UINT16)0xFC24) +#define HFA384x_RID_CNFWEPDEFAULTKEY1 ((UINT16)0xFC25) +#define HFA384x_RID_CNFWEPDEFAULTKEY2 ((UINT16)0xFC26) +#define HFA384x_RID_CNFWEPDEFAULTKEY3 ((UINT16)0xFC27) +#define HFA384x_RID_CNFWEPFLAGS ((UINT16)0xFC28) +#define HFA384x_RID_CNFWEPKEYMAPTABLE ((UINT16)0xFC29) +#define HFA384x_RID_CNFAUTHENTICATION ((UINT16)0xFC2A) +#define HFA384x_RID_CNFMAXASSOCSTATIONS ((UINT16)0xFC2B) +#define HFA384x_RID_CNFTXCONTROL ((UINT16)0xFC2C) +#define HFA384x_RID_CNFROAMINGMODE ((UINT16)0xFC2D) +#define HFA384x_RID_CNFHOSTAUTHASSOC ((UINT16)0xFC2E) +#define HFA384x_RID_CNFRCVCRCERROR ((UINT16)0xFC30) +// #define HFA384x_RID_CNFMMLIFE ((UINT16)0xFC31) +#define HFA384x_RID_CNFALTRETRYCNT ((UINT16)0xFC32) +#define HFA384x_RID_CNFAPBCNINT ((UINT16)0xFC33) +#define HFA384x_RID_CNFAPPCFINFO ((UINT16)0xFC34) +#define HFA384x_RID_CNFSTAPCFINFO ((UINT16)0xFC35) +#define HFA384x_RID_CNFPRIORITYQUSAGE ((UINT16)0xFC37) +#define HFA384x_RID_CNFTIMCTRL ((UINT16)0xFC40) +#define HFA384x_RID_CNFTHIRTY2TALLY ((UINT16)0xFC42) +#define HFA384x_RID_CNFENHSECURITY ((UINT16)0xFC43) +#define HFA384x_RID_CNFDBMADJUST ((UINT16)0xFC46) // NEW +#define HFA384x_RID_CNFWPADATA ((UINT16)0xFC48) // 1.7.0 +#define HFA384x_RID_CNFPROPOGATIONDELAY ((UINT16)0xFC49) // 1.7.6 +#define HFA384x_RID_CNFSHORTPREAMBLE ((UINT16)0xFCB0) +#define HFA384x_RID_CNFEXCLONGPREAMBLE ((UINT16)0xFCB1) +#define HFA384x_RID_CNFAUTHRSPTIMEOUT ((UINT16)0xFCB2) +#define HFA384x_RID_CNFBASICRATES ((UINT16)0xFCB3) +#define HFA384x_RID_CNFSUPPRATES ((UINT16)0xFCB4) +#define HFA384x_RID_CNFFALLBACKCTRL ((UINT16)0xFCB5) // NEW +#define HFA384x_RID_WEPKEYSTATUS ((UINT16)0xFCB6) // NEW +#define HFA384x_RID_WEPKEYMAPINDEX ((UINT16)0xFCB7) // NEW +#define HFA384x_RID_BROADCASTKEYID ((UINT16)0xFCB8) // NEW +#define HFA384x_RID_ENTSECFLAGEYID ((UINT16)0xFCB9) // NEW +#define HFA384x_RID_CNFPASSIVESCANCTRL ((UINT16)0xFCBA) // NEW STA +#define HFA384x_RID_CNFWPAHANDLING ((UINT16)0xFCBB) // 1.7.0 +#define HFA384x_RID_MDCCONTROL ((UINT16)0xFCBC) // 1.7.0/1.4.0 +#define HFA384x_RID_MDCCOUNTRY ((UINT16)0xFCBD) // 1.7.0/1.4.0 +#define HFA384x_RID_TXPOWERMAX ((UINT16)0xFCBE) // 1.7.0/1.4.0 +#define HFA384x_RID_CNFLFOENBLED ((UINT16)0xFCBF) // 1.6.3 +#define HFA384x_RID_CAPINFO ((UINT16)0xFCC0) // 1.7.0/1.3.7 +#define HFA384x_RID_LISTENINTERVAL ((UINT16)0xFCC1) // 1.7.0/1.3.7 +#define HFA384x_RID_DIVERSITYENABLED ((UINT16)0xFCC2) // 1.7.0/1.3.7 +#define HFA384x_RID_LED_CONTROL ((UINT16)0xFCC4) // 1.7.6 +#define HFA384x_RID_HFO_DELAY ((UINT16)0xFCC5) // 1.7.6 +#define HFA384x_RID_DISSALOWEDBSSID ((UINT16)0xFCC6) // 1.8.0 +#define HFA384x_RID_SCANREQUEST ((UINT16)0xFCE1) +#define HFA384x_RID_JOINREQUEST ((UINT16)0xFCE2) +#define HFA384x_RID_AUTHENTICATESTA ((UINT16)0xFCE3) +#define HFA384x_RID_CHANNELINFOREQUEST ((UINT16)0xFCE4) +#define HFA384x_RID_HOSTSCAN ((UINT16)0xFCE5) // NEW STA +#define HFA384x_RID_ASSOCIATESTA ((UINT16)0xFCE6) + +#define HFA384x_RID_CNFWEPDEFAULTKEY_LEN ((UINT16)6) +#define HFA384x_RID_CNFWEP128DEFAULTKEY_LEN ((UINT16)14) +#define HFA384x_RID_CNFPRIOQUSAGE_LEN ((UINT16)4) +/*-------------------------------------------------------------------- +PD Record codes +--------------------------------------------------------------------*/ +#define HFA384x_PDR_PCB_PARTNUM ((UINT16)0x0001) +#define HFA384x_PDR_PDAVER ((UINT16)0x0002) +#define HFA384x_PDR_NIC_SERIAL ((UINT16)0x0003) +#define HFA384x_PDR_MKK_MEASUREMENTS ((UINT16)0x0004) +#define HFA384x_PDR_NIC_RAMSIZE ((UINT16)0x0005) +#define HFA384x_PDR_MFISUPRANGE ((UINT16)0x0006) +#define HFA384x_PDR_CFISUPRANGE ((UINT16)0x0007) +#define HFA384x_PDR_NICID ((UINT16)0x0008) +//#define HFA384x_PDR_REFDAC_MEASUREMENTS ((UINT16)0x0010) +//#define HFA384x_PDR_VGDAC_MEASUREMENTS ((UINT16)0x0020) +//#define HFA384x_PDR_LEVEL_COMP_MEASUREMENTS ((UINT16)0x0030) +//#define HFA384x_PDR_MODEM_TRIMDAC_MEASUREMENTS ((UINT16)0x0040) +//#define HFA384x_PDR_COREGA_HACK ((UINT16)0x00ff) +#define HFA384x_PDR_MAC_ADDRESS ((UINT16)0x0101) +//#define HFA384x_PDR_MKK_CALLNAME ((UINT16)0x0102) +#define HFA384x_PDR_REGDOMAIN ((UINT16)0x0103) +#define HFA384x_PDR_ALLOWED_CHANNEL ((UINT16)0x0104) +#define HFA384x_PDR_DEFAULT_CHANNEL ((UINT16)0x0105) +//#define HFA384x_PDR_PRIVACY_OPTION ((UINT16)0x0106) +#define HFA384x_PDR_TEMPTYPE ((UINT16)0x0107) +//#define HFA384x_PDR_REFDAC_SETUP ((UINT16)0x0110) +//#define HFA384x_PDR_VGDAC_SETUP ((UINT16)0x0120) +//#define HFA384x_PDR_LEVEL_COMP_SETUP ((UINT16)0x0130) +//#define HFA384x_PDR_TRIMDAC_SETUP ((UINT16)0x0140) +#define HFA384x_PDR_IFR_SETTING ((UINT16)0x0200) +#define HFA384x_PDR_RFR_SETTING ((UINT16)0x0201) +#define HFA384x_PDR_HFA3861_BASELINE ((UINT16)0x0202) +#define HFA384x_PDR_HFA3861_SHADOW ((UINT16)0x0203) +#define HFA384x_PDR_HFA3861_IFRF ((UINT16)0x0204) +#define HFA384x_PDR_HFA3861_CHCALSP ((UINT16)0x0300) +#define HFA384x_PDR_HFA3861_CHCALI ((UINT16)0x0301) +#define HFA384x_PDR_MAX_TX_POWER ((UINT16)0x0302) +#define HFA384x_PDR_MASTER_CHAN_LIST ((UINT16)0x0303) +#define HFA384x_PDR_3842_NIC_CONFIG ((UINT16)0x0400) +#define HFA384x_PDR_USB_ID ((UINT16)0x0401) +#define HFA384x_PDR_PCI_ID ((UINT16)0x0402) +#define HFA384x_PDR_PCI_IFCONF ((UINT16)0x0403) +#define HFA384x_PDR_PCI_PMCONF ((UINT16)0x0404) +#define HFA384x_PDR_RFENRGY ((UINT16)0x0406) +#define HFA384x_PDR_USB_POWER_TYPE ((UINT16)0x0407) +//#define HFA384x_PDR_UNKNOWN408 ((UINT16)0x0408) +#define HFA384x_PDR_USB_MAX_POWER ((UINT16)0x0409) +#define HFA384x_PDR_USB_MANUFACTURER ((UINT16)0x0410) +#define HFA384x_PDR_USB_PRODUCT ((UINT16)0x0411) +#define HFA384x_PDR_ANT_DIVERSITY ((UINT16)0x0412) +#define HFA384x_PDR_HFO_DELAY ((UINT16)0x0413) +#define HFA384x_PDR_SCALE_THRESH ((UINT16)0x0414) + +#define HFA384x_PDR_HFA3861_MANF_TESTSP ((UINT16)0x0900) +#define HFA384x_PDR_HFA3861_MANF_TESTI ((UINT16)0x0901) +#define HFA384x_PDR_END_OF_PDA ((UINT16)0x0000) + + +/*=============================================================*/ +/*------ Macros -----------------------------------------------*/ + +/*--- Register ID macros ------------------------*/ + +#define HFA384x_CMD HFA384x_CMD_OFF +#define HFA384x_PARAM0 HFA384x_PARAM0_OFF +#define HFA384x_PARAM1 HFA384x_PARAM1_OFF +#define HFA384x_PARAM2 HFA384x_PARAM2_OFF +#define HFA384x_STATUS HFA384x_STATUS_OFF +#define HFA384x_RESP0 HFA384x_RESP0_OFF +#define HFA384x_RESP1 HFA384x_RESP1_OFF +#define HFA384x_RESP2 HFA384x_RESP2_OFF +#define HFA384x_INFOFID HFA384x_INFOFID_OFF +#define HFA384x_RXFID HFA384x_RXFID_OFF +#define HFA384x_ALLOCFID HFA384x_ALLOCFID_OFF +#define HFA384x_TXCOMPLFID HFA384x_TXCOMPLFID_OFF +#define HFA384x_SELECT0 HFA384x_SELECT0_OFF +#define HFA384x_OFFSET0 HFA384x_OFFSET0_OFF +#define HFA384x_DATA0 HFA384x_DATA0_OFF +#define HFA384x_SELECT1 HFA384x_SELECT1_OFF +#define HFA384x_OFFSET1 HFA384x_OFFSET1_OFF +#define HFA384x_DATA1 HFA384x_DATA1_OFF +#define HFA384x_EVSTAT HFA384x_EVSTAT_OFF +#define HFA384x_INTEN HFA384x_INTEN_OFF +#define HFA384x_EVACK HFA384x_EVACK_OFF +#define HFA384x_CONTROL HFA384x_CONTROL_OFF +#define HFA384x_SWSUPPORT0 HFA384x_SWSUPPORT0_OFF +#define HFA384x_SWSUPPORT1 HFA384x_SWSUPPORT1_OFF +#define HFA384x_SWSUPPORT2 HFA384x_SWSUPPORT2_OFF +#define HFA384x_AUXPAGE HFA384x_AUXPAGE_OFF +#define HFA384x_AUXOFFSET HFA384x_AUXOFFSET_OFF +#define HFA384x_AUXDATA HFA384x_AUXDATA_OFF +#define HFA384x_PCICOR HFA384x_PCICOR_OFF +#define HFA384x_PCIHCR HFA384x_PCIHCR_OFF + + +/*--- Register Test/Get/Set Field macros ------------------------*/ + +#define HFA384x_CMD_ISBUSY(value) ((UINT16)(((UINT16)value) & HFA384x_CMD_BUSY)) +#define HFA384x_CMD_AINFO_GET(value) ((UINT16)(((UINT16)(value) & HFA384x_CMD_AINFO) >> 8)) +#define HFA384x_CMD_AINFO_SET(value) ((UINT16)((UINT16)(value) << 8)) +#define HFA384x_CMD_MACPORT_GET(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_MACPORT))) +#define HFA384x_CMD_MACPORT_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET(value)) +#define HFA384x_CMD_ISRECL(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_RECL))) +#define HFA384x_CMD_RECL_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET(value)) +#define HFA384x_CMD_QOS_GET(value) ((UINT16((((UINT16)(value))&((UINT16)0x3000)) >> 12)) +#define HFA384x_CMD_QOS_SET(value) ((UINT16)((((UINT16)(value)) << 12) & 0x3000)) +#define HFA384x_CMD_ISWRITE(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_WRITE))) +#define HFA384x_CMD_WRITE_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value)) +#define HFA384x_CMD_PROGMODE_GET(value) ((UINT16)(HFA384x_CMD_AINFO_GET((UINT16)(value) & HFA384x_CMD_PROGMODE))) +#define HFA384x_CMD_PROGMODE_SET(value) ((UINT16)HFA384x_CMD_AINFO_SET((UINT16)value)) +#define HFA384x_CMD_CMDCODE_GET(value) ((UINT16)(((UINT16)(value)) & HFA384x_CMD_CMDCODE)) +#define HFA384x_CMD_CMDCODE_SET(value) ((UINT16)(value)) + +#define HFA384x_STATUS_RESULT_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_STATUS_RESULT) >> 8)) +#define HFA384x_STATUS_RESULT_SET(value) (((UINT16)(value)) << 8) +#define HFA384x_STATUS_CMDCODE_GET(value) (((UINT16)(value)) & HFA384x_STATUS_CMDCODE) +#define HFA384x_STATUS_CMDCODE_SET(value) ((UINT16)(value)) + +#define HFA384x_OFFSET_ISBUSY(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_BUSY)) +#define HFA384x_OFFSET_ISERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_ERR)) +#define HFA384x_OFFSET_DATAOFF_GET(value) ((UINT16)(((UINT16)(value)) & HFA384x_OFFSET_DATAOFF)) +#define HFA384x_OFFSET_DATAOFF_SET(value) ((UINT16)(value)) + +#define HFA384x_EVSTAT_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TICK)) +#define HFA384x_EVSTAT_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_WTERR)) +#define HFA384x_EVSTAT_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFDROP)) +#define HFA384x_EVSTAT_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_INFO)) +#define HFA384x_EVSTAT_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_DTIM)) +#define HFA384x_EVSTAT_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_CMD)) +#define HFA384x_EVSTAT_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_ALLOC)) +#define HFA384x_EVSTAT_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TXEXC)) +#define HFA384x_EVSTAT_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_TX)) +#define HFA384x_EVSTAT_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVSTAT_RX)) + +#define HFA384x_EVSTAT_ISBAP_OP(value) ((UINT16)(((UINT16)(value)) & HFA384x_INT_BAP_OP)) + +#define HFA384x_INTEN_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TICK)) +#define HFA384x_INTEN_TICK_SET(value) ((UINT16)(((UINT16)(value)) << 15)) +#define HFA384x_INTEN_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_WTERR)) +#define HFA384x_INTEN_WTERR_SET(value) ((UINT16)(((UINT16)(value)) << 14)) +#define HFA384x_INTEN_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFDROP)) +#define HFA384x_INTEN_INFDROP_SET(value) ((UINT16)(((UINT16)(value)) << 13)) +#define HFA384x_INTEN_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_INFO)) +#define HFA384x_INTEN_INFO_SET(value) ((UINT16)(((UINT16)(value)) << 7)) +#define HFA384x_INTEN_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_DTIM)) +#define HFA384x_INTEN_DTIM_SET(value) ((UINT16)(((UINT16)(value)) << 5)) +#define HFA384x_INTEN_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_CMD)) +#define HFA384x_INTEN_CMD_SET(value) ((UINT16)(((UINT16)(value)) << 4)) +#define HFA384x_INTEN_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_ALLOC)) +#define HFA384x_INTEN_ALLOC_SET(value) ((UINT16)(((UINT16)(value)) << 3)) +#define HFA384x_INTEN_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TXEXC)) +#define HFA384x_INTEN_TXEXC_SET(value) ((UINT16)(((UINT16)(value)) << 2)) +#define HFA384x_INTEN_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_TX)) +#define HFA384x_INTEN_TX_SET(value) ((UINT16)(((UINT16)(value)) << 1)) +#define HFA384x_INTEN_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_INTEN_RX)) +#define HFA384x_INTEN_RX_SET(value) ((UINT16)(((UINT16)(value)) << 0)) + +#define HFA384x_EVACK_ISTICK(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TICK)) +#define HFA384x_EVACK_TICK_SET(value) ((UINT16)(((UINT16)(value)) << 15)) +#define HFA384x_EVACK_ISWTERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_WTERR)) +#define HFA384x_EVACK_WTERR_SET(value) ((UINT16)(((UINT16)(value)) << 14)) +#define HFA384x_EVACK_ISINFDROP(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFDROP)) +#define HFA384x_EVACK_INFDROP_SET(value) ((UINT16)(((UINT16)(value)) << 13)) +#define HFA384x_EVACK_ISINFO(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_INFO)) +#define HFA384x_EVACK_INFO_SET(value) ((UINT16)(((UINT16)(value)) << 7)) +#define HFA384x_EVACK_ISDTIM(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_DTIM)) +#define HFA384x_EVACK_DTIM_SET(value) ((UINT16)(((UINT16)(value)) << 5)) +#define HFA384x_EVACK_ISCMD(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_CMD)) +#define HFA384x_EVACK_CMD_SET(value) ((UINT16)(((UINT16)(value)) << 4)) +#define HFA384x_EVACK_ISALLOC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_ALLOC)) +#define HFA384x_EVACK_ALLOC_SET(value) ((UINT16)(((UINT16)(value)) << 3)) +#define HFA384x_EVACK_ISTXEXC(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TXEXC)) +#define HFA384x_EVACK_TXEXC_SET(value) ((UINT16)(((UINT16)(value)) << 2)) +#define HFA384x_EVACK_ISTX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_TX)) +#define HFA384x_EVACK_TX_SET(value) ((UINT16)(((UINT16)(value)) << 1)) +#define HFA384x_EVACK_ISRX(value) ((UINT16)(((UINT16)(value)) & HFA384x_EVACK_RX)) +#define HFA384x_EVACK_RX_SET(value) ((UINT16)(((UINT16)(value)) << 0)) + +#define HFA384x_CONTROL_AUXEN_SET(value) ((UINT16)(((UINT16)(value)) << 14)) +#define HFA384x_CONTROL_AUXEN_GET(value) ((UINT16)(((UINT16)(value)) >> 14)) + +/* Byte Order */ +#ifdef __KERNEL__ +#define hfa384x2host_16(n) (__le16_to_cpu((UINT16)(n))) +#define hfa384x2host_32(n) (__le32_to_cpu((UINT32)(n))) +#define host2hfa384x_16(n) (__cpu_to_le16((UINT16)(n))) +#define host2hfa384x_32(n) (__cpu_to_le32((UINT32)(n))) +#endif + +/* Host Maintained State Info */ +#define HFA384x_STATE_PREINIT 0 +#define HFA384x_STATE_INIT 1 +#define HFA384x_STATE_RUNNING 2 + +/*=============================================================*/ +/*------ Types and their related constants --------------------*/ + +#define HFA384x_HOSTAUTHASSOC_HOSTAUTH BIT0 +#define HFA384x_HOSTAUTHASSOC_HOSTASSOC BIT1 + +#define HFA384x_WHAHANDLING_DISABLED 0 +#define HFA384x_WHAHANDLING_PASSTHROUGH BIT1 + +/*-------------------------------------------------------------*/ +/* Commonly used basic types */ +typedef struct hfa384x_bytestr +{ + UINT16 len; + UINT8 data[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_bytestr_t; + +typedef struct hfa384x_bytestr32 +{ + UINT16 len; + UINT8 data[32]; +} __WLAN_ATTRIB_PACK__ hfa384x_bytestr32_t; + +/*-------------------------------------------------------------------- +Configuration Record Structures: + Network Parameters, Static Configuration Entities +--------------------------------------------------------------------*/ +/* Prototype structure: all configuration record structures start with +these members */ + +typedef struct hfa384x_record +{ + UINT16 reclen; + UINT16 rid; +} __WLAN_ATTRIB_PACK__ hfa384x_rec_t; + +typedef struct hfa384x_record16 +{ + UINT16 reclen; + UINT16 rid; + UINT16 val; +} __WLAN_ATTRIB_PACK__ hfa384x_rec16_t; + +typedef struct hfa384x_record32 +{ + UINT16 reclen; + UINT16 rid; + UINT32 val; +} __WLAN_ATTRIB_PACK__ hfa384x_rec32; + +/*-- Hardware/Firmware Component Information ----------*/ +typedef struct hfa384x_compident +{ + UINT16 id; + UINT16 variant; + UINT16 major; + UINT16 minor; +} __WLAN_ATTRIB_PACK__ hfa384x_compident_t; + +typedef struct hfa384x_caplevel +{ + UINT16 role; + UINT16 id; + UINT16 variant; + UINT16 bottom; + UINT16 top; +} __WLAN_ATTRIB_PACK__ hfa384x_caplevel_t; + +/*-- Configuration Record: cnfPortType --*/ +typedef struct hfa384x_cnfPortType +{ + UINT16 cnfPortType; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPortType_t; + +/*-- Configuration Record: cnfOwnMACAddress --*/ +typedef struct hfa384x_cnfOwnMACAddress +{ + UINT8 cnfOwnMACAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnMACAddress_t; + +/*-- Configuration Record: cnfDesiredSSID --*/ +typedef struct hfa384x_cnfDesiredSSID +{ + UINT8 cnfDesiredSSID[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfDesiredSSID_t; + +/*-- Configuration Record: cnfOwnChannel --*/ +typedef struct hfa384x_cnfOwnChannel +{ + UINT16 cnfOwnChannel; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnChannel_t; + +/*-- Configuration Record: cnfOwnSSID --*/ +typedef struct hfa384x_cnfOwnSSID +{ + UINT8 cnfOwnSSID[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnSSID_t; + +/*-- Configuration Record: cnfOwnATIMWindow --*/ +typedef struct hfa384x_cnfOwnATIMWindow +{ + UINT16 cnfOwnATIMWindow; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnATIMWindow_t; + +/*-- Configuration Record: cnfSystemScale --*/ +typedef struct hfa384x_cnfSystemScale +{ + UINT16 cnfSystemScale; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfSystemScale_t; + +/*-- Configuration Record: cnfMaxDataLength --*/ +typedef struct hfa384x_cnfMaxDataLength +{ + UINT16 cnfMaxDataLength; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxDataLength_t; + +/*-- Configuration Record: cnfWDSAddress --*/ +typedef struct hfa384x_cnfWDSAddress +{ + UINT8 cnfWDSAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddress_t; + +/*-- Configuration Record: cnfPMEnabled --*/ +typedef struct hfa384x_cnfPMEnabled +{ + UINT16 cnfPMEnabled; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEnabled_t; + +/*-- Configuration Record: cnfPMEPS --*/ +typedef struct hfa384x_cnfPMEPS +{ + UINT16 cnfPMEPS; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEPS_t; + +/*-- Configuration Record: cnfMulticastReceive --*/ +typedef struct hfa384x_cnfMulticastReceive +{ + UINT16 cnfMulticastReceive; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastReceive_t; + +/*-- Configuration Record: cnfAuthentication --*/ +#define HFA384x_CNFAUTHENTICATION_OPENSYSTEM 0x0001 +#define HFA384x_CNFAUTHENTICATION_SHAREDKEY 0x0002 +#define HFA384x_CNFAUTHENTICATION_LEAP 0x0004 + +/*-- Configuration Record: cnfMaxSleepDuration --*/ +typedef struct hfa384x_cnfMaxSleepDuration +{ + UINT16 cnfMaxSleepDuration; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxSleepDuration_t; + +/*-- Configuration Record: cnfPMHoldoverDuration --*/ +typedef struct hfa384x_cnfPMHoldoverDuration +{ + UINT16 cnfPMHoldoverDuration; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMHoldoverDuration_t; + +/*-- Configuration Record: cnfOwnName --*/ +typedef struct hfa384x_cnfOwnName +{ + UINT8 cnfOwnName[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnName_t; + +/*-- Configuration Record: cnfOwnDTIMPeriod --*/ +typedef struct hfa384x_cnfOwnDTIMPeriod +{ + UINT16 cnfOwnDTIMPeriod; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnDTIMPeriod_t; + +/*-- Configuration Record: cnfWDSAddress --*/ +typedef struct hfa384x_cnfWDSAddressN +{ + UINT8 cnfWDSAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddressN_t; + +/*-- Configuration Record: cnfMulticastPMBuffering --*/ +typedef struct hfa384x_cnfMulticastPMBuffering +{ + UINT16 cnfMulticastPMBuffering; +} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastPMBuffering_t; + +/*-------------------------------------------------------------------- +Configuration Record Structures: + Network Parameters, Dynamic Configuration Entities +--------------------------------------------------------------------*/ + +/*-- Configuration Record: GroupAddresses --*/ +typedef struct hfa384x_GroupAddresses +{ + UINT8 MACAddress[16][6]; +} __WLAN_ATTRIB_PACK__ hfa384x_GroupAddresses_t; + +/*-- Configuration Record: CreateIBSS --*/ +typedef struct hfa384x_CreateIBSS +{ + UINT16 CreateIBSS; +} __WLAN_ATTRIB_PACK__ hfa384x_CreateIBSS_t; + +#define HFA384x_CREATEIBSS_JOINCREATEIBSS 0 +#define HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS 1 +#define HFA384x_CREATEIBSS_JOINIBSS 2 +#define HFA384x_CREATEIBSS_JOINESS_JOINIBSS 3 + +/*-- Configuration Record: FragmentationThreshold --*/ +typedef struct hfa384x_FragmentationThreshold +{ + UINT16 FragmentationThreshold; +} __WLAN_ATTRIB_PACK__ hfa384x_FragmentationThreshold_t; + +/*-- Configuration Record: RTSThreshold --*/ +typedef struct hfa384x_RTSThreshold +{ + UINT16 RTSThreshold; +} __WLAN_ATTRIB_PACK__ hfa384x_RTSThreshold_t; + +/*-- Configuration Record: TxRateControl --*/ +typedef struct hfa384x_TxRateControl +{ + UINT16 TxRateControl; +} __WLAN_ATTRIB_PACK__ hfa384x_TxRateControl_t; + +/*-- Configuration Record: PromiscuousMode --*/ +typedef struct hfa384x_PromiscuousMode +{ + UINT16 PromiscuousMode; +} __WLAN_ATTRIB_PACK__ hfa384x_PromiscuousMode_t; + +/*-- Configuration Record: ScanRequest (data portion only) --*/ +typedef struct hfa384x_ScanRequest_data +{ + UINT16 channelList; + UINT16 txRate; +} __WLAN_ATTRIB_PACK__ hfa384x_ScanRequest_data_t; + +/*-- Configuration Record: HostScanRequest (data portion only) --*/ +typedef struct hfa384x_HostScanRequest_data +{ + UINT16 channelList; + UINT16 txRate; + hfa384x_bytestr32_t ssid; +} __WLAN_ATTRIB_PACK__ hfa384x_HostScanRequest_data_t; + +/*-- Configuration Record: JoinRequest (data portion only) --*/ +typedef struct hfa384x_JoinRequest_data +{ + UINT8 bssid[WLAN_BSSID_LEN]; + UINT16 channel; +} __WLAN_ATTRIB_PACK__ hfa384x_JoinRequest_data_t; + +/*-- Configuration Record: authenticateStation (data portion only) --*/ +typedef struct hfa384x_authenticateStation_data +{ + UINT8 address[WLAN_ADDR_LEN]; + UINT16 status; + UINT16 algorithm; +} __WLAN_ATTRIB_PACK__ hfa384x_authenticateStation_data_t; + +/*-- Configuration Record: associateStation (data portion only) --*/ +typedef struct hfa384x_associateStation_data +{ + UINT8 address[WLAN_ADDR_LEN]; + UINT16 status; + UINT16 type; +} __WLAN_ATTRIB_PACK__ hfa384x_associateStation_data_t; + +/*-- Configuration Record: ChannelInfoRequest (data portion only) --*/ +typedef struct hfa384x_ChannelInfoRequest_data +{ + UINT16 channelList; + UINT16 channelDwellTime; +} __WLAN_ATTRIB_PACK__ hfa384x_ChannelInfoRequest_data_t; + +/*-- Configuration Record: WEPKeyMapping (data portion only) --*/ +typedef struct hfa384x_WEPKeyMapping +{ + UINT8 address[WLAN_ADDR_LEN]; + UINT16 key_index; + UINT8 key[16]; + UINT8 mic_transmit_key[4]; + UINT8 mic_receive_key[4]; +} __WLAN_ATTRIB_PACK__ hfa384x_WEPKeyMapping_t; + +/*-- Configuration Record: WPAData (data portion only) --*/ +typedef struct hfa384x_WPAData +{ + UINT16 datalen; + UINT8 data[0]; // max 80 +} __WLAN_ATTRIB_PACK__ hfa384x_WPAData_t; + +/*-------------------------------------------------------------------- +Configuration Record Structures: Behavior Parameters +--------------------------------------------------------------------*/ + +/*-- Configuration Record: TickTime --*/ +typedef struct hfa384x_TickTime +{ + UINT16 TickTime; +} __WLAN_ATTRIB_PACK__ hfa384x_TickTime_t; + +/*-------------------------------------------------------------------- +Information Record Structures: NIC Information +--------------------------------------------------------------------*/ + +/*-- Information Record: MaxLoadTime --*/ +typedef struct hfa384x_MaxLoadTime +{ + UINT16 MaxLoadTime; +} __WLAN_ATTRIB_PACK__ hfa384x_MaxLoadTime_t; + +/*-- Information Record: DownLoadBuffer --*/ +/* NOTE: The page and offset are in AUX format */ +typedef struct hfa384x_downloadbuffer +{ + UINT16 page; + UINT16 offset; + UINT16 len; +} __WLAN_ATTRIB_PACK__ hfa384x_downloadbuffer_t; + +/*-- Information Record: PRIIdentity --*/ +typedef struct hfa384x_PRIIdentity +{ + UINT16 PRICompID; + UINT16 PRIVariant; + UINT16 PRIMajorVersion; + UINT16 PRIMinorVersion; +} __WLAN_ATTRIB_PACK__ hfa384x_PRIIdentity_t; + +/*-- Information Record: PRISupRange --*/ +typedef struct hfa384x_PRISupRange +{ + UINT16 PRIRole; + UINT16 PRIID; + UINT16 PRIVariant; + UINT16 PRIBottom; + UINT16 PRITop; +} __WLAN_ATTRIB_PACK__ hfa384x_PRISupRange_t; + +/*-- Information Record: CFIActRanges --*/ +typedef struct hfa384x_CFIActRanges +{ + UINT16 CFIRole; + UINT16 CFIID; + UINT16 CFIVariant; + UINT16 CFIBottom; + UINT16 CFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_CFIActRanges_t; + +/*-- Information Record: NICSerialNumber --*/ +typedef struct hfa384x_NICSerialNumber +{ + UINT8 NICSerialNumber[12]; +} __WLAN_ATTRIB_PACK__ hfa384x_NICSerialNumber_t; + +/*-- Information Record: NICIdentity --*/ +typedef struct hfa384x_NICIdentity +{ + UINT16 NICCompID; + UINT16 NICVariant; + UINT16 NICMajorVersion; + UINT16 NICMinorVersion; +} __WLAN_ATTRIB_PACK__ hfa384x_NICIdentity_t; + +/*-- Information Record: MFISupRange --*/ +typedef struct hfa384x_MFISupRange +{ + UINT16 MFIRole; + UINT16 MFIID; + UINT16 MFIVariant; + UINT16 MFIBottom; + UINT16 MFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_MFISupRange_t; + +/*-- Information Record: CFISupRange --*/ +typedef struct hfa384x_CFISupRange +{ + UINT16 CFIRole; + UINT16 CFIID; + UINT16 CFIVariant; + UINT16 CFIBottom; + UINT16 CFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_CFISupRange_t; + +/*-- Information Record: BUILDSEQ:BuildSeq --*/ +typedef struct hfa384x_BuildSeq { + UINT16 primary; + UINT16 secondary; +} __WLAN_ATTRIB_PACK__ hfa384x_BuildSeq_t; + +/*-- Information Record: FWID --*/ +#define HFA384x_FWID_LEN 14 +typedef struct hfa384x_FWID { + UINT8 primary[HFA384x_FWID_LEN]; + UINT8 secondary[HFA384x_FWID_LEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_FWID_t; + +/*-- Information Record: ChannelList --*/ +typedef struct hfa384x_ChannelList +{ + UINT16 ChannelList; +} __WLAN_ATTRIB_PACK__ hfa384x_ChannelList_t; + +/*-- Information Record: RegulatoryDomains --*/ +typedef struct hfa384x_RegulatoryDomains +{ + UINT8 RegulatoryDomains[12]; +} __WLAN_ATTRIB_PACK__ hfa384x_RegulatoryDomains_t; + +/*-- Information Record: TempType --*/ +typedef struct hfa384x_TempType +{ + UINT16 TempType; +} __WLAN_ATTRIB_PACK__ hfa384x_TempType_t; + +/*-- Information Record: CIS --*/ +typedef struct hfa384x_CIS +{ + UINT8 CIS[480]; +} __WLAN_ATTRIB_PACK__ hfa384x_CIS_t; + +/*-- Information Record: STAIdentity --*/ +typedef struct hfa384x_STAIdentity +{ + UINT16 STACompID; + UINT16 STAVariant; + UINT16 STAMajorVersion; + UINT16 STAMinorVersion; +} __WLAN_ATTRIB_PACK__ hfa384x_STAIdentity_t; + +/*-- Information Record: STASupRange --*/ +typedef struct hfa384x_STASupRange +{ + UINT16 STARole; + UINT16 STAID; + UINT16 STAVariant; + UINT16 STABottom; + UINT16 STATop; +} __WLAN_ATTRIB_PACK__ hfa384x_STASupRange_t; + +/*-- Information Record: MFIActRanges --*/ +typedef struct hfa384x_MFIActRanges +{ + UINT16 MFIRole; + UINT16 MFIID; + UINT16 MFIVariant; + UINT16 MFIBottom; + UINT16 MFITop; +} __WLAN_ATTRIB_PACK__ hfa384x_MFIActRanges_t; + +/*-------------------------------------------------------------------- +Information Record Structures: NIC Information +--------------------------------------------------------------------*/ + +/*-- Information Record: PortStatus --*/ +typedef struct hfa384x_PortStatus +{ + UINT16 PortStatus; +} __WLAN_ATTRIB_PACK__ hfa384x_PortStatus_t; + +#define HFA384x_PSTATUS_DISABLED ((UINT16)1) +#define HFA384x_PSTATUS_SEARCHING ((UINT16)2) +#define HFA384x_PSTATUS_CONN_IBSS ((UINT16)3) +#define HFA384x_PSTATUS_CONN_ESS ((UINT16)4) +#define HFA384x_PSTATUS_OUTOFRANGE ((UINT16)5) +#define HFA384x_PSTATUS_CONN_WDS ((UINT16)6) + +/*-- Information Record: CurrentSSID --*/ +typedef struct hfa384x_CurrentSSID +{ + UINT8 CurrentSSID[34]; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentSSID_t; + +/*-- Information Record: CurrentBSSID --*/ +typedef struct hfa384x_CurrentBSSID +{ + UINT8 CurrentBSSID[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBSSID_t; + +/*-- Information Record: commsquality --*/ +typedef struct hfa384x_commsquality +{ + UINT16 CQ_currBSS; + UINT16 ASL_currBSS; + UINT16 ANL_currFC; +} __WLAN_ATTRIB_PACK__ hfa384x_commsquality_t; + +/*-- Information Record: dmbcommsquality --*/ +typedef struct hfa384x_dbmcommsquality +{ + UINT16 CQdbm_currBSS; + UINT16 ASLdbm_currBSS; + UINT16 ANLdbm_currFC; +} __WLAN_ATTRIB_PACK__ hfa384x_dbmcommsquality_t; + +/*-- Information Record: CurrentTxRate --*/ +typedef struct hfa384x_CurrentTxRate +{ + UINT16 CurrentTxRate; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentTxRate_t; + +/*-- Information Record: CurrentBeaconInterval --*/ +typedef struct hfa384x_CurrentBeaconInterval +{ + UINT16 CurrentBeaconInterval; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBeaconInterval_t; + +/*-- Information Record: CurrentScaleThresholds --*/ +typedef struct hfa384x_CurrentScaleThresholds +{ + UINT16 EnergyDetectThreshold; + UINT16 CarrierDetectThreshold; + UINT16 DeferDetectThreshold; + UINT16 CellSearchThreshold; /* Stations only */ + UINT16 DeadSpotThreshold; /* Stations only */ +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentScaleThresholds_t; + +/*-- Information Record: ProtocolRspTime --*/ +typedef struct hfa384x_ProtocolRspTime +{ + UINT16 ProtocolRspTime; +} __WLAN_ATTRIB_PACK__ hfa384x_ProtocolRspTime_t; + +/*-- Information Record: ShortRetryLimit --*/ +typedef struct hfa384x_ShortRetryLimit +{ + UINT16 ShortRetryLimit; +} __WLAN_ATTRIB_PACK__ hfa384x_ShortRetryLimit_t; + +/*-- Information Record: LongRetryLimit --*/ +typedef struct hfa384x_LongRetryLimit +{ + UINT16 LongRetryLimit; +} __WLAN_ATTRIB_PACK__ hfa384x_LongRetryLimit_t; + +/*-- Information Record: MaxTransmitLifetime --*/ +typedef struct hfa384x_MaxTransmitLifetime +{ + UINT16 MaxTransmitLifetime; +} __WLAN_ATTRIB_PACK__ hfa384x_MaxTransmitLifetime_t; + +/*-- Information Record: MaxReceiveLifetime --*/ +typedef struct hfa384x_MaxReceiveLifetime +{ + UINT16 MaxReceiveLifetime; +} __WLAN_ATTRIB_PACK__ hfa384x_MaxReceiveLifetime_t; + +/*-- Information Record: CFPollable --*/ +typedef struct hfa384x_CFPollable +{ + UINT16 CFPollable; +} __WLAN_ATTRIB_PACK__ hfa384x_CFPollable_t; + +/*-- Information Record: AuthenticationAlgorithms --*/ +typedef struct hfa384x_AuthenticationAlgorithms +{ + UINT16 AuthenticationType; + UINT16 TypeEnabled; +} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_t; + +/*-- Information Record: AuthenticationAlgorithms +(data only --*/ +typedef struct hfa384x_AuthenticationAlgorithms_data +{ + UINT16 AuthenticationType; + UINT16 TypeEnabled; +} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_data_t; + +/*-- Information Record: PrivacyOptionImplemented --*/ +typedef struct hfa384x_PrivacyOptionImplemented +{ + UINT16 PrivacyOptionImplemented; +} __WLAN_ATTRIB_PACK__ hfa384x_PrivacyOptionImplemented_t; + +/*-- Information Record: OwnMACAddress --*/ +typedef struct hfa384x_OwnMACAddress +{ + UINT8 OwnMACAddress[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_OwnMACAddress_t; + +/*-- Information Record: PCFInfo --*/ +typedef struct hfa384x_PCFInfo +{ + UINT16 MediumOccupancyLimit; + UINT16 CFPPeriod; + UINT16 CFPMaxDuration; + UINT16 CFPFlags; +} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_t; + +/*-- Information Record: PCFInfo (data portion only) --*/ +typedef struct hfa384x_PCFInfo_data +{ + UINT16 MediumOccupancyLimit; + UINT16 CFPPeriod; + UINT16 CFPMaxDuration; + UINT16 CFPFlags; +} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_data_t; + +/*-------------------------------------------------------------------- +Information Record Structures: Modem Information Records +--------------------------------------------------------------------*/ + +/*-- Information Record: PHYType --*/ +typedef struct hfa384x_PHYType +{ + UINT16 PHYType; +} __WLAN_ATTRIB_PACK__ hfa384x_PHYType_t; + +/*-- Information Record: CurrentChannel --*/ +typedef struct hfa384x_CurrentChannel +{ + UINT16 CurrentChannel; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentChannel_t; + +/*-- Information Record: CurrentPowerState --*/ +typedef struct hfa384x_CurrentPowerState +{ + UINT16 CurrentPowerState; +} __WLAN_ATTRIB_PACK__ hfa384x_CurrentPowerState_t; + +/*-- Information Record: CCAMode --*/ +typedef struct hfa384x_CCAMode +{ + UINT16 CCAMode; +} __WLAN_ATTRIB_PACK__ hfa384x_CCAMode_t; + +/*-- Information Record: SupportedDataRates --*/ +typedef struct hfa384x_SupportedDataRates +{ + UINT8 SupportedDataRates[10]; +} __WLAN_ATTRIB_PACK__ hfa384x_SupportedDataRates_t; + +/*-- Information Record: LFOStatus --*/ +typedef struct hfa384x_LFOStatus +{ + UINT16 TestResults; + UINT16 LFOResult; + UINT16 VRHFOResult; +} __WLAN_ATTRIB_PACK__ hfa384x_LFOStatus_t; + +#define HFA384x_TESTRESULT_ALLPASSED BIT0 +#define HFA384x_TESTRESULT_LFO_FAIL BIT1 +#define HFA384x_TESTRESULT_VR_HF0_FAIL BIT2 +#define HFA384x_HOST_FIRM_COORDINATE BIT7 +#define HFA384x_TESTRESULT_COORDINATE BIT15 + +/*-- Information Record: LEDControl --*/ +typedef struct hfa384x_LEDControl +{ + UINT16 searching_on; + UINT16 searching_off; + UINT16 assoc_on; + UINT16 assoc_off; + UINT16 activity; +} __WLAN_ATTRIB_PACK__ hfa384x_LEDControl_t; + +/*-------------------------------------------------------------------- + FRAME DESCRIPTORS AND FRAME STRUCTURES + +FRAME DESCRIPTORS: Offsets + +---------------------------------------------------------------------- +Control Info (offset 44-51) +--------------------------------------------------------------------*/ +#define HFA384x_FD_STATUS_OFF ((UINT16)0x44) +#define HFA384x_FD_TIME_OFF ((UINT16)0x46) +#define HFA384x_FD_SWSUPPORT_OFF ((UINT16)0x4A) +#define HFA384x_FD_SILENCE_OFF ((UINT16)0x4A) +#define HFA384x_FD_SIGNAL_OFF ((UINT16)0x4B) +#define HFA384x_FD_RATE_OFF ((UINT16)0x4C) +#define HFA384x_FD_RXFLOW_OFF ((UINT16)0x4D) +#define HFA384x_FD_RESERVED_OFF ((UINT16)0x4E) +#define HFA384x_FD_TXCONTROL_OFF ((UINT16)0x50) +/*-------------------------------------------------------------------- +802.11 Header (offset 52-6B) +--------------------------------------------------------------------*/ +#define HFA384x_FD_FRAMECONTROL_OFF ((UINT16)0x52) +#define HFA384x_FD_DURATIONID_OFF ((UINT16)0x54) +#define HFA384x_FD_ADDRESS1_OFF ((UINT16)0x56) +#define HFA384x_FD_ADDRESS2_OFF ((UINT16)0x5C) +#define HFA384x_FD_ADDRESS3_OFF ((UINT16)0x62) +#define HFA384x_FD_SEQCONTROL_OFF ((UINT16)0x68) +#define HFA384x_FD_ADDRESS4_OFF ((UINT16)0x6A) +#define HFA384x_FD_DATALEN_OFF ((UINT16)0x70) +/*-------------------------------------------------------------------- +802.3 Header (offset 72-7F) +--------------------------------------------------------------------*/ +#define HFA384x_FD_DESTADDRESS_OFF ((UINT16)0x72) +#define HFA384x_FD_SRCADDRESS_OFF ((UINT16)0x78) +#define HFA384x_FD_DATALENGTH_OFF ((UINT16)0x7E) + +/*-------------------------------------------------------------------- +FRAME STRUCTURES: Communication Frames +---------------------------------------------------------------------- +Communication Frames: Transmit Frames +--------------------------------------------------------------------*/ +/*-- Communication Frame: Transmit Frame Structure --*/ +typedef struct hfa384x_tx_frame +{ + UINT16 status; + UINT16 reserved1; + UINT16 reserved2; + UINT32 sw_support; + UINT8 tx_retrycount; + UINT8 tx_rate; + UINT16 tx_control; + + /*-- 802.11 Header Information --*/ + + UINT16 frame_control; + UINT16 duration_id; + UINT8 address1[6]; + UINT8 address2[6]; + UINT8 address3[6]; + UINT16 sequence_control; + UINT8 address4[6]; + UINT16 data_len; /* little endian format */ + + /*-- 802.3 Header Information --*/ + + UINT8 dest_addr[6]; + UINT8 src_addr[6]; + UINT16 data_length; /* big endian format */ +} __WLAN_ATTRIB_PACK__ hfa384x_tx_frame_t; +/*-------------------------------------------------------------------- +Communication Frames: Field Masks for Transmit Frames +--------------------------------------------------------------------*/ +/*-- Status Field --*/ +#define HFA384x_TXSTATUS_ACKERR ((UINT16)BIT5) +#define HFA384x_TXSTATUS_FORMERR ((UINT16)BIT3) +#define HFA384x_TXSTATUS_DISCON ((UINT16)BIT2) +#define HFA384x_TXSTATUS_AGEDERR ((UINT16)BIT1) +#define HFA384x_TXSTATUS_RETRYERR ((UINT16)BIT0) +/*-- Transmit Control Field --*/ +#define HFA384x_TX_CFPOLL ((UINT16)BIT12) +#define HFA384x_TX_PRST ((UINT16)BIT11) +#define HFA384x_TX_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8)) +#define HFA384x_TX_NOENCRYPT ((UINT16)BIT7) +#define HFA384x_TX_RETRYSTRAT ((UINT16)(BIT6 | BIT5)) +#define HFA384x_TX_STRUCTYPE ((UINT16)(BIT4 | BIT3)) +#define HFA384x_TX_TXEX ((UINT16)BIT2) +#define HFA384x_TX_TXOK ((UINT16)BIT1) +/*-------------------------------------------------------------------- +Communication Frames: Test/Get/Set Field Values for Transmit Frames +--------------------------------------------------------------------*/ +/*-- Status Field --*/ +#define HFA384x_TXSTATUS_ISERROR(v) \ + (((UINT16)(v))&\ + (HFA384x_TXSTATUS_ACKERR|HFA384x_TXSTATUS_FORMERR|\ + HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\ + HFA384x_TXSTATUS_RETRYERR)) + +#define HFA384x_TXSTATUS_ISACKERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_ACKERR)) +#define HFA384x_TXSTATUS_ISFORMERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_FORMERR)) +#define HFA384x_TXSTATUS_ISDISCON(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_DISCON)) +#define HFA384x_TXSTATUS_ISAGEDERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_AGEDERR)) +#define HFA384x_TXSTATUS_ISRETRYERR(v) ((UINT16)(((UINT16)(v)) & HFA384x_TXSTATUS_RETRYERR)) + +#define HFA384x_TX_GET(v,m,s) ((((UINT16)(v))&((UINT16)(m)))>>((UINT16)(s))) +#define HFA384x_TX_SET(v,m,s) ((((UINT16)(v))<<((UINT16)(s)))&((UINT16)(m))) + +#define HFA384x_TX_CFPOLL_GET(v) HFA384x_TX_GET(v, HFA384x_TX_CFPOLL,12) +#define HFA384x_TX_CFPOLL_SET(v) HFA384x_TX_SET(v, HFA384x_TX_CFPOLL,12) +#define HFA384x_TX_PRST_GET(v) HFA384x_TX_GET(v, HFA384x_TX_PRST,11) +#define HFA384x_TX_PRST_SET(v) HFA384x_TX_SET(v, HFA384x_TX_PRST,11) +#define HFA384x_TX_MACPORT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_MACPORT, 8) +#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8) +#define HFA384x_TX_NOENCRYPT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_NOENCRYPT, 7) +#define HFA384x_TX_NOENCRYPT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_NOENCRYPT, 7) +#define HFA384x_TX_RETRYSTRAT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_RETRYSTRAT, 5) +#define HFA384x_TX_RETRYSTRAT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_RETRYSTRAT, 5) +#define HFA384x_TX_STRUCTYPE_GET(v) HFA384x_TX_GET(v, HFA384x_TX_STRUCTYPE, 3) +#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3) +#define HFA384x_TX_TXEX_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXEX, 2) +#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2) +#define HFA384x_TX_TXOK_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXOK, 1) +#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1) +/*-------------------------------------------------------------------- +Communication Frames: Receive Frames +--------------------------------------------------------------------*/ +/*-- Communication Frame: Receive Frame Structure --*/ +typedef struct hfa384x_rx_frame +{ + /*-- MAC rx descriptor (hfa384x byte order) --*/ + UINT16 status; + UINT32 time; + UINT8 silence; + UINT8 signal; + UINT8 rate; + UINT8 rx_flow; + UINT16 reserved1; + UINT16 reserved2; + + /*-- 802.11 Header Information (802.11 byte order) --*/ + UINT16 frame_control; + UINT16 duration_id; + UINT8 address1[6]; + UINT8 address2[6]; + UINT8 address3[6]; + UINT16 sequence_control; + UINT8 address4[6]; + UINT16 data_len; /* hfa384x (little endian) format */ + + /*-- 802.3 Header Information --*/ + UINT8 dest_addr[6]; + UINT8 src_addr[6]; + UINT16 data_length; /* IEEE? (big endian) format */ +} __WLAN_ATTRIB_PACK__ hfa384x_rx_frame_t; +/*-------------------------------------------------------------------- +Communication Frames: Field Masks for Receive Frames +--------------------------------------------------------------------*/ +/*-- Offsets --------*/ +#define HFA384x_RX_DATA_LEN_OFF ((UINT16)44) +#define HFA384x_RX_80211HDR_OFF ((UINT16)14) +#define HFA384x_RX_DATA_OFF ((UINT16)60) + +/*-- Status Fields --*/ +#define HFA384x_RXSTATUS_MSGTYPE ((UINT16)(BIT15 | BIT14 | BIT13)) +#define HFA384x_RXSTATUS_MACPORT ((UINT16)(BIT10 | BIT9 | BIT8)) +#define HFA384x_RXSTATUS_UNDECR ((UINT16)BIT1) +#define HFA384x_RXSTATUS_FCSERR ((UINT16)BIT0) +/*-------------------------------------------------------------------- +Communication Frames: Test/Get/Set Field Values for Receive Frames +--------------------------------------------------------------------*/ +#define HFA384x_RXSTATUS_MSGTYPE_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MSGTYPE) >> 13)) +#define HFA384x_RXSTATUS_MSGTYPE_SET(value) ((UINT16)(((UINT16)(value)) << 13)) +#define HFA384x_RXSTATUS_MACPORT_GET(value) ((UINT16)((((UINT16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8)) +#define HFA384x_RXSTATUS_MACPORT_SET(value) ((UINT16)(((UINT16)(value)) << 8)) +#define HFA384x_RXSTATUS_ISUNDECR(value) ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_UNDECR)) +#define HFA384x_RXSTATUS_ISFCSERR(value) ((UINT16)(((UINT16)(value)) & HFA384x_RXSTATUS_FCSERR)) +/*-------------------------------------------------------------------- + FRAME STRUCTURES: Information Types and Information Frame Structures +---------------------------------------------------------------------- +Information Types +--------------------------------------------------------------------*/ +#define HFA384x_IT_HANDOVERADDR ((UINT16)0xF000UL) +#define HFA384x_IT_HANDOVERDEAUTHADDRESS ((UINT16)0xF001UL)//AP 1.3.7 +#define HFA384x_IT_COMMTALLIES ((UINT16)0xF100UL) +#define HFA384x_IT_SCANRESULTS ((UINT16)0xF101UL) +#define HFA384x_IT_CHINFORESULTS ((UINT16)0xF102UL) +#define HFA384x_IT_HOSTSCANRESULTS ((UINT16)0xF103UL) +#define HFA384x_IT_LINKSTATUS ((UINT16)0xF200UL) +#define HFA384x_IT_ASSOCSTATUS ((UINT16)0xF201UL) +#define HFA384x_IT_AUTHREQ ((UINT16)0xF202UL) +#define HFA384x_IT_PSUSERCNT ((UINT16)0xF203UL) +#define HFA384x_IT_KEYIDCHANGED ((UINT16)0xF204UL) +#define HFA384x_IT_ASSOCREQ ((UINT16)0xF205UL) +#define HFA384x_IT_MICFAILURE ((UINT16)0xF206UL) + +/*-------------------------------------------------------------------- +Information Frames Structures +---------------------------------------------------------------------- +Information Frames: Notification Frame Structures +--------------------------------------------------------------------*/ +/*-- Notification Frame,MAC Mgmt: Handover Address --*/ +typedef struct hfa384x_HandoverAddr +{ + UINT16 framelen; + UINT16 infotype; + UINT8 handover_addr[WLAN_BSSID_LEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_HandoverAddr_t; + +/*-- Inquiry Frame, Diagnose: Communication Tallies --*/ +typedef struct hfa384x_CommTallies16 +{ + UINT16 txunicastframes; + UINT16 txmulticastframes; + UINT16 txfragments; + UINT16 txunicastoctets; + UINT16 txmulticastoctets; + UINT16 txdeferredtrans; + UINT16 txsingleretryframes; + UINT16 txmultipleretryframes; + UINT16 txretrylimitexceeded; + UINT16 txdiscards; + UINT16 rxunicastframes; + UINT16 rxmulticastframes; + UINT16 rxfragments; + UINT16 rxunicastoctets; + UINT16 rxmulticastoctets; + UINT16 rxfcserrors; + UINT16 rxdiscardsnobuffer; + UINT16 txdiscardswrongsa; + UINT16 rxdiscardswepundecr; + UINT16 rxmsginmsgfrag; + UINT16 rxmsginbadmsgfrag; +} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies16_t; + +typedef struct hfa384x_CommTallies32 +{ + UINT32 txunicastframes; + UINT32 txmulticastframes; + UINT32 txfragments; + UINT32 txunicastoctets; + UINT32 txmulticastoctets; + UINT32 txdeferredtrans; + UINT32 txsingleretryframes; + UINT32 txmultipleretryframes; + UINT32 txretrylimitexceeded; + UINT32 txdiscards; + UINT32 rxunicastframes; + UINT32 rxmulticastframes; + UINT32 rxfragments; + UINT32 rxunicastoctets; + UINT32 rxmulticastoctets; + UINT32 rxfcserrors; + UINT32 rxdiscardsnobuffer; + UINT32 txdiscardswrongsa; + UINT32 rxdiscardswepundecr; + UINT32 rxmsginmsgfrag; + UINT32 rxmsginbadmsgfrag; +} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies32_t; + +/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/ +typedef struct hfa384x_ScanResultSub +{ + UINT16 chid; + UINT16 anl; + UINT16 sl; + UINT8 bssid[WLAN_BSSID_LEN]; + UINT16 bcnint; + UINT16 capinfo; + hfa384x_bytestr32_t ssid; + UINT8 supprates[10]; /* 802.11 info element */ + UINT16 proberesp_rate; +} __WLAN_ATTRIB_PACK__ hfa384x_ScanResultSub_t; + +typedef struct hfa384x_ScanResult +{ + UINT16 rsvd; + UINT16 scanreason; + hfa384x_ScanResultSub_t + result[HFA384x_SCANRESULT_MAX]; +} __WLAN_ATTRIB_PACK__ hfa384x_ScanResult_t; + +/*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/ +typedef struct hfa384x_ChInfoResultSub +{ + UINT16 chid; + UINT16 anl; + UINT16 pnl; + UINT16 active; +} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResultSub_t; + +#define HFA384x_CHINFORESULT_BSSACTIVE BIT0 +#define HFA384x_CHINFORESULT_PCFACTIVE BIT1 + +typedef struct hfa384x_ChInfoResult +{ + UINT16 scanchannels; + hfa384x_ChInfoResultSub_t + result[HFA384x_CHINFORESULT_MAX]; +} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResult_t; + +/*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/ +typedef struct hfa384x_HScanResultSub +{ + UINT16 chid; + UINT16 anl; + UINT16 sl; + UINT8 bssid[WLAN_BSSID_LEN]; + UINT16 bcnint; + UINT16 capinfo; + hfa384x_bytestr32_t ssid; + UINT8 supprates[10]; /* 802.11 info element */ + UINT16 proberesp_rate; + UINT16 atim; +} __WLAN_ATTRIB_PACK__ hfa384x_HScanResultSub_t; + +typedef struct hfa384x_HScanResult +{ + UINT16 nresult; + UINT16 rsvd; + hfa384x_HScanResultSub_t + result[HFA384x_HSCANRESULT_MAX]; +} __WLAN_ATTRIB_PACK__ hfa384x_HScanResult_t; + +/*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/ + +#define HFA384x_LINK_NOTCONNECTED ((UINT16)0) +#define HFA384x_LINK_CONNECTED ((UINT16)1) +#define HFA384x_LINK_DISCONNECTED ((UINT16)2) +#define HFA384x_LINK_AP_CHANGE ((UINT16)3) +#define HFA384x_LINK_AP_OUTOFRANGE ((UINT16)4) +#define HFA384x_LINK_AP_INRANGE ((UINT16)5) +#define HFA384x_LINK_ASSOCFAIL ((UINT16)6) + +typedef struct hfa384x_LinkStatus +{ + UINT16 linkstatus; +} __WLAN_ATTRIB_PACK__ hfa384x_LinkStatus_t; + + +/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/ + +#define HFA384x_ASSOCSTATUS_STAASSOC ((UINT16)1) +#define HFA384x_ASSOCSTATUS_REASSOC ((UINT16)2) +#define HFA384x_ASSOCSTATUS_DISASSOC ((UINT16)3) +#define HFA384x_ASSOCSTATUS_ASSOCFAIL ((UINT16)4) +#define HFA384x_ASSOCSTATUS_AUTHFAIL ((UINT16)5) + +typedef struct hfa384x_AssocStatus +{ + UINT16 assocstatus; + UINT8 sta_addr[WLAN_ADDR_LEN]; + /* old_ap_addr is only valid if assocstatus == 2 */ + UINT8 old_ap_addr[WLAN_ADDR_LEN]; + UINT16 reason; + UINT16 reserved; +} __WLAN_ATTRIB_PACK__ hfa384x_AssocStatus_t; + +/*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/ + +typedef struct hfa384x_AuthRequest +{ + UINT8 sta_addr[WLAN_ADDR_LEN]; + UINT16 algorithm; +} __WLAN_ATTRIB_PACK__ hfa384x_AuthReq_t; + +/*-- Unsolicited Frame, MAC Mgmt: AssocRequest (AP Only) --*/ + +typedef struct hfa384x_AssocRequest +{ + UINT8 sta_addr[WLAN_ADDR_LEN]; + UINT16 type; + UINT8 wpa_data[80]; +} __WLAN_ATTRIB_PACK__ hfa384x_AssocReq_t; + + +#define HFA384x_ASSOCREQ_TYPE_ASSOC 0 +#define HFA384x_ASSOCREQ_TYPE_REASSOC 1 + +/*-- Unsolicited Frame, MAC Mgmt: MIC Failure (AP Only) --*/ + +typedef struct hfa384x_MicFailure +{ + UINT8 sender[WLAN_ADDR_LEN]; + UINT8 dest[WLAN_ADDR_LEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_MicFailure_t; + +/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/ + +typedef struct hfa384x_PSUserCount +{ + UINT16 usercnt; +} __WLAN_ATTRIB_PACK__ hfa384x_PSUserCount_t; + +typedef struct hfa384x_KeyIDChanged +{ + UINT8 sta_addr[WLAN_ADDR_LEN]; + UINT16 keyid; +} __WLAN_ATTRIB_PACK__ hfa384x_KeyIDChanged_t; + +/*-- Collection of all Inf frames ---------------*/ +typedef union hfa384x_infodata { + hfa384x_CommTallies16_t commtallies16; + hfa384x_CommTallies32_t commtallies32; + hfa384x_ScanResult_t scanresult; + hfa384x_ChInfoResult_t chinforesult; + hfa384x_HScanResult_t hscanresult; + hfa384x_LinkStatus_t linkstatus; + hfa384x_AssocStatus_t assocstatus; + hfa384x_AuthReq_t authreq; + hfa384x_PSUserCount_t psusercnt; + hfa384x_KeyIDChanged_t keyidchanged; +} __WLAN_ATTRIB_PACK__ hfa384x_infodata_t; + +typedef struct hfa384x_InfFrame +{ + UINT16 framelen; + UINT16 infotype; + hfa384x_infodata_t info; +} __WLAN_ATTRIB_PACK__ hfa384x_InfFrame_t; + +#if (WLAN_HOSTIF == WLAN_USB) +/*-------------------------------------------------------------------- +USB Packet structures and constants. +--------------------------------------------------------------------*/ + +/* Should be sent to the ctrlout endpoint */ +#define HFA384x_USB_ENBULKIN 6 + +/* Should be sent to the bulkout endpoint */ +#define HFA384x_USB_TXFRM 0 +#define HFA384x_USB_CMDREQ 1 +#define HFA384x_USB_WRIDREQ 2 +#define HFA384x_USB_RRIDREQ 3 +#define HFA384x_USB_WMEMREQ 4 +#define HFA384x_USB_RMEMREQ 5 + +/* Received from the bulkin endpoint */ +#define HFA384x_USB_ISFRM(a) (!((a) & 0x8000)) +#define HFA384x_USB_ISTXFRM(a) (((a) & 0x9000) == 0x1000) +#define HFA384x_USB_ISRXFRM(a) (!((a) & 0x9000)) +#define HFA384x_USB_INFOFRM 0x8000 +#define HFA384x_USB_CMDRESP 0x8001 +#define HFA384x_USB_WRIDRESP 0x8002 +#define HFA384x_USB_RRIDRESP 0x8003 +#define HFA384x_USB_WMEMRESP 0x8004 +#define HFA384x_USB_RMEMRESP 0x8005 +#define HFA384x_USB_BUFAVAIL 0x8006 +#define HFA384x_USB_ERROR 0x8007 + +/*------------------------------------*/ +/* Request (bulk OUT) packet contents */ + +typedef struct hfa384x_usb_txfrm { + hfa384x_tx_frame_t desc; + UINT8 data[WLAN_DATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_txfrm_t; + +typedef struct hfa384x_usb_cmdreq { + UINT16 type; + UINT16 cmd; + UINT16 parm0; + UINT16 parm1; + UINT16 parm2; + UINT8 pad[54]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdreq_t; + +typedef struct hfa384x_usb_wridreq { + UINT16 type; + UINT16 frmlen; + UINT16 rid; + UINT8 data[HFA384x_RIDDATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_wridreq_t; + +typedef struct hfa384x_usb_rridreq { + UINT16 type; + UINT16 frmlen; + UINT16 rid; + UINT8 pad[58]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridreq_t; + +typedef struct hfa384x_usb_wmemreq { + UINT16 type; + UINT16 frmlen; + UINT16 offset; + UINT16 page; + UINT8 data[HFA384x_USB_RWMEM_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_wmemreq_t; + +typedef struct hfa384x_usb_rmemreq { + UINT16 type; + UINT16 frmlen; + UINT16 offset; + UINT16 page; + UINT8 pad[56]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemreq_t; + +/*------------------------------------*/ +/* Response (bulk IN) packet contents */ + +typedef struct hfa384x_usb_rxfrm { + hfa384x_rx_frame_t desc; + UINT8 data[WLAN_DATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rxfrm_t; + +typedef struct hfa384x_usb_infofrm { + UINT16 type; + hfa384x_InfFrame_t info; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_infofrm_t; + +typedef struct hfa384x_usb_statusresp { + UINT16 type; + UINT16 status; + UINT16 resp0; + UINT16 resp1; + UINT16 resp2; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdresp_t; + +typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t; + +typedef struct hfa384x_usb_rridresp { + UINT16 type; + UINT16 frmlen; + UINT16 rid; + UINT8 data[HFA384x_RIDDATA_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridresp_t; + +typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t; + +typedef struct hfa384x_usb_rmemresp { + UINT16 type; + UINT16 frmlen; + UINT8 data[HFA384x_USB_RWMEM_MAXLEN]; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemresp_t; + +typedef struct hfa384x_usb_bufavail { + UINT16 type; + UINT16 frmlen; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_bufavail_t; + +typedef struct hfa384x_usb_error { + UINT16 type; + UINT16 errortype; +} __WLAN_ATTRIB_PACK__ hfa384x_usb_error_t; + +/*----------------------------------------------------------*/ +/* Unions for packaging all the known packet types together */ + +typedef union hfa384x_usbout { + UINT16 type; + hfa384x_usb_txfrm_t txfrm; + hfa384x_usb_cmdreq_t cmdreq; + hfa384x_usb_wridreq_t wridreq; + hfa384x_usb_rridreq_t rridreq; + hfa384x_usb_wmemreq_t wmemreq; + hfa384x_usb_rmemreq_t rmemreq; +} __WLAN_ATTRIB_PACK__ hfa384x_usbout_t; + +typedef union hfa384x_usbin { + UINT16 type; + hfa384x_usb_rxfrm_t rxfrm; + hfa384x_usb_txfrm_t txfrm; + hfa384x_usb_infofrm_t infofrm; + hfa384x_usb_cmdresp_t cmdresp; + hfa384x_usb_wridresp_t wridresp; + hfa384x_usb_rridresp_t rridresp; + hfa384x_usb_wmemresp_t wmemresp; + hfa384x_usb_rmemresp_t rmemresp; + hfa384x_usb_bufavail_t bufavail; + hfa384x_usb_error_t usberror; + UINT8 boguspad[3000]; +} __WLAN_ATTRIB_PACK__ hfa384x_usbin_t; + +#endif /* WLAN_USB */ + +/*-------------------------------------------------------------------- +PD record structures. +--------------------------------------------------------------------*/ + +typedef struct hfa384x_pdr_pcb_partnum +{ + UINT8 num[8]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_partnum_t; + +typedef struct hfa384x_pdr_pcb_tracenum +{ + UINT8 num[8]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_tracenum_t; + +typedef struct hfa384x_pdr_nic_serial +{ + UINT8 num[12]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_serial_t; + +typedef struct hfa384x_pdr_mkk_measurements +{ + double carrier_freq; + double occupied_band; + double power_density; + double tx_spur_f1; + double tx_spur_f2; + double tx_spur_f3; + double tx_spur_f4; + double tx_spur_l1; + double tx_spur_l2; + double tx_spur_l3; + double tx_spur_l4; + double rx_spur_f1; + double rx_spur_f2; + double rx_spur_l1; + double rx_spur_l2; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_measurements_t; + +typedef struct hfa384x_pdr_nic_ramsize +{ + UINT8 size[12]; /* units of KB */ +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_ramsize_t; + +typedef struct hfa384x_pdr_mfisuprange +{ + UINT16 id; + UINT16 variant; + UINT16 bottom; + UINT16 top; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mfisuprange_t; + +typedef struct hfa384x_pdr_cfisuprange +{ + UINT16 id; + UINT16 variant; + UINT16 bottom; + UINT16 top; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_cfisuprange_t; + +typedef struct hfa384x_pdr_nicid +{ + UINT16 id; + UINT16 variant; + UINT16 major; + UINT16 minor; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nicid_t; + + +typedef struct hfa384x_pdr_refdac_measurements +{ + UINT16 value[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_measurements_t; + +typedef struct hfa384x_pdr_vgdac_measurements +{ + UINT16 value[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_measurements_t; + +typedef struct hfa384x_pdr_level_comp_measurements +{ + UINT16 value[0]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_compc_measurements_t; + +typedef struct hfa384x_pdr_mac_address +{ + UINT8 addr[6]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mac_address_t; + +typedef struct hfa384x_pdr_mkk_callname +{ + UINT8 callname[8]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_callname_t; + +typedef struct hfa384x_pdr_regdomain +{ + UINT16 numdomains; + UINT16 domain[5]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_regdomain_t; + +typedef struct hfa384x_pdr_allowed_channel +{ + UINT16 ch_bitmap; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_allowed_channel_t; + +typedef struct hfa384x_pdr_default_channel +{ + UINT16 channel; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_default_channel_t; + +typedef struct hfa384x_pdr_privacy_option +{ + UINT16 available; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_privacy_option_t; + +typedef struct hfa384x_pdr_temptype +{ + UINT16 type; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_temptype_t; + +typedef struct hfa384x_pdr_refdac_setup +{ + UINT16 ch_value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_setup_t; + +typedef struct hfa384x_pdr_vgdac_setup +{ + UINT16 ch_value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_setup_t; + +typedef struct hfa384x_pdr_level_comp_setup +{ + UINT16 ch_value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_comp_setup_t; + +typedef struct hfa384x_pdr_trimdac_setup +{ + UINT16 trimidac; + UINT16 trimqdac; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_trimdac_setup_t; + +typedef struct hfa384x_pdr_ifr_setting +{ + UINT16 value[3]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_ifr_setting_t; + +typedef struct hfa384x_pdr_rfr_setting +{ + UINT16 value[3]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_rfr_setting_t; + +typedef struct hfa384x_pdr_hfa3861_baseline +{ + UINT16 value[50]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_baseline_t; + +typedef struct hfa384x_pdr_hfa3861_shadow +{ + UINT32 value[32]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_shadow_t; + +typedef struct hfa384x_pdr_hfa3861_ifrf +{ + UINT32 value[20]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_ifrf_t; + +typedef struct hfa384x_pdr_hfa3861_chcalsp +{ + UINT16 value[14]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcalsp_t; + +typedef struct hfa384x_pdr_hfa3861_chcali +{ + UINT16 value[17]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcali_t; + +typedef struct hfa384x_pdr_hfa3861_nic_config +{ + UINT16 config_bitmap; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_config_t; + +typedef struct hfa384x_pdr_hfo_delay +{ + UINT8 hfo_delay; +} __WLAN_ATTRIB_PACK__ hfa384x_hfo_delay_t; + +typedef struct hfa384x_pdr_hfa3861_manf_testsp +{ + UINT16 value[30]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testsp_t; + +typedef struct hfa384x_pdr_hfa3861_manf_testi +{ + UINT16 value[30]; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testi_t; + +typedef struct hfa384x_end_of_pda +{ + UINT16 crc; +} __WLAN_ATTRIB_PACK__ hfa384x_pdr_end_of_pda_t; + +typedef struct hfa384x_pdrec +{ + UINT16 len; /* in words */ + UINT16 code; + union pdr { + hfa384x_pdr_pcb_partnum_t pcb_partnum; + hfa384x_pdr_pcb_tracenum_t pcb_tracenum; + hfa384x_pdr_nic_serial_t nic_serial; + hfa384x_pdr_mkk_measurements_t mkk_measurements; + hfa384x_pdr_nic_ramsize_t nic_ramsize; + hfa384x_pdr_mfisuprange_t mfisuprange; + hfa384x_pdr_cfisuprange_t cfisuprange; + hfa384x_pdr_nicid_t nicid; + hfa384x_pdr_refdac_measurements_t refdac_measurements; + hfa384x_pdr_vgdac_measurements_t vgdac_measurements; + hfa384x_pdr_level_compc_measurements_t level_compc_measurements; + hfa384x_pdr_mac_address_t mac_address; + hfa384x_pdr_mkk_callname_t mkk_callname; + hfa384x_pdr_regdomain_t regdomain; + hfa384x_pdr_allowed_channel_t allowed_channel; + hfa384x_pdr_default_channel_t default_channel; + hfa384x_pdr_privacy_option_t privacy_option; + hfa384x_pdr_temptype_t temptype; + hfa384x_pdr_refdac_setup_t refdac_setup; + hfa384x_pdr_vgdac_setup_t vgdac_setup; + hfa384x_pdr_level_comp_setup_t level_comp_setup; + hfa384x_pdr_trimdac_setup_t trimdac_setup; + hfa384x_pdr_ifr_setting_t ifr_setting; + hfa384x_pdr_rfr_setting_t rfr_setting; + hfa384x_pdr_hfa3861_baseline_t hfa3861_baseline; + hfa384x_pdr_hfa3861_shadow_t hfa3861_shadow; + hfa384x_pdr_hfa3861_ifrf_t hfa3861_ifrf; + hfa384x_pdr_hfa3861_chcalsp_t hfa3861_chcalsp; + hfa384x_pdr_hfa3861_chcali_t hfa3861_chcali; + hfa384x_pdr_nic_config_t nic_config; + hfa384x_hfo_delay_t hfo_delay; + hfa384x_pdr_hfa3861_manf_testsp_t hfa3861_manf_testsp; + hfa384x_pdr_hfa3861_manf_testi_t hfa3861_manf_testi; + hfa384x_pdr_end_of_pda_t end_of_pda; + + } data; +} __WLAN_ATTRIB_PACK__ hfa384x_pdrec_t; + + +#ifdef __KERNEL__ +/*-------------------------------------------------------------------- +--- MAC state structure, argument to all functions -- +--- Also, a collection of support types -- +--------------------------------------------------------------------*/ +typedef struct hfa384x_statusresult +{ + UINT16 status; + UINT16 resp0; + UINT16 resp1; + UINT16 resp2; +} hfa384x_cmdresult_t; + +#if (WLAN_HOSTIF == WLAN_USB) + +/* USB Control Exchange (CTLX): + * A queue of the structure below is maintained for all of the + * Request/Response type USB packets supported by Prism2. + */ +/* The following hfa384x_* structures are arguments to + * the usercb() for the different CTLX types. + */ +typedef hfa384x_cmdresult_t hfa384x_wridresult_t; +typedef hfa384x_cmdresult_t hfa384x_wmemresult_t; + +typedef struct hfa384x_rridresult +{ + UINT16 rid; + const void *riddata; + UINT riddata_len; +} hfa384x_rridresult_t; + +enum ctlx_state { + CTLX_START = 0, /* Start state, not queued */ + + CTLX_COMPLETE, /* CTLX successfully completed */ + CTLX_REQ_FAILED, /* OUT URB completed w/ error */ + + CTLX_PENDING, /* Queued, data valid */ + CTLX_REQ_SUBMITTED, /* OUT URB submitted */ + CTLX_REQ_COMPLETE, /* OUT URB complete */ + CTLX_RESP_COMPLETE /* IN URB received */ +}; +typedef enum ctlx_state CTLX_STATE; + +struct hfa384x_usbctlx; +struct hfa384x; + +typedef void (*ctlx_cmdcb_t)( struct hfa384x*, const struct hfa384x_usbctlx* ); + +typedef void (*ctlx_usercb_t)( + struct hfa384x *hw, + void *ctlxresult, + void *usercb_data); + +typedef struct hfa384x_usbctlx +{ + struct list_head list; + + size_t outbufsize; + hfa384x_usbout_t outbuf; /* pkt buf for OUT */ + hfa384x_usbin_t inbuf; /* pkt buf for IN(a copy) */ + + CTLX_STATE state; /* Tracks running state */ + + struct completion done; + volatile int reapable; /* Food for the reaper task */ + + ctlx_cmdcb_t cmdcb; /* Async command callback */ + ctlx_usercb_t usercb; /* Async user callback, */ + void *usercb_data; /* at CTLX completion */ + + int variant; /* Identifies cmd variant */ +} hfa384x_usbctlx_t; + +typedef struct hfa384x_usbctlxq +{ + spinlock_t lock; + struct list_head pending; + struct list_head active; + struct list_head completing; + struct list_head reapable; +} hfa384x_usbctlxq_t; +#endif + +typedef struct hfa484x_metacmd +{ + UINT16 cmd; + + UINT16 parm0; + UINT16 parm1; + UINT16 parm2; + +#if 0 //XXX cmd irq stuff + UINT16 bulkid; /* what RID/FID to copy down. */ + int bulklen; /* how much to copy from BAP */ + char *bulkdata; /* And to where? */ +#endif + + hfa384x_cmdresult_t result; +} hfa384x_metacmd_t; + +#define MAX_PRISM2_GRP_ADDR 16 +#define MAX_GRP_ADDR 32 +#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */ + +#define MM_SAT_PCF (BIT14) +#define MM_GCSD_PCF (BIT15) +#define MM_GCSD_PCF_EB (BIT14 | BIT15) + +#define WLAN_STATE_STOPPED 0 /* Network is not active. */ +#define WLAN_STATE_STARTED 1 /* Network has been started. */ + +#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */ +#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */ +#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */ +#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */ +#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */ +#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */ + +/* XXX These are going away ASAP */ +typedef struct prism2sta_authlist +{ + UINT cnt; + UINT8 addr[WLAN_AUTH_MAX][WLAN_ADDR_LEN]; + UINT8 assoc[WLAN_AUTH_MAX]; +} prism2sta_authlist_t; + +typedef struct prism2sta_accesslist +{ + UINT modify; + UINT cnt; + UINT8 addr[WLAN_ACCESS_MAX][WLAN_ADDR_LEN]; + UINT cnt1; + UINT8 addr1[WLAN_ACCESS_MAX][WLAN_ADDR_LEN]; +} prism2sta_accesslist_t; + +typedef struct hfa384x +{ +#if (WLAN_HOSTIF != WLAN_USB) + /* Resource config */ + UINT32 iobase; + char __iomem *membase; + UINT32 irq; +#else + /* USB support data */ + struct usb_device *usb; + struct urb rx_urb; + struct sk_buff *rx_urb_skb; + struct urb tx_urb; + struct urb ctlx_urb; + hfa384x_usbout_t txbuff; + hfa384x_usbctlxq_t ctlxq; + struct timer_list reqtimer; + struct timer_list resptimer; + + struct timer_list throttle; + + struct tasklet_struct reaper_bh; + struct tasklet_struct completion_bh; + + struct work_struct usb_work; + + unsigned long usb_flags; +#define THROTTLE_RX 0 +#define THROTTLE_TX 1 +#define WORK_RX_HALT 2 +#define WORK_TX_HALT 3 +#define WORK_RX_RESUME 4 +#define WORK_TX_RESUME 5 + + unsigned short req_timer_done:1; + unsigned short resp_timer_done:1; + + int endp_in; + int endp_out; +#endif /* !USB */ + +#if (WLAN_HOSTIF == WLAN_PCMCIA) +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,16) + struct pcmcia_device *pdev; +#else + dev_link_t *link; +#endif + dev_node_t node; +#endif + + int sniff_fcs; + int sniff_channel; + int sniff_truncate; + int sniffhdr; + + wait_queue_head_t cmdq; /* wait queue itself */ + + /* Controller state */ + UINT32 state; + UINT32 isap; + UINT8 port_enabled[HFA384x_NUMPORTS_MAX]; +#if (WLAN_HOSTIF != WLAN_USB) + UINT auxen; + UINT isram16; +#endif /* !USB */ + + /* Download support */ + UINT dlstate; + hfa384x_downloadbuffer_t bufinfo; + UINT16 dltimeout; + +#if (WLAN_HOSTIF != WLAN_USB) + spinlock_t cmdlock; + volatile int cmdflag; /* wait queue flag */ + hfa384x_metacmd_t *cmddata; /* for our async callback */ + + /* BAP support */ + spinlock_t baplock; + struct tasklet_struct bap_tasklet; + + /* MAC buffer ids */ + UINT16 txfid_head; + UINT16 txfid_tail; + UINT txfid_N; + UINT16 txfid_queue[HFA384x_DRVR_FIDSTACKLEN_MAX]; + UINT16 infofid; + struct semaphore infofid_sem; +#endif /* !USB */ + + int scanflag; /* to signal scan comlete */ + int join_ap; /* are we joined to a specific ap */ + int join_retries; /* number of join retries till we fail */ + hfa384x_JoinRequest_data_t joinreq; /* join request saved data */ + + wlandevice_t *wlandev; + /* Timer to allow for the deferred processing of linkstatus messages */ + struct work_struct link_bh; + + struct work_struct commsqual_bh; + hfa384x_commsquality_t qual; + struct timer_list commsqual_timer; + + UINT16 link_status; + UINT16 link_status_new; + struct sk_buff_head authq; + + /* And here we have stuff that used to be in priv */ + + /* State variables */ + UINT presniff_port_type; + UINT16 presniff_wepflags; + UINT32 dot11_desired_bss_type; + int ap; /* AP flag: 0 - Station, 1 - Access Point. */ + + int dbmadjust; + + /* Group Addresses - right now, there are up to a total + of MAX_GRP_ADDR group addresses */ + UINT8 dot11_grp_addr[MAX_GRP_ADDR][WLAN_ADDR_LEN]; + UINT dot11_grpcnt; + + /* Component Identities */ + hfa384x_compident_t ident_nic; + hfa384x_compident_t ident_pri_fw; + hfa384x_compident_t ident_sta_fw; + hfa384x_compident_t ident_ap_fw; + UINT16 mm_mods; + + /* Supplier compatibility ranges */ + hfa384x_caplevel_t cap_sup_mfi; + hfa384x_caplevel_t cap_sup_cfi; + hfa384x_caplevel_t cap_sup_pri; + hfa384x_caplevel_t cap_sup_sta; + hfa384x_caplevel_t cap_sup_ap; + + /* Actor compatibility ranges */ + hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */ + hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */ + hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */ + hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */ + hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */ + + UINT32 psusercount; /* Power save user count. */ + hfa384x_CommTallies32_t tallies; /* Communication tallies. */ + UINT8 comment[WLAN_COMMENT_MAX+1]; /* User comment */ + + /* Channel Info request results (AP only) */ + struct { + atomic_t done; + UINT8 count; + hfa384x_ChInfoResult_t results; + } channel_info; + + hfa384x_InfFrame_t *scanresults; + + + prism2sta_authlist_t authlist; /* Authenticated station list. */ + UINT accessmode; /* Access mode. */ + prism2sta_accesslist_t allow; /* Allowed station list. */ + prism2sta_accesslist_t deny; /* Denied station list. */ + +} hfa384x_t; + +/*=============================================================*/ +/*--- Function Declarations -----------------------------------*/ +/*=============================================================*/ +#if (WLAN_HOSTIF == WLAN_USB) +void +hfa384x_create( + hfa384x_t *hw, + struct usb_device *usb); +#else +void +hfa384x_create( + hfa384x_t *hw, + UINT irq, + UINT32 iobase, + UINT8 __iomem *membase); +#endif + +void hfa384x_destroy(hfa384x_t *hw); + +irqreturn_t +hfa384x_interrupt(int irq, void *dev_id PT_REGS); +int +hfa384x_corereset( hfa384x_t *hw, int holdtime, int settletime, int genesis); +int +hfa384x_drvr_chinforesults( hfa384x_t *hw); +int +hfa384x_drvr_commtallies( hfa384x_t *hw); +int +hfa384x_drvr_disable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_drvr_enable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_drvr_flashdl_enable(hfa384x_t *hw); +int +hfa384x_drvr_flashdl_disable(hfa384x_t *hw); +int +hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len); +int +hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len); +int +hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr); +int +hfa384x_drvr_hostscanresults( hfa384x_t *hw); +int +hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd); +int +hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 address, UINT32 *result); +int +hfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 address, UINT32 data); +int +hfa384x_drvr_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr); +int +hfa384x_drvr_ramdl_disable(hfa384x_t *hw); +int +hfa384x_drvr_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len); +int +hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len); +int +hfa384x_drvr_scanresults( hfa384x_t *hw); + +int +hfa384x_drvr_setconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len); + +static inline int +hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val) +{ + int result = 0; + result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16)); + if ( result == 0 ) { + *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val)); + } + return result; +} + +static inline int +hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val) +{ + int result = 0; + + result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32)); + if ( result == 0 ) { + *((UINT32*)val) = hfa384x2host_32(*((UINT32*)val)); + } + + return result; +} + +static inline int +hfa384x_drvr_setconfig16(hfa384x_t *hw, UINT16 rid, UINT16 val) +{ + UINT16 value = host2hfa384x_16(val); + return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); +} + +static inline int +hfa384x_drvr_setconfig32(hfa384x_t *hw, UINT16 rid, UINT32 val) +{ + UINT32 value = host2hfa384x_32(val); + return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); +} + +#if (WLAN_HOSTIF == WLAN_USB) +int +hfa384x_drvr_getconfig_async(hfa384x_t *hw, + UINT16 rid, + ctlx_usercb_t usercb, + void *usercb_data); + +int +hfa384x_drvr_setconfig_async(hfa384x_t *hw, + UINT16 rid, + void *buf, + UINT16 len, + ctlx_usercb_t usercb, + void *usercb_data); +#else +static inline int +hfa384x_drvr_setconfig_async(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len, + void *ptr1, void *ptr2) +{ + (void)ptr1; + (void)ptr2; + return hfa384x_drvr_setconfig(hw, rid, buf, len); +} +#endif + +static inline int +hfa384x_drvr_setconfig16_async(hfa384x_t *hw, UINT16 rid, UINT16 val) +{ + UINT16 value = host2hfa384x_16(val); + return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), + NULL , NULL); +} + +static inline int +hfa384x_drvr_setconfig32_async(hfa384x_t *hw, UINT16 rid, UINT32 val) +{ + UINT32 value = host2hfa384x_32(val); + return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), + NULL , NULL); +} + + +int +hfa384x_drvr_start(hfa384x_t *hw); +int +hfa384x_drvr_stop(hfa384x_t *hw); +int +hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep); +void +hfa384x_tx_timeout(wlandevice_t *wlandev); + +int +hfa384x_cmd_initialize(hfa384x_t *hw); +int +hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport); +int +hfa384x_cmd_diagnose(hfa384x_t *hw); +int +hfa384x_cmd_allocate(hfa384x_t *hw, UINT16 len); +int +hfa384x_cmd_transmit(hfa384x_t *hw, UINT16 reclaim, UINT16 qos, UINT16 fid); +int +hfa384x_cmd_clearpersist(hfa384x_t *hw, UINT16 fid); +int +hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, void *buf, UINT16 len); +int +hfa384x_cmd_inquire(hfa384x_t *hw, UINT16 fid); +int +hfa384x_cmd_access(hfa384x_t *hw, UINT16 write, UINT16 rid, void *buf, UINT16 len); +int +hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable); +int +hfa384x_cmd_download( + hfa384x_t *hw, + UINT16 mode, + UINT16 lowaddr, + UINT16 highaddr, + UINT16 codelen); +int +hfa384x_cmd_aux_enable(hfa384x_t *hw, int force); +int +hfa384x_cmd_aux_disable(hfa384x_t *hw); +int +hfa384x_copy_from_bap( + hfa384x_t *hw, + UINT16 bap, + UINT16 id, + UINT16 offset, + void *buf, + UINT len); +int +hfa384x_copy_to_bap( + hfa384x_t *hw, + UINT16 bap, + UINT16 id, + UINT16 offset, + void *buf, + UINT len); +void +hfa384x_copy_from_aux( + hfa384x_t *hw, + UINT32 cardaddr, + UINT32 auxctl, + void *buf, + UINT len); +void +hfa384x_copy_to_aux( + hfa384x_t *hw, + UINT32 cardaddr, + UINT32 auxctl, + void *buf, + UINT len); + +#if (WLAN_HOSTIF != WLAN_USB) + +/* + HFA384x is a LITTLE ENDIAN part. + + the get/setreg functions implicitly byte-swap the data to LE. + the _noswap variants do not perform a byte-swap on the data. +*/ + +static inline UINT16 +__hfa384x_getreg(hfa384x_t *hw, UINT reg); + +static inline void +__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg); + +static inline UINT16 +__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg); + +static inline void +__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg); + +#ifdef REVERSE_ENDIAN +#define hfa384x_getreg __hfa384x_getreg_noswap +#define hfa384x_setreg __hfa384x_setreg_noswap +#define hfa384x_getreg_noswap __hfa384x_getreg +#define hfa384x_setreg_noswap __hfa384x_setreg +#else +#define hfa384x_getreg __hfa384x_getreg +#define hfa384x_setreg __hfa384x_setreg +#define hfa384x_getreg_noswap __hfa384x_getreg_noswap +#define hfa384x_setreg_noswap __hfa384x_setreg_noswap +#endif + +/*---------------------------------------------------------------- +* hfa384x_getreg +* +* Retrieve the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* NOTE: This function returns the value in HOST ORDER!!!!!! +* +* Arguments: +* hw MAC part structure +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Value from the register in HOST ORDER!!!! +----------------------------------------------------------------*/ +static inline UINT16 +__hfa384x_getreg(hfa384x_t *hw, UINT reg) +{ +/* printk(KERN_DEBUG "Reading from 0x%0x\n", hw->membase + reg); */ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + return wlan_inw_le16_to_cpu(hw->iobase+reg); +#elif (WLAN_HOSTIF == WLAN_PCI) + return __le16_to_cpu(readw(hw->membase + reg)); +#endif +} + +/*---------------------------------------------------------------- +* hfa384x_setreg +* +* Set the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* NOTE: This function assumes the value is in HOST ORDER!!!!!! +* +* Arguments: +* hw MAC part structure +* val Value, in HOST ORDER!!, to put in the register +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Nothing +----------------------------------------------------------------*/ +static inline void +__hfa384x_setreg(hfa384x_t *hw, UINT16 val, UINT reg) +{ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + wlan_outw_cpu_to_le16( val, hw->iobase + reg); + return; +#elif (WLAN_HOSTIF == WLAN_PCI) + writew(__cpu_to_le16(val), hw->membase + reg); + return; +#endif +} + + +/*---------------------------------------------------------------- +* hfa384x_getreg_noswap +* +* Retrieve the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* +* Arguments: +* hw MAC part structure +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Value from the register. +----------------------------------------------------------------*/ +static inline UINT16 +__hfa384x_getreg_noswap(hfa384x_t *hw, UINT reg) +{ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + return wlan_inw(hw->iobase+reg); +#elif (WLAN_HOSTIF == WLAN_PCI) + return readw(hw->membase + reg); +#endif +} + + +/*---------------------------------------------------------------- +* hfa384x_setreg_noswap +* +* Set the value of one of the MAC registers. Done here +* because different PRISM2 MAC parts use different buses and such. +* +* Arguments: +* hw MAC part structure +* val Value to put in the register +* reg Register identifier (offset for I/O based i/f) +* +* Returns: +* Nothing +----------------------------------------------------------------*/ +static inline void +__hfa384x_setreg_noswap(hfa384x_t *hw, UINT16 val, UINT reg) +{ +#if ((WLAN_HOSTIF == WLAN_PCMCIA) || (WLAN_HOSTIF == WLAN_PLX)) + wlan_outw( val, hw->iobase + reg); + return; +#elif (WLAN_HOSTIF == WLAN_PCI) + writew(val, hw->membase + reg); + return; +#endif +} + + +static inline void hfa384x_events_all(hfa384x_t *hw) +{ + hfa384x_setreg(hw, + HFA384x_INT_NORMAL +#ifdef CMD_IRQ + | HFA384x_INTEN_CMD_SET(1) +#endif + , + HFA384x_INTEN); + +} + +static inline void hfa384x_events_nobap(hfa384x_t *hw) +{ + hfa384x_setreg(hw, + (HFA384x_INT_NORMAL & ~HFA384x_INT_BAP_OP) +#ifdef CMD_IRQ + | HFA384x_INTEN_CMD_SET(1) +#endif + , + HFA384x_INTEN); + +} + +#endif /* WLAN_HOSTIF != WLAN_USB */ +#endif /* __KERNEL__ */ + +#endif /* _HFA384x_H */ --- linux-2.6.28.orig/ubuntu/misc/media/Kconfig +++ linux-2.6.28/ubuntu/misc/media/Kconfig @@ -0,0 +1,13 @@ +menu "Media related drivers" + +config SND_BTSCO + tristate "Bluetooth SCO Sound driver" + default m + depends on SND && BT + +config USB_OV511_NEW + tristate "OmniVision OV511 Camera-to-USB Bridge Driver" + default m + depends on USB && VIDEO_V4L2 + +endmenu --- linux-2.6.28.orig/ubuntu/misc/media/Makefile +++ linux-2.6.28/ubuntu/misc/media/Makefile @@ -0,0 +1,4 @@ +# + +#obj-$(CONFIG_SND_BTSCO) += snd-bt-sco.o +obj-$(CONFIG_USB_OV511_NEW) += ov511/ --- linux-2.6.28.orig/ubuntu/misc/media/snd-bt-sco.c +++ linux-2.6.28/ubuntu/misc/media/snd-bt-sco.c @@ -0,0 +1,1231 @@ +/* + * Bluetooth SCO soundcard + * Copyright (c) 2003, 2004 by Jonathan Paisley + * + * Based on dummy.c which is + * Copyright (c) by Jaroslav Kysela + * + * 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 + * + */ + + +/* note: defining these two independently is not tested, + * thus not recommended + */ + +/* enable dynamic compression */ +#define DYNAMIC_COMPRESSION +/* enable automatic endianness fixup */ +#define AUTO_FIXUP_BYTESHIFT + + +#ifdef DYNAMIC_COMPRESSION +/* Autoadjust mic at most this often in 1/8000s */ +#define GRABSAMPLES 400 +/* Maximum push for the mike 16= 1:1 - default 20:1 = 320 */ +#define COMPRESSION_MAX_16 320 +/* Minimum push for the mike 1= 1:16 */ +#define COMPRESSION_MIN_16 1 +#endif + +#define chip_t snd_card_bt_sco_t + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// this was ostensibly for newer kernels but fails on 2.6.19.2 +#if 0 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18) +#include +#endif +#endif +#include +#include +#include +#include +#include +#define SNDRV_GET_ID +#include + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) +#include +#else +#define mutex semaphore +#define mutex_init init_MUTEX +#define mutex_lock down +#define mutex_unlock up +#endif + +#ifndef SNDRV_HWDEP_IFACE_BLUETOOTH +#define SNDRV_HWDEP_IFACE_BLUETOOTH (SNDRV_HWDEP_IFACE_EMUX_WAVETABLE + 1) +#endif + +#ifndef SNDRV_HWDEP_IFACE_BT_SCO +#define SNDRV_HWDEP_IFACE_BT_SCO (SNDRV_HWDEP_IFACE_BLUETOOTH + 1) +#endif + +#define SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET _IOW ('H', 0x10, int) +#define SNDRV_BT_SCO_IOCTL_REQ_INFO _IO ('H', 0x11) + +static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */ + +#define MOD_REVISION "$Revision: 1.19 $"; +static char *mod_revision = MOD_REVISION; + +MODULE_AUTHOR("Jonathan Paisley "); +MODULE_DESCRIPTION("Bluetooth SCO Headset Soundcard"); +MODULE_VERSION(MOD_REVISION); +MODULE_LICENSE("GPL"); +MODULE_SUPPORTED_DEVICE("{{ALSA,Bluetooth SCO Soundcard}}"); + +module_param_array(index, int, NULL, 0444); +MODULE_PARM_DESC(index, "Index value for Bluetooth SCO Headset Soundcard."); + +#undef dprintk +#if 1 +#define dprintk(fmt...) printk(KERN_INFO "snd-bt-sco: " fmt) +#else +#define dprintk(fmt...) do {} while(0) +#endif + +#define MAX_BUFFER_SIZE (32*1024) + +#define MIXER_ADDR_MASTER 0 +#define MIXER_ADDR_MIC 1 +#define MIXER_ADDR_LAST 1 + +#define MIXER_MASK_MASTER 1 +#define MIXER_MASK_MIC 2 + +#define MIXER_MIN_VOLUME 1 +#define MIXER_MAX_VOLUME 15 + +struct snd_card_bt_sco_pcm; + +typedef struct snd_card_bt_sco_info { + int mixer_volume[MIXER_ADDR_LAST + 1]; + int playback_count, capture_count; +} snd_card_bt_sco_info_t; + +typedef struct snd_card_bt_sco { + struct snd_card *card; + spinlock_t mixer_lock; + int mixer_volume[MIXER_ADDR_LAST + 1]; +#ifdef DYNAMIC_COMPRESSION + struct snd_kcontrol *mixer_controls[MIXER_ADDR_LAST + 2 + 1]; /* also loopback and agc */ +#else + struct snd_kcontrol *mixer_controls[MIXER_ADDR_LAST + 2 ]; /* also loopback */ +#endif + volatile int loopback; +#ifdef DYNAMIC_COMPRESSION + volatile int agc; +#endif + atomic_t playback_count, capture_count; + volatile int count_changed; + spinlock_t count_changed_lock; + + spinlock_t mixer_changed_lock; + volatile int mixer_changed; + wait_queue_head_t hwdep_wait; + + struct task_struct *thread; + + struct mutex thread_sem; + + volatile struct socket *sco_sock; + struct mutex sock_sem; + wait_queue_head_t wait; + + struct mutex playback_sem; + struct snd_card_bt_sco_pcm *playback; + struct mutex capture_sem; + struct snd_card_bt_sco_pcm *capture; +} snd_card_bt_sco_t; + +typedef struct snd_card_bt_sco_pcm { + snd_card_bt_sco_t *bt_sco; + spinlock_t lock; + unsigned int pcm_size; + unsigned int pcm_count; + unsigned int pcm_bps; /* bytes per second */ + unsigned int pcm_irq_pos; /* IRQ position */ + unsigned int pcm_buf_pos; /* position in buffer */ + struct snd_pcm_substream *substream; +} snd_card_bt_sco_pcm_t; + +static struct snd_card *snd_bt_sco_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR; + +static int snd_card_bt_sco_playback_trigger(struct snd_pcm_substream * + substream, int cmd) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("playback_trigger %d\n", cmd); + + if (cmd == SNDRV_PCM_TRIGGER_START) { + bt_sco->playback = bspcm; + dprintk("setting playback to bspcm\n"); + } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { + bt_sco->playback = NULL; + dprintk("setting playback to NULL\n"); + } else { + return -EINVAL; + } + return 0; +} + +static int snd_card_bt_sco_capture_trigger(struct snd_pcm_substream * + substream, int cmd) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("capture_trigger %d\n", cmd); + + if (cmd == SNDRV_PCM_TRIGGER_START) { + bt_sco->capture = bspcm; + dprintk("setting capture to bspcm\n"); + } else if (cmd == SNDRV_PCM_TRIGGER_STOP) { + bt_sco->capture = NULL; + dprintk("setting capture to NULL\n"); + } else { + return -EINVAL; + } + return 0; +} + +static int snd_card_bt_sco_pcm_prepare(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + unsigned int bps; + + bps = runtime->rate * runtime->channels; + bps *= snd_pcm_format_width(runtime->format); + bps /= 8; + if (bps <= 0) + return -EINVAL; + bspcm->pcm_bps = bps; + bspcm->pcm_size = snd_pcm_lib_buffer_bytes(substream); + bspcm->pcm_count = snd_pcm_lib_period_bytes(substream); + bspcm->pcm_irq_pos = 0; + bspcm->pcm_buf_pos = 0; + dprintk("prepare ok bps: %d size: %d count: %d\n", + bspcm->pcm_bps, bspcm->pcm_size, bspcm->pcm_count); + return 0; +} + +static int snd_card_bt_sco_playback_prepare(struct snd_pcm_substream * substream) +{ + return snd_card_bt_sco_pcm_prepare(substream); +} + +static int snd_card_bt_sco_capture_prepare(struct snd_pcm_substream * substream) +{ + dprintk("capture_prepare\n"); + return snd_card_bt_sco_pcm_prepare(substream); +} + +static void snd_card_bt_sco_pcm_receive(snd_card_bt_sco_pcm_t * bspcm, + unsigned char *data, unsigned int len) +{ + unsigned long flags; + unsigned int oldptr; + + spin_lock_irqsave(&bspcm->lock, flags); + oldptr = bspcm->pcm_buf_pos; + bspcm->pcm_irq_pos += len; + bspcm->pcm_buf_pos += len; + bspcm->pcm_buf_pos %= bspcm->pcm_size; + spin_unlock_irqrestore(&bspcm->lock, flags); + /* copy a data chunk */ + if (oldptr + len > bspcm->pcm_size) { + unsigned int cnt = bspcm->pcm_size - oldptr; + memcpy(bspcm->substream->runtime->dma_area + oldptr, data, cnt); + memcpy(bspcm->substream->runtime->dma_area, data + cnt, + len - cnt); + } else { + memcpy(bspcm->substream->runtime->dma_area + oldptr, data, len); + } + /* update the pointer, call callback if necessary */ + spin_lock_irqsave(&bspcm->lock, flags); + if (bspcm->pcm_irq_pos >= bspcm->pcm_count) { + bspcm->pcm_irq_pos %= bspcm->pcm_count; + spin_unlock_irqrestore(&bspcm->lock, flags); + snd_pcm_period_elapsed(bspcm->substream); + } else + spin_unlock_irqrestore(&bspcm->lock, flags); + +} + +static void snd_card_bt_sco_pcm_send(snd_card_bt_sco_pcm_t * bspcm, + unsigned char *data, unsigned int len) +{ + unsigned long flags; + unsigned int oldptr; + + spin_lock_irqsave(&bspcm->lock, flags); + oldptr = bspcm->pcm_buf_pos; + bspcm->pcm_irq_pos += len; + bspcm->pcm_buf_pos += len; + bspcm->pcm_buf_pos %= bspcm->pcm_size; + spin_unlock_irqrestore(&bspcm->lock, flags); + /* copy a data chunk */ + if (oldptr + len > bspcm->pcm_size) { + unsigned int cnt = bspcm->pcm_size - oldptr; + memcpy(data, bspcm->substream->runtime->dma_area + oldptr, cnt); + memcpy(data + cnt, bspcm->substream->runtime->dma_area, + len - cnt); + } else { + memcpy(data, bspcm->substream->runtime->dma_area + oldptr, len); + } + /* update the pointer, call callback if necessary */ + spin_lock_irqsave(&bspcm->lock, flags); + if (bspcm->pcm_irq_pos >= bspcm->pcm_count) { + bspcm->pcm_irq_pos %= bspcm->pcm_count; + spin_unlock_irqrestore(&bspcm->lock, flags); + snd_pcm_period_elapsed(bspcm->substream); + } else + spin_unlock_irqrestore(&bspcm->lock, flags); +} + +static snd_pcm_uframes_t +snd_card_bt_sco_playback_pointer(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + + return bytes_to_frames(runtime, bspcm->pcm_buf_pos); +} + +static snd_pcm_uframes_t +snd_card_bt_sco_capture_pointer(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + + return bytes_to_frames(runtime, bspcm->pcm_buf_pos); +} + +static struct snd_pcm_hardware snd_card_bt_sco_playback = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000, + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = MAX_BUFFER_SIZE, + .period_bytes_min = 24, + .period_bytes_max = MAX_BUFFER_SIZE, + .periods_min = 1, + .periods_max = 4 * 8000 / 24, + .fifo_size = 0, +}; + +static struct snd_pcm_hardware snd_card_bt_sco_capture = { + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_8000, + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = MAX_BUFFER_SIZE, + .period_bytes_min = 24, + .period_bytes_max = MAX_BUFFER_SIZE, + .periods_min = 1, + .periods_max = 4 * 8000 / 24, + .fifo_size = 0, +}; + +static void snd_card_bt_sco_runtime_free(struct snd_pcm_runtime * runtime) +{ + snd_card_bt_sco_pcm_t *bspcm = runtime->private_data; + kfree(bspcm); +} + +static int snd_card_bt_sco_playback_open(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("playback_open\n"); + + bspcm = kmalloc(sizeof(*bspcm), GFP_KERNEL); + if (bspcm == NULL) + return -ENOMEM; + memset(bspcm, 0, sizeof(*bspcm)); + if ((runtime->dma_area = + snd_malloc_pages(MAX_BUFFER_SIZE, GFP_KERNEL)) == NULL) { + kfree(bspcm); + return -ENOMEM; + } + runtime->dma_bytes = MAX_BUFFER_SIZE; + spin_lock_init(&bspcm->lock); + bspcm->substream = substream; + runtime->private_data = bspcm; + runtime->private_free = snd_card_bt_sco_runtime_free; + runtime->hw = snd_card_bt_sco_playback; + + atomic_inc(&bt_sco->playback_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + return 0; +} + +static int snd_card_bt_sco_capture_open(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_pcm_t *bspcm; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + dprintk("capture_open\n"); + + bspcm = kmalloc(sizeof(*bspcm), GFP_KERNEL); + if (bspcm == NULL) + return -ENOMEM; + memset(bspcm, 0, sizeof(*bspcm)); + if ((runtime->dma_area = + snd_malloc_pages(MAX_BUFFER_SIZE, GFP_KERNEL)) == NULL) { + kfree(bspcm); + return -ENOMEM; + } + runtime->dma_bytes = MAX_BUFFER_SIZE; + memset(runtime->dma_area, 0, runtime->dma_bytes); + spin_lock_init(&bspcm->lock); + bspcm->substream = substream; + runtime->private_data = bspcm; + runtime->private_free = snd_card_bt_sco_runtime_free; + runtime->hw = snd_card_bt_sco_capture; + + atomic_inc(&bt_sco->capture_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + return 0; +} + +static int snd_card_bt_sco_playback_close(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + snd_card_bt_sco_t *bt_sco = snd_pcm_substream_chip(substream); + + snd_assert(bt_sco->playback == NULL,; + ); + + /* Ensure any references to this in our thread have finished */ + mutex_lock(&bt_sco->playback_sem); + mutex_unlock(&bt_sco->playback_sem); + + atomic_dec(&bt_sco->playback_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + snd_free_pages(runtime->dma_area, runtime->dma_bytes); + return 0; +} + +static int snd_card_bt_sco_capture_close(struct snd_pcm_substream * substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_card_bt_sco *bt_sco = + (struct snd_card_bt_sco *)substream->private_data; + + snd_assert(bt_sco->capture == NULL,; + ); + + /* Ensure any references to this in our thread have finished */ + mutex_lock(&bt_sco->capture_sem); + mutex_unlock(&bt_sco->capture_sem); + + atomic_dec(&bt_sco->capture_count); + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + + snd_free_pages(runtime->dma_area, runtime->dma_bytes); + return 0; +} + +static struct snd_pcm_ops snd_card_bt_sco_playback_ops = { + .open = snd_card_bt_sco_playback_open, + .close = snd_card_bt_sco_playback_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = snd_card_bt_sco_playback_prepare, + .trigger = snd_card_bt_sco_playback_trigger, + .pointer = snd_card_bt_sco_playback_pointer, +}; + +static struct snd_pcm_ops snd_card_bt_sco_capture_ops = { + .open = snd_card_bt_sco_capture_open, + .close = snd_card_bt_sco_capture_close, + .ioctl = snd_pcm_lib_ioctl, + .prepare = snd_card_bt_sco_capture_prepare, + .trigger = snd_card_bt_sco_capture_trigger, + .pointer = snd_card_bt_sco_capture_pointer, +}; + +static int __init snd_card_bt_sco_pcm(snd_card_bt_sco_t * bt_sco) +{ + struct snd_pcm *pcm; + int err; + + if ((err = + snd_pcm_new(bt_sco->card, "Bluetooth SCO PCM", 0, 1, 1, &pcm)) < 0) + return err; + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + &snd_card_bt_sco_playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + &snd_card_bt_sco_capture_ops); + pcm->private_data = bt_sco; + pcm->info_flags = 0; + strcpy(pcm->name, "BT SCO PCM"); + return 0; +} + +#define BT_SCO_VOLUME(xname, xindex, addr) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ + .info = snd_bt_sco_volume_info, \ + .get = snd_bt_sco_volume_get, .put = snd_bt_sco_volume_put, \ + .private_value = addr } + +static int snd_bt_sco_volume_info(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_info * uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = MIXER_MIN_VOLUME; + uinfo->value.integer.max = MIXER_MAX_VOLUME; + return 0; +} + +static int snd_bt_sco_volume_get(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int addr = kcontrol->private_value; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + ucontrol->value.integer.value[0] = bt_sco->mixer_volume[addr]; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return 0; +} + +static int snd_bt_sco_volume_put(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int changed, addr = kcontrol->private_value; + int vol; + + vol = ucontrol->value.integer.value[0]; + if (vol < MIXER_MIN_VOLUME) + vol = MIXER_MIN_VOLUME; + if (vol > MIXER_MAX_VOLUME) + vol = MIXER_MAX_VOLUME; + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + changed = bt_sco->mixer_volume[addr] != vol; + bt_sco->mixer_volume[addr] = vol; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + if (changed) { + spin_lock_irqsave(&bt_sco->mixer_changed_lock, flags); + bt_sco->mixer_changed = 1; + spin_unlock_irqrestore(&bt_sco->mixer_changed_lock, flags); + wake_up(&bt_sco->hwdep_wait); + } + return changed; +} + +static int snd_bt_sco_boolean_info(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_info * uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +static int snd_bt_sco_loopback_get(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + ucontrol->value.integer.value[0] = bt_sco->loopback; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return 0; +} + +static int snd_bt_sco_loopback_put(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int changed; + int loopback; + + loopback = !!ucontrol->value.integer.value[0]; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + changed = bt_sco->loopback != loopback; + bt_sco->loopback = loopback; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return changed; +} + +#ifdef DYNAMIC_COMPRESSION +static int snd_bt_sco_agc_get(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + ucontrol->value.integer.value[0] = bt_sco->agc; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return 0; +} + +static int snd_bt_sco_agc_put(struct snd_kcontrol * kcontrol, + struct snd_ctl_elem_value * ucontrol) +{ + snd_card_bt_sco_t *bt_sco = snd_kcontrol_chip(kcontrol); + unsigned long flags; + int changed; + int agc; + + agc = !!ucontrol->value.integer.value[0]; + + spin_lock_irqsave(&bt_sco->mixer_lock, flags); + changed = bt_sco->agc != agc; + bt_sco->agc = agc; + spin_unlock_irqrestore(&bt_sco->mixer_lock, flags); + return changed; +} +#endif + +#define BT_SCO_CONTROLS (sizeof(snd_bt_sco_controls)/sizeof(struct snd_kcontrol_new)) + +static struct snd_kcontrol_new snd_bt_sco_controls[] = { + BT_SCO_VOLUME("Master Volume", 0, MIXER_ADDR_MASTER), + BT_SCO_VOLUME("Mic Volume", 0, MIXER_ADDR_MIC), + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Loopback Switch", + .index = 0, + .info = snd_bt_sco_boolean_info, + .get = snd_bt_sco_loopback_get, + .put = snd_bt_sco_loopback_put, + } +#ifdef DYNAMIC_COMPRESSION + , + {.iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "AGC Switch", + .index = 0, + .info = snd_bt_sco_boolean_info, + .get = snd_bt_sco_agc_get, + .put = snd_bt_sco_agc_put, + } +#endif +}; + +int __init snd_card_bt_sco_new_mixer(snd_card_bt_sco_t * bt_sco) +{ + struct snd_card *card = bt_sco->card; + + unsigned int idx; + int err; + + snd_assert(bt_sco != NULL, return -EINVAL); + spin_lock_init(&bt_sco->mixer_lock); + strcpy(card->mixername, "BT Headset Mixer"); + + for (idx = 0; idx < BT_SCO_CONTROLS; idx++) { + bt_sco->mixer_controls[idx] = + snd_ctl_new1(&snd_bt_sco_controls[idx], bt_sco); + + if ((err = snd_ctl_add(card, bt_sco->mixer_controls[idx])) < 0) + return err; + } + return 0; +} + +static int snd_card_bt_open(struct snd_hwdep * hw, struct file *file) +{ + return 0; +} + +static int snd_card_bt_release(struct snd_hwdep * hw, struct file *file) +{ + return 0; +} + +static int snd_card_bt_ioctl(struct snd_hwdep * hw, struct file *file, + unsigned int cmd, unsigned long arg) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + struct socket *sock; + int err = -ENOTTY; + int fd = arg; + + switch (cmd) { + case SNDRV_BT_SCO_IOCTL_SET_SCO_SOCKET: + err = 0; + /* Interrupt any socket operations, so that we may + * change the socket */ + mutex_lock(&bt_sco->sock_sem); + kthread_stop(bt_sco->thread); + if (bt_sco->sco_sock) { + dprintk("Disposing of previous socket count %d\n", + file_count(bt_sco->sco_sock->file)); + /* Extra brackets needed here since sockfd_put is a poorly implemented macro */ + sockfd_put(((struct socket *)bt_sco->sco_sock)); + + bt_sco->sco_sock = NULL; + } + + if (fd >= 0) { + err = -EINVAL; + sock = sockfd_lookup(fd, &err); + if (sock) { + if (sock->sk->sk_family == PF_BLUETOOTH && + sock->sk->sk_protocol == BTPROTO_SCO) { + bt_sco->sco_sock = sock; + wake_up(&bt_sco->wait); + err = 0; + } else { + dprintk + ("Not a bluetooth SCO socket %d:%d\n", + sock->sk->sk_family, + sock->sk->sk_protocol); + sockfd_put(sock); + } + } + } + mutex_unlock(&bt_sco->sock_sem); + break; + case SNDRV_BT_SCO_IOCTL_REQ_INFO: + spin_lock_irq(&bt_sco->count_changed_lock); + bt_sco->count_changed = 1; + spin_unlock_irq(&bt_sco->count_changed_lock); + wake_up(&bt_sco->hwdep_wait); + break; + } + return err; +} + +static long snd_card_bt_write(struct snd_hwdep * hw, const char *buf, long count, + loff_t * offset) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + int mixer_volume[MIXER_ADDR_LAST + 1]; + int retval; + int i; + + if (count != sizeof(mixer_volume)) + return -EINVAL; + + if (copy_from_user(mixer_volume, buf, sizeof(mixer_volume))) + return -EFAULT; + + retval = sizeof(mixer_volume); + + spin_lock_irq(&bt_sco->mixer_lock); + for (i = 0; i <= MIXER_ADDR_LAST; i++) { + int vol = mixer_volume[i]; + if (vol > MIXER_MAX_VOLUME) + vol = MIXER_MAX_VOLUME; + if (vol < MIXER_MIN_VOLUME) + vol = MIXER_MIN_VOLUME; + if (bt_sco->mixer_volume[i] != vol) { + bt_sco->mixer_volume[i] = vol; + snd_ctl_notify(bt_sco->card, + SNDRV_CTL_EVENT_MASK_VALUE, + &bt_sco->mixer_controls[i]->id); + } + } + spin_unlock_irq(&bt_sco->mixer_lock); + + return retval; +} + +static long snd_card_bt_read(struct snd_hwdep * hw, char *buf, long count, + loff_t * offset) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + DECLARE_WAITQUEUE(wait, current); + ssize_t retval; + int changed; + snd_card_bt_sco_info_t infobuf; + + if (count < sizeof(bt_sco->mixer_volume)) + return -EINVAL; + + add_wait_queue(&bt_sco->hwdep_wait, &wait); + current->state = TASK_INTERRUPTIBLE; + do { + changed = 0; + spin_lock_irq(&bt_sco->mixer_changed_lock); + if(bt_sco->mixer_changed) + changed = 1; + bt_sco->mixer_changed = 0; + spin_unlock_irq(&bt_sco->mixer_changed_lock); + + spin_lock_irq(&bt_sco->count_changed_lock); + if(bt_sco->count_changed) + changed = 1; + bt_sco->count_changed = 0; + spin_unlock_irq(&bt_sco->count_changed_lock); + + if (changed != 0) + break; + + if (signal_pending(current)) { + retval = -ERESTARTSYS; + goto out; + } + schedule(); + } while (1); + + memcpy(infobuf.mixer_volume, bt_sco->mixer_volume, sizeof(infobuf.mixer_volume)); + infobuf.playback_count = atomic_read(&bt_sco->playback_count); + infobuf.capture_count = atomic_read(&bt_sco->capture_count); + + if (copy_to_user + (buf, &infobuf, sizeof(infobuf))) + retval = -EFAULT; + else + retval = sizeof(infobuf); + + out: + current->state = TASK_RUNNING; + remove_wait_queue(&bt_sco->hwdep_wait, &wait); + return retval; +} + +static unsigned int snd_card_bt_poll(struct snd_hwdep * hw, + struct file *file, poll_table * wait) +{ + snd_card_bt_sco_t *bt_sco = hw->card->private_data; + int ret; + + poll_wait(file, &bt_sco->hwdep_wait, wait); + + ret = 0; + spin_lock_irq(&bt_sco->mixer_changed_lock); + if(bt_sco->mixer_changed) + ret |= POLLIN | POLLRDNORM; + spin_unlock_irq(&bt_sco->mixer_changed_lock); + + spin_lock_irq(&bt_sco->count_changed_lock); + if(bt_sco->count_changed) + ret |= POLLIN | POLLRDNORM; + spin_unlock_irq(&bt_sco->count_changed_lock); + + return ret; +} + +static int snd_card_bt_sco_thread(void *data) +{ + struct snd_card *card = (struct snd_card *) data; + snd_card_bt_sco_t *bt_sco = card->private_data; + struct socket *sock; + int len; +#define BUF_SIZE 256 + unsigned char buf[BUF_SIZE]; + struct msghdr msg; + struct iovec iov; +#if defined(DYNAMIC_COMPRESSION) || defined(AUTO_FIXUP_BYTESHIFT) + int i; +#endif +#ifdef DYNAMIC_COMPRESSION + static int factor=16; + static int maxvalsmoothed=0; + static int maxvalgrablen=GRABSAMPLES; /* adjust volume at most 4 times/second */ +#endif +#ifdef AUTO_FIXUP_BYTESHIFT + static int shift=0; + static unsigned char lastbyte; +#endif + + set_freezable(); + + dprintk("snd-bt-scod thread starting\n"); + mutex_unlock(&bt_sco->thread_sem); + + do { + /* This may be woken up by a wake_up() when + * a new socket is installed, or by a signal. + * Signals are sent to terminate the thread, + * in which case thread_exit is set, and to force + * recvmesg() to wake up (from the ioctl handler) + */ + wait_event_freezable(bt_sco->wait, bt_sco->sco_sock || kthread_should_stop()); + + mutex_lock(&bt_sco->sock_sem); + sock = (struct socket *)bt_sco->sco_sock; + if (sock) + get_file(sock->file); + mutex_unlock(&bt_sco->sock_sem); + + if (!sock) + continue; + + /* We have a socket, let's read from it and write to it... */ + + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + iov.iov_base = buf; + iov.iov_len = BUF_SIZE; + + /* This will block until we receive data or a signal */ + len = sock_recvmsg(sock, &msg, BUF_SIZE, 0); + if (len > 0) { + +#if defined (AUTO_FIXUP_BYTESHIFT) || defined (DYNAMIC_COMPRESSION) + +#ifdef AUTO_FIXUP_BYTESHIFT + int lostatcnt=0; +#endif + if (len&1) dprintk("odd len %d\n",len); +#ifdef AUTO_FIXUP_BYTESHIFT + if (shift) { + unsigned char newlastbyte; + newlastbyte=buf[len-1]; + memmove(buf+1,buf,len-1); + buf[0]=lastbyte; + lastbyte=newlastbyte; + } +#endif + for(i=0;i0x7fff) { + k=0x7fff; + if (bt_sco->agc&&factor>COMPRESSION_MIN_16) factor--; + } else if (k<-0x8000) { + k=0x8000; + if (bt_sco->agc&&factor>COMPRESSION_MIN_16) factor--; + } + buf[i+1]=(k>>8)&0xff; + buf[i ]=k&0xff; + + /* find the highest absolute value in a + * GRABSAMPLES long interval. + */ + if (k<0) k=-j; + if (k>maxvalsmoothed) maxvalsmoothed=k; + /* if the interval is over, recalculate + * the compression factor. Move it slowly. + */ + if (maxvalgrablen--<=0) { + maxvalgrablen=GRABSAMPLES; + /* If the noise goes up over 1000, we stop + * pushing the software gain + */ + if (maxvalsmoothed<1000&&factoragc) factor=16; + maxvalsmoothed=0; + } +#endif + } +#ifdef AUTO_FIXUP_BYTESHIFT + if (lostatcnt==len/2&&len>32) { + shift=!shift; + //dprintk("Shift problem detected! Fixing to %d.\n",shift); + } +#endif +#endif /* any of them */ + mutex_lock(&bt_sco->capture_sem); + if (bt_sco->capture) { + snd_card_bt_sco_pcm_receive + (bt_sco->capture, buf, len); + } + mutex_unlock(&bt_sco->capture_sem); + + mutex_lock(&bt_sco->playback_sem); + + if (bt_sco->playback || !bt_sco->loopback) { + memset(buf, 0, len); +#if 0 + /* fill with tone instead of silence */ + int i; + + for (i = 0; i < len / 2; i++) { + buf[i] = 0; + } + for (i = len / 2; i < len; i++) { + buf[i] = 127; + } +#endif + } + if (bt_sco->playback) { + int i, notzero = -1; + + snd_card_bt_sco_pcm_send + (bt_sco->playback, buf, len); + + /* Strangely, when the device is open but no audio is + being written by the app, there's an occasional glitch + in the silence data. This hack eliminates it. */ + + for (i = 0; i < len; i++) { + if (buf[i] != 0) { + if (notzero >= 0) + break; + notzero = i; + } + } + if (notzero >= 0 && i >= len) { + buf[notzero] = 0; + } + } + mutex_unlock(&bt_sco->playback_sem); + +#if 0 + /* This chunk of code lets us record (using arecord) + what data alsa is sending out. + + e.g., when idle, we'd expect something like: + + 8080 8080 8080 8080 8483 8281 8182 8384 + 8080 8080 8080 8080 8080 8080 8080 8080 + 8080 8080 8080 8080 8483 8281 8182 8384 + 8080 8080 8080 8080 8080 8080 8080 8080 + + (this is from 'xxd' of a wav file, that data in + which is unsigned, whereas we are dealing with signed). + */ + + mutex_lock(&bt_sco->capture_sem); + if (bt_sco->capture) { + snd_card_bt_sco_pcm_receive + (bt_sco->capture, "\001\002\003\004", 4); + snd_card_bt_sco_pcm_receive + (bt_sco->capture, buf, len); + snd_card_bt_sco_pcm_receive + (bt_sco->capture, "\004\003\002\001", 4); + } + mutex_unlock(&bt_sco->capture_sem); +#endif + msg.msg_flags = 0; + msg.msg_iov = &iov; + iov.iov_base = buf; + iov.iov_len = BUF_SIZE; + sock_sendmsg(sock, &msg, len); + } + + /* Expect this to be 3 because we (this thead) have a copy, + the driver process keeps one, and the app has the socket open. + */ + if (file_count(sock->file) != 3) { + dprintk("file_count is %d (expected 3)\n", + file_count(sock->file)); + } + fput(sock->file); + + schedule(); + } while (!kthread_should_stop() || bt_sco->sco_sock); + + dprintk("thread exiting\n"); + + return 0; +} + +static void snd_card_bt_private_free(struct snd_card * card) +{ + snd_card_bt_sco_t *bt_sco = card->private_data; + + dprintk("private_free, killing thread\n"); + kthread_stop(bt_sco->thread); + dprintk("private_free, thread exited\n"); + + if (bt_sco->sco_sock) { + dprintk("shutdown: freeing socket count %d\n", + file_count(bt_sco->sco_sock->file)); + + sockfd_put(((struct socket *)bt_sco->sco_sock)); + } + + kfree(bt_sco); +} + +static int __init snd_card_bt_sco_probe(int dev) +{ + struct snd_card *card; + snd_card_bt_sco_t *bt_sco; + int err; + struct snd_hwdep *hw; + + card = + snd_card_new(index[dev], SNDRV_DEFAULT_STR1, + THIS_MODULE, 0); + if (card == NULL) + return -ENOMEM; + + bt_sco = kmalloc(sizeof(*bt_sco), GFP_KERNEL); + if(bt_sco == NULL) + return -ENOMEM; + memset(bt_sco, 0, sizeof(*bt_sco)); + card->private_data = bt_sco; + card->private_free = snd_card_bt_private_free; + + bt_sco->card = card; + + mutex_init(&bt_sco->thread_sem); + mutex_lock(&bt_sco->thread_sem); + mutex_init(&bt_sco->sock_sem); + mutex_init(&bt_sco->capture_sem); + mutex_init(&bt_sco->playback_sem); + init_waitqueue_head(&bt_sco->wait); + init_waitqueue_head(&bt_sco->hwdep_wait); + spin_lock_init(&bt_sco->mixer_changed_lock); + spin_lock_init(&bt_sco->count_changed_lock); + + /* These clone flags copied from some other driver. + Not sure that they're really correct... */ + bt_sco->thread = + kthread_run(snd_card_bt_sco_thread, card, "snd-bt-scod"); + if (IS_ERR(bt_sco->thread)) { + err = PTR_ERR(bt_sco->thread); + goto __nodev; + } + + mutex_lock(&bt_sco->thread_sem); + + if ((err = snd_card_bt_sco_pcm(bt_sco)) < 0) + goto __nodev; + if ((err = snd_card_bt_sco_new_mixer(bt_sco)) < 0) + goto __nodev; + strcpy(card->driver, "Bluetooth SCO"); + strcpy(card->shortname, "BT Headset"); + sprintf(card->longname, "BT Headset %i", dev + 1); + + err = snd_hwdep_new(card, "BTSCO", 0, &hw); + if (err < 0) + goto __nodev; + + sprintf(hw->name, "BTSCO"); + hw->iface = SNDRV_HWDEP_IFACE_BT_SCO; + hw->ops.open = snd_card_bt_open; + hw->ops.ioctl = snd_card_bt_ioctl; + hw->ops.release = snd_card_bt_release; + hw->ops.read = snd_card_bt_read; + hw->ops.write = snd_card_bt_write; + hw->ops.poll = snd_card_bt_poll; + + if ((err = snd_card_register(card)) == 0) { + snd_bt_sco_cards[dev] = card; + return 0; + } + __nodev: + snd_card_free(card); + return err; +} + +static int __init alsa_card_bt_sco_init(void) +{ + printk(KERN_INFO "snd-bt-sco revision %s\n", mod_revision + 11); + + if (snd_card_bt_sco_probe(0) < 0) { +#ifdef MODULE + printk(KERN_ERR + "Bluetooth SCO soundcard not found or device busy\n"); +#endif + return -ENODEV; + } + return 0; +} + +static void __exit alsa_card_bt_sco_exit(void) +{ + int idx; + + for (idx = 0; idx < SNDRV_CARDS; idx++) + snd_card_free(snd_bt_sco_cards[idx]); +} + +module_init(alsa_card_bt_sco_init) + module_exit(alsa_card_bt_sco_exit) +#ifndef MODULE +static int __init alsa_card_bt_sco_setup(char *str) +{ + static unsigned __initdata nr_dev = 0; + + if (nr_dev >= SNDRV_CARDS) + return 0; + nr_dev++; + return 1; +} + +__setup("snd-bt-sco=", alsa_card_bt_sco_setup); + +#endif /* ifndef MODULE */ --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov518_decomp.c +++ linux-2.6.28/ubuntu/misc/media/ov511/ov518_decomp.c @@ -0,0 +1,1566 @@ +/* OV518 Decompression Support Module (No-MMX version) + * + * Copyright (c) 2002-2003 Mark W. McClelland. All rights reserved. + * http://alpha.dyndns.org/ov511/ + * + * Fast integer iDCT by Yuri van Oers + * Original OV511 decompression code Copyright 1998-2000 OmniVision Technologies + * + * 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. + */ + + +#if defined(OUTSIDE_KERNEL) + #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) + #define MODVERSIONS + #endif + + #include + + #ifdef MODVERSIONS + #include + #endif +#else + #include +#endif + +#include +#include + +#include "ov511.h" + +/****************************************************************************** + * Compile-time Options + ******************************************************************************/ + +/* Defining APPROXIMATE_MUL_BY_SHIFT increases performance by approximation + * the multiplications by shifts. I think there's no change in the + * calculated picture, but I'm not sure, so the choice is still in here. */ +#undef APPROXIMATE_MUL_BY_SHIFT + +/* Allows printing the dynamic quantization tables (only if debug >= 5) */ +#define PRINT_QT + +/****************************************************************************** + * Version Information + ******************************************************************************/ + +#define DRIVER_VERSION "v1.3" +#define DRIVER_AUTHOR "Mark McClelland , \ +Yuri van Oers , OmniVision Technologies \ +" +#define DRIVER_DESC "OV518 Decompression Module" + +/****************************************************************************** + * Decompression Module Interface Constants + ******************************************************************************/ + +static const int interface_ver = DECOMP_INTERFACE_VER; +static const int ov518 = 1; +static const int mmx = 0; + +/****************************************************************************** + * Module Features + ******************************************************************************/ + +static int debug = 0; + +/* Static quantization. This uses a fixed quantization table versus the one + * that is normally embedded in the data. Define this if you see very bad + * contrast or "blockiness" in the decompressed output. */ +static int staticquant = 0; + +module_param(debug, uint, 0400); +MODULE_PARM_DESC(debug, + "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +#if defined(MODULE_LICENSE) /* Introduced in ~2.4.10 */ +MODULE_LICENSE("GPL"); +#endif + +/****************************************************************************** + * Prototypes + ******************************************************************************/ + +extern int ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, + int ov518, int mmx); +extern void ov511_deregister_decomp_module(int ov518, int mmx); + +/****************************************************************************** + * Local Data Types + ******************************************************************************/ + +/* Make sure this remains naturally aligned and 2^n bytes in size */ +struct tree_node { + short left; /* Pointer to left child node */ + short right; /* Pointer to right child node */ + signed char depth; /* Depth (starting at 1) if leaf, else -1 */ + signed char coeffbits; /* Size of coefficient data, or zero if none */ + signed char skip; /* Number of zero coefficients. Unused w/ DC */ + char padding; /* Pad out to 8 bytes */ +}; + +struct comp_info { + int bytes; /* Number of processed input bytes */ + int bits; /* Number of unprocessed input bits */ + int rawLen; /* Total number of bytes in input buffer */ + unsigned char *qt; /* Current quantization table */ +}; + +/****************************************************************************** + * Constant Data Definitions + ******************************************************************************/ + +/* Zig-Zag Table */ +static const unsigned char ZigZag518[] = { + 0x00, 0x02, 0x03, 0x09, + 0x01, 0x04, 0x08, 0x0a, + 0x05, 0x07, 0x0b, 0x11, + 0x06, 0x0c, 0x10, 0x12, + 0x0d, 0x0f, 0x13, 0x19, + 0x0e, 0x14, 0x18, 0x1a, + 0x15, 0x17, 0x1b, 0x1e, + 0x16, 0x1c, 0x1d, 0x1f +}; + +/* Huffman trees */ + +static const struct tree_node treeYAC[] = { + { 1, 4, -1, 0, -1}, { 2, 3, -1, 0, -1}, + { -1, -1, 2, 1, 0}, { -1, -1, 2, 2, 0}, + { 5, 9, -1, 0, -1}, { 6, 7, -1, 0, -1}, + { -1, -1, 3, 3, 0}, {323, 8, -1, 0, -1}, + { -1, -1, 4, 4, 0}, { 10, 13, -1, 0, -1}, + { 38, 11, -1, 0, -1}, { 12, 39, -1, 0, -1}, + { -1, -1, 5, 5, 0}, { 59, 14, -1, 0, -1}, + { 15, 18, -1, 0, -1}, { 16, 113, -1, 0, -1}, + { 17, 40, -1, 0, -1}, { -1, -1, 7, 6, 0}, + { 19, 22, -1, 0, -1}, { 20, 41, -1, 0, -1}, + { 21, 61, -1, 0, -1}, { -1, -1, 8, 7, 0}, + { 23, 27, -1, 0, -1}, {169, 24, -1, 0, -1}, + {208, 25, -1, 0, -1}, { 26, 62, -1, 0, -1}, + { -1, -1, 10, 8, 0}, { 44, 28, -1, 0, -1}, + { 63, 29, -1, 0, -1}, { 30, 191, -1, 0, -1}, + { 31, 119, -1, 0, -1}, { 32, 82, -1, 0, -1}, + { 33, 55, -1, 0, -1}, { 34, 48, -1, 0, -1}, + {171, 35, -1, 0, -1}, { 36, 37, -1, 0, -1}, + { -1, -1, 16, 9, 0}, { -1, -1, 16, 10, 0}, + { -1, -1, 4, 1, 1}, { -1, -1, 5, 2, 1}, + { -1, -1, 7, 3, 1}, {151, 42, -1, 0, -1}, + { 43, 79, -1, 0, -1}, { -1, -1, 9, 4, 1}, + { 96, 45, -1, 0, -1}, {246, 46, -1, 0, -1}, + { 47, 115, -1, 0, -1}, { -1, -1, 11, 5, 1}, + { 49, 52, -1, 0, -1}, { 50, 51, -1, 0, -1}, + { -1, -1, 16, 6, 1}, { -1, -1, 16, 7, 1}, + { 53, 54, -1, 0, -1}, { -1, -1, 16, 8, 1}, + { -1, -1, 16, 9, 1}, { 56, 71, -1, 0, -1}, + { 57, 68, -1, 0, -1}, { 58, 67, -1, 0, -1}, + { -1, -1, 16, 10, 1}, { 60, 77, -1, 0, -1}, + { -1, -1, 5, 1, 2}, { -1, -1, 8, 2, 2}, + { -1, -1, 10, 3, 2}, {265, 64, -1, 0, -1}, + { 65, 134, -1, 0, -1}, { 66, 80, -1, 0, -1}, + { -1, -1, 12, 4, 2}, { -1, -1, 16, 5, 2}, + { 69, 70, -1, 0, -1}, { -1, -1, 16, 6, 2}, + { -1, -1, 16, 7, 2}, { 72, 75, -1, 0, -1}, + { 73, 74, -1, 0, -1}, { -1, -1, 16, 8, 2}, + { -1, -1, 16, 9, 2}, { 76, 81, -1, 0, -1}, + { -1, -1, 16, 10, 2}, { 78, 95, -1, 0, -1}, + { -1, -1, 6, 1, 3}, { -1, -1, 9, 2, 3}, + { -1, -1, 12, 3, 3}, { -1, -1, 16, 4, 3}, + { 83, 101, -1, 0, -1}, { 84, 91, -1, 0, -1}, + { 85, 88, -1, 0, -1}, { 86, 87, -1, 0, -1}, + { -1, -1, 16, 5, 3}, { -1, -1, 16, 6, 3}, + { 89, 90, -1, 0, -1}, { -1, -1, 16, 7, 3}, + { -1, -1, 16, 8, 3}, { 92, 98, -1, 0, -1}, + { 93, 94, -1, 0, -1}, { -1, -1, 16, 9, 3}, + { -1, -1, 16, 10, 3}, { -1, -1, 6, 1, 4}, + { 97, 225, -1, 0, -1}, { -1, -1, 10, 2, 4}, + { 99, 100, -1, 0, -1}, { -1, -1, 16, 3, 4}, + { -1, -1, 16, 4, 4}, {102, 109, -1, 0, -1}, + {103, 106, -1, 0, -1}, {104, 105, -1, 0, -1}, + { -1, -1, 16, 5, 4}, { -1, -1, 16, 6, 4}, + {107, 108, -1, 0, -1}, { -1, -1, 16, 7, 4}, + { -1, -1, 16, 8, 4}, {110, 116, -1, 0, -1}, + {111, 112, -1, 0, -1}, { -1, -1, 16, 9, 4}, + { -1, -1, 16, 10, 4}, {114, 133, -1, 0, -1}, + { -1, -1, 7, 1, 5}, { -1, -1, 11, 2, 5}, + {117, 118, -1, 0, -1}, { -1, -1, 16, 3, 5}, + { -1, -1, 16, 4, 5}, {120, 156, -1, 0, -1}, + {121, 139, -1, 0, -1}, {122, 129, -1, 0, -1}, + {123, 126, -1, 0, -1}, {124, 125, -1, 0, -1}, + { -1, -1, 16, 5, 5}, { -1, -1, 16, 6, 5}, + {127, 128, -1, 0, -1}, { -1, -1, 16, 7, 5}, + { -1, -1, 16, 8, 5}, {130, 136, -1, 0, -1}, + {131, 132, -1, 0, -1}, { -1, -1, 16, 9, 5}, + { -1, -1, 16, 10, 5}, { -1, -1, 7, 1, 6}, + {135, 152, -1, 0, -1}, { -1, -1, 12, 2, 6}, + {137, 138, -1, 0, -1}, { -1, -1, 16, 3, 6}, + { -1, -1, 16, 4, 6}, {140, 147, -1, 0, -1}, + {141, 144, -1, 0, -1}, {142, 143, -1, 0, -1}, + { -1, -1, 16, 5, 6}, { -1, -1, 16, 6, 6}, + {145, 146, -1, 0, -1}, { -1, -1, 16, 7, 6}, + { -1, -1, 16, 8, 6}, {148, 153, -1, 0, -1}, + {149, 150, -1, 0, -1}, { -1, -1, 16, 9, 6}, + { -1, -1, 16, 10, 6}, { -1, -1, 8, 1, 7}, + { -1, -1, 12, 2, 7}, {154, 155, -1, 0, -1}, + { -1, -1, 16, 3, 7}, { -1, -1, 16, 4, 7}, + {157, 175, -1, 0, -1}, {158, 165, -1, 0, -1}, + {159, 162, -1, 0, -1}, {160, 161, -1, 0, -1}, + { -1, -1, 16, 5, 7}, { -1, -1, 16, 6, 7}, + {163, 164, -1, 0, -1}, { -1, -1, 16, 7, 7}, + { -1, -1, 16, 8, 7}, {166, 172, -1, 0, -1}, + {167, 168, -1, 0, -1}, { -1, -1, 16, 9, 7}, + { -1, -1, 16, 10, 7}, {170, 187, -1, 0, -1}, + { -1, -1, 9, 1, 8}, { -1, -1, 15, 2, 8}, + {173, 174, -1, 0, -1}, { -1, -1, 16, 3, 8}, + { -1, -1, 16, 4, 8}, {176, 183, -1, 0, -1}, + {177, 180, -1, 0, -1}, {178, 179, -1, 0, -1}, + { -1, -1, 16, 5, 8}, { -1, -1, 16, 6, 8}, + {181, 182, -1, 0, -1}, { -1, -1, 16, 7, 8}, + { -1, -1, 16, 8, 8}, {184, 188, -1, 0, -1}, + {185, 186, -1, 0, -1}, { -1, -1, 16, 9, 8}, + { -1, -1, 16, 10, 8}, { -1, -1, 9, 1, 9}, + {189, 190, -1, 0, -1}, { -1, -1, 16, 2, 9}, + { -1, -1, 16, 3, 9}, {192, 258, -1, 0, -1}, + {193, 226, -1, 0, -1}, {194, 210, -1, 0, -1}, + {195, 202, -1, 0, -1}, {196, 199, -1, 0, -1}, + {197, 198, -1, 0, -1}, { -1, -1, 16, 4, 9}, + { -1, -1, 16, 5, 9}, {200, 201, -1, 0, -1}, + { -1, -1, 16, 6, 9}, { -1, -1, 16, 7, 9}, + {203, 206, -1, 0, -1}, {204, 205, -1, 0, -1}, + { -1, -1, 16, 8, 9}, { -1, -1, 16, 9, 9}, + {207, 209, -1, 0, -1}, { -1, -1, 16, 10, 9}, + { -1, -1, 9, 1, 10}, { -1, -1, 16, 2, 10}, + {211, 218, -1, 0, -1}, {212, 215, -1, 0, -1}, + {213, 214, -1, 0, -1}, { -1, -1, 16, 3, 10}, + { -1, -1, 16, 4, 10}, {216, 217, -1, 0, -1}, + { -1, -1, 16, 5, 10}, { -1, -1, 16, 6, 10}, + {219, 222, -1, 0, -1}, {220, 221, -1, 0, -1}, + { -1, -1, 16, 7, 10}, { -1, -1, 16, 8, 10}, + {223, 224, -1, 0, -1}, { -1, -1, 16, 9, 10}, + { -1, -1, 16, 10, 10}, { -1, -1, 10, 1, 11}, + {227, 242, -1, 0, -1}, {228, 235, -1, 0, -1}, + {229, 232, -1, 0, -1}, {230, 231, -1, 0, -1}, + { -1, -1, 16, 2, 11}, { -1, -1, 16, 3, 11}, + {233, 234, -1, 0, -1}, { -1, -1, 16, 4, 11}, + { -1, -1, 16, 5, 11}, {236, 239, -1, 0, -1}, + {237, 238, -1, 0, -1}, { -1, -1, 16, 6, 11}, + { -1, -1, 16, 7, 11}, {240, 241, -1, 0, -1}, + { -1, -1, 16, 8, 11}, { -1, -1, 16, 9, 11}, + {243, 251, -1, 0, -1}, {244, 248, -1, 0, -1}, + {245, 247, -1, 0, -1}, { -1, -1, 16, 10, 11}, + { -1, -1, 10, 1, 12}, { -1, -1, 16, 2, 12}, + {249, 250, -1, 0, -1}, { -1, -1, 16, 3, 12}, + { -1, -1, 16, 4, 12}, {252, 255, -1, 0, -1}, + {253, 254, -1, 0, -1}, { -1, -1, 16, 5, 12}, + { -1, -1, 16, 6, 12}, {256, 257, -1, 0, -1}, + { -1, -1, 16, 7, 12}, { -1, -1, 16, 8, 12}, + {259, 292, -1, 0, -1}, {260, 277, -1, 0, -1}, + {261, 270, -1, 0, -1}, {262, 267, -1, 0, -1}, + {263, 264, -1, 0, -1}, { -1, -1, 16, 9, 12}, + { -1, -1, 16, 10, 12}, {266, 322, -1, 0, -1}, + { -1, -1, 11, 1, 13}, {268, 269, -1, 0, -1}, + { -1, -1, 16, 2, 13}, { -1, -1, 16, 3, 13}, + {271, 274, -1, 0, -1}, {272, 273, -1, 0, -1}, + { -1, -1, 16, 4, 13}, { -1, -1, 16, 5, 13}, + {275, 276, -1, 0, -1}, { -1, -1, 16, 6, 13}, + { -1, -1, 16, 7, 13}, {278, 285, -1, 0, -1}, + {279, 282, -1, 0, -1}, {280, 281, -1, 0, -1}, + { -1, -1, 16, 8, 13}, { -1, -1, 16, 9, 13}, + {283, 284, -1, 0, -1}, { -1, -1, 16, 10, 13}, + { -1, -1, 16, 1, 14}, {286, 289, -1, 0, -1}, + {287, 288, -1, 0, -1}, { -1, -1, 16, 2, 14}, + { -1, -1, 16, 3, 14}, {290, 291, -1, 0, -1}, + { -1, -1, 16, 4, 14}, { -1, -1, 16, 5, 14}, + {293, 308, -1, 0, -1}, {294, 301, -1, 0, -1}, + {295, 298, -1, 0, -1}, {296, 297, -1, 0, -1}, + { -1, -1, 16, 6, 14}, { -1, -1, 16, 7, 14}, + {299, 300, -1, 0, -1}, { -1, -1, 16, 8, 14}, + { -1, -1, 16, 9, 14}, {302, 305, -1, 0, -1}, + {303, 304, -1, 0, -1}, { -1, -1, 16, 10, 14}, + { -1, -1, 16, 1, 15}, {306, 307, -1, 0, -1}, + { -1, -1, 16, 2, 15}, { -1, -1, 16, 3, 15}, + {309, 316, -1, 0, -1}, {310, 313, -1, 0, -1}, + {311, 312, -1, 0, -1}, { -1, -1, 16, 4, 15}, + { -1, -1, 16, 5, 15}, {314, 315, -1, 0, -1}, + { -1, -1, 16, 6, 15}, { -1, -1, 16, 7, 15}, + {317, 320, -1, 0, -1}, {318, 319, -1, 0, -1}, + { -1, -1, 16, 8, 15}, { -1, -1, 16, 9, 15}, + {321, -1, -1, 0, -1}, { -1, -1, 16, 10, 15}, + { -1, -1, 11, 0, 16}, { -1, -1, 4, 0, -1}, +}; + +static const struct tree_node treeUVAC[] = { + { 1, 3, -1, 0, -1}, {323, 2, -1, 0, -1}, + { -1, -1, 2, 1, 0}, { 4, 8, -1, 0, -1}, + { 5, 6, -1, 0, -1}, { -1, -1, 3, 2, 0}, + { 7, 37, -1, 0, -1}, { -1, -1, 4, 3, 0}, + { 9, 13, -1, 0, -1}, { 10, 60, -1, 0, -1}, + { 11, 12, -1, 0, -1}, { -1, -1, 5, 4, 0}, + { -1, -1, 5, 5, 0}, { 14, 17, -1, 0, -1}, + { 15, 97, -1, 0, -1}, { 16, 38, -1, 0, -1}, + { -1, -1, 6, 6, 0}, { 18, 21, -1, 0, -1}, + { 19, 39, -1, 0, -1}, { 20, 135, -1, 0, -1}, + { -1, -1, 7, 7, 0}, { 22, 26, -1, 0, -1}, + { 82, 23, -1, 0, -1}, { 24, 99, -1, 0, -1}, + { 25, 42, -1, 0, -1}, { -1, -1, 9, 8, 0}, + { 27, 31, -1, 0, -1}, {211, 28, -1, 0, -1}, + {248, 29, -1, 0, -1}, { 30, 63, -1, 0, -1}, + { -1, -1, 10, 9, 0}, { 43, 32, -1, 0, -1}, + { 33, 48, -1, 0, -1}, {153, 34, -1, 0, -1}, + { 35, 64, -1, 0, -1}, { 36, 47, -1, 0, -1}, + { -1, -1, 12, 10, 0}, { -1, -1, 4, 1, 1}, + { -1, -1, 6, 2, 1}, {152, 40, -1, 0, -1}, + { 41, 62, -1, 0, -1}, { -1, -1, 8, 3, 1}, + { -1, -1, 9, 4, 1}, { 84, 44, -1, 0, -1}, + {322, 45, -1, 0, -1}, { 46, 136, -1, 0, -1}, + { -1, -1, 11, 5, 1}, { -1, -1, 12, 6, 1}, + { 49, 189, -1, 0, -1}, { 50, 119, -1, 0, -1}, + { 51, 76, -1, 0, -1}, { 66, 52, -1, 0, -1}, + { 53, 69, -1, 0, -1}, { 54, 57, -1, 0, -1}, + { 55, 56, -1, 0, -1}, { -1, -1, 16, 7, 1}, + { -1, -1, 16, 8, 1}, { 58, 59, -1, 0, -1}, + { -1, -1, 16, 9, 1}, { -1, -1, 16, 10, 1}, + { 61, 81, -1, 0, -1}, { -1, -1, 5, 1, 2}, + { -1, -1, 8, 2, 2}, { -1, -1, 10, 3, 2}, + { 65, 86, -1, 0, -1}, { -1, -1, 12, 4, 2}, + {286, 67, -1, 0, -1}, { 68, 304, -1, 0, -1}, + { -1, -1, 15, 5, 2}, { 70, 73, -1, 0, -1}, + { 71, 72, -1, 0, -1}, { -1, -1, 16, 6, 2}, + { -1, -1, 16, 7, 2}, { 74, 75, -1, 0, -1}, + { -1, -1, 16, 8, 2}, { -1, -1, 16, 9, 2}, + { 77, 102, -1, 0, -1}, { 78, 91, -1, 0, -1}, + { 79, 88, -1, 0, -1}, { 80, 87, -1, 0, -1}, + { -1, -1, 16, 10, 2}, { -1, -1, 5, 1, 3}, + { 83, 171, -1, 0, -1}, { -1, -1, 8, 2, 3}, + { 85, 117, -1, 0, -1}, { -1, -1, 10, 3, 3}, + { -1, -1, 12, 4, 3}, { -1, -1, 16, 5, 3}, + { 89, 90, -1, 0, -1}, { -1, -1, 16, 6, 3}, + { -1, -1, 16, 7, 3}, { 92, 95, -1, 0, -1}, + { 93, 94, -1, 0, -1}, { -1, -1, 16, 8, 3}, + { -1, -1, 16, 9, 3}, { 96, 101, -1, 0, -1}, + { -1, -1, 16, 10, 3}, { 98, 116, -1, 0, -1}, + { -1, -1, 6, 1, 4}, {100, 188, -1, 0, -1}, + { -1, -1, 9, 2, 4}, { -1, -1, 16, 3, 4}, + {103, 110, -1, 0, -1}, {104, 107, -1, 0, -1}, + {105, 106, -1, 0, -1}, { -1, -1, 16, 4, 4}, + { -1, -1, 16, 5, 4}, {108, 109, -1, 0, -1}, + { -1, -1, 16, 6, 4}, { -1, -1, 16, 7, 4}, + {111, 114, -1, 0, -1}, {112, 113, -1, 0, -1}, + { -1, -1, 16, 8, 4}, { -1, -1, 16, 9, 4}, + {115, 118, -1, 0, -1}, { -1, -1, 16, 10, 4}, + { -1, -1, 6, 1, 5}, { -1, -1, 10, 2, 5}, + { -1, -1, 16, 3, 5}, {120, 156, -1, 0, -1}, + {121, 138, -1, 0, -1}, {122, 129, -1, 0, -1}, + {123, 126, -1, 0, -1}, {124, 125, -1, 0, -1}, + { -1, -1, 16, 4, 5}, { -1, -1, 16, 5, 5}, + {127, 128, -1, 0, -1}, { -1, -1, 16, 6, 5}, + { -1, -1, 16, 7, 5}, {130, 133, -1, 0, -1}, + {131, 132, -1, 0, -1}, { -1, -1, 16, 8, 5}, + { -1, -1, 16, 9, 5}, {134, 137, -1, 0, -1}, + { -1, -1, 16, 10, 5}, { -1, -1, 7, 1, 6}, + { -1, -1, 11, 2, 6}, { -1, -1, 16, 3, 6}, + {139, 146, -1, 0, -1}, {140, 143, -1, 0, -1}, + {141, 142, -1, 0, -1}, { -1, -1, 16, 4, 6}, + { -1, -1, 16, 5, 6}, {144, 145, -1, 0, -1}, + { -1, -1, 16, 6, 6}, { -1, -1, 16, 7, 6}, + {147, 150, -1, 0, -1}, {148, 149, -1, 0, -1}, + { -1, -1, 16, 8, 6}, { -1, -1, 16, 9, 6}, + {151, 155, -1, 0, -1}, { -1, -1, 16, 10, 6}, + { -1, -1, 7, 1, 7}, {154, 267, -1, 0, -1}, + { -1, -1, 11, 2, 7}, { -1, -1, 16, 3, 7}, + {157, 173, -1, 0, -1}, {158, 165, -1, 0, -1}, + {159, 162, -1, 0, -1}, {160, 161, -1, 0, -1}, + { -1, -1, 16, 4, 7}, { -1, -1, 16, 5, 7}, + {163, 164, -1, 0, -1}, { -1, -1, 16, 6, 7}, + { -1, -1, 16, 7, 7}, {166, 169, -1, 0, -1}, + {167, 168, -1, 0, -1}, { -1, -1, 16, 8, 7}, + { -1, -1, 16, 9, 7}, {170, 172, -1, 0, -1}, + { -1, -1, 16, 10, 7}, { -1, -1, 8, 1, 8}, + { -1, -1, 16, 2, 8}, {174, 181, -1, 0, -1}, + {175, 178, -1, 0, -1}, {176, 177, -1, 0, -1}, + { -1, -1, 16, 3, 8}, { -1, -1, 16, 4, 8}, + {179, 180, -1, 0, -1}, { -1, -1, 16, 5, 8}, + { -1, -1, 16, 6, 8}, {182, 185, -1, 0, -1}, + {183, 184, -1, 0, -1}, { -1, -1, 16, 7, 8}, + { -1, -1, 16, 8, 8}, {186, 187, -1, 0, -1}, + { -1, -1, 16, 9, 8}, { -1, -1, 16, 10, 8}, + { -1, -1, 9, 1, 9}, {190, 257, -1, 0, -1}, + {191, 224, -1, 0, -1}, {192, 207, -1, 0, -1}, + {193, 200, -1, 0, -1}, {194, 197, -1, 0, -1}, + {195, 196, -1, 0, -1}, { -1, -1, 16, 2, 9}, + { -1, -1, 16, 3, 9}, {198, 199, -1, 0, -1}, + { -1, -1, 16, 4, 9}, { -1, -1, 16, 5, 9}, + {201, 204, -1, 0, -1}, {202, 203, -1, 0, -1}, + { -1, -1, 16, 6, 9}, { -1, -1, 16, 7, 9}, + {205, 206, -1, 0, -1}, { -1, -1, 16, 8, 9}, + { -1, -1, 16, 9, 9}, {208, 217, -1, 0, -1}, + {209, 214, -1, 0, -1}, {210, 213, -1, 0, -1}, + { -1, -1, 16, 10, 9}, {212, 230, -1, 0, -1}, + { -1, -1, 9, 1, 10}, { -1, -1, 16, 2, 10}, + {215, 216, -1, 0, -1}, { -1, -1, 16, 3, 10}, + { -1, -1, 16, 4, 10}, {218, 221, -1, 0, -1}, + {219, 220, -1, 0, -1}, { -1, -1, 16, 5, 10}, + { -1, -1, 16, 6, 10}, {222, 223, -1, 0, -1}, + { -1, -1, 16, 7, 10}, { -1, -1, 16, 8, 10}, + {225, 241, -1, 0, -1}, {226, 234, -1, 0, -1}, + {227, 231, -1, 0, -1}, {228, 229, -1, 0, -1}, + { -1, -1, 16, 9, 10}, { -1, -1, 16, 10, 10}, + { -1, -1, 9, 1, 11}, {232, 233, -1, 0, -1}, + { -1, -1, 16, 2, 11}, { -1, -1, 16, 3, 11}, + {235, 238, -1, 0, -1}, {236, 237, -1, 0, -1}, + { -1, -1, 16, 4, 11}, { -1, -1, 16, 5, 11}, + {239, 240, -1, 0, -1}, { -1, -1, 16, 6, 11}, + { -1, -1, 16, 7, 11}, {242, 250, -1, 0, -1}, + {243, 246, -1, 0, -1}, {244, 245, -1, 0, -1}, + { -1, -1, 16, 8, 11}, { -1, -1, 16, 9, 11}, + {247, 249, -1, 0, -1}, { -1, -1, 16, 10, 11}, + { -1, -1, 9, 1, 12}, { -1, -1, 16, 2, 12}, + {251, 254, -1, 0, -1}, {252, 253, -1, 0, -1}, + { -1, -1, 16, 3, 12}, { -1, -1, 16, 4, 12}, + {255, 256, -1, 0, -1}, { -1, -1, 16, 5, 12}, + { -1, -1, 16, 6, 12}, {258, 291, -1, 0, -1}, + {259, 275, -1, 0, -1}, {260, 268, -1, 0, -1}, + {261, 264, -1, 0, -1}, {262, 263, -1, 0, -1}, + { -1, -1, 16, 7, 12}, { -1, -1, 16, 8, 12}, + {265, 266, -1, 0, -1}, { -1, -1, 16, 9, 12}, + { -1, -1, 16, 10, 12}, { -1, -1, 11, 1, 13}, + {269, 272, -1, 0, -1}, {270, 271, -1, 0, -1}, + { -1, -1, 16, 2, 13}, { -1, -1, 16, 3, 13}, + {273, 274, -1, 0, -1}, { -1, -1, 16, 4, 13}, + { -1, -1, 16, 5, 13}, {276, 283, -1, 0, -1}, + {277, 280, -1, 0, -1}, {278, 279, -1, 0, -1}, + { -1, -1, 16, 6, 13}, { -1, -1, 16, 7, 13}, + {281, 282, -1, 0, -1}, { -1, -1, 16, 8, 13}, + { -1, -1, 16, 9, 13}, {284, 288, -1, 0, -1}, + {285, 287, -1, 0, -1}, { -1, -1, 16, 10, 13}, + { -1, -1, 14, 1, 14}, { -1, -1, 16, 2, 14}, + {289, 290, -1, 0, -1}, { -1, -1, 16, 3, 14}, + { -1, -1, 16, 4, 14}, {292, 308, -1, 0, -1}, + {293, 300, -1, 0, -1}, {294, 297, -1, 0, -1}, + {295, 296, -1, 0, -1}, { -1, -1, 16, 5, 14}, + { -1, -1, 16, 6, 14}, {298, 299, -1, 0, -1}, + { -1, -1, 16, 7, 14}, { -1, -1, 16, 8, 14}, + {301, 305, -1, 0, -1}, {302, 303, -1, 0, -1}, + { -1, -1, 16, 9, 14}, { -1, -1, 16, 10, 14}, + { -1, -1, 15, 1, 15}, {306, 307, -1, 0, -1}, + { -1, -1, 16, 2, 15}, { -1, -1, 16, 3, 15}, + {309, 316, -1, 0, -1}, {310, 313, -1, 0, -1}, + {311, 312, -1, 0, -1}, { -1, -1, 16, 4, 15}, + { -1, -1, 16, 5, 15}, {314, 315, -1, 0, -1}, + { -1, -1, 16, 6, 15}, { -1, -1, 16, 7, 15}, + {317, 320, -1, 0, -1}, {318, 319, -1, 0, -1}, + { -1, -1, 16, 8, 15}, { -1, -1, 16, 9, 15}, + {321, -1, -1, 0, -1}, { -1, -1, 16, 10, 15}, + { -1, -1, 10, 0, 16}, { -1, -1, 2, 0, -1}, +}; + +static const struct tree_node treeYDC[] = { + { 1, 6, -1, 0}, { 2, 3, -1, 0}, + { -1, -1, 2, 0}, { 4, 5, -1, 0}, + { -1, -1, 3, 1}, { -1, -1, 3, 2}, + { 7, 10, -1, 0}, { 8, 9, -1, 0}, + { -1, -1, 3, 3}, { -1, -1, 3, 4}, + { 11, 12, -1, 0}, { -1, -1, 3, 5}, + { 13, 14, -1, 0}, { -1, -1, 4, 6}, + { 15, 16, -1, 0}, { -1, -1, 5, 7}, + { 17, 18, -1, 0}, { -1, -1, 6, 8}, + { 19, 20, -1, 0}, { -1, -1, 7, 9}, + { 21, 22, -1, 0}, { -1, -1, 8, 10}, + { 23, -1, -1, 0}, { -1, -1, 9, 11}, +}; + +static const struct tree_node treeUVDC[] = { + { 1, 4, -1, 0}, { 2, 3, -1, 0}, + { -1, -1, 2, 0}, { -1, -1, 2, 1}, + { 5, 6, -1, 0}, { -1, -1, 2, 2}, + { 7, 8, -1, 0}, { -1, -1, 3, 3}, + { 9, 10, -1, 0}, { -1, -1, 4, 4}, + { 11, 12, -1, 0}, { -1, -1, 5, 5}, + { 13, 14, -1, 0}, { -1, -1, 6, 6}, + { 15, 16, -1, 0}, { -1, -1, 7, 7}, + { 17, 18, -1, 0}, { -1, -1, 8, 8}, + { 19, 20, -1, 0}, { -1, -1, 9, 9}, + { 21, 22, -1, 0}, { -1, -1, 10, 10}, + { 23, -1, -1, 0}, { -1, -1, 11, 11}, +}; + +/****************************************************************************** + * Debugging + ******************************************************************************/ + +#ifdef PRINT_QT +#define PRN_QT_ROW(a, i) PDEBUG(5, "%02x %02x %02x %02x %02x %02x %02x %02x", \ + (a)[(i)], (a)[(i)+1], (a)[(i)+2], (a)[(i)+3], (a)[(i)+4], (a)[(i)+5], \ + (a)[(i)+6], (a)[(i)+7]) + +static inline void +print_qt(unsigned char *qt) +{ + PDEBUG(5, "Y Quantization table:"); + PRN_QT_ROW(qt, 0); + PRN_QT_ROW(qt, 8); + PRN_QT_ROW(qt, 16); + PRN_QT_ROW(qt, 24); + PDEBUG(5, "UV Quantization table:"); + PRN_QT_ROW(qt, 32); + PRN_QT_ROW(qt, 40); + PRN_QT_ROW(qt, 48); + PRN_QT_ROW(qt, 56); +} +#else +static inline void +print_qt(unsigned char *qt) { } +#endif /* PRINT_QT */ + +/****************************************************************************** + * Huffman Decoder + ******************************************************************************/ + +/* Note: There is no penalty for passing the tree as an argument, since dummy + * args are passed anyway (to maintain 16-byte stack alignment), and since the + * address is loaded into a register either way. */ + +/* If no node is found, coeffbits and skip will not be modified */ +/* Return: Depth of node found, or -1 if invalid input code */ +static int +getNodeAC(unsigned int in, signed char *coeffbits, signed char *skip, + const struct tree_node *tree) +{ + int node = 0; + int i = 0; + int depth; + + do { + if ((in & 0x80000000) == 0) + node = tree[node].left; + else + node = tree[node].right; + + if (node == -1) + break; + + depth = tree[node].depth; + + /* Is it a leaf? If not, branch downward */ + if (depth != -1) { + *coeffbits = tree[node].coeffbits; + *skip = tree[node].skip; + return depth; + } + + in <<= 1; + ++i; + } while (i <= 15); + + return -1; +} + +/* If no node is found, coeffbits will not be modified */ +/* Return: Depth of node found, or -1 if invalid input code */ +static int +getNodeDC(unsigned int in, signed char *coeffbits, const struct tree_node *tree) +{ + int node = 0; + int i = 0; + int depth; + + do { + if ((in & 0x80000000) == 0) + node = tree[node].left; + else + node = tree[node].right; + + if (node == -1) + break; + + depth = tree[node].depth; + + /* Is it a leaf? If not, branch downward */ + if (depth != -1) { + *coeffbits = tree[node].coeffbits; + return depth; + } + + in <<= 1; + ++i; + } while (i <= 15); + + return -1; +} + +static inline unsigned int +getBytes(int *rawData, struct comp_info *cinfo) +{ + int bufLen = cinfo->rawLen; + int bits = cinfo->bits; + int bytes = cinfo->bytes; + unsigned char *in = bytes + (unsigned char *) rawData; + unsigned char b1, b2, b3, b4, b5; + unsigned int packedIn; + + /* Pull 5 bytes out of raw data */ + if (bytes < bufLen - 4) { + b1 = in[0]; + b2 = in[1]; + b3 = in[2]; + b4 = in[3]; + b5 = in[4]; + } else { + if (bytes < bufLen - 3) { + b1 = in[0]; + b2 = in[1]; + b3 = in[2]; + b4 = in[3]; + } else { + if (bytes < bufLen - 2) { + b1 = in[0]; + b2 = in[1]; + b3 = in[2]; + } else { + if (bytes < bufLen - 1) { + b1 = in[0]; + b2 = in[1]; + } else { + if (bytes <= bufLen) { + b1 = in[0]; + } else { + b1 = 0; + } + b2 = 0; + } + b3 = 0; + } + b4 = 0; + } + b5 = 0; + } + + /* Pack the bytes */ + packedIn = b1 << 24; + packedIn += b2 << 16; + packedIn += b3 << 8; + packedIn += b4; + + if (bits != 0) { + packedIn = packedIn << bits; + packedIn += b5 >> (8 - bits); + } + + return packedIn; +} + +static int +getACCoefficient(int *rawData, int *coeff, struct comp_info *cinfo, + const struct tree_node *tree) +{ + int input, bits, bytes, tmp_c; + signed char coeffbits = 0; + signed char skip = 0; + + input = getBytes(rawData, cinfo); + bits = getNodeAC(input, &coeffbits, &skip, tree); + + if (coeffbits) { + input = input << (bits - 1); + input &= 0x7fffffff; + if (! (input & 0x40000000)) + input |= 0x80000000; + + tmp_c = input >> (31 - coeffbits); + if (tmp_c < 0) + tmp_c++; + *coeff = tmp_c; + + bits += coeffbits; + } + + bytes = (bits + cinfo->bits) >> 3; + cinfo->bytes += bytes; + cinfo->bits += bits - (bytes << 3); + + return skip; +} + +static void +getDCCoefficient(int *rawData, int *coeff, struct comp_info *cinfo, + const struct tree_node *tree) +{ + int input, bits, bytes, tmp_c; + signed char coeffbits = 0; + + input = getBytes(rawData, cinfo); + bits = getNodeDC(input, &coeffbits, tree); + + if (bits == -1) { + bits = 1; /* Try to re-sync at the next bit */ + *coeff = 0; /* Indicates no change from last DC */ + } else { + + input = input << (bits - 1); + input &= 0x7fffffff; + if (! (input & 0x40000000)) + input |= 0x80000000; + + tmp_c = input >> (31 - coeffbits); + if (tmp_c < 0) + tmp_c++; + *coeff = tmp_c; + + bits += coeffbits; + } + + bytes = (bits + cinfo->bits) >> 3; + cinfo->bytes += bytes; + cinfo->bits += bits - (bytes << 3); +} + +/* For AC coefficients, here is what the "skip" value means: + * -1: Either the 8x4 block has ended, or the decoding failed. + * 0: Use the returned coeff. Don't skip anything. + * 1-15: The next coeffs are zero. The returned coeff is used. + * 16: The next 16 coeffs are zero. The returned coeff is ignored. + * + * You must ensure that the C[] array not be overrun, or stack corruption will + * result. + */ +static void +huffmanDecoderY(int *C, int *pIn, struct comp_info *cinfo) +{ + int coeff = 0; + int i = 1; + int k, skip; + + getDCCoefficient(pIn, C, cinfo, treeYDC); + + i = 1; + do { + skip = getACCoefficient(pIn, &coeff, cinfo, treeYAC); + + if (skip == -1) { + break; + } else if (skip == 0) { + C[i++] = coeff; + } else if (skip == 16) { + k = 16; + if (i > 16) + k = 32 - i; + + while (k--) + C[i++] = 0; + } else { + k = skip; + if (skip > 31 - i) + k = 31 - i; + + while (k--) + C[i++] = 0; + + C[i++] = coeff; + } + } while (i <= 31); + + if (skip == -1) + while (i <= 31) C[i++] = 0; + else + getACCoefficient(pIn, &coeff, cinfo, treeYAC); +} + +/* Same as huffmanDecoderY, except for the tables used */ +static void +huffmanDecoderUV(int *C, int *pIn, struct comp_info *cinfo) +{ + int coeff = 0; + int i = 1; + int k, skip; + + getDCCoefficient(pIn, C, cinfo, treeUVDC); + + i = 1; + do { + skip = getACCoefficient(pIn, &coeff, cinfo, treeUVAC); + + if (skip == -1) { + break; + } else if (skip == 0) { + C[i++] = coeff; + } else if (skip == 16) { + k = 16; + if (i > 16) + k = 32 - i; + + while (k--) + C[i++] = 0; + } else { + k = skip; + if (skip > 31 - i) + k = 31 - i; + + while (k--) + C[i++] = 0; + + C[i++] = coeff; + } + } while (i <= 31); + + if (skip == -1) + while (i <= 31) C[i++] = 0; + else + getACCoefficient(pIn, &coeff, cinfo, treeUVAC); +} + +/****************************************************************************** + * iDCT Functions + ******************************************************************************/ + +#ifndef APPROXIMATE_MUL_BY_SHIFT + +#define IDCT_MESSAGE "iDCT with multiply" + +#define TIMES_16382(u) ((u)? 16382 * (u):0) +#define TIMES_23168(u) ((u)? 23168 * (u):0) +#define TIMES_30270(u) ((u)? 30270 * (u):0) +#define TIMES_41986(u) ((u)? 41986 * (u):0) +#define TIMES_35594(u) ((u)? 35594 * (u):0) +#define TIMES_23783(u) ((u)? 23783 * (u):0) +#define TIMES_8351(u) ((u)? 8351 * (u):0) +#define TIMES_17391(u) ((u)? 17391 * (u):0) +#define TIMES_14743(u) ((u)? 14743 * (u):0) +#define TIMES_9851(u) ((u)? 9851 * (u):0) +#define TIMES_3459(u) ((u)? 3459 * (u):0) +#define TIMES_32134(u) ((u)? 32134 * (u):0) +#define TIMES_27242(u) ((u)? 27242 * (u):0) +#define TIMES_18202(u) ((u)? 18202 * (u):0) +#define TIMES_6392(u) ((u)? 6392 * (u):0) +#define TIMES_39550(u) ((u)? 39550 * (u):0) +#define TIMES_6785(u) ((u)? 6785 * (u):0) +#define TIMES_12538(u) ((u)? 12538 * (u):0) + +#else + +#define IDCT_MESSAGE "iDCT with shift" + +#define TIMES_16382(u) ( (u)? x=(u) , (x<<14) - (x<<1) :0 ) +#define TIMES_23168(u) ( (u)? x=(u) , (x<<14) + (x<<12) + (x<<11) + (x<<9) :0 ) +#define TIMES_30270(u) ( (u)? x=(u) , (x<<15) - (x<<11) :0 ) +#define TIMES_41986(u) ( (u)? x=(u) , (x<<15) + (x<<13) + (x<<10) :0 ) +#define TIMES_35594(u) ( (u)? x=(u) , (x<<15) + (x<<11) + (x<<9) + (x<<8) :0 ) +#define TIMES_23783(u) ( (u)? x=(u) , (x<<14) + (x<<13) - (x<<9) - (x<<8) :0 ) +#define TIMES_8351(u) ( (u)? x=(u) , (x<<13) :0 ) +#define TIMES_17391(u) ( (u)? x=(u) , (x<<14) + (x<<10) :0 ) +#define TIMES_14743(u) ( (u)? x=(u) , (x<<14) - (x<<10) - (x<<9) :0 ) +#define TIMES_9851(u) ( (u)? x=(u) , (x<<13) + (x<<10) + (x<<9) :0 ) +#define TIMES_3459(u) ( (u)? x=(u) , (x<<12) - (x<<9) :0 ) +#define TIMES_32134(u) ( (u)? x=(u) , (x<<15) - (x<<9) :0 ) +#define TIMES_27242(u) ( (u)? x=(u) , (x<<14) + (x<<13) + (x<<11) + (x<<9) :0 ) +#define TIMES_18202(u) ( (u)? x=(u) , (x<<14) + (x<<11) - (x<<8) :0 ) +#define TIMES_6392(u) ( (u)? x=(u) , (x<<13) - (x<<11) + (x<<8) :0 ) +#define TIMES_39550(u) ( (u)? x=(u) , (x<<15) + (x<<12) + (x<<11) + (x<<9) :0 ) +#define TIMES_6785(u) ( (u)? x=(u) , (x<<12) + (x<<11) + (x<<9) :0 ) +#define TIMES_12538(u) ( (u)? x=(u) , (x<<13) + (x<<12) + (x<<8) :0 ) + +/* + * The variables C0, C4, C16 and C20 can also be removed from the algorithm + * if APPROXIMATE_MUL_BY_SHIFTS is defined. They store correction values + * and can be considered insignificant. + */ + +#endif + +static void +DCT_8x4(int *coeff, unsigned char *out) +/* pre: coeff == coefficients + post: coeff != coefficients + ** DO NOT ASSUME coeff TO BE THE SAME BEFORE AND AFTER CALLING THIS FUNCTION! +*/ +{ + register int base,val1,val2,val3; + int tmp1,tmp2; + int C0,C4,C16,C20; + int C2_18,C6_22,C1_17,C3_19,C5_21,C7_23; + register int t; +#ifdef APPROXIMATE_MUL_BY_SHIFT + register int x; +#endif + + C0=coeff[0]; + C4=coeff[4]; + C16=coeff[16]; + C20=coeff[20]; + + coeff[0]=TIMES_23168(coeff[0]); + coeff[4]=TIMES_23168(coeff[4]); + coeff[16]=TIMES_23168(coeff[16]); + coeff[20]=TIMES_23168(coeff[20]); + + C2_18 = coeff[2]+coeff[18]; + C6_22 = coeff[6]+coeff[22]; + C1_17 = coeff[1]+coeff[17]; + C3_19 = coeff[3]+coeff[19]; + C5_21 = coeff[5]+coeff[21]; + C7_23 = coeff[7]+coeff[23]; + +// 0,7,25,32 + + base = 0x1000000; + base += coeff[0]+coeff[4]+coeff[16]+coeff[20]; + base += TIMES_30270(C2_18); + base += TIMES_12538(C6_22); + + val1 = TIMES_41986(coeff[9]); + val1 += TIMES_35594(coeff[11]); + val1 += TIMES_23783(coeff[13]); + val1 += TIMES_8351(coeff[15]); + val1 += TIMES_17391(coeff[25]); + val1 += TIMES_14743(coeff[27]); + val1 += TIMES_9851(coeff[29]); + val1 += TIMES_3459(coeff[31]); + + val2 = TIMES_32134(C1_17); + val2 += TIMES_27242(C3_19); + val2 += TIMES_18202(C5_21); + val2 += TIMES_6392(C7_23); + + val3 = TIMES_39550(coeff[10]); + val3 += TIMES_16382(coeff[14]+coeff[26]); + val3 += TIMES_6785(coeff[30]); + val3 += TIMES_30270(coeff[8]+coeff[12]); + val3 += TIMES_12538(coeff[24]+coeff[28]); + + t=(base + val1 + val2 + val3) >> 17; + out[0]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 - C4 - C20) >> 17; + out[7]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - C16- C20) >> 17; + out[24]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 - C4 - C16 - C20) >> 17; + out[31]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//1,6,25,30 + + base = 0x1000000; + base += coeff[0]-coeff[4]+coeff[16]-coeff[20]; + base += TIMES_12538(C2_18); + base -= TIMES_30270(C6_22); + + val1 = TIMES_35594(coeff[9]); + val1 -= TIMES_8351(coeff[11]); + val1 -= TIMES_41986(coeff[13]); + val1 -= TIMES_23783(coeff[15]); + val1 -= TIMES_14743(coeff[25]); + val1 -= TIMES_3459(coeff[27]); + val1 -= TIMES_17391(coeff[29]); + val1 -= TIMES_9851(coeff[31]); + + val2 = TIMES_27242(C1_17); + val2 -= TIMES_6392(C3_19); + val2 -= TIMES_32134(C5_21); + val2 -= TIMES_18202(C7_23); + + val3 = TIMES_16382(coeff[10]-coeff[30]); + val3 -= TIMES_39550(coeff[14]); + val3 += TIMES_6785(coeff[26]); + val3 += TIMES_12538(coeff[24]-coeff[28]); + val3 += TIMES_30270(coeff[8]-coeff[12]); + + t=(base + val1 + val2 + val3 + C4 + C20) >> 17; + out[1]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3) >> 17; + out[6]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 + C4 - C16 + C20) >> 17; + out[25]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 + C20) >> 17; + out[30]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//2,5,26,29 + + base = 0x1000000; + base += coeff[0] - coeff[4] + coeff[16] - coeff[20]; + base -= TIMES_12538(C2_18); + base += TIMES_30270(C6_22); + + val1 = TIMES_23783(coeff[9]); + val1 -= TIMES_41986(coeff[11]); + val1 += TIMES_8351(coeff[13]); + val1 += TIMES_35594(coeff[15]); + val1 += TIMES_9851(coeff[25]); + val1 -= TIMES_17391(coeff[27]); + val1 += TIMES_3459(coeff[29]); + val1 += TIMES_14743(coeff[31]); + + val2 = TIMES_18202(C1_17); + val2 -= TIMES_32134(C3_19); + val2 += TIMES_6392(C5_21); + val2 += TIMES_27242(C7_23); + + val3 = -TIMES_16382(coeff[10] - coeff[30]); + val3 += TIMES_39550(coeff[14]); + val3 -= TIMES_6785(coeff[26]); + val3 += TIMES_12538(coeff[24] - coeff[28]); + val3 += TIMES_30270(coeff[8] - coeff[12]); + + t=(base + val1 + val2 + val3) >> 17; + out[2]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3) >> 17; + out[5]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - C16) >> 17; + out[26]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 + C4 - C16 + C20) >> 17; + out[29]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//3,4,27,28 + + base = 0x1000000; + base += coeff[0] + coeff[4] + coeff[16] + coeff[20]; + base -= TIMES_30270(C2_18); + base -= TIMES_12538(C6_22); + + val1 = TIMES_8351(coeff[9]); + val1 -= TIMES_23783(coeff[11]); + val1 += TIMES_35594(coeff[13]); + val1 += TIMES_3459(coeff[25]); + val1 -= TIMES_9851(coeff[27]); + val1 += TIMES_14743(coeff[29]); + + val2 = TIMES_6392(C1_17); + val2 -= TIMES_18202(C3_19); + val2 += TIMES_27242(C5_21); + + val3 = -TIMES_39550(coeff[10]); + val3 += TIMES_16382(coeff[14] + coeff[26]); + val3 -= TIMES_6785(coeff[30]); + val3 += TIMES_30270(coeff[8] + coeff[12]); + val3 += TIMES_12538(coeff[24] + coeff[28]); + + tmp1 = TIMES_32134(C7_23); + tmp2 = TIMES_41986(coeff[15]) + TIMES_17391(coeff[31]); + + t=(base + val1 + val2 + val3 - tmp1 - tmp2 - C4 - C20) >> 17; + out[3]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3) >> 17; + out[4]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - tmp1 + tmp2) >> 17; + out[27]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 - C16 - C20) >> 17; + out[28]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +// Second half + C2_18 = coeff[2] - coeff[18]; + C6_22 = coeff[6] - coeff[22]; + C1_17 = coeff[1] - coeff[17]; + C3_19 = coeff[3] - coeff[19]; + C5_21 = coeff[5] - coeff[21]; + C7_23 = coeff[7] - coeff[23]; + +// 8,15,16,23 + + base = 0x1000000; + base += coeff[0] + coeff[4] - coeff[16] - coeff[20]; + base +=TIMES_30270(C2_18); + base +=TIMES_12538(C6_22); + + val1 = TIMES_17391(coeff[9]); + val1 += TIMES_14743(coeff[11]); + val1 += TIMES_9851(coeff[13]); + val1 += TIMES_3459(coeff[15]); + val1 -= TIMES_41986(coeff[25]); + val1 -= TIMES_35594(coeff[27]); + val1 -= TIMES_23783(coeff[29]); + val1 -= TIMES_8351(coeff[31]); + + val2 = TIMES_32134(C1_17); + val2 += TIMES_27242(C3_19); + val2 += TIMES_18202(C5_21); + val2 += TIMES_6392(C7_23); + + val3 = TIMES_16382(coeff[10] - coeff[30]); + val3 += TIMES_6785(coeff[14]); + val3 -= TIMES_39550(coeff[26]); + val3 -=TIMES_30270(coeff[24] + coeff[28]); + val3 +=TIMES_12538(coeff[8] + coeff[12]); + + t=(base + val1 + val2 + val3) >> 17; + out[8]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 - C4 + C16 + C20) >> 17; + out[15]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3) >> 17; + out[16]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 - C4 + C20) >> 17; + out[23]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//9,14,17,22 + + base = 0x1000000; + base += coeff[0] - coeff[4] - coeff[16] + coeff[20]; + base += TIMES_12538(C2_18); + base -= TIMES_30270(C6_22); + + val1 = TIMES_14743(coeff[9]); + val1 -= TIMES_3459(coeff[11]); + val1 -= TIMES_17391(coeff[13]); + val1 -= TIMES_9851(coeff[15]); + val1 -= TIMES_35594(coeff[25]); + val1 += TIMES_8351(coeff[27]); + val1 += TIMES_41986(coeff[29]); + val1 += TIMES_23783(coeff[31]); + + val2 = TIMES_27242(C1_17); + val2 -= TIMES_6392(C3_19); + val2 -= TIMES_32134(C5_21); + val2 -= TIMES_18202(C7_23); + + val3 = TIMES_6785(coeff[10]); + val3 -= TIMES_16382(coeff[14] + coeff[26]); + val3 += TIMES_39550(coeff[30]); + val3 += TIMES_12538(coeff[8] - coeff[12]); + val3 -= TIMES_30270(coeff[24] - coeff[28]); + + t=(base + val1 + val2 + val3 + C4 + C16 - C20) >> 17; + out[9]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 + C16) >> 17; + out[14]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 + C4) >> 17; + out[17]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3) >> 17; + out[22]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +//10,13,18,21 + + base = 0x1000000; + base += coeff[0] - coeff[4] - coeff[16] + coeff[20]; + base -= TIMES_12538(C2_18); + base += TIMES_30270(C6_22); + + val1 = TIMES_9851(coeff[9]); + val1 -= TIMES_17391(coeff[11]); + val1 += TIMES_3459(coeff[13]); + val1 += TIMES_14743(coeff[15]); + val1 -= TIMES_23783(coeff[25]); + val1 += TIMES_41986(coeff[27]); + val1 -= TIMES_8351(coeff[29]); + val1 -= TIMES_35594(coeff[31]); + + val2 = TIMES_18202(C1_17); + val2 -= TIMES_32134(C3_19); + val2 += TIMES_6392(C5_21); + val2 += TIMES_27242(C7_23); + + val3 = -TIMES_6785(coeff[10]); + val3 += TIMES_16382(coeff[14]+coeff[26]); + val3 -= TIMES_39550(coeff[30]); + val3 += TIMES_12538(coeff[8]-coeff[12]); + val3 -= TIMES_30270(coeff[24]-coeff[28]); + + t=(base + val1 + val2 + val3) >> 17; + out[10]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 + C4 + C16 - C20) >> 17; + out[13]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3) >> 17; + out[18]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3 + C4) >> 17; + out[21]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + +// 11,12,19,20 + + base = 0x1000000; + base += coeff[0]+coeff[4]-coeff[16]-coeff[20]; + base -= TIMES_30270(C2_18); + base -= TIMES_12538(C6_22); + + val1 = TIMES_3459(coeff[9]); + val1 -= TIMES_9851(coeff[11]); + val1 += TIMES_14743(coeff[13]); + val1 -= TIMES_8351(coeff[25]); + val1 += TIMES_23783(coeff[27]); + val1 -= TIMES_35594(coeff[29]); + + val2 = TIMES_6392(C1_17); + val2 -= TIMES_18202(C3_19); + val2 += TIMES_27242(C5_21); + + val3 = -TIMES_16382(coeff[10] - coeff[30]); + val3 -= TIMES_6785(coeff[14]); + val3 += TIMES_39550(coeff[26]); + val3 -= TIMES_30270(coeff[24]+coeff[28]); + val3 += TIMES_12538(coeff[8]+coeff[12]); + + tmp1 = TIMES_32134(C7_23); + tmp2 = -TIMES_17391(coeff[15]) + TIMES_41986(coeff[31]); + + t=(base + val1 + val2 + val3 - tmp1 + tmp2 + C16 + C20) >> 17; + out[11]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 - val2 + val3 + C16 + C20) >> 17; + out[12]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base - val1 + val2 - val3 - tmp1 - tmp2 - C4 + C20) >> 17; + out[19]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; + t=(base + val1 - val2 - val3) >> 17; + out[20]= t&0xFFFFFF00? t<0?0:255 : (unsigned char)t; +} + +#undef TIMES_16382 +#undef TIMES_23168 +#undef TIMES_30270 +#undef TIMES_41986 +#undef TIMES_35594 +#undef TIMES_23783 +#undef TIMES_8351 +#undef TIMES_17391 +#undef TIMES_14743 +#undef TIMES_9851 +#undef TIMES_3459 +#undef TIMES_32134 +#undef TIMES_27242 +#undef TIMES_18202 +#undef TIMES_6392 +#undef TIMES_39550 +#undef TIMES_6785 +#undef TIMES_12538 + +/****************************************************************************** + * Main Decoder Functions + ******************************************************************************/ + +/* This function handles the decompression of a single 8x4 block. It is + * independent of the palette (YUV422, YUV420, YUV400, GBR422...). cinfo->bytes + * determines the positin in the input buffer. + */ +static int +decompress8x4(unsigned char *pOut, + unsigned char *pIn, + int *lastDC, + int uvFlag, + struct comp_info *cinfo) +{ + int i, x, y, dc; + int coeffs[32]; + int deZigZag[32]; + int *dest; + int *src; + unsigned char *qt = cinfo->qt; + + if (! uvFlag) { + huffmanDecoderY(coeffs, (int*) pIn, cinfo); + + /* iDPCM and dequantize first coefficient */ + dc = (*lastDC) + coeffs[0]; + coeffs[0] = dc * (qt[0] + 1); + *lastDC = dc; + + /* ...and the second coefficient */ + coeffs[1] = ((qt[1] + 1) * coeffs[1]) >> 1; + + /* Dequantize, starting at 3rd element */ + for (i = 2; i < 32; i++) + coeffs[i] = (qt[i] + 1) * coeffs[i]; + } else { + huffmanDecoderUV(coeffs, (int*) pIn, cinfo); + + /* iDPCM */ + dc = (*lastDC) + coeffs[0]; + coeffs[0] = dc; + *lastDC = dc; + + /* Dequantize */ + for (i = 0; i < 32; i++) + coeffs[i] = (qt[32 + i] + 1) * coeffs[i]; + } + + /* Dezigzag */ + for (i = 0; i < 32; i++) + deZigZag[i] = coeffs[ZigZag518[i]]; + + /* Transpose the dezigzagged coefficient matrix */ + src = deZigZag; + dest = coeffs; + for (y = 0; y <= 3; ++y) { + for (x = 0; x <= 7; ++x) { + dest[x] = src[x * 4]; + } + src += 1; + dest += 8; + } + + /* Do the inverse DCT transform */ + DCT_8x4(coeffs, pOut); + + return 0; /* Always returns 0 */ +} + +static inline void +copyBlock(unsigned char *src, unsigned char *dest, int destInc) +{ + int i; + unsigned int *pSrc, *pDest; + + for (i = 0; i <= 3; i++) { + pSrc = (unsigned int *) src; + pDest = (unsigned int *) dest; + pDest[0] = pSrc[0]; + pDest[1] = pSrc[1]; + src += 8; + dest += destInc; + } +} + +static inline int +decompress400NoMMXOV518(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + const int w, + const int h, + const int numpix, + struct comp_info *cinfo) +{ + int iOutY, x, y; + int lastYDC = 0; + + /* Start Y loop */ + y = 0; + do { + iOutY = w * y; + x = 0; + do { + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + x += 8; + } while (x < w); + y += 4; + } while (y < h); + + /* Did we decode too much? */ + if (cinfo->bytes > cinfo->rawLen + 897) + return 1; + + /* Did we decode enough? */ + if (cinfo->bytes >= cinfo->rawLen - 897) + return 0; + else + return 1; +} + +static inline int +decompress420NoMMXOV518(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + const int w, + const int h, + const int numpix, + struct comp_info *cinfo) +{ + unsigned char *pOutU = pOut + numpix; + unsigned char *pOutV = pOutU + numpix / 4; + int iOutY, iOutU, iOutV, x, y; + int lastYDC = 0; + int lastUDC = 0; + int lastVDC = 0; + + /* Start Y loop */ + y = 0; + do { + iOutY = w * y; + iOutV = iOutU = iOutY / 4; + + x = 0; + do { + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + x += 8; + } while (x < w); + + + + iOutY = w * (y + 4); + x = 0; + do { + decompress8x4(pTmp, pIn, &lastUDC, 1, cinfo); + copyBlock(pTmp, pOutU + iOutU, w/2); + iOutU += 8; + + decompress8x4(pTmp, pIn, &lastVDC, 1, cinfo); + copyBlock(pTmp, pOutV + iOutV, w/2); + iOutV += 8; + + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + + decompress8x4(pTmp, pIn, &lastYDC, 0, cinfo); + copyBlock(pTmp, pOut + iOutY, w); + iOutY += 8; + + x += 16; + } while (x < w); + + y += 8; + } while (y < h); + + /* Did we decode too much? */ + if (cinfo->bytes > cinfo->rawLen + 897) + return 1; + + /* Did we decode enough? */ + if (cinfo->bytes >= cinfo->rawLen - 897) + return 0; + else + return 1; +} + +/* Get quantization tables from static arrays + * Returns: <0 if error, or >=0 otherwise */ +static int +get_qt_static(struct comp_info *cinfo) +{ + unsigned char qtY[] = OV518_YQUANTABLE; + unsigned char qtUV[] = OV518_UVQUANTABLE; + unsigned char qt[64]; + + memcpy(qt, qtY, 32); + memcpy(qt + 32, qtUV, 32); + cinfo->qt = qt; + + return 0; +} + + +/* Get quantization tables from input + * Returns: <0 if error, or >=0 otherwise */ +static int +get_qt_dynamic(unsigned char *pIn, struct comp_info *cinfo) +{ + int rawLen = cinfo->rawLen; + + /* Make sure input is actually big enough to hold trailer */ + if (rawLen < 72) { + PDEBUG(1, "Not enough input to decompress"); + return -EINVAL; + } + + cinfo->qt = pIn + rawLen - 64; + + print_qt(cinfo->qt); + + return 0; +} + +/* Input format is raw isoc. data (with intact SOF header, packet numbers + * stripped, and all-zero blocks removed). + * Output format is planar YUV400 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress400(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + struct comp_info cinfo; + int numpix = w * h; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut, + pTmp, inSize); + + cinfo.bytes = 0; + cinfo.bits = 0; + cinfo.rawLen = inSize; + + if (staticquant) { + if (get_qt_static(&cinfo) < 0) + return 0; + } else { + if (get_qt_dynamic(pIn, &cinfo) < 0) + return 0; + } + + /* Decompress, skipping the 8-byte SOF header */ + if (decompress400NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo)) +// return 0; + ; /* Don't return error yet */ + + return (numpix); +} + +/* Input format is raw isoc. data (with intact SOF header, packet numbers + * stripped, and all-zero blocks removed). + * Output format is planar YUV420 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress420(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + struct comp_info cinfo; + int numpix = w * h; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p pTmp=%p inSize=%d", w, h, pIn, pOut, + pTmp, inSize); + + cinfo.bytes = 0; + cinfo.bits = 0; + cinfo.rawLen = inSize; + + if (staticquant) { + if (get_qt_static(&cinfo) < 0) + return 0; + } else { + if (get_qt_dynamic(pIn, &cinfo) < 0) + return 0; + } + + /* Decompress, skipping the 8-byte SOF header */ + if (decompress420NoMMXOV518(pIn + 8, pOut, pTmp, w, h, numpix, &cinfo)) +// return 0; + ; /* Don't return error yet */ + + return (numpix * 3 / 2); +} + +/****************************************************************************** + * Module Functions + ******************************************************************************/ + +static struct ov51x_decomp_ops decomp_ops = { + .decomp_400 = Decompress400, + .decomp_420 = Decompress420, + .owner = THIS_MODULE, +}; + +static int __init +decomp_init(void) +{ + int rc; + + rc = ov511_register_decomp_module(DECOMP_INTERFACE_VER, &decomp_ops, + ov518, mmx); + if (rc) { + err("Could not register with ov511 (rc=%d)", rc); + return -1; + } + + info(DRIVER_VERSION " : " DRIVER_DESC); + PDEBUG(1, "Using %s, %s quantization", IDCT_MESSAGE, + staticquant ? "static" : "dynamic"); + + return 0; +} + +static void __exit +decomp_exit(void) +{ + ov511_deregister_decomp_module(ov518, mmx); + info("deregistered"); +} + +module_init(decomp_init); +module_exit(decomp_exit); --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov511.c +++ linux-2.6.28/ubuntu/misc/media/ov511/ov511.c @@ -0,0 +1,6123 @@ +/* + * OmniVision OV511 Camera-to-USB Bridge Driver + * + * Copyright (c) 1999-2003 Mark W. McClelland + * Original decompression code Copyright 1998-2000 OmniVision Technologies + * Many improvements by Bret Wallach + * Color fixes by by Orion Sky Lawlor (2/26/2000) + * Snapshot code by Kevin Moore + * OV7620 fixes by Charl P. Botha + * Changes by Claudio Matsuoka + * Original SAA7111A code by Dave Perks + * URB error messages from pwc driver by Nemosoft + * generic_ioctl() code from videodev.c by Gerd Knorr and Alan Cox + * Memory management (rvmalloc) code from bttv driver, by Gerd Knorr and others + * + * Based on the Linux CPiA driver written by Peter Pregler, + * Scott J. Bertin and Johannes Erdfelt. + * + * Please see the file: Documentation/usb/ov511.txt + * and the website at: http://alpha.dyndns.org/ov511 + * for more info. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (__i386__) + #include +#endif + +#include "ov511.h" + +/* + * Version Information + */ +#define DRIVER_VERSION "v1.64 for Linux 2.5" +#define EMAIL "mark@alpha.dyndns.org" +#define DRIVER_AUTHOR "Mark McClelland & Bret Wallach \ + & Orion Sky Lawlor & Kevin Moore & Charl P. Botha \ + & Claudio Matsuoka " +#define DRIVER_DESC "ov511 USB Camera Driver" + +#define OV511_I2C_RETRIES 3 +#define ENABLE_Y_QUANTABLE 1 +#define ENABLE_UV_QUANTABLE 1 + +#define OV511_MAX_UNIT_VIDEO 16 + +/* Pixel count * bytes per YUV420 pixel (1.5) */ +#define MAX_FRAME_SIZE(w, h) ((w) * (h) * 3 / 2) + +#define MAX_DATA_SIZE(w, h) (MAX_FRAME_SIZE(w, h) + sizeof(struct timeval)) + +/* Max size * bytes per YUV420 pixel (1.5) + one extra isoc frame for safety */ +#define MAX_RAW_DATA_SIZE(w, h) ((w) * (h) * 3 / 2 + 1024) + +#define FATAL_ERROR(rc) ((rc) < 0 && (rc) != -EPERM) + +/********************************************************************** + * Module Parameters + * (See ov511.txt for detailed descriptions of these) + **********************************************************************/ + +/* These variables (and all static globals) default to zero */ +static int autobright = 1; +static int autogain = 1; +static int autoexp = 1; +static int debug; +static int snapshot; +static int cams = 1; +static int compress; +static int testpat; +static int dumppix; +static int led = 1; +static int dump_bridge; +static int dump_sensor; +static int printph; +static int phy = 0x1f; +static int phuv = 0x05; +static int pvy = 0x06; +static int pvuv = 0x06; +static int qhy = 0x14; +static int qhuv = 0x03; +static int qvy = 0x04; +static int qvuv = 0x04; +static int lightfreq; +static int bandingfilter; +static int clockdiv = -1; +static int packetsize = -1; +static int framedrop = -1; +static int fastset; +static int force_palette; +static int backlight; +static int unit_video[OV511_MAX_UNIT_VIDEO]; +static int remove_zeros; +static int mirror; +static int ov518_color; + +module_param(autobright, int, 0); +MODULE_PARM_DESC(autobright, "Sensor automatically changes brightness"); +module_param(autogain, int, 0); +MODULE_PARM_DESC(autogain, "Sensor automatically changes gain"); +module_param(autoexp, int, 0); +MODULE_PARM_DESC(autoexp, "Sensor automatically changes exposure"); +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, + "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max"); +module_param(snapshot, int, 0); +MODULE_PARM_DESC(snapshot, "Enable snapshot mode"); +module_param(cams, int, 0); +MODULE_PARM_DESC(cams, "Number of simultaneous cameras"); +module_param(compress, int, 0); +MODULE_PARM_DESC(compress, "Turn on compression"); +module_param(testpat, int, 0); +MODULE_PARM_DESC(testpat, + "Replace image with vertical bar testpattern (only partially working)"); +module_param(dumppix, int, 0); +MODULE_PARM_DESC(dumppix, "Dump raw pixel data"); +module_param(led, int, 0); +MODULE_PARM_DESC(led, + "LED policy (OV511+ or later). 0=off, 1=on (default), 2=auto (on when open)"); +module_param(dump_bridge, int, 0); +MODULE_PARM_DESC(dump_bridge, "Dump the bridge registers"); +module_param(dump_sensor, int, 0); +MODULE_PARM_DESC(dump_sensor, "Dump the sensor registers"); +module_param(printph, int, 0); +MODULE_PARM_DESC(printph, "Print frame start/end headers"); +module_param(phy, int, 0); +MODULE_PARM_DESC(phy, "Prediction range (horiz. Y)"); +module_param(phuv, int, 0); +MODULE_PARM_DESC(phuv, "Prediction range (horiz. UV)"); +module_param(pvy, int, 0); +MODULE_PARM_DESC(pvy, "Prediction range (vert. Y)"); +module_param(pvuv, int, 0); +MODULE_PARM_DESC(pvuv, "Prediction range (vert. UV)"); +module_param(qhy, int, 0); +MODULE_PARM_DESC(qhy, "Quantization threshold (horiz. Y)"); +module_param(qhuv, int, 0); +MODULE_PARM_DESC(qhuv, "Quantization threshold (horiz. UV)"); +module_param(qvy, int, 0); +MODULE_PARM_DESC(qvy, "Quantization threshold (vert. Y)"); +module_param(qvuv, int, 0); +MODULE_PARM_DESC(qvuv, "Quantization threshold (vert. UV)"); +module_param(lightfreq, int, 0); +MODULE_PARM_DESC(lightfreq, + "Light frequency. Set to 50 or 60 Hz, or zero for default settings"); +module_param(bandingfilter, int, 0); +MODULE_PARM_DESC(bandingfilter, + "Enable banding filter (to reduce effects of fluorescent lighting)"); +module_param(clockdiv, int, 0); +MODULE_PARM_DESC(clockdiv, "Force pixel clock divisor to a specific value"); +module_param(packetsize, int, 0); +MODULE_PARM_DESC(packetsize, "Force a specific isoc packet size"); +module_param(framedrop, int, 0); +MODULE_PARM_DESC(framedrop, "Force a specific frame drop register setting"); +module_param(fastset, int, 0); +MODULE_PARM_DESC(fastset, "Allows picture settings to take effect immediately"); +module_param(force_palette, int, 0); +MODULE_PARM_DESC(force_palette, "Force the palette to a specific value"); +module_param(backlight, int, 0); +MODULE_PARM_DESC(backlight, "For objects that are lit from behind"); +static int num_uv; +module_param_array(unit_video, int, &num_uv, 0); +MODULE_PARM_DESC(unit_video, + "Force use of specific minor number(s). 0 is not allowed."); +module_param(remove_zeros, int, 0); +MODULE_PARM_DESC(remove_zeros, + "Remove zero-padding from uncompressed incoming data"); +module_param(mirror, int, 0); +MODULE_PARM_DESC(mirror, "Reverse image horizontally"); +module_param(ov518_color, int, 0); +MODULE_PARM_DESC(ov518_color, "Enable OV518 color (experimental)"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); + +/********************************************************************** + * Miscellaneous Globals + **********************************************************************/ + +static struct usb_driver ov511_driver; + +static struct ov51x_decomp_ops *ov511_decomp_ops; +static struct ov51x_decomp_ops *ov511_mmx_decomp_ops; +static struct ov51x_decomp_ops *ov518_decomp_ops; +static struct ov51x_decomp_ops *ov518_mmx_decomp_ops; + +/* Number of times to retry a failed I2C transaction. Increase this if you + * are getting "Failed to read sensor ID..." */ +static int i2c_detect_tries = 5; + +/* MMX support is present in kernel and CPU. Checked upon decomp module load. */ +#if defined(__i386__) || defined(__x86_64__) +#define ov51x_mmx_available (cpu_has_mmx) +#else +#define ov51x_mmx_available (0) +#endif + +static struct usb_device_id device_table [] = { + { USB_DEVICE(VEND_OMNIVISION, PROD_OV511) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV511PLUS) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV518) }, + { USB_DEVICE(VEND_OMNIVISION, PROD_OV518PLUS) }, + { USB_DEVICE(VEND_MATTEL, PROD_ME2CAM) }, + { } /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, device_table); + +static unsigned char yQuanTable511[] = OV511_YQUANTABLE; +static unsigned char uvQuanTable511[] = OV511_UVQUANTABLE; +static unsigned char yQuanTable518[] = OV518_YQUANTABLE; +static unsigned char uvQuanTable518[] = OV518_UVQUANTABLE; + +/********************************************************************** + * Symbolic Names + **********************************************************************/ + +/* Known OV511-based cameras */ +static struct symbolic_list camlist[] = { + { 0, "Generic Camera (no ID)" }, + { 1, "Mustek WCam 3X" }, + { 3, "D-Link DSB-C300" }, + { 4, "Generic OV511/OV7610" }, + { 5, "Puretek PT-6007" }, + { 6, "Lifeview USB Life TV (NTSC)" }, + { 21, "Creative Labs WebCam 3" }, + { 22, "Lifeview USB Life TV (PAL D/K+B/G)" }, + { 36, "Koala-Cam" }, + { 38, "Lifeview USB Life TV (PAL)" }, + { 41, "Samsung Anycam MPC-M10" }, + { 43, "Mtekvision Zeca MV402" }, + { 46, "Suma eON" }, + { 70, "Lifeview USB Life TV (PAL/SECAM)" }, + { 100, "Lifeview RoboCam" }, + { 102, "AverMedia InterCam Elite" }, + { 112, "MediaForte MV300" }, /* or OV7110 evaluation kit */ + { 134, "Ezonics EZCam II" }, + { 192, "Webeye 2000B" }, + { 253, "Alpha Vision Tech. AlphaCam SE" }, + { -1, NULL } +}; + +/* Video4Linux1 Palettes */ +static struct symbolic_list v4l1_plist[] = { + { VIDEO_PALETTE_GREY, "GREY" }, + { VIDEO_PALETTE_HI240, "HI240" }, + { VIDEO_PALETTE_RGB565, "RGB565" }, + { VIDEO_PALETTE_RGB24, "RGB24" }, + { VIDEO_PALETTE_RGB32, "RGB32" }, + { VIDEO_PALETTE_RGB555, "RGB555" }, + { VIDEO_PALETTE_YUV422, "YUV422" }, + { VIDEO_PALETTE_YUYV, "YUYV" }, + { VIDEO_PALETTE_UYVY, "UYVY" }, + { VIDEO_PALETTE_YUV420, "YUV420" }, + { VIDEO_PALETTE_YUV411, "YUV411" }, + { VIDEO_PALETTE_RAW, "RAW" }, + { VIDEO_PALETTE_YUV422P,"YUV422P" }, + { VIDEO_PALETTE_YUV411P,"YUV411P" }, + { VIDEO_PALETTE_YUV420P,"YUV420P" }, + { VIDEO_PALETTE_YUV410P,"YUV410P" }, + { -1, NULL } +}; + +static struct symbolic_list brglist[] = { + { BRG_OV511, "OV511" }, + { BRG_OV511PLUS, "OV511+" }, + { BRG_OV518, "OV518" }, + { BRG_OV518PLUS, "OV518+" }, + { -1, NULL } +}; + +static struct symbolic_list senlist[] = { + { SEN_OV76BE, "OV76BE" }, + { SEN_OV7610, "OV7610" }, + { SEN_OV7620, "OV7620" }, + { SEN_OV7620AE, "OV7620AE" }, + { SEN_OV6620, "OV6620" }, + { SEN_OV6630, "OV6630" }, + { SEN_OV6630AE, "OV6630AE" }, + { SEN_OV6630AF, "OV6630AF" }, + { SEN_OV8600, "OV8600" }, + { SEN_KS0127, "KS0127" }, + { SEN_KS0127B, "KS0127B" }, + { SEN_SAA7111A, "SAA7111A" }, + { -1, NULL } +}; + +/* URB error codes: */ +static struct symbolic_list urb_errlist[] = { + { -ENOSR, "Buffer error (overrun)" }, + { -EPIPE, "Stalled (device not responding)" }, + { -EOVERFLOW, "Babble (bad cable?)" }, + { -EPROTO, "Bit-stuff error (bad cable?)" }, + { -EILSEQ, "CRC/Timeout" }, + { -ETIMEDOUT, "NAK (device does not respond)" }, + { -1, NULL } +}; + +/********************************************************************** + * Memory management + **********************************************************************/ +static void * +rvmalloc(unsigned long size) +{ + void *mem; + unsigned long adr; + + size = PAGE_ALIGN(size); + mem = vmalloc_32(size); + if (!mem) + return NULL; + + memset(mem, 0, size); /* Clear the ram out, no junk to the user */ + adr = (unsigned long) mem; + while (size > 0) { + SetPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + + return mem; +} + +static void +rvfree(void *mem, unsigned long size) +{ + unsigned long adr; + + if (!mem) + return; + + adr = (unsigned long) mem; + while ((long) size > 0) { + ClearPageReserved(vmalloc_to_page((void *)adr)); + adr += PAGE_SIZE; + size -= PAGE_SIZE; + } + vfree(mem); +} + +/********************************************************************** + * + * Register I/O + * + **********************************************************************/ + +/* Write an OV51x register */ +static int +reg_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) +{ + int rc; + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + down(&ov->cbuf_lock); + ov->cbuf[0] = value; + rc = usb_control_msg(ov->dev, + usb_sndctrlpipe(ov->dev, 0), + (ov->bclass == BCL_OV518)?1:2 /* REG_IO */, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, (__u16)reg, &ov->cbuf[0], 1, 1000); + up(&ov->cbuf_lock); + + if (rc < 0) + err("reg write: error %d: %s", rc, symbolic(urb_errlist, rc)); + + return rc; +} + +/* Read from an OV51x register */ +/* returns: negative is error, pos or zero is data */ +static int +reg_r(struct usb_ov511 *ov, unsigned char reg) +{ + int rc; + + down(&ov->cbuf_lock); + rc = usb_control_msg(ov->dev, + usb_rcvctrlpipe(ov->dev, 0), + (ov->bclass == BCL_OV518)?1:3 /* REG_IO */, + USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, (__u16)reg, &ov->cbuf[0], 1, 1000); + + if (rc < 0) { + err("reg read: error %d: %s", rc, symbolic(urb_errlist, rc)); + } else { + rc = ov->cbuf[0]; + PDEBUG(5, "0x%02X:0x%02X", reg, ov->cbuf[0]); + } + + up(&ov->cbuf_lock); + + return rc; +} + +/* + * Writes bits at positions specified by mask to an OV51x reg. Bits that are in + * the same position as 1's in "mask" are cleared and set to "value". Bits + * that are in the same position as 0's in "mask" are preserved, regardless + * of their respective state in "value". + */ +static int +reg_w_mask(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int ret; + unsigned char oldval, newval; + + ret = reg_r(ov, reg); + if (ret < 0) + return ret; + + oldval = (unsigned char) ret; + oldval &= (~mask); /* Clear the masked bits */ + value &= mask; /* Enforce mask on value */ + newval = oldval | value; /* Set the desired bits */ + + return (reg_w(ov, reg, newval)); +} + +/* + * Writes multiple (n) byte value to a single register. Only valid with certain + * registers (0x30 and 0xc4 - 0xce). + */ +static int +ov518_reg_w32(struct usb_ov511 *ov, unsigned char reg, u32 val, int n) +{ + int rc; + + PDEBUG(5, "0x%02X:%7d, n=%d", reg, val, n); + + down(&ov->cbuf_lock); + + *((__le32 *)ov->cbuf) = __cpu_to_le32(val); + + rc = usb_control_msg(ov->dev, + usb_sndctrlpipe(ov->dev, 0), + 1 /* REG_IO */, + USB_TYPE_VENDOR | USB_RECIP_DEVICE, + 0, (__u16)reg, ov->cbuf, n, 1000); + up(&ov->cbuf_lock); + + if (rc < 0) + err("reg write multiple: error %d: %s", rc, + symbolic(urb_errlist, rc)); + + return rc; +} + +static int +ov511_upload_quan_tables(struct usb_ov511 *ov) +{ + unsigned char *pYTable = yQuanTable511; + unsigned char *pUVTable = uvQuanTable511; + unsigned char val0, val1; + int i, rc, reg = R511_COMP_LUT_BEGIN; + + PDEBUG(4, "Uploading quantization tables"); + + for (i = 0; i < OV511_QUANTABLESIZE / 2; i++) { + if (ENABLE_Y_QUANTABLE) { + val0 = *pYTable++; + val1 = *pYTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg, val0); + if (rc < 0) + return rc; + } + + if (ENABLE_UV_QUANTABLE) { + val0 = *pUVTable++; + val1 = *pUVTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg + OV511_QUANTABLESIZE/2, val0); + if (rc < 0) + return rc; + } + + reg++; + } + + return 0; +} + +/* OV518 quantization tables are 8x4 (instead of 8x8) */ +static int +ov518_upload_quan_tables(struct usb_ov511 *ov) +{ + unsigned char *pYTable = yQuanTable518; + unsigned char *pUVTable = uvQuanTable518; + unsigned char val0, val1; + int i, rc, reg = R511_COMP_LUT_BEGIN; + + PDEBUG(4, "Uploading quantization tables"); + + for (i = 0; i < OV518_QUANTABLESIZE / 2; i++) { + if (ENABLE_Y_QUANTABLE) { + val0 = *pYTable++; + val1 = *pYTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg, val0); + if (rc < 0) + return rc; + } + + if (ENABLE_UV_QUANTABLE) { + val0 = *pUVTable++; + val1 = *pUVTable++; + val0 &= 0x0f; + val1 &= 0x0f; + val0 |= val1 << 4; + rc = reg_w(ov, reg + OV518_QUANTABLESIZE/2, val0); + if (rc < 0) + return rc; + } + + reg++; + } + + return 0; +} + +static int +ov51x_reset(struct usb_ov511 *ov, unsigned char reset_type) +{ + int rc; + + /* Setting bit 0 not allowed on 518/518Plus */ + if (ov->bclass == BCL_OV518) + reset_type &= 0xfe; + + PDEBUG(4, "Reset: type=0x%02X", reset_type); + + rc = reg_w(ov, R51x_SYS_RESET, reset_type); + rc = reg_w(ov, R51x_SYS_RESET, 0); + + if (rc < 0) + err("reset: command failed"); + + return rc; +} + +/********************************************************************** + * + * Low-level I2C I/O functions + * + **********************************************************************/ + +/* NOTE: Do not call this function directly! + * The OV518 I2C I/O procedure is different, hence, this function. + * This is normally only called from i2c_w(). Note that this function + * always succeeds regardless of whether the sensor is present and working. + */ +static int +ov518_i2c_write_internal(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value) +{ + int rc; + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_3, reg); + if (rc < 0) + return rc; + + /* Write "value" to I2C data port of OV511 */ + rc = reg_w(ov, R51x_I2C_DATA, value); + if (rc < 0) + return rc; + + /* Initiate 3-byte write cycle */ + rc = reg_w(ov, R518_I2C_CTL, 0x01); + if (rc < 0) + return rc; + + return 0; +} + +/* NOTE: Do not call this function directly! */ +static int +ov511_i2c_write_internal(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value) +{ + int rc, retries; + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + /* Three byte write cycle */ + for (retries = OV511_I2C_RETRIES; ; ) { + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_3, reg); + if (rc < 0) + break; + + /* Write "value" to I2C data port of OV511 */ + rc = reg_w(ov, R51x_I2C_DATA, value); + if (rc < 0) + break; + + /* Initiate 3-byte write cycle */ + rc = reg_w(ov, R511_I2C_CTL, 0x01); + if (rc < 0) + break; + + /* Retry until idle */ + do + rc = reg_r(ov, R511_I2C_CTL); + while (rc > 0 && ((rc&1) == 0)); + if (rc < 0) + break; + + /* Ack? */ + if ((rc&2) == 0) { + rc = 0; + break; + } +#if 0 + /* I2C abort */ + reg_w(ov, R511_I2C_CTL, 0x10); +#endif + if (--retries < 0) { + err("i2c write retries exhausted"); + rc = -1; + break; + } + } + + return rc; +} + +/* NOTE: Do not call this function directly! + * The OV518 I2C I/O procedure is different, hence, this function. + * This is normally only called from i2c_r(). Note that this function + * always succeeds regardless of whether the sensor is present and working. + */ +static int +ov518_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) +{ + int rc, value; + + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_2, reg); + if (rc < 0) + return rc; + + /* Initiate 2-byte write cycle */ + rc = reg_w(ov, R518_I2C_CTL, 0x03); + if (rc < 0) + return rc; + + /* Initiate 2-byte read cycle */ + rc = reg_w(ov, R518_I2C_CTL, 0x05); + if (rc < 0) + return rc; + + value = reg_r(ov, R51x_I2C_DATA); + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + return value; +} + +/* NOTE: Do not call this function directly! + * returns: negative is error, pos or zero is data */ +static int +ov511_i2c_read_internal(struct usb_ov511 *ov, unsigned char reg) +{ + int rc, value, retries; + + /* Two byte write cycle */ + for (retries = OV511_I2C_RETRIES; ; ) { + /* Select camera register */ + rc = reg_w(ov, R51x_I2C_SADDR_2, reg); + if (rc < 0) + return rc; + + /* Initiate 2-byte write cycle */ + rc = reg_w(ov, R511_I2C_CTL, 0x03); + if (rc < 0) + return rc; + + /* Retry until idle */ + do + rc = reg_r(ov, R511_I2C_CTL); + while (rc > 0 && ((rc&1) == 0)); + if (rc < 0) + return rc; + + if ((rc&2) == 0) /* Ack? */ + break; + + /* I2C abort */ + reg_w(ov, R511_I2C_CTL, 0x10); + + if (--retries < 0) { + err("i2c write retries exhausted"); + return -1; + } + } + + /* Two byte read cycle */ + for (retries = OV511_I2C_RETRIES; ; ) { + /* Initiate 2-byte read cycle */ + rc = reg_w(ov, R511_I2C_CTL, 0x05); + if (rc < 0) + return rc; + + /* Retry until idle */ + do + rc = reg_r(ov, R511_I2C_CTL); + while (rc > 0 && ((rc&1) == 0)); + if (rc < 0) + return rc; + + if ((rc&2) == 0) /* Ack? */ + break; + + /* I2C abort */ + rc = reg_w(ov, R511_I2C_CTL, 0x10); + if (rc < 0) + return rc; + + if (--retries < 0) { + err("i2c read retries exhausted"); + return -1; + } + } + + value = reg_r(ov, R51x_I2C_DATA); + + PDEBUG(5, "0x%02X:0x%02X", reg, value); + + /* This is needed to make i2c_w() work */ + rc = reg_w(ov, R511_I2C_CTL, 0x05); + if (rc < 0) + return rc; + + return value; +} + +/* returns: negative is error, pos or zero is data */ +static int +i2c_r(struct usb_ov511 *ov, unsigned char reg) +{ + int rc; + + down(&ov->i2c_lock); + + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_read_internal(ov, reg); + else + rc = ov511_i2c_read_internal(ov, reg); + + up(&ov->i2c_lock); + + return rc; +} + +static int +i2c_w(struct usb_ov511 *ov, unsigned char reg, unsigned char value) +{ + int rc; + + down(&ov->i2c_lock); + + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_write_internal(ov, reg, value); + else + rc = ov511_i2c_write_internal(ov, reg, value); + + up(&ov->i2c_lock); + + return rc; +} + +/* Do not call this function directly! */ +static int +ov51x_i2c_write_mask_internal(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int rc; + unsigned char oldval, newval; + + if (mask == 0xff) { + newval = value; + } else { + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_read_internal(ov, reg); + else + rc = ov511_i2c_read_internal(ov, reg); + if (rc < 0) + return rc; + + oldval = (unsigned char) rc; + oldval &= (~mask); /* Clear the masked bits */ + value &= mask; /* Enforce mask on value */ + newval = oldval | value; /* Set the desired bits */ + } + + if (ov->bclass == BCL_OV518) + return (ov518_i2c_write_internal(ov, reg, newval)); + else + return (ov511_i2c_write_internal(ov, reg, newval)); +} + +/* Writes bits at positions specified by mask to an I2C reg. Bits that are in + * the same position as 1's in "mask" are cleared and set to "value". Bits + * that are in the same position as 0's in "mask" are preserved, regardless + * of their respective state in "value". + */ +static int +i2c_w_mask(struct usb_ov511 *ov, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int rc; + + down(&ov->i2c_lock); + rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); + up(&ov->i2c_lock); + + return rc; +} + +/* Set the read and write slave IDs. The "slave" argument is the write slave, + * and the read slave will be set to (slave + 1). ov->i2c_lock should be held + * when calling this. This should not be called from outside the i2c I/O + * functions. + */ +static int +i2c_set_slave_internal(struct usb_ov511 *ov, unsigned char slave) +{ + int rc; + + rc = reg_w(ov, R51x_I2C_W_SID, slave); + if (rc < 0) + return rc; + + rc = reg_w(ov, R51x_I2C_R_SID, slave + 1); + if (rc < 0) + return rc; + + return 0; +} + +/* Write to a specific I2C slave ID and register, using the specified mask */ +static int +i2c_w_slave(struct usb_ov511 *ov, + unsigned char slave, + unsigned char reg, + unsigned char value, + unsigned char mask) +{ + int rc = 0; + + down(&ov->i2c_lock); + + /* Set new slave IDs */ + rc = i2c_set_slave_internal(ov, slave); + if (rc < 0) + goto out; + + rc = ov51x_i2c_write_mask_internal(ov, reg, value, mask); + +out: + /* Restore primary IDs */ + if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) + err("Couldn't restore primary I2C slave"); + + up(&ov->i2c_lock); + return rc; +} + +/* Read from a specific I2C slave ID and register */ +static int +i2c_r_slave(struct usb_ov511 *ov, + unsigned char slave, + unsigned char reg) +{ + int rc; + + down(&ov->i2c_lock); + + /* Set new slave IDs */ + rc = i2c_set_slave_internal(ov, slave); + if (rc < 0) + goto out; + + if (ov->bclass == BCL_OV518) + rc = ov518_i2c_read_internal(ov, reg); + else + rc = ov511_i2c_read_internal(ov, reg); + +out: + /* Restore primary IDs */ + if (i2c_set_slave_internal(ov, ov->primary_i2c_slave) < 0) + err("Couldn't restore primary I2C slave"); + + up(&ov->i2c_lock); + return rc; +} + +/* Sets I2C read and write slave IDs. Returns <0 for error */ +static int +ov51x_set_slave_ids(struct usb_ov511 *ov, unsigned char sid) +{ + int rc; + + down(&ov->i2c_lock); + + rc = i2c_set_slave_internal(ov, sid); + if (rc < 0) + goto out; + + // FIXME: Is this actually necessary? + rc = ov51x_reset(ov, OV511_RESET_NOREGS); +out: + up(&ov->i2c_lock); + return rc; +} + +static int +write_regvals(struct usb_ov511 *ov, struct ov511_regvals * pRegvals) +{ + int rc; + + while (pRegvals->bus != OV511_DONE_BUS) { + if (pRegvals->bus == OV511_REG_BUS) { + if ((rc = reg_w(ov, pRegvals->reg, pRegvals->val)) < 0) + return rc; + } else if (pRegvals->bus == OV511_I2C_BUS) { + if ((rc = i2c_w(ov, pRegvals->reg, pRegvals->val)) < 0) + return rc; + } else { + err("Bad regval array"); + return -1; + } + pRegvals++; + } + return 0; +} + +#ifdef OV511_DEBUG +static void +dump_i2c_range(struct usb_ov511 *ov, int reg1, int regn) +{ + int i, rc; + + for (i = reg1; i <= regn; i++) { + rc = i2c_r(ov, i); + info("Sensor[0x%02X] = 0x%02X", i, rc); + } +} + +static void +dump_i2c_regs(struct usb_ov511 *ov) +{ + info("I2C REGS"); + dump_i2c_range(ov, 0x00, 0x7C); +} + +static void +dump_reg_range(struct usb_ov511 *ov, int reg1, int regn) +{ + int i, rc; + + for (i = reg1; i <= regn; i++) { + rc = reg_r(ov, i); + info("OV511[0x%02X] = 0x%02X", i, rc); + } +} + +static void +ov511_dump_regs(struct usb_ov511 *ov) +{ + info("CAMERA INTERFACE REGS"); + dump_reg_range(ov, 0x10, 0x1f); + info("DRAM INTERFACE REGS"); + dump_reg_range(ov, 0x20, 0x23); + info("ISO FIFO REGS"); + dump_reg_range(ov, 0x30, 0x31); + info("PIO REGS"); + dump_reg_range(ov, 0x38, 0x39); + dump_reg_range(ov, 0x3e, 0x3e); + info("I2C REGS"); + dump_reg_range(ov, 0x40, 0x49); + info("SYSTEM CONTROL REGS"); + dump_reg_range(ov, 0x50, 0x55); + dump_reg_range(ov, 0x5e, 0x5f); + info("OmniCE REGS"); + dump_reg_range(ov, 0x70, 0x79); + /* NOTE: Quantization tables are not readable. You will get the value + * in reg. 0x79 for every table register */ + dump_reg_range(ov, 0x80, 0x9f); + dump_reg_range(ov, 0xa0, 0xbf); + +} + +static void +ov518_dump_regs(struct usb_ov511 *ov) +{ + info("VIDEO MODE REGS"); + dump_reg_range(ov, 0x20, 0x2f); + info("DATA PUMP AND SNAPSHOT REGS"); + dump_reg_range(ov, 0x30, 0x3f); + info("I2C REGS"); + dump_reg_range(ov, 0x40, 0x4f); + info("SYSTEM CONTROL AND VENDOR REGS"); + dump_reg_range(ov, 0x50, 0x5f); + info("60 - 6F"); + dump_reg_range(ov, 0x60, 0x6f); + info("70 - 7F"); + dump_reg_range(ov, 0x70, 0x7f); + info("Y QUANTIZATION TABLE"); + dump_reg_range(ov, 0x80, 0x8f); + info("UV QUANTIZATION TABLE"); + dump_reg_range(ov, 0x90, 0x9f); + info("A0 - BF"); + dump_reg_range(ov, 0xa0, 0xbf); + info("CBR"); + dump_reg_range(ov, 0xc0, 0xcf); +} +#endif + +/*****************************************************************************/ + +/* Temporarily stops OV511 from functioning. Must do this before changing + * registers while the camera is streaming */ +static inline int +ov51x_stop(struct usb_ov511 *ov) +{ + PDEBUG(4, "stopping"); + ov->stopped = 1; + if (ov->bclass == BCL_OV518) + return (reg_w_mask(ov, R51x_SYS_RESET, 0x3a, 0x3a)); + else + return (reg_w(ov, R51x_SYS_RESET, 0x3d)); +} + +/* Restarts OV511 after ov511_stop() is called. Has no effect if it is not + * actually stopped (for performance). */ +static inline int +ov51x_restart(struct usb_ov511 *ov) +{ + if (ov->stopped) { + PDEBUG(4, "restarting"); + ov->stopped = 0; + + /* Reinitialize the stream */ + if (ov->bclass == BCL_OV518) + reg_w(ov, 0x2f, 0x80); + + return (reg_w(ov, R51x_SYS_RESET, 0x00)); + } + + return 0; +} + +/* Sleeps until no frames are active. Returns !0 if got signal */ +static int +ov51x_wait_frames_inactive(struct usb_ov511 *ov) +{ + return wait_event_interruptible(ov->wq, ov->curframe < 0); +} + +/* Resets the hardware snapshot button */ +static void +ov51x_clear_snapshot(struct usb_ov511 *ov) +{ + if (ov->bclass == BCL_OV511) { + reg_w(ov, R51x_SYS_SNAP, 0x00); + reg_w(ov, R51x_SYS_SNAP, 0x02); + reg_w(ov, R51x_SYS_SNAP, 0x00); + } else if (ov->bclass == BCL_OV518) { + warn("snapshot reset not supported yet on OV518(+)"); + } else { + err("clear snap: invalid bridge type"); + } +} + +#if 0 +/* Checks the status of the snapshot button. Returns 1 if it was pressed since + * it was last cleared, and zero in all other cases (including errors) */ +static int +ov51x_check_snapshot(struct usb_ov511 *ov) +{ + int ret, status = 0; + + if (ov->bclass == BCL_OV511) { + ret = reg_r(ov, R51x_SYS_SNAP); + if (ret < 0) { + err("Error checking snspshot status (%d)", ret); + } else if (ret & 0x08) { + status = 1; + } + } else if (ov->bclass == BCL_OV518) { + warn("snapshot check not supported yet on OV518(+)"); + } else { + err("check snap: invalid bridge type"); + } + + return status; +} +#endif + +/* This does an initial reset of an OmniVision sensor and ensures that I2C + * is synchronized. Returns <0 for failure. + */ +static int +init_ov_sensor(struct usb_ov511 *ov) +{ + int i, success; + + /* Reset the sensor */ + if (i2c_w(ov, 0x12, 0x80) < 0) + return -EIO; + + /* Wait for it to initialize */ + msleep(150); + + for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) { + if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) && + (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) { + success = 1; + continue; + } + + /* Reset the sensor */ + if (i2c_w(ov, 0x12, 0x80) < 0) + return -EIO; + /* Wait for it to initialize */ + msleep(150); + /* Dummy read to sync I2C */ + if (i2c_r(ov, 0x00) < 0) + return -EIO; + } + + if (!success) + return -EIO; + + PDEBUG(1, "I2C synced in %d attempt(s)", i); + + return 0; +} + +static int +ov511_set_packet_size(struct usb_ov511 *ov, int size) +{ + int alt, mult; + + if (ov51x_stop(ov) < 0) + return -EIO; + + mult = size >> 5; + + if (ov->bridge == BRG_OV511) { + if (size == 0) + alt = OV511_ALT_SIZE_0; + else if (size == 257) + alt = OV511_ALT_SIZE_257; + else if (size == 513) + alt = OV511_ALT_SIZE_513; + else if (size == 769) + alt = OV511_ALT_SIZE_769; + else if (size == 993) + alt = OV511_ALT_SIZE_993; + else { + err("Set packet size: invalid size (%d)", size); + return -EINVAL; + } + } else if (ov->bridge == BRG_OV511PLUS) { + if (size == 0) + alt = OV511PLUS_ALT_SIZE_0; + else if (size == 33) + alt = OV511PLUS_ALT_SIZE_33; + else if (size == 129) + alt = OV511PLUS_ALT_SIZE_129; + else if (size == 257) + alt = OV511PLUS_ALT_SIZE_257; + else if (size == 385) + alt = OV511PLUS_ALT_SIZE_385; + else if (size == 513) + alt = OV511PLUS_ALT_SIZE_513; + else if (size == 769) + alt = OV511PLUS_ALT_SIZE_769; + else if (size == 961) + alt = OV511PLUS_ALT_SIZE_961; + else { + err("Set packet size: invalid size (%d)", size); + return -EINVAL; + } + } else { + err("Set packet size: Invalid bridge type"); + return -EINVAL; + } + + PDEBUG(3, "%d, mult=%d, alt=%d", size, mult, alt); + + if (reg_w(ov, R51x_FIFO_PSIZE, mult) < 0) + return -EIO; + + if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { + err("Set packet size: set interface error"); + return -EBUSY; + } + + if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) + return -EIO; + + ov->packet_size = size; + + if (ov51x_restart(ov) < 0) + return -EIO; + + return 0; +} + +/* Note: Unlike the OV511/OV511+, the size argument does NOT include the + * optional packet number byte. The actual size *is* stored in ov->packet_size, + * though. */ +static int +ov518_set_packet_size(struct usb_ov511 *ov, int size) +{ + int alt; + + if (ov51x_stop(ov) < 0) + return -EIO; + + if (ov->bclass == BCL_OV518) { + if (size == 0) + alt = OV518_ALT_SIZE_0; + else if (size == 128) + alt = OV518_ALT_SIZE_128; + else if (size == 256) + alt = OV518_ALT_SIZE_256; + else if (size == 384) + alt = OV518_ALT_SIZE_384; + else if (size == 512) + alt = OV518_ALT_SIZE_512; + else if (size == 640) + alt = OV518_ALT_SIZE_640; + else if (size == 768) + alt = OV518_ALT_SIZE_768; + else if (size == 896) + alt = OV518_ALT_SIZE_896; + else { + err("Set packet size: invalid size (%d)", size); + return -EINVAL; + } + } else { + err("Set packet size: Invalid bridge type"); + return -EINVAL; + } + + PDEBUG(3, "%d, alt=%d", size, alt); + + ov->packet_size = size; + if (size > 0) { + /* Program ISO FIFO size reg (packet number isn't included) */ + ov518_reg_w32(ov, 0x30, size, 2); + + if (ov->packet_numbering) + ++ov->packet_size; + } + + if (usb_set_interface(ov->dev, ov->iface, alt) < 0) { + err("Set packet size: set interface error"); + return -EBUSY; + } + + /* Initialize the stream */ + if (reg_w(ov, 0x2f, 0x80) < 0) + return -EIO; + + if (ov51x_restart(ov) < 0) + return -EIO; + + if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) + return -EIO; + + return 0; +} + +/* Upload compression params and quantization tables. Returns 0 for success. */ +static int +ov511_init_compression(struct usb_ov511 *ov) +{ + int rc = 0; + + if (!ov->compress_inited) { + reg_w(ov, 0x70, phy); + reg_w(ov, 0x71, phuv); + reg_w(ov, 0x72, pvy); + reg_w(ov, 0x73, pvuv); + reg_w(ov, 0x74, qhy); + reg_w(ov, 0x75, qhuv); + reg_w(ov, 0x76, qvy); + reg_w(ov, 0x77, qvuv); + + if (ov511_upload_quan_tables(ov) < 0) { + err("Error uploading quantization tables"); + rc = -EIO; + goto out; + } + } + + ov->compress_inited = 1; +out: + return rc; +} + +/* Upload compression params and quantization tables. Returns 0 for success. */ +static int +ov518_init_compression(struct usb_ov511 *ov) +{ + int rc = 0; + + if (!ov->compress_inited) { + if (ov518_upload_quan_tables(ov) < 0) { + err("Error uploading quantization tables"); + rc = -EIO; + goto out; + } + } + + ov->compress_inited = 1; +out: + return rc; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's contrast setting to "val" */ +static int +sensor_set_contrast(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + { + rc = i2c_w(ov, OV7610_REG_CNT, val >> 8); + if (rc < 0) + goto out; + break; + } + case SEN_OV6630: + { + rc = i2c_w_mask(ov, OV7610_REG_CNT, val >> 12, 0x0f); + if (rc < 0) + goto out; + break; + } + case SEN_OV7620: + { + unsigned char ctab[] = { + 0x01, 0x05, 0x09, 0x11, 0x15, 0x35, 0x37, 0x57, + 0x5b, 0xa5, 0xa7, 0xc7, 0xc9, 0xcf, 0xef, 0xff + }; + + /* Use Y gamma control instead. Bit 0 enables it. */ + rc = i2c_w(ov, 0x64, ctab[val>>12]); + if (rc < 0) + goto out; + break; + } + case SEN_SAA7111A: + { + rc = i2c_w(ov, 0x0b, val >> 9); + if (rc < 0) + goto out; + break; + } + default: + { + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + } + + rc = 0; /* Success */ + ov->contrast = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's contrast setting */ +static int +sensor_get_contrast(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + rc = i2c_r(ov, OV7610_REG_CNT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_CNT); + if (rc < 0) + return rc; + else + *val = rc << 12; + break; + case SEN_OV7620: + /* Use Y gamma reg instead. Bit 0 is the enable bit. */ + rc = i2c_r(ov, 0x64); + if (rc < 0) + return rc; + else + *val = (rc & 0xfe) << 8; + break; + case SEN_SAA7111A: + *val = ov->contrast; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->contrast = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's brightness setting to "val" */ +static int +sensor_set_brightness(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(4, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_w(ov, OV7610_REG_BRT, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_OV7620: + /* 7620 doesn't like manual changes when in auto mode */ + if (!ov->auto_brt) { + rc = i2c_w(ov, OV7610_REG_BRT, val >> 8); + if (rc < 0) + goto out; + } + break; + case SEN_SAA7111A: + rc = i2c_w(ov, 0x0a, val >> 8); + if (rc < 0) + goto out; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + + rc = 0; /* Success */ + ov->brightness = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's brightness setting */ +static int +sensor_get_brightness(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV7620: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_BRT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_SAA7111A: + *val = ov->brightness; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->brightness = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's saturation (color intensity) setting to "val" */ +static int +sensor_set_saturation(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_w(ov, OV7610_REG_SAT, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_OV7620: +// /* Use UV gamma control instead. Bits 0 & 7 are reserved. */ +// rc = ov_i2c_write(ov->dev, 0x62, (val >> 9) & 0x7e); +// if (rc < 0) +// goto out; + rc = i2c_w(ov, OV7610_REG_SAT, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_SAA7111A: + rc = i2c_w(ov, 0x0c, val >> 9); + if (rc < 0) + goto out; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + + rc = 0; /* Success */ + ov->colour = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's saturation (color intensity) setting */ +static int +sensor_get_saturation(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_SAT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_OV7620: +// /* Use UV gamma reg instead. Bits 0 & 7 are reserved. */ +// rc = i2c_r(ov, 0x62); +// if (rc < 0) +// return rc; +// else +// *val = (rc & 0x7e) << 9; + rc = i2c_r(ov, OV7610_REG_SAT); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_SAA7111A: + *val = ov->colour; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->colour = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +/* Sets sensor's hue (red/blue balance) setting to "val" */ +static int +sensor_set_hue(struct usb_ov511 *ov, unsigned short val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_w(ov, OV7610_REG_RED, 0xFF - (val >> 8)); + if (rc < 0) + goto out; + + rc = i2c_w(ov, OV7610_REG_BLUE, val >> 8); + if (rc < 0) + goto out; + break; + case SEN_OV7620: +// Hue control is causing problems. I will enable it once it's fixed. +#if 0 + rc = i2c_w(ov, 0x7a, (unsigned char)(val >> 8) + 0xb); + if (rc < 0) + goto out; + + rc = i2c_w(ov, 0x79, (unsigned char)(val >> 8) + 0xb); + if (rc < 0) + goto out; +#endif + break; + case SEN_SAA7111A: + rc = i2c_w(ov, 0x0d, (val + 32768) >> 8); + if (rc < 0) + goto out; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + rc = -EPERM; + goto out; + } + + rc = 0; /* Success */ + ov->hue = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} + +/* Gets sensor's hue (red/blue balance) setting */ +static int +sensor_get_hue(struct usb_ov511 *ov, unsigned short *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + case SEN_OV6630: + rc = i2c_r(ov, OV7610_REG_BLUE); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_OV7620: + rc = i2c_r(ov, 0x7a); + if (rc < 0) + return rc; + else + *val = rc << 8; + break; + case SEN_SAA7111A: + *val = ov->hue; + break; + default: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + } + + PDEBUG(3, "%d", *val); + ov->hue = *val; + + return 0; +} + +/* -------------------------------------------------------------------------- */ + +static int +sensor_set_picture(struct usb_ov511 *ov, struct video_picture *p) +{ + int rc; + + PDEBUG(4, "sensor_set_picture"); + + ov->whiteness = p->whiteness; + + /* Don't return error if a setting is unsupported, or rest of settings + * will not be performed */ + + rc = sensor_set_contrast(ov, p->contrast); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_brightness(ov, p->brightness); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_saturation(ov, p->colour); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_hue(ov, p->hue); + if (FATAL_ERROR(rc)) + return rc; + + return 0; +} + +static int +sensor_get_picture(struct usb_ov511 *ov, struct video_picture *p) +{ + int rc; + + PDEBUG(4, "sensor_get_picture"); + + /* Don't return error if a setting is unsupported, or rest of settings + * will not be performed */ + + rc = sensor_get_contrast(ov, &(p->contrast)); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_get_brightness(ov, &(p->brightness)); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_get_saturation(ov, &(p->colour)); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_get_hue(ov, &(p->hue)); + if (FATAL_ERROR(rc)) + return rc; + + p->whiteness = 105 << 8; + + return 0; +} + +#if 0 +// FIXME: Exposure range is only 0x00-0x7f in interlace mode +/* Sets current exposure for sensor. This only has an effect if auto-exposure + * is off */ +static inline int +sensor_set_exposure(struct usb_ov511 *ov, unsigned char val) +{ + int rc; + + PDEBUG(3, "%d", val); + + if (ov->stop_during_set) + if (ov51x_stop(ov) < 0) + return -EIO; + + switch (ov->sensor) { + case SEN_OV6620: + case SEN_OV6630: + case SEN_OV7610: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + rc = i2c_w(ov, 0x10, val); + if (rc < 0) + goto out; + + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_exposure"); + return -EINVAL; + } + + rc = 0; /* Success */ + ov->exposure = val; +out: + if (ov51x_restart(ov) < 0) + return -EIO; + + return rc; +} +#endif + +/* Gets current exposure level from sensor, regardless of whether it is under + * manual control. */ +static int +sensor_get_exposure(struct usb_ov511 *ov, unsigned char *val) +{ + int rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV6620: + case SEN_OV6630: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + rc = i2c_r(ov, 0x10); + if (rc < 0) + return rc; + else + *val = rc; + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + val = NULL; + PDEBUG(3, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for get_exposure"); + return -EINVAL; + } + + PDEBUG(3, "%d", *val); + ov->exposure = *val; + + return 0; +} + +/* Turns on or off the LED. Only has an effect with OV511+/OV518(+) */ +static void +ov51x_led_control(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + if (ov->bridge == BRG_OV511PLUS) + reg_w(ov, R511_SYS_LED_CTL, enable ? 1 : 0); + else if (ov->bclass == BCL_OV518) + reg_w_mask(ov, R518_GPIO_OUT, enable ? 0x02 : 0x00, 0x02); + + return; +} + +/* Matches the sensor's internal frame rate to the lighting frequency. + * Valid frequencies are: + * 50 - 50Hz, for European and Asian lighting + * 60 - 60Hz, for American lighting + * + * Tested with: OV7610, OV7620, OV76BE, OV6620 + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_light_freq(struct usb_ov511 *ov, int freq) +{ + int sixty; + + PDEBUG(4, "%d Hz", freq); + + if (freq == 60) + sixty = 1; + else if (freq == 50) + sixty = 0; + else { + err("Invalid light freq (%d Hz)", freq); + return -EINVAL; + } + + switch (ov->sensor) { + case SEN_OV7610: + i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); + i2c_w(ov, 0x2b, sixty?0x00:0xac); + i2c_w_mask(ov, 0x13, 0x10, 0x10); + i2c_w_mask(ov, 0x13, 0x00, 0x10); + break; + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + i2c_w_mask(ov, 0x2a, sixty?0x00:0x80, 0x80); + i2c_w(ov, 0x2b, sixty?0x00:0xac); + i2c_w_mask(ov, 0x76, 0x01, 0x01); + break; + case SEN_OV6620: + case SEN_OV6630: + i2c_w(ov, 0x2b, sixty?0xa8:0x28); + i2c_w(ov, 0x2a, sixty?0x84:0xa4); + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_light_freq"); + return -EINVAL; + } + + ov->lightfreq = freq; + + return 0; +} + +/* If enable is true, turn on the sensor's banding filter, otherwise turn it + * off. This filter tries to reduce the pattern of horizontal light/dark bands + * caused by some (usually fluorescent) lighting. The light frequency must be + * set either before or after enabling it with ov51x_set_light_freq(). + * + * Tested with: OV7610, OV7620, OV76BE, OV6620. + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_banding_filter(struct usb_ov511 *ov, int enable) +{ + int rc; + + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B + || ov->sensor == SEN_SAA7111A) { + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + } + + rc = i2c_w_mask(ov, 0x2d, enable?0x04:0x00, 0x04); + if (rc < 0) + return rc; + + ov->bandfilt = enable; + + return 0; +} + +/* If enable is true, turn on the sensor's auto brightness control, otherwise + * turn it off. + * + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_auto_brightness(struct usb_ov511 *ov, int enable) +{ + int rc; + + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + if (ov->sensor == SEN_KS0127 || ov->sensor == SEN_KS0127B + || ov->sensor == SEN_SAA7111A) { + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + } + + rc = i2c_w_mask(ov, 0x2d, enable?0x10:0x00, 0x10); + if (rc < 0) + return rc; + + ov->auto_brt = enable; + + return 0; +} + +/* If enable is true, turn on the sensor's auto exposure control, otherwise + * turn it off. + * + * Unsupported: KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_auto_exposure(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + switch (ov->sensor) { + case SEN_OV7610: + i2c_w_mask(ov, 0x29, enable?0x00:0x80, 0x80); + break; + case SEN_OV6620: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + i2c_w_mask(ov, 0x13, enable?0x01:0x00, 0x01); + break; + case SEN_OV6630: + i2c_w_mask(ov, 0x28, enable?0x00:0x10, 0x10); + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_auto_exposure"); + return -EINVAL; + } + + ov->auto_exp = enable; + + return 0; +} + +/* Modifies the sensor's exposure algorithm to allow proper exposure of objects + * that are illuminated from behind. + * + * Tested with: OV6620, OV7620 + * Unsupported: OV7610, OV76BE, KS0127, KS0127B, SAA7111A + * Returns: 0 for success + */ +static int +sensor_set_backlight(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + switch (ov->sensor) { + case SEN_OV7620: + case SEN_OV8600: + i2c_w_mask(ov, 0x68, enable?0xe0:0xc0, 0xe0); + i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); + i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); + break; + case SEN_OV6620: + i2c_w_mask(ov, 0x4e, enable?0xe0:0xc0, 0xe0); + i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); + i2c_w_mask(ov, 0x0e, enable?0x80:0x00, 0x80); + break; + case SEN_OV6630: + i2c_w_mask(ov, 0x4e, enable?0x80:0x60, 0xe0); + i2c_w_mask(ov, 0x29, enable?0x08:0x00, 0x08); + i2c_w_mask(ov, 0x28, enable?0x02:0x00, 0x02); + break; + case SEN_OV7610: + case SEN_OV76BE: + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_backlight"); + return -EINVAL; + } + + ov->backlight = enable; + + return 0; +} + +static int +sensor_set_mirror(struct usb_ov511 *ov, int enable) +{ + PDEBUG(4, " (%s)", enable ? "turn on" : "turn off"); + + switch (ov->sensor) { + case SEN_OV6620: + case SEN_OV6630: + case SEN_OV7610: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + i2c_w_mask(ov, 0x12, enable?0x40:0x00, 0x40); + break; + case SEN_KS0127: + case SEN_KS0127B: + case SEN_SAA7111A: + PDEBUG(5, "Unsupported with this sensor"); + return -EPERM; + default: + err("Sensor not supported for set_mirror"); + return -EINVAL; + } + + ov->mirror = enable; + + return 0; +} + +/* Returns number of bits per pixel (regardless of where they are located; + * planar or not), or zero for unsupported format. + */ +static inline int +get_depth(int palette) +{ + switch (palette) { + case VIDEO_PALETTE_GREY: return 8; + case VIDEO_PALETTE_YUV420: return 12; + case VIDEO_PALETTE_YUV420P: return 12; /* Planar */ + default: return 0; /* Invalid format */ + } +} + +/* Bytes per frame. Used by read(). Return of 0 indicates error */ +static inline long int +get_frame_length(struct ov511_frame *frame) +{ + if (!frame) + return 0; + else + return ((frame->width * frame->height + * get_depth(frame->format)) >> 3); +} + +static int +mode_init_ov_sensor_regs(struct usb_ov511 *ov, int width, int height, + int mode, int sub_flag, int qvga) +{ + int clock; + + /******** Mode (VGA/QVGA) and sensor specific regs ********/ + + switch (ov->sensor) { + case SEN_OV7610: + i2c_w(ov, 0x14, qvga?0x24:0x04); +// FIXME: Does this improve the image quality or frame rate? +#if 0 + i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); + i2c_w(ov, 0x24, 0x10); + i2c_w(ov, 0x25, qvga?0x40:0x8a); + i2c_w(ov, 0x2f, qvga?0x30:0xb0); + i2c_w(ov, 0x35, qvga?0x1c:0x9c); +#endif + break; + case SEN_OV7620: +// i2c_w(ov, 0x2b, 0x00); + i2c_w(ov, 0x14, qvga?0xa4:0x84); + i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); + i2c_w(ov, 0x24, qvga?0x20:0x3a); + i2c_w(ov, 0x25, qvga?0x30:0x60); + i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40); + i2c_w_mask(ov, 0x67, qvga?0xf0:0x90, 0xf0); + i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20); + break; + case SEN_OV76BE: +// i2c_w(ov, 0x2b, 0x00); + i2c_w(ov, 0x14, qvga?0xa4:0x84); +// FIXME: Enable this once 7620AE uses 7620 initial settings +#if 0 + i2c_w_mask(ov, 0x28, qvga?0x00:0x20, 0x20); + i2c_w(ov, 0x24, qvga?0x20:0x3a); + i2c_w(ov, 0x25, qvga?0x30:0x60); + i2c_w_mask(ov, 0x2d, qvga?0x40:0x00, 0x40); + i2c_w_mask(ov, 0x67, qvga?0xb0:0x90, 0xf0); + i2c_w_mask(ov, 0x74, qvga?0x20:0x00, 0x20); +#endif + break; + case SEN_OV6620: + i2c_w(ov, 0x14, qvga?0x24:0x04); + break; + case SEN_OV6630: + i2c_w(ov, 0x14, qvga?0xa0:0x80); + break; + default: + err("Invalid sensor"); + return -EINVAL; + } + + /******** Palette-specific regs ********/ + + if (mode == VIDEO_PALETTE_GREY) { + if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { + /* these aren't valid on the OV6620/OV7620/6630? */ + i2c_w_mask(ov, 0x0e, 0x40, 0x40); + } + + if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518 + && ov518_color) { + i2c_w_mask(ov, 0x12, 0x00, 0x10); + i2c_w_mask(ov, 0x13, 0x00, 0x20); + } else { + i2c_w_mask(ov, 0x13, 0x20, 0x20); + } + } else { + if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { + /* not valid on the OV6620/OV7620/6630? */ + i2c_w_mask(ov, 0x0e, 0x00, 0x40); + } + + /* The OV518 needs special treatment. Although both the OV518 + * and the OV6630 support a 16-bit video bus, only the 8 bit Y + * bus is actually used. The UV bus is tied to ground. + * Therefore, the OV6630 needs to be in 8-bit multiplexed + * output mode */ + + if (ov->sensor == SEN_OV6630 && ov->bridge == BRG_OV518 + && ov518_color) { + i2c_w_mask(ov, 0x12, 0x10, 0x10); + i2c_w_mask(ov, 0x13, 0x20, 0x20); + } else { + i2c_w_mask(ov, 0x13, 0x00, 0x20); + } + } + + /******** Clock programming ********/ + + /* The OV6620 needs special handling. This prevents the + * severe banding that normally occurs */ + if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) + { + /* Clock down */ + + i2c_w(ov, 0x2a, 0x04); + + if (ov->compress) { +// clock = 0; /* This ensures the highest frame rate */ + clock = 3; + } else if (clockdiv == -1) { /* If user didn't override it */ + clock = 3; /* Gives better exposure time */ + } else { + clock = clockdiv; + } + + PDEBUG(4, "Setting clock divisor to %d", clock); + + i2c_w(ov, 0x11, clock); + + i2c_w(ov, 0x2a, 0x84); + /* This next setting is critical. It seems to improve + * the gain or the contrast. The "reserved" bits seem + * to have some effect in this case. */ + i2c_w(ov, 0x2d, 0x85); + } + else + { + if (ov->compress) { + clock = 1; /* This ensures the highest frame rate */ + } else if (clockdiv == -1) { /* If user didn't override it */ + /* Calculate and set the clock divisor */ + clock = ((sub_flag ? ov->subw * ov->subh + : width * height) + * (mode == VIDEO_PALETTE_GREY ? 2 : 3) / 2) + / 66000; + } else { + clock = clockdiv; + } + + PDEBUG(4, "Setting clock divisor to %d", clock); + + i2c_w(ov, 0x11, clock); + } + + /******** Special Features ********/ + + if (framedrop >= 0) + i2c_w(ov, 0x16, framedrop); + + /* Test Pattern */ + i2c_w_mask(ov, 0x12, (testpat?0x02:0x00), 0x02); + + /* Enable auto white balance */ + i2c_w_mask(ov, 0x12, 0x04, 0x04); + + // This will go away as soon as ov51x_mode_init_sensor_regs() + // is fully tested. + /* 7620/6620/6630? don't have register 0x35, so play it safe */ + if (ov->sensor == SEN_OV7610 || ov->sensor == SEN_OV76BE) { + if (width == 640 && height == 480) + i2c_w(ov, 0x35, 0x9e); + else + i2c_w(ov, 0x35, 0x1e); + } + + return 0; +} + +static int +set_ov_sensor_window(struct usb_ov511 *ov, int width, int height, int mode, + int sub_flag) +{ + int ret; + int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize; + int hoffset, voffset, hwscale = 0, vwscale = 0; + + /* The different sensor ICs handle setting up of window differently. + * IF YOU SET IT WRONG, YOU WILL GET ALL ZERO ISOC DATA FROM OV51x!!! */ + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV76BE: + hwsbase = 0x38; + hwebase = 0x3a; + vwsbase = vwebase = 0x05; + break; + case SEN_OV6620: + case SEN_OV6630: + hwsbase = 0x38; + hwebase = 0x3a; + vwsbase = 0x05; + vwebase = 0x06; + break; + case SEN_OV7620: + hwsbase = 0x2f; /* From 7620.SET (spec is wrong) */ + hwebase = 0x2f; + vwsbase = vwebase = 0x05; + break; + default: + err("Invalid sensor"); + return -EINVAL; + } + + if (ov->sensor == SEN_OV6620 || ov->sensor == SEN_OV6630) { + /* Note: OV518(+) does downsample on its own) */ + if ((width > 176 && height > 144) + || ov->bclass == BCL_OV518) { /* CIF */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 0); + if (ret < 0) + return ret; + hwscale = 1; + vwscale = 1; /* The datasheet says 0; it's wrong */ + hwsize = 352; + vwsize = 288; + } else if (width > 176 || height > 144) { + err("Illegal dimensions"); + return -EINVAL; + } else { /* QCIF */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 1); + if (ret < 0) + return ret; + hwsize = 176; + vwsize = 144; + } + } else { + if (width > 320 && height > 240) { /* VGA */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 0); + if (ret < 0) + return ret; + hwscale = 2; + vwscale = 1; + hwsize = 640; + vwsize = 480; + } else if (width > 320 || height > 240) { + err("Illegal dimensions"); + return -EINVAL; + } else { /* QVGA */ + ret = mode_init_ov_sensor_regs(ov, width, height, + mode, sub_flag, 1); + if (ret < 0) + return ret; + hwscale = 1; + hwsize = 320; + vwsize = 240; + } + } + + /* Center the window */ + hoffset = ((hwsize - width) / 2) >> hwscale; + voffset = ((vwsize - height) / 2) >> vwscale; + + /* FIXME! - This needs to be changed to support 160x120 and 6620!!! */ + if (sub_flag) { + i2c_w(ov, 0x17, hwsbase+(ov->subx>>hwscale)); + i2c_w(ov, 0x18, hwebase+((ov->subx+ov->subw)>>hwscale)); + i2c_w(ov, 0x19, vwsbase+(ov->suby>>vwscale)); + i2c_w(ov, 0x1a, vwebase+((ov->suby+ov->subh)>>vwscale)); + } else { + i2c_w(ov, 0x17, hwsbase + hoffset); + i2c_w(ov, 0x18, hwebase + hoffset + (hwsize>>hwscale)); + i2c_w(ov, 0x19, vwsbase + voffset); + i2c_w(ov, 0x1a, vwebase + voffset + (vwsize>>vwscale)); + } + +#ifdef OV511_DEBUG + if (dump_sensor) + dump_i2c_regs(ov); +#endif + + return 0; +} + +/* Set up the OV511/OV511+ with the given image parameters. + * + * Do not put any sensor-specific code in here (including I2C I/O functions) + */ +static int +ov511_mode_init_regs(struct usb_ov511 *ov, + int width, int height, int mode, int sub_flag) +{ + int hsegs, vsegs; + + if (sub_flag) { + width = ov->subw; + height = ov->subh; + } + + PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", + width, height, mode, sub_flag); + + // FIXME: This should be moved to a 7111a-specific function once + // subcapture is dealt with properly + if (ov->sensor == SEN_SAA7111A) { + if (width == 320 && height == 240) { + /* No need to do anything special */ + } else if (width == 640 && height == 480) { + /* Set the OV511 up as 320x480, but keep the + * V4L resolution as 640x480 */ + width = 320; + } else { + err("SAA7111A only allows 320x240 or 640x480"); + return -EINVAL; + } + } + + /* Make sure width and height are a multiple of 8 */ + if (width % 8 || height % 8) { + err("Invalid size (%d, %d) (mode = %d)", width, height, mode); + return -EINVAL; + } + + if (width < ov->minwidth || height < ov->minheight) { + err("Requested dimensions are too small"); + return -EINVAL; + } + + if (ov51x_stop(ov) < 0) + return -EIO; + + if (mode == VIDEO_PALETTE_GREY) { + reg_w(ov, R511_CAM_UV_EN, 0x00); + reg_w(ov, R511_SNAP_UV_EN, 0x00); + reg_w(ov, R511_SNAP_OPTS, 0x01); + } else { + reg_w(ov, R511_CAM_UV_EN, 0x01); + reg_w(ov, R511_SNAP_UV_EN, 0x01); + reg_w(ov, R511_SNAP_OPTS, 0x03); + } + + /* Here I'm assuming that snapshot size == image size. + * I hope that's always true. --claudio + */ + hsegs = (width >> 3) - 1; + vsegs = (height >> 3) - 1; + + reg_w(ov, R511_CAM_PXCNT, hsegs); + reg_w(ov, R511_CAM_LNCNT, vsegs); + reg_w(ov, R511_CAM_PXDIV, 0x00); + reg_w(ov, R511_CAM_LNDIV, 0x00); + + /* YUV420, low pass filter on */ + reg_w(ov, R511_CAM_OPTS, 0x03); + + /* Snapshot additions */ + reg_w(ov, R511_SNAP_PXCNT, hsegs); + reg_w(ov, R511_SNAP_LNCNT, vsegs); + reg_w(ov, R511_SNAP_PXDIV, 0x00); + reg_w(ov, R511_SNAP_LNDIV, 0x00); + + if (ov->compress) { + /* Enable Y and UV quantization and compression */ + reg_w(ov, R511_COMP_EN, 0x07); + reg_w(ov, R511_COMP_LUT_EN, 0x03); + ov51x_reset(ov, OV511_RESET_OMNICE); + } + + if (ov51x_restart(ov) < 0) + return -EIO; + + return 0; +} + +/* Sets up the OV518/OV518+ with the given image parameters + * + * OV518 needs a completely different approach, until we can figure out what + * the individual registers do. Also, only 15 FPS is supported now. + * + * Do not put any sensor-specific code in here (including I2C I/O functions) + */ +static int +ov518_mode_init_regs(struct usb_ov511 *ov, + int width, int height, int mode, int sub_flag) +{ + int hsegs, vsegs, hi_res; + + if (sub_flag) { + width = ov->subw; + height = ov->subh; + } + + PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d", + width, height, mode, sub_flag); + + if (width % 16 || height % 8) { + err("Invalid size (%d, %d)", width, height); + return -EINVAL; + } + + if (width < ov->minwidth || height < ov->minheight) { + err("Requested dimensions are too small"); + return -EINVAL; + } + + if (width >= 320 && height >= 240) { + hi_res = 1; + } else if (width >= 320 || height >= 240) { + err("Invalid width/height combination (%d, %d)", width, height); + return -EINVAL; + } else { + hi_res = 0; + } + + if (ov51x_stop(ov) < 0) + return -EIO; + + /******** Set the mode ********/ + + reg_w(ov, 0x2b, 0); + reg_w(ov, 0x2c, 0); + reg_w(ov, 0x2d, 0); + reg_w(ov, 0x2e, 0); + reg_w(ov, 0x3b, 0); + reg_w(ov, 0x3c, 0); + reg_w(ov, 0x3d, 0); + reg_w(ov, 0x3e, 0); + + if (ov->bridge == BRG_OV518 && ov518_color) { + /* OV518 needs U and V swapped */ + i2c_w_mask(ov, 0x15, 0x00, 0x01); + + if (mode == VIDEO_PALETTE_GREY) { + /* Set 16-bit input format (UV data are ignored) */ + reg_w_mask(ov, 0x20, 0x00, 0x08); + + /* Set 8-bit (4:0:0) output format */ + reg_w_mask(ov, 0x28, 0x00, 0xf0); + reg_w_mask(ov, 0x38, 0x00, 0xf0); + } else { + /* Set 8-bit (YVYU) input format */ + reg_w_mask(ov, 0x20, 0x08, 0x08); + + /* Set 12-bit (4:2:0) output format */ + reg_w_mask(ov, 0x28, 0x80, 0xf0); + reg_w_mask(ov, 0x38, 0x80, 0xf0); + } + } else { + reg_w(ov, 0x28, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80); + reg_w(ov, 0x38, (mode == VIDEO_PALETTE_GREY) ? 0x00:0x80); + } + + hsegs = width / 16; + vsegs = height / 4; + + reg_w(ov, 0x29, hsegs); + reg_w(ov, 0x2a, vsegs); + + reg_w(ov, 0x39, hsegs); + reg_w(ov, 0x3a, vsegs); + + /* Windows driver does this here; who knows why */ + reg_w(ov, 0x2f, 0x80); + + /******** Set the framerate (to 15 FPS) ********/ + + /* Mode independent, but framerate dependent, regs */ + reg_w(ov, 0x51, 0x02); /* Clock divider; lower==faster */ + reg_w(ov, 0x22, 0x18); + reg_w(ov, 0x23, 0xff); + + if (ov->bridge == BRG_OV518PLUS) + reg_w(ov, 0x21, 0x19); + else + reg_w(ov, 0x71, 0x19); /* Compression-related? */ + + // FIXME: Sensor-specific + /* Bit 5 is what matters here. Of course, it is "reserved" */ + i2c_w(ov, 0x54, 0x23); + + reg_w(ov, 0x2f, 0x80); + + if (ov->bridge == BRG_OV518PLUS) { + reg_w(ov, 0x24, 0x94); + reg_w(ov, 0x25, 0x90); + ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */ + ov518_reg_w32(ov, 0xc6, 540, 2); /* 21ch */ + ov518_reg_w32(ov, 0xc7, 540, 2); /* 21ch */ + ov518_reg_w32(ov, 0xc8, 108, 2); /* 6ch */ + ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */ + ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */ + ov518_reg_w32(ov, 0xcc, 2400, 2); /* 960h */ + ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */ + ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */ + } else { + reg_w(ov, 0x24, 0x9f); + reg_w(ov, 0x25, 0x90); + ov518_reg_w32(ov, 0xc4, 400, 2); /* 190h */ + ov518_reg_w32(ov, 0xc6, 500, 2); /* 1f4h */ + ov518_reg_w32(ov, 0xc7, 500, 2); /* 1f4h */ + ov518_reg_w32(ov, 0xc8, 142, 2); /* 8eh */ + ov518_reg_w32(ov, 0xca, 131098, 3); /* 2001ah */ + ov518_reg_w32(ov, 0xcb, 532, 2); /* 214h */ + ov518_reg_w32(ov, 0xcc, 2000, 2); /* 7d0h */ + ov518_reg_w32(ov, 0xcd, 32, 2); /* 20h */ + ov518_reg_w32(ov, 0xce, 608, 2); /* 260h */ + } + + reg_w(ov, 0x2f, 0x80); + + if (ov51x_restart(ov) < 0) + return -EIO; + + /* Reset it just for good measure */ + if (ov51x_reset(ov, OV511_RESET_NOREGS) < 0) + return -EIO; + + return 0; +} + +/* This is a wrapper around the OV511, OV518, and sensor specific functions */ +static int +mode_init_regs(struct usb_ov511 *ov, + int width, int height, int mode, int sub_flag) +{ + int rc = 0; + + if (!ov || !ov->dev) + return -EFAULT; + + if (ov->bclass == BCL_OV518) { + rc = ov518_mode_init_regs(ov, width, height, mode, sub_flag); + } else { + rc = ov511_mode_init_regs(ov, width, height, mode, sub_flag); + } + + if (FATAL_ERROR(rc)) + return rc; + + switch (ov->sensor) { + case SEN_OV7610: + case SEN_OV7620: + case SEN_OV76BE: + case SEN_OV8600: + case SEN_OV6620: + case SEN_OV6630: + rc = set_ov_sensor_window(ov, width, height, mode, sub_flag); + break; + case SEN_KS0127: + case SEN_KS0127B: + err("KS0127-series decoders not supported yet"); + rc = -EINVAL; + break; + case SEN_SAA7111A: +// rc = mode_init_saa_sensor_regs(ov, width, height, mode, +// sub_flag); + + PDEBUG(1, "SAA status = 0x%02X", i2c_r(ov, 0x1f)); + break; + default: + err("Unknown sensor"); + rc = -EINVAL; + } + + if (FATAL_ERROR(rc)) + return rc; + + /* Sensor-independent settings */ + rc = sensor_set_auto_brightness(ov, ov->auto_brt); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_auto_exposure(ov, ov->auto_exp); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_banding_filter(ov, bandingfilter); + if (FATAL_ERROR(rc)) + return rc; + + if (ov->lightfreq) { + rc = sensor_set_light_freq(ov, lightfreq); + if (FATAL_ERROR(rc)) + return rc; + } + + rc = sensor_set_backlight(ov, ov->backlight); + if (FATAL_ERROR(rc)) + return rc; + + rc = sensor_set_mirror(ov, ov->mirror); + if (FATAL_ERROR(rc)) + return rc; + + return 0; +} + +/* This sets the default image parameters. This is useful for apps that use + * read() and do not set these. + */ +static int +ov51x_set_default_params(struct usb_ov511 *ov) +{ + int i; + + /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used + * (using read() instead). */ + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].width = ov->maxwidth; + ov->frame[i].height = ov->maxheight; + ov->frame[i].bytes_read = 0; + if (force_palette) + ov->frame[i].format = force_palette; + else + ov->frame[i].format = VIDEO_PALETTE_YUV420; + + ov->frame[i].depth = get_depth(ov->frame[i].format); + } + + PDEBUG(3, "%dx%d, %s", ov->maxwidth, ov->maxheight, + symbolic(v4l1_plist, ov->frame[0].format)); + + /* Initialize to max width/height, YUV420 or RGB24 (if supported) */ + if (mode_init_regs(ov, ov->maxwidth, ov->maxheight, + ov->frame[0].format, 0) < 0) + return -EINVAL; + + return 0; +} + +/********************************************************************** + * + * Video decoder stuff + * + **********************************************************************/ + +/* Set analog input port of decoder */ +static int +decoder_set_input(struct usb_ov511 *ov, int input) +{ + PDEBUG(4, "port %d", input); + + switch (ov->sensor) { + case SEN_SAA7111A: + { + /* Select mode */ + i2c_w_mask(ov, 0x02, input, 0x07); + /* Bypass chrominance trap for modes 4..7 */ + i2c_w_mask(ov, 0x09, (input > 3) ? 0x80:0x00, 0x80); + break; + } + default: + return -EINVAL; + } + + return 0; +} + +/* Get ASCII name of video input */ +static int +decoder_get_input_name(struct usb_ov511 *ov, int input, char *name) +{ + switch (ov->sensor) { + case SEN_SAA7111A: + { + if (input < 0 || input > 7) + return -EINVAL; + else if (input < 4) + sprintf(name, "CVBS-%d", input); + else // if (input < 8) + sprintf(name, "S-Video-%d", input - 4); + break; + } + default: + sprintf(name, "%s", "Camera"); + } + + return 0; +} + +/* Set norm (NTSC, PAL, SECAM, AUTO) */ +static int +decoder_set_norm(struct usb_ov511 *ov, int norm) +{ + PDEBUG(4, "%d", norm); + + switch (ov->sensor) { + case SEN_SAA7111A: + { + int reg_8, reg_e; + + if (norm == VIDEO_MODE_NTSC) { + reg_8 = 0x40; /* 60 Hz */ + reg_e = 0x00; /* NTSC M / PAL BGHI */ + } else if (norm == VIDEO_MODE_PAL) { + reg_8 = 0x00; /* 50 Hz */ + reg_e = 0x00; /* NTSC M / PAL BGHI */ + } else if (norm == VIDEO_MODE_AUTO) { + reg_8 = 0x80; /* Auto field detect */ + reg_e = 0x00; /* NTSC M / PAL BGHI */ + } else if (norm == VIDEO_MODE_SECAM) { + reg_8 = 0x00; /* 50 Hz */ + reg_e = 0x50; /* SECAM / PAL 4.43 */ + } else { + return -EINVAL; + } + + i2c_w_mask(ov, 0x08, reg_8, 0xc0); + i2c_w_mask(ov, 0x0e, reg_e, 0x70); + break; + } + default: + return -EINVAL; + } + + return 0; +} + +/********************************************************************** + * + * Raw data parsing + * + **********************************************************************/ + +/* Copies a 64-byte segment at pIn to an 8x8 block at pOut. The width of the + * image at pOut is specified by w. + */ +static inline void +make_8x8(unsigned char *pIn, unsigned char *pOut, int w) +{ + unsigned char *pOut1 = pOut; + int x, y; + + for (y = 0; y < 8; y++) { + pOut1 = pOut; + for (x = 0; x < 8; x++) { + *pOut1++ = *pIn++; + } + pOut += w; + } +} + +/* + * For RAW BW (YUV 4:0:0) images, data show up in 256 byte segments. + * The segments represent 4 squares of 8x8 pixels as follows: + * + * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199 + * 8 9 ... 15 72 73 ... 79 200 201 ... 207 + * ... ... ... + * 56 57 ... 63 120 121 ... 127 248 249 ... 255 + * + */ +static void +yuv400raw_to_yuv400p(struct ov511_frame *frame, + unsigned char *pIn0, unsigned char *pOut0) +{ + int x, y; + unsigned char *pIn, *pOut, *pOutLine; + + /* Copy Y */ + pIn = pIn0; + pOutLine = pOut0; + for (y = 0; y < frame->rawheight - 1; y += 8) { + pOut = pOutLine; + for (x = 0; x < frame->rawwidth - 1; x += 8) { + make_8x8(pIn, pOut, frame->rawwidth); + pIn += 64; + pOut += 8; + } + pOutLine += 8 * frame->rawwidth; + } +} + +/* + * For YUV 4:2:0 images, the data show up in 384 byte segments. + * The first 64 bytes of each segment are U, the next 64 are V. The U and + * V are arranged as follows: + * + * 0 1 ... 7 + * 8 9 ... 15 + * ... + * 56 57 ... 63 + * + * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block). + * + * The next 256 bytes are full resolution Y data and represent 4 squares + * of 8x8 pixels as follows: + * + * 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199 + * 8 9 ... 15 72 73 ... 79 200 201 ... 207 + * ... ... ... + * 56 57 ... 63 120 121 ... 127 ... 248 249 ... 255 + * + * Note that the U and V data in one segment represent a 16 x 16 pixel + * area, but the Y data represent a 32 x 8 pixel area. If the width is not an + * even multiple of 32, the extra 8x8 blocks within a 32x8 block belong to the + * next horizontal stripe. + * + * If dumppix module param is set, _parse_data just dumps the incoming segments, + * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480 + * this puts the data on the standard output and can be analyzed with the + * parseppm.c utility I wrote. That's a much faster way for figuring out how + * these data are scrambled. + */ + +/* Converts from raw, uncompressed segments at pIn0 to a YUV420P frame at pOut0. + * + * FIXME: Currently only handles width and height that are multiples of 16 + */ +static void +yuv420raw_to_yuv420p(struct ov511_frame *frame, + unsigned char *pIn0, unsigned char *pOut0) +{ + int k, x, y; + unsigned char *pIn, *pOut, *pOutLine; + const unsigned int a = frame->rawwidth * frame->rawheight; + const unsigned int w = frame->rawwidth / 2; + + /* Copy U and V */ + pIn = pIn0; + pOutLine = pOut0 + a; + for (y = 0; y < frame->rawheight - 1; y += 16) { + pOut = pOutLine; + for (x = 0; x < frame->rawwidth - 1; x += 16) { + make_8x8(pIn, pOut, w); + make_8x8(pIn + 64, pOut + a/4, w); + pIn += 384; + pOut += 8; + } + pOutLine += 8 * w; + } + + /* Copy Y */ + pIn = pIn0 + 128; + pOutLine = pOut0; + k = 0; + for (y = 0; y < frame->rawheight - 1; y += 8) { + pOut = pOutLine; + for (x = 0; x < frame->rawwidth - 1; x += 8) { + make_8x8(pIn, pOut, frame->rawwidth); + pIn += 64; + pOut += 8; + if ((++k) > 3) { + k = 0; + pIn += 128; + } + } + pOutLine += 8 * frame->rawwidth; + } +} + +/********************************************************************** + * + * Decompression + * + **********************************************************************/ + +/* Chooses a decompression module, locks it, and sets ov->decomp_ops + * accordingly. Returns -ENXIO if decompressor is not available, otherwise + * returns 0 if no other error. + */ +static int +request_decompressor(struct usb_ov511 *ov) +{ + if (!ov) + return -ENODEV; + + if (ov->decomp_ops) { + err("ERROR: Decompressor already requested!"); + return -EINVAL; + } + + lock_kernel(); + + /* Try to get MMX, and fall back on no-MMX if necessary */ + if (ov->bclass == BCL_OV511) { + if (ov511_mmx_decomp_ops) { + PDEBUG(3, "Using OV511 MMX decompressor"); + ov->decomp_ops = ov511_mmx_decomp_ops; + } else if (ov511_decomp_ops) { + PDEBUG(3, "Using OV511 decompressor"); + ov->decomp_ops = ov511_decomp_ops; + } else { + err("No decompressor available"); + } + } else if (ov->bclass == BCL_OV518) { + if (ov518_mmx_decomp_ops) { + PDEBUG(3, "Using OV518 MMX decompressor"); + ov->decomp_ops = ov518_mmx_decomp_ops; + } else if (ov518_decomp_ops) { + PDEBUG(3, "Using OV518 decompressor"); + ov->decomp_ops = ov518_decomp_ops; + } else { + err("No decompressor available"); + } + } else { + err("Unknown bridge"); + } + + if (!ov->decomp_ops) + goto nosys; + + if (!ov->decomp_ops->owner) { + ov->decomp_ops = NULL; + goto nosys; + } + + if (!try_module_get(ov->decomp_ops->owner)) + goto nosys; + + unlock_kernel(); + return 0; + + nosys: + unlock_kernel(); + return -ENOSYS; +} + +/* Unlocks decompression module and nulls ov->decomp_ops. Safe to call even + * if ov->decomp_ops is NULL. + */ +static void +release_decompressor(struct usb_ov511 *ov) +{ + int released = 0; /* Did we actually do anything? */ + + if (!ov) + return; + + lock_kernel(); + + if (ov->decomp_ops) { + module_put(ov->decomp_ops->owner); + released = 1; + } + + ov->decomp_ops = NULL; + + unlock_kernel(); + + if (released) + PDEBUG(3, "Decompressor released"); +} + +static void +decompress(struct usb_ov511 *ov, struct ov511_frame *frame, + unsigned char *pIn0, unsigned char *pOut0) +{ + if (!ov->decomp_ops) + if (request_decompressor(ov)) + return; + + PDEBUG(4, "Decompressing %d bytes", frame->bytes_recvd); + + if (frame->format == VIDEO_PALETTE_GREY + && ov->decomp_ops->decomp_400) { + int ret = ov->decomp_ops->decomp_400( + pIn0, + pOut0, + frame->compbuf, + frame->rawwidth, + frame->rawheight, + frame->bytes_recvd); + PDEBUG(4, "DEBUG: decomp_400 returned %d", ret); + } else if (frame->format != VIDEO_PALETTE_GREY + && ov->decomp_ops->decomp_420) { + int ret = ov->decomp_ops->decomp_420( + pIn0, + pOut0, + frame->compbuf, + frame->rawwidth, + frame->rawheight, + frame->bytes_recvd); + PDEBUG(4, "DEBUG: decomp_420 returned %d", ret); + } else { + err("Decompressor does not support this format"); + } +} + +/********************************************************************** + * + * Format conversion + * + **********************************************************************/ + +/* Fuses even and odd fields together, and doubles width. + * INPUT: an odd field followed by an even field at pIn0, in YUV planar format + * OUTPUT: a normal YUV planar image, with correct aspect ratio + */ +static void +deinterlace(struct ov511_frame *frame, int rawformat, + unsigned char *pIn0, unsigned char *pOut0) +{ + const int fieldheight = frame->rawheight / 2; + const int fieldpix = fieldheight * frame->rawwidth; + const int w = frame->width; + int x, y; + unsigned char *pInEven, *pInOdd, *pOut; + + PDEBUG(5, "fieldheight=%d", fieldheight); + + if (frame->rawheight != frame->height) { + err("invalid height"); + return; + } + + if ((frame->rawwidth * 2) != frame->width) { + err("invalid width"); + return; + } + + /* Y */ + pInOdd = pIn0; + pInEven = pInOdd + fieldpix; + pOut = pOut0; + for (y = 0; y < fieldheight; y++) { + for (x = 0; x < frame->rawwidth; x++) { + *pOut = *pInEven; + *(pOut+1) = *pInEven++; + *(pOut+w) = *pInOdd; + *(pOut+w+1) = *pInOdd++; + pOut += 2; + } + pOut += w; + } + + if (rawformat == RAWFMT_YUV420) { + /* U */ + pInOdd = pIn0 + fieldpix * 2; + pInEven = pInOdd + fieldpix / 4; + for (y = 0; y < fieldheight / 2; y++) { + for (x = 0; x < frame->rawwidth / 2; x++) { + *pOut = *pInEven; + *(pOut+1) = *pInEven++; + *(pOut+w/2) = *pInOdd; + *(pOut+w/2+1) = *pInOdd++; + pOut += 2; + } + pOut += w/2; + } + /* V */ + pInOdd = pIn0 + fieldpix * 2 + fieldpix / 2; + pInEven = pInOdd + fieldpix / 4; + for (y = 0; y < fieldheight / 2; y++) { + for (x = 0; x < frame->rawwidth / 2; x++) { + *pOut = *pInEven; + *(pOut+1) = *pInEven++; + *(pOut+w/2) = *pInOdd; + *(pOut+w/2+1) = *pInOdd++; + pOut += 2; + } + pOut += w/2; + } + } +} + +static void +ov51x_postprocess_grey(struct usb_ov511 *ov, struct ov511_frame *frame) +{ + /* Deinterlace frame, if necessary */ + if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, + frame->tempdata); + else + yuv400raw_to_yuv400p(frame, frame->rawdata, + frame->tempdata); + + deinterlace(frame, RAWFMT_YUV400, frame->tempdata, + frame->data); + } else { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, + frame->data); + else + yuv400raw_to_yuv400p(frame, frame->rawdata, + frame->data); + } +} + +/* Process raw YUV420 data into standard YUV420P */ +static void +ov51x_postprocess_yuv420(struct usb_ov511 *ov, struct ov511_frame *frame) +{ + /* Deinterlace frame, if necessary */ + if (ov->sensor == SEN_SAA7111A && frame->rawheight >= 480) { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, frame->tempdata); + else + yuv420raw_to_yuv420p(frame, frame->rawdata, + frame->tempdata); + + deinterlace(frame, RAWFMT_YUV420, frame->tempdata, + frame->data); + } else { + if (frame->compressed) + decompress(ov, frame, frame->rawdata, frame->data); + else + yuv420raw_to_yuv420p(frame, frame->rawdata, + frame->data); + } +} + +/* Post-processes the specified frame. This consists of: + * 1. Decompress frame, if necessary + * 2. Deinterlace frame and scale to proper size, if necessary + * 3. Convert from YUV planar to destination format, if necessary + * 4. Fix the RGB offset, if necessary + */ +static void +ov51x_postprocess(struct usb_ov511 *ov, struct ov511_frame *frame) +{ + if (dumppix) { + memset(frame->data, 0, + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)); + PDEBUG(4, "Dumping %d bytes", frame->bytes_recvd); + memcpy(frame->data, frame->rawdata, frame->bytes_recvd); + } else { + switch (frame->format) { + case VIDEO_PALETTE_GREY: + ov51x_postprocess_grey(ov, frame); + break; + case VIDEO_PALETTE_YUV420: + case VIDEO_PALETTE_YUV420P: + ov51x_postprocess_yuv420(ov, frame); + break; + default: + err("Cannot convert data to %s", + symbolic(v4l1_plist, frame->format)); + } + } +} + +/********************************************************************** + * + * OV51x data transfer, IRQ handler + * + **********************************************************************/ + +static inline void +ov511_move_data(struct usb_ov511 *ov, unsigned char *in, int n) +{ + int num, offset; + int pnum = in[ov->packet_size - 1]; /* Get packet number */ + int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); + struct ov511_frame *frame = &ov->frame[ov->curframe]; + struct timeval *ts; + + /* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th + * byte non-zero. The EOF packet has image width/height in the + * 10th and 11th bytes. The 9th byte is given as follows: + * + * bit 7: EOF + * 6: compression enabled + * 5: 422/420/400 modes + * 4: 422/420/400 modes + * 3: 1 + * 2: snapshot button on + * 1: snapshot frame + * 0: even/odd field + */ + + if (printph) { + info("ph(%3d): %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x %2x", + pnum, in[0], in[1], in[2], in[3], in[4], in[5], in[6], + in[7], in[8], in[9], in[10], in[11]); + } + + /* Check for SOF/EOF packet */ + if ((in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6] | in[7]) || + (~in[8] & 0x08)) + goto check_middle; + + /* Frame end */ + if (in[8] & 0x80) { + ts = (struct timeval *)(frame->data + + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); + do_gettimeofday(ts); + + /* Get the actual frame size from the EOF header */ + frame->rawwidth = ((int)(in[9]) + 1) * 8; + frame->rawheight = ((int)(in[10]) + 1) * 8; + + PDEBUG(4, "Frame end, frame=%d, pnum=%d, w=%d, h=%d, recvd=%d", + ov->curframe, pnum, frame->rawwidth, frame->rawheight, + frame->bytes_recvd); + + /* Validate the header data */ + RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth); + RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, + ov->maxheight); + + /* Don't allow byte count to exceed buffer size */ + RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); + + if (frame->scanstate == STATE_LINES) { + int nextf; + + frame->grabstate = FRAME_DONE; + wake_up_interruptible(&frame->wq); + + /* If next frame is ready or grabbing, + * point to it */ + nextf = (ov->curframe + 1) % OV511_NUMFRAMES; + if (ov->frame[nextf].grabstate == FRAME_READY + || ov->frame[nextf].grabstate == FRAME_GRABBING) { + ov->curframe = nextf; + ov->frame[nextf].scanstate = STATE_SCANNING; + } else { + if (frame->grabstate == FRAME_DONE) { + PDEBUG(4, "** Frame done **"); + } else { + PDEBUG(4, "Frame not ready? state = %d", + ov->frame[nextf].grabstate); + } + + ov->curframe = -1; + } + } else { + PDEBUG(5, "Frame done, but not scanning"); + } + /* Image corruption caused by misplaced frame->segment = 0 + * fixed by carlosf@conectiva.com.br + */ + } else { + /* Frame start */ + PDEBUG(4, "Frame start, framenum = %d", ov->curframe); + + /* Check to see if it's a snapshot frame */ + /* FIXME?? Should the snapshot reset go here? Performance? */ + if (in[8] & 0x02) { + frame->snapshot = 1; + PDEBUG(3, "snapshot detected"); + } + + frame->scanstate = STATE_LINES; + frame->bytes_recvd = 0; + frame->compressed = in[8] & 0x40; + } + +check_middle: + /* Are we in a frame? */ + if (frame->scanstate != STATE_LINES) { + PDEBUG(5, "Not in a frame; packet skipped"); + return; + } + + /* If frame start, skip header */ + if (frame->bytes_recvd == 0) + offset = 9; + else + offset = 0; + + num = n - offset - 1; + + /* Dump all data exactly as received */ + if (dumppix == 2) { + frame->bytes_recvd += n - 1; + if (frame->bytes_recvd <= max_raw) + memcpy(frame->rawdata + frame->bytes_recvd - (n - 1), + in, n - 1); + else + PDEBUG(3, "Raw data buffer overrun!! (%d)", + frame->bytes_recvd - max_raw); + } else if (!frame->compressed && !remove_zeros) { + frame->bytes_recvd += num; + if (frame->bytes_recvd <= max_raw) + memcpy(frame->rawdata + frame->bytes_recvd - num, + in + offset, num); + else + PDEBUG(3, "Raw data buffer overrun!! (%d)", + frame->bytes_recvd - max_raw); + } else { /* Remove all-zero FIFO lines (aligned 32-byte blocks) */ + int b, read = 0, allzero, copied = 0; + if (offset) { + frame->bytes_recvd += 32 - offset; // Bytes out + memcpy(frame->rawdata, in + offset, 32 - offset); + read += 32; + } + + while (read < n - 1) { + allzero = 1; + for (b = 0; b < 32; b++) { + if (in[read + b]) { + allzero = 0; + break; + } + } + + if (allzero) { + /* Don't copy it */ + } else { + if (frame->bytes_recvd + copied + 32 <= max_raw) + { + memcpy(frame->rawdata + + frame->bytes_recvd + copied, + in + read, 32); + copied += 32; + } else { + PDEBUG(3, "Raw data buffer overrun!!"); + } + } + read += 32; + } + + frame->bytes_recvd += copied; + } +} + +static inline void +ov518_move_data(struct usb_ov511 *ov, unsigned char *in, int n) +{ + int max_raw = MAX_RAW_DATA_SIZE(ov->maxwidth, ov->maxheight); + struct ov511_frame *frame = &ov->frame[ov->curframe]; + struct timeval *ts; + + /* Don't copy the packet number byte */ + if (ov->packet_numbering) + --n; + + /* A false positive here is likely, until OVT gives me + * the definitive SOF/EOF format */ + if ((!(in[0] | in[1] | in[2] | in[3] | in[5])) && in[6]) { + if (printph) { + info("ph: %2x %2x %2x %2x %2x %2x %2x %2x", in[0], + in[1], in[2], in[3], in[4], in[5], in[6], in[7]); + } + + if (frame->scanstate == STATE_LINES) { + PDEBUG(4, "Detected frame end/start"); + goto eof; + } else { //scanstate == STATE_SCANNING + /* Frame start */ + PDEBUG(4, "Frame start, framenum = %d", ov->curframe); + goto sof; + } + } else { + goto check_middle; + } + +eof: + ts = (struct timeval *)(frame->data + + MAX_FRAME_SIZE(ov->maxwidth, ov->maxheight)); + do_gettimeofday(ts); + + PDEBUG(4, "Frame end, curframe = %d, hw=%d, vw=%d, recvd=%d", + ov->curframe, + (int)(in[9]), (int)(in[10]), frame->bytes_recvd); + + // FIXME: Since we don't know the header formats yet, + // there is no way to know what the actual image size is + frame->rawwidth = frame->width; + frame->rawheight = frame->height; + + /* Validate the header data */ + RESTRICT_TO_RANGE(frame->rawwidth, ov->minwidth, ov->maxwidth); + RESTRICT_TO_RANGE(frame->rawheight, ov->minheight, ov->maxheight); + + /* Don't allow byte count to exceed buffer size */ + RESTRICT_TO_RANGE(frame->bytes_recvd, 8, max_raw); + + if (frame->scanstate == STATE_LINES) { + int nextf; + + frame->grabstate = FRAME_DONE; + wake_up_interruptible(&frame->wq); + + /* If next frame is ready or grabbing, + * point to it */ + nextf = (ov->curframe + 1) % OV511_NUMFRAMES; + if (ov->frame[nextf].grabstate == FRAME_READY + || ov->frame[nextf].grabstate == FRAME_GRABBING) { + ov->curframe = nextf; + ov->frame[nextf].scanstate = STATE_SCANNING; + frame = &ov->frame[nextf]; + } else { + if (frame->grabstate == FRAME_DONE) { + PDEBUG(4, "** Frame done **"); + } else { + PDEBUG(4, "Frame not ready? state = %d", + ov->frame[nextf].grabstate); + } + + ov->curframe = -1; + PDEBUG(4, "SOF dropped (no active frame)"); + return; /* Nowhere to store this frame */ + } + } +sof: + PDEBUG(4, "Starting capture on frame %d", frame->framenum); + +// Snapshot not reverse-engineered yet. +#if 0 + /* Check to see if it's a snapshot frame */ + /* FIXME?? Should the snapshot reset go here? Performance? */ + if (in[8] & 0x02) { + frame->snapshot = 1; + PDEBUG(3, "snapshot detected"); + } +#endif + frame->scanstate = STATE_LINES; + frame->bytes_recvd = 0; + frame->compressed = 1; + +check_middle: + /* Are we in a frame? */ + if (frame->scanstate != STATE_LINES) { + PDEBUG(4, "scanstate: no SOF yet"); + return; + } + + /* Dump all data exactly as received */ + if (dumppix == 2) { + frame->bytes_recvd += n; + if (frame->bytes_recvd <= max_raw) + memcpy(frame->rawdata + frame->bytes_recvd - n, in, n); + else + PDEBUG(3, "Raw data buffer overrun!! (%d)", + frame->bytes_recvd - max_raw); + } else { + /* All incoming data are divided into 8-byte segments. If the + * segment contains all zero bytes, it must be skipped. These + * zero-segments allow the OV518 to mainain a constant data rate + * regardless of the effectiveness of the compression. Segments + * are aligned relative to the beginning of each isochronous + * packet. The first segment in each image is a header (the + * decompressor skips it later). + */ + + int b, read = 0, allzero, copied = 0; + + while (read < n) { + allzero = 1; + for (b = 0; b < 8; b++) { + if (in[read + b]) { + allzero = 0; + break; + } + } + + if (allzero) { + /* Don't copy it */ + } else { + if (frame->bytes_recvd + copied + 8 <= max_raw) + { + memcpy(frame->rawdata + + frame->bytes_recvd + copied, + in + read, 8); + copied += 8; + } else { + PDEBUG(3, "Raw data buffer overrun!!"); + } + } + read += 8; + } + frame->bytes_recvd += copied; + } +} + +static void +ov51x_isoc_irq(struct urb *urb) +{ + int i; + struct usb_ov511 *ov; + struct ov511_sbuf *sbuf; + + if (!urb->context) { + PDEBUG(4, "no context"); + return; + } + + sbuf = urb->context; + ov = sbuf->ov; + + if (!ov || !ov->dev || !ov->user) { + PDEBUG(4, "no device, or not open"); + return; + } + + if (!ov->streaming) { + PDEBUG(4, "hmmm... not streaming, but got interrupt"); + return; + } + + if (urb->status == -ENOENT || urb->status == -ECONNRESET) { + PDEBUG(4, "URB unlinked"); + return; + } + + if (urb->status != -EINPROGRESS && urb->status != 0) { + err("ERROR: urb->status=%d: %s", urb->status, + symbolic(urb_errlist, urb->status)); + } + + /* Copy the data received into our frame buffer */ + PDEBUG(5, "sbuf[%d]: Moving %d packets", sbuf->n, + urb->number_of_packets); + for (i = 0; i < urb->number_of_packets; i++) { + /* Warning: Don't call *_move_data() if no frame active! */ + if (ov->curframe >= 0) { + int n = urb->iso_frame_desc[i].actual_length; + int st = urb->iso_frame_desc[i].status; + unsigned char *cdata; + + urb->iso_frame_desc[i].actual_length = 0; + urb->iso_frame_desc[i].status = 0; + + cdata = urb->transfer_buffer + + urb->iso_frame_desc[i].offset; + + if (!n) { + PDEBUG(4, "Zero-length packet"); + continue; + } + + if (st) + PDEBUG(2, "data error: [%d] len=%d, status=%d", + i, n, st); + + if (ov->bclass == BCL_OV511) + ov511_move_data(ov, cdata, n); + else if (ov->bclass == BCL_OV518) + ov518_move_data(ov, cdata, n); + else + err("Unknown bridge device (%d)", ov->bridge); + + } else if (waitqueue_active(&ov->wq)) { + wake_up_interruptible(&ov->wq); + } + } + + /* Resubmit this URB */ + urb->dev = ov->dev; + if ((i = usb_submit_urb(urb, GFP_ATOMIC)) != 0) + err("usb_submit_urb() ret %d", i); + + return; +} + +/**************************************************************************** + * + * Stream initialization and termination + * + ***************************************************************************/ + +static int +ov51x_init_isoc(struct usb_ov511 *ov) +{ + struct urb *urb; + int fx, err, n, size; + + PDEBUG(3, "*** Initializing capture ***"); + + ov->curframe = -1; + + if (ov->bridge == BRG_OV511) { + if (cams == 1) + size = 993; + else if (cams == 2) + size = 513; + else if (cams == 3 || cams == 4) + size = 257; + else { + err("\"cams\" parameter too high!"); + return -1; + } + } else if (ov->bridge == BRG_OV511PLUS) { + if (cams == 1) + size = 961; + else if (cams == 2) + size = 513; + else if (cams == 3 || cams == 4) + size = 257; + else if (cams >= 5 && cams <= 8) + size = 129; + else if (cams >= 9 && cams <= 31) + size = 33; + else { + err("\"cams\" parameter too high!"); + return -1; + } + } else if (ov->bclass == BCL_OV518) { + if (cams == 1) + size = 896; + else if (cams == 2) + size = 512; + else if (cams == 3 || cams == 4) + size = 256; + else if (cams >= 5 && cams <= 8) + size = 128; + else { + err("\"cams\" parameter too high!"); + return -1; + } + } else { + err("invalid bridge type"); + return -1; + } + + // FIXME: OV518 is hardcoded to 15 FPS (alternate 5) for now + if (ov->bclass == BCL_OV518) { + if (packetsize == -1) { + ov518_set_packet_size(ov, 640); + } else { + info("Forcing packet size to %d", packetsize); + ov518_set_packet_size(ov, packetsize); + } + } else { + if (packetsize == -1) { + ov511_set_packet_size(ov, size); + } else { + info("Forcing packet size to %d", packetsize); + ov511_set_packet_size(ov, packetsize); + } + } + + for (n = 0; n < OV511_NUMSBUF; n++) { + urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL); + if (!urb) { + err("init isoc: usb_alloc_urb ret. NULL"); + return -ENOMEM; + } + ov->sbuf[n].urb = urb; + urb->dev = ov->dev; + urb->context = &ov->sbuf[n]; + urb->pipe = usb_rcvisocpipe(ov->dev, OV511_ENDPOINT_ADDRESS); + urb->transfer_flags = URB_ISO_ASAP; + urb->transfer_buffer = ov->sbuf[n].data; + urb->complete = ov51x_isoc_irq; + urb->number_of_packets = FRAMES_PER_DESC; + urb->transfer_buffer_length = ov->packet_size * FRAMES_PER_DESC; + urb->interval = 1; + for (fx = 0; fx < FRAMES_PER_DESC; fx++) { + urb->iso_frame_desc[fx].offset = ov->packet_size * fx; + urb->iso_frame_desc[fx].length = ov->packet_size; + } + } + + ov->streaming = 1; + + for (n = 0; n < OV511_NUMSBUF; n++) { + ov->sbuf[n].urb->dev = ov->dev; + err = usb_submit_urb(ov->sbuf[n].urb, GFP_KERNEL); + if (err) { + err("init isoc: usb_submit_urb(%d) ret %d", n, err); + return err; + } + } + + return 0; +} + +static void +ov51x_unlink_isoc(struct usb_ov511 *ov) +{ + int n; + + /* Unschedule all of the iso td's */ + for (n = OV511_NUMSBUF - 1; n >= 0; n--) { + if (ov->sbuf[n].urb) { + usb_kill_urb(ov->sbuf[n].urb); + usb_free_urb(ov->sbuf[n].urb); + ov->sbuf[n].urb = NULL; + } + } +} + +static void +ov51x_stop_isoc(struct usb_ov511 *ov) +{ + if (!ov->streaming || !ov->dev) + return; + + PDEBUG(3, "*** Stopping capture ***"); + + if (ov->bclass == BCL_OV518) + ov518_set_packet_size(ov, 0); + else + ov511_set_packet_size(ov, 0); + + ov->streaming = 0; + + ov51x_unlink_isoc(ov); +} + +static int +ov51x_new_frame(struct usb_ov511 *ov, int framenum) +{ + struct ov511_frame *frame; + int newnum; + + PDEBUG(4, "ov->curframe = %d, framenum = %d", ov->curframe, framenum); + + if (!ov->dev) + return -1; + + /* If we're not grabbing a frame right now and the other frame is */ + /* ready to be grabbed into, then use it instead */ + if (ov->curframe == -1) { + newnum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES; + if (ov->frame[newnum].grabstate == FRAME_READY) + framenum = newnum; + } else + return 0; + + frame = &ov->frame[framenum]; + + PDEBUG(4, "framenum = %d, width = %d, height = %d", framenum, + frame->width, frame->height); + + frame->grabstate = FRAME_GRABBING; + frame->scanstate = STATE_SCANNING; + frame->snapshot = 0; + + ov->curframe = framenum; + + /* Make sure it's not too big */ + if (frame->width > ov->maxwidth) + frame->width = ov->maxwidth; + + frame->width &= ~7L; /* Multiple of 8 */ + + if (frame->height > ov->maxheight) + frame->height = ov->maxheight; + + frame->height &= ~3L; /* Multiple of 4 */ + + return 0; +} + +/**************************************************************************** + * + * Buffer management + * + ***************************************************************************/ + +/* + * - You must acquire buf_lock before entering this function. + * - Because this code will free any non-null pointer, you must be sure to null + * them if you explicitly free them somewhere else! + */ +static void +ov51x_do_dealloc(struct usb_ov511 *ov) +{ + int i; + PDEBUG(4, "entered"); + + if (ov->fbuf) { + rvfree(ov->fbuf, OV511_NUMFRAMES + * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight)); + ov->fbuf = NULL; + } + + vfree(ov->rawfbuf); + ov->rawfbuf = NULL; + + vfree(ov->tempfbuf); + ov->tempfbuf = NULL; + + for (i = 0; i < OV511_NUMSBUF; i++) { + kfree(ov->sbuf[i].data); + ov->sbuf[i].data = NULL; + } + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].data = NULL; + ov->frame[i].rawdata = NULL; + ov->frame[i].tempdata = NULL; + if (ov->frame[i].compbuf) { + free_page((unsigned long) ov->frame[i].compbuf); + ov->frame[i].compbuf = NULL; + } + } + + PDEBUG(4, "buffer memory deallocated"); + ov->buf_state = BUF_NOT_ALLOCATED; + PDEBUG(4, "leaving"); +} + +static int +ov51x_alloc(struct usb_ov511 *ov) +{ + int i; + const int w = ov->maxwidth; + const int h = ov->maxheight; + const int data_bufsize = OV511_NUMFRAMES * MAX_DATA_SIZE(w, h); + const int raw_bufsize = OV511_NUMFRAMES * MAX_RAW_DATA_SIZE(w, h); + + PDEBUG(4, "entered"); + down(&ov->buf_lock); + + if (ov->buf_state == BUF_ALLOCATED) + goto out; + + ov->fbuf = rvmalloc(data_bufsize); + if (!ov->fbuf) + goto error; + + ov->rawfbuf = vmalloc(raw_bufsize); + if (!ov->rawfbuf) + goto error; + + memset(ov->rawfbuf, 0, raw_bufsize); + + ov->tempfbuf = vmalloc(raw_bufsize); + if (!ov->tempfbuf) + goto error; + + memset(ov->tempfbuf, 0, raw_bufsize); + + for (i = 0; i < OV511_NUMSBUF; i++) { + ov->sbuf[i].data = kmalloc(FRAMES_PER_DESC * + MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL); + if (!ov->sbuf[i].data) + goto error; + + PDEBUG(4, "sbuf[%d] @ %p", i, ov->sbuf[i].data); + } + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].data = ov->fbuf + i * MAX_DATA_SIZE(w, h); + ov->frame[i].rawdata = ov->rawfbuf + + i * MAX_RAW_DATA_SIZE(w, h); + ov->frame[i].tempdata = ov->tempfbuf + + i * MAX_RAW_DATA_SIZE(w, h); + + ov->frame[i].compbuf = + (unsigned char *) __get_free_page(GFP_KERNEL); + if (!ov->frame[i].compbuf) + goto error; + + PDEBUG(4, "frame[%d] @ %p", i, ov->frame[i].data); + } + + ov->buf_state = BUF_ALLOCATED; +out: + up(&ov->buf_lock); + PDEBUG(4, "leaving"); + return 0; +error: + ov51x_do_dealloc(ov); + up(&ov->buf_lock); + PDEBUG(4, "errored"); + return -ENOMEM; +} + +static void +ov51x_dealloc(struct usb_ov511 *ov) +{ + PDEBUG(4, "entered"); + down(&ov->buf_lock); + ov51x_do_dealloc(ov); + up(&ov->buf_lock); + PDEBUG(4, "leaving"); +} + +/**************************************************************************** + * + * V4L 1 API + * + ***************************************************************************/ + +static int +ov51x_v4l1_open(struct inode *inode, struct file *file) +{ + struct video_device *vdev = video_devdata(file); + struct usb_ov511 *ov = video_get_drvdata(vdev); + int err, i; + + PDEBUG(4, "opening"); + + down(&ov->lock); + + err = -EBUSY; + if (ov->user) + goto out; + + ov->sub_flag = 0; + + /* In case app doesn't set them... */ + err = ov51x_set_default_params(ov); + if (err < 0) + goto out; + + /* Make sure frames are reset */ + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].grabstate = FRAME_UNUSED; + ov->frame[i].bytes_read = 0; + } + + /* If compression is on, make sure now that a + * decompressor can be loaded */ + if (ov->compress && !ov->decomp_ops) { + err = request_decompressor(ov); + if (err && !dumppix) + goto out; + } + + err = ov51x_alloc(ov); + if (err < 0) + goto out; + + err = ov51x_init_isoc(ov); + if (err) { + ov51x_dealloc(ov); + goto out; + } + + ov->user++; + file->private_data = vdev; + + if (ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 1); + +out: + up(&ov->lock); + return err; +} + +static int +ov51x_v4l1_close(struct inode *inode, struct file *file) +{ + struct video_device *vdev = file->private_data; + struct usb_ov511 *ov = video_get_drvdata(vdev); + + PDEBUG(4, "ov511_close"); + + down(&ov->lock); + + ov->user--; + ov51x_stop_isoc(ov); + + release_decompressor(ov); + + if (ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 0); + + if (ov->dev) + ov51x_dealloc(ov); + + up(&ov->lock); + + /* Device unplugged while open. Only a minimum of unregistration is done + * here; the disconnect callback already did the rest. */ + if (!ov->dev) { + down(&ov->cbuf_lock); + kfree(ov->cbuf); + ov->cbuf = NULL; + up(&ov->cbuf_lock); + + ov51x_dealloc(ov); + kfree(ov); + ov = NULL; + } + + file->private_data = NULL; + return 0; +} + +/* Do not call this function directly! */ +static int +ov51x_v4l1_ioctl_internal(struct inode *inode, struct file *file, + unsigned int cmd, void *arg) +{ + struct video_device *vdev = file->private_data; + struct usb_ov511 *ov = video_get_drvdata(vdev); + PDEBUG(5, "IOCtl: 0x%X", cmd); + + if (!ov->dev) + return -EIO; + + switch (cmd) { + case VIDIOCGCAP: + { + struct video_capability *b = arg; + + PDEBUG(4, "VIDIOCGCAP"); + + memset(b, 0, sizeof(struct video_capability)); + sprintf(b->name, "%s USB Camera", + symbolic(brglist, ov->bridge)); + b->type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE; + b->channels = ov->num_inputs; + b->audios = 0; + b->maxwidth = ov->maxwidth; + b->maxheight = ov->maxheight; + b->minwidth = ov->minwidth; + b->minheight = ov->minheight; + + return 0; + } + case VIDIOCGCHAN: + { + struct video_channel *v = arg; + + PDEBUG(4, "VIDIOCGCHAN"); + + if ((unsigned)(v->channel) >= ov->num_inputs) { + err("Invalid channel (%d)", v->channel); + return -EINVAL; + } + + v->norm = ov->norm; + v->type = VIDEO_TYPE_CAMERA; + v->flags = 0; +// v->flags |= (ov->has_decoder) ? VIDEO_VC_NORM : 0; + v->tuners = 0; + decoder_get_input_name(ov, v->channel, v->name); + + return 0; + } + case VIDIOCSCHAN: + { + struct video_channel *v = arg; + int err; + + PDEBUG(4, "VIDIOCSCHAN"); + + /* Make sure it's not a camera */ + if (!ov->has_decoder) { + if (v->channel == 0) + return 0; + else + return -EINVAL; + } + + if (v->norm != VIDEO_MODE_PAL && + v->norm != VIDEO_MODE_NTSC && + v->norm != VIDEO_MODE_SECAM && + v->norm != VIDEO_MODE_AUTO) { + err("Invalid norm (%d)", v->norm); + return -EINVAL; + } + + if ((unsigned)(v->channel) >= ov->num_inputs) { + err("Invalid channel (%d)", v->channel); + return -EINVAL; + } + + err = decoder_set_input(ov, v->channel); + if (err) + return err; + + err = decoder_set_norm(ov, v->norm); + if (err) + return err; + + return 0; + } + case VIDIOCGPICT: + { + struct video_picture *p = arg; + + PDEBUG(4, "VIDIOCGPICT"); + + memset(p, 0, sizeof(struct video_picture)); + if (sensor_get_picture(ov, p)) + return -EIO; + + /* Can we get these from frame[0]? -claudio? */ + p->depth = ov->frame[0].depth; + p->palette = ov->frame[0].format; + + return 0; + } + case VIDIOCSPICT: + { + struct video_picture *p = arg; + int i, rc; + + PDEBUG(4, "VIDIOCSPICT"); + + if (!get_depth(p->palette)) + return -EINVAL; + + if (sensor_set_picture(ov, p)) + return -EIO; + + if (force_palette && p->palette != force_palette) { + info("Palette rejected (%s)", + symbolic(v4l1_plist, p->palette)); + return -EINVAL; + } + + // FIXME: Format should be independent of frames + if (p->palette != ov->frame[0].format) { + PDEBUG(4, "Detected format change"); + + rc = ov51x_wait_frames_inactive(ov); + if (rc) + return rc; + + mode_init_regs(ov, ov->frame[0].width, + ov->frame[0].height, p->palette, ov->sub_flag); + } + + PDEBUG(4, "Setting depth=%d, palette=%s", + p->depth, symbolic(v4l1_plist, p->palette)); + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].depth = p->depth; + ov->frame[i].format = p->palette; + } + + return 0; + } + case VIDIOCGCAPTURE: + { + int *vf = arg; + + PDEBUG(4, "VIDIOCGCAPTURE"); + + ov->sub_flag = *vf; + return 0; + } + case VIDIOCSCAPTURE: + { + struct video_capture *vc = arg; + + PDEBUG(4, "VIDIOCSCAPTURE"); + + if (vc->flags) + return -EINVAL; + if (vc->decimation) + return -EINVAL; + + vc->x &= ~3L; + vc->y &= ~1L; + vc->y &= ~31L; + + if (vc->width == 0) + vc->width = 32; + + vc->height /= 16; + vc->height *= 16; + if (vc->height == 0) + vc->height = 16; + + ov->subx = vc->x; + ov->suby = vc->y; + ov->subw = vc->width; + ov->subh = vc->height; + + return 0; + } + case VIDIOCSWIN: + { + struct video_window *vw = arg; + int i, rc; + + PDEBUG(4, "VIDIOCSWIN: %dx%d", vw->width, vw->height); + +#if 0 + if (vw->flags) + return -EINVAL; + if (vw->clipcount) + return -EINVAL; + if (vw->height != ov->maxheight) + return -EINVAL; + if (vw->width != ov->maxwidth) + return -EINVAL; +#endif + + rc = ov51x_wait_frames_inactive(ov); + if (rc) + return rc; + + rc = mode_init_regs(ov, vw->width, vw->height, + ov->frame[0].format, ov->sub_flag); + if (rc < 0) + return rc; + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].width = vw->width; + ov->frame[i].height = vw->height; + } + + return 0; + } + case VIDIOCGWIN: + { + struct video_window *vw = arg; + + memset(vw, 0, sizeof(struct video_window)); + vw->x = 0; /* FIXME */ + vw->y = 0; + vw->width = ov->frame[0].width; + vw->height = ov->frame[0].height; + vw->flags = 30; + + PDEBUG(4, "VIDIOCGWIN: %dx%d", vw->width, vw->height); + + return 0; + } + case VIDIOCGMBUF: + { + struct video_mbuf *vm = arg; + int i; + + PDEBUG(4, "VIDIOCGMBUF"); + + memset(vm, 0, sizeof(struct video_mbuf)); + vm->size = OV511_NUMFRAMES + * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight); + vm->frames = OV511_NUMFRAMES; + + vm->offsets[0] = 0; + for (i = 1; i < OV511_NUMFRAMES; i++) { + vm->offsets[i] = vm->offsets[i-1] + + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight); + } + + return 0; + } + case VIDIOCMCAPTURE: + { + struct video_mmap *vm = arg; + int rc, depth; + unsigned int f = vm->frame; + + PDEBUG(4, "VIDIOCMCAPTURE: frame: %d, %dx%d, %s", f, vm->width, + vm->height, symbolic(v4l1_plist, vm->format)); + + depth = get_depth(vm->format); + if (!depth) { + PDEBUG(2, "VIDIOCMCAPTURE: invalid format (%s)", + symbolic(v4l1_plist, vm->format)); + return -EINVAL; + } + + if (f >= OV511_NUMFRAMES) { + err("VIDIOCMCAPTURE: invalid frame (%d)", f); + return -EINVAL; + } + + if (vm->width > ov->maxwidth + || vm->height > ov->maxheight) { + err("VIDIOCMCAPTURE: requested dimensions too big"); + return -EINVAL; + } + + if (ov->frame[f].grabstate == FRAME_GRABBING) { + PDEBUG(4, "VIDIOCMCAPTURE: already grabbing"); + return -EBUSY; + } + + if (force_palette && (vm->format != force_palette)) { + PDEBUG(2, "palette rejected (%s)", + symbolic(v4l1_plist, vm->format)); + return -EINVAL; + } + + if ((ov->frame[f].width != vm->width) || + (ov->frame[f].height != vm->height) || + (ov->frame[f].format != vm->format) || + (ov->frame[f].sub_flag != ov->sub_flag) || + (ov->frame[f].depth != depth)) { + PDEBUG(4, "VIDIOCMCAPTURE: change in image parameters"); + + rc = ov51x_wait_frames_inactive(ov); + if (rc) + return rc; + + rc = mode_init_regs(ov, vm->width, vm->height, + vm->format, ov->sub_flag); +#if 0 + if (rc < 0) { + PDEBUG(1, "Got error while initializing regs "); + return ret; + } +#endif + ov->frame[f].width = vm->width; + ov->frame[f].height = vm->height; + ov->frame[f].format = vm->format; + ov->frame[f].sub_flag = ov->sub_flag; + ov->frame[f].depth = depth; + } + + /* Mark it as ready */ + ov->frame[f].grabstate = FRAME_READY; + + PDEBUG(4, "VIDIOCMCAPTURE: renewing frame %d", f); + + return ov51x_new_frame(ov, f); + } + case VIDIOCSYNC: + { + unsigned int fnum = *((unsigned int *) arg); + struct ov511_frame *frame; + int rc; + + if (fnum >= OV511_NUMFRAMES) { + err("VIDIOCSYNC: invalid frame (%d)", fnum); + return -EINVAL; + } + + frame = &ov->frame[fnum]; + + PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum, + frame->grabstate); + + switch (frame->grabstate) { + case FRAME_UNUSED: + return -EINVAL; + case FRAME_READY: + case FRAME_GRABBING: + case FRAME_ERROR: +redo: + if (!ov->dev) + return -EIO; + + rc = wait_event_interruptible(frame->wq, + (frame->grabstate == FRAME_DONE) + || (frame->grabstate == FRAME_ERROR)); + + if (rc) + return rc; + + if (frame->grabstate == FRAME_ERROR) { + if ((rc = ov51x_new_frame(ov, fnum)) < 0) + return rc; + goto redo; + } + /* Fall through */ + case FRAME_DONE: + if (ov->snap_enabled && !frame->snapshot) { + if ((rc = ov51x_new_frame(ov, fnum)) < 0) + return rc; + goto redo; + } + + frame->grabstate = FRAME_UNUSED; + + /* Reset the hardware snapshot button */ + /* FIXME - Is this the best place for this? */ + if ((ov->snap_enabled) && (frame->snapshot)) { + frame->snapshot = 0; + ov51x_clear_snapshot(ov); + } + + /* Decompression, format conversion, etc... */ + ov51x_postprocess(ov, frame); + + break; + } /* end switch */ + + return 0; + } + case VIDIOCGFBUF: + { + struct video_buffer *vb = arg; + + PDEBUG(4, "VIDIOCGFBUF"); + + memset(vb, 0, sizeof(struct video_buffer)); + + return 0; + } + case VIDIOCGUNIT: + { + struct video_unit *vu = arg; + + PDEBUG(4, "VIDIOCGUNIT"); + + memset(vu, 0, sizeof(struct video_unit)); + + vu->video = ov->vdev->minor; + vu->vbi = VIDEO_NO_UNIT; + vu->radio = VIDEO_NO_UNIT; + vu->audio = VIDEO_NO_UNIT; + vu->teletext = VIDEO_NO_UNIT; + + return 0; + } + case OV511IOC_WI2C: + { + struct ov511_i2c_struct *w = arg; + + return i2c_w_slave(ov, w->slave, w->reg, w->value, w->mask); + } + case OV511IOC_RI2C: + { + struct ov511_i2c_struct *r = arg; + int rc; + + rc = i2c_r_slave(ov, r->slave, r->reg); + if (rc < 0) + return rc; + + r->value = rc; + return 0; + } + default: + PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd); + return -ENOIOCTLCMD; + } /* end switch */ + + return 0; +} + +static int +ov51x_v4l1_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct video_device *vdev = file->private_data; + struct usb_ov511 *ov = video_get_drvdata(vdev); + int rc; + + if (down_interruptible(&ov->lock)) + return -EINTR; + + rc = video_usercopy(inode, file, cmd, arg, ov51x_v4l1_ioctl_internal); + + up(&ov->lock); + return rc; +} + +static ssize_t +ov51x_v4l1_read(struct file *file, char __user *buf, size_t cnt, loff_t *ppos) +{ + struct video_device *vdev = file->private_data; + int noblock = file->f_flags&O_NONBLOCK; + unsigned long count = cnt; + struct usb_ov511 *ov = video_get_drvdata(vdev); + int i, rc = 0, frmx = -1; + struct ov511_frame *frame; + + if (down_interruptible(&ov->lock)) + return -EINTR; + + PDEBUG(4, "%ld bytes, noblock=%d", count, noblock); + + if (!vdev || !buf) { + rc = -EFAULT; + goto error; + } + + if (!ov->dev) { + rc = -EIO; + goto error; + } + +// FIXME: Only supports two frames + /* See if a frame is completed, then use it. */ + if (ov->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */ + frmx = 0; + else if (ov->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */ + frmx = 1; + + /* If nonblocking we return immediately */ + if (noblock && (frmx == -1)) { + rc = -EAGAIN; + goto error; + } + + /* If no FRAME_DONE, look for a FRAME_GRABBING state. */ + /* See if a frame is in process (grabbing), then use it. */ + if (frmx == -1) { + if (ov->frame[0].grabstate == FRAME_GRABBING) + frmx = 0; + else if (ov->frame[1].grabstate == FRAME_GRABBING) + frmx = 1; + } + + /* If no frame is active, start one. */ + if (frmx == -1) { + if ((rc = ov51x_new_frame(ov, frmx = 0))) { + err("read: ov51x_new_frame error"); + goto error; + } + } + + frame = &ov->frame[frmx]; + +restart: + if (!ov->dev) { + rc = -EIO; + goto error; + } + + /* Wait while we're grabbing the image */ + PDEBUG(4, "Waiting image grabbing"); + rc = wait_event_interruptible(frame->wq, + (frame->grabstate == FRAME_DONE) + || (frame->grabstate == FRAME_ERROR)); + + if (rc) + goto error; + + PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate); + PDEBUG(4, "bytes_recvd = %d", frame->bytes_recvd); + + if (frame->grabstate == FRAME_ERROR) { + frame->bytes_read = 0; + err("** ick! ** Errored frame %d", ov->curframe); + if (ov51x_new_frame(ov, frmx)) { + err("read: ov51x_new_frame error"); + goto error; + } + goto restart; + } + + + /* Repeat until we get a snapshot frame */ + if (ov->snap_enabled) + PDEBUG(4, "Waiting snapshot frame"); + if (ov->snap_enabled && !frame->snapshot) { + frame->bytes_read = 0; + if ((rc = ov51x_new_frame(ov, frmx))) { + err("read: ov51x_new_frame error"); + goto error; + } + goto restart; + } + + /* Clear the snapshot */ + if (ov->snap_enabled && frame->snapshot) { + frame->snapshot = 0; + ov51x_clear_snapshot(ov); + } + + /* Decompression, format conversion, etc... */ + ov51x_postprocess(ov, frame); + + PDEBUG(4, "frmx=%d, bytes_read=%ld, length=%ld", frmx, + frame->bytes_read, + get_frame_length(frame)); + + /* copy bytes to user space; we allow for partials reads */ +// if ((count + frame->bytes_read) +// > get_frame_length((struct ov511_frame *)frame)) +// count = frame->scanlength - frame->bytes_read; + + /* FIXME - count hardwired to be one frame... */ + count = get_frame_length(frame); + + PDEBUG(4, "Copy to user space: %ld bytes", count); + if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) { + PDEBUG(4, "Copy failed! %d bytes not copied", i); + rc = -EFAULT; + goto error; + } + + frame->bytes_read += count; + PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld", + count, frame->bytes_read); + + /* If all data have been read... */ + if (frame->bytes_read + >= get_frame_length(frame)) { + frame->bytes_read = 0; + +// FIXME: Only supports two frames + /* Mark it as available to be used again. */ + ov->frame[frmx].grabstate = FRAME_UNUSED; + if ((rc = ov51x_new_frame(ov, !frmx))) { + err("ov51x_new_frame returned error"); + goto error; + } + } + + PDEBUG(4, "read finished, returning %ld (sweet)", count); + + up(&ov->lock); + return count; + +error: + up(&ov->lock); + return rc; +} + +static int +ov51x_v4l1_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct video_device *vdev = file->private_data; + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; + struct usb_ov511 *ov = video_get_drvdata(vdev); + unsigned long page, pos; + + if (ov->dev == NULL) + return -EIO; + + PDEBUG(4, "mmap: %ld (%lX) bytes", size, size); + + if (size > (((OV511_NUMFRAMES + * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight) + + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))) + return -EINVAL; + + if (down_interruptible(&ov->lock)) + return -EINTR; + + pos = (unsigned long)ov->fbuf; + while (size > 0) { + page = vmalloc_to_pfn((void *)pos); + if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) { + up(&ov->lock); + return -EAGAIN; + } + start += PAGE_SIZE; + pos += PAGE_SIZE; + if (size > PAGE_SIZE) + size -= PAGE_SIZE; + else + size = 0; + } + + up(&ov->lock); + return 0; +} + +static struct file_operations ov511_fops = { + .owner = THIS_MODULE, + .open = ov51x_v4l1_open, + .release = ov51x_v4l1_close, + .read = ov51x_v4l1_read, + .mmap = ov51x_v4l1_mmap, + .ioctl = ov51x_v4l1_ioctl, + .llseek = no_llseek, +}; + +static struct video_device vdev_template = { + .name = "OV511 USB Camera", + .fops = &ov511_fops, + .release = video_device_release, + .minor = -1, +}; + +/**************************************************************************** + * + * OV511 and sensor configuration + * + ***************************************************************************/ + +/* This initializes the OV7610, OV7620, or OV76BE sensor. The OV76BE uses + * the same register settings as the OV7610, since they are very similar. + */ +static int +ov7xx0_configure(struct usb_ov511 *ov) +{ + int i, success; + int rc; + + /* Lawrence Glaister reports: + * + * Register 0x0f in the 7610 has the following effects: + * + * 0x85 (AEC method 1): Best overall, good contrast range + * 0x45 (AEC method 2): Very overexposed + * 0xa5 (spec sheet default): Ok, but the black level is + * shifted resulting in loss of contrast + * 0x05 (old driver setting): very overexposed, too much + * contrast + */ + static struct ov511_regvals aRegvalsNorm7610[] = { + { OV511_I2C_BUS, 0x10, 0xff }, + { OV511_I2C_BUS, 0x16, 0x06 }, + { OV511_I2C_BUS, 0x28, 0x24 }, + { OV511_I2C_BUS, 0x2b, 0xac }, + { OV511_I2C_BUS, 0x12, 0x00 }, + { OV511_I2C_BUS, 0x38, 0x81 }, + { OV511_I2C_BUS, 0x28, 0x24 }, /* 0c */ + { OV511_I2C_BUS, 0x0f, 0x85 }, /* lg's setting */ + { OV511_I2C_BUS, 0x15, 0x01 }, + { OV511_I2C_BUS, 0x20, 0x1c }, + { OV511_I2C_BUS, 0x23, 0x2a }, + { OV511_I2C_BUS, 0x24, 0x10 }, + { OV511_I2C_BUS, 0x25, 0x8a }, + { OV511_I2C_BUS, 0x26, 0xa2 }, + { OV511_I2C_BUS, 0x27, 0xc2 }, + { OV511_I2C_BUS, 0x2a, 0x04 }, + { OV511_I2C_BUS, 0x2c, 0xfe }, + { OV511_I2C_BUS, 0x2d, 0x93 }, + { OV511_I2C_BUS, 0x30, 0x71 }, + { OV511_I2C_BUS, 0x31, 0x60 }, + { OV511_I2C_BUS, 0x32, 0x26 }, + { OV511_I2C_BUS, 0x33, 0x20 }, + { OV511_I2C_BUS, 0x34, 0x48 }, + { OV511_I2C_BUS, 0x12, 0x24 }, + { OV511_I2C_BUS, 0x11, 0x01 }, + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0d, 0x24 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + static struct ov511_regvals aRegvalsNorm7620[] = { + { OV511_I2C_BUS, 0x00, 0x00 }, + { OV511_I2C_BUS, 0x01, 0x80 }, + { OV511_I2C_BUS, 0x02, 0x80 }, + { OV511_I2C_BUS, 0x03, 0xc0 }, + { OV511_I2C_BUS, 0x06, 0x60 }, + { OV511_I2C_BUS, 0x07, 0x00 }, + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0d, 0x24 }, + { OV511_I2C_BUS, 0x11, 0x01 }, + { OV511_I2C_BUS, 0x12, 0x24 }, + { OV511_I2C_BUS, 0x13, 0x01 }, + { OV511_I2C_BUS, 0x14, 0x84 }, + { OV511_I2C_BUS, 0x15, 0x01 }, + { OV511_I2C_BUS, 0x16, 0x03 }, + { OV511_I2C_BUS, 0x17, 0x2f }, + { OV511_I2C_BUS, 0x18, 0xcf }, + { OV511_I2C_BUS, 0x19, 0x06 }, + { OV511_I2C_BUS, 0x1a, 0xf5 }, + { OV511_I2C_BUS, 0x1b, 0x00 }, + { OV511_I2C_BUS, 0x20, 0x18 }, + { OV511_I2C_BUS, 0x21, 0x80 }, + { OV511_I2C_BUS, 0x22, 0x80 }, + { OV511_I2C_BUS, 0x23, 0x00 }, + { OV511_I2C_BUS, 0x26, 0xa2 }, + { OV511_I2C_BUS, 0x27, 0xea }, + { OV511_I2C_BUS, 0x28, 0x20 }, + { OV511_I2C_BUS, 0x29, 0x00 }, + { OV511_I2C_BUS, 0x2a, 0x10 }, + { OV511_I2C_BUS, 0x2b, 0x00 }, + { OV511_I2C_BUS, 0x2c, 0x88 }, + { OV511_I2C_BUS, 0x2d, 0x91 }, + { OV511_I2C_BUS, 0x2e, 0x80 }, + { OV511_I2C_BUS, 0x2f, 0x44 }, + { OV511_I2C_BUS, 0x60, 0x27 }, + { OV511_I2C_BUS, 0x61, 0x02 }, + { OV511_I2C_BUS, 0x62, 0x5f }, + { OV511_I2C_BUS, 0x63, 0xd5 }, + { OV511_I2C_BUS, 0x64, 0x57 }, + { OV511_I2C_BUS, 0x65, 0x83 }, + { OV511_I2C_BUS, 0x66, 0x55 }, + { OV511_I2C_BUS, 0x67, 0x92 }, + { OV511_I2C_BUS, 0x68, 0xcf }, + { OV511_I2C_BUS, 0x69, 0x76 }, + { OV511_I2C_BUS, 0x6a, 0x22 }, + { OV511_I2C_BUS, 0x6b, 0x00 }, + { OV511_I2C_BUS, 0x6c, 0x02 }, + { OV511_I2C_BUS, 0x6d, 0x44 }, + { OV511_I2C_BUS, 0x6e, 0x80 }, + { OV511_I2C_BUS, 0x6f, 0x1d }, + { OV511_I2C_BUS, 0x70, 0x8b }, + { OV511_I2C_BUS, 0x71, 0x00 }, + { OV511_I2C_BUS, 0x72, 0x14 }, + { OV511_I2C_BUS, 0x73, 0x54 }, + { OV511_I2C_BUS, 0x74, 0x00 }, + { OV511_I2C_BUS, 0x75, 0x8e }, + { OV511_I2C_BUS, 0x76, 0x00 }, + { OV511_I2C_BUS, 0x77, 0xff }, + { OV511_I2C_BUS, 0x78, 0x80 }, + { OV511_I2C_BUS, 0x79, 0x80 }, + { OV511_I2C_BUS, 0x7a, 0x80 }, + { OV511_I2C_BUS, 0x7b, 0xe2 }, + { OV511_I2C_BUS, 0x7c, 0x00 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + PDEBUG(4, "starting configuration"); + + /* This looks redundant, but is necessary for WebCam 3 */ + ov->primary_i2c_slave = OV7xx0_SID; + if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) + return -1; + + if (init_ov_sensor(ov) >= 0) { + PDEBUG(1, "OV7xx0 sensor initalized (method 1)"); + } else { + /* Reset the 76xx */ + if (i2c_w(ov, 0x12, 0x80) < 0) + return -1; + + /* Wait for it to initialize */ + msleep(150); + + i = 0; + success = 0; + while (i <= i2c_detect_tries) { + if ((i2c_r(ov, OV7610_REG_ID_HIGH) == 0x7F) && + (i2c_r(ov, OV7610_REG_ID_LOW) == 0xA2)) { + success = 1; + break; + } else { + i++; + } + } + +// Was (i == i2c_detect_tries) previously. This obviously used to always report +// success. Whether anyone actually depended on that bug is unknown + if ((i >= i2c_detect_tries) && (success == 0)) { + err("Failed to read sensor ID. You might not have an"); + err("OV7610/20, or it may be not responding. Report"); + err("this to " EMAIL); + err("This is only a warning. You can attempt to use"); + err("your camera anyway"); +// Only issue a warning for now +// return -1; + } else { + PDEBUG(1, "OV7xx0 initialized (method 2, %dx)", i+1); + } + } + + /* Detect sensor (sub)type */ + rc = i2c_r(ov, OV7610_REG_COM_I); + + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } else if ((rc & 3) == 3) { + info("Sensor is an OV7610"); + ov->sensor = SEN_OV7610; + } else if ((rc & 3) == 1) { + /* I don't know what's different about the 76BE yet. */ + if (i2c_r(ov, 0x15) & 1) + info("Sensor is an OV7620AE"); + else + info("Sensor is an OV76BE"); + + /* OV511+ will return all zero isoc data unless we + * configure the sensor as a 7620. Someone needs to + * find the exact reg. setting that causes this. */ + if (ov->bridge == BRG_OV511PLUS) { + info("Enabling 511+/7620AE workaround"); + ov->sensor = SEN_OV7620; + } else { + ov->sensor = SEN_OV76BE; + } + } else if ((rc & 3) == 0) { + info("Sensor is an OV7620"); + ov->sensor = SEN_OV7620; + } else { + err("Unknown image sensor version: %d", rc & 3); + return -1; + } + + if (ov->sensor == SEN_OV7620) { + PDEBUG(4, "Writing 7620 registers"); + if (write_regvals(ov, aRegvalsNorm7620)) + return -1; + } else { + PDEBUG(4, "Writing 7610 registers"); + if (write_regvals(ov, aRegvalsNorm7610)) + return -1; + } + + /* Set sensor-specific vars */ + ov->maxwidth = 640; + ov->maxheight = 480; + ov->minwidth = 64; + ov->minheight = 48; + + // FIXME: These do not match the actual settings yet + ov->brightness = 0x80 << 8; + ov->contrast = 0x80 << 8; + ov->colour = 0x80 << 8; + ov->hue = 0x80 << 8; + + return 0; +} + +/* This initializes the OV6620, OV6630, OV6630AE, or OV6630AF sensor. */ +static int +ov6xx0_configure(struct usb_ov511 *ov) +{ + int rc; + + static struct ov511_regvals aRegvalsNorm6x20[] = { + { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */ + { OV511_I2C_BUS, 0x11, 0x01 }, + { OV511_I2C_BUS, 0x03, 0x60 }, + { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */ + { OV511_I2C_BUS, 0x07, 0xa8 }, + /* The ratio of 0x0c and 0x0d controls the white point */ + { OV511_I2C_BUS, 0x0c, 0x24 }, + { OV511_I2C_BUS, 0x0d, 0x24 }, + { OV511_I2C_BUS, 0x0f, 0x15 }, /* COMS */ + { OV511_I2C_BUS, 0x10, 0x75 }, /* AEC Exposure time */ + { OV511_I2C_BUS, 0x12, 0x24 }, /* Enable AGC */ + { OV511_I2C_BUS, 0x14, 0x04 }, + /* 0x16: 0x06 helps frame stability with moving objects */ + { OV511_I2C_BUS, 0x16, 0x06 }, +// { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */ + { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */ + /* 0x28: 0x05 Selects RGB format if RGB on */ + { OV511_I2C_BUS, 0x28, 0x05 }, + { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */ +// { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */ + { OV511_I2C_BUS, 0x2d, 0x99 }, + { OV511_I2C_BUS, 0x33, 0xa0 }, /* Color Processing Parameter */ + { OV511_I2C_BUS, 0x34, 0xd2 }, /* Max A/D range */ + { OV511_I2C_BUS, 0x38, 0x8b }, + { OV511_I2C_BUS, 0x39, 0x40 }, + + { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */ + { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */ + { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */ + + { OV511_I2C_BUS, 0x3d, 0x80 }, + /* These next two registers (0x4a, 0x4b) are undocumented. They + * control the color balance */ + { OV511_I2C_BUS, 0x4a, 0x80 }, + { OV511_I2C_BUS, 0x4b, 0x80 }, + { OV511_I2C_BUS, 0x4d, 0xd2 }, /* This reduces noise a bit */ + { OV511_I2C_BUS, 0x4e, 0xc1 }, + { OV511_I2C_BUS, 0x4f, 0x04 }, +// Do 50-53 have any effect? +// Toggle 0x12[2] off and on here? + { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */ + }; + + static struct ov511_regvals aRegvalsNorm6x30[] = { + /*OK*/ { OV511_I2C_BUS, 0x12, 0x80 }, /* reset */ + { OV511_I2C_BUS, 0x11, 0x00 }, + /*OK*/ { OV511_I2C_BUS, 0x03, 0x60 }, + /*0A?*/ { OV511_I2C_BUS, 0x05, 0x7f }, /* For when autoadjust is off */ + { OV511_I2C_BUS, 0x07, 0xa8 }, + /* The ratio of 0x0c and 0x0d controls the white point */ + /*OK*/ { OV511_I2C_BUS, 0x0c, 0x24 }, + /*OK*/ { OV511_I2C_BUS, 0x0d, 0x24 }, + /*A*/ { OV511_I2C_BUS, 0x0e, 0x20 }, +// /*04?*/ { OV511_I2C_BUS, 0x14, 0x80 }, + { OV511_I2C_BUS, 0x16, 0x03 }, +// /*OK*/ { OV511_I2C_BUS, 0x20, 0x30 }, /* Aperture correction enable */ + // 21 & 22? The suggested values look wrong. Go with default + /*A*/ { OV511_I2C_BUS, 0x23, 0xc0 }, + /*A*/ { OV511_I2C_BUS, 0x25, 0x9a }, // Check this against default +// /*OK*/ { OV511_I2C_BUS, 0x26, 0xb2 }, /* BLC enable */ + + /* 0x28: 0x05 Selects RGB format if RGB on */ +// /*04?*/ { OV511_I2C_BUS, 0x28, 0x05 }, +// /*04?*/ { OV511_I2C_BUS, 0x28, 0x45 }, // DEBUG: Tristate UV bus + + /*OK*/ { OV511_I2C_BUS, 0x2a, 0x04 }, /* Disable framerate adjust */ +// /*OK*/ { OV511_I2C_BUS, 0x2b, 0xac }, /* Framerate; Set 2a[7] first */ + { OV511_I2C_BUS, 0x2d, 0x99 }, +// /*A*/ { OV511_I2C_BUS, 0x33, 0x26 }, // Reserved bits on 6620 +// /*d2?*/ { OV511_I2C_BUS, 0x34, 0x03 }, /* Max A/D range */ +// /*8b?*/ { OV511_I2C_BUS, 0x38, 0x83 }, +// /*40?*/ { OV511_I2C_BUS, 0x39, 0xc0 }, // 6630 adds bit 7 +// { OV511_I2C_BUS, 0x3c, 0x39 }, /* Enable AEC mode changing */ +// { OV511_I2C_BUS, 0x3c, 0x3c }, /* Change AEC mode */ +// { OV511_I2C_BUS, 0x3c, 0x24 }, /* Disable AEC mode changing */ + { OV511_I2C_BUS, 0x3d, 0x80 }, +// /*A*/ { OV511_I2C_BUS, 0x3f, 0x0e }, + + /* These next two registers (0x4a, 0x4b) are undocumented. They + * control the color balance */ +// /*OK?*/ { OV511_I2C_BUS, 0x4a, 0x80 }, // Check these +// /*OK?*/ { OV511_I2C_BUS, 0x4b, 0x80 }, + { OV511_I2C_BUS, 0x4d, 0x10 }, /* U = 0.563u, V = 0.714v */ + /*c1?*/ { OV511_I2C_BUS, 0x4e, 0x40 }, + + /* UV average mode, color killer: strongest */ + { OV511_I2C_BUS, 0x4f, 0x07 }, + + { OV511_I2C_BUS, 0x54, 0x23 }, /* Max AGC gain: 18dB */ + { OV511_I2C_BUS, 0x57, 0x81 }, /* (default) */ + { OV511_I2C_BUS, 0x59, 0x01 }, /* AGC dark current comp: +1 */ + { OV511_I2C_BUS, 0x5a, 0x2c }, /* (undocumented) */ + { OV511_I2C_BUS, 0x5b, 0x0f }, /* AWB chrominance levels */ +// { OV511_I2C_BUS, 0x5c, 0x10 }, + { OV511_DONE_BUS, 0x0, 0x00 }, /* END MARKER */ + }; + + PDEBUG(4, "starting sensor configuration"); + + if (init_ov_sensor(ov) < 0) { + err("Failed to read sensor ID. You might not have an OV6xx0,"); + err("or it may be not responding. Report this to " EMAIL); + return -1; + } else { + PDEBUG(1, "OV6xx0 sensor detected"); + } + + /* Detect sensor (sub)type */ + rc = i2c_r(ov, OV7610_REG_COM_I); + + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } + + if ((rc & 3) == 0) { + ov->sensor = SEN_OV6630; + info("Sensor is an OV6630"); + } else if ((rc & 3) == 1) { + ov->sensor = SEN_OV6620; + info("Sensor is an OV6620"); + } else if ((rc & 3) == 2) { + ov->sensor = SEN_OV6630; + info("Sensor is an OV6630AE"); + } else if ((rc & 3) == 3) { + ov->sensor = SEN_OV6630; + info("Sensor is an OV6630AF"); + } + + /* Set sensor-specific vars */ + ov->maxwidth = 352; + ov->maxheight = 288; + ov->minwidth = 64; + ov->minheight = 48; + + // FIXME: These do not match the actual settings yet + ov->brightness = 0x80 << 8; + ov->contrast = 0x80 << 8; + ov->colour = 0x80 << 8; + ov->hue = 0x80 << 8; + + if (ov->sensor == SEN_OV6620) { + PDEBUG(4, "Writing 6x20 registers"); + if (write_regvals(ov, aRegvalsNorm6x20)) + return -1; + } else { + PDEBUG(4, "Writing 6x30 registers"); + if (write_regvals(ov, aRegvalsNorm6x30)) + return -1; + } + + return 0; +} + +/* This initializes the KS0127 and KS0127B video decoders. */ +static int +ks0127_configure(struct usb_ov511 *ov) +{ + int rc; + +// FIXME: I don't know how to sync or reset it yet +#if 0 + if (ov51x_init_ks_sensor(ov) < 0) { + err("Failed to initialize the KS0127"); + return -1; + } else { + PDEBUG(1, "KS012x(B) sensor detected"); + } +#endif + + /* Detect decoder subtype */ + rc = i2c_r(ov, 0x00); + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } else if (rc & 0x08) { + rc = i2c_r(ov, 0x3d); + if (rc < 0) { + err("Error detecting sensor type"); + return -1; + } else if ((rc & 0x0f) == 0) { + info("Sensor is a KS0127"); + ov->sensor = SEN_KS0127; + } else if ((rc & 0x0f) == 9) { + info("Sensor is a KS0127B Rev. A"); + ov->sensor = SEN_KS0127B; + } + } else { + err("Error: Sensor is an unsupported KS0122"); + return -1; + } + + /* Set sensor-specific vars */ + ov->maxwidth = 640; + ov->maxheight = 480; + ov->minwidth = 64; + ov->minheight = 48; + + // FIXME: These do not match the actual settings yet + ov->brightness = 0x80 << 8; + ov->contrast = 0x80 << 8; + ov->colour = 0x80 << 8; + ov->hue = 0x80 << 8; + + /* This device is not supported yet. Bail out now... */ + err("This sensor is not supported yet."); + return -1; + + return 0; +} + +/* This initializes the SAA7111A video decoder. */ +static int +saa7111a_configure(struct usb_ov511 *ov) +{ + int rc; + + /* Since there is no register reset command, all registers must be + * written, otherwise gives erratic results */ + static struct ov511_regvals aRegvalsNormSAA7111A[] = { + { OV511_I2C_BUS, 0x06, 0xce }, + { OV511_I2C_BUS, 0x07, 0x00 }, + { OV511_I2C_BUS, 0x10, 0x44 }, /* YUV422, 240/286 lines */ + { OV511_I2C_BUS, 0x0e, 0x01 }, /* NTSC M or PAL BGHI */ + { OV511_I2C_BUS, 0x00, 0x00 }, + { OV511_I2C_BUS, 0x01, 0x00 }, + { OV511_I2C_BUS, 0x03, 0x23 }, + { OV511_I2C_BUS, 0x04, 0x00 }, + { OV511_I2C_BUS, 0x05, 0x00 }, + { OV511_I2C_BUS, 0x08, 0xc8 }, /* Auto field freq */ + { OV511_I2C_BUS, 0x09, 0x01 }, /* Chrom. trap off, APER=0.25 */ + { OV511_I2C_BUS, 0x0a, 0x80 }, /* BRIG=128 */ + { OV511_I2C_BUS, 0x0b, 0x40 }, /* CONT=1.0 */ + { OV511_I2C_BUS, 0x0c, 0x40 }, /* SATN=1.0 */ + { OV511_I2C_BUS, 0x0d, 0x00 }, /* HUE=0 */ + { OV511_I2C_BUS, 0x0f, 0x00 }, + { OV511_I2C_BUS, 0x11, 0x0c }, + { OV511_I2C_BUS, 0x12, 0x00 }, + { OV511_I2C_BUS, 0x13, 0x00 }, + { OV511_I2C_BUS, 0x14, 0x00 }, + { OV511_I2C_BUS, 0x15, 0x00 }, + { OV511_I2C_BUS, 0x16, 0x00 }, + { OV511_I2C_BUS, 0x17, 0x00 }, + { OV511_I2C_BUS, 0x02, 0xc0 }, /* Composite input 0 */ + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + +// FIXME: I don't know how to sync or reset it yet +#if 0 + if (ov51x_init_saa_sensor(ov) < 0) { + err("Failed to initialize the SAA7111A"); + return -1; + } else { + PDEBUG(1, "SAA7111A sensor detected"); + } +#endif + + /* 640x480 not supported with PAL */ + if (ov->pal) { + ov->maxwidth = 320; + ov->maxheight = 240; /* Even field only */ + } else { + ov->maxwidth = 640; + ov->maxheight = 480; /* Even/Odd fields */ + } + + ov->minwidth = 320; + ov->minheight = 240; /* Even field only */ + + ov->has_decoder = 1; + ov->num_inputs = 8; + ov->norm = VIDEO_MODE_AUTO; + ov->stop_during_set = 0; /* Decoder guarantees stable image */ + + /* Decoder doesn't change these values, so we use these instead of + * acutally reading the registers (which doesn't work) */ + ov->brightness = 0x80 << 8; + ov->contrast = 0x40 << 9; + ov->colour = 0x40 << 9; + ov->hue = 32768; + + PDEBUG(4, "Writing SAA7111A registers"); + if (write_regvals(ov, aRegvalsNormSAA7111A)) + return -1; + + /* Detect version of decoder. This must be done after writing the + * initial regs or the decoder will lock up. */ + rc = i2c_r(ov, 0x00); + + if (rc < 0) { + err("Error detecting sensor version"); + return -1; + } else { + info("Sensor is an SAA7111A (version 0x%x)", rc); + ov->sensor = SEN_SAA7111A; + } + + // FIXME: Fix this for OV518(+) + /* Latch to negative edge of clock. Otherwise, we get incorrect + * colors and jitter in the digital signal. */ + if (ov->bclass == BCL_OV511) + reg_w(ov, 0x11, 0x00); + else + warn("SAA7111A not yet supported with OV518/OV518+"); + + return 0; +} + +/* This initializes the OV511/OV511+ and the sensor */ +static int +ov511_configure(struct usb_ov511 *ov) +{ + static struct ov511_regvals aRegvalsInit511[] = { + { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, + { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x7f }, + { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x3f }, + { OV511_REG_BUS, R51x_SYS_INIT, 0x01 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x3d }, + { OV511_DONE_BUS, 0x0, 0x00}, + }; + + static struct ov511_regvals aRegvalsNorm511[] = { + { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0x01 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R511_FIFO_OPTS, 0x1f }, + { OV511_REG_BUS, R511_COMP_EN, 0x00 }, + { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + static struct ov511_regvals aRegvalsNorm511Plus[] = { + { OV511_REG_BUS, R511_DRAM_FLOW_CTL, 0xff }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, + { OV511_REG_BUS, R51x_SYS_SNAP, 0x00 }, + { OV511_REG_BUS, R511_FIFO_OPTS, 0xff }, + { OV511_REG_BUS, R511_COMP_EN, 0x00 }, + { OV511_REG_BUS, R511_COMP_LUT_EN, 0x03 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + PDEBUG(4, ""); + + ov->customid = reg_r(ov, R511_SYS_CUST_ID); + if (ov->customid < 0) { + err("Unable to read camera bridge registers"); + goto error; + } + + PDEBUG (1, "CustomID = %d", ov->customid); + ov->desc = symbolic(camlist, ov->customid); + info("model: %s", ov->desc); + + if (0 == strcmp(ov->desc, NOT_DEFINED_STR)) { + err("Camera type (%d) not recognized", ov->customid); + err("Please notify " EMAIL " of the name,"); + err("manufacturer, model, and this number of your camera."); + err("Also include the output of the detection process."); + } + + if (ov->customid == 70) /* USB Life TV (PAL/SECAM) */ + ov->pal = 1; + + if (write_regvals(ov, aRegvalsInit511)) + goto error; + + if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 0); + + /* The OV511+ has undocumented bits in the flow control register. + * Setting it to 0xff fixes the corruption with moving objects. */ + if (ov->bridge == BRG_OV511) { + if (write_regvals(ov, aRegvalsNorm511)) + goto error; + } else if (ov->bridge == BRG_OV511PLUS) { + if (write_regvals(ov, aRegvalsNorm511Plus)) + goto error; + } else { + err("Invalid bridge"); + } + + if (ov511_init_compression(ov)) + goto error; + + ov->packet_numbering = 1; + ov511_set_packet_size(ov, 0); + + ov->snap_enabled = snapshot; + + /* Test for 7xx0 */ + PDEBUG(3, "Testing for 0V7xx0"); + ov->primary_i2c_slave = OV7xx0_SID; + if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) + goto error; + + if (i2c_w(ov, 0x12, 0x80) < 0) { + /* Test for 6xx0 */ + PDEBUG(3, "Testing for 0V6xx0"); + ov->primary_i2c_slave = OV6xx0_SID; + if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0) + goto error; + + if (i2c_w(ov, 0x12, 0x80) < 0) { + /* Test for 8xx0 */ + PDEBUG(3, "Testing for 0V8xx0"); + ov->primary_i2c_slave = OV8xx0_SID; + if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0) + goto error; + + if (i2c_w(ov, 0x12, 0x80) < 0) { + /* Test for SAA7111A */ + PDEBUG(3, "Testing for SAA7111A"); + ov->primary_i2c_slave = SAA7111A_SID; + if (ov51x_set_slave_ids(ov, SAA7111A_SID) < 0) + goto error; + + if (i2c_w(ov, 0x0d, 0x00) < 0) { + /* Test for KS0127 */ + PDEBUG(3, "Testing for KS0127"); + ov->primary_i2c_slave = KS0127_SID; + if (ov51x_set_slave_ids(ov, KS0127_SID) < 0) + goto error; + + if (i2c_w(ov, 0x10, 0x00) < 0) { + err("Can't determine sensor slave IDs"); + goto error; + } else { + if (ks0127_configure(ov) < 0) { + err("Failed to configure KS0127"); + goto error; + } + } + } else { + if (saa7111a_configure(ov) < 0) { + err("Failed to configure SAA7111A"); + goto error; + } + } + } else { + err("Detected unsupported OV8xx0 sensor"); + goto error; + } + } else { + if (ov6xx0_configure(ov) < 0) { + err("Failed to configure OV6xx0"); + goto error; + } + } + } else { + if (ov7xx0_configure(ov) < 0) { + err("Failed to configure OV7xx0"); + goto error; + } + } + + return 0; + +error: + err("OV511 Config failed"); + + return -EBUSY; +} + +/* This initializes the OV518/OV518+ and the sensor */ +static int +ov518_configure(struct usb_ov511 *ov) +{ + /* For 518 and 518+ */ + static struct ov511_regvals aRegvalsInit518[] = { + { OV511_REG_BUS, R51x_SYS_RESET, 0x40 }, + { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x3e }, + { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, + { OV511_REG_BUS, R51x_SYS_RESET, 0x00 }, + { OV511_REG_BUS, R51x_SYS_INIT, 0xe1 }, + { OV511_REG_BUS, 0x46, 0x00 }, + { OV511_REG_BUS, 0x5d, 0x03 }, + { OV511_DONE_BUS, 0x0, 0x00}, + }; + + static struct ov511_regvals aRegvalsNorm518[] = { + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ + { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ + { OV511_REG_BUS, 0x31, 0x0f }, + { OV511_REG_BUS, 0x5d, 0x03 }, + { OV511_REG_BUS, 0x24, 0x9f }, + { OV511_REG_BUS, 0x25, 0x90 }, + { OV511_REG_BUS, 0x20, 0x00 }, + { OV511_REG_BUS, 0x51, 0x04 }, + { OV511_REG_BUS, 0x71, 0x19 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + static struct ov511_regvals aRegvalsNorm518Plus[] = { + { OV511_REG_BUS, R51x_SYS_SNAP, 0x02 }, /* Reset */ + { OV511_REG_BUS, R51x_SYS_SNAP, 0x01 }, /* Enable */ + { OV511_REG_BUS, 0x31, 0x0f }, + { OV511_REG_BUS, 0x5d, 0x03 }, + { OV511_REG_BUS, 0x24, 0x9f }, + { OV511_REG_BUS, 0x25, 0x90 }, + { OV511_REG_BUS, 0x20, 0x60 }, + { OV511_REG_BUS, 0x51, 0x02 }, + { OV511_REG_BUS, 0x71, 0x19 }, + { OV511_REG_BUS, 0x40, 0xff }, + { OV511_REG_BUS, 0x41, 0x42 }, + { OV511_REG_BUS, 0x46, 0x00 }, + { OV511_REG_BUS, 0x33, 0x04 }, + { OV511_REG_BUS, 0x21, 0x19 }, + { OV511_REG_BUS, 0x3f, 0x10 }, + { OV511_DONE_BUS, 0x0, 0x00 }, + }; + + PDEBUG(4, ""); + + /* First 5 bits of custom ID reg are a revision ID on OV518 */ + info("Device revision %d", 0x1F & reg_r(ov, R511_SYS_CUST_ID)); + + /* Give it the default description */ + ov->desc = symbolic(camlist, 0); + + if (write_regvals(ov, aRegvalsInit518)) + goto error; + + /* Set LED GPIO pin to output mode */ + if (reg_w_mask(ov, 0x57, 0x00, 0x02) < 0) + goto error; + + /* LED is off by default with OV518; have to explicitly turn it on */ + if (ov->led_policy == LED_OFF || ov->led_policy == LED_AUTO) + ov51x_led_control(ov, 0); + else + ov51x_led_control(ov, 1); + + /* Don't require compression if dumppix is enabled; otherwise it's + * required. OV518 has no uncompressed mode, to save RAM. */ + if (!dumppix && !ov->compress) { + ov->compress = 1; + warn("Compression required with OV518...enabling"); + } + + if (ov->bridge == BRG_OV518) { + if (write_regvals(ov, aRegvalsNorm518)) + goto error; + } else if (ov->bridge == BRG_OV518PLUS) { + if (write_regvals(ov, aRegvalsNorm518Plus)) + goto error; + } else { + err("Invalid bridge"); + } + + if (reg_w(ov, 0x2f, 0x80) < 0) + goto error; + + if (ov518_init_compression(ov)) + goto error; + + if (ov->bridge == BRG_OV518) + { + struct usb_interface *ifp; + struct usb_host_interface *alt; + __u16 mxps = 0; + + ifp = usb_ifnum_to_if(ov->dev, 0); + if (ifp) { + alt = usb_altnum_to_altsetting(ifp, 7); + if (alt) + mxps = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize); + } + + /* Some OV518s have packet numbering by default, some don't */ + if (mxps == 897) + ov->packet_numbering = 1; + else + ov->packet_numbering = 0; + } else { + /* OV518+ has packet numbering turned on by default */ + ov->packet_numbering = 1; + } + + ov518_set_packet_size(ov, 0); + + ov->snap_enabled = snapshot; + + /* Test for 76xx */ + ov->primary_i2c_slave = OV7xx0_SID; + if (ov51x_set_slave_ids(ov, OV7xx0_SID) < 0) + goto error; + + /* The OV518 must be more aggressive about sensor detection since + * I2C write will never fail if the sensor is not present. We have + * to try to initialize the sensor to detect its presence */ + + if (init_ov_sensor(ov) < 0) { + /* Test for 6xx0 */ + ov->primary_i2c_slave = OV6xx0_SID; + if (ov51x_set_slave_ids(ov, OV6xx0_SID) < 0) + goto error; + + if (init_ov_sensor(ov) < 0) { + /* Test for 8xx0 */ + ov->primary_i2c_slave = OV8xx0_SID; + if (ov51x_set_slave_ids(ov, OV8xx0_SID) < 0) + goto error; + + if (init_ov_sensor(ov) < 0) { + err("Can't determine sensor slave IDs"); + goto error; + } else { + err("Detected unsupported OV8xx0 sensor"); + goto error; + } + } else { + if (ov6xx0_configure(ov) < 0) { + err("Failed to configure OV6xx0"); + goto error; + } + } + } else { + if (ov7xx0_configure(ov) < 0) { + err("Failed to configure OV7xx0"); + goto error; + } + } + + ov->maxwidth = 352; + ov->maxheight = 288; + + // The OV518 cannot go as low as the sensor can + ov->minwidth = 160; + ov->minheight = 120; + + return 0; + +error: + err("OV518 Config failed"); + + return -EBUSY; +} + +/**************************************************************************** + * sysfs + ***************************************************************************/ + +static inline struct usb_ov511 *cd_to_ov(struct device *cd) +{ + struct video_device *vdev = to_video_device(cd); + return video_get_drvdata(vdev); +} + +static ssize_t show_custom_id(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%d\n", ov->customid); +} +static DEVICE_ATTR(custom_id, S_IRUGO, show_custom_id, NULL); + +static ssize_t show_model(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", ov->desc); +} +static DEVICE_ATTR(model, S_IRUGO, show_model, NULL); + +static ssize_t show_bridge(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", symbolic(brglist, ov->bridge)); +} +static DEVICE_ATTR(bridge, S_IRUGO, show_bridge, NULL); + +static ssize_t show_sensor(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + return sprintf(buf, "%s\n", symbolic(senlist, ov->sensor)); +} +static DEVICE_ATTR(sensor, S_IRUGO, show_sensor, NULL); + +static ssize_t show_brightness(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_brightness(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL); + +static ssize_t show_saturation(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_saturation(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL); + +static ssize_t show_contrast(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_contrast(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL); + +static ssize_t show_hue(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned short x; + + if (!ov->dev) + return -ENODEV; + sensor_get_hue(ov, &x); + return sprintf(buf, "%d\n", x >> 8); +} +static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL); + +static ssize_t show_exposure(struct device *cd, struct device_attribute *attr, char *buf) +{ + struct usb_ov511 *ov = cd_to_ov(cd); + unsigned char exp = 0; + + if (!ov->dev) + return -ENODEV; + sensor_get_exposure(ov, &exp); + return sprintf(buf, "%d\n", exp >> 8); +} +static DEVICE_ATTR(exposure, S_IRUGO, show_exposure, NULL); + +static void ov_create_sysfs(struct device *dev) +{ + device_create_file(dev, &dev_attr_custom_id); + device_create_file(dev, &dev_attr_model); + device_create_file(dev, &dev_attr_bridge); + device_create_file(dev, &dev_attr_sensor); + device_create_file(dev, &dev_attr_brightness); + device_create_file(dev, &dev_attr_saturation); + device_create_file(dev, &dev_attr_contrast); + device_create_file(dev, &dev_attr_hue); + device_create_file(dev, &dev_attr_exposure); +} + +/**************************************************************************** + * USB routines + ***************************************************************************/ + +static int +ov51x_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct usb_interface_descriptor *idesc; + struct usb_ov511 *ov; + int i; + + PDEBUG(1, "probing for device..."); + + /* We don't handle multi-config cameras */ + if (dev->descriptor.bNumConfigurations != 1) + return -ENODEV; + + idesc = &intf->cur_altsetting->desc; + + if (idesc->bInterfaceClass != 0xFF) + return -ENODEV; + if (idesc->bInterfaceSubClass != 0x00) + return -ENODEV; + + if ((ov = kmalloc(sizeof(*ov), GFP_KERNEL)) == NULL) { + err("couldn't kmalloc ov struct"); + goto error_out; + } + + memset(ov, 0, sizeof(*ov)); + + ov->dev = dev; + ov->iface = idesc->bInterfaceNumber; + ov->led_policy = led; + ov->compress = compress; + ov->lightfreq = lightfreq; + ov->num_inputs = 1; /* Video decoder init functs. change this */ + ov->stop_during_set = !fastset; + ov->backlight = backlight; + ov->mirror = mirror; + ov->auto_brt = autobright; + ov->auto_gain = autogain; + ov->auto_exp = autoexp; + + switch (le16_to_cpu(dev->descriptor.idProduct)) { + case PROD_OV511: + ov->bridge = BRG_OV511; + ov->bclass = BCL_OV511; + break; + case PROD_OV511PLUS: + ov->bridge = BRG_OV511PLUS; + ov->bclass = BCL_OV511; + break; + case PROD_OV518: + ov->bridge = BRG_OV518; + ov->bclass = BCL_OV518; + break; + case PROD_OV518PLUS: + ov->bridge = BRG_OV518PLUS; + ov->bclass = BCL_OV518; + break; + case PROD_ME2CAM: + if (le16_to_cpu(dev->descriptor.idVendor) != VEND_MATTEL) + goto error; + ov->bridge = BRG_OV511PLUS; + ov->bclass = BCL_OV511; + break; + default: + err("Unknown product ID 0x%04x", le16_to_cpu(dev->descriptor.idProduct)); + goto error; + } + + info("USB %s video device found", symbolic(brglist, ov->bridge)); + + init_waitqueue_head(&ov->wq); + + init_MUTEX(&ov->lock); /* to 1 == available */ + init_MUTEX(&ov->buf_lock); + init_MUTEX(&ov->param_lock); + init_MUTEX(&ov->i2c_lock); + init_MUTEX(&ov->cbuf_lock); + + ov->buf_state = BUF_NOT_ALLOCATED; + + if (usb_make_path(dev, ov->usb_path, OV511_USB_PATH_LEN) < 0) { + err("usb_make_path error"); + goto error; + } + + /* Allocate control transfer buffer. */ + /* Must be kmalloc()'ed, for DMA compatibility */ + ov->cbuf = kmalloc(OV511_CBUF_SIZE, GFP_KERNEL); + if (!ov->cbuf) + goto error; + + if (ov->bclass == BCL_OV518) { + if (ov518_configure(ov) < 0) + goto error; + } else { + if (ov511_configure(ov) < 0) + goto error; + } + + for (i = 0; i < OV511_NUMFRAMES; i++) { + ov->frame[i].framenum = i; + init_waitqueue_head(&ov->frame[i].wq); + } + + for (i = 0; i < OV511_NUMSBUF; i++) { + ov->sbuf[i].ov = ov; + spin_lock_init(&ov->sbuf[i].lock); + ov->sbuf[i].n = i; + } + + /* Unnecessary? (This is done on open(). Need to make sure variables + * are properly initialized without this before removing it, though). */ + if (ov51x_set_default_params(ov) < 0) + goto error; + +#ifdef OV511_DEBUG + if (dump_bridge) { + if (ov->bclass == BCL_OV511) + ov511_dump_regs(ov); + else + ov518_dump_regs(ov); + } +#endif + + ov->vdev = video_device_alloc(); + if (!ov->vdev) + goto error; + + memcpy(ov->vdev, &vdev_template, sizeof(*ov->vdev)); +// ov->vdev->dev = &dev->dev; + video_set_drvdata(ov->vdev, ov); + + for (i = 0; i < OV511_MAX_UNIT_VIDEO; i++) { + /* Minor 0 cannot be specified; assume user wants autodetect */ + if (unit_video[i] == 0) + break; + + if (video_register_device(ov->vdev, VFL_TYPE_GRABBER, + unit_video[i]) >= 0) { + break; + } + } + + /* Use the next available one */ + if ((ov->vdev->minor == -1) && + video_register_device(ov->vdev, VFL_TYPE_GRABBER, -1) < 0) { + err("video_register_device failed"); + goto error; + } + + info("Device at %s registered to minor %d", ov->usb_path, + ov->vdev->minor); + + usb_set_intfdata(intf, ov); + ov_create_sysfs(&ov->dev->dev); + return 0; + +error: + if (ov->vdev) { + if (-1 == ov->vdev->minor) + video_device_release(ov->vdev); + else + video_unregister_device(ov->vdev); + ov->vdev = NULL; + } + + if (ov->cbuf) { + down(&ov->cbuf_lock); + kfree(ov->cbuf); + ov->cbuf = NULL; + up(&ov->cbuf_lock); + } + + kfree(ov); + ov = NULL; + +error_out: + err("Camera initialization failed"); + return -EIO; +} + +static void +ov51x_disconnect(struct usb_interface *intf) +{ + struct usb_ov511 *ov = usb_get_intfdata(intf); + int n; + + PDEBUG(3, ""); + + usb_set_intfdata (intf, NULL); + + if (!ov) + return; + + if (ov->vdev) + video_unregister_device(ov->vdev); + + for (n = 0; n < OV511_NUMFRAMES; n++) + ov->frame[n].grabstate = FRAME_ERROR; + + ov->curframe = -1; + + /* This will cause the process to request another frame */ + for (n = 0; n < OV511_NUMFRAMES; n++) + wake_up_interruptible(&ov->frame[n].wq); + + wake_up_interruptible(&ov->wq); + + ov->streaming = 0; + ov51x_unlink_isoc(ov); + + ov->dev = NULL; + + /* Free the memory */ + if (ov && !ov->user) { + down(&ov->cbuf_lock); + kfree(ov->cbuf); + ov->cbuf = NULL; + up(&ov->cbuf_lock); + + ov51x_dealloc(ov); + kfree(ov); + ov = NULL; + } + + PDEBUG(3, "Disconnect complete"); +} + +static struct usb_driver ov511_driver = { + .name = "ov511", + .id_table = device_table, + .probe = ov51x_probe, + .disconnect = ov51x_disconnect +}; + +/**************************************************************************** + * + * Module routines + * + ***************************************************************************/ + +/* Returns 0 for success */ +int +ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, int ov518, + int mmx) +{ + if (ver != DECOMP_INTERFACE_VER) { + err("Decompression module has incompatible"); + err("interface version %d", ver); + err("Interface version %d is required", DECOMP_INTERFACE_VER); + return -EINVAL; + } + + if (!ops) + return -EFAULT; + + if (mmx && !ov51x_mmx_available) { + err("MMX not available on this system or kernel"); + return -EINVAL; + } + + lock_kernel(); + + if (ov518) { + if (mmx) { + if (ov518_mmx_decomp_ops) + goto err_in_use; + else + ov518_mmx_decomp_ops = ops; + } else { + if (ov518_decomp_ops) + goto err_in_use; + else + ov518_decomp_ops = ops; + } + } else { + if (mmx) { + if (ov511_mmx_decomp_ops) + goto err_in_use; + else + ov511_mmx_decomp_ops = ops; + } else { + if (ov511_decomp_ops) + goto err_in_use; + else + ov511_decomp_ops = ops; + } + } + + unlock_kernel(); + return 0; + +err_in_use: + unlock_kernel(); + return -EBUSY; +} + +void +ov511_deregister_decomp_module(int ov518, int mmx) +{ + lock_kernel(); + + if (ov518) { + if (mmx) + ov518_mmx_decomp_ops = NULL; + else + ov518_decomp_ops = NULL; + } else { + if (mmx) + ov511_mmx_decomp_ops = NULL; + else + ov511_decomp_ops = NULL; + } + + unlock_kernel(); +} + +static int __init +usb_ov511_init(void) +{ + int retval; + + retval = usb_register(&ov511_driver); + if (retval) + goto out; + + info(DRIVER_VERSION " : " DRIVER_DESC); + +out: + return retval; +} + +static void __exit +usb_ov511_exit(void) +{ + usb_deregister(&ov511_driver); + info("driver deregistered"); + +} + +module_init(usb_ov511_init); +module_exit(usb_ov511_exit); + +EXPORT_SYMBOL(ov511_register_decomp_module); +EXPORT_SYMBOL(ov511_deregister_decomp_module); --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov511.h +++ linux-2.6.28/ubuntu/misc/media/ov511/ov511.h @@ -0,0 +1,570 @@ +#ifndef __LINUX_OV511_H +#define __LINUX_OV511_H + +#include +#include +#include +#include +#include + +#define OV511_DEBUG /* Turn on debug messages */ + +#ifdef OV511_DEBUG + #define PDEBUG(level, fmt, args...) \ + if (debug >= (level)) info("[%s:%d] " fmt, \ + __FUNCTION__, __LINE__ , ## args) +#else + #define PDEBUG(level, fmt, args...) do {} while(0) +#endif + +/* This macro restricts an int variable to an inclusive range */ +#define RESTRICT_TO_RANGE(v,mi,ma) { \ + if ((v) < (mi)) (v) = (mi); \ + else if ((v) > (ma)) (v) = (ma); \ +} + +/* --------------------------------- */ +/* DEFINES FOR OV511 AND OTHER CHIPS */ +/* --------------------------------- */ + +/* USB IDs */ +#define VEND_OMNIVISION 0x05A9 +#define PROD_OV511 0x0511 +#define PROD_OV511PLUS 0xA511 +#define PROD_OV518 0x0518 +#define PROD_OV518PLUS 0xA518 + +#define VEND_MATTEL 0x0813 +#define PROD_ME2CAM 0x0002 + +/* --------------------------------- */ +/* OV51x REGISTER MNEMONICS */ +/* --------------------------------- */ + +/* Camera interface register numbers */ +#define R511_CAM_DELAY 0x10 +#define R511_CAM_EDGE 0x11 +#define R511_CAM_PXCNT 0x12 +#define R511_CAM_LNCNT 0x13 +#define R511_CAM_PXDIV 0x14 +#define R511_CAM_LNDIV 0x15 +#define R511_CAM_UV_EN 0x16 +#define R511_CAM_LINE_MODE 0x17 +#define R511_CAM_OPTS 0x18 + +/* Snapshot mode camera interface register numbers */ +#define R511_SNAP_FRAME 0x19 +#define R511_SNAP_PXCNT 0x1A +#define R511_SNAP_LNCNT 0x1B +#define R511_SNAP_PXDIV 0x1C +#define R511_SNAP_LNDIV 0x1D +#define R511_SNAP_UV_EN 0x1E +#define R511_SNAP_OPTS 0x1F + +/* DRAM register numbers */ +#define R511_DRAM_FLOW_CTL 0x20 +#define R511_DRAM_ARCP 0x21 +#define R511_DRAM_MRC 0x22 +#define R511_DRAM_RFC 0x23 + +/* ISO FIFO register numbers */ +#define R51x_FIFO_PSIZE 0x30 /* 2 bytes wide w/ OV518(+) */ +#define R511_FIFO_OPTS 0x31 + +/* Parallel IO register numbers */ +#define R511_PIO_OPTS 0x38 +#define R511_PIO_DATA 0x39 +#define R511_PIO_BIST 0x3E +#define R518_GPIO_IN 0x55 /* OV518(+) only */ +#define R518_GPIO_OUT 0x56 /* OV518(+) only */ +#define R518_GPIO_CTL 0x57 /* OV518(+) only */ +#define R518_GPIO_PULSE_IN 0x58 /* OV518(+) only */ +#define R518_GPIO_PULSE_CLEAR 0x59 /* OV518(+) only */ +#define R518_GPIO_PULSE_POL 0x5a /* OV518(+) only */ +#define R518_GPIO_PULSE_EN 0x5b /* OV518(+) only */ +#define R518_GPIO_RESET 0x5c /* OV518(+) only */ + +/* I2C registers */ +#define R511_I2C_CTL 0x40 +#define R518_I2C_CTL 0x47 /* OV518(+) only */ +#define R51x_I2C_W_SID 0x41 +#define R51x_I2C_SADDR_3 0x42 +#define R51x_I2C_SADDR_2 0x43 +#define R51x_I2C_R_SID 0x44 +#define R51x_I2C_DATA 0x45 +#define R51x_I2C_CLOCK 0x46 +#define R51x_I2C_TIMEOUT 0x47 + +/* I2C snapshot registers */ +#define R511_SI2C_SADDR_3 0x48 +#define R511_SI2C_DATA 0x49 + +/* System control registers */ +#define R51x_SYS_RESET 0x50 + /* Reset type definitions */ +#define OV511_RESET_UDC 0x01 +#define OV511_RESET_I2C 0x02 +#define OV511_RESET_FIFO 0x04 +#define OV511_RESET_OMNICE 0x08 +#define OV511_RESET_DRAM 0x10 +#define OV511_RESET_CAM_INT 0x20 +#define OV511_RESET_OV511 0x40 +#define OV511_RESET_NOREGS 0x3F /* All but OV511 & regs */ +#define OV511_RESET_ALL 0x7F + +#define R511_SYS_CLOCK_DIV 0x51 +#define R51x_SYS_SNAP 0x52 +#define R51x_SYS_INIT 0x53 +#define R511_SYS_PWR_CLK 0x54 /* OV511+/OV518(+) only */ +#define R511_SYS_LED_CTL 0x55 /* OV511+ only */ +#define R511_SYS_USER 0x5E +#define R511_SYS_CUST_ID 0x5F + +/* OmniCE (compression) registers */ +#define R511_COMP_PHY 0x70 +#define R511_COMP_PHUV 0x71 +#define R511_COMP_PVY 0x72 +#define R511_COMP_PVUV 0x73 +#define R511_COMP_QHY 0x74 +#define R511_COMP_QHUV 0x75 +#define R511_COMP_QVY 0x76 +#define R511_COMP_QVUV 0x77 +#define R511_COMP_EN 0x78 +#define R511_COMP_LUT_EN 0x79 +#define R511_COMP_LUT_BEGIN 0x80 + +/* --------------------------------- */ +/* ALTERNATE NUMBERS */ +/* --------------------------------- */ + +/* Alternate numbers for various max packet sizes (OV511 only) */ +#define OV511_ALT_SIZE_992 0 +#define OV511_ALT_SIZE_993 1 +#define OV511_ALT_SIZE_768 2 +#define OV511_ALT_SIZE_769 3 +#define OV511_ALT_SIZE_512 4 +#define OV511_ALT_SIZE_513 5 +#define OV511_ALT_SIZE_257 6 +#define OV511_ALT_SIZE_0 7 + +/* Alternate numbers for various max packet sizes (OV511+ only) */ +#define OV511PLUS_ALT_SIZE_0 0 +#define OV511PLUS_ALT_SIZE_33 1 +#define OV511PLUS_ALT_SIZE_129 2 +#define OV511PLUS_ALT_SIZE_257 3 +#define OV511PLUS_ALT_SIZE_385 4 +#define OV511PLUS_ALT_SIZE_513 5 +#define OV511PLUS_ALT_SIZE_769 6 +#define OV511PLUS_ALT_SIZE_961 7 + +/* Alternate numbers for various max packet sizes (OV518(+) only) */ +#define OV518_ALT_SIZE_0 0 +#define OV518_ALT_SIZE_128 1 +#define OV518_ALT_SIZE_256 2 +#define OV518_ALT_SIZE_384 3 +#define OV518_ALT_SIZE_512 4 +#define OV518_ALT_SIZE_640 5 +#define OV518_ALT_SIZE_768 6 +#define OV518_ALT_SIZE_896 7 + +/* --------------------------------- */ +/* OV7610 REGISTER MNEMONICS */ +/* --------------------------------- */ + +/* OV7610 registers */ +#define OV7610_REG_GAIN 0x00 /* gain setting (5:0) */ +#define OV7610_REG_BLUE 0x01 /* blue channel balance */ +#define OV7610_REG_RED 0x02 /* red channel balance */ +#define OV7610_REG_SAT 0x03 /* saturation */ + /* 04 reserved */ +#define OV7610_REG_CNT 0x05 /* Y contrast */ +#define OV7610_REG_BRT 0x06 /* Y brightness */ + /* 08-0b reserved */ +#define OV7610_REG_BLUE_BIAS 0x0C /* blue channel bias (5:0) */ +#define OV7610_REG_RED_BIAS 0x0D /* read channel bias (5:0) */ +#define OV7610_REG_GAMMA_COEFF 0x0E /* gamma settings */ +#define OV7610_REG_WB_RANGE 0x0F /* AEC/ALC/S-AWB settings */ +#define OV7610_REG_EXP 0x10 /* manual exposure setting */ +#define OV7610_REG_CLOCK 0x11 /* polarity/clock prescaler */ +#define OV7610_REG_COM_A 0x12 /* misc common regs */ +#define OV7610_REG_COM_B 0x13 /* misc common regs */ +#define OV7610_REG_COM_C 0x14 /* misc common regs */ +#define OV7610_REG_COM_D 0x15 /* misc common regs */ +#define OV7610_REG_FIELD_DIVIDE 0x16 /* field interval/mode settings */ +#define OV7610_REG_HWIN_START 0x17 /* horizontal window start */ +#define OV7610_REG_HWIN_END 0x18 /* horizontal window end */ +#define OV7610_REG_VWIN_START 0x19 /* vertical window start */ +#define OV7610_REG_VWIN_END 0x1A /* vertical window end */ +#define OV7610_REG_PIXEL_SHIFT 0x1B /* pixel shift */ +#define OV7610_REG_ID_HIGH 0x1C /* manufacturer ID MSB */ +#define OV7610_REG_ID_LOW 0x1D /* manufacturer ID LSB */ + /* 0e-0f reserved */ +#define OV7610_REG_COM_E 0x20 /* misc common regs */ +#define OV7610_REG_YOFFSET 0x21 /* Y channel offset */ +#define OV7610_REG_UOFFSET 0x22 /* U channel offset */ + /* 23 reserved */ +#define OV7610_REG_ECW 0x24 /* Exposure white level for AEC */ +#define OV7610_REG_ECB 0x25 /* Exposure black level for AEC */ +#define OV7610_REG_COM_F 0x26 /* misc settings */ +#define OV7610_REG_COM_G 0x27 /* misc settings */ +#define OV7610_REG_COM_H 0x28 /* misc settings */ +#define OV7610_REG_COM_I 0x29 /* misc settings */ +#define OV7610_REG_FRAMERATE_H 0x2A /* frame rate MSB + misc */ +#define OV7610_REG_FRAMERATE_L 0x2B /* frame rate LSB */ +#define OV7610_REG_ALC 0x2C /* Auto Level Control settings */ +#define OV7610_REG_COM_J 0x2D /* misc settings */ +#define OV7610_REG_VOFFSET 0x2E /* V channel offset adjustment */ +#define OV7610_REG_ARRAY_BIAS 0x2F /* Array bias -- don't change */ + /* 30-32 reserved */ +#define OV7610_REG_YGAMMA 0x33 /* misc gamma settings (7:6) */ +#define OV7610_REG_BIAS_ADJUST 0x34 /* misc bias settings */ +#define OV7610_REG_COM_L 0x35 /* misc settings */ + /* 36-37 reserved */ +#define OV7610_REG_COM_K 0x38 /* misc registers */ + +/* --------------------------------- */ +/* I2C ADDRESSES */ +/* --------------------------------- */ + +#define OV7xx0_SID 0x42 +#define OV6xx0_SID 0xC0 +#define OV8xx0_SID 0xA0 +#define KS0127_SID 0xD8 +#define SAA7111A_SID 0x48 + +/* --------------------------------- */ +/* MISCELLANEOUS DEFINES */ +/* --------------------------------- */ + +#define I2C_CLOCK_PRESCALER 0x03 + +#define FRAMES_PER_DESC 10 /* FIXME - What should this be? */ +#define MAX_FRAME_SIZE_PER_DESC 993 /* For statically allocated stuff */ +#define PIXELS_PER_SEG 256 /* Pixels per segment */ + +#define OV511_ENDPOINT_ADDRESS 1 /* Isoc endpoint number */ + +#define OV511_NUMFRAMES 2 +#if OV511_NUMFRAMES > VIDEO_MAX_FRAME + #error "OV511_NUMFRAMES is too high" +#endif + +#define OV511_NUMSBUF 2 + +/* Control transfers use up to 4 bytes */ +#define OV511_CBUF_SIZE 4 + +/* Size of usb_make_path() buffer */ +#define OV511_USB_PATH_LEN 64 + +/* Bridge types */ +enum { + BRG_UNKNOWN, + BRG_OV511, + BRG_OV511PLUS, + BRG_OV518, + BRG_OV518PLUS, +}; + +/* Bridge classes */ +enum { + BCL_UNKNOWN, + BCL_OV511, + BCL_OV518, +}; + +/* Sensor types */ +enum { + SEN_UNKNOWN, + SEN_OV76BE, + SEN_OV7610, + SEN_OV7620, + SEN_OV7620AE, + SEN_OV6620, + SEN_OV6630, + SEN_OV6630AE, + SEN_OV6630AF, + SEN_OV8600, + SEN_KS0127, + SEN_KS0127B, + SEN_SAA7111A, +}; + +enum { + STATE_SCANNING, /* Scanning for start */ + STATE_HEADER, /* Parsing header */ + STATE_LINES, /* Parsing lines */ +}; + +/* Buffer states */ +enum { + BUF_NOT_ALLOCATED, + BUF_ALLOCATED, +}; + +/* --------- Definition of ioctl interface --------- */ + +#define OV511_INTERFACE_VER 101 + +/* LED options */ +enum { + LED_OFF, + LED_ON, + LED_AUTO, +}; + +/* Raw frame formats */ +enum { + RAWFMT_INVALID, + RAWFMT_YUV400, + RAWFMT_YUV420, + RAWFMT_YUV422, + RAWFMT_GBR422, +}; + +struct ov511_i2c_struct { + unsigned char slave; /* Write slave ID (read ID - 1) */ + unsigned char reg; /* Index of register */ + unsigned char value; /* User sets this w/ write, driver does w/ read */ + unsigned char mask; /* Bits to be changed. Not used with read ops */ +}; + +/* ioctls */ +#define OV511IOC_WI2C _IOW('v', BASE_VIDIOCPRIVATE + 5, \ + struct ov511_i2c_struct) +#define OV511IOC_RI2C _IOWR('v', BASE_VIDIOCPRIVATE + 6, \ + struct ov511_i2c_struct) +/* ------------- End IOCTL interface -------------- */ + +struct usb_ov511; /* Forward declaration */ + +struct ov511_sbuf { + struct usb_ov511 *ov; + unsigned char *data; + struct urb *urb; + spinlock_t lock; + int n; +}; + +enum { + FRAME_UNUSED, /* Unused (no MCAPTURE) */ + FRAME_READY, /* Ready to start grabbing */ + FRAME_GRABBING, /* In the process of being grabbed into */ + FRAME_DONE, /* Finished grabbing, but not been synced yet */ + FRAME_ERROR, /* Something bad happened while processing */ +}; + +struct ov511_regvals { + enum { + OV511_DONE_BUS, + OV511_REG_BUS, + OV511_I2C_BUS, + } bus; + unsigned char reg; + unsigned char val; +}; + +struct ov511_frame { + int framenum; /* Index of this frame */ + unsigned char *data; /* Frame buffer */ + unsigned char *tempdata; /* Temp buffer for multi-stage conversions */ + unsigned char *rawdata; /* Raw camera data buffer */ + unsigned char *compbuf; /* Temp buffer for decompressor */ + + int depth; /* Bytes per pixel */ + int width; /* Width application is expecting */ + int height; /* Height application is expecting */ + + int rawwidth; /* Actual width of frame sent from camera */ + int rawheight; /* Actual height of frame sent from camera */ + + int sub_flag; /* Sub-capture mode for this frame? */ + unsigned int format; /* Format for this frame */ + int compressed; /* Is frame compressed? */ + + volatile int grabstate; /* State of grabbing */ + int scanstate; /* State of scanning */ + + int bytes_recvd; /* Number of image bytes received from camera */ + + long bytes_read; /* Amount that has been read() */ + + wait_queue_head_t wq; /* Processes waiting */ + + int snapshot; /* True if frame was a snapshot */ +}; + +#define DECOMP_INTERFACE_VER 4 + +/* Compression module operations */ +struct ov51x_decomp_ops { + int (*decomp_400)(unsigned char *, unsigned char *, unsigned char *, + int, int, int); + int (*decomp_420)(unsigned char *, unsigned char *, unsigned char *, + int, int, int); + int (*decomp_422)(unsigned char *, unsigned char *, unsigned char *, + int, int, int); + struct module *owner; +}; + +struct usb_ov511 { + struct video_device *vdev; + struct usb_device *dev; + + int customid; + char *desc; + unsigned char iface; + char usb_path[OV511_USB_PATH_LEN]; + + /* Determined by sensor type */ + int maxwidth; + int maxheight; + int minwidth; + int minheight; + + int brightness; + int colour; + int contrast; + int hue; + int whiteness; + int exposure; + int auto_brt; /* Auto brightness enabled flag */ + int auto_gain; /* Auto gain control enabled flag */ + int auto_exp; /* Auto exposure enabled flag */ + int backlight; /* Backlight exposure algorithm flag */ + int mirror; /* Image is reversed horizontally */ + + int led_policy; /* LED: off|on|auto; OV511+ only */ + + struct semaphore lock; /* Serializes user-accessible operations */ + int user; /* user count for exclusive use */ + + int streaming; /* Are we streaming Isochronous? */ + int grabbing; /* Are we grabbing? */ + + int compress; /* Should the next frame be compressed? */ + int compress_inited; /* Are compression params uploaded? */ + + int lightfreq; /* Power (lighting) frequency */ + int bandfilt; /* Banding filter enabled flag */ + + unsigned char *fbuf; /* Videodev buffer area */ + unsigned char *tempfbuf; /* Temporary (intermediate) buffer area */ + unsigned char *rawfbuf; /* Raw camera data buffer area */ + + int sub_flag; /* Pix Array subcapture on flag */ + int subx; /* Pix Array subcapture x offset */ + int suby; /* Pix Array subcapture y offset */ + int subw; /* Pix Array subcapture width */ + int subh; /* Pix Array subcapture height */ + + int curframe; /* Current receiving sbuf */ + struct ov511_frame frame[OV511_NUMFRAMES]; + + struct ov511_sbuf sbuf[OV511_NUMSBUF]; + + wait_queue_head_t wq; /* Processes waiting */ + + int snap_enabled; /* Snapshot mode enabled */ + + int bridge; /* Type of bridge (BRG_*) */ + int bclass; /* Class of bridge (BCL_*) */ + int sensor; /* Type of image sensor chip (SEN_*) */ + + int packet_size; /* Frame size per isoc desc */ + int packet_numbering; /* Is ISO frame numbering enabled? */ + + struct semaphore param_lock; /* params lock for this camera */ + + /* Framebuffer/sbuf management */ + int buf_state; + struct semaphore buf_lock; + + struct ov51x_decomp_ops *decomp_ops; + + /* Stop streaming while changing picture settings */ + int stop_during_set; + + int stopped; /* Streaming is temporarily paused */ + + /* Video decoder stuff */ + int input; /* Composite, S-VIDEO, etc... */ + int num_inputs; /* Number of inputs */ + int norm; /* NTSC / PAL / SECAM */ + int has_decoder; /* Device has a video decoder */ + int pal; /* Device is designed for PAL resolution */ + + /* I2C interface */ + struct semaphore i2c_lock; /* Protect I2C controller regs */ + unsigned char primary_i2c_slave; /* I2C write id of sensor */ + + /* Control transaction stuff */ + unsigned char *cbuf; /* Buffer for payload */ + struct semaphore cbuf_lock; +}; + +/* Used to represent a list of values and their respective symbolic names */ +struct symbolic_list { + int num; + char *name; +}; + +#define NOT_DEFINED_STR "Unknown" + +/* Returns the name of the matching element in the symbolic_list array. The + * end of the list must be marked with an element that has a NULL name. + */ +static inline char * +symbolic(struct symbolic_list list[], int num) +{ + int i; + + for (i = 0; list[i].name != NULL; i++) + if (list[i].num == num) + return (list[i].name); + + return (NOT_DEFINED_STR); +} + +/* Compression stuff */ + +#define OV511_QUANTABLESIZE 64 +#define OV518_QUANTABLESIZE 32 + +#define OV511_YQUANTABLE { \ + 0, 1, 1, 2, 2, 3, 3, 4, \ + 1, 1, 1, 2, 2, 3, 4, 4, \ + 1, 1, 2, 2, 3, 4, 4, 4, \ + 2, 2, 2, 3, 4, 4, 4, 4, \ + 2, 2, 3, 4, 4, 5, 5, 5, \ + 3, 3, 4, 4, 5, 5, 5, 5, \ + 3, 4, 4, 4, 5, 5, 5, 5, \ + 4, 4, 4, 4, 5, 5, 5, 5 \ +} + +#define OV511_UVQUANTABLE { \ + 0, 2, 2, 3, 4, 4, 4, 4, \ + 2, 2, 2, 4, 4, 4, 4, 4, \ + 2, 2, 3, 4, 4, 4, 4, 4, \ + 3, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4, \ + 4, 4, 4, 4, 4, 4, 4, 4 \ +} + +#define OV518_YQUANTABLE { \ + 5, 4, 5, 6, 6, 7, 7, 7, \ + 5, 5, 5, 5, 6, 7, 7, 7, \ + 6, 6, 6, 6, 7, 7, 7, 8, \ + 7, 7, 6, 7, 7, 7, 8, 8 \ +} + +#define OV518_UVQUANTABLE { \ + 6, 6, 6, 7, 7, 7, 7, 7, \ + 6, 6, 6, 7, 7, 7, 7, 7, \ + 6, 6, 6, 7, 7, 7, 7, 8, \ + 7, 7, 7, 7, 7, 7, 8, 8 \ +} + +#endif --- linux-2.6.28.orig/ubuntu/misc/media/ov511/Makefile +++ linux-2.6.28/ubuntu/misc/media/ov511/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_USB_OV511_NEW) += ov511.o ov511_decomp.o ov518_decomp.o --- linux-2.6.28.orig/ubuntu/misc/media/ov511/ov511_decomp.c +++ linux-2.6.28/ubuntu/misc/media/ov511/ov511_decomp.c @@ -0,0 +1,581 @@ +/* OV511 Decompression Support Module + * + * Copyright (c) 1999-2003 Mark W. McClelland. All rights reserved. + * http://alpha.dyndns.org/ov511/ + * + * Original decompression code Copyright 1998-2000 OmniVision Technologies + * + * 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. + */ + + +#if defined(OUTSIDE_KERNEL) + #if defined(CONFIG_MODVERSIONS) && !defined(MODVERSIONS) + #define MODVERSIONS + #endif + + #include + + #ifdef MODVERSIONS + #include + #endif +#else + #include +#endif + +#include +#include + +#include "ov511.h" + +/****************************************************************************** + * Version Information + ******************************************************************************/ + +#define DRIVER_VERSION "v1.6" +#define DRIVER_AUTHOR "Mark McClelland , OmniVision \ +Technologies " +#define DRIVER_DESC "OV511 Decompression Module" + +/****************************************************************************** + * Prototypes + ******************************************************************************/ + +extern int ov511_register_decomp_module(int ver, struct ov51x_decomp_ops *ops, + int ov518, int mmx); +extern void ov511_deregister_decomp_module(int ov518, int mmx); + +/****************************************************************************** + * Decompression Module Interface Constants + ******************************************************************************/ + +static const int interface_ver = DECOMP_INTERFACE_VER; +static const int ov518 = 0; +static const int mmx = 0; + +/****************************************************************************** + * Module Features + ******************************************************************************/ + +static int debug; + +module_param(debug, uint, 0400); +MODULE_PARM_DESC(debug, + "Debug level: 0=none, 1=inits, 2=warning, 3=config, 4=functions, 5=max"); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +#if defined(MODULE_LICENSE) /* Introduced in ~2.4.10 */ +MODULE_LICENSE("GPL"); +#endif + +/****************************************************************************** + * Decompression Functions + ******************************************************************************/ + +static void +DecompressYHI(unsigned char *pIn, + unsigned char *pOut, + int *iIn, /* in/out */ + int *iOut, /* in/out */ + const int w, + const int YUVFlag) +{ + short ZigZag[64]; + int temp[64]; + int Zcnt_Flag = 0; + int Num8_Flag = 0; + int in_pos = *iIn; + int out_pos = *iOut; + int tmp, tmp1, tmp2, tmp3; + unsigned char header, ZTable[64]; + short tmpl, tmph, half_byte, idx, count; + unsigned long ZigZag_length = 0, ZT_length, i, j; + short DeZigZag[64]; + + const short a = 11584; + const short b = 16068; + const short c = 15136; + const short d = 13624; + const short e = 9104; + const short f = 6270; + const short g = 3196; + + int out_idx; + + /* Take off every 'Zig' */ + for (i = 0; i < 64; i++) { + ZigZag[i] = 0; + } + + /***************************** + * Read in the Y header byte * + *****************************/ + + header = pIn[in_pos]; + in_pos++; + + ZigZag_length = header & 0x3f; + ZigZag_length = ZigZag_length + 1; + + Num8_Flag = header & 0x40; + Zcnt_Flag = header & 0x80; + + /************************* + * Read in the Y content * + *************************/ + + if (Zcnt_Flag == 0) { /* Without Zero Table read contents directly */ + /* Read in ZigZag[0] */ + ZigZag[0] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl<<8; + ZigZag[0] = ZigZag[0] | tmph; + ZigZag[0] = ZigZag[0]<<4; + ZigZag[0] = ZigZag[0]>>4; + + if (Num8_Flag) { /* 8 Bits */ + for (i = 1; i < ZigZag_length; i++) { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + ZigZag[i] = ZigZag[i]>>8; + } + } else { /* 12 bits and has no Zero Table */ + idx = 1; + half_byte = 0; + for (i = 1; i < ZigZag_length; i++) { + if (half_byte == 0) { + ZigZag[i] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl<<8; + tmph = tmph&0x0f00; + ZigZag[i] = ZigZag[i] | tmph; + ZigZag[i] = ZigZag[i]<<4; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 1; + } else { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + tmpl = tmpl & 0x00f0; + ZigZag[i] = ZigZag[i] | tmpl; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 0; + } + } + } + } else { /* Has Zero Table */ + /* Calculate Z-Table length */ + ZT_length = ZigZag_length/8; + tmp = ZigZag_length%8; + + if (tmp > 0) { + ZT_length = ZT_length + 1; + } + + /* Read in Zero Table */ + for (j = 0; j < ZT_length; j++) { + ZTable[j] = pIn[in_pos++]; + } + + /* Read in ZigZag[0] */ + ZigZag[0] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl<<8; + ZigZag[0] = ZigZag[0] | tmph; + ZigZag[0] = ZigZag[0]<<4; + ZigZag[0] = ZigZag[0]>>4; + + /* Decode ZigZag */ + idx = 0; + ZTable[idx] = ZTable[idx]<<1; + count = 7; + + if (Num8_Flag) { /* 8 Bits and has zero table */ + for (i = 1; i < ZigZag_length; i++) { + if ((ZTable[idx]&0x80)) { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + ZigZag[i] = ZigZag[i]>>8; + } + + ZTable[idx]=ZTable[idx]<<1; + count--; + if (count == 0) { + count = 8; + idx++; + } + } + } else { /* 12 bits and has Zero Table */ + half_byte = 0; + for (i = 1; i < ZigZag_length; i++) { + if (ZTable[idx]&0x80) { + if (half_byte == 0) { + ZigZag[i] = pIn[in_pos++]; + tmpl = pIn[in_pos++]; + tmph = tmpl <<8; + tmph = tmph & 0x0f00; + ZigZag[i] = ZigZag[i] | tmph; + ZigZag[i] = ZigZag[i]<<4; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 1; + } else { + ZigZag[i] = pIn[in_pos++]; + ZigZag[i] = ZigZag[i]<<8; + tmpl = tmpl & 0x00f0; + ZigZag[i] = ZigZag[i] | tmpl; + ZigZag[i] = ZigZag[i]>>4; + half_byte = 0; + } + } + + ZTable[idx] = ZTable[idx]<<1; + count--; + if (count == 0) { + count = 8; + idx++; + } + } + } + } + + /************* + * De-ZigZag * + *************/ + + for (j = 0; j < 64; j++) { + DeZigZag[j] = 0; + } + + if (YUVFlag == 1) { + DeZigZag[0] = ZigZag[0]; + DeZigZag[1] = ZigZag[1]<<1; + DeZigZag[2] = ZigZag[5]<<1; + DeZigZag[3] = ZigZag[6]<<2; + + DeZigZag[8] = ZigZag[2]<<1; + DeZigZag[9] = ZigZag[4]<<1; + DeZigZag[10] = ZigZag[7]<<1; + DeZigZag[11] = ZigZag[13]<<2; + + DeZigZag[16] = ZigZag[3]<<1; + DeZigZag[17] = ZigZag[8]<<1; + DeZigZag[18] = ZigZag[12]<<2; + DeZigZag[19] = ZigZag[17]<<2; + + DeZigZag[24] = ZigZag[9]<<2; + DeZigZag[25] = ZigZag[11]<<2; + DeZigZag[26] = ZigZag[18]<<2; + DeZigZag[27] = ZigZag[24]<<3; + } else { + DeZigZag[0] = ZigZag[0]; + DeZigZag[1] = ZigZag[1]<<2; + DeZigZag[2] = ZigZag[5]<<2; + DeZigZag[3] = ZigZag[6]<<3; + + DeZigZag[8] = ZigZag[2]<<2; + DeZigZag[9] = ZigZag[4]<<2; + DeZigZag[10] = ZigZag[7]<<2; + DeZigZag[11] = ZigZag[13]<<4; + + DeZigZag[16] = ZigZag[3]<<2; + DeZigZag[17] = ZigZag[8]<<2; + DeZigZag[18] = ZigZag[12]<<3; + DeZigZag[19] = ZigZag[17]<<4; + + DeZigZag[24] = ZigZag[9]<<3; + DeZigZag[25] = ZigZag[11]<<4; + DeZigZag[26] = ZigZag[18]<<4; + DeZigZag[27] = ZigZag[24]<<4; + } + + /***************** + **** IDCT 1D **** + *****************/ + +#define IDCT_1D(c0, c1, c2, c3, in) \ + do { \ + tmp1=((c0)*DeZigZag[in])+((c2)*DeZigZag[(in)+2]); \ + tmp2=(c1)*DeZigZag[(in)+1]; \ + tmp3=(c3)*DeZigZag[(in)+3]; \ + } while (0) + +#define COMPOSE_1(out1, out2) \ + do { \ + tmp=tmp1+tmp2+tmp3; \ + temp[out1] = tmp>>15; \ + tmp=tmp1-tmp2-tmp3; \ + temp[out2] = tmp>>15; \ + } while (0) + +#define COMPOSE_2(out1, out2) \ + do { \ + tmp=tmp1+tmp2-tmp3; \ + temp[out1] = tmp>>15; \ + tmp=tmp1-tmp2+tmp3; \ + temp[out2] = tmp>>15; \ + } while (0) + + /* j = 0 */ + IDCT_1D(a, b, c, d, 0); COMPOSE_1( 0, 56); + IDCT_1D(a, b, c, d, 8); COMPOSE_1( 1, 57); + IDCT_1D(a, b, c, d, 16); COMPOSE_1( 2, 58); + IDCT_1D(a, b, c, d, 24); COMPOSE_1( 3, 59); + + /* j = 1 */ + IDCT_1D(a, d, f, g, 0); COMPOSE_2( 8, 48); + IDCT_1D(a, d, f, g, 8); COMPOSE_2( 9, 49); + IDCT_1D(a, d, f, g, 16); COMPOSE_2(10, 50); + IDCT_1D(a, d, f, g, 24); COMPOSE_2(11, 51); + + /* j = 2 */ + IDCT_1D(a, e, -f, b, 0); COMPOSE_2(16, 40); + IDCT_1D(a, e, -f, b, 8); COMPOSE_2(17, 41); + IDCT_1D(a, e, -f, b, 16); COMPOSE_2(18, 42); + IDCT_1D(a, e, -f, b, 24); COMPOSE_2(19, 43); + + /* j = 3 */ + IDCT_1D(a, g, -c, e, 0); COMPOSE_2(24, 32); + IDCT_1D(a, g, -c, e, 8); COMPOSE_2(25, 33); + IDCT_1D(a, g, -c, e, 16); COMPOSE_2(26, 34); + IDCT_1D(a, g, -c, e, 24); COMPOSE_2(27, 35); + +#undef IDCT_1D +#undef COMPOSE_1 +#undef COMPOSE_2 + + /***************** + **** IDCT 2D **** + *****************/ + +#define IDCT_2D(c0, c1, c2, c3, in) \ + do { \ + tmp = temp[in]*(c0) + temp[(in)+1]*(c1) \ + + temp[(in)+2]*(c2) + temp[(in)+3]*(c3); \ + } while (0) + +#define STORE(i) \ + do { \ + tmp = tmp >> 15; \ + tmp = tmp + 128; \ + if (tmp > 255) tmp = 255; \ + if (tmp < 0) tmp = 0; \ + pOut[i] = (unsigned char) tmp; \ + } while (0) + +#define IDCT_2D_ROW(in) \ + do { \ + IDCT_2D(a, b, c, d, in); STORE(0+out_idx); \ + IDCT_2D(a, d, f, -g, in); STORE(1+out_idx); \ + IDCT_2D(a, e, -f, -b, in); STORE(2+out_idx); \ + IDCT_2D(a, g, -c, -e, in); STORE(3+out_idx); \ + IDCT_2D(a, -g, -c, e, in); STORE(4+out_idx); \ + IDCT_2D(a, -e, -f, b, in); STORE(5+out_idx); \ + IDCT_2D(a, -d, f, g, in); STORE(6+out_idx); \ + IDCT_2D(a, -b, c, -d, in); STORE(7+out_idx); \ + } while (0) + + +#define IDCT_2D_FAST(c0, c1, c2, c3, in) \ + do { \ + tmp1=((c0)*temp[in])+((c2)*temp[(in)+2]); \ + tmp2=(c1)*temp[(in)+1]; \ + tmp3=(c3)*temp[(in)+3]; \ + } while (0) + +#define STORE_FAST_1(out1, out2) \ + do { \ + tmp=tmp1+tmp2+tmp3; \ + STORE((out1)+out_idx); \ + tmp=tmp1-tmp2-tmp3; \ + STORE((out2)+out_idx); \ + } while (0) + +#define STORE_FAST_2(out1, out2) \ + do { \ + tmp=tmp1+tmp2-tmp3; \ + STORE((out1)+out_idx); \ + tmp=tmp1-tmp2+tmp3; \ + STORE((out2)+out_idx); \ + } while (0) + +#define IDCT_2D_FAST_ROW(in) \ + do { \ + IDCT_2D_FAST(a, b, c, d, in); STORE_FAST_1(0, 7); \ + IDCT_2D_FAST(a, d, f, g, in); STORE_FAST_2(1, 6); \ + IDCT_2D_FAST(a, e, -f, b, in); STORE_FAST_2(2, 5); \ + IDCT_2D_FAST(a, g, -c, e, in); STORE_FAST_2(3, 4); \ + } while (0) + + out_idx = out_pos; + + IDCT_2D_ROW(0); out_idx += w; + IDCT_2D_ROW(8); out_idx += w; + IDCT_2D_ROW(16); out_idx += w; + IDCT_2D_ROW(24); out_idx += w; + IDCT_2D_ROW(32); out_idx += w; + IDCT_2D_ROW(40); out_idx += w; + IDCT_2D_FAST_ROW(48); out_idx += w; + IDCT_2D_FAST_ROW(56); + + *iIn = in_pos; + *iOut = out_pos + 8; +} + +#define DECOMP_Y() DecompressYHI(pIn, pY, &iIn, &iY, w, 1) +#define DECOMP_U() DecompressYHI(pIn, pU, &iIn, &iU, w/2, 2) +#define DECOMP_V() DecompressYHI(pIn, pV, &iIn, &iV, w/2, 2) + +inline static int +Decompress400HiNoMMX(unsigned char *pIn, + unsigned char *pOut, + const int w, + const int h, + const int inSize) +{ + unsigned char *pY = pOut; + int x, y, iIn, iY; + + iIn = 0; + for (y = 0; y < h; y += 8) { + iY = w*y; + + for (x = 0; x < w; x += 8) + DECOMP_Y(); + } + + return 0; +} + +inline static int +Decompress420HiNoMMX(unsigned char *pIn, + unsigned char *pOut, + const int w, + const int h, + const int inSize) +{ + unsigned char *pY = pOut; + unsigned char *pU = pY + w*h; + unsigned char *pV = pU + w*h/4; + int xY, xUV, iY, iU, iV, iIn, count; + const int nBlocks = (w*h) / (32*8); + + iIn = 0; + iY = iU = iV = 0; + xY = xUV = 0; + + for (count = 0; count < nBlocks; count++) { + DECOMP_U(); + DECOMP_V(); xUV += 16; + if (xUV >= w) { + iU += (w*7)/2; + iV += (w*7)/2; + xUV = 0; + } + + DECOMP_Y(); xY += 8; + DECOMP_Y(); xY += 8; + if (xY >= w) { + iY += w*7; + xY = 0; + } + DECOMP_Y(); xY += 8; + DECOMP_Y(); xY += 8; + if (xY >= w) { + iY += w*7; + xY = 0; + } + } + + return 0; +} + +/* Input format is raw isoc. data (with header and packet + * number stripped, and all-zero blocks removed). + * Output format is YUV400 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress400(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + int numpix = w * h; + int rc; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize); + + rc = Decompress400HiNoMMX(pIn, pOut, w, h, inSize); + + if (rc) + return 0; + + return numpix; +} + +/* Input format is raw isoc. data (with header and packet + * number stripped, and all-zero blocks removed). + * Output format is planar YUV420 + * Returns uncompressed data length if success, or zero if error + */ +static int +Decompress420(unsigned char *pIn, + unsigned char *pOut, + unsigned char *pTmp, + int w, + int h, + int inSize) +{ + int numpix = w * h; + int rc; + + PDEBUG(4, "%dx%d pIn=%p pOut=%p inSize=%d", w, h, pIn, pOut, inSize); + + rc = Decompress420HiNoMMX(pIn, pOut, w, h, inSize); + + if (rc) + return 0; + + return (numpix * 3 / 2); +} + +/****************************************************************************** + * Module Functions + ******************************************************************************/ + +static struct ov51x_decomp_ops decomp_ops = { + .decomp_400 = Decompress400, + .decomp_420 = Decompress420, + .owner = THIS_MODULE, +}; + +static int __init +decomp_init(void) +{ + int rc; + + rc = ov511_register_decomp_module(DECOMP_INTERFACE_VER, &decomp_ops, + ov518, mmx); + if (rc) { + err("Could not register with ov511 (rc=%d)", rc); + return -1; + } + + info(DRIVER_VERSION " : " DRIVER_DESC); + + return 0; +} + +static void __exit +decomp_exit(void) +{ + ov511_deregister_decomp_module(ov518, mmx); + info("deregistered\n"); +} + +module_init(decomp_init); +module_exit(decomp_exit); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-region_hash.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-region_hash.c @@ -0,0 +1,643 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. + * Copyright (C) 2004-2007 Red Hat Inc. + * + * This file is released under the GPL. + */ + +#include "dm.h" +#include +#include "dm-region_hash.h" + +#include +#include +#include +#include + +#define DM_MSG_PREFIX "region hash" + +/*----------------------------------------------------------------- + * Region hash + * + * The set splits itself up into discrete regions. + * Each region can be in one of three states: + * + * o clean + * o dirty, + * o nosync. + * + * There is no need to put clean regions in the hash. + * + * + * In addition to being present in the hash table a region _may_ + * be present on one of three lists. + * + * clean_regions: Regions on this list have no io pending to + * them, they are in sync, we are no longer interested in them, + * they are dull. rh_update_states() will remove them from the + * hash table. + * + * quiesced_regions: These regions have been spun down, ready + * for recovery. rh_recovery_start() will remove regions from + * this list and hand them to kmirrord, which will schedule the + * recovery io with kcopyd. + * + * recovered_regions: Regions that kcopyd has successfully + * recovered. rh_update_states() will now schedule any delayed + * io, up the recovery_count, and remove the region from the hash. + * + * There are 2 locks: + * A rw spin lock 'hash_lock' protects just the hash table, + * this is never held in write mode from interrupt context, + * which I believe means that we only have to disable irqs when + * doing a write lock. + * + * An ordinary spin lock 'region_lock' that protects the three + * lists in the region_hash, with the 'state', 'list' and + * 'delayed_bios' fields of the regions. This is used from irq + * context, so all other uses will have to suspend local irqs. + *---------------------------------------------------------------*/ +enum region_hash_flags { + RECOVERY, +}; + +struct region_hash { + unsigned int max_recovery; /* Max # of regions to recover in parallel */ + unsigned long flags; + + /* Callback function to dispatch queued writes on recovered regions. */ + void (*dispatch)(void *context, struct bio_list *bios); + void *dispatch_context; + + /* Callback function to wakeup callers worker thread. */ + void (*wake)(void *context); + void *wake_context; + + uint32_t region_size; + unsigned int region_shift; + + /* holds persistent region state */ + struct dm_dirty_log *log; + + /* hash table */ + rwlock_t hash_lock; + mempool_t *region_pool; + unsigned int mask; + unsigned int nr_buckets; + unsigned int prime; + unsigned int shift; + struct list_head *buckets; + + spinlock_t region_lock; + struct semaphore recovery_count; + struct list_head clean_regions; + struct list_head quiesced_regions; + struct list_head recovered_regions; +}; + +struct region { + struct region_hash *rh; /* FIXME: can we get rid of this ? */ + region_t key; + int state; + void *context; /* Caller context. */ + + struct list_head hash_list; + struct list_head list; + + atomic_t pending; + struct bio_list delayed_bios; +}; + +/* + * Conversion fns + */ +region_t rh_sector_to_region(void *rh, sector_t sector) +{ + return sector >> ((struct region_hash*) rh)->region_shift; +} + +region_t rh_bio_to_region(void *rh, struct bio *bio) +{ + return rh_sector_to_region(rh, bio->bi_sector); +} + +sector_t rh_region_to_sector(void *rh, region_t region) +{ + return region << ((struct region_hash*) rh)->region_shift; +} + +/* + * Retrival fns. + */ +region_t rh_get_region_key(void *reg) +{ + return ((struct region *)reg)->key; +} + +sector_t rh_get_region_size(void *rh) +{ + return ((struct region_hash *)rh)->region_size; +} + +/* Squirrel a context with a region. */ +void *rh_reg_get_context(void *reg) +{ + return ((struct region*) reg)->context; +} + +void rh_reg_set_context(void *reg, void *context) +{ + ((struct region*) reg)->context = context; +} + +/* + * Region struct allocation/free. + */ +static void *region_alloc(unsigned int gfp_mask, void *pool_data) +{ + return kmalloc(sizeof(struct region), gfp_mask); +} + +static void region_free(void *element, void *pool_data) +{ + kfree(element); +} + +#define MIN_REGIONS 64 +int rh_init(void **region_hash, + unsigned int max_recovery, + + void (*dispatch)(void *dispatch_context, struct bio_list *bios), + void *dispatch_context, + void (*wake)(void *wake_context), + void *wake_context, + struct dm_dirty_log *log, uint32_t region_size, region_t nr_regions) +{ + unsigned int nr_buckets, max_buckets; + unsigned hash_primes[] = { + /* Table of primes for rh_hash/table size optimization. */ + 3, 7, 13, 27, 53, 97, 193, 389, 769, + 1543, 3079, 6151, 12289, 24593, + }; + size_t i; + struct region_hash *rh; + + if (region_size & (region_size - 1)) { + DMERR("region size must be 2^^n"); + return -EINVAL; + } + + rh = kmalloc(sizeof(*rh), GFP_KERNEL); + if (!rh) { + DMERR("unable to allocate region hash memory"); + return -ENOMEM; + } + + rh->max_recovery = max_recovery; + rh->dispatch = dispatch; + rh->dispatch_context = dispatch_context; + rh->wake = wake; + rh->wake_context = wake_context; + rh->log = log; + rh->region_size = region_size; + rh->region_shift = ffs(region_size) - 1; + rwlock_init(&rh->hash_lock); + + /* Calculate a suitable number of buckets for our hash table. */ + max_buckets = nr_regions >> 6; + for (nr_buckets = 128u; nr_buckets < max_buckets; nr_buckets <<= 1); + nr_buckets >>= 1; + rh->mask = rh->nr_buckets = nr_buckets; + rh->mask--; + rh->shift = ffs(nr_buckets); + rh->prime = hash_primes[rh->shift - 1]; + if (rh->prime > ARRAY_SIZE(hash_primes) - 2) + rh->prime = ARRAY_SIZE(hash_primes) - 1; + + rh->buckets = vmalloc(nr_buckets * sizeof(*rh->buckets)); + if (!rh->buckets) { + DMERR("unable to allocate region hash bucket memory"); + vfree(rh); + return -ENOMEM; + } + + for (i = 0; i < nr_buckets; i++) + INIT_LIST_HEAD(rh->buckets + i); + + spin_lock_init(&rh->region_lock); + sema_init(&rh->recovery_count, 0); + INIT_LIST_HEAD(&rh->clean_regions); + INIT_LIST_HEAD(&rh->quiesced_regions); + INIT_LIST_HEAD(&rh->recovered_regions); + + rh->region_pool = mempool_create(MIN_REGIONS, region_alloc, + region_free, NULL); + if (!rh->region_pool) { + vfree(rh->buckets); + vfree(rh); + return -ENOMEM; + } + + *region_hash = rh; + + return 0; +} + +void rh_exit(void *v) +{ + unsigned int h; + struct region *reg, *tmp; + struct region_hash *rh = v; + + BUG_ON(!list_empty(&rh->quiesced_regions)); + + for (h = 0; h < rh->nr_buckets; h++) { + list_for_each_entry_safe(reg, tmp, rh->buckets + h, hash_list) { + BUG_ON(atomic_read(®->pending)); + mempool_free(reg, rh->region_pool); + } + } + + dm_dirty_log_destroy(rh->log); + + if (rh->region_pool) + mempool_destroy(rh->region_pool); + + vfree(rh->buckets); + kfree(rh); +} + +static inline unsigned int rh_hash(struct region_hash *rh, region_t region) +{ + return (unsigned int) ((region * rh->prime) >> rh->shift) & rh->mask; +} + +static struct region *__rh_lookup(struct region_hash *rh, region_t region) +{ + struct region *reg; + struct list_head *bucket = rh->buckets + rh_hash(rh, region); + + list_for_each_entry(reg, bucket, hash_list) { + if (reg->key == region) + return reg; + } + + return NULL; +} + +static void __rh_insert(struct region_hash *rh, struct region *reg) +{ + unsigned int h = rh_hash(rh, reg->key); + list_add(®->hash_list, rh->buckets + h); +} + +static struct region *__rh_alloc(struct region_hash *rh, region_t region) +{ + struct region *reg, *nreg; + + read_unlock(&rh->hash_lock); + + nreg = mempool_alloc(rh->region_pool, GFP_NOIO); + nreg->state = rh->log->type->in_sync(rh->log, region, 1) ? + RH_CLEAN : RH_NOSYNC; + nreg->rh = rh; + nreg->key = region; + + INIT_LIST_HEAD(&nreg->list); + + atomic_set(&nreg->pending, 0); + bio_list_init(&nreg->delayed_bios); + + write_lock_irq(&rh->hash_lock); + + reg = __rh_lookup(rh, region); + if (reg) + /* we lost the race */ + mempool_free(nreg, rh->region_pool); + else { + __rh_insert(rh, nreg); + if (nreg->state == RH_CLEAN) { + spin_lock(&rh->region_lock); + list_add(&nreg->list, &rh->clean_regions); + spin_unlock(&rh->region_lock); + } + reg = nreg; + } + + write_unlock_irq(&rh->hash_lock); + read_lock(&rh->hash_lock); + + return reg; +} + +static inline struct region *__rh_find(struct region_hash *rh, region_t region) +{ + struct region *reg; + + reg = __rh_lookup(rh, region); + if (!reg) + reg = __rh_alloc(rh, region); + + return reg; +} + +int rh_state(void *v, region_t region, int may_block) +{ + int r = 0; + struct region *reg; + struct region_hash *rh = v; + + read_lock(&rh->hash_lock); + reg = __rh_lookup(rh, region); + if (reg) + r = reg->state; + read_unlock(&rh->hash_lock); + + if (r) + return r; + + /* + * The region wasn't in the hash, so we fall back to the dirty log. + */ + r = rh->log->type->in_sync(rh->log, region, may_block); + + /* + * Any error from the dirty log (eg. -EWOULDBLOCK) gets + * taken as a RH_NOSYNC + */ + return r == 1 ? RH_CLEAN : RH_NOSYNC; +} + +void rh_update_states(void *v) +{ + struct region *reg, *next; + struct region_hash *rh = v; + LIST_HEAD(clean); + LIST_HEAD(recovered); + + /* + * Quickly grab the lists. + */ + write_lock_irq(&rh->hash_lock); + spin_lock(&rh->region_lock); + if (!list_empty(&rh->clean_regions)) { + list_splice(&rh->clean_regions, &clean); + INIT_LIST_HEAD(&rh->clean_regions); + + list_for_each_entry(reg, &clean, list) + list_del(®->hash_list); + } + + if (!list_empty(&rh->recovered_regions)) { + list_splice(&rh->recovered_regions, &recovered); + INIT_LIST_HEAD(&rh->recovered_regions); + + list_for_each_entry(reg, &recovered, list) + list_del(®->hash_list); + } + + spin_unlock(&rh->region_lock); + write_unlock_irq(&rh->hash_lock); + + /* + * All the regions on the recovered and clean lists have + * now been pulled out of the system, so no need to do + * any more locking. + */ + list_for_each_entry_safe (reg, next, &recovered, list) { + if (reg->state != RH_ERROR) + rh->log->type->clear_region(rh->log, reg->key); + + rh->log->type->set_region_sync(rh->log, reg->key, + reg->state != RH_ERROR); + up(&rh->recovery_count); + if (reg->delayed_bios.head) + rh->dispatch(rh->dispatch_context, ®->delayed_bios); + + mempool_free(reg, rh->region_pool); + } + + list_for_each_entry_safe(reg, next, &clean, list) { + rh->log->type->clear_region(rh->log, reg->key); + mempool_free(reg, rh->region_pool); + } + + rh_flush(rh); +} + +void rh_inc(void *v, region_t region) +{ + struct region *reg; + struct region_hash *rh = v; + + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + if (reg->state == RH_CLEAN) { + rh->log->type->mark_region(rh->log, reg->key); + + spin_lock_irq(&rh->region_lock); + reg->state = RH_DIRTY; + list_del_init(®->list); /* Take off the clean list. */ + spin_unlock_irq(&rh->region_lock); + } + + atomic_inc(®->pending); + read_unlock(&rh->hash_lock); +} + +void rh_inc_pending(void *v, struct bio_list *bios) +{ + struct bio *bio; + struct region_hash *rh = v; + + for (bio = bios->head; bio; bio = bio->bi_next) + rh_inc(rh, rh_bio_to_region(rh, bio)); +} + +void rh_dec(void *v, region_t region) +{ + unsigned long flags; + struct region *reg; + struct region_hash *rh = v; + + read_lock(&rh->hash_lock); + reg = __rh_lookup(rh, region); + read_unlock(&rh->hash_lock); + + BUG_ON(!reg); + + if (atomic_dec_and_test(®->pending)) { + spin_lock_irqsave(&rh->region_lock, flags); + if (reg->state == RH_RECOVERING) { + list_add_tail(®->list, &rh->quiesced_regions); + } else { + reg->state = RH_CLEAN; + list_add(®->list, &rh->clean_regions); + } + spin_unlock_irqrestore(&rh->region_lock, flags); + } +} + +/* + * Starts quiescing a region in preparation for recovery. + */ +static int __rh_recovery_prepare(struct region_hash *rh) +{ + int r; + struct region *reg; + region_t region; + + /* + * Ask the dirty log what's next. + */ + r = rh->log->type->get_resync_work(rh->log, ®ion); + if (r <= 0) + return r; + + /* + * Get this region, and start it quiescing + * by setting the recovering flag. + */ + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + read_unlock(&rh->hash_lock); + + spin_lock_irq(&rh->region_lock); + + reg->state = RH_RECOVERING; + + /* Already quiesced ? */ + list_del_init(®->list); + if (!atomic_read(®->pending)) + list_add(®->list, &rh->quiesced_regions); + + spin_unlock_irq(&rh->region_lock); + + return 1; +} + +int rh_recovery_prepare(void *v) +{ + struct region_hash *rh = v; + + if (test_bit(RECOVERY, &rh->flags)) { + while (!down_trylock(&rh->recovery_count)) { + if (__rh_recovery_prepare(rh) <= 0) { + up(&rh->recovery_count); + return -ENOENT; + } + } + } + + return 0; +} + +/* + * Returns any quiesced regions. + */ +void *rh_recovery_start(void *v) +{ + struct region *reg = NULL; + struct region_hash *rh = v; + + spin_lock_irq(&rh->region_lock); + if (!list_empty(&rh->quiesced_regions)) { + reg = list_entry(rh->quiesced_regions.next, + struct region, list); + list_del_init(®->list); /* Remove from the quiesced list. */ + } + spin_unlock_irq(&rh->region_lock); + + return (void*) reg; +} + +/* + * Put region on list of recovered ones. + */ +void rh_recovery_end(void *v, int error) +{ + struct region *reg = v; + struct region_hash *rh = reg->rh; + + if (error) + reg->state = RH_ERROR; + + spin_lock_irq(&rh->region_lock); + list_add(®->list, &rh->recovered_regions); + spin_unlock_irq(&rh->region_lock); +} + +void rh_flush(void *v) +{ + struct region_hash *rh = v; + + rh->log->type->flush(rh->log); +} + +void rh_delay_by_region(void *v, struct bio *bio, region_t region) +{ + struct region_hash *rh = v; + struct region *reg; + + read_lock(&rh->hash_lock); + reg = __rh_find(rh, region); + bio_list_add(®->delayed_bios, bio); + read_unlock(&rh->hash_lock); +} + +void rh_delay(void *v, struct bio *bio) +{ + return rh_delay_by_region(v, bio, rh_bio_to_region(v, bio)); +} + +void rh_stop_recovery(void *v) +{ + int i; + struct region_hash *rh = v; + + clear_bit(RECOVERY, &rh->flags); + rh->wake(rh->wake_context); + + /* wait for any recovering regions */ + for (i = 0; i < rh->max_recovery; i++) + down(&rh->recovery_count); +} + +void rh_start_recovery(void *v) +{ + int i; + struct region_hash *rh = v; + + set_bit(RECOVERY, &rh->flags); + for (i = 0; i < rh->max_recovery; i++) + up(&rh->recovery_count); + + rh->wake(rh->wake_context); +} + +EXPORT_SYMBOL(rh_bio_to_region); +EXPORT_SYMBOL(rh_sector_to_region); +EXPORT_SYMBOL(rh_region_to_sector); +EXPORT_SYMBOL(rh_init); +EXPORT_SYMBOL(rh_exit); +EXPORT_SYMBOL(rh_state); +EXPORT_SYMBOL(rh_update_states); +EXPORT_SYMBOL(rh_flush); +EXPORT_SYMBOL(rh_inc); +EXPORT_SYMBOL(rh_inc_pending); +EXPORT_SYMBOL(rh_dec); +EXPORT_SYMBOL(rh_delay); +EXPORT_SYMBOL(rh_delay_by_region); +EXPORT_SYMBOL(rh_recovery_prepare); +EXPORT_SYMBOL(rh_recovery_start); +EXPORT_SYMBOL(rh_recovery_end); +EXPORT_SYMBOL(rh_stop_recovery); +EXPORT_SYMBOL(rh_start_recovery); +EXPORT_SYMBOL(rh_reg_get_context); +EXPORT_SYMBOL(rh_reg_set_context); +EXPORT_SYMBOL(rh_get_region_key); +EXPORT_SYMBOL(rh_get_region_size); + +MODULE_DESCRIPTION(DM_NAME " region hash"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-message.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-message.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * This file is released under the GPL. + * + * device-mapper message parser. + * + */ + +#include "dm.h" +#include "dm-message.h" +#include + +#define DM_MSG_PREFIX "dm_message" + +/* Basename of a path. */ +static inline char * +basename(char *s) +{ + char *p = strrchr(s, '/'); + + return p ? p + 1 : s; +} + +/* Get an argument depending on type. */ +static void +message_arguments(struct dm_msg *msg, int argc, char **argv) +{ + + if (argc) { + int i; + struct dm_message_argument *args = msg->spec->args; + + for (i = 0; i < args->num_args; i++) { + int r; + unsigned long **ptr = args->ptr; + enum dm_message_argument_type type = args->types[i]; + + switch (type) { + case dm_msg_base_t: + ((char **) ptr)[i] = basename(argv[i]); + break; + + case dm_msg_str_t: + ((char **) ptr)[i] = argv[i]; + break; + + case dm_msg_int_t: + r = sscanf(argv[i], "%d", ((int **) ptr)[i]); + goto check; + + case dm_msg_uint_t: + r = sscanf(argv[i], "%u", + ((unsigned **) ptr)[i]); + goto check; + + case dm_msg_uint64_t: + r = sscanf(argv[i], "%llu", + ((unsigned long long **) ptr)[i]); + + check: + if (r != 1) { + set_bit(dm_msg_ret_undef, &msg->ret); + set_bit(dm_msg_ret_arg, &msg->ret); + } + } + } + } +} + +/* Parse message options. */ +static void +message_options_parse(struct dm_msg *msg, int argc, char **argv) +{ + int hit = 0; + unsigned long *action; + size_t l1 = strlen(*argv), l_hit = 0; + struct dm_message_option *o = msg->spec->options; + char **option, **option_end = o->options + o->num_options; + + for (option = o->options, action = o->actions; + option < option_end; option++, action++) { + size_t l2 = strlen(*option); + + if (!strnicmp(*argv, *option, min(l1, l2))) { + hit++; + l_hit = l2; + set_bit(*action, &msg->action); + } + } + + /* Assume error. */ + msg->ret = 0; + set_bit(dm_msg_ret_option, &msg->ret); + if (!hit || l1 > l_hit) + set_bit(dm_msg_ret_undef, &msg->ret); /* Undefined option. */ + else if (hit > 1) + set_bit(dm_msg_ret_ambiguous, &msg->ret); /* Ambiguous option.*/ + else { + clear_bit(dm_msg_ret_option, &msg->ret); /* Option OK. */ + message_arguments(msg, --argc, ++argv); + } +} + +static inline void +print_ret(const char *caller, unsigned long ret) +{ + struct { + unsigned long err; + const char *err_str; + } static err_msg[] = { + { dm_msg_ret_ambiguous, "message ambiguous" }, + { dm_msg_ret_inval, "message invalid" }, + { dm_msg_ret_undef, "message undefined" }, + { dm_msg_ret_arg, "message argument" }, + { dm_msg_ret_argcount, "message argument count" }, + { dm_msg_ret_option, "option" }, + }, *e = ARRAY_END(err_msg); + + while (e-- > err_msg) { + if (test_bit(e->err, &ret)) + DMERR("%s %s", caller, e->err_str); + } +} + +/* Parse a message action. */ +int +dm_message_parse(const char *caller, struct dm_msg *msg, void *context, + int argc, char **argv) +{ + int hit = 0; + size_t l1 = strlen(*argv), l_hit = 0; + struct dm_msg_spec *s, *s_hit = NULL, + *s_end = msg->specs + msg->num_specs; + + if (argc < 2) + return -EINVAL; + + for (s = msg->specs; s < s_end; s++) { + size_t l2 = strlen(s->cmd); + + if (!strnicmp(*argv, s->cmd, min(l1, l2))) { + hit++; + l_hit = l2; + s_hit = s; + } + } + + msg->ret = 0; + if (!hit || l1 > l_hit) /* No hit or message string too long. */ + set_bit(dm_msg_ret_undef, &msg->ret); + else if (hit > 1) /* Ambiguous message. */ + set_bit(dm_msg_ret_ambiguous, &msg->ret); + else if (argc - 2 != s_hit->args->num_args) { + set_bit(dm_msg_ret_undef, &msg->ret); + set_bit(dm_msg_ret_argcount, &msg->ret); + } + + if (msg->ret) + goto bad; + + msg->action = 0; + msg->spec = s_hit; + set_bit(s_hit->action, &msg->action); + message_options_parse(msg, --argc, ++argv); + + if (!msg->ret) + return msg->spec->f(msg, context); + + bad: + print_ret(caller, msg->ret); + return -EINVAL; +} +EXPORT_SYMBOL(dm_message_parse); + +MODULE_DESCRIPTION(DM_NAME " device-mapper target message parser"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-raid4-5.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-raid4-5.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2006 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen (Mauelshagen@RedHat.com) + * + * This file is released under the GPL. + * + */ + +#ifndef _DM_RAID45_H +#define _DM_RAID45_H + +/* Factor out to dm.h! */ +#define STR_LEN(ptr, str) ptr, str, strlen(ptr) + +enum lock_type { RAID45_EX, RAID45_SHARED }; + +struct dmraid45_locking_type { + /* Request a lock on a stripe. */ + void* (*lock)(sector_t key, enum lock_type type); + + /* Release a lock on a stripe. */ + void (*unlock)(void *lock_handle); + +}; + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/Kconfig +++ linux-2.6.28/ubuntu/dm-raid4-5/Kconfig @@ -0,0 +1,6 @@ +config DM_RAID45 + tristate "RAID 4/5 target (EXPERIMENTAL)" + depends on BLK_DEV_DM && EXPERIMENTAL + default m + ---help--- + A target that supports RAID4 and RAID5 mappings. --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-raid4-5.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-raid4-5.c @@ -0,0 +1,4425 @@ +/* + * Copyright (C) 2005-2008 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * This file is released under the GPL. + * + * WARNING: this is Alpha software wich can corrupt your data! + * + * + * Linux 2.6 Device Mapper RAID4 and RAID5 target. + * + * Supports: + * o RAID4 with dedicated and selectable parity device + * o RAID5 with rotating parity (left+right, symmetric+asymmetric) + * + * + * Thanks to MD for: + * o the raid address calculation algorithm + * o the base of the biovec <-> page list copier. + * + * + * Uses region hash to keep track of how many writes are in flight to + * regions in order to use dirty log to keep state of regions to recover: + * + * o clean regions (those which are synchronized + * and don't have write io in flight) + * o dirty regions (those with write io in flight) + * + * + * On startup, any dirty regions are migrated to the 'nosync' state + * and are subject to recovery by the daemon. + * + * See raid_ctr() for table definition. + * + * + * FIXME: + * o add virtual interface for locking + * o remove instrumentation (REMOVEME:) + * + */ + +static const char *version = "v0.2427"; + +#include "dm.h" +#include "dm-bio-list.h" +#include +#include +#include "dm-mem-cache.h" +#include "dm-message.h" +#include "dm-region_hash.h" +#include "dm-raid4-5.h" +#include +#include + +#define STR_LEN(ptr, str) ptr, str, strlen(ptr) +/* + * Configurable parameters + */ +#define INLINE + +/* Default # of stripes if not set in constructor. */ +#define STRIPES 64 + +/* Minimum/maximum # of selectable stripes. */ +#define STRIPES_MIN 8 +#define STRIPES_MAX 16384 + +/* Default chunk size in sectors if not set in constructor. */ +#define CHUNK_SIZE 64 + +/* Default io size in sectors if not set in constructor. */ +#define IO_SIZE_MIN SECTORS_PER_PAGE +#define IO_SIZE IO_SIZE_MIN + +/* Maximum setable chunk size in sectors. */ +#define CHUNK_SIZE_MAX 16384 + +/* Recover io size default in sectors. */ +#define RECOVER_IO_SIZE_MIN 64 +#define RECOVER_IO_SIZE 256 + +/* Default percentage recover io bandwidth. */ +#define BANDWIDTH 10 +#define BANDWIDTH_MIN 1 +#define BANDWIDTH_MAX 100 +/* + * END Configurable parameters + */ + +#define TARGET "dm-raid45" +#define DAEMON "kraid45d" +#define DM_MSG_PREFIX TARGET + +#define SECTORS_PER_PAGE (PAGE_SIZE >> SECTOR_SHIFT) + +/* Amount/size for __xor(). */ +#define SECTORS_PER_XOR SECTORS_PER_PAGE +#define XOR_SIZE PAGE_SIZE + +/* Derive raid_set from stripe_cache pointer. */ +#define RS(x) container_of(x, struct raid_set, sc) + +/* Check value in range. */ +#define range_ok(i, min, max) (i >= min && i <= max) + +/* Page reference. */ +#define PAGE(stripe, p) ((stripe)->obj[p].pl->page) + +/* Bio list reference. */ +#define BL(stripe, p, rw) (stripe->ss[p].bl + rw) + +/* Page list reference. */ +#define PL(stripe, p) (stripe->obj[p].pl) + +/* Check argument is power of 2. */ +#define POWER_OF_2(a) (!(a & (a - 1))) + +/* xor optimization. */ +typedef unsigned long xor_t; + +/* Factor out to dm-bio-list.h */ +static inline void bio_list_push(struct bio_list *bl, struct bio *bio) +{ + bio->bi_next = bl->head; + bl->head = bio; + + if (!bl->tail) + bl->tail = bio; +} + +/* Factor out to dm.h */ +#define TI_ERR_RET(str, ret) \ + do { ti->error = DM_MSG_PREFIX ": " str; return ret; } while(0); +#define TI_ERR(str) TI_ERR_RET(str, -EINVAL) + +/*----------------------------------------------------------------- + * Stripe cache + * + * Cache for all reads and writes to raid sets (operational or degraded) + * + * We need to run all data to and from a RAID set through this cache, + * because parity chunks need to get calculated from data chunks + * or, in the degraded/resynchronization case, missing chunks need + * to be reconstructed using the other chunks of the stripe. + *---------------------------------------------------------------*/ +/* Protect kmem cache # counter. */ +static atomic_t _stripe_sc_nr = ATOMIC_INIT(-1); /* kmem cache # counter. */ + +/* A stripe set (holds bios hanging off). */ +struct stripe_set { + struct stripe *stripe; /* Backpointer to stripe for endio(). */ + struct bio_list bl[3]; /* Reads, writes, and writes merged. */ +#define WRITE_MERGED 2 +}; + +#if READ != 0 || WRITE != 1 +#error dm-raid45: READ/WRITE != 0/1 used as index!!! +#endif + +/* + * Stripe linked list indexes. Keep order, because the stripe + * and the stripe cache rely on the first 3! + */ +enum list_types { + LIST_IO = 0, /* Stripes with io pending. */ + LIST_ENDIO, /* Stripes to endio. */ + LIST_LRU, /* Least recently used stripes. */ + LIST_HASH, /* Hashed stripes. */ + NR_LISTS, /* To size array in struct stripe. */ +}; + +enum lock_types { + LOCK_ENDIO = 0, /* Protect endio list. */ + LOCK_LRU, /* Protect lru list. */ + NR_LOCKS, /* To size array in struct stripe_cache. */ +}; + +/* A stripe: the io object to handle all reads and writes to a RAID set. */ +struct stripe { + struct stripe_cache *sc; /* Backpointer to stripe cache. */ + + sector_t key; /* Hash key. */ + sector_t region; /* Region stripe is mapped to. */ + + /* Reference count. */ + atomic_t cnt; + + struct { + unsigned long flags; /* flags (see below). */ + + /* + * Pending ios in flight: + * + * used as a 'lock' to control move of stripe to endio list + */ + atomic_t pending; /* Pending ios in flight. */ + + /* Sectors to read and write for multi page stripe sets. */ + unsigned size; + } io; + + /* Lock on stripe (for clustering). */ + void *lock; + + /* + * 4 linked lists: + * o io list to flush io + * o endio list + * o LRU list to put stripes w/o reference count on + * o stripe cache hash + */ + struct list_head lists[NR_LISTS]; + + struct { + unsigned short parity; /* Parity chunk index. */ + short recover; /* Recovery chunk index. */ + } idx; + + /* This sets memory cache object (dm-mem-cache). */ + struct dm_mem_cache_object *obj; + + /* Array of stripe sets (dynamically allocated). */ + struct stripe_set ss[0]; +}; + +/* States stripes can be in (flags field). */ +enum stripe_states { + STRIPE_ACTIVE, /* Active io on stripe. */ + STRIPE_ERROR, /* io error on stripe. */ + STRIPE_MERGED, /* Writes got merged. */ + STRIPE_READ, /* Read. */ + STRIPE_RBW, /* Read-before-write. */ + STRIPE_RECONSTRUCT, /* reconstruct of a missing chunk required. */ + STRIPE_RECOVER, /* Stripe used for RAID set recovery. */ +}; + +/* ... and macros to access them. */ +#define BITOPS(name, what, var, flag) \ +static inline int TestClear ## name ## what(struct var *v) \ +{ return test_and_clear_bit(flag, &v->io.flags); } \ +static inline int TestSet ## name ## what(struct var *v) \ +{ return test_and_set_bit(flag, &v->io.flags); } \ +static inline void Clear ## name ## what(struct var *v) \ +{ clear_bit(flag, &v->io.flags); } \ +static inline void Set ## name ## what(struct var *v) \ +{ set_bit(flag, &v->io.flags); } \ +static inline int name ## what(struct var *v) \ +{ return test_bit(flag, &v->io.flags); } + + +BITOPS(Stripe, Active, stripe, STRIPE_ACTIVE) +BITOPS(Stripe, Merged, stripe, STRIPE_MERGED) +BITOPS(Stripe, Error, stripe, STRIPE_ERROR) +BITOPS(Stripe, Read, stripe, STRIPE_READ) +BITOPS(Stripe, RBW, stripe, STRIPE_RBW) +BITOPS(Stripe, Reconstruct, stripe, STRIPE_RECONSTRUCT) +BITOPS(Stripe, Recover, stripe, STRIPE_RECOVER) + +/* A stripe hash. */ +struct stripe_hash { + struct list_head *hash; + unsigned buckets; + unsigned mask; + unsigned prime; + unsigned shift; +}; + +/* A stripe cache. */ +struct stripe_cache { + /* Stripe hash. */ + struct stripe_hash hash; + + /* Stripes with io to flush, stripes to endio and LRU lists. */ + struct list_head lists[3]; + + /* Locks to protect endio and lru lists. */ + spinlock_t locks[NR_LOCKS]; + + /* Slab cache to allocate stripes from. */ + struct { + struct kmem_cache *cache; /* Cache itself. */ + char name[32]; /* Unique name. */ + } kc; + + struct dm_io_client *dm_io_client; /* dm-io client resource context. */ + + /* dm-mem-cache client resource context. */ + struct dm_mem_cache_client *dm_mem_cache_client; + + int stripes_parm; /* # stripes parameter from constructor. */ + atomic_t stripes; /* actual # of stripes in cache. */ + atomic_t stripes_to_shrink; /* # of stripes to shrink cache by. */ + atomic_t stripes_last; /* last # of stripes in cache. */ + atomic_t active_stripes; /* actual # of active stripes in cache. */ + + /* REMOVEME: */ + atomic_t max_active_stripes; /* actual # of active stripes in cache. */ +}; + +/* Flag specs for raid_dev */ ; +enum raid_dev_flags { DEVICE_FAILED, IO_QUEUED }; + +/* The raid device in a set. */ +struct raid_dev { + struct dm_dev *dev; + unsigned long flags; /* raid_dev_flags. */ + sector_t start; /* offset to map to. */ +}; + +/* Flags spec for raid_set. */ +enum raid_set_flags { + RS_CHECK_OVERWRITE, /* Check for chunk overwrites. */ + RS_DEAD, /* RAID set inoperational. */ + RS_DEVEL_STATS, /* REMOVEME: display status information. */ + RS_IO_ERROR, /* io error on set. */ + RS_RECOVER, /* Do recovery. */ + RS_RECOVERY_BANDWIDTH, /* Allow recovery bandwidth (delayed bios). */ + RS_REGION_GET, /* get a region to recover. */ + RS_SC_BUSY, /* stripe cache busy -> send an event. */ + RS_SUSPENDED, /* RAID set suspendedn. */ +}; + +/* REMOVEME: devel stats counters. */ +enum stats_types { + S_BIOS_READ, + S_BIOS_ADDED_READ, + S_BIOS_ENDIO_READ, + S_BIOS_WRITE, + S_BIOS_ADDED_WRITE, + S_BIOS_ENDIO_WRITE, + S_CAN_MERGE, + S_CANT_MERGE, + S_CONGESTED, + S_DM_IO_READ, + S_DM_IO_WRITE, + S_ACTIVE_READS, + S_BANDWIDTH, + S_BARRIER, + S_BIO_COPY_PL_NEXT, + S_DEGRADED, + S_DELAYED_BIOS, + S_EVICT, + S_FLUSHS, + S_HITS_1ST, + S_IOS_POST, + S_INSCACHE, + S_MAX_LOOKUP, + S_MERGE_PAGE_LOCKED, + S_NO_BANDWIDTH, + S_NOT_CONGESTED, + S_NO_RW, + S_NOSYNC, + S_PROHIBITPAGEIO, + S_RECONSTRUCT_EI, + S_RECONSTRUCT_DEV, + S_REDO, + S_REQUEUE, + S_STRIPE_ERROR, + S_SUM_DELAYED_BIOS, + S_XORS, + S_NR_STATS, /* # of stats counters. */ +}; + +/* Status type -> string mappings. */ +struct stats_map { + const enum stats_types type; + const char *str; +}; + +static struct stats_map stats_map[] = { + { S_BIOS_READ, "r=" }, + { S_BIOS_ADDED_READ, "/" }, + { S_BIOS_ENDIO_READ, "/" }, + { S_BIOS_WRITE, " w=" }, + { S_BIOS_ADDED_WRITE, "/" }, + { S_BIOS_ENDIO_WRITE, "/" }, + { S_DM_IO_READ, " rc=" }, + { S_DM_IO_WRITE, " wc=" }, + { S_ACTIVE_READS, " active_reads=" }, + { S_BANDWIDTH, " bandwidth=" }, + { S_NO_BANDWIDTH, " no_bandwidth=" }, + { S_BARRIER, " barrier=" }, + { S_BIO_COPY_PL_NEXT, " bio_copy_pl_next=" }, + { S_CAN_MERGE, " can_merge=" }, + { S_MERGE_PAGE_LOCKED, "/page_locked=" }, + { S_CANT_MERGE, "/cant_merge=" }, + { S_CONGESTED, " congested=" }, + { S_NOT_CONGESTED, "/not_congested=" }, + { S_DEGRADED, " degraded=" }, + { S_DELAYED_BIOS, " delayed_bios=" }, + { S_SUM_DELAYED_BIOS, "/sum_delayed_bios=" }, + { S_EVICT, " evict=" }, + { S_FLUSHS, " flushs=" }, + { S_HITS_1ST, " hits_1st=" }, + { S_IOS_POST, " ios_post=" }, + { S_INSCACHE, " inscache=" }, + { S_MAX_LOOKUP, " max_lookup=" }, + { S_NO_RW, " no_rw=" }, + { S_NOSYNC, " nosync=" }, + { S_PROHIBITPAGEIO, " ProhibitPageIO=" }, + { S_RECONSTRUCT_EI, " reconstruct_ei=" }, + { S_RECONSTRUCT_DEV, " reconstruct_dev=" }, + { S_REDO, " redo=" }, + { S_REQUEUE, " requeue=" }, + { S_STRIPE_ERROR, " stripe_error=" }, + { S_XORS, " xors=" }, +}; + +/* + * A RAID set. + */ +typedef void (*xor_function_t)(unsigned count, xor_t **data); +struct raid_set { + struct dm_target *ti; /* Target pointer. */ + + struct { + unsigned long flags; /* State flags. */ + spinlock_t in_lock; /* Protects central input list below. */ + struct bio_list in; /* Pending ios (central input list). */ + struct bio_list work; /* ios work set. */ + wait_queue_head_t suspendq; /* suspend synchronization. */ + atomic_t in_process; /* counter of queued bios (suspendq). */ + atomic_t in_process_max;/* counter of queued bios max. */ + + /* io work. */ + struct workqueue_struct *wq; + struct delayed_work dws; + } io; + + /* External locking. */ + struct dmraid45_locking_type *locking; + + struct stripe_cache sc; /* Stripe cache for this set. */ + + /* Xor optimization. */ + struct { + struct xor_func *f; + unsigned chunks; + unsigned speed; + } xor; + + /* Recovery parameters. */ + struct recover { + struct dm_dirty_log *dl; /* Dirty log. */ + void *rh; /* Region hash. */ + + region_t nr_regions; + region_t nr_regions_to_recover; + region_t nr_regions_recovered; + unsigned long start_jiffies; + unsigned long end_jiffies; + + unsigned bandwidth; /* Recovery bandwidth [%]. */ + unsigned bandwidth_work; /* Recovery bandwidth [factor]. */ + unsigned bandwidth_parm; /* " constructor parm. */ + unsigned io_size; /* io size <= chunk size. */ + unsigned io_size_parm; /* io size ctr parameter. */ + + /* recovery io throttling. */ + atomic_t io_count[2]; /* counter recover/regular io. */ + unsigned long last_jiffies; + + void *reg; /* Actual region to recover. */ + struct stripe *stripe; /* Stripe used for recovery. */ + sector_t pos; /* Position within region to recover. */ + sector_t end; /* End of region to recover. */ + } recover; + + /* RAID set parameters. */ + struct { + struct raid_type *raid_type; /* RAID type (eg, RAID4). */ + unsigned raid_parms; /* # variable raid parameters. */ + + unsigned chunk_size; /* Sectors per chunk. */ + unsigned chunk_size_parm; + unsigned chunk_mask; /* Mask for amount. */ + unsigned chunk_shift; /* rsector chunk size shift. */ + + unsigned io_size; /* Sectors per io. */ + unsigned io_size_parm; + unsigned io_mask; /* Mask for amount. */ + unsigned io_shift_mask; /* Mask for raid_address(). */ + unsigned io_shift; /* rsector io size shift. */ + unsigned pages_per_io; /* Pages per io. */ + + sector_t sectors_per_dev; /* Sectors per device. */ + + atomic_t failed_devs; /* Amount of devices failed. */ + + /* Index of device to initialize. */ + int dev_to_init; + int dev_to_init_parm; + + /* Raid devices dynamically allocated. */ + unsigned raid_devs; /* # of RAID devices below. */ + unsigned data_devs; /* # of RAID data devices. */ + + int ei; /* index of failed RAID device. */ + + /* index of dedicated parity device (i.e. RAID4). */ + int pi; + int pi_parm; /* constructor parm for status output. */ + } set; + + /* REMOVEME: devel stats counters. */ + atomic_t stats[S_NR_STATS]; + + /* Dynamically allocated temporary pointers for xor(). */ + xor_t **data; + + /* Dynamically allocated RAID devices. Alignment? */ + struct raid_dev dev[0]; +}; + + +BITOPS(RS, Bandwidth, raid_set, RS_RECOVERY_BANDWIDTH) +BITOPS(RS, CheckOverwrite, raid_set, RS_CHECK_OVERWRITE) +BITOPS(RS, Dead, raid_set, RS_DEAD) +BITOPS(RS, DevelStats, raid_set, RS_DEVEL_STATS) +BITOPS(RS, IoError, raid_set, RS_IO_ERROR) +BITOPS(RS, Recover, raid_set, RS_RECOVER) +BITOPS(RS, RegionGet, raid_set, RS_REGION_GET) +BITOPS(RS, ScBusy, raid_set, RS_SC_BUSY) +BITOPS(RS, Suspended, raid_set, RS_SUSPENDED) +#undef BITOPS + +#define PageIO(page) PageChecked(page) +#define AllowPageIO(page) SetPageChecked(page) +#define ProhibitPageIO(page) ClearPageChecked(page) + +/*----------------------------------------------------------------- + * Raid-4/5 set structures. + *---------------------------------------------------------------*/ +/* RAID level definitions. */ +enum raid_level { + raid4, + raid5, +}; + +/* Symmetric/Asymmetric, Left/Right parity rotating algorithms. */ +enum raid_algorithm { + none, + left_asym, + right_asym, + left_sym, + right_sym, +}; + +struct raid_type { + const char *name; /* RAID algorithm. */ + const char *descr; /* Descriptor text for logging. */ + const unsigned parity_devs; /* # of parity devices. */ + const unsigned minimal_devs; /* minimal # of devices in set. */ + const enum raid_level level; /* RAID level. */ + const enum raid_algorithm algorithm; /* RAID algorithm. */ +}; + +/* Supported raid types and properties. */ +static struct raid_type raid_types[] = { + {"raid4", "RAID4 (dedicated parity disk)", 1, 3, raid4, none}, + {"raid5_la", "RAID5 (left asymmetric)", 1, 3, raid5, left_asym}, + {"raid5_ra", "RAID5 (right asymmetric)", 1, 3, raid5, right_asym}, + {"raid5_ls", "RAID5 (left symmetric)", 1, 3, raid5, left_sym}, + {"raid5_rs", "RAID5 (right symmetric)", 1, 3, raid5, right_sym}, +}; + +/* Address as calculated by raid_address(). */ +struct address { + sector_t key; /* Hash key (start address of stripe). */ + unsigned di, pi; /* Data and parity disks index. */ +}; + +static inline void set_page_locked(struct page *page) { set_bit(PG_locked, &page->flags); } +static inline void clear_page_locked(struct page *page) { clear_bit(PG_locked, &page->flags); } + +/* REMOVEME: reset statistics counters. */ +static void stats_reset(struct raid_set *rs) +{ + unsigned s = S_NR_STATS; + + while (s--) + atomic_set(rs->stats + s, 0); +} + +/*---------------------------------------------------------------- + * RAID set management routines. + *--------------------------------------------------------------*/ +/* + * Begin small helper functions. + */ +/* Queue (optionally delayed) io work. */ +static void wake_do_raid_delayed(struct raid_set *rs, unsigned long delay) +{ + struct delayed_work *dws = &rs->io.dws; + + cancel_delayed_work(dws); + queue_delayed_work(rs->io.wq, dws, delay); +} + +/* Queue io work immediately (called from region hash too). */ +static INLINE void wake_do_raid(void *context) +{ + wake_do_raid_delayed(context, 0); +} + +/* Wait until all io has been processed. */ +static INLINE void wait_ios(struct raid_set *rs) +{ + wait_event(rs->io.suspendq, !atomic_read(&rs->io.in_process)); +} + +/* Declare io queued to device. */ +static INLINE void io_dev_queued(struct raid_dev *dev) +{ + set_bit(IO_QUEUED, &dev->flags); +} + +/* Io on device and reset ? */ +static inline int io_dev_clear(struct raid_dev *dev) +{ + return test_and_clear_bit(IO_QUEUED, &dev->flags); +} + +/* Get an io reference. */ +static INLINE void io_get(struct raid_set *rs) +{ + int p = atomic_inc_return(&rs->io.in_process); + + if (p > atomic_read(&rs->io.in_process_max)) + atomic_set(&rs->io.in_process_max, p); /* REMOVEME: max. */ +} + +/* Put the io reference and conditionally wake io waiters. */ +static INLINE void io_put(struct raid_set *rs) +{ + if (atomic_dec_and_test(&rs->io.in_process)) + wake_up(&rs->io.suspendq); +} + +/* Calculate device sector offset. */ +static INLINE sector_t _sector(struct raid_set *rs, struct bio *bio) +{ + sector_t sector = bio->bi_sector; + + sector_div(sector, rs->set.data_devs); + return sector; +} + +/* Test device operational. */ +static INLINE int dev_operational(struct raid_set *rs, unsigned p) +{ + return !test_bit(DEVICE_FAILED, &rs->dev[p].flags); +} + +/* Return # of active stripes in stripe cache. */ +static INLINE int sc_active(struct stripe_cache *sc) +{ + return atomic_read(&sc->active_stripes); +} + +/* Test io pending on stripe. */ +static INLINE int stripe_io(struct stripe *stripe) +{ + return atomic_read(&stripe->io.pending); +} + +static INLINE void stripe_io_inc(struct stripe *stripe) +{ + atomic_inc(&stripe->io.pending); +} + +static INLINE void stripe_io_dec(struct stripe *stripe) +{ + atomic_dec(&stripe->io.pending); +} + +/* Wrapper needed by for_each_io_dev(). */ +static void _stripe_io_inc(struct stripe *stripe, unsigned p) +{ + stripe_io_inc(stripe); +} + +/* Error a stripe. */ +static INLINE void stripe_error(struct stripe *stripe, struct page *page) +{ + SetStripeError(stripe); + SetPageError(page); + atomic_inc(RS(stripe->sc)->stats + S_STRIPE_ERROR); +} + +/* Page IOed ok. */ +enum dirty_type { CLEAN, DIRTY }; +static INLINE void page_set(struct page *page, enum dirty_type type) +{ + switch (type) { + case DIRTY: + SetPageDirty(page); + AllowPageIO(page); + break; + + case CLEAN: + ClearPageDirty(page); + break; + + default: + BUG(); + } + + SetPageUptodate(page); + ClearPageError(page); +} + +/* Return region state for a sector. */ +static INLINE int +region_state(struct raid_set *rs, sector_t sector, unsigned long state) +{ + void *rh = rs->recover.rh; + + if (unlikely(RSRecover(rs))) + return rh_state(rh, rh_sector_to_region(rh, sector), 1) & state; + else + return 0; +} + +/* Check maximum devices which may fail in a raid set. */ +static inline int raid_set_degraded(struct raid_set *rs) +{ + return RSIoError(rs); +} + +/* Check # of devices which may fail in a raid set. */ +static INLINE int raid_set_operational(struct raid_set *rs) +{ + /* Too many failed devices -> BAD. */ + return atomic_read(&rs->set.failed_devs) <= + rs->set.raid_type->parity_devs; +} + +/* + * Return true in case a page_list should be read/written + * + * Conditions to read/write: + * o 1st page in list not uptodate + * o 1st page in list dirty + * o if we optimized io away, we flag it using the pages checked bit. + */ +static INLINE unsigned page_io(struct page *page) +{ + /* Optimization: page was flagged to need io during first run. */ + if (PagePrivate(page)) { + ClearPagePrivate(page); + return 1; + } + + /* Avoid io if prohibited or a locked page. */ + if (!PageIO(page) || PageLocked(page)) + return 0; + + if (!PageUptodate(page) || PageDirty(page)) { + /* Flag page needs io for second run optimization. */ + SetPagePrivate(page); + return 1; + } + + return 0; +} + +/* Call a function on each page list needing io. */ +static INLINE unsigned +for_each_io_dev(struct raid_set *rs, struct stripe *stripe, + void (*f_io)(struct stripe *stripe, unsigned p)) +{ + unsigned p = rs->set.raid_devs, r = 0; + + while (p--) { + if (page_io(PAGE(stripe, p))) { + f_io(stripe, p); + r++; + } + } + + return r; +} + +/* Reconstruct a particular device ?. */ +static INLINE int dev_to_init(struct raid_set *rs) +{ + return rs->set.dev_to_init > -1; +} + +/* Index of device to calculate parity on. */ +static INLINE unsigned dev_for_parity(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + + return dev_to_init(rs) ? rs->set.dev_to_init : stripe->idx.parity; +} + +/* Return the index of the device to be recovered. */ +static int idx_get(struct raid_set *rs) +{ + /* Avoid to read in the pages to be reconstructed anyway. */ + if (dev_to_init(rs)) + return rs->set.dev_to_init; + else if (rs->set.raid_type->level == raid4) + return rs->set.pi; + + return -1; +} + +/* RAID set congested function. */ +static int raid_set_congested(void *congested_data, int bdi_bits) +{ + struct raid_set *rs = congested_data; + int r = 0; /* Assume uncongested. */ + unsigned p = rs->set.raid_devs; + + /* If any of our component devices are overloaded. */ + while (p--) + r |= bdi_congested(&bdev_get_queue(rs->dev[p].dev->bdev)->backing_dev_info, bdi_bits); + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (r ? S_CONGESTED : S_NOT_CONGESTED)); + return r; +} + +/* Display RAID set dead message once. */ +static void raid_set_dead(struct raid_set *rs) +{ + if (!TestSetRSDead(rs)) { + unsigned p; + char buf[BDEVNAME_SIZE]; + + DMERR("FATAL: too many devices failed -> RAID set dead"); + + for (p = 0; p < rs->set.raid_devs; p++) { + if (!dev_operational(rs, p)) + DMERR("device /dev/%s failed", + bdevname(rs->dev[p].dev->bdev, buf)); + } + } +} + +/* RAID set degrade check. */ +static INLINE int +raid_set_check_and_degrade(struct raid_set *rs, + struct stripe *stripe, unsigned p) +{ + if (test_and_set_bit(DEVICE_FAILED, &rs->dev[p].flags)) + return -EPERM; + + /* Through an event in case of member device errors. */ + dm_table_event(rs->ti->table); + atomic_inc(&rs->set.failed_devs); + + /* Only log the first member error. */ + if (!TestSetRSIoError(rs)) { + char buf[BDEVNAME_SIZE]; + + /* Store index for recovery. */ + mb(); + rs->set.ei = p; + mb(); + + DMERR("CRITICAL: %sio error on device /dev/%s " + "in region=%llu; DEGRADING RAID set", + stripe ? "" : "FAKED ", + bdevname(rs->dev[p].dev->bdev, buf), + (unsigned long long) (stripe ? stripe->key : 0)); + DMERR("further device error messages suppressed"); + } + + return 0; +} + +static void +raid_set_check_degrade(struct raid_set *rs, struct stripe *stripe) +{ + unsigned p = rs->set.raid_devs; + + while (p--) { + struct page *page = PAGE(stripe, p); + + if (PageError(page)) { + ClearPageError(page); + raid_set_check_and_degrade(rs, stripe, p); + } + } +} + +/* RAID set upgrade check. */ +static int raid_set_check_and_upgrade(struct raid_set *rs, unsigned p) +{ + if (!test_and_clear_bit(DEVICE_FAILED, &rs->dev[p].flags)) + return -EPERM; + + if (atomic_dec_and_test(&rs->set.failed_devs)) { + ClearRSIoError(rs); + rs->set.ei = -1; + } + + return 0; +} + +/* Lookup a RAID device by name or by major:minor number. */ +union dev_lookup { + const char *dev_name; + struct raid_dev *dev; +}; +enum lookup_type { byname, bymajmin, bynumber }; +static int raid_dev_lookup(struct raid_set *rs, enum lookup_type by, + union dev_lookup *dl) +{ + unsigned p; + + /* + * Must be an incremental loop, because the device array + * can have empty slots still on calls from raid_ctr() + */ + for (p = 0; p < rs->set.raid_devs; p++) { + char buf[BDEVNAME_SIZE]; + struct raid_dev *dev = rs->dev + p; + + if (!dev->dev) + break; + + /* Format dev string appropriately if necessary. */ + if (by == byname) + bdevname(dev->dev->bdev, buf); + else if (by == bymajmin) + format_dev_t(buf, dev->dev->bdev->bd_dev); + + /* Do the actual check. */ + if (by == bynumber) { + if (dl->dev->dev->bdev->bd_dev == + dev->dev->bdev->bd_dev) + return p; + } else if (!strcmp(dl->dev_name, buf)) + return p; + } + + return -ENODEV; +} + +/* End io wrapper. */ +static INLINE void +_bio_endio(struct raid_set *rs, struct bio *bio, int error) +{ + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (bio_data_dir(bio) == WRITE ? + S_BIOS_ENDIO_WRITE : S_BIOS_ENDIO_READ)); + bio_endio(bio, error); + io_put(rs); /* Wake any suspend waiters. */ +} + +/* + * End small helper functions. + */ + + +/* + * Stripe hash functions + */ +/* Initialize/destroy stripe hash. */ +static int hash_init(struct stripe_hash *hash, unsigned stripes) +{ + unsigned buckets = 1, max_buckets = stripes / 4; + unsigned hash_primes[] = { + /* Table of primes for hash_fn/table size optimization. */ + 3, 7, 13, 27, 53, 97, 193, 389, 769, + 1543, 3079, 6151, 12289, 24593, + }; + + /* Calculate number of buckets (2^^n <= stripes / 4). */ + while ((buckets <<= 1) < max_buckets); + + /* Allocate stripe hash. */ + hash->hash = vmalloc(buckets * sizeof(*hash->hash)); + if (!hash->hash) + return -ENOMEM; + + hash->buckets = buckets; + hash->mask = buckets - 1; + hash->shift = ffs(buckets); + if (hash->shift > ARRAY_SIZE(hash_primes) + 1) + hash->shift = ARRAY_SIZE(hash_primes) + 1; + + BUG_ON(hash->shift - 2 > ARRAY_SIZE(hash_primes) + 1); + hash->prime = hash_primes[hash->shift - 2]; + + /* Initialize buckets. */ + while (buckets--) + INIT_LIST_HEAD(hash->hash + buckets); + + return 0; +} + +static INLINE void hash_exit(struct stripe_hash *hash) +{ + if (hash->hash) { + vfree(hash->hash); + hash->hash = NULL; + } +} + +/* List add (head/tail/locked/unlocked) inlines. */ +enum list_lock_type { LIST_LOCKED, LIST_UNLOCKED }; +#define LIST_DEL(name, list) \ +static void stripe_ ## name ## _del(struct stripe *stripe, \ + enum list_lock_type lock) { \ + struct list_head *lh = stripe->lists + (list); \ + spinlock_t *l = NULL; \ +\ + if (lock == LIST_LOCKED) { \ + l = stripe->sc->locks + LOCK_LRU; \ + spin_lock_irq(l); \ + } \ +\ +\ + if (!list_empty(lh)) \ + list_del_init(lh); \ +\ + if (lock == LIST_LOCKED) \ + spin_unlock_irq(l); \ +} + +LIST_DEL(hash, LIST_HASH) +LIST_DEL(lru, LIST_LRU) +#undef LIST_DEL + +enum list_pos_type { POS_HEAD, POS_TAIL }; +#define LIST_ADD(name, list) \ +static void stripe_ ## name ## _add(struct stripe *stripe, \ + enum list_pos_type pos, \ + enum list_lock_type lock) { \ + struct list_head *lh = stripe->lists + (list); \ + struct stripe_cache *sc = stripe->sc; \ + spinlock_t *l = NULL; \ +\ + if (lock == LIST_LOCKED) { \ + l = sc->locks + LOCK_LRU; \ + spin_lock_irq(l); \ + } \ +\ + if (list_empty(lh)) { \ + if (pos == POS_HEAD) \ + list_add(lh, sc->lists + (list)); \ + else \ + list_add_tail(lh, sc->lists + (list)); \ + } \ +\ + if (lock == LIST_LOCKED) \ + spin_unlock_irq(l); \ +} + +LIST_ADD(endio, LIST_ENDIO) +LIST_ADD(io, LIST_IO) +LIST_ADD(lru, LIST_LRU) +#undef LIST_ADD + +#define POP(list) \ + if (list_empty(sc->lists + list)) \ + stripe = NULL; \ + else { \ + stripe = list_entry(sc->lists[list].next, struct stripe, \ + lists[list]); \ + list_del_init(&stripe->lists[list]); \ + } + +/* Pop an available stripe off the lru list. */ +static struct stripe *stripe_lru_pop(struct stripe_cache *sc) +{ + struct stripe *stripe; + spinlock_t *lock = sc->locks + LOCK_LRU; + + spin_lock_irq(lock); + POP(LIST_LRU); + spin_unlock_irq(lock); + + if (stripe) + /* Remove from hash before reuse. */ + stripe_hash_del(stripe, LIST_UNLOCKED); + + return stripe; +} + +static inline unsigned hash_fn(struct stripe_hash *hash, sector_t key) +{ + return (unsigned) (((key * hash->prime) >> hash->shift) & hash->mask); +} + +static inline struct list_head * +hash_bucket(struct stripe_hash *hash, sector_t key) +{ + return hash->hash + hash_fn(hash, key); +} + +/* Insert an entry into a hash. */ +static inline void hash_insert(struct stripe_hash *hash, struct stripe *stripe) +{ + list_add(stripe->lists + LIST_HASH, hash_bucket(hash, stripe->key)); +} + +/* Insert an entry into the stripe hash. */ +static inline void +sc_insert(struct stripe_cache *sc, struct stripe *stripe) +{ + hash_insert(&sc->hash, stripe); +} + +/* Lookup an entry in the stripe hash. */ +static inline struct stripe * +stripe_lookup(struct stripe_cache *sc, sector_t key) +{ + unsigned c = 0; + struct stripe *stripe; + struct list_head *bucket = hash_bucket(&sc->hash, key); + + list_for_each_entry(stripe, bucket, lists[LIST_HASH]) { + /* REMOVEME: statisics. */ + if (++c > atomic_read(RS(sc)->stats + S_MAX_LOOKUP)) + atomic_set(RS(sc)->stats + S_MAX_LOOKUP, c); + + if (stripe->key == key) + return stripe; + } + + return NULL; +} + +/* Resize the stripe cache hash on size changes. */ +static int hash_resize(struct stripe_cache *sc) +{ + /* Resize threshold reached? */ + if (atomic_read(&sc->stripes) > 2 * atomic_read(&sc->stripes_last) + || atomic_read(&sc->stripes) < atomic_read(&sc->stripes_last) / 4) { + int r; + struct stripe_hash hash, hash_tmp; + spinlock_t *lock; + + r = hash_init(&hash, atomic_read(&sc->stripes)); + if (r) + return r; + + lock = sc->locks + LOCK_LRU; + spin_lock_irq(lock); + if (sc->hash.hash) { + unsigned b = sc->hash.buckets; + struct list_head *pos, *tmp; + + /* Walk old buckets and insert into new. */ + while (b--) { + list_for_each_safe(pos, tmp, sc->hash.hash + b) + hash_insert(&hash, + list_entry(pos, struct stripe, + lists[LIST_HASH])); + } + + } + + memcpy(&hash_tmp, &sc->hash, sizeof(hash_tmp)); + memcpy(&sc->hash, &hash, sizeof(sc->hash)); + atomic_set(&sc->stripes_last, atomic_read(&sc->stripes)); + spin_unlock_irq(lock); + + hash_exit(&hash_tmp); + } + + return 0; +} + +/* + * Stripe cache locking functions + */ +/* Dummy lock function for local RAID4+5. */ +static void *no_lock(sector_t key, enum lock_type type) +{ + return &no_lock; +} + +/* Dummy unlock function for local RAID4+5. */ +static void no_unlock(void *lock_handle) +{ +} + +/* No locking (for local RAID 4+5). */ +static struct dmraid45_locking_type locking_none = { + .lock = no_lock, + .unlock = no_unlock, +}; + +/* Clustered RAID 4+5. */ +/* FIXME: code this. */ +static struct dmraid45_locking_type locking_cluster = { + .lock = no_lock, + .unlock = no_unlock, +}; + +/* Lock a stripe (for clustering). */ +static int +stripe_lock(struct raid_set *rs, struct stripe *stripe, int rw, sector_t key) +{ + stripe->lock = rs->locking->lock(key, rw == READ ? RAID45_SHARED : + RAID45_EX); + return stripe->lock ? 0 : -EPERM; +} + +/* Unlock a stripe (for clustering). */ +static void stripe_unlock(struct raid_set *rs, struct stripe *stripe) +{ + rs->locking->unlock(stripe->lock); + stripe->lock = NULL; +} + +/* + * Stripe cache functions. + */ +/* + * Invalidate all page lists pages of a stripe. + * + * I only keep state for the whole list in the first page. + */ +static INLINE void +stripe_pages_invalidate(struct stripe *stripe) +{ + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) { + struct page *page = PAGE(stripe, p); + + ProhibitPageIO(page); + ClearPageChecked(page); + ClearPageDirty(page); + ClearPageError(page); + clear_page_locked(page); + ClearPagePrivate(page); + ClearPageUptodate(page); + } +} + +/* Prepare stripe for (re)use. */ +static INLINE void stripe_invalidate(struct stripe *stripe) +{ + stripe->io.flags = 0; + stripe_pages_invalidate(stripe); +} + +/* Allow io on all chunks of a stripe. */ +static INLINE void stripe_allow_io(struct stripe *stripe) +{ + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) + AllowPageIO(PAGE(stripe, p)); +} + +/* Initialize a stripe. */ +static void +stripe_init(struct stripe_cache *sc, struct stripe *stripe, unsigned io_size) +{ + unsigned p = RS(sc)->set.raid_devs; + unsigned i; + + /* Work all io chunks. */ + while (p--) { + struct stripe_set *ss = stripe->ss + p; + + stripe->obj[p].private = ss; + ss->stripe = stripe; + + i = ARRAY_SIZE(ss->bl); + while (i--) + bio_list_init(ss->bl + i); + } + + stripe->sc = sc; + + i = ARRAY_SIZE(stripe->lists); + while (i--) + INIT_LIST_HEAD(&stripe->lists[i]); + + stripe->io.size = io_size; + atomic_set(&stripe->cnt, 0); + atomic_set(&stripe->io.pending, 0); + + stripe_invalidate(stripe); +} + +/* Number of pages per chunk. */ +static inline unsigned chunk_pages(unsigned io_size) +{ + return dm_div_up(io_size, SECTORS_PER_PAGE); +} + +/* Number of pages per stripe. */ +static inline unsigned stripe_pages(struct raid_set *rs, unsigned io_size) +{ + return chunk_pages(io_size) * rs->set.raid_devs; +} + +/* Initialize part of page_list (recovery). */ +static INLINE void stripe_zero_pl_part(struct stripe *stripe, unsigned p, + unsigned start, unsigned count) +{ + unsigned pages = chunk_pages(count); + /* Get offset into the page_list. */ + struct page_list *pl = pl_elem(PL(stripe, p), start / SECTORS_PER_PAGE); + + BUG_ON(!pl); + while (pl && pages--) { + BUG_ON(!pl->page); + memset(page_address(pl->page), 0, PAGE_SIZE); + pl = pl->next; + } +} + +/* Initialize parity chunk of stripe. */ +static INLINE void stripe_zero_chunk(struct stripe *stripe, unsigned p) +{ + stripe_zero_pl_part(stripe, p, 0, stripe->io.size); +} + +/* Return dynamic stripe structure size. */ +static INLINE size_t stripe_size(struct raid_set *rs) +{ + return sizeof(struct stripe) + + rs->set.raid_devs * sizeof(struct stripe_set); +} + +/* Allocate a stripe and its memory object. */ +enum grow { grow, keep }; +static struct stripe *stripe_alloc(struct stripe_cache *sc, + unsigned io_size, enum grow grow) +{ + int r; + unsigned pages_per_chunk = chunk_pages(io_size); + struct stripe *stripe; + + stripe = kmem_cache_alloc(sc->kc.cache, GFP_KERNEL); + if (stripe) { + memset(stripe, 0, stripe_size(RS(sc))); + + /* Grow the dm-mem-cache on request. */ + if (grow == grow) { + r = dm_mem_cache_grow(sc->dm_mem_cache_client, + pages_per_chunk); + if (r) + goto err_free; + } + + stripe->obj = dm_mem_cache_alloc(sc->dm_mem_cache_client, + pages_per_chunk); + if (!stripe->obj) + goto err_shrink; + + stripe_init(sc, stripe, io_size); + } + + return stripe; + + err_shrink: + if (grow == grow) + dm_mem_cache_shrink(sc->dm_mem_cache_client, pages_per_chunk); + err_free: + kmem_cache_free(sc->kc.cache, stripe); + return NULL; +} + +/* + * Free a stripes memory object, shrink the + * memory cache and free the stripe itself + */ +static void stripe_free(struct stripe *stripe) +{ + dm_mem_cache_free(stripe->sc->dm_mem_cache_client, stripe->obj); + dm_mem_cache_shrink(stripe->sc->dm_mem_cache_client, + chunk_pages(stripe->io.size)); + kmem_cache_free(stripe->sc->kc.cache, stripe); +} + +/* Free the recovery stripe. */ +static void stripe_recover_free(struct raid_set *rs) +{ + if (rs->recover.stripe) { + ClearRSRecover(rs); + stripe_free(rs->recover.stripe); + rs->recover.stripe = NULL; + } +} + +/* Push a stripe safely onto the endio list to be handled by do_endios(). */ +static INLINE void stripe_endio_push(struct stripe *stripe) +{ + int wake; + unsigned long flags; + struct stripe_cache *sc = stripe->sc; + spinlock_t *lock = sc->locks + LOCK_ENDIO; + + spin_lock_irqsave(lock, flags); + wake = list_empty(sc->lists + LIST_ENDIO); + stripe_endio_add(stripe, POS_HEAD, LIST_UNLOCKED); + spin_unlock_irqrestore(lock, flags); + + if (wake) + wake_do_raid(RS(sc)); +} + +/* Protected check for stripe cache endio list empty. */ +static INLINE int stripe_endio_empty(struct stripe_cache *sc) +{ + int r; + spinlock_t *lock = sc->locks + LOCK_ENDIO; + + spin_lock_irq(lock); + r = list_empty(sc->lists + LIST_ENDIO); + spin_unlock_irq(lock); + + return r; +} + +/* Pop a stripe off safely off the endio list. */ +static struct stripe *stripe_endio_pop(struct stripe_cache *sc) +{ + struct stripe *stripe; + spinlock_t *lock = sc->locks + LOCK_ENDIO; + + /* This runs in parallel with endio(). */ + spin_lock_irq(lock); + POP(LIST_ENDIO) + spin_unlock_irq(lock); + return stripe; +} + +#undef POP + +/* Evict stripe from cache. */ +static void stripe_evict(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + stripe_hash_del(stripe, LIST_UNLOCKED); /* Take off hash. */ + + if (list_empty(stripe->lists + LIST_LRU)) { + stripe_lru_add(stripe, POS_TAIL, LIST_LOCKED); + atomic_inc(rs->stats + S_EVICT); /* REMOVEME: statistics. */ + } +} + +/* Grow stripe cache. */ +static int +sc_grow(struct stripe_cache *sc, unsigned stripes, enum grow grow) +{ + int r = 0; + struct raid_set *rs = RS(sc); + + /* Try to allocate this many (additional) stripes. */ + while (stripes--) { + struct stripe *stripe = stripe_alloc(sc, rs->set.io_size, grow); + + if (likely(stripe)) { + stripe_lru_add(stripe, POS_TAIL, LIST_LOCKED); + atomic_inc(&sc->stripes); + } else { + r = -ENOMEM; + break; + } + } + + ClearRSScBusy(rs); + return r ? r : hash_resize(sc); +} + +/* Shrink stripe cache. */ +static int sc_shrink(struct stripe_cache *sc, unsigned stripes) +{ + int r = 0; + + /* Try to get unused stripe from LRU list. */ + while (stripes--) { + struct stripe *stripe; + + stripe = stripe_lru_pop(sc); + if (stripe) { + /* An lru stripe may never have ios pending!. */ + BUG_ON(stripe_io(stripe)); + stripe_free(stripe); + atomic_dec(&sc->stripes); + } else { + r = -ENOENT; + break; + } + } + + /* Check if stats are still sane. */ + if (atomic_read(&sc->max_active_stripes) > + atomic_read(&sc->stripes)) + atomic_set(&sc->max_active_stripes, 0); + + if (r) + return r; + + ClearRSScBusy(RS(sc)); + return hash_resize(sc); +} + +/* Create stripe cache. */ +static int sc_init(struct raid_set *rs, unsigned stripes) +{ + unsigned i, nr; + struct stripe_cache *sc = &rs->sc; + struct stripe *stripe; + + /* Initialize lists and locks. */ + i = ARRAY_SIZE(sc->lists); + while (i--) + INIT_LIST_HEAD(sc->lists + i); + + i = NR_LOCKS; + while (i--) + spin_lock_init(sc->locks + i); + + /* Initialize atomic variables. */ + atomic_set(&sc->stripes, 0); + atomic_set(&sc->stripes_last, 0); + atomic_set(&sc->stripes_to_shrink, 0); + atomic_set(&sc->active_stripes, 0); + atomic_set(&sc->max_active_stripes, 0); /* REMOVEME: */ + + /* + * We need a runtime unique # to suffix the kmem cache name + * because we'll have one for each active RAID set. + */ + nr = atomic_inc_return(&_stripe_sc_nr); + sprintf(sc->kc.name, "%s_%d", TARGET, nr); + sc->kc.cache = kmem_cache_create(sc->kc.name, stripe_size(rs), + 0, 0, NULL); + if (!sc->kc.cache) + return -ENOMEM; + + /* Create memory cache client context and Allocate memory objects. */ + sc->dm_mem_cache_client = dm_mem_cache_client_create( + stripes * stripe_pages(rs, rs->set.io_size) + + 2 * stripe_pages(rs, rs->recover.io_size), + stripes + 2, rs->set.raid_devs); + if (IS_ERR(sc->dm_mem_cache_client)) + return PTR_ERR(sc->dm_mem_cache_client); + + /* Allocate stripe for set recovery. */ + stripe = stripe_alloc(sc, rs->recover.io_size, keep); + if (!stripe) + return -ENOMEM; + + SetStripeRecover(stripe); + rs->recover.stripe = stripe; + return sc_grow(sc, stripes, keep); /* Grow the cache. */ +} + +/* Destroy the stripe cache. */ +static void sc_exit(struct stripe_cache *sc) +{ + if (sc->hash.hash) { + if (sc->kc.cache) { + BUG_ON(sc_shrink(sc, atomic_read(&sc->stripes))); + kmem_cache_destroy(sc->kc.cache); + } + + if (sc->dm_mem_cache_client) + dm_mem_cache_client_destroy(sc->dm_mem_cache_client); + + hash_exit(&sc->hash); + } +} + +/* + * Calculate RAID address + * + * Delivers tuple with the index of the data disk holding the chunk + * in the set, the parity disks index and the start of the stripe + * within the address space of the set (used as the stripe cache hash key). + */ +/* thx MD. */ +static struct address * +raid_address(struct raid_set *rs, sector_t sector, struct address *addr) +{ + unsigned data_devs = rs->set.data_devs, di, pi, + raid_devs = rs->set.raid_devs; + sector_t stripe, tmp; + + /* + * chunk_number = sector / chunk_size + * stripe = chunk_number / data_devs + * di = stripe % data_devs; + */ + stripe = sector >> rs->set.chunk_shift; + di = sector_div(stripe, data_devs); + + switch (rs->set.raid_type->level) { + case raid5: + tmp = stripe; + pi = sector_div(tmp, raid_devs); + + switch (rs->set.raid_type->algorithm) { + case left_asym: /* Left asymmetric. */ + pi = data_devs - pi; + case right_asym: /* Right asymmetric. */ + if (di >= pi) + di++; + break; + + case left_sym: /* Left symmetric. */ + pi = data_devs - pi; + case right_sym: /* Right symmetric. */ + di = (pi + di + 1) % raid_devs; + break; + + default: + DMERR("Unknown RAID algorithm %d", + rs->set.raid_type->algorithm); + goto out; + } + + break; + + case raid4: + pi = rs->set.pi; + if (di >= pi) + di++; + break; + + default: + DMERR("Unknown RAID level %d", rs->set.raid_type->level); + goto out; + } + + /* + * Hash key = start offset on any single device of the RAID set; + * adjusted in case io size differs from chunk size. + */ + addr->key = (stripe << rs->set.chunk_shift) + + (sector & rs->set.io_shift_mask); + addr->di = di; + addr->pi = pi; + + out: + return addr; +} + +/* + * Copy data across between stripe pages and bio vectors. + * + * Pay attention to data alignment in stripe and bio pages. + */ +static void +bio_copy_page_list(int rw, struct stripe *stripe, + struct page_list *pl, struct bio *bio) +{ + unsigned i, page_offset; + void *page_addr; + struct raid_set *rs = RS(stripe->sc); + struct bio_vec *bv; + + /* Get start page in page list for this sector. */ + i = (bio->bi_sector & rs->set.io_mask) / SECTORS_PER_PAGE; + pl = pl_elem(pl, i); + + page_addr = page_address(pl->page); + page_offset = to_bytes(bio->bi_sector & (SECTORS_PER_PAGE - 1)); + + /* Walk all segments and copy data across between bio_vecs and pages. */ + bio_for_each_segment(bv, bio, i) { + int len = bv->bv_len, size; + unsigned bio_offset = 0; + void *bio_addr = __bio_kmap_atomic(bio, i, KM_USER0); + redo: + size = (page_offset + len > PAGE_SIZE) ? + PAGE_SIZE - page_offset : len; + + if (rw == READ) + memcpy(bio_addr + bio_offset, + page_addr + page_offset, size); + else + memcpy(page_addr + page_offset, + bio_addr + bio_offset, size); + + page_offset += size; + if (page_offset == PAGE_SIZE) { + /* + * We reached the end of the chunk page -> + * need refer to the next one to copy more data. + */ + len -= size; + if (len) { + /* Get next page. */ + pl = pl->next; + BUG_ON(!pl); + page_addr = page_address(pl->page); + page_offset = 0; + bio_offset += size; + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_BIO_COPY_PL_NEXT); + goto redo; + } + } + + __bio_kunmap_atomic(bio_addr, KM_USER0); + } +} + +/* + * Xor optimization macros. + */ +/* Xor data pointer declaration and initialization macros. */ +#define DECLARE_2 xor_t *d0 = data[0], *d1 = data[1] +#define DECLARE_3 DECLARE_2, *d2 = data[2] +#define DECLARE_4 DECLARE_3, *d3 = data[3] +#define DECLARE_5 DECLARE_4, *d4 = data[4] +#define DECLARE_6 DECLARE_5, *d5 = data[5] +#define DECLARE_7 DECLARE_6, *d6 = data[6] +#define DECLARE_8 DECLARE_7, *d7 = data[7] + +/* Xor unrole macros. */ +#define D2(n) d0[n] = d0[n] ^ d1[n] +#define D3(n) D2(n) ^ d2[n] +#define D4(n) D3(n) ^ d3[n] +#define D5(n) D4(n) ^ d4[n] +#define D6(n) D5(n) ^ d5[n] +#define D7(n) D6(n) ^ d6[n] +#define D8(n) D7(n) ^ d7[n] + +#define X_2(macro, offset) macro(offset); macro(offset + 1); +#define X_4(macro, offset) X_2(macro, offset); X_2(macro, offset + 2); +#define X_8(macro, offset) X_4(macro, offset); X_4(macro, offset + 4); +#define X_16(macro, offset) X_8(macro, offset); X_8(macro, offset + 8); +#define X_32(macro, offset) X_16(macro, offset); X_16(macro, offset + 16); +#define X_64(macro, offset) X_32(macro, offset); X_32(macro, offset + 32); + +/* Define a _xor_#chunks_#xors_per_run() function. */ +#define _XOR(chunks, xors_per_run) \ +static void _xor ## chunks ## _ ## xors_per_run(xor_t **data) \ +{ \ + unsigned end = XOR_SIZE / sizeof(data[0]), i; \ + DECLARE_ ## chunks; \ +\ + for (i = 0; i < end; i += xors_per_run) { \ + X_ ## xors_per_run(D ## chunks, i); \ + } \ +} + +/* Define xor functions for 2 - 8 chunks. */ +#define MAKE_XOR_PER_RUN(xors_per_run) \ + _XOR(2, xors_per_run); _XOR(3, xors_per_run); \ + _XOR(4, xors_per_run); _XOR(5, xors_per_run); \ + _XOR(6, xors_per_run); _XOR(7, xors_per_run); \ + _XOR(8, xors_per_run); + +MAKE_XOR_PER_RUN(8) /* Define _xor_*_8() functions. */ +MAKE_XOR_PER_RUN(16) /* Define _xor_*_16() functions. */ +MAKE_XOR_PER_RUN(32) /* Define _xor_*_32() functions. */ +MAKE_XOR_PER_RUN(64) /* Define _xor_*_64() functions. */ + +#define MAKE_XOR(xors_per_run) \ +struct { \ + void (*f)(xor_t**); \ +} static xor_funcs ## xors_per_run[] = { \ + { NULL }, \ + { NULL }, \ + { _xor2_ ## xors_per_run }, \ + { _xor3_ ## xors_per_run }, \ + { _xor4_ ## xors_per_run }, \ + { _xor5_ ## xors_per_run }, \ + { _xor6_ ## xors_per_run }, \ + { _xor7_ ## xors_per_run }, \ + { _xor8_ ## xors_per_run }, \ +}; \ +\ +static void xor_ ## xors_per_run(unsigned n, xor_t **data) \ +{ \ + /* Call respective function for amount of chunks. */ \ + xor_funcs ## xors_per_run[n].f(data); \ +} + +/* Define xor_8() - xor_64 functions. */ +MAKE_XOR(8) +MAKE_XOR(16) +MAKE_XOR(32) +MAKE_XOR(64) + +/* Maximum number of chunks, which can be xor'ed in one go. */ +#define XOR_CHUNKS_MAX (ARRAY_SIZE(xor_funcs8) - 1) + +struct xor_func { + xor_function_t f; + const char *name; +} static xor_funcs[] = { + {xor_8, "xor_8"}, + {xor_16, "xor_16"}, + {xor_32, "xor_32"}, + {xor_64, "xor_64"}, +}; + +/* + * Calculate crc. + * + * This indexes into the page list of the stripe. + * + * All chunks will be xored into the parity chunk + * in maximum groups of xor.chunks. + * + * FIXME: try mapping the pages on discontiguous memory. + */ +static void xor(struct stripe *stripe, unsigned pi, unsigned sector) +{ + struct raid_set *rs = RS(stripe->sc); + unsigned max_chunks = rs->xor.chunks, n, p; + unsigned o = sector / SECTORS_PER_PAGE; /* Offset into the page_list. */ + xor_t **d = rs->data; + xor_function_t xor_f = rs->xor.f->f; + + /* Address of parity page to xor into. */ + d[0] = page_address(pl_elem(PL(stripe, pi), o)->page); + + /* Preset pointers to data pages. */ + for (n = 1, p = rs->set.raid_devs; p--; ) { + if (p != pi && PageIO(PAGE(stripe, p))) + d[n++] = page_address(pl_elem(PL(stripe, p), o)->page); + + /* If max chunks -> xor .*/ + if (n == max_chunks) { + xor_f(n, d); + n = 1; + } + } + + /* If chunks -> xor. */ + if (n > 1) + xor_f(n, d); + + /* Set parity page uptodate and clean. */ + page_set(PAGE(stripe, pi), CLEAN); +} + +/* Common xor loop through all stripe page lists. */ +static void common_xor(struct stripe *stripe, sector_t count, + unsigned off, unsigned p) +{ + unsigned sector; + + for (sector = off; sector < count; sector += SECTORS_PER_XOR) + xor(stripe, p, sector); + + atomic_inc(RS(stripe->sc)->stats + S_XORS); /* REMOVEME: statistics. */ +} + +/* + * Calculate parity sectors on intact stripes. + * + * Need to calculate raid address for recover stripe, because its + * chunk sizes differs and is typically larger than io chunk size. + */ +static void parity_xor(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + unsigned chunk_size = rs->set.chunk_size, + io_size = stripe->io.size, + xor_size = chunk_size > io_size ? io_size : chunk_size; + sector_t off; + + + /* This can be the recover stripe with a larger io size. */ + for (off = 0; off < io_size; off += xor_size) { + unsigned pi; + + /* + * Recover stripe likely is bigger than regular io + * ones and has no precalculated parity disk index -> + * need to calculate RAID address. + */ + if (unlikely(StripeRecover(stripe))) { + struct address addr; + + raid_address(rs, + (stripe->key + off) * rs->set.data_devs, + &addr); + pi = addr.pi; + stripe_zero_pl_part(stripe, pi, off, + rs->set.chunk_size); + } else + pi = stripe->idx.parity; + + common_xor(stripe, xor_size, off, pi); + page_set(PAGE(stripe, pi), DIRTY); + } +} + +/* Reconstruct missing chunk. */ +static void reconstruct_xor(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + int p = stripe->idx.recover; + + BUG_ON(p < 0); + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (raid_set_degraded(rs) ? + S_RECONSTRUCT_EI : S_RECONSTRUCT_DEV)); + + /* Zero chunk to be reconstructed. */ + stripe_zero_chunk(stripe, p); + common_xor(stripe, stripe->io.size, 0, p); +} + +/* + * Try getting a stripe either from the hash or from the lru list + */ +static inline void _stripe_get(struct stripe *stripe) +{ + atomic_inc(&stripe->cnt); +} + +static struct stripe *stripe_get(struct raid_set *rs, struct address *addr) +{ + struct stripe_cache *sc = &rs->sc; + struct stripe *stripe; + + + stripe = stripe_lookup(sc, addr->key); + if (stripe) { + _stripe_get(stripe); + /* Remove from the lru list if on. */ + stripe_lru_del(stripe, LIST_LOCKED); + atomic_inc(rs->stats + S_HITS_1ST); /* REMOVEME: statistics. */ + } else { + /* Second try to get an LRU stripe. */ + stripe = stripe_lru_pop(sc); + if (stripe) { + _stripe_get(stripe); + /* Invalidate before reinserting with changed key. */ + stripe_invalidate(stripe); + stripe->key = addr->key; + stripe->region = rh_sector_to_region(rs->recover.rh, + addr->key); + stripe->idx.parity = addr->pi; + sc_insert(sc, stripe); + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_INSCACHE); + } + } + + return stripe; +} + +/* + * Decrement reference count on a stripe. + * + * Move it to list of LRU stripes if zero. + */ +static void stripe_put(struct stripe *stripe) +{ + if (atomic_dec_and_test(&stripe->cnt)) { + if (TestClearStripeActive(stripe)) + atomic_dec(&stripe->sc->active_stripes); + + /* Put stripe onto the LRU list. */ + stripe_lru_add(stripe, POS_TAIL, LIST_LOCKED); + } + + BUG_ON(atomic_read(&stripe->cnt) < 0); +} + +/* + * Process end io + * + * I need to do it here because I can't in interrupt + * + * Read and write functions are split in order to avoid + * conditionals in the main loop for performamce reasons. + */ +typedef void(*endio_helper_function)(struct stripe *, struct page_list *, + struct bio *); + +/* Helper read bios on a page list. */ +static void _bio_copy_page_list(struct stripe *stripe, struct page_list *pl, + struct bio *bio) +{ + bio_copy_page_list(READ, stripe, pl, bio); +} + +/* Helper write bios on a page list. */ +static void _rh_dec(struct stripe *stripe, struct page_list *pl, + struct bio *bio) +{ + rh_dec(RS(stripe->sc)->recover.rh, stripe->region); +} + +/* End io all bios on a page list. */ +static inline int +page_list_endio(int rw, struct stripe *stripe, unsigned p, unsigned *count) +{ + int r = 0; + struct bio_list *bl = BL(stripe, p, rw); + + if (!bio_list_empty(bl)) { + struct page_list *pl = PL(stripe, p); + struct page *page = pl->page; + + if (PageLocked(page)) + r = -EBUSY; + else if (PageUptodate(page)) { + struct bio *bio; + struct raid_set *rs = RS(stripe->sc); + endio_helper_function h_f = + rw == READ ? _bio_copy_page_list : _rh_dec; + + while ((bio = bio_list_pop(bl))) { + h_f(stripe, pl, bio); + _bio_endio(rs, bio, 0); + stripe_put(stripe); + if (count) + (*count)++; + } + } else + r = -EAGAIN; + } + + return r; +} + +/* + * End io all reads/writes on a stripe copying + * read date accross from stripe to bios. + */ +static int stripe_end_io(int rw, struct stripe *stripe, unsigned *count) +{ + int r = 0; + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) { + int rr = page_list_endio(rw, stripe, p, count); + + if (rr && r != -EIO) + r = rr; + } + + return r; +} + +/* Fail all ios on a bio list and return # of bios. */ +static unsigned +bio_list_fail(struct raid_set *rs, struct stripe *stripe, struct bio_list *bl) +{ + unsigned r; + struct bio *bio; + + raid_set_dead(rs); + + /* Update region counters. */ + if (stripe) { + void *rh = rs->recover.rh; + + bio_list_for_each(bio, bl) { + if (bio_data_dir(bio) == WRITE) + rh_dec(rh, stripe->region); + } + } + + /* Error end io all bios. */ + for (r = 0; (bio = bio_list_pop(bl)); r++) + _bio_endio(rs, bio, -EIO); + + return r; +} + +/* Fail all ios of a bio list of a stripe and drop io pending count. */ +static void +stripe_bio_list_fail(struct raid_set *rs, struct stripe *stripe, + struct bio_list *bl) +{ + unsigned put = bio_list_fail(rs, stripe, bl); + + while (put--) + stripe_put(stripe); +} + +/* Fail all ios hanging off all bio lists of a stripe. */ +static void stripe_fail_io(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + unsigned p = rs->set.raid_devs; + + stripe_evict(stripe); + + while (p--) { + struct stripe_set *ss = stripe->ss + p; + int i = ARRAY_SIZE(ss->bl); + + while (i--) + stripe_bio_list_fail(rs, stripe, ss->bl + i); + } +} + +/* + * Handle all stripes by handing them to the daemon, because we can't + * map their pages to copy the data in interrupt context. + * + * We don't want to handle them here either, while interrupts are disabled. + */ + +/* Read/write endio function for dm-io (interrupt context). */ +static void endio(unsigned long error, void *context) +{ + struct dm_mem_cache_object *obj = context; + struct stripe_set *ss = obj->private; + struct stripe *stripe = ss->stripe; + struct page *page = obj->pl->page; + + if (unlikely(error)) + stripe_error(stripe, page); + else + page_set(page, CLEAN); + + clear_page_locked(page); + stripe_io_dec(stripe); + + /* Add stripe to endio list and wake daemon. */ + stripe_endio_push(stripe); +} + +/* + * Recovery io throttling + */ +/* Conditionally reset io counters. */ +enum count_type { IO_WORK = 0, IO_RECOVER }; +static int recover_io_reset(struct raid_set *rs) +{ + unsigned long j = jiffies; + + /* Pay attention to jiffies overflows. */ + if (j > rs->recover.last_jiffies + HZ + || j < rs->recover.last_jiffies) { + rs->recover.last_jiffies = j; + atomic_set(rs->recover.io_count + IO_WORK, 0); + atomic_set(rs->recover.io_count + IO_RECOVER, 0); + return 1; + } + + return 0; +} + +/* Count ios. */ +static INLINE void +recover_io_count(struct raid_set *rs, struct stripe *stripe) +{ + if (RSRecover(rs)) { + recover_io_reset(rs); + atomic_inc(rs->recover.io_count + + (stripe == rs->recover.stripe ? + IO_RECOVER : IO_WORK)); + } +} + +/* Read/Write a page_list asynchronously. */ +static void page_list_rw(struct stripe *stripe, unsigned p) +{ + struct stripe_cache *sc = stripe->sc; + struct raid_set *rs = RS(sc); + struct dm_mem_cache_object *obj = stripe->obj + p; + struct page_list *pl = obj->pl; + struct page *page = pl->page; + struct raid_dev *dev = rs->dev + p; + struct dm_io_region io = { + .bdev = dev->dev->bdev, + .sector = stripe->key, + .count = stripe->io.size, + }; + struct dm_io_request control = { + .bi_rw = PageDirty(page) ? WRITE : READ, + .mem.type = DM_IO_PAGE_LIST, + .mem.ptr.pl = pl, + .mem.offset = 0, + .notify.fn = endio, + .notify.context = obj, + .client = sc->dm_io_client, + }; + + BUG_ON(PageLocked(page)); + + /* + * Don't rw past end of device, which can happen, because + * typically sectors_per_dev isn't divisable by io_size. + */ + if (unlikely(io.sector + io.count > rs->set.sectors_per_dev)) + io.count = rs->set.sectors_per_dev - io.sector; + + io.sector += dev->start; /* Add . */ + recover_io_count(rs, stripe); /* Recovery io accounting. */ + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + (PageDirty(page) ? S_DM_IO_WRITE: S_DM_IO_READ)); + + ClearPageError(page); + set_page_locked(page); + io_dev_queued(dev); + BUG_ON(dm_io(&control, 1, &io, NULL)); +} + +/* + * Write dirty / read not uptodate page lists of a stripe. + */ +static unsigned stripe_page_lists_rw(struct raid_set *rs, struct stripe *stripe) +{ + unsigned r; + + /* + * Increment the pending count on the stripe + * first, so that we don't race in endio(). + * + * An inc (IO) is needed for any page: + * + * o not uptodate + * o dirtied by writes merged + * o dirtied by parity calculations + */ + r = for_each_io_dev(rs, stripe, _stripe_io_inc); + if (r) { + /* io needed: chunks are not uptodate/dirty. */ + int max; /* REMOVEME: */ + struct stripe_cache *sc = &rs->sc; + + if (!TestSetStripeActive(stripe)) + atomic_inc(&sc->active_stripes); + + /* Take off the lru list in case it got added there. */ + stripe_lru_del(stripe, LIST_LOCKED); + + /* Submit actual io. */ + for_each_io_dev(rs, stripe, page_list_rw); + + /* REMOVEME: statistics */ + max = sc_active(sc); + if (atomic_read(&sc->max_active_stripes) < max) + atomic_set(&sc->max_active_stripes, max); + + atomic_inc(rs->stats + S_FLUSHS); + /* END REMOVEME: statistics */ + } + + return r; +} + +/* Work in all pending writes. */ +static INLINE void _writes_merge(struct stripe *stripe, unsigned p) +{ + struct bio_list *write = BL(stripe, p, WRITE); + + if (!bio_list_empty(write)) { + struct page_list *pl = stripe->obj[p].pl; + struct bio *bio; + struct bio_list *write_merged = BL(stripe, p, WRITE_MERGED); + + /* + * We can play with the lists without holding a lock, + * because it is just us accessing them anyway. + */ + bio_list_for_each(bio, write) + bio_copy_page_list(WRITE, stripe, pl, bio); + + bio_list_merge(write_merged, write); + bio_list_init(write); + page_set(pl->page, DIRTY); + } +} + +/* Merge in all writes hence dirtying respective pages. */ +static INLINE void writes_merge(struct stripe *stripe) +{ + unsigned p = RS(stripe->sc)->set.raid_devs; + + while (p--) + _writes_merge(stripe, p); +} + +/* Check, if a chunk gets completely overwritten. */ +static INLINE int stripe_check_overwrite(struct stripe *stripe, unsigned p) +{ + unsigned sectors = 0; + struct bio *bio; + struct bio_list *bl = BL(stripe, p, WRITE); + + bio_list_for_each(bio, bl) + sectors += bio_sectors(bio); + + return sectors == RS(stripe->sc)->set.io_size; +} + +/* + * Prepare stripe to avoid io on broken/reconstructed + * drive to be reconstructed on endio. + */ +enum prepare_type { IO_ALLOW, IO_PROHIBIT }; +static void stripe_prepare(struct stripe *stripe, unsigned p, + enum prepare_type type) +{ + struct page *page = PAGE(stripe, p); + + switch (type) { + case IO_PROHIBIT: + /* REMOVEME: statistics. */ + atomic_inc(RS(stripe->sc)->stats + S_PROHIBITPAGEIO); + ProhibitPageIO(page); + stripe->idx.recover = p; + SetStripeReconstruct(stripe); + break; + + case IO_ALLOW: + AllowPageIO(page); + stripe->idx.recover = -1; + ClearStripeReconstruct(stripe); + break; + + default: + BUG(); + } +} + +/* + * Degraded/reconstruction mode. + * + * Check stripe state to figure which chunks don't need IO. + */ +static INLINE void stripe_check_reconstruct(struct stripe *stripe, + int prohibited) +{ + struct raid_set *rs = RS(stripe->sc); + + /* + * Degraded mode (device(s) failed) -> + * avoid io on the failed device. + */ + if (unlikely(raid_set_degraded(rs))) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_DEGRADED); + stripe_prepare(stripe, rs->set.ei, IO_PROHIBIT); + return; + } else { + /* + * Reconstruction mode (ie. a particular device or + * some (rotating) parity chunk is being resynchronized) -> + * o make sure all needed pages are read in + * o writes are allowed to go through + */ + int r = region_state(rs, stripe->key, RH_NOSYNC); + + if (r) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_NOSYNC); + stripe_prepare(stripe, dev_for_parity(stripe), + IO_PROHIBIT); + return; + } + } + + /* + * All disks good. Avoid reading parity chunk and reconstruct it + * unless we have prohibited io to chunk(s). + */ + if (!prohibited) { + if (StripeMerged(stripe)) + stripe_prepare(stripe, stripe->idx.parity, IO_ALLOW); + else { + stripe_prepare(stripe, stripe->idx.parity, IO_PROHIBIT); + ClearStripeReconstruct(stripe); + } + } +} + +/* Check, if stripe is ready to merge writes. */ +static INLINE int stripe_check_merge(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + int prohibited = 0; + unsigned chunks = 0, p = rs->set.raid_devs; + + /* Walk all chunks. */ + while (p--) { + struct page *page = PAGE(stripe, p); + + /* Can't merge active chunks. */ + if (PageLocked(page)) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_MERGE_PAGE_LOCKED); + break; + } + + /* Can merge uptodate chunks and have to count parity chunk. */ + if (PageUptodate(page) || p == stripe->idx.parity) { + chunks++; + continue; + } + + /* Read before write ordering. */ + if (RSCheckOverwrite(rs) && + bio_list_empty(BL(stripe, p, READ))) { + int r = stripe_check_overwrite(stripe, p); + + if (r) { + chunks++; + /* REMOVEME: statistics. */ + atomic_inc(RS(stripe->sc)->stats + + S_PROHIBITPAGEIO); + ProhibitPageIO(page); + prohibited = 1; + } + } + } + + if (chunks == rs->set.raid_devs) { + /* All pages are uptodate or get written over or mixture. */ + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_CAN_MERGE); + return 0; + } else + /* REMOVEME: statistics.*/ + atomic_inc(rs->stats + S_CANT_MERGE); + + return prohibited ? 1 : -EPERM; +} + +/* Check, if stripe is ready to merge writes. */ +static INLINE int stripe_check_read(struct stripe *stripe) +{ + int r = 0; + unsigned p = RS(stripe->sc)->set.raid_devs; + + /* Walk all chunks. */ + while (p--) { + struct page *page = PAGE(stripe, p); + + if (!PageLocked(page) && + bio_list_empty(BL(stripe, p, READ))) { + ProhibitPageIO(page); + r = 1; + } + } + + return r; +} + +/* + * Read/write a stripe. + * + * States to cover: + * o stripe to read and/or write + * o stripe with error to reconstruct + */ +static int stripe_rw(struct stripe *stripe) +{ + struct raid_set *rs = RS(stripe->sc); + int prohibited = 0, r; + + /* + * Check the state of the RAID set and if degraded (or + * resynchronizing for reads), read in all other chunks but + * the one on the dead/resynchronizing device in order to be + * able to reconstruct the missing one. + * + * Merge all writes hanging off uptodate pages of the stripe. + */ + + /* Initially allow io on all chunks and prohibit below, if necessary. */ + stripe_allow_io(stripe); + + if (StripeRBW(stripe)) { + r = stripe_check_merge(stripe); + if (!r) { + /* + * If I could rely on valid parity (which would only + * be sure in case of a full synchronization), + * I could xor a fraction of chunks out of + * parity and back in. + * + * For the time being, I got to redo parity... + */ + // parity_xor(stripe); /* Xor chunks out. */ + stripe_zero_chunk(stripe, stripe->idx.parity); + writes_merge(stripe); /* Merge writes in. */ + parity_xor(stripe); /* Update parity. */ + ClearStripeRBW(stripe); /* Disable RBW. */ + SetStripeMerged(stripe); /* Writes merged. */ + } + + if (r > 0) + prohibited = 1; + } else if (!raid_set_degraded(rs)) + prohibited = stripe_check_read(stripe); + + /* + * Check, if io needs to be allowed/prohibeted on certain chunks + * because of a degraded set or reconstruction on a region. + */ + stripe_check_reconstruct(stripe, prohibited); + + /* Now submit any reads/writes. */ + r = stripe_page_lists_rw(rs, stripe); + if (!r) { + /* + * No io submitted because of chunk io prohibited or + * locked pages -> push to end io list for processing. + */ + atomic_inc(rs->stats + S_NO_RW); /* REMOVEME: statistics. */ + stripe_endio_push(stripe); + wake_do_raid(rs); /* Wake myself. */ + } + + return 0; +} + +/* Flush stripe either via flush list or imeediately. */ +enum flush_type { FLUSH_DELAY, FLUSH_NOW }; +static int stripe_flush(struct stripe *stripe, enum flush_type type) +{ + int r = 0; + + stripe_lru_del(stripe, LIST_LOCKED); + + /* Delay flush by putting it on io list for later processing. */ + if (type == FLUSH_DELAY) + stripe_io_add(stripe, POS_TAIL, LIST_UNLOCKED); + + /* Immediately flush. */ + else if (type == FLUSH_NOW) { + if (likely(raid_set_operational(RS(stripe->sc)))) + r = stripe_rw(stripe); /* Read/write stripe. */ + else + /* Optimization: Fail early on failed sets. */ + stripe_fail_io(stripe); + } else + BUG(); + + return r; +} + +/* + * Queue reads and writes to a stripe by hanging + * their bios off the stripsets read/write lists. + * + * Endio reads on uptodate chunks. + */ +static INLINE int stripe_queue_bio(struct raid_set *rs, struct bio *bio, + struct bio_list *reject) +{ + int r = 0; + struct address addr; + struct stripe *stripe = + stripe_get(rs, raid_address(rs, bio->bi_sector, &addr)); + + if (stripe) { + int rr, rw = bio_data_dir(bio); + + rr = stripe_lock(rs, stripe, rw, addr.key); /* Lock stripe */ + if (rr) { + stripe_put(stripe); + goto out; + } + + /* Distinguish read and write cases. */ + bio_list_add(BL(stripe, addr.di, rw), bio); + + /* REMOVEME: statistics */ + atomic_inc(rs->stats + (rw == WRITE ? + S_BIOS_ADDED_WRITE : S_BIOS_ADDED_READ)); + + if (rw == READ) + SetStripeRead(stripe); + else { + SetStripeRBW(stripe); + + /* Inrement pending write count on region. */ + rh_inc(rs->recover.rh, stripe->region); + r = 1; /* Region hash needs a flush. */ + } + + /* + * Optimize stripe flushing: + * + * o directly start io for read stripes. + * + * o put stripe onto stripe caches io_list for RBW, + * so that do_flush() can belabour it after we put + * more bios to the stripe for overwrite optimization. + */ + stripe_flush(stripe, + StripeRead(stripe) ? FLUSH_NOW : FLUSH_DELAY); + + /* Got no stripe from cache -> reject bio. */ + } else { + out: + bio_list_add(reject, bio); + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_IOS_POST); + } + + return r; +} + +/* + * Recovery functions + */ +/* Read a stripe off a raid set for recovery. */ +static int recover_read(struct raid_set *rs, struct stripe *stripe, int idx) +{ + /* Invalidate all pages so that they get read in. */ + stripe_pages_invalidate(stripe); + + /* Allow io on all recovery chunks. */ + stripe_allow_io(stripe); + + if (idx > -1) + ProhibitPageIO(PAGE(stripe, idx)); + + stripe->key = rs->recover.pos; + return stripe_page_lists_rw(rs, stripe); +} + +/* Write a stripe to a raid set for recovery. */ +static int recover_write(struct raid_set *rs, struct stripe *stripe, int idx) +{ + /* + * If this is a reconstruct of a particular device, then + * reconstruct the respective page(s), else create parity page(s). + */ + if (idx > -1) { + struct page *page = PAGE(stripe, idx); + + AllowPageIO(page); + stripe_zero_chunk(stripe, idx); + common_xor(stripe, stripe->io.size, 0, idx); + page_set(page, DIRTY); + } else + parity_xor(stripe); + + return stripe_page_lists_rw(rs, stripe); +} + +/* Recover bandwidth available ?. */ +static int recover_bandwidth(struct raid_set *rs) +{ + int r, work; + + /* On reset -> allow recovery. */ + r = recover_io_reset(rs); + if (r || RSBandwidth(rs)) + goto out; + + work = atomic_read(rs->recover.io_count + IO_WORK); + if (work) { + /* Pay attention to larger recover stripe size. */ + int recover = + atomic_read(rs->recover.io_count + IO_RECOVER) * + rs->recover.stripe->io.size / + rs->set.io_size; + + /* + * Don't use more than given bandwidth of + * the work io for recovery. + */ + if (recover > work / rs->recover.bandwidth_work) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_NO_BANDWIDTH); + return 0; + } + } + + out: + atomic_inc(rs->stats + S_BANDWIDTH); /* REMOVEME: statistics. */ + return 1; +} + +/* Try to get a region to recover. */ +static int recover_get_region(struct raid_set *rs) +{ + struct recover *rec = &rs->recover; + void *rh = rec->rh; + + /* Start quiescing some regions. */ + if (!RSRegionGet(rs)) { + int r = recover_bandwidth(rs); /* Enough bandwidth ?. */ + + if (r) { + if (rh_recovery_prepare(rh) < 0) { + DMINFO("No %sregions to recover", + rec->nr_regions_to_recover ? + "more " : ""); + return -ENOENT; + } + } else + return -EAGAIN; + + SetRSRegionGet(rs); + } + + if (!rec->reg) { + rec->reg = rh_recovery_start(rh); + if (rec->reg) { + /* + * A reference for the the region I'll + * keep till I've completely synced it. + */ + io_get(rs); + rec->pos = + rh_region_to_sector(rh, + rh_get_region_key(rec->reg)); + rec->end = rec->pos + rh_get_region_size(rh); + return 1; + } else + return -EAGAIN; + } + + return 0; +} + +/* Read/write a recovery stripe. */ +static INLINE int recover_stripe_rw(struct raid_set *rs, struct stripe *stripe) +{ + /* Read/write flip-flop. */ + if (TestClearStripeRBW(stripe)) { + SetStripeRead(stripe); + return recover_read(rs, stripe, idx_get(rs)); + } else if (TestClearStripeRead(stripe)) + return recover_write(rs, stripe, idx_get(rs)); + + return 0; +} + +/* Reset recovery variables. */ +static void recovery_region_reset(struct raid_set *rs) +{ + rs->recover.reg = NULL; + ClearRSRegionGet(rs); +} + +/* Update region hash state. */ +static void recover_rh_update(struct raid_set *rs, int error) +{ + struct recover *rec = &rs->recover; + void *rh = rec->rh; + void *reg = rec->reg; + + if (reg) { + rh_recovery_end(reg, error); + if (!error) + rec->nr_regions_recovered++; + + recovery_region_reset(rs); + } + + rh_update_states(rh); + rh_flush(rh); + io_put(rs); /* Release the io reference for the region. */ +} + +/* Called by main io daemon to recover regions. */ +static INLINE void do_recovery(struct raid_set *rs) +{ + if (RSRecover(rs)) { + int r; + struct recover *rec = &rs->recover; + struct stripe *stripe = rec->stripe; + + /* If recovery is active -> return. */ + if (StripeActive(stripe)) + return; + + /* io error is fatal for recovery -> stop it. */ + if (unlikely(StripeError(stripe))) + goto err; + + /* Get a region to recover. */ + r = recover_get_region(rs); + switch (r) { + case 1: /* Got a new region. */ + /* Flag read before write. */ + ClearStripeRead(stripe); + SetStripeRBW(stripe); + break; + + case 0: + /* Got a region in the works. */ + r = recover_bandwidth(rs); + if (r) /* Got enough bandwidth. */ + break; + + case -EAGAIN: + /* No bandwidth/quiesced region yet, try later. */ + wake_do_raid_delayed(rs, HZ / 10); + return; + + case -ENOENT: /* No more regions. */ + goto free; + } + + /* Read/write a recover stripe. */ + r = recover_stripe_rw(rs, stripe); + if (r) { + /* Io initiated, get another reference for the IO. */ + io_get(rs); + return; + } + + /* Update recovery position within region. */ + rec->pos += stripe->io.size; + + /* If we're at end of region, update region hash. */ + if (rec->pos >= rec->end || + rec->pos >= rs->set.sectors_per_dev) + recover_rh_update(rs, 0); + else + SetStripeRBW(stripe); + + /* Schedule myself for another round... */ + wake_do_raid(rs); + return; + + err: + raid_set_check_degrade(rs, stripe); + + { + char buf[BDEVNAME_SIZE]; + + DMERR("stopping recovery due to " + "ERROR on /dev/%s, stripe at offset %llu", + bdevname(rs->dev[rs->set.ei].dev->bdev, buf), + (unsigned long long) stripe->key); + + } + + /* Make sure, that all quiesced regions get released. */ + do { + if (rec->reg) + rh_recovery_end(rec->reg, -EIO); + + rec->reg = rh_recovery_start(rec->rh); + } while (rec->reg); + + recover_rh_update(rs, -EIO); + free: + stripe_recover_free(rs); + rs->set.dev_to_init = -1; + rs->recover.end_jiffies = jiffies; + /* Check for jiffies overrun. */ + if (rs->recover.end_jiffies < rs->recover.start_jiffies) + rs->recover.end_jiffies = ~0; + } +} + +/* + * END recovery functions + */ + +/* End io process all stripes handed in by endio() callback. */ +static void do_endios(struct raid_set *rs) +{ + struct stripe_cache *sc = &rs->sc; + struct stripe *stripe; + + while ((stripe = stripe_endio_pop(sc))) { + unsigned count; + + /* Recovery stripe special case. */ + if (unlikely(StripeRecover(stripe))) { + if (stripe_io(stripe)) + continue; + + io_put(rs); /* Release region io reference. */ + ClearStripeActive(stripe); + atomic_dec(&sc->active_stripes); /* REMOVEME: */ + continue; + } + + /* Early end io all reads on any uptodate chunks. */ + stripe_end_io(READ, stripe, (count = 0, &count)); + if (stripe_io(stripe)) { + if (count) /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_ACTIVE_READS); + + continue; + } + + /* Set stripe inactive after all io got processed. */ + if (TestClearStripeActive(stripe)) + atomic_dec(&sc->active_stripes); + + /* Unlock stripe (for clustering). */ + stripe_unlock(rs, stripe); + + /* + * If an io error on a stripe occured and the RAID set + * is still operational, requeue the stripe for io. + */ + if (TestClearStripeError(stripe)) { + raid_set_check_degrade(rs, stripe); + ClearStripeReconstruct(stripe); + + if (!StripeMerged(stripe) && + raid_set_operational(rs)) { + stripe_pages_invalidate(stripe); + stripe_flush(stripe, FLUSH_DELAY); + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_REQUEUE); + continue; + } + } + + /* Check if the RAID set is inoperational to error ios. */ + if (!raid_set_operational(rs)) { + ClearStripeReconstruct(stripe); + stripe_fail_io(stripe); + BUG_ON(atomic_read(&stripe->cnt)); + continue; + } + + /* Got to reconstruct a missing chunk. */ + if (TestClearStripeReconstruct(stripe)) + reconstruct_xor(stripe); + + /* + * Now that we've got a complete stripe, we can + * process the rest of the end ios on reads. + */ + BUG_ON(stripe_end_io(READ, stripe, NULL)); + ClearStripeRead(stripe); + + /* + * Read-before-write stripes need to be flushed again in + * order to work the write data into the pages *after* + * they were read in. + */ + if (TestClearStripeMerged(stripe)) + /* End io all bios which got merged already. */ + BUG_ON(stripe_end_io(WRITE_MERGED, stripe, NULL)); + + /* Got to put on flush list because of new writes. */ + if (StripeRBW(stripe)) + stripe_flush(stripe, FLUSH_DELAY); + } +} + +/* + * Stripe cache shrinking. + */ +static INLINE void do_sc_shrink(struct raid_set *rs) +{ + unsigned shrink = atomic_read(&rs->sc.stripes_to_shrink); + + if (shrink) { + unsigned cur = atomic_read(&rs->sc.stripes); + + sc_shrink(&rs->sc, shrink); + shrink -= cur - atomic_read(&rs->sc.stripes); + atomic_set(&rs->sc.stripes_to_shrink, shrink); + + /* + * Wake myself up in case we failed to shrink the + * requested amount in order to try again later. + */ + if (shrink) + wake_do_raid(rs); + } +} + + +/* + * Process all ios + * + * We do different things with the io depending on the + * state of the region that it's in: + * + * o reads: hang off stripe cache or postpone if full + * + * o writes: + * + * CLEAN/DIRTY/NOSYNC: increment pending and hang io off stripe's stripe set. + * In case stripe cache is full or busy, postpone the io. + * + * RECOVERING: delay the io until recovery of the region completes. + * + */ +static INLINE void do_ios(struct raid_set *rs, struct bio_list *ios) +{ + int r; + unsigned flush = 0; + void *rh = rs->recover.rh; + struct bio *bio; + struct bio_list delay, reject; + + bio_list_init(&delay); + bio_list_init(&reject); + + /* + * Classify each io: + * o delay to recovering regions + * o queue to all other regions + */ + while ((bio = bio_list_pop(ios))) { + /* + * In case we get a barrier bio, push it back onto + * the input queue unless all work queues are empty + * and the stripe cache is inactive. + */ + if (unlikely(bio_barrier(bio))) { + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + S_BARRIER); + if (!list_empty(rs->sc.lists + LIST_IO) || + !bio_list_empty(&delay) || + !bio_list_empty(&reject) || + sc_active(&rs->sc)) { + bio_list_push(ios, bio); + break; + } + } + + r = region_state(rs, _sector(rs, bio), RH_RECOVERING); + if (unlikely(r)) { + /* Got to wait for recovering regions. */ + bio_list_add(&delay, bio); + SetRSBandwidth(rs); + } else { + /* + * Process ios to non-recovering regions by queueing + * them to stripes (does rh_inc()) for writes). + */ + flush += stripe_queue_bio(rs, bio, &reject); + } + } + + if (flush) + rh_flush(rh); /* Writes got queued -> flush dirty log. */ + + /* Delay ios to regions which are recovering. */ + while ((bio = bio_list_pop(&delay))) { + /* REMOVEME: statistics.*/ + atomic_inc(rs->stats + S_DELAYED_BIOS); + atomic_inc(rs->stats + S_SUM_DELAYED_BIOS); + rh_delay_by_region(rh, bio, + rh_sector_to_region(rh, _sector(rs, bio))); + } + + /* Merge any rejected bios back to the head of the input list. */ + bio_list_merge_head(ios, &reject); +} + +/* Flush any stripes on the io list. */ +static INLINE void do_flush(struct raid_set *rs) +{ + struct list_head *list = rs->sc.lists + LIST_IO, *pos, *tmp; + + list_for_each_safe(pos, tmp, list) { + int r = stripe_flush(list_entry(pos, struct stripe, + lists[LIST_IO]), FLUSH_NOW); + + /* Remove from the list only if the stripe got processed. */ + if (!r) + list_del_init(pos); + } +} + +/* Send an event in case we're getting too busy. */ +static INLINE void do_busy_event(struct raid_set *rs) +{ + if ((sc_active(&rs->sc) > atomic_read(&rs->sc.stripes) * 4 / 5)) { + if (!TestSetRSScBusy(rs)) + dm_table_event(rs->ti->table); + } else + ClearRSScBusy(rs); +} + +/* Unplug: let the io role on the sets devices. */ +static INLINE void do_unplug(struct raid_set *rs) +{ + struct raid_dev *dev = rs->dev + rs->set.raid_devs; + + while (dev-- > rs->dev) { + /* Only call any device unplug function, if io got queued. */ + if (io_dev_clear(dev)) { + struct request_queue *q = + bdev_get_queue(dev->dev->bdev); + + if (q->unplug_fn) + q->unplug_fn(q); + } + } +} + +/*----------------------------------------------------------------- + * RAID daemon + *---------------------------------------------------------------*/ +/* + * o belabour all end ios + * o optionally shrink the stripe cache + * o update the region hash states + * o optionally do recovery + * o grab the input queue + * o work an all requeued or new ios and perform stripe cache flushs + * unless the RAID set is inoperational (when we error ios) + * o check, if the stripe cache gets too busy and throw an event if so + * o unplug any component raid devices with queued bios + */ +static void do_raid(struct work_struct *ws) +{ + struct raid_set *rs = container_of(ws, struct raid_set, io.dws.work); + struct bio_list *ios = &rs->io.work, *ios_in = &rs->io.in; + spinlock_t *lock = &rs->io.in_lock; + + /* + * We always need to end io, so that ios + * can get errored in case the set failed + * and the region counters get decremented + * before we update the region hash states. + */ + redo: + do_endios(rs); + + /* + * Now that we've end io'd, which may have put stripes on + * the LRU list, we shrink the stripe cache if requested. + */ + do_sc_shrink(rs); + + /* Update region hash states before we go any further. */ + rh_update_states(rs->recover.rh); + + /* Try to recover regions. */ + do_recovery(rs); + + /* More endios -> process. */ + if (!stripe_endio_empty(&rs->sc)) { + atomic_inc(rs->stats + S_REDO); + goto redo; + } + + /* Quickly grab all new ios queued and add them to the work list. */ + spin_lock_irq(lock); + bio_list_merge(ios, ios_in); + bio_list_init(ios_in); + spin_unlock_irq(lock); + + /* Let's assume we're operational most of the time ;-). */ + if (likely(raid_set_operational(rs))) { + /* If we got ios, work them into the cache. */ + if (!bio_list_empty(ios)) { + do_ios(rs, ios); + do_unplug(rs); /* Unplug the sets device queues. */ + } + + do_flush(rs); /* Flush any stripes on io list. */ + do_unplug(rs); /* Unplug the sets device queues. */ + do_busy_event(rs); /* Check if we got too busy. */ + + /* More endios -> process. */ + if (!stripe_endio_empty(&rs->sc)) { + atomic_inc(rs->stats + S_REDO); + goto redo; + } + } else + /* No way to reconstruct data with too many devices failed. */ + bio_list_fail(rs, NULL, ios); +} + +/* + * Callback for region hash to dispatch + * delayed bios queued to recovered regions + * (Gets called via rh_update_states()). + */ +static void dispatch_delayed_bios(void *context, struct bio_list *bl) +{ + struct raid_set *rs = context; + struct bio *bio; + + /* REMOVEME: decrement pending delayed bios counter. */ + bio_list_for_each(bio, bl) + atomic_dec(rs->stats + S_DELAYED_BIOS); + + /* Merge region hash private list to work list. */ + bio_list_merge_head(&rs->io.work, bl); + bio_list_init(bl); + ClearRSBandwidth(rs); +} + +/************************************************************* + * Constructor helpers + *************************************************************/ +#define XOR_SPEED_SIZE rs->recover.io_size + +/* Calculate MB/sec. */ +static INLINE unsigned mbpers(struct raid_set *rs, unsigned speed) +{ + return to_bytes(speed * rs->set.data_devs * + XOR_SPEED_SIZE * HZ >> 10) >> 10; +} + +/* + * Discover fastest xor algorithm and # of chunks combination. + */ +/* Calculate speed for algorithm and # of chunks. */ +static INLINE unsigned xor_speed(struct raid_set *rs) +{ + unsigned r = 0; + unsigned long j; + + for (j = jiffies; j == jiffies;); /* Wait for next tick. */ + + /* Do xors for a full tick. */ + for (j = jiffies; j == jiffies;) { + mb(); + common_xor(rs->recover.stripe, XOR_SPEED_SIZE, 0, 0); + mb(); + r++; + mb(); + } + + return r; +} + +/* Optimize xor algorithm for this RAID set. */ +static unsigned xor_optimize(struct raid_set *rs) +{ + unsigned chunks_max = 2, speed_max = 0; + struct xor_func *f = ARRAY_END(xor_funcs), *f_max = NULL; + + /* + * Got to allow io on all chunks, so that + * xor() will actually work on them. + */ + stripe_allow_io(rs->recover.stripe); + + /* Try all xor functions. */ + while (f-- > xor_funcs) { + unsigned speed; + + /* Set actual xor function for common_xor(). */ + rs->xor.f = f; + rs->xor.chunks = XOR_CHUNKS_MAX + 1; + + while (rs->xor.chunks-- > 2) { + speed = xor_speed(rs); + if (speed > speed_max) { + speed_max = speed; + chunks_max = rs->xor.chunks; + f_max = f; + } + } + } + + /* Memorize optimum parameters. */ + rs->xor.f = f_max; + rs->xor.chunks = chunks_max; + return speed_max; +} + +/* + * Allocate a RAID context (a RAID set) + */ +static int +context_alloc(struct raid_set **raid_set, struct raid_type *raid_type, + unsigned stripes, unsigned chunk_size, unsigned io_size, + unsigned recover_io_size, unsigned raid_devs, + sector_t sectors_per_dev, + struct dm_target *ti, unsigned dl_parms, char **argv) +{ + int r; + unsigned p; + size_t len; + sector_t region_size, ti_len; + struct raid_set *rs = NULL; + struct dm_dirty_log *dl; + + /* + * Create the dirty log + * + * We need to change length for the dirty log constructor, + * because we want an amount of regions for all stripes derived + * from the single device size, so that we can keep region + * size = 2^^n independant of the number of devices + */ + ti_len = ti->len; + ti->len = sectors_per_dev; + dl = dm_dirty_log_create(argv[0], ti, dl_parms, argv + 2); + ti->len = ti_len; + if (!dl) + goto bad_dirty_log; + + /* Chunk size *must* be smaller than region size. */ + region_size = dl->type->get_region_size(dl); + if (chunk_size > region_size) + goto bad_chunk_size; + + /* Recover io size *must* be smaller than region size as well. */ + if (recover_io_size > region_size) + goto bad_recover_io_size; + + /* Size and allocate the RAID set structure. */ + len = sizeof(*rs->data) + sizeof(*rs->dev); + if (dm_array_too_big(sizeof(*rs), len, raid_devs)) + goto bad_array; + + len = sizeof(*rs) + raid_devs * len; + rs = kzalloc(len, GFP_KERNEL); + if (!rs) + goto bad_alloc; + + atomic_set(&rs->io.in_process, 0); + atomic_set(&rs->io.in_process_max, 0); + rs->recover.io_size = recover_io_size; + + /* Pointer to data array. */ + rs->data = (xor_t **) ((void *) rs->dev + raid_devs * sizeof(*rs->dev)); + rs->recover.dl = dl; + rs->set.raid_devs = p = raid_devs; + rs->set.data_devs = raid_devs - raid_type->parity_devs; + rs->set.raid_type = raid_type; + + /* + * Set chunk and io size and respective shifts + * (used to avoid divisions) + */ + rs->set.chunk_size = chunk_size; + rs->set.chunk_mask = chunk_size - 1; + rs->set.chunk_shift = ffs(chunk_size) - 1; + + rs->set.io_size = io_size; + rs->set.io_mask = io_size - 1; + rs->set.io_shift = ffs(io_size) - 1; + rs->set.io_shift_mask = rs->set.chunk_mask & ~rs->set.io_mask; + + rs->set.pages_per_io = chunk_pages(io_size); + rs->set.sectors_per_dev = sectors_per_dev; + + rs->set.ei = -1; /* Indicate no failed device. */ + atomic_set(&rs->set.failed_devs, 0); + + rs->ti = ti; + + atomic_set(rs->recover.io_count + IO_WORK, 0); + atomic_set(rs->recover.io_count + IO_RECOVER, 0); + + /* Initialize io lock and queues. */ + spin_lock_init(&rs->io.in_lock); + bio_list_init(&rs->io.in); + bio_list_init(&rs->io.work); + + init_waitqueue_head(&rs->io.suspendq); /* Suspend waiters (dm-io). */ + + rs->recover.nr_regions = dm_sector_div_up(sectors_per_dev, region_size); + r = rh_init(&rs->recover.rh, 1, dispatch_delayed_bios, rs, + wake_do_raid, rs, dl, region_size, + rs->recover.nr_regions); + if (r) + goto bad_rh; + + /* Initialize stripe cache. */ + r = sc_init(rs, stripes); + if (r) + goto bad_sc; + + /* Create dm-io client context. */ + rs->sc.dm_io_client = dm_io_client_create(rs->set.raid_devs * + rs->set.pages_per_io); + if (IS_ERR(rs->sc.dm_io_client)) + goto bad_dm_io_client; + + /* REMOVEME: statistics. */ + stats_reset(rs); + ClearRSDevelStats(rs); /* Disnable development status. */ + + *raid_set = rs; + return 0; + + bad_dirty_log: + TI_ERR_RET("Error creating dirty log", -ENOMEM); + + + bad_chunk_size: + dm_dirty_log_destroy(dl); + TI_ERR("Chunk size larger than region size"); + + bad_recover_io_size: + dm_dirty_log_destroy(dl); + TI_ERR("Recover stripe io size larger than region size"); + + bad_array: + dm_dirty_log_destroy(dl); + TI_ERR("Arry too big"); + + bad_alloc: + dm_dirty_log_destroy(dl); + TI_ERR_RET("Cannot allocate raid context", -ENOMEM); + + bad_rh: + dm_dirty_log_destroy(dl); + ti->error = DM_MSG_PREFIX "Error creating dirty region hash"; + goto free_rs; + + bad_sc: + ti->error = DM_MSG_PREFIX "Error creating stripe cache"; + goto free; + + bad_dm_io_client: + ti->error = DM_MSG_PREFIX "Error allocating dm-io resources"; + free: + sc_exit(&rs->sc); + rh_exit(rs->recover.rh); + free_rs: + kfree(rs); + return -ENOMEM; +} + +/* Free a RAID context (a RAID set). */ +static void +context_free(struct raid_set *rs, struct dm_target *ti, unsigned r) +{ + while (r--) + dm_put_device(ti, rs->dev[r].dev); + + dm_io_client_destroy(rs->sc.dm_io_client); + stripe_recover_free(rs); + sc_exit(&rs->sc); + rh_exit(rs->recover.rh); /* Destroys dirty log as well. */ + kfree(rs); +} + +/* Create work queue and initialize work. */ +static int rs_workqueue_init(struct raid_set *rs) +{ + struct dm_target *ti = rs->ti; + + rs->io.wq = create_singlethread_workqueue(DAEMON); + if (!rs->io.wq) + TI_ERR_RET("failed to create " DAEMON, -ENOMEM); + + INIT_DELAYED_WORK(&rs->io.dws, do_raid); + return 0; +} + +/* Return pointer to raid_type structure for raid name. */ +static struct raid_type *get_raid_type(char *name) +{ + struct raid_type *r = ARRAY_END(raid_types); + + while (r-- > raid_types) { + if (!strnicmp(STR_LEN(r->name, name))) + return r; + } + + return NULL; +} + +/* FIXME: factor out to dm core. */ +static int multiple(sector_t a, sector_t b, sector_t *n) +{ + sector_t r = a; + + sector_div(r, b); + *n = r; + return a == r * b; +} + +/* Log RAID set information to kernel log. */ +static void raid_set_log(struct raid_set *rs, unsigned speed) +{ + unsigned p; + char buf[BDEVNAME_SIZE]; + + for (p = 0; p < rs->set.raid_devs; p++) + DMINFO("/dev/%s is raid disk %u", + bdevname(rs->dev[p].dev->bdev, buf), p); + + DMINFO("%d/%d/%d sectors chunk/io/recovery size, %u stripes", + rs->set.chunk_size, rs->set.io_size, rs->recover.io_size, + atomic_read(&rs->sc.stripes)); + DMINFO("algorithm \"%s\", %u chunks with %uMB/s", rs->xor.f->name, + rs->xor.chunks, mbpers(rs, speed)); + DMINFO("%s set with net %u/%u devices", rs->set.raid_type->descr, + rs->set.data_devs, rs->set.raid_devs); +} + +/* Get all devices and offsets. */ +static int +dev_parms(struct dm_target *ti, struct raid_set *rs, + char **argv, int *p) +{ + for (*p = 0; *p < rs->set.raid_devs; (*p)++, argv += 2) { + int r; + unsigned long long tmp; + struct raid_dev *dev = rs->dev + *p; + union dev_lookup dl = {.dev = dev }; + + /* Get offset and device. */ + r = sscanf(argv[1], "%llu", &tmp); + if (r != 1) + TI_ERR("Invalid RAID device offset parameter"); + + dev->start = tmp; + r = dm_get_device(ti, argv[0], dev->start, + rs->set.sectors_per_dev, + dm_table_get_mode(ti->table), &dev->dev); + if (r) + TI_ERR_RET("RAID device lookup failure", r); + + r = raid_dev_lookup(rs, bynumber, &dl); + if (r != -ENODEV && r < *p) { + (*p)++; /* Ensure dm_put_device() on actual device. */ + TI_ERR_RET("Duplicate RAID device", -ENXIO); + } + } + + return 0; +} + +/* Set recovery bandwidth. */ +static INLINE void +recover_set_bandwidth(struct raid_set *rs, unsigned bandwidth) +{ + rs->recover.bandwidth = bandwidth; + rs->recover.bandwidth_work = 100 / bandwidth; +} + +/* Handle variable number of RAID parameters. */ +static int +raid_variable_parms(struct dm_target *ti, char **argv, + unsigned i, int *raid_parms, + int *chunk_size, int *chunk_size_parm, + int *stripes, int *stripes_parm, + int *io_size, int *io_size_parm, + int *recover_io_size, int *recover_io_size_parm, + int *bandwidth, int *bandwidth_parm) +{ + /* Fetch # of variable raid parameters. */ + if (sscanf(argv[i++], "%d", raid_parms) != 1 || + !range_ok(*raid_parms, 0, 5)) + TI_ERR("Bad variable raid parameters number"); + + if (*raid_parms) { + /* + * If we've got variable RAID parameters, + * chunk size is the first one + */ + if (sscanf(argv[i++], "%d", chunk_size) != 1 || + (*chunk_size != -1 && + (!POWER_OF_2(*chunk_size) || + !range_ok(*chunk_size, IO_SIZE_MIN, CHUNK_SIZE_MAX)))) + TI_ERR ("Invalid chunk size; " + "must be 2^^n and <= 16384"); + + *chunk_size_parm = *chunk_size; + if (*chunk_size == -1) + *chunk_size = CHUNK_SIZE; + + /* + * In case we've got 2 or more variable raid + * parameters, the number of stripes is the second one + */ + if (*raid_parms > 1) { + if (sscanf(argv[i++], "%d", stripes) != 1 || + (*stripes != -1 && + !range_ok(*stripes, STRIPES_MIN, + STRIPES_MAX))) + TI_ERR("Invalid number of stripes: must " + "be >= 8 and <= 8192"); + } + + *stripes_parm = *stripes; + if (*stripes == -1) + *stripes = STRIPES; + + /* + * In case we've got 3 or more variable raid + * parameters, the io size is the third one. + */ + if (*raid_parms > 2) { + if (sscanf(argv[i++], "%d", io_size) != 1 || + (*io_size != -1 && + (!POWER_OF_2(*io_size) || + !range_ok(*io_size, IO_SIZE_MIN, + min(BIO_MAX_SECTORS / 2, + *chunk_size))))) + TI_ERR("Invalid io size; must " + "be 2^^n and less equal " + "min(BIO_MAX_SECTORS/2, chunk size)"); + } else + *io_size = *chunk_size; + + *io_size_parm = *io_size; + if (*io_size == -1) + *io_size = *chunk_size; + + /* + * In case we've got 4 variable raid parameters, + * the recovery stripe io_size is the fourth one + */ + if (*raid_parms > 3) { + if (sscanf(argv[i++], "%d", recover_io_size) != 1 || + (*recover_io_size != -1 && + (!POWER_OF_2(*recover_io_size) || + !range_ok(*recover_io_size, RECOVER_IO_SIZE_MIN, + BIO_MAX_SECTORS / 2)))) + TI_ERR("Invalid recovery io size; must be " + "2^^n and less equal BIO_MAX_SECTORS/2"); + } + + *recover_io_size_parm = *recover_io_size; + if (*recover_io_size == -1) + *recover_io_size = RECOVER_IO_SIZE; + + /* + * In case we've got 5 variable raid parameters, + * the recovery io bandwidth is the fifth one + */ + if (*raid_parms > 4) { + if (sscanf(argv[i++], "%d", bandwidth) != 1 || + (*bandwidth != -1 && + !range_ok(*bandwidth, BANDWIDTH_MIN, + BANDWIDTH_MAX))) + TI_ERR("Invalid recovery bandwidth " + "percentage; must be > 0 and <= 100"); + } + + *bandwidth_parm = *bandwidth; + if (*bandwidth == -1) + *bandwidth = BANDWIDTH; + } + + return 0; +} + +/* Parse optional locking parameters. */ +static int +raid_locking_parms(struct dm_target *ti, char **argv, + unsigned i, int *locking_parms, + struct dmraid45_locking_type **locking_type) +{ + *locking_parms = 0; + *locking_type = &locking_none; + + if (!strnicmp(argv[i], "none", strlen(argv[i]))) + *locking_parms = 1; + else if (!strnicmp(argv[i + 1], "locking", strlen(argv[i + 1]))) { + *locking_type = &locking_none; + *locking_parms = 2; + } else if (!strnicmp(argv[i + 1], "cluster", strlen(argv[i + 1]))) { + *locking_type = &locking_cluster; + /* FIXME: namespace. */ + *locking_parms = 3; + } + + return *locking_parms == 1 ? -EINVAL : 0; +} + +/* Set backing device information properties of RAID set. */ +static void rs_set_bdi(struct raid_set *rs, unsigned stripes, unsigned chunks) +{ + unsigned p, ra_pages; + struct mapped_device *md = dm_table_get_md(rs->ti->table); + struct backing_dev_info *bdi = &dm_disk(md)->queue->backing_dev_info; + + /* Set read-ahead for the RAID set and the component devices. */ + bdi->ra_pages = stripes * stripe_pages(rs, rs->set.io_size); + ra_pages = chunks * chunk_pages(rs->set.io_size); + for (p = rs->set.raid_devs; p--; ) + bdev_get_queue(rs->dev[p].dev->bdev)->backing_dev_info.ra_pages = ra_pages; + + /* Set congested function and data. */ + bdi->congested_fn = raid_set_congested; + bdi->congested_data = rs; + + dm_put(md); +} + +/* Get backing device information properties of RAID set. */ +static void rs_get_ra(struct raid_set *rs, unsigned *stripes, unsigned *chunks) +{ + struct mapped_device *md = dm_table_get_md(rs->ti->table); + + *stripes = dm_disk(md)->queue->backing_dev_info.ra_pages + / stripe_pages(rs, rs->set.io_size); + *chunks = bdev_get_queue(rs->dev->dev->bdev)->backing_dev_info.ra_pages + / chunk_pages(rs->set.io_size); + + dm_put(md); +} + +/* + * Construct a RAID4/5 mapping: + * + * log_type #log_params \ + * raid_type [#parity_dev] #raid_variable_params \ + * [locking "none"/"cluster"] + * #raid_devs #dev_to_initialize [ ]{3,} + * + * log_type = "core"/"disk", + * #log_params = 1-3 (1-2 for core dirty log type, 3 for disk dirty log only) + * log_params = [dirty_log_path] region_size [[no]sync]) + * + * raid_type = "raid4", "raid5_la", "raid5_ra", "raid5_ls", "raid5_rs" + * + * #parity_dev = N if raid_type = "raid4" + * o N = -1: pick default = last device + * o N >= 0 and < #raid_devs: parity device index + * + * #raid_variable_params = 0-5; raid_params (-1 = default): + * [chunk_size [#stripes [io_size [recover_io_size [%recovery_bandwidth]]]]] + * o chunk_size (unit to calculate drive addresses; must be 2^^n, > 8 + * and <= CHUNK_SIZE_MAX) + * o #stripes is number of stripes allocated to stripe cache + * (must be > 1 and < STRIPES_MAX) + * o io_size (io unit size per device in sectors; must be 2^^n and > 8) + * o recover_io_size (io unit size per device for recovery in sectors; + must be 2^^n, > SECTORS_PER_PAGE and <= region_size) + * o %recovery_bandwith is the maximum amount spend for recovery during + * application io (1-100%) + * If raid_variable_params = 0, defaults will be used. + * Any raid_variable_param can be set to -1 to apply a default + * + * #raid_devs = N (N >= 3) + * + * #dev_to_initialize = N + * -1: initialize parity on all devices + * >= 0 and < #raid_devs: initialize raid_path; used to force reconstruction + * of a failed devices content after replacement + * + * = device_path (eg, /dev/sdd1) + * = begin at offset on + * + */ +#define MIN_PARMS 13 +static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) +{ + int bandwidth = BANDWIDTH, bandwidth_parm = -1, + chunk_size = CHUNK_SIZE, chunk_size_parm = -1, + dev_to_init, dl_parms, locking_parms, parity_parm, pi = -1, + i, io_size = IO_SIZE, io_size_parm = -1, + r, raid_devs, raid_parms, + recover_io_size = RECOVER_IO_SIZE, recover_io_size_parm = -1, + stripes = STRIPES, stripes_parm = -1; + unsigned speed; + sector_t tmp, sectors_per_dev; + struct dmraid45_locking_type *locking; + struct raid_set *rs; + struct raid_type *raid_type; + + /* Ensure minimum number of parameters. */ + if (argc < MIN_PARMS) + TI_ERR("Not enough parameters"); + + /* Fetch # of dirty log parameters. */ + if (sscanf(argv[1], "%d", &dl_parms) != 1 + || !range_ok(dl_parms, 1, 4711)) + TI_ERR("Bad dirty log parameters number"); + + /* Check raid_type. */ + raid_type = get_raid_type(argv[dl_parms + 2]); + if (!raid_type) + TI_ERR("Bad raid type"); + + /* In case of RAID4, parity drive is selectable. */ + parity_parm = !!(raid_type->level == raid4); + + /* Handle variable number of RAID parameters. */ + r = raid_variable_parms(ti, argv, dl_parms + parity_parm + 3, + &raid_parms, + &chunk_size, &chunk_size_parm, + &stripes, &stripes_parm, + &io_size, &io_size_parm, + &recover_io_size, &recover_io_size_parm, + &bandwidth, &bandwidth_parm); + if (r) + return r; + + r = raid_locking_parms(ti, argv, + dl_parms + parity_parm + raid_parms + 4, + &locking_parms, &locking); + if (r) + return r; + + /* # of raid devices. */ + if (sscanf(argv[dl_parms + parity_parm + raid_parms + locking_parms +4], + "%d", &raid_devs) != 1 || raid_devs < raid_type->minimal_devs) + TI_ERR("Invalid number of raid devices"); + + /* In case of RAID4, check parity drive index is in limits. */ + if (raid_type->level == raid4) { + /* Fetch index of parity device. */ + if (sscanf(argv[dl_parms + 3], "%d", &pi) != 1 || + !range_ok(pi, 0, raid_devs - 1)) + TI_ERR("Invalid RAID4 parity device index"); + } + + /* + * Index of device to initialize starts at 0 + * + * o -1 -> don't initialize a particular device, + * o 0..raid_devs-1 -> initialize respective device + * (used for reconstruction of a replaced device) + */ + if (sscanf + (argv[dl_parms + parity_parm + raid_parms + locking_parms + 5], + "%d", &dev_to_init) != 1 + || !range_ok(dev_to_init, -1, raid_devs - 1)) + TI_ERR("Invalid number for raid device to initialize"); + + /* Check # of raid device arguments. */ + if (argc - dl_parms - parity_parm - raid_parms - 6 != + 2 * raid_devs) + TI_ERR("Wrong number of raid device/offset arguments"); + + /* + * Check that the table length is devisable + * w/o rest by (raid_devs - parity_devs) + */ + if (!multiple(ti->len, raid_devs - raid_type->parity_devs, + §ors_per_dev)) + TI_ERR + ("Target length not divisable by number of data devices"); + + /* + * Check that the device size is + * devisable w/o rest by chunk size + */ + if (!multiple(sectors_per_dev, chunk_size, &tmp)) + TI_ERR("Device length not divisable by chunk_size"); + + /**************************************************************** + * Now that we checked the constructor arguments -> + * let's allocate the RAID set + ****************************************************************/ + r = context_alloc(&rs, raid_type, stripes, chunk_size, io_size, + recover_io_size, raid_devs, sectors_per_dev, + ti, dl_parms, argv); + if (r) + return r; + + /* + * Set these here in order to avoid passing + * too many arguments to context_alloc() + */ + rs->set.dev_to_init_parm = dev_to_init; + rs->set.dev_to_init = dev_to_init; + rs->set.pi_parm = pi; + rs->set.pi = (pi == -1) ? rs->set.data_devs : pi; + rs->set.raid_parms = raid_parms; + rs->set.chunk_size_parm = chunk_size_parm; + rs->set.io_size_parm = io_size_parm; + rs->sc.stripes_parm = stripes_parm; + rs->recover.io_size_parm = recover_io_size_parm; + rs->recover.bandwidth_parm = bandwidth_parm; + recover_set_bandwidth(rs, bandwidth); + + /* Use locking type to lock stripe access. */ + rs->locking = locking; + + /* Get the device/offset tupels. */ + argv += dl_parms + 6 + parity_parm + raid_parms; + r = dev_parms(ti, rs, argv, &i); + if (r) + goto err; + + /* Initialize recovery. */ + rs->recover.start_jiffies = jiffies; + rs->recover.end_jiffies = 0; + recovery_region_reset(rs); + SetRSRecover(rs); + + /* Set backing device information (eg. read ahead). */ + rs_set_bdi(rs, chunk_size * 2, io_size * 4); + SetRSCheckOverwrite(rs); /* Allow chunk overwrite checks. */ + + speed = xor_optimize(rs); /* Select best xor algorithm. */ + + /* Initialize work queue to handle this RAID set's io. */ + r = rs_workqueue_init(rs); + if (r) + goto err; + + raid_set_log(rs, speed); /* Log information about RAID set. */ + + /* + * Make sure that dm core only hands maximum io size + * length down and pays attention to io boundaries. + */ + ti->split_io = rs->set.io_size; + ti->private = rs; + return 0; + + err: + context_free(rs, ti, i); + return r; +} + +/* + * Destruct a raid mapping + */ +static void raid_dtr(struct dm_target *ti) +{ + struct raid_set *rs = ti->private; + + /* Indicate recovery end. */ + ClearRSRecover(rs); + wake_do_raid(rs); /* Wake daemon. */ + wait_ios(rs); /* Wait for any io still being processed. */ + destroy_workqueue(rs->io.wq); + context_free(rs, ti, rs->set.raid_devs); +} + +/* Queues ios to RAID sets. */ +static inline void queue_bio(struct raid_set *rs, struct bio *bio) +{ + int wake; + struct bio_list *in = &rs->io.in; + spinlock_t *in_lock = &rs->io.in_lock; + + spin_lock_irq(in_lock); + wake = bio_list_empty(in); + bio_list_add(in, bio); + spin_unlock_irq(in_lock); + + /* Wake daemon if input list was empty. */ + if (wake) + wake_do_raid(rs); +} + +/* Raid mapping function. */ +static int raid_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) +{ + /* I don't want to waste stripe cache capacity. */ + if (bio_rw(bio) == READA) + return -EIO; + else { + struct raid_set *rs = ti->private; + + /* REMOVEME: statistics. */ + atomic_inc(rs->stats + + (bio_data_dir(bio) == WRITE ? + S_BIOS_WRITE : S_BIOS_READ)); + + /* + * Get io reference to be waiting for to drop + * to zero on device suspension/destruction. + */ + io_get(rs); + bio->bi_sector -= ti->begin; /* Remap sector. */ + queue_bio(rs, bio); /* Queue to the daemon. */ + return DM_MAPIO_SUBMITTED; /* Handle later. */ + } +} + +/* Device suspend. */ +static void raid_postsuspend(struct dm_target *ti) +{ + struct raid_set *rs = ti->private; + struct dm_dirty_log *dl = rs->recover.dl; + + SetRSSuspended(rs); + + if (RSRecover(rs)) + rh_stop_recovery(rs->recover.rh); /* Wakes do_raid(). */ + else + wake_do_raid(rs); + + wait_ios(rs); /* Wait for completion of all ios being processed. */ + if (dl->type->postsuspend && dl->type->postsuspend(dl)) + /* Suspend dirty log. */ + /* FIXME: need better error handling. */ + DMWARN("log suspend failed"); +} + +/* Device resume. */ +static void raid_resume(struct dm_target *ti) +{ + struct raid_set *rs = ti->private; + struct dm_dirty_log *dl = rs->recover.dl; + + if (dl->type->resume && dl->type->resume(dl)) + /* Resume dirty log. */ + /* FIXME: need better error handling. */ + DMWARN("log resume failed"); + + rs->recover.nr_regions_to_recover = + rs->recover.nr_regions - dl->type->get_sync_count(dl); + + ClearRSSuspended(rs); + + /* Reset any unfinished recovery. */ + if (RSRecover(rs)) { + recovery_region_reset(rs); + rh_start_recovery(rs->recover.rh); /* Calls wake_do_raid(). */ + } else + wake_do_raid(rs); +} + +static INLINE unsigned sc_size(struct raid_set *rs) +{ + return to_sector(atomic_read(&rs->sc.stripes) * + (sizeof(struct stripe) + + (sizeof(struct stripe_set) + + (sizeof(struct page_list) + + to_bytes(rs->set.io_size) * + rs->set.raid_devs)) + + (rs->recover. + end_jiffies ? 0 : to_bytes(rs->set.raid_devs * + rs->recover. + io_size)))); +} + +/* REMOVEME: status output for development. */ +static void +raid_devel_stats(struct dm_target *ti, char *result, + unsigned *size, unsigned maxlen) +{ + unsigned chunks, stripes, sz = *size; + unsigned long j; + char buf[BDEVNAME_SIZE], *p; + struct stats_map *sm, *sm_end = ARRAY_END(stats_map); + struct raid_set *rs = ti->private; + struct recover *rec = &rs->recover; + struct timespec ts; + + DMEMIT("%s ", version); + DMEMIT("io_inprocess=%d ", atomic_read(&rs->io.in_process)); + DMEMIT("io_inprocess_max=%d ", atomic_read(&rs->io.in_process_max)); + + for (sm = stats_map; sm < sm_end; sm++) + DMEMIT("%s%d", sm->str, atomic_read(rs->stats + sm->type)); + + DMEMIT(" overwrite=%s ", RSCheckOverwrite(rs) ? "on" : "off"); + DMEMIT("sc=%u/%u/%u/%u/%u ", rs->set.chunk_size, rs->set.io_size, + atomic_read(&rs->sc.stripes), rs->sc.hash.buckets, + sc_size(rs)); + + j = (rec->end_jiffies ? rec->end_jiffies : jiffies) - + rec->start_jiffies; + jiffies_to_timespec(j, &ts); + sprintf(buf, "%ld.%ld", ts.tv_sec, ts.tv_nsec); + p = strchr(buf, '.'); + p[3] = 0; + + DMEMIT("rg=%llu%s/%llu/%llu/%u %s ", + (unsigned long long) rec->nr_regions_recovered, + RSRegionGet(rs) ? "+" : "", + (unsigned long long) rec->nr_regions_to_recover, + (unsigned long long) rec->nr_regions, rec->bandwidth, buf); + + rs_get_ra(rs, &stripes, &chunks); + DMEMIT("ra=%u/%u ", stripes, chunks); + + *size = sz; +} + +static int +raid_status(struct dm_target *ti, status_type_t type, + char *result, unsigned maxlen) +{ + unsigned i, sz = 0; + char buf[BDEVNAME_SIZE]; + struct raid_set *rs = ti->private; + + switch (type) { + case STATUSTYPE_INFO: + /* REMOVEME: statistics. */ + if (RSDevelStats(rs)) + raid_devel_stats(ti, result, &sz, maxlen); + + DMEMIT("%u ", rs->set.raid_devs); + + for (i = 0; i < rs->set.raid_devs; i++) + DMEMIT("%s ", + format_dev_t(buf, rs->dev[i].dev->bdev->bd_dev)); + + DMEMIT("1 "); + for (i = 0; i < rs->set.raid_devs; i++) { + DMEMIT("%c", + dev_operational(rs, i) ? 'A' : 'D'); + + if (rs->set.raid_type->level == raid4 && + i == rs->set.pi) + DMEMIT("p"); + + if (rs->set.dev_to_init == i) + DMEMIT("i"); + } + + break; + + case STATUSTYPE_TABLE: + sz = rs->recover.dl->type->status(rs->recover.dl, type, + result, maxlen); + DMEMIT("%s %u ", rs->set.raid_type->name, + rs->set.raid_parms); + + if (rs->set.raid_type->level == raid4) + DMEMIT("%d ", rs->set.pi_parm); + + if (rs->set.raid_parms) + DMEMIT("%d ", rs->set.chunk_size_parm); + + if (rs->set.raid_parms > 1) + DMEMIT("%d ", rs->sc.stripes_parm); + + if (rs->set.raid_parms > 2) + DMEMIT("%d ", rs->set.io_size_parm); + + if (rs->set.raid_parms > 3) + DMEMIT("%d ", rs->recover.io_size_parm); + + if (rs->set.raid_parms > 4) + DMEMIT("%d ", rs->recover.bandwidth_parm); + + DMEMIT("%u %d ", rs->set.raid_devs, rs->set.dev_to_init); + + for (i = 0; i < rs->set.raid_devs; i++) + DMEMIT("%s %llu ", + format_dev_t(buf, + rs->dev[i].dev->bdev->bd_dev), + (unsigned long long) rs->dev[i].start); + } + + return 0; +} + +/* + * Message interface + */ +enum raid_msg_actions { + act_bw, /* Recovery bandwidth switch. */ + act_dev, /* Device failure switch. */ + act_overwrite, /* Stripe overwrite check. */ + act_read_ahead, /* Set read ahead. */ + act_stats, /* Development statistics switch. */ + act_sc, /* Stripe cache switch. */ + + act_on, /* Set entity on. */ + act_off, /* Set entity off. */ + act_reset, /* Reset entity. */ + + act_set = act_on, /* Set # absolute. */ + act_grow = act_off, /* Grow # by an amount. */ + act_shrink = act_reset, /* Shrink # by an amount. */ +}; + +/* Turn a delta to absolute. */ +static int _absolute(unsigned long action, int act, int r) +{ + /* Make delta absolute. */ + if (test_bit(act_set, &action)); + else if (test_bit(act_grow, &action)) + r += act; + else if (test_bit(act_shrink, &action)) + r = act - r; + else + r = -EINVAL; + + return r; +} + + /* Change recovery io bandwidth. */ +static int bandwidth_change(struct dm_msg *msg, void *context) +{ + struct raid_set *rs = context; + int act = rs->recover.bandwidth; + int bandwidth = DM_MSG_INT_ARG(msg); + + if (range_ok(bandwidth, BANDWIDTH_MIN, BANDWIDTH_MAX)) { + /* Make delta bandwidth absolute. */ + bandwidth = _absolute(msg->action, act, bandwidth); + + /* Check range. */ + if (range_ok(bandwidth, BANDWIDTH_MIN, BANDWIDTH_MAX)) { + recover_set_bandwidth(rs, bandwidth); + return 0; + } + } + + set_bit(dm_msg_ret_arg, &msg->ret); + set_bit(dm_msg_ret_inval, &msg->ret); + return -EINVAL; +} + +/* Change state of a device (running/offline). */ +/* FIXME: this only works while recovering!. */ +static int device_state(struct dm_msg *msg, void *context) +{ + int r; + const char *str = "is already "; + union dev_lookup dl = { .dev_name = DM_MSG_STR_ARG(msg) }; + struct raid_set *rs = context; + + r = raid_dev_lookup(rs, strchr(dl.dev_name, ':') ? + bymajmin : byname, &dl); + if (r == -ENODEV) { + DMERR("device %s is no member of this set", dl.dev_name); + return r; + } + + if (test_bit(act_off, &msg->action)) { + if (dev_operational(rs, r)) + str = ""; + } else if (!dev_operational(rs, r)) + str = ""; + + DMINFO("/dev/%s %s%s", dl.dev_name, str, + test_bit(act_off, &msg->action) ? "offline" : "running"); + + return test_bit(act_off, &msg->action) ? + raid_set_check_and_degrade(rs, NULL, r) : + raid_set_check_and_upgrade(rs, r); +} + +/* Set/reset development feature flags. */ +static int devel_flags(struct dm_msg *msg, void *context) +{ + struct raid_set *rs = context; + + if (test_bit(act_on, &msg->action)) + return test_and_set_bit(msg->spec->parm, + &rs->io.flags) ? -EPERM : 0; + else if (test_bit(act_off, &msg->action)) + return test_and_clear_bit(msg->spec->parm, + &rs->io.flags) ? 0 : -EPERM; + else if (test_bit(act_reset, &msg->action)) { + if (test_bit(act_stats, &msg->action)) { + stats_reset(rs); + goto on; + } else if (test_bit(act_overwrite, &msg->action)) { + on: + set_bit(msg->spec->parm, &rs->io.flags); + return 0; + } + } + + return -EINVAL; +} + + /* Set stripe and chunk read ahead pages. */ +static int read_ahead_set(struct dm_msg *msg, void *context) +{ + int stripes = DM_MSG_INT_ARGS(msg, 0); + int chunks = DM_MSG_INT_ARGS(msg, 1); + + if (range_ok(stripes, 1, 512) && + range_ok(chunks, 1, 512)) { + rs_set_bdi(context, stripes, chunks); + return 0; + } + + set_bit(dm_msg_ret_arg, &msg->ret); + set_bit(dm_msg_ret_inval, &msg->ret); + return -EINVAL; +} + +/* Resize the stripe cache. */ +static int stripecache_resize(struct dm_msg *msg, void *context) +{ + int act, stripes; + struct raid_set *rs = context; + + /* Deny permission in case the daemon is still shrinking!. */ + if (atomic_read(&rs->sc.stripes_to_shrink)) + return -EPERM; + + stripes = DM_MSG_INT_ARG(msg); + if (stripes > 0) { + act = atomic_read(&rs->sc.stripes); + + /* Make delta stripes absolute. */ + stripes = _absolute(msg->action, act, stripes); + + /* + * Check range and that the # of stripes changes. + * We can grow from gere but need to leave any + * shrinking to the worker for synchronization. + */ + if (range_ok(stripes, STRIPES_MIN, STRIPES_MAX)) { + if (stripes > act) + return sc_grow(&rs->sc, stripes - act, grow); + else if (stripes < act) { + atomic_set(&rs->sc.stripes_to_shrink, + act - stripes); + wake_do_raid(rs); + } + + return 0; + } + } + + set_bit(dm_msg_ret_arg, &msg->ret); + set_bit(dm_msg_ret_inval, &msg->ret); + return -EINVAL; +} + +/* Parse the RAID message action. */ +/* + * 'ba[ndwidth] {se[t],g[row],sh[rink]} #' # e.g 'ba se 50' + * 'de{vice] o[ffline]/r[unning] DevName/maj:min' # e.g 'device o /dev/sda' + * "o[verwrite] {on,of[f],r[eset]}' # e.g. 'o of' + * "r[ead_ahead] set #stripes #chunks # e.g. 'r se 3 2' + * 'sta[tistics] {on,of[f],r[eset]}' # e.g. 'stat of' + * 'str[ipecache] {se[t],g[row],sh[rink]} #' # e.g. 'stripe set 1024' + * + */ +static int +raid_message(struct dm_target *ti, unsigned argc, char **argv) +{ + /* Variables to store the parsed parameters im. */ + static int i[2]; + static unsigned long *i_arg[] = { + (unsigned long *) i + 0, + (unsigned long *) i + 1, + }; + static char *p; + static unsigned long *p_arg[] = { (unsigned long *) &p }; + + /* Declare all message option strings. */ + static char *str_sgs[] = { "set", "grow", "shrink" }; + static char *str_dev[] = { "running", "offline" }; + static char *str_oor[] = { "on", "off", "reset" }; + + /* Declare all actions. */ + static unsigned long act_sgs[] = { act_set, act_grow, act_shrink }; + static unsigned long act_oor[] = { act_on, act_off, act_reset }; + + /* Bandwidth option. */ + static struct dm_message_option bw_opt = { 3, str_sgs, act_sgs }; + static struct dm_message_argument bw_args = + { 1, i_arg, { dm_msg_int_t } }; + + /* Device option. */ + static struct dm_message_option dev_opt = { 2, str_dev, act_oor }; + static struct dm_message_argument dev_args = + { 1, p_arg, { dm_msg_base_t } }; + + /* Read ahead option. */ + static struct dm_message_option ra_opt = { 1, str_sgs, act_sgs }; + static struct dm_message_argument ra_args = + { 2, i_arg, { dm_msg_int_t, dm_msg_int_t } }; + + static struct dm_message_argument null_args = + { 0, NULL, { dm_msg_int_t } }; + + /* Overwrite and statistics option. */ + static struct dm_message_option ovr_stats_opt = { 3, str_oor, act_oor }; + + /* Sripecache option. */ + static struct dm_message_option stripe_opt = { 3, str_sgs, act_sgs }; + + /* Declare messages. */ + static struct dm_msg_spec specs[] = { + { "bandwidth", act_bw, &bw_opt, &bw_args, + 0, bandwidth_change }, + { "device", act_dev, &dev_opt, &dev_args, + 0, device_state }, + { "overwrite", act_overwrite, &ovr_stats_opt, &null_args, + RS_CHECK_OVERWRITE, devel_flags }, + { "read_ahead", act_read_ahead, &ra_opt, &ra_args, + 0, read_ahead_set }, + { "statistics", act_stats, &ovr_stats_opt, &null_args, + RS_DEVEL_STATS, devel_flags }, + { "stripecache", act_sc, &stripe_opt, &bw_args, + 0, stripecache_resize }, + }; + + /* The message for the parser. */ + struct dm_msg msg = { + .num_specs = ARRAY_SIZE(specs), + .specs = specs, + }; + + return dm_message_parse(TARGET, &msg, ti->private, argc, argv); +} +/* + * END message interface + */ + +static struct target_type raid_target = { + .name = "raid45", + .version = {1, 0, 0}, + .module = THIS_MODULE, + .ctr = raid_ctr, + .dtr = raid_dtr, + .map = raid_map, + .postsuspend = raid_postsuspend, + .resume = raid_resume, + .status = raid_status, + .message = raid_message, +}; + +static void init_exit(const char *bad_msg, const char *good_msg, int r) +{ + if (r) + DMERR("Failed to %sregister target [%d]", bad_msg, r); + else + DMINFO("%s %s", good_msg, version); +} + +static int __init dm_raid_init(void) +{ + int r; + + r = dm_register_target(&raid_target); + init_exit("", "initialized", r); + return r; +} + +static void __exit dm_raid_exit(void) +{ + int r; + + r = dm_unregister_target(&raid_target); + init_exit("un", "exit", r); +} + +/* Module hooks. */ +module_init(dm_raid_init); +module_exit(dm_raid_exit); + +MODULE_DESCRIPTION(DM_NAME " raid4/5 target"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/Makefile +++ linux-2.6.28/ubuntu/dm-raid4-5/Makefile @@ -0,0 +1,3 @@ +EXTRA_CFLAGS += -I$(srctree)/drivers/md + +obj-$(CONFIG_DM_RAID45) += dm-raid4-5.o dm-mem-cache.o dm-region_hash.o dm-message.o --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-region_hash.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-region_hash.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2003 Sistina Software Limited. + * Copyright (C) 2004-2007 Red Hat Inc. + * + * This file is released under the GPL. + */ + +#ifndef DM_RH_H +#define DM_RH_H + +#include "dm.h" +#include +#include "dm-bio-list.h" + +/*----------------------------------------------------------------- + * Region hash + *----------------------------------------------------------------*/ + +/* + * States a region can have. + */ +enum { + RH_CLEAN = 0x01, /* No writes in flight. */ + RH_DIRTY = 0x02, /* Writes in flight. */ + RH_NOSYNC = 0x04, /* Out of sync. */ + RH_RECOVERING = 0x08, /* Under resynchronization. */ + RH_ERROR = 0x10, /* Error recovering region */ +}; + +/* + * Conversion fns + */ +region_t rh_bio_to_region(void *rh, struct bio *bio); +region_t rh_sector_to_region(void *rh, sector_t sector); +sector_t rh_region_to_sector(void *rh, region_t region); + + +/* + * Functions to set a caller context in a region. + */ +void *rh_reg_get_context(void *reg); +void rh_reg_set_context(void *reg, void *context); + +/* + * Reagion hash and region parameters. + */ +region_t rh_get_region_size(void *rh); +sector_t rh_get_region_key(void *reg); + +int rh_init(void **rh, + unsigned int max_recovery, + void (*dispatch)(void *dispatch_context, struct bio_list *bios), + void *dispatch_context, + void (*wake)(void *wake_context), + void *wake_context, + struct dm_dirty_log *log, uint32_t region_size, region_t nr_regions); +void rh_exit(void *rh); + +int rh_state(void *rh, region_t region, int may_block); +void rh_update_states(void *rh); +void rh_flush(void *rh); + +void rh_inc(void *rh, region_t region); +void rh_inc_pending(void *rh, struct bio_list *bios); +void rh_dec(void *rh, region_t region); +void rh_delay(void *rh, struct bio *bio); +void rh_delay_by_region(void *rh, struct bio *bio, region_t region); + +int rh_recovery_prepare(void *rh); +void *rh_recovery_start(void *rh); +void rh_recovery_end(void *reg, int error); +void rh_stop_recovery(void *rh); +void rh_start_recovery(void *rh); + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-message.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-message.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * This file is released under the GPL. + * + */ + +#ifndef DM_MESSAGE_H +#define DM_MESSAGE_H + +/* Factor out to dm.h. */ +/* Reference to array end. */ +#define ARRAY_END(a) ((a) + ARRAY_SIZE(a)) + +/* Message return bits. */ +enum dm_message_return { + dm_msg_ret_ambiguous, /* Action ambiguous. */ + dm_msg_ret_inval, /* Action invalid. */ + dm_msg_ret_undef, /* Action undefined. */ + + dm_msg_ret_option, /* Option error. */ + dm_msg_ret_arg, /* Argument error. */ + dm_msg_ret_argcount, /* Argument count error. */ +}; + +/* Message argument type conversions. */ +enum dm_message_argument_type { + dm_msg_base_t, /* Basename string. */ + dm_msg_str_t, /* String. */ + dm_msg_int_t, /* Signed int. */ + dm_msg_uint_t, /* Unsigned int. */ + dm_msg_uint64_t, /* Unsigned int 64. */ +}; + +/* A message option. */ +struct dm_message_option { + unsigned num_options; + char **options; + unsigned long *actions; +}; + +/* Message arguments and types. */ +struct dm_message_argument { + unsigned num_args; + unsigned long **ptr; + enum dm_message_argument_type types[]; +}; + +/* Client message. */ +struct dm_msg { + unsigned long action; /* Identified action. */ + unsigned long ret; /* Return bits. */ + unsigned num_specs; /* # of sepcifications listed. */ + struct dm_msg_spec *specs; /* Specification list. */ + struct dm_msg_spec *spec; /* Specification selected. */ +}; + +/* Secification of the message. */ +struct dm_msg_spec { + const char *cmd; /* Name of the command (i.e. 'bandwidth'). */ + unsigned long action; + struct dm_message_option *options; + struct dm_message_argument *args; + unsigned long parm; /* Parameter to pass through to callback. */ + /* Function to process for action. */ + int (*f) (struct dm_msg *msg, void *context); +}; + +/* Parameter access macros. */ +#define DM_MSG_PARM(msg) ((msg)->spec->parm) + +#define DM_MSG_STR_ARGS(msg, idx) ((char*) *(msg)->spec->args->ptr[idx]) +#define DM_MSG_INT_ARGS(msg, idx) ((int) *(msg)->spec->args->ptr[idx]) +#define DM_MSG_UINT_ARGS(msg, idx) ((unsigned) DM_MSG_INT_ARG(msg, idx)) +#define DM_MSG_UINT64_ARGS(msg, idx) ((uint64_t) *(msg)->spec->args->ptr[idx]) + +#define DM_MSG_STR_ARG(msg) DM_MSG_STR_ARGS(msg, 0) +#define DM_MSG_INT_ARG(msg) DM_MSG_INT_ARGS(msg, 0) +#define DM_MSG_UINT_ARG(msg) DM_MSG_UINT_ARGS(msg, 0) +#define DM_MSG_UINT64_ARG(msg) DM_MSG_UINT64_ARGS(msg, 0) + + +/* Parse a message and its options and optionally call a function back. */ +int dm_message_parse(const char *caller, struct dm_msg *msg, void *context, + int argc, char **argv); + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-mem-cache.c +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-mem-cache.c @@ -0,0 +1,292 @@ +/* + * Copyright (C) 2006,2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * Allocate/free total_pages to a per client page pool. + * Allocate/free memory objects with chunks (1..n) of pages_per_chunk pages + * hanging off. + * + * This file is released under the GPL. + */ + +#define DM_MEM_CACHE_VERSION "0.2" + +#include "dm.h" +#include +#include "dm-mem-cache.h" + +struct dm_mem_cache_client { + spinlock_t lock; + mempool_t *objs_pool; + struct page_list *free_list; + unsigned objects; + unsigned chunks; + unsigned free_pages; + unsigned total_pages; +}; + +/* + * Free pages and page_list elements of client. + */ +static void free_cache_pages(struct page_list *list) +{ + while (list) { + struct page_list *pl = list; + + list = pl->next; + BUG_ON(!pl->page); + __free_page(pl->page); + kfree(pl); + } +} + +/* + * Alloc number of pages and page_list elements as required by client. + */ +static struct page_list *alloc_cache_pages(unsigned pages) +{ + struct page_list *pl, *ret = NULL; + struct page *page; + + while (pages--) { + page = alloc_page(GFP_NOIO); + if (!page) + goto err; + + pl = kmalloc(sizeof(*pl), GFP_NOIO); + if (!pl) { + __free_page(page); + goto err; + } + + pl->page = page; + pl->next = ret; + ret = pl; + } + + return ret; + + err: + free_cache_pages(ret); + return NULL; +} + +/* + * Allocate page_list elements from the pool to chunks of the mem object + */ +static void alloc_chunks(struct dm_mem_cache_client *cl, + struct dm_mem_cache_object *obj, + unsigned pages_per_chunk) +{ + unsigned chunks = cl->chunks; + unsigned long flags; + + local_irq_save(flags); + local_irq_disable(); + while (chunks--) { + unsigned p = pages_per_chunk; + + obj[chunks].pl = NULL; + + while (p--) { + struct page_list *pl; + + /* Take next element from free list */ + spin_lock(&cl->lock); + pl = cl->free_list; + BUG_ON(!pl); + cl->free_list = pl->next; + spin_unlock(&cl->lock); + + pl->next = obj[chunks].pl; + obj[chunks].pl = pl; + } + } + + local_irq_restore(flags); +} + +/* + * Free page_list elements putting them back onto free list + */ +static void free_chunks(struct dm_mem_cache_client *cl, + struct dm_mem_cache_object *obj) +{ + unsigned chunks = cl->chunks; + unsigned long flags; + struct page_list *next, *pl; + + local_irq_save(flags); + local_irq_disable(); + while (chunks--) { + for (pl = obj[chunks].pl; pl; pl = next) { + next = pl->next; + + spin_lock(&cl->lock); + pl->next = cl->free_list; + cl->free_list = pl; + cl->free_pages++; + spin_unlock(&cl->lock); + } + } + + local_irq_restore(flags); +} + +/* + * Create/destroy dm memory cache client resources. + */ +struct dm_mem_cache_client * +dm_mem_cache_client_create(unsigned total_pages, unsigned objects, + unsigned chunks) +{ + struct dm_mem_cache_client *client; + + client = kzalloc(sizeof(*client), GFP_KERNEL); + if (!client) + return ERR_PTR(-ENOMEM); + + client->objs_pool = mempool_create_kmalloc_pool(objects, chunks * sizeof(struct dm_mem_cache_object)); + if (!client->objs_pool) + goto err; + + client->free_list = alloc_cache_pages(total_pages); + if (!client->free_list) + goto err1; + + spin_lock_init(&client->lock); + client->objects = objects; + client->chunks = chunks; + client->free_pages = client->total_pages = total_pages; + return client; + + err1: + mempool_destroy(client->objs_pool); + err: + kfree(client); + return ERR_PTR(-ENOMEM); +} + +void dm_mem_cache_client_destroy(struct dm_mem_cache_client *cl) +{ + BUG_ON(cl->free_pages != cl->total_pages); + free_cache_pages(cl->free_list); + mempool_destroy(cl->objs_pool); + kfree(cl); +} + +/* + * Grow a clients cache by an amount of pages. + * + * Don't call from interrupt context! + */ +int dm_mem_cache_grow(struct dm_mem_cache_client *cl, + unsigned pages_per_chunk) +{ + unsigned pages = cl->chunks * pages_per_chunk; + struct page_list *pl = alloc_cache_pages(pages), *last = pl; + + if (!pl) + return -ENOMEM; + + while (last->next) + last = last->next; + + spin_lock_irq(&cl->lock); + last->next = cl->free_list; + cl->free_list = pl; + cl->free_pages += pages; + cl->total_pages += pages; + cl->objects++; + spin_unlock_irq(&cl->lock); + + mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO); + return 0; +} + +/* Shrink a clients cache by an amount of pages */ +int dm_mem_cache_shrink(struct dm_mem_cache_client *cl, + unsigned pages_per_chunk) +{ + int r = 0; + unsigned pages = cl->chunks * pages_per_chunk, p = pages; + unsigned long flags; + struct page_list *last = NULL, *pl, *pos; + + spin_lock_irqsave(&cl->lock, flags); + pl = pos = cl->free_list; + while (p-- && pos->next) { + last = pos; + pos = pos->next; + } + + if (++p) + r = -ENOMEM; + else { + cl->free_list = pos; + cl->free_pages -= pages; + cl->total_pages -= pages; + cl->objects--; + last->next = NULL; + } + spin_unlock_irqrestore(&cl->lock, flags); + + if (!r) { + free_cache_pages(pl); + mempool_resize(cl->objs_pool, cl->objects, GFP_NOIO); + } + + return r; +} + +/* + * Allocate/free a memory object + * + * Can be called from interrupt context + */ +struct dm_mem_cache_object *dm_mem_cache_alloc(struct dm_mem_cache_client *cl, + unsigned pages_per_chunk) +{ + int r = 0; + unsigned pages = cl->chunks * pages_per_chunk; + unsigned long flags; + struct dm_mem_cache_object *obj; + + obj = mempool_alloc(cl->objs_pool, GFP_NOIO); + if (!obj) + return ERR_PTR(-ENOMEM); + + spin_lock_irqsave(&cl->lock, flags); + if (pages > cl->free_pages) + r = -ENOMEM; + else + cl->free_pages -= pages; + spin_unlock_irqrestore(&cl->lock, flags); + + if (r) { + mempool_free(obj, cl->objs_pool); + return ERR_PTR(r); + } + + alloc_chunks(cl, obj, pages_per_chunk); + return obj; +} + +void dm_mem_cache_free(struct dm_mem_cache_client *cl, + struct dm_mem_cache_object *obj) +{ + free_chunks(cl, obj); + mempool_free(obj, cl->objs_pool); +} + +EXPORT_SYMBOL(dm_mem_cache_client_create); +EXPORT_SYMBOL(dm_mem_cache_client_destroy); +EXPORT_SYMBOL(dm_mem_cache_alloc); +EXPORT_SYMBOL(dm_mem_cache_free); +EXPORT_SYMBOL(dm_mem_cache_grow); +EXPORT_SYMBOL(dm_mem_cache_shrink); + +MODULE_DESCRIPTION(DM_NAME " dm memory cache"); +MODULE_AUTHOR("Heinz Mauelshagen "); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/dm-raid4-5/dm-mem-cache.h +++ linux-2.6.28/ubuntu/dm-raid4-5/dm-mem-cache.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2006,2007 Red Hat GmbH + * + * Module Author: Heinz Mauelshagen + * + * Allocate/free total_pages to a per client page pool. + * Allocate/free memory objects with chunks (1..n) of pages_per_chunk pages + * hanging off. + * + * This file is released under the GPL. + */ + +#ifndef _DM_MEM_CACHE_H +#define _DM_MEM_CACHE_H + +#define DM_MEM_CACHE_H_VERSION "0.1" + +#include "dm.h" + +static inline struct page_list *pl_elem(struct page_list *pl, unsigned int p) +{ + while (pl && p--) + pl = pl->next; + + return pl; +} + +struct dm_mem_cache_object { + struct page_list *pl; /* Dynamically allocated array */ + void *private; /* Caller context reference */ +}; + +struct dm_mem_cache_client; + +/* + * Create/destroy dm memory cache client resources. + */ +struct dm_mem_cache_client *dm_mem_cache_client_create( + unsigned int total_pages, unsigned int objects, unsigned int chunks); +void dm_mem_cache_client_destroy(struct dm_mem_cache_client *client); + +/* + * Grow/shrink a dm memory cache client resources. + */ +int dm_mem_cache_grow(struct dm_mem_cache_client *client, unsigned int pages); +int dm_mem_cache_shrink(struct dm_mem_cache_client *client, unsigned int pages); + +/* + * Allocate/free a memory object + */ +struct dm_mem_cache_object * +dm_mem_cache_alloc(struct dm_mem_cache_client *client, + unsigned int pages_per_chunk); +void dm_mem_cache_free(struct dm_mem_cache_client *client, + struct dm_mem_cache_object *object); + +#endif --- linux-2.6.28.orig/ubuntu/dm-raid4-5/BOM +++ linux-2.6.28/ubuntu/dm-raid4-5/BOM @@ -0,0 +1,3 @@ +Downloaded from: http://people.redhat.com/~heinzm/sw/dm/dm-raid45/ +Current Version: 20080221 +Comments: All of the patches to dmraid1/dm-log, etc are upstream. --- linux-2.6.28.orig/ubuntu/tlsup/tlsup.h +++ linux-2.6.28/ubuntu/tlsup/tlsup.h @@ -0,0 +1,44 @@ +/* Toshiba Laptop Support -- tlsup.h + * + * General top level definitions etc for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_H +#define TLSUP_H + +#define MODULE_LOGPREFIX "tlsup: " + +#define tlsup_info(X...) printk(KERN_INFO MODULE_LOGPREFIX X) +#define tlsup_err(X...) printk(KERN_ERR MODULE_LOGPREFIX X) +#define tlsup_notice(X...) printk(KERN_NOTICE MODULE_LOGPREFIX X) + +#include "tlsup_acpi.h" +#include "tlsup_backlight.h" +#include "tlsup_hotkeys.h" +#include "tlsup_radios.h" + +#endif /* TLSUP_H */ --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_radios.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_radios.c @@ -0,0 +1,334 @@ +/* Toshiba Laptop Support -- tlsup_radios.c + * + * Radio kill switch support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include +#include +#include + +#include "tlsup.h" + +/* Module stuff */ +static int radio_powerdown_time = 100; +static int powerup_settle_time = 200; + +module_param(radio_powerdown_time, uint, 0400); +MODULE_PARM_DESC(radio_powerdown_time, "The number of milliseconds between powering off a radio and the device power."); +module_param(powerup_settle_time, uint, 0400); +MODULE_PARM_DESC(powerup_settle_time, "The number of milliseconds between powering on a device and applying radio power."); + +/* HCI registers */ +#define HCI_WIRELESS 0x0056 + +/* Value manipulation */ +#define HCI_WIRELESS_PRESENT 0x0000 +#define HCI_WIRELESS_STATUS 0x0001 +#define HCI_WIRELESS_GLOBAL_RADIO_SWITCH 0x0001 +#define HCI_WIRELESS_3GHSDPA_POWER 0x4000 +#define HCI_WIRELESS_3GHSDPA_RADIO 0x2000 +#define HCI_WIRELESS_BLUETOOTH_POWER 0x0040 +#define HCI_WIRELESS_BLUETOOTH_RADIO 0x0080 +#define HCI_WIRELESS_WLAN_RADIO 0x0200 + +/* Radio manipulation functions */ + +static u32 tlsup_radios_present = 0; + +static int tlsup_test_radio_presence(u32 this_switch) +{ + u32 swvalue; + u32 swaddr; + u32 hci_result; + u32 current_status; + + swvalue = 0; + swaddr = HCI_WIRELESS_STATUS; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + current_status = (swvalue & this_switch) ? 1 : 0; + + /* Attempt to invert the current state */ + + swvalue = !current_status; + swaddr = this_switch; + if (tlsup_hci_write_2_reg(HCI_WIRELESS, swvalue, swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + /* Read back the allegedly inverted switch status */ + swvalue = 0; + swaddr = HCI_WIRELESS_STATUS; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + if (((swvalue & this_switch) ? 1 : 0) != !current_status) + /* Failed to invert */ + return 0; + + /* inversion successful, attempt to restore previous value */ + + swvalue = current_status; + swaddr = this_switch; + + if (tlsup_hci_write_2_reg(HCI_WIRELESS, swvalue, swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + /* verify restoration of value */ + + swvalue = 0; + swaddr = HCI_WIRELESS_STATUS; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + if (((swvalue & this_switch) ? 1 : 0) != current_status) + /* Failed to restore */ + return 0; + + /* Restoration successful */ + + tlsup_radios_present |= this_switch; + return 1; +} + +static enum rfkill_state tlsup_read_switch_state(u32 this_switch) +{ + u32 swvalue = 0; + u32 swaddr = HCI_WIRELESS_STATUS; + u32 hci_result; + + if (tlsup_hci_read_2_reg(HCI_WIRELESS, &swvalue, &swaddr, &hci_result)) + return 0; + if (hci_result != HCI_SUCCESS) + return 0; + + return (swvalue & this_switch) ? RFKILL_STATE_ON : RFKILL_STATE_OFF; +} + +static void tlsup_set_switch_state(u32 this_switch, enum rfkill_state state) +{ + u32 swvalue = state; + u32 swaddr = this_switch; + u32 hci_result; + + if (tlsup_hci_write_2_reg(HCI_WIRELESS, swvalue, swaddr, &hci_result)) { + tlsup_err("Error setting switch state\n"); + } + if (hci_result != HCI_SUCCESS) { + tlsup_err("Error setting switch state\n"); + } +} + +/* Radio rfkill driver */ + +struct tlsup_radio_power_control { + u32 power_reg; + u32 radio_reg; +}; + +static int tlsup_radio_switch_set(void *data, enum rfkill_state state) +{ + struct tlsup_radio_power_control *rpc = (struct tlsup_radio_power_control *)data; + + if (state == RFKILL_STATE_OFF) { + if (rpc->radio_reg) { + tlsup_set_switch_state(rpc->radio_reg, RFKILL_STATE_OFF); + msleep(radio_powerdown_time); + } + + if (rpc->power_reg) + tlsup_set_switch_state(rpc->power_reg, RFKILL_STATE_OFF); + } else { + if (rpc->power_reg) { + tlsup_set_switch_state(rpc->power_reg, RFKILL_STATE_ON); + msleep(powerup_settle_time); + } + if (rpc->radio_reg) + tlsup_set_switch_state(rpc->radio_reg, RFKILL_STATE_ON); + } + + return 0; +} + +static struct rfkill *hsdpa_rfkill_dev = NULL; +static struct rfkill *bluetooth_rfkill_dev = NULL; +static struct rfkill *wlan_rfkill_dev = NULL; + +static struct rfkill *tlsup_register_rfkill(const char *name, enum rfkill_type rft, + u32 optional_power, + u32 optional_radio) +{ + struct tlsup_radio_power_control *rpc; + struct rfkill *ret; + enum rfkill_state curstate = RFKILL_STATE_OFF; + + ret = rfkill_allocate(NULL, rft); + + if (ret == NULL) + return NULL; + + rpc = kmalloc(sizeof(struct tlsup_radio_power_control), GFP_KERNEL); + if (rpc == NULL) { + rfkill_free(ret); + return NULL; + } + + ret->name = name; + ret->data = rpc; + + rpc->power_reg = optional_power; + rpc->radio_reg = optional_radio; + + if (optional_power) + curstate |= tlsup_read_switch_state(optional_power); + if (optional_radio) + curstate |= tlsup_read_switch_state(optional_radio); + + ret->state = curstate; + + if (optional_power) + tlsup_set_switch_state(optional_power, curstate); + if (optional_radio) + tlsup_set_switch_state(optional_radio, curstate); + + ret->toggle_radio = tlsup_radio_switch_set; + ret->user_claim_unsupported = 1; + + rfkill_register(ret); + + return ret; +} + +/* Registration functions */ + +int tlsup_register_radios(void) +{ + int hsdpa_present = 0, bluetooth_present = 0, wlan_present = 0; + int registered = 0; + + if (tlsup_test_radio_presence(HCI_WIRELESS_3GHSDPA_POWER)) { + hsdpa_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_3GHSDPA_RADIO)) { + hsdpa_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_BLUETOOTH_POWER)) { + bluetooth_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_BLUETOOTH_RADIO)) { + bluetooth_present = 1; + } + + if (tlsup_test_radio_presence(HCI_WIRELESS_WLAN_RADIO)) { + wlan_present = 1; + } + + if (hsdpa_present) { + tlsup_info("HSDPA Modem power switch %spresent, radio switch %spresent\n", + (tlsup_radios_present & HCI_WIRELESS_3GHSDPA_POWER) ? "" : "not ", + (tlsup_radios_present & HCI_WIRELESS_3GHSDPA_RADIO) ? "" : "not "); + hsdpa_rfkill_dev = tlsup_register_rfkill("tlsup-hsdpa_3g_modem", RFKILL_TYPE_WLAN, + HCI_WIRELESS_3GHSDPA_POWER, + HCI_WIRELESS_3GHSDPA_RADIO); + if (hsdpa_rfkill_dev) { + tlsup_info("HSDPA Modem claims to be %s\n", + (hsdpa_rfkill_dev->state == RFKILL_STATE_OFF) ? "off" : "on"); + registered++; + } else { + tlsup_err("Failed to register HSDPA modem switch\n"); + } + } + + if (bluetooth_present) { + tlsup_info("Bluetooth power switch %spresent, radio switch %spresent\n", + (tlsup_radios_present & HCI_WIRELESS_BLUETOOTH_POWER) ? "" : "not ", + (tlsup_radios_present & HCI_WIRELESS_BLUETOOTH_RADIO) ? "" : "not "); + bluetooth_rfkill_dev = tlsup_register_rfkill("tlsup-bluetooth", RFKILL_TYPE_BLUETOOTH, + HCI_WIRELESS_BLUETOOTH_POWER, + HCI_WIRELESS_BLUETOOTH_RADIO); + if (bluetooth_rfkill_dev) { + tlsup_info("Bluetooth claims to be %s\n", + (bluetooth_rfkill_dev->state == RFKILL_STATE_OFF) ? "off" : "on"); + registered++; + } else { + tlsup_err("Failed to register bluetooth switch\n"); + } + } + + if (wlan_present) { + tlsup_info("WLAN radio switch %spresent\n", + (tlsup_radios_present & HCI_WIRELESS_WLAN_RADIO) ? "" : "not "); + wlan_rfkill_dev = tlsup_register_rfkill("tlsup-wlan", RFKILL_TYPE_WLAN, + 0, + HCI_WIRELESS_WLAN_RADIO); + if (wlan_rfkill_dev) { + tlsup_info("WLAN claims to be %s\n", + (wlan_rfkill_dev->state == RFKILL_STATE_OFF) ? "off" : "on"); + registered++; + } else { + tlsup_err("Failed to register WLAN switch\n"); + } + } + + return registered; +} + +static inline void tlsup_free_rfkill_dev(struct rfkill *d) +{ + void *data = d->data; + rfkill_unregister(d); + kfree(data); +} + +void tlsup_deregister_radios(void) +{ + if (hsdpa_rfkill_dev) + tlsup_free_rfkill_dev(hsdpa_rfkill_dev); + if (bluetooth_rfkill_dev) + tlsup_free_rfkill_dev(bluetooth_rfkill_dev); + if (wlan_rfkill_dev) + tlsup_free_rfkill_dev(wlan_rfkill_dev); +} --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_backlight.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_backlight.h @@ -0,0 +1,44 @@ +/* Toshiba Laptop Support -- tlsup_backlight.h + * + * LCD Backlight support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_BACKLIGHT_H +#define TLSUP_BACKLIGHT_H + +/* Look for the LCD backlight support and if present, register a backlight + * class device to manage it. + * + * Returns -errno on error, 0 on success (but no registration) or 1 if + * a backlight was registered. + */ +extern int tlsup_register_backlight(void); + +/* Remove the registration of the backlight. */ +extern void tlsup_deregister_backlight(void); + +#endif /* TLSUP_BACKLIGHT_H */ --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_mod.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_mod.c @@ -0,0 +1,87 @@ +/* Toshiba Laptop Support -- tlsup_mod.c + * + * Aggregation and module structural support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include + +#include "tlsup.h" + +MODULE_AUTHOR("Daniel Silverstone"); +MODULE_DESCRIPTION("Toshiba Laptop Support Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_VERSION(TLSUP_VERSION); + +/* The following ACPI devices tend to be exported by toshiba laptops */ +MODULE_ALIAS("acpi:TOS6200"); +MODULE_ALIAS("acpi:TOS6207"); +MODULE_ALIAS("acpi:TOS6208"); + +static void toshiba_laptop_support_exit(void) +{ + tlsup_deregister_radios(); + tlsup_deregister_hotkeys(); + tlsup_deregister_backlight(); +} + +static int __init toshiba_laptop_support_init(void) +{ + int ret; + + if ((ret = tlsup_acpi_detect()) < 0) + return ret; + + tlsup_info("Toshiba Laptop Support version %s initialising...\n", + TLSUP_VERSION); + + tlsup_acpi_report(); + + if ((ret = tlsup_register_backlight()) < 0) + return ret; + + if ((ret = tlsup_register_hotkeys()) < 0) { + tlsup_deregister_backlight(); + return ret; + } + + if ((ret = tlsup_register_radios()) < 0) { + tlsup_deregister_hotkeys(); + tlsup_deregister_backlight(); + return ret; + } + + tlsup_info("Toshiba Laptop Support version %s loaded.\n", + TLSUP_VERSION); + + return 0; +} + +module_init(toshiba_laptop_support_init); +module_exit(toshiba_laptop_support_exit); --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_radios.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_radios.h @@ -0,0 +1,45 @@ +/* Toshiba Laptop Support -- tlsup_radios.h + * + * Radio kill-switch support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_RADIOS_H +#define TLSUP_RADIOS_H + +/* Look for the radio kill switch support and if present, register + * rfkill devices to manage them. This supports wifi, bluetooth and + * hsdpa modem. + * + * Returns -errno on error, 0 on success (but no registration) or the + * number of rfkills registered. + */ +extern int tlsup_register_radios(void); + +/* Remove the registration of the radios. */ +extern void tlsup_deregister_radios(void); + +#endif /* TLSUP_RADIOS_H */ --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_backlight.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_backlight.c @@ -0,0 +1,115 @@ +/* Toshiba Laptop Support -- tlsup_backlight.c + * + * LCD Backlight support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include +#include +#include + +#include "tlsup.h" + +/* HCI registers */ +#define HCI_REG_LCD_BRIGHTNESS 0x002a + +/* Value manipulation */ +#define HCI_LCD_BRIGHTNESS_BITS 3 +#define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) +#define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) + + +/* Backlight driver */ +static struct backlight_device *tlsup_backlight_device = NULL; + +static int tlsup_read_brightness(struct backlight_device *bd) +{ + u32 hci_result; + u32 value; + + if (tlsup_hci_read_1_reg(HCI_REG_LCD_BRIGHTNESS, &value, &hci_result)) + return -EFAULT; + + if (hci_result != HCI_SUCCESS) + return -EFAULT; + + return (value >> HCI_LCD_BRIGHTNESS_SHIFT); +} + +static int tlsup_set_brightness(struct backlight_device *bd) +{ + u32 hci_result; + u32 value = bd->props.brightness << HCI_LCD_BRIGHTNESS_SHIFT; + + if (tlsup_hci_write_1_reg(HCI_REG_LCD_BRIGHTNESS, value, &hci_result)) + return -EFAULT; + + if (hci_result != HCI_SUCCESS) + return -EFAULT; + + return 0; +} + +static struct backlight_ops tlsup_backlight_data = { + .get_brightness = tlsup_read_brightness, + .update_status = tlsup_set_brightness, +}; + +/* Registration functions */ + +int tlsup_register_backlight(void) +{ + u32 hci_result, ignored; + if (tlsup_hci_read_1_reg(HCI_REG_LCD_BRIGHTNESS, &ignored, &hci_result)) + return -EFAULT; + if (hci_result != HCI_SUCCESS) + return 0; + /* Present and results are sane, register the backlight driver. */ + tlsup_backlight_device = backlight_device_register("toshiba", + NULL, + NULL, + &tlsup_backlight_data); + + if (IS_ERR(tlsup_backlight_device)) { + int ret = PTR_ERR(tlsup_backlight_device); + tlsup_err("Could not register backlight device\n"); + tlsup_backlight_device = NULL; + return ret; + } + + tlsup_backlight_device->props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; + + return 1; +} + +void tlsup_deregister_backlight(void) +{ + if (tlsup_backlight_device) + backlight_device_unregister(tlsup_backlight_device); +} --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_acpi.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_acpi.c @@ -0,0 +1,162 @@ +/* Toshiba Laptop Support -- tlsup_acpi.c + * + * ACPI support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include + +#include + +#include "tlsup.h" + +/* Toshibas use one of two ACPI method named typically. + * + * The one we detect goes in here. + */ +static const char *hci_method = NULL; + +#define HCI_METHOD_1 "\\_SB_.VALD.GHCI" +#define HCI_METHOD_2 "\\_SB_.VALZ.GHCI" + +/* Check if the provided method name is a valid ACPI method for + * the machine. + * + * Return 0 if it is not valid, 1 if it is. + */ +static int is_valid_acpi_path(const char *method_name) +{ + acpi_handle handle; + acpi_status status; + + status = acpi_get_handle(NULL, (char *)method_name, &handle); + return !ACPI_FAILURE(status); +} + + +/* Detect the toshiba ACPI support and prepare the HCI. + * Returns zero on success, -errno on failure. + */ +int tlsup_acpi_detect(void) +{ + if (acpi_disabled) + return -ENODEV; + + if (is_valid_acpi_path(HCI_METHOD_1)) + hci_method = HCI_METHOD_1; + else if (is_valid_acpi_path(HCI_METHOD_2)) + hci_method = HCI_METHOD_2; + else + return -ENODEV; + + return 0; +} + +void tlsup_acpi_report(void) +{ + tlsup_info(" HCI method: %s\n", hci_method); +} + +/* Toshiba HCI IO */ + +#define HCI_WORDS (6) + +/* operations */ +#define HCI_SET 0xff00 +#define HCI_GET 0xfe00 + +static acpi_status tlsup_hci_raw_io(const u32 input[HCI_WORDS], u32 output[HCI_WORDS]) +{ + struct acpi_object_list params; + union acpi_object in_objs[HCI_WORDS]; + struct acpi_buffer results; + union acpi_object out_objs[HCI_WORDS + 1]; + acpi_status status; + int i; + + params.count = HCI_WORDS; + params.pointer = in_objs; + for (i = 0; i < HCI_WORDS; ++i) { + in_objs[i].type = ACPI_TYPE_INTEGER; + in_objs[i].integer.value = input[i]; + } + + results.length = sizeof(out_objs); + results.pointer = out_objs; + + status = acpi_evaluate_object(NULL, (char *)hci_method, ¶ms, + &results); + if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) { + for (i = 0; i < out_objs->package.count; ++i) { + output[i] = out_objs->package.elements[i].integer.value; + } + } + + return status; +} + +int tlsup_hci_read_1_reg(u32 reg, u32 *result, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_GET, reg, 0, 0, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *result = hci_output[2]; + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + +int tlsup_hci_write_1_reg(u32 reg, u32 value, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_SET, reg, value, 0, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + +int tlsup_hci_read_2_reg(u32 reg, u32 *result1, u32 *result2, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_GET, reg, *result1, *result2, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *result1 = hci_output[2]; + *result2 = hci_output[3]; + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + +int tlsup_hci_write_2_reg(u32 reg, u32 value1, u32 value2, u32 *hci_status) +{ + u32 hci_input[HCI_WORDS] = { HCI_SET, reg, value1, value2, 0, 0 }; + u32 hci_output[HCI_WORDS]; + acpi_status status = tlsup_hci_raw_io(hci_input, hci_output); + *hci_status = (status == AE_OK) ? hci_output[0] : HCI_FAILURE; + return (status == AE_OK) ? 0 : -EIO; +} + --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_acpi.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_acpi.h @@ -0,0 +1,81 @@ +/* Toshiba Laptop Support -- tlsup_acpi.h + * + * ACPI support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_ACPI_H +#define TLSUP_ACPI_H + +/* Detect the toshiba ACPI support and prepare the HCI. + * Returns zero on success, -errno on failure. + */ +extern int tlsup_acpi_detect(void); + +/* Report the details of the chosen/found ACPI interface to the kernel + * log + */ +extern void tlsup_acpi_report(void); + +/* Toshiba HCI */ + +#define HCI_SUCCESS 0x0000 +#define HCI_FAILURE 0x1000 +#define HCI_NOT_SUPPORTED 0x8000 +#define HCI_EMPTY 0x8c00 + +/* perform an HCI read operation, returning one u32 value and the + * HCI status. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_read_1_reg(u32 reg, u32 *result, u32 *hci_status); + +/* perform an HCI write operation with one u32 value and returning the + * HCI status. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_write_1_reg(u32 reg, u32 value, u32 *hci_status); + +/* perform an HCI read operation, returning two u32 values and the HCI + * status. + * + * The two values are passed to the call, so zero them if you don't + * want that. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_read_2_reg(u32 reg, u32 *result1, u32 *result2, u32 *hci_status); + +/* perform an HCI write operation with two u32 values and returning + * the HCI status. + * + * The function itself returns 0 on success, -errno on failure. + */ +extern int tlsup_hci_write_2_reg(u32 reg, u32 value1, u32 value2, u32 *hci_status); + +#endif /* TLSUP_ACPI_H */ --- linux-2.6.28.orig/ubuntu/tlsup/Kconfig +++ linux-2.6.28/ubuntu/tlsup/Kconfig @@ -0,0 +1,4 @@ +config TLSUP + tristate "Toshiba ACPI laptop driver" + depends on ACPI && X86 + default m --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_hotkeys.h +++ linux-2.6.28/ubuntu/tlsup/tlsup_hotkeys.h @@ -0,0 +1,45 @@ +/* Toshiba Laptop Support -- tlsup_hotkeys.h + * + * Hotkeys input support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#ifndef TLSUP_HOTKEYS_H +#define TLSUP_HOTKEYS_H + +/* Look for the hotkey support in the HCI and if found, register with + * input-polldev to get an input device to provide events to userland + * with. + * + * Returns -errno on error, 0 on success (but no registration) or 1 if + * an input device was registered. + */ +extern int tlsup_register_hotkeys(void); + +/* Remove the registration of the hotkeys input device. */ +extern void tlsup_deregister_hotkeys(void); + +#endif /* TLSUP_BACKLIGHT_H */ --- linux-2.6.28.orig/ubuntu/tlsup/tlsup_hotkeys.c +++ linux-2.6.28/ubuntu/tlsup/tlsup_hotkeys.c @@ -0,0 +1,238 @@ +/* Toshiba Laptop Support -- tlsup_hotkeys.c + * + * Hotkeys input support for T.L.S. + * + * Copyright 2008 Daniel Silverstone + * + * 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; specifically 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. + * + * + * Credits: + * Jonathan A. Buzzard - Toshiba HCI info, and critical tips on reverse + * engineering the Windows drivers + * Rob Miller - TV out and hotkeys help + * John Belmonte - The toshiba_acpi driver maintainance for some time. + */ + +#include +#include +#include +#include +#include +#include + +#include "tlsup.h" + +/* HCI registers */ +#define HCI_SYSTEM_EVENT 0x0016 + +/* Value manipulation */ + +/* Module stuff */ +static int hotkeys_checks_per_second = 4; +module_param(hotkeys_checks_per_second, uint, 0400); +MODULE_PARM_DESC(hotkeys_checks_per_second, "The number of times per second that the kernel will poll the HCI for hotkey events."); + +/* Keycode system */ + +struct key_entry { + u8 fncode; + u16 keycode; +}; + +static struct key_entry tlsup_hotkey_map[] = { + {2, KEY_FN_1}, + {0, 0} +}; + +static struct key_entry *tlsup_get_entry_by_scancode(int code) +{ + struct key_entry *key; + + for (key = tlsup_hotkey_map; key->fncode != 0; key++) { + if (key->fncode == code) + return key; + } + + return NULL; +} + +static struct key_entry *tlsup_get_entry_by_keycode(int code) +{ + struct key_entry *key; + + for (key = tlsup_hotkey_map; key->fncode != 0; key++) { + if (key->keycode == code) + return key; + } + + return NULL; +} + +static int tlsup_get_keycode(struct input_dev *dev, int scancode, int *keycode) +{ + struct key_entry *key = tlsup_get_entry_by_scancode(scancode); + + if (key != NULL) { + *keycode = key->keycode; + return 0; + } + + return -EINVAL; +} + +static int tlsup_set_keycode(struct input_dev *dev, int scancode, int keycode) +{ + struct key_entry *key = tlsup_get_entry_by_scancode(scancode); + int old_keycode; + + if (keycode < 0 || keycode > KEY_MAX) + return -EINVAL; + + if (key != NULL) { + old_keycode = key->keycode; + key->keycode = keycode; + set_bit(keycode, dev->keybit); + if (tlsup_get_entry_by_keycode(old_keycode) == NULL) + clear_bit(old_keycode, dev->keybit); + return 0; + } + + return -EINVAL; +} + +/* Hotkey system */ + +static struct input_polled_dev *tlsup_polled_dev = NULL; + +static int tlsup_read_hotkey_event(void) +{ + u32 value, hci_result; + if (tlsup_hci_read_1_reg(HCI_SYSTEM_EVENT, &value, &hci_result)) + return -EFAULT; + + if (hci_result == HCI_EMPTY) { + /* better luck next time */ + return 0; + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an unresolved issue on + * some machines where system events sporadically + * become disabled. */ + tlsup_hci_write_1_reg(HCI_SYSTEM_EVENT, 1, &hci_result); + tlsup_info("Had to re-enable hotkeys.\n"); + return 0; + } else if (hci_result == HCI_SUCCESS) { + /* Process key */ + if (value == 0x0100) { + /* Fn+ */ + return 0; + } else { + return value; + } + } else { + /* Unknown result */ + return -EFAULT; + } + /* Not reached */ + BUG(); +} + +static void tlsup_polled_dev_poll(struct input_polled_dev *dev) +{ + int scancode = tlsup_read_hotkey_event(); + struct key_entry *key; + + if (scancode <= 0) + return; + + key = tlsup_get_entry_by_scancode(scancode & 0x7F); + + if (key != NULL) { + input_report_key(dev->input, key->keycode, + !(scancode & 0x80)); + input_sync(dev->input); + } + +} + +/* Registration functions */ + +int tlsup_register_hotkeys(void) +{ + int ret; + struct input_dev *input; + struct key_entry *key; + + /* Swallow what's there already */ + while ((ret = tlsup_read_hotkey_event()) > 0); + + if (ret < 0) + return -EFAULT; + + + + /* Present and results are sane, register the backlight driver. */ + tlsup_polled_dev = input_allocate_polled_device(); + if (tlsup_polled_dev == NULL) { + tlsup_err("Could not allocate polled device for hotkeys\n"); + return -ENOMEM; + } + + tlsup_polled_dev->private = kmalloc(sizeof(tlsup_hotkey_map), GFP_KERNEL); + + tlsup_polled_dev->poll = tlsup_polled_dev_poll; + tlsup_polled_dev->poll_interval = 1000 / hotkeys_checks_per_second; + + /* id name phys bits */ + + input = tlsup_polled_dev->input; + + input->id.bustype = BUS_HOST; + input->name = "tlsup: Toshiba Fn Hotkeys"; + input->phys = "toshiba/hotkeys0"; + + input->keycode = tlsup_polled_dev->private; + input->keycodemax = ARRAY_SIZE(tlsup_hotkey_map); + input->keycodesize = sizeof(unsigned short); + + input->getkeycode = tlsup_get_keycode; + input->setkeycode = tlsup_set_keycode; + + set_bit(EV_KEY, input->evbit); + for (key = tlsup_hotkey_map; key->fncode != 0; key++) + set_bit(key->keycode, input->keybit); + clear_bit(KEY_RESERVED, input->keybit); + + if ((ret = input_register_polled_device(tlsup_polled_dev)) < 0) { + input_free_polled_device(tlsup_polled_dev); + tlsup_err("Could not register polled device for hotkeys\n"); + tlsup_polled_dev = NULL; + return ret; + } + + tlsup_info("Hotkeys polled every %dms.\n", 1000 / hotkeys_checks_per_second); + + return 1; +} + +void tlsup_deregister_hotkeys(void) +{ + if (tlsup_polled_dev != NULL) { + input_unregister_polled_device(tlsup_polled_dev); + input_free_polled_device(tlsup_polled_dev); + tlsup_polled_dev = NULL; + } +} --- linux-2.6.28.orig/ubuntu/tlsup/Makefile +++ linux-2.6.28/ubuntu/tlsup/Makefile @@ -0,0 +1,6 @@ +TLSUP_VERSION := 0.10 +EXTRA_CFLAGS += '-DTLSUP_VERSION="$(TLSUP_VERSION)"' + +obj-$(CONFIG_TLSUP) := tlsup.o + +tlsup-objs := tlsup_mod.o tlsup_acpi.o tlsup_backlight.o tlsup_hotkeys.o tlsup_radios.o --- linux-2.6.28.orig/ubuntu/tlsup/BOM +++ linux-2.6.28/ubuntu/tlsup/BOM @@ -0,0 +1,4 @@ +Downloaded from: http://bzr.digital-scurf.org/trees/dsilvers/toshiba-laptop-support/ +Current Version: Mon, 11 Aug 2008 13:07:54 -0400 +Comments: Supercedes toshiba and toshiba_acpi drivers. + --- linux-2.6.28.orig/ubuntu/compcache/compcache.c +++ linux-2.6.28/ubuntu/compcache/compcache.c @@ -0,0 +1,480 @@ +/* + * Compressed RAM based swap device + * + * (C) 2008 Nitin Gupta + * + * This RAM based block device acts as swap disk. + * Pages swapped to this device are compressed and + * stored in memory. + * + * Released under the terms of the GNU General Public + * License (version 2). See linux/COPYING for more information. + * + * Project home: http://code.google.com/p/compcache + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "compcache.h" + +static struct block_device_operations compcache_devops = { + .owner = THIS_MODULE, +}; + +static unsigned int init_done; +static struct compcache compcache; +static unsigned long compcache_size_kbytes; +#if defined(STATS) +static struct compcache_stats stats; +#endif + +#if defined(STATS) +static struct proc_dir_entry *proc; + +static int proc_compcache_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; +#if defined(STATS) + size_t succ_writes; + unsigned int good_compress_perc = 0, no_compress_perc = 0; +#endif + + if (off > 0) { + *eof = 1; + return 0; + } + + len = sprintf(page, + "DiskSize: %8zu kB\n", + compcache.size >> (10 - SECTOR_SHIFT)); +#if defined(STATS) + succ_writes = stats.num_writes - stats.failed_writes; + if (succ_writes) { + good_compress_perc = stats.good_compress * 100 / succ_writes; + no_compress_perc = stats.pages_expand * 100 / succ_writes; + } + +#define K(x) ((x) >> 10) + len += sprintf(page + len, + "NumReads: %8u\n" + "NumWrites: %8u\n" + "FailedReads: %8u\n" + "FailedWrites: %8u\n" + "InvalidIO: %8u\n" + "GoodCompress: %8u %%\n" + "NoCompress: %8u %%\n" + "NotifyFree: %8u\n" + "CurrentPages: %8zu\n" + "CurrentMem: %8zu kB\n" + "PeakMem: %8zu kB\n", + stats.num_reads, + stats.num_writes, + stats.failed_reads, + stats.failed_writes, + stats.invalid_io, + good_compress_perc, + no_compress_perc, + stats.notify_free, + stats.curr_pages, + K(stats.curr_mem), + K(stats.peak_mem)); +#endif + return len; +} +#endif /* STATS */ + +/* + * callback function called when swap_map[offset] == 0 + * i.e page at this swap offset is no longer used + */ +static void notify_swap_entry_free(unsigned long offset) +{ + stat_inc(stats.notify_free); + + /* + * + * This callback happened due to some page being + * freed from swap-cache. This page was not written + * to swap disk. + */ + if (compcache.table[offset].addr == NULL) + return; + + tlsf_free(compcache.table[offset].addr, compcache.mem_pool); + stat_dec(stats.curr_pages); + stat_set(stats.curr_mem, stats.curr_mem - + compcache.table[offset].len); + compcache.table[offset].addr = NULL; + compcache.table[offset].len = 0; +} + +/* Check if request is within bounds and page aligned */ +static inline int valid_swap_request(struct bio *bio) +{ + if (unlikely((bio->bi_sector >= compcache.size) || + (bio->bi_sector & (SECTORS_PER_PAGE - 1)) || + (bio->bi_vcnt != 1) || + (bio->bi_size != PAGE_SIZE) || + (bio->bi_io_vec[0].bv_offset != 0))) + return 0; + return 1; +} + +static int compcache_make_request(struct request_queue *queue, struct bio *bio) +{ + int ret; + size_t clen, page_no; + void *user_mem; + struct page *page; + + if (!valid_swap_request(bio)) { + stat_inc(stats.invalid_io); + goto out_nomap; + } + + page = bio->bi_io_vec[0].bv_page; + page_no = bio->bi_sector >> SECTORS_PER_PAGE_SHIFT; + + if (unlikely(!init_done) && PageSwapCache(page)) { + swp_entry_t entry = { .val = page_private(page) }; + set_notify_swap_entry_free(swp_type(entry), + notify_swap_entry_free); + init_done = 1; + } + + user_mem = kmap(page); + + if (bio_data_dir(bio) == READ) { + stat_inc(stats.num_reads); + /* + * This is attempt to read before any previous write + * to this location. This happens due to readahead when + * swap device is read from user-space (e.g. during swapon) + */ + if (unlikely(compcache.table[page_no].addr == NULL)) { + pr_debug("Read before write on swap device: " + "sector=%lu, size=%u, offset=%u\n", + (ulong)(bio->bi_sector), + bio->bi_size, + bio->bi_io_vec[0].bv_offset); + memset(user_mem, 0, PAGE_SIZE); + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } + + /* Page is stored uncompressed since its incompressible */ + if (unlikely(compcache.table[page_no].len == PAGE_SIZE)) { + memcpy(user_mem, compcache.table[page_no].addr, + PAGE_SIZE); + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } + + clen = PAGE_SIZE; + ret = lzo1x_decompress_safe( + compcache.table[page_no].addr, + compcache.table[page_no].len, + user_mem, + &clen); + + /* should NEVER happen */ + if (unlikely(ret != LZO_E_OK)) { + pr_err(C "Decompression failed! " + "err=%d, page=%zu, len=%lu\n", ret, page_no, + compcache.table[page_no].len); + stat_inc(stats.failed_reads); + goto out; + } + + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } else { /* Write */ + unsigned char *src = compcache.compress_buffer; + stat_inc(stats.num_writes); + /* + * System swaps to same sector again when the stored page + * is no longer referenced by any process. So, its now safe + * to free the memory that was allocated for this page. + */ + if (compcache.table[page_no].addr) { + tlsf_free(compcache.table[page_no].addr, + compcache.mem_pool); + stat_dec(stats.curr_pages); + stat_set(stats.curr_mem, stats.curr_mem - + compcache.table[page_no].len); + compcache.table[page_no].addr = NULL; + compcache.table[page_no].len = 0; + } + + mutex_lock(&compcache.lock); + ret = lzo1x_1_compress(user_mem, PAGE_SIZE, + src, &clen, compcache.compress_workmem); + if (unlikely(ret != LZO_E_OK)) { + mutex_unlock(&compcache.lock); + pr_err(C "Compression failed! err=%d\n", ret); + compcache.table[page_no].addr = NULL; + compcache.table[page_no].len = 0; + stat_inc(stats.failed_writes); + goto out; + } + + /* Page is incompressible - store it as is */ + if (clen >= PAGE_SIZE) { + pr_debug("Page expand on compression: " + "page=%zu, size=%zu\n", page_no, clen); + clen = PAGE_SIZE; + src = user_mem; + } + + if ((compcache.table[page_no].addr = tlsf_malloc(clen, + compcache.mem_pool)) == NULL) { + mutex_unlock(&compcache.lock); + pr_err(C "Error allocating memory for compressed " + "page: %zu, size=%zu \n", page_no, clen); + compcache.table[page_no].len = 0; + stat_inc(stats.failed_writes); + goto out; + } + + memcpy(compcache.table[page_no].addr, src, clen); + + /* Update stats */ + stat_inc(stats.curr_pages); + stat_set(stats.curr_mem, stats.curr_mem + clen); + stat_setmax(stats.peak_mem, stats.curr_mem); + stat_inc_if_less(stats.pages_expand, PAGE_SIZE - 1, clen); + stat_inc_if_less(stats.good_compress, clen, + PAGE_SIZE / 2 + 1); + mutex_unlock(&compcache.lock); + + compcache.table[page_no].len = clen; + + kunmap(page); + set_bit(BIO_UPTODATE, &bio->bi_flags); + bio_endio(bio, 0); + return 0; + } +out: + kunmap(page); +out_nomap: + bio_io_error(bio); + return 0; +} + +static void setup_swap_header(union swap_header *s) +{ + s->info.version = 1; + s->info.last_page = compcache.size >> SECTORS_PER_PAGE_SHIFT; + s->info.nr_badpages = 0; + memcpy(s->magic.magic, "SWAPSPACE2", 10); +} + +static void *get_mem(size_t size) +{ + return __vmalloc(size, GFP_NOIO, PAGE_KERNEL); +} + +static void put_mem(void *ptr) +{ + vfree(ptr); +} + +static int __init compcache_init(void) +{ + int ret; + size_t num_pages; + struct sysinfo i; + + mutex_init(&compcache.lock); + + if (compcache_size_kbytes == 0) { + pr_info(C "compcache size not provided." + " Using default: (%u%% of Total RAM).\n" + "Use compcache_size_kbytes module param to specify" + " custom size\n", DEFAULT_COMPCACHE_PERCENT); + si_meminfo(&i); + compcache_size_kbytes = ((DEFAULT_COMPCACHE_PERCENT * + i.totalram) / 100) << (PAGE_SHIFT - 10); + } + + compcache.size = compcache_size_kbytes << 10; + compcache.size = (compcache.size + PAGE_SIZE - 1) & PAGE_MASK; + pr_info(C "Compressed swap size set to: %zu KB\n", compcache.size >> 10); + compcache.size >>= SECTOR_SHIFT; + + compcache.compress_workmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + if (compcache.compress_workmem == NULL) { + pr_err(C "Error allocating compressor working memory\n"); + ret = -ENOMEM; + goto fail; + } + + compcache.compress_buffer = kmalloc(2 * PAGE_SIZE, GFP_KERNEL); + if (compcache.compress_buffer == NULL) { + pr_err(C "Error allocating compressor buffer space\n"); + ret = -ENOMEM; + goto fail; + } + + num_pages = compcache.size >> SECTORS_PER_PAGE_SHIFT; + compcache.table = vmalloc(num_pages * sizeof(*compcache.table)); + if (compcache.table == NULL) { + pr_err(C "Error allocating compcache address table\n"); + ret = -ENOMEM; + goto fail; + } + memset(compcache.table, 0, num_pages * sizeof(*compcache.table)); + + compcache.table[0].addr = (void *)get_zeroed_page(GFP_KERNEL); + if (compcache.table[0].addr == NULL) { + pr_err(C "Error allocating swap header page\n"); + ret = -ENOMEM; + goto fail; + } + compcache.table[0].len = PAGE_SIZE; + setup_swap_header((union swap_header *)(compcache.table[0].addr)); + + compcache.disk = alloc_disk(1); + if (compcache.disk == NULL) { + pr_err(C "Error allocating disk structure\n"); + ret = -ENOMEM; + goto fail; + } + + compcache.disk->first_minor = 0; + compcache.disk->fops = &compcache_devops; + /* + * It is named like this to prevent distro installers + * from offering compcache as installation target. They + * seem to ignore all devices beginning with 'ram' + */ + strcpy(compcache.disk->disk_name, "ramzswap0"); + + compcache.disk->major = register_blkdev(0, compcache.disk->disk_name); + if (compcache.disk->major < 0) { + pr_err(C "Cannot register block device\n"); + ret = -EFAULT; + goto fail; + } + + compcache.disk->queue = blk_alloc_queue(GFP_KERNEL); + if (compcache.disk->queue == NULL) { + pr_err(C "Cannot register disk queue\n"); + ret = -EFAULT; + goto fail; + } + + set_capacity(compcache.disk, compcache.size); + blk_queue_make_request(compcache.disk->queue, compcache_make_request); + blk_queue_hardsect_size(compcache.disk->queue, PAGE_SIZE); + add_disk(compcache.disk); + + compcache.mem_pool = tlsf_create_memory_pool("compcache", + get_mem, put_mem, + INIT_SIZE_BYTES, 0, GROW_SIZE_BYTES); + if (compcache.mem_pool == NULL) { + pr_err(C "Error creating memory pool\n"); + ret = -ENOMEM; + goto fail; + } + +#if defined(STATS) + proc = create_proc_entry("compcache", S_IRUGO, NULL); + if (proc) + proc->read_proc = &proc_compcache_read; + else { + ret = -ENOMEM; + pr_warning(C "Error creating proc entry\n"); + goto fail; + } +#endif + + pr_debug(C "Initialization done!\n"); + return 0; + +fail: + if (compcache.disk != NULL) { + if (compcache.disk->major > 0) + unregister_blkdev(compcache.disk->major, + compcache.disk->disk_name); + del_gendisk(compcache.disk); + } + + free_page((unsigned long)compcache.table[0].addr); + kfree(compcache.compress_workmem); + kfree(compcache.compress_buffer); + vfree(compcache.table); + tlsf_destroy_memory_pool(compcache.mem_pool); +#if defined(STATS) + if (proc) + remove_proc_entry("compcache", proc->parent); +#endif + pr_err(C "Initialization failed: err=%d\n", ret); + return ret; +} + +static void __exit compcache_exit(void) +{ + size_t i, num_pages; + num_pages = compcache.size >> SECTORS_PER_PAGE_SHIFT; + + unregister_blkdev(compcache.disk->major, compcache.disk->disk_name); + del_gendisk(compcache.disk); + free_page((unsigned long)compcache.table[0].addr); + kfree(compcache.compress_workmem); + kfree(compcache.compress_buffer); + + /* Free all pages that are still in compcache */ + for (i = 1; i < num_pages; i++) + if (compcache.table[i].addr) + tlsf_free(compcache.table[i].addr, compcache.mem_pool); + vfree(compcache.table); + tlsf_destroy_memory_pool(compcache.mem_pool); + +#if defined(STATS) + remove_proc_entry("compcache", proc->parent); +#endif + pr_debug("cleanup done!\n"); +} + +#ifndef MODULE +static int __init compcache_size_setup(char *str) +{ + if (str) + compcache_size_kbytes = strtoul(str, NULL, 10); + return 1; +} + +__setup("compcache_size_kbytes=", compcache_size_setup); +#endif + +module_param(compcache_size_kbytes, ulong, 0); +MODULE_PARM_DESC(compcache_size_kbytes, "compcache device size (in KB)"); + +module_init(compcache_init); +module_exit(compcache_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nitin Gupta "); +MODULE_DESCRIPTION("Compressed RAM Based Swap Device"); --- linux-2.6.28.orig/ubuntu/compcache/tlsf_int.h +++ linux-2.6.28/ubuntu/compcache/tlsf_int.h @@ -0,0 +1,145 @@ +/* + * To be used internally by TLSF allocator. + */ + +#ifndef _TLSF_INT_H_ +#define _TLSF_INT_H_ + +#include +#include + +/* Debugging and Stats */ +#define NOP do { } while(0) + +#if defined(CONFIG_TLSF_STATS) +#define stat_inc(stat) (stat++) +#define stat_set(stat, val) (stat = val) +#define stat_setmax(stat, curr) (stat = (curr) > stat ? (curr) : stat) + +#else /* STATS */ +#define stat_inc(x) NOP +#define stat_dec(x) NOP +#define stat_set(x, v) NOP +#define stat_setmax(x, v) NOP +#endif /* STATS */ + +/* Messsage prefix */ +#define T "TLSF: " + +#define MAX_POOL_NAME_LEN 16 + +/*-- TLSF structures */ + +/* Some IMPORTANT TLSF parameters */ +#define MEM_ALIGN (sizeof(void *) * 2) +#define MEM_ALIGN_MASK (~(MEM_ALIGN - 1)) + +#define MAX_FLI (30) +#define MAX_LOG2_SLI (5) +#define MAX_SLI (1 << MAX_LOG2_SLI) + +#define FLI_OFFSET (6) +/* tlsf structure just will manage blocks bigger than 128 bytes */ +#define SMALL_BLOCK (128) +#define REAL_FLI (MAX_FLI - FLI_OFFSET) +#define MIN_BLOCK_SIZE (sizeof(struct free_ptr)) +#define BHDR_OVERHEAD (sizeof(struct bhdr) - MIN_BLOCK_SIZE) + +#define PTR_MASK (sizeof(void *) - 1) +#define BLOCK_SIZE_MASK (0xFFFFFFFF - PTR_MASK) + +#define GET_NEXT_BLOCK(addr, r) ((struct bhdr *) \ + ((char *)(addr) + (r))) +#define ROUNDUP_SIZE(r) (((r) + MEM_ALIGN - 1) & MEM_ALIGN_MASK) +#define ROUNDDOWN_SIZE(r) ((r) & MEM_ALIGN_MASK) +#define ROUNDUP_PAGE(r) (((r) + PAGE_SIZE - 1) & PAGE_MASK) + +#define BLOCK_STATE (0x1) +#define PREV_STATE (0x2) + +/* bit 0 of the block size */ +#define FREE_BLOCK (0x1) +#define USED_BLOCK (0x0) + +/* bit 1 of the block size */ +#define PREV_FREE (0x2) +#define PREV_USED (0x0) + +#if defined(CONFIG_TLSF_DEBUG) +#define MAX_RETRY_EXPAND 10 +#endif + +struct free_ptr { + struct bhdr *prev; + struct bhdr *next; +}; + +struct bhdr { + /* All blocks in a region are linked in order of physical address */ + struct bhdr *prev_hdr; + /* + * The size is stored in bytes + * bit 0: block is free, if set + * bit 1: previous block is free, if set + */ + u32 size; + /* Free blocks in individual freelists are linked */ + union { + struct free_ptr free_ptr; + u8 buffer[sizeof(struct free_ptr)]; + } ptr; +}; + +struct pool { + /* First level bitmap (REAL_FLI bits) */ + u32 fl_bitmap; + + /* Second level bitmap */ + u32 sl_bitmap[REAL_FLI]; + + /* Free lists */ + struct bhdr *matrix[REAL_FLI][MAX_SLI]; + + spinlock_t lock; + + size_t init_size; + size_t max_size; + size_t grow_size; + + /* Basic stats */ + size_t used_size; + size_t num_regions; + + /* User provided functions for expanding/shrinking pool */ + get_memory *get_mem; + put_memory *put_mem; + + struct list_head list; + +#if defined(CONFIG_TLSF_STATS) + /* Extra stats */ + size_t peak_used; + size_t peak_total; + size_t peak_extra; /* MAX(Total - Used) */ + size_t count_alloc; + size_t count_free; + size_t count_region_alloc; + size_t count_region_free; + size_t count_failed_alloc; +#endif + +#if defined(CONFIG_TLSF_DEBUG) + /* + * Pool used size must be 0 when its destroyed. + * When non-empty pool is destroyed, it suggests + * memory leak. Such pools are marked invalid + * and kept in pool list for later debugging. + */ + unsigned int valid; +#endif + void *init_region; + char name[MAX_POOL_NAME_LEN]; +}; +/*-- TLSF structures end */ + +#endif --- linux-2.6.28.orig/ubuntu/compcache/compcache.txt +++ linux-2.6.28/ubuntu/compcache/compcache.txt @@ -0,0 +1,29 @@ + +compcache: Compressed RAM based swap device +------------------------------------------- + +Project home: http://code.google.com/p/compcache + +* Introduction +This is a RAM based block device which acts as swap disk. +Pages swapped to this device are compressed and stored in +memory itself. + +It uses these components: + - TLSF: memory allocator + - LZO: de/compressor + +* Usage + - modprobe compcache compcache_size_kbytes= + (If no size is specified, default size of 25% of RAM is taken). + - swapon /dev/ramzswap0 + +* Notes + - Allocator and compcache statistics are exported via /proc interface: + (if stats are enabled for corresponding modules) + - /proc/tlsfinfo (from tlsf.ko) + - /proc/compcache (from compcache.ko) + + +Nitin Gupta +(nitingupta910@gmail.com) --- linux-2.6.28.orig/ubuntu/compcache/tlsf.c +++ linux-2.6.28/ubuntu/compcache/tlsf.c @@ -0,0 +1,676 @@ +/* + * Two Levels Segregate Fit memory allocator (TLSF) + * Version 2.3.2 + * + * Written by Miguel Masmano Tello + * + * Thanks to Ismael Ripoll for his suggestions and reviews + * + * Copyright (C) 2007, 2006, 2005, 2004 + * + * This code is released using a dual license strategy: GPL/LGPL + * You can choose the licence that better fits your requirements. + * + * Released under the terms of the GNU General Public License Version 2.0 + * Released under the terms of the GNU Lesser General Public License Version 2.1 + * + * This is kernel port of TLSF allocator. + * Original code can be found at: http://rtportal.upv.es/rtmalloc/ + * - Nitin Gupta (nitingupta910@gmail.com) + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "tlsf_int.h" + +static spinlock_t pool_list_lock; +static struct list_head pool_list_head; + +#if defined(CONFIG_TLSF_STATS) +static struct proc_dir_entry *proc; + +/* Print in format similar to /proc/slabinfo -- easy to awk */ +static void print_tlsfinfo_header(struct seq_file *tlsf) +{ + seq_puts(tlsf, "# Size in kB\n"); + seq_puts(tlsf, "# name " + " "); +#if defined(CONFIG_TLSF_STATS) + seq_puts(tlsf, " " + " " + " "); +#endif +#if defined(CONFIG_TLSF_DEBUG) + seq_puts(tlsf, " "); +#endif + + seq_putc(tlsf, '\n'); +} + +/* Get pool no. (*pos) from pool list */ +static void *tlsf_start(struct seq_file *tlsf, loff_t *pos) +{ + struct list_head *lp; + loff_t p = *pos; + + spin_lock(&pool_list_lock); + if (!p) + return SEQ_START_TOKEN; + + list_for_each(lp, &pool_list_head) { + if (!--p) + return lp; + } + + return NULL; +} + +/* Get pool next to the one given by tlsf_start()/previous tlsf_next() */ +static void *tlsf_next(struct seq_file *tlsf, void *v, loff_t *pos) +{ + struct list_head *lp; + + if (v == SEQ_START_TOKEN) + lp = &pool_list_head; + else + lp = v; + + lp = lp->next; + if (lp == &pool_list_head) + return NULL; + + ++*pos; + return lp; +} + +static void tlsf_stop(struct seq_file *tlsf, void *v) +{ + spin_unlock(&pool_list_lock); +} + +/* Display stats for pool given by tlsf_next() */ +static int tlsf_show(struct seq_file *tlsf, void *v) +{ + struct pool *pool; + size_t used, total; + if (v == SEQ_START_TOKEN) { + print_tlsfinfo_header(tlsf); + return 0; + } + + pool = list_entry(v, struct pool, list); + used = tlsf_get_used_size(pool); + total = tlsf_get_total_size(pool); +#define K(x) ((x) >> 10) + seq_printf(tlsf, "%-16s %6zu %6zu %6zu %6zu %6zu %6zu", + pool->name, + K(pool->init_size), + K(pool->max_size), + K(pool->grow_size), + K(used), + K(total), + K(total - used)); + +#if defined(CONFIG_TLSF_STATS) + seq_printf(tlsf, " %6zu %6zu %6zu %6zu %6zu %6zu %6zu %6zu", + K(pool->peak_used), + K(pool->peak_total), + K(pool->peak_extra), + pool->count_alloc, + pool->count_free, + pool->count_region_alloc, + pool->count_region_free, + pool->count_failed_alloc); +#endif + +#if defined(CONFIG_TLSF_DEBUG) + seq_printf(tlsf, " %u", pool->valid); +#endif + + seq_putc(tlsf, '\n'); + return 0; +} + +static struct seq_operations tlsfinfo_op = { + .start = tlsf_start, + .next = tlsf_next, + .stop = tlsf_stop, + .show = tlsf_show, +}; + +static int tlsfinfo_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &tlsfinfo_op); +} + +static const struct file_operations proc_tlsfinfo_operations = { + .open = tlsfinfo_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; +#endif /* CONFIG_TLSF_STATS */ + +/* + * Helping functions + */ + +/** + * Returns indexes (fl, sl) of the list used to serve request of size r + */ +static inline void MAPPING_SEARCH(size_t *r, int *fl, int *sl) +{ + int t; + + if (*r < SMALL_BLOCK) { + *fl = 0; + *sl = *r / (SMALL_BLOCK / MAX_SLI); + } else { + t = (1 << (fls(*r) - 1 - MAX_LOG2_SLI)) - 1; + *r = *r + t; + *fl = fls(*r) - 1; + *sl = (*r >> (*fl - MAX_LOG2_SLI)) - MAX_SLI; + *fl -= FLI_OFFSET; + /*if ((*fl -= FLI_OFFSET) < 0) // FL will be always >0! + *fl = *sl = 0; + */ + *r &= ~t; + } +} + +/** + * Returns indexes (fl, sl) which is used as starting point to search + * for a block of size r. It also rounds up requested size(r) to the + * next list. + */ +static inline void MAPPING_INSERT(size_t r, int *fl, int *sl) +{ + if (r < SMALL_BLOCK) { + *fl = 0; + *sl = r / (SMALL_BLOCK / MAX_SLI); + } else { + *fl = fls(r) - 1; + *sl = (r >> (*fl - MAX_LOG2_SLI)) - MAX_SLI; + *fl -= FLI_OFFSET; + } +} + +/** + * Returns first block from a list that hold blocks larger than or + * equal to the one pointed by the indexes (fl, sl) + */ +static inline struct bhdr *FIND_SUITABLE_BLOCK(struct pool *p, int *fl, + int *sl) +{ + u32 tmp = p->sl_bitmap[*fl] & (~0 << *sl); + struct bhdr *b = NULL; + + if (tmp) { + *sl = ffs(tmp) - 1; + b = p->matrix[*fl][*sl]; + } else { + *fl = ffs(p->fl_bitmap & (~0 << (*fl + 1))) - 1; + if (*fl > 0) { /* likely */ + *sl = ffs(p->sl_bitmap[*fl]) - 1; + b = p->matrix[*fl][*sl]; + } + } + return b; +} + +/** + * Remove first free block(b) from free list with indexes (fl, sl). + */ +static inline void EXTRACT_BLOCK_HDR(struct bhdr *b, struct pool *p, int fl, + int sl) +{ + p->matrix[fl][sl] = b->ptr.free_ptr.next; + if (p->matrix[fl][sl]) + p->matrix[fl][sl]->ptr.free_ptr.prev = NULL; + else { + clear_bit(sl, (void *)&p->sl_bitmap[fl]); + if(!p->sl_bitmap[fl]) + clear_bit (fl, (void *)&p->fl_bitmap); + } + b->ptr.free_ptr = (struct free_ptr) {NULL, NULL}; +} + +/** + * Removes block(b) from free list with indexes (fl, sl) + */ +static inline void EXTRACT_BLOCK(struct bhdr *b, struct pool *p, int fl, + int sl) +{ + if (b->ptr.free_ptr.next) + b->ptr.free_ptr.next->ptr.free_ptr.prev = + b->ptr.free_ptr.prev; + if (b->ptr.free_ptr.prev) + b->ptr.free_ptr.prev->ptr.free_ptr.next = + b->ptr.free_ptr.next; + if (p->matrix[fl][sl] == b) { + p->matrix[fl][sl] = b->ptr.free_ptr.next; + if (!p->matrix[fl][sl]) { + clear_bit(sl, (void *)&p->sl_bitmap[fl]); + if (!p->sl_bitmap[fl]) + clear_bit (fl, (void *)&p->fl_bitmap); + } + } + b->ptr.free_ptr = (struct free_ptr) {NULL, NULL}; +} + +/** + * Insert block(b) in free list with indexes (fl, sl) + */ +static inline void INSERT_BLOCK(struct bhdr *b, struct pool *p, int fl, int sl) +{ + b->ptr.free_ptr = (struct free_ptr) {NULL, p->matrix[fl][sl]}; + if (p->matrix[fl][sl]) + p->matrix[fl][sl]->ptr.free_ptr.prev = b; + p->matrix[fl][sl] = b; + set_bit(sl, (void *)&p->sl_bitmap[fl]); + set_bit(fl, (void *)&p->fl_bitmap); +} + +/** + * Region is a virtually contiguous memory region and Pool is + * collection of such regions + */ +static inline void ADD_REGION(void *region, size_t region_size, + struct pool *pool) +{ + int fl, sl; + struct bhdr *b, *lb; + + b = (struct bhdr *)(region); + b->prev_hdr = NULL; + b->size = ROUNDDOWN_SIZE(region_size - 2 * BHDR_OVERHEAD) + | FREE_BLOCK | PREV_USED; + MAPPING_INSERT(b->size & BLOCK_SIZE_MASK, &fl, &sl); + INSERT_BLOCK(b, pool, fl, sl); + /* The sentinel block: allows us to know when we're in the last block */ + lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + lb->prev_hdr = b; + lb->size = 0 | USED_BLOCK | PREV_FREE; + pool->used_size += BHDR_OVERHEAD; /* only sentinel block is "used" */ + pool->num_regions++; + stat_inc(pool->count_region_alloc); +} + +/* + * Allocator code start + */ + +/** + * tlsf_create_memory_pool - create dynamic memory pool + * @name: name of the pool + * @get_mem: callback function used to expand pool + * @put_mem: callback function used to shrink pool + * @init_size: inital pool size (in bytes) + * @max_size: maximum pool size (in bytes) - set this as 0 for no limit + * @grow_size: amount of memory (in bytes) added to pool whenever required + * + * All size values are rounded up to next page boundary. + */ +void *tlsf_create_memory_pool(const char *name, + get_memory get_mem, + put_memory put_mem, + size_t init_size, + size_t max_size, + size_t grow_size) +{ + struct pool *pool; + void *region; +#if defined(CONFIG_TLSF_STATS) + size_t used, total; +#endif + + if (max_size) + BUG_ON(max_size < init_size); + + pool = get_mem(ROUNDUP_SIZE(sizeof(*pool))); + if (pool == NULL) + goto out; + memset(pool, 0, ROUNDUP_SIZE(sizeof(*pool))); + + /* Round to next page boundary */ + init_size = ROUNDUP_PAGE(init_size); + max_size = ROUNDUP_PAGE(max_size); + grow_size = ROUNDUP_PAGE(grow_size); + pr_info(T "pool: %p, init_size=%zu, max_size=%zu, grow_size=%zu\n", + pool, init_size, max_size, grow_size); + + /* pool global overhead not included in used size */ + pool->used_size = 0; + + pool->init_size = init_size; + pool->max_size = max_size; + pool->grow_size = grow_size; + pool->get_mem = get_mem; + pool->put_mem = put_mem; + strncpy(pool->name, name, MAX_POOL_NAME_LEN); + pool->name[MAX_POOL_NAME_LEN - 1] = '\0'; +#if defined(CONFIG_TLSF_DEBUG) + pool->valid = 1; +#endif + region = get_mem(init_size); + if (region == NULL) + goto out_region; + ADD_REGION(region, init_size, pool); + pool->init_region = region; + + spin_lock_init(&pool->lock); + + spin_lock(&pool_list_lock); + list_add_tail(&pool->list, &pool_list_head); + spin_unlock(&pool_list_lock); + + /* Pool created: update stats */ + stat_set(used, tlsf_get_used_size(pool)); + stat_set(total, tlsf_get_total_size(pool)); + stat_inc(pool->count_alloc); + stat_setmax(pool->peak_extra, total - used); + stat_setmax(pool->peak_used, used); + stat_setmax(pool->peak_total, total); + + return pool; + +out_region: + put_mem(pool); + +out: + return NULL; +} +EXPORT_SYMBOL_GPL(tlsf_create_memory_pool); + +/** + * tlsf_get_used_size - get memory currently used by given pool + * + * Used memory includes stored data + metadata + internal fragmentation + */ +size_t tlsf_get_used_size(void *mem_pool) +{ + struct pool *pool = (struct pool *)mem_pool; + return pool->used_size; +} +EXPORT_SYMBOL_GPL(tlsf_get_used_size); + +/** + * tlsf_get_total_size - get total memory currently allocated for given pool + * + * This is the total memory currently allocated for this pool which includes + * used size + free size. + * + * (Total - Used) is good indicator of memory efficiency of allocator. + */ +size_t tlsf_get_total_size(void *mem_pool) +{ + size_t total; + struct pool *pool = (struct pool *)mem_pool; + total = ROUNDUP_SIZE(sizeof(*pool)) + + pool->init_size + + (pool->num_regions - 1) * pool->grow_size; + return total; +} +EXPORT_SYMBOL_GPL(tlsf_get_total_size); + +/** + * tlsf_destory_memory_pool - cleanup given pool + * @mem_pool: Pool to be destroyed + * + * Data structures associated with pool are freed. + * All memory allocated from pool must be freed before + * destorying it. + */ +void tlsf_destroy_memory_pool(void *mem_pool) +{ + struct pool *pool; + + if (mem_pool == NULL) + return; + + pool = (struct pool *)mem_pool; + + /* User is destorying without ever allocating from this pool */ + if (tlsf_get_used_size(pool) == BHDR_OVERHEAD) { + pool->put_mem(pool->init_region); + pool->used_size -= BHDR_OVERHEAD; + stat_inc(pool->count_region_free); + } + + /* Check for memory leaks in this pool */ + if (tlsf_get_used_size(pool)) { + pr_warning(T "memory leak in pool: %s (%p). " + "%zu bytes still in use.\n", + pool->name, pool, tlsf_get_used_size(pool)); + +#if defined(CONFIG_TLSF_DEBUG) + pool->valid = 0; + /* Invalid pools stay in list for debugging purpose */ + return; +#endif + } + spin_lock(&pool_list_lock); + list_del_init(&pool->list); + spin_unlock(&pool_list_lock); + pool->put_mem(pool); +} +EXPORT_SYMBOL_GPL(tlsf_destroy_memory_pool); + +/** + * tlsf_malloc - allocate memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +void *tlsf_malloc(size_t size, void *mem_pool) +{ + struct pool *pool = (struct pool *)mem_pool; + struct bhdr *b, *b2, *next_b, *region; + int fl, sl; + size_t tmp_size; +#if defined(CONFIG_TLSF_STATS) + size_t used, total; +#endif + +#if defined(CONFIG_TLSF_DEBUG) + unsigned int retries = 0; +#endif + + size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size); + /* Rounding up the requested size and calculating fl and sl */ + + spin_lock(&pool->lock); +retry_find: + MAPPING_SEARCH(&size, &fl, &sl); + + /* Searching a free block */ + if (!(b = FIND_SUITABLE_BLOCK(pool, &fl, &sl))) { +#if defined(CONFIG_TLSF_DEBUG) + /* + * This can happen if there are too many users + * allocating from this pool simultaneously. + */ + if (unlikely(retries == MAX_RETRY_EXPAND)) + goto out_locked; + retries++; +#endif + /* Not found */ + if (size > (pool->grow_size - 2 * BHDR_OVERHEAD)) + goto out_locked; + if (pool->max_size && (pool->init_size + + pool->num_regions * pool->grow_size + > pool->max_size)) + goto out_locked; + spin_unlock(&pool->lock); + if ((region = pool->get_mem(pool->grow_size)) == NULL) + goto out; + spin_lock(&pool->lock); + ADD_REGION(region, pool->grow_size, pool); + goto retry_find; + } + EXTRACT_BLOCK_HDR(b, pool, fl, sl); + + /*-- found: */ + next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + /* Should the block be split? */ + tmp_size = (b->size & BLOCK_SIZE_MASK) - size; + if (tmp_size >= sizeof(struct bhdr) ) { + tmp_size -= BHDR_OVERHEAD; + b2 = GET_NEXT_BLOCK(b->ptr.buffer, size); + + b2->size = tmp_size | FREE_BLOCK | PREV_USED; + b2->prev_hdr = b; + + next_b->prev_hdr = b2; + + MAPPING_INSERT(tmp_size, &fl, &sl); + INSERT_BLOCK(b2, pool, fl, sl); + + b->size = size | (b->size & PREV_STATE); + } else { + next_b->size &= (~PREV_FREE); + b->size &= (~FREE_BLOCK); /* Now it's used */ + } + + pool->used_size += (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + + /* Successful alloc: update stats. */ + stat_set(used, tlsf_get_used_size(pool)); + stat_set(total, tlsf_get_total_size(pool)); + stat_inc(pool->count_alloc); + stat_setmax(pool->peak_extra, total - used); + stat_setmax(pool->peak_used, used); + stat_setmax(pool->peak_total, total); + + spin_unlock(&pool->lock); + return (void *)b->ptr.buffer; + + /* Failed alloc */ +out_locked: + spin_unlock(&pool->lock); + +out: + stat_inc(pool->count_failed_alloc); + return NULL; +} +EXPORT_SYMBOL_GPL(tlsf_malloc); + +/** + * tlsf_free - free memory from given pool + * @ptr: address of memory to be freed + * @mem_pool: pool to free from + */ +void tlsf_free(void *ptr, void *mem_pool) +{ + struct pool *pool = (struct pool *)mem_pool; + struct bhdr *b, *tmp_b; + int fl = 0, sl = 0; +#if defined(CONFIG_TLSF_STATS) + size_t used, total; +#endif + if (unlikely(ptr == NULL)) + return; + + b = (struct bhdr *) ((char *) ptr - BHDR_OVERHEAD); + + spin_lock(&pool->lock); + b->size |= FREE_BLOCK; + pool->used_size -= (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + b->ptr.free_ptr = (struct free_ptr) { NULL, NULL}; + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + if (tmp_b->size & FREE_BLOCK) { + MAPPING_INSERT(tmp_b->size & BLOCK_SIZE_MASK, &fl, &sl); + EXTRACT_BLOCK(tmp_b, pool, fl, sl); + b->size += (tmp_b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + } + if (b->size & PREV_FREE) { + tmp_b = b->prev_hdr; + MAPPING_INSERT(tmp_b->size & BLOCK_SIZE_MASK, &fl, &sl); + EXTRACT_BLOCK(tmp_b, pool, fl, sl); + tmp_b->size += (b->size & BLOCK_SIZE_MASK) + BHDR_OVERHEAD; + b = tmp_b; + } + tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE_MASK); + tmp_b->prev_hdr = b; + + MAPPING_INSERT(b->size & BLOCK_SIZE_MASK, &fl, &sl); + + if ((b->prev_hdr == NULL) && ((tmp_b->size & BLOCK_SIZE_MASK) == 0)) { + pool->put_mem(b); + pool->num_regions--; + pool->used_size -= BHDR_OVERHEAD; /* sentinel block header */ + stat_inc(pool->count_region_free); + goto out; + } + + INSERT_BLOCK(b, pool, fl, sl); + + tmp_b->size |= PREV_FREE; + tmp_b->prev_hdr = b; +out: + /* Update stats */ + stat_set(used, tlsf_get_used_size(pool)); + stat_set(total, tlsf_get_total_size(pool)); + stat_inc(pool->count_free); + stat_setmax(pool->peak_extra, total - used); + stat_setmax(pool->peak_used, used); + stat_setmax(pool->peak_total, total); + + spin_unlock(&pool->lock); +} +EXPORT_SYMBOL_GPL(tlsf_free); + +/** + * tlsf_calloc - allocate and zero-out memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +void *tlsf_calloc(size_t nelem, size_t elem_size, void *mem_pool) +{ + void *ptr; + + if (nelem == 0 || elem_size == 0) + return NULL; + + if ((ptr = tlsf_malloc(nelem * elem_size, mem_pool)) == NULL) + return NULL; + memset(ptr, 0, nelem * elem_size); + + return ptr; +} +EXPORT_SYMBOL_GPL(tlsf_calloc); + +static int __init tlsf_init(void) +{ + INIT_LIST_HEAD(&pool_list_head); + spin_lock_init(&pool_list_lock); +#if defined(CONFIG_TLSF_STATS) + proc = create_proc_entry("tlsfinfo", S_IRUGO, NULL); + if (proc) + proc->proc_fops = &proc_tlsfinfo_operations; + else + pr_warning(T "error creating proc entry\n"); +#endif + return 0; +} + +static void __exit tlsf_exit(void) +{ +#if defined(CONFIG_TLSF_STATS) + if (proc) + remove_proc_entry("tlsfinfo", proc->parent); +#endif + return; +} + +module_init(tlsf_init); +module_exit(tlsf_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Nitin Gupta "); +MODULE_DESCRIPTION("TLSF Memory Allocator"); --- linux-2.6.28.orig/ubuntu/compcache/Kconfig +++ linux-2.6.28/ubuntu/compcache/Kconfig @@ -0,0 +1,61 @@ +menu "Compcache options" + +config BLK_DEV_COMPCACHE + tristate "Compressed RAM based swap device" + default m + select TLSF + select LZO_COMPRESS + select LZO_DECOMPRESS + help + This creates RAM based block device which acts as swap disk. Pages + swapped to this disk are compressed and stored in memory itself. + Project Home: http://code.google.com/p/compcache/ + +config BLK_DEV_COMPCACHE_DEBUG + default n + depends on BLK_DEV_COMPCACHE + bool "Enable debugging" + help + This causes negligible performance loss and size increase. + If unsure, say Y. + +config BLK_DEV_COMPCACHE_STATS + default n + depends on BLK_DEV_COMPCACHE + bool "Enable statistics" + help + Creates /proc/compcache to export various statistics. + This adds about 4K to size with negligible performance loss. + If unsure, say Y. +endmenu + +menu "Two Level Segregate Fit Allocator" + +config TLSF + tristate "TLSF Allocator" + default m + help + Two Level Segregate Fit Allocator. Its fast and gives low + fragmentation. See: + http://rtportal.upv.es/rtmalloc/ + http://code.google.com/p/compcache/wiki/TLSFAllocator + for more information. + +config TLSF_DEBUG + default n + depends on TLSF + bool "Enable TLSF allocator debugging" + help + Enable TLSF debugging. + This causes negligible performance loss and size increase. + If unusure, say Y. + +config TLSF_STATS + default n + depends on TLSF + bool "Collect TLSF statistics" + help + Creates /proc/tlsfinfo to export various tlsf statistics. + This adds about 30K to size with significant performance loss. + If unsure, say N. +endmenu --- linux-2.6.28.orig/ubuntu/compcache/compcache.h +++ linux-2.6.28/ubuntu/compcache/compcache.h @@ -0,0 +1,96 @@ +/* + * Compressed RAM based swap device + * + * (C) 2008 Nitin Gupta + * + * This RAM based block device acts as swap disk. + * Pages swapped to this device are compressed and + * stored in memory. + * + * Released under the terms of the GNU General Public + * License (version 2). See linux/COPYING for more information. + * + * Project home: http://code.google.com/p/compcache + */ + +#ifndef _COMPCACHE_H_ +#define _COMPCACHE_H_ + +#define SECTOR_SHIFT 9 +#define SECTOR_SIZE (1 << SECTOR_SHIFT) +#define SECTORS_PER_PAGE_SHIFT (PAGE_SHIFT - SECTOR_SHIFT) +#define SECTORS_PER_PAGE (1 << SECTORS_PER_PAGE_SHIFT) + +/*-- Configurable parameters */ +/* Default compcache size: 25% of total RAM */ +#define DEFAULT_COMPCACHE_PERCENT 25 +#define INIT_SIZE_BYTES (16 * 1024) +#define GROW_SIZE_BYTES INIT_SIZE_BYTES +/*-- */ + +/* Message prefix */ +#define C "compcache: " + +/* Debugging and Stats */ +#define NOP do { } while(0) + +#if defined(CONFIG_BLK_DEV_COMPCACHE_DEBUG) +#define DEBUG +#endif + +#if defined(CONFIG_BLK_DEV_COMPCACHE_STATS) +#define STATS +#endif + +#if defined(STATS) +#define stat_inc(stat) (stat++) +#define stat_dec(stat) (stat--) +#define stat_set(stat, val) (stat = val) +#define stat_setmax(stat, curr) (stat = (curr) > stat ? (curr) : stat) +#define stat_inc_if_less(stat, val1, val2) \ + (stat += ((val1) < (val2) ? 1 : 0)) +#else /* STATS */ +#define stat_inc(x) NOP +#define stat_dec(x) NOP +#define stat_set(x, v) NOP +#define stat_setmax(x, v) NOP +#define stat_inc_if_less(x, v1, v2) NOP +#endif /* STATS */ + +/*-- Data structures */ +/* Indexed by page no. */ +struct table { + void *addr; + unsigned long len; +}; + +struct compcache { + void *mem_pool; + void *compress_workmem; + void *compress_buffer; + struct table *table; + struct mutex lock; + struct gendisk *disk; + size_t size; /* In sectors */ +}; + +#if defined(STATS) +struct compcache_stats { + u32 num_reads; /* failed + successful */ + u32 num_writes; /* --do-- */ + u32 failed_reads; /* can happen when memory is tooo low */ + u32 failed_writes; /* should NEVER! happen */ + u32 invalid_io; /* non-swap I/O requests */ + u32 good_compress; /* no. of pages with compression + * ratio <= 50%. TODO: export full + * compressed page size histogram */ + u32 pages_expand; /* no. of incompressible pages */ + u32 notify_free; /* count of swap entry free notifications */ + size_t curr_pages; /* current no. of compressed pages */ + size_t curr_mem; /* current total size of compressed pages */ + size_t peak_mem; +}; +#endif +/*-- */ + +#endif --- linux-2.6.28.orig/ubuntu/compcache/Makefile +++ linux-2.6.28/ubuntu/compcache/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_BLK_DEV_COMPCACHE) += compcache.o +obj-$(CONFIG_TLSF) += tlsf.o --- linux-2.6.28.orig/ubuntu/compcache/BOM +++ linux-2.6.28/ubuntu/compcache/BOM @@ -0,0 +1,5 @@ +Downloaded from: http://code.google.com/p/compcache/ +Current Version: Patch for 2.6.26.rc6 + +Moved compcache and tlsf modules to ubuntu/. Only touches swap subsystem +for free page callback. --- linux-2.6.28.orig/ubuntu/gfs/file.h +++ linux-2.6.28/ubuntu/gfs/file.h @@ -0,0 +1,42 @@ +#ifndef __FILE_DOT_H__ +#define __FILE_DOT_H__ + +typedef int (*read_copy_fn_t) (struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size); +typedef int (*write_copy_fn_t) (struct gfs_inode *ip, struct buffer_head *bh, + void **buf, unsigned int offset, + unsigned int size, int new); + +int gfs_copy2mem(struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size); +int gfs_copy2user(struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size); +int gfs_readi(struct gfs_inode *ip, void *buf, uint64_t offset, + unsigned int size, read_copy_fn_t copy_fn); + +int gfs_copy_from_mem(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new); +int gfs_copy_from_user(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new); +int gfs_writei(struct gfs_inode *ip, void *buf, uint64_t offset, + unsigned int size, write_copy_fn_t copy_fn, + struct kiocb *iocb); + +int gfs_zero_blocks(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new); + +static __inline__ int +gfs_internal_read(struct gfs_inode *ip, char *buf, uint64_t offset, + unsigned int size) +{ + return gfs_readi(ip, buf, offset, size, gfs_copy2mem); +} + +static __inline__ int +gfs_internal_write(struct gfs_inode *ip, char *buf, uint64_t offset, + unsigned int size) +{ + return gfs_writei(ip, buf, offset, size, gfs_copy_from_mem, NULL); +} + +#endif /* __FILE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/acl.c +++ linux-2.6.28/ubuntu/gfs/acl.c @@ -0,0 +1,396 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "eattr.h" +#include "inode.h" + +/** + * gfs_acl_validate_set - + * @ip: + * @access: + * @er: + * @mode: + * @remove: + * + * Returns: errno + */ + +int +gfs_acl_validate_set(struct gfs_inode *ip, int access, + struct gfs_ea_request *er, + int *remove, mode_t *mode) +{ + struct posix_acl *acl; + int error; + + error = gfs_acl_validate_remove(ip, access); + if (error) + return error; + + if (!er->er_data) + return -EINVAL; + + acl = posix_acl_from_xattr(er->er_data, er->er_data_len); + if (IS_ERR(acl)) + return PTR_ERR(acl); + if (!acl) { + *remove = TRUE; + return 0; + } + + error = posix_acl_valid(acl); + if (error) + goto out; + + if (access) { + error = posix_acl_equiv_mode(acl, mode); + if (!error) + *remove = TRUE; + else if (error > 0) + error = 0; + } + + out: + posix_acl_release(acl); + + return error; +} + +/** + * gfs_acl_validate_remove - + * @ip: + * @access: + * + * Returns: errno + */ + +int +gfs_acl_validate_remove(struct gfs_inode *ip, int access) +{ + if (!ip->i_sbd->sd_args.ar_posix_acls) + return -EOPNOTSUPP; + if (current->fsuid != ip->i_di.di_uid && !capable(CAP_FOWNER)) + return -EPERM; + if (ip->i_di.di_type == GFS_FILE_LNK) + return -EOPNOTSUPP; + if (!access && ip->i_di.di_type != GFS_FILE_DIR) + return -EACCES; + + return 0; +} + +/** + * gfs_acl_get - + * @ip: + * @access: + * @acl: + * + * Returns: errno + */ + +int +gfs_acl_get(struct gfs_inode *ip, int access, struct posix_acl **acl) +{ + struct gfs_ea_request er; + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) + return 0; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + if (access) { + er.er_name = GFS_POSIX_ACL_ACCESS; + er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; + } else { + er.er_name = GFS_POSIX_ACL_DEFAULT; + er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; + } + er.er_type = GFS_EATYPE_SYS; + + error = gfs_ea_find(ip, &er, &el); + if (error) + return error; + if (!el.el_ea) + return 0; + if (!GFS_EA_DATA_LEN(el.el_ea)) + goto out; + + er.er_data = kmalloc(GFS_EA_DATA_LEN(el.el_ea), GFP_KERNEL); + error = -ENOMEM; + if (!er.er_data) + goto out; + + error = gfs_ea_get_copy(ip, &el, er.er_data); + if (error) + goto out_kfree; + + *acl = posix_acl_from_xattr(er.er_data, GFS_EA_DATA_LEN(el.el_ea)); + if (IS_ERR(*acl)) + error = PTR_ERR(*acl); + + out_kfree: + kfree(er.er_data); + + out: + brelse(el.el_bh); + + return error; +} + +/** + * gfs_check_acl - Check an ACL for to see if we're allowed to do something + * @inode: the file we want to do something to + * @mask: what we want to do + * + * Returns: errno + */ + +int +gfs_check_acl(struct inode *inode, int mask) +{ + struct posix_acl *acl = NULL; + int error; + + error = gfs_acl_get(get_v2ip(inode), TRUE, &acl); + if (error) + return error; + + if (acl) { + error = posix_acl_permission(inode, acl, mask); + posix_acl_release(acl); + return error; + } + + return -EAGAIN; +} + +/** + * gfs_acl_new_prep - + * @dip: + * @type: + * @mode: + * @a_acl: + * @d_acl: + * @blocks: + * @data: + * + * Returns: errno + */ + +int +gfs_acl_new_prep(struct gfs_inode *dip, + unsigned int type, mode_t *mode, + void **a_data, void **d_data, + unsigned int *size, + unsigned int *blocks) +{ + struct posix_acl *acl = NULL; + int set_a = FALSE, set_d = FALSE; + int error; + + if (!dip->i_sbd->sd_args.ar_posix_acls) + return 0; + if (type == GFS_FILE_LNK) + return 0; + + error = gfs_acl_get(dip, FALSE, &acl); + if (error) + return error; + if (!acl) { + (*mode) &= ~current->fs->umask; + return 0; + } + + { + struct posix_acl *clone = posix_acl_clone(acl, GFP_KERNEL); + error = -ENOMEM; + if (!clone) + goto out; + posix_acl_release(acl); + acl = clone; + } + + error = posix_acl_create_masq(acl, mode); + if (error < 0) + goto out; + if (error > 0) { + set_a = TRUE; + error = 0; + } + if (type == GFS_FILE_DIR) + set_d = TRUE; + + if (set_a || set_d) { + struct gfs_ea_request er; + void *d; + unsigned int s = posix_acl_xattr_size(acl->a_count); + unsigned int b; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; + er.er_data_len = s; + error = gfs_ea_check_size(dip->i_sbd, &er); + if (error) + goto out; + + b = DIV_RU(er.er_data_len, dip->i_sbd->sd_jbsize); + if (set_a && set_d) + b *= 2; + b++; + + d = kmalloc(s, GFP_KERNEL); + error = -ENOMEM; + if (!d) + goto out; + posix_acl_to_xattr(acl, d, s); + + if (set_a) + *a_data = d; + if (set_d) + *d_data = d; + *size = s; + *blocks = b; + + error = 0; + } + + out: + posix_acl_release(acl); + + return error; +} + +/** + * gfs_acl_new_init - + * @dip: + * @ip: + * @a_data: + * @d_data: + * @size: + * + * Returns: errno + */ + +int gfs_acl_new_init(struct gfs_inode *dip, struct gfs_inode *ip, + void *a_data, void *d_data, unsigned int size) +{ + void *data = (a_data) ? a_data : d_data; + unsigned int x; + int error = 0; + + ip->i_alloc = dip->i_alloc; /* Cheesy, but it works. */ + + for (x = 0; x < 2; x++) { + struct gfs_ea_request er; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + if (x) { + if (!a_data) + continue; + er.er_name = GFS_POSIX_ACL_ACCESS; + er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; + } else { + if (!d_data) + continue; + er.er_name = GFS_POSIX_ACL_DEFAULT; + er.er_name_len = GFS_POSIX_ACL_DEFAULT_LEN; + } + er.er_data = data; + er.er_data_len = size; + er.er_type = GFS_EATYPE_SYS; + + error = gfs_ea_acl_init(ip, &er); + if (error) + break; + } + + ip->i_alloc = NULL; + + kfree(data); + + return error; +} + +/** + * gfs_acl_chmod - + * @ip: + * @attr: + * + * Returns: errno + */ + +int +gfs_acl_chmod(struct gfs_inode *ip, struct iattr *attr) +{ + struct gfs_ea_request er; + struct gfs_ea_location el; + struct posix_acl *acl; + int error; + + if (!ip->i_di.di_eattr) + goto simple; + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_name = GFS_POSIX_ACL_ACCESS; + er.er_name_len = GFS_POSIX_ACL_ACCESS_LEN; + er.er_type = GFS_EATYPE_SYS; + + error = gfs_ea_find(ip, &er, &el); + if (error) + return error; + if (!el.el_ea) + goto simple; + if (!GFS_EA_DATA_LEN(el.el_ea)) + goto simple; + + er.er_data = kmalloc(GFS_EA_DATA_LEN(el.el_ea), GFP_KERNEL); + error = -ENOMEM; + if (!er.er_data) + goto out; + + error = gfs_ea_get_copy(ip, &el, er.er_data); + if (error) + goto out_kfree; + + acl = posix_acl_from_xattr(er.er_data, GFS_EA_DATA_LEN(el.el_ea)); + if (IS_ERR(acl)) { + error = PTR_ERR(acl); + goto out_kfree; + } else if (!acl) { + kfree(er.er_data); + brelse(el.el_bh); + goto simple; + } + + error = posix_acl_chmod_masq(acl, attr->ia_mode); + if (error) + goto out_acl; + + posix_acl_to_xattr(acl, er.er_data, GFS_EA_DATA_LEN(el.el_ea)); + + error = gfs_ea_acl_chmod(ip, &el, attr, er.er_data); + + out_acl: + posix_acl_release(acl); + + out_kfree: + kfree(er.er_data); + + out: + brelse(el.el_bh); + + return error; + + simple: + return gfs_setattr_simple(ip, attr); +} --- linux-2.6.28.orig/ubuntu/gfs/bits.h +++ linux-2.6.28/ubuntu/gfs/bits.h @@ -0,0 +1,18 @@ +#ifndef __BITS_DOT_H__ +#define __BITS_DOT_H__ + +#define BFITNOENT (0xFFFFFFFF) + +void gfs_setbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + uint32_t block, unsigned char new_state); +unsigned char gfs_testbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + uint32_t block); +uint32_t gfs_bitfit(unsigned char *buffer, unsigned int buflen, + uint32_t goal, unsigned char old_state); +uint32_t gfs_bitcount(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + unsigned char state); + +#endif /* __BITS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/proc.c +++ linux-2.6.28/ubuntu/gfs/proc.c @@ -0,0 +1,491 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "glock.h" +#include "lm.h" +#include "proc.h" +#include "super.h" + +struct list_head gfs_fs_list; +struct semaphore gfs_fs_lock; +char *gfs_proc_margs; +spinlock_t gfs_proc_margs_lock; +spinlock_t gfs_req_lock; + +/** + * gfs_proc_fs_add - Add a FS to the list of mounted FSs + * @sdp: + * + */ + +void +gfs_proc_fs_add(struct gfs_sbd *sdp) +{ + down(&gfs_fs_lock); + list_add(&sdp->sd_list, &gfs_fs_list); + up(&gfs_fs_lock); +} + +/** + * gfs_proc_fs_del - Remove a FS from the list of mounted FSs + * @sdp: + * + */ + +void +gfs_proc_fs_del(struct gfs_sbd *sdp) +{ + down(&gfs_fs_lock); + list_del(&sdp->sd_list); + up(&gfs_fs_lock); +} + +/** + * do_list - Copy the list of mountes FSs to userspace + * @user_buf: + * @size: + * + * @Returns: -errno, or the number of bytes copied to userspace + */ + +static ssize_t +do_list(char *user_buf, size_t size) +{ + struct list_head *tmp; + struct gfs_sbd *sdp = NULL; + unsigned int x; + char num[21]; + char device_id[32]; + char *buf; + int error = 0; + + down(&gfs_fs_lock); + + x = 0; + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(device_id, "%u:%u", MAJOR(sdp->sd_vfs->s_dev), + MINOR(sdp->sd_vfs->s_dev)); + x += sprintf(num, "%lu", (unsigned long)sdp) + + strlen(device_id) + + strlen(sdp->sd_fsname) + 3; + } + + if (!x) + goto out; + + error = -EFBIG; + if (x > size) + goto out; + + error = -ENOMEM; + buf = kmalloc(x + 1, GFP_KERNEL); + if (!buf) + goto out; + + x = 0; + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(device_id, "%u:%u", MAJOR(sdp->sd_vfs->s_dev), + MINOR(sdp->sd_vfs->s_dev)); + x += sprintf(buf + x, "%lu %s %s\n", + (unsigned long)sdp, device_id, sdp->sd_fsname); + } + + if (copy_to_user(user_buf, buf, x)) + error = -EFAULT; + else + error = x; + + kfree(buf); + + out: + up(&gfs_fs_lock); + + return error; +} + +/** + * find_argument - + * @p: + * + * Returns: + */ + +static char * +find_argument(char *p) +{ + char *p2; + + while (*p == ' ' || *p == '\n') + p++; + if (!*p) + return NULL; + for (p2 = p; *p2; p2++) /* do nothing */; + p2--; + while (*p2 == ' ' || *p2 == '\n') + *p2-- = 0; + + return p; +} + +/** + * do_freeze - freeze a filesystem + * @p: the freeze command + * + * Returns: errno + */ + +static int +do_freeze(char *p) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + int error = 0; + + p = find_argument(p + 6); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else + error = gfs_freeze_fs(sdp); + + up(&gfs_fs_lock); + + return error; +} + +/** + * do_unfreeze - unfreeze a filesystem + * @p: the unfreeze command + * + * Returns: errno + */ + +static int +do_unfreeze(char *p) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + int error = 0; + + p = find_argument(p + 8); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else + gfs_unfreeze_fs(sdp); + + up(&gfs_fs_lock); + + return error; +} + +/** + * do_margs - Pass in mount arguments + * @p: the margs command + * + * Returns: errno + */ + +static int +do_margs(char *p) +{ + char *new_buf, *old_buf; + + p = find_argument(p + 5); + if (!p) + return -ENOENT; + + new_buf = kmalloc(strlen(p) + 1, GFP_KERNEL); + if (!new_buf) + return -ENOMEM; + strcpy(new_buf, p); + + spin_lock(&gfs_proc_margs_lock); + old_buf = gfs_proc_margs; + gfs_proc_margs = new_buf; + spin_unlock(&gfs_proc_margs_lock); + + if (old_buf) + kfree(old_buf); + + return 0; +} + +/** + * do_withdraw - withdraw a from the cluster for one filesystem + * @p: the cookie of the filesystem + * + * Returns: errno + */ + +static int +do_withdraw(char *p) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + int error = 0; + + p = find_argument(p + 8); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else + gfs_lm_withdraw(sdp, + "GFS: fsid=%s: withdrawing from cluster at user's request\n", + sdp->sd_fsname); + + up(&gfs_fs_lock); + + return error; +} + +/** + * do_lockdump - Copy out the lock hash table to userspace + * @p: the cookie of the filesystem + * @buf: + * @size: + * + * Returns: errno + */ + +static int +do_lockdump(char *p, char *buf, size_t size) +{ + struct list_head *tmp; + struct gfs_sbd *sdp; + char num[21]; + struct gfs_user_buffer ub; + int error = 0; + + p = find_argument(p + 8); + if (!p) + return -ENOENT; + + down(&gfs_fs_lock); + + for (tmp = gfs_fs_list.next; tmp != &gfs_fs_list; tmp = tmp->next) { + sdp = list_entry(tmp, struct gfs_sbd, sd_list); + sprintf(num, "%lu", (unsigned long)sdp); + if (strcmp(num, p) == 0) + break; + } + + if (tmp == &gfs_fs_list) + error = -ENOENT; + else { + ub.ub_data = buf; + ub.ub_size = size; + ub.ub_count = 0; + + error = gfs_dump_lockstate(sdp, &ub); + if (!error) + error = ub.ub_count; + } + + up(&gfs_fs_lock); + + return error; +} + +/** + * gfs_proc_write - take a command from userspace + * @file: + * @buf: + * @size: + * @offset: + * + * Returns: -errno or the number of bytes taken + */ + +static ssize_t +gfs_proc_write(struct file *file, const char *buf, size_t size, loff_t *offset) +{ + char *p; + + spin_lock(&gfs_req_lock); + p = file->private_data; + file->private_data = NULL; + spin_unlock(&gfs_req_lock); + + if (p) + kfree(p); + + if (!size) + return -EINVAL; + + p = kmalloc(size + 1, GFP_KERNEL); + if (!p) + return -ENOMEM; + p[size] = 0; + + if (copy_from_user(p, buf, size)) { + kfree(p); + return -EFAULT; + } + + spin_lock(&gfs_req_lock); + file->private_data = p; + spin_unlock(&gfs_req_lock); + + return size; +} + +/** + * gfs_proc_read - return the results of a command + * @file: + * @buf: + * @size: + * @offset: + * + * Returns: -errno or the number of bytes returned + */ + +static ssize_t +gfs_proc_read(struct file *file, char *buf, size_t size, loff_t *offset) +{ + char *p; + int error; + + spin_lock(&gfs_req_lock); + p = file->private_data; + file->private_data = NULL; + spin_unlock(&gfs_req_lock); + + if (!p) + return -ENOENT; + + if (!size) { + kfree(p); + return -EINVAL; + } + + if (strncmp(p, "list", 4) == 0) + error = do_list(buf, size); + else if (strncmp(p, "freeze", 6) == 0) + error = do_freeze(p); + else if (strncmp(p, "unfreeze", 8) == 0) + error = do_unfreeze(p); + else if (strncmp(p, "margs", 5) == 0) + error = do_margs(p); + else if (strncmp(p, "withdraw", 8) == 0) + error = do_withdraw(p); + else if (strncmp(p, "lockdump", 8) == 0) + error = do_lockdump(p, buf, size); + else + error = -ENOSYS; + + kfree(p); + + return error; +} + +/** + * gfs_proc_close - free any mismatches writes + * @inode: + * @file: + * + * Returns: 0 + */ + +static int +gfs_proc_close(struct inode *inode, struct file *file) +{ + if (file->private_data) + kfree(file->private_data); + return 0; +} + +static struct file_operations gfs_proc_fops = +{ + .owner = THIS_MODULE, + .write = gfs_proc_write, + .read = gfs_proc_read, + .release = gfs_proc_close, +}; + +/** + * gfs_proc_init - initialize GFS' proc interface + * + */ + +int +gfs_proc_init(void) +{ + struct proc_dir_entry *pde; + + INIT_LIST_HEAD(&gfs_fs_list); + init_MUTEX(&gfs_fs_lock); + gfs_proc_margs = NULL; + spin_lock_init(&gfs_proc_margs_lock); + spin_lock_init(&gfs_req_lock); + + pde = create_proc_entry("fs/gfs", S_IFREG | 0600, NULL); + if (!pde) + return -ENOMEM; + + pde->owner = THIS_MODULE; + pde->proc_fops = &gfs_proc_fops; + + return 0; +} + +/** + * gfs_proc_uninit - uninitialize GFS' proc interface + * + */ + +void +gfs_proc_uninit(void) +{ + if (gfs_proc_margs) + kfree(gfs_proc_margs); + remove_proc_entry("fs/gfs", NULL); +} + --- linux-2.6.28.orig/ubuntu/gfs/rgrp.h +++ linux-2.6.28/ubuntu/gfs/rgrp.h @@ -0,0 +1,75 @@ +#ifndef __RGRP_DOT_H__ +#define __RGRP_DOT_H__ + +void gfs_mhc_add(struct gfs_rgrpd *rgd, struct buffer_head **bh, + unsigned int num); +int gfs_mhc_fish(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_mhc_zap(struct gfs_rgrpd *rgd); + +void gfs_depend_add(struct gfs_rgrpd *rgd, uint64_t formal_ino); +void gfs_depend_sync(struct gfs_rgrpd *rgd); + +struct gfs_rgrpd *gfs_blk2rgrpd(struct gfs_sbd *sdp, uint64_t blk); +struct gfs_rgrpd *gfs_rgrpd_get_first(struct gfs_sbd *sdp); +struct gfs_rgrpd *gfs_rgrpd_get_next(struct gfs_rgrpd *rgd); + +void gfs_clear_rgrpd(struct gfs_sbd *sdp); + +int gfs_rindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ri_gh); + +int gfs_rgrp_read(struct gfs_rgrpd *rgd); +void gfs_rgrp_relse(struct gfs_rgrpd *rgd); + +void gfs_rgrp_lvb_fill(struct gfs_rgrpd *rgd); +int gfs_rgrp_lvb_init(struct gfs_rgrpd *rgd); + +struct gfs_alloc *gfs_alloc_get(struct gfs_inode *ip); +void gfs_alloc_put(struct gfs_inode *ip); + +int gfs_inplace_reserve_i(struct gfs_inode *ip, + char *file, unsigned int line); +#define gfs_inplace_reserve(ip) \ +gfs_inplace_reserve_i((ip), __FILE__, __LINE__) + +void gfs_inplace_release(struct gfs_inode *ip); + +unsigned char gfs_get_block_type(struct gfs_rgrpd *rgd, uint64_t block); + +void gfs_blkalloc(struct gfs_inode *ip, uint64_t *block); +int gfs_metaalloc(struct gfs_inode *ip, uint64_t *block); +int gfs_dialloc(struct gfs_inode *dip, uint64_t *block); + +void gfs_blkfree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen); +void gfs_metafree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen); +void gfs_difree_uninit(struct gfs_rgrpd *rgd, uint64_t addr); +void gfs_difree(struct gfs_rgrpd *rgd, struct gfs_inode *ip); + +extern void gfs_statfs_modify(struct gfs_sbd *sdp, + int64_t total, + int64_t free, + int64_t dinodes); + +/* + * gfs_rgrp_list + * + * Used to collect a list of all resource groups spanned by a given + * inode/file/directory + */ +struct gfs_rgrp_list { + unsigned int rl_rgrps; /* # (qty) of rgrps in list (array) */ + unsigned int rl_space; /* Current capacity in list for rgrps */ + struct gfs_rgrpd **rl_rgd; /* Array of ptrs to rgrp descriptors */ + struct gfs_holder *rl_ghs; /* Array of glock holders for rgrps */ +}; + +void gfs_rlist_add(struct gfs_sbd *sdp, struct gfs_rgrp_list *rlist, + uint64_t block); +void gfs_rlist_alloc(struct gfs_rgrp_list *rlist, unsigned int state, + int flags); +void gfs_rlist_free(struct gfs_rgrp_list *rlist); + +int gfs_reclaim_metadata(struct gfs_sbd *sdp, + uint64_t *inodes, + uint64_t *metadata); + +#endif /* __RGRP_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/glock.c +++ linux-2.6.28/ubuntu/gfs/glock.c @@ -0,0 +1,2996 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "lm.h" +#include "lops.h" +#include "quota.h" +#include "recovery.h" + +/* Must be kept in sync with the beginning of struct gfs_glock */ +struct glock_plug { + struct list_head gl_list; + unsigned long gl_flags; +}; + +struct greedy { + struct gfs_holder gr_gh; + struct delayed_work gr_work; +}; + +typedef void (*glock_examiner) (struct gfs_glock * gl, unsigned int *cnt); + +/** + * relaxed_state_ok - is a requested lock compatible with the current lock mode? + * @actual: the current state of the lock + * @requested: the lock state that was requested by the caller + * @flags: the modifier flags passed in by the caller + * + * Returns: TRUE if the locks are compatible, FALSE otherwise + * + * It's often possible that a holder B may request the lock in SHARED mode, + * while another holder A (on this same node) has the lock in EXCLUSIVE mode + * (node must hold the glock in EXCLUSIVE mode for this situation, of course). + * This is okay to grant, in some cases, since both holders would have access + * to the in-core up-to-date cached data that the EX holder would write to disk. + * This is the default behavior. + * + * The EXACT flag disallows this behavior, though. A SHARED request would + * compatible only with a SHARED lock with this flag. + * + * The ANY flag provides broader permission to grant the lock to a holder, + * whatever the requested state is, as long as the lock is locked in any mode. + */ + +static __inline__ int +relaxed_state_ok(unsigned int actual, unsigned requested, int flags) +{ + if (actual == requested) + return TRUE; + + if (flags & GL_EXACT) + return FALSE; + + if (actual == LM_ST_EXCLUSIVE && requested == LM_ST_SHARED) + return TRUE; + + if (actual != LM_ST_UNLOCKED && (flags & LM_FLAG_ANY)) + return TRUE; + + return FALSE; +} + +/** + * gl_hash() - Turn glock number into hash bucket number + * @lock: The glock number + * + * Returns: The number of the corresponding hash bucket + */ + +static unsigned int +gl_hash(struct lm_lockname *name) +{ + unsigned int h; + + h = gfs_hash(&name->ln_number, sizeof(uint64_t)); + h = gfs_hash_more(&name->ln_type, sizeof(unsigned int), h); + h &= GFS_GL_HASH_MASK; + + return h; +} + +/** + * glock_hold() - increment reference count on glock + * @gl: The glock to hold + * + */ + +static __inline__ void +glock_hold(struct gfs_glock *gl) +{ + gfs_assert(gl->gl_sbd, atomic_read(&gl->gl_count) > 0,); + atomic_inc(&gl->gl_count); +} + +/** + * glock_put() - Decrement reference count on glock + * @gl: The glock to put + * + */ + +static __inline__ void +glock_put(struct gfs_glock *gl) +{ + if (atomic_read(&gl->gl_count) == 1) + gfs_glock_schedule_for_reclaim(gl); + gfs_assert(gl->gl_sbd, atomic_read(&gl->gl_count) > 0,); + atomic_dec(&gl->gl_count); +} + +/** + * queue_empty - check to see if a glock's queue is empty + * @gl: the glock + * @head: the head of the queue to check + * + * Returns: TRUE if the queue is empty + */ + +static __inline__ int +queue_empty(struct gfs_glock *gl, struct list_head *head) +{ + int empty; + spin_lock(&gl->gl_spin); + empty = list_empty(head); + spin_unlock(&gl->gl_spin); + return empty; +} + +/** + * search_bucket() - Find struct gfs_glock by lock number + * @bucket: the bucket to search + * @name: The lock name + * + * Returns: NULL, or the struct gfs_glock with the requested number + */ + +static struct gfs_glock * +search_bucket(struct gfs_gl_hash_bucket *bucket, struct lm_lockname *name) +{ + struct list_head *tmp, *head; + struct gfs_glock *gl; + + for (head = &bucket->hb_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gl = list_entry(tmp, struct gfs_glock, gl_list); + + if (test_bit(GLF_PLUG, &gl->gl_flags)) + continue; + if (!lm_name_equal(&gl->gl_name, name)) + continue; + + atomic_inc(&gl->gl_count); + + return gl; + } + + return NULL; +} + +/** + * gfs_glock_find() - Find glock by lock number + * @sdp: The GFS superblock + * @name: The lock name + * + * Figure out what bucket the lock is in, acquire the read lock on + * it and call search_bucket(). + * + * Returns: NULL, or the struct gfs_glock with the requested number + */ + +struct gfs_glock * +gfs_glock_find(struct gfs_sbd *sdp, struct lm_lockname *name) +{ + struct gfs_gl_hash_bucket *bucket = &sdp->sd_gl_hash[gl_hash(name)]; + struct gfs_glock *gl; + + read_lock(&bucket->hb_lock); + gl = search_bucket(bucket, name); + read_unlock(&bucket->hb_lock); + + return gl; +} + +/** + * glock_free() - Perform a few checks and then release struct gfs_glock + * @gl: The glock to release + * + * Also calls lock module to release its internal structure for this glock. + * + */ + +static void +glock_free(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct inode *aspace = gl->gl_aspace; + + gfs_assert_warn(sdp, list_empty(&gl->gl_list)); + gfs_assert_warn(sdp, atomic_read(&gl->gl_count) == 1); + gfs_assert_warn(sdp, list_empty(&gl->gl_holders)); + gfs_assert_warn(sdp, list_empty(&gl->gl_waiters1)); + gfs_assert_warn(sdp, list_empty(&gl->gl_waiters2)); + gfs_assert_warn(sdp, list_empty(&gl->gl_waiters3)); + gfs_assert_warn(sdp, gl->gl_state == LM_ST_UNLOCKED); + gfs_assert_warn(sdp, !gl->gl_object); + gfs_assert_warn(sdp, !gl->gl_lvb); + gfs_assert_warn(sdp, list_empty(&gl->gl_reclaim)); + + gfs_lm_put_lock(sdp, gl->gl_lock); + + if (aspace) + gfs_aspace_put(aspace); + + kmem_cache_free(gfs_glock_cachep, gl); + + atomic_dec(&sdp->sd_glock_count); +} + +/** + * gfs_glock_get() - Get a glock, or create one if one doesn't exist + * @sdp: The GFS superblock + * @number: the lock number + * @glops: The glock_operations to use + * @create: If FALSE, don't create the glock if it doesn't exist + * @glp: the glock is returned here + * + * This does not lock a glock, just finds/creates structures for one. + * + * Returns: errno + */ + +int +gfs_glock_get(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + int create, struct gfs_glock **glp) +{ + struct lm_lockname name; + struct gfs_glock *gl, *tmp; + struct gfs_gl_hash_bucket *bucket; + int error; + + /* Look for pre-existing glock in hash table */ + name.ln_number = number; + name.ln_type = glops->go_type; + bucket = &sdp->sd_gl_hash[gl_hash(&name)]; + + read_lock(&bucket->hb_lock); + gl = search_bucket(bucket, &name); + read_unlock(&bucket->hb_lock); + + if (gl || !create) { + *glp = gl; + return 0; + } + + /* None found; create a new one */ + gl = kmem_cache_alloc(gfs_glock_cachep, GFP_KERNEL); + if (!gl) + return -ENOMEM; + + memset(gl, 0, sizeof(struct gfs_glock)); + + INIT_LIST_HEAD(&gl->gl_list); + gl->gl_name = name; + atomic_set(&gl->gl_count, 1); + + spin_lock_init(&gl->gl_spin); + + gl->gl_state = LM_ST_UNLOCKED; + INIT_LIST_HEAD(&gl->gl_holders); + INIT_LIST_HEAD(&gl->gl_waiters1); + INIT_LIST_HEAD(&gl->gl_waiters2); + INIT_LIST_HEAD(&gl->gl_waiters3); + + gl->gl_ops = glops; + + INIT_LE(&gl->gl_new_le, &gfs_glock_lops); + INIT_LE(&gl->gl_incore_le, &gfs_glock_lops); + + gl->gl_bucket = bucket; + INIT_LIST_HEAD(&gl->gl_reclaim); + + gl->gl_sbd = sdp; + + INIT_LIST_HEAD(&gl->gl_ail_bufs); + + /* If this glock protects actual on-disk data or metadata blocks, + create a VFS inode to manage the pages/buffers holding them. */ + if (glops == &gfs_inode_glops || + glops == &gfs_rgrp_glops || + glops == &gfs_meta_glops) { + gl->gl_aspace = gfs_aspace_get(sdp); + if (!gl->gl_aspace) { + error = -ENOMEM; + goto fail; + } + } + + /* Ask lock module to find/create its structure for this lock + (but this doesn't lock the inter-node lock yet) */ + error = gfs_lm_get_lock(sdp, &name, &gl->gl_lock); + if (error) + goto fail_aspace; + + atomic_inc(&sdp->sd_glock_count); + + /* Double-check, in case another process created the glock, and has + put it in the hash table while we were preparing this one */ + write_lock(&bucket->hb_lock); + tmp = search_bucket(bucket, &name); + if (tmp) { + /* Somebody beat us to it; forget the one we prepared */ + write_unlock(&bucket->hb_lock); + glock_free(gl); + gl = tmp; + } else { + /* Add our glock to hash table */ + list_add_tail(&gl->gl_list, &bucket->hb_list); + write_unlock(&bucket->hb_lock); + } + + *glp = gl; + + return 0; + + fail_aspace: + if (gl->gl_aspace) + gfs_aspace_put(gl->gl_aspace); + + fail: + kmem_cache_free(gfs_glock_cachep, gl); + + return error; +} + +/** + * gfs_glock_hold() - As glock_hold(), but suitable for exporting + * @gl: The glock to hold + * + */ + +void +gfs_glock_hold(struct gfs_glock *gl) +{ + glock_hold(gl); +} + +/** + * gfs_glock_put() - As glock_put(), but suitable for exporting + * @gl: The glock to put + * + */ + +void +gfs_glock_put(struct gfs_glock *gl) +{ + glock_put(gl); +} + +/** + * gfs_holder_init - initialize a struct gfs_holder in the default way + * @gl: the glock + * @state: the state we're requesting + * @flags: the modifier flags + * @gh: the holder structure + * + */ + +void +gfs_holder_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh) +{ + memset(gh, 0, sizeof(struct gfs_holder)); + + INIT_LIST_HEAD(&gh->gh_list); + gh->gh_gl = gl; + gh->gh_owner = current; + gh->gh_state = state; + gh->gh_flags = flags; + + if (gh->gh_state == LM_ST_EXCLUSIVE) + gh->gh_flags |= GL_LOCAL_EXCL; + + init_completion(&gh->gh_wait); + + glock_hold(gl); +} + +/** + * gfs_holder_reinit - reinitialize a struct gfs_holder so we can requeue it + * @state: the state we're requesting + * @flags: the modifier flags + * @gh: the holder structure + * + * Preserve holder's associated glock and owning process. + * Reset all holder state flags (we're starting a new request from scratch), + * except for HIF_ALLOCED. + * Don't do glock_hold() again (it was done in gfs_holder_init()). + * Don't mess with the glock. + * + * Rules: + * Holder must have been gfs_holder_init()d already + * Holder must *not* be in glock's holder list or wait queues now + */ + +void +gfs_holder_reinit(unsigned int state, int flags, struct gfs_holder *gh) +{ + int alloced; + + gfs_assert_warn(gh->gh_gl->gl_sbd, + list_empty(&gh->gh_list)); + + gh->gh_state = state; + gh->gh_flags = flags; + + if (gh->gh_state == LM_ST_EXCLUSIVE) + gh->gh_flags |= GL_LOCAL_EXCL; + + alloced = test_bit(HIF_ALLOCED, &gh->gh_iflags); + memset(&gh->gh_iflags, 0, sizeof(unsigned long)); + if (alloced) + set_bit(HIF_ALLOCED, &gh->gh_iflags); +} + +/** + * gfs_holder_uninit - uninitialize a holder structure (drop reference on glock) + * @gh: the holder structure + * + */ + +void +gfs_holder_uninit(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + gfs_assert_warn(gl->gl_sbd, list_empty(&gh->gh_list)); + gh->gh_gl = NULL; + + glock_put(gl); +} + +/** + * gfs_holder_get - get a struct gfs_holder structure + * @gl: the glock + * @state: the state we're requesting + * @flags: the modifier flags + * + * Figure out how big an impact this function has. Either: + * 1) Replace it with a cache of structures hanging off the struct gfs_sbd + * 2) Leave it like it is + * + * Returns: the holder structure, NULL on ENOMEM + */ + +struct gfs_holder * +gfs_holder_get(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_holder *gh; + + gh = kmalloc(sizeof(struct gfs_holder), GFP_KERNEL); + if (!gh) + return NULL; + + gfs_holder_init(gl, state, flags, gh); + set_bit(HIF_ALLOCED, &gh->gh_iflags); + + return gh; +} + +/** + * gfs_holder_put - get rid of a struct gfs_holder structure + * @gh: the holder structure + * + */ + +void +gfs_holder_put(struct gfs_holder *gh) +{ + if (gfs_assert_warn(gh->gh_gl->gl_sbd, + test_bit(HIF_ALLOCED, &gh->gh_iflags))) + return; + gfs_holder_uninit(gh); + kfree(gh); +} + +/** + * handle_recurse - put other holder structures (marked recursive) into the holders list + * @gh: the holder structure + * + */ + +static void +handle_recurse(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct list_head *tmp, *head, *next; + struct gfs_holder *tmp_gh; + int found = FALSE; + + if (gfs_assert_warn(sdp, gh->gh_owner)) + return; + + for (head = &gl->gl_waiters3, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner != gh->gh_owner) + continue; + + gfs_assert_warn(sdp, test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); + + list_move_tail(&tmp_gh->gh_list, &gl->gl_holders); + tmp_gh->gh_error = 0; + set_bit(HIF_HOLDER, &tmp_gh->gh_iflags); + + complete(&tmp_gh->gh_wait); + + found = TRUE; + } + + gfs_assert_warn(sdp, found); +} + +/** + * do_unrecurse - a recursive holder was just dropped of the waiters3 list + * @gh: the holder + * + * If there is only one other recursive holder, clear its HIF_RECURSE bit + * (it's no longer a recursive request). + * If there is more than one, leave them alone (they're recursive!). + * + */ + +static void +do_unrecurse(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct list_head *tmp, *head; + struct gfs_holder *tmp_gh, *last_gh = NULL; + int found = FALSE; + + if (gfs_assert_warn(sdp, gh->gh_owner)) + return; + + for (head = &gl->gl_waiters3, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner != gh->gh_owner) + continue; + + gfs_assert_warn(sdp, test_bit(HIF_RECURSE, &tmp_gh->gh_iflags)); + + /* found more than one */ + if (found) + return; + + found = TRUE; + last_gh = tmp_gh; + } + + /* found just one */ + if (!gfs_assert_warn(sdp, found)) + clear_bit(HIF_RECURSE, &last_gh->gh_iflags); +} + +/** + * rq_mutex - process a mutex request in the queue + * @gh: the glock holder + * + * Returns: TRUE if the queue is blocked (always, since there can be only one + * holder of the mutex). + * + * See lock_on_glock() + */ + +static int +rq_mutex(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + list_del_init(&gh->gh_list); + /* gh->gh_error never examined. */ + set_bit(GLF_LOCK, &gl->gl_flags); + complete(&gh->gh_wait); + + return TRUE; +} + +/** + * rq_promote - process a promote request in the queue + * @gh: the glock holder + * + * Acquire a new inter-node lock, or change a lock state to more restrictive. + * + * Returns: TRUE if the queue is blocked + */ + +static int +rq_promote(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int recurse; + + if (!relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { + if (list_empty(&gl->gl_holders)) { + gl->gl_req_gh = gh; + set_bit(GLF_LOCK, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + /* If we notice a lot of glocks in reclaim list, free + up memory for 2 of them before locking a new one */ + if (atomic_read(&sdp->sd_reclaim_count) > + gfs_tune_get(sdp, gt_reclaim_limit) && + !(gh->gh_flags & LM_FLAG_PRIORITY)) { + gfs_reclaim_glock(sdp); + gfs_reclaim_glock(sdp); + } + + glops->go_xmote_th(gl, gh->gh_state, + gh->gh_flags); + + spin_lock(&gl->gl_spin); + } + return TRUE; + } + + if (list_empty(&gl->gl_holders)) { + set_bit(HIF_FIRST, &gh->gh_iflags); + set_bit(GLF_LOCK, &gl->gl_flags); + recurse = FALSE; + } else { + struct gfs_holder *next_gh; + if (gh->gh_flags & GL_LOCAL_EXCL) + return TRUE; + next_gh = list_entry(gl->gl_holders.next, struct gfs_holder, gh_list); + if (next_gh->gh_flags & GL_LOCAL_EXCL) + return TRUE; + recurse = test_bit(HIF_RECURSE, &gh->gh_iflags); + } + + list_move_tail(&gh->gh_list, &gl->gl_holders); + gh->gh_error = 0; + set_bit(HIF_HOLDER, &gh->gh_iflags); + + if (recurse) + handle_recurse(gh); + + complete(&gh->gh_wait); + + return FALSE; +} + +/** + * rq_demote - process a demote request in the queue + * @gh: the glock holder + * + * Returns: TRUE if the queue is blocked + * + * Unlock an inter-node lock, or change a lock state to less restrictive. + * If the glock is already the same as the holder's requested state, or is + * UNLOCKED, no lock module request is required. + * Otherwise, we need to ask lock module to unlock or change locked state + * of the glock. + * If requested state is UNLOCKED, or current glock state is SHARED or + * DEFERRED (neither of which have a less restrictive state other than + * UNLOCK), we call go_drop_th() to unlock the lock. + * Otherwise (i.e. requested is SHARED or DEFERRED, and current is EXCLUSIVE), + * we can continue to hold the lock, and just ask for a new state; + * we call go_xmote_th() to change state. + * + * Must be called with glock's gl->gl_spin locked. + */ + +static int +rq_demote(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_glock_operations *glops = gl->gl_ops; + + if (!list_empty(&gl->gl_holders)) + return TRUE; + + if (gl->gl_state == gh->gh_state || gl->gl_state == LM_ST_UNLOCKED) { + list_del_init(&gh->gh_list); + gh->gh_error = 0; + spin_unlock(&gl->gl_spin); + if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) + gfs_holder_put(gh); + else + complete(&gh->gh_wait); + spin_lock(&gl->gl_spin); + } else { + gl->gl_req_gh = gh; + set_bit(GLF_LOCK, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + if (gh->gh_state == LM_ST_UNLOCKED || + gl->gl_state != LM_ST_EXCLUSIVE) + /* Unlock */ + glops->go_drop_th(gl); + else + /* Change state while holding lock */ + glops->go_xmote_th(gl, gh->gh_state, gh->gh_flags); + + spin_lock(&gl->gl_spin); + } + + return FALSE; +} + +/** + * rq_greedy - process a queued request to drop greedy status + * @gh: the glock holder + * + * Returns: TRUE if the queue is blocked + */ + +static int +rq_greedy(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + list_del_init(&gh->gh_list); + /* gh->gh_error never examined. */ + clear_bit(GLF_GREEDY, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + gfs_holder_uninit(gh); + kfree(container_of(gh, struct greedy, gr_gh)); + + spin_lock(&gl->gl_spin); + + return FALSE; +} + +/** + * run_queue - process holder structures on the glock's wait queues + * @gl: the glock + * + * Rules: + * Caller must hold gl->gl_spin. + */ + +static void +run_queue(struct gfs_glock *gl) +{ + struct gfs_holder *gh; + int blocked = TRUE; + + for (;;) { + /* Another process is manipulating the glock structure; + we can't do anything now */ + if (test_bit(GLF_LOCK, &gl->gl_flags)) + break; + + /* Waiting to manipulate the glock structure */ + if (!list_empty(&gl->gl_waiters1)) { + gh = list_entry(gl->gl_waiters1.next, + struct gfs_holder, gh_list); + + if (test_bit(HIF_MUTEX, &gh->gh_iflags)) + blocked = rq_mutex(gh); + else + gfs_assert_warn(gl->gl_sbd, FALSE); + + /* Waiting to demote the lock, or drop greedy status */ + } else if (!list_empty(&gl->gl_waiters2) && + !test_bit(GLF_SKIP_WAITERS2, &gl->gl_flags)) { + gh = list_entry(gl->gl_waiters2.next, + struct gfs_holder, gh_list); + + if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) + blocked = rq_demote(gh); + else if (test_bit(HIF_GREEDY, &gh->gh_iflags)) + blocked = rq_greedy(gh); + else + gfs_assert_warn(gl->gl_sbd, FALSE); + + /* Waiting to promote the lock */ + } else if (!list_empty(&gl->gl_waiters3)) { + gh = list_entry(gl->gl_waiters3.next, + struct gfs_holder, gh_list); + + if (test_bit(HIF_PROMOTE, &gh->gh_iflags)) + blocked = rq_promote(gh); + else + gfs_assert_warn(gl->gl_sbd, FALSE); + + } else + break; + + if (blocked) + break; + } +} + +/** + * lock_on_glock - acquire a local lock on a glock (structure) + * @gl: the glock + * + * Gives caller exclusive access to manipulate a glock structure. + * Has nothing to do with inter-node lock state or GL_LOCAL_EXCL! + * + * If structure already locked, places temporary holder structure on glock's + * wait-for-exclusive-access queue, and blocks until exclusive access granted. + */ + +static void +lock_on_glock(struct gfs_glock *gl) +{ + struct gfs_holder gh; + + gfs_holder_init(gl, 0, 0, &gh); + set_bit(HIF_MUTEX, &gh.gh_iflags); + + spin_lock(&gl->gl_spin); + if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) + list_add_tail(&gh.gh_list, &gl->gl_waiters1); + else + complete(&gh.gh_wait); + spin_unlock(&gl->gl_spin); + + wait_for_completion(&gh.gh_wait); + gfs_holder_uninit(&gh); +} + +/** + * trylock_on_glock - try to acquire a local lock on a glock (structure) + * @gl: the glock + * + * Returns: TRUE if the glock is acquired + * + * Tries to give caller exclusive access to manipulate a glock structure. + * Has nothing to do with inter-node lock state or LOCAL_EXCL! + * + * If structure already locked, does not block to wait; returns FALSE. + */ + +static int +trylock_on_glock(struct gfs_glock *gl) +{ + int acquired = TRUE; + + spin_lock(&gl->gl_spin); + if (test_and_set_bit(GLF_LOCK, &gl->gl_flags)) + acquired = FALSE; + spin_unlock(&gl->gl_spin); + + return acquired; +} + +/** + * unlock_on_glock - release a local lock on a glock (structure) + * @gl: the glock + * + * Caller is done manipulating glock structure. + * Service any others waiting for exclusive access. + */ + +static void +unlock_on_glock(struct gfs_glock *gl) +{ + spin_lock(&gl->gl_spin); + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); +} + +/** + * handle_callback - add a demote request to a lock's queue + * @gl: the glock + * @state: the state the caller wants us to change to + * + * Called when we learn that another node needs a lock held by this node, + * or when this node simply wants to drop a lock as soon as it's done with + * it (NOCACHE flag), or dump a glock out of glock cache (reclaim it). + * + * We are told the @state that will satisfy the needs of the caller, so + * we can ask for a demote to that state. + * + * If another demote request is already on the queue for a different state, just + * set its request to UNLOCK (and don't bother queueing a request for us). + * This consolidates LM requests and moves the lock to the least restrictive + * state, so it will be compatible with whatever reason we were called. + * No need to be too smart here. Demotes between the shared and deferred + * states will often fail, so don't even try. + * + * Otherwise, queue a demote request to the requested state. + */ + +static void +handle_callback(struct gfs_glock *gl, unsigned int state) +{ + struct list_head *tmp, *head; + struct gfs_holder *gh, *new_gh = NULL; + + if (gfs_assert_warn(gl->gl_sbd, state != LM_ST_EXCLUSIVE)) + return; + + restart: + spin_lock(&gl->gl_spin); + + /* If another queued demote request is for a different state, + set its request to UNLOCKED */ + for (head = &gl->gl_waiters2, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + if (test_bit(HIF_DEMOTE, &gh->gh_iflags) && + gl->gl_req_gh != gh) { + if (gh->gh_state != state) + gh->gh_state = LM_ST_UNLOCKED; + goto out; + } + } + + /* pass 2; add new holder to glock's demote request queue */ + if (new_gh) { + list_add_tail(&new_gh->gh_list, &gl->gl_waiters2); + new_gh = NULL; + + /* pass 1; set up a new holder struct for a demote request, then + check again to see if another process added a demote request + while we were preparing this one. */ + } else { + spin_unlock(&gl->gl_spin); + + RETRY_MALLOC(new_gh = gfs_holder_get(gl, state, LM_FLAG_TRY), + new_gh); + set_bit(HIF_DEMOTE, &new_gh->gh_iflags); + set_bit(HIF_DEALLOC, &new_gh->gh_iflags); + new_gh->gh_owner = NULL; + + goto restart; + } + + out: + spin_unlock(&gl->gl_spin); + + if (new_gh) + gfs_holder_put(new_gh); +} + +/** + * state_change - record that the glock is now in a different state + * @gl: the glock + * @new_state the new state + * + */ + +static void +state_change(struct gfs_glock *gl, unsigned int new_state) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + int held1, held2; + + held1 = (gl->gl_state != LM_ST_UNLOCKED); + held2 = (new_state != LM_ST_UNLOCKED); + + if (held1 != held2) { + if (held2) { + atomic_inc(&sdp->sd_glock_held_count); + glock_hold(gl); + } else { + atomic_dec(&sdp->sd_glock_held_count); + glock_put(gl); + } + } + + gl->gl_state = new_state; +} + +/** + * xmote_bh - Called after the lock module is done acquiring a lock + * @gl: The glock in question + * @ret: the int returned from the lock module + * + */ + +static void +xmote_bh(struct gfs_glock *gl, unsigned int ret) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + struct gfs_holder *gh = gl->gl_req_gh; + int prev_state = gl->gl_state; + int op_done = TRUE; + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, !(ret & LM_OUT_ASYNC)); + + state_change(gl, ret & LM_OUT_ST_MASK); + + if (prev_state != LM_ST_UNLOCKED && !(ret & LM_OUT_CACHEABLE)) { + if (glops->go_inval) + glops->go_inval(gl, DIO_METADATA | DIO_DATA); + } else if (gl->gl_state == LM_ST_DEFERRED) { + /* We might not want to do this here. + Look at moving to the inode glops. */ + if (glops->go_inval) + glops->go_inval(gl, DIO_DATA); + } + + /* Deal with each possible exit condition */ + + if (!gh) + gl->gl_stamp = jiffies; + + else if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = -EIO; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + + } else if (test_bit(HIF_DEMOTE, &gh->gh_iflags)) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + if (gl->gl_state == gh->gh_state || + gl->gl_state == LM_ST_UNLOCKED) + gh->gh_error = 0; + else { + if (gfs_assert_warn(sdp, gh->gh_flags & + (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) == -1) + printk("GFS: fsid=%s: ret = 0x%.8X\n", + sdp->sd_fsname, ret); + gh->gh_error = GLR_TRYFAILED; + } + spin_unlock(&gl->gl_spin); + + if (ret & LM_OUT_CANCELED) + handle_callback(gl, LM_ST_UNLOCKED); /* Lame */ + + } else if (ret & LM_OUT_CANCELED) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = GLR_CANCELED; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + + } else if (relaxed_state_ok(gl->gl_state, gh->gh_state, gh->gh_flags)) { + spin_lock(&gl->gl_spin); + list_move_tail(&gh->gh_list, &gl->gl_holders); + gh->gh_error = 0; + set_bit(HIF_HOLDER, &gh->gh_iflags); + spin_unlock(&gl->gl_spin); + + set_bit(HIF_FIRST, &gh->gh_iflags); + + op_done = FALSE; + + } else if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = GLR_TRYFAILED; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + + } else { + if (gfs_assert_withdraw(sdp, FALSE) == -1) + printk("GFS: fsid=%s: ret = 0x%.8X\n", + sdp->sd_fsname, ret); + } + + if (glops->go_xmote_bh) + glops->go_xmote_bh(gl); + + if (op_done) { + spin_lock(&gl->gl_spin); + gl->gl_req_gh = NULL; + gl->gl_req_bh = NULL; + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); + } + + glock_put(gl); + + if (gh) { + if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) + gfs_holder_put(gh); + else + complete(&gh->gh_wait); + } +} + +/** + * gfs_glock_xmote_th - Call into the lock module to acquire or change a glock + * @gl: The glock in question + * @state: the requested state + * @flags: modifier flags to the lock call + * + * Used to acquire a new glock, or to change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + * + * *Not* used to unlock a glock; use gfs_glock_drop_th() for that. + */ + +void +gfs_glock_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int lck_flags = flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB | + LM_FLAG_NOEXP | LM_FLAG_ANY | + LM_FLAG_PRIORITY); + unsigned int lck_ret; + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, state != LM_ST_UNLOCKED); + gfs_assert_warn(sdp, state != gl->gl_state); + + /* Current state EX, may need to sync log/data/metadata to disk */ + if (gl->gl_state == LM_ST_EXCLUSIVE) { + if (glops->go_sync) + glops->go_sync(gl, DIO_METADATA | DIO_DATA); + } + + glock_hold(gl); + gl->gl_req_bh = xmote_bh; + + atomic_inc(&sdp->sd_lm_lock_calls); + + lck_ret = gfs_lm_lock(sdp, gl->gl_lock, + gl->gl_state, state, + lck_flags); + + if (gfs_assert_withdraw(sdp, !(lck_ret & LM_OUT_ERROR))) + goto out; + + if (lck_ret & LM_OUT_ASYNC) + gfs_assert_warn(sdp, lck_ret == LM_OUT_ASYNC); + else + xmote_bh(gl, lck_ret); + out: + return; +} + +/** + * drop_bh - Called after a lock module unlock completes + * @gl: the glock + * @ret: the return status + * + * Doesn't wake up the process waiting on the struct gfs_holder (if any) + * Doesn't drop the reference on the glock the top half took out + * + */ + +static void +drop_bh(struct gfs_glock *gl, unsigned int ret) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + struct gfs_holder *gh = gl->gl_req_gh; + + clear_bit(GLF_PREFETCH, &gl->gl_flags); + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, !ret); + + state_change(gl, LM_ST_UNLOCKED); + + if (glops->go_inval) + glops->go_inval(gl, DIO_METADATA | DIO_DATA); + + if (gh) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = 0; + spin_unlock(&gl->gl_spin); + } + + if (glops->go_drop_bh) + glops->go_drop_bh(gl); + + spin_lock(&gl->gl_spin); + gl->gl_req_gh = NULL; + gl->gl_req_bh = NULL; + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + glock_put(gl); + + if (gh) { + if (test_bit(HIF_DEALLOC, &gh->gh_iflags)) + gfs_holder_put(gh); + else + complete(&gh->gh_wait); + } +} + +/** + * gfs_glock_drop_th - call into the lock module to unlock a lock + * @gl: the glock + * + */ + +void +gfs_glock_drop_th(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + unsigned int ret; + + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + gfs_assert_warn(sdp, queue_empty(gl, &gl->gl_holders)); + gfs_assert_warn(sdp, gl->gl_state != LM_ST_UNLOCKED); + + /* Leaving state EX, may need to sync log/data/metadata to disk */ + if (gl->gl_state == LM_ST_EXCLUSIVE) { + if (glops->go_sync) + glops->go_sync(gl, DIO_METADATA | DIO_DATA); + } + + glock_hold(gl); + gl->gl_req_bh = drop_bh; + + atomic_inc(&sdp->sd_lm_unlock_calls); + + ret = gfs_lm_unlock(sdp, gl->gl_lock, gl->gl_state); + + if (gfs_assert_withdraw(sdp, !(ret & LM_OUT_ERROR))) + goto out; + + if (!ret) + drop_bh(gl, ret); + else + gfs_assert_warn(sdp, ret == LM_OUT_ASYNC); + out: + return; +} + +/** + * do_cancels - cancel requests for locks stuck waiting on an expire flag + * @gh: the LM_FLAG_PRIORITY holder waiting to acquire the lock + * + * Don't cancel GL_NOCANCEL requests. + */ + +static void +do_cancels(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + + spin_lock(&gl->gl_spin); + + while (gl->gl_req_gh != gh && + !test_bit(HIF_HOLDER, &gh->gh_iflags) && + !list_empty(&gh->gh_list)) { + if (gl->gl_req_bh && + !(gl->gl_req_gh && + (gl->gl_req_gh->gh_flags & GL_NOCANCEL))) { + spin_unlock(&gl->gl_spin); + gfs_lm_cancel(gl->gl_sbd, gl->gl_lock); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); + spin_lock(&gl->gl_spin); + } else { + spin_unlock(&gl->gl_spin); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); + spin_lock(&gl->gl_spin); + } + } + + spin_unlock(&gl->gl_spin); +} + +/** + * glock_wait_internal - wait on a glock acquisition + * @gh: the glock holder + * + * Returns: 0 on success + */ + +static int +glock_wait_internal(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int error = 0; + + if (test_bit(HIF_ABORTED, &gh->gh_iflags)) + return -EIO; + + if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) { + spin_lock(&gl->gl_spin); + if (gl->gl_req_gh != gh && + !test_bit(HIF_HOLDER, &gh->gh_iflags) && + !list_empty(&gh->gh_list)) { + list_del_init(&gh->gh_list); + gh->gh_error = GLR_TRYFAILED; + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + run_queue(gl); + spin_unlock(&gl->gl_spin); + return GLR_TRYFAILED; + } + spin_unlock(&gl->gl_spin); + } + + if ((gh->gh_flags & LM_FLAG_PRIORITY) && + !(gh->gh_flags & GL_NOCANCEL_OTHER)) + do_cancels(gh); + + wait_for_completion(&gh->gh_wait); + + if (gh->gh_error) + return gh->gh_error; + + gfs_assert_withdraw(sdp, test_bit(HIF_HOLDER, &gh->gh_iflags)); + gfs_assert_withdraw(sdp, relaxed_state_ok(gl->gl_state, + gh->gh_state, + gh->gh_flags)); + + if (test_bit(HIF_FIRST, &gh->gh_iflags)) { + gfs_assert_warn(sdp, test_bit(GLF_LOCK, &gl->gl_flags)); + + if (glops->go_lock) { + error = glops->go_lock(gl, gh->gh_flags); + if (error) { + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + gh->gh_error = error; + if (test_and_clear_bit(HIF_RECURSE, &gh->gh_iflags)) + do_unrecurse(gh); + spin_unlock(&gl->gl_spin); + } + } + + spin_lock(&gl->gl_spin); + gl->gl_req_gh = NULL; + gl->gl_req_bh = NULL; + clear_bit(GLF_LOCK, &gl->gl_flags); + if (test_bit(HIF_RECURSE, &gh->gh_iflags)) + handle_recurse(gh); + run_queue(gl); + spin_unlock(&gl->gl_spin); + } + + return error; +} + +/** + * add_to_queue - Add a holder to the wait-for-promotion queue or holder list + * (according to recursion) + * @gh: the holder structure to add + * + * If the hold requestor's process already has a granted lock (on holder list), + * and this new request is compatible, go ahead and grant it, adding this + * new holder to the glock's holder list. + * + * If the hold requestor's process has earlier requested a lock, and is still + * waiting for it to be granted, and this new request is compatible with + * the earlier one, they can be handled at the same time when the request + * is finally granted. Mark both (all) with RECURSE flags, and add new + * holder to wait-for-promotion queue. + * + * If there is no previous holder from this process (on holder list or wait- + * for-promotion queue), simply add new holder to wait-for-promotion queue. + */ + +static void +add_to_queue(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct list_head *tmp, *head; + struct gfs_holder *tmp_gh; + + if (gh->gh_owner) { + /* Search through glock's holders list to see if this process + already holds a granted lock. */ + for (head = &gl->gl_holders, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner == gh->gh_owner) { + /* Make sure pre-existing holder is compatible + with this new one. */ + if (gfs_assert_warn(sdp, (gh->gh_flags & LM_FLAG_ANY) || + !(tmp_gh->gh_flags & LM_FLAG_ANY)) || + gfs_assert_warn(sdp, (tmp_gh->gh_flags & GL_LOCAL_EXCL) || + !(gh->gh_flags & GL_LOCAL_EXCL)) || + gfs_assert_warn(sdp, relaxed_state_ok(gl->gl_state, + gh->gh_state, + gh->gh_flags))) + goto fail; + + /* We're good! Grant the hold. */ + list_add_tail(&gh->gh_list, &gl->gl_holders); + set_bit(HIF_HOLDER, &gh->gh_iflags); + + gh->gh_error = 0; + complete(&gh->gh_wait); + + return; + } + } + + /* If not, Search through glock's wait-for-promotion list to + see if this process already is waiting for a grant. */ + for (head = &gl->gl_waiters3, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_gh = list_entry(tmp, struct gfs_holder, gh_list); + if (tmp_gh->gh_owner == gh->gh_owner) { + /* Yes, make sure it is compatible with new */ + if (gfs_assert_warn(sdp, test_bit(HIF_PROMOTE, + &tmp_gh->gh_iflags)) || + gfs_assert_warn(sdp, (gh->gh_flags & LM_FLAG_ANY) || + !(tmp_gh->gh_flags & LM_FLAG_ANY)) || + gfs_assert_warn(sdp, (tmp_gh->gh_flags & GL_LOCAL_EXCL) || + !(gh->gh_flags & GL_LOCAL_EXCL)) || + gfs_assert_warn(sdp, relaxed_state_ok(tmp_gh->gh_state, + gh->gh_state, + gh->gh_flags))) + goto fail; + + /* OK, make sure they're marked, so + * when one gets granted, the other will too. */ + set_bit(HIF_RECURSE, &gh->gh_iflags); + set_bit(HIF_RECURSE, &tmp_gh->gh_iflags); + + list_add_tail(&gh->gh_list, &gl->gl_waiters3); + + return; + } + } + } + + /* Else, no recursion ... + If high priority request, add to head of promote queue, else tail */ + if (gh->gh_flags & LM_FLAG_PRIORITY) + list_add(&gh->gh_list, &gl->gl_waiters3); + else + list_add_tail(&gh->gh_list, &gl->gl_waiters3); + + return; + + fail: + set_bit(HIF_ABORTED, &gh->gh_iflags); +} + +/** + * gfs_glock_nq - enqueue a struct gfs_holder onto a glock (acquire a glock) + * @gh: the holder structure + * + * if (gh->gh_flags & GL_ASYNC), this never returns an error + * + * Returns: 0, GLR_TRYFAILED, or errno on failure + * + * Rules: + * @gh must not be already attached to a glock. + * Don't ask for UNLOCKED state (use gfs_glock_dq() for that). + * LM_FLAG_ANY (liberal) and GL_EXACT (restrictive) are mutually exclusive. + */ + +int +gfs_glock_nq(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + int error = 0; + + atomic_inc(&sdp->sd_glock_nq_calls); + + restart: + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) || + gfs_assert_warn(sdp, list_empty(&gh->gh_list)) || + gfs_assert_warn(sdp, gh->gh_state != LM_ST_UNLOCKED) || + gfs_assert_warn(sdp, (gh->gh_flags & (LM_FLAG_ANY | GL_EXACT)) != + (LM_FLAG_ANY | GL_EXACT))) { + set_bit(HIF_ABORTED, &gh->gh_iflags); + return -EIO; + } + + set_bit(HIF_PROMOTE, &gh->gh_iflags); + + spin_lock(&gl->gl_spin); + add_to_queue(gh); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + if (!(gh->gh_flags & GL_ASYNC)) { + error = glock_wait_internal(gh); + if (error == GLR_CANCELED) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto restart; + } + } + + clear_bit(GLF_PREFETCH, &gl->gl_flags); + + return error; +} + +/** + * gfs_glock_poll - poll to see if an async request has been completed + * @gh: the holder + * + * Returns: TRUE if the request is ready to be gfs_glock_wait()ed on + */ + +int +gfs_glock_poll(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + int ready = FALSE; + + gfs_assert_warn(gl->gl_sbd, gh->gh_flags & GL_ASYNC); + + spin_lock(&gl->gl_spin); + + if (test_bit(HIF_HOLDER, &gh->gh_iflags)) + ready = TRUE; + else if (list_empty(&gh->gh_list)) { + if (gh->gh_error == GLR_CANCELED) { + spin_unlock(&gl->gl_spin); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + if (gfs_glock_nq(gh)) + return TRUE; + return FALSE; + } else + ready = TRUE; + } + + spin_unlock(&gl->gl_spin); + + return ready; +} + +/** + * gfs_glock_wait - wait for a lock acquisition that ended in a GLR_ASYNC + * @gh: the holder structure + * + * Returns: 0, GLR_TRYFAILED, or errno on failure + */ + +int +gfs_glock_wait(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + int error; + + gfs_assert_warn(gl->gl_sbd, gh->gh_flags & GL_ASYNC); + + error = glock_wait_internal(gh); + if (error == GLR_CANCELED) { + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + gh->gh_flags &= ~GL_ASYNC; + error = gfs_glock_nq(gh); + } + + return error; +} + +/** + * gfs_glock_dq - dequeue a struct gfs_holder from a glock (release a glock) + * @gh: the glock holder + * + * This releases a local process' hold on a glock, and services other waiters. + * If this is the last holder on this node, calls glock operation go_unlock(), + * and go_sync() if requested by glock's GL_SYNC flag. + * If glock's GL_NOCACHE flag is set, requests demotion to unlock the inter- + * node lock now, rather than caching the glock for later use. + * Otherwise, this function does *not* release the glock at inter-node scope. + * The glock will stay in glock cache until: + * -- This node uses it again (extending residence in glock cache), or + * -- Another node asks (via callback) for the lock, or + * -- The glock sits unused in glock cache for a while, and the cleanup + * daemons (gfs_scand and gfs_glockd) reclaim it. + */ + +void +gfs_glock_dq(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + + atomic_inc(&gl->gl_sbd->sd_glock_dq_calls); + + gfs_assert_withdraw(sdp, !queue_empty(gl, &gh->gh_list)); + gfs_assert_withdraw(sdp, test_bit(HIF_HOLDER, &gh->gh_iflags)); + + if (gh->gh_flags & GL_SYNC) + set_bit(GLF_SYNC, &gl->gl_flags); + + /* Don't cache glock; request demote to unlock at inter-node scope */ + if (gh->gh_flags & GL_NOCACHE && gl->gl_holders.next == &gh->gh_list && + gl->gl_holders.prev == &gh->gh_list) + /* There's a race here. If there are two holders, and both + * are dq'ed at almost the same time, you can't guarantee that + * you will call handle_callback. Fixing this will require + * some refactoring */ + handle_callback(gl, LM_ST_UNLOCKED); + + lock_on_glock(gl); + + spin_lock(&gl->gl_spin); + list_del_init(&gh->gh_list); + + /* If last holder, do appropriate glock operations, set cache timer */ + if (list_empty(&gl->gl_holders)) { + spin_unlock(&gl->gl_spin); + + if (glops->go_unlock) + glops->go_unlock(gl, gh->gh_flags); + + /* Do "early" sync, if requested by holder */ + if (test_bit(GLF_SYNC, &gl->gl_flags)) { + if (glops->go_sync) + glops->go_sync(gl, + DIO_METADATA | + DIO_DATA | + DIO_INVISIBLE); + } + + gl->gl_stamp = jiffies; + + spin_lock(&gl->gl_spin); + } + + clear_bit(GLF_LOCK, &gl->gl_flags); + run_queue(gl); + spin_unlock(&gl->gl_spin); +} + +/** + * gfs_glock_prefetch - Try to prefetch a glock + * @gl: the glock + * @state: the state to prefetch in + * @flags: flags passed to go_xmote_th() + * + * Bypass request queues of glock (i.e. no holder involved), and directly call + * go_xmote_th() to ask lock module for lock, to put in glock cache for + * later use. + * + * Will not prefetch the lock (no need to) if a process on this node is already + * interested in the lock, or if it's sitting in glock cache in a compatible + * state. + * + * Rules: + * Don't ask for UNLOCKED state (use gfs_glock_dq() for that). + * LM_FLAG_ANY (liberal) and GL_EXACT (restrictive) are mutually exclusive. + */ + +void +gfs_glock_prefetch(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + + if (gfs_assert_warn(sdp, state != LM_ST_UNLOCKED) || + gfs_assert_warn(sdp, (flags & (LM_FLAG_ANY | GL_EXACT)) != + (LM_FLAG_ANY | GL_EXACT))) + return; + + spin_lock(&gl->gl_spin); + + /* Should we prefetch? */ + if (test_bit(GLF_LOCK, &gl->gl_flags) || + !list_empty(&gl->gl_holders) || + !list_empty(&gl->gl_waiters1) || + !list_empty(&gl->gl_waiters2) || + !list_empty(&gl->gl_waiters3) || + relaxed_state_ok(gl->gl_state, state, flags)) { + spin_unlock(&gl->gl_spin); + return; + } + + /* Let bottom half know we're prefetching, ask lock module for lock */ + set_bit(GLF_PREFETCH, &gl->gl_flags); + + if (gfs_assert_warn(sdp, !gl->gl_req_gh)) + gl->gl_req_gh = NULL; + set_bit(GLF_LOCK, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + + glops->go_xmote_th(gl, state, flags); + + atomic_inc(&gl->gl_sbd->sd_glock_prefetch_calls); +} + +/** + * gfs_glock_force_drop - Force a glock to be uncached + * @gl: the glock + * + */ + +void +gfs_glock_force_drop(struct gfs_glock *gl) +{ + struct gfs_holder gh; + + gfs_holder_init(gl, LM_ST_UNLOCKED, 0, &gh); + set_bit(HIF_DEMOTE, &gh.gh_iflags); + gh.gh_owner = NULL; + + spin_lock(&gl->gl_spin); + list_add_tail(&gh.gh_list, &gl->gl_waiters2); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + wait_for_completion(&gh.gh_wait); + gfs_holder_uninit(&gh); +} + +/** + * greedy_work - + * @data: + * + */ + +static void +greedy_work(struct work_struct *work) +{ + struct greedy *gr = container_of(work, struct greedy, gr_work.work); + struct gfs_holder *gh = &gr->gr_gh; + struct gfs_glock *gl = gh->gh_gl; + struct gfs_glock_operations *glops = gl->gl_ops; + + clear_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); + + if (glops->go_greedy) + glops->go_greedy(gl); + + spin_lock(&gl->gl_spin); + + if (list_empty(&gl->gl_waiters2)) { + clear_bit(GLF_GREEDY, &gl->gl_flags); + spin_unlock(&gl->gl_spin); + gfs_holder_uninit(gh); + kfree(gr); + } else { + glock_hold(gl); + list_add_tail(&gh->gh_list, &gl->gl_waiters2); + run_queue(gl); + spin_unlock(&gl->gl_spin); + glock_put(gl); + } +} + +/** + * gfs_glock_be_greedy - + * @gl: + * @time: + * + * Returns: 0 if go_greedy will be called, 1 otherwise + */ + +int +gfs_glock_be_greedy(struct gfs_glock *gl, unsigned int time) +{ + struct greedy *gr; + struct gfs_holder *gh; + + if (!time || + gl->gl_sbd->sd_args.ar_localcaching || + test_and_set_bit(GLF_GREEDY, &gl->gl_flags)) + return 1; + + gr = kmalloc(sizeof(struct greedy), GFP_KERNEL); + if (!gr) { + clear_bit(GLF_GREEDY, &gl->gl_flags); + return 1; + } + gh = &gr->gr_gh; + + gfs_holder_init(gl, 0, 0, gh); + set_bit(HIF_GREEDY, &gh->gh_iflags); + gh->gh_owner = NULL; + INIT_DELAYED_WORK(&gr->gr_work, greedy_work); + + set_bit(GLF_SKIP_WAITERS2, &gl->gl_flags); + schedule_delayed_work(&gr->gr_work, time); + + return 0; +} + +/** + * gfs_glock_nq_init - intialize a holder and enqueue it on a glock + * @gl: the glock + * @state: the state we're requesting + * @flags: the modifier flags + * @gh: the holder structure + * + * Returns: 0, GLR_*, or errno + */ + +int +gfs_glock_nq_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh) +{ + int error; + + gfs_holder_init(gl, state, flags, gh); + + error = gfs_glock_nq(gh); + if (error) + gfs_holder_uninit(gh); + + return error; +} + +/** + * gfs_glock_dq_uninit - dequeue a holder from a glock and initialize it + * @gh: the holder structure + * + */ + +void +gfs_glock_dq_uninit(struct gfs_holder *gh) +{ + gfs_glock_dq(gh); + gfs_holder_uninit(gh); +} + +/** + * gfs_glock_nq_num - acquire a glock based on lock number + * @sdp: the filesystem + * @number: the lock number + * @glops: the glock operations for the type of glock + * @state: the state to acquire the glock in + * @flags: modifier flags for the aquisition + * @gh: the struct gfs_holder + * + * Returns: errno + */ + +int +gfs_glock_nq_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags, struct gfs_holder *gh) +{ + struct gfs_glock *gl; + int error; + + error = gfs_glock_get(sdp, number, glops, CREATE, &gl); + if (!error) { + error = gfs_glock_nq_init(gl, state, flags, gh); + glock_put(gl); + } + + return error; +} + +/** + * glock_compare - Compare two struct gfs_glock structures for sorting + * @arg_a: the first structure + * @arg_b: the second structure + * + */ + +static int +glock_compare(const void *arg_a, const void *arg_b) +{ + struct gfs_holder *gh_a = *(struct gfs_holder **)arg_a; + struct gfs_holder *gh_b = *(struct gfs_holder **)arg_b; + struct lm_lockname *a = &gh_a->gh_gl->gl_name; + struct lm_lockname *b = &gh_b->gh_gl->gl_name; + int ret = 0; + + if (a->ln_number > b->ln_number) + ret = 1; + else if (a->ln_number < b->ln_number) + ret = -1; + else { + if (gh_a->gh_state == LM_ST_SHARED && + gh_b->gh_state == LM_ST_EXCLUSIVE) + ret = 1; + else if (!(gh_a->gh_flags & GL_LOCAL_EXCL) && + (gh_b->gh_flags & GL_LOCAL_EXCL)) + ret = 1; + } + + return ret; +} + +/** + * nq_m_sync - synchonously acquire more than one glock in deadlock free order + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + * Returns: 0 on success (all glocks acquired), errno on failure (no glocks acquired) + */ + +static int +nq_m_sync(unsigned int num_gh, struct gfs_holder *ghs, struct gfs_holder **p) +{ + unsigned int x; + int error = 0; + + for (x = 0; x < num_gh; x++) + p[x] = &ghs[x]; + + gfs_sort(p, num_gh, sizeof(struct gfs_holder *), glock_compare); + + for (x = 0; x < num_gh; x++) { + p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + + error = gfs_glock_nq(p[x]); + if (error) { + while (x--) + gfs_glock_dq(p[x]); + break; + } + } + + return error; +} + +/** + * gfs_glock_nq_m - acquire multiple glocks + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + * Figure out how big an impact this function has. Either: + * 1) Replace this code with code that calls gfs_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) + */ + +int +gfs_glock_nq_m(unsigned int num_gh, struct gfs_holder *ghs) +{ + int *e; + unsigned int x; + int borked = FALSE, serious = 0; + int error = 0; + + if (!num_gh) + return 0; + + /* For just one gh, do request synchronously */ + if (num_gh == 1) { + ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + return gfs_glock_nq(ghs); + } + + /* using sizeof(struct gfs_holder *) instead of sizeof(int), because + * we're also using this memory for nq_m_sync and ints should never be + * larger than pointers.... I hope + */ + e = kmalloc(num_gh * sizeof(struct gfs_holder *), GFP_KERNEL); + if (!e) + return -ENOMEM; + + /* Send off asynchronous requests */ + for (x = 0; x < num_gh; x++) { + ghs[x].gh_flags |= LM_FLAG_TRY | GL_ASYNC; + error = gfs_glock_nq(&ghs[x]); + if (error) { + borked = TRUE; + serious = error; + num_gh = x; + break; + } + } + + /* Wait for all to complete */ + for (x = 0; x < num_gh; x++) { + error = e[x] = glock_wait_internal(&ghs[x]); + if (error) { + borked = TRUE; + if (error != GLR_TRYFAILED && error != GLR_CANCELED) + serious = error; + } + } + + /* If all good, done! */ + if (!borked) { + kfree(e); + return 0; + } + + for (x = 0; x < num_gh; x++) + if (!e[x]) + gfs_glock_dq(&ghs[x]); + + if (serious) + error = serious; + else { + for (x = 0; x < num_gh; x++) + gfs_holder_reinit(ghs[x].gh_state, ghs[x].gh_flags, + &ghs[x]); + error = nq_m_sync(num_gh, ghs, (struct gfs_holder **)e); + } + + kfree(e); + return error; +} + +/** + * gfs_glock_dq_m - release multiple glocks + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + */ + +void +gfs_glock_dq_m(unsigned int num_gh, struct gfs_holder *ghs) +{ + unsigned int x; + + for (x = 0; x < num_gh; x++) + gfs_glock_dq(&ghs[x]); +} + +/** + * gfs_glock_prefetch_num - prefetch a glock based on lock number + * @sdp: the filesystem + * @number: the lock number + * @glops: the glock operations for the type of glock + * @state: the state to acquire the glock in + * @flags: modifier flags for the aquisition + * + * Returns: errno + */ + +void +gfs_glock_prefetch_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags) +{ + struct gfs_glock *gl; + int error; + + if (atomic_read(&sdp->sd_reclaim_count) < gfs_tune_get(sdp, gt_reclaim_limit)) { + error = gfs_glock_get(sdp, number, glops, CREATE, &gl); + if (!error) { + gfs_glock_prefetch(gl, state, flags); + glock_put(gl); + } + } +} + +/** + * gfs_lvb_hold - attach a LVB from a glock + * @gl: The glock in question + * + */ + +int +gfs_lvb_hold(struct gfs_glock *gl) +{ + int error; + + lock_on_glock(gl); + + if (!atomic_read(&gl->gl_lvb_count)) { + gfs_assert_warn(gl->gl_sbd, !gl->gl_lvb); + error = gfs_lm_hold_lvb(gl->gl_sbd, gl->gl_lock, &gl->gl_lvb); + if (error) { + unlock_on_glock(gl); + return error; + } + glock_hold(gl); + } + atomic_inc(&gl->gl_lvb_count); + + unlock_on_glock(gl); + + return 0; +} + +/** + * gfs_lvb_unhold - detach a LVB from a glock + * @gl: The glock in question + * + */ + +void +gfs_lvb_unhold(struct gfs_glock *gl) +{ + glock_hold(gl); + + lock_on_glock(gl); + + if (!gfs_assert_warn(gl->gl_sbd, atomic_read(&gl->gl_lvb_count) > 0) && + atomic_dec_and_test(&gl->gl_lvb_count)) { + gfs_assert_warn(gl->gl_sbd, gl->gl_lvb); + gfs_lm_unhold_lvb(gl->gl_sbd, gl->gl_lock, gl->gl_lvb); + gl->gl_lvb = NULL; + glock_put(gl); + } + + unlock_on_glock(gl); + + glock_put(gl); +} + +#if 0 +/** + * gfs_lvb_sync - sync a LVB + * @gl: The glock in question + * + */ + +void +gfs_lvb_sync(struct gfs_glock *gl) +{ + if (gfs_assert_warn(gl->gl_sbd, atomic_read(&gl->gl_lvb_count))) + return; + + lock_on_glock(gl); + + if (!gfs_assert_warn(gl->gl_sbd, gfs_glock_is_held_excl(gl))) + gfs_lm_sync_lvb(gl->gl_sbd, gl->gl_lock, gl->gl_lvb); + + unlock_on_glock(gl); +} +#endif + +/** + * blocking_cb - + * @sdp: + * @name: + * @state: + * + */ + +void +blocking_cb(struct gfs_sbd *sdp, struct lm_lockname *name, unsigned int state) +{ + struct gfs_glock *gl; + + gl = gfs_glock_find(sdp, name); + if (!gl) + return; + + if (gl->gl_ops->go_callback) + gl->gl_ops->go_callback(gl, state); + handle_callback(gl, state); + + spin_lock(&gl->gl_spin); + run_queue(gl); + spin_unlock(&gl->gl_spin); + + glock_put(gl); +} + +/** + * gfs_glock_cb - Callback used by locking module + * @fsdata: Pointer to the superblock + * @type: Type of callback + * @data: Type dependent data pointer + * + * Called by the locking module when it wants to tell us something. + * Either we need to drop a lock, one of our ASYNC requests completed, or + * another client expired (crashed/died) and we need to recover its journal. + * If another node needs a lock held by this node, we queue a request to demote + * our lock to a state compatible with that needed by the other node. + * For example, if the other node needs EXCLUSIVE, we request UNLOCKED. + * SHARED and DEFERRED modes can be shared with other nodes, so we request + * accordingly. + * Once all incompatible holders on this node are done with the lock, the + * queued request will cause run_queue() to call the lock module to demote + * our lock to a compatible state, allowing the other node to grab the lock. + */ + +void +gfs_glock_cb(void *fsdata, unsigned int type, void *data) +{ + struct gfs_sbd *sdp = fsdata; + + atomic_inc(&sdp->sd_lm_callbacks); + + switch (type) { + case LM_CB_NEED_E: + blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_UNLOCKED); + return; + + case LM_CB_NEED_D: + blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_DEFERRED); + return; + + case LM_CB_NEED_S: + blocking_cb(sdp, (struct lm_lockname *)data, LM_ST_SHARED); + return; + + case LM_CB_ASYNC: { + struct lm_async_cb *async = (struct lm_async_cb *)data; + struct gfs_glock *gl; + + gl = gfs_glock_find(sdp, &async->lc_name); + if (gfs_assert_warn(sdp, gl)) + return; + if (!gfs_assert_warn(sdp, gl->gl_req_bh)) + gl->gl_req_bh(gl, async->lc_ret); + glock_put(gl); + + return; + } + + case LM_CB_NEED_RECOVERY: + gfs_add_dirty_j(sdp, *(unsigned int *)data); + if (sdp->sd_recoverd_process) + wake_up_process(sdp->sd_recoverd_process); + return; + + case LM_CB_DROPLOCKS: + gfs_gl_hash_clear(sdp, FALSE); + gfs_quota_scan(sdp); + return; + + default: + gfs_assert_warn(sdp, FALSE); + return; + } +} + +/** + * gfs_try_toss_inode - try to remove a particular GFS inode struct from cache + * sdp: the filesystem + * inum: the inode number + * + * Look for the glock protecting the inode of interest. + * If no process is manipulating or holding the glock, see if the glock + * has a gfs_inode attached. + * If gfs_inode has no references, unhold its iopen glock, release any + * indirect addressing buffers, and destroy the gfs_inode. + */ + +void +gfs_try_toss_inode(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_glock *gl; + struct gfs_inode *ip; + int error; + + error = gfs_glock_get(sdp, + inum->no_formal_ino, &gfs_inode_glops, + NO_CREATE, &gl); + if (error || !gl) + return; + + if (!trylock_on_glock(gl)) + goto out; + + if (!queue_empty(gl, &gl->gl_holders)) + goto out_unlock; + + ip = get_gl2ip(gl); + if (!ip) + goto out_unlock; + + if (atomic_read(&ip->i_count)) + goto out_unlock; + + gfs_inode_destroy(ip); + + out_unlock: + unlock_on_glock(gl); + + out: + glock_put(gl); +} + +/** + * gfs_iopen_go_callback - Try to kick the inode/vnode associated with an iopen glock from memory + * @io_gl: the iopen glock + * @state: the state into which the glock should be put + * + */ + +void +gfs_iopen_go_callback(struct gfs_glock *io_gl, unsigned int state) +{ + struct gfs_glock *i_gl; + struct gfs_inode *ip; + + if (state != LM_ST_UNLOCKED) + return; + + spin_lock(&io_gl->gl_spin); + i_gl = get_gl2gl(io_gl); + if (i_gl) { + glock_hold(i_gl); + spin_unlock(&io_gl->gl_spin); + } else { + spin_unlock(&io_gl->gl_spin); + return; + } + + if (trylock_on_glock(i_gl)) { + if (queue_empty(i_gl, &i_gl->gl_holders)) { + ip = get_gl2ip(i_gl); + if (ip) { + gfs_try_toss_vnode(ip); + unlock_on_glock(i_gl); + gfs_glock_schedule_for_reclaim(i_gl); + goto out; + } + } + unlock_on_glock(i_gl); + } + + out: + glock_put(i_gl); +} + +/** + * demote_ok - Check to see if it's ok to unlock a glock (to remove it + * from glock cache) + * @gl: the glock + * + * Called when trying to reclaim glocks, once it's determined that the glock + * has no holders on this node. + * + * Returns: TRUE if it's ok + * + * It's not okay if: + * -- glock is STICKY + * -- PREFETCHed glock has not been given enough chance to be used + * -- glock-type-specific test says "no" + */ + +static int +demote_ok(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock_operations *glops = gl->gl_ops; + int demote = TRUE; + + if (test_bit(GLF_STICKY, &gl->gl_flags)) + demote = FALSE; + else if (test_bit(GLF_PREFETCH, &gl->gl_flags)) + demote = time_after_eq(jiffies, + gl->gl_stamp + + gfs_tune_get(sdp, gt_prefetch_secs) * HZ); + else if (glops->go_demote_ok) + demote = glops->go_demote_ok(gl); + + return demote; +} + +/** + * gfs_glock_schedule_for_reclaim - Add a glock to the reclaim list + * @gl: the glock + * + */ + +void +gfs_glock_schedule_for_reclaim(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + + spin_lock(&sdp->sd_reclaim_lock); + if (list_empty(&gl->gl_reclaim)) { + glock_hold(gl); + list_add(&gl->gl_reclaim, &sdp->sd_reclaim_list); + atomic_inc(&sdp->sd_reclaim_count); + } + spin_unlock(&sdp->sd_reclaim_lock); + + wake_up(&sdp->sd_reclaim_wchan); +} + +/** + * gfs_reclaim_glock - process the next glock on the filesystem's reclaim list + * @sdp: the filesystem + * + * Called from gfs_glockd() glock reclaim daemon, or when promoting a + * (different) glock and we notice that there are a lot of glocks in the + * reclaim list. + * + * Remove glock from filesystem's reclaim list, update reclaim statistics. + * If no holders (might have gotten added since glock was placed on reclaim + * list): + * -- Destroy any now-unused inode protected by glock + * (and release hold on iopen glock). + * -- Ask for demote to UNLOCKED to enable removal of glock from glock cache. + * + * If no further interest in glock struct, remove it from glock cache, and + * free it from memory. (During normal operation, this is the only place + * that this is done). + * + * Glock-type-specific considerations for permission to demote are handled + * in demote_ok(). This includes how long to retain a glock in cache after it + * is no longer held by any process. + */ + +void +gfs_reclaim_glock(struct gfs_sbd *sdp) +{ + struct gfs_glock *gl; + struct gfs_gl_hash_bucket *bucket; + + spin_lock(&sdp->sd_reclaim_lock); + + /* Nothing to reclaim? Done! */ + if (list_empty(&sdp->sd_reclaim_list)) { + spin_unlock(&sdp->sd_reclaim_lock); + return; + } + + /* Remove next victim from reclaim list */ + gl = list_entry(sdp->sd_reclaim_list.next, + struct gfs_glock, gl_reclaim); + list_del_init(&gl->gl_reclaim); + + spin_unlock(&sdp->sd_reclaim_lock); + + atomic_dec(&sdp->sd_reclaim_count); + atomic_inc(&sdp->sd_reclaimed); + + if (trylock_on_glock(gl)) { + if (queue_empty(gl, &gl->gl_holders)) { + /* Inode glock-type-specific; free unused gfs inode, + and release hold on iopen glock */ + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + if (ip && !atomic_read(&ip->i_count)) + gfs_inode_destroy(ip); + } + /* Generic (including inodes); try to unlock glock */ + if (gl->gl_state != LM_ST_UNLOCKED && + demote_ok(gl)) + handle_callback(gl, LM_ST_UNLOCKED); + } + unlock_on_glock(gl); + } + + bucket = gl->gl_bucket; + + /* If glock struct's only remaining reference is from being put on + the reclaim list, remove glock from hash table (sd_gl_hash), + and free the glock's memory */ + write_lock(&bucket->hb_lock); + if (atomic_read(&gl->gl_count) == 1) { + list_del_init(&gl->gl_list); + write_unlock(&bucket->hb_lock); + glock_free(gl); + } else { + write_unlock(&bucket->hb_lock); + glock_put(gl); /* see gfs_glock_schedule_for_reclaim() */ + } +} + +/** + * examine_bucket - Call a function for glock in a hash bucket + * @examiner: the function + * @sdp: the filesystem + * @bucket: the bucket + * + * Returns: TRUE if the bucket has entries + */ + +static int +examine_bucket(glock_examiner examiner, + struct gfs_sbd *sdp, struct gfs_gl_hash_bucket *bucket, + unsigned int *purge_nr) +{ + struct glock_plug plug; + struct list_head *tmp; + struct gfs_glock *gl; + int entries; + + /* Add "plug" to end of bucket list, work back up list from there */ + memset(&plug.gl_flags, 0, sizeof(unsigned long)); + set_bit(GLF_PLUG, &plug.gl_flags); + + write_lock(&bucket->hb_lock); + list_add(&plug.gl_list, &bucket->hb_list); + write_unlock(&bucket->hb_lock); + + /* Look at each bucket entry */ + for (;;) { + write_lock(&bucket->hb_lock); + + /* Work back up list from plug */ + for (;;) { + tmp = plug.gl_list.next; + + /* Top of list; we're done */ + if (tmp == &bucket->hb_list) { + list_del(&plug.gl_list); + entries = !list_empty(&bucket->hb_list); + write_unlock(&bucket->hb_lock); + return entries; + } + gl = list_entry(tmp, struct gfs_glock, gl_list); + + /* Move plug up list */ + list_move(&plug.gl_list, &gl->gl_list); + + if (test_bit(GLF_PLUG, &gl->gl_flags)) + continue; + + /* glock_hold; examiner must glock_put() */ + atomic_inc(&gl->gl_count); + + break; + } + + write_unlock(&bucket->hb_lock); + + examiner(gl, purge_nr); + } +} + +static void +try_purge_iopen(struct gfs_glock *gl, unsigned int *p_count) +{ + struct gfs_glock *i_gl; + + if (*p_count == 0) + return; + + /* find the associated inode glock */ + i_gl = get_gl2gl(gl); + if (!i_gl) + return; + + /* + * If the associated inode glock has been in unlocked + * state, try to purge it. + */ + if (trylock_on_glock(i_gl)) { + if (i_gl->gl_state == LM_ST_UNLOCKED) { + *p_count = *p_count - 1; + unlock_on_glock(i_gl); + atomic_inc(&gl->gl_count); + gfs_iopen_go_callback(gl, LM_ST_UNLOCKED); + handle_callback(gl, LM_ST_UNLOCKED); + spin_lock(&gl->gl_spin); + run_queue(gl); + spin_unlock(&gl->gl_spin); + glock_put(gl); + } else + unlock_on_glock(i_gl); + } + + return; +} + +/** + * scan_glock - look at a glock and see if we can reclaim it + * @gl: the glock to look at + * + * Called via examine_bucket() when trying to release glocks from glock cache, + * during normal operation (i.e. not unmount time). + * + * Place glock on filesystem's reclaim list if, on this node: + * -- No process is manipulating glock struct, and + * -- No current holders, and either: + * -- GFS incore inode, protected by glock, is no longer in use, or + * -- Glock-type-specific demote_ok glops gives permission + */ + +static void +scan_glock(struct gfs_glock *gl, unsigned int *p_count) +{ + if (trylock_on_glock(gl)) { + if (queue_empty(gl, &gl->gl_holders)) { + /* Inode glock-type-specific; reclaim glock if gfs inode + no longer in use. */ + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + if (ip && !atomic_read(&ip->i_count)) { + unlock_on_glock(gl); + gfs_glock_schedule_for_reclaim(gl); + goto out; + } + } + /* Generic (including inodes not scheduled above) */ + if (gl->gl_state != LM_ST_UNLOCKED && + demote_ok(gl)) { + unlock_on_glock(gl); + gfs_glock_schedule_for_reclaim(gl); + goto out; + } + } + /* iopen always has holder(s) */ + if (gl->gl_name.ln_type == LM_TYPE_IOPEN) { + unlock_on_glock(gl); + try_purge_iopen(gl, p_count); + goto out; + } + unlock_on_glock(gl); + } + + out: + glock_put(gl); /* see examine_bucket() */ +} + +/** + * gfs_scand_internal - Look for glocks and inodes to toss from memory + * @sdp: the filesystem + * + * Invokes scan_glock() for each glock in each cache bucket. + * + * Steps of reclaiming a glock: + * -- scan_glock() places eligible glocks on filesystem's reclaim list. + * -- gfs_reclaim_glock() processes list members, attaches demotion requests + * to wait queues of glocks still locked at inter-node scope. + * -- Demote to UNLOCKED state (if not already unlocked). + * -- gfs_reclaim_lock() cleans up glock structure. + */ + +void +gfs_scand_internal(struct gfs_sbd *sdp) +{ + unsigned int x, purge_nr; + + if (!sdp->sd_tune.gt_glock_purge) + purge_nr = 0; + else + purge_nr = atomic_read(&sdp->sd_glock_count) * + sdp->sd_tune.gt_glock_purge / 100; + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) { + examine_bucket(scan_glock, sdp, &sdp->sd_gl_hash[x], &purge_nr); + cond_resched(); + } +} + +/** + * clear_glock - look at a glock and see if we can free it from glock cache + * @gl: the glock to look at + * + * Called via examine_bucket() when unmounting the filesystem, or + * when inter-node lock manager requests DROPLOCKS because it is running + * out of capacity. + * + * Similar to gfs_reclaim_glock(), except does *not*: + * -- Consult demote_ok() for permission + * -- Increment sdp->sd_reclaimed statistic + * + */ + +static void +clear_glock(struct gfs_glock *gl, unsigned int *unused) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_gl_hash_bucket *bucket = gl->gl_bucket; + + spin_lock(&sdp->sd_reclaim_lock); + if (!list_empty(&gl->gl_reclaim)) { + list_del_init(&gl->gl_reclaim); + atomic_dec(&sdp->sd_reclaim_count); + glock_put(gl); /* see gfs_glock_schedule_for_reclaim() */ + } + spin_unlock(&sdp->sd_reclaim_lock); + + if (trylock_on_glock(gl)) { + if (queue_empty(gl, &gl->gl_holders)) { + /* Inode glock-type-specific; free unused gfs inode, + and release hold on iopen glock */ + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + if (ip && !atomic_read(&ip->i_count)) + gfs_inode_destroy(ip); + } + /* Generic (including inodes); unlock glock */ + if (gl->gl_state != LM_ST_UNLOCKED) + handle_callback(gl, LM_ST_UNLOCKED); + } + + unlock_on_glock(gl); + } + + /* If glock struct's only remaining reference is from examine_bucket(), + remove glock from hash table (sd_gl_hash), and free glock's memory */ + write_lock(&bucket->hb_lock); + if (atomic_read(&gl->gl_count) == 1) { + list_del_init(&gl->gl_list); + write_unlock(&bucket->hb_lock); + glock_free(gl); + } else { + write_unlock(&bucket->hb_lock); + glock_put(gl); /* see examine_bucket() */ + } +} + +/** + * gfs_gl_hash_clear - Empty out the glock hash table + * @sdp: the filesystem + * @wait: wait until it's all gone + * + * Called when unmounting the filesystem, or when inter-node lock manager + * requests DROPLOCKS because it is running out of capacity. + */ + +void +gfs_gl_hash_clear(struct gfs_sbd *sdp, int wait) +{ + unsigned long t; + unsigned int x; + int cont; + + t = jiffies; + + for (;;) { + cont = FALSE; + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) + if (examine_bucket(clear_glock, sdp, &sdp->sd_gl_hash[x], 0)) + cont = TRUE; + + if (!wait || !cont) + break; + + if (time_after_eq(jiffies, t + gfs_tune_get(sdp, gt_stall_secs) * HZ)) { + printk("GFS: fsid=%s: Unmount seems to be stalled. Dumping lock state...\n", + sdp->sd_fsname); + gfs_dump_lockstate(sdp, NULL); + t = jiffies; + } + + invalidate_inodes(sdp->sd_vfs); + schedule_timeout_interruptible(HZ / 10); + } +} + +/* + * Diagnostic routines to help debug distributed deadlock + */ + +/** + * dump_holder - print information about a glock holder + * @str: a string naming the type of holder + * @gh: the glock holder + * @buf: the buffer + * @size: the size of the buffer + * @count: where we are in the buffer + * + * Returns: 0 on success, -ENOBUFS when we run out of space + */ + +static int +dump_holder(char *str, struct gfs_holder *gh, + char *buf, unsigned int size, unsigned int *count) +{ + unsigned int x; + int error = -ENOBUFS; + + gfs_printf(" %s\n", str); + gfs_printf(" owner = %ld\n", + (gh->gh_owner) ? (long)gh->gh_owner->pid : -1); + gfs_printf(" gh_state = %u\n", gh->gh_state); + gfs_printf(" gh_flags ="); + for (x = 0; x < 32; x++) + if (gh->gh_flags & (1 << x)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + gfs_printf(" error = %d\n", gh->gh_error); + gfs_printf(" gh_iflags ="); + for (x = 0; x < 32; x++) + if (test_bit(x, &gh->gh_iflags)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + + error = 0; + + out: + return error; +} + +/** + * dump_inode - print information about an inode + * @ip: the inode + * @buf: the buffer + * @size: the size of the buffer + * @count: where we are in the buffer + * + * Returns: 0 on success, -ENOBUFS when we run out of space + */ + +static int +dump_inode(struct gfs_inode *ip, + char *buf, unsigned int size, unsigned int *count) +{ + unsigned int x; + int error = -ENOBUFS; + + gfs_printf(" Inode:\n"); + gfs_printf(" num = %" PRIu64 "/%" PRIu64 "\n", + ip->i_num.no_formal_ino, ip->i_num.no_addr); + gfs_printf(" type = %u\n", ip->i_di.di_type); + gfs_printf(" i_count = %d\n", atomic_read(&ip->i_count)); + gfs_printf(" i_flags ="); + for (x = 0; x < 32; x++) + if (test_bit(x, &ip->i_flags)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + gfs_printf(" vnode = %s\n", (ip->i_vnode) ? "yes" : "no"); + + error = 0; + + out: + return error; +} + +/** + * dump_glock - print information about a glock + * @gl: the glock + * @buf: the buffer + * @size: the size of the buffer + * @count: where we are in the buffer + * + * Returns: 0 on success, -ENOBUFS when we run out of space + */ + +static int +dump_glock(struct gfs_glock *gl, + char *buf, unsigned int size, unsigned int *count) +{ + struct list_head *head, *tmp; + struct gfs_holder *gh; + unsigned int x; + int error = -ENOBUFS; + + spin_lock(&gl->gl_spin); + + gfs_printf("Glock (%u, %" PRIu64 ")\n", + gl->gl_name.ln_type, + gl->gl_name.ln_number); + gfs_printf(" gl_flags ="); + for (x = 0; x < 32; x++) + if (test_bit(x, &gl->gl_flags)) + gfs_printf(" %u", x); + gfs_printf(" \n"); + gfs_printf(" gl_count = %d\n", atomic_read(&gl->gl_count)); + gfs_printf(" gl_state = %u\n", gl->gl_state); + gfs_printf(" req_gh = %s\n", (gl->gl_req_gh) ? "yes" : "no"); + gfs_printf(" req_bh = %s\n", (gl->gl_req_bh) ? "yes" : "no"); + gfs_printf(" lvb_count = %d\n", atomic_read(&gl->gl_lvb_count)); + gfs_printf(" object = %s\n", (gl->gl_object) ? "yes" : "no"); + gfs_printf(" new_le = %s\n", (gl->gl_new_le.le_trans) ? "yes" : "no"); + gfs_printf(" incore_le = %s\n", (gl->gl_incore_le.le_trans) ? "yes" : "no"); + gfs_printf(" reclaim = %s\n", + (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); + if (gl->gl_aspace) + gfs_printf(" aspace = %lu\n", + gl->gl_aspace->i_mapping->nrpages); + else + gfs_printf(" aspace = no\n"); + gfs_printf(" ail_bufs = %s\n", + (list_empty(&gl->gl_ail_bufs)) ? "no" : "yes"); + if (gl->gl_req_gh) { + error = dump_holder("Request", gl->gl_req_gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_holders, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Holder", gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_waiters1, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Waiter1", gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_waiters2, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Waiter2", gh, buf, size, count); + if (error) + goto out; + } + for (head = &gl->gl_waiters3, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + error = dump_holder("Waiter3", gh, buf, size, count); + if (error) + goto out; + } + if (gl->gl_ops == &gfs_inode_glops && get_gl2ip(gl)) { + if (!test_bit(GLF_LOCK, &gl->gl_flags) && + list_empty(&gl->gl_holders)) { + error = dump_inode(get_gl2ip(gl), buf, size, count); + if (error) + goto out; + } else { + error = -ENOBUFS; + gfs_printf(" Inode: busy\n"); + } + } + + error = 0; + + out: + spin_unlock(&gl->gl_spin); + + return error; +} + +/** + * gfs_dump_lockstate - print out the current lockstate + * @sdp: the filesystem + * @ub: the buffer to copy the information into + * + * If @ub is NULL, dump the lockstate to the console. + * + */ + +int +gfs_dump_lockstate(struct gfs_sbd *sdp, struct gfs_user_buffer *ub) +{ + struct gfs_gl_hash_bucket *bucket; + struct list_head *tmp, *head; + struct gfs_glock *gl; + char *buf = NULL; + unsigned int size = gfs_tune_get(sdp, gt_lockdump_size); + unsigned int x, count; + int error = 0; + + if (ub) { + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + } + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) { + bucket = &sdp->sd_gl_hash[x]; + count = 0; + + read_lock(&bucket->hb_lock); + + for (head = &bucket->hb_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gl = list_entry(tmp, struct gfs_glock, gl_list); + + if (test_bit(GLF_PLUG, &gl->gl_flags)) + continue; + + error = dump_glock(gl, buf, size, &count); + if (error) + break; + } + + read_unlock(&bucket->hb_lock); + + if (error) + break; + + if (ub) { + if (ub->ub_count + count > ub->ub_size) { + error = -ENOMEM; + break; + } + if (copy_to_user(ub->ub_data + ub->ub_count, buf, count)) { + error = -EFAULT; + break; + } + ub->ub_count += count; + } + } + + if (ub) + kfree(buf); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/quota.h +++ linux-2.6.28/ubuntu/gfs/quota.h @@ -0,0 +1,28 @@ +#ifndef __QUOTA_DOT_H__ +#define __QUOTA_DOT_H__ + +#define NO_QUOTA_CHANGE ((uint32_t)-1) + +int gfs_quota_get(struct gfs_sbd *sdp, int user, uint32_t id, int create, + struct gfs_quota_data **qdp); +void gfs_quota_hold(struct gfs_sbd *sdp, struct gfs_quota_data *qd); +void gfs_quota_put(struct gfs_sbd *sdp, struct gfs_quota_data *qd); + +int gfs_quota_merge(struct gfs_sbd *sdp, struct gfs_quota_tag *tag); +void gfs_quota_scan(struct gfs_sbd *sdp); +void gfs_quota_cleanup(struct gfs_sbd *sdp); + +int gfs_quota_hold_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid); +void gfs_quota_unhold_m(struct gfs_inode *ip); + +int gfs_quota_lock_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid); +void gfs_quota_unlock_m(struct gfs_inode *ip); + +int gfs_quota_check(struct gfs_inode *ip, uint32_t uid, uint32_t gid); + +int gfs_quota_sync(struct gfs_sbd *sdp); +int gfs_quota_refresh(struct gfs_sbd *sdp, int user, uint32_t id); +int gfs_quota_read(struct gfs_sbd *sdp, int user, uint32_t id, + struct gfs_quota *q); + +#endif /* __QUOTA_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/unlinked.c +++ linux-2.6.28/ubuntu/gfs/unlinked.c @@ -0,0 +1,432 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "inode.h" +#include "log.h" +#include "lops.h" +#include "unlinked.h" + +/** + * gfs_unlinked_get - Get a structure to represent an unlinked inode + * @sdp: the filesystem + * @inum: identifies the inode that's unlinked + * @create: if TRUE, we're allowed to create the structure if we can't find it, + * otherwise return NULL + * + * Returns: the structure, or NULL + * + * Search the filesystem's list of gfs_unlinked to find a match. + * If none found, create a new one and place on list. + */ + +struct gfs_unlinked * +gfs_unlinked_get(struct gfs_sbd *sdp, struct gfs_inum *inum, int create) +{ + struct gfs_unlinked *ul = NULL, *new_ul = NULL; + struct list_head *tmp, *head; + + for (;;) { + spin_lock(&sdp->sd_unlinked_lock); + + for (head = &sdp->sd_unlinked_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + ul = list_entry(tmp, struct gfs_unlinked, ul_list); + if (gfs_inum_equal(&ul->ul_inum, inum)) { + ul->ul_count++; + break; + } + } + + if (tmp == head) + ul = NULL; + + /* 2nd pass, still not there; add the new_ul we prepared */ + if (!ul && new_ul) { + ul = new_ul; + list_add(&ul->ul_list, &sdp->sd_unlinked_list); + new_ul = NULL; + } + + spin_unlock(&sdp->sd_unlinked_lock); + + /* 1st pass; we found pre-existing, OR not allowed to create. + 2nd pass; another process added it, or we did */ + if (ul || !create) { + if (new_ul) + /* someone beat us to it; forget our new_ul */ + kfree(new_ul); + return ul; + } + + /* No match on list, 1st time through loop. + Prepare new_ul, then repeat loop to find out if another + process has created or unlinked an inode and put its + gfs_unlinked on list while we've been preparing this one. */ + new_ul = gmalloc(sizeof(struct gfs_unlinked)); + memset(new_ul, 0, sizeof(struct gfs_unlinked)); + + new_ul->ul_count = 1; + new_ul->ul_inum = *inum; + + INIT_LE(&new_ul->ul_new_le, &gfs_unlinked_lops); + INIT_LE(&new_ul->ul_incore_le, &gfs_unlinked_lops); + INIT_LE(&new_ul->ul_ondisk_le, &gfs_unlinked_lops); + } +} + +/** + * gfs_unlinked_hold - increment the usage count on a struct gfs_unlinked + * @sdp: the filesystem + * @ul: the structure + * + */ + +void +gfs_unlinked_hold(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + gfs_assert(sdp, ul->ul_count,); + ul->ul_count++; + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * gfs_unlinked_put - decrement the usage count on a struct gfs_unlinked + * @sdp: the filesystem + * @ul: the structure + * + * Free the structure if its reference count hits zero. + * + */ + +void +gfs_unlinked_put(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + + gfs_assert(sdp, ul->ul_count,); + ul->ul_count--; + + if (!ul->ul_count) { + gfs_assert_warn(sdp, + !test_bit(ULF_IC_LIST, &ul->ul_flags) && + !test_bit(ULF_OD_LIST, &ul->ul_flags) && + !test_bit(ULF_LOCK, &ul->ul_flags)); + list_del(&ul->ul_list); + spin_unlock(&sdp->sd_unlinked_lock); + kfree(ul); + } else + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * unlinked_find - Find a inode to try to deallocate + * @sdp: the filesystem + * + * The returned structure is locked and needs to be unlocked + * with gfs_unlinked_unlock(). + * + * Returns: A unlinked structure, or NULL + */ + +struct gfs_unlinked * +unlinked_find(struct gfs_sbd *sdp) +{ + struct list_head *tmp, *head; + struct gfs_unlinked *ul = NULL; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) + return NULL; + + gfs_log_lock(sdp); + spin_lock(&sdp->sd_unlinked_lock); + + if (!atomic_read(&sdp->sd_unlinked_ic_count)) + goto out; + + for (head = &sdp->sd_unlinked_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + ul = list_entry(tmp, struct gfs_unlinked, ul_list); + + if (test_bit(ULF_LOCK, &ul->ul_flags)) + continue; + if (!test_bit(ULF_IC_LIST, &ul->ul_flags)) + continue; + + list_move_tail(&ul->ul_list, &sdp->sd_unlinked_list); + + set_bit(ULF_LOCK, &ul->ul_flags); + ul->ul_count++; + + goto out; + } + + ul = NULL; + + out: + spin_unlock(&sdp->sd_unlinked_lock); + gfs_log_unlock(sdp); + + return ul; +} + +/** + * gfs_unlinked_lock - lock a unlinked structure + * @sdp: the filesystem + * @ul: the unlinked inode structure + * + */ + +void +gfs_unlinked_lock(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + + gfs_assert_warn(sdp, !test_bit(ULF_LOCK, &ul->ul_flags)); + set_bit(ULF_LOCK, &ul->ul_flags); + + ul->ul_count++; + + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * gfs_unlinked_unlock - drop a reference on a unlinked structure + * @sdp: the filesystem + * @ul: the unlinked inode structure + * + */ + +void +gfs_unlinked_unlock(struct gfs_sbd *sdp, struct gfs_unlinked *ul) +{ + spin_lock(&sdp->sd_unlinked_lock); + + gfs_assert_warn(sdp, test_bit(ULF_LOCK, &ul->ul_flags)); + clear_bit(ULF_LOCK, &ul->ul_flags); + + gfs_assert(sdp, ul->ul_count,); + ul->ul_count--; + + if (!ul->ul_count) { + gfs_assert_warn(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags) && + !test_bit(ULF_OD_LIST, &ul->ul_flags)); + list_del(&ul->ul_list); + spin_unlock(&sdp->sd_unlinked_lock); + kfree(ul); + } else + spin_unlock(&sdp->sd_unlinked_lock); +} + +/** + * gfs_unlinked_merge - add/remove a unlinked inode from the in-memory list + * @sdp: the filesystem + * @type: is this a unlink tag or a dealloc tag + * @inum: the inode number + * + * Called during journal recovery. + */ + +void +gfs_unlinked_merge(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum) +{ + struct gfs_unlinked *ul; + + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) == + atomic_read(&sdp->sd_unlinked_od_count),); + + ul = gfs_unlinked_get(sdp, inum, CREATE); + + gfs_log_lock(sdp); + + switch (type) { + case GFS_LOG_DESC_IUL: + gfs_unlinked_hold(sdp, ul); + gfs_unlinked_hold(sdp, ul); + gfs_assert(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags) && + !test_bit(ULF_OD_LIST, &ul->ul_flags),); + set_bit(ULF_IC_LIST, &ul->ul_flags); + set_bit(ULF_OD_LIST, &ul->ul_flags); + atomic_inc(&sdp->sd_unlinked_ic_count); + atomic_inc(&sdp->sd_unlinked_od_count); + + break; + + case GFS_LOG_DESC_IDA: + gfs_assert(sdp, test_bit(ULF_IC_LIST, &ul->ul_flags) && + test_bit(ULF_OD_LIST, &ul->ul_flags),); + clear_bit(ULF_IC_LIST, &ul->ul_flags); + clear_bit(ULF_OD_LIST, &ul->ul_flags); + gfs_unlinked_put(sdp, ul); + gfs_unlinked_put(sdp, ul); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) > 0,); + atomic_dec(&sdp->sd_unlinked_ic_count); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_od_count) > 0,); + atomic_dec(&sdp->sd_unlinked_od_count); + + break; + } + + gfs_log_unlock(sdp); + + gfs_unlinked_put(sdp, ul); +} + +/** + * gfs_unlinked_cleanup - get rid of any extra struct gfs_unlinked structures + * @sdp: the filesystem + * + */ + +void +gfs_unlinked_cleanup(struct gfs_sbd *sdp) +{ + struct gfs_unlinked *ul; + + restart: + gfs_log_lock(sdp); + + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count) == + atomic_read(&sdp->sd_unlinked_od_count),); + + spin_lock(&sdp->sd_unlinked_lock); + + while (!list_empty(&sdp->sd_unlinked_list)) { + ul = list_entry(sdp->sd_unlinked_list.next, + struct gfs_unlinked, ul_list); + + if (ul->ul_count > 2) { + spin_unlock(&sdp->sd_unlinked_lock); + gfs_log_unlock(sdp); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto restart; + } + gfs_assert(sdp, ul->ul_count == 2,); + + gfs_assert_warn(sdp, + test_bit(ULF_IC_LIST, &ul->ul_flags) && + test_bit(ULF_OD_LIST, &ul->ul_flags) && + !test_bit(ULF_LOCK, &ul->ul_flags)); + + list_del(&ul->ul_list); + + atomic_dec(&sdp->sd_unlinked_ic_count); + atomic_dec(&sdp->sd_unlinked_od_count); + + spin_unlock(&sdp->sd_unlinked_lock); + kfree(ul); + spin_lock(&sdp->sd_unlinked_lock); + } + + spin_unlock(&sdp->sd_unlinked_lock); + + gfs_assert(sdp, !atomic_read(&sdp->sd_unlinked_ic_count) && + !atomic_read(&sdp->sd_unlinked_od_count),); + + gfs_log_unlock(sdp); +} + +/** + * gfs_unlinked_limit - limit the number of inodes waiting to be deallocated + * @sdp: the filesystem + * + * Returns: errno + */ + +void +gfs_unlinked_limit(struct gfs_sbd *sdp) +{ + unsigned int tries = 0, min = 0; + int error; + + if (atomic_read(&sdp->sd_unlinked_ic_count) >= + gfs_tune_get(sdp, gt_ilimit2)) { + tries = gfs_tune_get(sdp, gt_ilimit2_tries); + min = gfs_tune_get(sdp, gt_ilimit2_min); + } else if (atomic_read(&sdp->sd_unlinked_ic_count) >= + gfs_tune_get(sdp, gt_ilimit1)) { + tries = gfs_tune_get(sdp, gt_ilimit1_tries); + min = gfs_tune_get(sdp, gt_ilimit1_min); + } + + while (tries--) { + struct gfs_unlinked *ul = unlinked_find(sdp); + if (!ul) + break; + + error = gfs_inode_dealloc(sdp, &ul->ul_inum); + + gfs_unlinked_unlock(sdp, ul); + + if (!error) { + if (!--min) + break; + } else if (error != 1) + break; + } +} + +/** + * gfs_unlinked_dealloc - Go through the list of inodes to be deallocated + * @sdp: the filesystem + * + * Returns: errno + */ + +void +gfs_unlinked_dealloc(struct gfs_sbd *sdp) +{ + unsigned int hits, strikes; + int error; + + for (;;) { + hits = 0; + strikes = 0; + + for (;;) { + struct gfs_unlinked *ul = unlinked_find(sdp); + if (!ul) + return; + + error = gfs_inode_dealloc(sdp, &ul->ul_inum); + + gfs_unlinked_unlock(sdp, ul); + + if (!error) { + hits++; + if (strikes) + strikes--; + } else if (error == 1) { + strikes++; + if (strikes >= atomic_read(&sdp->sd_unlinked_ic_count)) { + error = 0; + break; + } + } else + goto out; + } + + if (!hits || kthread_should_stop()) + break; + + cond_resched(); + } + + out: + if (error && + error != -EROFS && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + printk("GFS: fsid=%s: error deallocating inodes: %d\n", + sdp->sd_fsname, error); +} --- linux-2.6.28.orig/ubuntu/gfs/incore.h +++ linux-2.6.28/ubuntu/gfs/incore.h @@ -0,0 +1,1207 @@ +/* + * In-core (memory/RAM) structures. + * These do not appear on-disk. See gfs_ondisk.h for on-disk structures. + */ + +#ifndef __INCORE_DOT_H__ +#define __INCORE_DOT_H__ + +/* flags used in function call parameters */ + +#define DIO_NEW (0x00000001) /* Newly allocated metadata */ +#define DIO_FORCE (0x00000002) /* Force read of block from disk */ +#define DIO_CLEAN (0x00000004) /* Don't write to disk */ +#define DIO_DIRTY (0x00000008) /* Data changed, must write to disk */ +#define DIO_START (0x00000010) /* Start disk read or write */ +#define DIO_WAIT (0x00000020) /* Wait for disk r/w to complete */ + +#define DIO_METADATA (0x00000040) /* Process glock's protected metadata */ +#define DIO_DATA (0x00000080) /* Process glock's protected filedata */ +#define DIO_INVISIBLE (0x00000100) /* Don't monkey with glock's dirty bit */ +#define DIO_CHECK (0x00000200) /* Make sure all metadata has been synced */ +#define DIO_ALL (0x00000400) /* Flush all AIL transactions to disk */ + +/* Structure prototypes */ + +struct gfs_log_operations; +struct gfs_log_element; +struct gfs_meta_header_cache; +struct gfs_depend; +struct gfs_bitmap; +struct gfs_rgrpd; +struct gfs_bufdata; +struct gfs_glock_operations; +struct gfs_holder; +struct gfs_glock; +struct gfs_alloc; +struct gfs_inode; +struct gfs_file; +struct gfs_unlinked; +struct gfs_quota_le; +struct gfs_quota_data; +struct gfs_log_buf; +struct gfs_trans; +struct gfs_gl_hash_bucket; +struct gfs_sbd; + +typedef void (*gfs_glop_bh_t) (struct gfs_glock * gl, unsigned int ret); + +/* + * Structure of operations that are associated with each + * type of element in the log. + */ +struct gfs_log_operations { + /* + * Operations specific to a given log element (LE). + * These are typically executed individually via macros such as LO_ADD. + */ + + /* Add new LE to transaction */ + void (*lo_add) (struct gfs_sbd * sdp, struct gfs_log_element * le); + + /* Do any cleanup, etc., needed just before commit to incore log */ + void (*lo_trans_end) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* Print LE-specific info via printk() */ + void (*lo_print) (struct gfs_sbd * sdp, struct gfs_log_element * le, + unsigned int where); + + /* Find any incore transactions that overlap through this LE (e.g. + * share glocks), to determine if any transactions can be combined. */ + struct gfs_trans *(*lo_overlap_trans) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* Change LE from "new" to "incore" status, before write to log */ + void (*lo_incore_commit) (struct gfs_sbd * sdp, struct gfs_trans * tr, + struct gfs_log_element * le); + + /* Allow writes to in-place locations, after log is on-disk */ + void (*lo_add_to_ail) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* Clean up LE after log dump */ + void (*lo_clean_dump) (struct gfs_sbd * sdp, + struct gfs_log_element * le); + + /* + * Operations specific to a class of log elements. + * These are typically executed over a whole transaction by + * macros such as LO_TRANS_SIZE. Each LE-type-specific operation + * for each LE contributes its part to the overall result. + */ + + /* Determine LE-type-specific quantities of blocks of various types + * required for writing the log */ + void (*lo_trans_size) (struct gfs_sbd * sdp, struct gfs_trans * tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem); + + /* Combine LE-type-specific values in new_tr and tr, result is in tr */ + void (*lo_trans_combine) (struct gfs_sbd * sdp, struct gfs_trans * tr, + struct gfs_trans * new_tr); + + /* Create control and metadata buffers that will make up the log */ + void (*lo_build_bhlist) (struct gfs_sbd * sdp, struct gfs_trans * tr); + + /* Calculate log space needed for this LE in a log dump */ + void (*lo_dump_size) (struct gfs_sbd * sdp, unsigned int *elements, + unsigned int *blocks, unsigned int *bmem); + + /* Add LE to log dump */ + void (*lo_build_dump) (struct gfs_sbd * sdp, struct gfs_trans * tr); + + /* + * Operations that happen at recovery time + */ + + /* Reset/init whatever before doing recovery */ + void (*lo_before_scan) (struct gfs_sbd * sdp, unsigned int jid, + struct gfs_log_header * head, + unsigned int pass); + + /* LE-specific recovery procedure */ + int (*lo_scan_elements) (struct gfs_sbd * sdp, + struct gfs_jindex * jdesc, + struct gfs_glock * gl, uint64_t start, + struct gfs_log_descriptor * desc, + unsigned int pass); + + /* Verify and report recovery results/statistics */ + void (*lo_after_scan) (struct gfs_sbd * sdp, unsigned int jid, + unsigned int pass); + + + /* + * Type of element (glock/buf/unlinked/quota) + */ + char *lo_name; +}; + +/* + * Structure that gets added to struct gfs_trans->tr_elements. They + * make up the "stuff" in each transaction. + */ +struct gfs_log_element { + struct gfs_log_operations *le_ops; /* Vector of functions */ + + struct gfs_trans *le_trans; /* We're part of this transaction */ + struct list_head le_list; /* Link to transaction's element list */ +}; + +/* + * Meta-header cache structure. + * One for each metadata block that we've de-allocated. + * Used to temporarily store gfs_meta_header structs for meta blocks that + * have been freshly turned into FREEMETA (alloc'd or de-alloc'd). Storing + * these (small) structures in-core allows us to release the (large) buffers, + * and not need to re-read the header from disk if/when we re-allocate the + * blocks to USEDMETA, as long as this node holds the EXCLUSIVE lock for the + * resource group containing the blocks. If we release the EX lock, we must + * throw away the rgrp's cached meta headers, since another node could change + * the blocks' contents. + * In-core superblock structure hosts the hashed cache, as well as a + * linear list of all cached, in most-recently-added order. + * Also, each resource group keeps a list of cached blocks within its scope. + */ +struct gfs_meta_header_cache { + /* Links to various lists */ + struct list_head mc_list_hash; /* Superblock's hashed list */ + struct list_head mc_list_single; /* Superblock's list, MRU order */ + struct list_head mc_list_rgd; /* Resource group's list */ + + uint64_t mc_block; /* Block # (in-place address) */ + struct gfs_meta_header mc_mh; /* Payload: the block's meta-header */ +}; + +/* + * Dependency cache structure. + * In-core superblock structure hosts the actual cache. + * Also, each resource group keeps a list of dependency blocks within its scope. + */ +struct gfs_depend { + /* Links to various lists */ + struct list_head gd_list_hash; /* Superblock's hashed list */ + struct list_head gd_list_rgd; /* Resource group's list */ + + struct gfs_rgrpd *gd_rgd; /* Resource group descriptor */ + uint64_t gd_formal_ino; /* Inode ID */ + unsigned long gd_time; /* Time (jiffies) when put on list */ +}; + +/* + * Block allocation bitmap descriptor structure. + * One of these for each FS block that contains bitmap data + * (i.e. the resource group header blocks and their following bitmap blocks). + * Each allocatable FS data block is represented by 2 bits (4 alloc states). + */ +struct gfs_bitmap { + uint32_t bi_offset; /* Byte offset of bitmap within this bit block + (non-zero only for an rgrp header block) */ + uint32_t bi_start; /* Data block (rgrp scope, 32-bit) represented + by the first bit-pair in this bit block */ + uint32_t bi_len; /* The number of bitmap bytes in this bit block */ +}; + +/* + * Resource Group (Rgrp) descriptor structure. + * There is one of these for each resource (block) group in the FS. + * The filesystem is divided into a number of resource groups to allow + * simultaneous block alloc operations by a number of nodes. + */ +struct gfs_rgrpd { + /* Links to superblock lists */ + struct list_head rd_list; /* On-disk-order list of all rgrps */ + struct list_head rd_list_mru; /* Most Recently Used list of all rgs */ + struct list_head rd_recent; /* recently used rgrps */ + uint32_t rd_try_counter; /* # of times we fail a try lock */ + + struct gfs_glock *rd_gl; /* Glock for this rgrp */ + + struct gfs_rindex rd_ri; /* Resource Index (on-disk) structure */ + struct gfs_rgrp rd_rg; /* Resource Group (on-disk) structure */ + uint64_t rd_rg_vn; /* Version #: if != glock's gl_vn, + we need to read rgrp fm disk */ + + /* Block alloc bitmap cache */ + struct gfs_bitmap *rd_bits; /* Array of block bitmap descriptors */ + struct buffer_head **rd_bh; /* Array of ptrs to block bitmap bh's */ + + /* Block allocation strategy, rgrp scope. Start at these blocks when + searching for next data/meta block to alloc */ + uint32_t rd_last_alloc_data; /* Most recent data block allocated */ + uint32_t rd_last_alloc_meta; /* Most recent meta block allocated */ + + struct list_head rd_mhc; /* Cached meta-headers for this rgrp */ + struct list_head rd_depend; /* Dependent inodes (MRU order) */ + + struct gfs_sbd *rd_sbd; /* FS incore superblock (fs instance) */ +}; + +/* + * Per-buffer data + * One of these is attached as GFS private data to each FS block's buffer_head. + * These keep track of a buffer's progress through the transaction pipeline, + * using the "new" embedded log element to attach it to a being-built + * transaction, and moving the attachment point to the "incore" LE once + * the transaction completes (at which time the buffer becomes a candidate + * to be written to the on-disk log). + * A buffer may be attached simultaneously to a new and an incore transaction, + * but no more than one of each: Only one new trans may be built at a time + * for a given buffer, obviously, since the buffer's contents are protected + * by an EXclusive glock when writing. And, when a transaction is completely + * built, GFS combines incore transactions that share glocks (see + * incore_commit()), i.e. the glock that protects the buffer, so a buffer + * never needs to be attached to more than one (combined) incore trans. + * Note that multiple transactions can modify the buffer since its most + * recent writes to disk. This principle applies to both in-place and + * journal block locations on-disk, allowing this node to keep modifying the + * cached data without writing it to disk, unless/until another node needs + * to access the data, or the Linux OS tells us to sync to disk. + * If a transaction follows another transaction before the first transaction's + * log completes (indicated by the in-place buffer head still being pinned + * in RAM), GFS copies the first transaction's results to a "frozen" + * image of the buffer, so the first transaction results (an atomic + * snapshot) can be logged properly, while the second transaction is + * modifying the "real" buffer. This frozen copy lives only until the new + * transaction is complete, at which point one of two things has occurred: + * 1). Buffer was logged successfully; frozen copy's job is done. + * 2). Buffer was not yet logged; frozen copy no longer needed, newer + * buffer becomes the log candidate. + * + * gfs_bufdata structs also link into the Active Items Lists (AIL) (buffers + * flushed to on-disk log, but not yet flushed to on-disk in-place locations) + * attached to: + * 1). The latest transaction to modify and log (on-disk) the buffer, and + * 2). The glock that protects the buffer's contents. + * The buffer is attached to only the most recent transaction's AIL + * list for a couple of reasons. One is that only the most up-to-date + * buffer content needs to be written to the in-place block on-disk. The + * other is that since there is a more recent copy of the block in + * the log, we don't need to keep the older copies in the log. We can + * remove them from the AIL and let the log space be reused for new + * transactions (GFS advances the log tail when removing buffers from AIL). + */ +struct gfs_bufdata { + struct buffer_head *bd_bh; /* We belong to this Linux buffer_head */ + struct gfs_glock *bd_gl; /* This glock protects buffer's payload */ + + /* Log elements map us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element bd_new_le; /* New, incomplete transaction */ + struct gfs_log_element bd_incore_le; /* Complete (committed) trans */ + + char *bd_frozen; /* "Frozen" copy of buffer's data */ + struct semaphore bd_lock; /* Protects access to this structure */ + + /* "Pin" means keep buffer in RAM, don't write to disk (yet) */ + unsigned int bd_pinned; /* Recursive pin count */ + + /* Links to Active Items Lists */ + struct list_head bd_ail_tr_list; /* This buf's most recent trans' AIL */ + struct list_head bd_ail_gl_list; /* This buf's glock's AIL */ +}; + +/* + * Glock operations + * One set of operations for each glock, the set selected by type of glock. + * These functions get called at various points in a glock's lifetime. + * "xmote" = promote or demote (change lock state) a glock at inter-node scope. + * "th" = top half, "bh" = bottom half + * Some operations/fields are required (GFS assumes they are there): + * go_xmote_th + * go_drop_th + * go_type + * Other operations are optional (GFS checks for presence before calling). + */ +struct gfs_glock_operations { + + /* Acquire lock or change lock state at inter-node scope: + Does type-specific preparation (if any) + Uses gfs_glock_xmote_th to call lock module. */ + void (*go_xmote_th) (struct gfs_glock * gl, unsigned int state, + int flags); + + /* After acquiring or changing a lock at inter-node scope */ + void (*go_xmote_bh) (struct gfs_glock * gl); + + /* Release (unlock) a lock at inter-node scope: + Does type-specific preparation (if any) + Uses gfs_glock_drop_th to call lock module. */ + void (*go_drop_th) (struct gfs_glock * gl); + + /* After releasing a lock at inter-node scope */ + void (*go_drop_bh) (struct gfs_glock * gl); + + /* Sync dirty data to disk (e.g. before demoting an EX inter-node lock) + (another node needs to read the updated data from disk) */ + void (*go_sync) (struct gfs_glock * gl, int flags); + + /* Invalidate local cached data just after releasing an inter-node lock + (another node may change the on-disk data, so it's no good to us) */ + void (*go_inval) (struct gfs_glock * gl, int flags); + + /* Lock-type-specific check to see if it's okay to unlock a glock + at inter-node scope (and remove it from our glock cache) */ + int (*go_demote_ok) (struct gfs_glock * gl); + + /* After getting lock for first holder (within this node) */ + int (*go_lock) (struct gfs_glock * gl, int flags); + + /* After last holder (within this node) gives up lock (glock may + remain in glock cache, though) */ + void (*go_unlock) (struct gfs_glock * gl, int flags); + + /* After receiving a callback: another node needs the lock */ + void (*go_callback) (struct gfs_glock * gl, unsigned int state); + + /* Called when the glock layer marks a lock as being not greedy + anymore */ + void (*go_greedy) (struct gfs_glock * gl); + + /* Lock type: locks with same lock # (often an FS block #), + but different types, are different locks */ + int go_type; +}; + +/* + * Glock holder structure + * One for each holder of a glock. + * These coordinate the use, within this node, of an acquired inter-node glock. + * Once a node has acquired a glock, it may be shared within that node by + * several processes, or even by several recursive requests from the same + * process. Each is a separate "holder". Different holders may co-exist + * having requested different lock states, as long as the node holds the + * glock in a state that is compatible. A hold requestor may select, via + * flags, the rules by which sharing within the node is granted: + * LM_FLAG_ANY: Grant if glock state is any other than UNLOCKED. + * GL_EXACT: Grant only if glock state is exactly the requested state. + * GL_LOCAL_EXCL: Grant only one holder at a time within this node. + * With no flags, a hold will be granted to a SHARED request even if the + * node holds the glock in EXCLUSIVE mode. See relaxed_state_ok(). + * When a process needs to manipulate a lock, it requests it via one of + * these holder structures. If the request cannot be satisfied immediately, + * the holder structure gets queued on one of these lists in gfs_glock: + * 1) waiters1, for gaining exclusive access to the (local) glock structure. + * 2) waiters2, for demoting a lock (unlocking a glock, or changing its state + * to be less restrictive) or relenquishing "greedy" status. + * 3) waiters3, for promoting (locking a new glock, or changing a glock state + * to be more restrictive). + * When holding a lock, gfs_holder struct stays on glock's holder list. + * See gfs-kernel/src/harness/lm_interface.h for gh_state (LM_ST_...) + * and gh_flags (LM_FLAG...) fields. + * Also see glock.h for gh_flags field (GL_...) flags. + */ + +/* Action requests */ +#define HIF_MUTEX (0) /* Exclusive (local) access to glock struct */ +#define HIF_PROMOTE (1) /* Change lock to more restrictive state */ +#define HIF_DEMOTE (2) /* Change lock to less restrictive state */ +#define HIF_GREEDY (3) /* Wait for the glock to be unlocked */ + +/* States */ +#define HIF_ALLOCED (4) /* Holder structure is or was in use */ +#define HIF_DEALLOC (5) /* Toss holder struct as soon as queued request + * is satisfied */ +#define HIF_HOLDER (6) /* We have been granted a hold on the lock */ +#define HIF_FIRST (7) /* We are first holder to get the lock */ +#define HIF_RECURSE (8) /* >1 hold requests on same glock by same process*/ +#define HIF_ABORTED (9) /* Aborted before being submitted */ + +struct gfs_holder { + struct list_head gh_list; /* Link to one of glock's holder lists */ + + struct gfs_glock *gh_gl; /* Glock that we're holding */ + struct task_struct *gh_owner; /* Linux process that is the holder */ + + /* request to change lock state */ + unsigned int gh_state; /* LM_ST_... requested lock state */ + int gh_flags; /* GL_... or LM_FLAG_... req modifiers */ + + int gh_error; /* GLR_... CANCELLED/TRYFAILED/-errno */ + unsigned long gh_iflags; /* HIF_... holder state, see above */ + struct completion gh_wait; /* Wait for completion of ... */ +}; + +/* + * Glock Structure + * One for each inter-node lock held by this node. + * A glock is a local representation/abstraction of an inter-node lock. + * Inter-node locks are managed by a "lock module" (LM) which plugs in to + * the lock harness / glock interface (see gfs-kernel/harness). Different + * lock modules support different lock protocols (e.g. GULM, GDLM, no_lock). + * A glock may have one or more holders within a node. See gfs_holder above. + * Glocks are managed within a hash table hosted by the in-core superblock. + * After all holders have released a glock, it will stay in the hash table + * cache for a time (depending on lock type), during which the inter-node + * lock will not be released unless another node needs the lock (lock + * manager requests this via callback to GFS through LM on this node). This + * provides better performance in case this node needs the glock again soon. + * See comments for meta_go_demote_ok(), glops.c. + * Each glock has an associated vector of lock-type-specific "glops" functions + * which are called at important times during the life of a glock, and + * which define the type of lock (e.g. dinode, rgrp, non-disk, etc). + * See gfs_glock_operations above. + * A glock, at inter-node scope, is identified by the following dimensions: + * 1) lock number (usually a block # for on-disk protected entities, + * or a fixed assigned number for non-disk locks, e.g. MOUNT). + * 2) lock type (actually, the type of entity protected by the lock). + * 3) lock namespace, to support multiple GFS filesystems simultaneously. + * Namespace (usually cluster:filesystem) is specified when mounting. + * See man page for gfs_mount. + * Glocks require support of Lock Value Blocks (LVBs) by the inter-node lock + * manager. LVBs are small (32-byte) chunks of data associated with a given + * lock, that can be quickly shared between cluster nodes. Used for certain + * purposes such as sharing an rgroup's block usage statistics without + * requiring the overhead of: + * -- sync-to-disk by one node, then a + * -- read from disk by another node. + * + */ + +#define GLF_PLUG (0) /* Dummy */ +#define GLF_LOCK (1) /* Exclusive (local) access to glock + * structure */ +#define GLF_STICKY (2) /* Don't release this inter-node lock + * unless another node explicitly asks */ +#define GLF_PREFETCH (3) /* This lock has been (speculatively) + * prefetched, demote if not used soon */ +#define GLF_SYNC (4) /* Sync lock's protected data as soon as + * there are no more holders */ +#define GLF_DIRTY (5) /* There is dirty data for this lock, + * sync before releasing inter-node */ +#define GLF_SKIP_WAITERS2 (6) /* Make run_queue() ignore gl_waiters2 + * (demote/greedy) holders */ +#define GLF_GREEDY (7) /* This lock is ignoring callbacks + * (requests from other nodes) for now */ + +struct gfs_glock { + struct list_head gl_list; /* Link to hb_list in one of superblock's + * sd_gl_hash glock hash table buckets */ + unsigned long gl_flags; /* GLF_... see above */ + struct lm_lockname gl_name; /* Lock number and lock type */ + atomic_t gl_count; /* Usage count */ + + spinlock_t gl_spin; /* Protects some members of this struct */ + + /* Lock state reflects inter-node manager's lock state */ + unsigned int gl_state; /* LM_ST_... see harness/lm_interface.h */ + + /* Lists of gfs_holders */ + struct list_head gl_holders; /* all current holders of the glock */ + struct list_head gl_waiters1; /* HIF_MUTEX */ + struct list_head gl_waiters2; /* HIF_DEMOTE, HIF_GREEDY */ + struct list_head gl_waiters3; /* HIF_PROMOTE */ + + struct gfs_glock_operations *gl_ops; /* function vector, defines type */ + + /* State to remember for async lock requests */ + struct gfs_holder *gl_req_gh; /* Holder for request being serviced */ + gfs_glop_bh_t gl_req_bh; /* The bottom half to execute */ + + void *gl_lock; /* Lock module's private lock data */ + char *gl_lvb; /* Lock Value Block */ + atomic_t gl_lvb_count; /* LVB recursive usage (hold/unhold) count */ + + uint64_t gl_vn; /* Incremented when protected data changes */ + unsigned long gl_stamp; /* Glock cache retention timer */ + void *gl_object; /* The protected entity (e.g. a dinode) */ + + /* Incore transaction stuff */ + /* Log elements map us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element gl_new_le; /* New, incomplete transaction */ + struct gfs_log_element gl_incore_le; /* Complete (committed) trans */ + + struct gfs_gl_hash_bucket *gl_bucket; /* Our bucket in sd_gl_hash */ + struct list_head gl_reclaim; /* Link to sd_reclaim_list */ + + struct gfs_sbd *gl_sbd; /* Superblock (FS instance) */ + + struct inode *gl_aspace; /* The buffers protected by this lock */ + struct list_head gl_ail_bufs; /* AIL buffers protected by us */ +}; + +/* + * In-Place Reservation structure + * Coordinates allocation of "in-place" (as opposed to journal) FS blocks, + * which contain persistent inode/file/directory data and metadata. + * These blocks are the allocatable blocks within resource groups (i.e. + * not including rgrp header and block alloc bitmap blocks). + * gfs_inplace_reserve() calculates a fulfillment plan for allocating blocks, + * based on block statistics in the resource group headers. + * Then, gfs_blkalloc() or gfs_metaalloc() walks the block alloc bitmaps + * to do the actual allocation. + */ +struct gfs_alloc { + /* Up to 4 quotas (including an inode's user and group quotas) + can track changes in block allocation */ + + unsigned int al_qd_num; /* # of quotas tracking changes */ + struct gfs_quota_data *al_qd[4]; /* Ptrs to quota structures */ + struct gfs_holder al_qd_ghs[4]; /* Holders for quota glocks */ + + /* Request, filled in by the caller to gfs_inplace_reserve() */ + + uint32_t al_requested_di; /* Number of dinodes to reserve */ + uint32_t al_requested_meta; /* Number of metadata blocks to reserve */ + uint32_t al_requested_data; /* Number of data blocks to reserve */ + + /* Fulfillment plan, filled in by gfs_inplace_reserve() */ + + char *al_file; /* Debug info, .c file making request */ + unsigned int al_line; /* Debug info, line of code making req */ + struct gfs_holder al_ri_gh; /* Glock holder for resource grp index */ + struct gfs_holder al_rgd_gh; /* Glock holder for al_rgd rgrp */ + struct gfs_rgrpd *al_rgd; /* Resource group from which to alloc */ + uint32_t al_reserved_meta; /* Alloc up to this # meta blocks from al_rgd */ + uint32_t al_reserved_data; /* Alloc up to this # data blocks from al_rgd */ + + /* Actual alloc, filled in by gfs_blkalloc()/gfs_metaalloc(), etc. */ + + uint32_t al_alloced_di; /* # dinode blocks allocated */ + uint32_t al_alloced_meta; /* # meta blocks allocated */ + uint32_t al_alloced_data; /* # data blocks allocated */ + + /* Dinode allocation crap */ + + struct gfs_unlinked *al_ul; /* Unlinked dinode log entry */ +}; + +/* + * Incore inode structure + */ + +#define GIF_QD_LOCKED (0) +#define GIF_PAGED (1) +#define GIF_SW_PAGED (2) + +struct gfs_inode { + struct gfs_inum i_num; /* Formal inode # and block address */ + + atomic_t i_count; /* Usage count */ + unsigned long i_flags; /* GIF_... see above */ + + uint64_t i_vn; /* Version #: if different from glock's vn, + we need to read inode from disk */ + struct gfs_dinode i_di; /* Dinode (on-disk) structure */ + + struct gfs_glock *i_gl; /* This glock protects this inode */ + struct gfs_sbd *i_sbd; /* Superblock (fs instance structure) */ + struct inode *i_vnode; /* Linux VFS inode structure */ + + struct gfs_holder i_iopen_gh; /* Glock holder for Inode Open lock */ + + /* Block allocation strategy, inode scope */ + struct gfs_alloc *i_alloc; /* In-place block reservation structure */ + uint64_t i_last_rg_alloc; /* Most recent blk alloc was fm this rgrp */ + + spinlock_t i_spin; + struct rw_semaphore i_rw_mutex; + + /* Cache of most-recently used buffers in indirect addressing chain */ + struct buffer_head *i_cache[GFS_MAX_META_HEIGHT]; + + unsigned int i_greedy; /* The amount of time to be greedy */ + unsigned long i_last_pfault; /* The time of the last page fault */ + struct address_space_operations gfs_file_aops; +}; + +/* + * GFS per-fd structure + */ + +#define GFF_DID_DIRECT_ALLOC (0) + +struct gfs_file { + unsigned long f_flags; /* GFF_... see above */ + + struct semaphore f_fl_lock; /* Lock to protect flock operations */ + struct gfs_holder f_fl_gh; /* Holder for this f_vfile's flock */ + + struct gfs_inode *f_inode; /* Incore GFS inode */ + struct file *f_vfile; /* Linux file struct */ +}; + +/* + * Unlinked inode log entry incore structure + */ + +#define ULF_NEW_UL (0) /* Part of new (being built) trans */ +#define ULF_INCORE_UL (1) /* Part of incore-committed trans */ +#define ULF_IC_LIST (2) +#define ULF_OD_LIST (3) +#define ULF_LOCK (4) /* Protects access to this structure */ + +struct gfs_unlinked { + struct list_head ul_list; /* Link to superblock's sd_unlinked_list */ + unsigned int ul_count; /* Usage count */ + + struct gfs_inum ul_inum; /* Formal inode #, block addr */ + unsigned long ul_flags; /* ULF_... */ + + /* Log elements map us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element ul_new_le; /* New, not yet committed */ + struct gfs_log_element ul_incore_le; /* Committed to incore log */ + struct gfs_log_element ul_ondisk_le; /* Committed to ondisk log */ +}; + +/* + * Quota log element + * One for each logged change in a block alloc value affecting a given quota. + * Only one of these for a given quota within a given transaction; + * multiple changes, within one transaction, for a given quota will be + * combined into one log element. + */ +struct gfs_quota_le { + /* Log element maps us to a particular set of log operations functions, + and to a particular transaction */ + struct gfs_log_element ql_le; /* Generic log element structure */ + + struct gfs_quota_data *ql_data; /* The quota we're changing */ + struct list_head ql_data_list; /* Link to quota's log element list */ + + int64_t ql_change; /* # of blocks alloc'd (+) or freed (-) */ +}; + +/* + * Quota structure + * One for each user or group quota. + * Summarizes all block allocation activity for a given quota, and supports + * recording updates of current block alloc values in GFS' special quota + * file, including the journaling of these updates, encompassing + * multiple transactions and log dumps. + */ + +#define QDF_USER (0) /* User (1) vs. group (0) quota */ +#define QDF_OD_LIST (1) /* Waiting for sync to quota file */ +#define QDF_LOCK (2) /* Protects access to this structure */ + +struct gfs_quota_data { + struct list_head qd_list; /* Link to superblock's sd_quota_list */ + unsigned int qd_count; /* Usage count */ + + uint32_t qd_id; /* User or group ID number */ + unsigned long qd_flags; /* QDF_... */ + + /* This list is for non-log-dump transactions */ + struct list_head qd_le_list; /* List of gfs_quota_le log elements */ + + /* Summary of block alloc changes affecting this quota, in various + stages of logging & syncing changes to the special quota file */ + int64_t qd_change_new; /* New, not yet committed to in-core log*/ + int64_t qd_change_ic; /* Committed to in-core log */ + int64_t qd_change_od; /* Committed to on-disk log */ + int64_t qd_change_sync; /* Being synced to the in-place quota file */ + + struct gfs_quota_le qd_ondisk_ql; /* Log element for log dump */ + uint64_t qd_sync_gen; /* Sync-to-quota-file generation # */ + + /* Glock provides protection for quota, *and* provides + lock value block (LVB) communication, between nodes, of current + quota values. Shared lock -> LVB read. EX lock -> LVB write. */ + struct gfs_glock *qd_gl; /* glock for this quota */ + struct gfs_quota_lvb qd_qb; /* LVB (limit/warn/value) */ + + unsigned long qd_last_warn; /* Jiffies of last warning to user */ +}; + +/* + * Log Buffer descriptor structure. + * One for each block buffer recorded in the log. + * When beginning a new transaction, GFS pre-allocates a number of these, + * and puts them on transaction's tr_free_bufs list. + * Logged buffers are of two types: + * 1). Exact copies of buffers to be written to in-place location in FS. + * 2). Log-only buffers such as log headers and control blocks (e.g. tags). + * A gfs_log_buf is required for both types; the ones for log-only buffers + * contain NULL in lb_unlock, and get cleaned up after the log write. + * lb_bh is a "fake" buffer head that directs Linux block I/O to write the buf + * to the on-disk log location, rather than the on-disk in-place location. + * Used for both types. + * lb_unlock points to the "real" buffer head that directs Linux to write the + * buf to its regular on-disk in-place filesystem location. Once the commit + * to the on-disk log is finished, GFS unlocks the "real" buffer so it can be + * written to in-place block, or modified by another transaction. + * Used only for type 1). + */ +struct gfs_log_buf { + /* Link to one of the transaction structure's lists */ + struct list_head lb_list; /* Link to tr_free_bufs or tr_list */ + + struct buffer_head lb_bh; /* "Fake" bh; for the log block */ + struct buffer_head *lb_unlock; /* "Real" bh; for the in-place block */ +}; + +/* + * Transaction structure + * One for each transaction + * This coordinates the logging and flushing of written metadata. + */ + +#define TRF_LOG_DUMP (0x00000001) +#define TRF_DUMMY (0x00000002) + +struct gfs_trans { + + /* Link to various lists */ + struct list_head tr_list; /* Superblk's incore trans or AIL list*/ + + /* Initial creation stuff */ + + char *tr_file; /* Debug info: .c file creating trans */ + unsigned int tr_line; /* Debug info: codeline creating trans */ + + /* Reservations for on-disk space in journal. + Meta blocks are copies of in-place filesystem blocks. + Extra blocks are log-only (log header and control blocks) */ + unsigned int tr_mblks_asked; /* # of meta log blocks requested */ + unsigned int tr_eblks_asked; /* # of extra log blocks requested */ + unsigned int tr_seg_reserved; /* # of segments actually reserved */ + + struct gfs_holder *tr_t_gh; /* Glock holder for this transaction */ + + /* Stuff filled in during creation */ + + unsigned int tr_flags; /* TRF_... */ + struct list_head tr_elements; /* List of this trans' log elements */ + + /* Stuff modified during the commit */ + + /* When creating a new transaction, GFS pre-allocates as many of + these buffers and descriptor structures as it might need for + all loggable filesystem (meta)data, and log-control (log-only, not + going to filesystem in-place location) data going to on-disk log. + It keeps them on these "free" lists until they get used (and linked + into tr_bufs list, below) or "refunded" if not needed. */ + unsigned int tr_num_free_bufs; /* List of free gfs_log_buf structs */ + struct list_head tr_free_bufs; /* .. 1 for each log block */ + unsigned int tr_num_free_bmem; /* List of free fs-block-size buffers */ + struct list_head tr_free_bmem; /* .. for log-only (e.g. tag) blocks */ + + /* Logged transaction starts with a (first) log header at a segment + boundary, and fills contiguous blocks after that. Each segment + boundary block gets another log header. */ + uint64_t tr_log_head; /* The next log block # to fill */ + uint64_t tr_first_head; /* Trans' first log header's block # */ + + /* gfs_log_buf structs move from tr_free_bufs to here when being used */ + struct list_head tr_bufs; /* List of buffers going to the log */ + + /* Stuff that's part of the Active Items List (AIL) */ + + struct list_head tr_ail_bufs; /* List of buffers on AIL list */ + + /* # log elements of various types on tr_elements list */ + + unsigned int tr_num_gl; /* Glocks */ + unsigned int tr_num_buf; /* Buffers */ + unsigned int tr_num_iul; /* Unlinked inodes */ + unsigned int tr_num_ida; /* De-allocated inodes */ + unsigned int tr_num_q; /* Quotas */ +}; + +#define GFS_GLOCKD_DEFAULT (1) +#define GFS_GLOCKD_MAX (32) + +#define GFS_QUOTA_DEFAULT GFS_QUOTA_OFF +#define GFS_QUOTA_OFF 0 +#define GFS_QUOTA_ACCOUNT 1 +#define GFS_QUOTA_ON 2 + +#define GFS_DATA_DEFAULT GFS_DATA_ORDERED +#define GFS_DATA_WRITEBACK 1 +#define GFS_DATA_ORDERED 2 + + +struct gfs_args { + char ar_lockproto[GFS_LOCKNAME_LEN]; /* The name of the Lock Protocol */ + char ar_locktable[GFS_LOCKNAME_LEN]; /* The name of the Lock Table */ + char ar_hostdata[GFS_LOCKNAME_LEN]; /* The host specific data */ + + int ar_spectator; /* Don't get a journal because we're always RO. */ + /* + * GFS can invoke some flock and disk caching optimizations if it is + * not in a cluster, i.e. is a local filesystem. The chosen lock + * module tells GFS, at mount time, if it supports clustering. + * The nolock module is the only one that does not support clustering; + * it sets to TRUE the local_fs field in the struct lm_lockops. + * GFS can either optimize, or ignore the opportunity. + * The user controls behavior via the following mount options. + */ + int ar_ignore_local_fs; /* Don't optimize even if local_fs is TRUE */ + int ar_localflocks; /* Let the VFS do flock|fcntl locks for us */ + int ar_localcaching; /* Local-style caching (dangerous on multihost) */ + int ar_oopses_ok; /* Allow oopses */ + + int ar_debug; /* Oops on errors instead of trying to be graceful */ + int ar_upgrade; /* Upgrade ondisk/multihost format */ + + unsigned int ar_num_glockd; /* # of glock cleanup daemons to run + (more daemons => faster cleanup) */ + int ar_posix_acls; /* Enable posix acls */ + int ar_suiddir; /* suiddir support */ + int ar_noquota; /* Turn off quota support */ +}; + +struct gfs_tune { + spinlock_t gt_spin; + + unsigned int gt_ilimit1; + unsigned int gt_ilimit1_tries; + unsigned int gt_ilimit1_min; + unsigned int gt_ilimit2; + unsigned int gt_ilimit2_tries; + unsigned int gt_ilimit2_min; + unsigned int gt_demote_secs; /* Cache retention for unheld glock */ + unsigned int gt_incore_log_blocks; + unsigned int gt_jindex_refresh_secs; /* Check for new journal index */ + unsigned int gt_depend_secs; + + /* How often various daemons run (seconds) */ + unsigned int gt_scand_secs; /* Find unused glocks and inodes */ + unsigned int gt_recoverd_secs; /* Recover journal of crashed node */ + unsigned int gt_logd_secs; /* Update log tail as AIL flushes */ + unsigned int gt_quotad_secs; /* Sync changes to quota file, clean*/ + unsigned int gt_inoded_secs; /* Toss unused inodes */ + unsigned int gt_glock_purge; /* Purge glock */ + + unsigned int gt_quota_simul_sync; /* Max # quotavals to sync at once */ + unsigned int gt_quota_warn_period; /* Secs between quota warn msgs */ + unsigned int gt_atime_quantum; /* Min secs between atime updates */ + unsigned int gt_quota_quantum; /* Secs between syncs to quota file */ + unsigned int gt_quota_scale_num; /* Numerator */ + unsigned int gt_quota_scale_den; /* Denominator */ + unsigned int gt_quota_enforce; + unsigned int gt_quota_account; + unsigned int gt_new_files_jdata; + unsigned int gt_new_files_directio; + unsigned int gt_max_atomic_write; /* Split large writes into this size*/ + unsigned int gt_max_readahead; /* Max bytes to read-ahead from disk */ + unsigned int gt_lockdump_size; + unsigned int gt_stall_secs; /* Detects trouble! */ + unsigned int gt_complain_secs; + unsigned int gt_reclaim_limit; /* Max # glocks in reclaim list */ + unsigned int gt_entries_per_readdir; + unsigned int gt_prefetch_secs; /* Usage window for prefetched glocks */ + unsigned int gt_statfs_slots; + unsigned int gt_max_mhc; /* Max # of meta headers in mhc cache */ + unsigned int gt_greedy_default; + unsigned int gt_greedy_quantum; + unsigned int gt_greedy_max; + unsigned int gt_rgrp_try_threshold; + unsigned int gt_statfs_fast; +}; + +/* + * One bucket of the filesystem's sd_gl_hash glock hash table. + * + * A gfs_glock links into a bucket's list via glock's gl_list member. + * + */ +struct gfs_gl_hash_bucket { + rwlock_t hb_lock; /* Protects list */ + struct list_head hb_list; /* List of glocks in this bucket */ +}; + +/* + * "Super Block" Data Structure + * One per mounted filesystem. + * This is the big instance structure that ties everything together for + * a given mounted filesystem. Each GFS mount has its own, supporting + * mounts of multiple GFS filesystems on each node. + * Pointer to this is usually seen as "sdp" throughout code. + * This is a very large structure, as structures go, in part because it + * contains arrays of hash buckets for various in-core caches. + */ + +#define SDF_JOURNAL_LIVE (0) /* Journaling is active (journal is writeable)*/ +#define SDF_SHUTDOWN (1) /* FS abnormaly shutdown */ + +/* (Re)mount options from Linux VFS */ +#define SDF_NOATIME (8) /* Don't change access time */ +#define SDF_ROFS (9) /* Read-only mode */ + +/* Journal log dump support */ +#define SDF_NEED_LOG_DUMP (10) /* Need to rewrite unlink and quota tags */ +#define SDF_FOUND_UL_DUMP (11) /* Recovery found unlinked tags */ +#define SDF_FOUND_Q_DUMP (12) /* Recovery found qutoa tags */ +#define SDF_IN_LOG_DUMP (13) /* Serializes log dumps */ + +/* Glock cache */ +#define GFS_GL_HASH_SHIFT (13) /* # hash buckets = 8K */ +#define GFS_GL_HASH_SIZE (1 << GFS_GL_HASH_SHIFT) +#define GFS_GL_HASH_MASK (GFS_GL_HASH_SIZE - 1) + +/* Meta header cache */ +#define GFS_MHC_HASH_SHIFT (10) /* # hash buckets = 1K */ +#define GFS_MHC_HASH_SIZE (1 << GFS_MHC_HASH_SHIFT) +#define GFS_MHC_HASH_MASK (GFS_MHC_HASH_SIZE - 1) + +/* Dependency cache */ +#define GFS_DEPEND_HASH_SHIFT (10) /* # hash buckets = 1K */ +#define GFS_DEPEND_HASH_SIZE (1 << GFS_DEPEND_HASH_SHIFT) +#define GFS_DEPEND_HASH_MASK (GFS_DEPEND_HASH_SIZE - 1) + +struct gfs_sbd { + struct gfs_sb sd_sb; /* GFS on-disk Super Block image */ + + struct super_block *sd_vfs; /* Linux VFS device independent sb */ + + struct gfs_args sd_args; /* Mount arguments */ + unsigned long sd_flags; /* SDF_... see above */ + + struct gfs_tune sd_tune; /* Filesystem tuning structure */ + + /* statfs */ + struct inode *sd_statfs_inode; + spinlock_t sd_statfs_spin; + struct gfs_statfs_change_host sd_statfs_master; + struct gfs_statfs_change_host sd_statfs_local; + unsigned long sd_statfs_sync_time; + + /* Resource group stuff */ + + struct gfs_inode *sd_riinode; /* Resource Index (rindex) inode */ + uint64_t sd_riinode_vn; /* Resource Index version # (detects + whether new rgrps have been added) */ + + struct list_head sd_rglist; /* List of all resource groups, + on-disk order */ + struct semaphore sd_rindex_lock;/* Serializes RIndex rereads */ + struct list_head sd_rg_mru_list;/* List of all resource groups, + most-recently-used (MRU) order */ + spinlock_t sd_rg_mru_lock; /* Protect mru list */ + struct list_head sd_rg_recent; /* List of rgrps from which blocks + were recently allocated */ + spinlock_t sd_rg_recent_lock; /* Protect recent list */ + struct gfs_rgrpd *sd_rg_forward;/* Next rgrp from which to attempt + a block alloc */ + spinlock_t sd_rg_forward_lock; /* Protect forward pointer */ + + unsigned int sd_rgcount; /* Total # of resource groups */ + + /* Constants computed on mount */ + + /* "bb" == "basic block" == 512Byte sector */ + uint32_t sd_fsb2bb; /* # 512B basic blocks in a FS block */ + uint32_t sd_fsb2bb_shift; /* Shift sector # to the right by + this to get FileSystem block addr */ + uint32_t sd_diptrs; /* Max # of block pointers in a dinode */ + uint32_t sd_inptrs; /* Max # of block pointers in an indirect blk */ + uint32_t sd_jbsize; /* Payload size (bytes) of a journaled metadata + block (GFS journals all meta blocks) */ + uint32_t sd_hash_bsize; /* sizeof(exhash hash block) */ + uint32_t sd_hash_bsize_shift; + uint32_t sd_hash_ptrs; /* Number of points in a hash block */ + uint32_t sd_max_dirres; /* Max blocks needed to add a directory entry */ + uint32_t sd_max_height; /* Max height of a file's tree */ + uint64_t sd_heightsize[GFS_MAX_META_HEIGHT]; + uint32_t sd_max_jheight; /* Max height, journaled file's tree */ + uint64_t sd_jheightsize[GFS_MAX_META_HEIGHT]; + + /* Lock Stuff */ + + /* Glock cache (all glocks currently held by this node for this FS) */ + struct gfs_gl_hash_bucket sd_gl_hash[GFS_GL_HASH_SIZE]; + + /* Glock reclaim support for scand and glockd */ + struct list_head sd_reclaim_list; /* List of glocks to reclaim */ + spinlock_t sd_reclaim_lock; + wait_queue_head_t sd_reclaim_wchan; + atomic_t sd_reclaim_count; /* # glocks on reclaim list */ + + /* Lock module tells us if we're first-to-mount, + which journal to use, etc. */ + struct lm_lockstruct sd_lockstruct; /* Info provided by lock module */ + + /* Other caches */ + + /* Meta-header cache (incore copies of on-disk meta headers) */ + struct list_head sd_mhc[GFS_MHC_HASH_SIZE]; /* hash buckets */ + struct list_head sd_mhc_single; /* Non-hashed list of all MHCs */ + spinlock_t sd_mhc_lock; + atomic_t sd_mhc_count; /* # MHCs in cache */ + + /* Dependency cache */ + struct list_head sd_depend[GFS_DEPEND_HASH_SIZE]; /* Hash buckets */ + spinlock_t sd_depend_lock; + atomic_t sd_depend_count; /* # dependencies in cache */ + + /* LIVE inter-node lock indicates that FS is mounted on at least + one node */ + struct gfs_holder sd_live_gh; /* Glock holder for LIVE lock */ + + /* For quiescing the filesystem */ + struct gfs_holder sd_freeze_gh; + struct semaphore sd_freeze_lock; + unsigned int sd_freeze_count; + + /* Inode Stuff */ + + struct gfs_inode *sd_rooti; /* FS's root inode */ + + /* Only 1 node at a time may rename (e.g. mv) directory from + one directory to another. */ + struct gfs_glock *sd_rename_gl; /* Rename glock */ + + /* Daemon stuff */ + + /* Scan for glocks and inodes to toss from memory */ + struct task_struct *sd_scand_process; /* Scand places on reclaim list*/ + struct task_struct *sd_glockd_process[GFS_GLOCKD_MAX]; + unsigned int sd_glockd_num; /* # of glockd procs to do reclaiming*/ + + /* Recover journal of a crashed node */ + struct task_struct *sd_recoverd_process; + + /* Update log tail as AIL gets flushed to in-place on-disk blocks */ + struct task_struct *sd_logd_process; + + /* Sync quota updates to disk, and clean up unused quota structs */ + struct task_struct *sd_quotad_process; + + /* Clean up unused inode structures */ + struct task_struct *sd_inoded_process; + + /* Log stuff */ + + /* Transaction lock protects the following from one another: + normal write transaction, journal replay (recovery), fs upgrade, + fs read-only => read/write and read/write => read-only conversions. + Also, acquiring the transaction lock in a state other than shared + causes all other machines in the cluster to sync out their dirty + data, mark their journal as being clean, and prevent any new FS + modifications from occuring (i.e. quiesces the FS). */ + struct gfs_glock *sd_trans_gl; /* Transaction glock structure */ + + struct gfs_inode *sd_jiinode; /* Journal index inode */ + uint64_t sd_jiinode_vn; /* Journal index version # (detects + if new journals have been added) */ + + unsigned int sd_journals; /* Number of journals in the FS */ + struct gfs_jindex *sd_jindex; /* Array of journal descriptors */ + struct semaphore sd_jindex_lock; + unsigned long sd_jindex_refresh_time; /* Poll for new journals (secs) */ + + struct gfs_jindex sd_jdesc; /* This machine's journal descriptor */ + struct gfs_holder sd_journal_gh; /* This machine's jrnl glock holder */ + + uint64_t sd_sequence; /* Assigned to xactions in order they commit */ + uint64_t sd_log_head; /* Block number of next journal write */ + uint64_t sd_log_wrap; + + spinlock_t sd_log_seg_lock; + unsigned int sd_log_seg_free; /* # of free segments in the log */ + unsigned int sd_log_seg_ail2; /* # of freeable segments in the log */ + struct list_head sd_log_seg_list; + wait_queue_head_t sd_log_seg_wait; + + /* "Active Items List" of transactions that have been flushed to + on-disk log, and are waiting for flush to in-place on-disk blocks */ + struct list_head sd_log_ail; /* "next" is head, "prev" is tail */ + + /* Transactions committed incore, but not yet flushed to on-disk log */ + struct list_head sd_log_incore; /* "Next" is newest, "prev" is oldest */ + unsigned int sd_log_buffers; /* # of buffers in the incore log */ + + struct rw_semaphore sd_log_lock; /* Lock for access to log values */ + + uint64_t sd_log_dump_last; + uint64_t sd_log_dump_last_wrap; + + /* + * Unlinked inode crap. + * List includes newly created, not-yet-linked inodes, + * as well as inodes that have been unlinked and are waiting + * to be de-allocated. + */ + struct list_head sd_unlinked_list; /* List of unlinked inodes */ + spinlock_t sd_unlinked_lock; /* Protects list and members */ + + atomic_t sd_unlinked_ic_count; + atomic_t sd_unlinked_od_count; + + /* Quota crap */ + + struct list_head sd_quota_list; /* List of all gfs_quota_data structs */ + spinlock_t sd_quota_lock; + + atomic_t sd_quota_count; /* # quotas on sd_quota_list */ + atomic_t sd_quota_od_count; /* # quotas waiting for sync to + special on-disk quota file */ + + struct gfs_inode *sd_qinode; /* Special on-disk quota file */ + + uint64_t sd_quota_sync_gen; /* Generation, incr when sync to file */ + unsigned long sd_quota_sync_time; /* Jiffies, last sync to quota file */ + + /* License crap */ + + struct gfs_inode *sd_linode; /* Special on-disk license file */ + + /* Recovery stuff */ + + /* Lock module tells GFS, via callback, when a journal needs recovery. + It stays on this list until recovery daemon performs recovery. */ + struct list_head sd_dirty_j; /* List of dirty journals */ + spinlock_t sd_dirty_j_lock; /* Protects list */ + + /* Statistics for 3 possible recovery actions for each buffer in log, + determined by comparing generation #s of logged block and + in-place block. Scope of stats is for one journal. */ + unsigned int sd_recovery_replays; /* newer than in-place; copy it */ + unsigned int sd_recovery_skips; /* older than in-place; ignore it */ + unsigned int sd_recovery_sames; /* same as in-place; ignore it */ + + /* Counters */ + + /* current quantities of various things */ + atomic_t sd_glock_count; /* # of gfs_glock structs alloc'd */ + atomic_t sd_glock_held_count; /* # of glocks locked by this node */ + atomic_t sd_inode_count; /* # of gfs_inode structs alloc'd */ + atomic_t sd_bufdata_count; /* # of gfs_bufdata structs alloc'd */ + + atomic_t sd_fh2dentry_misses; /* total # get_dentry misses */ + atomic_t sd_reclaimed; /* total # glocks reclaimed since mount */ + + /* total lock-related calls handled since mount */ + atomic_t sd_glock_nq_calls; + atomic_t sd_glock_dq_calls; + atomic_t sd_glock_prefetch_calls; + atomic_t sd_lm_lock_calls; + atomic_t sd_lm_unlock_calls; + atomic_t sd_lm_callbacks; + + atomic_t sd_lm_outstanding; + atomic_t sd_bio_reads; + atomic_t sd_bio_writes; + atomic_t sd_bio_outstanding; + + /* total calls from Linux VFS handled since mount */ + atomic_t sd_ops_address; + atomic_t sd_ops_dentry; + atomic_t sd_ops_export; + atomic_t sd_ops_file; + atomic_t sd_ops_inode; + atomic_t sd_ops_super; + atomic_t sd_ops_vm; + + char sd_fsname[256]; + char sd_table_name[256]; + char sd_proto_name[256]; + + struct kobject sd_kobj; + + /* Debugging crud */ + + unsigned long sd_last_warning; + + spinlock_t sd_ail_lock; + struct list_head sd_recovery_bufs; + + struct list_head sd_list; +}; + +#endif /* __INCORE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/util.c +++ linux-2.6.28/ubuntu/gfs/util.c @@ -0,0 +1,571 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "glock.h" +#include "lm.h" + +uint32_t gfs_random_number; + +struct kmem_cache *gfs_glock_cachep = NULL; +struct kmem_cache *gfs_inode_cachep = NULL; +struct kmem_cache *gfs_bufdata_cachep = NULL; +struct kmem_cache *gfs_mhc_cachep = NULL; + +/** + * gfs_random - Generate a random 32-bit number + * + * Generate a semi-crappy 32-bit pseudo-random number without using + * floating point. + * + * The PRNG is from "Numerical Recipes in C" (second edition), page 284. + * + * Returns: a 32-bit random number + */ + +uint32_t +gfs_random(void) +{ + gfs_random_number = 0x0019660D * gfs_random_number + 0x3C6EF35F; + return gfs_random_number; +} + +/** + * hash_more_internal - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * @hash: the hash from a previous call + * + * Take some data and convert it to a 32-bit hash. + * + * This is the 32-bit FNV-1a hash from: + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * Hash guts + * + * Returns: the hash + */ + +static __inline__ uint32_t +hash_more_internal(const void *data, unsigned int len, uint32_t hash) +{ + unsigned char *p = (unsigned char *)data; + unsigned char *e = p + len; + uint32_t h = hash; + + while (p < e) { + h ^= (uint32_t)(*p++); + h *= 0x01000193; + } + + return h; +} + +/** + * gfs_hash - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * + * Take some data and convert it to a 32-bit hash. + * + * This is the 32-bit FNV-1a hash from: + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * Returns: the hash + */ + +uint32_t +gfs_hash(const void *data, unsigned int len) +{ + uint32_t h = 0x811C9DC5; + h = hash_more_internal(data, len, h); + return h; +} + +/** + * gfs_hash_more - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * @hash: the hash from a previous call + * + * Take some data and convert it to a 32-bit hash. + * + * This is the 32-bit FNV-1a hash from: + * http://www.isthe.com/chongo/tech/comp/fnv/ + * + * This version let's you hash together discontinuous regions. + * For example, to compute the combined hash of the memory in + * (data1, len1), (data2, len2), and (data3, len3) you: + * + * h = gfs_hash(data1, len1); + * h = gfs_hash_more(data2, len2, h); + * h = gfs_hash_more(data3, len3, h); + * + * Returns: the hash + */ + +uint32_t +gfs_hash_more(const void *data, unsigned int len, uint32_t hash) +{ + uint32_t h; + h = hash_more_internal(data, len, hash); + return h; +} + +/* Byte-wise swap two items of size SIZE. */ + +#define SWAP(a, b, size) \ +do { \ + register size_t __size = (size); \ + register char *__a = (a), *__b = (b); \ + do { \ + char __tmp = *__a; \ + *__a++ = *__b; \ + *__b++ = __tmp; \ + } while (__size-- > 1); \ +} while (0) + +/** + * gfs_sort - Sort base array using shell sort algorithm + * @base: the input array + * @num_elem: number of elements in array + * @size: size of each element in array + * @compar: fxn to compare array elements (returns negative + * for lt, 0 for eq, and positive for gt + * + * Sorts the array passed in using the compar fxn to compare elements using + * the shell sort algorithm + */ + +void +gfs_sort(void *base, unsigned int num_elem, unsigned int size, + int (*compar) (const void *, const void *)) +{ + register char *pbase = (char *)base; + int i, j, k, h; + static int cols[16] = {1391376, 463792, 198768, 86961, + 33936, 13776, 4592, 1968, + 861, 336, 112, 48, + 21, 7, 3, 1}; + + for (k = 0; k < 16; k++) { + h = cols[k]; + for (i = h; i < num_elem; i++) { + j = i; + while (j >= h && + (*compar)((void *)(pbase + size * (j - h)), + (void *)(pbase + size * j)) > 0) { + SWAP(pbase + size * j, + pbase + size * (j - h), + size); + j = j - h; + } + } + } +} + +/** + * gfs_assert_i - Cause the machine to panic if @assertion is false + * @sdp: + * @assertion: + * @function: + * @file: + * @line: + * + */ + +void +gfs_assert_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +{ + if (sdp->sd_args.ar_oopses_ok) { + printk("GFS: fsid=%s: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + BUG(); + } + dump_stack(); + panic("GFS: fsid=%s: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_assert_withdraw_i - Cause the machine to withdraw if @assertion is false + * @sdp: + * @assertion: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int +gfs_assert_withdraw_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +{ + int me; + me = gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + return (me) ? -1 : -2; +} + +/** + * gfs_assert_warn_i - Print a message to the console if @assertion is false + * @sdp: + * @assertion: + * @function: + * @file: + * @line: + * + * Returns: -1 if we printed something + * -2 if we didn't + */ + +int +gfs_assert_warn_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +{ + if (time_before(jiffies, + sdp->sd_last_warning + + gfs_tune_get(sdp, gt_complain_secs) * HZ)) + return -2; + + printk("GFS: fsid=%s: warning: assertion \"%s\" failed\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, assertion, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + + sdp->sd_last_warning = jiffies; + if (sdp->sd_args.ar_debug) + BUG(); + + + return -1; +} + +/** + * gfs_consist_i - Flag a filesystem consistency error and withdraw + * @sdp: + * @cluster_wide: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_consist_i(struct gfs_sbd *sdp, int cluster_wide, + const char *function, + char *file, unsigned int line) +{ + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: filesystem consistency error\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_consist_inode_i - Flag an inode consistency error and withdraw + * @ip: + * @cluster_wide: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_consist_inode_i(struct gfs_inode *ip, int cluster_wide, + const char *function, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = ip->i_sbd; + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: filesystem consistency error\n" + "GFS: fsid=%s: inode = %"PRIu64"/%"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, ip->i_num.no_formal_ino, ip->i_num.no_addr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_consist_rgrpd_i - Flag a RG consistency error and withdraw + * @rgd: + * @cluster_wide: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_consist_rgrpd_i(struct gfs_rgrpd *rgd, int cluster_wide, + const char *function, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: filesystem consistency error\n" + "GFS: fsid=%s: RG = %"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, rgd->rd_ri.ri_addr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_meta_check_ii - Flag a magic number consistency error and withdraw + * @sdp: + * @bh: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int +gfs_meta_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line) +{ + int me; + me = gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: invalid metadata block\n" + "GFS: fsid=%s: bh = %"PRIu64" (magic)\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, (uint64_t)bh->b_blocknr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + return (me) ? -1 : -2; +} + +/** + * gfs_metatype_check_ii - Flag a metadata type consistency error and withdraw + * @sdp: + * @bh: + * @type: + * @t: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int +gfs_metatype_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type, uint32_t t, + const char *function, + char *file, unsigned int line) +{ + int me; + me = gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: invalid metadata block\n" + "GFS: fsid=%s: bh = %"PRIu64" (type: exp=%u, found=%u)\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, (uint64_t)bh->b_blocknr, type, t, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); + return (me) ? -1 : -2; +} + +/** + * gfs_io_error_i - Flag an I/O error and withdraw + * @sdp: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_io_error_i(struct gfs_sbd *sdp, + const char *function, + char *file, unsigned int line) +{ + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: I/O error\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_io_error_inode_i - Flag an inode I/O error and withdraw + * @ip: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_io_error_inode_i(struct gfs_inode *ip, + const char *function, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = ip->i_sbd; + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: I/O error\n" + "GFS: fsid=%s: inode = %"PRIu64"/%"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, ip->i_num.no_formal_ino, ip->i_num.no_addr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gfs_io_error_bh_i - Flag a buffer I/O error and withdraw + * @sdp: + * @bh: + * @function: + * @file: + * @line: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int +gfs_io_error_bh_i(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line) +{ + return gfs_lm_withdraw(sdp, + "GFS: fsid=%s: fatal: I/O error\n" + "GFS: fsid=%s: block = %"PRIu64"\n" + "GFS: fsid=%s: function = %s\n" + "GFS: fsid=%s: file = %s, line = %u\n" + "GFS: fsid=%s: time = %lu\n", + sdp->sd_fsname, + sdp->sd_fsname, (uint64_t)bh->b_blocknr, + sdp->sd_fsname, function, + sdp->sd_fsname, file, line, + sdp->sd_fsname, get_seconds()); +} + +/** + * gmalloc - malloc a small amount of memory + * @size: the number of bytes to malloc + * + * Returns: the memory + */ + +void * +gmalloc(unsigned int size) +{ + void *p; + RETRY_MALLOC(p = kmalloc(size, GFP_KERNEL), p); + return p; +} + +/** + * gfs_add_bh_to_ub - copy a buffer up to user space + * @ub: the structure representing where to copy + * @bh: the buffer + * + * Returns: errno + */ + +int +gfs_add_bh_to_ub(struct gfs_user_buffer *ub, struct buffer_head *bh) +{ + uint64_t blkno = bh->b_blocknr; + + if (ub->ub_count + sizeof(uint64_t) + bh->b_size > ub->ub_size) + return -ENOMEM; + + if (copy_to_user(ub->ub_data + ub->ub_count, + &blkno, + sizeof(uint64_t))) + return -EFAULT; + ub->ub_count += sizeof(uint64_t); + + if (copy_to_user(ub->ub_data + ub->ub_count, + bh->b_data, + bh->b_size)) + return -EFAULT; + ub->ub_count += bh->b_size; + + return 0; +} + --- linux-2.6.28.orig/ubuntu/gfs/format.h +++ linux-2.6.28/ubuntu/gfs/format.h @@ -0,0 +1,17 @@ +#ifndef __FORMAT_DOT_H__ +#define __FORMAT_DOT_H__ + +static const uint32_t gfs_old_fs_formats[] = { + 1308, + 1307, + 1306, + 1305, + 0 +}; + +static const uint32_t gfs_old_multihost_formats[] = { + 1400, + 0 +}; + +#endif /* __FORMAT_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_inode.c +++ linux-2.6.28/ubuntu/gfs/ops_inode.c @@ -0,0 +1,1670 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "eaops.h" +#include "eattr.h" +#include "glock.h" +#include "inode.h" +#include "ops_dentry.h" +#include "ops_inode.h" +#include "page.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" +#include "unlinked.h" + +/** + * gfs_security_init - + * @dip: + * @ip: + * + * Returns: errno + */ + +static int +gfs_security_init(struct gfs_inode *dip, struct gfs_inode *ip) +{ + int err; + size_t len; + void *value; + char *name; + struct gfs_ea_request er; + + err = security_inode_init_security(ip->i_vnode, dip->i_vnode, + &name, &value, &len); + + if (err) { + if (err == -EOPNOTSUPP) + return 0; + return err; + } + + memset(&er, 0, sizeof(struct gfs_ea_request)); + + er.er_type = GFS_EATYPE_SECURITY; + er.er_name = name; + er.er_data = value; + er.er_name_len = strlen(name); + er.er_data_len = len; + + err = gfs_ea_set_i(ip, &er); + + kfree(value); + kfree(name); + + return err; +} + +/** + * gfs_create - Create a file + * @dir: The directory in which to create the file + * @dentry: The dentry of the new file + * @mode: The mode of the new file + * + * Returns: errno + */ + +static int +gfs_create(struct inode *dir, struct dentry *dentry, + int mode, struct nameidata *nd) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + int new = TRUE; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + for (;;) { + error = gfs_createi(&d_gh, &dentry->d_name, + GFS_FILE_REG, mode, + &i_gh); + if (!error) + break; + else if (error != -EEXIST || + (nd && (nd->intent.open.flags & O_EXCL))) { + gfs_holder_uninit(&d_gh); + return error; + } + + error = gfs_lookupi(&d_gh, &dentry->d_name, + FALSE, &i_gh); + if (!error) { + if (i_gh.gh_gl) { + new = FALSE; + break; + } + } else { + gfs_holder_uninit(&d_gh); + return error; + } + } + + ip = get_gl2ip(i_gh.gh_gl); + + if (new) { + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + } + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + if (!inode) + error = -ENOMEM; + else + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + d_instantiate(dentry, inode); + if (new) + mark_inode_dirty(inode); + + return 0; +} + +/** + * lookup_cdpn_sub_at - Maybe lookup a Context Dependent Pathname + * @sdp: the filesystem + * @dentry: the original dentry to lookup + * @new_dentry: the new dentry, if this was a substitutable path. + * + * Returns: the new dentry, a ERR_PTR, or NULL + */ + +static struct dentry * +lookup_cdpn_sub_at(struct gfs_sbd *sdp, struct dentry *dentry) +{ + struct dentry *parent, *new = NULL; + char *buf; + + buf = kmalloc(2 * __NEW_UTS_LEN + 2, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + parent = dget_parent(dentry); + + if (gfs_filecmp(&dentry->d_name, "@hostname", 9)) + new = lookup_one_len(init_utsname()->nodename, + parent, + strlen(init_utsname()->nodename)); + else if (gfs_filecmp(&dentry->d_name, "@mach", 5)) + new = lookup_one_len(init_utsname()->machine, + parent, + strlen(init_utsname()->machine)); + else if (gfs_filecmp(&dentry->d_name, "@os", 3)) + new = lookup_one_len(init_utsname()->sysname, + parent, + strlen(init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "@uid", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsuid)); + else if (gfs_filecmp(&dentry->d_name, "@gid", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsgid)); + else if (gfs_filecmp(&dentry->d_name, "@sys", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%s_%s", + init_utsname()->machine, + init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "@jid", 4)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", + sdp->sd_lockstruct.ls_jid)); + + dput(parent); + kfree(buf); + + return new; +} + +/** + * lookup_cdpn_sub_brace - Maybe lookup a Context Dependent Pathname + * @sdp: the filesystem + * @dentry: the original dentry to lookup + * @new_dentry: the new dentry, if this was a substitutable path. + * + * Returns: the new dentry, a ERR_PTR, or NULL + */ + +static struct dentry * +lookup_cdpn_sub_brace(struct gfs_sbd *sdp, struct dentry *dentry) +{ + struct dentry *parent, *new = NULL; + char *buf; + + buf = kmalloc(2 * __NEW_UTS_LEN + 2, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + parent = dget_parent(dentry); + + if (gfs_filecmp(&dentry->d_name, "{hostname}", 10)) + new = lookup_one_len(init_utsname()->nodename, + parent, + strlen(init_utsname()->nodename)); + else if (gfs_filecmp(&dentry->d_name, "{mach}", 6)) + new = lookup_one_len(init_utsname()->machine, + parent, + strlen(init_utsname()->machine)); + else if (gfs_filecmp(&dentry->d_name, "{os}", 4)) + new = lookup_one_len(init_utsname()->sysname, + parent, + strlen(init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "{uid}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsuid)); + else if (gfs_filecmp(&dentry->d_name, "{gid}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", current->fsgid)); + else if (gfs_filecmp(&dentry->d_name, "{sys}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%s_%s", + init_utsname()->machine, + init_utsname()->sysname)); + else if (gfs_filecmp(&dentry->d_name, "{jid}", 5)) + new = lookup_one_len(buf, + parent, + sprintf(buf, "%u", + sdp->sd_lockstruct.ls_jid)); + + dput(parent); + kfree(buf); + + return new; +} + +/** + * gfs_lookup - Look up a filename in a directory and return its inode + * @dir: The directory inode + * @dentry: The dentry of the new inode + * @nd: passed from Linux VFS, ignored by us + * + * Called by the VFS layer. Lock dir and call gfs_lookupi() + * + * Returns: errno + */ + +static struct dentry * +gfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_holder d_gh, i_gh; + struct inode *inode = NULL; + int error; + + atomic_inc(&dip->i_sbd->sd_ops_inode); + + /* Do Context Dependent Path Name expansion */ + + if (*dentry->d_name.name == '@' && dentry->d_name.len > 1) { + struct dentry *new_dentry; + new_dentry = lookup_cdpn_sub_at(dip->i_sbd, dentry); + if (new_dentry) + return new_dentry; + } else if (*dentry->d_name.name == '{' && dentry->d_name.len > 2) { + struct dentry *new_dentry; + new_dentry = lookup_cdpn_sub_brace(dip->i_sbd, dentry); + if (new_dentry) + return new_dentry; + } + + dentry->d_op = &gfs_dops; + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_lookupi(&d_gh, &dentry->d_name, FALSE, &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return ERR_PTR(error); + } + + if (i_gh.gh_gl) { + ip = get_gl2ip(i_gh.gh_gl); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (!inode) + return ERR_PTR(-ENOMEM); + } else + gfs_holder_uninit(&d_gh); + + if (inode) + return d_splice_alias(inode, dentry); + d_add(dentry, inode); + + return NULL; +} + +/** + * gfs_link - Link to a file + * @old_dentry: The inode to link + * @dir: Add link to this directory + * @dentry: The name of the link + * + * Link the inode in "old_dentry" into the directory "dir" with the + * name in "dentry". + * + * Returns: errno + */ + +static int +gfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) +{ + struct gfs_inode *dip = get_v2ip(dir); + struct gfs_sbd *sdp = dip->i_sbd; + struct inode *inode = old_dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_alloc *al = NULL; + struct gfs_holder ghs[2]; + int alloc_required; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + if (ip->i_di.di_type == GFS_FILE_DIR) + return -EPERM; + + gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + + error = gfs_glock_nq_m(2, ghs); + if (error) + goto fail; + + error = inode_permission(dir, MAY_WRITE | MAY_EXEC); + if (error) + goto fail_gunlock; + + error = gfs_dir_search(dip, &dentry->d_name, NULL, NULL); + switch (error) { + case -ENOENT: + break; + case 0: + error = -EEXIST; + default: + goto fail_gunlock; + } + + if (!dip->i_di.di_nlink) { + error = -EINVAL; + goto fail_gunlock; + } + if (dip->i_di.di_entries == (uint32_t)-1) { + error = -EFBIG; + goto fail_gunlock; + } + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { + error = -EPERM; + goto fail_gunlock; + } + if (!ip->i_di.di_nlink) { + error = -EINVAL; + goto fail_gunlock; + } + if (ip->i_di.di_nlink == (uint32_t)-1) { + error = -EMLINK; + goto fail_gunlock; + } + + error = gfs_diradd_alloc_required(dip, &dentry->d_name, &alloc_required); + if (error) + goto fail_gunlock; + + if (alloc_required) { + al = gfs_alloc_get(dip); + + error = gfs_quota_lock_m(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail_alloc; + + error = gfs_quota_check(dip, dip->i_di.di_uid, dip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = sdp->sd_max_dirres; + + error = gfs_inplace_reserve(dip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + two dinode blocks, directory modifications to add an entry, + RG bitmap blocks to allocate from, and quota change */ + + error = gfs_trans_begin(sdp, + 2 + sdp->sd_max_dirres + + al->al_rgd->rd_ri.ri_length, + 1); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + Two dinode blocks and a leaf block. */ + + error = gfs_trans_begin(sdp, 3, 0); + if (error) + goto fail_ipres; + } + + error = gfs_dir_add(dip, &dentry->d_name, &ip->i_num, ip->i_di.di_type); + if (error) + goto fail_end_trans; + + error = gfs_change_nlink(ip, +1); + if (error) + goto fail_end_trans; + + gfs_trans_end(sdp); + + if (alloc_required) { + gfs_assert_warn(sdp, al->al_alloced_meta); + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_alloc_put(dip); + } + + gfs_glock_dq_m(2, ghs); + + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + atomic_inc(&inode->i_count); + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (alloc_required) + gfs_inplace_release(dip); + + fail_gunlock_q: + if (alloc_required) + gfs_quota_unlock_m(dip); + + fail_alloc: + if (alloc_required) + gfs_alloc_put(dip); + + fail_gunlock: + gfs_glock_dq_m(2, ghs); + + fail: + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return error; +} + +/** + * gfs_unlink - Unlink a file + * @dir: The inode of the directory containing the file to unlink + * @dentry: The file itself + * + * Unlink a file. Call gfs_unlinki() + * + * Returns: errno + */ + +static int +gfs_unlink(struct inode *dir, struct dentry *dentry) +{ + struct gfs_inode *dip = get_v2ip(dir); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + struct gfs_holder ghs[2]; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + + error = gfs_glock_nq_m(2, ghs); + if (error) + goto fail; + + error = gfs_unlink_ok(dip, &dentry->d_name, ip); + if (error) + goto fail_gunlock; + + /* Trans may require: + Two dinode blocks and one modified directory leaf block + and one unlinked tag. */ + + error = gfs_trans_begin(sdp, 3, 1); + if (error) + goto fail_gunlock; + + error = gfs_unlinki(dip, &dentry->d_name, ip); + if (error) + goto fail_end_trans; + + gfs_trans_end(sdp); + + gfs_glock_dq_m(2, ghs); + + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_gunlock: + gfs_glock_dq_m(2, ghs); + + fail: + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return error; +} + +/** + * gfs_symlink - Create a symlink + * @dir: The directory to create the symlink in + * @dentry: The dentry to put the symlink in + * @symname: The thing which the link points to + * + * Returns: errno + */ + +static int +gfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + struct buffer_head *dibh; + int size; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + /* Must be stuffed with a null terminator for gfs_follow_link() */ + size = strlen(symname); + if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode) - 1) + return -ENAMETOOLONG; + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_createi(&d_gh, &dentry->d_name, + GFS_FILE_LNK, S_IFLNK | S_IRWXUGO, + &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + ip = get_gl2ip(i_gh.gh_gl); + + ip->i_di.di_size = size; + + error = gfs_get_inode_buffer(ip, &dibh); + + if (!gfs_assert_withdraw(sdp, !error)) { + gfs_dinode_out(&ip->i_di, dibh->b_data); + memcpy(dibh->b_data + sizeof(struct gfs_dinode), symname, size); + brelse(dibh); + } + + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + if (!inode) + return -ENOMEM; + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; +} + +/** + * gfs_mkdir - Make a directory + * @dir: The parent directory of the new one + * @dentry: The dentry of the new directory + * @mode: The mode of the new directory + * + * Returns: errno + */ + +static int +gfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + struct buffer_head *dibh; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_createi(&d_gh, &dentry->d_name, + GFS_FILE_DIR, S_IFDIR | mode, + &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + ip = get_gl2ip(i_gh.gh_gl); + + ip->i_di.di_nlink = 2; + ip->i_di.di_size = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); + ip->i_di.di_flags |= GFS_DIF_JDATA; + ip->i_di.di_payload_format = GFS_FORMAT_DE; + ip->i_di.di_entries = 2; + + error = gfs_get_inode_buffer(ip, &dibh); + + if (!gfs_assert_withdraw(sdp, !error)) { + struct gfs_dinode *di = (struct gfs_dinode *)dibh->b_data; + struct gfs_dirent *dent; + + gfs_dirent_alloc(ip, dibh, 1, &dent); + + dent->de_inum = di->di_num; /* already GFS endian */ + dent->de_hash = gfs_dir_hash(".", 1); + dent->de_hash = cpu_to_gfs32(dent->de_hash); + dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); + memcpy((char *) (dent + 1), ".", 1); + di->di_entries = cpu_to_gfs32(1); + + gfs_dirent_alloc(ip, dibh, 2, &dent); + + gfs_inum_out(&dip->i_num, (char *) &dent->de_inum); + dent->de_hash = gfs_dir_hash("..", 2); + dent->de_hash = cpu_to_gfs32(dent->de_hash); + dent->de_type = cpu_to_gfs16(GFS_FILE_DIR); + memcpy((char *) (dent + 1), "..", 2); + + gfs_dinode_out(&ip->i_di, (char *)di); + + brelse(dibh); + } + + error = gfs_change_nlink(dip, +1); + gfs_assert_withdraw(sdp, !error); /* dip already pinned */ + + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + if (!inode) + return -ENOMEM; + + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; +} + +/** + * gfs_rmdir - Remove a directory + * @dir: The parent directory of the directory to be removed + * @dentry: The dentry of the directory to remove + * + * Remove a directory. Call gfs_rmdiri() + * + * Returns: errno + */ + +static int +gfs_rmdir(struct inode *dir, struct dentry *dentry) +{ + struct gfs_inode *dip = get_v2ip(dir); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + struct gfs_holder ghs[2]; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + gfs_holder_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + + error = gfs_glock_nq_m(2, ghs); + if (error) + goto fail; + + error = gfs_unlink_ok(dip, &dentry->d_name, ip); + if (error) + goto fail_gunlock; + + if (ip->i_di.di_entries < 2) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + error = -EIO; + goto fail_gunlock; + } + if (ip->i_di.di_entries > 2) { + error = -ENOTEMPTY; + goto fail_gunlock; + } + + /* Trans may require: + Two dinode blocks, one directory leaf block containing the + entry to be rmdired, two leaf blocks containing . and .. of + the directory being rmdired, and one unlinked tag */ + + error = gfs_trans_begin(sdp, 5, 1); + if (error) + goto fail_gunlock; + + error = gfs_rmdiri(dip, &dentry->d_name, ip); + if (error) + goto fail_end_trans; + + gfs_trans_end(sdp); + + gfs_glock_dq_m(2, ghs); + + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_gunlock: + gfs_glock_dq_m(2, ghs); + + fail: + gfs_holder_uninit(&ghs[0]); + gfs_holder_uninit(&ghs[1]); + + return error; +} + +/** + * gfs_mknod - Make a special file + * @dir: The directory in which the special file will reside + * @dentry: The dentry of the special file + * @mode: The mode of the special file + * @rdev: The device specification of the special file + * + */ + +static int +gfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +{ + struct gfs_inode *dip = get_v2ip(dir), *ip; + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_holder d_gh, i_gh; + struct inode *inode; + struct buffer_head *dibh; + uint16_t type = 0; + uint32_t major = 0, minor = 0; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + switch (mode & S_IFMT) { + case S_IFBLK: + type = GFS_FILE_BLK; + major = MAJOR(dev); + minor = MINOR(dev); + break; + case S_IFCHR: + type = GFS_FILE_CHR; + major = MAJOR(dev); + minor = MINOR(dev); + break; + case S_IFIFO: + type = GFS_FILE_FIFO; + break; + case S_IFSOCK: + type = GFS_FILE_SOCK; + break; + default: + printk("GFS: fsid=%s: mknod() with invalid type (%d)\n", + sdp->sd_fsname, mode); + return -EINVAL; + }; + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + + error = gfs_createi(&d_gh, &dentry->d_name, + type, mode, + &i_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + ip = get_gl2ip(i_gh.gh_gl); + + ip->i_di.di_major = major; + ip->i_di.di_minor = minor; + + error = gfs_get_inode_buffer(ip, &dibh); + + if (!gfs_assert_withdraw(sdp, !error)) { + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + if (dip->i_alloc->al_rgd) + gfs_inplace_release(dip); + gfs_quota_unlock_m(dip); + gfs_unlinked_unlock(sdp, dip->i_alloc->al_ul); + gfs_alloc_put(dip); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + error = gfs_security_init(dip, ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (error) + return error; + + if (!inode) + return -ENOMEM; + + d_instantiate(dentry, inode); + mark_inode_dirty(inode); + + return 0; +} + +/** + * gfs_rename - Rename a file + * @odir: Parent directory of old file name + * @odentry: The old dentry of the file + * @ndir: Parent directory of new file name + * @ndentry: The new dentry of the file + * + * Returns: errno + */ + +static int +gfs_rename(struct inode *odir, struct dentry *odentry, + struct inode *ndir, struct dentry *ndentry) +{ + struct gfs_inode *odip = get_v2ip(odir); + struct gfs_inode *ndip = get_v2ip(ndir); + struct gfs_inode *ip = get_v2ip(odentry->d_inode); + struct gfs_inode *nip = NULL; + struct gfs_sbd *sdp = odip->i_sbd; + struct qstr name; + struct gfs_alloc *al; + struct gfs_holder ghs[4], r_gh; + unsigned int num_gh; + int dir_rename = FALSE; + int alloc_required; + unsigned int x; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + gfs_unlinked_limit(sdp); + + if (ndentry->d_inode) { + nip = get_v2ip(ndentry->d_inode); + if (ip == nip) + return 0; + } + + /* Make sure we aren't trying to move a dirctory into it's subdir */ + + if (ip->i_di.di_type == GFS_FILE_DIR && odip != ndip) { + dir_rename = TRUE; + + error = gfs_glock_nq_init(sdp->sd_rename_gl, + LM_ST_EXCLUSIVE, 0, + &r_gh); + if (error) + return error; + + error = gfs_ok_to_move(ip, ndip); + if (error) + goto fail; + } + + gfs_holder_init(odip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[0]); + gfs_holder_init(ndip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[1]); + num_gh = 2; + + if (nip) + gfs_holder_init(nip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[num_gh++]); + + if (dir_rename) + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[num_gh++]); + + error = gfs_glock_nq_m(num_gh, ghs); + if (error) + goto fail_uninit; + + /* Check out the old directory */ + + error = gfs_unlink_ok(odip, &odentry->d_name, ip); + if (error) + goto fail_gunlock; + + /* Check out the new directory */ + + if (nip) { + error = gfs_unlink_ok(ndip, &ndentry->d_name, nip); + if (error) + goto fail_gunlock; + + if (nip->i_di.di_type == GFS_FILE_DIR) { + if (nip->i_di.di_entries < 2) { + if (gfs_consist_inode(nip)) + gfs_dinode_print(&nip->i_di); + error = -EIO; + goto fail_gunlock; + } + if (nip->i_di.di_entries > 2) { + error = -ENOTEMPTY; + goto fail_gunlock; + } + } + } else { + error = inode_permission(ndir, MAY_WRITE | MAY_EXEC); + if (error) + goto fail_gunlock; + + error = gfs_dir_search(ndip, &ndentry->d_name, NULL, NULL); + switch (error) { + case -ENOENT: + error = 0; + break; + case 0: + error = -EEXIST; + default: + goto fail_gunlock; + }; + + if (odip != ndip) { + if (!ndip->i_di.di_nlink) { + error = -EINVAL; + goto fail_gunlock; + } + if (ndip->i_di.di_entries == (uint32_t)-1) { + error = -EFBIG; + goto fail_gunlock; + } + if (ip->i_di.di_type == GFS_FILE_DIR && + ndip->i_di.di_nlink == (uint32_t)-1) { + error = -EMLINK; + goto fail_gunlock; + } + } + } + + error = gfs_diradd_alloc_required(ndip, &ndentry->d_name, &alloc_required); + if (error) + goto fail_gunlock; + + if (alloc_required) { + al = gfs_alloc_get(ndip); + + error = gfs_quota_lock_m(ndip, + NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail_alloc; + + error = gfs_quota_check(ndip, ndip->i_di.di_uid, ndip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = sdp->sd_max_dirres; + + error = gfs_inplace_reserve(ndip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + Dinodes for the srcdir, srcino, dstdir, dstino. Blocks for + adding the entry to dstdir. RG bitmaps for that allocation. + One leaf block in the srcdir for removal of the entry. + One leaf block for changing .. in srcino (if it's a directory). + Two leaf blocks for removing . and .. from dstino (if it exists + and it's a directory), one unlinked tag, and one quota block. */ + + error = gfs_trans_begin(sdp, + 8 + sdp->sd_max_dirres + + al->al_rgd->rd_ri.ri_length, + 2); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + Dinodes for the srcdir, srcino, dstdir, dstino. One block for + adding the entry to dstdir. + One leaf block in the srcdir for removal of the entry. + One leaf block for changing .. in srcino (if it's a directory). + Two leaf blocks for removing . and .. from dstino (if it exists + and it's a directory), and one unlinked tag. */ + + error = gfs_trans_begin(sdp, 9, 1); + if (error) + goto fail_ipres; + } + + /* Remove the target file, if it exists */ + + if (nip) { + if (nip->i_di.di_type == GFS_FILE_DIR) + error = gfs_rmdiri(ndip, &ndentry->d_name, nip); + else + error = gfs_unlinki(ndip, &ndentry->d_name, nip); + + if (error) + goto fail_end_trans; + } + + if (dir_rename) { + error = gfs_change_nlink(ndip, +1); + if (error) + goto fail_end_trans; + error = gfs_change_nlink(odip, -1); + if (error) + goto fail_end_trans; + + name.len = 2; + name.name = ".."; + + error = gfs_dir_mvino(ip, &name, &ndip->i_num, GFS_FILE_DIR); + if (error) + goto fail_end_trans; + } + + error = gfs_dir_del(odip, &odentry->d_name); + if (error) + goto fail_end_trans; + + error = gfs_dir_add(ndip, &ndentry->d_name, &ip->i_num, ip->i_di.di_type); + if (error) + goto fail_end_trans; + + if (dir_rename) + gfs_trans_add_gl(sdp->sd_rename_gl); + + gfs_trans_end(sdp); + + if (alloc_required) { + /* Don't check al->al_alloced_meta and friends. */ + gfs_inplace_release(ndip); + gfs_quota_unlock_m(ndip); + gfs_alloc_put(ndip); + } + + gfs_glock_dq_m(num_gh, ghs); + + for (x = 0; x < num_gh; x++) + gfs_holder_uninit(&ghs[x]); + + if (dir_rename) + gfs_glock_dq_uninit(&r_gh); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (alloc_required) + gfs_inplace_release(ndip); + + fail_gunlock_q: + if (alloc_required) + gfs_quota_unlock_m(ndip); + + fail_alloc: + if (alloc_required) + gfs_alloc_put(ndip); + + fail_gunlock: + gfs_glock_dq_m(num_gh, ghs); + + fail_uninit: + for (x = 0; x < num_gh; x++) + gfs_holder_uninit(&ghs[x]); + + fail: + if (dir_rename) + gfs_glock_dq_uninit(&r_gh); + + return error; +} + +/** + * gfs_readlink - Read the value of a symlink + * @dentry: the symlink + * @buf: the buffer to read the symlink data into + * @size: the size of the buffer + * + * Returns: errno + */ + +static int +gfs_readlink(struct dentry *dentry, char *user_buf, int user_size) +{ + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + char array[GFS_FAST_NAME_SIZE], *buf = array; + unsigned int len = GFS_FAST_NAME_SIZE; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_readlinki(ip, &buf, &len); + if (error) + return error; + + if (user_size > len - 1) + user_size = len - 1; + + if (copy_to_user(user_buf, buf, user_size)) + error = -EFAULT; + else + error = user_size; + + if (buf != array) + kfree(buf); + + return error; +} + +/** + * gfs_follow_link - Follow a symbolic link + * @dentry: The dentry of the link + * @nd: Data that we pass to vfs_follow_link() + * + * This can handle symlinks of any size. It is optimised for symlinks + * under GFS_FAST_NAME_SIZE. + * + * Returns: 0 on success or error code + */ + +static void * +gfs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + char array[GFS_FAST_NAME_SIZE], *buf = array; + unsigned int len = GFS_FAST_NAME_SIZE; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_readlinki(ip, &buf, &len); + if (!error) { + error = vfs_follow_link(nd, buf); + if (buf != array) + kfree(buf); + } + + return ERR_PTR(error); +} + +/** + * gfs_permission_i - + * @inode: + * @mask: + * + * Shamelessly ripped from ext3 + * + * Returns: errno + */ + +static int +gfs_permission_i(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, gfs_check_acl); +} + +/** + * gfs_permission - + * @inode: + * @mask: + * + * Returns: errno + */ + +static int +gfs_permission(struct inode *inode, int mask) +{ + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_holder i_gh; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + return error; + + error = gfs_permission_i(inode, mask); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_setattr - Change attributes on an inode + * @dentry: The dentry which is changing + * @attr: The structure describing the change + * + * The VFS layer wants to change one or more of an inodes attributes. Write + * that change out to disk. + * + * Returns: errno + */ + +static int +gfs_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct inode *inode = dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_holder i_gh; + int error; + + atomic_inc(&sdp->sd_ops_inode); + + /* Bugzilla 203170: we'll have the same deadlock as described + * in bugzilla 173912 if + * 1. without RHEL4's DIO_CLUSTER_LOCKING, and + * 2. we come down to this line of code from do_truncate() + * where i_sem(i_mutex) and i_alloc_sem have been taken, and + * 3. grab the exclusive glock here. + * To avoid this to happen, i_alloc_sem must be dropped and trust + * be put into glock that it can carry the same protection. + * + * One issue with dropping i_alloc_sem is that the gfs_setattr() + * can be invoked from other code path without this sempaphore. + * We'll need a new rwsem function that can "up" the semaphore + * only when it is needed. Before that happens (will research the + * possibility), i_alloc_sem (now) is a meaningless lock within + * GFS. If it is ever been used by other non-directIO code, this + * hack will fall apart. + * + * wcheng@redhat.com 10/14/06 + */ + if (attr->ia_valid & ATTR_SIZE) { + up_write(&dentry->d_inode->i_alloc_sem); + } + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + + if (attr->ia_valid & ATTR_SIZE) { + down_write(&dentry->d_inode->i_alloc_sem); + } + + if (error) + return error; + + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { + error = -EPERM; + goto fail; + } + + error = inode_change_ok(inode, attr); + if (error) + goto fail; + + if (attr->ia_valid & ATTR_SIZE) { + error = inode_permission(inode, MAY_WRITE); + if (error) + goto fail; + + if (attr->ia_size != ip->i_di.di_size) { + error = vmtruncate(inode, attr->ia_size); + if (error) + goto fail; + } + + error = gfs_truncatei(ip, attr->ia_size, gfs_truncator_page); + if (error) { + if (inode->i_size != ip->i_di.di_size) + i_size_write(inode, ip->i_di.di_size); + goto fail; + } + + if ((sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) && + !gfs_is_jdata(ip)) + i_gh.gh_flags |= GL_SYNC; + } + + else if (attr->ia_valid & (ATTR_UID | ATTR_GID)) { + struct gfs_alloc *al; + struct buffer_head *dibh; + uint32_t ouid, ogid, nuid, ngid; + + ouid = ip->i_di.di_uid; + ogid = ip->i_di.di_gid; + nuid = attr->ia_uid; + ngid = attr->ia_gid; + + if (!(attr->ia_valid & ATTR_UID) || ouid == nuid) + ouid = nuid = NO_QUOTA_CHANGE; + if (!(attr->ia_valid & ATTR_GID) || ogid == ngid) + ogid = ngid = NO_QUOTA_CHANGE; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, nuid, ngid); + if (error) + goto fail_alloc; + + if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { + error = gfs_quota_check(ip, nuid, ngid); + if (error) + goto fail_gunlock_q; + } + + /* Trans may require: + one dinode block and one quota change block */ + + error = gfs_trans_begin(sdp, 1, 1); + if (error) + goto fail_gunlock_q; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + if (ouid != NO_QUOTA_CHANGE || ogid != NO_QUOTA_CHANGE) { + gfs_trans_add_quota(sdp, -ip->i_di.di_blocks, + ouid, ogid); + gfs_trans_add_quota(sdp, ip->i_di.di_blocks, + nuid, ngid); + } + + error = inode_setattr(inode, attr); + gfs_assert_warn(sdp, !error); + gfs_inode_attr_out(ip); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + gfs_trans_end(sdp); + + gfs_quota_unlock_m(ip); + gfs_alloc_put(ip); + } + + else if ((attr->ia_valid & ATTR_MODE) && IS_POSIXACL(inode)) { + error = gfs_acl_chmod(ip, attr); + if (error) + goto fail; + } + + else { + error = gfs_setattr_simple(ip, attr); + if (error) + goto fail; + } + + gfs_glock_dq_uninit(&i_gh); + + mark_inode_dirty(inode); + + return error; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_gunlock_q: + gfs_quota_unlock_m(ip); + + fail_alloc: + gfs_alloc_put(ip); + + fail: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_getattr - Read out an inode's attributes + * @mnt: ? + * @dentry: The dentry to stat + * @stat: The inode's stats + * + * Returns: errno + */ + +static int +gfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) +{ + struct inode *inode = dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_holder gh; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_inode); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &gh); + if (!error) { + generic_fillattr(inode, stat); + gfs_glock_dq_uninit(&gh); + } + + return error; +} + +/** + * gfs_setxattr - Set (or create or replace) an inode's extended attribute + * @dentry: + * @name: + * @data: + * @size: + * @flags: + * + * Returns: errno + */ + +int +gfs_setxattr(struct dentry *dentry, const char *name, + const void *data, size_t size, + int flags) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_type = gfs_ea_name2type(name, &er.er_name); + if (er.er_type == GFS_EATYPE_UNUSED) + return -EOPNOTSUPP; + er.er_data = (char *)data; + er.er_name_len = strlen(er.er_name); + er.er_data_len = size; + er.er_flags = flags; + + return gfs_ea_set(get_v2ip(dentry->d_inode), &er); +} + +/** + * gfs_getxattr - + * @dentry: + * @name: + * @data: + * @size: + * + * Returns: The number of bytes put into data, or -errno + */ + +ssize_t +gfs_getxattr(struct dentry *dentry, const char *name, + void *data, size_t size) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_type = gfs_ea_name2type(name, &er.er_name); + if (er.er_type == GFS_EATYPE_UNUSED) + return -EOPNOTSUPP; + er.er_data = data; + er.er_name_len = strlen(er.er_name); + er.er_data_len = size; + + return gfs_ea_get(get_v2ip(dentry->d_inode), &er); +} + +/** + * gfs_listxattr - + * @dentry: + * @buffer: + * @size: + * + * Returns: The number of bytes put into data, or -errno + */ + +ssize_t +gfs_listxattr(struct dentry *dentry, char *buffer, size_t size) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_data = (size) ? buffer : NULL; + er.er_data_len = size; + + return gfs_ea_list(get_v2ip(dentry->d_inode), &er); +} + +/** + * gfs_removexattr - + * @dentry: + * @name: + * + * Returns: errno + */ + +int +gfs_removexattr(struct dentry *dentry, const char *name) +{ + struct gfs_ea_request er; + + atomic_inc(&get_v2sdp(dentry->d_inode->i_sb)->sd_ops_inode); + + memset(&er, 0, sizeof(struct gfs_ea_request)); + er.er_type = gfs_ea_name2type(name, &er.er_name); + if (er.er_type == GFS_EATYPE_UNUSED) + return -EOPNOTSUPP; + er.er_name_len = strlen(er.er_name); + + return gfs_ea_remove(get_v2ip(dentry->d_inode), &er); +} + +struct inode_operations gfs_file_iops = { + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + +struct inode_operations gfs_dev_iops = { + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + +struct inode_operations gfs_dir_iops = { + .create = gfs_create, + .lookup = gfs_lookup, + .link = gfs_link, + .unlink = gfs_unlink, + .symlink = gfs_symlink, + .mkdir = gfs_mkdir, + .rmdir = gfs_rmdir, + .mknod = gfs_mknod, + .rename = gfs_rename, + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + +struct inode_operations gfs_symlink_iops = { + .readlink = gfs_readlink, + .follow_link = gfs_follow_link, + .permission = gfs_permission, + .setattr = gfs_setattr, + .getattr = gfs_getattr, + .setxattr = gfs_setxattr, + .getxattr = gfs_getxattr, + .listxattr = gfs_listxattr, + .removexattr = gfs_removexattr, +}; + --- linux-2.6.28.orig/ubuntu/gfs/fixed_div64.h +++ linux-2.6.28/ubuntu/gfs/fixed_div64.h @@ -0,0 +1,107 @@ +#ifndef __FIXED_DIV64_DOT_H__ +#define __FIXED_DIV64_DOT_H__ + +#include + +#if defined __i386__ +/* For ia32 we need to pull some tricks to get past various versions + * of the compiler which do not like us using do_div in the middle + * of large functions. + */ +static inline __u32 fixed_div64_do_div(void *a, __u32 b, int n) +{ + __u32 mod; + + switch (n) { + case 4: + mod = *(__u32 *)a % b; + *(__u32 *)a = *(__u32 *)a / b; + return mod; + case 8: + { + unsigned long __upper, __low, __high, __mod; + __u64 c = *(__u64 *)a; + __upper = __high = c >> 32; + __low = c; + if (__high) { + __upper = __high % (b); + __high = __high / (b); + } + asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); + asm("":"=A" (c):"a" (__low),"d" (__high)); + *(__u64 *)a = c; + return __mod; + } + } + + /* NOTREACHED */ + return 0; +} + +/* Side effect free 64 bit mod operation */ +static inline __u32 fixed_div64_do_mod(void *a, __u32 b, int n) +{ + switch (n) { + case 4: + return *(__u32 *)a % b; + case 8: + { + unsigned long __upper, __low, __high, __mod; + __u64 c = *(__u64 *)a; + __upper = __high = c >> 32; + __low = c; + if (__high) { + __upper = __high % (b); + __high = __high / (b); + } + asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (b), "0" (__low), "1" (__upper)); + asm("":"=A" (c):"a" (__low),"d" (__high)); + return __mod; + } + } + + /* NOTREACHED */ + return 0; +} +#else +static inline __u32 fixed_div64_do_div(void *a, __u32 b, int n) +{ + __u32 mod; + + switch (n) { + case 4: + mod = *(__u32 *)a % b; + *(__u32 *)a = *(__u32 *)a / b; + return mod; + case 8: + mod = do_div(*(__u64 *)a, b); + return mod; + } + + /* NOTREACHED */ + return 0; +} + +/* Side effect free 64 bit mod operation */ +static inline __u32 fixed_div64_do_mod(void *a, __u32 b, int n) +{ + switch (n) { + case 4: + return *(__u32 *)a % b; + case 8: + { + __u64 c = *(__u64 *)a; + return do_div(c, b); + } + } + + /* NOTREACHED */ + return 0; +} +#endif + +#undef do_div +#define do_div(a, b) fixed_div64_do_div(&(a), (b), sizeof(a)) +#define do_mod(a, b) fixed_div64_do_mod(&(a), (b), sizeof(a)) + +#endif /* __FIXED_DIV64_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ondisk.c +++ linux-2.6.28/ubuntu/gfs/ondisk.c @@ -0,0 +1,15 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" + +#define pv(struct, member, fmt) printk(" "#member" = "fmt"\n", struct->member); + +#define WANT_GFS_CONVERSION_FUNCTIONS +#include "gfs_ondisk.h" + --- linux-2.6.28.orig/ubuntu/gfs/glock.h +++ linux-2.6.28/ubuntu/gfs/glock.h @@ -0,0 +1,137 @@ +#ifndef __GFS_GLOCK_DOT_H__ +#define __GFS_GLOCK_DOT_H__ + +/* Flags for lock requests; used in gfs_holder gh_flag field. */ +/* These are defined in lm_interface.h, commented out here. +#define LM_FLAG_TRY (0x00000001) +#define LM_FLAG_TRY_1CB (0x00000002) +#define LM_FLAG_NOEXP (0x00000004) +#define LM_FLAG_ANY (0x00000008) +#define LM_FLAG_PRIORITY (0x00000010) + These are defined here. */ +#define GL_LOCAL_EXCL (0x00000020) /* Only one holder may be granted the + * lock on this node, even if SHARED */ +#define GL_ASYNC (0x00000040) /* Don't block waiting for lock ... + * must poll to wait for grant */ +#define GL_EXACT (0x00000080) /* Requested state must == current state + * for lock to be granted */ +#define GL_SKIP (0x00000100) /* Don't read from disk after grant */ +#define GL_ATIME (0x00000200) /* Update inode's ATIME after grant */ +#define GL_NOCACHE (0x00000400) /* Release glock when done, don't cache */ +#define GL_SYNC (0x00000800) /* Sync to disk when no more holders */ +#define GL_NOCANCEL (0x00001000) /* Don't ever cancel this request */ +#define GL_READPAGE (0x00002000) /* gfs_readpage() issued this lock request */ +#define GL_NOCANCEL_OTHER (0x00004000) /* Don't cancel other locks for this */ + +#define GLR_TRYFAILED (13) +#define GLR_CANCELED (14) + +static __inline__ struct gfs_holder* +gfs_glock_is_locked_by_me(struct gfs_glock *gl) +{ + struct list_head *tmp, *head; + struct gfs_holder *gh; + + /* Look in glock's list of holders for one with current task as owner */ + spin_lock(&gl->gl_spin); + for (head = &gl->gl_holders, tmp = head->next; + tmp != head; + tmp = tmp->next) { + gh = list_entry(tmp, struct gfs_holder, gh_list); + if (gh->gh_owner == current) + goto out; + } + gh = NULL; +out: + spin_unlock(&gl->gl_spin); + return gh; +} +static __inline__ int +gfs_glock_is_held_excl(struct gfs_glock *gl) +{ + return (gl->gl_state == LM_ST_EXCLUSIVE); +} +static __inline__ int +gfs_glock_is_held_dfrd(struct gfs_glock *gl) +{ + return (gl->gl_state == LM_ST_DEFERRED); +} +static __inline__ int +gfs_glock_is_held_shrd(struct gfs_glock *gl) +{ + return (gl->gl_state == LM_ST_SHARED); +} + +static __inline__ int +gfs_glock_is_blocking(struct gfs_glock *gl) +{ + int ret; + spin_lock(&gl->gl_spin); + ret = !list_empty(&gl->gl_waiters2) || !list_empty(&gl->gl_waiters3); + spin_unlock(&gl->gl_spin); + return ret; +} + +struct gfs_glock *gfs_glock_find(struct gfs_sbd *sdp, + struct lm_lockname *name); +int gfs_glock_get(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + int create, struct gfs_glock **glp); +void gfs_glock_hold(struct gfs_glock *gl); +void gfs_glock_put(struct gfs_glock *gl); + +void gfs_holder_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh); +void gfs_holder_reinit(unsigned int state, int flags, struct gfs_holder *gh); +void gfs_holder_uninit(struct gfs_holder *gh); +struct gfs_holder *gfs_holder_get(struct gfs_glock *gl, unsigned int state, + int flags); +void gfs_holder_put(struct gfs_holder *gh); + +void gfs_glock_xmote_th(struct gfs_glock *gl, unsigned int state, int flags); +void gfs_glock_drop_th(struct gfs_glock *gl); + +int gfs_glock_nq(struct gfs_holder *gh); +int gfs_glock_poll(struct gfs_holder *gh); +int gfs_glock_wait(struct gfs_holder *gh); +void gfs_glock_dq(struct gfs_holder *gh); + +void gfs_glock_prefetch(struct gfs_glock *gl, unsigned int state, int flags); +void gfs_glock_force_drop(struct gfs_glock *gl); + +int gfs_glock_be_greedy(struct gfs_glock *gl, unsigned int time); + +int gfs_glock_nq_init(struct gfs_glock *gl, unsigned int state, int flags, + struct gfs_holder *gh); +void gfs_glock_dq_uninit(struct gfs_holder *gh); +int gfs_glock_nq_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags, struct gfs_holder *gh); + +int gfs_glock_nq_m(unsigned int num_gh, struct gfs_holder *ghs); +void gfs_glock_dq_m(unsigned int num_gh, struct gfs_holder *ghs); + +void gfs_glock_prefetch_num(struct gfs_sbd *sdp, + uint64_t number, struct gfs_glock_operations *glops, + unsigned int state, int flags); + +/* Lock Value Block functions */ + +int gfs_lvb_hold(struct gfs_glock *gl); +void gfs_lvb_unhold(struct gfs_glock *gl); +void gfs_lvb_sync(struct gfs_glock *gl); + +void gfs_glock_cb(void *fsdata, unsigned int type, void *data); + +void gfs_try_toss_inode(struct gfs_sbd *sdp, struct gfs_inum *inum); +void gfs_iopen_go_callback(struct gfs_glock *gl, unsigned int state); + +void gfs_glock_schedule_for_reclaim(struct gfs_glock *gl); +void gfs_reclaim_glock(struct gfs_sbd *sdp); + +void gfs_scand_internal(struct gfs_sbd *sdp); +void gfs_gl_hash_clear(struct gfs_sbd *sdp, int wait); + +int gfs_dump_lockstate(struct gfs_sbd *sdp, struct gfs_user_buffer *ub); + +#endif /* __GFS_GLOCK_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/glops.c +++ linux-2.6.28/ubuntu/gfs/glops.c @@ -0,0 +1,664 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "page.h" +#include "recovery.h" +#include "rgrp.h" + +/** + * meta_go_sync - sync out the metadata for this glock + * @gl: the glock + * @flags: DIO_* + * + * Used for meta and rgrp glocks. + * + * Called when demoting (gfs_glock_xmote_th()) or unlocking + * (gfs_glock_drop_th() an EX glock at inter-node scope. We must flush + * to disk all dirty buffers/pages relating to this glock, and must not + * not return to caller to demote/unlock the glock until I/O is complete. + * + * This is *not* called from gfs_glock_dq(), because GL_SYNC flag is not + * currently used for anything but inode glocks. + */ + +static void +meta_go_sync(struct gfs_glock *gl, int flags) +{ + if (!(flags & DIO_METADATA)) + return; + + if (test_bit(GLF_DIRTY, &gl->gl_flags)) { + gfs_log_flush_glock(gl); + gfs_sync_buf(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + } + + /* We've synced everything, clear SYNC request and DIRTY flags */ + clear_bit(GLF_DIRTY, &gl->gl_flags); + clear_bit(GLF_SYNC, &gl->gl_flags); +} + +/** + * meta_go_inval - invalidate the metadata for this glock + * @gl: the glock + * @flags: + * + */ + +static void +meta_go_inval(struct gfs_glock *gl, int flags) +{ + if (!(flags & DIO_METADATA)) + return; + + gfs_inval_buf(gl); + gl->gl_vn++; +} + +/** + * meta_go_demote_ok - Check to see if it's ok to unlock a meta glock + * @gl: the glock + * + * Returns: TRUE if we have no cached data; ok to demote meta glock + * + * Called when trying to dump (reclaim) a glock from the glock cache, after + * determining that there is currently no holder on this node for this glock, + * and before placing LM_ST_UNLOCKED request on glock's wait-for-demote queue. + * Note that callbacks from other nodes that need a lock do *not* + * seek permission from this function before requesting a demote. + * Nor do glocks obtained with the following flags (see demote_ok()): + * -- GL_NOCACHE: gets unlocked (and not cached) immediately after use + * -- GLF_STICKY: equivalent to always getting "FALSE" from this function + * -- GLF_PREFETCH: uses its own timeout + * + * For glocks that protect on-disk data (meta, inode, and rgrp glocks), disk + * accesses are slow, while lock manipulation is usually fast. Releasing + * a lock means that we: + * -- Must sync memory-cached write data to disk immediately, before another + * node can be granted the lock (at which point that node must read the + * data from disk). + * -- Must invalidate memory-cached data that we had read from or written + * to disk. Another node can change it if we don't have a lock, so it's + * now useless to us. + * + * Then, if we re-acquire the lock again in the future, we: + * -- Must (re-)read (perhaps unchanged) data from disk into memory. + * + * All of these are painful, so it pays to retain a glock in our glock cache + * as long as we have cached data (even though we have no active holders + * for this lock on this node currently), unless/until another node needs + * to change it. This allows Linux block I/O to sync write data to disk in + * a "lazy" way, rather than forcing an immediate sync (and resultant WAIT), + * and retains current data in memory as long as possible. + * + * This also helps GFS respond to memory pressure. There is no mechanism for + * the Linux virtual memory manager to directly call into GFS to ask it to + * drop locks. So, we take a hint from what the VM does to the page cache. + * When that cache is trimmed (and we see no more pages relating to this + * glock), we trim the glock cache as well, by releasing this lock. + */ + +static int +meta_go_demote_ok(struct gfs_glock *gl) +{ + return (gl->gl_aspace->i_mapping->nrpages) ? FALSE : TRUE; +} + +/** + * inode_go_xmote_th - promote/demote (but don't unlock) an inode glock + * @gl: the glock + * @state: the requested state + * @flags: the flags passed into gfs_glock() + * + * Acquire a new glock, or change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + */ + +static void +inode_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + if (gl->gl_state != LM_ST_UNLOCKED) + gfs_inval_pte(gl); + gfs_glock_xmote_th(gl, state, flags); +} + +/** + * inode_go_xmote_bh - After promoting/demoting (but not unlocking) + * an inode glock + * @gl: the glock + * + * FIXME: This will be really broken when (no_formal_ino != no_addr) + * and gl_name.ln_number no longer refers to the dinode block #. + * + * If we've just acquired the inter-node lock for an inode, + * read the dinode block from disk (but don't wait for I/O completion). + * Exceptions (don't read if): + * Glock state is UNLOCKED. + * Glock's requesting holder's GL_SKIP flag is set. + */ + +static void +inode_go_xmote_bh(struct gfs_glock *gl) +{ + struct gfs_holder *gh = gl->gl_req_gh; + struct buffer_head *bh; + int error; + + if (gl->gl_state != LM_ST_UNLOCKED && + (!gh || !(gh->gh_flags & GL_SKIP))) { + error = gfs_dread(gl, gl->gl_name.ln_number, DIO_START, &bh); + if (!error) + brelse(bh); + } +} + +/** + * inode_go_drop_th - unlock an inode glock + * @gl: the glock + * + * Invoked from rq_demote(). + * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long) + * is being purged from our node's glock cache; we're dropping lock. + */ + +static void +inode_go_drop_th(struct gfs_glock *gl) +{ + gfs_inval_pte(gl); + gfs_glock_drop_th(gl); +} + +/** + * inode_go_sync - Sync the dirty data and/or metadata for an inode glock + * @gl: the glock protecting the inode + * @flags: DIO_METADATA -- sync inode's metadata + * DIO_DATA -- sync inode's data + * DIO_INVISIBLE -- don't clear glock's DIRTY flag when done + * + * If DIO_INVISIBLE: + * 1) Called from gfs_glock_dq(), when releasing the last holder for an EX + * glock (but glock is still in our glock cache in EX state, and might + * stay there for a few minutes). Holder had GL_SYNC flag set, asking + * for early sync (i.e. now, instead of later when we release the EX at + * inter-node scope). GL_SYNC is currently used only for inodes in + * special cases, so inode is the only type of glock for which + * DIO_INVISIBLE would apply. + * 2) Called from depend_sync_one() to sync deallocated inode metadata + * before it can be reallocated by another process or machine. Since + * this call can happen at any time during the lifetime of the + * glock, don't clear the sync bit (more data might be dirtied + * momentarily). + * Else (later): + * Called when demoting (gfs_glock_xmote_th()) or unlocking + * (gfs_glock_drop_th() an EX glock at inter-node scope. We must flush + * to disk all dirty buffers/pages relating to this glock, and must not + * return to caller to demote/unlock the glock until I/O is complete. + * + * Syncs go in following order: + * Start data page writes + * Sync metadata to log (wait to complete I/O) + * Sync metadata to in-place location (wait to complete I/O) + * Wait for data page I/O to complete + * + */ + +static void +inode_go_sync(struct gfs_glock *gl, int flags) +{ + int meta = (flags & DIO_METADATA); + int data = (flags & DIO_DATA); + + if (test_bit(GLF_DIRTY, &gl->gl_flags)) { + if (meta && data) { + gfs_sync_page(gl, flags | DIO_START); + gfs_log_flush_glock(gl); + gfs_sync_buf(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + gfs_sync_page(gl, flags | DIO_WAIT | DIO_CHECK); + } else if (meta) { + gfs_log_flush_glock(gl); + gfs_sync_buf(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + } else if (data) + gfs_sync_page(gl, flags | DIO_START | DIO_WAIT | DIO_CHECK); + } + + /* If we've synced everything, clear the SYNC request. + If we're doing the final (not early) sync, clear DIRTY */ + if (meta && data) { + if (!(flags & DIO_INVISIBLE)) + clear_bit(GLF_DIRTY, &gl->gl_flags); + clear_bit(GLF_SYNC, &gl->gl_flags); + } +} + +/** + * inode_go_inval - prepare a inode glock to be released + * @gl: the glock + * @flags: + * + */ + +static void +inode_go_inval(struct gfs_glock *gl, int flags) +{ + int meta = (flags & DIO_METADATA); + int data = (flags & DIO_DATA); + + if (meta) { + gfs_inval_buf(gl); + gl->gl_vn++; + } + if (data) + gfs_inval_page(gl); +} + +/** + * inode_go_demote_ok - Check to see if it's ok to unlock an inode glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * While other glock types (meta, rgrp) that protect disk data can be retained + * indefinitely, GFS imposes a timeout (overridden when using no_lock lock + * module) for inode glocks, even if there is still data in page cache for + * this inode. + * + * Returns: TRUE if it's ok + */ + +static int +inode_go_demote_ok(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + int demote = FALSE; + + if (!get_gl2ip(gl) && !gl->gl_aspace->i_mapping->nrpages) + demote = TRUE; + else if (!sdp->sd_args.ar_localcaching && + time_after_eq(jiffies, gl->gl_stamp + gfs_tune_get(sdp, gt_demote_secs) * HZ)) + demote = TRUE; + + return demote; +} + +/** + * inode_go_lock - operation done after an inode lock is locked by + * a first holder on this node + * @gl: the glock + * @flags: the flags passed into gfs_glock() + * + * Returns: errno + */ + +static int +inode_go_lock(struct gfs_glock *gl, int flags) +{ + struct gfs_inode *ip = get_gl2ip(gl); + int error = 0; + + if (ip && ip->i_vn != gl->gl_vn) { + error = gfs_copyin_dinode(ip); + if (!error) + gfs_inode_attr_in(ip); + } + + return error; +} + +/** + * inode_go_unlock - operation done when an inode lock is unlocked by + * a last holder on this node + * @gl: the glock + * @flags: the flags passed into gfs_gunlock() + * + */ + +static void +inode_go_unlock(struct gfs_glock *gl, int flags) +{ + struct gfs_inode *ip = get_gl2ip(gl); + + if (ip && test_bit(GLF_DIRTY, &gl->gl_flags)) + gfs_inode_attr_in(ip); + + if (ip) + gfs_flush_meta_cache(ip); +} + +/** + * inode_greedy - + * @gl: the glock + * + */ + +static void +inode_greedy(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_inode *ip = get_gl2ip(gl); + unsigned int quantum = gfs_tune_get(sdp, gt_greedy_quantum); + unsigned int max = gfs_tune_get(sdp, gt_greedy_max); + unsigned int new_time; + + spin_lock(&ip->i_spin); + + if (time_after(ip->i_last_pfault + quantum, jiffies)) { + new_time = ip->i_greedy + quantum; + if (new_time > max) + new_time = max; + } else { + new_time = ip->i_greedy - quantum; + if (!new_time || new_time > max) + new_time = 1; + } + + ip->i_greedy = new_time; + + spin_unlock(&ip->i_spin); + + gfs_inode_put(ip); +} + +/** + * rgrp_go_xmote_th - promote/demote (but don't unlock) a resource group glock + * @gl: the glock + * @state: the requested state + * @flags: the flags passed into gfs_glock() + * + * Acquire a new glock, or change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + * + * We're going to lock the lock in SHARED or EXCLUSIVE state, or + * demote it from EXCLUSIVE to SHARED (because another node needs it SHARED). + * When locking, gfs_mhc_zap() and gfs_depend_sync() are basically no-ops; + * meta-header cache and dependency lists should be empty. + * + */ + +static void +rgrp_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + + gfs_mhc_zap(rgd); + gfs_depend_sync(rgd); + gfs_glock_xmote_th(gl, state, flags); +} + +/** + * rgrp_go_drop_th - unlock a resource group glock + * @gl: the glock + * + * Invoked from rq_demote(). + * Another node needs the lock in EXCLUSIVE mode, or lock (unused for too long) + * is being purged from our node's glock cache; we're dropping lock. + */ + +static void +rgrp_go_drop_th(struct gfs_glock *gl) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + + gfs_mhc_zap(rgd); + gfs_depend_sync(rgd); + gfs_glock_drop_th(gl); +} + +/** + * rgrp_go_demote_ok - Check to see if it's ok to unlock a RG's glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * In addition to Linux page cache, we also check GFS meta-header-cache. + * + * Returns: TRUE if it's ok + */ + +static int +rgrp_go_demote_ok(struct gfs_glock *gl) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + int demote = TRUE; + + if (gl->gl_aspace->i_mapping->nrpages) + demote = FALSE; + else if (rgd && !list_empty(&rgd->rd_mhc)) /* Don't bother with lock here */ + demote = FALSE; + + return demote; +} + +/** + * rgrp_go_lock - operation done after an rgrp lock is locked by + * a first holder on this node. + * @gl: the glock + * @flags: the flags passed into gfs_glock() + * + * Returns: errno + * + * Read rgrp's header and block allocation bitmaps from disk. + */ + +static int +rgrp_go_lock(struct gfs_glock *gl, int flags) +{ + if (flags & GL_SKIP) + return 0; + return gfs_rgrp_read(get_gl2rgd(gl)); +} + +/** + * rgrp_go_unlock - operation done when an rgrp lock is unlocked by + * a last holder on this node. + * @gl: the glock + * @flags: the flags passed into gfs_gunlock() + * + * Release rgrp's bitmap buffers (read in when lock was first obtained). + * Make sure rgrp's glock's Lock Value Block has up-to-date block usage stats, + * so other nodes can see them. + */ + +static void +rgrp_go_unlock(struct gfs_glock *gl, int flags) +{ + struct gfs_rgrpd *rgd = get_gl2rgd(gl); + if (flags & GL_SKIP) + return; + gfs_rgrp_relse(rgd); + if (test_bit(GLF_DIRTY, &gl->gl_flags)) + gfs_rgrp_lvb_fill(rgd); +} + +/** + * trans_go_xmote_th - promote/demote (but don't unlock) the transaction glock + * @gl: the glock + * @state: the requested state + * @flags: the flags passed into gfs_glock() + * + * Acquire a new glock, or change an already-acquired glock to + * more/less restrictive state (other than LM_ST_UNLOCKED). + */ + +static void +trans_go_xmote_th(struct gfs_glock *gl, unsigned int state, int flags) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + + if (gl->gl_state != LM_ST_UNLOCKED && + test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { + gfs_sync_meta(sdp); + gfs_log_shutdown(sdp); + } + + gfs_glock_xmote_th(gl, state, flags); +} + +/** + * trans_go_xmote_bh - After promoting/demoting (but not unlocking) + * the transaction glock + * @gl: the glock + * + */ + +static void +trans_go_xmote_bh(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_glock *j_gl = sdp->sd_journal_gh.gh_gl; + struct gfs_log_header head; + int error; + + if (gl->gl_state != LM_ST_UNLOCKED && + test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { + j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); + + error = gfs_find_jhead(sdp, &sdp->sd_jdesc, j_gl, &head); + if (error) + gfs_consist(sdp); + if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) + gfs_consist(sdp); + + /* Initialize some head of the log stuff */ + if (!test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) { + sdp->sd_sequence = head.lh_sequence; + sdp->sd_log_head = head.lh_first + 1; + } + } +} + +/** + * trans_go_drop_th - unlock the transaction glock + * @gl: the glock + * + * Invoked from rq_demote(). + * Another node needs the lock in EXCLUSIVE mode to quiesce the filesystem + * (for journal replay, etc.). + * + * We want to sync the device even with localcaching. Remember + * that localcaching journal replay only marks buffers dirty. + */ + +static void +trans_go_drop_th(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + + if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) { + gfs_sync_meta(sdp); + gfs_log_shutdown(sdp); + } + + gfs_glock_drop_th(gl); +} + +/** + * nondisk_go_demote_ok - Check to see if it's ok to unlock a non-disk glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * We never give up a non-disk glock (unless another node needs it). + * Non-disk type used for GFS_MOUNT_LOCK, GFS_LIVE_LOCK, GFS_RENAME_LOCK. + * GFS_MOUNT_LOCK is always requested GL_NOCACHE, however, so it never uses + * this function. + * + * Returns: TRUE if it's ok + */ + +static int +nondisk_go_demote_ok(struct gfs_glock *gl) +{ + return FALSE; +} + +/** + * quota_go_demote_ok - Check to see if it's ok to unlock a quota glock + * @gl: the glock + * + * See comments for meta_go_demote_ok(). + * + * Returns: TRUE if it's ok + */ + +static int +quota_go_demote_ok(struct gfs_glock *gl) +{ + return !atomic_read(&gl->gl_lvb_count); +} + +struct gfs_glock_operations gfs_meta_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_sync = meta_go_sync, + .go_inval = meta_go_inval, + .go_demote_ok = meta_go_demote_ok, + .go_type = LM_TYPE_META +}; + +struct gfs_glock_operations gfs_inode_glops = { + .go_xmote_th = inode_go_xmote_th, + .go_xmote_bh = inode_go_xmote_bh, + .go_drop_th = inode_go_drop_th, + .go_sync = inode_go_sync, + .go_inval = inode_go_inval, + .go_demote_ok = inode_go_demote_ok, + .go_lock = inode_go_lock, + .go_unlock = inode_go_unlock, + .go_greedy = inode_greedy, + .go_type = LM_TYPE_INODE +}; + +struct gfs_glock_operations gfs_rgrp_glops = { + .go_xmote_th = rgrp_go_xmote_th, + .go_drop_th = rgrp_go_drop_th, + .go_sync = meta_go_sync, + .go_inval = meta_go_inval, + .go_demote_ok = rgrp_go_demote_ok, + .go_lock = rgrp_go_lock, + .go_unlock = rgrp_go_unlock, + .go_type = LM_TYPE_RGRP +}; + +struct gfs_glock_operations gfs_trans_glops = { + .go_xmote_th = trans_go_xmote_th, + .go_xmote_bh = trans_go_xmote_bh, + .go_drop_th = trans_go_drop_th, + .go_type = LM_TYPE_NONDISK +}; + +struct gfs_glock_operations gfs_iopen_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_callback = gfs_iopen_go_callback, + .go_type = LM_TYPE_IOPEN +}; + +struct gfs_glock_operations gfs_flock_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_type = LM_TYPE_FLOCK +}; + +struct gfs_glock_operations gfs_nondisk_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_demote_ok = nondisk_go_demote_ok, + .go_type = LM_TYPE_NONDISK +}; + +struct gfs_glock_operations gfs_quota_glops = { + .go_xmote_th = gfs_glock_xmote_th, + .go_drop_th = gfs_glock_drop_th, + .go_demote_ok = quota_go_demote_ok, + .go_type = LM_TYPE_QUOTA +}; --- linux-2.6.28.orig/ubuntu/gfs/super.h +++ linux-2.6.28/ubuntu/gfs/super.h @@ -0,0 +1,53 @@ +#ifndef __SUPER_DOT_H__ +#define __SUPER_DOT_H__ + +void gfs_tune_init(struct gfs_tune *gt); + +int gfs_check_sb(struct gfs_sbd *sdp, struct gfs_sb *sb, int silent); +int gfs_read_sb(struct gfs_sbd *sdp, struct gfs_glock *gl, int silent); +int gfs_do_upgrade(struct gfs_sbd *sdp, struct gfs_glock *gl_sb); + +static __inline__ unsigned int +gfs_num_journals(struct gfs_sbd *sdp) +{ + unsigned int num; + down(&sdp->sd_jindex_lock); + num = sdp->sd_journals; + up(&sdp->sd_jindex_lock); + return num; +} + +int gfs_jindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ji_gh); +void gfs_clear_journals(struct gfs_sbd *sdp); + +int gfs_get_jiinode(struct gfs_sbd *sdp); +int gfs_get_riinode(struct gfs_sbd *sdp); +int gfs_get_rootinode(struct gfs_sbd *sdp); +int gfs_get_qinode(struct gfs_sbd *sdp); +int gfs_get_linode(struct gfs_sbd *sdp); + +int gfs_make_fs_rw(struct gfs_sbd *sdp); +int gfs_make_fs_ro(struct gfs_sbd *sdp); + +int gfs_statfs_init(struct gfs_sbd *sdp, int flag); +int gfs_statfs_sync(struct gfs_sbd *sdp); +int gfs_statfs_fast(struct gfs_sbd *sdp, void *buf); + +struct gfs_stat_gfs { + uint64_t sg_total_blocks; + uint64_t sg_free; + uint64_t sg_used_dinode; + uint64_t sg_free_dinode; + uint64_t sg_used_meta; + uint64_t sg_free_meta; +}; + +int gfs_stat_gfs(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, + int interruptible); + +int gfs_lock_fs_check_clean(struct gfs_sbd *sdp, unsigned int state, + struct gfs_holder *t_gh); +int gfs_freeze_fs(struct gfs_sbd *sdp); +void gfs_unfreeze_fs(struct gfs_sbd *sdp); + +#endif /* __SUPER_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/mount.h +++ linux-2.6.28/ubuntu/gfs/mount.h @@ -0,0 +1,6 @@ +#ifndef __MOUNT_DOT_H__ +#define __MOUNT_DOT_H__ + +int gfs_make_args(char *data, struct gfs_args *args, int remount); + +#endif /* __MOUNT_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_thread.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_thread.c @@ -0,0 +1,367 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 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 version 2. + */ + +#include "lock_dlm.h" + +/* A lock placed on this queue is re-submitted to DLM as soon as the lock_dlm + thread gets to it. */ + +static void queue_submit(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + spin_lock(&ls->async_lock); + list_add_tail(&lp->delay_list, &ls->submit); + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +static void process_blocking(struct gdlm_lock *lp, int bast_mode) +{ + struct gdlm_ls *ls = lp->ls; + unsigned int cb = 0; + + switch (gdlm_make_lmstate(bast_mode)) { + case LM_ST_EXCLUSIVE: + cb = LM_CB_NEED_E; + break; + case LM_ST_DEFERRED: + cb = LM_CB_NEED_D; + break; + case LM_ST_SHARED: + cb = LM_CB_NEED_S; + break; + default: + gdlm_assert(0, "unknown bast mode %u", lp->bast_mode); + } + + 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; + struct lm_async_cb acb; + s16 prev_mode = lp->cur; + + memset(&acb, 0, sizeof(acb)); + + if (lp->lksb.sb_status == -DLM_ECANCEL) { + log_info("complete dlm cancel %x,%llx flags %lx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->flags); + + lp->req = lp->cur; + acb.lc_ret |= LM_OUT_CANCELED; + if (lp->cur == DLM_LOCK_IV) + lp->lksb.sb_lkid = 0; + goto out; + } + + if (test_and_clear_bit(LFL_DLM_UNLOCK, &lp->flags)) { + if (lp->lksb.sb_status != -DLM_EUNLOCK) { + log_info("unlock sb_status %d %x,%llx flags %lx", + lp->lksb.sb_status, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->flags); + return; + } + + lp->cur = DLM_LOCK_IV; + lp->req = DLM_LOCK_IV; + lp->lksb.sb_lkid = 0; + + if (test_and_clear_bit(LFL_UNLOCK_DELETE, &lp->flags)) { + gdlm_delete_lp(lp); + return; + } + goto out; + } + + if (lp->lksb.sb_flags & DLM_SBF_VALNOTVALID) + memset(lp->lksb.sb_lvbptr, 0, GDLM_LVB_SIZE); + + if (lp->lksb.sb_flags & DLM_SBF_ALTMODE) { + if (lp->req == DLM_LOCK_PR) + lp->req = DLM_LOCK_CW; + else if (lp->req == DLM_LOCK_CW) + lp->req = DLM_LOCK_PR; + } + + /* + * A canceled lock request. The lock was just taken off the delayed + * list and was never even submitted to dlm. + */ + + if (test_and_clear_bit(LFL_CANCEL, &lp->flags)) { + log_info("complete internal cancel %x,%llx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + lp->req = lp->cur; + acb.lc_ret |= LM_OUT_CANCELED; + goto out; + } + + /* + * An error occured. + */ + + if (lp->lksb.sb_status) { + /* a "normal" error */ + if ((lp->lksb.sb_status == -EAGAIN) && + (lp->lkf & DLM_LKF_NOQUEUE)) { + lp->req = lp->cur; + if (lp->cur == DLM_LOCK_IV) + lp->lksb.sb_lkid = 0; + goto out; + } + + /* this could only happen with cancels I think */ + log_info("ast sb_status %d %x,%llx flags %lx", + lp->lksb.sb_status, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->flags); + return; + } + + /* + * This is an AST for an EX->EX conversion for sync_lvb from GFS. + */ + + if (test_and_clear_bit(LFL_SYNC_LVB, &lp->flags)) { + wake_up_ast(lp); + return; + } + + /* + * A lock has been demoted to NL because it initially completed during + * BLOCK_LOCKS. Now it must be requested in the originally requested + * mode. + */ + + if (test_and_clear_bit(LFL_REREQUEST, &lp->flags)) { + gdlm_assert(lp->req == DLM_LOCK_NL, "%x,%llx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + gdlm_assert(lp->prev_req > DLM_LOCK_NL, "%x,%llx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + + lp->cur = DLM_LOCK_NL; + lp->req = lp->prev_req; + lp->prev_req = DLM_LOCK_IV; + lp->lkf &= ~DLM_LKF_CONVDEADLK; + + set_bit(LFL_NOCACHE, &lp->flags); + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && + !test_bit(LFL_NOBLOCK, &lp->flags)) + gdlm_queue_delayed(lp); + else + queue_submit(lp); + return; + } + + /* + * A request is granted during dlm recovery. It may be granted + * because the locks of a failed node were cleared. In that case, + * there may be inconsistent data beneath this lock and we must wait + * for recovery to complete to use it. When gfs recovery is done this + * granted lock will be converted to NL and then reacquired in this + * granted state. + */ + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && + !test_bit(LFL_NOBLOCK, &lp->flags) && + lp->req != DLM_LOCK_NL) { + + lp->cur = lp->req; + lp->prev_req = lp->req; + lp->req = DLM_LOCK_NL; + lp->lkf |= DLM_LKF_CONVERT; + lp->lkf &= ~DLM_LKF_CONVDEADLK; + + log_debug("rereq %x,%llx id %x %d,%d", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->lksb.sb_lkid, lp->cur, lp->req); + + set_bit(LFL_REREQUEST, &lp->flags); + queue_submit(lp); + return; + } + + /* + * DLM demoted the lock to NL before it was granted so GFS must be + * told it cannot cache data for this lock. + */ + + if (lp->lksb.sb_flags & DLM_SBF_DEMOTED) + set_bit(LFL_NOCACHE, &lp->flags); + +out: + /* + * This is an internal lock_dlm lock + */ + + if (test_bit(LFL_INLOCK, &lp->flags)) { + clear_bit(LFL_NOBLOCK, &lp->flags); + lp->cur = lp->req; + wake_up_ast(lp); + return; + } + + /* + * Normal completion of a lock request. Tell GFS it now has the lock. + */ + + clear_bit(LFL_NOBLOCK, &lp->flags); + lp->cur = lp->req; + + acb.lc_name = lp->lockname; + acb.lc_ret |= gdlm_make_lmstate(lp->cur); + + if (!test_and_clear_bit(LFL_NOCACHE, &lp->flags) && + (lp->cur > DLM_LOCK_NL) && (prev_mode > DLM_LOCK_NL)) + acb.lc_ret |= LM_OUT_CACHEABLE; + + ls->fscb(ls->sdp, LM_CB_ASYNC, &acb); +} + +static inline int no_work(struct gdlm_ls *ls, int blocking) +{ + int ret; + + spin_lock(&ls->async_lock); + ret = list_empty(&ls->complete) && list_empty(&ls->submit); + if (ret && blocking) + ret = list_empty(&ls->blocking); + spin_unlock(&ls->async_lock); + + return ret; +} + +static inline int check_drop(struct gdlm_ls *ls) +{ + if (!ls->drop_locks_count) + return 0; + + if (time_after(jiffies, ls->drop_time + ls->drop_locks_period * HZ)) { + ls->drop_time = jiffies; + if (ls->all_locks_count >= ls->drop_locks_count) + return 1; + } + return 0; +} + +static int gdlm_thread(void *data, int blist) +{ + struct gdlm_ls *ls = (struct gdlm_ls *) data; + struct gdlm_lock *lp = NULL; + uint8_t complete, blocking, submit, drop; + + /* Only thread1 is allowed to do blocking callbacks since gfs + may wait for a completion callback within a blocking cb. */ + + while (!kthread_should_stop()) { + wait_event_interruptible(ls->thread_wait, + !no_work(ls, blist) || kthread_should_stop()); + + complete = blocking = submit = drop = 0; + + spin_lock(&ls->async_lock); + + if (blist && !list_empty(&ls->blocking)) { + lp = list_entry(ls->blocking.next, struct gdlm_lock, + blist); + list_del_init(&lp->blist); + blocking = lp->bast_mode; + lp->bast_mode = 0; + } else if (!list_empty(&ls->complete)) { + lp = list_entry(ls->complete.next, struct gdlm_lock, + clist); + list_del_init(&lp->clist); + complete = 1; + } else if (!list_empty(&ls->submit)) { + lp = list_entry(ls->submit.next, struct gdlm_lock, + delay_list); + list_del_init(&lp->delay_list); + submit = 1; + } + + drop = check_drop(ls); + spin_unlock(&ls->async_lock); + + if (complete) + process_complete(lp); + + else if (blocking) + process_blocking(lp, blocking); + + else if (submit) + gdlm_do_lock(lp); + + if (drop) + ls->fscb(ls->sdp, LM_CB_DROPLOCKS, NULL); + + schedule(); + } + + return 0; +} + +static int gdlm_thread1(void *data) +{ + return gdlm_thread(data, 1); +} + +static int gdlm_thread2(void *data) +{ + return gdlm_thread(data, 0); +} + +int gdlm_init_threads(struct gdlm_ls *ls) +{ + struct task_struct *p; + int error; + + p = kthread_run(gdlm_thread1, ls, "lock_dlm1"); + error = IS_ERR(p); + if (error) { + log_error("can't start lock_dlm1 thread %d", error); + return error; + } + ls->thread1 = p; + + p = kthread_run(gdlm_thread2, ls, "lock_dlm2"); + error = IS_ERR(p); + if (error) { + log_error("can't start lock_dlm2 thread %d", error); + kthread_stop(ls->thread1); + return error; + } + ls->thread2 = p; + + return 0; +} + +void gdlm_release_threads(struct gdlm_ls *ls) +{ + kthread_stop(ls->thread1); + kthread_stop(ls->thread2); +} + --- linux-2.6.28.orig/ubuntu/gfs/recovery.c +++ linux-2.6.28/ubuntu/gfs/recovery.c @@ -0,0 +1,780 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "lm.h" +#include "lops.h" +#include "recovery.h" + +#define bn2seg(bn) (((uint32_t)((bn) - jdesc->ji_addr)) / sdp->sd_sb.sb_seg_size) +#define seg2bn(seg) ((seg) * sdp->sd_sb.sb_seg_size + jdesc->ji_addr) + +struct dirty_j { + struct list_head dj_list; + unsigned int dj_jid; + struct gfs_jindex dj_desc; +}; + +/** + * gfs_add_dirty_j - add a jid to the list of dirty journals + * @sdp: the filesystem + * @jid: the journal ID number + * + */ + +void +gfs_add_dirty_j(struct gfs_sbd *sdp, unsigned int jid) +{ + struct dirty_j *dj; + + dj = gmalloc(sizeof(struct dirty_j)); + memset(dj, 0, sizeof(struct dirty_j)); + + dj->dj_jid = jid; + + spin_lock(&sdp->sd_dirty_j_lock); + list_add(&dj->dj_list, &sdp->sd_dirty_j); + spin_unlock(&sdp->sd_dirty_j_lock); +} + +/** + * get_dirty_j - return a dirty journal from the list + * @sdp: the filesystem + * + * Returns: a struct dirty_j or NULL + */ + +static struct dirty_j * +get_dirty_j(struct gfs_sbd *sdp) +{ + struct dirty_j *dj = NULL; + + spin_lock(&sdp->sd_dirty_j_lock); + if (!list_empty(&sdp->sd_dirty_j)) { + dj = list_entry(sdp->sd_dirty_j.prev, struct dirty_j, dj_list); + list_del(&dj->dj_list); + } + spin_unlock(&sdp->sd_dirty_j_lock); + + return dj; +} + +/** + * gfs_clear_dirty_j - destroy the list of dirty journals + * @sdp: the filesystem + * + */ + +void +gfs_clear_dirty_j(struct gfs_sbd *sdp) +{ + struct dirty_j *dj; + for (;;) { + dj = get_dirty_j(sdp); + if (!dj) + break; + kfree(dj); + } +} + +/** + * gfs_log_header - read the log header for a given segment + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @seg: the segment to look at + * @lh: the log header to return + * + * Read the log header for a given segement in a given journal. Do a few + * sanity checks on it. + * + * Returns: 0 on success, 1 if the header was invalid or incomplete and, errno on error + */ + +static int +get_log_header(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint32_t seg, struct gfs_log_header *lh) +{ + struct buffer_head *bh; + struct gfs_log_header lh2; + int error; + + error = gfs_dread(gl, seg2bn(seg), DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + gfs_log_header_in(lh, bh->b_data); + gfs_log_header_in(&lh2, + bh->b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + brelse(bh); + + if (memcmp(lh, &lh2, sizeof(struct gfs_log_header)) != 0 || + lh->lh_header.mh_magic != GFS_MAGIC || + lh->lh_header.mh_type != GFS_METATYPE_LH) + error = 1; + + return error; +} + +/** + * find_good_lh - find a good log header + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @seg: the segment to start searching from (it's also filled in with a new value.) + * @lh: the log header to fill in + * @forward: if true search forward in the log, else search backward + * + * Call get_log_header() to get a log header for a segment, but if the + * segment is bad, either scan forward or backward until we find a good one. + * + * Returns: errno + */ + +static int +find_good_lh(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint32_t *seg, struct gfs_log_header *lh, + int forward) +{ + int error; + uint32_t orig_seg = *seg; + + for (;;) { + error = get_log_header(sdp, jdesc, gl, *seg, lh); + if (error <= 0) + return error; + + if (forward) { + if (++*seg == jdesc->ji_nsegment) + *seg = 0; + } else { + if ((*seg)-- == 0) + *seg = jdesc->ji_nsegment - 1; + } + + if (*seg == orig_seg) { + gfs_consist(sdp); + return -EIO; + } + } +} + +/** + * verify_jhead - make sure we've found the head of the log + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @head: this is filled in with the log descriptor of the head + * + * At this point, seg and lh should be either the head of the log or just + * before. Scan forward until we find the head. + * + * Returns: errno + */ + +static int +verify_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head) +{ + struct gfs_log_header lh; + uint32_t seg; + int error; + + seg = bn2seg(head->lh_first); + + for (;;) { + if (++seg == jdesc->ji_nsegment) + seg = 0; + + error = get_log_header(sdp, jdesc, gl, seg, &lh); + if (error < 0) + return error; + + if (error == 1) + continue; + if (lh.lh_sequence == head->lh_sequence) + continue; + + if (lh.lh_sequence < head->lh_sequence) + break; + + memcpy(head, &lh, sizeof(struct gfs_log_header)); + } + + return 0; +} + +/** + * gfs_find_jhead - find the head of a log + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @head: the log descriptor for the head of the log is returned here + * + * Do a binary search of a journal and find the valid log entry with the + * highest sequence number. (i.e. the log head) + * + * Returns: errno + */ + +int +gfs_find_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head) +{ + struct gfs_log_header lh; + uint32_t seg1, seg2, seg_m; + int error; + uint64_t lh1_sequence; + + seg1 = 0; + seg2 = jdesc->ji_nsegment - 1; + + for (;;) { + seg_m = (seg1 + seg2) / 2; + + error = find_good_lh(sdp, jdesc, gl, &seg1, &lh, TRUE); + if (error) + break; + + if (seg1 == seg_m) { + error = verify_jhead(sdp, jdesc, gl, &lh); + if (unlikely(error)) + printk("GFS: verify_jhead error=%d\n", error); + else + memcpy(head, &lh, sizeof(struct gfs_log_header)); + break; + } + + lh1_sequence = lh.lh_sequence; + + error = find_good_lh(sdp, jdesc, gl, &seg_m, &lh, FALSE); + if (error) + break; + + if (lh1_sequence <= lh.lh_sequence) + seg1 = seg_m; + else + seg2 = seg_m; + } + + return error; +} + +/** + * gfs_increment_blkno - move to the next block in a journal + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @addr: the block number to increment + * @skip_header: if this is TRUE, skip log headers + * + * Replace @addr with the location of the next block in the log. + * Take care of journal wrap and skip of log header if necessary. + * + * Returns: errno + */ + +int +gfs_increment_blkno(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t *addr, int skip_headers) +{ + struct gfs_log_header header; + int error; + + (*addr)++; + + /* Handle journal wrap */ + + if (*addr == seg2bn(jdesc->ji_nsegment)) + *addr -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; + + gfs_start_ra(gl, *addr, + jdesc->ji_addr + + jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size - *addr); + + /* Handle landing on a header block */ + + if (skip_headers && !do_mod(*addr, sdp->sd_sb.sb_seg_size)) { + error = get_log_header(sdp, jdesc, gl, bn2seg(*addr), &header); + if (error < 0) + return error; + + if (error) { /* Corrupt headers here are bad */ + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: *addr = %"PRIu64"\n", + sdp->sd_fsname, *addr); + return -EIO; + } + if (header.lh_first == *addr) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: *addr = %"PRIu64"\n", + sdp->sd_fsname, *addr); + gfs_log_header_print(&header); + return -EIO; + } + + (*addr)++; + /* Can't wrap here */ + } + + return 0; +} + +/** + * foreach_descriptor - go through the active part of the log + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @start: the first log header in the active region + * @end: the last log header (don't process the contents of this entry)) + * @pass: the recovery pass + * + * Call a given function once for every log descriptor in the active + * portion of the log. + * + * Returns: errno + */ + +static int +foreach_descriptor(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, uint64_t end, + unsigned int pass) +{ + struct gfs_log_header header; + struct gfs_log_descriptor desc; + struct buffer_head *bh; + int error = 0; + + while (start != end) { + if (do_mod(start, sdp->sd_sb.sb_seg_size)) { + gfs_consist(sdp); + return -EIO; + } + + error = get_log_header(sdp, jdesc, gl, bn2seg(start), &header); + if (error < 0) + return error; + + if (error) { /* Corrupt headers here are bad */ + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: start = %"PRIu64"\n", + sdp->sd_fsname, start); + return -EIO; + } + if (header.lh_first != start) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: start = %"PRIu64"\n", + sdp->sd_fsname, start); + gfs_log_header_print(&header); + return -EIO; + } + + start++; + + for (;;) { + error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + if (gfs_metatype_check(sdp, bh, GFS_METATYPE_LD)) { + brelse(bh); + return -EIO; + } + + gfs_desc_in(&desc, bh->b_data); + brelse(bh); + + if (desc.ld_type != GFS_LOG_DESC_LAST) { + error = LO_SCAN_ELEMENTS(sdp, jdesc, gl, start, + &desc, pass); + if (error) + return error; + + while (desc.ld_length--) { + error = gfs_increment_blkno(sdp, jdesc, gl, + &start, TRUE); + if (error) + return error; + } + } else { + while (desc.ld_length--) { + error = gfs_increment_blkno(sdp, jdesc, gl, + &start, + !!desc.ld_length); + if (error) + return error; + } + + break; + } + } + } + + return error; +} + +/** + * clean_journal - mark a dirty journal as being clean + * @sdp: the filesystem + * @jdesc: the journal + * @gl: the journal's glock + * @head: the head journal to start from + * + * Returns: errno + */ + +static int noinline +clean_journal(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head) +{ + struct gfs_log_header lh; + struct gfs_log_descriptor desc; + struct buffer_head *bh; + uint32_t seg; + uint64_t blkno; + int error; + + seg = bn2seg(head->lh_first); + + for (;;) { + if (++seg == jdesc->ji_nsegment) + seg = 0; + + error = get_log_header(sdp, jdesc, gl, seg, &lh); + if (error < 0) + return error; + + /* Rewrite corrupt header blocks */ + + if (error == 1) { + bh = gfs_dgetblk(gl, seg2bn(seg)); + + gfs_prep_new_buffer(bh); + gfs_buffer_clear(bh); + gfs_log_header_out(head, bh->b_data); + gfs_log_header_out(head, + bh->b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + brelse(bh); + if (error) + return error; + } + + /* Stop when we get to the end of the log. */ + + if (lh.lh_sequence < head->lh_sequence) + break; + } + + /* Build a "last" descriptor for the transaction we are + about to commit by writing the shutdown header. */ + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_LAST; + desc.ld_length = 0; + + for (blkno = head->lh_first + 1; blkno != seg2bn(seg);) { + if (do_mod(blkno, sdp->sd_sb.sb_seg_size)) + desc.ld_length++; + if (++blkno == seg2bn(jdesc->ji_nsegment)) + blkno -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; + } + + /* Write the descriptor */ + + bh = gfs_dgetblk(gl, head->lh_first + 1); + + gfs_prep_new_buffer(bh); + gfs_buffer_clear(bh); + gfs_desc_out(&desc, bh->b_data); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + brelse(bh); + if (error) + return error; + + /* Build a log header that says the journal is clean */ + + memset(&lh, 0, sizeof(struct gfs_log_header)); + lh.lh_header.mh_magic = GFS_MAGIC; + lh.lh_header.mh_type = GFS_METATYPE_LH; + lh.lh_header.mh_format = GFS_FORMAT_LH; + lh.lh_flags = GFS_LOG_HEAD_UNMOUNT; + lh.lh_first = seg2bn(seg); + lh.lh_sequence = head->lh_sequence + 1; + /* Don't care about tail */ + lh.lh_last_dump = head->lh_last_dump; + + /* Write the header */ + + bh = gfs_dgetblk(gl, lh.lh_first); + + gfs_prep_new_buffer(bh); + gfs_buffer_clear(bh); + gfs_log_header_out(&lh, bh->b_data); + gfs_log_header_out(&lh, + bh->b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + brelse(bh); + + return error; +} + +/** + * gfs_recover_journal - recover a given journal + * @sdp: the filesystem + * @jid: the number of the journal to recover + * @jdesc: the struct gfs_jindex describing the journal + * @wait: Don't return until the journal is clean (or an error is encountered) + * + * Acquire the journal's lock, check to see if the journal is clean, and + * do recovery if necessary. + * + * Returns: errno + */ + +int +gfs_recover_journal(struct gfs_sbd *sdp, + unsigned int jid, struct gfs_jindex *jdesc, + int wait) +{ + struct gfs_log_header *head; + struct gfs_holder j_gh, t_gh; + unsigned long t; + int error; + + printk("GFS: fsid=%s: jid=%u: Trying to acquire journal lock...\n", + sdp->sd_fsname, jid); + + /* Acquire the journal lock so we can do recovery */ + + error = gfs_glock_nq_num(sdp, + jdesc->ji_addr, &gfs_meta_glops, + LM_ST_EXCLUSIVE, + LM_FLAG_NOEXP | + ((wait) ? 0 : LM_FLAG_TRY) | + GL_NOCACHE, &j_gh); + switch (error) { + case 0: + break; + + case GLR_TRYFAILED: + printk("GFS: fsid=%s: jid=%u: Busy\n", sdp->sd_fsname, jid); + error = 0; + + default: + goto fail; + }; + + printk("GFS: fsid=%s: jid=%u: Looking at journal...\n", + sdp->sd_fsname, jid); + + head = kmalloc(sizeof(struct gfs_log_header), GFP_KERNEL); + if (!head) { + printk("GFS: fsid=%s jid=%u: Can't replay: Not enough memory", + sdp->sd_fsname, jid); + goto fail_gunlock; + } + + error = gfs_find_jhead(sdp, jdesc, j_gh.gh_gl, head); + if (error) + goto fail_header; + + if (!(head->lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + printk("GFS: fsid=%s: jid=%u: Can't replay: read-only FS\n", + sdp->sd_fsname, jid); + error = -EROFS; + goto fail_header; + } + + printk("GFS: fsid=%s: jid=%u: Acquiring the transaction lock...\n", + sdp->sd_fsname, jid); + + t = jiffies; + + /* Acquire an exclusive hold on the transaction lock */ + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_EXCLUSIVE, + LM_FLAG_NOEXP | + LM_FLAG_PRIORITY | + GL_NOCANCEL | + GL_NOCACHE, + &t_gh); + if (error) + goto fail_header; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + printk("GFS: fsid=%s: jid=%u: Can't replay: read-only FS\n", + sdp->sd_fsname, jid); + error = -EROFS; + goto fail_gunlock_tr; + } + + printk("GFS: fsid=%s: jid=%u: Replaying journal...\n", + sdp->sd_fsname, jid); + + set_bit(GLF_DIRTY, &j_gh.gh_gl->gl_flags); + + LO_BEFORE_SCAN(sdp, jid, head, GFS_RECPASS_A1); + + error = foreach_descriptor(sdp, jdesc, j_gh.gh_gl, + head->lh_tail, head->lh_first, + GFS_RECPASS_A1); + if (error) + goto fail_gunlock_tr; + + LO_AFTER_SCAN(sdp, jid, GFS_RECPASS_A1); + + gfs_replay_wait(sdp); + + error = clean_journal(sdp, jdesc, j_gh.gh_gl, head); + if (error) + goto fail_gunlock_tr; + + gfs_glock_dq_uninit(&t_gh); + + t = DIV_RU(jiffies - t, HZ); + + printk("GFS: fsid=%s: jid=%u: Journal replayed in %lus\n", + sdp->sd_fsname, jid, t); + } + + gfs_lm_recovery_done(sdp, jid, LM_RD_SUCCESS); + + kfree(head); + + gfs_glock_dq_uninit(&j_gh); + + printk("GFS: fsid=%s: jid=%u: Done\n", sdp->sd_fsname, jid); + + return 0; + + fail_gunlock_tr: + gfs_replay_wait(sdp); + gfs_glock_dq_uninit(&t_gh); + + fail_header: + kfree(head); + + fail_gunlock: + gfs_glock_dq_uninit(&j_gh); + + printk("GFS: fsid=%s: jid=%u: %s\n", + sdp->sd_fsname, jid, (error) ? "Failed" : "Done"); + + fail: + gfs_lm_recovery_done(sdp, jid, LM_RD_GAVEUP); + + return error; +} + +/** + * gfs_check_journals - Recover any dirty journals + * @sdp: the filesystem + * + */ + +void +gfs_check_journals(struct gfs_sbd *sdp) +{ + struct dirty_j *dj; + + for (;;) { + dj = get_dirty_j(sdp); + if (!dj) + break; + + down(&sdp->sd_jindex_lock); + + if (dj->dj_jid != sdp->sd_lockstruct.ls_jid && + dj->dj_jid < sdp->sd_journals) { + memcpy(&dj->dj_desc, + sdp->sd_jindex + dj->dj_jid, + sizeof(struct gfs_jindex)); + up(&sdp->sd_jindex_lock); + + gfs_recover_journal(sdp, + dj->dj_jid, &dj->dj_desc, + FALSE); + + } else { + up(&sdp->sd_jindex_lock); + gfs_lm_recovery_done(sdp, dj->dj_jid, LM_RD_GAVEUP); + } + + kfree(dj); + } +} + +/** + * gfs_recover_dump - recover the log elements in this machine's journal + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_recover_dump(struct gfs_sbd *sdp) +{ + struct gfs_log_header head; + int error; + + error = gfs_find_jhead(sdp, &sdp->sd_jdesc, sdp->sd_journal_gh.gh_gl, + &head); + if (error) + goto fail; + + if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + gfs_consist(sdp); + return -EIO; + } + if (!head.lh_last_dump) + return error; + + printk("GFS: fsid=%s: Scanning for log elements...\n", + sdp->sd_fsname); + + LO_BEFORE_SCAN(sdp, sdp->sd_lockstruct.ls_jid, &head, GFS_RECPASS_B1); + + error = foreach_descriptor(sdp, &sdp->sd_jdesc, sdp->sd_journal_gh.gh_gl, + head.lh_last_dump, head.lh_first, + GFS_RECPASS_B1); + if (error) + goto fail; + + LO_AFTER_SCAN(sdp, sdp->sd_lockstruct.ls_jid, GFS_RECPASS_B1); + + /* We need to make sure if we crash during the next log dump that + all intermediate headers in the transaction point to the last + log dump before the one we're making so we don't lose it. */ + + sdp->sd_log_dump_last = head.lh_last_dump; + + printk("GFS: fsid=%s: Done\n", sdp->sd_fsname); + + return 0; + + fail: + printk("GFS: fsid=%s: Failed\n", sdp->sd_fsname); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/lm.c +++ linux-2.6.28/ubuntu/gfs/lm.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include + +#include "gfs_ondisk.h" +#include "gfs.h" +#include "incore.h" +#include "glock.h" +#include "lm.h" +#include "super.h" +#include "util.h" +#include "lvb.h" + +/** + * gfs_lm_mount - mount a locking protocol + * @sdp: the filesystem + * @args: mount arguements + * @silent: if 1, don't complain if the FS isn't a GFS fs + * + * Returns: errno + */ + +int gfs_lm_mount(struct gfs_sbd *sdp, int silent) +{ + char *proto = sdp->sd_proto_name; + char *table = sdp->sd_table_name; + int flags = 0; + int error; + + if (sdp->sd_args.ar_spectator) + flags |= LM_MFLAG_SPECTATOR; + + printk("Trying to join cluster \"%s\", \"%s\"\n", proto, table); + + error = gfs_mount_lockproto(proto, table, sdp->sd_args.ar_hostdata, + gfs_glock_cb, sdp, + GFS_MIN_LVB_SIZE, flags, + &sdp->sd_lockstruct, &sdp->sd_kobj); + if (error) { + printk("can't mount proto=%s, table=%s, hostdata=%s\n", + proto, table, sdp->sd_args.ar_hostdata); + goto out; + } + + if (gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_lockspace) || + gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_ops) || + gfs_assert_warn(sdp, sdp->sd_lockstruct.ls_lvb_size >= + GFS_MIN_LVB_SIZE)) { + gfs_unmount_lockproto(&sdp->sd_lockstruct); + goto out; + } + + if (sdp->sd_args.ar_spectator) + snprintf(sdp->sd_fsname, 256, "%s.s", table); + else + snprintf(sdp->sd_fsname, 256, "%s.%u", table, + sdp->sd_lockstruct.ls_jid); + + printk("Joined cluster. Now mounting FS...\n"); + if ((sdp->sd_lockstruct.ls_flags & LM_LSFLAG_LOCAL) && + !sdp->sd_args.ar_ignore_local_fs) { + sdp->sd_args.ar_localflocks = 1; + sdp->sd_args.ar_localcaching = 1; + } + + out: + return error; +} + +void gfs_lm_others_may_mount(struct gfs_sbd *sdp) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_others_may_mount( + sdp->sd_lockstruct.ls_lockspace); +} + +void gfs_lm_unmount(struct gfs_sbd *sdp) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + gfs_unmount_lockproto(&sdp->sd_lockstruct); +} + +int gfs_lm_withdraw(struct gfs_sbd *sdp, char *fmt, ...) +{ + va_list args; + + if (test_and_set_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + return 0; + + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); + + printk("GFS: fsid=%s: about to withdraw from the cluster\n", + sdp->sd_fsname); + + BUG_ON(sdp->sd_args.ar_debug); + + printk("GFS: fsid=%s: telling LM to withdraw\n", + sdp->sd_fsname); + + gfs_withdraw_lockproto(&sdp->sd_lockstruct); + + printk("GFS: fsid=%s: withdrawn\n", + sdp->sd_fsname); + dump_stack(); + + return -1; +} + +int gfs_lm_get_lock(struct gfs_sbd *sdp, struct lm_lockname *name, + void **lockp) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_get_lock( + sdp->sd_lockstruct.ls_lockspace, name, lockp); + return error; +} + +void gfs_lm_put_lock(struct gfs_sbd *sdp, void *lock) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_put_lock(lock); +} + +unsigned int gfs_lm_lock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state, unsigned int req_state, + unsigned int flags) +{ + int ret; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + ret = 0; + else + ret = sdp->sd_lockstruct.ls_ops->lm_lock(lock, + cur_state, + req_state, flags); + return ret; +} + +unsigned int gfs_lm_unlock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state) +{ + int ret; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + ret = 0; + else + ret = sdp->sd_lockstruct.ls_ops->lm_unlock(lock, cur_state); + return ret; +} + +void gfs_lm_cancel(struct gfs_sbd *sdp, void *lock) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_cancel(lock); +} + +int gfs_lm_hold_lvb(struct gfs_sbd *sdp, void *lock, char **lvbp) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_hold_lvb(lock, lvbp); + return error; +} + +void gfs_lm_unhold_lvb(struct gfs_sbd *sdp, void *lock, char *lvb) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_unhold_lvb(lock, lvb); +} + +#if 0 +void gfs_lm_sync_lvb(struct gfs_sbd *sdp, void *lock, char *lvb) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_sync_lvb(lock, lvb); +} +#endif + +int gfs_lm_plock_get(struct gfs_sbd *sdp, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_plock_get( + sdp->sd_lockstruct.ls_lockspace, + name, file, fl); + return error; +} + +int gfs_lm_plock(struct gfs_sbd *sdp, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_plock( + sdp->sd_lockstruct.ls_lockspace, + name, file, cmd, fl); + return error; +} + +int gfs_lm_punlock(struct gfs_sbd *sdp, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + int error; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + else + error = sdp->sd_lockstruct.ls_ops->lm_punlock( + sdp->sd_lockstruct.ls_lockspace, + name, file, fl); + return error; +} + +void gfs_lm_recovery_done(struct gfs_sbd *sdp, unsigned int jid, + unsigned int message) +{ + if (likely(!test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + sdp->sd_lockstruct.ls_ops->lm_recovery_done( + sdp->sd_lockstruct.ls_lockspace, jid, message); +} + --- linux-2.6.28.orig/ubuntu/gfs/super.c +++ linux-2.6.28/ubuntu/gfs/super.c @@ -0,0 +1,1274 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "file.h" +#include "format.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "quota.h" +#include "recovery.h" +#include "rgrp.h" +#include "super.h" +#include "unlinked.h" +#include "trans.h" + +/** + * gfs_tune_init - Fill a gfs_tune structure with default values + * @gt: tune + * + */ + +void +gfs_tune_init(struct gfs_tune *gt) +{ + spin_lock_init(>->gt_spin); + + gt->gt_ilimit1 = 100; + gt->gt_ilimit1_tries = 3; + gt->gt_ilimit1_min = 1; + gt->gt_ilimit2 = 500; + gt->gt_ilimit2_tries = 10; + gt->gt_ilimit2_min = 3; + gt->gt_demote_secs = 300; + gt->gt_incore_log_blocks = 1024; + gt->gt_jindex_refresh_secs = 60; + gt->gt_depend_secs = 60; + gt->gt_scand_secs = 5; + gt->gt_recoverd_secs = 60; + gt->gt_logd_secs = 1; + gt->gt_quotad_secs = 5; + gt->gt_inoded_secs = 15; + gt->gt_glock_purge = 0; + gt->gt_quota_simul_sync = 64; + gt->gt_quota_warn_period = 10; + gt->gt_atime_quantum = 3600; + gt->gt_quota_quantum = 60; + gt->gt_quota_scale_num = 1; + gt->gt_quota_scale_den = 1; + gt->gt_quota_enforce = 1; + gt->gt_quota_account = 1; + gt->gt_new_files_jdata = 0; + gt->gt_new_files_directio = 0; + gt->gt_max_atomic_write = 4 << 20; + gt->gt_max_readahead = 1 << 18; + gt->gt_lockdump_size = 131072; + gt->gt_stall_secs = 600; + gt->gt_complain_secs = 10; + gt->gt_reclaim_limit = 5000; + gt->gt_entries_per_readdir = 32; + gt->gt_prefetch_secs = 10; + gt->gt_statfs_slots = 64; + gt->gt_max_mhc = 10000; + gt->gt_greedy_default = HZ / 10; + gt->gt_greedy_quantum = HZ / 40; + gt->gt_greedy_max = HZ / 4; + gt->gt_rgrp_try_threshold = 100; + gt->gt_statfs_fast = 0; +} + +/** + * gfs_check_sb - Check superblock + * @sdp: the filesystem + * @sb: The superblock + * @silent: Don't print a message if the check fails + * + * Checks the version code of the FS is one that we understand how to + * read and that the sizes of the various on-disk structures have not + * changed. + */ + +int +gfs_check_sb(struct gfs_sbd *sdp, struct gfs_sb *sb, int silent) +{ + unsigned int x; + + if (sb->sb_header.mh_magic != GFS_MAGIC || + sb->sb_header.mh_type != GFS_METATYPE_SB) { + if (!silent) + printk("GFS: not a GFS filesystem\n"); + return -EINVAL; + } + + /* If format numbers match exactly, we're done. */ + + if (sb->sb_fs_format == GFS_FORMAT_FS && + sb->sb_multihost_format == GFS_FORMAT_MULTI) + return 0; + + if (sb->sb_fs_format != GFS_FORMAT_FS) { + for (x = 0; gfs_old_fs_formats[x]; x++) + if (gfs_old_fs_formats[x] == sb->sb_fs_format) + break; + + if (!gfs_old_fs_formats[x]) { + printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", + GFS_FORMAT_FS, GFS_FORMAT_MULTI, + sb->sb_fs_format, sb->sb_multihost_format); + printk("GFS: I don't know how to upgrade this FS\n"); + return -EINVAL; + } + } + + if (sb->sb_multihost_format != GFS_FORMAT_MULTI) { + for (x = 0; gfs_old_multihost_formats[x]; x++) + if (gfs_old_multihost_formats[x] == sb->sb_multihost_format) + break; + + if (!gfs_old_multihost_formats[x]) { + printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", + GFS_FORMAT_FS, GFS_FORMAT_MULTI, + sb->sb_fs_format, sb->sb_multihost_format); + printk("GFS: I don't know how to upgrade this FS\n"); + return -EINVAL; + } + } + + if (!sdp->sd_args.ar_upgrade) { + printk("GFS: code version (%u, %u) is incompatible with ondisk format (%u, %u)\n", + GFS_FORMAT_FS, GFS_FORMAT_MULTI, + sb->sb_fs_format, sb->sb_multihost_format); + printk("GFS: Use the \"upgrade\" mount option to upgrade the FS\n"); + printk("GFS: See the manual for more details\n"); + return -EINVAL; + } + + return 0; +} + +/** + * gfs_read_sb - Read super block + * @sdp: The GFS superblock + * @gl: the glock for the superblock (assumed to be held) + * @silent: Don't print message if mount fails + * + */ + +int +gfs_read_sb(struct gfs_sbd *sdp, struct gfs_glock *gl, int silent) +{ + struct buffer_head *bh; + uint32_t hash_blocks, ind_blocks, leaf_blocks; + uint32_t tmp_blocks; + unsigned int x; + int error; + + error = gfs_dread(gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_FORCE | DIO_START | DIO_WAIT, &bh); + if (error) { + if (!silent) + printk("GFS: fsid=%s: can't read superblock\n", + sdp->sd_fsname); + return error; + } + + gfs_assert(sdp, sizeof(struct gfs_sb) <= bh->b_size,); + gfs_sb_in(&sdp->sd_sb, bh->b_data); + brelse(bh); + + error = gfs_check_sb(sdp, &sdp->sd_sb, silent); + if (error) + return error; + + sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - + GFS_BASIC_BLOCK_SHIFT; + sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; + sdp->sd_diptrs = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) / + sizeof(uint64_t); + sdp->sd_inptrs = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_indirect)) / + sizeof(uint64_t); + sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs_meta_header); + sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; + sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; + sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(uint64_t); + + /* Compute maximum reservation required to add a entry to a directory */ + + hash_blocks = DIV_RU(sizeof(uint64_t) * (1 << GFS_DIR_MAX_DEPTH), + sdp->sd_jbsize); + + ind_blocks = 0; + for (tmp_blocks = hash_blocks; tmp_blocks > sdp->sd_diptrs;) { + tmp_blocks = DIV_RU(tmp_blocks, sdp->sd_inptrs); + ind_blocks += tmp_blocks; + } + + leaf_blocks = 2 + GFS_DIR_MAX_DEPTH; + + sdp->sd_max_dirres = hash_blocks + ind_blocks + leaf_blocks; + + sdp->sd_heightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); + sdp->sd_heightsize[1] = sdp->sd_sb.sb_bsize * sdp->sd_diptrs; + for (x = 2;; x++) { + uint64_t space, d; + uint32_t m; + + space = sdp->sd_heightsize[x - 1] * sdp->sd_inptrs; + d = space; + m = do_div(d, sdp->sd_inptrs); + + if (d != sdp->sd_heightsize[x - 1] || m) + break; + sdp->sd_heightsize[x] = space; + } + sdp->sd_max_height = x; + gfs_assert(sdp, sdp->sd_max_height <= GFS_MAX_META_HEIGHT,); + + sdp->sd_jheightsize[0] = sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode); + sdp->sd_jheightsize[1] = sdp->sd_jbsize * sdp->sd_diptrs; + for (x = 2;; x++) { + uint64_t space, d; + uint32_t m; + + space = sdp->sd_jheightsize[x - 1] * sdp->sd_inptrs; + d = space; + m = do_div(d, sdp->sd_inptrs); + + if (d != sdp->sd_jheightsize[x - 1] || m) + break; + sdp->sd_jheightsize[x] = space; + } + sdp->sd_max_jheight = x; + gfs_assert(sdp, sdp->sd_max_jheight <= GFS_MAX_META_HEIGHT,); + + return 0; +} + +/** + * gfs_do_upgrade - upgrade a filesystem + * @sdp: The GFS superblock + * + */ + +int +gfs_do_upgrade(struct gfs_sbd *sdp, struct gfs_glock *sb_gl) +{ + struct gfs_holder ji_gh, t_gh, j_gh; + struct gfs_log_header lh; + struct buffer_head *bh; + unsigned int x; + int error; + + /* If format numbers match exactly, we're done. */ + + if (sdp->sd_sb.sb_fs_format == GFS_FORMAT_FS && + sdp->sd_sb.sb_multihost_format == GFS_FORMAT_MULTI) { + printk("GFS: fsid=%s: no upgrade necessary\n", + sdp->sd_fsname); + sdp->sd_args.ar_upgrade = FALSE; + return 0; + } + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) + goto fail; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_EXCLUSIVE, GL_NOCACHE, + &t_gh); + if (error) + goto fail_ji_relse; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + printk("GFS: fsid=%s: can't upgrade: read-only FS\n", + sdp->sd_fsname); + error = -EROFS; + goto fail_gunlock_tr; + } + + for (x = 0; x < sdp->sd_journals; x++) { + error = gfs_glock_nq_num(sdp, + sdp->sd_jindex[x].ji_addr, + &gfs_meta_glops, LM_ST_SHARED, + LM_FLAG_TRY | GL_NOCACHE, &j_gh); + switch (error) { + case 0: + break; + + case GLR_TRYFAILED: + printk("GFS: fsid=%s: journal %u is busy\n", + sdp->sd_fsname, x); + error = -EBUSY; + + default: + goto fail_gunlock_tr; + } + + error = gfs_find_jhead(sdp, &sdp->sd_jindex[x], + j_gh.gh_gl, &lh); + + gfs_glock_dq_uninit(&j_gh); + + if (error) + goto fail_gunlock_tr; + + if (!(lh.lh_flags & GFS_LOG_HEAD_UNMOUNT) || lh.lh_last_dump) { + printk("GFS: fsid=%s: journal %u is busy\n", + sdp->sd_fsname, x); + error = -EBUSY; + goto fail_gunlock_tr; + } + } + + /* We don't need to journal this change because we're changing + only one sector of one block. We definitely don't want to have + the journaling code running at this point. */ + + error = gfs_dread(sb_gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_START | DIO_WAIT, &bh); + if (error) + goto fail_gunlock_tr; + + gfs_sb_in(&sdp->sd_sb, bh->b_data); + + error = gfs_check_sb(sdp, &sdp->sd_sb, FALSE); + if (error) { + gfs_consist(sdp); + brelse(bh); + goto fail_gunlock_tr; + } + + sdp->sd_sb.sb_fs_format = GFS_FORMAT_FS; + sdp->sd_sb.sb_multihost_format = GFS_FORMAT_MULTI; + + gfs_sb_out(&sdp->sd_sb, bh->b_data); + + set_bit(GLF_DIRTY, &sb_gl->gl_flags); + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + + brelse(bh); + + gfs_glock_dq_uninit(&t_gh); + + gfs_glock_dq_uninit(&ji_gh); + + if (!error) { + printk("GFS: fsid=%s: upgrade successful\n", + sdp->sd_fsname); + sdp->sd_args.ar_upgrade = FALSE; + } + + return error; + + fail_gunlock_tr: + gfs_glock_dq_uninit(&t_gh); + + fail_ji_relse: + gfs_glock_dq_uninit(&ji_gh); + + fail: + if (error == -EBUSY) + printk("GFS: fsid=%s: can't upgrade: the FS is still busy or contains dirty journals\n", + sdp->sd_fsname); + else + printk("GFS: fsid=%s: can't upgrade: %d\n", + sdp->sd_fsname, error); + + return error; +} + +/** + * clear_journalsi - Clear all the journal index information (without locking) + * @sdp: The GFS superblock + * + */ + +static void +clear_journalsi(struct gfs_sbd *sdp) +{ + if (sdp->sd_jindex) { + kfree(sdp->sd_jindex); + sdp->sd_jindex = NULL; + } + sdp->sd_journals = 0; +} + +/** + * gfs_clear_journals - Clear all the journal index information + * @sdp: The GFS superblock + * + */ + +void +gfs_clear_journals(struct gfs_sbd *sdp) +{ + down(&sdp->sd_jindex_lock); + clear_journalsi(sdp); + up(&sdp->sd_jindex_lock); +} + +/** + * gfs_ji_update - Update the journal index information + * @ip: The journal index inode + * + * Returns: errno + */ + +static int +gfs_ji_update(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + char buf[sizeof(struct gfs_jindex)]; + unsigned int j; + int error; + + if (do_mod(ip->i_di.di_size, sizeof(struct gfs_jindex))) { + gfs_consist_inode(ip); + return -EIO; + } + + clear_journalsi(sdp); + + sdp->sd_jindex = kmalloc(ip->i_di.di_size, GFP_KERNEL); + if (!sdp->sd_jindex) + return -ENOMEM; + memset(sdp->sd_jindex, 0, ip->i_di.di_size); + + for (j = 0;; j++) { + error = gfs_internal_read(ip, buf, + j * sizeof(struct gfs_jindex), + sizeof(struct gfs_jindex)); + if (!error) + break; + if (error != sizeof(struct gfs_jindex)) { + if (error > 0) + error = -EIO; + goto fail; + } + + gfs_jindex_in(sdp->sd_jindex + j, buf); + } + + sdp->sd_journals = j; + sdp->sd_jiinode_vn = ip->i_gl->gl_vn; + + return 0; + + fail: + clear_journalsi(sdp); + return error; +} + +/** + * gfs_jindex_hold - Grab a lock on the jindex + * @sdp: The GFS superblock + * @ji_gh: the holder for the jindex glock + * + * This makes sure that we're using the latest copy of the journal index + * special file (this describes all of the journals for this filesystem), + * which might have been updated if someone added journals + * (via gfs_jadd utility). + * + * This is very similar to the gfs_rindex_hold() function, except that + * in general we hold the jindex lock for longer periods of time and + * we grab it far less frequently (in general) then the rgrp lock. + * + * Returns: errno + */ + +int +gfs_jindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ji_gh) +{ + struct gfs_inode *ip = sdp->sd_jiinode; + struct gfs_glock *gl = ip->i_gl; + int error; + + error = gfs_glock_nq_init(gl, LM_ST_SHARED, 0, ji_gh); + if (error) + return error; + + /* Read new copy from disk if we don't have the latest */ + if (sdp->sd_jiinode_vn != gl->gl_vn) { + down(&sdp->sd_jindex_lock); + if (sdp->sd_jiinode_vn != gl->gl_vn) + error = gfs_ji_update(ip); + up(&sdp->sd_jindex_lock); + } + + if (error) + gfs_glock_dq_uninit(ji_gh); + + return error; +} + +/** + * gfs_get_jiinode - Read-in the special (hidden) journal index inode + * @sdp: The GFS superblock + * + * Returns: errno + * + * This reads-in just the dinode, not the special file contents that describe + * the journals themselves (see gfs_jindex_hold()). + */ + +int +gfs_get_jiinode(struct gfs_sbd *sdp) +{ + struct gfs_holder ji_gh; + int error; + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_jindex_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &ji_gh); + if (error) + return error; + + error = gfs_inode_get(ji_gh.gh_gl, &sdp->sd_sb.sb_jindex_di, + CREATE, &sdp->sd_jiinode); + if (!error) { + sdp->sd_jiinode_vn = ji_gh.gh_gl->gl_vn - 1; + set_bit(GLF_STICKY, &ji_gh.gh_gl->gl_flags); + } + + gfs_glock_dq_uninit(&ji_gh); + + return error; +} + +/** + * gfs_get_riinode - Read in the special (hidden) resource group index inode + * @sdp: The GFS superblock + * + * Returns: errno + * + * This reads-in just the dinode, not the special file contents that describe + * the resource groups themselves (see gfs_rindex_hold()). + */ + +int +gfs_get_riinode(struct gfs_sbd *sdp) +{ + struct gfs_holder ri_gh; + int error; + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_rindex_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &ri_gh); + if (error) + return error; + + error = gfs_inode_get(ri_gh.gh_gl, &sdp->sd_sb.sb_rindex_di, + CREATE, &sdp->sd_riinode); + if (!error) { + sdp->sd_riinode_vn = ri_gh.gh_gl->gl_vn - 1; + set_bit(GLF_STICKY, &ri_gh.gh_gl->gl_flags); + } + + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * gfs_get_rootinode - Read in the filesystem's root inode + * @sdp: The GFS superblock + * + * Returns: errno + */ + +int +gfs_get_rootinode(struct gfs_sbd *sdp) +{ + struct gfs_holder i_gh; + int error; + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_root_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &i_gh); + if (error) + return error; + + error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_root_di, + CREATE, &sdp->sd_rooti); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_get_qinode - Read in the special (hidden) quota inode + * @sdp: The GFS superblock + * + * If one is not on-disk already, create a new one. + * Does not read in file contents, just the dinode. + * + * Returns: errno + */ + +int +gfs_get_qinode(struct gfs_sbd *sdp) +{ + struct gfs_holder i_gh; + int error; + + /* Create, if not on-disk already */ + if (!sdp->sd_sb.sb_quota_di.no_formal_ino) { + error = gfs_alloc_qinode(sdp); + if (error) + return error; + } + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_quota_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &i_gh); + if (error) + return error; + + error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_quota_di, + CREATE, &sdp->sd_qinode); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_get_linode - Read in the special (hidden) license inode + * @sdp: The GFS superblock + * + * If one is not on-disk already, create a new one. + * Does not read in file contents, just the dinode. + * + * Returns: errno + */ + +int +gfs_get_linode(struct gfs_sbd *sdp) +{ + struct gfs_holder i_gh; + int error; + + /* Create, if not on-disk already */ + if (!sdp->sd_sb.sb_license_di.no_formal_ino) { + error = gfs_alloc_linode(sdp); + if (error) + return error; + } + + error = gfs_glock_nq_num(sdp, + sdp->sd_sb.sb_license_di.no_formal_ino, + &gfs_inode_glops, + LM_ST_SHARED, GL_LOCAL_EXCL, + &i_gh); + if (error) + return error; + + /* iopen obtained in via gfs_glock_get(..gfs_iopen_glops) */ + error = gfs_inode_get(i_gh.gh_gl, &sdp->sd_sb.sb_license_di, + CREATE, &sdp->sd_linode); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_make_fs_rw - Turn a Read-Only FS into a Read-Write one + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_make_fs_rw(struct gfs_sbd *sdp) +{ + struct gfs_glock *j_gl = sdp->sd_journal_gh.gh_gl; + struct gfs_holder t_gh; + struct gfs_log_header head; + int error; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_EXACT, + &t_gh); + if (error) + return error; + + j_gl->gl_ops->go_inval(j_gl, DIO_METADATA | DIO_DATA); + + error = gfs_find_jhead(sdp, &sdp->sd_jdesc, j_gl, &head); + if (error) + goto fail; + + if (!(head.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + gfs_consist(sdp); + error = -EIO; + goto fail; + } + + /* Initialize some head of the log stuff */ + sdp->sd_sequence = head.lh_sequence; + sdp->sd_log_head = head.lh_first + 1; + + error = gfs_recover_dump(sdp); + if (error) + goto fail; + + set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + clear_bit(SDF_ROFS, &sdp->sd_flags); + + set_bit(GLF_DIRTY, &j_gl->gl_flags); + gfs_log_dump(sdp, TRUE); + + gfs_glock_dq_uninit(&t_gh); + + return 0; + + fail: + t_gh.gh_flags |= GL_NOCACHE; + gfs_glock_dq_uninit(&t_gh); + + return error; +} + +/** + * gfs_make_fs_ro - Turn a Read-Write FS into a Read-Only one + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_make_fs_ro(struct gfs_sbd *sdp) +{ + struct gfs_holder t_gh; + int error; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_EXACT | GL_NOCACHE, + &t_gh); + if (error && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + return error; + + gfs_statfs_sync(sdp); + + gfs_log_flush(sdp); + gfs_quota_sync(sdp); + gfs_quota_scan(sdp); + + gfs_sync_meta(sdp); + gfs_log_dump(sdp, TRUE); + gfs_log_shutdown(sdp); + + set_bit(SDF_ROFS, &sdp->sd_flags); + clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); + + if (t_gh.gh_gl) + gfs_glock_dq_uninit(&t_gh); + + gfs_unlinked_cleanup(sdp); + gfs_quota_cleanup(sdp); + + return error; +} + +/** + * stat_gfs_fill - fill in the sg for a given RG + * @rgd: the RG + * @sg: the sg structure + * + * Returns: 0 on success, -ESTALE if the LVB is invalid + */ + +static int +stat_gfs_fill(struct gfs_rgrpd *rgd, struct gfs_stat_gfs *sg) +{ + struct gfs_rgrp_lvb *rb = (struct gfs_rgrp_lvb *)rgd->rd_gl->gl_lvb; + + if (gfs32_to_cpu(rb->rb_magic) != GFS_MAGIC) + return -ESTALE; + + sg->sg_total_blocks += rgd->rd_ri.ri_data; + sg->sg_free += gfs32_to_cpu(rb->rb_free); + sg->sg_used_dinode += gfs32_to_cpu(rb->rb_useddi); + sg->sg_free_dinode += gfs32_to_cpu(rb->rb_freedi); + sg->sg_used_meta += gfs32_to_cpu(rb->rb_usedmeta); + sg->sg_free_meta += gfs32_to_cpu(rb->rb_freemeta); + + return 0; +} + +/** + * stat_gfs_async - Stat a filesystem using asynchronous locking + * @sdp: the filesystem + * @sg: the sg info that will be returned + * @interruptible: TRUE if we should look for signals. + * + * Any error (other than a signal) will cause this routine to fall back + * to the synchronous version. + * + * FIXME: This really shouldn't busy wait like this. + * + * Returns: errno + */ + +static int +stat_gfs_async(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) +{ + struct gfs_rgrpd *rgd_next = gfs_rgrpd_get_first(sdp); + struct gfs_holder *gha, *gh; + unsigned int slots = gfs_tune_get(sdp, gt_statfs_slots); + unsigned int x; + int done; + int error = 0, err; + + memset(sg, 0, sizeof(struct gfs_stat_gfs)); + + gha = vmalloc(slots * sizeof(struct gfs_holder)); + if (!gha) + return -ENOMEM; + memset(gha, 0, slots * sizeof(struct gfs_holder)); + + for (;;) { + done = TRUE; + + for (x = 0; x < slots; x++) { + gh = gha + x; + + if (gh->gh_gl && gfs_glock_poll(gh)) { + err = gfs_glock_wait(gh); + if (err) { + gfs_holder_uninit(gh); + error = err; + } else { + if (!error) + error = stat_gfs_fill(get_gl2rgd(gh->gh_gl), sg); + gfs_glock_dq_uninit(gh); + } + } + + if (gh->gh_gl) + done = FALSE; + else if (rgd_next && !error) { + error = gfs_glock_nq_init(rgd_next->rd_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_SKIP | GL_ASYNC, + gh); + rgd_next = gfs_rgrpd_get_next(rgd_next); + done = FALSE; + } + + if (interruptible && signal_pending(current)) + error = -ERESTARTSYS; + } + + if (done) + break; + + yield(); + } + + vfree(gha); + + return error; +} + +/** + * stat_gfs_sync - Stat a filesystem using synchronous locking + * @sdp: the filesystem + * @sg: the sg info that will be returned + * @interruptible: TRUE if we should look for signals. + * + * Returns: errno + */ + +static int +stat_gfs_sync(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) +{ + struct gfs_holder rgd_gh; + struct gfs_rgrpd *rgd; + int error; + + memset(sg, 0, sizeof(struct gfs_stat_gfs)); + + for (rgd = gfs_rgrpd_get_first(sdp); + rgd; + rgd = gfs_rgrpd_get_next(rgd)) { + for (;;) { + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_SHARED, + GL_LOCAL_EXCL | GL_SKIP, + &rgd_gh); + if (error) + return error; + + error = stat_gfs_fill(rgd, sg); + + gfs_glock_dq_uninit(&rgd_gh); + + if (!error) + break; + + error = gfs_rgrp_lvb_init(rgd); + if (error) + return error; + } + + if (interruptible && signal_pending(current)) + return -ERESTARTSYS; + } + + return 0; +} + +/** + * gfs_stat_gfs - Do a statfs + * @sdp: the filesystem + * @sg: the sg structure + * @interruptible: Stop if there is a signal pending + * + * Returns: errno + */ + +int +gfs_stat_gfs(struct gfs_sbd *sdp, struct gfs_stat_gfs *sg, int interruptible) +{ + struct gfs_holder ri_gh; + int error; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + return error; + + error = stat_gfs_async(sdp, sg, interruptible); + if (error == -ESTALE) + error = stat_gfs_sync(sdp, sg, interruptible); + + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * gfs_lock_fs_check_clean - Stop all writes to the FS and check that all journals are clean + * @sdp: the file system + * @state: the state to put the transaction lock into + * @t_gh: the hold on the transaction lock + * + * Returns: errno + */ + +int +gfs_lock_fs_check_clean(struct gfs_sbd *sdp, unsigned int state, + struct gfs_holder *t_gh) +{ + struct gfs_holder ji_gh, cl_gh; + struct gfs_log_header lh; + unsigned int x; + int error; + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) + return error; + + error = gfs_glock_nq_num(sdp, + GFS_CRAP_LOCK, &gfs_meta_glops, + LM_ST_SHARED, GL_NOCACHE, + &cl_gh); + if (error) + goto fail; + + error = gfs_glock_nq_init(sdp->sd_trans_gl, state, + LM_FLAG_PRIORITY | GL_EXACT | GL_NOCACHE, + t_gh); + if (error) + goto fail_gunlock_craplock; + + for (x = 0; x < sdp->sd_journals; x++) { + error = gfs_find_jhead(sdp, &sdp->sd_jindex[x], + cl_gh.gh_gl, &lh); + if (error) + goto fail_gunlock_trans; + + if (!(lh.lh_flags & GFS_LOG_HEAD_UNMOUNT)) { + error = -EBUSY; + goto fail_gunlock_trans; + } + } + + gfs_glock_dq_uninit(&cl_gh); + gfs_glock_dq_uninit(&ji_gh); + + return 0; + + fail_gunlock_trans: + gfs_glock_dq_uninit(t_gh); + + fail_gunlock_craplock: + gfs_glock_dq_uninit(&cl_gh); + + fail: + gfs_glock_dq_uninit(&ji_gh); + + return error; +} + +/** + * gfs_freeze_fs - freezes the file system + * @sdp: the file system + * + * This function flushes data and meta data for all machines by + * aquiring the transaction log exclusively. All journals are + * ensured to be in a clean state as well. + * + * Returns: errno + */ + +int +gfs_freeze_fs(struct gfs_sbd *sdp) +{ + int error = 0; + + down(&sdp->sd_freeze_lock); + + if (!sdp->sd_freeze_count++) { + error = gfs_lock_fs_check_clean(sdp, LM_ST_DEFERRED, + &sdp->sd_freeze_gh); + if (error) + sdp->sd_freeze_count--; + else + sdp->sd_freeze_gh.gh_owner = NULL; + } + + up(&sdp->sd_freeze_lock); + + return error; +} + +/** + * gfs_unfreeze_fs - unfreezes the file system + * @sdp: the file system + * + * This function allows the file system to proceed by unlocking + * the exclusively held transaction lock. Other GFS nodes are + * now free to acquire the lock shared and go on with their lives. + * + */ + +void +gfs_unfreeze_fs(struct gfs_sbd *sdp) +{ + down(&sdp->sd_freeze_lock); + + if (sdp->sd_freeze_count && !--sdp->sd_freeze_count) + gfs_glock_dq_uninit(&sdp->sd_freeze_gh); + + up(&sdp->sd_freeze_lock); +} + +/* + * Fast statfs implementation - mostly based on GFS2 implementation. + */ + +void gfs_statfs_change_in(struct gfs_statfs_change_host *sc, const void *buf) +{ + const struct gfs_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); +} + +void gfs_statfs_change_out(const struct gfs_statfs_change_host *sc, void *buf) +{ + struct gfs_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 gfs_statfs_start(struct gfs_sbd *sdp) +{ + struct gfs_stat_gfs sg; + struct gfs_inode *m_ip; + struct gfs_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + struct buffer_head *m_bh; + struct gfs_holder gh; + int error; + + printk("GFS: fsid=%s: fast statfs start time = %lu\n", + sdp->sd_fsname, get_seconds()); + + /* created via gfs_get_linode() in fill_super(). */ + /* gfs_inode_glops */ + m_ip = sdp->sd_linode; + + /* get real statistics */ + error = gfs_stat_gfs(sdp, &sg, TRUE); + if (error) + return error; + + /* make sure the page is refreshed via glock flushing */ + error = gfs_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, + &gh); + if (error) + goto gfs_statfs_start_out; + + error = gfs_get_inode_buffer(m_ip, &m_bh); + if (error) + goto gfs_statfs_start_unlock; + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + goto gfs_statfs_start_bh; + + spin_lock(&sdp->sd_statfs_spin); + m_sc->sc_total = sg.sg_total_blocks; + m_sc->sc_free = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; + m_sc->sc_dinodes = sg.sg_used_dinode; + memset(l_sc, 0, sizeof(struct gfs_statfs_change_host)); + spin_unlock(&sdp->sd_statfs_spin); + + gfs_trans_add_bh(m_ip->i_gl, m_bh); + gfs_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs_dinode)); + + gfs_trans_end(sdp); + +gfs_statfs_start_bh: + brelse(m_bh); + +gfs_statfs_start_unlock: + gfs_glock_dq_uninit(&gh); + +gfs_statfs_start_out: + return 0; +} + +int gfs_statfs_init(struct gfs_sbd *sdp, int flag) +{ + int error; + + /* if flag == 0, do we want to turn this off ? */ + if (!flag) + return 0; + + error = gfs_statfs_start(sdp); + if (error) + printk("GFS: fsid=%s: can't initialize statfs subsystem: %d\n", + sdp->sd_fsname, error); + + return error; +} + +void gfs_statfs_modify(struct gfs_sbd *sdp, + int64_t total, + int64_t free, + int64_t dinodes) +{ + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + + spin_lock(&sdp->sd_statfs_spin); + l_sc->sc_total += total; + l_sc->sc_free += free; + l_sc->sc_dinodes += dinodes; + spin_unlock(&sdp->sd_statfs_spin); +} + +int gfs_statfs_sync(struct gfs_sbd *sdp) +{ + struct gfs_inode *m_ip = sdp->sd_linode; + struct gfs_statfs_change_host *m_sc = &sdp->sd_statfs_master; + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + struct gfs_holder gh; + struct buffer_head *m_bh; + int error; + + error = gfs_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE, + &gh); + if (error) + return error; + + error = gfs_get_inode_buffer(m_ip, &m_bh); + if (error) + goto gfs_statfs_sync_out; + + /* if no change, simply return */ + spin_lock(&sdp->sd_statfs_spin); + gfs_statfs_change_in(m_sc, m_bh->b_data + + sizeof(struct gfs_dinode)); + if (!l_sc->sc_total && !l_sc->sc_free && !l_sc->sc_dinodes) { + spin_unlock(&sdp->sd_statfs_spin); + goto out_bh; + } + spin_unlock(&sdp->sd_statfs_spin); + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + goto out_bh; + + spin_lock(&sdp->sd_statfs_spin); + m_sc->sc_total += l_sc->sc_total; + m_sc->sc_free += l_sc->sc_free; + m_sc->sc_dinodes += l_sc->sc_dinodes; + memset(l_sc, 0, sizeof(struct gfs_statfs_change_host)); + spin_unlock(&sdp->sd_statfs_spin); + + gfs_trans_add_bh(m_ip->i_gl, m_bh); + gfs_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs_dinode)); + + gfs_trans_end(sdp); + +out_bh: + brelse(m_bh); + +gfs_statfs_sync_out: + gfs_glock_dq_uninit(&gh); + return error; +} + +int gfs_statfs_fast(struct gfs_sbd *sdp, void *b) +{ + struct kstatfs *buf = (struct kstatfs *)b; + struct gfs_statfs_change_host sc, *m_sc = &sdp->sd_statfs_master; + struct gfs_statfs_change_host *l_sc = &sdp->sd_statfs_local; + + spin_lock(&sdp->sd_statfs_spin); + + sc.sc_total = m_sc->sc_total + l_sc->sc_total; + sc.sc_free = m_sc->sc_free + l_sc->sc_free; + sc.sc_dinodes = m_sc->sc_dinodes + l_sc->sc_dinodes; + spin_unlock(&sdp->sd_statfs_spin); + + if (sc.sc_free < 0) + sc.sc_free = 0; + if (sc.sc_free > sc.sc_total) + sc.sc_free = sc.sc_total; + if (sc.sc_dinodes < 0) + sc.sc_dinodes = 0; + + /* fill in the statistics */ + memset(buf, 0, sizeof(struct kstatfs)); + + buf->f_type = GFS_MAGIC; buf->f_bsize = sdp->sd_sb.sb_bsize; + buf->f_blocks = sc.sc_total; + buf->f_bfree = sc.sc_free; + buf->f_bavail = sc.sc_free; + buf->f_files = sc.sc_dinodes + sc.sc_free; + buf->f_ffree = sc.sc_free; + buf->f_namelen = GFS_FNAMESIZE; + + return 0; +} --- linux-2.6.28.orig/ubuntu/gfs/unlinked.h +++ linux-2.6.28/ubuntu/gfs/unlinked.h @@ -0,0 +1,19 @@ +#ifndef __UNLINKED_DOT_H__ +#define __UNLINKED_DOT_H__ + +struct gfs_unlinked *gfs_unlinked_get(struct gfs_sbd *sdp, + struct gfs_inum *inum, int create); +void gfs_unlinked_hold(struct gfs_sbd *sdp, struct gfs_unlinked *ul); +void gfs_unlinked_put(struct gfs_sbd *sdp, struct gfs_unlinked *ul); + +void gfs_unlinked_lock(struct gfs_sbd *sdp, struct gfs_unlinked *ul); +void gfs_unlinked_unlock(struct gfs_sbd *sdp, struct gfs_unlinked *ul); + +void gfs_unlinked_merge(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum); +void gfs_unlinked_cleanup(struct gfs_sbd *sdp); + +void gfs_unlinked_limit(struct gfs_sbd *sdp); +void gfs_unlinked_dealloc(struct gfs_sbd *sdp); + +#endif /* __UNLINKED_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/dir.c +++ linux-2.6.28/ubuntu/gfs/dir.c @@ -0,0 +1,2394 @@ +/* +* Implements Extendible Hashing as described in: +* "Extendible Hashing" by Fagin, et al in +* __ACM Trans. on Database Systems__, Sept 1979. +* +* +* Here's the layout of dirents which is essentially the same as that of ext2 +* within a single block. The field de_name_len is the number of bytes +* actually required for the name (no null terminator). The field de_rec_len +* is the number of bytes allocated to the dirent. The offset of the next +* dirent in the block is (dirent + dirent->de_rec_len). When a dirent is +* deleted, the preceding dirent inherits its allocated space, ie +* prev->de_rec_len += deleted->de_rec_len. Since the next dirent is obtained +* by adding de_rec_len to the current dirent, this essentially causes the +* deleted dirent to get jumped over when iterating through all the dirents. +* +* When deleting the first dirent in a block, there is no previous dirent so +* the field de_ino is set to zero to designate it as deleted. When allocating +* a dirent, gfs_dirent_alloc iterates through the dirents in a block. If the +* first dirent has (de_ino == 0) and de_rec_len is large enough, this first +* dirent is allocated. Otherwise it must go through all the 'used' dirents +* searching for one in which the amount of total space minus the amount of +* used space will provide enough space for the new dirent. +* +* There are two types of blocks in which dirents reside. In a stuffed dinode, +* the dirents begin at offset sizeof(struct gfs_dinode) from the beginning of +* the block. In leaves, they begin at offset sizeof (struct gfs_leaf) from the +* beginning of the leaf block. The dirents reside in leaves when +* +* dip->i_di.di_flags & GFS_DIF_EXHASH is true +* +* Otherwise, the dirents are "linear", within a single stuffed dinode block. +* +* When the dirents are in leaves, the actual contents of the directory file are +* used as an array of 64-bit block pointers pointing to the leaf blocks. The +* dirents are NOT in the directory file itself. There can be more than one block +* pointer in the array that points to the same leaf. In fact, when a directory +* is first converted from linear to exhash, all of the pointers point to the +* same leaf. +* +* When a leaf is completely full, the size of the hash table can be +* doubled unless it is already at the maximum size which is hard coded into +* GFS_DIR_MAX_DEPTH. After that, leaves are chained together in a linked list, +* but never before the maximum hash table size has been reached. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "dir.h" +#include "file.h" +#include "glock.h" +#include "inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +#if 1 +#define gfs_dir_hash2offset(h) (((uint64_t)(h)) >> 1) +#define gfs_dir_offset2hash(p) ((uint32_t)(((uint64_t)(p)) << 1)) +#else +#define gfs_dir_hash2offset(h) (((uint64_t)(h))) +#define gfs_dir_offset2hash(p) ((uint32_t)(((uint64_t)(p)))) +#endif + +typedef int (*leaf_call_t) (struct gfs_inode *dip, + uint32_t index, uint32_t len, uint64_t leaf_no, + void *data); + +/** + * int gfs_filecmp - Compare two filenames + * @file1: The first filename + * @file2: The second filename + * @len_of_file2: The length of the second file + * + * This routine compares two filenames and returns TRUE if they are equal. + * + * Returns: TRUE (!=0) if the files are the same, otherwise FALSE (0). + */ + +int +gfs_filecmp(struct qstr *file1, char *file2, int len_of_file2) +{ + if (file1->len != len_of_file2) + return FALSE; + if (memcmp(file1->name, file2, file1->len)) + return FALSE; + return TRUE; +} + +/** + * dirent_first - Return the first dirent + * @dip: the directory + * @bh: The buffer + * @dent: Pointer to list of dirents + * + * return first dirent whether bh points to leaf or stuffed dinode + * + * Returns: IS_LEAF, IS_DINODE, or -errno + */ + +static int +dirent_first(struct gfs_inode *dip, struct buffer_head *bh, + struct gfs_dirent **dent) +{ + struct gfs_meta_header *h = (struct gfs_meta_header *)bh->b_data; + + if (gfs32_to_cpu(h->mh_type) == GFS_METATYPE_LF) { + if (gfs_meta_check(dip->i_sbd, bh)) + return -EIO; + *dent = (struct gfs_dirent *)(bh->b_data + sizeof(struct gfs_leaf)); + return IS_LEAF; + } else { + if (gfs_metatype_check(dip->i_sbd, bh, GFS_METATYPE_DI)) + return -EIO; + *dent = (struct gfs_dirent *)(bh->b_data + sizeof(struct gfs_dinode)); + return IS_DINODE; + } +} + +/** + * dirent_next - Next dirent + * @dip: the directory + * @bh: The buffer + * @dent: Pointer to list of dirents + * + * Returns: 0 on success, error code otherwise + */ + +static int +dirent_next(struct gfs_inode *dip, struct buffer_head *bh, + struct gfs_dirent **dent) +{ + struct gfs_dirent *tmp, *cur; + char *bh_end; + uint32_t cur_rec_len; + + cur = *dent; + bh_end = bh->b_data + bh->b_size; + cur_rec_len = gfs16_to_cpu(cur->de_rec_len); + + if ((char *)cur + cur_rec_len >= bh_end) { + if ((char *)cur + cur_rec_len > bh_end) { + gfs_consist_inode(dip); + return -EIO; + } + return -ENOENT; + } + + tmp = (struct gfs_dirent *)((char *)cur + cur_rec_len); + + if ((char *)tmp + gfs16_to_cpu(tmp->de_rec_len) > bh_end) { + gfs_consist_inode(dip); + return -EIO; + } + /* Only the first dent could ever have de_ino == 0 */ + if (!tmp->de_inum.no_formal_ino) { + gfs_consist_inode(dip); + return -EIO; + } + + *dent = tmp; + + return 0; +} + +/** + * dirent_del - Delete a dirent + * @dip: The GFS inode + * @bh: The buffer + * @prev: The previous dirent + * @cur: The current dirent + * + */ + +static void +dirent_del(struct gfs_inode *dip, struct buffer_head *bh, + struct gfs_dirent *prev, struct gfs_dirent *cur) +{ + uint32_t cur_rec_len, prev_rec_len; + + if (!cur->de_inum.no_formal_ino) { + gfs_consist_inode(dip); + return; + } + + gfs_trans_add_bh(dip->i_gl, bh); + + /* If there is no prev entry, this is the first entry in the block. + The de_rec_len is already as big as it needs to be. Just zero + out the inode number and return. */ + + if (!prev) { + cur->de_inum.no_formal_ino = 0; /* No endianess worries */ + return; + } + + /* Combine this dentry with the previous one. */ + + prev_rec_len = gfs16_to_cpu(prev->de_rec_len); + cur_rec_len = gfs16_to_cpu(cur->de_rec_len); + + if ((char *)prev + prev_rec_len != (char *)cur) + gfs_consist_inode(dip); + if ((char *)cur + cur_rec_len > bh->b_data + bh->b_size) + gfs_consist_inode(dip); + + prev_rec_len += cur_rec_len; + prev->de_rec_len = cpu_to_gfs16(prev_rec_len); +} + +/** + * gfs_dirent_alloc - Allocate a directory entry + * @dip: The GFS inode + * @bh: The buffer + * @name_len: The length of the name + * @dent_out: Pointer to list of dirents + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_dirent_alloc(struct gfs_inode *dip, struct buffer_head *bh, int name_len, + struct gfs_dirent **dent_out) +{ + struct gfs_dirent *dent, *new; + unsigned int rec_len = GFS_DIRENT_SIZE(name_len); + unsigned int entries = 0, offset = 0; + int type; + + type = dirent_first(dip, bh, &dent); + if (type < 0) + return type; + + if (type == IS_LEAF) { + struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + offset = sizeof(struct gfs_leaf); + } else { + struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; + entries = gfs32_to_cpu(dinode->di_entries); + offset = sizeof(struct gfs_dinode); + } + + if (!entries) { + if (dent->de_inum.no_formal_ino) { + gfs_consist_inode(dip); + return -EIO; + } + + gfs_trans_add_bh(dip->i_gl, bh); + + dent->de_rec_len = bh->b_size - offset; + dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); + dent->de_name_len = cpu_to_gfs16(name_len); + + *dent_out = dent; + return 0; + } + + do { + uint32_t cur_rec_len, cur_name_len; + + cur_rec_len = gfs16_to_cpu(dent->de_rec_len); + cur_name_len = gfs16_to_cpu(dent->de_name_len); + + if ((!dent->de_inum.no_formal_ino && cur_rec_len >= rec_len) || + (cur_rec_len >= GFS_DIRENT_SIZE(cur_name_len) + rec_len)) { + gfs_trans_add_bh(dip->i_gl, bh); + + if (dent->de_inum.no_formal_ino) { + new = (struct gfs_dirent *)((char *)dent + + GFS_DIRENT_SIZE(cur_name_len)); + memset(new, 0, sizeof(struct gfs_dirent)); + + new->de_rec_len = cpu_to_gfs16(cur_rec_len - + GFS_DIRENT_SIZE(cur_name_len)); + new->de_name_len = cpu_to_gfs16(name_len); + + dent->de_rec_len = cur_rec_len - gfs16_to_cpu(new->de_rec_len); + dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); + + *dent_out = new; + return 0; + } + + dent->de_name_len = cpu_to_gfs16(name_len); + + *dent_out = dent; + return 0; + } + } while (dirent_next(dip, bh, &dent) == 0); + + return -ENOSPC; +} + +/** + * dirent_fits - See if we can fit a entry in this buffer + * @dip: The GFS inode + * @bh: The buffer + * @name_len: The length of the name + * + * Returns: TRUE if it can fit, FALSE otherwise + */ + +static int +dirent_fits(struct gfs_inode *dip, struct buffer_head *bh, int name_len) +{ + struct gfs_dirent *dent; + unsigned int rec_len = GFS_DIRENT_SIZE(name_len); + unsigned int entries = 0; + int type; + + type = dirent_first(dip, bh, &dent); + if (type < 0) + return type; + + if (type == IS_LEAF) { + struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + } else { + struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; + entries = gfs32_to_cpu(dinode->di_entries); + } + + if (!entries) + return TRUE; + + do { + uint32_t cur_rec_len, cur_name_len; + + cur_rec_len = gfs16_to_cpu(dent->de_rec_len); + cur_name_len = gfs16_to_cpu(dent->de_name_len); + + if ((!dent->de_inum.no_formal_ino && cur_rec_len >= rec_len) || + (cur_rec_len >= GFS_DIRENT_SIZE(cur_name_len) + rec_len)) + return TRUE; + } while (dirent_next(dip, bh, &dent) == 0); + + return FALSE; +} + +/** + * leaf_search + * @bh: + * @filename: + * @dent_out: + * @dent_prev: + * + * Returns: + */ + +static int +leaf_search(struct gfs_inode *dip, + struct buffer_head *bh, struct qstr *filename, + struct gfs_dirent **dent_out, struct gfs_dirent **dent_prev) +{ + uint32_t hash; + struct gfs_dirent *dent, *prev = NULL; + unsigned int entries = 0; + int type; + + type = dirent_first(dip, bh, &dent); + if (type < 0) + return type; + + if (type == IS_LEAF) { + struct gfs_leaf *leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + } else if (type == IS_DINODE) { + struct gfs_dinode *dinode = (struct gfs_dinode *)bh->b_data; + entries = gfs32_to_cpu(dinode->di_entries); + } + + hash = gfs_dir_hash(filename->name, filename->len); + + do { + if (!dent->de_inum.no_formal_ino) { + prev = dent; + continue; + } + + if (gfs32_to_cpu(dent->de_hash) == hash && + gfs_filecmp(filename, (char *)(dent + 1), + gfs16_to_cpu(dent->de_name_len))) { + *dent_out = dent; + if (dent_prev) + *dent_prev = prev; + + return 0; + } + + prev = dent; + } while (dirent_next(dip, bh, &dent) == 0); + + return -ENOENT; +} + +/** + * get_leaf - Get leaf + * @dip: + * @leaf_no: + * @bh_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_leaf(struct gfs_inode *dip, uint64_t leaf_no, struct buffer_head **bhp) +{ + int error; + + error = gfs_dread(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp); + if (!error && gfs_metatype_check(dip->i_sbd, *bhp, GFS_METATYPE_LF)) + error = -EIO; + + return error; +} + +/** + * get_leaf_nr - Get a leaf number associated with the index + * @dip: The GFS inode + * @index: + * @leaf_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_leaf_nr(struct gfs_inode *dip, uint32_t index, uint64_t *leaf_out) +{ + uint64_t leaf_no; + int error; + + error = gfs_internal_read(dip, (char *)&leaf_no, + index * sizeof(uint64_t), + sizeof(uint64_t)); + if (error != sizeof(uint64_t)) + return (error < 0) ? error : -EIO; + + *leaf_out = gfs64_to_cpu(leaf_no); + + return 0; +} + +/** + * get_first_leaf - Get first leaf + * @dip: The GFS inode + * @index: + * @bh_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_first_leaf(struct gfs_inode *dip, uint32_t index, + struct buffer_head **bh_out) +{ + uint64_t leaf_no; + int error; + + error = get_leaf_nr(dip, index, &leaf_no); + if (!error) + error = get_leaf(dip, leaf_no, bh_out); + + return error; +} + +/** + * get_next_leaf - Get next leaf + * @dip: The GFS inode + * @bh_in: The buffer + * @bh_out: + * + * Returns: 0 on success, error code otherwise + */ + +static int +get_next_leaf(struct gfs_inode *dip, struct buffer_head *bh_in, + struct buffer_head **bh_out) +{ + struct gfs_leaf *leaf; + int error; + + leaf = (struct gfs_leaf *)bh_in->b_data; + + if (!leaf->lf_next) + error = -ENOENT; + else + error = get_leaf(dip, gfs64_to_cpu(leaf->lf_next), bh_out); + + return error; +} + +/** + * linked_leaf_search - Linked leaf search + * @dip: The GFS inode + * @filename: The filename to search for + * @dent_out: + * @dent_prev: + * @bh_out: + * + * Returns: 0 on sucess, error code otherwise + */ + +static int +linked_leaf_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_dirent **dent_out, struct gfs_dirent **dent_prev, + struct buffer_head **bh_out) +{ + struct buffer_head *bh = NULL, *bh_next; + uint32_t hsize, index; + uint32_t hash; + int error; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + /* Figure out the address of the leaf node. */ + + hash = gfs_dir_hash(filename->name, filename->len); + index = hash >> (32 - dip->i_di.di_depth); + + error = get_first_leaf(dip, index, &bh_next); + if (error) + return error; + + /* Find the entry */ + + do { + if (bh) + brelse(bh); + + bh = bh_next; + + error = leaf_search(dip, bh, filename, dent_out, dent_prev); + switch (error) { + case 0: + *bh_out = bh; + return 0; + + case -ENOENT: + break; + + default: + brelse(bh); + return error; + } + + error = get_next_leaf(dip, bh, &bh_next); + } + while (!error); + + brelse(bh); + + return error; +} + +/** + * dir_make_exhash - Convert a stuffed directory into an ExHash directory + * @dip: The GFS inode + * + * Returns: 0 on success, error code otherwise + */ + +static int +dir_make_exhash(struct gfs_inode *dip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_dirent *dent; + struct buffer_head *bh, *dibh; + struct gfs_leaf *leaf; + int y; + uint32_t x; + uint64_t *lp, bn; + int error; + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + /* Allocate a new block for the first leaf node */ + + error = gfs_metaalloc(dip, &bn); + if (error) + goto fail; + + /* Turn over a new leaf */ + + error = gfs_dread(dip->i_gl, bn, DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + goto fail; + + gfs_trans_add_bh(dip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_LF, GFS_FORMAT_LF); + gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); + + /* Fill in the leaf structure */ + + leaf = (struct gfs_leaf *)bh->b_data; + + gfs_assert(sdp, dip->i_di.di_entries < (1 << 16),); + + leaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); + leaf->lf_entries = cpu_to_gfs16(dip->i_di.di_entries); + + /* Copy dirents */ + + gfs_buffer_copy_tail(bh, sizeof(struct gfs_leaf), dibh, + sizeof(struct gfs_dinode)); + + /* Find last entry */ + + x = 0; + dirent_first(dip, bh, &dent); + + do { + if (!dent->de_inum.no_formal_ino) + continue; + if (++x == dip->i_di.di_entries) + break; + } + while (dirent_next(dip, bh, &dent) == 0); + + /* Adjust the last dirent's record length + (Remember that dent still points to the last entry.) */ + + dent->de_rec_len = gfs16_to_cpu(dent->de_rec_len) + + sizeof(struct gfs_dinode) - + sizeof(struct gfs_leaf); + dent->de_rec_len = cpu_to_gfs16(dent->de_rec_len); + + brelse(bh); + + /* We're done with the new leaf block, now setup the new + hash table. */ + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_buffer_clear_tail(dibh, sizeof (struct gfs_dinode)); + + lp = (uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)); + + for (x = sdp->sd_hash_ptrs; x--; lp++) + *lp = cpu_to_gfs64(bn); + + dip->i_di.di_size = sdp->sd_sb.sb_bsize / 2; + dip->i_di.di_blocks++; + dip->i_di.di_flags |= GFS_DIF_EXHASH; + dip->i_di.di_payload_format = 0; + + for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; + dip->i_di.di_depth = y; + + gfs_dinode_out(&dip->i_di, dibh->b_data); + + brelse(dibh); + + return 0; + + fail: + brelse(dibh); + return error; +} + +/** + * dir_split_leaf - Split a leaf block into two + * @dip: The GFS inode + * @index: + * @leaf_no: + * + * Returns: 0 on success, error code on failure + */ + +static int +dir_split_leaf(struct gfs_inode *dip, uint32_t index, uint64_t leaf_no) +{ + struct buffer_head *nbh, *obh, *dibh; + struct gfs_leaf *nleaf, *oleaf; + struct gfs_dirent *dent, *prev = NULL, *next = NULL, *new; + uint32_t start, len, half_len, divider; + uint64_t bn, *lp; + uint32_t name_len; + int x, moved = FALSE; + int error, lp_vfree=0; + + /* Allocate the new leaf block */ + + error = gfs_metaalloc(dip, &bn); + if (error) + return error; + + /* Get the new leaf block */ + + error = gfs_dread(dip->i_gl, bn, + DIO_NEW | DIO_START | DIO_WAIT, &nbh); + if (error) + return error; + + gfs_trans_add_bh(dip->i_gl, nbh); + gfs_metatype_set(nbh, GFS_METATYPE_LF, GFS_FORMAT_LF); + gfs_buffer_clear_tail(nbh, sizeof (struct gfs_meta_header)); + + nleaf = (struct gfs_leaf *)nbh->b_data; + + nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); + + /* Get the old leaf block */ + + error = get_leaf(dip, leaf_no, &obh); + if (error) + goto fail; + + gfs_trans_add_bh(dip->i_gl, obh); + + oleaf = (struct gfs_leaf *)obh->b_data; + + /* Compute the start and len of leaf pointers in the hash table. */ + + len = 1 << (dip->i_di.di_depth - gfs16_to_cpu(oleaf->lf_depth)); + half_len = len >> 1; + if (!half_len) { + gfs_consist_inode(dip); + error = -EIO; + goto fail_brelse; + } + + start = (index & ~(len - 1)); + + /* Change the pointers. + Don't bother distinguishing stuffed from non-stuffed. + This code is complicated enough already. */ + + lp = kmalloc(half_len * sizeof (uint64_t), GFP_KERNEL); + if (unlikely(!lp)) { + lp = vmalloc(half_len * sizeof (uint64_t)); + if (!lp) { + printk("GFS: dir_split_leaf vmalloc fail - half_len=%d\n", half_len); + error = -ENOMEM; + goto fail_brelse; + } else + lp_vfree = 1; + } + + error = gfs_internal_read(dip, (char *)lp, start * sizeof(uint64_t), + half_len * sizeof(uint64_t)); + if (error != half_len * sizeof(uint64_t)) { + if (error >= 0) + error = -EIO; + goto fail_lpfree; + } + + /* Change the pointers */ + + for (x = 0; x < half_len; x++) + lp[x] = cpu_to_gfs64(bn); + + error = gfs_internal_write(dip, (char *)lp, start * sizeof(uint64_t), + half_len * sizeof(uint64_t)); + if (error != half_len * sizeof(uint64_t)) { + if (error >= 0) + error = -EIO; + goto fail_lpfree; + } + + if (unlikely(lp_vfree)) + vfree(lp); + else + kfree(lp); + + /* Compute the divider */ + + divider = (start + half_len) << (32 - dip->i_di.di_depth); + + /* Copy the entries */ + + dirent_first(dip, obh, &dent); + + do { + next = dent; + if (dirent_next(dip, obh, &next)) + next = NULL; + + if (dent->de_inum.no_formal_ino && + gfs32_to_cpu(dent->de_hash) < divider) { + name_len = gfs16_to_cpu(dent->de_name_len); + + gfs_dirent_alloc(dip, nbh, name_len, &new); + + new->de_inum = dent->de_inum; /* No endianness worries */ + new->de_hash = dent->de_hash; /* No endianness worries */ + new->de_type = dent->de_type; /* No endianness worries */ + memcpy((char *)(new + 1), (char *)(dent + 1), + name_len); + + nleaf->lf_entries = gfs16_to_cpu(nleaf->lf_entries) + 1; + nleaf->lf_entries = cpu_to_gfs16(nleaf->lf_entries); + + dirent_del(dip, obh, prev, dent); + + if (!oleaf->lf_entries) + gfs_consist_inode(dip); + oleaf->lf_entries = gfs16_to_cpu(oleaf->lf_entries) - 1; + oleaf->lf_entries = cpu_to_gfs16(oleaf->lf_entries); + + if (!prev) + prev = dent; + + moved = TRUE; + } else + prev = dent; + + dent = next; + } + while (dent); + + /* If none of the entries got moved into the new leaf, + artificially fill in the first entry. */ + + if (!moved) { + gfs_dirent_alloc(dip, nbh, 0, &new); + new->de_inum.no_formal_ino = 0; + } + + oleaf->lf_depth = gfs16_to_cpu(oleaf->lf_depth) + 1; + oleaf->lf_depth = cpu_to_gfs16(oleaf->lf_depth); + nleaf->lf_depth = oleaf->lf_depth; + + error = gfs_get_inode_buffer(dip, &dibh); + if (!gfs_assert_withdraw(dip->i_sbd, !error)) { + dip->i_di.di_blocks++; + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + } + + brelse(obh); + brelse(nbh); + + return error; + + fail_lpfree: + if (unlikely(lp_vfree)) + vfree(lp); + else + kfree(lp); + + fail_brelse: + brelse(obh); + + fail: + brelse(nbh); + return error; +} + +/** + * dir_double_exhash - Double size of ExHash table + * @dip: The GFS dinode + * + * Returns: 0 on success, error code on failure + */ + +static int +dir_double_exhash(struct gfs_inode *dip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *dibh; + uint32_t hsize; + uint64_t *buf; + uint64_t *from, *to; + uint64_t block; + int x; + int error = 0; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + /* Allocate both the "from" and "to" buffers in one big chunk */ + + buf = gmalloc(3 * sdp->sd_hash_bsize); + + for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { + error = gfs_internal_read(dip, (char *)buf, + block * sdp->sd_hash_bsize, + sdp->sd_hash_bsize); + if (error != sdp->sd_hash_bsize) { + if (error >= 0) + error = -EIO; + goto fail; + } + + from = buf; + to = (uint64_t *)((char *)buf + sdp->sd_hash_bsize); + + for (x = sdp->sd_hash_ptrs; x--; from++) { + *to++ = *from; /* No endianess worries */ + *to++ = *from; + } + + error = gfs_internal_write(dip, (char *)buf + sdp->sd_hash_bsize, + block * sdp->sd_sb.sb_bsize, + sdp->sd_sb.sb_bsize); + if (error != sdp->sd_sb.sb_bsize) { + if (error >= 0) + error = -EIO; + goto fail; + } + } + + kfree(buf); + + error = gfs_get_inode_buffer(dip, &dibh); + if (!gfs_assert_withdraw(sdp, !error)) { + dip->i_di.di_depth++; + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + } + + return error; + + fail: + kfree(buf); + + return error; +} + +/** + * compare_dents - compare directory entries by hash value + * @a: first dent + * @b: second dent + * + * When comparing the hash entries of @a to @b: + * gt: returns 1 + * lt: returns -1 + * eq: returns 0 + */ + +static int +compare_dents(const void *a, const void *b) +{ + struct gfs_dirent *dent_a, *dent_b; + uint32_t hash_a, hash_b; + int ret = 0; + + dent_a = *(struct gfs_dirent **)a; + hash_a = dent_a->de_hash; + hash_a = gfs32_to_cpu(hash_a); + + dent_b = *(struct gfs_dirent **)b; + hash_b = dent_b->de_hash; + hash_b = gfs32_to_cpu(hash_b); + + if (hash_a > hash_b) + ret = 1; + else if (hash_a < hash_b) + ret = -1; + else { + unsigned int len_a = gfs16_to_cpu(dent_a->de_name_len); + unsigned int len_b = gfs16_to_cpu(dent_b->de_name_len); + + if (len_a > len_b) + ret = 1; + else if (len_a < len_b) + ret = -1; + else + ret = memcmp((char *)(dent_a + 1), + (char *)(dent_b + 1), + len_a); + } + + return ret; +} + +/** + * do_filldir_main - read out directory entries + * @dip: The GFS inode + * @offset: The offset in the file to read from + * @opaque: opaque data to pass to filldir + * @filldir: The function to pass entries to + * @darr: an array of struct gfs_dirent pointers to read + * @entries: the number of entries in darr + * @copied: pointer to int that's non-zero if a entry has been copied out + * + * Jump through some hoops to make sure that if there are hash collsions, + * they are read out at the beginning of a buffer. We want to minimize + * the possibility that they will fall into different readdir buffers or + * that someone will want to seek to that location. + * + * Returns: errno, >0 on exception from filldir + */ + +static int +do_filldir_main(struct gfs_inode *dip, uint64_t *offset, + void *opaque, gfs_filldir_t filldir, + struct gfs_dirent **darr, uint32_t entries, int *copied) +{ + struct gfs_dirent *dent, *dent_next; + struct gfs_inum inum; + uint64_t off, off_next; + unsigned int x, y; + int run = FALSE; + int error = 0; + + gfs_sort(darr, entries, sizeof(struct gfs_dirent *), compare_dents); + + dent_next = darr[0]; + off_next = gfs32_to_cpu(dent_next->de_hash); + off_next = gfs_dir_hash2offset(off_next); + + for (x = 0, y = 1; x < entries; x++, y++) { + dent = dent_next; + off = off_next; + + if (y < entries) { + dent_next = darr[y]; + off_next = gfs32_to_cpu(dent_next->de_hash); + off_next = gfs_dir_hash2offset(off_next); + + if (off < *offset) + continue; + *offset = off; + + if (off_next == off) { + if (*copied && !run) + return 1; + run = TRUE; + } else + run = FALSE; + } else { + if (off < *offset) + continue; + *offset = off; + } + + gfs_inum_in(&inum, (char *)&dent->de_inum); + + error = filldir(opaque, (char *)(dent + 1), + gfs16_to_cpu(dent->de_name_len), + off, &inum, + gfs16_to_cpu(dent->de_type)); + if (error) + return 1; + + *copied = TRUE; + } + + /* Increment the *offset by one, so the next time we come into the do_filldir fxn, + we get the next entry instead of the last one in the current leaf */ + + (*offset)++; + + return 0; +} + +/** + * do_filldir_single - Read directory entries out of a single block + * @dip: The GFS inode + * @offset: The offset in the file to read from + * @opaque: opaque data to pass to filldir + * @filldir: The function to pass entries to + * @bh: the block + * @entries: the number of entries in the block + * @copied: pointer to int that's non-zero if a entry has been copied out + * + * Returns: errno, >0 on exception from filldir + */ + +static int +do_filldir_single(struct gfs_inode *dip, uint64_t *offset, + void *opaque, gfs_filldir_t filldir, + struct buffer_head *bh, uint32_t entries, int *copied) +{ + struct gfs_dirent **darr; + struct gfs_dirent *de; + unsigned int e = 0; + int error, do_vfree=0; + + if (!entries) + return 0; + + darr = kmalloc(entries * sizeof(struct gfs_dirent *), GFP_KERNEL); + if (unlikely(!darr)) { + darr = vmalloc(entries * sizeof (struct gfs_dirent *)); + if (!darr) { + printk("GFS: do_filldir_single vmalloc fails, entries=%d\n", entries); + return -ENOMEM; + } + else + do_vfree = 1; + } + + dirent_first(dip, bh, &de); + do { + if (!de->de_inum.no_formal_ino) + continue; + if (e >= entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + darr[e++] = de; + } + while (dirent_next(dip, bh, &de) == 0); + + if (e != entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + + error = do_filldir_main(dip, offset, opaque, filldir, darr, + entries, copied); + + out: + if (unlikely(do_vfree)) + vfree(darr); + else + kfree(darr); + + return error; +} + +/** + * do_filldir_multi - Read directory entries out of a linked leaf list + * @dip: The GFS inode + * @offset: The offset in the file to read from + * @opaque: opaque data to pass to filldir + * @filldir: The function to pass entries to + * @bh: the first leaf in the list + * @copied: pointer to int that's non-zero if a entry has been copied out + * + * Returns: errno, >0 on exception from filldir + */ + +static int +do_filldir_multi(struct gfs_inode *dip, uint64_t *offset, + void *opaque, gfs_filldir_t filldir, + struct buffer_head *bh, int *copied) +{ + struct buffer_head **larr = NULL; + struct gfs_dirent **darr; + struct gfs_leaf *leaf; + struct buffer_head *tmp_bh; + struct gfs_dirent *de; + unsigned int entries, e = 0; + unsigned int leaves = 0, l = 0; + unsigned int x; + uint64_t ln; + int error = 0, leaves_vfree=0, entries_vfree=0; + + /* Count leaves and entries */ + + leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + ln = leaf->lf_next; + + while (ln) { + ln = gfs64_to_cpu(ln); + + error = get_leaf(dip, ln, &tmp_bh); + if (error) + return error; + + leaf = (struct gfs_leaf *)tmp_bh->b_data; + if (leaf->lf_entries) { + entries += gfs16_to_cpu(leaf->lf_entries); + leaves++; + } + ln = leaf->lf_next; + + brelse(tmp_bh); + } + + /* Bail out if there's nothing to do */ + + if (!entries) + return 0; + + /* Alloc arrays */ + + if (leaves) { + larr = kmalloc(leaves * sizeof(struct buffer_head *), GFP_KERNEL); + if (unlikely(!larr)) { + larr = vmalloc(leaves * sizeof (struct buffer_head *)); + if (!larr) { + printk("GFS: do_filldir_multi vmalloc fails leaves=%d\n", leaves); + return -ENOMEM; + } else + leaves_vfree = 1; + } + } + + darr = kmalloc(entries * sizeof(struct gfs_dirent *), GFP_KERNEL); + if (unlikely(!darr)) { + darr = vmalloc(entries * sizeof (struct gfs_dirent *)); + if (!darr) { + printk("GFS: do_filldir_multi vmalloc fails entries=%d\n", entries); + if (larr) { + if (leaves_vfree) + vfree(larr); + else + kfree(larr); + } + return -ENOMEM; + } else + entries_vfree = 1; + } + if (!darr) { + if (larr) + kfree(larr); + return -ENOMEM; + } + + /* Fill in arrays */ + + leaf = (struct gfs_leaf *)bh->b_data; + if (leaf->lf_entries) { + dirent_first(dip, bh, &de); + do { + if (!de->de_inum.no_formal_ino) + continue; + if (e >= entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + darr[e++] = de; + } + while (dirent_next(dip, bh, &de) == 0); + } + ln = leaf->lf_next; + + while (ln) { + ln = gfs64_to_cpu(ln); + + error = get_leaf(dip, ln, &tmp_bh); + if (error) + goto out; + + leaf = (struct gfs_leaf *)tmp_bh->b_data; + if (leaf->lf_entries) { + dirent_first(dip, tmp_bh, &de); + do { + if (!de->de_inum.no_formal_ino) + continue; + if (e >= entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + darr[e++] = de; + } + while (dirent_next(dip, tmp_bh, &de) == 0); + + larr[l++] = tmp_bh; + + ln = leaf->lf_next; + } else { + ln = leaf->lf_next; + brelse(tmp_bh); + } + } + + if (gfs_assert_withdraw(dip->i_sbd, l == leaves)) { + error = -EIO; + goto out; + } + if (e != entries) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + + /* Do work */ + + error = do_filldir_main(dip, offset, opaque, filldir, darr, + entries, copied); + + /* Clean up */ + + out: + if (unlikely(entries_vfree)) + vfree(darr); + else + kfree(darr); + + for (x = 0; x < l; x++) + brelse(larr[x]); + + if (leaves) { + if (unlikely(leaves_vfree)) + vfree(larr); + else + kfree(larr); + } + + return error; +} + +/** + * dir_e_search - Search exhash (leaf) dir for inode matching name + * @dip: The GFS inode + * @filename: Filename string + * @inode: If non-NULL, function fills with formal inode # and block address + * @type: If non-NULL, function fills with GFS_FILE_... dinode type + * + * Returns: + */ + +static int +dir_e_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type) +{ + struct buffer_head *bh; + struct gfs_dirent *dent; + int error; + + error = linked_leaf_search(dip, filename, &dent, NULL, &bh); + if (error) + return error; + + if (inum) + gfs_inum_in(inum, (char *)&dent->de_inum); + if (type) + *type = gfs16_to_cpu(dent->de_type); + + brelse(bh); + + return 0; +} + +/** + * dir_e_add - + * @dip: The GFS inode + * @filename: + * @inode: + * @type: + * + */ + +static int +dir_e_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type) +{ + struct buffer_head *bh, *nbh, *dibh; + struct gfs_leaf *leaf, *nleaf; + struct gfs_dirent *dent; + uint32_t hsize, index; + uint32_t hash; + uint64_t leaf_no, bn; + int error; + + restart: + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + /* Figure out the address of the leaf node. */ + + hash = gfs_dir_hash(filename->name, filename->len); + index = hash >> (32 - dip->i_di.di_depth); + + error = get_leaf_nr(dip, index, &leaf_no); + if (error) + return error; + + /* Add entry to the leaf */ + + for (;;) { + error = get_leaf(dip, leaf_no, &bh); + if (error) + return error; + + leaf = (struct gfs_leaf *)bh->b_data; + + if (gfs_dirent_alloc(dip, bh, filename->len, &dent)) { + + if (gfs16_to_cpu(leaf->lf_depth) < dip->i_di.di_depth) { + /* Can we split the leaf? */ + + brelse(bh); + + error = dir_split_leaf(dip, index, leaf_no); + if (error) + return error; + + goto restart; + + } else if (dip->i_di.di_depth < GFS_DIR_MAX_DEPTH) { + /* Can we double the hash table? */ + + brelse(bh); + + error = dir_double_exhash(dip); + if (error) + return error; + + goto restart; + + } else if (leaf->lf_next) { + /* Can we try the next leaf in the list? */ + leaf_no = gfs64_to_cpu(leaf->lf_next); + brelse(bh); + continue; + + } else { + /* Create a new leaf and add it to the list. */ + + error = gfs_metaalloc(dip, &bn); + if (error) { + brelse(bh); + return error; + } + + error = gfs_dread(dip->i_gl, bn, + DIO_NEW | DIO_START | DIO_WAIT, + &nbh); + if (error) { + brelse(bh); + return error; + } + + gfs_trans_add_bh(dip->i_gl, nbh); + gfs_metatype_set(nbh, + GFS_METATYPE_LF, + GFS_FORMAT_LF); + gfs_buffer_clear_tail(nbh, + sizeof(struct gfs_meta_header)); + + gfs_trans_add_bh(dip->i_gl, bh); + leaf->lf_next = cpu_to_gfs64(bn); + + nleaf = (struct gfs_leaf *)nbh->b_data; + nleaf->lf_depth = leaf->lf_depth; + nleaf->lf_dirent_format = cpu_to_gfs32(GFS_FORMAT_DE); + + gfs_dirent_alloc(dip, nbh, filename->len, &dent); + + dip->i_di.di_blocks++; + + brelse(bh); + + bh = nbh; + leaf = nleaf; + } + } + + /* If the gfs_dirent_alloc() succeeded, it pinned the "bh". */ + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_hash = cpu_to_gfs32(hash); + dent->de_type = cpu_to_gfs16(type); + memcpy((char *)(dent + 1), filename->name, filename->len); + + leaf->lf_entries = gfs16_to_cpu(leaf->lf_entries) + 1; + leaf->lf_entries = cpu_to_gfs16(leaf->lf_entries); + + brelse(bh); + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + dip->i_di.di_entries++; + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; + } + + return -ENOENT; +} + +/** + * dir_e_del - + * @dip: The GFS inode + * @filename: + * + * Returns: + */ + +static int +dir_e_del(struct gfs_inode *dip, struct qstr *filename) +{ + struct buffer_head *bh, *dibh; + struct gfs_dirent *dent, *prev; + struct gfs_leaf *leaf; + unsigned int entries; + int error; + + error = linked_leaf_search(dip, filename, &dent, &prev, &bh); + if (error == -ENOENT) { + gfs_consist_inode(dip); + return -EIO; + } + if (error) + return error; + + dirent_del(dip, bh, prev, dent); /* Pins bh */ + + leaf = (struct gfs_leaf *)bh->b_data; + entries = gfs16_to_cpu(leaf->lf_entries); + if (!entries) + gfs_consist_inode(dip); + entries--; + leaf->lf_entries = cpu_to_gfs16(entries); + + brelse(bh); + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + if (!dip->i_di.di_entries) + gfs_consist_inode(dip); + dip->i_di.di_entries--; + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * dir_e_read - Reads the entries from a directory into a filldir buffer + * @dip: dinode pointer + * @offset: the hash of the last entry read shifted to the right once + * @opaque: buffer for the filldir function to fill + * @filldir: points to the filldir function to use + * + * Returns: errno + */ + +static int +dir_e_read(struct gfs_inode *dip, uint64_t *offset, void *opaque, + gfs_filldir_t filldir) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *bh; + struct gfs_leaf leaf; + uint32_t hsize, len; + uint32_t ht_offset, lp_offset, ht_offset_cur = -1; + uint32_t hash, index; + uint64_t *lp; + int copied = FALSE; + int error = 0; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + hash = gfs_dir_offset2hash(*offset); + index = hash >> (32 - dip->i_di.di_depth); + + lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); + if (!lp) + return -ENOMEM; + + while (index < hsize) { + lp_offset = index & (sdp->sd_hash_ptrs - 1); + ht_offset = index - lp_offset; + + if (ht_offset_cur != ht_offset) { + error = gfs_internal_read(dip, (char *)lp, + ht_offset * sizeof(uint64_t), + sdp->sd_hash_bsize); + if (error != sdp->sd_hash_bsize) { + if (error >= 0) + error = -EIO; + goto out; + } + ht_offset_cur = ht_offset; + } + + error = get_leaf(dip, gfs64_to_cpu(lp[lp_offset]), &bh); + if (error) + goto out; + + gfs_leaf_in(&leaf, bh->b_data); + + if (leaf.lf_next) + error = do_filldir_multi(dip, offset, + opaque, filldir, + bh, &copied); + else + error = do_filldir_single(dip, offset, + opaque, filldir, + bh, leaf.lf_entries, + &copied); + + brelse(bh); + + if (error) { + if (error > 0) + error = 0; + goto out; + } + + len = 1 << (dip->i_di.di_depth - leaf.lf_depth); + index = (index & ~(len - 1)) + len; + } + + out: + kfree(lp); + + return error; +} + +/** + * dir_e_mvino - + * @dip: The GFS inode + * @filename: + * @new_inode: + * + * Returns: + */ + +static int +dir_e_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int new_type) +{ + struct buffer_head *bh, *dibh; + struct gfs_dirent *dent; + int error; + + error = linked_leaf_search(dip, filename, &dent, NULL, &bh); + if (error == -ENOENT) { + gfs_consist_inode(dip); + return -EIO; + } + if (error) + return error; + + gfs_trans_add_bh(dip->i_gl, bh); + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_type = cpu_to_gfs16(new_type); + + brelse(bh); + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * dir_l_search - Search linear (stuffed dinode) dir for inode matching name + * @dip: The GFS inode + * @filename: Filename string + * @inode: If non-NULL, function fills with formal inode # and block address + * @type: If non-NULL, function fills with GFS_FILE_... dinode type + * + * Returns: + */ + +static int +dir_l_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = leaf_search(dip, dibh, filename, &dent, NULL); + if (!error) { + if (inum) + gfs_inum_in(inum, (char *)&dent->de_inum); + if (type) + *type = gfs16_to_cpu(dent->de_type); + } + + brelse(dibh); + + return error; +} + +/** + * dir_l_add - + * @dip: The GFS inode + * @filename: + * @inode: + * @type: + * + * Returns: + */ + +static int +dir_l_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + if (gfs_dirent_alloc(dip, dibh, filename->len, &dent)) { + brelse(dibh); + + error = dir_make_exhash(dip); + if (!error) + error = dir_e_add(dip, filename, inum, type); + + return error; + } + + /* gfs_dirent_alloc() pins */ + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_hash = gfs_dir_hash(filename->name, filename->len); + dent->de_hash = cpu_to_gfs32(dent->de_hash); + dent->de_type = cpu_to_gfs16(type); + memcpy((char *)(dent + 1), filename->name, filename->len); + + dip->i_di.di_entries++; + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * dir_l_del - + * @dip: The GFS inode + * @filename: + * + * Returns: + */ + +static int +dir_l_del(struct gfs_inode *dip, struct qstr *filename) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent, *prev; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = leaf_search(dip, dibh, filename, &dent, &prev); + if (error == -ENOENT) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + if (error) + goto out; + + dirent_del(dip, dibh, prev, dent); + + /* dirent_del() pins */ + + if (!dip->i_di.di_entries) + gfs_consist_inode(dip); + dip->i_di.di_entries--; + + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&dip->i_di, dibh->b_data); + + out: + brelse(dibh); + + return error; +} + +/** + * dir_l_read - + * @dip: + * @offset: + * @opaque: + * @filldir: + * + * Returns: + */ + +static int +dir_l_read(struct gfs_inode *dip, uint64_t *offset, void *opaque, + gfs_filldir_t filldir) +{ + struct buffer_head *dibh; + int copied = FALSE; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + if (!dip->i_di.di_entries) + return 0; + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = do_filldir_single(dip, offset, + opaque, filldir, + dibh, dip->i_di.di_entries, + &copied); + if (error > 0) + error = 0; + + brelse(dibh); + + return error; +} + +/** + * dir_l_mvino - + * @dip: + * @filename: + * @new_inode: + * + * Returns: + */ + +static int +dir_l_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int new_type) +{ + struct buffer_head *dibh; + struct gfs_dirent *dent; + int error; + + if (!gfs_is_stuffed(dip)) { + gfs_consist_inode(dip); + return -EIO; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + return error; + + error = leaf_search(dip, dibh, filename, &dent, NULL); + if (error == -ENOENT) { + gfs_consist_inode(dip); + error = -EIO; + goto out; + } + if (error) + goto out; + + gfs_trans_add_bh(dip->i_gl, dibh); + + gfs_inum_out(inum, (char *)&dent->de_inum); + dent->de_type = cpu_to_gfs16(new_type); + + dip->i_di.di_mtime = dip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&dip->i_di, dibh->b_data); + + out: + brelse(dibh); + + return error; +} + +/** + * gfs_dir_search - Search a directory + * @dip: The GFS inode + * @filename: + * @inode: + * + * This routine searches a directory for a file or another directory. + * Assumes a glock is held on dip. + * + * Returns: errno + */ + +int +gfs_dir_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_search(dip, filename, inum, type); + else + error = dir_l_search(dip, filename, inum, type); + + return error; +} + +/** + * gfs_dir_add - Add new filename into directory + * @dip: The GFS inode + * @filename: The new name + * @inode: The inode number of the entry + * @type: The type of the entry + * + * Returns: 0 on success, error code on failure + */ + +int +gfs_dir_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_add(dip, filename, inum, type); + else + error = dir_l_add(dip, filename, inum, type); + + return error; +} + +/** + * gfs_dir_del - Delete a directory entry + * @dip: The GFS inode + * @filename: The filename + * + * Returns: 0 on success, error code on failure + */ + +int +gfs_dir_del(struct gfs_inode *dip, struct qstr *filename) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_del(dip, filename); + else + error = dir_l_del(dip, filename); + + return error; +} + +/** + * gfs_dir_read - Translate a GFS filename + * @dip: The GFS inode + * @offset: + * @opaque: + * @filldir: + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_dir_read(struct gfs_inode *dip, uint64_t * offset, void *opaque, + gfs_filldir_t filldir) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_read(dip, offset, opaque, filldir); + else + error = dir_l_read(dip, offset, opaque, filldir); + + return error; +} + +/** + * gfs_dir_mvino - Change inode number of directory entry + * @dip: The GFS inode + * @filename: + * @new_inode: + * + * This routine changes the inode number of a directory entry. It's used + * by rename to change ".." when a directory is moved. + * Assumes a glock is held on dvp. + * + * Returns: errno + */ + +int +gfs_dir_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int new_type) +{ + int error; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) + error = dir_e_mvino(dip, filename, inum, new_type); + else + error = dir_l_mvino(dip, filename, inum, new_type); + + return error; +} + +/** + * foreach_leaf - call a function for each leaf in a directory + * @dip: the directory + * @lc: the function to call for each each + * @data: private data to pass to it + * + * Returns: errno + */ + +static int +foreach_leaf(struct gfs_inode *dip, leaf_call_t lc, void *data) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *bh; + struct gfs_leaf leaf; + uint32_t hsize, len; + uint32_t ht_offset, lp_offset, ht_offset_cur = -1; + uint32_t index = 0; + uint64_t *lp; + uint64_t leaf_no; + int error = 0; + + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + lp = kmalloc(sdp->sd_hash_bsize, GFP_KERNEL); + if (!lp) + return -ENOMEM; + + while (index < hsize) { + lp_offset = index & (sdp->sd_hash_ptrs - 1); + ht_offset = index - lp_offset; + + if (ht_offset_cur != ht_offset) { + error = gfs_internal_read(dip, (char *)lp, + ht_offset * sizeof(uint64_t), + sdp->sd_hash_bsize); + if (error != sdp->sd_hash_bsize) { + if (error >= 0) + error = -EIO; + goto out; + } + ht_offset_cur = ht_offset; + } + + leaf_no = gfs64_to_cpu(lp[lp_offset]); + if (leaf_no) { + error = get_leaf(dip, leaf_no, &bh); + if (error) + goto out; + gfs_leaf_in(&leaf, bh->b_data); + brelse(bh); + + len = 1 << (dip->i_di.di_depth - leaf.lf_depth); + + error = lc(dip, index, len, leaf_no, data); + if (error) + goto out; + + index = (index & ~(len - 1)) + len; + } else + index++; + } + + if (index != hsize) { + gfs_consist_inode(dip); + error = -EIO; + } + + out: + kfree(lp); + + return error; +} + +/** + * leaf_free - Deallocate a directory leaf + * @dip: the directory + * @index: the hash table offset in the directory + * @len: the number of pointers to this leaf + * @leaf_no: the leaf number + * @data: not used + * + * Returns: errno + */ + +static int +leaf_free(struct gfs_inode *dip, + uint32_t index, uint32_t len, + uint64_t leaf_no, void *data) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_leaf tmp_leaf; + struct gfs_rgrp_list rlist; + struct buffer_head *bh, *dibh; + uint64_t blk; + unsigned int rg_blocks = 0; + char *ht=0; + unsigned int x, size = len * sizeof(uint64_t); + int error; + + memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); + + gfs_alloc_get(dip); + + error = gfs_quota_hold_m(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_rindex_hold(sdp, &dip->i_alloc->al_ri_gh); + if (error) + goto out_qs; + + /* Count the number of leaves */ + + for (blk = leaf_no; blk; blk = tmp_leaf.lf_next) { + error = get_leaf(dip, blk, &bh); + if (error) + goto out_rlist; + gfs_leaf_in(&tmp_leaf, (bh)->b_data); + brelse(bh); + + gfs_rlist_add(sdp, &rlist, blk); + } + + gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); + + for (x = 0; x < rlist.rl_rgrps; x++) { + struct gfs_rgrpd *rgd; + rgd = get_gl2rgd(rlist.rl_ghs[x].gh_gl); + rg_blocks += rgd->rd_ri.ri_length; + } + + error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); + if (error) + goto out_rlist; + + /* Trans may require: + All the bitmaps that were reserved. + One block for the dinode. + All the hash blocks that will be changed. + One block for a quota change. */ + + error = gfs_trans_begin(sdp, + rg_blocks + 1 + (DIV_RU(size, sdp->sd_jbsize) + 1), + 1); + if (error) + goto out_rg_gunlock; + + for (blk = leaf_no; blk; blk = tmp_leaf.lf_next) { + error = get_leaf(dip, blk, &bh); + if (error) + goto out_end_trans; + gfs_leaf_in(&tmp_leaf, bh->b_data); + brelse(bh); + + gfs_metafree(dip, blk, 1); + + if (!dip->i_di.di_blocks) + gfs_consist_inode(dip); + dip->i_di.di_blocks--; + } + + error = gfs_writei(dip, ht, index * sizeof (uint64_t), size, gfs_zero_blocks, NULL); + + if (error != size) { + if (error >= 0) + error = -EIO; + goto out_end_trans; + } + + error = gfs_get_inode_buffer(dip, &dibh); + if (error) + goto out_end_trans; + + gfs_trans_add_bh(dip->i_gl, dibh); + gfs_dinode_out(&dip->i_di, dibh->b_data); + brelse(dibh); + + out_end_trans: + gfs_trans_end(sdp); + + out_rg_gunlock: + gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); + + out_rlist: + gfs_rlist_free(&rlist); + gfs_glock_dq_uninit(&dip->i_alloc->al_ri_gh); + + out_qs: + gfs_quota_unhold_m(dip); + + out: + gfs_alloc_put(dip); + + return error; +} + +/** + * gfs_dir_exhash_free - free all the leaf blocks in a directory + * @dip: the directory + * + * Dealloc all on-disk directory leaves to FREEMETA state + * Change on-disk inode type to "regular file" + * + * Returns: errno + */ + +int +gfs_dir_exhash_free(struct gfs_inode *dip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct buffer_head *bh; + int error; + + /* Dealloc on-disk leaves to FREEMETA state */ + error = foreach_leaf(dip, leaf_free, NULL); + if (error) + return error; + + /* Make this a regular file in case we crash. + (We don't want to free these blocks a second time.) */ + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + return error; + + error = gfs_get_inode_buffer(dip, &bh); + if (!error) { + gfs_trans_add_bh(dip->i_gl, bh); + ((struct gfs_dinode *)bh->b_data)->di_type = cpu_to_gfs16(GFS_FILE_REG); + brelse(bh); + } + + gfs_trans_end(sdp); + + return error; +} + +/** + * gfs_diradd_alloc_required - figure out if an entry addition is going to require an allocation + * @ip: the file being written to + * @filname: the filename that's going to be added + * @alloc_required: the int is set to TRUE if an alloc is required, FALSE otherwise + * + * Returns: errno + */ + +int +gfs_diradd_alloc_required(struct gfs_inode *dip, struct qstr *filename, + int *alloc_required) +{ + struct buffer_head *bh = NULL, *bh_next; + uint32_t hsize, hash, index; + int error = 0; + + *alloc_required = FALSE; + + if (dip->i_di.di_flags & GFS_DIF_EXHASH) { + hsize = 1 << dip->i_di.di_depth; + if (hsize * sizeof(uint64_t) != dip->i_di.di_size) { + gfs_consist_inode(dip); + return -EIO; + } + + hash = gfs_dir_hash(filename->name, filename->len); + index = hash >> (32 - dip->i_di.di_depth); + + error = get_first_leaf(dip, index, &bh_next); + if (error) + return error; + + do { + if (bh) + brelse(bh); + + bh = bh_next; + + if (dirent_fits(dip, bh, filename->len)) + break; + + error = get_next_leaf(dip, bh, &bh_next); + if (error == -ENOENT) { + *alloc_required = TRUE; + error = 0; + break; + } + } + while (!error); + + brelse(bh); + } else { + error = gfs_get_inode_buffer(dip, &bh); + if (error) + return error; + + if (!dirent_fits(dip, bh, filename->len)) + *alloc_required = TRUE; + + brelse(bh); + } + + return error; +} + +/** + * do_gdm - copy out one leaf (or list of leaves) + * @dip: the directory + * @index: the hash table offset in the directory + * @len: the number of pointers to this leaf + * @leaf_no: the leaf number + * @data: a pointer to a struct gfs_user_buffer structure + * + * Returns: errno + */ + +static int +do_gdm(struct gfs_inode *dip, + uint32_t index, uint32_t len, uint64_t leaf_no, + void *data) +{ + struct gfs_user_buffer *ub = (struct gfs_user_buffer *)data; + struct gfs_leaf leaf; + struct buffer_head *bh; + uint64_t blk; + int error = 0; + + for (blk = leaf_no; blk; blk = leaf.lf_next) { + error = get_leaf(dip, blk, &bh); + if (error) + break; + + gfs_leaf_in(&leaf, bh->b_data); + + error = gfs_add_bh_to_ub(ub, bh); + + brelse(bh); + + if (error) + break; + } + + return error; +} + +/** + * gfs_get_dir_meta - return all the leaf blocks of a directory + * @dip: the directory + * @ub: the structure representing the meta + * + * Returns: errno + */ + +int +gfs_get_dir_meta(struct gfs_inode *dip, struct gfs_user_buffer *ub) +{ + return foreach_leaf(dip, do_gdm, ub); +} --- linux-2.6.28.orig/ubuntu/gfs/daemon.h +++ linux-2.6.28/ubuntu/gfs/daemon.h @@ -0,0 +1,11 @@ +#ifndef __DAEMON_DOT_H__ +#define __DAEMON_DOT_H__ + +int gfs_scand(void *data); +int gfs_glockd(void *data); +int gfs_recoverd(void *data); +int gfs_logd(void *data); +int gfs_quotad(void *data); +int gfs_inoded(void *data); + +#endif /* __DAEMON_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_dentry.h +++ linux-2.6.28/ubuntu/gfs/ops_dentry.h @@ -0,0 +1,6 @@ +#ifndef __OPS_DENTRY_DOT_H__ +#define __OPS_DENTRY_DOT_H__ + +extern struct dentry_operations gfs_dops; + +#endif /* __OPS_DENTRY_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/gfs_ondisk.h +++ linux-2.6.28/ubuntu/gfs/gfs_ondisk.h @@ -0,0 +1,1904 @@ +/* + * On-disk structures. + * + * THE BIG PICTURE of on-disk layout: + * + * GFS filesystem code views the entire filesystem, including journals, as + * one contiguous group of blocks on one (perhaps virtual) storage device. + * The filesystem space is shared, not distributed; each node in the cluster + * must see the entire filesystem space. + * + * If the filesystem is spread across multiple physical storage devices, + * volume management (device mapping) must be used to present the fileystem + * space to GFS as one (virtual) device, with contiguous blocks. + * + * The superblock contains basic information about the filesytem, and appears + * at a location 64 KBytes into the filesystem. The first 64 KBytes of the + * filesystem are empty, providing a safety buffer against wayward volume + * management software (that sometimes write data into the first few bytes of + * a device) or administrators. + * + * After the superblock, the rest of the filesystem is divided into multiple + * Resource Groups and several journals. + * + * The Resource Groups (RGs or rgrps) contain the allocatable blocks that are + * used for storing files, directories, etc., and all of the associated + * metadata. Each RG has its own set of block allocation statistics (within + * the RG header), a number of blocks containing the block allocation bitmap, + * and a large number of allocatable blocks for file data and metadata. + * Multiple RGs allow multiple nodes to simultaneously allocate blocks from the + * filesystem (using different RGs), enhancing parallel access. RG size and + * number of RGs are determined by gfs_mkfs when creating the filesystem. + * An administrator can specify RG size (see man gfs_mkfs). + * + * The journals contain temporary copies of metadata blocks, along with + * other data, that allow GFS to recover the filesystem to a consistent state + * (at least as far as metadata is concerned) if a node fails in the midst + * of performing a write transaction. There must be one journal for each node + * in the cluster. Since access to the entire filesystem space is shared, + * if a node crashes, another node will be able to read the crashed node's + * journal, and perform recovery. + * + * Currently, gfs_mkfs places the journals right in the middle of a freshly + * created filesystem space, between 2 large groups of RGs. From a filesystem + * layout perspective, this placement is not a requirement; the journals + * could be placed anywhere within the filesystem space. + * + * New Resource Groups and Journals may be added to the filesystem after the + * filesystem has been created, if the filesystem's (virtual) device is made + * larger. See man gfs_grow and gfs_jadd. + * + * A few special hidden inodes are contained in a GFS filesystem. They do + * not appear in any directories; instead, the superblock points to them + * using block numbers for their location. The special inodes are: + * + * Root inode: Root directory of the filesystem + * Resource Group Index: A file containing block numbers and sizes of all RGs + * Journal Index: A file containing block numbers and sizes of all journals + * Quota: A file containing all quota information for the filesystem + * License: A file containing license information + * + * Note that there is NOTHING RELATED TO INTER-NODE LOCK MANAGEMENT ON-DISK. + * Locking is handled completely off-disk, typically via LAN. + * + * NOTE: + * If you add 8 byte fields to these structures, they must be 8 byte + * aligned. 4 byte field must be 4 byte aligned, etc... + * + * All structures must be a multiple of 8 bytes long. + * + * GRIPES: + * We should have forgetten about supporting 512B FS block sizes + * and made the di_reserved field in the struct gfs_dinode structure + * much bigger. + * + * de_rec_len in struct gfs_dirent should really have been a 32-bit value + * as it now limits us to a 64k FS block size (with the current code + * in dir.c). + */ + +#ifndef __GFS_ONDISK_DOT_H__ +#define __GFS_ONDISK_DOT_H__ + +#define GFS_MAGIC (0x01161970) /* for all on-disk headers */ +#define GFS_BASIC_BLOCK (512) /* "basic block" = "sector" = 512B */ +#define GFS_BASIC_BLOCK_SHIFT (9) + +/* Controls how much data can be logged in-core before dumping log to disk */ + +#define GFS_DUMPS_PER_LOG (4) /* 1/4 of on-disk journal size*/ + +/* Lock numbers of the LM_TYPE_NONDISK type. These protect certain + * cluster-wide operations (rather than on-disk entities). + * Currently, the LIVE lock is not used for any real purpose. */ + +#define GFS_MOUNT_LOCK (0) /* only one node can Mount at a time */ +#define GFS_LIVE_LOCK (1) /* shared by all mounted nodes */ +#define GFS_TRANS_LOCK (2) /* Transaction, protects jrnl recovery */ +#define GFS_RENAME_LOCK (3) /* only one node can Rename at a time */ + +/* On-disk format (version) numbers for various metadata types, + * used in gfs_meta_header */ + +#define GFS_FORMAT_SB (100) /* Super-Block */ +#define GFS_FORMAT_RG (200) /* Resource Group Header */ +#define GFS_FORMAT_RB (300) /* Resource Group Block Alloc BitBlock */ +#define GFS_FORMAT_DI (400) /* "Disk" inode (dinode) */ +#define GFS_FORMAT_IN (500) /* Indirect dinode block list */ +#define GFS_FORMAT_LF (600) /* Leaf dinode block list */ +#define GFS_FORMAT_JD (700) /* Journal Data */ +#define GFS_FORMAT_LH (800) /* Log Header */ +#define GFS_FORMAT_LD (900) /* Log Descriptor */ +/* These don't have actual struct gfs_meta_header structures to go with them */ +#define GFS_FORMAT_JI (1000) /* Journal Index */ +#define GFS_FORMAT_RI (1100) /* Resource Group Index */ +#define GFS_FORMAT_DE (1200) /* Directory Entry */ +#define GFS_FORMAT_QU (1500) /* Quota */ +#define GFS_FORMAT_EA (1600) /* Extended Attribute */ +#define GFS_FORMAT_ED (1700) /* Extended Attribute data */ +/* These version #s are embedded in the superblock */ +#define GFS_FORMAT_FS (1309) /* Filesystem (all-encompassing) */ +#define GFS_FORMAT_MULTI (1401) /* Multi-Host */ + +/* + * An on-disk inode number + * Initially, the on-disk block address of the inode block is assigned as the + * formal (permanent) ID as well. Block address can change (to move inode + * on-disk), but formal ID must stay unchanged once assigned. + */ + +#define gfs_inum_equal(ino1, ino2) \ +(((ino1)->no_formal_ino == (ino2)->no_formal_ino) && \ + ((ino1)->no_addr == (ino2)->no_addr)) + +struct gfs_inum { + uint64_t no_formal_ino; /* inode identifier */ + uint64_t no_addr; /* block # of dinode block */ +}; + +/* + * Generic metadata head structure + * + * Every inplace buffer logged in the journal must start + * with a struct gfs_meta_header. + * + * In addition to telling what kind of metadata is in the block, + * the metaheader contains the important generation and incarnation + * numbers. + * + * The generation number is used during journal recovery to determine + * whether an in-place block on-disk is older than an on-disk journaled copy + * of the block. If so, GFS overwrites the in-place block with the journaled + * version of the block. + * + * A meta block's generation number must increment monotonically across the + * cluster, each time new contents are committed to the block. This means + * that whenever GFS allocates a pre-existing metadata block, GFS must read + * that block from disk (in case another node has incremented it). It also + * means that GFS must sync the block (with incremented generation number) + * to disk (both log and in-place blocks), not only after changing contents + * of the block, but also after de-allocating the block (GFS can't just throw + * away incore metadata for a file that it's just erased). + * + * The incarnation number is used only for on-disk (d)inodes. GFS increments + * it each time it de-allocates a dinode block (i.e. each time the dinode + * loses its identity with a particular file, directory, etc.). When the + * dinode is later allocated (i.e. to be identified with a new file, etc.), + * GFS copies the incarnation number into the VFS inode's i_generation member. + * If GFS is used as the backing store for an NFS server, GFS uses this + * i_generation number as part of the NFS filehandle, which differentiates + * it from the previous identity of the dinode, and helps protect against + * filesystem corruption that could happen with the use of outdated, + * invalid, or malicious filehandles. See ops_export.c. + * + * GFS caches de-allocated meta-headers, to minimize disk reads. + * See struct gfs_meta_header_cache. + */ + +#define GFS_METATYPE_NONE (0) +#define GFS_METATYPE_SB (1) /* Super-Block */ +#define GFS_METATYPE_RG (2) /* Resource Group Header */ +#define GFS_METATYPE_RB (3) /* Resource Group Block Alloc BitBlock */ +#define GFS_METATYPE_DI (4) /* "Disk" inode (dinode) */ +#define GFS_METATYPE_IN (5) /* Indirect dinode block list */ +#define GFS_METATYPE_LF (6) /* Leaf dinode block list */ +#define GFS_METATYPE_JD (7) /* Journal Data */ +#define GFS_METATYPE_LH (8) /* Log Header (gfs_log_header) */ +#define GFS_METATYPE_LD (9) /* Log Descriptor (gfs_log_descriptor) */ +#define GFS_METATYPE_EA (10) /* Extended Attribute */ +#define GFS_METATYPE_ED (11) /* Extended Attribute data */ + +#define GFS_META_CLUMP (64) /* # blocks to convert fm data to meta */ + +struct gfs_meta_header { + uint32_t mh_magic; /* GFS_MAGIC sanity check magic number */ + uint32_t mh_type; /* GFS_METATYPE_XX type of metadata block */ + uint64_t mh_generation; /* increment before writing to journal */ + uint32_t mh_format; /* GFS_FORMAT_XX (version # for this type) */ + uint32_t mh_incarn; /* increment when marking dinode "unused" */ +}; + +/* + * super-block structure + * + * One of these is at beginning of filesystem. + * It's probably good if SIZEOF_SB <= GFS_BASIC_BLOCK (512 bytes) + */ + +/* Address of SuperBlock in GFS basic blocks. 1st 64K of filesystem is empty + for safety against getting clobbered by wayward volume managers, etc. + 64k was chosen because it's the largest GFS-supported fs block size. */ +#define GFS_SB_ADDR (128) + +/* The lock number for the superblock (must be zero) */ +#define GFS_SB_LOCK (0) +#define GFS_CRAP_LOCK (1) + +/* Requirement: GFS_LOCKNAME_LEN % 8 == 0 + Includes: the fencing zero at the end */ +#define GFS_LOCKNAME_LEN (64) + +struct gfs_sb { + /* Order is important; need to be able to read old superblocks + in order to support on-disk version upgrades */ + struct gfs_meta_header sb_header; + + uint32_t sb_fs_format; /* GFS_FORMAT_FS (on-disk version) */ + uint32_t sb_multihost_format; /* GFS_FORMAT_MULTI */ + uint32_t sb_flags; /* ?? */ + + uint32_t sb_bsize; /* fundamental FS block size in bytes */ + uint32_t sb_bsize_shift; /* log2(sb_bsize) */ + uint32_t sb_seg_size; /* Journal segment size in FS blocks */ + + /* These special inodes do not appear in any on-disk directory. */ + struct gfs_inum sb_jindex_di; /* journal index inode */ + struct gfs_inum sb_rindex_di; /* resource group index inode */ + struct gfs_inum sb_root_di; /* root directory inode */ + + /* Default inter-node locking protocol (lock module) and namespace */ + char sb_lockproto[GFS_LOCKNAME_LEN]; /* lock protocol name */ + char sb_locktable[GFS_LOCKNAME_LEN]; /* unique name for this FS */ + + /* More special inodes */ + struct gfs_inum sb_quota_di; /* quota inode */ + struct gfs_inum sb_license_di; /* license inode */ + + char sb_reserved[96]; +}; + +/* + * journal index structure + * + * One for each journal used by the filesystem. + * These descriptors are packed contiguously within the jindex inode (file). + */ + +struct gfs_jindex { + uint64_t ji_addr; /* starting block of the journal */ + uint32_t ji_nsegment; /* number (quantity) of segments in journal */ + uint32_t ji_pad; + + char ji_reserved[64]; +}; + +/* + * resource index structure + * + * One of these for each resource group in the filesystem. + * These descriptors are packed contiguously within the rindex inode (file). + * Also see struct gfs_rgrp. + */ + +struct gfs_rindex { + uint64_t ri_addr; /* block # of 1st block (header) in rgrp */ + uint32_t ri_length; /* # fs blocks containing rgrp header & bitmap */ + uint32_t ri_pad; + + uint64_t ri_data1; /* block # of first data/meta block in rgrp */ + uint32_t ri_data; /* number (qty) of data/meta blocks in rgrp */ + + uint32_t ri_bitbytes; /* total # bytes used by block alloc bitmap */ + + char ri_reserved[64]; +}; + +/* + * resource group header structure + * + * One of these at beginning of the first block of an rgrp, + * followed by block alloc bitmap data in remainder of first block. + * Each resource group contains: + * Header block, including block allocation statistics (struct gfs_rgrp) + * and first part of block alloc bitmap. + * Bitmap block(s), continuing block alloc bitmap started in header block. + * Data/meta blocks, allocatable blocks containing file data and metadata. + * + * In older versions, now-unused (but previously allocated) dinodes were + * saved for re-use in an on-disk linked list (chain). This is no longer + * done, but support still exists for reclaiming dinodes from this list, + * to support upgrades from older on-disk formats. + */ + +/* Each data block within rgrp is represented by 2 bits in the alloc bitmap */ +#define GFS_NBBY (4) /* # blocks represented by 1 bitmap byte */ +#define GFS_BIT_SIZE (2) +#define GFS_BIT_MASK (0x00000003) + +/* + * 4 possible block allocation states: + * bit 0 = alloc(1)/free(0) + * bit 1 = metadata(1)/data(0) + */ +#define GFS_BLKST_FREE (0) +#define GFS_BLKST_USED (1) +#define GFS_BLKST_FREEMETA (2) +#define GFS_BLKST_USEDMETA (3) + +struct gfs_rgrp { + struct gfs_meta_header rg_header; + + uint32_t rg_flags; /* ?? */ + + uint32_t rg_free; /* Number (qty) of free data blocks */ + + /* Dinodes are USEDMETA, but are handled separately from other METAs */ + uint32_t rg_useddi; /* Number (qty) of dinodes (used or free) */ + uint32_t rg_freedi; /* Number (qty) of unused (free) dinodes */ + struct gfs_inum rg_freedi_list; /* 1st block in chain of free dinodes */ + + /* These META statistics do not include dinodes (used or free) */ + uint32_t rg_usedmeta; /* Number (qty) of used metadata blocks */ + uint32_t rg_freemeta; /* Number (qty) of unused metadata blocks */ + + char rg_reserved[64]; +}; + +/* + * quota structure + */ + +struct gfs_quota { + uint64_t qu_limit; + uint64_t qu_warn; + int64_t qu_value; + + char qu_reserved[64]; +}; + +/* + * dinode (disk inode) structure + * The ondisk representation of inodes + * One for each file, directory, etc. + * GFS does not put more than one inode in a single block. + * The inode may be "stuffed", carrying file data along with metadata, + * if the file data is small enough. + * Otherwise, the inode block contains pointers to other blocks that contain + * either file data or other pointers to other blocks (indirect addressing + * via a metadata tree). + */ + +#define GFS_MAX_META_HEIGHT (10) +#define GFS_DIR_MAX_DEPTH (17) + +/* Dinode types */ +#define GFS_FILE_NON (0) +#define GFS_FILE_REG (1) /* regular file */ +#define GFS_FILE_DIR (2) /* directory */ +#define GFS_FILE_LNK (5) /* link */ +#define GFS_FILE_BLK (7) /* block device node */ +#define GFS_FILE_CHR (8) /* character device node */ +#define GFS_FILE_FIFO (101) /* fifo/pipe */ +#define GFS_FILE_SOCK (102) /* socket */ + +/* Dinode flags */ +#define GFS_DIF_JDATA (0x00000001) /* jrnl all data for this file */ +#define GFS_DIF_EXHASH (0x00000002) /* hashed directory (leaves) */ +#define GFS_DIF_UNUSED (0x00000004) /* unused dinode */ +#define GFS_DIF_EA_INDIRECT (0x00000008) /* extended attribute, indirect*/ +#define GFS_DIF_DIRECTIO (0x00000010) +#define GFS_DIF_IMMUTABLE (0x00000020) /* Can't change file */ +#define GFS_DIF_APPENDONLY (0x00000040) /* Can only add to end of file */ +#define GFS_DIF_NOATIME (0x00000080) /* Don't update access time + (currently unused/ignored) */ +#define GFS_DIF_SYNC (0x00000100) /* Flush to disk, don't cache + (currently unused/ignored) */ +#define GFS_DIF_INHERIT_DIRECTIO (0x40000000) /* new files get DIRECTIO flag */ +#define GFS_DIF_INHERIT_JDATA (0x80000000) /* new files get JDATA flag */ + +struct gfs_dinode { + struct gfs_meta_header di_header; + + struct gfs_inum di_num; /* formal inode # and block address */ + + uint32_t di_mode; /* mode of file */ + uint32_t di_uid; /* owner's user id */ + uint32_t di_gid; /* owner's group id */ + uint32_t di_nlink; /* number (qty) of links to this file */ + uint64_t di_size; /* number (qty) of bytes in file */ + uint64_t di_blocks; /* number (qty) of blocks in file */ + int64_t di_atime; /* time last accessed */ + int64_t di_mtime; /* time last modified */ + int64_t di_ctime; /* time last changed */ + + /* Non-zero only for character or block device nodes */ + uint32_t di_major; /* device major number */ + uint32_t di_minor; /* device minor number */ + + /* Block allocation strategy */ + uint64_t di_rgrp; /* dinode rgrp block number */ + uint64_t di_goal_rgrp; /* rgrp to alloc from next */ + uint32_t di_goal_dblk; /* data block goal */ + uint32_t di_goal_mblk; /* metadata block goal */ + + uint32_t di_flags; /* GFS_DIF_... */ + + /* struct gfs_rindex, struct gfs_jindex, or struct gfs_dirent */ + uint32_t di_payload_format; /* GFS_FORMAT_... */ + uint16_t di_type; /* GFS_FILE_... type of file */ + uint16_t di_height; /* height of metadata (0 == stuffed) */ + uint32_t di_incarn; /* incarnation (unused, see gfs_meta_header) */ + uint16_t di_pad; + + /* These only apply to directories */ + uint16_t di_depth; /* Number of bits in the table */ + uint32_t di_entries; /* The # (qty) of entries in the directory */ + + /* This formed an on-disk chain of unused dinodes */ + struct gfs_inum di_next_unused; /* used in old versions only */ + + uint64_t di_eattr; /* extended attribute block number */ + + char di_reserved[56]; +}; + +/* + * indirect block header + * + * A component of a dinode's indirect addressing metadata tree. + * These are pointed to by pointers in dinodes or other indirect blocks. + */ + +struct gfs_indirect { + struct gfs_meta_header in_header; + + char in_reserved[64]; +}; + +/* + * directory structure - many of these per directory file + * + * See comments at beginning of dir.c + */ + +#define GFS_FNAMESIZE (255) +#define GFS_DIRENT_SIZE(name_len) ((sizeof(struct gfs_dirent) + (name_len) + 7) & ~7) +#define IS_LEAF (1) /* Hashed (leaf) directory */ +#define IS_DINODE (2) /* Linear (stuffed dinode block) directory */ + +struct gfs_dirent { + struct gfs_inum de_inum; /* formal inode number and block address */ + uint32_t de_hash; /* hash of the filename */ + uint16_t de_rec_len; /* the length of the dirent */ + uint16_t de_name_len; /* the length of the name */ + uint16_t de_type; /* GFS_FILE_... type of dinode this points to */ + + char de_reserved[14]; +}; + +/* + * Header of leaf directory nodes + * + * See comments at beginning of dir.c + */ + +struct gfs_leaf { + struct gfs_meta_header lf_header; + + uint16_t lf_depth; /* Depth of leaf */ + uint16_t lf_entries; /* Number of dirents in leaf */ + uint32_t lf_dirent_format; /* GFS_FORMAT_DE (version #) */ + uint64_t lf_next; /* Next leaf, if overflow */ + + char lf_reserved[64]; +}; + +/* + * Log header structure + * + * Two of these are in the first block of a transaction log: + * 1) at beginning of block + * 2) at end of first 512-byte sector within block + */ + +#define GFS_LOG_HEAD_UNMOUNT (0x00000001) /* log is clean, can unmount fs */ + +struct gfs_log_header { + struct gfs_meta_header lh_header; + + uint32_t lh_flags; /* GFS_LOG_HEAD_... */ + uint32_t lh_pad; + + uint64_t lh_first; /* Block number of first header in this trans */ + uint64_t lh_sequence; /* Sequence number of this transaction */ + + uint64_t lh_tail; /* Block number of log tail */ + uint64_t lh_last_dump; /* Block number of last dump */ + + char lh_reserved[64]; +}; + +/* + * Log type descriptor + * + * One of these for each chunk in a transaction + */ + +#define GFS_LOG_DESC_METADATA (300) /* metadata */ +/* ld_data1 is the number (quantity) of metadata blocks in the descriptor. + ld_data2 is unused. + */ + +#define GFS_LOG_DESC_IUL (400) /* unlinked inode */ +/* ld_data1 is TRUE if this is a dump. + ld_data2 is unused. + FixMe!!! ld_data1 should be the number (quantity) of entries. + ld_data2 should be "TRUE if this is a dump". + */ + +#define GFS_LOG_DESC_IDA (401) /* de-allocated inode */ +/* ld_data1 is unused. + ld_data2 is unused. + FixMe!!! ld_data1 should be the number (quantity) of entries. + */ + +#define GFS_LOG_DESC_Q (402) /* quota */ +/* ld_data1 is the number of quota changes in the descriptor. + ld_data2 is TRUE if this is a dump. + */ + +#define GFS_LOG_DESC_LAST (500) /* final in a logged transaction */ +/* ld_data1 is unused. + ld_data2 is unused. + */ + +struct gfs_log_descriptor { + struct gfs_meta_header ld_header; + + uint32_t ld_type; /* GFS_LOG_DESC_... Type of this log chunk */ + uint32_t ld_length; /* Number of buffers in this chunk */ + uint32_t ld_data1; /* descriptor-specific field */ + uint32_t ld_data2; /* descriptor-specific field */ + + char ld_reserved[64]; +}; + +/* + * Metadata block tags + * + * One for each logged block. Tells where block really belongs on-disk. + * These descriptor tags are packed contiguously after a gfs_log_descriptor. + */ + +struct gfs_block_tag { + uint64_t bt_blkno; /* inplace block number */ + uint32_t bt_flags; /* ?? */ + uint32_t bt_pad; +}; + +/* + * Quota Journal Tag + */ + +#define GFS_QTF_USER (0x00000001) + +struct gfs_quota_tag { + int64_t qt_change; + uint32_t qt_flags; /* GFS_QTF_... */ + uint32_t qt_id; +}; + +/* + * Extended attribute header format + */ + +#define GFS_EA_MAX_NAME_LEN (255) +#define GFS_EA_MAX_DATA_LEN (65536) + +#define GFS_EATYPE_UNUSED (0) +#define GFS_EATYPE_USR (1) /* user attribute */ +#define GFS_EATYPE_SYS (2) /* system attribute */ +#define GFS_EATYPE_SECURITY (3) /* security attribute */ + +#define GFS_EATYPE_LAST (3) +#define GFS_EATYPE_VALID(x) ((x) <= GFS_EATYPE_LAST) + +#define GFS_EAFLAG_LAST (0x01) /* last ea in block */ + +struct gfs_ea_header { + uint32_t ea_rec_len; /* total record length: hdr + name + data */ + uint32_t ea_data_len; /* data length, in bytes */ + uint8_t ea_name_len; /* no NULL pointer after the string */ + uint8_t ea_type; /* GFS_EATYPE_... */ + uint8_t ea_flags; /* GFS_EAFLAG_... */ + uint8_t ea_num_ptrs; /* # fs blocks needed for EA */ + uint32_t ea_pad; +}; + +/* + * Statfs change + * Describes an change to the pool of free and allocated + * blocks. + */ + +struct gfs_statfs_change { + uint64_t sc_total; + uint64_t sc_free; + uint64_t sc_dinodes; +}; + +struct gfs_statfs_change_host { + int64_t sc_total; + int64_t sc_free; + int64_t sc_dinodes; +}; + +/* Endian functions */ + +#define GFS_ENDIAN_BIG + +#ifdef GFS_ENDIAN_BIG + +#define gfs16_to_cpu be16_to_cpu +#define gfs32_to_cpu be32_to_cpu +#define gfs64_to_cpu be64_to_cpu + +#define cpu_to_gfs16 cpu_to_be16 +#define cpu_to_gfs32 cpu_to_be32 +#define cpu_to_gfs64 cpu_to_be64 + +#else /* GFS_ENDIAN_BIG */ + +#define gfs16_to_cpu le16_to_cpu +#define gfs32_to_cpu le32_to_cpu +#define gfs64_to_cpu le64_to_cpu + +#define cpu_to_gfs16 cpu_to_le16 +#define cpu_to_gfs32 cpu_to_le32 +#define cpu_to_gfs64 cpu_to_le64 + +#endif /* GFS_ENDIAN_BIG */ + +/* Translation functions */ + +void gfs_inum_in(struct gfs_inum *no, char *buf); +void gfs_inum_out(struct gfs_inum *no, char *buf); +void gfs_meta_header_in(struct gfs_meta_header *mh, char *buf); +void gfs_meta_header_out(struct gfs_meta_header *mh, char *buf); +void gfs_sb_in(struct gfs_sb *sb, char *buf); +void gfs_sb_out(struct gfs_sb *sb, char *buf); +void gfs_jindex_in(struct gfs_jindex *jindex, char *buf); +void gfs_jindex_out(struct gfs_jindex *jindex, char *buf); +void gfs_rindex_in(struct gfs_rindex *rindex, char *buf); +void gfs_rindex_out(struct gfs_rindex *rindex, char *buf); +void gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf); +void gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf); +void gfs_quota_in(struct gfs_quota *quota, char *buf); +void gfs_quota_out(struct gfs_quota *quota, char *buf); +void gfs_dinode_in(struct gfs_dinode *dinode, char *buf); +void gfs_dinode_out(struct gfs_dinode *dinode, char *buf); +void gfs_indirect_in(struct gfs_indirect *indirect, char *buf); +void gfs_indirect_out(struct gfs_indirect *indirect, char *buf); +void gfs_dirent_in(struct gfs_dirent *dirent, char *buf); +void gfs_dirent_out(struct gfs_dirent *dirent, char *buf); +void gfs_leaf_in(struct gfs_leaf *leaf, char *buf); +void gfs_leaf_out(struct gfs_leaf *leaf, char *buf); +void gfs_log_header_in(struct gfs_log_header *head, char *buf); +void gfs_log_header_out(struct gfs_log_header *head, char *buf); +void gfs_desc_in(struct gfs_log_descriptor *desc, char *buf); +void gfs_desc_out(struct gfs_log_descriptor *desc, char *buf); +void gfs_block_tag_in(struct gfs_block_tag *btag, char *buf); +void gfs_block_tag_out(struct gfs_block_tag *btag, char *buf); +void gfs_quota_tag_in(struct gfs_quota_tag *qtag, char *buf); +void gfs_quota_tag_out(struct gfs_quota_tag *qtag, char *buf); +void gfs_ea_header_in(struct gfs_ea_header *qtag, char *buf); +void gfs_ea_header_out(struct gfs_ea_header *qtag, char *buf); + +/* Printing functions */ + +void gfs_inum_print(struct gfs_inum *no); +void gfs_meta_header_print(struct gfs_meta_header *mh); +void gfs_sb_print(struct gfs_sb *sb); +void gfs_jindex_print(struct gfs_jindex *jindex); +void gfs_rindex_print(struct gfs_rindex *rindex); +void gfs_rgrp_print(struct gfs_rgrp *rgrp); +void gfs_quota_print(struct gfs_quota *quota); +void gfs_dinode_print(struct gfs_dinode *dinode); +void gfs_indirect_print(struct gfs_indirect *indirect); +void gfs_dirent_print(struct gfs_dirent *dirent, char *name); +void gfs_leaf_print(struct gfs_leaf *leaf); +void gfs_log_header_print(struct gfs_log_header *head); +void gfs_desc_print(struct gfs_log_descriptor *desc); +void gfs_block_tag_print(struct gfs_block_tag *tag); +void gfs_quota_tag_print(struct gfs_quota_tag *tag); +void gfs_ea_header_print(struct gfs_ea_header *ea, char *name); + +/* The hash function for ExHash directories */ + +uint32_t gfs_dir_hash(const char *data, int len); + +#endif /* __GFS_ONDISK_DOT_H__ */ + + + +#ifdef WANT_GFS_CONVERSION_FUNCTIONS + +#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} +#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} +#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} +#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} +#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} +#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} +#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} +#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} + +#define pa(struct, member, count) print_array(#member, struct->member, count); + +/** + * print_array - Print out an array of bytes + * @title: what to print before the array + * @buf: the array + * @count: the number of bytes + * + */ + +static void +print_array(char *title, char *buf, int count) +{ + int x; + + printk(" %s =\n", title); + for (x = 0; x < count; x++) { + printk("%.2X ", (unsigned char)buf[x]); + if (x % 16 == 15) + printk("\n"); + } + if (x % 16) + printk("\n"); +} + +/** + * gfs_inum_in - Read in an inode number + * @no: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_inum_in(struct gfs_inum *no, char *buf) +{ + struct gfs_inum *str = (struct gfs_inum *)buf; + + CPIN_64(no, str, no_formal_ino); + CPIN_64(no, str, no_addr); +} + +/** + * gfs_inum_out - Write out an inode number + * @no: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_inum_out(struct gfs_inum *no, char *buf) +{ + struct gfs_inum *str = (struct gfs_inum *)buf; + + CPOUT_64(no, str, no_formal_ino); + CPOUT_64(no, str, no_addr); +} + +/** + * gfs_inum_print - Print out a inode number + * @no: the cpu-order buffer + * + */ + +void +gfs_inum_print(struct gfs_inum *no) +{ + pv(no, no_formal_ino, "%"PRIu64); + pv(no, no_addr, "%"PRIu64); +} + +/** + * gfs_meta_header_in - Read in a metadata header + * @mh: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_meta_header_in(struct gfs_meta_header *mh, char *buf) +{ + struct gfs_meta_header *str = (struct gfs_meta_header *)buf; + + CPIN_32(mh, str, mh_magic); + CPIN_32(mh, str, mh_type); + CPIN_64(mh, str, mh_generation); + CPIN_32(mh, str, mh_format); + CPIN_32(mh, str, mh_incarn); +} + +/** + * gfs_meta_header_in - Write out a metadata header + * @mh: the cpu-order structure + * @buf: the disk-order buffer + * + * Don't ever change the generation number in this routine. + * It's done manually in increment_generation(). + */ + +void +gfs_meta_header_out(struct gfs_meta_header *mh, char *buf) +{ + struct gfs_meta_header *str = (struct gfs_meta_header *)buf; + + CPOUT_32(mh, str, mh_magic); + CPOUT_32(mh, str, mh_type); +#if 0 + /* Don't do this! + Mh_generation should only be change manually. */ + CPOUT_64(mh, str, mh_generation); +#endif + CPOUT_32(mh, str, mh_format); + CPOUT_32(mh, str, mh_incarn); +} + +/** + * gfs_meta_header_print - Print out a metadata header + * @mh: the cpu-order buffer + * + */ + +void +gfs_meta_header_print(struct gfs_meta_header *mh) +{ + pv(mh, mh_magic, "0x%.8X"); + pv(mh, mh_type, "%u"); + pv(mh, mh_generation, "%"PRIu64); + pv(mh, mh_format, "%u"); + pv(mh, mh_incarn, "%u"); +} + +/** + * gfs_sb_in - Read in a superblock + * @sb: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_sb_in(struct gfs_sb *sb, char *buf) +{ + struct gfs_sb *str = (struct gfs_sb *)buf; + + gfs_meta_header_in(&sb->sb_header, buf); + + CPIN_32(sb, str, sb_fs_format); + CPIN_32(sb, str, sb_multihost_format); + CPIN_32(sb, str, sb_flags); + + CPIN_32(sb, str, sb_bsize); + CPIN_32(sb, str, sb_bsize_shift); + CPIN_32(sb, str, sb_seg_size); + + gfs_inum_in(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); + gfs_inum_in(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); + gfs_inum_in(&sb->sb_root_di, (char *)&str->sb_root_di); + + CPIN_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); + CPIN_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); + + gfs_inum_in(&sb->sb_quota_di, (char *)&str->sb_quota_di); + gfs_inum_in(&sb->sb_license_di, (char *)&str->sb_license_di); + + CPIN_08(sb, str, sb_reserved, 96); +} + +/** + * gfs_sb_out - Write out a superblock + * @sb: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_sb_out(struct gfs_sb *sb, char *buf) +{ + struct gfs_sb *str = (struct gfs_sb *)buf; + + gfs_meta_header_out(&sb->sb_header, buf); + + CPOUT_32(sb, str, sb_fs_format); + CPOUT_32(sb, str, sb_multihost_format); + CPOUT_32(sb, str, sb_flags); + + CPOUT_32(sb, str, sb_bsize); + CPOUT_32(sb, str, sb_bsize_shift); + CPOUT_32(sb, str, sb_seg_size); + + gfs_inum_out(&sb->sb_jindex_di, (char *)&str->sb_jindex_di); + gfs_inum_out(&sb->sb_rindex_di, (char *)&str->sb_rindex_di); + gfs_inum_out(&sb->sb_root_di, (char *)&str->sb_root_di); + + CPOUT_08(sb, str, sb_lockproto, GFS_LOCKNAME_LEN); + CPOUT_08(sb, str, sb_locktable, GFS_LOCKNAME_LEN); + + gfs_inum_out(&sb->sb_quota_di, (char *)&str->sb_quota_di); + gfs_inum_out(&sb->sb_license_di, (char *)&str->sb_license_di); + + CPOUT_08(sb, str, sb_reserved, 96); +} + +/** + * gfs_sb_print - Print out a superblock + * @sb: the cpu-order buffer + * + */ + +void +gfs_sb_print(struct gfs_sb *sb) +{ + gfs_meta_header_print(&sb->sb_header); + + pv(sb, sb_fs_format, "%u"); + pv(sb, sb_multihost_format, "%u"); + pv(sb, sb_flags, "%u"); + + pv(sb, sb_bsize, "%u"); + pv(sb, sb_bsize_shift, "%u"); + pv(sb, sb_seg_size, "%u"); + + gfs_inum_print(&sb->sb_jindex_di); + gfs_inum_print(&sb->sb_rindex_di); + gfs_inum_print(&sb->sb_root_di); + + pv(sb, sb_lockproto, "%s"); + pv(sb, sb_locktable, "%s"); + + gfs_inum_print(&sb->sb_quota_di); + gfs_inum_print(&sb->sb_license_di); + + pa(sb, sb_reserved, 96); +} + +/** + * gfs_jindex_in - Read in a journal index structure + * @jindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_jindex_in(struct gfs_jindex *jindex, char *buf) +{ + struct gfs_jindex *str = (struct gfs_jindex *)buf; + + CPIN_64(jindex, str, ji_addr); + CPIN_32(jindex, str, ji_nsegment); + CPIN_32(jindex, str, ji_pad); + + CPIN_08(jindex, str, ji_reserved, 64); +} + +/** + * gfs_jindex_out - Write out a journal index structure + * @jindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_jindex_out(struct gfs_jindex *jindex, char *buf) +{ + struct gfs_jindex *str = (struct gfs_jindex *)buf; + + CPOUT_64(jindex, str, ji_addr); + CPOUT_32(jindex, str, ji_nsegment); + CPOUT_32(jindex, str, ji_pad); + + CPOUT_08(jindex, str, ji_reserved, 64); +} + +/** + * gfs_jindex_print - Print out a journal index structure + * @ji: the cpu-order buffer + * + */ + +void +gfs_jindex_print(struct gfs_jindex *ji) +{ + pv(ji, ji_addr, "%"PRIu64); + pv(ji, ji_nsegment, "%u"); + pv(ji, ji_pad, "%u"); + + pa(ji, ji_reserved, 64); +} + +/** + * gfs_rindex_in - Read in a resource index structure + * @rindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rindex_in(struct gfs_rindex *rindex, char *buf) +{ + struct gfs_rindex *str = (struct gfs_rindex *)buf; + + CPIN_64(rindex, str, ri_addr); + CPIN_32(rindex, str, ri_length); + CPIN_32(rindex, str, ri_pad); + + CPIN_64(rindex, str, ri_data1); + CPIN_32(rindex, str, ri_data); + + CPIN_32(rindex, str, ri_bitbytes); + + CPIN_08(rindex, str, ri_reserved, 64); +} + +/** + * gfs_rindex_out - Write out a resource index structure + * @rindex: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rindex_out(struct gfs_rindex *rindex, char *buf) +{ + struct gfs_rindex *str = (struct gfs_rindex *)buf; + + CPOUT_64(rindex, str, ri_addr); + CPOUT_32(rindex, str, ri_length); + CPOUT_32(rindex, str, ri_pad); + + CPOUT_64(rindex, str, ri_data1); + CPOUT_32(rindex, str, ri_data); + + CPOUT_32(rindex, str, ri_bitbytes); + + CPOUT_08(rindex, str, ri_reserved, 64); +} + +/** + * gfs_rindex_print - Print out a resource index structure + * @ri: the cpu-order buffer + * + */ + +void +gfs_rindex_print(struct gfs_rindex *ri) +{ + pv(ri, ri_addr, "%"PRIu64); + pv(ri, ri_length, "%u"); + pv(ri, ri_pad, "%u"); + + pv(ri, ri_data1, "%"PRIu64); + pv(ri, ri_data, "%u"); + + pv(ri, ri_bitbytes, "%u"); + + pa(ri, ri_reserved, 64); +} + +/** + * gfs_rgrp_in - Read in a resource group header + * @rgrp: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rgrp_in(struct gfs_rgrp *rgrp, char *buf) +{ + struct gfs_rgrp *str = (struct gfs_rgrp *)buf; + + gfs_meta_header_in(&rgrp->rg_header, buf); + + CPIN_32(rgrp, str, rg_flags); + + CPIN_32(rgrp, str, rg_free); + + CPIN_32(rgrp, str, rg_useddi); + CPIN_32(rgrp, str, rg_freedi); + gfs_inum_in(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); + + CPIN_32(rgrp, str, rg_usedmeta); + CPIN_32(rgrp, str, rg_freemeta); + + CPIN_08(rgrp, str, rg_reserved, 64); +} + +/** + * gfs_rgrp_out - Write out a resource group header + * @rgrp: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_rgrp_out(struct gfs_rgrp *rgrp, char *buf) +{ + struct gfs_rgrp *str = (struct gfs_rgrp *)buf; + + gfs_meta_header_out(&rgrp->rg_header, buf); + + CPOUT_32(rgrp, str, rg_flags); + + CPOUT_32(rgrp, str, rg_free); + + CPOUT_32(rgrp, str, rg_useddi); + CPOUT_32(rgrp, str, rg_freedi); + gfs_inum_out(&rgrp->rg_freedi_list, (char *)&str->rg_freedi_list); + + CPOUT_32(rgrp, str, rg_usedmeta); + CPOUT_32(rgrp, str, rg_freemeta); + + CPOUT_08(rgrp, str, rg_reserved, 64); +} + +/** + * gfs_rgrp_print - Print out a resource group header + * @rg: the cpu-order buffer + * + */ + +void +gfs_rgrp_print(struct gfs_rgrp *rg) +{ + gfs_meta_header_print(&rg->rg_header); + + pv(rg, rg_flags, "%u"); + + pv(rg, rg_free, "%u"); + + pv(rg, rg_useddi, "%u"); + pv(rg, rg_freedi, "%u"); + gfs_inum_print(&rg->rg_freedi_list); + + pv(rg, rg_usedmeta, "%u"); + pv(rg, rg_freemeta, "%u"); + + pa(rg, rg_reserved, 64); +} + +/** + * gfs_quota_in - Read in a quota structures + * @quota: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_in(struct gfs_quota *quota, char *buf) +{ + struct gfs_quota *str = (struct gfs_quota *)buf; + + CPIN_64(quota, str, qu_limit); + CPIN_64(quota, str, qu_warn); + CPIN_64(quota, str, qu_value); + + CPIN_08(quota, str, qu_reserved, 64); +} + +/** + * gfs_quota_out - Write out a quota structure + * @quota: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_out(struct gfs_quota *quota, char *buf) +{ + struct gfs_quota *str = (struct gfs_quota *)buf; + + CPOUT_64(quota, str, qu_limit); + CPOUT_64(quota, str, qu_warn); + CPOUT_64(quota, str, qu_value); + + CPOUT_08(quota, str, qu_reserved, 64); +} + +/** + * gfs_quota_print - Print out a quota structure + * @quota: the cpu-order buffer + * + */ + +void +gfs_quota_print(struct gfs_quota *quota) +{ + pv(quota, qu_limit, "%"PRIu64); + pv(quota, qu_warn, "%"PRIu64); + pv(quota, qu_value, "%"PRId64); + + pa(quota, qu_reserved, 64); +} + +/** + * gfs_dinode_in - Read in a dinode + * @dinode: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dinode_in(struct gfs_dinode *dinode, char *buf) +{ + struct gfs_dinode *str = (struct gfs_dinode *)buf; + + gfs_meta_header_in(&dinode->di_header, buf); + + gfs_inum_in(&dinode->di_num, (char *)&str->di_num); + + CPIN_32(dinode, str, di_mode); + CPIN_32(dinode, str, di_uid); + CPIN_32(dinode, str, di_gid); + CPIN_32(dinode, str, di_nlink); + CPIN_64(dinode, str, di_size); + CPIN_64(dinode, str, di_blocks); + CPIN_64(dinode, str, di_atime); + CPIN_64(dinode, str, di_mtime); + CPIN_64(dinode, str, di_ctime); + CPIN_32(dinode, str, di_major); + CPIN_32(dinode, str, di_minor); + + CPIN_64(dinode, str, di_rgrp); + CPIN_64(dinode, str, di_goal_rgrp); + CPIN_32(dinode, str, di_goal_dblk); + CPIN_32(dinode, str, di_goal_mblk); + CPIN_32(dinode, str, di_flags); + CPIN_32(dinode, str, di_payload_format); + CPIN_16(dinode, str, di_type); + CPIN_16(dinode, str, di_height); + CPIN_32(dinode, str, di_incarn); + CPIN_16(dinode, str, di_pad); + + CPIN_16(dinode, str, di_depth); + CPIN_32(dinode, str, di_entries); + + gfs_inum_in(&dinode->di_next_unused, (char *)&str->di_next_unused); + + CPIN_64(dinode, str, di_eattr); + + CPIN_08(dinode, str, di_reserved, 56); +} + +/** + * gfs_dinode_out - Write out a dinode + * @dinode: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dinode_out(struct gfs_dinode *dinode, char *buf) +{ + struct gfs_dinode *str = (struct gfs_dinode *)buf; + + gfs_meta_header_out(&dinode->di_header, buf); + + gfs_inum_out(&dinode->di_num, (char *)&str->di_num); + + CPOUT_32(dinode, str, di_mode); + CPOUT_32(dinode, str, di_uid); + CPOUT_32(dinode, str, di_gid); + CPOUT_32(dinode, str, di_nlink); + CPOUT_64(dinode, str, di_size); + CPOUT_64(dinode, str, di_blocks); + CPOUT_64(dinode, str, di_atime); + CPOUT_64(dinode, str, di_mtime); + CPOUT_64(dinode, str, di_ctime); + CPOUT_32(dinode, str, di_major); + CPOUT_32(dinode, str, di_minor); + + CPOUT_64(dinode, str, di_rgrp); + CPOUT_64(dinode, str, di_goal_rgrp); + CPOUT_32(dinode, str, di_goal_dblk); + CPOUT_32(dinode, str, di_goal_mblk); + CPOUT_32(dinode, str, di_flags); + CPOUT_32(dinode, str, di_payload_format); + CPOUT_16(dinode, str, di_type); + CPOUT_16(dinode, str, di_height); + CPOUT_32(dinode, str, di_incarn); + CPOUT_16(dinode, str, di_pad); + + CPOUT_16(dinode, str, di_depth); + CPOUT_32(dinode, str, di_entries); + + gfs_inum_out(&dinode->di_next_unused, (char *)&str->di_next_unused); + + CPOUT_64(dinode, str, di_eattr); + + CPOUT_08(dinode, str, di_reserved, 56); +} + +/** + * gfs_dinode_print - Print out a dinode + * @di: the cpu-order buffer + * + */ + +void +gfs_dinode_print(struct gfs_dinode *di) +{ + gfs_meta_header_print(&di->di_header); + + gfs_inum_print(&di->di_num); + + pv(di, di_mode, "0%o"); + pv(di, di_uid, "%u"); + pv(di, di_gid, "%u"); + pv(di, di_nlink, "%u"); + pv(di, di_size, "%"PRIu64); + pv(di, di_blocks, "%"PRIu64); + pv(di, di_atime, "%"PRId64); + pv(di, di_mtime, "%"PRId64); + pv(di, di_ctime, "%"PRId64); + pv(di, di_major, "%u"); + pv(di, di_minor, "%u"); + + pv(di, di_rgrp, "%"PRIu64); + pv(di, di_goal_rgrp, "%"PRIu64); + pv(di, di_goal_dblk, "%u"); + pv(di, di_goal_mblk, "%u"); + pv(di, di_flags, "0x%.8X"); + pv(di, di_payload_format, "%u"); + pv(di, di_type, "%u"); + pv(di, di_height, "%u"); + pv(di, di_incarn, "%u"); + pv(di, di_pad, "%u"); + + pv(di, di_depth, "%u"); + pv(di, di_entries, "%u"); + + gfs_inum_print(&di->di_next_unused); + + pv(di, di_eattr, "%"PRIu64); + + pa(di, di_reserved, 56); +} + +/** + * gfs_indirect_in - copy in the header of an indirect block + * @indirect: the in memory copy + * @buf: the buffer copy + * + */ + +void +gfs_indirect_in(struct gfs_indirect *indirect, char *buf) +{ + struct gfs_indirect *str = (struct gfs_indirect *)buf; + + gfs_meta_header_in(&indirect->in_header, buf); + + CPIN_08(indirect, str, in_reserved, 64); +} + +/** + * gfs_indirect_out - copy out the header of an indirect block + * @indirect: the in memory copy + * @buf: the buffer copy + * + */ + +void +gfs_indirect_out(struct gfs_indirect *indirect, char *buf) +{ + struct gfs_indirect *str = (struct gfs_indirect *)buf; + + gfs_meta_header_out(&indirect->in_header, buf); + + CPOUT_08(indirect, str, in_reserved, 64); +} + +/** + * gfs_indirect_print - Print out a indirect block header + * @indirect: the cpu-order buffer + * + */ + +void +gfs_indirect_print(struct gfs_indirect *indirect) +{ + gfs_meta_header_print(&indirect->in_header); + + pa(indirect, in_reserved, 64); +} + +/** + * gfs_dirent_in - Read in a directory entry + * @dirent: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dirent_in(struct gfs_dirent *dirent, char *buf) +{ + struct gfs_dirent *str = (struct gfs_dirent *)buf; + + gfs_inum_in(&dirent->de_inum, (char *)&str->de_inum); + CPIN_32(dirent, str, de_hash); + CPIN_16(dirent, str, de_rec_len); + CPIN_16(dirent, str, de_name_len); + CPIN_16(dirent, str, de_type); + + CPIN_08(dirent, str, de_reserved, 14); +} + +/** + * gfs_dirent_out - Write out a directory entry + * @dirent: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_dirent_out(struct gfs_dirent *dirent, char *buf) +{ + struct gfs_dirent *str = (struct gfs_dirent *)buf; + + gfs_inum_out(&dirent->de_inum, (char *)&str->de_inum); + CPOUT_32(dirent, str, de_hash); + CPOUT_16(dirent, str, de_rec_len); + CPOUT_16(dirent, str, de_name_len); + CPOUT_16(dirent, str, de_type); + + CPOUT_08(dirent, str, de_reserved, 14); +} + +/** + * gfs_dirent_print - Print out a directory entry + * @de: the cpu-order buffer + * @name: the filename + * + */ + +void +gfs_dirent_print(struct gfs_dirent *de, char *name) +{ + char buf[GFS_FNAMESIZE + 1]; + + gfs_inum_print(&de->de_inum); + pv(de, de_hash, "0x%.8X"); + pv(de, de_rec_len, "%u"); + pv(de, de_name_len, "%u"); + pv(de, de_type, "%u"); + + pa(de, de_reserved, 14); + + memset(buf, 0, GFS_FNAMESIZE + 1); + memcpy(buf, name, de->de_name_len); + printk(" name = %s\n", buf); +} + +/** + * gfs_leaf_in - Read in a directory leaf header + * @leaf: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_leaf_in(struct gfs_leaf *leaf, char *buf) +{ + struct gfs_leaf *str = (struct gfs_leaf *)buf; + + gfs_meta_header_in(&leaf->lf_header, buf); + + CPIN_16(leaf, str, lf_depth); + CPIN_16(leaf, str, lf_entries); + CPIN_32(leaf, str, lf_dirent_format); + CPIN_64(leaf, str, lf_next); + + CPIN_08(leaf, str, lf_reserved, 64); +} + +/** + * gfs_leaf_out - Write out a directory leaf header + * @leaf: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_leaf_out(struct gfs_leaf *leaf, char *buf) +{ + struct gfs_leaf *str = (struct gfs_leaf *)buf; + + gfs_meta_header_out(&leaf->lf_header, buf); + + CPOUT_16(leaf, str, lf_depth); + CPOUT_16(leaf, str, lf_entries); + CPOUT_32(leaf, str, lf_dirent_format); + CPOUT_64(leaf, str, lf_next); + + CPOUT_08(leaf, str, lf_reserved, 64); +} + +/** + * gfs_leaf_print - Print out a directory leaf header + * @lf: the cpu-order buffer + * + */ + +void +gfs_leaf_print(struct gfs_leaf *lf) +{ + gfs_meta_header_print(&lf->lf_header); + + pv(lf, lf_depth, "%u"); + pv(lf, lf_entries, "%u"); + pv(lf, lf_dirent_format, "%u"); + pv(lf, lf_next, "%"PRIu64); + + pa(lf, lf_reserved, 64); +} + +/** + * gfs_log_header_in - Read in a log header + * @head: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_log_header_in(struct gfs_log_header *head, char *buf) +{ + struct gfs_log_header *str = (struct gfs_log_header *)buf; + + gfs_meta_header_in(&head->lh_header, buf); + + CPIN_32(head, str, lh_flags); + CPIN_32(head, str, lh_pad); + + CPIN_64(head, str, lh_first); + CPIN_64(head, str, lh_sequence); + + CPIN_64(head, str, lh_tail); + CPIN_64(head, str, lh_last_dump); + + CPIN_08(head, str, lh_reserved, 64); +} + +/** + * gfs_log_header_out - Write out a log header + * @head: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_log_header_out(struct gfs_log_header *head, char *buf) +{ + struct gfs_log_header *str = (struct gfs_log_header *)buf; + + gfs_meta_header_out(&head->lh_header, buf); + + CPOUT_32(head, str, lh_flags); + CPOUT_32(head, str, lh_pad); + + CPOUT_64(head, str, lh_first); + CPOUT_64(head, str, lh_sequence); + + CPOUT_64(head, str, lh_tail); + CPOUT_64(head, str, lh_last_dump); + + CPOUT_08(head, str, lh_reserved, 64); +} + +/** + * gfs_log_header_print - Print out a log header + * @head: the cpu-order buffer + * + */ + +void +gfs_log_header_print(struct gfs_log_header *lh) +{ + gfs_meta_header_print(&lh->lh_header); + + pv(lh, lh_flags, "0x%.8X"); + pv(lh, lh_pad, "%u"); + + pv(lh, lh_first, "%"PRIu64); + pv(lh, lh_sequence, "%"PRIu64); + + pv(lh, lh_tail, "%"PRIu64); + pv(lh, lh_last_dump, "%"PRIu64); + + pa(lh, lh_reserved, 64); +} + +/** + * gfs_desc_in - Read in a log descriptor + * @desc: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_desc_in(struct gfs_log_descriptor *desc, char *buf) +{ + struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; + + gfs_meta_header_in(&desc->ld_header, buf); + + CPIN_32(desc, str, ld_type); + CPIN_32(desc, str, ld_length); + CPIN_32(desc, str, ld_data1); + CPIN_32(desc, str, ld_data2); + + CPIN_08(desc, str, ld_reserved, 64); +} + +/** + * gfs_desc_out - Write out a log descriptor + * @desc: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_desc_out(struct gfs_log_descriptor *desc, char *buf) +{ + struct gfs_log_descriptor *str = (struct gfs_log_descriptor *)buf; + + gfs_meta_header_out(&desc->ld_header, buf); + + CPOUT_32(desc, str, ld_type); + CPOUT_32(desc, str, ld_length); + CPOUT_32(desc, str, ld_data1); + CPOUT_32(desc, str, ld_data2); + + CPOUT_08(desc, str, ld_reserved, 64); +} + +/** + * gfs_desc_print - Print out a log descriptor + * @ld: the cpu-order buffer + * + */ + +void +gfs_desc_print(struct gfs_log_descriptor *ld) +{ + gfs_meta_header_print(&ld->ld_header); + + pv(ld, ld_type, "%u"); + pv(ld, ld_length, "%u"); + pv(ld, ld_data1, "%u"); + pv(ld, ld_data2, "%u"); + + pa(ld, ld_reserved, 64); +} + +/** + * gfs_block_tag_in - Read in a block tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_block_tag_in(struct gfs_block_tag *tag, char *buf) +{ + struct gfs_block_tag *str = (struct gfs_block_tag *)buf; + + CPIN_64(tag, str, bt_blkno); + CPIN_32(tag, str, bt_flags); + CPIN_32(tag, str, bt_pad); +} + +/** + * gfs_block_tag_out - Write out a block tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_block_tag_out(struct gfs_block_tag *tag, char *buf) +{ + struct gfs_block_tag *str = (struct gfs_block_tag *)buf; + + CPOUT_64(tag, str, bt_blkno); + CPOUT_32(tag, str, bt_flags); + CPOUT_32(tag, str, bt_pad); +} + +/** + * gfs_block_tag_print - Print out a block tag + * @tag: the cpu-order buffer + * + */ + +void +gfs_block_tag_print(struct gfs_block_tag *tag) +{ + pv(tag, bt_blkno, "%"PRIu64); + pv(tag, bt_flags, "%u"); + pv(tag, bt_pad, "%u"); +} + +/** + * gfs_quota_tag_in - Read in a quota tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_tag_in(struct gfs_quota_tag *tag, char *buf) +{ + struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; + + CPIN_64(tag, str, qt_change); + CPIN_32(tag, str, qt_flags); + CPIN_32(tag, str, qt_id); +} + +/** + * gfs_quota_tag_out - Write out a quota tag + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_quota_tag_out(struct gfs_quota_tag *tag, char *buf) +{ + struct gfs_quota_tag *str = (struct gfs_quota_tag *)buf; + + CPOUT_64(tag, str, qt_change); + CPOUT_32(tag, str, qt_flags); + CPOUT_32(tag, str, qt_id); +} + +/** + * gfs_quota_tag_print - Print out a quota tag + * @tag: the cpu-order buffer + * + */ + +void +gfs_quota_tag_print(struct gfs_quota_tag *tag) +{ + pv(tag, qt_change, "%"PRId64); + pv(tag, qt_flags, "0x%.8X"); + pv(tag, qt_id, "%u"); +} + +/** + * gfs_ea_header_in - Read in a Extended Attribute header + * @tag: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_ea_header_in(struct gfs_ea_header *ea, char *buf) +{ + struct gfs_ea_header *str = (struct gfs_ea_header *)buf; + + CPIN_32(ea, str, ea_rec_len); + CPIN_32(ea, str, ea_data_len); + ea->ea_name_len = str->ea_name_len; + ea->ea_type = str->ea_type; + ea->ea_flags = str->ea_flags; + ea->ea_num_ptrs = str->ea_num_ptrs; + CPIN_32(ea, str, ea_pad); +} + +/** + * gfs_ea_header_out - Write out a Extended Attribute header + * @ea: the cpu-order structure + * @buf: the disk-order buffer + * + */ + +void +gfs_ea_header_out(struct gfs_ea_header *ea, char *buf) +{ + struct gfs_ea_header *str = (struct gfs_ea_header *)buf; + + CPOUT_32(ea, str, ea_rec_len); + CPOUT_32(ea, str, ea_data_len); + str->ea_name_len = ea->ea_name_len; + str->ea_type = ea->ea_type; + str->ea_flags = ea->ea_flags; + str->ea_num_ptrs = ea->ea_num_ptrs; + CPOUT_32(ea, str, ea_pad); +} + +/** + * gfs_ea_header_printt - Print out a Extended Attribute header + * @ea: the cpu-order buffer + * + */ + +void +gfs_ea_header_print(struct gfs_ea_header *ea, char *name) +{ + char buf[GFS_EA_MAX_NAME_LEN + 1]; + + pv(ea, ea_rec_len, "%u"); + pv(ea, ea_data_len, "%u"); + pv(ea, ea_name_len, "%u"); + pv(ea, ea_type, "%u"); + pv(ea, ea_flags, "%u"); + pv(ea, ea_num_ptrs, "%u"); + pv(ea, ea_pad, "%u"); + + memset(buf, 0, GFS_EA_MAX_NAME_LEN + 1); + memcpy(buf, name, ea->ea_name_len); + printk(" name = %s\n", buf); +} + +static const uint32_t crc_32_tab[] = +{ + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +/** + * gfs_dir_hash - hash an array of data + * @data: the data to be hashed + * @len: the length of data to be hashed + * + * Take some data and convert it to a 32-bit hash. + * + * The hash function is a 32-bit CRC of the data. The algorithm uses + * the crc_32_tab table above. + * + * This may not be the fastest hash function, but it does a fair bit better + * at providing uniform results than the others I've looked at. That's + * really important for efficient directories. + * + * Returns: the hash + */ + +uint32_t +gfs_dir_hash(const char *data, int len) +{ + uint32_t hash = 0xFFFFFFFF; + + for (; len--; data++) + hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8); + + hash = ~hash; + + return hash; +} + +#endif /* WANT_GFS_CONVERSION_FUNCTIONS */ + --- linux-2.6.28.orig/ubuntu/gfs/ops_address.c +++ linux-2.6.28/ubuntu/gfs/ops_address.c @@ -0,0 +1,504 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "file.h" +#include "glock.h" +#include "inode.h" +#include "ops_address.h" +#include "page.h" +#include "quota.h" +#include "trans.h" + +static int gfs_commit_write(struct file *file, struct page *page, + unsigned from, unsigned to); +/** + * get_block - Fills in a buffer head with details about a block + * @inode: The inode + * @lblock: The block number to look up + * @bh_result: The buffer head to return the result in + * @create: Non-zero if we may add block to the file + * + * Returns: errno + */ + +static int +get_block(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + struct gfs_inode *ip = get_v2ip(inode); + int new = create; + uint64_t dblock; + int error; + + error = gfs_block_map(ip, lblock, &new, &dblock, NULL); + if (error) + return error; + + if (!dblock) + return 0; + + map_bh(bh_result, inode->i_sb, dblock); + if (new) + set_buffer_new(bh_result); + + return 0; +} + +/** + * get_block_noalloc - Fills in a buffer head with details about a block + * @inode: The inode + * @lblock: The block number to look up + * @bh_result: The buffer head to return the result in + * @create: Non-zero if we may add block to the file + * + * Returns: errno + */ + +static int +get_block_noalloc(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + int error; + + error = get_block(inode, lblock, bh_result, FALSE); + if (error) + return error; + + if (gfs_assert_withdraw(get_v2sdp(inode->i_sb), + !create || buffer_mapped(bh_result))) + return -EIO; + + return 0; +} + +/** + * get_blocks - + * @inode: + * @lblock: + * @max_blocks: + * @bh_result: + * @create: + * + * Returns: errno + */ + +static int +get_blocks(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + struct gfs_inode *ip = get_v2ip(inode); + int new = create; + uint64_t dblock; + int error; + + error = gfs_block_map(ip, lblock, &new, &dblock, NULL); + if (error) + return error; + + if (!dblock) + return 0; + + map_bh(bh_result, inode->i_sb, dblock); + if (new) + set_buffer_new(bh_result); + + return 0; +} + +/** + * get_blocks_noalloc - + * @inode: + * @lblock: + * @max_blocks: + * @bh_result: + * @create: + * + * Returns: errno + */ + +static int +get_blocks_noalloc(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + int error; + + error = get_blocks(inode, lblock, bh_result, FALSE); + if (error) + return error; + + if (gfs_assert_withdraw(get_v2sdp(inode->i_sb), + !create || buffer_mapped(bh_result))) + return -EIO; + + return 0; +} + +/** + * gfs_writepage - Write complete page + * @page: Page to write + * + * Returns: errno + * + * Use Linux VFS block_write_full_page() to write one page, + * using GFS's get_block_noalloc to find which blocks to write. + */ + +static int +gfs_writepage(struct page *page, struct writeback_control *wbc) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + int error; + + atomic_inc(&sdp->sd_ops_address); + + if (gfs_assert_withdraw(sdp, gfs_glock_is_held_excl(ip->i_gl))) { + unlock_page(page); + return -EIO; + } + if (get_transaction) { + redirty_page_for_writepage(wbc, page); + unlock_page(page); + return 0; + } + + error = block_write_full_page(page, get_block_noalloc, wbc); + + gfs_flush_meta_cache(ip); + + return error; +} + +/** + * stuffed_readpage - Fill in a Linux page with stuffed file data + * @ip: the inode + * @page: the page + * + * Returns: errno + */ + +static int +stuffed_readpage(struct gfs_inode *ip, struct page *page) +{ + struct buffer_head *dibh; + void *kaddr; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + kaddr = kmap(page); + memcpy((char *)kaddr, + dibh->b_data + sizeof(struct gfs_dinode), + ip->i_di.di_size); + memset((char *)kaddr + ip->i_di.di_size, + 0, + PAGE_CACHE_SIZE - ip->i_di.di_size); + kunmap(page); + + brelse(dibh); + + SetPageUptodate(page); + } + + return error; +} + +/** + * readi_readpage - readpage that goes through gfs_internal_read() + * @page: The page to read + * + * Returns: errno + */ + +static int +readi_readpage(struct page *page) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + void *kaddr; + int ret; + + kaddr = kmap(page); + + ret = gfs_internal_read(ip, kaddr, + (uint64_t)page->index << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE); + if (ret >= 0) { + if (ret < PAGE_CACHE_SIZE) + memset(kaddr + ret, 0, PAGE_CACHE_SIZE - ret); + SetPageUptodate(page); + ret = 0; + } + + kunmap(page); + + unlock_page(page); + + return ret; +} + +/** + * gfs_readpage - readpage with locking + * @file: The file to read a page for + * @page: The page to read + * + * Returns: errno + */ + +static int +gfs_readpage(struct file *file, struct page *page) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_holder *gh; + int error; + + atomic_inc(&sdp->sd_ops_address); + + /* When gfs_readpage is called from the sys_madvise code through the + * readahead code, the inode glock is not held. In this case, we hold + * the inode glock, unlock the page and return AOP_TRUNCATED_PAGE. The + * caller will then reload the page and call gfs_readpage again. We + * also add the flag GL_READPAGE to denote that the glock was held in + * this function and if so, we unlock it before leaving this function + */ + gh = gfs_glock_is_locked_by_me(ip->i_gl); + if (!gh) { + gh = kmalloc(sizeof(struct gfs_holder), GFP_NOFS); + if (!gh) + return -ENOBUFS; + gfs_holder_init(ip->i_gl, LM_ST_SHARED, + GL_READPAGE | LM_FLAG_ANY, gh); + unlock_page(page); + error = gfs_glock_nq(gh); + if (error) { + gfs_holder_uninit(gh); + kfree(gh); + goto out; + } + return AOP_TRUNCATED_PAGE; + } + + if (!gfs_is_jdata(ip)) { + if (gfs_is_stuffed(ip) && !page->index) { + error = stuffed_readpage(ip, page); + unlock_page(page); + } else + error = block_read_full_page(page, get_block); + } else + error = readi_readpage(page); + + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + error = -EIO; + + if (gh->gh_flags & GL_READPAGE) { /* If we grabbed the glock here */ + gfs_glock_dq_uninit(gh); + kfree(gh); + } +out: + return error; +} + +/** + * gfs_prepare_write - Prepare to write a page to a file + * @file: The file to write to + * @page: The page which is to be prepared for writing + * @from: From (byte range within page) + * @to: To (byte range within page) + * + * Returns: errno + * + * Make sure file's inode is glocked; we shouldn't write without that! + * If GFS dinode is currently stuffed (small enough that all data fits within + * the dinode block), and new file size is too large, unstuff it. + * Use Linux VFS block_prepare_write() to write blocks, using GFS' get_block() + * to find which blocks to write. + */ + +static int +gfs_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ + struct gfs_inode *ip = get_v2ip(page->mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + int error = 0; + + atomic_inc(&sdp->sd_ops_address); + + /* We can't set commit_write in the structure in the declare */ + /* because if we do, loopback (loop.c) will interpret that to mean */ + /* it's okay to do buffered writes without locking through sendfile. */ + /* This is a kludge to get around the problem with loop.c because */ + /* the upstream community rejected my changes to loop.c. */ + ip->gfs_file_aops.commit_write = gfs_commit_write; + + if (gfs_assert_warn(sdp, gfs_glock_is_locked_by_me(ip->i_gl))) + return -ENOSYS; + + if (gfs_is_stuffed(ip)) { + uint64_t file_size = ((uint64_t)page->index << PAGE_CACHE_SHIFT) + to; + + if (file_size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_page, page); + if (!error) + error = block_prepare_write(page, from, to, get_block); + } else if (!PageUptodate(page)) + error = stuffed_readpage(ip, page); + } else + error = block_prepare_write(page, from, to, get_block); + + return error; +} + +/** + * gfs_commit_write - Commit write to a file + * @file: The file to write to + * @page: The page containing the data + * @from: From (byte range within page) + * @to: To (byte range within page) + * + * Returns: errno + */ + +static int +gfs_commit_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ + struct inode *inode = page->mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + int error; + + atomic_inc(&sdp->sd_ops_address); + + if (gfs_is_stuffed(ip)) { + struct buffer_head *dibh; + uint64_t file_size = ((uint64_t)page->index << PAGE_CACHE_SHIFT) + to; + void *kaddr; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail; + + gfs_trans_add_bh(ip->i_gl, dibh); + + kaddr = kmap(page); + memcpy(dibh->b_data + sizeof(struct gfs_dinode) + from, + (char *)kaddr + from, + to - from); + kunmap(page); + + brelse(dibh); + + SetPageUptodate(page); + + if (inode->i_size < file_size) + i_size_write(inode, file_size); + } else { + loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; + error = block_commit_write(page, from, to); + if (error) + goto fail; + if (pos > inode->i_size) { + i_size_write(inode, pos); + mark_inode_dirty(inode); + } + } + + ip->gfs_file_aops.commit_write = NULL; + return 0; + + fail: + ClearPageUptodate(page); + + return error; +} + +/** + * gfs_bmap - Block map function + * @mapping: Address space info + * @lblock: The block to map + * + * Returns: The disk address for the block or 0 on hole or error + */ + +static sector_t +gfs_bmap(struct address_space *mapping, sector_t lblock) +{ + struct gfs_inode *ip = get_v2ip(mapping->host); + struct gfs_holder i_gh; + int dblock = 0; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_address); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return 0; + + if (!gfs_is_stuffed(ip)) + dblock = generic_block_bmap(mapping, lblock, get_block); + + gfs_glock_dq_uninit(&i_gh); + + return dblock; +} + +/** + * gfs_direct_IO - + * @rw: + * @iocb: + * @iov: + * @offset: + * @nr_segs: + * + * Returns: errno + */ + +static ssize_t +gfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, + loff_t offset, unsigned long nr_segs) +{ + struct file *file = iocb->ki_filp; + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + get_block_t *gb = get_blocks; + + atomic_inc(&sdp->sd_ops_address); + + if (gfs_assert_warn(sdp, gfs_glock_is_locked_by_me(ip->i_gl)) || + gfs_assert_warn(sdp, !gfs_is_stuffed(ip))) + return -EINVAL; + + if (rw == WRITE && !get_transaction) + gb = get_blocks_noalloc; + + if (rw == WRITE) + return blockdev_direct_IO(rw, iocb, inode, + inode->i_sb->s_bdev, iov, + offset, nr_segs, gb, NULL); + else + return blockdev_direct_IO_no_locking(rw, iocb, inode, + inode->i_sb->s_bdev, iov, + offset, nr_segs, gb, NULL); + +} + +struct address_space_operations gfs_file_aops = { + .writepage = gfs_writepage, + .readpage = gfs_readpage, + .sync_page = block_sync_page, + .prepare_write = gfs_prepare_write, + .bmap = gfs_bmap, + .direct_IO = gfs_direct_IO, +}; --- linux-2.6.28.orig/ubuntu/gfs/quota.c +++ linux-2.6.28/ubuntu/gfs/quota.c @@ -0,0 +1,1139 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "log.h" +#include "quota.h" +#include "rgrp.h" +#include "super.h" +#include "trans.h" + +/** + * gfs_quota_get - Get a structure to represent a quota change + * @sdp: the filesystem + * @user: TRUE if this is a user quota + * @id: the uid or gid + * @create: if TRUE, create the structure, otherwise return NULL + * @qdp: the returned quota structure + * + * Returns: errno + */ + +int +gfs_quota_get(struct gfs_sbd *sdp, int user, uint32_t id, int create, + struct gfs_quota_data **qdp) +{ + struct gfs_quota_data *qd = NULL, *new_qd = NULL; + struct list_head *tmp, *head; + int error; + + *qdp = NULL; + + for (;;) { + spin_lock(&sdp->sd_quota_lock); + + for (head = &sdp->sd_quota_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + if (qd->qd_id == id && + !test_bit(QDF_USER, &qd->qd_flags) == !user) { + qd->qd_count++; + break; + } + } + + if (tmp == head) + qd = NULL; + + if (!qd && new_qd) { + qd = new_qd; + list_add(&qd->qd_list, &sdp->sd_quota_list); + new_qd = NULL; + } + + spin_unlock(&sdp->sd_quota_lock); + + if (qd || !create) { + if (new_qd) { + gfs_lvb_unhold(new_qd->qd_gl); + kfree(new_qd); + atomic_dec(&sdp->sd_quota_count); + } + *qdp = qd; + return 0; + } + + new_qd = kmalloc(sizeof(struct gfs_quota_data), GFP_KERNEL); + if (!new_qd) + return -ENOMEM; + memset(new_qd, 0, sizeof(struct gfs_quota_data)); + + new_qd->qd_count = 1; + + new_qd->qd_id = id; + if (user) + set_bit(QDF_USER, &new_qd->qd_flags); + + INIT_LIST_HEAD(&new_qd->qd_le_list); + + error = gfs_glock_get(sdp, 2 * (uint64_t)id + ((user) ? 0 : 1), + &gfs_quota_glops, CREATE, + &new_qd->qd_gl); + if (error) { + kfree(new_qd); + return error; + } + + error = gfs_lvb_hold(new_qd->qd_gl); + + gfs_glock_put(new_qd->qd_gl); + + if (error) { + kfree(new_qd); + return error; + } + + atomic_inc(&sdp->sd_quota_count); + } +} + +/** + * gfs_quota_hold - increment the usage count on a struct gfs_quota_data + * @sdp: the filesystem + * @qd: the structure + * + */ + +void +gfs_quota_hold(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + spin_lock(&sdp->sd_quota_lock); + gfs_assert(sdp, qd->qd_count,); + qd->qd_count++; + spin_unlock(&sdp->sd_quota_lock); +} + +/** + * gfs_quota_put - decrement the usage count on a struct gfs_quota_data + * @sdp: the filesystem + * @qd: the structure + * + * Free the structure if its reference count hits zero. + * + */ + +void +gfs_quota_put(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + spin_lock(&sdp->sd_quota_lock); + gfs_assert(sdp, qd->qd_count,); + qd->qd_count--; + spin_unlock(&sdp->sd_quota_lock); +} + +/** + * quota_find - Find a quota change to sync to the quota file + * @sdp: the filesystem + * + * The returned structure is locked and needs to be unlocked + * with quota_unlock(). + * + * Returns: A quota structure, or NULL + */ + +static struct gfs_quota_data * +quota_find(struct gfs_sbd *sdp) +{ + struct list_head *tmp, *head; + struct gfs_quota_data *qd = NULL; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) + return NULL; + + gfs_log_lock(sdp); + spin_lock(&sdp->sd_quota_lock); + + if (!atomic_read(&sdp->sd_quota_od_count)) + goto out; + + for (head = &sdp->sd_quota_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + + if (test_bit(QDF_LOCK, &qd->qd_flags)) + continue; + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) + continue; + if (qd->qd_sync_gen >= sdp->sd_quota_sync_gen) + continue; + + list_move_tail(&qd->qd_list, &sdp->sd_quota_list); + + set_bit(QDF_LOCK, &qd->qd_flags); + qd->qd_count++; + qd->qd_change_sync = qd->qd_change_od; + + goto out; + } + + qd = NULL; + + out: + spin_unlock(&sdp->sd_quota_lock); + gfs_log_unlock(sdp); + + return qd; +} + +/** + * quota_trylock - Try to lock a given quota entry + * @sdp: the filesystem + * @qd: the quota data structure + * + * Returns: TRUE if the lock was successful, FALSE, otherwise + */ + +static int +quota_trylock(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + int ret = FALSE; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) + return FALSE; + + gfs_log_lock(sdp); + spin_lock(&sdp->sd_quota_lock); + + if (test_bit(QDF_LOCK, &qd->qd_flags)) + goto out; + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) + goto out; + + list_move_tail(&qd->qd_list, &sdp->sd_quota_list); + + set_bit(QDF_LOCK, &qd->qd_flags); + qd->qd_count++; + qd->qd_change_sync = qd->qd_change_od; + + ret = TRUE; + + out: + spin_unlock(&sdp->sd_quota_lock); + gfs_log_unlock(sdp); + + return ret; +} + +/** + * quota_unlock - drop and a reference on a quota structure + * @sdp: the filesystem + * @qd: the quota inode structure + * + */ + +static void +quota_unlock(struct gfs_sbd *sdp, struct gfs_quota_data *qd) +{ + spin_lock(&sdp->sd_quota_lock); + + gfs_assert_warn(sdp, test_bit(QDF_LOCK, &qd->qd_flags)); + clear_bit(QDF_LOCK, &qd->qd_flags); + + gfs_assert(sdp, qd->qd_count,); + qd->qd_count--; + + spin_unlock(&sdp->sd_quota_lock); +} + +/** + * gfs_quota_merge - add/remove a quota change from the in-memory list + * @sdp: the filesystem + * @tag: the quota change tag + * + * Returns: errno + */ + +int +gfs_quota_merge(struct gfs_sbd *sdp, struct gfs_quota_tag *tag) +{ + struct gfs_quota_data *qd; + int error; + + error = gfs_quota_get(sdp, + tag->qt_flags & GFS_QTF_USER, tag->qt_id, + CREATE, &qd); + if (error) + return error; + + gfs_assert(sdp, qd->qd_change_ic == qd->qd_change_od,); + + gfs_log_lock(sdp); + + qd->qd_change_ic += tag->qt_change; + qd->qd_change_od += tag->qt_change; + + if (qd->qd_change_od) { + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) { + gfs_quota_hold(sdp, qd); + set_bit(QDF_OD_LIST, &qd->qd_flags); + atomic_inc(&sdp->sd_quota_od_count); + } + } else { + gfs_assert_warn(sdp, test_bit(QDF_OD_LIST, &qd->qd_flags)); + clear_bit(QDF_OD_LIST, &qd->qd_flags); + gfs_quota_put(sdp, qd); + gfs_assert(sdp, atomic_read(&sdp->sd_quota_od_count) > 0,); + atomic_dec(&sdp->sd_quota_od_count); + } + + gfs_log_unlock(sdp); + + gfs_quota_put(sdp, qd); + + return 0; +} + +/** + * gfs_quota_scan - Look for unused struct gfs_quota_data structures to throw away + * @sdp: the filesystem + * + */ + +void +gfs_quota_scan(struct gfs_sbd *sdp) +{ + struct list_head *head, *tmp, *next; + struct gfs_quota_data *qd; + LIST_HEAD(dead); + + spin_lock(&sdp->sd_quota_lock); + + for (head = &sdp->sd_quota_list, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = next->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + if (!qd->qd_count) + list_move(&qd->qd_list, &dead); + } + + spin_unlock(&sdp->sd_quota_lock); + + while (!list_empty(&dead)) { + qd = list_entry(dead.next, struct gfs_quota_data, qd_list); + + gfs_assert_warn(sdp, !qd->qd_count); + gfs_assert_warn(sdp, !test_bit(QDF_OD_LIST, &qd->qd_flags) && + !test_bit(QDF_LOCK, &qd->qd_flags)); + gfs_assert_warn(sdp, !qd->qd_change_new && !qd->qd_change_ic && + !qd->qd_change_od); + + list_del(&qd->qd_list); + gfs_lvb_unhold(qd->qd_gl); + kfree(qd); + atomic_dec(&sdp->sd_quota_count); + } +} + +/** + * gfs_quota_cleanup - get rid of any extra struct gfs_quota_data structures + * @sdp: the filesystem + * + */ + +void +gfs_quota_cleanup(struct gfs_sbd *sdp) +{ + struct gfs_quota_data *qd; + + restart: + gfs_log_lock(sdp); + + spin_lock(&sdp->sd_quota_lock); + + while (!list_empty(&sdp->sd_quota_list)) { + qd = list_entry(sdp->sd_quota_list.next, + struct gfs_quota_data, + qd_list); + + if (qd->qd_count > 1) { + spin_unlock(&sdp->sd_quota_lock); + gfs_log_unlock(sdp); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + goto restart; + + } else if (qd->qd_count) { + gfs_assert_warn(sdp, + test_bit(QDF_OD_LIST, &qd->qd_flags) && + !test_bit(QDF_LOCK, &qd->qd_flags)); + gfs_assert_warn(sdp, qd->qd_change_od && + qd->qd_change_od == qd->qd_change_ic); + gfs_assert_warn(sdp, !qd->qd_change_new); + + list_del(&qd->qd_list); + atomic_dec(&sdp->sd_quota_od_count); + + spin_unlock(&sdp->sd_quota_lock); + gfs_lvb_unhold(qd->qd_gl); + kfree(qd); + atomic_dec(&sdp->sd_quota_count); + spin_lock(&sdp->sd_quota_lock); + + } else { + gfs_assert_warn(sdp, + !test_bit(QDF_OD_LIST, &qd->qd_flags) && + !test_bit(QDF_LOCK, &qd->qd_flags)); + gfs_assert_warn(sdp, !qd->qd_change_new && + !qd->qd_change_ic && + !qd->qd_change_od); + + list_del(&qd->qd_list); + + spin_unlock(&sdp->sd_quota_lock); + gfs_lvb_unhold(qd->qd_gl); + kfree(qd); + atomic_dec(&sdp->sd_quota_count); + spin_lock(&sdp->sd_quota_lock); + } + } + + spin_unlock(&sdp->sd_quota_lock); + + gfs_assert(sdp, !atomic_read(&sdp->sd_quota_od_count),); + + gfs_log_unlock(sdp); +} + +/** + * sort_qd - figure out the order between two quota data structures + * @a: first quota data structure + * @b: second quota data structure + * + * Returns: -1 if @a comes before @b, 0 if @a equals @b, 1 if @b comes before @a + */ + +static int +sort_qd(const void *a, const void *b) +{ + struct gfs_quota_data *qd_a = *(struct gfs_quota_data **)a; + struct gfs_quota_data *qd_b = *(struct gfs_quota_data **)b; + int ret = 0; + + if (!test_bit(QDF_USER, &qd_a->qd_flags) != + !test_bit(QDF_USER, &qd_b->qd_flags)) { + if (test_bit(QDF_USER, &qd_a->qd_flags)) + ret = -1; + else + ret = 1; + } else { + if (qd_a->qd_id < qd_b->qd_id) + ret = -1; + else if (qd_a->qd_id > qd_b->qd_id) + ret = 1; + } + + return ret; +} + +/** + * do_quota_sync - Sync a bunch quota changes to the quota file + * @sdp: the filesystem + * @qda: an array of struct gfs_quota_data structures to be synced + * @num_qd: the number of elements in @qda + * + * Returns: errno + */ + +static int +do_quota_sync(struct gfs_sbd *sdp, struct gfs_quota_data **qda, + unsigned int num_qd) +{ + struct gfs_inode *ip = sdp->sd_qinode; + struct gfs_alloc *al = NULL; + struct gfs_holder i_gh, *ghs; + struct gfs_quota q; + char buf[sizeof(struct gfs_quota)]; + uint64_t offset; + unsigned int qx, x; + int ar; + unsigned int nalloc = 0; + unsigned int data_blocks, ind_blocks; + int error; + + gfs_write_calc_reserv(ip, sizeof(struct gfs_quota), &data_blocks, + &ind_blocks); + + ghs = kmalloc(num_qd * sizeof(struct gfs_holder), GFP_KERNEL); + if (!ghs) + return -ENOMEM; + + gfs_sort(qda, num_qd, sizeof (struct gfs_quota_data *), sort_qd); + for (qx = 0; qx < num_qd; qx++) { + error = gfs_glock_nq_init(qda[qx]->qd_gl, + LM_ST_EXCLUSIVE, + GL_NOCACHE, &ghs[qx]); + if (error) + goto fail; + } + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + goto fail; + + for (x = 0; x < num_qd; x++) { + offset = (2 * (uint64_t)qda[x]->qd_id + + ((test_bit(QDF_USER, &qda[x]->qd_flags)) ? 0 : 1)) * + sizeof(struct gfs_quota); + + error = gfs_write_alloc_required(ip, offset, + sizeof(struct gfs_quota), + &ar); + if (error) + goto fail_gunlock; + + if (ar) + nalloc++; + } + + if (nalloc) { + al = gfs_alloc_get(ip); + + error = + gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, + NO_QUOTA_CHANGE); + if (error) + goto fail_alloc; + + al->al_requested_meta = nalloc * (data_blocks + ind_blocks); + + error = gfs_inplace_reserve(ip); + if (error) + goto fail_qs; + + /* Trans may require: + two (journaled) data blocks, a dinode block, RG bitmaps to allocate from, + indirect blocks, and a quota block */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + num_qd * data_blocks + + nalloc * ind_blocks, + gfs_struct2blk(sdp, num_qd + 2, + sizeof(struct gfs_quota_tag))); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + Data blocks, a dinode block, and quota blocks */ + + error = gfs_trans_begin(sdp, + 1 + data_blocks * num_qd, + gfs_struct2blk(sdp, num_qd, + sizeof(struct gfs_quota_tag))); + if (error) + goto fail_gunlock; + } + + for (x = 0; x < num_qd; x++) { + offset = (2 * (uint64_t)qda[x]->qd_id + + ((test_bit(QDF_USER, &qda[x]->qd_flags)) ? 0 : 1)) * + sizeof(struct gfs_quota); + + /* The quota file may not be a multiple of sizeof(struct gfs_quota) bytes. */ + memset(buf, 0, sizeof(struct gfs_quota)); + + error = gfs_internal_read(ip, buf, offset, + sizeof(struct gfs_quota)); + if (error < 0) + goto fail_end_trans; + + gfs_quota_in(&q, buf); + q.qu_value += qda[x]->qd_change_sync; + gfs_quota_out(&q, buf); + + error = gfs_internal_write(ip, buf, offset, + sizeof(struct gfs_quota)); + if (error < 0) + goto fail_end_trans; + else if (error != sizeof(struct gfs_quota)) { + error = -EIO; + goto fail_end_trans; + } + + if (test_bit(QDF_USER, &qda[x]->qd_flags)) + gfs_trans_add_quota(sdp, -qda[x]->qd_change_sync, + qda[x]->qd_id, NO_QUOTA_CHANGE); + else + gfs_trans_add_quota(sdp, -qda[x]->qd_change_sync, + NO_QUOTA_CHANGE, qda[x]->qd_id); + + memset(&qda[x]->qd_qb, 0, sizeof(struct gfs_quota_lvb)); + qda[x]->qd_qb.qb_magic = GFS_MAGIC; + qda[x]->qd_qb.qb_limit = q.qu_limit; + qda[x]->qd_qb.qb_warn = q.qu_warn; + qda[x]->qd_qb.qb_value = q.qu_value; + + gfs_quota_lvb_out(&qda[x]->qd_qb, qda[x]->qd_gl->gl_lvb); + } + + gfs_trans_end(sdp); + + if (nalloc) { + gfs_assert_warn(sdp, al->al_alloced_meta); + gfs_inplace_release(ip); + gfs_quota_unhold_m(ip); + gfs_alloc_put(ip); + } + + gfs_glock_dq_uninit(&i_gh); + + for (x = 0; x < num_qd; x++) + gfs_glock_dq_uninit(&ghs[x]); + + kfree(ghs); + + gfs_log_flush_glock(ip->i_gl); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (nalloc) + gfs_inplace_release(ip); + + fail_qs: + if (nalloc) + gfs_quota_unhold_m(ip); + + fail_alloc: + if (nalloc) + gfs_alloc_put(ip); + + fail_gunlock: + gfs_glock_dq_uninit(&i_gh); + + fail: + while (qx--) + gfs_glock_dq_uninit(&ghs[qx]); + + kfree(ghs); + + return error; +} + +/** + * glock_q - Acquire a lock for a quota entry + * @sdp: the filesystem + * @qd: the quota data structure to glock + * @force_refresh: If TRUE, always read from the quota file + * @q_gh: the glock holder for the quota lock + * + * Returns: errno + */ + +static int +glock_q(struct gfs_sbd *sdp, struct gfs_quota_data *qd, int force_refresh, + struct gfs_holder *q_gh) +{ + struct gfs_holder i_gh; + struct gfs_quota q; + char buf[sizeof(struct gfs_quota)]; + int error; + + restart: + error = gfs_glock_nq_init(qd->qd_gl, LM_ST_SHARED, 0, q_gh); + if (error) + return error; + + gfs_quota_lvb_in(&qd->qd_qb, qd->qd_gl->gl_lvb); + + if (force_refresh || + qd->qd_qb.qb_magic != GFS_MAGIC) { + gfs_glock_dq_uninit(q_gh); + error = gfs_glock_nq_init(qd->qd_gl, + LM_ST_EXCLUSIVE, GL_NOCACHE, + q_gh); + if (error) + return error; + + error = gfs_glock_nq_init(sdp->sd_qinode->i_gl, + LM_ST_SHARED, 0, + &i_gh); + if (error) + goto fail; + + memset(buf, 0, sizeof(struct gfs_quota)); + + error = gfs_internal_read(sdp->sd_qinode, buf, + (2 * (uint64_t)qd->qd_id + + ((test_bit(QDF_USER, &qd->qd_flags)) ? 0 : 1)) * + sizeof(struct gfs_quota), + sizeof(struct gfs_quota)); + if (error < 0) + goto fail_gunlock; + + gfs_glock_dq_uninit(&i_gh); + + gfs_quota_in(&q, buf); + + memset(&qd->qd_qb, 0, sizeof(struct gfs_quota_lvb)); + qd->qd_qb.qb_magic = GFS_MAGIC; + qd->qd_qb.qb_limit = q.qu_limit; + qd->qd_qb.qb_warn = q.qu_warn; + qd->qd_qb.qb_value = q.qu_value; + + gfs_quota_lvb_out(&qd->qd_qb, qd->qd_gl->gl_lvb); + + gfs_glock_dq_uninit(q_gh); + force_refresh = FALSE; + goto restart; + } + + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&i_gh); + + fail: + gfs_glock_dq_uninit(q_gh); + + return error; +} + +/** + * gfs_quota_hold_m - Hold the quota structures for up to 4 IDs + * @ip: Two of the IDs are the UID and GID from this file + * @uid: a UID or the constant NO_QUOTA_CHANGE + * @gid: a GID or the constant NO_QUOTA_CHANGE + * + * The struct gfs_quota_data structures representing the locks are + * stored in the ip->i_alloc->al_qd array. + * + * Returns: errno + */ + +int +gfs_quota_hold_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + unsigned int x = 0; + int error; + + if (gfs_assert_warn(sdp, !al->al_qd_num && + !test_bit(GIF_QD_LOCKED, &ip->i_flags))) + return -EIO; + + if (!gfs_tune_get(sdp, gt_quota_account)) + return 0; + + error = gfs_quota_get(sdp, TRUE, ip->i_di.di_uid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + + error = gfs_quota_get(sdp, FALSE, ip->i_di.di_gid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + + if (uid != NO_QUOTA_CHANGE) { + error = gfs_quota_get(sdp, TRUE, uid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + } + + if (gid != NO_QUOTA_CHANGE) { + error = gfs_quota_get(sdp, FALSE, gid, + CREATE, &al->al_qd[x]); + if (error) + goto fail; + x++; + } + + al->al_qd_num = x; + + return 0; + + fail: + if (x) { + al->al_qd_num = x; + gfs_quota_unhold_m(ip); + } + + return error; +} + +/** + * gfs_quota_unhold_m - throw away some quota locks + * @ip: the inode who's ip->i_alloc->al_qd array holds the structures + * + */ + +void +gfs_quota_unhold_m(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + unsigned int x; + + gfs_assert_warn(sdp, !test_bit(GIF_QD_LOCKED, &ip->i_flags)); + + for (x = 0; x < al->al_qd_num; x++) { + gfs_quota_put(sdp, al->al_qd[x]); + al->al_qd[x] = NULL; + } + al->al_qd_num = 0; +} + +/** + * gfs_quota_lock_m - Acquire the quota locks for up to 4 IDs + * @ip: Two of the IDs are the UID and GID from this file + * @uid: a UID or the constant NO_QUOTA_CHANGE + * @gid: a GID or the constant NO_QUOTA_CHANGE + * + * The struct gfs_quota_data structures representing the locks are + * stored in the ip->i_alloc->al_qd array. + * + * Returns: errno + */ + +int +gfs_quota_lock_m(struct gfs_inode *ip, uint32_t uid, uint32_t gid) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + unsigned int x; + int error; + + gfs_quota_hold_m(ip, uid, gid); + + if (!gfs_tune_get(sdp, gt_quota_enforce)) + return 0; + if (capable(CAP_SYS_RESOURCE)) + return 0; + + gfs_sort(al->al_qd, al->al_qd_num, + sizeof(struct gfs_quota_data *), sort_qd); + + for (x = 0; x < al->al_qd_num; x++) { + error = glock_q(sdp, al->al_qd[x], FALSE, &al->al_qd_ghs[x]); + if (error) + goto fail; + } + + set_bit(GIF_QD_LOCKED, &ip->i_flags); + + return 0; + + fail: + while (x--) + gfs_glock_dq_uninit(&al->al_qd_ghs[x]); + + return error; +} + +/** + * gfs_quota_unlock_m - drop some quota locks + * @ip: the inode who's ip->i_alloc->al_qd array holds the locks + * + */ + +void +gfs_quota_unlock_m(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_quota_data *qd, *qda[4]; + int64_t value; + unsigned int count = 0; + unsigned int x; + int do_sync; + + if (!test_and_clear_bit(GIF_QD_LOCKED, &ip->i_flags)) + goto out; + + for (x = 0; x < al->al_qd_num; x++) { + qd = al->al_qd[x]; + + spin_lock(&sdp->sd_quota_lock); + value = qd->qd_change_new + qd->qd_change_ic; + spin_unlock(&sdp->sd_quota_lock); + + do_sync = TRUE; + if (!qd->qd_qb.qb_limit) + do_sync = FALSE; + else if (qd->qd_qb.qb_value >= (int64_t)qd->qd_qb.qb_limit) + do_sync = FALSE; + else { + struct gfs_tune *gt = &sdp->sd_tune; + unsigned int num, den; + int64_t v; + + spin_lock(>->gt_spin); + num = gt->gt_quota_scale_num; + den = gt->gt_quota_scale_den; + spin_unlock(>->gt_spin); + + v = value * gfs_num_journals(sdp) * num; + do_div(v, den); + v += qd->qd_qb.qb_value; + if (v < (int64_t)qd->qd_qb.qb_limit) + do_sync = FALSE; + } + + gfs_glock_dq_uninit(&al->al_qd_ghs[x]); + + if (do_sync) { + gfs_log_flush(sdp); + if (quota_trylock(sdp, qd)) + qda[count++] = qd; + } + } + + if (count) { + do_quota_sync(sdp, qda, count); + + for (x = 0; x < count; x++) + quota_unlock(sdp, qda[x]); + } + + out: + gfs_quota_unhold_m(ip); +} + +/** + * print_quota_message - print a message to the user's tty about quotas + * @sdp: the filesystem + * @qd: the quota ID that the message is about + * @type: the type of message ("exceeded" or "warning") + * + * Returns: errno + */ + +static int +print_quota_message(struct gfs_sbd *sdp, struct gfs_quota_data *qd, char *type) +{ + struct tty_struct *tty; + char *line; + int len; + + line = kmalloc(256, GFP_KERNEL); + if (!line) + return -ENOMEM; + + len = snprintf(line, 256, "GFS: fsid=%s: quota %s for %s %u\r\n", + sdp->sd_fsname, type, + (test_bit(QDF_USER, &qd->qd_flags)) ? "user" : "group", + qd->qd_id); + + if (current->signal) { + tty = current->signal->tty; + if (tty && tty->ops->write) + tty->ops->write(tty, line, len); + } + + kfree(line); + + return 0; +} + +/** + * gfs_quota_check - Check to see if a block allocation is possible + * @ip: the inode who's ip->i_res.ir_qd array holds the quota locks + * @uid: the UID the block is allocated for + * @gid: the GID the block is allocated for + * + */ + +int +gfs_quota_check(struct gfs_inode *ip, uint32_t uid, uint32_t gid) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_quota_data *qd; + int64_t value; + unsigned int x; + int error = 0; + + if (!al) + return 0; + + if (!gfs_tune_get(sdp, gt_quota_enforce)) + return 0; + + for (x = 0; x < al->al_qd_num; x++) { + qd = al->al_qd[x]; + + if (!((qd->qd_id == uid && test_bit(QDF_USER, &qd->qd_flags)) || + (qd->qd_id == gid && !test_bit(QDF_USER, &qd->qd_flags)))) + continue; + + spin_lock(&sdp->sd_quota_lock); + value = qd->qd_change_new + qd->qd_change_ic; + spin_unlock(&sdp->sd_quota_lock); + value += qd->qd_qb.qb_value; + + if (qd->qd_qb.qb_limit && (int64_t)qd->qd_qb.qb_limit < value) { + print_quota_message(sdp, qd, "exceeded"); + error = -EDQUOT; + break; + } else if (qd->qd_qb.qb_warn && + (int64_t)qd->qd_qb.qb_warn < value && + time_after_eq(jiffies, + qd->qd_last_warn + + gfs_tune_get(sdp, gt_quota_warn_period) * HZ)) { + error = print_quota_message(sdp, qd, "warning"); + qd->qd_last_warn = jiffies; + } + } + + return error; +} + +/** + * gfs_quota_sync - Sync quota changes to the quota file + * @sdp: the filesystem + * + * Returns: errno + */ + +int +gfs_quota_sync(struct gfs_sbd *sdp) +{ + struct gfs_quota_data **qda; + unsigned int max_qd = gfs_tune_get(sdp, gt_quota_simul_sync); + unsigned int num_qd; + unsigned int x; + int error = 0; + + sdp->sd_quota_sync_gen++; + + qda = kmalloc(max_qd * sizeof(struct gfs_quota_data *), GFP_KERNEL); + if (!qda) + return -ENOMEM; + memset(qda, 0, max_qd * sizeof(struct gfs_quota_data *)); + + do { + num_qd = 0; + + for (;;) { + qda[num_qd] = quota_find(sdp); + if (!qda[num_qd]) + break; + + if (++num_qd == max_qd) + break; + } + + if (num_qd) { + error = do_quota_sync(sdp, qda, num_qd); + if (!error) + for (x = 0; x < num_qd; x++) + qda[x]->qd_sync_gen = + sdp->sd_quota_sync_gen; + + for (x = 0; x < num_qd; x++) + quota_unlock(sdp, qda[x]); + } + } + while (!error && num_qd == max_qd); + + kfree(qda); + + return error; +} + +/** + * gfs_quota_refresh - Refresh the LVB for a given quota ID + * @sdp: the filesystem + * @user: + * @id: + * + * Returns: errno + */ + +int +gfs_quota_refresh(struct gfs_sbd *sdp, int user, uint32_t id) +{ + struct gfs_quota_data *qd; + struct gfs_holder q_gh; + int error; + + error = gfs_quota_get(sdp, user, id, CREATE, &qd); + if (error) + return error; + + error = glock_q(sdp, qd, TRUE, &q_gh); + if (!error) + gfs_glock_dq_uninit(&q_gh); + + gfs_quota_put(sdp, qd); + + return error; +} + +/** + * gfs_quota_read - Read the info a given quota ID + * @sdp: the filesystem + * @user: + * @id: + * @q: + * + * Returns: errno + */ + +int +gfs_quota_read(struct gfs_sbd *sdp, int user, uint32_t id, + struct gfs_quota *q) +{ + struct gfs_quota_data *qd; + struct gfs_holder q_gh; + int error; + + if (((user) ? (id != current->fsuid) : (!in_group_p(id))) && + !capable(CAP_SYS_ADMIN)) + return -EACCES; + + error = gfs_quota_get(sdp, user, id, CREATE, &qd); + if (error) + return error; + + error = glock_q(sdp, qd, FALSE, &q_gh); + if (error) + goto out; + + memset(q, 0, sizeof(struct gfs_quota)); + q->qu_limit = qd->qd_qb.qb_limit; + q->qu_warn = qd->qd_qb.qb_warn; + q->qu_value = qd->qd_qb.qb_value; + + spin_lock(&sdp->sd_quota_lock); + q->qu_value += qd->qd_change_new + qd->qd_change_ic; + spin_unlock(&sdp->sd_quota_lock); + + gfs_glock_dq_uninit(&q_gh); + + out: + gfs_quota_put(sdp, qd); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/proc.h +++ linux-2.6.28/ubuntu/gfs/proc.h @@ -0,0 +1,14 @@ +#ifndef __PROC_DOT_H__ +#define __PROC_DOT_H__ + +/* Allow args to be passed to GFS when using an initial ram disk */ +extern char *gfs_proc_margs; +extern spinlock_t gfs_proc_margs_lock; + +void gfs_proc_fs_add(struct gfs_sbd *sdp); +void gfs_proc_fs_del(struct gfs_sbd *sdp); + +int gfs_proc_init(void); +void gfs_proc_uninit(void); + +#endif /* __PROC_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/sys.h +++ linux-2.6.28/ubuntu/gfs/sys.h @@ -0,0 +1,14 @@ +#ifndef __SYS_DOT_H__ +#define __SYS_DOT_H__ + +/* Allow args to be passed to GFS when using an initial ram disk */ +extern char *gfs_sys_margs; +extern spinlock_t gfs_sys_margs_lock; + +int gfs_sys_fs_add(struct gfs_sbd *sdp); +void gfs_sys_fs_del(struct gfs_sbd *sdp); + +int gfs_sys_init(void); +void gfs_sys_uninit(void); + +#endif /* __SYS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lm_interface.h +++ linux-2.6.28/ubuntu/gfs/lm_interface.h @@ -0,0 +1,278 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2006 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 version 2. + */ + +#ifndef __LM_INTERFACE_DOT_H__ +#define __LM_INTERFACE_DOT_H__ + + +typedef void (*lm_callback_t) (void *ptr, unsigned int type, void *data); + +/* + * lm_mount() flags + * + * LM_MFLAG_SPECTATOR + * GFS is asking to join the filesystem's lockspace, but it doesn't want to + * modify the filesystem. The lock module shouldn't assign a journal to the FS + * mount. It shouldn't send recovery callbacks to the FS mount. If the node + * dies or withdraws, all locks can be wiped immediately. + */ + +#define LM_MFLAG_SPECTATOR 0x00000001 + +/* + * lm_lockstruct flags + * + * LM_LSFLAG_LOCAL + * The lock_nolock module returns LM_LSFLAG_LOCAL to GFS, indicating that GFS + * can make single-node optimizations. + */ + +#define LM_LSFLAG_LOCAL 0x00000001 + +/* + * lm_lockname types + */ + +#define LM_TYPE_RESERVED 0x00 +#define LM_TYPE_NONDISK 0x01 +#define LM_TYPE_INODE 0x02 +#define LM_TYPE_RGRP 0x03 +#define LM_TYPE_META 0x04 +#define LM_TYPE_IOPEN 0x05 +#define LM_TYPE_FLOCK 0x06 +#define LM_TYPE_PLOCK 0x07 +#define LM_TYPE_QUOTA 0x08 +#define LM_TYPE_JOURNAL 0x09 + +/* + * lm_lock() states + * + * SHARED is compatible with SHARED, not with DEFERRED or EX. + * DEFERRED is compatible with DEFERRED, not with SHARED or EX. + */ + +#define LM_ST_UNLOCKED 0 +#define LM_ST_EXCLUSIVE 1 +#define LM_ST_DEFERRED 2 +#define LM_ST_SHARED 3 + +/* + * lm_lock() flags + * + * LM_FLAG_TRY + * Don't wait to acquire the lock if it can't be granted immediately. + * + * LM_FLAG_TRY_1CB + * Send one blocking callback if TRY is set and the lock is not granted. + * + * LM_FLAG_NOEXP + * GFS sets this flag on lock requests it makes while doing journal recovery. + * These special requests should not be blocked due to the recovery like + * ordinary locks would be. + * + * LM_FLAG_ANY + * A SHARED request may also be granted in DEFERRED, or a DEFERRED request may + * also be granted in SHARED. The preferred state is whichever is compatible + * with other granted locks, or the specified state if no other locks exist. + * + * LM_FLAG_PRIORITY + * Override fairness considerations. Suppose a lock is held in a shared state + * and there is a pending request for the deferred state. A shared lock + * request with the priority flag would be allowed to bypass the deferred + * request and directly join the other shared lock. A shared lock request + * without the priority flag might be forced to wait until the deferred + * requested had acquired and released the lock. + */ + +#define LM_FLAG_TRY 0x00000001 +#define LM_FLAG_TRY_1CB 0x00000002 +#define LM_FLAG_NOEXP 0x00000004 +#define LM_FLAG_ANY 0x00000008 +#define LM_FLAG_PRIORITY 0x00000010 + +/* + * lm_lock() and lm_async_cb return flags + * + * LM_OUT_ST_MASK + * Masks the lower two bits of lock state in the returned value. + * + * LM_OUT_CACHEABLE + * The lock hasn't been released so GFS can continue to cache data for it. + * + * LM_OUT_CANCELED + * The lock request was canceled. + * + * LM_OUT_ASYNC + * The result of the request will be returned in an LM_CB_ASYNC callback. + */ + +#define LM_OUT_ST_MASK 0x00000003 +#define LM_OUT_CACHEABLE 0x00000004 +#define LM_OUT_CANCELED 0x00000008 +#define LM_OUT_ASYNC 0x00000080 +#define LM_OUT_ERROR 0x00000100 + +/* + * lm_callback_t types + * + * LM_CB_NEED_E LM_CB_NEED_D LM_CB_NEED_S + * Blocking callback, a remote node is requesting the given lock in + * EXCLUSIVE, DEFERRED, or SHARED. + * + * LM_CB_NEED_RECOVERY + * The given journal needs to be recovered. + * + * LM_CB_DROPLOCKS + * Reduce the number of cached locks. + * + * LM_CB_ASYNC + * The given lock has been granted. + */ + +#define LM_CB_NEED_E 257 +#define LM_CB_NEED_D 258 +#define LM_CB_NEED_S 259 +#define LM_CB_NEED_RECOVERY 260 +#define LM_CB_DROPLOCKS 261 +#define LM_CB_ASYNC 262 + +/* + * lm_recovery_done() messages + */ + +#define LM_RD_GAVEUP 308 +#define LM_RD_SUCCESS 309 + + +struct lm_lockname { + u64 ln_number; + unsigned int ln_type; +}; + +#define lm_name_equal(name1, name2) \ + (((name1)->ln_number == (name2)->ln_number) && \ + ((name1)->ln_type == (name2)->ln_type)) \ + +struct lm_async_cb { + struct lm_lockname lc_name; + int lc_ret; +}; + +struct lm_lockstruct; + +struct lm_lockops { + const char *lm_proto_name; + + /* + * Mount/Unmount + */ + + int (*lm_mount) (char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj); + + void (*lm_others_may_mount) (void *lockspace); + + void (*lm_unmount) (void *lockspace); + + void (*lm_withdraw) (void *lockspace); + + /* + * Lock oriented operations + */ + + int (*lm_get_lock) (void *lockspace, struct lm_lockname *name, void **lockp); + + void (*lm_put_lock) (void *lock); + + unsigned int (*lm_lock) (void *lock, unsigned int cur_state, + unsigned int req_state, unsigned int flags); + + unsigned int (*lm_unlock) (void *lock, unsigned int cur_state); + + void (*lm_cancel) (void *lock); + + int (*lm_hold_lvb) (void *lock, char **lvbp); + void (*lm_unhold_lvb) (void *lock, char *lvb); + + /* + * Posix Lock oriented operations + */ + + int (*lm_plock_get) (void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl); + + int (*lm_plock) (void *lockspace, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl); + + int (*lm_punlock) (void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl); + + /* + * Client oriented operations + */ + + void (*lm_recovery_done) (void *lockspace, unsigned int jid, + unsigned int message); + + struct module *lm_owner; +}; + +/* + * lm_mount() return values + * + * ls_jid - the journal ID this node should use + * ls_first - this node is the first to mount the file system + * ls_lvb_size - size in bytes of lock value blocks + * ls_lockspace - lock module's context for this file system + * ls_ops - lock module's functions + * ls_flags - lock module features + */ + +struct lm_lockstruct { + unsigned int ls_jid; + unsigned int ls_first; + unsigned int ls_lvb_size; + void *ls_lockspace; + const struct lm_lockops *ls_ops; + int ls_flags; +}; + +/* + * Lock module bottom interface. A lock module makes itself available to GFS + * with these functions. + */ + +int gfs_register_lockproto(const struct lm_lockops *proto); +void gfs_unregister_lockproto(const struct lm_lockops *proto); + +/* + * Lock module top interface. GFS calls these functions when mounting or + * unmounting a file system. + */ + +int gfs_mount_lockproto(char *proto_name, char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj); + +void gfs_unmount_lockproto(struct lm_lockstruct *lockstruct); + +void gfs_withdraw_lockproto(struct lm_lockstruct *lockstruct); + +int init_lock_dlm(void); +void exit_lock_dlm(void); +int init_nolock(void); +void exit_nolock(void); + +#endif /* __LM_INTERFACE_DOT_H__ */ + --- linux-2.6.28.orig/ubuntu/gfs/main.c +++ linux-2.6.28/ubuntu/gfs/main.c @@ -0,0 +1,134 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "ops_fstype.h" +#include "sys.h" +#include "proc.h" + +/** + * init_gfs_fs - Register GFS as a filesystem + * + * Returns: 0 on success, error code on failure + */ + +int __init init_gfs_fs(void) +{ + int error; + struct timespec tv; + +/* gfs2_init_lmh(); gfs2 should do this for us*/ + + error = gfs_sys_init(); + if (error) + return error; + error = gfs_proc_init(); + if (error) + goto fail; + + getnstimeofday(&tv); + gfs_random_number = tv.tv_nsec; + + gfs_glock_cachep = kmem_cache_create("gfs_glock", sizeof(struct gfs_glock), + 0, 0, + NULL); + gfs_inode_cachep = NULL; + gfs_bufdata_cachep = NULL; + gfs_mhc_cachep = NULL; + error = -ENOMEM; + if (!gfs_glock_cachep) + goto fail1; + + gfs_inode_cachep = kmem_cache_create("gfs_inode", sizeof(struct gfs_inode), + 0, 0, + NULL); + if (!gfs_inode_cachep) + goto fail1; + + gfs_bufdata_cachep = kmem_cache_create("gfs_bufdata", sizeof(struct gfs_bufdata), + 0, 0, + NULL); + if (!gfs_bufdata_cachep) + goto fail1; + + gfs_mhc_cachep = kmem_cache_create("gfs_meta_header_cache", sizeof(struct gfs_meta_header_cache), + 0, 0, + NULL); + if (!gfs_mhc_cachep) + goto fail; + + error = register_filesystem(&gfs_fs_type); + if (error) + goto fail; + + printk("GFS %s (built %s %s) installed\n", + RELEASE_VERSION, __DATE__, __TIME__); + + error = init_lock_dlm(); + if (error) + goto fail1; + + error = init_nolock(); + if (error) + goto fail1; + + return 0; + + fail1: + if (gfs_mhc_cachep) + kmem_cache_destroy(gfs_mhc_cachep); + + if (gfs_bufdata_cachep) + kmem_cache_destroy(gfs_bufdata_cachep); + + if (gfs_inode_cachep) + kmem_cache_destroy(gfs_inode_cachep); + + if (gfs_glock_cachep) + kmem_cache_destroy(gfs_glock_cachep); + + gfs_proc_uninit(); + + fail: + gfs_sys_uninit(); + + return error; +} + +/** + * exit_gfs_fs - Unregister the file system + * + */ + +void __exit +exit_gfs_fs(void) +{ + exit_nolock(); + exit_lock_dlm(); + unregister_filesystem(&gfs_fs_type); + + kmem_cache_destroy(gfs_mhc_cachep); + kmem_cache_destroy(gfs_bufdata_cachep); + kmem_cache_destroy(gfs_inode_cachep); + kmem_cache_destroy(gfs_glock_cachep); + + gfs_proc_uninit(); + gfs_sys_uninit(); +} + +MODULE_DESCRIPTION("Global File System " RELEASE_VERSION); +MODULE_AUTHOR("Red Hat, Inc."); +MODULE_LICENSE("GPL"); + +module_init(init_gfs_fs); +module_exit(exit_gfs_fs); + --- linux-2.6.28.orig/ubuntu/gfs/ops_export.c +++ linux-2.6.28/ubuntu/gfs/ops_export.c @@ -0,0 +1,403 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "dir.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "ops_dentry.h" +#include "ops_export.h" +#include "rgrp.h" + +struct inode_cookie +{ + uint64_t formal_ino; + uint32_t gen; + int gen_valid; +}; + +struct get_name_filldir +{ + uint64_t formal_ino; + char *name; +}; + +/** + * gfs_encode_fh - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +int +gfs_encode_fh(struct dentry *dentry, __u32 *fh, int *len, + int connectable) +{ + struct inode *inode = dentry->d_inode; + struct gfs_inode *ip = get_v2ip(inode); + int maxlen = *len; + + atomic_inc(&ip->i_sbd->sd_ops_export); + + if (maxlen < 3) + return 255; + + fh[0] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino >> 32)); + fh[1] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino & 0xFFFFFFFF)); + fh[2] = cpu_to_gfs32(inode->i_generation); /* dinode's mh_incarn */ + *len = 3; + + if (maxlen < 5 || !connectable) + return 3; + + spin_lock(&dentry->d_lock); + + inode = dentry->d_parent->d_inode; + ip = get_v2ip(inode); + + fh[3] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino >> 32)); + fh[4] = cpu_to_gfs32((uint32_t)(ip->i_num.no_formal_ino & 0xFFFFFFFF)); + *len = 5; + + if (maxlen < 6) { + spin_unlock(&dentry->d_lock); + return 5; + } + + fh[5] = cpu_to_gfs32(inode->i_generation); /* dinode's mh_incarn */ + + spin_unlock(&dentry->d_lock); + + *len = 6; + + return 6; +} + +/** + * get_name_filldir - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +static int +get_name_filldir(void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type) +{ + struct get_name_filldir *gnfd = (struct get_name_filldir *)opaque; + + if (inum->no_formal_ino != gnfd->formal_ino) + return 0; + + memcpy(gnfd->name, name, length); + gnfd->name[length] = 0; + + return 1; +} + +/** + * gfs_get_name - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +int gfs_get_name(struct dentry *parent, char *name, + struct dentry *child) +{ + struct inode *dir = parent->d_inode; + struct inode *inode = child->d_inode; + struct gfs_inode *dip, *ip; + struct get_name_filldir gnfd; + struct gfs_holder gh; + uint64_t offset = 0; + int error; + + if (!dir) + return -EINVAL; + + atomic_inc(&get_v2sdp(dir->i_sb)->sd_ops_export); + + if (!S_ISDIR(dir->i_mode) || !inode) + return -EINVAL; + + dip = get_v2ip(dir); + ip = get_v2ip(inode); + + *name = 0; + gnfd.formal_ino = ip->i_num.no_formal_ino; + gnfd.name = name; + + error = gfs_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &gh); + if (error) + return error; + + error = gfs_dir_read(dip, &offset, &gnfd, get_name_filldir); + + gfs_glock_dq_uninit(&gh); + + if (!error & !*name) + error = -ENOENT; + + return error; +} + +/** + * gfs_get_parent - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +struct dentry * +gfs_get_parent(struct dentry *child) +{ + struct gfs_inode *dip = get_v2ip(child->d_inode); + struct gfs_holder d_gh, i_gh; + struct qstr dotdot = { .name = "..", .len = 2 }; + struct gfs_inode *ip; + struct inode *inode; + struct dentry *dentry; + int error; + + atomic_inc(&dip->i_sbd->sd_ops_export); + + gfs_holder_init(dip->i_gl, 0, 0, &d_gh); + error = gfs_lookupi(&d_gh, &dotdot, TRUE, &i_gh); + if (error) + goto fail; + + error = -ENOENT; + if (!i_gh.gh_gl) + goto fail; + + ip = get_gl2ip(i_gh.gh_gl); + + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + gfs_glock_dq_uninit(&d_gh); + gfs_glock_dq_uninit(&i_gh); + + if (!inode) + return ERR_PTR(-ENOMEM); + + dentry = d_alloc_anon(inode); + if (!dentry) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + + dentry->d_op = &gfs_dops; + return dentry; + + fail: + gfs_holder_uninit(&d_gh); + return ERR_PTR(error); +} + +/** + * gfs_get_dentry - + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +struct dentry * +gfs_get_dentry(struct super_block *sb, struct inode_cookie *cookie) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + struct gfs_inum inum; + struct gfs_holder i_gh, ri_gh, rgd_gh; + struct gfs_rgrpd *rgd; + struct buffer_head *bh; + struct gfs_dinode *di; + struct gfs_inode *ip; + struct inode *inode; + struct dentry *dentry; + int error; + + atomic_inc(&sdp->sd_ops_export); + + if (!cookie->formal_ino || + cookie->formal_ino == sdp->sd_jiinode->i_num.no_formal_ino || + cookie->formal_ino == sdp->sd_riinode->i_num.no_formal_ino || + cookie->formal_ino == sdp->sd_qinode->i_num.no_formal_ino) + return ERR_PTR(-EINVAL); + + inum.no_formal_ino = cookie->formal_ino; + inum.no_addr = cookie->formal_ino; + + error = gfs_glock_nq_num(sdp, + inum.no_formal_ino, &gfs_inode_glops, + LM_ST_SHARED, LM_FLAG_ANY | GL_LOCAL_EXCL, + &i_gh); + if (error) + return ERR_PTR(error); + + error = gfs_inode_get(i_gh.gh_gl, &inum, NO_CREATE, &ip); + if (error) + goto fail; + if (ip) + goto out; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + goto fail; + + error = -EINVAL; + rgd = gfs_blk2rgrpd(sdp, inum.no_addr); + if (!rgd) + goto fail_rindex; + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_SHARED, 0, &rgd_gh); + if (error) + goto fail_rindex; + + error = -ESTALE; + if (gfs_get_block_type(rgd, inum.no_addr) != GFS_BLKST_USEDMETA) + goto fail_rgd; + + error = gfs_dread(i_gh.gh_gl, inum.no_addr, + DIO_START | DIO_WAIT, &bh); + if (error) + goto fail_rgd; + + di = (struct gfs_dinode *)bh->b_data; + + error = -ESTALE; + if (gfs32_to_cpu(di->di_header.mh_magic) != GFS_MAGIC || + gfs32_to_cpu(di->di_header.mh_type) != GFS_METATYPE_DI || + (gfs32_to_cpu(di->di_flags) & GFS_DIF_UNUSED)) + goto fail_relse; + + brelse(bh); + gfs_glock_dq_uninit(&rgd_gh); + gfs_glock_dq_uninit(&ri_gh); + + error = gfs_inode_get(i_gh.gh_gl, &inum, CREATE, &ip); + if (error) + goto fail; + + atomic_inc(&sdp->sd_fh2dentry_misses); + + out: + inode = gfs_iget(ip, CREATE); + gfs_inode_put(ip); + + gfs_glock_dq_uninit(&i_gh); + + if (!inode) + return ERR_PTR(-ENOMEM); + + /* inode->i_generation is GFS dinode's mh_incarn value */ + if (cookie->gen_valid && cookie->gen != inode->i_generation) { + iput(inode); + return ERR_PTR(-ESTALE); + } + + dentry = d_alloc_anon(inode); + if (!dentry) { + iput(inode); + return ERR_PTR(-ENOMEM); + } + + dentry->d_op = &gfs_dops; + return dentry; + + fail_relse: + brelse(bh); + + fail_rgd: + gfs_glock_dq_uninit(&rgd_gh); + + fail_rindex: + gfs_glock_dq_uninit(&ri_gh); + + fail: + gfs_glock_dq_uninit(&i_gh); + return ERR_PTR(error); +} + +static struct dentry *gfs_fh_to_dentry(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + struct inode_cookie this; + __u32 *fh = fid->raw; + + atomic_inc(&get_v2sdp(sb)->sd_ops_export); + + switch (fh_type) { + case 6: + case 5: + case 3: + this.gen_valid = TRUE; + this.gen = gfs32_to_cpu(fh[2]); + this.formal_ino = ((uint64_t)gfs32_to_cpu(fh[0])) << 32; + this.formal_ino |= (uint64_t)gfs32_to_cpu(fh[1]); + return gfs_get_dentry(sb, &this); + default: + return NULL; + } +} + +static struct dentry *gfs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + struct inode_cookie parent; + __u32 *fh = fid->raw; + + atomic_inc(&get_v2sdp(sb)->sd_ops_export); + + switch (fh_type) { + case 6: + parent.gen_valid = TRUE; + parent.gen = gfs32_to_cpu(fh[5]); + case 5: + parent.formal_ino = ((uint64_t)gfs32_to_cpu(fh[3])) << 32; + parent.formal_ino |= (uint64_t)gfs32_to_cpu(fh[4]); + default: + return NULL; + } + + return gfs_get_dentry(sb, &parent); +} + +const struct export_operations gfs_export_ops = { + .encode_fh = gfs_encode_fh, + .fh_to_dentry = gfs_fh_to_dentry, + .fh_to_parent = gfs_fh_to_parent, + .get_name = gfs_get_name, + .get_parent = gfs_get_parent, +}; + --- linux-2.6.28.orig/ubuntu/gfs/ops_fstype.h +++ linux-2.6.28/ubuntu/gfs/ops_fstype.h @@ -0,0 +1,13 @@ +#ifndef __OPS_FSTYPE_DOT_H__ +#define __OPS_FSTYPE_DOT_H__ + +int gfs_sys_init(void); +void gfs_sys_uninit(void); +void gfs_sys_fs_del(struct gfs_sbd *sdp); +int gfs_test_bdev_super(struct super_block *sb, void *data); +int gfs_set_bdev_super(struct super_block *sb, void *data); +int init_names(struct gfs_sbd *sdp, int silent); + +extern struct file_system_type gfs_fs_type; + +#endif /* __OPS_FSTYPE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lm.h +++ linux-2.6.28/ubuntu/gfs/lm.h @@ -0,0 +1,32 @@ +#ifndef __LM_DOT_H__ +#define __LM_DOT_H__ + +int gfs_lm_mount(struct gfs_sbd *sdp, int silent); +void gfs_lm_others_may_mount(struct gfs_sbd *sdp); +void gfs_lm_unmount(struct gfs_sbd *sdp); +int gfs_lm_withdraw(struct gfs_sbd *sdp, char *fmt, ...) +__attribute__ ((format(printf, 2, 3))); +int gfs_lm_get_lock(struct gfs_sbd *sdp, + struct lm_lockname *name, void **lockp); +void gfs_lm_put_lock(struct gfs_sbd *sdp, void *lock); +unsigned int gfs_lm_lock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state, unsigned int req_state, + unsigned int flags); +unsigned int gfs_lm_unlock(struct gfs_sbd *sdp, void *lock, + unsigned int cur_state); +void gfs_lm_cancel(struct gfs_sbd *sdp, void *lock); +int gfs_lm_hold_lvb(struct gfs_sbd *sdp, void *lock, char **lvbp); +void gfs_lm_unhold_lvb(struct gfs_sbd *sdp, void *lock, char *lvb); +int gfs_lm_plock_get(struct gfs_sbd *sdp, + struct lm_lockname *name, + struct file *file, struct file_lock *fl); +int gfs_lm_plock(struct gfs_sbd *sdp, + struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl); +int gfs_lm_punlock(struct gfs_sbd *sdp, + struct lm_lockname *name, + struct file *file, struct file_lock *fl); +void gfs_lm_recovery_done(struct gfs_sbd *sdp, + unsigned int jid, unsigned int message); + +#endif /* __LM_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/file.c +++ linux-2.6.28/ubuntu/gfs/file.c @@ -0,0 +1,437 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "file.h" +#include "inode.h" +#include "trans.h" + +/** + * gfs_copy2mem - Trivial copy function for gfs_readi() + * @bh: The buffer to copy from, or NULL meaning zero the buffer + * @buf: The buffer to copy/zero + * @offset: The offset in the buffer to copy from + * @size: The amount of data to copy/zero + * + * Returns: errno + */ + +int +gfs_copy2mem(struct buffer_head *bh, void **buf, unsigned int offset, + unsigned int size) +{ + char **p = (char **)buf; + + if (bh) + memcpy(*p, bh->b_data + offset, size); + else + memset(*p, 0, size); + + *p += size; + + return 0; +} + +/** + * gfs_copy2user - Copy data to user space + * @bh: The buffer + * @buf: The destination of the data + * @offset: The offset into the buffer + * @size: The amount of data to copy + * + * Returns: errno + */ + +int +gfs_copy2user(struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size) +{ + char **p = (char **)buf; + int error; + + if (bh) + error = copy_to_user(*p, bh->b_data + offset, size); + else + error = clear_user(*p, size); + + if (error) + error = -EFAULT; + else + *p += size; + + return error; +} + +/** + * gfs_readi - Read a file + * @ip: The GFS Inode + * @buf: The buffer to place result into + * @offset: File offset to begin reading from + * @size: Amount of data to transfer + * @copy_fn: Function to actually perform the copy + * + * The @copy_fn only copies a maximum of a single block at once so + * we are safe calling it with int arguments. It is done so that + * we don't needlessly put 64bit arguments on the stack and it + * also makes the code in the @copy_fn nicer too. + * + * Returns: The amount of data actually copied or the error + */ + +int +gfs_readi(struct gfs_inode *ip, void *buf, + uint64_t offset, unsigned int size, + read_copy_fn_t copy_fn) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + uint64_t lblock, dblock; + unsigned int o; + uint32_t extlen = 0; + unsigned int amount; + int not_new = 0; + int journaled = gfs_is_jdata(ip); + int copied = 0; + int error = 0; + + if (offset >= ip->i_di.di_size) + return 0; + + if ((offset + size) > ip->i_di.di_size) + size = ip->i_di.di_size - offset; + + if (!size) + return 0; + + if (journaled) { + lblock = offset; + o = do_div(lblock, sdp->sd_jbsize); + } else { + lblock = offset >> sdp->sd_sb.sb_bsize_shift; + o = offset & (sdp->sd_sb.sb_bsize - 1); + } + + if (gfs_is_stuffed(ip)) + o += sizeof(struct gfs_dinode); + else if (journaled) + o += sizeof(struct gfs_meta_header); + + while (copied < size) { + amount = size - copied; + if (amount > sdp->sd_sb.sb_bsize - o) + amount = sdp->sd_sb.sb_bsize - o; + + if (!extlen) { + if (!gfs_is_stuffed(ip)) { + error = gfs_block_map(ip, lblock, ¬_new, + &dblock, &extlen); + if (error) + goto fail; + } else if (!lblock) { + dblock = ip->i_num.no_addr; + extlen = 1; + } else + dblock = 0; + } + + if (extlen > 1) + gfs_start_ra(ip->i_gl, dblock, extlen); + + if (dblock) { + error = gfs_get_data_buffer(ip, dblock, not_new, &bh); + if (error) + goto fail; + + dblock++; + extlen--; + } else + bh = NULL; + + error = copy_fn(bh, &buf, o, amount); + if (bh) + brelse(bh); + if (error) + goto fail; + + copied += amount; + lblock++; + + o = (journaled) ? sizeof(struct gfs_meta_header) : 0; + } + + return copied; + + fail: + return (copied) ? copied : error; +} + +/** + * gfs_copy_from_mem - Trivial copy function for gfs_writei() + * @ip: The file to write to + * @bh: The buffer to copy to or clear + * @buf: The buffer to copy from + * @offset: The offset in the buffer to write to + * @size: The amount of data to write + * @new: Flag indicating that remaining space in the buffer should be zeroed + * + * Returns: errno + */ + +int +gfs_copy_from_mem(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new) +{ + char **p = (char **)buf; + int error = 0; + + /* The dinode block always gets journaled */ + if (bh->b_blocknr == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + gfs_trans_add_bh(ip->i_gl, bh); + memcpy(bh->b_data + offset, *p, size); + + /* Data blocks for journaled files get written added to the journal */ + } else if (gfs_is_jdata(ip)) { + gfs_trans_add_bh(ip->i_gl, bh); + memcpy(bh->b_data + offset, *p, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, TRUE); + + /* Non-journaled data blocks get written to in-place disk blocks */ + } else { + memcpy(bh->b_data + offset, *p, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, FALSE); + error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } + + if (!error) + *p += size; + + return error; +} + +/** + * gfs_copy_from_user - Copy bytes from user space for gfs_writei() + * @ip: The file to write to + * @bh: The buffer to copy to or clear + * @buf: The buffer to copy from + * @offset: The offset in the buffer to write to + * @size: The amount of data to write + * @new: Flag indicating that remaining space in the buffer should be zeroed + * + * Returns: errno + */ + +int +gfs_copy_from_user(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new) +{ + char **p = (char **)buf; + int error = 0; + + /* the dinode block always gets journaled */ + if (bh->b_blocknr == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + gfs_trans_add_bh(ip->i_gl, bh); + if (copy_from_user(bh->b_data + offset, *p, size)) + error = -EFAULT; + + /* Data blocks for journaled files get written added to the journal */ + } else if (gfs_is_jdata(ip)) { + gfs_trans_add_bh(ip->i_gl, bh); + if (copy_from_user(bh->b_data + offset, *p, size)) + error = -EFAULT; + if (new) { + gfs_buffer_clear_ends(bh, offset, size, TRUE); + if (error) + memset(bh->b_data + offset, 0, size); + } + + /* non-journaled data blocks get written to in-place disk blocks */ + } else { + if (copy_from_user(bh->b_data + offset, *p, size)) + error = -EFAULT; + if (error) { + if (new) + gfs_buffer_clear(bh); + gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } else { + if (new) + gfs_buffer_clear_ends(bh, offset, size, FALSE); + error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } + } + + if (!error) + *p += size; + + return error; +} + +/** + * gfs_writei - Write bytes to a file + * @ip: The GFS inode + * @buf: The buffer containing information to be written + * @offset: The file offset to start writing at + * @size: The amount of data to write + * @copy_fn: Function to do the actual copying + * + * Returns: The number of bytes correctly written or error code + */ + +int +gfs_writei(struct gfs_inode *ip, void *buf, + uint64_t offset, unsigned int size, + write_copy_fn_t copy_fn, + struct kiocb *iocb) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *dibh, *bh; + uint64_t lblock, dblock; + unsigned int o; + uint32_t extlen = 0; + unsigned int amount; + int new; + int journaled = gfs_is_jdata(ip); + const uint64_t start = offset; + int copied = 0; + int error = 0; + + if (!size) + return 0; + + if (gfs_is_stuffed(ip) && + ((start + size) > (sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)))) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_async, NULL); + if (error) + return error; + } + + if (journaled) { + lblock = offset; + o = do_div(lblock, sdp->sd_jbsize); + } else { + lblock = offset >> sdp->sd_sb.sb_bsize_shift; + o = offset & (sdp->sd_sb.sb_bsize - 1); + } + + if (gfs_is_stuffed(ip)) + o += sizeof(struct gfs_dinode); + else if (journaled) + o += sizeof(struct gfs_meta_header); + + while (copied < size) { + amount = size - copied; + if (amount > sdp->sd_sb.sb_bsize - o) + amount = sdp->sd_sb.sb_bsize - o; + + if (!extlen) { + if (!gfs_is_stuffed(ip)) { + new = TRUE; + error = gfs_block_map(ip, lblock, &new, &dblock, &extlen); + if (error) + goto fail; + } else { + new = FALSE; + dblock = ip->i_num.no_addr; + extlen = 1; + } + } + + if (journaled && extlen > 1) + gfs_start_ra(ip->i_gl, dblock, extlen); + + error = gfs_get_data_buffer(ip, dblock, + (amount == sdp->sd_sb.sb_bsize) ? TRUE : new, + &bh); + if (error) + goto fail; + + error = copy_fn(ip, bh, &buf, o, amount, new); + brelse(bh); + if (error) + goto fail; + + copied += amount; + lblock++; + dblock++; + extlen--; + + o = (journaled) ? sizeof(struct gfs_meta_header) : 0; + } + + out: + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + if (ip->i_di.di_size < start + copied) + ip->i_di.di_size = start + copied; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + return copied; + + fail: + if (copied) + goto out; + return error; +} + +/* + * gfs_zero_blocks - zero out disk blocks via gfs_writei() + * @ip: The file to write to + * @bh: The buffer to clear + * @buf: The pseudo buffer (not used but added to keep interface unchanged) + * @offset: The offset in the buffer to write to + * @size: The size to zero out + * @new: Flag indicating that remaining space in the buffer should be zeroed + * + * Returns: 0 on success, -EXXX on failure + */ + +int +gfs_zero_blocks(struct gfs_inode *ip, struct buffer_head *bh, void **buf, + unsigned int offset, unsigned int size, int new) +{ + int error = 0; + + /* The dinode block always gets journaled */ + if (bh->b_blocknr == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + gfs_trans_add_bh(ip->i_gl, bh); + memset((bh)->b_data + offset, 0, size); + + /* Data blocks for journaled files get written added to the journal */ + } else if (gfs_is_jdata(ip)) { + gfs_trans_add_bh(ip->i_gl, bh); + memset((bh)->b_data + offset, 0, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, TRUE); + + /* Non-journaled data blocks get written to in-place disk blocks */ + } else { + memset((bh)->b_data + offset, 0, size); + if (new) + gfs_buffer_clear_ends(bh, offset, size, FALSE); + error = gfs_dwrite(ip->i_sbd, bh, DIO_DIRTY); + } + + return error; +} + --- linux-2.6.28.orig/ubuntu/gfs/util.h +++ linux-2.6.28/ubuntu/gfs/util.h @@ -0,0 +1,330 @@ +#ifndef __UTIL_DOT_H__ +#define __UTIL_DOT_H__ + + +/* Utility functions */ + +extern uint32_t gfs_random_number; +uint32_t gfs_random(void); + +uint32_t gfs_hash(const void *data, unsigned int len); +uint32_t gfs_hash_more(const void *data, unsigned int len, uint32_t hash); + +void gfs_sort(void *base, unsigned int num_elem, unsigned int size, + int (*compar) (const void *, const void *)); + + +/* Error handling */ + +/** + * gfs_assert - Cause the machine to panic if @assertion is false + * @sdp: + * @assertion: + * @todo: + * + */ + +void gfs_assert_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line) +__attribute__ ((noreturn)); +#define gfs_assert(sdp, assertion, todo) \ +do { \ + if (unlikely(!(assertion))) { \ + {todo} \ + gfs_assert_i((sdp), #assertion, \ + __FUNCTION__, __FILE__, __LINE__); \ + } \ +} while (0) + +/** + * gfs_assert_withdraw - Cause the machine to withdraw if @assertion is false + * @sdp: + * @assertion: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int gfs_assert_withdraw_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line); +#define gfs_assert_withdraw(sdp, assertion) \ +((likely(assertion)) ? 0 : \ + gfs_assert_withdraw_i((sdp), #assertion, \ + __FUNCTION__, __FILE__, __LINE__)) + +/** + * gfs_assert_warn - Print a message to the console if @assertion is false + * @sdp: + * @assertion: + * + * Returns: 0 if things are ok, + * -1 if we printed something + * -2 if we didn't + */ + +int gfs_assert_warn_i(struct gfs_sbd *sdp, + char *assertion, + const char *function, + char *file, unsigned int line); +#define gfs_assert_warn(sdp, assertion) \ +((likely(assertion)) ? 0 : \ + gfs_assert_warn_i((sdp), #assertion, \ + __FUNCTION__, __FILE__, __LINE__)) + +/** + * gfs_consist - Flag a filesystem consistency error and withdraw + * gfs_cconsist - Flag a filesystem consistency error and withdraw cluster + * @sdp: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_consist_i(struct gfs_sbd *sdp, int cluster_wide, + const char *function, + char *file, unsigned int line); +#define gfs_consist(sdp)\ +gfs_consist_i((sdp), FALSE, __FUNCTION__, __FILE__, __LINE__) +#define gfs_cconsist(sdp)\ +gfs_consist_i((sdp), TRUE, __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_consist_inode - Flag an inode consistency error and withdraw + * gfs_cconsist_inode - Flag an inode consistency error and withdraw cluster + * @ip: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_consist_inode_i(struct gfs_inode *ip, int cluster_wide, + const char *function, + char *file, unsigned int line); +#define gfs_consist_inode(ip) \ +gfs_consist_inode_i((ip), FALSE, __FUNCTION__, __FILE__, __LINE__) +#define gfs_cconsist_inode(ip) \ +gfs_consist_inode_i((ip), TRUE, __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_consist_rgrpd - Flag a RG consistency error and withdraw + * gfs_cconsist_rgrpd - Flag a RG consistency error and withdraw cluster + * @rgd: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_consist_rgrpd_i(struct gfs_rgrpd *rgd, int cluster_wide, + const char *function, + char *file, unsigned int line); +#define gfs_consist_rgrpd(rgd) \ +gfs_consist_rgrpd_i((rgd), FALSE, __FUNCTION__, __FILE__, __LINE__) +#define gfs_cconsist_rgrpd(rgd) \ +gfs_consist_rgrpd_i((rgd), TRUE, __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_meta_check - Flag a magic number consistency error and withdraw + * @sdp: + * @bh: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int gfs_meta_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line); +static __inline__ int +gfs_meta_check_i(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line) +{ + uint32_t magic; + magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; + magic = gfs32_to_cpu(magic); + if (likely(magic == GFS_MAGIC)) + return 0; + return gfs_meta_check_ii(sdp, bh, function, file, line); +} +#define gfs_meta_check(sdp, bh) \ +gfs_meta_check_i((sdp), (bh), \ + __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_metatype_check - Flag a metadata type consistency error and withdraw + * @sdp: + * @bh: + * @type: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +int gfs_metatype_check_ii(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type, uint32_t t, + const char *function, + char *file, unsigned int line); +static __inline__ int +gfs_metatype_check_i(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type, + const char *function, + char *file, unsigned int line) +{ + uint32_t magic, t; + magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; + magic = gfs32_to_cpu(magic); + if (unlikely(magic != GFS_MAGIC)) + return gfs_meta_check_ii(sdp, bh, function, file, line); + t = ((struct gfs_meta_header *)(bh)->b_data)->mh_type; + t = gfs32_to_cpu(t); + if (unlikely(t != type)) + return gfs_metatype_check_ii(sdp, bh, type, t, function, file, line); + return 0; +} +#define gfs_metatype_check(sdp, bh, type) \ +gfs_metatype_check_i((sdp), (bh), (type), \ + __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_metatype_check2 - Flag a metadata type consistency error and withdraw + * @sdp: + * @bh: + * @type1: + * @type2: + * + * Returns: 0 if things are ok, + * -1 if this call withdrew the machine, + * -2 if it was already withdrawn + */ + +static __inline__ int +gfs_metatype_check2_i(struct gfs_sbd *sdp, struct buffer_head *bh, + uint32_t type1, uint32_t type2, + const char *function, + char *file, unsigned int line) +{ + uint32_t magic, t; + magic = ((struct gfs_meta_header *)(bh)->b_data)->mh_magic; + magic = gfs32_to_cpu(magic); + if (unlikely(magic != GFS_MAGIC)) + return gfs_meta_check_ii(sdp, bh, function, file, line); + t = ((struct gfs_meta_header *)(bh)->b_data)->mh_type; + t = gfs32_to_cpu(t); + if (unlikely(t != type1 && t != type2)) + return gfs_metatype_check_ii(sdp, bh, type1, t, function, file, line); + return 0; +} +#define gfs_metatype_check2(sdp, bh, type1, type2) \ +gfs_metatype_check2_i((sdp), (bh), (type1), (type2), \ + __FUNCTION__, __FILE__, __LINE__) + +/** + * gfs_metatype_set - set the metadata type on a buffer + * @bh: + * @type: + * @format: + * + */ + +static __inline__ void +gfs_metatype_set(struct buffer_head *bh, uint32_t type, uint32_t format) +{ + struct gfs_meta_header *mh; + mh = (struct gfs_meta_header *)bh->b_data; + mh->mh_type = cpu_to_gfs32(type); + mh->mh_format = cpu_to_gfs32(format); +} + +/** + * gfs_io_error - Flag an I/O error and withdraw + * @sdp: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_io_error_i(struct gfs_sbd *sdp, + const char *function, + char *file, unsigned int line); +#define gfs_io_error(sdp) \ +gfs_io_error_i((sdp), __FUNCTION__, __FILE__, __LINE__); + +/** + * gfs_io_error_inode - Flag an inode I/O error and withdraw + * @ip: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_io_error_inode_i(struct gfs_inode *ip, + const char *function, + char *file, unsigned int line); +#define gfs_io_error_inode(ip) \ +gfs_io_error_inode_i((ip), __FUNCTION__, __FILE__, __LINE__); + +/** + * gfs_io_error_bh - Flag a buffer I/O error and withdraw + * @sdp: + * @bh: + * + * Returns: -1 if this call withdrew the machine, + * 0 if it was already withdrawn + */ + +int gfs_io_error_bh_i(struct gfs_sbd *sdp, struct buffer_head *bh, + const char *function, + char *file, unsigned int line); +#define gfs_io_error_bh(sdp, bh) \ +gfs_io_error_bh_i((sdp), (bh), __FUNCTION__, __FILE__, __LINE__); + + +/* Memory stuff */ + +#define RETRY_MALLOC(do_this, until_this) \ +for (;;) { \ + { do_this; } \ + if (until_this) \ + break; \ + printk("GFS: out of memory: %s, %u\n", __FILE__, __LINE__); \ + dump_stack(); \ + yield(); \ +} + +extern struct kmem_cache *gfs_glock_cachep; +extern struct kmem_cache *gfs_inode_cachep; +extern struct kmem_cache *gfs_bufdata_cachep; +extern struct kmem_cache *gfs_mhc_cachep; + +void *gmalloc(unsigned int size); + + +struct gfs_user_buffer { + char *ub_data; + unsigned int ub_size; + unsigned int ub_count; +}; +int gfs_add_bh_to_ub(struct gfs_user_buffer *ub, struct buffer_head *bh); + + +static __inline__ unsigned int +gfs_tune_get_i(struct gfs_tune *gt, unsigned int *p) +{ + unsigned int x; + spin_lock(>->gt_spin); + x = *p; + spin_unlock(>->gt_spin); + return x; +} +#define gfs_tune_get(sdp, field) \ +gfs_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field) + + +#endif /* __UTIL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/log.h +++ linux-2.6.28/ubuntu/gfs/log.h @@ -0,0 +1,66 @@ +#ifndef __LOG_DOT_H__ +#define __LOG_DOT_H__ + +/** + * gfs_log_lock - acquire the right to mess with the log manager + * @sdp: the filesystem + * + */ + +static __inline__ void +gfs_log_lock(struct gfs_sbd *sdp) +{ + down_write(&sdp->sd_log_lock); +} + +/** + * gfs_log_unlock - release the right to mess with the log manager + * @sdp: the filesystem + * + */ + +static __inline__ void +gfs_log_unlock(struct gfs_sbd *sdp) +{ + up_write(&sdp->sd_log_lock); +} + +unsigned int gfs_struct2blk(struct gfs_sbd *sdp, unsigned int nstruct, + unsigned int ssize); +unsigned int gfs_blk2seg(struct gfs_sbd *sdp, unsigned int blocks); + +int gfs_log_reserve(struct gfs_sbd *sdp, unsigned int segments, int jump_queue); +void gfs_log_release(struct gfs_sbd *sdp, unsigned int segments); + +void gfs_ail_start(struct gfs_sbd *sdp, int flags); +int gfs_ail_empty(struct gfs_sbd *sdp); + +void gfs_log_commit(struct gfs_sbd *sdp, struct gfs_trans *trans); +void gfs_log_flush(struct gfs_sbd *sdp); +void gfs_log_flush_glock(struct gfs_glock *gl); + +void gfs_log_shutdown(struct gfs_sbd *sdp); + +void gfs_log_dump(struct gfs_sbd *sdp, int force); + +/* Internal crap used the log operations */ + +/** + * gfs_log_is_header - Discover if block is on journal header + * @sdp: The GFS superblock + * @block: The block number + * + * Returns: TRUE if the block is on a journal segment boundary, FALSE otherwise + */ + +static __inline__ int +gfs_log_is_header(struct gfs_sbd *sdp, uint64_t block) +{ + return !do_mod(block, sdp->sd_sb.sb_seg_size); +} + +struct gfs_log_buf *gfs_log_get_buf(struct gfs_sbd *sdp, struct gfs_trans *tr); +void gfs_log_fake_buf(struct gfs_sbd *sdp, struct gfs_trans *tr, char *data, + struct buffer_head *unlock); + +#endif /* __LOG_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/bmap.c +++ linux-2.6.28/ubuntu/gfs/bmap.c @@ -0,0 +1,1393 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "glock.h" +#include "inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +struct metapath { + unsigned int mp_list[GFS_MAX_META_HEIGHT]; +}; + +typedef int (*block_call_t) (struct gfs_inode *ip, struct buffer_head *dibh, + struct buffer_head *bh, uint64_t *top, + uint64_t *bottom, unsigned int height, + void *data); + +struct strip_mine { + int sm_first; + unsigned int sm_height; +}; + +/** + * gfs_unstuffer_sync - unstuff a dinode synchronously + * @ip: the inode + * @dibh: the dinode buffer + * @block: the block number that was allocated + * @private: not used + * + * Returns: errno + */ + +int +gfs_unstuffer_sync(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + int error; + + error = gfs_get_data_buffer(ip, block, TRUE, &bh); + if (error) + return error; + + gfs_buffer_copy_tail(bh, 0, dibh, sizeof(struct gfs_dinode)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY | DIO_START | DIO_WAIT); + + brelse(bh); + + return error; +} + +/** + * gfs_unstuffer_async - unstuff a dinode asynchronously + * @ip: the inode + * @dibh: the dinode buffer + * @block: the block number that was allocated + * @private: not used + * + * Returns: errno + */ + +int +gfs_unstuffer_async(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + int error; + + error = gfs_get_data_buffer(ip, block, TRUE, &bh); + if (error) + return error; + + gfs_buffer_copy_tail(bh, 0, dibh, sizeof(struct gfs_dinode)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY); + + brelse(bh); + + return error; +} + +/** + * gfs_unstuff_dinode - Unstuff a dinode when the data has grown too big + * @ip: The GFS inode to unstuff + * @unstuffer: the routine that handles unstuffing a non-zero length file + * @private: private data for the unstuffer + * + * This routine unstuffs a dinode and returns it to a "normal" state such + * that the height can be grown in the traditional way. + * + * Returns: errno + */ + +int +gfs_unstuff_dinode(struct gfs_inode *ip, gfs_unstuffer_t unstuffer, + void *private) +{ + struct buffer_head *bh, *dibh; + uint64_t block = 0; + int journaled = gfs_is_jdata(ip); + int error; + + down_write(&ip->i_rw_mutex); + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out; + + if (ip->i_di.di_size) { + /* Get a free block, fill it with the stuffed data, + and write it out to disk */ + + if (journaled) { + error = gfs_metaalloc(ip, &block); + if (error) + goto out_brelse; + + error = gfs_get_data_buffer(ip, block, TRUE, &bh); + if (error) + goto out_brelse; + + gfs_buffer_copy_tail(bh, sizeof(struct gfs_meta_header), + dibh, sizeof(struct gfs_dinode)); + + brelse(bh); + } else { + gfs_blkalloc(ip, &block); + + error = unstuffer(ip, dibh, block, private); + if (error) + goto out_brelse; + } + } + + /* Set up the pointer to the new block */ + + gfs_trans_add_bh(ip->i_gl, dibh); + + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); + + if (ip->i_di.di_size) { + *(uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)) = cpu_to_gfs64(block); + ip->i_di.di_blocks++; + } + + ip->i_di.di_height = 1; + + gfs_dinode_out(&ip->i_di, dibh->b_data); + + out_brelse: + brelse(dibh); + + out: + up_write(&ip->i_rw_mutex); + + return error; +} + +/** + * calc_tree_height - Calculate the height of a metadata tree + * @ip: The GFS inode + * @size: The proposed size of the file + * + * Work out how tall a metadata tree needs to be in order to accommodate a + * file of a particular size. If size is less than the current size of + * the inode, then the current size of the inode is used instead of the + * supplied one. + * + * Returns: the height the tree should be + */ + +static unsigned int +calc_tree_height(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + uint64_t *arr; + unsigned int max, height; + + if (ip->i_di.di_size > size) + size = ip->i_di.di_size; + + if (gfs_is_jdata(ip)) { + arr = sdp->sd_jheightsize; + max = sdp->sd_max_jheight; + } else { + arr = sdp->sd_heightsize; + max = sdp->sd_max_height; + } + + for (height = 0; height < max; height++) + if (arr[height] >= size) + break; + + return height; +} + +/** + * build_height - Build a metadata tree of the requested height + * @ip: The GFS inode + * @height: The height to build to + * + * This routine makes sure that the metadata tree is tall enough to hold + * "size" bytes of data. + * + * Returns: errno + */ + +static int +build_height(struct gfs_inode *ip, int height) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh, *dibh; + uint64_t block, *bp; + unsigned int x; + int new_block; + int error; + + while (ip->i_di.di_height < height) { + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + new_block = FALSE; + bp = (uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)); + for (x = 0; x < sdp->sd_diptrs; x++, bp++) + if (*bp) { + new_block = TRUE; + break; + } + + if (new_block) { + /* Get a new block, fill it with the old direct pointers, + and write it out */ + + error = gfs_metaalloc(ip, &block); + if (error) + goto fail; + + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + goto fail; + + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, + GFS_METATYPE_IN, + GFS_FORMAT_IN); + memset(bh->b_data + sizeof(struct gfs_meta_header), + 0, + sizeof(struct gfs_indirect) - + sizeof(struct gfs_meta_header)); + gfs_buffer_copy_tail(bh, sizeof(struct gfs_indirect), + dibh, sizeof(struct gfs_dinode)); + + brelse(bh); + } + + /* Set up the new direct pointer and write it out to disk */ + + gfs_trans_add_bh(ip->i_gl, dibh); + + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); + + if (new_block) { + *(uint64_t *)(dibh->b_data + sizeof(struct gfs_dinode)) = cpu_to_gfs64(block); + ip->i_di.di_blocks++; + } + + ip->i_di.di_height++; + + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + return 0; + + fail: + brelse(dibh); + + return error; +} + +/** + * find_metapath - Find path through the metadata tree + * @ip: The inode pointer + * @mp: The metapath to return the result in + * @block: The disk block to look up + * + * This routine returns a struct metapath structure that defines a path through + * the metadata of inode "ip" to get to block "block". + * + * Example: + * Given: "ip" is a height 3 file, "offset" is 101342453, and this is a + * filesystem with a blocksize of 4096. + * + * find_metapath() would return a struct metapath structure set to: + * mp_offset = 101342453, mp_height = 3, mp_list[0] = 0, mp_list[1] = 48, + * and mp_list[2] = 165. + * + * That means that in order to get to the block containing the byte at + * offset 101342453, we would load the indirect block pointed to by pointer + * 0 in the dinode. We would then load the indirect block pointed to by + * pointer 48 in that indirect block. We would then load the data block + * pointed to by pointer 165 in that indirect block. + * + * ---------------------------------------- + * | Dinode | | + * | | 4| + * | |0 1 2 3 4 5 9| + * | | 6| + * ---------------------------------------- + * | + * | + * V + * ---------------------------------------- + * | Indirect Block | + * | 5| + * | 4 4 4 4 4 5 5 1| + * |0 5 6 7 8 9 0 1 2| + * ---------------------------------------- + * | + * | + * V + * ---------------------------------------- + * | Indirect Block | + * | 1 1 1 1 1 5| + * | 6 6 6 6 6 1| + * |0 3 4 5 6 7 2| + * ---------------------------------------- + * | + * | + * V + * ---------------------------------------- + * | Data block containing offset | + * | 101342453 | + * | | + * | | + * ---------------------------------------- + * + */ + +static struct metapath * +find_metapath(struct gfs_inode *ip, uint64_t block) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct metapath *mp; + uint64_t b = block; + unsigned int i; + + mp = gmalloc(sizeof(struct metapath)); + memset(mp, 0, sizeof(struct metapath)); + + for (i = ip->i_di.di_height; i--;) + mp->mp_list[i] = do_div(b, sdp->sd_inptrs); + + return mp; +} + +/** + * metapointer - Return pointer to start of metadata in a buffer + * @bh: The buffer + * @height: The metadata height (0 = dinode) + * @mp: The metapath + * + * Return a pointer to the block number of the next height of the metadata + * tree given a buffer containing the pointer to the current height of the + * metadata tree. + */ + +static __inline__ uint64_t * +metapointer(struct buffer_head *bh, unsigned int height, struct metapath *mp) +{ + unsigned int head_size = (height > 0) ? + sizeof(struct gfs_indirect) : sizeof(struct gfs_dinode); + + return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height]; +} + +/** + * get_metablock - Get the next metadata block in metadata tree + * @ip: The GFS inode + * @bh: Buffer containing the pointers to metadata blocks + * @height: The height of the tree (0 = dinode) + * @mp: The metapath + * @create: Non-zero if we may create a new meatdata block + * @new: Used to indicate if we did create a new metadata block + * @block: the returned disk block number + * + * Given a metatree, complete to a particular height, checks to see if the next + * height of the tree exists. If not the next height of the tree is created. + * The block number of the next height of the metadata tree is returned. + * + * Returns: errno + */ + +static int +get_metablock(struct gfs_inode *ip, + struct buffer_head *bh, unsigned int height, struct metapath *mp, + int create, int *new, uint64_t *block) +{ + uint64_t *ptr = metapointer(bh, height, mp); + int error; + + if (*ptr) { + *block = gfs64_to_cpu(*ptr); + return 0; + } + + *block = 0; + + if (!create) + return 0; + + error = gfs_metaalloc(ip, block); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, bh); + + *ptr = cpu_to_gfs64(*block); + ip->i_di.di_blocks++; + + *new = 1; + + return 0; +} + +/** + * get_datablock - Get datablock number from metadata block + * @ip: The GFS inode + * @bh: The buffer containing pointers to datablocks + * @mp: The metapath + * @create: Non-zero if we may create a new data block + * @new: Used to indicate if we created a new data block + * @block: the returned disk block number + * + * Given a fully built metadata tree, checks to see if a particular data + * block exists. It is created if it does not exist and the block number + * on disk is returned. + * + * Returns: errno + */ + +static int +get_datablock(struct gfs_inode *ip, + struct buffer_head *bh, struct metapath *mp, + int create, int *new, uint64_t *block) +{ + uint64_t *ptr = metapointer(bh, ip->i_di.di_height - 1, mp); + + if (*ptr) { + *block = gfs64_to_cpu(*ptr); + return 0; + } + + *block = 0; + + if (!create) + return 0; + + if (gfs_is_jdata(ip)) { + int error; + error = gfs_metaalloc(ip, block); + if (error) + return error; + } else + gfs_blkalloc(ip, block); + + gfs_trans_add_bh(ip->i_gl, bh); + + *ptr = cpu_to_gfs64(*block); + ip->i_di.di_blocks++; + + *new = 1; + + return 0; +} + +/** + * gfs_block_map - Map a block from an inode to a disk block + * @ip: The GFS inode + * @lblock: The logical block number + * @new: Value/Result argument (1 = may create/did create new blocks) + * @dblock: the disk block number of the start of an extent + * @extlen: the size of the extent + * + * Find the block number on the current device which corresponds to an + * inode's block. If the block had to be created, "new" will be set. + * + * Returns: errno + */ + +int +gfs_block_map(struct gfs_inode *ip, + uint64_t lblock, int *new, + uint64_t *dblock, uint32_t *extlen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + struct metapath *mp; + int create = *new; + unsigned int bsize; + unsigned int height; + unsigned int end_of_metadata; + unsigned int x; + int error = 0; + + *new = 0; + *dblock = 0; + if (extlen) + *extlen = 0; + + if (create) + down_write(&ip->i_rw_mutex); + else + down_read(&ip->i_rw_mutex); + + if (gfs_assert_warn(sdp, !gfs_is_stuffed(ip))) + goto out; + + bsize = (gfs_is_jdata(ip)) ? sdp->sd_jbsize : sdp->sd_sb.sb_bsize; + + height = calc_tree_height(ip, (lblock + 1) * bsize); + if (ip->i_di.di_height < height) { + if (!create) + goto out; + + error = build_height(ip, height); + if (error) + goto out; + } + + mp = find_metapath(ip, lblock); + end_of_metadata = ip->i_di.di_height - 1; + + error = gfs_get_inode_buffer(ip, &bh); + if (error) + goto out_kfree; + + for (x = 0; x < end_of_metadata; x++) { + error = get_metablock(ip, bh, x, mp, create, new, dblock); + brelse(bh); + if (error || !*dblock) + goto out_kfree; + + error = gfs_get_meta_buffer(ip, x + 1, *dblock, *new, &bh); + if (error) + goto out_kfree; + } + + error = get_datablock(ip, bh, mp, create, new, dblock); + if (error) { + brelse(bh); + goto out_kfree; + } + + if (extlen && *dblock) { + *extlen = 1; + + if (!*new) { + uint64_t tmp_dblock; + int tmp_new; + unsigned int nptrs; + + nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs; + + while (++mp->mp_list[end_of_metadata] < nptrs) { + get_datablock(ip, bh, mp, + FALSE, &tmp_new, + &tmp_dblock); + + if (*dblock + *extlen != tmp_dblock) + break; + + (*extlen)++; + } + } + } + + brelse(bh); + + if (*new) { + error = gfs_get_inode_buffer(ip, &bh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, bh); + gfs_dinode_out(&ip->i_di, bh->b_data); + brelse(bh); + } + } + + out_kfree: + kfree(mp); + + out: + if (create) + up_write(&ip->i_rw_mutex); + else + up_read(&ip->i_rw_mutex); + + return error; +} + +/** + * do_grow - Make a file look bigger than it is + * @ip: the inode + * @size: the size to set the file to + * + * Called with an exclusive lock on @ip. + * + * Returns: errno + */ + +static int +do_grow(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al; + struct buffer_head *dibh; + unsigned int h; + int journaled = gfs_is_jdata(ip); + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto out_gunlock_q; + + if (journaled) + al->al_requested_meta = sdp->sd_max_height + 1; + else { + al->al_requested_meta = sdp->sd_max_height; + al->al_requested_data = 1; + } + + error = gfs_inplace_reserve(ip); + if (error) + goto out_gunlock_q; + + /* Trans may require: + Full extention of the metadata tree, block allocation, + a dinode modification, and a quota change */ + + error = gfs_trans_begin(sdp, + sdp->sd_max_height + al->al_rgd->rd_ri.ri_length + + 1 + !!journaled, + 1); + if (error) + goto out_ipres; + + if (size > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) { + if (gfs_is_stuffed(ip)) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); + if (error) + goto out_end_trans; + } + + h = calc_tree_height(ip, size); + if (ip->i_di.di_height < h) { + down_write(&ip->i_rw_mutex); + error = build_height(ip, h); + up_write(&ip->i_rw_mutex); + if (error) + goto out_end_trans; + } + } + + ip->i_di.di_size = size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out_end_trans; + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + out_end_trans: + gfs_trans_end(sdp); + + out_ipres: + gfs_inplace_release(ip); + + out_gunlock_q: + gfs_quota_unlock_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * recursive_scan - recursively scan through the end of a file + * @ip: the inode + * @dibh: the dinode buffer + * @mp: the path through the metadata to the point to start + * @height: the height the recursion is at + * @block: the indirect block to look at + * @first: TRUE if this is the first block + * @bc: the call to make for each piece of metadata + * @data: data opaque to this function to pass to @bc + * + * When this is first called @height and @block should be zero and + * @first should be TRUE. + * + * Returns: errno + */ + +static int +recursive_scan(struct gfs_inode *ip, struct buffer_head *dibh, + struct metapath *mp, unsigned int height, uint64_t block, + int first, block_call_t bc, void *data) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh = NULL; + uint64_t *top, *bottom; + uint64_t bn; + int error; + + if (!height) { + error = gfs_get_inode_buffer(ip, &bh); + if (error) + goto fail; + dibh = bh; + + top = (uint64_t *)(bh->b_data + sizeof(struct gfs_dinode)) + + mp->mp_list[0]; + bottom = (uint64_t *)(bh->b_data + sizeof(struct gfs_dinode)) + + sdp->sd_diptrs; + } else { + error = gfs_get_meta_buffer(ip, height, block, FALSE, &bh); + if (error) + goto fail; + + top = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)) + + ((first) ? mp->mp_list[height] : 0); + bottom = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)) + + sdp->sd_inptrs; + } + + error = bc(ip, dibh, bh, top, bottom, height, data); + if (error) + goto fail; + + if (height < ip->i_di.di_height - 1) + for (; top < bottom; top++, first = FALSE) { + if (!*top) + continue; + + bn = gfs64_to_cpu(*top); + + error = recursive_scan(ip, dibh, mp, + height + 1, bn, first, + bc, data); + if (error) + goto fail; + } + + brelse(bh); + + return 0; + + fail: + if (bh) + brelse(bh); + + return error; +} + +/** + * do_strip - Look for a layer a particular layer of the file and strip it off + * @ip: the inode + * @dibh: the dinode buffer + * @bh: A buffer of pointers + * @top: The first pointer in the buffer + * @bottom: One more than the last pointer + * @height: the height this buffer is at + * @data: a pointer to a struct strip_mine + * + * Returns: errno + */ + +static int +do_strip(struct gfs_inode *ip, struct buffer_head *dibh, + struct buffer_head *bh, uint64_t *top, uint64_t *bottom, + unsigned int height, void *data) +{ + struct strip_mine *sm = (struct strip_mine *)data; + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrp_list rlist; + uint64_t bn, bstart; + uint32_t blen; + uint64_t *p; + unsigned int rg_blocks = 0; + int metadata; + int x; + int error; + + if (!*top) + sm->sm_first = FALSE; + + if (height != sm->sm_height) + return 0; + + if (sm->sm_first) { + top++; + sm->sm_first = FALSE; + } + + metadata = (height != ip->i_di.di_height - 1) || gfs_is_jdata(ip); + + error = gfs_rindex_hold(sdp, &ip->i_alloc->al_ri_gh); + if (error) + return error; + + memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); + bstart = 0; + blen = 0; + + for (p = top; p < bottom; p++) { + if (!*p) + continue; + + bn = gfs64_to_cpu(*p); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + + bstart = bn; + blen = 1; + } + } + + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + else + goto out; /* Nothing to do */ + + gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); + + for (x = 0; x < rlist.rl_rgrps; x++) { + struct gfs_rgrpd *rgd; + rgd = get_gl2rgd(rlist.rl_ghs[x].gh_gl); + rg_blocks += rgd->rd_ri.ri_length; + } + + error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); + if (error) + goto out_rlist; + + /* Trans may require: + All the bitmaps that were reserved. + One block for the dinode. + One block for the indirect block being cleared. + One block for a quota change. */ + + error = gfs_trans_begin(sdp, rg_blocks + 2, 1); + if (error) + goto out_rg_gunlock; + + down_write(&ip->i_rw_mutex); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_trans_add_bh(ip->i_gl, bh); + + bstart = 0; + blen = 0; + + for (p = top; p < bottom; p++) { + if (!*p) + continue; + + bn = gfs64_to_cpu(*p); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) { + if (metadata) + gfs_metafree(ip, bstart, blen); + else + gfs_blkfree(ip, bstart, blen); + } + + bstart = bn; + blen = 1; + } + + *p = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + } + if (bstart) { + if (metadata) + gfs_metafree(ip, bstart, blen); + else + gfs_blkfree(ip, bstart, blen); + } + + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_dinode_out(&ip->i_di, dibh->b_data); + + up_write(&ip->i_rw_mutex); + + gfs_trans_end(sdp); + + out_rg_gunlock: + gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); + + out_rlist: + gfs_rlist_free(&rlist); + + out: + gfs_glock_dq_uninit(&ip->i_alloc->al_ri_gh); + + return error; +} + +/** + * gfs_truncator_default - truncate a partial data block + * @ip: the inode + * @size: the size the file should be + * + * Returns: errno + */ + +int +gfs_truncator_default(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + uint64_t bn; + int not_new = 0; + int error; + + error = gfs_block_map(ip, size >> sdp->sd_sb.sb_bsize_shift, ¬_new, + &bn, NULL); + if (error) + return error; + if (!bn) + return 0; + + error = gfs_get_data_buffer(ip, bn, FALSE, &bh); + if (error) + return error; + + gfs_buffer_clear_tail(bh, size & (sdp->sd_sb.sb_bsize - 1)); + + error = gfs_dwrite(sdp, bh, DIO_DIRTY); + + brelse(bh); + + return error; +} + +/** + * truncator_journaled - truncate a partial data block + * @ip: the inode + * @size: the size the file should be + * + * Returns: errno + */ + +static int +truncator_journaled(struct gfs_inode *ip, uint64_t size) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *bh; + uint64_t lbn, dbn; + uint32_t off; + int not_new = 0; + int error; + + lbn = size; + off = do_div(lbn, sdp->sd_jbsize); + + error = gfs_block_map(ip, lbn, ¬_new, &dbn, NULL); + if (error) + return error; + if (!dbn) + return 0; + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + return error; + + error = gfs_get_data_buffer(ip, dbn, FALSE, &bh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, bh); + gfs_buffer_clear_tail(bh, + sizeof(struct gfs_meta_header) + + off); + brelse(bh); + } + + gfs_trans_end(sdp); + + return error; +} + +/** + * gfs_shrink - make a file smaller + * @ip: the inode + * @size: the size to make the file + * @truncator: function to truncate the last partial block + * + * Called with an exclusive lock on @ip. + * + * Returns: errno + */ + +int +gfs_shrink(struct gfs_inode *ip, uint64_t size, gfs_truncator_t truncator) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_holder ri_gh; + struct gfs_rgrpd *rgd; + struct buffer_head *dibh; + uint64_t block; + unsigned int height; + int journaled = gfs_is_jdata(ip); + int error; + + if (!size) + block = 0; + else if (journaled) { + block = size - 1; + do_div(block, sdp->sd_jbsize); + } + else + block = (size - 1) >> sdp->sd_sb.sb_bsize_shift; + + /* Get rid of all the data/metadata blocks */ + + height = ip->i_di.di_height; + if (height) { + struct metapath *mp = find_metapath(ip, block); + gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) { + gfs_alloc_put(ip); + kfree(mp); + return error; + } + + while (height--) { + struct strip_mine sm; + + sm.sm_first = (size) ? TRUE : FALSE; + sm.sm_height = height; + + error = recursive_scan(ip, NULL, mp, 0, 0, TRUE, + do_strip, &sm); + if (error) { + gfs_quota_unhold_m(ip); + gfs_alloc_put(ip); + kfree(mp); + return error; + } + } + + gfs_quota_unhold_m(ip); + gfs_alloc_put(ip); + kfree(mp); + } + + /* If we truncated in the middle of a block, zero out the leftovers. */ + + if (gfs_is_stuffed(ip)) { + /* Do nothing */ + } else if (journaled) { + if (do_mod(size, sdp->sd_jbsize)) { + error = truncator_journaled(ip, size); + if (error) + return error; + } + } else if (size & (uint64_t)(sdp->sd_sb.sb_bsize - 1)) { + error = truncator(ip, size); + if (error) + return error; + } + + /* Set the new size (and possibly the height) */ + + if (!size) { + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + return error; + } + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + goto out; + + down_write(&ip->i_rw_mutex); + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out_end_trans; + + if (!size) { + ip->i_di.di_height = 0; + + rgd = gfs_blk2rgrpd(sdp, ip->i_num.no_addr); + if (!rgd) { + gfs_consist_inode(ip); + error = -EIO; + goto out_end_trans; + } + + ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; + ip->i_di.di_goal_dblk = + ip->i_di.di_goal_mblk = + ip->i_num.no_addr - rgd->rd_ri.ri_data1; + } + + ip->i_di.di_size = size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + + if (!ip->i_di.di_height && + size < sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode) + size); + + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + out_end_trans: + up_write(&ip->i_rw_mutex); + + gfs_trans_end(sdp); + + out: + if (!size) + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * do_same - truncate to same size (update time stamps) + * @ip: + * + * Returns: errno + */ + +static int +do_same(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *dibh; + int error; + + error = gfs_trans_begin(sdp, 1, 0); + if (error) + return error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out; + + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + + brelse(dibh); + + out: + gfs_trans_end(sdp); + + return error; +} + +/** + * gfs_truncatei - make a file a give size + * @ip: the inode + * @size: the size to make the file + * @truncator: function to truncate the last partial block + * + * The file size can grow, shrink, or stay the same size. + * + * Returns: errno + */ + +int +gfs_truncatei(struct gfs_inode *ip, uint64_t size, + gfs_truncator_t truncator) +{ + if (gfs_assert_warn(ip->i_sbd, ip->i_di.di_type == GFS_FILE_REG)) + return -EINVAL; + + if (size == ip->i_di.di_size) + return do_same(ip); + else if (size > ip->i_di.di_size) + return do_grow(ip, size); + else + return gfs_shrink(ip, size, truncator); +} + +/** + * gfs_write_calc_reserv - calculate the number of blocks needed to write to a file + * @ip: the file + * @len: the number of bytes to be written to the file + * @data_blocks: returns the number of data blocks required + * @ind_blocks: returns the number of indirect blocks required + * + */ + +void +gfs_write_calc_reserv(struct gfs_inode *ip, unsigned int len, + unsigned int *data_blocks, unsigned int *ind_blocks) +{ + struct gfs_sbd *sdp = ip->i_sbd; + unsigned int tmp; + + if (gfs_is_jdata(ip)) { + *data_blocks = DIV_RU(len, sdp->sd_jbsize) + 2; + *ind_blocks = 3 * (sdp->sd_max_jheight - 1); + } else { + *data_blocks = (len >> sdp->sd_sb.sb_bsize_shift) + 3; + *ind_blocks = 3 * (sdp->sd_max_height - 1); + } + + for (tmp = *data_blocks; tmp > sdp->sd_diptrs;) { + tmp = DIV_RU(tmp, sdp->sd_inptrs); + *ind_blocks += tmp; + } +} + +/** + * gfs_write_alloc_required - figure out if a write is going to require an allocation + * @ip: the file being written to + * @offset: the offset to write to + * @len: the number of bytes being written + * @alloc_required: the int is set to TRUE if an alloc is required, FALSE otherwise + * + * Returns: errno + */ + +int +gfs_write_alloc_required(struct gfs_inode *ip, + uint64_t offset, unsigned int len, + int *alloc_required) +{ + struct gfs_sbd *sdp = ip->i_sbd; + uint64_t lblock, lblock_stop, dblock; + uint32_t extlen; + int not_new = FALSE; + int error = 0; + + *alloc_required = FALSE; + + if (!len) + return 0; + + if (gfs_is_stuffed(ip)) { + if (offset + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode)) + *alloc_required = TRUE; + return 0; + } + + if (gfs_is_jdata(ip)) { + unsigned int bsize = sdp->sd_jbsize; + lblock = offset; + do_div(lblock, bsize); + lblock_stop = offset + len + bsize - 1; + do_div(lblock_stop, bsize); + } else { + unsigned int shift = sdp->sd_sb.sb_bsize_shift; + lblock = offset >> shift; + lblock_stop = (offset + len + sdp->sd_sb.sb_bsize - 1) >> shift; + } + + for (; lblock < lblock_stop; lblock += extlen) { + error = gfs_block_map(ip, lblock, ¬_new, &dblock, &extlen); + if (error) + return error; + + if (!dblock) { + *alloc_required = TRUE; + return 0; + } + } + + return 0; +} + +/** + * do_gfm - Copy out the dinode/indirect blocks of a file + * @ip: the file + * @dibh: the dinode buffer + * @bh: the indirect buffer we're looking at + * @top: the first pointer in the block + * @bottom: one more than the last pointer in the block + * @height: the height the block is at + * @data: a pointer to a struct gfs_user_buffer structure + * + * If this is a journaled file, copy out the data too. + * + * Returns: errno + */ + +static int +do_gfm(struct gfs_inode *ip, struct buffer_head *dibh, + struct buffer_head *bh, uint64_t *top, uint64_t *bottom, + unsigned int height, void *data) +{ + struct gfs_user_buffer *ub = (struct gfs_user_buffer *)data; + int error; + + error = gfs_add_bh_to_ub(ub, bh); + if (error) + return error; + + if (ip->i_di.di_type != GFS_FILE_DIR || + height + 1 != ip->i_di.di_height) + return 0; + + for (; top < bottom; top++) + if (*top) { + struct buffer_head *data_bh; + + error = gfs_dread(ip->i_gl, gfs64_to_cpu(*top), + DIO_START | DIO_WAIT, + &data_bh); + if (error) + return error; + + error = gfs_add_bh_to_ub(ub, data_bh); + + brelse(data_bh); + + if (error) + return error; + } + + return 0; +} + +/** + * gfs_get_file_meta - return all the metadata for a file + * @ip: the file + * @ub: the structure representing the meta + * + * Returns: errno + */ + +int +gfs_get_file_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub) +{ + int error; + + if (gfs_is_stuffed(ip)) { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + error = gfs_add_bh_to_ub(ub, dibh); + brelse(dibh); + } + } else { + struct metapath *mp = find_metapath(ip, 0); + error = recursive_scan(ip, NULL, mp, 0, 0, TRUE, do_gfm, ub); + kfree(mp); + } + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/lvb.c +++ linux-2.6.28/ubuntu/gfs/lvb.c @@ -0,0 +1,135 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" + +#define pv(struct, member, fmt) printk(" "#member" = "fmt"\n", struct->member); + +#define CPIN_08(s1, s2, member, count) {memcpy((s1->member), (s2->member), (count));} +#define CPOUT_08(s1, s2, member, count) {memcpy((s2->member), (s1->member), (count));} +#define CPIN_16(s1, s2, member) {(s1->member) = gfs16_to_cpu((s2->member));} +#define CPOUT_16(s1, s2, member) {(s2->member) = cpu_to_gfs16((s1->member));} +#define CPIN_32(s1, s2, member) {(s1->member) = gfs32_to_cpu((s2->member));} +#define CPOUT_32(s1, s2, member) {(s2->member) = cpu_to_gfs32((s1->member));} +#define CPIN_64(s1, s2, member) {(s1->member) = gfs64_to_cpu((s2->member));} +#define CPOUT_64(s1, s2, member) {(s2->member) = cpu_to_gfs64((s1->member));} + +/** + * gfs_rgrp_lvb_in - Read in rgrp data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_rgrp_lvb_in(struct gfs_rgrp_lvb *rb, char *lvb) +{ + struct gfs_rgrp_lvb *str = (struct gfs_rgrp_lvb *)lvb; + + CPIN_32(rb, str, rb_magic); + CPIN_32(rb, str, rb_free); + CPIN_32(rb, str, rb_useddi); + CPIN_32(rb, str, rb_freedi); + CPIN_32(rb, str, rb_usedmeta); + CPIN_32(rb, str, rb_freemeta); +} + +/** + * gfs_rgrp_lvb_out - Write out rgrp data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_rgrp_lvb_out(struct gfs_rgrp_lvb *rb, char *lvb) +{ + struct gfs_rgrp_lvb *str = (struct gfs_rgrp_lvb *)lvb; + + CPOUT_32(rb, str, rb_magic); + CPOUT_32(rb, str, rb_free); + CPOUT_32(rb, str, rb_useddi); + CPOUT_32(rb, str, rb_freedi); + CPOUT_32(rb, str, rb_usedmeta); + CPOUT_32(rb, str, rb_freemeta); +} + +/** + * gfs_rgrp_lvb_print - Print out rgrp data + * @rb: the cpu-order structure + * @console - TRUE if this should be printed to the console, + * FALSE if it should be just printed to the incore debug + * buffer + */ + +void +gfs_rgrp_lvb_print(struct gfs_rgrp_lvb *rb) +{ + pv(rb, rb_magic, "%u"); + pv(rb, rb_free, "%u"); + pv(rb, rb_useddi, "%u"); + pv(rb, rb_freedi, "%u"); + pv(rb, rb_usedmeta, "%u"); + pv(rb, rb_freemeta, "%u"); +} + +/** + * gfs_quota_lvb_in - Read in quota data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_quota_lvb_in(struct gfs_quota_lvb *qb, char *lvb) +{ + struct gfs_quota_lvb *str = (struct gfs_quota_lvb *)lvb; + + CPIN_32(qb, str, qb_magic); + CPIN_32(qb, str, qb_pad); + CPIN_64(qb, str, qb_limit); + CPIN_64(qb, str, qb_warn); + CPIN_64(qb, str, qb_value); +} + +/** + * gfs_quota_lvb_out - Write out quota data + * @rb: the cpu-order structure + * @lvb: the lvb + * + */ + +void +gfs_quota_lvb_out(struct gfs_quota_lvb *qb, char *lvb) +{ + struct gfs_quota_lvb *str = (struct gfs_quota_lvb *)lvb; + + CPOUT_32(qb, str, qb_magic); + CPOUT_32(qb, str, qb_pad); + CPOUT_64(qb, str, qb_limit); + CPOUT_64(qb, str, qb_warn); + CPOUT_64(qb, str, qb_value); +} + +/** + * gfs_quota_lvb_print - Print out quota data + * @rb: the cpu-order structure + * @console - TRUE if this should be printed to the console, + * FALSE if it should be just printed to the incore debug + * buffer + */ + +void +gfs_quota_lvb_print(struct gfs_quota_lvb *qb) +{ + pv(qb, qb_magic, "%u"); + pv(qb, qb_pad, "%u"); + pv(qb, qb_limit, "%"PRIu64); + pv(qb, qb_warn, "%"PRIu64); + pv(qb, qb_value, "%"PRId64); +} --- linux-2.6.28.orig/ubuntu/gfs/eattr.h +++ linux-2.6.28/ubuntu/gfs/eattr.h @@ -0,0 +1,97 @@ +#ifndef __EATTR_DOT_H__ +#define __EATTR_DOT_H__ + +#define GFS_EA_REC_LEN(ea) gfs32_to_cpu((ea)->ea_rec_len) +#define GFS_EA_DATA_LEN(ea) gfs32_to_cpu((ea)->ea_data_len) + +#define GFS_EA_SIZE(ea) \ +MAKE_MULT8(sizeof(struct gfs_ea_header) + \ + (ea)->ea_name_len + \ + ((GFS_EA_IS_STUFFED(ea)) ? \ + GFS_EA_DATA_LEN(ea) : \ + (sizeof(uint64_t) * (ea)->ea_num_ptrs))) +#define GFS_EA_STRLEN(ea) \ +((((ea)->ea_type == GFS_EATYPE_USR) ? 5 : 7) + \ + (ea)->ea_name_len + 1) + +#define GFS_EA_IS_STUFFED(ea) (!(ea)->ea_num_ptrs) +#define GFS_EA_IS_LAST(ea) ((ea)->ea_flags & GFS_EAFLAG_LAST) + +#define GFS_EAREQ_SIZE_STUFFED(er) \ +MAKE_MULT8(sizeof(struct gfs_ea_header) + \ + (er)->er_name_len + (er)->er_data_len) +#define GFS_EAREQ_SIZE_UNSTUFFED(sdp, er) \ +MAKE_MULT8(sizeof(struct gfs_ea_header) + \ + (er)->er_name_len + \ + sizeof(uint64_t) * DIV_RU((er)->er_data_len, (sdp)->sd_jbsize)) + +#define GFS_EA2NAME(ea) ((char *)((struct gfs_ea_header *)(ea) + 1)) +#define GFS_EA2DATA(ea) (GFS_EA2NAME(ea) + (ea)->ea_name_len) +#define GFS_EA2DATAPTRS(ea) \ +((uint64_t *)(GFS_EA2NAME(ea) + MAKE_MULT8((ea)->ea_name_len))) +#define GFS_EA2NEXT(ea) \ +((struct gfs_ea_header *)((char *)(ea) + GFS_EA_REC_LEN(ea))) +#define GFS_EA_BH2FIRST(bh) \ +((struct gfs_ea_header *)((bh)->b_data + \ + sizeof(struct gfs_meta_header))) + +struct gfs_ea_request { + char *er_name; + char *er_data; + unsigned int er_name_len; + unsigned int er_data_len; + unsigned int er_type; /* GFS_EATYPE_... */ + int er_flags; + mode_t er_mode; +}; + +struct gfs_ea_location { + struct buffer_head *el_bh; + struct gfs_ea_header *el_ea; + struct gfs_ea_header *el_prev; +}; + +static inline unsigned int +gfs_ea_strlen(struct gfs_ea_header *ea) +{ + switch (ea->ea_type) { + case GFS_EATYPE_USR: + return (5 + (ea->ea_name_len + 1)); + case GFS_EATYPE_SYS: + return (7 + (ea->ea_name_len + 1)); + case GFS_EATYPE_SECURITY: + return (9 + (ea->ea_name_len + 1)); + default: + return (0); + } +} + +int gfs_ea_repack(struct gfs_inode *ip); + +int gfs_ea_get_i(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_set_i(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_remove_i(struct gfs_inode *ip, struct gfs_ea_request *er); + +int gfs_ea_list(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_get(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_set(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_remove(struct gfs_inode *ip, struct gfs_ea_request *er); + +int gfs_ea_dealloc(struct gfs_inode *ip); + +int gfs_get_eattr_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); + +/* Exported to acl.c */ + +int gfs_ea_check_size(struct gfs_sbd *sdp, struct gfs_ea_request *er); +int gfs_ea_find(struct gfs_inode *ip, + struct gfs_ea_request *er, + struct gfs_ea_location *el); +int gfs_ea_get_copy(struct gfs_inode *ip, + struct gfs_ea_location *el, + char *data); +int gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er); +int gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el, + struct iattr *attr, char *data); + +#endif /* __EATTR_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_file.c +++ linux-2.6.28/ubuntu/gfs/ops_file.c @@ -0,0 +1,1820 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs_ioctl.h" +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "ioctl.h" +#include "lm.h" +#include "log.h" +#include "ops_file.h" +#include "ops_vm.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +/* "bad" is for NFS support */ +struct filldir_bad_entry { + char *fbe_name; + unsigned int fbe_length; + uint64_t fbe_offset; + struct gfs_inum fbe_inum; + unsigned int fbe_type; +}; + +struct filldir_bad { + struct gfs_sbd *fdb_sbd; + + struct filldir_bad_entry *fdb_entry; + unsigned int fdb_entry_num; + unsigned int fdb_entry_off; + + char *fdb_name; + unsigned int fdb_name_size; + unsigned int fdb_name_off; +}; + +/* For regular, non-NFS */ +struct filldir_reg { + struct gfs_sbd *fdr_sbd; + int fdr_prefetch; + + filldir_t fdr_filldir; + void *fdr_opaque; +}; + +typedef ssize_t(*do_rw_t) (struct file * file, + char *buf, + size_t size, loff_t * offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder * ghs); + +/** + * gfs_llseek - seek to a location in a file + * @file: the file + * @offset: the offset + * @origin: Where to seek from (SEEK_SET, SEEK_CUR, or SEEK_END) + * + * SEEK_END requires the glock for the file because it references the + * file's size. + * + * Returns: The new offset, or errno + */ + +static loff_t +gfs_llseek(struct file *file, loff_t offset, int origin) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_holder i_gh; + loff_t error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + if (origin == 2) { + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (!error) { + error = generic_file_llseek_unlocked(file, offset, origin); + gfs_glock_dq_uninit(&i_gh); + } + } else + error = generic_file_llseek_unlocked(file, offset, origin); + + return error; +} + +#define vma2state(vma) \ +((((vma)->vm_flags & (VM_MAYWRITE | VM_MAYSHARE)) == \ + (VM_MAYWRITE | VM_MAYSHARE)) ? \ + LM_ST_EXCLUSIVE : LM_ST_SHARED) \ + +/** + * functionname - summary + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +static ssize_t +walk_vm_hard(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, do_rw_t operation) +{ + struct gfs_holder *ghs; + unsigned int num_gh = 0; + ssize_t count; + + { + struct super_block *sb = file->f_dentry->d_inode->i_sb; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long start = (unsigned long)buf; + unsigned long end = start + size; + int dumping = (current->flags & PF_DUMPCORE); + unsigned int x = 0; + + for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { + if (end <= vma->vm_start) + break; + if (vma->vm_file && + vma->vm_file->f_dentry->d_inode->i_sb == sb) { + num_gh++; + } + } + + ghs = kmalloc((num_gh + 1) * sizeof(struct gfs_holder), GFP_KERNEL); + if (!ghs) { + if (!dumping) + up_read(&mm->mmap_sem); + return -ENOMEM; + } + + for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { + if (end <= vma->vm_start) + break; + if (vma->vm_file) { + struct inode *inode = vma->vm_file->f_dentry->d_inode; + if (inode->i_sb == sb) + gfs_holder_init(get_v2ip(inode)->i_gl, + vma2state(vma), + 0, &ghs[x++]); + } + } + + if (!dumping) + up_read(&mm->mmap_sem); + + gfs_assert(get_v2sdp(sb), x == num_gh,); + } + + count = operation(file, buf, size, offset, iocb, num_gh, ghs); + + while (num_gh--) + gfs_holder_uninit(&ghs[num_gh]); + kfree(ghs); + + return count; +} + +/** + * walk_vm - Walk the vmas associated with a buffer for read or write. + * If any of them are gfs, pass the gfs inode down to the read/write + * worker function so that locks can be acquired in the correct order. + * @file: The file to read/write from/to + * @buf: The buffer to copy to/from + * @size: The amount of data requested + * @offset: The current file offset + * @operation: The read or write worker function + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +walk_vm(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + do_rw_t operation) +{ + if (current->mm) { + struct super_block *sb = file->f_dentry->d_inode->i_sb; + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + unsigned long start = (unsigned long)buf; + unsigned long end = start + size; + int dumping = (current->flags & PF_DUMPCORE); + + if (!dumping) + down_read(&mm->mmap_sem); + + for (vma = find_vma(mm, start); vma; vma = vma->vm_next) { + if (end <= vma->vm_start) + break; + if (vma->vm_file && + vma->vm_file->f_dentry->d_inode->i_sb == sb) + goto do_locks; + } + + if (!dumping) + up_read(&mm->mmap_sem); + } + + { + struct gfs_holder gh; + return operation(file, buf, size, offset, iocb, 0, &gh); + } + + do_locks: + return walk_vm_hard(file, buf, size, offset, iocb, operation); +} + +/** + * functionname - summary + * @param1: description + * @param2: description + * @param3: description + * + * Function description + * + * Returns: what is returned + */ + +static ssize_t +do_read_readi(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + ssize_t count = 0; + + if (*offset < 0) + return -EINVAL; + if (!access_ok(VERIFY_WRITE, buf, size)) + return -EFAULT; + + if (!(file->f_flags & O_LARGEFILE)) { + if (*offset >= 0x7FFFFFFFull) + return -EFBIG; + if (*offset + size > 0x7FFFFFFFull) + size = 0x7FFFFFFFull - *offset; + } + + /* ToDo: not sure about iocb .. wcheng + */ + count = gfs_readi(ip, buf, *offset, size, gfs_copy2user); + + if (count > 0) + *offset += count; + + return count; +} + +/** + * do_read_direct - Read bytes from a file + * @file: The file to read from + * @buf: The buffer to copy into + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @ghs: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes read + * + * Returns: The number of bytes read, errno on failure + */ + +static ssize_t +do_read_direct(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + unsigned int state = LM_ST_DEFERRED; + int flags = 0; + unsigned int x; + ssize_t count = 0; + int error; + + for (x = 0; x < num_gh; x++) + if (ghs[x].gh_gl == ip->i_gl) { + state = LM_ST_SHARED; + flags |= GL_LOCAL_EXCL; + break; + } + + gfs_holder_init(ip->i_gl, state, flags, &ghs[num_gh]); + + error = gfs_glock_nq_m(num_gh + 1, ghs); + if (error) + goto out; + + error = -EINVAL; + if (gfs_is_jdata(ip)) + goto out_gunlock; + + if (gfs_is_stuffed(ip)) { + size_t mask = bdev_hardsect_size(inode->i_sb->s_bdev) - 1; + + if (((*offset) & mask) || (((unsigned long)buf) & mask)) + goto out_gunlock; + + count = do_read_readi(file, buf, size & ~mask, offset, iocb); + } + else { + if (!iocb) + count = do_sync_read(file, buf, size, offset); + else { + struct iovec local_iov = { .iov_base = buf, .iov_len = size}; + + count = generic_file_aio_read(iocb, &local_iov, 1, *offset); + iocb->ki_pos = *offset; + } + } + + error = 0; + + out_gunlock: + gfs_glock_dq_m(num_gh + 1, ghs); + + out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +/** + * do_read_buf - Read bytes from a file + * @file: The file to read from + * @buf: The buffer to copy into + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @ghs: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes read + * + * Returns: The number of bytes read, errno on failure + */ + +static ssize_t +do_read_buf(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + ssize_t count = 0; + int error; + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &ghs[num_gh]); + + error = gfs_glock_nq_m_atime(num_gh + 1, ghs); + if (error) + goto out; + + if (gfs_is_jdata(ip) || + (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags))) + count = do_read_readi(file, buf, size, offset, iocb); + else { + if (!iocb) { + count = do_sync_read(file, buf, size, offset); + } else { + struct iovec local_iov = { .iov_base = buf, .iov_len = size}; + + count = generic_file_aio_read(iocb, &local_iov, 1, *offset); + iocb->ki_pos = *offset; + } + } + + gfs_glock_dq_m(num_gh + 1, ghs); + + out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +static ssize_t +__gfs_read(struct file *file, char *buf, size_t size, loff_t *offset, struct kiocb *iocb) +{ + atomic_inc(&get_v2sdp(file->f_mapping->host->i_sb)->sd_ops_file); + + if (file->f_flags & O_DIRECT) + return walk_vm(file, buf, size, offset, iocb, do_read_direct); + else + return walk_vm(file, buf, size, offset, iocb, do_read_buf); +} + +/** + * gfs_read - Read bytes from a file + * @file: The file to read from + * @buf: The buffer to copy into + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes read + * + * Returns: The number of bytes read, errno on failure + */ + +static ssize_t +gfs_read(struct file *file, char *buf, size_t size, loff_t *offset) +{ + return(__gfs_read(file, buf, size, offset, NULL)); +} + +/* + * gfs_aio_read: match with vfs generic_file_aio_read as: + * (struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) + */ +static ssize_t +gfs_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long count, + loff_t pos) +{ + struct file *filp = iocb->ki_filp; + + BUG_ON(iocb->ki_pos != pos); + return(__gfs_read(filp, iov->iov_base, iov->iov_len, &iocb->ki_pos, iocb)); +} + +/** + * grope_mapping - feel up a mapping that needs to be written + * @buf: the start of the memory to be written + * @size: the size of the memory to be written + * + * We do this after acquiring the locks on the mapping, + * but before starting the write transaction. We need to make + * sure that we don't cause recursive transactions if blocks + * need to be allocated to the file backing the mapping. + * + * Returns: errno + */ + +static int +grope_mapping(char *buf, size_t size) +{ + unsigned long start = (unsigned long)buf; + unsigned long stop = start + size; + char c; + + while (start < stop) { + if (copy_from_user(&c, (char *)start, 1)) + return -EFAULT; + + start += PAGE_CACHE_SIZE; + start &= PAGE_CACHE_MASK; + } + + return 0; +} + +/** + * gfs_file_aio_write_nolock - Call vfs aio layer to write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The offset in the file to write + * @iocb: The io control block. If NULL, a temporary one will be used. + * + * Returns: The number of bytes written, errno on failure + */ +static ssize_t +gfs_file_aio_write_nolock(struct file *file, char *buf, size_t size, + loff_t *offset, struct kiocb *iocb) +{ + struct iovec local_iov = { .iov_base = buf, .iov_len = size }; + struct kiocb local_iocb, *kiocb = NULL; + ssize_t count; + + if (!iocb) { + init_sync_kiocb(&local_iocb, file); + local_iocb.ki_nr_segs = 1; + kiocb = &local_iocb; + } + else + kiocb = iocb; + + kiocb->ki_pos = *offset; + count = generic_file_aio_write_nolock(kiocb, &local_iov, kiocb->ki_nr_segs, + kiocb->ki_pos); + *offset = kiocb->ki_pos; + if (kiocb == &local_iocb && count == -EIOCBQUEUED) + count = wait_on_sync_kiocb(kiocb); + return count; +} + +/** + * do_write_direct_alloc - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_write_direct_alloc(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb) +{ + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = NULL; + struct buffer_head *dibh; + unsigned int data_blocks, ind_blocks; + ssize_t count; + int error; + + gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks); + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = ind_blocks; + al->al_requested_data = data_blocks; + + error = gfs_inplace_reserve(ip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + All blocks for a RG bitmap, whatever indirect blocks we + need, a modified dinode, and a quota change. */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + ind_blocks, + 1); + if (error) + goto fail_ipres; + + if ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID)) { + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + ip->i_di.di_mode &= (ip->i_di.di_mode & S_IXGRP) ? (~(S_ISUID | S_ISGID)) : (~S_ISUID); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + if (gfs_is_stuffed(ip)) { error = gfs_unstuff_dinode(ip, gfs_unstuffer_sync, NULL); if (error) + goto fail_end_trans; + } + + count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb); + if (count < 0) { + error = count; + goto fail_end_trans; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + if (ip->i_di.di_size < inode->i_size) + ip->i_di.di_size = inode->i_size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + gfs_trans_end(sdp); + + /* Question (wcheng) + * 1. should IS_SYNC flush glock ? + * 2. does gfs_log_flush_glock flush data ? + */ + if (file->f_flags & O_SYNC) + gfs_log_flush_glock(ip->i_gl); + + gfs_inplace_release(ip); + gfs_quota_unlock_m(ip); + gfs_alloc_put(ip); + + if (file->f_mapping->nrpages) { + error = filemap_fdatawrite(file->f_mapping); + if (!error) + error = filemap_fdatawait(file->f_mapping); + } + if (error) + return error; + + return count; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + gfs_inplace_release(ip); + + fail_gunlock_q: + gfs_quota_unlock_m(ip); + + fail: + gfs_alloc_put(ip); + + return error; +} + +/** + * do_write_direct - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @gh: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_write_direct(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_file *fp = get_v2fp(file); + unsigned int state = LM_ST_DEFERRED; + int alloc_required; + unsigned int x; + size_t s; + ssize_t count = 0; + int error; + + if (test_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags)) + state = LM_ST_EXCLUSIVE; + else + for (x = 0; x < num_gh; x++) + if (ghs[x].gh_gl == ip->i_gl) { + state = LM_ST_EXCLUSIVE; + break; + } + + restart: + gfs_holder_init(ip->i_gl, state, 0, &ghs[num_gh]); + + error = gfs_glock_nq_m(num_gh + 1, ghs); + if (error) + goto out; + + error = -EINVAL; + if (gfs_is_jdata(ip)) + goto out_gunlock; + + if (num_gh) { + error = grope_mapping(buf, size); + if (error) + goto out_gunlock; + } + + if (file->f_flags & O_APPEND) + *offset = ip->i_di.di_size; + + if (!(file->f_flags & O_LARGEFILE)) { + error = -EFBIG; + if (*offset >= 0x7FFFFFFFull) + goto out_gunlock; + if (*offset + size > 0x7FFFFFFFull) + size = 0x7FFFFFFFull - *offset; + } + + if (gfs_is_stuffed(ip) || + *offset + size > ip->i_di.di_size || + ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID))) + alloc_required = TRUE; + else { + error = gfs_write_alloc_required(ip, *offset, size, + &alloc_required); + if (error) + goto out_gunlock; + } + + if (alloc_required && state != LM_ST_EXCLUSIVE) { + gfs_glock_dq_m(num_gh + 1, ghs); + gfs_holder_uninit(&ghs[num_gh]); + state = LM_ST_EXCLUSIVE; + goto restart; + } + + if (alloc_required) { + set_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags); + + /* for asynchronous IO, the buffer can not be splitted */ + if (iocb) { + count = do_write_direct_alloc(file, buf, size, offset, iocb); + goto out_iocb_write; + } + + /* split large writes into smaller atomic transactions */ + while (size) { + s = gfs_tune_get(sdp, gt_max_atomic_write); + if (s > size) + s = size; + + error = do_write_direct_alloc(file, buf, s, offset, iocb); + if (error < 0) + goto out_gunlock; + + buf += error; + size -= error; + count += error; + } + } else { + struct gfs_holder t_gh; + + clear_bit(GFF_DID_DIRECT_ALLOC, &fp->f_flags); + + error = gfs_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED, 0, &t_gh); + if (error) + goto out_gunlock; + + /* Todo: It would be nice if init_sync_kiocb is exported. + * .. wcheng + */ + count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb); + gfs_glock_dq_uninit(&t_gh); + } + +out_iocb_write: + error = 0; + +out_gunlock: + gfs_glock_dq_m(num_gh + 1, ghs); + +out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +/** + * do_do_write_buf - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_do_write_buf(struct file *file, char *buf, size_t size, loff_t *offset, + struct kiocb *iocb) +{ + struct inode *inode = file->f_mapping->host; + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = NULL; + struct buffer_head *dibh; + unsigned int data_blocks, ind_blocks; + int alloc_required, journaled; + ssize_t count; + int error; + + journaled = gfs_is_jdata(ip); + + gfs_write_calc_reserv(ip, size, &data_blocks, &ind_blocks); + + error = gfs_write_alloc_required(ip, *offset, size, &alloc_required); + if (error) + return error; + + if (alloc_required) { + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto fail; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + if (journaled) + al->al_requested_meta = ind_blocks + data_blocks; + else { + al->al_requested_meta = ind_blocks; + al->al_requested_data = data_blocks; + } + + error = gfs_inplace_reserve(ip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + All blocks for a RG bitmap, whatever indirect blocks we + need, a modified dinode, and a quota change. */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + ind_blocks + + ((journaled) ? data_blocks : 0), 1); + if (error) + goto fail_ipres; + } else { + /* Trans may require: + A modified dinode. */ + + error = gfs_trans_begin(sdp, + 1 + ((journaled) ? data_blocks : 0), 0); + if (error) + goto fail_ipres; + } + + if ((ip->i_di.di_mode & (S_ISUID | S_ISGID)) && !capable(CAP_FSETID)) { + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + ip->i_di.di_mode &= (ip->i_di.di_mode & S_IXGRP) ? (~(S_ISUID | S_ISGID)) : (~S_ISUID); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + if (journaled || + (gfs_is_stuffed(ip) && !test_bit(GIF_PAGED, &ip->i_flags) && + *offset + size <= sdp->sd_sb.sb_bsize - sizeof(struct gfs_dinode))) { + + count = gfs_writei(ip, buf, *offset, size, gfs_copy_from_user, iocb); + if (count < 0) { + error = count; + goto fail_end_trans; + } + if (gfs_is_stuffed(ip)){ + struct page *page; + page = find_get_page(file->f_mapping, 0); + if (page) { + ClearPageUptodate(page); + page_cache_release(page); + } + } + *offset += count; + } else { + count = gfs_file_aio_write_nolock(file, buf, size, offset, iocb); + if (count < 0) { + error = count; + goto fail_end_trans; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + if (ip->i_di.di_size < inode->i_size) + ip->i_di.di_size = inode->i_size; + ip->i_di.di_mtime = ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + if (file->f_flags & O_SYNC || IS_SYNC(inode)) { + gfs_log_flush_glock(ip->i_gl); + error = filemap_fdatawrite(file->f_mapping); + if (error == 0) + error = filemap_fdatawait(file->f_mapping); + if (error) + goto fail_ipres; + } + + if (alloc_required) { + gfs_assert_warn(sdp, count != size || + al->al_alloced_meta || + al->al_alloced_data); + gfs_inplace_release(ip); + gfs_quota_unlock_m(ip); + gfs_alloc_put(ip); + } + + return count; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_ipres: + if (alloc_required) + gfs_inplace_release(ip); + + fail_gunlock_q: + if (alloc_required) + gfs_quota_unlock_m(ip); + + fail: + if (alloc_required) + gfs_alloc_put(ip); + + return error; +} + +/** + * do_write_buf - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * @num_gh: The number of other locks we need to do the read + * @gh: the locks we need plus one for our lock + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +do_write_buf(struct file *file, + char *buf, size_t size, loff_t *offset, + struct kiocb *iocb, + unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + size_t s; + ssize_t count = 0; + int error; + + gfs_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ghs[num_gh]); + + error = gfs_glock_nq_m(num_gh + 1, ghs); + if (error) + goto out; + + if (num_gh) { + error = grope_mapping(buf, size); + if (error) + goto out_gunlock; + } + + if (file->f_flags & O_APPEND) + *offset = ip->i_di.di_size; + + if (!(file->f_flags & O_LARGEFILE)) { + error = -EFBIG; + if (*offset >= 0x7FFFFFFFull) + goto out_gunlock; + if (*offset + size > 0x7FFFFFFFull) + size = 0x7FFFFFFFull - *offset; + } + + /* split large writes into smaller atomic transactions */ + while (size) { + s = gfs_tune_get(sdp, gt_max_atomic_write); + if (s > size) + s = size; + + error = do_do_write_buf(file, buf, s, offset, iocb); + if (error < 0) + goto out_gunlock; + + buf += error; + size -= error; + count += error; + } + + error = 0; + + out_gunlock: + gfs_glock_dq_m(num_gh + 1, ghs); + + out: + gfs_holder_uninit(&ghs[num_gh]); + + return (count) ? count : error; +} + +/** + * gfs_write - Write bytes to a file + * @file: The file to write to + * @buf: The buffer to copy from + * @size: The amount of data requested + * @offset: The current file offset + * + * Outputs: Offset - updated according to number of bytes written + * + * Returns: The number of bytes written, errno on failure + */ + +static ssize_t +__gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset, struct kiocb *iocb) +{ + struct inode *inode = file->f_mapping->host; + ssize_t count; + + atomic_inc(&get_v2sdp(inode->i_sb)->sd_ops_file); + + if (*offset < 0) + return -EINVAL; + if (!access_ok(VERIFY_READ, buf, size)) + return -EFAULT; + + mutex_lock(&inode->i_mutex); + if (file->f_flags & O_DIRECT) + count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_direct); + else + count = walk_vm(file, (char *)buf, size, offset, iocb, do_write_buf); + mutex_unlock(&inode->i_mutex); + + return count; +} + +static ssize_t +gfs_write(struct file *file, const char *buf, size_t size, loff_t *offset) +{ + return(__gfs_write(file, buf, size, offset, NULL)); +} + +static ssize_t +gfs_aio_write(struct kiocb *iocb, const struct iovec *iov, unsigned long segs, + loff_t pos) +{ + struct file *file = iocb->ki_filp; + + BUG_ON(iocb->ki_pos != pos); + + return(__gfs_write(file, iov->iov_base, iov->iov_len, &iocb->ki_pos, + iocb)); +} + +/** + * filldir_reg_func - Report a directory entry to the caller of gfs_dir_read() + * @opaque: opaque data used by the function + * @name: the name of the directory entry + * @length: the length of the name + * @offset: the entry's offset in the directory + * @inum: the inode number the entry points to + * @type: the type of inode the entry points to + * + * Returns: 0 on success, 1 if buffer full + */ + +static int +filldir_reg_func(void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type) +{ + struct filldir_reg *fdr = (struct filldir_reg *)opaque; + struct gfs_sbd *sdp = fdr->fdr_sbd; + unsigned int vfs_type; + int error; + + switch (type) { + case GFS_FILE_NON: + vfs_type = DT_UNKNOWN; + break; + case GFS_FILE_REG: + vfs_type = DT_REG; + break; + case GFS_FILE_DIR: + vfs_type = DT_DIR; + break; + case GFS_FILE_LNK: + vfs_type = DT_LNK; + break; + case GFS_FILE_BLK: + vfs_type = DT_BLK; + break; + case GFS_FILE_CHR: + vfs_type = DT_CHR; + break; + case GFS_FILE_FIFO: + vfs_type = DT_FIFO; + break; + case GFS_FILE_SOCK: + vfs_type = DT_SOCK; + break; + default: + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: type = %u\n", + sdp->sd_fsname, type); + return -EIO; + } + + error = fdr->fdr_filldir(fdr->fdr_opaque, name, length, offset, + inum->no_formal_ino, vfs_type); + if (error) + return 1; + + /* Prefetch locks */ + if (fdr->fdr_prefetch && !(length == 1 && *name == '.')) { + gfs_glock_prefetch_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_SHARED, LM_FLAG_TRY | LM_FLAG_ANY); + gfs_glock_prefetch_num(sdp, + inum->no_addr, &gfs_iopen_glops, + LM_ST_SHARED, LM_FLAG_TRY); + } + + return 0; +} + +/** + * readdir_reg - Read directory entries from a directory + * @file: The directory to read from + * @dirent: Buffer for dirents + * @filldir: Function used to do the copying + * + * Returns: errno + */ + +static int +readdir_reg(struct file *file, void *dirent, filldir_t filldir) +{ + struct gfs_inode *dip = get_v2ip(file->f_mapping->host); + struct filldir_reg fdr; + struct gfs_holder d_gh; + uint64_t offset = file->f_pos; + int error; + + fdr.fdr_sbd = dip->i_sbd; + fdr.fdr_prefetch = TRUE; + fdr.fdr_filldir = filldir; + fdr.fdr_opaque = dirent; + + gfs_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); + error = gfs_glock_nq_atime(&d_gh); + if (error) { + gfs_holder_uninit(&d_gh); + return error; + } + + error = gfs_dir_read(dip, &offset, &fdr, filldir_reg_func); + + gfs_glock_dq_uninit(&d_gh); + + file->f_pos = offset; + + return error; +} + +/** + * filldir_bad_func - Report a directory entry to the caller of gfs_dir_read() + * @opaque: opaque data used by the function + * @name: the name of the directory entry + * @length: the length of the name + * @offset: the entry's offset in the directory + * @inum: the inode number the entry points to + * @type: the type of inode the entry points to + * + * For supporting NFS. + * + * Returns: 0 on success, 1 if buffer full + */ + +static int +filldir_bad_func(void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type) +{ + struct filldir_bad *fdb = (struct filldir_bad *)opaque; + struct gfs_sbd *sdp = fdb->fdb_sbd; + struct filldir_bad_entry *fbe; + + if (fdb->fdb_entry_off == fdb->fdb_entry_num || + fdb->fdb_name_off + length > fdb->fdb_name_size) + return 1; + + fbe = &fdb->fdb_entry[fdb->fdb_entry_off]; + fbe->fbe_name = fdb->fdb_name + fdb->fdb_name_off; + memcpy(fbe->fbe_name, name, length); + fbe->fbe_length = length; + fbe->fbe_offset = offset; + fbe->fbe_inum = *inum; + fbe->fbe_type = type; + + fdb->fdb_entry_off++; + fdb->fdb_name_off += length; + + /* Prefetch locks */ + if (!(length == 1 && *name == '.')) { + gfs_glock_prefetch_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_SHARED, LM_FLAG_TRY | LM_FLAG_ANY); + gfs_glock_prefetch_num(sdp, + inum->no_addr, &gfs_iopen_glops, + LM_ST_SHARED, LM_FLAG_TRY); + } + + return 0; +} + +/** + * readdir_bad - Read directory entries from a directory + * @file: The directory to read from + * @dirent: Buffer for dirents + * @filldir: Function used to do the copying + * + * For supporting NFS. + * + * Returns: errno + */ + +static int +readdir_bad(struct file *file, void *dirent, filldir_t filldir) +{ + struct gfs_inode *dip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = dip->i_sbd; + struct filldir_reg fdr; + unsigned int entries, size; + struct filldir_bad *fdb; + struct gfs_holder d_gh; + uint64_t offset = file->f_pos; + unsigned int x; + struct filldir_bad_entry *fbe; + int error; + + entries = gfs_tune_get(sdp, gt_entries_per_readdir); + size = sizeof(struct filldir_bad) + + entries * (sizeof(struct filldir_bad_entry) + GFS_FAST_NAME_SIZE); + + fdb = kmalloc(size, GFP_KERNEL); + if (!fdb) + return -ENOMEM; + memset(fdb, 0, size); + + fdb->fdb_sbd = sdp; + fdb->fdb_entry = (struct filldir_bad_entry *)(fdb + 1); + fdb->fdb_entry_num = entries; + fdb->fdb_name = ((char *)fdb) + sizeof(struct filldir_bad) + + entries * sizeof(struct filldir_bad_entry); + fdb->fdb_name_size = entries * GFS_FAST_NAME_SIZE; + + gfs_holder_init(dip->i_gl, LM_ST_SHARED, GL_ATIME, &d_gh); + error = gfs_glock_nq_atime(&d_gh); + if (error) { + gfs_holder_uninit(&d_gh); + goto out; + } + + error = gfs_dir_read(dip, &offset, fdb, filldir_bad_func); + + gfs_glock_dq_uninit(&d_gh); + + fdr.fdr_sbd = sdp; + fdr.fdr_prefetch = FALSE; + fdr.fdr_filldir = filldir; + fdr.fdr_opaque = dirent; + + for (x = 0; x < fdb->fdb_entry_off; x++) { + fbe = &fdb->fdb_entry[x]; + + error = filldir_reg_func(&fdr, + fbe->fbe_name, fbe->fbe_length, + fbe->fbe_offset, + &fbe->fbe_inum, fbe->fbe_type); + if (error) { + file->f_pos = fbe->fbe_offset; + error = 0; + goto out; + } + } + + file->f_pos = offset; + + out: + kfree(fdb); + + return error; +} + +/** + * gfs_readdir - Read directory entries from a directory + * @file: The directory to read from + * @dirent: Buffer for dirents + * @filldir: Function used to do the copying + * + * Returns: errno + */ + +static int +gfs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + int error; + + atomic_inc(&get_v2sdp(file->f_mapping->host->i_sb)->sd_ops_file); + + /* Use "bad" one if we're called from NFS daemon */ + if (strcmp(current->comm, "nfsd") != 0) + error = readdir_reg(file, dirent, filldir); + else + error = readdir_bad(file, dirent, filldir); + + return error; +} + +/** + * gfs_ioctl - do an ioctl on a file + * @inode: the inode + * @file: the file pointer + * @cmd: the ioctl command + * @arg: the argument + * + * Returns: errno + */ + +static int +gfs_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&ip->i_sbd->sd_ops_file); + + switch (cmd) { + case GFS_IOCTL_IDENTIFY: { + unsigned int x = GFS_MAGIC; + if (copy_to_user((unsigned int *)arg, &x, sizeof(unsigned int))) + return -EFAULT; + return 0; + } + + case GFS_IOCTL_SUPER: + return gfs_ioctl_i(ip, (void *)arg); + + default: + return -ENOTTY; + } +} + +#ifdef CONFIG_COMPAT +/** + * gfs_compat_ioctl - do an ioctl on a file - compatible between 32-64 bit + * @inode: the inode + * @file: the file pointer + * @cmd: the ioctl command + * @arg: the argument + * + * Returns: errno + */ + +static long +gfs_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + + atomic_inc(&ip->i_sbd->sd_ops_file); + + switch (cmd) { + case GFS_IOCTL_IDENTIFY: { + unsigned int x = GFS_MAGIC; + if (copy_to_user((unsigned int *)arg, &x, sizeof(unsigned int))) + return -EFAULT; + return 0; + } + + case GFS_IOCTL_SUPER: + return gfs_ioctl_i_compat(ip, arg); + + default: + return -ENOTTY; + } +} +#endif + +/** + * gfs_mmap - We don't support shared writable mappings right now + * @file: The file to map + * @vma: The VMA which described the mapping + * + * Returns: 0 or error code + */ + +static int +gfs_mmap(struct file *file, struct vm_area_struct *vma) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_holder i_gh; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); + error = gfs_glock_nq_atime(&i_gh); + if (error) { + gfs_holder_uninit(&i_gh); + return error; + } + + if (gfs_is_jdata(ip)) { + if (vma->vm_flags & VM_MAYSHARE) + error = -ENOSYS; + else + vma->vm_ops = &gfs_vm_ops_private; + } else { + /* This is VM_MAYWRITE instead of VM_WRITE because a call + to mprotect() can turn on VM_WRITE later. */ + + if ((vma->vm_flags & (VM_MAYSHARE | VM_MAYWRITE)) == (VM_MAYSHARE | VM_MAYWRITE)) + vma->vm_ops = &gfs_vm_ops_sharewrite; + else + vma->vm_ops = &gfs_vm_ops_private; + } + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_open - open a file + * @inode: the inode to open + * @file: the struct file for this opening + * + * Returns: errno + */ + +static int +gfs_open(struct inode *inode, struct file *file) +{ + struct gfs_inode *ip = get_v2ip(inode); + struct gfs_holder i_gh; + struct gfs_file *fp; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + fp = kmalloc(sizeof(struct gfs_file), GFP_KERNEL); + if (!fp) + return -ENOMEM; + memset(fp, 0, sizeof(struct gfs_file)); + + init_MUTEX(&fp->f_fl_lock); + + fp->f_inode = ip; + fp->f_vfile = file; + + gfs_assert_warn(ip->i_sbd, !get_v2fp(file)); + set_v2fp(file, fp); + + if (ip->i_di.di_type == GFS_FILE_REG) { + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + goto fail; + + if (!(file->f_flags & O_LARGEFILE) && + ip->i_di.di_size > 0x7FFFFFFFull) { + error = -EFBIG; + goto fail_gunlock; + } + + /* Listen to the Direct I/O flag */ + + if (ip->i_di.di_flags & GFS_DIF_DIRECTIO) + file->f_flags |= O_DIRECT; + + /* Don't let the user open O_DIRECT on a jdata file */ + + if ((file->f_flags & O_DIRECT) && gfs_is_jdata(ip)) { + error = -EINVAL; + goto fail_gunlock; + } + + gfs_glock_dq_uninit(&i_gh); + } + + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&i_gh); + + fail: + set_v2fp(file, NULL); + kfree(fp); + + return error; +} + +/** + * gfs_close - called to close a struct file + * @inode: the inode the struct file belongs to + * @file: the struct file being closed + * + * Returns: errno + */ + +static int +gfs_close(struct inode *inode, struct file *file) +{ + struct gfs_sbd *sdp = get_v2sdp(inode->i_sb); + struct gfs_file *fp; + + atomic_inc(&sdp->sd_ops_file); + + fp = get_v2fp(file); + set_v2fp(file, NULL); + + if (!gfs_assert_warn(sdp, fp)) + kfree(fp); + + return 0; +} + +/** + * gfs_fsync - sync the dirty data for a file (across the cluster) + * @file: the file that points to the dentry (we ignore this) + * @dentry: the dentry that points to the inode to sync + * + * Returns: errno + * + * Obtain a SHARED lock on the file, to force any node with an EXCLUSIVE lock + * to sync file's dirty data to disk, as it releases the EXCLUSIVE lock. + */ + +static int +gfs_fsync(struct file *file, struct dentry *dentry, int datasync) +{ + struct gfs_inode *ip = get_v2ip(dentry->d_inode); + struct gfs_holder i_gh; + struct inode *inode = dentry->d_inode; + int error; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return error; + + if (gfs_is_jdata(ip)) + gfs_log_flush_glock(ip->i_gl); + else { + if ((!datasync) || (inode->i_state & I_DIRTY_DATASYNC)) { + struct writeback_control wbc = { + .sync_mode = WB_SYNC_ALL, + .nr_to_write = 0, + }; + error = sync_inode(inode, &wbc); + } + } + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_lock - acquire/release a posix lock on a file + * @file: the file pointer + * @cmd: either modify or retrieve lock state, possibly wait + * @fl: type and range of lock + * + * Returns: errno + */ + +static int +gfs_lock(struct file *file, int cmd, struct file_lock *fl) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_sbd *sdp = ip->i_sbd; + struct lm_lockname name = + { .ln_number = ip->i_num.no_formal_ino, + .ln_type = LM_TYPE_PLOCK }; + + atomic_inc(&sdp->sd_ops_file); + + if (!(fl->fl_flags & FL_POSIX)) + return -ENOLCK; + if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) + return -ENOLCK; + + if (IS_GETLK(cmd)) + return gfs_lm_plock_get(sdp, &name, file, fl); + else if (fl->fl_type == F_UNLCK) + return gfs_lm_punlock(sdp, &name, file, fl); + else + return gfs_lm_plock(sdp, &name, file, cmd, fl); +} + +/** + * gfs_splice_read - Send bytes to a file or socket + * @in_file: The file to read from + * @out_file: The file to write to + * @count: The amount of data + * @ppos: The beginning file offset + * + * Outputs: offset - updated according to number of bytes read + * + * Returns: The number of bytes sent, errno on failure + */ + +static ssize_t +gfs_splice_read(struct file *in_file, loff_t *ppos, struct pipe_inode_info *pipe, size_t count, unsigned int flags) +{ + struct gfs_inode *ip = get_v2ip(in_file->f_mapping->host); + struct gfs_holder gh; + ssize_t retval; + + atomic_inc(&ip->i_sbd->sd_ops_file); + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); + + retval = gfs_glock_nq_atime(&gh); + if (retval) + goto out; + + if (gfs_is_jdata(ip)) + retval = -ENOSYS; + else + retval = generic_file_splice_read(in_file, ppos, pipe, count, flags); + + gfs_glock_dq(&gh); + + out: + gfs_holder_uninit(&gh); + + return retval; +} + +/** + * do_flock - Acquire a flock on a file + * @file: + * @cmd: + * @fl: + * + * Returns: errno + */ + +static int +do_flock(struct file *file, int cmd, struct file_lock *fl) +{ + struct gfs_file *fp = get_v2fp(file); + struct gfs_holder *fl_gh = &fp->f_fl_gh; + struct gfs_inode *ip = fp->f_inode; + struct gfs_glock *gl; + unsigned int state; + int flags; + int error = 0; + + state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED; + flags = ((IS_SETLKW(cmd)) ? 0 : LM_FLAG_TRY) | GL_EXACT | GL_NOCACHE; + + down(&fp->f_fl_lock); + + gl = fl_gh->gh_gl; + if (gl) { + if (fl_gh->gh_state == state) + goto out; + gfs_glock_hold(gl); + flock_lock_file_wait(file, + &(struct file_lock){.fl_type = F_UNLCK}); + gfs_glock_dq_uninit(fl_gh); + } else { + error = gfs_glock_get(ip->i_sbd, + ip->i_num.no_formal_ino, &gfs_flock_glops, + CREATE, &gl); + if (error) + goto out; + } + + gfs_holder_init(gl, state, flags, fl_gh); + gfs_glock_put(gl); + + error = gfs_glock_nq(fl_gh); + if (error) { + gfs_holder_uninit(fl_gh); + if (error == GLR_TRYFAILED) + error = -EAGAIN; + } else { + error = flock_lock_file_wait(file, fl); + gfs_assert_warn(ip->i_sbd, !error); + } + + out: + up(&fp->f_fl_lock); + + return error; +} + +/** + * do_unflock - Release a flock on a file + * @file: the file + * @fl: + * + */ + +static void +do_unflock(struct file *file, struct file_lock *fl) +{ + struct gfs_file *fp = get_v2fp(file); + struct gfs_holder *fl_gh = &fp->f_fl_gh; + + down(&fp->f_fl_lock); + flock_lock_file_wait(file, fl); + if (fl_gh->gh_gl) + gfs_glock_dq_uninit(fl_gh); + up(&fp->f_fl_lock); +} + +/** + * gfs_flock - acquire/release a flock lock on a file + * @file: the file pointer + * @cmd: either modify or retrieve lock state, possibly wait + * @fl: type and range of lock + * + * Returns: errno + */ + +static int +gfs_flock(struct file *file, int cmd, struct file_lock *fl) +{ + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + + atomic_inc(&ip->i_sbd->sd_ops_file); + + if (!(fl->fl_flags & FL_FLOCK)) + return -ENOLCK; + if ((ip->i_di.di_mode & (S_ISGID | S_IXGRP)) == S_ISGID) + return -ENOLCK; + + if (fl->fl_type == F_UNLCK) { + do_unflock(file, fl); + return 0; + } else + return do_flock(file, cmd, fl); +} + +struct file_operations gfs_file_fops = { + .llseek = gfs_llseek, + .read = gfs_read, + .write = gfs_write, + .aio_read = gfs_aio_read, + .aio_write = gfs_aio_write, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .mmap = gfs_mmap, + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, + .lock = gfs_lock, + .splice_read = gfs_splice_read, + .flock = gfs_flock, +}; + +struct file_operations gfs_dir_fops = { + .readdir = gfs_readdir, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, + .lock = gfs_lock, + .flock = gfs_flock, +}; + +struct file_operations gfs_file_fops_nolock = { + .llseek = gfs_llseek, + .read = gfs_read, + .write = gfs_write, + .aio_read = gfs_aio_read, + .aio_write = gfs_aio_write, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .mmap = gfs_mmap, + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, + .splice_read = gfs_splice_read, +}; + +struct file_operations gfs_dir_fops_nolock = { + .readdir = gfs_readdir, + .ioctl = gfs_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = gfs_compat_ioctl, +#endif + .open = gfs_open, + .release = gfs_close, + .fsync = gfs_fsync, +}; --- linux-2.6.28.orig/ubuntu/gfs/inode.h +++ linux-2.6.28/ubuntu/gfs/inode.h @@ -0,0 +1,57 @@ +#ifndef __INODE_DOT_H__ +#define __INODE_DOT_H__ + +void gfs_inode_attr_in(struct gfs_inode *ip); +void gfs_inode_attr_out(struct gfs_inode *ip); +struct inode *gfs_iget(struct gfs_inode *ip, int create); + +int gfs_copyin_dinode(struct gfs_inode *ip); + +int gfs_inode_get(struct gfs_glock *i_gl, struct gfs_inum *inum, int create, + struct gfs_inode **ipp); +void gfs_inode_hold(struct gfs_inode *ip); +void gfs_inode_put(struct gfs_inode *ip); +void gfs_inode_destroy(struct gfs_inode *ip); + +int gfs_inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum); + +int gfs_change_nlink(struct gfs_inode *ip, int diff); +int gfs_lookupi(struct gfs_holder *d_gh, struct qstr *name, + int is_root, struct gfs_holder *i_gh); +int gfs_createi(struct gfs_holder *d_gh, struct qstr *name, + unsigned int type, unsigned int mode, + struct gfs_holder *i_gh); +int gfs_unlinki(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); +int gfs_rmdiri(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip); +int gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, + struct gfs_inode *ip); +int gfs_ok_to_move(struct gfs_inode *this, struct gfs_inode *to); +int gfs_readlinki(struct gfs_inode *ip, char **buf, unsigned int *len); + +int gfs_glock_nq_atime(struct gfs_holder *gh); +int gfs_glock_nq_m_atime(unsigned int num_gh, struct gfs_holder *ghs); + +void gfs_try_toss_vnode(struct gfs_inode *ip); + +int gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr); + +/* Backwards compatibility functions */ + +int gfs_alloc_qinode(struct gfs_sbd *sdp); +int gfs_alloc_linode(struct gfs_sbd *sdp); + +/* Inlines */ + +static __inline__ int +gfs_is_stuffed(struct gfs_inode *ip) +{ + return !ip->i_di.di_height; +} + +static __inline__ int +gfs_is_jdata(struct gfs_inode *ip) +{ + return ip->i_di.di_flags & GFS_DIF_JDATA; +} + +#endif /* __INODE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/acl.h +++ linux-2.6.28/ubuntu/gfs/acl.h @@ -0,0 +1,34 @@ +#ifndef __ACL_DOT_H__ +#define __ACL_DOT_H__ + +#define GFS_POSIX_ACL_ACCESS "posix_acl_access" +#define GFS_POSIX_ACL_ACCESS_LEN (16) +#define GFS_POSIX_ACL_DEFAULT "posix_acl_default" +#define GFS_POSIX_ACL_DEFAULT_LEN (17) + +#define GFS_ACL_IS_ACCESS(name, len) \ + ((len) == GFS_POSIX_ACL_ACCESS_LEN && \ + !memcmp(GFS_POSIX_ACL_ACCESS, (name), (len))) + +#define GFS_ACL_IS_DEFAULT(name, len) \ + ((len) == GFS_POSIX_ACL_DEFAULT_LEN && \ + !memcmp(GFS_POSIX_ACL_DEFAULT, (name), (len))) + +struct gfs_ea_request; + +int gfs_acl_validate_set(struct gfs_inode *ip, int access, + struct gfs_ea_request *er, + int *remove, mode_t *mode); +int gfs_acl_validate_remove(struct gfs_inode *ip, int access); +int gfs_acl_get(struct gfs_inode *ip, int access, struct posix_acl **acl); +int gfs_check_acl(struct inode *inode, int mask); +int gfs_acl_new_prep(struct gfs_inode *dip, + unsigned int type, mode_t *mode, + void **a_data, void **d_data, + unsigned int *size, + unsigned int *blocks); +int gfs_acl_new_init(struct gfs_inode *dip, struct gfs_inode *ip, + void *a_data, void *d_data, unsigned int size); +int gfs_acl_chmod(struct gfs_inode *ip, struct iattr *attr); + +#endif /* __ACL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/bits.c +++ linux-2.6.28/ubuntu/gfs/bits.c @@ -0,0 +1,211 @@ +/* + * These routines are used by the resource group routines (rgrp.c) + * to keep track of block allocation. Each block is represented by two + * bits. One bit indicates whether or not the block is used. (1=used, + * 0=free) The other bit indicates whether or not the block contains a + * dinode or not. (1=dinode, 0=data block) So, each byte represents + * GFS_NBBY (i.e. 4) blocks. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bits.h" + +#if BITS_PER_LONG == 32 +#define LBITMASK (0x55555555UL) +#define LBITSKIP55 (0x55555555UL) +#define LBITSKIP00 (0x00000000UL) +#else +#define LBITMASK (0x5555555555555555UL) +#define LBITSKIP55 (0x5555555555555555UL) +#define LBITSKIP00 (0x0000000000000000UL) +#endif + +static const char valid_change[16] = { + /* current */ + /* n */ 0, 1, 1, 1, + /* e */ 1, 0, 0, 0, + /* w */ 1, 0, 0, 1, + 0, 0, 1, 0 +}; + +/** + * gfs_setbit - Set a bit in the bitmaps + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @block: the block to set + * @new_state: the new state of the block + * + */ + +void +gfs_setbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + uint32_t block, unsigned char new_state) +{ + unsigned char *byte, *end, cur_state; + unsigned int bit; + + byte = buffer + (block / GFS_NBBY); + bit = (block % GFS_NBBY) * GFS_BIT_SIZE; + end = buffer + buflen; + + gfs_assert(rgd->rd_sbd, byte < end,); + + cur_state = (*byte >> bit) & GFS_BIT_MASK; + + if (valid_change[new_state * 4 + cur_state]) { + *byte ^= cur_state << bit; + *byte |= new_state << bit; + } else + gfs_consist_rgrpd(rgd); +} + +/** + * gfs_testbit - test a bit in the bitmaps + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @block: the block to read + * + */ + +unsigned char +gfs_testbit(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, uint32_t block) +{ + unsigned char *byte, *end, cur_state; + unsigned int bit; + + byte = buffer + (block / GFS_NBBY); + bit = (block % GFS_NBBY) * GFS_BIT_SIZE; + end = buffer + buflen; + + gfs_assert(rgd->rd_sbd, byte < end,); + + cur_state = (*byte >> bit) & GFS_BIT_MASK; + + return cur_state; +} + +/** + * gfs_bitfit - Search an rgrp's bitmap buffer to find a bit-pair representing + * a block in a given allocation state. + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @goal: start search at this block's bit-pair (within @buffer) + * @old_state: GFS_BLKST_XXX the state of the block we're looking for; + * bit 0 = alloc(1)/free(0), bit 1 = meta(1)/data(0) + * + * Scope of @goal and returned block number is only within this bitmap buffer, + * not entire rgrp or filesystem. + * @buffer will be offset from the actual beginning of a bitmap block buffer, + * skipping any header structures. + * + * Return: the block number (bitmap buffer scope) that was found + */ + +uint32_t +gfs_bitfit(unsigned char *buffer, unsigned int buflen, + uint32_t goal, unsigned char old_state) +{ + const u8 *byte, *start, *end; + int bit, startbit; + u32 g1, g2, misaligned; + unsigned long *plong; + unsigned long lskipval; + + lskipval = (old_state & GFS_BLKST_USED) ? LBITSKIP00 : LBITSKIP55; + g1 = (goal / GFS_NBBY); + start = buffer + g1; + byte = start; + end = buffer + buflen; + g2 = ALIGN(g1, sizeof(unsigned long)); + plong = (unsigned long *)(buffer + g2); + startbit = bit = (goal % GFS_NBBY) * GFS_BIT_SIZE; + misaligned = g2 - g1; + if (!misaligned) + goto ulong_aligned; +/* parse the bitmap a byte at a time */ +misaligned: + while (byte < end) { + if (((*byte >> bit) & GFS_BIT_MASK) == old_state) { + return goal + + (((byte - start) * GFS_NBBY) + + ((bit - startbit) >> 1)); + } + bit += GFS_BIT_SIZE; + if (bit >= GFS_NBBY * GFS_BIT_SIZE) { + bit = 0; + byte++; + misaligned--; + if (!misaligned) { + plong = (unsigned long *)byte; + goto ulong_aligned; + } + } + } + return BFITNOENT; + +/* parse the bitmap a unsigned long at a time */ +ulong_aligned: + /* Stop at "end - 1" or else prefetch can go past the end and segfault. + We could "if" it but we'd lose some of the performance gained. + This way will only slow down searching the very last 4/8 bytes + depending on architecture. I've experimented with several ways + of writing this section such as using an else before the goto + but this one seems to be the fastest. */ + while ((unsigned char *)plong < end - sizeof(unsigned long)) { + prefetch(plong + 1); + if (((*plong) & LBITMASK) != lskipval) + break; + plong++; + } + if ((unsigned char *)plong < end) { + byte = (const u8 *)plong; + misaligned += sizeof(unsigned long) - 1; + goto misaligned; + } + return BFITNOENT; +} + +/** + * gfs_bitcount - count the number of bits in a certain state + * @buffer: the buffer that holds the bitmaps + * @buflen: the length (in bytes) of the buffer + * @state: the state of the block we're looking for + * + * Returns: The number of bits + */ + +uint32_t +gfs_bitcount(struct gfs_rgrpd *rgd, + unsigned char *buffer, unsigned int buflen, + unsigned char state) +{ + unsigned char *byte = buffer; + unsigned char *end = buffer + buflen; + unsigned char state1 = state << 2; + unsigned char state2 = state << 4; + unsigned char state3 = state << 6; + uint32_t count = 0; + + for (; byte < end; byte++) { + if (((*byte) & 0x03) == state) + count++; + if (((*byte) & 0x0C) == state1) + count++; + if (((*byte) & 0x30) == state2) + count++; + if (((*byte) & 0xC0) == state3) + count++; + } + + return count; +} --- linux-2.6.28.orig/ubuntu/gfs/Kconfig +++ linux-2.6.28/ubuntu/gfs/Kconfig @@ -0,0 +1,18 @@ +config GFS_FS + tristate "GFS file system support" + select FS_POSIX_ACL + select CRC32 + help + A cluster filesystem. + + Allows a cluster of computers to simultaneously use a block device + that is shared between them (with FC, iSCSI, NBD, etc...). GFS reads + and writes to the block device like a local filesystem, but also uses + a lock module to allow the computers coordinate their I/O so + filesystem consistency is maintained. One of the nifty features of + GFS is perfect consistency -- changes made to the filesystem on one + machine show up immediately on all other machines in the cluster. + + To use the GFS filesystem, you will need to enable one or more of + the below locking modules. Documentation and utilities for GFS can + be found here: http://sources.redhat.com/cluster --- linux-2.6.28.orig/ubuntu/gfs/rgrp.c +++ linux-2.6.28/ubuntu/gfs/rgrp.c @@ -0,0 +1,2152 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bits.h" +#include "dio.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "rgrp.h" +#include "super.h" +#include "trans.h" + +/** + * mhc_hash: find the mhc hash bucket for a buffer + * @bh: the buffer + * + * Returns: The bucket number + */ + +static unsigned int +mhc_hash(struct buffer_head *bh) +{ + uint64_t blkno; + unsigned int h; + + blkno = bh->b_blocknr; + h = gfs_hash(&blkno, sizeof(uint64_t)) & GFS_MHC_HASH_MASK; + + return h; +} + +/** + * mhc_trim - Throw away cached meta-headers, if there are too many of them + * @sdp: The filesystem instance + * @max: Max # of cached meta-headers allowed to survive + * + * Walk filesystem's list of cached meta-headers, in least-recently-used order, + * and keep throwing them away until we're under the max threshold. + */ + +static void +mhc_trim(struct gfs_sbd *sdp, unsigned int max) +{ + struct gfs_meta_header_cache *mc; + + for (;;) { + spin_lock(&sdp->sd_mhc_lock); + if (list_empty(&sdp->sd_mhc_single)) { + spin_unlock(&sdp->sd_mhc_lock); + return; + } else { + mc = list_entry(sdp->sd_mhc_single.prev, + struct gfs_meta_header_cache, + mc_list_single); + list_del(&mc->mc_list_hash); + list_del(&mc->mc_list_single); + list_del(&mc->mc_list_rgd); + spin_unlock(&sdp->sd_mhc_lock); + + kmem_cache_free(gfs_mhc_cachep, mc); + atomic_dec(&sdp->sd_mhc_count); + + if (atomic_read(&sdp->sd_mhc_count) <= max) + return; + } + } +} + +/** + * gfs_mhc_add - add buffer(s) to the cache of metadata headers + * @rgd: Resource Group in which the buffered block(s) reside + * @bh: an array of buffer_head pointers + * @num: the number of bh pointers in the array + * + * Increment each meta-header's generation # by 2. + * Alloc and add each gfs_meta-header_cache to 3 lists/caches: + * Filesystem's meta-header cache (hash) + * Filesystem's list of cached meta-headers + * Resource Group's list of cached meta-headers + * If we now have too many cached, throw some older ones away + */ + +void +gfs_mhc_add(struct gfs_rgrpd *rgd, + struct buffer_head **bh, unsigned int num) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + unsigned int x; + + for (x = 0; x < num; x++) { + struct gfs_meta_header_cache *mc; + struct list_head *head; + uint64_t gen; + + if (gfs_meta_check(sdp, bh[x])) + return; + + mc = kmem_cache_alloc(gfs_mhc_cachep, GFP_KERNEL); + if (!mc) + return; + memset(mc, 0, sizeof(struct gfs_meta_header_cache)); + + mc->mc_block = bh[x]->b_blocknr; + memcpy(&mc->mc_mh, bh[x]->b_data, + sizeof(struct gfs_meta_header)); + + gen = gfs64_to_cpu(mc->mc_mh.mh_generation) + 2; + mc->mc_mh.mh_generation = cpu_to_gfs64(gen); + + head = &sdp->sd_mhc[mhc_hash(bh[x])]; + + spin_lock(&sdp->sd_mhc_lock); + list_add(&mc->mc_list_hash, head); + list_add(&mc->mc_list_single, &sdp->sd_mhc_single); + list_add(&mc->mc_list_rgd, &rgd->rd_mhc); + spin_unlock(&sdp->sd_mhc_lock); + + atomic_inc(&sdp->sd_mhc_count); + } + + x = gfs_tune_get(sdp, gt_max_mhc); + + /* If we've got too many cached, throw some older ones away */ + if (atomic_read(&sdp->sd_mhc_count) > x) + mhc_trim(sdp, x); +} + +/** + * gfs_mhc_fish - Try to fill in a meta buffer with meta-header from the cache + * @sdp: the filesystem + * @bh: the buffer to fill in + * + * Returns: TRUE if the buffer was cached, FALSE otherwise + * + * If buffer is referenced in meta-header cache (search using hash): + * Copy the cached meta-header into the buffer (instead of reading from disk). + * Note that only the meta-header portion of the buffer will have valid data + * (as would be on disk), rest of buffer does *not* reflect disk contents. + * Remove cached gfs_meta_header_cache from all cache lists, free its memory. + */ + +int +gfs_mhc_fish(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + struct list_head *tmp, *head; + struct gfs_meta_header_cache *mc; + + head = &sdp->sd_mhc[mhc_hash(bh)]; + + spin_lock(&sdp->sd_mhc_lock); + + for (tmp = head->next; + tmp != head; + tmp = tmp->next) { + mc = list_entry(tmp, struct gfs_meta_header_cache, mc_list_hash); + if (mc->mc_block != bh->b_blocknr) + continue; + + list_del(&mc->mc_list_hash); + list_del(&mc->mc_list_single); + list_del(&mc->mc_list_rgd); + spin_unlock(&sdp->sd_mhc_lock); + + gfs_prep_new_buffer(bh); + memcpy(bh->b_data, &mc->mc_mh, + sizeof(struct gfs_meta_header)); + + kmem_cache_free(gfs_mhc_cachep, mc); + atomic_dec(&sdp->sd_mhc_count); + + return TRUE; + } + + spin_unlock(&sdp->sd_mhc_lock); + + return FALSE; +} + +/** + * gfs_mhc_zap - Throw away an RG's list of cached metadata headers + * @rgd: The resource group whose list we want to clear + * + * Simply throw away all cached metadata headers on RG's list, + * and free their memory. + */ + +void +gfs_mhc_zap(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_meta_header_cache *mc; + + spin_lock(&sdp->sd_mhc_lock); + + while (!list_empty(&rgd->rd_mhc)) { + mc = list_entry(rgd->rd_mhc.next, + struct gfs_meta_header_cache, + mc_list_rgd); + + list_del(&mc->mc_list_hash); + list_del(&mc->mc_list_single); + list_del(&mc->mc_list_rgd); + spin_unlock(&sdp->sd_mhc_lock); + + kmem_cache_free(gfs_mhc_cachep, mc); + atomic_dec(&sdp->sd_mhc_count); + + spin_lock(&sdp->sd_mhc_lock); + } + + spin_unlock(&sdp->sd_mhc_lock); +} + +/** + * depend_hash() - Turn glock number into hash bucket number + * @formal_ino: + * + * Returns: The number of the corresponding hash bucket + */ + +static unsigned int +depend_hash(uint64_t formal_ino) +{ + unsigned int h; + + h = gfs_hash(&formal_ino, sizeof(uint64_t)); + h &= GFS_DEPEND_HASH_MASK; + + return h; +} + +/** + * depend_sync_one - Sync metadata (not data) for a dependency inode + * @sdp: filesystem instance + * @gd: dependency descriptor + * + * Remove dependency from superblock's hash table and rgrp's list. + * Sync dependency inode's metadata to log and in-place location. + */ + +static void +depend_sync_one(struct gfs_sbd *sdp, struct gfs_depend *gd) +{ + struct gfs_glock *gl; + + spin_lock(&sdp->sd_depend_lock); + list_del(&gd->gd_list_hash); + spin_unlock(&sdp->sd_depend_lock); + list_del(&gd->gd_list_rgd); + + gl = gfs_glock_find(sdp, + &(struct lm_lockname){gd->gd_formal_ino, + LM_TYPE_INODE}); + if (gl) { + if (gl->gl_ops->go_sync) + gl->gl_ops->go_sync(gl, + DIO_METADATA | + DIO_INVISIBLE); + gfs_glock_put(gl); + } + + kfree(gd); + atomic_dec(&sdp->sd_depend_count); +} + +/** + * depend_sync_old - Sync older rgrp-dependent inodes to disk. + * @rgd: Resource group containing dependent inodes + * + * Look at oldest entries in resource group's dependency list, + * sync 'em if they're older than timeout threshold. + */ + +static void +depend_sync_old(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_depend *gd; + + while (!list_empty(&rgd->rd_depend)) { + /* Oldest entries are in prev direction */ + gd = list_entry(rgd->rd_depend.prev, + struct gfs_depend, + gd_list_rgd); + + if (time_before(jiffies, + gd->gd_time + + gfs_tune_get(sdp, gt_depend_secs) * HZ)) + return; + + depend_sync_one(sdp, gd); + } +} + +/** + * gfs_depend_add - Add a dependent inode to rgrp's and filesystem's list + * @rgd: Resource group containing blocks associated with inode + * @formal_ino: inode + * + * Dependent inodes must be flushed to log and in-place blocks before + * releasing an EXCLUSIVE rgrp lock. + * Find pre-existing dependency for this inode/rgrp combination in + * incore superblock struct's sd_depend hash table, or create a new one. + * Either way, move or attach dependency to head of superblock's hash bucket + * and top of rgrp's list. + * If we create a new one, take a moment to sync older dependencies to disk. + */ + +void +gfs_depend_add(struct gfs_rgrpd *rgd, uint64_t formal_ino) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct list_head *head, *tmp; + struct gfs_depend *gd; + + head = &sdp->sd_depend[depend_hash(formal_ino)]; + + spin_lock(&sdp->sd_depend_lock); + + for (tmp = head->next; + tmp != head; + tmp = tmp->next) { + gd = list_entry(tmp, struct gfs_depend, gd_list_hash); + if (gd->gd_rgd == rgd && + gd->gd_formal_ino == formal_ino) { + list_move(&gd->gd_list_hash, head); + spin_unlock(&sdp->sd_depend_lock); + list_move(&gd->gd_list_rgd, &rgd->rd_depend); + gd->gd_time = jiffies; + return; + } + } + + spin_unlock(&sdp->sd_depend_lock); + + gd = gmalloc(sizeof(struct gfs_depend)); + memset(gd, 0, sizeof(struct gfs_depend)); + + gd->gd_rgd = rgd; + gd->gd_formal_ino = formal_ino; + gd->gd_time = jiffies; + + spin_lock(&sdp->sd_depend_lock); + list_add(&gd->gd_list_hash, head); + spin_unlock(&sdp->sd_depend_lock); + list_add(&gd->gd_list_rgd, &rgd->rd_depend); + + atomic_inc(&sdp->sd_depend_count); + + depend_sync_old(rgd); +} + +/** + * gfs_depend_sync - Sync metadata (not data) for an rgrp's dependent inodes + * @rgd: Resource group containing the dependent inodes + * + * As long as this node owns an EXCLUSIVE lock on the rgrp, we can keep + * rgrp's modified metadata blocks in buffer cache. + * + * When this node releases the EX lock, we must flush metadata, so other + * nodes can read the modified content from disk. + */ + +void +gfs_depend_sync(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_depend *gd; + + while (!list_empty(&rgd->rd_depend)) { + gd = list_entry(rgd->rd_depend.next, + struct gfs_depend, + gd_list_rgd); + depend_sync_one(sdp, gd); + } +} + +/** + * rgrp_verify - Verify that a resource group is consistent + * @sdp: the filesystem + * @rgd: the rgrp + * + * Somebody should have already called gfs_glock_rg() on this RG. + */ + +static void +rgrp_verify(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_bitmap *bits = NULL; + uint32_t length = rgd->rd_ri.ri_length; + uint32_t count[4], tmp; + int buf, x; + + memset(count, 0, 4 * sizeof(uint32_t)); + + /* Count # blocks in each of 4 possible allocation states */ + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + for (x = 0; x < 4; x++) + count[x] += gfs_bitcount(rgd, + rgd->rd_bh[buf]->b_data + + bits->bi_offset, + bits->bi_len, x); + } + + if (count[0] != rgd->rd_rg.rg_free) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: free data mismatch: %u != %u\n", + sdp->sd_fsname, count[0], rgd->rd_rg.rg_free); + return; + } + + tmp = rgd->rd_ri.ri_data - + (rgd->rd_rg.rg_usedmeta + rgd->rd_rg.rg_freemeta) - + (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi) - + rgd->rd_rg.rg_free; + if (count[1] != tmp) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: used data mismatch: %u != %u\n", + sdp->sd_fsname, count[1], tmp); + return; + } + + if (count[2] != rgd->rd_rg.rg_freemeta) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: free metadata mismatch: %u != %u\n", + sdp->sd_fsname, count[2], rgd->rd_rg.rg_freemeta); + return; + } + + tmp = rgd->rd_rg.rg_usedmeta + + (rgd->rd_rg.rg_useddi + rgd->rd_rg.rg_freedi); + if (count[3] != tmp) { + if (gfs_consist_rgrpd(rgd)) + printk("GFS: fsid=%s: used metadata mismatch: %u != %u\n", + sdp->sd_fsname, count[3], tmp); + return; + } +} + +/** + * gfs_blk2rgrpd - Find resource group for a given data/meta block number + * @sdp: The GFS superblock + * @n: The data block number + * + * Returns: The resource group, or NULL if not found + * + * Don't try to use this for non-allocatable block numbers (i.e. rgrp header + * or bitmap blocks); it's for allocatable (data/meta) blocks only. + */ + +struct gfs_rgrpd * +gfs_blk2rgrpd(struct gfs_sbd *sdp, uint64_t blk) +{ + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd = NULL; + struct gfs_rindex *ri; + + spin_lock(&sdp->sd_rg_mru_lock); + + for (head = &sdp->sd_rg_mru_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_list_mru); + ri = &rgd->rd_ri; + + if (ri->ri_data1 <= blk && blk < ri->ri_data1 + ri->ri_data) { + list_move(&rgd->rd_list_mru, &sdp->sd_rg_mru_list); + spin_unlock(&sdp->sd_rg_mru_lock); + return rgd; + } + } + + spin_unlock(&sdp->sd_rg_mru_lock); + + return NULL; +} + +/** + * gfs_rgrpd_get_first - get the first Resource Group in the filesystem + * @sdp: The GFS superblock + * + * Returns: The first rgrp in the filesystem + */ + +struct gfs_rgrpd * +gfs_rgrpd_get_first(struct gfs_sbd *sdp) +{ + gfs_assert(sdp, !list_empty(&sdp->sd_rglist),); + return list_entry(sdp->sd_rglist.next, struct gfs_rgrpd, rd_list); +} + +/** + * gfs_rgrpd_get_next - get the next RG + * @rgd: A RG + * + * Returns: The next rgrp + */ + +struct gfs_rgrpd * +gfs_rgrpd_get_next(struct gfs_rgrpd *rgd) +{ + if (rgd->rd_list.next == &rgd->rd_sbd->sd_rglist) + return NULL; + return list_entry(rgd->rd_list.next, struct gfs_rgrpd, rd_list); +} + +/** + * clear_rgrpdi - Clear up rgrps + * @sdp: The GFS superblock + * + */ + +void +clear_rgrpdi(struct gfs_sbd *sdp) +{ + struct gfs_rgrpd *rgd; + struct gfs_glock *gl; + + spin_lock(&sdp->sd_rg_forward_lock); + sdp->sd_rg_forward = NULL; + spin_unlock(&sdp->sd_rg_forward_lock); + + spin_lock(&sdp->sd_rg_recent_lock); + while (!list_empty(&sdp->sd_rg_recent)) { + rgd = list_entry(sdp->sd_rg_recent.next, + struct gfs_rgrpd, rd_recent); + list_del(&rgd->rd_recent); + } + spin_unlock(&sdp->sd_rg_recent_lock); + + while (!list_empty(&sdp->sd_rglist)) { + rgd = list_entry(sdp->sd_rglist.next, + struct gfs_rgrpd, rd_list); + gl = rgd->rd_gl; + + list_del(&rgd->rd_list); + list_del(&rgd->rd_list_mru); + + if (gl) { + gfs_glock_force_drop(gl); + if (atomic_read(&gl->gl_lvb_count)) + gfs_lvb_unhold(gl); + set_gl2rgd(gl, NULL); + gfs_glock_put(gl); + } + + if (rgd->rd_bits) + kfree(rgd->rd_bits); + if (rgd->rd_bh) + kfree(rgd->rd_bh); + + kfree(rgd); + } +} + +/** + * gfs_clear_rgrpd - Clear up rgrps + * @sdp: The GFS superblock + * + */ + +void +gfs_clear_rgrpd(struct gfs_sbd *sdp) +{ + down(&sdp->sd_rindex_lock); + clear_rgrpdi(sdp); + up(&sdp->sd_rindex_lock); +} + +/** + * gfs_compute_bitstructs - Compute the bitmap sizes + * @rgd: The resource group descriptor + * + * Calculates bitmap descriptors, one for each block that contains bitmap data + * + * Returns: errno + */ + +static int +compute_bitstructs(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_bitmap *bits; + uint32_t length = rgd->rd_ri.ri_length; /* # blocks in hdr & bitmap */ + uint32_t bytes_left, bytes; + int x; + + rgd->rd_bits = kmalloc(length * sizeof(struct gfs_bitmap), GFP_KERNEL); + if (!rgd->rd_bits) + return -ENOMEM; + memset(rgd->rd_bits, 0, length * sizeof(struct gfs_bitmap)); + + bytes_left = rgd->rd_ri.ri_bitbytes; + + for (x = 0; x < length; x++) { + bits = &rgd->rd_bits[x]; + + /* small rgrp; bitmap stored completely in header block */ + if (length == 1) { + bytes = bytes_left; + bits->bi_offset = sizeof(struct gfs_rgrp); + bits->bi_start = 0; + bits->bi_len = bytes; + /* header block */ + } else if (x == 0) { + bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs_rgrp); + bits->bi_offset = sizeof(struct gfs_rgrp); + bits->bi_start = 0; + bits->bi_len = bytes; + /* last block */ + } else if (x + 1 == length) { + bytes = bytes_left; + bits->bi_offset = sizeof(struct gfs_meta_header); + bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bits->bi_len = bytes; + /* other blocks */ + } else { + bytes = sdp->sd_sb.sb_bsize - sizeof(struct gfs_meta_header); + bits->bi_offset = sizeof(struct gfs_meta_header); + bits->bi_start = rgd->rd_ri.ri_bitbytes - bytes_left; + bits->bi_len = bytes; + } + + bytes_left -= bytes; + } + + if (bytes_left) { + gfs_consist_rgrpd(rgd); + return -EIO; + } + if ((rgd->rd_bits[length - 1].bi_start + + rgd->rd_bits[length - 1].bi_len) * GFS_NBBY != + rgd->rd_ri.ri_data) { + if (gfs_consist_rgrpd(rgd)) { + gfs_rindex_print(&rgd->rd_ri); + printk("GFS: fsid=%s: start=%u len=%u offset=%u\n", + sdp->sd_fsname, + rgd->rd_bits[length - 1].bi_start, + rgd->rd_bits[length - 1].bi_len, + rgd->rd_bits[length - 1].bi_offset); + } + return -EIO; + } + + rgd->rd_bh = kmalloc(length * sizeof(struct buffer_head *), GFP_KERNEL); + if (!rgd->rd_bh) { + kfree(rgd->rd_bits); + rgd->rd_bits = NULL; + return -ENOMEM; + } + memset(rgd->rd_bh, 0, length * sizeof(struct buffer_head *)); + + return 0; +} + +/** + * gfs_ri_update - Pull in a new resource index from the disk + * @gl: The glock covering the rindex inode + * + * Returns: 0 on successful update, error code otherwise + */ + +static int +gfs_ri_update(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + char buf[sizeof(struct gfs_rindex)]; + int error; + + if (do_mod(ip->i_di.di_size, sizeof(struct gfs_rindex))) { + gfs_consist_inode(ip); + return -EIO; + } + + clear_rgrpdi(sdp); + + for (sdp->sd_rgcount = 0;; sdp->sd_rgcount++) { + error = gfs_internal_read(ip, buf, + sdp->sd_rgcount * + sizeof(struct gfs_rindex), + sizeof(struct gfs_rindex)); + if (!error) + break; + if (error != sizeof(struct gfs_rindex)) { + if (error > 0) + error = -EIO; + goto fail; + } + + rgd = kmalloc(sizeof(struct gfs_rgrpd), GFP_KERNEL); + error = -ENOMEM; + if (!rgd) + goto fail; + memset(rgd, 0, sizeof(struct gfs_rgrpd)); + + INIT_LIST_HEAD(&rgd->rd_mhc); + INIT_LIST_HEAD(&rgd->rd_depend); + rgd->rd_sbd = sdp; + + list_add_tail(&rgd->rd_list, &sdp->sd_rglist); + list_add_tail(&rgd->rd_list_mru, &sdp->sd_rg_mru_list); + + gfs_rindex_in(&rgd->rd_ri, buf); + + error = compute_bitstructs(rgd); + if (error) + goto fail; + + error = gfs_glock_get(sdp, rgd->rd_ri.ri_addr, &gfs_rgrp_glops, + CREATE, &rgd->rd_gl); + if (error) + goto fail; + + error = gfs_lvb_hold(rgd->rd_gl); + if (error) + goto fail; + + set_gl2rgd(rgd->rd_gl, rgd); + rgd->rd_rg_vn = rgd->rd_gl->gl_vn - 1; + } + + sdp->sd_riinode_vn = ip->i_gl->gl_vn; + + return 0; + + fail: + clear_rgrpdi(sdp); + + return error; +} + +/** + * gfs_rindex_hold - Grab a lock on the rindex + * @sdp: The GFS superblock + * @ri_gh: the glock holder + * + * We grab a lock on the rindex inode to make sure that it doesn't + * change whilst we are performing an operation. We keep this lock + * for quite long periods of time compared to other locks. This + * doesn't matter, since it is shared and it is very, very rarely + * accessed in the exclusive mode (i.e. only when expanding the filesystem). + * + * This makes sure that we're using the latest copy of the resource index + * special file, which might have been updated if someone expanded the + * filesystem (via gfs_grow utility), which adds new resource groups. + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_rindex_hold(struct gfs_sbd *sdp, struct gfs_holder *ri_gh) +{ + struct gfs_inode *ip = sdp->sd_riinode; + struct gfs_glock *gl = ip->i_gl; + int error; + + error = gfs_glock_nq_init(gl, LM_ST_SHARED, 0, ri_gh); + if (error) + return error; + + /* Read new copy from disk if we don't have the latest */ + if (sdp->sd_riinode_vn != gl->gl_vn) { + down(&sdp->sd_rindex_lock); + if (sdp->sd_riinode_vn != gl->gl_vn) { + error = gfs_ri_update(ip); + if (error) + gfs_glock_dq_uninit(ri_gh); + } + up(&sdp->sd_rindex_lock); + } + + return error; +} + +/** + * gfs_rgrp_read - Read in a RG's header and bitmaps + * @rgd: the struct gfs_rgrpd describing the RG to read in + * + * Read in all of a Resource Group's header and bitmap blocks. + * Caller must eventually call gfs_rgrp_relse() to free the bitmaps. + * + * Returns: errno + */ + +int +gfs_rgrp_read(struct gfs_rgrpd *rgd) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_glock *gl = rgd->rd_gl; + unsigned int x, length = rgd->rd_ri.ri_length; + int error; + + for (x = 0; x < length; x++) { + gfs_assert_warn(sdp, !rgd->rd_bh[x]); + rgd->rd_bh[x] = gfs_dgetblk(gl, rgd->rd_ri.ri_addr + x); + } + + for (x = 0; x < length; x++) { + error = gfs_dreread(sdp, rgd->rd_bh[x], DIO_START); + if (error) + goto fail; + } + + for (x = length; x--;) { + error = gfs_dreread(sdp, rgd->rd_bh[x], DIO_WAIT); + if (error) + goto fail; + if (gfs_metatype_check(sdp, rgd->rd_bh[x], + (x) ? GFS_METATYPE_RB : GFS_METATYPE_RG)) { + error = -EIO; + goto fail; + } + } + + if (rgd->rd_rg_vn != gl->gl_vn) { + gfs_rgrp_in(&rgd->rd_rg, (rgd->rd_bh[0])->b_data); + rgd->rd_rg_vn = gl->gl_vn; + } + + return 0; + + fail: + for (x = 0; x < length; x++) { + brelse(rgd->rd_bh[x]); + rgd->rd_bh[x] = NULL; + } + + return error; +} + +/** + * gfs_rgrp_relse - Release RG bitmaps read in with gfs_rgrp_read() + * @rgd: the struct gfs_rgrpd describing the RG to read in + * + */ + +void +gfs_rgrp_relse(struct gfs_rgrpd *rgd) +{ + int x, length = rgd->rd_ri.ri_length; + + for (x = 0; x < length; x++) { + brelse(rgd->rd_bh[x]); + rgd->rd_bh[x] = NULL; + } +} + +/** + * gfs_rgrp_lvb_fill - copy RG usage data out of the struct gfs_rgrp into the struct gfs_rgrp_lvb + * @rgd: the resource group data structure + * + */ + +void +gfs_rgrp_lvb_fill(struct gfs_rgrpd *rgd) +{ + struct gfs_rgrp *rg = &rgd->rd_rg; + struct gfs_rgrp_lvb *rb = (struct gfs_rgrp_lvb *)rgd->rd_gl->gl_lvb; + + rb->rb_magic = cpu_to_gfs32(GFS_MAGIC); + rb->rb_free = cpu_to_gfs32(rg->rg_free); + rb->rb_useddi = cpu_to_gfs32(rg->rg_useddi); + rb->rb_freedi = cpu_to_gfs32(rg->rg_freedi); + rb->rb_usedmeta = cpu_to_gfs32(rg->rg_usedmeta); + rb->rb_freemeta = cpu_to_gfs32(rg->rg_freemeta); +} + +/** + * gfs_rgrp_lvb_init - Init the data of a RG LVB + * @rgd: the resource group data structure + * + * Returns: errno + */ + +int +gfs_rgrp_lvb_init(struct gfs_rgrpd *rgd) +{ + struct gfs_glock *gl = rgd->rd_gl; + struct gfs_holder rgd_gh; + int error; + + error = gfs_glock_nq_init(gl, LM_ST_EXCLUSIVE, 0, &rgd_gh); + if (!error) { + gfs_rgrp_lvb_fill(rgd); + gfs_glock_dq_uninit(&rgd_gh); + } + + return error; +} + +/** + * gfs_alloc_get - allocate a struct gfs_alloc structure for an inode + * @ip: the incore GFS inode structure + * + * Alloc and zero an in-place reservation structure, + * and attach it to the GFS incore inode. + * + * FIXME: Don't use gmalloc() + * + * Returns: the struct gfs_alloc + */ + +struct gfs_alloc * +gfs_alloc_get(struct gfs_inode *ip) +{ + struct gfs_alloc *al = ip->i_alloc; + + gfs_assert_warn(ip->i_sbd, !al); + + al = gmalloc(sizeof(struct gfs_alloc)); + memset(al, 0, sizeof(struct gfs_alloc)); + + ip->i_alloc = al; + + return al; +} + +/** + * gfs_alloc_put - throw away the struct gfs_alloc for an inode + * @ip: the inode + * + */ + +void +gfs_alloc_put(struct gfs_inode *ip) +{ + struct gfs_alloc *al = ip->i_alloc; + + if (gfs_assert_warn(ip->i_sbd, al)) + return; + + ip->i_alloc = NULL; + kfree(al); +} + +/** + * try_rgrp_fit - See if a given reservation will fit in a given RG + * @rgd: the RG data + * @al: the struct gfs_alloc structure describing the reservation + * + * If there's room for the requested blocks to be allocated from the RG: + * Sets the $al_reserved_data field in @al. + * Sets the $al_reserved_meta field in @al. + * Sets the $al_rgd field in @al. + * + * Returns: 1 on success (it fits), 0 on failure (it doesn't fit) + */ + +static int +try_rgrp_fit(struct gfs_rgrpd *rgd, struct gfs_alloc *al) +{ + uint32_t freeblks = rgd->rd_rg.rg_free; + uint32_t freemeta = rgd->rd_rg.rg_freemeta; + uint32_t metares = al->al_requested_meta; + uint32_t datares = al->al_requested_data; + + /* First take care of the data blocks required */ + + if (freeblks < al->al_requested_data) + return 0; + + freeblks -= al->al_requested_data; + + /* Then take care of the dinodes */ + + metares += al->al_requested_di; + + /* Then take care of the metadata blocks */ + + while (freemeta < metares) { + if (freeblks < GFS_META_CLUMP) + return 0; + + freeblks -= GFS_META_CLUMP; + freemeta += GFS_META_CLUMP; + + datares += GFS_META_CLUMP; + } + + al->al_rgd = rgd; + al->al_reserved_meta = metares; + al->al_reserved_data = datares; + + return 1; +} + +/** + * recent_rgrp_first - get first RG from "recent" list + * @sdp: The GFS superblock + * @rglast: address of the rgrp used last + * + * Returns: The first rgrp in the recent list + */ + +static struct gfs_rgrpd * +recent_rgrp_first(struct gfs_sbd *sdp, uint64_t rglast) +{ + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd = NULL; + + spin_lock(&sdp->sd_rg_recent_lock); + + if (list_empty(&sdp->sd_rg_recent)) + goto out; + + if (!rglast) + goto first; + + for (head = &sdp->sd_rg_recent, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); + if (rgd->rd_ri.ri_addr == rglast) + goto out; + } + + first: + rgd = list_entry(sdp->sd_rg_recent.next, struct gfs_rgrpd, rd_recent); + + out: + spin_unlock(&sdp->sd_rg_recent_lock); + + return rgd; +} + +/** + * recent_rgrp_next - get next RG from "recent" list + * @cur_rgd: current rgrp + * @remove: + * + * Returns: The next rgrp in the recent list + */ + +static struct gfs_rgrpd * +recent_rgrp_next(struct gfs_rgrpd *cur_rgd, int remove) +{ + struct gfs_sbd *sdp = cur_rgd->rd_sbd; + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd; + + spin_lock(&sdp->sd_rg_recent_lock); + + for (head = &sdp->sd_rg_recent, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); + if (rgd == cur_rgd) { + if (cur_rgd->rd_recent.next != head) + rgd = list_entry(cur_rgd->rd_recent.next, + struct gfs_rgrpd, rd_recent); + else + rgd = NULL; + + if (remove) + list_del(&cur_rgd->rd_recent); + + goto out; + } + } + + rgd = NULL; + if (!list_empty(head)) + rgd = list_entry(head->next, struct gfs_rgrpd, rd_recent); + + out: + spin_unlock(&sdp->sd_rg_recent_lock); + + return rgd; +} + +/** + * recent_rgrp_add - add an RG to tail of "recent" list + * @new_rgd: The rgrp to add + * + * Before adding, make sure that: + * 1) it's not already on the list + * 2) there's still room for more entries + * The capacity limit imposed on the "recent" list is basically a node's "share" + * of rgrps within a cluster, i.e. (total # rgrps) / (# nodes (journals)) + */ + +static void +recent_rgrp_add(struct gfs_rgrpd *new_rgd) +{ + struct gfs_sbd *sdp = new_rgd->rd_sbd; + struct list_head *tmp, *head; + struct gfs_rgrpd *rgd = NULL; + unsigned int count = 0; + unsigned int max = sdp->sd_rgcount / gfs_num_journals(sdp); + + spin_lock(&sdp->sd_rg_recent_lock); + + for (head = &sdp->sd_rg_recent, tmp = head->next; + tmp != head; + tmp = tmp->next) { + rgd = list_entry(tmp, struct gfs_rgrpd, rd_recent); + if (rgd == new_rgd) + goto out; + + if (++count >= max) + goto out; + } + new_rgd->rd_try_counter = 0; + list_add_tail(&new_rgd->rd_recent, &sdp->sd_rg_recent); + + out: + spin_unlock(&sdp->sd_rg_recent_lock); +} + +/** + * forward_rgrp_get - get an rgrp to try next from full list + * @sdp: The GFS superblock + * + * Returns: The rgrp to try next + */ + +static struct gfs_rgrpd * +forward_rgrp_get(struct gfs_sbd *sdp) +{ + struct gfs_rgrpd *rgd; + unsigned int journals = gfs_num_journals(sdp); + unsigned int rg = 0, x; + + spin_lock(&sdp->sd_rg_forward_lock); + + rgd = sdp->sd_rg_forward; + if (!rgd) { + if (sdp->sd_rgcount >= journals) + rg = sdp->sd_rgcount * + sdp->sd_lockstruct.ls_jid / + journals; + + for (x = 0, rgd = gfs_rgrpd_get_first(sdp); + x < rg; + x++, rgd = gfs_rgrpd_get_next(rgd)) + /* Do Nothing */; + + sdp->sd_rg_forward = rgd; + } + + spin_unlock(&sdp->sd_rg_forward_lock); + + return rgd; +} + +/** + * forward_rgrp_set - set the forward rgrp pointer + * @sdp: the filesystem + * @rgd: The new forward rgrp + * + */ + +static void +forward_rgrp_set(struct gfs_sbd *sdp, struct gfs_rgrpd *rgd) +{ + spin_lock(&sdp->sd_rg_forward_lock); + sdp->sd_rg_forward = rgd; + spin_unlock(&sdp->sd_rg_forward_lock); +} + +/** + * get_local_rgrp - Choose and lock a rgrp for allocation + * @ip: the inode to reserve space for + * @rgp: the chosen and locked rgrp + * + * Try to acquire rgrp in way which avoids contending with others. + * + * Returns: errno + */ + +static int +get_local_rgrp(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd, *begin = NULL; + struct gfs_alloc *al = ip->i_alloc; + int flags = LM_FLAG_TRY; + int skipped = 0; + int loops = 0; + int error; + int try_flag; + unsigned int try_threshold = gfs_tune_get(sdp, gt_rgrp_try_threshold); + + /* Try recently successful rgrps */ + + rgd = recent_rgrp_first(sdp, ip->i_last_rg_alloc); + + while (rgd) { + try_flag = (rgd->rd_try_counter >= try_threshold) ? + 0: LM_FLAG_TRY; + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_EXCLUSIVE, try_flag, + &al->al_rgd_gh); + switch (error) { + case 0: + if (try_rgrp_fit(rgd, al)) { + rgd->rd_try_counter = 0; + goto out; + } + gfs_glock_dq_uninit(&al->al_rgd_gh); + rgd = recent_rgrp_next(rgd, TRUE); + break; + + case GLR_TRYFAILED: + rgd->rd_try_counter++; + rgd = recent_rgrp_next(rgd, FALSE); + break; + + default: + return error; + } + } + + /* Go through full list of rgrps */ + + begin = rgd = forward_rgrp_get(sdp); + + for (;;) { + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_EXCLUSIVE, flags, + &al->al_rgd_gh); + switch (error) { + case 0: + if (try_rgrp_fit(rgd, al)) + goto out; + gfs_glock_dq_uninit(&al->al_rgd_gh); + break; + + case GLR_TRYFAILED: + skipped++; + break; + + default: + return error; + } + + rgd = gfs_rgrpd_get_next(rgd); + if (!rgd) + rgd = gfs_rgrpd_get_first(sdp); + + if (rgd == begin) { + if (++loops >= 2 || !skipped) + return -ENOSPC; + flags = 0; + } + } + + out: + ip->i_last_rg_alloc = rgd->rd_ri.ri_addr; + + if (begin) { + recent_rgrp_add(rgd); + rgd = gfs_rgrpd_get_next(rgd); + if (!rgd) + rgd = gfs_rgrpd_get_first(sdp); + forward_rgrp_set(sdp, rgd); + } + + return 0; +} + +/** + * gfs_inplace_reserve_i - Reserve space in the filesystem + * @ip: the inode to reserve space for + * + * Acquire resource group locks to allow for the maximum allocation + * described by "res". + * + * This should probably become more complex again, but for now, let's go + * for simple (one resource group) reservations. + * + * Returns: errno + */ + +int +gfs_inplace_reserve_i(struct gfs_inode *ip, + char *file, unsigned int line) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + int error; + + if (gfs_assert_warn(sdp, + al->al_requested_di || + al->al_requested_data || + al->al_requested_meta)) + return -EINVAL; + + error = gfs_rindex_hold(sdp, &al->al_ri_gh); + if (error) + return error; + + error = get_local_rgrp(ip); + if (error) { + gfs_glock_dq_uninit(&al->al_ri_gh); + return error; + } + + gfs_depend_sync(al->al_rgd); + + al->al_file = file; + al->al_line = line; + + return 0; +} + +/** + * gfs_inplace_release - release an inplace reservation + * @ip: the inode the reservation was taken out on + * + * Release a reservation made by gfs_inplace_reserve(). + */ + +void +gfs_inplace_release(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + + if (gfs_assert_warn(sdp, al->al_alloced_di <= al->al_requested_di) == -1) + printk("GFS: fsid=%s: al_alloced_di = %u, al_requested_di = %u\n" + "GFS: fsid=%s: al_file = %s, al_line = %u\n", + sdp->sd_fsname, al->al_alloced_di, al->al_requested_di, + sdp->sd_fsname, al->al_file, al->al_line); + if (gfs_assert_warn(sdp, al->al_alloced_meta <= al->al_reserved_meta) == -1) + printk("GFS: fsid=%s: al_alloced_meta = %u, al_reserved_meta = %u\n" + "GFS: fsid=%s: al_file = %s, al_line = %u\n", + sdp->sd_fsname, al->al_alloced_meta, al->al_reserved_meta, + sdp->sd_fsname, al->al_file, al->al_line); + if (gfs_assert_warn(sdp, al->al_alloced_data <= al->al_reserved_data) == -1) + printk("GFS: fsid=%s: al_alloced_data = %u, al_reserved_data = %u\n" + "GFS: fsid=%s: al_file = %s, al_line = %u\n", + sdp->sd_fsname, al->al_alloced_data, al->al_reserved_data, + sdp->sd_fsname, al->al_file, al->al_line); + + al->al_rgd = NULL; + gfs_glock_dq_uninit(&al->al_rgd_gh); + gfs_glock_dq_uninit(&al->al_ri_gh); +} + +/** + * gfs_get_block_type - Check a block in a RG is of given type + * @rgd: the resource group holding the block + * @block: the block number + * + * Returns: The block type (GFS_BLKST_*) + */ + +unsigned char +gfs_get_block_type(struct gfs_rgrpd *rgd, uint64_t block) +{ + struct gfs_bitmap *bits = NULL; + uint32_t length, rgrp_block, buf_block; + unsigned int buf; + unsigned char type; + + length = rgd->rd_ri.ri_length; + rgrp_block = block - rgd->rd_ri.ri_data1; + + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + if (rgrp_block < (bits->bi_start + bits->bi_len) * GFS_NBBY) + break; + } + + gfs_assert(rgd->rd_sbd, buf < length,); + buf_block = rgrp_block - bits->bi_start * GFS_NBBY; + + type = gfs_testbit(rgd, + rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, buf_block); + + return type; +} + +/** + * blkalloc_internal - find a block in @old_state, change allocation + * state to @new_state + * @rgd: the resource group descriptor + * @goal: the goal block within the RG (start here to search for avail block) + * @old_state: GFS_BLKST_XXX the before-allocation state to find + * @new_state: GFS_BLKST_XXX the after-allocation block state + * + * Walk rgrp's bitmap to find bits that represent a block in @old_state. + * Add the found bitmap buffer to the transaction. + * Set the found bits to @new_state to change block's allocation state. + * + * This function never fails, because we wouldn't call it unless we + * know (from reservation results, etc.) that a block is available. + * + * Scope of @goal and returned block is just within rgrp (32-bit), + * not the whole filesystem (64-bit). + * + * Returns: the block # allocated (32-bit rgrp scope) + */ + +static uint32_t +blkalloc_internal(struct gfs_rgrpd *rgd, + uint32_t goal, + unsigned char old_state, unsigned char new_state) +{ + struct gfs_bitmap *bits = NULL; + uint32_t length = rgd->rd_ri.ri_length; + uint32_t blk = 0; + unsigned int buf, x; + + /* Find bitmap block that contains bits for goal block */ + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + if (goal < (bits->bi_start + bits->bi_len) * GFS_NBBY) + break; + } + + gfs_assert(rgd->rd_sbd, buf < length,); + + /* Convert scope of "goal" from rgrp-wide to within found bit block */ + goal -= bits->bi_start * GFS_NBBY; + + /* Search (up to entire) bitmap in this rgrp for allocatable block. + "x <= length", instead of "x < length", because we typically start + the search in the middle of a bit block, but if we can't find an + allocatable block anywhere else, we want to be able wrap around and + search in the first part of our first-searched bit block. */ + for (x = 0; x <= length; x++) { + blk = gfs_bitfit(rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, goal, old_state); + if (blk != BFITNOENT) + break; + + /* Try next bitmap block (wrap back to rgrp header if at end) */ + buf = (buf + 1) % length; + bits = &rgd->rd_bits[buf]; + goal = 0; + } + + if (unlikely(x > length)) { + printk("GFS error: possible RG corruption\n"); + printk(" please run gfs_fsck after withdraw\n"); + dump_stack(); + if (gfs_assert_withdraw(rgd->rd_sbd, x <= length)) + blk = 0; + } + + /* Attach bitmap buffer to trans, modify bits to do block alloc */ + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[buf]); + gfs_setbit(rgd, + rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, blk, new_state); + + /* Return allocated block #, rgrp scope (32-bit) */ + return bits->bi_start * GFS_NBBY + blk; +} + +/** + * blkfree_internal - Change alloc state of given block(s) + * @sdp: the filesystem + * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks + * @blen: the length of the block run (all must lie within ONE RG!) + * @new_state: GFS_BLKST_XXX the after-allocation block state + * + * Returns: Resource group containing the block(s) + * + * Find rgrp containing @bstart. + * For each block in run: + * Find allocation bitmap buffer. + * Add bitmap buffer to transaction. + * Set bits to new state. + * Typically used to free blocks to GFS_BLKST_FREE or GFS_BLKST_FREEMETA, + * but @new_state can be any GFS_BLKST_XXX + * + */ + +static struct gfs_rgrpd * +blkfree_internal(struct gfs_sbd *sdp, uint64_t bstart, uint32_t blen, + unsigned char new_state) +{ + struct gfs_rgrpd *rgd; + struct gfs_bitmap *bits = NULL; + uint32_t length, rgrp_blk, buf_blk; + unsigned int buf; + + /* Find rgrp */ + rgd = gfs_blk2rgrpd(sdp, bstart); + if (!rgd) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: block = %llu\n", + sdp->sd_fsname, bstart); + return NULL; + } + + length = rgd->rd_ri.ri_length; + + /* Convert blk # from filesystem scope (64-bit) to RG scope (32-bit) */ + rgrp_blk = bstart - rgd->rd_ri.ri_data1; + + while (blen--) { + /* Find bitmap buffer for this block */ + for (buf = 0; buf < length; buf++) { + bits = &rgd->rd_bits[buf]; + if (rgrp_blk < (bits->bi_start + bits->bi_len) * GFS_NBBY) + break; + } + + gfs_assert(rgd->rd_sbd, buf < length,); + + /* Find bits and set 'em */ + buf_blk = rgrp_blk - bits->bi_start * GFS_NBBY; + rgrp_blk++; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[buf]); + gfs_setbit(rgd, + rgd->rd_bh[buf]->b_data + bits->bi_offset, + bits->bi_len, buf_blk, new_state); + } + + return rgd; +} + +/** + * clump_alloc - Allocate a clump of metadata blocks + * @rgd: the resource group in which to allocate + * @first: returns the first block allocated + * + * Returns: errno + * + * Bitmap-allocate a clump of metadata blocks + * Write metadata blocks to disk with dummy meta-headers + * Add meta-headers to incore meta-header cache + */ + +static int +clump_alloc(struct gfs_rgrpd *rgd, uint32_t *first) +{ + struct gfs_sbd *sdp = rgd->rd_sbd; + struct gfs_meta_header mh; + struct buffer_head **bh; + uint32_t goal, blk; + unsigned int x; + int error = 0; + + /* Dummy meta-header template */ + memset(&mh, 0, sizeof(struct gfs_meta_header)); + mh.mh_magic = GFS_MAGIC; + mh.mh_type = GFS_METATYPE_NONE; + + /* Array of bh pointers used in several steps */ + bh = gmalloc(GFS_META_CLUMP * sizeof(struct buffer_head *)); + memset(bh, 0, GFS_META_CLUMP * sizeof(struct buffer_head *)); + + /* Since we're looking for data blocks to change into meta blocks, + use last alloc'd *data* (not meta) block as start point */ + goal = rgd->rd_last_alloc_data; + + for (x = 0; x < GFS_META_CLUMP; x++) { + blk = blkalloc_internal(rgd, goal, GFS_BLKST_FREE, + GFS_BLKST_FREEMETA); + if (!x) + *first = blk; + + bh[x] = gfs_dgetblk(rgd->rd_gl, rgd->rd_ri.ri_data1 + blk); + + gfs_prep_new_buffer(bh[x]); + + gfs_meta_header_out(&mh, bh[x]->b_data); + ((struct gfs_meta_header *)bh[x]->b_data)->mh_generation = 0; + + /* start write of new meta-buffer to disk */ + error = gfs_dwrite(sdp, bh[x], DIO_DIRTY | DIO_START); + if (error) + goto out; + + goal = blk; + } + + /* Block alloc start point for next time */ + rgd->rd_last_alloc_data = goal; + + /* Wait for all new meta-buffers to get on-disk */ + for (x = 0; x < GFS_META_CLUMP; x++) { + error = gfs_dwrite(sdp, bh[x], DIO_WAIT); + if (error) + goto out; + } + + /* Add all new meta-headers to meta-header cache */ + gfs_mhc_add(rgd, bh, GFS_META_CLUMP); + + gfs_assert_withdraw(sdp, rgd->rd_rg.rg_free >= GFS_META_CLUMP); + rgd->rd_rg.rg_free -= GFS_META_CLUMP; + rgd->rd_rg.rg_freemeta += GFS_META_CLUMP; + + out: + for (x = 0; x < GFS_META_CLUMP; x++) + if (bh[x]) { + gfs_dwrite(sdp, bh[x], DIO_WAIT); + brelse(bh[x]); + } + kfree(bh); + + return error; +} + +/** + * gfs_blkalloc - Allocate a data block + * @ip: the inode to allocate the data block for + * @block: the block allocated + * + */ + +void +gfs_blkalloc(struct gfs_inode *ip, uint64_t *block) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_rgrpd *rgd = al->al_rgd; + uint32_t goal, blk; + int same; + + same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); + goal = (same) ? ip->i_di.di_goal_dblk : rgd->rd_last_alloc_data; + + blk = blkalloc_internal(rgd, goal, + GFS_BLKST_FREE, GFS_BLKST_USED); + rgd->rd_last_alloc_data = blk; + + if (!same) { + ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; + ip->i_di.di_goal_mblk = 0; + } + ip->i_di.di_goal_dblk = blk; + + *block = rgd->rd_ri.ri_data1 + blk; + + gfs_assert_withdraw(sdp, rgd->rd_rg.rg_free); + rgd->rd_rg.rg_free--; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + al->al_alloced_data++; + + gfs_trans_add_quota(sdp, +1, ip->i_di.di_uid, ip->i_di.di_gid); + + /* total=0, free=-1, dinodes=0 */ + gfs_statfs_modify(sdp, 0, -1, 0); +} + +/** + * gfs_metaalloc - Allocate a metadata block to a file + * @ip: the file + * @block: the block allocated + * + * Returns: errno + */ + +int +gfs_metaalloc(struct gfs_inode *ip, uint64_t *block) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_rgrpd *rgd = al->al_rgd; + uint32_t goal, blk; + int same; + int error; + + same = (rgd->rd_ri.ri_addr == ip->i_di.di_goal_rgrp); + + if (!rgd->rd_rg.rg_freemeta) { + error = clump_alloc(rgd, &goal); + if (error) + return error; + + al->al_alloced_data += GFS_META_CLUMP; + } else + goal = (same) ? ip->i_di.di_goal_mblk : rgd->rd_last_alloc_meta; + + blk = blkalloc_internal(rgd, goal, + GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA); + rgd->rd_last_alloc_meta = blk; + + if (!same) { + ip->i_di.di_goal_rgrp = rgd->rd_ri.ri_addr; + ip->i_di.di_goal_dblk = 0; + } + ip->i_di.di_goal_mblk = blk; + + *block = rgd->rd_ri.ri_data1 + blk; + + gfs_assert_withdraw(sdp, rgd->rd_rg.rg_freemeta); + rgd->rd_rg.rg_freemeta--; + rgd->rd_rg.rg_usedmeta++; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + al->al_alloced_meta++; + + gfs_trans_add_quota(sdp, +1, ip->i_di.di_uid, ip->i_di.di_gid); + + /* total=0, free=-1, dinode=0 */ + gfs_statfs_modify(sdp, 0, -1, 0); + + return 0; +} + +/** + * gfs_dialloc - Allocate a dinode + * @dip: the directory that the inode is going in + * @block: the block (result) which this function allocates as the dinode + * (64-bit filesystem scope) + * + * Returns: errno + */ + +int +gfs_dialloc(struct gfs_inode *dip, uint64_t *block) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_alloc *al = dip->i_alloc; + struct gfs_rgrpd *rgd = al->al_rgd; + uint32_t goal, blk; + int error = 0; + + if (rgd->rd_rg.rg_freemeta) + /* pick up where we left off last time */ + goal = rgd->rd_last_alloc_meta; + else { + /* no free meta blocks, allocate a bunch more */ + error = clump_alloc(rgd, &goal); + if (error) + return error; + + al->al_alloced_data += GFS_META_CLUMP; + } + + /* Alloc the dinode; 32-bit "blk" is block offset within rgrp */ + blk = blkalloc_internal(rgd, goal, + GFS_BLKST_FREEMETA, GFS_BLKST_USEDMETA); + + /* remember where we left off, for next time */ + rgd->rd_last_alloc_meta = blk; + + /* convert from rgrp scope (32-bit) to filesystem scope (64-bit) */ + *block = rgd->rd_ri.ri_data1 + blk; + + gfs_assert_withdraw(rgd->rd_sbd, rgd->rd_rg.rg_freemeta); + rgd->rd_rg.rg_freemeta--; + rgd->rd_rg.rg_useddi++; + + /* Attach rgrp header to trans, update freemeta and useddi stats */ + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + /* Update stats in in-place reservation struct */ + al->al_alloced_di++; + al->al_alloced_meta++; + + /* total=0, free=-1, dinodes=1 */ + gfs_statfs_modify(sdp, 0, -1, +1); + + return error; +} + +/** + * gfs_blkfree - free a contiguous run of data block(s) + * @ip: the inode these blocks are being freed from + * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks + * @blen: the length of the block run (all must lie within ONE RG!) + * + * Bitmap-deallocate the blocks (to FREE data state), add bitmap blks to trans + * Update rgrp alloc statistics in rgrp header, add rgrp header buf to trans + * Update quotas, add to trans. + */ + +void +gfs_blkfree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + + rgd = blkfree_internal(sdp, bstart, blen, GFS_BLKST_FREE); + if (!rgd) + return; + + rgd->rd_rg.rg_free += blen; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + gfs_trans_add_quota(sdp, -(int64_t)blen, + ip->i_di.di_uid, + ip->i_di.di_gid); + + /* total=0, free=+blen, dinodes=0 */ + gfs_statfs_modify(sdp, 0, blen, 0); +} + +/** + * gfs_metafree - free a contiguous run of metadata block(s) + * @ip: the inode these blocks are being freed from + * @bstart: first block (64-bit filesystem scope) of a run of contiguous blocks + * @blen: the length of the block run (all must lie within ONE RG!) + * + * Bitmap-deallocate the blocks (to FREEMETA state), add bitmap blks to trans. + * Update rgrp alloc statistics in rgrp header, add rgrp header to trans. + * Update quotas (quotas include metadata, not just data block usage), + * add to trans. + * Release deallocated buffers, add to meta-header cache (we save these in-core + * so we don't need to re-read meta blocks if/when they are re-alloc'd). + */ + +void +gfs_metafree(struct gfs_inode *ip, uint64_t bstart, uint32_t blen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + + rgd = blkfree_internal(sdp, bstart, blen, GFS_BLKST_FREEMETA); + if (!rgd) + return; + + if (rgd->rd_rg.rg_usedmeta < blen) + gfs_consist_rgrpd(rgd); + rgd->rd_rg.rg_usedmeta -= blen; + rgd->rd_rg.rg_freemeta += blen; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + /* total=0, free=blen, dinode=0 */ + gfs_statfs_modify(sdp, 0, blen, 0); + + gfs_trans_add_quota(sdp, -(int64_t)blen, + ip->i_di.di_uid, + ip->i_di.di_gid); + gfs_wipe_buffers(ip, rgd, bstart, blen); +} + +/** + * gfs_difree_uninit - free a dinode block + * @rgd: the resource group that contains the dinode + * @addr: the dinode address + * + * De-allocate the dinode to FREEMETA using block alloc bitmap. + * Update rgrp's block usage statistics (used dinode--, free meta++). + * Add rgrp header to transaction. + */ + +void +gfs_difree_uninit(struct gfs_rgrpd *rgd, uint64_t addr) +{ + struct gfs_rgrpd *tmp_rgd; + + tmp_rgd = blkfree_internal(rgd->rd_sbd, addr, 1, + GFS_BLKST_FREEMETA); + if (!tmp_rgd) + return; + gfs_assert_withdraw(rgd->rd_sbd, rgd == tmp_rgd); + + if (!rgd->rd_rg.rg_useddi) + gfs_consist_rgrpd(rgd); + rgd->rd_rg.rg_useddi--; + rgd->rd_rg.rg_freemeta++; + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(&rgd->rd_rg, rgd->rd_bh[0]->b_data); + + /* total=0, free=1, dinodes=-1 */ + gfs_statfs_modify(rgd->rd_sbd, 0, +1, -1); +} + +/** + * gfs_difree - free a dinode block + * @rgd: the resource group that contains the dinode + * @ip: the inode representing the dinode to free + * + * Free the dinode block to FREEMETA, update rgrp's block usage stats. + * Update quotas (quotas include metadata, not just data block usage), + * add to trans. + * Release deallocated buffers, add to meta-header cache (we save these in-core + * so we don't need to re-read meta blocks if/when they are re-alloc'd). + */ + +void +gfs_difree(struct gfs_rgrpd *rgd, struct gfs_inode *ip) +{ + gfs_difree_uninit(rgd, ip->i_num.no_addr); + gfs_trans_add_quota(ip->i_sbd, -1, ip->i_di.di_uid, ip->i_di.di_gid); + gfs_wipe_buffers(ip, rgd, ip->i_num.no_addr, 1); +} + +/** + * gfs_rlist_add - add a RG to a list of RGs + * @sdp: the filesystem + * @rlist: the list of resource groups + * @block: the block + * + * Figure out what RG a block belongs to and add that RG to the list + * + * FIXME: Don't use gmalloc() + * + */ + +void +gfs_rlist_add(struct gfs_sbd *sdp, struct gfs_rgrp_list *rlist, uint64_t block) +{ + struct gfs_rgrpd *rgd; + struct gfs_rgrpd **tmp; + unsigned int new_space; + unsigned int x; + + if (gfs_assert_warn(sdp, !rlist->rl_ghs)) + return; + + rgd = gfs_blk2rgrpd(sdp, block); + if (!rgd) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: block = %llu\n", + sdp->sd_fsname, block); + return; + } + + for (x = 0; x < rlist->rl_rgrps; x++) + if (rlist->rl_rgd[x] == rgd) + return; + + if (rlist->rl_rgrps == rlist->rl_space) { + new_space = rlist->rl_space + 10; + + tmp = gmalloc(new_space * sizeof(struct gfs_rgrpd *)); + + if (rlist->rl_rgd) { + memcpy(tmp, rlist->rl_rgd, + rlist->rl_space * sizeof(struct gfs_rgrpd *)); + kfree(rlist->rl_rgd); + } + + rlist->rl_space = new_space; + rlist->rl_rgd = tmp; + } + + rlist->rl_rgd[rlist->rl_rgrps++] = rgd; +} + +/** + * gfs_rlist_alloc - all RGs have been added to the rlist, now allocate + * and initialize an array of glock holders for them + * @rlist: the list of resource groups + * @state: the lock state to acquire the RG lock in + * @flags: the modifier flags for the holder structures + * + * FIXME: Don't use gmalloc() + * + */ + +void +gfs_rlist_alloc(struct gfs_rgrp_list *rlist, unsigned int state, int flags) +{ + unsigned int x; + + rlist->rl_ghs = gmalloc(rlist->rl_rgrps * sizeof(struct gfs_holder)); + for (x = 0; x < rlist->rl_rgrps; x++) + gfs_holder_init(rlist->rl_rgd[x]->rd_gl, + state, flags, + &rlist->rl_ghs[x]); +} + +/** + * gfs_rlist_free - free a resource group list + * @list: the list of resource groups + * + */ + +void +gfs_rlist_free(struct gfs_rgrp_list *rlist) +{ + unsigned int x; + + if (rlist->rl_rgd) + kfree(rlist->rl_rgd); + + if (rlist->rl_ghs) { + for (x = 0; x < rlist->rl_rgrps; x++) + gfs_holder_uninit(&rlist->rl_ghs[x]); + kfree(rlist->rl_ghs); + } +} + +/** + * gfs_reclaim_metadata - reclaims unused metadata + * @sdp: the file system + * @inodes: + * @metadata: + * + * This function will look through the resource groups and + * free the unused metadata. + * + * Returns: errno + */ + +int +gfs_reclaim_metadata(struct gfs_sbd *sdp, + uint64_t *inodes, + uint64_t *metadata) +{ + struct gfs_holder ji_gh, ri_gh, rgd_gh, t_gh; + struct gfs_rgrpd *rgd; + struct gfs_rgrp *rg; + struct gfs_dinode *di; + struct gfs_inum next; + struct buffer_head *bh; + uint32_t flags; + uint32_t goal; + unsigned int x; + int error = 0; + + *inodes = *metadata = 0; + + /* Acquire the jindex lock here so we don't deadlock with a + process writing the the jindex inode. :-( */ + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) + goto fail; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + goto fail_jindex_relse; + + for (rgd = gfs_rgrpd_get_first(sdp); + rgd; + rgd = gfs_rgrpd_get_next(rgd)) { + error = gfs_glock_nq_init(rgd->rd_gl, + LM_ST_EXCLUSIVE, GL_NOCACHE, + &rgd_gh); + if (error) + goto fail_rindex_relse; + + rgrp_verify(rgd); + + rg = &rgd->rd_rg; + + if (!rg->rg_freedi && !rg->rg_freemeta) { + gfs_glock_dq_uninit(&rgd_gh); + continue; + } + + gfs_mhc_zap(rgd); + gfs_depend_sync(rgd); + + error = gfs_lock_fs_check_clean(sdp, LM_ST_EXCLUSIVE, &t_gh); + if (error) + goto fail_gunlock_rg; + + error = gfs_trans_begin(sdp, rgd->rd_ri.ri_length, 0); + if (error) + goto fail_unlock_fs; + + next = rg->rg_freedi_list; + + for (x = rg->rg_freedi; x--;) { + if (!next.no_formal_ino || !next.no_addr) { + gfs_consist_rgrpd(rgd); + error = -EIO; + goto fail_end_trans; + } + + blkfree_internal(sdp, next.no_addr, 1, GFS_BLKST_FREE); + + error = gfs_dread(rgd->rd_gl, next.no_addr, + DIO_FORCE | DIO_START | DIO_WAIT, &bh); + if (error) + goto fail_end_trans; + + di = (struct gfs_dinode *)bh->b_data; + flags = di->di_flags; + flags = gfs32_to_cpu(flags); + if (!(flags & GFS_DIF_UNUSED)) { + gfs_consist_rgrpd(rgd); + brelse(bh); + error = -EIO; + goto fail_end_trans; + } + + gfs_inum_in(&next, (char *)&di->di_next_unused); + + brelse(bh); + + rg->rg_freedi--; + rg->rg_free++; + (*inodes)++; + } + + if (next.no_formal_ino || next.no_addr) { + gfs_consist_rgrpd(rgd); + error = -EIO; + goto fail_end_trans; + } + rg->rg_freedi_list = next; + + goal = 0; + for (x = rg->rg_freemeta; x--;) { + goal = blkalloc_internal(rgd, goal, + GFS_BLKST_FREEMETA, GFS_BLKST_FREE); + rg->rg_freemeta--; + rg->rg_free++; + (*metadata)++; + } + + gfs_trans_add_bh(rgd->rd_gl, rgd->rd_bh[0]); + gfs_rgrp_out(rg, rgd->rd_bh[0]->b_data); + + gfs_trans_end(sdp); + + gfs_glock_dq_uninit(&t_gh); + + gfs_glock_dq_uninit(&rgd_gh); + } + + gfs_glock_dq_uninit(&ri_gh); + + gfs_glock_dq_uninit(&ji_gh); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_unlock_fs: + gfs_glock_dq_uninit(&t_gh); + + fail_gunlock_rg: + gfs_glock_dq_uninit(&rgd_gh); + + fail_rindex_relse: + gfs_glock_dq_uninit(&ri_gh); + + fail_jindex_relse: + gfs_glock_dq_uninit(&ji_gh); + + fail: + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/lvb.h +++ linux-2.6.28/ubuntu/gfs/lvb.h @@ -0,0 +1,53 @@ +/* + * Formats of Lock Value Blocks (LVBs) for various types of locks. + * These 32-bit data chunks can be shared quickly between nodes + * via the inter-node lock manager (via LAN instead of on-disk). + */ + +#ifndef __LVB_DOT_H__ +#define __LVB_DOT_H__ + +#define GFS_MIN_LVB_SIZE (32) + +/* + * Resource Group block allocation statistics + * Each resource group lock contains one of these in its LVB. + * Used for sharing approximate current statistics for statfs. + * Not used for actual block allocation. + */ +struct gfs_rgrp_lvb { + uint32_t rb_magic; /* GFS_MAGIC sanity check value */ + uint32_t rb_free; /* # free data blocks */ + uint32_t rb_useddi; /* # used dinode blocks */ + uint32_t rb_freedi; /* # free dinode blocks */ + uint32_t rb_usedmeta; /* # used metadata blocks */ + uint32_t rb_freemeta; /* # free metadata blocks */ +}; + +/* + * Quota + * Each quota lock contains one of these in its LVB. + * Keeps track of block allocation limits and current block allocation + * for either a cluster-wide user or a cluster-wide group. + */ +struct gfs_quota_lvb { + uint32_t qb_magic; /* GFS_MAGIC sanity check value */ + uint32_t qb_pad; + uint64_t qb_limit; /* Hard limit of # blocks to alloc */ + uint64_t qb_warn; /* Warn user when alloc is above this # */ + int64_t qb_value; /* Current # blocks allocated */ +}; + +/* Translation functions */ + +void gfs_rgrp_lvb_in(struct gfs_rgrp_lvb *rb, char *lvb); +void gfs_rgrp_lvb_out(struct gfs_rgrp_lvb *rb, char *lvb); +void gfs_quota_lvb_in(struct gfs_quota_lvb *qb, char *lvb); +void gfs_quota_lvb_out(struct gfs_quota_lvb *qb, char *lvb); + +/* Printing functions */ + +void gfs_rgrp_lvb_print(struct gfs_rgrp_lvb *rb); +void gfs_quota_lvb_print(struct gfs_quota_lvb *qb); + +#endif /* __LVB_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/gfs_ioctl.h +++ linux-2.6.28/ubuntu/gfs/gfs_ioctl.h @@ -0,0 +1,31 @@ +#ifndef __GFS_IOCTL_DOT_H__ +#define __GFS_IOCTL_DOT_H__ + +#define _GFSC_(x) (('G' << 8) | (x)) + +/* Ioctls implemented */ + +#define GFS_IOCTL_IDENTIFY _GFSC_(35) +#define GFS_IOCTL_SUPER _GFSC_(45) + +struct gfs_ioctl { + unsigned int gi_argc; + char **gi_argv; + + char __user *gi_data; + unsigned int gi_size; + uint64_t gi_offset; +}; + +#ifdef CONFIG_COMPAT +struct gfs_ioctl_compat { + unsigned int gi_argc; + uint32_t gi_argv; + + uint32_t gi_data; + unsigned int gi_size; + uint64_t gi_offset; +}; +#endif + +#endif /* ___GFS_IOCTL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_file.h +++ linux-2.6.28/ubuntu/gfs/ops_file.h @@ -0,0 +1,9 @@ +#ifndef __OPS_FILE_DOT_H__ +#define __OPS_FILE_DOT_H__ + +extern struct file_operations gfs_file_fops; +extern struct file_operations gfs_dir_fops; +extern struct file_operations gfs_file_fops_nolock; +extern struct file_operations gfs_dir_fops_nolock; + +#endif /* __OPS_FILE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/dio.h +++ linux-2.6.28/ubuntu/gfs/dio.h @@ -0,0 +1,157 @@ +#ifndef __DIO_DOT_H__ +#define __DIO_DOT_H__ + +void gfs_ail_start_trans(struct gfs_sbd *sdp, struct gfs_trans *tr); +int gfs_ail_empty_trans(struct gfs_sbd *sdp, struct gfs_trans *tr); + +/* Asynchronous I/O Routines */ + +struct buffer_head *gfs_dgetblk(struct gfs_glock *gl, uint64_t blkno); +int gfs_dread(struct gfs_glock *gl, uint64_t blkno, + int flags, struct buffer_head **bhp); + +void gfs_prep_new_buffer(struct buffer_head *bh); +int gfs_dreread(struct gfs_sbd *sdp, struct buffer_head *bh, int flags); +int gfs_dwrite(struct gfs_sbd *sdp, struct buffer_head *bh, int flags); + +void gfs_attach_bufdata(struct buffer_head *bh, struct gfs_glock *gl); +int gfs_is_pinned(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_dpin(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_dunpin(struct gfs_sbd *sdp, struct buffer_head *bh, + struct gfs_trans *tr); + +static __inline__ +void gfs_lock_buffer(struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + down(&bd->bd_lock); +} +static __inline__ +int gfs_trylock_buffer(struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + return down_trylock(&bd->bd_lock); +} +static __inline__ +void gfs_unlock_buffer(struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + up(&bd->bd_lock); +} + +void gfs_logbh_init(struct gfs_sbd *sdp, struct buffer_head *bh, uint64_t blkno, + char *data); +void gfs_logbh_uninit(struct gfs_sbd *sdp, struct buffer_head *bh); +void gfs_logbh_start(struct gfs_sbd *sdp, struct buffer_head *bh); +int gfs_logbh_wait(struct gfs_sbd *sdp, struct buffer_head *bh); + +int gfs_replay_buf(struct gfs_glock *gl, struct buffer_head *bh); +void gfs_replay_check(struct gfs_sbd *sdp); +void gfs_replay_wait(struct gfs_sbd *sdp); + +void gfs_wipe_buffers(struct gfs_inode *ip, struct gfs_rgrpd *rgd, + uint64_t bstart, uint32_t blen); + +void gfs_sync_meta(struct gfs_sbd *sdp); + +/* Buffer Caching routines */ + +int gfs_get_meta_buffer(struct gfs_inode *ip, int height, uint64_t num, int new, + struct buffer_head **bhp); +int gfs_get_data_buffer(struct gfs_inode *ip, uint64_t block, int new, + struct buffer_head **bhp); +void gfs_start_ra(struct gfs_glock *gl, uint64_t dblock, uint32_t extlen); + +static __inline__ int +gfs_get_inode_buffer(struct gfs_inode *ip, struct buffer_head **bhp) +{ + return gfs_get_meta_buffer(ip, 0, ip->i_num.no_addr, FALSE, bhp); +} + +struct inode *gfs_aspace_get(struct gfs_sbd *sdp); +void gfs_aspace_put(struct inode *aspace); + +void gfs_inval_buf(struct gfs_glock *gl); +void gfs_sync_buf(struct gfs_glock *gl, int flags); + +void gfs_flush_meta_cache(struct gfs_inode *ip); + +/* Buffer Content Functions */ + +/** + * gfs_buffer_clear - Zeros out a buffer + * @ip: The GFS inode + * @bh: The buffer to zero + * + */ + +static __inline__ void +gfs_buffer_clear(struct buffer_head *bh) +{ + memset(bh->b_data, 0, bh->b_size); +} + +/** + * gfs_buffer_clear_tail - Clear buffer beyond the dinode + * @bh: The buffer containing the on-disk inode + * @head: the size of the head of the buffer + * + * Clears the remaining part of an on-disk inode that is not a dinode. + * i.e. The data part of a stuffed inode, or the top level of metadata + * of a non-stuffed inode. + */ + +static __inline__ void +gfs_buffer_clear_tail(struct buffer_head *bh, int head) +{ + memset(bh->b_data + head, 0, bh->b_size - head); +} + +/** + * gfs_buffer_clear_ends - Zero out any bits of a buffer which are not being written + * @bh: The buffer + * @offset: Offset in buffer where write starts + * @amount: Amount of data being written + * @journaled: TRUE if this is a journaled buffer + * + */ + +static __inline__ void +gfs_buffer_clear_ends(struct buffer_head *bh, int offset, int amount, + int journaled) +{ + int z_off1 = (journaled) ? sizeof(struct gfs_meta_header) : 0; + int z_len1 = offset - z_off1; + int z_off2 = offset + amount; + int z_len2 = (bh)->b_size - z_off2; + + if (z_len1) + memset(bh->b_data + z_off1, 0, z_len1); + + if (z_len2) + memset(bh->b_data + z_off2, 0, z_len2); +} + +/** + * gfs_buffer_copy_tail - copies the tail of one buffer to another + * @to_bh: the buffer to copy to + * @to_head: the size of the head of to_bh + * @from_bh: the buffer to copy from + * @from_head: the size of the head of from_bh + * + * from_head is guaranteed to bigger than to_head + */ + +static __inline__ void +gfs_buffer_copy_tail(struct buffer_head *to_bh, int to_head, + struct buffer_head *from_bh, int from_head) +{ + memcpy(to_bh->b_data + to_head, + from_bh->b_data + from_head, + from_bh->b_size - from_head); + memset(to_bh->b_data + to_bh->b_size + to_head - from_head, + 0, + from_head - to_head); +} + +#endif /* __DIO_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_super.h +++ linux-2.6.28/ubuntu/gfs/ops_super.h @@ -0,0 +1,6 @@ +#ifndef __OPS_SUPER_DOT_H__ +#define __OPS_SUPER_DOT_H__ + +extern struct super_operations gfs_super_ops; + +#endif /* __OPS_SUPER_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/dio.c +++ linux-2.6.28/ubuntu/gfs/dio.c @@ -0,0 +1,1342 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "lops.h" +#include "rgrp.h" +#include "trans.h" + +#define buffer_busy(bh) ((bh)->b_state & ((1ul << BH_Dirty) | (1ul << BH_Lock))) + +/** + * aspace_get_block - + * @inode: + * @lblock: + * @bh_result: + * @create: + * + * Returns: errno + */ + +static int +aspace_get_block(struct inode *inode, sector_t lblock, + struct buffer_head *bh_result, int create) +{ + gfs_assert_warn(get_v2sdp(inode->i_sb), FALSE); + return -ENOSYS; +} + +/** + * gfs_aspace_writepage - write an aspace page + * @page: the page + * @wbc: + * + * Returns: errno + */ + +static int +gfs_aspace_writepage(struct page *page, struct writeback_control *wbc) +{ + return block_write_full_page(page, aspace_get_block, wbc); +} + +/** + * stuck_releasepage - We're stuck in gfs_releasepage(). Print stuff out. + * @bh: the buffer we're stuck on + * + */ + +static void +stuck_releasepage(struct buffer_head *bh) +{ + struct gfs_sbd *sdp = get_v2sdp(bh->b_page->mapping->host->i_sb); + struct gfs_bufdata *bd = get_v2bd(bh); + + printk("GFS: fsid=%s: stuck in gfs_releasepage()...\n", sdp->sd_fsname); + printk("GFS: fsid=%s: blkno = %"PRIu64", bh->b_count = %d\n", + sdp->sd_fsname, + (uint64_t)bh->b_blocknr, + atomic_read(&bh->b_count)); + printk("GFS: fsid=%s: get_v2bd(bh) = %s\n", + sdp->sd_fsname, + (bd) ? "!NULL" : "NULL"); + + if (bd) { + struct gfs_glock *gl = bd->bd_gl; + + printk("GFS: fsid=%s: gl = (%u, %"PRIu64")\n", + sdp->sd_fsname, + gl->gl_name.ln_type, + gl->gl_name.ln_number); + + printk("GFS: fsid=%s: bd_new_le.le_trans = %s\n", + sdp->sd_fsname, + (bd->bd_new_le.le_trans) ? "!NULL" : "NULL"); + printk("GFS: fsid=%s: bd_incore_le.le_trans = %s\n", + sdp->sd_fsname, + (bd->bd_incore_le.le_trans) ? "!NULL" : "NULL"); + printk("GFS: fsid=%s: bd_frozen = %s\n", + sdp->sd_fsname, + (bd->bd_frozen) ? "!NULL" : "NULL"); + printk("GFS: fsid=%s: bd_pinned = %u\n", + sdp->sd_fsname, bd->bd_pinned); + printk("GFS: fsid=%s: bd_ail_tr_list = %s\n", + sdp->sd_fsname, + (list_empty(&bd->bd_ail_tr_list)) ? "Empty" : "!Empty"); + + if (gl->gl_ops == &gfs_inode_glops) { + struct gfs_inode *ip = get_gl2ip(gl); + + if (ip) { + unsigned int x; + + printk("GFS: fsid=%s: ip = %"PRIu64"/%"PRIu64"\n", + sdp->sd_fsname, + ip->i_num.no_formal_ino, + ip->i_num.no_addr); + printk("GFS: fsid=%s: ip->i_count = %d, ip->i_vnode = %s\n", + sdp->sd_fsname, + atomic_read(&ip->i_count), + (ip->i_vnode) ? "!NULL" : "NULL"); + for (x = 0; x < GFS_MAX_META_HEIGHT; x++) + printk("GFS: fsid=%s: ip->i_cache[%u] = %s\n", + sdp->sd_fsname, x, + (ip->i_cache[x]) ? "!NULL" : "NULL"); + } + } + } +} + +/** + * gfs_aspace_releasepage - free the metadata associated with a page + * @page: the page that's being released + * @gfp_mask: passed from Linux VFS, ignored by us + * + * Call try_to_free_buffers() if the buffers in this page can be + * released. + * + * Returns: 0 + */ + +static int +gfs_aspace_releasepage(struct page *page, gfp_t gfp_mask) +{ + struct inode *aspace = page->mapping->host; + struct gfs_sbd *sdp = get_v2sdp(aspace->i_sb); + struct buffer_head *bh, *head; + struct gfs_bufdata *bd; + unsigned long t; + + if (!page_has_buffers(page)) + goto out; + + head = bh = page_buffers(page); + do { + t = jiffies; + + while (atomic_read(&bh->b_count)) { + if (atomic_read(&aspace->i_writecount)) { + if (time_after_eq(jiffies, + t + + gfs_tune_get(sdp, gt_stall_secs) * HZ)) { + stuck_releasepage(bh); + t = jiffies; + } + + yield(); + continue; + } + + return 0; + } + + bd = get_v2bd(bh); + if (bd) { + gfs_assert_warn(sdp, bd->bd_bh == bh); + gfs_assert_warn(sdp, !bd->bd_new_le.le_trans); + gfs_assert_warn(sdp, !bd->bd_incore_le.le_trans); + gfs_assert_warn(sdp, !bd->bd_frozen); + gfs_assert_warn(sdp, !bd->bd_pinned); + gfs_assert_warn(sdp, list_empty(&bd->bd_ail_tr_list)); + kmem_cache_free(gfs_bufdata_cachep, bd); + atomic_dec(&sdp->sd_bufdata_count); + set_v2bd(bh, NULL); + } + + bh = bh->b_this_page; + } + while (bh != head); + + out: + return try_to_free_buffers(page); +} + +static struct address_space_operations aspace_aops = { + .writepage = gfs_aspace_writepage, + .releasepage = gfs_aspace_releasepage, +}; + +/** + * gfs_aspace_get - Create and initialize a struct inode structure + * @sdp: the filesystem the aspace is in + * + * Right now a struct inode is just a struct inode. Maybe Linux + * will supply a more lightweight address space construct (that works) + * in the future. + * + * Make sure pages/buffers in this aspace aren't in high memory. + * + * Returns: the aspace + */ + +struct inode * +gfs_aspace_get(struct gfs_sbd *sdp) +{ + struct inode *aspace; + + aspace = new_inode(sdp->sd_vfs); + if (aspace) { + mapping_set_gfp_mask(aspace->i_mapping, GFP_KERNEL); + aspace->i_mapping->a_ops = &aspace_aops; + aspace->i_size = ~0ULL; + set_v2ip(aspace, NULL); + insert_inode_hash(aspace); + } + + return aspace; +} + +/** + * gfs_aspace_put - get rid of an aspace + * @aspace: + * + */ + +void +gfs_aspace_put(struct inode *aspace) +{ + remove_inode_hash(aspace); + iput(aspace); +} + +/** + * gfs_ail_start_trans - Start I/O on a part of the AIL + * @sdp: the filesystem + * @tr: the part of the AIL + * + */ + +void +gfs_ail_start_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *head, *tmp, *prev; + struct gfs_bufdata *bd; + struct buffer_head *bh; + int retry; + + do { + retry = FALSE; + + spin_lock(&sdp->sd_ail_lock); + + for (head = &tr->tr_ail_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (gfs_trylock_buffer(bh)) + continue; + + if (bd->bd_pinned) { + gfs_unlock_buffer(bh); + continue; + } + + if (!buffer_busy(bh)) { + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + + gfs_unlock_buffer(bh); + brelse(bh); + continue; + } + + if (buffer_dirty(bh)) { + list_move(&bd->bd_ail_tr_list, head); + + spin_unlock(&sdp->sd_ail_lock); + wait_on_buffer(bh); + ll_rw_block(WRITE, 1, &bh); + spin_lock(&sdp->sd_ail_lock); + + gfs_unlock_buffer(bh); + retry = TRUE; + break; + } + + gfs_unlock_buffer(bh); + } + + spin_unlock(&sdp->sd_ail_lock); + } while (retry); +} + +/** + * gfs_ail_empty_trans - Check whether or not a trans in the AIL has been synced + * @sdp: the filesystem + * @tr: the transaction + * + */ + +int +gfs_ail_empty_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *head, *tmp, *prev; + struct gfs_bufdata *bd; + struct buffer_head *bh; + int ret; + + spin_lock(&sdp->sd_ail_lock); + + for (head = &tr->tr_ail_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (gfs_trylock_buffer(bh)) + continue; + + if (bd->bd_pinned || buffer_busy(bh)) { + gfs_unlock_buffer(bh); + continue; + } + + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + + gfs_unlock_buffer(bh); + brelse(bh); + } + + ret = list_empty(head); + + spin_unlock(&sdp->sd_ail_lock); + + return ret; +} + +/** + * ail_empty_gl - remove all buffers for a given lock from the AIL + * @gl: the glock + * + * None of the buffers should be dirty, locked, or pinned. + */ + +static void +ail_empty_gl(struct gfs_glock *gl) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_bufdata *bd; + struct buffer_head *bh; + + spin_lock(&sdp->sd_ail_lock); + + while (!list_empty(&gl->gl_ail_bufs)) { + bd = list_entry(gl->gl_ail_bufs.next, + struct gfs_bufdata, bd_ail_gl_list); + bh = bd->bd_bh; + + gfs_assert_withdraw(sdp, !bd->bd_pinned && !buffer_busy(bh)); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + + brelse(bh); + } + + spin_unlock(&sdp->sd_ail_lock); +} + +/** + * gfs_inval_buf - Invalidate all buffers associated with a glock + * @gl: the glock + * + */ + +void +gfs_inval_buf(struct gfs_glock *gl) +{ + struct inode *aspace = gl->gl_aspace; + struct address_space *mapping = gl->gl_aspace->i_mapping; + + ail_empty_gl(gl); + + atomic_inc(&aspace->i_writecount); + truncate_inode_pages(mapping, 0); + atomic_dec(&aspace->i_writecount); + + gfs_assert_withdraw(gl->gl_sbd, !mapping->nrpages); +} + +/** + * gfs_sync_buf - Sync all buffers associated with a glock + * @gl: The glock + * @flags: DIO_START | DIO_WAIT | DIO_CHECK + * + */ + +void +gfs_sync_buf(struct gfs_glock *gl, int flags) +{ + struct address_space *mapping = gl->gl_aspace->i_mapping; + int error = 0; + + if (flags & DIO_START) + error = filemap_fdatawrite(mapping); + if (!error && (flags & DIO_WAIT)) + error = filemap_fdatawait(mapping); + if (!error && (flags & (DIO_INVISIBLE | DIO_CHECK)) == DIO_CHECK) + ail_empty_gl(gl); + + if (error) + gfs_io_error(gl->gl_sbd); +} + +/** + * getbuf - Get a buffer with a given address space + * @sdp: the filesystem + * @aspace: the address space + * @blkno: the block number (filesystem scope) + * @create: TRUE if the buffer should be created + * + * Returns: the buffer + */ + +static struct buffer_head * +getbuf(struct gfs_sbd *sdp, struct inode *aspace, uint64_t blkno, int create) +{ + struct page *page; + struct buffer_head *bh; + unsigned int shift; + unsigned long index; + unsigned int bufnum; + + shift = PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift; + index = blkno >> shift; /* convert block to page */ + bufnum = blkno - (index << shift); /* block buf index within page */ + + if (create) { + RETRY_MALLOC(page = grab_cache_page(aspace->i_mapping, index), page); + } else { + page = find_lock_page(aspace->i_mapping, index); + if (!page) + return NULL; + } + + if (!page_has_buffers(page)) + create_empty_buffers(page, sdp->sd_sb.sb_bsize, 0); + + /* Locate header for our buffer within our page */ + for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page) + /* Do nothing */; + get_bh(bh); + + if (!buffer_mapped(bh)) + map_bh(bh, sdp->sd_vfs, blkno); + else if (gfs_assert_warn(sdp, bh->b_bdev == sdp->sd_vfs->s_bdev && + bh->b_blocknr == blkno)) + map_bh(bh, sdp->sd_vfs, blkno); + + unlock_page(page); + page_cache_release(page); + + return bh; +} + +/** + * gfs_dgetblk - Get a block + * @gl: The glock associated with this block + * @blkno: The block number + * + * Returns: The buffer + */ + +struct buffer_head * +gfs_dgetblk(struct gfs_glock *gl, uint64_t blkno) +{ + return getbuf(gl->gl_sbd, gl->gl_aspace, blkno, CREATE); +} + +/** + * gfs_dread - Read a block from disk + * @gl: The glock covering the block + * @blkno: The block number + * @flags: flags to gfs_dreread() + * @bhp: the place where the buffer is returned (NULL on failure) + * + * Returns: errno + */ + +int +gfs_dread(struct gfs_glock *gl, uint64_t blkno, + int flags, struct buffer_head **bhp) +{ + int error; + + *bhp = gfs_dgetblk(gl, blkno); + error = gfs_dreread(gl->gl_sbd, *bhp, flags); + if (error) + brelse(*bhp); + + return error; +} + +/** + * gfs_prep_new_buffer - Mark a new buffer we just gfs_dgetblk()ed uptodate + * @bh: the buffer + * + */ + +void +gfs_prep_new_buffer(struct buffer_head *bh) +{ + wait_on_buffer(bh); + clear_buffer_dirty(bh); + set_buffer_uptodate(bh); +} + +/** + * gfs_dreread - Reread a block from disk + * @sdp: the filesystem + * @bh: The block to read + * @flags: Flags that control the read + * + * Returns: errno + */ + +int +gfs_dreread(struct gfs_sbd *sdp, struct buffer_head *bh, int flags) +{ + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + + /* Fill in meta-header if we have a cached copy, else read from disk */ + if (flags & DIO_NEW) { + if (gfs_mhc_fish(sdp, bh)) + return 0; + clear_buffer_uptodate(bh); + } + + if (flags & DIO_FORCE) + clear_buffer_uptodate(bh); + + if ((flags & DIO_START) && !buffer_uptodate(bh)) + ll_rw_block(READ, 1, &bh); + + if (flags & DIO_WAIT) { + wait_on_buffer(bh); + + if (!buffer_uptodate(bh)) { + gfs_io_error_bh(sdp, bh); + return -EIO; + } + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + } + + return 0; +} + +/** + * gfs_dwrite - Write a buffer to disk (and/or wait for write to complete) + * @sdp: the filesystem + * @bh: The buffer to write + * @flags: DIO_XXX The type of write/wait operation to do + * + * Returns: errno + */ + +int +gfs_dwrite(struct gfs_sbd *sdp, struct buffer_head *bh, int flags) +{ + if (gfs_assert_warn(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags))) + return -EIO; + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + + if (flags & DIO_CLEAN) { + lock_buffer(bh); + clear_buffer_dirty(bh); + unlock_buffer(bh); + } + + if (flags & DIO_DIRTY) { + if (gfs_assert_warn(sdp, buffer_uptodate(bh))) + return -EIO; + mark_buffer_dirty(bh); + } + + if ((flags & DIO_START) && buffer_dirty(bh)) { + wait_on_buffer(bh); + ll_rw_block(WRITE, 1, &bh); + } + + if (flags & DIO_WAIT) { + wait_on_buffer(bh); + + if (!buffer_uptodate(bh) || buffer_dirty(bh)) { + gfs_io_error_bh(sdp, bh); + return -EIO; + } + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + } + + return 0; +} + +/** + * gfs_attach_bufdata - attach a struct gfs_bufdata structure to a buffer + * @bh: The buffer to be attached to + * @gl: the glock the buffer belongs to + * + */ + +void +gfs_attach_bufdata(struct buffer_head *bh, struct gfs_glock *gl) +{ + struct gfs_bufdata *bd; + + lock_page(bh->b_page); + + /* If there's one attached already, we're done */ + if (get_v2bd(bh)) { + unlock_page(bh->b_page); + return; + } + + RETRY_MALLOC(bd = kmem_cache_alloc(gfs_bufdata_cachep, GFP_KERNEL), bd); + atomic_inc(&gl->gl_sbd->sd_bufdata_count); + + memset(bd, 0, sizeof(struct gfs_bufdata)); + + bd->bd_bh = bh; + bd->bd_gl = gl; + + INIT_LE(&bd->bd_new_le, &gfs_buf_lops); + INIT_LE(&bd->bd_incore_le, &gfs_buf_lops); + + init_MUTEX(&bd->bd_lock); + + INIT_LIST_HEAD(&bd->bd_ail_tr_list); + + set_v2bd(bh, bd); + + unlock_page(bh->b_page); +} + +/** + * gfs_is_pinned - Figure out if a buffer is pinned or not + * @sdp: the filesystem the buffer belongs to + * @bh: The buffer to be pinned + * + * Returns: TRUE if the buffer is pinned, FALSE otherwise + */ + +int +gfs_is_pinned(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + int ret = FALSE; + + if (bd) { + gfs_lock_buffer(bh); + if (bd->bd_pinned) + ret = TRUE; + gfs_unlock_buffer(bh); + } + + return ret; +} + +/** + * gfs_dpin - Pin a metadata buffer in memory + * @sdp: the filesystem the buffer belongs to + * @bh: The buffer to be pinned + * + * "Pinning" means keeping buffer from being written to its in-place location. + * A buffer should be pinned from the time it is added to a new transaction, + * until after it has been written to the log. + * If an earlier change to this buffer is still pinned, waiting to be written + * to on-disk log, we need to keep a "frozen" copy of the old data while this + * transaction is modifying the real data. We keep the frozen copy until + * this transaction's incore_commit(), i.e. until the transaction has + * finished modifying the real data, at which point we can use the real + * buffer for logging, even if the frozen copy didn't get written to the log. + * + */ + +void +gfs_dpin(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + char *data; + + gfs_assert_withdraw(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags)); + + gfs_lock_buffer(bh); + + gfs_assert_warn(sdp, !bd->bd_frozen); + + if (!bd->bd_pinned++) { + wait_on_buffer(bh); + + /* If this buffer is in the AIL and it has already been written + to in-place disk block, remove it from the AIL. */ + + spin_lock(&sdp->sd_ail_lock); + if (!list_empty(&bd->bd_ail_tr_list) && !buffer_busy(bh)) { + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + brelse(bh); + } + spin_unlock(&sdp->sd_ail_lock); + + clear_buffer_dirty(bh); + wait_on_buffer(bh); + + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + } else { + gfs_unlock_buffer(bh); + + gfs_assert_withdraw(sdp, buffer_uptodate(bh)); + + data = gmalloc(sdp->sd_sb.sb_bsize); + + gfs_lock_buffer(bh); + + /* Create frozen copy, if needed. */ + if (bd->bd_pinned > 1) { + memcpy(data, bh->b_data, sdp->sd_sb.sb_bsize); + bd->bd_frozen = data; + } else + kfree(data); + } + + gfs_unlock_buffer(bh); + + get_bh(bh); +} + +/** + * gfs_dunpin - Unpin a buffer + * @sdp: the filesystem the buffer belongs to + * @bh: The buffer to unpin + * @tr: The transaction in the AIL that contains this buffer + * If NULL, don't attach buffer to any AIL list + * (i.e. when dropping a pin reference when merging a new transaction + * with an already existing incore transaction) + * + * Called for (meta) buffers, after they've been logged to on-disk journal. + * Make a (meta) buffer writeable to in-place location on-disk, if recursive + * pin count is 1 (i.e. no other, later transaction is modifying this buffer). + * Add buffer to AIL lists of 1) the latest transaction that's modified and + * logged (on-disk) the buffer, and of 2) the glock that protects the buffer. + * A single buffer might have been modified by more than one transaction + * since the buffer's previous write to disk (in-place location). We keep + * the buffer on only one transaction's AIL list, i.e. that of the latest + * transaction that's completed logging this buffer (no need to write it to + * in-place block multiple times for multiple transactions, only once with + * the most up-to-date data). + * A single buffer will be protected by one and only one glock. If buffer is + * already on a (previous) transaction's AIL, we know that we're already + * on buffer's glock's AIL. + * + */ + +void +gfs_dunpin(struct gfs_sbd *sdp, struct buffer_head *bh, struct gfs_trans *tr) +{ + struct gfs_bufdata *bd = get_v2bd(bh); + + gfs_assert_withdraw(sdp, buffer_uptodate(bh)); + + gfs_lock_buffer(bh); + + if (gfs_assert_warn(sdp, bd->bd_pinned)) { + gfs_unlock_buffer(bh); + return; + } + + /* No other (later) transaction is modifying buffer; ready to write */ + if (bd->bd_pinned == 1) + mark_buffer_dirty(bh); + + bd->bd_pinned--; + + gfs_unlock_buffer(bh); + + if (tr) { + spin_lock(&sdp->sd_ail_lock); + + if (list_empty(&bd->bd_ail_tr_list)) { + /* Buffer not attached to any earlier transaction. Add + it to glock's AIL, and this trans' AIL (below). */ + list_add(&bd->bd_ail_gl_list, &bd->bd_gl->gl_ail_bufs); + } else { + /* Was part of earlier transaction. + Move from that trans' AIL to this newer one's AIL. + Buf is already on glock's AIL. */ + list_del_init(&bd->bd_ail_tr_list); + brelse(bh); + } + list_add(&bd->bd_ail_tr_list, &tr->tr_ail_bufs); + + spin_unlock(&sdp->sd_ail_lock); + } else + brelse(bh); +} + +/** + * logbh_end_io - Called by OS at the end of a logbh ("fake" bh) write to log + * @bh: the buffer + * @uptodate: whether or not the write succeeded + * + * Interrupt context, no ENTER/RETURN + * + */ + +static void +logbh_end_io(struct buffer_head *bh, int uptodate) +{ + if (uptodate) + set_buffer_uptodate(bh); + else + clear_buffer_uptodate(bh); + unlock_buffer(bh); +} + +/** + * gfs_logbh_init - Initialize a fake buffer head + * @sdp: the filesystem + * @bh: the buffer to initialize + * @blkno: the block address of the buffer + * @data: the data to be written + * + */ + +void +gfs_logbh_init(struct gfs_sbd *sdp, struct buffer_head *bh, + uint64_t blkno, char *data) +{ + memset(bh, 0, sizeof(struct buffer_head)); + bh->b_state = (1 << BH_Mapped) | (1 << BH_Uptodate) | (1 << BH_Lock); + atomic_set(&bh->b_count, 1); + set_bh_page(bh, virt_to_page(data), ((unsigned long)data) & (PAGE_SIZE - 1)); + bh->b_blocknr = blkno; + bh->b_size = sdp->sd_sb.sb_bsize; + bh->b_bdev = sdp->sd_vfs->s_bdev; + init_buffer(bh, logbh_end_io, NULL); + INIT_LIST_HEAD(&bh->b_assoc_buffers); +} + +/** + * gfs_logbh_uninit - Clean up a fake buffer head + * @sdp: the filesystem + * @bh: the buffer to clean + * + */ + +void +gfs_logbh_uninit(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + gfs_assert_warn(sdp, test_bit(SDF_SHUTDOWN, &sdp->sd_flags) || + !buffer_busy(bh)); + gfs_assert_warn(sdp, atomic_read(&bh->b_count) == 1); +} + +/** + * gfs_logbh_start - Start writing a fake buffer head + * @sdp: the filesystem + * @bh: the buffer to write + * + * This starts a block write to our journal. + */ + +void +gfs_logbh_start(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + submit_bh(WRITE, bh); +} + +/** + * gfs_logbh_wait - Wait for the write of a fake buffer head to complete + * @sdp: the filesystem + * @bh: the buffer to write + * + * This waits for a block write to our journal to complete. + * + * Returns: errno + */ + +int +gfs_logbh_wait(struct gfs_sbd *sdp, struct buffer_head *bh) +{ + wait_on_buffer(bh); + + if (!buffer_uptodate(bh) || buffer_dirty(bh)) { + gfs_io_error_bh(sdp, bh); + return -EIO; + } + if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) + return -EIO; + + return 0; +} + +/** + * gfs_replay_buf - write a log buffer to its inplace location + * @gl: the journal's glock + * @bh: the buffer + * + * Returns: errno + */ + +int +gfs_replay_buf(struct gfs_glock *gl, struct buffer_head *bh) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_bufdata *bd; + + bd = get_v2bd(bh); + if (!bd) { + gfs_attach_bufdata(bh, gl); + bd = get_v2bd(bh); + } + + mark_buffer_dirty(bh); + + if (list_empty(&bd->bd_ail_tr_list)) { + get_bh(bh); + list_add(&bd->bd_ail_tr_list, &sdp->sd_recovery_bufs); + } + + return 0; +} + +/** + * gfs_replay_check - Check up on journal replay + * @sdp: the filesystem + * + */ + +void +gfs_replay_check(struct gfs_sbd *sdp) +{ + struct buffer_head *bh; + struct gfs_bufdata *bd; + + while (!list_empty(&sdp->sd_recovery_bufs)) { + bd = list_entry(sdp->sd_recovery_bufs.prev, + struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (buffer_busy(bh)) { + list_move(&bd->bd_ail_tr_list, + &sdp->sd_recovery_bufs); + break; + } else { + list_del_init(&bd->bd_ail_tr_list); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + brelse(bh); + } + } +} + +/** + * gfs_replay_wait - Wait for all replayed buffers to hit the disk + * @sdp: the filesystem + * + */ + +void +gfs_replay_wait(struct gfs_sbd *sdp) +{ + struct list_head *head, *tmp, *prev; + struct buffer_head *bh; + struct gfs_bufdata *bd; + + for (head = &sdp->sd_recovery_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + bd = list_entry(tmp, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + if (!buffer_busy(bh)) { + list_del_init(&bd->bd_ail_tr_list); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + brelse(bh); + continue; + } + + if (buffer_dirty(bh)) { + wait_on_buffer(bh); + ll_rw_block(WRITE, 1, &bh); + } + } + + while (!list_empty(head)) { + bd = list_entry(head->prev, struct gfs_bufdata, bd_ail_tr_list); + bh = bd->bd_bh; + + wait_on_buffer(bh); + + gfs_assert_withdraw(sdp, !buffer_busy(bh)); + + list_del_init(&bd->bd_ail_tr_list); + if (!buffer_uptodate(bh)) + gfs_io_error_bh(sdp, bh); + brelse(bh); + } +} + +/** + * gfs_wipe_buffers - make inode's buffers so they aren't dirty/AILed anymore + * @ip: the inode who owns the buffers + * @rgd: the resource group + * @bstart: the first buffer in the run + * @blen: the number of buffers in the run + * + * Called when de-allocating a contiguous run of meta blocks within an rgrp. + * Make sure all buffers for de-alloc'd blocks are removed from the AIL, if + * they can be. Dirty or pinned blocks are left alone. Add relevant + * meta-headers to meta-header cache, so we don't need to read disk + * if we re-allocate blocks. + */ + +void +gfs_wipe_buffers(struct gfs_inode *ip, struct gfs_rgrpd *rgd, + uint64_t bstart, uint32_t blen) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct inode *aspace = ip->i_gl->gl_aspace; + struct buffer_head *bh; + struct gfs_bufdata *bd; + int busy; + int add = FALSE; + + while (blen) { + bh = getbuf(sdp, aspace, bstart, NO_CREATE); + if (bh) { + + bd = get_v2bd(bh); + + if (buffer_uptodate(bh)) { + if (bd) { + gfs_lock_buffer(bh); + gfs_mhc_add(rgd, &bh, 1); + busy = bd->bd_pinned || buffer_busy(bh); + gfs_unlock_buffer(bh); + + if (busy) + add = TRUE; + else { + spin_lock(&sdp->sd_ail_lock); + if (!list_empty(&bd->bd_ail_tr_list)) { + list_del_init(&bd->bd_ail_tr_list); + list_del(&bd->bd_ail_gl_list); + brelse(bh); + } + spin_unlock(&sdp->sd_ail_lock); + } + } else { + gfs_assert_withdraw(sdp, !buffer_dirty(bh)); + wait_on_buffer(bh); + gfs_assert_withdraw(sdp, !buffer_busy(bh)); + gfs_mhc_add(rgd, &bh, 1); + } + } else { + gfs_assert_withdraw(sdp, !bd || !bd->bd_pinned); + gfs_assert_withdraw(sdp, !buffer_dirty(bh)); + wait_on_buffer(bh); + gfs_assert_withdraw(sdp, !buffer_busy(bh)); + } + + brelse(bh); + } + + bstart++; + blen--; + } + + if (add) + gfs_depend_add(rgd, ip->i_num.no_formal_ino); +} + +/** + * gfs_sync_meta - sync all the buffers in a filesystem + * @sdp: the filesystem + * + * Flush metadata blocks to on-disk journal, then + * Flush metadata blocks (now in AIL) to on-disk in-place locations + * Periodically keep checking until done (AIL empty) + */ + +void +gfs_sync_meta(struct gfs_sbd *sdp) +{ + gfs_log_flush(sdp); + for (;;) { + gfs_ail_start(sdp, DIO_ALL); + if (gfs_ail_empty(sdp)) + break; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ / 10); + } +} + +/** + * gfs_flush_meta_cache - get rid of any references on buffers for this inode + * @ip: The GFS inode + * + * This releases buffers that are in the most-recently-used array of + * blocks used for indirect block addressing for this inode. + * Don't confuse this with the meta-HEADER cache (mhc)! + */ + +void +gfs_flush_meta_cache(struct gfs_inode *ip) +{ + struct buffer_head **bh_slot; + unsigned int x; + + spin_lock(&ip->i_spin); + + for (x = 0; x < GFS_MAX_META_HEIGHT; x++) { + bh_slot = &ip->i_cache[x]; + if (*bh_slot) { + brelse(*bh_slot); + *bh_slot = NULL; + } + } + + spin_unlock(&ip->i_spin); +} + +/** + * gfs_get_meta_buffer - Get a metadata buffer + * @ip: The GFS inode + * @height: The level of this buf in the metadata (indir addr) tree (if any) + * @num: The block number (device relative) of the buffer + * @new: Non-zero if we may create a new buffer + * @bhp: the buffer is returned here + * + * Returns: errno + */ + +int +gfs_get_meta_buffer(struct gfs_inode *ip, int height, uint64_t num, int new, + struct buffer_head **bhp) +{ + struct buffer_head *bh, **bh_slot = &ip->i_cache[height]; + int flags = ((new) ? DIO_NEW : 0) | DIO_START | DIO_WAIT; + int error; + + /* Try to use the gfs_inode's MRU metadata tree cache */ + spin_lock(&ip->i_spin); + bh = *bh_slot; + if (bh) { + if (bh->b_blocknr == num) + get_bh(bh); + else + bh = NULL; + } + spin_unlock(&ip->i_spin); + + if (bh) { + error = gfs_dreread(ip->i_sbd, bh, flags); + if (error) { + brelse(bh); + return error; + } + } else { + error = gfs_dread(ip->i_gl, num, flags, &bh); + if (error) + return error; + + spin_lock(&ip->i_spin); + if (*bh_slot != bh) { + if (*bh_slot) + brelse(*bh_slot); + *bh_slot = bh; + get_bh(bh); + } + spin_unlock(&ip->i_spin); + } + + if (new) { + if (gfs_assert_warn(ip->i_sbd, height)) { + brelse(bh); + return -EIO; + } + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_IN, GFS_FORMAT_IN); + gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); + } else if (gfs_metatype_check(ip->i_sbd, bh, + (height) ? GFS_METATYPE_IN : GFS_METATYPE_DI)) { + brelse(bh); + return -EIO; + } + + *bhp = bh; + + return 0; +} + +/** + * gfs_get_data_buffer - Get a data buffer + * @ip: The GFS inode + * @num: The block number (device relative) of the data block + * @new: Non-zero if this is a new allocation + * @bhp: the buffer is returned here + * + * Returns: errno + */ + +int +gfs_get_data_buffer(struct gfs_inode *ip, uint64_t block, int new, + struct buffer_head **bhp) +{ + struct buffer_head *bh; + int error = 0; + + if (block == ip->i_num.no_addr) { + if (gfs_assert_warn(ip->i_sbd, !new)) + return -EIO; + error = gfs_dread(ip->i_gl, block, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_DI)) { + brelse(bh); + return -EIO; + } + } else if (gfs_is_jdata(ip)) { + if (new) { + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + return error; + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_JD, GFS_FORMAT_JD); + gfs_buffer_clear_tail(bh, sizeof(struct gfs_meta_header)); + } else { + error = gfs_dread(ip->i_gl, block, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_JD)) { + brelse(bh); + return -EIO; + } + } + } else { + if (new) { + bh = gfs_dgetblk(ip->i_gl, block); + gfs_prep_new_buffer(bh); + } else { + error = gfs_dread(ip->i_gl, block, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + } + } + + *bhp = bh; + + return 0; +} + +/** + * gfs_start_ra - start readahead on an extent of a file + * @gl: the glock the blocks belong to + * @dblock: the starting disk block + * @extlen: the number of blocks in the extent + * + */ + +void +gfs_start_ra(struct gfs_glock *gl, uint64_t dblock, uint32_t extlen) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct inode *aspace = gl->gl_aspace; + struct buffer_head *first_bh, *bh; + uint32_t max_ra = gfs_tune_get(sdp, gt_max_readahead) >> sdp->sd_sb.sb_bsize_shift; + int error; + + if (!extlen) + return; + if (!max_ra) + return; + if (extlen > max_ra) + extlen = max_ra; + + first_bh = getbuf(sdp, aspace, dblock, CREATE); + + if (buffer_uptodate(first_bh)) + goto out; + if (!buffer_locked(first_bh)) { + error = gfs_dreread(sdp, first_bh, DIO_START); + if (error) + goto out; + } + + dblock++; + extlen--; + + while (extlen) { + bh = getbuf(sdp, aspace, dblock, CREATE); + + if (!buffer_uptodate(bh) && !buffer_locked(bh)) { + error = gfs_dreread(sdp, bh, DIO_START); + brelse(bh); + if (error) + goto out; + } else + brelse(bh); + + dblock++; + extlen--; + + if (buffer_uptodate(first_bh)) + break; + } + + out: + brelse(first_bh); +} --- linux-2.6.28.orig/ubuntu/gfs/mount.c +++ linux-2.6.28/ubuntu/gfs/mount.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "mount.h" +#include "proc.h" +#include "sys.h" + +/** + * gfs_make_args - Parse mount arguments + * @data: + * @args: + * + * Return: errno + */ + +int +gfs_make_args(char *data_arg, struct gfs_args *args, int remount) +{ + char *data = data_arg; + char *options, *x, *y; + int error = 0; + + /* If someone preloaded options, use those instead */ + + spin_lock(&gfs_proc_margs_lock); + if (!remount && gfs_proc_margs) { + data = gfs_proc_margs; + gfs_proc_margs = NULL; + } + spin_unlock(&gfs_proc_margs_lock); + + /* Set some defaults */ + + memset(args, 0, sizeof(struct gfs_args)); + args->ar_num_glockd = GFS_GLOCKD_DEFAULT; + + if (!remount) { + /* If someone preloaded options, use those instead */ + spin_lock(&gfs_sys_margs_lock); + if (gfs_sys_margs) { + data = gfs_sys_margs; + gfs_sys_margs = NULL; + } + spin_unlock(&gfs_sys_margs_lock); + + /* Set some defaults */ + args->ar_num_glockd = GFS_GLOCKD_DEFAULT; + } + + /* Split the options into tokens with the "," character and + process them */ + + for (options = data; (x = strsep(&options, ",")); ) { + if (!*x) + continue; + + y = strchr(x, '='); + if (y) + *y++ = 0; + + if (!strcmp(x, "lockproto")) { + if (!y) { + printk("GFS: need argument to lockproto\n"); + error = -EINVAL; + break; + } + strncpy(args->ar_lockproto, y, GFS_LOCKNAME_LEN); + args->ar_lockproto[GFS_LOCKNAME_LEN - 1] = 0; + } + + else if (!strcmp(x, "locktable")) { + if (!y) { + printk("GFS: need argument to locktable\n"); + error = -EINVAL; + break; + } + strncpy(args->ar_locktable, y, GFS_LOCKNAME_LEN); + args->ar_locktable[GFS_LOCKNAME_LEN - 1] = 0; + } + + else if (!strcmp(x, "hostdata")) { + if (!y) { + printk("GFS: need argument to hostdata\n"); + error = -EINVAL; + break; + } + strncpy(args->ar_hostdata, y, GFS_LOCKNAME_LEN); + args->ar_hostdata[GFS_LOCKNAME_LEN - 1] = 0; + } + + else if (!strcmp(x, "spectator")) + args->ar_spectator = TRUE; + + else if (!strcmp(x, "ignore_local_fs")) + args->ar_ignore_local_fs = TRUE; + + else if (!strcmp(x, "localflocks")) + args->ar_localflocks = TRUE; + + else if (!strcmp(x, "localcaching")) + args->ar_localcaching = TRUE; + + else if (!strcmp(x, "oopses_ok")) + args->ar_oopses_ok = TRUE; + + else if (!strcmp(x, "debug")) { + args->ar_oopses_ok = TRUE; + args->ar_debug = TRUE; + + } else if (!strcmp(x, "upgrade")) + args->ar_upgrade = TRUE; + + else if (!strcmp(x, "num_glockd")) { + if (!y) { + printk("GFS: need argument to num_glockd\n"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &args->ar_num_glockd); + if (!args->ar_num_glockd || args->ar_num_glockd > GFS_GLOCKD_MAX) { + printk("GFS: 0 < num_glockd <= %u (not %u)\n", + GFS_GLOCKD_MAX, args->ar_num_glockd); + error = -EINVAL; + break; + } + } + + else if (!strcmp(x, "acl")) + args->ar_posix_acls = TRUE; + + else if (!strcmp(x, "noacl")) + args->ar_posix_acls = FALSE; + + else if (!strcmp(x, "suiddir")) + args->ar_suiddir = TRUE; + + else if (!strcmp(x, "noquota")) + args->ar_noquota = TRUE; + + /* Unknown */ + + else { + printk("GFS: unknown option: %s\n", x); + error = -EINVAL; + break; + } + } + + if (error) + printk("GFS: invalid mount option(s)\n"); + + if (data != data_arg) + kfree(data); + + return error; +} + --- linux-2.6.28.orig/ubuntu/gfs/ops_export.h +++ linux-2.6.28/ubuntu/gfs/ops_export.h @@ -0,0 +1,6 @@ +#ifndef __OPS_EXPORT_DOT_H__ +#define __OPS_EXPORT_DOT_H__ + +extern const struct export_operations gfs_export_ops; + +#endif /* __OPS_EXPORT_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/eaops.h +++ linux-2.6.28/ubuntu/gfs/eaops.h @@ -0,0 +1,21 @@ +#ifndef __EAOPS_DOT_H__ +#define __EAOPS_DOT_H__ + +struct gfs_ea_request; + +struct gfs_eattr_operations { + int (*eo_get) (struct gfs_inode *ip, struct gfs_ea_request *er); + int (*eo_set) (struct gfs_inode *ip, struct gfs_ea_request *er); + int (*eo_remove) (struct gfs_inode *ip, struct gfs_ea_request *er); + char *eo_name; +}; + +unsigned int gfs_ea_name2type(const char *name, char **truncated_name); + +extern struct gfs_eattr_operations gfs_user_eaops; +extern struct gfs_eattr_operations gfs_system_eaops; + +extern struct gfs_eattr_operations *gfs_ea_ops[]; + +#endif /* __EAOPS_DOT_H__ */ + --- linux-2.6.28.orig/ubuntu/gfs/page.h +++ linux-2.6.28/ubuntu/gfs/page.h @@ -0,0 +1,13 @@ +#ifndef __PAGE_DOT_H__ +#define __PAGE_DOT_H__ + +void gfs_inval_pte(struct gfs_glock *gl); +void gfs_inval_page(struct gfs_glock *gl); +void gfs_sync_page_i(struct inode *inode, int flags); +void gfs_sync_page(struct gfs_glock *gl, int flags); + +int gfs_unstuffer_page(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private); +int gfs_truncator_page(struct gfs_inode *ip, uint64_t size); + +#endif /* __PAGE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ioctl.h +++ linux-2.6.28/ubuntu/gfs/ioctl.h @@ -0,0 +1,9 @@ +#ifndef __IOCTL_DOT_H__ +#define __IOCTL_DOT_H__ + +int gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi, + const char *arg0, int from_user); +int gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg); +int gfs_ioctl_i(struct gfs_inode *ip, void *arg); + +#endif /* __IOCTL_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lops.c +++ linux-2.6.28/ubuntu/gfs/lops.c @@ -0,0 +1,1648 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "log.h" +#include "lops.h" +#include "quota.h" +#include "recovery.h" +#include "trans.h" +#include "unlinked.h" + +/** + * generic_le_add - generic routine to add a log element to a transaction + * @sdp: the filesystem + * @le: the log entry + * + */ + +static void +generic_le_add(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_trans *tr; + + /* Make sure it's not attached to a transaction already */ + gfs_assert(sdp, le->le_ops && + !le->le_trans && + list_empty(&le->le_list),); + + /* Attach it to the (one) transaction being built by this process */ + tr = get_transaction; + gfs_assert(sdp, tr,); + + le->le_trans = tr; + list_add(&le->le_list, &tr->tr_elements); +} + +/** + * glock_trans_end - drop a glock reference + * @sdp: the filesystem + * @le: the log element + * + * Called before incore-committing a transaction + * Release reference that was taken in gfs_trans_add_gl() + */ + +static void +glock_trans_end(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); + + gfs_assert(sdp, gfs_glock_is_locked_by_me(gl) && + gfs_glock_is_held_excl(gl),); + gfs_glock_put(gl); +} + +/** + * glock_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +glock_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) +{ + struct gfs_glock *gl; + + switch (where) { + case TRANS_IS_NEW: + gl = container_of(le, struct gfs_glock, gl_new_le); + break; + case TRANS_IS_INCORE: + gl = container_of(le, struct gfs_glock, gl_incore_le); + break; + default: + gfs_assert_warn(sdp, FALSE); + return; + } + + printk(" Glock: (%u, %"PRIu64")\n", + gl->gl_name.ln_type, + gl->gl_name.ln_number); +} + +/** + * glock_overlap_trans - Find any incore transactions that might overlap with + * (i.e. be combinable with the transaction containing) this LE + * @sdp: the filesystem + * @le: the log element + * + * Transactions that share a given glock are combinable. + * + * For a glock, the scope of the "search" is just the (max) one unique incore + * committed transaction to which the glock may be attached via its + * gl->gl_incore_le embedded log element. This trans may have previously + * been combined with other transactions, though (i.e. previous + * incore committed transactions that shared the same glock). + * + * Called as a beginning part of the incore commit of a transaction. + */ + +static struct gfs_trans * +glock_overlap_trans(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); + + return gl->gl_incore_le.le_trans; +} + +/** + * glock_incore_commit - commit this LE to the incore log + * @sdp: the filesystem + * @tr: the being-incore-committed transaction this LE is to be a part of + * @le: the log element (should be a gl->gl_new_le), which is attached + * to a "new" (just-ended) transaction. + * + * Attach glock's gl_incore_le to the being-incore-committed trans' LE list. + * Remove glock's gl_new_le from the just-ended new trans' LE list. + * If the just-ended new trans (le->le_trans) was combined (in incore_commit()) + * with a pre-existing incore trans (tr), this function effectively moves + * the LE from the new to the combined incore trans. + * If there was no combining, then the new trans itself is being committed + * (le->le_trans == tr); this function simply replaces the gl_new_le with a + * gl_incore_le on the trans' LE list. + * + * Make sure that this glock's gl_incore_le is attached to one and only one + * incore-committed transaction's (this one's) tr_elements list. + * One transaction (instead of a list of transactions) is sufficient, + * because incore_commit() combines multiple transactions that share a glock + * into one trans. + * Since transactions can contain multiple glocks, there are multiple + * possibilities for shared glocks, therefore multiple potential "bridges" + * for combining transactions. + */ + +static void +glock_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_glock *gl = container_of(le, struct gfs_glock, gl_new_le); + + /* Transactions were combined, based on this glock */ + if (gl->gl_incore_le.le_trans) + gfs_assert(sdp, gl->gl_incore_le.le_trans == tr,); + else { + /* Attach gl->gl_incore_le to being-committed trans */ + gl->gl_incore_le.le_trans = tr; + list_add(&gl->gl_incore_le.le_list, &tr->tr_elements); + + /* If transactions were combined (via another shared glock), + the combined trans is getting a new glock log element */ + if (tr != le->le_trans) + tr->tr_num_gl++; + } + + /* Remove gl->gl_new_le from "new" trans */ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * glock_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + * Glocks don't really get added to AIL (there's nothing to write to disk), + * they just get removed from the transaction at this time. + */ + +static void +glock_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * glock_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +glock_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_gl += new_tr->tr_num_gl; +} + +/** + * buf_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +buf_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) +{ + struct gfs_bufdata *bd; + + switch (where) { + case TRANS_IS_NEW: + bd = container_of(le, struct gfs_bufdata, bd_new_le); + break; + case TRANS_IS_INCORE: + bd = container_of(le, struct gfs_bufdata, bd_incore_le); + break; + default: + gfs_assert_warn(sdp, FALSE); + return; + } + + printk(" Buffer: %"PRIu64"\n", (uint64_t)bd->bd_bh->b_blocknr); +} + +/** + * buf_incore_commit - commit this buffer LE to the incore log + * @sdp: the filesystem + * @tr: the incore transaction this LE is a part of + * @le: the log element for the "new" (just now complete) trans + * + * Invoked from incore_commit(). + * Move this buffer from "new" stage to "incore committed" stage of the + * transaction pipeline. + * If this buffer was already attached to a pre-existing incore trans, GFS is + * combining the new and incore transactions; decrement buffer's recursive + * pin count that was incremented when it was added to the new transaction, + * and remove the reference to the "new" (being swallowed) trans. + * Else, move this buffer's attach point from "new" to "incore" embedded LE + * (same transaction, just new status) and add this buf to (incore) trans' + * LE list. + */ + +static void +buf_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_bufdata *bd = container_of(le, struct gfs_bufdata, bd_new_le); + + /* We've completed our (atomic) changes to this buffer for this trans. + We no longer need the frozen copy. If frozen copy was not written + to on-disk log already, there's no longer a need to; we can now + write the "real" buffer (with more up-to-date content) instead. */ + if (bd->bd_frozen) { + kfree(bd->bd_frozen); + bd->bd_frozen = NULL; + } + + /* New trans being combined with pre-existing incore trans? */ + if (bd->bd_incore_le.le_trans) { + gfs_assert(sdp, bd->bd_incore_le.le_trans == tr,); + gfs_dunpin(sdp, bd->bd_bh, NULL); + } else { + bd->bd_incore_le.le_trans = tr; + list_add(&bd->bd_incore_le.le_list, &tr->tr_elements); + if (tr != le->le_trans) + tr->tr_num_buf++; + + sdp->sd_log_buffers++; + } + + /* Reset buffer's bd_new_le */ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * buf_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +buf_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_bufdata *bd = container_of(le, + struct gfs_bufdata, + bd_incore_le); + + gfs_dunpin(sdp, bd->bd_bh, le->le_trans); + + le->le_trans = NULL; + list_del_init(&le->le_list); + + gfs_assert(sdp, sdp->sd_log_buffers,); + sdp->sd_log_buffers--; +} + +/** + * buf_trans_size - compute how much space the LE class takes up in a transaction + * @sdp: the filesystem + * @tr: the transaction + * @mblks: the number of regular metadata blocks + * @eblks: the number of extra blocks + * @blocks: the number of log blocks + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +buf_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int cblks; + + if (tr->tr_num_buf) { + cblks = gfs_struct2blk(sdp, tr->tr_num_buf, + sizeof(struct gfs_block_tag)); + + if (mblks) + *mblks += tr->tr_num_buf; + if (blocks) + *blocks += tr->tr_num_buf + cblks; + if (bmem) + *bmem += cblks; + } +} + +/** + * buf_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +buf_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_buf += new_tr->tr_num_buf; +} + +/** + * increment_generation - increment the generation number in metadata buffer + * @sdp: the filesystem + * @bd: the struct gfs_bufdata structure associated with the buffer + * + * Increment the generation # of the most recent buffer contents, as well as + * that of frozen buffer, if any. If there is a frozen buffer, only *it* + * will be going to the log now ... in this case, the current buffer will + * have its gen # incremented again later, when it gets written to log. + * Gen # is used by journal recovery (replay_block()) to determine whether + * to overwrite an inplace block with the logged block contents. + */ + +static void +increment_generation(struct gfs_sbd *sdp, struct gfs_bufdata *bd) +{ + struct gfs_meta_header *mh, *mh2; + uint64_t tmp64; + + mh = (struct gfs_meta_header *)bd->bd_bh->b_data; + + tmp64 = gfs64_to_cpu(mh->mh_generation) + 1; + tmp64 = cpu_to_gfs64(tmp64); + + if (bd->bd_frozen) { + mh2 = (struct gfs_meta_header *)bd->bd_frozen; + gfs_assert(sdp, mh->mh_generation == mh2->mh_generation,); + mh2->mh_generation = tmp64; + } + mh->mh_generation = tmp64; +} + +/** + * buf_build_bhlist - create the buffers that will make up the ondisk part of a transaction + * @sdp: the filesystem + * @tr: the transaction + * + * Create the log (transaction) descriptor block + */ + +static void +buf_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_log_element *le; + struct gfs_bufdata *bd; + struct gfs_log_descriptor desc; + struct gfs_block_tag tag; + struct gfs_log_buf *clb = NULL; + unsigned int num_ctl; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x, bufs; + + if (!tr->tr_num_buf) + return; + + /* set up control buffers for descriptor and tags */ + + num_ctl = gfs_struct2blk(sdp, tr->tr_num_buf, + sizeof(struct gfs_block_tag)); + + for (x = 0; x < num_ctl; x++) { + if (clb) + gfs_log_get_buf(sdp, tr); + else + clb = gfs_log_get_buf(sdp, tr); + } + + /* Init and copy log descriptor into 1st control block */ + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_METADATA; + desc.ld_length = num_ctl + tr->tr_num_buf; + desc.ld_data1 = tr->tr_num_buf; + gfs_desc_out(&desc, clb->lb_bh.b_data); + + x = 1; + bufs = 0; + + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + + /* Skip over non-buffer (e.g. glock, unlinked, etc.) LEs */ + if (le->le_ops != &gfs_buf_lops) + continue; + + bd = container_of(le, struct gfs_bufdata, bd_incore_le); + + gfs_meta_check(sdp, bd->bd_bh); + + gfs_lock_buffer(bd->bd_bh); + + increment_generation(sdp, bd); + + /* Create "fake" buffer head to write block to on-disk log. Use + frozen copy if another transaction is modifying the "real" + buffer contents. Unlock real bh after log write completes, + so Linux can write real contents to inplace block. */ + gfs_log_fake_buf(sdp, tr, + (bd->bd_frozen) ? bd->bd_frozen : bd->bd_bh->b_data, + bd->bd_bh); + + /* find another buffer for tags if we're overflowing this one */ + if (offset + sizeof(struct gfs_block_tag) > sdp->sd_sb.sb_bsize) { + clb = list_entry(clb->lb_list.prev, + struct gfs_log_buf, lb_list); + if (gfs_log_is_header(sdp, clb->lb_bh.b_blocknr)) + clb = list_entry(clb->lb_list.prev, + struct gfs_log_buf, lb_list); + x++; + offset = 0; + } + + /* Write this LE's tag into a control buffer */ + memset(&tag, 0, sizeof(struct gfs_block_tag)); + tag.bt_blkno = bd->bd_bh->b_blocknr; + + gfs_block_tag_out(&tag, clb->lb_bh.b_data + offset); + + offset += sizeof(struct gfs_block_tag); + bufs++; + } + + gfs_assert(sdp, x == num_ctl,); + gfs_assert(sdp, bufs == tr->tr_num_buf,); +} + +/** + * buf_before_scan - called before journal replay + * @sdp: the filesystem + * @jid: the journal ID about to be replayed + * @head: the current head of the log + * @pass: the pass through the journal + * + */ + +static void +buf_before_scan(struct gfs_sbd *sdp, unsigned int jid, + struct gfs_log_header *head, unsigned int pass) +{ + if (pass == GFS_RECPASS_A1) + sdp->sd_recovery_replays = + sdp->sd_recovery_skips = + sdp->sd_recovery_sames = 0; +} + +/** + * replay_block - Replay a single metadata block + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being replayed + * @gl: the journal's glock + * @tag: the block tag describing the inplace location of the block + * @blkno: the location of the log's copy of the block + * + * Returns: errno + * + * Read in-place block from disk + * Read log (journal) block from disk + * Compare generation numbers + * Copy log block to in-place block on-disk if: + * log generation # > in-place generation # + * OR generation #s are ==, but data contained in block is different (corrupt) + */ + +static int +replay_block(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_block_tag *tag, uint64_t blkno) +{ + struct buffer_head *inplace_bh, *log_bh; + struct gfs_meta_header inplace_mh, log_mh; + int replay_block = TRUE; + int error = 0; + + gfs_replay_check(sdp); + + /* Warning: Using a real buffer here instead of a tempbh can be bad + on a OS that won't support multiple simultaneous buffers for the + same block on different glocks. */ + + error = gfs_dread(gl, tag->bt_blkno, + DIO_START | DIO_WAIT, &inplace_bh); + if (error) + return error; + if (gfs_meta_check(sdp, inplace_bh)) { + brelse(inplace_bh); + return -EIO; + } + gfs_meta_header_in(&inplace_mh, inplace_bh->b_data); + + error = gfs_dread(gl, blkno, DIO_START | DIO_WAIT, &log_bh); + if (error) { + brelse(inplace_bh); + return error; + } + if (gfs_meta_check(sdp, log_bh)) { + brelse(inplace_bh); + brelse(log_bh); + return -EIO; + } + gfs_meta_header_in(&log_mh, log_bh->b_data); + + if (log_mh.mh_generation < inplace_mh.mh_generation) { + replay_block = FALSE; + sdp->sd_recovery_skips++; + } else if (log_mh.mh_generation == inplace_mh.mh_generation) { + if (memcmp(log_bh->b_data, + inplace_bh->b_data, + sdp->sd_sb.sb_bsize) == 0) { + replay_block = FALSE; + sdp->sd_recovery_sames++; + } + } + + if (replay_block) { + memcpy(inplace_bh->b_data, + log_bh->b_data, + sdp->sd_sb.sb_bsize); + + error = gfs_replay_buf(gl, inplace_bh); + if (!error) + sdp->sd_recovery_replays++; + } + + brelse(log_bh); + brelse(inplace_bh); + + return error; +} + +/** + * buf_scan_elements - Replay a metadata log descriptor + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being replayed + * @gl: the journal's glock + * @start: the starting block of the descriptor + * @desc: the descriptor structure + * @pass: the pass through the journal + * + * Returns: errno + */ + +static int +buf_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + struct gfs_block_tag tag; + struct buffer_head *bh; + uint64_t cblk = start; + unsigned int num_tags = desc->ld_data1; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x; + int error; + + if (pass != GFS_RECPASS_A1) + return 0; + if (desc->ld_type != GFS_LOG_DESC_METADATA) + return 0; + + x = gfs_struct2blk(sdp, num_tags, sizeof(struct gfs_block_tag)); + while (x--) { + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + return error; + } + + for (;;) { + gfs_assert(sdp, num_tags,); + + error = gfs_dread(gl, cblk, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + /* Do readahead for the inplace blocks in this control block */ + { + unsigned int o2 = offset; + unsigned int nt2 = num_tags; + + while (o2 + sizeof(struct gfs_block_tag) <= + sdp->sd_sb.sb_bsize) { + gfs_block_tag_in(&tag, bh->b_data + o2); + gfs_start_ra(gl, tag.bt_blkno, 1); + if (!--nt2) + break; + o2 += sizeof(struct gfs_block_tag); + } + } + + while (offset + sizeof(struct gfs_block_tag) <= + sdp->sd_sb.sb_bsize) { + gfs_block_tag_in(&tag, bh->b_data + offset); + + error = replay_block(sdp, jdesc, gl, &tag, start); + if (error) + goto out_drelse; + + if (!--num_tags) + goto out_drelse; + + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + goto out_drelse; + + offset += sizeof(struct gfs_block_tag); + } + + brelse(bh); + + error = gfs_increment_blkno(sdp, jdesc, gl, &cblk, TRUE); + if (error) + return error; + + offset = 0; + } + + return 0; + + out_drelse: + brelse(bh); + + return error; +} + +/** + * buf_after_scan - called after journal replay + * @sdp: the filesystem + * @jid: the journal ID about to be replayed + * @pass: the pass through the journal + * + */ + +static void +buf_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) +{ + if (pass == GFS_RECPASS_A1) { + printk("GFS: fsid=%s: jid=%u: Replayed %u of %u blocks\n", + sdp->sd_fsname, jid, + sdp->sd_recovery_replays, + sdp->sd_recovery_replays + sdp->sd_recovery_skips + + sdp->sd_recovery_sames); + printk("GFS: fsid=%s: jid=%u: replays = %u, skips = %u, sames = %u\n", + sdp->sd_fsname, jid, sdp->sd_recovery_replays, + sdp->sd_recovery_skips, sdp->sd_recovery_sames); + } +} + +/** + * unlinked_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +unlinked_print(struct gfs_sbd *sdp, struct gfs_log_element *le, + unsigned int where) +{ + struct gfs_unlinked *ul; + char *type; + + switch (where) { + case TRANS_IS_NEW: + ul = container_of(le, struct gfs_unlinked, ul_new_le); + type = (test_bit(ULF_NEW_UL, &ul->ul_flags)) ? + "unlink" : "dealloc"; + break; + case TRANS_IS_INCORE: + ul = container_of(le, struct gfs_unlinked, ul_incore_le); + type = (test_bit(ULF_INCORE_UL, &ul->ul_flags)) ? + "unlink" : "dealloc"; + break; + default: + gfs_assert_warn(sdp, FALSE); + return; + } + + printk(" unlinked: %"PRIu64"/%"PRIu64", %s\n", + ul->ul_inum.no_formal_ino, ul->ul_inum.no_addr, + type); +} + +/** + * unlinked_incore_commit - commit this LE to the incore log + * @sdp: the filesystem + * @tr: the incore transaction this LE is a part of + * @le: the log element + * + */ + +static void +unlinked_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_unlinked *ul = container_of(le, + struct gfs_unlinked, + ul_new_le); + int n = !!test_bit(ULF_NEW_UL, &ul->ul_flags); + int i = !!test_bit(ULF_INCORE_UL, &ul->ul_flags); + + if (ul->ul_incore_le.le_trans) { + gfs_assert(sdp, ul->ul_incore_le.le_trans == tr,); + gfs_assert(sdp, n != i,); + + ul->ul_incore_le.le_trans = NULL; + list_del_init(&ul->ul_incore_le.le_list); + gfs_unlinked_put(sdp, ul); + + if (i) { + gfs_assert(sdp, tr->tr_num_iul,); + tr->tr_num_iul--; + } else { + gfs_assert(sdp, tr->tr_num_ida,); + tr->tr_num_ida--; + } + } else { + gfs_unlinked_hold(sdp, ul); + ul->ul_incore_le.le_trans = tr; + list_add(&ul->ul_incore_le.le_list, &tr->tr_elements); + + if (n) { + set_bit(ULF_INCORE_UL, &ul->ul_flags); + if (tr != le->le_trans) + tr->tr_num_iul++; + } else { + clear_bit(ULF_INCORE_UL, &ul->ul_flags); + if (tr != le->le_trans) + tr->tr_num_ida++; + } + } + + if (n) { + gfs_unlinked_hold(sdp, ul); + gfs_assert(sdp, !test_bit(ULF_IC_LIST, &ul->ul_flags),); + set_bit(ULF_IC_LIST, &ul->ul_flags); + atomic_inc(&sdp->sd_unlinked_ic_count); + } else { + gfs_assert(sdp, test_bit(ULF_IC_LIST, &ul->ul_flags),); + clear_bit(ULF_IC_LIST, &ul->ul_flags); + gfs_unlinked_put(sdp, ul); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_ic_count),); + atomic_dec(&sdp->sd_unlinked_ic_count); + } + + le->le_trans = NULL; + list_del_init(&le->le_list); + gfs_unlinked_put(sdp, ul); +} + +/** + * unlinked_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +unlinked_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_unlinked *ul = container_of(le, + struct gfs_unlinked, + ul_incore_le); + int i = !!test_bit(ULF_INCORE_UL, &ul->ul_flags); + + if (i) { + gfs_unlinked_hold(sdp, ul); + gfs_assert(sdp, !test_bit(ULF_OD_LIST, &ul->ul_flags),); + set_bit(ULF_OD_LIST, &ul->ul_flags); + atomic_inc(&sdp->sd_unlinked_od_count); + } else { + gfs_assert(sdp, test_bit(ULF_OD_LIST, &ul->ul_flags),); + clear_bit(ULF_OD_LIST, &ul->ul_flags); + gfs_unlinked_put(sdp, ul); + gfs_assert(sdp, atomic_read(&sdp->sd_unlinked_od_count),); + atomic_dec(&sdp->sd_unlinked_od_count); + } + + le->le_trans = NULL; + list_del_init(&le->le_list); + gfs_unlinked_put(sdp, ul); +} + +/** + * unlinked_clean_dump - clean up a LE after a log dump + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +unlinked_clean_dump(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * unlinked_trans_size - compute how much space the LE class takes up in a transaction + * @sdp: the filesystem + * @tr: the transaction + * @mblks: the number of regular metadata blocks + * @eblks: the number of extra blocks + * @blocks: the number of log blocks + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +unlinked_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int ublks = 0; + + if (tr->tr_num_iul) + ublks = gfs_struct2blk(sdp, tr->tr_num_iul, + sizeof(struct gfs_inum)); + if (tr->tr_num_ida) + ublks += gfs_struct2blk(sdp, tr->tr_num_ida, + sizeof(struct gfs_inum)); + + if (eblks) + *eblks += ublks; + if (blocks) + *blocks += ublks; + if (bmem) + *bmem += ublks; +} + +/** + * unlinked_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +unlinked_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_iul += new_tr->tr_num_iul; + tr->tr_num_ida += new_tr->tr_num_ida; +} + +/** + * unlinked_build_bhlist - create the buffers that will make up the ondisk part of a transaction + * @sdp: the filesystem + * @tr: the transaction + * + * For unlinked and/or deallocated inode log elements (separately): + * Get a log block + * Create a log descriptor in beginning of that block + * Fill rest of block with gfs_inum structs to identify each inode + * that became unlinked/deallocated during this transaction. + * Get another log block if needed, continue filling with gfs_inums. + */ + +static void +unlinked_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_log_element *le; + struct gfs_unlinked *ul; + struct gfs_log_descriptor desc; + struct gfs_log_buf *lb; + unsigned int pass = 2; + unsigned int type, number; + unsigned int offset, entries; + + /* 2 passes: 1st for Unlinked, 2nd for De-Alloced inodes, + unless this is a log dump: just 1 pass, for Unlinked */ + while (pass--) { + if (tr->tr_flags & TRF_LOG_DUMP) { + if (pass) { + type = GFS_LOG_DESC_IUL; + number = tr->tr_num_iul; + } else + break; + } else { + if (pass) { + type = GFS_LOG_DESC_IUL; + number = tr->tr_num_iul; + } else { + type = GFS_LOG_DESC_IDA; + number = tr->tr_num_ida; + } + + if (!number) + continue; + } + + lb = gfs_log_get_buf(sdp, tr); + + /* Header: log descriptor */ + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = type; + desc.ld_length = gfs_struct2blk(sdp, number, sizeof(struct gfs_inum)); + desc.ld_data1 = (tr->tr_flags & TRF_LOG_DUMP) ? TRUE : FALSE; + gfs_desc_out(&desc, lb->lb_bh.b_data); + + offset = sizeof(struct gfs_log_descriptor); + entries = 0; + + /* Look through transaction's log elements for Unlinked LEs */ + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + if (le->le_ops != &gfs_unlinked_lops) + continue; + if (tr->tr_flags & TRF_LOG_DUMP) + ul = container_of(le, + struct gfs_unlinked, + ul_ondisk_le); + else { + ul = container_of(le, + struct gfs_unlinked, + ul_incore_le); + if (!!test_bit(ULF_INCORE_UL, &ul->ul_flags) != pass) + continue; + } + + if (offset + sizeof(struct gfs_inum) > sdp->sd_sb.sb_bsize) { + offset = 0; + lb = gfs_log_get_buf(sdp, tr); + } + + /* Payload: write the inode identifier */ + gfs_inum_out(&ul->ul_inum, + lb->lb_bh.b_data + offset); + + offset += sizeof(struct gfs_inum); + entries++; + } + + gfs_assert(sdp, entries == number,); + } +} + +/** + * unlinked_dump_size - compute how much space the LE class takes up in a log dump + * @sdp: the filesystem + * @elements: the number of log elements in the dump + * @blocks: the number of blocks in the dump + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +unlinked_dump_size(struct gfs_sbd *sdp, unsigned int *elements, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int c = atomic_read(&sdp->sd_unlinked_od_count); + unsigned int b = gfs_struct2blk(sdp, c, sizeof(struct gfs_inum)); + + if (elements) + *elements += c; + if (blocks) + *blocks += b; + if (bmem) + *bmem += b; +} + +/** + * unlinked_build_dump - create a transaction that represents a log dump for this LE class + * @sdp: the filesystem + * @tr: the transaction to fill + * + */ + +static void +unlinked_build_dump(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_unlinked *ul; + unsigned int x = 0; + + tr->tr_num_iul = atomic_read(&sdp->sd_unlinked_od_count); + + spin_lock(&sdp->sd_unlinked_lock); + + for (head = &sdp->sd_unlinked_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + ul = list_entry(tmp, struct gfs_unlinked, ul_list); + if (!test_bit(ULF_OD_LIST, &ul->ul_flags)) + continue; + + gfs_assert(sdp, !ul->ul_ondisk_le.le_trans,); + ul->ul_ondisk_le.le_trans = tr; + list_add(&ul->ul_ondisk_le.le_list, &tr->tr_elements); + + x++; + } + + spin_unlock(&sdp->sd_unlinked_lock); + + gfs_assert(sdp, x == atomic_read(&sdp->sd_unlinked_od_count),); +} + +/** + * unlinked_before_scan - called before a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @head: the current head of the log + * @pass: the pass through the journal + * + */ + +static void +unlinked_before_scan(struct gfs_sbd *sdp, unsigned int jid, + struct gfs_log_header *head, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) + clear_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags); +} + +/** + * unlinked_scan_elements - scan unlinked inodes from the journal + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being scaned + * @gl: the journal's glock + * @start: the starting block of the descriptor + * @desc: the descriptor structure + * @pass: the pass through the journal + * + * Returns: errno + */ + +static int +unlinked_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + struct gfs_inum inum; + struct buffer_head *bh; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x; + int error; + + if (pass != GFS_RECPASS_B1) + return 0; + + switch (desc->ld_type) { + case GFS_LOG_DESC_IUL: + if (test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags)) + gfs_assert(sdp, !desc->ld_data1,); + else { + gfs_assert(sdp, desc->ld_data1,); + set_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags); + } + break; + + case GFS_LOG_DESC_IDA: + gfs_assert(sdp, test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags),); + break; + + default: + return 0; + } + + for (x = 0; x < desc->ld_length; x++) { + error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + for (; + offset + sizeof(struct gfs_inum) <= sdp->sd_sb.sb_bsize; + offset += sizeof(struct gfs_inum)) { + gfs_inum_in(&inum, bh->b_data + offset); + + if (inum.no_addr) + gfs_unlinked_merge(sdp, desc->ld_type, &inum); + } + + brelse(bh); + + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + return error; + + offset = 0; + } + + return 0; +} + +/** + * unlinked_after_scan - called after a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @pass: the pass through the journal + * + */ + +static void +unlinked_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) { + gfs_assert(sdp, test_bit(SDF_FOUND_UL_DUMP, &sdp->sd_flags),); + printk("GFS: fsid=%s: Found %d unlinked inodes\n", + sdp->sd_fsname, atomic_read(&sdp->sd_unlinked_ic_count)); + } +} + +/** + * quota_print - print debug info about a log element + * @sdp: the filesystem + * @le: the log element + * @where: is this a new transaction or a incore transaction + * + */ + +static void +quota_print(struct gfs_sbd *sdp, struct gfs_log_element *le, unsigned int where) +{ + struct gfs_quota_le *ql; + + ql = container_of(le, struct gfs_quota_le, ql_le); + printk(" quota: %s %u: %"PRId64" blocks\n", + (test_bit(QDF_USER, &ql->ql_data->qd_flags)) ? "user" : "group", + ql->ql_data->qd_id, ql->ql_change); +} + +/** + * quota_incore_commit - commit this LE to the incore log + * @sdp: the filesystem + * @tr: the incore transaction this LE is a part of + * @le: the log element + * + */ + +static void +quota_incore_commit(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_log_element *le) +{ + struct gfs_quota_le *ql = container_of(le, struct gfs_quota_le, ql_le); + struct gfs_quota_data *qd = ql->ql_data; + + gfs_assert(sdp, ql->ql_change,); + + /* Make this change under the sd_quota_lock, so other processes + checking qd_change_ic don't have to acquire the log lock. */ + + spin_lock(&sdp->sd_quota_lock); + qd->qd_change_new -= ql->ql_change; + qd->qd_change_ic += ql->ql_change; + spin_unlock(&sdp->sd_quota_lock); + + if (le->le_trans == tr) + list_add(&ql->ql_data_list, &qd->qd_le_list); + else { + struct list_head *tmp, *head; + struct gfs_quota_le *tmp_ql; + int found = FALSE; + + for (head = &qd->qd_le_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + tmp_ql = list_entry(tmp, struct gfs_quota_le, ql_data_list); + if (tmp_ql->ql_le.le_trans != tr) + continue; + + tmp_ql->ql_change += ql->ql_change; + + list_del(&le->le_list); + gfs_quota_put(sdp, qd); + kfree(ql); + + if (!tmp_ql->ql_change) { + list_del(&tmp_ql->ql_data_list); + list_del(&tmp_ql->ql_le.le_list); + gfs_quota_put(sdp, tmp_ql->ql_data); + kfree(tmp_ql); + tr->tr_num_q--; + } + + found = TRUE; + break; + } + + if (!found) { + le->le_trans = tr; + list_move(&le->le_list, &tr->tr_elements); + tr->tr_num_q++; + list_add(&ql->ql_data_list, &qd->qd_le_list); + } + } +} + +/** + * quota_add_to_ail - Add this LE to the AIL + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +quota_add_to_ail(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + struct gfs_quota_le *ql = container_of(le, struct gfs_quota_le, ql_le); + struct gfs_quota_data *qd = ql->ql_data; + + qd->qd_change_od += ql->ql_change; + if (qd->qd_change_od) { + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) { + gfs_quota_hold(sdp, qd); + set_bit(QDF_OD_LIST, &qd->qd_flags); + atomic_inc(&sdp->sd_quota_od_count); + } + } else { + gfs_assert(sdp, test_bit(QDF_OD_LIST, &qd->qd_flags),); + clear_bit(QDF_OD_LIST, &qd->qd_flags); + gfs_quota_put(sdp, qd); + gfs_assert(sdp, atomic_read(&sdp->sd_quota_od_count),); + atomic_dec(&sdp->sd_quota_od_count); + } + + list_del(&ql->ql_data_list); + list_del(&le->le_list); + gfs_quota_put(sdp, qd); + kfree(ql); +} + +/** + * quota_clean_dump - clean up a LE after a log dump + * @sdp: the filesystem + * @le: the log element + * + */ + +static void +quota_clean_dump(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + le->le_trans = NULL; + list_del_init(&le->le_list); +} + +/** + * quota_trans_size - compute how much space the LE class takes up in a transaction + * @sdp: the filesystem + * @tr: the transaction + * @mblks: the number of regular metadata blocks + * @eblks: the number of extra blocks + * @blocks: the number of log blocks + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +quota_trans_size(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int *mblks, unsigned int *eblks, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int qblks; + + if (tr->tr_num_q) { + qblks = gfs_struct2blk(sdp, tr->tr_num_q, + sizeof(struct gfs_quota_tag)); + + if (eblks) + *eblks += qblks; + if (blocks) + *blocks += qblks; + if (bmem) + *bmem += qblks; + } +} + +/** + * quota_trans_combine - combine two incore transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that's going to disappear + * + */ + +static void +quota_trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + tr->tr_num_q += new_tr->tr_num_q; +} + +/** + * quota_build_bhlist - create the buffers that will make up the ondisk part of a transaction + * @sdp: the filesystem + * @tr: the transaction + * + */ + +static void +quota_build_bhlist(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_log_element *le; + struct gfs_quota_le *ql; + struct gfs_log_descriptor desc; + struct gfs_quota_tag tag; + struct gfs_log_buf *lb; + unsigned int offset = sizeof(struct gfs_log_descriptor), entries = 0; + + if (!tr->tr_num_q && !(tr->tr_flags & TRF_LOG_DUMP)) + return; + + lb = gfs_log_get_buf(sdp, tr); + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_Q; + desc.ld_length = gfs_struct2blk(sdp, tr->tr_num_q, + sizeof(struct gfs_quota_tag)); + desc.ld_data1 = tr->tr_num_q; + desc.ld_data2 = (tr->tr_flags & TRF_LOG_DUMP) ? TRUE : FALSE; + gfs_desc_out(&desc, lb->lb_bh.b_data); + + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + if (le->le_ops != &gfs_quota_lops) + continue; + + ql = container_of(le, struct gfs_quota_le, ql_le); + + if (offset + sizeof(struct gfs_quota_tag) > + sdp->sd_sb.sb_bsize) { + offset = 0; + lb = gfs_log_get_buf(sdp, tr); + } + + memset(&tag, 0, sizeof(struct gfs_quota_tag)); + tag.qt_change = ql->ql_change; + tag.qt_flags = (test_bit(QDF_USER, &ql->ql_data->qd_flags)) ? + GFS_QTF_USER : 0; + tag.qt_id = ql->ql_data->qd_id; + + gfs_quota_tag_out(&tag, lb->lb_bh.b_data + offset); + + offset += sizeof(struct gfs_quota_tag); + entries++; + } + + gfs_assert(sdp, entries == tr->tr_num_q,); +} + +/** + * quota_dump_size - compute how much space the LE class takes up in a log dump + * @sdp: the filesystem + * @elements: the number of log elements in the dump + * @blocks: the number of blocks in the dump + * @bmem: the number of buffer-sized chunks of memory we need + * + */ + +static void +quota_dump_size(struct gfs_sbd *sdp, unsigned int *elements, + unsigned int *blocks, unsigned int *bmem) +{ + unsigned int c = atomic_read(&sdp->sd_quota_od_count); + unsigned int b = gfs_struct2blk(sdp, c, sizeof(struct gfs_quota_tag)); + + if (elements) + *elements += c; + if (blocks) + *blocks += b; + if (bmem) + *bmem += b; +} + +/** + * quota_build_dump - create a transaction that represents a log dump for this LE class + * @sdp: the filesystem + * @tr: the transaction to fill + * + */ + +static void +quota_build_dump(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head; + struct gfs_quota_data *qd; + struct gfs_quota_le *ql; + unsigned int x = 0; + + tr->tr_num_q = atomic_read(&sdp->sd_quota_od_count); + + spin_lock(&sdp->sd_quota_lock); + + for (head = &sdp->sd_quota_list, tmp = head->next; + tmp != head; + tmp = tmp->next) { + qd = list_entry(tmp, struct gfs_quota_data, qd_list); + if (!test_bit(QDF_OD_LIST, &qd->qd_flags)) + continue; + + ql = &qd->qd_ondisk_ql; + + ql->ql_le.le_ops = &gfs_quota_lops; + gfs_assert(sdp, !ql->ql_le.le_trans,); + ql->ql_le.le_trans = tr; + list_add(&ql->ql_le.le_list, &tr->tr_elements); + + ql->ql_data = qd; + ql->ql_change = qd->qd_change_od; + + x++; + } + + spin_unlock(&sdp->sd_quota_lock); + + gfs_assert(sdp, x == atomic_read(&sdp->sd_quota_od_count),); +} + +/** + * quota_before_scan - called before a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @head: the current head of the log + * @pass: the pass through the journal + * + */ + +static void +quota_before_scan(struct gfs_sbd *sdp, unsigned int jid, + struct gfs_log_header *head, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) + clear_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags); +} + +/** + * quota_scan_elements - scan quota inodes from the journal + * @sdp: the filesystem + * @jdesc: the struct gfs_jindex structure for the journal being scaned + * @gl: the journal's glock + * @start: the starting block of the descriptor + * @desc: the descriptor structure + * @pass: the pass through the journal + * + * Returns: errno + */ + +static int +quota_scan_elements(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + struct gfs_quota_tag tag; + struct buffer_head *bh; + unsigned int num_tags = desc->ld_data1; + unsigned int offset = sizeof(struct gfs_log_descriptor); + unsigned int x; + int error; + + if (pass != GFS_RECPASS_B1) + return 0; + if (desc->ld_type != GFS_LOG_DESC_Q) + return 0; + + if (test_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags)) + gfs_assert(sdp, !desc->ld_data2,); + else { + gfs_assert(sdp, desc->ld_data2,); + set_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags); + } + + if (!num_tags) + return 0; + + for (x = 0; x < desc->ld_length; x++) { + error = gfs_dread(gl, start, DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + while (offset + sizeof(struct gfs_quota_tag) <= + sdp->sd_sb.sb_bsize) { + gfs_quota_tag_in(&tag, bh->b_data + offset); + + error = gfs_quota_merge(sdp, &tag); + if (error) + goto out_drelse; + + if (!--num_tags) + goto out_drelse; + + offset += sizeof(struct gfs_quota_tag); + } + + brelse(bh); + + error = gfs_increment_blkno(sdp, jdesc, gl, &start, TRUE); + if (error) + return error; + + offset = 0; + } + + return 0; + + out_drelse: + brelse(bh); + + return error; +} + +/** + * quota_after_scan - called after a log dump is recovered + * @sdp: the filesystem + * @jid: the journal ID about to be scanned + * @pass: the pass through the journal + * + */ + +static void +quota_after_scan(struct gfs_sbd *sdp, unsigned int jid, unsigned int pass) +{ + if (pass == GFS_RECPASS_B1) { + gfs_assert(sdp, !sdp->sd_sb.sb_quota_di.no_formal_ino || + test_bit(SDF_FOUND_Q_DUMP, &sdp->sd_flags),); + printk("GFS: fsid=%s: Found quota changes for %d IDs\n", + sdp->sd_fsname, atomic_read(&sdp->sd_quota_od_count)); + } +} + +struct gfs_log_operations gfs_glock_lops = { + .lo_add = generic_le_add, + .lo_trans_end = glock_trans_end, + .lo_print = glock_print, + .lo_overlap_trans = glock_overlap_trans, + .lo_incore_commit = glock_incore_commit, + .lo_add_to_ail = glock_add_to_ail, + .lo_trans_combine = glock_trans_combine, + .lo_name = "glock" +}; + +struct gfs_log_operations gfs_buf_lops = { + .lo_add = generic_le_add, + .lo_print = buf_print, + .lo_incore_commit = buf_incore_commit, + .lo_add_to_ail = buf_add_to_ail, + .lo_trans_size = buf_trans_size, + .lo_trans_combine = buf_trans_combine, + .lo_build_bhlist = buf_build_bhlist, + .lo_before_scan = buf_before_scan, + .lo_scan_elements = buf_scan_elements, + .lo_after_scan = buf_after_scan, + .lo_name = "buf" +}; + +struct gfs_log_operations gfs_unlinked_lops = { + .lo_add = generic_le_add, + .lo_print = unlinked_print, + .lo_incore_commit = unlinked_incore_commit, + .lo_add_to_ail = unlinked_add_to_ail, + .lo_clean_dump = unlinked_clean_dump, + .lo_trans_size = unlinked_trans_size, + .lo_trans_combine = unlinked_trans_combine, + .lo_build_bhlist = unlinked_build_bhlist, + .lo_dump_size = unlinked_dump_size, + .lo_build_dump = unlinked_build_dump, + .lo_before_scan = unlinked_before_scan, + .lo_scan_elements = unlinked_scan_elements, + .lo_after_scan = unlinked_after_scan, + .lo_name = "unlinked" +}; + +struct gfs_log_operations gfs_quota_lops = { + .lo_add = generic_le_add, + .lo_print = quota_print, + .lo_incore_commit = quota_incore_commit, + .lo_add_to_ail = quota_add_to_ail, + .lo_clean_dump = quota_clean_dump, + .lo_trans_size = quota_trans_size, + .lo_trans_combine = quota_trans_combine, + .lo_build_bhlist = quota_build_bhlist, + .lo_dump_size = quota_dump_size, + .lo_build_dump = quota_build_dump, + .lo_before_scan = quota_before_scan, + .lo_scan_elements = quota_scan_elements, + .lo_after_scan = quota_after_scan, + .lo_name = "quota" +}; + +struct gfs_log_operations *gfs_log_ops[] = { + &gfs_glock_lops, + &gfs_buf_lops, + &gfs_unlinked_lops, + &gfs_quota_lops, + NULL +}; --- linux-2.6.28.orig/ubuntu/gfs/ops_dentry.c +++ linux-2.6.28/ubuntu/gfs/ops_dentry.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dir.h" +#include "glock.h" +#include "ops_dentry.h" + +/** + * gfs_drevalidate - Check directory lookup consistency + * @dentry: the mapping to check + * @nd: + * + * Check to make sure the lookup necessary to arrive at this inode from its + * parent is still good. + * + * Returns: 1 if the dentry is ok, 0 if it isn't + */ + +static int +gfs_drevalidate(struct dentry *dentry, struct nameidata *nd) +{ + struct dentry *parent = dget_parent(dentry); + struct gfs_inode *dip = get_v2ip(parent->d_inode); + struct gfs_sbd *sdp = dip->i_sbd; + struct inode *inode; + struct gfs_holder d_gh; + struct gfs_inode *ip; + struct gfs_inum inum; + unsigned int type; + int error; + + lock_kernel(); + + atomic_inc(&sdp->sd_ops_dentry); + + if (sdp->sd_args.ar_localcaching) + goto valid; + + inode = dentry->d_inode; + if (inode && is_bad_inode(inode)) + goto invalid; + + error = gfs_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); + if (error) + goto fail; + + error = gfs_dir_search(dip, &dentry->d_name, &inum, &type); + switch (error) { + case 0: + if (!inode) + goto invalid_gunlock; + break; + case -ENOENT: + if (!inode) + goto valid_gunlock; + goto invalid_gunlock; + default: + goto fail_gunlock; + } + + ip = get_v2ip(inode); + + if (ip->i_num.no_formal_ino != inum.no_formal_ino) + goto invalid_gunlock; + + if (ip->i_di.di_type != type) { + gfs_consist_inode(dip); + goto fail_gunlock; + } + + valid_gunlock: + gfs_glock_dq_uninit(&d_gh); + + valid: + unlock_kernel(); + dput(parent); + return 1; + + invalid_gunlock: + gfs_glock_dq_uninit(&d_gh); + + invalid: + if (inode && S_ISDIR(inode->i_mode)) { + if (have_submounts(dentry)) + goto valid; + shrink_dcache_parent(dentry); + } + d_drop(dentry); + + unlock_kernel(); + dput(parent); + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&d_gh); + + fail: + unlock_kernel(); + dput(parent); + return 0; +} + +struct dentry_operations gfs_dops = { + .d_revalidate = gfs_drevalidate, +}; --- linux-2.6.28.orig/ubuntu/gfs/Makefile +++ linux-2.6.28/ubuntu/gfs/Makefile @@ -0,0 +1,46 @@ +#obj-$(CONFIG_GFS_FS) += gfs.o +gfs-objs := acl.o \ + bits.o \ + bmap.o \ + daemon.o \ + dio.o \ + dir.o \ + eaops.o \ + eattr.o \ + file.o \ + glock.o \ + glops.o \ + inode.o \ + ioctl.o \ + lm.o \ + locking.o \ + lock_nolock_main.o \ + lock_dlm_lock.o \ + lock_dlm_main.o \ + lock_dlm_mount.o \ + lock_dlm_sysfs.o \ + lock_dlm_thread.o \ + log.o \ + lops.o \ + lvb.o \ + main.o \ + mount.o \ + ondisk.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 \ + page.o \ + proc.o \ + quota.o \ + recovery.o \ + rgrp.o \ + super.o \ + sys.o \ + trans.o \ + unlinked.o \ + util.o --- linux-2.6.28.orig/ubuntu/gfs/ops_vm.h +++ linux-2.6.28/ubuntu/gfs/ops_vm.h @@ -0,0 +1,7 @@ +#ifndef __OPS_VM_DOT_H__ +#define __OPS_VM_DOT_H__ + +extern struct vm_operations_struct gfs_vm_ops_private; +extern struct vm_operations_struct gfs_vm_ops_sharewrite; + +#endif /* __OPS_VM_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/dir.h +++ linux-2.6.28/ubuntu/gfs/dir.h @@ -0,0 +1,42 @@ +#ifndef __DIR_DOT_H__ +#define __DIR_DOT_H__ + +/** + * gfs_filldir_t - Report a directory entry to the caller of gfs_dir_read() + * @opaque: opaque data used by the function + * @name: the name of the directory entry + * @length: the length of the name + * @offset: the entry's offset in the directory + * @inum: the inode number the entry points to + * @type: the type of inode the entry points to + * + * Returns: 0 on success, 1 if buffer full + */ + +typedef int (*gfs_filldir_t) (void *opaque, + const char *name, unsigned int length, + uint64_t offset, + struct gfs_inum *inum, unsigned int type); + +int gfs_filecmp(struct qstr *file1, char *file2, int len_of_file2); +int gfs_dirent_alloc(struct gfs_inode *dip, struct buffer_head *bh, + int name_len, struct gfs_dirent **dent_out); + +int gfs_dir_search(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int *type); +int gfs_dir_add(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *inum, unsigned int type); +int gfs_dir_del(struct gfs_inode *dip, struct qstr *filename); +int gfs_dir_read(struct gfs_inode *dip, uint64_t * offset, void *opaque, + gfs_filldir_t filldir); +int gfs_dir_mvino(struct gfs_inode *dip, struct qstr *filename, + struct gfs_inum *new_inum, unsigned int new_type); + +int gfs_dir_exhash_free(struct gfs_inode *dip); + +int gfs_diradd_alloc_required(struct gfs_inode *dip, struct qstr *filename, + int *alloc_required); + +int gfs_get_dir_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); + +#endif /* __DIR_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/eattr.c +++ linux-2.6.28/ubuntu/gfs/eattr.c @@ -0,0 +1,2008 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "dio.h" +#include "eaops.h" +#include "eattr.h" +#include "glock.h" +#include "inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +/** + * ea_calc_size - returns the acutal number of bytes the request will take up + * (not counting any unstuffed data blocks) + * @sdp: + * @er: + * @size: + * + * Returns: TRUE if the EA should be stuffed + */ + +static int +ea_calc_size(struct gfs_sbd *sdp, + struct gfs_ea_request *er, + unsigned int *size) +{ + *size = GFS_EAREQ_SIZE_STUFFED(er); + if (*size <= sdp->sd_jbsize) + return TRUE; + + *size = GFS_EAREQ_SIZE_UNSTUFFED(sdp, er); + return FALSE; +} + +/** + * gfs_ea_check_size - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_check_size(struct gfs_sbd *sdp, struct gfs_ea_request *er) +{ + unsigned int size; + + if (er->er_data_len > GFS_EA_MAX_DATA_LEN) + return -ERANGE; + + ea_calc_size(sdp, er, &size); + if (size > sdp->sd_jbsize) + return -ERANGE; /* This can only happen with 512 byte blocks */ + + return 0; +} + +typedef int (*ea_call_t) (struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private); + +/** + * ea_foreach_i - + * @ip: + * @bh: + * @eabc: + * @data: + * + * Returns: errno + */ + +static int +ea_foreach_i(struct gfs_inode *ip, + struct buffer_head *bh, + ea_call_t ea_call, void *data) +{ + struct gfs_ea_header *ea, *prev = NULL; + int error = 0; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) + return -EIO; + + for (ea = GFS_EA_BH2FIRST(bh);; prev = ea, ea = GFS_EA2NEXT(ea)) { + if (!GFS_EA_REC_LEN(ea)) + goto fail; + if (!(bh->b_data <= (char *)ea && + (char *)GFS_EA2NEXT(ea) <= + bh->b_data + bh->b_size)) + goto fail; + if (!GFS_EATYPE_VALID(ea->ea_type)) + goto fail; + + error = ea_call(ip, bh, ea, prev, data); + if (error) + return error; + + if (GFS_EA_IS_LAST(ea)) { + if ((char *)GFS_EA2NEXT(ea) != + bh->b_data + bh->b_size) + goto fail; + break; + } + } + + return error; + + fail: + gfs_consist_inode(ip); + return -EIO; +} + +/** + * ea_foreach - + * @ip: + * @ea_call: + * @data: + * + * Returns: errno + */ + +static int +ea_foreach(struct gfs_inode *ip, + ea_call_t ea_call, + void *data) +{ + struct buffer_head *bh; + int error; + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + if (!(ip->i_di.di_flags & GFS_DIF_EA_INDIRECT)) + error = ea_foreach_i(ip, bh, ea_call, data); + else { + struct buffer_head *eabh; + uint64_t *eablk, *end; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)); + end = eablk + ip->i_sbd->sd_inptrs; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + error = gfs_dread(ip->i_gl, bn, + DIO_START | DIO_WAIT, &eabh); + if (error) + break; + error = ea_foreach_i(ip, eabh, ea_call, data); + brelse(eabh); + if (error) + break; + } + } + + out: + brelse(bh); + + return error; +} + +struct ea_find { + struct gfs_ea_request *ef_er; + struct gfs_ea_location *ef_el; +}; + +/** + * ea_find_i - + * @ip: + * @bh: + * @ea: + * @prev: + * @private: + * + * Returns: -errno on error, 1 if search is over, + * 0 if search should continue + */ + +static int +ea_find_i(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + struct ea_find *ef = (struct ea_find *)private; + struct gfs_ea_request *er = ef->ef_er; + + if (ea->ea_type == GFS_EATYPE_UNUSED) + return 0; + + if (ea->ea_type == er->er_type) { + if (ea->ea_name_len == er->er_name_len && + !memcmp(GFS_EA2NAME(ea), er->er_name, ea->ea_name_len)) { + struct gfs_ea_location *el = ef->ef_el; + get_bh(bh); + el->el_bh = bh; + el->el_ea = ea; + el->el_prev = prev; + return 1; + } + } + +#if 0 + else if ((ip->i_di.di_flags & GFS_DIF_EA_PACKED) && + er->er_type == GFS_EATYPE_SYS) + return 1; +#endif + + return 0; +} + +/** + * gfs_ea_find - find a matching eattr + * @ip: + * @er: + * @el: + * + * Returns: errno + */ + +int +gfs_ea_find(struct gfs_inode *ip, + struct gfs_ea_request *er, + struct gfs_ea_location *el) +{ + struct ea_find ef; + int error; + + ef.ef_er = er; + ef.ef_el = el; + + memset(el, 0, sizeof(struct gfs_ea_location)); + + error = ea_foreach(ip, ea_find_i, &ef); + if (error > 0) + return 0; + + return error; +} + +/** + * ea_dealloc_unstuffed - + * @ip: + * @bh: + * @ea: + * @prev: + * @private: + * + * Take advantage of the fact that all unstuffed blocks are + * allocated from the same RG. But watch, this may not always + * be true. + * + * Returns: errno + */ + +static int +ea_dealloc_unstuffed(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + int *leave = (int *)private; + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrpd *rgd; + struct gfs_holder rg_gh; + struct buffer_head *dibh; + uint64_t *dataptrs, bn = 0; + uint64_t bstart = 0; + unsigned int blen = 0; + unsigned int x; + int error; + + if (GFS_EA_IS_STUFFED(ea)) + return 0; + + dataptrs = GFS_EA2DATAPTRS(ea); + for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) + if (*dataptrs) { + bn = gfs64_to_cpu(*dataptrs); + break; + } + if (!bn) + return 0; + + rgd = gfs_blk2rgrpd(sdp, bn); + if (!rgd) { + gfs_consist_inode(ip); + return -EIO; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rg_gh); + if (error) + return error; + + error = gfs_trans_begin(sdp, 2 + rgd->rd_ri.ri_length, 1); + if (error) + goto out_gunlock; + + gfs_trans_add_bh(ip->i_gl, bh); + + dataptrs = GFS_EA2DATAPTRS(ea); + for (x = 0; x < ea->ea_num_ptrs; x++, dataptrs++) { + if (!*dataptrs) + break; + bn = gfs64_to_cpu(*dataptrs); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_metafree(ip, bstart, blen); + bstart = bn; + blen = 1; + } + + *dataptrs = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + } + if (bstart) + gfs_metafree(ip, bstart, blen); + + if (prev && !leave) { + uint32_t len; + + len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); + prev->ea_rec_len = cpu_to_gfs32(len); + + if (GFS_EA_IS_LAST(ea)) + prev->ea_flags |= GFS_EAFLAG_LAST; + } else { + ea->ea_type = GFS_EATYPE_UNUSED; + ea->ea_num_ptrs = 0; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + out_gunlock: + gfs_glock_dq_uninit(&rg_gh); + + return error; +} + +/** + * ea_remove_unstuffed - + * @ip: + * @bh: + * @ea: + * @prev: + * @leave: + * + * Returns: errno + */ + +static int +ea_remove_unstuffed(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + int leave) +{ + struct gfs_alloc *al; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out_alloc; + + error = gfs_rindex_hold(ip->i_sbd, &al->al_ri_gh); + if (error) + goto out_quota; + + error = ea_dealloc_unstuffed(ip, + bh, ea, prev, + (leave) ? &error : NULL); + + gfs_glock_dq_uninit(&al->al_ri_gh); + + out_quota: + gfs_quota_unhold_m(ip); + + out_alloc: + gfs_alloc_put(ip); + + return error; +} + +/**************************************************************************************************/ + +/** + * gfs_ea_repack_i - + * @ip: + * + * Returns: errno + */ + +int +gfs_ea_repack_i(struct gfs_inode *ip) +{ + return -ENOSYS; +} + +/** + * gfs_ea_repack - + * @ip: + * + * Returns: errno + */ + +int gfs_ea_repack(struct gfs_inode *ip) +{ + struct gfs_holder gh; + int error; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); + if (error) + return error; + + /* Some sort of permissions checking would be nice */ + + error = gfs_ea_repack_i(ip); + + gfs_glock_dq_uninit(&gh); + + return error; +} + +struct ea_list { + struct gfs_ea_request *ei_er; + unsigned int ei_size; +}; + +/** + * ea_list_i - + * @ip: + * @bh: + * @ea: + * @prev: + * @private: + * + * Returns: errno + */ + +static int +ea_list_i(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + struct ea_list *ei = (struct ea_list *)private; + struct gfs_ea_request *er = ei->ei_er; + unsigned int ea_size = gfs_ea_strlen(ea); + + if (ea->ea_type == GFS_EATYPE_UNUSED) + return 0; + + if (er->er_data_len) { + char *prefix; + unsigned int l; + char c = 0; + + if (ei->ei_size + ea_size > er->er_data_len) + return -ERANGE; + + switch (ea->ea_type) { + case GFS_EATYPE_USR: + prefix = "user."; + l = 5; + break; + case GFS_EATYPE_SYS: + prefix = "system."; + l = 7; + break; + case GFS_EATYPE_SECURITY: + prefix = "security."; + l = 9; + break; + default: + prefix = NULL; + l = 0; + break; + } + + if (prefix == NULL || l == 0) + return -EIO; + + memcpy(er->er_data + ei->ei_size, + prefix, l); + memcpy(er->er_data + ei->ei_size + l, + GFS_EA2NAME(ea), + ea->ea_name_len); + memcpy(er->er_data + ei->ei_size + + ea_size - 1, + &c, 1); + } + + ei->ei_size += ea_size; + + return 0; +} + +/** + * gfs_ea_list - + * @ip: + * @er: + * + * Returns: actual size of data on success, -errno on error + */ + +int +gfs_ea_list(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_data || !er->er_data_len) { + er->er_data = NULL; + er->er_data_len = 0; + } + + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + return error; + + if (ip->i_di.di_eattr) { + struct ea_list ei = { .ei_er = er, .ei_size = 0 }; + + error = ea_foreach(ip, ea_list_i, &ei); + if (!error) + error = ei.ei_size; + } + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * ea_get_unstuffed - actually copies the unstuffed data into the + * request buffer + * @ip: + * @ea: + * @data: + * + * Returns: errno + */ + +static int +ea_get_unstuffed(struct gfs_inode *ip, struct gfs_ea_header *ea, + char *data) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head **bh; + unsigned int amount = GFS_EA_DATA_LEN(ea); + unsigned int nptrs = DIV_RU(amount, sdp->sd_jbsize); + uint64_t *dataptrs = GFS_EA2DATAPTRS(ea); + unsigned int x; + int error = 0; + + bh = kmalloc(nptrs * sizeof(struct buffer_head *), GFP_KERNEL); + if (!bh) + return -ENOMEM; + + for (x = 0; x < nptrs; x++) { + error = gfs_dread(ip->i_gl, gfs64_to_cpu(*dataptrs), + DIO_START, bh + x); + if (error) { + while (x--) + brelse(bh[x]); + goto out; + } + dataptrs++; + } + + for (x = 0; x < nptrs; x++) { + error = gfs_dreread(sdp, bh[x], DIO_WAIT); + if (error) { + for (; x < nptrs; x++) + brelse(bh[x]); + goto out; + } + if (gfs_metatype_check2(sdp, bh[x], + GFS_METATYPE_ED, GFS_METATYPE_EA)) { + for (; x < nptrs; x++) + brelse(bh[x]); + error = -EIO; + goto out; + } + + memcpy(data, + bh[x]->b_data + sizeof(struct gfs_meta_header), + (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); + + amount -= sdp->sd_jbsize; + data += sdp->sd_jbsize; + + brelse(bh[x]); + } + + out: + kfree(bh); + + return error; +} + +/** + * gfs_ea_get_copy - + * @ip: + * @el: + * @data: + * + * Returns: errno + */ + +int +gfs_ea_get_copy(struct gfs_inode *ip, + struct gfs_ea_location *el, + char *data) +{ + if (GFS_EA_IS_STUFFED(el->el_ea)) { + memcpy(data, + GFS_EA2DATA(el->el_ea), + GFS_EA_DATA_LEN(el->el_ea)); + return 0; + } else + return ea_get_unstuffed(ip, el->el_ea, data); +} + +/** + * gfs_ea_get_i - + * @ip: + * @er: + * + * Returns: actual size of data on success, -errno on error + */ + +int +gfs_ea_get_i(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) + return -ENODATA; + + error = gfs_ea_find(ip, er, &el); + if (error) + return error; + if (!el.el_ea) + return -ENODATA; + + if (er->er_data_len) { + if (GFS_EA_DATA_LEN(el.el_ea) > er->er_data_len) + error = -ERANGE; + else + error = gfs_ea_get_copy(ip, &el, er->er_data); + } + if (!error) + error = GFS_EA_DATA_LEN(el.el_ea); + + brelse(el.el_bh); + + return error; +} + +/** + * gfs_ea_get - + * @ip: + * @er: + * + * Returns: actual size of data on success, -errno on error + */ + +int +gfs_ea_get(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_name_len || + er->er_name_len > GFS_EA_MAX_NAME_LEN) + return -EINVAL; + if (!er->er_data || !er->er_data_len) { + er->er_data = NULL; + er->er_data_len = 0; + } + + error = gfs_glock_nq_init(ip->i_gl, + LM_ST_SHARED, LM_FLAG_ANY, + &i_gh); + if (error) + return error; + + error = gfs_ea_ops[er->er_type]->eo_get(ip, er); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * ea_alloc_blk - allocates a new block for extended attributes. + * @ip: A pointer to the inode that's getting extended attributes + * @bhp: + * + * Returns: errno + */ + +static int +ea_alloc_blk(struct gfs_inode *ip, + struct buffer_head **bhp) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_ea_header *ea; + uint64_t block; + int error; + + error = gfs_metaalloc(ip, &block); + if (error) + return error; + + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, bhp); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, *bhp); + gfs_metatype_set(*bhp, GFS_METATYPE_EA, GFS_FORMAT_EA); + + ea = GFS_EA_BH2FIRST(*bhp); + ea->ea_rec_len = cpu_to_gfs32(sdp->sd_jbsize); + ea->ea_type = GFS_EATYPE_UNUSED; + ea->ea_flags = GFS_EAFLAG_LAST; + ea->ea_num_ptrs = 0; + + ip->i_di.di_blocks++; + + return 0; +} + +/** + * ea_write - writes the request info to an ea, creating new blocks if + * necessary + * @ip: inode that is being modified + * @ea: the location of the new ea in a block + * @er: the write request + * + * Note: does not update ea_rec_len or the GFS_EAFLAG_LAST bin of ea_flags + * + * returns : errno + */ + +static int +ea_write(struct gfs_inode *ip, + struct gfs_ea_header *ea, + struct gfs_ea_request *er) +{ + struct gfs_sbd *sdp = ip->i_sbd; + + ea->ea_data_len = cpu_to_gfs32(er->er_data_len); + ea->ea_name_len = er->er_name_len; + ea->ea_type = er->er_type; + ea->ea_pad = 0; + + memcpy(GFS_EA2NAME(ea), er->er_name, er->er_name_len); + + if (GFS_EAREQ_SIZE_STUFFED(er) <= sdp->sd_jbsize) { + ea->ea_num_ptrs = 0; + memcpy(GFS_EA2DATA(ea), er->er_data, er->er_data_len); + } else { + uint64_t *dataptr = GFS_EA2DATAPTRS(ea); + const char *data = er->er_data; + unsigned int data_len = er->er_data_len; + unsigned int copy; + unsigned int x; + + ea->ea_num_ptrs = DIV_RU(er->er_data_len, sdp->sd_jbsize); + for (x = 0; x < ea->ea_num_ptrs; x++) { + struct buffer_head *bh; + uint64_t block; + int error; + + error = gfs_metaalloc(ip, &block); + if (error) + return error; + + error = gfs_dread(ip->i_gl, block, + DIO_NEW | DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, bh); + gfs_metatype_set(bh, GFS_METATYPE_ED, GFS_FORMAT_ED); + ip->i_di.di_blocks++; + + copy = (data_len > sdp->sd_jbsize) ? sdp->sd_jbsize : data_len; + memcpy(bh->b_data + sizeof(struct gfs_meta_header), + data, + copy); + + *dataptr++ = cpu_to_gfs64((uint64_t)bh->b_blocknr); + data += copy; + data_len -= copy; + + brelse(bh); + } + + gfs_assert_withdraw(sdp, !data_len); + } + + return 0; +} + +typedef int (*ea_skeleton_call_t) (struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private); +/** + * ea_alloc_skeleton - + * @ip: + * @er: + * @blks: + * @skeleton_call: + * @private: + * + * Returns: errno + */ + +static int +ea_alloc_skeleton(struct gfs_inode *ip, struct gfs_ea_request *er, + unsigned int blks, + ea_skeleton_call_t skeleton_call, void *private) +{ + struct gfs_alloc *al; + struct buffer_head *dibh; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto out_gunlock_q; + + al->al_requested_meta = blks; + + error = gfs_inplace_reserve(ip); + if (error) + goto out_gunlock_q; + + /* Trans may require: + A modified dinode, multiple EA metadata blocks, and all blocks for a RG + bitmap */ + + error = gfs_trans_begin(ip->i_sbd, + 1 + blks + al->al_rgd->rd_ri.ri_length, 1); + if (error) + goto out_ipres; + + error = skeleton_call(ip, er, private); + if (error) + goto out_end_trans; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + if (er->er_mode) { + ip->i_vnode->i_mode = er->er_mode; + gfs_inode_attr_out(ip); + } + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + out_end_trans: + gfs_trans_end(ip->i_sbd); + + out_ipres: + gfs_inplace_release(ip); + + out_gunlock_q: + gfs_quota_unlock_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * ea_init_i - initializes a new eattr block + * @ip: + * @er: + * @private: + * + * Returns: errno + */ + +static int +ea_init_i(struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private) +{ + struct buffer_head *bh; + int error; + + error = ea_alloc_blk(ip, &bh); + if (error) + return error; + + ip->i_di.di_eattr = bh->b_blocknr; + error = ea_write(ip, GFS_EA_BH2FIRST(bh), er); + + brelse(bh); + + return error; +} + +/** + * ea_init - initializes a new eattr block + * @ip: + * @er: + * + * Returns: errno + */ + +static int +ea_init(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + unsigned int jbsize = ip->i_sbd->sd_jbsize; + unsigned int blks = 1; + + if (GFS_EAREQ_SIZE_STUFFED(er) > jbsize) + blks += DIV_RU(er->er_data_len, jbsize); + + return ea_alloc_skeleton(ip, er, + blks, + ea_init_i, NULL); +} + +/** + * ea_split_ea - + * @ea: + * + * Returns: the new ea + */ + +static struct gfs_ea_header * +ea_split_ea(struct gfs_ea_header *ea) +{ + uint32_t ea_size = GFS_EA_SIZE(ea); + struct gfs_ea_header *new = (struct gfs_ea_header *)((char *)ea + ea_size); + uint32_t new_size = GFS_EA_REC_LEN(ea) - ea_size; + int last = ea->ea_flags & GFS_EAFLAG_LAST; + + ea->ea_rec_len = cpu_to_gfs32(ea_size); + ea->ea_flags ^= last; + + new->ea_rec_len = cpu_to_gfs32(new_size); + new->ea_flags = last; + + return new; +} + +/** + * ea_set_remove_stuffed - + * @ip: + * @ea: + * + */ + +static void +ea_set_remove_stuffed(struct gfs_inode *ip, struct gfs_ea_location *el) +{ + struct gfs_ea_header *ea = el->el_ea; + struct gfs_ea_header *prev = el->el_prev; + uint32_t len; + + gfs_trans_add_bh(ip->i_gl, el->el_bh); + + if (!prev || !GFS_EA_IS_STUFFED(ea)) { + ea->ea_type = GFS_EATYPE_UNUSED; + return; + } else if (GFS_EA2NEXT(prev) != ea) { + prev = GFS_EA2NEXT(prev); + gfs_assert_withdraw(ip->i_sbd, GFS_EA2NEXT(prev) == ea); + } + + len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); + prev->ea_rec_len = cpu_to_gfs32(len); + + if (GFS_EA_IS_LAST(ea)) + prev->ea_flags |= GFS_EAFLAG_LAST; +} + +struct ea_set { + int ea_split; + + struct gfs_ea_request *es_er; + struct gfs_ea_location *es_el; + + struct buffer_head *es_bh; + struct gfs_ea_header *es_ea; +}; + +/** + * ea_set_simple_noalloc - + * @ip: + * @ea: + * @es: + * + * Returns: errno + */ + +static int +ea_set_simple_noalloc(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct ea_set *es) +{ + struct gfs_ea_request *er = es->es_er; + int error; + + error = gfs_trans_begin(ip->i_sbd, 3, 0); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, bh); + + if (es->ea_split) + ea = ea_split_ea(ea); + + ea_write(ip, ea, er); + + if (es->es_el) + ea_set_remove_stuffed(ip, es->es_el); + + { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + if (er->er_mode) { + ip->i_vnode->i_mode = er->er_mode; + gfs_inode_attr_out(ip); + } + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + } + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * ea_set_simple_alloc - + * @ip: + * @er: + * @private: + * + * Returns: errno + */ + +static int +ea_set_simple_alloc(struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private) +{ + struct ea_set *es = (struct ea_set *)private; + struct gfs_ea_header *ea = es->es_ea; + int error; + + gfs_trans_add_bh(ip->i_gl, es->es_bh); + + if (es->ea_split) + ea = ea_split_ea(ea); + + error = ea_write(ip, ea, er); + if (error) + return error; + + if (es->es_el) + ea_set_remove_stuffed(ip, es->es_el); + + return 0; +} + +/** + * ea_set_simple - + * @ip: + * @el: + * + * Returns: errno + */ + +static int +ea_set_simple(struct gfs_inode *ip, + struct buffer_head *bh, + struct gfs_ea_header *ea, + struct gfs_ea_header *prev, + void *private) +{ + struct ea_set *es = (struct ea_set *)private; + unsigned int size; + int stuffed; + int error; + + stuffed = ea_calc_size(ip->i_sbd, es->es_er, &size); + + if (ea->ea_type == GFS_EATYPE_UNUSED) { + if (GFS_EA_REC_LEN(ea) < size) + return 0; + if (!GFS_EA_IS_STUFFED(ea)) { + error = ea_remove_unstuffed(ip, bh, ea, prev, TRUE); + if (error) + return error; + } + es->ea_split = FALSE; + } else if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) + es->ea_split = TRUE; + else + return 0; + + if (stuffed) { + error = ea_set_simple_noalloc(ip, bh, ea, es); + if (error) + return error; + } else { + unsigned int blks; + + es->es_bh = bh; + es->es_ea = ea; + blks = 2 + DIV_RU(es->es_er->er_data_len, + ip->i_sbd->sd_jbsize); + + error = ea_alloc_skeleton(ip, es->es_er, + blks, + ea_set_simple_alloc, es); + if (error) + return error; + } + + return 1; +} + +/** + * ea_set_block - + * @ip: + * @er: + * @private: + * + * Returns: errno + */ + +static int +ea_set_block(struct gfs_inode *ip, + struct gfs_ea_request *er, + void *private) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head *indbh, *newbh; + uint64_t *eablk; + int error; + + if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { + uint64_t *end; + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &indbh); + if (error) + return error; + + if (gfs_metatype_check(sdp, indbh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + end = eablk + sdp->sd_inptrs; + + for (; eablk < end; eablk++) + if (!*eablk) + break; + + if (eablk == end) { + error = -ENOSPC; + goto out; + } + + gfs_trans_add_bh(ip->i_gl, indbh); + } else { + uint64_t blk; + + error = gfs_metaalloc(ip, &blk); + if (error) + return error; + + error = gfs_dread(ip->i_gl, blk, + DIO_NEW | DIO_START | DIO_WAIT, &indbh); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, indbh); + gfs_metatype_set(indbh, GFS_METATYPE_IN, GFS_FORMAT_IN); + gfs_buffer_clear_tail(indbh, sizeof(struct gfs_meta_header)); + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + *eablk = cpu_to_gfs64(ip->i_di.di_eattr); + ip->i_di.di_eattr = blk; + ip->i_di.di_flags |= GFS_DIF_EA_INDIRECT; + ip->i_di.di_blocks++; + + eablk++; + } + + error = ea_alloc_blk(ip, &newbh); + if (error) + goto out; + + *eablk = cpu_to_gfs64((uint64_t)newbh->b_blocknr); + error = ea_write(ip, GFS_EA_BH2FIRST(newbh), er); + brelse(newbh); + if (error) + goto out; + + if (private) + ea_set_remove_stuffed(ip, (struct gfs_ea_location *)private); + + out: + brelse(indbh); + + return error; +} + +/** + * ea_set_i - + * @ip: + * @el: + * + * Returns: errno + */ + +static int +ea_set_i(struct gfs_inode *ip, + struct gfs_ea_request *er, + struct gfs_ea_location *el) +{ + { + struct ea_set es; + int error; + + memset(&es, 0, sizeof(struct ea_set)); + es.es_er = er; + es.es_el = el; + + error = ea_foreach(ip, ea_set_simple, &es); + if (error > 0) + return 0; + if (error) + return error; + } + { + unsigned int blks = 2; + if (!(ip->i_di.di_flags & GFS_DIF_EA_INDIRECT)) + blks++; + if (GFS_EAREQ_SIZE_STUFFED(er) > ip->i_sbd->sd_jbsize) + blks += DIV_RU(er->er_data_len, + ip->i_sbd->sd_jbsize); + + return ea_alloc_skeleton(ip, er, blks, ea_set_block, el); + } +} + +/** + * ea_set_remove_unstuffed - + * @ip: + * @el: + * + * Returns: errno + */ + +static int +ea_set_remove_unstuffed(struct gfs_inode *ip, struct gfs_ea_location *el) +{ + if (el->el_prev && GFS_EA2NEXT(el->el_prev) != el->el_ea) { + el->el_prev = GFS_EA2NEXT(el->el_prev); + gfs_assert_withdraw(ip->i_sbd, + GFS_EA2NEXT(el->el_prev) == el->el_ea); + } + + return ea_remove_unstuffed(ip, el->el_bh, el->el_ea, el->el_prev, FALSE); +} + +/** + * gfs_ea_set_i - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_set_i(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) { + if (er->er_flags & XATTR_REPLACE) + return -ENODATA; + return ea_init(ip, er); + } + + error = gfs_ea_find(ip, er, &el); + if (error) + return error; + + if (el.el_ea) { + if (IS_APPEND(ip->i_vnode)) { + brelse(el.el_bh); + return -EPERM; + } + + error = -EEXIST; + if (!(er->er_flags & XATTR_CREATE)) { + int unstuffed = !GFS_EA_IS_STUFFED(el.el_ea); + error = ea_set_i(ip, er, &el); + if (!error && unstuffed) + ea_set_remove_unstuffed(ip, &el); + } + + brelse(el.el_bh); + } else { + error = -ENODATA; + if (!(er->er_flags & XATTR_REPLACE)) + error = ea_set_i(ip, er, NULL); + } + + return error; +} + +/** + * gfs_ea_set - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_set(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_name_len || + er->er_name_len > GFS_EA_MAX_NAME_LEN) + return -EINVAL; + if (!er->er_data || !er->er_data_len) { + er->er_data = NULL; + er->er_data_len = 0; + } + error = gfs_ea_check_size(ip->i_sbd, er); + if (error) + return error; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + if (IS_IMMUTABLE(ip->i_vnode)) + error = -EPERM; + else + error = gfs_ea_ops[er->er_type]->eo_set(ip, er); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * ea_remove_stuffed - + * @ip: + * @el: + * @mode: + * + * Returns: errno + */ + +static int +ea_remove_stuffed(struct gfs_inode *ip, + struct gfs_ea_location *el) +{ + struct gfs_ea_header *ea = el->el_ea; + struct gfs_ea_header *prev = el->el_prev; + int error; + + error = gfs_trans_begin(ip->i_sbd, 2, 0); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, el->el_bh); + + if (prev) { + uint32_t len; + + len = GFS_EA_REC_LEN(prev) + GFS_EA_REC_LEN(ea); + prev->ea_rec_len = cpu_to_gfs32(len); + + if (GFS_EA_IS_LAST(ea)) + prev->ea_flags |= GFS_EAFLAG_LAST; + } else + ea->ea_type = GFS_EATYPE_UNUSED; + + { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + ip->i_di.di_ctime = get_seconds(); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + } + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * gfs_ea_remove_i - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_remove_i(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_ea_location el; + int error; + + if (!ip->i_di.di_eattr) + return -ENODATA; + + error = gfs_ea_find(ip, er, &el); + if (error) + return error; + if (!el.el_ea) + return -ENODATA; + + if (GFS_EA_IS_STUFFED(el.el_ea)) + error = ea_remove_stuffed(ip, &el); + else + error = ea_remove_unstuffed(ip, el.el_bh, el.el_ea, el.el_prev, FALSE); + + brelse(el.el_bh); + + return error; +} + +/** + * gfs_ea_remove - sets (or creates or replaces) an extended attribute + * @ip: pointer to the inode of the target file + * @er: request information + * + * Returns: errno + */ + +int +gfs_ea_remove(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + struct gfs_holder i_gh; + int error; + + if (!er->er_name_len || + er->er_name_len > GFS_EA_MAX_NAME_LEN) + return -EINVAL; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode)) + error = -EPERM; + else + error = gfs_ea_ops[er->er_type]->eo_remove(ip, er); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_ea_acl_init - + * @ip: + * @er: + * + * Returns: errno + */ + +int +gfs_ea_acl_init(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + int error; + + if (!ip->i_di.di_eattr) + return ea_init_i(ip, er, NULL); + + { + struct buffer_head *bh; + struct gfs_ea_header *ea; + unsigned int size; + + ea_calc_size(ip->i_sbd, er, &size); + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_EA)) { + brelse(bh); + return -EIO; + } + + ea = GFS_EA_BH2FIRST(bh); + if (GFS_EA_REC_LEN(ea) - GFS_EA_SIZE(ea) >= size) { + ea = ea_split_ea(ea); + ea_write(ip, ea, er); + brelse(bh); + return 0; + } + + brelse(bh); + } + + error = ea_set_block(ip, er, NULL); + gfs_assert_withdraw(ip->i_sbd, error != -ENOSPC); + if (error) + return error; + + { + struct buffer_head *dibh; + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + return error; +} + +/** + * ea_acl_chmod_unstuffed - + * @ip: + * @ea: + * @data: + * + * Returns: errno + */ + +static int +ea_acl_chmod_unstuffed(struct gfs_inode *ip, + struct gfs_ea_header *ea, + char *data) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct buffer_head **bh; + unsigned int amount = GFS_EA_DATA_LEN(ea); + unsigned int nptrs = DIV_RU(amount, sdp->sd_jbsize); + uint64_t *dataptrs = GFS_EA2DATAPTRS(ea); + unsigned int x; + int error; + + bh = kmalloc(nptrs * sizeof(struct buffer_head *), GFP_KERNEL); + if (!bh) + return -ENOMEM; + + error = gfs_trans_begin(sdp, 1 + nptrs, 0); + if (error) + goto out; + + for (x = 0; x < nptrs; x++) { + error = gfs_dread(ip->i_gl, gfs64_to_cpu(*dataptrs), + DIO_START, bh + x); + if (error) { + while (x--) + brelse(bh[x]); + goto fail; + } + dataptrs++; + } + + for (x = 0; x < nptrs; x++) { + error = gfs_dreread(sdp, bh[x], DIO_WAIT); + if (error) { + for (; x < nptrs; x++) + brelse(bh[x]); + goto fail; + } + if (gfs_metatype_check2(sdp, bh[x], + GFS_METATYPE_ED, GFS_METATYPE_EA)) { + for (; x < nptrs; x++) + brelse(bh[x]); + error = -EIO; + goto fail; + } + + gfs_trans_add_bh(ip->i_gl, bh[x]); + + memcpy(bh[x]->b_data + sizeof(struct gfs_meta_header), + data, + (sdp->sd_jbsize > amount) ? amount : sdp->sd_jbsize); + + amount -= sdp->sd_jbsize; + data += sdp->sd_jbsize; + + brelse(bh[x]); + } + + out: + kfree(bh); + + return error; + + fail: + gfs_trans_end(sdp); + kfree(bh); + + return error; +} + +/** + * gfs_ea_acl_chmod - + * @ip: + * @el: + * @attr: + * @data: + * + * Returns: errno + */ + +int +gfs_ea_acl_chmod(struct gfs_inode *ip, struct gfs_ea_location *el, + struct iattr *attr, char *data) +{ + struct buffer_head *dibh; + int error; + + if (GFS_EA_IS_STUFFED(el->el_ea)) { + error = gfs_trans_begin(ip->i_sbd, 2, 0); + if (error) + return error; + + gfs_trans_add_bh(ip->i_gl, el->el_bh); + memcpy(GFS_EA2DATA(el->el_ea), + data, + GFS_EA_DATA_LEN(el->el_ea)); + } else + error = ea_acl_chmod_unstuffed(ip, el->el_ea, data); + + if (error) + return error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + error = inode_setattr(ip->i_vnode, attr); + gfs_assert_warn(ip->i_sbd, !error); + gfs_inode_attr_out(ip); + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * ea_dealloc_indirect - + * @ip: + * + * Returns: errno + */ + +static int +ea_dealloc_indirect(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_rgrp_list rlist; + struct buffer_head *indbh, *dibh; + uint64_t *eablk, *end; + unsigned int rg_blocks = 0; + uint64_t bstart = 0; + unsigned int blen = 0; + unsigned int x; + int error; + + memset(&rlist, 0, sizeof(struct gfs_rgrp_list)); + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &indbh); + if (error) + return error; + + if (gfs_metatype_check(sdp, indbh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + end = eablk + sdp->sd_inptrs; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + bstart = bn; + blen = 1; + } + } + if (bstart) + gfs_rlist_add(sdp, &rlist, bstart); + else + goto out; + + gfs_rlist_alloc(&rlist, LM_ST_EXCLUSIVE, 0); + + for (x = 0; x < rlist.rl_rgrps; x++) { + struct gfs_rgrpd *rgd; + rgd = get_gl2rgd(rlist.rl_ghs[x].gh_gl); + rg_blocks += rgd->rd_ri.ri_length; + } + + error = gfs_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); + if (error) + goto out_rlist_free; + + error = gfs_trans_begin(sdp, 2 + rg_blocks, 1); + if (error) + goto out_gunlock; + + gfs_trans_add_bh(ip->i_gl, indbh); + + eablk = (uint64_t *)(indbh->b_data + sizeof(struct gfs_indirect)); + bstart = 0; + blen = 0; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + if (bstart + blen == bn) + blen++; + else { + if (bstart) + gfs_metafree(ip, bstart, blen); + bstart = bn; + blen = 1; + } + + *eablk = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + } + if (bstart) + gfs_metafree(ip, bstart, blen); + + ip->i_di.di_flags &= ~GFS_DIF_EA_INDIRECT; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + out_gunlock: + gfs_glock_dq_m(rlist.rl_rgrps, rlist.rl_ghs); + + out_rlist_free: + gfs_rlist_free(&rlist); + + out: + brelse(indbh); + + return error; +} + +/** + * ea_dealloc_block - + * @ip: + * + * Returns: errno + */ + +static int +ea_dealloc_block(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al = ip->i_alloc; + struct gfs_rgrpd *rgd; + struct buffer_head *dibh; + int error; + + rgd = gfs_blk2rgrpd(sdp, ip->i_di.di_eattr); + if (!rgd) { + gfs_consist_inode(ip); + return -EIO; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &al->al_rgd_gh); + if (error) + return error; + + error = gfs_trans_begin(sdp, 1 + rgd->rd_ri.ri_length, 1); + if (error) + goto out_gunlock; + + gfs_metafree(ip, ip->i_di.di_eattr, 1); + + ip->i_di.di_eattr = 0; + if (!ip->i_di.di_blocks) + gfs_consist_inode(ip); + ip->i_di.di_blocks--; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + gfs_trans_end(sdp); + + out_gunlock: + gfs_glock_dq_uninit(&al->al_rgd_gh); + + return error; +} + +/** + * gfs_ea_dealloc - deallocate the extended attribute fork + * @ip: the inode + * + * Returns: errno + */ + +int +gfs_ea_dealloc(struct gfs_inode *ip) +{ + struct gfs_alloc *al; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out_alloc; + + error = gfs_rindex_hold(ip->i_sbd, &al->al_ri_gh); + if (error) + goto out_quota; + + error = ea_foreach(ip, ea_dealloc_unstuffed, NULL); + if (error) + goto out_rindex; + + if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { + error = ea_dealloc_indirect(ip); + if (error) + goto out_rindex; + } + + error = ea_dealloc_block(ip); + + out_rindex: + gfs_glock_dq_uninit(&al->al_ri_gh); + + out_quota: + gfs_quota_unhold_m(ip); + + out_alloc: + gfs_alloc_put(ip); + + return error; +} + +/** + * gfs_get_eattr_meta - return all the eattr blocks of a file + * @dip: the directory + * @ub: the structure representing the user buffer to copy to + * + * Returns: errno + */ + +int +gfs_get_eattr_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub) +{ + struct buffer_head *bh; + int error; + + error = gfs_dread(ip->i_gl, ip->i_di.di_eattr, + DIO_START | DIO_WAIT, &bh); + if (error) + return error; + + gfs_add_bh_to_ub(ub, bh); + + if (ip->i_di.di_flags & GFS_DIF_EA_INDIRECT) { + struct buffer_head *eabh; + uint64_t *eablk, *end; + + if (gfs_metatype_check(ip->i_sbd, bh, GFS_METATYPE_IN)) { + error = -EIO; + goto out; + } + + eablk = (uint64_t *)(bh->b_data + sizeof(struct gfs_indirect)); + end = eablk + ip->i_sbd->sd_inptrs; + + for (; eablk < end; eablk++) { + uint64_t bn; + + if (!*eablk) + break; + bn = gfs64_to_cpu(*eablk); + + error = gfs_dread(ip->i_gl, bn, + DIO_START | DIO_WAIT, &eabh); + if (error) + break; + gfs_add_bh_to_ub(ub, eabh); + brelse(eabh); + if (error) + break; + } + } + + out: + brelse(bh); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/lops.h +++ linux-2.6.28/ubuntu/gfs/lops.h @@ -0,0 +1,166 @@ +#ifndef __LOPS_DOT_H__ +#define __LOPS_DOT_H__ + +extern struct gfs_log_operations gfs_glock_lops; +extern struct gfs_log_operations gfs_buf_lops; +extern struct gfs_log_operations gfs_unlinked_lops; +extern struct gfs_log_operations gfs_quota_lops; + +extern struct gfs_log_operations *gfs_log_ops[]; + +#define INIT_LE(le, lops) \ +do \ +{ \ + (le)->le_ops = (lops); \ + (le)->le_trans = NULL; \ + INIT_LIST_HEAD(&(le)->le_list); \ +} \ +while (0) + +#define LO_ADD(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_add) \ + (le)->le_ops->lo_add((sdp), (le)); \ +} \ +while (0) + +#define LO_TRANS_END(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_trans_end) \ + (le)->le_ops->lo_trans_end((sdp), (le)); \ +} \ +while (0) + +#define LO_PRINT(sdp, le, where) \ +do \ +{ \ + if ((le)->le_ops->lo_print) \ + (le)->le_ops->lo_print((sdp), (le), (where)); \ +} \ +while (0) + +static __inline__ struct gfs_trans * +LO_OVERLAP_TRANS(struct gfs_sbd *sdp, struct gfs_log_element *le) +{ + if (le->le_ops->lo_overlap_trans) + return le->le_ops->lo_overlap_trans(sdp, le); + else + return NULL; +} + +#define LO_INCORE_COMMIT(sdp, tr, le) \ +do \ +{ \ + if ((le)->le_ops->lo_incore_commit) \ + (le)->le_ops->lo_incore_commit((sdp), (tr), (le)); \ +} \ +while (0) + +#define LO_ADD_TO_AIL(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_add_to_ail) \ + (le)->le_ops->lo_add_to_ail((sdp), (le)); \ +} \ +while (0) + +#define LO_CLEAN_DUMP(sdp, le) \ +do \ +{ \ + if ((le)->le_ops->lo_clean_dump) \ + (le)->le_ops->lo_clean_dump((sdp), (le)); \ +} \ +while (0) + +#define LO_TRANS_SIZE(sdp, tr, mblks, eblks, blocks, bmem) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_trans_size) \ + gfs_log_ops[__lops_x]->lo_trans_size((sdp), (tr), (mblks), (eblks), (blocks), (bmem)); \ +} \ +while (0) + +#define LO_TRANS_COMBINE(sdp, tr, new_tr) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_trans_combine) \ + gfs_log_ops[__lops_x]->lo_trans_combine((sdp), (tr), (new_tr)); \ +} \ +while (0) + +#define LO_BUILD_BHLIST(sdp, tr) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_build_bhlist) \ + gfs_log_ops[__lops_x]->lo_build_bhlist((sdp), (tr)); \ +} \ +while (0) + +#define LO_DUMP_SIZE(sdp, elements, blocks, bmem) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_dump_size) \ + gfs_log_ops[__lops_x]->lo_dump_size((sdp), (elements), (blocks), (bmem)); \ +} \ +while (0) + +#define LO_BUILD_DUMP(sdp, tr) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_build_dump) \ + gfs_log_ops[__lops_x]->lo_build_dump((sdp), (tr)); \ +} \ +while (0) + +#define LO_BEFORE_SCAN(sdp, jid, head, pass) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_before_scan) \ + gfs_log_ops[__lops_x]->lo_before_scan((sdp), (jid), (head), (pass)); \ +} \ +while (0) + +static __inline__ int +LO_SCAN_ELEMENTS(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t start, + struct gfs_log_descriptor *desc, unsigned int pass) +{ + int x; + int error; + + for (x = 0; gfs_log_ops[x]; x++) + if (gfs_log_ops[x]->lo_scan_elements) { + error = gfs_log_ops[x]->lo_scan_elements(sdp, jdesc, gl, + start, desc, pass); + if (error) + return error; + } + + return 0; +} + +#define LO_AFTER_SCAN(sdp, jid, pass) \ +do \ +{ \ + int __lops_x; \ + for (__lops_x = 0; gfs_log_ops[__lops_x]; __lops_x++) \ + if (gfs_log_ops[__lops_x]->lo_after_scan) \ + gfs_log_ops[__lops_x]->lo_after_scan((sdp), (jid), (pass)); \ +} \ +while (0) + +#endif /* __LOPS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_inode.h +++ linux-2.6.28/ubuntu/gfs/ops_inode.h @@ -0,0 +1,9 @@ +#ifndef __OPS_INODE_DOT_H__ +#define __OPS_INODE_DOT_H__ + +extern struct inode_operations gfs_file_iops; +extern struct inode_operations gfs_dir_iops; +extern struct inode_operations gfs_symlink_iops; +extern struct inode_operations gfs_dev_iops; + +#endif /* __OPS_INODE_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/daemon.c +++ linux-2.6.28/ubuntu/gfs/daemon.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "daemon.h" +#include "glock.h" +#include "log.h" +#include "quota.h" +#include "recovery.h" +#include "super.h" +#include "unlinked.h" + +/** + * gfs_scand - Look for cached glocks and inodes to toss from memory + * @sdp: Pointer to GFS superblock + * + * One of these daemons runs, finding candidates to add to sd_reclaim_list. + * See gfs_glockd() + */ + +int +gfs_scand(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + gfs_scand_internal(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_scand_secs) * HZ); + } + + return 0; +} + +/** + * gfs_glockd - Reclaim unused glock structures + * @sdp: Pointer to GFS superblock + * + * One or more of these daemons run, reclaiming glocks on sd_reclaim_list. + * sd_glockd_num says how many daemons are running now. + * Number of daemons can be set by user, with num_glockd mount option. + * See gfs_scand() + */ + +int +gfs_glockd(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + while (atomic_read(&sdp->sd_reclaim_count)) + gfs_reclaim_glock(sdp); + + wait_event_interruptible(sdp->sd_reclaim_wchan, + (atomic_read(&sdp->sd_reclaim_count) || + kthread_should_stop())); + } + + return 0; +} + +/** + * gfs_recoverd - Recover dead machine's journals + * @sdp: Pointer to GFS superblock + * + */ + +int +gfs_recoverd(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + gfs_check_journals(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_recoverd_secs) * HZ); + } + + return 0; +} + +/** + * gfs_logd - Update log tail as Active Items get flushed to in-place blocks + * @sdp: Pointer to GFS superblock + * + * Also, periodically check to make sure that we're using the most recent + * journal index. + */ + +int +gfs_logd(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + struct gfs_holder ji_gh; + + while (!kthread_should_stop()) { + /* Advance the log tail */ + gfs_ail_empty(sdp); + + /* Check for latest journal index */ + if (time_after_eq(jiffies, + sdp->sd_jindex_refresh_time + + gfs_tune_get(sdp, gt_jindex_refresh_secs) * HZ)) { + if (test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags) && + !gfs_jindex_hold(sdp, &ji_gh)) + gfs_glock_dq_uninit(&ji_gh); + sdp->sd_jindex_refresh_time = jiffies; + } + + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_logd_secs) * HZ); + } + + return 0; +} + +/** + * gfs_quotad - Write cached quota changes into the quota file + * @sdp: Pointer to GFS superblock + * + */ + +int +gfs_quotad(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + int error; + + while (!kthread_should_stop()) { + /* Update statfs file */ + if (gfs_tune_get(sdp, gt_statfs_fast) && + time_after_eq(jiffies, + sdp->sd_statfs_sync_time + + gfs_tune_get(sdp, gt_statfs_fast) * HZ)) { + error = gfs_statfs_sync(sdp); + if (error && error != -EROFS && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + printk("GFS: fsid=%s: statfs: error = %d\n", + sdp->sd_fsname, error); + sdp->sd_statfs_sync_time = jiffies; + } + /* Update quota file */ + if (time_after_eq(jiffies, + sdp->sd_quota_sync_time + + gfs_tune_get(sdp, gt_quota_quantum) * HZ)) { + error = gfs_quota_sync(sdp); + if (error && + error != -EROFS && + !test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + printk("GFS: fsid=%s: quotad: error = %d\n", + sdp->sd_fsname, error); + sdp->sd_quota_sync_time = jiffies; + } + + /* Clean up */ + gfs_quota_scan(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_quotad_secs) * HZ); + } + + return 0; +} + +/** + * gfs_inoded - Deallocate unlinked inodes + * @sdp: Pointer to GFS superblock + * + */ + +int +gfs_inoded(void *data) +{ + struct gfs_sbd *sdp = (struct gfs_sbd *)data; + + while (!kthread_should_stop()) { + gfs_unlinked_dealloc(sdp); + schedule_timeout_interruptible(gfs_tune_get(sdp, gt_inoded_secs) * HZ); + } + + return 0; +} --- linux-2.6.28.orig/ubuntu/gfs/recovery.h +++ linux-2.6.28/ubuntu/gfs/recovery.h @@ -0,0 +1,23 @@ +#ifndef __RECOVERY_DOT_H__ +#define __RECOVERY_DOT_H__ + +#define GFS_RECPASS_A1 (12) +#define GFS_RECPASS_B1 (14) + +void gfs_add_dirty_j(struct gfs_sbd *sdp, unsigned int jid); +void gfs_clear_dirty_j(struct gfs_sbd *sdp); + +int gfs_find_jhead(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, struct gfs_log_header *head); +int gfs_increment_blkno(struct gfs_sbd *sdp, struct gfs_jindex *jdesc, + struct gfs_glock *gl, uint64_t *addr, + int skip_headers); + +int gfs_recover_journal(struct gfs_sbd *sdp, + unsigned int jid, struct gfs_jindex *jdesc, + int wait); +void gfs_check_journals(struct gfs_sbd *sdp); + +int gfs_recover_dump(struct gfs_sbd *sdp); + +#endif /* __RECOVERY_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/ops_fstype.c +++ linux-2.6.28/ubuntu/gfs/ops_fstype.c @@ -0,0 +1,816 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "daemon.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "lm.h" +#include "mount.h" +#include "ops_export.h" +#include "ops_fstype.h" +#include "ops_super.h" +#include "proc.h" +#include "quota.h" +#include "recovery.h" +#include "rgrp.h" +#include "super.h" +#include "sys.h" +#include "unlinked.h" + +#define DO 0 +#define UNDO 1 + +extern struct dentry_operations gfs_dops; + +static struct gfs_sbd *init_sbd(struct super_block *sb) +{ + struct gfs_sbd *sdp; + unsigned int x; + + sdp = vmalloc(sizeof(struct gfs_sbd)); + if (!sdp) + return NULL; + + memset(sdp, 0, sizeof(struct gfs_sbd)); + + set_v2sdp(sb, sdp); + sdp->sd_vfs = sb; + gfs_tune_init(&sdp->sd_tune); + + /* Init rgrp variables */ + + INIT_LIST_HEAD(&sdp->sd_rglist); + init_MUTEX(&sdp->sd_rindex_lock); + INIT_LIST_HEAD(&sdp->sd_rg_mru_list); + spin_lock_init(&sdp->sd_rg_mru_lock); + INIT_LIST_HEAD(&sdp->sd_rg_recent); + spin_lock_init(&sdp->sd_rg_recent_lock); + spin_lock_init(&sdp->sd_rg_forward_lock); + + spin_lock_init(&sdp->sd_statfs_spin); + + for (x = 0; x < GFS_GL_HASH_SIZE; x++) { + sdp->sd_gl_hash[x].hb_lock = RW_LOCK_UNLOCKED; + INIT_LIST_HEAD(&sdp->sd_gl_hash[x].hb_list); + } + + INIT_LIST_HEAD(&sdp->sd_reclaim_list); + spin_lock_init(&sdp->sd_reclaim_lock); + init_waitqueue_head(&sdp->sd_reclaim_wchan); + + for (x = 0; x < GFS_MHC_HASH_SIZE; x++) + INIT_LIST_HEAD(&sdp->sd_mhc[x]); + INIT_LIST_HEAD(&sdp->sd_mhc_single); + spin_lock_init(&sdp->sd_mhc_lock); + + for (x = 0; x < GFS_DEPEND_HASH_SIZE; x++) + INIT_LIST_HEAD(&sdp->sd_depend[x]); + spin_lock_init(&sdp->sd_depend_lock); + + init_MUTEX(&sdp->sd_freeze_lock); + + spin_lock_init(&sdp->sd_log_seg_lock); + INIT_LIST_HEAD(&sdp->sd_log_seg_list); + init_waitqueue_head(&sdp->sd_log_seg_wait); + INIT_LIST_HEAD(&sdp->sd_log_ail); + INIT_LIST_HEAD(&sdp->sd_log_incore); + init_rwsem(&sdp->sd_log_lock); + INIT_LIST_HEAD(&sdp->sd_unlinked_list); + spin_lock_init(&sdp->sd_unlinked_lock); + INIT_LIST_HEAD(&sdp->sd_quota_list); + spin_lock_init(&sdp->sd_quota_lock); + + INIT_LIST_HEAD(&sdp->sd_dirty_j); + spin_lock_init(&sdp->sd_dirty_j_lock); + + spin_lock_init(&sdp->sd_ail_lock); + INIT_LIST_HEAD(&sdp->sd_recovery_bufs); + + return sdp; +} + +static void init_vfs(struct super_block *sb, unsigned noatime) +{ + struct gfs_sbd *sdp = sb->s_fs_info; + + /* Set up Linux Virtual (VFS) Super Block */ + + sb->s_magic = GFS_MAGIC; + sb->s_op = &gfs_super_ops; + sb->s_export_op = &gfs_export_ops; + + /* Don't let the VFS update atimes. GFS handles this itself. */ + sb->s_flags |= MS_NOATIME | MS_NODIRATIME; + sb->s_maxbytes = MAX_LFS_FILESIZE; + + /* If we were mounted with -o acl (to support POSIX access control + lists), tell VFS */ + if (sdp->sd_args.ar_posix_acls) + sb->s_flags |= MS_POSIXACL; +} + +int init_names(struct gfs_sbd *sdp, int silent) +{ + struct gfs_sb *sb = NULL; + char *proto, *table; + int error = 0; + + proto = sdp->sd_args.ar_lockproto; + table = sdp->sd_args.ar_locktable; + + /* Try to autodetect */ + + if (!proto[0] || !table[0]) { + struct buffer_head *bh; + + bh = sb_getblk(sdp->sd_vfs, + GFS_SB_ADDR >> sdp->sd_fsb2bb_shift); + lock_buffer(bh); + clear_buffer_uptodate(bh); + clear_buffer_dirty(bh); + unlock_buffer(bh); + ll_rw_block(READ, 1, &bh); + wait_on_buffer(bh); + + if (!buffer_uptodate(bh)) { + brelse(bh); + return -EIO; + } + + sb = kmalloc(sizeof(struct gfs_sb), GFP_KERNEL); + if (!sb) { + brelse(bh); + return -ENOMEM; + } + gfs_sb_in(sb, bh->b_data); + brelse(bh); + + error = gfs_check_sb(sdp, sb, silent); + if (error) + goto out; + + if (!proto[0]) + proto = sb->sb_lockproto; + if (!table[0]) + table = sb->sb_locktable; + } + + if (!table[0]) + table = sdp->sd_vfs->s_id; + + snprintf(sdp->sd_proto_name, 256, "%s", proto); + snprintf(sdp->sd_table_name, 256, "%s", table); + + while ((table = strchr(sdp->sd_table_name, '/'))) + *table = '_'; + + out: + kfree(sb); + + return error; +} + +static int init_locking(struct gfs_sbd *sdp, struct gfs_holder *mount_gh, + int undo) +{ + struct task_struct *p; + int error = 0; + + if (undo) + goto fail_live; + + if ((sdp->sd_lockstruct.ls_flags & LM_LSFLAG_LOCAL) && + !sdp->sd_args.ar_ignore_local_fs) { + /* Force local [p|f]locks */ + sdp->sd_args.ar_localflocks = TRUE; + + /* Force local read ahead and caching */ + sdp->sd_args.ar_localcaching = TRUE; + + /* Allow the machine to oops */ + sdp->sd_args.ar_oopses_ok = TRUE; + } + + /* Start up the scand thread */ + + p = kthread_run(gfs_scand, sdp, "gfs_scand"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start scand thread: %d\n", + sdp->sd_fsname, error); + return error; + } + sdp->sd_scand_process = p; + + /* Start up the glockd thread */ + + for (sdp->sd_glockd_num = 0; + sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd; + sdp->sd_glockd_num++) { + p = kthread_run(gfs_glockd, sdp, "gfs_glockd"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start glockd thread: %d\n", + sdp->sd_fsname, error); + goto fail; + } + sdp->sd_glockd_process[sdp->sd_glockd_num] = p; + } + + /* Only one node may mount at a time */ + error = gfs_glock_nq_num(sdp, + GFS_MOUNT_LOCK, &gfs_nondisk_glops, + LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE, + mount_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire mount glock: %d\n", + sdp->sd_fsname, error); + goto fail; + } + + /* Show that cluster is alive */ + error = gfs_glock_nq_num(sdp, + GFS_LIVE_LOCK, &gfs_nondisk_glops, + LM_ST_SHARED, LM_FLAG_NOEXP | GL_EXACT, + &sdp->sd_live_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire live glock: %d\n", + sdp->sd_fsname, error); + goto fail_mount; + } + + sdp->sd_live_gh.gh_owner = NULL; + return 0; + +fail_live: + gfs_glock_dq_uninit(&sdp->sd_live_gh); + +fail_mount: + gfs_glock_dq_uninit(mount_gh); + +fail: + while (sdp->sd_glockd_num--) + kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); + + kthread_stop(sdp->sd_scand_process); + + return error; +} + +static int init_sb(struct gfs_sbd *sdp, int silent, int undo) +{ + struct super_block *sb = sdp->sd_vfs; + struct gfs_holder sb_gh; + int error = 0; + struct inode *inode; + + if (undo) + goto fail_dput; + + /* Read the SuperBlock from disk, get enough info to enable us + to read-in the journal index and replay all journals. */ + + error = gfs_glock_nq_num(sdp, + GFS_SB_LOCK, &gfs_meta_glops, + (sdp->sd_args.ar_upgrade) ? LM_ST_EXCLUSIVE : LM_ST_SHARED, + 0, &sb_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire superblock glock: %d\n", + sdp->sd_fsname, error); + return error; + } + + error = gfs_read_sb(sdp, sb_gh.gh_gl, silent); + if (error) { + printk("GFS: fsid=%s: can't read superblock: %d\n", + sdp->sd_fsname, error); + goto out; + } + + /* Set up the buffer cache and SB for real, now that we know block + sizes, version #s, locations of important on-disk inodes, etc. */ + + error = -EINVAL; + if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) { + printk("GFS: fsid=%s: FS block size (%u) is too small for device block size (%u)\n", + sdp->sd_fsname, sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev)); + goto fail; + } + if (sdp->sd_sb.sb_bsize > PAGE_SIZE) { + printk("GFS: fsid=%s: FS block size (%u) is too big for machine page size (%u)\n", + sdp->sd_fsname, sdp->sd_sb.sb_bsize, + (unsigned int)PAGE_SIZE); + goto fail; + } + + /* Get rid of buffers from the original block size */ + sb_gh.gh_gl->gl_ops->go_inval(sb_gh.gh_gl, DIO_METADATA | DIO_DATA); + sb_gh.gh_gl->gl_aspace->i_blkbits = sdp->sd_sb.sb_bsize_shift; + + sb_set_blocksize(sb, sdp->sd_sb.sb_bsize); + + /* Read in the resource index inode */ + + error = gfs_get_riinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get resource index inode: %d\n", + sdp->sd_fsname, error); + goto fail; + } + + /* Get the root inode */ + error = gfs_get_rootinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't read in root inode: %d\n", + sdp->sd_fsname, error); + goto fail_ri_free; + } + /* Get the root inode/dentry */ + + inode = gfs_iget(sdp->sd_rooti, CREATE); + if (!inode) { + printk("GFS: fsid=%s: can't get root inode\n", sdp->sd_fsname); + error = -ENOMEM; + goto fail_ri_free; + } + sb->s_root = d_alloc_root(inode); + if (!sb->s_root) { + iput(inode); + printk("GFS: fsid=%s: can't get root dentry\n", sdp->sd_fsname); + error = -ENOMEM; + goto fail_root_free; + } + sb->s_root->d_op = &gfs_dops; + + /* Read in the quota inode */ + error = gfs_get_qinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get quota file inode: %d\n", + sdp->sd_fsname, error); + goto fail_root_free; + } + + /* Implement fast statfs on the unused license inode location. + * sb->sb_quota_di.no_formal_ino = jindex_dinode + 2; + * sb->sb_quota_di.no_addr = jindex_dinode + 2; + * sb->sb_license_di.no_formal_ino = jindex_dinode + 3; + * sb->sb_license_di.no_addr = jindex_dinode + 3; + */ + error = gfs_get_linode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get statfs file inode: %d\n", + sdp->sd_fsname, error); + goto fail_qi_free; + } + + /* We're through with the superblock lock */ +out: + gfs_glock_dq_uninit(&sb_gh); + return error; + +fail_dput: + gfs_inode_put(sdp->sd_linode); + if (sb->s_root) { + dput(sb->s_root); + sb->s_root = NULL; + } +fail_qi_free: + gfs_inode_put(sdp->sd_qinode); +fail_root_free: + gfs_inode_put(sdp->sd_rooti); +fail_ri_free: + gfs_inode_put(sdp->sd_riinode); + gfs_clear_rgrpd(sdp); +fail: + if (!undo) + gfs_glock_dq_uninit(&sb_gh); + return error; +} + +static int init_journal(struct gfs_sbd *sdp, int undo) +{ + struct gfs_holder ji_gh; + int error = 0; + unsigned int x; + int jindex = TRUE; + struct task_struct *p; + + if (undo) { + jindex = 0; + goto fail_recoverd; + } + + init_MUTEX(&sdp->sd_jindex_lock); + + /* Get a handle on the transaction glock; we need this for disk format + upgrade and journal replays, as well as normal operation. */ + + error = gfs_glock_get(sdp, GFS_TRANS_LOCK, &gfs_trans_glops, + CREATE, &sdp->sd_trans_gl); + if (error) + return error; + set_bit(GLF_STICKY, &sdp->sd_trans_gl->gl_flags); + + /* Load in the journal index special file */ + + error = gfs_jindex_hold(sdp, &ji_gh); + if (error) { + printk("GFS: fsid=%s: can't read journal index: %d\n", + sdp->sd_fsname, error); + goto fail_jhold; + } + + if (sdp->sd_args.ar_spectator) { + sdp->sd_jdesc = sdp->sd_jindex[0]; + sdp->sd_log_seg_free = sdp->sd_jdesc.ji_nsegment; + sdp->sd_log_seg_ail2 = 0; + } + else { + /* Discover this node's journal number (lock module tells us + which one to use), and lock it */ + error = -EINVAL; + if (sdp->sd_lockstruct.ls_jid >= sdp->sd_journals) { + printk("GFS: fsid=%s: can't mount journal #%u\n", + sdp->sd_fsname, sdp->sd_lockstruct.ls_jid); + printk("GFS: fsid=%s: there are only %u journals (0 - %u)\n", + sdp->sd_fsname, sdp->sd_journals, sdp->sd_journals - 1); + goto fail_jindex; + } + sdp->sd_jdesc = sdp->sd_jindex[sdp->sd_lockstruct.ls_jid]; + sdp->sd_log_seg_free = sdp->sd_jdesc.ji_nsegment; + sdp->sd_log_seg_ail2 = 0; + + error = gfs_glock_nq_num(sdp, + sdp->sd_jdesc.ji_addr, &gfs_meta_glops, + LM_ST_EXCLUSIVE, LM_FLAG_NOEXP, + &sdp->sd_journal_gh); + if (error) { + printk("GFS: fsid=%s: can't acquire the journal glock: %d\n", + sdp->sd_fsname, error); + goto fail_jindex; + } + } + + if (sdp->sd_lockstruct.ls_first) { + /* We're first node within cluster to mount this filesystem, + replay ALL of the journals, then let lock module know + that we're done. */ + for (x = 0; x < sdp->sd_journals; x++) { + error = gfs_recover_journal(sdp, + x, sdp->sd_jindex + x, + FALSE); + if (error) { + printk("GFS: fsid=%s: error recovering journal %u: %d\n", + sdp->sd_fsname, x, error); + goto fail_journal_gh; + } + } + + gfs_lm_others_may_mount(sdp); + } else if (!sdp->sd_args.ar_spectator) { + /* We're not the first; replay only our own journal. */ + error = gfs_recover_journal(sdp, sdp->sd_lockstruct.ls_jid, + &sdp->sd_jdesc, TRUE); + if (error) { + printk("GFS: fsid=%s: error recovering my journal: %d\n", + sdp->sd_fsname, error); + goto fail_journal_gh; + } + } + + gfs_glock_dq_uninit(&ji_gh); + jindex = FALSE; + + /* Disown my Journal glock */ + sdp->sd_journal_gh.gh_owner = NULL; + + /* Make the FS read/write */ + + if (!test_bit(SDF_ROFS, &sdp->sd_flags)) { + error = gfs_make_fs_rw(sdp); + if (error) { + printk("GFS: fsid=%s: can't make file system RW: %d\n", + sdp->sd_fsname, error); + goto fail_journal_gh; + } + } + + /* Start up the journal recovery thread */ + + p = kthread_run(gfs_recoverd, sdp, "gfs_recoverd"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start recoverd thread: %d\n", + sdp->sd_fsname, error); + goto fail_journal_gh; + } + sdp->sd_recoverd_process = p; + + return 0; + +fail_recoverd: + kthread_stop(sdp->sd_recoverd_process); + sdp->sd_recoverd_process = NULL; + +fail_journal_gh: + if (!sdp->sd_args.ar_spectator) + gfs_glock_dq_uninit(&sdp->sd_journal_gh); + +fail_jindex: + if (jindex) + gfs_glock_dq_uninit(&ji_gh); + +fail_jhold: + gfs_glock_put(sdp->sd_trans_gl); + return error; +} + +static int init_threads(struct gfs_sbd *sdp, int undo) +{ + struct task_struct *p; + int error = 0; + + if (undo) + goto fail_logd; + + sdp->sd_jindex_refresh_time = jiffies; + + /* Start up the logd thread */ + p = kthread_run(gfs_logd, sdp, "gfs_logd"); + error = IS_ERR(p); + if (error) { + printk("GFS: fsid=%s: can't start logd thread: %d\n", + sdp->sd_fsname, error); + goto fail; + } + sdp->sd_logd_process = p; + + /* Start up the quotad thread */ + + p = kthread_run(gfs_quotad, sdp, "gfs_quotad"); + if (error < 0) { + printk("GFS: fsid=%s: can't start quotad thread: %d\n", + sdp->sd_fsname, error); + goto fail_quotad; + } + sdp->sd_quotad_process = p; + + /* Start up the inoded thread */ + + p = kthread_run(gfs_inoded, sdp, "gfs_inoded"); + if (error < 0) { + printk("GFS: fsid=%s: can't start inoded thread: %d\n", + sdp->sd_fsname, error); + goto fail_inoded; + } + sdp->sd_inoded_process = p; + return 0; + +fail_logd: + kthread_stop(sdp->sd_inoded_process); +fail_inoded: + kthread_stop(sdp->sd_quotad_process); +fail_quotad: + kthread_stop(sdp->sd_logd_process); +fail: + return error; +} + +/** + * fill_super - Read in superblock + * @sb: The VFS superblock + * @data: Mount options + * @silent: Don't complain if it's not a GFS filesystem + * + * Returns: errno + * + * After cross-linking Linux VFS incore superblock and our GFS incore + * superblock (filesystem instance structures) to one another, we: + * -- Init some of our GFS incore superblock, including some temporary + * block-size values (enough to read on-disk superblock). + * -- Set up some things in Linux VFS superblock. + * -- Mount a lock module, init glock system (incl. glock reclaim daemons), + * and init some important inter-node locks (MOUNT, LIVE, SuperBlock). + * -- Read-in the GFS on-disk superblock (1st time, to get enough info + * to do filesystem upgrade and journal replay, incl. journal index). + * -- Upgrade on-disk filesystem format (rarely needed). + * -- Replay journals (always; replay *all* journals if we're first-to-mount). + * -- Read-in on-disk superblock and journal index special file again + * (2nd time, assumed 100% valid now after journal replay). + * -- Read-in info on other special (hidden) files (root inode, resource index, + * quota inode, license inode). + * -- Start other daemons (journal/log recovery, log tail, quota updates, inode + * reclaim) for periodic maintenance. + * + */ + +static int fill_super(struct super_block *sb, void *data, int silent) +{ + struct gfs_sbd *sdp; + struct gfs_holder mount_gh; + int error; + + sdp = init_sbd(sb); + if (!sdp) { + printk(KERN_WARNING "GFS: can't alloc struct gfs_sbd\n"); + return -ENOMEM; + } + + error = gfs_make_args((char *)data, &sdp->sd_args, FALSE); + if (error) { + printk("GFS: can't parse mount arguments\n"); + goto fail; + } + + if (sdp->sd_args.ar_spectator) { + sb->s_flags |= MS_RDONLY; + set_bit(SDF_ROFS, &sdp->sd_flags); + } + + /* Copy VFS mount flags */ + + if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME)) + set_bit(SDF_NOATIME, &sdp->sd_flags); + if (sb->s_flags & MS_RDONLY) + set_bit(SDF_ROFS, &sdp->sd_flags); + + init_vfs(sb, SDF_NOATIME); + + /* Turn off quota stuff if we get the noquota mount option, don't + need to grab the sd_tune lock here since its before anything + touches the sd_tune values */ + if (sdp->sd_args.ar_noquota) { + sdp->sd_tune.gt_quota_enforce = 0; + sdp->sd_tune.gt_quota_account = 0; + } + + /* Set up the buffer cache and fill in some fake block size values + to allow us to read-in the on-disk superblock. */ + + sdp->sd_sb.sb_bsize = sb_min_blocksize(sb, GFS_BASIC_BLOCK); + sdp->sd_sb.sb_bsize_shift = sb->s_blocksize_bits; + sdp->sd_fsb2bb_shift = sdp->sd_sb.sb_bsize_shift - GFS_BASIC_BLOCK_SHIFT; + sdp->sd_fsb2bb = 1 << sdp->sd_fsb2bb_shift; + + if (sizeof(struct gfs_sb) > sdp->sd_sb.sb_bsize) { + printk("GFS: sizeof(struct gfs_sb) > sdp->sd_sb.sb_bsize\n" + "GFS: %u > %u\n", + (unsigned int)sizeof(struct gfs_sb), sdp->sd_sb.sb_bsize); + error = -EINVAL; + goto fail; + } + error = init_names(sdp, silent); + if (error) + goto fail; + + error = gfs_sys_fs_add(sdp); + if (error) + goto fail; + + /* Mount an inter-node lock module, check for local optimizations */ + + error = gfs_lm_mount(sdp, silent); + if (error) + goto fail_sys; + + error = init_locking(sdp, &mount_gh, DO); + if (error) + goto fail_lm; + + error = init_sb(sdp, silent, DO); + if (error) + goto fail_locking; + + /* Read-in journal index inode (but not the file contents, yet) */ + + error = gfs_get_jiinode(sdp); + if (error) { + printk("GFS: fsid=%s: can't get journal index inode: %d\n", + sdp->sd_fsname, error); + goto fail_jiinode; + } + + error = init_journal(sdp, DO); + if (error) + goto fail_sb; + /* Get a handle on the rename lock */ + + error = gfs_glock_get(sdp, GFS_RENAME_LOCK, &gfs_nondisk_glops, + CREATE, &sdp->sd_rename_gl); + if (error) + goto fail_journal; + + error = init_threads(sdp, DO); + if (error) + goto fail_journal; + + gfs_proc_fs_add(sdp); + gfs_glock_dq_uninit(&mount_gh); + + return 0; + +fail_journal: + init_journal(sdp, UNDO); + +fail_sb: + gfs_inode_put(sdp->sd_jiinode); + +fail_jiinode: + init_sb(sdp, 0, UNDO); + +fail_locking: + init_locking(sdp, &mount_gh, UNDO); + +fail_lm: + gfs_gl_hash_clear(sdp, TRUE); + gfs_lm_unmount(sdp); + gfs_clear_dirty_j(sdp); + while (invalidate_inodes(sb)) + yield(); + +fail_sys: + gfs_sys_fs_del(sdp); + +fail: + vfree(sdp); + sb->s_fs_info = NULL; + + return error; +} + +/** + * gfs_test_bdev_super - + * @sb: + * @data: + * + */ + +int +gfs_test_bdev_super(struct super_block *sb, void *data) +{ + return (void *)sb->s_bdev == data; +} + +/** + * gfs_test_bdev_super - + * @sb: + * @data: + * + */ + +int +gfs_set_bdev_super(struct super_block *sb, void *data) +{ + sb->s_bdev = data; + sb->s_dev = sb->s_bdev->bd_dev; + return 0; +} + +/** + * gfs_get_sb - + * @fs_type: + * @flags: + * @dev_name: + * @data: + * + * Rip off of get_sb_bdev(). + * + * Returns: the new superblock + */ + +static int gfs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *data, struct vfsmount *mnt) +{ + return get_sb_bdev(fs_type, flags, dev_name, data, fill_super, mnt); +} + +/** + * gfs_kill_sb - + * @sb: + * + * Rip off of kill_block_super(). + * + */ + +void +gfs_kill_sb(struct super_block *sb) +{ + kill_block_super(sb); +} + +struct file_system_type gfs_fs_type = { + .name = "gfs", + .fs_flags = FS_REQUIRES_DEV, + .get_sb = gfs_get_sb, + .kill_sb = gfs_kill_sb, + .owner = THIS_MODULE, +}; --- linux-2.6.28.orig/ubuntu/gfs/trans.c +++ linux-2.6.28/ubuntu/gfs/trans.c @@ -0,0 +1,453 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "log.h" +#include "lops.h" +#include "quota.h" +#include "trans.h" +#include "unlinked.h" + +/** + * gfs_trans_print - Print a transaction to the console + * @sdp: the filesystem + * @tr: The GFS transaction + * @where: Situation of transaction + * + */ + +void +gfs_trans_print(struct gfs_sbd *sdp, struct gfs_trans *tr, unsigned int where) +{ + struct gfs_log_element *le; + struct list_head *tmp, *head; + unsigned int mblks = 0, eblks = 0; + + LO_TRANS_SIZE(sdp, tr, &mblks, &eblks, NULL, NULL); + + printk("Transaction: (%s, %u)\n", tr->tr_file, tr->tr_line); + printk(" tr_mblks_asked = %u, tr_eblks_asked = %u, tr_seg_reserved = %u\n", + tr->tr_mblks_asked, tr->tr_eblks_asked, tr->tr_seg_reserved); + printk(" mblks = %u, eblks = %u\n", mblks, eblks); + printk(" tr_flags = 0x%.8X\n", tr->tr_flags); + + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + LO_PRINT(sdp, le, where); + } + + printk("End Trans\n"); +} + +/** + * gfs_trans_begin_i - Prepare to start a transaction + * @sdp: The GFS superblock + * @meta_blocks: Reserve this many metadata blocks in the log + * @extra_blocks: Number of non-metadata blocks to reserve + * + * Allocate the struct gfs_trans struct. + * Grab a shared TRANSaction lock (protects this transaction from + * overlapping with unusual fs writes, e.g. journal replay, fs upgrade, + * while allowing simultaneous transaction writes throughout cluster). + * Reserve space in the log. @meta_blocks and @extra_blocks must indicate + * the worst case (maximum) size of the transaction. + * Record this transaction as the *one* transaction being built by this + * Linux process, in current->journal_info. + * + * Returns: errno + */ + +int +gfs_trans_begin_i(struct gfs_sbd *sdp, + unsigned int meta_blocks, unsigned int extra_blocks, + char *file, unsigned int line) +{ + struct gfs_trans *tr; + unsigned int blocks; + int error; + + tr = kmalloc(sizeof(struct gfs_trans), GFP_KERNEL); + if (!tr) + return -ENOMEM; + memset(tr, 0, sizeof(struct gfs_trans)); + + INIT_LIST_HEAD(&tr->tr_elements); + INIT_LIST_HEAD(&tr->tr_free_bufs); + INIT_LIST_HEAD(&tr->tr_free_bmem); + INIT_LIST_HEAD(&tr->tr_bufs); + INIT_LIST_HEAD(&tr->tr_ail_bufs); + tr->tr_file = file; + tr->tr_line = line; + + error = -ENOMEM; + tr->tr_t_gh = gfs_holder_get(sdp->sd_trans_gl, LM_ST_SHARED, 0); + if (!tr->tr_t_gh) + goto fail; + + error = gfs_glock_nq(tr->tr_t_gh); + if (error) + goto fail_holder_put; + + if (test_bit(SDF_ROFS, &sdp->sd_flags)) { + tr->tr_t_gh->gh_flags |= GL_NOCACHE; + error = -EROFS; + goto fail_gunlock; + } + + /* Do log reservation */ + + tr->tr_mblks_asked = meta_blocks; + tr->tr_eblks_asked = extra_blocks; + + blocks = 1; + if (meta_blocks) + blocks += gfs_struct2blk(sdp, meta_blocks, + sizeof(struct gfs_block_tag)) + + meta_blocks; + blocks += extra_blocks; + tr->tr_seg_reserved = gfs_blk2seg(sdp, blocks); + + error = gfs_log_reserve(sdp, tr->tr_seg_reserved, FALSE); + if (error) + goto fail_gunlock; + + gfs_assert(sdp, !get_transaction,); + set_transaction(tr); + + return 0; + + fail_gunlock: + gfs_glock_dq(tr->tr_t_gh); + + fail_holder_put: + gfs_holder_put(tr->tr_t_gh); + + fail: + kfree(tr); + + return error; +} + +/** + * gfs_trans_end - End a transaction + * @sdp: The GFS superblock + * + * If buffers were actually added to the transaction, + * commit it. + * + */ + +void +gfs_trans_end(struct gfs_sbd *sdp) +{ + struct gfs_trans *tr; + struct gfs_holder *t_gh; + struct list_head *tmp, *head; + struct gfs_log_element *le; + + /* Linux task struct indicates current new trans for this process. + * We're done building it, so set it to NULL */ + tr = get_transaction; + gfs_assert(sdp, tr,); + set_transaction(NULL); + + t_gh = tr->tr_t_gh; + tr->tr_t_gh = NULL; + + /* If no buffers were ever added to trans, forget it */ + if (list_empty(&tr->tr_elements)) { + gfs_log_release(sdp, tr->tr_seg_reserved); + kfree(tr); + + gfs_glock_dq(t_gh); + gfs_holder_put(t_gh); + + return; + } + + /* Do trans_end log-operation for each log element */ + for (head = &tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + LO_TRANS_END(sdp, le); + } + + gfs_log_commit(sdp, tr); + + gfs_glock_dq(t_gh); + gfs_holder_put(t_gh); + + if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) + gfs_log_flush(sdp); +} + +/** + * gfs_trans_add_gl - Add a glock to a transaction + * @gl: the glock + * + * If not already attached, add the given glock to this process's transaction. + * + * Even though no glock info will be written to the on-disk log, the glocks + * associated with a transaction provide bridges by which to combine + * a just-built transaction with an earlier incore committed transaction + * that was protected by the same glock. See incore_commit(). + * Combining transactions makes for more efficient logging. + * + * Note that more than one glock may be associated with a single transaction. + * However, a given glock protects no more than *one* transaction at a + * given stage in the transaction pipeline (i.e. new or incore-committed). + * After all, the process holds the glock EX (so no other process can be + * building a separate trans protected by this glock), and the process can + * build only one transaction at a time. + * + * Rules: + * This process must hold the glock in EXclusive mode, since we're going + * to be writing to something protected by this glock. + */ + +void +gfs_trans_add_gl(struct gfs_glock *gl) +{ + if (!gl->gl_new_le.le_trans) { + gfs_assert_withdraw(gl->gl_sbd, + gfs_glock_is_locked_by_me(gl) && + gfs_glock_is_held_excl(gl)); + gfs_glock_hold(gl); /* Released in glock_trans_end() */ + + /* Ask for eventual flush of (meta)data protected by this glock, + once trans is complete and logged. */ + set_bit(GLF_DIRTY, &gl->gl_flags); + + /* Invoke generic_le_add() */ + LO_ADD(gl->gl_sbd, &gl->gl_new_le); + gl->gl_new_le.le_trans->tr_num_gl++; + } +} + +/** + * gfs_trans_add_bh - Add a to-be-modified buffer to the current transaction + * @gl: the glock the buffer belongs to + * @bh: The buffer to add + * + * Add a to-be-modified buffer to the current being-built (i.e. new) trans, + * and pin the buffer in memory. + * + * Caller must hold the glock protecting this buffer. + * + * Call this as many times as you want during transaction formation. It does + * its attachment work only once. After buffer is attached to trans, the + * process building the trans can modify the buffer again and again (calling + * this function before each change). Only the final result (within this trans) + * will be written to log. A good example is when allocating blocks in an RG, + * a given bitmap buffer may be updated many times within a transaction. + * + * Note: This final result will also be written to its in-place location, + * unless this transaction gets combined with a later transaction, + * in which case only the later result will go to in-place. + * + */ + +void +gfs_trans_add_bh(struct gfs_glock *gl, struct buffer_head *bh) +{ + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_bufdata *bd; + + /* Make sure GFS private info struct is attached to buffer head */ + bd = get_v2bd(bh); + if (!bd) { + gfs_attach_bufdata(bh, gl); + bd = get_v2bd(bh); + } + + /* If buffer has already been attached to trans, we're done */ + if (bd->bd_new_le.le_trans) + return; + + gfs_meta_check(sdp, bh); + + gfs_assert(sdp, bd->bd_gl == gl,); + + /* Make sure glock is attached to trans */ + if (!gl->gl_new_le.le_trans) + gfs_trans_add_gl(gl); + + gfs_dpin(sdp, bh); + + /* Attach buffer to trans */ + LO_ADD(sdp, &bd->bd_new_le); + bd->bd_new_le.le_trans->tr_num_buf++; +} + +/** + * gfs_trans_add_unlinked - Add an unlinked or dealloced tag to + * the current transaction + * @sdp: the filesystem + * @type: the type of entry + * @inum: the inode number + * + * Returns: the unlinked structure + */ + +struct gfs_unlinked * +gfs_trans_add_unlinked(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum) +{ + struct gfs_unlinked *ul; + + /* Find in fileystem's unlinked list, or create */ + ul = gfs_unlinked_get(sdp, inum, CREATE); + + LO_ADD(sdp, &ul->ul_new_le); + + switch (type) { + case GFS_LOG_DESC_IUL: + set_bit(ULF_NEW_UL, &ul->ul_flags); + ul->ul_new_le.le_trans->tr_num_iul++; + break; + case GFS_LOG_DESC_IDA: + clear_bit(ULF_NEW_UL, &ul->ul_flags); + ul->ul_new_le.le_trans->tr_num_ida++; + break; + default: + gfs_assert(sdp, FALSE,); + break; + } + + return ul; +} + +/** + * gfs_trans_add_quota - Add quota changes to a transaction + * @sdp: the filesystem + * @change: The number of blocks allocated (positive) or freed (negative) + * @uid: the user ID doing the change + * @gid: the group ID doing the change + * + */ + +void +gfs_trans_add_quota(struct gfs_sbd *sdp, int64_t change, + uint32_t uid, uint32_t gid) +{ + struct gfs_trans *tr; + struct list_head *tmp, *head, *next; + struct gfs_log_element *le; + struct gfs_quota_le *ql; + int found_uid, found_gid; + int error; + + if (!gfs_tune_get(sdp, gt_quota_account)) + return; + if (gfs_assert_warn(sdp, change)) + return; + + found_uid = (uid == NO_QUOTA_CHANGE); + found_gid = (gid == NO_QUOTA_CHANGE); + + if (gfs_assert_warn(sdp, !found_uid || !found_gid)) + return; + + tr = get_transaction; + gfs_assert(sdp, tr,); + + for (head = &tr->tr_elements, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = next->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + if (le->le_ops != &gfs_quota_lops) + continue; + + ql = container_of(le, struct gfs_quota_le, ql_le); + + if (test_bit(QDF_USER, &ql->ql_data->qd_flags)) { + if (ql->ql_data->qd_id == uid) { + ql->ql_change += change; + + spin_lock(&sdp->sd_quota_lock); + ql->ql_data->qd_change_new += change; + spin_unlock(&sdp->sd_quota_lock); + + list_del(&le->le_list); + + if (ql->ql_change) + list_add(&le->le_list, + &tr->tr_elements); + else { + gfs_quota_put(sdp, ql->ql_data); + kfree(ql); + tr->tr_num_q--; + } + + gfs_assert(sdp, !found_uid,); + found_uid = TRUE; + if (found_gid) + break; + } + } else { + if (ql->ql_data->qd_id == gid) { + ql->ql_change += change; + + spin_lock(&sdp->sd_quota_lock); + ql->ql_data->qd_change_new += change; + spin_unlock(&sdp->sd_quota_lock); + + list_del(&le->le_list); + + if (ql->ql_change) + list_add(&le->le_list, + &tr->tr_elements); + else { + gfs_quota_put(sdp, ql->ql_data); + kfree(ql); + tr->tr_num_q--; + } + + gfs_assert(sdp, !found_gid,); + found_gid = TRUE; + if (found_uid) + break; + } + } + } + + while (!found_uid || !found_gid) { + ql = gmalloc(sizeof(struct gfs_quota_le)); + memset(ql, 0, sizeof(struct gfs_quota_le)); + + INIT_LE(&ql->ql_le, &gfs_quota_lops); + + if (found_uid) { + error = gfs_quota_get(sdp, FALSE, gid, + NO_CREATE, + &ql->ql_data); + found_gid = TRUE; + } else { + error = gfs_quota_get(sdp, TRUE, uid, + NO_CREATE, + &ql->ql_data); + found_uid = TRUE; + } + + gfs_assert(sdp, !error && ql->ql_data,); + + ql->ql_change = change; + + spin_lock(&sdp->sd_quota_lock); + ql->ql_data->qd_change_new += change; + spin_unlock(&sdp->sd_quota_lock); + + LO_ADD(sdp, &ql->ql_le); + tr->tr_num_q++; + } +} --- linux-2.6.28.orig/ubuntu/gfs/lock_nolock_main.c +++ linux-2.6.28/ubuntu/gfs/lock_nolock_main.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 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 version 2. + */ + +#include +#include +#include +#include +#include +#include "lm_interface.h" + +struct nolock_lockspace { + unsigned int nl_lvb_size; +}; + +static const struct lm_lockops nolock_ops; + +static int nolock_mount(char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj) +{ + char *c; + unsigned int jid; + struct nolock_lockspace *nl; + + c = strstr(host_data, "jid="); + if (!c) + jid = 0; + else { + c += 4; + sscanf(c, "%u", &jid); + } + + nl = kzalloc(sizeof(struct nolock_lockspace), GFP_KERNEL); + if (!nl) + return -ENOMEM; + + nl->nl_lvb_size = min_lvb_size; + + lockstruct->ls_jid = jid; + lockstruct->ls_first = 1; + lockstruct->ls_lvb_size = min_lvb_size; + lockstruct->ls_lockspace = nl; + lockstruct->ls_ops = &nolock_ops; + lockstruct->ls_flags = LM_LSFLAG_LOCAL; + + return 0; +} + +static void nolock_others_may_mount(void *lockspace) +{ +} + +static void nolock_unmount(void *lockspace) +{ + struct nolock_lockspace *nl = lockspace; + kfree(nl); +} + +static void nolock_withdraw(void *lockspace) +{ +} + +/** + * nolock_get_lock - get a lm_lock_t given a descripton of the lock + * @lockspace: the lockspace the lock lives in + * @name: the name of the lock + * @lockp: return the lm_lock_t here + * + * Returns: 0 on success, -EXXX on failure + */ + +static int nolock_get_lock(void *lockspace, struct lm_lockname *name, + void **lockp) +{ + *lockp = lockspace; + return 0; +} + +/** + * nolock_put_lock - get rid of a lock structure + * @lock: the lock to throw away + * + */ + +static void nolock_put_lock(void *lock) +{ +} + +/** + * nolock_lock - acquire a lock + * @lock: the lock to manipulate + * @cur_state: the current state + * @req_state: the requested state + * @flags: modifier flags + * + * Returns: A bitmap of LM_OUT_* + */ + +static unsigned int nolock_lock(void *lock, unsigned int cur_state, + unsigned int req_state, unsigned int flags) +{ + return req_state | LM_OUT_CACHEABLE; +} + +/** + * nolock_unlock - unlock a lock + * @lock: the lock to manipulate + * @cur_state: the current state + * + * Returns: 0 + */ + +static unsigned int nolock_unlock(void *lock, unsigned int cur_state) +{ + return 0; +} + +static void nolock_cancel(void *lock) +{ +} + +/** + * nolock_hold_lvb - hold on to a lock value block + * @lock: the lock the LVB is associated with + * @lvbp: return the lm_lvb_t here + * + * Returns: 0 on success, -EXXX on failure + */ + +static int nolock_hold_lvb(void *lock, char **lvbp) +{ + struct nolock_lockspace *nl = lock; + int error = 0; + + *lvbp = kzalloc(nl->nl_lvb_size, GFP_NOFS); + if (!*lvbp) + error = -ENOMEM; + + return error; +} + +/** + * nolock_unhold_lvb - release a LVB + * @lock: the lock the LVB is associated with + * @lvb: the lock value block + * + */ + +static void nolock_unhold_lvb(void *lock, char *lvb) +{ + kfree(lvb); +} + +static int nolock_plock_get(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + posix_test_lock(file, fl); + + return 0; +} + +static int nolock_plock(void *lockspace, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl) +{ + int error; + error = posix_lock_file_wait(file, fl); + return error; +} + +static int nolock_punlock(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + int error; + error = posix_lock_file_wait(file, fl); + return error; +} + +static void nolock_recovery_done(void *lockspace, unsigned int jid, + unsigned int message) +{ +} + +static const struct lm_lockops nolock_ops = { + .lm_proto_name = "lock_nolock", + .lm_mount = nolock_mount, + .lm_others_may_mount = nolock_others_may_mount, + .lm_unmount = nolock_unmount, + .lm_withdraw = nolock_withdraw, + .lm_get_lock = nolock_get_lock, + .lm_put_lock = nolock_put_lock, + .lm_lock = nolock_lock, + .lm_unlock = nolock_unlock, + .lm_cancel = nolock_cancel, + .lm_hold_lvb = nolock_hold_lvb, + .lm_unhold_lvb = nolock_unhold_lvb, + .lm_plock_get = nolock_plock_get, + .lm_plock = nolock_plock, + .lm_punlock = nolock_punlock, + .lm_recovery_done = nolock_recovery_done, + .lm_owner = THIS_MODULE, +}; + +int init_nolock() +{ + int error; + + error = gfs_register_lockproto(&nolock_ops); + if (error) { + printk(KERN_WARNING + "lock_nolock: can't register protocol: %d\n", error); + return error; + } + + printk(KERN_INFO + "Lock_Nolock (built %s %s) installed\n", __DATE__, __TIME__); + return 0; +} + +void exit_nolock() +{ + gfs_unregister_lockproto(&nolock_ops); +} --- linux-2.6.28.orig/ubuntu/gfs/page.c +++ linux-2.6.28/ubuntu/gfs/page.c @@ -0,0 +1,266 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "inode.h" +#include "page.h" + +/** + * gfs_inval_pte - Sync and invalidate all PTEs associated with a glock + * @gl: the glock + * + */ + +void +gfs_inval_pte(struct gfs_glock *gl) +{ + struct gfs_inode *ip; + struct inode *inode; + + ip = get_gl2ip(gl); + if (!ip || + ip->i_di.di_type != GFS_FILE_REG) + return; + + if (!test_bit(GIF_PAGED, &ip->i_flags)) + return; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + unmap_shared_mapping_range(inode->i_mapping, 0, 0); + iput(inode); + + if (test_bit(GIF_SW_PAGED, &ip->i_flags)) + set_bit(GLF_DIRTY, &gl->gl_flags); + } + + clear_bit(GIF_SW_PAGED, &ip->i_flags); +} + +/** + * gfs_inval_page - Invalidate all pages associated with a glock + * @gl: the glock + * + */ + +void +gfs_inval_page(struct gfs_glock *gl) +{ + struct gfs_inode *ip; + struct inode *inode; + + ip = get_gl2ip(gl); + if (!ip || + ip->i_di.di_type != GFS_FILE_REG) + return; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + struct address_space *mapping = inode->i_mapping; + + truncate_inode_pages(mapping, 0); + gfs_assert_withdraw(ip->i_sbd, !mapping->nrpages); + + iput(inode); + } + + clear_bit(GIF_PAGED, &ip->i_flags); +} + +/** + * gfs_sync_page_i - Sync the data pages (not metadata) for a struct inode + * @inode: the inode + * @flags: DIO_START | DIO_WAIT + * + */ + +void +gfs_sync_page_i(struct inode *inode, int flags) +{ + struct address_space *mapping = inode->i_mapping; + int error = 0; + + if (flags & DIO_START) + error = filemap_fdatawrite(mapping); + if (!error && (flags & DIO_WAIT)) + error = filemap_fdatawait(mapping); + + /* Find a better way to report this to the user. */ + if (error) + gfs_io_error_inode(get_v2ip(inode)); +} + +/** + * gfs_sync_page - Sync the data pages (not metadata) associated with a glock + * @gl: the glock + * @flags: DIO_START | DIO_WAIT + * + * Syncs data (not metadata) for a regular file. + * No-op for all other types. + */ + +void +gfs_sync_page(struct gfs_glock *gl, int flags) +{ + struct gfs_inode *ip; + struct inode *inode; + + ip = get_gl2ip(gl); + if (!ip || + ip->i_di.di_type != GFS_FILE_REG) + return; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + gfs_sync_page_i(inode, flags); + iput(inode); + } +} + +/** + * gfs_unstuffer_page - unstuff a stuffed inode into a block cached by a page + * @ip: the inode + * @dibh: the dinode buffer + * @block: the block number that was allocated + * @private: any locked page held by the caller process + * + * Returns: errno + */ + +int +gfs_unstuffer_page(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private) +{ + struct inode *inode = ip->i_vnode; + struct page *page = (struct page *)private; + struct buffer_head *bh; + int release = FALSE; + + if (!page || page->index) { + page = grab_cache_page(inode->i_mapping, 0); + if (!page) + return -ENOMEM; + release = TRUE; + } + + if (!PageUptodate(page)) { + void *kaddr = kmap(page); + + memcpy(kaddr, + dibh->b_data + sizeof(struct gfs_dinode), + ip->i_di.di_size); + memset(kaddr + ip->i_di.di_size, + 0, + PAGE_CACHE_SIZE - ip->i_di.di_size); + kunmap(page); + + SetPageUptodate(page); + } + + if (!page_has_buffers(page)) + create_empty_buffers(page, 1 << inode->i_blkbits, + (1 << BH_Uptodate)); + + bh = page_buffers(page); + + if (!buffer_mapped(bh)) + map_bh(bh, inode->i_sb, block); + else if (gfs_assert_warn(ip->i_sbd, + bh->b_bdev == inode->i_sb->s_bdev && + bh->b_blocknr == block)) + map_bh(bh, inode->i_sb, block); + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + + if (release) { + unlock_page(page); + page_cache_release(page); + } + + return 0; +} + +/** + * gfs_truncator_page - truncate a partial data block in the page cache + * @ip: the inode + * @size: the size the file should be + * + * Returns: errno + */ + +int +gfs_truncator_page(struct gfs_inode *ip, uint64_t size) +{ + struct inode *inode = ip->i_vnode; + struct page *page; + struct buffer_head *bh; + void *kaddr; + uint64_t lbn, dbn; + unsigned long index; + unsigned int offset; + unsigned int bufnum; + int not_new = 0; + int error; + + lbn = size >> inode->i_blkbits; + error = gfs_block_map(ip, + lbn, ¬_new, + &dbn, NULL); + if (error || !dbn) + return error; + + index = size >> PAGE_CACHE_SHIFT; + offset = size & (PAGE_CACHE_SIZE - 1); + bufnum = lbn - (index << (PAGE_CACHE_SHIFT - inode->i_blkbits)); + + /* Not in a transaction here -- a non-disk-I/O error is ok. */ + + page = read_cache_page(inode->i_mapping, index, + (filler_t *)inode->i_mapping->a_ops->readpage, + NULL); + if (IS_ERR(page)) + return PTR_ERR(page); + + lock_page(page); + + if (!PageUptodate(page) || PageError(page)) { + error = -EIO; + goto out; + } + + kaddr = kmap(page); + memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset); + kunmap(page); + + if (!page_has_buffers(page)) + create_empty_buffers(page, 1 << inode->i_blkbits, + (1 << BH_Uptodate)); + + for (bh = page_buffers(page); bufnum--; bh = bh->b_this_page) + /* Do nothing */; + + if (!buffer_mapped(bh)) + map_bh(bh, inode->i_sb, dbn); + else if (gfs_assert_warn(ip->i_sbd, + bh->b_bdev == inode->i_sb->s_bdev && + bh->b_blocknr == dbn)) + map_bh(bh, inode->i_sb, dbn); + + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + + out: + unlock_page(page); + page_cache_release(page); + + return error; +} --- linux-2.6.28.orig/ubuntu/gfs/ops_address.h +++ linux-2.6.28/ubuntu/gfs/ops_address.h @@ -0,0 +1,6 @@ +#ifndef __OPS_ADDRESS_DOT_H__ +#define __OPS_ADDRESS_DOT_H__ + +extern struct address_space_operations gfs_file_aops; + +#endif /* __OPS_ADDRESS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_lock.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_lock.c @@ -0,0 +1,527 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 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 version 2. + */ + +#include "lock_dlm.h" + +static char junk_lvb[GDLM_LVB_SIZE]; + +static void queue_complete(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + clear_bit(LFL_ACTIVE, &lp->flags); + + spin_lock(&ls->async_lock); + list_add_tail(&lp->clist, &ls->complete); + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +static inline void gdlm_ast(void *astarg) +{ + queue_complete(astarg); +} + +static inline void gdlm_bast(void *astarg, int mode) +{ + struct gdlm_lock *lp = astarg; + struct gdlm_ls *ls = lp->ls; + + if (!mode) { + printk(KERN_INFO "lock_dlm: bast mode zero %x,%llx\n", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + return; + } + + spin_lock(&ls->async_lock); + if (!lp->bast_mode) { + list_add_tail(&lp->blist, &ls->blocking); + lp->bast_mode = mode; + } else if (lp->bast_mode < mode) + lp->bast_mode = mode; + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +void gdlm_queue_delayed(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + spin_lock(&ls->async_lock); + list_add_tail(&lp->delay_list, &ls->delayed); + spin_unlock(&ls->async_lock); +} + +/* convert gfs lock-state to dlm lock-mode */ + +static s16 make_mode(s16 lmstate) +{ + switch (lmstate) { + case LM_ST_UNLOCKED: + return DLM_LOCK_NL; + case LM_ST_EXCLUSIVE: + return DLM_LOCK_EX; + case LM_ST_DEFERRED: + return DLM_LOCK_CW; + case LM_ST_SHARED: + return DLM_LOCK_PR; + } + gdlm_assert(0, "unknown LM state %d", lmstate); + return -1; +} + +/* convert dlm lock-mode to gfs lock-state */ + +s16 gdlm_make_lmstate(s16 dlmmode) +{ + switch (dlmmode) { + case DLM_LOCK_IV: + case DLM_LOCK_NL: + return LM_ST_UNLOCKED; + case DLM_LOCK_EX: + return LM_ST_EXCLUSIVE; + case DLM_LOCK_CW: + return LM_ST_DEFERRED; + case DLM_LOCK_PR: + return LM_ST_SHARED; + } + gdlm_assert(0, "unknown DLM mode %d", dlmmode); + return -1; +} + +/* verify agreement with GFS on the current lock state, NB: DLM_LOCK_NL and + DLM_LOCK_IV are both considered LM_ST_UNLOCKED by GFS. */ + +static void check_cur_state(struct gdlm_lock *lp, unsigned int cur_state) +{ + s16 cur = make_mode(cur_state); + if (lp->cur != DLM_LOCK_IV) + gdlm_assert(lp->cur == cur, "%d, %d", lp->cur, cur); +} + +static inline unsigned int make_flags(struct gdlm_lock *lp, + unsigned int gfs_flags, + s16 cur, s16 req) +{ + unsigned int lkf = 0; + + if (gfs_flags & LM_FLAG_TRY) + lkf |= DLM_LKF_NOQUEUE; + + if (gfs_flags & LM_FLAG_TRY_1CB) { + lkf |= DLM_LKF_NOQUEUE; + lkf |= DLM_LKF_NOQUEUEBAST; + } + + if (gfs_flags & LM_FLAG_PRIORITY) { + lkf |= DLM_LKF_NOORDER; + lkf |= DLM_LKF_HEADQUE; + } + + if (gfs_flags & LM_FLAG_ANY) { + if (req == DLM_LOCK_PR) + lkf |= DLM_LKF_ALTCW; + else if (req == DLM_LOCK_CW) + lkf |= DLM_LKF_ALTPR; + } + + if (lp->lksb.sb_lkid != 0) { + lkf |= DLM_LKF_CONVERT; + + /* Conversion deadlock avoidance by DLM */ + + if (!test_bit(LFL_FORCE_PROMOTE, &lp->flags) && + !(lkf & DLM_LKF_NOQUEUE) && + cur > DLM_LOCK_NL && req > DLM_LOCK_NL && cur != req) + lkf |= DLM_LKF_CONVDEADLK; + } + + if (lp->lvb) + lkf |= DLM_LKF_VALBLK; + + return lkf; +} + +/* make_strname - convert GFS lock numbers to a string */ + +static inline void make_strname(const struct lm_lockname *lockname, + struct gdlm_strname *str) +{ + sprintf(str->name, "%8x%16llx", lockname->ln_type, + (unsigned long long)lockname->ln_number); + str->namelen = GDLM_STRNAME_BYTES; +} + +static int gdlm_create_lp(struct gdlm_ls *ls, struct lm_lockname *name, + struct gdlm_lock **lpp) +{ + struct gdlm_lock *lp; + + lp = kzalloc(sizeof(struct gdlm_lock), GFP_NOFS); + if (!lp) + return -ENOMEM; + + lp->lockname = *name; + make_strname(name, &lp->strname); + lp->ls = ls; + lp->cur = DLM_LOCK_IV; + lp->lvb = NULL; + lp->hold_null = NULL; + INIT_LIST_HEAD(&lp->clist); + INIT_LIST_HEAD(&lp->blist); + INIT_LIST_HEAD(&lp->delay_list); + + spin_lock(&ls->async_lock); + list_add(&lp->all_list, &ls->all_locks); + ls->all_locks_count++; + spin_unlock(&ls->async_lock); + + *lpp = lp; + return 0; +} + +void gdlm_delete_lp(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + + spin_lock(&ls->async_lock); + if (!list_empty(&lp->clist)) + list_del_init(&lp->clist); + if (!list_empty(&lp->blist)) + list_del_init(&lp->blist); + if (!list_empty(&lp->delay_list)) + list_del_init(&lp->delay_list); + gdlm_assert(!list_empty(&lp->all_list), "%x,%llx", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + list_del_init(&lp->all_list); + ls->all_locks_count--; + spin_unlock(&ls->async_lock); + + kfree(lp); +} + +int gdlm_get_lock(void *lockspace, struct lm_lockname *name, + void **lockp) +{ + struct gdlm_lock *lp; + int error; + + error = gdlm_create_lp(lockspace, name, &lp); + + *lockp = lp; + return error; +} + +void gdlm_put_lock(void *lock) +{ + gdlm_delete_lp(lock); +} + +unsigned int gdlm_do_lock(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + int error, bast = 1; + + /* + * When recovery is in progress, delay lock requests for submission + * once recovery is done. Requests for recovery (NOEXP) and unlocks + * can pass. + */ + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags) && + !test_bit(LFL_NOBLOCK, &lp->flags) && lp->req != DLM_LOCK_NL) { + gdlm_queue_delayed(lp); + return LM_OUT_ASYNC; + } + + /* + * Submit the actual lock request. + */ + + if (test_bit(LFL_NOBAST, &lp->flags)) + bast = 0; + + set_bit(LFL_ACTIVE, &lp->flags); + + log_debug("lk %x,%llx id %x %d,%d %x", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->lksb.sb_lkid, + lp->cur, lp->req, lp->lkf); + + error = dlm_lock(ls->dlm_lockspace, lp->req, &lp->lksb, lp->lkf, + lp->strname.name, lp->strname.namelen, 0, gdlm_ast, + lp, bast ? gdlm_bast : NULL); + + if ((error == -EAGAIN) && (lp->lkf & DLM_LKF_NOQUEUE)) { + lp->lksb.sb_status = -EAGAIN; + queue_complete(lp); + error = 0; + } + + if (error) { + log_error("%s: gdlm_lock %x,%llx err=%d cur=%d req=%d lkf=%x " + "flags=%lx", ls->fsname, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, error, + lp->cur, lp->req, lp->lkf, lp->flags); + return LM_OUT_ERROR; + } + return LM_OUT_ASYNC; +} + +static unsigned int gdlm_do_unlock(struct gdlm_lock *lp) +{ + struct gdlm_ls *ls = lp->ls; + unsigned int lkf = 0; + int error; + + set_bit(LFL_DLM_UNLOCK, &lp->flags); + set_bit(LFL_ACTIVE, &lp->flags); + + if (lp->lvb) + lkf = DLM_LKF_VALBLK; + + log_debug("un %x,%llx %x %d %x", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, + lp->lksb.sb_lkid, lp->cur, lkf); + + error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, lkf, NULL, lp); + + if (error) { + log_error("%s: gdlm_unlock %x,%llx err=%d cur=%d req=%d lkf=%x " + "flags=%lx", ls->fsname, lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, error, + lp->cur, lp->req, lp->lkf, lp->flags); + return LM_OUT_ERROR; + } + return LM_OUT_ASYNC; +} + +unsigned int gdlm_lock(void *lock, unsigned int cur_state, + unsigned int req_state, unsigned int flags) +{ + struct gdlm_lock *lp = lock; + + clear_bit(LFL_DLM_CANCEL, &lp->flags); + if (flags & LM_FLAG_NOEXP) + set_bit(LFL_NOBLOCK, &lp->flags); + + check_cur_state(lp, cur_state); + lp->req = make_mode(req_state); + lp->lkf = make_flags(lp, flags, lp->cur, lp->req); + + return gdlm_do_lock(lp); +} + +unsigned int gdlm_unlock(void *lock, unsigned int cur_state) +{ + struct gdlm_lock *lp = lock; + + clear_bit(LFL_DLM_CANCEL, &lp->flags); + if (lp->cur == DLM_LOCK_IV) + return 0; + return gdlm_do_unlock(lp); +} + +void gdlm_cancel(void *lock) +{ + struct gdlm_lock *lp = lock; + struct gdlm_ls *ls = lp->ls; + int error, delay_list = 0; + + if (test_bit(LFL_DLM_CANCEL, &lp->flags)) + return; + + log_info("gdlm_cancel %x,%llx flags %lx", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->flags); + + spin_lock(&ls->async_lock); + if (!list_empty(&lp->delay_list)) { + list_del_init(&lp->delay_list); + delay_list = 1; + } + spin_unlock(&ls->async_lock); + + if (delay_list) { + set_bit(LFL_CANCEL, &lp->flags); + set_bit(LFL_ACTIVE, &lp->flags); + queue_complete(lp); + return; + } + + if (!test_bit(LFL_ACTIVE, &lp->flags) || + test_bit(LFL_DLM_UNLOCK, &lp->flags)) { + log_info("gdlm_cancel skip %x,%llx flags %lx", + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->flags); + return; + } + + /* the lock is blocked in the dlm */ + + set_bit(LFL_DLM_CANCEL, &lp->flags); + set_bit(LFL_ACTIVE, &lp->flags); + + error = dlm_unlock(ls->dlm_lockspace, lp->lksb.sb_lkid, DLM_LKF_CANCEL, + NULL, lp); + + log_info("gdlm_cancel rv %d %x,%llx flags %lx", error, + lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number, lp->flags); + + if (error == -EBUSY) + clear_bit(LFL_DLM_CANCEL, &lp->flags); +} + +static int gdlm_add_lvb(struct gdlm_lock *lp) +{ + char *lvb; + + lvb = kzalloc(GDLM_LVB_SIZE, GFP_NOFS); + if (!lvb) + return -ENOMEM; + + lp->lksb.sb_lvbptr = lvb; + lp->lvb = lvb; + return 0; +} + +static void gdlm_del_lvb(struct gdlm_lock *lp) +{ + kfree(lp->lvb); + lp->lvb = NULL; + 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). */ + +static int hold_null_lock(struct gdlm_lock *lp) +{ + struct gdlm_lock *lpn = NULL; + int error; + + if (lp->hold_null) { + printk(KERN_INFO "lock_dlm: lvb already held\n"); + return 0; + } + + error = gdlm_create_lp(lp->ls, &lp->lockname, &lpn); + if (error) + goto out; + + lpn->lksb.sb_lvbptr = junk_lvb; + lpn->lvb = junk_lvb; + + lpn->req = DLM_LOCK_NL; + 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); + + gdlm_do_lock(lpn); + 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", + error); + gdlm_delete_lp(lpn); + lpn = NULL; + } +out: + lp->hold_null = lpn; + return error; +} + +/* This cannot do a synchronous dlm request (requiring a lock_dlm thread to get + the completion) because gfs may call unhold_lvb() during a callback (from + the context of a lock_dlm thread) which could cause a deadlock since the + other lock_dlm thread could be engaged in recovery. */ + +static void unhold_null_lock(struct gdlm_lock *lp) +{ + struct gdlm_lock *lpn = lp->hold_null; + + gdlm_assert(lpn, "%x,%llx", lp->lockname.ln_type, + (unsigned long long)lp->lockname.ln_number); + lpn->lksb.sb_lvbptr = NULL; + lpn->lvb = NULL; + set_bit(LFL_UNLOCK_DELETE, &lpn->flags); + gdlm_do_unlock(lpn); + lp->hold_null = NULL; +} + +/* Acquire a NL lock because gfs requires the value block to remain + intact on the resource while the lvb is "held" even if it's holding no locks + on the resource. */ + +int gdlm_hold_lvb(void *lock, char **lvbp) +{ + struct gdlm_lock *lp = lock; + int error; + + error = gdlm_add_lvb(lp); + if (error) + return error; + + *lvbp = lp->lvb; + + error = hold_null_lock(lp); + if (error) + gdlm_del_lvb(lp); + + return error; +} + +void gdlm_unhold_lvb(void *lock, char *lvb) +{ + struct gdlm_lock *lp = lock; + + unhold_null_lock(lp); + gdlm_del_lvb(lp); +} + +void gdlm_submit_delayed(struct gdlm_ls *ls) +{ + struct gdlm_lock *lp, *safe; + + spin_lock(&ls->async_lock); + list_for_each_entry_safe(lp, safe, &ls->delayed, delay_list) { + list_del_init(&lp->delay_list); + list_add_tail(&lp->delay_list, &ls->submit); + } + spin_unlock(&ls->async_lock); + wake_up(&ls->thread_wait); +} + +int gdlm_release_all_locks(struct gdlm_ls *ls) +{ + struct gdlm_lock *lp, *safe; + int count = 0; + + spin_lock(&ls->async_lock); + list_for_each_entry_safe(lp, safe, &ls->all_locks, all_list) { + list_del_init(&lp->all_list); + + if (lp->lvb && lp->lvb != junk_lvb) + kfree(lp->lvb); + kfree(lp); + count++; + } + spin_unlock(&ls->async_lock); + + return count; +} + --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_mount.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_mount.c @@ -0,0 +1,279 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 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 version 2. + */ + +#include "lock_dlm.h" + +const struct lm_lockops gdlm_ops; + + +static struct gdlm_ls *init_gdlm(lm_callback_t cb, struct gfs_sbd *sdp, + int flags, char *table_name) +{ + struct gdlm_ls *ls; + char buf[256], *p; + + ls = kzalloc(sizeof(struct gdlm_ls), GFP_KERNEL); + if (!ls) + return NULL; + + ls->drop_locks_count = GDLM_DROP_COUNT; + ls->drop_locks_period = GDLM_DROP_PERIOD; + ls->fscb = cb; + ls->sdp = sdp; + ls->fsflags = flags; + spin_lock_init(&ls->async_lock); + INIT_LIST_HEAD(&ls->complete); + INIT_LIST_HEAD(&ls->blocking); + INIT_LIST_HEAD(&ls->delayed); + INIT_LIST_HEAD(&ls->submit); + INIT_LIST_HEAD(&ls->all_locks); + init_waitqueue_head(&ls->thread_wait); + init_waitqueue_head(&ls->wait_control); + ls->thread1 = NULL; + ls->thread2 = NULL; + ls->drop_time = jiffies; + ls->jid = -1; + + strncpy(buf, table_name, 256); + buf[255] = '\0'; + + p = strchr(buf, ':'); + if (!p) { + log_info("invalid table_name \"%s\"", table_name); + kfree(ls); + return NULL; + } + *p = '\0'; + p++; + + strncpy(ls->clustername, buf, GDLM_NAME_LEN); + strncpy(ls->fsname, p, GDLM_NAME_LEN); + + return ls; +} + +static int make_args(struct gdlm_ls *ls, char *data_arg, int *nodir) +{ + char data[256]; + char *options, *x, *y; + int error = 0; + + memset(data, 0, 256); + strncpy(data, data_arg, 255); + + if (!strlen(data)) { + log_error("no mount options, (u)mount helpers not installed"); + return -EINVAL; + } + + for (options = data; (x = strsep(&options, ":")); ) { + if (!*x) + continue; + + y = strchr(x, '='); + if (y) + *y++ = 0; + + if (!strcmp(x, "jid")) { + if (!y) { + log_error("need argument to jid"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &ls->jid); + + } else if (!strcmp(x, "first")) { + if (!y) { + log_error("need argument to first"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &ls->first); + + } else if (!strcmp(x, "id")) { + if (!y) { + log_error("need argument to id"); + error = -EINVAL; + break; + } + sscanf(y, "%u", &ls->id); + + } else if (!strcmp(x, "nodir")) { + if (!y) { + log_error("need argument to nodir"); + error = -EINVAL; + break; + } + sscanf(y, "%u", nodir); + + } else { + log_error("unkonwn option: %s", x); + error = -EINVAL; + break; + } + } + + return error; +} + +static int gdlm_mount(char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj) +{ + struct gdlm_ls *ls; + int error = -ENOMEM, nodir = 0; + + if (min_lvb_size > GDLM_LVB_SIZE) + goto out; + + ls = init_gdlm(cb, cb_data, flags, table_name); + if (!ls) + goto out; + + error = make_args(ls, host_data, &nodir); + if (error) + goto out; + + error = gdlm_init_threads(ls); + if (error) + goto out_free; + + error = gdlm_kobject_setup(ls, fskobj); + if (error) + goto out_thread; + + error = dlm_new_lockspace(ls->fsname, strlen(ls->fsname), + &ls->dlm_lockspace, + DLM_LSFL_FS | (nodir ? DLM_LSFL_NODIR : 0), + GDLM_LVB_SIZE); + if (error) { + log_error("dlm_new_lockspace error %d", error); + goto out_kobj; + } + + lockstruct->ls_jid = ls->jid; + lockstruct->ls_first = ls->first; + lockstruct->ls_lockspace = ls; + lockstruct->ls_ops = &gdlm_ops; + lockstruct->ls_flags = 0; + lockstruct->ls_lvb_size = GDLM_LVB_SIZE; + return 0; + +out_kobj: + gdlm_kobject_release(ls); +out_thread: + gdlm_release_threads(ls); +out_free: + kfree(ls); +out: + return error; +} + +static void gdlm_unmount(void *lockspace) +{ + struct gdlm_ls *ls = lockspace; + int rv; + + log_debug("unmount flags %lx", ls->flags); + + /* FIXME: serialize unmount and withdraw in case they + happen at once. Also, if unmount follows withdraw, + wait for withdraw to finish. */ + + if (test_bit(DFL_WITHDRAW, &ls->flags)) + goto out; + + gdlm_kobject_release(ls); + dlm_release_lockspace(ls->dlm_lockspace, 2); + gdlm_release_threads(ls); + rv = gdlm_release_all_locks(ls); + if (rv) + log_info("gdlm_unmount: %d stray locks freed", rv); +out: + kfree(ls); +} + +static void gdlm_recovery_done(void *lockspace, unsigned int jid, + unsigned int message) +{ + struct gdlm_ls *ls = lockspace; + ls->recover_jid_done = jid; + ls->recover_jid_status = message; + kobject_uevent(&ls->kobj, KOBJ_CHANGE); +} + +static void gdlm_others_may_mount(void *lockspace) +{ + struct gdlm_ls *ls = lockspace; + ls->first_done = 1; + kobject_uevent(&ls->kobj, KOBJ_CHANGE); +} + +/* Userspace gets the offline uevent, blocks new gfs locks on + other mounters, and lets us know (sets WITHDRAW flag). Then, + userspace leaves the mount group while we leave the lockspace. */ + +static void gdlm_withdraw(void *lockspace) +{ + struct gdlm_ls *ls = lockspace; + + kobject_uevent(&ls->kobj, KOBJ_OFFLINE); + + wait_event_interruptible(ls->wait_control, + test_bit(DFL_WITHDRAW, &ls->flags)); + + dlm_release_lockspace(ls->dlm_lockspace, 2); + gdlm_release_threads(ls); + gdlm_release_all_locks(ls); + gdlm_kobject_release(ls); +} + +static int gdlm_plock(void *lockspace, struct lm_lockname *name, + struct file *file, int cmd, struct file_lock *fl) +{ + struct gdlm_ls *ls = lockspace; + return dlm_posix_lock(ls->dlm_lockspace, name->ln_number, file, cmd, fl); +} + +static int gdlm_punlock(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + struct gdlm_ls *ls = lockspace; + return dlm_posix_unlock(ls->dlm_lockspace, name->ln_number, file, fl); +} + +static int gdlm_plock_get(void *lockspace, struct lm_lockname *name, + struct file *file, struct file_lock *fl) +{ + struct gdlm_ls *ls = lockspace; + return dlm_posix_get(ls->dlm_lockspace, name->ln_number, file, fl); +} + +const struct lm_lockops gdlm_ops = { + .lm_proto_name = "lock_dlm", + .lm_mount = gdlm_mount, + .lm_others_may_mount = gdlm_others_may_mount, + .lm_unmount = gdlm_unmount, + .lm_withdraw = gdlm_withdraw, + .lm_get_lock = gdlm_get_lock, + .lm_put_lock = gdlm_put_lock, + .lm_lock = gdlm_lock, + .lm_unlock = gdlm_unlock, + .lm_plock = gdlm_plock, + .lm_punlock = gdlm_punlock, + .lm_plock_get = gdlm_plock_get, + .lm_cancel = gdlm_cancel, + .lm_hold_lvb = gdlm_hold_lvb, + .lm_unhold_lvb = gdlm_unhold_lvb, + .lm_recovery_done = gdlm_recovery_done, + .lm_owner = THIS_MODULE, +}; + --- linux-2.6.28.orig/ubuntu/gfs/ops_vm.c +++ linux-2.6.28/ubuntu/gfs/ops_vm.c @@ -0,0 +1,233 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "bmap.h" +#include "glock.h" +#include "inode.h" +#include "ops_vm.h" +#include "page.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" + +/** + * pfault_be_greedy - + * @ip: + * + */ + +static void +pfault_be_greedy(struct gfs_inode *ip) +{ + unsigned int time; + + spin_lock(&ip->i_spin); + time = ip->i_greedy; + ip->i_last_pfault = jiffies; + spin_unlock(&ip->i_spin); + + gfs_inode_hold(ip); + if (gfs_glock_be_greedy(ip->i_gl, time)) + gfs_inode_put(ip); +} + +/** + * gfs_private_fault - + * @area: + * @address: + * @type: + * + * Returns: the page + */ + +static int gfs_private_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + struct gfs_inode *ip = get_v2ip(vma->vm_file->f_mapping->host); + struct gfs_holder i_gh; + int error; + int ret = 0; + + atomic_inc(&ip->i_sbd->sd_ops_vm); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); + if (error) + goto out; + + set_bit(GIF_PAGED, &ip->i_flags); + + ret = filemap_fault(vma, vmf); + + if (ret && ret != VM_FAULT_OOM) + pfault_be_greedy(ip); + + gfs_glock_dq_uninit(&i_gh); + out: + return ret; +} + +/** + * alloc_page_backing - + * @ip: + * @index: + * + * Returns: errno + */ + +static int +alloc_page_backing(struct gfs_inode *ip, struct page *page) +{ + struct gfs_sbd *sdp = ip->i_sbd; + unsigned long index = page->index; + uint64_t lblock = index << (PAGE_CACHE_SHIFT - sdp->sd_sb.sb_bsize_shift); + unsigned int blocks = PAGE_CACHE_SIZE >> sdp->sd_sb.sb_bsize_shift; + struct gfs_alloc *al; + unsigned int x; + int error; + + al = gfs_alloc_get(ip); + + error = gfs_quota_lock_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid); + if (error) + goto out_gunlock_q; + + gfs_write_calc_reserv(ip, PAGE_CACHE_SIZE, + &al->al_requested_data, &al->al_requested_meta); + + error = gfs_inplace_reserve(ip); + if (error) + goto out_gunlock_q; + + /* Trans may require: + a dinode block, RG bitmaps to allocate from, + indirect blocks, and a quota block */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + al->al_requested_meta, 1); + if (error) + goto out_ipres; + + if (gfs_is_stuffed(ip)) { + error = gfs_unstuff_dinode(ip, gfs_unstuffer_page, NULL); + if (error) + goto out_trans; + } + + for (x = 0; x < blocks; ) { + uint64_t dblock; + unsigned int extlen; + int new = TRUE; + + error = gfs_block_map(ip, lblock, &new, &dblock, &extlen); + if (error) + goto out_trans; + + lblock += extlen; + x += extlen; + } + + gfs_assert_warn(sdp, al->al_alloced_meta || al->al_alloced_data); + + out_trans: + gfs_trans_end(sdp); + + out_ipres: + gfs_inplace_release(ip); + + out_gunlock_q: + gfs_quota_unlock_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * gfs_sharewrite_fault - + * @area: + * @address: + * @type: + * + * Returns: the page + */ + +static int gfs_sharewrite_fault(struct vm_area_struct *vma, + struct vm_fault *vmf) +{ + struct file *file = vma->vm_file; + struct gfs_inode *ip = get_v2ip(file->f_mapping->host); + struct gfs_holder i_gh; + int alloc_required; + int error; + int ret = 0; + + atomic_inc(&ip->i_sbd->sd_ops_vm); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + goto out; + + if (gfs_is_jdata(ip)) + goto out_unlock; + + set_bit(GIF_PAGED, &ip->i_flags); + set_bit(GIF_SW_PAGED, &ip->i_flags); + + error = gfs_write_alloc_required(ip, + (u64)vmf->pgoff << PAGE_CACHE_SHIFT, + PAGE_CACHE_SIZE, &alloc_required); + if (error) { + ret = VM_FAULT_OOM; /* XXX: are these right? */ + goto out_unlock; + } + + ret = filemap_fault(vma, vmf); + if (ret & VM_FAULT_ERROR) + goto out_unlock; + + if (alloc_required) { + /* XXX: do we need to drop page lock around alloc_page_backing?*/ + error = alloc_page_backing(ip, vmf->page); + if (error) { + /* + * VM_FAULT_LOCKED should always be the case for + * filemap_fault, but it may not be in a future + * implementation. + */ + if (ret & VM_FAULT_LOCKED) + unlock_page(vmf->page); + page_cache_release(vmf->page); + ret = VM_FAULT_OOM; + goto out_unlock; + } + set_page_dirty(vmf->page); + } + + pfault_be_greedy(ip); + + out_unlock: + gfs_glock_dq_uninit(&i_gh); + out: + return ret; +} + +struct vm_operations_struct gfs_vm_ops_private = { + .fault = gfs_private_fault, +}; + +struct vm_operations_struct gfs_vm_ops_sharewrite = { + .fault = gfs_sharewrite_fault, +}; + --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_sysfs.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_sysfs.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 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 version 2. + */ + +#include +#include + +#include "lock_dlm.h" + +static ssize_t proto_name_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%s\n", gdlm_ops.lm_proto_name); +} + +static ssize_t block_show(struct gdlm_ls *ls, char *buf) +{ + ssize_t ret; + int val = 0; + + if (test_bit(DFL_BLOCK_LOCKS, &ls->flags)) + val = 1; + ret = sprintf(buf, "%d\n", val); + return ret; +} + +static ssize_t block_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ssize_t ret = len; + int val; + + val = simple_strtol(buf, NULL, 0); + + if (val == 1) + set_bit(DFL_BLOCK_LOCKS, &ls->flags); + else if (val == 0) { + clear_bit(DFL_BLOCK_LOCKS, &ls->flags); + gdlm_submit_delayed(ls); + } else { + ret = -EINVAL; + } + return ret; +} + +static ssize_t withdraw_show(struct gdlm_ls *ls, char *buf) +{ + ssize_t ret; + int val = 0; + + if (test_bit(DFL_WITHDRAW, &ls->flags)) + val = 1; + ret = sprintf(buf, "%d\n", val); + return ret; +} + +static ssize_t withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ssize_t ret = len; + int val; + + val = simple_strtol(buf, NULL, 0); + + if (val == 1) + set_bit(DFL_WITHDRAW, &ls->flags); + else + ret = -EINVAL; + wake_up(&ls->wait_control); + return ret; +} + +static ssize_t id_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%u\n", ls->id); +} + +static ssize_t jid_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->jid); +} + +static ssize_t first_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->first); +} + +static ssize_t first_done_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->first_done); +} + +static ssize_t recover_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->recover_jid); +} + +static ssize_t recover_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ls->recover_jid = simple_strtol(buf, NULL, 0); + ls->fscb(ls->sdp, LM_CB_NEED_RECOVERY, &ls->recover_jid); + return len; +} + +static ssize_t recover_done_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->recover_jid_done); +} + +static ssize_t recover_status_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->recover_jid_status); +} + +static ssize_t drop_count_show(struct gdlm_ls *ls, char *buf) +{ + return sprintf(buf, "%d\n", ls->drop_locks_count); +} + +static ssize_t drop_count_store(struct gdlm_ls *ls, const char *buf, size_t len) +{ + ls->drop_locks_count = simple_strtol(buf, NULL, 0); + return len; +} + +struct gdlm_attr { + struct attribute attr; + ssize_t (*show)(struct gdlm_ls *, char *); + ssize_t (*store)(struct gdlm_ls *, const char *, size_t); +}; + +#define GDLM_ATTR(_name,_mode,_show,_store) \ +static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) + +GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); +GDLM_ATTR(block, 0644, block_show, block_store); +GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); +GDLM_ATTR(id, 0444, id_show, NULL); +GDLM_ATTR(jid, 0444, jid_show, NULL); +GDLM_ATTR(first, 0444, first_show, NULL); +GDLM_ATTR(first_done, 0444, first_done_show, NULL); +GDLM_ATTR(recover, 0644, recover_show, recover_store); +GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); +GDLM_ATTR(recover_status, 0444, recover_status_show, NULL); +GDLM_ATTR(drop_count, 0644, drop_count_show, drop_count_store); + +static struct attribute *gdlm_attrs[] = { + &gdlm_attr_proto_name.attr, + &gdlm_attr_block.attr, + &gdlm_attr_withdraw.attr, + &gdlm_attr_id.attr, + &gdlm_attr_jid.attr, + &gdlm_attr_first.attr, + &gdlm_attr_first_done.attr, + &gdlm_attr_recover.attr, + &gdlm_attr_recover_done.attr, + &gdlm_attr_recover_status.attr, + &gdlm_attr_drop_count.attr, + NULL, +}; + +static ssize_t gdlm_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj); + struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr); + return a->show ? a->show(ls, buf) : 0; +} + +static ssize_t gdlm_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj); + struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr); + return a->store ? a->store(ls, buf, len) : len; +} + +static struct sysfs_ops gdlm_attr_ops = { + .show = gdlm_attr_show, + .store = gdlm_attr_store, +}; + +static struct kobj_type gdlm_ktype = { + .default_attrs = gdlm_attrs, + .sysfs_ops = &gdlm_attr_ops, +}; + +static struct kset *gdlm_kset; + +int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj) +{ + int error; + + ls->kobj.kset = gdlm_kset; + error = kobject_init_and_add(&ls->kobj, &gdlm_ktype, fskobj, + "lock_module"); + if (error) + log_error("can't register kobj %d", error); + kobject_uevent(&ls->kobj, KOBJ_ADD); + + return error; +} + +void gdlm_kobject_release(struct gdlm_ls *ls) +{ + kobject_put(&ls->kobj); +} + +int gdlm_sysfs_init(void) +{ + gdlm_kset = kset_create_and_add("lock_dlm_gfs", NULL, kernel_kobj); + if (!gdlm_kset) { + printk(KERN_WARNING "%s: can not create kset\n", __FUNCTION__); + return -ENOMEM; + } + return 0; +} + +void gdlm_sysfs_exit(void) +{ + kset_unregister(gdlm_kset); +} + --- linux-2.6.28.orig/ubuntu/gfs/ops_super.c +++ linux-2.6.28/ubuntu/gfs/ops_super.c @@ -0,0 +1,455 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "glock.h" +#include "inode.h" +#include "lm.h" +#include "log.h" +#include "ops_fstype.h" +#include "ops_super.h" +#include "page.h" +#include "proc.h" +#include "quota.h" +#include "recovery.h" +#include "rgrp.h" +#include "super.h" +#include "sys.h" +#include "mount.h" + +/** + * gfs_write_inode - Make sure the inode is stable on the disk + * @inode: The inode + * @sync: synchronous write flag + * + * Returns: errno + */ + +static int +gfs_write_inode(struct inode *inode, int sync) +{ + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&ip->i_sbd->sd_ops_super); + + if (ip && sync) + gfs_log_flush_glock(ip->i_gl); + + return 0; +} + +/** + * gfs_drop_inode - drop an inode + * @inode: The inode + * + * If i_nlink is zero, any dirty data for the inode is thrown away. + * If a process on another machine has the file open, it may need that + * data. So, sync it out. + */ + +static void +gfs_drop_inode(struct inode *inode) +{ + struct gfs_sbd *sdp = get_v2sdp(inode->i_sb); + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&sdp->sd_ops_super); + + if (ip && + !inode->i_nlink && + S_ISREG(inode->i_mode) && + !sdp->sd_args.ar_localcaching) + gfs_sync_page_i(inode, DIO_START | DIO_WAIT); + generic_drop_inode(inode); +} + +/** + * gfs_put_super - Unmount the filesystem + * @sb: The VFS superblock + * + */ + +static void +gfs_put_super(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + int error; + + if (!sdp) + return; + + atomic_inc(&sdp->sd_ops_super); + + gfs_proc_fs_del(sdp); + + /* Unfreeze the filesystem, if we need to */ + + down(&sdp->sd_freeze_lock); + if (sdp->sd_freeze_count) + gfs_glock_dq_uninit(&sdp->sd_freeze_gh); + up(&sdp->sd_freeze_lock); + + /* Kill off the inode thread */ + kthread_stop(sdp->sd_inoded_process); + + /* Kill off the quota thread */ + kthread_stop(sdp->sd_quotad_process); + + /* Kill off the log thread */ + kthread_stop(sdp->sd_logd_process); + + /* Kill off the recoverd thread */ + kthread_stop(sdp->sd_recoverd_process); + + /* Kill off the glockd threads */ + while (sdp->sd_glockd_num--) + kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]); + + /* Kill off the scand thread */ + kthread_stop(sdp->sd_scand_process); + + if (!test_bit(SDF_ROFS, &sdp->sd_flags)) { + error = gfs_make_fs_ro(sdp); + if (error) + gfs_io_error(sdp); + } + + /* At this point, we're through modifying the disk */ + + /* Release stuff */ + + gfs_inode_put(sdp->sd_riinode); + gfs_inode_put(sdp->sd_jiinode); + gfs_inode_put(sdp->sd_rooti); + gfs_inode_put(sdp->sd_qinode); + gfs_inode_put(sdp->sd_linode); + gfs_glock_put(sdp->sd_trans_gl); + gfs_glock_put(sdp->sd_rename_gl); + + if (!sdp->sd_args.ar_spectator) + gfs_glock_dq_uninit(&sdp->sd_journal_gh); + + gfs_glock_dq_uninit(&sdp->sd_live_gh); + + /* Get rid of rgrp bitmap structures */ + gfs_clear_rgrpd(sdp); + gfs_clear_journals(sdp); + + /* Take apart glock structures and buffer lists */ + gfs_gl_hash_clear(sdp, TRUE); + + /* Unmount the locking protocol */ + gfs_lm_unmount(sdp); + + /* At this point, we're through participating in the lockspace */ + + gfs_sys_fs_del(sdp); + + gfs_clear_dirty_j(sdp); + + /* Get rid of any extra inodes */ + while (invalidate_inodes(sb)) + yield(); + + vfree(sdp); + + set_v2sdp(sb, NULL); +} + +/** + * gfs_write_super - disk commit all incore transactions + * @sb: the filesystem + * + * This function is called every time sync(2) is called. + * After this exits, all dirty buffers and synced. + */ + +static void +gfs_write_super(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + atomic_inc(&sdp->sd_ops_super); + gfs_log_flush(sdp); +} + +/** + * gfs_write_super_lockfs - prevent further writes to the filesystem + * @sb: the VFS structure for the filesystem + * + */ + +static void +gfs_write_super_lockfs(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + int error; + + if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + return; + + atomic_inc(&sdp->sd_ops_super); + + for (;;) { + error = gfs_freeze_fs(sdp); + if (!error) + break; + + switch (error) { + case -EBUSY: + printk("GFS: fsid=%s: waiting for recovery before freeze\n", + sdp->sd_fsname); + break; + + default: + printk("GFS: fsid=%s: error freezing FS: %d\n", + sdp->sd_fsname, error); + break; + } + + printk("GFS: fsid=%s: retrying...\n", sdp->sd_fsname); + + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(HZ); + } +} + +/** + * gfs_unlockfs - reallow writes to the filesystem + * @sb: the VFS structure for the filesystem + * + */ + +static void +gfs_unlockfs(struct super_block *sb) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + + atomic_inc(&sdp->sd_ops_super); + + gfs_unfreeze_fs(sdp); +} + +/** + * gfs_statfs - Gather and return stats about the filesystem + * @sb: The superblock + * @statfsbuf: The buffer + * + * Returns: 0 on success or error code + */ + +static int gfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct super_block *sb = dentry->d_inode->i_sb; + struct gfs_sbd *sdp = get_v2sdp(sb); + struct gfs_stat_gfs sg; + int error; + + atomic_inc(&sdp->sd_ops_super); + + if (gfs_tune_get(sdp, gt_statfs_fast)) + return(gfs_statfs_fast(sdp, (void *)buf)); + + error = gfs_stat_gfs(sdp, &sg, TRUE); + if (error) + return error; + + memset(buf, 0, sizeof(struct kstatfs)); + + buf->f_type = GFS_MAGIC; + buf->f_bsize = sdp->sd_sb.sb_bsize; + buf->f_blocks = sg.sg_total_blocks; + buf->f_bfree = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; + buf->f_bavail = sg.sg_free + sg.sg_free_dinode + sg.sg_free_meta; + buf->f_files = sg.sg_used_dinode + sg.sg_free_dinode + + sg.sg_free_meta + sg.sg_free; + buf->f_ffree = sg.sg_free_dinode + sg.sg_free_meta + sg.sg_free; + buf->f_namelen = GFS_FNAMESIZE; + + return 0; +} + +/** + * gfs_remount_fs - called when the FS is remounted + * @sb: the filesystem + * @flags: the remount flags + * @data: extra data passed in (not used right now) + * + * Returns: errno + */ + +static int +gfs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + struct gfs_sbd *sdp = get_v2sdp(sb); + struct gfs_tune *gt = &sdp->sd_tune; + int error = 0; + struct gfs_args *args; + + atomic_inc(&sdp->sd_ops_super); + + args = kmalloc(sizeof(struct gfs_args), GFP_KERNEL); + if (!args) + return -ENOMEM; + + error = gfs_make_args(data, args, TRUE); + if (error) { + printk("GFS: can't parse remount arguments\n"); + goto out; + } + if (args->ar_posix_acls) { + sdp->sd_args.ar_posix_acls = TRUE; + sb->s_flags |= MS_POSIXACL; + } + else { + sdp->sd_args.ar_posix_acls = FALSE; + sb->s_flags &= ~MS_POSIXACL; + } + + if (*flags & (MS_NOATIME | MS_NODIRATIME)) + set_bit(SDF_NOATIME, &sdp->sd_flags); + else + clear_bit(SDF_NOATIME, &sdp->sd_flags); + + if (sdp->sd_args.ar_spectator) + *flags |= MS_RDONLY; + else { + if (*flags & MS_RDONLY) { + if (!test_bit(SDF_ROFS, &sdp->sd_flags)) + error = gfs_make_fs_ro(sdp); + } else if (!(*flags & MS_RDONLY) && + test_bit(SDF_ROFS, &sdp->sd_flags)) { + error = gfs_make_fs_rw(sdp); + } + } + + if (args->ar_noquota) { + if (sdp->sd_args.ar_noquota == FALSE) + printk("GFS: remounting without quota\n"); + sdp->sd_args.ar_noquota = TRUE; + spin_lock(>->gt_spin); + gt->gt_quota_enforce = 0; + gt->gt_quota_account = 0; + spin_unlock(>->gt_spin); + } + else { + if (sdp->sd_args.ar_noquota == TRUE) + printk("GFS: remounting with quota\n"); + sdp->sd_args.ar_noquota = FALSE; + spin_lock(>->gt_spin); + gt->gt_quota_enforce = 1; + gt->gt_quota_account = 1; + spin_unlock(>->gt_spin); + } + + /* Don't let the VFS update atimes. GFS handles this itself. */ + *flags |= MS_NOATIME | MS_NODIRATIME; + +out: + kfree(args); + return error; +} + +/** + * gfs_clear_inode - Deallocate an inode when VFS is done with it + * @inode: The VFS inode + * + * If there's a GFS incore inode structure attached to the VFS inode: + * -- Detach them from one another. + * -- Schedule reclaim of GFS inode struct, the glock protecting it, and + * the associated iopen glock. + */ + +static void +gfs_clear_inode(struct inode *inode) +{ + struct gfs_inode *ip = get_v2ip(inode); + + atomic_inc(&get_v2sdp(inode->i_sb)->sd_ops_super); + + if (ip) { + spin_lock(&ip->i_spin); + ip->i_vnode = NULL; + set_v2ip(inode, NULL); + spin_unlock(&ip->i_spin); + + gfs_glock_schedule_for_reclaim(ip->i_gl); + gfs_inode_put(ip); + } +} + +/** + * gfs_show_options - Show mount options for /proc/mounts + * @s: seq_file structure + * @mnt: vfsmount + * + * Returns: 0 on success or error code + */ + +static int +gfs_show_options(struct seq_file *s, struct vfsmount *mnt) +{ + struct gfs_sbd *sdp = get_v2sdp(mnt->mnt_sb); + struct gfs_args *args = &sdp->sd_args; + + atomic_inc(&sdp->sd_ops_super); + + if (args->ar_lockproto[0]) { + seq_printf(s, ",lockproto="); + seq_puts(s, args->ar_lockproto); + } + if (args->ar_locktable[0]) { + seq_printf(s, ",locktable="); + seq_puts(s, args->ar_locktable); + } + if (args->ar_hostdata[0]) { + seq_printf(s, ",hostdata="); + seq_puts(s, args->ar_hostdata); + } + if (args->ar_spectator) + seq_printf(s, ",spectator"); + if (args->ar_ignore_local_fs) + seq_printf(s, ",ignore_local_fs"); + if (args->ar_localflocks) + seq_printf(s, ",localflocks"); + if (args->ar_localcaching) + seq_printf(s, ",localcaching"); + if (args->ar_oopses_ok) + seq_printf(s, ",oopses_ok"); + if (args->ar_debug) + seq_printf(s, ",debug"); + if (args->ar_upgrade) + seq_printf(s, ",upgrade"); + if (args->ar_num_glockd != GFS_GLOCKD_DEFAULT) + seq_printf(s, ",num_glockd=%u", args->ar_num_glockd); + if (args->ar_posix_acls) + seq_printf(s, ",acl"); + if (args->ar_noquota) + seq_printf(s, ",noquota"); + if (args->ar_suiddir) + seq_printf(s, ",suiddir"); + + return 0; +} + +struct super_operations gfs_super_ops = { + .write_inode = gfs_write_inode, + .drop_inode = gfs_drop_inode, + .put_super = gfs_put_super, + .write_super = gfs_write_super, + .write_super_lockfs = gfs_write_super_lockfs, + .unlockfs = gfs_unlockfs, + .statfs = gfs_statfs, + .remount_fs = gfs_remount_fs, + .clear_inode = gfs_clear_inode, + .show_options = gfs_show_options, +}; --- linux-2.6.28.orig/ubuntu/gfs/log.c +++ linux-2.6.28/ubuntu/gfs/log.c @@ -0,0 +1,1429 @@ +/* + What rolls down stairs + Alone or in pairs + Rolls over your neighbor's dog. + What's great for a snack + And fits on your back + It's log, log, log! + It's lo-og, lo-og, + It's big, it's heavy, it's wood. + It's lo-og, lo-og, + It's better than bad, it's good. + Everyone wants a log, + You're gonna love it, log + Come on and get your log, + Everyone needs a log... + LOG... FROM BLAMMO! + + -- The Ren and Stimpy Show +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "dio.h" +#include "log.h" +#include "lops.h" + +/** + * gfs_struct2blk - compute stuff + * @sdp: the filesystem + * @nstruct: the number of structures + * @ssize: the size of the structures + * + * Compute the number of log descriptor blocks needed to hold a certain number + * of structures of a certain size. + * + * Returns: the number of blocks needed (minimum is always 1) + */ + +unsigned int +gfs_struct2blk(struct gfs_sbd *sdp, unsigned int nstruct, unsigned int ssize) +{ + unsigned int blks; + unsigned int first, second; + + blks = 1; + first = (sdp->sd_sb.sb_bsize - sizeof(struct gfs_log_descriptor)) / ssize; + + if (nstruct > first) { + second = sdp->sd_sb.sb_bsize / ssize; + blks += DIV_RU(nstruct - first, second); + } + + return blks; +} + +/** + * gfs_blk2seg - Convert number of blocks into number of segments + * @sdp: The GFS superblock + * @blocks: The number of blocks + * + * Returns: The number of journal segments + */ + +unsigned int +gfs_blk2seg(struct gfs_sbd *sdp, unsigned int blocks) +{ + return DIV_RU(blocks, sdp->sd_sb.sb_seg_size - 1); +} + +/** + * log_distance - Compute distance between two journal blocks + * @sdp: The GFS superblock + * @newer: The most recent journal block of the pair + * @older: The older journal block of the pair + * + * Compute the distance (in the journal direction) between two + * blocks in the journal + * + * Returns: the distance in blocks + */ + +static __inline__ unsigned int +log_distance(struct gfs_sbd *sdp, uint64_t newer, uint64_t older) +{ + int64_t dist; + + dist = newer - older; + if (dist < 0) + dist += sdp->sd_jdesc.ji_nsegment * sdp->sd_sb.sb_seg_size; + + return dist; +} + +/** + * log_incr_head - Increment journal head (next block to fill in journal) + * @sdp: The GFS superblock + * @head: the variable holding the head of the journal + * + * Increment journal head by one. + * At the end of the journal, wrap head back to the start. + * Don't confuse journal/log head with a gfs_log_header! + */ + +static __inline__ void +log_incr_head(struct gfs_sbd *sdp, uint64_t * head) +{ + struct gfs_jindex *jdesc = &sdp->sd_jdesc; + + if (++*head == + jdesc->ji_addr + jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size) + *head = jdesc->ji_addr; +} + +/** + * gfs_ail_start - Start I/O on the AIL + * @sdp: the filesystem + * @flags: DIO_ALL -- flush *all* AIL transactions to disk + * default -- flush first-on-list AIL transaction to disk + * + */ + +void +gfs_ail_start(struct gfs_sbd *sdp, int flags) +{ + struct list_head *head = &sdp->sd_log_ail; + struct list_head *first, *tmp; + struct gfs_trans *first_tr, *tr; + + gfs_log_lock(sdp); + + if (list_empty(head)) { + gfs_log_unlock(sdp); + return; + } + + first = head->prev; + first_tr = list_entry(first, struct gfs_trans, tr_list); + gfs_ail_start_trans(sdp, first_tr); + + if (flags & DIO_ALL) + first_tr = NULL; + + for (tmp = first->prev; tmp != head; tmp = tmp->prev) { + if (first_tr && gfs_ail_empty_trans(sdp, first_tr)) + break; + + tr = list_entry(tmp, struct gfs_trans, tr_list); + gfs_ail_start_trans(sdp, tr); + } + + gfs_log_unlock(sdp); +} + +/** + * current_tail - Find block number of current log tail + * @sdp: The GFS superblock + * + * Find the block number of the current tail of the log. + * Assumes that the log lock is held. + * + * Returns: The tail's block number (must be on a log segment boundary) + */ + +static uint64_t +current_tail(struct gfs_sbd *sdp) +{ + struct gfs_trans *tr; + uint64_t tail; + + if (list_empty(&sdp->sd_log_ail)) { + tail = sdp->sd_log_head; + + if (!gfs_log_is_header(sdp, tail)) { + tail--; + gfs_assert(sdp, gfs_log_is_header(sdp, tail), ); + } + } else { + tr = list_entry(sdp->sd_log_ail.prev, + struct gfs_trans, tr_list); + tail = tr->tr_first_head; + } + + return tail; +} + +/** + * gfs_ail_empty - move the tail of the log forward (if possible) + * @sdp: the filesystem + * + * Returns: TRUE if the AIL is empty + * + * Checks each transaction on sd_log_ail, to see if it has been successfully + * flushed to in-place blocks on disk. If so, removes trans from sd_log_ail, + * effectively advancing the tail of the log (freeing log segments so they + * can be overwritten). + * Adds # freed log segments to sd_log_seg_free. + */ + +int +gfs_ail_empty(struct gfs_sbd *sdp) +{ + struct list_head *head, *tmp, *prev; + struct gfs_trans *tr; + uint64_t oldtail, newtail; + unsigned int dist; + unsigned int segments; + int ret; + + gfs_log_lock(sdp); + + oldtail = current_tail(sdp); + + for (head = &sdp->sd_log_ail, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + tr = list_entry(tmp, struct gfs_trans, tr_list); + if (gfs_ail_empty_trans(sdp, tr)) { + list_del(&tr->tr_list); + kfree(tr); + } + } + + newtail = current_tail(sdp); + + if (oldtail != newtail) { + dist = log_distance(sdp, newtail, oldtail); + + segments = dist / sdp->sd_sb.sb_seg_size; + gfs_assert(sdp, segments * sdp->sd_sb.sb_seg_size == dist,); + + sdp->sd_log_seg_ail2 += segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + } + + ret = list_empty(head); + + gfs_log_unlock(sdp); + + return ret; +} + +/** + * gfs_log_reserve - Make a log reservation + * @sdp: The GFS superblock + * @segments: The number of segments to reserve + * @jump_queue: if TRUE, don't care about fairness ordering + * + * Returns: errno + */ + +int +gfs_log_reserve(struct gfs_sbd *sdp, unsigned int segments, int jump_queue) +{ + struct list_head list; + unsigned int try = 0; + + if (gfs_assert_warn(sdp, segments)) + return -EINVAL; + if (gfs_assert_warn(sdp, segments < sdp->sd_jdesc.ji_nsegment)) + return -EINVAL; + + INIT_LIST_HEAD(&list); + + for (;;) { + spin_lock(&sdp->sd_log_seg_lock); + + if (list_empty(&list)) { + if (jump_queue) + list_add(&list, &sdp->sd_log_seg_list); + else { + list_add_tail(&list, &sdp->sd_log_seg_list); + while (sdp->sd_log_seg_list.next != &list) { + DECLARE_WAITQUEUE(__wait_chan, current); + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&sdp->sd_log_seg_wait, + &__wait_chan); + spin_unlock(&sdp->sd_log_seg_lock); + schedule(); + spin_lock(&sdp->sd_log_seg_lock); + remove_wait_queue(&sdp->sd_log_seg_wait, + &__wait_chan); + set_current_state(TASK_RUNNING); + } + } + } + + if (sdp->sd_log_seg_free > segments) { + sdp->sd_log_seg_free -= segments; + list_del(&list); + spin_unlock(&sdp->sd_log_seg_lock); + wake_up(&sdp->sd_log_seg_wait); + break; + } + + spin_unlock(&sdp->sd_log_seg_lock); + + if (try) { + gfs_log_flush(sdp); + gfs_ail_start(sdp, 0); + } + + gfs_ail_empty(sdp); + + try++; + yield(); + } + + return 0; +} + +/** + * gfs_log_release - Release a given number of log segments + * @sdp: The GFS superblock + * @segments: The number of segments + * + */ + +void +gfs_log_release(struct gfs_sbd *sdp, unsigned int segments) +{ + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); +} + +/** + * log_get_header - Get and initialize a journal header buffer + * @sdp: The GFS superblock + * @tr: The transaction that needs a log header + * @next: FALSE if this log header appears in midst of current transaction + * TRUE if this starts next transaction (and commits current trans) + * + * Returns: the initialized log buffer descriptor + * + * Initialize one of the transaction's pre-allocated buffers (and associated + * log buffer descriptor) to be a log header for this transaction. + * A log header gets written to *each* log segment boundary block, so journal + * recovery will quickly be able to get its bearings. A single transaction + * may span several log segments, which means that log headers will appear + * in the midst of that transaction (@next == FALSE). These headers get + * added to trans' list of buffers to write to log. + * Log commit is accomplished by writing the log header for the next + * transaction (@next == TRUE), with pre-incremented sequence number, + * and updated first-in-transaction block number. These headers do *not* get + * added to trans' buffer list, since they are written separately to disk + * *after* the trans gets completely flushed to on-disk log. + * NOTE: This buffer will *not* get written to an in-place location in the + * filesystem; it is for use only within the log. + */ + +static struct gfs_log_buf * +log_get_header(struct gfs_sbd *sdp, struct gfs_trans *tr, int next) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + struct gfs_log_header header; + + /* Make sure we're on a log segment boundary block */ + gfs_assert(sdp, gfs_log_is_header(sdp, tr->tr_log_head),); + + /* Grab a free log buffer descriptor (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bufs && + !list_empty(&tr->tr_free_bufs),); + lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + tr->tr_num_free_bufs--; + + /* Grab a free log buffer (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bmem && + !list_empty(&tr->tr_free_bmem),); + bmem = tr->tr_free_bmem.next; + list_del(bmem); + tr->tr_num_free_bmem--; + + /* Create "fake" bh to write bmem to log header block */ + gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, (char *)bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + + memset(&header, 0, sizeof (header)); + + if (next) { + /* Fill in header for next transaction, committing previous */ + header.lh_header.mh_magic = GFS_MAGIC; + header.lh_header.mh_type = GFS_METATYPE_LH; + header.lh_header.mh_format = GFS_FORMAT_LH; + header.lh_first = tr->tr_log_head; + header.lh_sequence = sdp->sd_sequence + 1; + header.lh_tail = current_tail(sdp); + header.lh_last_dump = sdp->sd_log_dump_last; + } else { + /* Fill in another header for this transaction */ + header.lh_header.mh_magic = GFS_MAGIC; + header.lh_header.mh_type = GFS_METATYPE_LH; + header.lh_header.mh_format = GFS_FORMAT_LH; + header.lh_first = tr->tr_first_head; + header.lh_sequence = sdp->sd_sequence; + header.lh_tail = current_tail(sdp); + header.lh_last_dump = sdp->sd_log_dump_last; + + /* Attach log header buf to trans' list of bufs going to log */ + list_add(&lb->lb_list, &tr->tr_bufs); + } + + /* Copy log header struct to beginning and end of buffer's 1st 512B */ + gfs_log_header_out(&header, lb->lb_bh.b_data); + gfs_log_header_out(&header, + lb->lb_bh.b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + + /* Find next log buffer to fill */ + log_incr_head(sdp, &tr->tr_log_head); + + return lb; +} + +/** + * gfs_log_get_buf - Get and initialize a buffer to use for log control data + * @sdp: The GFS superblock + * @tr: The GFS transaction + * + * Initialize one of the transaction's pre-allocated buffers (and associated + * log buffer descriptor) to be used for log control data (e.g. log tags). + * Make sure this buffer is attached to the transaction, to be logged to disk. + * NOTE: This buffer will *not* get written to an in-place location in the + * filesystem; it is for use only within the log. + * + * Returns: the log buffer descriptor + */ + +struct gfs_log_buf * +gfs_log_get_buf(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + + /* If next block in log is on a segment boundary, we need to + write a log header */ + if (gfs_log_is_header(sdp, tr->tr_log_head)) + log_get_header(sdp, tr, FALSE); + + /* Grab a free buffer descriptor (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bufs && + !list_empty(&tr->tr_free_bufs),); + lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + tr->tr_num_free_bufs--; + + /* Grab a free buffer (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bmem + && !list_empty(&tr->tr_free_bmem),); + bmem = tr->tr_free_bmem.next; + list_del(bmem); + tr->tr_num_free_bmem--; + + /* Create "fake" bh to write bmem to log block */ + gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, (char *)bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + + list_add(&lb->lb_list, &tr->tr_bufs); + + /* Find next log buffer to fill */ + log_incr_head(sdp, &tr->tr_log_head); + + return lb; +} + +/** + * gfs_log_fake_buf - Build a fake buffer head to write metadata buffer to log + * @sdp: the filesystem + * @tr: the transaction this is part of + * @data: the data the buffer_head should point to + * @unlock: a buffer_head to be unlocked when struct gfs_log_buf is torn down + * (i.e. the "real" buffer_head that will write to in-place location) + * + * Initialize one of the transaction's pre-allocated log buffer descriptors + * to be used for writing a metadata buffer into the log. + * Make sure this buffer is attached to the transaction, to be logged to disk. + * NOTE: This buffer *will* be written to in-place location within filesytem, + * in addition to being written into the log. + * + */ + +void +gfs_log_fake_buf(struct gfs_sbd *sdp, struct gfs_trans *tr, char *data, + struct buffer_head *unlock) +{ + struct gfs_log_buf *lb; + + if (gfs_log_is_header(sdp, tr->tr_log_head)) + log_get_header(sdp, tr, FALSE); + + /* Grab a free buffer descriptor (attached to trans) */ + gfs_assert(sdp, tr->tr_num_free_bufs && + !list_empty(&tr->tr_free_bufs),); + lb = list_entry(tr->tr_free_bufs.next, struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + tr->tr_num_free_bufs--; + + /* Create "fake" bh to write data to log block */ + gfs_logbh_init(sdp, &lb->lb_bh, tr->tr_log_head, data); + lb->lb_unlock = unlock; + + list_add(&lb->lb_list, &tr->tr_bufs); + + /* Find next log buffer to fill */ + log_incr_head(sdp, &tr->tr_log_head); +} + +/** + * check_seg_usage - Check that we didn't use too many segments + * @sdp: The GFS superblock + * @tr: The transaction + * + * Also, make sure we don't write ever get to a point where there are + * no dumps in the log (corrupting the log). Panic before we let + * that happen. + * + */ + +static void +check_seg_usage(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_jindex *jdesc = &sdp->sd_jdesc; + unsigned int dist; + unsigned int segments; + uint64_t head_off, head_wrap; + uint64_t dump_off, dump_wrap; + + dist = log_distance(sdp, tr->tr_log_head, tr->tr_first_head); + + segments = dist / sdp->sd_sb.sb_seg_size; + gfs_assert(sdp, segments * sdp->sd_sb.sb_seg_size == dist,); + gfs_assert(sdp, segments == tr->tr_seg_reserved,); + + if (sdp->sd_log_dump_last) { + int diff; + + head_off = tr->tr_first_head + + tr->tr_seg_reserved * sdp->sd_sb.sb_seg_size; + head_wrap = sdp->sd_log_wrap; + if (head_off >= jdesc->ji_addr + + jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size) { + head_off -= jdesc->ji_nsegment * sdp->sd_sb.sb_seg_size; + head_wrap++; + } + + dump_off = sdp->sd_log_dump_last; + dump_wrap = sdp->sd_log_dump_last_wrap; + + diff = (int)(head_wrap - dump_wrap); + switch (diff) { + case 0: + break; + + case 1: + if (head_off < dump_off - sdp->sd_sb.sb_seg_size) + break; + else if (head_off <= dump_off && + (tr->tr_flags & TRF_LOG_DUMP)) + break; + + default: + gfs_assert(sdp, FALSE, + printk("GFS: fsid=%s: head_off = %"PRIu64", head_wrap = %"PRIu64"\n" + "GFS: fsid=%s: dump_off = %"PRIu64", dump_wrap = %"PRIu64"\n", + sdp->sd_fsname, head_off, head_wrap, + sdp->sd_fsname, dump_off, dump_wrap);); + break; + } + } +} + +/** + * log_free_buf - Free a struct gfs_log_buf (and possibly the data it points to) + * @sdp: the filesystem + * @lb: the log buffer descriptor + * + * If buffer contains (meta)data to be written into filesystem in-place block, + * descriptor will point to the "real" (lb_unlock) buffer head. Unlock it. + * If buffer was used only for log header or control data (e.g. tags), we're + * done with it as soon as it gets written to on-disk log. Free it. + * Either way, we can free the log descriptor structure. + */ + +static void +log_free_buf(struct gfs_sbd *sdp, struct gfs_log_buf *lb) +{ + char *bmem; + + bmem = lb->lb_bh.b_data; + gfs_logbh_uninit(sdp, &lb->lb_bh); + + if (lb->lb_unlock) + gfs_unlock_buffer(lb->lb_unlock); + else + kfree(bmem); + + kfree(lb); +} + +/** + * sync_trans - Add "last" descriptor, sync transaction to on-disk log + * @sdp: The GFS superblock + * @tr: The transaction + * + * Add the "last" descriptor onto the end of the current transaction + * and sync the whole transaction out to on-disk log. + * Don't log-commit (i.e. write next transaction's log header) yet, though. + * + * Returns: errno + */ + +static int +sync_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct list_head *tmp, *head, *prev; + struct gfs_log_descriptor desc; + struct gfs_log_buf *lb; + uint64_t blk; + int error = 0, e; + + /* Build LAST descriptor */ + + lb = gfs_log_get_buf(sdp, tr); + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_LAST; + desc.ld_length = 1; + for (blk = tr->tr_log_head; !gfs_log_is_header(sdp, blk); blk++) + desc.ld_length++; + gfs_desc_out(&desc, lb->lb_bh.b_data); + + while (!gfs_log_is_header(sdp, tr->tr_log_head)) + log_incr_head(sdp, &tr->tr_log_head); + + check_seg_usage(sdp, tr); + + /* Start I/O + Go in "prev" direction to start the I/O in order. */ + + for (head = &tr->tr_bufs, tmp = head->prev, prev = tmp->prev; + tmp != head; + tmp = prev, prev = tmp->prev) { + lb = list_entry(tmp, struct gfs_log_buf, lb_list); + gfs_logbh_start(sdp, &lb->lb_bh); + } + + /* Wait on I/O + Go in "next" direction to minimize sleeps/wakeups. */ + + while (!list_empty(&tr->tr_bufs)) { + lb = list_entry(tr->tr_bufs.next, struct gfs_log_buf, lb_list); + + e = gfs_logbh_wait(sdp, &lb->lb_bh); + if (e) + error = e; + + list_del(&lb->lb_list); + log_free_buf(sdp, lb); + } + + return error; +} + +/** + * commit_trans - Commit the current transaction + * @sdp: The GFS superblock + * @tr: The transaction + * + * Write next header to commit + * + * Returns: errno + */ + +static int +commit_trans(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + int error; + + lb = log_get_header(sdp, tr, TRUE); + + gfs_logbh_start(sdp, &lb->lb_bh); + error = gfs_logbh_wait(sdp, &lb->lb_bh); + if (!error) { + spin_lock(&sdp->sd_log_seg_lock); + if (!(tr->tr_flags & TRF_DUMMY)) + sdp->sd_log_seg_free += sdp->sd_log_seg_ail2; + else + sdp->sd_log_seg_free += (sdp->sd_log_seg_ail2 - 1); + sdp->sd_log_seg_ail2 = 0; + spin_unlock(&sdp->sd_log_seg_lock); + } + log_free_buf(sdp, lb); + + return error; +} + +/** + * disk_commit - Write a transaction to the on-disk journal + * @sdp: The GFS superblock + * @tr: The transaction + * + * Returns: errno + */ + +static int +disk_commit(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + uint64_t last_dump, last_dump_wrap; + int error = 0; + + gfs_assert(sdp, !test_bit(SDF_ROFS, &sdp->sd_flags),); + tr->tr_log_head = sdp->sd_log_head; + tr->tr_first_head = tr->tr_log_head - 1; + gfs_assert(sdp, gfs_log_is_header(sdp, tr->tr_first_head),); + + LO_BUILD_BHLIST(sdp, tr); + + if (!(tr->tr_flags & TRF_DUMMY)) + gfs_assert(sdp, !list_empty(&tr->tr_bufs),); + + error = sync_trans(sdp, tr); + if (error) { + /* Eat unusable commit buffer */ + log_free_buf(sdp, log_get_header(sdp, tr, TRUE)); + goto out; + } + + if (tr->tr_flags & TRF_LOG_DUMP) { + /* This commit header should point to the log dump we're + commiting as the current one. But save the copy of the + old one in case we have problems commiting the dump. */ + + last_dump = sdp->sd_log_dump_last; + last_dump_wrap = sdp->sd_log_dump_last_wrap; + + sdp->sd_log_dump_last = tr->tr_first_head; + sdp->sd_log_dump_last_wrap = sdp->sd_log_wrap; + + error = commit_trans(sdp, tr); + if (error) { + sdp->sd_log_dump_last = last_dump; + sdp->sd_log_dump_last_wrap = last_dump_wrap; + goto out; + } + } else { + error = commit_trans(sdp, tr); + if (error) + goto out; + } + + if (sdp->sd_log_head > tr->tr_log_head) + sdp->sd_log_wrap++; + sdp->sd_log_head = tr->tr_log_head; + sdp->sd_sequence++; + + out: + gfs_assert_warn(sdp, !tr->tr_num_free_bufs && + list_empty(&tr->tr_free_bufs)); + gfs_assert_warn(sdp, !tr->tr_num_free_bmem && + list_empty(&tr->tr_free_bmem)); + + return error; +} + +/** + * add_trans_to_ail - Add a ondisk commited transaction to the AIL + * @sdp: the filesystem + * @tr: the transaction + * + */ + +static void +add_trans_to_ail(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_element *le; + + while (!list_empty(&tr->tr_elements)) { + le = list_entry(tr->tr_elements.next, + struct gfs_log_element, le_list); + LO_ADD_TO_AIL(sdp, le); + } + + list_add(&tr->tr_list, &sdp->sd_log_ail); +} + +/** + * log_refund - Refund log segments to the free pool + * @sdp: The GFS superblock + * @tr: The transaction to examine + * + * Look at the number of segments reserved for this transaction and the + * number of segments actually needed for it. If they aren't the + * same, refund the difference to the free segment pool. + * + * De-alloc any unneeded log buffers and log buffer descriptors. + * + * Called with the log lock held. + */ + +static void +log_refund(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + unsigned int num_bufs = 0, num_bmem = 0; + unsigned int segments; + + LO_TRANS_SIZE(sdp, tr, NULL, NULL, &num_bufs, &num_bmem); + + segments = gfs_blk2seg(sdp, num_bufs + 1); + num_bufs += segments + 1; + num_bmem += segments + 1; + + /* Unreserve unneeded log segments */ + if (tr->tr_seg_reserved > segments) { + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += tr->tr_seg_reserved - segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); + + tr->tr_seg_reserved = segments; + } else + gfs_assert(sdp, tr->tr_seg_reserved == segments,); + + /* De-alloc unneeded log buffer descriptors */ + gfs_assert(sdp, tr->tr_num_free_bufs >= num_bufs,); + while (tr->tr_num_free_bufs > num_bufs) { + lb = list_entry(tr->tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + kfree(lb); + tr->tr_num_free_bufs--; + } + + /* De-alloc unneeded log buffers */ + gfs_assert(sdp, tr->tr_num_free_bmem >= num_bmem,); + while (tr->tr_num_free_bmem > num_bmem) { + bmem = tr->tr_free_bmem.next; + list_del(bmem); + kfree(bmem); + tr->tr_num_free_bmem--; + } +} + +/** + * trans_combine - combine two transactions + * @sdp: the filesystem + * @tr: the surviving transaction + * @new_tr: the transaction that gets freed + * + * Assumes that the two transactions are independent. + */ + +static void +trans_combine(struct gfs_sbd *sdp, struct gfs_trans *tr, + struct gfs_trans *new_tr) +{ + struct gfs_log_element *le; + struct gfs_log_buf *lb; + struct list_head *bmem; + + tr->tr_file = __FILE__; + tr->tr_line = __LINE__; + tr->tr_seg_reserved += new_tr->tr_seg_reserved; + tr->tr_flags |= new_tr->tr_flags; + tr->tr_num_free_bufs += new_tr->tr_num_free_bufs; + tr->tr_num_free_bmem += new_tr->tr_num_free_bmem; + + /* Combine the log elements of the two transactions */ + + while (!list_empty(&new_tr->tr_elements)) { + le = list_entry(new_tr->tr_elements.next, + struct gfs_log_element, le_list); + gfs_assert(sdp, le->le_trans == new_tr,); + le->le_trans = tr; + list_move(&le->le_list, &tr->tr_elements); + } + + LO_TRANS_COMBINE(sdp, tr, new_tr); + + /* Move free log buffer descriptors to surviving trans */ + while (!list_empty(&new_tr->tr_free_bufs)) { + lb = list_entry(new_tr->tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_move(&lb->lb_list, &tr->tr_free_bufs); + new_tr->tr_num_free_bufs--; + } + /* Move free log buffers to surviving trans */ + while (!list_empty(&new_tr->tr_free_bmem)) { + bmem = new_tr->tr_free_bmem.next; + list_move(bmem, &tr->tr_free_bmem); + new_tr->tr_num_free_bmem--; + } + + gfs_assert_warn(sdp, !new_tr->tr_num_free_bufs); + gfs_assert_warn(sdp, !new_tr->tr_num_free_bmem); + + kfree(new_tr); +} + +static void +make_dummy_transaction(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + + memset(tr, 0, sizeof(struct gfs_trans)); + INIT_LIST_HEAD(&tr->tr_list); + INIT_LIST_HEAD(&tr->tr_elements); + INIT_LIST_HEAD(&tr->tr_free_bufs); + INIT_LIST_HEAD(&tr->tr_free_bmem); + INIT_LIST_HEAD(&tr->tr_bufs); + INIT_LIST_HEAD(&tr->tr_ail_bufs); + tr->tr_flags = TRF_DUMMY; + tr->tr_file = __FILE__; + tr->tr_line = __LINE__; + tr->tr_seg_reserved = 1; + while (tr->tr_num_free_bufs < 2) { + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + list_add(&lb->lb_list, &tr->tr_free_bufs); + tr->tr_num_free_bufs++; + } + while (tr->tr_num_free_bmem < 2) { + bmem = gmalloc(sdp->sd_sb.sb_bsize); + list_add(bmem, &tr->tr_free_bmem); + tr->tr_num_free_bmem++; + } +} + + +/** + * log_flush_internal - flush incore transaction(s) + * @sdp: the filesystem + * @gl: The glock structure to flush. If NULL, flush the whole incore log + * + * If a glock is provided, we flush, to on-disk log, all of the metadata for + * the one incore-committed (complete, but not-yet-flushed-to-log) + * transaction that the glock protects. + * If NULL, we combine *all* of the filesystem's incore-committed + * transactions into one big transaction, and flush it to the log. + */ + +static void +log_flush_internal(struct gfs_sbd *sdp, struct gfs_glock *gl) +{ + + struct gfs_trans *trans = NULL, *tr; + int error; + + gfs_log_lock(sdp); + + if (!gl && list_empty(&sdp->sd_log_incore)) { + if (sdp->sd_log_seg_ail2) { + trans = gmalloc(sizeof(struct gfs_trans)); + make_dummy_transaction(sdp, trans); + } + else + goto out; + } + + if (gl) { + if (!gl->gl_incore_le.le_trans) + goto out; + + trans = gl->gl_incore_le.le_trans; + + list_del(&trans->tr_list); + } else { + /* combine *all* transactions in incore list */ + while (!list_empty(&sdp->sd_log_incore)) { + tr = list_entry(sdp->sd_log_incore.next, + struct gfs_trans, tr_list); + + list_del(&tr->tr_list); + + if (trans) + trans_combine(sdp, trans, tr); + else + trans = tr; + } + } + + log_refund(sdp, trans); + + /* Actually do the stuff to commit the transaction */ + + error = disk_commit(sdp, trans); + if (error) + gfs_io_error(sdp); + + add_trans_to_ail(sdp, trans); + + if (log_distance(sdp, sdp->sd_log_head, sdp->sd_log_dump_last) * GFS_DUMPS_PER_LOG >= + sdp->sd_jdesc.ji_nsegment * sdp->sd_sb.sb_seg_size) + set_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags); + + out: + if (list_empty(&sdp->sd_log_incore)) + sdp->sd_vfs->s_dirt = FALSE; + + gfs_log_unlock(sdp); + + /* Dump if we need to. */ + + if (test_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags)) + gfs_log_dump(sdp, FALSE); +} + +/** + * gfs_log_flush - flush the whole incore log + * @sdp: the filesystem + * + */ + +void +gfs_log_flush(struct gfs_sbd *sdp) +{ + log_flush_internal(sdp, NULL); +} + +/** + * gfs_log_flush_glock - flush the incore log for a glock + * @gl: the glock + * + */ + +void +gfs_log_flush_glock(struct gfs_glock *gl) +{ + log_flush_internal(gl->gl_sbd, gl); +} + +/** + * incore_commit - commit a transaction in-core + * @sdp: the filesystem + * @new_tr: the transaction to commit + * + * Add the transaction @new_tr to the end of the incore commit list. + * Pull up and merge any previously committed transactions that share + * locks. Also pull up any rename transactions that need it. + */ + +static void +incore_commit(struct gfs_sbd *sdp, struct gfs_trans *new_tr) +{ + struct gfs_log_element *le; + struct gfs_trans *trans = NULL, *exist_tr; + struct gfs_log_buf *lb; + struct list_head *bmem; + struct list_head *tmp, *head, *next; + + for (head = &new_tr->tr_elements, tmp = head->next; + tmp != head; + tmp = tmp->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + + /* Do overlap_trans log-op, if any, to find another + incore transaction with which we can combine new_tr */ + exist_tr = LO_OVERLAP_TRANS(sdp, le); + if (!exist_tr) + continue; + + if (exist_tr != trans) { + /* remove trans from superblock's sd_log_incore list */ + list_del(&exist_tr->tr_list); + + /* Maybe there's more than one that can be combined. + If so, combine them together before merging new_tr */ + if (trans) + trans_combine(sdp, trans, exist_tr); + else + trans = exist_tr; + } + } + + /* Yes, we can combine new_tr with pre-existing transaction(s) */ + if (trans) { + trans->tr_file = __FILE__; + trans->tr_line = __LINE__; + trans->tr_seg_reserved += new_tr->tr_seg_reserved; + trans->tr_flags |= new_tr->tr_flags; + trans->tr_num_free_bufs += new_tr->tr_num_free_bufs; + trans->tr_num_free_bmem += new_tr->tr_num_free_bmem; + + /* Move free log buffer descriptors to surviving trans */ + while (!list_empty(&new_tr->tr_free_bufs)) { + lb = list_entry(new_tr->tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_move(&lb->lb_list, &trans->tr_free_bufs); + new_tr->tr_num_free_bufs--; + } + + /* Move free log buffers to surviving trans */ + while (!list_empty(&new_tr->tr_free_bmem)) { + bmem = new_tr->tr_free_bmem.next; + list_move(bmem, &trans->tr_free_bmem); + new_tr->tr_num_free_bmem--; + } + } else + trans = new_tr; + + /* Do incore_commit log-op for each *new* log element (in new_tr). + Each commit log-op removes its log element from "new_tr" LE list, + and attaches an LE to "trans" LE list; if there was no trans + combining, "new_tr" is the same transaction as "trans". */ + for (head = &new_tr->tr_elements, tmp = head->next, next = tmp->next; + tmp != head; + tmp = next, next = next->next) { + le = list_entry(tmp, struct gfs_log_element, le_list); + LO_INCORE_COMMIT(sdp, trans, le); + } + + /* If we successfully combined transactions, new_tr should be empty */ + if (trans != new_tr) { + gfs_assert_warn(sdp, !new_tr->tr_num_free_bufs); + gfs_assert_warn(sdp, !new_tr->tr_num_free_bmem); + gfs_assert_warn(sdp, list_empty(&new_tr->tr_elements)); + kfree(new_tr); + } + + /* If we successfully combined transactions, we might have some log + segments that we reserved, and log buffers and buffer descriptors + that we allocated, but now don't need. */ + log_refund(sdp, trans); + + list_add(&trans->tr_list, &sdp->sd_log_incore); +} + +/** + * gfs_log_commit - Commit a transaction to the log + * @sdp: the filesystem + * @tr: the transaction + * + * Returns: errno + */ + +void +gfs_log_commit(struct gfs_sbd *sdp, struct gfs_trans *tr) +{ + struct gfs_log_buf *lb; + struct list_head *bmem; + unsigned int num_mblks = 0, num_eblks = 0, num_bufs = 0, num_bmem = 0; + unsigned int segments; + + /* Calculate actual log area needed for this trans */ + LO_TRANS_SIZE(sdp, tr, &num_mblks, &num_eblks, &num_bufs, &num_bmem); + + gfs_assert(sdp, num_mblks <= tr->tr_mblks_asked && + num_eblks <= tr->tr_eblks_asked, + printk("GFS: fsid=%s: type = (%s, %u)\n" + "GFS: fsid=%s: num_mblks = %u, tr->tr_mblks_asked = %u\n" + "GFS: fsid=%s: num_eblks = %u, tr->tr_eblks_asked = %u\n", + sdp->sd_fsname, tr->tr_file, tr->tr_line, + sdp->sd_fsname, num_mblks, tr->tr_mblks_asked, + sdp->sd_fsname, num_eblks, tr->tr_eblks_asked);); + + segments = gfs_blk2seg(sdp, num_bufs + 1); + num_bufs += segments + 1; + num_bmem += segments + 1; + + /* Alloc log buffer descriptors */ + while (num_bufs--) { + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + list_add(&lb->lb_list, &tr->tr_free_bufs); + tr->tr_num_free_bufs++; + } + /* Alloc log buffers */ + while (num_bmem--) { + bmem = gmalloc(sdp->sd_sb.sb_bsize); + list_add(bmem, &tr->tr_free_bmem); + tr->tr_num_free_bmem++; + } + + gfs_log_lock(sdp); + + incore_commit(sdp, tr); + + /* Flush log buffers to disk if we're over the threshold */ + if (sdp->sd_log_buffers > gfs_tune_get(sdp, gt_incore_log_blocks)) { + gfs_log_unlock(sdp); + gfs_log_flush(sdp); + } else { + sdp->sd_vfs->s_dirt = TRUE; + gfs_log_unlock(sdp); + } + +} + +/** + * gfs_log_dump - make a Log Dump entry in the log + * @sdp: the filesystem + * @force: if TRUE, always make the dump even if one has been made recently + * + */ + +void +gfs_log_dump(struct gfs_sbd *sdp, int force) +{ + struct gfs_log_element *le; + struct gfs_trans tr; + struct gfs_log_buf *lb; + struct list_head *bmem; + unsigned int num_bufs, num_bmem; + unsigned int segments; + int error; + + if (test_and_set_bit(SDF_IN_LOG_DUMP, &sdp->sd_flags)) { + gfs_assert(sdp, !force,); + return; + } + + memset(&tr, 0, sizeof(struct gfs_trans)); + INIT_LIST_HEAD(&tr.tr_elements); + INIT_LIST_HEAD(&tr.tr_free_bufs); + INIT_LIST_HEAD(&tr.tr_free_bmem); + INIT_LIST_HEAD(&tr.tr_bufs); + tr.tr_flags = TRF_LOG_DUMP; + tr.tr_file = __FILE__; + tr.tr_line = __LINE__; + + for (;;) { + gfs_log_lock(sdp); + + if (!force && !test_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags)) + goto out; + + num_bufs = num_bmem = 0; + LO_DUMP_SIZE(sdp, NULL, &num_bufs, &num_bmem); + gfs_assert(sdp, num_bufs,); + segments = gfs_blk2seg(sdp, num_bufs + 1); + num_bufs += segments + 1; + num_bmem += segments + 1; + + if (tr.tr_seg_reserved >= segments && + tr.tr_num_free_bufs >= num_bufs && + tr.tr_num_free_bmem >= num_bmem) + break; + + gfs_log_unlock(sdp); + + if (tr.tr_seg_reserved < segments) { + error = gfs_log_reserve(sdp, + segments - tr.tr_seg_reserved, + TRUE); + gfs_assert(sdp, !error,); + tr.tr_seg_reserved = segments; + } + while (tr.tr_num_free_bufs < num_bufs) { + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + list_add(&lb->lb_list, &tr.tr_free_bufs); + tr.tr_num_free_bufs++; + } + while (tr.tr_num_free_bmem < num_bmem) { + bmem = gmalloc(sdp->sd_sb.sb_bsize); + list_add(bmem, &tr.tr_free_bmem); + tr.tr_num_free_bmem++; + } + } + + if (tr.tr_seg_reserved > segments) { + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += tr.tr_seg_reserved - segments; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); + tr.tr_seg_reserved = segments; + } + while (tr.tr_num_free_bufs > num_bufs) { + lb = list_entry(tr.tr_free_bufs.next, + struct gfs_log_buf, lb_list); + list_del(&lb->lb_list); + kfree(lb); + tr.tr_num_free_bufs--; + } + while (tr.tr_num_free_bmem > num_bmem) { + bmem = tr.tr_free_bmem.next; + list_del(bmem); + kfree(bmem); + tr.tr_num_free_bmem--; + } + + LO_BUILD_DUMP(sdp, &tr); + + error = disk_commit(sdp, &tr); + if (error) + gfs_io_error(sdp); + + while (!list_empty(&tr.tr_elements)) { + le = list_entry(tr.tr_elements.next, + struct gfs_log_element, le_list); + LO_CLEAN_DUMP(sdp, le); + } + + /* If there isn't anything in the AIL, we won't get back the log + space we reserved unless we do it ourselves. */ + + if (list_empty(&sdp->sd_log_ail)) { + spin_lock(&sdp->sd_log_seg_lock); + sdp->sd_log_seg_free += tr.tr_seg_reserved; + gfs_assert(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 <= + sdp->sd_jdesc.ji_nsegment,); + spin_unlock(&sdp->sd_log_seg_lock); + } + + clear_bit(SDF_NEED_LOG_DUMP, &sdp->sd_flags); + + out: + gfs_log_unlock(sdp); + clear_bit(SDF_IN_LOG_DUMP, &sdp->sd_flags); +} + +/** + * gfs_log_shutdown - write a shutdown header into a journal + * @sdp: the filesystem + * + */ + +void +gfs_log_shutdown(struct gfs_sbd *sdp) +{ + struct gfs_log_buf *lb; + char *bmem; + struct gfs_log_header head; + struct gfs_log_descriptor desc; + unsigned int elements = 0; + int error; + + lb = gmalloc(sizeof(struct gfs_log_buf)); + memset(lb, 0, sizeof(struct gfs_log_buf)); + bmem = gmalloc(sdp->sd_sb.sb_bsize); + + gfs_log_lock(sdp); + + gfs_assert_withdraw(sdp, list_empty(&sdp->sd_log_ail)); + gfs_assert_withdraw(sdp, sdp->sd_log_seg_free + sdp->sd_log_seg_ail2 == + sdp->sd_jdesc.ji_nsegment); + gfs_assert_withdraw(sdp, !sdp->sd_log_buffers); + gfs_assert_withdraw(sdp, gfs_log_is_header(sdp, sdp->sd_log_head - 1)); + if (test_bit(SDF_SHUTDOWN, &sdp->sd_flags)) + goto out; + + /* Build a "last" log descriptor */ + + memset(&desc, 0, sizeof(struct gfs_log_descriptor)); + desc.ld_header.mh_magic = GFS_MAGIC; + desc.ld_header.mh_type = GFS_METATYPE_LD; + desc.ld_header.mh_format = GFS_FORMAT_LD; + desc.ld_type = GFS_LOG_DESC_LAST; + desc.ld_length = sdp->sd_sb.sb_seg_size - 1; + + /* Write the descriptor */ + + gfs_logbh_init(sdp, &lb->lb_bh, sdp->sd_log_head, bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + gfs_desc_out(&desc, lb->lb_bh.b_data); + gfs_logbh_start(sdp, &lb->lb_bh); + error = gfs_logbh_wait(sdp, &lb->lb_bh); + gfs_logbh_uninit(sdp, &lb->lb_bh); + + if (error) + goto out; + + /* Move to the next header */ + + while (!gfs_log_is_header(sdp, sdp->sd_log_head)) + log_incr_head(sdp, &sdp->sd_log_head); + + LO_DUMP_SIZE(sdp, &elements, NULL, NULL); + + /* Build the shutdown header */ + + memset(&head, 0, sizeof (struct gfs_log_header)); + head.lh_header.mh_magic = GFS_MAGIC; + head.lh_header.mh_type = GFS_METATYPE_LH; + head.lh_header.mh_format = GFS_FORMAT_LH; + head.lh_flags = GFS_LOG_HEAD_UNMOUNT; + head.lh_first = sdp->sd_log_head; + head.lh_sequence = sdp->sd_sequence + 1; + /* Don't care about tail */ + head.lh_last_dump = (elements) ? sdp->sd_log_dump_last : 0; + + /* Write out the shutdown header */ + + gfs_logbh_init(sdp, &lb->lb_bh, sdp->sd_log_head, bmem); + memset(bmem, 0, sdp->sd_sb.sb_bsize); + gfs_log_header_out(&head, lb->lb_bh.b_data); + gfs_log_header_out(&head, + lb->lb_bh.b_data + GFS_BASIC_BLOCK - + sizeof(struct gfs_log_header)); + gfs_logbh_start(sdp, &lb->lb_bh); + gfs_logbh_wait(sdp, &lb->lb_bh); + gfs_logbh_uninit(sdp, &lb->lb_bh); + + /* If a withdraw is called before we've a chance to relock the trans + * lock, the sd_log_head points to the wrong place, and a umount will + * fail on asserts because of this. + * Adding one puts sd_log_head at a value that passes the assert. The + * value may not be correct for on disk, but we've withdrawn so there is + * no more disk io. + * If we're not withdrawn, the next io will grab the trans lock, which + * will fill sd_log_head with the correct value. + */ + sdp->sd_log_head += 1; + + out: + gfs_log_unlock(sdp); + + kfree(lb); + kfree(bmem); +} --- linux-2.6.28.orig/ubuntu/gfs/ioctl.c +++ linux-2.6.28/ubuntu/gfs/ioctl.c @@ -0,0 +1,1605 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs_ioctl.h" +#include "gfs.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "eattr.h" +#include "file.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "ioctl.h" +#include "log.h" +#include "quota.h" +#include "rgrp.h" +#include "super.h" +#include "trans.h" + +typedef int (*gi_filler_t) (struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count); + +#define ARG_SIZE (32) + +/** + * gi_skeleton - Setup a buffer that functions can print into + * @ip: + * @gi: + * @filler: + * + * Returns: -errno or count of bytes copied to userspace + */ + +static int +gi_skeleton(struct gfs_inode *ip, struct gfs_ioctl *gi, + gi_filler_t filler) +{ + unsigned int size = gfs_tune_get(ip->i_sbd, gt_lockdump_size); + char *buf; + unsigned int count = 0; + int error; + + if (size > gi->gi_size) + size = gi->gi_size; + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + error = filler(ip, gi, buf, size, &count); + if (error) + goto out; + + if (copy_to_user(gi->gi_data, buf, count + 1)) + error = -EFAULT; + else + error = count + 1; + + out: + kfree(buf); + + return error; +} + +/** + * gi_get_cookie - Return the "cookie" (identifying string) for a + * filesystem mount + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_cookie(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("%lu", (unsigned long)ip->i_sbd); + + error = 0; + + out: + return error; +} + +/** + * gi_get_super - Return the "struct gfs_sb" for a filesystem + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_get_super(struct gfs_sbd *sdp, struct gfs_ioctl *gi) +{ + struct gfs_holder sb_gh; + struct buffer_head *bh; + struct gfs_sb *sb; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + if (gi->gi_size != sizeof(struct gfs_sb)) + return -EINVAL; + + sb = kmalloc(sizeof(struct gfs_sb), GFP_KERNEL); + if (!sb) + return -ENOMEM; + + error = gfs_glock_nq_num(sdp, + GFS_SB_LOCK, &gfs_meta_glops, + LM_ST_SHARED, 0, &sb_gh); + if (error) + goto out; + + error = gfs_dread(sb_gh.gh_gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_START | DIO_WAIT, &bh); + if (error) { + gfs_glock_dq_uninit(&sb_gh); + goto out; + } + gfs_sb_in(sb, bh->b_data); + brelse(bh); + + gfs_glock_dq_uninit(&sb_gh); + + if (copy_to_user(gi->gi_data, sb, + sizeof(struct gfs_sb))) + error = -EFAULT; + else + error = sizeof(struct gfs_sb); + + out: + kfree(sb); + + return error; +} + +/** + * gi_get_args - Return the mount arguments + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_args(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_args *args = &ip->i_sbd->sd_args; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("lockproto %s\n", args->ar_lockproto); + gfs_printf("locktable %s\n", args->ar_locktable); + gfs_printf("hostdata %s\n", args->ar_hostdata); + gfs_printf("ignore_local_fs %d\n", args->ar_ignore_local_fs); + gfs_printf("localcaching %d\n", args->ar_localcaching); + gfs_printf("localflocks %d\n", args->ar_localflocks); + gfs_printf("oopses_ok %d\n", args->ar_oopses_ok); + gfs_printf("upgrade %d\n", args->ar_upgrade); + gfs_printf("num_glockd %u\n", args->ar_num_glockd); + gfs_printf("posix_acls %d\n", args->ar_posix_acls); + gfs_printf("suiddir %d\n", args->ar_suiddir); + + error = 0; + + out: + return error; +} + +/** + * gi_get_lockstruct - Return the information in the FS' lockstruct + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_lockstruct(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct lm_lockstruct *ls = &ip->i_sbd->sd_lockstruct; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("jid %u\n", ls->ls_jid); + gfs_printf("first %u\n", ls->ls_first); + gfs_printf("lvb_size %u\n", ls->ls_lvb_size); + gfs_printf("flags %d\n", ls->ls_flags); + + error = 0; + + out: + return error; +} + +/** + * gi_get_stat_gfs - Return a filesystem's space usage information + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_stat_gfs(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_stat_gfs sg; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + + error = gfs_stat_gfs(ip->i_sbd, &sg, TRUE); + if (error) + return error; + + error = -ENOBUFS; + + gfs_printf("version 0\n"); + gfs_printf("bsize %u\n", ip->i_sbd->sd_sb.sb_bsize); + gfs_printf("total_blocks %"PRIu64"\n", sg.sg_total_blocks); + gfs_printf("free %"PRIu64"\n", sg.sg_free); + gfs_printf("used_dinode %"PRIu64"\n", sg.sg_used_dinode); + gfs_printf("free_dinode %"PRIu64"\n", sg.sg_free_dinode); + gfs_printf("used_meta %"PRIu64"\n", sg.sg_used_meta); + gfs_printf("free_meta %"PRIu64"\n", sg.sg_free_meta); + + error = 0; + + out: + return error; +} + +/** + * handle_roll - Read a atomic_t as an unsigned int + * @a: a counter + * + * if @a is negative, reset it to zero + * + * Returns: the value of the counter + */ + +static unsigned int +handle_roll(atomic_t *a) +{ + int x = atomic_read(a); + if (x < 0) { + atomic_set(a, 0); + return 0; + } + return (unsigned int)x; +} + +/** + * gi_get_counters - Return usage counters + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_counters(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_sbd *sdp = ip->i_sbd; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + gfs_printf("version 0\n"); + gfs_printf("sd_glock_count:locks::%d\n", + atomic_read(&sdp->sd_glock_count)); + gfs_printf("sd_glock_held_count:locks held::%d\n", + atomic_read(&sdp->sd_glock_held_count)); + gfs_printf("sd_freeze_count:freeze count::%d\n", + sdp->sd_freeze_count); + gfs_printf("sd_inode_count:incore inodes::%d\n", + atomic_read(&sdp->sd_inode_count)); + gfs_printf("sd_bufdata_count:metadata buffers::%d\n", + atomic_read(&sdp->sd_bufdata_count)); + gfs_printf("sd_unlinked_ic_count:unlinked inodes::%d\n", + atomic_read(&sdp->sd_unlinked_ic_count)); + gfs_printf("sd_quota_count:quota IDs::%d\n", + atomic_read(&sdp->sd_quota_count)); + gfs_printf("sd_log_buffers:incore log buffers::%u\n", + sdp->sd_log_buffers); + gfs_printf("sd_log_seg_free:log segments free::%u\n", + sdp->sd_log_seg_free); + gfs_printf("ji_nsegment:log segments total::%u\n", + sdp->sd_jdesc.ji_nsegment); + gfs_printf("sd_mhc_count:meta header cache entries::%d\n", + atomic_read(&sdp->sd_mhc_count)); + gfs_printf("sd_depend_count:glock dependencies::%d\n", + atomic_read(&sdp->sd_depend_count)); + gfs_printf("sd_reclaim_count:glocks on reclaim list::%d\n", + atomic_read(&sdp->sd_reclaim_count)); + gfs_printf("sd_log_wrap:log wraps::%"PRIu64"\n", + sdp->sd_log_wrap); + gfs_printf("sd_lm_outstanding:outstanding LM calls::%d\n", + atomic_read(&sdp->sd_lm_outstanding)); + gfs_printf("sd_bio_outstanding:outstanding BIO calls::%u\n", + atomic_read(&sdp->sd_bio_outstanding)); + gfs_printf("sd_fh2dentry_misses:fh2dentry misses:diff:%u\n", + handle_roll(&sdp->sd_fh2dentry_misses)); + gfs_printf("sd_reclaimed:glocks reclaimed:diff:%u\n", + handle_roll(&sdp->sd_reclaimed)); + gfs_printf("sd_glock_nq_calls:glock nq calls:diff:%u\n", + handle_roll(&sdp->sd_glock_nq_calls)); + gfs_printf("sd_glock_dq_calls:glock dq calls:diff:%u\n", + handle_roll(&sdp->sd_glock_dq_calls)); + gfs_printf("sd_glock_prefetch_calls:glock prefetch calls:diff:%u\n", + handle_roll(&sdp->sd_glock_prefetch_calls)); + gfs_printf("sd_lm_lock_calls:lm_lock calls:diff:%u\n", + handle_roll(&sdp->sd_lm_lock_calls)); + gfs_printf("sd_lm_unlock_calls:lm_unlock calls:diff:%u\n", + handle_roll(&sdp->sd_lm_unlock_calls)); + gfs_printf("sd_lm_callbacks:lm callbacks:diff:%u\n", + handle_roll(&sdp->sd_lm_callbacks)); + gfs_printf("sd_ops_address:address operations:diff:%u\n", + handle_roll(&sdp->sd_ops_address)); + gfs_printf("sd_ops_dentry:dentry operations:diff:%u\n", + handle_roll(&sdp->sd_ops_dentry)); + gfs_printf("sd_ops_export:export operations:diff:%u\n", + handle_roll(&sdp->sd_ops_export)); + gfs_printf("sd_ops_file:file operations:diff:%u\n", + handle_roll(&sdp->sd_ops_file)); + gfs_printf("sd_ops_inode:inode operations:diff:%u\n", + handle_roll(&sdp->sd_ops_inode)); + gfs_printf("sd_ops_super:super operations:diff:%u\n", + handle_roll(&sdp->sd_ops_super)); + gfs_printf("sd_ops_vm:vm operations:diff:%u\n", + handle_roll(&sdp->sd_ops_vm)); + gfs_printf("sd_bio_reads:block I/O reads:diff:%u\n", + handle_roll(&sdp->sd_bio_reads) >> + (sdp->sd_sb.sb_bsize_shift - 9)); + gfs_printf("sd_bio_writes:block I/O writes:diff:%u\n", + handle_roll(&sdp->sd_bio_writes) >> + (sdp->sd_sb.sb_bsize_shift - 9)); + + error = 0; + + out: + return error; +} + +/** + * gi_get_tune - Return current values of the tuneable parameters + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_get_tune(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + struct gfs_tune *gt = &ip->i_sbd->sd_tune; + int error = -ENOBUFS; + + if (gi->gi_argc != 1) + return -EINVAL; + + spin_lock(>->gt_spin); + + gfs_printf("version 0\n"); + gfs_printf("ilimit1 %u\n", gt->gt_ilimit1); + gfs_printf("ilimit1_tries %u\n", gt->gt_ilimit1_tries); + gfs_printf("ilimit1_min %u\n", gt->gt_ilimit1_min); + gfs_printf("ilimit2 %u\n", gt->gt_ilimit2); + gfs_printf("ilimit2_tries %u\n", gt->gt_ilimit2_tries); + gfs_printf("ilimit2_min %u\n", gt->gt_ilimit2_min); + gfs_printf("demote_secs %u\n", gt->gt_demote_secs); + gfs_printf("incore_log_blocks %u\n", gt->gt_incore_log_blocks); + gfs_printf("jindex_refresh_secs %u\n", gt->gt_jindex_refresh_secs); + gfs_printf("depend_secs %u\n", gt->gt_depend_secs); + gfs_printf("scand_secs %u\n", gt->gt_scand_secs); + gfs_printf("recoverd_secs %u\n", gt->gt_recoverd_secs); + gfs_printf("logd_secs %u\n", gt->gt_logd_secs); + gfs_printf("quotad_secs %u\n", gt->gt_quotad_secs); + gfs_printf("inoded_secs %u\n", gt->gt_inoded_secs); + gfs_printf("glock_purge %u\n", gt->gt_glock_purge); + gfs_printf("quota_simul_sync %u\n", gt->gt_quota_simul_sync); + gfs_printf("quota_warn_period %u\n", gt->gt_quota_warn_period); + gfs_printf("atime_quantum %u\n", gt->gt_atime_quantum); + gfs_printf("quota_quantum %u\n", gt->gt_quota_quantum); + gfs_printf("quota_scale_num %u\n", gt->gt_quota_scale_num); + gfs_printf("quota_scale_den %u\n", gt->gt_quota_scale_den); + gfs_printf("quota_enforce %u\n", gt->gt_quota_enforce); + gfs_printf("quota_account %u\n", gt->gt_quota_account); + gfs_printf("new_files_jdata %u\n", gt->gt_new_files_jdata); + gfs_printf("new_files_directio %u\n", gt->gt_new_files_directio); + gfs_printf("max_atomic_write %u\n", gt->gt_max_atomic_write); + gfs_printf("max_readahead %u\n", gt->gt_max_readahead); + gfs_printf("lockdump_size %u\n", gt->gt_lockdump_size); + gfs_printf("stall_secs %u\n", gt->gt_stall_secs); + gfs_printf("complain_secs %u\n", gt->gt_complain_secs); + gfs_printf("reclaim_limit %u\n", gt->gt_reclaim_limit); + gfs_printf("entries_per_readdir %u\n", gt->gt_entries_per_readdir); + gfs_printf("prefetch_secs %u\n", gt->gt_prefetch_secs); + gfs_printf("statfs_slots %u\n", gt->gt_statfs_slots); + gfs_printf("max_mhc %u\n", gt->gt_max_mhc); + gfs_printf("greedy_default %u\n", gt->gt_greedy_default); + gfs_printf("greedy_quantum %u\n", gt->gt_greedy_quantum); + gfs_printf("greedy_max %u\n", gt->gt_greedy_max); + gfs_printf("rgrp_try_threshold %u\n", gt->gt_rgrp_try_threshold); + gfs_printf("statfs_fast %u\n", gt->gt_statfs_fast); + + error = 0; + + out: + spin_unlock(>->gt_spin); + + return error; +} + +#define tune_set(f, v) \ +do { \ + spin_lock(>->gt_spin); \ + gt->f = (v); \ + spin_unlock(>->gt_spin); \ +} while (0) + +/** + * gi_set_tune - Set a tuneable parameter + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_set_tune(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_tune *gt = &sdp->sd_tune; + char param[ARG_SIZE], value[ARG_SIZE]; + unsigned int x; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 3) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(param, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(param, gi->gi_argv[1], ARG_SIZE); + } + param[ARG_SIZE - 1] = 0; + + if (from_user) { + if (strncpy_from_user(value, gi->gi_argv[2], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(value, gi->gi_argv[2], ARG_SIZE); + } + + value[ARG_SIZE - 1] = 0; + + if (strcmp(param, "ilimit1") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit1, x); + + } else if (strcmp(param, "ilimit1_tries") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit1_tries, x); + + } else if (strcmp(param, "ilimit1_min") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit1_min, x); + + } else if (strcmp(param, "ilimit2") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit2, x); + + } else if (strcmp(param, "ilimit2_tries") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit2_tries, x); + + } else if (strcmp(param, "ilimit2_min") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_ilimit2_min, x); + + } else if (strcmp(param, "demote_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_demote_secs, x); + + } else if (strcmp(param, "incore_log_blocks") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_incore_log_blocks, x); + + } else if (strcmp(param, "jindex_refresh_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_jindex_refresh_secs, x); + + } else if (strcmp(param, "depend_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_depend_secs, x); + + } else if (strcmp(param, "scand_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_scand_secs, x); + wake_up_process(sdp->sd_scand_process); + + } else if (strcmp(param, "recoverd_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_recoverd_secs, x); + wake_up_process(sdp->sd_recoverd_process); + + } else if (strcmp(param, "logd_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_logd_secs, x); + wake_up_process(sdp->sd_logd_process); + + } else if (strcmp(param, "quotad_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_quotad_secs, x); + wake_up_process(sdp->sd_quotad_process); + + } else if (strcmp(param, "inoded_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_inoded_secs, x); + wake_up_process(sdp->sd_inoded_process); + + } else if (strcmp(param, "glock_purge") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_glock_purge, x); + + } else if (strcmp(param, "quota_simul_sync") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_quota_simul_sync, x); + + } else if (strcmp(param, "quota_warn_period") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_quota_warn_period, x); + + } else if (strcmp(param, "atime_quantum") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_atime_quantum, x); + + } else if (strcmp(param, "quota_quantum") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_quota_quantum, x); + + } else if (strcmp(param, "quota_scale") == 0) { + unsigned int y; + if (sscanf(value, "%u %u", &x, &y) != 2 || !y) + return -EINVAL; + spin_lock(>->gt_spin); + gt->gt_quota_scale_num = x; + gt->gt_quota_scale_den = y; + spin_unlock(>->gt_spin); + + } else if (strcmp(param, "quota_enforce") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + spin_lock(>->gt_spin); + gt->gt_quota_enforce = x; + if (x) + gt->gt_quota_account = 1; + spin_unlock(>->gt_spin); + + } else if (strcmp(param, "quota_account") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + spin_lock(>->gt_spin); + gt->gt_quota_account = x; + if (x) + spin_unlock(>->gt_spin); + else { + unsigned int y; + gt->gt_quota_enforce = 0; + spin_unlock(>->gt_spin); + for (y = 0; y < 2; y++) { + gfs_log_flush(sdp); + gfs_sync_meta(sdp); + gfs_quota_sync(sdp); + } + } + + } else if (strcmp(param, "new_files_jdata") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + tune_set(gt_new_files_jdata, x); + + } else if (strcmp(param, "new_files_directio") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + x = !!x; + tune_set(gt_new_files_directio, x); + + } else if (strcmp(param, "max_atomic_write") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_max_atomic_write, x); + + } else if (strcmp(param, "max_readahead") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_max_readahead, x); + + } else if (strcmp(param, "lockdump_size") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_lockdump_size, x); + + } else if (strcmp(param, "stall_secs") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_stall_secs, x); + + } else if (strcmp(param, "complain_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_complain_secs, x); + + } else if (strcmp(param, "reclaim_limit") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_reclaim_limit, x); + + } else if (strcmp(param, "entries_per_readdir") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_entries_per_readdir, x); + + } else if (strcmp(param, "prefetch_secs") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_prefetch_secs, x); + + } else if (strcmp(param, "statfs_slots") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_statfs_slots, x); + + } else if (strcmp(param, "max_mhc") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_max_mhc, x); + + } else if (strcmp(param, "greedy_default") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_greedy_default, x); + + } else if (strcmp(param, "greedy_quantum") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_greedy_quantum, x); + + } else if (strcmp(param, "greedy_max") == 0) { + if (sscanf(value, "%u", &x) != 1 || !x) + return -EINVAL; + tune_set(gt_greedy_max, x); + + } else if (strcmp(param, "rgrp_try_threshold") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + tune_set(gt_rgrp_try_threshold, x); + + } else if (strcmp(param, "statfs_fast") == 0) { + if (sscanf(value, "%u", &x) != 1) + return -EINVAL; + error = gfs_statfs_init(sdp, x); + if (error) + return error; + else + tune_set(gt_statfs_fast, x); + + + } else + return -EINVAL; + + return 0; +} + +/** + * gi_do_reclaim - Reclaim unused metadata + * @ip: + * @gi: + * @buf: + * @size: + * @count: + * + * Returns: errno + */ + +static int +gi_do_reclaim(struct gfs_inode *ip, + struct gfs_ioctl *gi, + char *buf, + unsigned int size, + unsigned int *count) +{ + uint64_t inodes, metadata; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 1) + return -EINVAL; + + error = gfs_reclaim_metadata(ip->i_sbd, + &inodes, + &metadata); + if (error) + return error; + + error = -ENOBUFS; + + gfs_printf("version 0\n"); + gfs_printf("inodes %"PRIu64"\n", inodes); + gfs_printf("metadata %"PRIu64"\n", metadata); + + error = 0; + + out: + return error; +} + +/** + * gi_do_shrink - throw out unused glocks + * @sdp: + * @gi: + * + * Returns: 0 + */ + +static int +gi_do_shrink(struct gfs_sbd *sdp, struct gfs_ioctl *gi) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 1) + return -EINVAL; + gfs_gl_hash_clear(sdp, FALSE); + return 0; +} + +/** + * gi_get_file_stat - + * @ip: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_get_file_stat(struct gfs_inode *ip, struct gfs_ioctl *gi) +{ + struct gfs_holder i_gh; + struct gfs_dinode *di; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + if (gi->gi_size != sizeof(struct gfs_dinode)) + return -EINVAL; + + di = kmalloc(sizeof(struct gfs_dinode), GFP_KERNEL); + if (!di) + return -ENOMEM; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + goto out; + memcpy(di, &ip->i_di, sizeof(struct gfs_dinode)); + gfs_glock_dq_uninit(&i_gh); + + if (copy_to_user(gi->gi_data, di, + sizeof(struct gfs_dinode))) + error = -EFAULT; + else + error = sizeof(struct gfs_dinode); + + out: + kfree(di); + + return error; +} + +/** + * gi_set_file_flag - set or clear a flag on a file + * @ip: + * @gi: + * + * Returns: errno + */ + +static int +gi_set_file_flag(struct gfs_inode *ip, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + int set; + uint32_t flag; + struct gfs_holder i_gh; + struct buffer_head *dibh; + int error; + + if (gi->gi_argc != 3) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + if (strcmp(buf, "set") == 0) + set = TRUE; + else if (strcmp(buf, "clear") == 0) + set = FALSE; + else + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[2], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[2], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + error = -EACCES; + if (ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) + goto out; + + error = -EINVAL; + + if (strcmp(buf, "jdata") == 0) { + if (ip->i_di.di_type != GFS_FILE_REG || + ip->i_di.di_size) + goto out; + flag = GFS_DIF_JDATA; + } else if (strcmp(buf, "directio") == 0) { + if (ip->i_di.di_type != GFS_FILE_REG) + goto out; + flag = GFS_DIF_DIRECTIO; + } else if (strcmp(buf, "immutable") == 0) { + /* The IMMUTABLE flag can only be changed by + the relevant capability. */ + error = -EPERM; + if (!capable(CAP_LINUX_IMMUTABLE)) + goto out; + flag = GFS_DIF_IMMUTABLE; + } else if (strcmp(buf, "appendonly") == 0) { + /* The APPENDONLY flag can only be changed by + the relevant capability. */ + error = -EPERM; + if (!capable(CAP_LINUX_IMMUTABLE)) + goto out; + flag = GFS_DIF_APPENDONLY; + } else if (strcmp(buf, "inherit_jdata") == 0) { + if (ip->i_di.di_type != GFS_FILE_DIR) + goto out; + flag = GFS_DIF_INHERIT_JDATA; + } else if (strcmp(buf, "inherit_directio") == 0) { + if (ip->i_di.di_type != GFS_FILE_DIR) + goto out; + flag = GFS_DIF_INHERIT_DIRECTIO; + } else + goto out; + + error = gfs_trans_begin(ip->i_sbd, 1, 0); + if (error) + goto out; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out_trans_end; + + if (set) + ip->i_di.di_flags |= flag; + else + ip->i_di.di_flags &= ~flag; + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + + brelse(dibh); + + out_trans_end: + gfs_trans_end(ip->i_sbd); + + out: + gfs_glock_dq_uninit(&i_gh); + + return error; + +} + +/** + * gi_get_file_meta - Return all the metadata for a file + * @ip: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_get_file_meta(struct gfs_inode *ip, struct gfs_ioctl *gi) +{ + struct gfs_holder i_gh; + struct gfs_user_buffer ub; + int error; + + if (gi->gi_argc != 1) + return -EINVAL; + + ub.ub_data = gi->gi_data; + ub.ub_size = gi->gi_size; + ub.ub_count = 0; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + return error; + + error = -EACCES; + if (ip->i_di.di_uid != current->fsuid && !capable(CAP_FOWNER)) + goto out; + + error = gfs_get_file_meta(ip, &ub); + if (error) + goto out; + + if (ip->i_di.di_type == GFS_FILE_DIR && + (ip->i_di.di_flags & GFS_DIF_EXHASH)) { + error = gfs_get_dir_meta(ip, &ub); + if (error) + goto out; + } + + if (ip->i_di.di_eattr) { + error = gfs_get_eattr_meta(ip, &ub); + if (error) + goto out; + } + + error = ub.ub_count; + + out: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_file_flush - sync out all dirty data and + * drop the cache (and lock) for a file. + * @ip: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_file_flush(struct gfs_inode *ip, struct gfs_ioctl *gi) +{ + if (gi->gi_argc != 1) + return -EINVAL; + gfs_glock_force_drop(ip->i_gl); + return 0; +} + +/** + * gi2hip - return the "struct gfs_inode" for a hidden file + * @sdp: + * @gi: + * + * Returns: the "struct gfs_inode" + */ + +static struct gfs_inode * +gi2hip(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + + if (gi->gi_argc != 2) + return ERR_PTR(-EINVAL); + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return ERR_PTR(-EFAULT); + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + if (strcmp(buf, "jindex") == 0) + return sdp->sd_jiinode; + else if (strcmp(buf, "rindex") == 0) + return sdp->sd_riinode; + else if (strcmp(buf, "quota") == 0) + return sdp->sd_qinode; + else if (strcmp(buf, "license") == 0) + return sdp->sd_linode; + else + return ERR_PTR(-EINVAL); +} + +/** + * gi_get_hfile_stat - get stat info on a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_get_hfile_stat(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_dinode *di; + struct gfs_holder i_gh; + int error; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + if (gi->gi_size != sizeof(struct gfs_dinode)) + return -EINVAL; + + di = kmalloc(sizeof(struct gfs_dinode), GFP_KERNEL); + if (!di) + return -ENOMEM; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh); + if (error) + goto out; + memcpy(di, &ip->i_di, sizeof(struct gfs_dinode)); + gfs_glock_dq_uninit(&i_gh); + + if (copy_to_user(gi->gi_data, di, + sizeof(struct gfs_dinode))) + error = -EFAULT; + else + error = sizeof(struct gfs_dinode); + + out: + kfree(di); + + return error; +} + +/** + * gi_do_hfile_read - Read data from a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes read, or -errno + */ + +static int +gi_do_hfile_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_holder i_gh; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + if (!access_ok(VERIFY_WRITE, gi->gi_data, gi->gi_size)) + return -EFAULT; + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &i_gh); + if (error) + return error; + + error = gfs_readi(ip, gi->gi_data, gi->gi_offset, gi->gi_size, + gfs_copy2user); + + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_hfile_write - Write data to a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes written, or -errno + */ + +static int +gi_do_hfile_write(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_alloc *al = NULL; + struct gfs_holder i_gh; + unsigned int data_blocks, ind_blocks; + int alloc_required; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + if (!access_ok(VERIFY_READ, gi->gi_data, gi->gi_size)) + return -EFAULT; + + gfs_write_calc_reserv(ip, gi->gi_size, &data_blocks, &ind_blocks); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, + LM_FLAG_PRIORITY | GL_SYNC | GL_NOCANCEL_OTHER, + &i_gh); + if (error) + return error; + + if (!gfs_is_jdata(ip)) { + gfs_consist_inode(ip); + error = -EIO; + goto out; + } + + error = gfs_write_alloc_required(ip, gi->gi_offset, gi->gi_size, + &alloc_required); + if (error) + goto out; + + if (alloc_required) { + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, + NO_QUOTA_CHANGE); + if (error) + goto out_alloc; + + al->al_requested_meta = ind_blocks + data_blocks; + + error = gfs_inplace_reserve(ip); + if (error) + goto out_qs; + + /* Trans may require: + All blocks for a RG bitmap, all the "data" blocks, whatever + indirect blocks we need, a modified dinode, and a quota change */ + + error = gfs_trans_begin(sdp, + 1 + al->al_rgd->rd_ri.ri_length + + ind_blocks + data_blocks, 1); + if (error) + goto out_relse; + } else { + /* Trans may require: + All the "data" blocks and a modified dinode. */ + + error = gfs_trans_begin(sdp, 1 + data_blocks, 0); + if (error) + goto out_relse; + } + + if (from_user) + error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size, + gfs_copy_from_user, NULL); + else + error = gfs_writei(ip, gi->gi_data, gi->gi_offset, gi->gi_size, + gfs_copy_from_mem, NULL); + + gfs_trans_end(sdp); + + out_relse: + if (alloc_required) { + gfs_assert_warn(sdp, error || al->al_alloced_meta); + gfs_inplace_release(ip); + } + + out_qs: + if (alloc_required) + gfs_quota_unhold_m(ip); + + out_alloc: + if (alloc_required) + gfs_alloc_put(ip); + + out: + ip->i_gl->gl_vn++; + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_hfile_trunc - truncate a hidden file + * @sdp: + * @gi: + * + * Returns: the number of bytes copied, or -errno + */ + +static int +gi_do_hfile_trunc(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + struct gfs_inode *ip; + struct gfs_holder i_gh; + int error; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + ip = gi2hip(sdp, gi, from_user); + if (IS_ERR(ip)) + return PTR_ERR(ip); + + error = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SYNC, &i_gh); + if (error) + return error; + + error = gfs_truncatei(ip, gi->gi_offset, NULL); + + ip->i_gl->gl_vn++; + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gi_do_quota_sync - sync the outstanding quota changes for a FS + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_quota_sync(struct gfs_sbd *sdp, struct gfs_ioctl *gi) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 1) + return -EINVAL; + return gfs_quota_sync(sdp); +} + +/** + * gi_do_quota_refresh - Refresh the a quota LVB from the quota file + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_quota_refresh(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + int user; + uint32_t id; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (gi->gi_argc != 2) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + switch (buf[0]) { + case 'u': + user = TRUE; + break; + case 'g': + user = FALSE; + break; + default: + return -EINVAL; + } + + if (buf[1] != ':') + return -EINVAL; + + if (sscanf(buf + 2, "%u", &id) != 1) + return -EINVAL; + + return gfs_quota_refresh(sdp, user, id); +} + +/** + * gi_do_quota_read - read quota values from the quota file + * @sdp: + * @gi: + * + * Returns: errno + */ + +static int +gi_do_quota_read(struct gfs_sbd *sdp, struct gfs_ioctl *gi, int from_user) +{ + char buf[ARG_SIZE]; + int user; + uint32_t id; + struct gfs_quota q; + int error; + + if (gi->gi_argc != 2) + return -EINVAL; + if (gi->gi_size != sizeof(struct gfs_quota)) + return -EINVAL; + + if (from_user) { + if (strncpy_from_user(buf, gi->gi_argv[1], ARG_SIZE) < 0) + return -EFAULT; + } else { + strncpy(buf, gi->gi_argv[1], ARG_SIZE); + } + buf[ARG_SIZE - 1] = 0; + + switch (buf[0]) { + case 'u': + user = TRUE; + break; + case 'g': + user = FALSE; + break; + default: + return -EINVAL; + } + + if (buf[1] != ':') + return -EINVAL; + + if (sscanf(buf + 2, "%u", &id) != 1) + return -EINVAL; + + error = gfs_quota_read(sdp, user, id, &q); + if (error) + return error; + + if (copy_to_user(gi->gi_data, &q, sizeof(struct gfs_quota))) + return -EFAULT; + + return 0; +} + +int +gfs_ioctl_i_local(struct gfs_inode *ip, struct gfs_ioctl *gi, const char *arg0, + int from_user) +{ + int error = -EFAULT; + + if (strcmp(arg0, "get_cookie") == 0) + error = gi_skeleton(ip, gi, gi_get_cookie); + else if (strcmp(arg0, "get_super") == 0) + error = gi_get_super(ip->i_sbd, gi); + else if (strcmp(arg0, "get_args") == 0) + error = gi_skeleton(ip, gi, gi_get_args); + else if (strcmp(arg0, "get_lockstruct") == 0) + error = gi_skeleton(ip, gi, gi_get_lockstruct); + else if (strcmp(arg0, "get_stat_gfs") == 0) + error = gi_skeleton(ip, gi, gi_get_stat_gfs); + else if (strcmp(arg0, "get_counters") == 0) + error = gi_skeleton(ip, gi, gi_get_counters); + else if (strcmp(arg0, "get_tune") == 0) + error = gi_skeleton(ip, gi, gi_get_tune); + else if (strcmp(arg0, "set_tune") == 0) + error = gi_set_tune(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_reclaim") == 0) + error = gi_skeleton(ip, gi, gi_do_reclaim); + else if (strcmp(arg0, "do_shrink") == 0) + error = gi_do_shrink(ip->i_sbd, gi); + else if (strcmp(arg0, "get_file_stat") == 0) + error = gi_get_file_stat(ip, gi); + else if (strcmp(arg0, "set_file_flag") == 0) + error = gi_set_file_flag(ip, gi, from_user); + else if (strcmp(arg0, "get_file_meta") == 0) + error = gi_get_file_meta(ip, gi); + else if (strcmp(arg0, "get_file_meta_quota") == 0) + error = gi_get_file_meta(ip->i_sbd->sd_qinode, gi); + else if (strcmp(arg0, "do_file_flush") == 0) + error = gi_do_file_flush(ip, gi); + else if (strcmp(arg0, "get_hfile_stat") == 0) + error = gi_get_hfile_stat(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_hfile_read") == 0) + error = gi_do_hfile_read(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_hfile_write") == 0) + error = gi_do_hfile_write(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_hfile_trunc") == 0) + error = gi_do_hfile_trunc(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_quota_sync") == 0) + error = gi_do_quota_sync(ip->i_sbd, gi); + else if (strcmp(arg0, "do_quota_refresh") == 0) + error = gi_do_quota_refresh(ip->i_sbd, gi, from_user); + else if (strcmp(arg0, "do_quota_read") == 0) + error = gi_do_quota_read(ip->i_sbd, gi, from_user); + else + error = -ENOTTY; + + return error; +} + +/** + * gfs_ioctl_i - Normal ioctls + * @ip: + * @arg: + * + * Returns: -errno or positive byte count + */ + +int +gfs_ioctl_i(struct gfs_inode *ip, void *arg) +{ + struct gfs_ioctl *gi_user = (struct gfs_ioctl *)arg; + struct gfs_ioctl gi; + char **argv; + char arg0[ARG_SIZE]; + int error = -EFAULT; + + if (copy_from_user(&gi, gi_user, sizeof(struct gfs_ioctl))) + return -EFAULT; + if (!gi.gi_argc) + return -EINVAL; + argv = kmalloc(gi.gi_argc * sizeof(char *), GFP_KERNEL); + if (!argv) + return -ENOMEM; + if (copy_from_user(argv, gi.gi_argv, + gi.gi_argc * sizeof(char *))) + goto out; + gi.gi_argv = argv; + + if (strncpy_from_user(arg0, argv[0], ARG_SIZE) < 0) + goto out; + arg0[ARG_SIZE - 1] = 0; + error = gfs_ioctl_i_local(ip, &gi, arg0, 1); + out: + kfree(argv); + + return error; +} + +#ifdef CONFIG_COMPAT +/** + * gfs_ioctl_i_compat - compatibility ioctls + * These ioctls are used to provide ioctls for situations + * where userland and kernel arch is different. + * For example, userland may be 32-bit ppc whereas the + * kernel may be ppc64. In this case, we need to do + * extra translation between the addresses. + * @ip: + * @arg: + * + * Returns: -errno or positive byte count + */ + +int +gfs_ioctl_i_compat(struct gfs_inode *ip, unsigned long arg) +{ + struct gfs_ioctl_compat *src; + struct gfs_ioctl dst; + char **argv, *argptr; + uint32_t *ptr; + char arg0[ARG_SIZE]; + char *tmparg; + int i; + int error = -EFAULT; + + src = (struct gfs_ioctl_compat *)compat_ptr(arg); + + memset(&dst, 0, sizeof(dst)); + dst.gi_argc = src->gi_argc; + dst.gi_size = src->gi_size; + dst.gi_offset = src->gi_offset; + + argv = kmalloc(dst.gi_argc * sizeof(char *), GFP_KERNEL); + if (!argv) + return -ENOMEM; + + memset(argv, 0, dst.gi_argc * sizeof(char *)); + ptr = (uint32_t *)compat_ptr(src->gi_argv); + + for (i = 0; i < dst.gi_argc; i++) { /* for each parm */ + tmparg = kmalloc(ARG_SIZE * sizeof(char *), GFP_KERNEL); + if (!tmparg) + goto out; + argptr = (char *)compat_ptr(*ptr); + if (strncpy_from_user(tmparg, argptr, ARG_SIZE) < 0) + goto out; + argv[i] = tmparg; + ptr++; + } + + strncpy(arg0, argv[0], ARG_SIZE); + arg0[ARG_SIZE - 1] = 0; + dst.gi_argv = argv; + dst.gi_data = compat_ptr(src->gi_data); + error = gfs_ioctl_i_local(ip, &dst, arg0, 0); + out: + for (i = 0; i < dst.gi_argc; i++) + kfree(argv[i]); + kfree(argv); + return error; +} +#endif --- linux-2.6.28.orig/ubuntu/gfs/sys.c +++ linux-2.6.28/ubuntu/gfs/sys.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "glock.h" +#include "lm.h" +#include "sys.h" +#include "super.h" + +char *gfs_sys_margs; +spinlock_t gfs_sys_margs_lock; + +static ssize_t id_show(struct gfs_sbd *sdp, char *buf) +{ + return sprintf(buf, "%s\n", sdp->sd_vfs->s_id); +} + +static ssize_t fsname_show(struct gfs_sbd *sdp, char *buf) +{ + return sprintf(buf, "%s\n", sdp->sd_fsname); +} + +struct gfs_attr { + struct attribute attr; + ssize_t (*show)(struct gfs_sbd *, char *); + ssize_t (*store)(struct gfs_sbd *, const char *, size_t); +}; + +#define GFS_ATTR(name, mode, show, store) \ +static struct gfs_attr gfs_attr_##name = __ATTR(name, mode, show, store) + +GFS_ATTR(id, 0444, id_show, NULL); +GFS_ATTR(fsname, 0444, fsname_show, NULL); + +static struct attribute *gfs_attrs[] = { + &gfs_attr_id.attr, + &gfs_attr_fsname.attr, + NULL, +}; + +static ssize_t gfs_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct gfs_sbd *sdp = container_of(kobj, struct gfs_sbd, sd_kobj); + struct gfs_attr *a = container_of(attr, struct gfs_attr, attr); + return a->show ? a->show(sdp, buf) : 0; +} + +static ssize_t gfs_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t len) +{ + struct gfs_sbd *sdp = container_of(kobj, struct gfs_sbd, sd_kobj); + struct gfs_attr *a = container_of(attr, struct gfs_attr, attr); + return a->store ? a->store(sdp, buf, len) : len; +} + +static struct sysfs_ops gfs_attr_ops = { + .show = gfs_attr_show, + .store = gfs_attr_store, +}; + +static struct kobj_type gfs_ktype = { + .default_attrs = gfs_attrs, + .sysfs_ops = &gfs_attr_ops, +}; + +static struct kset *gfs_kset; + +int gfs_sys_fs_add(struct gfs_sbd *sdp) +{ + int error; + + sdp->sd_kobj.kset = gfs_kset; + + error = kobject_init_and_add(&sdp->sd_kobj, &gfs_ktype, NULL, + "%s", sdp->sd_table_name); + if (error) + goto fail; + + kobject_uevent(&sdp->sd_kobj, KOBJ_ADD); + + return 0; + + fail: + return error; +} + +void gfs_sys_fs_del(struct gfs_sbd *sdp) +{ + kobject_put(&sdp->sd_kobj); +} + +int gfs_sys_init(void) +{ + gfs_sys_margs = NULL; + spin_lock_init(&gfs_sys_margs_lock); + gfs_kset = kset_create_and_add("gfs", NULL, fs_kobj); + if (!gfs_kset) + return -ENOMEM; + return 0; +} + +void gfs_sys_uninit(void) +{ + kfree(gfs_sys_margs); + kset_unregister(gfs_kset); +} --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm_main.c +++ linux-2.6.28/ubuntu/gfs/lock_dlm_main.c @@ -0,0 +1,40 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 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 version 2. + */ + +#include + +#include "lock_dlm.h" + +int init_lock_dlm() +{ + int error; + + error = gfs_register_lockproto(&gdlm_ops); + if (error) { + printk(KERN_WARNING "lock_dlm: can't register protocol: %d\n", + error); + return error; + } + + error = gdlm_sysfs_init(); + if (error) { + gfs_unregister_lockproto(&gdlm_ops); + return error; + } + + printk(KERN_INFO + "Lock_DLM (built %s %s) installed\n", __DATE__, __TIME__); + return 0; +} + +void exit_lock_dlm() +{ + gdlm_sysfs_exit(); + gfs_unregister_lockproto(&gdlm_ops); +} --- linux-2.6.28.orig/ubuntu/gfs/gfs.h +++ linux-2.6.28/ubuntu/gfs/gfs.h @@ -0,0 +1,89 @@ +#ifndef __GFS_DOT_H__ +#define __GFS_DOT_H__ + +#define RELEASE_VERSION "" + +#include "lm_interface.h" + +#include "gfs_ondisk.h" +#include "fixed_div64.h" +#include "lvb.h" +#include "incore.h" +#include "util.h" + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#define NO_CREATE (0) +#define CREATE (1) + +#if (BITS_PER_LONG == 64) +#define PRIu64 "lu" +#define PRId64 "ld" +#define PRIo64 "lo" +#define PRIx64 "lx" +#define PRIX64 "lX" +#define SCNu64 "lu" +#define SCNd64 "ld" +#define SCNo64 "lo" +#define SCNx64 "lx" +#define SCNX64 "lX" +#else +#define PRIu64 "Lu" +#define PRId64 "Ld" +#define PRIo64 "Lo" +#define PRIx64 "Lx" +#define PRIX64 "LX" +#define SCNu64 "Lu" +#define SCNd64 "Ld" +#define SCNo64 "Lo" +#define SCNx64 "Lx" +#define SCNX64 "LX" +#endif + +/* Divide num by den. Round up if there is a remainder. */ +#define DIV_RU(num, den) (((num) + (den) - 1) / (den)) +#define MAKE_MULT8(x) (((x) + 7) & ~7) + +#define GFS_FAST_NAME_SIZE (8) + +#define get_v2sdp(sb) ((struct gfs_sbd *)(sb)->s_fs_info) +#define set_v2sdp(sb, sdp) (sb)->s_fs_info = (sdp) +#define get_v2ip(inode) ((struct gfs_inode *)(inode)->i_private) +#define set_v2ip(inode, ip) (inode)->i_private = (ip) +#define get_v2fp(file) ((struct gfs_file *)(file)->private_data) +#define set_v2fp(file, fp) (file)->private_data = (fp) +#define get_v2bd(bh) ((struct gfs_bufdata *)(bh)->b_private) +#define set_v2bd(bh, bd) (bh)->b_private = (bd) + +#define get_transaction ((struct gfs_trans *)(current->journal_info)) +#define set_transaction(tr) (current->journal_info) = (tr) + +#define get_gl2ip(gl) ((struct gfs_inode *)(gl)->gl_object) +#define set_gl2ip(gl, ip) (gl)->gl_object = (ip) +#define get_gl2rgd(gl) ((struct gfs_rgrpd *)(gl)->gl_object) +#define set_gl2rgd(gl, rgd) (gl)->gl_object = (rgd) +#define get_gl2gl(gl) ((struct gfs_glock *)(gl)->gl_object) +#define set_gl2gl(gl, gl2) (gl)->gl_object = (gl2) + +#define gfs_printf(fmt, args...) \ +do { \ + if (buf) { \ + int gspf_left = size - *count, gspf_out; \ + if (gspf_left <= 0) \ + goto out; \ + gspf_out = snprintf(buf + *count, gspf_left, fmt, ##args); \ + if (gspf_out < gspf_left) \ + *count += gspf_out; \ + else \ + goto out; \ + } else \ + printk(fmt, ##args); \ +} while (0) + +#endif /* __GFS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/inode.c +++ linux-2.6.28/ubuntu/gfs/inode.c @@ -0,0 +1,2212 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "bmap.h" +#include "dio.h" +#include "dir.h" +#include "eattr.h" +#include "glock.h" +#include "glops.h" +#include "inode.h" +#include "log.h" +#include "ops_address.h" +#include "ops_file.h" +#include "ops_inode.h" +#include "quota.h" +#include "rgrp.h" +#include "trans.h" +#include "unlinked.h" + +/** + * inode_attr_in - Copy attributes from the dinode into the VFS inode + * @ip: The GFS inode (with embedded disk inode data) + * @inode: The Linux VFS inode + * + */ + +static void +inode_attr_in(struct gfs_inode *ip, struct inode *inode) +{ + unsigned int mode; + + inode->i_ino = ip->i_num.no_formal_ino; + + switch (ip->i_di.di_type) { + case GFS_FILE_REG: + mode = S_IFREG; + inode->i_rdev = 0; + break; + case GFS_FILE_DIR: + mode = S_IFDIR; + inode->i_rdev = 0; + break; + case GFS_FILE_LNK: + mode = S_IFLNK; + inode->i_rdev = 0; + break; + case GFS_FILE_BLK: + mode = S_IFBLK; + inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor); + break; + case GFS_FILE_CHR: + mode = S_IFCHR; + inode->i_rdev = MKDEV(ip->i_di.di_major, ip->i_di.di_minor); + break; + case GFS_FILE_FIFO: + mode = S_IFIFO; + inode->i_rdev = 0; + break; + case GFS_FILE_SOCK: + mode = S_IFSOCK; + inode->i_rdev = 0; + break; + default: + if (gfs_consist_inode(ip)) + printk("GFS: fsid=%s: type = %u\n", + ip->i_sbd->sd_fsname, ip->i_di.di_type); + return; + }; + + inode->i_mode = mode | (ip->i_di.di_mode & S_IALLUGO); + inode->i_nlink = ip->i_di.di_nlink; + inode->i_uid = ip->i_di.di_uid; + inode->i_gid = ip->i_di.di_gid; + i_size_write(inode, ip->i_di.di_size); + inode->i_atime.tv_sec = ip->i_di.di_atime; + inode->i_mtime.tv_sec = ip->i_di.di_mtime; + inode->i_ctime.tv_sec = ip->i_di.di_ctime; + inode->i_atime.tv_nsec = inode->i_mtime.tv_nsec = inode->i_ctime.tv_nsec = 0; + inode->i_blocks = ip->i_di.di_blocks << + (ip->i_sbd->sd_sb.sb_bsize_shift - GFS_BASIC_BLOCK_SHIFT); + inode->i_generation = ip->i_di.di_header.mh_incarn; + + if (ip->i_di.di_flags & GFS_DIF_IMMUTABLE) + inode->i_flags |= S_IMMUTABLE; + else + inode->i_flags &= ~S_IMMUTABLE; + + if (ip->i_di.di_flags & GFS_DIF_APPENDONLY) + inode->i_flags |= S_APPEND; + else + inode->i_flags &= ~S_APPEND; +} + +/** + * gfs_inode_attr_in - Copy attributes from the dinode into the VFS inode + * @ip: The GFS inode (with embedded disk inode data) + * + */ + +void +gfs_inode_attr_in(struct gfs_inode *ip) +{ + struct inode *inode; + + inode = gfs_iget(ip, NO_CREATE); + if (inode) { + inode_attr_in(ip, inode); + iput(inode); + } + +} + +/** + * gfs_inode_attr_out - Copy attributes from VFS inode into the dinode + * @ip: The GFS inode + * + * Only copy out the attributes that we want the VFS layer + * to be able to modify. + */ + +void +gfs_inode_attr_out(struct gfs_inode *ip) +{ + struct inode *inode = ip->i_vnode; + + ip->i_di.di_mode = inode->i_mode & S_IALLUGO; + ip->i_di.di_uid = inode->i_uid; + ip->i_di.di_gid = inode->i_gid; + ip->i_di.di_atime = inode->i_atime.tv_sec; + ip->i_di.di_mtime = inode->i_mtime.tv_sec; + ip->i_di.di_ctime = inode->i_ctime.tv_sec; +} + +/** + * gfs_iget - Get/Create a struct inode for a struct gfs_inode + * @ip: the struct gfs_inode to get the struct inode for + * @create: CREATE -- create a new struct inode if one does not already exist + * NO_CREATE -- return NULL if inode doesn't exist + * + * Returns: A VFS inode, or NULL if NO_CREATE and none in existance + * + * If this function creates a new inode, it: + * Copies fields from the GFS on-disk (d)inode to the VFS inode + * Attaches the appropriate ops vectors to the VFS inode and address_space + * Attaches the VFS inode to the gfs_inode + * Inserts the new inode in the VFS inode hash, while avoiding races + */ + +struct inode * +gfs_iget(struct gfs_inode *ip, int create) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct inode *inode = NULL, *tmp; + + spin_lock(&ip->i_spin); + if (ip->i_vnode) + inode = igrab(ip->i_vnode); + spin_unlock(&ip->i_spin); + + if (inode || !create) + return inode; + + tmp = new_inode(ip->i_sbd->sd_vfs); + if (!tmp) + return NULL; + + inode_attr_in(ip, tmp); + + /* Attach GFS-specific ops vectors */ + if (ip->i_di.di_type == GFS_FILE_REG) { + tmp->i_op = &gfs_file_iops; + memcpy(&ip->gfs_file_aops, &gfs_file_aops, + sizeof(struct address_space_operations)); + tmp->i_mapping->a_ops = &ip->gfs_file_aops; + if (sdp->sd_args.ar_localflocks) + tmp->i_fop = &gfs_file_fops_nolock; + else + tmp->i_fop = &gfs_file_fops; + } else if (ip->i_di.di_type == GFS_FILE_DIR) { + tmp->i_op = &gfs_dir_iops; + if (sdp->sd_args.ar_localflocks) + tmp->i_fop = &gfs_dir_fops_nolock; + else + tmp->i_fop = &gfs_dir_fops; + } else if (ip->i_di.di_type == GFS_FILE_LNK) { + tmp->i_op = &gfs_symlink_iops; + } else { + tmp->i_op = &gfs_dev_iops; + init_special_inode(tmp, tmp->i_mode, tmp->i_rdev); + } + + set_v2ip(tmp, NULL); + + /* Did another process successfully create an inode while we were + preparing this (tmp) one? If so, we can use that other one, and + trash the one we were preparing. + The other process might not be done inserting the inode in the + VFS hash table. If so, we need to wait until it is done, then + we can use it. */ + for (;;) { + spin_lock(&ip->i_spin); + if (!ip->i_vnode) + break; + inode = igrab(ip->i_vnode); + spin_unlock(&ip->i_spin); + + if (inode) { + iput(tmp); + return inode; + } + yield(); + } + + inode = tmp; + + gfs_inode_hold(ip); + ip->i_vnode = inode; + set_v2ip(inode, ip); + + spin_unlock(&ip->i_spin); + + insert_inode_hash(inode); + + return inode; +} + +/** + * gfs_copyin_dinode - Refresh the incore copy of the dinode + * @ip: The GFS inode + * + * Returns: errno + */ + +int +gfs_copyin_dinode(struct gfs_inode *ip) +{ + struct buffer_head *dibh; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + if (gfs_metatype_check(ip->i_sbd, dibh, GFS_METATYPE_DI)) { + brelse(dibh); + return -EIO; + } + + gfs_dinode_in(&ip->i_di, dibh->b_data); + brelse(dibh); + + if (ip->i_num.no_formal_ino != ip->i_di.di_num.no_formal_ino) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + /* Handle a moved inode (not implemented yet) */ + if (ip->i_num.no_addr != ip->i_di.di_num.no_addr) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + ip->i_vn = ip->i_gl->gl_vn; + + return 0; +} + +/** + * inode_create - create a struct gfs_inode, acquire Inode-Open (iopen) glock, + * read dinode from disk + * @i_gl: The (already held) glock covering the inode + * @inum: The inode number + * @io_gl: the iopen glock to acquire/hold (using holder in new gfs_inode) + * @io_state: the state the iopen glock should be acquired in + * @ipp: pointer to put the returned inode in + * + * Returns: errno + */ + +static int +inode_create(struct gfs_glock *i_gl, struct gfs_inum *inum, + struct gfs_glock *io_gl, unsigned int io_state, + struct gfs_inode **ipp) +{ + struct gfs_sbd *sdp = i_gl->gl_sbd; + struct gfs_inode *ip; + int error = 0; + + RETRY_MALLOC(ip = kmem_cache_alloc(gfs_inode_cachep, GFP_KERNEL), ip); + memset(ip, 0, sizeof(struct gfs_inode)); + + ip->i_num = *inum; + + atomic_set(&ip->i_count, 1); + + ip->i_gl = i_gl; + ip->i_sbd = sdp; + + spin_lock_init(&ip->i_spin); + init_rwsem(&ip->i_rw_mutex); + + ip->i_greedy = gfs_tune_get(sdp, gt_greedy_default); + + /* Lock the iopen glock (may be recursive) */ + error = gfs_glock_nq_init(io_gl, + io_state, GL_LOCAL_EXCL | GL_EXACT, + &ip->i_iopen_gh); + if (error) + goto fail; + + ip->i_iopen_gh.gh_owner = NULL; + + /* Assign the inode's glock as this iopen glock's protected object */ + spin_lock(&io_gl->gl_spin); + gfs_glock_hold(i_gl); + set_gl2gl(io_gl, i_gl); + spin_unlock(&io_gl->gl_spin); + + /* Read dinode from disk */ + error = gfs_copyin_dinode(ip); + if (error) + goto fail_iopen; + + gfs_glock_hold(i_gl); + set_gl2ip(i_gl, ip); + + atomic_inc(&sdp->sd_inode_count); + + *ipp = ip; + + return 0; + + fail_iopen: + spin_lock(&io_gl->gl_spin); + set_gl2gl(io_gl, NULL); + gfs_glock_put(i_gl); + spin_unlock(&io_gl->gl_spin); + + gfs_glock_dq_uninit(&ip->i_iopen_gh); + + fail: + gfs_flush_meta_cache(ip); + kmem_cache_free(gfs_inode_cachep, ip); + *ipp = NULL; + + return error; +} + +/** + * gfs_inode_get - Get an inode given its number + * @i_gl: The glock covering the inode + * @inum: The inode number + * @create: Flag to say if we are allowed to create a new struct gfs_inode + * @ipp: pointer to put the returned inode in + * + * Returns: errno + * + * If creating a new gfs_inode structure, reads dinode from disk. + */ + +int +gfs_inode_get(struct gfs_glock *i_gl, struct gfs_inum *inum, int create, + struct gfs_inode **ipp) +{ + struct gfs_glock *io_gl; + int error = 0; + + *ipp = get_gl2ip(i_gl); + if (*ipp) { + atomic_inc(&(*ipp)->i_count); + gfs_assert_warn(i_gl->gl_sbd, + (*ipp)->i_num.no_formal_ino == + inum->no_formal_ino); + } else if (create) { + error = gfs_glock_get(i_gl->gl_sbd, + inum->no_addr, &gfs_iopen_glops, + CREATE, &io_gl); + if (!error) { + error = inode_create(i_gl, inum, io_gl, + LM_ST_SHARED, ipp); + gfs_glock_put(io_gl); + } + } + + return error; +} + +/** + * gfs_inode_hold - hold a struct gfs_inode structure + * @ip: The GFS inode + * + */ + +void +gfs_inode_hold(struct gfs_inode *ip) +{ + gfs_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0,); + atomic_inc(&ip->i_count); +} + +/** + * gfs_inode_put - put a struct gfs_inode structure + * @ip: The GFS inode + * + */ + +void +gfs_inode_put(struct gfs_inode *ip) +{ + gfs_assert(ip->i_sbd, atomic_read(&ip->i_count) > 0,); + atomic_dec(&ip->i_count); +} + +/** + * gfs_inode_destroy - Destroy a GFS inode structure with no references on it + * @ip: The GFS inode + * + * Also, unhold the iopen glock and release indirect addressing buffers. + * This function must be called with a glocks held on the inode and + * the associated iopen. + * + */ + +void +gfs_inode_destroy(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_glock *io_gl = ip->i_iopen_gh.gh_gl; + struct gfs_glock *i_gl = ip->i_gl; + + gfs_assert_warn(sdp, !atomic_read(&ip->i_count)); + gfs_assert(sdp, get_gl2gl(io_gl) == i_gl,); + + /* Unhold the iopen glock */ + spin_lock(&io_gl->gl_spin); + set_gl2gl(io_gl, NULL); + gfs_glock_put(i_gl); + spin_unlock(&io_gl->gl_spin); + + gfs_glock_dq_uninit(&ip->i_iopen_gh); + + /* Release indirect addressing buffers, destroy the GFS inode struct */ + gfs_flush_meta_cache(ip); + kmem_cache_free(gfs_inode_cachep, ip); + + set_gl2ip(i_gl, NULL); + gfs_glock_put(i_gl); + + atomic_dec(&sdp->sd_inode_count); +} + +/** + * dinode_mark_unused - Set UNUSED flag in on-disk dinode + * @ip: + * + * Also: + * -- Increment incarnation number, to indicate that it no longer + * represents the old inode. + * -- Update change time (ctime) + * + * Returns: errno + */ + +static int +dinode_mark_unused(struct gfs_inode *ip) +{ + struct buffer_head *dibh; + struct gfs_dinode *di; + uint32_t incarn; + uint64_t ctime; + uint32_t flags; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + di = (struct gfs_dinode *)dibh->b_data; + + gfs_trans_add_bh(ip->i_gl, dibh); + + incarn = gfs32_to_cpu(di->di_header.mh_incarn) + 1; + di->di_header.mh_incarn = cpu_to_gfs32(incarn); + + ctime = get_seconds(); + di->di_ctime = cpu_to_gfs64(ctime); + + flags = (gfs32_to_cpu(di->di_flags)) | GFS_DIF_UNUSED; + di->di_flags = cpu_to_gfs32(flags); + + brelse(dibh); + + return 0; +} + +/** + * dinode_dealloc - Put deallocate a dinode + * @ip: The GFS inode + * + * Returns: errno + */ + +static int +dinode_dealloc(struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = ip->i_sbd; + struct gfs_alloc *al; + struct gfs_rgrpd *rgd; + int error; + + if (ip->i_di.di_blocks != 1) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + al = gfs_alloc_get(ip); + + error = gfs_quota_hold_m(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); + if (error) + goto out; + + error = gfs_rindex_hold(sdp, &al->al_ri_gh); + if (error) + goto out_qs; + + rgd = gfs_blk2rgrpd(sdp, ip->i_num.no_addr); + if (!rgd) { + gfs_consist_inode(ip); + error = -EIO; + goto out_rindex_relse; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &al->al_rgd_gh); + if (error) + goto out_rindex_relse; + + /* Trans may require: + One block for the RG header. + One block for the dinode bit. + One block for the dinode. + We also need a block for the unlinked change. + One block for the quota change. */ + + error = gfs_trans_begin(sdp, 3, 2); + if (error) + goto out_rg_gunlock; + + /* Set the UNUSED flag in the on-disk dinode block, increment incarn */ + error = dinode_mark_unused(ip); + if (error) + goto out_end_trans; + + /* De-allocate on-disk dinode block to FREEMETA */ + gfs_difree(rgd, ip); + + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, &ip->i_num); + clear_bit(GLF_STICKY, &ip->i_gl->gl_flags); + + out_end_trans: + gfs_trans_end(sdp); + + out_rg_gunlock: + gfs_glock_dq_uninit(&al->al_rgd_gh); + + out_rindex_relse: + gfs_glock_dq_uninit(&al->al_ri_gh); + + out_qs: + gfs_quota_unhold_m(ip); + + out: + gfs_alloc_put(ip); + + return error; +} + +/** + * inode_dealloc - Deallocate all on-disk blocks for an inode (dinode) + * @sdp: the filesystem + * @inum: the inode number to deallocate + * @io_gh: a holder for the iopen glock for this inode + * + * De-allocates all on-disk blocks, data and metadata, associated with an inode. + * All metadata blocks become GFS_BLKST_FREEMETA. + * All data blocks become GFS_BLKST_FREE. + * Also de-allocates incore gfs_inode structure. + * + * Returns: errno + */ + +static int +inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum, + struct gfs_holder *io_gh) +{ + struct gfs_inode *ip; + struct gfs_holder i_gh; + int error; + + /* Lock the inode as we blow it away */ + error = gfs_glock_nq_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, 0, &i_gh); + if (error) + return error; + + /* We reacquire the iopen lock here to avoid a race with the NFS server + calling gfs_read_inode() with the inode number of a inode we're in + the process of deallocating. And we can't keep our hold on the lock + from inode_dealloc_init() for deadlock reasons. We do, however, + overlap this iopen lock with the one to be acquired EX within + inode_create(), below (recursive EX locks will be granted to same + holder process, i.e. this process). */ + + gfs_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY, io_gh); + error = gfs_glock_nq(io_gh); + switch (error) { + case 0: + break; + case GLR_TRYFAILED: + error = 0; + goto fail; + default: + goto fail; + } + + gfs_assert_warn(sdp, !get_gl2ip(i_gh.gh_gl)); + error = inode_create(i_gh.gh_gl, inum, io_gh->gh_gl, LM_ST_EXCLUSIVE, + &ip); + + gfs_glock_dq(io_gh); + + if (error) + goto fail; + + /* Verify disk (d)inode, gfs inode, and VFS (v)inode are unused */ + if (ip->i_di.di_nlink) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + error = -EIO; + goto fail_iput; + } + gfs_assert_warn(sdp, atomic_read(&ip->i_count) == 1); + gfs_assert_warn(sdp, !ip->i_vnode); + + /* Free all on-disk directory leaves (if any) to FREEMETA state */ + if (ip->i_di.di_type == GFS_FILE_DIR && + (ip->i_di.di_flags & GFS_DIF_EXHASH)) { + error = gfs_dir_exhash_free(ip); + if (error) + goto fail_iput; + } + + /* Free all on-disk extended attribute blocks to FREEMETA state */ + if (ip->i_di.di_eattr) { + error = gfs_ea_dealloc(ip); + if (error) + goto fail_iput; + } + + /* Free all data blocks to FREE state, and meta blocks to FREEMETA */ + error = gfs_shrink(ip, 0, NULL); + if (error) + goto fail_iput; + + /* Set UNUSED flag and increment incarn # in on-disk dinode block, + and de-alloc the block to FREEMETA */ + error = dinode_dealloc(ip); + if (error) + goto fail_iput; + + /* Free the GFS inode structure, unhold iopen and inode glocks */ + gfs_inode_put(ip); + gfs_inode_destroy(ip); + + gfs_glock_dq_uninit(&i_gh); + + return 0; + + fail_iput: + gfs_inode_put(ip); + gfs_inode_destroy(ip); + + fail: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * inode_dealloc_init - Try to deallocate an initialized on-disk inode (dinode) + * and all of its associated data and meta blocks + * @sdp: the filesystem + * + * Returns: 0 on success, -errno on error, 1 on busy (inode open) + */ + +static int +inode_dealloc_init(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_holder io_gh; + int error = 0; + + /* If not busy (on this node), de-alloc GFS incore inode, releasing + any indirect addressing buffers, and unholding iopen glock */ + gfs_try_toss_inode(sdp, inum); + + /* Does another process (cluster-wide) have this inode open? */ + error = gfs_glock_nq_num(sdp, + inum->no_addr, &gfs_iopen_glops, + LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB, &io_gh); + switch (error) { + case 0: + break; + case GLR_TRYFAILED: + return 1; + default: + return error; + } + + /* Unlock here to prevent deadlock */ + gfs_glock_dq(&io_gh); + + /* No other process in the entire cluster has this inode open; + we can remove it and all of its associated blocks from disk */ + error = inode_dealloc(sdp, inum, &io_gh); + gfs_holder_uninit(&io_gh); + + return error; +} + +/** + * inode_dealloc_uninit - dealloc an uninitialized on-disk inode (dinode) block + * @sdp: the filesystem + * + * Create a transaction to change dinode block's alloc state to FREEMETA + * + * Returns: 0 on success, -errno on error, 1 on busy + */ + +static int +inode_dealloc_uninit(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_rgrpd *rgd; + struct gfs_holder ri_gh, rgd_gh; + int error; + + error = gfs_rindex_hold(sdp, &ri_gh); + if (error) + return error; + + rgd = gfs_blk2rgrpd(sdp, inum->no_addr); + if (!rgd) { + gfs_consist(sdp); + error = -EIO; + goto fail; + } + + error = gfs_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &rgd_gh); + if (error) + goto fail; + + /* Trans may require: + One block for the RG header. + One block for the dinode bit. + We also need a block for the unlinked change. */ + + error = gfs_trans_begin(sdp, 2, 1); + if (error) + goto fail_gunlock; + + gfs_difree_uninit(rgd, inum->no_addr); + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, inum); + + gfs_trans_end(sdp); + + gfs_glock_dq_uninit(&rgd_gh); + gfs_glock_dq_uninit(&ri_gh); + + return 0; + + fail_gunlock: + gfs_glock_dq_uninit(&rgd_gh); + + fail: + gfs_glock_dq_uninit(&ri_gh); + + return error; +} + +/** + * gfs_inode_dealloc - Grab an unlinked inode off the list and try to free it. + * @sdp: the filesystem + * + * Returns: 0 on success, -errno on error, 1 on busy + */ + +int +gfs_inode_dealloc(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + if (inum->no_formal_ino) + return inode_dealloc_init(sdp, inum); + else + return inode_dealloc_uninit(sdp, inum); +} + +/** + * gfs_change_nlink - Change nlink count on inode + * @ip: The GFS inode + * @diff: The change in the nlink count required + * + * Returns: errno + */ + +int +gfs_change_nlink(struct gfs_inode *ip, int diff) +{ + struct buffer_head *dibh; + uint32_t nlink; + int error; + + nlink = ip->i_di.di_nlink + diff; + + /* Tricky. If we are reducing the nlink count, + but the new value ends up being bigger than the + old one, we must have underflowed. */ + if (diff < 0 && nlink > ip->i_di.di_nlink) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + return error; + + ip->i_di.di_nlink = nlink; + ip->i_di.di_ctime = get_seconds(); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * gfs_lookupi - Look up a filename in a directory and return its inode + * @d_gh: An initialized holder for the directory glock + * @name: The name of the inode to look for + * @is_root: If TRUE, ignore the caller's permissions + * @i_gh: An uninitialized holder for the new inode glock + * + * There will always be a vnode (Linux VFS inode) for the d_gh inode unless + * @is_root is true. + * + * Returns: errno + */ + +int +gfs_lookupi(struct gfs_holder *d_gh, struct qstr *name, + int is_root, struct gfs_holder *i_gh) +{ + struct gfs_inode *dip = get_gl2ip(d_gh->gh_gl); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_glock *gl; + struct gfs_inode *ip; + struct gfs_inum inum, inum2; + unsigned int type; + int error; + + i_gh->gh_gl = NULL; + + if (!name->len || name->len > GFS_FNAMESIZE) + return -ENAMETOOLONG; + + if (gfs_filecmp(name, ".", 1) || + (gfs_filecmp(name, "..", 2) && dip == sdp->sd_rooti)) { + gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (!error) { + error = gfs_glock_nq_init(dip->i_gl, + LM_ST_SHARED, 0, + i_gh); + if (error) { + gfs_glock_dq(d_gh); + return error; + } + gfs_inode_hold(dip); + } + return error; + } + + if (gfs_assert_warn(sdp, !gfs_glock_is_locked_by_me(d_gh->gh_gl))) + return -EINVAL; + + gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) + return error; + + if (!is_root) { + error = inode_permission(dip->i_vnode, MAY_EXEC); + if (error) { + gfs_glock_dq(d_gh); + return error; + } + } + + error = gfs_dir_search(dip, name, &inum, &type); + if (error) { + gfs_glock_dq(d_gh); + if (error == -ENOENT) + error = 0; + return error; + } + + restart: + error = gfs_glock_get(sdp, inum.no_formal_ino, &gfs_inode_glops, + CREATE, &gl); + if (error) { + gfs_glock_dq(d_gh); + return error; + } + + /* Acquire the second lock */ + + if (gl->gl_name.ln_number < dip->i_gl->gl_name.ln_number) { + gfs_glock_dq(d_gh); + + error = gfs_glock_nq_init(gl, LM_ST_SHARED, + LM_FLAG_ANY | GL_LOCAL_EXCL, + i_gh); + if (error) + goto out; + + gfs_holder_reinit(LM_ST_SHARED, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) { + gfs_glock_dq_uninit(i_gh); + goto out; + } + + if (!is_root) { + error = inode_permission(dip->i_vnode, MAY_EXEC); + if (error) { + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + goto out; + } + } + + error = gfs_dir_search(dip, name, &inum2, &type); + if (error) { + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + if (error == -ENOENT) + error = 0; + goto out; + } + + if (!gfs_inum_equal(&inum, &inum2)) { + gfs_glock_dq_uninit(i_gh); + gfs_glock_put(gl); + inum = inum2; + goto restart; + } + } else { + error = gfs_glock_nq_init(gl, LM_ST_SHARED, + LM_FLAG_ANY | GL_LOCAL_EXCL, + i_gh); + if (error) { + gfs_glock_dq(d_gh); + goto out; + } + } + + error = gfs_inode_get(gl, &inum, CREATE, &ip); + if (error) { + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + } else if (ip->i_di.di_type != type) { + gfs_consist_inode(dip); + gfs_inode_put(ip); + gfs_glock_dq(d_gh); + gfs_glock_dq_uninit(i_gh); + error = -EIO; + } + + out: + gfs_glock_put(gl); + + return error; +} + +/** + * create_ok - OK to create a new on-disk inode here? + * @dip: Directory in which dinode is to be created + * @name: Name of new dinode + * @type: GFS_FILE_XXX (regular file, dir, etc.) + * + * Returns: errno + */ + +static int +create_ok(struct gfs_inode *dip, struct qstr *name, unsigned int type) +{ + int error; + + error = inode_permission(dip->i_vnode, MAY_WRITE | MAY_EXEC); + if (error) + return error; + + /* Don't create entries in an unlinked directory */ + + if (!dip->i_di.di_nlink) + return -EPERM; + + error = gfs_dir_search(dip, name, NULL, NULL); + switch (error) { + case -ENOENT: + error = 0; + break; + case 0: + return -EEXIST; + default: + return error; + } + + if (dip->i_di.di_entries == (uint32_t)-1) + return -EFBIG; + if (type == GFS_FILE_DIR && dip->i_di.di_nlink == (uint32_t)-1) + return -EMLINK; + + return 0; +} + +/** + * dinode_alloc - Create an on-disk inode + * @dip: Directory in which to create the dinode + * @ul: + * + * Since this dinode is not yet linked, we also create an unlinked inode + * descriptor. + * + * Returns: errno + */ + +static int +dinode_alloc(struct gfs_inode *dip, struct gfs_unlinked **ul) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_alloc *al; + struct gfs_inum inum; + int error; + + /* Create in-place allocation structure, reserve 1 dinode */ + al = gfs_alloc_get(dip); + al->al_requested_di = 1; + error = gfs_inplace_reserve(dip); + if (error) + goto out; + + error = gfs_trans_begin(sdp, al->al_rgd->rd_ri.ri_length, 1); + if (error) + goto out_inplace; + + inum.no_formal_ino = 0; + error = gfs_dialloc(dip, &inum.no_addr); + if (error) + goto out_end_trans; + + *ul = gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &inum); + gfs_unlinked_lock(sdp, *ul); + + gfs_trans_add_gl(dip->i_gl); + + out_end_trans: + gfs_trans_end(sdp); + + out_inplace: + gfs_inplace_release(dip); + + out: + gfs_alloc_put(dip); + + return error; +} + +/** + * pick_formal_ino - Pick a formal inode number for a given inode + * @sdp: the filesystem + * @inum: the inode number structure + * + */ + +static void +pick_formal_ino(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + /* This won't always be true */ + inum->no_formal_ino = inum->no_addr; +} + +/** + * make_dinode - Fill in a new dinode structure + * @dip: the directory this inode is being created in + * @gl: The glock covering the new inode + * @inum: the inode number + * @type: the file type + * @mode: the file permissions + * @uid: + * @gid: + * + */ + +static int +make_dinode(struct gfs_inode *dip, + struct gfs_glock *gl, struct gfs_inum *inum, + unsigned int type, unsigned int mode, + unsigned int uid, unsigned int gid) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_dinode di; + struct buffer_head *dibh; + struct gfs_rgrpd *rgd; + int error; + + error = gfs_dread(gl, inum->no_addr, + DIO_NEW | DIO_START | DIO_WAIT, + &dibh); + if (error) + return error; + + gfs_trans_add_bh(gl, dibh); + gfs_metatype_set(dibh, GFS_METATYPE_DI, GFS_FORMAT_DI); + gfs_buffer_clear_tail(dibh, sizeof(struct gfs_dinode)); + + memset(&di, 0, sizeof(struct gfs_dinode)); + + gfs_meta_header_in(&di.di_header, dibh->b_data); + + di.di_num = *inum; + + di.di_mode = mode & S_IALLUGO; + di.di_uid = uid; + di.di_gid = gid; + di.di_nlink = 1; + di.di_blocks = 1; + di.di_atime = di.di_mtime = di.di_ctime = get_seconds(); + + rgd = gfs_blk2rgrpd(sdp, inum->no_addr); + if (!rgd) { + if (gfs_consist(sdp)) + printk("GFS: fsid=%s: block = %"PRIu64"\n", + sdp->sd_fsname, inum->no_addr); + brelse(dibh); + return -EIO; + } + + di.di_rgrp = rgd->rd_ri.ri_addr; + di.di_goal_rgrp = di.di_rgrp; + di.di_goal_dblk = di.di_goal_mblk = inum->no_addr - rgd->rd_ri.ri_data1; + + if (type == GFS_FILE_REG) { + if ((dip->i_di.di_flags & GFS_DIF_INHERIT_JDATA) || + gfs_tune_get(sdp, gt_new_files_jdata)) + di.di_flags |= GFS_DIF_JDATA; + if ((dip->i_di.di_flags & GFS_DIF_INHERIT_DIRECTIO) || + gfs_tune_get(sdp, gt_new_files_directio)) + di.di_flags |= GFS_DIF_DIRECTIO; + } else if (type == GFS_FILE_DIR) { + di.di_flags |= (dip->i_di.di_flags & GFS_DIF_INHERIT_DIRECTIO); + di.di_flags |= (dip->i_di.di_flags & GFS_DIF_INHERIT_JDATA); + } + + di.di_type = type; + + gfs_dinode_out(&di, dibh->b_data); + brelse(dibh); + + return 0; +} + +/** + * inode_init_and_link - + * @dip: + * @name: + * @inum: + * @gl: + * @type: + * @mode: + * + * Returns: errno + */ + +static int +inode_init_and_link(struct gfs_inode *dip, struct qstr *name, + struct gfs_inum *inum, struct gfs_glock *gl, + unsigned int type, mode_t mode) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_alloc *al; + struct gfs_inode *ip; + unsigned int uid, gid; + int alloc_required; + void *acl_a_data = NULL, *acl_d_data = NULL; + unsigned int acl_size = 0, acl_blocks = 0; + int error; + + if (sdp->sd_args.ar_suiddir && + (dip->i_di.di_mode & S_ISUID) && + dip->i_di.di_uid) { + if (type == GFS_FILE_DIR) + mode |= S_ISUID; + else if (dip->i_di.di_uid != current->fsuid) + mode &= ~07111; + uid = dip->i_di.di_uid; + } else + uid = current->fsuid; + + if (dip->i_di.di_mode & S_ISGID) { + if (type == GFS_FILE_DIR) + mode |= S_ISGID; + gid = dip->i_di.di_gid; + } else + gid = current->fsgid; + + error = gfs_acl_new_prep(dip, type, &mode, + &acl_a_data, &acl_d_data, + &acl_size, &acl_blocks); + if (error) + return error; + + al = gfs_alloc_get(dip); + + error = gfs_quota_lock_m(dip, uid, gid); + if (error) + goto fail; + + error = gfs_quota_check(dip, uid, gid); + if (error) + goto fail_gunlock_q; + + if (acl_blocks) + alloc_required = TRUE; + else { + error = gfs_diradd_alloc_required(dip, name, &alloc_required); + if (error) + goto fail_gunlock_q; + } + + if (alloc_required) { + error = gfs_quota_check(dip, dip->i_di.di_uid, dip->i_di.di_gid); + if (error) + goto fail_gunlock_q; + + al->al_requested_meta = sdp->sd_max_dirres + acl_blocks; + + error = gfs_inplace_reserve(dip); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + blocks for two dinodes, the directory blocks necessary for + a new entry, RG bitmap blocks for an allocation, + and one block for a quota change and + one block for an unlinked tag. */ + + error = gfs_trans_begin(sdp, + 2 + sdp->sd_max_dirres + acl_blocks + + al->al_rgd->rd_ri.ri_length, 2); + if (error) + goto fail_inplace; + } else { + error = gfs_rindex_hold(sdp, &al->al_ri_gh); + if (error) + goto fail_gunlock_q; + + /* Trans may require: + blocks for two dinodes, a leaf block, + and one block for a quota change and + one block for an unlinked tag. */ + + error = gfs_trans_begin(sdp, 3, 2); + if (error) + goto fail_inplace; + } + + error = gfs_dir_add(dip, name, inum, type); + if (error) + goto fail_end_trans; + + error = make_dinode(dip, gl, inum, type, mode, uid, gid); + if (error) + goto fail_end_trans; + + al->al_ul = gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, + &(struct gfs_inum){0, inum->no_addr}); + gfs_trans_add_quota(sdp, +1, uid, gid); + + error = gfs_inode_get(gl, inum, CREATE, &ip); + + /* This should only fail if we are already shutdown. */ + if (gfs_assert_withdraw(sdp, !error)) + goto fail_end_trans; + + if (acl_blocks) + error = gfs_acl_new_init(dip, ip, + acl_a_data, acl_d_data, + acl_size); + + if (!alloc_required) + gfs_glock_dq_uninit(&al->al_ri_gh); + + return error; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_inplace: + if (alloc_required) + gfs_inplace_release(dip); + else + gfs_glock_dq_uninit(&al->al_ri_gh); + + fail_gunlock_q: + gfs_quota_unlock_m(dip); + + fail: + gfs_alloc_put(dip); + if (acl_a_data) + kfree(acl_a_data); + else if (acl_d_data) + kfree(acl_d_data); + + return error; +} + +/** + * gfs_createi - Create a new inode + * @d_gh: An initialized holder for the directory glock + * @name: The name of the new file + * @type: The type of dinode (GFS_FILE_REG, GFS_FILE_DIR, GFS_FILE_LNK, ...) + * @mode: the permissions on the new inode + * @i_gh: An uninitialized holder for the new inode glock + * + * If the return value is 0, the glocks on both the directory and the new + * file are held. A transaction has been started and an inplace reservation + * is held, as well. + * + * Returns: errno + */ + +int +gfs_createi(struct gfs_holder *d_gh, struct qstr *name, + unsigned int type, unsigned int mode, + struct gfs_holder *i_gh) +{ + struct gfs_inode *dip = get_gl2ip(d_gh->gh_gl); + struct gfs_sbd *sdp = dip->i_sbd; + struct gfs_unlinked *ul; + struct gfs_inum inum; + struct gfs_holder io_gh; + int error; + + if (!name->len || name->len > GFS_FNAMESIZE) + return -ENAMETOOLONG; + + gfs_holder_reinit(LM_ST_EXCLUSIVE, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) + return error; + + error = create_ok(dip, name, type); + if (error) + goto fail; + + error = dinode_alloc(dip, &ul); + if (error) + goto fail; + + inum.no_addr = ul->ul_inum.no_addr; + pick_formal_ino(sdp, &inum); + + if (inum.no_formal_ino < dip->i_num.no_formal_ino) { + gfs_glock_dq(d_gh); + + error = gfs_glock_nq_num(sdp, + inum.no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, GL_SKIP, i_gh); + if (error) { + gfs_unlinked_unlock(sdp, ul); + return error; + } + + gfs_holder_reinit(LM_ST_EXCLUSIVE, 0, d_gh); + error = gfs_glock_nq(d_gh); + if (error) { + gfs_glock_dq_uninit(i_gh); + gfs_unlinked_unlock(sdp, ul); + return error; + } + + error = create_ok(dip, name, type); + if (error) + goto fail_gunlock_i; + } else { + error = gfs_glock_nq_num(sdp, + inum.no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, GL_SKIP, i_gh); + if (error) + goto fail_ul; + } + + error = gfs_glock_nq_num(sdp, + inum.no_addr, &gfs_iopen_glops, + LM_ST_SHARED, GL_LOCAL_EXCL | GL_EXACT, + &io_gh); + if (error) + goto fail_gunlock_i; + + error = inode_init_and_link(dip, name, &inum, i_gh->gh_gl, type, mode); + if (error) + goto fail_gunlock_io; + + gfs_glock_dq_uninit(&io_gh); + + return 0; + + fail_gunlock_io: + gfs_glock_dq_uninit(&io_gh); + + fail_gunlock_i: + gfs_glock_dq_uninit(i_gh); + + fail_ul: + gfs_unlinked_unlock(sdp, ul); + + fail: + gfs_glock_dq(d_gh); + + return error; +} + +/** + * gfs_unlinki - Unlink a file + * @dip: The inode of the directory + * @name: The name of the file to be unlinked + * @ip: The inode of the file to be removed + * + * Assumes Glocks on both dip and ip are held. + * + * Returns: errno + */ + +int +gfs_unlinki(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + int error; + + error = gfs_dir_del(dip, name); + if (error) + return error; + + error = gfs_change_nlink(ip, -1); + if (error) + return error; + + /* If this inode is being unlinked from the directory structure, + we need to mark that in the log so that it isn't lost during + a crash. */ + + if (!ip->i_di.di_nlink) { + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &ip->i_num); + set_bit(GLF_STICKY, &ip->i_gl->gl_flags); + } + + return 0; +} + +/** + * gfs_rmdiri - Remove a directory + * @dip: The parent directory of the directory to be removed + * @name: The name of the directory to be removed + * @ip: The GFS inode of the directory to be removed + * + * Assumes Glocks on dip and ip are held + * + * Returns: errno + */ + +int +gfs_rmdiri(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) +{ + struct gfs_sbd *sdp = dip->i_sbd; + struct qstr dotname; + int error; + + if (ip->i_di.di_entries != 2) { + if (gfs_consist_inode(ip)) + gfs_dinode_print(&ip->i_di); + return -EIO; + } + + error = gfs_dir_del(dip, name); + if (error) + return error; + + error = gfs_change_nlink(dip, -1); + if (error) + return error; + + dotname.len = 1; + dotname.name = "."; + error = gfs_dir_del(ip, &dotname); + if (error) + return error; + + dotname.len = 2; + dotname.name = ".."; + error = gfs_dir_del(ip, &dotname); + if (error) + return error; + + error = gfs_change_nlink(ip, -2); + if (error) + return error; + + /* This inode is being unlinked from the directory structure and + we need to mark that in the log so that it isn't lost during + a crash. */ + + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IUL, &ip->i_num); + set_bit(GLF_STICKY, &ip->i_gl->gl_flags); + + return 0; +} + +/* + * gfs_unlink_ok - check to see that a inode is still in a directory + * @dip: the directory + * @name: the name of the file + * @ip: the inode + * + * Assumes that the lock on (at least) @dip is held. + * + * Returns: 0 if the parent/child relationship is correct, errno if it isn't + */ + +int +gfs_unlink_ok(struct gfs_inode *dip, struct qstr *name, struct gfs_inode *ip) +{ + struct gfs_inum inum; + unsigned int type; + int error; + + if (IS_IMMUTABLE(ip->i_vnode) || IS_APPEND(ip->i_vnode)) + return -EPERM; + + if ((dip->i_di.di_mode & S_ISVTX) && + dip->i_di.di_uid != current->fsuid && + ip->i_di.di_uid != current->fsuid && + !capable(CAP_FOWNER)) + return -EPERM; + + if (IS_APPEND(dip->i_vnode)) + return -EPERM; + + error = inode_permission(dip->i_vnode, MAY_WRITE | MAY_EXEC); + if (error) + return error; + + error = gfs_dir_search(dip, name, &inum, &type); + if (error) + return error; + + if (inum.no_formal_ino != ip->i_num.no_formal_ino) + return -ENOENT; + + if (ip->i_di.di_type != type) { + gfs_consist_inode(dip); + return -EIO; + } + + return 0; +} + +/* + * gfs_ok_to_move - check if it's ok to move a directory to another directory + * @this: move this + * @to: to here + * + * Follow @to back to the root and make sure we don't encounter @this + * Assumes we already hold the rename lock. + * + * Returns: errno + */ + +int +gfs_ok_to_move(struct gfs_inode *this, struct gfs_inode *to) +{ + struct gfs_sbd *sdp = this->i_sbd; + struct gfs_inode *tmp; + struct gfs_holder to_gh, tmp_gh; + struct qstr dotdot; + int error = 0; + + memset(&dotdot, 0, sizeof (struct qstr)); + dotdot.name = ".."; + dotdot.len = 2; + + gfs_inode_hold(to); + + for (;;) { + if (to == this) { + error = -EINVAL; + break; + } + if (to == sdp->sd_rooti) { + error = 0; + break; + } + + gfs_holder_init(to->i_gl, 0, 0, &to_gh); + + error = gfs_lookupi(&to_gh, &dotdot, TRUE, &tmp_gh); + if (error) { + gfs_holder_uninit(&to_gh); + break; + } + if (!tmp_gh.gh_gl) { + gfs_holder_uninit(&to_gh); + error = -ENOENT; + break; + } + + tmp = get_gl2ip(tmp_gh.gh_gl); + + gfs_glock_dq_uninit(&to_gh); + gfs_glock_dq_uninit(&tmp_gh); + + gfs_inode_put(to); + to = tmp; + } + + gfs_inode_put(to); + + return error; +} + +/** + * gfs_readlinki - return the contents of a symlink + * @ip: the symlink's inode + * @buf: a pointer to the buffer to be filled + * @len: a pointer to the length of @buf + * + * If @buf is too small, a piece of memory is kmalloc()ed and needs + * to be freed by the caller. + * + * Returns: errno + */ + +int +gfs_readlinki(struct gfs_inode *ip, char **buf, unsigned int *len) +{ + struct gfs_holder i_gh; + struct buffer_head *dibh; + unsigned int x; + int error; + + gfs_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &i_gh); + error = gfs_glock_nq_atime(&i_gh); + if (error) { + gfs_holder_uninit(&i_gh); + return error; + } + + if (!ip->i_di.di_size) { + gfs_consist_inode(ip); + error = -EIO; + goto out; + } + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto out; + + x = ip->i_di.di_size + 1; + if (x > *len) { + *buf = kmalloc(x, GFP_KERNEL); + if (!*buf) { + error = -ENOMEM; + goto out_brelse; + } + } + + memcpy(*buf, dibh->b_data + sizeof(struct gfs_dinode), x); + *len = x; + + out_brelse: + brelse(dibh); + + out: + gfs_glock_dq_uninit(&i_gh); + + return error; +} + +/** + * gfs_glock_nq_atime - Acquire a hold on an inode's glock, and + * conditionally update the inode's atime + * @gh: the holder to acquire + * + * Tests atime (access time) for gfs_read, gfs_readdir and gfs_mmap + * Update if the difference between the current time and the inode's current + * atime is greater than an interval specified at mount (or default). + * + * Will not update if GFS mounted NOATIME (this is *the* place where NOATIME + * has an effect) or Read-Only. + * + * Returns: errno + */ + +int +gfs_glock_nq_atime(struct gfs_holder *gh) +{ + struct gfs_glock *gl = gh->gh_gl; + struct gfs_sbd *sdp = gl->gl_sbd; + struct gfs_inode *ip = get_gl2ip(gl); + int64_t curtime, quantum = gfs_tune_get(sdp, gt_atime_quantum); + unsigned int state; + int flags; + int error; + + if (gfs_assert_warn(sdp, gh->gh_flags & GL_ATIME) || + gfs_assert_warn(sdp, !(gh->gh_flags & GL_ASYNC)) || + gfs_assert_warn(sdp, gl->gl_ops == &gfs_inode_glops)) + return -EINVAL; + + /* Save original request state of lock holder */ + state = gh->gh_state; + flags = gh->gh_flags; + + error = gfs_glock_nq(gh); + if (error) + return error; + + if (test_bit(SDF_NOATIME, &sdp->sd_flags) || + test_bit(SDF_ROFS, &sdp->sd_flags)) + return 0; + + curtime = get_seconds(); + if (curtime - ip->i_di.di_atime >= quantum) { + /* Get EX hold (force EX glock via !ANY) to write the dinode */ + gfs_glock_dq(gh); + gfs_holder_reinit(LM_ST_EXCLUSIVE, + gh->gh_flags & ~LM_FLAG_ANY, + gh); + error = gfs_glock_nq(gh); + if (error) + return error; + + /* Verify that atime hasn't been updated while we were + trying to get exclusive lock. */ + + curtime = get_seconds(); + if (curtime - ip->i_di.di_atime >= quantum) { + struct buffer_head *dibh; + + error = gfs_trans_begin(sdp, 1, 0); + if (error == -EROFS) + return 0; + if (error) + goto fail; + + error = gfs_get_inode_buffer(ip, &dibh); + if (error) + goto fail_end_trans; + + ip->i_di.di_atime = curtime; + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + + gfs_trans_end(sdp); + } + + /* If someone else has asked for the glock, + unlock and let them have it. Then reacquire + in the original state. */ + if (gfs_glock_is_blocking(gl)) { + gfs_glock_dq(gh); + gfs_holder_reinit(state, flags, gh); + return gfs_glock_nq(gh); + } + } + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail: + gfs_glock_dq(gh); + + return error; +} + +/** + * glock_compare_atime - Compare two struct gfs_glock structures for gfs_sort() + * @arg_a: the first structure + * @arg_b: the second structure + * + * Sort order determined by (in order of priority): + * -- lock number + * -- lock state (SHARED > EXCLUSIVE or GL_ATIME, which can demand EXCLUSIVE) + * + * Returns: 1 if A > B + * -1 if A < B + * 0 if A = B + */ + +static int +glock_compare_atime(const void *arg_a, const void *arg_b) +{ + struct gfs_holder *gh_a = *(struct gfs_holder **)arg_a; + struct gfs_holder *gh_b = *(struct gfs_holder **)arg_b; + struct lm_lockname *a = &gh_a->gh_gl->gl_name; + struct lm_lockname *b = &gh_b->gh_gl->gl_name; + int ret = 0; + + if (a->ln_number > b->ln_number) + ret = 1; + else if (a->ln_number < b->ln_number) + ret = -1; + else { + if (gh_a->gh_state == LM_ST_SHARED && + gh_b->gh_state == LM_ST_EXCLUSIVE) + ret = 1; + else if (gh_a->gh_state == LM_ST_SHARED && + (gh_b->gh_flags & GL_ATIME)) + ret = 1; + } + + return ret; +} + +/** + * gfs_glock_nq_m_atime - acquire multiple glocks where one may need an + * atime update + * @num_gh: the number of structures + * @ghs: an array of struct gfs_holder structures + * + * Returns: 0 on success (all glocks acquired), + * errno on failure (no glocks acquired) + */ + +int +gfs_glock_nq_m_atime(unsigned int num_gh, struct gfs_holder *ghs) +{ + struct gfs_holder **p; + unsigned int x; + int error = 0; + + if (!num_gh) + return 0; + + if (num_gh == 1) { + ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + if (ghs->gh_flags & GL_ATIME) + error = gfs_glock_nq_atime(ghs); + else + error = gfs_glock_nq(ghs); + return error; + } + + p = kmalloc(num_gh * sizeof(struct gfs_holder *), GFP_KERNEL); + if (!p) + return -ENOMEM; + + for (x = 0; x < num_gh; x++) + p[x] = &ghs[x]; + + gfs_sort(p, num_gh, sizeof(struct gfs_holder *), glock_compare_atime); + + for (x = 0; x < num_gh; x++) { + p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC); + + if (p[x]->gh_flags & GL_ATIME) + error = gfs_glock_nq_atime(p[x]); + else + error = gfs_glock_nq(p[x]); + + if (error) { + while (x--) + gfs_glock_dq(p[x]); + break; + } + } + + kfree(p); + return error; +} + +/** + * gfs_try_toss_vnode - See if we can toss a vnode from memory + * @ip: the inode + * + * Returns: TRUE if the vnode was tossed + */ + +void +gfs_try_toss_vnode(struct gfs_inode *ip) +{ + struct inode *inode; + + inode = gfs_iget(ip, NO_CREATE); + if (!inode) + return; + + d_prune_aliases(inode); + + if (ip->i_di.di_type == GFS_FILE_DIR) { + struct list_head *head = &inode->i_dentry; + struct dentry *d = NULL; + + spin_lock(&dcache_lock); + if (list_empty(head)) + spin_unlock(&dcache_lock); + else { + d = list_entry(head->next, struct dentry, d_alias); + dget_locked(d); + spin_unlock(&dcache_lock); + + if (have_submounts(d)) + dput(d); + else { + shrink_dcache_parent(d); + dput(d); + d_prune_aliases(inode); + } + } + } + + inode->i_nlink = 0; + iput(inode); +} + + +static int +__gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr) +{ + struct buffer_head *dibh; + int error; + + error = gfs_get_inode_buffer(ip, &dibh); + if (!error) { + error = inode_setattr(ip->i_vnode, attr); + gfs_assert_warn(ip->i_sbd, !error); + gfs_inode_attr_out(ip); + + gfs_trans_add_bh(ip->i_gl, dibh); + gfs_dinode_out(&ip->i_di, dibh->b_data); + brelse(dibh); + } + + return error; +} + +/** + * gfs_setattr_simple - + * @ip: + * @attr: + * + * Called with a reference on the vnode. + * + * Returns: errno + */ + +int +gfs_setattr_simple(struct gfs_inode *ip, struct iattr *attr) +{ + int error; + + if (get_transaction) + return __gfs_setattr_simple(ip, attr); + + /* Trans may require: + one dinode block. */ + + error = gfs_trans_begin(ip->i_sbd, 1, 0); + if (error) + return error; + + error = __gfs_setattr_simple(ip, attr); + + gfs_trans_end(ip->i_sbd); + + return error; +} + +/** + * iah_make_jdata - + * @gl: + * @inum: + * + */ + +static void +iah_make_jdata(struct gfs_glock *gl, struct gfs_inum *inum) +{ + struct buffer_head *bh; + struct gfs_dinode *di; + uint32_t flags; + int error; + + error = gfs_dread(gl, inum->no_addr, DIO_START | DIO_WAIT, &bh); + + /* This should only fail if we are already shutdown. */ + if (gfs_assert_withdraw(gl->gl_sbd, !error)) + return; + + di = (struct gfs_dinode *)bh->b_data; + + flags = di->di_flags; + flags = gfs32_to_cpu(flags) | GFS_DIF_JDATA; + di->di_flags = cpu_to_gfs32(flags); + + brelse(bh); +} + +/** + * iah_super_update - Write superblock to disk + * @sdp: filesystem instance structure + * + * Returns: errno + * + * Update on-disk superblock, using (modified) data in sdp->sd_sb + */ + +static int +iah_super_update(struct gfs_sbd *sdp) +{ + struct gfs_glock *gl; + struct buffer_head *bh; + int error; + + error = gfs_glock_get(sdp, + GFS_SB_LOCK, &gfs_meta_glops, + NO_CREATE, &gl); + if (gfs_assert_withdraw(sdp, !error && gl)) /* This should already be held. */ + return -EINVAL; + + error = gfs_dread(gl, GFS_SB_ADDR >> sdp->sd_fsb2bb_shift, + DIO_START | DIO_WAIT, &bh); + if (!error) { + gfs_trans_add_bh(gl, bh); + gfs_sb_out(&sdp->sd_sb, bh->b_data); + brelse(bh); + } + + gfs_glock_put(gl); + + return error; +} + +/** + * inode_alloc_hidden - allocate on-disk inode for a special (hidden) file + * @sdp: the filesystem instance structure + * @inum: new dinode's block # and formal inode #, to be filled + * in by this function. + * + * Returns: errno + * + * This function is called only very rarely, when the first-to-mount + * node can't find a pre-existing special file (e.g. license or quota file) that + * it expects to find. This should happen only when upgrading from an older + * version of the filesystem. + * + * The @inum must be a member of sdp->sd_sb in order to get updated to on-disk + * superblock properly. + */ + +static int +inode_alloc_hidden(struct gfs_sbd *sdp, struct gfs_inum *inum) +{ + struct gfs_inode *dip = sdp->sd_rooti; + struct gfs_holder d_gh, i_gh; + struct gfs_unlinked *ul; + int error; + + error = gfs_glock_nq_init(dip->i_gl, LM_ST_EXCLUSIVE, 0, &d_gh); + if (error) + return error; + + error = dinode_alloc(dip, &ul); + if (error) + goto fail; + + inum->no_addr = ul->ul_inum.no_addr; + pick_formal_ino(sdp, inum); + + /* Don't worry about deadlock ordering here. We're the first + mounter and still under the mount lock (i.e. there is no + contention). */ + + error = gfs_glock_nq_num(sdp, + inum->no_formal_ino, &gfs_inode_glops, + LM_ST_EXCLUSIVE, GL_SKIP, &i_gh); + if (error) + goto fail_ul; + + gfs_alloc_get(dip); + + error = gfs_quota_hold_m(dip, 0, 0); + if (error) + goto fail_al; + + /* Trans may require: + The new inode, the superblock, + and one block for a quota change and + one block for an unlinked tag. */ + + error = gfs_trans_begin(sdp, 2, 2); + if (error) + goto fail_unhold; + + error = make_dinode(dip, i_gh.gh_gl, inum, GFS_FILE_REG, 0600, 0, 0); + if (error) + goto fail_end_trans; + + /* Hidden files get all of their data (not just metadata) journaled */ + iah_make_jdata(i_gh.gh_gl, inum); + + error = iah_super_update(sdp); + if (error) + goto fail_end_trans; + + gfs_trans_add_unlinked(sdp, GFS_LOG_DESC_IDA, + &(struct gfs_inum){0, inum->no_addr}); + gfs_trans_add_quota(sdp, +1, 0, 0); + gfs_trans_add_gl(dip->i_gl); + + gfs_trans_end(sdp); + gfs_quota_unhold_m(dip); + gfs_alloc_put(dip); + + gfs_glock_dq_uninit(&i_gh); + gfs_glock_dq_uninit(&d_gh); + + gfs_unlinked_unlock(sdp, ul); + + gfs_log_flush(sdp); + + return 0; + + fail_end_trans: + gfs_trans_end(sdp); + + fail_unhold: + gfs_quota_unhold_m(dip); + + fail_al: + gfs_alloc_put(dip); + gfs_glock_dq_uninit(&i_gh); + + fail_ul: + gfs_unlinked_unlock(sdp, ul); + + fail: + gfs_glock_dq_uninit(&d_gh); + + return error; +} + +/** + * gfs_alloc_qinode - allocate a quota inode + * @sdp: The GFS superblock + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_alloc_qinode(struct gfs_sbd *sdp) +{ + return inode_alloc_hidden(sdp, &sdp->sd_sb.sb_quota_di); +} + +/** + * gfs_alloc_linode - allocate a license inode + * @sdp: The GFS superblock + * + * Returns: 0 on success, error code otherwise + */ + +int +gfs_alloc_linode(struct gfs_sbd *sdp) +{ + return inode_alloc_hidden(sdp, &sdp->sd_sb.sb_license_di); +} --- linux-2.6.28.orig/ubuntu/gfs/locking.c +++ linux-2.6.28/ubuntu/gfs/locking.c @@ -0,0 +1,180 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2006 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 version 2. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lm_interface.h" + +struct lmh_wrapper { + struct list_head lw_list; + const struct lm_lockops *lw_ops; +}; + +/* List of registered low-level locking protocols. A file system selects one + of them by name at mount time, e.g. lock_nolock, lock_dlm. */ + +static LIST_HEAD(lmh_list); +static DEFINE_MUTEX(lmh_lock); + +/** + * gfs_register_lockproto - Register a low-level locking protocol + * @proto: the protocol definition + * + * Returns: 0 on success, -EXXX on failure + */ + +int gfs_register_lockproto(const struct lm_lockops *proto) +{ + struct lmh_wrapper *lw; + + mutex_lock(&lmh_lock); + + list_for_each_entry(lw, &lmh_list, lw_list) { + if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) { + mutex_unlock(&lmh_lock); + printk(KERN_INFO "GFS2: protocol %s already exists\n", + proto->lm_proto_name); + return -EEXIST; + } + } + + lw = kzalloc(sizeof(struct lmh_wrapper), GFP_KERNEL); + if (!lw) { + mutex_unlock(&lmh_lock); + return -ENOMEM; + } + + lw->lw_ops = proto; + list_add(&lw->lw_list, &lmh_list); + + mutex_unlock(&lmh_lock); + + return 0; +} + +/** + * gfs_unregister_lockproto - Unregister a low-level locking protocol + * @proto: the protocol definition + * + */ + +void gfs_unregister_lockproto(const struct lm_lockops *proto) +{ + struct lmh_wrapper *lw; + + mutex_lock(&lmh_lock); + + list_for_each_entry(lw, &lmh_list, lw_list) { + if (!strcmp(lw->lw_ops->lm_proto_name, proto->lm_proto_name)) { + list_del(&lw->lw_list); + mutex_unlock(&lmh_lock); + kfree(lw); + return; + } + } + + mutex_unlock(&lmh_lock); + + printk(KERN_WARNING "GFS2: can't unregister lock protocol %s\n", + proto->lm_proto_name); +} + +/** + * gfs_mount_lockproto - Mount a lock protocol + * @proto_name - the name of the protocol + * @table_name - the name of the lock space + * @host_data - data specific to this host + * @cb - the callback to the code using the lock module + * @sdp - The GFS2 superblock + * @min_lvb_size - the mininum LVB size that the caller can deal with + * @flags - LM_MFLAG_* + * @lockstruct - a structure returned describing the mount + * + * Returns: 0 on success, -EXXX on failure + */ + +int gfs_mount_lockproto(char *proto_name, char *table_name, char *host_data, + lm_callback_t cb, void *cb_data, + unsigned int min_lvb_size, int flags, + struct lm_lockstruct *lockstruct, + struct kobject *fskobj) +{ + struct lmh_wrapper *lw = NULL; + int try = 0; + int error, found; + +retry: + mutex_lock(&lmh_lock); + + found = 0; + list_for_each_entry(lw, &lmh_list, lw_list) { + if (!strcmp(lw->lw_ops->lm_proto_name, proto_name)) { + found = 1; + break; + } + } + + if (!found) { + if (!try && capable(CAP_SYS_MODULE)) { + try = 1; + mutex_unlock(&lmh_lock); + request_module(proto_name); + goto retry; + } + printk(KERN_INFO "GFS2: can't find protocol %s\n", proto_name); + error = -ENOENT; + goto out; + } + + if (!try_module_get(lw->lw_ops->lm_owner)) { + try = 0; + mutex_unlock(&lmh_lock); + msleep(1000); + goto retry; + } + + error = lw->lw_ops->lm_mount(table_name, host_data, cb, cb_data, + min_lvb_size, flags, lockstruct, fskobj); + if (error) + module_put(lw->lw_ops->lm_owner); +out: + mutex_unlock(&lmh_lock); + return error; +} + +void gfs_unmount_lockproto(struct lm_lockstruct *lockstruct) +{ + mutex_lock(&lmh_lock); + lockstruct->ls_ops->lm_unmount(lockstruct->ls_lockspace); + if (lockstruct->ls_ops->lm_owner) + module_put(lockstruct->ls_ops->lm_owner); + mutex_unlock(&lmh_lock); +} + +/** + * gfs_withdraw_lockproto - abnormally unmount a lock module + * @lockstruct: the lockstruct passed into mount + * + */ + +void gfs_withdraw_lockproto(struct lm_lockstruct *lockstruct) +{ + mutex_lock(&lmh_lock); + lockstruct->ls_ops->lm_withdraw(lockstruct->ls_lockspace); + if (lockstruct->ls_ops->lm_owner) + module_put(lockstruct->ls_ops->lm_owner); + mutex_unlock(&lmh_lock); +} --- linux-2.6.28.orig/ubuntu/gfs/trans.h +++ linux-2.6.28/ubuntu/gfs/trans.h @@ -0,0 +1,24 @@ +#ifndef __TRANS_DOT_H__ +#define __TRANS_DOT_H__ + +#define TRANS_IS_NEW (53) +#define TRANS_IS_INCORE (54) +void gfs_trans_print(struct gfs_sbd *sdp, struct gfs_trans *tr, + unsigned int where); + +int gfs_trans_begin_i(struct gfs_sbd *sdp, + unsigned int meta_blocks, unsigned int extra_blocks, + char *file, unsigned int line); +#define gfs_trans_begin(sdp, mb, eb) \ +gfs_trans_begin_i((sdp), (mb), (eb), __FILE__, __LINE__) + +void gfs_trans_end(struct gfs_sbd *sdp); + +void gfs_trans_add_gl(struct gfs_glock *gl); +void gfs_trans_add_bh(struct gfs_glock *gl, struct buffer_head *bh); +struct gfs_unlinked *gfs_trans_add_unlinked(struct gfs_sbd *sdp, unsigned int type, + struct gfs_inum *inum); +void gfs_trans_add_quota(struct gfs_sbd *sdp, int64_t change, uint32_t uid, + uint32_t gid); + +#endif /* __TRANS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/bmap.h +++ linux-2.6.28/ubuntu/gfs/bmap.h @@ -0,0 +1,35 @@ +#ifndef __BMAP_DOT_H__ +#define __BMAP_DOT_H__ + +typedef int (*gfs_unstuffer_t) (struct gfs_inode * ip, + struct buffer_head * dibh, uint64_t block, + void *private); + +int gfs_unstuffer_sync(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private); +int gfs_unstuffer_async(struct gfs_inode *ip, struct buffer_head *dibh, + uint64_t block, void *private); + +int gfs_unstuff_dinode(struct gfs_inode *ip, gfs_unstuffer_t unstuffer, + void *private); + +int gfs_block_map(struct gfs_inode *ip, + uint64_t lblock, int *new, + uint64_t *dblock, uint32_t *extlen); + +typedef int (*gfs_truncator_t) (struct gfs_inode * ip, uint64_t size); + +int gfs_truncator_default(struct gfs_inode *ip, uint64_t size); + +int gfs_shrink(struct gfs_inode *ip, uint64_t size, gfs_truncator_t truncator); +int gfs_truncatei(struct gfs_inode *ip, uint64_t size, + gfs_truncator_t truncator); + +void gfs_write_calc_reserv(struct gfs_inode *ip, unsigned int len, + unsigned int *data_blocks, unsigned int *ind_blocks); +int gfs_write_alloc_required(struct gfs_inode *ip, uint64_t offset, + unsigned int len, int *alloc_required); + +int gfs_get_file_meta(struct gfs_inode *ip, struct gfs_user_buffer *ub); + +#endif /* __BMAP_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/gfs/lock_dlm.h +++ linux-2.6.28/ubuntu/gfs/lock_dlm.h @@ -0,0 +1,182 @@ +/* + * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. + * Copyright (C) 2004-2005 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 version 2. + */ + +#ifndef LOCK_DLM_DOT_H +#define LOCK_DLM_DOT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "lm_interface.h" + +/* + * Internally, we prefix things with gdlm_ and GDLM_ (for gfs-dlm) since a + * prefix of lock_dlm_ gets awkward. Externally, GFS refers to this module + * as "lock_dlm". + */ + +#define GDLM_STRNAME_BYTES 24 +#define GDLM_LVB_SIZE 32 +#define GDLM_DROP_COUNT 0 +#define GDLM_DROP_PERIOD 60 +#define GDLM_NAME_LEN 128 + +/* GFS uses 12 bytes to identify a resource (32 bit type + 64 bit number). + We sprintf these numbers into a 24 byte string of hex values to make them + human-readable (to make debugging simpler.) */ + +struct gdlm_strname { + unsigned char name[GDLM_STRNAME_BYTES]; + unsigned short namelen; +}; + +enum { + DFL_BLOCK_LOCKS = 0, + DFL_SPECTATOR = 1, + DFL_WITHDRAW = 2, +}; + +struct gdlm_ls { + u32 id; + int jid; + int first; + int first_done; + unsigned long flags; + struct kobject kobj; + char clustername[GDLM_NAME_LEN]; + char fsname[GDLM_NAME_LEN]; + int fsflags; + dlm_lockspace_t *dlm_lockspace; + lm_callback_t fscb; + struct gfs_sbd *sdp; + int recover_jid; + int recover_jid_done; + int recover_jid_status; + spinlock_t async_lock; + struct list_head complete; + struct list_head blocking; + struct list_head delayed; + struct list_head submit; + struct list_head all_locks; + u32 all_locks_count; + wait_queue_head_t wait_control; + struct task_struct *thread1; + struct task_struct *thread2; + wait_queue_head_t thread_wait; + unsigned long drop_time; + int drop_locks_count; + int drop_locks_period; +}; + +enum { + LFL_NOBLOCK = 0, + LFL_NOCACHE = 1, + LFL_DLM_UNLOCK = 2, + LFL_DLM_CANCEL = 3, + LFL_SYNC_LVB = 4, + LFL_FORCE_PROMOTE = 5, + LFL_REREQUEST = 6, + LFL_ACTIVE = 7, + LFL_INLOCK = 8, + LFL_CANCEL = 9, + LFL_NOBAST = 10, + LFL_HEADQUE = 11, + LFL_UNLOCK_DELETE = 12, + LFL_AST_WAIT = 13, +}; + +struct gdlm_lock { + struct gdlm_ls *ls; + struct lm_lockname lockname; + struct gdlm_strname strname; + char *lvb; + struct dlm_lksb lksb; + + s16 cur; + s16 req; + s16 prev_req; + u32 lkf; /* dlm flags DLM_LKF_ */ + unsigned long flags; /* lock_dlm flags LFL_ */ + + int bast_mode; /* protected by async_lock */ + + struct list_head clist; /* complete */ + struct list_head blist; /* blocking */ + struct list_head delay_list; /* delayed */ + struct list_head all_list; /* all locks for the fs */ + struct gdlm_lock *hold_null; /* NL lock for hold_lvb */ +}; + +#define gdlm_assert(assertion, fmt, args...) \ +do { \ + if (unlikely(!(assertion))) { \ + printk(KERN_EMERG "lock_dlm: fatal assertion failed \"%s\"\n" \ + "lock_dlm: " fmt "\n", \ + #assertion, ##args); \ + BUG(); \ + } \ +} while (0) + +#define log_print(lev, fmt, arg...) printk(lev "lock_dlm: " fmt "\n" , ## arg) +#define log_info(fmt, arg...) log_print(KERN_INFO , fmt , ## arg) +#define log_error(fmt, arg...) log_print(KERN_ERR , fmt , ## arg) +#ifdef LOCK_DLM_LOG_DEBUG +#define log_debug(fmt, arg...) log_print(KERN_DEBUG , fmt , ## arg) +#else +#define log_debug(fmt, arg...) +#endif + +/* sysfs.c */ + +int gdlm_sysfs_init(void); +void gdlm_sysfs_exit(void); +int gdlm_kobject_setup(struct gdlm_ls *, struct kobject *); +void gdlm_kobject_release(struct gdlm_ls *); + +/* thread.c */ + +int gdlm_init_threads(struct gdlm_ls *); +void gdlm_release_threads(struct gdlm_ls *); + +/* lock.c */ + +s16 gdlm_make_lmstate(s16); +void gdlm_queue_delayed(struct gdlm_lock *); +void gdlm_submit_delayed(struct gdlm_ls *); +int gdlm_release_all_locks(struct gdlm_ls *); +void gdlm_delete_lp(struct gdlm_lock *); +unsigned int gdlm_do_lock(struct gdlm_lock *); + +int gdlm_get_lock(void *, struct lm_lockname *, void **); +void gdlm_put_lock(void *); +unsigned int gdlm_lock(void *, unsigned int, unsigned int, unsigned int); +unsigned int gdlm_unlock(void *, unsigned int); +void gdlm_cancel(void *); +int gdlm_hold_lvb(void *, char **); +void gdlm_unhold_lvb(void *, char *); + +/* mount.c */ + +extern const struct lm_lockops gdlm_ops; + +#endif + --- linux-2.6.28.orig/ubuntu/gfs/eaops.c +++ linux-2.6.28/ubuntu/gfs/eaops.c @@ -0,0 +1,173 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gfs.h" +#include "acl.h" +#include "eaops.h" +#include "eattr.h" + +/** + * gfs_ea_name2type - get the type of the ea, and trucate the type from the name + * @namep: ea name, possibly with type appended + * + * Returns: GFS_EATYPE_XXX + */ + +unsigned int +gfs_ea_name2type(const char *name, char **truncated_name) +{ + unsigned int type; + + if (strncmp(name, "system.", 7) == 0) { + type = GFS_EATYPE_SYS; + if (truncated_name) + *truncated_name = strchr(name, '.') + 1; + } else if (strncmp(name, "user.", 5) == 0) { + type = GFS_EATYPE_USR; + if (truncated_name) + *truncated_name = strchr(name, '.') + 1; + } else if (strncmp(name, "security.", 9) == 0) { + type = GFS_EATYPE_SECURITY; + if (truncated_name) + *truncated_name = strchr(name, '.') + 1; + } else { + type = GFS_EATYPE_UNUSED; + if (truncated_name) + *truncated_name = NULL; + } + + return type; +} + +/** + * system_eo_get - + * @ip: + * @er: + * + * Returns: errno + */ + +static int +system_eo_get(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + if (!GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len) && + !GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len) && + !capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (ip->i_sbd->sd_args.ar_posix_acls == FALSE && + (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len) || + GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len))) + return -EOPNOTSUPP; + + return gfs_ea_get_i(ip, er); +} + +/** + * system_eo_set - + * @ip: + * @er: + * + * Returns: errno + */ + +static int +system_eo_set(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + int remove = FALSE; + int error; + + if (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { + er->er_mode = ip->i_vnode->i_mode; + error = gfs_acl_validate_set(ip, TRUE, er, + &remove, &er->er_mode); + if (error) + return error; + error = gfs_ea_set_i(ip, er); + if (error) + return error; + if (remove) + gfs_ea_remove_i(ip, er); + return 0; + + } else if (GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) { + int error = gfs_acl_validate_set(ip, FALSE, er, + &remove, NULL); + if (error) + return error; + if (!remove) + error = gfs_ea_set_i(ip, er); + else { + error = gfs_ea_remove_i(ip, er); + if (error == -ENODATA) + error = 0; + } + return error; + } + + return -EPERM; +} + +/** + * system_eo_remove - + * @ip: + * @er: + * + * Returns: errno + */ + +static int +system_eo_remove(struct gfs_inode *ip, struct gfs_ea_request *er) +{ + if (GFS_ACL_IS_ACCESS(er->er_name, er->er_name_len)) { + int error = gfs_acl_validate_remove(ip, TRUE); + if (error) + return error; + + } else if (GFS_ACL_IS_DEFAULT(er->er_name, er->er_name_len)) { + int error = gfs_acl_validate_remove(ip, FALSE); + if (error) + return error; + + } else + return -EPERM; + + return gfs_ea_remove_i(ip, er); +} + +struct gfs_eattr_operations gfs_user_eaops = { + .eo_get = gfs_ea_get_i, + .eo_set = gfs_ea_set_i, + .eo_remove = gfs_ea_remove_i, + .eo_name = "user", +}; + +struct gfs_eattr_operations gfs_system_eaops = { + .eo_get = system_eo_get, + .eo_set = system_eo_set, + .eo_remove = system_eo_remove, + .eo_name = "system", +}; + +struct gfs_eattr_operations gfs_security_eaops = { + .eo_get = gfs_ea_get_i, + .eo_set = gfs_ea_set_i, + .eo_remove = gfs_ea_remove_i, + .eo_name = "security", +}; + +struct gfs_eattr_operations *gfs_ea_ops[] = { + NULL, + &gfs_user_eaops, + &gfs_system_eaops, + &gfs_security_eaops, +}; + --- linux-2.6.28.orig/ubuntu/gfs/glops.h +++ linux-2.6.28/ubuntu/gfs/glops.h @@ -0,0 +1,13 @@ +#ifndef __GLOPS_DOT_H__ +#define __GLOPS_DOT_H__ + +extern struct gfs_glock_operations gfs_meta_glops; +extern struct gfs_glock_operations gfs_inode_glops; +extern struct gfs_glock_operations gfs_rgrp_glops; +extern struct gfs_glock_operations gfs_trans_glops; +extern struct gfs_glock_operations gfs_iopen_glops; +extern struct gfs_glock_operations gfs_flock_glops; +extern struct gfs_glock_operations gfs_nondisk_glops; +extern struct gfs_glock_operations gfs_quota_glops; + +#endif /* __GLOPS_DOT_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/sysfs.c +++ linux-2.6.28/ubuntu/aufs/sysfs.c @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sysfs interface + * + * $Id: sysfs.c,v 1.13 2008/09/15 03:14:55 sfjro Exp $ + */ + +#include +#include +#include +#include +#include "aufs.h" + + +#ifdef CONFIG_AUFS_LOCAL +static ssize_t config_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ +#define conf_bool(name) "CONFIG_AUFS_" #name "=y\n" + static const char opt[] = +#ifdef CONFIG_AUFS + "CONFIG_AUFS=y\n" +#else + "CONFIG_AUFS=m\n" +#endif +#ifdef CONFIG_AUFS_BRANCH_MAX_127 + conf_bool(BRANCH_MAX_127) +#elif defined(CONFIG_AUFS_BRANCH_MAX_511) + conf_bool(BRANCH_MAX_511) +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) + conf_bool(BRANCH_MAX_1023) +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) + conf_bool(BRANCH_MAX_32767) +#endif +#ifdef CONFIG_AUFS_HINOTIFY + conf_bool(HINOTIFY) +#endif +#ifdef CONFIG_AUFS_EXPORT + conf_bool(EXPORT) +#endif +#ifdef CONFIG_AUFS_ROBR + conf_bool(ROBR) +#endif +#ifdef CONFIG_AUFS_SHWH + conf_bool(SHWH) +#endif +#ifdef CONFIG_AUFS_DLGT + conf_bool(DLGT) +#endif +#ifdef CONFIG_AUFS_HIN_OR_DLGT + conf_bool(HIN_OR_DLGT) +#endif +#ifdef CONFIG_AUFS_RR_SQUASHFS + conf_bool(RR_SQUASHFS) +#endif +#ifdef CONFIG_AUFS_SEC_PERM_PATCH + conf_bool(SEC_PERM_PATCH) +#endif +#ifdef CONFIG_AUFS_SPLICE_PATCH + conf_bool(SPLICE_PATCH) +#endif +#ifdef CONFIG_AUFS_PUT_FILP_PATCH + conf_bool(PUT_FILP_PATCH) +#endif +#ifdef CONFIG_AUFS_LHASH_PATCH + conf_bool(LHASH_PATCH) +#endif +#ifdef CONFIG_AUFS_BR_NFS + conf_bool(BR_NFS) +#endif +#ifdef CONFIG_AUFS_BR_XFS + conf_bool(BR_XFS) +#endif +#ifdef CONFIG_AUFS_FSYNC_SUPER_PATCH + conf_bool(FSYNC_SUPER_PATCH) +#endif +#ifdef CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH + conf_bool(DENY_WRITE_ACCESS_PATCH) +#endif +#ifdef CONFIG_AUFS_KSIZE_PATCH + conf_bool(KSIZE_PATCH) +#endif +#ifdef CONFIG_AUFS_WORKAROUND_FUSE + conf_bool(WORKAROUND_FUSE) +#endif +#ifdef CONFIG_AUFS_HIN_OR_FUSE + conf_bool(HIN_OR_FUSE) +#endif +#ifdef CONFIG_AUFS_STAT + conf_bool(STAT) +#endif +#ifdef CONFIG_AUFS_DEBUG + conf_bool(DEBUG) +#endif +#ifdef CONFIG_AUFS_MAGIC_SYSRQ + conf_bool(MAGIC_SYSRQ) +#endif +#ifdef CONFIG_AUFS_COMPAT + conf_bool(COMPAT) +#endif +#ifdef CONFIG_AUFS_UNIONFS22_PATCH + conf_bool(UNIONFS22_PATCH) +#endif +#ifdef CONFIG_AUFS_UNIONFS23_PATCH + conf_bool(UNIONFS23_PATCH) +#endif + ; +#undef conf_bool + + char *p = buf; + const char *end = buf + PAGE_SIZE; + + p += snprintf(p, end - p, "%s", opt); +#ifdef DbgUdbaRace + if (p < end) + p += snprintf(p, end - p, "DbgUdbaRace=%d\n", DbgUdbaRace); +#endif + if (p < end) + return p - buf; + else + return -EFBIG; +} + +static struct kobj_attribute au_config_attr = __ATTR_RO(config); +#endif + +#ifdef CONFIG_AUFS_STAT +static ssize_t stat_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + char *p = buf; + const char *end = buf + PAGE_SIZE; + int i; + + p += snprintf(p, end - p, "wkq max_busy:"); + for (i = 0; p < end && i < aufs_nwkq; i++) + p += snprintf(p, end - p, " %u", au_wkq[i].max_busy); + if (p < end) + p += snprintf(p, end - p, ", %u(generic)\n", + au_wkq[aufs_nwkq].max_busy); + + if (p < end) + return p - buf; + else + return -EFBIG; +} + +static struct kobj_attribute au_stat_attr = __ATTR_RO(stat); +#endif + +#ifdef CONFIG_AUFS_DEBUG +static ssize_t debug_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", au_debug_test()); +} + +static ssize_t debug_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t sz) +{ + LKTRTrace("%.*s\n", (unsigned int)sz, buf); + + if (unlikely(!sz || (*buf != '0' && *buf != '1'))) + return -EOPNOTSUPP; + + if (*buf == '0') + au_debug_off(); + else if (*buf == '1') + au_debug_on(); + return sz; +} + +static struct kobj_attribute au_debug_attr = __ATTR(debug, S_IRUGO | S_IWUSR, + debug_show, debug_store); +#endif + +static struct attribute *au_attr[] = { +#ifdef CONFIG_AUFS_LOCAL + &au_config_attr.attr, +#endif +#ifdef CONFIG_AUFS_STAT + &au_stat_attr.attr, +#endif +#ifdef CONFIG_AUFS_DEBUG + &au_debug_attr.attr, +#endif + NULL, /* need to NULL terminate the list of attributes */ +}; + +static struct attribute_group au_attr_group_body = { + .attrs = au_attr +}; + +struct attribute_group *au_attr_group = &au_attr_group_body; + +/* ---------------------------------------------------------------------- */ + +/* + * they are copied from linux/lib/kobject.c, + * and will be exported in the future. + */ +static ssize_t au_attr_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + struct kobj_attribute *kattr; + ssize_t ret = -EIO; + + kattr = container_of(attr, struct kobj_attribute, attr); + if (kattr->show) + ret = kattr->show(kobj, kattr, buf); + return ret; +} + +#ifdef CONFIG_AUFS_DEBUG +static ssize_t au_attr_store(struct kobject *kobj, struct attribute *attr, + const char *buf, size_t count) +{ + struct kobj_attribute *kattr; + ssize_t ret = -EIO; + + kattr = container_of(attr, struct kobj_attribute, attr); + if (kattr->store) + ret = kattr->store(kobj, kattr, buf, count); + return ret; +} +#endif + +static struct sysfs_ops sysaufs_ops = { + .show = au_attr_show, +#ifdef CONFIG_AUFS_DEBUG + .store = au_attr_store +#endif +}; + +static struct kobj_type au_ktype_body = { + .sysfs_ops = &sysaufs_ops +}; +struct kobj_type *au_ktype = &au_ktype_body; + +/* ---------------------------------------------------------------------- */ + +static int sysaufs_sbi_xi(struct seq_file *seq, struct file *xf, int dlgt, + int print_path) +{ + int err; + struct kstat st; + struct path path; + + err = vfsub_getattr(xf->f_vfsmnt, xf->f_dentry, &st, dlgt); + if (!err) { + seq_printf(seq, "%llux%lu %lld", + st.blocks, st.blksize, (long long)st.size); + if (unlikely(print_path)) { + path.dentry = xf->f_dentry; + path.mnt = xf->f_vfsmnt; + seq_putc(seq, ' '); + seq_path(seq, &path, au_esc_chars); + } + seq_putc(seq, '\n'); + } else + seq_printf(seq, "err %d\n", err); + + AuTraceErr(err); + return err; +} + +int sysaufs_sbi_xino(struct seq_file *seq, struct super_block *sb) +{ + int err; + unsigned int mnt_flags; + aufs_bindex_t bend, bindex; + unsigned char dlgt, xinodir; + struct kstat st; + struct path path; + struct au_sbinfo *sbinfo; + struct file *xf; + + AuTraceEnter(); + + sbinfo = au_sbi(sb); + mnt_flags = au_mntflags(sb); + xinodir = !!au_opt_test(mnt_flags, XINODIR); + if (unlikely(!au_opt_test_xino(mnt_flags))) { +#ifdef CONFIG_AUFS_DEBUG + AuDebugOn(sbinfo->si_xib); + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) + AuDebugOn(au_sbr(sb, bindex)->br_xino.xi_file); +#endif + err = 0; + goto out; /* success */ + } + + dlgt = !!au_test_dlgt(mnt_flags); + err = sysaufs_sbi_xi(seq, sbinfo->si_xib, dlgt, xinodir); + + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) { + xf = au_sbr(sb, bindex)->br_xino.xi_file; + if (!xf) + continue; + seq_printf(seq, "%d: ", bindex); + err = vfsub_getattr(xf->f_vfsmnt, xf->f_dentry, &st, dlgt); + if (!err) { + seq_printf(seq, "%ld, %llux%lu %lld", + (long)file_count(xf), st.blocks, st.blksize, + (long long)st.size); + if (unlikely(xinodir)) { + path.dentry = xf->f_dentry; + path.mnt = xf->f_vfsmnt; + seq_putc(seq, ' '); + seq_path(seq, &path, au_esc_chars); + } + seq_putc(seq, '\n'); + } else + seq_printf(seq, "err %d\n", err); + } + + out: + AuTraceErr(err); + return err; +} + +#ifdef CONFIG_AUFS_EXPORT +int sysaufs_sbi_xigen(struct seq_file *seq, struct super_block *sb) +{ + int err; + unsigned int mnt_flags; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + + err = 0; + sbinfo = au_sbi(sb); + mnt_flags = au_mntflags(sb); + if (au_opt_test_xino(mnt_flags)) + err = sysaufs_sbi_xi(seq, sbinfo->si_xigen, + !!au_opt_test(mnt_flags, DLGT), + !!au_opt_test(mnt_flags, XINODIR)); + + AuTraceErr(err); + return err; +} +#endif + +/* + * the lifetime of branch is independent from the entry under sysfs. + * sysfs handles the lifetime of the entry, and never call ->show() after it is + * unlinked. + */ +#define SysaufsBr_PREFIX "br" +static int sysaufs_sbi_br(struct seq_file *seq, struct super_block *sb, + aufs_bindex_t bindex) +{ + int err; + struct dentry *root; + struct au_branch *br; + struct path path; + + LKTRTrace("b%d\n", bindex); + + err = -ENOENT; + if (unlikely(au_sbend(sb) < bindex)) + goto out; + + err = 0; + root = sb->s_root; + di_read_lock_parent(root, !AuLock_IR); + br = au_sbr(sb, bindex); + path.mnt = br->br_mnt; + path.dentry = au_h_dptr(root, bindex); + seq_path(seq, &path, au_esc_chars); + di_read_unlock(root, !AuLock_IR); + seq_printf(seq, "=%s\n", au_optstr_br_perm(br->br_perm)); + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static struct seq_file *au_seq(char *p, ssize_t len) +{ + struct seq_file *seq; + + seq = kzalloc(sizeof(*seq), GFP_NOFS); + if (seq) { + /* todo: necessary? */ + /* mutex_init(&seq.lock); */ + seq->buf = p; + seq->size = len; + return seq; /* success */ + } + + seq = ERR_PTR(-ENOMEM); + AuTraceErrPtr(seq); + return seq; +} + +/* todo: file size may exceed PAGE_SIZE */ +ssize_t sysaufs_sbi_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + ssize_t err; + struct au_sbinfo *sbinfo; + struct super_block *sb; + struct seq_file *seq; + char *name; + struct attribute **cattr; + + LKTRTrace("%s/%s\n", kobject_name(kobj), attr->name); + + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + sb = sbinfo->si_sb; + si_noflush_read_lock(sb); + + seq = au_seq(buf, PAGE_SIZE); + err = PTR_ERR(seq); + if (IS_ERR(seq)) + goto out; + + name = (void *)attr->name; + cattr = au_sbi_attrs; + while (*cattr) { + if (!strcmp(name, (*cattr)->name)) { + err = container_of(*cattr, struct au_sbi_attr, attr) + ->show(seq, sb); + goto out_seq; + } + cattr++; + } + + if (!strncmp(name, SysaufsBr_PREFIX, sizeof(SysaufsBr_PREFIX) - 1)) { + name += sizeof(SysaufsBr_PREFIX) - 1; + err = sysaufs_sbi_br(seq, sb, simple_strtol(name, NULL, 10)); + goto out_seq; + } + BUG(); + + out_seq: + if (!err) { + err = seq->count; + /* sysfs limit */ + if (unlikely(err == PAGE_SIZE)) + err = -EFBIG; + } + kfree(seq); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +void sysaufs_br_init(struct au_branch *br) +{ + br->br_attr.name = br->br_name; + br->br_attr.mode = S_IRUGO; + br->br_attr.owner = THIS_MODULE; +} + +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) +{ + struct au_sbinfo *sbinfo; + aufs_bindex_t bend; + + LKTRTrace("b%d\n", bindex); + + if (!sysaufs_brs) + return; + + sbinfo = au_sbi(sb); + bend = au_sbend(sb); + for (; bindex <= bend; bindex++) + sysfs_remove_file(&sbinfo->si_kobj, + &au_sbr(sb, bindex)->br_attr); +} + +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) +{ + int err; + struct kobject *kobj; + aufs_bindex_t bend; + struct au_branch *br; + + LKTRTrace("b%d\n", bindex); + + if (!sysaufs_brs) + return; + + kobj = &au_sbi(sb)->si_kobj; + bend = au_sbend(sb); + for (; bindex <= bend; bindex++) { + br = au_sbr(sb, bindex); + snprintf(br->br_name, sizeof(br->br_name), + SysaufsBr_PREFIX "%d", bindex); + err = sysfs_create_file(kobj, &br->br_attr); + if (unlikely(err)) + AuWarn("failed %s under sysfs(%d)\n", br->br_name, err); + } +} --- linux-2.6.28.orig/ubuntu/aufs/file.h +++ linux-2.6.28/ubuntu/aufs/file.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * file operations + * + * $Id: file.h,v 1.5 2008/06/30 03:53:43 sfjro Exp $ + */ + +#ifndef __AUFS_FILE_H__ +#define __AUFS_FILE_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include "dentry.h" +#include "misc.h" +#include "super.h" + +/* ---------------------------------------------------------------------- */ + +struct au_branch; +struct au_hfile { + struct file *hf_file; + struct au_branch *hf_br; +}; + +struct au_vdir; +struct au_finfo { + atomic_t fi_generation; + + struct au_rwsem fi_rwsem; + struct au_hfile *fi_hfile; + aufs_bindex_t fi_bstart, fi_bend; + + union { + struct vm_operations_struct *fi_h_vm_ops; + struct au_vdir *fi_vdir_cache; + }; +}; + +/* ---------------------------------------------------------------------- */ + +/* file.c */ +extern struct address_space_operations aufs_aop; +unsigned int au_file_roflags(unsigned int flags); +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, + struct file *file); +int au_do_open(struct inode *inode, struct file *file, + int (*open)(struct file *file, int flags)); +int au_reopen_nondir(struct file *file); +struct au_pin; +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin); +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), + int wlock, int locked); + +/* f_op.c */ +extern struct file_operations aufs_file_fop; +int aufs_flush(struct file *file, fl_owner_t id); + +/* finfo.c */ +struct au_finfo *au_fi(struct file *file); +struct au_branch *au_fbr(struct file *file, aufs_bindex_t bindex); +struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex); + +void au_hfput(struct au_hfile *hf); +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, + struct file *h_file); + +void au_finfo_fin(struct file *file); +int au_finfo_init(struct file *file); + +#ifdef CONFIG_AUFS_ROBR +/* robr.c */ +struct file *au_robr_safe_file(struct vm_area_struct *vma); +void au_robr_reset_file(struct vm_area_struct *vma, struct file *file); +#else +static inline struct file *au_robr_safe_file(struct vm_area_struct *vma) +{ + struct file *file; + + file = vma->vm_file; + if (file->private_data && au_test_aufs(file->f_dentry->d_sb)) + return file; + return NULL; +} + +static inline +void au_robr_reset_file(struct vm_area_struct *vma, struct file *file) +{ + vma->vm_file = file; + /* smp_mb(); */ /* flush vm_file */ +} +#endif /* CONFIG_AUFS_ROBR */ + +/* ---------------------------------------------------------------------- */ + +/* todo: memory barrier? */ +static inline au_gen_t au_figen(struct file *f) +{ + return atomic_read(&au_fi(f)->fi_generation); +} + +static inline int au_test_mmapped(struct file *f) +{ + return !!(au_fi(f)->fi_h_vm_ops); +} + +static inline int au_test_aufs_file(struct file *f) +{ + return !(f->f_dentry->d_inode->i_mode + & (S_IFCHR | S_IFBLK | S_IFIFO | S_IFSOCK)); +} + +/* ---------------------------------------------------------------------- */ + +#if !defined(CONFIG_AUFS_MODULE) || defined(CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH) +int au_store_fmode_exec(struct nameidata *nd, struct inode *inode); + +static inline int au_deny_write_access(struct file *h_file) +{ + LKTRTrace("%.*s\n", AuDLNPair(h_file->f_dentry)); + return deny_write_access(h_file); +} + +static inline void au_allow_write_access(struct file *h_file) +{ + allow_write_access(h_file); +} + +#else + +static inline int au_store_fmode_exec(struct nameidata *nd, struct inode *inode) +{ + /* nothing */ + return 0; +} + +static inline int au_deny_write_access(struct file *h_file) +{ + /* nothing */ + return 0; +} + +static inline void au_allow_write_access(struct file *h_file) +{ + /* nothing */ +} +#endif /* CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH */ + +/* ---------------------------------------------------------------------- */ + +/* + * fi_read_lock, fi_write_lock, + * fi_read_unlock, fi_write_unlock, fi_downgrade_lock + */ +AuSimpleRwsemFuncs(fi, struct file *f, au_fi(f)->fi_rwsem); + +/* to debug easier, do not make them inlined functions */ +#define FiMustReadLock(f) do { \ + SiMustAnyLock((f)->f_dentry->d_sb); \ + AuRwMustReadLock(&au_fi(f)->fi_rwsem); \ +} while (0) + +#define FiMustWriteLock(f) do { \ + SiMustAnyLock((f)->f_dentry->d_sb); \ + AuRwMustWriteLock(&au_fi(f)->fi_rwsem); \ +} while (0) + +#define FiMustAnyLock(f) do { \ + SiMustAnyLock((f)->f_dentry->d_sb); \ + AuRwMustAnyLock(&au_fi(f)->fi_rwsem); \ +} while (0) + +#define FiMustNoWaiters(f) AuRwMustNoWaiters(&au_fi(f)->fi_rwsem) + +/* ---------------------------------------------------------------------- */ + +/* todo: hard/soft set? */ +static inline aufs_bindex_t au_fbstart(struct file *file) +{ + FiMustAnyLock(file); + return au_fi(file)->fi_bstart; +} + +static inline aufs_bindex_t au_fbend(struct file *file) +{ + FiMustAnyLock(file); + return au_fi(file)->fi_bend; +} + +static inline struct au_vdir *au_fvdir_cache(struct file *file) +{ + FiMustAnyLock(file); + return au_fi(file)->fi_vdir_cache; +} + +static inline void au_set_fbstart(struct file *file, aufs_bindex_t bindex) +{ + FiMustWriteLock(file); + AuDebugOn(au_sbend(file->f_dentry->d_sb) < bindex); + au_fi(file)->fi_bstart = bindex; +} + +static inline void au_set_fbend(struct file *file, aufs_bindex_t bindex) +{ + FiMustWriteLock(file); + AuDebugOn(au_sbend(file->f_dentry->d_sb) < bindex + || bindex < au_fbstart(file)); + au_fi(file)->fi_bend = bindex; +} + +static inline void au_set_fvdir_cache(struct file *file, + struct au_vdir *vdir_cache) +{ + FiMustWriteLock(file); + AuDebugOn(!S_ISDIR(file->f_dentry->d_inode->i_mode) + || (au_fi(file)->fi_vdir_cache && vdir_cache)); + au_fi(file)->fi_vdir_cache = vdir_cache; +} + +static inline void au_update_figen(struct file *file) +{ + atomic_set(&au_fi(file)->fi_generation, au_digen(file->f_dentry)); + /* smp_mb(); */ /* atomic_set */ +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_FILE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/plink.c +++ linux-2.6.28/ubuntu/aufs/plink.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * pseudo-link + * + * $Id: plink.c,v 1.9 2008/09/01 02:55:35 sfjro Exp $ + */ + +#include "aufs.h" + +struct pseudo_link { + struct list_head list; + struct inode *inode; +}; + +#ifdef CONFIG_AUFS_DEBUG +void au_plink_list(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink; + + AuTraceEnter(); + SiMustAnyLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + plink_list = &sbinfo->si_plink; + spin_lock(&sbinfo->si_plink_lock); + list_for_each_entry(plink, plink_list, list) + AuDbg("%lu\n", plink->inode->i_ino); + spin_unlock(&sbinfo->si_plink_lock); +} +#endif + +int au_plink_test(struct super_block *sb, struct inode *inode) +{ + int found; + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink; + + LKTRTrace("i%lu\n", inode->i_ino); + SiMustAnyLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + found = 0; + plink_list = &sbinfo->si_plink; + spin_lock(&sbinfo->si_plink_lock); + list_for_each_entry(plink, plink_list, list) + if (plink->inode == inode) { + found = 1; + break; + } + spin_unlock(&sbinfo->si_plink_lock); + return found; +} + +/* 20 is max digits length of ulong 64 */ +#define PLINK_NAME_LEN ((20 + 1) * 2) + +static int plink_name(char *name, int len, struct inode *inode, + aufs_bindex_t bindex) +{ + int rlen; + struct inode *h_inode; + + LKTRTrace("i%lu, b%d\n", inode->i_ino, bindex); + AuDebugOn(len != PLINK_NAME_LEN); + h_inode = au_h_iptr(inode, bindex); + AuDebugOn(!h_inode); + rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino); + AuDebugOn(rlen >= len); + return rlen; +} + +struct dentry *au_plink_lkup(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode) +{ + struct dentry *h_dentry, *h_parent; + struct au_branch *br; + struct au_wbr *wbr; + struct inode *h_dir; + char tgtname[PLINK_NAME_LEN]; + int len; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("b%d, i%lu\n", bindex, inode->i_ino); + br = au_sbr(sb, bindex); + wbr = br->br_wbr; + AuDebugOn(!wbr); + h_parent = wbr->wbr_plink; + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + + len = plink_name(tgtname, sizeof(tgtname), inode, bindex); + + /* always superio. */ + ndx.nfsmnt = au_do_nfsmnt(br->br_mnt); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); + h_dentry = au_sio_lkup_one(tgtname, h_parent, len, &ndx); + mutex_unlock(&h_dir->i_mutex); + return h_dentry; +} + +static int do_whplink(char *tgt, int len, struct dentry *h_parent, + struct dentry *h_dentry, struct vfsmount *nfsmnt, + struct super_block *sb) +{ + int err, dlgt; + struct dentry *h_tgt; + struct inode *h_dir; + struct vfsub_args vargs; + struct au_ndx ndx = { + .nfsmnt = nfsmnt, + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + AuTraceEnter(); + + dlgt = !!au_test_dlgt(au_mntflags(sb)); + if (unlikely(dlgt)) + au_fset_ndx(ndx.flags, DLGT); + h_tgt = au_lkup_one(tgt, h_parent, len, &ndx); + err = PTR_ERR(h_tgt); + if (IS_ERR(h_tgt)) + goto out; + + err = 0; + vfsub_args_init(&vargs, NULL, dlgt, 0); + /* wh.plink dir is not monitored */ + h_dir = h_parent->d_inode; + if (unlikely(h_tgt->d_inode && h_tgt->d_inode != h_dentry->d_inode)) + err = vfsub_unlink(h_dir, h_tgt, &vargs); + if (!err && !h_tgt->d_inode) { + err = vfsub_link(h_dentry, h_dir, h_tgt, &vargs); + /* todo: unnecessary? */ + /* inc_nlink(inode); */ + } + dput(h_tgt); + + out: + AuTraceErr(err); + return err; +} + +struct do_whplink_args { + int *errp; + char *tgt; + int len; + struct dentry *h_parent; + struct dentry *h_dentry; + struct vfsmount *nfsmnt; + struct super_block *sb; +}; + +static void call_do_whplink(void *args) +{ + struct do_whplink_args *a = args; + *a->errp = do_whplink(a->tgt, a->len, a->h_parent, a->h_dentry, + a->nfsmnt, a->sb); +} + +static int whplink(struct dentry *h_dentry, struct inode *inode, + aufs_bindex_t bindex, struct super_block *sb) +{ + int err, len, wkq_err; + struct au_branch *br; + struct au_wbr *wbr; + struct dentry *h_parent; + struct inode *h_dir; + char tgtname[PLINK_NAME_LEN]; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + br = au_sbr(inode->i_sb, bindex); + wbr = br->br_wbr; + AuDebugOn(!wbr); + h_parent = wbr->wbr_plink; + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + + len = plink_name(tgtname, sizeof(tgtname), inode, bindex); + + /* always superio. */ + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2); + if (!au_test_wkq(current)) { + struct do_whplink_args args = { + .errp = &err, + .tgt = tgtname, + .len = len, + .h_parent = h_parent, + .h_dentry = h_dentry, + .nfsmnt = au_do_nfsmnt(br->br_mnt), + .sb = sb + }; + wkq_err = au_wkq_wait(call_do_whplink, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } else + err = do_whplink(tgtname, len, h_parent, h_dentry, + au_do_nfsmnt(br->br_mnt), sb); + mutex_unlock(&h_dir->i_mutex); + + AuTraceErr(err); + return err; +} + +void au_plink_append(struct super_block *sb, struct inode *inode, + struct dentry *h_dentry, aufs_bindex_t bindex) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink; + int found, err, cnt; + + LKTRTrace("i%lu\n", inode->i_ino); + SiMustAnyLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + cnt = 0; + found = 0; + plink_list = &sbinfo->si_plink; + spin_lock(&sbinfo->si_plink_lock); + list_for_each_entry(plink, plink_list, list) { + cnt++; + if (plink->inode == inode) { + found = 1; + break; + } + } + + err = 0; + if (!found) { + plink = kmalloc(sizeof(*plink), GFP_ATOMIC); + if (plink) { + plink->inode = au_igrab(inode); + list_add(&plink->list, plink_list); + cnt++; + } else + err = -ENOMEM; + } + spin_unlock(&sbinfo->si_plink_lock); + +#if 0 /* todo: test here */ + if (found) + return; /* success */ +#endif + + if (!err) + err = whplink(h_dentry, inode, bindex, sb); + + if (unlikely(cnt > AUFS_PLINK_WARN)) + AuWarn1("unexpectedly many pseudo links, %d\n", cnt); + if (unlikely(err)) + AuWarn("err %d, damaged pseudo link. ignored.\n", err); +} + +static void do_put_plink(struct pseudo_link *plink, int do_del) +{ + AuTraceEnter(); + + iput(plink->inode); + if (do_del) + list_del(&plink->list); + kfree(plink); +} + +void au_plink_put(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink, *tmp; + + AuTraceEnter(); + SiMustWriteLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + plink_list = &sbinfo->si_plink; + /* spin_lock(&sbinfo->si_plink_lock); */ + list_for_each_entry_safe(plink, tmp, plink_list, list) + do_put_plink(plink, 0); + INIT_LIST_HEAD(plink_list); + /* spin_unlock(&sbinfo->si_plink_lock); */ +} + +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id) +{ + struct au_sbinfo *sbinfo; + struct list_head *plink_list; + struct pseudo_link *plink, *tmp; + struct inode *inode; + aufs_bindex_t bstart, bend, bindex; + int do_put; + + AuTraceEnter(); + SiMustWriteLock(sb); + sbinfo = au_sbi(sb); + AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK)); + + plink_list = &sbinfo->si_plink; + /* spin_lock(&sbinfo->si_plink_lock); */ + list_for_each_entry_safe(plink, tmp, plink_list, list) { + do_put = 0; + inode = au_igrab(plink->inode); + ii_write_lock_child(inode); + bstart = au_ibstart(inode); + bend = au_ibend(inode); + if (bstart >= 0) { + for (bindex = bstart; bindex <= bend; bindex++) { + if (!au_h_iptr(inode, bindex) + || au_ii_br_id(inode, bindex) != br_id) + continue; + au_set_h_iptr(inode, bindex, NULL, 0); + do_put = 1; + break; + } + } else + do_put_plink(plink, 1); + + if (do_put) { + for (bindex = bstart; bindex <= bend; bindex++) + if (au_h_iptr(inode, bindex)) { + do_put = 0; + break; + } + if (do_put) + do_put_plink(plink, 1); + } + ii_write_unlock(inode); + iput(inode); + } + /* spin_unlock(&sbinfo->si_plink_lock); */ +} --- linux-2.6.28.orig/ubuntu/aufs/export.c +++ linux-2.6.28/ubuntu/aufs/export.c @@ -0,0 +1,797 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * export via nfs + * + * $Id: export.c,v 1.15 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include +#include +#include +#include "aufs.h" + +union conv { +#ifdef CONFIG_AUFS_INO_T_64 + __u32 a[2]; +#else + __u32 a[1]; +#endif + ino_t ino; +}; + +static ino_t decode_ino(__u32 *a) +{ + union conv u; + + BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a)); + u.a[0] = a[0]; +#ifdef CONFIG_AUFS_INO_T_64 + u.a[1] = a[1]; +#endif + return u.ino; +} + +static void encode_ino(__u32 *a, ino_t ino) +{ + union conv u; + + u.ino = ino; + a[0] = u.a[0]; +#ifdef CONFIG_AUFS_INO_T_64 + a[1] = u.a[1]; +#endif +} + +/* NFS file handle */ +enum { + Fh_br_id, + Fh_sigen, +#ifdef CONFIG_AUFS_INO_T_64 + /* support 64bit inode number */ + Fh_ino1, + Fh_ino2, + Fh_dir_ino1, + Fh_dir_ino2, +#else + Fh_ino1, + Fh_dir_ino1, +#endif + Fh_igen, + Fh_h_type, + Fh_tail, + + Fh_ino = Fh_ino1, + Fh_dir_ino = Fh_dir_ino1 +}; + +static int au_test_anon(struct dentry *dentry) +{ + return !!(dentry->d_flags & DCACHE_DISCONNECTED); +} + +/* ---------------------------------------------------------------------- */ +/* inode generation external table */ + +int au_xigen_inc(struct inode *inode) +{ + int err; + loff_t pos; + ssize_t sz; + __u32 igen; + struct super_block *sb; + struct au_sbinfo *sbinfo; + + LKTRTrace("i%lu\n", (unsigned long)inode->i_ino); + + err = 0; + sb = inode->i_sb; + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + goto out; + + pos = inode->i_ino; + pos *= sizeof(igen); + igen = inode->i_generation + 1; + sbinfo = au_sbi(sb); + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen, + sizeof(igen), &pos); + if (sz == sizeof(igen)) + goto out; /* success */ + + err = sz; + if (unlikely(sz >= 0)) { + err = -EIO; + AuIOErr("xigen error (%ld)\n", (long)sz); + } + + out: + AuTraceErr(err); + return err; +} + +int au_xigen_new(struct inode *inode) +{ + int err; + loff_t pos; + ssize_t sz; + struct super_block *sb; + struct au_sbinfo *sbinfo; + struct file *file; + + LKTRTrace("i%lu\n", (unsigned long)inode->i_ino); + + err = 0; + sb = inode->i_sb; + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + goto out; + + err = -EFBIG; + pos = inode->i_ino; + if (unlikely(Au_LOFF_MAX / sizeof(inode->i_generation) - 1 < pos)) { + AuIOErr1("too large i%lld\n", pos); + goto out; + } + pos *= sizeof(inode->i_generation); + + err = 0; + sbinfo = au_sbi(sb); + file = sbinfo->si_xigen; + /* todo: dirty, at mount time */ + if (unlikely(!file)) { + if (inode->i_ino == AUFS_ROOT_INO) + goto out; + else + BUG(); + } + + if (i_size_read(file->f_dentry->d_inode) + < pos + sizeof(inode->i_generation)) { + spin_lock(&sbinfo->si_xigen_lock); + inode->i_generation = sbinfo->si_xigen_next++; + spin_unlock(&sbinfo->si_xigen_lock); + sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation, + sizeof(inode->i_generation), &pos); + } else + sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation, + sizeof(inode->i_generation), &pos); + if (sz == sizeof(inode->i_generation)) + goto out; /* success */ + + err = sz; + if (unlikely(sz >= 0)) { + err = -EIO; + AuIOErr("xigen error (%ld)\n", (long)sz); + } + + out: + AuTraceErr(err); + return err; +} + +int au_xigen_set(struct super_block *sb, struct file *base) +{ + int err; + struct au_sbinfo *sbinfo; + struct file *file; + + LKTRTrace("%.*s\n", AuDLNPair(base->f_dentry)); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + file = au_xino_create2(sb, base, sbinfo->si_xigen); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + err = 0; + if (sbinfo->si_xigen) + fput(sbinfo->si_xigen); + sbinfo->si_xigen = file; + + out: + AuTraceErr(err); + return err; +} + +void au_xigen_clr(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + sbinfo = au_sbi(sb); + if (sbinfo->si_xigen) { + fput(sbinfo->si_xigen); + sbinfo->si_xigen = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino, + ino_t dir_ino) +{ + struct dentry *dentry, *d; + struct inode *inode; + + LKTRTrace("i%lu, diri%lu\n", + (unsigned long)ino, (unsigned long)dir_ino); + + dentry = NULL; + inode = ilookup(sb, ino); + if (unlikely(!inode)) + goto out; + + dentry = ERR_PTR(-ESTALE); + if (unlikely(is_bad_inode(inode) || IS_DEADDIR(inode))) + goto out_iput; + AuDbgInode(inode); + + dentry = NULL; + if (!dir_ino || S_ISDIR(inode->i_mode)) + dentry = d_find_alias(inode); + else { + spin_lock(&dcache_lock); + list_for_each_entry(d, &inode->i_dentry, d_alias) + if (!au_test_anon(d) + && d->d_parent->d_inode->i_ino == dir_ino) { + dentry = dget_locked(d); + break; + } + spin_unlock(&dcache_lock); + } + AuDbgDentry(dentry); + + out_iput: + iput(inode); + out: + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +/* todo: dirty? */ +/* + * when you mntput() for the return value of this function, + * you have to store it to your local var. + * ie. never mntput si_mntcache directly. + */ +static struct vfsmount *au_do_mnt_get(struct super_block *sb) +{ + struct mnt_namespace *ns; + struct vfsmount *pos, *mnt; + + AuTraceEnter(); + + /* vfsmount_lock is not exported */ + /* no get/put ?? */ + AuDebugOn(!current->nsproxy); + ns = current->nsproxy->mnt_ns; + AuDebugOn(!ns); + mnt = NULL; + /* the order (reverse) will not be a problem */ + list_for_each_entry(pos, &ns->list, mnt_list) + if (pos->mnt_sb == sb) { + mnt = pos; + break; + } + AuDebugOn(!mnt); + + return mntget(mnt); +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static struct vfsmount *au_mnt_get(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + struct vfsmount *mnt; + + sbinfo = au_sbi(sb); + spin_lock(&sbinfo->si_mntcache_lock); + if (sbinfo->si_mntcache) + mnt = mntget(sbinfo->si_mntcache); + else { + sbinfo->si_mntcache = au_do_mnt_get(sb); + mnt = sbinfo->si_mntcache; + } + spin_unlock(&sbinfo->si_mntcache_lock); + return mnt; +} +#else +static struct vfsmount *au_mnt_get(struct super_block *sb) +{ + return au_do_mnt_get(sb); +} +#endif + +struct find_name_by_ino { + int called, found; + ino_t ino; + char *name; + int namelen; +}; + +static int +find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset, + u64 ino, unsigned int d_type) +{ + struct find_name_by_ino *a = arg; + + a->called++; + if (a->ino != ino) + return 0; + + memcpy(a->name, name, namelen); + a->namelen = namelen; + a->found = 1; + return 1; +} + +static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino) +{ + struct dentry *dentry, *parent; + struct file *file; + struct inode *dir, *inode; + struct find_name_by_ino arg; + int err; + + parent = path->dentry; + LKTRTrace("%.*s, i%lu\n", AuDLNPair(parent), (unsigned long )ino); + + path_get(path); + file = dentry_open(parent, path->mnt, au_dir_roflags); + dentry = (void *)file; + if (IS_ERR(file)) + goto out; + + dentry = ERR_PTR(-ENOMEM); + arg.name = __getname(); + if (unlikely(!arg.name)) + goto out_file; + arg.ino = ino; + arg.found = 0; + do { + arg.called = 0; + /* smp_mb(); */ + err = vfsub_readdir(file, find_name_by_ino, &arg, /*dlgt*/0); + } while (!err && !arg.found && arg.called); + dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_name; + dentry = ERR_PTR(-ENOENT); + if (!arg.found) + goto out_name; + + /* do not call au_lkup_one(), nor dlgt */ + dir = parent->d_inode; + mutex_lock(&dir->i_mutex); + dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen); + mutex_unlock(&dir->i_mutex); + AuTraceErrPtr(dentry); + if (IS_ERR(dentry)) + goto out_name; + AuDebugOn(au_test_anon(dentry)); + inode = dentry->d_inode; + if (unlikely(!inode)) { + dput(dentry); + dentry = ERR_PTR(-ENOENT); + } + + out_name: + __putname(arg.name); + out_file: + fput(file); + out: + AuTraceErrPtr(dentry); + return dentry; +} + +static /* noinline_for_stack */ +struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino, + ino_t dir_ino) +{ + struct dentry *dentry, *parent; + struct path path; + + LKTRTrace("i%lu, diri%lu\n", + (unsigned long)ino, (unsigned long)dir_ino); + + parent = sb->s_root; + if (dir_ino != AUFS_ROOT_INO) { + parent = decode_by_ino(sb, dir_ino, 0); + AuDbgDentry(parent); + dentry = parent; + if (unlikely(!parent)) + goto out; + if (IS_ERR(parent)) + goto out; + AuDebugOn(au_test_anon(parent)); + } else + dget(parent); + + path.dentry = parent; + path.mnt = au_mnt_get(sb); + dentry = au_lkup_by_ino(&path, ino); + path_put(&path); + + out: + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +static int h_acceptable(void *expv, struct dentry *dentry) +{ + return 1; +} + +static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath, + char *buf, int len, struct super_block *sb) +{ + char *p; + int n; + struct path path; + + AuTraceEnter(); + + p = d_path(h_rootpath, buf, len); + if (IS_ERR(p)) + goto out; + n = strlen(p); + + path.mnt = h_rootpath->mnt; + path.dentry = h_parent; + p = d_path(&path, buf, len); + if (IS_ERR(p)) + goto out; + LKTRTrace("%s\n", p); + if (n != 1) + p += n; + LKTRTrace("%p, %s, %ld\n", + p, p, (long)(p - buf)); + + path.mnt = au_mnt_get(sb); + path.dentry = sb->s_root; + p = d_path(&path, buf, len - strlen(p)); + mntput(path.mnt); + if (IS_ERR(p)) + goto out; + if (n != 1) + p[strlen(p)] = '/'; + LKTRTrace("%s\n", p); + + out: + AuTraceErrPtr(p); + return p; +} + +static noinline_for_stack +struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex, + ino_t ino, __u32 *fh, int fh_len) +{ + struct dentry *dentry, *h_parent, *root; + struct super_block *h_sb; + char *pathname, *p; + struct vfsmount *h_mnt; + struct au_branch *br; + int err; + struct nameidata nd; + + LKTRTrace("b%d\n", bindex); + SiMustAnyLock(sb); + + br = au_sbr(sb, bindex); + /* au_br_get(br); */ + h_mnt = br->br_mnt; + h_sb = h_mnt->mnt_sb; + LKTRTrace("%s, h_decode_fh\n", au_sbtype(h_sb)); + /* in linux-2.6.24, it takes struct fid * as file handle */ + /* todo: call lower fh_to_dentry()? fh_to_parent()? */ + h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail), + fh_len - Fh_tail, fh[Fh_h_type], + h_acceptable, /*context*/NULL); + dentry = h_parent; + if (unlikely(!h_parent || IS_ERR(h_parent))) { + AuWarn1("%s decode_fh failed, %ld\n", + au_sbtype(h_sb), PTR_ERR(h_parent)); + goto out; + } + dentry = NULL; + if (unlikely(au_test_anon(h_parent))) { + AuWarn1("%s decode_fh returned a disconnected dentry\n", + au_sbtype(h_sb)); + goto out_h_parent; + } + + dentry = ERR_PTR(-ENOMEM); + pathname = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!pathname)) + goto out_h_parent; + + root = sb->s_root; + nd.path.mnt = h_mnt; + di_read_lock_parent(root, !AuLock_IR); + nd.path.dentry = au_h_dptr(root, bindex); + di_read_unlock(root, !AuLock_IR); + p = au_build_path(h_parent, &nd.path, pathname, PAGE_SIZE, sb); + dentry = (void *)p; + if (IS_ERR(p)) + goto out_pathname; + + LKTRTrace("%s\n", p); + err = vfsub_path_lookup(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &nd); + dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_pathname; + + dentry = ERR_PTR(-ENOENT); + AuDebugOn(au_test_anon(nd.path.dentry)); + if (unlikely(!nd.path.dentry->d_inode)) + goto out_nd; + + if (ino != nd.path.dentry->d_inode->i_ino) + dentry = au_lkup_by_ino(&nd.path, ino); + else + dentry = dget(nd.path.dentry); + + out_nd: + path_put(&nd.path); + out_pathname: + free_page((unsigned long)pathname); + out_h_parent: + dput(h_parent); + out: + /* au_br_put(br); */ + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +static struct dentry * +aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, + int fh_type) +{ + struct dentry *dentry; + struct inode *inode; + __u32 *fh = fid->raw; + ino_t ino, dir_ino; + aufs_bindex_t bindex, br_id; + au_gen_t sigen; + + LKTRTrace("%d, fh{br_id %u, sigen %u, i%u, diri%u, g%u}\n", + fh_type, fh[Fh_br_id], fh[Fh_sigen], fh[Fh_ino], + fh[Fh_dir_ino], fh[Fh_igen]); + AuDebugOn(fh_len < Fh_tail); + + si_read_lock(sb, AuLock_FLUSH); + lockdep_off(); + + /* branch id may be wrapped around */ + dentry = ERR_PTR(-ESTALE); + br_id = fh[Fh_br_id]; + sigen = fh[Fh_sigen]; + bindex = au_br_index(sb, br_id); + LKTRTrace("b%d\n", bindex); + if (unlikely(bindex < 0 + || (0 && sigen != au_sigen(sb)) + || (1 && sigen + AUFS_BRANCH_MAX <= au_sigen(sb)) + )) + goto out; + + /* is this inode still cached? */ + ino = decode_ino(fh + Fh_ino); + AuDebugOn(ino == AUFS_ROOT_INO); + dir_ino = decode_ino(fh + Fh_dir_ino); + dentry = decode_by_ino(sb, ino, dir_ino); + if (IS_ERR(dentry)) + goto out; + if (dentry) + goto accept; + + /* is the parent dir cached? */ + dentry = decode_by_dir_ino(sb, ino, dir_ino); + if (IS_ERR(dentry)) + goto out; + if (dentry) + goto accept; + + /* lookup path */ + dentry = decode_by_path(sb, bindex, ino, fh, fh_len); + if (IS_ERR(dentry)) + goto out; + if (unlikely(!dentry)) + goto out; + + accept: + LKTRLabel(accept); + inode = dentry->d_inode; +#if 0 + /* support branch manupilation and udba on nfs server */ + sigen = au_sigen(sb); + if (unlikely(au_digen(dentry) != sigen + || au_iigen(inode) != sigen)) { + int err; + + //lktr_set_pid(current->pid, LktrArrayPid); + //au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS); + di_write_lock_child(dentry); + err = au_reval_dpath(dentry, sigen); + di_write_unlock(dentry); + //lktr_clear_pid(current->pid, LktrArrayPid); + if (unlikely(err < 0)) + goto out_dput; + } +#endif + + if (unlikely(inode->i_generation != fh[Fh_igen])) { + LKTRLabel(stale); + dput(dentry); + dentry = ERR_PTR(-ESTALE); + } + + out: + LKTRLabel(out); + lockdep_on(); + si_read_unlock(sb); + AuTraceErrPtr(dentry); + return dentry; +} + +#if 0 /* reserved for future use */ +/* support subtreecheck option */ +static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid, + int fh_len, int fh_type) +{ + struct dentry *parent; + __u32 *fh = fid->raw; + ino_t dir_ino; + + dir_ino = decode_ino(fh + Fh_dir_ino); + parent = decode_by_ino(sb, dir_ino, 0); + if (IS_ERR(parent)) + goto out; + if (!parent) + parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]), + dir_ino, fh, fh_len); + + out: + AuTraceErrPtr(parent); + return parent; +} +#endif + +/* ---------------------------------------------------------------------- */ + +static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, + int connectable) +{ + int err; + aufs_bindex_t bindex, bend; + struct super_block *sb, *h_sb; + struct inode *inode; + struct dentry *parent, *h_parent; + struct au_branch *br; + + LKTRTrace("%.*s, max %d, conn %d\n", + AuDLNPair(dentry), *max_len, connectable); + AuDebugOn(au_test_anon(dentry)); + + parent = NULL; + err = -ENOSPC; + if (unlikely(*max_len <= Fh_tail)) { + AuWarn1("NFSv2 client (max_len %d)?\n", *max_len); + goto out; + } + + err = FILEID_ROOT; + inode = dentry->d_inode; + AuDebugOn(!inode); + if (inode->i_ino == AUFS_ROOT_INO) + goto out; + + err = -EIO; + h_parent = NULL; + sb = dentry->d_sb; + parent = dget_parent(dentry); + aufs_read_lock(parent, AuLock_FLUSH | AuLock_IR); +#ifdef CONFIG_AUFS_DEBUG + { + unsigned int mnt_flags = au_mntflags(sb); + + if (unlikely(!au_opt_test_xino(mnt_flags))) + AuWarn1("NFS-exporting requires xino\n"); + if (unlikely(0 && !au_opt_test(mnt_flags, UDBA_INOTIFY))) + AuWarn1("udba=inotify is recommended " + "for NFS-exporting\n"); + } +#endif + + bend = au_dbtaildir(parent); + for (bindex = au_dbstart(parent); bindex <= bend; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (h_parent) { + dget(h_parent); + break; + } + } + if (unlikely(!h_parent)) + goto out_unlock; + LKTRTrace("b%d\n", bindex); + + err = -EPERM; + br = au_sbr(sb, bindex); + h_sb = br->br_mnt->mnt_sb; + if (unlikely(!h_sb->s_export_op)) { + AuErr1("%s branch is not exportable\n", au_sbtype(h_sb)); + goto out_dput; + } + + fh[Fh_br_id] = br->br_id; + fh[Fh_sigen] = au_sigen(sb); + encode_ino(fh + Fh_ino, inode->i_ino); + encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino); + fh[Fh_igen] = inode->i_generation; + + *max_len -= Fh_tail; + /* in linux-2.6.24, it takes struct fid * as file handle */ + fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail), + max_len, connectable); + err = fh[Fh_h_type]; + *max_len += Fh_tail; + /* todo: macros? */ + if (err != 255) + err = 99; + else + AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb)); + + out_dput: + dput(h_parent); + out_unlock: + aufs_read_unlock(parent, AuLock_IR); + dput(parent); + out: + AuTraceErr(err); + if (unlikely(err < 0)) + err = 255; + return err; +} + +/* ---------------------------------------------------------------------- */ + +static struct export_operations aufs_export_op = { + .fh_to_dentry = aufs_fh_to_dentry, + //.fh_to_parent = aufs_fh_to_parent, + .encode_fh = aufs_encode_fh +}; + +void au_export_init(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + sb->s_export_op = &aufs_export_op; + sbinfo = au_sbi(sb); + sbinfo->si_xigen = NULL; + spin_lock_init(&sbinfo->si_xigen_lock); + /* todo: meaningless? */ + get_random_bytes(&sbinfo->si_xigen_next, sizeof(sbinfo->si_xigen_next)); + memset(&sbinfo->si_xinodir, 0, sizeof(struct path)); +} --- linux-2.6.28.orig/ubuntu/aufs/iinfo.c +++ linux-2.6.28/ubuntu/aufs/iinfo.c @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode private data + * + * $Id: iinfo.c,v 1.8 2008/09/15 03:16:36 sfjro Exp $ + */ + +#include "aufs.h" + +struct au_iinfo *au_ii(struct inode *inode) +{ + struct au_iinfo *iinfo; + + iinfo = &(container_of(inode, struct aufs_icntnr, vfs_inode)->iinfo); + /* bad_inode case */ + if (unlikely(!iinfo->ii_hinode)) + return NULL; + AuDebugOn(!iinfo->ii_hinode + /* || au_sbi(inode->i_sb)->si_bend < iinfo->ii_bend */ + || iinfo->ii_bend < iinfo->ii_bstart); + return iinfo; +} + +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex) +{ + struct inode *hidden_inode; + + IiMustAnyLock(inode); + AuDebugOn(bindex < 0 || au_ibend(inode) < bindex); + hidden_inode = au_ii(inode)->ii_hinode[0 + bindex].hi_inode; + AuDebugOn(hidden_inode && atomic_read(&hidden_inode->i_count) <= 0); + return hidden_inode; +} + +aufs_bindex_t au_ii_br_id(struct inode *inode, aufs_bindex_t bindex) +{ + IiMustAnyLock(inode); + AuDebugOn(bindex < 0 + || au_ibend(inode) < bindex + || !au_ii(inode)->ii_hinode[0 + bindex].hi_inode); + return au_ii(inode)->ii_hinode[0 + bindex].hi_id; +} + +/* todo: hard/soft set? */ +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex) +{ + struct au_iinfo *iinfo = au_ii(inode); + struct inode *h_inode; + + IiMustWriteLock(inode); + AuDebugOn(au_sbend(inode->i_sb) < bindex); + iinfo->ii_bstart = bindex; + h_inode = iinfo->ii_hinode[bindex + 0].hi_inode; + if (h_inode) + au_cpup_igen(inode, h_inode); +} + +unsigned int au_hi_flags(struct inode *inode, int isdir) +{ + unsigned int flags; + const unsigned int mnt_flags = au_mntflags(inode->i_sb); + + flags = 0; + if (au_opt_test_xino(mnt_flags)) + au_fset_hi(flags, XINO); + if (unlikely(isdir && au_opt_test(mnt_flags, UDBA_INOTIFY))) + au_fset_hi(flags, NOTIFY); + return flags; +} + +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, + struct inode *h_inode, unsigned int flags) +{ + struct au_hinode *hinode; + struct inode *hi; + struct au_iinfo *iinfo = au_ii(inode); + + LKTRTrace("i%lu, b%d, hi%lu, flags 0x%x\n", + inode->i_ino, bindex, h_inode ? h_inode->i_ino : 0, flags); + IiMustWriteLock(inode); + hinode = iinfo->ii_hinode + bindex; + hi = hinode->hi_inode; + AuDebugOn(bindex < au_ibstart(inode) || au_ibend(inode) < bindex); + AuDebugOn(h_inode && atomic_read(&h_inode->i_count) <= 0); + AuDebugOn(h_inode && hi); + + if (hi) + au_hiput(hinode); + hinode->hi_inode = h_inode; + if (h_inode) { + int err; + struct super_block *sb = inode->i_sb; + + if (bindex == iinfo->ii_bstart) + au_cpup_igen(inode, h_inode); + hinode->hi_id = au_sbr_id(sb, bindex); + if (au_ftest_hi(flags, XINO)) { + struct au_xino_entry xinoe = { + .ino = inode->i_ino, + /* .h_gen = h_inode->i_generation */ + }; + err = au_xino_write(sb, bindex, h_inode->i_ino, &xinoe); + if (unlikely(err)) + AuIOErr1("failed au_xino_write() %d\n", err); + } + + if (unlikely(au_ftest_hi(flags, NOTIFY) + && au_br_hinotifyable(au_sbr_perm(sb, bindex)))) { + err = au_hin_alloc(hinode, inode, h_inode); + if (unlikely(err)) + AuIOErr1("au_hin_alloc() %d\n", err); + } + } +} + +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, + struct dentry *h_wh) +{ + struct au_hinode *hinode; + + IiMustWriteLock(inode); + hinode = au_ii(inode)->ii_hinode + bindex; + AuDebugOn(hinode->hi_whdentry); + hinode->hi_whdentry = h_wh; +} + +void au_update_iigen(struct inode *inode) +{ + AuDebugOn(!inode->i_sb); + atomic_set(&au_ii(inode)->ii_generation, au_sigen(inode->i_sb)); + /* smp_mb(); */ /* atomic_set */ +} + +/* it may be called at remount time, too */ +void au_update_brange(struct inode *inode, int do_put_zero) +{ + struct au_iinfo *iinfo; + + LKTRTrace("i%lu, %d\n", inode->i_ino, do_put_zero); + IiMustWriteLock(inode); + + iinfo = au_ii(inode); + if (unlikely(!iinfo) || iinfo->ii_bstart < 0) + return; + + if (do_put_zero) { + aufs_bindex_t bindex; + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; + bindex++) { + struct inode *h_i; + h_i = iinfo->ii_hinode[0 + bindex].hi_inode; + if (h_i && !h_i->i_nlink) + au_set_h_iptr(inode, bindex, NULL, 0); + } + } + + iinfo->ii_bstart = -1; + while (++iinfo->ii_bstart <= iinfo->ii_bend) + if (iinfo->ii_hinode[0 + iinfo->ii_bstart].hi_inode) + break; + if (iinfo->ii_bstart > iinfo->ii_bend) { + iinfo->ii_bstart = -1; + iinfo->ii_bend = -1; + return; + } + + iinfo->ii_bend++; + while (0 <= --iinfo->ii_bend) + if (iinfo->ii_hinode[0 + iinfo->ii_bend].hi_inode) + break; + AuDebugOn(iinfo->ii_bstart > iinfo->ii_bend || iinfo->ii_bend < 0); +} + +/* ---------------------------------------------------------------------- */ + +int au_iinfo_init(struct inode *inode) +{ + struct au_iinfo *iinfo; + struct super_block *sb; + int nbr, i; + + sb = inode->i_sb; + AuDebugOn(!sb); + iinfo = &(container_of(inode, struct aufs_icntnr, vfs_inode)->iinfo); + AuDebugOn(iinfo->ii_hinode); + nbr = au_sbend(sb) + 1; + if (unlikely(nbr <= 0)) + nbr = 1; + iinfo->ii_hinode = kcalloc(nbr, sizeof(*iinfo->ii_hinode), GFP_NOFS); + if (iinfo->ii_hinode) { + for (i = 0; i < nbr; i++) + iinfo->ii_hinode[i].hi_id = -1; + atomic_set(&iinfo->ii_generation, au_sigen(sb)); + /* smp_mb(); */ /* atomic_set */ + au_rw_init_nolock(&iinfo->ii_rwsem); + iinfo->ii_bstart = -1; + iinfo->ii_bend = -1; + iinfo->ii_vdir = NULL; + return 0; + } + return -ENOMEM; +} + +static int au_iinfo_write0(struct super_block *sb, struct au_hinode *hinode, + ino_t ino) +{ + int err, locked; + aufs_bindex_t bindex; + + err = 0; + locked = si_noflush_read_trylock(sb); /* crucio! */ + bindex = au_br_index(sb, hinode->hi_id); + if (bindex >= 0) + err = au_xino_write0(sb, bindex, hinode->hi_inode->i_ino, ino); + /* error action? */ + if (locked) + si_read_unlock(sb); + return err; +} + +void au_iinfo_fin(struct inode *inode) +{ + struct au_iinfo *iinfo; + aufs_bindex_t bend; + unsigned char unlinked; + struct au_hinode *hi; + struct super_block *sb; + ino_t ino; + + iinfo = au_ii(inode); + /* bad_inode case */ + if (unlikely(!iinfo)) + return; + + if (unlikely(iinfo->ii_vdir)) + au_vdir_free(iinfo->ii_vdir); + + if (iinfo->ii_bstart >= 0) { + sb = inode->i_sb; + unlinked = !inode->i_nlink; + ino = 0; + if (unlinked) + ino = inode->i_ino; + hi = iinfo->ii_hinode + iinfo->ii_bstart; + bend = iinfo->ii_bend; + while (iinfo->ii_bstart++ <= bend) { + if (hi->hi_inode) { + if (unlinked || !hi->hi_inode->i_nlink) { + au_iinfo_write0(sb, hi, ino); + /* ignore this error */ + ino = 0; + } + au_hiput(hi); + } + hi++; + } + } + + kfree(iinfo->ii_hinode); +} --- linux-2.6.28.orig/ubuntu/aufs/sysaufs.h +++ linux-2.6.28/ubuntu/aufs/sysaufs.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sysfs interface and lifetime management + * + * $Id: sysaufs.h,v 1.11 2008/09/15 03:14:55 sfjro Exp $ + */ + +#ifndef __SYSAUFS_H__ +#define __SYSAUFS_H__ + +#ifdef __KERNEL__ + +#include +#include +#include "module.h" +#include "super.h" + +#define SysaufsSb_PREFIX "si_" /* followed by %p */ + +struct au_sbi_attr { + struct attribute attr; + int (*show)(struct seq_file *seq, struct super_block *sb); +}; + +/* ---------------------------------------------------------------------- */ + +/* sysaufs.c */ +extern unsigned long au_si_mask; +extern struct kset *au_kset; +extern struct attribute *au_sbi_attrs[]; +int sysaufs_si_init(struct au_sbinfo *sbinfo); +int __init sysaufs_init(void); +void sysaufs_fin(void); + +/* ---------------------------------------------------------------------- */ + +struct au_branch; +#ifdef CONFIG_SYSFS +/* sysfs.c */ +extern struct attribute_group *au_attr_group; +extern struct kobj_type *au_ktype; + +int sysaufs_sbi_xino(struct seq_file *seq, struct super_block *sb); +#ifdef CONFIG_AUFS_EXPORT +int sysaufs_sbi_xigen(struct seq_file *seq, struct super_block *sb); +#endif +int sysaufs_sbi_mntpnt1(struct seq_file *seq, struct super_block *sb); +ssize_t sysaufs_sbi_show(struct kobject *kobj, struct attribute *attr, + char *buf); + +void sysaufs_br_init(struct au_branch *br); +void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex); +void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex); +#else +#define au_attr_group NULL +#define au_ktype NULL + +static inline +int sysaufs_sbi_xino(struct seq_file *seq, struct super_block *sb) +{ + return 0; +} + +#ifdef CONFIG_AUFS_EXPORT +static inline +int sysaufs_sbi_xigen(struct seq_file *seq, struct super_block *sb) +{ + return 0; +} +#endif + +static inline +int sysaufs_sbi_mntpnt1(struct seq_file *seq, struct super_block *sb) +{ + return 0; +} + +static inline +ssize_t sysaufs_sbi_show(struct kobject *kobj, struct attribute *attr, + char *buf) +{ + return 0; +} + +static inline void sysaufs_br_init(struct au_branch *br) +{ + /* empty */ +} + +static inline void sysaufs_brs_add(struct super_block *sb, aufs_bindex_t bindex) +{ + /* nothing */ +} + +static inline void sysaufs_brs_del(struct super_block *sb, aufs_bindex_t bindex) +{ + /* nothing */ +} +#endif /* CONFIG_SYSFS */ + +#endif /* __KERNEL__ */ +#endif /* __SYSAUFS_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/vfsub.c +++ linux-2.6.28/ubuntu/aufs/vfsub.c @@ -0,0 +1,719 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for VFS + * + * $Id: vfsub.c,v 1.11 2008/08/04 00:32:35 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +void vfsub_args_init(struct vfsub_args *vargs, struct au_hin_ignore *ign, + int dlgt, int force_unlink) +{ + do_vfsub_args_reinit(vargs, ign); + vargs->flags = 0; + if (unlikely(dlgt)) + vfsub_fset(vargs->flags, DLGT); + if (force_unlink) + vfsub_fset(vargs->flags, FORCE_UNLINK); +} + +/* ---------------------------------------------------------------------- */ + +struct file *vfsub_filp_open(const char *path, int oflags, int mode) +{ + struct file *err; + + LKTRTrace("%s\n", path); + + lockdep_off(); + err = filp_open(path, oflags, mode); + lockdep_on(); + if (!IS_ERR(err)) + au_update_fuse_h_inode(err->f_vfsmnt, err->f_dentry); /*ignore*/ + return err; +} + +int vfsub_path_lookup(const char *name, unsigned int flags, + struct nameidata *nd) +{ + int err; + + LKTRTrace("%s\n", name); + + /* lockdep_off(); */ + err = path_lookup(name, flags, nd); + /* lockdep_on(); */ + if (!err) + au_update_fuse_h_inode(nd->path.mnt, nd->path.dentry); + /*ignore*/ + return err; +} + +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, + int len) +{ + struct dentry *d; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name); + IMustLock(parent->d_inode); + + d = lookup_one_len(name, parent, len); + if (!IS_ERR(d)) + au_update_fuse_h_inode(NULL, d); /*ignore*/ + return d; +} + +#ifdef CONFIG_AUFS_LHASH_PATCH +struct dentry *vfsub__lookup_hash(struct qstr *name, struct dentry *parent, + struct nameidata *nd) +{ + struct dentry *d; + + LKTRTrace("%.*s/%.*s, nd %d\n", + AuDLNPair(parent), AuLNPair(name), !!nd); + if (nd) + LKTRTrace("nd{0x%x}\n", nd->flags); + IMustLock(parent->d_inode); + + d = __lookup_hash(name, parent, nd); + if (!IS_ERR(d)) + au_update_fuse_h_inode(NULL, d); /*ignore*/ + return d; +} +#endif + +/* ---------------------------------------------------------------------- */ + +int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + int err; + struct vfsmount *mnt; + + LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); + + err = vfs_create(dir, dentry, mode, nd); + if (!err) { + mnt = NULL; + if (nd) + mnt = nd->path.mnt; + /* dir inode is locked */ + au_update_fuse_h_inode(mnt, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(mnt, dentry); /*ignore*/ + } + return err; +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +#define VfsubSymlinkArgs dir, dentry, symname +#else +#define VfsubSymlinkArgs dir, dentry, symname, mode +#endif + +int do_vfsub_symlink(struct inode *dir, struct dentry *dentry, + const char *symname, int mode) +{ + int err; + + LKTRTrace("i%lu, %.*s, %s, 0x%x\n", + dir->i_ino, AuDLNPair(dentry), symname, mode); + IMustLock(dir); + + err = vfs_symlink(dir, dentry, NULL, symname); + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev) +{ + int err; + + LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); + + #ifdef CONFIG_VSERVER + err = vfs_mknod(dir, dentry, mode, dev, NULL); + #elif defined(CONFIG_SECURITY_APPARMOR) + err = vfs_mknod(dir, dentry, NULL, mode, dev); + #else + err = vfs_mknod(dir, dentry, mode, dev); + #endif + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry) +{ + int err; + + LKTRTrace("%.*s, i%lu, %.*s\n", + AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + + lockdep_off(); + #ifdef CONFIG_VSERVER + err = vfs_link(src_dentry, dir, dentry, NULL); + #elif defined(CONFIG_SECURITY_APPARMOR) + err = vfs_link(src_dentry, NULL, dir, dentry, NULL); + #else + err = vfs_link(src_dentry, dir, dentry); + #endif + + lockdep_on(); + if (!err) { + LKTRTrace("src_i %p, dst_i %p\n", + src_dentry->d_inode, dentry->d_inode); + /* fuse has different memory inode for the same inumber */ + au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/ + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry) +{ + int err; + + LKTRTrace("i%lu, %.*s, i%lu, %.*s\n", + src_dir->i_ino, AuDLNPair(src_dentry), + dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + IMustLock(src_dir); + + lockdep_off(); + #ifdef CONFIG_SECURITY_APPARMOR + err = vfs_rename(src_dir, src_dentry, NULL, dir, dentry, NULL); + #else + err = vfs_rename(src_dir, src_dentry, dir, dentry); + #endif + lockdep_on(); + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, src_dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, src_dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + int err; + + LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); + + #ifdef CONFIG_VSERVER + err = vfs_mkdir(dir, dentry, mode, NULL); + #elif defined(CONFIG_SECURITY_APPARMOR) + err = vfs_mkdir(dir, dentry, NULL, mode); + #else + err = vfs_mkdir(dir, dentry, mode); + #endif + + if (!err) { + /* dir inode is locked */ + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + au_update_fuse_h_inode(NULL, dentry); /*ignore*/ + } + return err; +} + +int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry) +{ + int err; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + + lockdep_off(); + #if defined(CONFIG_VSERVER) || defined(CONFIG_SECURITY_APPARMOR) + err = vfs_rmdir(dir, dentry, NULL); + #else + err = vfs_rmdir(dir, dentry); + #endif + + lockdep_on(); + /* dir inode is locked */ + if (!err) + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + return err; +} + +int do_vfsub_unlink(struct inode *dir, struct dentry *dentry) +{ + int err; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + + /* vfs_unlink() locks inode */ + lockdep_off(); + #if defined(CONFIG_VSERVER) || defined(CONFIG_SECURITY_APPARMOR) + err = vfs_unlink(dir, dentry, NULL); + #else + err = vfs_unlink(dir, dentry); + #endif + + lockdep_on(); + /* dir inode is locked */ + if (!err) + au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/ + return err; +} + +/* ---------------------------------------------------------------------- */ + +ssize_t do_vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos) +{ + ssize_t err; + + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)count, *ppos); + + /* todo: always off, regardless nfs branch? */ + au_br_nfs_lockdep_off(file->f_vfsmnt->mnt_sb); + err = vfs_read(file, ubuf, count, ppos); + au_br_nfs_lockdep_on(file->f_vfsmnt->mnt_sb); + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + return err; +} + +/* todo: kernel_read()? */ +ssize_t do_vfsub_read_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos) +{ + ssize_t err; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = do_vfsub_read_u(file, (char __user *)kbuf, count, ppos); + set_fs(oldfs); + return err; +} + +ssize_t do_vfsub_write_u(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + ssize_t err; + + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)count, *ppos); + + lockdep_off(); + err = vfs_write(file, ubuf, count, ppos); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + return err; +} + +ssize_t do_vfsub_write_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos) +{ + ssize_t err; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + err = do_vfsub_write_u(file, (const char __user *)kbuf, count, ppos); + set_fs(oldfs); + return err; +} + +int do_vfsub_readdir(struct file *file, filldir_t filldir, void *arg) +{ + int err; + + LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry)); + + lockdep_off(); + err = vfs_readdir(file, filldir, arg); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + return err; +} + +#ifdef CONFIG_AUFS_SPLICE_PATCH +long do_vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + long err; + + LKTRTrace("%.*s, pos %lld, len %lu, 0x%x\n", + AuDLNPair(in->f_dentry), *ppos, (unsigned long)len, flags); + + lockdep_off(); + err = vfs_splice_to(in, ppos, pipe, len, flags); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(in->f_vfsmnt, in->f_dentry); /*ignore*/ + return err; +} + +long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) +{ + long err; + + LKTRTrace("%.*s, pos %lld, len %lu, 0x%x\n", + AuDLNPair(out->f_dentry), *ppos, (unsigned long)len, flags); + + lockdep_off(); + err = vfs_splice_from(pipe, out, ppos, len, flags); + lockdep_on(); + if (err >= 0) + au_update_fuse_h_inode(out->f_vfsmnt, out->f_dentry); /*ignore*/ + return err; +} +#endif + +/* ---------------------------------------------------------------------- */ + +struct au_vfsub_mkdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + struct vfsub_args *vargs; +}; + +static void au_call_vfsub_mkdir(void *args) +{ + struct au_vfsub_mkdir_args *a = args; + *a->errp = vfsub_mkdir(a->dir, a->dentry, a->mode, a->vargs); +} + +int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry, int mode, + int dlgt) +{ + int err, do_sio, wkq_err; + struct inode *dir = hdir->hi_inode; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + vfsub_ign_hinode(&vargs, IN_CREATE, hdir); + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt); + if (!do_sio) + err = vfsub_mkdir(dir, dentry, mode, &vargs); + else { + struct au_vfsub_mkdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_vfsub_mkdir, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} + +struct au_vfsub_rmdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + struct vfsub_args *vargs; +}; + +static void au_call_vfsub_rmdir(void *args) +{ + struct au_vfsub_rmdir_args *a = args; + *a->errp = vfsub_rmdir(a->dir, a->dentry, a->vargs); +} + +int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry, int dlgt) +{ + int err, do_sio, wkq_err; + struct inode *dir = hdir->hi_inode; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt); + if (!do_sio) + err = vfsub_rmdir(dir, dentry, &vargs); + else { + struct au_vfsub_rmdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_vfsub_rmdir, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct notify_change_args { + int *errp; + struct dentry *h_dentry; + struct iattr *ia; + struct vfsub_args *vargs; +}; + +static void call_notify_change(void *args) +{ + struct notify_change_args *a = args; + struct inode *h_inode; + + LKTRTrace("%.*s, ia_valid 0x%x\n", + AuDLNPair(a->h_dentry), a->ia->ia_valid); + h_inode = a->h_dentry->d_inode; + IMustLock(h_inode); + + *a->errp = -EPERM; + if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) { + vfsub_ignore(a->vargs); + lockdep_off(); + *a->errp = notify_change(a->h_dentry, NULL, a->ia); + lockdep_on(); + if (!*a->errp) + au_update_fuse_h_inode(NULL, a->h_dentry); /*ignore*/ + else + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); + } + AuTraceErr(*a->errp); +} + +#ifdef CONFIG_AUFS_DLGT +static void vfsub_notify_change_dlgt(struct notify_change_args *args, + unsigned int flags) +{ + if (!vfsub_ftest(flags, DLGT)) + call_notify_change(args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_notify_change, args, /*dlgt*/1); + if (unlikely(wkq_err)) + *args->errp = wkq_err; + } +} +#else +static void vfsub_notify_change_dlgt(struct notify_change_args *args, + unsigned int flags) +{ + call_notify_change(args); +} +#endif + +int vfsub_notify_change(struct dentry *dentry, struct iattr *ia, + struct vfsub_args *vargs) +{ + int err; + struct notify_change_args args = { + .errp = &err, + .h_dentry = dentry, + .ia = ia, + .vargs = vargs + }; + + vfsub_notify_change_dlgt(&args, vargs->flags); + + AuTraceErr(err); + return err; +} + +int vfsub_sio_notify_change(struct au_hinode *hdir, struct dentry *dentry, + struct iattr *ia) +{ + int err, wkq_err; + struct au_hin_ignore ign; + struct vfsub_args vargs; + __u32 events; + struct notify_change_args args = { + .errp = &err, + .h_dentry = dentry, + .ia = ia, + .vargs = &vargs + }; + + LKTRTrace("%.*s, 0x%x\n", AuDLNPair(dentry), ia->ia_valid); + + vfsub_args_init(&vargs, &ign, /*dlgt*/0, /*force_unlink*/0); + events = vfsub_events_notify_change(ia); + if (events) + vfsub_ign_hinode(&vargs, events, hdir); + wkq_err = au_wkq_wait(call_notify_change, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct unlink_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + struct vfsub_args *vargs; +}; + +static void call_unlink(void *args) +{ + struct unlink_args *a = args; + struct inode *h_inode; + const int stop_sillyrename = (au_test_nfs(a->dentry->d_sb) + && atomic_read(&a->dentry->d_count) == 1); + + LKTRTrace("%.*s, stop_silly %d, cnt %d\n", + AuDLNPair(a->dentry), stop_sillyrename, + atomic_read(&a->dentry->d_count)); + + if (!stop_sillyrename) + dget(a->dentry); + h_inode = a->dentry->d_inode; + if (h_inode) + atomic_inc_return(&h_inode->i_count); + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_unlink(a->dir, a->dentry); + if (unlikely(*a->errp || (a->dentry->d_flags & DCACHE_NFSFS_RENAMED))) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); + if (!stop_sillyrename) + dput(a->dentry); + if (h_inode) + iput(h_inode); + + AuTraceErr(*a->errp); +} + +/* + * @dir: must be locked. + * @dentry: target dentry. + */ +int vfsub_unlink(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + int err; + struct unlink_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT) + && !vfsub_ftest(vargs->flags, FORCE_UNLINK)) + call_unlink(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_unlink, &args, + vfsub_ftest(vargs->flags, DLGT)); + if (unlikely(wkq_err)) + err = wkq_err; + } + + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct statfs_args { + int *errp; + void *arg; + struct kstatfs *buf; +}; + +static void call_statfs(void *args) +{ + struct statfs_args *a = args; + *a->errp = vfs_statfs(a->arg, a->buf); +} + +#ifdef CONFIG_AUFS_DLGT +static void vfsub_statfs_dlgt(struct statfs_args *args, int dlgt) +{ + if (!dlgt) + call_statfs(args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_statfs, args, /*dlgt*/1); + if (unlikely(wkq_err)) + *args->errp = wkq_err; + } +} +#else +static void vfsub_statfs_dlgt(struct statfs_args *args, int dlgt) +{ + call_statfs(args); +} +#endif + +int vfsub_statfs(void *arg, struct kstatfs *buf, int dlgt) +{ + int err; + struct statfs_args args = { + .errp = &err, + .arg = arg, + .buf = buf + }; + + vfsub_statfs_dlgt(&args, dlgt); + + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/vfsub.h +++ linux-2.6.28/ubuntu/aufs/vfsub.h @@ -0,0 +1,518 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for VFS + * + * $Id: vfsub.h,v 1.11 2008/08/25 01:51:04 sfjro Exp $ + */ + +#ifndef __AUFS_VFSUB_H__ +#define __AUFS_VFSUB_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* vfsub flags */ +#define Vfsub_DLGT 1 /* operation with delegation */ +#define Vfsub_FORCE_UNLINK (1 << 1) /* force unlinking */ +#define vfsub_ftest(flags, name) ((flags) & Vfsub_##name) +#define vfsub_fset(flags, name) { (flags) |= Vfsub_##name; } +#define vfsub_fclr(flags, name) { (flags) &= ~Vfsub_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef Vfsub_DLGT +#define Vfsub_DLGT 0 +#endif + +struct au_hin_ignore; +struct vfsub_args { +#ifdef CONFIG_AUFS_HINOTIFY + /* inotify events to be ignored */ + int nignore; + struct au_hin_ignore *ignore; +#endif + + unsigned int flags; +}; + +struct au_hinode; +#ifdef CONFIG_AUFS_HINOTIFY +static inline +void do_vfsub_args_reinit(struct vfsub_args *vargs, struct au_hin_ignore *ign) +{ + vargs->nignore = 0; + vargs->ignore = ign; +} + +static inline void vfsub_args_reinit(struct vfsub_args *vargs) +{ + vargs->nignore = 0; +} + +__u32 vfsub_events_notify_change(struct iattr *ia); +void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events, + struct au_hinode *hinode); +void vfsub_ignore(struct vfsub_args *vargs); +void vfsub_unignore(struct vfsub_args *vargs); +#else +static inline +void do_vfsub_args_reinit(struct vfsub_args *vargs, struct au_hin_ignore *ign) +{ + /* empty */ +} + +static inline void vfsub_args_reinit(struct vfsub_args *vargs) +{ + /* empty */ +} + +static inline __u32 vfsub_events_notify_change(struct iattr *ia) +{ + return 0; +} + +static inline void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events, + struct au_hinode *hinode) +{ + /* empty */ +} + +static inline void vfsub_ignore(struct vfsub_args *vargs) +{ + /* empty */ +} + +static inline void vfsub_unignore(struct vfsub_args *vargs) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_HINOTIFY */ + +void vfsub_args_init(struct vfsub_args *vargs, struct au_hin_ignore *ign, + int dlgt, int force_unlink); + +/* ---------------------------------------------------------------------- */ + +/* inotify_inode_watched() is not exported */ +static inline int au_test_inotify(struct inode *inode) +{ +#ifdef CONFIG_INOTIFY + return !list_empty(&inode->inotify_watches); +#endif + return 0; +} + +/* ---------------------------------------------------------------------- */ + +/* lock subclass for hidden inode */ +/* default MAX_LOCKDEP_SUBCLASSES(8) is not enough */ +/* reduce? gave up. */ +enum { + AuLsc_I_Begin = I_MUTEX_QUOTA, /* 4 */ + AuLsc_I_PARENT, /* hidden inode, parent first */ + AuLsc_I_PARENT2, /* copyup dirs */ + AuLsc_I_PARENT3, /* rename with hinotify */ + AuLsc_I_PARENT4, /* ditto */ + AuLsc_I_CHILD, + AuLsc_I_CHILD2, + AuLsc_I_End +}; + +#define IMustLock(i) MtxMustLock(&(i)->i_mutex) + +static inline void vfsub_lock_rename_mutex(struct super_block *sb) +{ + lockdep_off(); + mutex_lock(&sb->s_vfs_rename_mutex); + lockdep_on(); +} + +static inline void vfsub_unlock_rename_mutex(struct super_block *sb) +{ + lockdep_off(); + mutex_unlock(&sb->s_vfs_rename_mutex); + lockdep_on(); +} + +static inline +struct dentry *vfsub_lock_rename(struct dentry *d1, struct dentry *d2) +{ + struct dentry *d; + + lockdep_off(); + d = lock_rename(d1, d2); + lockdep_on(); + return d; +} + +static inline void vfsub_unlock_rename(struct dentry *d1, struct dentry *d2) +{ + lockdep_off(); + unlock_rename(d1, d2); + lockdep_on(); +} + +static inline int au_verify_parent(struct dentry *dentry, struct inode *dir) +{ + IMustLock(dir); + return (/* !dir->i_nlink || */ dentry->d_parent->d_inode != dir); +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_WORKAROUND_FUSE +/* br_fuse.c */ +int au_update_fuse_h_inode(struct vfsmount *h_mnt, struct dentry *h_dentry); +#else +static inline +int au_update_fuse_h_inode(struct vfsmount *h_mnt, struct dentry *h_dentry) +{ + return 0; +} +#endif + +#ifdef CONFIG_AUFS_BR_XFS +/* br_xfs.c */ +dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt, + struct dentry *h_dentry); +#else +static inline +dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt, + struct dentry *h_dentry) +{ + return h_inode->i_rdev; +} +#endif + +/* simple abstractions, for future use */ +static inline +int do_vfsub_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + LKTRTrace("i%lu, mask 0x%x, nd %d\n", inode->i_ino, mask, !!nd); + IMustLock(inode); +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + return inode_permission(inode, mask); +#else + return permission(inode, mask, nd); +#endif +} + +static inline +int vfsub_security_inode_permission(struct inode *inode, int mask, + struct nameidata *nd) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) + return security_inode_permission(inode, mask); +#else + return security_inode_permission(inode, mask, nd); +#endif +} + +/* ---------------------------------------------------------------------- */ + +struct file *vfsub_filp_open(const char *path, int oflags, int mode); +int vfsub_path_lookup(const char *name, unsigned int flags, + struct nameidata *nd); +struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent, + int len); + +#ifdef CONFIG_AUFS_LHASH_PATCH +struct dentry *vfsub__lookup_hash(struct qstr *name, struct dentry *parent, + struct nameidata *nd); +#endif + +/* ---------------------------------------------------------------------- */ + +int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd); +int do_vfsub_symlink(struct inode *dir, struct dentry *dentry, + const char *symname, int mode); +int do_vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, + dev_t dev); +int do_vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry); +int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry); +int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode); +int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry); +int do_vfsub_unlink(struct inode *dir, struct dentry *dentry); + +/* ---------------------------------------------------------------------- */ + +ssize_t do_vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos); +/* todo: kernel_read()? */ +ssize_t do_vfsub_read_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos); +ssize_t do_vfsub_write_u(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos); +ssize_t do_vfsub_write_k(struct file *file, void *kbuf, size_t count, + loff_t *ppos); +int do_vfsub_readdir(struct file *file, filldir_t filldir, void *arg); + +/* ---------------------------------------------------------------------- */ + +#ifndef CONFIG_AUFS_UNIONFS22_PATCH +static inline void vfsub_copy_inode_size(struct inode *inode, + struct inode *h_inode) +{ + spin_lock(&inode->i_lock); + fsstack_copy_inode_size(inode, h_inode); + spin_unlock(&inode->i_lock); +} +#else +static inline void vfsub_copy_inode_size(struct inode *inode, + struct inode *h_inode) +{ + fsstack_copy_inode_size(inode, h_inode); +} +#endif + +#ifndef CONFIG_AUFS_UNIONFS23_PATCH +#define vfs_splice_to do_splice_to +#define vfs_splice_from do_splice_from +#endif + +#ifdef CONFIG_AUFS_SPLICE_PATCH +long do_vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); +long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); +#else +static inline +long do_vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + return -ENOSYS; +} + +static inline +long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) +{ + return -ENOSYS; +} +#endif /* CONFIG_AUFS_SPLICE_PATCH */ + +/* ---------------------------------------------------------------------- */ + +static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin) +{ + loff_t err; + + LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry)); + + lockdep_off(); + err = vfs_llseek(file, offset, origin); + lockdep_on(); + return err; +} + +static inline int do_vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, + struct kstat *st) +{ + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + return vfs_getattr(mnt, dentry, st); +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HIN_OR_DLGT +/* hin_or_dlgt.c */ +int vfsub_permission(struct inode *inode, int mask, struct nameidata *nd, + int dlgt); + +int vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd, struct vfsub_args *vargs); +int vfsub_symlink(struct inode *dir, struct dentry *dentry, const char *symname, + int mode, struct vfsub_args *vargs); +int vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev, + struct vfsub_args *vargs); +int vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct vfsub_args *vargs); +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs); +int vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode, + struct vfsub_args *vargs); +int vfsub_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs); + +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos, int dlgt); +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + int dlgt); +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, + loff_t *ppos, struct vfsub_args *vargs); +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + struct vfsub_args *vargs); +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg, int dlgt); +long vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags, int dlgt); +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + struct vfsub_args *vargs); + +int vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st, + int dlgt); +#else + +static inline +int vfsub_permission(struct inode *inode, int mask, struct nameidata *nd, + int dlgt) +{ + return do_vfsub_permission(inode, mask, nd); +} + +static inline +int vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd, struct vfsub_args *vargs) +{ + return do_vfsub_create(dir, dentry, mode, nd); +} + +static inline +int vfsub_symlink(struct inode *dir, struct dentry *dentry, const char *symname, + int mode, struct vfsub_args *vargs) +{ + return do_vfsub_symlink(dir, dentry, symname, mode); +} + +static inline +int vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev, + struct vfsub_args *vargs) +{ + return do_vfsub_mknod(dir, dentry, mode, dev); +} + +static inline +int vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct vfsub_args *vargs) +{ + return do_vfsub_link(src_dentry, dir, dentry); +} + +static inline +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + return do_vfsub_rename(src_dir, src_dentry, dir, dentry); +} + +static inline +int vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode, + struct vfsub_args *vargs) +{ + return do_vfsub_mkdir(dir, dentry, mode); +} + +static inline +int vfsub_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + return do_vfsub_rmdir(dir, dentry); +} + +static inline +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos, int dlgt) +{ + return do_vfsub_read_u(file, ubuf, count, ppos); +} + +static inline +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + int dlgt) +{ + return do_vfsub_read_k(file, kbuf, count, ppos); +} + +static inline +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, + loff_t *ppos, struct vfsub_args *vargs) +{ + return do_vfsub_write_u(file, ubuf, count, ppos); +} + +static inline +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + struct vfsub_args *vargs) +{ + return do_vfsub_write_k(file, kbuf, count, ppos); +} + +static inline +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg, int dlgt) +{ + return do_vfsub_readdir(file, filldir, arg); +} + +static inline +long vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags, int dlgt) +{ + return do_vfsub_splice_to(in, ppos, pipe, len, flags); +} + +static inline +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + struct vfsub_args *vargs) +{ + return do_vfsub_splice_from(pipe, out, ppos, len, flags); +} + +static inline +int vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st, + int dlgt) +{ + return do_vfsub_getattr(mnt, dentry, st); +} +#endif /* HIN_OR_DLGT */ + +/* ---------------------------------------------------------------------- */ + +int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry, int mode, + int dlgt); +int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry, int dlgt); +int vfsub_sio_notify_change(struct au_hinode *hdir, struct dentry *dentry, + struct iattr *ia); + +/* ---------------------------------------------------------------------- */ + +int vfsub_notify_change(struct dentry *dentry, struct iattr *ia, + struct vfsub_args *vargs); +int vfsub_unlink(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs); +int vfsub_statfs(void *arg, struct kstatfs *buf, int dlgt); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_VFSUB_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/vdir.c +++ linux-2.6.28/ubuntu/aufs/vdir.c @@ -0,0 +1,941 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * virtual or vertical directory + * + * $Id: vdir.c,v 1.11 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +static int calc_size(int namelen) +{ + int sz; + + sz = sizeof(struct au_vdir_de) + namelen; + if (sizeof(ino_t) == sizeof(long)) { + const int mask = sizeof(ino_t) - 1; + if (sz & mask) { + sz += sizeof(ino_t); + sz &= ~mask; + } + } + + AuDebugOn(sz % sizeof(ino_t)); + return sz; +} + +static int set_deblk_end(union au_vdir_deblk_p *p, + union au_vdir_deblk_p *deblk_end) +{ + if (calc_size(0) <= deblk_end->p - p->p) { + p->de->de_str.len = 0; + /* smp_mb(); */ + return 0; + } + return -1; /* error */ +} + +/* returns true or false */ +static int is_deblk_end(union au_vdir_deblk_p *p, + union au_vdir_deblk_p *deblk_end) +{ + if (calc_size(0) <= deblk_end->p - p->p) + return !p->de->de_str.len; + return 1; +} + +static au_vdir_deblk_t *last_deblk(struct au_vdir *vdir) +{ + return vdir->vd_deblk[vdir->vd_nblk - 1]; +} + +void au_nhash_init(struct au_nhash *nhash) +{ + int i; + for (i = 0; i < AuSize_NHASH; i++) + INIT_HLIST_HEAD(nhash->heads + i); +} + +struct au_nhash *au_nhash_new(gfp_t gfp) +{ + struct au_nhash *nhash; + + nhash = kmalloc(sizeof(*nhash), gfp); + if (nhash) { + au_nhash_init(nhash); + return nhash; + } + return ERR_PTR(-ENOMEM); +} + +void au_nhash_del(struct au_nhash *nhash) +{ + au_nhash_fin(nhash); + kfree(nhash); +} + +void au_nhash_move(struct au_nhash *dst, struct au_nhash *src) +{ + int i; + + AuTraceEnter(); + + *dst = *src; + for (i = 0; i < AuSize_NHASH; i++) { + struct hlist_head *h; + h = dst->heads + i; + if (h->first) + h->first->pprev = &h->first; + INIT_HLIST_HEAD(src->heads + i); + } + /* smp_mb(); */ +} + +/* ---------------------------------------------------------------------- */ + +void au_nhash_fin(struct au_nhash *whlist) +{ + int i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos, *n; + + AuTraceEnter(); + + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) { + /* hlist_del(pos); */ + kfree(tpos); + } + } +} + +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, + int limit) +{ + int n, i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + + LKTRTrace("limit %d\n", limit); + + n = 0; + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry(tpos, pos, head, wh_hash) + if (tpos->wh_bindex == btgt && ++n > limit) + return 1; + } + return 0; +} + +static unsigned int au_name_hash(const unsigned char *name, unsigned int len) +{ + return (full_name_hash(name, len) % AuSize_NHASH); +} + +/* returns found(true) or not */ +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int namelen) +{ + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + struct au_vdir_destr *str; + + LKTRTrace("%.*s\n", namelen, name); + + head = whlist->heads + au_name_hash(name, namelen); + hlist_for_each_entry(tpos, pos, head, wh_hash) { + str = &tpos->wh_str; + LKTRTrace("%.*s\n", str->len, str->name); + if (str->len == namelen && !memcmp(str->name, name, namelen)) + return 1; + } + return 0; +} + +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int namelen, + ino_t ino, unsigned int d_type, aufs_bindex_t bindex, + unsigned char shwh) +{ + int err; + struct au_vdir_destr *str; + struct au_vdir_wh *wh; + + LKTRTrace("%.*s\n", namelen, name); + + err = -ENOMEM; + wh = kmalloc(sizeof(*wh) + namelen, GFP_NOFS); + if (unlikely(!wh)) + goto out; + err = 0; + wh->wh_bindex = bindex; + if (unlikely(shwh)) + au_shwh_init_wh(wh, ino, d_type); + str = &wh->wh_str; + str->len = namelen; + memcpy(str->name, name, namelen); + hlist_add_head(&wh->wh_hash, + whlist->heads + au_name_hash(name, namelen)); + /* smp_mb(); */ + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +void au_vdir_free(struct au_vdir *vdir) +{ + au_vdir_deblk_t **deblk; + + AuTraceEnter(); + + deblk = vdir->vd_deblk; + while (vdir->vd_nblk--) { + kfree(*deblk); + deblk++; + } + kfree(vdir->vd_deblk); + au_cache_free_vdir(vdir); +} + +static int append_deblk(struct au_vdir *vdir) +{ + int err, sz, i; + au_vdir_deblk_t **o; + union au_vdir_deblk_p p, deblk_end; + + AuTraceEnter(); + + err = -ENOMEM; + sz = sizeof(*o) * vdir->vd_nblk; + o = au_kzrealloc(vdir->vd_deblk, sz, sz + sizeof(*o), GFP_NOFS); + if (unlikely(!o)) + goto out; + vdir->vd_deblk = o; + p.deblk = kmalloc(sizeof(*p.deblk), GFP_NOFS); + if (p.deblk) { + i = vdir->vd_nblk++; + vdir->vd_deblk[i] = p.deblk; + vdir->vd_last.i = i; + vdir->vd_last.p.p = p.p; + deblk_end.deblk = p.deblk + 1; + err = set_deblk_end(&p, &deblk_end); + AuDebugOn(err); + } + + out: + AuTraceErr(err); + return err; +} + +static struct au_vdir *alloc_vdir(void) +{ + struct au_vdir *vdir; + int err; + + AuTraceEnter(); + + err = -ENOMEM; + vdir = au_cache_alloc_vdir(); + if (unlikely(!vdir)) + goto out; + vdir->vd_deblk = kzalloc(sizeof(*vdir->vd_deblk), GFP_NOFS); + if (unlikely(!vdir->vd_deblk)) + goto out_free; + + vdir->vd_nblk = 0; + vdir->vd_version = 0; + vdir->vd_jiffy = 0; + err = append_deblk(vdir); + if (!err) + return vdir; /* success */ + + kfree(vdir->vd_deblk); + + out_free: + au_cache_free_vdir(vdir); + out: + vdir = ERR_PTR(err); + AuTraceErrPtr(vdir); + return vdir; +} + +static int reinit_vdir(struct au_vdir *vdir) +{ + int err; + union au_vdir_deblk_p p, deblk_end; + + AuTraceEnter(); + + while (vdir->vd_nblk > 1) { + kfree(vdir->vd_deblk[vdir->vd_nblk - 1]); + vdir->vd_deblk[vdir->vd_nblk - 1] = NULL; + vdir->vd_nblk--; + } + p.deblk = vdir->vd_deblk[0]; + deblk_end.deblk = p.deblk + 1; + err = set_deblk_end(&p, &deblk_end); + AuDebugOn(err); + vdir->vd_version = 0; + vdir->vd_jiffy = 0; + vdir->vd_last.i = 0; + vdir->vd_last.p.deblk = vdir->vd_deblk[0]; + /* smp_mb(); */ + return err; +} + +/* ---------------------------------------------------------------------- */ + +static void free_dehlist(struct au_nhash *dehlist) +{ + int i; + struct hlist_head *head; + struct au_vdir_dehstr *tpos; + struct hlist_node *pos, *n; + + AuTraceEnter(); + + for (i = 0; i < AuSize_NHASH; i++) { + head = dehlist->heads + i; + hlist_for_each_entry_safe(tpos, pos, n, head, hash) { + /* hlist_del(pos); */ + au_cache_free_dehstr(tpos); + } + } +} + +/* returns found(true) or not */ +static int test_known(struct au_nhash *delist, char *name, int namelen) +{ + struct hlist_head *head; + struct au_vdir_dehstr *tpos; + struct hlist_node *pos; + struct au_vdir_destr *str; + + LKTRTrace("%.*s\n", namelen, name); + + head = delist->heads + au_name_hash(name, namelen); + hlist_for_each_entry(tpos, pos, head, hash) { + str = tpos->str; + LKTRTrace("%.*s\n", str->len, str->name); + if (str->len == namelen && !memcmp(str->name, name, namelen)) + return 1; + } + return 0; + +} + +static int append_de(struct au_vdir *vdir, char *name, int namelen, ino_t ino, + unsigned int d_type, struct au_nhash *delist) +{ + int err, sz; + union au_vdir_deblk_p p, *room, deblk_end; + struct au_vdir_dehstr *dehstr; + + LKTRTrace("%.*s %d, i%lu, dt%u\n", + namelen, name, namelen, (unsigned long)ino, d_type); + + p.deblk = last_deblk(vdir); + deblk_end.deblk = p.deblk + 1; + room = &vdir->vd_last.p; + AuDebugOn(room->p < p.p || deblk_end.p <= room->p + || !is_deblk_end(room, &deblk_end)); + + sz = calc_size(namelen); + if (unlikely(sz > deblk_end.p - room->p)) { + err = append_deblk(vdir); + if (unlikely(err)) + goto out; + p.deblk = last_deblk(vdir); + deblk_end.deblk = p.deblk + 1; + /* smp_mb(); */ + AuDebugOn(room->p != p.p); + } + + err = -ENOMEM; + dehstr = au_cache_alloc_dehstr(); + if (unlikely(!dehstr)) + goto out; + dehstr->str = &room->de->de_str; + hlist_add_head(&dehstr->hash, + delist->heads + au_name_hash(name, namelen)); + + room->de->de_ino = ino; + room->de->de_type = d_type; + room->de->de_str.len = namelen; + memcpy(room->de->de_str.name, name, namelen); + + err = 0; + room->p += sz; + if (unlikely(set_deblk_end(room, &deblk_end))) + err = append_deblk(vdir); + /* smp_mb(); */ + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + unsigned int d_type, ino_t *ino) +{ + int err; + struct au_xino_entry xinoe; + struct mutex *mtx; + const int isdir = (d_type == DT_DIR); + + /* prevent hardlinks from race condition */ + mtx = NULL; + if (!isdir) { + mtx = &au_sbr(sb, bindex)->br_xino.xi_nondir_mtx; + mutex_lock(mtx); + } + err = au_xino_read(sb, bindex, h_ino, &xinoe); + if (unlikely(err)) + goto out; + + if (!xinoe.ino) { + err = -EIO; + xinoe.ino = au_xino_new_ino(sb); + if (unlikely(!xinoe.ino)) + goto out; + +#if 0 /* reserved for future use */ + struct inode *h_inode; + xinoe.h_gen = AuXino_INVALID_HGEN; + h_inode = ilookup(au_sbr_sb(sb, bindex), h_ino); + if (h_inode) { + if (!is_bad_inode(h_inode)) { + xinoe.h_gen = h_inode->i_generation; + WARN_ON(xinoe.h_gen == AuXino_INVALID_HGEN); + } + iput(h_inode); + } +#endif + err = au_xino_write(sb, bindex, h_ino, &xinoe); + if (unlikely(err)) + goto out; + } + + *ino = xinoe.ino; + + out: + if (!isdir) + mutex_unlock(mtx); + AuTraceErr(err); + return err; +} + +static int au_wh_ino(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + unsigned int d_type, ino_t *ino) +{ +#ifdef CONFIG_AUFS_SHWH + return au_ino(sb, bindex, h_ino, d_type, ino); +#else + return 0; +#endif +} + +#define AuFillVdir_CALLED 1 +#define AuFillVdir_SHWH (1 << 1) +#define au_ftest_fillvdir(flags, name) ((flags) & AuFillVdir_##name) +#define au_fset_fillvdir(flags, name) { (flags) |= AuFillVdir_##name; } +#define au_fclr_fillvdir(flags, name) { (flags) &= ~AuFillVdir_##name; } +#ifndef CONFIG_AUFS_SHWH +#undef AuFillVdir_SHWH +#define AuFillVdir_SHWH 0 +#endif + +struct fillvdir_arg { + struct file *file; + struct au_vdir *vdir; + struct au_nhash *delist; + struct au_nhash *whlist; + aufs_bindex_t bindex; + unsigned int flags; + int err; +}; + +static int fillvdir(void *__arg, const char *__name, int namelen, loff_t offset, + u64 h_ino, unsigned int d_type) +{ + struct fillvdir_arg *arg = __arg; + char *name = (void *)__name; + aufs_bindex_t bindex, bend; + struct super_block *sb; + ino_t ino; + + LKTRTrace("%.*s, namelen %d, i%llu, dt%u\n", + namelen, name, namelen, (unsigned long long)h_ino, d_type); + + sb = arg->file->f_dentry->d_sb; + bend = arg->bindex; + arg->err = 0; + au_fset_fillvdir(arg->flags, CALLED); + /* smp_mb(); */ + if (namelen <= AUFS_WH_PFX_LEN + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { + for (bindex = 0; bindex < bend; bindex++) + if (test_known(arg->delist + bindex, name, namelen) + || au_nhash_test_known_wh(arg->whlist + bindex, + name, namelen)) + goto out; /* already exists or whiteouted */ + + ino = 1; /* why does gcc warns? */ + arg->err = au_ino(sb, bend, h_ino, d_type, &ino); + if (!arg->err) + arg->err = append_de(arg->vdir, name, namelen, ino, + d_type, arg->delist + bend); + } else { + name += AUFS_WH_PFX_LEN; + namelen -= AUFS_WH_PFX_LEN; + for (bindex = 0; bindex < bend; bindex++) + if (au_nhash_test_known_wh(arg->whlist + bend, name, + namelen)) + goto out; /* already whiteouted */ + + ino = 1; /* dummy */ + if (unlikely(au_ftest_fillvdir(arg->flags, SHWH))) + arg->err = au_wh_ino(sb, bend, h_ino, d_type, &ino); + if (!arg->err) + arg->err = au_nhash_append_wh + (arg->whlist + bend, name, namelen, ino, d_type, + bend, au_ftest_fillvdir(arg->flags, SHWH)); + } + + out: + if (!arg->err) + arg->vdir->vd_jiffy = jiffies; + /* smp_mb(); */ + AuTraceErr(arg->err); + return arg->err; +} + +static int au_handle_shwh(struct super_block *sb, struct au_vdir *vdir, + aufs_bindex_t bstart, aufs_bindex_t bend, + struct au_nhash *_whlist, struct au_nhash *_delist) +{ +#ifdef CONFIG_AUFS_SHWH + int err, i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos, *n; + char *p, *o; + struct au_nhash *whlist, *delist; + struct au_vdir_destr *destr; + aufs_bindex_t bindex; + + AuTraceEnter(); + AuDebugOn(!au_opt_test(au_mntflags(sb), SHWH)); + + err = -ENOMEM; + o = p = __getname(); + if (unlikely(!p)) + goto out; + + err = 0; + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); + p += AUFS_WH_PFX_LEN; + for (bindex = bstart; !err && bindex <= bend; bindex++) { + whlist = _whlist + bindex; + delist = _delist + bindex; + + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry_safe(tpos, pos, n, head, wh_hash) { + destr = &tpos->wh_str; + memcpy(p, destr->name, destr->len); + err = append_de(vdir, o, + destr->len + AUFS_WH_PFX_LEN, + tpos->wh_ino, tpos->wh_type, + delist); + if (unlikely(err)) + break; + } + } + } + + __putname(o); + + out: + AuTraceErr(err); + return err; +#else + return 0; +#endif +} + +static int au_do_read_vdir(struct fillvdir_arg *arg) +{ + int err; + unsigned int mnt_flags; + loff_t offset; + aufs_bindex_t bend, bindex, bstart; + unsigned char dlgt, shwh; + struct super_block *sb; + struct file *hf; + + AuTraceEnter(); + + err = -ENOMEM; + bend = au_fbend(arg->file); + arg->delist = kmalloc(sizeof(*arg->delist) * (bend + 1), GFP_NOFS); + if (unlikely(!arg->delist)) + goto out; + arg->whlist = kmalloc(sizeof(*arg->whlist) * (bend + 1), GFP_NOFS); + if (unlikely(!arg->whlist)) + goto out_delist; + err = 0; + for (bindex = 0; bindex <= bend; bindex++) { + au_nhash_init(arg->delist + bindex); + au_nhash_init(arg->whlist + bindex); + } + + sb = arg->file->f_dentry->d_sb; + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + arg->flags = 0; + shwh = 0; + if (unlikely(au_opt_test(mnt_flags, SHWH))) { + shwh = 1; + au_fset_fillvdir(arg->flags, SHWH); + } + bstart = au_fbstart(arg->file); + for (bindex = bstart; !err && bindex <= bend; bindex++) { + hf = au_h_fptr(arg->file, bindex); + if (!hf) + continue; + + offset = vfsub_llseek(hf, 0, SEEK_SET); + err = offset; + if (unlikely(offset)) + break; + arg->bindex = bindex; + do { + arg->err = 0; + au_fclr_fillvdir(arg->flags, CALLED); + /* smp_mb(); */ + err = vfsub_readdir(hf, fillvdir, arg, dlgt); + if (err >= 0) + err = arg->err; + } while (!err && au_ftest_fillvdir(arg->flags, CALLED)); + } + + if (unlikely(!err && shwh)) + err = au_handle_shwh(sb, arg->vdir, bstart, bend, arg->whlist, + arg->delist); + + for (bindex = bstart; bindex <= bend; bindex++) { + free_dehlist(arg->delist + bindex); + au_nhash_fin(arg->whlist + bindex); + } + kfree(arg->whlist); + + out_delist: + kfree(arg->delist); + out: + AuTraceErr(err); + return err; +} + +static int read_vdir(struct file *file, int may_read) +{ + int err; + unsigned long expire; + struct fillvdir_arg arg; + unsigned char do_read; + struct dentry *dentry; + struct inode *inode; + struct au_vdir *vdir, *allocated; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, may %d\n", AuDLNPair(dentry), may_read); + FiMustWriteLock(file); + inode = dentry->d_inode; + IMustLock(inode); + IiMustWriteLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode)); + + err = 0; + allocated = NULL; + do_read = 0; + sb = inode->i_sb; + expire = au_sbi(sb)->si_rdcache; + vdir = au_ivdir(inode); + if (!vdir) { + AuDebugOn(au_fvdir_cache(file)); + do_read = 1; + vdir = alloc_vdir(); + err = PTR_ERR(vdir); + if (IS_ERR(vdir)) + goto out; + err = 0; + allocated = vdir; + } else if (may_read + && (inode->i_version != vdir->vd_version + || time_after(jiffies, vdir->vd_jiffy + expire))) { + LKTRTrace("iver %llu, vdver %lu, exp %lu\n", + (unsigned long long)inode->i_version, + vdir->vd_version, vdir->vd_jiffy + expire); + do_read = 1; + err = reinit_vdir(vdir); + if (unlikely(err)) + goto out; + } + + if (!do_read) + return 0; /* success */ + + arg.file = file; + arg.vdir = vdir; + err = au_do_read_vdir(&arg); + if (!err) { + /* todo: necessary? */ + /* file->f_pos = 0; */ + vdir->vd_version = inode->i_version; + vdir->vd_last.i = 0; + vdir->vd_last.p.deblk = vdir->vd_deblk[0]; + if (allocated) + au_set_ivdir(inode, allocated); + } else if (allocated) + au_vdir_free(allocated); + + out: + AuTraceErr(err); + return err; +} + +static int copy_vdir(struct au_vdir *tgt, struct au_vdir *src) +{ + int err, i, rerr, n; + + AuTraceEnter(); + AuDebugOn(tgt->vd_nblk != 1); + + err = -ENOMEM; + if (tgt->vd_nblk < src->vd_nblk) { + au_vdir_deblk_t **p; + p = au_kzrealloc(tgt->vd_deblk, sizeof(*p) * tgt->vd_nblk, + sizeof(*p) * src->vd_nblk, GFP_NOFS); + if (unlikely(!p)) + goto out; + tgt->vd_deblk = p; + } + + tgt->vd_nblk = src->vd_nblk; + n = src->vd_nblk; + memcpy(tgt->vd_deblk[0], src->vd_deblk[0], AuSize_DEBLK); + /* tgt->vd_last.i = 0; */ + /* tgt->vd_last.p.deblk = tgt->vd_deblk[0]; */ + tgt->vd_version = src->vd_version; + tgt->vd_jiffy = src->vd_jiffy; + + for (i = 1; i < n; i++) { + tgt->vd_deblk[i] = kmalloc(AuSize_DEBLK, GFP_NOFS); + if (tgt->vd_deblk[i]) + memcpy(tgt->vd_deblk[i], src->vd_deblk[i], + AuSize_DEBLK); + else + goto out; + } + /* smp_mb(); */ + return 0; /* success */ + + out: + rerr = reinit_vdir(tgt); + BUG_ON(rerr); + AuTraceErr(err); + return err; +} + +int au_vdir_init(struct file *file) +{ + int err; + struct dentry *dentry; + struct inode *inode; + struct au_vdir *vdir_cache, *allocated; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + FiMustWriteLock(file); + inode = dentry->d_inode; + IiMustWriteLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode)); + + err = read_vdir(file, !file->f_pos); + if (unlikely(err)) + goto out; + + allocated = NULL; + vdir_cache = au_fvdir_cache(file); + if (!vdir_cache) { + vdir_cache = alloc_vdir(); + err = PTR_ERR(vdir_cache); + if (IS_ERR(vdir_cache)) + goto out; + allocated = vdir_cache; + } else if (!file->f_pos && vdir_cache->vd_version != file->f_version) { + err = reinit_vdir(vdir_cache); + if (unlikely(err)) + goto out; + } else + return 0; /* success */ + + err = copy_vdir(vdir_cache, au_ivdir(inode)); + if (!err) { + file->f_version = inode->i_version; + if (allocated) + au_set_fvdir_cache(file, allocated); + } else if (allocated) + au_vdir_free(allocated); + + out: + AuTraceErr(err); + return err; +} + +static loff_t calc_offset(struct au_vdir *vdir) +{ + loff_t offset; + union au_vdir_deblk_p p; + + p.deblk = vdir->vd_deblk[vdir->vd_last.i]; + offset = vdir->vd_last.p.p - p.p; + offset += sizeof(*p.deblk) * vdir->vd_last.i; + return offset; +} + +/* returns true or false */ +static int seek_vdir(struct file *file) +{ + int valid, i, n; + struct dentry *dentry; + struct au_vdir *vdir_cache; + loff_t offset; + union au_vdir_deblk_p p, deblk_end; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + vdir_cache = au_fvdir_cache(file); + AuDebugOn(!vdir_cache); + + valid = 1; + offset = calc_offset(vdir_cache); + LKTRTrace("offset %lld\n", offset); + if (file->f_pos == offset) + goto out; + + vdir_cache->vd_last.i = 0; + vdir_cache->vd_last.p.deblk = vdir_cache->vd_deblk[0]; + if (!file->f_pos) + goto out; + + valid = 0; + i = file->f_pos / AuSize_DEBLK; + LKTRTrace("i %d\n", i); + if (i >= vdir_cache->vd_nblk) + goto out; + + n = vdir_cache->vd_nblk; + for (; i < n; i++) { + p.deblk = vdir_cache->vd_deblk[i]; + deblk_end.deblk = p.deblk + 1; + offset = i; + offset *= AuSize_DEBLK; + while (!is_deblk_end(&p, &deblk_end) && offset < file->f_pos) { + int l; + l = calc_size(p.de->de_str.len); + offset += l; + p.p += l; + } + if (!is_deblk_end(&p, &deblk_end)) { + valid = 1; + vdir_cache->vd_last.i = i; + vdir_cache->vd_last.p = p; + break; + } + } + + out: + /* smp_mb(); */ + AuTraceErr(!valid); + return valid; +} + +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir) +{ + int err, l; + struct dentry *dentry; + struct au_vdir *vdir_cache; + struct au_vdir_de *de; + union au_vdir_deblk_p deblk_end; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + vdir_cache = au_fvdir_cache(file); + AuDebugOn(!vdir_cache); + + if (!seek_vdir(file)) + return 0; + + while (1) { + deblk_end.deblk + = vdir_cache->vd_deblk[vdir_cache->vd_last.i] + 1; + while (!is_deblk_end(&vdir_cache->vd_last.p, &deblk_end)) { + de = vdir_cache->vd_last.p.de; + LKTRTrace("%.*s, off%lld, i%lu, dt%d\n", + de->de_str.len, de->de_str.name, + file->f_pos, (unsigned long)de->de_ino, + de->de_type); + err = filldir(dirent, de->de_str.name, de->de_str.len, + file->f_pos, de->de_ino, de->de_type); + if (unlikely(err)) { + AuTraceErr(err); + /* todo: ignore the error caused by udba? */ + /* return err; */ + return 0; + } + + l = calc_size(de->de_str.len); + vdir_cache->vd_last.p.p += l; + file->f_pos += l; + } + if (vdir_cache->vd_last.i < vdir_cache->vd_nblk - 1) { + vdir_cache->vd_last.i++; + vdir_cache->vd_last.p.deblk + = vdir_cache->vd_deblk[vdir_cache->vd_last.i]; + file->f_pos = sizeof(*vdir_cache->vd_last.p.deblk) + * vdir_cache->vd_last.i; + continue; + } + break; + } + + /* smp_mb(); */ + return 0; +} --- linux-2.6.28.orig/ubuntu/aufs/dinfo.c +++ linux-2.6.28/ubuntu/aufs/dinfo.c @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * dentry private data + * + * $Id: dinfo.c,v 1.7 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +int au_alloc_dinfo(struct dentry *dentry) +{ + struct au_dinfo *dinfo; + struct super_block *sb; + int nbr; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(dentry->d_fsdata); + + dinfo = au_cache_alloc_dinfo(); + if (dinfo) { + sb = dentry->d_sb; + nbr = au_sbend(sb) + 1; + if (unlikely(nbr <= 0)) + nbr = 1; + dinfo->di_hdentry = kcalloc(nbr, sizeof(*dinfo->di_hdentry), + GFP_NOFS); + if (dinfo->di_hdentry) { + au_h_dentry_init_all(dinfo->di_hdentry, nbr); + atomic_set(&dinfo->di_generation, au_sigen(sb)); + /* smp_mb(); */ /* atomic_set */ + au_rw_init_wlock_nested(&dinfo->di_rwsem, + AuLsc_DI_CHILD); + dinfo->di_bstart = -1; + dinfo->di_bend = -1; + dinfo->di_bwh = -1; + dinfo->di_bdiropq = -1; + + dentry->d_fsdata = dinfo; + dentry->d_op = &aufs_dop; + return 0; /* success */ + } + au_cache_free_dinfo(dinfo); + } + AuTraceErr(-ENOMEM); + return -ENOMEM; +} + +struct au_dinfo *au_di(struct dentry *dentry) +{ + struct au_dinfo *dinfo = dentry->d_fsdata; + AuDebugOn(!dinfo + || !dinfo->di_hdentry + /* || au_sbi(dentry->d_sb)->si_bend < dinfo->di_bend */ + || dinfo->di_bend < dinfo->di_bstart + /* dbwh can be outside of this range */ + || (0 <= dinfo->di_bdiropq + && (dinfo->di_bdiropq < dinfo->di_bstart + /* || dinfo->di_bend < dinfo->di_bdiropq */)) + ); + return dinfo; +} + +/* ---------------------------------------------------------------------- */ + +static void do_ii_write_lock(struct inode *inode, unsigned int lsc) +{ + switch (lsc) { + case AuLsc_DI_CHILD: + ii_write_lock_child(inode); + break; + case AuLsc_DI_CHILD2: + ii_write_lock_child2(inode); + break; + case AuLsc_DI_CHILD3: + ii_write_lock_child3(inode); + break; + case AuLsc_DI_PARENT: + ii_write_lock_parent(inode); + break; + case AuLsc_DI_PARENT2: + ii_write_lock_parent2(inode); + break; + case AuLsc_DI_PARENT3: + ii_write_lock_parent3(inode); + break; + case AuLsc_DI_PARENT4: + ii_write_lock_parent4(inode); + break; + default: + BUG(); + } +} + +static void do_ii_read_lock(struct inode *inode, unsigned int lsc) +{ + switch (lsc) { + case AuLsc_DI_CHILD: + ii_read_lock_child(inode); + break; + case AuLsc_DI_CHILD2: + ii_read_lock_child2(inode); + break; + case AuLsc_DI_CHILD3: + ii_read_lock_child3(inode); + break; + case AuLsc_DI_PARENT: + ii_read_lock_parent(inode); + break; + case AuLsc_DI_PARENT2: + ii_read_lock_parent2(inode); + break; + case AuLsc_DI_PARENT3: + ii_read_lock_parent3(inode); + break; + case AuLsc_DI_PARENT4: + ii_read_lock_parent4(inode); + break; + default: + BUG(); + } +} + +void di_read_lock(struct dentry *d, int flags, unsigned int lsc) +{ + LKTRTrace("%.*s, %u\n", AuDLNPair(d), lsc); + SiMustAnyLock(d->d_sb); + + /* todo: always nested? */ + au_rw_read_lock_nested(&au_di(d)->di_rwsem, lsc); + if (d->d_inode) { + if (au_ftest_lock(flags, IW)) + do_ii_write_lock(d->d_inode, lsc); + else if (au_ftest_lock(flags, IR)) + do_ii_read_lock(d->d_inode, lsc); + } +} + +void di_read_unlock(struct dentry *d, int flags) +{ + LKTRTrace("%.*s\n", AuDLNPair(d)); + SiMustAnyLock(d->d_sb); + + if (d->d_inode) { + if (au_ftest_lock(flags, IW)) + ii_write_unlock(d->d_inode); + else if (au_ftest_lock(flags, IR)) + ii_read_unlock(d->d_inode); + } + au_rw_read_unlock(&au_di(d)->di_rwsem); +} + +void di_downgrade_lock(struct dentry *d, int flags) +{ + SiMustAnyLock(d->d_sb); + + au_rw_dgrade_lock(&au_di(d)->di_rwsem); + if (d->d_inode && au_ftest_lock(flags, IR)) + ii_downgrade_lock(d->d_inode); +} + +void di_write_lock(struct dentry *d, unsigned int lsc) +{ + LKTRTrace("%.*s, %u\n", AuDLNPair(d), lsc); + SiMustAnyLock(d->d_sb); + + /* todo: always nested? */ + au_rw_write_lock_nested(&au_di(d)->di_rwsem, lsc); + if (d->d_inode) + do_ii_write_lock(d->d_inode, lsc); +} + +void di_write_unlock(struct dentry *d) +{ + LKTRTrace("%.*s\n", AuDLNPair(d)); + SiMustAnyLock(d->d_sb); + + if (d->d_inode) + ii_write_unlock(d->d_inode); + au_rw_write_unlock(&au_di(d)->di_rwsem); +} + +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir) +{ + AuTraceEnter(); + AuDebugOn(d1 == d2 + || d1->d_inode == d2->d_inode + || d1->d_sb != d2->d_sb); + + if (isdir && au_test_subdir(d1, d2)) { + di_write_lock_child(d1); + di_write_lock_child2(d2); + } else { + /* there should be no races */ + di_write_lock_child(d2); + di_write_lock_child2(d1); + } +} + +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir) +{ + AuTraceEnter(); + AuDebugOn(d1 == d2 + || d1->d_inode == d2->d_inode + || d1->d_sb != d2->d_sb); + + if (isdir && au_test_subdir(d1, d2)) { + di_write_lock_parent(d1); + di_write_lock_parent2(d2); + } else { + /* there should be no races */ + di_write_lock_parent(d2); + di_write_lock_parent2(d1); + } +} + +void di_write_unlock2(struct dentry *d1, struct dentry *d2) +{ + di_write_unlock(d1); + if (d1->d_inode == d2->d_inode) + au_rw_write_unlock(&au_di(d2)->di_rwsem); + else + di_write_unlock(d2); +} + +/* ---------------------------------------------------------------------- */ + +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex) +{ + struct dentry *d; + + DiMustAnyLock(dentry); + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) + return NULL; + AuDebugOn(bindex < 0 + /* || bindex > au_sbend(dentry->d_sb) */); + d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry; + AuDebugOn(d && (atomic_read(&d->d_count) <= 0)); + return d; +} + +aufs_bindex_t au_dbtail(struct dentry *dentry) +{ + aufs_bindex_t bend, bwh; + + bend = au_dbend(dentry); + if (0 <= bend) { + bwh = au_dbwh(dentry); + if (!bwh) + return bwh; + if (0 < bwh && bwh < bend) + return bwh - 1; + } + return bend; +} + +aufs_bindex_t au_dbtaildir(struct dentry *dentry) +{ + aufs_bindex_t bend, bopq; + + AuDebugOn(dentry->d_inode + && dentry->d_inode->i_mode + && !S_ISDIR(dentry->d_inode->i_mode)); + + bend = au_dbtail(dentry); + if (0 <= bend) { + bopq = au_dbdiropq(dentry); + AuDebugOn(bend < bopq); + if (0 <= bopq && bopq < bend) + bend = bopq; + } + return bend; +} + +#if 0 /* reserved for future use */ +aufs_bindex_t au_dbtail_generic(struct dentry *dentry) +{ + struct inode *inode; + + inode = dentry->d_inode; + if (inode && S_ISDIR(inode->i_mode)) + return au_dbtaildir(dentry); + else + return au_dbtail(dentry); +} +#endif + +/* ---------------------------------------------------------------------- */ + +void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex); + AuDebugOn((bindex >= 0 + && (bindex < au_dbstart(dentry) + || au_dbend(dentry) < bindex)) + || (dentry->d_inode + && dentry->d_inode->i_mode + && !S_ISDIR(dentry->d_inode->i_mode))); + au_di(dentry)->di_bdiropq = bindex; +} + +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_dentry) +{ + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; + DiMustWriteLock(dentry); + AuDebugOn(bindex < au_di(dentry)->di_bstart + || bindex > au_di(dentry)->di_bend + || (h_dentry && atomic_read(&h_dentry->d_count) <= 0) + || (h_dentry && hd->hd_dentry) + ); + if (hd->hd_dentry) + au_hdput(hd, /*do_free*/0); + hd->hd_dentry = h_dentry; +} + +/* ---------------------------------------------------------------------- */ + +void au_update_dbrange(struct dentry *dentry, int do_put_zero) +{ + struct au_dinfo *dinfo; + aufs_bindex_t bindex; + struct dentry *h_d; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), do_put_zero); + DiMustWriteLock(dentry); + + dinfo = au_di(dentry); + if (unlikely(!dinfo) || dinfo->di_bstart < 0) + return; + + if (do_put_zero) { + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; + bindex++) { + h_d = dinfo->di_hdentry[0 + bindex].hd_dentry; + if (h_d && !h_d->d_inode) + au_set_h_dptr(dentry, bindex, NULL); + } + } + + dinfo->di_bstart = -1; + while (++dinfo->di_bstart <= dinfo->di_bend) + if (dinfo->di_hdentry[0 + dinfo->di_bstart].hd_dentry) + break; + if (dinfo->di_bstart > dinfo->di_bend) { + dinfo->di_bstart = -1; + dinfo->di_bend = -1; + return; + } + + dinfo->di_bend++; + while (0 <= --dinfo->di_bend) + if (dinfo->di_hdentry[0 + dinfo->di_bend].hd_dentry) + break; + AuDebugOn(dinfo->di_bstart > dinfo->di_bend || dinfo->di_bend < 0); +} + +void au_update_dbstart(struct dentry *dentry) +{ + aufs_bindex_t bindex, + bstart = au_dbstart(dentry), + bend = au_dbend(dentry); + struct dentry *h_dentry; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + DiMustWriteLock(dentry); + + for (bindex = bstart; bindex <= bend; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + if (h_dentry->d_inode) { + au_set_dbstart(dentry, bindex); + return; + } + au_set_h_dptr(dentry, bindex, NULL); + } +} + +void au_update_dbend(struct dentry *dentry) +{ + aufs_bindex_t bindex, + bstart = au_dbstart(dentry), + bend = au_dbend(dentry); + struct dentry *h_dentry; + + DiMustWriteLock(dentry); + for (bindex = bend; bindex <= bstart; bindex--) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + if (h_dentry->d_inode) { + au_set_dbend(dentry, bindex); + return; + } + au_set_h_dptr(dentry, bindex, NULL); + } +} + +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry) +{ + aufs_bindex_t bindex, bend; + + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) + if (au_h_dptr(dentry, bindex) == h_dentry) + return bindex; + return -1; +} --- linux-2.6.28.orig/ubuntu/aufs/branch.h +++ linux-2.6.28/ubuntu/aufs/branch.h @@ -0,0 +1,393 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * branch filesystems and xino for them + * + * $Id: branch.h,v 1.12 2008/09/15 03:14:03 sfjro Exp $ + */ + +#ifndef __AUFS_BRANCH_H__ +#define __AUFS_BRANCH_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include "misc.h" +#include "super.h" + +/* ---------------------------------------------------------------------- */ + +/* an entry in a xino file */ +struct au_xino_entry { + ino_t ino; + /* __u32 h_gen; */ /* reserved for future use */ +} __packed; + +/* reserved for future use */ +/* #define AuXino_INVALID_HGEN (-1) */ + +/* a xino file */ +struct au_xino_file { + struct file *xi_file; + struct mutex xi_nondir_mtx; + + /* reserved for future use */ +#if 0 + struct file **xi_file; + + /* array management */ + unsigned long long xi_limit; /* Max xino file size */ + unsigned long long xi_size; /* s_maxbytes */ + + /* truncation */ + unsigned long long xi_upper; /* watermark in bytes */ + unsigned long long xi_step; /* to next watermark in bytes */ + + /* truncation */ + blkcnt_t xi_upper; /* watermark in blocks */ + atomic_t xi_running; +#endif +}; + +/* members for writable branch only */ +enum {AuBrWh_BASE, AuBrWh_PLINK, AuBrWh_TMP, AuBrWh_Last}; +struct au_wbr { + struct au_rwsem wbr_wh_rwsem; + struct dentry *wbr_wh[AuBrWh_Last]; + atomic_t wbr_wh_running; +#define wbr_whbase wbr_wh[AuBrWh_BASE] /* whiteout base */ +#define wbr_plink wbr_wh[AuBrWh_PLINK] /* pseudo-link dir */ +#define wbr_tmp wbr_wh[AuBrWh_TMP] /* temporary dir */ + + /* mfs mode */ + unsigned long long wbr_bytes; +}; + +/* protected by superblock rwsem */ +struct au_branch { + struct au_xino_file br_xino; + + aufs_bindex_t br_id; + + int br_perm; + struct vfsmount *br_mnt; + atomic_t br_count; + + struct au_wbr *br_wbr; + +#if 1 /* reserved for future use */ + /* xino truncation */ + blkcnt_t br_xino_upper; /* watermark in blocks */ + atomic_t br_xino_running; +#endif + +#ifdef CONFIG_SYSFS + /* an entry under sysfs per mount-point */ + char br_name[8]; + struct attribute br_attr; +#endif + + au_gen_t br_generation; +}; + +/* ---------------------------------------------------------------------- */ + +/* branch permission and attribute */ +enum { + AuBrPerm_RW, /* writable, linkable wh */ + AuBrPerm_RO, /* readonly, no wh */ + AuBrPerm_RR, /* natively readonly, no wh */ + + AuBrPerm_RWNoLinkWH, /* un-linkable whiteouts */ + + AuBrPerm_ROWH, + AuBrPerm_RRWH, /* whiteout-able */ + + AuBrPerm_Last +}; + +static inline int au_br_writable(int brperm) +{ + return (brperm == AuBrPerm_RW || brperm == AuBrPerm_RWNoLinkWH); +} + +static inline int au_br_whable(int brperm) +{ + return (brperm == AuBrPerm_RW + || brperm == AuBrPerm_ROWH + || brperm == AuBrPerm_RRWH); +} + +#if 0 /* reserved for future use */ +static inline int au_br_linkable_wh(int brperm) +{ + return (brperm == AuBrPerm_RW); +} +#endif + +static inline int au_br_hinotifyable(int brperm) +{ +#ifdef CONFIG_AUFS_HINOTIFY + return (brperm != AuBrPerm_RR && brperm != AuBrPerm_RRWH); +#else + return 0; +#endif +} + +/* ---------------------------------------------------------------------- */ + +/* branch.c */ +struct au_sbinfo; +void au_br_free(struct au_sbinfo *sinfo); +int au_test_def_rr(struct super_block *h_sb); +int au_br_index(struct super_block *sb, aufs_bindex_t br_id); +struct au_opt_add; +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); +struct au_opt_del; +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); +struct au_opt_mod; +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, + int *do_update); + +/* xino.c */ +#define Au_LOFF_MAX ((loff_t)LLONG_MAX) +int au_xib_trunc(struct super_block *sb); +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, + loff_t *pos); +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, + loff_t *pos); +struct file *au_xino_create(struct super_block *sb, char *fname, int silent); +struct file *au_xino_create2(struct super_block *sb, struct file *base_file, + struct file *copy_src); +ino_t au_xino_new_ino(struct super_block *sb); +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + ino_t ino); +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe); +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe); +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t hino, + struct file *base_file, int do_test); +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex); + +struct au_opt_xino; +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount); +void au_xino_clr(struct super_block *sb); +struct file *au_xino_def(struct super_block *sb); + +struct au_opt_xinodir; +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for future use */ +/* export.c */ +int au_xinodir_br(struct super_block *sb, struct au_branch *br, ino_t hino, + int do_test); +int au_xinodir_set(struct super_block *sb, struct au_opt_xinodir *xinodir, + int remount); +#else +static inline +int au_xinodir_br(struct super_block *sb, struct au_branch *br, ino_t hino, + int do_test) +{ + return 0; +} + +static inline +int au_xinodir_set(struct super_block *sb, struct au_opt_xinodir *xinodir, + int remount) +{ + return 0; +} +#endif + +/* ---------------------------------------------------------------------- */ + +/* todo: memory barrier? */ +static inline int au_br_count(struct au_branch *br) +{ + return atomic_read(&br->br_count); +} + +static inline int au_br_get(struct au_branch *br) +{ + return atomic_inc_return(&br->br_count); +} + +static inline int au_br_put(struct au_branch *br) +{ + return atomic_dec_return(&br->br_count); +} + +static inline au_gen_t au_br_gen(struct au_branch *br) +{ + return br->br_generation; +} + +/* + * test if the @br is readonly or not. + */ +static inline int au_br_rdonly(struct au_branch *br) +{ + return ((br->br_mnt->mnt_sb->s_flags & MS_RDONLY) + || !au_br_writable(br->br_perm)) + ? -EROFS : 0; +} + +/* ---------------------------------------------------------------------- */ + +/* Superblock to branch */ +static inline +aufs_bindex_t au_sbr_id(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr(sb, bindex)->br_id; +} + +static inline +struct vfsmount *au_sbr_mnt(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr(sb, bindex)->br_mnt; +} + +static inline +struct super_block *au_sbr_sb(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr_mnt(sb, bindex)->mnt_sb; +} + +#if 0 /* reserved for future use */ +static inline int au_sbr_count(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_br_count(au_sbr(sb, bindex)); +} + +static inline void au_sbr_get(struct super_block *sb, aufs_bindex_t bindex) +{ + au_br_get(au_sbr(sb, bindex)); +} +#endif + +static inline void au_sbr_put(struct super_block *sb, aufs_bindex_t bindex) +{ + au_br_put(au_sbr(sb, bindex)); +} + +static inline int au_sbr_perm(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_sbr(sb, bindex)->br_perm; +} + +static inline int au_sbr_whable(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_br_whable(au_sbr_perm(sb, bindex)); +} + +static inline int au_test_trunc_xino(struct super_block *sb) +{ + return au_test_tmpfs(sb); +} + +/* temporary support for i#1 in cramfs */ +static inline int au_test_unique_ino(struct dentry *h_dentry, ino_t h_ino) +{ +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) + if (unlikely(h_dentry->d_sb->s_magic == CRAMFS_MAGIC)) + return (h_ino != 1); +#endif + return 1; +} + +static inline struct vfsmount *au_do_nfsmnt(struct vfsmount *h_mnt) +{ + if (!au_test_nfs(h_mnt->mnt_sb)) + return NULL; + return h_mnt; +} + +static inline void au_br_nfs_lockdep_off(struct super_block *sb) +{ + if (au_test_nfs(sb)) + lockdep_off(); +} + +static inline void au_br_nfs_lockdep_on(struct super_block *sb) +{ + /* hoping this condition will be optimized... */ + if (au_test_nfs(sb)) + lockdep_on(); +} + +#ifdef CONFIG_AUFS_BR_NFS +static inline int au_test_unsupported_nfs(struct super_block *h_sb) +{ + return 0; +} + +/* it doesn't mntget() */ +static inline +struct vfsmount *au_nfsmnt(struct super_block *sb, aufs_bindex_t bindex) +{ + return au_do_nfsmnt(au_sbr_mnt(sb, bindex)); +} + +#define AuNoNfsBranchMsg "dummy" + +#else +static inline int au_test_unsupported_nfs(struct super_block *h_sb) +{ + return (h_sb->s_magic == NFS_SUPER_MAGIC); +} + +static inline +struct vfsmount *au_nfsmnt(struct super_block *sb, aufs_bindex_t bindex) +{ + return NULL; +} + +#define AuNoNfsBranchMsg "NFS branch is not supported" \ + ", try some configurations and patches included in aufs source CVS." + +#endif /* CONFIG_AUFS_BR_NFS */ + +/* ---------------------------------------------------------------------- */ + +/* + * br_wh_read_lock, br_wh_write_lock + * br_wh_read_unlock, br_wh_write_unlock, br_wh_downgrade_lock + */ +AuSimpleRwsemFuncs(wbr_wh, struct au_wbr *wbr, wbr->wbr_wh_rwsem); + +/* to debug easier, do not make them inlined functions */ +#define WbrWhMustReadLock(wbr) do { \ + /* SiMustAnyLock(sb); */ \ + AuRwMustReadLock(&(wbr)->wbr_wh_rwsem); \ +} while (0) + +#define WbrWhMustWriteLock(wbr) do { \ + /* SiMustAnyLock(sb); */ \ + AuRwMustWriteLock(&(wbr)->wbr_wh_rwsem); \ +} while (0) + +#define WbrWhMustAnyLock(br) do { \ + /* SiMustAnyLock(sb); */ \ + AuRwMustAnyLock(&(wbr)->wbr_wh_rwsem); \ +} while (0) + +#endif /* __KERNEL__ */ +#endif /* __AUFS_BRANCH_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/cpup.h +++ linux-2.6.28/ubuntu/aufs/cpup.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * copy-up/down functions + * + * $Id: cpup.h,v 1.5 2008/09/01 02:54:48 sfjro Exp $ + */ + +#ifndef __AUFS_CPUP_H__ +#define __AUFS_CPUP_H__ + +#ifdef __KERNEL__ + +#include +#include + +void au_cpup_attr_timesizes(struct inode *inode); +void au_cpup_attr_nlink(struct inode *inode); +void au_cpup_attr_changeable(struct inode *inode); +void au_cpup_igen(struct inode *inode, struct inode *h_inode); +void au_cpup_attr_all(struct inode *inode); + +/* ---------------------------------------------------------------------- */ + +/* cpup flags */ +#define AuCpup_DTIME 1 /* do dtime_store/revert */ +#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, + for link(2) */ +#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) +#define au_fset_cpup(flags, name) { (flags) |= AuCpup_##name; } +#define au_fclr_cpup(flags, name) { (flags) &= ~AuCpup_##name; } + +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, unsigned int flags, + struct dentry *dst_parent); +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + unsigned int flags); +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + struct file *file); + +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg), + void *arg); +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst); + +/* ---------------------------------------------------------------------- */ + +/* keep timestamps when copyup */ +struct au_dtime { + struct dentry *dt_dentry, *dt_h_dentry; + struct au_hinode *dt_hinode, *dt_hdir; + struct timespec dt_atime, dt_mtime; +}; +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, + struct dentry *h_dentry, struct au_hinode *hinode, + struct au_hinode *hdir); +void au_dtime_revert(struct au_dtime *dt); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_CPUP_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/opts.c +++ linux-2.6.28/ubuntu/aufs/opts.c @@ -0,0 +1,1570 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * mount options/flags + * + * $Id: opts.c,v 1.15 2008/09/01 02:55:31 sfjro Exp $ + */ + +#include /* a distribution requires */ +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +enum { + Opt_br, + Opt_add, Opt_del, Opt_mod, Opt_reorder, Opt_append, Opt_prepend, + Opt_idel, Opt_imod, Opt_ireorder, + Opt_dirwh, Opt_rdcache, Opt_deblk, Opt_nhash, Opt_rendir, + Opt_xino, Opt_zxino, Opt_noxino, + Opt_trunc_xino, Opt_trunc_xino_v, Opt_notrunc_xino, + Opt_trunc_xino_path, Opt_itrunc_xino, + Opt_xinodir, + Opt_trunc_xib, Opt_notrunc_xib, + Opt_dirperm1, Opt_nodirperm1, + Opt_shwh, Opt_noshwh, + Opt_plink, Opt_noplink, Opt_list_plink, Opt_clean_plink, + Opt_udba, + /* Opt_lock, Opt_unlock, */ + Opt_cmd, Opt_cmd_args, + Opt_diropq_a, Opt_diropq_w, + Opt_warn_perm, Opt_nowarn_perm, + Opt_wbr_copyup, Opt_wbr_create, + Opt_coo, + Opt_dlgt, Opt_nodlgt, + Opt_refrof, Opt_norefrof, + Opt_verbose, Opt_noverbose, + Opt_tail, Opt_ignore, Opt_ignore_silent, Opt_err +}; + +static match_table_t options = { + {Opt_br, "br=%s"}, + {Opt_br, "br:%s"}, + + {Opt_add, "add=%d:%s"}, + {Opt_add, "add:%d:%s"}, + {Opt_add, "ins=%d:%s"}, + {Opt_add, "ins:%d:%s"}, + {Opt_append, "append=%s"}, + {Opt_append, "append:%s"}, + {Opt_prepend, "prepend=%s"}, + {Opt_prepend, "prepend:%s"}, + + {Opt_del, "del=%s"}, + {Opt_del, "del:%s"}, + /* {Opt_idel, "idel:%d"}, */ + {Opt_mod, "mod=%s"}, + {Opt_mod, "mod:%s"}, + {Opt_imod, "imod:%d:%s"}, + + {Opt_dirwh, "dirwh=%d"}, + {Opt_dirwh, "dirwh:%d"}, + + {Opt_xino, "xino=%s"}, + {Opt_xino, "xino:%s"}, +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for futur use */ + {Opt_xinodir, "xinodir=%s"}, + {Opt_xinodir, "xinodir:%s"}, +#endif + {Opt_noxino, "noxino"}, + {Opt_trunc_xino, "trunc_xino"}, + {Opt_trunc_xino_v, "trunc_xino_v=%d:%d"}, + {Opt_notrunc_xino, "notrunc_xino"}, + {Opt_trunc_xino_path, "trunc_xino=%s"}, + {Opt_trunc_xino_path, "trunc_xino:%s"}, + {Opt_itrunc_xino, "itrunc_xino=%d"}, + {Opt_itrunc_xino, "itrunc_xino:%d"}, + /* {Opt_zxino, "zxino=%s"}, */ + {Opt_trunc_xib, "trunc_xib"}, + {Opt_notrunc_xib, "notrunc_xib"}, + + {Opt_plink, "plink"}, + {Opt_noplink, "noplink"}, +#ifdef CONFIG_AUFS_DEBUG + {Opt_list_plink, "list_plink"}, +#endif + {Opt_clean_plink, "clean_plink"}, + + {Opt_udba, "udba=%s"}, + + {Opt_diropq_a, "diropq=always"}, + {Opt_diropq_a, "diropq=a"}, + {Opt_diropq_w, "diropq=whiteouted"}, + {Opt_diropq_w, "diropq=w"}, + + {Opt_warn_perm, "warn_perm"}, + {Opt_nowarn_perm, "nowarn_perm"}, + +#ifdef CONFIG_AUFS_DLGT + {Opt_dlgt, "dlgt"}, + {Opt_nodlgt, "nodlgt"}, + + {Opt_dirperm1, "dirperm1"}, + {Opt_nodirperm1, "nodirperm1"}, +#endif + +#ifdef CONFIG_AUFS_SHWH + {Opt_shwh, "shwh"}, + {Opt_noshwh, "noshwh"}, +#endif + + {Opt_rendir, "rendir=%d"}, + {Opt_rendir, "rendir:%d"}, + + {Opt_refrof, "refrof"}, + {Opt_norefrof, "norefrof"}, + + {Opt_verbose, "verbose"}, + {Opt_verbose, "v"}, + {Opt_noverbose, "noverbose"}, + {Opt_noverbose, "quiet"}, + {Opt_noverbose, "q"}, + {Opt_noverbose, "silent"}, + + {Opt_rdcache, "rdcache=%d"}, + {Opt_rdcache, "rdcache:%d"}, + + {Opt_coo, "coo=%s"}, + + {Opt_wbr_create, "create=%s"}, + {Opt_wbr_create, "create:%s"}, + {Opt_wbr_create, "create_policy=%s"}, + {Opt_wbr_create, "create_policy:%s"}, + {Opt_wbr_copyup, "cpup=%s"}, + {Opt_wbr_copyup, "cpup:%s"}, + {Opt_wbr_copyup, "copyup=%s"}, + {Opt_wbr_copyup, "copyup:%s"}, + {Opt_wbr_copyup, "copyup_policy=%s"}, + {Opt_wbr_copyup, "copyup_policy:%s"}, + + /* internal use for the scripts */ + {Opt_ignore_silent, "si=%s"}, + +#if 0 /* reserved for future use */ + {Opt_deblk, "deblk=%d"}, + {Opt_deblk, "deblk:%d"}, + {Opt_nhash, "nhash=%d"}, + {Opt_nhash, "nhash:%d"}, +#endif + + {Opt_br, "dirs=%s"}, + {Opt_ignore, "debug=%d"}, + {Opt_ignore, "delete=whiteout"}, + {Opt_ignore, "delete=all"}, + {Opt_ignore, "imap=%s"}, + + {Opt_err, NULL} +}; + +/* ---------------------------------------------------------------------- */ + +static const char *au_parser_pattern(int val, struct match_token *token) +{ + while (token->pattern) { + if (token->token == val) + return token->pattern; + token++; + } + BUG(); + return "??"; +} + +/* ---------------------------------------------------------------------- */ + +#define RW "rw" +#define RO "ro" +#define WH "wh" +#define RR "rr" +#define NoLinkWH "nolwh" + +static match_table_t brperms = { + {AuBrPerm_RR, RR}, + {AuBrPerm_RO, RO}, + {AuBrPerm_RW, RW}, + + {AuBrPerm_RRWH, RR "+" WH}, + {AuBrPerm_ROWH, RO "+" WH}, + {AuBrPerm_RWNoLinkWH, RW "+" NoLinkWH}, + + {AuBrPerm_ROWH, "nfsro"}, + {AuBrPerm_RO, NULL} +}; + +static noinline_for_stack int br_perm_val(char *perm) +{ + int val; + substring_t args[MAX_OPT_ARGS]; + + AuDebugOn(!perm || !*perm); + LKTRTrace("perm %s\n", perm); + val = match_token(perm, brperms, args); + AuTraceErr(val); + return val; +} + +const char *au_optstr_br_perm(int brperm) +{ + return au_parser_pattern(brperm, (void *)brperms); +} + +/* ---------------------------------------------------------------------- */ + +static match_table_t udbalevel = { + {AuOpt_UDBA_REVAL, "reval"}, +#ifdef CONFIG_AUFS_HINOTIFY + {AuOpt_UDBA_INOTIFY, "inotify"}, +#endif + {AuOpt_UDBA_NONE, "none"}, + {-1, NULL} +}; + +static noinline_for_stack int udba_val(char *str) +{ + substring_t args[MAX_OPT_ARGS]; + return match_token(str, udbalevel, args); +} + +const char *au_optstr_udba(int udba) +{ + return au_parser_pattern(udba, (void *)udbalevel); +} + +/* ---------------------------------------------------------------------- */ + +static match_table_t coolevel = { + {AuOpt_COO_NONE, "none"}, + {AuOpt_COO_LEAF, "leaf"}, + {AuOpt_COO_ALL, "all"}, + {-1, NULL} +}; + +static noinline_for_stack int coo_val(char *str) +{ + substring_t args[MAX_OPT_ARGS]; + return match_token(str, coolevel, args); +} + +const char *au_optstr_coo(int coo) +{ + return au_parser_pattern(coo, (void *)coolevel); +} + +/* ---------------------------------------------------------------------- */ + +static match_table_t au_wbr_create_policy = { + {AuWbrCreate_TDP, "tdp"}, + {AuWbrCreate_TDP, "top-down-parent"}, + {AuWbrCreate_RR, "rr"}, + {AuWbrCreate_RR, "round-robin"}, + {AuWbrCreate_MFS, "mfs"}, + {AuWbrCreate_MFS, "most-free-space"}, + {AuWbrCreate_MFSV, "mfs:%d"}, + {AuWbrCreate_MFSV, "most-free-space:%d"}, + + {AuWbrCreate_MFSRR, "mfsrr:%d"}, + {AuWbrCreate_MFSRRV, "mfsrr:%d:%d"}, + {AuWbrCreate_PMFS, "pmfs"}, + {AuWbrCreate_PMFSV, "pmfs:%d"}, + + {-1, NULL} +}; + +/* cf. linux/lib/parser.c */ +static int au_match_ull(substring_t *s, unsigned long long *result, int base) +{ + char *endp; + char *buf; + int ret; + + buf = kmalloc(s->to - s->from + 1, GFP_NOFS); + if (!buf) + return -ENOMEM; + memcpy(buf, s->from, s->to - s->from); + buf[s->to - s->from] = '\0'; + *result = simple_strtoull(buf, &endp, base); + ret = 0; + if (endp == buf) + ret = -EINVAL; + kfree(buf); + return ret; +} + +static int au_wbr_mfs_wmark(substring_t *arg, char *str, + struct au_opt_wbr_create *create) +{ + int err; + unsigned long long ull; + + err = 0; + if (!au_match_ull(arg, &ull, 0)) + create->mfsrr_watermark = ull; + else { + AuErr("bad integer in %s\n", str); + err = -EINVAL; + } + + AuTraceErr(err); + return err; +} + +static int au_wbr_mfs_sec(substring_t *arg, char *str, + struct au_opt_wbr_create *create) +{ + int n, err; + + err = 0; + if (!match_int(arg, &n) && 0 <= n) + create->mfs_second = n; + else { + AuErr("bad integer in %s\n", str); + err = -EINVAL; + } + + AuTraceErr(err); + return err; +} + +static noinline_for_stack +int au_wbr_create_val(char *str, struct au_opt_wbr_create *create) +{ + int err, e; + substring_t args[MAX_OPT_ARGS]; + + err = match_token(str, au_wbr_create_policy, args); + create->wbr_create = err; + switch (err) { + case AuWbrCreate_MFSRRV: + e = au_wbr_mfs_wmark(&args[0], str, create); + if (!e) + e = au_wbr_mfs_sec(&args[1], str, create); + if (unlikely(e)) + err = e; + break; + case AuWbrCreate_MFSRR: + e = au_wbr_mfs_wmark(&args[0], str, create); + if (unlikely(e)) { + err = e; + break; + } + /*FALLTHROUGH*/ + case AuWbrCreate_MFS: + case AuWbrCreate_PMFS: + create->mfs_second = AUFS_MFS_SECOND_DEF; + break; + case AuWbrCreate_MFSV: + case AuWbrCreate_PMFSV: + e = au_wbr_mfs_sec(&args[0], str, create); + if (unlikely(e)) + err = e; + break; + } + + return err; +} + +const char *au_optstr_wbr_create(int wbr_create) +{ + return au_parser_pattern(wbr_create, (void *)au_wbr_create_policy); +} + +static match_table_t au_wbr_copyup_policy = { + {AuWbrCopyup_TDP, "tdp"}, + {AuWbrCopyup_TDP, "top-down-parent"}, + {AuWbrCopyup_BUP, "bup"}, + {AuWbrCopyup_BUP, "bottom-up-parent"}, + {AuWbrCopyup_BU, "bu"}, + {AuWbrCopyup_BU, "bottom-up"}, + {-1, NULL} +}; + +static noinline_for_stack int au_wbr_copyup_val(char *str) +{ + substring_t args[MAX_OPT_ARGS]; + return match_token(str, au_wbr_copyup_policy, args); +} + +const char *au_optstr_wbr_copyup(int wbr_copyup) +{ + return au_parser_pattern(wbr_copyup, (void *)au_wbr_copyup_policy); +} + +/* ---------------------------------------------------------------------- */ + +static const int lkup_dirflags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY; + +static void dump_opts(struct au_opts *opts) +{ +#ifdef CONFIG_AUFS_DEBUG + /* reduce stack space */ + union { + struct au_opt_add *add; + struct au_opt_del *del; + struct au_opt_mod *mod; + struct au_opt_xino *xino; + struct au_opt_xinodir *xinodir; + struct au_opt_xino_itrunc *xino_itrunc; + struct au_opt_wbr_create *create; + } u; + struct au_opt *opt; + + AuTraceEnter(); + + opt = opts->opt; + while (/* opt < opts_tail && */ opt->type != Opt_tail) { + switch (opt->type) { + case Opt_add: + u.add = &opt->add; + LKTRTrace("add {b%d, %s, 0x%x, %p}\n", + u.add->bindex, u.add->path, u.add->perm, + u.add->nd.path.dentry); + break; + case Opt_del: + case Opt_idel: + u.del = &opt->del; + LKTRTrace("del {%s, %p}\n", u.del->path, u.del->h_root); + break; + case Opt_mod: + case Opt_imod: + u.mod = &opt->mod; + LKTRTrace("mod {%s, 0x%x, %p}\n", + u.mod->path, u.mod->perm, u.mod->h_root); + break; + case Opt_append: + u.add = &opt->add; + LKTRTrace("append {b%d, %s, 0x%x, %p}\n", + u.add->bindex, u.add->path, u.add->perm, + u.add->nd.path.dentry); + break; + case Opt_prepend: + u.add = &opt->add; + LKTRTrace("prepend {b%d, %s, 0x%x, %p}\n", + u.add->bindex, u.add->path, u.add->perm, + u.add->nd.path.dentry); + break; + case Opt_dirwh: + LKTRTrace("dirwh %d\n", opt->dirwh); + break; + case Opt_rdcache: + LKTRTrace("rdcache %d\n", opt->rdcache); + break; + case Opt_xino: + u.xino = &opt->xino; + LKTRTrace("xino {%s %.*s}\n", + u.xino->path, + AuDLNPair(u.xino->file->f_dentry)); + break; + case Opt_xinodir: + u.xinodir = &opt->xinodir; + LKTRTrace("xinodir {%s %.*s}\n", + u.xinodir->name, + AuDLNPair(u.xinodir->path.dentry)); + break; + case Opt_trunc_xino: + LKTRLabel(trunc_xino); + break; + case Opt_notrunc_xino: + LKTRLabel(notrunc_xino); + break; + case Opt_trunc_xino_path: + case Opt_itrunc_xino: + u.xino_itrunc = &opt->xino_itrunc; + LKTRTrace("trunc_xino %d\n", u.xino_itrunc->bindex); + break; + + case Opt_noxino: + LKTRLabel(noxino); + break; + case Opt_trunc_xib: + LKTRLabel(trunc_xib); + break; + case Opt_notrunc_xib: + LKTRLabel(notrunc_xib); + break; + case Opt_dirperm1: + LKTRLabel(dirperm1); + break; + case Opt_nodirperm1: + LKTRLabel(nodirperm1); + break; + case Opt_shwh: + LKTRLabel(shwh); + break; + case Opt_noshwh: + LKTRLabel(noshwh); + break; + case Opt_plink: + LKTRLabel(plink); + break; + case Opt_noplink: + LKTRLabel(noplink); + break; + case Opt_list_plink: + LKTRLabel(list_plink); + break; + case Opt_clean_plink: + LKTRLabel(clean_plink); + break; + case Opt_udba: + LKTRTrace("udba %d, %s\n", + opt->udba, au_optstr_udba(opt->udba)); + break; + case Opt_diropq_a: + LKTRLabel(diropq_a); + break; + case Opt_diropq_w: + LKTRLabel(diropq_w); + break; + case Opt_warn_perm: + LKTRLabel(warn_perm); + break; + case Opt_nowarn_perm: + LKTRLabel(nowarn_perm); + break; + case Opt_dlgt: + LKTRLabel(dlgt); + break; + case Opt_nodlgt: + LKTRLabel(nodlgt); + break; + case Opt_refrof: + LKTRLabel(refrof); + break; + case Opt_norefrof: + LKTRLabel(norefrof); + break; + case Opt_verbose: + LKTRLabel(verbose); + break; + case Opt_noverbose: + LKTRLabel(noverbose); + break; + case Opt_coo: + LKTRTrace("coo %d, %s\n", + opt->coo, au_optstr_coo(opt->coo)); + break; + case Opt_wbr_create: + u.create = &opt->wbr_create; + LKTRTrace("create %d, %s\n", u.create->wbr_create, + au_optstr_wbr_create(u.create->wbr_create)); + switch (u.create->wbr_create) { + case AuWbrCreate_MFSV: + case AuWbrCreate_PMFSV: + LKTRTrace("%d sec\n", u.create->mfs_second); + break; + case AuWbrCreate_MFSRR: + LKTRTrace("%llu watermark\n", + u.create->mfsrr_watermark); + break; + case AuWbrCreate_MFSRRV: + LKTRTrace("%llu watermark, %d sec\n", + u.create->mfsrr_watermark, + u.create->mfs_second); + break; + } + break; + case Opt_wbr_copyup: + LKTRTrace("copyup %d, %s\n", opt->wbr_copyup, + au_optstr_wbr_copyup(opt->wbr_copyup)); + break; + default: + BUG(); + } + opt++; + } +#endif +} + +void au_opts_free(struct au_opts *opts) +{ + struct au_opt *opt; + + AuTraceEnter(); + + opt = opts->opt; + while (opt->type != Opt_tail) { + switch (opt->type) { + case Opt_add: + case Opt_append: + case Opt_prepend: + path_put(&opt->add.nd.path); + break; + case Opt_del: + case Opt_idel: + dput(opt->del.h_root); + break; + case Opt_mod: + case Opt_imod: + dput(opt->mod.h_root); + break; + case Opt_xino: + fput(opt->xino.file); + break; + case Opt_xinodir: + path_put(&opt->xinodir.path); + break; + } + opt++; + } +} + +static int opt_add(struct au_opt *opt, char *opt_str, struct super_block *sb, + aufs_bindex_t bindex) +{ + int err; + struct au_opt_add *add = &opt->add; + char *p; + + LKTRTrace("%s, b%d\n", opt_str, bindex); + + add->bindex = bindex; + add->perm = AuBrPerm_Last; + add->path = opt_str; + p = strchr(opt_str, '='); + if (unlikely(p)) { + *p++ = 0; + if (*p) + add->perm = br_perm_val(p); + } + + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(add->path, lkup_dirflags, &add->nd); + if (!err) { + if (!p /* && add->perm == AuBrPerm_Last */) { + add->perm = AuBrPerm_RO; + if (au_test_def_rr(add->nd.path.dentry->d_sb)) + add->perm = AuBrPerm_RR; + if (!bindex && !(sb->s_flags & MS_RDONLY)) + add->perm = AuBrPerm_RW; +#ifdef CONFIG_AUFS_COMPAT + add->perm = AuBrPerm_RW; +#endif + } + opt->type = Opt_add; + goto out; + } + AuErr("lookup failed %s (%d)\n", add->path, err); + err = -EINVAL; + + out: + AuTraceErr(err); + return err; +} + +/* called without aufs lock */ +int au_opts_parse(struct super_block *sb, unsigned long flags, char *str, + struct au_opts *opts) +{ + int err, n, token; + struct dentry *root; + struct au_opt *opt, *opt_tail; + char *opt_str, *p; + aufs_bindex_t bindex, bend; + unsigned char skipped; + union { + struct au_opt_del *del; + struct au_opt_mod *mod; + struct au_opt_xino *xino; + struct au_opt_xinodir *xinodir; + struct au_opt_xino_itrunc *xino_itrunc; + struct au_opt_wbr_create *create; + } u; + struct file *file; + /* reduce the stack space */ + struct { + substring_t args[MAX_OPT_ARGS]; + struct nameidata nd; + } *a; + + LKTRTrace("%s, nopts %d\n", str, opts->max_opt); + + err = -ENOMEM; + a = kmalloc(sizeof(*a), GFP_NOFS); + if (unlikely(!a)) + goto out; + + root = sb->s_root; + err = 0; + bindex = 0; + opt = opts->opt; + opt_tail = opt + opts->max_opt - 1; + opt->type = Opt_tail; + while (!err && (opt_str = strsep(&str, ",")) && *opt_str) { + err = -EINVAL; + token = match_token(opt_str, options, a->args); + LKTRTrace("%s, token %d, a->args[0]{%p, %p}\n", + opt_str, token, a->args[0].from, a->args[0].to); + + skipped = 0; + switch (token) { + case Opt_br: + err = 0; + while (!err && (opt_str = strsep(&a->args[0].from, ":")) + && *opt_str) { + err = opt_add(opt, opt_str, sb, bindex++); + if (unlikely(!err && ++opt > opt_tail)) { + err = -E2BIG; + break; + } + opt->type = Opt_tail; + skipped = 1; + } + break; + case Opt_add: + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + bindex = n; + err = opt_add(opt, a->args[1].from, sb, bindex); + break; + case Opt_append: + err = opt_add(opt, a->args[0].from, sb, + /*dummy bindex*/1); + if (!err) + opt->type = token; + break; + case Opt_prepend: + err = opt_add(opt, a->args[0].from, sb, /*bindex*/0); + if (!err) + opt->type = token; + break; + case Opt_del: + u.del = &opt->del; + u.del->path = a->args[0].from; + LKTRTrace("del path %s\n", u.del->path); + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(u.del->path, lkup_dirflags, + &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", + u.del->path, err); + break; + } + u.del->h_root = dget(a->nd.path.dentry); + path_put(&a->nd.path); + opt->type = token; + break; +#if 0 /* reserved for future use */ + case Opt_idel: + u.del = &opt->del; + u.del->path = "(indexed)"; + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + bindex = n; + aufs_read_lock(root, AuLock_FLUSH); + if (bindex < 0 || au_sbend(sb) < bindex) { + AuErr("out of bounds, %d\n", bindex); + aufs_read_unlock(root, !AuLock_IR); + break; + } + err = 0; + u.del->h_root = dget(au_h_dptr(root, bindex)); + opt->type = token; + aufs_read_unlock(root, !AuLock_IR); + break; +#endif + case Opt_mod: + u.mod = &opt->mod; + u.mod->path = a->args[0].from; + p = strchr(u.mod->path, '='); + if (unlikely(!p)) { + AuErr("no permssion %s\n", opt_str); + break; + } + *p++ = 0; + u.mod->perm = br_perm_val(p); + LKTRTrace("mod path %s, perm 0x%x, %s\n", + u.mod->path, u.mod->perm, p); + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(u.mod->path, lkup_dirflags, + &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", + u.mod->path, err); + break; + } + u.mod->h_root = dget(a->nd.path.dentry); + path_put(&a->nd.path); + opt->type = token; + break; +#ifdef IMOD /* reserved for future use */ + case Opt_imod: + u.mod = &opt->mod; + u.mod->path = "(indexed)"; + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + bindex = n; + aufs_read_lock(root, AuLock_FLUSH); + if (bindex < 0 || au_sbend(sb) < bindex) { + AuErr("out of bounds, %d\n", bindex); + aufs_read_unlock(root, !AuLock_IR); + break; + } + u.mod->perm = br_perm_val(a->args[1].from); + LKTRTrace("mod path %s, perm 0x%x, %s\n", + u.mod->path, u.mod->perm, a->args[1].from); + err = 0; + u.mod->h_root = dget(au_h_dptr(root, bindex)); + opt->type = token; + aufs_read_unlock(root, !AuLock_IR); + break; +#endif + case Opt_xino: + u.xino = &opt->xino; + file = au_xino_create(sb, a->args[0].from, /*silent*/0); + err = PTR_ERR(file); + if (IS_ERR(file)) + break; + err = -EINVAL; + if (unlikely(file->f_dentry->d_sb == sb)) { + fput(file); + AuErr("%s must be outside\n", a->args[0].from); + break; + } + err = 0; + u.xino->file = file; + u.xino->path = a->args[0].from; + opt->type = token; + break; + +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for futur use */ + case Opt_xinodir: + u.xinodir = &opt->xinodir; + u.xinodir->name = a->args[0].from; + err = vfsub_path_lookup(u.xinodir->name, lkup_dirflags, + &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", + u.xinodir->name, err); + break; + } + u.xinodir->path = a->nd.path; + /* do not path_put() */ + opt->type = token; + break; +#endif + + case Opt_trunc_xino_path: + u.xino_itrunc = &opt->xino_itrunc; + p = a->args[0].from; + LKTRTrace("trunc_xino path %s\n", p); + /* LSM may detect it */ + /* do not superio. */ + err = vfsub_path_lookup(p, lkup_dirflags, &a->nd); + if (unlikely(err)) { + AuErr("lookup failed %s (%d)\n", p , err); + break; + } + u.xino_itrunc->bindex = -1; + aufs_read_lock(root, AuLock_FLUSH); + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) { + if (au_h_dptr(root, bindex) + == a->nd.path.dentry) { + u.xino_itrunc->bindex = bindex; + break; + } + } + aufs_read_unlock(root, !AuLock_IR); + path_put(&a->nd.path); + if (unlikely(u.xino_itrunc->bindex < 0)) { + AuErr("no such branch %s\n", p); + err = -EINVAL; + break; + } + opt->type = token; + break; + + case Opt_itrunc_xino: + u.xino_itrunc = &opt->xino_itrunc; + if (unlikely(match_int(&a->args[0], &n))) { + AuErr("bad integer in %s\n", opt_str); + break; + } + u.xino_itrunc->bindex = n; + aufs_read_lock(root, AuLock_FLUSH); + if (n < 0 || au_sbend(sb) < n) { + AuErr("out of bounds, %d\n", n); + aufs_read_unlock(root, !AuLock_IR); + break; + } + aufs_read_unlock(root, !AuLock_IR); + err = 0; + opt->type = token; + break; + + case Opt_dirwh: + if (unlikely(match_int(&a->args[0], &opt->dirwh))) + break; + err = 0; + opt->type = token; + break; + + case Opt_rdcache: + if (unlikely(match_int(&a->args[0], &opt->rdcache))) + break; + err = 0; + opt->type = token; + break; + + case Opt_shwh: + if (flags & MS_RDONLY) { + err = 0; + opt->type = token; + } else + AuErr("shwh requires ro\n"); + break; + + case Opt_trunc_xino: + case Opt_notrunc_xino: + case Opt_noxino: + case Opt_trunc_xib: + case Opt_notrunc_xib: + case Opt_dirperm1: + case Opt_nodirperm1: + case Opt_noshwh: + case Opt_plink: + case Opt_noplink: + case Opt_list_plink: + case Opt_clean_plink: + case Opt_diropq_a: + case Opt_diropq_w: + case Opt_warn_perm: + case Opt_nowarn_perm: + case Opt_dlgt: + case Opt_nodlgt: + case Opt_refrof: + case Opt_norefrof: + case Opt_verbose: + case Opt_noverbose: + err = 0; + opt->type = token; + break; + + case Opt_udba: + opt->udba = udba_val(a->args[0].from); + if (opt->udba >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + + case Opt_wbr_create: + u.create = &opt->wbr_create; + u.create->wbr_create + = au_wbr_create_val(a->args[0].from, u.create); + if (u.create->wbr_create >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + case Opt_wbr_copyup: + opt->wbr_copyup = au_wbr_copyup_val(a->args[0].from); + if (opt->wbr_copyup >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + + case Opt_coo: + opt->coo = coo_val(a->args[0].from); + if (opt->coo >= 0) { + err = 0; + opt->type = token; + } else + AuErr("wrong value, %s\n", opt_str); + break; + + case Opt_ignore: +#ifndef CONFIG_AUFS_COMPAT + AuWarn("ignored %s\n", opt_str); +#endif + case Opt_ignore_silent: + skipped = 1; + err = 0; + break; + case Opt_err: + AuErr("unknown option %s\n", opt_str); + break; + } + + if (!err && !skipped) { + if (unlikely(++opt > opt_tail)) { + err = -E2BIG; + opt--; + opt->type = Opt_tail; + break; + } + opt->type = Opt_tail; + } + } + + kfree(a); + dump_opts(opts); + if (unlikely(err)) + au_opts_free(opts); + + out: + AuTraceErr(err); + return err; +} + +/* + * returns, + * plus: processed without an error + * zero: unprocessed + */ +static int au_opt_simple(struct super_block *sb, struct au_opt *opt, + struct au_opts *opts) +{ + int err; + struct au_sbinfo *sbinfo; + struct au_opt_wbr_create *create; + + AuTraceEnter(); + + err = 1; /* handled */ + sbinfo = au_sbi(sb); + switch (opt->type) { + case Opt_udba: + sbinfo->si_mntflags &= ~AuOptMask_UDBA; + sbinfo->si_mntflags |= opt->udba; + opts->given_udba |= opt->udba; + break; + + case Opt_plink: + au_opt_set(sbinfo->si_mntflags, PLINK); + break; + case Opt_noplink: + if (au_opt_test(sbinfo->si_mntflags, PLINK)) + au_plink_put(sb); + au_opt_clr(sbinfo->si_mntflags, PLINK); + break; + case Opt_list_plink: + if (au_opt_test(sbinfo->si_mntflags, PLINK)) + au_plink_list(sb); + break; + case Opt_clean_plink: + if (au_opt_test(sbinfo->si_mntflags, PLINK)) + au_plink_put(sb); + break; + + case Opt_diropq_a: + au_opt_set(sbinfo->si_mntflags, ALWAYS_DIROPQ); + break; + case Opt_diropq_w: + au_opt_clr(sbinfo->si_mntflags, ALWAYS_DIROPQ); + break; + + case Opt_dlgt: + au_opt_set(sbinfo->si_mntflags, DLGT); + break; + case Opt_nodlgt: + au_opt_clr(sbinfo->si_mntflags, DLGT); + break; + + case Opt_warn_perm: + au_opt_set(sbinfo->si_mntflags, WARN_PERM); + break; + case Opt_nowarn_perm: + au_opt_clr(sbinfo->si_mntflags, WARN_PERM); + break; + + case Opt_refrof: + au_opt_set(sbinfo->si_mntflags, REFROF); + break; + case Opt_norefrof: + /* au_opt_set(sbinfo->si_mntflags, COO_LEAF); */ + au_opt_clr(sbinfo->si_mntflags, REFROF); + break; + + case Opt_verbose: + au_opt_set(sbinfo->si_mntflags, VERBOSE); + break; + case Opt_noverbose: + au_opt_clr(sbinfo->si_mntflags, VERBOSE); + break; + + case Opt_wbr_create: + create = &opt->wbr_create; + if (sbinfo->si_wbr_create_ops->fin) { + err = sbinfo->si_wbr_create_ops->fin(sb); + if (!err) + err = 1; + } + sbinfo->si_wbr_create = create->wbr_create; + sbinfo->si_wbr_create_ops + = au_wbr_create_ops + create->wbr_create; + switch (create->wbr_create) { + case AuWbrCreate_MFSRRV: + case AuWbrCreate_MFSRR: + sbinfo->si_wbr_mfs.mfsrr_watermark + = create->mfsrr_watermark; + /*FALLTHROUGH*/ + case AuWbrCreate_MFS: + case AuWbrCreate_MFSV: + case AuWbrCreate_PMFS: + case AuWbrCreate_PMFSV: + sbinfo->si_wbr_mfs.mfs_expire = create->mfs_second * HZ; + break; + } + if (sbinfo->si_wbr_create_ops->init) + sbinfo->si_wbr_create_ops->init(sb); /* ignore */ + break; + case Opt_wbr_copyup: + sbinfo->si_wbr_copyup = opt->wbr_copyup; + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + opt->wbr_copyup; + break; + + case Opt_coo: + sbinfo->si_mntflags &= ~AuOptMask_COO; + sbinfo->si_mntflags |= opt->coo; + break; + + case Opt_dirwh: + sbinfo->si_dirwh = opt->dirwh; + break; + + case Opt_rdcache: + sbinfo->si_rdcache = opt->rdcache * HZ; + break; + + case Opt_trunc_xino: + au_opt_set(sbinfo->si_mntflags, TRUNC_XINO); + break; + case Opt_notrunc_xino: + au_opt_clr(sbinfo->si_mntflags, TRUNC_XINO); + break; + + case Opt_dirperm1: + au_opt_set(sbinfo->si_mntflags, DIRPERM1); + break; + case Opt_nodirperm1: + au_opt_clr(sbinfo->si_mntflags, DIRPERM1); + break; + + case Opt_shwh: + au_opt_set(sbinfo->si_mntflags, SHWH); + break; + case Opt_noshwh: + au_opt_clr(sbinfo->si_mntflags, SHWH); + break; + + case Opt_trunc_xino_path: + case Opt_itrunc_xino: + err = au_xino_trunc(sb, opt->xino_itrunc.bindex); + if (!err) + err = 1; + break; + + case Opt_trunc_xib: + au_fset_opts(opts->flags, TRUNC_XIB); + break; + case Opt_notrunc_xib: + au_fclr_opts(opts->flags, TRUNC_XIB); + break; + + default: + err = 0; + break; + } + + AuTraceErr(err); + return err; +} + +/* + * returns tri-state. + * plus: processed without an error + * zero: unprocessed + * minus: error + */ +static int au_opt_br(struct super_block *sb, struct au_opt *opt, + struct au_opts *opts) +{ + int err, do_refresh; + + AuTraceEnter(); + + err = 0; + switch (opt->type) { + case Opt_append: + opt->add.bindex = au_sbend(sb) + 1; + if (unlikely(opt->add.bindex < 0)) + opt->add.bindex = 0; + goto add; + case Opt_prepend: + opt->add.bindex = 0; + add: + case Opt_add: + err = au_br_add(sb, &opt->add, + au_ftest_opts(opts->flags, REMOUNT)); + if (!err) { + err = 1; + au_fset_opts(opts->flags, REFRESH_DIR); + if (unlikely(au_br_whable(opt->add.perm))) + au_fset_opts(opts->flags, REFRESH_NONDIR); + } + break; + + case Opt_del: + case Opt_idel: + err = au_br_del(sb, &opt->del, + au_ftest_opts(opts->flags, REMOUNT)); + if (!err) { + err = 1; + au_fset_opts(opts->flags, TRUNC_XIB); + au_fset_opts(opts->flags, REFRESH_DIR); + au_fset_opts(opts->flags, REFRESH_NONDIR); + } + break; + + case Opt_mod: + case Opt_imod: + err = au_br_mod(sb, &opt->mod, + au_ftest_opts(opts->flags, REMOUNT), + &do_refresh); + if (!err) { + err = 1; + if (unlikely(do_refresh)) { + au_fset_opts(opts->flags, REFRESH_DIR); + au_fset_opts(opts->flags, REFRESH_NONDIR); + } + } + break; + } + + AuTraceErr(err); + return err; +} + +static int au_opt_xino(struct super_block *sb, struct au_opt *opt, + struct au_opt_xino **opt_xino, + struct au_opt_xinodir **opt_xinodir, + struct au_opts *opts) +{ + int err; + const int remount = !!au_ftest_opts(opts->flags, REMOUNT); + + AuTraceEnter(); + + err = 0; + switch (opt->type) { + case Opt_xino: + err = au_xino_set(sb, &opt->xino, remount); + if (!err) + *opt_xino = &opt->xino; + break; +#if 0 /* def CONFIG_AUFS_EXPORT */ /* reserved for futur use */ + case Opt_xinodir: + err = au_xinodir_set(sb, &opt->xinodir, remount); + if (!err) + *opt_xinodir = &opt->xinodir; + break; +#endif + case Opt_noxino: + au_xino_clr(sb); + *opt_xino = (void *)-1; + break; + } + + AuTraceErr(err); + return err; +} + +static int verify_opts(struct super_block *sb, unsigned int pending, + int remount) +{ + int err; + aufs_bindex_t bindex, bend; + unsigned char do_plink, skip, do_free; + struct au_branch *br; + struct au_wbr *wbr; + struct dentry *root; + struct inode *dir, *h_dir; + unsigned int mnt_flags; + + AuTraceEnter(); + mnt_flags = au_mntflags(sb); + AuDebugOn(!(mnt_flags & AuOptMask_COO)); + AuDebugOn(!(mnt_flags & AuOptMask_UDBA)); + + if (!(sb->s_flags & MS_RDONLY)) { + if (unlikely(!au_br_writable(au_sbr_perm(sb, 0)))) + AuWarn("first branch should be rw\n"); + if (unlikely(au_opt_test(mnt_flags, SHWH))) + AuWarn("shwh should be used with ro\n"); + } + + if (unlikely(au_opt_test((mnt_flags | pending), UDBA_INOTIFY) + && !au_opt_test_xino(mnt_flags))) + AuWarn("udba=inotify requires xino\n"); + + err = 0; + root = sb->s_root; + dir = sb->s_root->d_inode; + do_plink = !!au_opt_test(mnt_flags, PLINK); + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) { + skip = 0; + h_dir = au_h_iptr(dir, bindex); + br = au_sbr(sb, bindex); + do_free = 0; + wbr = br->br_wbr; + if (wbr) + wbr_wh_read_lock(wbr); + switch (br->br_perm) { + case AuBrPerm_RR: + case AuBrPerm_RO: + case AuBrPerm_RRWH: + case AuBrPerm_ROWH: + do_free = !!wbr; + skip = (!wbr + || (!wbr->wbr_whbase + && !wbr->wbr_plink + && !wbr->wbr_tmp)); + break; + + case AuBrPerm_RWNoLinkWH: + /* skip = (!br->br_whbase && !br->br_tmp); */ + skip = (!wbr || !wbr->wbr_whbase); + if (skip && wbr) { + if (do_plink) + skip = !!wbr->wbr_plink; + else + skip = !wbr->wbr_plink; + } + break; + + case AuBrPerm_RW: + /* skip = (br->br_whbase && br->br_tmp); */ + skip = (wbr && wbr->wbr_whbase); + if (skip) { + if (do_plink) + skip = !!wbr->wbr_plink; + else + skip = !wbr->wbr_plink; + } + break; + + default: + BUG(); + } + if (wbr) + wbr_wh_read_unlock(wbr); + + if (skip) + continue; + + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + if (wbr) + wbr_wh_write_lock(wbr); + err = au_wh_init(au_h_dptr(root, bindex), br, + au_nfsmnt(sb, bindex), sb, bindex); + if (wbr) + wbr_wh_write_unlock(wbr); + mutex_unlock(&h_dir->i_mutex); + + if (!err && do_free) { + kfree(wbr); + br->br_wbr = NULL; + } + } + + AuTraceErr(err); + return err; +} + +int au_opts_mount(struct super_block *sb, struct au_opts *opts) +{ + int err; + struct inode *dir; + struct au_opt *opt; + struct au_opt_xino *opt_xino, xino; + struct au_opt_xinodir *opt_xinodir; + aufs_bindex_t bend; + struct au_sbinfo *sbinfo; + unsigned int tmp; + struct au_branch *br; + + AuTraceEnter(); + SiMustWriteLock(sb); + DiMustWriteLock(sb->s_root); + dir = sb->s_root->d_inode; + IiMustWriteLock(dir); + + err = 0; + opt_xino = NULL; + opt_xinodir = NULL; + opt = opts->opt; + while (err >= 0 && opt->type != Opt_tail) + err = au_opt_simple(sb, opt++, opts); + if (err > 0) + err = 0; + else if (unlikely(err < 0)) + goto out; + + /* disable xino, xinodir, hinotify, dlgt temporary */ + sbinfo = au_sbi(sb); + tmp = sbinfo->si_mntflags; + au_opt_clr(sbinfo->si_mntflags, XINO); + au_opt_clr(sbinfo->si_mntflags, XINODIR); + au_opt_clr(sbinfo->si_mntflags, DLGT); + au_opt_set_udba(sbinfo->si_mntflags, UDBA_REVAL); + + opt = opts->opt; + while (err >= 0 && opt->type != Opt_tail) + err = au_opt_br(sb, opt++, opts); + if (err > 0) + err = 0; + else if (unlikely(err < 0)) + goto out; + + bend = au_sbend(sb); + if (unlikely(bend < 0)) { + err = -EINVAL; + AuErr("no branches\n"); + goto out; + } + + if (au_opt_test(tmp, XINO)) + au_opt_set(sbinfo->si_mntflags, XINO); + else if (au_opt_test(tmp, XINODIR)) + au_opt_set(sbinfo->si_mntflags, XINODIR); + opt = opts->opt; + while (!err && opt->type != Opt_tail) + err = au_opt_xino(sb, opt++, &opt_xino, &opt_xinodir, opts); + if (unlikely(err)) + goto out; + + /* todo: test this error case? */ + err = verify_opts(sb, tmp, /*remount*/0); + if (unlikely(err)) + goto out; + + /* enable xino */ + if (au_opt_test(tmp, XINO) && !opt_xino) { + xino.file = au_xino_def(sb); + err = PTR_ERR(xino.file); + if (IS_ERR(xino.file)) + goto out; + + br = au_xino_def_br(sbinfo); + err = au_xino_set(sb, &xino, /*remount*/0); + fput(xino.file); + if (unlikely(err)) + goto out; + au_xino_def_br_set(br, sbinfo); + } + + /* restore hinotify */ + sbinfo->si_mntflags &= ~AuOptMask_UDBA; + sbinfo->si_mntflags |= (tmp & AuOptMask_UDBA); + if (au_opt_test(tmp, UDBA_INOTIFY)) + au_reset_hinotify(dir, au_hi_flags(dir, 1) & ~AuHi_XINO); + + /* restore dlgt */ + if (au_opt_test(tmp, DLGT)) + au_opt_set(sbinfo->si_mntflags, DLGT); + + out: + AuTraceErr(err); + return err; +} + +int au_opts_remount(struct super_block *sb, struct au_opts *opts) +{ + int err, rerr; + struct inode *dir; + struct au_opt_xino *opt_xino; + struct au_opt_xinodir *opt_xinodir; + struct au_opt *opt; + unsigned char dlgt; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + DiMustWriteLock(sb->s_root); + dir = sb->s_root->d_inode; + IiMustWriteLock(dir); + sbinfo = au_sbi(sb); + + err = 0; + dlgt = !!au_opt_test(sbinfo->si_mntflags, DLGT); + opt_xino = NULL; + opt_xinodir = NULL; + opt = opts->opt; + while (err >= 0 && opt->type != Opt_tail) { + err = au_opt_simple(sb, opt, opts); + + /* disable it temporary */ + dlgt = !!au_opt_test(sbinfo->si_mntflags, DLGT); + au_opt_clr(sbinfo->si_mntflags, DLGT); + + if (!err) + err = au_opt_br(sb, opt, opts); + if (!err) + err = au_opt_xino(sb, opt, &opt_xino, &opt_xinodir, + opts); + + /* restore it */ + if (unlikely(dlgt)) + au_opt_set(sbinfo->si_mntflags, DLGT); + opt++; + } + if (err > 0) + err = 0; + AuTraceErr(err); + + /* go on even err */ + + /* todo: test this error case? */ + au_opt_clr(sbinfo->si_mntflags, DLGT); + rerr = verify_opts(sb, sbinfo->si_mntflags, /*remount*/1); + if (unlikely(dlgt)) + au_opt_set(sbinfo->si_mntflags, DLGT); + if (unlikely(rerr && !err)) + err = rerr; + + if (unlikely(au_ftest_opts(opts->flags, TRUNC_XIB))) { + rerr = au_xib_trunc(sb); + if (unlikely(rerr && !err)) + err = rerr; + } + + /* they are handled by the caller */ + if (!au_ftest_opts(opts->flags, REFRESH_DIR) + && (opts->given_udba || au_opt_test_xino(sbinfo->si_mntflags))) + au_fset_opts(opts->flags, REFRESH_DIR); + + LKTRTrace("status 0x%x\n", opts->flags); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/robr.c +++ linux-2.6.28/ubuntu/aufs/robr.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * 'robr', aufs as readonly branch of another aufs + * + * $Id: robr.c,v 1.6 2008/07/21 02:53:51 sfjro Exp $ + */ + +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +int au_test_robr_wh(struct qstr *name, struct dentry *h_parent, + struct qstr *wh_name, int try_sio, struct au_ndx *ndx) +{ + if (strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) + return au_wh_test(h_parent, wh_name, try_sio, ndx); + return -EPERM; +} + +int au_test_robr_shwh(struct super_block *sb, const struct qstr *name) +{ + return 0; +} + +/* ---------------------------------------------------------------------- */ + +struct au_robr_lvma { + struct list_head list; + struct vm_area_struct *vma; +}; + +struct file *au_robr_safe_file(struct vm_area_struct *vma) +{ + struct file *file = vma->vm_file; + struct super_block *sb = file->f_dentry->d_sb; + struct au_robr_lvma *lvma, *entry; + struct au_sbinfo *sbinfo; + unsigned char found, warn; + + AuTraceEnter(); + AuDebugOn(!au_test_aufs(sb)); + + warn = 0; + found = 0; + sbinfo = au_sbi(sb); + spin_lock(&sbinfo->si_lvma_lock); + list_for_each_entry(entry, &sbinfo->si_lvma, list) { + found = (entry->vma == vma); + if (unlikely(found)) + break; + } + if (!found) { + lvma = kmalloc(sizeof(*lvma), GFP_ATOMIC); + if (lvma) { + lvma->vma = vma; + list_add(&lvma->list, &sbinfo->si_lvma); + } else { + warn = 1; + file = NULL; + } + } else + file = NULL; + spin_unlock(&sbinfo->si_lvma_lock); + + if (unlikely(warn)) + AuWarn1("no memory for lvma\n"); + return file; +} + +void au_robr_reset_file(struct vm_area_struct *vma, struct file *file) +{ + struct super_block *sb = file->f_dentry->d_sb; + struct au_robr_lvma *entry, *found; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + AuDebugOn(!au_test_aufs(sb)); + + vma->vm_file = file; + /* smp_mb(); */ /* flush vm_file */ + + found = NULL; + sbinfo = au_sbi(sb); + spin_lock(&sbinfo->si_lvma_lock); + list_for_each_entry(entry, &sbinfo->si_lvma, list) + if (entry->vma == vma) { + found = entry; + break; + } + AuDebugOn(!found); + list_del(&found->list); + spin_unlock(&sbinfo->si_lvma_lock); + kfree(found); +} --- linux-2.6.28.orig/ubuntu/aufs/dlgt.c +++ linux-2.6.28/ubuntu/aufs/dlgt.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup functions in 'delegate' mode + * + * $Id: dlgt.c,v 1.5 2008/08/11 02:50:34 sfjro Exp $ + */ + +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +struct au_lookup_one_len_args { + struct dentry **errp; + const char *name; + struct dentry *parent; + int len; +}; + +static void au_call_lookup_one_len(void *args) +{ + struct au_lookup_one_len_args *a = args; + *a->errp = vfsub_lookup_one_len(a->name, a->parent, a->len); +} + +struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent, + int len, unsigned int flags) +{ + struct dentry *dentry; + int dirperm1; + + LKTRTrace("%.*s/%.*s, 0x%x\n", AuDLNPair(parent), len, name, flags); + + dirperm1 = au_ftest_ndx(flags, DIRPERM1); + if (!dirperm1 && !au_ftest_ndx(flags, DLGT)) + dentry = vfsub_lookup_one_len(name, parent, len); + else { + int wkq_err; + struct au_lookup_one_len_args args = { + .errp = &dentry, + .name = name, + .parent = parent, + .len = len + }; + wkq_err = au_wkq_wait(au_call_lookup_one_len, &args, + /*dlgt*/!dirperm1); + if (unlikely(wkq_err)) + dentry = ERR_PTR(wkq_err); + } + + AuTraceErrPtr(dentry); + return dentry; +} + +/* ---------------------------------------------------------------------- */ + +struct security_inode_permission_args { + int *errp; + struct inode *h_inode; + int mask; + struct nameidata *fake_nd; +}; + +static void call_security_inode_permission(void *args) +{ + struct security_inode_permission_args *a = args; + LKTRTrace("fsuid %d\n", current->fsuid); + *a->errp = vfsub_security_inode_permission(a->h_inode, a->mask, + a->fake_nd); +} + +int au_security_inode_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int dlgt) +{ + int err; + + AuTraceEnter(); + + if (!dlgt) + err = vfsub_security_inode_permission(h_inode, mask, fake_nd); + else { + int wkq_err; + struct security_inode_permission_args args = { + .errp = &err, + .h_inode = h_inode, + .mask = mask, + .fake_nd = fake_nd + }; + wkq_err = au_wkq_wait(call_security_inode_permission, &args, + /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/i_op.c +++ linux-2.6.28/ubuntu/aufs/i_op.c @@ -0,0 +1,1003 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations (except add/del/rename) + * + * $Id: i_op.c,v 1.19 2008/09/08 02:39:57 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +static int silly_lock(struct inode *inode, struct nameidata *nd) +{ + int locked = 0; + struct super_block *sb = inode->i_sb; + + LKTRTrace("i%lu, nd %p\n", inode->i_ino, nd); + + if (!nd || !nd->path.dentry) { + si_read_lock(sb, AuLock_FLUSH); + ii_read_lock_child(inode); + } else if (nd->path.dentry->d_inode != inode) { + locked = 1; + /* lock child first, then parent */ + si_read_lock(sb, AuLock_FLUSH); + ii_read_lock_child(inode); + di_read_lock_parent(nd->path.dentry, 0); + } else { + locked = 2; + aufs_read_lock(nd->path.dentry, AuLock_FLUSH | AuLock_IR); + } + return locked; +} + +static void silly_unlock(int locked, struct inode *inode, struct nameidata *nd) +{ + struct super_block *sb = inode->i_sb; + + LKTRTrace("locked %d, i%lu, nd %p\n", locked, inode->i_ino, nd); + + switch (locked) { + case 0: + ii_read_unlock(inode); + si_read_unlock(sb); + break; + case 1: + di_read_unlock(nd->path.dentry, 0); + ii_read_unlock(inode); + si_read_unlock(sb); + break; + case 2: + aufs_read_unlock(nd->path.dentry, AuLock_IR); + break; + default: + BUG(); + } +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +static int h_permission(struct inode *h_inode, int mask, + struct vfsmount *h_mnt, int brperm, int dlgt) +{ + int err, submask; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, brperm 0x%x\n", + h_inode->i_ino, mask, brperm); + + err = -EACCES; + if (unlikely((write_mask && IS_IMMUTABLE(h_inode)) + || ((mask & MAY_EXEC) && S_ISREG(h_inode->i_mode) + && (h_mnt->mnt_flags & MNT_NOEXEC)) + )) + goto out; + + /* + * - skip hidden fs test in the case of write to ro branch. + * - nfs dir permission write check is optimized, but a policy for + * link/rename requires a real check. + */ + submask = mask & ~MAY_APPEND; + if ((write_mask && !au_br_writable(brperm)) + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) + && write_mask && !(mask & MAY_READ)) + || !h_inode->i_op + || !h_inode->i_op->permission) { + /* LKTRLabel(generic_permission); */ + err = generic_permission(h_inode, submask, NULL); + } else { + /* LKTRLabel(h_inode->permission); */ + err = h_inode->i_op->permission(h_inode, submask); + AuTraceErr(err); + } + +#if 1 /* todo: export? */ + if (!err) + err = au_security_inode_permission(h_inode, mask, NULL, + dlgt); +#endif + + out: + AuTraceErr(err); + return err; +} + +static int aufs_permission(struct inode *inode, int mask) +{ + int err; + aufs_bindex_t bindex, bend; + unsigned char locked, dlgt; + const unsigned char isdir = S_ISDIR(inode->i_mode); + struct inode *h_inode; + struct super_block *sb; + unsigned int mnt_flags; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, isdir %d, write_mask %d\n", + inode->i_ino, mask, isdir, write_mask); + + sb = inode->i_sb; + locked = silly_lock(inode, NULL); + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + + if (/* unlikely */(!isdir || write_mask + || au_test_dirperm1(mnt_flags))) { + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode + || ((h_inode->i_mode & S_IFMT) + != (inode->i_mode & S_IFMT))); + err = 0; + bindex = au_ibstart(inode); + LKTRTrace("b%d\n", bindex); + err = h_permission(h_inode, mask, au_sbr_mnt(sb, bindex), + au_sbr_perm(sb, bindex), dlgt); + + if (write_mask && !err) { + /* test whether the upper writable branch exists */ + err = -EROFS; + for (; bindex >= 0; bindex--) + if (!au_br_rdonly(au_sbr(sb, bindex))) { + err = 0; + break; + } + } + goto out; + } + + /* non-write to dir */ + err = 0; + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (!h_inode) + continue; + AuDebugOn(!S_ISDIR(h_inode->i_mode)); + + LKTRTrace("b%d\n", bindex); + err = h_permission(h_inode, mask, au_sbr_mnt(sb, bindex), + au_sbr_perm(sb, bindex), dlgt); + } + + out: + silly_unlock(locked, inode, NULL); + AuTraceErr(err); + return err; +} +#else + +static int h_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int brperm, int dlgt) +{ + int err, submask; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, brperm 0x%x\n", + h_inode->i_ino, mask, brperm); + + err = -EACCES; + if (unlikely((write_mask && IS_IMMUTABLE(h_inode)) + || ((mask & MAY_EXEC) && S_ISREG(h_inode->i_mode) + && fake_nd && fake_nd->path.mnt + && (fake_nd->path.mnt->mnt_flags & MNT_NOEXEC)) + )) + goto out; + + /* + * - skip hidden fs test in the case of write to ro branch. + * - nfs dir permission write check is optimized, but a policy for + * link/rename requires a real check. + */ + submask = mask & ~MAY_APPEND; + if ((write_mask && !au_br_writable(brperm)) + || (au_test_nfs(h_inode->i_sb) && S_ISDIR(h_inode->i_mode) + && write_mask && !(mask & MAY_READ)) + || !h_inode->i_op + || !h_inode->i_op->permission) { + /* LKTRLabel(generic_permission); */ + err = generic_permission(h_inode, submask, NULL); + } else { + /* LKTRLabel(h_inode->permission); */ + err = h_inode->i_op->permission(h_inode, submask, fake_nd); + AuTraceErr(err); + } + +#if 1 /* todo: export? */ + if (!err) + err = au_security_inode_permission(h_inode, mask, fake_nd, + dlgt); +#endif + + out: + AuTraceErr(err); + return err; +} + +static int aufs_permission(struct inode *inode, int mask, struct nameidata *nd) +{ + int err; + aufs_bindex_t bindex, bend; + unsigned char locked, dlgt, do_nd; + const unsigned char isdir = S_ISDIR(inode->i_mode); + struct inode *h_inode; + struct super_block *sb; + unsigned int mnt_flags; + struct path path; + const int write_mask = (mask & (MAY_WRITE | MAY_APPEND)); + + LKTRTrace("ino %lu, mask 0x%x, isdir %d, write_mask %d, " + "nd %d{%d, %d}\n", + inode->i_ino, mask, isdir, write_mask, + !!nd, nd ? !!nd->path.dentry : 0, nd ? !!nd->path.mnt : 0); + + sb = inode->i_sb; + locked = silly_lock(inode, nd); + do_nd = (nd && locked >= 1); + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + + if (/* unlikely */(!isdir || write_mask + || au_test_dirperm1(mnt_flags))) { + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode + || ((h_inode->i_mode & S_IFMT) + != (inode->i_mode & S_IFMT))); + err = 0; + bindex = au_ibstart(inode); + LKTRTrace("b%d\n", bindex); + if (do_nd) { + path = nd->path; + nd->path.mnt = au_sbr_mnt(sb, bindex); + nd->path.dentry = au_h_dptr(nd->path.dentry, bindex); + path_get(&nd->path); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + path_put(&nd->path); + nd->path = path; + } else { + AuDebugOn(nd && nd->path.mnt); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + } + + if (write_mask && !err) { + /* test whether the upper writable branch exists */ + err = -EROFS; + for (; bindex >= 0; bindex--) + if (!au_br_rdonly(au_sbr(sb, bindex))) { + err = 0; + break; + } + } + goto out; + } + + /* non-write to dir */ + if (do_nd) + path = nd->path; + else { + path.mnt = NULL; + path.dentry = NULL; + } + err = 0; + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); !err && bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (!h_inode) + continue; + AuDebugOn(!S_ISDIR(h_inode->i_mode)); + + LKTRTrace("b%d\n", bindex); + if (do_nd) { + nd->path.mnt = au_sbr_mnt(sb, bindex); + nd->path.dentry = au_h_dptr(path.dentry, bindex); + path_get(&nd->path); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + path_put(&nd->path); + } else { + AuDebugOn(nd && nd->path.mnt); + err = h_permission(h_inode, mask, nd, + au_sbr_perm(sb, bindex), dlgt); + } + } + if (do_nd) + nd->path = path; + + out: + silly_unlock(locked, inode, nd); + AuTraceErr(err); + return err; +} +#endif /* KERNEL_VERSION(2, 6, 27) */ + +/* ---------------------------------------------------------------------- */ + +static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, + struct nameidata *nd) +{ + struct dentry *ret, *parent; + int err, npositive; + struct inode *inode, *h_inode; + struct nameidata tmp_nd, *ndp; + aufs_bindex_t bstart; + struct mutex *mtx; + struct super_block *sb; + + LKTRTrace("dir %lu, %.*s, nd{0x%x}\n", + dir->i_ino, AuDLNPair(dentry), nd ? nd->flags : 0); + AuDebugOn(IS_ROOT(dentry)); + IMustLock(dir); + + sb = dir->i_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_alloc_dinfo(dentry); + ret = ERR_PTR(err); + if (unlikely(err)) + goto out; + + /* nd can be NULL */ + ndp = au_dup_nd(au_sbi(sb), &tmp_nd, nd); + parent = dentry->d_parent; /* dir inode is locked */ + di_read_lock_parent(parent, AuLock_IR); + npositive = au_lkup_dentry(dentry, au_dbstart(parent), /*type*/0, ndp); + di_read_unlock(parent, AuLock_IR); + err = npositive; + ret = ERR_PTR(err); + if (unlikely(err < 0)) + goto out_unlock; + + inode = NULL; + if (npositive) { + bstart = au_dbstart(dentry); + h_inode = au_h_dptr(dentry, bstart)->d_inode; + AuDebugOn(!h_inode); + if (!S_ISDIR(h_inode->i_mode)) { + /* + * stop 'race'-ing between hardlinks under different + * parents. + */ + mtx = &au_sbr(sb, bstart)->br_xino.xi_nondir_mtx; + mutex_lock(mtx); + inode = au_new_inode(dentry); + mutex_unlock(mtx); + } else + inode = au_new_inode(dentry); + ret = (void *)inode; + } + if (!IS_ERR(inode)) { + ret = d_splice_alias(inode, dentry); + if (unlikely(IS_ERR(ret) && inode)) + ii_write_unlock(inode); + AuDebugOn(nd + && (nd->flags & LOOKUP_OPEN) + && nd->intent.open.file + && nd->intent.open.file->f_dentry); + au_store_fmode_exec(nd, inode); + } + + out_unlock: + di_write_unlock(dentry); + out: + si_read_unlock(sb); + AuTraceErrPtr(ret); + return ret; +} + +/* ---------------------------------------------------------------------- */ + +/* + * decide the branch and the parent dir where we will create a new entry. + * returns new bindex or an error. + * copyup the parent dir if needed. + */ +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, + struct au_wr_dir_args *args) +{ + int err; + aufs_bindex_t bcpup, bstart, src_bstart; + struct super_block *sb; + struct dentry *parent; + struct au_sbinfo *sbinfo; + const int add_entry = au_ftest_wrdir(args->flags, ADD_ENTRY); + + LKTRTrace("%.*s, src %p, {%d, 0x%x}\n", + AuDLNPair(dentry), src_dentry, args->force_btgt, args->flags); + + sb = dentry->d_sb; + sbinfo = au_sbi(sb); + parent = dget_parent(dentry); + bstart = au_dbstart(dentry); + bcpup = bstart; + if (args->force_btgt < 0) { + if (src_dentry) { + src_bstart = au_dbstart(src_dentry); + if (src_bstart < bstart) + bcpup = src_bstart; + } else if (add_entry) { + err = AuWbrCreate(sbinfo, dentry, + au_ftest_wrdir(args->flags, ISDIR)); + bcpup = err; + } + + if (bcpup < 0 || au_test_ro(sb, bcpup, dentry->d_inode)) { + if (add_entry) + err = AuWbrCopyup(sbinfo, dentry); + else { + di_read_lock_parent(parent, !AuLock_IR); + err = AuWbrCopyup(sbinfo, dentry); + di_read_unlock(parent, !AuLock_IR); + } + bcpup = err; + if (unlikely(err < 0)) + goto out; + } + } else { + bcpup = args->force_btgt; + AuDebugOn(au_test_ro(sb, bcpup, dentry->d_inode)); + } + LKTRTrace("bstart %d, bcpup %d\n", bstart, bcpup); + if (bstart < bcpup) + au_update_dbrange(dentry, /*do_put_zero*/1); + + err = bcpup; + if (bcpup == bstart) + goto out; /* success */ + + /* copyup the new parent into the branch we process */ + if (add_entry) { + au_update_dbstart(dentry); + IMustLock(parent->d_inode); + DiMustWriteLock(parent); + IiMustWriteLock(parent->d_inode); + } else + di_write_lock_parent(parent); + + err = 0; + if (!au_h_dptr(parent, bcpup)) { + if (bstart < bcpup) + err = au_cpdown_dirs(dentry, bcpup); + else + err = au_cpup_dirs(dentry, bcpup); + } + if (!err && add_entry) { + struct dentry *h_parent; + struct inode *h_dir; + + h_parent = au_h_dptr(parent, bcpup); + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + err = au_lkup_neg(dentry, bcpup); + mutex_unlock(&h_dir->i_mutex); + if (bstart < bcpup && au_dbstart(dentry) < 0) { + au_set_dbstart(dentry, 0); + au_update_dbrange(dentry, /*do_put_zero*/0); + } + } + + if (!add_entry) + di_write_unlock(parent); + if (!err) + err = bcpup; /* success */ + out: + dput(parent); + LKTRTrace("err %d\n", err); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct dentry *au_do_pinned_h_parent(struct au_pin1 *pin, aufs_bindex_t bindex) +{ + if (pin && pin->parent) + return au_h_dptr(pin->parent, bindex); + return NULL; +} + +void au_do_unpin(struct au_pin1 *p, struct au_pin1 *gp) +{ + LKTRTrace("%p, %p\n", p, gp); + AuDebugOn(!p); + + if (unlikely(!p->h_dir)) + return; + + LKTRTrace("p{%.*s, %d, %d, %d, %d}\n", + AuDLNPair(p->dentry), p->lsc_di, p->lsc_hi, + !!p->parent, !!p->h_dir); + + mutex_unlock(&p->h_dir->i_mutex); + if (unlikely(gp)) + au_do_unpin(gp, NULL); + if (!p->di_locked) + di_read_unlock(p->parent, AuLock_IR); + iput(p->h_dir); + dput(p->parent); + p->parent = NULL; + p->h_dir = NULL; +} + +int au_do_pin(struct au_pin1 *p, struct au_pin1 *gp, const aufs_bindex_t bindex, + const int do_gp) +{ + int err; + struct dentry *h_dentry; + + LKTRTrace("%.*s, %d, b%d, %d\n", + AuDLNPair(p->dentry), !!gp, bindex, do_gp); + AuDebugOn(do_gp && !gp); + /* AuDebugOn(!do_gp && gp); */ + + err = 0; + if (unlikely(IS_ROOT(p->dentry))) + goto out; + + h_dentry = NULL; + if (bindex <= au_dbend(p->dentry)) + h_dentry = au_h_dptr(p->dentry, bindex); + + p->parent = dget_parent(p->dentry); + if (!p->di_locked) + di_read_lock(p->parent, AuLock_IR, p->lsc_di); + else + DiMustAnyLock(p->parent); + AuDebugOn(!p->parent->d_inode); + p->h_dir = au_igrab(au_h_iptr(p->parent->d_inode, bindex)); + /* udba case */ + if (unlikely(p->do_verify && !p->h_dir)) { + err = -EIO; + if (!p->di_locked) + di_read_unlock(p->parent, AuLock_IR); + dput(p->parent); + p->parent = NULL; + goto out; + } + + if (unlikely(do_gp)) { + gp->dentry = p->parent; + err = au_do_pin(gp, NULL, bindex, 0); + if (unlikely(err)) + gp->dentry = NULL; + } + mutex_lock_nested(&p->h_dir->i_mutex, p->lsc_hi); + if (!err) { + /* todo: call d_revalidate() here? */ + if (!h_dentry + || !p->do_verify + || !au_verify_parent(h_dentry, p->h_dir)) + goto out; /* success */ + else { + AuWarn1("bypassed %.*s/%.*s?\n", + AuDLNPair(p->parent), AuDLNPair(p->dentry)); + err = -EIO; + } + } + + AuDbgDentry(p->dentry); + AuDbgDentry(h_dentry); + AuDbgDentry(p->parent); + AuDbgInode(p->h_dir); + if (h_dentry) + AuDbgDentry(h_dentry->d_parent); + + au_do_unpin(p, gp); + if (unlikely(do_gp)) + gp->dentry = NULL; + + out: + AuTraceErr(err); + return err; +} + +void au_pin_init(struct au_pin *args, struct dentry *dentry, int di_locked, + int lsc_di, int lsc_hi, int do_gp) +{ + struct au_pin1 *p; + unsigned char do_verify; + + AuTraceEnter(); + + memset(args, 0, sizeof(*args)); + p = args->pin + AuPin_PARENT; + p->dentry = dentry; + p->di_locked = di_locked; + p->lsc_di = lsc_di; + p->lsc_hi = lsc_hi; + p->do_verify = !au_opt_test(au_mntflags(dentry->d_sb), UDBA_NONE); + if (!do_gp) + return; + + do_verify = p->do_verify; + p = au_pin_gp(args); + if (unlikely(p)) { + p->lsc_di = lsc_di + 1; /* child first */ + p->lsc_hi = lsc_hi - 1; /* parent first */ + p->do_verify = do_verify; + } +} + +int au_pin(struct au_pin *args, struct dentry *dentry, aufs_bindex_t bindex, + int di_locked, int do_gp) +{ + LKTRTrace("%.*s, b%d, di_locked %d, do_gp %d\n", + AuDLNPair(dentry), bindex, di_locked, do_gp); + + au_pin_init(args, dentry, di_locked, AuLsc_DI_PARENT, AuLsc_I_PARENT2, + do_gp); + return au_do_pin(args->pin + AuPin_PARENT, au_pin_gp(args), bindex, do_gp); +} + +/* ---------------------------------------------------------------------- */ + +struct au_icpup_args { + aufs_bindex_t btgt; + unsigned char isdir, hinotify, did_cpup; /* flags */ + struct dentry *h_dentry; + struct inode *h_inode; + struct au_pin pin; + struct au_hin_ignore ign[2]; + struct vfsub_args vargs; +}; + +/* todo: refine it */ +static int au_lock_and_icpup(struct dentry *dentry, loff_t sz, + struct au_icpup_args *a) +{ + int err; + aufs_bindex_t bstart; + struct super_block *sb; + struct dentry *hi_wh, *parent; + struct inode *inode; + struct au_wr_dir_args wr_dir_args = { + .force_btgt = -1, + .flags = 0 + }; + + LKTRTrace("%.*s, %lld\n", AuDLNPair(dentry), sz); + + di_write_lock_child(dentry); + bstart = au_dbstart(dentry); + sb = dentry->d_sb; + inode = dentry->d_inode; + a->isdir = !!S_ISDIR(inode->i_mode); + if (unlikely(a->isdir)) + au_fset_wrdir(wr_dir_args.flags, ISDIR); + /* plink or hi_wh() */ + if (bstart != au_ibstart(inode)) + wr_dir_args.force_btgt = au_ibstart(inode); + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); + if (unlikely(err < 0)) + goto out_dentry; + a->btgt = err; + a->did_cpup = (err != bstart); + err = 0; + + /* crazy udba locks */ + a->hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY); + parent = NULL; + if (!IS_ROOT(dentry)) { + parent = dget_parent(dentry); + di_write_lock_parent(parent); + } + err = au_pin(&a->pin, dentry, a->btgt, /*di_locked*/!!parent, + /*dp_gp*/a->hinotify); + if (unlikely(err)) { + if (parent) { + di_write_unlock(parent); + dput(parent); + } + goto out_dentry; + } + a->h_dentry = au_h_dptr(dentry, bstart); + a->h_inode = a->h_dentry->d_inode; + AuDebugOn(!a->h_inode); + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); + if (!a->did_cpup) { + au_unpin_gp(&a->pin); + if (parent) { + au_pin_set_parent_lflag(&a->pin, /*lflag*/0); + di_downgrade_lock(parent, AuLock_IR); + dput(parent); + } + goto out; /* success */ + } + + hi_wh = NULL; + if (!d_unhashed(dentry)) { + if (parent) { + au_pin_set_parent_lflag(&a->pin, /*lflag*/0); + di_downgrade_lock(parent, AuLock_IR); + dput(parent); + } + err = au_sio_cpup_simple(dentry, a->btgt, sz, AuCpup_DTIME); + if (!err) + a->h_dentry = au_h_dptr(dentry, a->btgt); + } else { + hi_wh = au_hi_wh(inode, a->btgt); + if (!hi_wh) { + err = au_sio_cpup_wh(dentry, a->btgt, sz, + /*file*/NULL); + if (!err) + hi_wh = au_hi_wh(inode, a->btgt); + /* todo: revalidate hi_wh? */ + } + if (parent) { + au_pin_set_parent_lflag(&a->pin, /*lflag*/0); + di_downgrade_lock(parent, AuLock_IR); + dput(parent); + } + if (!hi_wh) + a->h_dentry = au_h_dptr(dentry, a->btgt); + else + a->h_dentry = hi_wh; /* do not dget here */ + } + + mutex_unlock(&a->h_inode->i_mutex); + a->h_inode = a->h_dentry->d_inode; + AuDebugOn(!a->h_inode); + if (!err) { + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); + au_unpin_gp(&a->pin); + goto out; /* success */ + } + + au_unpin(&a->pin); + + out_dentry: + di_write_unlock(dentry); + out: + AuTraceErr(err); + return err; +} + +static int aufs_setattr(struct dentry *dentry, struct iattr *ia) +{ + int err; + struct inode *inode; + struct super_block *sb; + __u32 events; + struct file *file; + loff_t sz; + struct au_icpup_args *a; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + IMustLock(inode); + + err = -ENOMEM; + a = kzalloc(sizeof(*a), GFP_NOFS); + if (unlikely(!a)) + goto out; + + file = NULL; + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + vfsub_args_init(&a->vargs, a->ign, au_test_dlgt(au_mntflags(sb)), 0); + + if (ia->ia_valid & ATTR_FILE) { + /* currently ftruncate(2) only */ + file = ia->ia_file; + fi_write_lock(file); + ia->ia_file = au_h_fptr(file, au_fbstart(file)); + } + + sz = -1; + if ((ia->ia_valid & ATTR_SIZE) + && ia->ia_size < i_size_read(inode)) + sz = ia->ia_size; + err = au_lock_and_icpup(dentry, sz, a); + if (unlikely(err < 0)) + goto out_si; + if (a->did_cpup) { + ia->ia_file = NULL; + ia->ia_valid &= ~ATTR_FILE; + } + + if ((ia->ia_valid & ATTR_SIZE) + && ia->ia_size < i_size_read(inode)) { + err = vmtruncate(inode, ia->ia_size); + if (unlikely(err)) + goto out_unlock; + } + + if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) + ia->ia_valid &= ~ATTR_MODE; + + events = 0; + if (unlikely(a->hinotify)) { + events = vfsub_events_notify_change(ia); + if (events) { + if (unlikely(a->isdir)) + vfsub_ign_hinode(&a->vargs, events, + au_hi(inode, a->btgt)); + vfsub_ign_hinode(&a->vargs, events, + au_pinned_hdir(&a->pin, a->btgt)); + } + } + err = vfsub_notify_change(a->h_dentry, ia, &a->vargs); + if (!err) + au_cpup_attr_changeable(inode); + + out_unlock: + mutex_unlock(&a->h_inode->i_mutex); + au_unpin(&a->pin); + di_write_unlock(dentry); + out_si: + if (file) { + fi_write_unlock(file); + ia->ia_file = file; + ia->ia_valid |= ATTR_FILE; + } + si_read_unlock(sb); + kfree(a); + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int h_readlink(struct dentry *dentry, int bindex, char __user *buf, + int bufsiz) +{ + struct super_block *sb; + struct dentry *h_dentry; + + LKTRTrace("%.*s, b%d, %d\n", AuDLNPair(dentry), bindex, bufsiz); + + h_dentry = au_h_dptr(dentry, bindex); + if (unlikely(/* !h_dentry + || !h_dentry->d_inode + || */ + !h_dentry->d_inode->i_op + || !h_dentry->d_inode->i_op->readlink)) + return -EINVAL; + + sb = dentry->d_sb; + if (!au_test_ro(sb, bindex, dentry->d_inode)) { + touch_atime(au_sbr_mnt(sb, bindex), h_dentry); + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ + fsstack_copy_attr_atime(dentry->d_inode, h_dentry->d_inode); + } + return h_dentry->d_inode->i_op->readlink(h_dentry, buf, bufsiz); +} + +static int aufs_readlink(struct dentry *dentry, char __user *buf, int bufsiz) +{ + int err; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), bufsiz); + + aufs_read_lock(dentry, AuLock_IR); + err = h_readlink(dentry, au_dbstart(dentry), buf, bufsiz); + aufs_read_unlock(dentry, AuLock_IR); + AuTraceErr(err); + return err; +} + +static void *aufs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + int err; + char *buf; + mm_segment_t old_fs; + + LKTRTrace("%.*s, nd %.*s\n", + AuDLNPair(dentry), AuDLNPair(nd->path.dentry)); + + err = -ENOMEM; + buf = __getname(); + if (unlikely(!buf)) + goto out; + + aufs_read_lock(dentry, AuLock_IR); + old_fs = get_fs(); + set_fs(KERNEL_DS); + err = h_readlink(dentry, au_dbstart(dentry), (char __user *)buf, + PATH_MAX); + set_fs(old_fs); + aufs_read_unlock(dentry, AuLock_IR); + + if (err >= 0) { + buf[err] = 0; + /* will be freed by put_link */ + nd_set_link(nd, buf); + return NULL; /* success */ + } + __putname(buf); + + out: + path_put(&nd->path); + AuTraceErr(err); + return ERR_PTR(err); +} + +static void aufs_put_link(struct dentry *dentry, struct nameidata *nd, + void *cookie) +{ + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + __putname(nd_get_link(nd)); +} + +/* ---------------------------------------------------------------------- */ + +static void aufs_truncate_range(struct inode *inode, loff_t start, loff_t end) +{ + AuUnsupport(); +} + +/* ---------------------------------------------------------------------- */ + +struct inode_operations aufs_symlink_iop = { + .permission = aufs_permission, + .setattr = aufs_setattr, +#ifdef CONFIG_AUFS_HIN_OR_FUSE + .getattr = aufs_getattr, +#endif + + .readlink = aufs_readlink, + .follow_link = aufs_follow_link, + .put_link = aufs_put_link +}; + +struct inode_operations aufs_dir_iop = { + .create = aufs_create, + .lookup = aufs_lookup, + .link = aufs_link, + .unlink = aufs_unlink, + .symlink = aufs_symlink, + .mkdir = aufs_mkdir, + .rmdir = aufs_rmdir, + .mknod = aufs_mknod, + .rename = aufs_rename, + + .permission = aufs_permission, + .setattr = aufs_setattr, +#ifdef CONFIG_AUFS_HIN_OR_FUSE + .getattr = aufs_getattr, +#endif + +#if 0 /* reserved for future use */ + .setxattr = aufs_setxattr, + .getxattr = aufs_getxattr, + .listxattr = aufs_listxattr, + .removexattr = aufs_removexattr +#endif +}; + +struct inode_operations aufs_iop = { + .permission = aufs_permission, + .setattr = aufs_setattr, +#ifdef CONFIG_AUFS_HIN_OR_FUSE + .getattr = aufs_getattr, +#endif + +#if 0 /* reserved for future use */ + .setxattr = aufs_setxattr, + .getxattr = aufs_getxattr, + .listxattr = aufs_listxattr, + .removexattr = aufs_removexattr, +#endif + + .truncate_range = aufs_truncate_range +}; --- linux-2.6.28.orig/ubuntu/aufs/i_op_del.c +++ linux-2.6.28/ubuntu/aufs/i_op_del.c @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations (del entry) + * + * $Id: i_op_del.c,v 1.12 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +/* returns, + * 0: wh is unnecessary + * plus: wh is necessary + * minus: error + */ +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) +{ + int need_wh, err; + aufs_bindex_t bstart; + struct dentry *h_dentry; + struct super_block *sb; + + LKTRTrace("%.*s, isdir %d, *bcpup %d\n", + AuDLNPair(dentry), isdir, *bcpup); + sb = dentry->d_sb; + + bstart = au_dbstart(dentry); + LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart); + h_dentry = au_h_dptr(dentry, bstart); + if (*bcpup < 0) { + *bcpup = bstart; + if (au_test_ro(sb, bstart, dentry->d_inode)) { + err = AuWbrCopyup(au_sbi(sb), dentry); + *bcpup = err; + if (unlikely(err < 0)) + goto out; + } + } else + AuDebugOn(bstart < *bcpup + || au_test_ro(sb, *bcpup, dentry->d_inode)); + LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart); + + if (*bcpup != bstart) { + err = au_cpup_dirs(dentry, *bcpup); + if (unlikely(err)) + goto out; + need_wh = 1; + } else { + aufs_bindex_t old_bend, new_bend, bdiropq = -1; + old_bend = au_dbend(dentry); + if (isdir) { + bdiropq = au_dbdiropq(dentry); + au_set_dbdiropq(dentry, -1); + } + need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0, + /*nd*/NULL); + err = need_wh; + if (isdir) + au_set_dbdiropq(dentry, bdiropq); + if (unlikely(err < 0)) + goto out; + new_bend = au_dbend(dentry); + if (!need_wh && old_bend != new_bend) { + au_set_h_dptr(dentry, new_bend, NULL); + au_set_dbend(dentry, old_bend); +#if 0 /* todo: remove this? */ + } else if (!au_h_dptr(dentry, new_bend)->d_inode) { + LKTRTrace("negative\n"); + au_set_h_dptr(dentry, new_bend, NULL); + au_set_dbend(dentry, old_bend); + need_wh = 0; +#endif + } + } + LKTRTrace("need_wh %d\n", need_wh); + err = need_wh; + + out: + AuTraceErr(err); + return err; +} + +/* + * simple tests for the removal inode operations. + * following the checks in vfs, plus the parent-child relationship. + */ +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx) +{ + int err, exist; + struct super_block *sb; + struct dentry *h_dentry; + struct inode *h_inode; + umode_t h_mode; + + LKTRTrace("%.*s/%.*s, b%d, dir %d\n", + AuDLNPair(h_parent), AuDLNPair(dentry), bindex, isdir); + + sb = dentry->d_sb; + exist = !!dentry->d_inode; + h_dentry = au_h_dptr(dentry, bindex); + h_inode = h_dentry->d_inode; + if (exist) { + err = -ENOENT; + if (unlikely(!h_inode || !h_inode->i_nlink)) + goto out; + + h_mode = h_inode->i_mode; + if (!isdir) { + err = -EISDIR; + if (unlikely(S_ISDIR(h_mode))) + goto out; + } else if (unlikely(!S_ISDIR(h_mode))) { + err = -ENOTDIR; + goto out; + } + } else { + /* rename(2) case */ + err = -EIO; + if (unlikely(h_inode)) + goto out; + } + + err = -ENOENT; + /* expected parent dir is locked */ + if (unlikely(h_parent != h_dentry->d_parent)) + goto out; + err = 0; + + /* + * some filesystem may unlink a dir and corrupt its consistency. + * so let's try heavy test. + */ + if (1 /*unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))*/) { + struct dentry *h_latest; + struct qstr *qstr = &dentry->d_name; + + err = -EACCES; + if (unlikely(au_test_h_perm(h_parent->d_inode, + MAY_EXEC | MAY_WRITE, + au_ftest_ndx(ndx->flags, DLGT)))) + goto out; + + h_latest = au_sio_lkup_one(qstr->name, h_parent, qstr->len, + ndx); + err = -EIO; + if (IS_ERR(h_latest)) + goto out; + dput(h_latest); + if (h_latest == h_dentry) + err = 0; + } + + out: + AuTraceErr(err); + return err; +} + +static struct dentry * +lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup, + struct au_dtime *dt, struct au_pin *pin) +{ + struct dentry *wh_dentry; + int err, need_wh; + struct dentry *h_parent; + struct au_ndx ndx; + struct super_block *sb; + aufs_bindex_t bcpup; + unsigned int mnt_flags; + + LKTRTrace("%.*s, isdir %d\n", AuDLNPair(dentry), isdir); + + need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup); + err = need_wh; + wh_dentry = ERR_PTR(err); + if (unlikely(err < 0)) + goto out; + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + bcpup = *rbcpup; + err = au_pin(pin, dentry, bcpup, /*di_locked*/1, + /*do_gp*/au_opt_test(mnt_flags, UDBA_INOTIFY)); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out; + h_parent = au_pinned_h_parent(pin, bcpup); + if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) { + ndx.nfsmnt = au_nfsmnt(sb, bcpup); + ndx.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nd = NULL; + /* ndx.br = au_sbr(sb, bcpup); */ + /* ndx.nd_file = NULL; */ + err = au_may_del(dentry, bcpup, h_parent, isdir, &ndx); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_unpin; + } + + au_dtime_store(dt, au_pinned_parent(pin), h_parent, + au_pinned_hdir(pin, bcpup), au_pinned_hgdir(pin, bcpup)); + wh_dentry = NULL; + if (!need_wh) + goto out; /* success, no need to create whiteout */ + + ndx.nfsmnt = au_nfsmnt(sb, bcpup); + ndx.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nd = NULL; + /* ndx.br = NULL; */ + wh_dentry = au_wh_create(dentry, bcpup, h_parent, &ndx); + if (!IS_ERR(wh_dentry)) + goto out; /* success */ + /* returns with the parent is locked and wh_dentry is DGETed */ + + out_unpin: + au_unpin(pin); + out: + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex, + struct au_nhash *whlist, struct inode *dir) +{ + int rmdir_later, err; + struct dentry *h_dentry; + struct inode *inode, *h_inode; + struct super_block *sb; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex); + + inode = NULL; + h_inode = NULL; + sb = dentry->d_sb; + if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))) { + inode = dentry->d_inode; + h_inode = au_h_iptr(inode, bindex); + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + } + h_dentry = au_h_dptr(dentry, bindex); + err = au_whtmp_ren(dir, bindex, h_dentry); + if (unlikely(inode)) { + /* todo: bad approach? */ + if (!err) + au_hin_suspend(au_hi(inode, bindex)); + mutex_unlock(&h_inode->i_mutex); + } + if (unlikely(err)) + goto out; + + if (!au_test_nfs(h_dentry->d_sb)) { + const int dirwh = au_sbi(sb)->si_dirwh; + rmdir_later = (dirwh <= 1); + if (!rmdir_later) + rmdir_later = au_nhash_test_longer_wh(whlist, bindex, + dirwh); + if (rmdir_later) + return rmdir_later; + } + + err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist); + if (unlikely(err)) { + AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n", + AuDLNPair(h_dentry), bindex, err); + /* we do not revert the inotify watch */ + err = 0; + } + + out: + AuTraceErr(err); + return err; +} + +static void epilog(struct inode *dir, struct dentry *dentry, + aufs_bindex_t bindex) +{ + /* todo: unnecessary? */ + d_drop(dentry); + dentry->d_inode->i_ctime = dir->i_ctime; + + if (atomic_read(&dentry->d_count) == 1) { + au_set_h_dptr(dentry, au_dbstart(dentry), NULL); + au_update_dbstart(dentry); + } + if (au_ibstart(dir) == bindex) + au_cpup_attr_timesizes(dir); + dir->i_version++; +} + +/* revert flags */ +#define AuRev_DLGT 1 +#define au_ftest_rev(flags, name) ((flags) & AuRev_##name) +#define au_fset_rev(flags, name) { (flags) |= AuRev_##name; } +#define au_fclr_rev(flags, name) { (flags) &= ~AuRev_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuRev_DLGT +#define AuRev_DLGT 0 +#endif + +static int do_revert(int err, struct inode *dir, aufs_bindex_t bwh, + struct dentry *wh_dentry, struct dentry *dentry, + struct au_dtime *dt, unsigned int flags) +{ + int rerr; + + rerr = au_wh_unlink_dentry(au_hi(dir, bwh), wh_dentry, dentry, + au_ftest_rev(flags, DLGT)); + if (!rerr) { + au_set_dbwh(dentry, bwh); + au_dtime_revert(dt); + return 0; + } + + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + return -EIO; +} + +/* ---------------------------------------------------------------------- */ + +int aufs_unlink(struct inode *dir, struct dentry *dentry) +{ + int err; + struct inode *inode, *h_dir; + struct dentry *parent, *wh_dentry, *h_dentry; + struct au_dtime dt; + aufs_bindex_t bwh, bindex, bstart; + unsigned char dlgt; + struct super_block *sb; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_pin pin; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + inode = dentry->d_inode; + if (unlikely(!inode)) + return -ENOENT; /* possible? */ + IMustLock(inode); + + aufs_read_lock(dentry, AuLock_DW); + parent = dentry->d_parent; /* dir inode is locked */ + di_write_lock_parent(parent); + + bstart = au_dbstart(dentry); + bwh = au_dbwh(dentry); + bindex = -1; + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + sb = dir->i_sb; + dlgt = !!au_test_dlgt(au_mntflags(sb)); + AuDebugOn(au_dbstart(dentry) != bstart); + h_dentry = au_h_dptr(dentry, bstart); + dget(h_dentry); + + if (bindex == bstart) { + vfsub_args_init(&vargs, &ign, dlgt, 0); + vfsub_ign_hinode(&vargs, IN_DELETE, au_pinned_hdir(&pin, + bstart)); + h_dir = au_pinned_h_dir(&pin); + err = vfsub_unlink(h_dir, h_dentry, &vargs); + } else { + /* dir inode is locked */ + AuDebugOn(!wh_dentry + || wh_dentry->d_parent != au_h_dptr(parent, bindex)); + h_dir = wh_dentry->d_parent->d_inode; + IMustLock(h_dir); + err = 0; + } + + if (!err) { + drop_nlink(inode); +#if 0 /* todo: update plink? */ + if (unlikely(!inode->i_nlink + && au_plink_test(sb, inode) + /* && atomic_read(&inode->i_count) == 2) */)) { + au_debug_on(); + DbgInode(inode); + au_debug_off(); + } +#endif +#if 0 + /* + * although this is not a dir, + * set it here since we need to detect + * the dead inode in d_revalidate(). + */ + if (!inode->i_nlink) + inode->i_flags |= S_DEAD; +#endif + epilog(dir, dentry, bindex); + + /* update target timestamps */ + if (bindex == bstart) { + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ + inode->i_ctime = h_dentry->d_inode->i_ctime; + } else + /* todo: this timestamp may be reverted later */ + inode->i_ctime = h_dir->i_ctime; + goto out_unlock; /* success */ + } + + /* revert */ + if (wh_dentry) { + int rerr; + unsigned int rev_flags; + + rev_flags = 0; + if (unlikely(dlgt)) + au_fset_rev(rev_flags, DLGT); + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt, + rev_flags); + if (rerr) + err = rerr; + } + + out_unlock: + au_unpin(&pin); + dput(wh_dentry); + dput(h_dentry); + out: + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuTraceErr(err); + return err; +} + +int aufs_rmdir(struct inode *dir, struct dentry *dentry) +{ + int err, rmdir_later; + struct inode *inode; + struct dentry *parent, *wh_dentry, *h_dentry; + struct au_dtime dt; + aufs_bindex_t bwh, bindex, bstart; + struct au_whtmp_rmdir_args *args; + struct au_nhash *whlist; + struct super_block *sb; + unsigned int mnt_flags; + struct au_pin pin; + + LKTRTrace("i%lu, %.*s\n", dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); +#if 0 + err = -ENOENT; /* possible? */ + if (unlikely(IS_DEADDIR(dir))) { + AuDbg("here\n"); + goto out; + } +#endif + inode = dentry->d_inode; + err = -ENOENT; /* possible? */ + if (unlikely(!inode + //|| IS_DEADDIR(inode) || IS_DEADDIR(dir) + )) { + //AuDbg("here\n"); + goto out; + } + IMustLock(inode); + + whlist = au_nhash_new(GFP_NOFS); + err = PTR_ERR(whlist); + if (IS_ERR(whlist)) + goto out; + + err = -ENOMEM; + args = kmalloc(sizeof(*args), GFP_NOFS); + if (unlikely(!args)) + goto out_whlist; + + aufs_read_lock(dentry, AuLock_DW); + parent = dentry->d_parent; /* dir inode is locked */ + di_write_lock_parent(parent); + err = au_test_empty(dentry, whlist); + if (unlikely(err)) + goto out_args; + + bstart = au_dbstart(dentry); + bwh = au_dbwh(dentry); + bindex = -1; + wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_args; + + AuDebugOn(au_dbstart(dentry) != bstart); + h_dentry = au_h_dptr(dentry, bstart); + dget(h_dentry); + + rmdir_later = 0; + if (bindex == bstart) { + err = renwh_and_rmdir(dentry, bstart, whlist, dir); + if (err > 0) { + rmdir_later = err; + err = 0; + } + } else { + /* dir inode is locked */ + AuDebugOn(!wh_dentry + || wh_dentry->d_parent != au_h_dptr(parent, bindex)); + IMustLock(wh_dentry->d_parent->d_inode); + err = 0; + } + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + if (!err) { + if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY) + && rmdir_later)) + au_reset_hinotify(inode, /*flags*/0); + clear_nlink(inode); + //inode->i_flags |= S_DEAD; + au_set_dbdiropq(dentry, -1); + epilog(dir, dentry, bindex); + + if (rmdir_later) { + au_whtmp_kick_rmdir(dir, bstart, h_dentry, whlist, + args); + args = NULL; + } + + goto out_unlock; /* success */ + } + + /* revert */ + LKTRLabel(revert); + if (wh_dentry) { + int rerr; + unsigned int rev_flags; + + rev_flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_rev(rev_flags, DLGT); + rerr = do_revert(err, dir, bwh, wh_dentry, dentry, &dt, + rev_flags); + if (rerr) + err = rerr; + } + + out_unlock: + au_unpin(&pin); + dput(wh_dentry); + dput(h_dentry); + out_args: + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + kfree(args); + out_whlist: + au_nhash_del(whlist); + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/super.h +++ linux-2.6.28/ubuntu/aufs/super.h @@ -0,0 +1,494 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * super_block operations + * + * $Id: super.h,v 1.14 2008/09/15 03:14:52 sfjro Exp $ + */ + +#ifndef __AUFS_SUPER_H__ +#define __AUFS_SUPER_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include "misc.h" +#include "wkq.h" + +typedef ssize_t (*au_readf_t)(struct file *, char __user *, size_t, loff_t *); +typedef ssize_t (*au_writef_t)(struct file *, const char __user *, size_t, + loff_t *); + +struct au_wbr_copyup_operations { + int (*copyup)(struct dentry *dentry); +}; + +struct au_wbr_create_operations { + int (*create)(struct dentry *dentry, int isdir); + int (*init)(struct super_block *sb); + int (*fin)(struct super_block *sb); +}; + +struct au_wbr_mfs { + struct mutex mfs_lock; /* protect this structure */ + unsigned long mfs_jiffy; + unsigned long mfs_expire; + aufs_bindex_t mfs_bindex; + + unsigned long long mfsrr_bytes; + unsigned long long mfsrr_watermark; +}; + +/* sbinfo status flags */ +/* + * set true when refresh_dirs() failed at remount time. + * then try refreshing dirs at access time again. + * if it is false, refreshing dirs at access time is unnecesary + */ +#define AuSi_FAILED_REFRESH_DIRS 1 +#define au_ftest_si(sbinfo, name) ((sbinfo)->au_si_status & AuSi_##name) +#define au_fset_si(sbinfo, name) \ + { (sbinfo)->au_si_status |= AuSi_##name; } +#define au_fclr_si(sbinfo, name) \ + { (sbinfo)->au_si_status &= ~AuSi_##name; } + +struct au_branch; +struct au_sbinfo { + /* nowait tasks in the system-wide workqueue */ + struct au_nowait_tasks si_nowait; + + struct au_rwsem si_rwsem; + + /* branch management */ + au_gen_t si_generation; + + /* see above flags */ + unsigned char au_si_status; + + aufs_bindex_t si_bend; + aufs_bindex_t si_last_br_id; + struct au_branch **si_branch; + + /* policy to select a writable branch */ + unsigned char si_wbr_copyup; + unsigned char si_wbr_create; + struct au_wbr_copyup_operations *si_wbr_copyup_ops; + struct au_wbr_create_operations *si_wbr_create_ops; + + /* round robin */ + atomic_t si_wbr_rr_next; + + /* most free space */ + struct au_wbr_mfs si_wbr_mfs; + + /* mount flags */ + /* include/asm-ia64/siginfo.h defines a macro named si_flags */ + unsigned int si_mntflags; + + /* external inode number (bitmap and translation table) */ + au_readf_t si_xread; + au_writef_t si_xwrite; + struct file *si_xib; + struct mutex si_xib_mtx; /* protect xib members */ + unsigned long *si_xib_buf; + unsigned long si_xib_last_pindex; + int si_xib_next_bit; + /* reserved for future use */ + /* unsigned long long si_xib_limit; */ /* Max xib file size */ + +#ifdef CONFIG_AUFS_HINOTIFY + struct au_branch *si_xino_def_br; +#endif + +#ifdef CONFIG_AUFS_EXPORT + /* i_generation */ + struct file *si_xigen; + /* todo: atomic_t? */ + spinlock_t si_xigen_lock; + __u32 si_xigen_next; +#endif + + /* readdir cache time, max, in HZ */ + unsigned long si_rdcache; + + /* + * If the number of whiteouts are larger than si_dirwh, leave all of + * them after au_whtmp_ren to reduce the cost of rmdir(2). + * future fsck.aufs or kernel thread will remove them later. + * Otherwise, remove all whiteouts and the dir in rmdir(2). + */ + unsigned int si_dirwh; + + /* + * rename(2) a directory with all children. + */ + /* reserved for future use */ + /* int si_rendir; */ + + /* pseudo_link list */ /* todo: dirty? */ + spinlock_t si_plink_lock; + struct list_head si_plink; + +#if defined(CONFIG_AUFS_EXPORT) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + /* dirty, for export, async ops, and sysfs */ + spinlock_t si_mntcache_lock; + struct vfsmount *si_mntcache; /* no get/put */ +#endif + + /* + * sysfs and lifetime management. + * this is not a small structure and it may be a waste of memory in case + * of sysfs is disabled, particulary when many aufs-es are mounted. + */ + struct kobject si_kobj; + +#ifdef CONFIG_AUFS_ROBR + /* locked vma list for mmap() */ /* todo: dirty? */ + spinlock_t si_lvma_lock; + struct list_head si_lvma; +#endif + +#ifdef CONFIG_AUFS_EXPORT /* reserved for future use */ + struct path si_xinodir; +#endif + + /* dirty, necessary for unmounting, sysfs and sysrq */ + struct super_block *si_sb; +}; + +/* ---------------------------------------------------------------------- */ + +/* policy to select one among writable branches */ +#define AuWbrCopyup(sbinfo, args...) \ + (sbinfo)->si_wbr_copyup_ops->copyup(args) +#define AuWbrCreate(sbinfo, args...) \ + (sbinfo)->si_wbr_create_ops->create(args) + +/* flags for si_read_lock()/aufs_read_lock()/di_read_lock() */ +#define AuLock_DW 1 /* write-lock dentry */ +#define AuLock_IR (1 << 1) /* read-lock inode */ +#define AuLock_IW (1 << 2) /* write-lock inode */ +#define AuLock_FLUSH (1 << 3) /* wait for 'nowait' tasks */ +#define AuLock_DIR (1 << 4) /* target is a dir */ +#define au_ftest_lock(flags, name) ((flags) & AuLock_##name) +#define au_fset_lock(flags, name) { (flags) |= AuLock_##name; } +#define au_fclr_lock(flags, name) { (flags) &= ~AuLock_##name; } + +/* ---------------------------------------------------------------------- */ + +/* super.c */ +extern struct file_system_type aufs_fs_type; +struct inode *au_iget_locked(struct super_block *sb, ino_t ino); + +/* sbinfo.c */ +void au_si_free(struct kobject *kobj); +int au_si_alloc(struct super_block *sb); +struct au_branch *au_sbr(struct super_block *sb, aufs_bindex_t bindex); +au_gen_t au_sigen_inc(struct super_block *sb); +int au_find_bindex(struct super_block *sb, struct au_branch *br); + +void aufs_read_lock(struct dentry *dentry, int flags); +void aufs_read_unlock(struct dentry *dentry, int flags); +void aufs_write_lock(struct dentry *dentry); +void aufs_write_unlock(struct dentry *dentry); +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int isdir); +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2); + +aufs_bindex_t au_new_br_id(struct super_block *sb); + +/* wbr_policy.c */ +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; +extern struct au_wbr_create_operations au_wbr_create_ops[]; +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); + +/* ---------------------------------------------------------------------- */ + +#if defined(CONFIG_AUFS_EXPORT) && LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static inline void au_mnt_init(struct au_sbinfo *sbinfo, struct vfsmount *mnt) +{ + spin_lock_init(&sbinfo->si_mntcache_lock); + sbinfo->si_mntcache = mnt; +} + +static inline void au_mnt_reset(struct au_sbinfo *sbinfo) +{ + spin_lock(&sbinfo->si_mntcache_lock); + sbinfo->si_mntcache = NULL; + spin_unlock(&sbinfo->si_mntcache_lock); +} +#else +static inline void au_mnt_init(struct au_sbinfo *sbinfo, struct vfsmount *mnt) +{ + /* emptr */ +} + +static inline void au_mnt_reset(struct au_sbinfo *sbinfo) +{ + /* emptr */ +} +#endif /* EXPORT && < 2.6.26 */ + +/* ---------------------------------------------------------------------- */ + +static inline struct au_sbinfo *au_sbi(struct super_block *sb) +{ + return sb->s_fs_info; +} + +static inline const char *au_sbtype(struct super_block *sb) +{ + return sb->s_type->name; +} + +static inline int au_test_aufs(struct super_block *sb) +{ + return (sb->s_magic == AUFS_SUPER_MAGIC); +} + +static inline int au_test_nfs(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_BR_NFS + return (sb->s_magic == NFS_SUPER_MAGIC); +#else + return 0; +#endif +} + +static inline int au_test_fuse(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_WORKAROUND_FUSE + return (sb->s_magic == FUSE_SUPER_MAGIC); +#else + return 0; +#endif +} + +static inline int au_test_xfs(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_BR_XFS + return (sb->s_magic == XFS_SB_MAGIC); +#else + return 0; +#endif +} + +static inline int au_test_tmpfs(struct super_block *sb) +{ +#ifdef CONFIG_TMPFS + return (sb->s_magic == TMPFS_MAGIC); +#else + return 0; +#endif +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HINOTIFY +static inline void au_xino_def_br_set(struct au_branch *br, + struct au_sbinfo *sbinfo) +{ + sbinfo->si_xino_def_br = br; +} + +static inline struct au_branch *au_xino_def_br(struct au_sbinfo *sbinfo) +{ + return sbinfo->si_xino_def_br; +} +#else +static inline void au_xino_def_br_set(struct au_branch *br, + struct au_sbinfo *sbinfo) +{ + /* empty */ +} + +static inline struct au_branch *au_xino_def_br(struct au_sbinfo *sbinfo) +{ + return NULL; +} +#endif + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_EXPORT +void au_export_init(struct super_block *sb); + +static inline int au_test_nfsd(struct task_struct *tsk) +{ + return (!tsk->mm && !strcmp(tsk->comm, "nfsd")); +} + +static inline void au_nfsd_lockdep_off(void) +{ + if (au_test_nfsd(current)) + lockdep_off(); +} + +static inline void au_nfsd_lockdep_on(void) +{ + if (au_test_nfsd(current)) + lockdep_on(); +} + +static inline void au_export_put(struct au_sbinfo *sbinfo) +{ + path_put(&sbinfo->si_xinodir); +} + +int au_xigen_inc(struct inode *inode); +int au_xigen_new(struct inode *inode); +int au_xigen_set(struct super_block *sb, struct file *base); +void au_xigen_clr(struct super_block *sb); + +#else +static inline void au_export_init(struct super_block *sb) +{ + /* nothing */ +} + +static inline int au_test_nfsd(struct task_struct *tsk) +{ + return 0; +} + +#define au_nfsd_lockdep_off() do {} while (0) +#define au_nfsd_lockdep_on() do {} while (0) + +static inline void au_export_put(struct au_sbinfo *sbinfo) +{ + /* nothing */ +} + +static inline int au_xigen_inc(struct inode *inode) +{ + return 0; +} + +static inline int au_xigen_new(struct inode *inode) +{ + return 0; +} + +static inline int au_xigen_set(struct super_block *sb, struct file *base) +{ + return 0; +} + +static inline void au_xigen_clr(struct super_block *sb) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_EXPORT */ + +#ifdef CONFIG_AUFS_ROBR +static inline int au_test_nested(struct super_block *h_sb) +{ + return 0; +} + +static inline void au_robr_lvma_init(struct au_sbinfo *sbinfo) +{ + spin_lock_init(&sbinfo->si_lvma_lock); + INIT_LIST_HEAD(&sbinfo->si_lvma); +} +#else +static inline int au_test_nested(struct super_block *h_sb) +{ + int err = 0; + if (unlikely(au_test_aufs(h_sb))) { + err = -EINVAL; + AuTraceErr(err); + } + return err; +} + +static inline void au_robr_lvma_init(struct au_sbinfo *sbinfo) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_ROBR */ + +/* ---------------------------------------------------------------------- */ + +/* lock superblock. mainly for entry point functions */ +/* + * si_noflush_read_lock, si_noflush_write_lock, + * si_read_unlock, si_write_unlock, si_downgrade_lock + */ +AuSimpleLockRwsemFuncs(si_noflush, struct super_block *sb, + au_sbi(sb)->si_rwsem); +AuSimpleUnlockRwsemFuncs(si, struct super_block *sb, au_sbi(sb)->si_rwsem); + +static inline void si_read_lock(struct super_block *sb, int flags) +{ + if (au_ftest_lock(flags, FLUSH)) + au_nwt_flush(&au_sbi(sb)->si_nowait); + si_noflush_read_lock(sb); +} + +static inline void si_write_lock(struct super_block *sb) +{ + au_nwt_flush(&au_sbi(sb)->si_nowait); + si_noflush_write_lock(sb); +} + +static inline int si_read_trylock(struct super_block *sb, int flags) +{ + if (au_ftest_lock(flags, FLUSH)) + au_nwt_flush(&au_sbi(sb)->si_nowait); + return si_noflush_read_trylock(sb); +} + +static inline int si_write_trylock(struct super_block *sb, int flags) +{ + if (au_ftest_lock(flags, FLUSH)) + au_nwt_flush(&au_sbi(sb)->si_nowait); + return si_noflush_write_trylock(sb); +} + +/* to debug easier, do not make them inlined functions */ +#define SiMustReadLock(sb) AuRwMustReadLock(&au_sbi(sb)->si_rwsem) +#define SiMustWriteLock(sb) AuRwMustWriteLock(&au_sbi(sb)->si_rwsem) +#define SiMustAnyLock(sb) AuRwMustAnyLock(&au_sbi(sb)->si_rwsem) + +/* ---------------------------------------------------------------------- */ + +static inline aufs_bindex_t au_sbend(struct super_block *sb) +{ + SiMustAnyLock(sb); + return au_sbi(sb)->si_bend; +} + +static inline unsigned int au_mntflags(struct super_block *sb) +{ + SiMustAnyLock(sb); + return au_sbi(sb)->si_mntflags; +} + +static inline au_gen_t au_sigen(struct super_block *sb) +{ + SiMustAnyLock(sb); + return au_sbi(sb)->si_generation; +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_SUPER_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/super.c +++ linux-2.6.28/ubuntu/aufs/super.c @@ -0,0 +1,863 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * mount and super_block operations + * + * $Id: super.c,v 1.16 2008/09/15 03:14:49 sfjro Exp $ + */ + +#include +#include +#include +#include +#include + +#include "aufs.h" + +/* + * super_operations + */ +static struct inode *aufs_alloc_inode(struct super_block *sb) +{ + struct aufs_icntnr *c; + + AuTraceEnter(); + + c = au_cache_alloc_icntnr(); + if (c) { + inode_init_once(&c->vfs_inode); + c->vfs_inode.i_version = 1; /* sigen(sb); */ + c->iinfo.ii_hinode = NULL; + return &c->vfs_inode; + } + return NULL; +} + +static void aufs_destroy_inode(struct inode *inode) +{ + int err; + + LKTRTrace("i%lu\n", inode->i_ino); + + if (!inode->i_nlink) { + struct super_block *sb = inode->i_sb; + int locked; + + /* in nowait task, sbi is write-locked */ + /* todo: test kernel thread */ + locked = si_noflush_read_trylock(sb); + err = au_xigen_inc(inode); + if (unlikely(err)) + AuWarn1("failed resetting i_generation, %d\n", err); + if (locked) + si_read_unlock(sb); + } + + au_iinfo_fin(inode); + au_cache_free_icntnr(container_of(inode, struct aufs_icntnr, + vfs_inode)); +} + +struct inode *au_iget_locked(struct super_block *sb, ino_t ino) +{ + struct inode *inode; + int err; + + LKTRTrace("i%lu\n", (unsigned long)ino); + + inode = iget_locked(sb, ino); + if (unlikely(!inode)) { + inode = ERR_PTR(-ENOMEM); + goto out; + } + AuDebugOn(IS_ERR(inode)); + if (unlikely(!(inode->i_state & I_NEW))) + goto out; + + err = au_xigen_new(inode); + if (!err) + err = au_iinfo_init(inode); + if (!err) + inode->i_version++; + else { + iget_failed(inode); + inode = ERR_PTR(err); + } + + out: + /* never return NULL */ + AuDebugOn(!inode); + AuTraceErrPtr(inode); + return inode; +} + +static int au_show_brs(struct seq_file *seq, struct super_block *sb) +{ + int err; + aufs_bindex_t bindex, bend; + struct dentry *root; + struct path path; + + AuTraceEnter(); + + err = 0; + root = sb->s_root; + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) { + path.mnt = au_sbr_mnt(sb, bindex); + path.dentry = au_h_dptr(root, bindex); + err = seq_path(seq, &path, au_esc_chars); + if (err > 0) + err = seq_printf + (seq, "=%s", + au_optstr_br_perm(au_sbr_perm(sb, bindex))); + if (!err && bindex != bend) + err = seq_putc(seq, ':'); + } + + AuTraceErr(err); + return err; +} + +static void au_show_wbr_create(struct seq_file *m, int v, + struct au_sbinfo *sbinfo) +{ + const char *pat; + + AuDebugOn(v == AuWbrCreate_Def); + + seq_printf(m, ",create="); + pat = au_optstr_wbr_create(v); + switch (v) { + case AuWbrCreate_TDP: + case AuWbrCreate_RR: + case AuWbrCreate_MFS: + case AuWbrCreate_PMFS: + seq_printf(m, pat); + break; + case AuWbrCreate_MFSV: + seq_printf(m, /*pat*/"mfs:%lu", + sbinfo->si_wbr_mfs.mfs_expire / HZ); + break; + case AuWbrCreate_PMFSV: + seq_printf(m, /*pat*/"pmfs:%lu", + sbinfo->si_wbr_mfs.mfs_expire / HZ); + break; + case AuWbrCreate_MFSRR: + seq_printf(m, /*pat*/"mfsrr:%llu", + sbinfo->si_wbr_mfs.mfsrr_watermark); + break; + case AuWbrCreate_MFSRRV: + seq_printf(m, /*pat*/"mfsrr:%llu:%lu", + sbinfo->si_wbr_mfs.mfsrr_watermark, + sbinfo->si_wbr_mfs.mfs_expire / HZ); + break; + } +} + +/* seq_file will re-call me in case of too long string */ +static int aufs_show_options(struct seq_file *m, struct vfsmount *mnt) +{ + int err, n; + struct super_block *sb; + struct au_sbinfo *sbinfo; + struct dentry *root; + struct file *xino; + unsigned int mnt_flags, v; + struct path path; + + AuTraceEnter(); + + sb = mnt->mnt_sb; + root = sb->s_root; + if (!sysaufs_brs) + aufs_read_lock(root, !AuLock_IR); + else + si_noflush_read_lock(sb); + sbinfo = au_sbi(sb); + seq_printf(m, ",si=%lx", au_si_mask ^ (unsigned long)sbinfo); + mnt_flags = au_mntflags(sb); + if (au_opt_test(mnt_flags, XINO)) { + seq_puts(m, ",xino="); + xino = sbinfo->si_xib; + path.mnt = xino->f_vfsmnt; + path.dentry = xino->f_dentry; + err = seq_path(m, &path, au_esc_chars); + if (unlikely(err <= 0)) + goto out; + err = 0; +#define Deleted "\\040(deleted)" + m->count -= sizeof(Deleted) - 1; + AuDebugOn(memcmp(m->buf + m->count, Deleted, + sizeof(Deleted) - 1)); +#undef Deleted +#ifdef CONFIG_AUFS_EXPORT /* reserved for future use */ + } else if (au_opt_test(mnt_flags, XINODIR)) { + seq_puts(m, ",xinodir="); + seq_path(m, &sbinfo->si_xinodir, au_esc_chars); +#endif + } else + seq_puts(m, ",noxino"); + +#define AuBool(name, str) do { \ + v = au_opt_test(mnt_flags, name); \ + if (v != au_opt_test(AuOpt_Def, name)) \ + seq_printf(m, ",%s" #str, v ? "" : "no"); \ +} while (0) + +#define AuStr(name, str) do { \ + v = mnt_flags & AuOptMask_##name; \ + if (v != (AuOpt_Def & AuOptMask_##name)) \ + seq_printf(m, "," #str "=%s", au_optstr_##str(v)); \ +} while (0) + +#ifdef CONFIG_AUFS_COMPAT +#define AuStr_BrOpt "dirs=" +#else +#define AuStr_BrOpt "br:" +#endif + + AuBool(TRUNC_XINO, trunc_xino); + AuBool(DIRPERM1, dirperm1); + AuBool(SHWH, shwh); + AuBool(PLINK, plink); + AuStr(UDBA, udba); + + v = sbinfo->si_wbr_create; + if (v != AuWbrCreate_Def) + au_show_wbr_create(m, v, sbinfo); + + v = sbinfo->si_wbr_copyup; + if (v != AuWbrCopyup_Def) + seq_printf(m, ",cpup=%s", au_optstr_wbr_copyup(v)); + + v = au_opt_test(mnt_flags, ALWAYS_DIROPQ); + if (v != au_opt_test(AuOpt_Def, ALWAYS_DIROPQ)) + seq_printf(m, ",diropq=%c", v ? 'a' : 'w'); + AuBool(REFROF, refrof); + AuBool(DLGT, dlgt); + AuBool(WARN_PERM, warn_perm); + AuBool(VERBOSE, verbose); + + n = sbinfo->si_dirwh; + if (n != AUFS_DIRWH_DEF) + seq_printf(m, ",dirwh=%d", n); + n = sbinfo->si_rdcache / HZ; + if (n != AUFS_RDCACHE_DEF) + seq_printf(m, ",rdcache=%d", n); + + AuStr(COO, coo); + + out: + if (!sysaufs_brs) { + seq_puts(m, "," AuStr_BrOpt); + au_show_brs(m, sb); + aufs_read_unlock(root, !AuLock_IR); + } else + si_read_unlock(sb); + return 0; + +#undef AuBool +#undef AuStr +#undef AuStr_BrOpt +} + +/* todo: in case of round-robin policy, return the sum of all rw branches? */ +static int aufs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + int err; + + AuTraceEnter(); + + aufs_read_lock(dentry->d_sb->s_root, 0); + err = vfsub_statfs(au_h_dptr(dentry->d_sb->s_root, 0), buf, + !!au_test_dlgt(au_mntflags(dentry->d_sb))); + aufs_read_unlock(dentry->d_sb->s_root, 0); + if (!err) { + buf->f_type = AUFS_SUPER_MAGIC; + buf->f_namelen -= AUFS_WH_PFX_LEN; + memset(&buf->f_fsid, 0, sizeof(buf->f_fsid)); + } + /* buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1; */ + + AuTraceErr(err); + return err; +} + +static void au_fsync_br(struct super_block *sb) +{ +#ifdef CONFIG_AUFS_FSYNC_SUPER_PATCH + aufs_bindex_t bend, bindex; + int brperm; + struct super_block *h_sb; + + AuTraceEnter(); + + si_write_lock(sb); + bend = au_sbend(sb); + for (bindex = 0; bindex < bend; bindex++) { + brperm = au_sbr_perm(sb, bindex); + if (brperm == AuBrPerm_RR || brperm == AuBrPerm_RRWH) + continue; + h_sb = au_sbr_sb(sb, bindex); + if (bdev_read_only(h_sb->s_bdev)) + continue; + + lockdep_off(); + down_write(&h_sb->s_umount); + shrink_dcache_sb(h_sb); + fsync_super(h_sb); + up_write(&h_sb->s_umount); + lockdep_on(); + } + si_write_unlock(sb); +#endif +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) +/* this IS NOT for super_operations */ +static void aufs_umount_begin(struct super_block *arg) +#define AuUmountBeginSb(arg) (arg) +#else +/* this IS for super_operations */ +static void aufs_umount_begin(struct vfsmount *arg, int flags) +#define AuUmountBeginSb(arg) (arg)->mnt_sb +#endif +{ + struct super_block *sb = AuUmountBeginSb(arg); + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + /* dont trust BKL */ + AuDebugOn(!kernel_locked()); + + sbinfo = au_sbi(sb); + if (unlikely(!sbinfo)) + return; + + au_fsync_br(sb); + + si_write_lock(sb); + if (au_opt_test(au_mntflags(sb), PLINK)) + au_plink_put(sb); + au_mnt_reset(sbinfo); +#if 0 /* reserved for future use */ + if (sbinfo->si_wbr_create_ops->fin) + sbinfo->si_wbr_create_ops->fin(sb); +#endif + si_write_unlock(sb); +} + +/* final actions when unmounting a file system */ +static void aufs_put_super(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + + sbinfo = au_sbi(sb); + if (unlikely(!sbinfo)) + return; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26) + aufs_umount_begin(sb); +#endif + kobject_put(&sbinfo->si_kobj); +} + +/* ---------------------------------------------------------------------- */ + +/* + * refresh dentry and inode at remount time. + */ +static int do_refresh(struct dentry *dentry, mode_t type, + unsigned int dir_flags) +{ + int err; + struct dentry *parent; + struct inode *inode; + + LKTRTrace("%.*s, 0%o\n", AuDLNPair(dentry), type); + inode = dentry->d_inode; + AuDebugOn(!inode); + + di_write_lock_child(dentry); + parent = dget_parent(dentry); + di_read_lock_parent(parent, AuLock_IR); + /* returns a number of positive dentries */ + err = au_refresh_hdentry(dentry, type); + if (err >= 0) { + err = au_refresh_hinode(inode, dentry); + if (!err && type == S_IFDIR) + au_reset_hinotify(inode, dir_flags); + } + if (unlikely(err)) + AuErr("unrecoverable error %d, %.*s\n", err, AuDLNPair(dentry)); + di_read_unlock(parent, AuLock_IR); + dput(parent); + di_write_unlock(dentry); + + AuTraceErr(err); + return err; +} + +static int test_dir(struct dentry *dentry, void *arg) +{ + return S_ISDIR(dentry->d_inode->i_mode); +} + +/* todo: merge with refresh_nondir()? */ +static int refresh_dir(struct dentry *root, au_gen_t sgen) +{ + int err, i, j, ndentry, e; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + struct inode *inode; + const unsigned int flags = au_hi_flags(root->d_inode, /*isdir*/1); + + LKTRTrace("sgen %d\n", sgen); + SiMustWriteLock(root->d_sb); + /* dont trust BKL */ + AuDebugOn(au_digen(root) != sgen || !kernel_locked()); + + err = 0; + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) + if (S_ISDIR(inode->i_mode) && au_iigen(inode) != sgen) { + ii_write_lock_child(inode); + e = au_refresh_hinode_self(inode); + ii_write_unlock(inode); + if (unlikely(e)) { + LKTRTrace("e %d, i%lu\n", e, inode->i_ino); + if (!err) + err = e; + /* go on even if err */ + } + } + + e = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(e)) { + if (!err) + err = e; + goto out; + } + e = au_dcsub_pages(&dpages, root, test_dir, NULL); + if (unlikely(e)) { + if (!err) + err = e; + goto out_dpages; + } + + for (i = 0; !e && i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + ndentry = dpage->ndentry; + for (j = 0; !e && j < ndentry; j++) { + struct dentry *d; + d = dentries[j]; +#ifdef CONFIG_AUFS_DEBUG + { + struct dentry *parent; + parent = dget_parent(d); + AuDebugOn(!S_ISDIR(d->d_inode->i_mode) + || IS_ROOT(d) + || au_digen(parent) != sgen); + dput(parent); + } +#endif + if (au_digen(d) != sgen) { + e = do_refresh(d, S_IFDIR, flags); + if (unlikely(e && !err)) + err = e; + /* break on err */ + } + } + } + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErr(err); + return err; +} + +static int test_nondir(struct dentry *dentry, void *arg) +{ + return !S_ISDIR(dentry->d_inode->i_mode); +} + +static int refresh_nondir(struct dentry *root, au_gen_t sgen, int do_dentry) +{ + int err, i, j, ndentry, e; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + struct inode *inode; + + LKTRTrace("sgen %d\n", sgen); + SiMustWriteLock(root->d_sb); + /* dont trust BKL */ + AuDebugOn(au_digen(root) != sgen || !kernel_locked()); + + err = 0; + list_for_each_entry(inode, &root->d_sb->s_inodes, i_sb_list) + if (!S_ISDIR(inode->i_mode) && au_iigen(inode) != sgen) { + ii_write_lock_child(inode); + e = au_refresh_hinode_self(inode); + ii_write_unlock(inode); + if (unlikely(e)) { + LKTRTrace("e %d, i%lu\n", e, inode->i_ino); + if (!err) + err = e; + /* go on even if err */ + } + } + + if (!do_dentry) + goto out; + + e = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(e)) { + if (!err) + err = e; + goto out; + } + e = au_dcsub_pages(&dpages, root, test_nondir, NULL); + if (unlikely(e)) { + if (!err) + err = e; + goto out_dpages; + } + + for (i = 0; i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + ndentry = dpage->ndentry; + for (j = 0; j < ndentry; j++) { + struct dentry *d; + d = dentries[j]; +#ifdef CONFIG_AUFS_DEBUG + { + struct dentry *parent; + parent = dget_parent(d); + AuDebugOn(S_ISDIR(d->d_inode->i_mode) + || au_digen(parent) != sgen); + dput(parent); + } +#endif + inode = d->d_inode; + if (inode && au_digen(d) != sgen) { + e = do_refresh(d, inode->i_mode & S_IFMT, 0); + if (unlikely(e && !err)) + err = e; + /* go on even err */ + } + } + } + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErr(err); + return err; +} + +/* stop extra interpretation of errno in mount(8), and strange error messages */ +static int cvt_err(int err) +{ + AuTraceErr(err); + + switch (err) { + case -ENOENT: + case -ENOTDIR: + case -EEXIST: + case -EIO: + err = -EINVAL; + } + return err; +} + +/* protected by s_umount */ +static int aufs_remount_fs(struct super_block *sb, int *flags, char *data) +{ + int err, rerr; + au_gen_t sigen; + struct dentry *root; + struct inode *inode; + struct au_opts opts; + struct au_sbinfo *sbinfo; + unsigned char dlgt; + + LKTRTrace("flags 0x%x, data %s, len %lu\n", + *flags, data ? data : "NULL", + (unsigned long)(data ? strlen(data) : 0)); + + au_fsync_br(sb); + + err = 0; + if (!data || !*data) + goto out; /* success */ + + err = -ENOMEM; + memset(&opts, 0, sizeof(opts)); + opts.opt = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!opts.opt)) + goto out; + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); + opts.flags = AuOpts_REMOUNT; + + /* parse it before aufs lock */ + err = au_opts_parse(sb, *flags, data, &opts); + if (unlikely(err)) + goto out_opts; + + sbinfo = au_sbi(sb); + root = sb->s_root; + inode = root->d_inode; + mutex_lock(&inode->i_mutex); + aufs_write_lock(root); + + /* au_do_opts() may return an error */ + err = au_opts_remount(sb, &opts); + au_opts_free(&opts); + + if (au_ftest_opts(opts.flags, REFRESH_DIR) + || au_ftest_opts(opts.flags, REFRESH_NONDIR)) { + dlgt = !!au_opt_test(sbinfo->si_mntflags, DLGT); + au_opt_clr(sbinfo->si_mntflags, DLGT); + au_sigen_inc(sb); + au_reset_hinotify(inode, au_hi_flags(inode, /*isdir*/1)); + sigen = au_sigen(sb); + au_fclr_si(sbinfo, FAILED_REFRESH_DIRS); + + DiMustNoWaiters(root); + IiMustNoWaiters(root->d_inode); + di_write_unlock(root); + + rerr = refresh_dir(root, sigen); + if (unlikely(rerr)) { + au_fset_si(sbinfo, FAILED_REFRESH_DIRS); + AuWarn("Refreshing directories failed, ignores (%d)\n", + rerr); + } + + if (unlikely(au_ftest_opts(opts.flags, REFRESH_NONDIR))) { + rerr = refresh_nondir(root, sigen, !rerr); + if (unlikely(rerr)) + AuWarn("Refreshing non-directories failed," + " ignores (%d)\n", rerr); + } + + /* aufs_write_lock() calls ..._child() */ + di_write_lock_child(root); + + au_cpup_attr_all(inode); + if (unlikely(dlgt)) + au_opt_set(sbinfo->si_mntflags, DLGT); + } + + aufs_write_unlock(root); + mutex_unlock(&inode->i_mutex); + + out_opts: + free_page((unsigned long)opts.opt); + out: + err = cvt_err(err); + AuTraceErr(err); + return err; +} + +static struct super_operations aufs_sop = { + .alloc_inode = aufs_alloc_inode, + .destroy_inode = aufs_destroy_inode, + .drop_inode = generic_delete_inode, + + .show_options = aufs_show_options, + .statfs = aufs_statfs, + + .put_super = aufs_put_super, + .remount_fs = aufs_remount_fs, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + .umount_begin = aufs_umount_begin +#endif +}; + +/* ---------------------------------------------------------------------- */ + +static int alloc_root(struct super_block *sb) +{ + int err; + struct inode *inode; + struct dentry *root; + + AuTraceEnter(); + + err = -ENOMEM; + inode = au_iget_locked(sb, AUFS_ROOT_INO); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out; + inode->i_op = &aufs_dir_iop; + inode->i_fop = &aufs_dir_fop; + inode->i_mode = S_IFDIR; + unlock_new_inode(inode); + root = d_alloc_root(inode); + if (unlikely(!root)) + goto out_iput; + err = PTR_ERR(root); + if (IS_ERR(root)) + goto out_iput; + + err = au_alloc_dinfo(root); + if (!err) { + sb->s_root = root; + return 0; /* success */ + } + dput(root); + goto out; /* do not iput */ + + out_iput: + iget_failed(inode); + iput(inode); + out: + AuTraceErr(err); + return err; + +} + +static int aufs_fill_super(struct super_block *sb, void *raw_data, int silent) +{ + int err; + struct dentry *root; + struct inode *inode; + struct au_opts opts; + char *arg = raw_data; + + if (unlikely(!arg || !*arg)) { + err = -EINVAL; + AuErr("no arg\n"); + goto out; + } + LKTRTrace("%s, silent %d\n", arg, silent); + + err = -ENOMEM; + memset(&opts, 0, sizeof(opts)); + opts.opt = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!opts.opt)) + goto out; + opts.max_opt = PAGE_SIZE / sizeof(*opts.opt); + + err = au_si_alloc(sb); + if (unlikely(err)) + goto out_opts; + SiMustWriteLock(sb); + /* all timestamps always follow the ones on the branch */ + sb->s_flags |= MS_NOATIME | MS_NODIRATIME; + sb->s_op = &aufs_sop; + sb->s_magic = AUFS_SUPER_MAGIC; + au_export_init(sb); + + err = alloc_root(sb); + if (unlikely(err)) { + AuDebugOn(sb->s_root); + si_write_unlock(sb); + goto out_info; + } + root = sb->s_root; + DiMustWriteLock(root); + inode = root->d_inode; + inode->i_nlink = 2; + + /* + * actually we can parse options regardless aufs lock here. + * but at remount time, parsing must be done before aufs lock. + * so we follow the same rule. + */ + ii_write_lock_parent(inode); + aufs_write_unlock(root); + err = au_opts_parse(sb, sb->s_flags, arg, &opts); + if (unlikely(err)) + goto out_root; + + /* lock vfs_inode first, then aufs. */ + mutex_lock(&inode->i_mutex); + inode->i_op = &aufs_dir_iop; + inode->i_fop = &aufs_dir_fop; + aufs_write_lock(root); + + sb->s_maxbytes = 0; + err = au_opts_mount(sb, &opts); + au_opts_free(&opts); + if (unlikely(err)) + goto out_unlock; + AuDebugOn(!sb->s_maxbytes); + + aufs_write_unlock(root); + mutex_unlock(&inode->i_mutex); + goto out_opts; /* success */ + + out_unlock: + aufs_write_unlock(root); + mutex_unlock(&inode->i_mutex); + out_root: + dput(root); + sb->s_root = NULL; + out_info: + kobject_put(&au_sbi(sb)->si_kobj); + sb->s_fs_info = NULL; + out_opts: + free_page((unsigned long)opts.opt); + out: + AuTraceErr(err); + err = cvt_err(err); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int aufs_get_sb(struct file_system_type *fs_type, int flags, + const char *dev_name, void *raw_data, + struct vfsmount *mnt) +{ + int err; + struct super_block *sb; + + /* all timestamps always follow the ones on the branch */ + /* mnt->mnt_flags |= MNT_NOATIME | MNT_NODIRATIME; */ + err = get_sb_nodev(fs_type, flags, raw_data, aufs_fill_super, mnt); + if (!err) { + sb = mnt->mnt_sb; + au_mnt_init(au_sbi(sb), mnt); + si_write_lock(sb); + sysaufs_brs_add(sb, 0); + si_write_unlock(sb); + } + return err; +} + +struct file_system_type aufs_fs_type = { + .name = AUFS_FSTYPE, + .fs_flags = + FS_RENAME_DOES_D_MOVE /* a race between rename and others*/ + | FS_REVAL_DOT, /* for NFS branch */ + .get_sb = aufs_get_sb, + .kill_sb = generic_shutdown_super, + /* no need to __module_get() and module_put(). */ + .owner = THIS_MODULE, +}; --- linux-2.6.28.orig/ubuntu/aufs/opts.h +++ linux-2.6.28/ubuntu/aufs/opts.h @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * mount options/flags + * + * $Id: opts.h,v 1.6 2008/08/17 23:03:27 sfjro Exp $ + */ + +#ifndef __AUFS_OPTS_H__ +#define __AUFS_OPTS_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include "wkq.h" + +/* ---------------------------------------------------------------------- */ +/* mount flags */ + +/* external inode number bitmap and translation table */ +#define AuOpt_XINO 1 +#define AuOpt_XINODIR (1 << 1) +#define AuOpt_TRUNC_XINO (1 << 2) +#define AuOpt_UDBA_NONE (1 << 3) /* users direct branch access */ +#define AuOpt_UDBA_REVAL (1 << 4) +#define AuOpt_UDBA_INOTIFY (1 << 5) +#define AuOpt_SHWH (1 << 6) +#define AuOpt_PLINK (1 << 7) +#define AuOpt_WARN_PERM (1 << 8) +#define AuOpt_DIRPERM1 (1 << 9) +#define AuOpt_DLGT (1 << 10) +#define AuOpt_COO_NONE (1 << 11) /* copyup on open */ +#define AuOpt_COO_LEAF (1 << 12) +#define AuOpt_COO_ALL (1 << 13) +#define AuOpt_ALWAYS_DIROPQ (1 << 14) +#define AuOpt_REFROF (1 << 15) +#define AuOpt_VERBOSE (1 << 16) + +#if 1 /* ndef CONFIG_AUFS_EXPORT */ /* reserved for future use */ +#undef AuOpt_XINODIR +#define AuOpt_XINODIR 0 +#endif +#ifndef CONFIG_AUFS_HINOTIFY +#undef AuOpt_UDBA_INOTIFY +#define AuOpt_UDBA_INOTIFY 0 +#endif +#ifndef CONFIG_AUFS_SHWH +#undef AuOpt_SHWH +#define AuOpt_SHWH 0 +#endif +#ifndef CONFIG_AUFS_DLGT +#undef AuOpt_DIRPERM1 +#define AuOpt_DIRPERM1 0 +#undef AuOpt_DLGT +#define AuOpt_DLGT 0 +#endif + +/* policies to select one among multiple writable branches */ +enum { + AuWbrCreate_TDP, /* top down parent */ + AuWbrCreate_RR, /* round robin */ + AuWbrCreate_MFS, /* most free space */ + AuWbrCreate_MFSV, /* mfs with seconds */ + AuWbrCreate_MFSRR, /* mfs then rr */ + AuWbrCreate_MFSRRV, /* mfs then rr with seconds */ + AuWbrCreate_PMFS, /* parent and mfs */ + AuWbrCreate_PMFSV, /* parent and mfs with seconds */ + + AuWbrCreate_Def = AuWbrCreate_TDP +}; + +enum { + AuWbrCopyup_TDP, /* top down parent */ + AuWbrCopyup_BUP, /* bottom up parent */ + AuWbrCopyup_BU, /* bottom up */ + + AuWbrCopyup_Def = AuWbrCopyup_TDP +}; + +#define AuOptMask_COO (AuOpt_COO_NONE \ + | AuOpt_COO_LEAF \ + | AuOpt_COO_ALL) +#define AuOptMask_UDBA (AuOpt_UDBA_NONE \ + | AuOpt_UDBA_REVAL \ + | AuOpt_UDBA_INOTIFY) + +#ifdef CONFIG_AUFS_COMPAT +#define AuOpt_DefExtra1 AuOpt_ALWAYS_DIROPQ +#else +#define AuOpt_DefExtra1 0 +#endif + +#define AuOpt_Def (AuOpt_XINO \ + | AuOpt_UDBA_REVAL \ + | AuOpt_WARN_PERM \ + | AuOpt_COO_NONE \ + | AuOpt_PLINK \ + | AuOpt_DefExtra1) + +/* ---------------------------------------------------------------------- */ + +struct au_opt_add { + aufs_bindex_t bindex; + char *path; + int perm; + struct nameidata nd; +}; + +struct au_opt_del { + char *path; + struct dentry *h_root; +}; + +struct au_opt_mod { + char *path; + int perm; + struct dentry *h_root; +}; + +struct au_opt_xino { + char *path; + struct file *file; +}; + +struct au_opt_xinodir { + char *name; + struct path path; +}; + +struct au_opt_xino_itrunc { + aufs_bindex_t bindex; +}; + +struct au_opt_xino_trunc_v { + unsigned long long upper; + int step; +}; + +struct au_opt_wbr_create { + int wbr_create; + int mfs_second; + unsigned long long mfsrr_watermark; +}; + +struct au_opt { + int type; + union { + struct au_opt_xino xino; + struct au_opt_xinodir xinodir; + struct au_opt_xino_itrunc xino_itrunc; + struct au_opt_add add; + struct au_opt_del del; + struct au_opt_mod mod; + int dirwh; + int rdcache; + int deblk; + int nhash; + int udba; + int coo; + struct au_opt_wbr_create wbr_create; + int wbr_copyup; + }; +}; + +/* opts flags */ +#define AuOpts_REMOUNT 1 +#define AuOpts_REFRESH_DIR (1 << 1) +#define AuOpts_REFRESH_NONDIR (1 << 2) +#define AuOpts_TRUNC_XIB (1 << 3) +#define au_ftest_opts(flags, name) ((flags) & AuOpts_##name) +#define au_fset_opts(flags, name) { (flags) |= AuOpts_##name; } +#define au_fclr_opts(flags, name) { (flags) &= ~AuOpts_##name; } + +struct au_opts { + struct au_opt *opt; + int max_opt; + + unsigned int given_udba; + unsigned int flags; +}; + +/* ---------------------------------------------------------------------- */ + +const char *au_optstr_br_perm(int brperm); +const char *au_optstr_udba(int udba); +const char *au_optstr_coo(int coo); +const char *au_optstr_wbr_copyup(int wbr_copyup); +const char *au_optstr_wbr_create(int wbr_create); + +void au_opts_free(struct au_opts *opts); +int au_opts_parse(struct super_block *sb, unsigned long flags, char *str, + struct au_opts *opts); +int au_opts_mount(struct super_block *sb, struct au_opts *opts); +int au_opts_remount(struct super_block *sb, struct au_opts *opts); + +/* ---------------------------------------------------------------------- */ + +#define au_opt_test(flags, name) (flags & AuOpt_##name) + +static inline int au_opt_test_xino(unsigned int flags) +{ + return (flags & (AuOpt_XINO | AuOpt_XINODIR)); +} + +#define au_opt_set(flags, name) do { \ + BUILD_BUG_ON(AuOpt_##name & (AuOptMask_COO | AuOptMask_UDBA)); \ + ((flags) |= AuOpt_##name); \ +} while (0) + +#define au_opt_set_coo(flags, name) do { \ + (flags) &= ~AuOptMask_COO; \ + ((flags) |= AuOpt_##name); \ +} while (0) + +#define au_opt_set_udba(flags, name) do { \ + (flags) &= ~AuOptMask_UDBA; \ + ((flags) |= AuOpt_##name); \ +} while (0) + +#define au_opt_clr(flags, name) { ((flags) &= ~AuOpt_##name); } + +static inline int au_test_dlgt(unsigned int flags) +{ + return (au_opt_test(flags, DLGT) && !au_test_wkq(current)); +} + +static inline int au_test_dirperm1(unsigned int flags) +{ + return (au_opt_test(flags, DIRPERM1) && !au_test_wkq(current)); +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_OPTS_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/module.c +++ linux-2.6.28/ubuntu/aufs/module.c @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * module global variables and operations + * + * $Id: module.c,v 1.10 2008/08/25 01:50:37 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +/* + * aufs caches + */ +struct kmem_cache *au_cachep[AuCache_Last]; +static int __init create_cache(void) +{ + au_cachep[AuCache_DINFO] = AuCache(au_dinfo); + if (au_cachep[AuCache_DINFO]) + au_cachep[AuCache_ICNTNR] = AuCache(aufs_icntnr); + if (au_cachep[AuCache_ICNTNR]) + au_cachep[AuCache_FINFO] = AuCache(au_finfo); + if (au_cachep[AuCache_FINFO]) + au_cachep[AuCache_VDIR] = AuCache(au_vdir); + if (au_cachep[AuCache_VDIR]) + au_cachep[AuCache_DEHSTR] = AuCache(au_vdir_dehstr); + if (au_cachep[AuCache_DEHSTR]) + return 0; + + return -ENOMEM; +} + +static void destroy_cache(void) +{ + int i; + for (i = 0; i < AuCache_Last; i++) + if (au_cachep[i]) { + kmem_cache_destroy(au_cachep[i]); + au_cachep[i] = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +char au_esc_chars[0x20 + 3]; /* 0x01-0x20, backslash, del, and NULL */ +int au_dir_roflags; + +/* + * functions for module interface. + */ +MODULE_LICENSE("GPL"); +/* MODULE_LICENSE("GPL v2"); */ +MODULE_AUTHOR("Junjiro Okajima"); +MODULE_DESCRIPTION(AUFS_NAME " -- Another unionfs"); +MODULE_VERSION(AUFS_VERSION); + +/* it should be 'byte', but param_set_byte() prints it by "%c" */ +short aufs_nwkq = AUFS_NWKQ_DEF; +MODULE_PARM_DESC(nwkq, "the number of workqueue thread, " AUFS_WKQ_NAME); +module_param_named(nwkq, aufs_nwkq, short, S_IRUGO); + +int sysaufs_brs; +MODULE_PARM_DESC(brs, "use /fs/aufs/si_*/brN"); +module_param_named(brs, sysaufs_brs, int, S_IRUGO); + +/* ---------------------------------------------------------------------- */ + +static int __init aufs_init(void) +{ + int err, i; + char *p; + + au_debug_init(); +#ifdef CONFIG_AUFS_INO_T_64 + BUILD_BUG_ON(sizeof(ino_t) != sizeof(long long)); +#else + BUILD_BUG_ON(sizeof(ino_t) != sizeof(int)); +#endif + + p = au_esc_chars; + for (i = 1; i <= ' '; i++) + *p++ = i; + *p++ = '\\'; + *p++ = '\x7f'; + *p = 0; + + au_dir_roflags = au_file_roflags(O_DIRECTORY | O_LARGEFILE); + + err = -EINVAL; + if (unlikely(aufs_nwkq <= 0)) + goto out; + + err = sysaufs_init(); + if (unlikely(err)) + goto out; + err = au_wkq_init(); + if (unlikely(err)) + goto out_sysaufs; + err = au_inotify_init(); + if (unlikely(err)) + goto out_wkq; + err = au_sysrq_init(); + if (unlikely(err)) + goto out_inotify; + + err = create_cache(); + if (unlikely(err)) + goto out_sysrq; + + err = register_filesystem(&aufs_fs_type); + if (unlikely(err)) + goto out_cache; + pr_info(AUFS_NAME " " AUFS_VERSION "\n"); + return 0; /* success */ + + out_cache: + destroy_cache(); + out_sysrq: + au_sysrq_fin(); + out_inotify: + au_inotify_fin(); + out_wkq: + au_wkq_fin(); + out_sysaufs: + sysaufs_fin(); + out: + AuTraceErr(err); + return err; +} + +static void __exit aufs_exit(void) +{ + unregister_filesystem(&aufs_fs_type); + destroy_cache(); + + au_sysrq_fin(); + au_inotify_fin(); + au_wkq_fin(); + sysaufs_fin(); +} + +module_init(aufs_init); +module_exit(aufs_exit); + +/* ---------------------------------------------------------------------- */ + +/* fake Kconfig */ +#if 1 + +#ifdef CONFIG_AUFS_HINOTIFY +#ifndef CONFIG_INOTIFY +#error enable CONFIG_INOTIFY to use CONFIG_AUFS_HINOTIFY. +#endif +#endif /* CONFIG_AUFS_HINOTIFY */ + +#if AUFS_BRANCH_MAX > 511 && PAGE_SIZE > 4096 +#warning pagesize is larger than 4kb, \ + CONFIG_AUFS_BRANCH_MAX_511 or smaller is recommended. +#endif + +#ifdef CONFIG_AUFS_STAT +#ifndef CONFIG_SYSFS +#error CONFIG_AUFS_STAT requires CONFIG_SYSFS. +#endif +#endif /* CONFIG_AUFS_STAT */ + +#ifdef CONFIG_AUFS_SYSAUFS +#warning CONFIG_AUFS_SYSAUFS is unnecessary for linux-2.6.25 and later. +#endif + +#ifdef CONFIG_AUFS_EXPORT +#if !defined(CONFIG_EXPORTFS) && !defined(CONFIG_EXPORTFS_MODULE) +#error CONFIG_AUFS_EXPORT requires CONFIG_EXPORTFS +#endif +#if defined(CONFIG_EXPORTFS_MODULE) && defined(CONFIG_AUFS) +#error need CONFIG_EXPORTFS = y to link aufs statically with CONFIG_AUFS_EXPORT +#endif +#endif /* CONFIG_AUFS_EXPORT */ + +#ifdef CONFIG_AUFS_SEC_PERM_PATCH +#ifndef CONFIG_SECURITY +#warning CONFIG_AUFS_SEC_PERM_PATCH is unnecessary since CONFIG_SECURITY is disabled. +#endif +#ifdef CONFIG_AUFS +#warning CONFIG_AUFS_SEC_PERM_PATCH is unnecessary since CONFIG_AUFS is not a module. +#endif +#endif + +#ifdef CONFIG_AUFS_PUT_FILP_PATCH +#if !defined(CONFIG_NFS_FS) && !defined(CONFIG_NFS_FS_MODULE) +#warning CONFIG_AUFS_PUT_FILP_PATCH is unnecessary since CONFIG_NFS_FS is disabled. +#endif +#ifdef CONFIG_AUFS +#warning CONFIG_AUFS_PUT_FILP_PATCH is unnecessary since CONFIG_AUFS is not a module. +#endif +#endif /* CONFIG_AUFS_PUT_FILP_PATCH */ + +#ifdef CONFIG_AUFS_LHASH_PATCH +#if !defined(CONFIG_NFS_FS) && !defined(CONFIG_NFS_FS_MODULE) +#warning CONFIG_AUFS_LHASH_PATCH is unnecessary since CONFIG_NFS_FS is disabled. +#endif +#endif + +#ifdef CONFIG_AUFS_KSIZE_PATCH +#warning CONFIG_AUFS_KSIZE_PATCH is unnecessary for linux-2.6.22 and later. +#endif + +#ifdef CONFIG_AUFS_WORKAROUND_FUSE +#if !defined(CONFIG_FUSE_FS) && !defined(CONFIG_FUSE_FS_MODULE) +#warning CONFIG_AUFS_WORKAROUND_FUSE is enabled while FUSE is disabled. +#endif +#endif + +#ifdef CONFIG_DEBUG_PROVE_LOCKING +#if MAX_LOCKDEP_SUBCLASSES < AuLsc_I_End +#warning lockdep will not work since aufs uses deeper locks. +#endif +#endif + +#ifdef CONFIG_AUFS_COMPAT +#warning CONFIG_AUFS_COMPAT will be removed in the near future. +#endif + +#if defined(CONFIG_AUFS_UNIONFS23_PATCH) \ + && !defined(CONFIG_AUFS_UNIONFS22_PATCH) +#error mis-configuration. CONFIG_AUFS_UNIONFS23_PATCH is enabled but CONFIG_AUFS_UNIONFS22_PATCH. +#endif + +#endif --- linux-2.6.28.orig/ubuntu/aufs/dir.c +++ linux-2.6.28/ubuntu/aufs/dir.c @@ -0,0 +1,547 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * directory operations + * + * $Id: dir.c,v 1.13 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include +#include "aufs.h" + +static int reopen_dir(struct file *file) +{ + int err; + struct dentry *dentry, *h_dentry; + aufs_bindex_t bindex, btail, bstart; + struct file *h_file; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(!S_ISDIR(dentry->d_inode->i_mode)); + + /* open all hidden dirs */ + bstart = au_dbstart(dentry); +#if 1 /* todo: necessary? */ + for (bindex = au_fbstart(file); bindex < bstart; bindex++) + au_set_h_fptr(file, bindex, NULL); +#endif + au_set_fbstart(file, bstart); + btail = au_dbtaildir(dentry); +#if 1 /* todo: necessary? */ + for (bindex = au_fbend(file); btail < bindex; bindex--) + au_set_h_fptr(file, bindex, NULL); +#endif + au_set_fbend(file, btail); + for (bindex = bstart; bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + h_file = au_h_fptr(file, bindex); + if (h_file) { + AuDebugOn(h_file->f_dentry != h_dentry); + continue; + } + + h_file = au_h_open(dentry, bindex, file->f_flags, file); + err = PTR_ERR(h_file); + if (IS_ERR(h_file)) + goto out; /* close all? */ + /* cpup_file_flags(h_file, file); */ + au_set_h_fptr(file, bindex, h_file); + } + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + err = 0; + + out: + AuTraceErr(err); + return err; +} + +static int do_open_dir(struct file *file, int flags) +{ + int err; + aufs_bindex_t bindex, btail; + struct dentry *dentry, *h_dentry; + struct file *h_file; + + dentry = file->f_dentry; + LKTRTrace("%.*s, 0x%x\n", AuDLNPair(dentry), flags); + AuDebugOn(!dentry->d_inode || !S_ISDIR(dentry->d_inode->i_mode)); + + err = 0; + au_set_fvdir_cache(file, NULL); + file->f_version = dentry->d_inode->i_version; + bindex = au_dbstart(dentry); + au_set_fbstart(file, bindex); + btail = au_dbtaildir(dentry); + au_set_fbend(file, btail); + for (; !err && bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + + h_file = au_h_open(dentry, bindex, flags, file); + if (IS_ERR(h_file)) { + err = PTR_ERR(h_file); + break; + } + au_set_h_fptr(file, bindex, h_file); + } + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + if (!err) + return 0; /* success */ + + /* close all */ + for (bindex = au_fbstart(file); bindex <= btail; bindex++) + au_set_h_fptr(file, bindex, NULL); + au_set_fbstart(file, -1); + au_set_fbend(file, -1); + return err; +} + +static int aufs_open_dir(struct inode *inode, struct file *file) +{ + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + return au_do_open(inode, file, do_open_dir); +} + +static int aufs_release_dir(struct inode *inode, struct file *file) +{ + struct au_vdir *vdir_cache; + struct super_block *sb; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + sb = file->f_dentry->d_sb; + si_noflush_read_lock(sb); + fi_write_lock(file); + vdir_cache = au_fvdir_cache(file); + if (vdir_cache) + au_vdir_free(vdir_cache); + fi_write_unlock(file); + au_finfo_fin(file); + si_read_unlock(sb); + return 0; +} + +static int fsync_dir(struct dentry *dentry, int datasync) +{ + int err; + struct inode *inode; + struct super_block *sb; + aufs_bindex_t bend, bindex; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync); + DiMustAnyLock(dentry); + sb = dentry->d_sb; + SiMustAnyLock(sb); + inode = dentry->d_inode; + IMustLock(inode); + IiMustAnyLock(inode); + + err = 0; + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); !err && bindex <= bend; bindex++) { + struct dentry *h_dentry; + struct inode *h_inode; + struct file_operations *fop; + + if (au_test_ro(sb, bindex, inode)) + continue; + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + h_inode = h_dentry->d_inode; + if (!h_inode) + continue; + + /* cf. fs/nsfd/vfs.c and fs/nfsd/nfs4recover.c */ + /* todo: inotiry fired? */ + mutex_lock(&h_inode->i_mutex); + fop = (void *)h_inode->i_fop; + err = filemap_fdatawrite(h_inode->i_mapping); + if (!err && fop && fop->fsync) + err = fop->fsync(NULL, h_dentry, datasync); + if (!err) + err = filemap_fdatawrite(h_inode->i_mapping); + if (!err) + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ + mutex_unlock(&h_inode->i_mutex); + } + + AuTraceErr(err); + return err; +} + +/* + * @file may be NULL + */ +static int aufs_fsync_dir(struct file *file, struct dentry *dentry, + int datasync) +{ + int err; + struct inode *inode; + struct file *h_file; + struct super_block *sb; + aufs_bindex_t bend, bindex; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync); + inode = dentry->d_inode; + IMustLock(inode); + + err = 0; + sb = dentry->d_sb; + si_noflush_read_lock(sb); + if (file) { + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + } else + di_write_lock_child(dentry); + + if (file) { + bend = au_fbend(file); + for (bindex = au_fbstart(file); !err && bindex <= bend; + bindex++) { + h_file = au_h_fptr(file, bindex); + if (!h_file || au_test_ro(sb, bindex, inode)) + continue; + + err = -EINVAL; + if (h_file->f_op && h_file->f_op->fsync) { + /* todo: try do_fsync() in fs/sync.c? */ + mutex_lock(&h_file->f_mapping->host->i_mutex); + err = h_file->f_op->fsync + (h_file, h_file->f_dentry, datasync); + if (!err) + au_update_fuse_h_inode + (h_file->f_vfsmnt, + h_file->f_dentry); + /*ignore*/ + mutex_unlock(&h_file->f_mapping->host->i_mutex); + } + } + } else + err = fsync_dir(dentry, datasync); + au_cpup_attr_timesizes(inode); + di_write_unlock(dentry); + if (file) + fi_write_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int aufs_readdir(struct file *file, void *dirent, filldir_t filldir) +{ + int err, iflag; + struct dentry *dentry; + struct inode *inode; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld\n", AuDLNPair(dentry), file->f_pos); + inode = dentry->d_inode; + IMustLock(inode); + + au_nfsd_lockdep_off(); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, reopen_dir, /*wlock*/1, /*locked*/1); + if (unlikely(err)) + goto out; + + err = au_vdir_init(file); + if (unlikely(err)) { + di_write_unlock(dentry); + goto out_unlock; + } + + /* nfsd filldir calls lookup_one_len(). */ + iflag = AuLock_IW; + if (unlikely(au_test_nfsd(current))) + iflag = AuLock_IR; + di_downgrade_lock(dentry, iflag); + err = au_vdir_fill_de(file, dirent, filldir); + + fsstack_copy_attr_atime(inode, au_h_iptr(inode, au_ibstart(inode))); + di_read_unlock(dentry, iflag); + + out_unlock: + fi_write_unlock(file); + out: + si_read_unlock(sb); + au_nfsd_lockdep_on(); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +#define AuTestEmpty_WHONLY 1 +#define AuTestEmpty_DLGT (1 << 1) +#define AuTestEmpty_DIRPERM1 (1 << 2) +#define AuTestEmpty_CALLED (1 << 3) +#define AuTestEmpty_SHWH (1 << 4) +#define au_ftest_testempty(flags, name) ((flags) & AuTestEmpty_##name) +#define au_fset_testempty(flags, name) { (flags) |= AuTestEmpty_##name; } +#define au_fclr_testempty(flags, name) { (flags) &= ~AuTestEmpty_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuTestEmpty_DLGT +#define AuTestEmpty_DLGT 0 +#undef AuTestEmpty_DIRPERM1 +#define AuTestEmpty_DIRPERM1 0 +#endif +#ifndef CONFIG_AUFS_SHWH +#undef AuTestEmpty_SHWH +#define AuTestEmpty_SHWH 0 +#endif + +struct test_empty_arg { + struct au_nhash *whlist; + unsigned int flags; + int err; + aufs_bindex_t bindex; +}; + +static int test_empty_cb(void *__arg, const char *__name, int namelen, + loff_t offset, u64 ino, unsigned int d_type) +{ + struct test_empty_arg *arg = __arg; + char *name = (void *)__name; + + LKTRTrace("%.*s\n", namelen, name); + + arg->err = 0; + au_fset_testempty(arg->flags, CALLED); + /* smp_mb(); */ + if (name[0] == '.' + && (namelen == 1 || (name[1] == '.' && namelen == 2))) + return 0; /* success */ + + if (namelen <= AUFS_WH_PFX_LEN + || memcmp(name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { + if (au_ftest_testempty(arg->flags, WHONLY) + && !au_nhash_test_known_wh(arg->whlist, name, namelen)) + arg->err = -ENOTEMPTY; + goto out; + } + + name += AUFS_WH_PFX_LEN; + namelen -= AUFS_WH_PFX_LEN; + if (!au_nhash_test_known_wh(arg->whlist, name, namelen)) + arg->err = au_nhash_append_wh + (arg->whlist, name, namelen, ino, d_type, arg->bindex, + au_ftest_testempty(arg->flags, SHWH)); + + out: + /* smp_mb(); */ + AuTraceErr(arg->err); + return arg->err; +} + +static int do_test_empty(struct dentry *dentry, struct test_empty_arg *arg) +{ + int err, dlgt; + struct file *h_file; + + LKTRTrace("%.*s, {%p, 0x%x, %d}\n", + AuDLNPair(dentry), arg->whlist, arg->flags, arg->bindex); + + h_file = au_h_open(dentry, arg->bindex, + O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_LARGEFILE, + /*file*/NULL); + err = PTR_ERR(h_file); + if (IS_ERR(h_file)) + goto out; + err = 0; + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), UDBA_INOTIFY) + && !h_file->f_dentry->d_inode->i_nlink)) + goto out_put; + + dlgt = au_ftest_testempty(arg->flags, DLGT); + do { + arg->err = 0; + au_fclr_testempty(arg->flags, CALLED); + /* smp_mb(); */ + err = vfsub_readdir(h_file, test_empty_cb, arg, dlgt); + if (err >= 0) + err = arg->err; + } while (!err && au_ftest_testempty(arg->flags, CALLED)); + + out_put: + fput(h_file); + au_sbr_put(dentry->d_sb, arg->bindex); + out: + AuTraceErr(err); + return err; +} + +struct do_test_empty_args { + int *errp; + struct dentry *dentry; + struct test_empty_arg *arg; +}; + +static void call_do_test_empty(void *args) +{ + struct do_test_empty_args *a = args; + *a->errp = do_test_empty(a->dentry, a->arg); +} + +static int sio_test_empty(struct dentry *dentry, struct test_empty_arg *arg) +{ + int err, wkq_err; + struct dentry *h_dentry; + struct inode *h_inode; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + h_dentry = au_h_dptr(dentry, arg->bindex); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + AuDebugOn(!h_inode); + + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + err = au_test_h_perm_sio(h_inode, MAY_EXEC | MAY_READ, + au_test_dlgt(au_mntflags(dentry->d_sb))); + mutex_unlock(&h_inode->i_mutex); + if (!err) + err = do_test_empty(dentry, arg); + else { + struct do_test_empty_args args = { + .errp = &err, + .dentry = dentry, + .arg = arg + }; + unsigned int flags = arg->flags; + + au_fclr_testempty(arg->flags, DLGT); + au_fclr_testempty(arg->flags, DIRPERM1); + wkq_err = au_wkq_wait(call_do_test_empty, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + arg->flags = flags; + } + + AuTraceErr(err); + return err; +} + +int au_test_empty_lower(struct dentry *dentry) +{ + int err; + struct inode *inode; + struct test_empty_arg arg; + struct au_nhash *whlist; + aufs_bindex_t bindex, bstart, btail; + unsigned int mnt_flags; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + AuDebugOn(!inode || !S_ISDIR(inode->i_mode)); + + whlist = au_nhash_new(GFP_NOFS); + err = PTR_ERR(whlist); + if (IS_ERR(whlist)) + goto out; + + bstart = au_dbstart(dentry); + mnt_flags = au_mntflags(dentry->d_sb); + arg.whlist = whlist; + arg.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_testempty(arg.flags, DLGT); + if (unlikely(au_opt_test(mnt_flags, SHWH))) + au_fset_testempty(arg.flags, SHWH); + arg.bindex = bstart; + err = do_test_empty(dentry, &arg); + if (unlikely(err)) + goto out_whlist; + + au_fset_testempty(arg.flags, WHONLY); + if (unlikely(au_test_dirperm1(mnt_flags))) + au_fset_testempty(arg.flags, DIRPERM1); + btail = au_dbtaildir(dentry); + for (bindex = bstart + 1; !err && bindex <= btail; bindex++) { + struct dentry *h_dentry; + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry && h_dentry->d_inode) { + arg.bindex = bindex; + err = do_test_empty(dentry, &arg); + } + } + + out_whlist: + au_nhash_del(whlist); + out: + AuTraceErr(err); + return err; +} + +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist) +{ + int err; + struct inode *inode; + struct test_empty_arg arg; + aufs_bindex_t bindex, btail; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + AuDebugOn(!inode || !S_ISDIR(inode->i_mode)); + + err = 0; + arg.whlist = whlist; + arg.flags = AuTestEmpty_WHONLY; + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), SHWH))) + au_fset_testempty(arg.flags, SHWH); + btail = au_dbtaildir(dentry); + for (bindex = au_dbstart(dentry); !err && bindex <= btail; bindex++) { + struct dentry *h_dentry; + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry && h_dentry->d_inode) { + arg.bindex = bindex; + err = sio_test_empty(dentry, &arg); + } + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct file_operations aufs_dir_fop = { + .read = generic_read_dir, + .readdir = aufs_readdir, + .open = aufs_open_dir, + .release = aufs_release_dir, + .flush = aufs_flush, + .fsync = aufs_fsync_dir, +}; --- linux-2.6.28.orig/ubuntu/aufs/whout.h +++ linux-2.6.28/ubuntu/aufs/whout.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * whiteout for logical deletion and opaque directory + * + * $Id: whout.h,v 1.3 2008/06/30 03:57:35 sfjro Exp $ + */ + +#ifndef __AUFS_WHOUT_H__ +#define __AUFS_WHOUT_H__ + +#ifdef __KERNEL__ + +#include +#include +#include "dir.h" +#include "opts.h" +#include "super.h" + +int au_wh_name_alloc(const char *name, int len, struct qstr *wh); +void au_wh_name_free(struct qstr *wh); + +struct au_ndx; +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio, + struct au_ndx *ndx); +int au_diropq_test(struct dentry *h_dentry, struct au_ndx *ndx); + +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct qstr *prefix, + struct au_ndx *ndx); +int au_whtmp_ren(struct inode *dir, aufs_bindex_t bindex, + struct dentry *h_dentry); +int au_wh_unlink_dentry(struct au_hinode *dir, struct dentry *wh_dentry, + struct dentry *dentry, int dlgt); + +struct au_branch; +int au_wh_init(struct dentry *h_parent, struct au_branch *br, + struct vfsmount *nfsmnt, struct super_block *sb, + aufs_bindex_t bindex); + +/* diropq flags */ +#define AuDiropq_CREATE 1 +#define AuDiropq_DLGT (1 << 1) +#define au_ftest_diropq(flags, name) ((flags) & AuDiropq_##name) +#define au_fset_diropq(flags, name) { (flags) |= AuDiropq_##name; } +#define au_fclr_diropq(flags, name) { (flags) &= ~AuDiropq_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuDiropq_DLGT +#define AuDiropq_DLGT 0 +#endif + +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, + unsigned int flags); + +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, + struct au_ndx *ndx); +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, struct au_ndx *ndx); + +/* real rmdir the whiteout-ed dir */ +struct au_whtmp_rmdir_args { + struct inode *dir; + aufs_bindex_t bindex; + struct dentry *wh_dentry; + struct au_nhash whlist; +}; + +struct au_nhash; +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist); +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist, + struct au_whtmp_rmdir_args *args); + +/* ---------------------------------------------------------------------- */ + +static inline +struct dentry *au_diropq_create(struct dentry *dentry, aufs_bindex_t bindex, + int dlgt) +{ + unsigned int flags = AuDiropq_CREATE; + if (unlikely(dlgt)) + au_fset_diropq(flags, DLGT); + return au_diropq_sio(dentry, bindex, flags); +} + +static inline +int au_diropq_remove(struct dentry *dentry, aufs_bindex_t bindex, int dlgt) +{ + unsigned int flags = !AuDiropq_CREATE; + if (unlikely(dlgt)) + au_fset_diropq(flags, DLGT); + return PTR_ERR(au_diropq_sio(dentry, bindex, flags)); +} + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_ROBR +/* robr.c */ +int au_test_robr_wh(struct qstr *name, struct dentry *h_parent, + struct qstr *wh_name, int try_sio, struct au_ndx *ndx); +int au_test_robr_shwh(struct super_block *sb, const struct qstr *name); +#else +static inline +int au_test_robr_wh(struct qstr *name, struct dentry *h_parent, + struct qstr *wh_name, int try_sio, struct au_ndx *ndx) +{ + return au_wh_test(h_parent, wh_name, try_sio, ndx); +} + +static inline +int au_test_robr_shwh(struct super_block *sb, const struct qstr *name) +{ + if (unlikely(!au_opt_test(au_mntflags(sb), SHWH) + && !strncmp(name->name, AUFS_WH_PFX, AUFS_WH_PFX_LEN))) + return -EPERM; + return 0; +} +#endif /* CONFIG_AUFS_ROBR */ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WHOUT_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/br_fuse.c +++ linux-2.6.28/ubuntu/aufs/br_fuse.c @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * special handling for inode attributes on FUSE branch + * + * $Id: br_fuse.c,v 1.6 2008/07/27 22:49:28 sfjro Exp $ + */ + +#include "aufs.h" + +/* h_mnt can be NULL, is it safe? */ +int au_update_fuse_h_inode(struct vfsmount *h_mnt, struct dentry *h_dentry) +{ + int err; + struct kstat st; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + + err = 0; + if (unlikely(h_dentry->d_inode + /* && atomic_read(&h_dentry->d_inode->i_count) */ + && au_test_fuse(h_dentry->d_sb))) { + err = vfsub_getattr(h_mnt, h_dentry, &st, /*dlgt*/0); + if (unlikely(err)) { + AuDbg("err %d\n", err); + au_debug_on(); + AuDbgDentry(h_dentry); + au_debug_off(); + WARN_ON(err); + } + } + return err; +} + +#if 0 /* temp */ +/* + * This function was born after a discussion with the FUSE developer. + * The inode attributes on a filesystem who defines i_op->getattr() + * is unreliable since such fs may not maintain the attributes at lookup. + * This function doesn't want the result of stat, instead wants the side-effect + * which refreshes the attributes. + * Hmm, there seems to be no such filesystem except fuse. + */ +int vfsub_i_attr(struct vfsmount *mnt, struct dentry *dentry, int dlgt) +{ + int err; + struct inode *inode; + struct inode_operations *op; + struct kstat st; + + inode = dentry->d_inode; + AuDebugOn(!inode); + + err = 0; + op = inode->i_op; + if (unlikely(op && op->getattr && !au_test_aufs(dentry->d_sb))) { + err = security_inode_getattr(mnt, dentry); + if (!err) + err = op->getattr(mnt, dentry, &st); + } + AuTraceErr(err); + return err; +} +#endif --- linux-2.6.28.orig/ubuntu/aufs/wkq.c +++ linux-2.6.28/ubuntu/aufs/wkq.c @@ -0,0 +1,363 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * workqueue for asynchronous/super-io/delegated operations + * + * $Id: wkq.c,v 1.13 2008/09/15 03:16:36 sfjro Exp $ + */ + +#include +#include "aufs.h" + +struct au_wkq *au_wkq; + +struct au_cred { +#ifdef CONFIG_AUFS_DLGT + int umask; + uid_t fsuid; + gid_t fsgid; + kernel_cap_t cap_effective, cap_inheritable, cap_permitted; +#if 0 /* reserved for future use */ + unsigned keep_capabilities:1; + struct user_struct *user; + struct fs_struct *fs; + struct nsproxy *nsproxy; +#endif +#endif +}; + +struct au_wkinfo { + struct work_struct wk; + struct super_block *sb; + + unsigned int flags; + struct au_cred cred; + + au_wkq_func_t func; + void *args; + + atomic_t *busyp; + struct completion *comp; +}; + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_DLGT +static void cred_store(struct au_cred *cred) +{ + cred->umask = current->fs->umask; + cred->fsuid = current->fsuid; + cred->fsgid = current->fsgid; + cred->cap_effective = current->cap_effective; + cred->cap_inheritable = current->cap_inheritable; + cred->cap_permitted = current->cap_permitted; +} + +static void cred_revert(struct au_cred *cred) +{ + AuDebugOn(!au_test_wkq(current)); + current->fs->umask = cred->umask; + current->fsuid = cred->fsuid; + current->fsgid = cred->fsgid; + current->cap_effective = cred->cap_effective; + current->cap_inheritable = cred->cap_inheritable; + current->cap_permitted = cred->cap_permitted; +} + +static void cred_switch(struct au_cred *old, struct au_cred *new) +{ + cred_store(old); + cred_revert(new); +} + +static void dlgt_cred_store(unsigned int flags, struct au_wkinfo *wkinfo) +{ + if (unlikely(au_ftest_wkq(flags, DLGT))) + cred_store(&wkinfo->cred); +} + +static void dlgt_func(struct au_wkinfo *wkinfo) +{ + if (!au_ftest_wkq(wkinfo->flags, DLGT)) + wkinfo->func(wkinfo->args); + else { + struct au_cred cred; + cred_switch(&cred, &wkinfo->cred); + wkinfo->func(wkinfo->args); + cred_revert(&cred); + } +} +#else +static void dlgt_cred_store(unsigned int flags, struct au_wkinfo *wkinfo) +{ + /* empty */ +} + +static void dlgt_func(struct au_wkinfo *wkinfo) +{ + wkinfo->func(wkinfo->args); +} +#endif /* CONFIG_AUFS_DLGT */ + +/* ---------------------------------------------------------------------- */ + +static void update_busy(struct au_wkq *wkq, struct au_wkinfo *wkinfo) +{ +#ifdef CONFIG_AUFS_STAT + unsigned int new, old; + + do { + new = atomic_read(wkinfo->busyp); + old = wkq->max_busy; + if (new <= old) + break; + } while (cmpxchg(&wkq->max_busy, old, new) == old); +#endif +} + +static int enqueue(struct au_wkq *wkq, struct au_wkinfo *wkinfo) +{ + AuTraceEnter(); + + wkinfo->busyp = &wkq->busy; + update_busy(wkq, wkinfo); + if (au_ftest_wkq(wkinfo->flags, WAIT)) + return !queue_work(wkq->q, &wkinfo->wk); + else + return !schedule_work(&wkinfo->wk); +} + +static void do_wkq(struct au_wkinfo *wkinfo) +{ + unsigned int idle, n; + int i, idle_idx; + + AuTraceEnter(); + + while (1) { + if (au_ftest_wkq(wkinfo->flags, WAIT)) { + idle_idx = 0; + idle = UINT_MAX; + for (i = 0; i < aufs_nwkq; i++) { + n = atomic_inc_return(&au_wkq[i].busy); + if (n == 1 && !enqueue(au_wkq + i, wkinfo)) + return; /* success */ + + if (n < idle) { + idle_idx = i; + idle = n; + } + atomic_dec_return(&au_wkq[i].busy); + } + } else + idle_idx = aufs_nwkq; + + atomic_inc_return(&au_wkq[idle_idx].busy); + if (!enqueue(au_wkq + idle_idx, wkinfo)) + return; /* success */ + + /* impossible? */ + AuWarn1("failed to queue_work()\n"); + yield(); + } +} + +static void wkq_func(struct work_struct *wk) +{ + struct au_wkinfo *wkinfo = container_of(wk, struct au_wkinfo, wk); + + LKTRTrace("wkinfo{0x%x, %p, %p, %p}\n", + wkinfo->flags, wkinfo->func, wkinfo->busyp, wkinfo->comp); + + dlgt_func(wkinfo); + atomic_dec_return(wkinfo->busyp); + if (au_ftest_wkq(wkinfo->flags, WAIT)) + complete(wkinfo->comp); + else { + kobject_put(&au_sbi(wkinfo->sb)->si_kobj); + module_put(THIS_MODULE); + kfree(wkinfo); + } +} + +#if defined(CONFIG_4KSTACKS) || defined(Test4KSTACKS) +#define AuWkqCompDeclare(name) struct completion *comp = NULL + +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) +{ + *comp = kmalloc(sizeof(**comp), GFP_NOFS); + if (*comp) { + init_completion(*comp); + wkinfo->comp = *comp; + return 0; + } + return -ENOMEM; +} + +static void au_wkq_comp_free(struct completion *comp) +{ + kfree(comp); +} + +#else + +#define AuWkqCompDeclare(name) \ + DECLARE_COMPLETION_ONSTACK(_ ## name); \ + struct completion *comp = &_ ## name + +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) +{ + wkinfo->comp = *comp; + return 0; +} + +static void au_wkq_comp_free(struct completion *comp) +{ + /* empty */ +} +#endif /* 4KSTACKS */ + +/* todo: break to three funcs */ +int au_wkq_run(au_wkq_func_t func, void *args, struct super_block *sb, + unsigned int flags) +{ + int err; + AuWkqCompDeclare(comp); + struct au_wkinfo _wkinfo = { + .flags = flags, + .func = func, + .args = args + }, *wkinfo = &_wkinfo; + const unsigned char do_wait = au_ftest_wkq(flags, WAIT); + + LKTRTrace("0x%x\n", flags); +#if 1 /* tmp debug */ + if (au_test_wkq(current)) + au_dbg_blocked(); +#endif + AuDebugOn(au_test_wkq(current)); + + if (do_wait) { + err = au_wkq_comp_alloc(wkinfo, &comp); + if (unlikely(err)) + goto out; + } else { + AuDebugOn(!sb); + /* + * wkq_func() must free this wkinfo. + * it highly depends upon the implementation of workqueue. + */ + err = -ENOMEM; + wkinfo = kmalloc(sizeof(*wkinfo), GFP_NOFS); + if (unlikely(!wkinfo)) + goto out; + + err = 0; + wkinfo->sb = sb; + wkinfo->flags = flags; + wkinfo->func = func; + wkinfo->args = args; + wkinfo->comp = NULL; + kobject_get(&au_sbi(sb)->si_kobj); + __module_get(THIS_MODULE); + } + + INIT_WORK(&wkinfo->wk, wkq_func); + dlgt_cred_store(flags, wkinfo); + do_wkq(wkinfo); + if (do_wait) { + /* no timeout, no interrupt */ + wait_for_completion(wkinfo->comp); + au_wkq_comp_free(comp); + } + out: + AuTraceErr(err); + return err; +} + +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, + int dlgt) +{ + int err; + unsigned int flags = !AuWkq_WAIT; + + AuTraceEnter(); + + if (unlikely(dlgt)) + au_fset_wkq(flags, DLGT); + atomic_inc_return(&au_sbi(sb)->si_nowait.nw_len); + err = au_wkq_run(func, args, sb, flags); + if (unlikely(err)) + atomic_dec_return(&au_sbi(sb)->si_nowait.nw_len); + + return err; +} + +/* ---------------------------------------------------------------------- */ + +void au_wkq_fin(void) +{ + int i; + + AuTraceEnter(); + + for (i = 0; i < aufs_nwkq; i++) + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) + destroy_workqueue(au_wkq[i].q); + kfree(au_wkq); +} + +int __init au_wkq_init(void) +{ + int err, i; + struct au_wkq *nowaitq; + + LKTRTrace("%d\n", aufs_nwkq); + + /* '+1' is for accounting of nowait queue */ + err = -ENOMEM; + au_wkq = kcalloc(aufs_nwkq + 1, sizeof(*au_wkq), GFP_NOFS); + if (unlikely(!au_wkq)) + goto out; + + err = 0; + for (i = 0; i < aufs_nwkq; i++) { + au_wkq[i].q = create_singlethread_workqueue(AUFS_WKQ_NAME); + if (au_wkq[i].q && !IS_ERR(au_wkq[i].q)) { + atomic_set(&au_wkq[i].busy, 0); + au_wkq_max_busy_init(au_wkq + i); + continue; + } + + err = PTR_ERR(au_wkq[i].q); + au_wkq_fin(); + break; + } + + /* nowait accounting */ + nowaitq = au_wkq + aufs_nwkq; + atomic_set(&nowaitq->busy, 0); + au_wkq_max_busy_init(nowaitq); + nowaitq->q = NULL; + /* smp_mb(); */ /* atomic_set */ + + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/dentry.h +++ linux-2.6.28/ubuntu/aufs/dentry.h @@ -0,0 +1,396 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup and dentry operations + * + * $Id: dentry.h,v 1.7 2008/09/01 02:54:54 sfjro Exp $ + */ + +#ifndef __AUFS_DENTRY_H__ +#define __AUFS_DENTRY_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include "misc.h" +#include "super.h" +#include "vfsub.h" + +/* nameidata open_intent */ +enum { + AuIntent_AUFS, + AuIntent_BRANCH, + AuIntent_Last +}; + +struct au_hdintent { + struct list_head hdi_list; + struct file *hdi_file[AuIntent_Last]; +}; + +struct au_hdentry { + struct dentry *hd_dentry; + +#ifdef CONFIG_AUFS_BR_NFS + spinlock_t hd_lock; /* intest_list */ + struct list_head *hd_intent_list; +#endif +}; + +struct au_dinfo { + atomic_t di_generation; + + struct au_rwsem di_rwsem; + aufs_bindex_t di_bstart, di_bend, di_bwh, di_bdiropq; + struct au_hdentry *di_hdentry; +}; + +/* nameidata extension flags */ +#define AuNdx_DLGT 1 +#define AuNdx_DIRPERM1 (1 << 1) +#define au_ftest_ndx(flags, name) ((flags) & AuNdx_##name) +#define au_fset_ndx(flags, name) { (flags) |= AuNdx_##name; } +#define au_fclr_ndx(flags, name) { (flags) &= ~AuNdx_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuNdx_DLGT +#define AuNdx_DLGT 0 +#undef AuNdx_DIRPERM1 +#define AuNdx_DIRPERM1 0 +#endif + +struct au_ndx { + struct vfsmount *nfsmnt; + unsigned int flags; + struct nameidata *nd; + struct au_branch *br; + struct file *nd_file; +}; + +/* ---------------------------------------------------------------------- */ + +static inline void au_do_h_dentry_init(struct au_hdentry *hdentry) +{ + hdentry->hd_dentry = NULL; +} + +#ifdef CONFIG_AUFS_BR_NFS +static inline void au_h_dentry_init(struct au_hdentry *hdentry) +{ + au_do_h_dentry_init(hdentry); + spin_lock_init(&hdentry->hd_lock); +} + +static inline void au_h_dentry_init_all(struct au_hdentry *hdentry, int n) +{ + while (n--) + spin_lock_init(&hdentry[n].hd_lock); +} + +/* br_nfs.c */ +struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file); +int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry, + aufs_bindex_t bindex, struct nameidata *nd); +void au_hintent_put(struct au_hdentry *hd, int do_free); +int au_fake_intent(struct nameidata *nd, int perm); +int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry, + aufs_bindex_t bindex, struct file *file); +struct dentry *au_lkup_hash(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx); +#else + +static inline void au_h_dentry_init(struct au_hdentry *hdentry) +{ + au_do_h_dentry_init(hdentry); +} + +static inline void au_h_dentry_init_all(struct au_hdentry *hdentry, int n) +{ + /* nothing */ +} + +static inline +struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file) +{ + /* return ERR_PTR(-ENOSYS); */ + return NULL; +} + +static inline +int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry, + aufs_bindex_t bindex, struct nameidata *nd) +{ + return 0; +} + +static inline void au_hintent_put(struct au_hdentry *hd, int do_free) +{ + /* empty */ +} + +static inline int au_fake_intent(struct nameidata *nd, int perm) +{ + return 0; +} + +static inline +int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry, + aufs_bindex_t bindex, struct file *file) +{ + return 0; +} + +#ifdef CONFIG_AUFS_DLGT +static inline +struct dentry *au_lkup_hash(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + /* return ERR_PTR(-ENOSYS); */ + return vfsub_lookup_one_len(name, parent, len); +} +#endif +#endif /* CONFIG_AUFS_BR_NFS */ + +#ifdef CONFIG_AUFS_DLGT +/* dlgt.c */ +struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent, + int len, unsigned int flags); +#elif defined(CONFIG_AUFS_BR_NFS) +/* regardelss kernel version */ +static inline +struct dentry *au_lkup_one_dlgt(const char *name, struct dentry *parent, + int len, unsigned int flags) +{ + return vfsub_lookup_one_len(name, parent, len); +} +#endif + +/* dentry.c */ +extern struct dentry_operations aufs_dop; +#if defined(CONFIG_AUFS_BR_NFS) || defined(CONFIG_AUFS_DLGT) +struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx); +#else +static inline +struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + /* todo? ndx->nd_file = NULL; */ + return vfsub_lookup_one_len(name, parent, len); +} +#endif +struct dentry *au_sio_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx); +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, + struct nameidata *nd); +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex); +int au_refresh_hdentry(struct dentry *dentry, mode_t type); +int au_reval_dpath(struct dentry *dentry, au_gen_t sgen); + +/* dinfo.c */ +int au_alloc_dinfo(struct dentry *dentry); +struct au_dinfo *au_di(struct dentry *dentry); + +void di_read_lock(struct dentry *d, int flags, unsigned int lsc); +void di_read_unlock(struct dentry *d, int flags); +void di_downgrade_lock(struct dentry *d, int flags); +void di_write_lock(struct dentry *d, unsigned int lsc); +void di_write_unlock(struct dentry *d); +void di_write_lock2_child(struct dentry *d1, struct dentry *d2, int isdir); +void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir); +void di_write_unlock2(struct dentry *d1, struct dentry *d2); + +struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex); + +aufs_bindex_t au_dbtail(struct dentry *dentry); +aufs_bindex_t au_dbtaildir(struct dentry *dentry); +#if 0 /* reserved for future use */ +aufs_bindex_t au_dbtail_generic(struct dentry *dentry); +#endif + +void au_set_dbdiropq(struct dentry *dentry, aufs_bindex_t bindex); +void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_dentry); + +void au_update_dbrange(struct dentry *dentry, int do_put_zero); +void au_update_dbstart(struct dentry *dentry); +void au_update_dbend(struct dentry *dentry); +int au_find_dbindex(struct dentry *dentry, struct dentry *h_dentry); + +/* ---------------------------------------------------------------------- */ + +/* todo: memory barrier? */ +static inline au_gen_t au_digen(struct dentry *d) +{ + return atomic_read(&au_di(d)->di_generation); +} + +#ifdef CONFIG_AUFS_HINOTIFY +static inline au_gen_t au_digen_dec(struct dentry *d) +{ + return atomic_dec_return(&au_di(d)->di_generation); +} + +static inline void au_hin_di_reinit(struct dentry *d) +{ + d->d_fsdata = NULL; +} +#else +static inline void au_hin_di_reinit(struct dentry *d) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_HINOTIFY */ + +/* ---------------------------------------------------------------------- */ + +/* lock subclass for dinfo */ +enum { + AuLsc_DI_CHILD, /* child first */ + AuLsc_DI_CHILD2, /* rename(2), link(2), and cpup at hinotify */ + AuLsc_DI_CHILD3, /* copyup dirs */ + AuLsc_DI_PARENT, + AuLsc_DI_PARENT2, + AuLsc_DI_PARENT3, + AuLsc_DI_PARENT4 +}; + +/* + * di_read_lock_child, di_write_lock_child, + * di_read_lock_child2, di_write_lock_child2, + * di_read_lock_child3, di_write_lock_child3, + * di_read_lock_parent, di_write_lock_parent, + * di_read_lock_parent2, di_write_lock_parent2, + * di_read_lock_parent3, di_write_lock_parent3, + * di_read_lock_parent4, di_write_lock_parent4, + */ +#define AuReadLockFunc(name, lsc) \ +static inline void di_read_lock_##name(struct dentry *d, int flags) \ +{ di_read_lock(d, flags, AuLsc_DI_##lsc); } + +#define AuWriteLockFunc(name, lsc) \ +static inline void di_write_lock_##name(struct dentry *d) \ +{ di_write_lock(d, AuLsc_DI_##lsc); } + +#define AuRWLockFuncs(name, lsc) \ + AuReadLockFunc(name, lsc) \ + AuWriteLockFunc(name, lsc) + +AuRWLockFuncs(child, CHILD); +AuRWLockFuncs(child2, CHILD2); +AuRWLockFuncs(child3, CHILD3); +AuRWLockFuncs(parent, PARENT); +AuRWLockFuncs(parent2, PARENT2); +AuRWLockFuncs(parent3, PARENT3); +AuRWLockFuncs(parent4, PARENT4); + +#undef AuReadLockFunc +#undef AuWriteLockFunc +#undef AuRWLockFuncs + +/* to debug easier, do not make them inlined functions */ +#define DiMustReadLock(d) do { \ + SiMustAnyLock((d)->d_sb); \ + AuRwMustReadLock(&au_di(d)->di_rwsem); \ +} while (0) + +#define DiMustWriteLock(d) do { \ + SiMustAnyLock((d)->d_sb); \ + AuRwMustWriteLock(&au_di(d)->di_rwsem); \ +} while (0) + +#define DiMustAnyLock(d) do { \ + SiMustAnyLock((d)->d_sb); \ + AuRwMustAnyLock(&au_di(d)->di_rwsem); \ +} while (0) + +#define DiMustNoWaiters(d) AuRwMustNoWaiters(&au_di(d)->di_rwsem) + +/* ---------------------------------------------------------------------- */ + +static inline aufs_bindex_t au_dbstart(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + return au_di(dentry)->di_bstart; +} + +static inline aufs_bindex_t au_dbend(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + return au_di(dentry)->di_bend; +} + +static inline aufs_bindex_t au_dbwh(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + return au_di(dentry)->di_bwh; +} + +static inline aufs_bindex_t au_dbdiropq(struct dentry *dentry) +{ + DiMustAnyLock(dentry); + AuDebugOn(dentry->d_inode + && dentry->d_inode->i_mode + && !S_ISDIR(dentry->d_inode->i_mode)); + return au_di(dentry)->di_bdiropq; +} + +/* todo: hard/soft set? */ +static inline void au_set_dbstart(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex); + /* */ + au_di(dentry)->di_bstart = bindex; +} + +static inline void au_set_dbend(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex + || bindex < au_dbstart(dentry)); + au_di(dentry)->di_bend = bindex; +} + +static inline void au_set_dbwh(struct dentry *dentry, aufs_bindex_t bindex) +{ + DiMustWriteLock(dentry); + AuDebugOn(au_sbend(dentry->d_sb) < bindex); + /* dbwh can be outside of bstart - bend range */ + au_di(dentry)->di_bwh = bindex; +} + +static inline void au_hdput(struct au_hdentry *hd, int do_free) +{ + au_hintent_put(hd, do_free); + dput(hd->hd_dentry); +} + +static inline void au_update_digen(struct dentry *dentry) +{ + AuDebugOn(!dentry->d_sb); + atomic_set(&au_di(dentry)->di_generation, au_sigen(dentry->d_sb)); + /* smp_mb(); */ /* atomic_set */ +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DENTRY_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/file.c +++ linux-2.6.28/ubuntu/aufs/file.c @@ -0,0 +1,762 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * handling file/dir, and address_space operation + * + * $Id: file.c,v 1.16 2008/09/22 03:52:09 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* + * a dirty trick for handling FMODE_EXEC and deny_write_access(). + * because FMODE_EXEC flag is not passed to f_op->open(), + * set it to file->private_data temporary. + */ +#if !defined(CONFIG_AUFS_MODULE) || defined(CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH) +int au_store_fmode_exec(struct nameidata *nd, struct inode *inode) +{ + int err; + union { + void *p; + unsigned long ul; + } u; + + err = 0; + if (nd + && (nd->flags & LOOKUP_OPEN) + && nd->intent.open.file + && (nd->intent.open.flags & FMODE_EXEC) + && inode + && S_ISREG(inode->i_mode)) { + u.ul = nd->intent.open.flags; + nd->intent.open.file->private_data = u.p; + /* smp_mb(); */ + err = 1; + } + + return err; +} +#endif + +/* drop flags for writing */ +unsigned int au_file_roflags(unsigned int flags) +{ + flags &= ~(O_WRONLY | O_RDWR | O_APPEND | O_CREAT | O_TRUNC); + flags |= O_RDONLY | O_NOATIME; + return flags; +} + +/* common functions to regular file and dir */ +struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags, + struct file *file) +{ + struct file *h_file; + struct dentry *h_dentry; + struct inode *h_inode; + struct super_block *sb; + struct au_branch *br; + int err; + + LKTRTrace("%.*s, b%d, flags 0%o, f %d\n", + AuDLNPair(dentry), bindex, flags, !!file); + h_dentry = au_h_dptr(dentry, bindex); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + + /* a race condition can happen between open and unlink/rmdir */ + h_file = ERR_PTR(-ENOENT); + if (unlikely((!d_unhashed(dentry) && d_unhashed(h_dentry)) + || !h_inode)) + goto out; + + sb = dentry->d_sb; + br = au_sbr(sb, bindex); + au_br_get(br); + /* drop flags for writing */ + if (au_test_ro(sb, bindex, dentry->d_inode)) + flags = au_file_roflags(flags); + flags &= ~O_CREAT; + + h_file = NULL; + if (unlikely(file && au_test_nfs(h_dentry->d_sb))) + h_file = au_h_intent(dentry, bindex, file); + if (!h_file) + h_file = dentry_open(dget(h_dentry), mntget(br->br_mnt), flags); + + /* + * a dirty trick for handling FMODE_EXEC and deny_write_access(). + */ + if (file && (file->f_mode & FMODE_EXEC)) { + h_file->f_mode |= FMODE_EXEC; + smp_mb(); /* flush f_mode */ + err = au_deny_write_access(h_file); + if (unlikely(err)) { + fput(h_file); + h_file = ERR_PTR(err); + } + } + if (IS_ERR(h_file)) + au_br_put(br); + +out: + AuTraceErrPtr(h_file); + return h_file; +} + +static int do_coo(struct dentry *dentry, aufs_bindex_t bstart) +{ + int err; + struct dentry *parent; + aufs_bindex_t bcpup; + struct mutex *h_mtx; + struct super_block *sb; + struct au_pin pin; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(IS_ROOT(dentry)); + DiMustWriteLock(dentry); + + parent = dget_parent(dentry); + di_write_lock_parent(parent); + sb = dentry->d_sb; + err = AuWbrCopyup(au_sbi(sb), dentry); + bcpup = err; + if (err < 0) { + err = 0; /* stop copyup, it is not an error */ + goto out_dgrade; + } + err = 0; + + if (!au_h_dptr(parent, bcpup)) { + err = au_cpup_dirs(dentry, bcpup); + if (unlikely(err)) + goto out_dgrade; + } + + di_downgrade_lock(parent, AuLock_IR); + err = au_pin(&pin, dentry, bcpup, /*di_locked*/1, + /*do_gp*/au_opt_test(au_mntflags(sb), UDBA_INOTIFY)); + if (unlikely(err)) + goto out; + h_mtx = &au_h_dptr(dentry, bstart)->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + AuDebugOn(au_h_dptr(dentry, bcpup)); + err = au_sio_cpup_simple(dentry, bcpup, -1, AuCpup_DTIME); + AuTraceErr(err); + mutex_unlock(h_mtx); + au_unpin(&pin); + goto out; + + out_dgrade: + di_downgrade_lock(parent, AuLock_IR); + out: + di_read_unlock(parent, AuLock_IR); + dput(parent); + AuTraceErr(err); + return err; +} + +int au_do_open(struct inode *inode, struct file *file, + int (*open)(struct file *file, int flags)) +{ + int err; + struct dentry *dentry; + struct super_block *sb; + aufs_bindex_t bstart; + unsigned char coo; + + dentry = file->f_dentry; + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(dentry)); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + coo = 0; + switch (au_mntflags(sb) & AuOptMask_COO) { + case AuOpt_COO_LEAF: + coo = !S_ISDIR(inode->i_mode); + break; + case AuOpt_COO_ALL: + coo = 1; + break; + } + err = au_finfo_init(file); + if (unlikely(err)) + goto out; + + if (!coo) + di_read_lock_child(dentry, AuLock_IR); + else { + di_write_lock_child(dentry); + bstart = au_dbstart(dentry); + if (au_test_ro(sb, bstart, dentry->d_inode)) { + err = do_coo(dentry, bstart); + if (err) { + di_write_unlock(dentry); + goto out_finfo; + } + } + di_downgrade_lock(dentry, AuLock_IR); + } + + err = open(file, file->f_flags); + di_read_unlock(dentry, AuLock_IR); + + out_finfo: + fi_write_unlock(file); + if (unlikely(err)) + au_finfo_fin(file); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +int au_reopen_nondir(struct file *file) +{ + int err; + aufs_bindex_t bstart, bindex, bend; + struct dentry *dentry; + struct file *h_file, *h_file_tmp; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + bstart = au_dbstart(dentry); + //bstart = au_ibstart(inode); + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode) + || !au_h_dptr(dentry, bstart)->d_inode); + + h_file_tmp = NULL; + if (au_fbstart(file) == bstart) { + h_file = au_h_fptr(file, bstart); + if (file->f_mode == h_file->f_mode) + return 0; /* success */ + h_file_tmp = h_file; + get_file(h_file_tmp); + au_set_h_fptr(file, bstart, NULL); + } + AuDebugOn(au_fbstart(file) < bstart + || au_fi(file)->fi_hfile[0 + bstart].hf_file); + + h_file = au_h_open(dentry, bstart, file->f_flags & ~O_TRUNC, file); + err = PTR_ERR(h_file); + if (IS_ERR(h_file)) + goto out; /* todo: close all? */ + err = 0; + /* cpup_file_flags(h_file, file); */ + au_set_fbstart(file, bstart); + au_set_h_fptr(file, bstart, h_file); + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + + /* close lower files */ + bend = au_fbend(file); + for (bindex = bstart + 1; bindex <= bend; bindex++) + au_set_h_fptr(file, bindex, NULL); + au_set_fbend(file, bstart); + + out: + if (h_file_tmp) + fput(h_file_tmp); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_ready_to_write_wh(struct file *file, loff_t len, + aufs_bindex_t bcpup) +{ + int err; + aufs_bindex_t old_bstart; + struct inode *inode; + struct dentry *dentry, *hi_wh, *old_h_dentry; + struct au_dinfo *dinfo; + struct super_block *sb; + + AuTraceEnter(); + + dentry = file->f_dentry; + inode = dentry->d_inode; + hi_wh = au_hi_wh(inode, bcpup); + if (!hi_wh) + err = au_sio_cpup_wh(dentry, bcpup, len, file); + else { + /* already copied-up after unlink */ + dinfo = au_di(dentry); + old_bstart = dinfo->di_bstart; + dinfo->di_bstart = bcpup; + old_h_dentry = dinfo->di_hdentry[0 + bcpup].hd_dentry; + dinfo->di_hdentry[0 + bcpup].hd_dentry = hi_wh; + err = au_reopen_nondir(file); + dinfo->di_hdentry[0 + bcpup].hd_dentry = old_h_dentry; + dinfo->di_bstart = old_bstart; + } + + sb = dentry->d_sb; + if (!err && inode->i_nlink > 1 && au_opt_test(au_mntflags(sb), PLINK)) + au_plink_append(sb, inode, au_h_dptr(dentry, bcpup), bcpup); + + AuTraceErr(err); + return err; +} + +/* + * prepare the @file for writing. + */ +int au_ready_to_write(struct file *file, loff_t len, struct au_pin *pin) +{ + int err; + struct dentry *dentry, *parent, *h_dentry; + struct inode *h_inode, *inode; + struct super_block *sb; + aufs_bindex_t bstart, bcpup; + + dentry = file->f_dentry; + LKTRTrace("%.*s, len %lld\n", AuDLNPair(dentry), len); + FiMustWriteLock(file); + + sb = dentry->d_sb; + bstart = au_fbstart(file); + AuDebugOn(au_fbr(file, bstart) != au_sbr(sb, bstart)); + + inode = dentry->d_inode; + AuDebugOn(S_ISDIR(inode->i_mode)); + LKTRTrace("rdonly %d, bstart %d\n", + au_test_ro(sb, bstart, inode), bstart); + + err = au_test_ro(sb, bstart, inode); + if (!err && (au_h_fptr(file, bstart)->f_mode & FMODE_WRITE)) { + err = au_pin(pin, dentry, bstart, /*di_locked*/0, /*dp_gp*/0); + goto out; + } + + /* need to cpup */ + parent = dget_parent(dentry); + di_write_lock_parent(parent); + err = AuWbrCopyup(au_sbi(sb), dentry); + bcpup = err; + if (unlikely(err < 0)) + goto out_dgrade; + err = 0; + + if (!au_h_dptr(parent, bcpup)) { + err = au_cpup_dirs(dentry, bcpup); + if (unlikely(err)) + goto out_dgrade; + } + + err = au_pin(pin, dentry, bcpup, /*di_locked*/1, + /*dp_gp*/au_opt_test(au_mntflags(sb), UDBA_INOTIFY)); + if (unlikely(err)) + goto out_dgrade; + + AuDebugOn(au_fbstart(file) != bstart); + h_dentry = au_h_fptr(file, bstart)->f_dentry; + h_inode = h_dentry->d_inode; + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + if (d_unhashed(dentry) /* || d_unhashed(h_dentry) */ + /* || !h_inode->i_nlink */) { + err = au_ready_to_write_wh(file, len, bcpup); + di_downgrade_lock(parent, AuLock_IR); + } else { + di_downgrade_lock(parent, AuLock_IR); + if (!au_h_dptr(dentry, bcpup)) + err = au_sio_cpup_simple(dentry, bcpup, len, + AuCpup_DTIME); + AuTraceErr(err); + if (!err) + err = au_reopen_nondir(file); + AuTraceErr(err); + } + mutex_unlock(&h_inode->i_mutex); + + if (!err) { + au_unpin_gp(pin); + au_pin_set_parent_lflag(pin, /*lflag*/0); + goto out_dput; /* success */ + } + au_unpin(pin); + goto out_unlock; + + out_dgrade: + di_downgrade_lock(parent, AuLock_IR); + out_unlock: + di_read_unlock(parent, AuLock_IR); + out_dput: + dput(parent); + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_file_refresh_by_inode(struct file *file, int *need_reopen) +{ + int err; + struct au_finfo *finfo; + struct dentry *dentry, *parent, *old_h_dentry, *hi_wh; + struct inode *inode, *dir; + aufs_bindex_t bstart, new_bstart, old_bstart; + struct super_block *sb; + struct au_dinfo *dinfo; + unsigned int mnt_flags; + struct au_pin pin; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + FiMustWriteLock(file); + + err = 0; + finfo = au_fi(file); + inode = dentry->d_inode; + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + again: + bstart = au_ibstart(inode); + if (bstart == finfo->fi_bstart) + goto out; + + new_bstart = bstart; + parent = dget_parent(dentry); + dir = parent->d_inode; + if (au_test_ro(sb, bstart, inode)) { + di_read_lock_parent(parent, !AuLock_IR); + err = AuWbrCopyup(au_sbi(sb), dentry); + new_bstart = err; + di_read_unlock(parent, !AuLock_IR); + if (unlikely(err < 0)) + goto out_dput; + err = 0; + } + /* someone else might change our inode while we were sleeping */ + /* todo: test more? */ + if (bstart != au_ibstart(inode)) { + err = 0; + dput(parent); + goto again; + } + di_read_lock_parent(parent, AuLock_IR); + bstart = new_bstart; + + hi_wh = au_hi_wh(inode, bstart); + if (au_opt_test(mnt_flags, PLINK) + && au_plink_test(sb, inode) + && !d_unhashed(dentry)) { + err = au_test_and_cpup_dirs(dentry, bstart); + if (unlikely(err)) + goto out_unlock; + + /* always superio. */ +#if 1 + err = au_pin(&pin, dentry, bstart, /*di_locked*/1, + /*do_gp*/au_opt_test(mnt_flags, UDBA_INOTIFY)); + if (!err) + err = au_sio_cpup_simple(dentry, bstart, -1, AuCpup_DTIME); + au_unpin(&pin); +#else /* reserved for future use */ + if (!au_test_wkq(current)) { + int wkq_err; + struct cpup_pseudo_link_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bstart, + .do_lock = 1 + }; + wkq_err = au_wkq_wait(call_cpup_pseudo_link, &args); + if (unlikely(wkq_err)) + err = wkq_err; + } else + err = cpup_pseudo_link(dentry, bstart, /*do_lock*/1); +#endif + } else if (hi_wh) { + /* already copied-up after unlink */ + dinfo = au_di(dentry); + old_bstart = dinfo->di_bstart; + dinfo->di_bstart = bstart; + old_h_dentry = dinfo->di_hdentry[0 + bstart].hd_dentry; + dinfo->di_hdentry[0 + bstart].hd_dentry = hi_wh; + err = au_reopen_nondir(file); + dinfo->di_hdentry[0 + bstart].hd_dentry = old_h_dentry; + dinfo->di_bstart = old_bstart; + *need_reopen = 0; + } + + out_unlock: + di_read_unlock(parent, AuLock_IR); + out_dput: + dput(parent); + out: + AuTraceErr(err); + return err; +} + +/* + * after branch manipulating, refresh the file. + */ +static int refresh_file(struct file *file, int (*reopen)(struct file *file)) +{ + int err, new_sz, need_reopen; + struct dentry *dentry; + aufs_bindex_t bend, bindex, brid; + struct au_hfile *p; + struct au_finfo *finfo; + struct super_block *sb; + struct inode *inode; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + FiMustWriteLock(file); + DiMustAnyLock(dentry); + inode = dentry->d_inode; + IiMustAnyLock(inode); + + err = -ENOMEM; + sb = dentry->d_sb; + finfo = au_fi(file); + new_sz = sizeof(*finfo->fi_hfile) * (au_sbend(sb) + 1); + p = au_kzrealloc(finfo->fi_hfile, sizeof(*p) * (finfo->fi_bend + 1), + new_sz, GFP_NOFS); + if (unlikely(!p)) + goto out; + finfo->fi_hfile = p; + + p += finfo->fi_bstart; + brid = p->hf_br->br_id; + bend = finfo->fi_bend; + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++, p++) { + struct au_hfile tmp, *q; + aufs_bindex_t new_bindex; + + if (!p->hf_file) + continue; + new_bindex = au_find_bindex(sb, p->hf_br); + if (new_bindex == bindex) + continue; + /* todo: test more? */ + if (new_bindex < 0) { + au_set_h_fptr(file, bindex, NULL); + continue; + } + + /* swap two hidden inode, and loop again */ + q = finfo->fi_hfile + new_bindex; + tmp = *q; + *q = *p; + *p = tmp; + if (tmp.hf_file) { + bindex--; + p--; + } + } + { + aufs_bindex_t s = finfo->fi_bstart, e = finfo->fi_bend; + finfo->fi_bstart = 0; + finfo->fi_bend = au_sbend(sb); + finfo->fi_bstart = s; + finfo->fi_bend = e; + } + + p = finfo->fi_hfile; + if (!au_test_mmapped(file) && !d_unhashed(dentry)) { + bend = au_sbend(sb); + for (finfo->fi_bstart = 0; finfo->fi_bstart <= bend; + finfo->fi_bstart++, p++) + if (p->hf_file) { + if (p->hf_file->f_dentry + && p->hf_file->f_dentry->d_inode) + break; + else + au_hfput(p); + } + } else { + bend = au_br_index(sb, brid); + for (finfo->fi_bstart = 0; finfo->fi_bstart < bend; + finfo->fi_bstart++, p++) + if (p->hf_file) + au_hfput(p); + bend = au_sbend(sb); + } + + p = finfo->fi_hfile + bend; + for (finfo->fi_bend = bend; finfo->fi_bend >= finfo->fi_bstart; + finfo->fi_bend--, p--) + if (p->hf_file) { + if (p->hf_file->f_dentry + && p->hf_file->f_dentry->d_inode) + break; + else + au_hfput(p); + } + AuDebugOn(finfo->fi_bend < finfo->fi_bstart); + + err = 0; + need_reopen = 1; + if (!au_test_mmapped(file)) + err = au_file_refresh_by_inode(file, &need_reopen); + if (!err && need_reopen && !d_unhashed(dentry)) + err = reopen(file); + if (!err) { + au_update_figen(file); + return 0; /* success */ + } + + /* error, close all hidden files */ + bend = au_fbend(file); + for (bindex = au_fbstart(file); bindex <= bend; bindex++) + au_set_h_fptr(file, bindex, NULL); + + out: + AuTraceErr(err); + return err; +} + +/* common function to regular file and dir */ +int au_reval_and_lock_fdi(struct file *file, int (*reopen)(struct file *file), + int wlock, int locked) +{ + int err; + struct dentry *dentry; + struct super_block *sb; + aufs_bindex_t bstart; + unsigned char pseudo_link; + au_gen_t sgen, fgen; + + dentry = file->f_dentry; + LKTRTrace("%.*s, w %d, l %d\n", AuDLNPair(dentry), wlock, locked); + sb = dentry->d_sb; + SiMustAnyLock(sb); + + err = 0; + sgen = au_sigen(sb); + fi_write_lock(file); + fgen = au_figen(file); + di_write_lock_child(dentry); + bstart = au_dbstart(dentry); + pseudo_link = (bstart != au_ibstart(dentry->d_inode)); + if (sgen == fgen && !pseudo_link && au_fbstart(file) == bstart) { + if (!wlock) { + di_downgrade_lock(dentry, AuLock_IR); + fi_downgrade_lock(file); + } + goto out; /* success */ + } + + LKTRTrace("sgen %d, fgen %d\n", sgen, fgen); + if (unlikely(sgen != au_digen(dentry) + || sgen != au_iigen(dentry->d_inode))) { + /* + * d_path() and path_lookup() is a simple and good approach + * to revalidate. but si_rwsem in DEBUG_RWSEM will cause a + * deadlock. removed the code. + */ + err = au_reval_dpath(dentry, sgen); + if (unlikely(err < 0)) + goto out; + AuDebugOn(au_digen(dentry) != sgen + || au_iigen(dentry->d_inode) != sgen); + } + + err = refresh_file(file, reopen + /* , au_opt_test(au_mnt_flags(sb), REFROF) */); + if (!err) { + if (!wlock) { + di_downgrade_lock(dentry, AuLock_IR); + fi_downgrade_lock(file); + } + } else { + di_write_unlock(dentry); + fi_write_unlock(file); + } + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* cf. aufs_nopage() */ +/* for madvise(2) */ +static int aufs_readpage(struct file *file, struct page *page) +{ + AuTraceEnter(); + unlock_page(page); + return 0; +} + +/* they will never be called. */ +#ifdef CONFIG_AUFS_DEBUG +static int aufs_prepare_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ AuUnsupport(); return 0; } +static int aufs_commit_write(struct file *file, struct page *page, + unsigned from, unsigned to) +{ AuUnsupport(); return 0; } +static int aufs_write_begin(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned flags, + struct page **pagep, void **fsdata) +{ AuUnsupport(); return 0; } +static int aufs_write_end(struct file *file, struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) +{ AuUnsupport(); return 0; } +static int aufs_writepage(struct page *page, struct writeback_control *wbc) +{ AuUnsupport(); return 0; } +static void aufs_sync_page(struct page *page) +{ AuUnsupport(); } + +static int aufs_set_page_dirty(struct page *page) +{ AuUnsupport(); return 0; } +static void aufs_invalidatepage(struct page *page, unsigned long offset) +{ AuUnsupport(); } +static int aufs_releasepage(struct page *page, gfp_t gfp) +{ AuUnsupport(); return 0; } +static ssize_t aufs_direct_IO(int rw, struct kiocb *iocb, + const struct iovec *iov, loff_t offset, + unsigned long nr_segs) +{ AuUnsupport(); return 0; } +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) +static struct page *aufs_get_xip_page(struct address_space *mapping, + sector_t offset, int create) +{ AuUnsupport(); return NULL; } +#endif +#endif /* CONFIG_AUFS_DEBUG */ + +struct address_space_operations aufs_aop = { + .readpage = aufs_readpage, +#ifdef CONFIG_AUFS_DEBUG + .writepage = aufs_writepage, + .sync_page = aufs_sync_page, + .set_page_dirty = aufs_set_page_dirty, + .prepare_write = aufs_prepare_write, + .commit_write = aufs_commit_write, + .write_begin = aufs_write_begin, + .write_end = aufs_write_end, + .invalidatepage = aufs_invalidatepage, + .releasepage = aufs_releasepage, + .direct_IO = aufs_direct_IO, +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26) + .get_xip_page = aufs_get_xip_page, +#endif +#endif /* CONFIG_AUFS_DEBUG */ +}; --- linux-2.6.28.orig/ubuntu/aufs/dcsub.c +++ linux-2.6.28/ubuntu/aufs/dcsub.c @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for dentry cache + * + * $Id: dcsub.c,v 1.7 2008/07/21 02:54:22 sfjro Exp $ + */ + +#include "aufs.h" + +static void au_dpage_free(struct au_dpage *dpage) +{ + int i; + + AuTraceEnter(); + AuDebugOn(!dpage); + + for (i = 0; i < dpage->ndentry; i++) + dput(dpage->dentries[i]); + free_page((unsigned long)dpage->dentries); +} + +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp) +{ + int err; + void *p; + + AuTraceEnter(); + + err = -ENOMEM; + dpages->dpages = kmalloc(sizeof(*dpages->dpages), gfp); + if (unlikely(!dpages->dpages)) + goto out; + p = (void *)__get_free_page(gfp); + if (unlikely(!p)) + goto out_dpages; + dpages->dpages[0].ndentry = 0; + dpages->dpages[0].dentries = p; + dpages->ndpage = 1; + return 0; /* success */ + + out_dpages: + kfree(dpages->dpages); + out: + AuTraceErr(err); + return err; +} + +void au_dpages_free(struct au_dcsub_pages *dpages) +{ + int i; + + AuTraceEnter(); + + for (i = 0; i < dpages->ndpage; i++) + au_dpage_free(dpages->dpages + i); + kfree(dpages->dpages); +} + +static int au_dpages_append(struct au_dcsub_pages *dpages, + struct dentry *dentry, gfp_t gfp) +{ + int err, sz; + struct au_dpage *dpage; + void *p; + + /* AuTraceEnter(); */ + + dpage = dpages->dpages + dpages->ndpage - 1; + AuDebugOn(!dpage); + sz = PAGE_SIZE / sizeof(dentry); + if (unlikely(dpage->ndentry >= sz)) { + LKTRLabel(new dpage); + err = -ENOMEM; + sz = dpages->ndpage * sizeof(*dpages->dpages); + p = au_kzrealloc(dpages->dpages, sz, + sz + sizeof(*dpages->dpages), gfp); + if (unlikely(!p)) + goto out; + dpages->dpages = p; + dpage = dpages->dpages + dpages->ndpage; + p = (void *)__get_free_page(gfp); + if (unlikely(!p)) + goto out; + dpage->ndentry = 0; + dpage->dentries = p; + dpages->ndpage++; + } + + dpage->dentries[dpage->ndentry++] = dget(dentry); + return 0; /* success */ + + out: + /* AuTraceErr(err); */ + return err; +} + +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, + au_dpages_test test, void *arg) +{ + int err; + struct dentry *this_parent = root; + struct list_head *next; + struct super_block *sb = root->d_sb; + + AuTraceEnter(); + + err = 0; + spin_lock(&dcache_lock); + repeat: + next = this_parent->d_subdirs.next; + resume: + if (this_parent->d_sb == sb + && !IS_ROOT(this_parent) + && atomic_read(&this_parent->d_count) + && this_parent->d_inode + && (!test || test(this_parent, arg))) { + err = au_dpages_append(dpages, this_parent, GFP_ATOMIC); + if (unlikely(err)) + goto out; + } + + while (next != &this_parent->d_subdirs) { + struct list_head *tmp = next; + struct dentry *dentry = list_entry(tmp, struct dentry, + d_u.d_child); + next = tmp->next; + if (unlikely(/*d_unhashed(dentry) || */!dentry->d_inode)) + continue; + if (!list_empty(&dentry->d_subdirs)) { + this_parent = dentry; + goto repeat; + } + if (dentry->d_sb == sb + && atomic_read(&dentry->d_count) + && (!test || test(dentry, arg))) { + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); + if (unlikely(err)) + goto out; + } + } + + if (this_parent != root) { + next = this_parent->d_u.d_child.next; + this_parent = this_parent->d_parent; /* dcache_lock is locked */ + goto resume; + } + out: + spin_unlock(&dcache_lock); +#if 0 /* debug */ + if (!err) { + int i, j; + j = 0; + for (i = 0; i < dpages->ndpage; i++) { + if ((dpages->dpages + i)->ndentry) + AuDbg("%d: %d\n", + i, (dpages->dpages + i)->ndentry); + j += (dpages->dpages + i)->ndentry; + } + if (j) + AuDbg("ndpage %d, %d\n", dpages->ndpage, j); + } +#endif + AuTraceErr(err); + return err; +} + +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, + int do_include, au_dpages_test test, void *arg) +{ + int err; + + AuTraceEnter(); + + err = 0; + spin_lock(&dcache_lock); + if (do_include && (!test || test(dentry, arg))) { + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); + if (unlikely(err)) + goto out; + } + while (!IS_ROOT(dentry)) { + dentry = dentry->d_parent; /* dcache_lock is locked */ + if (!test || test(dentry, arg)) { + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); + if (unlikely(err)) + break; + } + } + + out: + spin_unlock(&dcache_lock); + + AuTraceErr(err); + return err; +} + +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2) +{ + struct dentry *trap, **dentries; + int err, i, j; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + + LKTRTrace("%.*s, %.*s\n", AuDLNPair(d1), AuDLNPair(d2)); + + trap = ERR_PTR(-ENOMEM); + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) + goto out; + err = au_dcsub_pages_rev(&dpages, d1, /*do_include*/1, NULL, NULL); + if (unlikely(err)) + goto out_dpages; + + trap = d1; + for (i = 0; !err && i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + for (j = 0; !err && j < dpage->ndentry; j++) { + struct dentry *d; + d = dentries[j]; + err = (d == d2); + if (!err) + trap = d; + } + } + if (!err) + trap = NULL; + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErrPtr(trap); + return trap; +} --- linux-2.6.28.orig/ubuntu/aufs/hin_or_dlgt.c +++ linux-2.6.28/ubuntu/aufs/hin_or_dlgt.c @@ -0,0 +1,737 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for vfs in hinotify or dlgt mode + * + * $Id: hin_or_dlgt.c,v 1.6 2008/07/14 00:15:10 sfjro Exp $ + */ + +#include +#include "aufs.h" + +#if !defined(CONFIG_AUFS_HINOTIFY) && !defined(CONFIG_AUFS_DLGT) +#error mis-configuraion or Makefile +#endif + +/* ---------------------------------------------------------------------- */ + +struct permission_args { + int *errp; + struct inode *inode; + int mask; + struct nameidata *nd; +}; + +static void call_permission(void *args) +{ + struct permission_args *a = args; + *a->errp = do_vfsub_permission(a->inode, a->mask, a->nd); +} + +int vfsub_permission(struct inode *inode, int mask, struct nameidata *nd, + int dlgt) +{ + if (!dlgt) + return do_vfsub_permission(inode, mask, nd); + else { + int err, wkq_err; + struct permission_args args = { + .errp = &err, + .inode = inode, + .mask = mask, + .nd = nd + }; + wkq_err = au_wkq_wait(call_permission, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +/* ---------------------------------------------------------------------- */ + +struct create_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + struct nameidata *nd; + struct vfsub_args *vargs; +}; + +static void call_create(void *args) +{ + struct create_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_create(a->dir, a->dentry, a->mode, a->nd); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd, struct vfsub_args *vargs) +{ + int err; + struct create_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .nd = nd, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_create(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_create, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct symlink_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + const char *symname; + int mode; + struct vfsub_args *vargs; +}; + +static void call_symlink(void *args) +{ + struct symlink_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_symlink(a->dir, a->dentry, a->symname, a->mode); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_symlink(struct inode *dir, struct dentry *dentry, const char *symname, + int mode, struct vfsub_args *vargs) +{ + int err; + struct symlink_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .symname = symname, + .mode = mode, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_symlink(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_symlink, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct mknod_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + dev_t dev; + struct vfsub_args *vargs; +}; + +static void call_mknod(void *args) +{ + struct mknod_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_mknod(a->dir, a->dentry, a->mode, a->dev); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev, + struct vfsub_args *vargs) +{ + int err; + struct mknod_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .dev = dev, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_mknod(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_mknod, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct mkdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + int mode; + struct vfsub_args *vargs; +}; + +static void call_mkdir(void *args) +{ + struct mkdir_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_mkdir(a->dir, a->dentry, a->mode); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode, + struct vfsub_args *vargs) +{ + int err; + struct mkdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .mode = mode, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_mkdir(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_mkdir, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct link_args { + int *errp; + struct inode *dir; + struct dentry *src_dentry, *dentry; + struct vfsub_args *vargs; +}; + +static void call_link(void *args) +{ + struct link_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_link(a->src_dentry, a->dir, a->dentry); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct vfsub_args *vargs) +{ + int err; + struct link_args args = { + .errp = &err, + .src_dentry = src_dentry, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_link(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_link, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct rename_args { + int *errp; + struct inode *src_dir, *dir; + struct dentry *src_dentry, *dentry; + struct vfsub_args *vargs; +}; + +static void call_rename(void *args) +{ + struct rename_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_rename(a->src_dir, a->src_dentry, a->dir, + a->dentry); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + int err; + struct rename_args args = { + .errp = &err, + .src_dir = src_dir, + .src_dentry = src_dentry, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_rename(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_rename, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct rmdir_args { + int *errp; + struct inode *dir; + struct dentry *dentry; + struct vfsub_args *vargs; +}; + +static void call_rmdir(void *args) +{ + struct rmdir_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_rmdir(a->dir, a->dentry); + if (unlikely(*a->errp)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +int vfsub_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsub_args *vargs) +{ + int err; + struct rmdir_args args = { + .errp = &err, + .dir = dir, + .dentry = dentry, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_rmdir(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_rmdir, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct read_args { + ssize_t *errp; + struct file *file; + union { + void *kbuf; + char __user *ubuf; + }; + size_t count; + loff_t *ppos; +}; + +static void call_read_k(void *args) +{ + struct read_args *a = args; + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(a->file->f_dentry), (unsigned long)a->count, + *a->ppos); + *a->errp = do_vfsub_read_k(a->file, a->kbuf, a->count, a->ppos); +} + +ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count, + loff_t *ppos, int dlgt) +{ + if (!dlgt) + return do_vfsub_read_u(file, ubuf, count, ppos); + else { + int wkq_err; + ssize_t err, read; + struct read_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos + }; + + if (unlikely(!count)) + return 0; + + /* + * workaround an application bug. + * generally, read(2) or write(2) may return the value shorter + * than requested. But many applications don't support it, + * for example bash. + */ + err = -ENOMEM; + if (args.count > PAGE_SIZE) + args.count = PAGE_SIZE; + args.kbuf = kmalloc(args.count, GFP_NOFS); + if (unlikely(!args.kbuf)) + goto out; + + read = 0; + do { + wkq_err = au_wkq_wait(call_read_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + if (unlikely(err > 0 + && copy_to_user(ubuf, args.kbuf, err))) { + err = -EFAULT; + goto out_free; + } else if (!err) + break; + else if (unlikely(err < 0)) + goto out_free; + count -= err; + /* do not read too much because of file i/o pointer */ + if (count < args.count) + args.count = count; + ubuf += err; + read += err; + } while (count); + smp_mb(); /* flush ubuf */ + err = read; + + out_free: + kfree(args.kbuf); + out: + return err; + } +} + +ssize_t vfsub_read_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + int dlgt) +{ + if (!dlgt) + return do_vfsub_read_k(file, kbuf, count, ppos); + else { + ssize_t err; + int wkq_err; + struct read_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos + }; + args.kbuf = kbuf; + wkq_err = au_wkq_wait(call_read_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +struct write_args { + ssize_t *errp; + struct file *file; + union { + void *kbuf; + const char __user *ubuf; + }; + size_t count; + loff_t *ppos; + struct vfsub_args *vargs; +}; + +static void call_write_k(void *args) +{ + struct write_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_write_k(a->file, a->kbuf, a->count, a->ppos); + if (unlikely(*a->errp <= 0)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count, + loff_t *ppos, struct vfsub_args *vargs) +{ + ssize_t err; + + if (!vfsub_ftest(vargs->flags, DLGT)) { + vfsub_ignore(vargs); + err = do_vfsub_write_u(file, ubuf, count, ppos); + if (unlikely(err <= 0)) + vfsub_unignore(vargs); + au_dbg_hin_list(vargs); + } else { + ssize_t written; + int wkq_err; + struct write_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos, + .vargs = vargs + }; + + if (unlikely(!count)) + return 0; + + /* + * workaround an application bug. + * generally, read(2) or write(2) may return the value shorter + * than requested. But many applications don't support it, + * for example bash. + */ + err = -ENOMEM; + if (args.count > PAGE_SIZE) + args.count = PAGE_SIZE; + args.kbuf = kmalloc(args.count, GFP_NOFS); + if (unlikely(!args.kbuf)) + goto out; + + written = 0; + do { + if (unlikely(copy_from_user(args.kbuf, ubuf, + args.count))) { + err = -EFAULT; + goto out_free; + } + + wkq_err = au_wkq_wait(call_write_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + if (err > 0) { + count -= err; + if (count < args.count) + args.count = count; + ubuf += err; + written += err; + } else if (!err) + break; + else if (unlikely(err < 0)) + goto out_free; + } while (count); + err = written; + + out_free: + kfree(args.kbuf); + } + out: + return err; +} + +ssize_t vfsub_write_k(struct file *file, void *kbuf, size_t count, loff_t *ppos, + struct vfsub_args *vargs) +{ + ssize_t err; + struct write_args args = { + .errp = &err, + .file = file, + .count = count, + .ppos = ppos, + .vargs = vargs + }; + + args.kbuf = kbuf; + if (!vfsub_ftest(vargs->flags, DLGT)) + call_write_k(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_write_k, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +struct readdir_args { + int *errp; + struct file *file; + filldir_t filldir; + void *arg; +}; + +static void call_readdir(void *args) +{ + struct readdir_args *a = args; + *a->errp = do_vfsub_readdir(a->file, a->filldir, a->arg); +} + +int vfsub_readdir(struct file *file, filldir_t filldir, void *arg, int dlgt) +{ + if (!dlgt) + return do_vfsub_readdir(file, filldir, arg); + else { + int err, wkq_err; + struct readdir_args args = { + .errp = &err, + .file = file, + .filldir = filldir, + .arg = arg + }; + wkq_err = au_wkq_wait(call_readdir, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +/* ---------------------------------------------------------------------- */ + +struct splice_to_args { + long *errp; + struct file *in; + loff_t *ppos; + struct pipe_inode_info *pipe; + size_t len; + unsigned int flags; +}; + +static void call_splice_to(void *args) +{ + struct splice_to_args *a = args; + *a->errp = do_vfsub_splice_to(a->in, a->ppos, a->pipe, a->len, + a->flags); +} + +long vfsub_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags, int dlgt) +{ + if (!dlgt) + return do_vfsub_splice_to(in, ppos, pipe, len, flags); + else { + long err; + int wkq_err; + struct splice_to_args args = { + .errp = &err, + .in = in, + .ppos = ppos, + .pipe = pipe, + .len = len, + .flags = flags + }; + wkq_err = au_wkq_wait(call_splice_to, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} + +struct splice_from_args { + long *errp; + struct pipe_inode_info *pipe; + struct file *out; + loff_t *ppos; + size_t len; + unsigned int flags; + struct vfsub_args *vargs; +}; + +static void call_splice_from(void *args) +{ + struct splice_from_args *a = args; + vfsub_ignore(a->vargs); + *a->errp = do_vfsub_splice_from(a->pipe, a->out, a->ppos, a->len, + a->flags); + if (unlikely(*a->errp < 0)) + vfsub_unignore(a->vargs); + au_dbg_hin_list(a->vargs); +} + +long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags, + struct vfsub_args *vargs) +{ + long err; + struct splice_from_args args = { + .errp = &err, + .pipe = pipe, + .out = out, + .ppos = ppos, + .len = len, + .flags = flags, + .vargs = vargs + }; + + if (!vfsub_ftest(vargs->flags, DLGT)) + call_splice_from(&args); + else { + int wkq_err; + wkq_err = au_wkq_wait(call_splice_from, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + } + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct getattr_args { + int *errp; + struct vfsmount *mnt; + struct dentry *dentry; + struct kstat *st; +}; + +static void call_getattr(void *args) +{ + struct getattr_args *a = args; + *a->errp = do_vfsub_getattr(a->mnt, a->dentry, a->st); +} + +int vfsub_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st, + int dlgt) +{ + if (!dlgt) + return do_vfsub_getattr(mnt, dentry, st); + else { + int err, wkq_err; + struct getattr_args args = { + .errp = &err, + .mnt = mnt, + .dentry = dentry, + .st = st + }; + wkq_err = au_wkq_wait(call_getattr, &args, /*dlgt*/1); + if (unlikely(wkq_err)) + err = wkq_err; + return err; + } +} --- linux-2.6.28.orig/ubuntu/aufs/module.h +++ linux-2.6.28/ubuntu/aufs/module.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * module initialization and module-global + * + * $Id: module.h,v 1.8 2008/08/25 01:50:37 sfjro Exp $ + */ + +#ifndef __AUFS_MODULE_H__ +#define __AUFS_MODULE_H__ + +#ifdef __KERNEL__ + +/* module parameters */ +extern short aufs_nwkq; +extern int sysaufs_brs; + +/* ---------------------------------------------------------------------- */ + +extern char au_esc_chars[]; +extern int au_dir_roflags; + +/* kmem cache */ +enum { + AuCache_DINFO, + AuCache_ICNTNR, + AuCache_FINFO, + AuCache_VDIR, + AuCache_DEHSTR, +#ifdef CONFIG_AUFS_HINOTIFY + AuCache_HINOTIFY, +#endif + AuCache_Last +}; + +extern struct kmem_cache *au_cachep[]; + +#define AuCacheArgs(type, sz) (type), (sz), 0, SLAB_RECLAIM_ACCOUNT, NULL +#define AuCache(type) \ + kmem_cache_create(AuCacheArgs(#type, sizeof(struct type))) + +/* ---------------------------------------------------------------------- */ + +#define AuCacheFuncs(name, index) \ +static inline void *au_cache_alloc_##name(void) \ +{ return kmem_cache_alloc(au_cachep[index], GFP_NOFS); } \ +static inline void au_cache_free_##name(void *p) \ +{ kmem_cache_free(au_cachep[index], p); } + +AuCacheFuncs(dinfo, AuCache_DINFO); +AuCacheFuncs(icntnr, AuCache_ICNTNR); +AuCacheFuncs(finfo, AuCache_FINFO); +AuCacheFuncs(vdir, AuCache_VDIR); +AuCacheFuncs(dehstr, AuCache_DEHSTR); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/dentry.c +++ linux-2.6.28/ubuntu/aufs/dentry.c @@ -0,0 +1,1023 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup and dentry operations + * + * $Id: dentry.c,v 1.15 2008/09/22 03:52:06 sfjro Exp $ + */ + +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +/* + * au_lkup_one() is a generic abstract entry function which calls + * lookup_one_len() or __lookup_hash() finally. it is some condisions that makes + * lookup complicated, which are nfs branch, open-intent and dlgt mode. + */ + +#if defined(CONFIG_AUFS_BR_NFS) || defined(CONFIG_AUFS_DLGT) +/* cf. lookup_one_len() in linux/fs/namei.c */ +struct dentry *au_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + struct dentry *dentry; + + LKTRTrace("%.*s/%.*s, ndx{%d, 0x%x}\n", + AuDLNPair(parent), len, name, !!ndx->nfsmnt, ndx->flags); + + ndx->nd_file = NULL; + if (!ndx->nfsmnt) + dentry = au_lkup_one_dlgt(name, parent, len, ndx->flags); + else + dentry = au_lkup_hash(name, parent, len, ndx); + + AuTraceErrPtr(dentry); + return dentry; +} +#endif /* CONFIG_AUFS_BR_NFS || CONFIG_AUFS_DLGT */ + +struct au_lkup_one_args { + struct dentry **errp; + const char *name; + struct dentry *parent; + int len; + struct au_ndx *ndx; +}; + +static void au_call_lkup_one(void *args) +{ + struct au_lkup_one_args *a = args; + *a->errp = au_lkup_one(a->name, a->parent, a->len, a->ndx); +} + +#define AuLkup_ALLOW_NEG 1 +#define AuLkup_DLGT (1 << 1) +#define AuLkup_DIRPERM1 (1 << 2) +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) +#define au_fset_lkup(flags, name) { (flags) |= AuLkup_##name; } +#define au_fclr_lkup(flags, name) { (flags) &= ~AuLkup_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuLkup_DLGT +#define AuLkup_DLGT 0 +#undef AuLkup_DIRPERM1 +#define AuLkup_DIRPERM1 0 +#endif + +struct au_do_lookup_args { + unsigned int flags; + mode_t type; + struct nameidata *nd; +}; + +/* + * returns positive/negative dentry, NULL or an error. + * NULL means whiteout-ed or not-found. + */ +static /* noinline_for_stack */ +struct dentry *au_do_lookup(struct dentry *h_parent, struct dentry *dentry, + aufs_bindex_t bindex, struct qstr *wh_name, + struct au_do_lookup_args *args) +{ + struct dentry *h_dentry; + int err, wh_found, opq; + unsigned char wh_able; + struct inode *h_dir, *h_inode, *inode; + struct qstr *name; + struct super_block *sb; + unsigned int nd_flags; + struct au_ndx ndx = { + .flags = 0, + .nd = args->nd + }; + const int allow_neg = au_ftest_lkup(args->flags, ALLOW_NEG); + + LKTRTrace("%.*s/%.*s, b%d, {flags 0x%x, type 0%o, nd %d}\n", + AuDLNPair(h_parent), AuDLNPair(dentry), bindex, + args->flags, args->type, !!args->nd); + if (args->nd) + LKTRTrace("nd{0x%x}\n", args->nd->flags); + AuDebugOn(IS_ROOT(dentry)); + h_dir = h_parent->d_inode; + + nd_flags = 0; + wh_found = 0; + sb = dentry->d_sb; + ndx.nfsmnt = au_nfsmnt(sb, bindex); + if (unlikely(au_ftest_lkup(args->flags, DLGT))) + au_fset_ndx(ndx.flags, DLGT); + if (unlikely(au_ftest_lkup(args->flags, DIRPERM1))) + au_fset_ndx(ndx.flags, DIRPERM1); + LKTRTrace("nfsmnt %p\n", ndx.nfsmnt); + ndx.br = au_sbr(sb, bindex); + wh_able = !!au_br_whable(ndx.br->br_perm); + name = &dentry->d_name; + if (unlikely(wh_able)) + wh_found = au_test_robr_wh(name, h_parent, wh_name, + /*try_sio*/0, &ndx); + h_dentry = ERR_PTR(wh_found); + if (!wh_found) + goto real_lookup; + if (unlikely(wh_found < 0)) + goto out; + + /* We found a whiteout */ + /* au_set_dbend(dentry, bindex); */ + au_set_dbwh(dentry, bindex); + if (!allow_neg) + return NULL; /* success */ + if (unlikely(ndx.nd + && au_test_nfs(h_parent->d_sb) + && (ndx.nd->flags & LOOKUP_CREATE))) { + nd_flags = ndx.nd->flags; + ndx.nd->flags &= ~(LOOKUP_OPEN | LOOKUP_CREATE); + } + + real_lookup: + /* do not superio. */ + h_dentry = au_lkup_one(name->name, h_parent, name->len, &ndx); + if (IS_ERR(h_dentry)) + goto out; + AuDebugOn(d_unhashed(h_dentry)); + h_inode = h_dentry->d_inode; + if (!h_inode) { + if (!allow_neg) + goto out_neg; + } else if (wh_found + || (args->type && args->type != (h_inode->i_mode & S_IFMT))) + goto out_neg; + + if (au_dbend(dentry) <= bindex) + au_set_dbend(dentry, bindex); + if (au_dbstart(dentry) < 0 || bindex < au_dbstart(dentry)) + au_set_dbstart(dentry, bindex); + au_set_h_dptr(dentry, bindex, h_dentry); + + err = au_br_nfs_h_intent(ndx.nd_file, dentry, bindex, args->nd); + if (unlikely(err)) { + h_dentry = ERR_PTR(err); + goto out; + } + + inode = dentry->d_inode; + if (!h_inode || !S_ISDIR(h_inode->i_mode) || !wh_able + || (inode && !S_ISDIR(inode->i_mode))) + goto out; /* success */ + + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + opq = au_diropq_test(h_dentry, &ndx); + mutex_unlock(&h_inode->i_mutex); + if (opq > 0) + au_set_dbdiropq(dentry, bindex); + else if (unlikely(opq < 0)) { + au_set_h_dptr(dentry, bindex, NULL); + h_dentry = ERR_PTR(opq); + } + goto out; + + out_neg: + dput(h_dentry); + h_dentry = NULL; + out: + if (unlikely(nd_flags)) + ndx.nd->flags |= (nd_flags & (LOOKUP_OPEN | LOOKUP_CREATE)); + AuTraceErrPtr(h_dentry); + return h_dentry; +} + +/* + * returns the number of hidden positive dentries, + * otherwise an error. + * can be called at unlinking with @type is zero. + */ +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t bstart, mode_t type, + struct nameidata *nd) +{ + int npositive, err; + unsigned int mnt_flags; + aufs_bindex_t bindex, btail, bdiropq; + unsigned char isdir; + struct qstr whname; + struct au_do_lookup_args args = { + .type = type, + .nd = nd + }; + const struct qstr *name = &dentry->d_name; + struct dentry *parent; + struct super_block *sb; + struct inode *inode; + + LKTRTrace("%.*s, b%d, type 0%o\n", AuLNPair(name), bstart, type); + AuDebugOn(bstart < 0 || IS_ROOT(dentry)); + + /* dir may not be locked */ + parent = dget_parent(dentry); + + err = au_test_robr_shwh(dentry->d_sb, name); + if (unlikely(err)) + goto out; + + err = au_wh_name_alloc(name->name, name->len, &whname); + if (unlikely(err)) + goto out; + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + inode = dentry->d_inode; + isdir = !!(inode && S_ISDIR(inode->i_mode)); + args.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_lkup(args.flags, DLGT); + if (unlikely(au_test_dirperm1(mnt_flags))) + au_fset_lkup(args.flags, DIRPERM1); + if (!type) + au_fset_lkup(args.flags, ALLOW_NEG); + npositive = 0; + btail = au_dbtaildir(parent); + for (bindex = bstart; bindex <= btail; bindex++) { + struct dentry *h_parent, *h_dentry; + struct inode *h_inode, *h_dir; + + h_dentry = au_h_dptr(dentry, bindex); + if (h_dentry) { + if (h_dentry->d_inode) + npositive++; + if (type != S_IFDIR) + break; + continue; + } + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir || !S_ISDIR(h_dir->i_mode)) + continue; + + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + h_dentry = au_do_lookup(h_parent, dentry, bindex, &whname, + &args); + mutex_unlock(&h_dir->i_mutex); + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out_wh; + au_fclr_lkup(args.flags, ALLOW_NEG); + + if (au_dbwh(dentry) >= 0) + break; + if (!h_dentry) + continue; + h_inode = h_dentry->d_inode; + if (!h_inode) + continue; + npositive++; + if (!args.type) + args.type = h_inode->i_mode & S_IFMT; + if (args.type != S_IFDIR) + break; + else if (isdir) { + /* the type of lowers may be different */ + bdiropq = au_dbdiropq(dentry); + if (bdiropq >= 0 && bdiropq <= bindex) + break; + } + } + + if (npositive) { + LKTRLabel(positive); + au_update_dbstart(dentry); + } + err = npositive; + if (unlikely(!au_opt_test(mnt_flags, UDBA_NONE) + && au_dbstart(dentry) < 0)) + /* both of real entry and whiteout found */ + err = -EIO; + + out_wh: + au_wh_name_free(&whname); + out: + dput(parent); + AuTraceErr(err); + return err; +} + +struct dentry *au_sio_lkup_one(const char *name, struct dentry *parent, int len, + struct au_ndx *ndx) +{ + struct dentry *dentry; + int wkq_err; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name); + + if (!au_test_h_perm_sio(parent->d_inode, MAY_EXEC, + au_ftest_ndx(ndx->flags, DLGT))) + dentry = au_lkup_one(name, parent, len, ndx); + else { + /* todo: ugly? */ + unsigned int flags = ndx->flags; + struct au_lkup_one_args args = { + .errp = &dentry, + .name = name, + .parent = parent, + .len = len, + .ndx = ndx + }; + + au_fclr_ndx(ndx->flags, DLGT); + au_fclr_ndx(ndx->flags, DIRPERM1); + wkq_err = au_wkq_wait(au_call_lkup_one, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + dentry = ERR_PTR(wkq_err); + ndx->flags = flags; + } + + AuTraceErrPtr(dentry); + return dentry; +} + +/* + * lookup @dentry on @bindex which should be negative. + */ +int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex) +{ + int err; + struct dentry *parent, *h_parent, *h_dentry; + struct inode *h_dir; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + struct super_block *sb; + unsigned int mnt_flags; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bindex); + /* dir may not be locked */ + parent = dget_parent(dentry); + AuDebugOn(!parent || !parent->d_inode + || !S_ISDIR(parent->d_inode->i_mode)); + h_parent = au_h_dptr(parent, bindex); + AuDebugOn(!h_parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir || !S_ISDIR(h_dir->i_mode)); + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + ndx.nfsmnt = au_nfsmnt(sb, bindex); + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + if (unlikely(au_test_dirperm1(mnt_flags))) + au_fset_ndx(ndx.flags, DIRPERM1); + h_dentry = au_sio_lkup_one(dentry->d_name.name, h_parent, + dentry->d_name.len, &ndx); + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out; + if (unlikely(h_dentry->d_inode)) { + err = -EIO; + AuIOErr("b%d %.*s should be negative.\n", + bindex, AuDLNPair(h_dentry)); + dput(h_dentry); + goto out; + } + + if (bindex < au_dbstart(dentry)) + au_set_dbstart(dentry, bindex); + if (au_dbend(dentry) < bindex) + au_set_dbend(dentry, bindex); + au_set_h_dptr(dentry, bindex, h_dentry); + err = 0; + + out: + dput(parent); + AuTraceErr(err); + return err; +} + +/* + * returns the number of found hidden positive dentries, + * otherwise an error. + */ +int au_refresh_hdentry(struct dentry *dentry, mode_t type) +{ + int npositive, new_sz; + struct au_dinfo *dinfo; + struct super_block *sb; + struct dentry *parent; + aufs_bindex_t bindex, parent_bend, parent_bstart, bwh, bdiropq, bend; + struct au_hdentry *p; + au_gen_t sgen; + + LKTRTrace("%.*s, type 0%o\n", AuDLNPair(dentry), type); + DiMustWriteLock(dentry); + sb = dentry->d_sb; + AuDebugOn(IS_ROOT(dentry)); + sgen = au_sigen(sb); + parent = dget_parent(dentry); + AuDebugOn(au_digen(parent) != sgen + || au_iigen(parent->d_inode) != sgen); + + npositive = -ENOMEM; + new_sz = sizeof(*dinfo->di_hdentry) * (au_sbend(sb) + 1); + dinfo = au_di(dentry); + p = au_kzrealloc(dinfo->di_hdentry, sizeof(*p) * (dinfo->di_bend + 1), + new_sz, GFP_NOFS); + if (unlikely(!p)) + goto out; + dinfo->di_hdentry = p; + + bend = dinfo->di_bend; + bwh = dinfo->di_bwh; + bdiropq = dinfo->di_bdiropq; + p += dinfo->di_bstart; + for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) { + struct dentry *hd, *hdp; + struct au_hdentry tmp, *q; + aufs_bindex_t new_bindex; + + hd = p->hd_dentry; + if (!hd) + continue; + hdp = dget_parent(hd); + if (hdp == au_h_dptr(parent, bindex)) { + dput(hdp); + continue; + } + + new_bindex = au_find_dbindex(parent, hdp); + dput(hdp); + AuDebugOn(new_bindex == bindex); + if (dinfo->di_bwh == bindex) + bwh = new_bindex; + if (dinfo->di_bdiropq == bindex) + bdiropq = new_bindex; + /* todo: test more? */ + if (new_bindex < 0) { + au_hdput(p, /*do_free*/0); + p->hd_dentry = NULL; + continue; + } + /* swap two hidden dentries, and loop again */ + q = dinfo->di_hdentry + new_bindex; + tmp = *q; + *q = *p; + *p = tmp; + if (tmp.hd_dentry) { + bindex--; + p--; + } + } + + /* todo: test more? */ + dinfo->di_bwh = -1; + if (unlikely(bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))) + dinfo->di_bwh = bwh; + dinfo->di_bdiropq = -1; + if (unlikely(bdiropq >= 0 && bdiropq <= au_sbend(sb) + && au_sbr_whable(sb, bdiropq))) + dinfo->di_bdiropq = bdiropq; + parent_bend = au_dbend(parent); + p = dinfo->di_hdentry; + for (bindex = 0; bindex <= parent_bend; bindex++, p++) + if (p->hd_dentry) { + dinfo->di_bstart = bindex; + break; + } + p = dinfo->di_hdentry + parent_bend; + for (bindex = parent_bend; bindex >= 0; bindex--, p--) + if (p->hd_dentry) { + dinfo->di_bend = bindex; + break; + } + + npositive = 0; + parent_bstart = au_dbstart(parent); + if (type != S_IFDIR && dinfo->di_bstart == parent_bstart) + goto out_dgen; /* success */ + + npositive = au_lkup_dentry(dentry, parent_bstart, type, /*nd*/NULL); + if (npositive < 0) + goto out; + if (unlikely(dinfo->di_bwh >= 0 && dinfo->di_bwh <= dinfo->di_bstart)) + d_drop(dentry); + + out_dgen: + au_update_digen(dentry); + out: + dput(parent); + AuTraceErr(npositive); + return npositive; +} + +static int au_lock_nd(struct dentry *dentry, struct nameidata *nd) +{ + int locked = 0; + if (nd && dentry != nd->path.dentry) { + di_read_lock_parent(nd->path.dentry, 0); + locked = 1; + } + return locked; +} + +static void au_unlock_nd(int locked, struct nameidata *nd) +{ + if (locked) + di_read_unlock(nd->path.dentry, 0); +} + +/* #define TestingFuse */ +static noinline_for_stack +int au_do_h_d_reval(struct dentry *dentry, aufs_bindex_t bindex, + struct nameidata *nd, struct dentry *h_dentry) +{ + int err, valid, e; + int (*reval)(struct dentry *, struct nameidata *); + struct super_block *sb; + struct nameidata fake_nd, *p; + + LKTRTrace("%.*s, b%d, nd %d\n", AuDLNPair(dentry), bindex, !!nd); + + err = 0; + reval = NULL; + if (h_dentry->d_op) + reval = h_dentry->d_op->d_revalidate; + if (!reval) + goto out; + + sb = dentry->d_sb; + if (nd) { + memcpy(&fake_nd, nd, sizeof(*nd)); + err = au_fake_intent(&fake_nd, au_sbr_perm(sb, bindex)); + if (unlikely(err)) { + err = -EINVAL; + goto out; + } + } + p = au_fake_dm(&fake_nd, nd, sb, bindex); + AuDebugOn(IS_ERR(p)); + AuDebugOn(nd && p != &fake_nd); + LKTRTrace("b%d\n", bindex); + + /* it may return tri-state */ +#if 1 + valid = reval(h_dentry, p); +#else + if (p /*&& !IS_ROOT(h_dentry)*/) { + struct dentry *h_parent = dget_parent(h_dentry); + struct mutex *h_mtx = &h_parent->d_inode->i_mutex; +#if 0 + lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(p->path.dentry); + AuDbgDentry(h_dentry); + lktr_clear_pid(current->pid, LktrArrayPid); +#endif + mutex_lock_nested(h_mtx, AuLsc_I_PARENT); + valid = reval(h_dentry, p); + mutex_unlock(h_mtx); + dput(h_parent); + } else + valid = reval(h_dentry, p); +#endif + if (unlikely(valid < 0)) + err = valid; + else if (!valid) + err = -EINVAL; + else + AuDebugOn(err); + + if (p) { + AuDebugOn(!nd); + e = au_hin_after_reval(p, dentry, bindex, nd->intent.open.file); +#ifndef TestingFuse + au_update_fuse_h_inode(p->path.mnt, h_dentry); /*ignore*/ +#endif + if (unlikely(e && !err)) + err = e; + } +#ifndef TestingFuse + else + au_update_fuse_h_inode(NULL, h_dentry); /*ignore*/ +#endif + au_fake_dm_release(p); + + out: + AuTraceErr(err); + return err; +} + +static noinline_for_stack +int h_d_revalidate(struct dentry *dentry, struct inode *inode, + struct nameidata *nd, int do_udba) +{ + int err; + aufs_bindex_t bindex, btail, bstart, ibs, ibe; + unsigned char plus, locked, unhashed, is_root, h_plus; + struct super_block *sb; + struct inode *first, *h_inode, *h_cached_inode; + umode_t mode, h_mode; + struct dentry *h_dentry; + struct qstr *name; + + LKTRTrace("%.*s, nd %d\n", AuDLNPair(dentry), !!nd); + AuDebugOn(inode && au_digen(dentry) != au_iigen(inode)); + + err = 0; + sb = dentry->d_sb; + plus = 0; + mode = 0; + first = NULL; + ibs = -1; + ibe = -1; + unhashed = !!d_unhashed(dentry); + is_root = !!IS_ROOT(dentry); + name = &dentry->d_name; + + /* + * Theoretically, REVAL test should be unnecessary in case of INOTIFY. + * But inotify doesn't fire some necessary events, + * IN_ATTRIB for atime/nlink/pageio + * IN_DELETE for NFS dentry + * Let's do REVAL test too. + */ + if (do_udba && inode) { + mode = (inode->i_mode & S_IFMT); + plus = (inode->i_nlink > 0); + first = au_h_iptr(inode, au_ibstart(inode)); + ibs = au_ibstart(inode); + ibe = au_ibend(inode); + } + + bstart = au_dbstart(dentry); + btail = bstart; + if (inode && S_ISDIR(inode->i_mode)) + btail = au_dbtaildir(dentry); + locked = !!au_lock_nd(dentry, nd); + for (bindex = bstart; bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + + LKTRTrace("b%d, %.*s\n", bindex, AuDLNPair(h_dentry)); +#ifdef TestingFuse + /* force re-lookup for fuse, in order to update attributes */ + if (unlikely(au_test_fuse(h_dentry->d_sb))) + goto err; +#endif + + if (unlikely(do_udba + && !is_root + && (unhashed != !!d_unhashed(h_dentry) + || name->len != h_dentry->d_name.len + || memcmp(name->name, h_dentry->d_name.name, + name->len) + ))) { + LKTRTrace("unhash 0x%x 0x%x, %.*s %.*s\n", + unhashed, d_unhashed(h_dentry), + AuDLNPair(dentry), AuDLNPair(h_dentry)); + goto err; + } + + err = au_do_h_d_reval(dentry, bindex, nd, h_dentry); + if (unlikely(err)) + /* do not goto err, to keep the errno */ + break; + + /* todo: plink too? */ + if (unlikely(!do_udba)) + continue; + + /* UDBA tests */ + h_inode = h_dentry->d_inode; + if (unlikely(!!inode != !!h_inode)) + goto err; + + h_plus = plus; + h_mode = mode; + h_cached_inode = h_inode; + if (h_inode) { + h_mode = (h_inode->i_mode & S_IFMT); + h_plus = (h_inode->i_nlink > 0); + } + if (inode && ibs <= bindex && bindex <= ibe) + h_cached_inode = au_h_iptr(inode, bindex); + + LKTRTrace("{%d, 0%o, %p}, h{%d, 0%o, %p}\n", + plus, mode, h_cached_inode, + h_plus, h_mode, h_inode); + if (unlikely(plus != h_plus + || mode != h_mode + || h_cached_inode != h_inode)) + goto err; + continue; + + err: + err = -EINVAL; + break; + } + au_unlock_nd(locked, nd); + + /* + * judging by timestamps is meaningless since some filesystem uses + * CURRENT_TIME_SEC instead of CURRENT_TIME. + */ + /* + * NFS may stop IN_DELETE because of DCACHE_NFSFS_RENAMED. + */ + + AuTraceErr(err); + return err; +} + +static int simple_reval_dpath(struct dentry *dentry, au_gen_t sgen) +{ + int err; + mode_t type; + struct dentry *parent; + struct inode *inode; + + LKTRTrace("%.*s, sgen %d\n", AuDLNPair(dentry), sgen); + SiMustAnyLock(dentry->d_sb); + DiMustWriteLock(dentry); + inode = dentry->d_inode; + AuDebugOn(!inode); + + if (au_digen(dentry) == sgen && au_iigen(inode) == sgen) + return 0; + + parent = dget_parent(dentry); + di_read_lock_parent(parent, AuLock_IR); + AuDebugOn(au_digen(parent) != sgen + || au_iigen(parent->d_inode) != sgen); +#ifdef CONFIG_AUFS_DEBUG + { + int i, j; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + + err = au_dpages_init(&dpages, GFP_NOFS); + AuDebugOn(err); + err = au_dcsub_pages_rev(&dpages, parent, /*do_include*/1, NULL, + NULL); + AuDebugOn(err); + for (i = dpages.ndpage - 1; !err && i >= 0; i--) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + for (j = dpage->ndentry - 1; !err && j >= 0; j--) + AuDebugOn(au_digen(dentries[j]) != sgen); + } + au_dpages_free(&dpages); + } +#endif + type = (inode->i_mode & S_IFMT); + /* returns a number of positive dentries */ + err = au_refresh_hdentry(dentry, type); + if (err >= 0) + err = au_refresh_hinode(inode, dentry); + di_read_unlock(parent, AuLock_IR); + dput(parent); + AuTraceErr(err); + return err; +} + +int au_reval_dpath(struct dentry *dentry, au_gen_t sgen) +{ + int err; + struct dentry *d, *parent; + struct inode *inode; + + LKTRTrace("%.*s, sgen %d\n", AuDLNPair(dentry), sgen); + AuDebugOn(!dentry->d_inode); + DiMustWriteLock(dentry); + + if (!au_ftest_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS)) + return simple_reval_dpath(dentry, sgen); + + /* slow loop, keep it simple and stupid */ + /* cf: au_cpup_dirs() */ + err = 0; + parent = NULL; + while (au_digen(dentry) != sgen || au_iigen(dentry->d_inode) != sgen) { + d = dentry; + while (1) { + dput(parent); + parent = dget_parent(d); + if (au_digen(parent) == sgen + && au_iigen(parent->d_inode) == sgen) + break; + d = parent; + } + + inode = d->d_inode; + if (d != dentry) + di_write_lock_child(d); + + /* someone might update our dentry while we were sleeping */ + if (au_digen(d) != sgen || au_iigen(d->d_inode) != sgen) { + di_read_lock_parent(parent, AuLock_IR); + /* returns a number of positive dentries */ + err = au_refresh_hdentry(d, inode->i_mode & S_IFMT); + if (err >= 0) + err = au_refresh_hinode(inode, d); + di_read_unlock(parent, AuLock_IR); + } + + if (d != dentry) + di_write_unlock(d); + dput(parent); + if (unlikely(err)) + break; + } + + AuTraceErr(err); + return err; +} + +/* + * THIS IS A BOOLEAN FUNCTION: returns 1 if valid, 0 otherwise. + * nfsd passes NULL as nameidata. + */ +static int aufs_d_revalidate(struct dentry *dentry, struct nameidata *nd) +{ + int valid, err; + au_gen_t sgen; + unsigned char do_udba; + struct nameidata tmp_nd, *ndp; + struct super_block *sb; + struct inode *inode; + + LKTRTrace("dentry %.*s\n", AuDLNPair(dentry)); + if (nd && nd->path.dentry) + LKTRTrace("nd{%.*s, 0x%x}\n", + AuDLNPair(nd->path.dentry), nd->flags); + /* + * dir case: AuDebugOn(dentry->d_parent != nd->dentry); + * remove failure case:AuDebugOn(!IS_ROOT(dentry) + * && d_unhashed(dentry)); + */ + AuDebugOn(!dentry->d_fsdata); + + err = -EINVAL; +#if 0 + if (d_unhashed(dentry)) + goto __out; +#endif + sb = dentry->d_sb; +#if 1 + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_DW); + inode = dentry->d_inode; +#else + si_read_lock(sb, AuLock_FLUSH); + //lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(dentry); + AuDbgInode(dentry->d_inode); + au_rw_write_lock_nested(&au_di(dentry)->di_rwsem, AuLsc_DI_CHILD); + LKTRLabel(clean); + //lktr_clear_pid(current->pid, LktrArrayPid); + inode = dentry->d_inode; + if (unlikely(inode && (!inode->i_nlink || IS_DEADDIR(inode)))) { + AuDbg("here\n"); + au_rw_write_unlock(&au_di(dentry)->di_rwsem); + si_read_unlock(sb); + goto __out; + } + if (inode) { + //lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(dentry); + AuDbgInode(inode); + ii_write_lock_child(inode); + LKTRLabel(clean); + //lktr_clear_pid(current->pid, LktrArrayPid); + } +#endif + + sgen = au_sigen(sb); + if (unlikely(au_digen(dentry) != sgen)) { + AuDebugOn(IS_ROOT(dentry)); +#ifdef ForceInotify + AuDbg("UDBA or digen, %.*s\n", AuDLNPair(dentry)); +#endif + if (inode) + err = au_reval_dpath(dentry, sgen); + if (unlikely(err)) + goto out_dgrade; + AuDebugOn(au_digen(dentry) != sgen); + } + if (unlikely(inode && au_iigen(inode) != sgen)) { + AuDebugOn(IS_ROOT(dentry)); +#ifdef ForceInotify + AuDbg("UDBA or survived, %.*s\n", AuDLNPair(dentry)); +#endif + err = au_refresh_hinode(inode, dentry); + if (unlikely(err)) + goto out_dgrade; + AuDebugOn(au_iigen(inode) != sgen); + } + di_downgrade_lock(dentry, AuLock_IR); + +#if 0 /* todo: support it? */ + /* parent dir i_nlink is not updated in the case of setattr */ + if (S_ISDIR(inode->i_mode)) { + mutex_lock(&inode->i_mutex); + ii_write_lock(inode); + au_cpup_attr_nlink(inode); + ii_write_unlock(inode); + mutex_unlock(&inode->i_mutex); + } +#endif + + AuDebugOn(au_digen(dentry) != sgen); + AuDebugOn(inode && au_iigen(inode) != sgen); + err = -EINVAL; + do_udba = !au_opt_test(au_mntflags(sb), UDBA_NONE); + if (do_udba && inode) { + aufs_bindex_t bstart = au_ibstart(inode); + if (bstart >= 0 + && au_test_higen(inode, au_h_iptr(inode, bstart))) + goto out; + } + ndp = au_dup_nd(au_sbi(sb), &tmp_nd, nd); +#if 0 + if (nd) { + path = nd->path; + nd->path.dentry = au_h_dptr(nd->path.dentry, bindex); + if (fake_nd->path.dentry) { + fake_nd->path.mnt = au_sbr_mnt(sb, bindex); + AuDebugOn(!fake_nd->path.mnt); + path_get(&fake_nd->path); + nd->path. + } + } +#endif + err = h_d_revalidate(dentry, inode, ndp, do_udba); + if (unlikely(!err && do_udba && au_dbstart(dentry) < 0)) + /* both of real entry and whiteout found */ + err = -EIO; + goto out; + + out_dgrade: + di_downgrade_lock(dentry, AuLock_IR); + out: + au_store_fmode_exec(nd, inode); + + aufs_read_unlock(dentry, AuLock_IR); + //__out: + AuTraceErr(err); + valid = !err; + if (!valid) + LKTRTrace("%.*s invalid\n", AuDLNPair(dentry)); + return valid; +} + +static void aufs_d_release(struct dentry *dentry) +{ + struct au_dinfo *dinfo; + aufs_bindex_t bend, bindex; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(!d_unhashed(dentry)); + + dinfo = dentry->d_fsdata; + if (unlikely(!dinfo)) + return; + + /* dentry may not be revalidated */ + bindex = dinfo->di_bstart; + if (bindex >= 0) { + struct au_hdentry *p; + bend = dinfo->di_bend; + AuDebugOn(bend < bindex); + p = dinfo->di_hdentry + bindex; + while (bindex++ <= bend) { + if (p->hd_dentry) + au_hdput(p, /*do_free*/1); + p++; + } + } + kfree(dinfo->di_hdentry); + au_cache_free_dinfo(dinfo); + au_hin_di_reinit(dentry); + /* todo: tmp code */ + //dentry->d_fsdata = NULL; +} + +struct dentry_operations aufs_dop = { + .d_revalidate = aufs_d_revalidate, + .d_release = aufs_d_release, + /* never use d_delete, especially in case of nfs server */ +}; --- linux-2.6.28.orig/ubuntu/aufs/sbinfo.c +++ linux-2.6.28/ubuntu/aufs/sbinfo.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * superblock private data + * + * $Id: sbinfo.c,v 1.11 2008/07/27 22:49:36 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* + * they are necessary regardless sysfs is disabled. + */ +void au_si_free(struct kobject *kobj) +{ + struct au_sbinfo *sbinfo; + struct super_block *sb; + + LKTRTrace("kobj %p\n", kobj); + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + LKTRTrace("sbinfo %p\n", sbinfo); + AuDebugOn(!list_empty(&sbinfo->si_plink)); + + sb = sbinfo->si_sb; + si_write_lock(sb); + au_xino_clr(sb); + au_br_free(sbinfo); + kfree(sbinfo->si_branch); + au_export_put(sbinfo); + si_write_unlock(sb); + + kfree(sbinfo); +} + +int au_si_alloc(struct super_block *sb) +{ + int err; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + + err = -ENOMEM; + sbinfo = kmalloc(sizeof(*sbinfo), GFP_NOFS); + if (unlikely(!sbinfo)) + goto out; + sbinfo->si_branch = kzalloc(sizeof(*sbinfo->si_branch), GFP_NOFS); + if (unlikely(!sbinfo->si_branch)) + goto out_sbinfo; + + memset(&sbinfo->si_kobj, 0, sizeof(sbinfo->si_kobj)); + err = sysaufs_si_init(sbinfo); + if (unlikely(err)) + goto out_br; + + au_rw_init_wlock(&sbinfo->si_rwsem); + sbinfo->si_generation = 0; + sbinfo->au_si_status = 0; + sbinfo->si_bend = -1; + sbinfo->si_last_br_id = 0; + + sbinfo->si_wbr_copyup = AuWbrCopyup_Def; + sbinfo->si_wbr_create = AuWbrCreate_Def; + sbinfo->si_wbr_copyup_ops = au_wbr_copyup_ops + AuWbrCopyup_Def; + sbinfo->si_wbr_create_ops = au_wbr_create_ops + AuWbrCreate_Def; + + sbinfo->si_mntflags = AuOpt_Def; + + sbinfo->si_xread = NULL; + sbinfo->si_xwrite = NULL; + sbinfo->si_xib = NULL; + mutex_init(&sbinfo->si_xib_mtx); + sbinfo->si_xib_buf = NULL; + au_xino_def_br_set(NULL, sbinfo); + /* leave si_xib_last_pindex and si_xib_next_bit */ + + au_nwt_init(&sbinfo->si_nowait); + + sbinfo->si_rdcache = AUFS_RDCACHE_DEF * HZ; + sbinfo->si_dirwh = AUFS_DIRWH_DEF; + + spin_lock_init(&sbinfo->si_plink_lock); + INIT_LIST_HEAD(&sbinfo->si_plink); + + au_robr_lvma_init(sbinfo); + + /* leave other members for sysaufs and si_mnt. */ + sbinfo->si_sb = sb; + + sb->s_fs_info = sbinfo; + + au_debug_sbinfo_init(sbinfo); + return 0; /* success */ + + out_br: + kfree(sbinfo->si_branch); + out_sbinfo: + kfree(sbinfo); + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct au_branch *au_sbr(struct super_block *sb, aufs_bindex_t bindex) +{ + struct au_branch *br; + + SiMustAnyLock(sb); + AuDebugOn(bindex < 0 || au_sbend(sb) < bindex); + br = au_sbi(sb)->si_branch[0 + bindex]; + AuDebugOn(!br); + return br; +} + +au_gen_t au_sigen_inc(struct super_block *sb) +{ + au_gen_t gen; + + SiMustWriteLock(sb); + gen = ++au_sbi(sb)->si_generation; + au_update_digen(sb->s_root); + au_update_iigen(sb->s_root->d_inode); + sb->s_root->d_inode->i_version++; + return gen; +} + +int au_find_bindex(struct super_block *sb, struct au_branch *br) +{ + aufs_bindex_t bindex, bend; + + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) + if (au_sbr(sb, bindex) == br) + return bindex; + return -1; +} + +/* ---------------------------------------------------------------------- */ + +/* dentry and super_block lock. call at entry point */ +void aufs_read_lock(struct dentry *dentry, int flags) +{ + si_read_lock(dentry->d_sb, flags); + if (au_ftest_lock(flags, DW)) + di_write_lock_child(dentry); + else + di_read_lock_child(dentry, flags); +} + +void aufs_read_unlock(struct dentry *dentry, int flags) +{ + if (au_ftest_lock(flags, DW)) + di_write_unlock(dentry); + else + di_read_unlock(dentry, flags); + si_read_unlock(dentry->d_sb); +} + +void aufs_write_lock(struct dentry *dentry) +{ + si_write_lock(dentry->d_sb); + di_write_lock_child(dentry); +} + +void aufs_write_unlock(struct dentry *dentry) +{ + di_write_unlock(dentry); + si_write_unlock(dentry->d_sb); +} + +void aufs_read_and_write_lock2(struct dentry *d1, struct dentry *d2, int flags) +{ + AuDebugOn(d1 == d2 || d1->d_sb != d2->d_sb); + si_read_lock(d1->d_sb, flags); + di_write_lock2_child(d1, d2, au_ftest_lock(flags, DIR)); +} + +void aufs_read_and_write_unlock2(struct dentry *d1, struct dentry *d2) +{ + AuDebugOn(d1 == d2 || d1->d_sb != d2->d_sb); + di_write_unlock2(d1, d2); + si_read_unlock(d1->d_sb); +} + +/* ---------------------------------------------------------------------- */ + +aufs_bindex_t au_new_br_id(struct super_block *sb) +{ + aufs_bindex_t br_id; + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + while (1) { + br_id = ++sbinfo->si_last_br_id; + if (br_id && au_br_index(sb, br_id) < 0) + return br_id; + } +} --- linux-2.6.28.orig/ubuntu/aufs/inode.h +++ linux-2.6.28/ubuntu/aufs/inode.h @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations + * + * $Id: inode.h,v 1.13 2008/09/15 03:14:44 sfjro Exp $ + */ + +#ifndef __AUFS_INODE_H__ +#define __AUFS_INODE_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include "hinode.h" +#include "misc.h" +#include "super.h" + +struct au_hinode; +struct au_vdir; +struct au_iinfo { + atomic_t ii_generation; + struct super_block *ii_hsb1; /* no get/put */ + + struct au_rwsem ii_rwsem; + aufs_bindex_t ii_bstart, ii_bend; + __u32 ii_higen; + struct au_hinode *ii_hinode; + struct au_vdir *ii_vdir; +}; + +struct aufs_icntnr { + struct au_iinfo iinfo; + struct inode vfs_inode; +}; + +struct au_pin1 { + /* input */ + struct dentry *dentry; + unsigned char di_locked, lsc_di, lsc_hi; + /* auto */ + unsigned char do_verify; + + /* output */ + struct dentry *parent; + struct inode *h_dir; +}; + +enum {AuPin_PARENT, AuPin_GPARENT}; +struct au_pin { +#ifdef CONFIG_AUFS_HINOTIFY + struct au_pin1 pin[2]; +#else + struct au_pin1 pin[1]; /* no grand parent */ +#endif +}; + +/* ---------------------------------------------------------------------- */ + +/* inode.c */ +int au_refresh_hinode_self(struct inode *inode); +int au_refresh_hinode(struct inode *inode, struct dentry *dentry); +struct inode *au_new_inode(struct dentry *dentry); +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode); +int au_test_h_perm(struct inode *h_inode, int mask, int dlgt); +int au_test_h_perm_sio(struct inode *h_inode, int mask, int dlgt); + +/* i_op.c */ +extern struct inode_operations aufs_iop, aufs_symlink_iop, aufs_dir_iop; + +/* au_wr_dir flags */ +#define AuWrDir_ADD_ENTRY 1 +#define AuWrDir_ISDIR (1 << 1) +#define au_ftest_wrdir(flags, name) ((flags) & AuWrDir_##name) +#define au_fset_wrdir(flags, name) { (flags) |= AuWrDir_##name; } +#define au_fclr_wrdir(flags, name) { (flags) &= ~AuWrDir_##name; } + +struct au_wr_dir_args { + aufs_bindex_t force_btgt; + unsigned char flags; +}; +int au_wr_dir(struct dentry *dentry, struct dentry *src_dentry, + struct au_wr_dir_args *args); + +void au_pin_init(struct au_pin *args, struct dentry *dentry, int di_locked, + int lsc_di, int lsc_hi, int do_gp); +int au_pin(struct au_pin *args, struct dentry *dentry, aufs_bindex_t bindex, + int di_locked, int do_gp) __must_check; +int au_do_pin(struct au_pin1 *p, struct au_pin1 *gp, const aufs_bindex_t bindex, + const int do_gp) __must_check; +void au_do_unpin(struct au_pin1 *p, struct au_pin1 *gp); + +/* i_op_add.c */ +struct au_ndx; +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx); +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname); +int aufs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd); +int aufs_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry); +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode); + +/* i_op_del.c */ +int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup); +int au_may_del(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx); +int aufs_unlink(struct inode *dir, struct dentry *dentry); +int aufs_rmdir(struct inode *dir, struct dentry *dentry); + +/* i_op_ren.c */ +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt); +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry); + +#ifdef CONFIG_AUFS_DLGT +/* dlgt.c */ +int au_security_inode_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int dlgt); +#else +static inline +int au_security_inode_permission(struct inode *h_inode, int mask, + struct nameidata *fake_nd, int dlgt) +{ + return vfsub_security_inode_permission(h_inode, mask, fake_nd); +} +#endif /* CONFIG_AUFS_DLGT */ + +#ifdef CONFIG_AUFS_HIN_OR_FUSE +/* hin_or_fuse.c */ +int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st); +#endif + +#if 0 /* reserved for future use */ +/* xattr.c */ +int aufs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t sz, int flags); +ssize_t aufs_getxattr(struct dentry *dentry, const char *name, void *value, + size_t sz); +ssize_t aufs_listxattr(struct dentry *dentry, char *list, size_t sz); +int aufs_removexattr(struct dentry *dentry, const char *name); +#endif + +/* iinfo.c */ +struct au_iinfo *au_ii(struct inode *inode); +struct inode *au_h_iptr(struct inode *inode, aufs_bindex_t bindex); +aufs_bindex_t au_ii_br_id(struct inode *inode, aufs_bindex_t bindex); + +void au_set_ibstart(struct inode *inode, aufs_bindex_t bindex); +void au_set_hi_wh(struct inode *inode, aufs_bindex_t bindex, + struct dentry *h_wh); +unsigned int au_hi_flags(struct inode *inode, int isdir); + +/* hinode flags */ +#define AuHi_XINO 1 +#define AuHi_NOTIFY (1 << 1) +#define au_ftest_hi(flags, name) ((flags) & AuHi_##name) +#define au_fset_hi(flags, name) { (flags) |= AuHi_##name; } +#define au_fclr_hi(flags, name) { (flags) &= ~AuHi_##name; } +#ifndef CONFIG_AUFS_HINOTIFY +#undef AuHi_NOTIFY +#define AuHi_NOTIFY 0 +#endif + +void au_set_h_iptr(struct inode *inode, aufs_bindex_t bindex, + struct inode *h_inode, unsigned int flags); + +void au_update_iigen(struct inode *inode); +void au_update_brange(struct inode *inode, int do_put_zero); + +int au_iinfo_init(struct inode *inode); +void au_iinfo_fin(struct inode *inode); + +/* plink.c */ +#ifdef CONFIG_AUFS_DEBUG +void au_plink_list(struct super_block *sb); +#else +static inline void au_plink_list(struct super_block *sb) +{ + /* nothing */ +} +#endif +int au_plink_test(struct super_block *sb, struct inode *inode); +struct dentry *au_plink_lkup(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode); +void au_plink_append(struct super_block *sb, struct inode *inode, + struct dentry *h_dentry, aufs_bindex_t bindex); +void au_plink_put(struct super_block *sb); +void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id); + +/* ---------------------------------------------------------------------- */ + +/* lock subclass for iinfo */ +enum { + AuLsc_II_CHILD, /* child first */ + AuLsc_II_CHILD2, /* rename(2), link(2), and cpup at hinotify */ + AuLsc_II_CHILD3, /* copyup dirs */ + AuLsc_II_PARENT, /* see AuLsc_I_PARENT in vfsub.h */ + AuLsc_II_PARENT2, + AuLsc_II_PARENT3, + AuLsc_II_PARENT4, + AuLsc_II_NEW_CHILD, +}; + +/* + * ii_read_lock_child, ii_write_lock_child, + * ii_read_lock_child2, ii_write_lock_child2, + * ii_read_lock_child3, ii_write_lock_child3, + * ii_read_lock_parent, ii_write_lock_parent, + * ii_read_lock_parent2, ii_write_lock_parent2, + * ii_read_lock_parent3, ii_write_lock_parent3, + * ii_read_lock_parent4, ii_write_lock_parent4, + * ii_read_lock_new_child, ii_write_lock_new_child, + */ +#define AuReadLockFunc(name, lsc) \ +static inline void ii_read_lock_##name(struct inode *i) \ +{ au_rw_read_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); } + +#define AuWriteLockFunc(name, lsc) \ +static inline void ii_write_lock_##name(struct inode *i) \ +{ au_rw_write_lock_nested(&au_ii(i)->ii_rwsem, AuLsc_II_##lsc); } + +#define AuRWLockFuncs(name, lsc) \ + AuReadLockFunc(name, lsc) \ + AuWriteLockFunc(name, lsc) + +AuRWLockFuncs(child, CHILD); +AuRWLockFuncs(child2, CHILD2); +AuRWLockFuncs(child3, CHILD3); +AuRWLockFuncs(parent, PARENT); +AuRWLockFuncs(parent2, PARENT2); +AuRWLockFuncs(parent3, PARENT3); +AuRWLockFuncs(parent4, PARENT4); +AuRWLockFuncs(new_child, NEW_CHILD); + +#undef AuReadLockFunc +#undef AuWriteLockFunc +#undef AuRWLockFuncs + +/* + * ii_read_unlock, ii_write_unlock, ii_downgrade_lock + */ +AuSimpleUnlockRwsemFuncs(ii, struct inode *i, au_ii(i)->ii_rwsem); + +/* to debug easier, do not make them inlined functions */ +#define IiMustReadLock(i) do { \ + SiMustAnyLock((i)->i_sb); \ + AuRwMustReadLock(&au_ii(i)->ii_rwsem); \ +} while (0) + +#define IiMustWriteLock(i) do { \ + SiMustAnyLock((i)->i_sb); \ + AuRwMustWriteLock(&au_ii(i)->ii_rwsem); \ +} while (0) + +#define IiMustAnyLock(i) do { \ + SiMustAnyLock((i)->i_sb); \ + AuRwMustAnyLock(&au_ii(i)->ii_rwsem); \ +} while (0) + +#define IiMustNoWaiters(i) AuRwMustNoWaiters(&au_ii(i)->ii_rwsem) + +/* ---------------------------------------------------------------------- */ + +static inline struct inode *au_igrab(struct inode *inode) +{ + if (inode) { + AuDebugOn(!atomic_read(&inode->i_count)); + atomic_inc_return(&inode->i_count); + } + return inode; +} + +/* ---------------------------------------------------------------------- */ + +static inline aufs_bindex_t au_ibstart(struct inode *inode) +{ + IiMustAnyLock(inode); + return au_ii(inode)->ii_bstart; +} + +static inline aufs_bindex_t au_ibend(struct inode *inode) +{ + IiMustAnyLock(inode); + return au_ii(inode)->ii_bend; +} + +static inline struct au_vdir *au_ivdir(struct inode *inode) +{ + IiMustAnyLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode)); + return au_ii(inode)->ii_vdir; +} + +static inline struct dentry *au_hi_wh(struct inode *inode, aufs_bindex_t bindex) +{ + struct au_hinode *hinode; + IiMustAnyLock(inode); + hinode = au_ii(inode)->ii_hinode + bindex; + return hinode->hi_whdentry; +} + +static inline void au_set_ibend(struct inode *inode, aufs_bindex_t bindex) +{ + IiMustWriteLock(inode); + AuDebugOn(au_sbend(inode->i_sb) < bindex || bindex < au_ibstart(inode)); + au_ii(inode)->ii_bend = bindex; +} + +static inline void au_set_ivdir(struct inode *inode, struct au_vdir *vdir) +{ + IiMustWriteLock(inode); + AuDebugOn(!S_ISDIR(inode->i_mode) || (au_ii(inode)->ii_vdir && vdir)); + au_ii(inode)->ii_vdir = vdir; +} + +static inline void au_hiput(struct au_hinode *hinode) +{ + au_hin_free(hinode); + dput(hinode->hi_whdentry); + iput(hinode->hi_inode); +} + +static inline struct au_hinode *au_hi(struct inode *inode, aufs_bindex_t bindex) +{ + /* todo: this lock check causes some unnecessary locks in callers. */ + IiMustAnyLock(inode); + return au_ii(inode)->ii_hinode + bindex; +} + +/* tiny test for inode number */ +/* tmpfs generation is too rough */ +static inline int au_test_higen(struct inode *inode, struct inode *h_inode) +{ + struct au_iinfo *iinfo; + + IiMustAnyLock(inode); + + iinfo = au_ii(inode); + return !(iinfo->ii_hsb1 == h_inode->i_sb + && iinfo->ii_higen == h_inode->i_generation); +} + +static inline au_gen_t au_iigen(struct inode *inode) +{ + return atomic_read(&au_ii(inode)->ii_generation); +} + +#ifdef CONFIG_AUFS_HINOTIFY +static inline au_gen_t au_iigen_dec(struct inode *inode) +{ + /* AuDbg("i%lu\n", inode->i_ino); */ + return atomic_dec_return(&au_ii(inode)->ii_generation); +} +#endif + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HINOTIFY +static inline struct au_pin1 *au_pin_gp(struct au_pin *args) +{ + return args->pin + AuPin_GPARENT; +} + +/* hinotify.c */ +void au_unpin_gp(struct au_pin *args); + +#else + +static inline struct au_pin1 *au_pin_gp(struct au_pin *args) +{ + return NULL; +} + +static inline void au_unpin_gp(struct au_pin *args) +{ + /* empty */ +} +#endif /* HINOTIFY */ + +static inline void au_unpin(struct au_pin *args) +{ + au_do_unpin(args->pin + AuPin_PARENT, au_pin_gp(args)); +} + +static inline +struct au_hinode *au_do_pinned_hdir(struct au_pin1 *pin, aufs_bindex_t bindex) +{ + if (pin && pin->parent) + return au_hi(pin->parent->d_inode, bindex); + return NULL; +} + +struct dentry *au_do_pinned_h_parent(struct au_pin1 *pin, aufs_bindex_t bindex); + +static inline struct dentry *au_do_pinned_parent(struct au_pin1 *pin) +{ + if (pin) + return pin->parent; + return NULL; +} + +static inline struct inode *au_do_pinned_h_dir(struct au_pin1 *pin) +{ + if (pin) + return pin->h_dir; + return NULL; +} + +static inline +void au_pin_do_set_dentry(struct au_pin1 *pin, struct dentry *dentry) +{ + if (pin) + pin->dentry = dentry; +} + +static inline +void au_pin_do_set_parent(struct au_pin1 *pin, struct dentry *parent) +{ + if (pin) { + dput(pin->parent); + pin->parent = dget(parent); + } +} + +static inline void au_pin_do_set_h_dir(struct au_pin1 *pin, struct inode *h_dir) +{ + if (pin) { + iput(pin->h_dir); + pin->h_dir = au_igrab(h_dir); + } +} + +static inline +void au_pin_do_set_parent_lflag(struct au_pin1 *pin, unsigned char lflag) +{ + if (pin) + pin->di_locked = lflag; +} + +static inline +struct au_hinode *au_pinned_hdir(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_hdir(args->pin + AuPin_PARENT, bindex); +} + +static inline +struct au_hinode *au_pinned_hgdir(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_hdir(au_pin_gp(args), bindex); +} + +static inline +struct dentry *au_pinned_h_parent(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_h_parent(args->pin + AuPin_PARENT, bindex); +} + +#if 0 /* reserved for future use */ +static inline +struct dentry *au_pinned_h_gparent(struct au_pin *args, aufs_bindex_t bindex) +{ + return au_do_pinned_h_parent(au_pin_gp(args), bindex); +} +#endif + +static inline +struct dentry *au_pinned_parent(struct au_pin *args) +{ + return au_do_pinned_parent(args->pin + AuPin_PARENT); +} + +static inline +struct dentry *au_pinned_gparent(struct au_pin *args) +{ + return au_do_pinned_parent(au_pin_gp(args)); +} + +static inline +struct inode *au_pinned_h_dir(struct au_pin *args) +{ + return au_do_pinned_h_dir(args->pin + AuPin_PARENT); +} + +static inline +struct inode *au_pinned_h_gdir(struct au_pin *args) +{ + return au_do_pinned_h_dir(au_pin_gp(args)); +} + +static inline void au_pin_set_parent(struct au_pin *args, struct dentry *d) +{ + au_pin_do_set_parent(args->pin + AuPin_PARENT, d); +} + +static inline void au_pin_set_gparent(struct au_pin *args, struct dentry *d) +{ + au_pin_do_set_parent(au_pin_gp(args), d); +} + +static inline void au_pin_set_h_dir(struct au_pin *args, struct inode *h_dir) +{ + au_pin_do_set_h_dir(args->pin + AuPin_PARENT, h_dir); +} + +static inline void au_pin_set_h_gdir(struct au_pin *args, struct inode *h_dir) +{ + au_pin_do_set_h_dir(au_pin_gp(args), h_dir); +} + +static inline +void au_pin_set_parent_lflag(struct au_pin *args, unsigned char lflag) +{ + au_pin_do_set_parent_lflag(args->pin + AuPin_PARENT, lflag); +} + +static inline +void au_pin_set_gparent_lflag(struct au_pin *args, unsigned char lflag) +{ + au_pin_do_set_parent_lflag(au_pin_gp(args), lflag); +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_INODE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/Kconfig +++ linux-2.6.28/ubuntu/aufs/Kconfig @@ -0,0 +1,265 @@ +config AUFS + tristate "Another unionfs" + help + Aufs is a stackable unification filesystem such as Unionfs, + which unifies several directories and provides a merged single + directory. + In the early days, aufs was entirely re-designed and + re-implemented Unionfs Version 1.x series. After many original + ideas, approaches and improvements, it becomes totally + different from Unionfs while keeping the basic features. + See Unionfs for the basic features. +if AUFS +comment "These options are for 2.6.27-3-generic" +choice + prompt "Maximum number of branches" + default AUFS_BRANCH_MAX_127 + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_127 + bool "127" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_511 + bool "511" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_1023 + bool "1023" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +config AUFS_BRANCH_MAX_32767 + bool "32767" + help + Specifies the maximum number of branches (or member directories) in a single aufs. The larger value consumes more system resources and has an impact to performance. +endchoice +config AUFS_STAT + bool "Use /fs/aufs/stat" + depends on SYSFS + help + Shows some statistic data via /fs/aufs/stat. + See detail in aufs.5. +comment "SYSFS and AUFS_STAT are disabled" + depends on SYSFS = n +config AUFS_HINOTIFY + bool "Use inotify to detect actions on a branch" + depends on INOTIFY + help + If you want to modify files on branches directly, eg. bypassing aufs, + and want aufs to detect the changes of them fully, then enable this + option and use 'udba=inotify' mount option. + It will have a negative impact to the performance. + See detail in aufs.5. +comment "INOTIFY and AUFS_HINOTIFY are disabled" + depends on INOTIFY = n +config AUFS_EXPORT + bool "NFS-exportable aufs" + depends on (AUFS = y && EXPORTFS = y) || (AUFS = m && EXPORTFS) + help + If you want to export your mounted aufs, then enable this + option. There are several requirements to export aufs. + See detail in aufs.5. +comment "EXPORTFS and AUFS_EXPORT are disabled" + depends on EXPORTFS = n +comment "AUFS_EXPORT is disabled since EXPORTFS is a module but AUFS" + depends on EXPORTFS = m && AUFS = y +config AUFS_INO_T_64 + bool + depends on 64BIT && !(ALPHA || S390) + default y +config AUFS_ROBR + bool "Aufs as an readonly branch of another aufs mount" + help + If you want make your aufs to be a part of another aufs, then + enable this option. In other words, you can specify your aufs + path in 'br:' mount option for another aufs, but cannot + specify 'rw' as the branch permission. + It will have a negative impact to the performance. + See detail in aufs.5. +config AUFS_DLGT + bool "Delegate the internal branch access the kernel thread" + help + If you want aufs to delegate + the internal access to the branches which is made by aufs, to + the kernel thread, in order to hide the access issued by your + application from your LSM or something or make your + application to be traced strictly by the task I/O accounting, + then enable this option and use 'dlgt' mount option. + It will have a negative impact to the performance. + See detail in aufs.5. +config AUFS_HIN_OR_DLGT + bool + depends on AUFS_HINOTIFY || AUFS_DLGT + default y + help + Automatic configuration for internal use. +config AUFS_SHWH + bool "Show whiteouts" + help + If you want to make the whiteouts in aufs visible, then enable + this option and specify 'shwh' mount option. Although it may + sounds like philosophy or something, but in technically it + simply shows the name of whiteout with keeping its behaviour. +config AUFS_RR_SQUASHFS + bool "Make squashfs branch RR (real readonly) by default" + default y + help + If you use squashfs or LZMA patched squashfs as an aufs branch + and want to set '=rr' to it by default, then enable this + configuration. + 'rr' stands for real readonly and it optimizes some aspects of + 'ro.' + See detail in aufs.5. +config AUFS_SEC_PERM_PATCH + bool "sec_perm-2.6.24.patch was applied or not" + depends on AUFS = m + depends on SECURITY + help + If you build aufs as a module and enabled CONFIG_SECURITY, + then you need to apply the patch + 'CVS_TREE/aufs/patch/sec_perm-2.6.24.patch' to your kernel + source, and enable this configuration. + The sec_perm-2.6.24.patch exports a kernel function + security_inode_permission() to modules. +comment "SECURITY and AUFS_SEC_PERM_PATCH are disabled" + depends on SECURITY = n +config AUFS_SPLICE_PATCH + bool "splice.patch for sendfile(2) and splice(2)" + help + If you use 'loopback mount' on a fs-image file, or use + splice(2) or sendfile(2) systemcall in aufs, then you need to + apply the patch 'CVS_TREE/aufs/patch/splice.patch' to your + kernel source, and enable this configuration. + The splice.patch makes the kernel function do_splice_to/from() + global and exports them to modules. +config AUFS_PUT_FILP_PATCH + bool "put_filp.patch for NFS branch" + depends on AUFS = m + depends on NFS_FS + help + If you build aufs as a module and use mounted NFS as an aufs + branch filesystem, then you need to apply the patch + 'CVS_TREE/aufs/patch/put_filp.patch' to your kernel source, + and enable this configuration. + The put_filp.patch exports a kernel function put_filp() to + modules. +comment "NFS_FS and AUFS_PUT_FILP_PATCH are disabled" + depends on NFS_FS = n +config AUFS_LHASH_PATCH + bool "lhash.patch for NFS branch" + depends on NFS_FS + help + If you use mounted NFS as an aufs branch filesystem, then you + need to apply the patch 'CVS_TREE/aufs/patch/lhash.patch' (or + lhash-2.6.22.patch for linux-2.6.22 and later) to your kernel + source, and enable this configuration. + The patch file makes the kernel function __lookup_hash() global + and exports it to modules. +comment "NFS_FS and AUFS_LHASH_PATCH are disabled" + depends on NFS_FS = n +config AUFS_BR_NFS + bool + depends on NFS_FS + default n if (!AUFS_LHASH_PATCH || !(AUFS = y || AUFS_PUT_FILP_PATCH)) + default y + help + Automatic configuration for internal use. + When aufs supports NFS branch, enabled automatically. +config AUFS_BR_XFS + bool + depends on XFS_FS + default y + help + Automatic configuration for internal use. + When aufs supports XFS branch, enabled automatically. +config AUFS_FSYNC_SUPER_PATCH + bool "fsync_super-2.6.xx.patch was applied or not" + depends on AUFS = m + help + If you build aufs as a module and want to flush everything for + branch filesystems which are not marked as 'rr' nor 'rr+wh' at + umount or remount time, then you need to apply the patch + 'CVS_TREE/aufs/patch/fsync_super-2.6.16.patch' or + '...-2.6.19.patch' to your kernel source, and enable this + configuration. + It may be helpful at shutdown time in case of your aufs is a + root filesystem. But this behaviour will not guarantee the + consistency of branch filesystems. To guarantee it, try the + approach described in the aufs manual, and do not forget + installing auplink script. + The fsync_super-2.6.xx.patch does nothing but exports a kernel + function fsync_super() to modules. +config AUFS_DENY_WRITE_ACCESS_PATCH + bool "deny_write_access.patch was applied or not" + depends on AUFS = m + help + A security enhancement to deny writing to a running executable + which exists on an aufs branch filesystem and executed through + aufs. If you applied + 'CVS_TREE/aufs/patch/deny_write_access.patch' to your kernel + and you are compiling aufs as a module, then enable this + option. + The write_deny_access.patch does nothing but export the + function. +config AUFS_WORKAROUND_FUSE + bool "Special handling for FUSE-based filesystem" + depends on FUSE_FS + help + A FUSE-based filesystem may not initialize its inode + attributes and the FUSE developer thinks the inode attributes + in a positive dentry which is returned by VFS lookup operation + are not reliable. + If you use a FUSE-based filesystem as an aufs branch, and it + customizes the inode attribute on it without overriding + fuse_lowlevel_ops.lookup, probably you need to enable this + configuration. + If you enable this configuration, aufs calls getattr operation + in every lookup and revalidate operation for the FUSE-based + filesystem branch. + It will have a negative impact to the performance even if you do + not use a FUSE-based filesystem branch. +config AUFS_HIN_OR_FUSE + bool + depends on AUFS_HINOTIFY || AUFS_WORKAROUND_FUSE + default y + help + Automatic configuration for internal use. +config AUFS_DEBUG + bool "Debug aufs" + default y + help + Enable this to compile aufs internal debug code. + It will have a negative impact to the performance. +config AUFS_MAGIC_SYSRQ + bool + depends on AUFS_DEBUG && MAGIC_SYSRQ + default y + help + Automatic configuration for internal use. + When aufs supports Magic SysRq, enabled automatically. +config AUFS_COMPAT + bool "Compatibility with Unionfs (obsolete)" + help + This makes aufs compatible with unionfs-style mount options and some + behaviours. + The dirs= mount option and =nfsro branch permission flag are always + interpreted as br: mount option and =ro flag respectively. The + 'debug', 'delete' and 'imap' mount options are ignored. + If you disable this option, you will get, + - aufs issues a warning about the ignored mount options + - the default branch permission flag is set. RW for the first branch, + and RO for the rests. + - the name of a internal file which represents the directory is + 'opaque', becomes '.wh..wh..opq' + - the 'diropq=w' mount option is set by default +config AUFS_UNIONFS22_PATCH + bool "Unionfs-2.2 or later patch is applied or not (obsolete)" + help + Unionfs version 2.2 (and later) patch introduces some changes in VFS layer which has an impact to aufs. If you have applied such patch to your kernel, you need to enable this configuration even if you disabled CONFIG_UNIONFS. +config AUFS_UNIONFS23_PATCH + bool "Unionfs-2.3 or later patch is applied or not (obsolete)" + select AUFS_SPLICE_PATCH + select AUFS_UNIONFS22_PATCH + help + Unionfs version 2.3 (and later) patch introduces some changes in VFS layer which has an impact to aufs. If you have applied such patch to your kernel, you need to enable this configuration even if you disabled CONFIG_UNIONFS. +endif --- linux-2.6.28.orig/ubuntu/aufs/sysaufs.c +++ linux-2.6.28/ubuntu/aufs/sysaufs.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sysfs interface and lifetime management + * they are necessary regardless sysfs is disabled. + * + * $Id: sysaufs.c,v 1.10 2008/09/15 03:14:55 sfjro Exp $ + */ + +#include +#include +#include +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +unsigned long au_si_mask; + +/* ---------------------------------------------------------------------- */ + +struct kset *au_kset; + +#define AuSbiAttr(_name) { \ + .attr = { .name = __stringify(_name), .mode = 0444 }, \ + .show = sysaufs_sbi_##_name, \ +} + +static struct au_sbi_attr au_sbi_attr_xino = AuSbiAttr(xino); +#ifdef CONFIG_AUFS_EXPORT +static struct au_sbi_attr au_sbi_attr_xigen = AuSbiAttr(xigen); +#endif +struct attribute *au_sbi_attrs[] = { + &au_sbi_attr_xino.attr, +#ifdef CONFIG_AUFS_EXPORT + &au_sbi_attr_xigen.attr, +#endif + NULL, +}; + +static struct sysfs_ops au_sbi_ops = { + .show = sysaufs_sbi_show +}; + +static struct kobj_type au_sbi_ktype = { + .release = au_si_free, + .sysfs_ops = &au_sbi_ops, + .default_attrs = au_sbi_attrs +}; + +/* ---------------------------------------------------------------------- */ + +int sysaufs_si_init(struct au_sbinfo *sbinfo) +{ + int err; + + sbinfo->si_kobj.kset = au_kset; + /* some people doesn't like to show a pointer in kernel */ + err = kobject_init_and_add(&sbinfo->si_kobj, &au_sbi_ktype, + NULL/*&au_kset->kobj*/, + SysaufsSb_PREFIX "%lx", + au_si_mask ^ (unsigned long)sbinfo); + AuTraceErr(err); + return err; +} + + +/* ---------------------------------------------------------------------- */ + +void sysaufs_fin(void) +{ + sysfs_remove_group(&au_kset->kobj, au_attr_group); + kset_unregister(au_kset); +} + +int __init sysaufs_init(void) +{ + int err; + + get_random_bytes(&au_si_mask, sizeof(au_si_mask)); + + au_kset = kset_create_and_add(AUFS_NAME, NULL, fs_kobj); + err = PTR_ERR(au_kset); + if (IS_ERR(au_kset)) + goto out; + err = sysfs_create_group(&au_kset->kobj, au_attr_group); + if (unlikely(err)) + kset_unregister(au_kset); + + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/br_xfs.c +++ linux-2.6.28/ubuntu/aufs/br_xfs.c @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * special handling inode attributes on XFS branch in linux-2.6.24 and later + * + * $Id: br_xfs.c,v 1.3 2008/07/07 01:12:38 sfjro Exp $ + */ + +#include "aufs.h" + +/* h_mnt can be NULL, is it safe? */ +dev_t au_h_rdev(struct inode *h_inode, struct vfsmount *h_mnt, + struct dentry *h_dentry) +{ + dev_t rdev; + int err; + struct kstat st; + + LKTRTrace("hi%lu\n", h_inode->i_ino); + if (h_dentry) + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + + rdev = h_inode->i_rdev; + if (!rdev || !au_test_xfs(h_inode->i_sb)) + goto out; + + rdev = 0; + if (!h_dentry) { + err = 0; + h_dentry = d_find_alias(h_inode); + if (unlikely(!h_dentry)) + goto failure; + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) { + h_dentry = NULL; + goto failure; + } + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + } else + dget(h_dentry); + + err = vfsub_getattr(h_mnt, h_dentry, &st, /*dlgt*/0); + dput(h_dentry); + if (!err) { + rdev = st.rdev; + goto out; /* success */ + } + + failure: + AuIOErr("failed rdev for XFS inode, hi%lu, %d\n", h_inode->i_ino, err); + out: + return rdev; +} --- linux-2.6.28.orig/ubuntu/aufs/debug.c +++ linux-2.6.28/ubuntu/aufs/debug.c @@ -0,0 +1,512 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * debug print functions + * + * $Id: debug.c,v 1.14 2008/09/22 03:52:03 sfjro Exp $ + */ + +#include "aufs.h" + +atomic_t au_cond = ATOMIC_INIT(0); + +char *au_plevel = KERN_DEBUG; +#define dpri(fmt, arg...) do { \ + if (LktrCond) \ + printk("%s" fmt, au_plevel, ##arg); \ +} while (0) + +/* ---------------------------------------------------------------------- */ + +void au_dpri_whlist(struct au_nhash *whlist) +{ + int i; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + + for (i = 0; i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry(tpos, pos, head, wh_hash) + dpri("b%d, %.*s, %d\n", + tpos->wh_bindex, + tpos->wh_str.len, tpos->wh_str.name, + tpos->wh_str.len); + } +} + +void au_dpri_vdir(struct au_vdir *vdir) +{ + int i; + union au_vdir_deblk_p p; + unsigned char *o; + + if (!vdir || IS_ERR(vdir)) { + dpri("err %ld\n", PTR_ERR(vdir)); + return; + } + + dpri("nblk %d, deblk %p, last{%d, %p}, ver %lu\n", + vdir->vd_nblk, vdir->vd_deblk, + vdir->vd_last.i, vdir->vd_last.p.p, vdir->vd_version); + for (i = 0; i < vdir->vd_nblk; i++) { + p.deblk = vdir->vd_deblk[i]; + o = p.p; + dpri("[%d]: %p\n", i, o); + } +} + +static int do_pri_inode(aufs_bindex_t bindex, struct inode *inode, + struct dentry *wh) +{ + char *n = NULL; + int l = 0, ntfy = 0; + + if (!inode || IS_ERR(inode)) { + dpri("i%d: err %ld\n", bindex, PTR_ERR(inode)); + return -1; + } + + /* the type of i_blocks depends upon CONFIG_LSF */ + BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) + && sizeof(inode->i_blocks) != sizeof(u64)); + if (wh) { + n = (void *)wh->d_name.name; + l = wh->d_name.len; + } + + ntfy = au_test_inotify(inode); + dpri("i%d: i%lu, %s, cnt %d, nl %u, 0%o, ntfy %d, sz %llu, blk %llu," + " ct %lld, np %lu, st 0x%lx, f 0x%x, g %x%s%.*s\n", + bindex, + inode->i_ino, inode->i_sb ? au_sbtype(inode->i_sb) : "??", + atomic_read(&inode->i_count), inode->i_nlink, inode->i_mode, + ntfy, + i_size_read(inode), (unsigned long long)inode->i_blocks, + (long long)timespec_to_ns(&inode->i_ctime) & 0x0ffff, + inode->i_mapping ? inode->i_mapping->nrpages : 0, + inode->i_state, inode->i_flags, inode->i_generation, + l ? ", wh " : "", l, n); + return 0; +} + +void au_dpri_inode(struct inode *inode) +{ + struct au_iinfo *iinfo; + aufs_bindex_t bindex; + int err; + + err = do_pri_inode(-1, inode, NULL); + if (err || !au_test_aufs(inode->i_sb)) + return; + + iinfo = au_ii(inode); + if (!iinfo) + return; + dpri("i-1: bstart %d, bend %d, gen %d\n", + iinfo->ii_bstart, iinfo->ii_bend, au_iigen(inode)); + if (iinfo->ii_bstart < 0) + return; + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++) + do_pri_inode(bindex, iinfo->ii_hinode[0 + bindex].hi_inode, + iinfo->ii_hinode[0 + bindex].hi_whdentry); +} + +static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry, + struct list_head *intent) +{ + struct dentry *wh = NULL; + + if (!dentry || IS_ERR(dentry)) { + dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); + return -1; + } + /* do not call dget_parent() here */ + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x, intent %d\n", + bindex, + AuDLNPair(dentry->d_parent), AuDLNPair(dentry), + dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", + atomic_read(&dentry->d_count), dentry->d_flags, !!intent); + if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { + struct au_iinfo *iinfo = au_ii(dentry->d_inode); + if (iinfo) + wh = iinfo->ii_hinode[0 + bindex].hi_whdentry; + } + do_pri_inode(bindex, dentry->d_inode, wh); + return 0; +} + +static struct list_head *au_dbg_h_intent(struct au_dinfo *dinfo, + aufs_bindex_t bindex) +{ +#ifdef CONFIG_AUFS_BR_NFS + return dinfo->di_hdentry[0 + bindex].hd_intent_list; +#else + return NULL; +#endif +} + +void au_dpri_dentry(struct dentry *dentry) +{ + struct au_dinfo *dinfo; + aufs_bindex_t bindex; + int err; + + err = do_pri_dentry(-1, dentry, NULL); + if (err || !au_test_aufs(dentry->d_sb)) + return; + + dinfo = au_di(dentry); + if (!dinfo) + return; + dpri("d-1: bstart %d, bend %d, bwh %d, bdiropq %d, gen %d\n", + dinfo->di_bstart, dinfo->di_bend, + dinfo->di_bwh, dinfo->di_bdiropq, au_digen(dentry)); + if (dinfo->di_bstart < 0) + return; + for (bindex = dinfo->di_bstart; bindex <= dinfo->di_bend; bindex++) + do_pri_dentry(bindex, dinfo->di_hdentry[0 + bindex].hd_dentry, + au_dbg_h_intent(dinfo, bindex)); +} + +static int do_pri_file(aufs_bindex_t bindex, struct file *file) +{ + char a[32]; + + if (!file || IS_ERR(file)) { + dpri("f%d: err %ld\n", bindex, PTR_ERR(file)); + return -1; + } + a[0] = 0; + if (bindex < 0 + && file->f_dentry + && au_test_aufs(file->f_dentry->d_sb) + && au_fi(file)) + snprintf(a, sizeof(a), ", mmapped %d", au_test_mmapped(file)); + dpri("f%d: mode 0x%x, flags 0%o, cnt %ld, pos %llu%s\n", + bindex, file->f_mode, file->f_flags, (long)file_count(file), + file->f_pos, a); + if (file->f_dentry) + do_pri_dentry(bindex, file->f_dentry, NULL); + return 0; +} + +void au_dpri_file(struct file *file) +{ + struct au_finfo *finfo; + aufs_bindex_t bindex; + int err; + + err = do_pri_file(-1, file); + if (err || !file->f_dentry || !au_test_aufs(file->f_dentry->d_sb)) + return; + + finfo = au_fi(file); + if (!finfo) + return; + if (finfo->fi_bstart < 0) + return; + for (bindex = finfo->fi_bstart; bindex <= finfo->fi_bend; bindex++) { + struct au_hfile *hf; + hf = finfo->fi_hfile + bindex; + do_pri_file(bindex, hf ? hf->hf_file : NULL); + } +} + +static int do_pri_br(aufs_bindex_t bindex, struct au_branch *br) +{ + struct vfsmount *mnt; + struct super_block *sb; + + if (!br || IS_ERR(br) + || !(mnt = br->br_mnt) || IS_ERR(mnt) + || !(sb = mnt->mnt_sb) || IS_ERR(sb)) { + dpri("s%d: err %ld\n", bindex, PTR_ERR(br)); + return -1; + } + + dpri("s%d: {perm 0x%x, cnt %d, wbr %p}, " + "%s, dev 0x%02x%02x, flags 0x%lx, cnt(BIAS) %d, active %d, " + "xino %d\n", + bindex, br->br_perm, au_br_count(br), br->br_wbr, + au_sbtype(sb), MAJOR(sb->s_dev), MINOR(sb->s_dev), + sb->s_flags, sb->s_count - S_BIAS, + atomic_read(&sb->s_active), !!br->br_xino.xi_file); + return 0; +} + +void au_dpri_sb(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + aufs_bindex_t bindex; + int err; + /* to reuduce stack size */ + struct { + struct vfsmount mnt; + struct au_branch fake; + } *a; + + /* this function can be called from magic sysrq */ + a = kzalloc(sizeof(*a), GFP_ATOMIC); + if (unlikely(!a)) { + dpri("no memory\n"); + return; + } + + a->mnt.mnt_sb = sb; + a->fake.br_perm = 0; + a->fake.br_mnt = &a->mnt; + a->fake.br_xino.xi_file = NULL; + atomic_set(&a->fake.br_count, 0); + smp_mb(); /* atomic_set */ + err = do_pri_br(-1, &a->fake); + kfree(a); + dpri("dev 0x%x\n", sb->s_dev); + if (err || !au_test_aufs(sb)) + return; + + sbinfo = au_sbi(sb); + if (!sbinfo) + return; + dpri("gen %u\n", sbinfo->si_generation); + for (bindex = 0; bindex <= sbinfo->si_bend; bindex++) + do_pri_br(bindex, sbinfo->si_branch[0 + bindex]); +} + +/* ---------------------------------------------------------------------- */ + +void au_dbg_sleep(int sec) +{ + static DECLARE_WAIT_QUEUE_HEAD(wq); + wait_event_timeout(wq, 0, sec * HZ); +} + +void au_dbg_sleep_jiffy(int jiffy) +{ + static DECLARE_WAIT_QUEUE_HEAD(wq); + wait_event_timeout(wq, 0, jiffy); +} + +void au_dbg_iattr(struct iattr *ia) +{ +#define AuBit(name) if (ia->ia_valid & ATTR_ ## name) dpri(#name "\n") + AuBit(MODE); + AuBit(UID); + AuBit(GID); + AuBit(SIZE); + AuBit(ATIME); + AuBit(MTIME); + AuBit(CTIME); + AuBit(ATIME_SET); + AuBit(MTIME_SET); + AuBit(FORCE); + AuBit(ATTR_FLAG); + AuBit(KILL_SUID); + AuBit(KILL_SGID); + AuBit(FILE); + AuBit(KILL_PRIV); + AuBit(OPEN); + AuBit(TIMES_SET); +#undef AuBit + dpri("ia_file %p\n", ia->ia_file); +} + +/* ---------------------------------------------------------------------- */ + +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo) +{ +#ifdef ForceInotify + au_opt_set_udba(sbinfo->si_mntflags, UDBA_INOTIFY); +#endif +#ifdef ForceDlgt + au_opt_set(sbinfo->si_mntflags, DLGT); +#endif +#ifdef ForceNoPlink + au_opt_clr(sbinfo->si_mntflags, PLINK); +#endif +#ifdef ForceNoXino + au_opt_clr(sbinfo->si_mntflags, XINO); +#endif +#ifdef ForceNoRefrof + au_opt_clr(sbinfo->si_mntflags, REFROF); +#endif +#ifdef ForceShwh + au_opt_set(sbinfo->si_mntflags, SHWH); +#endif +} + +int __init au_debug_init(void) +{ + aufs_bindex_t bindex; + struct au_vdir_destr destr; + + bindex = -1; + AuDebugOn(bindex >= 0); + + destr.len = -1; + AuDebugOn(destr.len < NAME_MAX); + +#ifdef CONFIG_4KSTACKS + AuWarn("CONFIG_4KSTACKS is defined.\n"); +#endif + +#ifdef ForceBrs + sysaufs_brs = 1; +#endif + +#if 0 /* verbose debug */ + { + union { + struct au_branch *br; + struct au_dinfo *di; + struct au_finfo *fi; + struct au_iinfo *ii; + struct au_hinode *hi; + struct au_sbinfo *si; + struct au_vdir_destr *destr; + struct au_vdir_de *de; + struct au_vdir_wh *wh; + struct au_vdir *vd; + } u; + + pr_info("br{" + "xino %d, " + "id %d, perm %d, mnt %d, count %d, " + "wbr %d, " + "xup %d, xrun %d, " + "gen %d, " + "sa %d} %d\n", + offsetof(typeof(*u.br), br_xino), + offsetof(typeof(*u.br), br_id), + offsetof(typeof(*u.br), br_perm), + offsetof(typeof(*u.br), br_mnt), + offsetof(typeof(*u.br), br_count), + offsetof(typeof(*u.br), wbr), + offsetof(typeof(*u.br), br_xino_upper), + offsetof(typeof(*u.br), br_xino_running), + offsetof(typeof(*u.br), br_generation), + offsetof(typeof(*u.br), br_sabr), + sizeof(*u.br)); + pr_info("di{gen %d, rwsem %d, bstart %d, bend %d, bwh %d, " + "bdiropq %d, hdentry %d} %d\n", + offsetof(typeof(*u.di), di_generation), + offsetof(typeof(*u.di), di_rwsem), + offsetof(typeof(*u.di), di_bstart), + offsetof(typeof(*u.di), di_bend), + offsetof(typeof(*u.di), di_bwh), + offsetof(typeof(*u.di), di_bdiropq), + offsetof(typeof(*u.di), di_hdentry), + sizeof(*u.di)); + pr_info("fi{gen %d, rwsem %d, hfile %d, bstart %d, bend %d, " + "h_vm_ops %d, vdir_cach %d} %d\n", + offsetof(typeof(*u.fi), fi_generation), + offsetof(typeof(*u.fi), fi_rwsem), + offsetof(typeof(*u.fi), fi_hfile), + offsetof(typeof(*u.fi), fi_bstart), + offsetof(typeof(*u.fi), fi_bend), + offsetof(typeof(*u.fi), fi_h_vm_ops), + offsetof(typeof(*u.fi), fi_vdir_cache), + sizeof(*u.fi)); + pr_info("ii{gen %d, hsb %d, " + "rwsem %d, bstart %d, bend %d, hinode %d, vdir %d} " + "%d\n", + offsetof(typeof(*u.ii), ii_generation), + offsetof(typeof(*u.ii), ii_hsb1), + offsetof(typeof(*u.ii), ii_rwsem), + offsetof(typeof(*u.ii), ii_bstart), + offsetof(typeof(*u.ii), ii_bend), + offsetof(typeof(*u.ii), ii_hinode), + offsetof(typeof(*u.ii), ii_vdir), + sizeof(*u.ii)); + pr_info("hi{inode %d, id %d, notify %d, wh %d} %d\n", + offsetof(typeof(*u.hi), hi_inode), + offsetof(typeof(*u.hi), hi_id), + offsetof(typeof(*u.hi), hi_notify), + offsetof(typeof(*u.hi), hi_whdentry), + sizeof(*u.hi)); + pr_info("si{nwt %d, rwsem %d, gen %d, stat %d, " + "bend %d, last id %d, br %d, " + "cpup %d, creat %d, ops %d, ops %d, " + "rr %d, mfs %d, " + "mntflags %d, " + "xread %d, xwrite %d, xib %d, xmtx %d, buf %d, " + "xlast %d, xnext %d, " + "rdcache %d, " + "dirwh %d, " + "pl_lock %d, pl %d, " + "mnt %d, " + "sys %d, " + /* "lvma_l %d, lvma %d" */ + "} %d\n", + offsetof(typeof(*u.si), si_nowait), + offsetof(typeof(*u.si), si_rwsem), + offsetof(typeof(*u.si), si_generation), + offsetof(typeof(*u.si), au_si_status), + offsetof(typeof(*u.si), si_bend), + offsetof(typeof(*u.si), si_last_br_id), + offsetof(typeof(*u.si), si_branch), + offsetof(typeof(*u.si), si_wbr_copyup), + offsetof(typeof(*u.si), si_wbr_create), + offsetof(typeof(*u.si), si_wbr_copyup_ops), + offsetof(typeof(*u.si), si_wbr_create_ops), + offsetof(typeof(*u.si), si_wbr_rr_next), + offsetof(typeof(*u.si), si_wbr_mfs), + offsetof(typeof(*u.si), si_mntflags), + offsetof(typeof(*u.si), si_xread), + offsetof(typeof(*u.si), si_xwrite), + offsetof(typeof(*u.si), si_xib), + offsetof(typeof(*u.si), si_xib_mtx), + offsetof(typeof(*u.si), si_xib_buf), + offsetof(typeof(*u.si), si_xib_last_pindex), + offsetof(typeof(*u.si), si_xib_next_bit), + offsetof(typeof(*u.si), si_rdcache), + offsetof(typeof(*u.si), si_dirwh), + offsetof(typeof(*u.si), si_plink_lock), + offsetof(typeof(*u.si), si_plink), + offsetof(typeof(*u.si), si_mnt), + offsetof(typeof(*u.si), si_sa), + /*offsetof(typeof(*u.si), si_lvma_lock), + offsetof(typeof(*u.si), si_lvma),*/ + sizeof(*u.si)); + pr_info("destr{len %d, name %d} %d\n", + offsetof(typeof(*u.destr), len), + offsetof(typeof(*u.destr), name), + sizeof(*u.destr)); + pr_info("de{ino %d, type %d, str %d} %d\n", + offsetof(typeof(*u.de), de_ino), + offsetof(typeof(*u.de), de_type), + offsetof(typeof(*u.de), de_str), + sizeof(*u.de)); + pr_info("wh{hash %d, bindex %d, str %d} %d\n", + offsetof(typeof(*u.wh), wh_hash), + offsetof(typeof(*u.wh), wh_bindex), + offsetof(typeof(*u.wh), wh_str), + sizeof(*u.wh)); + pr_info("vd{deblk %d, nblk %d, last %d, ver %d, jiffy %d} %d\n", + offsetof(typeof(*u.vd), vd_deblk), + offsetof(typeof(*u.vd), vd_nblk), + offsetof(typeof(*u.vd), vd_last), + offsetof(typeof(*u.vd), vd_version), + offsetof(typeof(*u.vd), vd_jiffy), + sizeof(*u.vd)); + } +#endif + + return 0; +} --- linux-2.6.28.orig/ubuntu/aufs/misc.c +++ linux-2.6.28/ubuntu/aufs/misc.c @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * $Id: misc.c,v 1.17 2008/09/08 02:40:48 sfjro Exp $ + */ + +#include "aufs.h" + +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp) +{ + void *q; + + LKTRTrace("p %p, nused %d, sz %d\n", p, nused, new_sz); + AuDebugOn(new_sz <= 0); + if (new_sz <= nused) + return p; + + q = krealloc(p, new_sz, gfp); + if (q) + memset(q + nused, 0, new_sz - nused); + return q; +} + +/* ---------------------------------------------------------------------- */ + +struct nameidata *au_dup_nd(struct au_sbinfo *sbinfo, struct nameidata *dst, + struct nameidata *src) +{ + LKTRTrace("src %p\n", src); + + if (src) { + *dst = *src; + dst->flags &= ~LOOKUP_PARENT; + if (sbinfo->si_wbr_create == AuWbrCreate_TDP) { + if ((dst->flags & LOOKUP_CREATE) + && !(dst->intent.open.flags & O_CREAT)) + dst->flags &= ~LOOKUP_CREATE; + } else { + dst->flags &= ~LOOKUP_CREATE; + dst->intent.open.flags &= ~O_CREAT; + } + } else + dst = NULL; + + return dst; +} + +struct nameidata *au_fake_dm(struct nameidata *fake_nd, struct nameidata *nd, + struct super_block *sb, aufs_bindex_t bindex) +{ + LKTRTrace("nd %p, b%d\n", nd, bindex); + + if (!nd) + return NULL; + + DiMustAnyLock(nd->path.dentry); + + fake_nd->path.dentry = NULL; + fake_nd->path.mnt = NULL; + + if (bindex <= au_dbend(nd->path.dentry)) + fake_nd->path.dentry = au_h_dptr(nd->path.dentry, bindex); + if (fake_nd->path.dentry) { + fake_nd->path.mnt = au_sbr_mnt(sb, bindex); + AuDebugOn(!fake_nd->path.mnt); + path_get(&fake_nd->path); + } else + fake_nd = ERR_PTR(-ENOENT); + + AuTraceErrPtr(fake_nd); + return fake_nd; +} + +void au_fake_dm_release(struct nameidata *fake_nd) +{ + if (fake_nd) + path_put(&fake_nd->path); +} + +int au_h_create(struct inode *h_dir, struct dentry *h_dentry, int mode, + struct vfsub_args *vargs, struct nameidata *nd, + struct vfsmount *nfsmnt) +{ + int err; + + LKTRTrace("hi%lu, %.*s, 0%o, nd %d, nfsmnt %d\n", + h_dir->i_ino, AuDLNPair(h_dentry), mode, !!nd, !!nfsmnt); + + err = -ENOSYS; + if (!nfsmnt) + err = vfsub_create(h_dir, h_dentry, mode, /*nd*/NULL, vargs); + else { + struct nameidata fake_nd; + + if (nd) + fake_nd = *nd; + else + memset(&fake_nd, 0, sizeof(fake_nd)); + fake_nd.path.dentry = h_dentry; + fake_nd.path.mnt = nfsmnt; + path_get(&fake_nd.path); + fake_nd.flags = LOOKUP_CREATE; + fake_nd.intent.open.flags = O_CREAT | FMODE_READ; + fake_nd.intent.open.create_mode = mode; + + err = vfsub_create(h_dir, h_dentry, mode, &fake_nd, vargs); + path_put(&fake_nd.path); + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +int au_copy_file(struct file *dst, struct file *src, loff_t len, + struct au_hinode *hdir, struct super_block *sb, + struct vfsub_args *vargs) +{ + int err, all_zero, do_kfree; + unsigned long blksize; + char *buf, *zp; + /* reduce stack usage */ + struct iattr *ia; + + LKTRTrace("%.*s, %.*s\n", + AuDLNPair(dst->f_dentry), AuDLNPair(src->f_dentry)); + AuDebugOn(!(dst->f_mode & FMODE_WRITE)); +#ifdef CONFIG_AUFS_DEBUG + { + struct dentry *parent; + parent = dget_parent(dst->f_dentry); + IMustLock(parent->d_inode); + dput(parent); + } +#endif + + err = -ENOMEM; + blksize = dst->f_dentry->d_sb->s_blocksize; + if (!blksize || PAGE_SIZE < blksize) + blksize = PAGE_SIZE; + LKTRTrace("blksize %lu\n", blksize); + /* todo: use ZERO_PAGE(0) */ + BUILD_BUG_ON(KMALLOC_MAX_SIZE < 128 << 10); + do_kfree = 1; + if (blksize <= 64 << 10 && blksize * 2 >= sizeof(*ia)) { + buf = kmalloc(blksize * 2, GFP_NOFS); + if (unlikely(!buf)) + goto out; + zp = buf + blksize; + memset(zp, 0, blksize); + } else { + BUILD_BUG_ON(PAGE_SIZE * 2 < sizeof(*ia)); +#if 0 + buf = (void *)__get_free_pages(GFP_NOFS, 1); + zp = buf + PAGE_SIZE; +#endif + do_kfree = 0; + buf = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!buf)) + goto out; + zp = (void *)get_zeroed_page(GFP_NOFS); + if (unlikely(!zp)) + goto out_buf; + } + +#ifdef CONFIG_AUFS_DEBUG + if (len > (1 << 22)) + AuWarn("copying a large file %lld\n", (long long)len); +#endif + err = 0; + all_zero = 0; + src->f_pos = 0; + dst->f_pos = 0; + while (len) { + size_t sz, rbytes, wbytes; + char *p; + + LKTRTrace("len %lld\n", len); + sz = blksize; + if (len < blksize) + sz = len; + + /* support LSM and notify */ + rbytes = 0; + /* todo: signal_pending? */ + while (!rbytes || err == -EAGAIN || err == -EINTR) { + rbytes = vfsub_read_k(src, buf, sz, &src->f_pos, + vfsub_ftest(vargs->flags, DLGT)); + err = rbytes; + } + if (unlikely(err < 0)) + break; + + all_zero = 0; + if (len >= rbytes && rbytes == blksize) { +#if 1 + all_zero = !memcmp(buf, zp, rbytes); +#else /* reserved for future use */ + unsigned long long *ullp; + size_t n, i; + + all_zero = 1; + ullp = (void *)buf; + n = rbytes / sizeof(*ullp); + i = n; + while (n-- > 0 && all_zero) + all_zero = !*ullp++; + p = (void *)ullp; + i *= sizeof(*ullp); + for (; all_zero && i < rbytes; i++) + all_zero = !*p++; +#endif + } + if (!all_zero) { + wbytes = rbytes; + p = buf; + while (wbytes) { + size_t b; + /* support LSM and notify */ + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_MODIFY, hdir); + b = vfsub_write_k(dst, p, wbytes, &dst->f_pos, + vargs); + err = b; + /* todo: signal_pending? */ + if (unlikely(err == -EAGAIN || err == -EINTR)) + continue; + if (unlikely(err < 0)) + break; + wbytes -= b; + p += b; + } + } else { + loff_t res; + LKTRLabel(hole); + res = vfsub_llseek(dst, rbytes, SEEK_CUR); + err = res; + if (unlikely(res < 0)) + break; + } + len -= rbytes; + err = 0; + } + + /* the last block may be a hole */ + if (unlikely(!err && all_zero)) { + struct dentry *h_d = dst->f_dentry; + struct inode *h_i = h_d->d_inode; + + LKTRLabel(last hole); + do { + /* todo: signal_pending? */ + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_MODIFY, hdir); + err = vfsub_write_k(dst, "\0", 1, &dst->f_pos, vargs); + } while (err == -EAGAIN || err == -EINTR); + if (err == 1) { + ia = (void *)buf; + ia->ia_size = dst->f_pos; + ia->ia_valid = ATTR_SIZE | ATTR_FILE; + ia->ia_file = dst; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, vfsub_events_notify_change(ia), + hdir); + mutex_lock_nested(&h_i->i_mutex, AuLsc_I_CHILD2); + err = vfsub_notify_change(h_d, ia, vargs); + mutex_unlock(&h_i->i_mutex); + } + } + if (do_kfree) + kfree(buf); + else + free_page((unsigned long)zp); + + out_buf: + if (unlikely(!do_kfree)) + free_page((unsigned long)buf); + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/cpup.c +++ linux-2.6.28/ubuntu/aufs/cpup.c @@ -0,0 +1,1105 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * copy-up functions, see wbr_policy.c for copy-down + * + * $Id: cpup.c,v 1.17 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +/* todo? violent cpup_attr_*() functions don't care inode lock */ + +void au_cpup_attr_timesizes(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode); + /* todo? IMustLock(!h_inode); */ + + fsstack_copy_attr_times(inode, h_inode); + vfsub_copy_inode_size(inode, h_inode); +} + +void au_cpup_attr_nlink(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + AuDebugOn(!inode->i_mode); + + h_inode = au_h_iptr(inode, au_ibstart(inode)); + inode->i_nlink = h_inode->i_nlink; + + /* + * fewer nlink makes find(1) noisy, but larger nlink doesn't. + * it may includes whplink directory. + */ + if (unlikely(S_ISDIR(h_inode->i_mode))) { + aufs_bindex_t bindex, bend; + bend = au_ibend(inode); + for (bindex = au_ibstart(inode) + 1; bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (h_inode) + au_add_nlink(inode, h_inode); + } + } +} + +void au_cpup_attr_changeable(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode); + + inode->i_mode = h_inode->i_mode; + inode->i_uid = h_inode->i_uid; + inode->i_gid = h_inode->i_gid; + au_cpup_attr_timesizes(inode); + + /* todo: remove this? */ + inode->i_flags = h_inode->i_flags; +} + +void au_cpup_igen(struct inode *inode, struct inode *h_inode) +{ + struct au_iinfo *iinfo = au_ii(inode); + iinfo->ii_higen = h_inode->i_generation; + iinfo->ii_hsb1 = h_inode->i_sb; +} + +void au_cpup_attr_all(struct inode *inode) +{ + struct inode *h_inode; + + LKTRTrace("i%lu\n", inode->i_ino); + /* todo? IMustLock(inode); */ + h_inode = au_h_iptr(inode, au_ibstart(inode)); + AuDebugOn(!h_inode); + + au_cpup_attr_changeable(inode); + if (inode->i_nlink > 0) + au_cpup_attr_nlink(inode); + + switch (inode->i_mode & S_IFMT) { + case S_IFBLK: + case S_IFCHR: + inode->i_rdev = au_h_rdev(h_inode, /*h_mnt*/NULL, + /*h_dentry*/NULL); + } + inode->i_blkbits = h_inode->i_blkbits; + au_cpup_igen(inode, h_inode); +} + +/* ---------------------------------------------------------------------- */ + +/* Note: dt_dentry and dt_hidden_dentry are not dget/dput-ed */ + +/* keep the timestamps of the parent dir when cpup */ +void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, + struct dentry *h_dentry, struct au_hinode *hinode, + struct au_hinode *hdir) +{ + struct inode *h_inode; + + LKTRTrace("%.*s, hdir %d\n", AuDLNPair(dentry), !!hdir); + AuDebugOn(!dentry || !h_dentry || !h_dentry->d_inode); + + dt->dt_dentry = dentry; + dt->dt_h_dentry = h_dentry; + dt->dt_hinode = hinode; + dt->dt_hdir = hdir; + h_inode = h_dentry->d_inode; + dt->dt_atime = h_inode->i_atime; + dt->dt_mtime = h_inode->i_mtime; + /* smp_mb(); */ +} + +void au_dtime_revert(struct au_dtime *dt) +{ + struct iattr attr; + int err; + struct au_hin_ignore ign[2]; + struct vfsub_args vargs; + + LKTRTrace("%.*s\n", AuDLNPair(dt->dt_dentry)); + + attr.ia_atime = dt->dt_atime; + attr.ia_mtime = dt->dt_mtime; + attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET + | ATTR_ATIME | ATTR_ATIME_SET; + + vfsub_args_init(&vargs, ign, + au_test_dlgt(au_mntflags(dt->dt_dentry->d_sb)), 0); + /* + * IN_ATTRIB should be divided into + * IN_ATTRIB_ATIME, IN_ATTRIB_MTIME ..., + * and define all ORed new IN_ATTRIB macro. + */ + vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hinode); + vfsub_ign_hinode(&vargs, IN_ATTRIB, dt->dt_hdir); + err = vfsub_notify_change(dt->dt_h_dentry, &attr, &vargs); + if (unlikely(err)) + AuWarn("restoring timestamps failed(%d). ignored\n", err); +} + +/* ---------------------------------------------------------------------- */ + +static noinline_for_stack +int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err, sbits; + struct dentry *h_dst; + struct iattr ia; + struct inode *h_isrc, *h_idst; + + h_dst = au_h_dptr(dst, bindex); + LKTRTrace("%.*s\n", AuDLNPair(h_dst)); + h_idst = h_dst->d_inode; + /* todo? IMustLock(h_idst); */ + h_isrc = h_src->d_inode; + /* todo? IMustLock(h_isrc); */ + + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID + | ATTR_ATIME | ATTR_MTIME + | ATTR_ATIME_SET | ATTR_MTIME_SET; + ia.ia_mode = h_isrc->i_mode; + ia.ia_uid = h_isrc->i_uid; + ia.ia_gid = h_isrc->i_gid; + ia.ia_atime = h_isrc->i_atime; + ia.ia_mtime = h_isrc->i_mtime; + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); + + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_ATTRIB, hdir); + err = vfsub_notify_change(h_dst, &ia, vargs); + + /* is this nfs only? */ + if (!err && sbits && au_test_nfs(h_dst->d_sb)) { + ia.ia_valid = ATTR_FORCE | ATTR_MODE; + ia.ia_mode = h_isrc->i_mode; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_ATTRIB, hdir); + err = vfsub_notify_change(h_dst, &ia, vargs); + } + + /* todo? remove this? */ + if (!err) + h_idst->i_flags = h_isrc->i_flags; + + AuTraceErr(err); + return err; +} + +/* + * to support a sparse file which is opened with O_APPEND, + * we need to close the file. + */ +static noinline_for_stack +int cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc, + loff_t len, struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err, i; + struct super_block *sb; + struct inode *h_inode; + enum { SRC, DST }; + struct { + aufs_bindex_t bindex; + unsigned int flags; + struct dentry *dentry; + struct file *file; + void *label, *label_file; + } *h, hidden[] = { + { + .bindex = bsrc, + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, + .file = NULL, + .label = &&out, + .label_file = &&out_src_file + }, + { + .bindex = bdst, + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, + .file = NULL, + .label = &&out_src_file, + .label_file = &&out_dst_file + } + }; + + LKTRTrace("dentry %.*s, bdst %d, bsrc %d, len %lld\n", + AuDLNPair(dentry), bdst, bsrc, len); + AuDebugOn(bsrc <= bdst); + AuDebugOn(!len); + sb = dentry->d_sb; + AuDebugOn(au_test_ro(sb, bdst, dentry->d_inode)); + /* bsrc branch can be ro/rw. */ + + h = hidden; + for (i = 0; i < 2; i++, h++) { + h->dentry = au_h_dptr(dentry, h->bindex); + AuDebugOn(!h->dentry); + h_inode = h->dentry->d_inode; + AuDebugOn(!h_inode || !S_ISREG(h_inode->i_mode)); + h->file = au_h_open(dentry, h->bindex, h->flags, /*file*/NULL); + err = PTR_ERR(h->file); + if (IS_ERR(h->file)) + goto *h->label; + err = -EINVAL; + if (unlikely(!h->file->f_op)) + goto *h->label_file; + } + + /* stop updating while we copyup */ + IMustLock(hidden[SRC].dentry->d_inode); + err = au_copy_file(hidden[DST].file, hidden[SRC].file, len, hdir, sb, + vargs); + + out_dst_file: + fput(hidden[DST].file); + au_sbr_put(sb, hidden[DST].bindex); + out_src_file: + fput(hidden[SRC].file); + au_sbr_put(sb, hidden[SRC].bindex); + out: + AuTraceErr(err); + return err; +} + +static int au_do_cpup_regular(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, + struct au_hinode *hdir, struct dentry *h_dst, + struct vfsub_args *vargs) +{ + int err, rerr; + loff_t l; + + AuTraceEnter(); + + err = 0; + l = i_size_read(au_h_iptr(dentry->d_inode, bsrc)); + if (len == -1 || l < len) + len = l; + if (len) + err = cpup_regular(dentry, bdst, bsrc, len, hdir, vargs); + if (!err) + goto out; /* success */ + + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + rerr = vfsub_unlink(hdir->hi_inode, h_dst, vargs); + if (rerr) { + AuIOErr("failed unlinking cpup-ed %.*s(%d, %d)\n", + AuDLNPair(h_dst), err, rerr); + err = -EIO; + } + + out: + AuTraceErr(err); + return err; +} + +static int au_do_cpup_symlink(struct dentry *h_dst, struct dentry *h_src, + struct inode *h_dir, umode_t mode, + struct vfsub_args *vargs) +{ + int err, symlen; + char *sym; + mm_segment_t old_fs; + + AuTraceEnter(); + + err = -ENOMEM; + sym = __getname(); + if (unlikely(!sym)) + goto out; + + old_fs = get_fs(); + set_fs(KERNEL_DS); + symlen = h_src->d_inode->i_op->readlink(h_src, (char __user *)sym, + PATH_MAX); + err = symlen; + set_fs(old_fs); + + if (symlen > 0) { + sym[symlen] = 0; + err = vfsub_symlink(h_dir, h_dst, sym, mode, vargs); + } + __putname(sym); + + out: + AuTraceErr(err); + return err; +} + +/* return with hidden dst inode is locked */ +static noinline_for_stack +int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, aufs_bindex_t bsrc, + loff_t len, unsigned int flags, struct dentry *dst_parent, + struct vfsub_args *vargs) +{ + int err; + unsigned char isdir, hinotify; + struct dentry *h_src, *h_dst, *h_parent, *gparent; + struct inode *h_inode, *h_dir; + struct au_dtime dt; + umode_t mode; + struct super_block *sb; + struct au_hinode *hgdir, *hdir; + unsigned int mnt_flags; + const int do_dt = au_ftest_cpup(flags, DTIME); + + LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, dtime %u\n", + AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len, + do_dt); + sb = dentry->d_sb; + AuDebugOn(bdst >= bsrc || au_test_ro(sb, bdst, NULL)); + /* bsrc branch can be ro/rw. */ + + h_src = au_h_dptr(dentry, bsrc); + AuDebugOn(!h_src); + h_inode = h_src->d_inode; + AuDebugOn(!h_inode); + AuDebugOn(h_inode != au_h_iptr(dentry->d_inode, bsrc)); + + /* stop referencing while we are creating */ + h_dst = au_h_dptr(dentry, bdst); + AuDebugOn(h_dst && h_dst->d_inode); + h_parent = h_dst->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + AuDebugOn(h_parent != h_dst->d_parent); + + hdir = NULL; + mnt_flags = au_mntflags(sb); + hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY); + if (unlikely(hinotify)) { + hdir = au_hi(dst_parent->d_inode, bdst); + AuDebugOn(hdir->hi_inode != h_dir); + } + + if (do_dt) { + hgdir = NULL; + if (unlikely(hinotify && !IS_ROOT(dst_parent))) { + gparent = dget_parent(dst_parent); + hgdir = au_hi(gparent->d_inode, bdst); + IMustLock(hgdir->hi_inode); + dput(gparent); + } + au_dtime_store(&dt, dst_parent, h_parent, hdir, hgdir); + } + + isdir = 0; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_CREATE, hdir); + mode = h_inode->i_mode; + switch (mode & S_IFMT) { + case S_IFREG: + /* stop updating while we are referencing */ + IMustLock(h_inode); + err = au_h_create(h_dir, h_dst, mode | S_IWUSR, vargs, NULL, + au_nfsmnt(sb, bdst)); + if (!err) + err = au_do_cpup_regular(dentry, bdst, bsrc, len, + hdir, h_dst, vargs); + break; + case S_IFDIR: + isdir = 1; + err = vfsub_mkdir(h_dir, h_dst, mode, vargs); + if (!err) { + /* setattr case: dir is not locked */ + if (0 && au_ibstart(dst_parent->d_inode) == bdst) + au_cpup_attr_nlink(dst_parent->d_inode); + au_cpup_attr_nlink(dentry->d_inode); + } + break; + case S_IFLNK: + err = au_do_cpup_symlink(h_dst, h_src, h_dir, mode, vargs); + break; + case S_IFCHR: + case S_IFBLK: + AuDebugOn(!capable(CAP_MKNOD)); + /*FALLTHROUGH*/ + case S_IFIFO: + case S_IFSOCK: + err = vfsub_mknod(h_dir, h_dst, mode, + au_h_rdev(h_inode, /*h_mnt*/NULL, h_src), + vargs); + break; + default: + AuIOErr("Unknown inode type 0%o\n", mode); + err = -EIO; + } + + if (unlikely(hinotify + && !isdir + && au_opt_test_xino(mnt_flags) + && h_inode->i_nlink == 1 + //&& dentry->d_inode->i_nlink == 1 + && bdst < bsrc + && !au_ftest_cpup(flags, KEEPLINO))) + au_xino_write0(sb, bsrc, h_inode->i_ino, /*ino*/0); + /* ignore this error */ + + if (do_dt) + au_dtime_revert(&dt); + AuTraceErr(err); + return err; +} + +/* + * copyup the @dentry from @bsrc to @bdst. + * the caller must set the both of hidden dentries. + * @len is for truncating when it is -1 copyup the entire file. + */ +static int au_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, unsigned int flags, + struct dentry *dst_parent, struct vfsub_args *vargs) +{ + int err, rerr; + unsigned int mnt_flags; + aufs_bindex_t old_ibstart; + unsigned char isdir, plink, hinotify; + struct au_dtime dt; + struct dentry *h_src, *h_dst, *h_parent, *gparent; + struct inode *dst_inode, *h_dir, *inode; + struct super_block *sb; + struct au_hinode *hgdir, *hdir; + + LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len, + flags); + sb = dentry->d_sb; + AuDebugOn(bsrc <= bdst); + h_dst = au_h_dptr(dentry, bdst); + AuDebugOn(!h_dst || h_dst->d_inode); + h_parent = h_dst->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + h_src = au_h_dptr(dentry, bsrc); + AuDebugOn(!h_src || !h_src->d_inode); + inode = dentry->d_inode; + IiMustWriteLock(inode); + if (!dst_parent) + dst_parent = dget_parent(dentry); + else + dget(dst_parent); + + mnt_flags = au_mntflags(sb); + plink = !!au_opt_test(mnt_flags, PLINK); + hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY); + hdir = NULL; + if (unlikely(hinotify)) + hdir = au_hi(dst_parent->d_inode, bdst); + dst_inode = au_h_iptr(inode, bdst); + if (unlikely(dst_inode)) { + if (unlikely(!plink)) { + err = -EIO; + AuIOErr("i%lu exists on a upper branch " + "but plink is disabled\n", inode->i_ino); + goto out; + } + + if (dst_inode->i_nlink) { + const int do_dt = au_ftest_cpup(flags, DTIME); + + h_src = au_plink_lkup(sb, bdst, inode); + err = PTR_ERR(h_src); + if (IS_ERR(h_src)) + goto out; + AuDebugOn(!h_src->d_inode); + + if (do_dt) { + hgdir = NULL; + if (unlikely(hinotify && !IS_ROOT(dst_parent))) { + gparent = dget_parent(dst_parent); + hgdir = au_hi(gparent->d_inode, bdst); + IMustLock(hgdir->hi_inode); + dput(gparent); + } + au_dtime_store(&dt, dst_parent, h_parent, hdir, + hgdir); + } + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_CREATE, hdir); + err = vfsub_link(h_src, h_dir, h_dst, vargs); + if (do_dt) + au_dtime_revert(&dt); + dput(h_src); + goto out; + } else + /* todo: cpup_wh_file? */ + /* udba work */ + au_update_brange(inode, 1); + } + + old_ibstart = au_ibstart(inode); + err = cpup_entry(dentry, bdst, bsrc, len, flags, dst_parent, vargs); + if (unlikely(err)) + goto out; + dst_inode = h_dst->d_inode; + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); + + /* todo: test dlgt? */ + err = cpup_iattr(dentry, bdst, h_src, hdir, vargs); +#if 0 /* reserved for future use */ + if (0 && !err) + err = cpup_xattrs(h_src, h_dst); +#endif + isdir = S_ISDIR(dst_inode->i_mode); + if (!err) { + if (bdst < old_ibstart) + au_set_ibstart(inode, bdst); + au_set_h_iptr(inode, bdst, au_igrab(dst_inode), + au_hi_flags(inode, isdir)); + mutex_unlock(&dst_inode->i_mutex); + if (!isdir + && h_src->d_inode->i_nlink > 1 + && plink) + au_plink_append(sb, inode, h_dst, bdst); + goto out; /* success */ + } + + /* revert */ + mutex_unlock(&dst_inode->i_mutex); + hgdir = NULL; + if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY) + && !IS_ROOT(dst_parent))) { + gparent = dget_parent(dst_parent); + hgdir = au_hi(gparent->d_inode, bdst); + dput(gparent); + } + au_dtime_store(&dt, dst_parent, h_parent, hdir, hgdir); + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + if (!isdir) + rerr = vfsub_unlink(h_dir, h_dst, vargs); + else + rerr = vfsub_rmdir(h_dir, h_dst, vargs); + au_dtime_revert(&dt); + if (rerr) { + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); + err = -EIO; + } + + out: + dput(dst_parent); + AuTraceErr(err); + return err; +} + +struct au_cpup_single_args { + int *errp; + struct dentry *dentry; + aufs_bindex_t bdst, bsrc; + loff_t len; + unsigned int flags; + struct dentry *dst_parent; + struct vfsub_args *vargs; +}; + +static void au_call_cpup_single(void *args) +{ + struct au_cpup_single_args *a = args; + *a->errp = au_cpup_single(a->dentry, a->bdst, a->bsrc, a->len, + a->flags, a->dst_parent, a->vargs); +} + +int au_sio_cpup_single(struct dentry *dentry, aufs_bindex_t bdst, + aufs_bindex_t bsrc, loff_t len, unsigned int flags, + struct dentry *dst_parent) +{ + int err, wkq_err; + struct dentry *h_dentry; + umode_t mode; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len, + flags); + + vfsub_args_init(&vargs, &ign, au_test_dlgt(au_mntflags(dentry->d_sb)), + /*force_unlink*/0); + h_dentry = au_h_dptr(dentry, bsrc); + mode = h_dentry->d_inode->i_mode & S_IFMT; + if ((mode != S_IFCHR && mode != S_IFBLK) + || capable(CAP_MKNOD)) + err = au_cpup_single(dentry, bdst, bsrc, len, flags, + dst_parent, &vargs); + else { + struct au_cpup_single_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bdst, + .bsrc = bsrc, + .len = len, + .flags = flags, + .dst_parent = dst_parent, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_cpup_single, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + AuTraceErr(err); + return err; +} + +/* + * copyup the @dentry from the first active hidden branch to @bdst, + * using au_cpup_single(). + */ +static int au_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + unsigned int flags, struct vfsub_args *vargs) +{ + int err; + struct inode *inode; + aufs_bindex_t bsrc, bend; + + LKTRTrace("%.*s, bdst %d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), bdst, len, flags); + inode = dentry->d_inode; + AuDebugOn(!S_ISDIR(inode->i_mode) && au_dbstart(dentry) < bdst); + + bend = au_dbend(dentry); + for (bsrc = bdst + 1; bsrc <= bend; bsrc++) + if (au_h_dptr(dentry, bsrc)) + break; + AuDebugOn(!au_h_dptr(dentry, bsrc)); + + err = au_lkup_neg(dentry, bdst); + if (!err) { + err = au_cpup_single(dentry, bdst, bsrc, len, flags, NULL, + vargs); + if (!err) + return 0; /* success */ + + /* revert */ + au_set_h_dptr(dentry, bdst, NULL); + au_set_dbstart(dentry, bsrc); + } + + AuTraceErr(err); + return err; +} + +struct au_cpup_simple_args { + int *errp; + struct dentry *dentry; + aufs_bindex_t bdst; + loff_t len; + unsigned int flags; + struct vfsub_args *vargs; +}; + +static void au_call_cpup_simple(void *args) +{ + struct au_cpup_simple_args *a = args; + *a->errp = au_cpup_simple(a->dentry, a->bdst, a->len, a->flags, + a->vargs); +} + +int au_sio_cpup_simple(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + unsigned int flags) +{ + int err, wkq_err; + unsigned char do_sio, dlgt; + struct dentry *parent; + struct inode *h_dir, *dir; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("%.*s, b%d, len %lld, flags 0x%x\n", + AuDLNPair(dentry), bdst, len, flags); + + parent = dget_parent(dentry); + dir = parent->d_inode; + h_dir = au_h_iptr(dir, bdst); + dlgt = !!au_test_dlgt(au_mntflags(dir->i_sb)); + do_sio = !!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE, dlgt); + if (!do_sio) { + /* + * testing CAP_MKNOD is for generic fs, + * but CAP_FSETID is for xfs only, currently. + */ + umode_t mode = dentry->d_inode->i_mode; + do_sio = (((mode & (S_IFCHR | S_IFBLK)) + && !capable(CAP_MKNOD)) + || ((mode & (S_ISUID | S_ISGID)) + && !capable(CAP_FSETID))); + } + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + if (!do_sio) + err = au_cpup_simple(dentry, bdst, len, flags, &vargs); + else { + struct au_cpup_simple_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bdst, + .len = len, + .flags = flags, + .vargs = &vargs + }; + vfsub_fclr(vargs.flags, DLGT); + wkq_err = au_wkq_wait(au_call_cpup_simple, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + dput(parent); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int au_do_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *wh_dentry, struct file *file, + loff_t len, struct vfsub_args *vargs) +{ + int err; + struct au_dinfo *dinfo; + aufs_bindex_t bstart; + struct dentry *h_d_bdst, *h_d_bstart; + + AuTraceEnter(); + + dinfo = au_di(dentry); + bstart = dinfo->di_bstart; + h_d_bdst = dinfo->di_hdentry[0 + bdst].hd_dentry; + dinfo->di_bstart = bdst; + dinfo->di_hdentry[0 + bdst].hd_dentry = wh_dentry; + h_d_bstart = dinfo->di_hdentry[0 + bstart].hd_dentry; + if (file) + dinfo->di_hdentry[0 + bstart].hd_dentry + = au_h_fptr(file, au_fbstart(file))->f_dentry; + err = au_cpup_single(dentry, bdst, bstart, len, !AuCpup_DTIME, + /*h_parent*/NULL, vargs); + if (!err && file) { + err = au_reopen_nondir(file); + dinfo->di_hdentry[0 + bstart].hd_dentry = h_d_bstart; + } + dinfo->di_hdentry[0 + bdst].hd_dentry = h_d_bdst; + dinfo->di_bstart = bstart; + + AuTraceErr(err); + return err; +} + +/* + * copyup the deleted file for writing. + */ +static int au_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + struct file *file) +{ + int err; + unsigned char dlgt; + struct dentry *parent, *h_parent, *wh_dentry; + struct super_block *sb; + unsigned int mnt_flags; + struct au_dtime dt; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_hinode *hgdir, *hdir; + struct au_ndx ndx = { + .nd = NULL, + .flags = 0, + /* .br = NULL */ + }; + + LKTRTrace("%.*s, bdst %d, len %llu\n", AuDLNPair(dentry), bdst, len); + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode) + || (file && !(file->f_mode & FMODE_WRITE))); + DiMustWriteLock(dentry); + + parent = dget_parent(dentry); + IiMustAnyLock(parent->d_inode); + h_parent = au_h_dptr(parent, bdst); + AuDebugOn(!h_parent); + + sb = parent->d_sb; + mnt_flags = au_mntflags(sb); + dlgt = 0; + ndx.nfsmnt = au_nfsmnt(sb, bdst); + if (unlikely(au_test_dlgt(mnt_flags))) { + dlgt = 1; + au_fset_ndx(ndx.flags, DLGT); + } + wh_dentry = au_whtmp_lkup(h_parent, &dentry->d_name, &ndx); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + hdir = NULL; + hgdir = NULL; + if (unlikely(au_opt_test(mnt_flags, UDBA_INOTIFY))) { + hdir = au_hi(parent->d_inode, bdst); + if (!IS_ROOT(parent)) { + struct dentry *gparent; + gparent = dget_parent(parent); + hgdir = au_hi(gparent->d_inode, bdst); + dput(gparent); + } + } + au_dtime_store(&dt, parent, h_parent, hdir, hgdir); + vfsub_args_init(&vargs, &ign, dlgt, /*force_unlink*/0); + err = au_do_cpup_wh(dentry, bdst, wh_dentry, file, len, &vargs); + if (unlikely(err)) + goto out_wh; + + AuDebugOn(!d_unhashed(dentry)); + /* dget first to force sillyrename on nfs */ + dget(wh_dentry); + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + err = vfsub_unlink(h_parent->d_inode, wh_dentry, &vargs); + if (unlikely(err)) { + AuIOErr("failed remove copied-up tmp file %.*s(%d)\n", + AuDLNPair(wh_dentry), err); + err = -EIO; + } + au_dtime_revert(&dt); + au_set_hi_wh(dentry->d_inode, bdst, wh_dentry); + + out_wh: + dput(wh_dentry); + out: + dput(parent); + AuTraceErr(err); + return err; +} + +struct au_cpup_wh_args { + int *errp; + struct dentry *dentry; + aufs_bindex_t bdst; + loff_t len; + struct file *file; +}; + +static void au_call_cpup_wh(void *args) +{ + struct au_cpup_wh_args *a = args; + *a->errp = au_cpup_wh(a->dentry, a->bdst, a->len, a->file); +} + +int au_sio_cpup_wh(struct dentry *dentry, aufs_bindex_t bdst, loff_t len, + struct file *file) +{ + int err, wkq_err; + struct dentry *parent, *h_tmp, *h_parent; + struct inode *dir, *h_dir, *h_tmpdir; + struct au_wbr *wbr; + + AuTraceEnter(); + parent = dget_parent(dentry); + dir = parent->d_inode; + IiMustAnyLock(dir); + + h_tmp = NULL; + h_parent = NULL; + h_dir = au_igrab(au_h_iptr(dir, bdst)); + h_tmpdir = h_dir; + if (unlikely(!h_dir->i_nlink)) { + DiMustWriteLock(parent); + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; + AuDebugOn(!wbr); + h_tmp = wbr->wbr_tmp; + + h_parent = dget(au_h_dptr(parent, bdst)); + au_set_h_dptr(parent, bdst, NULL); + au_set_h_dptr(parent, bdst, dget(h_tmp)); + h_tmpdir = h_tmp->d_inode; + au_set_h_iptr(dir, bdst, NULL, 0); + au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); + } + + if (!au_test_h_perm_sio + (h_tmpdir, MAY_EXEC | MAY_WRITE, + au_test_dlgt(au_mntflags(dentry->d_sb)))) + err = au_cpup_wh(dentry, bdst, len, file); + else { + struct au_cpup_wh_args args = { + .errp = &err, + .dentry = dentry, + .bdst = bdst, + .len = len, + .file = file + }; + wkq_err = au_wkq_wait(au_call_cpup_wh, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } + + /* todo: is this restore safe? */ + if (unlikely(h_tmp)) { + mutex_unlock(&h_tmpdir->i_mutex); + au_set_h_iptr(dir, bdst, NULL, 0); + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); + au_set_h_dptr(parent, bdst, NULL); + au_set_h_dptr(parent, bdst, h_parent); + } + iput(h_dir); + dput(parent); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * generic routine for both of copy-up and copy-down. + * Although I've tried building a path by dcsub, I gave up this approach. + * Since the ancestor directory may be moved/renamed during copy. + */ +/* cf. revalidate function in file.c */ +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg), + void *arg) +{ + int err, hinotify; + struct super_block *sb; + struct dentry *d, *parent, *h_parent, *real_parent; + struct au_pin pin; + + LKTRTrace("%.*s, b%d, parent i%lu\n", + AuDLNPair(dentry), bdst, (unsigned long)parent_ino(dentry)); + sb = dentry->d_sb; + AuDebugOn(au_test_ro(sb, bdst, NULL)); + err = 0; + parent = dget_parent(dentry); + IiMustWriteLock(parent->d_inode); + if (unlikely(IS_ROOT(parent))) + goto out; + + /* do not use au_dpage */ + real_parent = parent; + hinotify = !!au_opt_test(au_mntflags(sb), UDBA_INOTIFY); + while (1) { + dput(parent); + parent = dget_parent(dentry); + h_parent = au_h_dptr(parent, bdst); + if (h_parent) + goto out; /* success */ + + /* find top dir which is needed to cpup */ + do { + d = parent; + dput(parent); + parent = dget_parent(d); + di_read_lock_parent3(parent, !AuLock_IR); + h_parent = au_h_dptr(parent, bdst); + di_read_unlock(parent, !AuLock_IR); + } while (!h_parent); + + if (d != real_parent) + di_write_lock_child3(d); + + /* somebody else might create while we were sleeping */ + if (!au_h_dptr(d, bdst) || !au_h_dptr(d, bdst)->d_inode) { + if (au_h_dptr(d, bdst)) + au_update_dbstart(d); + + au_pin_init(&pin, d, /*di_locked*/0, + AuLsc_DI_PARENT3, AuLsc_I_PARENT2, hinotify); + err = au_do_pin(pin.pin + AuPin_PARENT, au_pin_gp(&pin), + bdst, hinotify); + if (!err) { + err = cp(d, bdst, h_parent, arg); + au_unpin(&pin); + } + } + + if (d != real_parent) + di_write_unlock(d); + if (unlikely(err)) + break; + } + + out: + dput(parent); + AuTraceErr(err); + return err; +} + +static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg) +{ + int err; + + err = au_sio_cpup_simple(dentry, bdst, -1, AuCpup_DTIME); + + AuTraceErr(err); + return err; +} + +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) +{ + int err; + + err = au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); + + AuTraceErr(err); + return err; +} + +int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) +{ + int err; + struct dentry *parent; + struct inode *dir; + + parent = dget_parent(dentry); + dir = parent->d_inode; + LKTRTrace("%.*s, b%d, parent i%lu\n", + AuDLNPair(dentry), bdst, dir->i_ino); + DiMustReadLock(parent); + IiMustReadLock(dir); + + err = 0; + if (au_h_iptr(dir, bdst)) + goto out; + + di_read_unlock(parent, AuLock_IR); + di_write_lock_parent(parent); + /* someone else might change our inode while we were sleeping */ + if (unlikely(!au_h_iptr(dir, bdst))) + err = au_cpup_dirs(dentry, bdst); + di_downgrade_lock(parent, AuLock_IR); + + out: + dput(parent); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/dcsub.h +++ linux-2.6.28/ubuntu/aufs/dcsub.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sub-routines for dentry cache + * + * $Id: dcsub.h,v 1.4 2008/07/21 02:54:22 sfjro Exp $ + */ + +#ifndef __AUFS_DCSUB_H__ +#define __AUFS_DCSUB_H__ + +#ifdef __KERNEL__ + +#include + +struct au_dpage { + int ndentry; + struct dentry **dentries; +}; + +struct au_dcsub_pages { + int ndpage; + struct au_dpage *dpages; +}; + +/* ---------------------------------------------------------------------- */ + +int au_dpages_init(struct au_dcsub_pages *dpages, gfp_t gfp); +void au_dpages_free(struct au_dcsub_pages *dpages); +typedef int (*au_dpages_test)(struct dentry *dentry, void *arg); +int au_dcsub_pages(struct au_dcsub_pages *dpages, struct dentry *root, + au_dpages_test test, void *arg); +int au_dcsub_pages_rev(struct au_dcsub_pages *dpages, struct dentry *dentry, + int do_include, au_dpages_test test, void *arg); +struct dentry *au_test_subdir(struct dentry *d1, struct dentry *d2); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DCSUB_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/Makefile +++ linux-2.6.28/ubuntu/aufs/Makefile @@ -0,0 +1,74 @@ +# AUFS Makefile for the Linux 2.6.25 and later +# $Id: Makefile,v 1.8 2008/08/04 00:32:21 sfjro Exp $ + +# the environment variables are not inherited since 2.6.23 +ifdef AUFS_EXTRA_CFLAGS +ccflags-y += ${AUFS_EXTRA_CFLAGS} +endif + +######################################## + +ifdef CONFIG_AUFS_RR_SQUASHFS +# cf. squashfs3.2-r2 and sqlzma patch. +ccflags-y += -DSQUASHFS_MAGIC=0x73717368 +ccflags-y += -DSQUASHFS_MAGIC_SWAP=0x68737173 +ccflags-y += -DSQUASHFS_MAGIC_LZMA=0x71736873 +ccflags-y += -DSQUASHFS_MAGIC_LZMA_SWAP=0x73687371 +endif + +# defined in ${srctree}/fs/fuse/inode.c +ccflags-$(CONFIG_AUFS_WORKAROUND_FUSE) += -DFUSE_SUPER_MAGIC=0x65735546 + +# defined in ${srctree}/fs/xfs/xfs_sb.h +# tristate +ifdef CONFIG_XFS_FS +ccflags-y += -DXFS_SB_MAGIC=0x58465342 +endif + +# defined in ${srctree}/mm/shmem.c in linux-2.6.26 and earlier +# tristate +ifdef CONFIG_TMPFS +ccflags-y += -DTMPFS_MAGIC=0x01021994 +endif + +# defined in ${srctree}fs/sysfs/mount.c +# bool +ccflags-$(CONFIG_SYSFS) += -DSYSFS_MAGIC=0x62656572 + +ifndef EXTRAVERSION +EXTRAVERSION = $(shell echo ${KERNELVERSION} | cut -f3- -d. | cut -f2- -d-) +endif +# for -mm tree, support the latest version only +ifneq ($(strip $(shell echo ${EXTRAVERSION} | fgrep -- mm)),) +ccflags-y += -DCONFIG_AUFS_UNIONFS22_PATCH -DCONFIG_AUFS_UNIONFS23_PATCH +endif + +-include $(dir $(lastword ${MAKEFILE_LIST}))priv.mk +#$(warning ${ccflags-y}) + +######################################## + +obj-$(CONFIG_AUFS) += aufs.o +aufs-y := module.o super.o sbinfo.o branch.o xino.o sysaufs.o opts.o \ + wkq.o vfsub.o dcsub.o \ + cpup.o whout.o plink.o wbr_policy.o \ + dentry.o dinfo.o \ + file.o f_op.o finfo.o \ + dir.o vdir.o \ + inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o iinfo.o \ + misc.o + +aufs-$(CONFIG_SYSFS) += sysfs.o +aufs-$(CONFIG_AUFS_BR_NFS) += br_nfs.o +aufs-$(CONFIG_AUFS_BR_XFS) += br_xfs.o +aufs-$(CONFIG_AUFS_WORKAROUND_FUSE) += br_fuse.o +aufs-$(CONFIG_AUFS_DLGT) += dlgt.o +aufs-$(CONFIG_AUFS_HINOTIFY) += hinotify.o +aufs-$(CONFIG_AUFS_HIN_OR_DLGT) += hin_or_dlgt.o +aufs-$(CONFIG_AUFS_HIN_OR_FUSE) += hin_or_fuse.o +aufs-$(CONFIG_AUFS_EXPORT) += export.o +aufs-$(CONFIG_AUFS_ROBR) += robr.o +# reserved for future use +#aufs-$(CONFIG_AUFS_XATTR) += xattr.o +aufs-$(CONFIG_AUFS_DEBUG) += debug.o +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o --- linux-2.6.28.orig/ubuntu/aufs/i_op_add.c +++ linux-2.6.28/ubuntu/aufs/i_op_add.c @@ -0,0 +1,754 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operations (add entry) + * + * $Id: i_op_add.c,v 1.14 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +/* + * final procedure of adding a new entry, except link(2). + * remove whiteout, instantiate, copyup the parent dir's times and size + * and update version. + * if it failed, re-create the removed whiteout. + */ +static int epilog(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct dentry *dentry) +{ + int err, rerr; + aufs_bindex_t bwh; + struct inode *inode, *h_dir; + struct dentry *wh; + struct au_ndx ndx; + struct super_block *sb; + + LKTRTrace("wh %p, %.*s\n", wh_dentry, AuDLNPair(dentry)); + + sb = dentry->d_sb; + bwh = -1; + if (wh_dentry) { + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ + IMustLock(h_dir); + AuDebugOn(au_h_iptr(dir, bindex) != h_dir); + bwh = au_dbwh(dentry); + err = au_wh_unlink_dentry(au_hi(dir, bindex), wh_dentry, dentry, + /*dlgt*/0); + if (unlikely(err)) + goto out; + } + + inode = au_new_inode(dentry); + if (!IS_ERR(inode)) { + d_instantiate(dentry, inode); + dir = dentry->d_parent->d_inode; /* dir inode is locked */ + IMustLock(dir); + /* or always cpup dir mtime? */ + if (au_ibstart(dir) == au_dbstart(dentry)) + au_cpup_attr_timesizes(dir); + dir->i_version++; + return 0; /* success */ + } + + err = PTR_ERR(inode); + if (!wh_dentry) + goto out; + + /* revert */ + ndx.flags = 0; + if (unlikely(au_test_dlgt(au_mntflags(sb)))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nfsmnt = au_nfsmnt(sb, bwh); + ndx.nd = NULL; + /* ndx.br = NULL; */ + /* dir inode is locked */ + wh = au_wh_create(dentry, bwh, wh_dentry->d_parent, &ndx); + rerr = PTR_ERR(wh); + if (IS_ERR(wh)) { + AuIOErr("%.*s reverting whiteout failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } else { + err = 0; + dput(wh); + } + + out: + AuTraceErr(err); + return err; +} + +/* + * simple tests for the adding inode operations. + * following the checks in vfs, plus the parent-child relationship. + */ +int au_may_add(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, int isdir, struct au_ndx *ndx) +{ + int err, exist; + struct dentry *h_dentry; + struct inode *h_inode; + umode_t h_mode; + + LKTRTrace("%.*s/%.*s, b%d, dir %d\n", + AuDLNPair(h_parent), AuDLNPair(dentry), bindex, isdir); + + exist = !!dentry->d_inode; + h_dentry = au_h_dptr(dentry, bindex); + h_inode = h_dentry->d_inode; + if (!exist) { + err = -EEXIST; + if (unlikely(h_inode)) + goto out; + } else { + /* rename(2) case */ + err = -EIO; + if (unlikely(!h_inode || !h_inode->i_nlink)) + goto out; + + h_mode = h_inode->i_mode; + if (!isdir) { + err = -EISDIR; + if (unlikely(S_ISDIR(h_mode))) + goto out; + } else if (unlikely(!S_ISDIR(h_mode))) { + err = -ENOTDIR; + goto out; + } + } + + err = -EIO; + /* expected parent dir is locked */ + if (unlikely(h_parent != h_dentry->d_parent)) + goto out; + err = 0; + + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), UDBA_INOTIFY))) { + struct dentry *h_latest; + struct qstr *qstr = &dentry->d_name; + + err = -EACCES; + if (unlikely(au_test_h_perm + (h_parent->d_inode, MAY_EXEC | MAY_WRITE, + au_ftest_ndx(ndx->flags, DLGT)))) + goto out; + + err = -EIO; + h_latest = au_sio_lkup_one(qstr->name, h_parent, qstr->len, + ndx); + err = PTR_ERR(h_latest); + if (IS_ERR(h_latest)) + goto out; + err = -EIO; + dput(h_latest); + if (h_latest == h_dentry) + err = 0; + } + + out: + AuTraceErr(err); + return err; +} + +/* + * initial procedure of adding a new entry. + * prepare writable branch and the parent dir, lock it, + * lookup whiteout for the new entry. + */ +static struct dentry* +lock_hdir_lkup_wh(struct dentry *dentry, struct au_dtime *dt, + struct dentry *src_dentry, struct au_pin *pin, + struct au_wr_dir_args *wr_dir_args) +{ + struct dentry *wh_dentry, *h_parent; + int err; + aufs_bindex_t bstart, bcpup; + struct au_ndx ndx; + struct super_block *sb; + unsigned int mnt_flags; + + LKTRTrace("%.*s, src %p\n", AuDLNPair(dentry), src_dentry); + + bstart = au_dbstart(dentry); + err = au_wr_dir(dentry, src_dentry, wr_dir_args); + bcpup = err; + wh_dentry = ERR_PTR(err); + if (unlikely(err < 0)) + goto out; + + sb = dentry->d_sb; + mnt_flags = au_mntflags(sb); + err = au_pin(pin, dentry, bcpup, /*di_locked*/1, + /*do_gp*/dt && au_opt_test(mnt_flags, UDBA_INOTIFY)); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out; + + ndx.nfsmnt = au_nfsmnt(sb, bcpup); + ndx.flags = 0; + if (unlikely(au_test_dlgt(mnt_flags))) + au_fset_ndx(ndx.flags, DLGT); + ndx.nd = NULL; + /* ndx.br = NULL; */ + /* ndx.nd_file = NULL; */ + + h_parent = au_pinned_h_parent(pin, bcpup); + if (!au_opt_test(mnt_flags, UDBA_NONE) && au_dbstart(dentry) == bcpup) { + struct nameidata nd; + + if (unlikely(ndx.nfsmnt)) { + /* todo: dirty? */ + ndx.nd = &nd; + ndx.br = au_sbr(sb, bcpup); + memset(&nd, 0, sizeof(nd)); + nd.flags = LOOKUP_CREATE; + nd.intent.open.flags = O_EXCL; + } + err = au_may_add(dentry, bcpup, h_parent, + au_ftest_wrdir(wr_dir_args->flags, ISDIR), + &ndx); + wh_dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_unpin; + ndx.nd = NULL; + ndx.br = NULL; + } + + if (dt) + au_dtime_store(dt, au_pinned_parent(pin), h_parent, + au_pinned_hdir(pin, bcpup), + au_pinned_hgdir(pin, bcpup)); + + wh_dentry = NULL; + if (/* bcpup != bstart || */ bcpup != au_dbwh(dentry)) + goto out; /* success */ + + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, &ndx); + + out_unpin: + if (IS_ERR(wh_dentry)) + au_unpin(pin); + out: + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +/* ---------------------------------------------------------------------- */ + +enum { Mknod, Symlink, Creat }; +struct simple_arg { + int type; + union { + struct { + int mode; + struct nameidata *nd; + } c; + struct { + const char *symname; + } s; + struct { + int mode; + dev_t dev; + } m; + } u; +}; + +static int add_simple(struct inode *dir, struct dentry *dentry, + struct simple_arg *arg) +{ + int err; + struct dentry *h_dentry, *wh_dentry, *parent; + struct inode *h_dir; + struct au_dtime dt; + struct vfsub_args vargs; + struct super_block *sb; + aufs_bindex_t bstart; + unsigned char created; + struct au_hin_ignore ign; + struct au_pin pin; + struct au_wr_dir_args wr_dir_args = { + .force_btgt = -1, + .flags = AuWrDir_ADD_ENTRY + }; + + LKTRTrace("type %d, %.*s\n", arg->type, AuDLNPair(dentry)); + IMustLock(dir); + + sb = dir->i_sb; + parent = dentry->d_parent; /* dir inode is locked */ + aufs_read_lock(dentry, AuLock_DW); + vfsub_args_init(&vargs, &ign, !!au_test_dlgt(au_mntflags(sb)), 0); + di_write_lock_parent(parent); + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, + &wr_dir_args); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + bstart = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bstart); + h_dir = au_pinned_h_dir(&pin); + vfsub_ign_hinode(&vargs, IN_CREATE, au_pinned_hdir(&pin, bstart)); + + switch (arg->type) { + case Creat: + AuDebugOn(au_test_nfs(h_dir->i_sb) && !arg->u.c.nd); + err = au_h_create(h_dir, h_dentry, arg->u.c.mode, &vargs, + arg->u.c.nd, au_nfsmnt(sb, bstart)); + break; + case Symlink: + err = vfsub_symlink(h_dir, h_dentry, arg->u.s.symname, + S_IALLUGO, &vargs); + break; + case Mknod: + err = vfsub_mknod(h_dir, h_dentry, arg->u.m.mode, arg->u.m.dev, + &vargs); + break; + default: + BUG(); + } + created = !err; + if (!err) + err = epilog(dir, bstart, wh_dentry, dentry); + + /* revert */ + if (unlikely(created && err && h_dentry->d_inode)) { + int rerr; + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, + au_pinned_hdir(&pin, bstart)); + rerr = vfsub_unlink(h_dir, h_dentry, &vargs); + if (rerr) { + AuIOErr("%.*s revert failure(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } + /* todo: inotify will be fired to the grand parent dir? */ + au_dtime_revert(&dt); + d_drop(dentry); + } + + au_unpin(&pin); + dput(wh_dentry); + + out: + if (unlikely(err)) { + au_update_dbstart(dentry); + d_drop(dentry); + } + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuTraceErr(err); + return err; +} + +int aufs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +{ + struct simple_arg arg = { + .type = Mknod, + .u.m = { + .mode = mode, + .dev = dev + } + }; + return add_simple(dir, dentry, &arg); +} + +int aufs_symlink(struct inode *dir, struct dentry *dentry, const char *symname) +{ + struct simple_arg arg = { + .type = Symlink, + .u.s.symname = symname + }; + return add_simple(dir, dentry, &arg); +} + +int aufs_create(struct inode *dir, struct dentry *dentry, int mode, + struct nameidata *nd) +{ + struct simple_arg arg = { + .type = Creat, + .u.c = { + .mode = mode, + .nd = nd + } + }; + return add_simple(dir, dentry, &arg); +} + +/* ---------------------------------------------------------------------- */ + +struct au_link_args { + aufs_bindex_t bdst, bsrc; + struct dentry *h_dentry; + struct dentry *src_parent, *parent; + struct au_pin pin; + struct au_hin_ignore ign; + struct vfsub_args vargs; + unsigned int mnt_flags; +}; + +static int au_cpup_before_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry, struct au_link_args *a) +{ + int err; + struct mutex *h_mtx; + const int hinotify = au_opt_test(a->mnt_flags, UDBA_INOTIFY); + + LKTRTrace("src %.*s, i%lu, dst %.*s\n", + AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); + + di_read_lock_parent(a->src_parent, AuLock_IR); + err = au_test_and_cpup_dirs(src_dentry, a->bdst); + if (unlikely(err)) + goto out; + + AuDebugOn(au_dbstart(src_dentry) != a->bsrc); + h_mtx = &au_h_dptr(src_dentry, a->bsrc)->d_inode->i_mutex; + err = au_pin(&a->pin, src_dentry, a->bdst, /*di_locked*/1, + /*do_gp*/hinotify); + if (unlikely(err)) + goto out; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + /* todo: no KEEPLINO because of noplink? */ + err = au_sio_cpup_simple(src_dentry, a->bdst, -1, + AuCpup_DTIME /* | AuCpup_KEEPLINO */); + mutex_unlock(h_mtx); + au_unpin(&a->pin); + + out: + di_read_unlock(a->src_parent, AuLock_IR); + AuTraceErr(err); + return err; +} + +static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a) +{ + int err; + struct inode *h_inode; + aufs_bindex_t bstart; + struct dentry *h_src_dentry; + + AuTraceEnter(); + AuDebugOn(au_dbstart(src_dentry) != a->bsrc); + + bstart = au_ibstart(src_dentry->d_inode); + h_inode = NULL; + if (bstart <= a->bdst) + h_inode = au_h_iptr(src_dentry->d_inode, a->bdst); + if (!h_inode || !h_inode->i_nlink) { + /* copyup src_dentry as the name of dentry. */ + au_set_dbstart(src_dentry, a->bdst); + au_set_h_dptr(src_dentry, a->bdst, dget(a->h_dentry)); + h_inode = au_h_dptr(src_dentry, a->bsrc)->d_inode; + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + err = au_sio_cpup_single(src_dentry, a->bdst, a->bsrc, -1, + AuCpup_KEEPLINO, a->parent); + mutex_unlock(&h_inode->i_mutex); + au_set_h_dptr(src_dentry, a->bdst, NULL); + au_set_dbstart(src_dentry, a->bsrc); + } else { + /* the inode of src_dentry already exists on a.bdst branch */ + h_src_dentry = d_find_alias(h_inode); + if (h_src_dentry) { + /* vfsub_args_reinit(&a->vargs); */ + vfsub_ign_hinode(&a->vargs, IN_CREATE, + au_pinned_hdir(&a->pin, a->bdst)); + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), + a->h_dentry, &a->vargs); + dput(h_src_dentry); + } else { + AuIOErr("no dentry found for i%lu on b%d\n", + h_inode->i_ino, a->bdst); + err = -EIO; + } + } + + if (!err) + au_plink_append(src_dentry->d_sb, src_dentry->d_inode, + a->h_dentry, a->bdst); + + AuTraceErr(err); + return err; +} + +int aufs_link(struct dentry *src_dentry, struct inode *dir, + struct dentry *dentry) +{ + int err, rerr; + struct dentry *wh_dentry, *h_src_dentry; + struct inode *inode; + struct au_dtime dt; + struct super_block *sb; + struct au_link_args *a; + struct au_wr_dir_args wr_dir_args = { + /* .force_btgt = -1, */ + .flags = AuWrDir_ADD_ENTRY + }; + + LKTRTrace("src %.*s, i%lu, dst %.*s\n", + AuDLNPair(src_dentry), dir->i_ino, AuDLNPair(dentry)); + IMustLock(dir); + inode = src_dentry->d_inode; + IMustLock(inode); + AuDebugOn(S_ISDIR(inode->i_mode)); + + err = -ENOMEM; + a = kzalloc(sizeof(*a), GFP_NOFS); + if (unlikely(!a)) + goto out; + + sb = dentry->d_sb; + a->parent = dentry->d_parent; /* dir inode is locked */ + aufs_read_and_write_lock2(dentry, src_dentry, /*AuLock_FLUSH*/0); + a->src_parent = dget_parent(src_dentry); + wr_dir_args.force_btgt = au_dbstart(src_dentry); + a->mnt_flags = au_mntflags(sb); + vfsub_args_init(&a->vargs, &a->ign, au_test_dlgt(a->mnt_flags), 0); + + di_write_lock_parent(a->parent); + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, src_dentry, &a->pin, + &wr_dir_args); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_unlock; + err = 0; + + a->bdst = au_dbstart(dentry); + a->h_dentry = au_h_dptr(dentry, a->bdst); + + /* todo: minor optimize, + their sb may be same while their bindex differs? */ + a->bsrc = au_dbstart(src_dentry); + if (au_opt_test(a->mnt_flags, PLINK)) { + if (a->bdst < a->bsrc + /* && h_src_dentry->d_sb != a->h_dentry->d_sb */) + err = au_cpup_or_link(src_dentry, a); + else { + h_src_dentry = au_h_dptr(src_dentry, a->bdst); + AuDebugOn(!h_src_dentry); + AuDebugOn(!h_src_dentry->d_inode); + vfsub_ign_hinode(&a->vargs, IN_CREATE, + au_pinned_hdir(&a->pin, a->bdst)); + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), + a->h_dentry, &a->vargs); + } + } else { + /* + * copyup src_dentry to the branch we process, + * and then link(2) to it. + */ + if (a->bdst < a->bsrc + /* && h_src_dentry->d_sb != a->h_dentry->d_sb */) { + au_unpin(&a->pin); + di_write_unlock(a->parent); + err = au_cpup_before_link(src_dentry, dir, dentry, a); + if (!err) { + di_write_lock_parent(a->parent); + err = au_pin + (&a->pin, dentry, a->bdst, + /*di_locked*/1, + /*do_gp*/au_opt_test(a->mnt_flags, + UDBA_INOTIFY)); + if (unlikely(err)) + goto out_wh; + } + } + if (!err) { + /* vfsub_args_reinit(&a->vargs); */ + vfsub_ign_hinode(&a->vargs, IN_CREATE, + au_pinned_hdir(&a->pin, a->bdst)); + h_src_dentry = au_h_dptr(src_dentry, a->bdst); + err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin), + a->h_dentry, &a->vargs); + } + } + if (unlikely(err)) + goto out_unpin; + + if (wh_dentry) { + err = au_wh_unlink_dentry(au_pinned_hdir(&a->pin, a->bdst), + wh_dentry, dentry, /*dlgt*/0); + if (unlikely(err)) + goto out_revert; + } + +#if 0 /* cannot support it */ + /* fuse has different memory inode for the same inode number */ + if (unlikely(au_test_fuse(a->h_dentry->d_sb))) { + LKTRLabel(here); + d_drop(a->h_dentry); + /*d_drop(h_src_dentry); + d_drop(src_dentry);*/ + inc_nlink(a->inode); + a->inode->i_ctime = dir->i_ctime; + } +#endif + + dir->i_version++; + if (au_ibstart(dir) == au_dbstart(dentry)) + au_cpup_attr_timesizes(dir); + if (!d_unhashed(a->h_dentry) + /* || h_old_inode->i_nlink <= nlink */ + /* || SB_NFS(h_src_dentry->d_sb) */) { + d_instantiate(dentry, au_igrab(inode)); + inc_nlink(inode); + inode->i_ctime = dir->i_ctime; + } else + /* nfs case (< 2.6.15) */ + d_drop(dentry); + goto out_unpin; /* success */ + + out_revert: + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_DELETE, au_pinned_hdir(&a->pin, a->bdst)); + rerr = vfsub_unlink(au_pinned_h_dir(&a->pin), a->h_dentry, &a->vargs); + if (!rerr) + goto out_dt; + AuIOErr("%.*s reverting failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + out_dt: + d_drop(dentry); + au_dtime_revert(&dt); + out_unpin: + au_unpin(&a->pin); + out_wh: + dput(wh_dentry); + out_unlock: + if (unlikely(err)) { + au_update_dbstart(dentry); + d_drop(dentry); + } + di_write_unlock(a->parent); + dput(a->src_parent); + aufs_read_and_write_unlock2(dentry, src_dentry); + kfree(a); + out: + AuTraceErr(err); + return err; +} + +int aufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) +{ + int err, rerr; + struct dentry *h_dentry, *wh_dentry, *parent, *opq_dentry; + struct mutex *h_mtx; + struct au_dtime dt; + aufs_bindex_t bindex; + unsigned char diropq, dlgt; + unsigned int mnt_flags; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_pin pin; + struct au_wr_dir_args wr_dir_args = { + .force_btgt = -1, + .flags = AuWrDir_ADD_ENTRY | AuWrDir_ISDIR + }; + + LKTRTrace("i%lu, %.*s, mode 0%o\n", + dir->i_ino, AuDLNPair(dentry), mode); + IMustLock(dir); +#if 0 + if (IS_DEADDIR(dir)) { + AuDbg("here\n"); + return -ENOENT; + } +#endif + + aufs_read_lock(dentry, AuLock_DW); + parent = dentry->d_parent; /* dir inode is locked */ + mnt_flags = au_mntflags(dentry->d_sb); + dlgt = !!au_test_dlgt(mnt_flags); + vfsub_args_init(&vargs, &ign, dlgt, 0); + + di_write_lock_parent(parent); + wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, + &wr_dir_args); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + bindex = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bindex); + vfsub_ign_hinode(&vargs, IN_CREATE, au_pinned_hdir(&pin, bindex)); + err = vfsub_mkdir(au_pinned_h_dir(&pin), h_dentry, mode, &vargs); + if (unlikely(err)) + goto out_unlock; + + /* make the dir opaque */ + diropq = 0; + h_mtx = &h_dentry->d_inode->i_mutex; + if (wh_dentry || au_opt_test(mnt_flags, ALWAYS_DIROPQ)) { + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + opq_dentry = au_diropq_create(dentry, bindex, /*dlgt*/0); + mutex_unlock(h_mtx); + err = PTR_ERR(opq_dentry); + if (IS_ERR(opq_dentry)) + goto out_dir; + dput(opq_dentry); + diropq = 1; + } + + err = epilog(dir, bindex, wh_dentry, dentry); + if (!err) { + inc_nlink(dir); + goto out_unlock; /* success */ + } + + /* revert */ + if (diropq) { + LKTRLabel(revert opq); + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + rerr = au_diropq_remove(dentry, bindex, dlgt); + mutex_unlock(h_mtx); + if (rerr) { + AuIOErr("%.*s reverting diropq failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } + } + + out_dir: + LKTRLabel(revert dir); + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, au_pinned_hdir(&pin, bindex)); + rerr = vfsub_rmdir(au_pinned_h_dir(&pin), h_dentry, &vargs); + if (rerr) { + AuIOErr("%.*s reverting dir failed(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } + d_drop(dentry); + au_dtime_revert(&dt); + out_unlock: + au_unpin(&pin); + dput(wh_dentry); + out: + if (unlikely(err)) { + au_update_dbstart(dentry); + d_drop(dentry); + } + di_write_unlock(parent); + aufs_read_unlock(dentry, AuLock_DW); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/dir.h +++ linux-2.6.28/ubuntu/aufs/dir.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * directory operations + * + * $Id: dir.h,v 1.3 2008/05/26 04:04:23 sfjro Exp $ + */ + +#ifndef __AUFS_DIR_H__ +#define __AUFS_DIR_H__ + +#ifdef __KERNEL__ + +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* need to be faster and smaller */ + +/* todo: changeable? */ +#define AuSize_DEBLK 512 +#define AuSize_NHASH 32 +#if AuSize_DEBLK < NAME_MAX || PAGE_SIZE < AuSize_DEBLK +#error invalid size AuSize_DEBLK +#endif + +typedef char au_vdir_deblk_t[AuSize_DEBLK]; + +struct au_nhash { + struct hlist_head heads[AuSize_NHASH]; +}; + +struct au_vdir_destr { + unsigned char len; + char name[0]; +} __packed; + +struct au_vdir_dehstr { + struct hlist_node hash; + struct au_vdir_destr *str; +}; + +struct au_vdir_de { + ino_t de_ino; + unsigned char de_type; + /* caution: packed */ + struct au_vdir_destr de_str; +} __packed; + +struct au_vdir_wh { + struct hlist_node wh_hash; + aufs_bindex_t wh_bindex; +#ifdef CONFIG_AUFS_SHWH + ino_t wh_ino; + unsigned char wh_type; + /* caution: packed */ +#endif + struct au_vdir_destr wh_str; +} __packed; + +union au_vdir_deblk_p { + unsigned char *p; + au_vdir_deblk_t *deblk; + struct au_vdir_de *de; +}; + +struct au_vdir { + au_vdir_deblk_t **vd_deblk; + int vd_nblk; + struct { + int i; + union au_vdir_deblk_p p; + } vd_last; + + unsigned long vd_version; + unsigned long vd_jiffy; +}; + +/* ---------------------------------------------------------------------- */ + +/* dir.c */ +extern struct file_operations aufs_dir_fop; +int au_test_empty_lower(struct dentry *dentry); +int au_test_empty(struct dentry *dentry, struct au_nhash *whlist); + +/* vdir.c */ +struct au_nhash *au_nhash_new(gfp_t gfp); +void au_nhash_del(struct au_nhash *nhash); +void au_nhash_init(struct au_nhash *nhash); +void au_nhash_move(struct au_nhash *dst, struct au_nhash *src); +void au_nhash_fin(struct au_nhash *nhash); +int au_nhash_test_longer_wh(struct au_nhash *whlist, aufs_bindex_t btgt, + int limit); +int au_nhash_test_known_wh(struct au_nhash *whlist, char *name, int namelen); +int au_nhash_append_wh(struct au_nhash *whlist, char *name, int namelen, + ino_t ino, unsigned int d_type, aufs_bindex_t bindex, + unsigned char shwh); +void au_vdir_free(struct au_vdir *vdir); +int au_vdir_init(struct file *file); +int au_vdir_fill_de(struct file *file, void *dirent, filldir_t filldir); + +/* ---------------------------------------------------------------------- */ + +static inline +void au_shwh_init_wh(struct au_vdir_wh *wh, ino_t ino, unsigned char d_type) +{ +#ifdef CONFIG_AUFS_SHWH + wh->wh_ino = ino; + wh->wh_type = d_type; +#endif +} + +static inline void au_add_nlink(struct inode *dir, struct inode *h_dir) +{ + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); + dir->i_nlink += h_dir->i_nlink - 2; + if (unlikely(h_dir->i_nlink < 2)) + dir->i_nlink += 2; +} + +static inline void au_sub_nlink(struct inode *dir, struct inode *h_dir) +{ + AuDebugOn(!S_ISDIR(dir->i_mode) || !S_ISDIR(h_dir->i_mode)); + dir->i_nlink -= h_dir->i_nlink - 2; + if (unlikely(h_dir->i_nlink < 2)) + dir->i_nlink -= 2; +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DIR_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/i_op_ren.c +++ linux-2.6.28/ubuntu/aufs/i_op_ren.c @@ -0,0 +1,1211 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode operation (rename entry) + * todo: this is crazy monster + * + * $Id: i_op_ren.c,v 1.14 2008/09/22 03:52:12 sfjro Exp $ + */ + +#include "aufs.h" + +enum { SRC, DST }; + +#define AuRen_ISDIR 1 +#define AuRen_ISSAMEDIR (1 << 1) +#define AuRen_WHSRC (1 << 2) +#define AuRen_WHDST (1 << 3) +#define AuRen_DLGT (1 << 4) +#define AuRen_VFSLOCK (1 << 5) +#define AuRen_PINNED (1 << 6) +#define au_ftest_ren(flags, name) ((flags) & AuRen_##name) +#define au_fset_ren(flags, name) { (flags) |= AuRen_##name; } +#define au_fclr_ren(flags, name) { (flags) &= ~AuRen_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuRen_DLGT +#define AuRen_DLGT 0 +#endif + +struct au_ren_args { + /* original args */ + struct dentry *src_dentry, *dentry; + struct inode *src_dir, *dir; + + struct dentry *h_dentry[2], *h_parent[2], *h_trap, *h_locked[2]; + /* todo: remove them */ + struct dentry *parent[2], *gparent[2]; + struct au_pin pin[2]; + struct au_nhash whlist; + aufs_bindex_t btgt, bstart[2]; + /* do_rename() only */ + unsigned char need_diropq, bycpup; + struct super_block *sb; + unsigned int flags; + unsigned int mnt_flags; + struct au_ndx ndx; + + /* do_rename() only */ +#ifdef CONFIG_AUFS_BR_NFS + struct au_hin_ignore ign[3]; +#else + struct au_hin_ignore ign[2]; +#endif + struct vfsub_args vargs; + struct au_whtmp_rmdir_args *thargs; + struct dentry *wh_dentry[2], *h_dst, *h_src; +}; + +/* ---------------------------------------------------------------------- */ + +#define RevertFailure(fmt, args...) do { \ + AuIOErrWhck("revert failure: " fmt " (%d, %d)\n", \ + ##args, err, rerr); \ + err = -EIO; \ + } while (0) + +static noinline_for_stack +void au_ren_rev_diropq(int err, struct au_ren_args *a) +{ + int rerr; + struct mutex *h_mtx; + + /* lock inode simply since inotify is not set to h_inode. */ + h_mtx = &au_h_dptr(a->src_dentry, a->btgt)->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + rerr = au_diropq_remove(a->src_dentry, a->btgt, + au_ftest_ren(a->flags, DLGT)); + mutex_unlock(h_mtx); + if (rerr) + RevertFailure("remove diropq %.*s", AuDLNPair(a->src_dentry)); +} + +static noinline_for_stack +void au_ren_rev_rename(int err, struct au_ren_args *a) +{ + int rerr; + struct dentry *h_d; + struct qstr *name = &a->src_dentry->d_name; + + h_d = au_lkup_one(name->name, a->h_parent[SRC], name->len, &a->ndx); + rerr = PTR_ERR(h_d); + if (IS_ERR(h_d)) { + RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry)); + return; + } + + AuDebugOn(h_d->d_inode); + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_MOVED_FROM, au_pinned_hdir(a->pin + DST, + a->btgt)); + vfsub_ign_hinode(&a->vargs, IN_MOVED_TO, au_pinned_hdir(a->pin + SRC, + a->btgt)); + rerr = vfsub_rename(au_pinned_h_dir(a->pin + DST), + au_h_dptr(a->src_dentry, a->btgt), + au_pinned_h_dir(a->pin + SRC), h_d, &a->vargs); + d_drop(h_d); + dput(h_d); + /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ + if (rerr) + RevertFailure("rename %.*s", AuDLNPair(a->src_dentry)); +} + +static noinline_for_stack +void au_ren_rev_cpup(int err, struct au_ren_args *a) +{ + int rerr; + + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_DELETE, au_pinned_hdir(a->pin + DST, + a->btgt)); + rerr = vfsub_unlink(au_pinned_h_dir(a->pin + DST), a->h_dentry[DST], + &a->vargs); + au_set_h_dptr(a->src_dentry, a->btgt, NULL); + au_set_dbstart(a->src_dentry, a->bstart[SRC]); + if (rerr) + RevertFailure("unlink %.*s", AuDLNPair(a->h_dentry[DST])); +} + +static noinline_for_stack +void au_ren_rev_whtmp(int err, struct au_ren_args *a) +{ + int rerr; + struct dentry *h_d; + struct mutex *h_mtx; + struct qstr *name = &a->dentry->d_name; + + h_d = au_lkup_one(name->name, a->h_parent[DST], name->len, &a->ndx); + rerr = PTR_ERR(h_d); + if (IS_ERR(h_d)) { + RevertFailure("lookup %.*s", AuLNPair(name)); + return; + } + if (h_d->d_inode) { + d_drop(h_d); + dput(h_d); + return; + } + + h_mtx = &a->h_dst->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + au_hin_resume(au_hi(a->src_dentry->d_inode, a->btgt)); + mutex_unlock(h_mtx); + vfsub_args_reinit(&a->vargs); + vfsub_ign_hinode(&a->vargs, IN_MOVED_TO | IN_MOVED_FROM, + au_pinned_hdir(a->pin + DST, a->btgt)); + rerr = vfsub_rename(au_pinned_h_dir(a->pin + DST), a->h_dst, + au_pinned_h_dir(a->pin + DST), h_d, &a->vargs); + d_drop(h_d); + dput(h_d); + if (!rerr) { + au_set_h_dptr(a->dentry, a->btgt, NULL); + au_set_h_dptr(a->dentry, a->btgt, dget(a->h_dst)); + } else + RevertFailure("rename %.*s", AuDLNPair(a->h_dst)); +} + +static noinline_for_stack +void au_ren_rev_whsrc(int err, struct au_ren_args *a) +{ + int rerr; + + rerr = au_wh_unlink_dentry(au_pinned_hdir(a->pin + SRC, a->btgt), + a->wh_dentry[SRC], a->src_dentry, /*dlgt*/0); + if (rerr) + RevertFailure("unlink %.*s", AuDLNPair(a->wh_dentry[SRC])); +} +#undef RevertFailure + +/* ---------------------------------------------------------------------- */ + +static /* noinline_for_stack */ +int au_ren_or_cpup(struct au_ren_args *a) +{ + int err; + + AuTraceEnter(); + + if (au_dbstart(a->src_dentry) == a->btgt) { + if (a->need_diropq && au_dbdiropq(a->src_dentry) == a->btgt) + a->need_diropq = 0; + vfsub_ign_hinode(&a->vargs, IN_MOVED_FROM, + au_pinned_hdir(a->pin + SRC, a->btgt)); + vfsub_ign_hinode(&a->vargs, IN_MOVED_TO, + au_pinned_hdir(a->pin + DST, a->btgt)); + /* nfs_rename() calls d_delete() */ + if (au_test_nfs(au_pinned_h_dir(a->pin + DST)->i_sb) + && a->h_dentry[DST]->d_inode + && (S_ISDIR(a->h_dentry[DST]->d_inode->i_mode) + || atomic_read(&a->h_dentry[DST]->d_count) <= 2)) + vfsub_ign_hinode(&a->vargs, IN_DELETE, + au_pinned_hdir(a->pin + DST, a->btgt)); + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); + err = vfsub_rename(au_pinned_h_dir(a->pin + SRC), + au_h_dptr(a->src_dentry, a->btgt), + au_pinned_h_dir(a->pin + DST), + a->h_dentry[DST], &a->vargs); + } else { + struct mutex *h_mtx = &a->h_dentry[SRC]->d_inode->i_mutex; + + a->bycpup = 1; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + au_set_dbstart(a->src_dentry, a->btgt); + au_set_h_dptr(a->src_dentry, a->btgt, dget(a->h_dentry[DST])); + err = au_sio_cpup_single(a->src_dentry, a->btgt, a->bstart[SRC], + -1, !AuCpup_DTIME, a->parent[DST]); + if (unlikely(err)) { + au_set_h_dptr(a->src_dentry, a->btgt, NULL); + au_set_dbstart(a->src_dentry, a->bstart[SRC]); + } + mutex_unlock(h_mtx); + } + + return err; +} + +static /* noinline_for_stack */ +int au_ren_del_whtmp(struct au_ren_args *a) +{ + int err; + + AuTraceEnter(); + + if (au_test_nfs(a->h_dst->d_sb) + || !au_nhash_test_longer_wh(&a->whlist, a->btgt, + au_sbi(a->sb)->si_dirwh)) { + err = au_whtmp_rmdir(a->dir, a->btgt, a->h_dst, &a->whlist); + if (unlikely(err)) + AuWarn("failed removing whtmp dir %.*s (%d), " + "ignored.\n", AuDLNPair(a->h_dst), err); + } else { + au_whtmp_kick_rmdir(a->dir, a->btgt, a->h_dst, &a->whlist, + a->thargs); + dput(a->h_dst); + a->thargs = NULL; + } + + return 0; +} + +static /* noinline_for_stack */ +int au_ren_diropq(struct au_ren_args *a) +{ + int err; + struct dentry *diropq; + struct mutex *h_mtx; + + AuTraceEnter(); + + err = 0; + h_mtx = &au_h_dptr(a->src_dentry, a->btgt)->d_inode->i_mutex; + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + diropq = au_diropq_create(a->src_dentry, a->btgt, + au_ftest_ren(a->flags, DLGT)); + mutex_unlock(h_mtx); + if (IS_ERR(diropq)) + err = PTR_ERR(diropq); + dput(diropq); + + return err; +} + +static /* noinline_for_stack */ +int do_rename(struct au_ren_args *a) +{ + int err; + aufs_bindex_t bindex, bend; + struct dentry *h_d; + + LKTRTrace("%.*s/%.*s, %.*s/%.*s, " + "hd{%p, %p}, hp{%p, %p}, wh %p, btgt %d, bstart{%d, %d}, " + "flags 0x%x\n", + AuDLNPair(a->parent[SRC]), AuDLNPair(a->src_dentry), + AuDLNPair(a->parent[DST]), AuDLNPair(a->dentry), + a->h_dentry[SRC], a->h_dentry[DST], + a->h_parent[SRC], a->h_parent[DST], + &a->whlist, a->btgt, + a->bstart[SRC], a->bstart[DST], + a->flags); + + /* prepare workqueue args */ + if (au_ftest_ren(a->flags, ISDIR) && a->h_dentry[DST]->d_inode) { + err = -ENOMEM; + a->thargs = kmalloc(sizeof(*a->thargs), GFP_NOFS); + if (unlikely(!a->thargs)) + goto out; + a->h_dst = dget(a->h_dentry[DST]); + } + + a->ndx.nfsmnt = au_nfsmnt(a->sb, a->btgt); + if (unlikely(au_ftest_ren(a->flags, DLGT))) + au_fset_ndx(a->ndx.flags, DLGT); + + /* create whiteout for src_dentry */ + if (au_ftest_ren(a->flags, WHSRC)) { + a->wh_dentry[SRC] = au_wh_create(a->src_dentry, a->btgt, + a->h_parent[SRC], &a->ndx); + err = PTR_ERR(a->wh_dentry[SRC]); + if (IS_ERR(a->wh_dentry[SRC])) + goto out_thargs; + } + + /* lookup whiteout for dentry */ + if (au_ftest_ren(a->flags, WHDST)) { + h_d = au_wh_lkup(a->h_parent[DST], &a->dentry->d_name, &a->ndx); + err = PTR_ERR(h_d); + if (IS_ERR(h_d)) + goto out_whsrc; + if (!h_d->d_inode) + dput(h_d); + else + a->wh_dentry[DST] = h_d; + } + + /* rename dentry to tmpwh */ + if (a->thargs) { + struct au_hinode *hinode; + + AuDbgDentry(a->h_dentry[DST]); + err = au_whtmp_ren(a->dir, a->btgt, a->h_dentry[DST]); + if (unlikely(err)) + goto out_whdst; + AuDbgDentry(a->h_dentry[DST]); + hinode = au_hi(a->dentry->d_inode, a->btgt); + /* todo: bad approach? */ + mutex_lock_nested(&hinode->hi_inode->i_mutex, AuLsc_I_CHILD); + au_hin_suspend(hinode); + mutex_unlock(&hinode->hi_inode->i_mutex); + au_set_h_dptr(a->dentry, a->btgt, NULL); + AuDbgDentry(a->h_dentry[DST]); + err = au_lkup_neg(a->dentry, a->btgt); + if (unlikely(err)) + goto out_whtmp; + a->h_dentry[DST] = au_h_dptr(a->dentry, a->btgt); + } + + /* cpup src */ + if (a->h_dentry[DST]->d_inode && a->bstart[SRC] != a->btgt) { + struct mutex *h_mtx = &a->h_dentry[SRC]->d_inode->i_mutex; + + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + err = au_sio_cpup_simple(a->src_dentry, a->btgt, -1, + !AuCpup_DTIME); + mutex_unlock(h_mtx); + if (unlikely(err)) + goto out_whtmp; + } + + /* rename by vfs_rename or cpup */ + a->need_diropq = au_ftest_ren(a->flags, ISDIR) + && (a->wh_dentry[DST] + || au_dbdiropq(a->dentry) == a->btgt + /* hide the lower to keep xino */ + || a->btgt < au_dbend(a->dentry) + || au_opt_test(a->mnt_flags, ALWAYS_DIROPQ)); + a->bycpup = 0; + vfsub_args_init(&a->vargs, a->ign, au_ftest_ren(a->flags, DLGT), 0); + err = au_ren_or_cpup(a); + if (unlikely(err)) + goto out_whtmp; + + /* make dir opaque */ + if (a->need_diropq) { + err = au_ren_diropq(a); + if (unlikely(err)) + goto out_rename; + } + + /* update target timestamps */ + AuDebugOn(au_dbstart(a->src_dentry) != a->btgt); + a->h_src = au_h_dptr(a->src_dentry, a->btgt); + au_update_fuse_h_inode(NULL, a->h_src); /*ignore*/ + /* fsstack_copy_attr_atime(a->src_dentry->d_inode, a->h_src->d_inode); */ + a->src_dentry->d_inode->i_ctime = a->h_src->d_inode->i_ctime; + + /* remove whiteout for dentry */ + if (a->wh_dentry[DST]) { + err = au_wh_unlink_dentry(au_pinned_hdir(a->pin + DST, a->btgt), + a->wh_dentry[DST], a->dentry, + /*dlgt*/0); + if (unlikely(err)) + goto out_diropq; + } + + /* remove whtmp */ + if (a->thargs) + /* ignore this error */ + au_ren_del_whtmp(a); + + err = 0; + goto out_success; + + out_diropq: + if (a->need_diropq) + au_ren_rev_diropq(err, a); + out_rename: + if (!a->bycpup) + au_ren_rev_rename(err, a); + else + au_ren_rev_cpup(err, a); + out_whtmp: + if (a->thargs) + au_ren_rev_whtmp(err, a); + out_whdst: + dput(a->wh_dentry[DST]); + a->wh_dentry[DST] = NULL; + out_whsrc: + if (a->wh_dentry[SRC]) + au_ren_rev_whsrc(err, a); + d_drop(a->src_dentry); + bend = au_dbend(a->src_dentry); + for (bindex = au_dbstart(a->src_dentry); bindex <= bend; bindex++) { + h_d = au_h_dptr(a->src_dentry, bindex); + if (h_d) + d_drop(h_d); + } + d_drop(a->dentry); + bend = au_dbend(a->dentry); + for (bindex = au_dbstart(a->dentry); bindex <= bend; bindex++) { + h_d = au_h_dptr(a->dentry, bindex); + if (h_d) + d_drop(h_d); + } + au_update_dbstart(a->dentry); + if (a->thargs) + d_drop(a->h_dst); + out_success: + dput(a->wh_dentry[SRC]); + dput(a->wh_dentry[DST]); + out_thargs: + if (a->thargs) { + dput(a->h_dst); + kfree(a->thargs); + } + out: + AuTraceErr(err); + return err; +} + +/* + * test if @dentry dir can be rename destination or not. + * success means, it is a logically empty dir. + */ +static int may_rename_dstdir(struct dentry *dentry, aufs_bindex_t btgt, + struct au_nhash *whlist) +{ + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + return au_test_empty(dentry, whlist); +} + +/* + * test if @dentry dir can be rename source or not. + * if it can, return 0 and @children is filled. + * success means, + * - or, it is a logically empty dir. + * - or, it exists on writable branch and has no children including whiteouts + * on the lower branch. + */ +static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt) +{ + int err; + aufs_bindex_t bstart; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + bstart = au_dbstart(dentry); + if (bstart != btgt) { + struct au_nhash *whlist; + + whlist = au_nhash_new(GFP_NOFS); + err = PTR_ERR(whlist); + if (IS_ERR(whlist)) + goto out; + err = au_test_empty(dentry, whlist); + au_nhash_del(whlist); + goto out; + } + + if (bstart == au_dbtaildir(dentry)) + return 0; /* success */ + + err = au_test_empty_lower(dentry); + + out: + if (/* unlikely */(err == -ENOTEMPTY)) { + AuWarn1("renaming dir who has child(ren) on multiple branches," + " is not supported\n"); + err = -EXDEV; + } + AuTraceErr(err); + return err; +} + +/* mainly for link(2) and rename(2) */ +int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) +{ + aufs_bindex_t bdiropq, bwh; + struct dentry *parent; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), btgt); + parent = dentry->d_parent; + IMustLock(parent->d_inode); /* dir is locked */ + + bdiropq = au_dbdiropq(parent); + bwh = au_dbwh(dentry); + if (au_br_rdonly(au_sbr(dentry->d_sb, btgt)) + || (0 <= bdiropq && bdiropq < btgt) + || (0 <= bwh && bwh < btgt)) + btgt = -1; + + LKTRTrace("btgt %d\n", btgt); + return btgt; +} + +/* + * simple tests for rename. + * following the checks in vfs, plus the parent-child relationship. + */ +static int au_may_ren(struct au_ren_args *a) +{ + int err; + struct inode *h_inode; + + AuTraceEnter(); + + if (a->bstart[SRC] == a->btgt) { + err = au_may_del(a->src_dentry, a->btgt, a->h_parent[SRC], + au_ftest_ren(a->flags, ISDIR), &a->ndx); + if (unlikely(err)) + goto out; + err = -EINVAL; + if (unlikely(a->h_dentry[SRC] == a->h_trap)) + goto out; + } + + err = 0; + if (a->bstart[DST] != a->btgt) + goto out; + + err = -EIO; + h_inode = a->h_dentry[DST]->d_inode; + if (!a->dentry->d_inode) { + if (unlikely(h_inode)) + goto out; + err = au_may_add(a->dentry, a->btgt, a->h_parent[DST], + au_ftest_ren(a->flags, ISDIR), &a->ndx); + } else { + if (unlikely(!h_inode || !h_inode->i_nlink)) + goto out; + err = au_may_del(a->dentry, a->btgt, a->h_parent[DST], + au_ftest_ren(a->flags, ISDIR), &a->ndx); + if (unlikely(err)) + goto out; + err = -ENOTEMPTY; + if (unlikely(a->h_dentry[DST] == a->h_trap)) + goto out; + err = 0; + } + + out: + if (unlikely(err == -ENOENT || err == -EEXIST)) + err = -EIO; + AuTraceErr(err); + return err; +} + +/* + * locking order + * (VFS) + * - src_dir and dir by lock_rename() + * - inode if exitsts + * (aufs) + * - lock all + * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, + * + si_read_lock + * + di_write_lock2_child() + * + di_write_lock_child() + * + ii_write_lock_child() + * + di_write_lock_child2() + * + ii_write_lock_child2() + * + src_parent and parent + * + di_write_lock_parent() + * + ii_write_lock_parent() + * + di_write_lock_parent2() + * + ii_write_lock_parent2() + * + if udab=inotify is specified, lock grand parents (crazy) + * + di_read_lock_gparent() + * + ii_read_lock_gparent() + * + di_read_lock_gparent2() + * + ii_read_lock_gparent2() + * + mutex_lock_gparent() + * + mutex_lock_gparent2() + * + lower src_dir and dir by vfsub_lock_rename()? + * + verify the every relations between child, parent and grand parent. if any + * of them failed, unlock all and return -EBUSY. + */ +static void au_ren_pin_init(struct au_pin *first, struct dentry *d1, + struct au_pin *next, struct dentry *d2) +{ + AuTraceEnter(); + + /* AuLsc_DI_PARENT3 is for higher gparent initially */ + au_pin_init(first, d1, /*di_locked*/1, AuLsc_DI_PARENT2, + AuLsc_I_PARENT2, /*do_gp*/1); + /* AuLsc_DI_PARENT4 is for lower gparent initially */ + au_pin_init(next, d2, /*di_locked*/1, AuLsc_DI_PARENT3, + AuLsc_I_PARENT4, /*do_gp*/1); +} + +static void au_ren_fake_pin(struct au_ren_args *a) +{ + int i; + struct au_pin1 *p; + struct inode *h_i; + + AuTraceEnter(); + + /* they increment the ref counter */ + for (i = 0; i < 2; i++) { + p = a->pin[i].pin + AuPin_PARENT; + au_pin_set_parent(a->pin + i, a->parent[i]); + dput(a->parent[i]); + h_i = a->h_parent[i]->d_inode; + au_pin_set_h_dir(a->pin + i, h_i); + iput(h_i); + + if (!a->gparent[i]) { + au_pin_set_gparent(a->pin + i, NULL); + au_pin_set_h_gdir(a->pin + i, NULL); + } else { + au_pin_set_gparent(a->pin + i, a->gparent[i]); + dput(a->gparent[i]); + h_i = au_h_iptr(a->gparent[i]->d_inode, a->btgt); + au_pin_set_h_gdir(a->pin + i, h_i); + iput(h_i); + } + } +} + +/* crazy */ +/* cf. i_op.c: au_do_pin() */ +static int au_ren_pin4(int higher, int lower, struct au_ren_args *a) +{ + int err, i, lsc; + struct au_pin *p; + struct au_pin1 *p4[4]; + struct inode *h_dir; + + LKTRTrace("%d, %d\n", higher, lower); + + p = a->pin + higher; + p4[0] = au_pin_gp(p); /* highest */ + p4[1] = p->pin + AuPin_PARENT; + p = a->pin + lower; + p4[2] = au_pin_gp(p); + p4[3] = p->pin + AuPin_PARENT; + + if (a->gparent[higher]) { + au_pin_do_set_parent(p4[0], a->gparent[higher]); + au_pin_do_set_dentry(p4[0], a->parent[higher]); + } + au_pin_do_set_parent(p4[1], a->parent[higher]); + if (a->gparent[lower]) { + au_pin_do_set_parent(p4[2], a->gparent[lower]); + au_pin_do_set_dentry(p4[2], a->parent[lower]); + } + au_pin_do_set_parent(p4[3], a->parent[lower]); + + DiMustWriteLock(p4[3]->parent); + di_write_unlock(p4[1]->parent); + if (p4[2]->parent) + di_read_lock_parent2(p4[2]->parent, AuLock_IR); + di_write_lock_parent3(p4[1]->parent); + if (p4[0]->parent) + di_read_lock_parent4(p4[0]->parent, AuLock_IR); + + lsc = AuLsc_I_PARENT; + for (i = 0; i < 4; i++, lsc++) { + if (p4[i]->parent) { + h_dir = au_h_iptr(p4[i]->parent->d_inode, a->btgt); + au_pin_do_set_h_dir(p4[i], h_dir); + mutex_lock_nested(&h_dir->i_mutex, lsc); + } + } + + err = 0; + AuTraceErr(err); + return err; +} + +static struct dentry *au_ren_pin3(int higher, int lower, struct au_ren_args *a) +{ + struct dentry *h_trap; + struct au_pin *p; + int err; + + LKTRTrace("%d, %d\n", higher, lower); + + p = a->pin + higher; + err = au_do_pin(p->pin + AuPin_PARENT, au_pin_gp(p), a->btgt, + /*do_gp*/1); + h_trap = ERR_PTR(err); + if (unlikely(err)) + goto out; + p = a->pin + lower; + err = au_do_pin(p->pin + AuPin_PARENT, NULL, a->btgt, /*do_gp*/0); + h_trap = ERR_PTR(err); + if (unlikely(err)) { + au_do_unpin(p->pin + AuPin_PARENT, au_pin_gp(p)); + goto out; + } + h_trap = au_pinned_h_parent(p, a->btgt); + + out: + AuTraceErrPtr(h_trap); + return h_trap; +} + +static struct dentry *au_ren_pin(struct au_ren_args *a) +{ + struct dentry *h_trap; + struct inode *h_gdir; + int err, i, same_gp; + + AuTraceEnter(); + AuDebugOn(!au_opt_test(a->mnt_flags, UDBA_INOTIFY)); + + vfsub_lock_rename_mutex(a->h_dentry[SRC]->d_sb); + au_fset_ren(a->flags, VFSLOCK); + + /* gdir is not locked */ + same_gp = 0; + if (!IS_ROOT(a->parent[SRC])) + a->gparent[SRC] = dget_parent(a->parent[SRC]); + if (!IS_ROOT(a->parent[DST])) { + a->gparent[DST] = dget_parent(a->parent[DST]); + same_gp = (a->gparent[SRC] == a->gparent[DST]); + } + + /* + * patterns + * - gparent[SRC] is parent[DST] + * - parent[SRC] is gparent[DST] + * - gparent[SRC] is gparent[DST] + * - gparent[SRC] is a descendant of parent[DST] + * - parent[SRC] is an ancestor of gparent[DST] + * - not within grand parent range + */ + err = 0; + h_trap = ERR_PTR(-EBUSY); + if (a->gparent[SRC] == a->parent[DST]) { + LKTRLabel(here); + au_ren_pin_init(a->pin + DST, a->dentry, a->pin + SRC, + a->src_dentry); + h_trap = au_ren_pin3(DST, SRC, a); + if (!IS_ERR(h_trap)) { + h_gdir = au_pinned_h_dir(a->pin + DST); + err = au_verify_parent(a->h_parent[SRC], h_gdir); + if (unlikely(err)) + h_trap = ERR_PTR(-EBUSY); + } + } else if (a->parent[SRC] == a->gparent[DST] || same_gp) { + LKTRLabel(here); + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + h_trap = au_ren_pin3(SRC, DST, a); + if (!IS_ERR(h_trap)) { + if (!same_gp) + h_gdir = au_pinned_h_dir(a->pin + SRC); + else + h_gdir = au_pinned_h_gdir(a->pin + SRC); + err = au_verify_parent(a->h_parent[DST], h_gdir); + if (unlikely(err)) + h_trap = ERR_PTR(-EBUSY); + } + } else if (a->gparent[SRC] + && (h_trap = au_test_subdir(a->gparent[SRC], + a->parent[DST]))) { + LKTRLabel(here); + au_ren_pin_init(a->pin + DST, a->dentry, a->pin + SRC, + a->src_dentry); + if (a->gparent[DST]) { + err = au_ren_pin4(DST, SRC, a); + if (unlikely(err)) + h_trap = ERR_PTR(err); + } else { + struct dentry *t; + t = au_ren_pin3(DST, SRC, a); + AuDebugOn(t == h_trap); + } + } else /* if (a->gparent[DST] + && (h_trap = au_test_subdir(a->gparent[DST], + a->parent[SRC]))) */ { + LKTRLabel(here); + h_trap = NULL; + if (a->gparent[DST]) + h_trap = au_test_subdir(a->gparent[DST], + a->parent[SRC]); + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + err = au_ren_pin4(SRC, DST, a); + if (unlikely(err)) + h_trap = ERR_PTR(err); + } + au_fset_ren(a->flags, PINNED); + + if (!IS_ERR(h_trap)) { + err = 0; + for (i = 0; !err && i < 2; i++) { + h_gdir = au_pinned_h_gdir(a->pin + i); + if (h_gdir) + err = au_verify_parent(a->h_parent[i], h_gdir); + } + if (unlikely(err)) + h_trap = ERR_PTR(err); + } + + dput(a->gparent[SRC]); + dput(a->gparent[DST]); + /* memset(a->gparent, 0, sizeof(a->gparent)); */ + AuTraceErrPtr(h_trap); + return h_trap; +} + +static void au_ren_unlock(struct au_ren_args *a) +{ + int i; + + AuTraceEnter(); + + if (a->h_locked[0]) + vfsub_unlock_rename(a->h_locked[0], a->h_locked[1]); + if (au_ftest_ren(a->flags, PINNED)) { + au_unpin(a->pin + SRC); + au_unpin(a->pin + DST); + memset(a->gparent, 0, sizeof(a->gparent)); + } + if (au_ftest_ren(a->flags, VFSLOCK)) + vfsub_unlock_rename_mutex(a->h_dentry[SRC]->d_sb); + for (i = 0; i < 2; i++) + if (unlikely(a->gparent[i])) { + di_read_unlock(a->gparent[i], AuLock_IR); + dput(a->gparent[i]); + } +} + +static int au_ren_lock(struct au_ren_args *a) +{ + int err; + const int hinotify = au_opt_test(a->mnt_flags, UDBA_INOTIFY); + + AuTraceEnter(); + + err = 0; + if (!hinotify + || (au_ftest_ren(a->flags, ISSAMEDIR) && IS_ROOT(a->parent[SRC]))) { + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + LKTRLabel(here); + a->h_locked[0] = a->h_parent[SRC]; + a->h_locked[1] = a->h_parent[DST]; + a->h_trap = vfsub_lock_rename(a->h_locked[0], a->h_locked[1]); + au_ren_fake_pin(a); + } else if (au_ftest_ren(a->flags, ISSAMEDIR) + && !IS_ROOT(a->parent[SRC])) { + /* this and next block should not be compiled when + hinotify is not enabled */ + /* irregular/tricky rename lock */ + LKTRLabel(here); + au_ren_pin_init(a->pin + SRC, a->src_dentry, a->pin + DST, + a->dentry); + a->gparent[SRC] = dget_parent(a->parent[SRC]); + di_read_lock_parent2(a->gparent[SRC], AuLock_IR); + a->h_locked[0] = a->h_parent[SRC]; + a->h_locked[1] = dget_parent(a->h_parent[SRC]); + a->h_trap = vfsub_lock_rename(a->h_locked[0], a->h_locked[1]); + err = au_verify_parent(a->h_parent[SRC], + a->h_locked[1]->d_inode); + dput(a->h_locked[1]); + if (!err) + au_ren_fake_pin(a); + } else { + /* 3 or 4 dir locks. crazy */ + LKTRLabel(here); + a->h_trap = au_ren_pin(a); + if (IS_ERR(a->h_trap)) + err = PTR_ERR(a->h_trap); + } + + if (!err && au_dbstart(a->src_dentry) == a->btgt) + err = au_verify_parent(a->h_dentry[SRC], + a->h_parent[SRC]->d_inode); + if (!err && au_dbstart(a->dentry) == a->btgt) + err = au_verify_parent(a->h_dentry[DST], + a->h_parent[DST]->d_inode); + if (unlikely(err)) { + err = -EBUSY; + au_ren_unlock(a); + } + AuTraceErr(err); + return err; +} + +int aufs_rename(struct inode *src_dir, struct dentry *src_dentry, + struct inode *dir, struct dentry *dentry) +{ + int err; + aufs_bindex_t bend, bindex; + unsigned char do_dt_dstdir, hinotify; + struct inode *inode[2]; + enum { PARENT, CHILD }; + /* reduce stack space */ + struct { + struct au_ren_args a; + struct au_dtime dt[2][2]; + } *p; + struct au_wr_dir_args wr_dir_args = { + /* .force_btgt = -1, */ + .flags = AuWrDir_ADD_ENTRY + }; + + //lktr_set_pid(current->pid, LktrArrayPid); + LKTRTrace("i%lu, %.*s, i%lu, %.*s\n", + src_dir->i_ino, AuDLNPair(src_dentry), + dir->i_ino, AuDLNPair(dentry)); + AuDebugOn(IS_ROOT(src_dentry) || IS_ROOT(dentry)); + IMustLock(src_dir); + IMustLock(dir); + inode[DST] = dentry->d_inode; + if (inode[DST]) { + IMustLock(inode[DST]); + au_igrab(inode[DST]); + } + + err = -ENOMEM; + BUILD_BUG_ON(sizeof(*p) > PAGE_SIZE); + p = kzalloc(sizeof(*p), GFP_NOFS); + if (unlikely(!p)) + goto out; + + err = -ENOTDIR; + p->a.src_dir = src_dir; + p->a.src_dentry = src_dentry; + p->a.dir = dir; + p->a.dentry = dentry; + p->a.sb = src_dentry->d_sb; + inode[SRC] = src_dentry->d_inode; + p->a.flags = 0; + if (S_ISDIR(inode[SRC]->i_mode)) { + au_fset_ren(p->a.flags, ISDIR); + if (unlikely(inode[DST] && !S_ISDIR(inode[DST]->i_mode))) + goto out_free; + aufs_read_and_write_lock2(dentry, src_dentry, AuLock_DIR); + } else + aufs_read_and_write_lock2(dentry, src_dentry, 0); + + p->a.mnt_flags = au_mntflags(p->a.sb); + if (unlikely(au_test_dlgt(p->a.mnt_flags))) + au_fset_ren(p->a.flags, DLGT); + p->a.parent[SRC] = src_dentry->d_parent; /* dir inode is locked */ + p->a.parent[DST] = dentry->d_parent; /* dir inode is locked */ + au_fset_ren(p->a.flags, ISSAMEDIR); /* temporary */ + di_write_lock_parent(p->a.parent[DST]); + + /* which branch we process */ + p->a.bstart[SRC] = au_dbstart(src_dentry); + p->a.bstart[DST] = au_dbstart(dentry); + if (au_ftest_ren(p->a.flags, ISDIR)) + au_fset_wrdir(wr_dir_args.flags, ISDIR); + wr_dir_args.force_btgt = p->a.bstart[SRC]; + if (dentry->d_inode && p->a.bstart[DST] < p->a.bstart[SRC]) + wr_dir_args.force_btgt = p->a.bstart[DST]; + wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt); + err = au_wr_dir(dentry, src_dentry, &wr_dir_args); + p->a.btgt = err; + if (unlikely(err < 0)) + goto out_unlock; + + /* are they available to be renamed */ + err = 0; + au_nhash_init(&p->a.whlist); + if (au_ftest_ren(p->a.flags, ISDIR) && inode[DST]) { + au_set_dbstart(dentry, p->a.bstart[DST]); + err = may_rename_dstdir(dentry, p->a.btgt, &p->a.whlist); + au_set_dbstart(dentry, p->a.btgt); + } + p->a.h_dentry[DST] = au_h_dptr(dentry, au_dbstart(dentry)); + if (unlikely(err)) + goto out_unlock; + /* todo: minor optimize, + their sb may be same while their bindex differs? */ + p->a.h_dentry[SRC] = au_h_dptr(src_dentry, au_dbstart(src_dentry)); + if (au_ftest_ren(p->a.flags, ISDIR)) { + err = may_rename_srcdir(src_dentry, p->a.btgt); + if (unlikely(err)) + goto out_children; + } + + /* prepare the writable parent dir on the same branch */ + if (p->a.bstart[DST] == p->a.btgt) { + au_fset_ren(p->a.flags, WHDST); + } else { + err = au_cpup_dirs(dentry, p->a.btgt); + if (unlikely(err)) + goto out_children; + } + + if (src_dir != dir) { + /* + * this temporary unlock is safe, + * because dir->i_mutex is locked. + */ + di_write_unlock(p->a.parent[DST]); + di_write_lock_parent(p->a.parent[SRC]); + err = au_wr_dir_need_wh + (src_dentry, au_ftest_ren(p->a.flags, ISDIR), + &p->a.btgt); + di_write_unlock(p->a.parent[SRC]); + di_write_lock2_parent(p->a.parent[SRC], p->a.parent[DST], + /*isdir*/1); + au_fclr_ren(p->a.flags, ISSAMEDIR); + } else + err = au_wr_dir_need_wh + (src_dentry, au_ftest_ren(p->a.flags, ISDIR), + &p->a.btgt); + if (unlikely(err < 0)) + goto out_children; + if (err) + au_fset_ren(p->a.flags, WHSRC); + + hinotify = au_opt_test(p->a.mnt_flags, UDBA_INOTIFY); + p->a.h_parent[SRC] = au_h_dptr(p->a.parent[SRC], p->a.btgt); + p->a.h_parent[DST] = au_h_dptr(p->a.parent[DST], p->a.btgt); + err = au_ren_lock(&p->a); + if (unlikely(err)) + goto out_children; + + if (!au_opt_test(p->a.mnt_flags, UDBA_NONE)) { + p->a.ndx.nfsmnt = au_nfsmnt(p->a.sb, p->a.btgt); + if (unlikely(au_ftest_ren(p->a.flags, DLGT))) + au_fset_ndx(p->a.ndx.flags, DLGT); + err = au_may_ren(&p->a); + if (unlikely(err)) + goto out_hdir; + memset(&p->a.ndx, 0, sizeof(p->a.ndx)); + } + + /* store timestamps to be revertible */ + au_dtime_store(p->dt[PARENT] + SRC, p->a.parent[SRC], + p->a.h_parent[SRC], + au_pinned_hdir(p->a.pin + SRC, p->a.btgt), + au_pinned_hgdir(p->a.pin + SRC, p->a.btgt) + /* hgdir[SRC] */); + if (!au_ftest_ren(p->a.flags, ISSAMEDIR)) + au_dtime_store(p->dt[PARENT] + DST, p->a.parent[DST], + p->a.h_parent[DST], + au_pinned_hdir(p->a.pin + DST, p->a.btgt), + au_pinned_hgdir(p->a.pin + DST, p->a.btgt) + /* hgdir[DST] */); + do_dt_dstdir = 0; + if (au_ftest_ren(p->a.flags, ISDIR)) { + au_dtime_store(p->dt[CHILD] + SRC, src_dentry, + p->a.h_dentry[SRC], au_hi(inode[SRC], p->a.btgt), + au_pinned_hdir(p->a.pin + SRC, p->a.btgt)); + if (p->a.h_dentry[DST]->d_inode) { + do_dt_dstdir = 1; + au_dtime_store(p->dt[CHILD] + DST, dentry, + p->a.h_dentry[DST], + au_hi(inode[DST], p->a.btgt), + au_pinned_hdir(p->a.pin + DST, + p->a.btgt)); + } + } + + err = do_rename(&p->a); + if (unlikely(err)) + goto out_dt; + + /* update dir attributes */ + dir->i_version++; + if (au_ftest_ren(p->a.flags, ISDIR)) { + /* is this updating defined in POSIX? */ + /* mutex_lock(&inode[SRC]->i_mutex); */ + au_cpup_attr_timesizes(inode[SRC]); + /* mutex_unlock(&inode[SRC]->i_mutex); */ + + au_cpup_attr_nlink(dir); + if (inode[DST]) { + clear_nlink(inode[DST]); + au_cpup_attr_timesizes(inode[DST]); + } + } + if (au_ibstart(dir) == p->a.btgt) + au_cpup_attr_timesizes(dir); + + if (!au_ftest_ren(p->a.flags, ISSAMEDIR)) { + src_dir->i_version++; + if (au_ftest_ren(p->a.flags, ISDIR)) + au_cpup_attr_nlink(src_dir); + if (au_ibstart(src_dir) == p->a.btgt) + au_cpup_attr_timesizes(src_dir); + } + + /* todo: simple d_drop(src_dentry) is not enough? */ + /* dput/iput all lower dentries */ + au_set_dbwh(src_dentry, -1); + bend = au_dbend(src_dentry); + for (bindex = p->a.btgt + 1; bindex <= bend; bindex++) { + struct dentry *hd; + hd = au_h_dptr(src_dentry, bindex); + if (hd) + au_set_h_dptr(src_dentry, bindex, NULL); + } + au_set_dbend(src_dentry, p->a.btgt); + + if (au_opt_test(p->a.mnt_flags, PLINK) + && !au_plink_test(src_dentry->d_sb, inode[SRC])) { + bend = au_ibend(inode[SRC]); + for (bindex = p->a.btgt + 1; bindex <= bend; bindex++) { + struct inode *hi; + hi = au_h_iptr(inode[SRC], bindex); + if (hi) { + au_xino_write0(p->a.sb, bindex, hi->i_ino, 0); + /* ignore this error */ + au_set_h_iptr(inode[SRC], bindex, NULL, 0); + } + } + au_set_ibend(inode[SRC], p->a.btgt); + } + goto out_hdir; /* success */ + + out_dt: + au_dtime_revert(p->dt[PARENT] + SRC); + if (!au_ftest_ren(p->a.flags, ISSAMEDIR)) + au_dtime_revert(p->dt[PARENT] + DST); + if (au_ftest_ren(p->a.flags, ISDIR) && err != -EIO) { + struct dentry *hd; + + hd = p->dt[CHILD][SRC].dt_h_dentry; + mutex_lock_nested(&hd->d_inode->i_mutex, AuLsc_I_CHILD); + au_dtime_revert(p->dt[CHILD] + SRC); + mutex_unlock(&hd->d_inode->i_mutex); + if (do_dt_dstdir) { + hd = p->dt[CHILD][DST].dt_h_dentry; + mutex_lock_nested(&hd->d_inode->i_mutex, AuLsc_I_CHILD); + au_dtime_revert(p->dt[CHILD] + DST); + mutex_unlock(&hd->d_inode->i_mutex); + } + } + out_hdir: + au_ren_unlock(&p->a); + out_children: + au_nhash_fin(&p->a.whlist); + out_unlock: + if (unlikely(err && au_ftest_ren(p->a.flags, ISDIR))) { + au_update_dbstart(dentry); + d_drop(dentry); + } + if (!err) { + d_move(src_dentry, dentry); +#if 0 + lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(src_dentry); + AuDbgDentry(dentry); + lktr_clear_pid(current->pid, LktrArrayPid); +#endif +#if 0 + if (inode[DST]) { + inode[DST]->i_flags |= S_DEAD; + ii_write_unlock(inode[DST]); + } +#endif + } + if (au_ftest_ren(p->a.flags, ISSAMEDIR)) + di_write_unlock(p->a.parent[DST]); + else + di_write_unlock2(p->a.parent[SRC], p->a.parent[DST]); + aufs_read_and_write_unlock2(dentry, src_dentry); + out_free: + kfree(p); + out: + iput(inode[DST]); + AuTraceErr(err); + //lktr_clear_pid(current->pid, LktrArrayPid); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/misc.h +++ linux-2.6.28/ubuntu/aufs/misc.h @@ -0,0 +1,218 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * $Id: misc.h,v 1.7 2008/09/22 03:52:19 sfjro Exp $ + */ + +#ifndef __AUFS_MISC_H__ +#define __AUFS_MISC_H__ + +#ifdef __KERNEL__ + +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +typedef unsigned int au_gen_t; +/* see linux/include/linux/jiffies.h */ +#define AuGenYounger(a, b) ((int)(b) - (int)(a) < 0) +#define AuGenOlder(a, b) AufsGenYounger(b, a) + +/* ---------------------------------------------------------------------- */ + +struct au_rwsem { + struct rw_semaphore rwsem; +#ifdef CONFIG_AUFS_DEBUG + atomic_t rcnt; +#endif +}; + +#ifdef CONFIG_AUFS_DEBUG +#define AuDbgRcntInit(rw) do { \ + atomic_set(&(rw)->rcnt, 0); \ + smp_mb(); /* atomic set */ \ +} while (0) + +#define AuDbgRcntInc(rw) atomic_inc_return(&(rw)->rcnt) +#define AuDbgRcntDec(rw) WARN_ON(atomic_dec_return(&(rw)->rcnt) < 0) +#else +#define AuDbgRcntInit(rw) do {} while (0) +#define AuDbgRcntInc(rw) do {} while (0) +#define AuDbgRcntDec(rw) do {} while (0) +#endif /* CONFIG_AUFS_DEBUG */ + +static inline void au_rw_init_nolock(struct au_rwsem *rw) +{ + AuDbgRcntInit(rw); + init_rwsem(&rw->rwsem); +} + +static inline void au_rw_init_wlock(struct au_rwsem *rw) +{ + au_rw_init_nolock(rw); + down_write(&rw->rwsem); +} + +static inline void au_rw_init_wlock_nested(struct au_rwsem *rw, + unsigned int lsc) +{ + au_rw_init_nolock(rw); + down_write_nested(&rw->rwsem, lsc); +} + +static inline void au_rw_read_lock(struct au_rwsem *rw) +{ + down_read(&rw->rwsem); + AuDbgRcntInc(rw); +} + +static inline void au_rw_read_lock_nested(struct au_rwsem *rw, unsigned int lsc) +{ + down_read_nested(&rw->rwsem, lsc); + AuDbgRcntInc(rw); +} + +static inline void au_rw_read_unlock(struct au_rwsem *rw) +{ + AuDbgRcntDec(rw); + up_read(&rw->rwsem); + //au_dbg_sleep_jiffy(1 * HZ / HZ); +} + +static inline void au_rw_dgrade_lock(struct au_rwsem *rw) +{ + AuDbgRcntInc(rw); + downgrade_write(&rw->rwsem); + //au_dbg_sleep_jiffy(1 * HZ / HZ); +} + +static inline void au_rw_write_lock(struct au_rwsem *rw) +{ + down_write(&rw->rwsem); +} + +static inline void au_rw_write_lock_nested(struct au_rwsem *rw, + unsigned int lsc) +{ + down_write_nested(&rw->rwsem, lsc); +} + +static inline void au_rw_write_unlock(struct au_rwsem *rw) +{ + up_write(&rw->rwsem); + //au_dbg_sleep_jiffy(1 * HZ / HZ); +} + +/* why is not _nested version defined */ +static inline int au_rw_read_trylock(struct au_rwsem *rw) +{ + int ret = down_read_trylock(&rw->rwsem); + if (ret) + AuDbgRcntInc(rw); + return ret; +} + +static inline int au_rw_write_trylock(struct au_rwsem *rw) +{ + return down_write_trylock(&rw->rwsem); +} + +#undef AuDbgRcntInit +#undef AuDbgRcntInc +#undef AuDbgRcntDec + +/* to debug easier, do not make them inlined functions */ +#define AuRwMustNoWaiters(rw) AuDebugOn(!list_empty(&(rw)->rwsem.wait_list)) +#define AuRwMustAnyLock(rw) AuDebugOn(down_write_trylock(&(rw)->rwsem)) +#ifdef CONFIG_AUFS_DEBUG +#define AuRwMustReadLock(rw) do { \ + AuRwMustAnyLock(rw); \ + AuDebugOn(!atomic_read(&(rw)->rcnt)); \ +} while (0) + +#define AuRwMustWriteLock(rw) do { \ + AuRwMustAnyLock(rw); \ + AuDebugOn(atomic_read(&(rw)->rcnt)); \ +} while (0) +#else +#define AuRwMustReadLock(rw) AuRwMustAnyLock(rw) +#define AuRwMustWriteLock(rw) AuRwMustAnyLock(rw) +#endif /* CONFIG_AUFS_DEBUG */ + +#define AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ +static inline void prefix##_read_lock(param) \ +{ au_rw_read_lock(&(rwsem)); } \ +static inline void prefix##_write_lock(param) \ +{ au_rw_write_lock(&(rwsem)); } \ +static inline int prefix##_read_trylock(param) \ +{ return au_rw_read_trylock(&(rwsem)); } \ +static inline int prefix##_write_trylock(param) \ +{ return au_rw_write_trylock(&(rwsem)); } +/* static inline void prefix##_read_trylock_nested(param, lsc) +{au_rw_read_trylock_nested(&(rwsem, lsc));} +static inline void prefix##_write_trylock_nestd(param, lsc) +{au_rw_write_trylock_nested(&(rwsem), nested);} */ + +#define AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) \ +static inline void prefix##_read_unlock(param) \ +{ au_rw_read_unlock(&(rwsem)); } \ +static inline void prefix##_write_unlock(param) \ +{ au_rw_write_unlock(&(rwsem)); } \ +static inline void prefix##_downgrade_lock(param) \ +{ au_rw_dgrade_lock(&(rwsem)); } + +#define AuSimpleRwsemFuncs(prefix, param, rwsem) \ + AuSimpleLockRwsemFuncs(prefix, param, rwsem) \ + AuSimpleUnlockRwsemFuncs(prefix, param, rwsem) + +/* ---------------------------------------------------------------------- */ + +void *au_kzrealloc(void *p, unsigned int nused, unsigned int new_sz, gfp_t gfp); + +struct au_nd_store { + unsigned int flags; + struct path path; + struct open_intent intent; +}; +struct au_sbinfo; +void au_nd_store(struct au_nd_store *store, struct nameidata *nd, + struct au_sbinfo *sbinfo); +void au_nd_revert(struct au_nd_store *store, struct nameidata *nd, + struct au_sbinfo *sbinfo); + +struct nameidata *au_dup_nd(struct au_sbinfo *sbinfo, struct nameidata *dst, + struct nameidata *src); + +struct nameidata *au_fake_dm(struct nameidata *fake_nd, struct nameidata *nd, + struct super_block *sb, aufs_bindex_t bindex); +void au_fake_dm_release(struct nameidata *fake_nd); +struct vfsub_args; +int au_h_create(struct inode *h_dir, struct dentry *h_dentry, int mode, + struct vfsub_args *vargs, struct nameidata *nd, + struct vfsmount *nfsmnt); + +struct au_hinode; +int au_copy_file(struct file *dst, struct file *src, loff_t len, + struct au_hinode *hdir, struct super_block *sb, + struct vfsub_args *vargs); + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MISC_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/br_nfs.c +++ linux-2.6.28/ubuntu/aufs/br_nfs.c @@ -0,0 +1,347 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lookup functions for NFS branch in linux-2.6.19 and later + * + * $Id: br_nfs.c,v 1.7 2008/07/21 02:54:22 sfjro Exp $ + */ + +#include "aufs.h" + +static struct file *au_find_h_intent(struct au_hdentry *hd, struct file *file) +{ + struct file *h_file, *hf; + struct au_hdintent *hdi, *tmp, *do_free; + + LKTRTrace("%.*s\n", AuDLNPair(hd->hd_dentry)); + + h_file = NULL; + do_free = NULL; + spin_lock(&hd->hd_lock); + list_for_each_entry_safe(hdi, tmp, hd->hd_intent_list, hdi_list) { + hf = hdi->hdi_file[AuIntent_BRANCH]; + if (hdi->hdi_file[AuIntent_AUFS] == file + && hf->f_dentry == hd->hd_dentry) { + h_file = hf; + do_free = hdi; + list_del(&hdi->hdi_list); + break; + } + } + spin_unlock(&hd->hd_lock); + kfree(do_free); + + return h_file; +} + +struct file *au_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file) +{ + struct file *h_file; + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; + + LKTRTrace("%.*s, b%d, f %p\n", AuDLNPair(dentry), bindex, file); + DiMustAnyLock(dentry); + AuDebugOn(bindex < au_di(dentry)->di_bstart + || bindex > au_di(dentry)->di_bend); + + h_file = NULL; + if (!hd->hd_intent_list || !file) + return h_file; /* success */ + + /* AuDebugOn(au_test_wkq(current)); */ + h_file = au_find_h_intent(hd, file); + return h_file; +} + +static int au_set_h_intent(struct dentry *dentry, aufs_bindex_t bindex, + struct file *file, struct file *h_file) +{ + int err; + struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex; + struct au_hdintent *hdi; + struct file *hf; + + LKTRTrace("%.*s, b%d, f %p\n", AuDLNPair(dentry), bindex, file); + /* d_revalidate() holds read_lock */ + /* DiMustWriteLock(dentry); */ + AuDebugOn(bindex < au_di(dentry)->di_bstart + || bindex > au_di(dentry)->di_bend + || !file + || !h_file + /* || au_test_wkq(current) */); + + err = -ENOMEM; + if (hd->hd_intent_list) { + while (1) { + hf = au_find_h_intent(hd, file); + if (!hf) + break; + fput(hf); + AuWarn("freed hfile %.*s b%d left\n", + AuDLNPair(dentry), bindex); + } + } else { + spin_lock(&hd->hd_lock); + if (!hd->hd_intent_list) { + hd->hd_intent_list + = kmalloc(sizeof(*hd->hd_intent_list), + GFP_ATOMIC); + if (unlikely(!hd->hd_intent_list)) { + spin_unlock(&hd->hd_lock); + goto out; + } + INIT_LIST_HEAD(hd->hd_intent_list); + } + spin_unlock(&hd->hd_lock); + } + + hdi = kmalloc(sizeof(*hdi), GFP_NOFS); + if (unlikely(!hdi)) + goto out; + + err = 0; + /* hdi->hdi_pid = current->pid; */ + hdi->hdi_file[AuIntent_AUFS] = file; + hdi->hdi_file[AuIntent_BRANCH] = h_file; + spin_lock(&hd->hd_lock); + list_add(&hdi->hdi_list, hd->hd_intent_list); + spin_unlock(&hd->hd_lock); + + out: + AuTraceErr(err); + return err; +} + +int au_br_nfs_h_intent(struct file *nd_file, struct dentry *dentry, + aufs_bindex_t bindex, struct nameidata *nd) +{ + int err; + + AuTraceEnter(); + + err = 0; + if (!nd_file) + goto out; + + AuDebugOn(!nd); + err = au_set_h_intent(dentry, bindex, nd->intent.open.file, nd_file); + if (unlikely(err)) { + fput(nd_file); + au_set_h_dptr(dentry, bindex, NULL); + /* todo: update bstart and bend? */ + } + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +void au_hintent_put(struct au_hdentry *hd, int do_free) +{ + struct au_hdintent *hdi, *tmp; + struct file *hf; + + if (unlikely(hd->hd_intent_list)) { + /* no spin lock */ + list_for_each_entry_safe(hdi, tmp, hd->hd_intent_list, + hdi_list) { + LKTRTrace("hdi %p\n", hdi); + hf = hdi->hdi_file[AuIntent_BRANCH]; + if (unlikely(hf)) + fput(hf); + /* list_del(&hdi->hdi_list); */ + kfree(hdi); + } + if (do_free) + kfree(hd->hd_intent_list); + } +} + +/* ---------------------------------------------------------------------- */ + +int au_fake_intent(/* struct au_ndsub *save, */struct nameidata *nd, + int perm) +{ + int err; + + LKTRTrace("perm %d\n", perm); + + err = 0; + nd->intent.open.file = NULL; + if (nd->flags & LOOKUP_OPEN) { + err = -ENFILE; + nd->intent.open.file = get_empty_filp(); + if (unlikely(!nd->intent.open.file)) + goto out; + + err = 0; + if (!au_br_writable(perm)) { + nd->intent.open.flags = FMODE_READ + | au_file_roflags(nd->intent.open.flags); + nd->flags &= ~LOOKUP_CREATE; + } + } + + out: + AuTraceErr(err); + return err; +} + +int au_hin_after_reval(struct nameidata *nd, struct dentry *dentry, + aufs_bindex_t bindex, struct file *file) +{ + int err; + + LKTRTrace("nd %p, %.*s, b%d, f %d\n", + nd, AuDLNPair(dentry), bindex, !!file); + + err = 0; + if ((nd->flags & LOOKUP_OPEN) + && nd->intent.open.file + && !IS_ERR(nd->intent.open.file)) { + if (nd->intent.open.file->f_dentry) { + err = au_set_h_intent(dentry, bindex, file, + nd->intent.open.file); + if (!err) + nd->intent.open.file = NULL; + } + if (unlikely(nd->intent.open.file)) + put_filp(nd->intent.open.file); + } + + return err; +} + +#ifdef CONFIG_AUFS_DLGT +struct au_lookup_hash_args { + struct dentry **errp; + struct qstr *name; + struct dentry *base; + struct nameidata *nd; +}; + +static void au_call_lookup_hash(void *args) +{ + struct au_lookup_hash_args *a = args; + *a->errp = vfsub__lookup_hash(a->name, a->base, a->nd); +} + +static struct dentry * +au_lkup_hash_dlgt(struct qstr *this, struct dentry *parent, + struct nameidata *nd, unsigned int flags) +{ + struct dentry *dentry; + int dirperm1; + + dirperm1 = au_ftest_ndx(flags, DIRPERM1); + if (!dirperm1 && !au_ftest_ndx(flags, DLGT)) + dentry = vfsub__lookup_hash(this, parent, nd); + else { + int wkq_err; + struct au_lookup_hash_args args = { + .errp = &dentry, + .name = this, + .base = parent, + .nd = nd + }; + wkq_err = au_wkq_wait(au_call_lookup_hash, &args, + /*dlgt*/!dirperm1); + if (unlikely(wkq_err)) + dentry = ERR_PTR(wkq_err); + } + + AuTraceErrPtr(dentry); + return dentry; +} +#else +static struct dentry * +au_lkup_hash_dlgt(struct qstr *this, struct dentry *parent, + struct nameidata *nd, unsigned int flags) +{ + return vfsub__lookup_hash(this, parent, nd); +} +#endif /* CONFIG_AUFS_DLGT */ + +struct dentry *au_lkup_hash(const char *name, struct dentry *parent, + int len, struct au_ndx *ndx) +{ + struct dentry *dentry; + char *p; + unsigned long hash; + struct qstr this; + unsigned int c; + struct nameidata tmp_nd, *ndo; + int err; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(parent), len, name); + + /* todo: export and call __lookup_one_len() in fs/namei.c? */ + dentry = ERR_PTR(-EACCES); + this.name = name; + this.len = len; + if (unlikely(!len)) + goto out; + + p = (void *)name; + hash = init_name_hash(); + while (len--) { + c = *p++; + if (unlikely(c == '/' || c == '\0')) + goto out; + hash = partial_name_hash(c, hash); + } + this.hash = end_name_hash(hash); + + ndo = ndx->nd; + if (ndo) { + tmp_nd = *ndo; + err = au_fake_intent(&tmp_nd, ndx->br->br_perm); + dentry = ERR_PTR(err); + if (unlikely(err)) + goto out_intent; + } else + memset(&tmp_nd, 0, sizeof(tmp_nd)); + + tmp_nd.path.dentry = parent; + tmp_nd.path.mnt = ndx->nfsmnt; + path_get(&tmp_nd.path); + dentry = au_lkup_hash_dlgt(&this, parent, &tmp_nd, ndx->flags); + if (!IS_ERR(dentry)) { + /* why negative dentry for a new dir was unhashed? */ + if (unlikely(d_unhashed(dentry))) + d_rehash(dentry); + if (tmp_nd.intent.open.file + && tmp_nd.intent.open.file->f_dentry) { + ndx->nd_file = tmp_nd.intent.open.file; + tmp_nd.intent.open.file = NULL; + /* au_br_get(ndx->br); */ + } + } + path_put(&tmp_nd.path); + + out_intent: + if (tmp_nd.intent.open.file) + put_filp(tmp_nd.intent.open.file); + out: + AuTraceErrPtr(dentry); + return dentry; +} --- linux-2.6.28.orig/ubuntu/aufs/hinode.h +++ linux-2.6.28/ubuntu/aufs/hinode.h @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * lower (branch filesystem) inode and setting inotify + * + * $Id: hinode.h,v 1.9 2008/08/25 01:49:59 sfjro Exp $ + */ + +#ifndef __AUFS_HINODE_H__ +#define __AUFS_HINODE_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include "super.h" +#include "vfsub.h" + +/* ---------------------------------------------------------------------- */ + +struct au_hinotify { +#ifdef CONFIG_AUFS_HINOTIFY + spinlock_t hin_ignore_lock; + struct list_head hin_ignore_list; + + struct inotify_watch hin_watch; + struct inode *hin_aufs_inode; /* no get/put */ +#endif +}; + +struct au_hinode { + struct inode *hi_inode; + aufs_bindex_t hi_id; +#ifdef CONFIG_AUFS_HINOTIFY + struct au_hinotify *hi_notify; +#endif + + /* reference to the copied-up whiteout with get/put */ + struct dentry *hi_whdentry; +}; + +struct au_hin_ignore { +#ifdef CONFIG_AUFS_HINOTIFY + struct list_head ign_list; + + pid_t ign_pid; + __u32 ign_events, ign_handled; + struct au_hinode *ign_hinode; +#endif +}; + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_HINOTIFY +/* inotify events */ +static const __u32 AuInMask = (IN_MOVE | IN_DELETE | IN_CREATE + /* | IN_ACCESS */ + | IN_MODIFY | IN_ATTRIB + /* | IN_DELETE_SELF | IN_MOVE_SELF */ + ); + +static inline +void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val) +{ + hinode->hi_notify = val; +} + +/* hinotify.c */ +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, + struct inode *h_inode); +void au_hin_free(struct au_hinode *hinode); +void au_hin_ctl(struct au_hinode *hinode, const __u32 mask); +void au_reset_hinotify(struct inode *inode, unsigned int flags); + +int au_hin_verify_gen(struct dentry *dentry); + +int __init au_inotify_init(void); +void au_inotify_fin(void); + +static inline void au_hin_suspend(struct au_hinode *hinode) +{ + au_hin_ctl(hinode, 0); +} + +static inline void au_hin_resume(struct au_hinode *hinode) +{ + au_hin_ctl(hinode, AuInMask); +} + +#else + +static inline +void au_hin_init(struct au_hinode *hinode, struct au_hinotify *val) +{ + /* empty */ +} + +static inline +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, + struct inode *h_inode) +{ + return -EOPNOTSUPP; +} + +static inline void au_hin_free(struct au_hinode *hinode) +{ + /* nothing */ +} + +static inline void au_reset_hinotify(struct inode *inode, unsigned int flags) +{ + /* nothing */ +} + +static inline int au_hin_verify_gen(struct dentry *dentry) +{ + return 0; +} + +static inline int au_inotify_init(void) +{ + return 0; +} + +#define au_inotify_fin() do {} while (0) + +static inline void au_hin_suspend(struct au_hinode *hinode) +{ + /* empty */ +} + +static inline void au_hin_resume(struct au_hinode *hinode) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_HINOTIFY */ + +#if defined(CONFIG_AUFS_HINOTIFY) && defined(CONFIG_AUFS_DEBUG) +static inline void au_hin_list_del(struct list_head *e) +{ + list_del_init(e); +} + +void au_dbg_hin_list(struct vfsub_args *vargs); +#else +static inline void au_hin_list_del(struct list_head *e) +{ + list_del(e); +} + +static inline void au_dbg_hin_list(struct vfsub_args *vargs) +{ + /* empty */ +} +#endif /* CONFIG_AUFS_DEBUG */ + +/* ---------------------------------------------------------------------- */ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_HINODE_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/sysrq.c +++ linux-2.6.28/ubuntu/aufs/sysrq.c @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * magic sysrq hanlder + * + * $Id: sysrq.c,v 1.10 2008/09/08 02:40:48 sfjro Exp $ + */ + +#include +#include +#include +/* #include */ +#include "aufs.h" + +static void sysrq_sb(struct super_block *sb) +{ + char *plevel; + struct inode *i; + + plevel = au_plevel; + au_plevel = KERN_WARNING; + au_debug_on(); + + pr_warning("si=%lx\n", au_si_mask ^ (unsigned long)au_sbi(sb)); + pr_warning(AUFS_NAME ": superblock\n"); + au_dpri_sb(sb); + pr_warning(AUFS_NAME ": root dentry\n"); + au_dpri_dentry(sb->s_root); + pr_warning(AUFS_NAME ": root inode\n"); + au_dpri_inode(sb->s_root->d_inode); + pr_warning(AUFS_NAME ": isolated inode\n"); + list_for_each_entry(i, &sb->s_inodes, i_sb_list) + if (list_empty(&i->i_dentry)) + au_dpri_inode(i); + + au_plevel = plevel; + au_debug_off(); +} + +/* ---------------------------------------------------------------------- */ + +/* module parameter */ +static char *aufs_sysrq_key = "a"; +module_param_named(sysrq, aufs_sysrq_key, charp, S_IRUGO); +MODULE_PARM_DESC(sysrq, "MagicSysRq key for " AUFS_NAME); + +static void au_sysrq(int key, struct tty_struct *tty) +{ + struct kobject *kobj; + struct au_sbinfo *sbinfo; + + /* spin_lock(&au_kset->list_lock); */ + list_for_each_entry(kobj, &au_kset->list, entry) { + sbinfo = container_of(kobj, struct au_sbinfo, si_kobj); + sysrq_sb(sbinfo->si_sb); + } + /* spin_unlock(&au_kset->list_lock); */ +} + +static struct sysrq_key_op au_sysrq_op = { + .handler = au_sysrq, + .help_msg = "Aufs", + .action_msg = "Aufs", + /* todo: test mask? */ + .enable_mask = SYSRQ_ENABLE_DUMP +}; + +/* ---------------------------------------------------------------------- */ + +int __init au_sysrq_init(void) +{ + int err; + char key; + + err = -1; + key = *aufs_sysrq_key; + if ('a' <= key && key <= 'z') + err = register_sysrq_key(key, &au_sysrq_op); + if (unlikely(err)) + AuErr("err %d, sysrq=%c\n", err, key); + return err; +} + +void au_sysrq_fin(void) +{ + int err; + err = unregister_sysrq_key(*aufs_sysrq_key, &au_sysrq_op); + if (unlikely(err)) + AuErr("err %d (ignored)\n", err); +} --- linux-2.6.28.orig/ubuntu/aufs/xino.c +++ linux-2.6.28/ubuntu/aufs/xino.c @@ -0,0 +1,1259 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * external inode number translation table and bitmap + * + * $Id: xino.c,v 1.16 2008/09/15 03:16:30 sfjro Exp $ + */ + +#include +#include "aufs.h" + +/* ---------------------------------------------------------------------- */ + +ssize_t xino_fread(au_readf_t func, struct file *file, void *buf, size_t size, + loff_t *pos) +{ + ssize_t err; + mm_segment_t oldfs; + + LKTRTrace("%.*s, sz %lu, *pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)size, *pos); + + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + /* todo: signal_pending? */ + err = func(file, (char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + +#if 0 /* reserved for future use */ + if (err > 0) + fsnotify_access(file->f_dentry); +#endif + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static ssize_t do_xino_fwrite(au_writef_t func, struct file *file, void *buf, + size_t size, loff_t *pos) +{ + ssize_t err; + mm_segment_t oldfs; + + lockdep_off(); + oldfs = get_fs(); + set_fs(KERNEL_DS); + do { + /* todo: signal_pending? */ + err = func(file, (const char __user *)buf, size, pos); + } while (err == -EAGAIN || err == -EINTR); + set_fs(oldfs); + lockdep_on(); + + if (err >= 0) + au_update_fuse_h_inode(file->f_vfsmnt, file->f_dentry); + /*ignore*/ + +#if 0 /* reserved for future use */ + if (err > 0) + fsnotify_modify(file->f_dentry); +#endif + + AuTraceErr(err); + return err; +} + +struct do_xino_fwrite_args { + ssize_t *errp; + au_writef_t func; + struct file *file; + void *buf; + size_t size; + loff_t *pos; +}; + +static void call_do_xino_fwrite(void *args) +{ + struct do_xino_fwrite_args *a = args; + *a->errp = do_xino_fwrite(a->func, a->file, a->buf, a->size, a->pos); +} + +ssize_t xino_fwrite(au_writef_t func, struct file *file, void *buf, size_t size, + loff_t *pos) +{ + ssize_t err; + + LKTRTrace("%.*s, sz %lu, *pos %lld\n", + AuDLNPair(file->f_dentry), (unsigned long)size, *pos); + + /* todo: signal block and no wkq? */ + /* + * it breaks RLIMIT_FSIZE and normal user's limit, + * users should care about quota and real 'filesystem full.' + */ + if (!au_test_wkq(current)) { + int wkq_err; + struct do_xino_fwrite_args args = { + .errp = &err, + .func = func, + .file = file, + .buf = buf, + .size = size, + .pos = pos + }; + wkq_err = au_wkq_wait(call_do_xino_fwrite, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + } else + err = do_xino_fwrite(func, file, buf, size, pos); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct xino_do_trunc_args { + struct super_block *sb; + struct au_branch *br; +}; + +static void xino_do_trunc(void *_args) +{ + struct xino_do_trunc_args *args = _args; + struct super_block *sb; + aufs_bindex_t bindex; + int err; + struct file *file; + struct inode *dir; + struct au_sbinfo *sbinfo; + struct kobject *kobj; + + err = 0; + sb = args->sb; + dir = sb->s_root->d_inode; + si_noflush_write_lock(sb); + ii_read_lock_parent(dir); + bindex = au_br_index(sb, args->br->br_id); + AuDebugOn(bindex < 0); + err = au_xino_trunc(sb, bindex); + if (unlikely(err)) + goto out; + + file = args->br->br_xino.xi_file; + au_update_fuse_h_inode(args->br->br_mnt, file->f_dentry); /*ignore*/ + if (file->f_dentry->d_inode->i_blocks >= args->br->br_xino_upper) + args->br->br_xino_upper += AUFS_XINO_TRUNC_STEP; + + out: + ii_read_unlock(dir); + if (unlikely(err)) + AuWarn("err b%d, (%d)\n", bindex, err); + atomic_dec_return(&args->br->br_xino_running); + au_br_put(args->br); + sbinfo = au_sbi(sb); + kobj = &sbinfo->si_kobj; + au_nwt_done(&sbinfo->si_nowait); + si_write_unlock(sb); + kobject_put(kobj); + kfree(args); +} + +static void xino_try_trunc(struct super_block *sb, struct au_branch *br) +{ + struct xino_do_trunc_args *args; + struct au_sbinfo *sbinfo; + struct file *file = br->br_xino.xi_file; + int wkq_err; + + au_update_fuse_h_inode(br->br_mnt, file->f_dentry); /*ignore*/ + if (file->f_dentry->d_inode->i_blocks < br->br_xino_upper) + return; + if (atomic_inc_return(&br->br_xino_running) > 1) + goto out; + + /* lock and kfree() will be called in trunc_xino() */ + args = kmalloc(sizeof(*args), GFP_NOFS); + if (unlikely(!args)) { + AuErr1("no memory\n"); + goto out_args; + } + + sbinfo = au_sbi(sb); + kobject_get(&sbinfo->si_kobj); + au_br_get(br); + args->sb = sb; + args->br = br; + wkq_err = au_wkq_nowait(xino_do_trunc, args, sb, /*dlgt*/0); + if (!wkq_err) + return; /* success */ + + AuErr("wkq %d\n", wkq_err); + au_br_put(br); + kobject_put(&sbinfo->si_kobj); + + out_args: + kfree(args); + out: + atomic_dec_return(&br->br_xino_running); +} + +/* ---------------------------------------------------------------------- */ + +static int au_xino_do_write(au_writef_t write, struct file *file, + ino_t h_ino, struct au_xino_entry *xinoe) +{ + loff_t pos; + ssize_t sz; + + AuTraceEnter(); + + pos = h_ino; + if (unlikely(Au_LOFF_MAX / sizeof(*xinoe) - 1 < pos)) { + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); + return -EFBIG; + } + pos *= sizeof(*xinoe); + sz = xino_fwrite(write, file, xinoe, sizeof(*xinoe), &pos); + if (sz == sizeof(*xinoe)) + return 0; /* success */ + + AuIOErr("write failed (%ld)\n", (long)sz); + return -EIO; +} + +/* + * write @ino to the xinofile for the specified branch{@sb, @bindex} + * at the position of @_ino. + * when @ino is zero, it is written to the xinofile and means no entry. + */ +int au_xino_write(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe) +{ + int err; + struct file *file; + struct au_branch *br; + unsigned int mnt_flags; + + LKTRTrace("b%d, hi%lu, i%lu\n", + bindex, (unsigned long)h_ino, (unsigned long)xinoe->ino); + BUILD_BUG_ON(sizeof(long long) != sizeof(Au_LOFF_MAX) + || ((loff_t)-1) > 0); + + mnt_flags = au_mntflags(sb); + if (unlikely(!au_opt_test_xino(mnt_flags))) + return 0; + + br = au_sbr(sb, bindex); + file = br->br_xino.xi_file; + AuDebugOn(!file); + + err = au_xino_do_write(au_sbi(sb)->si_xwrite, file, h_ino, xinoe); + if (!err) { + if (unlikely(au_opt_test(mnt_flags, TRUNC_XINO) + && au_test_trunc_xino(br->br_mnt->mnt_sb))) + xino_try_trunc(sb, br); + return 0; /* success */ + } + + AuIOErr("write failed (%d)\n", err); + return -EIO; +} + +/* ---------------------------------------------------------------------- */ + +static const int page_bits = (int)PAGE_SIZE * BITS_PER_BYTE; +static ino_t xib_calc_ino(unsigned long pindex, int bit) +{ + ino_t ino; + + AuDebugOn(bit < 0 || page_bits <= bit); + ino = AUFS_FIRST_INO + pindex * page_bits + bit; + return ino; +} + +static void xib_calc_bit(ino_t ino, unsigned long *pindex, int *bit) +{ + AuDebugOn(ino < AUFS_FIRST_INO); + ino -= AUFS_FIRST_INO; + *pindex = ino / page_bits; + *bit = ino % page_bits; +} + +static int xib_pindex(struct super_block *sb, unsigned long pindex) +{ + int err; + struct au_sbinfo *sbinfo; + loff_t pos; + ssize_t sz; + struct file *xib; + unsigned long *p; + + LKTRTrace("pindex %lu\n", pindex); + sbinfo = au_sbi(sb); + MtxMustLock(&sbinfo->si_xib_mtx); + AuDebugOn(pindex > ULONG_MAX / PAGE_SIZE + || !au_opt_test_xino(sbinfo->si_mntflags)); + + if (pindex == sbinfo->si_xib_last_pindex) + return 0; + + xib = sbinfo->si_xib; + p = sbinfo->si_xib_buf; + pos = sbinfo->si_xib_last_pindex; + pos *= PAGE_SIZE; + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); + if (unlikely(sz != PAGE_SIZE)) + goto out; + + pos = pindex; + pos *= PAGE_SIZE; + if (i_size_read(xib->f_dentry->d_inode) >= pos + PAGE_SIZE) + sz = xino_fread(sbinfo->si_xread, xib, p, PAGE_SIZE, &pos); + else { + memset(p, 0, PAGE_SIZE); + sz = xino_fwrite(sbinfo->si_xwrite, xib, p, PAGE_SIZE, &pos); + } + if (sz == PAGE_SIZE) { + sbinfo->si_xib_last_pindex = pindex; + return 0; /* success */ + } + + out: + AuIOErr1("write failed (%ld)\n", (long)sz); + err = sz; + if (sz >= 0) + err = -EIO; + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +int au_xino_write0(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + ino_t ino) +{ + int err, bit; + unsigned long pindex; + struct au_sbinfo *sbinfo; + struct au_xino_entry xinoe = { + .ino = 0 + }; + + LKTRTrace("b%d, hi%lu, i%lu\n", + bindex, (unsigned long)h_ino, (unsigned long)ino); + + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + return 0; + + err = 0; + sbinfo = au_sbi(sb); + if (unlikely(ino)) { + AuDebugOn(ino < AUFS_FIRST_INO); + xib_calc_bit(ino, &pindex, &bit); + AuDebugOn(page_bits <= bit); + mutex_lock(&sbinfo->si_xib_mtx); + err = xib_pindex(sb, pindex); + if (!err) { + clear_bit(bit, sbinfo->si_xib_buf); + sbinfo->si_xib_next_bit = bit; + } + mutex_unlock(&sbinfo->si_xib_mtx); + } + + if (!err) + err = au_xino_write(sb, bindex, h_ino, &xinoe); + return err; +} + +ino_t au_xino_new_ino(struct super_block *sb) +{ + ino_t ino; + struct au_sbinfo *sbinfo; + int free_bit, err; + unsigned long *p, pindex, ul, pend; + struct file *file; + + AuTraceEnter(); + + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + return iunique(sb, AUFS_FIRST_INO); + + sbinfo = au_sbi(sb); + mutex_lock(&sbinfo->si_xib_mtx); + p = sbinfo->si_xib_buf; + free_bit = sbinfo->si_xib_next_bit; + if (free_bit < page_bits && !test_bit(free_bit, p)) + goto out; /* success */ + free_bit = find_first_zero_bit(p, page_bits); + if (free_bit < page_bits) + goto out; /* success */ + + pindex = sbinfo->si_xib_last_pindex; + for (ul = pindex - 1; ul < ULONG_MAX; ul--) { + err = xib_pindex(sb, ul); + if (unlikely(err)) + goto out_err; + free_bit = find_first_zero_bit(p, page_bits); + if (free_bit < page_bits) + goto out; /* success */ + } + + file = sbinfo->si_xib; + pend = i_size_read(file->f_dentry->d_inode) / PAGE_SIZE; + for (ul = pindex + 1; ul <= pend; ul++) { + err = xib_pindex(sb, ul); + if (unlikely(err)) + goto out_err; + free_bit = find_first_zero_bit(p, page_bits); + if (free_bit < page_bits) + goto out; /* success */ + } + BUG(); + + out: + set_bit(free_bit, p); + sbinfo->si_xib_next_bit++; + pindex = sbinfo->si_xib_last_pindex; + mutex_unlock(&sbinfo->si_xib_mtx); + ino = xib_calc_ino(pindex, free_bit); + LKTRTrace("i%lu\n", (unsigned long)ino); + return ino; + out_err: + mutex_unlock(&sbinfo->si_xib_mtx); + LKTRTrace("i0\n"); + return 0; +} + +/* + * read @ino from xinofile for the specified branch{@sb, @bindex} + * at the position of @h_ino. + * if @ino does not exist and @do_new is true, get new one. + */ +int au_xino_read(struct super_block *sb, aufs_bindex_t bindex, ino_t h_ino, + struct au_xino_entry *xinoe) +{ + int err; + struct file *file; + loff_t pos; + ssize_t sz; + struct au_sbinfo *sbinfo; + + LKTRTrace("b%d, hi%lu\n", bindex, (unsigned long)h_ino); + + xinoe->ino = 0; + if (unlikely(!au_opt_test_xino(au_mntflags(sb)))) + return 0; /* no ino */ + + err = 0; + sbinfo = au_sbi(sb); + pos = h_ino; + if (unlikely(Au_LOFF_MAX / sizeof(*xinoe) - 1 < pos)) { + AuIOErr1("too large hi%lu\n", (unsigned long)h_ino); + return -EFBIG; + } + pos *= sizeof(*xinoe); + + file = au_sbr(sb, bindex)->br_xino.xi_file; + AuDebugOn(!file); + if (i_size_read(file->f_dentry->d_inode) < pos + sizeof(*xinoe)) + return 0; /* no ino */ + + sz = xino_fread(sbinfo->si_xread, file, xinoe, sizeof(*xinoe), &pos); + if (sz == sizeof(*xinoe)) + return 0; /* success */ + + err = sz; + if (unlikely(sz >= 0)) { + err = -EIO; + AuIOErr("xino read error (%ld)\n", (long)sz); + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct file *au_xino_create(struct super_block *sb, char *fname, int silent) +{ + struct file *file; + int err; + struct dentry *h_parent; + struct inode *h_dir; + struct vfsub_args vargs; + + LKTRTrace("%s\n", fname); + + /* + * at mount-time, and the xino file is the default path, + * hinotify is disabled so we have no inotify events to ignore. + * when a user specified the xino, we cannot get au_hdir to be ignored. + */ + vfsub_args_init(&vargs, /*ign*/NULL, /*dlgt*/0, 0); + file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE, + S_IRUGO | S_IWUGO); + if (IS_ERR(file)) { + if (!silent) + AuErr("open %s(%ld)\n", fname, PTR_ERR(file)); + return file; + } + + /* keep file count */ + h_parent = dget_parent(file->f_dentry); + h_dir = h_parent->d_inode; + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + err = vfsub_unlink(h_dir, file->f_dentry, &vargs); + mutex_unlock(&h_dir->i_mutex); + dput(h_parent); + if (unlikely(err)) { + if (!silent) + AuErr("unlink %s(%d)\n", fname, err); + goto out; + } + + if (sb != file->f_dentry->d_sb) + return file; /* success */ + + if (!silent) + AuErr("%s must be outside\n", fname); + err = -EINVAL; + + out: + fput(file); + file = ERR_PTR(err); + return file; +} + +/* + * find another branch who is on the same filesystem of the specified + * branch{@btgt}. search until @bend. + */ +static int is_sb_shared(struct super_block *sb, aufs_bindex_t btgt, + aufs_bindex_t bend) +{ + aufs_bindex_t bindex; + struct super_block *tgt_sb = au_sbr_sb(sb, btgt); + + for (bindex = 0; bindex < btgt; bindex++) + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) + return bindex; + for (bindex++; bindex <= bend; bindex++) + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) + return bindex; + return -1; +} + +/* + * create a new xinofile at the same place/path as @base_file. + */ +struct file *au_xino_create2(struct super_block *sb, struct file *base_file, + struct file *copy_src) +{ + struct file *file; + int err; + struct dentry *base, *dentry, *parent; + struct inode *dir, *inode; + struct qstr *name; + struct au_hinode *hdir; + struct au_branch *br; + aufs_bindex_t bindex; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_ndx ndx = { + .nfsmnt = NULL, + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + base = base_file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(base)); + parent = base->d_parent; /* dir inode is locked */ + dir = parent->d_inode; + IMustLock(dir); + + file = ERR_PTR(-EINVAL); + if (unlikely(au_test_nfs(parent->d_sb))) + goto out; + + /* do not superio, nor NFS. */ + name = &base->d_name; + dentry = au_lkup_one(name->name, parent, name->len, &ndx); + if (IS_ERR(dentry)) { + file = (void *)dentry; + AuErr("%.*s lookup err %ld\n", AuLNPair(name), PTR_ERR(dentry)); + goto out; + } + + hdir = NULL; + br = au_xino_def_br(au_sbi(sb)); + if (br) { + bindex = au_find_bindex(sb, br); + if (bindex >= 0) + hdir = au_hi(sb->s_root->d_inode, bindex); + } + vfsub_args_init(&vargs, &ign, 0, 0); + vfsub_ign_hinode(&vargs, IN_CREATE, hdir); + err = vfsub_create(dir, dentry, S_IRUGO | S_IWUGO, NULL, &vargs); + if (unlikely(err)) { + file = ERR_PTR(err); + AuErr("%.*s create err %d\n", AuLNPair(name), err); + goto out_dput; + } + file = dentry_open(dget(dentry), mntget(base_file->f_vfsmnt), + O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE); + if (IS_ERR(file)) { + AuErr("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file)); + goto out_dput; + } + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + err = vfsub_unlink(dir, dentry, &vargs); + if (unlikely(err)) { + AuErr("%.*s unlink err %d\n", AuLNPair(name), err); + goto out_fput; + } + + if (copy_src) { + inode = copy_src->f_dentry->d_inode; + err = au_copy_file(file, copy_src, i_size_read(inode), + hdir, sb, &vargs); + if (unlikely(err)) { + AuErr("%.*s copy err %d\n", AuLNPair(name), err); + goto out_fput; + } + } + goto out_dput; /* success */ + + out_fput: + fput(file); + file = ERR_PTR(err); + out_dput: + dput(dentry); + out: + AuTraceErrPtr(file); + return file; +} + +/* ---------------------------------------------------------------------- */ + +/* + * initialize the xinofile for the specified branch{@sb, @bindex} + * at the place/path where @base_file indicates. + * test whether another branch is on the same filesystem or not, + * if @do_test is true. + */ +int au_xino_br(struct super_block *sb, struct au_branch *br, ino_t h_ino, + struct file *base_file, int do_test) +{ + int err; + struct au_branch *shared_br; + aufs_bindex_t bshared, bend, bindex; + unsigned char do_create; + struct inode *dir; + struct au_xino_entry xinoe; + struct dentry *parent; + struct file *file; + struct super_block *tgt_sb; + + LKTRTrace("base_file %p, do_test %d\n", base_file, do_test); + SiMustWriteLock(sb); + AuDebugOn(!au_opt_test_xino(au_mntflags(sb))); + AuDebugOn(br->br_xino.xi_file); + + do_create = 1; + bshared = -1; + shared_br = NULL; + bend = au_sbend(sb); + if (do_test) { + tgt_sb = br->br_mnt->mnt_sb; + for (bindex = 0; bindex <= bend; bindex++) + if (unlikely(tgt_sb == au_sbr_sb(sb, bindex))) { + bshared = bindex; + break; + } + } + if (unlikely(bshared >= 0)) { + shared_br = au_sbr(sb, bshared); + do_create = !shared_br->br_xino.xi_file; + } + + if (do_create) { + parent = dget_parent(base_file->f_dentry); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + file = au_xino_create2(sb, base_file, NULL); + mutex_unlock(&dir->i_mutex); + dput(parent); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + br->br_xino.xi_file = file; + } else { + br->br_xino.xi_file = shared_br->br_xino.xi_file; + get_file(br->br_xino.xi_file); + } + + xinoe.ino = AUFS_ROOT_INO; +#if 0 /* reserved for future use */ + xinoe.h_gen = h_inode->i_generation; + WARN_ON(xinoe.h_gen == AuXino_INVALID_HGEN); +#endif + err = au_xino_do_write(au_sbi(sb)->si_xwrite, br->br_xino.xi_file, + h_ino, &xinoe); + if (!err) + return 0; /* success */ + + + out: + AuTraceErr(err); + return err; +} + +/* too slow */ +static int do_xib_restore(struct super_block *sb, struct file *file, void *page) +{ + int err, bit; + struct au_sbinfo *sbinfo; + au_readf_t func; + loff_t pos, pend; + ssize_t sz; + struct au_xino_entry *xinoe; + unsigned long pindex; + + AuTraceEnter(); + SiMustWriteLock(sb); + + err = 0; + sbinfo = au_sbi(sb); + func = sbinfo->si_xread; + pend = i_size_read(file->f_dentry->d_inode); +#ifdef CONFIG_AUFS_DEBUG + if (unlikely(pend > (1 << 22))) + AuWarn("testing a large xino file %lld\n", (long long)pend); +#endif + pos = 0; + while (pos < pend) { + sz = xino_fread(func, file, page, PAGE_SIZE, &pos); + err = sz; + if (unlikely(sz <= 0)) + goto out; + + err = 0; + for (xinoe = page; sz > 0; xinoe++, sz -= sizeof(xinoe)) { + if (unlikely(xinoe->ino < AUFS_FIRST_INO)) + continue; + + xib_calc_bit(xinoe->ino, &pindex, &bit); + AuDebugOn(page_bits <= bit); + err = xib_pindex(sb, pindex); + if (!err) + set_bit(bit, sbinfo->si_xib_buf); + else + goto out; + } + } + + out: + AuTraceErr(err); + return err; +} + +static int xib_restore(struct super_block *sb) +{ + int err; + aufs_bindex_t bindex, bend; + void *page; + + AuTraceEnter(); + + err = -ENOMEM; + page = (void *)__get_free_page(GFP_NOFS); + if (unlikely(!page)) + goto out; + + err = 0; + bend = au_sbend(sb); + for (bindex = 0; !err && bindex <= bend; bindex++) + if (!bindex || is_sb_shared(sb, bindex, bindex - 1) < 0) + err = do_xib_restore + (sb, au_sbr(sb, bindex)->br_xino.xi_file, page); + else + LKTRTrace("b%d\n", bindex); + free_page((unsigned long)page); + + out: + AuTraceErr(err); + return err; +} + +int au_xib_trunc(struct super_block *sb) +{ + int err; + struct au_sbinfo *sbinfo; + unsigned long *p; + loff_t pos; + ssize_t sz; + struct dentry *parent; + struct inode *dir; + struct file *file; + unsigned int mnt_flags; + + AuTraceEnter(); + SiMustWriteLock(sb); + + mnt_flags = au_mntflags(sb); + if (unlikely(!au_opt_test_xino(mnt_flags))) + return 0; + + sbinfo = au_sbi(sb); + parent = dget_parent(sbinfo->si_xib->f_dentry); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + file = au_xino_create2(sb, sbinfo->si_xib, NULL); + mutex_unlock(&dir->i_mutex); + dput(parent); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + fput(sbinfo->si_xib); + sbinfo->si_xib = file; + + p = sbinfo->si_xib_buf; + memset(p, 0, PAGE_SIZE); + pos = 0; + sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xib, p, PAGE_SIZE, &pos); + if (unlikely(sz != PAGE_SIZE)) { + err = sz; + AuIOErr("err %d\n", err); + if (sz >= 0) + err = -EIO; + goto out; + } + + if (au_opt_test_xino(mnt_flags)) { + mutex_lock(&sbinfo->si_xib_mtx); + err = xib_restore(sb); + mutex_unlock(&sbinfo->si_xib_mtx); +#if 0 /* reserved for future use */ + } else { + /* is it really safe? */ + /* dont trust BKL */ + AuDebugOn(!kernel_locked()); + ino = AUFS_FIRST_INO; + list_for_each_entry(inode, &sb->s_inodes, i_sb_list) + if (ino < inode->i_ino) + ino = inode->i_ino; + + /* make iunique to return larger than active max inode number */ + iunique(sb, ino); + err = 0; +#endif + } + +out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * xino mount option handlers + */ +static au_readf_t find_readf(struct file *h_file) +{ + const struct file_operations *fop = h_file->f_op; + + if (fop) { + if (fop->read) + return fop->read; + if (fop->aio_read) + return do_sync_read; + } + return ERR_PTR(-ENOSYS); +} + +static au_writef_t find_writef(struct file *h_file) +{ + const struct file_operations *fop = h_file->f_op; + + if (fop) { + if (fop->write) + return fop->write; + if (fop->aio_write) + return do_sync_write; + } + return ERR_PTR(-ENOSYS); +} + +/* xino bitmap */ +static void xino_clear_xib(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + sbinfo->si_xread = NULL; + sbinfo->si_xwrite = NULL; + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = NULL; + free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; +} + +static int au_xino_set_xib(struct super_block *sb, struct file *base) +{ + int err; + struct au_sbinfo *sbinfo; + struct file *file; + loff_t pos; + + LKTRTrace("%.*s\n", AuDLNPair(base->f_dentry)); + SiMustWriteLock(sb); + + sbinfo = au_sbi(sb); + file = au_xino_create2(sb, base, sbinfo->si_xib); + err = PTR_ERR(file); + if (IS_ERR(file)) + goto out; + if (sbinfo->si_xib) + fput(sbinfo->si_xib); + sbinfo->si_xib = file; + sbinfo->si_xread = find_readf(file); + AuDebugOn(IS_ERR(sbinfo->si_xread)); + sbinfo->si_xwrite = find_writef(file); + AuDebugOn(IS_ERR(sbinfo->si_xwrite)); + + err = -ENOMEM; + if (!sbinfo->si_xib_buf) + sbinfo->si_xib_buf = (void *)get_zeroed_page(GFP_NOFS); + if (unlikely(!sbinfo->si_xib_buf)) + goto out_unset; + + sbinfo->si_xib_last_pindex = 0; + sbinfo->si_xib_next_bit = 0; + + /* no need to lock for i_size_read() */ + if (i_size_read(file->f_dentry->d_inode) < PAGE_SIZE) { + pos = 0; + err = xino_fwrite(sbinfo->si_xwrite, file, sbinfo->si_xib_buf, + PAGE_SIZE, &pos); + if (unlikely(err != PAGE_SIZE)) + goto out_free; + } + err = 0; + goto out; /* success */ + + out_free: + free_page((unsigned long)sbinfo->si_xib_buf); + sbinfo->si_xib_buf = NULL; + if (err >= 0) + err = -EIO; + out_unset: + fput(sbinfo->si_xib); + sbinfo->si_xib = NULL; + sbinfo->si_xread = NULL; + sbinfo->si_xwrite = NULL; + out: + AuTraceErr(err); + return err; +} + +/* xino for each branch */ +static void xino_clear_br(struct super_block *sb) +{ + aufs_bindex_t bindex, bend; + struct au_branch *br; + + AuTraceEnter(); + SiMustWriteLock(sb); + + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) { + br = au_sbr(sb, bindex); + if (unlikely(!br || !br->br_xino.xi_file)) + continue; + + fput(br->br_xino.xi_file); + br->br_xino.xi_file = NULL; + } +} + +static int au_xino_set_br(struct super_block *sb, struct file *base) +{ + int err; + aufs_bindex_t bindex, bend, bshared; + struct { + struct file *old, *new; + } *fpair, *p; + struct au_branch *br; + struct au_xino_entry xinoe; + struct inode *inode; + au_writef_t writef; + + LKTRTrace("%.*s\n", AuDLNPair(base->f_dentry)); + SiMustWriteLock(sb); + + err = -ENOMEM; + bend = au_sbend(sb); + fpair = kcalloc(bend + 1, sizeof(*fpair), GFP_NOFS); + if (unlikely(!fpair)) + goto out; + + inode = sb->s_root->d_inode; + xinoe.ino = AUFS_ROOT_INO; + writef = au_sbi(sb)->si_xwrite; + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { + br = au_sbr(sb, bindex); + bshared = is_sb_shared(sb, bindex, bindex - 1); + if (bshared >= 0) { + /* shared xino */ + *p = fpair[bshared]; + get_file(p->new); + } + + if (!p->new) { + /* new xino */ + p->old = br->br_xino.xi_file; + p->new = au_xino_create2(sb, base, br->br_xino.xi_file); + err = PTR_ERR(p->new); + if (IS_ERR(p->new)) { + p->new = NULL; + goto out_pair; + } + } + + err = au_xino_do_write(writef, p->new, + au_h_iptr(inode, bindex)->i_ino, &xinoe); + if (unlikely(err)) + goto out_pair; + } + + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) { + br = au_sbr(sb, bindex); + AuDebugOn(p->old != br->br_xino.xi_file); + if (br->br_xino.xi_file) + fput(br->br_xino.xi_file); + get_file(p->new); + br->br_xino.xi_file = p->new; + } + + out_pair: + for (bindex = 0, p = fpair; bindex <= bend; bindex++, p++) + if (p->new) + fput(p->new); + else + break; + kfree(fpair); + out: + AuTraceErr(err); + return err; +} + +void au_xino_clr(struct super_block *sb) +{ + struct au_sbinfo *sbinfo; + + AuTraceEnter(); + SiMustWriteLock(sb); + + au_xigen_clr(sb); + xino_clear_xib(sb); + xino_clear_br(sb); + sbinfo = au_sbi(sb); + /* lvalue, do not call au_mntflags() */ + au_opt_clr(sbinfo->si_mntflags, XINO); + au_xino_def_br_set(NULL, sbinfo); +} + +int au_xino_set(struct super_block *sb, struct au_opt_xino *xino, int remount) +{ + int err, skip; + struct dentry *parent, *cur_parent; + struct qstr *dname, *cur_name; + struct file *cur_xino; + struct inode *dir; + struct au_sbinfo *sbinfo; + + LKTRTrace("remount %d\n", remount); + SiMustWriteLock(sb); + + err = 0; + sbinfo = au_sbi(sb); + parent = dget_parent(xino->file->f_dentry); + if (remount) { + skip = 0; + dname = &xino->file->f_dentry->d_name; + cur_xino = sbinfo->si_xib; + if (cur_xino) { + cur_parent = dget_parent(cur_xino->f_dentry); + cur_name = &cur_xino->f_dentry->d_name; + skip = (cur_parent == parent + && dname->len == cur_name->len + && !memcmp(dname->name, cur_name->name, + dname->len)); + dput(cur_parent); + } + if (skip) + goto out; + } + + au_opt_set(sbinfo->si_mntflags, XINO); + au_xino_def_br_set(NULL, sbinfo); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + err = au_xino_set_xib(sb, xino->file); + if (!err) + err = au_xigen_set(sb, xino->file); + if (!err) + err = au_xino_set_br(sb, xino->file); + mutex_unlock(&dir->i_mutex); + if (!err) + goto out; /* success */ + + /* reset all */ + AuIOErr("failed creating xino(%d).\n", err); + + out: + dput(parent); + AuTraceErr(err); + return err; +} + +int au_xino_trunc(struct super_block *sb, aufs_bindex_t bindex) +{ + int err; + struct au_branch *br; + struct file *new_xino; + struct super_block *h_sb; + aufs_bindex_t bi, bend; + struct dentry *parent; + struct inode *dir; + + LKTRTrace("b%d\n", bindex); + SiMustWriteLock(sb); + + err = -EINVAL; + bend = au_sbend(sb); + if (unlikely(bindex < 0 || bend < bindex)) + goto out; + br = au_sbr(sb, bindex); + if (unlikely(!br->br_xino.xi_file)) + goto out; + + parent = dget_parent(br->br_xino.xi_file->f_dentry); + dir = parent->d_inode; + mutex_lock_nested(&dir->i_mutex, AuLsc_I_PARENT); + new_xino = au_xino_create2(sb, br->br_xino.xi_file, + br->br_xino.xi_file); + mutex_unlock(&dir->i_mutex); + dput(parent); + err = PTR_ERR(new_xino); + if (IS_ERR(new_xino)) + goto out; + err = 0; + fput(br->br_xino.xi_file); + br->br_xino.xi_file = new_xino; + + h_sb = br->br_mnt->mnt_sb; + for (bi = 0; bi <= bend; bi++) { + if (unlikely(bi == bindex)) + continue; + br = au_sbr(sb, bi); + if (br->br_mnt->mnt_sb != h_sb) + continue; + + fput(br->br_xino.xi_file); + br->br_xino.xi_file = new_xino; + get_file(new_xino); + } + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * create a xinofile at the default place/path. + */ +struct file *au_xino_def(struct super_block *sb) +{ + struct file *file; + aufs_bindex_t bend, bindex, bwr; + char *page, *p; + struct path path; + struct dentry *root; + + AuTraceEnter(); + + root = sb->s_root; + bend = au_sbend(sb); + bwr = -1; + for (bindex = 0; bindex <= bend; bindex++) + if (au_br_writable(au_sbr_perm(sb, bindex)) + && !au_test_nfs(au_h_dptr(root, bindex)->d_sb)) { + bwr = bindex; + break; + } + + if (bwr >= 0) { + file = ERR_PTR(-ENOMEM); + page = __getname(); + if (unlikely(!page)) + goto out; + path.mnt = au_sbr_mnt(sb, bwr); + path.dentry = au_h_dptr(root, bwr); + p = d_path(&path, page, PATH_MAX - sizeof(AUFS_XINO_FNAME)); + file = (void *)p; + if (!IS_ERR(p)) { + strcat(p, "/" AUFS_XINO_FNAME); + LKTRTrace("%s\n", p); + file = au_xino_create(sb, p, /*silent*/0); + if (!IS_ERR(file)) + au_xino_def_br_set(au_sbr(sb, bwr), au_sbi(sb)); + } + __putname(page); + } else { + file = au_xino_create(sb, AUFS_XINO_DEFPATH, /*silent*/0); + if (unlikely(au_test_nfs(file->f_dentry->d_sb))) { + AuErr("xino or noxino option is required " + "since %s is NFS\n", AUFS_XINO_DEFPATH); + fput(file); + file = ERR_PTR(-EINVAL); + } + if (!IS_ERR(file)) + au_xino_def_br_set(NULL, au_sbi(sb)); + } + + out: + AuTraceErrPtr(file); + return file; +} --- linux-2.6.28.orig/ubuntu/aufs/whout.c +++ linux-2.6.28/ubuntu/aufs/whout.c @@ -0,0 +1,1118 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * whiteout for logical deletion and opaque directory + * + * $Id: whout.c,v 1.13 2008/09/08 02:40:12 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +#define WH_MASK S_IRUGO + +/* If a directory contains this file, then it is opaque. We start with the + * .wh. flag so that it is blocked by lookup. + */ +static struct qstr diropq_name = { + .name = AUFS_WH_DIROPQ, + .len = sizeof(AUFS_WH_DIROPQ) - 1 +}; + +/* + * generate whiteout name, which is NOT terminated by NULL. + * @name: original d_name.name + * @len: original d_name.len + * @wh: whiteout qstr + * returns zero when succeeds, otherwise error. + * succeeded value as wh->name should be freed by au_wh_name_free(). + */ +int au_wh_name_alloc(const char *name, int len, struct qstr *wh) +{ + char *p; + + AuDebugOn(!name || !len || !wh); + + if (unlikely(len > PATH_MAX - AUFS_WH_PFX_LEN)) + return -ENAMETOOLONG; + + wh->len = len + AUFS_WH_PFX_LEN; + p = kmalloc(wh->len, GFP_NOFS); + wh->name = p; + if (p) { + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); + memcpy(p + AUFS_WH_PFX_LEN, name, len); + /* smp_mb(); */ + return 0; + } + return -ENOMEM; +} + +void au_wh_name_free(struct qstr *wh) +{ + AuDebugOn(!wh || !wh->name); + kfree(wh->name); +} + +/* ---------------------------------------------------------------------- */ + +/* + * test if the @wh_name exists under @h_parent. + * @try_sio specifies the necessary of super-io. + */ +int au_wh_test(struct dentry *h_parent, struct qstr *wh_name, int try_sio, + struct au_ndx *ndx) +{ + int err; + struct dentry *wh_dentry; + struct inode *h_dir; + unsigned int flags; + + LKTRTrace("%.*s/%.*s, ndx{%p, 0x%x}\n", AuDLNPair(h_parent), + wh_name->len, wh_name->name, ndx->nfsmnt, ndx->flags); + h_dir = h_parent->d_inode; + AuDebugOn(!S_ISDIR(h_dir->i_mode)); + + flags = 0; + if (ndx && ndx->nd) { + flags = ndx->nd->flags; + ndx->nd->flags &= ~(LOOKUP_OPEN | LOOKUP_CREATE); + } + + if (!try_sio) + wh_dentry = au_lkup_one(wh_name->name, h_parent, + wh_name->len, ndx); + else + wh_dentry = au_sio_lkup_one(wh_name->name, h_parent, + wh_name->len, ndx); + if (flags) + ndx->nd->flags = flags; + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out; + + err = 0; + if (!wh_dentry->d_inode) + goto out_wh; /* success */ + + err = 1; + if (S_ISREG(wh_dentry->d_inode->i_mode)) + goto out_wh; /* success */ + + err = -EIO; + AuIOErr("%.*s Invalid whiteout entry type 0%o.\n", + AuDLNPair(wh_dentry), wh_dentry->d_inode->i_mode); + + out_wh: + dput(wh_dentry); + out: + AuTraceErr(err); + return err; +} + +/* + * test if the @h_dentry sets opaque or not. + */ +int au_diropq_test(struct dentry *h_dentry, struct au_ndx *ndx) +{ + int err, try_sio; + struct inode *h_dir; + + LKTRTrace("dentry %.*s\n", AuDLNPair(h_dentry)); + h_dir = h_dentry->d_inode; + AuDebugOn(!S_ISDIR(h_dir->i_mode)); + + try_sio = au_test_h_perm_sio(h_dir, MAY_EXEC, + au_ftest_ndx(ndx->flags, DLGT)); + err = au_wh_test(h_dentry, &diropq_name, try_sio, ndx); + AuTraceErr(err); + return err; +} + +/* + * returns a negative dentry whose name is unique and temporary. + */ +struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct qstr *prefix, + struct au_ndx *ndx) +{ +#define HEX_LEN 4 + struct dentry *dentry; + int len, i; + char defname[AUFS_WH_PFX_LEN * 2 + DNAME_INLINE_LEN_MIN + 1 + + HEX_LEN + 1], *name, *p; + static unsigned char cnt; + + LKTRTrace("hp %.*s, prefix %.*s\n", + AuDLNPair(h_parent), prefix->len, prefix->name); + AuDebugOn(!h_parent->d_inode); + + name = defname; + len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1; + if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) { + dentry = ERR_PTR(-ENAMETOOLONG); + if (unlikely(len >= PATH_MAX)) + goto out; + dentry = ERR_PTR(-ENOMEM); + name = kmalloc(len + 1, GFP_NOFS); + if (unlikely(!name)) + goto out; + } + + /* doubly whiteout-ed */ + memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2); + p = name + AUFS_WH_PFX_LEN * 2; + memcpy(p, prefix->name, prefix->len); + p += prefix->len; + *p++ = '.'; + AuDebugOn(name + len + 1 - p <= HEX_LEN); + + for (i = 0; i < 3; i++) { + sprintf(p, "%.*d", HEX_LEN, cnt++); + dentry = au_sio_lkup_one(name, h_parent, len, ndx); + if (IS_ERR(dentry) || !dentry->d_inode) + goto out_name; + dput(dentry); + } + /* AuWarn("could not get random name\n"); */ + dentry = ERR_PTR(-EEXIST); + AuDbg("%.*s\n", len, name); + BUG(); + + out_name: + if (unlikely(name != defname)) + kfree(name); + out: + AuTraceErrPtr(dentry); + return dentry; +#undef HEX_LEN +} + +/* + * rename the @dentry of @bindex to the whiteouted temporary name. + */ +int au_whtmp_ren(struct inode *dir, aufs_bindex_t bindex, + struct dentry *h_dentry) +{ + int err, dlgt; + struct inode *h_dir; + struct dentry *h_parent, *tmp_dentry; + struct super_block *sb; + unsigned int mnt_flags; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + AuDebugOn(!h_dentry->d_inode); + h_parent = h_dentry->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + + sb = dir->i_sb; + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + if (unlikely(dlgt)) + au_fset_ndx(ndx.flags, DLGT); + ndx.nfsmnt = au_nfsmnt(sb, bindex); + tmp_dentry = au_whtmp_lkup(h_parent, &h_dentry->d_name, &ndx); + err = PTR_ERR(tmp_dentry); + if (IS_ERR(tmp_dentry)) + goto out; + + /* under the same dir, no need to lock_rename() */ + vfsub_args_init(&vargs, &ign, dlgt, 0); + AuDebugOn(!S_ISDIR(h_dentry->d_inode->i_mode)); + vfsub_ign_hinode(&vargs, IN_MOVED_FROM | IN_MOVED_TO, + au_hi(dir, bindex)); + err = vfsub_rename(h_dir, h_dentry, h_dir, tmp_dentry, &vargs); + AuTraceErr(err); + dput(tmp_dentry); + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int do_unlink_wh(struct au_hinode *hdir, struct inode *h_dir, + struct dentry *wh_dentry, const int dlgt) +{ + int err; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + AuDebugOn(hdir && h_dir); + AuDebugOn(!hdir && !h_dir); + if (!h_dir) + h_dir = hdir->hi_inode; + LKTRTrace("hi%lu, wh %.*s\n", h_dir->i_ino, AuDLNPair(wh_dentry)); + AuDebugOn(!wh_dentry->d_inode || !S_ISREG(wh_dentry->d_inode->i_mode)); + + /* + * forces superio when the dir has a sticky bit. + * this may be a violation of unix fs semantics. + */ + vfsub_args_init(&vargs, &ign, dlgt, + (h_dir->i_mode & S_ISVTX) + && wh_dentry->d_inode->i_uid != current->fsuid); + vfsub_ign_hinode(&vargs, IN_DELETE, hdir); + err = vfsub_unlink(h_dir, wh_dentry, &vargs); + AuTraceErr(err); + return err; +} + +int au_wh_unlink_dentry(struct au_hinode *hdir, struct dentry *wh_dentry, + struct dentry *dentry, int dlgt) +{ + int err; + + LKTRTrace("i%lu, wh %.*s, d %p\n", + hdir->hi_inode->i_ino, AuDLNPair(wh_dentry), dentry); + AuDebugOn((dentry && au_dbwh(dentry) < 0) + || !wh_dentry->d_inode + || !S_ISREG(wh_dentry->d_inode->i_mode)); + + err = do_unlink_wh(hdir, /*h_dir*/NULL, wh_dentry, dlgt); + if (!err && dentry) + au_set_dbwh(dentry, -1); + + AuTraceErr(err); + return err; +} + +static int unlink_wh_name(struct dentry *h_parent, struct qstr *wh, + struct au_ndx *ndx) +{ + int err; + struct dentry *wh_dentry; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(h_parent), AuLNPair(wh)); + + /* au_test_h_perm() is already done */ + wh_dentry = au_lkup_one(wh->name, h_parent, wh->len, ndx); + if (IS_ERR(wh_dentry)) + err = PTR_ERR(wh_dentry); + else { + err = 0; + if (wh_dentry->d_inode && S_ISREG(wh_dentry->d_inode->i_mode)) + err = do_unlink_wh(/*hdir*/NULL, h_parent->d_inode, + wh_dentry, + au_ftest_ndx(ndx->flags, DLGT)); + dput(wh_dentry); + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static void clean_wh(struct inode *h_dir, struct dentry *wh, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err; + + AuTraceEnter(); + + if (wh->d_inode) { + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + err = vfsub_unlink(h_dir, wh, vargs); + if (unlikely(err)) + AuWarn("failed unlink %.*s (%d), ignored.\n", + AuDLNPair(wh), err); + } +} + +static void au_whdir_clean(struct inode *h_dir, struct dentry *dentry, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err; + + AuTraceEnter(); + + if (dentry->d_inode) { + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_DELETE, hdir); + err = vfsub_rmdir(h_dir, dentry, vargs); + if (unlikely(err)) + AuWarn("failed rmdir %.*s (%d), ignored.\n", + AuDLNPair(dentry), err); + } +} + +static int test_linkable(struct inode *h_dir) +{ + if (h_dir->i_op && h_dir->i_op->link) + return 0; + return -ENOSYS; +} + +/* todo: should this mkdir be done in /sbin/mount.aufs script? */ +static int au_whdir(struct inode *h_dir, struct dentry *dentry, + struct au_hinode *hdir, struct vfsub_args *vargs) +{ + int err; + + err = -EEXIST; + if (!dentry->d_inode) { + int mode = S_IRWXU; + if (unlikely(au_test_nfs(dentry->d_sb))) + mode |= S_IXUGO; + vfsub_args_reinit(vargs); + vfsub_ign_hinode(vargs, IN_CREATE, hdir); + err = vfsub_mkdir(h_dir, dentry, mode, vargs); + } else if (S_ISDIR(dentry->d_inode->i_mode)) + err = 0; + else + AuErr("unknown %.*s exists\n", AuDLNPair(dentry)); + + return err; +} + +/* + * initialize the whiteout base file/dir for @br. + */ +int au_wh_init(struct dentry *h_root, struct au_branch *br, + struct vfsmount *nfsmnt, struct super_block *sb, + aufs_bindex_t bindex) +{ + int err, i; + struct inode *h_dir; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_hinode *hdir; + struct au_wbr *wbr = br->br_wbr; + static const struct qstr base_name[] = { + [AuBrWh_BASE] = { + .name = AUFS_WH_BASENAME, + .len = sizeof(AUFS_WH_BASENAME) - 1 + }, + [AuBrWh_PLINK] = { + .name = AUFS_WH_PLINKDIR, + .len = sizeof(AUFS_WH_PLINKDIR) - 1 + }, + [AuBrWh_TMP] = { + .name = AUFS_WH_TMPDIR, + .len = sizeof(AUFS_WH_TMPDIR) - 1 + } + }; + struct { + const struct qstr *name; + struct dentry *dentry; + } base[] = { + [AuBrWh_BASE] = { + .name = base_name + AuBrWh_BASE, + .dentry = NULL + }, + [AuBrWh_PLINK] = { + .name = base_name + AuBrWh_PLINK, + .dentry = NULL + }, + [AuBrWh_TMP] = { + .name = base_name + AuBrWh_TMP, + .dentry = NULL + } + }; + struct au_ndx ndx = { + .nfsmnt = nfsmnt, + .flags = 0, /* always no dlgt */ + .nd = NULL, + /* .br = NULL */ + }; + const unsigned int mnt_flags = au_mntflags(sb); + const int do_plink = au_opt_test(mnt_flags, PLINK); + const int do_hinotify = au_opt_test(mnt_flags, UDBA_INOTIFY); + + LKTRTrace("nfsmnt %p\n", nfsmnt); + WbrWhMustWriteLock(wbr); + SiMustWriteLock(sb); + h_dir = h_root->d_inode; + + for (i = 0; i < AuBrWh_Last; i++) { + /* doubly whiteouted */ + base[i].dentry = au_wh_lkup(h_root, (void *)base[i].name, &ndx); + err = PTR_ERR(base[i].dentry); + if (IS_ERR(base[i].dentry)) + goto out; + AuDebugOn(wbr + && wbr->wbr_wh[i] + && wbr->wbr_wh[i] != base[i].dentry); + } + + if (wbr) + for (i = 0; i < AuBrWh_Last; i++) { + dput(wbr->wbr_wh[i]); + wbr->wbr_wh[i] = NULL; + } + + err = 0; + hdir = NULL; + if (unlikely(bindex >= 0 && do_hinotify)) + hdir = au_hi(sb->s_root->d_inode, bindex); + vfsub_args_init(&vargs, &ign, au_test_dlgt(mnt_flags), 0); + + switch (br->br_perm) { + case AuBrPerm_RR: + case AuBrPerm_RO: + case AuBrPerm_RRWH: + case AuBrPerm_ROWH: + clean_wh(h_dir, base[AuBrWh_BASE].dentry, hdir, &vargs); + au_whdir_clean(h_dir, base[AuBrWh_PLINK].dentry, hdir, &vargs); + au_whdir_clean(h_dir, base[AuBrWh_TMP].dentry, hdir, &vargs); + break; + + case AuBrPerm_RWNoLinkWH: + clean_wh(h_dir, base[AuBrWh_BASE].dentry, hdir, &vargs); + if (do_plink) { + err = test_linkable(h_dir); + if (unlikely(err)) + goto out_nolink; + + err = au_whdir(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); + } else + au_whdir_clean(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + err = au_whdir(h_dir, base[AuBrWh_TMP].dentry, hdir, &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_tmp = dget(base[AuBrWh_TMP].dentry); + break; + + case AuBrPerm_RW: + /* + * for the moment, aufs supports the branch filesystem + * which does not support link(2). + * testing on FAT which does not support i_op->setattr() fully + * either, copyup failed. + * finally, such filesystem will not be used as the writable + * branch. + */ + err = test_linkable(h_dir); + if (unlikely(err)) + goto out_nolink; + + err = -EEXIST; + /* + * todo: should this create be done + * in /sbin/mount.aufs script? + */ + if (!base[AuBrWh_BASE].dentry->d_inode) { + vfsub_args_reinit(&vargs); + vfsub_ign_hinode(&vargs, IN_CREATE, hdir); + err = au_h_create(h_dir, base[AuBrWh_BASE].dentry, + WH_MASK, &vargs, /*nd*/NULL, nfsmnt); + } + else if (S_ISREG(base[AuBrWh_BASE].dentry->d_inode->i_mode)) + err = 0; + else + AuErr("unknown %.*s/%.*s exists\n", + AuDLNPair(h_root), + AuDLNPair(base[AuBrWh_BASE].dentry)); + if (unlikely(err)) + goto out_err; + + if (do_plink) { + err = au_whdir(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_plink = dget(base[AuBrWh_PLINK].dentry); + } else + au_whdir_clean(h_dir, base[AuBrWh_PLINK].dentry, hdir, + &vargs); + wbr->wbr_whbase = dget(base[AuBrWh_BASE].dentry); + + err = au_whdir(h_dir, base[AuBrWh_TMP].dentry, hdir, &vargs); + if (unlikely(err)) + goto out_err; + wbr->wbr_tmp = dget(base[AuBrWh_TMP].dentry); + break; + + default: + BUG(); + } + + out: + for (i = 0; i < AuBrWh_Last; i++) + dput(base[i].dentry); + AuTraceErr(err); + return err; + out_nolink: + AuErr("%.*s doesn't support link(2), use noplink and rw+nolwh\n", + AuDLNPair(h_root)); + goto out; + out_err: + AuErr("an error(%d) on the writable branch %.*s(%s)\n", + err, AuDLNPair(h_root), au_sbtype(h_root->d_sb)); + goto out; +} + +struct reinit_br_wh { + struct super_block *sb; + struct au_branch *br; +}; + +static void reinit_br_wh(void *arg) +{ + int err; + struct reinit_br_wh *a = arg; + struct au_wbr *wbr; + struct inode *h_dir, *dir; + struct dentry *h_root; + aufs_bindex_t bindex; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + AuTraceEnter(); + AuDebugOn(current->fsuid); + + err = 0; + wbr = a->br->br_wbr; + /* big aufs lock */ + si_noflush_write_lock(a->sb); + if (unlikely(!au_br_writable(a->br->br_perm))) + goto out; + bindex = au_br_index(a->sb, a->br->br_id); + if (unlikely(bindex < 0)) + goto out; + + AuDebugOn(!wbr); + AuDebugOn(!wbr->wbr_whbase || !wbr->wbr_whbase->d_inode); + + dir = a->sb->s_root->d_inode; + ii_read_lock_parent(dir); + h_root = dget_parent(wbr->wbr_whbase); + h_dir = h_root->d_inode; + AuDebugOn(!h_dir->i_op || !h_dir->i_op->link); + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + wbr_wh_write_lock(wbr); + if (!au_verify_parent(wbr->wbr_whbase, h_dir)) { + vfsub_args_init(&vargs, &ign, /*dlgt*/0, 0); + vfsub_ign_hinode(&vargs, IN_DELETE, au_hi(dir, bindex)); + err = vfsub_unlink(h_dir, wbr->wbr_whbase, &vargs); + } else { + AuWarn("%.*s is moved, ignored\n", AuDLNPair(wbr->wbr_whbase)); + err = 0; + } + dput(wbr->wbr_whbase); + wbr->wbr_whbase = NULL; + if (!err) + err = au_wh_init(h_root, a->br, au_do_nfsmnt(a->br->br_mnt), + a->sb, bindex); + wbr_wh_write_unlock(wbr); + mutex_unlock(&h_dir->i_mutex); + dput(h_root); + ii_read_unlock(dir); + + out: + if (wbr) + atomic_dec_return(&wbr->wbr_wh_running); + au_br_put(a->br); + au_nwt_done(&au_sbi(a->sb)->si_nowait); + si_write_unlock(a->sb); + kfree(arg); + if (unlikely(err)) + AuIOErr("err %d\n", err); +} + +static void kick_reinit_br_wh(struct super_block *sb, struct au_branch *br) +{ + int do_dec, wkq_err; + struct reinit_br_wh *arg; + + AuTraceEnter(); + AuDebugOn(!br->br_wbr); + + do_dec = 1; + if (atomic_inc_return(&br->br_wbr->wbr_wh_running) != 1) + goto out; + + /* ignore ENOMEM */ + arg = kmalloc(sizeof(*arg), GFP_NOFS); + if (arg) { + /* + * dec(wh_running), kfree(arg) and au_br_put() + * in reinit function + */ + arg->sb = sb; + arg->br = br; + au_br_get(br); + wkq_err = au_wkq_nowait(reinit_br_wh, arg, sb, /*dlgt*/0); + if (unlikely(wkq_err)) { + atomic_dec_return(&br->br_wbr->wbr_wh_running); + au_br_put(br); + kfree(arg); + } + do_dec = 0; + } + + out: + if (do_dec) + atomic_dec_return(&br->br_wbr->wbr_wh_running); +} + +/* + * create the whiteout @wh. + */ +static int link_or_create_wh(struct super_block *sb, aufs_bindex_t bindex, + struct dentry *wh, struct inode *dir) +{ + int err, dlgt; + struct au_branch *br; + struct au_wbr *wbr; + struct dentry *h_parent; + struct inode *h_dir; + struct au_hin_ignore ign; + struct vfsub_args vargs; + + LKTRTrace("%.*s\n", AuDLNPair(wh)); + h_parent = wh->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + br = au_sbr(sb, bindex); + wbr = br->br_wbr; + AuDebugOn(!wbr); + + dlgt = !!au_test_dlgt(au_mntflags(sb)); + wbr_wh_read_lock(wbr); + if (wbr->wbr_whbase) { + vfsub_args_init(&vargs, &ign, dlgt, 0); + if (unlikely(dir)) + vfsub_ign_hinode(&vargs, IN_CREATE, au_hi(dir, bindex)); + err = vfsub_link(wbr->wbr_whbase, h_dir, wh, &vargs); + if (!err || err != -EMLINK) + goto out; + + /* link count full. re-initialize br_whbase. */ + kick_reinit_br_wh(sb, br); + } + + /* return this error in this context */ + vfsub_args_init(&vargs, &ign, dlgt, 0); + if (unlikely(dir)) + vfsub_ign_hinode(&vargs, IN_CREATE, au_hi(dir, bindex)); + err = au_h_create(h_dir, wh, WH_MASK, &vargs, /*nd*/NULL, + au_do_nfsmnt(br->br_mnt)); + + out: + wbr_wh_read_unlock(wbr); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * create or remove the diropq. + */ +static struct dentry *do_diropq(struct dentry *dentry, aufs_bindex_t bindex, + unsigned int flags) +{ + struct dentry *opq_dentry, *h_dentry; + struct inode *h_dir; + int err, dlgt; + struct super_block *sb; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("%.*s, bindex %d, flags 0x%x\n", + AuDLNPair(dentry), bindex, flags); + h_dentry = au_h_dptr(dentry, bindex); + AuDebugOn(!h_dentry); + h_dir = h_dentry->d_inode; + AuDebugOn(!h_dir || !S_ISDIR(h_dir->i_mode)); + + /* already checked by au_test_h_perm(). */ + sb = dentry->d_sb; + ndx.nfsmnt = au_nfsmnt(sb, bindex); + dlgt = 0; + if (unlikely(au_ftest_diropq(flags, DLGT))) { + dlgt = 1; + au_fset_ndx(ndx.flags, DLGT); + } + opq_dentry = au_lkup_one(diropq_name.name, h_dentry, diropq_name.len, + &ndx); + if (IS_ERR(opq_dentry)) + goto out; + + if (au_ftest_diropq(flags, CREATE)) { + AuDebugOn(opq_dentry->d_inode); + err = link_or_create_wh(dentry->d_sb, bindex, opq_dentry, + dentry->d_inode); + if (!err) { + au_set_dbdiropq(dentry, bindex); + goto out; /* success */ + } + } else { + AuDebugOn(/* !S_ISDIR(dentry->d_inode->i_mode) + * || */!opq_dentry->d_inode); + err = do_unlink_wh(au_hi(dentry->d_inode, bindex), + /*h_dir*/NULL, opq_dentry, dlgt); + if (!err) + au_set_dbdiropq(dentry, -1); + } + dput(opq_dentry); + opq_dentry = ERR_PTR(err); + + out: + AuTraceErrPtr(opq_dentry); + return opq_dentry; +} + +struct do_diropq_args { + struct dentry **errp; + struct dentry *dentry; + aufs_bindex_t bindex; + unsigned int flags; +}; + +static void call_do_diropq(void *args) +{ + struct do_diropq_args *a = args; + *a->errp = do_diropq(a->dentry, a->bindex, a->flags); +} + +struct dentry *au_diropq_sio(struct dentry *dentry, aufs_bindex_t bindex, + unsigned int flags) +{ + struct dentry *diropq, *h_dentry; + + LKTRTrace("%.*s, bindex %d, flags 0x%x\n", + AuDLNPair(dentry), bindex, flags); + + h_dentry = au_h_dptr(dentry, bindex); + if (!au_test_h_perm_sio(h_dentry->d_inode, MAY_EXEC | MAY_WRITE, + au_ftest_diropq(flags, DLGT))) + diropq = do_diropq(dentry, bindex, flags); + else { + int wkq_err; + struct do_diropq_args args = { + .errp = &diropq, + .dentry = dentry, + .bindex = bindex, + .flags = flags + }; + wkq_err = au_wkq_wait(call_do_diropq, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + diropq = ERR_PTR(wkq_err); + } + + AuTraceErrPtr(diropq); + return diropq; +} + +/* ---------------------------------------------------------------------- */ + +/* + * lookup whiteout dentry. + * @h_parent: hidden parent dentry which must exist and be locked + * @base_name: name of dentry which will be whiteouted + * returns dentry for whiteout. + */ +struct dentry *au_wh_lkup(struct dentry *h_parent, struct qstr *base_name, + struct au_ndx *ndx) +{ + int err; + struct qstr wh_name; + struct dentry *wh_dentry; + + LKTRTrace("%.*s/%.*s\n", AuDLNPair(h_parent), AuLNPair(base_name)); + + err = au_wh_name_alloc(base_name->name, base_name->len, &wh_name); + wh_dentry = ERR_PTR(err); + if (!err) { + /* do not superio. */ + wh_dentry = au_lkup_one(wh_name.name, h_parent, + wh_name.len, ndx); + au_wh_name_free(&wh_name); + } + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +/* + * link/create a whiteout for @dentry on @bindex. + */ +struct dentry *au_wh_create(struct dentry *dentry, aufs_bindex_t bindex, + struct dentry *h_parent, struct au_ndx *ndx) +{ + struct dentry *wh_dentry; + struct inode *dir; + int err; + struct super_block *sb; + + LKTRTrace("%.*s/%.*s on b%d\n", AuDLNPair(h_parent), + AuDLNPair(dentry), bindex); + + sb = dentry->d_sb; + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, ndx); + if (!IS_ERR(wh_dentry) && !wh_dentry->d_inode) { + dir = dentry->d_parent->d_inode; /* dir is locked */ + IMustLock(dir); + err = link_or_create_wh(sb, bindex, wh_dentry, dir); + if (!err) + au_set_dbwh(dentry, bindex); + else { + dput(wh_dentry); + wh_dentry = ERR_PTR(err); + } + } + + AuTraceErrPtr(wh_dentry); + return wh_dentry; +} + +/* ---------------------------------------------------------------------- */ + +/* Delete all whiteouts in this directory on branch bindex. */ +static int del_wh_children(struct dentry *h_dentry, struct au_nhash *whlist, + aufs_bindex_t bindex, struct au_ndx *ndx) +{ + int err, i; + struct qstr wh_name; + char *p; + struct inode *h_inode; + struct hlist_head *head; + struct au_vdir_wh *tpos; + struct hlist_node *pos; + struct au_vdir_destr *str; + + LKTRTrace("%.*s\n", AuDLNPair(h_dentry)); + h_inode = h_dentry->d_inode; + AuDebugOn(IS_RDONLY(h_inode)); + + err = -ENOMEM; + p = __getname(); + wh_name.name = p; + if (unlikely(!wh_name.name)) + goto out; + memcpy(p, AUFS_WH_PFX, AUFS_WH_PFX_LEN); + p += AUFS_WH_PFX_LEN; + + /* already checked by au_test_h_perm(). */ + err = 0; + for (i = 0; !err && i < AuSize_NHASH; i++) { + head = whlist->heads + i; + hlist_for_each_entry(tpos, pos, head, wh_hash) { + if (tpos->wh_bindex != bindex) + continue; + str = &tpos->wh_str; + if (str->len + AUFS_WH_PFX_LEN <= PATH_MAX) { + memcpy(p, str->name, str->len); + wh_name.len = AUFS_WH_PFX_LEN + str->len; + err = unlink_wh_name(h_dentry, &wh_name, ndx); + if (!err) + continue; + break; + } + AuIOErr("whiteout name too long %.*s\n", + str->len, str->name); + err = -EIO; + break; + } + } + __putname(wh_name.name); + + out: + AuTraceErr(err); + return err; +} + +struct del_wh_children_args { + int *errp; + struct dentry *h_dentry; + struct au_nhash *whlist; + aufs_bindex_t bindex; + struct au_ndx *ndx; +}; + +static void call_del_wh_children(void *args) +{ + struct del_wh_children_args *a = args; + *a->errp = del_wh_children(a->h_dentry, a->whlist, a->bindex, a->ndx); +} + +/* ---------------------------------------------------------------------- */ + +/* + * rmdir the whiteouted temporary named dir @h_dentry. + * @whlist: whiteouted children. + */ +int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist) +{ + int err, dlgt; + struct inode *wh_inode, *h_dir; + struct super_block *sb; + unsigned int mnt_flags; + struct au_hin_ignore ign; + struct vfsub_args vargs; + struct au_ndx ndx = { + .flags = 0, + .nd = NULL, + /* .br = NULL */ + }; + + LKTRTrace("i%lu, %.*s, b%d\n", + dir->i_ino, AuDLNPair(wh_dentry), bindex); + /* IMustLock(dir); */ + IiMustAnyLock(dir); + h_dir = wh_dentry->d_parent->d_inode; /* dir inode is locked */ + IMustLock(h_dir); + + sb = dir->i_sb; + mnt_flags = au_mntflags(sb); + dlgt = !!au_test_dlgt(mnt_flags); + if (unlikely(dlgt)) + au_fset_ndx(ndx.flags, DLGT); + ndx.nfsmnt = au_nfsmnt(sb, bindex); + wh_inode = wh_dentry->d_inode; + mutex_lock_nested(&wh_inode->i_mutex, AuLsc_I_CHILD); + + /* + * someone else might change some whiteouts while we were sleeping. + * it means this whlist may have an obsoleted entry. + */ + if (!au_test_h_perm_sio(wh_inode, MAY_EXEC | MAY_WRITE, dlgt)) + err = del_wh_children(wh_dentry, whlist, bindex, &ndx); + else { + int wkq_err; + /* ugly */ + unsigned int flags = ndx.flags; + struct del_wh_children_args args = { + .errp = &err, + .h_dentry = wh_dentry, + .whlist = whlist, + .bindex = bindex, + .ndx = &ndx + }; + + ndx.flags = 0; + wkq_err = au_wkq_wait(call_del_wh_children, &args, /*dlgt*/0); + if (unlikely(wkq_err)) + err = wkq_err; + ndx.flags = flags; + } + mutex_unlock(&wh_inode->i_mutex); + + if (!err) { + vfsub_args_init(&vargs, &ign, dlgt, 0); + vfsub_ign_hinode(&vargs, IN_DELETE, au_hi(dir, bindex)); + err = vfsub_rmdir(h_dir, wh_dentry, &vargs); + /* d_drop(h_dentry); */ + } + + if (!err) { + if (au_ibstart(dir) == bindex) { + au_cpup_attr_timesizes(dir); + /* au_cpup_attr_nlink(dir); */ + drop_nlink(dir); + } + return 0; /* success */ + } + + AuWarn("failed removing %.*s(%d), ignored\n", + AuDLNPair(wh_dentry), err); + return err; +} + +static void au_whtmp_rmdir_free_args(struct au_whtmp_rmdir_args *args) +{ + au_nhash_fin(&args->whlist); + dput(args->wh_dentry); + iput(args->dir); + kfree(args); +} + +static void call_rmdir_whtmp(void *args) +{ + int err; + struct au_whtmp_rmdir_args *a = args; + struct super_block *sb; + struct dentry *h_parent; + struct inode *h_dir; + + LKTRTrace("%.*s, b%d, dir i%lu\n", + AuDLNPair(a->wh_dentry), a->bindex, a->dir->i_ino); + + /* rmdir by nfsd may cause deadlock with this i_mutex */ + /* mutex_lock(&a->dir->i_mutex); */ + sb = a->dir->i_sb; + si_noflush_read_lock(sb); + err = au_test_ro(sb, a->bindex, NULL); + if (unlikely(err)) + goto out; + + err = -EIO; + ii_write_lock_parent(a->dir); + h_parent = dget_parent(a->wh_dentry); + h_dir = h_parent->d_inode; + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + if (!au_verify_parent(a->wh_dentry, h_dir)) + err = au_whtmp_rmdir(a->dir, a->bindex, a->wh_dentry, + &a->whlist); + mutex_unlock(&h_dir->i_mutex); + dput(h_parent); + ii_write_unlock(a->dir); + + out: + /* mutex_unlock(&a->dir->i_mutex); */ + au_nwt_done(&au_sbi(sb)->si_nowait); + si_read_unlock(sb); + au_whtmp_rmdir_free_args(a); + if (unlikely(err)) + AuIOErr("err %d\n", err); +} + +void au_whtmp_kick_rmdir(struct inode *dir, aufs_bindex_t bindex, + struct dentry *wh_dentry, struct au_nhash *whlist, + struct au_whtmp_rmdir_args *args) +{ + int wkq_err; + + LKTRTrace("%.*s\n", AuDLNPair(wh_dentry)); + IMustLock(dir); + + /* all post-process will be done in do_rmdir_whtmp(). */ + args->dir = au_igrab(dir); + args->bindex = bindex; + args->wh_dentry = dget(wh_dentry); + au_nhash_init(&args->whlist); + au_nhash_move(&args->whlist, whlist); + wkq_err = au_wkq_nowait(call_rmdir_whtmp, args, dir->i_sb, /*dlgt*/0); + if (unlikely(wkq_err)) { + AuWarn("rmdir error %.*s (%d), ignored\n", + AuDLNPair(wh_dentry), wkq_err); + au_whtmp_rmdir_free_args(args); + } +} --- linux-2.6.28.orig/ubuntu/aufs/branch.c +++ linux-2.6.28/ubuntu/aufs/branch.c @@ -0,0 +1,1025 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * branch management + * + * $Id: branch.c,v 1.16 2008/09/08 02:39:41 sfjro Exp $ + */ + +#include +#include +#include +#include +#include "aufs.h" + +static void au_br_do_free(struct au_branch *br) +{ + int i; + struct au_wbr *wbr; + + AuTraceEnter(); + + if (br->br_xino.xi_file) + fput(br->br_xino.xi_file); + wbr = br->br_wbr; + if (wbr) + for (i = 0; i < AuBrWh_Last; i++) + dput(wbr->wbr_wh[i]); + /* do not call au_br_nfs_lockdep_off() here */ + if (!au_test_nfs(br->br_mnt->mnt_sb)) + mntput(br->br_mnt); + else { + lockdep_off(); + mntput(br->br_mnt); + lockdep_on(); + } + AuDebugOn(au_br_count(br)); + if (wbr) + AuDebugOn(atomic_read(&wbr->wbr_wh_running)); + kfree(wbr); + kfree(br); +} + +/* + * frees all branches + */ +void au_br_free(struct au_sbinfo *sbinfo) +{ + aufs_bindex_t bmax; + struct au_branch **br; + + AuTraceEnter(); + bmax = sbinfo->si_bend + 1; + br = sbinfo->si_branch; + while (bmax--) + au_br_do_free(*br++); +} + +/* + * find the index of a branch which is specified by @br_id. + */ +int au_br_index(struct super_block *sb, aufs_bindex_t br_id) +{ + aufs_bindex_t bindex, bend; + + AuTraceEnter(); + + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) + if (au_sbr_id(sb, bindex) == br_id) + return bindex; + return -1; +} + +/* + * test if the @h_sb is real-readonly. + */ +int au_test_def_rr(struct super_block *h_sb) +{ + switch (h_sb->s_magic) { +#ifdef CONFIG_AUFS_RR_SQUASHFS + case SQUASHFS_MAGIC_LZMA: + case SQUASHFS_MAGIC: + case SQUASHFS_MAGIC_LZMA_SWAP: + case SQUASHFS_MAGIC_SWAP: + return 1; /* real readonly */ +#endif + +#if defined(CONFIG_ISO9660_FS) || defined(CONFIG_ISO9660_FS_MODULE) + case ISOFS_SUPER_MAGIC: + return 1; +#endif + +#if defined(CONFIG_CRAMFS) || defined(CONFIG_CRAMFS_MODULE) + case CRAMFS_MAGIC: + return 1; +#endif + +#if defined(CONFIG_ROMFS_FS) || defined(CONFIG_ROMFS_FS_MODULE) + case ROMFS_MAGIC: + return 1; +#endif + + default: + return 0; + } +} + +/* ---------------------------------------------------------------------- */ + +/* + * test if two hidden_dentries have overlapping branches. + */ +static int do_test_overlap(struct super_block *sb, struct dentry *h_d1, + struct dentry *h_d2) +{ + struct dentry *d; + + LKTRTrace("%.*s, %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2)); + + d = au_test_subdir(h_d1, h_d2); + if (unlikely(d)) { + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + } + return !!d; +} + +static int test_overlap_loopback(struct super_block *sb, struct dentry *h_d1, + struct dentry *h_d2) +{ +#if defined(CONFIG_BLK_DEV_LOOP) || defined(CONFIG_BLK_DEV_LOOP_MODULE) + struct inode *h_inode; + struct loop_device *l; + + LKTRTrace("%.*s, %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2)); + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + AuDbgSb(h_d1->d_sb); + AuDbgSb(h_d2->d_sb); + + h_inode = h_d1->d_inode; + if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR) + return 0; + + l = h_inode->i_sb->s_bdev->bd_disk->private_data; + h_d1 = l->lo_backing_file->f_dentry; + /* h_d1 can be local NFS. in this case aufs cannot detect the loop */ + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + AuDbgSb(h_d1->d_sb); + AuDbgSb(h_d2->d_sb); + if (unlikely(h_d1->d_sb == sb)) + return 1; + return do_test_overlap(sb, h_d1, h_d2); +#else + return 0; +#endif +} + +static int test_overlap(struct super_block *sb, struct dentry *h_d1, + struct dentry *h_d2) +{ + LKTRTrace("d1 %.*s, d2 %.*s\n", AuDLNPair(h_d1), AuDLNPair(h_d2)); + + if (unlikely(h_d1 == h_d2)) { + AuDbgDentry(h_d1); + AuDbgDentry(h_d2); + return 1; + } + return do_test_overlap(sb, h_d1, h_d2) + || do_test_overlap(sb, h_d2, h_d1) + || test_overlap_loopback(sb, h_d1, h_d2) + || test_overlap_loopback(sb, h_d2, h_d1); +} + +/* ---------------------------------------------------------------------- */ + +static int au_br_init_wh(struct super_block *sb, aufs_bindex_t bindex, + struct au_branch *br, int new_perm, + struct dentry *h_root, struct vfsmount *h_mnt) +{ + int err, old_perm; + struct inode *h_dir; + struct au_wbr *wbr; + + LKTRTrace("b%d, new_perm %d\n", bindex, new_perm); + + wbr = br->br_wbr; + h_dir = h_root->d_inode; + old_perm = br->br_perm; + mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_PARENT); + if (wbr) + wbr_wh_write_lock(wbr); + br->br_perm = new_perm; + err = au_wh_init(h_root, br, au_do_nfsmnt(h_mnt), sb, bindex); + br->br_perm = old_perm; + if (wbr) + wbr_wh_write_unlock(wbr); + mutex_unlock(&h_dir->i_mutex); + if (!err && wbr && !au_br_writable(new_perm)) { + AuDebugOn(wbr->wbr_whbase); + AuDebugOn(wbr->wbr_plink); + AuDebugOn(wbr->wbr_tmp); + kfree(wbr); + br->br_wbr = NULL; + } + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* + * returns a newly allocated branch. @new_nbranch is a number of branches + * after adding a branch. + */ +static struct au_branch *alloc_addbr(struct super_block *sb, int new_nbranch, + int perm) +{ + struct au_branch **branchp, *add_branch; + int sz; + void *p; + struct dentry *root; + struct inode *inode; + struct au_hinode *hinodep; + struct au_hdentry *hdentryp; + + LKTRTrace("new_nbranch %d\n", new_nbranch); + SiMustWriteLock(sb); + root = sb->s_root; + DiMustWriteLock(root); + inode = root->d_inode; + IiMustWriteLock(inode); + + add_branch = kmalloc(sizeof(*add_branch), GFP_NOFS); + if (unlikely(!add_branch)) + goto out; + add_branch->br_wbr = NULL; + if (unlikely(au_br_writable(perm))) { + add_branch->br_wbr = kmalloc(sizeof(*add_branch->br_wbr), + GFP_NOFS); + if (unlikely(!add_branch->br_wbr)) + goto out_br; + } + + sz = sizeof(*branchp) * (new_nbranch - 1); + if (unlikely(!sz)) + sz = sizeof(*branchp); + p = au_sbi(sb)->si_branch; + branchp = au_kzrealloc(p, sz, sizeof(*branchp) * new_nbranch, GFP_NOFS); + if (unlikely(!branchp)) + goto out_wbr; + au_sbi(sb)->si_branch = branchp; + + sz = sizeof(*hdentryp) * (new_nbranch - 1); + if (unlikely(!sz)) + sz = sizeof(*hdentryp); + p = au_di(root)->di_hdentry; + hdentryp = au_kzrealloc(p, sz, sizeof(*hdentryp) * new_nbranch, + GFP_NOFS); + if (unlikely(!hdentryp)) + goto out_wbr; + au_di(root)->di_hdentry = hdentryp; + + sz = sizeof(*hinodep) * (new_nbranch - 1); + if (unlikely(!sz)) + sz = sizeof(*hinodep); + p = au_ii(inode)->ii_hinode; + hinodep = au_kzrealloc(p, sz, sizeof(*hinodep) * new_nbranch, GFP_NOFS); + if (unlikely(!hinodep)) + goto out_wbr; + au_ii(inode)->ii_hinode = hinodep; + return add_branch; /* success */ + + out_wbr: + kfree(add_branch->br_wbr); + out_br: + kfree(add_branch); + out: + AuTraceErr(-ENOMEM); + return ERR_PTR(-ENOMEM); +} + +/* + * test if the branch permission is legal or not. + */ +static int test_br(struct super_block *sb, struct inode *inode, int brperm, + char *path) +{ + int err; + + err = 0; + if (unlikely(au_br_writable(brperm) && IS_RDONLY(inode))) { + AuErr("write permission for readonly fs or inode, %s\n", path); + err = -EINVAL; + } + + AuTraceErr(err); + return err; +} + +static int au_unsupported_fs(struct super_block *sb) +{ + return (sb->s_magic == PROC_SUPER_MAGIC +#ifdef SYSFS_MAGIC + || sb->s_magic == SYSFS_MAGIC +#endif + || !strcmp(au_sbtype(sb), "unionfs")); +} + +/* + * returns: + * 0: success, the caller will add it + * plus: success, it is already unified, the caller should ignore it + * minus: error + */ +static int test_add(struct super_block *sb, struct au_opt_add *add, int remount) +{ + int err; + struct dentry *root; + struct inode *inode, *h_inode; + aufs_bindex_t bend, bindex; + + LKTRTrace("%s, remo%d\n", add->path, remount); + + root = sb->s_root; + bend = au_sbend(sb); + if (unlikely(bend >= 0 + && au_find_dbindex(root, add->nd.path.dentry) >= 0)) { + err = 1; + if (!remount) { + err = -EINVAL; + AuErr("%s duplicated\n", add->path); + } + goto out; + } + + err = -ENOSPC; /* -E2BIG; */ + if (unlikely(AUFS_BRANCH_MAX <= add->bindex + || AUFS_BRANCH_MAX - 1 <= bend)) { + AuErr("number of branches exceeded %s\n", add->path); + goto out; + } + + err = -EDOM; + if (unlikely(add->bindex < 0 || bend + 1 < add->bindex)) { + AuErr("bad index %d\n", add->bindex); + goto out; + } + + inode = add->nd.path.dentry->d_inode; + AuDebugOn(!inode || !S_ISDIR(inode->i_mode)); + err = -ENOENT; + if (unlikely(!inode->i_nlink)) { + AuErr("no existence %s\n", add->path); + goto out; + } + + err = -EINVAL; + if (unlikely(inode->i_sb == sb)) { + AuErr("%s must be outside\n", add->path); + goto out; + } + + if (unlikely(au_test_nested(inode->i_sb))) { + AuErr("nested " AUFS_NAME " %s\n", add->path); + goto out; + } + + if (unlikely(au_unsupported_fs(inode->i_sb))) { + AuErr("unsupported filesystem, %s\n", add->path); + goto out; + } + + if (unlikely(au_test_unsupported_nfs(inode->i_sb))) { + AuErr(AuNoNfsBranchMsg " %s\n", add->path); + goto out; + } + + err = test_br(sb, add->nd.path.dentry->d_inode, add->perm, add->path); + if (unlikely(err)) + goto out; + + if (bend < 0) + return 0; /* success */ + + err = -EINVAL; + for (bindex = 0; bindex <= bend; bindex++) + if (unlikely(test_overlap(sb, add->nd.path.dentry, + au_h_dptr(root, bindex)))) { + AuErr("%s is overlapped\n", add->path); + goto out; + } + + err = 0; + h_inode = au_h_dptr(root, 0)->d_inode; + if (unlikely(au_opt_test(au_mntflags(sb), WARN_PERM) + && ((h_inode->i_mode & S_IALLUGO) + != (inode->i_mode & S_IALLUGO) + || h_inode->i_uid != inode->i_uid + || h_inode->i_gid != inode->i_gid))) + AuWarn("uid/gid/perm %s %u/%u/0%o, %u/%u/0%o\n", + add->path, + inode->i_uid, inode->i_gid, (inode->i_mode & S_IALLUGO), + h_inode->i_uid, h_inode->i_gid, + (h_inode->i_mode & S_IALLUGO)); + + out: + AuTraceErr(err); + return err; +} + +static int au_wbr_init(struct au_branch *br, struct super_block *sb, + int perm, struct path *path) +{ + int err; + struct au_wbr *wbr; + + AuTraceEnter(); + wbr = br->br_wbr; + AuDebugOn(!wbr); + + au_rw_init_nolock(&wbr->wbr_wh_rwsem); + memset(wbr->wbr_wh, 0, sizeof(wbr->wbr_wh)); + atomic_set(&wbr->wbr_wh_running, 0); + wbr->wbr_bytes = 0; + + err = au_br_init_wh(sb, /*bindex*/-1, br, perm, + path->dentry, path->mnt); + + AuTraceErr(err); + return err; +} + +static int au_br_init(struct au_branch *br, struct super_block *sb, + struct au_opt_add *add) +{ + int err; + unsigned int mnt_flags; + + AuTraceEnter(); + + err = 0; + if (unlikely(au_br_writable(add->perm))) { + err = au_wbr_init(br, sb, add->perm, &add->nd.path); + if (unlikely(err)) + goto out; + } + + br->br_xino.xi_file = NULL; + mutex_init(&br->br_xino.xi_nondir_mtx); + br->br_mnt = mntget(add->nd.path.mnt); + mnt_flags = au_mntflags(sb); + if (au_opt_test(mnt_flags, XINO)) { + err = au_xino_br(sb, br, add->nd.path.dentry->d_inode->i_ino, + au_sbr(sb, 0)->br_xino.xi_file, /*do_test*/1); + if (unlikely(err)) { + AuDebugOn(br->br_xino.xi_file); + goto out; + } +#if 0 /* reserved for future use */ + } else if (au_opt_test(mnt_flags, XINODIR)) { + err = au_xinodir_br(sb, br, add->nd.path.dentry->d_inode->i_ino, + /*do_test*/1); + if (unlikely(err)) { + AuDebugOn(br->br_xino.xi_file); + goto out; + } +#endif + } + + br->br_id = au_new_br_id(sb); + br->br_perm = add->perm; + atomic_set(&br->br_count, 0); + br->br_xino_upper = AUFS_XINO_TRUNC_INIT; + atomic_set(&br->br_xino_running, 0); + sysaufs_br_init(br); + br->br_generation = au_sigen(sb); + /* smp_mb(); */ /* atomic_set */ + + out: + AuTraceErr(err); + return err; +} + +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount) +{ + int err, amount; + aufs_bindex_t bend, add_bindex; + struct dentry *root, *dentry; + struct au_iinfo *iinfo; + struct au_sbinfo *sbinfo; + struct au_dinfo *dinfo; + struct inode *root_inode; + unsigned long long maxb; + struct au_branch **branchp, *add_branch; + struct au_hdentry *hdentryp; + struct au_hinode *hinodep; + + dentry = add->nd.path.dentry; + LKTRTrace("b%d, %s, 0x%x, %.*s\n", + add->bindex, add->path, add->perm, AuDLNPair(dentry)); + SiMustWriteLock(sb); + root = sb->s_root; + DiMustWriteLock(root); + root_inode = root->d_inode; + IMustLock(root_inode); + IiMustWriteLock(root_inode); + + err = test_add(sb, add, remount); + if (unlikely(err < 0)) + goto out; + if (err) + return 0; /* success */ + + bend = au_sbend(sb); + add_branch = alloc_addbr(sb, bend + 2, add->perm); + err = PTR_ERR(add_branch); + if (IS_ERR(add_branch)) + goto out; + err = au_br_init(add_branch, sb, add); + if (unlikely(err)) { + au_br_do_free(add_branch); + goto out; + } + + add_bindex = add->bindex; + if (remount) + sysaufs_brs_del(sb, add_bindex); + + sbinfo = au_sbi(sb); + dinfo = au_di(root); + iinfo = au_ii(root_inode); + + amount = bend + 1 - add_bindex; + branchp = sbinfo->si_branch + add_bindex; + memmove(branchp + 1, branchp, sizeof(*branchp) * amount); + *branchp = add_branch; + hdentryp = dinfo->di_hdentry + add_bindex; + memmove(hdentryp + 1, hdentryp, sizeof(*hdentryp) * amount); + au_h_dentry_init(hdentryp); + hinodep = iinfo->ii_hinode + add_bindex; + memmove(hinodep + 1, hinodep, sizeof(*hinodep) * amount); + hinodep->hi_inode = NULL; + au_hin_init(hinodep, NULL); + + sbinfo->si_bend++; + dinfo->di_bend++; + iinfo->ii_bend++; + if (unlikely(bend < 0)) { + sbinfo->si_bend = 0; + dinfo->di_bstart = 0; + iinfo->ii_bstart = 0; + } + au_set_h_dptr(root, add_bindex, dget(dentry)); + au_set_h_iptr(root_inode, add_bindex, au_igrab(dentry->d_inode), 0); + if (remount) + sysaufs_brs_add(sb, add_bindex); + + if (!add_bindex) + au_cpup_attr_all(root_inode); + else + au_add_nlink(root_inode, dentry->d_inode); + maxb = dentry->d_sb->s_maxbytes; + if (sb->s_maxbytes < maxb) + sb->s_maxbytes = maxb; + + /* safe d_parent reference */ + if (!au_xino_def_br(sbinfo) + && add_branch->br_xino.xi_file + && add_branch->br_xino.xi_file->f_dentry->d_parent == dentry) + au_xino_def_br_set(add_branch, sbinfo); + + out: + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +#define AuVerbose(do_info, fmt, args...) do { \ + if (!do_info) \ + LKTRTrace(fmt, ##args); \ + else \ + AuInfo(fmt, ##args); \ +} while (0) + +/* + * test if the branch is deletable or not. + */ +static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex, + au_gen_t sigen) +{ + int err, i, j, ndentry; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry *d; + aufs_bindex_t bstart, bend; + unsigned char verbose; + struct inode *inode; + + LKTRTrace("b%d, gen%d\n", bindex, sigen); + SiMustWriteLock(root->d_sb); + + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) + goto out; + err = au_dcsub_pages(&dpages, root, NULL, NULL); + if (unlikely(err)) + goto out_dpages; + + verbose = !!au_opt_test(au_mntflags(root->d_sb), VERBOSE); + for (i = 0; !err && i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + ndentry = dpage->ndentry; + for (j = 0; !err && j < ndentry; j++) { + d = dpage->dentries[j]; + AuDebugOn(!atomic_read(&d->d_count)); + inode = d->d_inode; + AuDebugOn(!inode); + if (au_digen(d) == sigen + && au_iigen(inode) == sigen) + di_read_lock_child(d, AuLock_IR); + else { + di_write_lock_child(d); + err = au_reval_dpath(d, sigen); + if (!err) + di_downgrade_lock(d, AuLock_IR); + else { + di_write_unlock(d); + break; + } + } + + bstart = au_dbstart(d); + bend = au_dbend(d); + if (bstart <= bindex + && bindex <= bend + && au_h_dptr(d, bindex) + && (!S_ISDIR(d->d_inode->i_mode) + || bstart == bend)) { + err = -EBUSY; + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d)); + } + di_read_unlock(d, AuLock_IR); + } + } + + out_dpages: + au_dpages_free(&dpages); + out: + AuTraceErr(err); + return err; +} + +static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex, + au_gen_t sigen) +{ + int err; + struct inode *i; + aufs_bindex_t bstart, bend; + unsigned char verbose; + + LKTRTrace("b%d, gen%d\n", bindex, sigen); + SiMustWriteLock(sb); + + err = 0; + verbose = !!au_opt_test(au_mntflags(sb), VERBOSE); + list_for_each_entry(i, &sb->s_inodes, i_sb_list) { + AuDebugOn(!atomic_read(&i->i_count)); + if (!list_empty(&i->i_dentry)) + continue; + + if (au_iigen(i) == sigen) + ii_read_lock_child(i); + else { + ii_write_lock_child(i); + err = au_refresh_hinode_self(i); + if (!err) + ii_downgrade_lock(i); + else { + ii_write_unlock(i); + break; + } + } + + bstart = au_ibstart(i); + bend = au_ibend(i); + if (bstart <= bindex + && bindex <= bend + && au_h_iptr(i, bindex) + && (!S_ISDIR(i->i_mode) || bstart == bend)) { + err = -EBUSY; + AuVerbose(verbose, "busy i%lu\n", i->i_ino); + ii_read_unlock(i); + break; + } + ii_read_unlock(i); + } + + AuTraceErr(err); + return err; +} + +static int test_children_busy(struct dentry *root, aufs_bindex_t bindex) +{ + int err; + au_gen_t sigen; + + LKTRTrace("b%d\n", bindex); + SiMustWriteLock(root->d_sb); + DiMustWriteLock(root); + /* dont trust BKL */ + AuDebugOn(!kernel_locked()); + + sigen = au_sigen(root->d_sb); + DiMustNoWaiters(root); + IiMustNoWaiters(root->d_inode); + di_write_unlock(root); + err = test_dentry_busy(root, bindex, sigen); + if (!err) + err = test_inode_busy(root->d_sb, bindex, sigen); + di_write_lock_child(root); /* aufs_write_lock() calls ..._child() */ + + AuTraceErr(err); + return err; +} + +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount) +{ + int err, rerr, i; + aufs_bindex_t bindex, bend, br_id; + unsigned char do_wh, verbose; + struct au_sbinfo *sbinfo; + struct au_dinfo *dinfo; + struct au_iinfo *iinfo; + struct au_branch *br, **brp; + struct au_wbr *wbr; + struct au_hdentry *hdp; + struct au_hinode *hip; + + LKTRTrace("%s, %.*s\n", del->path, AuDLNPair(del->h_root)); + SiMustWriteLock(sb); + DiMustWriteLock(sb->s_root); + IiMustWriteLock(sb->s_root->d_inode); + + err = 0; + bindex = au_find_dbindex(sb->s_root, del->h_root); + if (bindex < 0) { + if (remount) + goto out; /* success */ + err = -ENOENT; + AuErr("%s no such branch\n", del->path); + goto out; + } + LKTRTrace("bindex b%d\n", bindex); + + err = -EBUSY; + verbose = !!au_opt_test(au_mntflags(sb), VERBOSE); + bend = au_sbend(sb); + if (unlikely(!bend)) { + AuVerbose(verbose, "no more branches left\n"); + goto out; + } + br = au_sbr(sb, bindex); + if (unlikely(au_br_count(br))) { + AuVerbose(verbose, "%d file(s) opened\n", au_br_count(br)); + goto out; + } + + wbr = br->br_wbr; + do_wh = wbr && (wbr->wbr_whbase || wbr->wbr_plink || wbr->wbr_tmp); + if (do_wh) { +#if 0 /* reserved for future use */ + /* remove whiteout base */ + err = au_br_init_wh(sb, bindex, br, AuBr_RO, del->h_root, + br->br_mnt); + if (unlikely(err)) + goto out; +#else + for (i = 0; i < AuBrWh_Last; i++) { + dput(wbr->wbr_wh[i]); + wbr->wbr_wh[i] = NULL; + } +#endif + } + + err = test_children_busy(sb->s_root, bindex); + if (unlikely(err)) { + if (unlikely(do_wh)) + goto out_wh; + goto out; + } + + err = 0; + if (remount) + sysaufs_brs_del(sb, bindex); + sbinfo = au_sbi(sb); + dinfo = au_di(sb->s_root); + iinfo = au_ii(sb->s_root->d_inode); + + dput(au_h_dptr(sb->s_root, bindex)); + au_hiput(iinfo->ii_hinode + bindex); + br_id = br->br_id; + au_br_do_free(br); + + /* todo: realloc and shrink memory? */ + if (bindex < bend) { + const aufs_bindex_t n = bend - bindex; + + brp = sbinfo->si_branch + bindex; + memmove(brp, brp + 1, sizeof(*brp) * n); + hdp = dinfo->di_hdentry + bindex; + memmove(hdp, hdp + 1, sizeof(*hdp) * n); + hip = iinfo->ii_hinode + bindex; + memmove(hip, hip + 1, sizeof(*hip) * n); + } + sbinfo->si_branch[0 + bend] = NULL; + dinfo->di_hdentry[0 + bend].hd_dentry = NULL; + iinfo->ii_hinode[0 + bend].hi_inode = NULL; + au_hin_init(iinfo->ii_hinode + bend, NULL); + + sbinfo->si_bend--; + dinfo->di_bend--; + iinfo->ii_bend--; + if (remount) + sysaufs_brs_add(sb, bindex); + + if (!bindex) + au_cpup_attr_all(sb->s_root->d_inode); + else + au_sub_nlink(sb->s_root->d_inode, del->h_root->d_inode); + if (au_opt_test(au_mntflags(sb), PLINK)) + au_plink_half_refresh(sb, br_id); + + if (sb->s_maxbytes == del->h_root->d_sb->s_maxbytes) { + bend--; + sb->s_maxbytes = 0; + for (bindex = 0; bindex <= bend; bindex++) { + unsigned long long maxb; + maxb = au_sbr_sb(sb, bindex)->s_maxbytes; + if (sb->s_maxbytes < maxb) + sb->s_maxbytes = maxb; + } + } + + if (au_xino_def_br(sbinfo) == br) + au_xino_def_br_set(NULL, sbinfo); + goto out; /* success */ + + out_wh: + /* revert */ + rerr = au_br_init_wh(sb, bindex, br, br->br_perm, del->h_root, + br->br_mnt); + if (rerr) + AuWarn("failed re-creating base whiteout, %s. (%d)\n", + del->path, rerr); + out: + AuTraceErr(err); + return err; +} + +static int do_need_sigen_inc(int a, int b) +{ + return (au_br_whable(a) && !au_br_whable(b)); +} + +static int need_sigen_inc(int old, int new) +{ + return (do_need_sigen_inc(old, new) + || do_need_sigen_inc(new, old)); +} + +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) +{ + int err; + struct file *file, *hf; + + AuTraceEnter(); + SiMustWriteLock(sb); + + /* no need file_list_lock() since sbinfo is locked */ + err = 0; + list_for_each_entry(file, &sb->s_files, f_u.fu_list) { + LKTRTrace("%.*s\n", AuDLNPair(file->f_dentry)); + if (!au_test_aufs_file(file)) + continue; + + fi_read_lock(file); + if (!S_ISREG(file->f_dentry->d_inode->i_mode) + || !(file->f_mode & FMODE_WRITE) + || au_fbstart(file) != bindex) { + FiMustNoWaiters(file); + fi_read_unlock(file); + continue; + } + + if (unlikely(au_test_mmapped(file))) { + err = -EBUSY; + FiMustNoWaiters(file); + fi_read_unlock(file); + break; + } + + /* todo: already flushed? */ + hf = au_h_fptr(file, au_fbstart(file)); + hf->f_flags = au_file_roflags(hf->f_flags); + hf->f_mode &= ~FMODE_WRITE; + put_write_access(hf->f_dentry->d_inode); + FiMustNoWaiters(file); + fi_read_unlock(file); + } + + AuTraceErr(err); + return err; +} + +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, + int *do_update) +{ + int err; + struct dentry *root; + aufs_bindex_t bindex; + struct au_branch *br; + struct inode *hidden_dir; + + LKTRTrace("%s, %.*s, 0x%x\n", + mod->path, AuDLNPair(mod->h_root), mod->perm); + SiMustWriteLock(sb); + root = sb->s_root; + DiMustWriteLock(root); + IiMustWriteLock(root->d_inode); + + bindex = au_find_dbindex(root, mod->h_root); + if (bindex < 0) { + if (remount) + return 0; /* success */ + err = -ENOENT; + AuErr("%s no such branch\n", mod->path); + goto out; + } + LKTRTrace("bindex b%d\n", bindex); + + hidden_dir = mod->h_root->d_inode; + err = test_br(sb, hidden_dir, mod->perm, mod->path); + if (unlikely(err)) + goto out; + + br = au_sbr(sb, bindex); + if (br->br_perm == mod->perm) + return 0; /* success */ + + if (au_br_writable(br->br_perm)) { +#if 1 + /* remove whiteout base */ + err = au_br_init_wh(sb, bindex, br, mod->perm, mod->h_root, + br->br_mnt); + if (unlikely(err)) + goto out; +#else /* reserved for future use */ + struct au_wbr *wbr; + wbr = br->wbr; + if (wbr) + for (i = 0; i < AuBrWh_Last; i++) { + dput(wbr->wbr_wh[i]); + wbr->wbr_wh[i] = NULL; + } +#endif + + if (!au_br_writable(mod->perm)) { + /* rw --> ro, file might be mmapped */ + +#if 1 /* todo: test more? */ + DiMustNoWaiters(root); + IiMustNoWaiters(root->d_inode); + di_write_unlock(root); + err = au_br_mod_files_ro(sb, bindex); + /* aufs_write_lock() calls ..._child() */ + di_write_lock_child(root); +#endif + } + } else if (au_br_writable(mod->perm)) { + /* ro --> rw */ + err = -ENOMEM; + br->br_wbr = kmalloc(sizeof(*br->br_wbr), GFP_NOFS); + if (br->br_wbr) { + struct path path = { + .mnt = br->br_mnt, + .dentry = mod->h_root + }; + + err = au_wbr_init(br, sb, mod->perm, &path); + if (unlikely(err)) { + kfree(br->br_wbr); + br->br_wbr = NULL; + } + } + } + + if (!err) { + *do_update |= need_sigen_inc(br->br_perm, mod->perm); + br->br_perm = mod->perm; + } + + out: + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/hin_or_fuse.c +++ linux-2.6.28/ubuntu/aufs/hin_or_fuse.c @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode attributes on FUSE branch or HINOTIFY + * + * $Id: hin_or_fuse.c,v 1.6 2008/09/15 03:14:30 sfjro Exp $ + */ + +#include "aufs.h" + +static struct dentry * +au_h_dget_any(struct dentry *dentry, aufs_bindex_t *bindex) +{ + struct dentry *h_dentry; + struct inode *inode, *h_inode; + struct super_block *sb; + aufs_bindex_t ib, db; + + /* must be positive dentry */ + inode = dentry->d_inode; + LKTRTrace("%.*s, i%lu\n", AuDLNPair(dentry), inode->i_ino); + + sb = dentry->d_sb; + db = au_dbstart(dentry); + ib = au_ibstart(inode); + if (db == ib) { + *bindex = db; + h_dentry = dget(au_h_dptr(dentry, db)); + if (h_dentry) + goto out; /* success */ + } + + *bindex = ib; + h_inode = au_h_iptr(inode, ib); + h_dentry = d_find_alias(h_inode); + if (h_dentry) + goto out; /* success */ + +#if 0 + if (au_opt_test(au_mntflags(sb), PLINK) + && au_plink_test(sb, inode)) { + h_dentry = au_plink_lkup(sb, ib, inode); + if (IS_ERR(h_dentry)) + goto out; + AuDebugOn(!h_dentry->d_inode); + goto out; /* success */ + } +#endif + + h_dentry = dget(au_hi_wh(inode, ib)); + + out: + AuTraceErrPtr(h_dentry); + return h_dentry; +} + +int aufs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *st) +{ + int err; + unsigned int mnt_flags; + aufs_bindex_t bindex; + struct inode *inode; + struct dentry *h_dentry; + struct super_block *sb, *h_sb; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = 0; + inode = dentry->d_inode; + sb = dentry->d_sb; + aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR); + + /* todo: nfs branch too? */ + /* todo: test bit inotify option too? */ + mnt_flags = au_mntflags(sb); + bindex = au_ibstart(inode); + h_sb = au_sbr_sb(sb, bindex); + if (!au_test_fuse(h_sb) + //&& !au_test_nfs(h_sb) /* todo: fix me */ + && (au_iigen(inode) == au_sigen(sb) + || (au_opt_test(mnt_flags, PLINK) && au_plink_test(sb, inode)))) + goto fill; + + h_dentry = au_h_dget_any(dentry, &bindex); + err = PTR_ERR(h_dentry); + if (IS_ERR(h_dentry)) + goto out; + + err = -EIO; + if (h_dentry && h_dentry->d_inode) + err = vfsub_getattr(au_sbr_mnt(sb, bindex), h_dentry, st, + au_test_dlgt(mnt_flags)); + dput(h_dentry); + if (!err) { + au_cpup_attr_all(inode); + fill: + generic_fillattr(inode, st); + } + + out: + aufs_read_unlock(dentry, AuLock_IR); + AuTraceErr(err); + return err; +} --- linux-2.6.28.orig/ubuntu/aufs/hinotify.c +++ linux-2.6.28/ubuntu/aufs/hinotify.c @@ -0,0 +1,1133 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * internal/hidden inotify handler + * + * $Id: hinotify.c,v 1.16 2008/09/08 02:39:54 sfjro Exp $ + */ + +#include "aufs.h" + +/* +#ifdef DbgInotify +#define AuDbgHin(args...) AuDbg(##args) +#else +#define AuDbgHin(args...) do {} while () +#endif +*/ + +static struct inotify_handle *in_handle; + +AuCacheFuncs(hinotify, AuCache_HINOTIFY); + +int au_hin_alloc(struct au_hinode *hinode, struct inode *inode, + struct inode *h_inode) +{ + int err; + struct au_hinotify *hin; + s32 wd; + + LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino); + + err = -ENOMEM; + hin = au_cache_alloc_hinotify(); + if (hin) { + AuDebugOn(hinode->hi_notify); + hinode->hi_notify = hin; + spin_lock_init(&hin->hin_ignore_lock); + INIT_LIST_HEAD(&hin->hin_ignore_list); + hin->hin_aufs_inode = inode; + + inotify_init_watch(&hin->hin_watch); + wd = inotify_add_watch(in_handle, &hin->hin_watch, h_inode, + AuInMask); + if (wd >= 0) + return 0; /* success */ + + err = wd; + put_inotify_watch(&hin->hin_watch); + au_cache_free_hinotify(hin); + hinode->hi_notify = NULL; + } + + AuTraceErr(err); + return err; +} + +void au_hin_free(struct au_hinode *hinode) +{ + int err; + struct au_hinotify *hin; + + AuTraceEnter(); + + hin = hinode->hi_notify; + if (unlikely(hin)) { + err = 0; + if (atomic_read(&hin->hin_watch.count)) + err = inotify_rm_watch(in_handle, &hin->hin_watch); + if (unlikely(err)) + /* it means the watch is already removed */ + LKTRTrace("failed inotify_rm_watch() %d\n", err); + au_cache_free_hinotify(hin); + hinode->hi_notify = NULL; + } +} + +/* ---------------------------------------------------------------------- */ + +void au_hin_ctl(struct au_hinode *hinode, const __u32 mask) +{ + struct inode *h_inode; + struct inotify_watch *watch; + + h_inode = hinode->hi_inode; + LKTRTrace("hi%lu, sb %p, 0x%x\n", h_inode->i_ino, h_inode->i_sb, mask); + IMustLock(h_inode); + if (!hinode->hi_notify) + return; + + watch = &hinode->hi_notify->hin_watch; +#if 0 /* reserved for future use */ + { + u32 wd; + wd = inotify_find_update_watch(in_handle, h_inode, mask); + AuTraceErr(wd); + /* ignore an err; */ + } +#else + /* struct inotify_handle is hidden */ + mutex_lock(&h_inode->inotify_mutex); + /* mutex_lock(&watch->ih->mutex); */ + watch->mask = mask; + /* mutex_unlock(&watch->ih->mutex); */ + mutex_unlock(&h_inode->inotify_mutex); +#endif + LKTRTrace("watch %p, mask %u\n", watch, watch->mask); +} + +void au_reset_hinotify(struct inode *inode, unsigned int flags) +{ + aufs_bindex_t bindex, bend; + struct inode *hi; + struct dentry *iwhdentry; + + LKTRTrace("i%lu, 0x%x\n", inode->i_ino, flags); + + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { + hi = au_h_iptr(inode, bindex); + if (hi) { + /* mutex_lock_nested(&hi->i_mutex, AuLsc_I_CHILD); */ + iwhdentry = au_hi_wh(inode, bindex); + if (unlikely(iwhdentry)) + dget(iwhdentry); + au_igrab(hi); + au_set_h_iptr(inode, bindex, NULL, 0); + au_set_h_iptr(inode, bindex, au_igrab(hi), + flags & ~AuHi_XINO); + iput(hi); + dput(iwhdentry); + /* mutex_unlock(&hi->i_mutex); */ + } + } +} + +/* ---------------------------------------------------------------------- */ + +void au_unpin_gp(struct au_pin *args) +{ + struct au_pin1 *gp; + + gp = au_pin_gp(args); + AuDebugOn(!gp); + if (gp->dentry) + LKTRTrace("%.*s\n", AuDLNPair(gp->dentry)); + else + AuTraceEnter(); + + au_do_unpin(gp, NULL); +} + +int au_hin_verify_gen(struct dentry *dentry) +{ + struct super_block *sb = dentry->d_sb; + au_gen_t sigen; + struct inode *inode; + + if (!au_opt_test(au_mntflags(sb), UDBA_INOTIFY)) + return 0; + + sigen = au_sigen(dentry->d_sb); + inode = dentry->d_inode; + return (au_digen(dentry) != sigen + || (inode && au_iigen(inode) != sigen)); +} + +/* ---------------------------------------------------------------------- */ + +/* cf. fsnotify_change() */ +__u32 vfsub_events_notify_change(struct iattr *ia) +{ + __u32 events; + const unsigned int amtime = (ATTR_ATIME | ATTR_MTIME); + + events = 0; + if ((ia->ia_valid & (ATTR_UID | ATTR_GID | ATTR_MODE)) + || (ia->ia_valid & amtime) == amtime) + events |= IN_ATTRIB; + if ((ia->ia_valid & ATTR_SIZE) + || (ia->ia_valid & amtime) == ATTR_MTIME) + events |= IN_MODIFY; + return events; +} + +void vfsub_ign_hinode(struct vfsub_args *vargs, __u32 events, + struct au_hinode *hinode) +{ + struct au_hinotify *hin; + struct super_block *sb; + struct au_hin_ignore *ign; + + if (!hinode) + return; + + hin = hinode->hi_notify; + if (!hin || !hin->hin_watch.mask) + return; + + sb = hin->hin_aufs_inode->i_sb; + AuDebugOn(!au_opt_test(au_mntflags(sb), UDBA_INOTIFY)); + + ign = vargs->ignore + vargs->nignore++; + ign->ign_events = events; + ign->ign_handled = 0; + ign->ign_hinode = hinode; + + { + struct inode *h_inode; + h_inode = hinode->hi_inode; + if (!mutex_is_locked(&h_inode->i_mutex)) + au_dbg_blocked(); + IMustLock(h_inode); + } +} + +static void au_hin_ignore(struct au_hin_ignore *ign) +{ + struct au_hinode *hinode; + __u32 events; + struct au_hinotify *hin; + struct inode *h_inode; + + hinode = ign->ign_hinode; + events = ign->ign_events; + LKTRTrace("0x%x\n", events); + AuDebugOn(!hinode || !events); + + hin = hinode->hi_notify; + h_inode = hinode->hi_inode; + if (h_inode && hin) { + LKTRTrace("hi%lu\n", h_inode->i_ino); +#ifdef DbgInotify + AuDbg("hi%lu, 0x%x\n", h_inode->i_ino, events); +#endif + + spin_lock(&hin->hin_ignore_lock); + list_add(&ign->ign_list, &hin->hin_ignore_list); + spin_unlock(&hin->hin_ignore_lock); + /* AuDbg("list_add %p, 0x%x\n", ign, events); */ + } +#if 1 /* todo: test dlgt */ + else + /* + * it may happen by this scenario. + * - a file and its parent dir exist on two branches + * - a file on the upper branch is opened + * - the parent dir and the file are removed by udba + * - the parent is re-accessed, and new dentry/inode in + * aufs is generated for it, based upon the one on the lower + * branch + * - the opened file is re-accessed, re-validated, and it may be + * re-connected to the new parent dentry + * it means the file in aufs cannot get the actual removed + * parent dir on the branch. + */ + INIT_LIST_HEAD(&ign->ign_list); +#endif +} + +static void au_hin_unignore(struct au_hin_ignore *ign) +{ + struct au_hinode *hinode; + __u32 events; + struct au_hinotify *hin; + struct inode *h_inode; + + hinode = ign->ign_hinode; + events = ign->ign_events; + LKTRTrace("0x%x\n", events); + /* AuDbg("0x%x\n", events); */ + AuDebugOn(!hinode || !events); + + hin = hinode->hi_notify; + h_inode = hinode->hi_inode; + if (unlikely(!h_inode || !hin)) + return; + LKTRTrace("hi%lu\n", h_inode->i_ino); +#ifdef DbgInotify + AuDbg("hi%lu, 0x%x\n", h_inode->i_ino, events); +#endif + + spin_lock(&hin->hin_ignore_lock); + au_hin_list_del(&ign->ign_list); + spin_unlock(&hin->hin_ignore_lock); + /* AuDbg("list_del %p, 0x%x\n", ign, events); */ +} + +static int au_hin_test_ignore(u32 mask, struct au_hinotify *hin) +{ + int do_ignore; + struct au_hin_ignore *ign, *tmp; + u32 events; + + do_ignore = 0; + spin_lock(&hin->hin_ignore_lock); + list_for_each_entry_safe(ign, tmp, &hin->hin_ignore_list, ign_list) { + /* AuDbg("ign %p\n", ign); */ + if (ign->ign_pid == current->pid) { + events = (mask & ign->ign_events); + if (events) { + do_ignore = 1; + ign->ign_handled |= events; + if (ign->ign_events == ign->ign_handled) { + list_del_init(&ign->ign_list); + /* + AuDbg("list_del %p, 0x%x\n", + ign, events); + */ + } + break; + } + } + } + spin_unlock(&hin->hin_ignore_lock); + + return do_ignore; +} + +void vfsub_ignore(struct vfsub_args *vargs) +{ + int n; + struct au_hin_ignore *ign; + struct super_block *sb; + struct au_hinode *hinode; + struct inode *h_inode; + + n = vargs->nignore; + if (!n) + return; + + ign = vargs->ignore; + hinode = ign->ign_hinode; + sb = hinode->hi_notify->hin_aufs_inode->i_sb; + h_inode = hinode->hi_inode; + if (unlikely(au_opt_test(au_mntflags(sb), UDBA_INOTIFY))) { + if (!mutex_is_locked(&h_inode->i_mutex)) + au_dbg_blocked(); + IMustLock(h_inode); + } + while (n-- > 0) { + ign->ign_pid = current->pid; + au_hin_ignore(ign++); + } +} + +void vfsub_unignore(struct vfsub_args *vargs) +{ + int n; + struct au_hin_ignore *ign; + + n = vargs->nignore; + if (!n) + return; + + ign = vargs->ignore; + while (n-- > 0) + au_hin_unignore(ign++); +} + +#ifdef CONFIG_AUFS_DEBUG +void au_dbg_hin_list(struct vfsub_args *vargs) +{ + int n; + struct au_hin_ignore *ign; + + n = vargs->nignore; + if (!n) + return; + + ign = vargs->ignore; + while (n-- > 0) { + /* AuDebugOn(!list_empty(&ign++->ign_list)); */ + if (list_empty(&ign++->ign_list)) + continue; + ign--; + AuDbg("%d: pid %d, 0x%x\n", + n + 1, ign->ign_pid, ign->ign_events); + ign++; + au_dbg_blocked(); + } +} +#endif + +/* ---------------------------------------------------------------------- */ + +static char *in_name(u32 mask) +{ +#ifdef CONFIG_AUFS_DEBUG +#define test_ret(flag) if (mask & flag) return #flag; + test_ret(IN_ACCESS); + test_ret(IN_MODIFY); + test_ret(IN_ATTRIB); + test_ret(IN_CLOSE_WRITE); + test_ret(IN_CLOSE_NOWRITE); + test_ret(IN_OPEN); + test_ret(IN_MOVED_FROM); + test_ret(IN_MOVED_TO); + test_ret(IN_CREATE); + test_ret(IN_DELETE); + test_ret(IN_DELETE_SELF); + test_ret(IN_MOVE_SELF); + test_ret(IN_UNMOUNT); + test_ret(IN_Q_OVERFLOW); + test_ret(IN_IGNORED); + return ""; +#undef test_ret +#else + return "??"; +#endif +} + +/* ---------------------------------------------------------------------- */ + +static struct dentry *lookup_wlock_by_name(char *name, unsigned int nlen, + struct inode *dir) +{ + struct dentry *dentry, *d, *parent; + struct qstr *dname; + + LKTRTrace("%.*s, dir%lu\n", nlen, name, dir->i_ino); + + parent = d_find_alias(dir); + if (!parent) + return NULL; + + dentry = NULL; + spin_lock(&dcache_lock); + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) { + LKTRTrace("%.*s\n", AuDLNPair(d)); + dname = &d->d_name; + if (dname->len != nlen || memcmp(dname->name, name, nlen)) + continue; + if (!atomic_read(&d->d_count) || !d->d_fsdata) { + spin_lock(&d->d_lock); + __d_drop(d); + spin_unlock(&d->d_lock); + continue; + } + + dentry = dget(d); + break; + } + spin_unlock(&dcache_lock); + dput(parent); + + if (dentry) { +#if 0 + lktr_set_pid(current->pid, LktrArrayPid); + AuDbgDentry(dentry); + lktr_clear_pid(current->pid, LktrArrayPid); +#endif + di_write_lock_child(dentry); + } + return dentry; +} + +static struct inode *lookup_wlock_by_ino(struct super_block *sb, + aufs_bindex_t bindex, ino_t h_ino) +{ + struct inode *inode; + struct au_xino_entry xinoe; + int err; + + LKTRTrace("b%d, hi%lu\n", bindex, (unsigned long)h_ino); + AuDebugOn(!au_opt_test_xino(au_mntflags(sb))); + + inode = NULL; + err = au_xino_read(sb, bindex, h_ino, &xinoe); + if (!err && xinoe.ino) + inode = ilookup(sb, xinoe.ino); + if (!inode) + goto out; + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { + AuWarn("wrong root branch\n"); + iput(inode); + inode = NULL; + goto out; + } + + ii_write_lock_child(inode); + + out: + return inode; +} + +static int hin_xino(struct inode *inode, struct inode *h_inode) +{ + int err; + aufs_bindex_t bindex, bend, bfound, bstart; + struct inode *h_i; + + LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino); + + err = 0; + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { + AuWarn("branch root dir was changed\n"); + goto out; + } + + bfound = -1; + bend = au_ibend(inode); + bstart = au_ibstart(inode); +#if 0 /* reserved for future use */ + if (bindex == bend) { + /* keep this ino in rename case */ + goto out; + } +#endif + for (bindex = bstart; bindex <= bend; bindex++) { + if (au_h_iptr(inode, bindex) == h_inode) { + bfound = bindex; + break; + } + } + if (bfound < 0) + goto out; + + for (bindex = bstart; bindex <= bend; bindex++) { + h_i = au_h_iptr(inode, bindex); + if (h_i) + err = au_xino_write0(inode->i_sb, bindex, h_i->i_ino, + 0); + /* ignore this error */ + /* bad action? */ + } + + /* children inode number will be broken */ + + out: + AuTraceErr(err); + return err; +} + +static int hin_gen_tree(struct dentry *dentry) +{ + int err, i, j, ndentry; + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry **dentries; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) + goto out; + err = au_dcsub_pages(&dpages, dentry, NULL, NULL); + if (unlikely(err)) + goto out_dpages; + + for (i = 0; i < dpages.ndpage; i++) { + dpage = dpages.dpages + i; + dentries = dpage->dentries; + ndentry = dpage->ndentry; + for (j = 0; j < ndentry; j++) { + struct dentry *d; + d = dentries[j]; + LKTRTrace("%.*s\n", AuDLNPair(d)); + if (IS_ROOT(d)) + continue; + + d_drop(d); + au_digen_dec(d); + if (d->d_inode) + /* todo: reset children xino? + cached children only? */ + au_iigen_dec(d->d_inode); + } + } + + out_dpages: + au_dpages_free(&dpages); + + /* discard children */ + dentry_unhash(dentry); + dput(dentry); + out: + AuTraceErr(err); + return err; +} + +/* + * return 0 if processed. + */ +static int hin_gen_by_inode(char *name, unsigned int nlen, struct inode *inode, + const unsigned int isdir) +{ + int err; + struct dentry *d; + struct qstr *dname; + + LKTRTrace("%.*s, i%lu\n", nlen, name, inode->i_ino); + + err = 1; + if (unlikely(inode->i_ino == AUFS_ROOT_INO)) { + AuWarn("branch root dir was changed\n"); + err = 0; + goto out; + } + + if (!isdir) { + AuDebugOn(!name); + au_iigen_dec(inode); + spin_lock(&dcache_lock); + list_for_each_entry(d, &inode->i_dentry, d_alias) { + dname = &d->d_name; + if (dname->len != nlen + && memcmp(dname->name, name, nlen)) + continue; + err = 0; + spin_lock(&d->d_lock); + __d_drop(d); + au_digen_dec(d); + spin_unlock(&d->d_lock); + break; + } + spin_unlock(&dcache_lock); + } else { + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIRS); + d = d_find_alias(inode); + if (!d) { + au_iigen_dec(inode); + goto out; + } + + dname = &d->d_name; + if (dname->len == nlen && !memcmp(dname->name, name, nlen)) + err = hin_gen_tree(d); + dput(d); + } + + out: + AuTraceErr(err); + return err; +} + +static int hin_gen_by_name(struct dentry *dentry, const unsigned int isdir) +{ + int err; + struct inode *inode; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + inode = dentry->d_inode; + if (IS_ROOT(dentry) + /* || (inode && inode->i_ino == AUFS_ROOT_INO) */ + ) { + AuWarn("branch root dir was changed\n"); + return 0; + } + + err = 0; + if (!isdir) { + d_drop(dentry); + au_digen_dec(dentry); + if (inode) + au_iigen_dec(inode); + } else { + au_fset_si(au_sbi(dentry->d_sb), FAILED_REFRESH_DIRS); + if (inode) + err = hin_gen_tree(dentry); + } + + AuTraceErr(err); + return err; +} + +static void hin_attr(struct inode *inode, struct inode *h_inode) +{ + struct dentry *h_dentry; + + LKTRTrace("i%lu, hi%lu\n", inode->i_ino, h_inode->i_ino); + + if (au_h_iptr(inode, au_ibstart(inode)) != h_inode) + return; + + h_dentry = d_find_alias(h_inode); + if (h_dentry) { + au_update_fuse_h_inode(NULL, h_dentry); + /* ignore an error*/ + dput(h_dentry); + } + + au_cpup_attr_all(inode); +} + +/* ---------------------------------------------------------------------- */ + +/* hinotify job flags */ +#define AuHinJob_XINO0 1 +#define AuHinJob_GEN (1 << 1) +#define AuHinJob_DIRENT (1 << 2) +#define AuHinJob_ATTR (1 << 3) +#define AuHinJob_ISDIR (1 << 4) +#define AuHinJob_TRYXINO0 (1 << 5) +#define AuHinJob_MNTPNT (1 << 6) +#define au_ftest_hinjob(flags, name) ((flags) & AuHinJob_##name) +#define au_fset_hinjob(flags, name) { (flags) |= AuHinJob_##name; } +#define au_fclr_hinjob(flags, name) { (flags) &= ~AuHinJob_##name; } + +struct hin_job_args { + unsigned int flags; + struct inode *inode, *h_inode, *dir, *h_dir; + struct dentry *dentry; + char *h_name; + int h_nlen; +}; + +static int hin_job(struct hin_job_args *a) +{ + const unsigned int isdir = au_ftest_hinjob(a->flags, ISDIR); + + /* reset xino */ + if (au_ftest_hinjob(a->flags, XINO0) && a->inode) + hin_xino(a->inode, a->h_inode); + /* ignore this error */ + + if (au_ftest_hinjob(a->flags, TRYXINO0) + && a->inode + && a->h_inode) { + mutex_lock_nested(&a->h_inode->i_mutex, AuLsc_I_CHILD); + if (!a->h_inode->i_nlink) + hin_xino(a->inode, a->h_inode); + /* ignore this error */ + mutex_unlock(&a->h_inode->i_mutex); + } + + /* make the generation obsolete */ + if (au_ftest_hinjob(a->flags, GEN)) { + int err = -1; + if (a->inode) + err = hin_gen_by_inode(a->h_name, a->h_nlen, a->inode, + isdir); + if (err && a->dentry) + hin_gen_by_name(a->dentry, isdir); + /* ignore this error */ + } + + /* make dir entries obsolete */ + if (au_ftest_hinjob(a->flags, DIRENT) && a->inode) { + struct au_vdir *vdir; + IiMustWriteLock(a->inode); + vdir = au_ivdir(a->inode); + if (vdir) + vdir->vd_jiffy = 0; + /* IMustLock(a->inode); */ + /* a->inode->i_version++; */ + } + + /* update the attr */ + if (au_ftest_hinjob(a->flags, ATTR) && a->inode && a->h_inode) + hin_attr(a->inode, a->h_inode); + + /* can do nothing but warn */ + if (au_ftest_hinjob(a->flags, MNTPNT) + && a->dentry + && d_mountpoint(a->dentry)) + AuWarn("mount-point %.*s is removed or renamed\n", + AuDLNPair(a->dentry)); + + return 0; +} + +/* ---------------------------------------------------------------------- */ + +enum { CHILD, PARENT }; +struct postproc_args { + struct inode *h_dir, *dir, *h_child_inode; + u32 mask; + unsigned int flags[2]; + unsigned int h_child_nlen; + char h_child_name[]; +}; + +static void postproc(void *_args) +{ + struct postproc_args *a = _args; + struct super_block *sb; + aufs_bindex_t bindex, bend, bfound; + unsigned char xino, try_iput; + int err; + struct inode *inode; + ino_t h_ino; + struct hin_job_args args; + struct dentry *dentry; + struct au_sbinfo *sbinfo; + + AuDebugOn(!_args); + AuDebugOn(!a->h_dir); + AuDebugOn(!a->dir); + AuDebugOn(!a->mask); + LKTRTrace("mask 0x%x %s, i%lu, hi%lu, hci%lu\n", + a->mask, in_name(a->mask), a->dir->i_ino, a->h_dir->i_ino, + a->h_child_inode ? a->h_child_inode->i_ino : 0); + + inode = NULL; + dentry = NULL; + /* + * do not lock a->dir->i_mutex here + * because of d_revalidate() may cause a deadlock. + */ + sb = a->dir->i_sb; + AuDebugOn(!sb); + sbinfo = au_sbi(sb); + AuDebugOn(!sbinfo); + /* big aufs lock */ + si_noflush_write_lock(sb); + + ii_read_lock_parent(a->dir); + bfound = -1; + bend = au_ibend(a->dir); + for (bindex = au_ibstart(a->dir); bindex <= bend; bindex++) + if (au_h_iptr(a->dir, bindex) == a->h_dir) { + bfound = bindex; + break; + } + ii_read_unlock(a->dir); + if (unlikely(bfound < 0)) + goto out; + + xino = !!au_opt_test_xino(au_mntflags(sb)); + h_ino = 0; + if (a->h_child_inode) + h_ino = a->h_child_inode->i_ino; + + if (a->h_child_nlen + && (au_ftest_hinjob(a->flags[CHILD], GEN) + || au_ftest_hinjob(a->flags[CHILD], MNTPNT))) + dentry = lookup_wlock_by_name(a->h_child_name, a->h_child_nlen, + a->dir); + try_iput = 0; + if (dentry) + inode = dentry->d_inode; + if (xino && !inode && h_ino + && (au_ftest_hinjob(a->flags[CHILD], XINO0) + || au_ftest_hinjob(a->flags[CHILD], TRYXINO0) + || au_ftest_hinjob(a->flags[CHILD], GEN) + || au_ftest_hinjob(a->flags[CHILD], ATTR))) { + inode = lookup_wlock_by_ino(sb, bfound, h_ino); + try_iput = 1; + } + + args.flags = a->flags[CHILD]; + args.dentry = dentry; + args.inode = inode; + args.h_inode = a->h_child_inode; + args.dir = a->dir; + args.h_dir = a->h_dir; + args.h_name = a->h_child_name; + args.h_nlen = a->h_child_nlen; + err = hin_job(&args); + if (dentry) { + if (dentry->d_fsdata) + di_write_unlock(dentry); + dput(dentry); + } + if (inode && try_iput) { + ii_write_unlock(inode); + iput(inode); + } + + ii_write_lock_parent(a->dir); + args.flags = a->flags[PARENT]; + args.dentry = NULL; + args.inode = a->dir; + args.h_inode = a->h_dir; + args.dir = NULL; + args.h_dir = NULL; + args.h_name = NULL; + args.h_nlen = 0; + err = hin_job(&args); + ii_write_unlock(a->dir); + + out: + au_nwt_done(&sbinfo->si_nowait); + si_write_unlock(sb); + + iput(a->h_child_inode); + iput(a->h_dir); + iput(a->dir); + kfree(a); +} + +static void aufs_inotify(struct inotify_watch *watch, u32 wd, u32 mask, + u32 cookie, const char *h_child_name, + struct inode *h_child_inode) +{ + struct au_hinotify *hinotify; + struct postproc_args *args; + int len, wkq_err; + unsigned char isdir, isroot, wh; + char *p; + struct inode *dir; + unsigned int flags[2]; + + LKTRTrace("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n", + watch->inode->i_ino, wd, mask, in_name(mask), cookie, + h_child_name ? h_child_name : "", + h_child_inode ? h_child_inode->i_ino : 0); + + /* if IN_UNMOUNT happens, there must be another bug */ + if (mask & (IN_IGNORED | IN_UNMOUNT)) { + put_inotify_watch(watch); + return; + } + +#ifdef DbgInotify + if (!h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) + AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s," + " hi%lu\n", + watch->inode->i_ino, wd, mask, in_name(mask), cookie, + h_child_name ? h_child_name : "", + h_child_inode ? h_child_inode->i_ino : 0); +#endif + + hinotify = container_of(watch, struct au_hinotify, hin_watch); + AuDebugOn(!hinotify || !hinotify->hin_aufs_inode); + if (au_hin_test_ignore(mask, hinotify)) { +#ifdef DbgInotify + AuDbg("ignored\n"); +#endif + return; + } +#if 0 /* tmp debug */ + if (h_child_name && !strcmp(h_child_name, AUFS_XINO_FNAME)) + { + AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s, hi%lu\n", + watch->inode->i_ino, wd, mask, in_name(mask), cookie, + h_child_name ? h_child_name : "", + h_child_inode ? h_child_inode->i_ino : 0); + //au_dbg_blocked(); + } +#endif + + dir = igrab(hinotify->hin_aufs_inode); + if (!dir) + return; + isroot = (dir->i_ino == AUFS_ROOT_INO); + len = 0; + wh = 0; + if (h_child_name) { + len = strlen(h_child_name); + if (!memcmp(h_child_name, AUFS_WH_PFX, AUFS_WH_PFX_LEN)) { + h_child_name += AUFS_WH_PFX_LEN; + len -= AUFS_WH_PFX_LEN; + wh = 1; + } + } + + isdir = 0; + if (h_child_inode) + isdir = !!S_ISDIR(h_child_inode->i_mode); + flags[PARENT] = AuHinJob_ISDIR; + flags[CHILD] = 0; + if (isdir) + flags[CHILD] = AuHinJob_ISDIR; + switch (mask & IN_ALL_EVENTS) { + case IN_MODIFY: + /*FALLTHROUGH*/ + case IN_ATTRIB: + if (h_child_inode) { + if (!wh) + au_fset_hinjob(flags[CHILD], ATTR); + } else + au_fset_hinjob(flags[PARENT], ATTR); + break; + + /* IN_MOVED_FROM is the first event in rename(2) */ + case IN_MOVED_FROM: + case IN_MOVED_TO: + AuDebugOn(!h_child_name || !h_child_inode); + au_fset_hinjob(flags[CHILD], GEN); + au_fset_hinjob(flags[CHILD], ATTR); + if (1 || isdir) + au_fset_hinjob(flags[CHILD], XINO0); + au_fset_hinjob(flags[CHILD], MNTPNT); + + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + break; + + case IN_CREATE: + AuDebugOn(!h_child_name || !h_child_inode); + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + au_fset_hinjob(flags[CHILD], GEN); + /* hard link */ + if (!isdir && h_child_inode->i_nlink > 1) + au_fset_hinjob(flags[CHILD], ATTR); + break; + + case IN_DELETE: + /* + * aufs never be able to get this child inode. + * revalidation should be in d_revalidate() + * by checking i_nlink, i_generation or d_unhashed(). + */ + AuDebugOn(!h_child_name); + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + au_fset_hinjob(flags[CHILD], GEN); + au_fset_hinjob(flags[CHILD], TRYXINO0); + au_fset_hinjob(flags[CHILD], MNTPNT); + break; + + case IN_DELETE_SELF: +#if 0 + if (!isroot) + au_fset_hinjob(flags[PARENT], GEN); + /*FALLTHROUGH*/ +#endif + + case IN_MOVE_SELF: +#if 0 + /* + * when an inotify is set to an aufs inode, + * such inode can be isolated and this event can be fired + * solely. + */ + AuDebugOn(h_child_name || h_child_inode); + if (unlikely(isroot)) { + AuWarn("root branch was moved\n"); + iput(dir); + return; + } + au_fset_hinjob(flags[PARENT], XINO0); + au_fset_hinjob(flags[PARENT], GEN); + au_fset_hinjob(flags[PARENT], ATTR); + au_fset_hinjob(flags[PARENT], DIRENT); + /* au_fset_hinjob(flags[PARENT], MNTPNT); */ + break; +#endif + + case IN_ACCESS: + default: + AuDebugOn(1); + } + + if (wh) + h_child_inode = NULL; + + /* iput() and kfree() will be called in postproc() */ + /* + * inotify_mutex is already acquired and kmalloc/prune_icache may lock + * iprune_mutex. strange. + */ + lockdep_off(); + args = kmalloc(sizeof(*args) + len + 1, GFP_NOFS); + lockdep_on(); + if (unlikely(!args)) { + AuErr1("no memory\n"); + iput(dir); + return; + } + args->flags[PARENT] = flags[PARENT]; + args->flags[CHILD] = flags[CHILD]; + args->mask = mask; + args->dir = dir; + args->h_dir = igrab(watch->inode); + if (h_child_inode) + h_child_inode = igrab(h_child_inode); /* can be NULL */ + args->h_child_inode = h_child_inode; + args->h_child_nlen = len; + if (len) { + p = (void *)args; + p += sizeof(*args); + memcpy(p, h_child_name, len + 1); + } + + lockdep_off(); + wkq_err = au_wkq_nowait(postproc, args, dir->i_sb, /*dlgt*/0); + lockdep_on(); + if (unlikely(wkq_err)) + AuErr("wkq %d\n", wkq_err); +} + +static void aufs_inotify_destroy(struct inotify_watch *watch) +{ + return; +} + +static struct inotify_operations aufs_inotify_ops = { + .handle_event = aufs_inotify, + .destroy_watch = aufs_inotify_destroy +}; + +/* ---------------------------------------------------------------------- */ + +static void au_hin_destroy_cache(void) +{ + kmem_cache_destroy(au_cachep[AuCache_HINOTIFY]); + au_cachep[AuCache_HINOTIFY] = NULL; +} + +int __init au_inotify_init(void) +{ + int err; + + err = -ENOMEM; + au_cachep[AuCache_HINOTIFY] = AuCache(au_hinotify); + if (au_cachep[AuCache_HINOTIFY]) { + err = 0; + in_handle = inotify_init(&aufs_inotify_ops); + if (IS_ERR(in_handle)) { + err = PTR_ERR(in_handle); + au_hin_destroy_cache(); + } + } + AuTraceErr(err); + return err; +} + +void au_inotify_fin(void) +{ + inotify_destroy(in_handle); + if (au_cachep[AuCache_HINOTIFY]) + au_hin_destroy_cache(); +} --- linux-2.6.28.orig/ubuntu/aufs/wbr_policy.c +++ linux-2.6.28/ubuntu/aufs/wbr_policy.c @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * policies for selecting one among multiple writable branches + * + * $Id: wbr_policy.c,v 1.12 2008/09/01 02:55:35 sfjro Exp $ + */ + +#include +#include "aufs.h" + +static int au_cpdown_attr(struct au_hinode *hdir, struct dentry *h_dst, + struct dentry *h_src) +{ + int err, sbits; + struct iattr ia; + struct inode *h_idst, *h_isrc; + + LKTRTrace("%.*s\n", AuDLNPair(h_dst)); + h_idst = h_dst->d_inode; + /* todo? IMustLock(h_idst); */ + h_isrc = h_src->d_inode; + /* todo? IMustLock(h_isrc); */ + + ia.ia_valid = ATTR_FORCE | ATTR_MODE | ATTR_UID | ATTR_GID; + ia.ia_mode = h_isrc->i_mode; + ia.ia_uid = h_isrc->i_uid; + ia.ia_gid = h_isrc->i_gid; + sbits = !!(ia.ia_mode & (S_ISUID | S_ISGID)); + + err = vfsub_sio_notify_change(hdir, h_dst, &ia); + + /* is this nfs only? */ + if (!err && sbits && au_test_nfs(h_dst->d_sb)) { + ia.ia_valid = ATTR_FORCE | ATTR_MODE; + ia.ia_mode = h_isrc->i_mode; + err = vfsub_sio_notify_change(hdir, h_dst, &ia); + } + + /* todo: necessary? */ + if (!err) + h_idst->i_flags = h_isrc->i_flags; + + AuTraceErr(err); + return err; +} + +struct au_cpdown_dir_args { + struct dentry *parent; + unsigned int parent_opq; /* bit-flags */ +}; + +static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t bdst, + struct dentry *h_parent, void *arg) +{ + int err, rerr; + struct au_cpdown_dir_args *args = arg; + aufs_bindex_t bend, bopq, bstart; + unsigned char parent_opq, whed, dlgt, do_opq, made_dir, diropq; + struct dentry *h_dentry, *opq_dentry, *wh_dentry, *parent; + struct inode *h_dir, *h_inode, *inode, *dir; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bdst); + bstart = au_dbstart(dentry); + AuDebugOn(bstart <= bdst + && bdst <= au_dbend(dentry) + && au_h_dptr(dentry, bdst)); + AuDebugOn(!h_parent); + /* todo: safe? */ + parent = dget_parent(dentry); + dir = parent->d_inode; + dput(parent); + h_dir = h_parent->d_inode; + AuDebugOn(!h_dir); + AuDebugOn(h_dir != au_h_iptr(dir, bdst)); + IMustLock(h_dir); + + err = au_lkup_neg(dentry, bdst); + if (unlikely(err < 0)) + goto out; + h_dentry = au_h_dptr(dentry, bdst); + dlgt = !!au_test_dlgt(au_mntflags(dentry->d_sb)); + err = vfsub_sio_mkdir(au_hi(dir, bdst), h_dentry, S_IRWXU | S_IRUGO | S_IXUGO, + dlgt); + if (unlikely(err)) + goto out_put; + + made_dir = 1; + bend = au_dbend(dentry); + bopq = au_dbdiropq(dentry); + whed = (au_dbwh(dentry) == bdst); + if (!args->parent_opq) + args->parent_opq |= (bopq <= bdst); + parent_opq = (args->parent_opq && args->parent == dentry); + do_opq = 0; + diropq = 0; + h_inode = h_dentry->d_inode; + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + if (whed || (parent_opq && do_opq)) { + opq_dentry = au_diropq_create(dentry, bdst, dlgt); + err = PTR_ERR(opq_dentry); + if (IS_ERR(opq_dentry)) { + mutex_unlock(&h_inode->i_mutex); + goto out_dir; + } + dput(opq_dentry); + diropq = 1; + } + + err = au_cpdown_attr(au_hi(dir, bdst), h_dentry, au_h_dptr(dentry, bstart)); + mutex_unlock(&h_inode->i_mutex); + if (unlikely(err)) + goto out_opq; + + wh_dentry = NULL; + if (whed) { + wh_dentry = au_wh_lkup(h_parent, &dentry->d_name, /*ndx*/NULL); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_opq; + err = 0; + if (wh_dentry->d_inode) + err = au_wh_unlink_dentry(au_hi(dir, bdst), wh_dentry, + dentry, dlgt); + dput(wh_dentry); + if (unlikely(err)) + goto out_opq; + } + + inode = dentry->d_inode; + if (au_ibend(inode) < bdst) + au_set_ibend(inode, bdst); + au_set_h_iptr(inode, bdst, au_igrab(h_inode), au_hi_flags(inode, 1)); + goto out; /* success */ + + /* revert */ + out_opq: + if (diropq) { + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + rerr = au_diropq_remove(dentry, bdst, dlgt); + mutex_unlock(&h_inode->i_mutex); + if (unlikely(rerr)) { + AuIOErr("failed removing diropq for %.*s b%d (%d)\n", + AuDLNPair(dentry), bdst, rerr); + err = -EIO; + goto out; + } + } + out_dir: + if (made_dir) { + rerr = vfsub_sio_rmdir(au_hi(dir, bdst), h_dentry, dlgt); + if (unlikely(rerr)) { + AuIOErr("failed removing %.*s b%d (%d)\n", + AuDLNPair(dentry), bdst, rerr); + err = -EIO; + } + } + out_put: + au_set_h_dptr(dentry, bdst, NULL); + if (au_dbend(dentry) == bdst) + au_update_dbend(dentry); + out: + AuTraceErr(err); + return err; +} + +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) +{ + int err; + struct au_cpdown_dir_args args = { + .parent = dget_parent(dentry), + .parent_opq = 0 + }; + + LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bdst); + + err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args); + dput(args.parent); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* policies for create */ + +static int au_wbr_bu(struct super_block *sb, aufs_bindex_t bindex) +{ + for (; bindex >= 0; bindex--) + if (!au_br_rdonly(au_sbr(sb, bindex))) + return bindex; + return -EROFS; +} + +/* top down parent */ +static int au_wbr_create_tdp(struct dentry *dentry, int isdir) +{ + int err; + struct super_block *sb; + aufs_bindex_t bstart, bindex; + unsigned char dirperm1; + struct dentry *parent, *h_parent; + struct inode *h_dir; + + LKTRTrace("%.*s, dir %d\n", AuDLNPair(dentry), isdir); + + sb = dentry->d_sb; + dirperm1 = !!au_test_dirperm1(au_mntflags(sb)); + bstart = au_dbstart(dentry); + AuDebugOn(bstart < 0); + err = bstart; + /* todo: can 'err' be an illegal? */ + if (/* err >= 0 && */ !au_br_rdonly(au_sbr(sb, bstart))) + goto out; + + err = -EROFS; + parent = dget_parent(dentry); + for (bindex = au_dbstart(parent); bindex < bstart; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir) + continue; + + if (!au_br_rdonly(au_sbr(sb, bindex)) + && (!dirperm1 + || au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC, + /*dlgt*/0))) { + err = bindex; + break; + } + } + dput(parent); + + /* bottom up here */ + if (unlikely(err < 0)) + err = au_wbr_bu(sb, bstart - 1); + + out: + LKTRTrace("b%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* an exception for the policy other than tdp */ +static int au_wbr_create_exp(struct dentry *dentry) +{ + int err; + struct dentry *parent; + aufs_bindex_t bwh, bdiropq; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = -1; + bwh = au_dbwh(dentry); + parent = dget_parent(dentry); + bdiropq = au_dbdiropq(parent); + if (bwh >= 0) { + if (bdiropq >= 0) + err = min(bdiropq, bwh); + else + err = bwh; + LKTRTrace("%d\n", err); + } else if (bdiropq >= 0) { + err = bdiropq; + LKTRTrace("%d\n", err); + } + dput(parent); + + if (err >= 0 && au_br_rdonly(au_sbr(dentry->d_sb, err))) + err = -1; + + LKTRTrace("%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* round robin */ +static int au_wbr_create_init_rr(struct super_block *sb) +{ + int err; + + err = au_wbr_bu(sb, au_sbend(sb)); + atomic_set(&au_sbi(sb)->si_wbr_rr_next, -err); /* less important */ + + LKTRTrace("b%d\n", err); + return err; +} + +static int au_wbr_create_rr(struct dentry *dentry, int isdir) +{ + int err, nbr; + struct super_block *sb; + atomic_t *next; + unsigned int u; + aufs_bindex_t bindex, bend; + + LKTRTrace("%.*s, dir %d\n", AuDLNPair(dentry), isdir); + + sb = dentry->d_sb; + next = NULL; + err = au_wbr_create_exp(dentry); + if (err >= 0) + goto out; + + next = &au_sbi(sb)->si_wbr_rr_next; + bend = au_sbend(sb); + nbr = bend + 1; + for (bindex = 0; bindex <= bend; bindex++) { + if (!isdir) { + err = atomic_dec_return(next) + 1; + /* modulo for 0 is meaningless */ + if (unlikely(!err)) + err = atomic_dec_return(next) + 1; + } else + err = atomic_read(next); + LKTRTrace("%d\n", err); + u = err; + err = u % nbr; + LKTRTrace("%d\n", err); + if (!au_br_rdonly(au_sbr(sb, err))) + break; + err = -EROFS; + } + + out: + LKTRTrace("%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* most free space */ +static void *au_wbr_statfs_arg(struct au_branch *br, struct super_block *sb, + aufs_bindex_t bindex) +{ + struct super_block *h_sb; + + h_sb = br->br_mnt->mnt_sb; + + if (!au_test_nfs(h_sb)) + return h_sb->s_root; + + /* sigh,,, why nfs s_root has wrong inode? */ + return au_di(sb->s_root)->di_hdentry[0 + bindex].hd_dentry; +} + +static void au_mfs(struct dentry *dentry) +{ + struct super_block *sb; + aufs_bindex_t bindex, bend; + unsigned char dlgt; + int err; + struct kstatfs st; + unsigned long long b, bavail; + void *arg; + struct au_branch *br; + struct au_wbr_mfs *mfs; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + bavail = 0; + sb = dentry->d_sb; + mfs = &au_sbi(sb)->si_wbr_mfs; + mfs->mfs_bindex = -EROFS; + mfs->mfsrr_bytes = 0; + dlgt = !!au_test_dlgt(au_mntflags(sb)); + bend = au_sbend(sb); + for (bindex = 0; bindex <= bend; bindex++) { + br = au_sbr(sb, bindex); + if (au_br_rdonly(br)) + continue; + AuDebugOn(!br->br_wbr); + arg = au_wbr_statfs_arg(br, sb, bindex); + if (!arg) + continue; + + err = vfsub_statfs(arg, &st, dlgt); + LKTRTrace("b%d, %d, %llu\n", + bindex, err, (unsigned long long)st.f_bavail); + if (unlikely(err)) { + AuWarn1("failed statfs, b%d, %d\n", bindex, err); + continue; + } + + /* when the available size is equal, select lower one */ + b = st.f_bavail * st.f_bsize; + br->br_wbr->wbr_bytes = b; + if (b >= bavail) { + bavail = b; + mfs->mfs_bindex = bindex; + mfs->mfs_jiffy = jiffies; + } + } + + mfs->mfsrr_bytes = bavail; + LKTRTrace("b%d\n", mfs->mfs_bindex); +} + +static int au_wbr_create_mfs(struct dentry *dentry, int isdir) +{ + int err; + struct super_block *sb; + struct au_wbr_mfs *mfs; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + sb = dentry->d_sb; + err = au_wbr_create_exp(dentry); + if (err >= 0) + goto out; + + mfs = &au_sbi(sb)->si_wbr_mfs; + mutex_lock(&mfs->mfs_lock); + if (unlikely(time_after(jiffies, mfs->mfs_jiffy + mfs->mfs_expire) + || mfs->mfs_bindex < 0 + || au_br_rdonly(au_sbr(sb, mfs->mfs_bindex)))) + au_mfs(dentry); + mutex_unlock(&mfs->mfs_lock); + err = mfs->mfs_bindex; + + out: + LKTRTrace("b%d\n", err); + return err; +} + +static int au_wbr_create_init_mfs(struct super_block *sb) +{ + struct au_wbr_mfs *mfs; + + mfs = &au_sbi(sb)->si_wbr_mfs; + LKTRTrace("expire %lu\n", mfs->mfs_expire); + + mutex_init(&mfs->mfs_lock); + mfs->mfs_jiffy = 0; + mfs->mfs_bindex = -EROFS; + + return 0; +} + +static int au_wbr_create_fin_mfs(struct super_block *sb) +{ + AuTraceEnter(); + mutex_destroy(&au_sbi(sb)->si_wbr_mfs.mfs_lock); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +/* most free space and then round robin */ +static int au_wbr_create_mfsrr(struct dentry *dentry, int isdir) +{ + int err; + struct au_wbr_mfs *mfs; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), isdir); + + err = au_wbr_create_mfs(dentry, isdir); + if (err >= 0) { + mfs = &au_sbi(dentry->d_sb)->si_wbr_mfs; + LKTRTrace("%llu bytes, %llu wmark\n", + mfs->mfsrr_bytes, mfs->mfsrr_watermark); + if (unlikely(mfs->mfsrr_bytes < mfs->mfsrr_watermark)) + err = au_wbr_create_rr(dentry, isdir); + } + + LKTRTrace("b%d\n", err); + return err; +} + +static int au_wbr_create_init_mfsrr(struct super_block *sb) +{ + int err; + + au_wbr_create_init_mfs(sb); /* ignore */ + err = au_wbr_create_init_rr(sb); + + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* top down parent and most free space */ +static int au_wbr_create_pmfs(struct dentry *dentry, int isdir) +{ + int err, e2; + struct super_block *sb; + struct dentry *parent, *h_parent; + aufs_bindex_t bindex, bstart, bend; + unsigned char dirperm1; + struct au_branch *br; + unsigned long long b; + struct inode *h_dir; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), isdir); + + err = au_wbr_create_tdp(dentry, isdir); + if (unlikely(err < 0)) + goto out; + parent = dget_parent(dentry); + bstart = au_dbstart(parent); + bend = au_dbtaildir(parent); + if (bstart == bend) + goto out_parent; /* success */ + + e2 = au_wbr_create_mfs(dentry, isdir); + if (e2 < 0) + goto out_parent; /* success */ + + /* when the available size is equal, select upper one */ + sb = dentry->d_sb; + br = au_sbr(sb, err); + AuDebugOn(!br->br_wbr); + dirperm1 = !!au_test_dirperm1(au_mntflags(sb)); + b = br->br_wbr->wbr_bytes; + LKTRTrace("b%d, %llu\n", err, b); + + if (unlikely(dirperm1)) { + for (bindex = bstart; bindex <= bend; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir) + continue; + + br = au_sbr(sb, bindex); + if (!au_br_rdonly(br) + && au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC, + /*dlgt*/0) + && br->br_wbr->wbr_bytes > b) { + b = br->br_wbr->wbr_bytes; + err = bindex; + LKTRTrace("b%d, %llu\n", err, b); + } + } + if (err >= 0) + goto out_parent; + } + for (bindex = bstart; bindex <= bend; bindex++) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent || !h_parent->d_inode) + continue; + + br = au_sbr(sb, bindex); + if (!au_br_rdonly(br) && br->br_wbr->wbr_bytes > b) { + b = br->br_wbr->wbr_bytes; + err = bindex; + LKTRTrace("b%d, %llu\n", err, b); + } + } + + out_parent: + dput(parent); + out: + LKTRTrace("b%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +/* policies for copyup */ + +/* top down parent */ +static int au_wbr_copyup_tdp(struct dentry *dentry) +{ + return au_wbr_create_tdp(dentry, /*isdir, anything is ok*/0); +} + +/* bottom up parent */ +static int au_wbr_copyup_bup(struct dentry *dentry) +{ + int err; + struct dentry *parent, *h_parent; + aufs_bindex_t bindex, bstart; + unsigned char dirperm1; + struct super_block *sb; + struct inode *h_dir; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = -EROFS; + sb = dentry->d_sb; + dirperm1 = !!au_test_dirperm1(au_mntflags(sb)); + parent = dget_parent(dentry); + bstart = au_dbstart(parent); + for (bindex = au_dbstart(dentry); bindex >= bstart; bindex--) { + h_parent = au_h_dptr(parent, bindex); + if (!h_parent) + continue; + h_dir = h_parent->d_inode; + if (!h_dir) + continue; + + if (!au_br_rdonly(au_sbr(sb, bindex)) + && (!dirperm1 + || au_test_h_perm(h_dir, MAY_WRITE | MAY_EXEC, + /*dlgt*/0))) { + err = bindex; + break; + } + } + dput(parent); + + /* bottom up here */ + if (unlikely(err < 0)) + err = au_wbr_bu(sb, bstart - 1); + + LKTRTrace("b%d\n", err); + return err; +} + +/* bottom up */ +static int au_wbr_copyup_bu(struct dentry *dentry) +{ + int err; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + err = au_wbr_bu(dentry->d_sb, au_dbstart(dentry)); + + LKTRTrace("b%d\n", err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct au_wbr_copyup_operations au_wbr_copyup_ops[] = { + [AuWbrCopyup_TDP] = { + .copyup = au_wbr_copyup_tdp + }, + [AuWbrCopyup_BUP] = { + .copyup = au_wbr_copyup_bup + }, + [AuWbrCopyup_BU] = { + .copyup = au_wbr_copyup_bu + } +}; + +struct au_wbr_create_operations au_wbr_create_ops[] = { + [AuWbrCreate_TDP] = { + .create = au_wbr_create_tdp + }, + [AuWbrCreate_RR] = { + .create = au_wbr_create_rr, + .init = au_wbr_create_init_rr + }, + [AuWbrCreate_MFS] = { + .create = au_wbr_create_mfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_MFSV] = { + .create = au_wbr_create_mfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_MFSRR] = { + .create = au_wbr_create_mfsrr, + .init = au_wbr_create_init_mfsrr, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_MFSRRV] = { + .create = au_wbr_create_mfsrr, + .init = au_wbr_create_init_mfsrr, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_PMFS] = { + .create = au_wbr_create_pmfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + }, + [AuWbrCreate_PMFSV] = { + .create = au_wbr_create_pmfs, + .init = au_wbr_create_init_mfs, + .fin = au_wbr_create_fin_mfs + } +}; --- linux-2.6.28.orig/ubuntu/aufs/inode.c +++ linux-2.6.28/ubuntu/aufs/inode.c @@ -0,0 +1,420 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * inode functions + * + * $Id: inode.c,v 1.13 2008/09/22 03:52:19 sfjro Exp $ + */ + +#include "aufs.h" + +int au_refresh_hinode_self(struct inode *inode) +{ + int err, new_sz, update; + struct inode *first; + struct au_hinode *p, *q, tmp; + struct super_block *sb; + struct au_iinfo *iinfo; + aufs_bindex_t bindex, bend, new_bindex; + + LKTRTrace("i%lu\n", inode->i_ino); + IiMustWriteLock(inode); + + err = -ENOMEM; + update = 0; + sb = inode->i_sb; + bend = au_sbend(sb); + new_sz = sizeof(*iinfo->ii_hinode) * (bend + 1); + iinfo = au_ii(inode); + p = au_kzrealloc(iinfo->ii_hinode, sizeof(*p) * (iinfo->ii_bend + 1), + new_sz, GFP_NOFS); + if (unlikely(!p)) + goto out; + + iinfo->ii_hinode = p; + p = iinfo->ii_hinode + iinfo->ii_bstart; + first = p->hi_inode; + err = 0; + for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; + bindex++, p++) { + if (!p->hi_inode) + continue; + + new_bindex = au_br_index(sb, p->hi_id); + if (new_bindex == bindex) + continue; + if (new_bindex < 0) { + update++; + au_hiput(p); + p->hi_inode = NULL; + continue; + } + + if (new_bindex < iinfo->ii_bstart) + iinfo->ii_bstart = new_bindex; + if (iinfo->ii_bend < new_bindex) + iinfo->ii_bend = new_bindex; + /* swap two hidden inode, and loop again */ + q = iinfo->ii_hinode + new_bindex; + tmp = *q; + *q = *p; + *p = tmp; + if (tmp.hi_inode) { + bindex--; + p--; + } + } + au_update_brange(inode, /*do_put_zero*/0); + + if (unlikely(err)) + goto out; + + if (1 || first != au_h_iptr(inode, iinfo->ii_bstart)) + au_cpup_attr_all(inode); + if (update && S_ISDIR(inode->i_mode)) + inode->i_version++; + au_update_iigen(inode); + + out: + AuTraceErr(err); + return err; +} + +int au_refresh_hinode(struct inode *inode, struct dentry *dentry) +{ + int err, update; + struct inode *first; + struct au_hinode *p; + struct super_block *sb; + struct au_iinfo *iinfo; + aufs_bindex_t bindex, bend; + unsigned char isdir; + unsigned int flags; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + IiMustWriteLock(inode); + + err = au_refresh_hinode_self(inode); + if (unlikely(err)) + goto out; + + sb = dentry->d_sb; + bend = au_sbend(sb); + iinfo = au_ii(inode); + update = 0; + p = iinfo->ii_hinode + iinfo->ii_bstart; + first = p->hi_inode; + isdir = S_ISDIR(inode->i_mode); + flags = au_hi_flags(inode, isdir); + bend = au_dbend(dentry); + for (bindex = au_dbstart(dentry); bindex <= bend; bindex++) { + struct inode *hi; + struct dentry *hd; + + hd = au_h_dptr(dentry, bindex); + if (!hd || !hd->d_inode) + continue; + + if (iinfo->ii_bstart <= bindex && bindex <= iinfo->ii_bend) { + hi = au_h_iptr(inode, bindex); + if (hi) { + if (hi == hd->d_inode) + continue; + err = -ESTALE; + break; + } + } + if (bindex < iinfo->ii_bstart) + iinfo->ii_bstart = bindex; + if (iinfo->ii_bend < bindex) + iinfo->ii_bend = bindex; + au_set_h_iptr(inode, bindex, au_igrab(hd->d_inode), flags); + update++; + } + au_update_brange(inode, /*do_put_zero*/0); + + if (unlikely(err)) + goto out; + + if (1 || first != au_h_iptr(inode, iinfo->ii_bstart)) + au_cpup_attr_all(inode); + if (update && isdir) + inode->i_version++; + au_update_iigen(inode); + + out: + AuTraceErr(err); + return err; +} + +static int set_inode(struct inode *inode, struct dentry *dentry) +{ + int err; + struct dentry *h_dentry; + struct inode *h_inode; + umode_t mode; + aufs_bindex_t bindex, bstart, btail; + unsigned char isdir; + struct au_iinfo *iinfo; + unsigned int flags; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(dentry)); + AuDebugOn(!(inode->i_state & I_NEW)); + IiMustWriteLock(inode); + bstart = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bstart); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + AuDebugOn(!h_inode); + + err = 0; + isdir = 0; + mode = h_inode->i_mode; + switch (mode & S_IFMT) { + case S_IFREG: + btail = au_dbtail(dentry); + inode->i_op = &aufs_iop; + inode->i_fop = &aufs_file_fop; + inode->i_mapping->a_ops = &aufs_aop; + break; + case S_IFDIR: + isdir = 1; + btail = au_dbtaildir(dentry); + inode->i_op = &aufs_dir_iop; + inode->i_fop = &aufs_dir_fop; + break; + case S_IFLNK: + btail = au_dbtail(dentry); + inode->i_op = &aufs_symlink_iop; + /* inode->i_fop = &aufs_file_fop; */ + break; + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + case S_IFSOCK: + btail = au_dbtail(dentry); + init_special_inode(inode, mode, + au_h_rdev(h_inode, /*h_mnt*/NULL, h_dentry)); + break; + default: + AuIOErr("Unknown file type 0%o\n", mode); + err = -EIO; + goto out; + } + + /* do not set inotify for whiteouted dirs (SHWH mode) */ + flags = au_hi_flags(inode, isdir); + if (unlikely(au_opt_test(au_mntflags(dentry->d_sb), SHWH) + && au_ftest_hi(flags, NOTIFY) + && dentry->d_name.len > AUFS_WH_PFX_LEN + && !memcmp(dentry->d_name.name, AUFS_WH_PFX, + AUFS_WH_PFX_LEN))) + au_fclr_hi(flags, NOTIFY); + iinfo = au_ii(inode); + iinfo->ii_bstart = bstart; + iinfo->ii_bend = btail; + for (bindex = bstart; bindex <= btail; bindex++) { + h_dentry = au_h_dptr(dentry, bindex); + if (!h_dentry) + continue; + AuDebugOn(!h_dentry->d_inode); + au_set_h_iptr(inode, bindex, au_igrab(h_dentry->d_inode), + flags); + } + au_cpup_attr_all(inode); + + out: + AuTraceErr(err); + return err; +} + +/* successful returns with iinfo write_locked */ +/* todo: return with unlocked? */ +static int reval_inode(struct inode *inode, struct dentry *dentry, int *matched) +{ + int err; + struct inode *h_inode, *h_dinode; + aufs_bindex_t bindex, bend; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(dentry)); + + *matched = 0; + + /* + * before this function, if aufs got any iinfo lock, it must be only + * one, the parent dir. + * it can happen by UDBA and the obsoleted inode number. + */ + err = -EIO; + if (unlikely(inode->i_ino == parent_ino(dentry))) + goto out; + /* todo: test here */ + //AuDebugOn(IS_DEADDIR(inode)); + + err = 0; + h_dinode = au_h_dptr(dentry, au_dbstart(dentry))->d_inode; + /* mutex_lock_nested(&inode->i_mutex, AuLsc_I_CHILD); */ + ii_write_lock_new_child(inode); + bend = au_ibend(inode); + for (bindex = au_ibstart(inode); bindex <= bend; bindex++) { + h_inode = au_h_iptr(inode, bindex); + if (h_inode && h_inode == h_dinode) { + /* && (ibs != bstart + || !au_test_higen(inode, h_inode))); */ + *matched = 1; + err = 0; + if (unlikely(au_iigen(inode) != au_digen(dentry))) + err = au_refresh_hinode(inode, dentry); + break; + } + } + if (unlikely(err)) + ii_write_unlock(inode); + /* mutex_unlock(&inode->i_mutex); */ + + out: + AuTraceErr(err); + return err; +} + +/* successful returns with iinfo write_locked */ +/* todo: return with unlocked? */ +struct inode *au_new_inode(struct dentry *dentry) +{ + struct inode *inode, *h_inode; + struct dentry *h_dentry; + ino_t h_ino; + struct super_block *sb; + int err, match; + aufs_bindex_t bstart; + struct au_xino_entry xinoe; + + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + sb = dentry->d_sb; + bstart = au_dbstart(dentry); + h_dentry = au_h_dptr(dentry, bstart); + AuDebugOn(!h_dentry); + h_inode = h_dentry->d_inode; + AuDebugOn(!h_inode); + + h_ino = h_inode->i_ino; + err = au_xino_read(sb, bstart, h_ino, &xinoe); + inode = ERR_PTR(err); + if (unlikely(err)) + goto out; + new_ino: + if (!xinoe.ino) { + xinoe.ino = au_xino_new_ino(sb); + if (!xinoe.ino) { + inode = ERR_PTR(-EIO); + goto out; + } + } + + LKTRTrace("i%lu\n", (unsigned long)xinoe.ino); + inode = au_iget_locked(sb, xinoe.ino); + err = PTR_ERR(inode); + if (IS_ERR(inode)) + goto out; + /* todo: test here */ + //AuDebugOn(IS_DEADDIR(inode)); + + LKTRTrace("%lx, new %d\n", inode->i_state, !!(inode->i_state & I_NEW)); + if (inode->i_state & I_NEW) { + ii_write_lock_new_child(inode); + err = set_inode(inode, dentry); + unlock_new_inode(inode); + if (!err) + goto out; /* success */ + iget_failed(inode); + ii_write_unlock(inode); + goto out_iput; + } else { + AuDebugOn(inode->i_state & I_LOCK); + err = reval_inode(inode, dentry, &match); + if (!err) + goto out; /* success */ + else if (match) + goto out_iput; + } + + if (unlikely(au_test_unique_ino(h_dentry, h_ino))) + AuWarn1("Un-notified UDBA or repeatedly renamed dir," + " b%d, %s, %.*s, hi%lu, i%lu.\n", + bstart, au_sbtype(h_dentry->d_sb), AuDLNPair(dentry), + (unsigned long)h_ino, (unsigned long)xinoe.ino); + xinoe.ino = 0; + err = au_xino_write0(sb, bstart, h_ino, 0); + if (!err) { + iput(inode); + goto new_ino; + } + /* force noxino? */ + + out_iput: + iput(inode); + inode = ERR_PTR(err); + out: + AuTraceErrPtr(inode); + return inode; +} + +/* ---------------------------------------------------------------------- */ + +int au_test_ro(struct super_block *sb, aufs_bindex_t bindex, + struct inode *inode) +{ + int err; + + err = au_br_rdonly(au_sbr(sb, bindex)); + + /* pseudo-link after flushed may out of bounds */ + if (!err + && inode + && au_ibstart(inode) <= bindex + && bindex <= au_ibend(inode)) { + /* + * permission check is unnecessary since vfsub routine + * will be called later + */ + struct inode *hi = au_h_iptr(inode, bindex); + if (hi) + err = IS_IMMUTABLE(hi) ? -EROFS : 0; + } + + AuTraceErr(err); + return err; +} + +int au_test_h_perm(struct inode *h_inode, int mask, int dlgt) +{ + if (!current->fsuid) + return 0; + /* todo: fake nameidata? */ + return vfsub_permission(h_inode, mask, NULL, dlgt); +} + +int au_test_h_perm_sio(struct inode *h_inode, int mask, int dlgt) +{ + if (unlikely(au_test_nfs(h_inode->i_sb) + && (mask & MAY_WRITE) + && S_ISDIR(h_inode->i_mode))) + mask |= MAY_READ; /* force permission check */ + return au_test_h_perm(h_inode, mask, dlgt); +} --- linux-2.6.28.orig/ubuntu/aufs/debug.h +++ linux-2.6.28/ubuntu/aufs/debug.h @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * debug print functions + * + * $Id: debug.h,v 1.8 2008/09/22 03:52:03 sfjro Exp $ + */ + +#ifndef __AUFS_DEBUG_H__ +#define __AUFS_DEBUG_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +/* to debug easier, do not make it an inlined function */ +#define MtxMustLock(mtx) AuDebugOn(!mutex_is_locked(mtx)) + +#ifdef CONFIG_AUFS_DEBUG +/* sparse warns about pointer */ +#define AuDebugOn(a) BUG_ON(!!(a)) +extern atomic_t au_cond; +#define au_debug_on() atomic_inc_return(&au_cond) +#define au_debug_off() atomic_dec_return(&au_cond) +static inline int au_debug_test(void) +{ + return atomic_read(&au_cond); +} +#else +#define AuDebugOn(a) do {} while (0) +#define au_debug_on() do {} while (0) +#define au_debug_off() do {} while (0) +static inline int au_debug_test(void) +{ + return 0; +} +#endif /* CONFIG_AUFS_DEBUG */ + +/* ---------------------------------------------------------------------- */ + +/* debug print */ +#if defined(CONFIG_LKTR) || defined(CONFIG_LKTR_MODULE) +#include +#ifdef CONFIG_AUFS_DEBUG +#undef LktrCond +#define LktrCond unlikely(au_debug_test() || (lktr_cond && lktr_cond())) +#endif +#else +#define LktrCond au_debug_test() +#define LKTRDumpVma(pre, vma, suf) do {} while (0) +#define LKTRDumpStack() do {} while (0) +#define LKTRTrace(fmt, args...) do { \ + if (LktrCond) \ + AuDbg(fmt, ##args); \ +} while (0) +#define LKTRLabel(label) LKTRTrace("%s\n", #label) +#endif /* CONFIG_LKTR */ + +#define AuTraceErr(e) do { \ + if (unlikely((e) < 0)) \ + LKTRTrace("err %d\n", (int)(e)); \ +} while (0) + +#define AuTraceErrPtr(p) do { \ + if (IS_ERR(p)) \ + LKTRTrace("err %ld\n", PTR_ERR(p)); \ +} while (0) + +#define AuTraceEnter() LKTRLabel(enter) + +/* dirty macros for debug print, use with "%.*s" and caution */ +#define AuLNPair(qstr) (qstr)->len, (qstr)->name +#define AuDLNPair(d) AuLNPair(&(d)->d_name) + +/* ---------------------------------------------------------------------- */ + +#define AuDpri(lvl, fmt, arg...) \ + printk(lvl AUFS_NAME " %s:%d:%s[%d]: " fmt, \ + __func__, __LINE__, current->comm, current->pid, ##arg) +#define AuDbg(fmt, arg...) AuDpri(KERN_DEBUG, fmt, ##arg) +#define AuInfo(fmt, arg...) AuDpri(KERN_INFO, fmt, ##arg) +#define AuWarn(fmt, arg...) AuDpri(KERN_WARNING, fmt, ##arg) +#define AuErr(fmt, arg...) AuDpri(KERN_ERR, fmt, ##arg) +#define AuIOErr(fmt, arg...) AuErr("I/O Error, " fmt, ##arg) +#define AuIOErrWhck(fmt, arg...) AuErr("I/O Error, try whck. " fmt, ##arg) +#define AuWarn1(fmt, arg...) do { \ + static unsigned char _c; \ + if (!_c++) AuWarn(fmt, ##arg); \ +} while (0) + +#define AuErr1(fmt, arg...) do { \ + static unsigned char _c; \ + if (!_c++) AuErr(fmt, ##arg); \ +} while (0) + +#define AuIOErr1(fmt, arg...) do { \ + static unsigned char _c; \ + if (!_c++) AuIOErr(fmt, ##arg); \ +} while (0) + +#define AuUnsupportMsg "This operation is not supported." \ + " Please report this application to aufs-users ML." +#define AuUnsupport(fmt, args...) do { \ + AuErr(AuUnsupportMsg "\n" fmt, ##args); \ + dump_stack(); \ +} while (0) + +/* ---------------------------------------------------------------------- */ + +struct au_sbinfo; +#ifdef CONFIG_AUFS_DEBUG +extern char *au_plevel; +struct au_nhash; +void au_dpri_whlist(struct au_nhash *whlist); +struct au_vdir; +void au_dpri_vdir(struct au_vdir *vdir); +void au_dpri_inode(struct inode *inode); +void au_dpri_dentry(struct dentry *dentry); +void au_dpri_file(struct file *filp); +void au_dpri_sb(struct super_block *sb); +void au_dbg_sleep(int sec); +void au_dbg_sleep_jiffy(int jiffy); +#ifndef ATTR_TIMES_SET +#define ATTR_TIMES_SET 0 +#endif +void au_dbg_iattr(struct iattr *ia); +int __init au_debug_init(void); +void au_debug_sbinfo_init(struct au_sbinfo *sbinfo); +#define AuDbgWhlist(w) do { \ + LKTRTrace(#w "\n"); \ + au_dpri_whlist(w); \ +} while (0) + +#define AuDbgVdir(v) do { \ + LKTRTrace(#v "\n"); \ + au_dpri_vdir(v); \ +} while (0) + +#define AuDbgInode(i) do { \ + LKTRTrace(#i "\n"); \ + au_dpri_inode(i); \ +} while (0) + +#define AuDbgDentry(d) do { \ + LKTRTrace(#d "\n"); \ + au_dpri_dentry(d); \ +} while (0) + +#define AuDbgFile(f) do { \ + LKTRTrace(#f "\n"); \ + au_dpri_file(f); \ +} while (0) + +#define AuDbgSb(sb) do { \ + LKTRTrace(#sb "\n"); \ + au_dpri_sb(sb); \ +} while (0) + +#define AuDbgSleep(sec) do { \ + AuDbg("sleep %d sec\n", sec); \ + au_dbg_sleep(sec); \ +} while (0) + +#define AuDbgSleepJiffy(jiffy) do { \ + AuDbg("sleep %d jiffies\n", jiffy); \ + au_dbg_sleep_jiffy(jiffy); \ +} while (0) + +#define AuDbgIAttr(ia) do { \ + AuDbg("ia_valid 0x%x\n", (ia)->ia_valid); \ + au_dbg_iattr(ia); \ +} while (0) +#else +static inline int au_debug_init(void) +{ + return 0; +} +static inline void au_debug_sbinfo_init(struct au_sbinfo *sbinfo) +{ + /* empty */ +} +#define AuDbgWhlist(w) do {} while (0) +#define AuDbgVdir(v) do {} while (0) +#define AuDbgInode(i) do {} while (0) +#define AuDbgDentry(d) do {} while (0) +#define AuDbgFile(f) do {} while (0) +#define AuDbgSb(sb) do {} while (0) +#define AuDbgSleep(sec) do {} while (0) +#define AuDbgSleepJiffy(jiffy) do {} while (0) +#define AuDbgIAttr(ia) do {} while (0) +#endif /* CONFIG_AUFS_DEBUG */ + +#ifdef DbgUdbaRace +#define AuDbgSleep_UdbaRace() AuDbgSleep(DbgUdbaRace) +#else +#define AuDbgSleep_UdbaRace() do {} while (0) +#endif + +#ifdef CONFIG_AUFS_MAGIC_SYSRQ +int __init au_sysrq_init(void); +void au_sysrq_fin(void); + +#ifdef CONFIG_HW_CONSOLE +#define au_dbg_blocked() do { \ + WARN_ON(1); \ + handle_sysrq('w', vc_cons[fg_console].d->vc_tty); \ +} while (0) +#else +#define au_dbg_blocked() do {} while (0) +#endif + +#else +static inline int au_sysrq_init(void) +{ + return 0; +} +#define au_sysrq_fin() do {} while (0) +#define au_dbg_blocked() do {} while (0) +#endif /* CONFIG_AUFS_MAGIC_SYSRQ */ + +#endif /* __KERNEL__ */ +#endif /* __AUFS_DEBUG_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/BOM +++ linux-2.6.28/ubuntu/aufs/BOM @@ -0,0 +1,3 @@ +Downloaded from: pserver:anonymous@aufs.cvs.sourceforge.net:/cvsroot/aufs +Current Version: Mon, 22 Sep 2008 +Comments: Unmodified upstream checkout --- linux-2.6.28.orig/ubuntu/aufs/aufs.h +++ linux-2.6.28/ubuntu/aufs/aufs.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * main header files + * + * $Id: aufs.h,v 1.4 2008/06/30 03:58:55 sfjro Exp $ + */ + +#ifndef __AUFS_H__ +#define __AUFS_H__ + +#ifdef __KERNEL__ + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25) +#error you got wrong version +#endif + +#include "debug.h" + +#include "branch.h" +#include "cpup.h" +#include "dcsub.h" +#include "dentry.h" +#include "dir.h" +#include "file.h" +#include "hinode.h" +#include "inode.h" +#include "misc.h" +#include "module.h" +#include "opts.h" +#include "super.h" +#include "sysaufs.h" +#include "vfsub.h" +#include "whout.h" +#include "wkq.h" +/* reserved for future use */ +/* #include "xattr.h" */ + +#ifdef AuNoInlineForStack +#undef noinline_for_stack +#define noinline_for_stack /* */ +#endif + +#endif /* __KERNEL__ */ +#endif /* __AUFS_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/finfo.c +++ linux-2.6.28/ubuntu/aufs/finfo.c @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * file private data + * + * $Id: finfo.c,v 1.4 2008/06/30 03:50:21 sfjro Exp $ + */ + +#include "aufs.h" + +struct au_finfo *au_fi(struct file *file) +{ + struct au_finfo *finfo = file->private_data; + AuDebugOn(!finfo + || !finfo->fi_hfile + || (0 < finfo->fi_bend + && (/* au_sbi(file->f_dentry->d_sb)->si_bend + < finfo->fi_bend + || */ finfo->fi_bend < finfo->fi_bstart))); + return finfo; +} + +struct au_branch *au_fbr(struct file *file, aufs_bindex_t bindex) +{ + struct au_finfo *finfo = au_fi(file); + struct au_hfile *hf; + + FiMustAnyLock(file); + AuDebugOn(!finfo + || finfo->fi_bstart < 0 + || bindex < finfo->fi_bstart + || finfo->fi_bend < bindex); + hf = finfo->fi_hfile + bindex; + AuDebugOn(hf->hf_br && au_br_count(hf->hf_br) <= 0); + return hf->hf_br; +} + +struct file *au_h_fptr(struct file *file, aufs_bindex_t bindex) +{ + struct au_finfo *finfo = au_fi(file); + struct au_hfile *hf; + + FiMustAnyLock(file); + AuDebugOn(!finfo + || finfo->fi_bstart < 0 + || bindex < finfo->fi_bstart + || finfo->fi_bend < bindex); + hf = finfo->fi_hfile + bindex; + AuDebugOn(hf->hf_file + && file_count(hf->hf_file) <= 0 + && au_br_count(hf->hf_br) <= 0); + return hf->hf_file; +} + +void au_hfput(struct au_hfile *hf) +{ + if (hf->hf_file->f_mode & FMODE_EXEC) + au_allow_write_access(hf->hf_file); + fput(hf->hf_file); + hf->hf_file = NULL; + AuDebugOn(!hf->hf_br); + au_br_put(hf->hf_br); + hf->hf_br = NULL; +} + +void au_set_h_fptr(struct file *file, aufs_bindex_t bindex, struct file *val) +{ + struct au_finfo *finfo = au_fi(file); + struct au_hfile *hf; + + FiMustWriteLock(file); + AuDebugOn(!finfo + || finfo->fi_bstart < 0 + || bindex < finfo->fi_bstart + || finfo->fi_bend < bindex); + AuDebugOn(val && file_count(val) <= 0); + hf = finfo->fi_hfile + bindex; + AuDebugOn(val && hf->hf_file); + if (hf->hf_file) + au_hfput(hf); + if (val) { + hf->hf_file = val; + hf->hf_br = au_sbr(file->f_dentry->d_sb, bindex); + } +} + +void au_finfo_fin(struct file *file) +{ + struct au_finfo *finfo; + struct dentry *dentry; + aufs_bindex_t bindex, bend; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + SiMustAnyLock(dentry->d_sb); + + fi_write_lock(file); + bend = au_fbend(file); + bindex = au_fbstart(file); + if (bindex >= 0) + for (; bindex <= bend; bindex++) + au_set_h_fptr(file, bindex, NULL); + + finfo = au_fi(file); +#ifdef CONFIG_AUFS_DEBUG + if (finfo->fi_bstart >= 0) { + bend = au_fbend(file); + for (bindex = finfo->fi_bstart; bindex <= bend; bindex++) { + struct au_hfile *hf; + hf = finfo->fi_hfile + bindex; + AuDebugOn(hf->hf_file || hf->hf_br); + } + } +#endif + + kfree(finfo->fi_hfile); + fi_write_unlock(file); + au_cache_free_finfo(finfo); +} + +int au_finfo_init(struct file *file) +{ + struct au_finfo *finfo; + struct dentry *dentry; + union { + void *p; + unsigned long ul; + } u; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + AuDebugOn(!dentry->d_inode); + + finfo = au_cache_alloc_finfo(); + if (finfo) { + finfo->fi_hfile = kcalloc(au_sbend(dentry->d_sb) + 1, + sizeof(*finfo->fi_hfile), GFP_NOFS); + if (finfo->fi_hfile) { + au_rw_init_wlock(&finfo->fi_rwsem); + finfo->fi_bstart = -1; + finfo->fi_bend = -1; + atomic_set(&finfo->fi_generation, au_digen(dentry)); + /* smp_mb(); */ /* atomic_set */ + + /* + * a dirty trick for handling FMODE_EXEC and + * deny_write_access(). + * because FMODE_EXEC flag is not passed to + * f_op->open(), + * aufs set it to file->private_data temporary in lookup + * or dentry revalidation operations. + * restore the flag to f_mode here. + */ + u.p = file->private_data; + if (u.ul & FMODE_EXEC) { + file->f_mode |= FMODE_EXEC; + smp_mb(); /* flush f_mode */ + } + + file->private_data = finfo; + return 0; /* success */ + } + au_cache_free_finfo(finfo); + } + + AuTraceErr(-ENOMEM); + return -ENOMEM; +} --- linux-2.6.28.orig/ubuntu/aufs/wkq.h +++ linux-2.6.28/ubuntu/aufs/wkq.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * workqueue for asynchronous/super-io/delegated operations + * + * $Id: wkq.h,v 1.7 2008/09/15 03:16:36 sfjro Exp $ + */ + +#ifndef __AUFS_WKQ_H__ +#define __AUFS_WKQ_H__ + +#ifdef __KERNEL__ + +#include +#include +#include +#include + +/* ---------------------------------------------------------------------- */ + +/* internal workqueue named AUFS_WKQ_NAME */ +struct au_wkq { + struct workqueue_struct *q; + + /* balancing */ + atomic_t busy; + + /* accounting */ +#ifdef CONFIG_AUFS_STAT + unsigned int max_busy; +#endif +}; + +/* + * in the next operation, wait for the 'nowait' tasks in system-wide workqueue + */ +struct au_nowait_tasks { + atomic_t nw_len; + wait_queue_head_t nw_wq; +}; + +/* ---------------------------------------------------------------------- */ + +extern struct au_wkq *au_wkq; +typedef void (*au_wkq_func_t)(void *args); + +/* wkq flags */ +#define AuWkq_WAIT 1 +#define AuWkq_DLGT (1 << 1) +#define au_ftest_wkq(flags, name) ((flags) & AuWkq_##name) +#define au_fset_wkq(flags, name) { (flags) |= AuWkq_##name; } +#define au_fclr_wkq(flags, name) { (flags) &= ~AuWkq_##name; } +#ifndef CONFIG_AUFS_DLGT +#undef AuWkq_DLGT +#define AuWkq_DLGT 0 +#endif + +int au_wkq_run(au_wkq_func_t func, void *args, struct super_block *sb, + unsigned int flags); +int au_wkq_nowait(au_wkq_func_t func, void *args, struct super_block *sb, + int dlgt); +int __init au_wkq_init(void); +void au_wkq_fin(void); + +/* ---------------------------------------------------------------------- */ + +static inline int au_test_wkq(struct task_struct *tsk) +{ + return (!tsk->mm && !strcmp(tsk->comm, AUFS_WKQ_NAME)); +#if 0 /* reserved for future use, per-cpu workqueue */ + return (!tsk->mm + && !memcmp(tsk->comm, AUFS_WKQ_NAME "/", + sizeof(AUFS_WKQ_NAME))); +#endif +} + +static inline int au_wkq_wait(au_wkq_func_t func, void *args, int dlgt) +{ + unsigned int flags = AuWkq_WAIT; + if (unlikely(dlgt)) + au_fset_wkq(flags, DLGT); + return au_wkq_run(func, args, /*sb*/NULL, flags); +} + +static inline void au_wkq_max_busy_init(struct au_wkq *wkq) +{ +#ifdef CONFIG_AUFS_STAT + wkq->max_busy = 0; +#endif +} + +/* todo: memory barrier? */ +static inline void au_nwt_init(struct au_nowait_tasks *nwt) +{ + atomic_set(&nwt->nw_len, 0); + smp_mb(); /* atomic_set */ + init_waitqueue_head(&nwt->nw_wq); +} + +/* todo: make it void */ +static inline int au_nwt_done(struct au_nowait_tasks *nwt) +{ + int ret; + + AuTraceEnter(); + + ret = atomic_dec_return(&nwt->nw_len); + if (!ret) + wake_up_all(&nwt->nw_wq); + return ret; +} + +static inline int au_nwt_flush(struct au_nowait_tasks *nwt) +{ + wait_event(nwt->nw_wq, !atomic_read(&nwt->nw_len)); + return 0; +} + +#endif /* __KERNEL__ */ +#endif /* __AUFS_WKQ_H__ */ --- linux-2.6.28.orig/ubuntu/aufs/f_op.c +++ linux-2.6.28/ubuntu/aufs/f_op.c @@ -0,0 +1,670 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * file and vm operations + * + * $Id: f_op.c,v 1.11 2008/09/01 02:55:44 sfjro Exp $ + */ + +#include +#include +#include "aufs.h" + +/* common function to regular file and dir */ +int aufs_flush(struct file *file, fl_owner_t id) +{ + int err; + struct dentry *dentry; + aufs_bindex_t bindex, bend; + struct file *h_file; + + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + + si_noflush_read_lock(dentry->d_sb); + fi_read_lock(file); + di_read_lock_child(dentry, AuLock_IW); + + err = 0; + bend = au_fbend(file); + for (bindex = au_fbstart(file); !err && bindex <= bend; bindex++) { + h_file = au_h_fptr(file, bindex); + if (h_file && h_file->f_op && h_file->f_op->flush) { + err = h_file->f_op->flush(h_file, id); + if (!err) + au_update_fuse_h_inode + (h_file->f_vfsmnt, h_file->f_dentry); + /*ignore*/ + } + } + au_cpup_attr_timesizes(dentry->d_inode); + + di_read_unlock(dentry, AuLock_IW); + fi_read_unlock(file); + si_read_unlock(dentry->d_sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static int do_open_nondir(struct file *file, int flags) +{ + int err; + aufs_bindex_t bindex; + struct super_block *sb; + struct file *h_file; + struct dentry *dentry; + struct inode *inode; + struct au_finfo *finfo; + + dentry = file->f_dentry; + LKTRTrace("%.*s, flags 0%o\n", AuDLNPair(dentry), flags); + FiMustWriteLock(file); + inode = dentry->d_inode; + AuDebugOn(!inode || S_ISDIR(inode->i_mode)); + + err = 0; + finfo = au_fi(file); + finfo->fi_h_vm_ops = NULL; + sb = dentry->d_sb; + bindex = au_dbstart(dentry); + AuDebugOn(!au_h_dptr(dentry, bindex)->d_inode); + /* O_TRUNC is processed already */ + BUG_ON(au_test_ro(sb, bindex, inode) && (flags & O_TRUNC)); + + h_file = au_h_open(dentry, bindex, flags, file); + if (IS_ERR(h_file)) + err = PTR_ERR(h_file); + else { + au_set_fbstart(file, bindex); + au_set_fbend(file, bindex); + au_set_h_fptr(file, bindex, h_file); + au_update_figen(file); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + err = 0; + } + AuTraceErr(err); + return err; +} + +static int aufs_open_nondir(struct inode *inode, struct file *file) +{ + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + return au_do_open(inode, file, do_open_nondir); +} + +static int aufs_release_nondir(struct inode *inode, struct file *file) +{ + struct super_block *sb = file->f_dentry->d_sb; + + LKTRTrace("i%lu, %.*s\n", inode->i_ino, AuDLNPair(file->f_dentry)); + + si_noflush_read_lock(sb); + au_finfo_fin(file); + si_read_unlock(sb); + return 0; +} + +/* ---------------------------------------------------------------------- */ + +static ssize_t aufs_read(struct file *file, char __user *buf, size_t count, + loff_t *ppos) +{ + ssize_t err; + struct dentry *dentry; + struct file *h_file; + struct super_block *sb; + struct inode *h_inode; + + dentry = file->f_dentry; + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(dentry), (unsigned long)count, *ppos); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + /* support LSM and notify */ + h_file = au_h_fptr(file, au_fbstart(file)); + h_inode = h_file->f_dentry->d_inode; + err = vfsub_read_u(h_file, buf, count, ppos, + au_test_dlgt(au_mntflags(sb))); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); + + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +static ssize_t aufs_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + ssize_t err; + struct dentry *dentry; + struct inode *inode; + struct super_block *sb; + unsigned int mnt_flags; + struct file *h_file; + char __user *buf = (char __user *)ubuf; + struct au_hin_ignore ign; + struct vfsub_args vargs; + aufs_bindex_t bstart; + int hinotify; + struct au_pin pin; + + dentry = file->f_dentry; + LKTRTrace("%.*s, cnt %lu, pos %lld\n", + AuDLNPair(dentry), (unsigned long)count, *ppos); + + inode = dentry->d_inode; + mutex_lock(&inode->i_mutex); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + mnt_flags = au_mntflags(sb); + hinotify = !!au_opt_test(mnt_flags, UDBA_INOTIFY); + vfsub_args_init(&vargs, &ign, au_test_dlgt(mnt_flags), 0); + + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + + bstart = au_fbstart(file); + h_file = au_h_fptr(file, bstart); + if (!hinotify) { + au_unpin(&pin); + err = vfsub_write_u(h_file, buf, count, ppos, &vargs); + } else { + vfsub_ign_hinode(&vargs, IN_MODIFY, + au_pinned_hdir(&pin, bstart)); + err = vfsub_write_u(h_file, buf, count, ppos, &vargs); + au_unpin(&pin); + } + au_cpup_attr_timesizes(inode); + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + fi_write_unlock(file); + out: + si_read_unlock(sb); + mutex_unlock(&inode->i_mutex); + AuTraceErr(err); + return err; +} + +#ifdef CONFIG_AUFS_SPLICE_PATCH +static int au_test_loopback(void) +{ + const char c = current->comm[4]; + /* true if a kernel thread named 'loop[0-9].*' accesses a file */ + const int loopback = (current->mm == NULL + && '0' <= c && c <= '9' + && strncmp(current->comm, "loop", 4) == 0); + return loopback; +} + +static ssize_t aufs_splice_read(struct file *file, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) +{ + ssize_t err; + struct file *h_file; + struct dentry *dentry; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, pos %lld, len %lu\n", + AuDLNPair(dentry), *ppos, (unsigned long)len); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + err = -EINVAL; + /* support LSM and notify */ + h_file = au_h_fptr(file, au_fbstart(file)); + if (/* unlikely */(au_test_loopback())) { + file->f_mapping = h_file->f_mapping; + smp_mb(); /* unnecessary? */ + } + err = vfsub_splice_to(h_file, ppos, pipe, len, flags, + au_test_dlgt(au_mntflags(sb))); + /* todo: necessasry? */ + /* file->f_ra = h_file->f_ra; */ + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +static ssize_t +aufs_splice_write(struct pipe_inode_info *pipe, struct file *file, loff_t *ppos, + size_t len, unsigned int flags) +{ + ssize_t err; + struct dentry *dentry; + struct inode *inode, *h_inode; + struct super_block *sb; + struct file *h_file; + /* struct au_hin_ignore ign; */ + struct vfsub_args vargs; + unsigned int mnt_flags; + struct au_pin pin; + + dentry = file->f_dentry; + LKTRTrace("%.*s, len %lu, pos %lld\n", + AuDLNPair(dentry), (unsigned long)len, *ppos); + + inode = dentry->d_inode; + mutex_lock(&inode->i_mutex); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + mnt_flags = au_mntflags(sb); + vfsub_args_init(&vargs, /*&ign*/NULL, au_test_dlgt(mnt_flags), 0); + + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + + /* support LSM and notify */ + /* current vfs_splice_from() doesn't fire up the inotify event */ + h_file = au_h_fptr(file, au_fbstart(file)); + h_inode = h_file->f_dentry->d_inode; + if (1 || !au_opt_test(mnt_flags, UDBA_INOTIFY)) { + au_unpin(&pin); + err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs); + } +#if 0 /* reserved for future use */ + else { + struct dentry *parent = dget_parent(dentry); + vfsub_ign_hinode(&vargs, IN_MODIFY, + au_pinned_hdir(&pin, bstart)); + err = vfsub_splice_from(pipe, h_file, ppos, len, flags, &vargs); + au_unpin(&pin); + } +#endif + au_cpup_attr_timesizes(inode); + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + fi_write_unlock(file); + out: + si_read_unlock(sb); + mutex_unlock(&inode->i_mutex); + AuTraceErr(err); + return err; +} +#endif /* CONFIG_AUFS_SPLICE_PATCH */ + +/* ---------------------------------------------------------------------- */ + +static int aufs_fault(struct vm_area_struct *vma, struct vm_fault *vmf) +{ + int err; + struct dentry *dentry; + struct file *file, *h_file; + struct inode *inode; + static DECLARE_WAIT_QUEUE_HEAD(wq); + struct au_finfo *finfo; + + AuTraceEnter(); + AuDebugOn(!vma || !vma->vm_file); + /* todo: non-robr mode, user vm_file as it is? */ + wait_event(wq, (file = au_robr_safe_file(vma))); + AuDebugOn(!au_test_aufs(file->f_dentry->d_sb)); + dentry = file->f_dentry; + LKTRTrace("%.*s\n", AuDLNPair(dentry)); + inode = dentry->d_inode; + AuDebugOn(!S_ISREG(inode->i_mode)); + + /* do not revalidate, no si lock */ + finfo = au_fi(file); + h_file = finfo->fi_hfile[0 + finfo->fi_bstart].hf_file; + AuDebugOn(!h_file || !au_test_mmapped(file)); + fi_write_lock(file); + vma->vm_file = h_file; + err = finfo->fi_h_vm_ops->fault(vma, vmf); + /* todo: necessary? */ + /* file->f_ra = h_file->f_ra; */ + au_robr_reset_file(vma, file); + fi_write_unlock(file); +#if 0 /* def CONFIG_SMP */ + /* wake_up_nr(&wq, online_cpu - 1); */ + wake_up_all(&wq); +#else + wake_up(&wq); +#endif + + if (!(err & VM_FAULT_ERROR)) { +#if 0 /* debug */ + struct page *page; + page = vmf->page; + AuDbg("%p, %d\n", page, page_mapcount(page)); + + page->mapping = file->f_mapping; + get_page(page); + file->f_mapping = h_file->f_mapping; + touch_atime(NULL, dentry); + inode->i_atime = h_file->f_dentry->d_inode->i_atime; +#endif + } + AuTraceErr(err); + return err; +} + +static struct vm_operations_struct aufs_vm_ops = { + .fault = aufs_fault, +#if 0 /* reserved for future use */ + .open = aufs_vmaopen, + .close = aufs_vmaclose, + unsigned long (*nopfn)(struct vm_area_struct *area, + unsigned long address); + page_mkwrite(struct vm_area_struct *vma, struct page *page) +#endif +}; + +/* ---------------------------------------------------------------------- */ + +static struct vm_operations_struct *au_vm_ops(struct file *h_file, + struct vm_area_struct *vma) +{ + struct vm_operations_struct *vm_ops; + int err; + + AuTraceEnter(); + + au_br_nfs_lockdep_off(h_file->f_vfsmnt->mnt_sb); + err = h_file->f_op->mmap(h_file, vma); + au_br_nfs_lockdep_on(h_file->f_vfsmnt->mnt_sb); + vm_ops = ERR_PTR(err); + if (unlikely(err)) + goto out; + vm_ops = vma->vm_ops; + err = do_munmap(current->mm, vma->vm_start, + vma->vm_end - vma->vm_start); + if (unlikely(err)) { + AuIOErr("failed internal unmapping %.*s, %d\n", + AuDLNPair(h_file->f_dentry), err); + vm_ops = ERR_PTR(-EIO); + } + + out: + AuTraceErrPtr(vm_ops); + return vm_ops; +} + +static int aufs_mmap(struct file *file, struct vm_area_struct *vma) +{ + int err; + unsigned char wlock, mmapped; + struct dentry *dentry; + struct super_block *sb; + struct file *h_file; + struct vm_operations_struct *vm_ops; + + dentry = file->f_dentry; + LKTRTrace("%.*s, %lx, len %lu\n", + AuDLNPair(dentry), vma->vm_start, + vma->vm_end - vma->vm_start); + AuDebugOn(!S_ISREG(dentry->d_inode->i_mode)); + AuDebugOn(down_write_trylock(&vma->vm_mm->mmap_sem)); + + mmapped = au_test_mmapped(file); /* can be harmless race condition */ + wlock = !!(file->f_mode & FMODE_WRITE); + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, wlock | !mmapped, + /*locked*/0); + if (unlikely(err)) + goto out; + + if (wlock) { + struct au_pin pin; + + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + au_unpin(&pin); + } else if (!mmapped) + di_downgrade_lock(dentry, AuLock_IR); + + h_file = au_h_fptr(file, au_fbstart(file)); + if (unlikely(au_test_fuse(h_file->f_dentry->d_sb))) { + /* + * by this assignment, f_mapping will differs from aufs inode + * i_mapping. + * if someone else mixes the use of f_dentry->d_inode and + * f_mapping->host, then a problem may arise. + */ + file->f_mapping = h_file->f_mapping; + } + + if (0 && h_file->f_op->mmap == generic_file_mmap) { + err = generic_file_mmap(file, vma); /* instead of h_file */ + if (unlikely(err)) + goto out_unlock; + au_fi(file)->fi_h_vm_ops = vma->vm_ops; + } else { + vm_ops = NULL; + if (!mmapped) { + vm_ops = au_vm_ops(h_file, vma); + err = PTR_ERR(vm_ops); + if (IS_ERR(vm_ops)) + goto out_unlock; + } + + err = generic_file_mmap(file, vma); + if (unlikely(err)) + goto out_unlock; + vma->vm_ops = &aufs_vm_ops; + /* test again */ + if (!au_test_mmapped(file)) { + FiMustWriteLock(file); + au_fi(file)->fi_h_vm_ops = vm_ops; + } + } + + file_accessed(h_file); + au_update_fuse_h_inode(h_file->f_vfsmnt, h_file->f_dentry); /*ignore*/ + fsstack_copy_attr_atime(dentry->d_inode, h_file->f_dentry->d_inode); + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + if (!wlock && mmapped) + fi_read_unlock(file); + else + fi_write_unlock(file); + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +static unsigned int aufs_poll(struct file *file, poll_table *wait) +{ + unsigned int mask; + struct file *h_file; + int err; + struct dentry *dentry; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, wait %p\n", AuDLNPair(dentry), wait); + AuDebugOn(S_ISDIR(dentry->d_inode->i_mode)); + + /* We should pretend an error happened. */ + mask = POLLERR /* | POLLIN | POLLOUT */; + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + /* it is not an error of hidden_file has no operation */ + mask = DEFAULT_POLLMASK; + h_file = au_h_fptr(file, au_fbstart(file)); + if (h_file->f_op && h_file->f_op->poll) + mask = h_file->f_op->poll(h_file, wait); + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr((int)mask); + return mask; +} + +static int aufs_fsync_nondir(struct file *file, struct dentry *dentry, + int datasync) +{ + int err; + struct inode *inode; + struct file *h_file; + struct super_block *sb; + struct au_pin pin; + + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), datasync); + inode = dentry->d_inode; + + IMustLock(file->f_mapping->host); + if (unlikely(inode != file->f_mapping->host)) { + mutex_unlock(&file->f_mapping->host->i_mutex); + mutex_lock(&inode->i_mutex); + } + IMustLock(inode); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = 0; /* -EBADF; */ /* posix? */ + if (unlikely(!(file->f_mode & FMODE_WRITE))) + goto out; + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/1, + /*locked*/1); + if (unlikely(err)) + goto out; + err = au_ready_to_write(file, -1, &pin); + di_downgrade_lock(dentry, AuLock_IR); + if (unlikely(err)) + goto out_unlock; + au_unpin(&pin); + + err = -EINVAL; + h_file = au_h_fptr(file, au_fbstart(file)); + if (h_file->f_op && h_file->f_op->fsync) { + struct mutex *h_mtx = &h_file->f_dentry->d_inode->i_mutex; + + mutex_lock_nested(h_mtx, AuLsc_I_CHILD); + err = h_file->f_op->fsync(h_file, h_file->f_dentry, datasync); + if (!err) + au_update_fuse_h_inode(h_file->f_vfsmnt, + h_file->f_dentry); + au_cpup_attr_timesizes(inode); + mutex_unlock(h_mtx); + } + + out_unlock: + di_read_unlock(dentry, AuLock_IR); + fi_write_unlock(file); + out: + si_read_unlock(sb); + if (unlikely(inode != file->f_mapping->host)) { + mutex_unlock(&inode->i_mutex); + mutex_lock(&file->f_mapping->host->i_mutex); + } + AuTraceErr(err); + return err; +} + +static int aufs_fasync(int fd, struct file *file, int flag) +{ + int err; + struct file *h_file; + struct dentry *dentry; + struct super_block *sb; + + dentry = file->f_dentry; + LKTRTrace("%.*s, %d\n", AuDLNPair(dentry), flag); + + sb = dentry->d_sb; + si_read_lock(sb, AuLock_FLUSH); + err = au_reval_and_lock_fdi(file, au_reopen_nondir, /*wlock*/0, + /*locked*/0); + if (unlikely(err)) + goto out; + + h_file = au_h_fptr(file, au_fbstart(file)); + if (h_file->f_op && h_file->f_op->fasync) + err = h_file->f_op->fasync(fd, h_file, flag); + di_read_unlock(dentry, AuLock_IR); + fi_read_unlock(file); + + out: + si_read_unlock(sb); + AuTraceErr(err); + return err; +} + +/* ---------------------------------------------------------------------- */ + +struct file_operations aufs_file_fop = { + .read = aufs_read, + .write = aufs_write, + .poll = aufs_poll, + .mmap = aufs_mmap, + .open = aufs_open_nondir, + .flush = aufs_flush, + .release = aufs_release_nondir, + .fsync = aufs_fsync_nondir, + .fasync = aufs_fasync, +#ifdef CONFIG_AUFS_SPLICE_PATCH + .splice_write = aufs_splice_write, + .splice_read = aufs_splice_read, +#endif +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/param.c +++ linux-2.6.28/ubuntu/iscsitarget/param.c @@ -0,0 +1,194 @@ +/* + * (C) 2005 FUJITA Tomonori + * + * This code is licenced under the GPL. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "digest.h" + +struct target_type *target_type_array[] = { + &disk_ops, +}; + +#define CHECK_PARAM(info, iparam, word, min, max) \ +do { \ + if (!info->partial || (info->partial & 1 << key_##word)) \ + if (iparam[key_##word] < min || \ + iparam[key_##word] > max) { \ + eprintk("%s: %u is out of range (%u %u)\n", \ + #word, iparam[key_##word], min, max); \ + iparam[key_##word] = min; \ + } \ +} while (0) + +#define SET_PARAM(param, info, iparam, word) \ +({ \ + int changed = 0; \ + if (!info->partial || (info->partial & 1 << key_##word)) { \ + if (param->word != iparam[key_##word]) \ + changed = 1; \ + param->word = iparam[key_##word]; \ + } \ + changed; \ +}) + +#define GET_PARAM(param, info, iparam, word) \ +do { \ + iparam[key_##word] = param->word; \ +} while (0) + +static void sess_param_check(struct iscsi_param_info *info) +{ + u32 *iparam = info->session_param; + + CHECK_PARAM(info, iparam, max_connections, 1, 1); + CHECK_PARAM(info, iparam, max_recv_data_length, 512, + (u32) ((ISCSI_CONN_IOV_MAX - 1) * PAGE_CACHE_SIZE)); + CHECK_PARAM(info, iparam, max_xmit_data_length, 512, + (u32) ((ISCSI_CONN_IOV_MAX - 1) * PAGE_CACHE_SIZE)); + CHECK_PARAM(info, iparam, error_recovery_level, 0, 0); + CHECK_PARAM(info, iparam, data_pdu_inorder, 1, 1); + CHECK_PARAM(info, iparam, data_sequence_inorder, 1, 1); + + digest_alg_available(&iparam[key_header_digest]); + digest_alg_available(&iparam[key_data_digest]); + + CHECK_PARAM(info, iparam, ofmarker, 0, 0); + CHECK_PARAM(info, iparam, ifmarker, 0, 0); +} + +static void sess_param_set(struct iscsi_sess_param *param, struct iscsi_param_info *info) +{ + u32 *iparam = info->session_param; + + SET_PARAM(param, info, iparam, initial_r2t); + SET_PARAM(param, info, iparam, immediate_data); + SET_PARAM(param, info, iparam, max_connections); + SET_PARAM(param, info, iparam, max_recv_data_length); + SET_PARAM(param, info, iparam, max_xmit_data_length); + SET_PARAM(param, info, iparam, max_burst_length); + SET_PARAM(param, info, iparam, first_burst_length); + SET_PARAM(param, info, iparam, default_wait_time); + SET_PARAM(param, info, iparam, default_retain_time); + SET_PARAM(param, info, iparam, max_outstanding_r2t); + SET_PARAM(param, info, iparam, data_pdu_inorder); + SET_PARAM(param, info, iparam, data_sequence_inorder); + SET_PARAM(param, info, iparam, error_recovery_level); + SET_PARAM(param, info, iparam, header_digest); + SET_PARAM(param, info, iparam, data_digest); + SET_PARAM(param, info, iparam, ofmarker); + SET_PARAM(param, info, iparam, ifmarker); + SET_PARAM(param, info, iparam, ofmarkint); + SET_PARAM(param, info, iparam, ifmarkint); +} + +static void sess_param_get(struct iscsi_sess_param *param, struct iscsi_param_info *info) +{ + u32 *iparam = info->session_param; + + GET_PARAM(param, info, iparam, initial_r2t); + GET_PARAM(param, info, iparam, immediate_data); + GET_PARAM(param, info, iparam, max_connections); + GET_PARAM(param, info, iparam, max_recv_data_length); + GET_PARAM(param, info, iparam, max_xmit_data_length); + GET_PARAM(param, info, iparam, max_burst_length); + GET_PARAM(param, info, iparam, first_burst_length); + GET_PARAM(param, info, iparam, default_wait_time); + GET_PARAM(param, info, iparam, default_retain_time); + GET_PARAM(param, info, iparam, max_outstanding_r2t); + GET_PARAM(param, info, iparam, data_pdu_inorder); + GET_PARAM(param, info, iparam, data_sequence_inorder); + GET_PARAM(param, info, iparam, error_recovery_level); + GET_PARAM(param, info, iparam, header_digest); + GET_PARAM(param, info, iparam, data_digest); + GET_PARAM(param, info, iparam, ofmarker); + GET_PARAM(param, info, iparam, ifmarker); + GET_PARAM(param, info, iparam, ofmarkint); + GET_PARAM(param, info, iparam, ifmarkint); +} + +static void trgt_param_check(struct iscsi_param_info *info) +{ + u32 *iparam = info->target_param; + + CHECK_PARAM(info, iparam, wthreads, MIN_NR_WTHREADS, MAX_NR_WTHREADS); + CHECK_PARAM(info, iparam, target_type, 0, + (unsigned int) ARRAY_SIZE(target_type_array) - 1); + CHECK_PARAM(info, iparam, queued_cmnds, MIN_NR_QUEUED_CMNDS, MAX_NR_QUEUED_CMNDS); +} + +static void trgt_param_set(struct iscsi_target *target, struct iscsi_param_info *info) +{ + struct iscsi_trgt_param *param = &target->trgt_param; + u32 *iparam = info->target_param; + + if (SET_PARAM(param, info, iparam, wthreads)) + wthread_start(target); + SET_PARAM(param, info, iparam, target_type); + SET_PARAM(param, info, iparam, queued_cmnds); +} + +static void trgt_param_get(struct iscsi_trgt_param *param, struct iscsi_param_info *info) +{ + u32 *iparam = info->target_param; + + GET_PARAM(param, info, iparam, wthreads); + GET_PARAM(param, info, iparam, target_type); + GET_PARAM(param, info, iparam, queued_cmnds); +} + +static int trgt_param(struct iscsi_target *target, struct iscsi_param_info *info, int set) +{ + + if (set) { + trgt_param_check(info); + trgt_param_set(target, info); + } else + trgt_param_get(&target->trgt_param, info); + + return 0; +} + +static int sess_param(struct iscsi_target *target, struct iscsi_param_info *info, int set) +{ + struct iscsi_session *session = NULL; + struct iscsi_sess_param *param; + int err = -ENOENT; + + if (set) + sess_param_check(info); + + if (info->sid) { + if (!(session = session_lookup(target, info->sid))) + goto out; + param = &session->param; + } else { + param = &target->sess_param; + } + + if (set) { + sess_param_set(param, info); + show_param(param); + } else + sess_param_get(param, info); + + err = 0; +out: + return err; +} + +int iscsi_param_set(struct iscsi_target *target, struct iscsi_param_info *info, int set) +{ + int err; + + if (info->param_type == key_session) + err = sess_param(target, info, set); + else if (info->param_type == key_target) + err = trgt_param(target, info, set); + else + err = -EINVAL; + + return err; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/iet_u.h +++ linux-2.6.28/ubuntu/iscsitarget/iet_u.h @@ -0,0 +1,139 @@ +#ifndef _IET_U_H +#define _IET_U_H + +#define IET_VERSION_STRING "0.4.15" + +/* The maximum length of 223 bytes in the RFC. */ +#define ISCSI_NAME_LEN 256 +#define ISCSI_ARGS_LEN 2048 + +#define ISCSI_LISTEN_PORT 3260 + +#define VENDOR_ID_LEN 8 +#define SCSI_ID_LEN 24 +#define SCSI_SN_LEN 16 + +#ifndef aligned_u64 +#define aligned_u64 unsigned long long __attribute__((aligned(8))) +#endif + +struct target_info { + u32 tid; + char name[ISCSI_NAME_LEN]; +}; + +struct volume_info { + u32 tid; + u32 lun; + aligned_u64 args_ptr; + u32 args_len; +}; + +struct session_info { + u32 tid; + + aligned_u64 sid; + char initiator_name[ISCSI_NAME_LEN]; + u32 exp_cmd_sn; + u32 max_cmd_sn; +}; + +#define DIGEST_ALL (DIGEST_NONE | DIGEST_CRC32C) +#define DIGEST_NONE (1 << 0) +#define DIGEST_CRC32C (1 << 1) + +struct conn_info { + u32 tid; + aligned_u64 sid; + + u32 cid; + u32 stat_sn; + u32 exp_stat_sn; + int header_digest; + int data_digest; + int fd; +}; + +enum { + key_initial_r2t, + key_immediate_data, + key_max_connections, + key_max_recv_data_length, + key_max_xmit_data_length, + key_max_burst_length, + key_first_burst_length, + key_default_wait_time, + key_default_retain_time, + key_max_outstanding_r2t, + key_data_pdu_inorder, + key_data_sequence_inorder, + key_error_recovery_level, + key_header_digest, + key_data_digest, + key_ofmarker, + key_ifmarker, + key_ofmarkint, + key_ifmarkint, + session_key_last, +}; + +enum { + key_wthreads, + key_target_type, + key_queued_cmnds, + target_key_last, +}; + +enum { + key_session, + key_target, +}; + +struct iscsi_param_info { + u32 tid; + aligned_u64 sid; + + u32 param_type; + u32 partial; + + u32 session_param[session_key_last]; + u32 target_param[target_key_last]; +}; + +enum iet_event_state { + E_CONN_CLOSE, +}; + +struct iet_event { + u32 tid; + aligned_u64 sid; + u32 cid; + u32 state; +}; + +#define DEFAULT_NR_WTHREADS 8 +#define MIN_NR_WTHREADS 1 +#define MAX_NR_WTHREADS 128 + +#define DEFAULT_NR_QUEUED_CMNDS 32 +#define MIN_NR_QUEUED_CMNDS 1 +#define MAX_NR_QUEUED_CMNDS 256 + +#define NETLINK_IET 21 + +#define ADD_TARGET _IOW('i', 0, struct target_info) +#define DEL_TARGET _IOW('i', 1, struct target_info) +#define START_TARGET _IO('i', 2) +#define STOP_TARGET _IO('i', 3) +#define ADD_VOLUME _IOW('i', 4, struct volume_info) +#define DEL_VOLUME _IOW('i', 5, struct volume_info) +#define ADD_SESSION _IOW('i', 6, struct session_info) +#define DEL_SESSION _IOW('i', 7, struct session_info) +#define GET_SESSION_INFO _IOWR('i', 8, struct session_info) +#define ADD_CONN _IOW('i', 9, struct conn_info) +#define DEL_CONN _IOW('i', 10, struct conn_info) +#define GET_CONN_INFO _IOWR('i', 11, struct conn_info) +#define ISCSI_PARAM_SET _IOW('i', 12, struct iscsi_param_info) +#define ISCSI_PARAM_GET _IOWR('i', 13, struct iscsi_param_info) + +#endif --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi_dbg.h +++ linux-2.6.28/ubuntu/iscsitarget/iscsi_dbg.h @@ -0,0 +1,130 @@ +#ifndef ISCSI_DBG_H +#define ISCSI_DBG_H + +#define D_SETUP (1UL << 0) +#define D_EXIT (1UL << 1) +#define D_GENERIC (1UL << 2) +#define D_READ (1UL << 3) +#define D_WRITE (1UL << 4) +#define D_IOD (1UL << 5) +#define D_THREAD (1UL << 6) +#define D_TASK_MGT (1UL << 7) +#define D_IOMODE (1UL << 8) + +#define D_DATA (D_READ | D_WRITE) + +extern unsigned long debug_enable_flags; + +#define PFX "iscsi_trgt: " + +#define dprintk(debug, fmt, args...) do { \ + if ((debug) & debug_enable_flags) { \ + printk(KERN_DEBUG PFX "%s(%d) " fmt, __FUNCTION__,\ + __LINE__, args);\ + } \ +} while (0) + +#define eprintk(fmt, args...) do { \ + printk(KERN_ERR PFX "%s(%d) " fmt, __FUNCTION__, \ + __LINE__, args);\ +} while (0) + +#define iprintk(X...) printk(KERN_INFO PFX X) + +#define assert(p) do { \ + if (!(p)) { \ + printk(KERN_CRIT PFX "BUG at %s:%d assert(%s)\n",\ + __FILE__, __LINE__, #p); \ + dump_stack(); \ + BUG(); \ + } \ +} while (0) + +#ifdef D_IOV +static inline void iscsi_dump_iov(struct msghdr *msg) +{ + int i; + printk(PFX "%p, %d\n", msg->msg_iov, msg->msg_iovlen); + for (i = 0; i < min_t(size_t, msg->msg_iovlen, ISCSI_CONN_IOV_MAX); i++) + printk(PFX "%d: %p,%d\n", i, msg->msg_iov[i].iov_base, + msg->msg_iov[i].iov_len); +} +#else +#define iscsi_dump_iov(x) do {} while (0) +#endif + +#ifdef D_DUMP_PDU +static void iscsi_dump_char(int ch) +{ + static unsigned char text[16]; + static int i = 0; + + if (ch < 0) { + while ((i % 16) != 0) { + printk(" "); + text[i] = ' '; + i++; + if ((i % 16) == 0) + printk(" | %.16s |\n", text); + else if ((i % 4) == 0) + printk(" |"); + } + i = 0; + return; + } + + text[i] = (ch < 0x20 || (ch >= 0x80 && ch <= 0xa0)) ? ' ' : ch; + printk(" %02x", ch); + i++; + if ((i % 16) == 0) { + printk(" | %.16s |\n", text); + i = 0; + } else if ((i % 4) == 0) + printk(" |"); +} + +static inline void iscsi_dump_pdu(struct iscsi_pdu *pdu) +{ + unsigned char *buf; + int i; + + buf = (void *)&pdu->bhs; + printk(PFX "BHS: (%p,%d)\n", buf, sizeof(pdu->bhs)); + for (i = 0; i < sizeof(pdu->bhs); i++) + iscsi_dump_char(*buf++); + iscsi_dump_char(-1); + + buf = (void *)pdu->ahs; + printk(PFX "AHS: (%p,%d)\n", buf, pdu->ahssize); + for (i = 0; i < pdu->ahssize; i++) + iscsi_dump_char(*buf++); + iscsi_dump_char(-1); + + printk(PFX "Data: (%d)\n", pdu->datasize); +} + +#else +#define iscsi_dump_pdu(x) do {} while (0) +#endif + +#define show_param(param)\ +{\ + dprintk(D_SETUP, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",\ + (param)->initial_r2t,\ + (param)->immediate_data,\ + (param)->max_connections,\ + (param)->max_recv_data_length,\ + (param)->max_xmit_data_length,\ + (param)->max_burst_length,\ + (param)->first_burst_length,\ + (param)->default_wait_time,\ + (param)->default_retain_time,\ + (param)->max_outstanding_r2t,\ + (param)->data_pdu_inorder,\ + (param)->data_sequence_inorder,\ + (param)->error_recovery_level,\ + (param)->header_digest,\ + (param)->data_digest);\ +} + +#endif --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi.c +++ linux-2.6.28/ubuntu/iscsitarget/iscsi.c @@ -0,0 +1,1787 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +unsigned long debug_enable_flags; + +static struct kmem_cache *iscsi_cmnd_cache; +static u8 dummy_data[PAGE_SIZE]; + +static int ctr_major; +static char ctr_name[] = "ietctl"; +extern struct file_operations ctr_fops; + +static u32 cmnd_write_size(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); + + if (hdr->flags & ISCSI_CMD_WRITE) + return be32_to_cpu(hdr->data_length); + return 0; +} + +static u32 cmnd_read_size(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *hdr = cmnd_hdr(cmnd); + + if (hdr->flags & ISCSI_CMD_READ) { + struct iscsi_rlength_ahdr *ahdr = + (struct iscsi_rlength_ahdr *)cmnd->pdu.ahs; + + if (!(hdr->flags & ISCSI_CMD_WRITE)) + return be32_to_cpu(hdr->data_length); + if (ahdr && ahdr->ahstype == ISCSI_AHSTYPE_RLENGTH) + return be32_to_cpu(ahdr->read_length); + } + return 0; +} + +static void iscsi_device_queue_cmnd(struct iscsi_cmnd *cmnd) +{ + set_cmnd_waitio(cmnd); + wthread_queue(cmnd); +} + +static void iscsi_scsi_queuecmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_queue *queue = &cmnd->lun->queue; + + dprintk(D_GENERIC, "%p\n", cmnd); + + if ((cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) != ISCSI_CMD_UNTAGGED && + (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) != ISCSI_CMD_SIMPLE) { + cmnd->pdu.bhs.flags &= ~ISCSI_CMD_ATTR_MASK; + cmnd->pdu.bhs.flags |= ISCSI_CMD_UNTAGGED; + } + + spin_lock(&queue->queue_lock); + + set_cmnd_queued(cmnd); + + switch (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) { + case ISCSI_CMD_UNTAGGED: + case ISCSI_CMD_SIMPLE: + if (!list_empty(&queue->wait_list) || queue->ordered_cmnd) + goto pending; + queue->active_cnt++; + break; + + default: + BUG(); + } + spin_unlock(&queue->queue_lock); + + iscsi_device_queue_cmnd(cmnd); + return; + pending: + assert(list_empty(&cmnd->list)); + + list_add_tail(&cmnd->list, &queue->wait_list); + spin_unlock(&queue->queue_lock); + return; +} + +static void iscsi_scsi_dequeuecmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_queue *queue; + + if (!cmnd->lun) + return; + queue = &cmnd->lun->queue; + spin_lock(&queue->queue_lock); + switch (cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK) { + case ISCSI_CMD_UNTAGGED: + case ISCSI_CMD_SIMPLE: + --queue->active_cnt; + break; + case ISCSI_CMD_ORDERED: + case ISCSI_CMD_HEAD_OF_QUEUE: + case ISCSI_CMD_ACA: + BUG(); + default: + /* Should the iscsi_scsi_queuecmnd func reject this ? */ + break; + } + + while (!list_empty(&queue->wait_list)) { + cmnd = list_entry(queue->wait_list.next, struct iscsi_cmnd, list); + switch ((cmnd->pdu.bhs.flags & ISCSI_CMD_ATTR_MASK)) { + case ISCSI_CMD_UNTAGGED: + case ISCSI_CMD_SIMPLE: + list_del_init(&cmnd->list); + queue->active_cnt++; + iscsi_device_queue_cmnd(cmnd); + break; + case ISCSI_CMD_ORDERED: + case ISCSI_CMD_HEAD_OF_QUEUE: + case ISCSI_CMD_ACA: + BUG(); + } + } + + spin_unlock(&queue->queue_lock); + + return; +} + +/** + * create a new command. + * + * iscsi_cmnd_create - + * @conn: ptr to connection (for i/o) + * + * @return ptr to command or NULL + */ + +struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *conn, int req) +{ + struct iscsi_cmnd *cmnd; + + /* TODO: async interface is necessary ? */ + cmnd = kmem_cache_alloc(iscsi_cmnd_cache, GFP_KERNEL|__GFP_NOFAIL); + + memset(cmnd, 0, sizeof(*cmnd)); + INIT_LIST_HEAD(&cmnd->list); + INIT_LIST_HEAD(&cmnd->pdu_list); + INIT_LIST_HEAD(&cmnd->conn_list); + INIT_LIST_HEAD(&cmnd->hash_list); + cmnd->conn = conn; + spin_lock(&conn->list_lock); + atomic_inc(&conn->nr_cmnds); + if (req) + list_add_tail(&cmnd->conn_list, &conn->pdu_list); + spin_unlock(&conn->list_lock); + cmnd->tio = NULL; + + dprintk(D_GENERIC, "%p:%p\n", conn, cmnd); + + return cmnd; +} + +/** + * create a new command used as response. + * + * iscsi_cmnd_create_rsp_cmnd - + * @cmnd: ptr to request command + * + * @return ptr to response command or NULL + */ + +static struct iscsi_cmnd *iscsi_cmnd_create_rsp_cmnd(struct iscsi_cmnd *cmnd, int final) +{ + struct iscsi_cmnd *rsp = cmnd_alloc(cmnd->conn, 0); + + if (final) + set_cmnd_final(rsp); + list_add_tail(&rsp->pdu_list, &cmnd->pdu_list); + rsp->req = cmnd; + return rsp; +} + +static struct iscsi_cmnd *get_rsp_cmnd(struct iscsi_cmnd *req) +{ + return list_entry(req->pdu_list.prev, struct iscsi_cmnd, pdu_list); +} + +static void iscsi_cmnds_init_write(struct list_head *send) +{ + struct iscsi_cmnd *cmnd = list_entry(send->next, struct iscsi_cmnd, list); + struct iscsi_conn *conn = cmnd->conn; + struct list_head *pos, *next; + + spin_lock(&conn->list_lock); + + list_for_each_safe(pos, next, send) { + cmnd = list_entry(pos, struct iscsi_cmnd, list); + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + + list_del_init(&cmnd->list); + assert(conn == cmnd->conn); + list_add_tail(&cmnd->list, &conn->write_list); + } + + spin_unlock(&conn->list_lock); + + nthread_wakeup(conn->session->target); +} + +static void iscsi_cmnd_init_write(struct iscsi_cmnd *cmnd) +{ + LIST_HEAD(head); + + if (!list_empty(&cmnd->list)) { + eprintk("%x %x %x %x %lx %u %u %u %u %u %u %u %d %d\n", + cmnd_itt(cmnd), cmnd_ttt(cmnd), cmnd_opcode(cmnd), + cmnd_scsicode(cmnd), cmnd->flags, cmnd->r2t_sn, + cmnd->r2t_length, cmnd->is_unsolicited_data, + cmnd->target_task_tag, cmnd->outstanding_r2t, + cmnd->hdigest, cmnd->ddigest, + list_empty(&cmnd->pdu_list), list_empty(&cmnd->hash_list)); + + assert(list_empty(&cmnd->list)); + } + list_add(&cmnd->list, &head); + iscsi_cmnds_init_write(&head); +} + +static void do_send_data_rsp(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iscsi_cmnd *data_cmnd; + struct tio *tio = cmnd->tio; + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct iscsi_data_in_hdr *rsp; + u32 pdusize, expsize, scsisize, size, offset, sn; + LIST_HEAD(send); + + dprintk(D_GENERIC, "%p\n", cmnd); + pdusize = conn->session->param.max_xmit_data_length; + expsize = cmnd_read_size(cmnd); + size = min(expsize, tio->size); + offset = 0; + sn = 0; + + while (1) { + data_cmnd = iscsi_cmnd_create_rsp_cmnd(cmnd, size <= pdusize); + tio_get(tio); + data_cmnd->tio = tio; + rsp = (struct iscsi_data_in_hdr *)&data_cmnd->pdu.bhs; + + rsp->opcode = ISCSI_OP_SCSI_DATA_IN; + rsp->itt = req->itt; + rsp->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); + rsp->buffer_offset = offset; + rsp->data_sn = cpu_to_be32(sn); + + if (size <= pdusize) { + data_cmnd->pdu.datasize = size; + rsp->flags = ISCSI_FLG_FINAL | ISCSI_FLG_STATUS; + + scsisize = tio->size; + if (scsisize < expsize) { + rsp->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + size = expsize - scsisize; + } else if (scsisize > expsize) { + rsp->flags |= ISCSI_FLG_RESIDUAL_OVERFLOW; + size = scsisize - expsize; + } else + size = 0; + rsp->residual_count = cpu_to_be32(size); + list_add_tail(&data_cmnd->list, &send); + + break; + } + + data_cmnd->pdu.datasize = pdusize; + + size -= pdusize; + offset += pdusize; + sn++; + + list_add_tail(&data_cmnd->list, &send); + } + + iscsi_cmnds_init_write(&send); +} + +static struct iscsi_cmnd *create_scsi_rsp(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req); + struct iscsi_scsi_rsp_hdr *rsp_hdr; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + + rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_SCSI_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->response = ISCSI_RESPONSE_COMMAND_COMPLETED; + rsp_hdr->cmd_status = SAM_STAT_GOOD; + rsp_hdr->itt = req_hdr->itt; + + return rsp; +} + +static struct iscsi_cmnd *create_sense_rsp(struct iscsi_cmnd *req, + u8 sense_key, u8 asc, u8 ascq) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_rsp_hdr *rsp_hdr; + struct tio *tio; + struct iscsi_sense_data *sense; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + + rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_SCSI_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->response = ISCSI_RESPONSE_COMMAND_COMPLETED; + rsp_hdr->cmd_status = SAM_STAT_CHECK_CONDITION; + rsp_hdr->itt = cmnd_hdr(req)->itt; + + tio = rsp->tio = tio_alloc(1); + sense = (struct iscsi_sense_data *) page_address(tio->pvec[0]); + assert(sense); + clear_page(sense); + sense->length = cpu_to_be16(14); + sense->data[0] = 0xf0; + sense->data[2] = sense_key; + sense->data[7] = 6; // Additional sense length + sense->data[12] = asc; + sense->data[13] = ascq; + + rsp->pdu.datasize = sizeof(struct iscsi_sense_data) + 14; + tio->size = (rsp->pdu.datasize + 3) & -4; + tio->offset = 0; + + return rsp; +} + +void send_scsi_rsp(struct iscsi_cmnd *req, int (*func)(struct iscsi_cmnd *)) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_rsp_hdr *rsp_hdr; + u32 size; + int ret = func(req); + + switch (ret) { + case 0: + case -EBUSY: + rsp = create_scsi_rsp(req); + rsp_hdr = (struct iscsi_scsi_rsp_hdr *) &rsp->pdu.bhs; + if ((size = cmnd_read_size(req)) != 0) { + rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + rsp_hdr->residual_count = cpu_to_be32(size); + } + if (ret == -EBUSY) + rsp_hdr->cmd_status = SAM_STAT_RESERVATION_CONFLICT; + break; + case -EIO: + /* Medium Error/Write Fault */ + rsp = create_sense_rsp(req, MEDIUM_ERROR, 0x03, 0x0); + break; + default: + rsp = create_sense_rsp(req, ILLEGAL_REQUEST, 0x24, 0x0); + } + iscsi_cmnd_init_write(rsp); +} + +void send_data_rsp(struct iscsi_cmnd *req, int (*func)(struct iscsi_cmnd *)) +{ + struct iscsi_cmnd *rsp; + + switch (func(req)) { + case 0: + do_send_data_rsp(req); + return; + case -EIO: + /* Medium Error/Unrecovered Read Error */ + rsp = create_sense_rsp(req, MEDIUM_ERROR, 0x11, 0x0); + break; + default: + rsp = create_sense_rsp(req, ILLEGAL_REQUEST, 0x24, 0x0); + } + iscsi_cmnd_init_write(rsp); +} + +/** + * Free a command. + * Also frees the additional header. + * + * iscsi_cmnd_remove - + * @cmnd: ptr to command + */ + +static void iscsi_cmnd_remove(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn; + + if (!cmnd) + return; + dprintk(D_GENERIC, "%p\n", cmnd); + conn = cmnd->conn; + kfree(cmnd->pdu.ahs); + + if (!list_empty(&cmnd->list)) { + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + + eprintk("cmnd %p still on some list?, %x, %x, %x, %x, %x, %x, %x %lx\n", + cmnd, req->opcode, req->scb[0], req->flags, req->itt, + be32_to_cpu(req->data_length), + req->cmd_sn, be32_to_cpu(cmnd->pdu.datasize), + conn->state); + + if (cmnd->req) { + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd->req); + eprintk("%p %x %u\n", req, req->opcode, req->scb[0]); + } + dump_stack(); + BUG(); + } + list_del(&cmnd->list); + spin_lock(&conn->list_lock); + atomic_dec(&conn->nr_cmnds); + list_del(&cmnd->conn_list); + spin_unlock(&conn->list_lock); + + if (cmnd->tio) + tio_put(cmnd->tio); + + kmem_cache_free(iscsi_cmnd_cache, cmnd); +} + +static void cmnd_skip_pdu(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct tio *tio = cmnd->tio; + char *addr; + u32 size; + int i; + + eprintk("%x %x %x %u\n", cmnd_itt(cmnd), cmnd_opcode(cmnd), + cmnd_hdr(cmnd)->scb[0], cmnd->pdu.datasize); + + if (!(size = cmnd->pdu.datasize)) + return; + + if (tio) + assert(tio->pg_cnt > 0); + else + tio = cmnd->tio = tio_alloc(1); + + addr = page_address(tio->pvec[0]); + assert(addr); + size = (size + 3) & -4; + conn->read_size = size; + for (i = 0; size > PAGE_CACHE_SIZE; i++, size -= PAGE_CACHE_SIZE) { + assert(i < ISCSI_CONN_IOV_MAX); + conn->read_iov[i].iov_base = addr; + conn->read_iov[i].iov_len = PAGE_CACHE_SIZE; + } + conn->read_iov[i].iov_base = addr; + conn->read_iov[i].iov_len = size; + conn->read_msg.msg_iov = conn->read_iov; + conn->read_msg.msg_iovlen = ++i; +} + +static void iscsi_cmnd_reject(struct iscsi_cmnd *req, int reason) +{ + struct iscsi_cmnd *rsp; + struct iscsi_reject_hdr *rsp_hdr; + struct tio *tio; + char *addr; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + rsp_hdr = (struct iscsi_reject_hdr *)&rsp->pdu.bhs; + + rsp_hdr->opcode = ISCSI_OP_REJECT; + rsp_hdr->ffffffff = ISCSI_RESERVED_TAG; + rsp_hdr->reason = reason; + + rsp->tio = tio = tio_alloc(1); + addr = page_address(tio->pvec[0]); + clear_page(addr); + memcpy(addr, &req->pdu.bhs, sizeof(struct iscsi_hdr)); + tio->size = rsp->pdu.datasize = sizeof(struct iscsi_hdr); + cmnd_skip_pdu(req); + + req->pdu.bhs.opcode = ISCSI_OP_PDU_REJECT; +} + +static void cmnd_set_sn(struct iscsi_cmnd *cmnd, int set_stat_sn) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iscsi_session *sess = conn->session; + + if (set_stat_sn) + cmnd->pdu.bhs.sn = cpu_to_be32(conn->stat_sn++); + cmnd->pdu.bhs.exp_sn = cpu_to_be32(sess->exp_cmd_sn); + cmnd->pdu.bhs.max_sn = cpu_to_be32(sess->exp_cmd_sn + sess->max_queued_cmnds); +} + +static void update_stat_sn(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + u32 exp_stat_sn; + + cmnd->pdu.bhs.exp_sn = exp_stat_sn = be32_to_cpu(cmnd->pdu.bhs.exp_sn); + dprintk(D_GENERIC, "%x,%x\n", cmnd_opcode(cmnd), exp_stat_sn); + if ((int)(exp_stat_sn - conn->exp_stat_sn) > 0 && + (int)(exp_stat_sn - conn->stat_sn) <= 0) { + // free pdu resources + cmnd->conn->exp_stat_sn = exp_stat_sn; + } +} + +static int check_cmd_sn(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + u32 cmd_sn; + + cmnd->pdu.bhs.sn = cmd_sn = be32_to_cpu(cmnd->pdu.bhs.sn); + dprintk(D_GENERIC, "%d(%d)\n", cmd_sn, session->exp_cmd_sn); + if ((s32)(cmd_sn - session->exp_cmd_sn) >= 0) + return 0; + eprintk("sequence error (%x,%x)\n", cmd_sn, session->exp_cmd_sn); + return -ISCSI_REASON_PROTOCOL_ERROR; +} + +static struct iscsi_cmnd *__cmnd_find_hash(struct iscsi_session *session, u32 itt, u32 ttt) +{ + struct list_head *head; + struct iscsi_cmnd *cmnd; + + head = &session->cmnd_hash[cmnd_hashfn(itt)]; + + list_for_each_entry(cmnd, head, hash_list) { + if (cmnd->pdu.bhs.itt == itt) { + if ((ttt != ISCSI_RESERVED_TAG) && (ttt != cmnd->target_task_tag)) + continue; + return cmnd; + } + } + + return NULL; +} + +static struct iscsi_cmnd *cmnd_find_hash(struct iscsi_session *session, u32 itt, u32 ttt) +{ + struct iscsi_cmnd *cmnd; + + spin_lock(&session->cmnd_hash_lock); + + cmnd = __cmnd_find_hash(session, itt, ttt); + + spin_unlock(&session->cmnd_hash_lock); + + return cmnd; +} + +static int cmnd_insert_hash(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + struct iscsi_cmnd *tmp; + struct list_head *head; + int err = 0; + u32 itt = cmnd->pdu.bhs.itt; + + dprintk(D_GENERIC, "%p:%x\n", cmnd, itt); + if (itt == ISCSI_RESERVED_TAG) { + err = -ISCSI_REASON_PROTOCOL_ERROR; + goto out; + } + + head = &session->cmnd_hash[cmnd_hashfn(cmnd->pdu.bhs.itt)]; + + spin_lock(&session->cmnd_hash_lock); + + tmp = __cmnd_find_hash(session, itt, ISCSI_RESERVED_TAG); + if (!tmp) { + list_add_tail(&cmnd->hash_list, head); + set_cmnd_hashed(cmnd); + } else + err = -ISCSI_REASON_TASK_IN_PROGRESS; + + spin_unlock(&session->cmnd_hash_lock); + + if (!err) { + update_stat_sn(cmnd); + err = check_cmd_sn(cmnd); + } + +out: + return err; +} + +static void __cmnd_remove_hash(struct iscsi_cmnd *cmnd) +{ + list_del(&cmnd->hash_list); +} + +static void cmnd_remove_hash(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + struct iscsi_cmnd *tmp; + + spin_lock(&session->cmnd_hash_lock); + + tmp = __cmnd_find_hash(session, cmnd->pdu.bhs.itt, ISCSI_RESERVED_TAG); + + if (tmp && tmp == cmnd) + __cmnd_remove_hash(tmp); + else + eprintk("%p:%x not found\n", cmnd, cmnd_itt(cmnd)); + + spin_unlock(&session->cmnd_hash_lock); +} + +static void cmnd_skip_data(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_scsi_rsp_hdr *rsp_hdr; + u32 size; + + rsp = get_rsp_cmnd(req); + rsp_hdr = (struct iscsi_scsi_rsp_hdr *)&rsp->pdu.bhs; + if (cmnd_opcode(rsp) != ISCSI_OP_SCSI_RSP) { + eprintk("unexpected response command %u\n", cmnd_opcode(rsp)); + return; + } + + size = cmnd_write_size(req); + if (size) { + rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + rsp_hdr->residual_count = cpu_to_be32(size); + } + size = cmnd_read_size(req); + if (size) { + if (cmnd_hdr(req)->flags & ISCSI_CMD_WRITE) { + rsp_hdr->flags |= ISCSI_FLG_BIRESIDUAL_UNDERFLOW; + rsp_hdr->bi_residual_count = cpu_to_be32(size); + } else { + rsp_hdr->flags |= ISCSI_FLG_RESIDUAL_UNDERFLOW; + rsp_hdr->residual_count = cpu_to_be32(size); + } + } + req->pdu.bhs.opcode = + (req->pdu.bhs.opcode & ~ISCSI_OPCODE_MASK) | ISCSI_OP_SCSI_REJECT; + + cmnd_skip_pdu(req); +} + +static int cmnd_recv_pdu(struct iscsi_conn *conn, struct tio *tio, u32 offset, u32 size) +{ + int idx, i; + char *addr; + + dprintk(D_GENERIC, "%p %u,%u\n", tio, offset, size); + offset += tio->offset; + + if (!(offset < tio->offset + tio->size) || + !(offset + size <= tio->offset + tio->size)) { + eprintk("%u %u %u %u", offset, size, tio->offset, tio->size); + return -EIO; + } + assert(offset < tio->offset + tio->size); + assert(offset + size <= tio->offset + tio->size); + + idx = offset >> PAGE_CACHE_SHIFT; + offset &= ~PAGE_CACHE_MASK; + + conn->read_msg.msg_iov = conn->read_iov; + conn->read_size = size = (size + 3) & -4; + conn->read_overflow = 0; + + i = 0; + while (1) { + assert(tio->pvec[idx]); + addr = page_address(tio->pvec[idx]); + assert(addr); + conn->read_iov[i].iov_base = addr + offset; + if (offset + size <= PAGE_CACHE_SIZE) { + conn->read_iov[i].iov_len = size; + conn->read_msg.msg_iovlen = ++i; + break; + } + conn->read_iov[i].iov_len = PAGE_CACHE_SIZE - offset; + size -= conn->read_iov[i].iov_len; + offset = 0; + if (++i >= ISCSI_CONN_IOV_MAX) { + conn->read_msg.msg_iovlen = i; + conn->read_overflow = size; + conn->read_size -= size; + break; + } + + idx++; + } + + return 0; +} + +static void set_offset_and_length(struct iet_volume *lu, u8 *cmd, loff_t *off, u32 *len) +{ + assert(lu); + + switch (cmd[0]) { + case READ_6: + case WRITE_6: + *off = ((cmd[1] & 0x1f) << 16) + (cmd[2] << 8) + cmd[3]; + *len = cmd[4]; + if (!*len) + *len = 256; + break; + case READ_10: + case WRITE_10: + case WRITE_VERIFY: + *off = (u32)cmd[2] << 24 | (u32)cmd[3] << 16 | + (u32)cmd[4] << 8 | (u32)cmd[5]; + *len = (cmd[7] << 8) + cmd[8]; + break; + case READ_16: + case WRITE_16: + *off = (u64)cmd[2] << 56 | (u64)cmd[3] << 48 | + (u64)cmd[4] << 40 | (u64)cmd[5] << 32 | + (u64)cmd[6] << 24 | (u64)cmd[7] << 16 | + (u64)cmd[8] << 8 | (u64)cmd[9]; + *len = (u32)cmd[10] << 24 | (u32)cmd[11] << 16 | + (u32)cmd[12] << 8 | (u32)cmd[13]; + break; + default: + BUG(); + } + + *off <<= lu->blk_shift; + *len <<= lu->blk_shift; +} + +static u32 translate_lun(u16 * data) +{ + u8 *p = (u8 *) data; + u32 lun = ~0U; + + switch (*p >> 6) { + case 0: + lun = p[1]; + break; + case 1: + lun = (0x3f & p[0]) << 8 | p[1]; + break; + case 2: + case 3: + default: + eprintk("%u %u %u %u\n", data[0], data[1], data[2], data[3]); + break; + } + + return lun; +} + +static void send_r2t(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_r2t_hdr *rsp_hdr; + u32 length, offset, burst; + LIST_HEAD(send); + + length = req->r2t_length; + burst = req->conn->session->param.max_burst_length; + offset = be32_to_cpu(cmnd_hdr(req)->data_length) - length; + + do { + rsp = iscsi_cmnd_create_rsp_cmnd(req, 0); + rsp->pdu.bhs.ttt = req->target_task_tag; + + rsp_hdr = (struct iscsi_r2t_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_R2T; + rsp_hdr->flags = ISCSI_FLG_FINAL; + memcpy(rsp_hdr->lun, cmnd_hdr(req)->lun, 8); + rsp_hdr->itt = cmnd_hdr(req)->itt; + rsp_hdr->r2t_sn = cpu_to_be32(req->r2t_sn++); + rsp_hdr->buffer_offset = cpu_to_be32(offset); + if (length > burst) { + rsp_hdr->data_length = cpu_to_be32(burst); + length -= burst; + offset += burst; + } else { + rsp_hdr->data_length = cpu_to_be32(length); + length = 0; + } + + dprintk(D_WRITE, "%x %u %u %u %u\n", cmnd_itt(req), + be32_to_cpu(rsp_hdr->data_length), + be32_to_cpu(rsp_hdr->buffer_offset), + be32_to_cpu(rsp_hdr->r2t_sn), req->outstanding_r2t); + + list_add_tail(&rsp->list, &send); + + if (++req->outstanding_r2t >= req->conn->session->param.max_outstanding_r2t) + break; + + } while (length); + + iscsi_cmnds_init_write(&send); +} + +static void scsi_cmnd_exec(struct iscsi_cmnd *cmnd) +{ + if (cmnd->r2t_length) { + if (!cmnd->is_unsolicited_data) + send_r2t(cmnd); + } else { + if (cmnd->lun) { + iscsi_scsi_queuecmnd(cmnd); + } else { + iscsi_device_queue_cmnd(cmnd); + } + } +} + +static int noop_out_start(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + u32 size, tmp; + int i, err = 0; + + if (cmnd_ttt(cmnd) != cpu_to_be32(ISCSI_RESERVED_TAG)) { + /* + * We don't request a NOP-Out by sending a NOP-In. + * See 10.18.2 in the draft 20. + */ + eprintk("initiator bug %x\n", cmnd_itt(cmnd)); + err = -ISCSI_REASON_PROTOCOL_ERROR; + goto out; + } + + if (cmnd_itt(cmnd) == cpu_to_be32(ISCSI_RESERVED_TAG)) { + if (!(cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE)) + eprintk("%s\n","initiator bug!"); + update_stat_sn(cmnd); + err = check_cmd_sn(cmnd); + if (err) + goto out; + } else if ((err = cmnd_insert_hash(cmnd)) < 0) { + eprintk("ignore this request %x\n", cmnd_itt(cmnd)); + goto out; + } + + if ((size = cmnd->pdu.datasize)) { + size = (size + 3) & -4; + conn->read_msg.msg_iov = conn->read_iov; + if (cmnd->pdu.bhs.itt != cpu_to_be32(ISCSI_RESERVED_TAG)) { + struct tio *tio; + int pg_cnt = get_pgcnt(size, 0); + + assert(pg_cnt < ISCSI_CONN_IOV_MAX); + cmnd->tio = tio = tio_alloc(pg_cnt); + tio_set(tio, size, 0); + + for (i = 0; i < pg_cnt; i++) { + conn->read_iov[i].iov_base + = page_address(tio->pvec[i]); + tmp = min_t(u32, size, PAGE_CACHE_SIZE); + conn->read_iov[i].iov_len = tmp; + conn->read_size += tmp; + size -= tmp; + } + } else { + for (i = 0; i < ISCSI_CONN_IOV_MAX; i++) { + conn->read_iov[i].iov_base = dummy_data; + tmp = min_t(u32, size, sizeof(dummy_data)); + conn->read_iov[i].iov_len = tmp; + conn->read_size += tmp; + size -= tmp; + } + } + assert(!size); + conn->read_overflow = size; + conn->read_msg.msg_iovlen = i; + } + +out: + return err; +} + +static u32 get_next_ttt(struct iscsi_session *session) +{ + u32 ttt; + + if (session->next_ttt == ISCSI_RESERVED_TAG) + session->next_ttt++; + ttt = session->next_ttt++; + + return cpu_to_be32(ttt); +} + +static void scsi_cmnd_start(struct iscsi_conn *conn, struct iscsi_cmnd *req) +{ + struct iscsi_scsi_cmd_hdr *req_hdr = cmnd_hdr(req); + + dprintk(D_GENERIC, "scsi command: %02x\n", req_hdr->scb[0]); + + req->lun = volume_get(conn->session->target, translate_lun(req_hdr->lun)); + if (!req->lun) { + switch (req_hdr->scb[0]) { + case INQUIRY: + case REPORT_LUNS: + break; + default: + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + create_sense_rsp(req, ILLEGAL_REQUEST, 0x25, 0x0); + cmnd_skip_data(req); + goto out; + } + } else + set_cmnd_lunit(req); + + switch (req_hdr->scb[0]) { + case SERVICE_ACTION_IN: + if ((req_hdr->scb[1] & 0x1f) != 0x10) + goto error; + case INQUIRY: + case REPORT_LUNS: + case TEST_UNIT_READY: + case SYNCHRONIZE_CACHE: + case VERIFY: + case VERIFY_16: + case START_STOP: + case READ_CAPACITY: + case MODE_SENSE: + case REQUEST_SENSE: + case RESERVE: + case RELEASE: + { + if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) { + /* unexpected unsolicited data */ + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); + cmnd_skip_data(req); + } + break; + } + case READ_6: + case READ_10: + case READ_16: + { + loff_t offset; + u32 length; + + if (!(req_hdr->flags & ISCSI_CMD_FINAL) || req->pdu.datasize) { + /* unexpected unsolicited data */ + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + create_sense_rsp(req, ABORTED_COMMAND, 0xc, 0xc); + cmnd_skip_data(req); + break; + } + + set_offset_and_length(req->lun, req_hdr->scb, &offset, &length); + req->tio = tio_alloc(get_pgcnt(length, offset)); + tio_set(req->tio, length, offset); + break; + } + case WRITE_6: + case WRITE_10: + case WRITE_16: + case WRITE_VERIFY: + { + struct iscsi_sess_param *param = &conn->session->param; + loff_t offset; + u32 length; + + req->r2t_length = be32_to_cpu(req_hdr->data_length) - req->pdu.datasize; + req->is_unsolicited_data = !(req_hdr->flags & ISCSI_CMD_FINAL); + req->target_task_tag = get_next_ttt(conn->session); + + if (LUReadonly(req->lun)) { + create_sense_rsp(req, DATA_PROTECT, 0x27, 0x0); + cmnd_skip_data(req); + break; + } + + if (!param->immediate_data && req->pdu.datasize) + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + + if (param->initial_r2t && !(req_hdr->flags & ISCSI_CMD_FINAL)) + eprintk("%x %x\n", cmnd_itt(req), req_hdr->scb[0]); + + if (req_hdr->scb[0] == WRITE_VERIFY && req_hdr->scb[1] & 0x02) + eprintk("Verification is ignored %x\n", cmnd_itt(req)); + + set_offset_and_length(req->lun, req_hdr->scb, &offset, &length); + if (cmnd_write_size(req) != length) + eprintk("%x %u %u\n", cmnd_itt(req), cmnd_write_size(req), length); + + req->tio = tio_alloc(get_pgcnt(length, offset)); + tio_set(req->tio, length, offset); + + if (req->pdu.datasize) { + if (cmnd_recv_pdu(conn, req->tio, 0, req->pdu.datasize) < 0) + assert(0); + } + break; + } + error: + default: + eprintk("Unsupported %x\n", req_hdr->scb[0]); + create_sense_rsp(req, ILLEGAL_REQUEST, 0x20, 0x0); + cmnd_skip_data(req); + break; + } + +out: + return; +} + +static void data_out_start(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs; + struct iscsi_cmnd *scsi_cmnd = NULL; + u32 offset = be32_to_cpu(req->buffer_offset); + + update_stat_sn(cmnd); + + cmnd->req = scsi_cmnd = cmnd_find_hash(conn->session, req->itt, req->ttt); + if (!scsi_cmnd) { + eprintk("unable to find scsi task %x %x\n", + cmnd_itt(cmnd), cmnd_ttt(cmnd)); + goto skip_data; + } + + if (scsi_cmnd->r2t_length < cmnd->pdu.datasize) { + eprintk("invalid data len %x %u %u\n", + cmnd_itt(scsi_cmnd), cmnd->pdu.datasize, scsi_cmnd->r2t_length); + goto skip_data; + } + + if (scsi_cmnd->r2t_length + offset != cmnd_write_size(scsi_cmnd)) { + eprintk("%x %u %u %u\n", cmnd_itt(scsi_cmnd), scsi_cmnd->r2t_length, + offset, cmnd_write_size(scsi_cmnd)); + goto skip_data; + } + + scsi_cmnd->r2t_length -= cmnd->pdu.datasize; + + if (req->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) { + /* unsolicited burst data */ + if (scsi_cmnd->pdu.bhs.flags & ISCSI_FLG_FINAL) { + eprintk("unexpected data from %x %x\n", + cmnd_itt(cmnd), cmnd_ttt(cmnd)); + goto skip_data; + } + } + + dprintk(D_WRITE, "%u %p %p %p %u %u\n", req->ttt, cmnd, scsi_cmnd, + scsi_cmnd->tio, offset, cmnd->pdu.datasize); + + if (cmnd_recv_pdu(conn, scsi_cmnd->tio, offset, cmnd->pdu.datasize) < 0) + goto skip_data; + return; + +skip_data: + cmnd->pdu.bhs.opcode = ISCSI_OP_DATA_REJECT; + cmnd_skip_pdu(cmnd); + return; +} + +static void data_out_end(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *) &cmnd->pdu.bhs; + struct iscsi_cmnd *scsi_cmnd; + u32 offset; + + assert(cmnd); + scsi_cmnd = cmnd->req; + assert(scsi_cmnd); + + if (conn->read_overflow) { + eprintk("%x %u\n", cmnd_itt(cmnd), conn->read_overflow); + assert(scsi_cmnd->tio); + offset = be32_to_cpu(req->buffer_offset); + offset += cmnd->pdu.datasize - conn->read_overflow; + if (cmnd_recv_pdu(conn, scsi_cmnd->tio, offset, conn->read_overflow) < 0) + assert(0); + return; + } + + if (req->ttt == cpu_to_be32(ISCSI_RESERVED_TAG)) { + if (req->flags & ISCSI_FLG_FINAL) { + scsi_cmnd->is_unsolicited_data = 0; + if (!cmnd_pending(scsi_cmnd)) + scsi_cmnd_exec(scsi_cmnd); + } + } else { + /* TODO : proper error handling */ + if (!(req->flags & ISCSI_FLG_FINAL) && scsi_cmnd->r2t_length == 0) + eprintk("initiator error %x\n", cmnd_itt(scsi_cmnd)); + + if (!(req->flags & ISCSI_FLG_FINAL)) + goto out; + + scsi_cmnd->outstanding_r2t--; + + if (scsi_cmnd->r2t_length == 0) + assert(list_empty(&scsi_cmnd->pdu_list)); + + scsi_cmnd_exec(scsi_cmnd); + } + +out: + iscsi_cmnd_remove(cmnd); + return; +} + +static int __cmnd_abort(struct iscsi_cmnd *cmnd) +{ + if (cmnd_waitio(cmnd)) + return -ISCSI_RESPONSE_UNKNOWN_TASK; + + if (cmnd->conn->read_cmnd != cmnd) + cmnd_release(cmnd, 1); + else if (cmnd_rxstart(cmnd)) + set_cmnd_tmfabort(cmnd); + else + return -ISCSI_RESPONSE_UNKNOWN_TASK; + + return 0; +} + +static int cmnd_abort(struct iscsi_session *session, u32 itt) +{ + struct iscsi_cmnd *cmnd; + int err = -ISCSI_RESPONSE_UNKNOWN_TASK; + + if ((cmnd = cmnd_find_hash(session, itt, ISCSI_RESERVED_TAG))) { + eprintk("%x %x %x %u %u %u %u\n", cmnd_itt(cmnd), cmnd_opcode(cmnd), + cmnd->r2t_length, cmnd_scsicode(cmnd), + cmnd_write_size(cmnd), cmnd->is_unsolicited_data, + cmnd->outstanding_r2t); + err = __cmnd_abort(cmnd); + } + + return err; +} + +static int target_reset(struct iscsi_cmnd *req, u32 lun, int all) +{ + struct iscsi_target *target = req->conn->session->target; + struct iscsi_session *session; + struct iscsi_conn *conn; + struct iscsi_cmnd *cmnd, *tmp; + struct iet_volume *volumes; + + list_for_each_entry(session, &target->session_list, list) { + list_for_each_entry(conn, &session->conn_list, list) { + list_for_each_entry_safe(cmnd, tmp, &conn->pdu_list, conn_list) { + if (cmnd == req) + continue; + + if (all) + __cmnd_abort(cmnd); + else if (translate_lun(cmnd_hdr(cmnd)->lun) == lun) + __cmnd_abort(cmnd); + } + } + } + + list_for_each_entry(volumes, &target->volumes, list) + if (all || volumes->lun == lun) + /* force release */ + volume_release(volumes, 0, 1); + + return 0; +} + +static void task_set_abort(struct iscsi_cmnd *req) +{ + struct iscsi_session *session = req->conn->session; + struct iscsi_conn *conn; + struct iscsi_cmnd *cmnd, *tmp; + + list_for_each_entry(conn, &session->conn_list, list) { + list_for_each_entry_safe(cmnd, tmp, &conn->pdu_list, conn_list) { + if (cmnd != req) + __cmnd_abort(cmnd); + } + } +} + +static inline char *tmf_desc(int fun) +{ + static char *tmf_desc[] = { + "Unknown Function", + "Abort Task", + "Abort Task Set", + "Clear ACA", + "Clear Task Set", + "Logical Unit Reset", + "Target Warm Reset", + "Target Cold Reset", + "Task Reassign", + }; + + if ((fun < ISCSI_FUNCTION_ABORT_TASK) || + (fun > ISCSI_FUNCTION_TASK_REASSIGN)) + fun = 0; + + return tmf_desc[fun]; +} + +static inline char *rsp_desc(int rsp) +{ + static char *rsp_desc[] = { + "Function Complete", + "Unknown Task", + "Unknown LUN", + "Task Allegiant", + "Failover Unsupported", + "Function Unsupported", + "No Authorization", + "Function Rejected", + "Unknown Response", + }; + + if (((rsp < ISCSI_RESPONSE_FUNCTION_COMPLETE) || + (rsp > ISCSI_RESPONSE_NO_AUTHORIZATION)) && + (rsp != ISCSI_RESPONSE_FUNCTION_REJECTED)) + rsp = 8; + else if (rsp == ISCSI_RESPONSE_FUNCTION_REJECTED) + rsp = 7; + + return rsp_desc[rsp]; +} + +static void execute_task_management(struct iscsi_cmnd *req) +{ + struct iscsi_conn *conn = req->conn; + struct iscsi_session *session = conn->session; + struct iscsi_target *target = session->target; + struct iscsi_cmnd *rsp; + struct iscsi_task_mgt_hdr *req_hdr = (struct iscsi_task_mgt_hdr *)&req->pdu.bhs; + struct iscsi_task_rsp_hdr *rsp_hdr; + u32 lun; + int err, function = req_hdr->function & ISCSI_FUNCTION_MASK; + + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + rsp_hdr = (struct iscsi_task_rsp_hdr *)&rsp->pdu.bhs; + + rsp_hdr->opcode = ISCSI_OP_SCSI_TASK_MGT_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->itt = req_hdr->itt; + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_COMPLETE; + + switch (function) { + case ISCSI_FUNCTION_ABORT_TASK: + case ISCSI_FUNCTION_ABORT_TASK_SET: + case ISCSI_FUNCTION_CLEAR_ACA: + case ISCSI_FUNCTION_CLEAR_TASK_SET: + case ISCSI_FUNCTION_LOGICAL_UNIT_RESET: + lun = translate_lun(req_hdr->lun); + if (!volume_lookup(target, lun)) { + rsp_hdr->response = ISCSI_RESPONSE_UNKNOWN_LUN; + goto out; + } + } + + switch (function) { + case ISCSI_FUNCTION_ABORT_TASK: + if ((err = cmnd_abort(conn->session, req_hdr->rtt)) < 0) + rsp_hdr->response = -err; + break; + case ISCSI_FUNCTION_ABORT_TASK_SET: + task_set_abort(req); + break; + case ISCSI_FUNCTION_CLEAR_ACA: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; + break; + case ISCSI_FUNCTION_CLEAR_TASK_SET: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; + break; + case ISCSI_FUNCTION_LOGICAL_UNIT_RESET: + target_reset(req, translate_lun(req_hdr->lun), 0); + break; + case ISCSI_FUNCTION_TARGET_WARM_RESET: + case ISCSI_FUNCTION_TARGET_COLD_RESET: + target_reset(req, 0, 1); + if (function == ISCSI_FUNCTION_TARGET_COLD_RESET) + set_cmnd_close(rsp); + break; + case ISCSI_FUNCTION_TASK_REASSIGN: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_UNSUPPORTED; + break; + default: + rsp_hdr->response = ISCSI_RESPONSE_FUNCTION_REJECTED; + break; + } +out: + iprintk("%s (%02x) issued on tid:%d lun:%d by sid:%llu (%s)\n", + tmf_desc(function), function, target->tid, + translate_lun(req_hdr->lun), session->sid, + rsp_desc(rsp_hdr->response)); + + iscsi_cmnd_init_write(rsp); +} + +static void noop_out_exec(struct iscsi_cmnd *req) +{ + struct iscsi_cmnd *rsp; + struct iscsi_nop_in_hdr *rsp_hdr; + + if (cmnd_itt(req) != cpu_to_be32(ISCSI_RESERVED_TAG)) { + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + + rsp_hdr = (struct iscsi_nop_in_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_NOOP_IN; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->itt = req->pdu.bhs.itt; + rsp_hdr->ttt = cpu_to_be32(ISCSI_RESERVED_TAG); + + if (req->pdu.datasize) + assert(req->tio); + else + assert(!req->tio); + + if (req->tio) { + tio_get(req->tio); + rsp->tio = req->tio; + } + + assert(get_pgcnt(req->pdu.datasize, 0) < ISCSI_CONN_IOV_MAX); + rsp->pdu.datasize = req->pdu.datasize; + iscsi_cmnd_init_write(rsp); + } else + iscsi_cmnd_remove(req); +} + +static void logout_exec(struct iscsi_cmnd *req) +{ + struct iscsi_logout_req_hdr *req_hdr; + struct iscsi_cmnd *rsp; + struct iscsi_logout_rsp_hdr *rsp_hdr; + + req_hdr = (struct iscsi_logout_req_hdr *)&req->pdu.bhs; + rsp = iscsi_cmnd_create_rsp_cmnd(req, 1); + rsp_hdr = (struct iscsi_logout_rsp_hdr *)&rsp->pdu.bhs; + rsp_hdr->opcode = ISCSI_OP_LOGOUT_RSP; + rsp_hdr->flags = ISCSI_FLG_FINAL; + rsp_hdr->itt = req_hdr->itt; + set_cmnd_close(rsp); + iscsi_cmnd_init_write(rsp); +} + +static void iscsi_cmnd_exec(struct iscsi_cmnd *cmnd) +{ + dprintk(D_GENERIC, "%p,%x,%u\n", cmnd, cmnd_opcode(cmnd), cmnd->pdu.bhs.sn); + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_OUT: + noop_out_exec(cmnd); + break; + case ISCSI_OP_SCSI_CMD: + scsi_cmnd_exec(cmnd); + break; + case ISCSI_OP_SCSI_TASK_MGT_MSG: + execute_task_management(cmnd); + break; + case ISCSI_OP_LOGOUT_CMD: + logout_exec(cmnd); + break; + case ISCSI_OP_SCSI_REJECT: + iscsi_cmnd_init_write(get_rsp_cmnd(cmnd)); + break; + case ISCSI_OP_TEXT_CMD: + case ISCSI_OP_SNACK_CMD: + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + break; + } +} + +static void __cmnd_send_pdu(struct iscsi_conn *conn, struct tio *tio, u32 offset, u32 size) +{ + dprintk(D_GENERIC, "%p %u,%u\n", tio, offset, size); + offset += tio->offset; + + assert(offset <= tio->offset + tio->size); + assert(offset + size <= tio->offset + tio->size); + + conn->write_tcmnd = tio; + conn->write_offset = offset; + conn->write_size += size; +} + +static void cmnd_send_pdu(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + u32 size; + struct tio *tio; + + if (!cmnd->pdu.datasize) + return; + + size = (cmnd->pdu.datasize + 3) & -4; + tio = cmnd->tio; + assert(tio); + assert(tio->size == size); + __cmnd_send_pdu(conn, tio, 0, size); +} + +static void set_cork(struct socket *sock, int on) +{ + int opt = on; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(get_ds()); + sock->ops->setsockopt(sock, SOL_TCP, TCP_CORK, (void *)&opt, sizeof(opt)); + set_fs(oldfs); +} + +void cmnd_release(struct iscsi_cmnd *cmnd, int force) +{ + struct iscsi_cmnd *req, *rsp; + int is_last = 0; + + if (!cmnd) + return; + +/* eprintk("%x %lx %d\n", cmnd_opcode(cmnd), cmnd->flags, force); */ + + req = cmnd->req; + is_last = cmnd_final(cmnd); + + if (force) { + while (!list_empty(&cmnd->pdu_list)) { + rsp = list_entry(cmnd->pdu_list.next, struct iscsi_cmnd, pdu_list); + list_del_init(&rsp->list); + list_del(&rsp->pdu_list); + iscsi_cmnd_remove(rsp); + } + list_del_init(&cmnd->list); + } else + if (cmnd_queued(cmnd)) + iscsi_scsi_dequeuecmnd(cmnd); + + if (cmnd_hashed(cmnd)) + cmnd_remove_hash(cmnd); + + if (cmnd_lunit(cmnd)) { + assert(cmnd->lun); + volume_put(cmnd->lun); + } + + list_del_init(&cmnd->pdu_list); + iscsi_cmnd_remove(cmnd); + + if (is_last) { + assert(!force); + assert(req); + cmnd_release(req, 0); + } + + return; +} + +void cmnd_tx_start(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iovec *iop; + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + assert(cmnd); + iscsi_cmnd_set_length(&cmnd->pdu); + + set_cork(conn->sock, 1); + + conn->write_iop = iop = conn->write_iov; + iop->iov_base = &cmnd->pdu.bhs; + iop->iov_len = sizeof(cmnd->pdu.bhs); + iop++; + conn->write_size = sizeof(cmnd->pdu.bhs); + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_IN: + cmnd_set_sn(cmnd, 1); + cmnd_send_pdu(conn, cmnd); + break; + case ISCSI_OP_SCSI_RSP: + cmnd_set_sn(cmnd, 1); + cmnd_send_pdu(conn, cmnd); + break; + case ISCSI_OP_SCSI_TASK_MGT_RSP: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_TEXT_RSP: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_SCSI_DATA_IN: + { + struct iscsi_data_in_hdr *rsp = (struct iscsi_data_in_hdr *)&cmnd->pdu.bhs; + u32 offset; + + cmnd_set_sn(cmnd, (rsp->flags & ISCSI_FLG_FINAL) ? 1 : 0); + offset = rsp->buffer_offset; + rsp->buffer_offset = cpu_to_be32(offset); + __cmnd_send_pdu(conn, cmnd->tio, offset, cmnd->pdu.datasize); + break; + } + case ISCSI_OP_LOGOUT_RSP: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_R2T: + cmnd_set_sn(cmnd, 0); + cmnd->pdu.bhs.sn = cpu_to_be32(conn->stat_sn); + break; + case ISCSI_OP_ASYNC_MSG: + cmnd_set_sn(cmnd, 1); + break; + case ISCSI_OP_REJECT: + cmnd_set_sn(cmnd, 1); + cmnd_send_pdu(conn, cmnd); + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + break; + } + + iop->iov_len = 0; + // move this? + conn->write_size = (conn->write_size + 3) & -4; + iscsi_dump_pdu(&cmnd->pdu); +} + +void cmnd_tx_end(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_IN: + case ISCSI_OP_SCSI_RSP: + case ISCSI_OP_SCSI_TASK_MGT_RSP: + case ISCSI_OP_TEXT_RSP: + case ISCSI_OP_R2T: + case ISCSI_OP_ASYNC_MSG: + case ISCSI_OP_REJECT: + case ISCSI_OP_SCSI_DATA_IN: + case ISCSI_OP_LOGOUT_RSP: + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + assert(0); + break; + } + + if (cmnd_close(cmnd)) + conn_close(conn); + + list_del_init(&cmnd->list); + set_cork(cmnd->conn->sock, 0); +} + +/** + * Push the command for execution. + * This functions reorders the commands. + * Called from the read thread. + * + * iscsi_session_push_cmnd - + * @cmnd: ptr to command + */ + +static void iscsi_session_push_cmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_session *session = cmnd->conn->session; + struct list_head *entry; + u32 cmd_sn; + + dprintk(D_GENERIC, "%p:%x %u,%u\n", + cmnd, cmnd_opcode(cmnd), cmnd->pdu.bhs.sn, session->exp_cmd_sn); + + if (cmnd->pdu.bhs.opcode & ISCSI_OP_IMMEDIATE) { + iscsi_cmnd_exec(cmnd); + return; + } + + cmd_sn = cmnd->pdu.bhs.sn; + if (cmd_sn == session->exp_cmd_sn) { + while (1) { + session->exp_cmd_sn = ++cmd_sn; + iscsi_cmnd_exec(cmnd); + + if (list_empty(&session->pending_list)) + break; + cmnd = list_entry(session->pending_list.next, struct iscsi_cmnd, list); + if (cmnd->pdu.bhs.sn != cmd_sn) + break; +/* eprintk("find out-of-order %x %u %u\n", */ +/* cmnd_itt(cmnd), cmd_sn, cmnd->pdu.bhs.sn); */ + list_del_init(&cmnd->list); + clear_cmnd_pending(cmnd); + } + } else { +/* eprintk("out-of-order %x %u %u\n", */ +/* cmnd_itt(cmnd), cmd_sn, session->exp_cmd_sn); */ + + set_cmnd_pending(cmnd); + if (before(cmd_sn, session->exp_cmd_sn)) /* close the conn */ + eprintk("unexpected cmd_sn (%u,%u)\n", cmd_sn, session->exp_cmd_sn); + + if (after(cmd_sn, session->exp_cmd_sn + session->max_queued_cmnds)) + eprintk("too large cmd_sn (%u,%u)\n", cmd_sn, session->exp_cmd_sn); + + list_for_each(entry, &session->pending_list) { + struct iscsi_cmnd *tmp = list_entry(entry, struct iscsi_cmnd, list); + if (before(cmd_sn, tmp->pdu.bhs.sn)) + break; + } + + assert(list_empty(&cmnd->list)); + + list_add_tail(&cmnd->list, entry); + } +} + +static int check_segment_length(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iscsi_sess_param *param = &conn->session->param; + + if (cmnd->pdu.datasize > param->max_recv_data_length) { + eprintk("data too long %x %u %u\n", cmnd_itt(cmnd), + cmnd->pdu.datasize, param->max_recv_data_length); + + if (get_pgcnt(cmnd->pdu.datasize, 0) > ISCSI_CONN_IOV_MAX) { + conn_close(conn); + return -EINVAL; + } + } + + return 0; +} + +void cmnd_rx_start(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + int err = 0; + + iscsi_dump_pdu(&cmnd->pdu); + + set_cmnd_rxstart(cmnd); + if (check_segment_length(cmnd) < 0) + return; + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_NOOP_OUT: + err = noop_out_start(conn, cmnd); + break; + case ISCSI_OP_SCSI_CMD: + if (!(err = cmnd_insert_hash(cmnd))) + scsi_cmnd_start(conn, cmnd); + break; + case ISCSI_OP_SCSI_TASK_MGT_MSG: + err = cmnd_insert_hash(cmnd); + break; + case ISCSI_OP_SCSI_DATA_OUT: + data_out_start(conn, cmnd); + break; + case ISCSI_OP_LOGOUT_CMD: + err = cmnd_insert_hash(cmnd); + break; + case ISCSI_OP_TEXT_CMD: + case ISCSI_OP_SNACK_CMD: + err = -ISCSI_REASON_UNSUPPORTED_COMMAND; + break; + default: + err = -ISCSI_REASON_UNSUPPORTED_COMMAND; + break; + } + + if (err < 0) { + eprintk("%x %x %d\n", cmnd_opcode(cmnd), cmnd_itt(cmnd), err); + iscsi_cmnd_reject(cmnd, -err); + } +} + +void cmnd_rx_end(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + + if (cmnd_tmfabort(cmnd)) { + cmnd_release(cmnd, 1); + return; + } + + dprintk(D_GENERIC, "%p:%x\n", cmnd, cmnd_opcode(cmnd)); + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_REJECT: + case ISCSI_OP_NOOP_OUT: + case ISCSI_OP_SCSI_CMD: + case ISCSI_OP_SCSI_TASK_MGT_MSG: + case ISCSI_OP_TEXT_CMD: + case ISCSI_OP_LOGOUT_CMD: + iscsi_session_push_cmnd(cmnd); + break; + case ISCSI_OP_SCSI_DATA_OUT: + data_out_end(conn, cmnd); + break; + case ISCSI_OP_SNACK_CMD: + break; + case ISCSI_OP_PDU_REJECT: + iscsi_cmnd_init_write(get_rsp_cmnd(cmnd)); + break; + case ISCSI_OP_DATA_REJECT: + cmnd_release(cmnd, 0); + break; + default: + eprintk("unexpected cmnd op %x\n", cmnd_opcode(cmnd)); + BUG(); + break; + } +} + +static void iscsi_exit(void) +{ + unregister_chrdev(ctr_major, ctr_name); + + iet_procfs_exit(); + + event_exit(); + + tio_exit(); + + iotype_exit(); + + if (iscsi_cmnd_cache) + kmem_cache_destroy(iscsi_cmnd_cache); +} + +static int iscsi_init(void) +{ + int err = -ENOMEM; + + printk("iSCSI Enterprise Target Software - version %s\n", IET_VERSION_STRING); + + if ((ctr_major = register_chrdev(0, ctr_name, &ctr_fops)) < 0) { + eprintk("failed to register the control device %d\n", ctr_major); + return ctr_major; + } + + if ((err = iet_procfs_init()) < 0) + goto err; + + if ((err = event_init()) < 0) + goto err; + + iscsi_cmnd_cache = KMEM_CACHE(iscsi_cmnd, 0); + if (!iscsi_cmnd_cache) + goto err; + + if ((err = tio_init()) < 0) + goto err; + + if ((err = iotype_init()) < 0) + goto err; + + return 0; + +err: + iscsi_exit(); + return err; +} + +module_param(debug_enable_flags, ulong, S_IRUGO); + +module_init(iscsi_init); +module_exit(iscsi_exit); + +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/ubuntu/iscsitarget/conn.c +++ linux-2.6.28/ubuntu/iscsitarget/conn.c @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "digest.h" + +static void print_conn_state(char *p, size_t size, unsigned long state) +{ + if (test_bit(CONN_ACTIVE, &state)) + snprintf(p, size, "%s", "active"); + else if (test_bit(CONN_CLOSING, &state)) + snprintf(p, size, "%s", "closing"); + else + snprintf(p, size, "%s", "unknown"); +} + +static void print_digest_state(char *p, size_t size, unsigned long flags) +{ + if (DIGEST_NONE & flags) + snprintf(p, size, "%s", "none"); + else if (DIGEST_CRC32C & flags) + snprintf(p, size, "%s", "crc32c"); + else + snprintf(p, size, "%s", "unknown"); +} + +void conn_info_show(struct seq_file *seq, struct iscsi_session *session) +{ + struct iscsi_conn *conn; + struct sock *sk; + char buf[64]; + + list_for_each_entry(conn, &session->conn_list, list) { + sk = conn->sock->sk; + switch (sk->sk_family) { + case AF_INET: + snprintf(buf, sizeof(buf), + "%u.%u.%u.%u", NIPQUAD(inet_sk(sk)->daddr)); + break; + case AF_INET6: + snprintf(buf, sizeof(buf), + "[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]", + NIP6(inet6_sk(sk)->daddr)); + break; + default: + break; + } + seq_printf(seq, "\t\tcid:%u ip:%s ", conn->cid, buf); + print_conn_state(buf, sizeof(buf), conn->state); + seq_printf(seq, "state:%s ", buf); + print_digest_state(buf, sizeof(buf), conn->hdigest_type); + seq_printf(seq, "hd:%s ", buf); + print_digest_state(buf, sizeof(buf), conn->ddigest_type); + seq_printf(seq, "dd:%s\n", buf); + } +} + +struct iscsi_conn *conn_lookup(struct iscsi_session *session, u16 cid) +{ + struct iscsi_conn *conn; + + list_for_each_entry(conn, &session->conn_list, list) { + if (conn->cid == cid) + return conn; + } + return NULL; +} + +static void iet_state_change(struct sock *sk) +{ + struct iscsi_conn *conn = sk->sk_user_data; + struct iscsi_target *target = conn->session->target; + + if (sk->sk_state != TCP_ESTABLISHED) + conn_close(conn); + else + nthread_wakeup(target); + + target->nthread_info.old_state_change(sk); +} + +static void iet_data_ready(struct sock *sk, int len) +{ + struct iscsi_conn *conn = sk->sk_user_data; + struct iscsi_target *target = conn->session->target; + + nthread_wakeup(target); + target->nthread_info.old_data_ready(sk, len); +} + +/* + * @locking: grabs the target's nthread_lock to protect it from races with + * set_conn_wspace_wait() + */ +static void iet_write_space(struct sock *sk) +{ + struct iscsi_conn *conn = sk->sk_user_data; + struct network_thread_info *info = &conn->session->target->nthread_info; + + spin_lock_bh(&info->nthread_lock); + + if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && + test_bit(CONN_WSPACE_WAIT, &conn->state)) { + clear_bit(CONN_WSPACE_WAIT, &conn->state); + __nthread_wakeup(info); + } + + spin_unlock_bh(&info->nthread_lock); + + info->old_write_space(sk); +} + +static void iet_socket_bind(struct iscsi_conn *conn) +{ + int opt = 1; + mm_segment_t oldfs; + struct iscsi_session *session = conn->session; + struct iscsi_target *target = session->target; + + dprintk(D_GENERIC, "%llu\n", (unsigned long long) session->sid); + + conn->sock = SOCKET_I(conn->file->f_dentry->d_inode); + conn->sock->sk->sk_user_data = conn; + + write_lock_bh(&conn->sock->sk->sk_callback_lock); + target->nthread_info.old_state_change = conn->sock->sk->sk_state_change; + conn->sock->sk->sk_state_change = iet_state_change; + + target->nthread_info.old_data_ready = conn->sock->sk->sk_data_ready; + conn->sock->sk->sk_data_ready = iet_data_ready; + + target->nthread_info.old_write_space = conn->sock->sk->sk_write_space; + conn->sock->sk->sk_write_space = iet_write_space; + write_unlock_bh(&conn->sock->sk->sk_callback_lock); + + oldfs = get_fs(); + set_fs(get_ds()); + conn->sock->ops->setsockopt(conn->sock, SOL_TCP, TCP_NODELAY, (void *)&opt, sizeof(opt)); + set_fs(oldfs); +} + +int conn_free(struct iscsi_conn *conn) +{ + dprintk(D_GENERIC, "%p %#Lx %u\n", conn->session, + (unsigned long long) conn->session->sid, conn->cid); + + assert(atomic_read(&conn->nr_cmnds) == 0); + assert(list_empty(&conn->pdu_list)); + assert(list_empty(&conn->write_list)); + + list_del(&conn->list); + list_del(&conn->poll_list); + + digest_cleanup(conn); + kfree(conn); + + return 0; +} + +static int iet_conn_alloc(struct iscsi_session *session, struct conn_info *info) +{ + struct iscsi_conn *conn; + + dprintk(D_SETUP, "%#Lx:%u\n", (unsigned long long) session->sid, info->cid); + + conn = kzalloc(sizeof(*conn), GFP_KERNEL); + if (!conn) + return -ENOMEM; + + conn->session = session; + conn->cid = info->cid; + conn->stat_sn = info->stat_sn; + conn->exp_stat_sn = info->exp_stat_sn; + + conn->hdigest_type = info->header_digest; + conn->ddigest_type = info->data_digest; + if (digest_init(conn) < 0) { + kfree(conn); + return -ENOMEM; + } + + spin_lock_init(&conn->list_lock); + atomic_set(&conn->nr_cmnds, 0); + atomic_set(&conn->nr_busy_cmnds, 0); + INIT_LIST_HEAD(&conn->pdu_list); + INIT_LIST_HEAD(&conn->write_list); + INIT_LIST_HEAD(&conn->poll_list); + + list_add(&conn->list, &session->conn_list); + + set_bit(CONN_ACTIVE, &conn->state); + + conn->file = fget(info->fd); + iet_socket_bind(conn); + + list_add(&conn->poll_list, &session->target->nthread_info.active_conns); + + nthread_wakeup(conn->session->target); + + return 0; +} + +void conn_close(struct iscsi_conn *conn) +{ + if (test_and_clear_bit(CONN_ACTIVE, &conn->state)) + set_bit(CONN_CLOSING, &conn->state); + + nthread_wakeup(conn->session->target); +} + +int conn_add(struct iscsi_session *session, struct conn_info *info) +{ + struct iscsi_conn *conn; + int err = -EEXIST; + + conn = conn_lookup(session, info->cid); + if (conn) + return err; + + return iet_conn_alloc(session, info); +} + +int conn_del(struct iscsi_session *session, struct conn_info *info) +{ + struct iscsi_conn *conn; + int err = -EEXIST; + + conn = conn_lookup(session, info->cid); + if (!conn) + return err; + + conn_close(conn); + + return 0; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/digest.h +++ linux-2.6.28/ubuntu/iscsitarget/digest.h @@ -0,0 +1,20 @@ +/* + * iSCSI digest handling. + * (C) 2004 Xiranet Communications GmbH + * This code is licensed under the GPL. + */ + +#ifndef __IET_DIGEST_H__ +#define __IET_DIGEST_H__ + +extern void digest_alg_available(unsigned int *val); +extern int digest_init(struct iscsi_conn *conn); +extern void digest_cleanup(struct iscsi_conn *conn); + +extern int digest_rx_header(struct iscsi_cmnd *cmnd); +extern int digest_rx_data(struct iscsi_cmnd *cmnd); + +extern void digest_tx_header(struct iscsi_cmnd *cmnd); +extern void digest_tx_data(struct iscsi_cmnd *cmnd); + +#endif /* __IET_DIGEST_H__ */ --- linux-2.6.28.orig/ubuntu/iscsitarget/block-io.c +++ linux-2.6.28/ubuntu/iscsitarget/block-io.c @@ -0,0 +1,393 @@ +/* + * Target device block I/O. + * + * Based on file I/O driver from FUJITA Tomonori + * (C) 2004 - 2005 FUJITA Tomonori + * (C) 2006 Andre Brinkmann + * (C) 2007 Ross Walker + * (C) 2007 Ming Zhang + * This code is licenced under the GPL. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct blockio_data { + char *path; + struct block_device *bdev; + fmode_t fmode; +}; + +struct tio_work { + atomic_t error; + atomic_t bios_remaining; + struct completion tio_complete; +}; + +static void blockio_bio_endio(struct bio *bio, int error) +{ + struct tio_work *tio_work = bio->bi_private; + + error = test_bit(BIO_UPTODATE, &bio->bi_flags) ? error : -EIO; + + if (error) + atomic_set(&tio_work->error, error); + + /* If last bio signal completion */ + if (atomic_dec_and_test(&tio_work->bios_remaining)) + complete(&tio_work->tio_complete); + + bio_put(bio); +} + +/* + * Blockio_make_request(): The function translates an iscsi-request into + * a number of requests to the corresponding block device. + */ +static int +blockio_make_request(struct iet_volume *volume, struct tio *tio, int rw) +{ + struct blockio_data *bio_data = volume->private; + struct request_queue *bdev_q = bdev_get_queue(bio_data->bdev); + struct tio_work *tio_work; + struct bio *tio_bio = NULL, *bio = NULL, *biotail = NULL; + + u32 offset = tio->offset; + u32 size = tio->size; + u32 tio_index = 0; + + int max_pages = 1; + int err = 0; + + loff_t ppos = ((loff_t) tio->idx << PAGE_SHIFT) + offset; + + /* Calculate max_pages for bio_alloc (memory saver) */ + if (bdev_q) + max_pages = bio_get_nr_vecs(bio_data->bdev); + + tio_work = kzalloc(sizeof (*tio_work), GFP_KERNEL); + if (!tio_work) + return -ENOMEM; + + atomic_set(&tio_work->error, 0); + atomic_set(&tio_work->bios_remaining, 0); + init_completion(&tio_work->tio_complete); + + /* Main processing loop, allocate and fill all bios */ + while (tio_index < tio->pg_cnt) { + bio = bio_alloc(GFP_KERNEL, min(max_pages, BIO_MAX_PAGES)); + if (!bio) { + err = -ENOMEM; + goto out; + } + + bio->bi_sector = ppos >> volume->blk_shift; + bio->bi_bdev = bio_data->bdev; + bio->bi_end_io = blockio_bio_endio; + bio->bi_private = tio_work; + + if (tio_bio) + biotail = biotail->bi_next = bio; + else + tio_bio = biotail = bio; + + atomic_inc(&tio_work->bios_remaining); + + /* Loop for filling bio */ + while (tio_index < tio->pg_cnt) { + unsigned int bytes = PAGE_SIZE - offset; + + if (bytes > size) + bytes = size; + + if (!bio_add_page(bio, tio->pvec[tio_index], bytes, offset)) + break; + + size -= bytes; + ppos += bytes; + + offset = 0; + + tio_index++; + } + } + + /* Walk the list, submitting bios 1 by 1 */ + while (tio_bio) { + bio = tio_bio; + tio_bio = tio_bio->bi_next; + bio->bi_next = NULL; + + submit_bio(rw, bio); + } + + if (bdev_q && bdev_q->unplug_fn) + bdev_q->unplug_fn(bdev_q); + + wait_for_completion(&tio_work->tio_complete); + + err = atomic_read(&tio_work->error); + + kfree(tio_work); + + return err; +out: + while (tio_bio) { + bio = tio_bio; + tio_bio = tio_bio->bi_next; + + bio_put(bio); + } + + kfree(tio_work); + + return err; +} + +static int +blockio_open_path(struct iet_volume *volume, const char *path) +{ + struct blockio_data *bio_data = volume->private; + struct block_device *bdev; + int err = 0; + + bio_data->fmode = FMODE_READ|FMODE_WRITE; + bio_data->path = kstrdup(path, GFP_KERNEL); + if (!bio_data->path) + return -ENOMEM; + + bdev = open_bdev_exclusive(path, bio_data->fmode, THIS_MODULE); + if (IS_ERR(bdev)) { + err = PTR_ERR(bdev); + eprintk("Can't open device %s, error %d\n", path, err); + bio_data->bdev = NULL; + } else { + if (LUReadonly(volume)) + set_device_ro(bdev,1); + bio_data->bdev = bdev; + fsync_bdev(bio_data->bdev); + } + + return err; +} + +static int +set_scsiid(struct iet_volume *volume, const char *id) +{ + size_t len; + + if ((len = strlen(id)) > SCSI_ID_LEN - VENDOR_ID_LEN) { + eprintk("SCSI ID too long, %zd provided, %u max\n", len, + SCSI_ID_LEN - VENDOR_ID_LEN); + return -EINVAL; + } + + memcpy(volume->scsi_id + VENDOR_ID_LEN, id, len); + + return 0; +} + +static void +gen_scsiid(struct iet_volume *volume, struct inode *inode) +{ + int i; + u32 *p; + + strlcpy(volume->scsi_id, VENDOR_ID, VENDOR_ID_LEN); + + for (i = VENDOR_ID_LEN; i < SCSI_ID_LEN; i++) + if (volume->scsi_id[i]) + return; + + /* If a scsi id doesn't exist generate a 16 byte one: + * Bytes 1-4: target type + * Bytes 5-8: target id + * Bytes 9-12: inode number + * Bytes 13-16: device type + */ + p = (u32 *) (volume->scsi_id + VENDOR_ID_LEN); + *(p + 0) = volume->target->trgt_param.target_type; + *(p + 1) = volume->target->tid; + *(p + 2) = volume->lun; + *(p + 3) = (unsigned int) inode->i_sb->s_dev; +} + +static int +set_scsisn(struct iet_volume *volume, const char *sn) +{ + size_t len; + + if ((len = strlen(sn)) > SCSI_SN_LEN) { + eprintk("SCSI SN too long, %zd provided, %u max\n", len, + SCSI_SN_LEN); + return -EINVAL; + } + + memcpy(volume->scsi_sn, sn, len); + + return 0; +} + +/* Create an enumeration of our accepted actions */ +enum +{ + Opt_scsiid, Opt_scsisn, Opt_path, Opt_ignore, Opt_err, +}; + +/* Create a match table using our action enums and their matching options */ +static match_table_t tokens = { + {Opt_scsiid, "ScsiId=%s"}, + {Opt_scsisn, "ScsiSN=%s"}, + {Opt_path, "Path=%s"}, + {Opt_ignore, "Type=%s"}, + {Opt_ignore, "IOMode=%s"}, + {Opt_err, NULL}, +}; + +static int +parse_blockio_params(struct iet_volume *volume, char *params) +{ + struct blockio_data *info = volume->private; + int err = 0; + char *p, *q; + + /* Loop through parameters separated by commas, look up our + * parameter in match table, return enumeration and arguments + * select case based on the returned enum and run the action */ + while ((p = strsep(¶ms, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + int token; + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_scsiid: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsiid(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_scsisn: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsisn(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_path: + if (info->path) { + iprintk("Target %s, LUN %u: " + "duplicate \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + goto out; + } + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = blockio_open_path(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_ignore: + break; + default: + iprintk("Target %s, LUN %u: unknown param %s\n", + volume->target->name, volume->lun, p); + return -EINVAL; + } + } + + if (!info->path) { + iprintk("Target %s, LUN %u: missing \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + } + out: + return err; +} + +static void +blockio_detach(struct iet_volume *volume) +{ + struct blockio_data *bio_data = volume->private; + + if (bio_data->bdev) + close_bdev_exclusive(bio_data->bdev,bio_data->fmode); + kfree(bio_data->path); + + kfree(volume->private); +} + +static int +blockio_attach(struct iet_volume *volume, char *args) +{ + struct blockio_data *bio_data; + int err = 0; + + if (volume->private) { + eprintk("Lun %u already attached on Target %s \n", + volume->lun, volume->target->name); + return -EBUSY; + } + + bio_data = kzalloc(sizeof (*bio_data), GFP_KERNEL); + if (!bio_data) + return -ENOMEM; + + volume->private = bio_data; + + if ((err = parse_blockio_params(volume, args)) < 0) { + eprintk("Error attaching Lun %u to Target %s \n", + volume->lun, volume->target->name); + goto out; + } + + /* Assign a vendor id, generate scsi id if none exists */ + gen_scsiid(volume, bio_data->bdev->bd_inode); + + /* Offer neither write nor read caching */ + ClearLURCache(volume); + ClearLUWCache(volume); + + volume->blk_shift = SECTOR_SIZE_BITS; + volume->blk_cnt = bio_data->bdev->bd_inode->i_size >> volume->blk_shift; + + out: + if (err < 0) + blockio_detach(volume); + + return err; +} + +static void +blockio_show(struct iet_volume *volume, struct seq_file *seq) +{ + struct blockio_data *bio_data = volume->private; + + /* Used to display blockio volume info in /proc/net/iet/volumes */ + seq_printf(seq, " path:%s\n", bio_data->path); +} + +struct iotype blockio = { + .name = "blockio", + .attach = blockio_attach, + .make_request = blockio_make_request, + .detach = blockio_detach, + .show = blockio_show, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/file-io.c +++ linux-2.6.28/ubuntu/iscsitarget/file-io.c @@ -0,0 +1,324 @@ +/* + * Target device file I/O. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct fileio_data { + char *path; + struct file *filp; +}; + +static int fileio_make_request(struct iet_volume *lu, struct tio *tio, int rw) +{ + struct fileio_data *p = lu->private; + struct file *filp; + mm_segment_t oldfs; + struct page *page; + u32 offset, size; + loff_t ppos, count; + char *buf; + int i, err = 0; + ssize_t ret; + + assert(p); + filp = p->filp; + size = tio->size; + offset= tio->offset; + + ppos = (loff_t) tio->idx << PAGE_CACHE_SHIFT; + ppos += offset; + + for (i = 0; i < tio->pg_cnt; i++) { + page = tio->pvec[i]; + assert(page); + buf = page_address(page); + buf += offset; + + if (offset + size > PAGE_CACHE_SIZE) + count = PAGE_CACHE_SIZE - offset; + else + count = size; + + oldfs = get_fs(); + set_fs(get_ds()); + + if (rw == READ) + ret = do_sync_read(filp, buf, count, &ppos); + else + ret = do_sync_write(filp, buf, count, &ppos); + + set_fs(oldfs); + + if (ret != count) { + eprintk("I/O error %lld, %ld\n", count, (long) ret); + err = -EIO; + } + + size -= count; + offset = 0; + } + assert(!size); + + return err; +} + +static int fileio_sync(struct iet_volume *lu, struct tio *tio) +{ + struct fileio_data *p = lu->private; + struct inode *inode = p->filp->f_dentry->d_inode; + struct address_space *mapping = inode->i_mapping; + loff_t ppos, count; + int res; + + if (tio) { + ppos = (loff_t) tio->idx << PAGE_CACHE_SHIFT; + count = tio->size; + } else { + ppos = 0; + count = lu->blk_cnt << lu->blk_shift; + } + + res = sync_page_range(inode, mapping, ppos, count); + if (res) { + eprintk("I/O error: syncing pages failed: %d\n", res); + return -EIO; + } else + return 0; +} + +static int open_path(struct iet_volume *volume, const char *path) +{ + int err = 0; + struct fileio_data *info = volume->private; + struct file *filp; + mm_segment_t oldfs; + int flags; + + info->path = kstrdup(path, GFP_KERNEL); + if (!info->path) + return -ENOMEM; + + oldfs = get_fs(); + set_fs(get_ds()); + flags = (LUReadonly(volume) ? O_RDONLY : O_RDWR) | O_LARGEFILE; + filp = filp_open(path, flags, 0); + set_fs(oldfs); + + if (IS_ERR(filp)) { + err = PTR_ERR(filp); + eprintk("Can't open %s %d\n", path, err); + info->filp = NULL; + } else + info->filp = filp; + + return err; +} + +static int set_scsiid(struct iet_volume *volume, const char *id) +{ + size_t len; + + if ((len = strlen(id)) > SCSI_ID_LEN - VENDOR_ID_LEN) { + eprintk("SCSI ID too long, %zd provided, %u max\n", len, + SCSI_ID_LEN - VENDOR_ID_LEN); + return -EINVAL; + } + + memcpy(volume->scsi_id + VENDOR_ID_LEN, id, len); + + return 0; +} + +static void gen_scsiid(struct iet_volume *volume, struct inode *inode) +{ + int i; + u32 *p; + + strlcpy(volume->scsi_id, VENDOR_ID, VENDOR_ID_LEN); + + for (i = VENDOR_ID_LEN; i < SCSI_ID_LEN; i++) + if (volume->scsi_id[i]) + return; + + p = (u32 *) (volume->scsi_id + VENDOR_ID_LEN); + *(p + 0) = volume->target->trgt_param.target_type; + *(p + 1) = volume->target->tid; + *(p + 2) = (unsigned int) inode->i_ino; + *(p + 3) = (unsigned int) inode->i_sb->s_dev; +} + +static int set_scsisn(struct iet_volume *volume, const char *sn) +{ + size_t len; + + if ((len = strlen(sn)) > SCSI_SN_LEN) { + eprintk("SCSI SN too long, %zd provided, %u max\n", len, + SCSI_SN_LEN); + return -EINVAL; + } + memcpy(volume->scsi_sn, sn, len); + return 0; +} + +enum { + Opt_scsiid, Opt_scsisn, Opt_path, Opt_ignore, Opt_err, +}; + +static match_table_t tokens = { + {Opt_scsiid, "ScsiId=%s"}, + {Opt_scsisn, "ScsiSN=%s"}, + {Opt_path, "Path=%s"}, + {Opt_ignore, "Type=%s"}, + {Opt_ignore, "IOMode=%s"}, + {Opt_err, NULL}, +}; + +static int parse_fileio_params(struct iet_volume *volume, char *params) +{ + struct fileio_data *info = volume->private; + int err = 0; + char *p, *q; + + while ((p = strsep(¶ms, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + int token; + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_scsiid: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsiid(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_scsisn: + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = set_scsisn(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_path: + if (info->path) { + iprintk("Target %s, LUN %u: " + "duplicate \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + goto out; + } + if (!(q = match_strdup(&args[0]))) { + err = -ENOMEM; + goto out; + } + err = open_path(volume, q); + kfree(q); + if (err < 0) + goto out; + break; + case Opt_ignore: + break; + default: + iprintk("Target %s, LUN %u: unknown param %s\n", + volume->target->name, volume->lun, p); + return -EINVAL; + } + } + + if (!info->path) { + iprintk("Target %s, LUN %u: missing \"Path\" param\n", + volume->target->name, volume->lun); + err = -EINVAL; + } +out: + return err; +} + +static void fileio_detach(struct iet_volume *lu) +{ + struct fileio_data *p = lu->private; + + kfree(p->path); + if (p->filp) + filp_close(p->filp, NULL); + kfree(p); + lu->private = NULL; +} + +static int fileio_attach(struct iet_volume *lu, char *args) +{ + int err = 0; + struct fileio_data *p; + struct inode *inode; + + if (lu->private) { + printk("already attached ? %d\n", lu->lun); + return -EBUSY; + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + lu->private = p; + + if ((err = parse_fileio_params(lu, args)) < 0) { + eprintk("%d\n", err); + goto out; + } + inode = p->filp->f_dentry->d_inode; + + gen_scsiid(lu, inode); + + if (S_ISREG(inode->i_mode)) + ; + else if (S_ISBLK(inode->i_mode)) + inode = inode->i_bdev->bd_inode; + else { + err = -EINVAL; + goto out; + } + + lu->blk_shift = SECTOR_SIZE_BITS; + lu->blk_cnt = inode->i_size >> lu->blk_shift; + + /* we're using the page cache */ + SetLURCache(lu); +out: + if (err < 0) + fileio_detach(lu); + return err; +} + +static void fileio_show(struct iet_volume *lu, struct seq_file *seq) +{ + struct fileio_data *p = lu->private; + seq_printf(seq, " path:%s\n", p->path); +} + +struct iotype fileio = +{ + .name = "fileio", + .attach = fileio_attach, + .make_request = fileio_make_request, + .sync = fileio_sync, + .detach = fileio_detach, + .show = fileio_show, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/volume.c +++ linux-2.6.28/ubuntu/iscsitarget/volume.c @@ -0,0 +1,264 @@ +/* + * Volume manager + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct iet_volume *volume_lookup(struct iscsi_target *target, u32 lun) +{ + struct iet_volume *volume; + + list_for_each_entry(volume, &target->volumes, list) { + if (volume->lun == lun) + return volume; + } + return NULL; +} + +enum { + Opt_type, + Opt_iomode, + Opt_err, +}; + +static match_table_t tokens = { + {Opt_type, "Type=%s"}, + {Opt_iomode, "IOMode=%s"}, + {Opt_err, NULL}, +}; + +static int set_iotype(struct iet_volume *volume, char *params) +{ + int err = 0; + substring_t args[MAX_OPT_ARGS]; + char *p, *argp = NULL, *buf = (char *) get_zeroed_page(GFP_USER); + + if (!buf) + return -ENOMEM; + strncpy(buf, params, PAGE_CACHE_SIZE); + + while ((p = strsep(&buf, ",")) != NULL) { + int token; + + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_type: + if (!(argp = match_strdup(&args[0]))) + err = -ENOMEM; + if (argp && !(volume->iotype = get_iotype(argp))) + err = -ENOENT; + kfree(argp); + break; + case Opt_iomode: + if (!(argp = match_strdup(&args[0]))) + err = -ENOMEM; + if (argp && !strcmp(argp, "ro")) + SetLUReadonly(volume); + else if (argp && !strcmp(argp, "wb")) + SetLUWCache(volume); + kfree(argp); + break; + default: + break; + } + } + + if (!err && !volume->iotype && !(volume->iotype = get_iotype("fileio"))) { + eprintk("%s\n", "Cannot find fileio"); + err = -EINVAL; + } + + free_page((unsigned long) buf); + + return err; +} + +int volume_add(struct iscsi_target *target, struct volume_info *info) +{ + int ret; + struct iet_volume *volume; + char *args; + + volume = volume_lookup(target, info->lun); + if (volume) + return -EEXIST; + + if (info->lun > 0x3fff) + return -EINVAL; + + volume = kzalloc(sizeof(*volume), GFP_KERNEL); + if (!volume) + return -ENOMEM; + + volume->target = target; + volume->lun = info->lun; + + args = kzalloc(info->args_len + 1, GFP_KERNEL); + if (!args) { + ret = -ENOMEM; + goto free_volume; + } + + ret = copy_from_user(args, (void *)(unsigned long)info->args_ptr, + info->args_len); + if (ret) { + ret = -EFAULT; + goto free_args; + } + + ret = set_iotype(volume, args); + if (ret < 0) + goto free_args; + + ret = volume->iotype->attach(volume, args); + if (ret < 0) + goto free_args; + + INIT_LIST_HEAD(&volume->queue.wait_list); + spin_lock_init(&volume->queue.queue_lock); + spin_lock_init(&volume->reserve_lock); + + volume->l_state = IDEV_RUNNING; + atomic_set(&volume->l_count, 0); + + list_add_tail(&volume->list, &target->volumes); + atomic_inc(&target->nr_volumes); + + kfree(args); + + return 0; +free_args: + kfree(args); +free_volume: + put_iotype(volume->iotype); + kfree(volume); + + return ret; +} + +void iscsi_volume_destroy(struct iet_volume *volume) +{ + assert(volume->l_state == IDEV_DEL); + assert(!atomic_read(&volume->l_count)); + + volume->iotype->detach(volume); + put_iotype(volume->iotype); + list_del(&volume->list); + kfree(volume); +} + +int iscsi_volume_del(struct iscsi_target *target, struct volume_info *info) +{ + struct iet_volume *volume; + + eprintk("%x %x\n", target->tid, info->lun); + if (!(volume = volume_lookup(target, info->lun))) + return -ENOENT; + + volume->l_state = IDEV_DEL; + atomic_dec(&target->nr_volumes); + if (!atomic_read(&volume->l_count)) + iscsi_volume_destroy(volume); + + return 0; +} + +struct iet_volume *volume_get(struct iscsi_target *target, u32 lun) +{ + struct iet_volume *volume; + + if ((volume = volume_lookup(target, lun))) { + if (volume->l_state == IDEV_RUNNING) + atomic_inc(&volume->l_count); + else + volume = NULL; + } + return volume; +} + +void volume_put(struct iet_volume *volume) +{ + if (atomic_dec_and_test(&volume->l_count) && volume->l_state == IDEV_DEL) + iscsi_volume_destroy(volume); +} + +int volume_reserve(struct iet_volume *volume, u64 sid) +{ + if (!volume) + return -ENOENT; + + spin_lock(&volume->reserve_lock); + if (volume->reserve_sid && volume->reserve_sid != sid) { + spin_unlock(&volume->reserve_lock); + return -EBUSY; + } + + volume->reserve_sid = sid; + spin_unlock(&volume->reserve_lock); + + return 0; +} + +int is_volume_reserved(struct iet_volume *volume, u64 sid) +{ + if (!volume || !volume->reserve_sid || volume->reserve_sid == sid) + return 0; + + return -EBUSY; +} + +int volume_release(struct iet_volume *volume, u64 sid, int force) +{ + if (force || volume->reserve_sid == sid) + volume->reserve_sid = 0; + + return 0; +} + +static void iet_volume_info_show(struct seq_file *seq, struct iscsi_target *target) +{ + struct iet_volume *volume; + + list_for_each_entry(volume, &target->volumes, list) { + seq_printf(seq, "\tlun:%u state:%x iotype:%s", + volume->lun, volume->l_state, volume->iotype->name); + if (LUReadonly(volume)) + seq_printf(seq, " iomode:ro"); + else if (LUWCache(volume)) + seq_printf(seq, " iomode:wb"); + else + seq_printf(seq, " iomode:wt"); + + if (volume->iotype->show) + volume->iotype->show(volume, seq); + else + seq_printf(seq, "\n"); + } +} + +static int iet_volumes_info_show(struct seq_file *seq, void *v) +{ + return iet_info_show(seq, iet_volume_info_show); +} + +static int iet_volume_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, iet_volumes_info_show, NULL); +} + +struct file_operations volume_seq_fops = { + .owner = THIS_MODULE, + .open = iet_volume_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/Kconfig +++ linux-2.6.28/ubuntu/iscsitarget/Kconfig @@ -0,0 +1,3 @@ +config SCSI_ISCSITARGET + tristate "iSCSI Target Driver" + depends on SCSI --- linux-2.6.28.orig/ubuntu/iscsitarget/iotype.c +++ linux-2.6.28/ubuntu/iscsitarget/iotype.c @@ -0,0 +1,110 @@ +/* + * Manager for various I/O types. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include "iscsi.h" +#include "iotype.h" +#include "iscsi_dbg.h" + +static LIST_HEAD(iotypes); +static rwlock_t iotypes_lock = RW_LOCK_UNLOCKED; + +static struct iotype *find_iotype(const char *name) +{ + struct iotype *iot = NULL; + + list_for_each_entry(iot, &iotypes, iot_list) { + if (strcmp(iot->name, name) == 0) + return iot; + } + return NULL; +} + +struct iotype *get_iotype(const char *name) +{ + struct iotype *iot; + + read_lock(&iotypes_lock); + iot = find_iotype(name); + read_unlock(&iotypes_lock); + + return iot; +} + +void put_iotype(struct iotype *iot) +{ + if (!iot) + return; + return; +} + +static int register_iotype(struct iotype *iot) +{ + int err = 0; + struct iotype *p; + + write_lock(&iotypes_lock); + + p = find_iotype(iot->name); + if (p) + err = -EBUSY; + else + list_add_tail(&iot->iot_list, &iotypes); + + write_unlock(&iotypes_lock); + + return err; +} + +static int unregister_iotype(struct iotype *iot) +{ + int err = 0; + struct iotype *p; + + write_lock(&iotypes_lock); + + p = find_iotype(iot->name); + if (p && p == iot) + list_del_init(&iot->iot_list); + else + err = -EINVAL; + + write_unlock(&iotypes_lock); + + + return err; +} + +struct iotype *iotype_array[] = { + &fileio, + &blockio, + &nullio, +}; + +int iotype_init(void) +{ + int i, err; + + for (i = 0; i < ARRAY_SIZE(iotype_array); i++) { + if (!(err = register_iotype(iotype_array[i]))) + iprintk("Registered io type %s\n", + iotype_array[i]->name); + else { + eprintk("Failed to register io type %s\n", + iotype_array[i]->name); + break; + } + } + + return err; +} + +void iotype_exit(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(iotype_array); i++) + unregister_iotype(iotype_array[i]); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/session.c +++ linux-2.6.28/ubuntu/iscsitarget/session.c @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" + +struct iscsi_session *session_lookup(struct iscsi_target *target, u64 sid) +{ + struct iscsi_session *session; + + list_for_each_entry(session, &target->session_list, list) { + if (session->sid == sid) + return session; + } + return NULL; +} + +static struct iscsi_session * +iet_session_alloc(struct iscsi_target *target, struct session_info *info) +{ + int i; + struct iscsi_session *session; + + dprintk(D_SETUP, "%p %u %#Lx\n", target, target->tid, + (unsigned long long) info->sid); + + session = kzalloc(sizeof(*session), GFP_KERNEL); + if (!session) + return NULL; + + session->target = target; + session->sid = info->sid; + memcpy(&session->param, &target->sess_param, sizeof(session->param)); + session->max_queued_cmnds = target->trgt_param.queued_cmnds; + + session->exp_cmd_sn = info->exp_cmd_sn; + session->max_cmd_sn = info->max_cmd_sn; + + session->initiator = kstrdup(info->initiator_name, GFP_KERNEL); + if (!session->initiator) { + kfree(session); + return NULL; + } + + INIT_LIST_HEAD(&session->conn_list); + INIT_LIST_HEAD(&session->pending_list); + + spin_lock_init(&session->cmnd_hash_lock); + for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) + INIT_LIST_HEAD(&session->cmnd_hash[i]); + + session->next_ttt = 1; + + list_add(&session->list, &target->session_list); + + return session; +} + +static int session_free(struct iscsi_session *session) +{ + int i; + + dprintk(D_SETUP, "%#Lx\n", (unsigned long long) session->sid); + + assert(list_empty(&session->conn_list)); + + for (i = 0; i < ARRAY_SIZE(session->cmnd_hash); i++) { + if (!list_empty(&session->cmnd_hash[i])) + BUG(); + } + + list_del(&session->list); + + kfree(session->initiator); + kfree(session); + + return 0; +} + +int session_add(struct iscsi_target *target, struct session_info *info) +{ + struct iscsi_session *session; + int err = -EEXIST; + + session = session_lookup(target, info->sid); + if (session) + return err; + + session = iet_session_alloc(target, info); + if (!session) + err = -ENOMEM; + + return err; +} + +int session_del(struct iscsi_target *target, u64 sid) +{ + struct iscsi_session *session; + + session = session_lookup(target, sid); + if (!session) + return -ENOENT; + + if (!list_empty(&session->conn_list)) { + eprintk("%llu still have connections\n", (unsigned long long) session->sid); + return -EBUSY; + } + + return session_free(session); +} + +static void iet_session_info_show(struct seq_file *seq, struct iscsi_target *target) +{ + struct iscsi_session *session; + + list_for_each_entry(session, &target->session_list, list) { + seq_printf(seq, "\tsid:%llu initiator:%s\n", + (unsigned long long) session->sid, session->initiator); + conn_info_show(seq, session); + } +} + +static int iet_sessions_info_show(struct seq_file *seq, void *v) +{ + return iet_info_show(seq, iet_session_info_show); +} + +static int iet_session_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, iet_sessions_info_show, NULL); +} + +struct file_operations session_seq_fops = { + .owner = THIS_MODULE, + .open = iet_session_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/target_disk.c +++ linux-2.6.28/ubuntu/iscsitarget/target_disk.c @@ -0,0 +1,488 @@ +/* + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + * + * heavily based on code from kernel/iscsi.c: + * Copyright (C) 2002-2003 Ardis Technolgies , + * licensed under the terms of the GNU GPL v2.0, + */ + +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" + +static int insert_disconnect_pg(u8 *ptr) +{ + unsigned char disconnect_pg[] = {0x02, 0x0e, 0x80, 0x80, 0x00, 0x0a, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(ptr, disconnect_pg, sizeof(disconnect_pg)); + return sizeof(disconnect_pg); +} + +static int insert_caching_pg(u8 *ptr, int wcache, int rcache) +{ + unsigned char caching_pg[] = {0x08, 0x12, 0x10, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + + memcpy(ptr, caching_pg, sizeof(caching_pg)); + if (wcache) + ptr[2] |= 0x04; /* set WCE bit if we're caching writes */ + if (!rcache) + ptr[2] |= 0x01; /* Read Cache Disable */ + + return sizeof(caching_pg); +} + +static int insert_ctrl_m_pg(u8 *ptr) +{ + unsigned char ctrl_m_pg[] = {0x0a, 0x0a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x4b}; + + memcpy(ptr, ctrl_m_pg, sizeof(ctrl_m_pg)); + return sizeof(ctrl_m_pg); +} + +static int insert_iec_m_pg(u8 *ptr) +{ + unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00}; + + memcpy(ptr, iec_m_pg, sizeof(iec_m_pg)); + return sizeof(iec_m_pg); +} + +static int insert_format_m_pg(u8 *ptr) +{ + unsigned char format_m_pg[] = {0x03, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00}; + memcpy(ptr, format_m_pg, sizeof(format_m_pg)); + return sizeof(format_m_pg); +} + +static int insert_geo_m_pg(u8 *ptr, u64 sec) +{ + unsigned char geo_m_pg[] = {0x04, 0x16, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00}; + u32 ncyl; + u32 n; + + /* assume 0xff heads, 15krpm. */ + memcpy(ptr, geo_m_pg, sizeof(geo_m_pg)); + ncyl = sec >> 14; /* 256 * 64 */ + memcpy(&n, ptr+1, sizeof(u32)); + n = n | cpu_to_be32(ncyl); + memcpy(ptr+1, &n, sizeof(u32)); + return sizeof(geo_m_pg); +} + +static int build_mode_sense_response(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct tio *tio = cmnd->tio; + u8 *data, *scb = req->scb; + int len = 4, err = 0; + u8 pcode; + + /* changeable parameter mode pages are unsupported */ + if ((scb[2] & 0xc0) >> 6 == 0x1) + return -1; + + pcode = req->scb[2] & 0x3f; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + + if (LUReadonly(cmnd->lun)) + data[2] = 0x80; + + if ((scb[1] & 0x8)) + data[3] = 0; + else { + data[3] = 8; + len += 8; + *(u32 *)(data + 4) = (cmnd->lun->blk_cnt >> 32) ? + cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt); + *(u32 *)(data + 8) = cpu_to_be32(1 << cmnd->lun->blk_shift); + } + + switch (pcode) { + case 0x0: + break; + case 0x2: + len += insert_disconnect_pg(data + len); + break; + case 0x3: + len += insert_format_m_pg(data + len); + break; + case 0x4: + len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt); + break; + case 0x8: + len += insert_caching_pg(data + len, LUWCache(cmnd->lun), + LURCache(cmnd->lun)); + break; + case 0xa: + len += insert_ctrl_m_pg(data + len); + break; + case 0x1c: + len += insert_iec_m_pg(data + len); + break; + case 0x3f: + len += insert_disconnect_pg(data + len); + len += insert_format_m_pg(data + len); + len += insert_geo_m_pg(data + len, cmnd->lun->blk_cnt); + len += insert_caching_pg(data + len, LUWCache(cmnd->lun), + LURCache(cmnd->lun)); + len += insert_ctrl_m_pg(data + len); + len += insert_iec_m_pg(data + len); + break; + default: + err = -1; + } + + data[0] = len - 1; + + tio_set(tio, len, 0); + + return err; +} + +static int build_inquiry_response(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct tio *tio = cmnd->tio; + u8 *data; + u8 *scb = req->scb; + int err = -1; + + /* + * - CmdDt and EVPD both set or EVPD and Page Code set: illegal + * - CmdDt set: not supported + */ + if ((scb[1] & 0x3) > 0x1 || (!(scb[1] & 0x3) && scb[2])) + return err; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + + if (!(scb[1] & 0x3)) { + data[2] = 4; + data[3] = 0x52; + data[4] = 59; + data[7] = 0x02; + memset(data + 8, 0x20, 28); + memcpy(data + 8, + VENDOR_ID, min_t(size_t, strlen(VENDOR_ID), 8)); + memcpy(data + 16, + PRODUCT_ID, min_t(size_t, strlen(PRODUCT_ID), 16)); + memcpy(data + 32, + PRODUCT_REV, min_t(size_t, strlen(PRODUCT_REV), 4)); + data[58] = 0x03; + data[59] = 0x20; + data[60] = 0x09; + data[61] = 0x60; + data[62] = 0x03; + data[63] = 0x00; + tio_set(tio, 64, 0); + err = 0; + } else if (scb[1] & 0x1) { + /* EVPD bit set */ + if (scb[2] == 0x0) { + data[1] = 0x0; + data[3] = 3; + data[4] = 0x0; + data[5] = 0x80; + data[6] = 0x83; + tio_set(tio, 7, 0); + err = 0; + } else if (scb[2] == 0x80) { + int len = (cmnd->lun && strlen(cmnd->lun->scsi_sn)) ? + SCSI_SN_LEN : 4; + + data[1] = 0x80; + data[3] = len; + memset(data + 4, 0x20, len); + tio_set(tio, len + 4, 0); + err = 0; + + if (len == SCSI_SN_LEN) { + char *p, *q; + + p = data + 4 + len - 1; + q = cmnd->lun->scsi_sn + len - 1; + + for (; len > 0; len--, q--) + if (isascii(*q) && isprint(*q)) + *(p--) = *q; + } + } else if (scb[2] == 0x83) { + u32 len = SCSI_ID_LEN * sizeof(u8); + + data[1] = 0x83; + data[3] = len + 4; + data[4] = 0x1; + data[5] = 0x1; + data[7] = len; + if (cmnd->lun) /* We need this ? */ + memcpy(data + 8, cmnd->lun->scsi_id, len); + tio_set(tio, len + 8, 0); + err = 0; + } + } + + tio_set(tio, min_t(u8, tio->size, scb[4]), 0); + if (!cmnd->lun) + data[0] = TYPE_NO_LUN; + + return err; +} + +static int build_report_luns_response(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + struct tio *tio = cmnd->tio; + u32 *data, size, len; + struct iet_volume *lun; + int rest, idx = 0; + + size = (u32)req->scb[6] << 24 | (u32)req->scb[7] << 16 | + (u32)req->scb[8] << 8 | (u32)req->scb[9]; + if (size < 16) + return -1; + + len = atomic_read(&cmnd->conn->session->target->nr_volumes) * 8; + size = min(size & ~(8 - 1), len + 8); + + assert(!tio); + tio = cmnd->tio = tio_alloc(get_pgcnt(size, 0)); + tio_set(tio, size, 0); + + data = page_address(tio->pvec[idx]); + assert(data); + *data++ = cpu_to_be32(len); + *data++ = 0; + size -= 8; + rest = PAGE_CACHE_SIZE - 8; + list_for_each_entry(lun, &cmnd->conn->session->target->volumes, list) { + if (lun->l_state != IDEV_RUNNING) + continue; + + *data++ = cpu_to_be32((0x3ff & lun->lun) << 16 | + ((lun->lun > 0xff) ? (0x1 << 30) : 0)); + *data++ = 0; + if ((size -= 8) == 0) + break; + if ((rest -= 8) == 0) { + idx++; + data = page_address(tio->pvec[idx]); + rest = PAGE_CACHE_SIZE; + } + } + + return 0; +} + +static int build_read_capacity_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + u32 *data; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + + data[0] = (cmnd->lun->blk_cnt >> 32) ? + cpu_to_be32(0xffffffff) : cpu_to_be32(cmnd->lun->blk_cnt - 1); + data[1] = cpu_to_be32(1U << cmnd->lun->blk_shift); + + tio_set(tio, 8, 0); + return 0; +} + +static int build_request_sense_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + u8 *data; + + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + memset(data, 0, 18); + data[0] = 0xf0; + data[1] = 0; + data[2] = NO_SENSE; + data[7] = 10; + tio_set(tio, 18, 0); + + return 0; +} + +static int build_service_action_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + u32 *data; + u64 *data64; + +/* assert((req->scb[1] & 0x1f) == 0x10); */ + assert(!tio); + tio = cmnd->tio = tio_alloc(1); + data = page_address(tio->pvec[0]); + assert(data); + clear_page(data); + data64 = (u64*) data; + data64[0] = cpu_to_be64(cmnd->lun->blk_cnt - 1); + data[2] = cpu_to_be32(1UL << cmnd->lun->blk_shift); + + tio_set(tio, 12, 0); + return 0; +} + +static int build_read_response(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + + assert(tio); + assert(cmnd->lun); + + return tio_read(cmnd->lun, tio); +} + +static int build_write_response(struct iscsi_cmnd *cmnd) +{ + int err; + struct tio *tio = cmnd->tio; + + assert(tio); + assert(cmnd->lun); + + list_del_init(&cmnd->list); + err = tio_write(cmnd->lun, tio); + if (!err && !LUWCache(cmnd->lun)) + err = tio_sync(cmnd->lun, tio); + + return err; +} + +static int build_sync_cache_response(struct iscsi_cmnd *cmnd) +{ + assert(cmnd->lun); + return tio_sync(cmnd->lun, NULL); +} + +static int build_generic_response(struct iscsi_cmnd *cmnd) +{ + return 0; +} + +static int build_reserve_response(struct iscsi_cmnd *cmnd) +{ + return volume_reserve(cmnd->lun, cmnd->conn->session->sid); +} + +static int build_release_response(struct iscsi_cmnd *cmnd) +{ + return volume_release(cmnd->lun, + cmnd->conn->session->sid, 0); +} + +static int build_reservation_conflict_response(struct iscsi_cmnd *cmnd) +{ + return -EBUSY; +} + +static int disk_execute_cmnd(struct iscsi_cmnd *cmnd) +{ + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + + req->opcode &= ISCSI_OPCODE_MASK; + + if (is_volume_reserved(cmnd->lun, + cmnd->conn->session->sid)) { + switch (req->scb[0]) { + case INQUIRY: + case RELEASE: + case REPORT_LUNS: + case REQUEST_SENSE: + /* allowed commands when reserved */ + break; + default: + /* return reservation conflict for all others */ + send_scsi_rsp(cmnd, + build_reservation_conflict_response); + return 0; + } + } + + switch (req->scb[0]) { + case INQUIRY: + send_data_rsp(cmnd, build_inquiry_response); + break; + case REPORT_LUNS: + send_data_rsp(cmnd, build_report_luns_response); + break; + case READ_CAPACITY: + send_data_rsp(cmnd, build_read_capacity_response); + break; + case MODE_SENSE: + send_data_rsp(cmnd, build_mode_sense_response); + break; + case REQUEST_SENSE: + send_data_rsp(cmnd, build_request_sense_response); + break; + case SERVICE_ACTION_IN: + send_data_rsp(cmnd, build_service_action_response); + break; + case READ_6: + case READ_10: + case READ_16: + send_data_rsp(cmnd, build_read_response); + break; + case WRITE_6: + case WRITE_10: + case WRITE_16: + case WRITE_VERIFY: + send_scsi_rsp(cmnd, build_write_response); + break; + case SYNCHRONIZE_CACHE: + send_scsi_rsp(cmnd, build_sync_cache_response); + break; + case RESERVE: + send_scsi_rsp(cmnd, build_reserve_response); + break; + case RELEASE: + send_scsi_rsp(cmnd, build_release_response); + break; + case START_STOP: + case TEST_UNIT_READY: + case VERIFY: + case VERIFY_16: + send_scsi_rsp(cmnd, build_generic_response); + break; + default: + eprintk("%s\n", "we should not come here!"); + break; + } + + return 0; +} + +struct target_type disk_ops = +{ + .id = 0, + .execute_cmnd = disk_execute_cmnd, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi.h +++ linux-2.6.28/ubuntu/iscsitarget/iscsi.h @@ -0,0 +1,456 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef __ISCSI_H__ +#define __ISCSI_H__ + +#include +#include +#include +#include +#include +#include + +#include "iscsi_hdr.h" +#include "iet_u.h" + +struct iscsi_sess_param { + int initial_r2t; + int immediate_data; + int max_connections; + int max_recv_data_length; + int max_xmit_data_length; + int max_burst_length; + int first_burst_length; + int default_wait_time; + int default_retain_time; + int max_outstanding_r2t; + int data_pdu_inorder; + int data_sequence_inorder; + int error_recovery_level; + int header_digest; + int data_digest; + int ofmarker; + int ifmarker; + int ofmarkint; + int ifmarkint; +}; + +struct iscsi_trgt_param { + int wthreads; + int target_type; + int queued_cmnds; +}; + +struct tio { + u32 pg_cnt; + + pgoff_t idx; + u32 offset; + u32 size; + + struct page **pvec; + + atomic_t count; +}; + +struct network_thread_info { + struct task_struct *task; + unsigned long flags; + struct list_head active_conns; + + spinlock_t nthread_lock; + + void (*old_state_change)(struct sock *); + void (*old_data_ready)(struct sock *, int); + void (*old_write_space)(struct sock *); +}; + +struct worker_thread_info; + +struct worker_thread { + struct task_struct *w_task; + struct list_head w_list; + struct worker_thread_info *w_info; +}; + +struct worker_thread_info { + spinlock_t wthread_lock; + + u32 nr_running_wthreads; + + struct list_head wthread_list; + struct list_head work_queue; + + wait_queue_head_t wthread_sleep; +}; + +struct iscsi_cmnd; + +struct target_type { + int id; + int (*execute_cmnd) (struct iscsi_cmnd *); +}; + +enum iscsi_device_state { + IDEV_RUNNING, + IDEV_DEL, +}; + +struct iscsi_target { + struct list_head t_list; + u32 tid; + + char name[ISCSI_NAME_LEN]; + + struct iscsi_sess_param sess_param; + struct iscsi_trgt_param trgt_param; + + atomic_t nr_volumes; + struct list_head volumes; + struct list_head session_list; + + struct network_thread_info nthread_info; + struct worker_thread_info wthread_info; + + struct semaphore target_sem; +}; + +struct iscsi_queue { + spinlock_t queue_lock; + struct iscsi_cmnd *ordered_cmnd; + struct list_head wait_list; + int active_cnt; +}; + +struct iet_volume { + u32 lun; + + enum iscsi_device_state l_state; + atomic_t l_count; + + struct iscsi_target *target; + struct list_head list; + + struct iscsi_queue queue; + + u8 scsi_id[SCSI_ID_LEN]; + u8 scsi_sn[SCSI_SN_LEN]; + + u32 blk_shift; + u64 blk_cnt; + + u64 reserve_sid; + spinlock_t reserve_lock; + + unsigned long flags; + + struct iotype *iotype; + void *private; +}; + +enum lu_flags { + LU_READONLY, + LU_WCACHE, + LU_RCACHE, +}; + +#define LUReadonly(lu) test_bit(LU_READONLY, &(lu)->flags) +#define SetLUReadonly(lu) set_bit(LU_READONLY, &(lu)->flags) + +#define LUWCache(lu) test_bit(LU_WCACHE, &(lu)->flags) +#define SetLUWCache(lu) set_bit(LU_WCACHE, &(lu)->flags) +#define ClearLUWCache(lu) clear_bit(LU_WCACHE, &(lu)->flags) + +#define LURCache(lu) test_bit(LU_RCACHE, &(lu)->flags) +#define SetLURCache(lu) set_bit(LU_RCACHE, &(lu)->flags) +#define ClearLURCache(lu) clear_bit(LU_RCACHE, &(lu)->flags) + +#define IET_HASH_ORDER 8 +#define cmnd_hashfn(itt) hash_long((itt), IET_HASH_ORDER) + +struct iscsi_session { + struct list_head list; + struct iscsi_target *target; + + char *initiator; + u64 sid; + + u32 exp_cmd_sn; + u32 max_cmd_sn; + + struct iscsi_sess_param param; + u32 max_queued_cmnds; + + struct list_head conn_list; + + struct list_head pending_list; + + spinlock_t cmnd_hash_lock; + struct list_head cmnd_hash[1 << IET_HASH_ORDER]; + + u32 next_ttt; +}; + +enum connection_state_bit { + CONN_ACTIVE, + CONN_CLOSING, + CONN_WSPACE_WAIT, +}; + +#define ISCSI_CONN_IOV_MAX (((256 << 10) >> PAGE_SHIFT) + 1) + +struct iscsi_conn { + struct list_head list; /* list entry in session list */ + struct iscsi_session *session; /* owning session */ + + u16 cid; + unsigned long state; + + u32 stat_sn; + u32 exp_stat_sn; + + int hdigest_type; + int ddigest_type; + + struct list_head poll_list; + + struct file *file; + struct socket *sock; + spinlock_t list_lock; + atomic_t nr_cmnds; + atomic_t nr_busy_cmnds; + struct list_head pdu_list; /* in/outcoming pdus */ + struct list_head write_list; /* list of data pdus to be sent */ + + struct iscsi_cmnd *read_cmnd; + struct msghdr read_msg; + struct iovec read_iov[ISCSI_CONN_IOV_MAX]; + u32 read_size; + u32 read_overflow; + int read_state; + + struct iscsi_cmnd *write_cmnd; + struct iovec write_iov[ISCSI_CONN_IOV_MAX]; + struct iovec *write_iop; + struct tio *write_tcmnd; + u32 write_size; + u32 write_offset; + int write_state; + + struct hash_desc rx_hash; + struct hash_desc tx_hash; + struct scatterlist hash_sg[ISCSI_CONN_IOV_MAX]; +}; + +struct iscsi_pdu { + struct iscsi_hdr bhs; + void *ahs; + unsigned int ahssize; + unsigned int datasize; +}; + +typedef void (iet_show_info_t)(struct seq_file *seq, struct iscsi_target *target); + +struct iscsi_cmnd { + struct list_head list; + struct list_head conn_list; + unsigned long flags; + struct iscsi_conn *conn; + struct iet_volume *lun; + + struct iscsi_pdu pdu; + struct list_head pdu_list; + + struct list_head hash_list; + + struct tio *tio; + + u32 r2t_sn; + u32 r2t_length; + u32 is_unsolicited_data; + u32 target_task_tag; + u32 outstanding_r2t; + + u32 hdigest; + u32 ddigest; + + struct iscsi_cmnd *req; +}; + +#define ISCSI_OP_SCSI_REJECT ISCSI_OP_VENDOR1_CMD +#define ISCSI_OP_PDU_REJECT ISCSI_OP_VENDOR2_CMD +#define ISCSI_OP_DATA_REJECT ISCSI_OP_VENDOR3_CMD +#define ISCSI_OP_SCSI_ABORT ISCSI_OP_VENDOR4_CMD + +/* iscsi.c */ +extern struct iscsi_cmnd *cmnd_alloc(struct iscsi_conn *, int); +extern void cmnd_rx_start(struct iscsi_cmnd *); +extern void cmnd_rx_end(struct iscsi_cmnd *); +extern void cmnd_tx_start(struct iscsi_cmnd *); +extern void cmnd_tx_end(struct iscsi_cmnd *); +extern void cmnd_release(struct iscsi_cmnd *, int); +extern void send_data_rsp(struct iscsi_cmnd *, int (*)(struct iscsi_cmnd *)); +extern void send_scsi_rsp(struct iscsi_cmnd *, int (*)(struct iscsi_cmnd *)); + +/* conn.c */ +extern struct iscsi_conn *conn_lookup(struct iscsi_session *, u16); +extern int conn_add(struct iscsi_session *, struct conn_info *); +extern int conn_del(struct iscsi_session *, struct conn_info *); +extern int conn_free(struct iscsi_conn *); +extern void conn_close(struct iscsi_conn *); +extern void conn_info_show(struct seq_file *, struct iscsi_session *); + +/* nthread.c */ +extern int nthread_init(struct iscsi_target *); +extern int nthread_start(struct iscsi_target *); +extern int nthread_stop(struct iscsi_target *); +extern void __nthread_wakeup(struct network_thread_info *); +extern void nthread_wakeup(struct iscsi_target *); + +/* wthread.c */ +extern int wthread_init(struct iscsi_target *); +extern int wthread_start(struct iscsi_target *); +extern int wthread_stop(struct iscsi_target *); +extern void wthread_queue(struct iscsi_cmnd *); +extern struct target_type *target_type_array[]; + +/* target.c */ +extern int target_lock(struct iscsi_target *, int); +extern void target_unlock(struct iscsi_target *); +struct iscsi_target *target_lookup_by_id(u32); +extern int target_add(struct target_info *); +extern int target_del(u32 id); + +/* config.c */ +extern int iet_procfs_init(void); +extern void iet_procfs_exit(void); +extern int iet_info_show(struct seq_file *, iet_show_info_t *); + +/* session.c */ +extern struct file_operations session_seq_fops; +extern struct iscsi_session *session_lookup(struct iscsi_target *, u64); +extern int session_add(struct iscsi_target *, struct session_info *); +extern int session_del(struct iscsi_target *, u64); + +/* volume.c */ +extern struct file_operations volume_seq_fops; +extern int volume_add(struct iscsi_target *, struct volume_info *); +extern int iscsi_volume_del(struct iscsi_target *, struct volume_info *); +extern void iscsi_volume_destroy(struct iet_volume *); +extern struct iet_volume *volume_lookup(struct iscsi_target *, u32); +extern struct iet_volume *volume_get(struct iscsi_target *, u32); +extern void volume_put(struct iet_volume *); +extern int volume_reserve(struct iet_volume *volume, u64 sid); +extern int volume_release(struct iet_volume *volume, u64 sid, int force); +extern int is_volume_reserved(struct iet_volume *volume, u64 sid); + +/* tio.c */ +extern int tio_init(void); +extern void tio_exit(void); +extern struct tio *tio_alloc(int); +extern void tio_get(struct tio *); +extern void tio_put(struct tio *); +extern void tio_set(struct tio *, u32, loff_t); +extern int tio_read(struct iet_volume *, struct tio *); +extern int tio_write(struct iet_volume *, struct tio *); +extern int tio_sync(struct iet_volume *, struct tio *); + +/* iotype.c */ +extern struct iotype *get_iotype(const char *name); +extern void put_iotype(struct iotype *iot); + +/* params.c */ +extern int iscsi_param_set(struct iscsi_target *, struct iscsi_param_info *, int); + +/* target_disk.c */ +extern struct target_type disk_ops; + +/* event.c */ +extern int event_send(u32, u64, u32, u32, int); +extern int event_init(void); +extern void event_exit(void); + +#define get_pgcnt(size, offset) ((((size) + ((offset) & ~PAGE_CACHE_MASK)) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) + +static inline void iscsi_cmnd_get_length(struct iscsi_pdu *pdu) +{ +#if defined(__BIG_ENDIAN) + pdu->ahssize = pdu->bhs.length.ahslength * 4; + pdu->datasize = pdu->bhs.length.datalength; +#elif defined(__LITTLE_ENDIAN) + pdu->ahssize = (pdu->bhs.length & 0xff) * 4; + pdu->datasize = be32_to_cpu(pdu->bhs.length & ~0xff); +#else +#error +#endif +} + +static inline void iscsi_cmnd_set_length(struct iscsi_pdu *pdu) +{ +#if defined(__BIG_ENDIAN) + pdu->bhs.length.ahslength = pdu->ahssize / 4; + pdu->bhs.length.datalength = pdu->datasize; +#elif defined(__LITTLE_ENDIAN) + pdu->bhs.length = cpu_to_be32(pdu->datasize) | (pdu->ahssize / 4); +#else +#error +#endif +} + +#define cmnd_hdr(cmnd) ((struct iscsi_scsi_cmd_hdr *) (&((cmnd)->pdu.bhs))) +#define cmnd_ttt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.ttt) +#define cmnd_itt(cmnd) cpu_to_be32((cmnd)->pdu.bhs.itt) +#define cmnd_opcode(cmnd) ((cmnd)->pdu.bhs.opcode & ISCSI_OPCODE_MASK) +#define cmnd_scsicode(cmnd) cmnd_hdr(cmnd)->scb[0] + +#define SECTOR_SIZE_BITS 9 + +enum cmnd_flags { + CMND_hashed, + CMND_queued, + CMND_final, + CMND_waitio, + CMND_close, + CMND_lunit, + CMND_pending, + CMND_tmfabort, + CMND_rxstart, +}; + +#define set_cmnd_hashed(cmnd) set_bit(CMND_hashed, &(cmnd)->flags) +#define cmnd_hashed(cmnd) test_bit(CMND_hashed, &(cmnd)->flags) + +#define set_cmnd_queued(cmnd) set_bit(CMND_queued, &(cmnd)->flags) +#define cmnd_queued(cmnd) test_bit(CMND_queued, &(cmnd)->flags) + +#define set_cmnd_final(cmnd) set_bit(CMND_final, &(cmnd)->flags) +#define cmnd_final(cmnd) test_bit(CMND_final, &(cmnd)->flags) + +#define set_cmnd_waitio(cmnd) set_bit(CMND_waitio, &(cmnd)->flags) +#define cmnd_waitio(cmnd) test_bit(CMND_waitio, &(cmnd)->flags) + +#define set_cmnd_close(cmnd) set_bit(CMND_close, &(cmnd)->flags) +#define cmnd_close(cmnd) test_bit(CMND_close, &(cmnd)->flags) + +#define set_cmnd_lunit(cmnd) set_bit(CMND_lunit, &(cmnd)->flags) +#define cmnd_lunit(cmnd) test_bit(CMND_lunit, &(cmnd)->flags) + +#define set_cmnd_pending(cmnd) set_bit(CMND_pending, &(cmnd)->flags) +#define clear_cmnd_pending(cmnd) clear_bit(CMND_pending, &(cmnd)->flags) +#define cmnd_pending(cmnd) test_bit(CMND_pending, &(cmnd)->flags) + +#define set_cmnd_tmfabort(cmnd) set_bit(CMND_tmfabort, &(cmnd)->flags) +#define cmnd_tmfabort(cmnd) test_bit(CMND_tmfabort, &(cmnd)->flags) + +#define set_cmnd_rxstart(cmnd) set_bit(CMND_rxstart, &(cmnd)->flags) +#define cmnd_rxstart(cmnd) test_bit(CMND_rxstart, &(cmnd)->flags) + +#define VENDOR_ID "IET" +#define PRODUCT_ID "VIRTUAL-DISK" +#define PRODUCT_REV "0" + +#endif /* __ISCSI_H__ */ --- linux-2.6.28.orig/ubuntu/iscsitarget/nthread.c +++ linux-2.6.28/ubuntu/iscsitarget/nthread.c @@ -0,0 +1,731 @@ +/* + * Network thread. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "digest.h" + +enum daemon_state_bit { + D_ACTIVE, + D_DATA_READY, +}; + +void __nthread_wakeup(struct network_thread_info *info) +{ + set_bit(D_DATA_READY, &info->flags); + wake_up_process(info->task); +} + +void nthread_wakeup(struct iscsi_target *target) +{ + struct network_thread_info *info = &target->nthread_info; + + spin_lock_bh(&info->nthread_lock); + __nthread_wakeup(info); + spin_unlock_bh(&info->nthread_lock); +} + +static inline void iscsi_conn_init_read(struct iscsi_conn *conn, void *data, size_t len) +{ + len = (len + 3) & -4; // XXX ??? + conn->read_iov[0].iov_base = data; + conn->read_iov[0].iov_len = len; + conn->read_msg.msg_iov = conn->read_iov; + conn->read_msg.msg_iovlen = 1; + conn->read_size = (len + 3) & -4; +} + +static void iscsi_conn_read_ahs(struct iscsi_conn *conn, struct iscsi_cmnd *cmnd) +{ + cmnd->pdu.ahs = kmalloc(cmnd->pdu.ahssize, __GFP_NOFAIL|GFP_KERNEL); + assert(cmnd->pdu.ahs); + iscsi_conn_init_read(conn, cmnd->pdu.ahs, cmnd->pdu.ahssize); +} + +static struct iscsi_cmnd * iscsi_get_send_cmnd(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd = NULL; + + spin_lock(&conn->list_lock); + if (!list_empty(&conn->write_list)) { + cmnd = list_entry(conn->write_list.next, struct iscsi_cmnd, list); + list_del_init(&cmnd->list); + } + spin_unlock(&conn->list_lock); + + return cmnd; +} + +static int is_data_available(struct iscsi_conn *conn) +{ + int avail, res; + mm_segment_t oldfs; + struct socket *sock = conn->sock; + + oldfs = get_fs(); + set_fs(get_ds()); + res = sock->ops->ioctl(sock, SIOCINQ, (unsigned long) &avail); + set_fs(oldfs); + return (res >= 0) ? avail : res; +} + +static void forward_iov(struct msghdr *msg, int len) +{ + while (msg->msg_iov->iov_len <= len) { + len -= msg->msg_iov->iov_len; + msg->msg_iov++; + msg->msg_iovlen--; + } + + msg->msg_iov->iov_base = (char *) msg->msg_iov->iov_base + len; + msg->msg_iov->iov_len -= len; +} + +static int do_recv(struct iscsi_conn *conn, int state) +{ + mm_segment_t oldfs; + struct msghdr msg; + struct iovec iov[ISCSI_CONN_IOV_MAX]; + int i, len, res; + + if (!test_bit(CONN_ACTIVE, &conn->state)) { + res = -EIO; + goto out; + } + + if (is_data_available(conn) <= 0) { + res = -EAGAIN; + goto out; + } + + msg.msg_iov = iov; + msg.msg_iovlen = min_t(size_t, conn->read_msg.msg_iovlen, ISCSI_CONN_IOV_MAX); + for (i = 0, len = 0; i < msg.msg_iovlen; i++) { + iov[i] = conn->read_msg.msg_iov[i]; + len += iov[i].iov_len; + } + + oldfs = get_fs(); + set_fs(get_ds()); + res = sock_recvmsg(conn->sock, &msg, len, MSG_DONTWAIT | MSG_NOSIGNAL); + set_fs(oldfs); + + if (res <= 0) { + switch (res) { + case -EAGAIN: + case -ERESTARTSYS: + break; + default: + eprintk("%d\n", res); + conn_close(conn); + break; + } + } else { + conn->read_size -= res; + if (conn->read_size) + forward_iov(&conn->read_msg, res); + else + conn->read_state = state; + } + +out: + dprintk(D_IOD, "%d\n", res); + + return res; +} + +enum rx_state { + RX_INIT_BHS, /* Must be zero. */ + RX_BHS, + + RX_INIT_AHS, + RX_AHS, + + RX_INIT_HDIGEST, + RX_HDIGEST, + RX_CHECK_HDIGEST, + + RX_INIT_DATA, + RX_DATA, + + RX_INIT_DDIGEST, + RX_DDIGEST, + RX_CHECK_DDIGEST, + + RX_END, +}; + +static void rx_ddigest(struct iscsi_conn *conn, int state) +{ + struct iscsi_cmnd *cmnd = conn->read_cmnd; + int res = digest_rx_data(cmnd); + + if (!res) + conn->read_state = state; + else + conn_close(conn); +} + +static void rx_hdigest(struct iscsi_conn *conn, int state) +{ + struct iscsi_cmnd *cmnd = conn->read_cmnd; + int res = digest_rx_header(cmnd); + + if (!res) + conn->read_state = state; + else + conn_close(conn); +} + +static struct iscsi_cmnd *create_cmnd(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd; + + cmnd = cmnd_alloc(conn, 1); + iscsi_conn_init_read(cmnd->conn, &cmnd->pdu.bhs, sizeof(cmnd->pdu.bhs)); + conn->read_state = RX_BHS; + + return cmnd; +} + +static int recv(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd = conn->read_cmnd; + int hdigest, ddigest, res = 1; + + if (!test_bit(CONN_ACTIVE, &conn->state)) + return -EIO; + + hdigest = conn->hdigest_type & DIGEST_NONE ? 0 : 1; + ddigest = conn->ddigest_type & DIGEST_NONE ? 0 : 1; + + switch (conn->read_state) { + case RX_INIT_BHS: + assert(!cmnd); + cmnd = conn->read_cmnd = create_cmnd(conn); + case RX_BHS: + res = do_recv(conn, RX_INIT_AHS); + if (res <= 0 || conn->read_state != RX_INIT_AHS) + break; + case RX_INIT_AHS: + iscsi_cmnd_get_length(&cmnd->pdu); + if (cmnd->pdu.ahssize) { + iscsi_conn_read_ahs(conn, cmnd); + conn->read_state = RX_AHS; + } else + conn->read_state = hdigest ? RX_INIT_HDIGEST : RX_INIT_DATA; + + if (conn->read_state != RX_AHS) + break; + case RX_AHS: + res = do_recv(conn, hdigest ? RX_INIT_HDIGEST : RX_INIT_DATA); + if (res <= 0 || conn->read_state != RX_INIT_HDIGEST) + break; + case RX_INIT_HDIGEST: + iscsi_conn_init_read(conn, &cmnd->hdigest, sizeof(u32)); + conn->read_state = RX_HDIGEST; + case RX_HDIGEST: + res = do_recv(conn, RX_CHECK_HDIGEST); + if (res <= 0 || conn->read_state != RX_CHECK_HDIGEST) + break; + case RX_CHECK_HDIGEST: + rx_hdigest(conn, RX_INIT_DATA); + if (conn->read_state != RX_INIT_DATA) + break; + case RX_INIT_DATA: + cmnd_rx_start(cmnd); + conn->read_state = cmnd->pdu.datasize ? RX_DATA : RX_END; + if (conn->read_state != RX_DATA) + break; + case RX_DATA: + res = do_recv(conn, ddigest ? RX_INIT_DDIGEST : RX_END); + if (res <= 0 || conn->read_state != RX_INIT_DDIGEST) + break; + case RX_INIT_DDIGEST: + iscsi_conn_init_read(conn, &cmnd->ddigest, sizeof(u32)); + conn->read_state = RX_DDIGEST; + case RX_DDIGEST: + res = do_recv(conn, RX_CHECK_DDIGEST); + if (res <= 0 || conn->read_state != RX_CHECK_DDIGEST) + break; + case RX_CHECK_DDIGEST: + rx_ddigest(conn, RX_END); + break; + default: + eprintk("%d %d %x\n", res, conn->read_state, cmnd_opcode(cmnd)); + assert(0); + } + + if (res <= 0) + return res; + + if (conn->read_state != RX_END) + return res; + + if (conn->read_size) { + eprintk("%d %x %d\n", res, cmnd_opcode(cmnd), conn->read_size); + assert(0); + } + + cmnd_rx_end(cmnd); + if (conn->read_size) { + eprintk("%x %d\n", cmnd_opcode(cmnd), conn->read_size); + conn->read_state = RX_DATA; + return 1; + } + + conn->read_cmnd = NULL; + conn->read_state = RX_INIT_BHS; + + return 0; +} + +/* + * @locking: grabs the target's nthread_lock to protect it from races with + * iet_write_space() + */ +static void set_conn_wspace_wait(struct iscsi_conn *conn) +{ + struct network_thread_info *info = &conn->session->target->nthread_info; + struct sock *sk = conn->sock->sk; + + spin_lock_bh(&info->nthread_lock); + + if (sk_stream_wspace(sk) < sk_stream_min_wspace(sk)) + set_bit(CONN_WSPACE_WAIT, &conn->state); + + spin_unlock_bh(&info->nthread_lock); +} + +/* This is taken from the Ardis code. */ +static int write_data(struct iscsi_conn *conn) +{ + mm_segment_t oldfs; + struct file *file; + struct socket *sock; + ssize_t (*sendpage)(struct socket *, struct page *, int, size_t, int); + struct tio *tio; + struct iovec *iop; + int saved_size, size, sendsize; + int offset, idx; + int flags, res; + + file = conn->file; + saved_size = size = conn->write_size; + iop = conn->write_iop; + + if (iop) while (1) { + loff_t off = 0; + unsigned long count; + struct iovec *vec; + int rest; + + vec = iop; + for (count = 0; vec->iov_len; count++, vec++) + ; + oldfs = get_fs(); + set_fs(KERNEL_DS); + res = vfs_writev(file, (struct iovec __user *) iop, count, &off); + set_fs(oldfs); + dprintk(D_DATA, "%#Lx:%u: %d(%ld)\n", + (unsigned long long) conn->session->sid, conn->cid, + res, (long) iop->iov_len); + if (unlikely(res <= 0)) { + if (res == -EAGAIN || res == -EINTR) { + conn->write_iop = iop; + goto out_iov; + } + goto err; + } + + rest = res; + size -= res; + while (iop->iov_len <= rest && rest) { + rest -= iop->iov_len; + iop++; + } + iop->iov_base += rest; + iop->iov_len -= rest; + + if (!iop->iov_len) { + conn->write_iop = NULL; + if (size) + break; + goto out_iov; + } + } + + if (!(tio = conn->write_tcmnd)) { + eprintk("%s\n", "warning data missing!"); + return 0; + } + offset = conn->write_offset; + idx = offset >> PAGE_CACHE_SHIFT; + offset &= ~PAGE_CACHE_MASK; + + sock = conn->sock; + sendpage = sock->ops->sendpage ? : sock_no_sendpage; + flags = MSG_DONTWAIT; + + while (1) { + sendsize = PAGE_CACHE_SIZE - offset; + if (size <= sendsize) { + res = sendpage(sock, tio->pvec[idx], offset, size, flags); + dprintk(D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)\n", + sock->ops->sendpage ? "sendpage" : "writepage", + (unsigned long long ) conn->session->sid, conn->cid, + res, tio->pvec[idx]->index, offset, size); + if (unlikely(res <= 0)) { + if (res == -EAGAIN || res == -EINTR) { + goto out; + } + goto err; + } + if (res == size) { + conn->write_tcmnd = NULL; + conn->write_size = 0; + return saved_size; + } + offset += res; + size -= res; + continue; + } + + res = sendpage(sock, tio->pvec[idx], offset,sendsize, flags | MSG_MORE); + dprintk(D_DATA, "%s %#Lx:%u: %d(%lu,%u,%u)\n", + sock->ops->sendpage ? "sendpage" : "writepage", + (unsigned long long ) conn->session->sid, conn->cid, + res, tio->pvec[idx]->index, offset, sendsize); + if (unlikely(res <= 0)) { + if (res == -EAGAIN || res == -EINTR) { + goto out; + } + goto err; + } + if (res == sendsize) { + idx++; + offset = 0; + } else + offset += res; + size -= res; + } + out: + conn->write_offset = (idx << PAGE_CACHE_SHIFT) + offset; + out_iov: + conn->write_size = size; + if (res == -EAGAIN) { + set_conn_wspace_wait(conn); + if (saved_size == size) + return res; + } + + return saved_size - size; + + err: + eprintk("error %d at %#Lx:%u\n", res, + (unsigned long long) conn->session->sid, conn->cid); + return res; +} + +static void exit_tx(struct iscsi_conn *conn, int res) +{ + if (res > 0) + return; + + switch (res) { + case -EAGAIN: + case -ERESTARTSYS: + break; + default: + eprintk("%d %d %d\n", conn->write_size, conn->write_state, res); + conn_close(conn); + break; + } +} + +static int tx_ddigest(struct iscsi_cmnd *cmnd, int state) +{ + int res, rest = cmnd->conn->write_size; + struct msghdr msg = {.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT}; + struct kvec iov; + + iov.iov_base = (char *) (&cmnd->ddigest) + (sizeof(u32) - rest); + iov.iov_len = rest; + + res = kernel_sendmsg(cmnd->conn->sock, &msg, &iov, 1, rest); + + if (res > 0) { + cmnd->conn->write_size -= res; + if (!cmnd->conn->write_size) + cmnd->conn->write_state = state; + } else + exit_tx(cmnd->conn, res); + + return res; +} + +static void init_tx_hdigest(struct iscsi_cmnd *cmnd) +{ + struct iscsi_conn *conn = cmnd->conn; + struct iovec *iop; + + if (conn->hdigest_type & DIGEST_NONE) + return; + + digest_tx_header(cmnd); + + for (iop = conn->write_iop; iop->iov_len; iop++) + ; + iop->iov_base = &(cmnd->hdigest); + iop->iov_len = sizeof(u32); + conn->write_size += sizeof(u32); + iop++; + iop->iov_len = 0; + + return; +} + +enum tx_state { + TX_INIT, /* Must be zero. */ + TX_BHS_DATA, + TX_INIT_DDIGEST, + TX_DDIGEST, + TX_END, +}; + +static int do_send(struct iscsi_conn *conn, int state) +{ + int res; + + res = write_data(conn); + + if (res > 0) { + if (!conn->write_size) + conn->write_state = state; + } else + exit_tx(conn, res); + + return res; +} + +static int send(struct iscsi_conn *conn) +{ + struct iscsi_cmnd *cmnd = conn->write_cmnd; + int ddigest, res = 0; + + ddigest = conn->ddigest_type != DIGEST_NONE ? 1 : 0; + + switch (conn->write_state) { + case TX_INIT: + assert(!cmnd); + cmnd = conn->write_cmnd = iscsi_get_send_cmnd(conn); + if (!cmnd) + return 0; + cmnd_tx_start(cmnd); + init_tx_hdigest(cmnd); + conn->write_state = TX_BHS_DATA; + case TX_BHS_DATA: + res = do_send(conn, ddigest && cmnd->pdu.datasize ? TX_INIT_DDIGEST : TX_END); + if (res <= 0 || conn->write_state != TX_INIT_DDIGEST) + break; + case TX_INIT_DDIGEST: + digest_tx_data(cmnd); + assert(!cmnd->conn->write_size); + cmnd->conn->write_size += sizeof(u32); + conn->write_state = TX_DDIGEST; + case TX_DDIGEST: + res = tx_ddigest(cmnd, TX_END); + break; + default: + eprintk("%d %d %x\n", res, conn->write_state, cmnd_opcode(cmnd)); + assert(0); + } + + if (res <= 0) + return res; + + if (conn->write_state != TX_END) + return res; + + if (conn->write_size) { + eprintk("%d %x %u\n", res, cmnd_opcode(cmnd), conn->write_size); + assert(!conn->write_size); + } + cmnd_tx_end(cmnd); + cmnd_release(cmnd, 0); + conn->write_cmnd = NULL; + conn->write_state = TX_INIT; + + return 0; +} + +static void process_io(struct iscsi_conn *conn) +{ + struct iscsi_target *target = conn->session->target; + int res, wakeup = 0; + + res = recv(conn); + + if (is_data_available(conn) > 0 || res > 0) + wakeup = 1; + + if (!test_bit(CONN_ACTIVE, &conn->state)) { + wakeup = 1; + goto out; + } + + if (test_bit(CONN_WSPACE_WAIT, &conn->state)) + goto out; + + res = send(conn); + + if (!list_empty(&conn->write_list) || conn->write_cmnd) + wakeup = 1; + +out: + if (wakeup) + nthread_wakeup(target); + + return; +} + +static void close_conn(struct iscsi_conn *conn) +{ + struct iscsi_session *session = conn->session; + struct iscsi_target *target = session->target; + struct iscsi_cmnd *cmnd; + + assert(conn); + + conn->sock->ops->shutdown(conn->sock, 2); + + write_lock_bh(&conn->sock->sk->sk_callback_lock); + conn->sock->sk->sk_state_change = target->nthread_info.old_state_change; + conn->sock->sk->sk_data_ready = target->nthread_info.old_data_ready; + conn->sock->sk->sk_write_space = target->nthread_info.old_write_space; + write_unlock_bh(&conn->sock->sk->sk_callback_lock); + + fput(conn->file); + conn->file = NULL; + conn->sock = NULL; + + while (atomic_read(&conn->nr_busy_cmnds)) + yield(); + + while (!list_empty(&conn->pdu_list)) { + cmnd = list_entry(conn->pdu_list.next, struct iscsi_cmnd, conn_list); + + list_del_init(&cmnd->list); + cmnd_release(cmnd, 1); + } + + if (atomic_read(&conn->nr_cmnds)) { + eprintk("%u\n", atomic_read(&conn->nr_cmnds)); + list_for_each_entry(cmnd, &conn->pdu_list, conn_list) + eprintk("%x %x\n", cmnd_opcode(cmnd), cmnd_itt(cmnd)); + assert(0); + } + + event_send(target->tid, session->sid, conn->cid, E_CONN_CLOSE, 0); + conn_free(conn); + + if (list_empty(&session->conn_list)) + session_del(target, session->sid); +} + +static int istd(void *arg) +{ + struct iscsi_target *target = arg; + struct network_thread_info *info = &target->nthread_info; + struct iscsi_conn *conn, *tmp; + + __set_current_state(TASK_RUNNING); + do { + spin_lock_bh(&info->nthread_lock); + __set_current_state(TASK_INTERRUPTIBLE); + + if (!test_bit(D_DATA_READY, &info->flags)) { + spin_unlock_bh(&info->nthread_lock); + schedule(); + spin_lock_bh(&info->nthread_lock); + } + __set_current_state(TASK_RUNNING); + clear_bit(D_DATA_READY, &info->flags); + spin_unlock_bh(&info->nthread_lock); + + target_lock(target, 0); + list_for_each_entry_safe(conn, tmp, &info->active_conns, poll_list) { + if (test_bit(CONN_ACTIVE, &conn->state)) + process_io(conn); + else + close_conn(conn); + } + target_unlock(target); + + } while (!kthread_should_stop()); + + return 0; +} + +int nthread_init(struct iscsi_target *target) +{ + struct network_thread_info *info = &target->nthread_info; + + info->flags = 0; + info->task = NULL; + + info->old_state_change = NULL; + info->old_data_ready = NULL; + info->old_write_space = NULL; + + INIT_LIST_HEAD(&info->active_conns); + + spin_lock_init(&info->nthread_lock); + + return 0; +} + +int nthread_start(struct iscsi_target *target) +{ + int err = 0; + struct network_thread_info *info = &target->nthread_info; + struct task_struct *task; + + if (info->task) { + eprintk("Target (%u) already runs\n", target->tid); + return -EALREADY; + } + + task = kthread_run(istd, target, "istd%d", target->tid); + + if (IS_ERR(task)) + err = PTR_ERR(task); + else + info->task = task; + + return err; +} + +int nthread_stop(struct iscsi_target *target) +{ + int err; + struct network_thread_info *info = &target->nthread_info; + + if (!info->task) + return -ESRCH; + + err = kthread_stop(info->task); + + if (!err) + info->task = NULL; + + return err; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/event.c +++ linux-2.6.28/ubuntu/iscsitarget/event.c @@ -0,0 +1,97 @@ +/* + * Event notification code. + * (C) 2005 FUJITA Tomonori + * This code is licenced under the GPL. + * + * Some functions are based on audit code. + */ + +#include +#include "iet_u.h" +#include "iscsi_dbg.h" + +static struct sock *nl; +static u32 ietd_pid; + +static int event_recv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +{ + u32 uid, pid, seq; + char *data; + + pid = NETLINK_CREDS(skb)->pid; + uid = NETLINK_CREDS(skb)->uid; + seq = nlh->nlmsg_seq; + data = NLMSG_DATA(nlh); + + ietd_pid = pid; + + return 0; +} + +static void event_recv_skb(struct sk_buff *skb) +{ + int err; + struct nlmsghdr *nlh; + u32 rlen; + + while (skb->len >= NLMSG_SPACE(0)) { + nlh = (struct nlmsghdr *)skb->data; + if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) + break; + rlen = NLMSG_ALIGN(nlh->nlmsg_len); + if (rlen > skb->len) + rlen = skb->len; + if ((err = event_recv_msg(skb, nlh))) { + netlink_ack(skb, nlh, -err); + } else if (nlh->nlmsg_flags & NLM_F_ACK) + netlink_ack(skb, nlh, 0); + skb_pull(skb, rlen); + } +} + +static int notify(void *data, int len, int gfp_mask) +{ + struct sk_buff *skb; + struct nlmsghdr *nlh; + static u32 seq = 0; + + if (!(skb = alloc_skb(NLMSG_SPACE(len), gfp_mask))) + return -ENOMEM; + + nlh = __nlmsg_put(skb, ietd_pid, seq++, NLMSG_DONE, len - sizeof(*nlh), 0); + + memcpy(NLMSG_DATA(nlh), data, len); + + return netlink_unicast(nl, skb, ietd_pid, 0); +} + +int event_send(u32 tid, u64 sid, u32 cid, u32 state, int atomic) +{ + int err; + struct iet_event event; + + event.tid = tid; + event.sid = sid; + event.cid = cid; + event.state = state; + + err = notify(&event, NLMSG_SPACE(sizeof(struct iet_event)), 0); + + return err; +} + +int event_init(void) +{ + nl = netlink_kernel_create(&init_net, NETLINK_IET, 1, event_recv_skb, + NULL, THIS_MODULE); + if (!nl) + return -ENOMEM; + else + return 0; +} + +void event_exit(void) +{ + if (nl) + sock_release(nl->sk_socket); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/Makefile +++ linux-2.6.28/ubuntu/iscsitarget/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for the Linux kernel device drivers. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile. + +EXTRA_CFLAGS += -I$(src)/include + +obj-m += iscsi_trgt.o +iscsi_trgt-objs := tio.o iscsi.o nthread.o wthread.o config.o digest.o \ + conn.o session.o target.o volume.o iotype.o \ + file-io.o null-io.o target_disk.o event.o param.o \ + block-io.o + --- linux-2.6.28.orig/ubuntu/iscsitarget/null-io.c +++ linux-2.6.28/ubuntu/iscsitarget/null-io.c @@ -0,0 +1,114 @@ +/* + * Target device null I/O. + * (C) 2005 MING Zhang + * This code is licenced under the GPL. + * + * The nullio mode will not return any meaningful or previous written + * data. It is only for performance measurement purpose. + */ + +#include +#include +#include +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +struct nullio_data { + u64 sectors; +}; + +enum { + Opt_sectors, Opt_ignore, Opt_err, +}; + +static match_table_t tokens = { + {Opt_sectors, "Sectors=%u"}, + {Opt_ignore, "Type=%s"}, + {Opt_err, NULL}, +}; + +static int parse_nullio_params(struct iet_volume *volume, char *params) +{ + int err = 0; + char *p, *q; + struct nullio_data *data = volume->private; + + while ((p = strsep(¶ms, ",")) != NULL) { + substring_t args[MAX_OPT_ARGS]; + int token; + if (!*p) + continue; + token = match_token(p, tokens, args); + switch (token) { + case Opt_sectors: + q = match_strdup(&args[0]); + if (!q) + return -ENOMEM; + data->sectors = simple_strtoull(q, NULL, 10); + kfree(q); + break; + case Opt_ignore: + break; + default: + eprintk("Unknown %s\n", p); + return -EINVAL; + break; + } + } + return err; +} + +static void nullio_detach(struct iet_volume *lu) +{ + struct nullio_data *p = lu->private; + + kfree(p); + lu->private = NULL; +} + +static int nullio_attach(struct iet_volume *lu, char *args) +{ + int err = 0; + struct nullio_data *p; + + if (lu->private) { + printk("already attached ? %d\n", lu->lun); + return -EBUSY; + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + lu->private = p; + + if ((err = parse_nullio_params(lu, args)) < 0) { + eprintk("%d\n", err); + goto out; + } + + lu->blk_shift = SECTOR_SIZE_BITS; + lu->blk_cnt = (p->sectors = p->sectors ? : 1 << 27); /* 64 GB */ + +out: + if (err < 0) + nullio_detach(lu); + return err; +} + +void nullio_show(struct iet_volume *lu, struct seq_file *seq) +{ + struct nullio_data *p = lu->private; + seq_printf(seq, " sectors:%llu\n", p->sectors); +} + +struct iotype nullio = +{ + .name = "nullio", + .attach = nullio_attach, + .detach = nullio_detach, + .show = nullio_show, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/wthread.c +++ linux-2.6.28/ubuntu/iscsitarget/wthread.c @@ -0,0 +1,189 @@ +/* + * Worker thread. + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" + +void wthread_queue(struct iscsi_cmnd *cmnd) +{ + struct worker_thread_info *info = &cmnd->conn->session->target->wthread_info; + + if (!list_empty(&cmnd->list)) { + struct iscsi_scsi_cmd_hdr *req = cmnd_hdr(cmnd); + eprintk("%x %p %x %x %x %x %lx %x\n", + cmnd_itt(cmnd), req, req->opcode, req->scb[0], cmnd->pdu.datasize, + be32_to_cpu(req->data_length), cmnd->flags, req->flags); + + if (cmnd->lun) + eprintk("%u\n", cmnd->lun->lun); + assert(list_empty(&cmnd->list)); + } + + spin_lock(&info->wthread_lock); + list_add_tail(&cmnd->list, &info->work_queue); + spin_unlock(&info->wthread_lock); + + atomic_inc(&cmnd->conn->nr_busy_cmnds); + + wake_up(&info->wthread_sleep); +} + +static struct iscsi_cmnd * get_ready_cmnd(struct worker_thread_info *info) +{ + struct iscsi_cmnd *cmnd = NULL; + + spin_lock(&info->wthread_lock); + if (!list_empty(&info->work_queue)) { + cmnd = list_entry(info->work_queue.next, struct iscsi_cmnd, list); + list_del_init(&cmnd->list); + + assert(cmnd->conn); + } + spin_unlock(&info->wthread_lock); + + return cmnd; +} + +static int cmnd_execute(struct iscsi_cmnd *cmnd) +{ + int type = cmnd->conn->session->target->trgt_param.target_type; + + assert(target_type_array[type]->execute_cmnd); + return target_type_array[type]->execute_cmnd(cmnd); +} + +static int worker_thread(void *arg) +{ + struct worker_thread *wt = (struct worker_thread *) arg; + struct worker_thread_info *info = wt->w_info; + struct iscsi_cmnd *cmnd; + struct iscsi_conn *conn; + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue(&info->wthread_sleep, &wait); + + __set_current_state(TASK_RUNNING); + do { + while (!list_empty(&info->work_queue) && + (cmnd = get_ready_cmnd(info))) { + conn = cmnd->conn; + cmnd_execute(cmnd); + assert(conn); + atomic_dec(&conn->nr_busy_cmnds); + } + + __set_current_state(TASK_INTERRUPTIBLE); + if (list_empty(&info->work_queue)) + schedule(); + + __set_current_state(TASK_RUNNING); + } while (!kthread_should_stop()); + + remove_wait_queue(&info->wthread_sleep, &wait); + + return 0; +} + +static int start_one_worker_thread(struct iscsi_target *target) +{ + struct worker_thread_info *info = &target->wthread_info; + struct worker_thread *wt; + struct task_struct *task; + + if (!(wt = kmalloc(sizeof(struct worker_thread), GFP_KERNEL))) + return -ENOMEM; + + wt->w_info = info; + task = kthread_create(worker_thread, wt, "istiod%d", target->tid); + if (IS_ERR(task)) { + kfree(wt); + return PTR_ERR(task); + } + + wt->w_task = task; + list_add(&wt->w_list, &info->wthread_list); + info->nr_running_wthreads++; + + wake_up_process(task); + + return 0; +} + +static int stop_one_worker_thread(struct worker_thread *wt) +{ + struct worker_thread_info *info = wt->w_info; + int err; + + assert(wt->w_task); + err = kthread_stop(wt->w_task); + + if (err < 0 && err != -EINTR) + return err; + + list_del(&wt->w_list); + kfree(wt); + info->nr_running_wthreads--; + + return 0; +} + +int wthread_init(struct iscsi_target *target) +{ + struct worker_thread_info *info = &target->wthread_info; + + spin_lock_init(&info->wthread_lock); + + info->nr_running_wthreads = 0; + + INIT_LIST_HEAD(&info->work_queue); + INIT_LIST_HEAD(&info->wthread_list); + + init_waitqueue_head(&info->wthread_sleep); + + return 0; +} + +int wthread_start(struct iscsi_target *target) +{ + int err = 0; + struct worker_thread_info *info = &target->wthread_info; + + while (info->nr_running_wthreads < target->trgt_param.wthreads) { + if ((err = start_one_worker_thread(target)) < 0) { + eprintk("Fail to create a worker thread %d\n", err); + goto out; + } + } + + while (info->nr_running_wthreads > target->trgt_param.wthreads) { + struct worker_thread *wt; + wt = list_entry(info->wthread_list.next, struct worker_thread, w_list); + if ((err = stop_one_worker_thread(wt)) < 0) { + eprintk("Fail to stop a worker thread %d\n", err); + break; + } + } +out: + return err; +} + +int wthread_stop(struct iscsi_target *target) +{ + struct worker_thread *wt, *tmp; + int err = 0; + struct worker_thread_info *info = &target->wthread_info; + + list_for_each_entry_safe(wt, tmp, &info->wthread_list, w_list) { + if ((err = stop_one_worker_thread(wt)) < 0) { + eprintk("Fail to stop a worker thread %d\n", err); + return err; + } + } + + return err; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/iotype.h +++ linux-2.6.28/ubuntu/iscsitarget/iotype.h @@ -0,0 +1,29 @@ +/* + * (C) 2004 - 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include "iscsi.h" + +#ifndef __IOTYPE_H__ +#define __IOTYPE_H__ + +struct iotype { + const char *name; + struct list_head iot_list; + + int (*attach)(struct iet_volume *dev, char *args); + int (*make_request)(struct iet_volume *dev, struct tio *tio, int rw); + int (*sync)(struct iet_volume *dev, struct tio *tio); + void (*detach)(struct iet_volume *dev); + void (*show)(struct iet_volume *dev, struct seq_file *seq); +}; + +extern struct iotype fileio; +extern struct iotype nullio; +extern struct iotype blockio; + +extern int iotype_init(void); +extern void iotype_exit(void); + +#endif --- linux-2.6.28.orig/ubuntu/iscsitarget/iscsi_hdr.h +++ linux-2.6.28/ubuntu/iscsitarget/iscsi_hdr.h @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#ifndef __ISCSI_HDR_H__ +#define __ISCSI_HDR_H__ + +#include +#include + +#define ISCSI_VERSION 0 + +#ifndef __packed +#define __packed __attribute__ ((packed)) +#endif + +struct iscsi_hdr { + u8 opcode; /* 0 */ + u8 flags; + u8 spec1[2]; +#if defined(__BIG_ENDIAN_BITFIELD) + struct { /* 4 */ + unsigned ahslength : 8; + unsigned datalength : 24; + } length; +#elif defined(__LITTLE_ENDIAN_BITFIELD) + u32 length; /* 4 */ +#endif + u16 lun[4]; /* 8 */ + u32 itt; /* 16 */ + u32 ttt; /* 20 */ + u32 sn; /* 24 */ + u32 exp_sn; /* 28 */ + u32 max_sn; /* 32 */ + u32 spec3[3]; /* 36 */ +} __packed; /* 48 */ + +/* Opcode encoding bits */ +#define ISCSI_OP_RETRY 0x80 +#define ISCSI_OP_IMMEDIATE 0x40 +#define ISCSI_OPCODE_MASK 0x3F + +/* Client to Server Message Opcode values */ +#define ISCSI_OP_NOOP_OUT 0x00 +#define ISCSI_OP_SCSI_CMD 0x01 +#define ISCSI_OP_SCSI_TASK_MGT_MSG 0x02 +#define ISCSI_OP_LOGIN_CMD 0x03 +#define ISCSI_OP_TEXT_CMD 0x04 +#define ISCSI_OP_SCSI_DATA_OUT 0x05 +#define ISCSI_OP_LOGOUT_CMD 0x06 +#define ISCSI_OP_SNACK_CMD 0x10 + +#define ISCSI_OP_VENDOR1_CMD 0x1c +#define ISCSI_OP_VENDOR2_CMD 0x1d +#define ISCSI_OP_VENDOR3_CMD 0x1e +#define ISCSI_OP_VENDOR4_CMD 0x1f + +/* Server to Client Message Opcode values */ +#define ISCSI_OP_NOOP_IN 0x20 +#define ISCSI_OP_SCSI_RSP 0x21 +#define ISCSI_OP_SCSI_TASK_MGT_RSP 0x22 +#define ISCSI_OP_LOGIN_RSP 0x23 +#define ISCSI_OP_TEXT_RSP 0x24 +#define ISCSI_OP_SCSI_DATA_IN 0x25 +#define ISCSI_OP_LOGOUT_RSP 0x26 +#define ISCSI_OP_R2T 0x31 +#define ISCSI_OP_ASYNC_MSG 0x32 +#define ISCSI_OP_REJECT 0x3f + +struct iscsi_ahs_hdr { + u16 ahslength; + u8 ahstype; +} __packed; + +#define ISCSI_AHSTYPE_CDB 1 +#define ISCSI_AHSTYPE_RLENGTH 2 + +union iscsi_sid { + struct { + u8 isid[6]; /* Initiator Session ID */ + u16 tsih; /* Target Session ID */ + } id; + u64 id64; +} __packed; + +struct iscsi_scsi_cmd_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 data_length; + u32 cmd_sn; + u32 exp_stat_sn; + u8 scb[16]; +} __packed; + +#define ISCSI_CMD_FINAL 0x80 +#define ISCSI_CMD_READ 0x40 +#define ISCSI_CMD_WRITE 0x20 +#define ISCSI_CMD_ATTR_MASK 0x07 +#define ISCSI_CMD_UNTAGGED 0x00 +#define ISCSI_CMD_SIMPLE 0x01 +#define ISCSI_CMD_ORDERED 0x02 +#define ISCSI_CMD_HEAD_OF_QUEUE 0x03 +#define ISCSI_CMD_ACA 0x04 + +struct iscsi_cdb_ahdr { + u16 ahslength; + u8 ahstype; + u8 reserved; + u8 cdb[0]; +} __packed; + +struct iscsi_rlength_ahdr { + u16 ahslength; + u8 ahstype; + u8 reserved; + u32 read_length; +} __packed; + +struct iscsi_scsi_rsp_hdr { + u8 opcode; + u8 flags; + u8 response; + u8 cmd_status; + u8 ahslength; + u8 datalength[3]; + u32 rsvd1[2]; + u32 itt; + u32 snack; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 exp_data_sn; + u32 bi_residual_count; + u32 residual_count; +} __packed; + +#define ISCSI_FLG_RESIDUAL_UNDERFLOW 0x02 +#define ISCSI_FLG_RESIDUAL_OVERFLOW 0x04 +#define ISCSI_FLG_BIRESIDUAL_UNDERFLOW 0x08 +#define ISCSI_FLG_BIRESIDUAL_OVERFLOW 0x10 + +#define ISCSI_RESPONSE_COMMAND_COMPLETED 0x00 +#define ISCSI_RESPONSE_TARGET_FAILURE 0x01 + +struct iscsi_sense_data { + u16 length; + u8 data[0]; +} __packed; + +struct iscsi_task_mgt_hdr { + u8 opcode; + u8 function; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 rtt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 ref_cmd_sn; + u32 exp_data_sn; + u32 rsvd2[2]; +} __packed; + +#define ISCSI_FUNCTION_MASK 0x7f + +#define ISCSI_FUNCTION_ABORT_TASK 1 +#define ISCSI_FUNCTION_ABORT_TASK_SET 2 +#define ISCSI_FUNCTION_CLEAR_ACA 3 +#define ISCSI_FUNCTION_CLEAR_TASK_SET 4 +#define ISCSI_FUNCTION_LOGICAL_UNIT_RESET 5 +#define ISCSI_FUNCTION_TARGET_WARM_RESET 6 +#define ISCSI_FUNCTION_TARGET_COLD_RESET 7 +#define ISCSI_FUNCTION_TASK_REASSIGN 8 + +struct iscsi_task_rsp_hdr { + u8 opcode; + u8 flags; + u8 response; + u8 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 rsvd3; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd4[3]; +} __packed; + +#define ISCSI_RESPONSE_FUNCTION_COMPLETE 0 +#define ISCSI_RESPONSE_UNKNOWN_TASK 1 +#define ISCSI_RESPONSE_UNKNOWN_LUN 2 +#define ISCSI_RESPONSE_TASK_ALLEGIANT 3 +#define ISCSI_RESPONSE_FAILOVER_UNSUPPORTED 4 +#define ISCSI_RESPONSE_FUNCTION_UNSUPPORTED 5 +#define ISCSI_RESPONSE_NO_AUTHORIZATION 6 +#define ISCSI_RESPONSE_FUNCTION_REJECTED 255 + +struct iscsi_data_out_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 rsvd2; + u32 exp_stat_sn; + u32 rsvd3; + u32 data_sn; + u32 buffer_offset; + u32 rsvd4; +} __packed; + +struct iscsi_data_in_hdr { + u8 opcode; + u8 flags; + u8 rsvd1; + u8 cmd_status; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 data_sn; + u32 buffer_offset; + u32 residual_count; +} __packed; + +#define ISCSI_FLG_STATUS 0x01 + +struct iscsi_r2t_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 r2t_sn; + u32 buffer_offset; + u32 data_length; +} __packed; + +struct iscsi_async_msg_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 ffffffff; + u32 rsvd2; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u8 async_event; + u8 async_vcode; + u16 param1; + u16 param2; + u16 param3; + u32 rsvd3; +} __packed; + +#define ISCSI_ASYNC_SCSI 0 +#define ISCSI_ASYNC_LOGOUT 1 +#define ISCSI_ASYNC_DROP_CONNECTION 2 +#define ISCSI_ASYNC_DROP_SESSION 3 +#define ISCSI_ASYNC_PARAM_REQUEST 4 +#define ISCSI_ASYNC_VENDOR 255 + +struct iscsi_text_req_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd3[4]; +} __packed; + +struct iscsi_text_rsp_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd3[3]; +} __packed; + +struct iscsi_login_req_hdr { + u8 opcode; + u8 flags; + u8 max_version; /* Max. version supported */ + u8 min_version; /* Min. version supported */ + u8 ahslength; + u8 datalength[3]; + union iscsi_sid sid; + u32 itt; /* Initiator Task Tag */ + u16 cid; /* Connection ID */ + u16 rsvd1; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd2[4]; +} __packed; + +struct iscsi_login_rsp_hdr { + u8 opcode; + u8 flags; + u8 max_version; /* Max. version supported */ + u8 active_version; /* Active version */ + u8 ahslength; + u8 datalength[3]; + union iscsi_sid sid; + u32 itt; /* Initiator Task Tag */ + u32 rsvd1; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u8 status_class; /* see Login RSP ststus classes below */ + u8 status_detail; /* see Login RSP Status details below */ + u8 rsvd2[10]; +} __packed; + +#define ISCSI_FLG_FINAL 0x80 +#define ISCSI_FLG_TRANSIT 0x80 +#define ISCSI_FLG_CSG_SECURITY 0x00 +#define ISCSI_FLG_CSG_LOGIN 0x04 +#define ISCSI_FLG_CSG_FULL_FEATURE 0x0c +#define ISCSI_FLG_CSG_MASK 0x0c +#define ISCSI_FLG_NSG_SECURITY 0x00 +#define ISCSI_FLG_NSG_LOGIN 0x01 +#define ISCSI_FLG_NSG_FULL_FEATURE 0x03 +#define ISCSI_FLG_NSG_MASK 0x03 + +/* Login Status response classes */ +#define ISCSI_STATUS_SUCCESS 0x00 +#define ISCSI_STATUS_REDIRECT 0x01 +#define ISCSI_STATUS_INITIATOR_ERR 0x02 +#define ISCSI_STATUS_TARGET_ERR 0x03 + +/* Login Status response detail codes */ +/* Class-0 (Success) */ +#define ISCSI_STATUS_ACCEPT 0x00 + +/* Class-1 (Redirection) */ +#define ISCSI_STATUS_TGT_MOVED_TEMP 0x01 +#define ISCSI_STATUS_TGT_MOVED_PERM 0x02 + +/* Class-2 (Initiator Error) */ +#define ISCSI_STATUS_INIT_ERR 0x00 +#define ISCSI_STATUS_AUTH_FAILED 0x01 +#define ISCSI_STATUS_TGT_FORBIDDEN 0x02 +#define ISCSI_STATUS_TGT_NOT_FOUND 0x03 +#define ISCSI_STATUS_TGT_REMOVED 0x04 +#define ISCSI_STATUS_NO_VERSION 0x05 +#define ISCSI_STATUS_TOO_MANY_CONN 0x06 +#define ISCSI_STATUS_MISSING_FIELDS 0x07 +#define ISCSI_STATUS_CONN_ADD_FAILED 0x08 +#define ISCSI_STATUS_INV_SESSION_TYPE 0x09 +#define ISCSI_STATUS_SESSION_NOT_FOUND 0x0a +#define ISCSI_STATUS_INV_REQ_TYPE 0x0b + +/* Class-3 (Target Error) */ +#define ISCSI_STATUS_TARGET_ERROR 0x00 +#define ISCSI_STATUS_SVC_UNAVAILABLE 0x01 +#define ISCSI_STATUS_NO_RESOURCES 0x02 + +struct iscsi_logout_req_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u16 cid; + u16 rsvd3; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd4[4]; +} __packed; + +struct iscsi_logout_rsp_hdr { + u8 opcode; + u8 flags; + u8 response; + u8 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 rsvd3; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd4; + u16 time2wait; + u16 time2retain; + u32 rsvd5; +} __packed; + +struct iscsi_snack_req_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 itt; + u32 ttt; + u32 rsvd3; + u32 exp_stat_sn; + u32 rsvd4[2]; + u32 beg_run; + u32 run_length; +} __packed; + +struct iscsi_reject_hdr { + u8 opcode; + u8 flags; + u8 reason; + u8 rsvd1; + u8 ahslength; + u8 datalength[3]; + u32 rsvd2[2]; + u32 ffffffff; + u32 rsvd3; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 data_sn; + u32 rsvd4[2]; +} __packed; + +#define ISCSI_REASON_NO_FULL_FEATURE_PHASE 0x01 +#define ISCSI_REASON_DATA_DIGEST_ERROR 0x02 +#define ISCSI_REASON_DATA_SNACK_REJECT 0x03 +#define ISCSI_REASON_PROTOCOL_ERROR 0x04 +#define ISCSI_REASON_UNSUPPORTED_COMMAND 0x05 +#define ISCSI_REASON_IMMEDIATE_COMMAND_REJECT 0x06 +#define ISCSI_REASON_TASK_IN_PROGRESS 0x07 +#define ISCSI_REASON_INVALID_SNACK 0x08 +#define ISCSI_REASON_NO_BOOKMARK 0x09 +#define ISCSI_REASON_BOOKMARK_REJECT 0x0a +#define ISCSI_REASON_NEGOTIATION_RESET 0x0b +#define ISCSI_REASON_WAITING_LOGOUT 0x0c + + +struct iscsi_nop_out_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 cmd_sn; + u32 exp_stat_sn; + u32 rsvd2[4]; +} __packed; + +struct iscsi_nop_in_hdr { + u8 opcode; + u8 flags; + u16 rsvd1; + u8 ahslength; + u8 datalength[3]; + u16 lun[4]; + u32 itt; + u32 ttt; + u32 stat_sn; + u32 exp_cmd_sn; + u32 max_cmd_sn; + u32 rsvd2[3]; +} __packed; + +#define ISCSI_RESERVED_TAG (0xffffffffU) + +#endif /* __ISCSI_HDR_H__ */ --- linux-2.6.28.orig/ubuntu/iscsitarget/tio.c +++ linux-2.6.28/ubuntu/iscsitarget/tio.c @@ -0,0 +1,121 @@ +/* + * Target I/O. + * (C) 2005 FUJITA Tomonori + * This code is licenced under the GPL. + */ + +#include "iscsi.h" +#include "iscsi_dbg.h" +#include "iotype.h" + +static int tio_add_pages(struct tio *tio, int count) +{ + int i; + struct page *page; + + dprintk(D_GENERIC, "%p %d (%d)\n", tio, count, tio->pg_cnt); + + tio->pg_cnt = count; + + count *= sizeof(struct page *); + + do { + tio->pvec = kzalloc(count, GFP_KERNEL); + if (!tio->pvec) + yield(); + } while (!tio->pvec); + + for (i = 0; i < tio->pg_cnt; i++) { + do { + if (!(page = alloc_page(GFP_KERNEL))) + yield(); + } while (!page); + tio->pvec[i] = page; + } + return 0; +} + +static struct kmem_cache *tio_cache; + +struct tio *tio_alloc(int count) +{ + struct tio *tio; + + tio = kmem_cache_alloc(tio_cache, GFP_KERNEL | __GFP_NOFAIL); + + tio->pg_cnt = 0; + tio->idx = 0; + tio->offset = 0; + tio->size = 0; + tio->pvec = NULL; + + atomic_set(&tio->count, 1); + + if (count) + tio_add_pages(tio, count); + + return tio; +} + +static void tio_free(struct tio *tio) +{ + int i; + for (i = 0; i < tio->pg_cnt; i++) { + assert(tio->pvec[i]); + __free_page(tio->pvec[i]); + } + kfree(tio->pvec); + kmem_cache_free(tio_cache, tio); +} + +void tio_put(struct tio *tio) +{ + assert(atomic_read(&tio->count)); + if (atomic_dec_and_test(&tio->count)) + tio_free(tio); +} + +void tio_get(struct tio *tio) +{ + atomic_inc(&tio->count); +} + +void tio_set(struct tio *tio, u32 size, loff_t offset) +{ + tio->idx = offset >> PAGE_CACHE_SHIFT; + tio->offset = offset & ~PAGE_CACHE_MASK; + tio->size = size; +} + +int tio_read(struct iet_volume *lu, struct tio *tio) +{ + struct iotype *iot = lu->iotype; + assert(iot); + return iot->make_request ? iot->make_request(lu, tio, READ) : 0; +} + +int tio_write(struct iet_volume *lu, struct tio *tio) +{ + struct iotype *iot = lu->iotype; + assert(iot); + return iot->make_request ? iot->make_request(lu, tio, WRITE) : 0; +} + +int tio_sync(struct iet_volume *lu, struct tio *tio) +{ + struct iotype *iot = lu->iotype; + assert(iot); + return iot->sync ? iot->sync(lu, tio) : 0; +} + +int tio_init(void) +{ + tio_cache = KMEM_CACHE(tio, 0); + return tio_cache ? 0 : -ENOMEM; +} + +void tio_exit(void) +{ + if (tio_cache) + kmem_cache_destroy(tio_cache); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/BOM +++ linux-2.6.28/ubuntu/iscsitarget/BOM @@ -0,0 +1,5 @@ +Downloaded from: http://iscsitarget.sourceforge.net/ +Current Version: 0.4.17 + +Applied iscsitarget.diff in order to compile with 2.6.28. + --- linux-2.6.28.orig/ubuntu/iscsitarget/target.c +++ linux-2.6.28/ubuntu/iscsitarget/target.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2002-2003 Ardis Technolgies + * + * Released under the terms of the GNU GPL v2.0. + */ + +#include "iscsi.h" +#include "digest.h" +#include "iscsi_dbg.h" + +#define MAX_NR_TARGETS (1UL << 30) + +static LIST_HEAD(target_list); +static DECLARE_MUTEX(target_list_sem); +static u32 next_target_id; +static u32 nr_targets; + +static struct iscsi_sess_param default_session_param = { + .initial_r2t = 1, + .immediate_data = 1, + .max_connections = 1, + .max_recv_data_length = 8192, + .max_xmit_data_length = 8192, + .max_burst_length = 262144, + .first_burst_length = 65536, + .default_wait_time = 2, + .default_retain_time = 20, + .max_outstanding_r2t = 1, + .data_pdu_inorder = 1, + .data_sequence_inorder = 1, + .error_recovery_level = 0, + .header_digest = DIGEST_NONE, + .data_digest = DIGEST_NONE, + .ofmarker = 0, + .ifmarker = 0, + .ofmarkint = 2048, + .ifmarkint = 2048, +}; + +static struct iscsi_trgt_param default_target_param = { + .wthreads = DEFAULT_NR_WTHREADS, + .target_type = 0, + .queued_cmnds = DEFAULT_NR_QUEUED_CMNDS, +}; + +inline int target_lock(struct iscsi_target *target, int interruptible) +{ + int err = 0; + + if (interruptible) + err = down_interruptible(&target->target_sem); + else + down(&target->target_sem); + + return err; +} + +inline void target_unlock(struct iscsi_target *target) +{ + up(&target->target_sem); +} + +static struct iscsi_target *__target_lookup_by_id(u32 id) +{ + struct iscsi_target *target; + + list_for_each_entry(target, &target_list, t_list) { + if (target->tid == id) + return target; + } + return NULL; +} + +static struct iscsi_target *__target_lookup_by_name(char *name) +{ + struct iscsi_target *target; + + list_for_each_entry(target, &target_list, t_list) { + if (!strcmp(target->name, name)) + return target; + } + return NULL; +} + +struct iscsi_target *target_lookup_by_id(u32 id) +{ + struct iscsi_target *target; + + down(&target_list_sem); + target = __target_lookup_by_id(id); + up(&target_list_sem); + + return target; +} + +static int target_thread_start(struct iscsi_target *target) +{ + int err; + + if ((err = nthread_start(target)) < 0) + return err; + + if ((err = wthread_start(target)) < 0) { + nthread_stop(target); + } + + return err; +} + +static void target_thread_stop(struct iscsi_target *target) +{ + wthread_stop(target); + nthread_stop(target); +} + +static int iscsi_target_create(struct target_info *info, u32 tid) +{ + int err = -EINVAL, len; + char *name = info->name; + struct iscsi_target *target; + + dprintk(D_SETUP, "%u %s\n", tid, name); + + if (!(len = strlen(name))) { + eprintk("The length of the target name is zero %u\n", tid); + return err; + } + + if (!try_module_get(THIS_MODULE)) { + eprintk("Fail to get module %u\n", tid); + return err; + } + + target = kzalloc(sizeof(*target), GFP_KERNEL); + if (!target) { + err = -ENOMEM; + goto out; + } + + target->tid = info->tid = tid; + + memcpy(&target->sess_param, &default_session_param, sizeof(default_session_param)); + memcpy(&target->trgt_param, &default_target_param, sizeof(default_target_param)); + + strncpy(target->name, name, sizeof(target->name) - 1); + + init_MUTEX(&target->target_sem); + + INIT_LIST_HEAD(&target->session_list); + INIT_LIST_HEAD(&target->volumes); + + atomic_set(&target->nr_volumes, 0); + + list_add(&target->t_list, &target_list); + + nthread_init(target); + wthread_init(target); + + if ((err = target_thread_start(target)) < 0) { + target_thread_stop(target); + goto out; + } + + return 0; +out: + kfree(target); + module_put(THIS_MODULE); + + return err; +} + +int target_add(struct target_info *info) +{ + int err = -EEXIST; + u32 tid = info->tid; + + down(&target_list_sem); + + if (nr_targets > MAX_NR_TARGETS) { + err = -EBUSY; + goto out; + } + + if (__target_lookup_by_name(info->name)) + goto out; + + if (tid && __target_lookup_by_id(tid)) + goto out; + + if (!tid) { + do { + if (!++next_target_id) + ++next_target_id; + } while (__target_lookup_by_id(next_target_id)); + + tid = next_target_id; + } + + if (!(err = iscsi_target_create(info, tid))) + nr_targets++; +out: + up(&target_list_sem); + + return err; +} + +static void target_destroy(struct iscsi_target *target) +{ + dprintk(D_SETUP, "%u\n", target->tid); + + target_thread_stop(target); + + while (!list_empty(&target->volumes)) { + struct iet_volume *volume; + volume = list_entry(target->volumes.next, struct iet_volume, list); + volume->l_state = IDEV_DEL; + iscsi_volume_destroy(volume); + } + + kfree(target); + + module_put(THIS_MODULE); +} + +int target_del(u32 id) +{ + struct iscsi_target *target; + int err; + + if ((err = down_interruptible(&target_list_sem)) < 0) + return err; + + if (!(target = __target_lookup_by_id(id))) { + err = -ENOENT; + goto out; + } + + target_lock(target, 0); + + if (!list_empty(&target->session_list)) { + err = -EBUSY; + target_unlock(target); + goto out; + } + + list_del(&target->t_list); + nr_targets--; + + target_unlock(target); + up(&target_list_sem); + + target_destroy(target); + return 0; +out: + up(&target_list_sem); + return err; +} + +int iet_info_show(struct seq_file *seq, iet_show_info_t *func) +{ + int err; + struct iscsi_target *target; + + if ((err = down_interruptible(&target_list_sem)) < 0) + return err; + + list_for_each_entry(target, &target_list, t_list) { + seq_printf(seq, "tid:%u name:%s\n", target->tid, target->name); + + if ((err = target_lock(target, 1)) < 0) + break; + + func(seq, target); + + target_unlock(target); + } + + up(&target_list_sem); + + return 0; +} --- linux-2.6.28.orig/ubuntu/iscsitarget/config.c +++ linux-2.6.28/ubuntu/iscsitarget/config.c @@ -0,0 +1,316 @@ +/* + * (C) 2004 - 2005 FUJITA Tomonori + * + * This code is licenced under the GPL. + */ + +#include + +#include "iscsi.h" +#include "iscsi_dbg.h" + +struct proc_entries { + const char *name; + struct file_operations *fops; +}; + +static struct proc_entries iet_proc_entries[] = +{ + {"volume", &volume_seq_fops}, + {"session", &session_seq_fops}, +}; + +static struct proc_dir_entry *proc_iet_dir; + +void iet_procfs_exit(void) +{ + int i; + + if (!proc_iet_dir) + return; + + for (i = 0; i < ARRAY_SIZE(iet_proc_entries); i++) + remove_proc_entry(iet_proc_entries[i].name, proc_iet_dir); + + remove_proc_entry(proc_iet_dir->name, proc_iet_dir->parent); +} + +int iet_procfs_init(void) +{ + int i; + struct proc_dir_entry *ent; + + if (!(proc_iet_dir = proc_mkdir("iet", init_net.proc_net))) + goto err; + + proc_iet_dir->owner = THIS_MODULE; + + for (i = 0; i < ARRAY_SIZE(iet_proc_entries); i++) { + ent = create_proc_entry(iet_proc_entries[i].name, 0, proc_iet_dir); + if (ent) + ent->proc_fops = iet_proc_entries[i].fops; + else + goto err; + } + + return 0; + +err: + if (proc_iet_dir) + iet_procfs_exit(); + + return -ENOMEM; +} + +static int get_conn_info(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct conn_info info; + struct iscsi_conn *conn; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + session = session_lookup(target, info.sid); + if (!session) + return -ENOENT; + conn = conn_lookup(session, info.cid); + + info.cid = conn->cid; + info.stat_sn = conn->stat_sn; + info.exp_stat_sn = conn->exp_stat_sn; + + if (copy_to_user((void *) ptr, &info, sizeof(info))) + return -EFAULT; + + return 0; +} + +static int add_conn(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct conn_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + if (!(session = session_lookup(target, info.sid))) + return -ENOENT; + + return conn_add(session, &info); +} + +static int del_conn(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct conn_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + if (!(session = session_lookup(target, info.sid))) + return -ENOENT; + + return conn_del(session, &info); +} + +static int get_session_info(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct iscsi_session *session; + struct session_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + session = session_lookup(target, info.sid); + + if (!session) + return -ENOENT; + + info.exp_cmd_sn = session->exp_cmd_sn; + info.max_cmd_sn = session->max_cmd_sn; + + if (copy_to_user((void *) ptr, &info, sizeof(info))) + return -EFAULT; + + return 0; +} + +static int add_session(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct session_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return session_add(target, &info); +} + +static int del_session(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct session_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return session_del(target, info.sid); +} + +static int add_volume(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct volume_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return volume_add(target, &info); +} + +static int del_volume(struct iscsi_target *target, unsigned long ptr) +{ + int err; + struct volume_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + return iscsi_volume_del(target, &info); +} + +static int iscsi_param_config(struct iscsi_target *target, unsigned long ptr, int set) +{ + int err; + struct iscsi_param_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + goto out; + + if ((err = iscsi_param_set(target, &info, set)) < 0) + goto out; + + if (!set) + err = copy_to_user((void *) ptr, &info, sizeof(info)); + +out: + return err; +} + +static int add_target(unsigned long ptr) +{ + int err; + struct target_info info; + + if ((err = copy_from_user(&info, (void *) ptr, sizeof(info))) < 0) + return err; + + if (!(err = target_add(&info))) + err = copy_to_user((void *) ptr, &info, sizeof(info)); + + return err; +} + +static long ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct iscsi_target *target = NULL; + long err; + u32 id; + + if ((err = get_user(id, (u32 *) arg)) != 0) + goto done; + + if (cmd == DEL_TARGET) { + err = target_del(id); + goto done; + } + + target = target_lookup_by_id(id); + + if (cmd == ADD_TARGET) + if (target) { + err = -EEXIST; + eprintk("Target %u already exist!\n", id); + goto done; + } + + switch (cmd) { + case ADD_TARGET: + assert(!target); + err = add_target(arg); + goto done; + } + + if (!target) { + eprintk("can't find the target %u\n", id); + err = -EINVAL; + goto done; + } + + if ((err = target_lock(target, 1)) < 0) { + eprintk("interrupted %ld %d\n", err, cmd); + goto done; + } + + switch (cmd) { + case ADD_VOLUME: + err = add_volume(target, arg); + break; + + case DEL_VOLUME: + err = del_volume(target, arg); + break; + + case ADD_SESSION: + err = add_session(target, arg); + break; + + case DEL_SESSION: + err = del_session(target, arg); + break; + + case GET_SESSION_INFO: + err = get_session_info(target, arg); + break; + + case ISCSI_PARAM_SET: + err = iscsi_param_config(target, arg, 1); + break; + + case ISCSI_PARAM_GET: + err = iscsi_param_config(target, arg, 0); + break; + + case ADD_CONN: + err = add_conn(target, arg); + break; + + case DEL_CONN: + err = del_conn(target, arg); + break; + + case GET_CONN_INFO: + err = get_conn_info(target, arg); + break; + default: + eprintk("invalid ioctl cmd %x\n", cmd); + err = -EINVAL; + } + + if (target) + target_unlock(target); + +done: + return err; +} + +struct file_operations ctr_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = ioctl, + .compat_ioctl = ioctl, +}; --- linux-2.6.28.orig/ubuntu/iscsitarget/digest.c +++ linux-2.6.28/ubuntu/iscsitarget/digest.c @@ -0,0 +1,279 @@ +/* + * iSCSI digest handling. + * (C) 2004 - 2006 Xiranet Communications GmbH + * This code is licensed under the GPL. + */ + +#include + +#include "iscsi.h" +#include "digest.h" +#include "iscsi_dbg.h" + +void digest_alg_available(unsigned int *val) +{ + if (*val & DIGEST_CRC32C && + !crypto_has_alg("crc32c", 0, CRYPTO_ALG_ASYNC)) { + printk("CRC32C digest algorithm not available in kernel\n"); + *val |= ~DIGEST_CRC32C; + } +} + +/** + * initialize support for digest calculation. + * + * digest_init - + * @conn: ptr to connection to make use of digests + * + * @return: 0 on success, < 0 on error + */ +int digest_init(struct iscsi_conn *conn) +{ + int err = 0; + + if (!(conn->hdigest_type & DIGEST_ALL)) + conn->hdigest_type = DIGEST_NONE; + + if (!(conn->ddigest_type & DIGEST_ALL)) + conn->ddigest_type = DIGEST_NONE; + + if (conn->hdigest_type & DIGEST_CRC32C || + conn->ddigest_type & DIGEST_CRC32C) { + conn->rx_hash.tfm = crypto_alloc_hash("crc32c", 0, + CRYPTO_ALG_ASYNC); + conn->rx_hash.flags = 0; + if (IS_ERR(conn->rx_hash.tfm)) { + conn->rx_hash.tfm = NULL; + err = -ENOMEM; + goto out; + } + + conn->tx_hash.tfm = crypto_alloc_hash("crc32c", 0, + CRYPTO_ALG_ASYNC); + conn->tx_hash.flags = 0; + if (IS_ERR(conn->tx_hash.tfm)) { + conn->tx_hash.tfm = NULL; + err = -ENOMEM; + goto out; + } + } + +out: + if (err) + digest_cleanup(conn); + + return err; +} + +/** + * free resources used for digest calculation. + * + * digest_cleanup - + * @conn: ptr to connection that made use of digests + */ +void digest_cleanup(struct iscsi_conn *conn) +{ + if (conn->tx_hash.tfm) + crypto_free_hash(conn->tx_hash.tfm); + if (conn->rx_hash.tfm) + crypto_free_hash(conn->rx_hash.tfm); +} + +/** + * debug handling of header digest errors: + * simulates a digest error after n PDUs / every n-th PDU of type + * HDIGEST_ERR_CORRUPT_PDU_TYPE. + */ +static inline void __dbg_simulate_header_digest_error(struct iscsi_cmnd *cmnd) +{ +#define HDIGEST_ERR_AFTER_N_CMNDS 1000 +#define HDIGEST_ERR_ONLY_ONCE 1 +#define HDIGEST_ERR_CORRUPT_PDU_TYPE ISCSI_OP_SCSI_CMD +#define HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY 0 + + static int num_cmnds = 0; + static int num_errs = 0; + + if (cmnd_opcode(cmnd) == HDIGEST_ERR_CORRUPT_PDU_TYPE) { + if (HDIGEST_ERR_CORRUPT_PDU_WITH_DATA_ONLY) { + if (cmnd->pdu.datasize) + num_cmnds++; + } else + num_cmnds++; + } + + if ((num_cmnds == HDIGEST_ERR_AFTER_N_CMNDS) + && (!(HDIGEST_ERR_ONLY_ONCE && num_errs))) { + printk("*** Faking header digest error ***\n"); + printk("\tcmnd: 0x%x, itt 0x%x, sn 0x%x\n", + cmnd_opcode(cmnd), + be32_to_cpu(cmnd->pdu.bhs.itt), + be32_to_cpu(cmnd->pdu.bhs.sn)); + cmnd->hdigest = ~cmnd->hdigest; + /* make things even worse by manipulating header fields */ + cmnd->pdu.datasize += 8; + num_errs++; + num_cmnds = 0; + } + return; +} + +/** + * debug handling of data digest errors: + * simulates a digest error after n PDUs / every n-th PDU of type + * DDIGEST_ERR_CORRUPT_PDU_TYPE. + */ +static inline void __dbg_simulate_data_digest_error(struct iscsi_cmnd *cmnd) +{ +#define DDIGEST_ERR_AFTER_N_CMNDS 50 +#define DDIGEST_ERR_ONLY_ONCE 1 +#define DDIGEST_ERR_CORRUPT_PDU_TYPE ISCSI_OP_SCSI_DATA_OUT +#define DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY 0 + + static int num_cmnds = 0; + static int num_errs = 0; + + if ((cmnd->pdu.datasize) + && (cmnd_opcode(cmnd) == DDIGEST_ERR_CORRUPT_PDU_TYPE)) { + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_DATA_OUT: + if ((DDIGEST_ERR_CORRUPT_UNSOL_DATA_ONLY) + && (cmnd->pdu.bhs.ttt != ISCSI_RESERVED_TAG)) + break; + default: + num_cmnds++; + } + } + + if ((num_cmnds == DDIGEST_ERR_AFTER_N_CMNDS) + && (!(DDIGEST_ERR_ONLY_ONCE && num_errs)) + && (cmnd->pdu.datasize) + && (!cmnd->conn->read_overflow)) { + printk("*** Faking data digest error: ***"); + printk("\tcmnd 0x%x, itt 0x%x, sn 0x%x\n", + cmnd_opcode(cmnd), + be32_to_cpu(cmnd->pdu.bhs.itt), + be32_to_cpu(cmnd->pdu.bhs.sn)); + cmnd->ddigest = ~cmnd->ddigest; + num_errs++; + num_cmnds = 0; + } +} + +static void digest_header(struct hash_desc *hash, struct iscsi_pdu *pdu, + u8 *crc) +{ + struct scatterlist sg[2]; + unsigned int nbytes = sizeof(struct iscsi_hdr); + + sg_init_table(sg, pdu->ahssize ? 2 : 1); + + sg_set_buf(&sg[0], &pdu->bhs, nbytes); + if (pdu->ahssize) { + sg_set_buf(&sg[1], pdu->ahs, pdu->ahssize); + nbytes += pdu->ahssize; + } + + crypto_hash_init(hash); + crypto_hash_update(hash, sg, nbytes); + crypto_hash_final(hash, crc); +} + +int digest_rx_header(struct iscsi_cmnd *cmnd) +{ + u32 crc; + + digest_header(&cmnd->conn->rx_hash, &cmnd->pdu, (u8 *) &crc); + if (crc != cmnd->hdigest) + return -EIO; + + return 0; +} + +void digest_tx_header(struct iscsi_cmnd *cmnd) +{ + digest_header(&cmnd->conn->tx_hash, &cmnd->pdu, (u8 *) &cmnd->hdigest); +} + +static void digest_data(struct hash_desc *hash, struct iscsi_cmnd *cmnd, + struct tio *tio, u32 offset, u8 *crc) +{ + struct scatterlist *sg = cmnd->conn->hash_sg; + u32 size, length; + int i, idx, count; + unsigned int nbytes; + + size = cmnd->pdu.datasize; + nbytes = size = (size + 3) & ~3; + + offset += tio->offset; + idx = offset >> PAGE_CACHE_SHIFT; + offset &= ~PAGE_CACHE_MASK; + count = get_pgcnt(size, offset); + assert(idx + count <= tio->pg_cnt); + + assert(count <= ISCSI_CONN_IOV_MAX); + + sg_init_table(sg, ARRAY_SIZE(cmnd->conn->hash_sg)); + crypto_hash_init(hash); + + for (i = 0; size; i++) { + if (offset + size > PAGE_CACHE_SIZE) + length = PAGE_CACHE_SIZE - offset; + else + length = size; + + sg_set_page(&sg[i], tio->pvec[idx + i], length, offset); + size -= length; + offset = 0; + } + + sg_mark_end(&sg[i - 1]); + + crypto_hash_update(hash, sg, nbytes); + crypto_hash_final(hash, crc); +} + +int digest_rx_data(struct iscsi_cmnd *cmnd) +{ + struct tio *tio; + struct iscsi_cmnd *scsi_cmnd; + struct iscsi_data_out_hdr *req; + u32 offset, crc; + + switch (cmnd_opcode(cmnd)) { + case ISCSI_OP_SCSI_REJECT: + case ISCSI_OP_PDU_REJECT: + case ISCSI_OP_DATA_REJECT: + return 0; + case ISCSI_OP_SCSI_DATA_OUT: + scsi_cmnd = cmnd->req; + req = (struct iscsi_data_out_hdr *) &cmnd->pdu.bhs; + tio = scsi_cmnd->tio; + offset = be32_to_cpu(req->buffer_offset); + break; + default: + tio = cmnd->tio; + offset = 0; + } + + digest_data(&cmnd->conn->rx_hash, cmnd, tio, offset, (u8 *) &crc); + + if (!cmnd->conn->read_overflow && + (cmnd_opcode(cmnd) != ISCSI_OP_PDU_REJECT)) { + if (crc != cmnd->ddigest) + return -EIO; + } + + return 0; +} + +void digest_tx_data(struct iscsi_cmnd *cmnd) +{ + struct tio *tio = cmnd->tio; + struct iscsi_data_out_hdr *req = (struct iscsi_data_out_hdr *)&cmnd->pdu.bhs; + + assert(tio); + digest_data(&cmnd->conn->tx_hash, cmnd, tio, + be32_to_cpu(req->buffer_offset), (u8 *) &cmnd->ddigest); +} --- linux-2.6.28.orig/ubuntu/iscsitarget/include/iet_u.h +++ linux-2.6.28/ubuntu/iscsitarget/include/iet_u.h @@ -0,0 +1,139 @@ +#ifndef _IET_U_H +#define _IET_U_H + +#define IET_VERSION_STRING "0.4.17" + +/* The maximum length of 223 bytes in the RFC. */ +#define ISCSI_NAME_LEN 256 +#define ISCSI_ARGS_LEN 2048 + +#define ISCSI_LISTEN_PORT 3260 + +#define VENDOR_ID_LEN 8 +#define SCSI_ID_LEN 24 +#define SCSI_SN_LEN 16 + +#ifndef aligned_u64 +#define aligned_u64 unsigned long long __attribute__((aligned(8))) +#endif + +struct target_info { + u32 tid; + char name[ISCSI_NAME_LEN]; +}; + +struct volume_info { + u32 tid; + u32 lun; + aligned_u64 args_ptr; + u32 args_len; +}; + +struct session_info { + u32 tid; + + aligned_u64 sid; + char initiator_name[ISCSI_NAME_LEN]; + u32 exp_cmd_sn; + u32 max_cmd_sn; +}; + +#define DIGEST_ALL (DIGEST_NONE | DIGEST_CRC32C) +#define DIGEST_NONE (1 << 0) +#define DIGEST_CRC32C (1 << 1) + +struct conn_info { + u32 tid; + aligned_u64 sid; + + u32 cid; + u32 stat_sn; + u32 exp_stat_sn; + int header_digest; + int data_digest; + int fd; +}; + +enum { + key_initial_r2t, + key_immediate_data, + key_max_connections, + key_max_recv_data_length, + key_max_xmit_data_length, + key_max_burst_length, + key_first_burst_length, + key_default_wait_time, + key_default_retain_time, + key_max_outstanding_r2t, + key_data_pdu_inorder, + key_data_sequence_inorder, + key_error_recovery_level, + key_header_digest, + key_data_digest, + key_ofmarker, + key_ifmarker, + key_ofmarkint, + key_ifmarkint, + session_key_last, +}; + +enum { + key_wthreads, + key_target_type, + key_queued_cmnds, + target_key_last, +}; + +enum { + key_session, + key_target, +}; + +struct iscsi_param_info { + u32 tid; + aligned_u64 sid; + + u32 param_type; + u32 partial; + + u32 session_param[session_key_last]; + u32 target_param[target_key_last]; +}; + +enum iet_event_state { + E_CONN_CLOSE, +}; + +struct iet_event { + u32 tid; + aligned_u64 sid; + u32 cid; + u32 state; +}; + +#define DEFAULT_NR_WTHREADS 8 +#define MIN_NR_WTHREADS 1 +#define MAX_NR_WTHREADS 128 + +#define DEFAULT_NR_QUEUED_CMNDS 32 +#define MIN_NR_QUEUED_CMNDS 1 +#define MAX_NR_QUEUED_CMNDS 256 + +#define NETLINK_IET 21 + +#define ADD_TARGET _IOW('i', 0, struct target_info) +#define DEL_TARGET _IOW('i', 1, struct target_info) +#define START_TARGET _IO('i', 2) +#define STOP_TARGET _IO('i', 3) +#define ADD_VOLUME _IOW('i', 4, struct volume_info) +#define DEL_VOLUME _IOW('i', 5, struct volume_info) +#define ADD_SESSION _IOW('i', 6, struct session_info) +#define DEL_SESSION _IOW('i', 7, struct session_info) +#define GET_SESSION_INFO _IOWR('i', 8, struct session_info) +#define ADD_CONN _IOW('i', 9, struct conn_info) +#define DEL_CONN _IOW('i', 10, struct conn_info) +#define GET_CONN_INFO _IOWR('i', 11, struct conn_info) +#define ISCSI_PARAM_SET _IOW('i', 12, struct iscsi_param_info) +#define ISCSI_PARAM_GET _IOWR('i', 13, struct iscsi_param_info) + +#endif --- linux-2.6.28.orig/ubuntu/include/README +++ linux-2.6.28/ubuntu/include/README @@ -0,0 +1,4 @@ +Only use this directory for things which need to share their headers with +other parts of the kernel or other modules in ubuntu/ + +Otherwise, keep them local to the module directory. --- linux-2.6.28.orig/ubuntu/include/linux/squashfs_fs_i.h +++ linux-2.6.28/ubuntu/include/linux/squashfs_fs_i.h @@ -0,0 +1,45 @@ +#ifndef SQUASHFS_FS_I +#define SQUASHFS_FS_I +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs_fs_i.h + */ + +struct squashfs_inode_info { + long long start_block; + unsigned int offset; + union { + struct { + long long fragment_start_block; + unsigned int fragment_size; + unsigned int fragment_offset; + long long block_list_start; + } s1; + struct { + long long directory_index_start; + unsigned int directory_index_offset; + unsigned int directory_index_count; + unsigned int parent_inode; + } s2; + } u; + struct inode vfs_inode; +}; +#endif --- linux-2.6.28.orig/ubuntu/include/linux/tlsf.h +++ linux-2.6.28/ubuntu/include/linux/tlsf.h @@ -0,0 +1,93 @@ +/* + * Two Levels Segregate Fit memory allocator (TLSF) + * Version 2.3.2 + * + * Written by Miguel Masmano Tello + * + * Thanks to Ismael Ripoll for his suggestions and reviews + * + * Copyright (C) 2007, 2006, 2005, 2004 + * + * This code is released using a dual license strategy: GPL/LGPL + * You can choose the licence that better fits your requirements. + * + * Released under the terms of the GNU General Public License Version 2.0 + * Released under the terms of the GNU Lesser General Public License Version 2.1 + * + * This is kernel port of TLSF allocator. + * Original code can be found at: http://rtportal.upv.es/rtmalloc/ + * - Nitin Gupta (nitingupta910@gmail.com) + */ + +#ifndef _TLSF_H_ +#define _TLSF_H_ + +typedef void* (get_memory)(size_t bytes); +typedef void (put_memory)(void *ptr); + +/** + * tlsf_create_memory_pool - create dynamic memory pool + * @name: name of the pool + * @get_mem: callback function used to expand pool + * @put_mem: callback function used to shrink pool + * @init_size: inital pool size (in bytes) + * @max_size: maximum pool size (in bytes) - set this as 0 for no limit + * @grow_size: amount of memory (in bytes) added to pool whenever required + * + * All size values are rounded up to next page boundary. + */ +extern void *tlsf_create_memory_pool(const char *name, + get_memory get_mem, + put_memory put_mem, + size_t init_size, + size_t max_size, + size_t grow_size); +/** + * tlsf_destory_memory_pool - cleanup given pool + * @mem_pool: Pool to be destroyed + * + * Data structures associated with pool are freed. + * All memory allocated from pool must be freed before + * destorying it. + */ +extern void tlsf_destroy_memory_pool(void *mem_pool); + +/** + * tlsf_malloc - allocate memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +extern void *tlsf_malloc(size_t size, void *mem_pool); + +/** + * tlsf_calloc - allocate and zero-out memory from given pool + * @size: no. of bytes + * @mem_pool: pool to allocate from + */ +extern void *tlsf_calloc(size_t nelem, size_t elem_size, void *mem_pool); + +/** + * tlsf_free - free memory from given pool + * @ptr: address of memory to be freed + * @mem_pool: pool to free from + */ +extern void tlsf_free(void *ptr, void *mem_pool); + +/** + * tlsf_get_used_size - get memory currently used by given pool + * + * Used memory includes stored data + metadata + internal fragmentation + */ +extern size_t tlsf_get_used_size(void *mem_pool); + +/** + * tlsf_get_total_size - get total memory currently allocated for given pool + * + * This is the total memory currently allocated for this pool which includes + * used size + free size. + * + * (Total - Used) is good indicator of memory efficiency of allocator. + */ +extern size_t tlsf_get_total_size(void *mem_pool); + +#endif --- linux-2.6.28.orig/ubuntu/include/linux/squashfs_fs_sb.h +++ linux-2.6.28/ubuntu/include/linux/squashfs_fs_sb.h @@ -0,0 +1,76 @@ +#ifndef SQUASHFS_FS_SB +#define SQUASHFS_FS_SB +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs_fs_sb.h + */ + +#include + +struct squashfs_cache { + long long block; + int length; + long long next_index; + char *data; +}; + +struct squashfs_fragment_cache { + long long block; + int length; + unsigned int locked; + char *data; +}; + +struct squashfs_sb_info { + struct squashfs_super_block sblk; + int devblksize; + int devblksize_log2; + int swap; + struct squashfs_cache *block_cache; + struct squashfs_fragment_cache *fragment; + int next_cache; + int next_fragment; + int next_meta_index; + unsigned int *uid; + unsigned int *guid; + long long *fragment_index; + unsigned int *fragment_index_2; + char *read_page; + struct mutex read_data_mutex; + struct mutex read_page_mutex; + struct mutex block_cache_mutex; + struct mutex fragment_mutex; + struct mutex meta_index_mutex; + wait_queue_head_t waitq; + wait_queue_head_t fragment_wait_queue; + struct meta_index *meta_index; + z_stream stream; + long long *inode_lookup_table; + int unused_cache_blks; + int unused_frag_blks; + int (*read_inode)(struct inode *i, squashfs_inode_t \ + inode); + long long (*read_blocklist)(struct inode *inode, int \ + index, int readahead_blks, char *block_list, \ + unsigned short **block_p, unsigned int *bsize); + int (*read_fragment_index_table)(struct super_block *s); +}; +#endif --- linux-2.6.28.orig/ubuntu/include/linux/aufs_types.h +++ linux-2.6.28/ubuntu/include/linux/aufs_types.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2005, 2006, 2007, 2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* $Id: aufs_type.h,v 1.110 2008/06/09 01:11:58 sfjro Exp $ */ + +#include + +#ifndef __AUFS_TYPE_H__ +#define __AUFS_TYPE_H__ + +#define AUFS_VERSION "20080609" + +/* move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_BRANCH_MAX_127 +/* some environments treat 'char' as 'unsigned char' by default */ +typedef signed char aufs_bindex_t; +#define AUFS_BRANCH_MAX 127 +#else +typedef short aufs_bindex_t; +#ifdef CONFIG_AUFS_BRANCH_MAX_511 +#define AUFS_BRANCH_MAX 511 +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) +#define AUFS_BRANCH_MAX 1023 +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) +#define AUFS_BRANCH_MAX 32767 +#else +#error unknown CONFIG_AUFS_BRANCH_MAX value +#endif +#endif + +#define AUFS_NAME "aufs" +#define AUFS_FSTYPE AUFS_NAME + +#define AUFS_ROOT_INO 2 +#define AUFS_FIRST_INO 11 + +#define AUFS_WH_PFX ".wh." +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */ +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */ +#define AUFS_DIRWH_DEF 3 +#define AUFS_RDCACHE_DEF 10 /* seconds */ +#define AUFS_WKQ_NAME AUFS_NAME "d" +#define AUFS_NWKQ_DEF 4 +#define AUFS_MFS_SECOND_DEF 30 /* seconds */ +#define AUFS_PLINK_WARN 100 /* number of plinks */ + +#ifdef CONFIG_AUFS_COMPAT +#define AUFS_DIROPQ_NAME "__dir_opaque" +#else +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ +#endif +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME + +/* will be whiteouted doubly */ +#define AUFS_WH_BASENAME AUFS_WH_PFX AUFS_NAME +#define AUFS_WH_PLINKDIR AUFS_WH_PFX "plink" + +/* ---------------------------------------------------------------------- */ + +/* ioctl */ +#if 0 /* reserved for future use */ +enum { + AuCtlErr, + AuCtlErr_Last +}; +enum { + AuCtl_REFRESH, AuCtl_REFRESHV, + AuCtl_FLUSH_PLINK, + AuCtl_CPUP, + AuCtl_CPDOWN, AuCtl_MVDOWN, + AuCtl_DIROPQ +}; + +struct aufs_ctl_cp { + int bsrc, bdst; + int err; +}; + +#define AuCtlType 'A' +#define AUFS_CTL_REFRESH _IO(AuCtlType, AuCtl_REFRESH) +#define AUFS_CTL_REFRESHV _IO(AuCtlType, AuCtl_REFRESHV) +#define AUFS_CTL_FLUSH_PLINK _IOR(AuCtlType, AuCtl_FLUSH_PLINK) +#define AUFS_CTL_CPUP _IOWR(AuCtlType, AuCtl_CPUP, struct aufs_ctl_cp) +#define AUFS_CTL_CPDOWN \ + _IOWR(AuCtlType, AuCtl_CPDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_MVDOWN \ + _IOWR(AuCtlType, AuCtl_MVDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_DIROPQ _IO(AuCtlType, AuCtl_DIROPQ) +#endif + +#endif /* __AUFS_TYPE_H__ */ --- linux-2.6.28.orig/ubuntu/include/linux/squashfs_fs.h +++ linux-2.6.28/ubuntu/include/linux/squashfs_fs.h @@ -0,0 +1,935 @@ +#ifndef SQUASHFS_FS +#define SQUASHFS_FS + +/* + * Squashfs + * + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007 + * Phillip Lougher + * + * 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, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * squashfs_fs.h + */ + +#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY +#define CONFIG_SQUASHFS_2_0_COMPATIBILITY +#endif + +#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE +#define SQUASHFS_MAJOR 3 +#define SQUASHFS_MINOR 1 +#define SQUASHFS_MAGIC 0x73717368 +#define SQUASHFS_MAGIC_SWAP 0x68737173 +#define SQUASHFS_START 0 + +/* size of metadata (inode and directory) blocks */ +#define SQUASHFS_METADATA_SIZE 8192 +#define SQUASHFS_METADATA_LOG 13 + +/* default size of data blocks */ +#define SQUASHFS_FILE_SIZE 131072 +#define SQUASHFS_FILE_LOG 17 + +#define SQUASHFS_FILE_MAX_SIZE 1048576 + +/* Max number of uids and gids */ +#define SQUASHFS_UIDS 256 +#define SQUASHFS_GUIDS 255 + +/* Max length of filename (not 255) */ +#define SQUASHFS_NAME_LEN 256 + +#define SQUASHFS_INVALID ((long long) 0xffffffffffff) +#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff) +#define SQUASHFS_INVALID_BLK ((long long) -1) +#define SQUASHFS_USED_BLK ((long long) -2) + +/* Filesystem flags */ +#define SQUASHFS_NOI 0 +#define SQUASHFS_NOD 1 +#define SQUASHFS_CHECK 2 +#define SQUASHFS_NOF 3 +#define SQUASHFS_NO_FRAG 4 +#define SQUASHFS_ALWAYS_FRAG 5 +#define SQUASHFS_DUPLICATE 6 +#define SQUASHFS_EXPORT 7 + +#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) + +#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOI) + +#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOD) + +#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NOF) + +#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_NO_FRAG) + +#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_ALWAYS_FRAG) + +#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_DUPLICATE) + +#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_EXPORT) + +#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \ + SQUASHFS_CHECK) + +#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \ + duplicate_checking, exortable) (noi | (nod << 1) | (check_data << 2) \ + | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \ + (duplicate_checking << 6) | (exportable << 7)) + +/* Max number of types and file types */ +#define SQUASHFS_DIR_TYPE 1 +#define SQUASHFS_FILE_TYPE 2 +#define SQUASHFS_SYMLINK_TYPE 3 +#define SQUASHFS_BLKDEV_TYPE 4 +#define SQUASHFS_CHRDEV_TYPE 5 +#define SQUASHFS_FIFO_TYPE 6 +#define SQUASHFS_SOCKET_TYPE 7 +#define SQUASHFS_LDIR_TYPE 8 +#define SQUASHFS_LREG_TYPE 9 + +/* 1.0 filesystem type definitions */ +#define SQUASHFS_TYPES 5 +#define SQUASHFS_IPC_TYPE 0 + +/* Flag whether block is compressed or uncompressed, bit is set if block is + * uncompressed */ +#define SQUASHFS_COMPRESSED_BIT (1 << 15) + +#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ + (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) + +#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) + +#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) + +#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \ + ~SQUASHFS_COMPRESSED_BIT_BLOCK) + +#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) + +/* + * Inode number ops. Inodes consist of a compressed block number, and an + * uncompressed offset within that block + */ +#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) + +#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) + +#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\ + << 16) + (B))) + +/* Compute 32 bit VFS inode number from squashfs inode number */ +#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \ + ((b) >> 2) + 1)) +/* XXX */ + +/* Translate between VFS mode and squashfs mode */ +#define SQUASHFS_MODE(a) ((a) & 0xfff) + +/* fragment and fragment table defines */ +#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry)) + +#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\ + sizeof(long long)) + +/* inode lookup table defines */ +#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t)) + +#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\ + sizeof(long long)) + +/* cached data constants for filesystem */ +#define SQUASHFS_CACHED_BLKS 8 + +#define SQUASHFS_MAX_FILE_SIZE_LOG 64 + +#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \ + (SQUASHFS_MAX_FILE_SIZE_LOG - 2)) + +#define SQUASHFS_MARKER_BYTE 0xff + +/* meta index cache */ +#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int)) +#define SQUASHFS_META_ENTRIES 31 +#define SQUASHFS_META_NUMBER 8 +#define SQUASHFS_SLOTS 4 + +struct meta_entry { + long long data_block; + unsigned int index_block; + unsigned short offset; + unsigned short pad; +}; + +struct meta_index { + unsigned int inode_number; + unsigned int offset; + unsigned short entries; + unsigned short skip; + unsigned short locked; + unsigned short pad; + struct meta_entry meta_entry[SQUASHFS_META_ENTRIES]; +}; + + +/* + * definitions for structures on disk + */ + +typedef long long squashfs_block_t; +typedef long long squashfs_inode_t; + +struct squashfs_super_block { + unsigned int s_magic; + unsigned int inodes; + unsigned int bytes_used_2; + unsigned int uid_start_2; + unsigned int guid_start_2; + unsigned int inode_table_start_2; + unsigned int directory_table_start_2; + unsigned int s_major:16; + unsigned int s_minor:16; + unsigned int block_size_1:16; + unsigned int block_log:16; + unsigned int flags:8; + unsigned int no_uids:8; + unsigned int no_guids:8; + unsigned int mkfs_time /* time of filesystem creation */; + squashfs_inode_t root_inode; + unsigned int block_size; + unsigned int fragments; + unsigned int fragment_table_start_2; + long long bytes_used; + long long uid_start; + long long guid_start; + long long inode_table_start; + long long directory_table_start; + long long fragment_table_start; + long long lookup_table_start; +} __attribute__ ((packed)); + +struct squashfs_dir_index { + unsigned int index; + unsigned int start_block; + unsigned char size; + unsigned char name[0]; +} __attribute__ ((packed)); + +#define SQUASHFS_BASE_INODE_HEADER \ + unsigned int inode_type:4; \ + unsigned int mode:12; \ + unsigned int uid:8; \ + unsigned int guid:8; \ + unsigned int mtime; \ + unsigned int inode_number; + +struct squashfs_base_inode_header { + SQUASHFS_BASE_INODE_HEADER; +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned short rdev; +} __attribute__ ((packed)); + +struct squashfs_symlink_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned short symlink_size; + char symlink[0]; +} __attribute__ ((packed)); + +struct squashfs_reg_inode_header { + SQUASHFS_BASE_INODE_HEADER; + squashfs_block_t start_block; + unsigned int fragment; + unsigned int offset; + unsigned int file_size; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_lreg_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + squashfs_block_t start_block; + unsigned int fragment; + unsigned int offset; + long long file_size; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned int file_size:19; + unsigned int offset:13; + unsigned int start_block; + unsigned int parent_inode; +} __attribute__ ((packed)); + +struct squashfs_ldir_inode_header { + SQUASHFS_BASE_INODE_HEADER; + unsigned int nlink; + unsigned int file_size:27; + unsigned int offset:13; + unsigned int start_block; + unsigned int i_count:16; + unsigned int parent_inode; + struct squashfs_dir_index index[0]; +} __attribute__ ((packed)); + +union squashfs_inode_header { + struct squashfs_base_inode_header base; + struct squashfs_dev_inode_header dev; + struct squashfs_symlink_inode_header symlink; + struct squashfs_reg_inode_header reg; + struct squashfs_lreg_inode_header lreg; + struct squashfs_dir_inode_header dir; + struct squashfs_ldir_inode_header ldir; + struct squashfs_ipc_inode_header ipc; +}; + +struct squashfs_dir_entry { + unsigned int offset:13; + unsigned int type:3; + unsigned int size:8; + int inode_number:16; + char name[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_header { + unsigned int count:8; + unsigned int start_block; + unsigned int inode_number; +} __attribute__ ((packed)); + +struct squashfs_fragment_entry { + long long start_block; + unsigned int size; + unsigned int pending; +} __attribute__ ((packed)); + +extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); +extern int squashfs_uncompress_init(void); +extern int squashfs_uncompress_exit(void); + +/* + * macros to convert each packed bitfield structure from little endian to big + * endian and vice versa. These are needed when creating or using a filesystem + * on a machine with different byte ordering to the target architecture. + * + */ + +#define SQUASHFS_SWAP_START \ + int bits;\ + int b_pos;\ + unsigned long long val;\ + unsigned char *s;\ + unsigned char *d; + +#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\ + SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ + SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ + SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\ + SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\ + SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\ + SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\ + SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\ + SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ + SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ + SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ + SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ + SQUASHFS_SWAP((s)->flags, d, 288, 8);\ + SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ + SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ + SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ + SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ + SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ + SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ + SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\ + SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\ + SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\ + SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\ + SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\ + SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\ + SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\ + SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\ +} + +#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ + SQUASHFS_MEMSET(s, d, n);\ + SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ + SQUASHFS_SWAP((s)->mode, d, 4, 12);\ + SQUASHFS_SWAP((s)->uid, d, 16, 8);\ + SQUASHFS_SWAP((s)->guid, d, 24, 8);\ + SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ + SQUASHFS_SWAP((s)->inode_number, d, 64, 32); + +#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\ +} + +#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_ipc_inode_header))\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ +} + +#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_dev_inode_header)); \ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->rdev, d, 128, 16);\ +} + +#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_symlink_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\ +} + +#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_reg_inode_header));\ + SQUASHFS_SWAP((s)->start_block, d, 96, 64);\ + SQUASHFS_SWAP((s)->fragment, d, 160, 32);\ + SQUASHFS_SWAP((s)->offset, d, 192, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 224, 32);\ +} + +#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_lreg_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 128, 64);\ + SQUASHFS_SWAP((s)->fragment, d, 192, 32);\ + SQUASHFS_SWAP((s)->offset, d, 224, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 256, 64);\ +} + +#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_dir_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 128, 19);\ + SQUASHFS_SWAP((s)->offset, d, 147, 13);\ + SQUASHFS_SWAP((s)->start_block, d, 160, 32);\ + SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\ +} + +#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \ + sizeof(struct squashfs_ldir_inode_header));\ + SQUASHFS_SWAP((s)->nlink, d, 96, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 128, 27);\ + SQUASHFS_SWAP((s)->offset, d, 155, 13);\ + SQUASHFS_SWAP((s)->start_block, d, 168, 32);\ + SQUASHFS_SWAP((s)->i_count, d, 200, 16);\ + SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\ +} + +#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\ + SQUASHFS_SWAP((s)->index, d, 0, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 32, 32);\ + SQUASHFS_SWAP((s)->size, d, 64, 8);\ +} + +#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\ + SQUASHFS_SWAP((s)->count, d, 0, 8);\ + SQUASHFS_SWAP((s)->start_block, d, 8, 32);\ + SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\ +} + +#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\ + SQUASHFS_SWAP((s)->offset, d, 0, 13);\ + SQUASHFS_SWAP((s)->type, d, 13, 3);\ + SQUASHFS_SWAP((s)->size, d, 16, 8);\ + SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\ + SQUASHFS_SWAP((s)->start_block, d, 0, 64);\ + SQUASHFS_SWAP((s)->size, d, 64, 32);\ +} + +#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1) + +#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * 2);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 16)\ + SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ +} + +#define SQUASHFS_SWAP_INTS(s, d, n) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * 4);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 32)\ + SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ +} + +#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * 8);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + 64)\ + SQUASHFS_SWAP(s[entry], d, bit_position, 64);\ +} + +#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ + int entry;\ + int bit_position;\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, n * bits / 8);\ + for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \ + bits)\ + SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) +#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n) + +#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY + +struct squashfs_base_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned int type:4; + unsigned int offset:4; +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned short rdev; +} __attribute__ ((packed)); + +struct squashfs_symlink_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned short symlink_size; + char symlink[0]; +} __attribute__ ((packed)); + +struct squashfs_reg_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned int mtime; + unsigned int start_block; + unsigned int file_size:32; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header_1 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:4; /* index into uid table */ + unsigned int guid:4; /* index into guid table */ + unsigned int file_size:19; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; +} __attribute__ ((packed)); + +union squashfs_inode_header_1 { + struct squashfs_base_inode_header_1 base; + struct squashfs_dev_inode_header_1 dev; + struct squashfs_symlink_inode_header_1 symlink; + struct squashfs_reg_inode_header_1 reg; + struct squashfs_dir_inode_header_1 dir; + struct squashfs_ipc_inode_header_1 ipc; +}; + +#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \ + SQUASHFS_MEMSET(s, d, n);\ + SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ + SQUASHFS_SWAP((s)->mode, d, 4, 12);\ + SQUASHFS_SWAP((s)->uid, d, 16, 4);\ + SQUASHFS_SWAP((s)->guid, d, 20, 4); + +#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\ +} + +#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_ipc_inode_header_1));\ + SQUASHFS_SWAP((s)->type, d, 24, 4);\ + SQUASHFS_SWAP((s)->offset, d, 28, 4);\ +} + +#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_dev_inode_header_1));\ + SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ +} + +#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_symlink_inode_header_1));\ + SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ +} + +#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_reg_inode_header_1));\ + SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 88, 32);\ +} + +#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \ + sizeof(struct squashfs_dir_inode_header_1));\ + SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ + SQUASHFS_SWAP((s)->offset, d, 43, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ +} + +#endif + +#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY + +struct squashfs_dir_index_2 { + unsigned int index:27; + unsigned int start_block:29; + unsigned char size; + unsigned char name[0]; +} __attribute__ ((packed)); + +struct squashfs_base_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_ipc_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ +} __attribute__ ((packed)); + +struct squashfs_dev_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned short rdev; +} __attribute__ ((packed)); + +struct squashfs_symlink_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned short symlink_size; + char symlink[0]; +} __attribute__ ((packed)); + +struct squashfs_reg_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int mtime; + unsigned int start_block; + unsigned int fragment; + unsigned int offset; + unsigned int file_size:32; + unsigned short block_list[0]; +} __attribute__ ((packed)); + +struct squashfs_dir_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int file_size:19; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; +} __attribute__ ((packed)); + +struct squashfs_ldir_inode_header_2 { + unsigned int inode_type:4; + unsigned int mode:12; /* protection */ + unsigned int uid:8; /* index into uid table */ + unsigned int guid:8; /* index into guid table */ + unsigned int file_size:27; + unsigned int offset:13; + unsigned int mtime; + unsigned int start_block:24; + unsigned int i_count:16; + struct squashfs_dir_index_2 index[0]; +} __attribute__ ((packed)); + +union squashfs_inode_header_2 { + struct squashfs_base_inode_header_2 base; + struct squashfs_dev_inode_header_2 dev; + struct squashfs_symlink_inode_header_2 symlink; + struct squashfs_reg_inode_header_2 reg; + struct squashfs_dir_inode_header_2 dir; + struct squashfs_ldir_inode_header_2 ldir; + struct squashfs_ipc_inode_header_2 ipc; +}; + +struct squashfs_dir_header_2 { + unsigned int count:8; + unsigned int start_block:24; +} __attribute__ ((packed)); + +struct squashfs_dir_entry_2 { + unsigned int offset:13; + unsigned int type:3; + unsigned int size:8; + char name[0]; +} __attribute__ ((packed)); + +struct squashfs_fragment_entry_2 { + unsigned int start_block; + unsigned int size; +} __attribute__ ((packed)); + +#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ + SQUASHFS_MEMSET(s, d, n);\ + SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ + SQUASHFS_SWAP((s)->mode, d, 4, 12);\ + SQUASHFS_SWAP((s)->uid, d, 16, 8);\ + SQUASHFS_SWAP((s)->guid, d, 24, 8);\ + +#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\ +} + +#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \ + SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2)) + +#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_dev_inode_header_2)); \ + SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ +} + +#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_symlink_inode_header_2));\ + SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ +} + +#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_reg_inode_header_2));\ + SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ + SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ + SQUASHFS_SWAP((s)->offset, d, 128, 32);\ + SQUASHFS_SWAP((s)->file_size, d, 160, 32);\ +} + +#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_dir_inode_header_2));\ + SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ + SQUASHFS_SWAP((s)->offset, d, 51, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ +} + +#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \ + sizeof(struct squashfs_ldir_inode_header_2));\ + SQUASHFS_SWAP((s)->file_size, d, 32, 27);\ + SQUASHFS_SWAP((s)->offset, d, 59, 13);\ + SQUASHFS_SWAP((s)->mtime, d, 72, 32);\ + SQUASHFS_SWAP((s)->start_block, d, 104, 24);\ + SQUASHFS_SWAP((s)->i_count, d, 128, 16);\ +} + +#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\ + SQUASHFS_SWAP((s)->index, d, 0, 27);\ + SQUASHFS_SWAP((s)->start_block, d, 27, 29);\ + SQUASHFS_SWAP((s)->size, d, 56, 8);\ +} +#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\ + SQUASHFS_SWAP((s)->count, d, 0, 8);\ + SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ +} + +#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\ + SQUASHFS_SWAP((s)->offset, d, 0, 13);\ + SQUASHFS_SWAP((s)->type, d, 13, 3);\ + SQUASHFS_SWAP((s)->size, d, 16, 8);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\ + SQUASHFS_SWAP_START\ + SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\ + SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ + SQUASHFS_SWAP((s)->size, d, 32, 32);\ +} + +#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) + +/* fragment and fragment table defines */ +#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2)) + +#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \ + SQUASHFS_METADATA_SIZE - 1) / \ + SQUASHFS_METADATA_SIZE) + +#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\ + sizeof(int)) + +#endif + +#ifdef __KERNEL__ + +/* + * macros used to swap each structure entry, taking into account + * bitfields and different bitfield placing conventions on differing + * architectures + */ + +#include + +#ifdef __BIG_ENDIAN + /* convert from little endian to big endian */ +#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ + tbits, b_pos) +#else + /* convert from big endian to little endian */ +#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \ + tbits, 64 - tbits - b_pos) +#endif + +#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ + b_pos = pos % 8;\ + val = 0;\ + s = (unsigned char *)p + (pos / 8);\ + d = ((unsigned char *) &val) + 7;\ + for(bits = 0; bits < (tbits + b_pos); bits += 8) \ + *d-- = *s++;\ + value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ +} + +#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); + +#endif +#endif --- linux-2.6.28.orig/ubuntu/drbd/drbd_int.h +++ linux-2.6.28/ubuntu/drbd/drbd_int.h @@ -0,0 +1,2130 @@ +/* + drbd_int.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef _DRBD_INT_H +#define _DRBD_INT_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "lru_cache.h" + +#ifdef __CHECKER__ +# define __protected_by(x) __attribute__((require_context(x,1,999,"rdwr"))) +# define __protected_read_by(x) __attribute__((require_context(x,1,999,"read"))) +# define __protected_write_by(x) __attribute__((require_context(x,1,999,"write"))) +# define __must_hold(x) __attribute__((context(x,1,1), require_context(x,1,999,"call"))) +#else +# define __protected_by(x) +# define __protected_read_by(x) +# define __protected_write_by(x) +# define __must_hold(x) +#endif + +#define __no_warn(lock, stmt) do { __acquire(lock); stmt; __release(lock); } while (0) + +/* Compatibility for older kernels */ +#ifndef __acquires +# ifdef __CHECKER__ +# define __acquires(x) __attribute__((context(x,0,1))) +# define __releases(x) __attribute__((context(x,1,0))) +# define __acquire(x) __context__(x,1) +# define __release(x) __context__(x,-1) +# define __cond_lock(x,c) ((c) ? ({ __acquire(x); 1; }) : 0) +# else +# define __acquires(x) +# define __releases(x) +# define __acquire(x) (void)0 +# define __release(x) (void)0 +# define __cond_lock(x,c) (c) +# endif +#endif + +/* module parameter, defined in drbd_main.c */ +extern int minor_count; +extern int allow_oos; + +#ifdef DRBD_ENABLE_FAULTS +extern int enable_faults; +extern int fault_rate; +extern int fault_devs; +#endif + +extern char usermode_helper[]; + +#include +#ifndef DRBD_MAJOR +# define DRBD_MAJOR 147 +#endif + +#include +#include + +// XXX do we need this? +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +/* I don't remember why XCPU ... + * This is used to wake the asender, + * and to interrupt sending the sending task + * on disconnect. + */ +#define DRBD_SIG SIGXCPU + +/* This is used to stop/restart our threads. + * Cannot use SIGTERM nor SIGKILL, since these + * are sent out by init on runlevel changes + * I choose SIGHUP for now. + * + * FIXME btw, we should register some reboot notifier. + */ +#define DRBD_SIGKILL SIGHUP + +/* All EEs on the free list should have ID_VACANT (== 0) + * freshly allocated EEs get !ID_VACANT (== 1) + * so if it says "cannot dereference null pointer at adress 0x00000001", + * it is most likely one of these :( */ + +#define ID_IN_SYNC (4711ULL) +#define ID_OUT_OF_SYNC (4712ULL) + +#define ID_SYNCER (-1ULL) +#define ID_VACANT 0 +#define is_syncer_block_id(id) ((id) == ID_SYNCER) + +struct drbd_conf; + +#ifdef DBG_ALL_SYMBOLS +# define STATIC +#else +# define STATIC static +#endif + +#ifdef PARANOIA +# define PARANOIA_BUG_ON(x) BUG_ON(x) +#else +# define PARANOIA_BUG_ON(x) +#endif + +/* + * Some Message Macros + *************************/ + +/* handy macro: DUMPP(somepointer) */ +#define DUMPP(A) ERR( #A " = %p in %s:%d\n", (A), __FILE__, __LINE__); +#define DUMPLU(A) ERR( #A " = %lu in %s:%d\n", (unsigned long)(A), __FILE__, __LINE__); +#define DUMPLLU(A) ERR( #A " = %llu in %s:%d\n", (unsigned long long)(A), __FILE__, __LINE__); +#define DUMPLX(A) ERR( #A " = %lx in %s:%d\n", (A), __FILE__, __LINE__); +#define DUMPI(A) ERR( #A " = %d in %s:%d\n", (int)(A), __FILE__, __LINE__); + +#define DUMPST(A) DUMPLLU((unsigned long long)(A)) + +#if 0 +#define D_DUMPP(A) DUMPP(A) +#define D_DUMPLU(A) DUMPLU(A) +#define D_DUMPLLU(A) DUMPLLU(A) +#define D_DUMPLX(A) DUMPLX(A) +#define D_DUMPI(A) DUMPI(A) +#else +#define D_DUMPP(A) +#define D_DUMPLU(A) +#define D_DUMPLLU(A) +#define D_DUMPLX(A) +#define D_DUMPI(A) +#endif + +/* Info: do not remove the spaces around the "," before ## + * Otherwise this is not portable from gcc-2.95 to gcc-3.3 */ +#define PRINTK(level, fmt, args...) \ + printk(level "drbd%d: " fmt, \ + mdev->minor , ##args) + +#define ALERT(fmt, args...) PRINTK(KERN_ALERT, fmt , ##args) +#define ERR(fmt, args...) PRINTK(KERN_ERR, fmt , ##args) +#define DRBD_WARN(fmt, args...) PRINTK(KERN_WARNING, fmt , ##args) +#define INFO(fmt, args...) PRINTK(KERN_INFO, fmt , ##args) +#define DBG(fmt, args...) PRINTK(KERN_DEBUG, fmt , ##args) + +/* see kernel/printk.c:printk_ratelimit + * macro, so it is easy do have independend rate limits at different locations + * "initializer element not constant ..." with kernel 2.4 :( + * so I initialize toks to something large + */ +#define DRBD_ratelimit(ratelimit_jiffies, ratelimit_burst) \ +({ \ + int __ret; \ + static unsigned long toks = 0x80000000UL; \ + static unsigned long last_msg; \ + static int missed; \ + unsigned long now = jiffies; \ + toks += now - last_msg; \ + last_msg = now; \ + if (toks > (ratelimit_burst * ratelimit_jiffies)) \ + toks = ratelimit_burst * ratelimit_jiffies; \ + if (toks >= ratelimit_jiffies) { \ + int lost = missed; \ + missed = 0; \ + toks -= ratelimit_jiffies; \ + if (lost) \ + DRBD_WARN("%d messages suppressed in %s:%d.\n", \ + lost , __FILE__ , __LINE__ ); \ + __ret = 1; \ + } else { \ + missed++; \ + __ret = 0; \ + } \ + __ret; \ +}) + + +#ifdef DBG_ASSERTS +extern void drbd_assert_breakpoint(struct drbd_conf *, char *, char *, int ); +# define D_ASSERT(exp) if (!(exp)) \ + drbd_assert_breakpoint(mdev, #exp, __FILE__, __LINE__) +#else +# define D_ASSERT(exp) if (!(exp)) \ + ERR("ASSERT( " #exp " ) in %s:%d\n", __FILE__, __LINE__) +#endif +#define ERR_IF(exp) if (({ \ + int _b = (exp)!=0; \ + if (_b) ERR("%s: (%s) in %s:%d\n", \ + __func__, #exp, __FILE__,__LINE__); \ + _b; \ + })) + +/* Defines to control fault insertion */ +enum { + DRBD_FAULT_MD_WR = 0, /* meta data write */ + DRBD_FAULT_MD_RD, /* read */ + DRBD_FAULT_RS_WR, /* resync */ + DRBD_FAULT_RS_RD, + DRBD_FAULT_DT_WR, /* data */ + DRBD_FAULT_DT_RD, + DRBD_FAULT_DT_RA, /* data read ahead */ + + DRBD_FAULT_MAX, +}; + +#ifdef DRBD_ENABLE_FAULTS +extern unsigned int +_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type); +static inline int +drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) { + return (fault_rate && + (enable_faults & (1< +/* integer division, round _UP_ to the next integer */ +#define div_ceil(A, B) ( (A)/(B) + ((A)%(B) ? 1 : 0) ) +/* usual integer division */ +#define div_floor(A, B) ( (A)/(B) ) + +/* + * Compatibility Section + *************************/ + +#define LOCK_SIGMASK(task, flags) spin_lock_irqsave(&task->sighand->siglock, flags) +#define UNLOCK_SIGMASK(task, flags) spin_unlock_irqrestore(&task->sighand->siglock, flags) +#define RECALC_SIGPENDING() recalc_sigpending(); + +#if defined(DBG_SPINLOCKS) && defined(__SMP__) +# define MUST_HOLD(lock) if (!spin_is_locked(lock)) { ERR("Not holding lock! in %s\n", __FUNCTION__ ); } +#else +# define MUST_HOLD(lock) +#endif + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8) +# define HAVE_KERNEL_SENDMSG 1 +#else +# define HAVE_KERNEL_SENDMSG 0 +#endif + + +/* + * our structs + *************************/ + +#define SET_MDEV_MAGIC(x) \ + ({ typecheck(struct drbd_conf*, x); \ + (x)->magic = (long)(x) ^ DRBD_MAGIC; }) +#define IS_VALID_MDEV(x) \ + ( typecheck(struct drbd_conf*, x) && \ + ((x) ? (((x)->magic ^ DRBD_MAGIC) == (long)(x)):0)) + +/* drbd_meta-data.c (still in drbd_main.c) */ +/* 4th incarnation of the disk layout. */ +#define DRBD_MD_MAGIC (DRBD_MAGIC+4) + +extern struct drbd_conf **minor_table; + +/*** + * on the wire + *********************************************************************/ + +enum Drbd_Packet_Cmd { + Data, + DataReply, /* Response to DataRequest */ + RSDataReply, /* Response to RSDataRequest */ + Barrier, + ReportBitMap, + BecomeSyncTarget, + BecomeSyncSource, + UnplugRemote, /* Used at various times to hint the peer */ + DataRequest, /* Used to ask for a data block */ + RSDataRequest, /* Used to ask for a data block for resync */ + SyncParam, + ReportProtocol, + ReportUUIDs, + ReportSizes, + ReportState, + ReportSyncUUID, + AuthChallenge, + AuthResponse, + StateChgRequest, + + FIRST_ASENDER_CMD, + Ping = FIRST_ASENDER_CMD, + PingAck, + RecvAck, /* Used in protocol B */ + WriteAck, /* Used in protocol C */ + RSWriteAck, /* Is a WriteAck, additionally call set_in_sync(). */ + DiscardAck, /* Used in proto C, two-primaries conflict detection */ + NegAck, /* Sent if local disk is unusable */ + NegDReply, /* Local disk is broken... */ + NegRSDReply, /* Local disk is broken... */ + BarrierAck, + StateChgReply, + LAST_ASENDER_CMD = StateChgReply, + + OVRequest, + OVReply, + OVResult, // Exception to the FIRST/LAST ASENDER_CMD + + MAX_CMD, + MayIgnore = 0x100, /* Flag to test if (cmd > MayIgnore) ... */ + MAX_OPT_CMD, + + /* FIXME + * to get a more useful error message with drbd-8 <-> drbd 0.7.x, + * these could be reimplemented as special case of HandShake. */ + HandShakeM = 0xfff1, /* First Packet on the MetaSock */ + HandShakeS = 0xfff2, /* First Packet on the Socket */ + + HandShake = 0xfffe /* FIXED for the next century! */ +}; + +static inline const char *cmdname(enum Drbd_Packet_Cmd cmd) +{ + /* THINK may need to become several global tables + * when we want to support more than + * one PRO_VERSION */ + static const char *cmdnames[] = { + [Data] = "Data", + [DataReply] = "DataReply", + [RSDataReply] = "RSDataReply", + [Barrier] = "Barrier", + [ReportBitMap] = "ReportBitMap", + [BecomeSyncTarget] = "BecomeSyncTarget", + [BecomeSyncSource] = "BecomeSyncSource", + [UnplugRemote] = "UnplugRemote", + [DataRequest] = "DataRequest", + [RSDataRequest] = "RSDataRequest", + [SyncParam] = "SyncParam", + [ReportProtocol] = "ReportProtocol", + [ReportUUIDs] = "ReportUUIDs", + [ReportSizes] = "ReportSizes", + [ReportState] = "ReportState", + [ReportSyncUUID] = "ReportSyncUUID", + [AuthChallenge] = "AuthChallenge", + [AuthResponse] = "AuthResponse", + [Ping] = "Ping", + [PingAck] = "PingAck", + [RecvAck] = "RecvAck", + [WriteAck] = "WriteAck", + [RSWriteAck] = "RSWriteAck", + [DiscardAck] = "DiscardAck", + [NegAck] = "NegAck", + [NegDReply] = "NegDReply", + [NegRSDReply] = "NegRSDReply", + [BarrierAck] = "BarrierAck", + [StateChgRequest] = "StateChgRequest", + [StateChgReply] = "StateChgReply", + [OVRequest] = "OVRequest", + [OVReply] = "OVReply", + [OVResult] = "OVResult", + }; + + if (Data > cmd || cmd >= MAX_CMD) { + switch (cmd) { + case HandShakeM: + return "HandShakeM"; + break; + case HandShakeS: + return "HandShakeS"; + break; + case HandShake: + return "HandShake"; + break; + default: + return "Unknown"; + break; + } + } + return cmdnames[cmd]; +} + + +/* This is the layout for a packet on the wire. + * The byteorder is the network byte order. + * (except block_id and barrier fields. + * these are pointers to local structs + * and have no relevance for the partner, + * which just echoes them as received.) + * + * NOTE that the payload starts at a long aligned offset, + * regardless of 32 or 64 bit arch! + */ +struct Drbd_Header { + u32 magic; + u16 command; + u16 length; /* bytes of data after this header */ + char payload[0]; +} __attribute((packed)); +/* 8 bytes. packet FIXED for the next century! */ + +/* + * short commands, packets without payload, plain Drbd_Header: + * Ping + * PingAck + * BecomeSyncTarget + * BecomeSyncSource + * UnplugRemote + */ + +/* + * commands with out-of-struct payload: + * ReportBitMap (no additional fields) + * Data, DataReply (see Drbd_Data_Packet) + */ + +#define DP_HARDBARRIER 1 +#define DP_RW_SYNC 2 +#define DP_MAY_SET_IN_SYNC 4 + +struct Drbd_Data_Packet { + struct Drbd_Header head; + u64 sector; /* 64 bits sector number */ + u64 block_id; /* to identify the request in protocol B&C */ + u32 seq_num; + u32 dp_flags; +} __attribute((packed)); + +/* + * commands which share a struct: + * Drbd_BlockAck_Packet: + * RecvAck (proto B), WriteAck (proto C), + * DiscardAck (proto C, two-primaries conflict detection) + * Drbd_BlockRequest_Packet: + * DataRequest, RSDataRequest + */ +struct Drbd_BlockAck_Packet { + struct Drbd_Header head; + u64 sector; + u64 block_id; + u32 blksize; + u32 seq_num; +} __attribute((packed)); + + +struct Drbd_BlockRequest_Packet { + struct Drbd_Header head; + u64 sector; + u64 block_id; + u32 blksize; + u32 pad; /* to multiple of 8 Byte */ +} __attribute((packed)); + +/* + * commands with their own struct for additional fields: + * HandShake + * Barrier + * BarrierAck + * SyncParam + * ReportParams + */ + +struct Drbd_HandShake_Packet { + struct Drbd_Header head; /* 8 bytes */ + u32 protocol_min; + u32 feature_flags; + u32 protocol_max; + + /* should be more than enough for future enhancements + * for now, feature_flags and the reserverd array shall be zero. + */ + + u32 _pad; + u64 reserverd[7]; +} __attribute((packed)); +/* 80 bytes, FIXED for the next century */ + +struct Drbd_Barrier_Packet { + struct Drbd_Header head; + u32 barrier; /* barrier number _handle_ only */ + u32 pad; /* to multiple of 8 Byte */ +} __attribute((packed)); + +struct Drbd_BarrierAck_Packet { + struct Drbd_Header head; + u32 barrier; + u32 set_size; +} __attribute((packed)); + +struct Drbd_SyncParam_Packet { + struct Drbd_Header head; + u32 rate; + + /* Since protocol version 88 and higher. */ + char online_verify_alg[0]; +} __attribute((packed)); + +struct Drbd_Protocol_Packet { + struct Drbd_Header head; + u32 protocol; + u32 after_sb_0p; + u32 after_sb_1p; + u32 after_sb_2p; + u32 want_lose; + u32 two_primaries; + + /* Since protocol version 87 and higher. */ + char integrity_alg[0]; + +} __attribute((packed)); + +struct Drbd_GenCnt_Packet { + struct Drbd_Header head; + u64 uuid[EXT_UUID_SIZE]; +} __attribute((packed)); + +struct Drbd_SyncUUID_Packet { + struct Drbd_Header head; + u64 uuid; +} __attribute((packed)); + +struct Drbd_Sizes_Packet { + struct Drbd_Header head; + u64 d_size; /* size of disk */ + u64 u_size; /* user requested size */ + u64 c_size; /* current exported size */ + u32 max_segment_size; /* Maximal size of a BIO */ + u32 queue_order_type; +} __attribute((packed)); + +struct Drbd_State_Packet { + struct Drbd_Header head; + u32 state; +} __attribute((packed)); + +struct Drbd_Req_State_Packet { + struct Drbd_Header head; + u32 mask; + u32 val; +} __attribute((packed)); + +struct Drbd_RqS_Reply_Packet { + struct Drbd_Header head; + u32 retcode; +} __attribute((packed)); + +struct Drbd06_Parameter_P { + u64 size; + u32 state; + u32 blksize; + u32 protocol; + u32 version; + u32 gen_cnt[5]; + u32 bit_map_gen[5]; +} __attribute((packed)); + +struct Drbd_Discard_Packet { + struct Drbd_Header head; + u64 block_id; + u32 seq_num; + u32 pad; +} __attribute((packed)); + +union Drbd_Polymorph_Packet { + struct Drbd_Header head; + struct Drbd_HandShake_Packet HandShake; + struct Drbd_Data_Packet Data; + struct Drbd_BlockAck_Packet BlockAck; + struct Drbd_Barrier_Packet Barrier; + struct Drbd_BarrierAck_Packet BarrierAck; + struct Drbd_SyncParam_Packet SyncParam; + struct Drbd_Protocol_Packet Protocol; + struct Drbd_Sizes_Packet Sizes; + struct Drbd_GenCnt_Packet GenCnt; + struct Drbd_State_Packet State; + struct Drbd_Req_State_Packet ReqState; + struct Drbd_RqS_Reply_Packet RqSReply; + struct Drbd_BlockRequest_Packet BlockRequest; +} __attribute((packed)); + +/**********************************************************************/ +enum Drbd_thread_state { + None, + Running, + Exiting, + Restarting +}; + +struct Drbd_thread { + spinlock_t t_lock; + struct task_struct *task; + struct completion startstop; + enum Drbd_thread_state t_state; + int (*function) (struct Drbd_thread *); + struct drbd_conf *mdev; + struct mutex task_mutex; +}; + +static inline enum Drbd_thread_state get_t_state(struct Drbd_thread *thi) +{ + /* THINK testing the t_state seems to be uncritical in all cases + * (but thread_{start,stop}), so we can read it *without* the lock. + * --lge */ + + smp_rmb(); + return thi->t_state; +} + + +/* + * Having this as the first member of a struct provides sort of "inheritance". + * "derived" structs can be "drbd_queue_work()"ed. + * The callback should know and cast back to the descendant struct. + * drbd_request and Tl_epoch_entry are descendants of drbd_work. + */ +struct drbd_work; +typedef int (*drbd_work_cb)(struct drbd_conf *, struct drbd_work *, int cancel); +struct drbd_work { + struct list_head list; + drbd_work_cb cb; +}; + +struct drbd_barrier; +struct drbd_request { + struct drbd_work w; + struct drbd_conf *mdev; + struct bio *private_bio; + struct hlist_node colision; + sector_t sector; + unsigned int size; + unsigned int epoch; /* barrier_nr */ + + /* barrier_nr: used to check on "completion" whether this req was in + * the current epoch, and we therefore have to close it, + * starting a new epoch... + */ + + /* up to here, the struct layout is identical to Tl_epoch_entry; + * we might be able to use that to our advantage... */ + + struct list_head tl_requests; /* ring list in the transfer log */ + struct bio *master_bio; /* master bio pointer */ + unsigned long rq_state; /* see comments above _req_mod() */ + int seq_num; + unsigned long start_time; +}; + +struct drbd_barrier { + struct drbd_work w; + struct list_head requests; /* requests before */ + struct drbd_barrier *next; /* pointer to the next barrier */ + unsigned int br_number; /* the barriers identifier. */ + int n_req; /* number of requests attached before this barrier */ +}; + +struct drbd_request; + +/* These Tl_epoch_entries may be in one of 6 lists: + active_ee .. data packet being written + sync_ee .. syncer block being written + done_ee .. block written, need to send WriteAck + read_ee .. [RS]DataRequest being read +*/ + +struct Tl_epoch_entry { + struct drbd_work w; + struct drbd_conf *mdev; + struct bio *private_bio; + struct hlist_node colision; + sector_t sector; + unsigned int size; + unsigned int barrier_nr; + + /* up to here, the struct layout is identical to drbd_request; + * we might be able to use that to our advantage... */ + + unsigned int barrier_nr2; + /* If we issue the bio with BIO_RW_BARRIER we have to + send a barrier ACK before we send the ACK to this + write. We store the barrier number in here. + In case the barrier after this write has been coalesced + as well, we set it's barrier_nr into barrier_nr2 */ + + unsigned int flags; + u64 block_id; +}; + +struct digest_info { + int digest_size; + void *digest; +}; + +/* ee flag bits */ +enum { + __EE_CALL_AL_COMPLETE_IO, + __EE_CONFLICT_PENDING, + __EE_MAY_SET_IN_SYNC, +}; +#define EE_CALL_AL_COMPLETE_IO (1<<__EE_CALL_AL_COMPLETE_IO) +#define EE_CONFLICT_PENDING (1<<__EE_CONFLICT_PENDING) +#define EE_MAY_SET_IN_SYNC (1<<__EE_MAY_SET_IN_SYNC) + +/* global flag bits */ +enum { + CREATE_BARRIER, /* next Data is preceeded by a Barrier */ + SIGNAL_ASENDER, /* whether asender wants to be interrupted */ + SEND_PING, /* whether asender should send a ping asap */ + WRITE_ACK_PENDING, /* so BarrierAck won't overtake WriteAck */ + WORK_PENDING, /* completion flag for drbd_disconnect */ + STOP_SYNC_TIMER, /* tell timer to cancel itself */ + UNPLUG_QUEUED, /* only relevant with kernel 2.4 */ + UNPLUG_REMOTE, /* sending a "UnplugRemote" could help */ + MD_DIRTY, /* current uuids and flags not yet on disk */ + DISCARD_CONCURRENT, /* Set on one node, cleared on the peer! */ + USE_DEGR_WFC_T, /* degr-wfc-timeout instead of wfc-timeout. */ + CLUSTER_ST_CHANGE, /* Cluster wide state change going on... */ + CL_ST_CHG_SUCCESS, + CL_ST_CHG_FAIL, + CRASHED_PRIMARY, /* This node was a crashed primary. + * Gets cleared when the state.conn + * goes into Connected state. */ + WRITE_BM_AFTER_RESYNC, /* A kmalloc() during resync failed */ + NO_BARRIER_SUPP, /* underlying block device doesn't implement barriers */ + CONSIDER_RESYNC, + + LL_DEV_NO_FLUSH, /* blkdev_issue_flush does not work, + so don't even try */ + MD_NO_BARRIER, /* meta data device does not support barriers, + so don't even try */ + BITMAP_IO, /* Let user IO drain */ + BITMAP_IO_QUEUED, /* Started bitmap IO */ +}; + +struct drbd_bitmap; /* opaque for drbd_conf */ + +/* TODO sort members for performance + * MAYBE group them further */ + +/* THINK maybe we actually want to use the default "event/%s" worker threads + * or similar in linux 2.6, which uses per cpu data and threads. + * + * To be general, this might need a spin_lock member. + * For now, please use the mdev->req_lock to protect list_head, + * see drbd_queue_work below. + */ +struct drbd_work_queue { + struct list_head q; + struct semaphore s; /* producers up it, worker down()s it */ + spinlock_t q_lock; /* to protect the list. */ +}; + +/* If Philipp agrees, we remove the "mutex", and make_request will only + * (throttle on "queue full" condition and) queue it to the worker thread... + * which then is free to do whatever is needed, and has exclusive send access + * to the data socket ... + */ +struct drbd_socket { + struct drbd_work_queue work; + struct semaphore mutex; + struct socket *socket; + /* this way we get our + * send/receive buffers off the stack */ + union Drbd_Polymorph_Packet sbuf; + union Drbd_Polymorph_Packet rbuf; +}; + +struct drbd_md { + u64 md_offset; /* sector offset to 'super' block */ + + u64 la_size_sect; /* last agreed size, unit sectors */ + u64 uuid[UUID_SIZE]; + u64 device_uuid; + u32 flags; + u32 md_size_sect; + + s32 al_offset; /* signed relative sector offset to al area */ + s32 bm_offset; /* signed relative sector offset to bitmap */ + + /* u32 al_nr_extents; important for restoring the AL + * is stored into sync_conf.al_extents, which in turn + * gets applied to act_log->nr_elements + */ +}; + +// for sync_conf and other types... +#define NL_PACKET(name, number, fields) struct name { fields }; +#define NL_INTEGER(pn,pr,member) int member; +#define NL_INT64(pn,pr,member) __u64 member; +#define NL_BIT(pn,pr,member) unsigned member : 1; +#define NL_STRING(pn,pr,member,len) unsigned char member[len]; int member ## _len; +#include "linux/drbd_nl.h" + +struct drbd_backing_dev { + struct block_device *backing_bdev; + struct block_device *md_bdev; + struct file *lo_file; + struct file *md_file; + struct drbd_md md; + struct disk_conf dc; /* The user provided config... */ + sector_t known_size; +}; + +struct drbd_md_io { + struct drbd_conf *mdev; + struct completion event; + int error; +}; + +struct bm_io_work { + struct drbd_work w; + int (*io_fn)(struct drbd_conf *mdev); + void (*done)(struct drbd_conf *mdev, int rv); +}; + +struct drbd_conf { +#ifdef PARANOIA + long magic; +#endif + /* things that are stored as / read from meta data on disk */ + unsigned long flags; + + /* configured by drbdsetup */ + struct net_conf *net_conf; /* protected by inc_net() and dec_net() */ + struct syncer_conf sync_conf; + struct drbd_backing_dev *bc __protected_by(local); + + sector_t p_size; /* partner's disk size */ + struct request_queue *rq_queue; + struct block_device *this_bdev; + struct gendisk *vdisk; + + struct drbd_socket data; /* data/barrier/cstate/parameter packets */ + struct drbd_socket meta; /* ping/ack (metadata) packets */ + int agreed_pro_version; /* actually used protocol version */ + unsigned long last_received; /* in jiffies, either socket */ + unsigned int ko_count; + struct drbd_work resync_work, + unplug_work, + md_sync_work; + struct timer_list resync_timer; + struct timer_list md_sync_timer; + + /* Used after attach while negotiating new disk state. */ + union drbd_state_t new_state_tmp; + + union drbd_state_t state; + wait_queue_head_t misc_wait; + wait_queue_head_t state_wait; /* upon each state change. */ + unsigned int send_cnt; + unsigned int recv_cnt; + unsigned int read_cnt; + unsigned int writ_cnt; + unsigned int al_writ_cnt; + unsigned int bm_writ_cnt; + atomic_t ap_bio_cnt; /* Requests we need to complete */ + atomic_t ap_pending_cnt; /* AP data packets on the wire, ack expected */ + atomic_t rs_pending_cnt; /* RS request/data packets on the wire */ + atomic_t unacked_cnt; /* Need to send replys for */ + atomic_t local_cnt; /* Waiting for local completion */ + atomic_t net_cnt; /* Users of net_conf */ + spinlock_t req_lock; + struct drbd_barrier *unused_spare_barrier; /* for pre-allocation */ + struct drbd_barrier *newest_barrier; + struct drbd_barrier *oldest_barrier; + struct hlist_head *tl_hash; + unsigned int tl_hash_s; + + /* blocks to sync in this run [unit BM_BLOCK_SIZE] */ + unsigned long rs_total; + /* number of sync IOs that failed in this run */ + unsigned long rs_failed; + /* Syncer's start time [unit jiffies] */ + unsigned long rs_start; + /* cumulated time in PausedSyncX state [unit jiffies] */ + unsigned long rs_paused; + /* block not up-to-date at mark [unit BM_BLOCK_SIZE] */ + unsigned long rs_mark_left; + /* marks's time [unit jiffies] */ + unsigned long rs_mark_time; + + sector_t ov_position; + sector_t ov_last_oos_start; /* Start sector of out of sync range */ + sector_t ov_last_oos_size; /* size of out-of-sync range in sectors */ + unsigned long ov_left; + struct crypto_hash *verify_tfm; + + struct Drbd_thread receiver; + struct Drbd_thread worker; + struct Drbd_thread asender; + struct drbd_bitmap *bitmap; + + /* Used to track operations of resync... */ + struct lru_cache *resync; + /* Number of locked elements in resync LRU */ + unsigned int resync_locked; + /* resync extent number waiting for application requests */ + unsigned int resync_wenr; + + int open_cnt; + u64 *p_uuid; + /* FIXME clean comments, restructure so it is more obvious which + * members are protected by what */ + unsigned int epoch_size; + struct list_head active_ee; /* IO in progress */ + struct list_head sync_ee; /* IO in progress */ + struct list_head done_ee; /* send ack */ + struct list_head read_ee; /* IO in progress */ + struct list_head net_ee; /* zero-copy network send in progress */ + struct hlist_head *ee_hash; /* is proteced by req_lock! */ + unsigned int ee_hash_s; + + /* this one is protected by ee_lock, single thread */ + struct Tl_epoch_entry *last_write_w_barrier; + + int next_barrier_nr; + struct hlist_head *app_reads_hash; /* is proteced by req_lock */ + struct list_head resync_reads; + atomic_t pp_in_use; + wait_queue_head_t ee_wait; + struct page *md_io_page; /* one page buffer for md_io */ + struct page *md_io_tmpp; /* for hardsect != 512 [s390 only?] */ + struct semaphore md_io_mutex; /* protects the md_io_buffer */ + spinlock_t al_lock; + wait_queue_head_t al_wait; + struct lru_cache *act_log; /* activity log */ + unsigned int al_tr_number; + int al_tr_cycle; + int al_tr_pos; /* position of the next transaction in the journal */ + struct crypto_hash *cram_hmac_tfm; + struct crypto_hash *integrity_w_tfm; /* to be used by the worker thread */ + struct crypto_hash *integrity_r_tfm; /* to be used by the receiver thread */ + void *int_dig_out; + void *int_dig_in; + void *int_dig_vv; + wait_queue_head_t seq_wait; + atomic_t packet_seq; + unsigned int peer_seq; + spinlock_t peer_seq_lock; + int minor; + unsigned long comm_bm_set; /* communicated number of set bits. */ + cpumask_t cpu_mask; + struct bm_io_work bm_io_work; + u64 ed_uuid; /* UUID of the exposed data */ + struct mutex state_mutex; +}; + +static inline struct drbd_conf *minor_to_mdev(int minor) +{ + struct drbd_conf *mdev; + + mdev = minor < minor_count ? minor_table[minor] : NULL; + + return mdev; +} + +static inline int mdev_to_minor(struct drbd_conf *mdev) +{ + return mdev->minor; +} + +/* returns 1 if it was successfull, + * returns 0 if there was no data socket. + * so wherever you are going to use the data.socket, e.g. do + * if (!drbd_get_data_sock(mdev)) + * return 0; + * CODE(); + * drbd_put_data_sock(mdev); + */ +static inline int drbd_get_data_sock(struct drbd_conf *mdev) +{ + down(&mdev->data.mutex); + /* drbd_disconnect() could have called drbd_free_sock() + * while we were waiting in down()... */ + if (unlikely(mdev->data.socket == NULL)) { + up(&mdev->data.mutex); + return 0; + } + return 1; +} + +static inline void drbd_put_data_sock(struct drbd_conf *mdev) +{ + up(&mdev->data.mutex); +} + +/* + * function declarations + *************************/ + +/* drbd_main.c */ + +enum chg_state_flags { + ChgStateHard = 1, + ChgStateVerbose = 2, + ChgWaitComplete = 4, + ChgSerialize = 8, + ChgOrdered = ChgWaitComplete + ChgSerialize, +}; + +extern void drbd_init_set_defaults(struct drbd_conf *mdev); +extern int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, + union drbd_state_t mask, union drbd_state_t val); +extern void drbd_force_state(struct drbd_conf *, union drbd_state_t, + union drbd_state_t); +extern int _drbd_request_state(struct drbd_conf *, union drbd_state_t, + union drbd_state_t, enum chg_state_flags); +extern int _drbd_set_state(struct drbd_conf *, union drbd_state_t, + enum chg_state_flags, struct completion *done); +extern void print_st_err(struct drbd_conf *, union drbd_state_t, + union drbd_state_t, int ); +extern int drbd_thread_start(struct Drbd_thread *thi); +extern void _drbd_thread_stop(struct Drbd_thread *thi, int restart, int wait); +#ifdef CONFIG_SMP +extern void drbd_thread_set_cpu(struct Drbd_thread *thi, cpumask_t cpu_mask); +extern cpumask_t drbd_calc_cpu_mask(struct drbd_conf *mdev); +#else +#define drbd_thread_set_cpu(A,B) ({}) +#define drbd_calc_cpu_mask(A) CPU_MASK_ALL +#endif +extern void drbd_free_resources(struct drbd_conf *mdev); +extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, + unsigned int set_size); +extern void tl_clear(struct drbd_conf *mdev); +extern void _tl_add_barrier(struct drbd_conf *, struct drbd_barrier *); +extern void drbd_free_sock(struct drbd_conf *mdev); +extern int drbd_send(struct drbd_conf *mdev, struct socket *sock, + void *buf, size_t size, unsigned msg_flags); +extern int drbd_send_protocol(struct drbd_conf *mdev); +extern int _drbd_send_uuids(struct drbd_conf *mdev); +extern int drbd_send_uuids(struct drbd_conf *mdev); +extern int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val); +extern int drbd_send_sizes(struct drbd_conf *mdev); +extern int _drbd_send_state(struct drbd_conf *mdev); +extern int drbd_send_state(struct drbd_conf *mdev); +extern int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, + size_t size, unsigned msg_flags); +#define USE_DATA_SOCKET 1 +#define USE_META_SOCKET 0 +extern int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, + size_t size); +extern int drbd_send_cmd2(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + char *data, size_t size); +extern int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc); +extern int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, + u32 set_size); +extern int drbd_send_ack(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Tl_epoch_entry *e); +extern int drbd_send_ack_rp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_BlockRequest_Packet *rp); +extern int drbd_send_ack_dp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_Data_Packet *dp); +extern int drbd_send_ack_ex(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + sector_t sector, int blksize, u64 block_id); +extern int _drbd_send_page(struct drbd_conf *mdev, struct page *page, + int offset, size_t size); +extern int drbd_send_block(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Tl_epoch_entry *e); +extern int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req); +extern int _drbd_send_barrier(struct drbd_conf *mdev, + struct drbd_barrier *barrier); +extern int drbd_send_drequest(struct drbd_conf *mdev, int cmd, + sector_t sector, int size, u64 block_id); +extern int drbd_send_drequest_csum(struct drbd_conf *mdev, + sector_t sector,int size, + void *digest, int digest_size, + enum Drbd_Packet_Cmd cmd); +extern int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size); + +extern int drbd_send_bitmap(struct drbd_conf *mdev); +extern int _drbd_send_bitmap(struct drbd_conf *mdev); +extern int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode); +extern void drbd_free_bc(struct drbd_backing_dev *bc); +extern int drbd_io_error(struct drbd_conf *mdev, int forcedetach); +extern void drbd_mdev_cleanup(struct drbd_conf *mdev); + +/* drbd_meta-data.c (still in drbd_main.c) */ +extern void drbd_md_sync(struct drbd_conf *mdev); +extern int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev); +/* maybe define them below as inline? */ +extern void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); +extern void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local); +extern void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); +extern void _drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local); +extern void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local); +extern void drbd_md_set_flag(struct drbd_conf *mdev, int flags) __must_hold(local); +extern void drbd_md_clear_flag(struct drbd_conf *mdev, int flags)__must_hold(local); +extern int drbd_md_test_flag(struct drbd_backing_dev *, int); +extern void drbd_md_mark_dirty(struct drbd_conf *mdev); +extern void drbd_queue_bitmap_io(struct drbd_conf *mdev, + int (*io_fn)(struct drbd_conf *), + void (*done)(struct drbd_conf *, int)); +extern int drbd_bmio_set_n_write(struct drbd_conf *mdev); +extern int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *)); + + +/* Meta data layout + We reserve a 128MB Block (4k aligned) + * either at the end of the backing device + * or on a seperate meta data device. */ + +#define MD_RESERVED_SECT ( 128LU << 11 ) /* 128 MB, unit sectors */ +/* The following numbers are sectors */ +#define MD_AL_OFFSET 8 /* 8 Sectors after start of meta area */ +#define MD_AL_MAX_SIZE 64 /* = 32 kb LOG ~ 3776 extents ~ 14 GB Storage */ +/* Allows up to about 3.8TB */ +#define MD_BM_OFFSET (MD_AL_OFFSET + MD_AL_MAX_SIZE) + +/* Since the smalles IO unit is usually 512 byte */ +#define MD_HARDSECT_B 9 +#define MD_HARDSECT (1< we need 32 KB bitmap. + * Bit 0 ==> local node thinks this block is binary identical on both nodes + * Bit 1 ==> local node thinks this block needs to be synced. + */ + +#define BM_BLOCK_SIZE_B 12 /* 4k per bit */ +#define BM_BLOCK_SIZE (1<>(BM_BLOCK_SIZE_B-9)) +#define BM_BIT_TO_SECT(x) ((sector_t)(x)<<(BM_BLOCK_SIZE_B-9)) +#define BM_SECT_PER_BIT BM_BIT_TO_SECT(1) + +/* bit to represented kilo byte conversion */ +#define Bit2KB(bits) ((bits)<<(BM_BLOCK_SIZE_B-10)) + +/* in which _bitmap_ extent (resp. sector) the bit for a certain + * _storage_ sector is located in */ +#define BM_SECT_TO_EXT(x) ((x)>>(BM_EXT_SIZE_B-9)) + +/* who much _storage_ sectors we have per bitmap sector */ +#define BM_SECT_PER_EXT (1ULL << (BM_EXT_SIZE_B-9)) + +/* in one sector of the bitmap, we have this many activity_log extents. */ +#define AL_EXT_PER_BM_SECT (1 << (BM_EXT_SIZE_B - AL_EXTENT_SIZE_B) ) +#define BM_WORDS_PER_AL_EXT (1 << (AL_EXTENT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL)) + + +#define BM_BLOCKS_PER_BM_EXT_B ( BM_EXT_SIZE_B - BM_BLOCK_SIZE_B ) +#define BM_BLOCKS_PER_BM_EXT_MASK ( (1<= level) && (type & trace_type)); +} +static inline int +is_mdev_trace(struct drbd_conf *mdev, unsigned int type, unsigned int level) { + return (is_trace(type, level) && + ( ( 1 << mdev_to_minor(mdev)) & trace_devs)); +} + +#define MTRACE(type, lvl, code...) \ +do { \ + if (unlikely(is_mdev_trace(mdev, type, lvl))) { \ + code \ + } \ +} while (0) + +#define TRACE(type, lvl, code...) \ +do { \ + if (unlikely(is_trace(type, lvl))) { \ + code \ + } \ +} while (0) + +/* Buffer printing support + * dbg_print_flags: used for Flags arg to drbd_print_buffer + * - DBGPRINT_BUFFADDR; if set, each line starts with the + * virtual address of the line being output. If clear, + * each line starts with the offset from the beginning + * of the buffer. */ +enum dbg_print_flags { + DBGPRINT_BUFFADDR = 0x0001, +}; + +extern void drbd_print_uuid(struct drbd_conf *mdev, unsigned int idx); + +extern void drbd_print_buffer(const char *prefix, unsigned int flags, int size, + const void *buffer, const void *buffer_va, + unsigned int length); + +/* Bio printing support */ +extern void _dump_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete); + +static inline void dump_bio(struct drbd_conf *mdev, + struct bio *bio, int complete) +{ + MTRACE(TraceTypeRq, TraceLvlSummary, + _dump_bio("Rq", mdev, bio, complete); + ); +} + +static inline void dump_internal_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete) { + MTRACE(TraceTypeIntRq,TraceLvlSummary, + _dump_bio(pfx, mdev, bio, complete); + ); +} + +/* Packet dumping support */ +extern void _dump_packet(struct drbd_conf *mdev, struct socket *sock, + int recv, union Drbd_Polymorph_Packet *p, + char *file, int line); + +static inline void +dump_packet(struct drbd_conf *mdev, struct socket *sock, + int recv, union Drbd_Polymorph_Packet *p, char *file, int line) +{ + MTRACE(TraceTypePacket, TraceLvlSummary, + _dump_packet(mdev, sock, recv, p, file, line); + ); +} + +#else + +#define MTRACE(ignored...) ((void)0) +#define TRACE(ignored...) ((void)0) + +#define dump_bio(ignored...) ((void)0) +#define dump_internal_bio(ignored...) ((void)0) +#define dump_packet(ignored...) ((void)0) +#endif + +/* drbd_req */ +extern int drbd_make_request_26(struct request_queue *q, struct bio *bio); +extern int drbd_read_remote(struct drbd_conf *mdev, struct drbd_request *req); +extern int drbd_merge_bvec(struct request_queue *, struct bvec_merge_data *bvm, struct bio_vec *); +extern int is_valid_ar_handle(struct drbd_request *, sector_t); + + +/* drbd_nl.c */ +extern char *ppsize(char *buf, unsigned long long size); +extern sector_t drbd_new_dev_size(struct drbd_conf *, + struct drbd_backing_dev *); +enum determin_dev_size_enum { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 }; +extern enum determin_dev_size_enum drbd_determin_dev_size(struct drbd_conf *) __must_hold(local); +extern void resync_after_online_grow(struct drbd_conf *); +extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local); +extern int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, + int force); +extern int drbd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); +enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev); +extern long drbd_compat_ioctl(struct file *f, unsigned cmd, unsigned long arg); +extern int drbd_khelper(struct drbd_conf *mdev, char *cmd); + +/* drbd_worker.c */ +extern int drbd_worker(struct Drbd_thread *thi); +extern void drbd_alter_sa(struct drbd_conf *mdev, int na); +extern void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side); +extern void resume_next_sg(struct drbd_conf *mdev); +extern void suspend_other_sg(struct drbd_conf *mdev); +extern int drbd_resync_finished(struct drbd_conf *mdev); +/* maybe rather drbd_main.c ? */ +extern int drbd_md_sync_page_io(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev, sector_t sector, int rw); +extern void drbd_ov_oos_found(struct drbd_conf*, sector_t, int); + +static inline void ov_oos_print(struct drbd_conf *mdev) +{ + if (mdev->ov_last_oos_size) { + ERR("Out of sync: start=%llu, size=%lu (sectors)\n", + (unsigned long long)mdev->ov_last_oos_start, + (unsigned long)mdev->ov_last_oos_size); + } + mdev->ov_last_oos_size=0; +} + + +void drbd_csum(struct drbd_conf *, struct crypto_hash *, struct bio *, void *); +/* worker callbacks */ +extern int w_req_cancel_conflict(struct drbd_conf *, struct drbd_work *, int); +extern int w_read_retry_remote(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_data_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_rsdata_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_ov_reply(struct drbd_conf *, struct drbd_work *, int); +extern int w_e_end_ov_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_ov_finished(struct drbd_conf *, struct drbd_work *, int); +extern int w_resync_inactive(struct drbd_conf *, struct drbd_work *, int); +extern int w_resume_next_sg(struct drbd_conf *, struct drbd_work *, int); +extern int w_io_error(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_write_hint(struct drbd_conf *, struct drbd_work *, int); +extern int w_make_resync_request(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_dblock(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_barrier(struct drbd_conf *, struct drbd_work *, int); +extern int w_send_read_req(struct drbd_conf *, struct drbd_work *, int); +extern int w_prev_work_done(struct drbd_conf *, struct drbd_work *, int); + +extern void resync_timer_fn(unsigned long data); + +/* drbd_receiver.c */ +extern int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list); +extern struct Tl_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, + u64 id, + sector_t sector, + unsigned int data_size, + gfp_t gfp_mask) __must_hold(local); +extern void drbd_free_ee(struct drbd_conf *mdev, struct Tl_epoch_entry *e); +extern void drbd_wait_ee_list_empty(struct drbd_conf *mdev, + struct list_head *head); +extern void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, + struct list_head *head); +extern void drbd_set_recv_tcq(struct drbd_conf *mdev, int tcq_enabled); +extern void _drbd_clear_done_ee(struct drbd_conf *mdev); + +static inline void drbd_tcp_cork(struct socket *sock) +{ + int __user val = 1; + tcp_setsockopt(sock->sk, SOL_TCP, TCP_CORK, (char __user *)&val, sizeof(val) ); +} + +static inline void drbd_tcp_flush(struct socket *sock) +{ + int __user val = 0; + tcp_setsockopt(sock->sk, SOL_TCP, TCP_CORK, (char __user *)&val, sizeof(val) ); +} + +/* drbd_proc.c */ +extern struct proc_dir_entry *drbd_proc; +extern struct file_operations drbd_proc_fops; +extern const char *conns_to_name(enum drbd_conns s); +extern const char *roles_to_name(enum drbd_role s); + +/* drbd_actlog.c */ +extern void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector); +extern void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector); +extern void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector); +extern int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector); +extern int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector); +extern void drbd_rs_cancel_all(struct drbd_conf *mdev); +extern int drbd_rs_del_all(struct drbd_conf *mdev); +extern void drbd_rs_failed_io(struct drbd_conf *mdev, + sector_t sector, int size); +extern int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *); +extern void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, + int size, const char *file, const unsigned int line); +#define drbd_set_in_sync(mdev, sector, size) \ + __drbd_set_in_sync(mdev, sector, size, __FILE__, __LINE__ ) +extern void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, + int size, const char *file, const unsigned int line); +#define drbd_set_out_of_sync(mdev, sector, size) \ + __drbd_set_out_of_sync(mdev, sector, size, __FILE__, __LINE__ ) +extern void drbd_al_apply_to_bm(struct drbd_conf *mdev); +extern void drbd_al_to_on_disk_bm(struct drbd_conf *mdev); +extern void drbd_al_shrink(struct drbd_conf *mdev); + + +/* drbd_nl.c */ + +void drbd_nl_cleanup(void); +int __init drbd_nl_init(void); +void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state_t); +void drbd_bcast_sync_progress(struct drbd_conf *mdev); +void drbd_bcast_ee(struct drbd_conf *mdev, + const char *reason, const int dgs, + const char* seen_hash, const char* calc_hash, + const struct Tl_epoch_entry* e); + +/* + * inline helper functions + *************************/ + +#define peer_mask role_mask +#define pdsk_mask disk_mask +#define susp_mask 1 +#define user_isp_mask 1 +#define aftr_isp_mask 1 + +#define NS(T, S) \ + ({ union drbd_state_t mask; mask.i = 0; mask.T = T##_mask; mask; }), \ + ({ union drbd_state_t val; val.i = 0; val.T = (S); val; }) +#define NS2(T1, S1, T2, S2) \ + ({ union drbd_state_t mask; mask.i = 0; mask.T1 = T1##_mask; \ + mask.T2 = T2##_mask; mask; }), \ + ({ union drbd_state_t val; val.i = 0; val.T1 = (S1); \ + val.T2 = (S2); val; }) +#define NS3(T1, S1, T2, S2, T3, S3) \ + ({ union drbd_state_t mask; mask.i = 0; mask.T1 = T1##_mask; \ + mask.T2 = T2##_mask; mask.T3 = T3##_mask; mask; }), \ + ({ union drbd_state_t val; val.i = 0; val.T1 = (S1); \ + val.T2 = (S2); val.T3 = (S3); val; }) + +#define _NS(D, T, S) \ + D, ({ union drbd_state_t __ns; __ns.i = D->state.i; __ns.T = (S); __ns; }) +#define _NS2(D, T1, S1, T2, S2) \ + D, ({ union drbd_state_t __ns; __ns.i = D->state.i; __ns.T1 = (S1); \ + __ns.T2 = (S2); __ns; }) +#define _NS3(D, T1, S1, T2, S2, T3, S3) \ + D, ({ union drbd_state_t __ns; __ns.i = D->state.i; __ns.T1 = (S1); \ + __ns.T2 = (S2); __ns.T3 = (S3); __ns; }) + +static inline void drbd_state_lock(struct drbd_conf *mdev) +{ + wait_event(mdev->misc_wait, + !test_and_set_bit(CLUSTER_ST_CHANGE, &mdev->flags)); +} + +static inline void drbd_state_unlock(struct drbd_conf *mdev) +{ + clear_bit(CLUSTER_ST_CHANGE, &mdev->flags); + wake_up(&mdev->misc_wait); +} + +static inline int drbd_request_state(struct drbd_conf *mdev, + union drbd_state_t mask, + union drbd_state_t val) +{ + return _drbd_request_state(mdev, mask, val, ChgStateVerbose + ChgOrdered); +} + +/** + * drbd_chk_io_error: Handles the on_io_error setting, should be called from + * all io completion handlers. See also drbd_io_error(). + */ +static inline void __drbd_chk_io_error(struct drbd_conf *mdev, int forcedetach) +{ + switch (mdev->bc->dc.on_io_error) { + case PassOn: /* FIXME would this be better named "Ignore"? */ + if (!forcedetach) { + if (printk_ratelimit()) + ERR("Local IO failed. Passing error on...\n"); + break; + } + /* NOTE fall through to detach case if forcedetach set */ + case Detach: + case CallIOEHelper: + if (mdev->state.disk > Failed) { + _drbd_set_state(_NS(mdev, disk, Failed), ChgStateHard, NULL); + ERR("Local IO failed. Detaching...\n"); + } + break; + } +} + +static inline void drbd_chk_io_error(struct drbd_conf *mdev, + int error, int forcedetach) +{ + if (error) { + unsigned long flags; + spin_lock_irqsave(&mdev->req_lock, flags); + __drbd_chk_io_error(mdev, forcedetach); + spin_unlock_irqrestore(&mdev->req_lock, flags); + } +} + +static inline int semaphore_is_locked(struct semaphore *s) +{ + if (!down_trylock(s)) { + up(s); + return 0; + } + return 1; +} + +/* Returns the first sector number of our meta data, + * which, for internal meta data, happens to be the maximum capacity + * we could agree upon with our peer + */ +static inline sector_t drbd_md_first_sector(struct drbd_backing_dev *bdev) +{ + switch (bdev->dc.meta_dev_idx) { + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + return bdev->md.md_offset + bdev->md.bm_offset; + case DRBD_MD_INDEX_FLEX_EXT: + default: + return bdev->md.md_offset; + } +} + +/* returns the last sector number of our meta data, + * to be able to catch out of band md access */ +static inline sector_t drbd_md_last_sector(struct drbd_backing_dev *bdev) +{ + switch (bdev->dc.meta_dev_idx) { + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + return bdev->md.md_offset + MD_AL_OFFSET -1; + case DRBD_MD_INDEX_FLEX_EXT: + default: + return bdev->md.md_offset + bdev->md.md_size_sect; + } +} + +/* returns the capacity we announce to out peer */ +static inline sector_t drbd_get_max_capacity(struct drbd_backing_dev *bdev) +{ + switch (bdev->dc.meta_dev_idx) { + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + return drbd_get_capacity(bdev->backing_bdev) + ? drbd_md_first_sector(bdev) + : 0; + case DRBD_MD_INDEX_FLEX_EXT: + default: + return drbd_get_capacity(bdev->backing_bdev); + } +} + +/* returns the sector number of our meta data 'super' block */ +static inline sector_t drbd_md_ss__(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev) +{ + switch (bdev->dc.meta_dev_idx) { + default: /* external, some index */ + return MD_RESERVED_SECT * bdev->dc.meta_dev_idx; + case DRBD_MD_INDEX_INTERNAL: + /* with drbd08, internal meta data is always "flexible" */ + case DRBD_MD_INDEX_FLEX_INT: + /* sizeof(struct md_on_disk_07) == 4k + * position: last 4k aligned block of 4k size */ + if (!bdev->backing_bdev) { + if (DRBD_ratelimit(5*HZ, 5)) { + ERR("bdev->backing_bdev==NULL\n"); + dump_stack(); + } + return 0; + } + return (drbd_get_capacity(bdev->backing_bdev) & ~7ULL) + - MD_AL_OFFSET; + case DRBD_MD_INDEX_FLEX_EXT: + return 0; + } +} + +static inline void +_drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w) +{ + list_add_tail(&w->list, &q->q); + up(&q->s); +} + +static inline void +drbd_queue_work_front(struct drbd_work_queue *q, struct drbd_work *w) +{ + unsigned long flags; + spin_lock_irqsave(&q->q_lock, flags); + list_add(&w->list, &q->q); + up(&q->s); /* within the spinlock, + see comment near end of drbd_worker() */ + spin_unlock_irqrestore(&q->q_lock, flags); +} + +static inline void +drbd_queue_work(struct drbd_work_queue *q, struct drbd_work *w) +{ + unsigned long flags; + spin_lock_irqsave(&q->q_lock, flags); + list_add_tail(&w->list, &q->q); + up(&q->s); /* within the spinlock, + see comment near end of drbd_worker() */ + spin_unlock_irqrestore(&q->q_lock, flags); +} + +static inline void wake_asender(struct drbd_conf *mdev) +{ + if (test_bit(SIGNAL_ASENDER, &mdev->flags)) + force_sig(DRBD_SIG, mdev->asender.task); +} + +static inline void request_ping(struct drbd_conf *mdev) +{ + set_bit(SEND_PING, &mdev->flags); + wake_asender(mdev); +} + +static inline int drbd_send_short_cmd(struct drbd_conf *mdev, + enum Drbd_Packet_Cmd cmd) +{ + struct Drbd_Header h; + return drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, &h, sizeof(h)); +} + +static inline int drbd_send_ping(struct drbd_conf *mdev) +{ + struct Drbd_Header h; + return drbd_send_cmd(mdev, USE_META_SOCKET, Ping, &h, sizeof(h)); +} + +static inline int drbd_send_ping_ack(struct drbd_conf *mdev) +{ + struct Drbd_Header h; + return drbd_send_cmd(mdev, USE_META_SOCKET, PingAck, &h, sizeof(h)); +} + +static inline void drbd_thread_stop(struct Drbd_thread *thi) +{ + _drbd_thread_stop(thi, FALSE, TRUE); +} + +static inline void drbd_thread_stop_nowait(struct Drbd_thread *thi) +{ + _drbd_thread_stop(thi, FALSE, FALSE); +} + +static inline void drbd_thread_restart_nowait(struct Drbd_thread *thi) +{ + _drbd_thread_stop(thi, TRUE, FALSE); +} + +/* counts how many answer packets packets we expect from our peer, + * for either explicit application requests, + * or implicit barrier packets as necessary. + * increased: + * w_send_barrier + * _req_mod(req, queue_for_net_write or queue_for_net_read); + * it is much easier and equally valid to count what we queue for the + * worker, even before it actually was queued or send. + * (drbd_make_request_common; recovery path on read io-error) + * decreased: + * got_BarrierAck (respective tl_clear, tl_clear_barrier) + * _req_mod(req, data_received) + * [from receive_DataReply] + * _req_mod(req, write_acked_by_peer or recv_acked_by_peer or neg_acked) + * [from got_BlockAck (WriteAck, RecvAck)] + * FIXME + * for some reason it is NOT decreased in got_NegAck, + * but in the resulting cleanup code from report_params. + * we should try to remember the reason for that... + * _req_mod(req, send_failed or send_canceled) + * _req_mod(req, connection_lost_while_pending) + * [from tl_clear_barrier] + */ +static inline void inc_ap_pending(struct drbd_conf *mdev) +{ + atomic_inc(&mdev->ap_pending_cnt); +} + +#define ERR_IF_CNT_IS_NEGATIVE(which) \ + if (atomic_read(&mdev->which) < 0) \ + ERR("in %s:%d: " #which " = %d < 0 !\n", \ + __func__ , __LINE__ , \ + atomic_read(&mdev->which)) + +#define dec_ap_pending(mdev) do { \ + typecheck(struct drbd_conf *, mdev); \ + if (atomic_dec_and_test(&mdev->ap_pending_cnt)) \ + wake_up(&mdev->misc_wait); \ + ERR_IF_CNT_IS_NEGATIVE(ap_pending_cnt); } while (0) + +/* counts how many resync-related answers we still expect from the peer + * increase decrease + * SyncTarget sends RSDataRequest (and expects RSDataReply) + * SyncSource sends RSDataReply (and expects WriteAck whith ID_SYNCER) + * (or NegAck with ID_SYNCER) + */ +static inline void inc_rs_pending(struct drbd_conf *mdev) +{ + atomic_inc(&mdev->rs_pending_cnt); +} + +#define dec_rs_pending(mdev) do { \ + typecheck(struct drbd_conf *, mdev); \ + atomic_dec(&mdev->rs_pending_cnt); \ + ERR_IF_CNT_IS_NEGATIVE(rs_pending_cnt); } while (0) + +/* counts how many answers we still need to send to the peer. + * increased on + * receive_Data unless protocol A; + * we need to send a RecvAck (proto B) + * or WriteAck (proto C) + * receive_RSDataReply (recv_resync_read) we need to send a WriteAck + * receive_DataRequest (receive_RSDataRequest) we need to send back Data + * receive_Barrier_* we need to send a BarrierAck + */ +static inline void inc_unacked(struct drbd_conf *mdev) +{ + atomic_inc(&mdev->unacked_cnt); +} + +#define dec_unacked(mdev) do { \ + typecheck(struct drbd_conf *, mdev); \ + atomic_dec(&mdev->unacked_cnt); \ + ERR_IF_CNT_IS_NEGATIVE(unacked_cnt); } while (0) + +#define sub_unacked(mdev, n) do { \ + typecheck(struct drbd_conf *, mdev); \ + atomic_sub(n, &mdev->unacked_cnt); \ + ERR_IF_CNT_IS_NEGATIVE(unacked_cnt); } while (0) + + +static inline void dec_net(struct drbd_conf *mdev) +{ + if (atomic_dec_and_test(&mdev->net_cnt)) + wake_up(&mdev->misc_wait); +} + +/** + * inc_net: Returns TRUE when it is ok to access mdev->net_conf. You + * should call dec_net() when finished looking at mdev->net_conf. + */ +static inline int inc_net(struct drbd_conf *mdev) +{ + int have_net_conf; + + atomic_inc(&mdev->net_cnt); + have_net_conf = mdev->state.conn >= Unconnected; + if (!have_net_conf) + dec_net(mdev); + return have_net_conf; +} + +/** + * inc_local: Returns TRUE when local IO is possible. If it returns + * TRUE you should call dec_local() after IO is completed. + */ +#define inc_local_if_state(M,MINS) __cond_lock(local, _inc_local_if_state(M,MINS)) +#define inc_local(M) __cond_lock(local, _inc_local_if_state(M,Inconsistent)) + +static inline void dec_local(struct drbd_conf *mdev) +{ + __release(local); + if (atomic_dec_and_test(&mdev->local_cnt)) + wake_up(&mdev->misc_wait); + D_ASSERT(atomic_read(&mdev->local_cnt) >= 0); +} + +#ifndef __CHECKER__ +static inline int _inc_local_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins) +{ + int io_allowed; + + atomic_inc(&mdev->local_cnt); + io_allowed = (mdev->state.disk >= mins ); + if (!io_allowed) + dec_local(mdev); + return io_allowed; +} +#else +extern int _inc_local_if_state(struct drbd_conf *mdev, enum drbd_disk_state mins); +#endif + +/* you must have an "inc_local" reference */ +static inline void drbd_get_syncer_progress(struct drbd_conf *mdev, + unsigned long *bits_left, unsigned int *per_mil_done) +{ + /* + * this is to break it at compile time when we change that + * (we may feel 4TB maximum storage per drbd is not enough) + */ + typecheck(unsigned long, mdev->rs_total); + + /* note: both rs_total and rs_left are in bits, i.e. in + * units of BM_BLOCK_SIZE. + * for the percentage, we don't care. */ + + *bits_left = drbd_bm_total_weight(mdev) - mdev->rs_failed; + /* >> 10 to prevent overflow, + * +1 to prevent division by zero */ + if (*bits_left > mdev->rs_total) { + /* doh. maybe a logic bug somewhere. + * may also be just a race condition + * between this and a disconnect during sync. + * for now, just prevent in-kernel buffer overflow. + */ + smp_rmb(); + DRBD_WARN("cs:%s rs_left=%lu > rs_total=%lu (rs_failed %lu)\n", + conns_to_name(mdev->state.conn), + *bits_left, mdev->rs_total, mdev->rs_failed); + *per_mil_done = 0; + } else { + /* make sure the calculation happens in long context */ + unsigned long tmp = 1000UL - + (*bits_left >> 10)*1000UL + / ((mdev->rs_total >> 10) + 1UL); + *per_mil_done = tmp; + } +} + + +/* this throttles on-the-fly application requests + * according to max_buffers settings; + * maybe re-implement using semaphores? */ +static inline int drbd_get_max_buffers(struct drbd_conf *mdev) +{ + int mxb = 1000000; /* arbitrary limit on open requests */ + if (inc_net(mdev)) { + mxb = mdev->net_conf->max_buffers; + dec_net(mdev); + } + return mxb; +} + +static inline int __inc_ap_bio_cond(struct drbd_conf *mdev) +{ + const unsigned int cs = mdev->state.conn; + const unsigned int ds = mdev->state.disk; + int mxb = drbd_get_max_buffers(mdev); + if (mdev->state.susp) + return 0; + /* to avoid deadlock or bitmap corruption, we need to lock out + * application io during attaching and bitmap exchange */ + if (Attaching <= ds && ds <= Negotiating) + return 0; + if (cs == WFBitMapS || cs == WFBitMapT || cs == WFReportParams || cs == WFSyncUUID) + return 0; + + /* since some older kernels don't have atomic_add_unless, + * and we are within the spinlock anyways, we have this workaround. */ + if (atomic_read(&mdev->ap_bio_cnt) > mxb) + return 0; + if (test_bit(BITMAP_IO, &mdev->flags)) + return 0; + atomic_inc(&mdev->ap_bio_cnt); + return 1; +} + +/* I'd like to use wait_event_lock_irq, + * but I'm not sure when it got introduced, + * and not sure when it has 3 or 4 arguments */ +static inline void inc_ap_bio(struct drbd_conf *mdev) +{ + /* compare with after_state_ch, + * os.conn != WFBitMapS && ns.conn == WFBitMapS */ + DEFINE_WAIT(wait); + + /* we wait here + * as long as the device is suspended + * until the bitmap is no longer on the fly during connection + * handshake as long as we would exeed the max_buffer limit. + * + * to avoid races with the reconnect code, + * we need to atomic_inc within the spinlock. */ + + spin_lock_irq(&mdev->req_lock); + while (!__inc_ap_bio_cond(mdev)) { + prepare_to_wait(&mdev->misc_wait, &wait, TASK_UNINTERRUPTIBLE); + spin_unlock_irq(&mdev->req_lock); + schedule(); + finish_wait(&mdev->misc_wait, &wait); + spin_lock_irq(&mdev->req_lock); + } + spin_unlock_irq(&mdev->req_lock); +} + +static inline void dec_ap_bio(struct drbd_conf *mdev) +{ + int mxb = drbd_get_max_buffers(mdev); + int ap_bio = atomic_dec_return(&mdev->ap_bio_cnt); + + D_ASSERT(ap_bio >= 0); + if (ap_bio < mxb) + wake_up(&mdev->misc_wait); + if (ap_bio == 0 && test_bit(BITMAP_IO, &mdev->flags)) { + if (!test_and_set_bit(BITMAP_IO_QUEUED, &mdev->flags)) + drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w); + } +} + +static inline void drbd_set_ed_uuid(struct drbd_conf *mdev, u64 val) +{ + mdev->ed_uuid = val; + + MTRACE(TraceTypeUuid,TraceLvlMetrics, + INFO(" exposed data uuid now %016llX\n",val); + ); +} + +static inline int seq_cmp(u32 a, u32 b) +{ + /* we assume wrap around at 32bit. + * for wrap around at 24bit (old atomic_t), + * we'd have to + * a <<= 8; b <<= 8; + */ + return ((s32)(a) - (s32)(b)); +} +#define seq_lt(a, b) (seq_cmp((a), (b)) < 0) +#define seq_gt(a, b) (seq_cmp((a), (b)) > 0) +#define seq_ge(a, b) (seq_cmp((a), (b)) >= 0) +#define seq_le(a, b) (seq_cmp((a), (b)) <= 0) +/* CAUTION: please no side effects in arguments! */ +#define seq_max(a, b) ((u32)(seq_gt((a), (b)) ? (a) : (b))) + +static inline void update_peer_seq(struct drbd_conf *mdev, unsigned int new_seq) +{ + unsigned int m; + spin_lock(&mdev->peer_seq_lock); + m = seq_max(mdev->peer_seq, new_seq); + mdev->peer_seq = m; + spin_unlock(&mdev->peer_seq_lock); + if (m == new_seq) + wake_up(&mdev->seq_wait); +} + +static inline int drbd_queue_order_type(struct drbd_conf *mdev) +{ + /* sorry, we currently have no working implementation + * of distributed TCQ stuff */ +#ifndef QUEUE_ORDERED_NONE +#define QUEUE_ORDERED_NONE 0 +#endif + return QUEUE_ORDERED_NONE; +} + +/* + * FIXME investigate what makes most sense: + * a) blk_run_queue(q); + * + * b) struct backing_dev_info *bdi; + * b1) bdi = &q->backing_dev_info; + * b2) bdi = mdev->bc->backing_bdev->bd_inode->i_mapping->backing_dev_info; + * blk_run_backing_dev(bdi,NULL); + * + * c) generic_unplug(q) ? __generic_unplug(q) ? + * + * d) q->unplug_fn(q), which is what all the drivers/md/ stuff uses... + * + */ +static inline void drbd_blk_run_queue(struct request_queue *q) +{ + if (q && q->unplug_fn) + q->unplug_fn(q); +} + +static inline void drbd_kick_lo(struct drbd_conf *mdev) +{ + if (inc_local(mdev)) { + drbd_blk_run_queue(bdev_get_queue(mdev->bc->backing_bdev)); + dec_local(mdev); + } +} +#endif --- linux-2.6.28.orig/ubuntu/drbd/drbd_bitmap.c +++ linux-2.6.28/ubuntu/drbd/drbd_bitmap.c @@ -0,0 +1,1004 @@ +/* +-*- linux-c -*- + drbd_bitmap.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2004-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2004-2008, Philipp Reisner . + Copyright (C) 2004-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include "drbd_int.h" + +/* OPAQUE outside this file! + * interface defined in drbd_int.h + + * convetion: + * function name drbd_bm_... => used elsewhere, "public". + * function name bm_... => internal to implementation, "private". + + * Note that since find_first_bit returns int, at the current granularity of + * the bitmap (4KB per byte), this implementation "only" supports up to + * 1<<(32+12) == 16 TB... + * other shortcomings in the meta data area may reduce this even further. + * + * we will eventually change the implementation to not allways hold the full + * bitmap in memory, but only some 'lru_cache' of the on disk bitmap. + + * THINK + * I'm not yet sure whether this file should be bits only, + * or wether I want it to do all the sector<->bit calculation in here. + */ + +/* + * NOTE + * Access to the *bm is protected by bm_lock. + * It is safe to read the other members within the lock. + * + * drbd_bm_set_bits is called from bio_endio callbacks, + * We may be called with irq already disabled, + * so we need spin_lock_irqsave(). + * FIXME + * for performance reasons, when we _know_ we have irq disabled, we should + * probably introduce some _in_irq variants, so we know to only spin_lock(). + * + * FIXME + * Actually you need to serialize all resize operations. + * but then, resize is a drbd state change, and it should be serialized + * already. Unfortunately it is not (yet), so two concurrent resizes, like + * attach storage (drbdsetup) and receive the peers size (drbd receiver) + * may eventually blow things up. + * Therefore, + * you may only change the other members when holding + * the bm_change mutex _and_ the bm_lock. + * thus reading them holding either is safe. + * this is sort of overkill, but I rather do it right + * than have two resize operations interfere somewhen. + */ +struct drbd_bitmap { + unsigned long *bm; + spinlock_t bm_lock; + /* WARNING unsigned long bm_fo and friends: + * 32bit number of bit offset is just enough for 512 MB bitmap. + * it will blow up if we make the bitmap bigger... + * not that it makes much sense to have a bitmap that large, + * rather change the granularity to 16k or 64k or something. + * (that implies other problems, however...) + */ + unsigned long bm_fo; /* next offset for drbd_bm_find_next */ + unsigned long bm_set; /* nr of set bits; THINK maybe atomic_t? */ + unsigned long bm_bits; + size_t bm_words; + sector_t bm_dev_capacity; + struct semaphore bm_change; /* serializes resize operations */ + + atomic_t bm_async_io; + wait_queue_head_t bm_io_wait; + + unsigned long bm_flags; + + /* debugging aid, in case we are still racy somewhere */ + unsigned long bm_line; + char *bm_file; +}; + +/* definition of bits in bm_flags */ +#define BM_LOCKED 0 +#define BM_MD_IO_ERROR (BITS_PER_LONG-1) /* 31? 63? */ + +void __drbd_bm_lock(struct drbd_conf *mdev, char *file, int line) +{ + struct drbd_bitmap *b = mdev->bitmap; + + spin_lock_irq(&b->bm_lock); + if (!__test_and_set_bit(BM_LOCKED,&b->bm_flags)) { + b->bm_file = file; + b->bm_line = line; + } else if (DRBD_ratelimit(5*HZ,5)) { + ERR("%s:%d: bitmap already locked by %s:%lu\n", + file, line, b->bm_file,b->bm_line); + /* + dump_stack(); + ERR("This is no oops, but debug stack trace only.\n"); + ERR("If you get this often, or in reproducable situations, " + "notify \n"); + */ + } + spin_unlock_irq(&b->bm_lock); +} + +void drbd_bm_unlock(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + spin_lock_irq(&b->bm_lock); + if (!__test_and_clear_bit(BM_LOCKED,&mdev->bitmap->bm_flags)) { + ERR("bitmap not locked in bm_unlock\n"); + } else { + /* FIXME if we got a "is already locked" previously, + * we unlock here even though we actually MUST NOT do so... */ + b->bm_file = NULL; + b->bm_line = -1; + } + spin_unlock_irq(&b->bm_lock); +} + +#if DUMP_MD >= 3 +/* debugging aid */ +void bm_end_info(struct drbd_conf *mdev, const char *where) +{ + struct drbd_bitmap *b = mdev->bitmap; + size_t w = (b->bm_bits-1) >> LN2_BPL; + + INFO("%s: bm_set=%lu\n", where, b->bm_set); + INFO("bm[%d]=0x%lX\n", w, b->bm[w]); + w++; + + if (w < b->bm_words) { + D_ASSERT(w == b->bm_words -1); + INFO("bm[%d]=0x%lX\n", w, b->bm[w]); + } +} +#else +#define bm_end_info(ignored...) ((void)(0)) +#endif + +/* long word offset of _bitmap_ sector */ +#define S2W(s) ((s)<<(BM_EXT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL)) + +/* + * actually most functions herein should take a struct drbd_bitmap*, not a + * struct drbd_conf*, but for the debug macros I like to have the mdev around + * to be able to report device specific. + */ + +/* FIXME TODO sometimes I use "int offset" as index into the bitmap. + * since we currently are LIMITED to (128<<11)-64-8 sectors of bitmap, + * this is ok [as long as we dont run on a 24 bit arch :)]. + * But it is NOT strictly ok. + */ + +/* + * called on driver init only. TODO call when a device is created. + * allocates the drbd_bitmap, and stores it in mdev->bitmap. + */ +int drbd_bm_init(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + WARN_ON(b != NULL); + b = kzalloc(sizeof(struct drbd_bitmap), GFP_KERNEL); + if (!b) + return -ENOMEM; + spin_lock_init(&b->bm_lock); + init_MUTEX(&b->bm_change); + init_waitqueue_head(&b->bm_io_wait); + + mdev->bitmap = b; + + return 0; +} + +sector_t drbd_bm_capacity(struct drbd_conf *mdev) +{ + ERR_IF(!mdev->bitmap) return 0; + return mdev->bitmap->bm_dev_capacity; +} + +/* called on driver unload. TODO: call when a device is destroyed. + */ +void drbd_bm_cleanup(struct drbd_conf *mdev) +{ + ERR_IF (!mdev->bitmap) return; + /* FIXME I think we should explicitly change the device size to zero + * before this... + * + WARN_ON(mdev->bitmap->bm); + */ + vfree(mdev->bitmap->bm); + kfree(mdev->bitmap); + mdev->bitmap = NULL; +} + +/* + * since (b->bm_bits % BITS_PER_LONG) != 0, + * this masks out the remaining bits. + * Rerturns the number of bits cleared. + */ +STATIC int bm_clear_surplus(struct drbd_bitmap *b) +{ + const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) -1; + size_t w = b->bm_bits >> LN2_BPL; + int cleared = 0; + + if (w < b->bm_words) { + cleared = hweight_long(b->bm[w] & ~mask); + b->bm[w++] &= mask; + } + + if (w < b->bm_words) { + cleared += hweight_long(b->bm[w]); + b->bm[w++] = 0; + } + + return cleared; +} + +STATIC void bm_set_surplus(struct drbd_bitmap *b) +{ + const unsigned long mask = (1UL << (b->bm_bits & (BITS_PER_LONG-1))) -1; + size_t w = b->bm_bits >> LN2_BPL; + + if (w < b->bm_words) + b->bm[w++] |= ~mask; + + if (w < b->bm_words) + b->bm[w++] = ~(0UL); +} + +STATIC unsigned long __bm_count_bits(struct drbd_bitmap *b, const int swap_endian) +{ + unsigned long *bm = b->bm; + unsigned long *ep = b->bm + b->bm_words; + unsigned long bits = 0; + + while ( bm < ep ) { +#ifndef __LITTLE_ENDIAN + if (swap_endian) *bm = lel_to_cpu(*bm); +#endif + bits += hweight_long(*bm++); + } + + return bits; +} + +static inline unsigned long bm_count_bits(struct drbd_bitmap *b) +{ + return __bm_count_bits(b,0); +} + +static inline unsigned long bm_count_bits_swap_endian(struct drbd_bitmap *b) +{ + return __bm_count_bits(b,1); +} + + +void _drbd_bm_recount_bits(struct drbd_conf *mdev, char* file, int line) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long flags, bits; + + ERR_IF(!b) return; + + spin_lock_irqsave(&b->bm_lock, flags); + bits = bm_count_bits(b); + if (bits != b->bm_set) { + ERR("bm_set was %lu, corrected to %lu. %s:%d\n", + b->bm_set, bits, file, line); + b->bm_set = bits; + } + spin_unlock_irqrestore(&b->bm_lock, flags); +} + +#define BM_SECTORS_PER_BIT (BM_BLOCK_SIZE/512) + +/* + * make sure the bitmap has enough room for the attached storage, + * if neccessary, resize. + * called whenever we may have changed the device size. + * returns -ENOMEM if we could not allocate enough memory, 0 on success. + * In case this is actually a resize, we copy the old bitmap into the new one. + * Otherwise, the bitmap is initiallized to all bits set. + */ +int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long bits, bytes, words, *nbm, *obm = NULL; + int err = 0, growing; + + ERR_IF(!b) return -ENOMEM; + + ERR_IF (down_trylock(&b->bm_change)) { + down(&b->bm_change); + } + + INFO("drbd_bm_resize called with capacity == %llu\n", + (unsigned long long)capacity); + + if (capacity == b->bm_dev_capacity) + goto out; + + if (capacity == 0) { + spin_lock_irq(&b->bm_lock); + obm = b->bm; + b->bm = NULL; + b->bm_fo = + b->bm_set = + b->bm_bits = + b->bm_words = + b->bm_dev_capacity = 0; + spin_unlock_irq(&b->bm_lock); + goto free_obm; + } else { + bits = BM_SECT_TO_BIT(ALIGN(capacity, BM_SECTORS_PER_BIT)); + + /* if we would use + words = ALIGN(bits,BITS_PER_LONG) >> LN2_BPL; + a 32bit host could present the wrong number of words + to a 64bit host. + */ + words = ALIGN(bits, 64) >> LN2_BPL; + + if (inc_local(mdev)) { + D_ASSERT((u64)bits <= (((u64)mdev->bc->md.md_size_sect-MD_BM_OFFSET) << 12)); + dec_local(mdev); + } + + if (words == b->bm_words) { + /* optimize: capacity has changed, + * but only within one long word worth of bits. + * just update the bm_dev_capacity and bm_bits members. + */ + spin_lock_irq(&b->bm_lock); + b->bm_bits = bits; + b->bm_dev_capacity = capacity; + b->bm_set -= bm_clear_surplus(b); + bm_end_info(mdev, __FUNCTION__ ); + spin_unlock_irq(&b->bm_lock); + goto out; + } else { + /* one extra long to catch off by one errors */ + bytes = (words+1)*sizeof(long); + nbm = vmalloc(bytes); + if (!nbm) { + ERR("bitmap: failed to vmalloc %lu bytes\n", + bytes); + err = -ENOMEM; + goto out; + } + } + spin_lock_irq(&b->bm_lock); + obm = b->bm; + /* brgs. move several MB within spinlock... + * FIXME this should go into userspace! */ + if (obm) { + bm_set_surplus(b); + D_ASSERT(b->bm[b->bm_words] == DRBD_MAGIC); + memcpy(nbm, obm, min_t(size_t, b->bm_words, words) + *sizeof(long)); + } + growing = words > b->bm_words; + if (growing) { + /* set all newly allocated bits + * start at -1, just to be sure. */ + memset( nbm + (b->bm_words?:1)-1 , 0xff, + (words - ((b->bm_words?:1)-1)) * sizeof(long) ); + b->bm_set += bits - b->bm_bits; + } + nbm[words] = DRBD_MAGIC; + b->bm = nbm; + b->bm_bits = bits; + b->bm_words = words; + b->bm_dev_capacity = capacity; + bm_clear_surplus(b); + if (!growing) + b->bm_set = bm_count_bits(b); + bm_end_info(mdev, __FUNCTION__ ); + spin_unlock_irq(&b->bm_lock); + INFO("resync bitmap: bits=%lu words=%lu\n", bits, words); + } + free_obm: + vfree(obm); /* vfree(NULL) is noop */ + out: + up(&b->bm_change); + return err; +} + +/* inherently racy: + * if not protected by other means, return value may be out of date when + * leaving this function... + * we still need to lock it, since it is important that this returns + * bm_set == 0 precisely. + * + * maybe bm_set should be atomic_t ? + */ +unsigned long drbd_bm_total_weight(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long s; + unsigned long flags; + + ERR_IF(!b) return 0; + + spin_lock_irqsave(&b->bm_lock, flags); + s = b->bm_set; + spin_unlock_irqrestore(&b->bm_lock, flags); + + return s; +} + +size_t drbd_bm_words(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + ERR_IF(!b) return 0; + return b->bm_words; +} + +unsigned long drbd_bm_bits(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + ERR_IF(!b) return 0; + + return b->bm_bits; +} + + +/* merge number words from buffer into the bitmap starting at offset. + * buffer[i] is expected to be little endian unsigned long. + */ +void drbd_bm_merge_lel( struct drbd_conf *mdev, size_t offset, size_t number, + unsigned long *buffer ) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *bm; + unsigned long word, bits; + size_t n = number; + + if (number == 0) + return; + ERR_IF(!b) return; + ERR_IF(!b->bm) return; + WARN_ON(offset >= b->bm_words); + WARN_ON(offset+number > b->bm_words); + WARN_ON(number > PAGE_SIZE/sizeof(long)); + + spin_lock_irq(&b->bm_lock); + bm = b->bm + offset; + while (n--) { + bits = hweight_long(*bm); + word = *bm | lel_to_cpu(*buffer++); + *bm++ = word; + b->bm_set += hweight_long(word) - bits; + } + /* with 32bit <-> 64bit cross-platform connect + * this is only correct for current usage, + * where we _know_ that we are 64 bit aligned, + * and know that this function is used in this way, too... + */ + if (offset+number == b->bm_words) { + b->bm_set -= bm_clear_surplus(b); + bm_end_info(mdev, __FUNCTION__ ); + } + spin_unlock_irq(&b->bm_lock); +} + +/* copy number words from the bitmap starting at offset into the buffer. + * buffer[i] will be little endian unsigned long. + */ +void drbd_bm_get_lel(struct drbd_conf *mdev, size_t offset, size_t number, + unsigned long *buffer ) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long *bm; + + if (number == 0) + return; + ERR_IF(!b) return; + ERR_IF(!b->bm) return; + if ( (offset >= b->bm_words) || + (offset+number > b->bm_words) || + (number > PAGE_SIZE/sizeof(long)) || + (number <= 0) ) { + /* yes, there is "%z", but that gives compiler warnings... */ + ERR("offset=%lu number=%lu bm_words=%lu\n", + (unsigned long) offset, + (unsigned long) number, + (unsigned long) b->bm_words); + return; + } + + spin_lock_irq(&b->bm_lock); + bm = b->bm + offset; + while (number--) *buffer++ = cpu_to_lel(*bm++); + spin_unlock_irq(&b->bm_lock); +} + +/* set all bits in the bitmap */ +void drbd_bm_set_all(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + ERR_IF(!b) return; + ERR_IF(!b->bm) return; + + spin_lock_irq(&b->bm_lock); + memset(b->bm, 0xff, b->bm_words*sizeof(long)); + bm_clear_surplus(b); + b->bm_set = b->bm_bits; + spin_unlock_irq(&b->bm_lock); +} + +static BIO_ENDIO_TYPE bm_async_io_complete BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + struct drbd_bitmap *b = bio->bi_private; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + BIO_ENDIO_FN_START; + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to DRBD_WARN() on this? */ + if (!error && !uptodate) + error = -EIO; + + if (error) { + /* doh. what now? + * for now, set all bits, and flag MD_IO_ERROR + */ + /* FIXME kmap_atomic memset etc. pp. */ + __set_bit(BM_MD_IO_ERROR, &b->bm_flags); + } + if (atomic_dec_and_test(&b->bm_async_io)) + wake_up(&b->bm_io_wait); + + bio_put(bio); + + BIO_ENDIO_FN_RETURN; +} + +STATIC void bm_page_io_async(struct drbd_conf *mdev, struct drbd_bitmap *b, int page_nr, int rw) __must_hold(local) +{ + /* we are process context. we always get a bio */ + /* THINK: do we need GFP_NOIO here? */ + struct bio *bio = bio_alloc(GFP_KERNEL, 1); + struct page *page = vmalloc_to_page((char *)(b->bm) + + (PAGE_SIZE*page_nr)); + unsigned int len; + sector_t on_disk_sector = + mdev->bc->md.md_offset + mdev->bc->md.bm_offset; + on_disk_sector += ((sector_t)page_nr) << (PAGE_SHIFT-9); + + /* this might happen with very small + * flexible external meta data device */ + len = min_t(unsigned int, PAGE_SIZE, + (drbd_md_last_sector(mdev->bc) - on_disk_sector + 1)<<9); + + D_DUMPLU(on_disk_sector); + D_DUMPI(len); + + bio->bi_bdev = mdev->bc->md_bdev; + bio->bi_sector = on_disk_sector; + bio_add_page(bio, page, len, 0); + bio->bi_private = b; + bio->bi_end_io = bm_async_io_complete; + + if (FAULT_ACTIVE(mdev, (rw&WRITE)?DRBD_FAULT_MD_WR:DRBD_FAULT_MD_RD)) { + bio->bi_rw |= rw; + bio_endio(bio, -EIO); + } else { + submit_bio(rw, bio); + } +} + +# if defined(__LITTLE_ENDIAN) + /* nothing to do, on disk == in memory */ +# define bm_cpu_to_lel(x) ((void)0) +# else +void bm_cpu_to_lel(struct drbd_bitmap *b) +{ + /* need to cpu_to_lel all the pages ... + * this may be optimized by using + * cpu_to_lel(-1) == -1 and cpu_to_lel(0) == 0; + * the following is still not optimal, but better than nothing */ + const unsigned long *end = b->bm+b->bm_words; + unsigned long *bm; + if (b->bm_set == 0) { + /* no page at all; avoid swap if all is 0 */ + return; + } else if (b->bm_set == b->bm_bits) { + /* only the last words */ + bm = end-2; + } else { + /* all pages */ + bm = b->bm; + } + for (; bm < end; bm++) + *bm = cpu_to_lel(*bm); +} +# endif +/* lel_to_cpu == cpu_to_lel */ +# define bm_lel_to_cpu(x) bm_cpu_to_lel(x) + +/* + * bm_rw: read/write the whole bitmap from/to its on disk location. + */ +STATIC int bm_rw(struct drbd_conf *mdev, int rw) __must_hold(local) +{ + struct drbd_bitmap *b = mdev->bitmap; + /* sector_t sector; */ + int bm_words, num_pages, i; + unsigned long now; + char ppb[10]; + int err = 0; + + bm_words = drbd_bm_words(mdev); + num_pages = (bm_words*sizeof(long) + PAGE_SIZE-1) >> PAGE_SHIFT; + + /* OK, I manipulate the bitmap low level, + * and I expect to be the exclusive user. + * If not, I am really in a bad mood... + * to catch such bugs early, make all people who want to access the + * bitmap while I read/write it dereference a NULL pointer :-> + */ + mdev->bitmap = NULL; + + /* on disk bitmap is little endian */ + if (rw == WRITE) + bm_cpu_to_lel(b); + + now = jiffies; + atomic_set(&b->bm_async_io, num_pages); + __clear_bit(BM_MD_IO_ERROR, &b->bm_flags); + + /* let the layers below us try to merge these bios... */ + for (i = 0; i < num_pages; i++) + bm_page_io_async(mdev, b, i, rw); + + drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev)); + wait_event(b->bm_io_wait, atomic_read(&b->bm_async_io) == 0); + INFO("%s of bitmap took %lu jiffies\n", + rw == READ ? "reading" : "writing", jiffies - now); + + if (test_bit(BM_MD_IO_ERROR, &b->bm_flags)) { + ALERT("we had at least one MD IO ERROR during bitmap IO\n"); + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + err = -EIO; + } + + now = jiffies; + if (rw == WRITE) { + /* swap back endianness */ + bm_lel_to_cpu(b); + /* flush bitmap to stable storage */ + if (!test_bit(MD_NO_BARRIER,&mdev->flags)) + blkdev_issue_flush(mdev->bc->md_bdev, NULL); + } else /* rw == READ */ { + /* just read, if neccessary adjust endianness */ + b->bm_set = bm_count_bits_swap_endian(b); + INFO("recounting of set bits took additional %lu jiffies\n", + jiffies - now); + } + now = b->bm_set; + + /* ok, done, + * now it is visible again + */ + + mdev->bitmap = b; + + INFO("%s (%lu bits) marked out-of-sync by on disk bit-map.\n", + ppsize(ppb, now << (BM_BLOCK_SIZE_B-10)), now); + + return err; +} + +/** + * drbd_bm_read: Read the whole bitmap from its on disk location. + * + * currently only called from "drbd_nl_disk_conf" + */ +int drbd_bm_read(struct drbd_conf *mdev) __must_hold(local) +{ + struct drbd_bitmap *b = mdev->bitmap; + int err = 0; + + if (b->bm) { + /* bitmap size > 0 */ + err = bm_rw(mdev, READ); + + if (err == 0) + b->bm[b->bm_words] = DRBD_MAGIC; + } + + return err; +} + +/** + * drbd_bm_write: Write the whole bitmap to its on disk location. + * + * called at various occasions. + */ +int drbd_bm_write(struct drbd_conf *mdev) __must_hold(local) +{ + return bm_rw(mdev, WRITE); +} + +/** + * drbd_bm_write_sect: Writes a 512 byte piece of the bitmap to its + * on disk location. On disk bitmap is little endian. + * + * @enr: The _sector_ offset from the start of the bitmap. + * + */ +int drbd_bm_write_sect(struct drbd_conf *mdev, unsigned long enr) __must_hold(local) +{ + sector_t on_disk_sector = enr + mdev->bc->md.md_offset + + mdev->bc->md.bm_offset; + int bm_words, num_words, offset; + int err = 0; + + down(&mdev->md_io_mutex); + bm_words = drbd_bm_words(mdev); + offset = S2W(enr); /* word offset into bitmap */ + num_words = min(S2W(1), bm_words - offset); +#if DUMP_MD >= 3 + INFO("write_sect: sector=%lu offset=%u num_words=%u\n", + enr, offset, num_words); +#endif + if (num_words < S2W(1)) + memset(page_address(mdev->md_io_page), 0, MD_HARDSECT); + drbd_bm_get_lel( mdev, offset, num_words, + page_address(mdev->md_io_page) ); + if (!drbd_md_sync_page_io(mdev, mdev->bc, on_disk_sector, WRITE)) { + int i; + err = -EIO; + ERR( "IO ERROR writing bitmap sector %lu " + "(meta-disk sector %llus)\n", + enr, (unsigned long long)on_disk_sector ); + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + for (i = 0; i < AL_EXT_PER_BM_SECT; i++) + drbd_bm_ALe_set_all(mdev, enr*AL_EXT_PER_BM_SECT+i); + } + mdev->bm_writ_cnt++; + up(&mdev->md_io_mutex); + return err; +} + +void drbd_bm_reset_find(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + + ERR_IF(!b) return; + + spin_lock_irq(&b->bm_lock); + b->bm_fo = 0; + spin_unlock_irq(&b->bm_lock); + +} + +/* NOTE + * find_first_bit returns int, we return unsigned long. + * should not make much difference anyways, but ... + * this returns a bit number, NOT a sector! + */ +unsigned long drbd_bm_find_next(struct drbd_conf *mdev) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long i = -1UL; + + ERR_IF(!b) return i; + ERR_IF(!b->bm) return i; + + spin_lock_irq(&b->bm_lock); + if (b->bm_fo < b->bm_bits) + i = find_next_bit(b->bm, b->bm_bits, b->bm_fo); + else if (b->bm_fo > b->bm_bits) + ERR("bm_fo=%lu bm_bits=%lu\n", b->bm_fo, b->bm_bits); + + if (i >= b->bm_bits) { + i = -1UL; + /* leave b->bm_fo unchanged. */ + } else { + b->bm_fo = i+1; + } + spin_unlock_irq(&b->bm_lock); + return i; +} + +void drbd_bm_set_find(struct drbd_conf *mdev, unsigned long i) +{ + struct drbd_bitmap *b = mdev->bitmap; + + spin_lock_irq(&b->bm_lock); + + b->bm_fo = min_t(unsigned long, i, b->bm_bits); + + spin_unlock_irq(&b->bm_lock); +} + + +int drbd_bm_rs_done(struct drbd_conf *mdev) +{ + return (mdev->bitmap->bm_fo >= mdev->bitmap->bm_bits); +} + +/* returns number of bits actually changed. + * for val != 0, we change 0 -> 1, return code positiv + * for val == 0, we change 1 -> 0, return code negative + * wants bitnr, not sector */ +static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, + const unsigned long e, int val) +{ + unsigned long flags; + struct drbd_bitmap *b = mdev->bitmap; + unsigned long bitnr; + int c = 0; + ERR_IF(!b) return 1; + ERR_IF(!b->bm) return 1; + + spin_lock_irqsave(&b->bm_lock,flags); + for (bitnr = s; bitnr <= e; bitnr++) { + ERR_IF (bitnr >= b->bm_bits) { + ERR("bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits); + } else { + if (val) + c += (0 == __test_and_set_bit(bitnr, b->bm)); + else + c -= (0 != __test_and_clear_bit(bitnr, b->bm)); + } + } + b->bm_set += c; + spin_unlock_irqrestore(&b->bm_lock, flags); + return c; +} + +/* returns number of bits changed 0 -> 1 */ +int drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e) +{ + return bm_change_bits_to(mdev, s, e, 1); +} + +/* returns number of bits changed 1 -> 0 */ +int drbd_bm_clear_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e) +{ + return -bm_change_bits_to(mdev, s, e, 0); +} + +/* returns bit state + * wants bitnr, NOT sector. + * inherently racy... area needs to be locked by means of {al,rs}_lru + * 1 ... bit set + * 0 ... bit not set + * -1 ... first out of bounds access, stop testing for bits! + */ +int drbd_bm_test_bit(struct drbd_conf *mdev, const unsigned long bitnr) +{ + unsigned long flags; + struct drbd_bitmap *b = mdev->bitmap; + int i; + ERR_IF(!b) return 0; + ERR_IF(!b->bm) return 0; + + spin_lock_irqsave(&b->bm_lock, flags); + if (bitnr < b->bm_bits) { + i = test_bit(bitnr, b->bm) ? 1 : 0; + } else if (bitnr == b->bm_bits) { + i = -1; + } else { /* (bitnr > b->bm_bits) */ + ERR("bitnr=%lu > bm_bits=%lu\n", bitnr, b->bm_bits); + i = 0; + } + + spin_unlock_irqrestore(&b->bm_lock, flags); + return i; +} + +/* returns number of bits set */ +int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsigned long e) +{ + unsigned long flags; + struct drbd_bitmap *b = mdev->bitmap; + unsigned long bitnr; + int c = 0; + + /* If this is called without a bitmap, that is a bug. But just to be + * robust in case we screwed up elsewhere, in that case pretend there + * was one dirty bit in the requested area, so we won't try to do a + * local read there (no bitmap probably implies no disk) */ + ERR_IF(!b) return 1; + ERR_IF(!b->bm) return 1; + + spin_lock_irqsave(&b->bm_lock,flags); + for (bitnr = s; bitnr <=e; bitnr++) { + ERR_IF (bitnr >= b->bm_bits) { + ERR("bitnr=%lu bm_bits=%lu\n",bitnr, b->bm_bits); + } else { + c += (0 != test_bit(bitnr, b->bm)); + } + } + spin_unlock_irqrestore(&b->bm_lock,flags); + return c; +} + + +/* inherently racy... + * return value may be already out-of-date when this function returns. + * but the general usage is that this is only use during a cstate when bits are + * only cleared, not set, and typically only care for the case when the return + * value is zero, or we already "locked" this "bitmap extent" by other means. + * + * enr is bm-extent number, since we chose to name one sector (512 bytes) + * worth of the bitmap a "bitmap extent". + * + * TODO + * I think since we use it like a reference count, we should use the real + * reference count of some bitmap extent element from some lru instead... + * + */ +int drbd_bm_e_weight(struct drbd_conf *mdev, unsigned long enr) +{ + struct drbd_bitmap *b = mdev->bitmap; + int count, s, e; + unsigned long flags; + + ERR_IF(!b) return 0; + ERR_IF(!b->bm) return 0; + spin_lock_irqsave(&b->bm_lock, flags); + + s = S2W(enr); + e = min((size_t)S2W(enr+1), b->bm_words); + count = 0; + if (s < b->bm_words) { + const unsigned long *w = b->bm+s; + int n = e-s; + while (n--) count += hweight_long(*w++); + } else { + ERR("start offset (%d) too large in drbd_bm_e_weight\n", s); + } + spin_unlock_irqrestore(&b->bm_lock, flags); +#if DUMP_MD >= 3 + INFO("enr=%lu weight=%d e=%d s=%d\n", enr, count, e, s); +#endif + return count; +} + +/* set all bits covered by the AL-extent al_enr */ +unsigned long drbd_bm_ALe_set_all(struct drbd_conf *mdev, unsigned long al_enr) +{ + struct drbd_bitmap *b = mdev->bitmap; + unsigned long weight; + int count, s, e; + ERR_IF(!b) return 0; + ERR_IF(!b->bm) return 0; + + spin_lock_irq(&b->bm_lock); + weight = b->bm_set; + + s = al_enr * BM_WORDS_PER_AL_EXT; + e = min_t(size_t, s + BM_WORDS_PER_AL_EXT, b->bm_words); + count = 0; + if (s < b->bm_words) { + const unsigned long *w = b->bm+s; + int n = e-s; + while (n--) count += hweight_long(*w++); + n = e-s; + memset(b->bm+s, -1, n*sizeof(long)); + b->bm_set += n*BITS_PER_LONG - count; + if (e == b->bm_words) + b->bm_set -= bm_clear_surplus(b); + } else { + ERR("start offset (%d) too large in drbd_bm_ALe_set_all\n", s); + } + weight = b->bm_set - weight; + spin_unlock_irq(&b->bm_lock); + return weight; +} --- linux-2.6.28.orig/ubuntu/drbd/lru_cache.h +++ linux-2.6.28/ubuntu/drbd/lru_cache.h @@ -0,0 +1,149 @@ +/* +-*- linux-c -*- + lru_cache.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +/* + * The lru_cache describes a big set of objects that are addressed + * by an index number (=lc_number). Only a small fraction of this set + * is present in the cache. + * (You set the size of the cache during lc_alloc) + * Once created, the api consists of + * lc_find(,nr) -- finds the object with the given number, if present + * lc_get(,nr) -- finds the object and increases the usage count + * if not present, actions are taken to make sure that + * the cache is updated, the user is notified of this by a callback. + * Return value is NULL in this case. + * As soon as the user informs the cache that it has been updated, + * the next lc_get on that very object number will be successfull. + * lc_put(,lc_element*) + * -- decreases the usage count of this object, and returns the new value. + * + * NOTE: It is the USERS responsibility + * to make sure that calls do not happen concurrently. + */ + +#ifndef LRU_CACHE_H +#define LRU_CACHE_H + +#include +#ifndef HLIST_HEAD_INIT +# include "hlist.h" +#endif + +#include + +/* FIXME + * I want these structs opaque outside of lru_cache.c + */ + +struct lc_element { + struct hlist_node colision; + struct list_head list; /* LRU list or free list */ + unsigned int refcnt; + unsigned int lc_number; +}; + +struct lru_cache { + struct list_head lru; + struct list_head free; + struct list_head in_use; + size_t element_size; + unsigned int nr_elements; + unsigned int new_number; + + /* here may or may not be a pad... */ + + unsigned int used; + unsigned long flags; + unsigned long hits, misses, starving, dirty, changed; + struct lc_element *changing_element; /* just for paranoia */ + + void *lc_private; + const char *name; + + struct hlist_head slot[0]; + /* hash colision chains here, then element storage. */ +}; + + +/* flag-bits for lru_cache */ +enum { + __LC_PARANOIA, + __LC_DIRTY, + __LC_STARVING, +}; +#define LC_PARANOIA (1<<__LC_PARANOIA) +#define LC_DIRTY (1<<__LC_DIRTY) +#define LC_STARVING (1<<__LC_STARVING) + +extern struct lru_cache *lc_alloc(const char *name, unsigned int e_count, + size_t e_size, void *private_p); +extern void lc_reset(struct lru_cache *lc); +extern void lc_free(struct lru_cache *lc); +extern void lc_set(struct lru_cache *lc, unsigned int enr, int index); +extern void lc_del(struct lru_cache *lc, struct lc_element *element); + +extern struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr); +extern struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr); +extern struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr); +extern unsigned int lc_put(struct lru_cache *lc, struct lc_element *e); +extern void lc_changed(struct lru_cache *lc, struct lc_element *e); + +struct seq_file; +extern size_t lc_printf_stats(struct seq_file *seq, struct lru_cache *lc); + +void lc_dump(struct lru_cache *lc, struct seq_file *seq, char *utext, + void (*detail) (struct seq_file *, struct lc_element *) ); + +/* This can be used to stop lc_get from changing the set of active elements. + * Note that the reference counts and order on the lru list may still change. + * returns true if we aquired the lock. + */ +static inline int lc_try_lock(struct lru_cache *lc) +{ + return !test_and_set_bit(__LC_DIRTY, &lc->flags); +} + +static inline void lc_unlock(struct lru_cache *lc) +{ + clear_bit(__LC_DIRTY, &lc->flags); + smp_mb__after_clear_bit(); +} + +static inline int lc_is_used(struct lru_cache *lc, unsigned int enr) +{ + struct lc_element *e = lc_find(lc, enr); + return (e && e->refcnt); +} + +#define LC_FREE (-1U) + +#define lc_e_base(lc) ((char *) ( (lc)->slot + (lc)->nr_elements ) ) +#define lc_entry(lc, i) ((struct lc_element *) \ + (lc_e_base(lc) + (i)*(lc)->element_size)) +#define lc_index_of(lc, e) (((char *)(e) - lc_e_base(lc))/(lc)->element_size) + +#endif --- linux-2.6.28.orig/ubuntu/drbd/drbd_main.c +++ linux-2.6.28/ubuntu/drbd/drbd_main.c @@ -0,0 +1,3752 @@ +/* +-*- Linux-c -*- + drbd.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define __KERNEL_SYSCALLS__ +#include +#include + +#include +#include +#include "drbd_int.h" +#include "drbd_req.h" /* only for _req_mod in tl_release and tl_clear */ + +struct after_state_chg_work { + struct drbd_work w; + union drbd_state_t os; + union drbd_state_t ns; + enum chg_state_flags flags; + struct completion *done; +}; + +int drbdd_init(struct Drbd_thread *); +int drbd_worker(struct Drbd_thread *); +int drbd_asender(struct Drbd_thread *); + +int drbd_init(void); +int drbd_open(struct inode *inode, struct file *file); +int drbd_close(struct inode *inode, struct file *file); +int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused); +static void after_state_ch(struct drbd_conf *mdev, union drbd_state_t os, + union drbd_state_t ns, enum chg_state_flags flags); +int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused); +void md_sync_timer_fn(unsigned long data); + +MODULE_AUTHOR("Philipp Reisner , " + "Lars Ellenberg "); +MODULE_DESCRIPTION("drbd - Distributed Replicated Block Device v" REL_VERSION); +MODULE_LICENSE("GPL"); +MODULE_PARM_DESC(minor_count, "Maximum number of drbd devices (1-255)"); +MODULE_ALIAS_BLOCKDEV_MAJOR(DRBD_MAJOR); + +#include +/* allow_open_on_secondary */ +MODULE_PARM_DESC(allow_oos, "DONT USE!"); +/* thanks to these macros, if compiled into the kernel (not-module), + * this becomes the boot parameter drbd.minor_count */ +module_param(minor_count, int,0444); +module_param(allow_oos, bool,0); + +#ifdef DRBD_ENABLE_FAULTS +int enable_faults; +int fault_rate; +static int fault_count; +int fault_devs; +/* bitmap of enabled faults */ +module_param(enable_faults, int, 0664); +/* fault rate % value - applies to all enabled faults */ +module_param(fault_rate, int, 0664); +/* count of faults inserted */ +module_param(fault_count, int, 0664); +/* bitmap of devices to insert faults on */ +module_param(fault_devs, int, 0644); +#endif + +/* module parameter, defined */ +int minor_count = 32; +int allow_oos; + +#ifdef ENABLE_DYNAMIC_TRACE +int trace_type; /* Bitmap of trace types to enable */ +int trace_level; /* Current trace level */ +int trace_devs; /* Bitmap of devices to trace */ +int proc_details; /* Detail level in proc drbd*/ + +module_param(trace_level, int, 0644); +module_param(trace_type, int, 0644); +module_param(trace_devs, int, 0644); +module_param(proc_details, int, 0644); +#endif + +/* Module parameter for setting the user mode helper program + * to run. Default is /sbin/drbdadm */ +char usermode_helper[80] = "/sbin/drbdadm"; + +module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644); + +/* in 2.6.x, our device mapping and config info contains our virtual gendisks + * as member "struct gendisk *vdisk;" + */ +struct drbd_conf **minor_table; + +struct kmem_cache *drbd_request_cache; +struct kmem_cache *drbd_ee_cache; +mempool_t *drbd_request_mempool; +mempool_t *drbd_ee_mempool; + +/* I do not use a standard mempool, because: + 1) I want to hand out the preallocated objects first. + 2) I want to be able to interrupt sleeping allocation with a signal. + Note: This is a single linked list, the next pointer is the private + member of struct page. + */ +struct page *drbd_pp_pool; +spinlock_t drbd_pp_lock; +int drbd_pp_vacant; +wait_queue_head_t drbd_pp_wait; + +STATIC struct block_device_operations drbd_ops = { + .owner = THIS_MODULE, + .open = drbd_open, + .release = drbd_close, +}; + +#define ARRY_SIZE(A) (sizeof(A)/sizeof(A[0])) + +#ifdef __CHECKER__ +/* When checking with sparse, and this is an inline function, sparse will + give tons of false positives. When this is a real functions sparse works. + */ +int _inc_local_if_state(struct drbd_conf* mdev, enum drbd_disk_state mins) +{ + int io_allowed; + + atomic_inc(&mdev->local_cnt); + io_allowed = (mdev->state.disk >= mins ); + if( !io_allowed ) { + if(atomic_dec_and_test(&mdev->local_cnt)) + wake_up(&mdev->misc_wait); + } + return io_allowed; +} + +#endif + +/************************* The transfer log start */ +STATIC int tl_init(struct drbd_conf *mdev) +{ + struct drbd_barrier *b; + + b = kmalloc(sizeof(struct drbd_barrier), GFP_KERNEL); + if (!b) + return 0; + INIT_LIST_HEAD(&b->requests); + INIT_LIST_HEAD(&b->w.list); + b->next = NULL; + b->br_number = 4711; + b->n_req = 0; + b->w.cb = NULL; /* if this is != NULL, we need to dec_ap_pending in tl_clear */ + + mdev->oldest_barrier = b; + mdev->newest_barrier = b; + + mdev->tl_hash = NULL; + mdev->tl_hash_s = 0; + + return 1; +} + +STATIC void tl_cleanup(struct drbd_conf *mdev) +{ + D_ASSERT(mdev->oldest_barrier == mdev->newest_barrier); + kfree(mdev->oldest_barrier); + kfree(mdev->unused_spare_barrier); + kfree(mdev->tl_hash); + mdev->tl_hash_s = 0; +} + +/** + * _tl_add_barrier: Adds a barrier to the TL. + */ +void _tl_add_barrier(struct drbd_conf *mdev, struct drbd_barrier *new) +{ + struct drbd_barrier *newest_before; + + INIT_LIST_HEAD(&new->requests); + INIT_LIST_HEAD(&new->w.list); + new->w.cb = NULL; /* if this is != NULL, we need to dec_ap_pending in tl_clear */ + new->next = NULL; + new->n_req = 0; + + newest_before = mdev->newest_barrier; + /* never send a barrier number == 0, because that is special-cased + * when using TCQ for our write ordering code */ + new->br_number = (newest_before->br_number+1) ?: 1; + if (mdev->newest_barrier != new) { + mdev->newest_barrier->next = new; + mdev->newest_barrier = new; + } +} + +/* when we receive a barrier ack */ +void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr, + unsigned int set_size) +{ + struct drbd_barrier *b, *nob; /* next old barrier */ + struct list_head *le, *tle; + struct drbd_request *r; + + spin_lock_irq(&mdev->req_lock); + + b = mdev->oldest_barrier; + + /* Clean up list of requests processed during current epoch */ + list_for_each_safe(le, tle, &b->requests) { + r = list_entry(le, struct drbd_request, tl_requests); + _req_mod(r, barrier_acked, 0); + } + list_del(&b->requests); + /* There could be requests on the list waiting for completion + of the write to the local disk, to avoid corruptions of + slab's data structures we have to remove the lists head */ + + D_ASSERT(b->br_number == barrier_nr); + D_ASSERT(b->n_req == set_size); + +#if 1 + if (b->br_number != barrier_nr) { + DUMPI(b->br_number); + DUMPI(barrier_nr); + } + if (b->n_req != set_size) { + DUMPI(b->n_req); + DUMPI(set_size); + } +#endif + + nob = b->next; + if (test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) { + _tl_add_barrier(mdev, b); + if (nob) + mdev->oldest_barrier = nob; + /* if nob == NULL b was the only barrier, and becomes the new + barrer. Threfore mdev->oldest_barrier points already to b */ + } else { + D_ASSERT(nob != NULL); + mdev->oldest_barrier = nob; + kfree(b); + } + + spin_unlock_irq(&mdev->req_lock); +} + + +/* called by drbd_disconnect (exiting receiver thread) + * or from some after_state_ch */ +void tl_clear(struct drbd_conf *mdev) +{ + struct drbd_barrier *b, *tmp; + + DRBD_WARN("tl_clear()\n"); + + spin_lock_irq(&mdev->req_lock); + + b = mdev->oldest_barrier; + while ( b ) { + struct list_head *le, *tle; + struct drbd_request *r; + + list_for_each_safe(le, tle, &b->requests) { + r = list_entry(le, struct drbd_request, tl_requests); + _req_mod(r, connection_lost_while_pending, 0); + } + tmp = b->next; + + /* there could still be requests on that ring list, + * in case local io is still pending */ + list_del(&b->requests); + + /* dec_ap_pending corresponding to queue_barrier. + * the newest barrier may not have been queued yet, + * in which case w.cb is still NULL. */ + if (b->w.cb != NULL) + dec_ap_pending(mdev); + + if (b == mdev->newest_barrier) { + /* recycle, but reinit! */ + D_ASSERT(tmp == NULL); + INIT_LIST_HEAD(&b->requests); + INIT_LIST_HEAD(&b->w.list); + b->w.cb = NULL; + b->br_number = 4711; + b->n_req = 0; + + mdev->oldest_barrier = b; + break; + } + kfree(b); + b = tmp; + } + D_ASSERT(mdev->newest_barrier == mdev->oldest_barrier); + D_ASSERT(mdev->newest_barrier->br_number == 4711); + + /* ensure bit indicating barrier is required is clear */ + clear_bit(CREATE_BARRIER, &mdev->flags); + + spin_unlock_irq(&mdev->req_lock); +} + +/** + * drbd_io_error: Handles the on_io_error setting, should be called in the + * unlikely(!drbd_bio_uptodate(e->bio)) case from kernel thread context. + * See also drbd_chk_io_error + * + * NOTE: we set ourselves FAILED here if on_io_error is Detach or Panic OR + * if the forcedetach flag is set. This flag is set when failures + * occur writing the meta data portion of the disk as they are + * not recoverable. We also try to write the "need full sync bit" here + * anyways. This is to make sure that you get a resynchronisation of + * the full device the next time you connect. + */ +int drbd_io_error(struct drbd_conf *mdev, int forcedetach) +{ + enum io_error_handler eh; + unsigned long flags; + int send; + int ok = 1; + + eh = PassOn; + if (inc_local_if_state(mdev, Failed)) { + eh = mdev->bc->dc.on_io_error; + dec_local(mdev); + } + + if (!forcedetach && eh == PassOn) + return 1; + + spin_lock_irqsave(&mdev->req_lock, flags); + send = (mdev->state.disk == Failed); + if (send) + _drbd_set_state(_NS(mdev, disk, Diskless), ChgStateHard, NULL); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (!send) + return ok; + + if (mdev->state.conn >= Connected) { + ok = drbd_send_state(mdev); + if (ok) DRBD_WARN("Notified peer that my disk is broken.\n"); + else ERR("Sending state in drbd_io_error() failed\n"); + } + + /* Make sure we try to flush meta-data to disk - we come + * in here because of a local disk error so it might fail + * but we still need to try -- both because the error might + * be in the data portion of the disk and because we need + * to ensure the md-sync-timer is stopped if running. */ + drbd_md_sync(mdev); + + /* Releasing the backing device is done in after_state_ch() */ + + if (eh == CallIOEHelper) + drbd_khelper(mdev, "local-io-error"); + + return ok; +} + +/** + * cl_wide_st_chg: + * Returns TRUE if this state change should be preformed as a cluster wide + * transaction. Of course it returns 0 as soon as the connection is lost. + */ +STATIC int cl_wide_st_chg(struct drbd_conf *mdev, + union drbd_state_t os, union drbd_state_t ns) +{ + return ( os.conn >= Connected && ns.conn >= Connected && + ( ( os.role != Primary && ns.role == Primary ) || + ( os.conn != StartingSyncT && ns.conn == StartingSyncT ) || + ( os.conn != StartingSyncS && ns.conn == StartingSyncS ) || + ( os.disk != Diskless && ns.disk == Diskless ) ) ) || + (os.conn >= Connected && ns.conn == Disconnecting) || + (os.conn == Connected && ns.conn == VerifyS); +} + +int drbd_change_state(struct drbd_conf *mdev, enum chg_state_flags f, + union drbd_state_t mask, union drbd_state_t val) +{ + unsigned long flags; + union drbd_state_t os, ns; + int rv; + + spin_lock_irqsave(&mdev->req_lock, flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; + rv = _drbd_set_state(mdev, ns, f, NULL); + ns = mdev->state; + spin_unlock_irqrestore(&mdev->req_lock, flags); + + return rv; +} + +void drbd_force_state(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val) +{ + drbd_change_state(mdev, ChgStateHard, mask, val); +} + +int is_valid_state(struct drbd_conf *mdev, union drbd_state_t ns); +int is_valid_state_transition(struct drbd_conf *, + union drbd_state_t, union drbd_state_t); +int drbd_send_state_req(struct drbd_conf *, + union drbd_state_t, union drbd_state_t); + +STATIC enum set_st_err _req_st_cond(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val) +{ + union drbd_state_t os, ns; + unsigned long flags; + int rv; + + if (test_and_clear_bit(CL_ST_CHG_SUCCESS, &mdev->flags)) + return SS_CW_Success; + + if (test_and_clear_bit(CL_ST_CHG_FAIL, &mdev->flags)) + return SS_CW_FailedByPeer; + + rv = 0; + spin_lock_irqsave(&mdev->req_lock, flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; + if ( !cl_wide_st_chg(mdev, os, ns) ) rv = SS_CW_NoNeed; + if (!rv) { + rv = is_valid_state(mdev, ns); + if (rv == SS_Success) { + rv = is_valid_state_transition(mdev, ns, os); + if (rv == SS_Success) + rv = 0; /* cont waiting, otherwise fail. */ + } + } + spin_unlock_irqrestore(&mdev->req_lock, flags); + + return rv; +} + +/** + * _drbd_request_state: + * This function is the most gracefull way to change state. For some state + * transition this function even does a cluster wide transaction. + * It has a cousin named drbd_request_state(), which is always verbose. + */ +STATIC int drbd_req_state(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val, + enum chg_state_flags f) +{ + struct completion done; + unsigned long flags; + union drbd_state_t os, ns; + int rv; + + init_completion(&done); + + if (f & ChgSerialize) + mutex_lock(&mdev->state_mutex); + + spin_lock_irqsave(&mdev->req_lock,flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; + + if (cl_wide_st_chg(mdev, os, ns)) { + rv = is_valid_state(mdev, ns); + if (rv == SS_Success) + rv = is_valid_state_transition(mdev, ns, os); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (rv < SS_Success) { + if (f & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + goto abort; + } + + drbd_state_lock(mdev); + if ( !drbd_send_state_req(mdev, mask, val) ) { + drbd_state_unlock(mdev); + rv = SS_CW_FailedByPeer; + if (f & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + goto abort; + } + + wait_event(mdev->state_wait, + (rv = _req_st_cond(mdev, mask, val))); + + if (rv < SS_Success) { + /* nearly dead code. */ + drbd_state_unlock(mdev); + if (f & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + goto abort; + } + spin_lock_irqsave(&mdev->req_lock, flags); + os = mdev->state; + ns.i = (os.i & ~mask.i) | val.i; + rv = _drbd_set_state(mdev, ns, f, &done); + drbd_state_unlock(mdev); + } else { + rv = _drbd_set_state(mdev, ns, f, &done); + } + + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (f & ChgWaitComplete && rv == SS_Success) { + D_ASSERT(current != mdev->worker.task); + wait_for_completion(&done); + } + + abort: + if (f & ChgSerialize) + mutex_unlock(&mdev->state_mutex); + + return rv; +} + +/** + * _drbd_request_state: + * This function is the most gracefull way to change state. For some state + * transition this function even does a cluster wide transaction. + * It has a cousin named drbd_request_state(), which is always verbose. + */ +int _drbd_request_state(struct drbd_conf *mdev, union drbd_state_t mask, + union drbd_state_t val, enum chg_state_flags f) +{ + int rv; + + wait_event(mdev->state_wait, + (rv = drbd_req_state(mdev, mask, val, f)) != SS_InTransientState); + + return rv; +} + + +STATIC void print_st(struct drbd_conf *mdev, char *name, union drbd_state_t ns) +{ + ERR(" %s = { cs:%s st:%s/%s ds:%s/%s %c%c%c%c }\n", + name, + conns_to_name(ns.conn), + roles_to_name(ns.role), + roles_to_name(ns.peer), + disks_to_name(ns.disk), + disks_to_name(ns.pdsk), + ns.susp ? 's' : 'r', + ns.aftr_isp ? 'a' : '-', + ns.peer_isp ? 'p' : '-', + ns.user_isp ? 'u' : '-' + ); +} + +void print_st_err(struct drbd_conf *mdev, + union drbd_state_t os, union drbd_state_t ns, int err) +{ + if (err == SS_InTransientState) + return; + ERR("State change failed: %s\n", set_st_err_name(err)); + print_st(mdev, " state", os); + print_st(mdev, "wanted", ns); +} + + +#define peers_to_name roles_to_name +#define pdsks_to_name disks_to_name + +#define susps_to_name(A) ( (A) ? "1" : "0" ) +#define aftr_isps_to_name(A) ( (A) ? "1" : "0" ) +#define peer_isps_to_name(A) ( (A) ? "1" : "0" ) +#define user_isps_to_name(A) ( (A) ? "1" : "0" ) + +#define PSC(A) \ + ({ if (ns.A != os.A) { \ + pbp += sprintf(pbp, #A "( %s -> %s ) ", \ + A##s_to_name(os.A), \ + A##s_to_name(ns.A)); \ + } }) + +int is_valid_state(struct drbd_conf *mdev, union drbd_state_t ns) +{ + /* See drbd_state_sw_errors in drbd_strings.c */ + + enum fencing_policy fp; + int rv = SS_Success; + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + if (inc_net(mdev)) { + if ( !mdev->net_conf->two_primaries && + ns.role == Primary && ns.peer == Primary ) + rv = SS_TwoPrimaries; + dec_net(mdev); + } + + if (rv <= 0) + /* already found a reason to abort */; + else if (ns.role == Secondary && mdev->open_cnt) + rv = SS_DeviceInUse; + + else if ( ns.role == Primary && ns.conn < Connected && + ns.disk < UpToDate ) rv = SS_NoUpToDateDisk; + + else if ( fp >= Resource && + ns.role == Primary && ns.conn < Connected && + ns.pdsk >= DUnknown ) rv = SS_PrimaryNOP; + + else if ( ns.role == Primary && ns.disk <= Inconsistent && + ns.pdsk <= Inconsistent ) rv = SS_NoUpToDateDisk; + + else if ( ns.conn > Connected && + ns.disk < UpToDate && ns.pdsk < UpToDate ) + rv = SS_BothInconsistent; + + else if ( ns.conn > Connected && + (ns.disk == Diskless || ns.pdsk == Diskless ) ) + rv = SS_SyncingDiskless; + + else if ( (ns.conn == Connected || + ns.conn == WFBitMapS || + ns.conn == SyncSource || + ns.conn == PausedSyncS) && + ns.disk == Outdated ) rv = SS_ConnectedOutdates; + + else if( (ns.conn == VerifyS || + ns.conn == VerifyT) && + (mdev->sync_conf.verify_alg[0] == 0)) rv=SS_NoVerifyAlg; + + else if( (ns.conn == VerifyS || + ns.conn == VerifyT) && + mdev->agreed_pro_version < 88) rv = SS_NotSupported; + + return rv; +} + +int is_valid_state_transition(struct drbd_conf *mdev, + union drbd_state_t ns, union drbd_state_t os) +{ + int rv = SS_Success; + + if ( (ns.conn == StartingSyncT || ns.conn == StartingSyncS ) && + os.conn > Connected) rv = SS_ResyncRunning; + + if (ns.conn == Disconnecting && os.conn == StandAlone) + rv = SS_AlreadyStandAlone; + + if (ns.disk > Attaching && os.disk == Diskless) + rv = SS_IsDiskLess; + + if ( ns.conn == WFConnection && os.conn < Unconnected ) + rv=SS_NoNetConfig; + + if ( ns.disk == Outdated && os.disk < Outdated && os.disk != Attaching) + rv=SS_LowerThanOutdated; + + if (ns.conn == Disconnecting && os.conn == Unconnected) + rv = SS_InTransientState; + + if (ns.conn == os.conn && ns.conn == WFReportParams) + rv = SS_InTransientState; + + if( (ns.conn == VerifyS || ns.conn == VerifyT) && os.conn < Connected ) + rv=SS_NeedConnection; + + if ((ns.conn == VerifyS || ns.conn == VerifyT) && + ns.conn != os.conn && os.conn > Connected) + rv = SS_ResyncRunning; + + if ((ns.conn == StartingSyncS || ns.conn == StartingSyncT) && + os.conn < Connected) + rv = SS_NeedConnection; + + return rv; +} + +int _drbd_set_state(struct drbd_conf *mdev, + union drbd_state_t ns, enum chg_state_flags flags, + struct completion *done) +{ + union drbd_state_t os; + int rv = SS_Success; + int warn_sync_abort = 0; + enum fencing_policy fp; + struct after_state_chg_work* ascw; + + MUST_HOLD(&mdev->req_lock); + + os = mdev->state; + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + /* Early state sanitising. */ + + /* Dissalow Network errors to configure a device's network part */ + if ( (ns.conn >= Timeout && ns.conn <= TearDown ) && + os.conn <= Disconnecting ) + ns.conn = os.conn; + + /* After a network error (+TearDown) only Unconnected can follow */ + if (os.conn >= Timeout && os.conn <= TearDown && ns.conn != Unconnected) + ns.conn = os.conn; + + /* After Disconnecting only StandAlone may follow */ + if (os.conn == Disconnecting && ns.conn != StandAlone) + ns.conn = os.conn; + + if (ns.conn < Connected) { + ns.peer_isp = 0; + ns.peer = Unknown; + if ( ns.pdsk > DUnknown || + ns.pdsk < Inconsistent ) ns.pdsk = DUnknown; + } + + if (ns.conn <= Disconnecting && ns.disk == Diskless) + ns.pdsk = DUnknown; + + if (os.conn > Connected && ns.conn > Connected && + (ns.disk <= Failed || ns.pdsk <= Failed )) { + warn_sync_abort = 1; + ns.conn = Connected; + } + + if (ns.conn != os.conn && ns.conn >= Connected && + (ns.disk == Consistent || ns.disk == Outdated)) { + switch(ns.conn) { + case WFBitMapT: + case PausedSyncT: + ns.disk = Outdated; + break; + case Connected: + case WFBitMapS: + case SyncSource: + case PausedSyncS: + ns.disk = UpToDate; + break; + case SyncTarget: + ns.disk = Inconsistent; + DRBD_WARN("Implicit set disk state Inconsistent!\n"); + break; + } + if (os.disk == Outdated && ns.disk == UpToDate) + DRBD_WARN("Implicit set disk from Outdate to UpToDate\n"); + } + + if (ns.conn != os.conn && ns.conn >= Connected && + (ns.pdsk == Consistent || ns.pdsk == Outdated)) { + switch(ns.conn) { + case Connected: + case WFBitMapT: + case PausedSyncT: + case SyncTarget: + ns.pdsk = UpToDate; + break; + case WFBitMapS: + case PausedSyncS: + ns.pdsk = Outdated; + break; + case SyncSource: + ns.pdsk = Inconsistent; + DRBD_WARN("Implicit set pdsk Inconsistent!\n"); + break; + } + if (os.pdsk == Outdated && ns.pdsk == UpToDate) + DRBD_WARN("Implicit set pdsk from Outdate to UpToDate\n"); + } + + /* Connection breaks down before we finished "Negotiating" */ + if (ns.conn < Connected && ns.disk == Negotiating && + inc_local_if_state(mdev, Negotiating)) { + if (mdev->ed_uuid == mdev->bc->md.uuid[Current]) { + ns.disk = mdev->new_state_tmp.disk; + ns.pdsk = mdev->new_state_tmp.pdsk; + } else { + ALERT("Connection lost while negotiating, no data!\n"); + ns.disk = Diskless; + ns.pdsk = DUnknown; + } + dec_local(mdev); + } + + if (fp == Stonith && + (ns.role == Primary && + ns.conn < Connected && + ns.pdsk > Outdated)) + ns.susp = 1; + + if (ns.aftr_isp || ns.peer_isp || ns.user_isp) { + if (ns.conn == SyncSource) + ns.conn = PausedSyncS; + if (ns.conn == SyncTarget) + ns.conn = PausedSyncT; + } else { + if (ns.conn == PausedSyncS) + ns.conn = SyncSource; + if (ns.conn == PausedSyncT) + ns.conn = SyncTarget; + } + + if (ns.i == os.i) + return SS_NothingToDo; + + if ( !(flags & ChgStateHard) ) { + /* pre-state-change checks ; only look at ns */ + /* See drbd_state_sw_errors in drbd_strings.c */ + + rv = is_valid_state(mdev, ns); + if (rv < SS_Success) { + /* If the old state was illegal as well, then let + this happen...*/ + + if ( is_valid_state(mdev, os) == rv ) { + ERR("Considering state change from bad state. " + "Error would be: '%s'\n", + set_st_err_name(rv)); + print_st(mdev, "old", os); + print_st(mdev, "new", ns); + rv = is_valid_state_transition(mdev,ns,os); + } + } else + rv = is_valid_state_transition(mdev, ns, os); + } + + if (rv < SS_Success) { + if (flags & ChgStateVerbose) + print_st_err(mdev, os, ns, rv); + return rv; + } + + if (warn_sync_abort) + DRBD_WARN("Resync aborted.\n"); + +#if DUMP_MD >= 2 + { + char *pbp, pb[300]; + pbp = pb; + *pbp = 0; + PSC(role); + PSC(peer); + PSC(conn); + PSC(disk); + PSC(pdsk); + PSC(susp); + PSC(aftr_isp); + PSC(peer_isp); + PSC(user_isp); + INFO("%s\n", pb); + } +#endif + + mdev->state.i = ns.i; + wake_up(&mdev->misc_wait); + wake_up(&mdev->state_wait); + + /** post-state-change actions **/ + if (os.conn >= SyncSource && ns.conn <= Connected) { + set_bit(STOP_SYNC_TIMER, &mdev->flags); + mod_timer(&mdev->resync_timer, jiffies); + } + + if ( (os.conn == PausedSyncT || os.conn == PausedSyncS) && + (ns.conn == SyncTarget || ns.conn == SyncSource) ) { + INFO("Syncer continues.\n"); + mdev->rs_paused += (long)jiffies-(long)mdev->rs_mark_time; + if (ns.conn == SyncTarget) { + if (!test_and_clear_bit(STOP_SYNC_TIMER,&mdev->flags)) { + mod_timer(&mdev->resync_timer,jiffies); + } + /* This if (!test_bit) is only needed for the case + that a device that has ceased to used its timer, + i.e. it is already in drbd_resync_finished() gets + paused and resumed. */ + } + } + + if ( (os.conn == SyncTarget || os.conn == SyncSource) && + (ns.conn == PausedSyncT || ns.conn == PausedSyncS) ) { + INFO("Resync suspended\n"); + mdev->rs_mark_time = jiffies; + if (ns.conn == PausedSyncT) + set_bit(STOP_SYNC_TIMER, &mdev->flags); + } + + if (os.conn == Connected && + (ns.conn == VerifyS || ns.conn == VerifyT )) { + mdev->ov_position = 0; + mdev->ov_left = + mdev->rs_total = + mdev->rs_mark_left = drbd_bm_bits(mdev); + mdev->rs_start = + mdev->rs_mark_time = jiffies; + mdev->ov_last_oos_size = 0; + mdev->ov_last_oos_start = 0; + if(ns.conn == VerifyS) { + mod_timer(&mdev->resync_timer,jiffies); + } + } + + if(inc_local(mdev)) { + u32 mdf = mdev->bc->md.flags & ~(MDF_Consistent|MDF_PrimaryInd| + MDF_ConnectedInd|MDF_WasUpToDate| + MDF_PeerOutDated ); + if (test_bit(CRASHED_PRIMARY,&mdev->flags) || + mdev->state.role == Primary || + ( mdev->state.pdsk < Inconsistent && + mdev->state.peer == Primary ) ) mdf |= MDF_PrimaryInd; + if (mdev->state.conn > WFReportParams) mdf |= MDF_ConnectedInd; + if (mdev->state.disk > Inconsistent) mdf |= MDF_Consistent; + if (mdev->state.disk > Outdated) mdf |= MDF_WasUpToDate; + if (mdev->state.pdsk <= Outdated && + mdev->state.pdsk >= Inconsistent) mdf |= MDF_PeerOutDated; + if( mdf != mdev->bc->md.flags) { + mdev->bc->md.flags = mdf; + drbd_md_mark_dirty(mdev); + } + if (os.disk < Consistent && ns.disk >= Consistent) + drbd_set_ed_uuid(mdev, mdev->bc->md.uuid[Current]); + dec_local(mdev); + } + + /* Peer was forced UpToDate & Primary, consider to resync */ + if (os.disk == Inconsistent && os.pdsk == Inconsistent && + os.peer == Secondary && ns.peer == Primary) + set_bit(CONSIDER_RESYNC, &mdev->flags); + + /* Receiver should clean up itself */ + if (os.conn != Disconnecting && ns.conn == Disconnecting) + drbd_thread_stop_nowait(&mdev->receiver); + + /* Now the receiver finished cleaning up itself, it should die */ + if (os.conn != StandAlone && ns.conn == StandAlone) + drbd_thread_stop_nowait(&mdev->receiver); + + /* Upon network failure, we need to restart the receiver. */ + if (os.conn > TearDown && + ns.conn <= TearDown && ns.conn >= Timeout) + drbd_thread_restart_nowait(&mdev->receiver); + + ascw = kmalloc(sizeof(*ascw), GFP_ATOMIC); + if (ascw) { + ascw->os = os; + ascw->ns = ns; + ascw->flags = flags; + ascw->w.cb = w_after_state_ch; + ascw->done = done; + drbd_queue_work(&mdev->data.work, &ascw->w); + } else { + DRBD_WARN("Could not kmalloc an ascw\n"); + } + + return rv; +} + +int w_after_state_ch(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct after_state_chg_work *ascw; + + ascw = (struct after_state_chg_work *) w; + after_state_ch(mdev, ascw->os, ascw->ns, ascw->flags); + if (ascw->flags & ChgWaitComplete) { + D_ASSERT(ascw->done != NULL); + complete(ascw->done); + } + kfree(ascw); + + return 1; +} + +static void abw_start_sync(struct drbd_conf *mdev, int rv) +{ + if (rv) { + ERR("Writing the bitmap failed not starting resync.\n"); + _drbd_request_state(mdev, NS(conn, Connected), ChgStateVerbose); + return; + } + + switch (mdev->state.conn) { + case StartingSyncT: + _drbd_request_state(mdev, NS(conn, WFSyncUUID), ChgStateVerbose); + break; + case StartingSyncS: + drbd_start_resync(mdev, SyncSource); + break; + } +} + +static void after_state_ch(struct drbd_conf *mdev, union drbd_state_t os, + union drbd_state_t ns, enum chg_state_flags flags) +{ + enum fencing_policy fp; + + if ( (os.conn != Connected && ns.conn == Connected) ) { + clear_bit(CRASHED_PRIMARY, &mdev->flags); + if (mdev->p_uuid) + mdev->p_uuid[UUID_FLAGS] &= ~((u64)2); + } + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + /* Inform userspace about the change... */ + drbd_bcast_state(mdev, ns); + + /* Here we have the actions that are performed after a + state change. This function might sleep */ + + if (fp == Stonith && ns.susp) { + /* case1: The outdate peer handler is successfull: + * case2: The connection was established again: */ + if ( (os.pdsk > Outdated && ns.pdsk <= Outdated) || + (os.conn < Connected && ns.conn >= Connected) ) { + tl_clear(mdev); + spin_lock_irq(&mdev->req_lock); + _drbd_set_state(_NS(mdev, susp, 0), ChgStateVerbose, NULL); + spin_unlock_irq(&mdev->req_lock); + } + } + /* Do not change the order of the if above and below... */ + if (os.conn != WFBitMapS && ns.conn == WFBitMapS) + drbd_queue_bitmap_io(mdev, &drbd_send_bitmap, NULL); + + /* Lost contact to peer's copy of the data */ + if ( (os.pdsk >= Inconsistent && + os.pdsk != DUnknown && + os.pdsk != Outdated) + && (ns.pdsk < Inconsistent || + ns.pdsk == DUnknown || + ns.pdsk == Outdated) ) { + kfree(mdev->p_uuid); + mdev->p_uuid = NULL; + if (inc_local(mdev)) { + /* generate new uuid, unless we did already */ + if (ns.role == Primary && + mdev->bc->md.uuid[Bitmap] == 0) + drbd_uuid_new_current(mdev); + if (ns.peer == Primary) { + /* Note: The condition ns.peer == Primary implies + that we are connected. Otherwise it would + be ns.peer == Unknown. */ + /* A FullSync is required after a + primary detached from its disk! */ + _drbd_uuid_new_current(mdev); + drbd_send_uuids(mdev); + } + dec_local(mdev); + } + } + + if (ns.pdsk < Inconsistent && inc_local(mdev)) { + if (ns.peer == Primary && mdev->bc->md.uuid[Bitmap] == 0) { + /* Diskless Peer becomes primary */ + if (os.peer == Secondary) + drbd_uuid_new_current(mdev); + + /* Got connected to diskless, primary peer */ + if (os.peer == Unknown) + _drbd_uuid_new_current(mdev); + } + + /* Diskless Peer becomes secondary */ + if (os.peer == Primary && ns.peer == Secondary) + drbd_al_to_on_disk_bm(mdev); + dec_local(mdev); + } + + /* Last part of the attaching process ... */ + if ( ns.conn >= Connected && + os.disk == Attaching && ns.disk == Negotiating ) { + kfree(mdev->p_uuid); /* We expect to receive up-to-date UUIDs soon. */ + mdev->p_uuid = NULL; /* ...to not use the old ones in the mean time */ + drbd_send_sizes(mdev); /* to start sync... */ + drbd_send_uuids(mdev); + drbd_send_state(mdev); + } + + /* We want to pause/continue resync, tell peer. */ + if ( ns.conn >= Connected && + (( os.aftr_isp != ns.aftr_isp ) || + ( os.user_isp != ns.user_isp )) ) + drbd_send_state(mdev); + + /* In case one of the isp bits got set, suspend other devices. */ + if ( ( !os.aftr_isp && !os.peer_isp && !os.user_isp) && + ( ns.aftr_isp || ns.peer_isp || ns.user_isp) ) + suspend_other_sg(mdev); + + /* Make sure the peer gets informed about eventual state + changes (ISP bits) while we were in WFReportParams. */ + if (os.conn == WFReportParams && ns.conn >= Connected) { + drbd_send_state(mdev); + } + + /* We are in the progress to start a full sync... */ + if ( ( os.conn != StartingSyncT && ns.conn == StartingSyncT ) || + ( os.conn != StartingSyncS && ns.conn == StartingSyncS ) ) { + INFO("Queueing bitmap io: about to start a forced full sync\n"); + drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, &abw_start_sync); + } + + /* We are invalidating our self... */ + if ( os.conn < Connected && ns.conn < Connected && + os.disk > Inconsistent && ns.disk == Inconsistent ) { + INFO("Queueing bitmap io: invalidate forced full sync\n"); + drbd_queue_bitmap_io(mdev, &drbd_bmio_set_n_write, NULL); + } + + if (os.disk > Diskless && ns.disk == Diskless) { + /* since inc_local() only works as long as disk>=Inconsistent, + and it is Diskless here, local_cnt can only go down, it can + not increase... It will reach zero */ + wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt)); + + lc_free(mdev->resync); + mdev->resync = NULL; + lc_free(mdev->act_log); + mdev->act_log = NULL; + __no_warn(local, drbd_free_bc(mdev->bc);); + wmb(); /* see begin of drbd_nl_disk_conf() */ + __no_warn(local, mdev->bc = NULL;); + } + + /* A resync finished or aborted, wake paused devices... */ + if ( (os.conn > Connected && ns.conn <= Connected) || + (os.peer_isp && !ns.peer_isp) || + (os.user_isp && !ns.user_isp) ) + resume_next_sg(mdev); + + /* Upon network connection, we need to start the received */ + if (os.conn == StandAlone && ns.conn == Unconnected) + drbd_thread_start(&mdev->receiver); + + /* Terminate worker thread if we are unconfigured - it will be + restarted as needed... */ + if (ns.disk == Diskless && ns.conn == StandAlone) + drbd_thread_stop_nowait(&mdev->worker); + + drbd_md_sync(mdev); +} + + +STATIC int drbd_thread_setup(void *arg) +{ + struct Drbd_thread *thi = (struct Drbd_thread *) arg; + struct drbd_conf *mdev = thi->mdev; + int retval; + + daemonize("drbd_thread"); + D_ASSERT(get_t_state(thi) == Running); + D_ASSERT(thi->task == NULL); + spin_lock(&thi->t_lock); + thi->task = current; + smp_mb(); + spin_unlock(&thi->t_lock); + complete(&thi->startstop); /* notify: thi->task is set. */ + + while (1) { + retval = thi->function(thi); + if (get_t_state(thi) != Restarting) break; + thi->t_state = Running; + } + + mutex_lock(&thi->task_mutex); + spin_lock(&thi->t_lock); + thi->task = NULL; + thi->t_state = None; + smp_mb(); + spin_unlock(&thi->t_lock); + mutex_unlock(&thi->task_mutex); + + /* THINK maybe two different completions? */ + complete(&thi->startstop); /* notify: thi->task unset. */ + + INFO("Terminating %s thread\n", + thi == &mdev->receiver ? "receiver" : + thi == &mdev->asender ? "asender" : + thi == &mdev->worker ? "worker" : "NONSENSE"); + + // Release mod reference taken when thread was started + module_put(THIS_MODULE); + return retval; +} + +STATIC void drbd_thread_init(struct drbd_conf *mdev, struct Drbd_thread *thi, + int (*func) (struct Drbd_thread *)) +{ + spin_lock_init(&thi->t_lock); + thi->task = NULL; + thi->t_state = None; + thi->function = func; + thi->mdev = mdev; + mutex_init(&thi->task_mutex); +} + +int drbd_thread_start(struct Drbd_thread *thi) +{ + int pid; + struct drbd_conf *mdev = thi->mdev; + + spin_lock(&thi->t_lock); + + if (thi->t_state == None) { + INFO("Starting %s thread (from %s [%d])\n", + thi == &mdev->receiver ? "receiver" : + thi == &mdev->asender ? "asender" : + thi == &mdev->worker ? "worker" : "NONSENSE", + current->comm, current->pid); + + /* Get ref on module for thread - this is released when thread exits */ + if (!try_module_get(THIS_MODULE)) { + ERR("Failed to get module reference in drbd_thread_start\n"); + spin_unlock(&thi->t_lock); + return FALSE; + } + + init_completion(&thi->startstop); + D_ASSERT(thi->task == NULL); + thi->t_state = Running; + spin_unlock(&thi->t_lock); + flush_signals(current); /* otherw. may get -ERESTARTNOINTR */ + + /* FIXME rewrite to use kthread interface */ + pid = kernel_thread(drbd_thread_setup, (void *) thi, CLONE_FS); + if (pid < 0) { + ERR("Couldn't start thread (%d)\n", pid); + + module_put(THIS_MODULE); + return FALSE; + } + /* waits until thi->task is set */ + wait_for_completion(&thi->startstop); + D_ASSERT(thi->task); + D_ASSERT(get_t_state(thi) == Running); + } else { + spin_unlock(&thi->t_lock); + } + + return TRUE; +} + + +void _drbd_thread_stop(struct Drbd_thread *thi, int restart, int wait) +{ + struct drbd_conf *mdev = thi->mdev; + enum Drbd_thread_state ns = restart ? Restarting : Exiting; + + spin_lock(&thi->t_lock); + + /* INFO("drbd_thread_stop: %s [%d]: %s %d -> %d; %d\n", + current->comm, current->pid, + thi->task ? thi->task->comm : "NULL", thi->t_state, ns, wait); */ + + if (thi->t_state == None) { + spin_unlock(&thi->t_lock); + if (restart) + drbd_thread_start(thi); + return; + } + + if (thi->t_state != ns) { + if (thi->task == NULL) { + spin_unlock(&thi->t_lock); + return; + } + + thi->t_state = ns; + smp_mb(); + if (thi->task != current) { + if (wait) + init_completion(&thi->startstop); + force_sig(DRBD_SIGKILL, thi->task); + } else + D_ASSERT(!wait); + } + spin_unlock(&thi->t_lock); + + if (wait) { + D_ASSERT(thi->task != current); + wait_for_completion(&thi->startstop); + spin_lock(&thi->t_lock); + D_ASSERT(thi->task == NULL); + D_ASSERT(thi->t_state == None); + spin_unlock(&thi->t_lock); + } +} + +#ifdef CONFIG_SMP +/** + * drbd_calc_cpu_mask: Generates CPU masks, sprad over all CPUs. + * Forces all threads of a device onto the same CPU. This is benificial for + * DRBD's performance. May be overwritten by user's configuration. + */ +cpumask_t drbd_calc_cpu_mask(struct drbd_conf *mdev) +{ + int sv, cpu; + cpumask_t av_cpu_m; + + if (cpus_weight(mdev->cpu_mask)) + return mdev->cpu_mask; + + av_cpu_m = cpu_online_map; + sv = mdev_to_minor(mdev) % cpus_weight(av_cpu_m); + + for_each_cpu_mask(cpu, av_cpu_m) { + if (sv-- == 0) + return cpumask_of_cpu(cpu); + } + + /* some kernel versions "forget" to add the (cpumask_t) typecast + * to that macro, which results in "parse error before '{'" ;-> */ + return (cpumask_t) CPU_MASK_ALL; /* Never reached. */ +} + +void drbd_thread_set_cpu(struct Drbd_thread *thi, cpumask_t cpu_mask) +{ + struct task_struct *p; + + mutex_lock(&thi->task_mutex); + p = thi->task; + if (p) set_cpus_allowed(p, cpu_mask); + mutex_unlock(&thi->task_mutex); +} + +#endif + +/* the appropriate socket mutex must be held already */ +int _drbd_send_cmd(struct drbd_conf *mdev, struct socket *sock, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, + size_t size, unsigned msg_flags) +{ + int sent, ok; + + ERR_IF(!h) return FALSE; + ERR_IF(!size) return FALSE; + + h->magic = BE_DRBD_MAGIC; + h->command = cpu_to_be16(cmd); + h->length = cpu_to_be16(size-sizeof(struct Drbd_Header)); + + dump_packet(mdev, sock, 0, (void *)h, __FILE__, __LINE__); + sent = drbd_send(mdev, sock, h, size, msg_flags); + + ok = ( sent == size ); + if (!ok) + ERR("short sent %s size=%d sent=%d\n", + cmdname(cmd), (int)size, sent); + return ok; +} + +/* don't pass the socket. we may only look at it + * when we hold the appropriate socket mutex. + */ +int drbd_send_cmd(struct drbd_conf *mdev, int use_data_socket, + enum Drbd_Packet_Cmd cmd, struct Drbd_Header *h, size_t size) +{ + int ok = 0; + struct socket *sock; + + if (use_data_socket) { + down(&mdev->data.mutex); + sock = mdev->data.socket; + } else { + down(&mdev->meta.mutex); + sock = mdev->meta.socket; + } + + /* drbd_disconnect() could have called drbd_free_sock() + * while we were waiting in down()... */ + if (likely(sock != NULL)) + ok = _drbd_send_cmd(mdev, sock, cmd, h, size, 0); + + if (use_data_socket) + up(&mdev->data.mutex); + else + up(&mdev->meta.mutex); + return ok; +} + +int drbd_send_cmd2(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, char *data, + size_t size) +{ + struct Drbd_Header h; + int ok; + + h.magic = BE_DRBD_MAGIC; + h.command = cpu_to_be16(cmd); + h.length = cpu_to_be16(size); + + if (!drbd_get_data_sock(mdev)) + return 0; + + dump_packet(mdev, mdev->data.socket, 0, (void *)&h, __FILE__, __LINE__); + + ok = ( sizeof(h) == + drbd_send(mdev, mdev->data.socket, &h, sizeof(h), 0) ); + ok = ok && ( size == + drbd_send(mdev, mdev->data.socket, data, size, 0) ); + + drbd_put_data_sock(mdev); + + return ok; +} + +int drbd_send_sync_param(struct drbd_conf *mdev, struct syncer_conf *sc) +{ + struct Drbd_SyncParam_Packet *p; + int size, rv; + + size = sizeof(struct Drbd_SyncParam_Packet); + + if (mdev->agreed_pro_version >= 88) + size += strlen(mdev->sync_conf.verify_alg) + 1; + + p = kmalloc(size, GFP_KERNEL); + if (p == NULL) + return 0; + + p->rate = cpu_to_be32(sc->rate); + + if (mdev->agreed_pro_version >= 88) + strcpy(p->online_verify_alg,mdev->sync_conf.verify_alg); + + rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, SyncParam, + (struct Drbd_Header *)p, size); + kfree(p); + return rv; +} + +int drbd_send_protocol(struct drbd_conf *mdev) +{ + struct Drbd_Protocol_Packet *p; + int size,rv; + + size = sizeof(struct Drbd_Protocol_Packet); + + if (mdev->agreed_pro_version >= 87) + size += strlen(mdev->net_conf->integrity_alg) + 1; + + if ((p = kmalloc(size, GFP_KERNEL)) == NULL) + return 0; + + p->protocol = cpu_to_be32(mdev->net_conf->wire_protocol); + p->after_sb_0p = cpu_to_be32(mdev->net_conf->after_sb_0p); + p->after_sb_1p = cpu_to_be32(mdev->net_conf->after_sb_1p); + p->after_sb_2p = cpu_to_be32(mdev->net_conf->after_sb_2p); + p->want_lose = cpu_to_be32(mdev->net_conf->want_lose); + p->two_primaries = cpu_to_be32(mdev->net_conf->two_primaries); + + if (mdev->agreed_pro_version >= 87) + strcpy(p->integrity_alg, mdev->net_conf->integrity_alg); + + rv = drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportProtocol, + (struct Drbd_Header *)p, size); + kfree(p); + return rv; +} + +int drbd_send_uuids(struct drbd_conf *mdev) +{ + struct Drbd_GenCnt_Packet p; + int i; + + u64 uuid_flags = 0; + + if (!inc_local_if_state(mdev, Negotiating)) + return 1; + + /* FIXME howto handle diskless ? */ + for (i = Current; i < UUID_SIZE; i++) + p.uuid[i] = mdev->bc ? cpu_to_be64(mdev->bc->md.uuid[i]) : 0; + + mdev->comm_bm_set = drbd_bm_total_weight(mdev); + p.uuid[UUID_SIZE] = cpu_to_be64(mdev->comm_bm_set); + uuid_flags |= mdev->net_conf->want_lose ? 1 : 0; + uuid_flags |= test_bit(CRASHED_PRIMARY, &mdev->flags) ? 2 : 0; + uuid_flags |= mdev->new_state_tmp.disk == Inconsistent ? 4 : 0; + p.uuid[UUID_FLAGS] = cpu_to_be64(uuid_flags); + + dec_local(mdev); + + return drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportUUIDs, + (struct Drbd_Header*)&p, sizeof(p)); +} + +int drbd_send_sync_uuid(struct drbd_conf *mdev, u64 val) +{ + struct Drbd_SyncUUID_Packet p; + + p.uuid = cpu_to_be64(val); + + return drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportSyncUUID, + (struct Drbd_Header *)&p, sizeof(p)); +} + +int drbd_send_sizes(struct drbd_conf *mdev) +{ + struct Drbd_Sizes_Packet p; + sector_t d_size, u_size; + int q_order_type; + int ok; + + if (inc_local_if_state(mdev, Negotiating)) { + D_ASSERT(mdev->bc->backing_bdev); + d_size = drbd_get_max_capacity(mdev->bc); + u_size = mdev->bc->dc.disk_size; + q_order_type = drbd_queue_order_type(mdev); + p.queue_order_type = cpu_to_be32(drbd_queue_order_type(mdev)); + dec_local(mdev); + } else { + d_size = 0; + u_size = 0; + q_order_type = QUEUE_ORDERED_NONE; + } + + p.d_size = cpu_to_be64(d_size); + p.u_size = cpu_to_be64(u_size); + p.c_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev)); + p.max_segment_size = cpu_to_be32(mdev->rq_queue->max_segment_size); + p.queue_order_type = cpu_to_be32(q_order_type); + + ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, ReportSizes, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + +/** + * drbd_send_state: + * Informs the peer about our state. Only call it when + * mdev->state.conn >= Connected (I.e. you may not call it while in + * WFReportParams. Though there is one valid and necessary exception, + * drbd_connect() calls drbd_send_state() while in it WFReportParams. + */ +int drbd_send_state(struct drbd_conf *mdev) +{ + struct socket *sock; + struct Drbd_State_Packet p; + int ok = 0; + + /* Grab state lock so we wont send state if we're in the middle + * of a cluster wide state change on another thread */ + drbd_state_lock(mdev); + + down(&mdev->data.mutex); + + p.state = cpu_to_be32(mdev->state.i); /* Within the send mutex */ + sock = mdev->data.socket; + + if (likely(sock != NULL)) { + ok = _drbd_send_cmd(mdev, sock, ReportState, + (struct Drbd_Header*)&p, sizeof(p), 0); + } + + up(&mdev->data.mutex); + + drbd_state_unlock(mdev); + return ok; +} + +int drbd_send_state_req(struct drbd_conf *mdev, + union drbd_state_t mask, union drbd_state_t val) +{ + struct Drbd_Req_State_Packet p; + + p.mask = cpu_to_be32(mask.i); + p.val = cpu_to_be32(val.i); + + return drbd_send_cmd(mdev, USE_DATA_SOCKET, StateChgRequest, + (struct Drbd_Header *)&p, sizeof(p)); +} + +int drbd_send_sr_reply(struct drbd_conf *mdev, int retcode) +{ + struct Drbd_RqS_Reply_Packet p; + + p.retcode = cpu_to_be32(retcode); + + return drbd_send_cmd(mdev, USE_META_SOCKET, StateChgReply, + (struct Drbd_Header *)&p, sizeof(p)); +} + + +/* See the comment at receive_bitmap() */ +int _drbd_send_bitmap(struct drbd_conf *mdev) +{ + int want; + int ok = TRUE; + int bm_i = 0; + size_t bm_words, num_words; + unsigned long *buffer; + struct Drbd_Header *p; + + ERR_IF(!mdev->bitmap) return FALSE; + + bm_words = drbd_bm_words(mdev); + p = vmalloc(PAGE_SIZE); /* sleeps. cannot fail. */ + buffer = (unsigned long *)p->payload; + + if (inc_local(mdev)) { + if (drbd_md_test_flag(mdev->bc,MDF_FullSync)) { + INFO("Writing the whole bitmap, MDF_FullSync was set.\n"); + drbd_bm_set_all(mdev); + if (drbd_bm_write(mdev)) { + /* write_bm did fail! Leave full sync flag set in Meta Data + * but otherwise process as per normal - need to tell other + * side that a full resync is required! */ + ERR("Failed to write bitmap to disk!\n"); + } + else { + drbd_md_clear_flag(mdev,MDF_FullSync); + drbd_md_sync(mdev); + } + } + dec_local(mdev); + } + + /* + * maybe TODO use some simple compression scheme, nowadays there are + * some such algorithms in the kernel anyways. + */ + do { + num_words = min_t(size_t, BM_PACKET_WORDS, bm_words-bm_i ); + want = num_words * sizeof(long); + if (want) + drbd_bm_get_lel(mdev, bm_i, num_words, buffer); + ok = _drbd_send_cmd(mdev, mdev->data.socket, ReportBitMap, + p, sizeof(*p) + want, 0); + bm_i += num_words; + } while (ok && want); + + vfree(p); + return ok; +} + +int drbd_send_bitmap(struct drbd_conf *mdev) +{ + int err; + + if (!drbd_get_data_sock(mdev)) + return -1; + err = !_drbd_send_bitmap(mdev); + drbd_put_data_sock(mdev); + return err; +} + +int drbd_send_b_ack(struct drbd_conf *mdev, u32 barrier_nr, u32 set_size) +{ + int ok; + struct Drbd_BarrierAck_Packet p; + + p.barrier = barrier_nr; + p.set_size = cpu_to_be32(set_size); + + ok = drbd_send_cmd(mdev, USE_META_SOCKET, BarrierAck, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + +/** + * _drbd_send_ack: + * This helper function expects the sector and block_id parameter already + * in big endian! + */ +STATIC int _drbd_send_ack(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + u64 sector, + u32 blksize, + u64 block_id) +{ + int ok; + struct Drbd_BlockAck_Packet p; + + p.sector = sector; + p.block_id = block_id; + p.blksize = blksize; + p.seq_num = cpu_to_be32(atomic_add_return(1, &mdev->packet_seq)); + + if (!mdev->meta.socket || mdev->state.conn < Connected) + return FALSE; + ok = drbd_send_cmd(mdev, USE_META_SOCKET, cmd, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + +int drbd_send_ack_dp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_Data_Packet *dp) +{ + const int header_size = sizeof(struct Drbd_Data_Packet) + - sizeof(struct Drbd_Header); + int data_size = ((struct Drbd_Header *)dp)->length - header_size; + + return _drbd_send_ack(mdev, cmd, dp->sector, cpu_to_be32(data_size), + dp->block_id); +} + +int drbd_send_ack_rp(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Drbd_BlockRequest_Packet *rp) +{ + return _drbd_send_ack(mdev, cmd, rp->sector, rp->blksize, rp->block_id); +} + +int drbd_send_ack(struct drbd_conf *mdev, + enum Drbd_Packet_Cmd cmd, struct Tl_epoch_entry *e) +{ + return _drbd_send_ack(mdev, cmd, + cpu_to_be64(e->sector), + cpu_to_be32(e->size), + e->block_id); +} + +int drbd_send_ack_ex(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + sector_t sector, int blksize, u64 block_id) +{ + /* This function misuses the block_id field to signal if the blocks + are is sync or not. */ + return _drbd_send_ack(mdev,cmd, + cpu_to_be64(sector), + cpu_to_be32(blksize), + cpu_to_be64(block_id)); +} + + +int drbd_send_drequest(struct drbd_conf *mdev, int cmd, + sector_t sector, int size, u64 block_id) +{ + int ok; + struct Drbd_BlockRequest_Packet p; + + p.sector = cpu_to_be64(sector); + p.block_id = block_id; + p.blksize = cpu_to_be32(size); + + /* FIXME BIO_RW_SYNC ? */ + + ok = drbd_send_cmd(mdev, USE_DATA_SOCKET, cmd, + (struct Drbd_Header *)&p, sizeof(p)); + return ok; +} + + +int drbd_send_drequest_csum(struct drbd_conf *mdev, + sector_t sector,int size, + void *digest, int digest_size, + enum Drbd_Packet_Cmd cmd) +{ + int ok; + struct Drbd_BlockRequest_Packet p; + + p.sector = cpu_to_be64(sector); + p.block_id = BE_DRBD_MAGIC + 0xbeef; + p.blksize = cpu_to_be32(size); + + p.head.magic = BE_DRBD_MAGIC; + p.head.command = cpu_to_be16(cmd); + p.head.length = cpu_to_be16( sizeof(p)-sizeof(struct Drbd_Header) + digest_size ); + + down(&mdev->data.mutex); + + ok = ( sizeof(p) == drbd_send(mdev,mdev->data.socket,&p,sizeof(p),0) ); + ok = ok&& ( digest_size == drbd_send(mdev,mdev->data.socket,digest,digest_size,0) ); + + up(&mdev->data.mutex); + + return ok; +} + +int drbd_send_ov_request(struct drbd_conf *mdev,sector_t sector,int size) +{ + int ok; + struct Drbd_BlockRequest_Packet p; + + p.sector = cpu_to_be64(sector); + p.block_id = BE_DRBD_MAGIC + 0xbabe; + p.blksize = cpu_to_be32(size); + + ok = drbd_send_cmd(mdev,USE_DATA_SOCKET, OVRequest, + (struct Drbd_Header*)&p,sizeof(p)); + return ok; +} + + +/* called on sndtimeo + * returns FALSE if we should retry, + * TRUE if we think connection is dead + */ +STATIC int we_should_drop_the_connection(struct drbd_conf *mdev, struct socket *sock) +{ + int drop_it; + /* long elapsed = (long)(jiffies - mdev->last_received); */ + /* DUMPLU(elapsed); // elapsed ignored for now. */ + + drop_it = mdev->meta.socket == sock + || !mdev->asender.task + || get_t_state(&mdev->asender) != Running + || mdev->state.conn < Connected; + + if (drop_it) + return TRUE; + + drop_it = !--mdev->ko_count; + if (!drop_it) { + ERR("[%s/%d] sock_sendmsg time expired, ko = %u\n", + current->comm, current->pid, mdev->ko_count); + request_ping(mdev); + } + + return drop_it; /* && (mdev->state == Primary) */; +} + +/* The idea of sendpage seems to be to put some kind of reference + * to the page into the skb, and to hand it over to the NIC. In + * this process get_page() gets called. + * + * As soon as the page was really sent over the network put_page() + * gets called by some part of the network layer. [ NIC driver? ] + * + * [ get_page() / put_page() increment/decrement the count. If count + * reaches 0 the page will be freed. ] + * + * This works nicely with pages from FSs. + * But this means that in protocol A we might signal IO completion too early! + * + * In order not to corrupt data during a resync we must make sure + * that we do not reuse our own buffer pages (EEs) to early, therefore + * we have the net_ee list. + * + * XFS seems to have problems, still, it submits pages with page_count == 0! + * As a workaround, we disable sendpage on pages + * with page_count == 0 or PageSlab. + */ +STATIC int _drbd_no_send_page(struct drbd_conf *mdev, struct page *page, + int offset, size_t size) +{ + int ret; + ret = drbd_send(mdev, mdev->data.socket, kmap(page) + offset, size, 0); + kunmap(page); + return ret; +} + +int _drbd_send_page(struct drbd_conf *mdev, struct page *page, + int offset, size_t size) +{ + mm_segment_t oldfs = get_fs(); + int sent, ok; + int len = size; + +#ifdef SHOW_SENDPAGE_USAGE + unsigned long now = jiffies; + static unsigned long total; + static unsigned long fallback; + static unsigned long last_rep; + + /* report statistics every hour, + * if we had at least one fallback. + */ + ++total; + if (fallback && time_before(last_rep+3600*HZ, now)) { + last_rep = now; + printk(KERN_INFO "drbd: sendpage() omitted: %lu/%lu\n", + fallback, total); + } +#endif + + /* PARANOIA. if this ever triggers, + * something in the layers above us is really kaputt. + *one roundtrip later: + * doh. it triggered. so XFS _IS_ really kaputt ... + * oh well... + */ + if ( (page_count(page) < 1) || PageSlab(page) ) { + /* e.g. XFS meta- & log-data is in slab pages, which have a + * page_count of 0 and/or have PageSlab() set... + */ +#ifdef SHOW_SENDPAGE_USAGE + ++fallback; +#endif + sent = _drbd_no_send_page(mdev, page, offset, size); + if (likely(sent > 0)) len -= sent; + goto out; + } + + set_fs(KERNEL_DS); + do { + sent = mdev->data.socket->ops->sendpage(mdev->data.socket, page, + offset, len, + MSG_NOSIGNAL); + if (sent == -EAGAIN) { + if (we_should_drop_the_connection(mdev, + mdev->data.socket)) + break; + else + continue; + } + if (sent <= 0) { + DRBD_WARN("%s: size=%d len=%d sent=%d\n", + __func__, (int)size, len, sent); + break; + } + len -= sent; + offset += sent; + /* FIXME test "last_received" ... */ + } while (len > 0 /* THINK && mdev->cstate >= Connected*/); + set_fs(oldfs); + +out: + ok = (len == 0); + if (likely(ok)) + mdev->send_cnt += size>>9; + return ok; +} + +static inline int _drbd_send_bio(struct drbd_conf *mdev, struct bio *bio) +{ + struct bio_vec *bvec; + int i; + __bio_for_each_segment(bvec, bio, i, 0) { + if (!_drbd_no_send_page(mdev, bvec->bv_page, + bvec->bv_offset, bvec->bv_len)) + return 0; + } + return 1; +} + +static inline int _drbd_send_zc_bio(struct drbd_conf *mdev, struct bio *bio) +{ + struct bio_vec *bvec; + int i; + __bio_for_each_segment(bvec, bio, i, 0) { + if (!_drbd_send_page(mdev, bvec->bv_page, + bvec->bv_offset, bvec->bv_len)) + return 0; + } + + return 1; +} + +/* Used to send write requests + * Primary -> Peer (Data) + */ +int drbd_send_dblock(struct drbd_conf *mdev, struct drbd_request *req) +{ + int ok = 1; + struct Drbd_Data_Packet p; + unsigned int dp_flags = 0; + void *dgb; + int dgs; + + if (!drbd_get_data_sock(mdev)) + return 0; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ? + crypto_hash_digestsize(mdev->integrity_w_tfm) : 0; + + p.head.magic = BE_DRBD_MAGIC; + p.head.command = cpu_to_be16(Data); + p.head.length = cpu_to_be16( sizeof(p) + -sizeof(struct Drbd_Header)+dgs+req->size); + + p.sector = cpu_to_be64(req->sector); + p.block_id = (unsigned long)req; + p.seq_num = cpu_to_be32( req->seq_num = + atomic_add_return(1, &mdev->packet_seq) ); + dp_flags = 0; + + /* NOTE: no need to check if barriers supported here as we would + * not pass the test in make_request_common in that case + */ + if (bio_barrier(req->master_bio)) + dp_flags |= DP_HARDBARRIER; + if (bio_sync(req->master_bio)) + dp_flags |= DP_RW_SYNC; + if (mdev->state.conn >= SyncSource && + mdev->state.conn <= PausedSyncT) + dp_flags |= DP_MAY_SET_IN_SYNC; + + p.dp_flags = cpu_to_be32(dp_flags); + dump_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__); + set_bit(UNPLUG_REMOTE, &mdev->flags); + ok = (sizeof(p) == + drbd_send(mdev, mdev->data.socket, &p, sizeof(p), MSG_MORE)); + if (ok && dgs) { + dgb = mdev->int_dig_out; + drbd_csum(mdev, mdev->integrity_w_tfm, req->master_bio, dgb); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); + } + if (ok) { + if (mdev->net_conf->wire_protocol == DRBD_PROT_A) + ok = _drbd_send_bio(mdev, req->master_bio); + else + ok = _drbd_send_zc_bio(mdev, req->master_bio); + } + + drbd_put_data_sock(mdev); + return ok; +} + +/* answer packet, used to send data back for read requests: + * Peer -> (diskless) Primary (DataReply) + * SyncSource -> SyncTarget (RSDataReply) + */ +int drbd_send_block(struct drbd_conf *mdev, enum Drbd_Packet_Cmd cmd, + struct Tl_epoch_entry *e) +{ + int ok; + struct Drbd_Data_Packet p; + void *dgb; + int dgs; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_w_tfm) ? + crypto_hash_digestsize(mdev->integrity_w_tfm) : 0; + + p.head.magic = BE_DRBD_MAGIC; + p.head.command = cpu_to_be16(cmd); + p.head.length = cpu_to_be16( sizeof(p) + -sizeof(struct Drbd_Header) + dgs + e->size); + + p.sector = cpu_to_be64(e->sector); + p.block_id = e->block_id; + /* p.seq_num = 0; No sequence numbers here.. */ + + /* Only called by our kernel thread. + * This one may be interupted by DRBD_SIG and/or DRBD_SIGKILL + * in response to ioctl or module unload. + */ + if (!drbd_get_data_sock(mdev)) + return 0; + + dump_packet(mdev, mdev->data.socket, 0, (void *)&p, __FILE__, __LINE__); + ok = sizeof(p) == drbd_send(mdev, mdev->data.socket, &p, + sizeof(p), MSG_MORE); + if (ok && dgs) { + dgb = mdev->int_dig_out; + drbd_csum(mdev, mdev->integrity_w_tfm, e->private_bio, dgb); + ok = drbd_send(mdev, mdev->data.socket, dgb, dgs, MSG_MORE); + } + if (ok) + ok = _drbd_send_zc_bio(mdev, e->private_bio); + + drbd_put_data_sock(mdev); + return ok; +} + +/* + drbd_send distinguishes two cases: + + Packets sent via the data socket "sock" + and packets sent via the meta data socket "msock" + + sock msock + -----------------+-------------------------+------------------------------ + timeout conf.timeout / 2 conf.timeout / 2 + timeout action send a ping via msock Abort communication + and close all sockets +*/ + +/* + * you must have down()ed the appropriate [m]sock_mutex elsewhere! + */ +int drbd_send(struct drbd_conf *mdev, struct socket *sock, + void *buf, size_t size, unsigned msg_flags) +{ +#if !HAVE_KERNEL_SENDMSG + mm_segment_t oldfs; + struct iovec iov; +#else + struct kvec iov; +#endif + struct msghdr msg; + int rv, sent = 0; + + if (!sock) + return -1000; + + /* THINK if (signal_pending) return ... ? */ + + iov.iov_base = buf; + iov.iov_len = size; + + msg.msg_name = NULL; + msg.msg_namelen = 0; +#if !HAVE_KERNEL_SENDMSG + msg.msg_iov = &iov; + msg.msg_iovlen = 1; +#endif + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = msg_flags | MSG_NOSIGNAL; + +#if !HAVE_KERNEL_SENDMSG + oldfs = get_fs(); + set_fs(KERNEL_DS); +#endif + + if (sock == mdev->data.socket) + mdev->ko_count = mdev->net_conf->ko_count; + do { + /* STRANGE + * tcp_sendmsg does _not_ use its size parameter at all ? + * + * -EAGAIN on timeout, -EINTR on signal. + */ +/* THINK + * do we need to block DRBD_SIG if sock == &meta.socket ?? + * otherwise wake_asender() might interrupt some send_*Ack ! + */ +#if !HAVE_KERNEL_SENDMSG + rv = sock_sendmsg(sock, &msg, iov.iov_len ); +#else + rv = kernel_sendmsg(sock, &msg, &iov, 1, size); +#endif + if (rv == -EAGAIN) { + if (we_should_drop_the_connection(mdev, sock)) + break; + else + continue; + } + D_ASSERT(rv != 0); + if (rv == -EINTR) { +#if 0 + /* FIXME this happens all the time. + * we don't care for now! + * eventually this should be sorted out be the proper + * use of the SIGNAL_ASENDER bit... */ + if (DRBD_ratelimit(5*HZ, 5)) { + DBG("Got a signal in drbd_send(,%c,)!\n", + sock == mdev->meta.socket ? 'm' : 's'); + /* dump_stack(); */ + } +#endif + flush_signals(current); + rv = 0; + } + if (rv < 0) + break; + sent += rv; + iov.iov_base += rv; + iov.iov_len -= rv; + } while (sent < size); + +#if !HAVE_KERNEL_SENDMSG + set_fs(oldfs); +#endif + + if (rv <= 0) { + if (rv != -EAGAIN) { + ERR("%s_sendmsg returned %d\n", + sock == mdev->meta.socket ? "msock" : "sock", + rv); + drbd_force_state(mdev, NS(conn, BrokenPipe)); + } else + drbd_force_state(mdev, NS(conn, Timeout)); + } + + return sent; +} + +int drbd_open(struct inode *inode, struct file *file) +{ + struct drbd_conf *mdev; + unsigned long flags; + int rv = 0; + + mdev = minor_to_mdev(MINOR(inode->i_rdev)); + if (!mdev) + return -ENODEV; + + spin_lock_irqsave(&mdev->req_lock, flags); + /* to have a stable mdev->state.role + * and no race with updating open_cnt */ + + if (mdev->state.role != Primary) { + if (file->f_mode & FMODE_WRITE) + rv = -EROFS; + else if (!allow_oos) + rv = -EMEDIUMTYPE; + } + + if (!rv) + mdev->open_cnt++; + spin_unlock_irqrestore(&mdev->req_lock, flags); + + return rv; +} + +int drbd_close(struct inode *inode, struct file *file) +{ + /* do not use *file (May be NULL, in case of a unmount :-) */ + struct drbd_conf *mdev; + + mdev = minor_to_mdev(MINOR(inode->i_rdev)); + if (!mdev) + return -ENODEV; + + /* + printk(KERN_ERR "drbd: close(inode=%p,file=%p)" + "current=%p,minor=%d,wc=%d\n", inode, file, current, minor, + inode->i_writecount); + */ + + mdev->open_cnt--; + + return 0; +} + +STATIC void drbd_unplug_fn(struct request_queue *q) +{ + struct drbd_conf *mdev = q->queuedata; + + MTRACE(TraceTypeUnplug, TraceLvlSummary, + INFO("got unplugged ap_bio_count=%d\n", + atomic_read(&mdev->ap_bio_cnt)); + ); + + /* unplug FIRST */ + spin_lock_irq(q->queue_lock); + blk_remove_plug(q); + spin_unlock_irq(q->queue_lock); + + /* only if connected */ + spin_lock_irq(&mdev->req_lock); + if (mdev->state.pdsk >= Inconsistent && mdev->state.conn >= Connected) { + D_ASSERT(mdev->state.role == Primary); + if (test_and_clear_bit(UNPLUG_REMOTE, &mdev->flags)) { + /* add to the data.work queue, + * unless already queued. + * XXX this might be a good addition to drbd_queue_work + * anyways, to detect "double queuing" ... */ + if (list_empty(&mdev->unplug_work.list)) + drbd_queue_work(&mdev->data.work, + &mdev->unplug_work); + } + } + spin_unlock_irq(&mdev->req_lock); + + if (mdev->state.disk >= Inconsistent) + drbd_kick_lo(mdev); +} + +STATIC void drbd_set_defaults(struct drbd_conf *mdev) +{ + mdev->sync_conf.after = DRBD_AFTER_DEF; + mdev->sync_conf.rate = DRBD_RATE_DEF; + mdev->sync_conf.al_extents = DRBD_AL_EXTENTS_DEF; + mdev->state = (union drbd_state_t) { + { Secondary, Unknown, StandAlone, Diskless, DUnknown, 0 } }; +} + +void drbd_init_set_defaults(struct drbd_conf *mdev) +{ + /* the memset(,0,) did most of this. + * note: only assignments, no allocation in here */ + +#ifdef PARANOIA + SET_MDEV_MAGIC(mdev); +#endif + + drbd_set_defaults(mdev); + + /* for now, we do NOT yet support it, + * even though we start some framework + * to eventually support barriers */ + set_bit(NO_BARRIER_SUPP, &mdev->flags); + + atomic_set(&mdev->ap_bio_cnt, 0); + atomic_set(&mdev->ap_pending_cnt, 0); + atomic_set(&mdev->rs_pending_cnt, 0); + atomic_set(&mdev->unacked_cnt, 0); + atomic_set(&mdev->local_cnt, 0); + atomic_set(&mdev->net_cnt, 0); + atomic_set(&mdev->packet_seq, 0); + atomic_set(&mdev->pp_in_use, 0); + + init_MUTEX(&mdev->md_io_mutex); + init_MUTEX(&mdev->data.mutex); + init_MUTEX(&mdev->meta.mutex); + sema_init(&mdev->data.work.s, 0); + sema_init(&mdev->meta.work.s, 0); + mutex_init(&mdev->state_mutex); + + spin_lock_init(&mdev->data.work.q_lock); + spin_lock_init(&mdev->meta.work.q_lock); + + spin_lock_init(&mdev->al_lock); + spin_lock_init(&mdev->req_lock); + spin_lock_init(&mdev->peer_seq_lock); + + INIT_LIST_HEAD(&mdev->active_ee); + INIT_LIST_HEAD(&mdev->sync_ee); + INIT_LIST_HEAD(&mdev->done_ee); + INIT_LIST_HEAD(&mdev->read_ee); + INIT_LIST_HEAD(&mdev->net_ee); + INIT_LIST_HEAD(&mdev->resync_reads); + INIT_LIST_HEAD(&mdev->data.work.q); + INIT_LIST_HEAD(&mdev->meta.work.q); + INIT_LIST_HEAD(&mdev->resync_work.list); + INIT_LIST_HEAD(&mdev->unplug_work.list); + INIT_LIST_HEAD(&mdev->md_sync_work.list); + mdev->resync_work.cb = w_resync_inactive; + mdev->unplug_work.cb = w_send_write_hint; + mdev->md_sync_work.cb = w_md_sync; + init_timer(&mdev->resync_timer); + init_timer(&mdev->md_sync_timer); + mdev->resync_timer.function = resync_timer_fn; + mdev->resync_timer.data = (unsigned long) mdev; + mdev->md_sync_timer.function = md_sync_timer_fn; + mdev->md_sync_timer.data = (unsigned long) mdev; + + init_waitqueue_head(&mdev->misc_wait); + init_waitqueue_head(&mdev->state_wait); + init_waitqueue_head(&mdev->ee_wait); + init_waitqueue_head(&mdev->al_wait); + init_waitqueue_head(&mdev->seq_wait); + + drbd_thread_init(mdev, &mdev->receiver, drbdd_init); + drbd_thread_init(mdev, &mdev->worker, drbd_worker); + drbd_thread_init(mdev, &mdev->asender, drbd_asender); + + mdev->agreed_pro_version = PRO_VERSION_MAX; + +#ifdef __arch_um__ + INFO("mdev = 0x%p\n", mdev); +#endif + mdev->resync_wenr = LC_FREE; +} + +void drbd_mdev_cleanup(struct drbd_conf *mdev) +{ + /* I'd like to cleanup completely, and memset(,0,) it. + * but I'd have to reinit it. + * FIXME: do the right thing... + */ + + /* list of things that may still + * hold data of the previous config + + * act_log ** re-initialized in set_disk + * on_io_error + + * al_tr_cycle ** re-initialized in ... FIXME?? + * al_tr_number + * al_tr_pos + + * backing_bdev ** re-initialized in drbd_free_ll_dev + * lo_file + * md_bdev + * md_file + * md_index + + * ko_count ** re-initialized in set_net + + * last_received ** currently ignored + + * mbds_id ** re-initialized in ... FIXME?? + + * resync ** re-initialized in ... FIXME?? + + *** no re-init necessary (?) *** + * md_io_page + * this_bdev + + * vdisk ? + + * rq_queue ** FIXME ASSERT ?? + * newest_barrier + * oldest_barrier + */ + + D_ASSERT(mdev->receiver.t_state == None); + + if (mdev->verify_tfm) { + crypto_free_hash(mdev->verify_tfm); + mdev->verify_tfm=NULL; + } + /* no need to lock it, I'm the only thread alive */ + if (mdev->epoch_size != 0) + ERR("epoch_size:%d\n", mdev->epoch_size); + mdev->al_writ_cnt = + mdev->bm_writ_cnt = + mdev->read_cnt = + mdev->recv_cnt = + mdev->send_cnt = + mdev->writ_cnt = + mdev->p_size = + mdev->rs_start = + mdev->rs_total = + mdev->rs_failed = + mdev->rs_mark_left = + mdev->rs_mark_time = 0; + D_ASSERT(mdev->net_conf == NULL); + drbd_set_my_capacity(mdev, 0); + drbd_bm_resize(mdev, 0); + drbd_bm_cleanup(mdev); + + /* just in case */ + drbd_free_resources(mdev); + + /* + * currently we drbd_init_ee only on module load, so + * we may do drbd_release_ee only on module unload! + */ + D_ASSERT(list_empty(&mdev->active_ee)); + D_ASSERT(list_empty(&mdev->sync_ee)); + D_ASSERT(list_empty(&mdev->done_ee)); + D_ASSERT(list_empty(&mdev->read_ee)); + D_ASSERT(list_empty(&mdev->net_ee)); + D_ASSERT(list_empty(&mdev->resync_reads)); + D_ASSERT(list_empty(&mdev->data.work.q)); + D_ASSERT(list_empty(&mdev->meta.work.q)); + D_ASSERT(list_empty(&mdev->resync_work.list)); + D_ASSERT(list_empty(&mdev->unplug_work.list)); + +} + + +STATIC void drbd_destroy_mempools(void) +{ + struct page *page; + + while (drbd_pp_pool) { + page = drbd_pp_pool; + drbd_pp_pool = (struct page *)page_private(page); + __free_page(page); + drbd_pp_vacant--; + } + + /* D_ASSERT(atomic_read(&drbd_pp_vacant)==0); */ + + if (drbd_ee_mempool) + mempool_destroy(drbd_ee_mempool); + if (drbd_request_mempool) + mempool_destroy(drbd_request_mempool); + if (drbd_ee_cache) + kmem_cache_destroy(drbd_ee_cache); + if (drbd_request_cache) + kmem_cache_destroy(drbd_request_cache); + + drbd_ee_mempool = NULL; + drbd_request_mempool = NULL; + drbd_ee_cache = NULL; + drbd_request_cache = NULL; + + return; +} + +STATIC int drbd_create_mempools(void) +{ + struct page *page; + const int number = (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE) * minor_count; + int i; + + /* prepare our caches and mempools */ + drbd_request_mempool = NULL; + drbd_ee_cache = NULL; + drbd_request_cache = NULL; + drbd_pp_pool = NULL; + + /* caches */ + drbd_request_cache = kmem_cache_create( + "drbd_req_cache", sizeof(struct drbd_request), 0, 0, NULL); + if (drbd_request_cache == NULL) + goto Enomem; + + drbd_ee_cache = kmem_cache_create( + "drbd_ee_cache", sizeof(struct Tl_epoch_entry), 0, 0, NULL); + if (drbd_ee_cache == NULL) + goto Enomem; + + /* mempools */ + drbd_request_mempool = mempool_create( number, + mempool_alloc_slab, mempool_free_slab, drbd_request_cache); + if (drbd_request_mempool == NULL) + goto Enomem; + + drbd_ee_mempool = mempool_create( number, + mempool_alloc_slab, mempool_free_slab, drbd_ee_cache); + if (drbd_request_mempool == NULL) + goto Enomem; + + /* drbd's page pool */ + spin_lock_init(&drbd_pp_lock); + + for (i = 0; i < number; i++) { + page = alloc_page(GFP_HIGHUSER); + if (!page) + goto Enomem; + set_page_private(page, (unsigned long)drbd_pp_pool); + drbd_pp_pool = page; + } + drbd_pp_vacant = number; + + return 0; + +Enomem: + drbd_destroy_mempools(); /* in case we allocated some */ + return -ENOMEM; +} + +STATIC int drbd_notify_sys(struct notifier_block *this, unsigned long code, + void *unused) +{ + /* just so we have it. you never know what interessting things we + * might want to do here some day... + */ + + return NOTIFY_DONE; +} + +STATIC struct notifier_block drbd_notifier = { + .notifier_call = drbd_notify_sys, +}; + + +STATIC void drbd_cleanup(void) +{ + int i, rr; + + unregister_reboot_notifier(&drbd_notifier); + + drbd_nl_cleanup(); + + if (minor_table) { + if (drbd_proc) { + remove_proc_entry("drbd", NULL); + drbd_proc = NULL; + } + i = minor_count; + while (i--) { + struct drbd_conf *mdev = minor_to_mdev(i); + struct gendisk **disk = &mdev->vdisk; + struct request_queue **q = &mdev->rq_queue; + + if (!mdev) + continue; + drbd_free_resources(mdev); + + if (*disk) { + del_gendisk(*disk); + put_disk(*disk); + *disk = NULL; + } + if (*q) + blk_cleanup_queue(*q); + *q = NULL; + + D_ASSERT(mdev->open_cnt == 0); + if (mdev->this_bdev) + bdput(mdev->this_bdev); + + tl_cleanup(mdev); + if (mdev->resync) + lc_free(mdev->resync); + + rr = drbd_release_ee(mdev, &mdev->active_ee); + if (rr) + ERR("%d EEs in active list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->sync_ee); + if (rr) + ERR("%d EEs in sync list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->read_ee); + if (rr) + ERR("%d EEs in read list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->done_ee); + if (rr) + ERR("%d EEs in done list found!\n", rr); + + rr = drbd_release_ee(mdev, &mdev->net_ee); + if (rr) + ERR("%d EEs in net list found!\n", rr); + + ERR_IF (!list_empty(&mdev->data.work.q)) { + struct list_head *lp; + list_for_each(lp, &mdev->data.work.q) { + DUMPP(lp); + } + }; + + if (mdev->md_io_page) + __free_page(mdev->md_io_page); + + if (mdev->md_io_tmpp) + __free_page(mdev->md_io_tmpp); + + if (mdev->act_log) + lc_free(mdev->act_log); + + kfree(mdev->ee_hash); + mdev->ee_hash_s = 0; + mdev->ee_hash = NULL; + + kfree(mdev->tl_hash); + mdev->tl_hash_s = 0; + mdev->tl_hash = NULL; + + kfree(mdev->app_reads_hash); + mdev->app_reads_hash = NULL; + + kfree(mdev->p_uuid); + mdev->p_uuid = NULL; + + kfree(mdev->int_dig_out); + kfree(mdev->int_dig_in); + kfree(mdev->int_dig_vv); + } + drbd_destroy_mempools(); + } + + kfree(minor_table); + + drbd_unregister_blkdev(DRBD_MAJOR, "drbd"); + + printk(KERN_INFO "drbd: module cleanup done.\n"); +} + +struct drbd_conf *drbd_new_device(int minor) +{ + struct drbd_conf *mdev = NULL; + struct gendisk *disk; + struct request_queue *q; + + mdev = kzalloc(sizeof(struct drbd_conf), GFP_KERNEL); + if (!mdev) + goto Enomem; + + mdev->minor = minor; + + drbd_init_set_defaults(mdev); + + q = blk_alloc_queue(GFP_KERNEL); + if (!q) + goto Enomem; + mdev->rq_queue = q; + q->queuedata = mdev; + q->max_segment_size = DRBD_MAX_SEGMENT_SIZE; + + disk = alloc_disk(1); + if (!disk) + goto Enomem; + mdev->vdisk = disk; + + set_disk_ro( disk, TRUE ); + + disk->queue = q; + disk->major = DRBD_MAJOR; + disk->first_minor = minor; + disk->fops = &drbd_ops; + sprintf(disk->disk_name, "drbd%d", minor); + disk->private_data = mdev; + add_disk(disk); + + mdev->this_bdev = bdget(MKDEV(DRBD_MAJOR, minor)); + /* we have no partitions. we contain only ourselves. */ + mdev->this_bdev->bd_contains = mdev->this_bdev; + + blk_queue_make_request(q, drbd_make_request_26); + blk_queue_merge_bvec(q, drbd_merge_bvec); + q->queue_lock = &mdev->req_lock; /* needed since we use */ + /* plugging on a queue, that actually has no requests! */ + q->unplug_fn = drbd_unplug_fn; + + mdev->md_io_page = alloc_page(GFP_KERNEL); + if (!mdev->md_io_page) + goto Enomem; + + if (!tl_init(mdev)) goto Enomem; + + mdev->app_reads_hash = kzalloc(APP_R_HSIZE*sizeof(void *), GFP_KERNEL); + if (!mdev->app_reads_hash) + goto Enomem; + + return mdev; + + Enomem: + if (mdev) { + kfree(mdev->app_reads_hash); + if (mdev->md_io_page) + __free_page(mdev->md_io_page); + kfree(mdev); + } + return NULL; +} + +int __init drbd_init(void) +{ + int err; + +#ifdef __arch_um__ + printk(KERN_INFO "drbd_module = 0x%p core = 0x%p\n", + THIS_MODULE, THIS_MODULE->module_core); +#endif + + /* FIXME should be a compile time assert */ + if (sizeof(struct Drbd_HandShake_Packet) != 80) { + printk(KERN_ERR + "drbd: never change the size or layout " + "of the HandShake packet.\n"); + return -EINVAL; + } + + if (1 > minor_count || minor_count > 255) { + printk(KERN_ERR + "drbd: invalid minor_count (%d)\n", minor_count); +#ifdef MODULE + return -EINVAL; +#else + minor_count = 8; +#endif + } + + err = drbd_nl_init(); + if (err) + return err; + + err = register_blkdev(DRBD_MAJOR, "drbd"); + if (err) { + printk(KERN_ERR + "drbd: unable to register block device major %d\n", + DRBD_MAJOR); + return err; + } + + register_reboot_notifier(&drbd_notifier); + + /* + * allocate all necessary structs + */ + err = -ENOMEM; + + init_waitqueue_head(&drbd_pp_wait); + + minor_table = kzalloc(sizeof(struct drbd_conf *)*minor_count, + GFP_KERNEL); + if (!minor_table) + goto Enomem; + + err = drbd_create_mempools(); + if (err) + goto Enomem; + +#if CONFIG_PROC_FS + /* + * register with procfs + */ + drbd_proc = proc_create("drbd", S_IFREG | S_IRUGO , NULL, &drbd_proc_fops); + + if (!drbd_proc) { + printk(KERN_ERR "drbd: unable to register proc file\n"); + goto Enomem; + } + + drbd_proc->owner = THIS_MODULE; +#else +# error "Currently drbd depends on the proc file system (CONFIG_PROC_FS)" +#endif + + printk(KERN_INFO "drbd: initialised. " + "Version: " REL_VERSION " (api:%d/proto:%d-%d)\n", + API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX); + printk(KERN_INFO "drbd: %s\n", drbd_buildtag()); + printk(KERN_INFO "drbd: registered as block device major %d\n", + DRBD_MAJOR); + printk(KERN_INFO "drbd: minor_table @ 0x%p\n", minor_table); + + return 0; /* Success! */ + +Enomem: + drbd_cleanup(); + if (err == -ENOMEM) + /* currently always the case */ + printk(KERN_ERR "drbd: ran out of memory\n"); + else + printk(KERN_ERR "drbd: initialization failure\n"); + return err; +} + +void drbd_free_bc(struct drbd_backing_dev *bc) +{ + if (bc == NULL) + return; + + bd_release(bc->backing_bdev); + bd_release(bc->md_bdev); + + fput(bc->lo_file); + fput(bc->md_file); + + kfree(bc); +} + +void drbd_free_sock(struct drbd_conf *mdev) +{ + if (mdev->data.socket) { + sock_release(mdev->data.socket); + mdev->data.socket = NULL; + } + if (mdev->meta.socket) { + sock_release(mdev->meta.socket); + mdev->meta.socket = NULL; + } +} + + +void drbd_free_resources(struct drbd_conf *mdev) +{ + crypto_free_hash(mdev->cram_hmac_tfm); + mdev->cram_hmac_tfm = NULL; + crypto_free_hash(mdev->integrity_w_tfm); + mdev->integrity_w_tfm=NULL; + crypto_free_hash(mdev->integrity_r_tfm); + mdev->integrity_r_tfm=NULL; + drbd_free_sock(mdev); + __no_warn(local, + drbd_free_bc(mdev->bc); + mdev->bc = NULL;); +} + +/*********************************/ +/* meta data management */ + +struct meta_data_on_disk { + u64 la_size; /* last agreed size. */ + u64 uuid[UUID_SIZE]; /* UUIDs. */ + u64 device_uuid; + u64 reserved_u64_1; + u32 flags; /* MDF */ + u32 magic; + u32 md_size_sect; + u32 al_offset; /* offset to this block */ + u32 al_nr_extents; /* important for restoring the AL */ + /* `-- act_log->nr_elements <-- sync_conf.al_extents */ + u32 bm_offset; /* offset to the bitmap, from here */ + u32 bm_bytes_per_bit; /* BM_BLOCK_SIZE */ + u32 reserved_u32[4]; + +} __attribute((packed)); + +/** + * drbd_md_sync: + * Writes the meta data super block if the MD_DIRTY flag bit is set. + */ +void drbd_md_sync(struct drbd_conf *mdev) +{ + struct meta_data_on_disk *buffer; + sector_t sector; + int i; + + if (!test_and_clear_bit(MD_DIRTY, &mdev->flags)) return; + del_timer(&mdev->md_sync_timer); + + /* We use here Failed and not Attaching because we try to write + * metadata even if we detach due to a disk failure! */ + if (!inc_local_if_state(mdev, Failed)) return; + + INFO("Writing meta data super block now.\n"); + + down(&mdev->md_io_mutex); + buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page); + memset(buffer, 0, 512); + + buffer->la_size = cpu_to_be64(drbd_get_capacity(mdev->this_bdev)); + for (i = Current; i < UUID_SIZE; i++) + buffer->uuid[i] = cpu_to_be64(mdev->bc->md.uuid[i]); + buffer->flags = cpu_to_be32(mdev->bc->md.flags); + buffer->magic = cpu_to_be32(DRBD_MD_MAGIC); + + buffer->md_size_sect = cpu_to_be32(mdev->bc->md.md_size_sect); + buffer->al_offset = cpu_to_be32(mdev->bc->md.al_offset); + buffer->al_nr_extents = cpu_to_be32(mdev->act_log->nr_elements); + buffer->bm_bytes_per_bit = cpu_to_be32(BM_BLOCK_SIZE); + buffer->device_uuid = cpu_to_be64(mdev->bc->md.device_uuid); + + buffer->bm_offset = cpu_to_be32(mdev->bc->md.bm_offset); + + D_ASSERT(drbd_md_ss__(mdev, mdev->bc) == mdev->bc->md.md_offset); + sector = mdev->bc->md.md_offset; + + if (drbd_md_sync_page_io(mdev, mdev->bc, sector, WRITE)) { + clear_bit(MD_DIRTY, &mdev->flags); + } else { + /* this was a try anyways ... */ + ERR("meta data update failed!\n"); + + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + } + + /* Update mdev->bc->md.la_size_sect, + * since we updated it on metadata. */ + mdev->bc->md.la_size_sect = drbd_get_capacity(mdev->this_bdev); + + up(&mdev->md_io_mutex); + dec_local(mdev); +} + +/** + * drbd_md_read: + * @bdev: describes the backing storage and the meta-data storage + * Reads the meta data from bdev. Return 0 (NoError) on success, and an + * enum ret_codes in case something goes wrong. + * Currently only: MDIOError, MDInvalid. + */ +int drbd_md_read(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) +{ + struct meta_data_on_disk *buffer; + int i, rv = NoError; + + if (!inc_local_if_state(mdev, Attaching)) return MDIOError; + + down(&mdev->md_io_mutex); + buffer = (struct meta_data_on_disk *)page_address(mdev->md_io_page); + + if (!drbd_md_sync_page_io(mdev, bdev, bdev->md.md_offset, READ)) { + /* NOTE: cant do normal error processing here as this is + called BEFORE disk is attached */ + ERR("Error while reading metadata.\n"); + rv = MDIOError; + goto err; + } + + if (be32_to_cpu(buffer->magic) != DRBD_MD_MAGIC) { + ERR("Error while reading metadata, magic not found.\n"); + rv = MDInvalid; + goto err; + } + if (be32_to_cpu(buffer->al_offset) != bdev->md.al_offset) { + ERR("unexpected al_offset: %d (expected %d)\n", + be32_to_cpu(buffer->al_offset), bdev->md.al_offset); + rv = MDInvalid; + goto err; + } + if (be32_to_cpu(buffer->bm_offset) != bdev->md.bm_offset) { + ERR("unexpected bm_offset: %d (expected %d)\n", + be32_to_cpu(buffer->bm_offset), bdev->md.bm_offset); + rv = MDInvalid; + goto err; + } + if (be32_to_cpu(buffer->md_size_sect) != bdev->md.md_size_sect) { + ERR("unexpected md_size: %u (expected %u)\n", + be32_to_cpu(buffer->md_size_sect), bdev->md.md_size_sect); + rv = MDInvalid; + goto err; + } + + if (be32_to_cpu(buffer->bm_bytes_per_bit) != BM_BLOCK_SIZE) { + ERR("unexpected bm_bytes_per_bit: %u (expected %u)\n", + be32_to_cpu(buffer->bm_bytes_per_bit), BM_BLOCK_SIZE); + rv = MDInvalid; + goto err; + } + + bdev->md.la_size_sect = be64_to_cpu(buffer->la_size); + for (i = Current; i < UUID_SIZE; i++) + bdev->md.uuid[i] = be64_to_cpu(buffer->uuid[i]); + bdev->md.flags = be32_to_cpu(buffer->flags); + mdev->sync_conf.al_extents = be32_to_cpu(buffer->al_nr_extents); + bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid); + + if (mdev->sync_conf.al_extents < 7) + mdev->sync_conf.al_extents = 127; + /* FIXME if this ever happens when reading meta data, + * it possibly screws up reading of the activity log? + */ + + err: + up(&mdev->md_io_mutex); + dec_local(mdev); + + return rv; +} + +/** + * drbd_md_mark_dirty: + * Call this function if you change enything that should be written to + * the meta-data super block. This function sets MD_DIRTY, and starts a + * timer that ensures that within five seconds you have to call drbd_md_sync(). + */ +void drbd_md_mark_dirty(struct drbd_conf *mdev) +{ + set_bit(MD_DIRTY, &mdev->flags); + mod_timer(&mdev->md_sync_timer, jiffies + 5*HZ ); +} + + +STATIC void drbd_uuid_move_history(struct drbd_conf *mdev) __must_hold(local) +{ + int i; + + for ( i = History_start ; i < History_end ; i++ ) { + mdev->bc->md.uuid[i+1] = mdev->bc->md.uuid[i]; + + MTRACE(TraceTypeUuid, TraceLvlAll, + drbd_print_uuid(mdev, i+1); + ); + } +} + +void _drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) +{ + if (idx == Current) { + if (mdev->state.role == Primary) + val |= 1; + else + val &= ~((u64)1); + + drbd_set_ed_uuid(mdev, val); + } + + mdev->bc->md.uuid[idx] = val; + + MTRACE(TraceTypeUuid, TraceLvlSummary, + drbd_print_uuid(mdev, idx); + ); + + drbd_md_mark_dirty(mdev); +} + + +void drbd_uuid_set(struct drbd_conf *mdev, int idx, u64 val) __must_hold(local) +{ + if (mdev->bc->md.uuid[idx]) { + drbd_uuid_move_history(mdev); + mdev->bc->md.uuid[History_start] = mdev->bc->md.uuid[idx]; + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, History_start); + ); + } + _drbd_uuid_set(mdev, idx, val); +} + +/** + * _drbd_uuid_new_current: + * Creates a new current UUID, but does NOT rotate the old current + * UUID into the bitmap slot (but into history). This causes a full + * sync upon next connect. Aditionally the full sync is also requested + * by the FullSync bit. + */ +void _drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) +{ + u64 uuid; + + /* Actually a seperate bit names DisklessPeer, would be + the right thing. But for now the FullSync bit is a + working substitute, to avoid repetitive generating + of new current UUIDs in case we loose connection + and reconnect in a loop. */ + if (mdev->bc->md.flags & MDF_FullSync) return; + INFO("Creating new current UUID [no BitMap]\n"); + get_random_bytes(&uuid, sizeof(u64)); + drbd_uuid_set(mdev, Current, uuid); + drbd_md_set_flag(mdev, MDF_FullSync); +} + +/** + * drbd_uuid_new_current: + * Creates a new current UUID, and rotates the old current UUID into + * the bitmap slot. Causes an incremental resync upon next connect. + */ +void drbd_uuid_new_current(struct drbd_conf *mdev) __must_hold(local) +{ + u64 val; + + INFO("Creating new current UUID\n"); + D_ASSERT(mdev->bc->md.uuid[Bitmap] == 0); + mdev->bc->md.uuid[Bitmap] = mdev->bc->md.uuid[Current]; + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, Bitmap); + ); + + get_random_bytes(&val, sizeof(u64)); + _drbd_uuid_set(mdev, Current, val); +} + +void drbd_uuid_set_bm(struct drbd_conf *mdev, u64 val) __must_hold(local) +{ + if (mdev->bc->md.uuid[Bitmap] == 0 && val == 0) + return; + + if (val == 0) { + drbd_uuid_move_history(mdev); + mdev->bc->md.uuid[History_start] = mdev->bc->md.uuid[Bitmap]; + mdev->bc->md.uuid[Bitmap] = 0; + + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, History_start); + drbd_print_uuid(mdev, Bitmap); + ); + } else { + if (mdev->bc->md.uuid[Bitmap]) + DRBD_WARN("bm UUID already set"); + + mdev->bc->md.uuid[Bitmap] = val; + mdev->bc->md.uuid[Bitmap] &= ~((u64)1); + + MTRACE(TraceTypeUuid, TraceLvlMetrics, + drbd_print_uuid(mdev, Bitmap); + ); + } + drbd_md_mark_dirty(mdev); +} + +/** + * drbd_bmio_set_n_write: + * Is an io_fn for drbd_queue_bitmap_io() or drbd_bitmap_io() that sets + * all bits in the bitmap and writes the whole bitmap to stable storage. + */ +int drbd_bmio_set_n_write(struct drbd_conf *mdev) +{ + int rv = -EIO; + + if (inc_local_if_state(mdev, Attaching)) { + drbd_md_set_flag(mdev, MDF_FullSync); + drbd_md_sync(mdev); + drbd_bm_set_all(mdev); + + rv = drbd_bm_write(mdev); + + if (!rv) { + drbd_md_clear_flag(mdev, MDF_FullSync); + drbd_md_sync(mdev); + } + + dec_local(mdev); + } + + return rv; +} + +STATIC int w_bitmap_io(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct bm_io_work *work = (struct bm_io_work *)w; + int rv; + + D_ASSERT(atomic_read(&mdev->ap_bio_cnt)==0); + + drbd_bm_lock(mdev); + rv = work->io_fn(mdev); + drbd_bm_unlock(mdev); + + clear_bit(BITMAP_IO, &mdev->flags); + wake_up(&mdev->misc_wait); + + if (work->done) work->done(mdev, rv); + + return 1; +} + +/** + * drbd_queue_bitmap_io: + * Queues an IO operation on the whole bitmap. + * While IO on the bitmap happens we freeze appliation IO thus we ensure + * that drbd_set_out_of_sync() can not be called. This function might be + * called from the worker thread and other contexts. + */ +void drbd_queue_bitmap_io(struct drbd_conf *mdev, + int (*io_fn)(struct drbd_conf *), + void (*done)(struct drbd_conf *, int)) +{ + unsigned long flags; + + D_ASSERT(!test_bit(BITMAP_IO, &mdev->flags)); + + mdev->bm_io_work.w.cb = w_bitmap_io; + mdev->bm_io_work.io_fn = io_fn; + mdev->bm_io_work.done = done; + + spin_lock_irqsave(&mdev->req_lock, flags); + clear_bit(BITMAP_IO_QUEUED, &mdev->flags); + set_bit(BITMAP_IO, &mdev->flags); + if (atomic_read(&mdev->ap_bio_cnt) == 0) { + set_bit(BITMAP_IO_QUEUED, &mdev->flags); + drbd_queue_work(&mdev->data.work, &mdev->bm_io_work.w); + } + spin_unlock_irqrestore(&mdev->req_lock, flags); +} + +/** + * drbd_bitmap_io: + * Does an IO operation on the bitmap, freezing application IO while that + * IO operations runs. This functions might not be called from the context + * of the worker thread. + */ +int drbd_bitmap_io(struct drbd_conf *mdev, int (*io_fn)(struct drbd_conf *)) +{ + int rv; + + D_ASSERT(current != mdev->worker.task); + D_ASSERT(!test_bit(BITMAP_IO, &mdev->flags)); + + set_bit(BITMAP_IO_QUEUED, &mdev->flags); + set_bit(BITMAP_IO, &mdev->flags); + wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); + + drbd_bm_lock(mdev); + rv = io_fn(mdev); + drbd_bm_unlock(mdev); + + clear_bit(BITMAP_IO, &mdev->flags); + wake_up(&mdev->misc_wait); + + return rv; +} + +void drbd_md_set_flag(struct drbd_conf *mdev, int flag) __must_hold(local) +{ + MUST_HOLD(mdev->req_lock); + if ( (mdev->bc->md.flags & flag) != flag) { + drbd_md_mark_dirty(mdev); + mdev->bc->md.flags |= flag; + } +} + +void drbd_md_clear_flag(struct drbd_conf *mdev, int flag) __must_hold(local) +{ + MUST_HOLD(mdev->req_lock); + if ( (mdev->bc->md.flags & flag) != 0 ) { + drbd_md_mark_dirty(mdev); + mdev->bc->md.flags &= ~flag; + } +} +int drbd_md_test_flag(struct drbd_backing_dev *bdev, int flag) +{ + return ((bdev->md.flags & flag) != 0); +} + +void md_sync_timer_fn(unsigned long data) +{ + struct drbd_conf *mdev = (struct drbd_conf *) data; + + drbd_queue_work_front(&mdev->data.work, &mdev->md_sync_work); +} + +int w_md_sync(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + DRBD_WARN("md_sync_timer expired! Worker calls drbd_md_sync().\n"); + drbd_md_sync(mdev); + + return 1; +} + +#ifdef DRBD_ENABLE_FAULTS +/* Fault insertion support including random number generator shamelessly + * stolen from kernel/rcutorture.c */ +struct fault_random_state { + unsigned long state; + unsigned long count; +}; + +#define FAULT_RANDOM_MULT 39916801 /* prime */ +#define FAULT_RANDOM_ADD 479001701 /* prime */ +#define FAULT_RANDOM_REFRESH 10000 + +/* + * Crude but fast random-number generator. Uses a linear congruential + * generator, with occasional help from get_random_bytes(). + */ +STATIC unsigned long +_drbd_fault_random(struct fault_random_state *rsp) +{ + long refresh; + + if (--rsp->count < 0) { + get_random_bytes(&refresh, sizeof(refresh)); + rsp->state += refresh; + rsp->count = FAULT_RANDOM_REFRESH; + } + rsp->state = rsp->state * FAULT_RANDOM_MULT + FAULT_RANDOM_ADD; + return swahw32(rsp->state); +} + +STATIC char * +_drbd_fault_str(unsigned int type) { + static char *_faults[] = { + "Meta-data write", + "Meta-data read", + "Resync write", + "Resync read", + "Data write", + "Data read", + "Data read ahead", + }; + + return (type < DRBD_FAULT_MAX)? _faults[type] : "**Unknown**"; +} + +unsigned int +_drbd_insert_fault(struct drbd_conf *mdev, unsigned int type) +{ + static struct fault_random_state rrs = {0, 0}; + + unsigned int ret = ( + (fault_devs == 0 || + ((1 << mdev_to_minor(mdev)) & fault_devs) != 0) && + (((_drbd_fault_random(&rrs) % 100) + 1) <= fault_rate)); + + if (ret) { + fault_count++; + + if (printk_ratelimit()) + DRBD_WARN("***Simulating %s failure\n", + _drbd_fault_str(type)); + } + + return ret; +} +#endif + +#ifdef ENABLE_DYNAMIC_TRACE + +STATIC char *_drbd_uuid_str(unsigned int idx) +{ + static char *uuid_str[] = { + "Current", + "Bitmap", + "History_start", + "History_end", + "UUID_SIZE", + "UUID_FLAGS", + }; + + return (idx < EXT_UUID_SIZE) ? uuid_str[idx] : "*Unknown UUID index*"; +} + +/* Pretty print a UUID value */ +void drbd_print_uuid(struct drbd_conf *mdev, unsigned int idx) __must_hold(local) +{ + INFO(" uuid[%s] now %016llX\n", + _drbd_uuid_str(idx), mdev->bc->md.uuid[idx]); +} + + +/* + * + * drbd_print_buffer + * + * This routine dumps binary data to the debugging output. Can be + * called at interrupt level. + * + * Arguments: + * + * prefix - String is output at the beginning of each line output + * flags - Control operation of the routine. Currently defined + * Flags are: + * DBGPRINT_BUFFADDR; if set, each line starts with the + * virtual address of the line being outupt. If clear, + * each line starts with the offset from the beginning + * of the buffer. + * size - Indicates the size of each entry in the buffer. Supported + * values are sizeof(char), sizeof(short) and sizeof(int) + * buffer - Start address of buffer + * buffer_va - Virtual address of start of buffer (normally the same + * as Buffer, but having it separate allows it to hold + * file address for example) + * length - length of buffer + * + */ +void +drbd_print_buffer(const char *prefix, unsigned int flags, int size, + const void *buffer, const void *buffer_va, + unsigned int length) + +#define LINE_SIZE 16 +#define LINE_ENTRIES (int)(LINE_SIZE/size) +{ + const unsigned char *pstart; + const unsigned char *pstart_va; + const unsigned char *pend; + char bytes_str[LINE_SIZE*3+8], ascii_str[LINE_SIZE+8]; + char *pbytes = bytes_str, *pascii = ascii_str; + int offset = 0; + long sizemask; + int field_width; + int index; + const unsigned char *pend_str; + const unsigned char *p; + int count; + + /* verify size parameter */ + if (size != sizeof(char) && + size != sizeof(short) && + size != sizeof(int)) { + printk(KERN_DEBUG "drbd_print_buffer: " + "ERROR invalid size %d\n", size); + return; + } + + sizemask = size-1; + field_width = size*2; + + /* Adjust start/end to be on appropriate boundary for size */ + buffer = (const char *)((long)buffer & ~sizemask); + pend = (const unsigned char *) + (((long)buffer + length + sizemask) & ~sizemask); + + if (flags & DBGPRINT_BUFFADDR) { + /* Move start back to nearest multiple of line size, + * if printing address. This results in nicely formatted output + * with addresses being on line size (16) byte boundaries */ + pstart = (const unsigned char *)((long)buffer & ~(LINE_SIZE-1)); + } else { + pstart = (const unsigned char *)buffer; + } + + /* Set value of start VA to print if addresses asked for */ + pstart_va = (const unsigned char *)buffer_va + - ((const unsigned char *)buffer-pstart); + + /* Calculate end position to nicely align right hand side */ + pend_str = pstart + (((pend-pstart) + LINE_SIZE-1) & ~(LINE_SIZE-1)); + + /* Init strings */ + *pbytes = *pascii = '\0'; + + /* Start at beginning of first line */ + p = pstart; + count = 0; + + while (p < pend_str) { + if (p < (const unsigned char *)buffer || p >= pend) { + /* Before start of buffer or after end- print spaces */ + pbytes += sprintf(pbytes, "%*c ", field_width, ' '); + pascii += sprintf(pascii, "%*c", size, ' '); + p += size; + } else { + /* Add hex and ascii to strings */ + int val; + switch (size) { + default: + case 1: + val = *(unsigned char *)p; + break; + case 2: + val = *(unsigned short *)p; + break; + case 4: + val = *(unsigned int *)p; + break; + } + + pbytes += sprintf(pbytes, "%0*x ", field_width, val); + + for (index = size; index; index--) { + *pascii++ = isprint(*p) ? *p : '.'; + p++; + } + } + + count++; + + if (count == LINE_ENTRIES || p >= pend_str) { + /* Null terminate and print record */ + *pascii = '\0'; + printk(KERN_DEBUG "%s%8.8lx: %*s|%*s|\n", + prefix, + (flags & DBGPRINT_BUFFADDR) + ? (long)pstart_va : (long)offset, + LINE_ENTRIES*(field_width+1), bytes_str, + LINE_SIZE, ascii_str); + + /* Move onto next line */ + pstart_va += (p-pstart); + pstart = p; + count = 0; + offset += LINE_SIZE; + + /* Re-init strings */ + pbytes = bytes_str; + pascii = ascii_str; + *pbytes = *pascii = '\0'; + } + } +} + +#define PSM(A) \ +do { \ + if (mask.A) { \ + int i = snprintf(p, len, " " #A "( %s )", \ + A##s_to_name(val.A)); \ + if (i >= len) \ + return op; \ + p += i; \ + len -= i; \ + } \ +} while (0) + +STATIC char *dump_st(char *p, int len, union drbd_state_t mask, union drbd_state_t val) +{ + char *op = p; + *p = '\0'; + PSM(role); + PSM(peer); + PSM(conn); + PSM(disk); + PSM(pdsk); + + return op; +} + +#define INFOP(fmt, args...) \ +do { \ + if (trace_level >= TraceLvlAll) { \ + INFO("%s:%d: %s [%d] %s %s " fmt , \ + file, line, current->comm, current->pid, \ + sockname, recv?"<<<":">>>", \ + ## args ); \ + } \ + else { \ + INFO("%s %s " fmt, sockname, \ + recv?"<<<":">>>", \ + ## args ); \ + } \ +} while (0) + +STATIC char *_dump_block_id(u64 block_id, char *buff) +{ + if (is_syncer_block_id(block_id)) + strcpy(buff, "SyncerId"); + else + sprintf(buff, "%llx", block_id); + + return buff; +} + +void +_dump_packet(struct drbd_conf *mdev, struct socket *sock, + int recv, union Drbd_Polymorph_Packet *p, char *file, int line) +{ + char *sockname = sock == mdev->meta.socket ? "meta" : "data"; + int cmd = (recv == 2) ? p->head.command : be16_to_cpu(p->head.command); + char tmp[300]; + union drbd_state_t m, v; + + switch (cmd) { + case HandShake: + INFOP("%s (protocol %u-%u)\n", cmdname(cmd), + be32_to_cpu(p->HandShake.protocol_min), + be32_to_cpu(p->HandShake.protocol_max)); + break; + + case ReportBitMap: /* don't report this */ + break; + + case Data: + INFOP("%s (sector %llus, id %s, seq %u, f %x)\n", cmdname(cmd), + (unsigned long long)be64_to_cpu(p->Data.sector), + _dump_block_id(p->Data.block_id, tmp), + be32_to_cpu(p->Data.seq_num), + be32_to_cpu(p->Data.dp_flags) + ); + break; + + case DataReply: + case RSDataReply: + INFOP("%s (sector %llus, id %s)\n", cmdname(cmd), + (unsigned long long)be64_to_cpu(p->Data.sector), + _dump_block_id(p->Data.block_id, tmp) + ); + break; + + case RecvAck: + case WriteAck: + case RSWriteAck: + case DiscardAck: + case NegAck: + case NegRSDReply: + INFOP("%s (sector %llus, size %u, id %s, seq %u)\n", + cmdname(cmd), + (long long)be64_to_cpu(p->BlockAck.sector), + be32_to_cpu(p->BlockAck.blksize), + _dump_block_id(p->BlockAck.block_id, tmp), + be32_to_cpu(p->BlockAck.seq_num) + ); + break; + + case DataRequest: + case RSDataRequest: + INFOP("%s (sector %llus, size %u, id %s)\n", cmdname(cmd), + (long long)be64_to_cpu(p->BlockRequest.sector), + be32_to_cpu(p->BlockRequest.blksize), + _dump_block_id(p->BlockRequest.block_id, tmp) + ); + break; + + case Barrier: + case BarrierAck: + INFOP("%s (barrier %u)\n", cmdname(cmd), p->Barrier.barrier); + break; + + case ReportUUIDs: + INFOP("%s Curr:%016llX, Bitmap:%016llX, " + "HisSt:%016llX, HisEnd:%016llX\n", + cmdname(cmd), + be64_to_cpu(p->GenCnt.uuid[Current]), + be64_to_cpu(p->GenCnt.uuid[Bitmap]), + be64_to_cpu(p->GenCnt.uuid[History_start]), + be64_to_cpu(p->GenCnt.uuid[History_end])); + break; + + case ReportSizes: + INFOP("%s (d %lluMiB, u %lluMiB, c %lldMiB, " + "max bio %x, q order %x)\n", + cmdname(cmd), + (long long)(be64_to_cpu(p->Sizes.d_size)>>(20-9)), + (long long)(be64_to_cpu(p->Sizes.u_size)>>(20-9)), + (long long)(be64_to_cpu(p->Sizes.c_size)>>(20-9)), + be32_to_cpu(p->Sizes.max_segment_size), + be32_to_cpu(p->Sizes.queue_order_type)); + break; + + case ReportState: + v.i = be32_to_cpu(p->State.state); + m.i = 0xffffffff; + dump_st(tmp, sizeof(tmp), m, v); + INFOP("%s (s %x {%s})\n", cmdname(cmd), v.i, tmp); + break; + + case StateChgRequest: + m.i = be32_to_cpu(p->ReqState.mask); + v.i = be32_to_cpu(p->ReqState.val); + dump_st(tmp, sizeof(tmp), m, v); + INFOP("%s (m %x v %x {%s})\n", cmdname(cmd), m.i, v.i, tmp); + break; + + case StateChgReply: + INFOP("%s (ret %x)\n", cmdname(cmd), + be32_to_cpu(p->RqSReply.retcode)); + break; + + case Ping: + case PingAck: + /* + * Dont trace pings at summary level + */ + if (trace_level < TraceLvlAll) + break; + /* fall through... */ + default: + INFOP("%s (%u)\n", cmdname(cmd), cmd); + break; + } +} + +/* Debug routine to dump info about bio */ + +void _dump_bio(const char *pfx, struct drbd_conf *mdev, struct bio *bio, int complete) +{ +#ifdef CONFIG_LBD +#define SECTOR_FORMAT "%Lx" +#else +#define SECTOR_FORMAT "%lx" +#endif +#define SECTOR_SHIFT 9 + + unsigned long lowaddr = (unsigned long)(bio->bi_sector << SECTOR_SHIFT); + char *faddr = (char *)(lowaddr); + struct bio_vec *bvec; + int segno; + + const int rw = bio->bi_rw; + const int biorw = (rw & (RW_MASK|RWA_MASK)); + const int biobarrier = (rw & (1<>>", + pfx, + biorw==WRITE?"Write":"Read", + biobarrier?":B":"", + biosync?":S":"", + bio, + complete? (drbd_bio_uptodate(bio)? "Success, ":"Failed, ") : "", + bio->bi_sector << SECTOR_SHIFT, + bio->bi_size); + + if (trace_level >= TraceLvlMetrics && + ((biorw == WRITE) ^ complete) ) { + printk(KERN_DEBUG " ind page offset length\n"); + __bio_for_each_segment(bvec, bio, segno, 0) { + printk(KERN_DEBUG " [%d] %p %8.8x %8.8x\n", segno, + bvec->bv_page, bvec->bv_offset, bvec->bv_len); + + if (trace_level >= TraceLvlAll) { + char *bvec_buf; + unsigned long flags; + + bvec_buf = bvec_kmap_irq(bvec, &flags); + + drbd_print_buffer(" ", DBGPRINT_BUFFADDR, 1, + bvec_buf, + faddr, + (bvec->bv_len <= 0x80) + ? bvec->bv_len : 0x80); + + bvec_kunmap_irq(bvec_buf, &flags); + + if (bvec->bv_len > 0x40) + printk(KERN_DEBUG " ....\n"); + + faddr += bvec->bv_len; + } + } + } +} +#endif + +module_init(drbd_init) +module_exit(drbd_cleanup) --- linux-2.6.28.orig/ubuntu/drbd/Kconfig +++ linux-2.6.28/ubuntu/drbd/Kconfig @@ -0,0 +1,32 @@ +# +# DRBD device driver configuration +# +config BLK_DEV_DRBD + tristate "DRBD Distributed Replicated Block Device support" + select INET + select PROC_FS + select CONNECTOR + select CRYPTO + select CRYPTO_HMAC + ---help--- + DRBD is a block device which is designed to build high availability + clusters. This is done by mirroring a whole block device via (a + dedicated) network. You could see it as a network RAID 1. + + Each minor device has a state, which can be 'primary' or 'secondary'. + On the node with the primary device the application is supposed to + run and to access the device (/dev/drbdX). Every write is sent to the + local 'lower level block device' and via network to the node with the + device in 'secondary' state. + The secondary device simply writes the data to its lower level block + device. Currently no read-balancing via the network is done. + + DRBD can also be used with "shared-disk semantics" (primary-primary), + even though it is a "shared-nothing cluster". You'd need to use a + cluster file system on top of that for cache coherency. + + DRBD management is done through user-space tools. + For automatic failover you need a cluster manager (e.g. heartbeat). + See also: http://www.drbd.org/, http://www.linux-ha.org + + If unsure, say N. --- linux-2.6.28.orig/ubuntu/drbd/drbd_wrappers.h +++ linux-2.6.28/ubuntu/drbd/drbd_wrappers.h @@ -0,0 +1,442 @@ +#include + +#include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) +# error "use a 2.6 kernel, please" +#endif + + +/* struct page has a union in 2.6.15 ... + * an anonymous union and struct since 2.6.16 + * or in fc5 "2.6.15" */ +#include +#ifndef page_private +# define page_private(page) ((page)->private) +# define set_page_private(page, v) ((page)->private = (v)) +#endif + +/* see get_sb_bdev and bd_claim */ +extern char *drbd_sec_holder; + +static inline sector_t drbd_get_hardsect(struct block_device *bdev) +{ + return bdev->bd_disk->queue->hardsect_size; +} + +/* Returns the number of 512 byte sectors of the device */ +static inline sector_t drbd_get_capacity(struct block_device *bdev) +{ + /* return bdev ? get_capacity(bdev->bd_disk) : 0; */ + return bdev ? bdev->bd_inode->i_size >> 9 : 0; +} + +/* sets the number of 512 byte sectors of our virtual device */ +static inline void drbd_set_my_capacity(struct drbd_conf *mdev, + sector_t size) +{ + /* set_capacity(mdev->this_bdev->bd_disk, size); */ + set_capacity(mdev->vdisk, size); + mdev->this_bdev->bd_inode->i_size = (loff_t)size << 9; +} + +#define drbd_bio_uptodate(bio) bio_flagged(bio, BIO_UPTODATE) + +static inline int drbd_bio_has_active_page(struct bio *bio) +{ + struct bio_vec *bvec; + int i; + + __bio_for_each_segment(bvec, bio, i, 0) { + if (page_count(bvec->bv_page) > 1) return 1; + } + + return 0; +} + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +/* Before Linux-2.6.24 bie_endio() had the size of the bio as second argument. + See 6712ecf8f648118c3363c142196418f89a510b90 */ +#define bio_endio(B,E) bio_endio(B, (B)->bi_size, E) +#define BIO_ENDIO_TYPE int +#define BIO_ENDIO_ARGS(b,e) (b, unsigned int bytes_done, e) +#define BIO_ENDIO_FN_START if (bio->bi_size) return 1 +#define BIO_ENDIO_FN_RETURN return 0 +#else +#define BIO_ENDIO_TYPE void +#define BIO_ENDIO_ARGS(b,e) (b,e) +#define BIO_ENDIO_FN_START while(0) {} +#define BIO_ENDIO_FN_RETURN return +#endif + +// bi_end_io handlers +extern BIO_ENDIO_TYPE drbd_md_io_complete BIO_ENDIO_ARGS(struct bio *bio, int error); +extern BIO_ENDIO_TYPE drbd_endio_read_sec BIO_ENDIO_ARGS(struct bio *bio, int error); +extern BIO_ENDIO_TYPE drbd_endio_write_sec BIO_ENDIO_ARGS(struct bio *bio, int error); +extern BIO_ENDIO_TYPE drbd_endio_pri BIO_ENDIO_ARGS(struct bio *bio, int error); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +/* Before 2.6.23 (with 20c2df83d25c6a95affe6157a4c9cac4cf5ffaac) kmem_cache_create had a + ctor and a dtor */ +#define kmem_cache_create(N,S,A,F,C) kmem_cache_create(N,S,A,F,C,NULL) +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +static inline void sg_set_page(struct scatterlist *sg, struct page *page, + unsigned int len, unsigned int offset) +{ + sg->page = page; + sg->offset = offset; + sg->length = len; +} + +#define sg_init_table(S,N) ({}) + +#ifdef NEED_SG_SET_BUF +static inline void sg_set_buf(struct scatterlist *sg, const void *buf, + unsigned int buflen) +{ + sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); +} +#endif + +#endif + +/* + * used to submit our private bio + */ +static inline void drbd_generic_make_request(struct drbd_conf *mdev, + int fault_type, struct bio *bio) +{ + __release(local); + if (!bio->bi_bdev) { + printk(KERN_ERR "drbd%d: drbd_generic_make_request: " + "bio->bi_bdev == NULL\n", + mdev_to_minor(mdev)); + dump_stack(); + bio_endio(bio, -ENODEV); + return; + } + + if (FAULT_ACTIVE(mdev, fault_type)) + bio_endio(bio, -EIO); + else + generic_make_request(bio); +} + +static inline void drbd_plug_device(struct drbd_conf *mdev) +{ + struct request_queue *q; + q = bdev_get_queue(mdev->this_bdev); + + spin_lock_irq(q->queue_lock); + +/* XXX the check on !blk_queue_plugged is redundant, + * implicitly checked in blk_plug_device */ + + if (!blk_queue_plugged(q)) { + blk_plug_device(q); + del_timer(&q->unplug_timer); + /* unplugging should not happen automatically... */ + } + spin_unlock_irq(q->queue_lock); +} + +#ifdef DEFINE_SOCK_CREATE_KERN +#define sock_create_kern sock_create +#endif + +#ifdef USE_KMEM_CACHE_S +#define kmem_cache kmem_cache_s +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) +static inline void drbd_unregister_blkdev(unsigned int major, const char *name) +{ + int ret = unregister_blkdev(major,name); + if (ret) + printk(KERN_ERR "drbd: unregister of device failed\n"); +} +#else +#define drbd_unregister_blkdev unregister_blkdev +#endif + +#ifdef NEED_BACKPORT_OF_ATOMIC_ADD + +#if defined(__x86_64__) + +static __inline__ int atomic_add_return(int i, atomic_t *v) +{ + int __i = i; + __asm__ __volatile__( + LOCK_PREFIX "xaddl %0, %1;" + :"=r"(i) + :"m"(v->counter), "0"(i)); + return i + __i; +} + +static __inline__ int atomic_sub_return(int i, atomic_t *v) +{ + return atomic_add_return(-i,v); +} + +#define atomic_inc_return(v) (atomic_add_return(1,v)) +#define atomic_dec_return(v) (atomic_sub_return(1,v)) + +#elif defined(__i386__) || defined(__arch_um__) + +static __inline__ int atomic_add_return(int i, atomic_t *v) +{ + int __i; +#ifdef CONFIG_M386 + unsigned long flags; + if(unlikely(boot_cpu_data.x86==3)) + goto no_xadd; +#endif + /* Modern 486+ processor */ + __i = i; + __asm__ __volatile__( + LOCK_PREFIX "xaddl %0, %1;" + :"=r"(i) + :"m"(v->counter), "0"(i)); + return i + __i; + +#ifdef CONFIG_M386 +no_xadd: /* Legacy 386 processor */ + local_irq_save(flags); + __i = atomic_read(v); + atomic_set(v, i + __i); + local_irq_restore(flags); + return i + __i; +#endif +} + +static __inline__ int atomic_sub_return(int i, atomic_t *v) +{ + return atomic_add_return(-i,v); +} + +#define atomic_inc_return(v) (atomic_add_return(1,v)) +#define atomic_dec_return(v) (atomic_sub_return(1,v)) + +#else +# error "You need to copy/past atomic_inc_return()/atomic_dec_return() here" +# error "for your architecture. (Hint: Kernels after 2.6.10 have those" +# error "by default! Using a later kernel might be less effort!)" +#endif + +#endif + +#if !defined(CRYPTO_ALG_ASYNC) +/* With Linux-2.6.19 the crypto API changed! */ +/* This is not a generic backport of the new api, it just implements + the corner case of "hmac(xxx)". */ + +#define CRYPTO_ALG_ASYNC 4711 +#define CRYPTO_ALG_TYPE_HASH CRYPTO_ALG_TYPE_DIGEST + +struct crypto_hash { + struct crypto_tfm *base; + const u8 *key; + int keylen; +}; + +struct hash_desc { + struct crypto_hash *tfm; + u32 flags; +}; + +static inline struct crypto_hash * +crypto_alloc_hash(char *alg_name, u32 type, u32 mask) +{ + struct crypto_hash *ch; + char *closing_bracket; + + // "hmac(xxx)" is in alg_name we need that xxx. + closing_bracket = strchr(alg_name,')'); + if(!closing_bracket) { + ch = kmalloc(sizeof(struct crypto_hash),GFP_KERNEL); + if(!ch) return ERR_PTR(-ENOMEM); + ch->base = crypto_alloc_tfm(alg_name, 0); + if (ch->base == NULL) { + kfree(ch); + return ERR_PTR(-ENOMEM); + } + return ch; + } + if(closing_bracket-alg_name < 6) return ERR_PTR(-ENOENT); + + ch = kmalloc(sizeof(struct crypto_hash),GFP_KERNEL); + if(!ch) return ERR_PTR(-ENOMEM); + + *closing_bracket = 0; + ch->base = crypto_alloc_tfm(alg_name + 5, 0); + *closing_bracket = ')'; + + if (ch->base == NULL) { + kfree(ch); + return ERR_PTR(-ENOMEM); + } + + return ch; +} + +static inline int +crypto_hash_setkey(struct crypto_hash *hash,const u8 *key,unsigned int keylen) +{ + hash->key = key; + hash->keylen = keylen; + + return 0; +} + +static inline int +crypto_hash_digest(struct hash_desc *desc, struct scatterlist *sg, + unsigned int nbytes, u8 *out) +{ + + crypto_hmac(desc->tfm->base, (u8*)desc->tfm->key, + &desc->tfm->keylen, sg, 1 /* ! */ , out); + /* ! this is not generic. Would need to convert nbytes -> nsg */ + + return 0; +} + +static inline void crypto_free_hash(struct crypto_hash *tfm) +{ + if (!tfm) return; + crypto_free_tfm(tfm->base); + kfree(tfm); +} + +static inline unsigned int crypto_hash_digestsize(struct crypto_hash *tfm) +{ + return crypto_tfm_alg_digestsize(tfm->base); +} + +static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm) +{ + return tfm->base; +} + +static inline int crypto_hash_init(struct hash_desc *desc) +{ + crypto_digest_init(desc->tfm->base); + return 0; +} + +static inline int crypto_hash_update(struct hash_desc *desc, + struct scatterlist *sg, + unsigned int nbytes) +{ + crypto_digest_update(desc->tfm->base,sg,1 /* ! */ ); + /* ! this is not generic. Would need to convert nbytes -> nsg */ + + return 0; +} + +static inline int crypto_hash_final(struct hash_desc *desc, u8 *out) +{ + crypto_digest_final(desc->tfm->base, out); + return 0; +} + +#endif + +#ifdef NEED_BACKPORT_OF_KZALLOC +static inline void *kzalloc(size_t size, int flags) +{ + void *rv = kmalloc(size,flags); + if(rv) memset(rv,0,size); + + return rv; +} +#endif + + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) +#define __bitmap_parse(BUF, BUFLEN, ISUSR, MASKP, NMASK) \ + backport_bitmap_parse(BUF, BUFLEN, ISUSR, MASKP, NMASK) + +#define CHUNKSZ 32 +#define nbits_to_hold_value(val) fls(val) +#define unhex(c) (isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10)) + +static inline int backport_bitmap_parse(const char *buf, unsigned int buflen, + int is_user, unsigned long *maskp, + int nmaskbits) +{ + int c, old_c, totaldigits, ndigits, nchunks, nbits; + u32 chunk; + const char __user *ubuf = buf; + + bitmap_zero(maskp, nmaskbits); + + nchunks = nbits = totaldigits = c = 0; + do { + chunk = ndigits = 0; + + /* Get the next chunk of the bitmap */ + while (buflen) { + old_c = c; + if (is_user) { + if (__get_user(c, ubuf++)) + return -EFAULT; + } + else + c = *buf++; + buflen--; + if (isspace(c)) + continue; + + /* + * If the last character was a space and the current + * character isn't '\0', we've got embedded whitespace. + * This is a no-no, so throw an error. + */ + if (totaldigits && c && isspace(old_c)) + return -EINVAL; + + /* A '\0' or a ',' signal the end of the chunk */ + if (c == '\0' || c == ',') + break; + + if (!isxdigit(c)) + return -EINVAL; + + /* + * Make sure there are at least 4 free bits in 'chunk'. + * If not, this hexdigit will overflow 'chunk', so + * throw an error. + */ + if (chunk & ~((1UL << (CHUNKSZ - 4)) - 1)) + return -EOVERFLOW; + + chunk = (chunk << 4) | unhex(c); + ndigits++; totaldigits++; + } + if (ndigits == 0) + return -EINVAL; + if (nchunks == 0 && chunk == 0) + continue; + + bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits); + *maskp |= chunk; + nchunks++; + nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ; + if (nbits > nmaskbits) + return -EOVERFLOW; + } while (buflen && c == ','); + + return 0; +} +#endif + +#ifndef __CHECKER__ +# undef __cond_lock +# define __cond_lock(x,c) (c) +#endif + +#ifndef KERNEL_HAS_GFP_T +#define KERNEL_HAS_GFP_T +typedef unsigned gfp_t; +#endif --- linux-2.6.28.orig/ubuntu/drbd/drbd_req.c +++ linux-2.6.28/ubuntu/drbd/drbd_req.c @@ -0,0 +1,1274 @@ +/* +-*- linux-c -*- + drbd_req.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include + +#include +#include +#include "drbd_int.h" +#include "drbd_req.h" + +/* outside of the ifdef + * because of the _print_rq_state(,FIXME) in barrier_acked */ +STATIC void _print_rq_state(struct drbd_request *req, const char *txt) +{ + const unsigned long s = req->rq_state; + struct drbd_conf *mdev = req->mdev; + const int rw = (req->master_bio == NULL || + bio_data_dir(req->master_bio) == WRITE) ? + 'W' : 'R'; + + INFO("%s %p %c L%c%c%cN%c%c%c%c%c %u (%llus +%u) %s\n", + txt, req, rw, + s & RQ_LOCAL_PENDING ? 'p' : '-', + s & RQ_LOCAL_COMPLETED ? 'c' : '-', + s & RQ_LOCAL_OK ? 'o' : '-', + s & RQ_NET_PENDING ? 'p' : '-', + s & RQ_NET_QUEUED ? 'q' : '-', + s & RQ_NET_SENT ? 's' : '-', + s & RQ_NET_DONE ? 'd' : '-', + s & RQ_NET_OK ? 'o' : '-', + req->epoch, + (unsigned long long)req->sector, + req->size, + conns_to_name(mdev->state.conn)); +} + +/* #define VERBOSE_REQUEST_CODE */ +#if defined(VERBOSE_REQUEST_CODE) || defined(ENABLE_DYNAMIC_TRACE) +STATIC void _print_req_mod(struct drbd_request *req, enum drbd_req_event what) +{ + struct drbd_conf *mdev = req->mdev; + const int rw = (req->master_bio == NULL || + bio_data_dir(req->master_bio) == WRITE) ? + 'W' : 'R'; + + static const char *rq_event_names[] = { + [created] = "created", + [to_be_send] = "to_be_send", + [to_be_submitted] = "to_be_submitted", + [queue_for_net_write] = "queue_for_net_write", + [queue_for_net_read] = "queue_for_net_read", + [send_canceled] = "send_canceled", + [send_failed] = "send_failed", + [handed_over_to_network] = "handed_over_to_network", + [connection_lost_while_pending] = + "connection_lost_while_pending", + [recv_acked_by_peer] = "recv_acked_by_peer", + [write_acked_by_peer] = "write_acked_by_peer", + [neg_acked] = "neg_acked", + [conflict_discarded_by_peer] = "conflict_discarded_by_peer", + [barrier_acked] = "barrier_acked", + [data_received] = "data_received", + [read_completed_with_error] = "read_completed_with_error", + [write_completed_with_error] = "write_completed_with_error", + [completed_ok] = "completed_ok", + }; + + INFO("_req_mod(%p %c ,%s)\n", req, rw, rq_event_names[what]); +} + +# ifdef ENABLE_DYNAMIC_TRACE +# define print_rq_state(R, T) \ + MTRACE(TraceTypeRq, TraceLvlMetrics, _print_rq_state(R, T);) +# define print_req_mod(T, W) \ + MTRACE(TraceTypeRq, TraceLvlMetrics, _print_req_mod(T, W);) +# else +# define print_rq_state(R, T) _print_rq_state(R, T) +# define print_req_mod(T, W) _print_req_mod(T, W) +# endif + +#else +#define print_rq_state(R, T) +#define print_req_mod(T, W) +#endif + +/* We only support diskstats for 2.6.16 and up. + * see also commit commit a362357b6cd62643d4dda3b152639303d78473da + * Author: Jens Axboe + * Date: Tue Nov 1 09:26:16 2005 +0100 + * [BLOCK] Unify the seperate read/write io stat fields into arrays */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) +#define _drbd_start_io_acct(...) do {} while (0) +#define _drbd_end_io_acct(...) do {} while (0) +#else + +/* Update disk stats at start of I/O request */ +static inline void _drbd_start_io_acct(struct drbd_conf *mdev, struct drbd_request *req, struct bio *bio) +{ + const int rw = bio_data_dir(bio); + + MUST_HOLD(&mdev->req_lock) + __disk_stat_inc(mdev->vdisk, ios[rw]); + __disk_stat_add(mdev->vdisk, sectors[rw], bio_sectors(bio)); + disk_round_stats(mdev->vdisk); + mdev->vdisk->in_flight++; +} + +/* Update disk stats when completing request upwards */ +static inline void _drbd_end_io_acct(struct drbd_conf *mdev, struct drbd_request *req) +{ + int rw = bio_data_dir(req->master_bio); + unsigned long duration = jiffies - req->start_time; + + MUST_HOLD(&mdev->req_lock) + __disk_stat_add(mdev->vdisk, ticks[rw], duration); + disk_round_stats(mdev->vdisk); + mdev->vdisk->in_flight--; +} + +#endif + +static void _req_is_done(struct drbd_conf *mdev, struct drbd_request *req, const int rw) +{ + const unsigned long s = req->rq_state; + /* if it was a write, we may have to set the corresponding + * bit(s) out-of-sync first. If it had a local part, we need to + * release the reference to the activity log. */ + if (rw == WRITE) { + /* remove it from the transfer log. + * well, only if it had been there in the first + * place... if it had not (local only or conflicting + * and never sent), it should still be "empty" as + * initialised in drbd_req_new(), so we can list_del() it + * here unconditionally */ + list_del(&req->tl_requests); + /* Set out-of-sync unless both OK flags are set + * (local only or remote failed). + * Other places where we set out-of-sync: + * READ with local io-error */ + if (!(s & RQ_NET_OK) || !(s & RQ_LOCAL_OK)) + drbd_set_out_of_sync(mdev, req->sector, req->size); + + if ((s & RQ_NET_OK) && (s & RQ_LOCAL_OK) && (s & RQ_NET_SIS)) + drbd_set_in_sync(mdev, req->sector, req->size); + + /* one might be tempted to move the drbd_al_complete_io + * to the local io completion callback drbd_endio_pri. + * but, if this was a mirror write, we may only + * drbd_al_complete_io after this is RQ_NET_DONE, + * otherwise the extent could be dropped from the al + * before it has actually been written on the peer. + * if we crash before our peer knows about the request, + * but after the extent has been dropped from the al, + * we would forget to resync the corresponding extent. + */ + if (s & RQ_LOCAL_MASK) { + if (inc_local_if_state(mdev, Failed)) { + drbd_al_complete_io(mdev, req->sector); + dec_local(mdev); + } else { + DRBD_WARN("Should have called drbd_al_complete_io(, %llu), " + "but my Disk seems to have failed :(\n", + (unsigned long long) req->sector); + } + } + } + + /* if it was a local io error, we want to notify our + * peer about that, and see if we need to + * detach the disk and stuff. + * to avoid allocating some special work + * struct, reuse the request. */ + + /* THINK + * why do we do this not when we detect the error, + * but delay it until it is "done", i.e. possibly + * until the next barrier ack? */ + + if (rw == WRITE && + (( s & RQ_LOCAL_MASK) && !(s & RQ_LOCAL_OK))) { + if (!(req->w.list.next == LIST_POISON1 || + list_empty(&req->w.list))) { + /* DEBUG ASSERT only; if this triggers, we + * probably corrupt the worker list here */ + DUMPP(req->w.list.next); + DUMPP(req->w.list.prev); + } + req->w.cb = w_io_error; + drbd_queue_work(&mdev->data.work, &req->w); + /* drbd_req_free() is done in w_io_error */ + } else { + drbd_req_free(req); + } +} + +static void queue_barrier(struct drbd_conf *mdev) +{ + struct drbd_barrier *b; + + /* We are within the req_lock. Once we queued the barrier for sending, + * we set the CREATE_BARRIER bit. It is cleared as soon as a new + * barrier/epoch object is added. This is the only place this bit is + * set. It indicates that the barrier for this epoch is already queued, + * and no new epoch has been created yet. */ + if (test_bit(CREATE_BARRIER, &mdev->flags)) + return; + + b = mdev->newest_barrier; + b->w.cb = w_send_barrier; + /* inc_ap_pending done here, so we won't + * get imbalanced on connection loss. + * dec_ap_pending will be done in got_BarrierAck + * or (on connection loss) in tl_clear. */ + inc_ap_pending(mdev); + drbd_queue_work(&mdev->data.work, &b->w); + set_bit(CREATE_BARRIER, &mdev->flags); +} + +static void _about_to_complete_local_write(struct drbd_conf *mdev, + struct drbd_request *req) +{ + const unsigned long s = req->rq_state; + struct drbd_request *i; + struct Tl_epoch_entry *e; + struct hlist_node *n; + struct hlist_head *slot; + + /* before we can signal completion to the upper layers, + * we may need to close the current epoch */ + if (mdev->state.conn >= Connected && + req->epoch == mdev->newest_barrier->br_number) + queue_barrier(mdev); + + /* we need to do the conflict detection stuff, + * if we have the ee_hash (two_primaries) and + * this has been on the network */ + if ((s & RQ_NET_DONE) && mdev->ee_hash != NULL) { + const sector_t sector = req->sector; + const int size = req->size; + + /* ASSERT: + * there must be no conflicting requests, since + * they must have been failed on the spot */ +#define OVERLAPS overlaps(sector, size, i->sector, i->size) + slot = tl_hash_slot(mdev, sector); + hlist_for_each_entry(i, n, slot, colision) { + if (OVERLAPS) { + ALERT("LOGIC BUG: completed: %p %llus +%u; " + "other: %p %llus +%u\n", + req, (unsigned long long)sector, size, + i, (unsigned long long)i->sector, i->size); + } + } + + /* maybe "wake" those conflicting epoch entries + * that wait for this request to finish. + * + * currently, there can be only _one_ such ee + * (well, or some more, which would be pending + * DiscardAck not yet sent by the asender...), + * since we block the receiver thread upon the + * first conflict detection, which will wait on + * misc_wait. maybe we want to assert that? + * + * anyways, if we found one, + * we just have to do a wake_up. */ +#undef OVERLAPS +#define OVERLAPS overlaps(sector, size, e->sector, e->size) + slot = ee_hash_slot(mdev, req->sector); + hlist_for_each_entry(e, n, slot, colision) { + if (OVERLAPS) { + wake_up(&mdev->misc_wait); + break; + } + } + } +#undef OVERLAPS +} + +static void _complete_master_bio(struct drbd_conf *mdev, + struct drbd_request *req, int error) +{ + dump_bio(mdev, req->master_bio, 1); + bio_endio(req->master_bio, error); + req->master_bio = NULL; + dec_ap_bio(mdev); +} + +void _req_may_be_done(struct drbd_request *req, int error) +{ + const unsigned long s = req->rq_state; + struct drbd_conf *mdev = req->mdev; + int rw; + + print_rq_state(req, "_req_may_be_done"); + MUST_HOLD(&mdev->req_lock) + + /* we must not complete the master bio, while it is + * still being processed by _drbd_send_zc_bio (drbd_send_dblock) + * not yet acknowledged by the peer + * not yet completed by the local io subsystem + * these flags may get cleared in any order by + * the worker, + * the receiver, + * the bio_endio completion callbacks. + */ + if (s & RQ_NET_QUEUED) + return; + if (s & RQ_NET_PENDING) + return; + if (s & RQ_LOCAL_PENDING) + return; + + if (req->master_bio) { + /* this is data_received (remote read) + * or protocol C WriteAck + * or protocol B RecvAck + * or protocol A "handed_over_to_network" (SendAck) + * or canceled or failed, + * or killed from the transfer log due to connection loss. + */ + + /* + * figure out whether to report success or failure. + * + * report success when at least one of the operations suceeded. + * or, to put the other way, + * only report failure, when both operations failed. + * + * what to do about the failures is handled elsewhere. + * what we need to do here is just: complete the master_bio. + */ + int ok = (s & RQ_LOCAL_OK) || (s & RQ_NET_OK); + rw = bio_data_dir(req->master_bio); + + /* remove the request from the conflict detection + * respective block_id verification hash */ + if (!hlist_unhashed(&req->colision)) + hlist_del(&req->colision); + else + D_ASSERT((s & RQ_NET_MASK) == 0); + + /* for writes we need to do some extra housekeeping */ + if (rw == WRITE) + _about_to_complete_local_write(mdev, req); + + /* FIXME not yet implemented... + * in case we got "suspended" (on_disconnect: freeze io) + * we may not yet complete the request... + * though, this is probably best handled elsewhere by not + * walking the transfer log until "unfreeze", so we won't end + * up here anyways during the freeze ... + * then again, if it is a READ, it is not in the TL at all. + * is it still leagal to complete a READ during freeze? */ + + /* Update disk stats */ + _drbd_end_io_acct(mdev, req); + + _complete_master_bio(mdev,req, + ok ? 0 : ( error ? error : -EIO ) ); + } else { + /* only WRITE requests can end up here without a master_bio */ + rw = WRITE; + } + + if ((s & RQ_NET_MASK) == 0 || (s & RQ_NET_DONE)) { + /* this is disconnected (local only) operation, + * or protocol C WriteAck, + * or protocol A or B BarrierAck, + * or killed from the transfer log due to connection loss. */ + _req_is_done(mdev, req, rw); + } + /* else: network part and not DONE yet. that is + * protocol A or B, barrier ack still pending... */ +} + +/* + * checks whether there was an overlapping request + * or ee already registered. + * + * if so, return 1, in which case this request is completed on the spot, + * without ever being submitted or send. + * + * return 0 if it is ok to submit this request. + * + * NOTE: + * paranoia: assume something above us is broken, and issues different write + * requests for the same block simultaneously... + * + * To ensure these won't be reordered differently on both nodes, resulting in + * diverging data sets, we discard the later one(s). Not that this is supposed + * to happen, but this is the rationale why we also have to check for + * conflicting requests with local origin, and why we have to do so regardless + * of whether we allowed multiple primaries. + * + * BTW, in case we only have one primary, the ee_hash is empty anyways, and the + * second hlist_for_each_entry becomes a noop. This is even simpler than to + * grab a reference on the net_conf, and check for the two_primaries flag... + */ +STATIC int _req_conflicts(struct drbd_request *req) +{ + struct drbd_conf *mdev = req->mdev; + const sector_t sector = req->sector; + const int size = req->size; + struct drbd_request *i; + struct Tl_epoch_entry *e; + struct hlist_node *n; + struct hlist_head *slot; + + MUST_HOLD(&mdev->req_lock); + D_ASSERT(hlist_unhashed(&req->colision)); + + /* FIXME should this inc_net/dec_net + * rather be done in drbd_make_request_common? */ + if (!inc_net(mdev)) + return 0; + + /* BUG_ON */ + ERR_IF (mdev->tl_hash_s == 0) + goto out_no_conflict; + BUG_ON(mdev->tl_hash == NULL); + +#define OVERLAPS overlaps(i->sector, i->size, sector, size) + slot = tl_hash_slot(mdev, sector); + hlist_for_each_entry(i, n, slot, colision) { + if (OVERLAPS) { + ALERT("%s[%u] Concurrent local write detected! " + "[DISCARD L] new: %llus +%u; " + "pending: %llus +%u\n", + current->comm, current->pid, + (unsigned long long)sector, size, + (unsigned long long)i->sector, i->size); + goto out_conflict; + } + } + + if (mdev->ee_hash_s) { + /* now, check for overlapping requests with remote origin */ + BUG_ON(mdev->ee_hash == NULL); +#undef OVERLAPS +#define OVERLAPS overlaps(e->sector, e->size, sector, size) + slot = ee_hash_slot(mdev, sector); + hlist_for_each_entry(e, n, slot, colision) { + if (OVERLAPS) { + ALERT("%s[%u] Concurrent remote write detected!" + " [DISCARD L] new: %llus +%u; " + "pending: %llus +%u\n", + current->comm, current->pid, + (unsigned long long)sector, size, + (unsigned long long)e->sector, e->size); + goto out_conflict; + } + } + } +#undef OVERLAPS + +out_no_conflict: + /* this is like it should be, and what we expected. + * our users do behave after all... */ + dec_net(mdev); + return 0; + +out_conflict: + dec_net(mdev); + return 1; +} + +/* obviously this could be coded as many single functions + * instead of one huge switch, + * or by putting the code directly in the respective locations + * (as it has been before). + * + * but having it this way + * enforces that it is all in this one place, where it is easier to audit, + * it makes it obvious that whatever "event" "happens" to a request should + * happen "atomically" within the req_lock, + * and it enforces that we have to think in a very structured manner + * about the "events" that may happen to a request during its life time ... + * + * Though I think it is likely that we break this again into many + * static inline void _req_mod_ ## what (req) ... + */ +void _req_mod(struct drbd_request *req, enum drbd_req_event what, int error) +{ + struct drbd_conf *mdev = req->mdev; + MUST_HOLD(&mdev->req_lock); + + if (error && (bio_rw(req->master_bio) != READA)) + ERR("got an _req_mod() errno of %d\n", error); + + print_req_mod(req, what); + + switch (what) { + default: + ERR("LOGIC BUG in %s:%u\n", __FILE__ , __LINE__ ); + return; + + /* does not happen... + * initialization done in drbd_req_new + case created: + break; + */ + + case to_be_send: /* via network */ + /* reached via drbd_make_request_common + * and from FIXME w_read_retry_remote */ + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + req->rq_state |= RQ_NET_PENDING; + inc_ap_pending(mdev); + break; + + case to_be_submitted: /* locally */ + /* reached via drbd_make_request_common */ + D_ASSERT(!(req->rq_state & RQ_LOCAL_MASK)); + req->rq_state |= RQ_LOCAL_PENDING; + break; + + /* FIXME these *_completed_* are basically the same. + * can probably be merged with some if (what == xy) */ + + case completed_ok: + if (bio_data_dir(req->private_bio) == WRITE) + mdev->writ_cnt += req->size>>9; + else + mdev->read_cnt += req->size>>9; + + bio_put(req->private_bio); + req->private_bio = NULL; + + req->rq_state |= (RQ_LOCAL_COMPLETED|RQ_LOCAL_OK); + req->rq_state &= ~RQ_LOCAL_PENDING; + + _req_may_be_done(req, error); + dec_local(mdev); + break; + + case write_completed_with_error: + req->rq_state |= RQ_LOCAL_COMPLETED; + req->rq_state &= ~RQ_LOCAL_PENDING; + + bio_put(req->private_bio); + req->private_bio = NULL; + ALERT("Local WRITE failed sec=%llus size=%u\n", + (unsigned long long)req->sector, req->size); + /* and now: check how to handle local io error. + * FIXME see comment below in read_completed_with_error */ + __drbd_chk_io_error(mdev, FALSE); + _req_may_be_done(req, error); + dec_local(mdev); + break; + + case read_completed_with_error: + if (bio_rw(req->master_bio) != READA) + drbd_set_out_of_sync(mdev, req->sector, req->size); + + req->rq_state |= RQ_LOCAL_COMPLETED; + req->rq_state &= ~RQ_LOCAL_PENDING; + + bio_put(req->private_bio); + req->private_bio = NULL; + if (bio_rw(req->master_bio) == READA) { + /* it is legal to fail READA */ + _req_may_be_done(req, error); + dec_local(mdev); + break; + } + /* else */ + ALERT("Local READ failed sec=%llus size=%u\n", + (unsigned long long)req->sector, req->size); + /* _req_mod(req,to_be_send); oops, recursion in static inline */ + D_ASSERT(!(req->rq_state & RQ_NET_MASK)); + req->rq_state |= RQ_NET_PENDING; + inc_ap_pending(mdev); + + /* and now: check how to handle local io error. + * + * FIXME we should not handle WRITE and READ io errors + * the same. When we retry the READ, and then write + * the answer, that might suceed because modern drives + * would relocate the sectors. We'd need to keep our + * private bio then, and round the offset and size so + * we get back enough data to be able to clear the bits again. + */ + __drbd_chk_io_error(mdev, FALSE); + dec_local(mdev); + /* NOTE: if we have no connection, + * or know the peer has no good data either, + * then we don't actually need to "queue_for_net_read", + * but we do so anyways, since the drbd_io_error() + * and the potential state change to "Diskless" + * needs to be done from process context */ + + /* fall through: _req_mod(req,queue_for_net_read); */ + + case queue_for_net_read: + /* READ or READA, and + * no local disk, + * or target area marked as invalid, + * or just got an io-error. */ + /* from drbd_make_request_common + * or from bio_endio during read io-error recovery */ + + /* so we can verify the handle in the answer packet + * corresponding hlist_del is in _req_may_be_done() */ + hlist_add_head(&req->colision, ar_hash_slot(mdev, req->sector)); + + set_bit(UNPLUG_REMOTE, &mdev->flags); /* why? */ + + D_ASSERT(req->rq_state & RQ_NET_PENDING); + req->rq_state |= RQ_NET_QUEUED; + req->w.cb = (req->rq_state & RQ_LOCAL_MASK) + ? w_read_retry_remote + : w_send_read_req; + drbd_queue_work(&mdev->data.work, &req->w); + break; + + case queue_for_net_write: + /* assert something? */ + /* from drbd_make_request_common only */ + + hlist_add_head(&req->colision, tl_hash_slot(mdev, req->sector)); + /* corresponding hlist_del is in _req_may_be_done() */ + + /* NOTE + * In case the req ended up on the transfer log before being + * queued on the worker, it could lead to this request being + * missed during cleanup after connection loss. + * So we have to do both operations here, + * within the same lock that protects the transfer log. + * + * _req_add_to_epoch(req); this has to be after the + * _maybe_start_new_epoch(req); which happened in + * drbd_make_request_common, because we now may set the bit + * again ourselves to close the current epoch. + * + * Add req to the (now) current epoch (barrier). */ + + /* see drbd_make_request_common, + * just after it grabs the req_lock */ + D_ASSERT(test_bit(CREATE_BARRIER, &mdev->flags) == 0); + + req->epoch = mdev->newest_barrier->br_number; + list_add_tail(&req->tl_requests, + &mdev->newest_barrier->requests); + + /* increment size of current epoch */ + mdev->newest_barrier->n_req++; + + /* queue work item to send data */ + D_ASSERT(req->rq_state & RQ_NET_PENDING); + req->rq_state |= RQ_NET_QUEUED; + req->w.cb = w_send_dblock; + drbd_queue_work(&mdev->data.work, &req->w); + + /* close the epoch, in case it outgrew the limit */ + if (mdev->newest_barrier->n_req >= mdev->net_conf->max_epoch_size) + queue_barrier(mdev); + + break; + + /* FIXME + * to implement freeze-io, + * we may not finish the request just yet. + */ + case send_canceled: + /* may be a write, may be a remote read */ + if (req->rq_state & RQ_NET_PENDING) dec_ap_pending(mdev); + req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); + /* fall through */ + case send_failed: + /* real cleanup will be done from tl_clear. just update flags + * so it is no longer marked as on the worker queue */ + req->rq_state &= ~RQ_NET_QUEUED; + /* if we did it right, tl_clear should be scheduled only after + * this, so this should not be necessary! */ + _req_may_be_done(req, error); + break; + + case handed_over_to_network: + /* assert something? */ + if ( bio_data_dir(req->master_bio) == WRITE && + mdev->net_conf->wire_protocol == DRBD_PROT_A ) { + /* this is what is dangerous about protocol A: + * pretend it was sucessfully written on the peer. + * FIXME in case we get a local io-error in + * protocol != C, we might want to defer comletion + * until we get the barrier ack, and send a NegAck + * in case the other node had an io-error, too... + * That way we would at least not report "success" + * if it was not written at all. */ + if (req->rq_state & RQ_NET_PENDING) { + dec_ap_pending(mdev); + req->rq_state &= ~RQ_NET_PENDING; + req->rq_state |= RQ_NET_OK; + } /* else: neg-ack was faster... */ + /* it is still not yet RQ_NET_DONE until the + * corresponding epoch barrier got acked as well, + * so we know what to dirty on connection loss */ + } + req->rq_state &= ~RQ_NET_QUEUED; + req->rq_state |= RQ_NET_SENT; + /* because _drbd_send_zc_bio could sleep, and may want to + * dereference the bio even after the "write_acked_by_peer" and + * "completed_ok" events came in, once we return from + * _drbd_send_zc_bio (drbd_send_dblock), we have to check + * whether it is done already, and end it. */ + _req_may_be_done(req, error); + break; + + case connection_lost_while_pending: + /* transfer log cleanup after connection loss */ + /* assert something? */ + if (req->rq_state & RQ_NET_PENDING) + dec_ap_pending(mdev); + req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); + req->rq_state |= RQ_NET_DONE; + /* if it is still queued, we may not complete it here. + * it will be canceled soon. + * FIXME we should change the code so this can not happen. */ + if (!(req->rq_state & RQ_NET_QUEUED)) + _req_may_be_done(req, error); + break; + + case write_acked_by_peer_and_sis: + req->rq_state |= RQ_NET_SIS; + case conflict_discarded_by_peer: + /* for discarded conflicting writes of multiple primarys, + * there is no need to keep anything in the tl, potential + * node crashes are covered by the activity log. */ + req->rq_state |= RQ_NET_DONE; + /* fall through */ + case write_acked_by_peer: + /* protocol C; successfully written on peer. + * Nothing to do here. + * We want to keep the tl in place for all protocols, to cater + * for volatile write-back caches on lower level devices. + * + * A barrier request is expected to have forced all prior + * requests onto stable storage, so completion of a barrier + * request could set NET_DONE right here, and not wait for the + * BarrierAck, but that is an unecessary optimisation. */ + + /* this makes it effectively the same as for: */ + case recv_acked_by_peer: + /* protocol B; pretends to be sucessfully written on peer. + * see also notes above in handed_over_to_network about + * protocol != C */ + req->rq_state |= RQ_NET_OK; + D_ASSERT(req->rq_state & RQ_NET_PENDING); + dec_ap_pending(mdev); + req->rq_state &= ~RQ_NET_PENDING; + _req_may_be_done(req, error); + break; + + case neg_acked: + /* assert something? */ + if (req->rq_state & RQ_NET_PENDING) + dec_ap_pending(mdev); + req->rq_state &= ~(RQ_NET_OK|RQ_NET_PENDING); + /* FIXME THINK! is it DONE now, or is it not? */ + req->rq_state |= RQ_NET_DONE; + _req_may_be_done(req, error); + /* else: done by handed_over_to_network */ + break; + + case barrier_acked: + if (req->rq_state & RQ_NET_PENDING) { + /* barrier came in before all requests have been acked. + * this is bad, because if the connection is lost now, + * we won't be able to clean them up... */ + _print_rq_state(req, + "FIXME (barrier_acked but pending)"); + } + D_ASSERT(req->rq_state & RQ_NET_SENT); + req->rq_state |= RQ_NET_DONE; + _req_may_be_done(req, error); + break; + + case data_received: + D_ASSERT(req->rq_state & RQ_NET_PENDING); + dec_ap_pending(mdev); + req->rq_state &= ~RQ_NET_PENDING; + req->rq_state |= (RQ_NET_OK|RQ_NET_DONE); + _req_may_be_done(req, error); + break; + }; +} + +/* we may do a local read if: + * - we are consistent (of course), + * - or we are generally inconsistent, + * BUT we are still/already IN SYNC for this area. + * since size may be bigger than BM_BLOCK_SIZE, + * we may need to check several bits. + */ +STATIC int drbd_may_do_local_read(struct drbd_conf *mdev, sector_t sector, int size) +{ + unsigned long sbnr, ebnr; + sector_t esector, nr_sectors; + + if (mdev->state.disk == UpToDate) + return 1; + if (mdev->state.disk >= Outdated) + return 0; + if (mdev->state.disk < Inconsistent) + return 0; + /* state.disk == Inconsistent We will have a look at the BitMap */ + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size>>9) -1; + + D_ASSERT(sector < nr_sectors); + D_ASSERT(esector < nr_sectors); + + sbnr = BM_SECT_TO_BIT(sector); + ebnr = BM_SECT_TO_BIT(esector); + + return (0 == drbd_bm_count_bits(mdev, sbnr, ebnr)); +} + +/* + * general note: + * looking at the state (conn, disk, susp, pdsk) outside of the spinlock that + * protects the state changes is inherently racy. + * + * FIXME verify this rationale why we may do so anyways: + * + * I think it "should" be like this: + * as soon as we have a "ap_bio_cnt" reference we may test for "bad" states, + * because the transition from "bad" to "good" states may only happen while no + * application request is on the fly, so once we are positive about a "bad" + * state, we know it won't get better during the lifetime of this request. + * + * In case we think we are ok, but "asynchronously" some interrupt or other + * thread marks some operation as impossible, we are still ok, since we would + * just try anyways, and then see that it does not work there and then. + */ + +STATIC int drbd_make_request_common(struct drbd_conf *mdev, struct bio *bio) +{ + const int rw = bio_rw(bio); + const int size = bio->bi_size; + const sector_t sector = bio->bi_sector; + struct drbd_barrier *b = NULL; + struct drbd_request *req; + int local, remote; + int err = -EIO; + + /* allocate outside of all locks; get a "reference count" (ap_bio_cnt) + * to avoid races with the disconnect/reconnect code. */ + inc_ap_bio(mdev); + req = drbd_req_new(mdev, bio); + if (!req) { + dec_ap_bio(mdev); + /* only pass the error to the upper layers. + * if user cannot handle io errors, thats not our business. */ + ERR("could not kmalloc() req\n"); + bio_endio(bio, -ENOMEM); + return 0; + } + + dump_bio(mdev, bio, 0); + + local = inc_local(mdev); + if (!local) { + bio_put(req->private_bio); /* or we get a bio leak */ + req->private_bio = NULL; + } + if (rw == WRITE) { + remote = 1; + } else { + /* READ || READA */ + if (local) { + if (!drbd_may_do_local_read(mdev, sector, size)) { + /* we could kick the syncer to + * sync this extent asap, wait for + * it, then continue locally. + * Or just issue the request remotely. + */ + /* FIXME + * I think we have a RACE here. We request + * something from the peer, then later some + * write starts ... and finished *before* + * the answer to the read comes in, because + * the ACK for the WRITE goes over + * meta-socket ... + * Maybe we need to properly lock reads + * against the syncer, too. But if we have + * some user issuing writes on an area that + * he has pending reads on, _he_ is really + * broke anyways, and would get "undefined + * results" on _any_ io stack, even just the + * local io stack. + */ + + local = 0; + bio_put(req->private_bio); + req->private_bio = NULL; + dec_local(mdev); + } + } + remote = !local && mdev->state.pdsk >= UpToDate; + } + + /* If we have a disk, but a READA request is mapped to remote, + * we are Primary, Inconsistent, SyncTarget. + * Just fail that READA request right here. + * + * THINK: maybe fail all READA when not local? + * or make this configurable... + * if network is slow, READA won't do any good. + */ + if (rw == READA && mdev->state.disk >= Inconsistent && !local) { + err = -EWOULDBLOCK; + goto fail_and_free_req; + } + + /* For WRITES going to the local disk, grab a reference on the target + * extent. This waits for any resync activity in the corresponding + * resync extent to finish, and, if necessary, pulls in the target + * extent into the activity log, which involves further disk io because + * of transactional on-disk meta data updates. */ + if (rw == WRITE && local) + drbd_al_begin_io(mdev, sector); + + remote = remote && (mdev->state.pdsk == UpToDate || + ( mdev->state.pdsk == Inconsistent && + mdev->state.conn >= Connected ) ); + + if (!(local || remote)) { + ERR("IO ERROR: neither local nor remote disk\n"); + goto fail_and_free_req; + } + + /* For WRITE request, we have to make sure that we have an + * unused_spare_barrier, in case we need to start a new epoch. + * I try to be smart and avoid to pre-allocate always "just in case", + * but there is a race between testing the bit and pointer outside the + * spinlock, and grabbing the spinlock. + * if we lost that race, we retry. */ + if (rw == WRITE && remote && + mdev->unused_spare_barrier == NULL && + test_bit(CREATE_BARRIER, &mdev->flags)) { +allocate_barrier: + b = kmalloc(sizeof(struct drbd_barrier), GFP_NOIO); + if (!b) { + ERR("Failed to alloc barrier.\n"); + err = -ENOMEM; + goto fail_and_free_req; + } + } + + /* GOOD, everything prepared, grab the spin_lock */ + spin_lock_irq(&mdev->req_lock); + + /* FIXME race with drbd_disconnect and tl_clear? */ + if (remote) { + remote = (mdev->state.pdsk == UpToDate || + ( mdev->state.pdsk == Inconsistent && + mdev->state.conn >= Connected ) ); + if (!remote) + DRBD_WARN("lost connection while grabbing the req_lock!\n"); + if (!(local || remote)) { + ERR("IO ERROR: neither local nor remote disk\n"); + spin_unlock_irq(&mdev->req_lock); + goto fail_and_free_req; + } + } + + if (b && mdev->unused_spare_barrier == NULL) { + mdev->unused_spare_barrier = b; + b = NULL; + } + if (rw == WRITE && remote && + mdev->unused_spare_barrier == NULL && + test_bit(CREATE_BARRIER, &mdev->flags)) { + /* someone closed the current epoch + * while we were grabbing the spinlock */ + spin_unlock_irq(&mdev->req_lock); + goto allocate_barrier; + } + + + /* Update disk stats */ + _drbd_start_io_acct(mdev, req, bio); + + /* _maybe_start_new_epoch(mdev); + * If we need to generate a write barrier packet, we have to add the + * new epoch (barrier) object, and queue the barrier packet for sending, + * and queue the req's data after it _within the same lock_, otherwise + * we have race conditions were the reorder domains could be mixed up. + * + * Even read requests may start a new epoch and queue the corresponding + * barrier packet. To get the write ordering right, we only have to + * make sure that, if this is a write request and it triggered a + * barrier packet, this request is queued within the same spinlock. */ + if (remote && mdev->unused_spare_barrier && + test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) { + _tl_add_barrier(mdev, mdev->unused_spare_barrier); + mdev->unused_spare_barrier = NULL; + } else { + D_ASSERT(!(remote && rw == WRITE && + test_bit(CREATE_BARRIER, &mdev->flags))); + } + + /* NOTE + * Actually, 'local' may be wrong here already, since we may have failed + * to write to the meta data, and may become wrong anytime because of + * local io-error for some other request, which would lead to us + * "detaching" the local disk. + * + * 'remote' may become wrong any time because the network could fail. + * + * This is a harmless race condition, though, since it is handled + * correctly at the appropriate places; so it just deferres the failure + * of the respective operation. + */ + + /* mark them early for readability. + * this just sets some state flags. */ + if (remote) + _req_mod(req, to_be_send, 0); + if (local) + _req_mod(req, to_be_submitted, 0); + + /* check this request on the colison detection hash tables. + * if we have a conflict, just complete it here. + * THINK do we want to check reads, too? (I don't think so...) */ + if (rw == WRITE && _req_conflicts(req)) { + /* this is a conflicting request. + * even though it may have been only _partially_ + * overlapping with one of the currently pending requests, + * without even submitting or sending it, we will + * pretend that it was successfully served right now. + */ + if (local) { + bio_put(req->private_bio); + req->private_bio = NULL; + drbd_al_complete_io(mdev, req->sector); + dec_local(mdev); + local = 0; + } + if (remote) + dec_ap_pending(mdev); + _drbd_end_io_acct(mdev, req); + /* THINK: do we want to fail it (-EIO), or pretend success? */ + bio_endio(req->master_bio, 0); + req->master_bio = NULL; + dec_ap_bio(mdev); + drbd_req_free(req); + remote = 0; + } + + /* NOTE remote first: to get the concurrent write detection right, + * we must register the request before start of local IO. */ + if (remote) { + /* either WRITE and Connected, + * or READ, and no local disk, + * or READ, but not in sync. + */ + if (rw == WRITE) + _req_mod(req, queue_for_net_write, 0); + else + _req_mod(req, queue_for_net_read, 0); + } + spin_unlock_irq(&mdev->req_lock); + kfree(b); /* if someone else has beaten us to it... */ + + if (local) { + req->private_bio->bi_bdev = mdev->bc->backing_bdev; + + dump_internal_bio("Pri", mdev, req->private_bio, 0); + + if (FAULT_ACTIVE(mdev, rw==WRITE ? DRBD_FAULT_DT_WR : + (rw==READ ? DRBD_FAULT_DT_RD : + DRBD_FAULT_DT_RA) )) + bio_endio(req->private_bio, -EIO); + else + generic_make_request(req->private_bio); + } + + /* we need to plug ALWAYS since we possibly need to kick lo_dev. + * we plug after submit, so we won't miss an unplug event */ + drbd_plug_device(mdev); + + return 0; + +fail_and_free_req: + kfree(b); + bio_endio(bio, err); + drbd_req_free(req); + return 0; +} + +/* helper function for drbd_make_request + * if we can determine just by the mdev (state) that this request will fail, + * return 1 + * otherwise return 0 + */ +static int drbd_fail_request_early(struct drbd_conf *mdev, int is_write) +{ + /* Unconfigured */ + if (mdev->state.conn == Disconnecting && + mdev->state.disk == Diskless) + return 1; + + if (mdev->state.role != Primary && + ( !allow_oos || is_write) ) { + if (DRBD_ratelimit(5*HZ, 5)) { + ERR("Process %s[%u] tried to %s; " + "since we are not in Primary state, " + "we cannot allow this\n", + current->comm, current->pid, + is_write ? "WRITE" : "READ"); + } + return 1; + } + + /* + * Paranoia: we might have been primary, but sync target, or + * even diskless, then lost the connection. + * This should have been handled (panic? suspend?) somehwere + * else. But maybe it was not, so check again here. + * Caution: as long as we do not have a read/write lock on mdev, + * to serialize state changes, this is racy, since we may lose + * the connection *after* we test for the cstate. + */ + if ( mdev->state.disk < UpToDate && + mdev->state.conn < Connected) { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Sorry, I have no access to good data anymore.\n"); + /* + * FIXME suspend, loop waiting on cstate wait? + */ + return 1; + } + + return 0; +} + +int drbd_make_request_26(struct request_queue *q, struct bio *bio) +{ + unsigned int s_enr, e_enr; + struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata; + + if (drbd_fail_request_early(mdev, bio_data_dir(bio) & WRITE)) { + bio_endio(bio, -EPERM); + return 0; + } + + /* Reject barrier requests if we know the underlying device does + * not support them. + * XXX: Need to get this info from peer as well some how so we + * XXX: reject if EITHER side/data/metadata area does not support them. + * + * because of those XXX, this is not yet enabled, + * i.e. in drbd_init_set_defaults we set the NO_BARRIER_SUPP bit. + */ + if (unlikely(bio_barrier(bio) && test_bit(NO_BARRIER_SUPP, &mdev->flags))) { + /* DRBD_WARN("Rejecting barrier request as underlying device does not support\n"); */ + bio_endio(bio, -EOPNOTSUPP); + return 0; + } + + /* + * what we "blindly" assume: + */ + D_ASSERT(bio->bi_size > 0); + D_ASSERT( (bio->bi_size & 0x1ff) == 0); + D_ASSERT(bio->bi_idx == 0); + + /* to make some things easier, force allignment of requests within the + * granularity of our hash tables */ + s_enr = bio->bi_sector >> HT_SHIFT; + e_enr = (bio->bi_sector+(bio->bi_size>>9)-1) >> HT_SHIFT; + + if (unlikely(s_enr != e_enr)) { + if (bio->bi_vcnt != 1 || bio->bi_idx != 0) { + /* rather error out here than BUG in bio_split */ + ERR("bio would need to, but cannot, be split: " + "(vcnt=%u,idx=%u,size=%u,sector=%llu)\n", + bio->bi_vcnt, bio->bi_idx, bio->bi_size, + (unsigned long long)bio->bi_sector); + bio_endio(bio, -EINVAL); + return 0; + } else { + /* This bio crosses some boundary, so we have to split it. */ + struct bio_pair *bp; + /* works for the "do not cross hash slot boundaries" case + * e.g. sector 262269, size 4096 + * s_enr = 262269 >> 6 = 4097 + * e_enr = (262269+8-1) >> 6 = 4098 + * HT_SHIFT = 6 + * sps = 64, mask = 63 + * first_sectors = 64 - (262269 & 63) = 3 + */ + const sector_t sect = bio->bi_sector; + const int sps = 1<bio1); + drbd_make_request_26(q, &bp->bio2); + bio_pair_release(bp); + return 0; + } + } + + return drbd_make_request_common(mdev,bio); +} + +/* This is called by bio_add_page(). With this function we reduce + * the number of BIOs that span over multiple DRBD_MAX_SEGMENT_SIZEs + * units (was AL_EXTENTs). + * + * we do the calculation within the lower 32bit of the byte offsets, + * since we don't care for actual offset, but only check whether it + * would cross "activity log extent" boundaries. + * + * As long as the BIO is emtpy we have to allow at least one bvec, + * regardless of size and offset. so the resulting bio may still + * cross extent boundaries. those are dealt with (bio_split) in + * drbd_make_request_26. + */ +int drbd_merge_bvec(struct request_queue *q, struct bvec_merge_data *bvm, struct bio_vec *bvec) +{ + struct drbd_conf *mdev = (struct drbd_conf *) q->queuedata; + unsigned int bio_offset = + (unsigned int)bvm->bi_sector << 9; /* 32 bit */ + unsigned int bio_size = bvm->bi_size; + int limit, backing_limit; + + limit = DRBD_MAX_SEGMENT_SIZE + - ((bio_offset & (DRBD_MAX_SEGMENT_SIZE-1)) + bio_size); + if (limit < 0) + limit = 0; + if (bio_size == 0) { + if (limit <= bvec->bv_len) + limit = bvec->bv_len; + } else if (limit && inc_local(mdev)) { + struct request_queue * const b = + mdev->bc->backing_bdev->bd_disk->queue; + if (b->merge_bvec_fn && mdev->bc->dc.use_bmbv) { + backing_limit = b->merge_bvec_fn(b, bvm, bvec); + limit = min(limit, backing_limit); + } + dec_local(mdev); + } + return limit; +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_worker.c +++ linux-2.6.28/ubuntu/drbd/drbd_worker.c @@ -0,0 +1,1322 @@ +/* +-*- linux-c -*- + drbd_worker.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LINUX_SCATTERLIST_H +#include +#endif + +#include +#include "drbd_int.h" +#include "drbd_req.h" + +/* defined here: + drbd_md_io_complete + drbd_endio_write_sec + drbd_endio_read_sec + drbd_endio_pri + + * more endio handlers: + atodb_endio in drbd_actlog.c + drbd_bm_async_io_complete in drbd_bitmap.c + + * For all these callbacks, note the follwing: + * The callbacks will be called in irq context by the IDE drivers, + * and in Softirqs/Tasklets/BH context by the SCSI drivers. + * Try to get the locking right :) + * + */ + +/* used for synchronous meta data and bitmap IO + * submitted by drbd_md_sync_page_io() + */ +BIO_ENDIO_TYPE drbd_md_io_complete BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + struct drbd_md_io *md_io; + + BIO_ENDIO_FN_START; + + /* error parameter ignored: + * drbd_md_sync_page_io explicitly tests bio_uptodate(bio); */ + + md_io = (struct drbd_md_io *)bio->bi_private; + + md_io->error = error; + + dump_internal_bio("Md", md_io->mdev, bio, 1); + + complete(&md_io->event); + + BIO_ENDIO_FN_RETURN; +} + +/* reads on behalf of the partner, + * "submitted" by the receiver + */ +BIO_ENDIO_TYPE drbd_endio_read_sec BIO_ENDIO_ARGS(struct bio *bio, int error) __releases(local) +{ + unsigned long flags = 0; + struct Tl_epoch_entry *e = NULL; + struct drbd_conf *mdev; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + e = bio->bi_private; + mdev = e->mdev; + + BIO_ENDIO_FN_START; + if (!error && !uptodate) { + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to DRBD_WARN() on this? */ + error = -EIO; + } + + D_ASSERT(e->block_id != ID_VACANT); + + dump_internal_bio("Sec", mdev, bio, 1); + + spin_lock_irqsave(&mdev->req_lock, flags); + mdev->read_cnt += e->size >> 9; + list_del(&e->w.list); + if (list_empty(&mdev->read_ee)) wake_up(&mdev->ee_wait); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + drbd_chk_io_error(mdev, error, FALSE); + drbd_queue_work(&mdev->data.work, &e->w); + dec_local(mdev); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Moved EE (READ) to worker sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + BIO_ENDIO_FN_RETURN; +} + +/* writes on behalf of the partner, or resync writes, + * "submitted" by the receiver. + */ +BIO_ENDIO_TYPE drbd_endio_write_sec BIO_ENDIO_ARGS(struct bio *bio, int error) __releases(local) +{ + unsigned long flags = 0; + struct Tl_epoch_entry *e = NULL; + struct drbd_conf *mdev; + sector_t e_sector; + int do_wake; + int is_syncer_req; + int do_al_complete_io; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + e = bio->bi_private; + mdev = e->mdev; + + BIO_ENDIO_FN_START; + if (!error && !uptodate) { + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to DRBD_WARN() on this? */ + error = -EIO; + } + + D_ASSERT(e->block_id != ID_VACANT); + + dump_internal_bio("Sec", mdev, bio, 1); + + spin_lock_irqsave(&mdev->req_lock, flags); + mdev->writ_cnt += e->size >> 9; + is_syncer_req = is_syncer_block_id(e->block_id); + + /* after we moved e to done_ee, + * we may no longer access it, + * it may be freed/reused already! + * (as soon as we release the req_lock) */ + e_sector = e->sector; + do_al_complete_io = e->flags & EE_CALL_AL_COMPLETE_IO; + + list_del(&e->w.list); /* has been on active_ee or sync_ee */ + list_add_tail(&e->w.list, &mdev->done_ee); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Moved EE (WRITE) to done_ee sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + + /* No hlist_del_init(&e->colision) here, we did not send the Ack yet, + * neither did we wake possibly waiting conflicting requests. + * done from "drbd_process_done_ee" within the appropriate w.cb + * (e_end_block/e_end_resync_block) or from _drbd_clear_done_ee */ + + if (!is_syncer_req) + mdev->epoch_size++; + + do_wake = is_syncer_req + ? list_empty(&mdev->sync_ee) + : list_empty(&mdev->active_ee); + + if (error) + __drbd_chk_io_error(mdev, FALSE); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + if (is_syncer_req) + drbd_rs_complete_io(mdev, e_sector); + + if (do_wake) + wake_up(&mdev->ee_wait); + + if (do_al_complete_io) + drbd_al_complete_io(mdev, e_sector); + + wake_asender(mdev); + dec_local(mdev); + + BIO_ENDIO_FN_RETURN; +} + +/* read, readA or write requests on Primary comming from drbd_make_request + */ +BIO_ENDIO_TYPE drbd_endio_pri BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + unsigned long flags; + struct drbd_request *req = bio->bi_private; + struct drbd_conf *mdev = req->mdev; + enum drbd_req_event what; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + BIO_ENDIO_FN_START; + if (!error && !uptodate) { + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to DRBD_WARN() on this? */ + error = -EIO; + } + + dump_internal_bio("Pri", mdev, bio, 1); + + /* to avoid recursion in _req_mod */ + what = error + ? (bio_data_dir(bio) == WRITE) + ? write_completed_with_error + : read_completed_with_error + : completed_ok; + spin_lock_irqsave(&mdev->req_lock, flags); + _req_mod(req, what, error); + spin_unlock_irqrestore(&mdev->req_lock, flags); + + BIO_ENDIO_FN_RETURN; +} + +int w_io_error(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + int ok; + + /* FIXME send a "set_out_of_sync" packet to the peer + * in the PassOn case... + * in the Detach (or Panic) case, we (try to) send + * a "we are diskless" param packet anyways, and the peer + * will then set the FullSync bit in the meta data ... + */ + /* NOTE: mdev->bc can be NULL by the time we get here! */ + /* D_ASSERT(mdev->bc->dc.on_io_error != PassOn); */ + + /* the only way this callback is scheduled is from _req_may_be_done, + * when it is done and had a local write error, see comments there */ + drbd_req_free(req); + + ok = drbd_io_error(mdev, FALSE); + if (unlikely(!ok)) ERR("Sending in w_io_error() failed\n"); + return ok; +} + +int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + + /* FIXME this is ugly. we should not detach for read io-error, + * but try to WRITE the DataReply to the failed location, + * to give the disk the chance to relocate that block */ + drbd_io_error(mdev,FALSE); /* tries to schedule a detach and notifies peer */ + + spin_lock_irq(&mdev->req_lock); + if ( cancel || + mdev->state.conn < Connected || + mdev->state.pdsk <= Inconsistent ) { + _req_mod(req, send_canceled, 0); /* FIXME freeze? ... */ + spin_unlock_irq(&mdev->req_lock); + drbd_khelper(mdev, "pri-on-incon-degr"); /* FIXME REALLY? */ + ALERT("WE ARE LOST. Local IO failure, no peer.\n"); + return 1; + } + spin_unlock_irq(&mdev->req_lock); + + return w_send_read_req(mdev, w, 0); +} + +int w_resync_inactive(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + ERR_IF(cancel) return 1; + ERR("resync inactive, but callback triggered??\n"); + return 1; /* Simply ignore this! */ +} + +STATIC void drbd_csum(struct drbd_conf *mdev, struct crypto_hash *tfm, struct bio *bio, void *digest) +{ + struct hash_desc desc; + struct scatterlist sg; + struct bio_vec *bvec; + int i; + + desc.tfm=tfm; + desc.flags=0; + + sg_init_table(&sg, 1); + crypto_hash_init(&desc); + + __bio_for_each_segment(bvec, bio, i, 0) { + sg_set_page(&sg, bvec->bv_page, bvec->bv_len, bvec->bv_offset); + crypto_hash_update(&desc, &sg, sg.length); + } + crypto_hash_final(&desc, digest); +} + +int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work* w,int cancel); + + +void resync_timer_fn(unsigned long data) +{ + unsigned long flags; + struct drbd_conf *mdev = (struct drbd_conf *) data; + int queue; + + spin_lock_irqsave(&mdev->req_lock, flags); + + if (likely(!test_and_clear_bit(STOP_SYNC_TIMER, &mdev->flags))) { + queue = 1; + if(mdev->state.conn == VerifyS ) { + mdev->resync_work.cb = w_make_ov_request; + } else mdev->resync_work.cb = w_make_resync_request; + } else { + queue = 0; + mdev->resync_work.cb = w_resync_inactive; + } + + spin_unlock_irqrestore(&mdev->req_lock, flags); + + /* harmless race: list_empty outside data.work.q_lock */ + if (list_empty(&mdev->resync_work.list) && queue) + drbd_queue_work(&mdev->data.work, &mdev->resync_work); +} + +#define SLEEP_TIME (HZ/10) + +int w_make_resync_request(struct drbd_conf *mdev, + struct drbd_work *w, int cancel) +{ + unsigned long bit; + sector_t sector; + const sector_t capacity = drbd_get_capacity(mdev->this_bdev); + int max_segment_size = mdev->rq_queue->max_segment_size; + int number, i, size; + int align; + + PARANOIA_BUG_ON(w != &mdev->resync_work); + + if (unlikely(cancel)) return 1; + + if (unlikely(mdev->state.conn < Connected)) { + ERR("Confused in w_make_resync_request()! cstate < Connected"); + return 0; + } + + if (mdev->state.conn != SyncTarget) + ERR("%s in w_make_resync_request\n", + conns_to_name(mdev->state.conn)); + + if (!inc_local(mdev)) { + /* Since we only need to access mdev->rsync a + inc_local_if_state(mdev,Failed) would be sufficient, but + to continue resync with a broken disk makes no sense at + all */ + ERR("Disk broke down during resync!\n"); + mdev->resync_work.cb = w_resync_inactive; + return 1; + } + /* All goto requeses have to happend after this block: inc_local() */ + + number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ); + + if (atomic_read(&mdev->rs_pending_cnt) > number) + goto requeue; + number -= atomic_read(&mdev->rs_pending_cnt); + + for (i = 0; i < number; i++) { +next_sector: + size = BM_BLOCK_SIZE; + /* as of now, we are the only user of drbd_bm_find_next */ + bit = drbd_bm_find_next(mdev); + + if (bit == -1UL) { + /* FIXME either test_and_set some bit, + * or make this the _only_ place that is allowed + * to assign w_resync_inactive! */ + mdev->resync_work.cb = w_resync_inactive; + dec_local(mdev); + return 1; + } + + sector = BM_BIT_TO_SECT(bit); + + if (drbd_try_rs_begin_io(mdev, sector)) { + drbd_bm_set_find(mdev, bit); + goto requeue; + } + + if (unlikely(drbd_bm_test_bit(mdev, bit) == 0 )) { + drbd_rs_complete_io(mdev, sector); + goto next_sector; + } + +#if DRBD_MAX_SEGMENT_SIZE > BM_BLOCK_SIZE + /* try to find some adjacent bits. + * we stop if we have already the maximum req size. + * + * Aditionally always align bigger requests, in order to + * be prepared for all stripe sizes of software RAIDs. + * + * we _do_ care about the agreed-uppon q->max_segment_size + * here, as splitting up the requests on the other side is more + * difficult. the consequence is, that on lvm and md and other + * "indirect" devices, this is dead code, since + * q->max_segment_size will be PAGE_SIZE. + */ + align = 1; + for (;;) { + if (size + BM_BLOCK_SIZE > max_segment_size) + break; + + /* Be always aligned */ + if (sector & ((1<<(align+3))-1) ) + break; + + /* do not cross extent boundaries */ + if (( (bit+1) & BM_BLOCKS_PER_BM_EXT_MASK ) == 0) + break; + /* now, is it actually dirty, after all? + * caution, drbd_bm_test_bit is tri-state for some + * obscure reason; ( b == 0 ) would get the out-of-band + * only accidentally right because of the "oddly sized" + * adjustment below */ + if ( drbd_bm_test_bit(mdev, bit+1) != 1 ) + break; + bit++; + size += BM_BLOCK_SIZE; + if ( (BM_BLOCK_SIZE< BM_BLOCK_SIZE) + drbd_bm_set_find(mdev, bit+1); +#endif + + /* adjust very last sectors, in case we are oddly sized */ + if (sector + (size>>9) > capacity) + size = (capacity-sector)<<9; + inc_rs_pending(mdev); + if (!drbd_send_drequest(mdev, RSDataRequest, + sector, size, ID_SYNCER)) { + ERR("drbd_send_drequest() failed, aborting...\n"); + dec_rs_pending(mdev); + dec_local(mdev); + return 0; + } + } + + if (drbd_bm_rs_done(mdev)) { + /* last syncer _request_ was sent, + * but the RSDataReply not yet received. sync will end (and + * next sync group will resume), as soon as we receive the last + * resync data block, and the last bit is cleared. + * until then resync "work" is "inactive" ... + */ + mdev->resync_work.cb = w_resync_inactive; + dec_local(mdev); + return 1; + } + + requeue: + mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME); + dec_local(mdev); + return 1; +} + +int w_make_ov_request(struct drbd_conf *mdev, struct drbd_work* w,int cancel) +{ + int number,i,size; + sector_t sector; + const sector_t capacity = drbd_get_capacity(mdev->this_bdev); + + if(unlikely(cancel)) return 1; + + if (unlikely(mdev->state.conn < Connected)) { + ERR("Confused in w_make_ov_request()! cstate < Connected"); + return 0; + } + + number = SLEEP_TIME*mdev->sync_conf.rate / ((BM_BLOCK_SIZE/1024)*HZ); + if (atomic_read(&mdev->rs_pending_cnt)>number) { + goto requeue; + } + number -= atomic_read(&mdev->rs_pending_cnt); + + sector = mdev->ov_position; + for(i=0;iov_position = sector; + goto requeue; + } + + if (sector + (size>>9) > capacity) size = (capacity-sector)<<9; + + inc_rs_pending(mdev); + if(!drbd_send_ov_request(mdev, sector, size)) { + dec_rs_pending(mdev); + return 0; + } + sector += BM_SECT_PER_BIT; + if(sector >= capacity) { + mdev->resync_work.cb = w_resync_inactive; + + return 1; + } + } + mdev->ov_position = sector; + + requeue: + mod_timer(&mdev->resync_timer, jiffies + SLEEP_TIME); + return 1; +} + + +int w_ov_finished(struct drbd_conf *mdev, struct drbd_work* w,int cancel) +{ + kfree(w); + ov_oos_print(mdev); + drbd_resync_finished(mdev); + + return 1; +} + +STATIC int w_resync_finished(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + kfree(w); + + drbd_resync_finished(mdev); + + return 1; +} + +int drbd_resync_finished(struct drbd_conf *mdev) +{ + unsigned long db,dt,dbdt; + union drbd_state_t os, ns; + struct drbd_work *w; + int art = 0; + + /* Remove all elements from the resync LRU. Since future actions + * might set bits in the (main) bitmap, then the entries in the + * resync LRU would be wrong. */ + if (drbd_rs_del_all(mdev)) { + /* In case this is not possible now, most probabely because + * there are RSDataReply Packets lingering on the worker's + * queue (or even the read operations for those packets + * is not finished by now). Retry in 100ms. */ + + drbd_kick_lo(mdev); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); + w = kmalloc(sizeof(struct drbd_work), GFP_ATOMIC); + if (w) { + w->cb = w_resync_finished; + drbd_queue_work(&mdev->data.work, w); + return 1; + } + ERR("Warn failed to drbd_rs_del_all() and to kmalloc(w).\n"); + } + + dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; + if (dt <= 0) + dt = 1; + db = mdev->rs_total; + dbdt = Bit2KB(db/dt); + mdev->rs_paused /= HZ; + + if (!inc_local(mdev)) + goto out; + + spin_lock_irq(&mdev->req_lock); + os = mdev->state; + + /* This protects us against multiple calls (that can happen in the presence + of application IO), and against connectivity loss just before we arrive here. */ + if (os.conn <= Connected) + goto out_unlock; + + ns = os; + ns.conn = Connected; + + INFO("%s done (total %lu sec; paused %lu sec; %lu K/sec)\n", + (os.conn == VerifyS || os.conn == VerifyT) ? + "Online verify ": "Resync", + dt + mdev->rs_paused, mdev->rs_paused, dbdt); + + if (os.conn == VerifyS || os.conn == VerifyT) { + if (drbd_bm_total_weight(mdev)) { + ALERT("Online verify found %lu %dk block out of sync!\n", + drbd_bm_total_weight(mdev),BM_BLOCK_SIZE/1024); + drbd_khelper(mdev,"out-of-sync"); + } + } else { + D_ASSERT((drbd_bm_total_weight(mdev)-mdev->rs_failed) == 0); + } + + if (mdev->rs_failed) { + INFO(" %lu failed blocks\n", mdev->rs_failed); + + if (os.conn == SyncTarget || os.conn == PausedSyncT) { + ns.disk = Inconsistent; + ns.pdsk = UpToDate; + } else { + ns.disk = UpToDate; + ns.pdsk = Inconsistent; + } + } else { + ns.disk = UpToDate; + ns.pdsk = UpToDate; + + if (os.conn == SyncTarget || os.conn == PausedSyncT) { + if (mdev->p_uuid) { + int i; + for (i = Bitmap ; i <= History_end ; i++) + _drbd_uuid_set(mdev, i, mdev->p_uuid[i]); + drbd_uuid_set(mdev, Bitmap, mdev->bc->md.uuid[Current]); + _drbd_uuid_set(mdev, Current, mdev->p_uuid[Current]); + } else { + ERR("mdev->p_uuid is NULL! BUG\n"); + } + } + + drbd_uuid_set_bm(mdev, 0UL); + + if (mdev->p_uuid) { + /* Now the two UUID sets are equal, update what we + * know of the peer. */ + int i; + for (i = Current ; i <= History_end ; i++) + mdev->p_uuid[i] = mdev->bc->md.uuid[i]; + } + } + + art = os.conn == SyncTarget || os.conn == PausedSyncT; + + _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); + out_unlock: + spin_unlock_irq(&mdev->req_lock); + dec_local(mdev); + out: + mdev->rs_total = 0; + mdev->rs_failed = 0; + mdev->rs_paused = 0; + + if (test_and_clear_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags)) { + DRBD_WARN("Writing the whole bitmap, due to failed kmalloc\n"); + drbd_queue_bitmap_io(mdev, &drbd_bm_write, NULL); + } + + drbd_bm_recount_bits(mdev); + + if (art) + drbd_khelper(mdev, "after-resync-target"); + + return 1; +} + +/** + * w_e_end_data_req: Send the answer (DataReply) in response to a DataRequest. + */ +int w_e_end_data_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + int ok; + + if (unlikely(cancel)) { + drbd_free_ee(mdev, e); + dec_unacked(mdev); + return 1; + } + + if (likely(drbd_bio_uptodate(e->private_bio))) { + ok = drbd_send_block(mdev, DataReply, e); + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Sending NegDReply. sector=%llus.\n", + (unsigned long long)e->sector); + + ok = drbd_send_ack(mdev, NegDReply, e); + + /* FIXME we should not detach for read io-errors, in particular + * not now: when the peer asked us for our data, we are likely + * the only remaining disk... */ + drbd_io_error(mdev, FALSE); + } + + dec_unacked(mdev); + + spin_lock_irq(&mdev->req_lock); + if (drbd_bio_has_active_page(e->private_bio)) { + /* This might happen if sendpage() has not finished */ + list_add_tail(&e->w.list, &mdev->net_ee); + } else { + drbd_free_ee(mdev, e); + } + spin_unlock_irq(&mdev->req_lock); + + if (unlikely(!ok)) ERR("drbd_send_block() failed\n"); + return ok; +} + +/** + * w_e_end_rsdata_req: Send the answer (RSDataReply) to a RSDataRequest. + */ +int w_e_end_rsdata_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + int ok; + + if (unlikely(cancel)) { + drbd_free_ee(mdev, e); + dec_unacked(mdev); + return 1; + } + + if (inc_local_if_state(mdev, Failed)) { + drbd_rs_complete_io(mdev, e->sector); + dec_local(mdev); + } + + if (likely(drbd_bio_uptodate(e->private_bio))) { + if (likely( mdev->state.pdsk >= Inconsistent )) { + inc_rs_pending(mdev); + ok = drbd_send_block(mdev, RSDataReply, e); + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Not sending RSDataReply, " + "partner DISKLESS!\n"); + ok = 1; + } + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Sending NegRSDReply. sector %llus.\n", + (unsigned long long)e->sector); + + ok = drbd_send_ack(mdev, NegRSDReply, e); + + drbd_io_error(mdev, FALSE); + + /* update resync data with failure */ + drbd_rs_failed_io(mdev, e->sector, e->size); + } + + dec_unacked(mdev); + + spin_lock_irq(&mdev->req_lock); + if (drbd_bio_has_active_page(e->private_bio)) { + /* This might happen if sendpage() has not finished */ + list_add_tail(&e->w.list, &mdev->net_ee); + } else { + drbd_free_ee(mdev, e); + } + spin_unlock_irq(&mdev->req_lock); + + if (unlikely(!ok)) ERR("drbd_send_block() failed\n"); + return ok; +} + + +int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w; + int digest_size; + void *digest; + int ok=1; + + if(unlikely(cancel)) { + drbd_free_ee(mdev,e); + dec_unacked(mdev); + return 1; + } + + if(likely(drbd_bio_uptodate(e->private_bio))) { + digest_size = crypto_hash_digestsize(mdev->verify_tfm); + digest = kmalloc(digest_size,GFP_KERNEL); + if(digest) { + drbd_csum(mdev,mdev->verify_tfm,e->private_bio,digest); + ok = drbd_send_drequest_csum(mdev, e->sector, e->size, + digest, digest_size, OVReply); + if (ok) inc_rs_pending(mdev); + kfree(digest); + } + } + + dec_unacked(mdev); + + spin_lock_irq(&mdev->req_lock); + drbd_free_ee(mdev,e); + spin_unlock_irq(&mdev->req_lock); + + return ok; +} + +void drbd_ov_oos_found(struct drbd_conf *mdev, sector_t sector, int size) +{ + if (mdev->ov_last_oos_start + mdev->ov_last_oos_size == sector) { + mdev->ov_last_oos_size += size>>9; + } else { + mdev->ov_last_oos_start = sector; + mdev->ov_last_oos_size = size>>9; + } + drbd_set_out_of_sync(mdev, sector, size); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); +} + +int w_e_end_ov_reply(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry*)w; + struct digest_info *di; + int digest_size; + void *digest; + int ok,eq=0; + + if(unlikely(cancel)) { + drbd_free_ee(mdev,e); + dec_unacked(mdev); + return 1; + } + + /* after "cancel", because after drbd_disconnect/drbd_rs_cancel_all + * the resync lru has been cleaned up already */ + drbd_rs_complete_io(mdev,e->sector); + + di = (struct digest_info *)(unsigned long)e->block_id; + + if(likely(drbd_bio_uptodate(e->private_bio))) { + digest_size = crypto_hash_digestsize(mdev->verify_tfm); + digest = kmalloc(digest_size,GFP_KERNEL); + if(digest) { + drbd_csum(mdev, mdev->verify_tfm, e->private_bio, digest); + + D_ASSERT(digest_size == di->digest_size); + eq = !memcmp(digest, di->digest, digest_size); + kfree(digest); + } + } else { + ok=drbd_send_ack(mdev,NegRSDReply,e); + if (DRBD_ratelimit(5*HZ,5)) + ERR("Sending NegDReply. I guess it gets messy.\n"); + drbd_io_error(mdev, FALSE); + } + + dec_unacked(mdev); + + kfree(di); + + if (!eq) drbd_ov_oos_found(mdev,e->sector,e->size); + else ov_oos_print(mdev); + + ok = drbd_send_ack_ex(mdev,OVResult,e->sector,e->size, + eq ? ID_IN_SYNC : ID_OUT_OF_SYNC); + + spin_lock_irq(&mdev->req_lock); + drbd_free_ee(mdev,e); + spin_unlock_irq(&mdev->req_lock); + + if( --mdev->ov_left == 0 ) { + ov_oos_print(mdev); + drbd_resync_finished(mdev); + } + + return ok; +} + + +int w_prev_work_done(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + clear_bit(WORK_PENDING, &mdev->flags); + wake_up(&mdev->misc_wait); + return 1; +} + +int w_send_barrier(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_barrier *b = (struct drbd_barrier *)w; + struct Drbd_Barrier_Packet *p = &mdev->data.sbuf.Barrier; + int ok = 1; + + /* really avoid racing with tl_clear. w.cb may have been referenced + * just before it was reassigned and requeued, so double check that. + * actually, this race was harmless, since we only try to send the + * barrier packet here, and otherwise do nothing with the object. + * but compare with the head of w_clear_epoch */ + spin_lock_irq(&mdev->req_lock); + if (w->cb != w_send_barrier || mdev->state.conn < Connected) + cancel = 1; + spin_unlock_irq(&mdev->req_lock); + if (cancel) + return 1; + + if (!drbd_get_data_sock(mdev)) + return 0; + p->barrier = b->br_number; + /* inc_ap_pending was done where this was queued. + * dec_ap_pending will be done in got_BarrierAck + * or (on connection loss) in w_clear_epoch. */ + ok = _drbd_send_cmd(mdev, mdev->data.socket, Barrier, + (struct Drbd_Header *)p, sizeof(*p), 0); + drbd_put_data_sock(mdev); + + return ok; +} + +int w_send_write_hint(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + if (cancel) + return 1; + return drbd_send_short_cmd(mdev, UnplugRemote); +} + +/** + * w_send_dblock: Send a mirrored write request. + */ +int w_send_dblock(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + int ok; + + if (unlikely(cancel)) { + req_mod(req, send_canceled, 0); + return 1; + } + + ok = drbd_send_dblock(mdev, req); + req_mod(req, ok ? handed_over_to_network : send_failed, 0); + + return ok; +} + +/** + * w_send_read_req: Send a read requests. + */ +int w_send_read_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel) +{ + struct drbd_request *req = (struct drbd_request *)w; + int ok; + + if (unlikely(cancel)) { + req_mod(req, send_canceled, 0); + return 1; + } + + ok = drbd_send_drequest(mdev, DataRequest, req->sector, req->size, + (unsigned long)req); + + if (ok) { + req_mod(req, handed_over_to_network, 0); + } else { + /* ?? we set Timeout or BrokenPipe in drbd_send() */ + if (mdev->state.conn >= Connected) + drbd_force_state(mdev, NS(conn, NetworkFailure)); + /* req_mod(req, send_failed); we should not fail it here, + * we might have to "freeze" on disconnect. + * handled by req_mod(req, connection_lost_while_pending); + * in drbd_fail_pending_reads soon enough. */ + } + + return ok; +} + +STATIC void drbd_global_lock(void) __acquires(drbd_global_lock) +{ + struct drbd_conf *mdev; + int i; + + __acquire(drbd_global_lock); + local_irq_disable(); + for (i = 0; i < minor_count; i++) { + mdev = minor_to_mdev(i); + if (!mdev) + continue; + spin_lock(&mdev->req_lock); + __release(&mdev->req_lock); /* annihilate the spin_lock's annotation here */ + } +} + +STATIC void drbd_global_unlock(void) __releases(drbd_global_lock) +{ + struct drbd_conf *mdev; + int i; + + for (i = 0; i < minor_count; i++) { + mdev = minor_to_mdev(i); + if (!mdev) + continue; + __acquire(&mdev->req_lock); + spin_unlock(&mdev->req_lock); + } + local_irq_enable(); + __release(drbd_global_lock); +} + +STATIC int _drbd_may_sync_now(struct drbd_conf *mdev) +{ + struct drbd_conf *odev = mdev; + + while (1) { + if (odev->sync_conf.after == -1) + return 1; + odev = minor_to_mdev(odev->sync_conf.after); + ERR_IF(!odev) return 1; + if ( (odev->state.conn >= SyncSource && + odev->state.conn <= PausedSyncT) || + odev->state.aftr_isp || odev->state.peer_isp || + odev->state.user_isp ) return 0; + } +} + +/** + * _drbd_pause_after: + * Finds all devices that may not resync now, and causes them to + * pause their resynchronisation. + * Called from process context only ( ioctl and after_state_ch ). + */ +STATIC int _drbd_pause_after(struct drbd_conf *mdev) +{ + struct drbd_conf *odev; + int i, rv = 0; + + for (i = 0; i < minor_count; i++) { + odev = minor_to_mdev(i); + if (!odev) + continue; + if (odev->state.conn == StandAlone && odev->state.disk == Diskless) + continue; + if (!_drbd_may_sync_now(odev)) + rv |= ( _drbd_set_state(_NS(odev, aftr_isp, 1), ChgStateHard, NULL) + != SS_NothingToDo ) ; + } + + return rv; +} + +/** + * _drbd_resume_next: + * Finds all devices that can resume resynchronisation + * process, and causes them to resume. + * Called from process context only ( ioctl and worker ). + */ +STATIC int _drbd_resume_next(struct drbd_conf *mdev) +{ + struct drbd_conf *odev; + int i, rv = 0; + + for (i = 0; i < minor_count; i++) { + odev = minor_to_mdev(i); + if (!odev) + continue; + if (odev->state.aftr_isp) { + if (_drbd_may_sync_now(odev)) + rv |= (_drbd_set_state(_NS(odev, aftr_isp, 0), + ChgStateHard, NULL) + != SS_NothingToDo) ; + } + } + return rv; +} + +void resume_next_sg(struct drbd_conf *mdev) +{ + drbd_global_lock(); + _drbd_resume_next(mdev); + drbd_global_unlock(); +} + +void suspend_other_sg(struct drbd_conf *mdev) +{ + drbd_global_lock(); + _drbd_pause_after(mdev); + drbd_global_unlock(); +} + +void drbd_alter_sa(struct drbd_conf *mdev, int na) +{ + int changes; + + drbd_global_lock(); + mdev->sync_conf.after = na; + + do { + changes = _drbd_pause_after(mdev); + changes |= _drbd_resume_next(mdev); + } while (changes); + + drbd_global_unlock(); +} + +/** + * drbd_start_resync: + * @side: Either SyncSource or SyncTarget + * Start the resync process. Called from process context only, + * either ioctl or drbd_receiver. + * Note, this function might bring you directly into one of the + * PausedSync* states. + */ +void drbd_start_resync(struct drbd_conf *mdev, enum drbd_conns side) +{ + union drbd_state_t ns; + int r; + + MTRACE(TraceTypeResync, TraceLvlSummary, + INFO("Resync starting: side=%s\n", + side == SyncTarget?"SyncTarget":"SyncSource"); + ); + + drbd_bm_recount_bits(mdev); + + /* In case a previous resync run was aborted by an IO error... */ + drbd_rs_cancel_all(mdev); + + if (side == SyncTarget) { + /* Since application IO was locked out during WFBitMapT and + WFSyncUUID we are still unmodified. Before going to SyncTarget + we check that we might make the data inconsistent. */ + r = drbd_khelper(mdev, "before-resync-target"); + r = (r >> 8) & 0xff; + if (r > 0) { + INFO("before-resync-target handler returned %d, " + "dropping connection.\n", r); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return; + } + } + + drbd_state_lock(mdev); + + if (!inc_local_if_state(mdev, Negotiating)) { + drbd_state_unlock(mdev); + return; + } + + if (side == SyncTarget) { + drbd_bm_reset_find(mdev); + } else /* side == SyncSource */ { + u64 uuid; + + get_random_bytes(&uuid, sizeof(u64)); + drbd_uuid_set(mdev, Bitmap, uuid); + drbd_send_sync_uuid(mdev, uuid); + + D_ASSERT(mdev->state.disk == UpToDate); + } + + drbd_global_lock(); + ns = mdev->state; + + ns.aftr_isp = !_drbd_may_sync_now(mdev); + + ns.conn = side; + + if (side == SyncTarget) + ns.disk = Inconsistent; + else /* side == SyncSource */ + ns.pdsk = Inconsistent; + + r = _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); + ns = mdev->state; + + if (ns.conn < Connected) + r = SS_UnknownError; + + if (r == SS_Success) { + mdev->rs_total = + mdev->rs_mark_left = drbd_bm_total_weight(mdev); + mdev->rs_failed = 0; + mdev->rs_paused = 0; + mdev->rs_start = + mdev->rs_mark_time = jiffies; + _drbd_pause_after(mdev); + } + drbd_global_unlock(); + drbd_state_unlock(mdev); + dec_local(mdev); + + if (r == SS_Success) { + INFO("Began resync as %s (will sync %lu KB [%lu bits set]).\n", + conns_to_name(ns.conn), + (unsigned long) mdev->rs_total << (BM_BLOCK_SIZE_B-10), + (unsigned long) mdev->rs_total); + + if (mdev->rs_total == 0) { + drbd_resync_finished(mdev); + return; + } + + if (ns.conn == SyncTarget) { + D_ASSERT(!test_bit(STOP_SYNC_TIMER, &mdev->flags)); + mod_timer(&mdev->resync_timer, jiffies); + } + + drbd_md_sync(mdev); + } +} + +int drbd_worker(struct Drbd_thread *thi) +{ + struct drbd_conf *mdev = thi->mdev; + struct drbd_work *w = NULL; + LIST_HEAD(work_list); + int intr = 0, i; + + sprintf(current->comm, "drbd%d_worker", mdev_to_minor(mdev)); + set_cpus_allowed(current, drbd_calc_cpu_mask(mdev)); + + while (get_t_state(thi) == Running) { + + if (down_trylock(&mdev->data.work.s)) { + down(&mdev->data.mutex); + if (mdev->data.socket) + drbd_tcp_flush(mdev->data.socket); + up(&mdev->data.mutex); + + intr = down_interruptible(&mdev->data.work.s); + + down(&mdev->data.mutex); + if (mdev->data.socket) + drbd_tcp_cork(mdev->data.socket); + up(&mdev->data.mutex); + } + + if (intr) { + D_ASSERT(intr == -EINTR); + flush_signals(current); + ERR_IF (get_t_state(thi) == Running) + continue; + break; + } + + if (get_t_state(thi) != Running) break; + /* With this break, we have done a down() but not consumed + the entry from the list. The cleanup code takes care of + this... */ + + w = NULL; + spin_lock_irq(&mdev->data.work.q_lock); + ERR_IF(list_empty(&mdev->data.work.q)) { + /* something terribly wrong in our logic. + * we were able to down() the semaphore, + * but the list is empty... doh. + * + * what is the best thing to do now? + * try again from scratch, restarting the receiver, + * asender, whatnot? could break even more ugly, + * e.g. when we are primary, but no good local data. + * + * I'll try to get away just starting over this loop. + */ + spin_unlock_irq(&mdev->data.work.q_lock); + continue; + } + w = list_entry(mdev->data.work.q.next, struct drbd_work, list); + list_del_init(&w->list); + spin_unlock_irq(&mdev->data.work.q_lock); + + if (!w->cb(mdev, w, mdev->state.conn < Connected )) { + /* DRBD_WARN("worker: a callback failed! \n"); */ + if (mdev->state.conn >= Connected) + drbd_force_state(mdev, + NS(conn, NetworkFailure)); + } + } + + spin_lock_irq(&mdev->data.work.q_lock); + i = 0; + while (!list_empty(&mdev->data.work.q)) { + list_splice_init(&mdev->data.work.q, &work_list); + spin_unlock_irq(&mdev->data.work.q_lock); + + while (!list_empty(&work_list)) { + w = list_entry(work_list.next, struct drbd_work, list); + list_del_init(&w->list); + w->cb(mdev, w, 1); + i++; /* dead debugging code */ + } + + spin_lock_irq(&mdev->data.work.q_lock); + } + sema_init(&mdev->data.work.s, 0); + /* DANGEROUS race: if someone did queue his work within the spinlock, + * but up() ed outside the spinlock, we could get an up() on the + * semaphore without corresponding list entry. + * So don't do that. + */ + spin_unlock_irq(&mdev->data.work.q_lock); + /* FIXME verify that there absolutely can not be any more work + * on the queue now... + * if so, the comment above is no longer true, but historic + * from the times when the worker did not live as long as the + * device.. */ + + D_ASSERT(mdev->state.disk == Diskless && mdev->state.conn == StandAlone); + drbd_mdev_cleanup(mdev); + + INFO("worker terminated\n"); + + return 0; +} --- linux-2.6.28.orig/ubuntu/drbd/Makefile +++ linux-2.6.28/ubuntu/drbd/Makefile @@ -0,0 +1,7 @@ +drbd-objs := drbd_buildtag.o drbd_bitmap.o drbd_proc.o \ + drbd_worker.o drbd_receiver.o drbd_req.o drbd_actlog.o \ + lru_cache.o drbd_main.o drbd_strings.o drbd_nl.o + +EXTRA_CFLAGS += -I$(src) + +#obj-$(CONFIG_BLK_DEV_DRBD) += drbd.o --- linux-2.6.28.orig/ubuntu/drbd/drbd_proc.c +++ linux-2.6.28/ubuntu/drbd/drbd_proc.c @@ -0,0 +1,257 @@ +/* +-*- linux-c -*- + drbd_proc.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include "drbd_int.h" +#include "lru_cache.h" /* for lc_sprintf_stats */ + +int drbd_proc_open(struct inode *inode, struct file *file); + + +struct proc_dir_entry *drbd_proc; +struct file_operations drbd_proc_fops = { + .owner = THIS_MODULE, + .open = drbd_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +/*lge + * progress bars shamelessly adapted from driver/md/md.c + * output looks like + * [=====>..............] 33.5% (23456/123456) + * finish: 2:20:20 speed: 6,345 (6,456) K/sec + */ +STATIC void drbd_syncer_progress(struct drbd_conf *mdev, struct seq_file *seq) +{ + unsigned long db, dt, dbdt, rt, rs_left; + unsigned int res; + int i, x, y; + + drbd_get_syncer_progress(mdev, &rs_left, &res); + + x = res/50; + y = 20-x; + seq_printf(seq, "\t["); + for (i = 1; i < x; i++) + seq_printf(seq, "="); + seq_printf(seq, ">"); + for (i = 0; i < y; i++) + seq_printf(seq, "."); + seq_printf(seq, "] "); + + seq_printf(seq, "sync'ed:%3u.%u%% ", res / 10, res % 10); + /* if more than 1 GB display in MB */ + if (mdev->rs_total > 0x100000L) + seq_printf(seq, "(%lu/%lu)M\n\t", + (unsigned long) Bit2KB(rs_left) >> 10, + (unsigned long) Bit2KB(mdev->rs_total) >> 10 ); + else + seq_printf(seq, "(%lu/%lu)K\n\t", + (unsigned long) Bit2KB(rs_left), + (unsigned long) Bit2KB(mdev->rs_total) ); + + /* see drivers/md/md.c + * We do not want to overflow, so the order of operands and + * the * 100 / 100 trick are important. We do a +1 to be + * safe against division by zero. We only estimate anyway. + * + * dt: time from mark until now + * db: blocks written from mark until now + * rt: remaining time + */ + dt = (jiffies - mdev->rs_mark_time) / HZ; + + if (dt > 20) { + /* if we made no update to rs_mark_time for too long, + * we are stalled. show that. */ + seq_printf(seq, "stalled\n"); + return; + } + + if (!dt) + dt++; + db = mdev->rs_mark_left - rs_left; + rt = (dt * (rs_left / (db/100+1)))/100; /* seconds */ + + seq_printf(seq, "finish: %lu:%02lu:%02lu", + rt / 3600, (rt % 3600) / 60, rt % 60); + + /* current speed average over (SYNC_MARKS * SYNC_MARK_STEP) jiffies */ + dbdt = Bit2KB(db/dt); + if (dbdt > 1000) + seq_printf(seq, " speed: %ld,%03ld", + dbdt/1000, dbdt % 1000); + else + seq_printf(seq, " speed: %ld", dbdt); + + /* mean speed since syncer started + * we do account for PausedSync periods */ + dt = (jiffies - mdev->rs_start - mdev->rs_paused) / HZ; + if (dt <= 0) + dt = 1; + db = mdev->rs_total - rs_left; + dbdt = Bit2KB(db/dt); + if (dbdt > 1000) + seq_printf(seq, " (%ld,%03ld)", + dbdt/1000, dbdt % 1000); + else + seq_printf(seq, " (%ld)", dbdt); + + seq_printf(seq, " K/sec\n"); +} + +#ifdef ENABLE_DYNAMIC_TRACE +STATIC void resync_dump_detail(struct seq_file *seq, struct lc_element *e) +{ + struct bm_extent *bme = (struct bm_extent *)e; + + seq_printf(seq, "%5d %s %s\n", bme->rs_left, + bme->flags & BME_NO_WRITES ? "NO_WRITES" : "---------", + bme->flags & BME_LOCKED ? "LOCKED" : "------" + ); +} +#endif + +STATIC int drbd_seq_show(struct seq_file *seq, void *v) +{ + int i, hole = 0; + const char *sn; + struct drbd_conf *mdev; + + seq_printf(seq, "version: " REL_VERSION " (api:%d/proto:%d-%d)\n%s\n", + API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX, drbd_buildtag()); + + /* + cs .. connection state + st .. node state (local/remote) + ld .. local data consistentency + ns .. network send + nr .. network receive + dw .. disk write + dr .. disk read + pe .. pending (waiting for ack) + ua .. unack'd (still need to send ack) + al .. access log write count + */ + + for (i = 0; i < minor_count; i++) { + mdev = minor_to_mdev(i); + if (!mdev) { + hole = 1; + continue; + } + if (hole) { + hole = 0; + seq_printf( seq, "\n"); + } + + sn = conns_to_name(mdev->state.conn); + + if ( mdev->state.conn == StandAlone && + mdev->state.disk == Diskless) { + seq_printf( seq, "%2d: cs:Unconfigured\n", i); + } else { + seq_printf( seq, + "%2d: cs:%s st:%s/%s ds:%s/%s %c %c%c%c%c\n" + " ns:%u nr:%u dw:%u dr:%u al:%u bm:%u " + "lo:%d pe:%d ua:%d ap:%d", + i, sn, + roles_to_name(mdev->state.role), + roles_to_name(mdev->state.peer), + disks_to_name(mdev->state.disk), + disks_to_name(mdev->state.pdsk), + (mdev->net_conf == NULL ? ' ' : + (mdev->net_conf->wire_protocol - DRBD_PROT_A+'A')), + mdev->state.susp ? 's' : 'r', + mdev->state.aftr_isp ? 'a' : '-', + mdev->state.peer_isp ? 'p' : '-', + mdev->state.user_isp ? 'u' : '-', + mdev->send_cnt/2, + mdev->recv_cnt/2, + mdev->writ_cnt/2, + mdev->read_cnt/2, + mdev->al_writ_cnt, + mdev->bm_writ_cnt, + atomic_read(&mdev->local_cnt), + atomic_read(&mdev->ap_pending_cnt) + + atomic_read(&mdev->rs_pending_cnt), + atomic_read(&mdev->unacked_cnt), + atomic_read(&mdev->ap_bio_cnt) + ); + seq_printf(seq, " oos:%lu\n", + drbd_bm_total_weight(mdev) << (BM_BLOCK_SIZE_B - 10)); + } + if ( mdev->state.conn == SyncSource || + mdev->state.conn == SyncTarget ) + drbd_syncer_progress(mdev, seq); + + if ( mdev->state.conn == VerifyS || + mdev->state.conn == VerifyT ) { + seq_printf(seq,"\t%3d%% %lu/%lu\n", + (int)((mdev->rs_total-mdev->ov_left) / + (mdev->rs_total/100+1)), + mdev->rs_total - mdev->ov_left, + mdev->rs_total); + } + +#ifdef ENABLE_DYNAMIC_TRACE + if (proc_details >= 1 && inc_local_if_state(mdev, Failed)) { + lc_printf_stats(seq, mdev->resync); + lc_printf_stats(seq, mdev->act_log); + dec_local(mdev); + } + + if (proc_details >= 2) { + if (mdev->resync) { + lc_dump(mdev->resync, seq, "rs_left", + resync_dump_detail); + } + } +#endif + } + + return 0; +} + +int drbd_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, drbd_seq_show, PDE(inode)->data); +} + +/* PROC FS stuff end */ --- linux-2.6.28.orig/ubuntu/drbd/drbd_actlog.c +++ linux-2.6.28/ubuntu/drbd/drbd_actlog.c @@ -0,0 +1,1510 @@ +/* +-*- linux-c -*- + drbd_actlog.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include "drbd_int.h" + +/* This is what I like so much about the linux kernel: + * if you have a close look, you can almost always reuse code by someone else + * ;) + * this is mostly from drivers/md/md.c + */ +STATIC int _drbd_md_sync_page_io(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev, + struct page *page, sector_t sector, + int rw, int size) +{ + struct bio *bio; + struct drbd_md_io md_io; + int ok; + + md_io.mdev = mdev; + init_completion(&md_io.event); + md_io.error = 0; + + if (rw == WRITE && !test_bit(MD_NO_BARRIER, &mdev->flags)) + rw |= (1<bi_bdev = bdev->md_bdev; + bio->bi_sector = sector; + ok = (bio_add_page(bio, page, size, 0) == size); + if (!ok) + goto out; + bio->bi_private = &md_io; + bio->bi_end_io = drbd_md_io_complete; + bio->bi_rw = rw; + + dump_internal_bio("Md", mdev, bio, 0); + + if (FAULT_ACTIVE(mdev, (rw & WRITE)? DRBD_FAULT_MD_WR:DRBD_FAULT_MD_RD)) + bio_endio(bio, -EIO); + else + submit_bio(rw, bio); + wait_for_completion(&md_io.event); + ok = bio_flagged(bio, BIO_UPTODATE); + + /* check for unsupported barrier op */ + if (unlikely(md_io.error == -EOPNOTSUPP && bio_barrier(bio))) { + /* Try again with no barrier */ + DRBD_WARN("Barriers not supported on meta data device - disabling\n"); + set_bit(MD_NO_BARRIER,&mdev->flags); + rw &= ~(1 << BIO_RW_BARRIER); + bio_put(bio); + goto retry; + } + out: + bio_put(bio); + return ok; +} + +int drbd_md_sync_page_io(struct drbd_conf *mdev, struct drbd_backing_dev *bdev, + sector_t sector, int rw) +{ + int hardsect, mask, ok; + int offset = 0; + struct page *iop = mdev->md_io_page; + + D_ASSERT(semaphore_is_locked(&mdev->md_io_mutex)); + + if (!bdev->md_bdev) { + if (DRBD_ratelimit(5*HZ, 5)) { + ERR("bdev->md_bdev==NULL\n"); + dump_stack(); + } + return 0; + } + + hardsect = drbd_get_hardsect(bdev->md_bdev); + if (hardsect == 0) + hardsect = MD_HARDSECT; + + /* in case hardsect != 512 [ s390 only? ] */ + if (hardsect != MD_HARDSECT) { + if (!mdev->md_io_tmpp) { + struct page *page = alloc_page(GFP_NOIO); + if (!page) + return 0; + + DRBD_WARN("Meta data's bdev hardsect = %d != %d\n", + hardsect, MD_HARDSECT); + DRBD_WARN("Workaround engaged (has performace impact).\n"); + + mdev->md_io_tmpp = page; + } + + mask = ( hardsect / MD_HARDSECT ) - 1; + D_ASSERT( mask == 1 || mask == 3 || mask == 7 ); + D_ASSERT( hardsect == (mask+1) * MD_HARDSECT ); + offset = sector & mask; + sector = sector & ~mask; + iop = mdev->md_io_tmpp; + + if (rw == WRITE) { + void *p = page_address(mdev->md_io_page); + void *hp = page_address(mdev->md_io_tmpp); + + ok = _drbd_md_sync_page_io(mdev, bdev, iop, + sector, READ, hardsect); + + if (unlikely(!ok)) { + ERR("drbd_md_sync_page_io(,%llus," + "READ [hardsect!=512]) failed!\n", + (unsigned long long)sector); + return 0; + } + + memcpy(hp + offset*MD_HARDSECT , p, MD_HARDSECT); + } + } + +#if DUMP_MD >= 3 + INFO("%s [%d]:%s(,%llus,%s)\n", + current->comm, current->pid, __func__, + (unsigned long long)sector, rw ? "WRITE" : "READ"); +#endif + + if (sector < drbd_md_first_sector(bdev) || + sector > drbd_md_last_sector(bdev)) + ALERT("%s [%d]:%s(,%llus,%s) out of range md access!\n", + current->comm, current->pid, __func__, + (unsigned long long)sector, rw ? "WRITE" : "READ"); + + ok = _drbd_md_sync_page_io(mdev, bdev, iop, sector, rw, hardsect); + if (unlikely(!ok)) { + ERR("drbd_md_sync_page_io(,%llus,%s) failed!\n", + (unsigned long long)sector, rw ? "WRITE" : "READ"); + return 0; + } + + if (hardsect != MD_HARDSECT && rw == READ) { + void *p = page_address(mdev->md_io_page); + void *hp = page_address(mdev->md_io_tmpp); + + memcpy(p, hp + offset*MD_HARDSECT, MD_HARDSECT); + } + + return ok; +} + +/* I do not believe that all storage medias can guarantee atomic + * 512 byte write operations. When the journal is read, only + * transactions with correct xor_sums are considered. + * sizeof() = 512 byte */ +struct __attribute__((packed)) al_transaction { + u32 magic; + u32 tr_number; + /* u32 tr_generation; TODO */ + struct __attribute__((packed)) { + u32 pos; + u32 extent; } updates[1 + AL_EXTENTS_PT]; + u32 xor_sum; +}; + +struct update_odbm_work { + struct drbd_work w; + unsigned int enr; +}; + +struct update_al_work { + struct drbd_work w; + struct lc_element *al_ext; + struct completion event; + unsigned int enr; + /* if old_enr != LC_FREE, write corresponding bitmap sector, too */ + unsigned int old_enr; +}; + +int w_al_write_transaction(struct drbd_conf *, struct drbd_work *, int); + +static inline +struct lc_element *_al_get(struct drbd_conf *mdev, unsigned int enr) +{ + struct lc_element *al_ext; + struct bm_extent *bm_ext; + unsigned long al_flags = 0; + + spin_lock_irq(&mdev->al_lock); + bm_ext = (struct bm_extent *) + lc_find(mdev->resync, enr/AL_EXT_PER_BM_SECT); + if (unlikely(bm_ext != NULL)) { + if (test_bit(BME_NO_WRITES, &bm_ext->flags)) { + spin_unlock_irq(&mdev->al_lock); + return NULL; + } + } + al_ext = lc_get(mdev->act_log, enr); + al_flags = mdev->act_log->flags; + spin_unlock_irq(&mdev->al_lock); + + /* + if (!al_ext) { + if (al_flags & LC_STARVING) + DRBD_WARN("Have to wait for LRU element (AL too small?)\n"); + if (al_flags & LC_DIRTY) + DRBD_WARN("Ongoing AL update (AL device too slow?)\n"); + } + */ + + return al_ext; +} + +/* FIXME + * this should be able to return failure when meta data update has failed. + */ +void drbd_al_begin_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = (sector >> (AL_EXTENT_SIZE_B-9)); + struct lc_element *al_ext; + struct update_al_work al_work; + + D_ASSERT(atomic_read(&mdev->local_cnt) > 0); + + MTRACE(TraceTypeALExts, TraceLvlMetrics, + INFO("al_begin_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n", + (unsigned long long) sector, enr, + (int)BM_SECT_TO_EXT(sector)); + ); + + wait_event(mdev->al_wait, (al_ext = _al_get(mdev, enr)) ); + + if (al_ext->lc_number != enr) { + /* drbd_al_write_transaction(mdev,al_ext,enr); + generic_make_request() are serialized on the + current->bio_tail list now. Therefore we have + to deligate writing something to AL to the + worker thread. */ + init_completion(&al_work.event); + al_work.al_ext = al_ext; + al_work.enr = enr; + al_work.old_enr = al_ext->lc_number; + al_work.w.cb = w_al_write_transaction; + drbd_queue_work_front(&mdev->data.work, &al_work.w); + wait_for_completion(&al_work.event); + + mdev->al_writ_cnt++; + + /* + DUMPI(al_ext->lc_number); + DUMPI(mdev->act_log->new_number); + */ + spin_lock_irq(&mdev->al_lock); + lc_changed(mdev->act_log, al_ext); + spin_unlock_irq(&mdev->al_lock); + wake_up(&mdev->al_wait); + } +} + +void drbd_al_complete_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = (sector >> (AL_EXTENT_SIZE_B-9)); + struct lc_element *extent; + unsigned long flags; + + MTRACE(TraceTypeALExts, TraceLvlMetrics, + INFO("al_complete_io( sec=%llus (al_enr=%u) (rs_enr=%d) )\n", + (unsigned long long) sector, enr, + (int)BM_SECT_TO_EXT(sector)); + ); + + spin_lock_irqsave(&mdev->al_lock, flags); + + extent = lc_find(mdev->act_log, enr); + + if (!extent) { + spin_unlock_irqrestore(&mdev->al_lock, flags); + ERR("al_complete_io() called on inactive extent %u\n", enr); + return; + } + + if (lc_put(mdev->act_log, extent) == 0) + wake_up(&mdev->al_wait); + + spin_unlock_irqrestore(&mdev->al_lock, flags); +} + +int +w_al_write_transaction(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct update_al_work *aw = (struct update_al_work*)w; + struct lc_element *updated = aw->al_ext; + const unsigned int new_enr = aw->enr; + const unsigned int evicted = aw->old_enr; + + struct al_transaction* buffer; + sector_t sector; + int i,n,mx; + unsigned int extent_nr; + u32 xor_sum=0; + + if (!inc_local(mdev)) { + ERR("inc_local() failed in w_al_write_transaction\n"); + complete(&((struct update_al_work*)w)->event); + return 1; + } + /* do we have to do a bitmap write, first? + * TODO reduce maximum latency: + * submit both bios, then wait for both, + * instead of doing two synchronous sector writes. */ + if (mdev->state.conn < Connected && evicted != LC_FREE) + drbd_bm_write_sect(mdev, evicted/AL_EXT_PER_BM_SECT); + + down(&mdev->md_io_mutex); /* protects md_io_buffer, al_tr_cycle, ... */ + buffer = (struct al_transaction *)page_address(mdev->md_io_page); + + buffer->magic = __constant_cpu_to_be32(DRBD_MAGIC); + buffer->tr_number = cpu_to_be32(mdev->al_tr_number); + + n = lc_index_of(mdev->act_log, updated); + + buffer->updates[0].pos = cpu_to_be32(n); + buffer->updates[0].extent = cpu_to_be32(new_enr); + + xor_sum ^= new_enr; + + mx = min_t(int, AL_EXTENTS_PT, + mdev->act_log->nr_elements - mdev->al_tr_cycle); + for (i = 0; i < mx; i++) { + extent_nr = lc_entry(mdev->act_log, + mdev->al_tr_cycle+i)->lc_number; + buffer->updates[i+1].pos = cpu_to_be32(mdev->al_tr_cycle+i); + buffer->updates[i+1].extent = cpu_to_be32(extent_nr); + xor_sum ^= extent_nr; + } + for (; i < AL_EXTENTS_PT; i++) { + buffer->updates[i+1].pos = __constant_cpu_to_be32(-1); + buffer->updates[i+1].extent = __constant_cpu_to_be32(LC_FREE); + xor_sum ^= LC_FREE; + } + mdev->al_tr_cycle += AL_EXTENTS_PT; + if (mdev->al_tr_cycle >= mdev->act_log->nr_elements) + mdev->al_tr_cycle = 0; + + buffer->xor_sum = cpu_to_be32(xor_sum); + + sector = mdev->bc->md.md_offset + + mdev->bc->md.al_offset + mdev->al_tr_pos; + + if (!drbd_md_sync_page_io(mdev, mdev->bc, sector, WRITE)) { + drbd_chk_io_error(mdev, 1, TRUE); + drbd_io_error(mdev, TRUE); + } + + if (++mdev->al_tr_pos > + div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT)) + mdev->al_tr_pos = 0; + + D_ASSERT(mdev->al_tr_pos < MD_AL_MAX_SIZE); + mdev->al_tr_number++; + + up(&mdev->md_io_mutex); + + complete(&((struct update_al_work *)w)->event); + dec_local(mdev); + + return 1; +} + +/** + * drbd_al_read_tr: Reads a single transaction record form the + * on disk activity log. + * Returns -1 on IO error, 0 on checksum error and 1 if it is a valid + * record. + */ +STATIC int drbd_al_read_tr(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev, + struct al_transaction *b, + int index) +{ + sector_t sector; + int rv, i; + u32 xor_sum = 0; + + sector = bdev->md.md_offset + bdev->md.al_offset + index; + + /* Dont process error normally, + * as this is done before disk is atached! */ + if (!drbd_md_sync_page_io(mdev, bdev, sector, READ)) + return -1; + + rv = ( be32_to_cpu(b->magic) == DRBD_MAGIC ); + + for (i = 0; i < AL_EXTENTS_PT+1; i++) + xor_sum ^= be32_to_cpu(b->updates[i].extent); + rv &= (xor_sum == be32_to_cpu(b->xor_sum)); + + return rv; +} + +/** + * drbd_al_read_log: Restores the activity log from its on disk + * representation. Returns 1 on success, returns 0 when + * reading the log failed due to IO errors. + */ +int drbd_al_read_log(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) +{ + struct al_transaction *buffer; + int i; + int rv; + int mx; + int cnr; + int active_extents = 0; + int transactions = 0; + int overflow = 0; + int from = -1; + int to = -1; + u32 from_tnr = -1; + u32 to_tnr = 0; + + mx = div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT); + + /* lock out all other meta data io for now, + * and make sure the page is mapped. + */ + down(&mdev->md_io_mutex); + buffer = page_address(mdev->md_io_page); + + /* Find the valid transaction in the log */ + for (i = 0; i <= mx; i++) { + rv = drbd_al_read_tr(mdev, bdev, buffer, i); + if (rv == 0) + continue; + if (rv == -1) { + up(&mdev->md_io_mutex); + return 0; + } + cnr = be32_to_cpu(buffer->tr_number); + /* INFO("index %d valid tnr=%d\n",i,cnr); */ + + if (cnr == -1) + overflow = 1; + + if (cnr < from_tnr && !overflow) { + from = i; + from_tnr = cnr; + } + if (cnr > to_tnr) { + to = i; + to_tnr = cnr; + } + } + + if (from == -1 || to == -1) { + DRBD_WARN("No usable activity log found.\n"); + + up(&mdev->md_io_mutex); + return 1; + } + + /* Read the valid transactions. + * INFO("Reading from %d to %d.\n",from,to); */ + i = from; + while (1) { + int j, pos; + unsigned int extent_nr; + unsigned int trn; + + rv = drbd_al_read_tr(mdev, bdev, buffer, i); + ERR_IF(rv == 0) goto cancel; + if (rv == -1) { + up(&mdev->md_io_mutex); + return 0; + } + + trn = be32_to_cpu(buffer->tr_number); + + spin_lock_irq(&mdev->al_lock); + + /* This loop runs backwards because in the cyclic + elements there might be an old version of the + updated element (in slot 0). So the element in slot 0 + can overwrite old versions. */ + for (j = AL_EXTENTS_PT; j >= 0; j--) { + pos = be32_to_cpu(buffer->updates[j].pos); + extent_nr = be32_to_cpu(buffer->updates[j].extent); + + if (extent_nr == LC_FREE) + continue; + + lc_set(mdev->act_log, extent_nr, pos); + active_extents++; + } + spin_unlock_irq(&mdev->al_lock); + + transactions++; + +cancel: + if (i == to) + break; + i++; + if (i > mx) + i = 0; + } + + mdev->al_tr_number = to_tnr+1; + mdev->al_tr_pos = to; + if (++mdev->al_tr_pos > + div_ceil(mdev->act_log->nr_elements, AL_EXTENTS_PT)) + mdev->al_tr_pos = 0; + + /* ok, we are done with it */ + up(&mdev->md_io_mutex); + + INFO("Found %d transactions (%d active extents) in activity log.\n", + transactions, active_extents); + + return 1; +} + +struct drbd_atodb_wait { + atomic_t count; + struct completion io_done; + struct drbd_conf *mdev; + int error; +}; + +STATIC BIO_ENDIO_TYPE atodb_endio BIO_ENDIO_ARGS(struct bio *bio, int error) +{ + struct drbd_atodb_wait *wc = bio->bi_private; + struct drbd_conf *mdev = wc->mdev; + struct page *page; + int uptodate = bio_flagged(bio, BIO_UPTODATE); + + BIO_ENDIO_FN_START; + /* strange behaviour of some lower level drivers... + * fail the request by clearing the uptodate flag, + * but do not return any error?! + * do we want to DRBD_WARN() on this? */ + if (!error && !uptodate) + error = -EIO; + + /* corresponding drbd_io_error is in drbd_al_to_on_disk_bm */ + drbd_chk_io_error(mdev, error, TRUE); + if (error && wc->error == 0) + wc->error = error; + + if (atomic_dec_and_test(&wc->count)) + complete(&wc->io_done); + + page = bio->bi_io_vec[0].bv_page; + put_page(page); + bio_put(bio); + mdev->bm_writ_cnt++; + dec_local(mdev); + + BIO_ENDIO_FN_RETURN; +} + +#define S2W(s) ((s)<<(BM_EXT_SIZE_B-BM_BLOCK_SIZE_B-LN2_BPL)) +/* activity log to on disk bitmap -- prepare bio unless that sector + * is already covered by previously prepared bios */ +STATIC int atodb_prepare_unless_covered(struct drbd_conf *mdev, + struct bio **bios, + unsigned int enr, + struct drbd_atodb_wait *wc) __must_hold(local) +{ + struct bio *bio; + struct page *page; + sector_t on_disk_sector = enr + mdev->bc->md.md_offset + + mdev->bc->md.bm_offset; + unsigned int page_offset = PAGE_SIZE; + int offset; + int i = 0; + int err = -ENOMEM; + + /* Check if that enr is already covered by an already created bio. + * Caution, bios[] is not NULL terminated, + * but only initialized to all NULL. + * For completely scattered activity log, + * the last invocation iterates over all bios, + * and finds the last NULL entry. + */ + while ( (bio = bios[i]) ) { + if (bio->bi_sector == on_disk_sector) + return 0; + i++; + } + /* bios[i] == NULL, the next not yet used slot */ + + bio = bio_alloc(GFP_KERNEL, 1); + if (bio == NULL) + return -ENOMEM; + + if (i > 0) { + const struct bio_vec *prev_bv = bios[i-1]->bi_io_vec; + page_offset = prev_bv->bv_offset + prev_bv->bv_len; + page = prev_bv->bv_page; + } + if (page_offset == PAGE_SIZE) { + page = alloc_page(__GFP_HIGHMEM); + if (page == NULL) + goto out_bio_put; + page_offset = 0; + } else { + get_page(page); + } + + offset = S2W(enr); + drbd_bm_get_lel( mdev, offset, + min_t(size_t, S2W(1), drbd_bm_words(mdev) - offset), + kmap(page) + page_offset ); + kunmap(page); + + bio->bi_private = wc; + bio->bi_end_io = atodb_endio; + bio->bi_bdev = mdev->bc->md_bdev; + bio->bi_sector = on_disk_sector; + + if (bio_add_page(bio, page, MD_HARDSECT, page_offset) != MD_HARDSECT) + goto out_put_page; + + atomic_inc(&wc->count); + /* we already know that we may do this... + * inc_local_if_state(mdev,Attaching); + * just get the extra reference, so that the local_cnt reflects + * the number of pending IO requests DRBD at its backing device. + */ + atomic_inc(&mdev->local_cnt); + + bios[i] = bio; + + return 0; + +out_put_page: + err = -EINVAL; + put_page(page); +out_bio_put: + bio_put(bio); + return err; +} + +/** + * drbd_al_to_on_disk_bm: + * Writes the areas of the bitmap which are covered by the AL. + * called when we detach (unconfigure) local storage, + * or when we go from Primary to Secondary state. + */ +void drbd_al_to_on_disk_bm(struct drbd_conf *mdev) +{ + int i, nr_elements; + unsigned int enr; + struct bio **bios; + struct drbd_atodb_wait wc; + + ERR_IF (!inc_local_if_state(mdev, Attaching)) + return; /* sorry, I don't have any act_log etc... */ + + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + + nr_elements = mdev->act_log->nr_elements; + + bios = kzalloc(sizeof(struct bio *) * nr_elements, GFP_KERNEL); + if (!bios) + goto submit_one_by_one; + + atomic_set(&wc.count, 0); + init_completion(&wc.io_done); + wc.mdev = mdev; + wc.error = 0; + + for (i = 0; i < nr_elements; i++) { + enr = lc_entry(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + /* next statement also does atomic_inc wc.count and local_cnt */ + if (atodb_prepare_unless_covered(mdev, bios, + enr/AL_EXT_PER_BM_SECT, + &wc)) + goto free_bios_submit_one_by_one; + } + + /* unneccessary optimization? */ + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + /* all prepared, submit them */ + for (i = 0; i < nr_elements; i++) { + if (bios[i] == NULL) + break; + if (FAULT_ACTIVE( mdev, DRBD_FAULT_MD_WR )) { + bios[i]->bi_rw = WRITE; + bio_endio(bios[i], -EIO); + } else { + submit_bio(WRITE, bios[i]); + } + } + + drbd_blk_run_queue(bdev_get_queue(mdev->bc->md_bdev)); + + /* In case we did not submit a single IO do not wait for + * them to complete. ( Because we would wait forever here. ) + * + * In case we had IOs and they are already complete, there + * is not point in waiting anyways. + * Therefore this if () ... */ + if (atomic_read(&wc.count)) { + wait_for_completion(&wc.io_done); + /* flush bitmap to stable storage */ + if (!test_bit(MD_NO_BARRIER, &mdev->flags)) + blkdev_issue_flush(mdev->bc->md_bdev, NULL); + } + + dec_local(mdev); + + if (wc.error) + drbd_io_error(mdev, TRUE); + kfree(bios); + return; + + free_bios_submit_one_by_one: + /* free everything by calling the endio callback directly. */ + for (i = 0; i < nr_elements && bios[i]; i++) + bio_endio(bios[i], 0); + + kfree(bios); + + submit_one_by_one: + DRBD_WARN("Using the slow drbd_al_to_on_disk_bm()\n"); + + for (i = 0; i < mdev->act_log->nr_elements; i++) { + enr = lc_entry(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + /* Really slow: if we have al-extents 16..19 active, + * sector 4 will be written four times! Synchronous! */ + drbd_bm_write_sect(mdev, enr/AL_EXT_PER_BM_SECT ); + } + + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + dec_local(mdev); +} + +/** + * drbd_al_apply_to_bm: Sets the bits in the bitmap that are described + * by the active extents of the AL. + */ +void drbd_al_apply_to_bm(struct drbd_conf *mdev) +{ + unsigned int enr; + unsigned long add = 0; + char ppb[10]; + int i; + + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + + for (i = 0; i < mdev->act_log->nr_elements; i++) { + enr = lc_entry(mdev->act_log, i)->lc_number; + if (enr == LC_FREE) + continue; + add += drbd_bm_ALe_set_all(mdev, enr); + } + + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + INFO("Marked additional %s as out-of-sync based on AL.\n", + ppsize(ppb, Bit2KB(add))); +} + +static inline int _try_lc_del(struct drbd_conf *mdev, struct lc_element *al_ext) +{ + int rv; + + spin_lock_irq(&mdev->al_lock); + rv = (al_ext->refcnt == 0); + if (likely(rv)) lc_del(mdev->act_log, al_ext); + spin_unlock_irq(&mdev->al_lock); + + MTRACE(TraceTypeALExts,TraceLvlMetrics, + if(unlikely(!rv)) + INFO("Waiting for extent in drbd_al_shrink()\n"); + ); + + return rv; +} + +/** + * drbd_al_shrink: Removes all active extents form the AL. (but does not + * write any transactions) + * You need to lock mdev->act_log with lc_try_lock() / lc_unlock() + */ +void drbd_al_shrink(struct drbd_conf *mdev) +{ + struct lc_element *al_ext; + int i; + + D_ASSERT( test_bit(__LC_DIRTY, &mdev->act_log->flags) ); + + for (i = 0; i < mdev->act_log->nr_elements; i++) { + al_ext = lc_entry(mdev->act_log, i); + if (al_ext->lc_number == LC_FREE) + continue; + wait_event(mdev->al_wait, _try_lc_del(mdev, al_ext)); + } + + wake_up(&mdev->al_wait); +} + +STATIC int w_update_odbm(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct update_odbm_work *udw = (struct update_odbm_work *)w; + + if (!inc_local(mdev)) { + if (DRBD_ratelimit(5*HZ, 5)) + DRBD_WARN("Can not update on disk bitmap, local IO disabled.\n"); + return 1; + } + + drbd_bm_write_sect(mdev, udw->enr ); + dec_local(mdev); + + kfree(udw); + + if (drbd_bm_total_weight(mdev) <= mdev->rs_failed) { + switch (mdev->state.conn) { + case SyncSource: case SyncTarget: + case PausedSyncS: case PausedSyncT: + drbd_resync_finished(mdev); + default: /* nothing to do */; + } + } + drbd_bcast_sync_progress(mdev); + + return 1; +} + + +/* ATTENTION. The AL's extents are 4MB each, while the extents in the + * resync LRU-cache are 16MB each. + * The caller of this function has to hold an inc_local() reference. + * + * TODO will be obsoleted once we have a caching lru of the on disk bitmap + */ +STATIC void drbd_try_clear_on_disk_bm(struct drbd_conf *mdev, sector_t sector, + int count, int success) +{ + struct bm_extent *ext; + struct update_odbm_work *udw; + + unsigned int enr; + + MUST_HOLD(&mdev->al_lock); + D_ASSERT(atomic_read(&mdev->local_cnt)); + + /* I simply assume that a sector/size pair never crosses + * a 16 MB extent border. (Currently this is true...) */ + enr = BM_SECT_TO_EXT(sector); + + ext = (struct bm_extent *) lc_get(mdev->resync, enr); + if (ext) { + if (ext->lce.lc_number == enr) { + if (success) + ext->rs_left -= count; + else + ext->rs_failed += count; + if (ext->rs_left < ext->rs_failed) { + ERR("BAD! sector=%llus enr=%u rs_left=%d " + "rs_failed=%d count=%d\n", + (unsigned long long)sector, + ext->lce.lc_number, ext->rs_left, + ext->rs_failed, count); + dump_stack(); + /* FIXME brrrgs. should never happen! */ + lc_put(mdev->resync, &ext->lce); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return; + } + } else { + /* Normally this element should be in the cache, + * since drbd_rs_begin_io() pulled it already in. + * + * But maybe an application write finished, and we set + * something in outside the resync lru_cache in sync. + */ + int rs_left = drbd_bm_e_weight(mdev, enr); + if (ext->flags != 0) { + DRBD_WARN("changing resync lce: %d[%u;%02lx]" + " -> %d[%u;00]\n", + ext->lce.lc_number, ext->rs_left, + ext->flags, enr, rs_left); + ext->flags = 0; + } + if (ext->rs_failed) { + DRBD_WARN("Kicking resync_lru element enr=%u " + "out with rs_failed=%d\n", + ext->lce.lc_number, ext->rs_failed); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); + } + ext->rs_left = rs_left; + ext->rs_failed = success ? 0 : count; + lc_changed(mdev->resync, &ext->lce); + } + lc_put(mdev->resync, &ext->lce); + /* no race, we are within the al_lock! */ + + if (ext->rs_left == ext->rs_failed) { + ext->rs_failed = 0; + + udw = kmalloc(sizeof(*udw), GFP_ATOMIC); + if (udw) { + udw->enr = ext->lce.lc_number; + udw->w.cb = w_update_odbm; + drbd_queue_work_front(&mdev->data.work, &udw->w); + } else { + DRBD_WARN("Could not kmalloc an udw\n"); + set_bit(WRITE_BM_AFTER_RESYNC, &mdev->flags); + } + } + } else { + ERR("lc_get() failed! locked=%d/%d flags=%lu\n", + mdev->resync_locked, + mdev->resync->nr_elements, + mdev->resync->flags); + } +} + +/* clear the bit corresponding to the piece of storage in question: + * size byte of data starting from sector. Only clear a bits of the affected + * one ore more _aligned_ BM_BLOCK_SIZE blocks. + * + * called by worker on SyncTarget and receiver on SyncSource. + * + */ +void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size, + const char *file, const unsigned int line) +{ + /* Is called from worker and receiver context _only_ */ + unsigned long sbnr, ebnr, lbnr; + unsigned long count = 0; + sector_t esector, nr_sectors; + int wake_up = 0; + unsigned long flags; + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("drbd_set_in_sync: sector=%llus size=%d nonsense!\n", + (unsigned long long)sector, size); + return; + } + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size>>9) -1; + + ERR_IF(sector >= nr_sectors) return; + ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1); + + lbnr = BM_SECT_TO_BIT(nr_sectors-1); + + /* we clear it (in sync). + * round up start sector, round down end sector. we make sure we only + * clear full, alligned, BM_BLOCK_SIZE (4K) blocks */ + if (unlikely(esector < BM_SECT_PER_BIT-1)) + return; + if (unlikely(esector == (nr_sectors-1))) + ebnr = lbnr; + else + ebnr = BM_SECT_TO_BIT(esector - (BM_SECT_PER_BIT-1)); + sbnr = BM_SECT_TO_BIT(sector + BM_SECT_PER_BIT-1); + + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_set_in_sync: sector=%llus size=%u sbnr=%lu ebnr=%lu\n", + (unsigned long long)sector, size, sbnr, ebnr); + ); + + if (sbnr > ebnr) + return; + + /* + * ok, (capacity & 7) != 0 sometimes, but who cares... + * we count rs_{total,left} in bits, not sectors. + */ + spin_lock_irqsave(&mdev->al_lock, flags); + count = drbd_bm_clear_bits(mdev, sbnr, ebnr); + if (count) { + /* we need the lock for drbd_try_clear_on_disk_bm */ + if (jiffies - mdev->rs_mark_time > HZ*10) { + /* should be roling marks, + * but we estimate only anyways. */ + if ( mdev->rs_mark_left != drbd_bm_total_weight(mdev) && + mdev->state.conn != PausedSyncT && + mdev->state.conn != PausedSyncS ) { + mdev->rs_mark_time = jiffies; + mdev->rs_mark_left = drbd_bm_total_weight(mdev); + } + } + if (inc_local(mdev)) { + drbd_try_clear_on_disk_bm(mdev, sector, count, TRUE); + dec_local(mdev); + } + /* just wake_up unconditional now, various lc_chaged(), + * lc_put() in drbd_try_clear_on_disk_bm(). */ + wake_up = 1; + } + spin_unlock_irqrestore(&mdev->al_lock, flags); + if (wake_up) + wake_up(&mdev->al_wait); +} + +/* + * this is intended to set one request worth of data out of sync. + * affects at least 1 bit, + * and at most 1+DRBD_MAX_SEGMENT_SIZE/BM_BLOCK_SIZE bits. + * + * called by tl_clear and drbd_send_dblock (==drbd_make_request). + * so this can be _any_ process. + */ +void __drbd_set_out_of_sync(struct drbd_conf *mdev, sector_t sector, int size, + const char *file, const unsigned int line) +{ + unsigned long sbnr, ebnr, lbnr, flags; + sector_t esector, nr_sectors; + unsigned int enr, count; + struct bm_extent* ext; + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("sector: %llus, size: %d\n", + (unsigned long long)sector, size); + return; + } + + if (!inc_local(mdev)) + return; /* no disk, no metadata, no bitmap to set bits in */ + + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size>>9) -1; + + ERR_IF(sector >= nr_sectors) + goto out; + ERR_IF(esector >= nr_sectors) + esector = (nr_sectors-1); + + lbnr = BM_SECT_TO_BIT(nr_sectors-1); + + /* we set it out of sync, + * we do not need to round anything here */ + sbnr = BM_SECT_TO_BIT(sector); + ebnr = BM_SECT_TO_BIT(esector); + + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_set_out_of_sync: sector=%llus size=%u " + "sbnr=%lu ebnr=%lu\n", + (unsigned long long)sector, size, sbnr, ebnr); + ); + + /* ok, (capacity & 7) != 0 sometimes, but who cares... + * we count rs_{total,left} in bits, not sectors. */ + spin_lock_irqsave(&mdev->al_lock, flags); + count = drbd_bm_set_bits(mdev, sbnr, ebnr); + + enr = BM_SECT_TO_EXT(sector); + ext = (struct bm_extent *) lc_find(mdev->resync, enr); + if (ext) + ext->rs_left += count; + spin_unlock_irqrestore(&mdev->al_lock, flags); + +out: + dec_local(mdev); +} + +static inline +struct bm_extent *_bme_get(struct drbd_conf *mdev, unsigned int enr) +{ + struct bm_extent *bm_ext; + int wakeup = 0; + unsigned long rs_flags; + + spin_lock_irq(&mdev->al_lock); + if (mdev->resync_locked > mdev->resync->nr_elements/2) { + spin_unlock_irq(&mdev->al_lock); + return NULL; + } + bm_ext = (struct bm_extent *) lc_get(mdev->resync, enr); + if (bm_ext) { + if (bm_ext->lce.lc_number != enr) { + bm_ext->rs_left = drbd_bm_e_weight(mdev, enr); + bm_ext->rs_failed = 0; + lc_changed(mdev->resync, (struct lc_element *)bm_ext); + wakeup = 1; + } + if (bm_ext->lce.refcnt == 1) + mdev->resync_locked++; + set_bit(BME_NO_WRITES, &bm_ext->flags); + } + rs_flags = mdev->resync->flags; + spin_unlock_irq(&mdev->al_lock); + if (wakeup) + wake_up(&mdev->al_wait); + + if (!bm_ext) { + if (rs_flags & LC_STARVING) + DRBD_WARN("Have to wait for element" + " (resync LRU too small?)\n"); + BUG_ON(rs_flags & LC_DIRTY); + } + + return bm_ext; +} + +static inline int _is_in_al(struct drbd_conf *mdev, unsigned int enr) +{ + struct lc_element *al_ext; + int rv = 0; + + spin_lock_irq(&mdev->al_lock); + if (unlikely(enr == mdev->act_log->new_number)) rv = 1; + else { + al_ext = lc_find(mdev->act_log, enr); + if (al_ext) { + if (al_ext->refcnt) + rv = 1; + } + } + spin_unlock_irq(&mdev->al_lock); + + /* + if (unlikely(rv)) { + INFO("Delaying sync read until app's write is done\n"); + } + */ + return rv; +} + +/** + * drbd_rs_begin_io: Gets an extent in the resync LRU cache and sets it + * to BME_LOCKED. + * + * @sector: The sector number + * + * sleeps on al_wait. + * returns 1 if successful. + * returns 0 if interrupted. + */ +int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = BM_SECT_TO_EXT(sector); + struct bm_extent *bm_ext; + int i, sig; + + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("drbd_rs_begin_io: sector=%llus (rs_end=%d)\n", + (unsigned long long)sector, enr); + ); + + sig = wait_event_interruptible( mdev->al_wait, + (bm_ext = _bme_get(mdev, enr)) ); + if (sig) + return 0; + + if (test_bit(BME_LOCKED, &bm_ext->flags)) return 1; + + for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { + sig = wait_event_interruptible( mdev->al_wait, + !_is_in_al(mdev, enr*AL_EXT_PER_BM_SECT+i) ); + if (sig) { + spin_lock_irq(&mdev->al_lock); + if ( lc_put(mdev->resync, &bm_ext->lce) == 0 ) { + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_locked--; + wake_up(&mdev->al_wait); + } + spin_unlock_irq(&mdev->al_lock); + return 0; + } + } + + set_bit(BME_LOCKED, &bm_ext->flags); + + return 1; +} + +/** + * drbd_try_rs_begin_io: Gets an extent in the resync LRU cache, sets it + * to BME_NO_WRITES, then tries to set it to BME_LOCKED. + * + * @sector: The sector number + * + * does not sleep. + * returns zero if we could set BME_LOCKED and can proceed, + * -EAGAIN if we need to try again. + */ +int drbd_try_rs_begin_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = BM_SECT_TO_EXT(sector); + const unsigned int al_enr = enr*AL_EXT_PER_BM_SECT; + struct bm_extent *bm_ext; + int i; + + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("drbd_try_rs_begin_io: sector=%llus\n", + (unsigned long long)sector); + ); + + spin_lock_irq(&mdev->al_lock); + if (mdev->resync_wenr != LC_FREE && mdev->resync_wenr != enr) { + /* in case you have very heavy scattered io, it may + * stall the syncer undefined if we giveup the ref count + * when we try again and requeue. + * + * if we don't give up the refcount, but the next time + * we are scheduled this extent has been "synced" by new + * application writes, we'd miss the lc_put on the + * extent we keept the refcount on. + * so we remembered which extent we had to try agin, and + * if the next requested one is something else, we do + * the lc_put here... + * we also have to wake_up + */ + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("dropping %u, aparently got 'synced' " + "by application io\n", mdev->resync_wenr); + ); + bm_ext = (struct bm_extent *) + lc_find(mdev->resync, mdev->resync_wenr); + if (bm_ext) { + D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags)); + D_ASSERT(test_bit(BME_NO_WRITES, &bm_ext->flags)); + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_wenr = LC_FREE; + if (lc_put(mdev->resync, &bm_ext->lce) == 0) + mdev->resync_locked--; + wake_up(&mdev->al_wait); + } else { + ALERT("LOGIC BUG\n"); + } + } + bm_ext = (struct bm_extent *)lc_try_get(mdev->resync, enr); + if (bm_ext) { + if (test_bit(BME_LOCKED, &bm_ext->flags)) + goto proceed; + if (!test_and_set_bit(BME_NO_WRITES, &bm_ext->flags)) { + mdev->resync_locked++; + } else { + /* we did set the BME_NO_WRITES, + * but then could not set BME_LOCKED, + * so we tried again. + * drop the extra reference. */ + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("dropping extra reference on %u\n", enr); + ); + bm_ext->lce.refcnt--; + D_ASSERT(bm_ext->lce.refcnt > 0); + } + goto check_al; + } else { + if (mdev->resync_locked > mdev->resync->nr_elements-3) { + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("resync_locked = %u!\n", mdev->resync_locked); + ); + goto try_again; + } + bm_ext = (struct bm_extent *)lc_get(mdev->resync, enr); + if (!bm_ext) { + const unsigned long rs_flags = mdev->resync->flags; + if (rs_flags & LC_STARVING) + DRBD_WARN("Have to wait for element" + " (resync LRU too small?)\n"); + BUG_ON(rs_flags & LC_DIRTY); + goto try_again; + } + if (bm_ext->lce.lc_number != enr) { + bm_ext->rs_left = drbd_bm_e_weight(mdev, enr); + bm_ext->rs_failed = 0; + lc_changed(mdev->resync, (struct lc_element *)bm_ext); + wake_up(&mdev->al_wait); + D_ASSERT(test_bit(BME_LOCKED, &bm_ext->flags) == 0); + } + set_bit(BME_NO_WRITES, &bm_ext->flags); + D_ASSERT(bm_ext->lce.refcnt == 1); + mdev->resync_locked++; + goto check_al; + } +check_al: + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("checking al for %u\n", enr); + ); + for (i = 0; i < AL_EXT_PER_BM_SECT; i++) { + if (unlikely(al_enr+i == mdev->act_log->new_number)) + goto try_again; + if (lc_is_used(mdev->act_log, al_enr+i)) + goto try_again; + } + set_bit(BME_LOCKED, &bm_ext->flags); +proceed: + mdev->resync_wenr = LC_FREE; + spin_unlock_irq(&mdev->al_lock); + return 0; + +try_again: + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("need to try again for %u\n", enr); + ); + if (bm_ext) + mdev->resync_wenr = enr; + spin_unlock_irq(&mdev->al_lock); + return -EAGAIN; +} + +void drbd_rs_complete_io(struct drbd_conf *mdev, sector_t sector) +{ + unsigned int enr = BM_SECT_TO_EXT(sector); + struct bm_extent *bm_ext; + unsigned long flags; + + MTRACE(TraceTypeResync, TraceLvlAll, + INFO("drbd_rs_complete_io: sector=%llus (rs_enr=%d)\n", + (long long)sector, enr); + ); + + spin_lock_irqsave(&mdev->al_lock, flags); + bm_ext = (struct bm_extent *) lc_find(mdev->resync, enr); + if (!bm_ext) { + spin_unlock_irqrestore(&mdev->al_lock, flags); + ERR("drbd_rs_complete_io() called, but extent not found\n"); + return; + } + + if (bm_ext->lce.refcnt == 0) { + spin_unlock_irqrestore(&mdev->al_lock, flags); + ERR("drbd_rs_complete_io(,%llu [=%u]) called, " + "but refcnt is 0!?\n", + (unsigned long long)sector, enr); + return; + } + + if ( lc_put(mdev->resync, (struct lc_element *)bm_ext) == 0 ) { + clear_bit(BME_LOCKED, &bm_ext->flags); + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_locked--; + wake_up(&mdev->al_wait); + } + + spin_unlock_irqrestore(&mdev->al_lock, flags); +} + +/** + * drbd_rs_cancel_all: Removes extents from the resync LRU. Even + * if they are BME_LOCKED. + */ +void drbd_rs_cancel_all(struct drbd_conf *mdev) +{ + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_rs_cancel_all\n"); + ); + + spin_lock_irq(&mdev->al_lock); + + if (inc_local_if_state(mdev,Failed)) { /* Makes sure ->resync is there. */ + lc_reset(mdev->resync); + dec_local(mdev); + } + mdev->resync_locked = 0; + mdev->resync_wenr = LC_FREE; + spin_unlock_irq(&mdev->al_lock); + wake_up(&mdev->al_wait); +} + +/** + * drbd_rs_del_all: Gracefully remove all extents from the resync LRU. + * there may be still a reference hold by someone. In that case this function + * returns -EAGAIN. + * In case all elements got removed it returns zero. + */ +int drbd_rs_del_all(struct drbd_conf *mdev) +{ + struct bm_extent *bm_ext; + int i; + + MTRACE(TraceTypeResync, TraceLvlMetrics, + INFO("drbd_rs_del_all\n"); + ); + + spin_lock_irq(&mdev->al_lock); + + if (inc_local_if_state(mdev, Failed)) { + /* ok, ->resync is there. */ + for (i = 0; i < mdev->resync->nr_elements; i++) { + bm_ext = (struct bm_extent *) lc_entry(mdev->resync, i); + if (bm_ext->lce.lc_number == LC_FREE) + continue; + if (bm_ext->lce.lc_number == mdev->resync_wenr) { + INFO("dropping %u in drbd_rs_del_all, aparently" + " got 'synced' by application io\n", + mdev->resync_wenr); + D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags)); + D_ASSERT(test_bit(BME_NO_WRITES, &bm_ext->flags)); + clear_bit(BME_NO_WRITES, &bm_ext->flags); + mdev->resync_wenr = LC_FREE; + lc_put(mdev->resync, &bm_ext->lce); + } + if (bm_ext->lce.refcnt != 0) { + INFO("Retrying drbd_rs_del_all() later. " + "refcnt=%d\n", bm_ext->lce.refcnt); + dec_local(mdev); + spin_unlock_irq(&mdev->al_lock); + return -EAGAIN; + } + D_ASSERT(!test_bit(BME_LOCKED, &bm_ext->flags)); + D_ASSERT(!test_bit(BME_NO_WRITES, &bm_ext->flags)); + lc_del(mdev->resync, &bm_ext->lce); + } + D_ASSERT(mdev->resync->used == 0); + dec_local(mdev); + } + spin_unlock_irq(&mdev->al_lock); + + return 0; +} + +/* Record information on a failure to resync the specified blocks + * + * called on SyncTarget when resync write fails or NegRSDReply received + * + */ +void drbd_rs_failed_io(struct drbd_conf *mdev, sector_t sector, int size) +{ + /* Is called from worker and receiver context _only_ */ + unsigned long sbnr, ebnr, lbnr; + unsigned long count; + sector_t esector, nr_sectors; + int wake_up = 0; + + MTRACE(TraceTypeResync, TraceLvlSummary, + INFO("drbd_rs_failed_io: sector=%llus, size=%u\n", + (unsigned long long)sector, size); + ); + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("drbd_rs_failed_io: sector=%llus size=%d nonsense!\n", + (unsigned long long)sector, size); + return; + } + nr_sectors = drbd_get_capacity(mdev->this_bdev); + esector = sector + (size>>9) -1; + + ERR_IF(sector >= nr_sectors) return; + ERR_IF(esector >= nr_sectors) esector = (nr_sectors-1); + + lbnr = BM_SECT_TO_BIT(nr_sectors-1); + + /* + * round up start sector, round down end sector. we make sure we only + * handle full, alligned, BM_BLOCK_SIZE (4K) blocks */ + if (unlikely(esector < BM_SECT_PER_BIT-1)) + return; + if (unlikely(esector == (nr_sectors-1))) + ebnr = lbnr; + else + ebnr = BM_SECT_TO_BIT(esector - (BM_SECT_PER_BIT-1)); + sbnr = BM_SECT_TO_BIT(sector + BM_SECT_PER_BIT-1); + + if (sbnr > ebnr) + return; + + /* + * ok, (capacity & 7) != 0 sometimes, but who cares... + * we count rs_{total,left} in bits, not sectors. + */ + spin_lock_irq(&mdev->al_lock); + count = drbd_bm_count_bits(mdev, sbnr, ebnr); + if (count) { + mdev->rs_failed += count; + + if (inc_local(mdev)) { + drbd_try_clear_on_disk_bm(mdev, sector, count, FALSE); + dec_local(mdev); + } + + /* just wake_up unconditional now, various lc_chaged(), + * lc_put() in drbd_try_clear_on_disk_bm(). */ + wake_up = 1; + } + spin_unlock_irq(&mdev->al_lock); + if (wake_up) + wake_up(&mdev->al_wait); +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_buildtag.c +++ linux-2.6.28/ubuntu/drbd/drbd_buildtag.c @@ -0,0 +1,7 @@ +/* automatically generated. DO NOT EDIT. */ +#include +const char * drbd_buildtag(void) +{ + return "GIT-hash: 3e69822d3bb4920a8c1bfdf7d647169eba7d2eb4" + " build by phil@fat-tyre, 2008-05-30 12:59:17"; +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_nl.c +++ linux-2.6.28/ubuntu/drbd/drbd_nl.c @@ -0,0 +1,2197 @@ +/* +-*- linux-c -*- + drbd_nl.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include +#include +#include /* for fsync_bdev */ +#include +#include +#include +#include +#include +#include + +#include "drbd_int.h" +#include +#include + +/* see get_sb_bdev and bd_claim */ +static char *drbd_m_holder = "Hands off! this is DRBD's meta data device."; + +/* Generate the tag_list to struct functions */ +#define NL_PACKET(name, number, fields) \ +STATIC int name ## _from_tags (struct drbd_conf *mdev, \ + unsigned short *tags, struct name *arg) \ +{ \ + int tag; \ + int dlen; \ + \ + while ( (tag = *tags++) != TT_END ) { \ + dlen = *tags++; \ + switch ( tag_number(tag) ) { \ + fields \ + default: \ + if (tag & T_MANDATORY) { \ + ERR("Unknown tag: %d\n", tag_number(tag)); \ + return 0; \ + } \ + } \ + tags = (unsigned short *)((char *)tags + dlen); \ + } \ + return 1; \ +} +#define NL_INTEGER(pn, pr, member) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_INTEGER ); */ \ + arg->member = *(int *)(tags); \ + break; +#define NL_INT64(pn, pr, member) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_INT64 ); */ \ + arg->member = *(u64 *)(tags); \ + break; +#define NL_BIT(pn, pr, member) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_BIT ); */ \ + arg->member = *(char *)(tags) ? 1 : 0; \ + break; +#define NL_STRING(pn, pr, member, len) \ + case pn: /* D_ASSERT( tag_type(tag) == TT_STRING ); */ \ + arg->member ## _len = dlen; \ + memcpy(arg->member, tags, min_t(size_t, dlen, len)); \ + break; +#include "linux/drbd_nl.h" + +// Generate the struct to tag_list functions +#define NL_PACKET(name, number, fields) \ +STATIC unsigned short* \ +name ## _to_tags (struct drbd_conf *mdev, \ + struct name *arg, unsigned short *tags) \ +{ \ + fields \ + return tags; \ +} + +#define NL_INTEGER(pn, pr, member) \ + *tags++ = pn | pr | TT_INTEGER; \ + *tags++ = sizeof(int); \ + *(int *)tags = arg->member; \ + tags = (unsigned short *)((char *)tags+sizeof(int)); +#define NL_INT64(pn, pr, member) \ + *tags++ = pn | pr | TT_INT64; \ + *tags++ = sizeof(u64); \ + *(u64 *)tags = arg->member; \ + tags = (unsigned short *)((char *)tags+sizeof(u64)); +#define NL_BIT(pn, pr, member) \ + *tags++ = pn | pr | TT_BIT; \ + *tags++ = sizeof(char); \ + *(char *)tags = arg->member; \ + tags = (unsigned short *)((char *)tags+sizeof(char)); +#define NL_STRING(pn, pr, member, len) \ + *tags++ = pn | pr | TT_STRING; \ + *tags++ = arg->member ## _len; \ + memcpy(tags, arg->member, arg->member ## _len); \ + tags = (unsigned short *)((char *)tags + arg->member ## _len); +#include "linux/drbd_nl.h" + +void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name); +void drbd_nl_send_reply(struct cn_msg *, int); + +STATIC char *nl_packet_name(int packet_type) +{ +/* Generate packet type strings */ +#define NL_PACKET(name, number, fields) \ + [ P_ ## name ] = # name, +#define NL_INTEGER Argh! +#define NL_BIT Argh! +#define NL_INT64 Argh! +#define NL_STRING Argh! + + static char *nl_tag_name[P_nl_after_last_packet] = { +#include "linux/drbd_nl.h" + }; + + return (packet_type < sizeof(nl_tag_name)/sizeof(nl_tag_name[0])) ? + nl_tag_name[packet_type] : "*Unknown*"; +} + +STATIC void nl_trace_packet(void *data) +{ + struct cn_msg *req = data; + struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)req->data; + + printk(KERN_INFO "drbd%d: " + "Netlink: << %s (%d) - seq: %x, ack: %x, len: %x\n", + nlp->drbd_minor, + nl_packet_name(nlp->packet_type), + nlp->packet_type, + req->seq, req->ack, req->len); +} + +STATIC void nl_trace_reply(void *data) +{ + struct cn_msg *req = data; + struct drbd_nl_cfg_reply *nlp = (struct drbd_nl_cfg_reply *)req->data; + + printk(KERN_INFO "drbd%d: " + "Netlink: >> %s (%d) - seq: %x, ack: %x, len: %x\n", + nlp->minor, + nlp->packet_type == P_nl_after_last_packet? + "Empty-Reply" : nl_packet_name(nlp->packet_type), + nlp->packet_type, + req->seq, req->ack, req->len); +} + +int drbd_khelper(struct drbd_conf *mdev, char *cmd) +{ + char mb[12]; + char *argv[] = {usermode_helper, cmd, mb, NULL }; + static char *envp[] = { "HOME=/", + "TERM=linux", + "PATH=/sbin:/usr/sbin:/bin:/usr/bin", + NULL }; + + snprintf(mb, 12, "minor-%d", mdev_to_minor(mdev)); + + INFO("helper command: %s %s\n", usermode_helper, cmd); + + drbd_bcast_ev_helper(mdev, cmd); + return call_usermodehelper(usermode_helper, argv, envp, 1); +} + +enum drbd_disk_state drbd_try_outdate_peer(struct drbd_conf *mdev) +{ + char *ex_to_string; + int r; + enum drbd_disk_state nps; + enum fencing_policy fp; + + D_ASSERT(mdev->state.pdsk == DUnknown); + + if (inc_local_if_state(mdev, Consistent)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } else { + DRBD_WARN("Not outdating peer, I'm not even Consistent myself.\n"); + return mdev->state.pdsk; + } + + if (fp == Stonith) + _drbd_request_state(mdev, NS(susp,1), ChgWaitComplete); + + r = drbd_khelper(mdev, "outdate-peer"); + + switch ((r>>8) & 0xff) { + case 3: /* peer is inconsistent */ + ex_to_string = "peer is inconsistent or worse"; + nps = Inconsistent; + break; + case 4: + ex_to_string = "peer is outdated"; + nps = Outdated; + break; + case 5: /* peer was down, we will(have) create(d) a new UUID anyways... */ + /* If we would be more strict, we would return DUnknown here. */ + ex_to_string = "peer is unreachable, assumed to be dead"; + nps = Outdated; + break; + case 6: /* Peer is primary, voluntarily outdate myself. + * This is useful when an unconnected Secondary is asked to + * become Primary, but findes the other peer being active. */ + ex_to_string = "peer is active"; + DRBD_WARN("Peer is primary, outdating myself.\n"); + nps = DUnknown; + _drbd_request_state(mdev, NS(disk, Outdated), ChgWaitComplete); + break; + case 7: + if (fp != Stonith) + ERR("outdate-peer() = 7 && fencing != Stonith !!!\n"); + ex_to_string = "peer was stonithed"; + nps = Outdated; + break; + default: + /* The script is broken ... */ + nps = DUnknown; + ERR("outdate-peer helper broken, returned %d\n", (r>>8)&0xff); + return nps; + } + + INFO("outdate-peer helper returned %d (%s)\n", + (r>>8) & 0xff, ex_to_string); + return nps; +} + + +int drbd_set_role(struct drbd_conf *mdev, enum drbd_role new_role, int force) +{ + const int max_tries = 4; + int r = 0; + int try = 0; + int forced = 0; + union drbd_state_t mask, val; + enum drbd_disk_state nps; + + if (new_role == Primary) + request_ping(mdev); /* Detect a dead peer ASAP */ + + mutex_lock(&mdev->state_mutex); + + mask.i = 0; mask.role = role_mask; + val.i = 0; val.role = new_role; + + while (try++ < max_tries) { + r = _drbd_request_state(mdev, mask, val, ChgWaitComplete); + + /* in case we first succeeded to outdate, + * but now suddenly could establish a connection */ + if (r == SS_CW_FailedByPeer && mask.pdsk != 0) { + val.pdsk = 0; + mask.pdsk = 0; + continue; + } + + if( r == SS_NoUpToDateDisk && force && + ( mdev->state.disk == Inconsistent || + mdev->state.disk == Outdated ) ) { + mask.disk = disk_mask; + val.disk = UpToDate; + forced = 1; + continue; + } + + if ( r == SS_NoUpToDateDisk && + mdev->state.disk == Consistent ) { + D_ASSERT(mdev->state.pdsk == DUnknown); + nps = drbd_try_outdate_peer(mdev); + + if (nps == Outdated) { + val.disk = UpToDate; + mask.disk = disk_mask; + } + + val.pdsk = nps; + mask.pdsk = disk_mask; + + continue; + } + + if (r == SS_NothingToDo) + goto fail; + if (r == SS_PrimaryNOP) { + nps = drbd_try_outdate_peer(mdev); + + if (force && nps > Outdated) { + DRBD_WARN("Forced into split brain situation!\n"); + nps = Outdated; + } + + mask.pdsk = disk_mask; + val.pdsk = nps; + + continue; + } + if (r == SS_TwoPrimaries) { + /* Maybe the peer is detected as dead very soon... + retry at most once more in this case. */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout((mdev->net_conf->ping_timeo+1)*HZ/10); + if (try < max_tries) + try = max_tries -1; + continue; + } + if (r < SS_Success) { + r = _drbd_request_state(mdev, mask, val, + ChgStateVerbose + ChgWaitComplete); + if (r < SS_Success) + goto fail; + } + break; + } + + if (forced) + DRBD_WARN("Forced to consider local data as UpToDate!\n"); + + fsync_bdev(mdev->this_bdev); + + /* Wait until nothing is on the fly :) */ + wait_event(mdev->misc_wait, atomic_read(&mdev->ap_pending_cnt) == 0); + + /* FIXME RACE here: if our direct user is not using bd_claim (i.e. + * not a filesystem) since cstate might still be >= Connected, new + * ap requests may come in and increase ap_pending_cnt again! + * but that means someone is misusing DRBD... + * */ + + if (new_role == Secondary) { + set_disk_ro(mdev->vdisk, TRUE ); + if (inc_local(mdev)) { + mdev->bc->md.uuid[Current] &= ~(u64)1; + dec_local(mdev); + } + } else { + if (inc_net(mdev)) { + mdev->net_conf->want_lose = 0; + dec_net(mdev); + } + set_disk_ro(mdev->vdisk, FALSE ); + if (inc_local(mdev)) { + if ( ((mdev->state.conn < Connected || + mdev->state.pdsk <= Failed) + && mdev->bc->md.uuid[Bitmap] == 0) || forced) + drbd_uuid_new_current(mdev); + + mdev->bc->md.uuid[Current] |= (u64)1; + dec_local(mdev); + } + } + + if ((new_role == Secondary) && inc_local(mdev) ) + { + drbd_al_to_on_disk_bm(mdev); + dec_local(mdev); + } + + if (mdev->state.conn >= WFReportParams) { + /* if this was forced, we should consider sync */ + if (forced) + drbd_send_uuids(mdev); + drbd_send_state(mdev); + } + + drbd_md_sync(mdev); + + fail: + mutex_unlock(&mdev->state_mutex); + return r; +} + + +STATIC int drbd_nl_primary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + struct primary primary_args; + + memset(&primary_args, 0, sizeof(struct primary)); + if (!primary_from_tags(mdev, nlp->tag_list, &primary_args)) { + reply->ret_code = UnknownMandatoryTag; + return 0; + } + + reply->ret_code = + drbd_set_role(mdev, Primary, primary_args.overwrite_peer); + + return 0; +} + +STATIC int drbd_nl_secondary(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_set_role(mdev, Secondary, 0); + + return 0; +} + +/* initializes the md.*_offset members, so we are able to find + * the on disk meta data */ +STATIC void drbd_md_set_sector_offsets(struct drbd_conf *mdev, + struct drbd_backing_dev *bdev) +{ + sector_t md_size_sect = 0; + switch (bdev->dc.meta_dev_idx) { + default: + /* v07 style fixed size indexed meta data */ + bdev->md.md_size_sect = MD_RESERVED_SECT; + bdev->md.md_offset = drbd_md_ss__(mdev, bdev); + bdev->md.al_offset = MD_AL_OFFSET; + bdev->md.bm_offset = MD_BM_OFFSET; + break; + case DRBD_MD_INDEX_FLEX_EXT: + /* just occupy the full device; unit: sectors */ + bdev->md.md_size_sect = drbd_get_capacity(bdev->md_bdev); + bdev->md.md_offset = 0; + bdev->md.al_offset = MD_AL_OFFSET; + bdev->md.bm_offset = MD_BM_OFFSET; + break; + case DRBD_MD_INDEX_INTERNAL: + case DRBD_MD_INDEX_FLEX_INT: + bdev->md.md_offset = drbd_md_ss__(mdev, bdev); + /* al size is still fixed */ + bdev->md.al_offset = -MD_AL_MAX_SIZE; + /* LGE FIXME max size check missing. */ + /* we need (slightly less than) ~ this much bitmap sectors: */ + md_size_sect = drbd_get_capacity(bdev->backing_bdev); + md_size_sect = ALIGN(md_size_sect, BM_SECT_PER_EXT); + md_size_sect = BM_SECT_TO_EXT(md_size_sect); + md_size_sect = ALIGN(md_size_sect, 8); + + /* plus the "drbd meta data super block", + * and the activity log; */ + md_size_sect += MD_BM_OFFSET; + + bdev->md.md_size_sect = md_size_sect; + /* bitmap offset is adjusted by 'super' block size */ + bdev->md.bm_offset = -md_size_sect + MD_AL_OFFSET; + break; + } +} + +char *ppsize(char *buf, unsigned long long size) +{ + /* Needs 9 bytes at max. */ + static char units[] = { 'K', 'M', 'G', 'T', 'P', 'E' }; + int base = 0; + while (size >= 10000 ) { + /* shift + round */ + size = (size >> 10) + !!(size & (1<<9)); + base++; + } + sprintf(buf, "%lu %cB", (long)size, units[base]); + + return buf; +} + +/** + * drbd_determin_dev_size: + * Evaluates all constraints and sets our correct device size. + * Negative return values indicate errors. 0 and positive values + * indicate success. + * You should call drbd_md_sync() after calling this function. + */ +enum determin_dev_size_enum drbd_determin_dev_size(struct drbd_conf *mdev) __must_hold(local) +{ + sector_t prev_first_sect, prev_size; /* previous meta location */ + sector_t la_size; + sector_t size; + char ppb[10]; + + int md_moved, la_size_changed; + enum determin_dev_size_enum rv=unchanged; + + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + + prev_first_sect = drbd_md_first_sector(mdev->bc); + prev_size = mdev->bc->md.md_size_sect; + la_size = mdev->bc->md.la_size_sect; + + /* TODO: should only be some assert here, not (re)init... */ + drbd_md_set_sector_offsets(mdev, mdev->bc); + + size = drbd_new_dev_size(mdev, mdev->bc); + + if ( drbd_get_capacity(mdev->this_bdev) != size || + drbd_bm_capacity(mdev) != size ) { + int err; + err = drbd_bm_resize(mdev, size); + if (unlikely(err)) { + /* currently there is only one error: ENOMEM! */ + size = drbd_bm_capacity(mdev)>>1; + if (size == 0) { + ERR("OUT OF MEMORY! " + "Could not allocate bitmap! "); + } else { + /* FIXME this is problematic, + * if we in fact are smaller now! */ + ERR("BM resizing failed. " + "Leaving size unchanged at size = %lu KB\n", + (unsigned long)size); + } + rv = dev_size_error; + } + /* racy, see comments above. */ + drbd_set_my_capacity(mdev, size); + mdev->bc->md.la_size_sect = size; + INFO("size = %s (%llu KB)\n", ppsize(ppb, size>>1), + (unsigned long long)size>>1); + } + if (rv == dev_size_error) + goto out; + + la_size_changed = (la_size != mdev->bc->md.la_size_sect); + + /* LGE: flexible device size!! is this the right thing to test? */ + md_moved = prev_first_sect != drbd_md_first_sector(mdev->bc) + || prev_size != mdev->bc->md.md_size_sect; + + if (md_moved) { + DRBD_WARN("Moving meta-data.\n"); + /* assert: (flexible) internal meta data */ + } + + if (la_size_changed || md_moved) { + drbd_al_shrink(mdev); /* All extents inactive. */ + INFO("Writing the whole bitmap, size changed\n"); + rv = drbd_bitmap_io(mdev, &drbd_bm_write); + drbd_md_mark_dirty(mdev); + } + + if (size > la_size) rv = grew; + if (size < la_size) rv = shrunk; +out: + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + return rv; +} + +sector_t +drbd_new_dev_size(struct drbd_conf *mdev, struct drbd_backing_dev *bdev) +{ + sector_t p_size = mdev->p_size; /* partner's disk size. */ + sector_t la_size = bdev->md.la_size_sect; /* last agreed size. */ + sector_t m_size; /* my size */ + sector_t u_size = bdev->dc.disk_size; /* size requested by user. */ + sector_t size = 0; + + m_size = drbd_get_max_capacity(bdev); + + if (p_size && m_size) { + size = min_t(sector_t, p_size, m_size); + } else { + if (la_size) { + size = la_size; + if (m_size && m_size < size) + size = m_size; + if (p_size && p_size < size) + size = p_size; + } else { + if (m_size) + size = m_size; + if (p_size) + size = p_size; + } + } + + if (size == 0) + ERR("Both nodes diskless!\n"); + + if (u_size) { + if (u_size > size) + ERR("Requested disk size is too big (%lu > %lu)\n", + (unsigned long)u_size>>1, (unsigned long)size>>1); + else + size = u_size; + } + + return size; +} + +/** + * drbd_check_al_size: + * checks that the al lru is of requested size, and if neccessary tries to + * allocate a new one. returns -EBUSY if current al lru is still used, + * -ENOMEM when allocation failed, and 0 on success. You should call + * drbd_md_sync() after you called this function. + */ +STATIC int drbd_check_al_size(struct drbd_conf *mdev) +{ + struct lru_cache *n, *t; + struct lc_element *e; + unsigned int in_use; + int i; + + ERR_IF(mdev->sync_conf.al_extents < 7) + mdev->sync_conf.al_extents = 127; + + if ( mdev->act_log && + mdev->act_log->nr_elements == mdev->sync_conf.al_extents ) + return 0; + + in_use = 0; + t = mdev->act_log; + n = lc_alloc("act_log", mdev->sync_conf.al_extents, + sizeof(struct lc_element), mdev); + + if (n == NULL) { + ERR("Cannot allocate act_log lru!\n"); + return -ENOMEM; + } + spin_lock_irq(&mdev->al_lock); + if (t) { + for (i = 0; i < t->nr_elements; i++) { + e = lc_entry(t, i); + if (e->refcnt) + ERR("refcnt(%d)==%d\n", + e->lc_number, e->refcnt); + in_use += e->refcnt; + } + } + if (!in_use) + mdev->act_log = n; + spin_unlock_irq(&mdev->al_lock); + if (in_use) { + ERR("Activity log still in use!\n"); + lc_free(n); + return -EBUSY; + } else { + if (t) + lc_free(t); + } + drbd_md_mark_dirty(mdev); /* we changed mdev->act_log->nr_elemens */ + return 0; +} + +void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_seg_s) __must_hold(local) +{ + struct request_queue * const q = mdev->rq_queue; + struct request_queue * const b = mdev->bc->backing_bdev->bd_disk->queue; + /* unsigned int old_max_seg_s = q->max_segment_size; */ + int max_segments = mdev->bc->dc.max_bio_bvecs; + + if (b->merge_bvec_fn && !mdev->bc->dc.use_bmbv) + max_seg_s = PAGE_SIZE; + + max_seg_s = min(b->max_sectors * b->hardsect_size, max_seg_s); + + MTRACE(TraceTypeRq, TraceLvlSummary, + DUMPI(b->max_sectors); + DUMPI(b->max_phys_segments); + DUMPI(b->max_hw_segments); + DUMPI(b->max_segment_size); + DUMPI(b->hardsect_size); + DUMPI(b->seg_boundary_mask); + ); + + q->max_sectors = max_seg_s >> 9; + if (max_segments) { + q->max_phys_segments = max_segments; + q->max_hw_segments = max_segments; + } else { + q->max_phys_segments = MAX_PHYS_SEGMENTS; + q->max_hw_segments = MAX_HW_SEGMENTS; + } + q->max_segment_size = max_seg_s; + q->hardsect_size = 512; + q->seg_boundary_mask = PAGE_SIZE-1; + blk_queue_stack_limits(q, b); + + /* KERNEL BUG. in ll_rw_blk.c ?? + * t->max_segment_size = min(t->max_segment_size,b->max_segment_size); + * should be + * t->max_segment_size = min_not_zero(...,...) + * workaround here: */ + if (q->max_segment_size == 0) + q->max_segment_size = max_seg_s; + + MTRACE(TraceTypeRq, TraceLvlSummary, + DUMPI(q->max_sectors); + DUMPI(q->max_phys_segments); + DUMPI(q->max_hw_segments); + DUMPI(q->max_segment_size); + DUMPI(q->hardsect_size); + DUMPI(q->seg_boundary_mask); + ); + + if (b->merge_bvec_fn) + DRBD_WARN("Backing device's merge_bvec_fn() = %p\n", + b->merge_bvec_fn); + INFO("max_segment_size ( = BIO size ) = %u\n", q->max_segment_size); + + if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) { + INFO("Adjusting my ra_pages to backing device's (%lu -> %lu)\n", + q->backing_dev_info.ra_pages, + b->backing_dev_info.ra_pages); + q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages; + } +} + +/* does always return 0; + * interesting return code is in reply->ret_code */ +STATIC int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + enum ret_codes retcode; + struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ + struct inode *inode, *inode2; + struct lru_cache *resync_lru = NULL; + union drbd_state_t ns, os; + int rv, ntries = 0; + + /* if you want to reconfigure, please tear down first */ + if (mdev->state.disk > Diskless) { + retcode = HaveDiskConfig; + goto fail; + } + + /* + * We may have gotten here very quickly from a detach. Wait for a bit + * then fail. + */ + while (1) { + __no_warn(local, nbc = mdev->bc; ); + if (nbc == NULL) + break; + if (ntries++ >= 5) { + DRBD_WARN("drbd_nl_disk_conf: mdev->bc not NULL.\n"); + retcode = HaveDiskConfig; + goto fail; + } + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/10); + } + + nbc = kmalloc(sizeof(struct drbd_backing_dev), GFP_KERNEL); + if (!nbc) { + retcode = KMallocFailed; + goto fail; + } + + if ( !(nlp->flags & DRBD_NL_SET_DEFAULTS) && inc_local(mdev) ) { + memcpy(&nbc->dc, &mdev->bc->dc, sizeof(struct disk_conf)); + dec_local(mdev); + } else { + memset(&nbc->dc, 0, sizeof(struct disk_conf)); + nbc->dc.disk_size = DRBD_DISK_SIZE_SECT_DEF; + nbc->dc.on_io_error = DRBD_ON_IO_ERROR_DEF; + nbc->dc.fencing = DRBD_FENCING_DEF; + nbc->dc.max_bio_bvecs= DRBD_MAX_BIO_BVECS_DEF; + } + + if (!disk_conf_from_tags(mdev, nlp->tag_list, &nbc->dc)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + nbc->lo_file = NULL; + nbc->md_file = NULL; + + if (nbc->dc.meta_dev_idx < DRBD_MD_INDEX_FLEX_INT) { + retcode = LDMDInvalid; + goto fail; + } + + nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0); + if (IS_ERR(nbc->lo_file)) { + ERR("open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, + PTR_ERR(nbc->lo_file)); + nbc->lo_file = NULL; + retcode = LDNameInvalid; + goto fail; + } + + inode = nbc->lo_file->f_dentry->d_inode; + + if (!S_ISBLK(inode->i_mode)) { + retcode = LDNoBlockDev; + goto fail; + } + + nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0); + if (IS_ERR(nbc->md_file)) { + ERR("open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, + PTR_ERR(nbc->md_file)); + nbc->md_file = NULL; + retcode = MDNameInvalid; + goto fail; + } + + inode2 = nbc->md_file->f_dentry->d_inode; + + if (!S_ISBLK(inode2->i_mode)) { + retcode = MDNoBlockDev; + goto fail; + } + + nbc->backing_bdev = inode->i_bdev; + if (bd_claim(nbc->backing_bdev, mdev)) { + printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n", + nbc->backing_bdev, mdev, + nbc->backing_bdev->bd_holder, + nbc->backing_bdev->bd_contains->bd_holder, + nbc->backing_bdev->bd_holders); + retcode = LDMounted; + goto fail; + } + + resync_lru = lc_alloc("resync", 61, sizeof(struct bm_extent), mdev); + if (!resync_lru) { + retcode = KMallocFailed; + goto fail; + } + + if (!mdev->bitmap) { + if(drbd_bm_init(mdev)) { + retcode = KMallocFailed; + goto fail; + } + } + + nbc->md_bdev = inode2->i_bdev; + if (bd_claim(nbc->md_bdev, + (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || + nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT) ? + (void *)mdev : (void *) drbd_m_holder )) { + retcode = MDMounted; + goto release_bdev_fail; + } + + if ( (nbc->backing_bdev == nbc->md_bdev) != + (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || + nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT) ) { + retcode = LDMDInvalid; + goto release_bdev2_fail; + } + + if ((drbd_get_capacity(nbc->backing_bdev)) < nbc->dc.disk_size) { + retcode = LDDeviceTooSmall; + goto release_bdev2_fail; + } + +/* TODO check whether backing device size is within plausible limits */ + + /* Make sure the new disk is big enough + * (we may currently be Primary with no local disk...) */ + if (drbd_get_capacity(nbc->backing_bdev) < + drbd_get_capacity(mdev->this_bdev) ) { + retcode = LDDeviceTooSmall; + goto release_bdev2_fail; + } + + nbc->known_size = drbd_get_capacity(nbc->backing_bdev); + + retcode = _drbd_request_state(mdev, NS(disk, Attaching), ChgStateVerbose); + if (retcode < SS_Success ) + goto release_bdev2_fail; + + if (!inc_local_if_state(mdev, Attaching)) { + goto force_diskless; + } + + drbd_thread_start(&mdev->worker); + drbd_md_set_sector_offsets(mdev, nbc); + + retcode = drbd_md_read(mdev, nbc); + if (retcode != NoError) + goto force_diskless_dec; + + if (mdev->state.conn < Connected && + mdev->state.role == Primary && + (mdev->ed_uuid & ~((u64)1)) != (nbc->md.uuid[Current] & ~((u64)1))) { + ERR("Can only attach to data with current UUID=%016llX\n", + (unsigned long long)mdev->ed_uuid); + retcode = DataOfWrongCurrent; + goto force_diskless_dec; + } + + /* Since we are diskless, fix the AL first... */ + if (drbd_check_al_size(mdev)) { + retcode = KMallocFailed; + goto force_diskless_dec; + } + + /* Prevent shrinking of consistent devices ! */ + if (drbd_md_test_flag(nbc, MDF_Consistent) && + drbd_new_dev_size(mdev, nbc) < nbc->md.la_size_sect) { + retcode = LDDeviceTooSmall; + goto force_diskless_dec; + } + + if (!drbd_al_read_log(mdev, nbc)) { + retcode = MDIOError; + goto force_diskless_dec; + } + + /* Reset the "barriers don't work" bits here, then force meta data to + * be written, to ensure we determine if barriers are supported. */ + if (nbc->dc.no_disk_flush) + set_bit(LL_DEV_NO_FLUSH, &mdev->flags); + else + clear_bit(LL_DEV_NO_FLUSH, &mdev->flags); + + if (nbc->dc.no_md_flush) + set_bit(MD_NO_BARRIER, &mdev->flags); + else + clear_bit(MD_NO_BARRIER, &mdev->flags); + + /* Point of no return reached. + * Devices and memory are no longer released by error cleanup below. + * now mdev takes over responsibility, and the state engine should + * clean it up somewhere. */ + D_ASSERT(mdev->bc == NULL); + mdev->bc = nbc; + mdev->resync = resync_lru; + nbc = NULL; + resync_lru = NULL; + + if (drbd_md_test_flag(mdev->bc, MDF_PrimaryInd)) + set_bit(CRASHED_PRIMARY, &mdev->flags); + else + clear_bit(CRASHED_PRIMARY, &mdev->flags); + + mdev->send_cnt = 0; + mdev->recv_cnt = 0; + mdev->read_cnt = 0; + mdev->writ_cnt = 0; + + drbd_setup_queue_param(mdev, DRBD_MAX_SEGMENT_SIZE); + /* + * FIXME currently broken. + * drbd_set_recv_tcq(mdev, + * drbd_queue_order_type(mdev)==QUEUE_ORDERED_TAG); + */ + + /* If I am currently not Primary, + * but meta data primary indicator is set, + * I just now recover from a hard crash, + * and have been Primary before that crash. + * + * Now, if I had no connection before that crash + * (have been degraded Primary), chances are that + * I won't find my peer now either. + * + * In that case, and _only_ in that case, + * we use the degr-wfc-timeout instead of the default, + * so we can automatically recover from a crash of a + * degraded but active "cluster" after a certain timeout. + */ + clear_bit(USE_DEGR_WFC_T, &mdev->flags); + if ( mdev->state.role != Primary && + drbd_md_test_flag(mdev->bc, MDF_PrimaryInd) && + !drbd_md_test_flag(mdev->bc, MDF_ConnectedInd) ) + set_bit(USE_DEGR_WFC_T, &mdev->flags); + + if (drbd_determin_dev_size(mdev) == dev_size_error) { + retcode = VMallocFailed; + goto force_diskless_dec; + } + + if (drbd_md_test_flag(mdev->bc, MDF_FullSync)) { + INFO("Assuming that all blocks are out of sync " + "(aka FullSync)\n"); + if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write)) { + retcode = MDIOError; + goto force_diskless_dec; + } + } else { + if (drbd_bitmap_io(mdev, &drbd_bm_read) < 0) { + retcode = MDIOError; + goto force_diskless_dec; + } + } + + if (test_bit(CRASHED_PRIMARY, &mdev->flags)) { + drbd_al_apply_to_bm(mdev); + drbd_al_to_on_disk_bm(mdev); + } + /* else { + FIXME wipe out on disk al! + } */ + + spin_lock_irq(&mdev->req_lock); + os = mdev->state; + ns.i = os.i; + /* If MDF_Consistent is not set go into inconsistent state, + otherwise investige MDF_WasUpToDate... + If MDF_WasUpToDate is not set go into Outdated disk state, + otherwise into Consistent state. + */ + if (drbd_md_test_flag(mdev->bc, MDF_Consistent)) { + if (drbd_md_test_flag(mdev->bc, MDF_WasUpToDate)) + ns.disk = Consistent; + else + ns.disk = Outdated; + } else { + ns.disk = Inconsistent; + } + + if (drbd_md_test_flag(mdev->bc, MDF_PeerOutDated)) + ns.pdsk = Outdated; + + if ( ns.disk == Consistent && + ( ns.pdsk == Outdated || mdev->bc->dc.fencing == DontCare ) ) + ns.disk = UpToDate; + + /* All tests on MDF_PrimaryInd, MDF_ConnectedInd, + MDF_Consistent and MDF_WasUpToDate must happen before + this point, because drbd_request_state() modifies these + flags. */ + + /* In case we are Connected postpone any desicion on the new disk + state after the negotiation phase. */ + if (mdev->state.conn == Connected) { + mdev->new_state_tmp.i = ns.i; + ns.i = os.i; + ns.disk = Negotiating; + } + + rv = _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); + ns = mdev->state; + spin_unlock_irq(&mdev->req_lock); + + if (rv < SS_Success) + goto force_diskless_dec; + + if(mdev->state.role == Primary) mdev->bc->md.uuid[Current] |= (u64)1; + else mdev->bc->md.uuid[Current] &= ~(u64)1; + + drbd_md_mark_dirty(mdev); + drbd_md_sync(mdev); + + dec_local(mdev); + reply->ret_code = retcode; + return 0; + + force_diskless_dec: + dec_local(mdev); + force_diskless: + drbd_force_state(mdev, NS(disk, Diskless)); + drbd_md_sync(mdev); + release_bdev2_fail: + if (nbc) + bd_release(nbc->md_bdev); + release_bdev_fail: + if (nbc) + bd_release(nbc->backing_bdev); + fail: + if (nbc) { + if (nbc->lo_file) + fput(nbc->lo_file); + if (nbc->md_file) + fput(nbc->md_file); + kfree(nbc); + } + if (resync_lru) + lc_free(resync_lru); + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + fsync_bdev(mdev->this_bdev); + reply->ret_code = drbd_request_state(mdev, NS(disk, Diskless)); + + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/20); /* 50ms; Time for worker to finally terminate */ + + return 0; +} + +#define HMAC_NAME_L 20 + +STATIC int drbd_nl_net_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int i, ns; + enum ret_codes retcode; + struct net_conf *new_conf = NULL; + struct crypto_hash *tfm = NULL; + struct crypto_hash *integrity_w_tfm = NULL; + struct crypto_hash *integrity_r_tfm = NULL; + struct hlist_head *new_tl_hash = NULL; + struct hlist_head *new_ee_hash = NULL; + struct drbd_conf *odev; + char hmac_name[HMAC_NAME_L]; + void *int_dig_out = NULL; + void *int_dig_in = NULL; + void *int_dig_vv = NULL; + + if (mdev->state.conn > StandAlone) { + retcode = HaveNetConfig; + goto fail; + } + + new_conf = kmalloc(sizeof(struct net_conf), GFP_KERNEL); + if (!new_conf) { + retcode = KMallocFailed; + goto fail; + } + + if ( !(nlp->flags & DRBD_NL_SET_DEFAULTS) && inc_net(mdev)) { + memcpy(new_conf, mdev->net_conf, sizeof(struct net_conf)); + dec_net(mdev); + } else { + memset(new_conf, 0, sizeof(struct net_conf)); + new_conf->timeout = DRBD_TIMEOUT_DEF; + new_conf->try_connect_int = DRBD_CONNECT_INT_DEF; + new_conf->ping_int = DRBD_PING_INT_DEF; + new_conf->max_epoch_size = DRBD_MAX_EPOCH_SIZE_DEF; + new_conf->max_buffers = DRBD_MAX_BUFFERS_DEF; + new_conf->unplug_watermark = DRBD_UNPLUG_WATERMARK_DEF; + new_conf->sndbuf_size = DRBD_SNDBUF_SIZE_DEF; + new_conf->ko_count = DRBD_KO_COUNT_DEF; + new_conf->after_sb_0p = DRBD_AFTER_SB_0P_DEF; + new_conf->after_sb_1p = DRBD_AFTER_SB_1P_DEF; + new_conf->after_sb_2p = DRBD_AFTER_SB_2P_DEF; + new_conf->want_lose = 0; + new_conf->two_primaries = 0; + new_conf->wire_protocol = DRBD_PROT_C; + new_conf->ping_timeo = DRBD_PING_TIMEO_DEF; + new_conf->rr_conflict = DRBD_RR_CONFLICT_DEF; + } + + if (!net_conf_from_tags(mdev, nlp->tag_list, new_conf)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + if (new_conf->two_primaries + && (new_conf->wire_protocol != DRBD_PROT_C)) { + retcode = ProtocolCRequired; + goto fail; + }; + + if (mdev->state.role == Primary && new_conf->want_lose) { + retcode = DiscardNotAllowed; + goto fail; + } + +#define M_ADDR(A) (((struct sockaddr_in *)&A->my_addr)->sin_addr.s_addr) +#define M_PORT(A) (((struct sockaddr_in *)&A->my_addr)->sin_port) +#define O_ADDR(A) (((struct sockaddr_in *)&A->peer_addr)->sin_addr.s_addr) +#define O_PORT(A) (((struct sockaddr_in *)&A->peer_addr)->sin_port) + retcode = NoError; + for (i = 0; i < minor_count; i++) { + odev = minor_to_mdev(i); + if (!odev || odev == mdev) + continue; + if ( inc_net(odev)) { + if ( M_ADDR(new_conf) == M_ADDR(odev->net_conf) && + M_PORT(new_conf) == M_PORT(odev->net_conf) ) + retcode = LAAlreadyInUse; + + if (O_ADDR(new_conf) == O_ADDR(odev->net_conf) && + O_PORT(new_conf) == O_PORT(odev->net_conf) ) + retcode = OAAlreadyInUse; + + dec_net(odev); + if (retcode != NoError) + goto fail; + } + } +#undef M_ADDR +#undef M_PORT +#undef O_ADDR +#undef O_PORT + + if (new_conf->cram_hmac_alg[0] != 0) { + snprintf(hmac_name, HMAC_NAME_L, "hmac(%s)", + new_conf->cram_hmac_alg); + tfm = crypto_alloc_hash(hmac_name, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(tfm)) { + tfm = NULL; + retcode = CRAMAlgNotAvail; + goto fail; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(tfm)) + != CRYPTO_ALG_TYPE_HASH) { + retcode = CRAMAlgNotDigest; + goto fail; + } + } + + if (new_conf->integrity_alg[0]) { + integrity_w_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(integrity_w_tfm)) { + integrity_w_tfm = NULL; + retcode=IntegrityAlgNotAvail; + goto fail; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(integrity_w_tfm)) != CRYPTO_ALG_TYPE_DIGEST) { + retcode=IntegrityAlgNotDigest; + goto fail; + } + + integrity_r_tfm = crypto_alloc_hash(new_conf->integrity_alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(integrity_r_tfm)) { + integrity_r_tfm = NULL; + retcode=IntegrityAlgNotAvail; + goto fail; + } + } + + ns = new_conf->max_epoch_size/8; + if (mdev->tl_hash_s != ns) { + new_tl_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL); + if (!new_tl_hash) { + retcode = KMallocFailed; + goto fail; + } + } + + ns = new_conf->max_buffers/8; + if (new_conf->two_primaries && ( mdev->ee_hash_s != ns ) ) { + new_ee_hash = kzalloc(ns*sizeof(void *), GFP_KERNEL); + if (!new_ee_hash) { + retcode = KMallocFailed; + goto fail; + } + } + + ((char *)new_conf->shared_secret)[SHARED_SECRET_MAX-1] = 0; + +#if 0 + /* for the connection loss logic in drbd_recv + * I _need_ the resulting timeo in jiffies to be + * non-zero and different + * + * XXX maybe rather store the value scaled to jiffies? + * Note: MAX_SCHEDULE_TIMEOUT/HZ*HZ != MAX_SCHEDULE_TIMEOUT + * and HZ > 10; which is unlikely to change... + * Thus, if interrupted by a signal, + * sock_{send,recv}msg returns -EINTR, + * if the timeout expires, -EAGAIN. + */ + /* unlikely: someone disabled the timeouts ... + * just put some huge values in there. */ + if (!new_conf->ping_int) + new_conf->ping_int = MAX_SCHEDULE_TIMEOUT/HZ; + if (!new_conf->timeout) + new_conf->timeout = MAX_SCHEDULE_TIMEOUT/HZ*10; + if (new_conf->ping_int*10 < new_conf->timeout) + new_conf->timeout = new_conf->ping_int*10/6; + if (new_conf->ping_int*10 == new_conf->timeout) + new_conf->ping_int = new_conf->ping_int+1; +#endif + + if (integrity_w_tfm) { + i = crypto_hash_digestsize(integrity_w_tfm); + int_dig_out = kmalloc(i, GFP_KERNEL); + if (!int_dig_out) { + retcode = KMallocFailed; + goto fail; + } + int_dig_in = kmalloc(i, GFP_KERNEL); + if (!int_dig_in) { + retcode = KMallocFailed; + goto fail; + } + int_dig_vv = kmalloc(i, GFP_KERNEL); + if (!int_dig_vv) { + retcode = KMallocFailed; + goto fail; + } + } + + if (!mdev->bitmap) { + if(drbd_bm_init(mdev)) { + retcode = KMallocFailed; + goto fail; + } + } + + D_ASSERT(mdev->net_conf == NULL); + mdev->net_conf = new_conf; + + mdev->send_cnt = 0; + mdev->recv_cnt = 0; + + if (new_tl_hash) { + kfree(mdev->tl_hash); + mdev->tl_hash_s = mdev->net_conf->max_epoch_size/8; + mdev->tl_hash = new_tl_hash; + } + + if (new_ee_hash) { + kfree(mdev->ee_hash); + mdev->ee_hash_s = mdev->net_conf->max_buffers/8; + mdev->ee_hash = new_ee_hash; + } + + crypto_free_hash(mdev->cram_hmac_tfm); + mdev->cram_hmac_tfm = tfm; + + crypto_free_hash(mdev->integrity_w_tfm); + mdev->integrity_w_tfm = integrity_w_tfm; + + crypto_free_hash(mdev->integrity_r_tfm); + mdev->integrity_r_tfm = integrity_r_tfm; + + kfree(mdev->int_dig_out); + kfree(mdev->int_dig_in); + kfree(mdev->int_dig_vv); + mdev->int_dig_out=int_dig_out; + mdev->int_dig_in=int_dig_in; + mdev->int_dig_vv=int_dig_vv; + + retcode = _drbd_request_state(mdev, NS(conn, Unconnected), ChgStateVerbose); + if (retcode >= SS_Success) + drbd_thread_start(&mdev->worker); + + reply->ret_code = retcode; + return 0; + +fail: + kfree(int_dig_out); + kfree(int_dig_in); + kfree(int_dig_vv); + crypto_free_hash(tfm); + crypto_free_hash(integrity_w_tfm); + crypto_free_hash(integrity_r_tfm); + kfree(new_tl_hash); + kfree(new_ee_hash); + kfree(new_conf); + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_disconnect(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode; + + retcode = _drbd_request_state(mdev, NS(conn, Disconnecting), ChgOrdered); + + if (retcode == SS_NothingToDo) + goto done; + else if (retcode == SS_AlreadyStandAlone) + goto done; + else if (retcode == SS_PrimaryNOP) { + /* Our statche checking code wants to see the peer outdated. */ + retcode = drbd_request_state(mdev, NS2(conn, Disconnecting, + pdsk, Outdated)); + } else if (retcode == SS_CW_FailedByPeer) { + /* The peer probabely wants to see us outdated. */ + retcode = _drbd_request_state(mdev, NS2(conn, Disconnecting, + disk, Outdated), + ChgOrdered); + if (retcode == SS_IsDiskLess || retcode == SS_LowerThanOutdated) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + retcode = SS_Success; + } + + } + + if (retcode < SS_Success) + goto fail; + + if (wait_event_interruptible(mdev->state_wait, + mdev->state.conn != Disconnecting) ) { + /* Do not test for mdev->state.conn == StandAlone, since + someone else might connect us in the mean time! */ + retcode = GotSignal; + goto fail; + } + + done: + retcode = NoError; + fail: + drbd_md_sync(mdev); + reply->ret_code = retcode; + return 0; +} + +void resync_after_online_grow(struct drbd_conf *mdev) +{ + int iass; /* I am sync source */ + + INFO("Resync of new storage after online grow\n"); + if (mdev->state.role != mdev->state.peer) + iass = (mdev->state.role == Primary); + else + iass = test_bit(DISCARD_CONCURRENT,&mdev->flags); + + if (iass) + drbd_start_resync(mdev,SyncSource); + else + drbd_request_state(mdev,NS(conn,WFSyncUUID)); +} + +STATIC int drbd_nl_resize(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + struct resize rs; + int retcode = NoError; + int ldsc = 0; /* local disk size changed */ + enum determin_dev_size_enum dd; + + memset(&rs, 0, sizeof(struct resize)); + if (!resize_from_tags(mdev, nlp->tag_list, &rs)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + if (mdev->state.conn > Connected) { + retcode = NoResizeDuringResync; + goto fail; + } + + if ( mdev->state.role == Secondary && + mdev->state.peer == Secondary) { + retcode = APrimaryNodeNeeded; + goto fail; + } + + if (!inc_local(mdev)) { + retcode = HaveNoDiskConfig; + goto fail; + } + + if (mdev->bc->known_size != drbd_get_capacity(mdev->bc->backing_bdev)) { + mdev->bc->known_size = drbd_get_capacity(mdev->bc->backing_bdev); + ldsc = 1; + } + + mdev->bc->dc.disk_size = (sector_t)rs.resize_size; + dd = drbd_determin_dev_size(mdev); + drbd_md_sync(mdev); + dec_local(mdev); + if (dd == dev_size_error) { + retcode = VMallocFailed; + goto fail; + } + + if (mdev->state.conn == Connected && ( dd != unchanged || ldsc) ) { + drbd_send_uuids(mdev); + drbd_send_sizes(mdev); + if (dd == grew) + resync_after_online_grow(mdev); + } + + fail: + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_syncer_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode = NoError; + struct syncer_conf sc; + struct drbd_conf *odev; + int err; + struct crypto_hash *verify_tfm = NULL, *old_verify_tfm = NULL; + int ovr; /* online verify running */ + cpumask_t n_cpu_mask = CPU_MASK_NONE; + + memcpy(&sc, &mdev->sync_conf, sizeof(struct syncer_conf)); + + if (nlp->flags & DRBD_NL_SET_DEFAULTS) { + memset(&sc, 0, sizeof(struct syncer_conf)); + sc.rate = DRBD_RATE_DEF; + sc.after = DRBD_AFTER_DEF; + sc.al_extents = DRBD_AL_EXTENTS_DEF; + } + + if (!syncer_conf_from_tags(mdev, nlp->tag_list, &sc)) { + retcode = UnknownMandatoryTag; + goto fail; + } + + if (sc.after != -1) { + if ( sc.after < -1 || minor_to_mdev(sc.after) == NULL ) { + retcode = SyncAfterInvalid; + goto fail; + } + odev = minor_to_mdev(sc.after); /* check against loops in */ + while (1) { + if (odev == mdev) { + retcode = SyncAfterCycle; + goto fail; + } + if (odev->sync_conf.after == -1) + break; /* no cycles. */ + odev = minor_to_mdev(odev->sync_conf.after); + } + } + + ovr = (mdev->state.conn == VerifyS || mdev->state.conn == VerifyT); + + if (ovr) { + if (strcmp(sc.verify_alg, mdev->sync_conf.verify_alg)) { + retcode = VERIFYIsRunning; + goto fail; + } + } + + if (!ovr && sc.verify_alg[0]) { + verify_tfm = crypto_alloc_hash(sc.verify_alg, 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(verify_tfm)) { + verify_tfm = NULL; + retcode=VERIFYAlgNotAvail; + goto fail; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(verify_tfm)) != CRYPTO_ALG_TYPE_DIGEST) { + retcode=VERIFYAlgNotDigest; + goto fail; + } + } + + if (sc.cpu_mask[0] != 0) { + err = __bitmap_parse(sc.cpu_mask, 32, 0, (unsigned long *)&n_cpu_mask, NR_CPUS); + if (err) { + DRBD_WARN("__bitmap_parse() failed with %d\n", err); + retcode = CPUMaskParseFailed; + goto fail; + } + } + + ERR_IF (sc.rate < 1) sc.rate = 1; + ERR_IF (sc.al_extents < 7) sc.al_extents = 127; /* arbitrary minimum */ +#define AL_MAX ((MD_AL_MAX_SIZE-1) * AL_EXTENTS_PT) + if (sc.al_extents > AL_MAX) { + ERR("sc.al_extents > %d\n", AL_MAX); + sc.al_extents = AL_MAX; + } +#undef AL_MAX + + spin_lock(&mdev->peer_seq_lock); + /* lock against receive_SyncParam() */ + mdev->sync_conf = sc; + if (!ovr) { + old_verify_tfm = mdev->verify_tfm; + mdev->verify_tfm = verify_tfm; + verify_tfm = NULL; + } + spin_unlock(&mdev->peer_seq_lock); + + crypto_free_hash(old_verify_tfm); + + if (inc_local(mdev)) { + wait_event(mdev->al_wait, lc_try_lock(mdev->act_log)); + drbd_al_shrink(mdev); + err = drbd_check_al_size(mdev); + lc_unlock(mdev->act_log); + wake_up(&mdev->al_wait); + + dec_local(mdev); + drbd_md_sync(mdev); + + if (err) { + retcode = KMallocFailed; + goto fail; + } + } + + if (mdev->state.conn >= Connected) + drbd_send_sync_param(mdev, &sc); + + drbd_alter_sa(mdev, sc.after); + + if (!cpus_equal(mdev->cpu_mask, n_cpu_mask)) { + mdev->cpu_mask = n_cpu_mask; + n_cpu_mask = drbd_calc_cpu_mask(mdev); + drbd_thread_set_cpu(&mdev->receiver, n_cpu_mask); + drbd_thread_set_cpu(&mdev->worker, n_cpu_mask); + drbd_thread_set_cpu(&mdev->asender, n_cpu_mask); + } + +fail: + crypto_free_hash(verify_tfm); + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_invalidate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode; + + retcode = _drbd_request_state(mdev, NS(conn, StartingSyncT), ChgOrdered); + + if (retcode < SS_Success && retcode != SS_NeedConnection) + retcode = drbd_request_state(mdev, NS(conn, StartingSyncT)); + + while (retcode == SS_NeedConnection) { + spin_lock_irq(&mdev->req_lock); + if (mdev->state.conn < Connected) + retcode = _drbd_set_state(_NS(mdev, disk, Inconsistent), ChgStateVerbose, NULL); + spin_unlock_irq(&mdev->req_lock); + + if (retcode != SS_NeedConnection) + break; + + retcode = drbd_request_state(mdev, NS(conn, StartingSyncT)); + } + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_invalidate_peer(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + + reply->ret_code = drbd_request_state(mdev, NS(conn, StartingSyncS)); + + return 0; +} + +STATIC int drbd_nl_pause_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode = NoError; + + if (drbd_request_state(mdev, NS(user_isp, 1)) == SS_NothingToDo) + retcode = PauseFlagAlreadySet; + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_resume_sync(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + int retcode = NoError; + + if (drbd_request_state(mdev, NS(user_isp, 0)) == SS_NothingToDo) + retcode = PauseFlagAlreadyClear; + + reply->ret_code = retcode; + return 0; +} + +STATIC int drbd_nl_suspend_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev, NS(susp, 1)); + + return 0; +} + +STATIC int drbd_nl_resume_io(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev, NS(susp, 0)); + return 0; +} + +STATIC int drbd_nl_outdate(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev, NS(disk, Outdated)); + return 0; +} + +STATIC int drbd_nl_get_config(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl; + + tl = reply->tag_list; + + if (inc_local(mdev)) { + tl = disk_conf_to_tags(mdev, &mdev->bc->dc, tl); + dec_local(mdev); + } + + if (inc_net(mdev)) { + tl = net_conf_to_tags(mdev, mdev->net_conf, tl); + dec_net(mdev); + } + tl = syncer_conf_to_tags(mdev, &mdev->sync_conf, tl); + + *tl++ = TT_END; /* Close the tag list */ + + return (int)((char *)tl - (char *)reply->tag_list); +} + +STATIC int drbd_nl_get_state(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl; + + tl = reply->tag_list; + + tl = get_state_to_tags(mdev, (struct get_state *)&mdev->state, tl); + *tl++ = TT_END; /* Close the tag list */ + + return (int)((char *)tl - (char *)reply->tag_list); +} + +STATIC int drbd_nl_get_uuids(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl; + + tl = reply->tag_list; + + if (inc_local(mdev)) { + /* This is a hand crafted add tag ;) */ + *tl++ = T_uuids; + *tl++ = UUID_SIZE*sizeof(u64); + memcpy(tl, mdev->bc->md.uuid, UUID_SIZE*sizeof(u64)); + tl = (unsigned short *)((char *)tl + UUID_SIZE*sizeof(u64)); + *tl++ = T_uuids_flags; + *tl++ = sizeof(int); + memcpy(tl, &mdev->bc->md.flags, sizeof(int)); + tl = (unsigned short *)((char *)tl + sizeof(int)); + dec_local(mdev); + } + *tl++ = TT_END; /* Close the tag list */ + + return (int)((char *)tl - (char *)reply->tag_list); +} + + +STATIC int drbd_nl_get_timeout_flag(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + unsigned short *tl; + + tl = reply->tag_list; + + /* This is a hand crafted add tag ;) */ + *tl++ = T_use_degraded; + *tl++ = sizeof(char); + *((char *)tl) = test_bit(USE_DEGR_WFC_T, &mdev->flags) ? 1 : 0 ; + tl = (unsigned short *)((char *)tl + sizeof(char)); + *tl++ = TT_END; + + return (int)((char *)tl - (char *)reply->tag_list); +} + +STATIC int drbd_nl_start_ov(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp, + struct drbd_nl_cfg_reply *reply) +{ + reply->ret_code = drbd_request_state(mdev,NS(conn,VerifyS)); + + return 0; +} + + +STATIC struct drbd_conf *ensure_mdev(struct drbd_nl_cfg_req *nlp) +{ + struct drbd_conf *mdev; + + mdev = minor_to_mdev(nlp->drbd_minor); + + if (!mdev && (nlp->flags & DRBD_NL_CREATE_DEVICE)) { + mdev = drbd_new_device(nlp->drbd_minor); + + spin_lock_irq(&drbd_pp_lock); + if (minor_table[nlp->drbd_minor] == NULL) { + minor_table[nlp->drbd_minor] = mdev; + mdev = NULL; + } + spin_unlock_irq(&drbd_pp_lock); + + if (mdev) { + kfree(mdev->app_reads_hash); + if (mdev->md_io_page) + __free_page(mdev->md_io_page); + kfree(mdev); + mdev = NULL; + } + + mdev = minor_to_mdev(nlp->drbd_minor); + } + + return mdev; +} + +struct cn_handler_struct { + int (*function)(struct drbd_conf *, + struct drbd_nl_cfg_req *, + struct drbd_nl_cfg_reply* ); + int reply_body_size; +}; + +static struct cn_handler_struct cnd_table[] = { + [ P_primary ] = { &drbd_nl_primary, 0 }, + [ P_secondary ] = { &drbd_nl_secondary, 0 }, + [ P_disk_conf ] = { &drbd_nl_disk_conf, 0 }, + [ P_detach ] = { &drbd_nl_detach, 0 }, + [ P_net_conf ] = { &drbd_nl_net_conf, 0 }, + [ P_disconnect ] = { &drbd_nl_disconnect, 0 }, + [ P_resize ] = { &drbd_nl_resize, 0 }, + [ P_syncer_conf ] = { &drbd_nl_syncer_conf, 0 }, + [ P_invalidate ] = { &drbd_nl_invalidate, 0 }, + [ P_invalidate_peer ] = { &drbd_nl_invalidate_peer, 0 }, + [ P_pause_sync ] = { &drbd_nl_pause_sync, 0 }, + [ P_resume_sync ] = { &drbd_nl_resume_sync, 0 }, + [ P_suspend_io ] = { &drbd_nl_suspend_io, 0 }, + [ P_resume_io ] = { &drbd_nl_resume_io, 0 }, + [ P_outdate ] = { &drbd_nl_outdate, 0 }, + [ P_get_config ] = { &drbd_nl_get_config, + sizeof(struct syncer_conf_tag_len_struct) + + sizeof(struct disk_conf_tag_len_struct) + + sizeof(struct net_conf_tag_len_struct) }, + [ P_get_state ] = { &drbd_nl_get_state, + sizeof(struct get_state_tag_len_struct) }, + [ P_get_uuids ] = { &drbd_nl_get_uuids, + sizeof(struct get_uuids_tag_len_struct) }, + [ P_get_timeout_flag ] = + { &drbd_nl_get_timeout_flag, + sizeof(struct get_timeout_flag_tag_len_struct)}, + [ P_start_ov ] = { &drbd_nl_start_ov, 0 }, +}; + +STATIC void drbd_connector_callback(void *data) +{ + struct cn_msg *req = data; + struct drbd_nl_cfg_req *nlp = (struct drbd_nl_cfg_req *)req->data; + struct cn_handler_struct *cm; + struct cn_msg *cn_reply; + struct drbd_nl_cfg_reply *reply; + struct drbd_conf *mdev; + int retcode, rr; + int reply_size = sizeof(struct cn_msg) + + sizeof(struct drbd_nl_cfg_reply) + + sizeof(short int); + + if (!try_module_get(THIS_MODULE)) { + printk(KERN_ERR "drbd: try_module_get() failed!\n"); + return; + } + + mdev = ensure_mdev(nlp); + if (!mdev) { + retcode = MinorNotKnown; + goto fail; + } + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_packet(data);); + + if (nlp->packet_type >= P_nl_after_last_packet) { + retcode = UnknownNetLinkPacket; + goto fail; + } + + cm = cnd_table + nlp->packet_type; + reply_size += cm->reply_body_size; + + cn_reply = kmalloc(reply_size, GFP_KERNEL); + if (!cn_reply) { + retcode = KMallocFailed; + goto fail; + } + reply = (struct drbd_nl_cfg_reply *) cn_reply->data; + + reply->packet_type = + cm->reply_body_size ? nlp->packet_type : P_nl_after_last_packet; + reply->minor = nlp->drbd_minor; + reply->ret_code = NoError; /* Might by modified by cm->function. */ + /* reply->tag_list; might be modified by cm->fucntion. */ + + rr = cm->function(mdev, nlp, reply); + + cn_reply->id = req->id; + cn_reply->seq = req->seq; + cn_reply->ack = req->ack + 1; + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + rr; + cn_reply->flags = 0; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); + if (rr && rr != -ESRCH) + printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr); + + kfree(cn_reply); + module_put(THIS_MODULE); + return; + fail: + drbd_nl_send_reply(req, retcode); + module_put(THIS_MODULE); +} + +static atomic_t drbd_nl_seq = ATOMIC_INIT(2); /* two. */ + +static inline unsigned short * +__tl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data, + int len, int nul_terminated) +{ + int l = tag_descriptions[tag_number(tag)].max_len; + l = (len < l) ? len : l; + *tl++ = tag; + *tl++ = len; + memcpy(tl, data, len); + /* TODO + * maybe we need to add some padding to the data stream. + * otherwise we may get strange effects on architectures + * that require certain data types to be strictly aligned, + * because now the next "unsigned short" may be misaligned. */ + tl = (unsigned short*)((char*)tl + len); + if (nul_terminated) + *((char*)tl - 1) = 0; + return tl; +} + +static inline unsigned short * +tl_add_blob(unsigned short *tl, enum drbd_tags tag, const void *data, int len) +{ + return __tl_add_blob(tl, tag, data, len, 0); +} + +static inline unsigned short * +tl_add_str(unsigned short *tl, enum drbd_tags tag, const char *str) +{ + return __tl_add_blob(tl, tag, str, strlen(str)+1, 0); +} + +static inline unsigned short * +tl_add_int(unsigned short *tl, enum drbd_tags tag, const void *val) +{ + switch(tag_type(tag)) { + case TT_INTEGER: + *tl++ = tag; + *tl++ = sizeof(int); + *(int*)tl = *(int*)val; + tl = (unsigned short*)((char*)tl+sizeof(int)); + break; + case TT_INT64: + *tl++ = tag; + *tl++ = sizeof(u64); + *(u64*)tl = *(u64*)val; + tl = (unsigned short*)((char*)tl+sizeof(u64)); + break; + default: + /* someone did something stupid. */ + ; + } + return tl; +} + +void drbd_bcast_state(struct drbd_conf *mdev, union drbd_state_t state) +{ + char buffer[sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct get_state_tag_len_struct)+ + sizeof(short int)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + unsigned short *tl = reply->tag_list; + + /* DRBD_WARN("drbd_bcast_state() got called\n"); */ + + tl = get_state_to_tags(mdev, (struct get_state *)&state, tl); + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1, &drbd_nl_seq); + cn_reply->ack = 0; /* not used here. */ + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char *)tl - (char *)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_get_state; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); +} + +void drbd_bcast_ev_helper(struct drbd_conf *mdev, char *helper_name) +{ + char buffer[sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct call_helper_tag_len_struct)+ + sizeof(short int)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + unsigned short *tl = reply->tag_list; + int str_len; + + /* DRBD_WARN("drbd_bcast_state() got called\n"); */ + + str_len = strlen(helper_name)+1; + *tl++ = T_helper; + *tl++ = str_len; + memcpy(tl, helper_name, str_len); + tl = (unsigned short *)((char *)tl + str_len); + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1, &drbd_nl_seq); + cn_reply->ack = 0; /* not used here. */ + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char *)tl - (char *)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_call_helper; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); +} + +void drbd_bcast_ee(struct drbd_conf *mdev, + const char *reason, const int dgs, + const char* seen_hash, const char* calc_hash, + const struct Tl_epoch_entry* e) +{ + struct cn_msg *cn_reply; + struct drbd_nl_cfg_reply *reply; + struct bio_vec *bvec; + unsigned short *tl; + int i; + + if (!e) + return; + if (!reason || !reason[0]) + return; + + /* aparently we have to memcpy twice, first to prepare the data for the + * struct cn_msg, then within cn_netlink_send from the cn_msg to the + * netlink skb. */ + cn_reply = kmalloc( + sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct dump_ee_tag_len_struct)+ + sizeof(short int) + , GFP_KERNEL); + + if (!cn_reply) { + ERR("could not kmalloc buffer for drbd_bcast_ee, sector %llu, size %u\n", + (unsigned long long)e->sector, e->size); + return; + } + + reply = (struct drbd_nl_cfg_reply*)cn_reply->data; + tl = reply->tag_list; + + tl = tl_add_str(tl, T_dump_ee_reason, reason); + tl = tl_add_blob(tl, T_seen_digest, seen_hash, dgs); + tl = tl_add_blob(tl, T_calc_digest, calc_hash, dgs); + tl = tl_add_int(tl, T_ee_sector, &e->sector); + tl = tl_add_int(tl, T_ee_block_id, &e->block_id); + + *tl++ = T_ee_data; + *tl++ = e->size; + + __bio_for_each_segment(bvec, e->private_bio, i, 0) { + void *d = kmap(bvec->bv_page); + memcpy(tl, d + bvec->bv_offset, bvec->bv_len); + kunmap(bvec->bv_page); + tl=(unsigned short*)((char*)tl + bvec->bv_len); + } + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1,&drbd_nl_seq); + cn_reply->ack = 0; // not used here. + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char*)tl - (char*)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_dump_ee; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); + kfree(cn_reply); +} + +void drbd_bcast_sync_progress(struct drbd_conf *mdev) +{ + char buffer[sizeof(struct cn_msg)+ + sizeof(struct drbd_nl_cfg_reply)+ + sizeof(struct sync_progress_tag_len_struct)+ + sizeof(short int)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + unsigned short *tl = reply->tag_list; + unsigned long rs_left; + unsigned int res; + + /* no local ref, no bitmap, no syncer progress, no broadcast. */ + if (!inc_local(mdev)) + return; + drbd_get_syncer_progress(mdev, &rs_left, &res); + dec_local(mdev); + + *tl++ = T_sync_progress; + *tl++ = sizeof(int); + memcpy(tl, &res, sizeof(int)); + tl = (unsigned short *)((char *)tl + sizeof(int)); + *tl++ = TT_END; /* Close the tag list */ + + cn_reply->id.idx = CN_IDX_DRBD; + cn_reply->id.val = CN_VAL_DRBD; + + cn_reply->seq = atomic_add_return(1, &drbd_nl_seq); + cn_reply->ack = 0; /* not used here. */ + cn_reply->len = sizeof(struct drbd_nl_cfg_reply) + + (int)((char *)tl - (char *)reply->tag_list); + cn_reply->flags = 0; + + reply->packet_type = P_sync_progress; + reply->minor = mdev_to_minor(mdev); + reply->ret_code = NoError; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); +} + +int __init drbd_nl_init(void) +{ + static struct cb_id cn_id_drbd = { CN_IDX_DRBD, CN_VAL_DRBD }; + int err; + + err = cn_add_callback(&cn_id_drbd, "cn_drbd", &drbd_connector_callback); + if (err) { + printk(KERN_ERR "drbd: cn_drbd failed to register\n"); + return err; + } + + return 0; +} + +void drbd_nl_cleanup(void) +{ + static struct cb_id cn_id_drbd = { CN_IDX_DRBD, CN_VAL_DRBD }; + + cn_del_callback(&cn_id_drbd); +} + +void drbd_nl_send_reply( struct cn_msg *req, + int ret_code) +{ + char buffer[sizeof(struct cn_msg)+sizeof(struct drbd_nl_cfg_reply)]; + struct cn_msg *cn_reply = (struct cn_msg *) buffer; + struct drbd_nl_cfg_reply *reply = + (struct drbd_nl_cfg_reply *)cn_reply->data; + int rr; + + cn_reply->id = req->id; + + cn_reply->seq = req->seq; + cn_reply->ack = req->ack + 1; + cn_reply->len = sizeof(struct drbd_nl_cfg_reply); + cn_reply->flags = 0; + + reply->minor = ((struct drbd_nl_cfg_req *)req->data)->drbd_minor; + reply->ret_code = ret_code; + + TRACE(TraceTypeNl, TraceLvlSummary, nl_trace_reply(cn_reply);); + + rr = cn_netlink_send(cn_reply, CN_IDX_DRBD, GFP_KERNEL); + if (rr && rr != -ESRCH) + printk(KERN_INFO "drbd: cn_netlink_send()=%d\n", rr); +} + --- linux-2.6.28.orig/ubuntu/drbd/lru_cache.c +++ linux-2.6.28/ubuntu/drbd/lru_cache.c @@ -0,0 +1,398 @@ +/* +-*- linux-c -*- + lru_cache.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + + */ + +#include +#include +#include /* for memset */ +#include /* for seq_printf */ +#include "lru_cache.h" + +#define STATIC static + +/* this is developers aid only! */ +#define PARANOIA_ENTRY() BUG_ON(test_and_set_bit(__LC_PARANOIA, &lc->flags)) +#define PARANOIA_LEAVE() do { clear_bit(__LC_PARANOIA, &lc->flags); smp_mb__after_clear_bit(); } while (0) +#define RETURN(x...) do { PARANOIA_LEAVE(); return x ; } while (0) + +static inline size_t size_of_lc(unsigned int e_count, size_t e_size) +{ + return sizeof(struct lru_cache) + + e_count * (e_size + sizeof(struct hlist_head)); +} + +static inline void lc_init(struct lru_cache *lc, + const size_t bytes, const char *name, + const unsigned int e_count, const size_t e_size, + void *private_p) +{ + struct lc_element *e; + unsigned int i; + + memset(lc, 0, bytes); + INIT_LIST_HEAD(&lc->in_use); + INIT_LIST_HEAD(&lc->lru); + INIT_LIST_HEAD(&lc->free); + lc->element_size = e_size; + lc->nr_elements = e_count; + lc->new_number = -1; + lc->lc_private = private_p; + lc->name = name; + for (i = 0; i < e_count; i++) { + e = lc_entry(lc, i); + e->lc_number = LC_FREE; + list_add(&e->list, &lc->free); + // memset(,0,) did the rest of init for us + } +} + +/** + * lc_alloc: allocates memory for @e_count objects of @e_size bytes plus the + * struct lru_cache, and the hash table slots. + * returns pointer to a newly initialized lru_cache object with said parameters. + */ +struct lru_cache *lc_alloc(const char *name, unsigned int e_count, + size_t e_size, void *private_p) +{ + struct lru_cache *lc; + size_t bytes; + + BUG_ON(!e_count); + e_size = max(sizeof(struct lc_element),e_size); + bytes = size_of_lc(e_count, e_size); + lc = vmalloc(bytes); + if (lc) + lc_init(lc, bytes, name, e_count, e_size, private_p); + return lc; +} + +/** + * lc_free: Frees memory allocated by lc_alloc. + * @lc: The lru_cache object + */ +void lc_free(struct lru_cache *lc) +{ + vfree(lc); +} + +/** + * lc_reset: does a full reset for @lc and the hash table slots. + * It is roughly the equivalent of re-allocating a fresh lru_cache object, + * basically a short cut to lc_free(lc); lc = lc_alloc(...); + */ +void lc_reset(struct lru_cache *lc) +{ + lc_init(lc, size_of_lc(lc->nr_elements, lc->element_size), lc->name, + lc->nr_elements, lc->element_size, lc->lc_private); +} + +size_t lc_printf_stats(struct seq_file *seq, struct lru_cache* lc) +{ + /* NOTE: + * total calls to lc_get are + * (starving + hits + misses) + * misses include "dirty" count (update from an other thread in + * progress) and "changed", when this in fact lead to an successful + * update of the cache. + */ + return seq_printf(seq, "\t%s: used:%u/%u " + "hits:%lu misses:%lu starving:%lu dirty:%lu changed:%lu\n", + lc->name, lc->used, lc->nr_elements, + lc->hits, lc->misses, lc->starving, lc->dirty, lc->changed); +} + +static unsigned int lc_hash_fn(struct lru_cache *lc, unsigned int enr) +{ + return enr % lc->nr_elements; +} + + +/** + * lc_find: Returns the pointer to an element, if the element is present + * in the hash table. In case it is not this function returns NULL. + * @lc: The lru_cache object + * @enr: element number + */ +struct lc_element *lc_find(struct lru_cache *lc, unsigned int enr) +{ + struct hlist_node *n; + struct lc_element *e; + + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + hlist_for_each_entry(e, n, lc->slot + lc_hash_fn(lc, enr), colision) { + if (e->lc_number == enr) + return e; + } + return NULL; +} + +STATIC struct lc_element *lc_evict(struct lru_cache *lc) +{ + struct list_head *n; + struct lc_element *e; + + if (list_empty(&lc->lru)) return NULL; + + n = lc->lru.prev; + e = list_entry(n, struct lc_element, list); + + list_del(&e->list); + hlist_del(&e->colision); + return e; +} + +/** + * lc_del: Removes an element from the cache (and therefore adds the + * element's storage to the free list) + * + * @lc: The lru_cache object + * @e: The element to remove + */ +void lc_del(struct lru_cache *lc, struct lc_element *e) +{ + /* FIXME what to do with refcnt != 0 ? */ + PARANOIA_ENTRY(); + BUG_ON(e->refcnt); + list_del(&e->list); + hlist_del_init(&e->colision); + e->lc_number = LC_FREE; + e->refcnt = 0; + list_add(&e->list, &lc->free); + RETURN(); +} + +STATIC struct lc_element *lc_get_unused_element(struct lru_cache *lc) +{ + struct list_head *n; + + if (list_empty(&lc->free)) return lc_evict(lc); + + n = lc->free.next; + list_del(n); + return list_entry(n, struct lc_element, list); +} + +STATIC int lc_unused_element_available(struct lru_cache *lc) +{ + if (!list_empty(&lc->free)) return 1; /* something on the free list */ + if (!list_empty(&lc->lru)) return 1; /* something to evict */ + + return 0; +} + + +/** + * lc_get: Finds an element in the cache, increases its usage count, + * "touches" and returns it. + * In case the requested number is not present, it needs to be added to the + * cache. Therefore it is possible that an other element becomes eviced from + * the cache. In either case, the user is notified so he is able to e.g. keep + * a persistent log of the cache changes, and therefore the objects in use. + * + * Return values: + * NULL if the requested element number was not in the cache, and no unused + * element could be recycled + * pointer to the element with the REQUESTED element number + * In this case, it can be used right away + * + * pointer to an UNUSED element with some different element number. + * In this case, the cache is marked dirty, and the returned element + * pointer is removed from the lru list and hash collision chains. + * The user now should do whatever houskeeping is necessary. Then he + * needs to call lc_element_changed(lc,element_pointer), to finish the + * change. + * + * NOTE: The user needs to check the lc_number on EACH use, so he recognizes + * any cache set change. + * + * @lc: The lru_cache object + * @enr: element number + */ +struct lc_element *lc_get(struct lru_cache *lc, unsigned int enr) +{ + struct lc_element *e; + + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + + PARANOIA_ENTRY(); + if (lc->flags & LC_STARVING) { + ++lc->starving; + RETURN(NULL); + } + + e = lc_find(lc, enr); + if (e) { + ++lc->hits; + if (e->refcnt++ == 0) + lc->used++; + list_move(&e->list, &lc->in_use); /* Not evictable... */ + RETURN(e); + } + + ++lc->misses; + + /* In case there is nothing available and we can not kick out + * the LRU element, we have to wait ... + */ + if (!lc_unused_element_available(lc)) { + __set_bit(__LC_STARVING, &lc->flags); + RETURN(NULL); + } + + /* it was not present in the cache, find an unused element, + * which then is replaced. + * we need to update the cache; serialize on lc->flags & LC_DIRTY + */ + if (test_and_set_bit(__LC_DIRTY, &lc->flags)) { + ++lc->dirty; + RETURN(NULL); + } + + e = lc_get_unused_element(lc); + BUG_ON(!e); + + clear_bit(__LC_STARVING, &lc->flags); + BUG_ON(++e->refcnt != 1); + lc->used++; + + lc->changing_element = e; + lc->new_number = enr; + + RETURN(e); +} + +/* similar to lc_get, + * but only gets a new reference on an existing element. + * you either get the requested element, or NULL. + */ +struct lc_element *lc_try_get(struct lru_cache *lc, unsigned int enr) +{ + struct lc_element *e; + + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + + PARANOIA_ENTRY(); + if (lc->flags & LC_STARVING) { + ++lc->starving; + RETURN(NULL); + } + + e = lc_find(lc, enr); + if (e) { + ++lc->hits; + if (e->refcnt++ == 0) + lc->used++; + list_move(&e->list, &lc->in_use); /* Not evictable... */ + } + RETURN(e); +} + +void lc_changed(struct lru_cache *lc, struct lc_element *e) +{ + PARANOIA_ENTRY(); + BUG_ON(e != lc->changing_element); + ++lc->changed; + e->lc_number = lc->new_number; + list_add(&e->list, &lc->in_use); + hlist_add_head(&e->colision, + lc->slot + lc_hash_fn(lc, lc->new_number)); + lc->changing_element = NULL; + lc->new_number = -1; + clear_bit(__LC_DIRTY, &lc->flags); + smp_mb__after_clear_bit(); + PARANOIA_LEAVE(); +} + + +unsigned int lc_put(struct lru_cache *lc, struct lc_element *e) +{ + BUG_ON(!lc); + BUG_ON(!lc->nr_elements); + BUG_ON(!e); + + PARANOIA_ENTRY(); + BUG_ON(e->refcnt == 0); + BUG_ON(e == lc->changing_element); + if (--e->refcnt == 0) { + /* move it to the front of LRU. */ + list_move(&e->list, &lc->lru); + lc->used--; + clear_bit(__LC_STARVING, &lc->flags); + smp_mb__after_clear_bit(); + } + RETURN(e->refcnt); +} + + +/** + * lc_set: Sets an element in the cache. You might use this function to + * setup the cache. It is expected that the elements are properly initialized. + * @lc: The lru_cache object + * @enr: element number + * @index: The elements' position in the cache + */ +void lc_set(struct lru_cache *lc, unsigned int enr, int index) +{ + struct lc_element *e; + + if (index < 0 || index >= lc->nr_elements) + return; + + e = lc_entry(lc, index); + e->lc_number = enr; + + hlist_del_init(&e->colision); + hlist_add_head( &e->colision, lc->slot + lc_hash_fn(lc, enr) ); + list_move(&e->list, e->refcnt ? &lc->in_use : &lc->lru); +} + +/** + * lc_dump: Dump a complete LRU cache to seq in textual form. + */ +void lc_dump(struct lru_cache *lc, struct seq_file *seq, char *utext, + void (*detail) (struct seq_file *, struct lc_element *) ) +{ + unsigned int nr_elements = lc->nr_elements; + struct lc_element *e; + int i; + + seq_printf(seq, "\tnn: lc_number refcnt %s\n ", utext); + for (i = 0; i < nr_elements; i++) { + e = lc_entry(lc, i); + if (e->lc_number == LC_FREE) { + seq_printf(seq, "\t%2d: FREE\n", i ); + } else { + seq_printf(seq, "\t%2d: %4u %4u ", i, + e->lc_number, + e->refcnt ); + detail(seq, e); + } + } +} + --- linux-2.6.28.orig/ubuntu/drbd/drbd_strings.c +++ linux-2.6.28/ubuntu/drbd/drbd_strings.c @@ -0,0 +1,116 @@ +/* + drbd.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2003-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2003-2008, Philipp Reisner . + Copyright (C) 2003-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include + +static const char *drbd_conn_s_names[] = { + [StandAlone] = "StandAlone", + [Disconnecting] = "Disconnecting", + [Unconnected] = "Unconnected", + [Timeout] = "Timeout", + [BrokenPipe] = "BrokenPipe", + [NetworkFailure] = "NetworkFailure", + [ProtocolError] = "ProtocolError", + [WFConnection] = "WFConnection", + [WFReportParams] = "WFReportParams", + [TearDown] = "TearDown", + [Connected] = "Connected", + [StartingSyncS] = "StartingSyncS", + [StartingSyncT] = "StartingSyncT", + [WFBitMapS] = "WFBitMapS", + [WFBitMapT] = "WFBitMapT", + [WFSyncUUID] = "WFSyncUUID", + [SyncSource] = "SyncSource", + [SyncTarget] = "SyncTarget", + [VerifyS] = "VerifyS", + [VerifyT] = "VerifyT", + [PausedSyncS] = "PausedSyncS", + [PausedSyncT] = "PausedSyncT" +}; + +static const char *drbd_role_s_names[] = { + [Primary] = "Primary", + [Secondary] = "Secondary", + [Unknown] = "Unknown" +}; + +static const char *drbd_disk_s_names[] = { + [Diskless] = "Diskless", + [Attaching] = "Attaching", + [Failed] = "Failed", + [Negotiating] = "Negotiating", + [Inconsistent] = "Inconsistent", + [Outdated] = "Outdated", + [DUnknown] = "DUnknown", + [Consistent] = "Consistent", + [UpToDate] = "UpToDate", +}; + +static const char *drbd_state_sw_errors[] = { + [-SS_TwoPrimaries] = "Multiple primaries not allowed by config", + [-SS_NoUpToDateDisk] = + "Refusing to be Primary without at least one UpToDate disk", + [-SS_BothInconsistent] = "Refusing to be inconsistent on both nodes", + [-SS_SyncingDiskless] = "Refusing to be syncing and diskless", + [-SS_ConnectedOutdates] = "Refusing to be Outdated while Connected", + [-SS_PrimaryNOP] = "Refusing to be Primary while peer is not outdated", + [-SS_ResyncRunning] = "Can not start OV/resync since it is already active", + [-SS_AlreadyStandAlone] = "Can not disconnect a StandAlone device", + [-SS_CW_FailedByPeer] = "State changed was refused by peer node", + [-SS_IsDiskLess] = + "Device is diskless, the requesed operation requires a disk", + [-SS_DeviceInUse] = "Device is held open by someone", + [-SS_NoNetConfig] = "Have no net/connection configuration", + [-SS_NoVerifyAlg] = "Need a verify algorithm to start online verify", + [-SS_NeedConnection] = "Need a connection to start verify or resync", + [-SS_NotSupported] = "Peer does not support protocol", + [-SS_LowerThanOutdated] = "Disk state is lower than outdated", + [-SS_InTransientState] = "In transient state, retry after next state change", + [-SS_ConcurrentStChg] = "Concurrent state changes detected and aborted", +}; + +const char *conns_to_name(enum drbd_conns s) +{ + /* enums are unsigned... */ + return s > PausedSyncT ? "TOO_LARGE" : drbd_conn_s_names[s]; +} + +const char *roles_to_name(enum drbd_role s) +{ + return s > Secondary ? "TOO_LARGE" : drbd_role_s_names[s]; +} + +const char *disks_to_name(enum drbd_disk_state s) +{ + return s > UpToDate ? "TOO_LARGE" : drbd_disk_s_names[s]; +} + +const char *set_st_err_name(enum set_st_err err) +{ + return err < SS_NotSupported ? "TOO_SMALL" : + err > SS_TwoPrimaries ? "TOO_LARGE" + : drbd_state_sw_errors[-err]; +} --- linux-2.6.28.orig/ubuntu/drbd/drbd_req.h +++ linux-2.6.28/ubuntu/drbd/drbd_req.h @@ -0,0 +1,333 @@ +/* + drbd_req.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2006-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2006-2008, Lars Ellenberg . + Copyright (C) 2006-2008, Philipp Reisner . + + DRBD 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. + + DRBD 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _DRBD_REQ_H +#define _DRBD_REQ_H + +#include +#include + +#include +#include +#include "drbd_int.h" + +/* The request callbacks will be called in irq context by the IDE drivers, + and in Softirqs/Tasklets/BH context by the SCSI drivers, + and by the receiver and worker in kernel-thread context. + Try to get the locking right :) */ + +/* + * Objects of type struct drbd_request do only exist on a Primary node, and are + * associated with IO requests originating from the block layer above us. + * + * There are quite a few things that may happen to a drbd request + * during its lifetime. + * + * It will be created. + * It will be marked with the intention to be + * submitted to local disk and/or + * send via the network. + * + * It has to be placed on the transfer log and other housekeeping lists, + * In case we have a network connection. + * FIXME I believe that for consistency we should place even READ requests + * on these lists, so we can moan when we detect that the other node is + * writing to an area that we currently read from (when this happens, our + * users are broken). + * + * It may be identified as a concurrent (write) request + * and be handled accordingly. + * + * It may me handed over to the local disk subsystem. + * It may be completed by the local disk subsystem, + * either sucessfully or with io-error. + * In case it is a READ request, and it failed locally, + * it may be retried remotely. + * + * It may be queued for sending. + * It may be handed over to the network stack, + * which may fail. + * It may be acknowledged by the "peer" according to the wire_protocol in use. + * this may be a negative ack. + * It may receive a faked ack when the network connection is lost and the + * transfer log is cleaned up. + * Sending may be canceled due to network connection loss. + * When it finally has outlived its time, + * corresponding dirty bits in the resync-bitmap may be cleared or set, + * it will be destroyed, + * and completion will be signalled to the originator, + * with or without "success". + * + * See also documentation/drbd-request-state-overview.dot + * (dot -Tps2 documentation/drbd-request-state-overview.dot | display -) + */ + +enum drbd_req_event { + created, + to_be_send, + to_be_submitted, + + /* XXX yes, now I am inconsistent... + * these two are not "events" but "actions" + * oh, well... */ + queue_for_net_write, + queue_for_net_read, + + send_canceled, + send_failed, + handed_over_to_network, + connection_lost_while_pending, + recv_acked_by_peer, + write_acked_by_peer, + write_acked_by_peer_and_sis, /* and set_in_sync */ + conflict_discarded_by_peer, + neg_acked, + barrier_acked, /* in protocol A and B */ + data_received, /* (remote read) */ + + read_completed_with_error, + write_completed_with_error, + completed_ok, +}; + +/* encoding of request states for now. we don't actually need that many bits. + * we don't need to do atomic bit operations either, since most of the time we + * need to look at the connection state and/or manipulate some lists at the + * same time, so we should hold the request lock anyways. + */ +enum drbd_req_state_bits { + /* 210 + * 000: no local possible + * 001: to be submitted + * UNUSED, we could map: 011: submitted, completion still pending + * 110: completed ok + * 010: completed with error + */ + __RQ_LOCAL_PENDING, + __RQ_LOCAL_COMPLETED, + __RQ_LOCAL_OK, + + /* 76543 + * 00000: no network possible + * 00001: to be send + * 00011: to be send, on worker queue + * 00101: sent, expecting recv_ack (B) or write_ack (C) + * 11101: sent, + * recv_ack (B) or implicit "ack" (A), + * still waiting for the barrier ack. + * master_bio may already be completed and invalidated. + * 11100: write_acked (C), + * data_received (for remote read, any protocol) + * or finally the barrier ack has arrived (B,A)... + * request can be freed + * 01100: neg-acked (write, protocol C) + * or neg-d-acked (read, any protocol) + * or killed from the transfer log + * during cleanup after connection loss + * request can be freed + * 01000: canceled or send failed... + * request can be freed + */ + + /* if "SENT" is not set, yet, this can still fail or be canceled. + * if "SENT" is set already, we still wait for an Ack packet. + * when cleared, the master_bio may be completed. + * in (B,A) the request object may still linger on the transaction log + * until the corresponding barrier ack comes in */ + __RQ_NET_PENDING, + + /* If it is QUEUED, and it is a WRITE, it is also registered in the + * transfer log. Currently we need this flag to avoid conflicts between + * worker canceling the request and tl_clear_barrier killing it from + * transfer log. We should restructure the code so this conflict does + * no longer occur. */ + __RQ_NET_QUEUED, + + /* well, actually only "handed over to the network stack". + * + * TODO can potentially be dropped because of the similar meaning + * of RQ_NET_SENT and ~RQ_NET_QUEUED. + * however it is not exactly the same. before we drop it + * we must ensure that we can tell a request with network part + * from a request without, regardless of what happens to it. */ + __RQ_NET_SENT, + + /* when set, the request may be freed (if RQ_NET_QUEUED is clear). + * in (C) this happens when WriteAck is received, + * in (B,A) when the corresponding BarrierAck is received */ + __RQ_NET_DONE, + + /* whether or not we know (C) or pretend (B,A) that the write + * was successfully written on the peer. + */ + __RQ_NET_OK, + + /* peer called drbd_set_in_sync() for this write */ + __RQ_NET_SIS, + + /* keep this last, its for the RQ_NET_MASK */ + __RQ_NET_MAX, +}; + +#define RQ_LOCAL_PENDING (1UL << __RQ_LOCAL_PENDING) +#define RQ_LOCAL_COMPLETED (1UL << __RQ_LOCAL_COMPLETED) +#define RQ_LOCAL_OK (1UL << __RQ_LOCAL_OK) + +#define RQ_LOCAL_MASK ((RQ_LOCAL_OK << 1)-1) /* 0x07 */ + +#define RQ_NET_PENDING (1UL << __RQ_NET_PENDING) +#define RQ_NET_QUEUED (1UL << __RQ_NET_QUEUED) +#define RQ_NET_SENT (1UL << __RQ_NET_SENT) +#define RQ_NET_DONE (1UL << __RQ_NET_DONE) +#define RQ_NET_OK (1UL << __RQ_NET_OK) +#define RQ_NET_SIS (1UL << __RQ_NET_SIS) + +/* 0x1f8 */ +#define RQ_NET_MASK (((1UL << __RQ_NET_MAX)-1) & ~RQ_LOCAL_MASK) + +/* epoch entries */ +static inline +struct hlist_head *ee_hash_slot(struct drbd_conf *mdev, sector_t sector) +{ + BUG_ON(mdev->ee_hash_s == 0); + return mdev->ee_hash + + ((unsigned int)(sector>>HT_SHIFT) % mdev->ee_hash_s); +} + +/* transfer log (drbd_request objects) */ +static inline +struct hlist_head *tl_hash_slot(struct drbd_conf *mdev, sector_t sector) +{ + BUG_ON(mdev->tl_hash_s == 0); + return mdev->tl_hash + + ((unsigned int)(sector>>HT_SHIFT) % mdev->tl_hash_s); +} + +/* when we receive the ACK for a write request, + * verify that we actually know about it */ +static inline struct drbd_request *_ack_id_to_req(struct drbd_conf *mdev, + u64 id, sector_t sector) +{ + struct hlist_head *slot = tl_hash_slot(mdev, sector); + struct hlist_node *n; + struct drbd_request *req; + + hlist_for_each_entry(req, n, slot, colision) { + if ((unsigned long)req == (unsigned long)id) + { + if (req->sector != sector) { + ERR("_ack_id_to_req: found req %p but it has " + "wrong sector (%llus versus %llus)\n", req, + (unsigned long long)req->sector, + (unsigned long long)sector); + break; + } + return req; + } + } + ERR("_ack_id_to_req: failed to find req %p, sector %llus in list\n", + (void *)(unsigned long)id, (unsigned long long)sector); + return NULL; +} + +/* application reads (drbd_request objects) */ +static struct hlist_head *ar_hash_slot(struct drbd_conf *mdev, sector_t sector) +{ + return mdev->app_reads_hash + + ((unsigned int)(sector) % APP_R_HSIZE); +} + +/* when we receive the answer for a read request, + * verify that we actually know about it */ +static inline struct drbd_request *_ar_id_to_req(struct drbd_conf *mdev, + u64 id, sector_t sector) +{ + struct hlist_head *slot = ar_hash_slot(mdev, sector); + struct hlist_node *n; + struct drbd_request *req; + + hlist_for_each_entry(req, n, slot, colision) { + if ((unsigned long)req == (unsigned long)id) + { + D_ASSERT(req->sector == sector); + return req; + } + } + return NULL; +} + +static inline struct drbd_request *drbd_req_new(struct drbd_conf *mdev, + struct bio *bio_src) +{ + struct bio *bio; + struct drbd_request *req = + mempool_alloc(drbd_request_mempool, GFP_NOIO); + if (likely(req)) { + bio = bio_clone(bio_src, GFP_NOIO); /* XXX cannot fail?? */ + + req->rq_state = 0; + req->mdev = mdev; + req->master_bio = bio_src; + req->private_bio = bio; + req->epoch = 0; + req->sector = bio->bi_sector; + req->size = bio->bi_size; + req->start_time = jiffies; + INIT_HLIST_NODE(&req->colision); + INIT_LIST_HEAD(&req->tl_requests); + + bio->bi_private = req; + bio->bi_end_io = drbd_endio_pri; + bio->bi_next = NULL; + } + return req; +} + +static inline void drbd_req_free(struct drbd_request *req) +{ + mempool_free(req, drbd_request_mempool); +} + +static inline int overlaps(sector_t s1, int l1, sector_t s2, int l2) +{ + return !( ( s1 + (l1>>9) <= s2 ) || ( s1 >= s2 + (l2>>9) ) ); +} + +/* aparently too large to be inlined... + * moved to drbd_req.c */ +extern void _req_may_be_done(struct drbd_request *req, int error); +extern void _req_mod(struct drbd_request *req, + enum drbd_req_event what, int error); + +/* If you need it irqsave, do it your self! */ +static inline void req_mod(struct drbd_request *req, + enum drbd_req_event what, int error) +{ + struct drbd_conf *mdev = req->mdev; + spin_lock_irq(&mdev->req_lock); + _req_mod(req, what, error); + spin_unlock_irq(&mdev->req_lock); +} +#endif --- linux-2.6.28.orig/ubuntu/drbd/BOM +++ linux-2.6.28/ubuntu/drbd/BOM @@ -0,0 +1,2 @@ +Downloaded from: http://oss.linbit.com/drbd/ +Current Version: 8.2.6 --- linux-2.6.28.orig/ubuntu/drbd/drbd_receiver.c +++ linux-2.6.28/ubuntu/drbd/drbd_receiver.c @@ -0,0 +1,3652 @@ +/* +-*- linux-c -*- + drbd_receiver.c + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 1999-2008, Philipp Reisner . + Copyright (C) 2002-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define __KERNEL_SYSCALLS__ +#include +#include +#include +#ifdef HAVE_LINUX_SCATTERLIST_H +#include +#endif +#include +#include "drbd_int.h" +#include "drbd_req.h" + +#ifdef DBG_ASSERTS +void drbd_assert_breakpoint(struct drbd_conf *mdev, char *exp, + char *file, int line) +{ + ERR("ASSERT( %s ) in %s:%d\n", exp, file, line); +} +#endif + +#define GFP_TRY ( __GFP_HIGHMEM | __GFP_NOWARN ) + +/** + * drbd_bp_alloc: Returns a page. Fails only if a signal comes in. + */ +STATIC struct page *drbd_pp_alloc(struct drbd_conf *mdev, gfp_t gfp_mask) +{ + unsigned long flags = 0; + struct page *page; + DEFINE_WAIT(wait); + + /* FIXME Add some usefull watermark again to "kick_lo", if pages get + * used up too quickly. The watermark that had been in place here did + * not make sense. + */ + + spin_lock_irqsave(&drbd_pp_lock, flags); + /* This lock needs to lock out irq because we might call drbd_pp_free() + from IRQ context. + FIXME but why irq _save_ ? + this is only called from drbd_alloc_ee, + and that is strictly process context! */ + page = drbd_pp_pool; + if (page) { + drbd_pp_pool = (struct page *)page_private(page); + set_page_private(page, 0); /* just to be polite */ + drbd_pp_vacant--; + } + spin_unlock_irqrestore(&drbd_pp_lock, flags); + if (page) + goto got_page; + + drbd_kick_lo(mdev); + + for (;;) { + prepare_to_wait(&drbd_pp_wait, &wait, TASK_INTERRUPTIBLE); + + /* try the pool again, maybe the drbd_kick_lo set some free */ + spin_lock_irqsave(&drbd_pp_lock, flags); + page = drbd_pp_pool; + if (page) { + drbd_pp_pool = (struct page *)page_private(page); + drbd_pp_vacant--; + } + spin_unlock_irqrestore(&drbd_pp_lock, flags); + + if (page) + break; + + /* hm. pool was empty. try to allocate from kernel. + * don't wait, if none is available, though. + */ + if (atomic_read(&mdev->pp_in_use) + < mdev->net_conf->max_buffers) { + page = alloc_page(GFP_TRY); + if (page) + break; + } + + /* doh. still no page. + * either used up the configured maximum number, + * or we are low on memory. + * wait for someone to return a page into the pool. + * unless, of course, someone signalled us. + */ + if (signal_pending(current)) { + DRBD_WARN("drbd_pp_alloc interrupted!\n"); + finish_wait(&drbd_pp_wait, &wait); + return NULL; + } + drbd_kick_lo(mdev); + schedule(); + } + finish_wait(&drbd_pp_wait, &wait); + + got_page: + atomic_inc(&mdev->pp_in_use); + return page; +} + +STATIC void drbd_pp_free(struct drbd_conf *mdev, struct page *page) +{ + unsigned long flags = 0; + int free_it; + + spin_lock_irqsave(&drbd_pp_lock, flags); + if (drbd_pp_vacant > (DRBD_MAX_SEGMENT_SIZE/PAGE_SIZE)*minor_count) { + free_it = 1; + } else { + set_page_private(page, (unsigned long)drbd_pp_pool); + drbd_pp_pool = page; + drbd_pp_vacant++; + free_it = 0; + } + spin_unlock_irqrestore(&drbd_pp_lock, flags); + + atomic_dec(&mdev->pp_in_use); + + if (free_it) + __free_page(page); + + /* + * FIXME + * typically there are no waiters. + * we should try to avoid any unnecessary call to wake_up. + */ + wake_up(&drbd_pp_wait); +} + +/* +You need to hold the req_lock: + drbd_free_ee() + _drbd_wait_ee_list_empty() + +You must not have the req_lock: + drbd_alloc_ee() + drbd_init_ee() + drbd_release_ee() + drbd_ee_fix_bhs() + drbd_process_done_ee() + drbd_clear_done_ee() + drbd_wait_ee_list_empty() +*/ + +struct Tl_epoch_entry *drbd_alloc_ee(struct drbd_conf *mdev, + u64 id, + sector_t sector, + unsigned int data_size, + gfp_t gfp_mask) __must_hold(local) +{ + struct request_queue *q; + struct Tl_epoch_entry *e; + struct bio_vec *bvec; + struct page *page; + struct bio *bio; + unsigned int ds; + int i; + + e = mempool_alloc(drbd_ee_mempool, gfp_mask); + if (!e) { + ERR("alloc_ee: Allocation of an EE failed\n"); + return NULL; + } + + bio = bio_alloc(GFP_KERNEL, div_ceil(data_size, PAGE_SIZE)); + if (!bio) { + ERR("alloc_ee: Allocation of a bio failed\n"); + goto fail1; + } + + bio->bi_bdev = mdev->bc->backing_bdev; + bio->bi_sector = sector; + + ds = data_size; + while (ds) { + page = drbd_pp_alloc(mdev, gfp_mask); + if (!page) { + ERR("alloc_ee: Allocation of a page failed\n"); + goto fail2; + } + if (!bio_add_page(bio, page, min_t(int, ds, PAGE_SIZE), 0)) { + drbd_pp_free(mdev, page); + ERR("alloc_ee: bio_add_page(s=%llu," + "data_size=%u,ds=%u) failed\n", + (unsigned long long)sector, data_size, ds); + + q = bdev_get_queue(bio->bi_bdev); + if (q->merge_bvec_fn) { + struct bvec_merge_data bvm = { + .bi_bdev = bio->bi_bdev, + .bi_sector = bio->bi_sector, + .bi_size = bio->bi_size, + .bi_rw = bio->bi_rw, + }; + ERR("merge_bvec_fn() = %d\n", + q->merge_bvec_fn(q, &bvm, + &bio->bi_io_vec[bio->bi_vcnt])); + } + + /* dump more of the bio. */ + DUMPI(bio->bi_max_vecs); + DUMPI(bio->bi_vcnt); + DUMPI(bio->bi_size); + DUMPI(bio->bi_phys_segments); + DUMPI(bio->bi_hw_segments); + + goto fail2; + break; + } + ds -= min_t(int, ds, PAGE_SIZE); + } + + D_ASSERT( data_size == bio->bi_size); + + bio->bi_private = e; + e->mdev = mdev; + e->sector = sector; + e->size = bio->bi_size; + + e->private_bio = bio; + e->block_id = id; + INIT_HLIST_NODE(&e->colision); + e->barrier_nr = 0; + e->barrier_nr2 = 0; + e->flags = 0; + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("allocated EE sec=%llus size=%u ee=%p\n", + (unsigned long long)sector, data_size, e); + ); + + return e; + + fail2: + __bio_for_each_segment(bvec, bio, i, 0) { + drbd_pp_free(mdev, bvec->bv_page); + } + bio_put(bio); + fail1: + mempool_free(e, drbd_ee_mempool); + + return NULL; +} + +void drbd_free_ee(struct drbd_conf *mdev, struct Tl_epoch_entry *e) +{ + struct bio *bio = e->private_bio; + struct bio_vec *bvec; + int i; + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Free EE sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + + __bio_for_each_segment(bvec, bio, i, 0) { + drbd_pp_free(mdev, bvec->bv_page); + } + + bio_put(bio); + + D_ASSERT(hlist_unhashed(&e->colision)); + + mempool_free(e, drbd_ee_mempool); +} + +/* currently on module unload only */ +int drbd_release_ee(struct drbd_conf *mdev, struct list_head *list) +{ + int count = 0; + struct Tl_epoch_entry *e; + struct list_head *le; + + spin_lock_irq(&mdev->req_lock); + while (!list_empty(list)) { + le = list->next; + list_del(le); + e = list_entry(le, struct Tl_epoch_entry, w.list); + drbd_free_ee(mdev, e); + count++; + } + spin_unlock_irq(&mdev->req_lock); + + return count; +} + + +STATIC void reclaim_net_ee(struct drbd_conf *mdev) +{ + struct Tl_epoch_entry *e; + struct list_head *le, *tle; + + /* The EEs are always appended to the end of the list. Since + they are sent in order over the wire, they have to finish + in order. As soon as we see the first not finished we can + stop to examine the list... */ + + list_for_each_safe(le, tle, &mdev->net_ee) { + e = list_entry(le, struct Tl_epoch_entry, w.list); + if ( drbd_bio_has_active_page(e->private_bio) ) break; + list_del(le); + drbd_free_ee(mdev, e); + } +} + + +/* + * This function is called from _asender only_ + * but see also comments in _req_mod(,barrier_acked) + * and receive_Barrier_no_tcq. + * + * Move entries from net_ee to done_ee, if ready. + * Grab done_ee, call all callbacks, free the entries. + * The callbacks typically send out ACKs. + */ +STATIC int drbd_process_done_ee(struct drbd_conf *mdev) +{ + LIST_HEAD(work_list); + struct Tl_epoch_entry *e, *t; + int ok = 1; + int do_clear_bit = test_bit(WRITE_ACK_PENDING, &mdev->flags); + + spin_lock_irq(&mdev->req_lock); + reclaim_net_ee(mdev); + list_splice_init(&mdev->done_ee, &work_list); + spin_unlock_irq(&mdev->req_lock); + + /* possible callbacks here: + * e_end_block, and e_end_resync_block, e_send_discard_ack. + * all ignore the last argument. + */ + list_for_each_entry_safe(e, t, &work_list, w.list) { + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("Process EE on done_ee sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + /* list_del not necessary, next/prev members not touched */ + if (e->w.cb(mdev, &e->w, 0) == 0) ok = 0; + drbd_free_ee(mdev, e); + } + if (do_clear_bit) + clear_bit(WRITE_ACK_PENDING, &mdev->flags); + wake_up(&mdev->ee_wait); + + return ok; +} + + + +/* clean-up helper for drbd_disconnect */ +void _drbd_clear_done_ee(struct drbd_conf *mdev) +{ + struct list_head *le; + struct Tl_epoch_entry *e; + int n = 0; + + MUST_HOLD(&mdev->req_lock); + + reclaim_net_ee(mdev); + + while (!list_empty(&mdev->done_ee)) { + le = mdev->done_ee.next; + list_del(le); + e = list_entry(le, struct Tl_epoch_entry, w.list); + if (mdev->net_conf->wire_protocol == DRBD_PROT_C + || is_syncer_block_id(e->block_id)) + ++n; + + if (!hlist_unhashed(&e->colision)) hlist_del_init(&e->colision); + drbd_free_ee(mdev, e); + } + + sub_unacked(mdev, n); +} + +void _drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head) +{ + DEFINE_WAIT(wait); + MUST_HOLD(&mdev->req_lock); + + /* avoids spin_lock/unlock + * and calling prepare_to_wait in the fast path */ + while (!list_empty(head)) { + prepare_to_wait(&mdev->ee_wait, &wait, TASK_UNINTERRUPTIBLE); + spin_unlock_irq(&mdev->req_lock); + drbd_kick_lo(mdev); + schedule(); + finish_wait(&mdev->ee_wait, &wait); + spin_lock_irq(&mdev->req_lock); + } +} + +void drbd_wait_ee_list_empty(struct drbd_conf *mdev, struct list_head *head) +{ + spin_lock_irq(&mdev->req_lock); + _drbd_wait_ee_list_empty(mdev, head); + spin_unlock_irq(&mdev->req_lock); +} + +STATIC struct socket *drbd_accept(struct drbd_conf *mdev, struct socket *sock) +{ + struct socket *newsock; + int err = 0; + + err = sock->ops->listen(sock, 5); + if (err) + goto out; + + if (sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &newsock)) + goto out; + + newsock->type = sock->type; + newsock->ops = sock->ops; + + err = newsock->ops->accept(sock, newsock, 0); + if (err < 0) + goto out_release; + + return newsock; + +out_release: + sock_release(newsock); +out: + if (err != -EAGAIN && err != -EINTR) + ERR("accept failed! %d\n", err); + return NULL; +} + +STATIC int drbd_recv_short(struct drbd_conf *mdev, struct socket *sock, + void *buf, size_t size, int flags) +{ + mm_segment_t oldfs; + struct kvec iov = { + .iov_base = buf, + .iov_len = size, + }; + struct msghdr msg = { + .msg_iovlen = 1, + .msg_iov = (struct iovec *)&iov, + .msg_flags = (flags ? flags : MSG_WAITALL | MSG_NOSIGNAL) + }; + int rv; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + rv = sock_recvmsg(sock, &msg, size, msg.msg_flags); + set_fs(oldfs); + + return rv; +} + +STATIC int drbd_recv(struct drbd_conf *mdev, void *buf, size_t size) +{ + mm_segment_t oldfs; + struct kvec iov = { + .iov_base = buf, + .iov_len = size, + }; + struct msghdr msg = { + .msg_iovlen = 1, + .msg_iov = (struct iovec *)&iov, + .msg_flags = MSG_WAITALL | MSG_NOSIGNAL + }; + int rv; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + + for (;;) { + rv = sock_recvmsg(mdev->data.socket, &msg, size, msg.msg_flags); + if (rv == size) + break; + + /* Note: + * ECONNRESET other side closed the connection + * ERESTARTSYS (on sock) we got a signal + */ + + if (rv < 0) { + if (rv == -ECONNRESET) + INFO("sock was reset by peer\n"); + else if (rv != -ERESTARTSYS) + ERR("sock_recvmsg returned %d\n", rv); + break; + } else if (rv == 0) { + INFO("sock was shut down by peer\n"); + break; + } else { + /* signal came in, or peer/link went down, + * after we read a partial message + */ + /* D_ASSERT(signal_pending(current)); */ + break; + } + }; + + set_fs(oldfs); + + if (rv != size) + drbd_force_state(mdev, NS(conn, BrokenPipe)); + + return rv; +} + +STATIC struct socket *drbd_try_connect(struct drbd_conf *mdev) +{ + int err; + struct socket *sock; + struct sockaddr_in src_in; + + if (!inc_net(mdev)) return NULL; + + err = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); + if (err) { + dec_net(mdev); + ERR("sock_creat(..)=%d\n", err); + return NULL; + } + + sock->sk->sk_rcvtimeo = + sock->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ; + + /* explicitly bind to the configured IP as source IP + * for the outgoing connections. + * This is needed for multihomed hosts and to be + * able to use lo: interfaces for drbd. + * Make sure to use 0 as portnumber, so linux selects + * a free one dynamically. + */ + memcpy(&src_in, &(mdev->net_conf->my_addr), sizeof(struct sockaddr_in)); + src_in.sin_port = 0; + + err = sock->ops->bind(sock, + (struct sockaddr *) &src_in, + sizeof(struct sockaddr_in)); + if (err) { + ERR("Unable to bind source sock (%d)\n", err); + sock_release(sock); + sock = NULL; + dec_net(mdev); + return sock; + } + + err = sock->ops->connect(sock, + (struct sockaddr *)mdev->net_conf->peer_addr, + mdev->net_conf->peer_addr_len, 0); + + if (err) { + sock_release(sock); + sock = NULL; + } + + dec_net(mdev); + return sock; +} + +STATIC struct socket *drbd_wait_for_connect(struct drbd_conf *mdev) +{ + int err; + struct socket *sock, *sock2; + + if (!inc_net(mdev)) return NULL; + + err = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock2); + if (err) { + dec_net(mdev); + ERR("sock_creat(..)=%d\n", err); + return NULL; + } + + sock2->sk->sk_reuse = 1; /* SO_REUSEADDR */ + sock2->sk->sk_rcvtimeo = + sock2->sk->sk_sndtimeo = mdev->net_conf->try_connect_int*HZ; + + err = sock2->ops->bind(sock2, + (struct sockaddr *) mdev->net_conf->my_addr, + mdev->net_conf->my_addr_len); + dec_net(mdev); + + if (err) { + ERR("Unable to bind sock2 (%d)\n", err); + sock_release(sock2); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return NULL; + } + + sock = drbd_accept(mdev, sock2); + sock_release(sock2); + + return sock; +} + +int drbd_do_handshake(struct drbd_conf *mdev); +int drbd_do_auth(struct drbd_conf *mdev); + +STATIC int drbd_send_fp(struct drbd_conf *mdev, + struct socket *sock, enum Drbd_Packet_Cmd cmd) +{ + struct Drbd_Header *h = (struct Drbd_Header *) &mdev->data.sbuf.head; + + return _drbd_send_cmd(mdev, sock, cmd, h, sizeof(*h), 0); +} + +STATIC enum Drbd_Packet_Cmd drbd_recv_fp(struct drbd_conf *mdev, struct socket *sock) +{ + struct Drbd_Header *h = (struct Drbd_Header *) &mdev->data.sbuf.head; + int rr; + + rr = drbd_recv_short(mdev, sock, h, sizeof(*h), 0); + + if (rr == sizeof(*h) && h->magic == BE_DRBD_MAGIC) + return be16_to_cpu(h->command); + + return 0xffff; +} + +/** + * drbd_socket_okay: + * Tests if the connection behind the socket still exists. If not it frees + * the socket. + */ +STATIC int drbd_socket_okay(struct drbd_conf *mdev, struct socket **sock) +{ + int rr; + char tb[4]; + + rr = drbd_recv_short(mdev, *sock, tb, 4, MSG_DONTWAIT | MSG_PEEK); + + if (rr > 0 || rr == -EAGAIN) { + return TRUE; + } else { + sock_release(*sock); + *sock = NULL; + return FALSE; + } +} + +/* + * return values: + * 1 yess, we have a valid connection + * 0 oops, did not work out, please try again + * -1 peer talks different language, + * no point in trying again, please go standalone. + * -2 We do not have a network config... + */ +STATIC int drbd_connect(struct drbd_conf *mdev) +{ + struct socket *s, *sock, *msock; + int try, h, ok; + + D_ASSERT(!mdev->data.socket); + + if (test_and_clear_bit(CREATE_BARRIER, &mdev->flags)) + ERR("CREATE_BARRIER flag was set in drbd_connect - now cleared!\n"); + + if (drbd_request_state(mdev, NS(conn, WFConnection)) < SS_Success ) + return -2; + + clear_bit(DISCARD_CONCURRENT, &mdev->flags); + + sock = NULL; + msock = NULL; + + do { + for (try = 0;;) { + /* 3 tries, this should take less than a second! */ + s = drbd_try_connect(mdev); + if (s || ++try >= 3) + break; + /* give the other side time to call bind() & listen() */ + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); + } + + if (s) { + if (!sock) { + drbd_send_fp(mdev, s, HandShakeS); + sock = s; + s = NULL; + } else if (!msock) { + drbd_send_fp(mdev, s, HandShakeM); + msock = s; + s = NULL; + } else { + ERR("Logic error in drbd_connect()\n"); + return -1; + } + } + + if (sock && msock) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ / 10); + ok = drbd_socket_okay(mdev, &sock); + ok = drbd_socket_okay(mdev, &msock) && ok; + if (ok) break; + } + + s = drbd_wait_for_connect(mdev); + if (s) { + switch (drbd_recv_fp(mdev, s)) { + case HandShakeS: + if (sock) + sock_release(sock); + sock = s; + break; + case HandShakeM: + if (msock) + sock_release(msock); + msock = s; + set_bit(DISCARD_CONCURRENT, &mdev->flags); + break; + default: + DRBD_WARN("Error receiving initial packet\n"); + sock_release(s); + } + } + + if (mdev->state.conn <= Disconnecting) + return -1; + if (signal_pending(current)) { + flush_signals(current); + smp_rmb(); + if (get_t_state(&mdev->receiver) == Exiting) { + if (sock) + sock_release(sock); + if (msock) + sock_release(msock); + return -1; + } + } + + if (sock && msock) { + ok = drbd_socket_okay(mdev, &sock); + ok = drbd_socket_okay(mdev, &msock) && ok; + if (ok) break; + } + } while (1); + + msock->sk->sk_reuse = 1; /* SO_REUSEADDR */ + sock->sk->sk_reuse = 1; /* SO_REUSEADDR */ + + sock->sk->sk_allocation = GFP_NOIO; + msock->sk->sk_allocation = GFP_NOIO; + + sock->sk->sk_priority = TC_PRIO_BULK; + /* FIXME fold to limits. should be done in drbd_ioctl */ + sock->sk->sk_sndbuf = mdev->net_conf->sndbuf_size; + sock->sk->sk_rcvbuf = mdev->net_conf->sndbuf_size; + /* NOT YET ... + * sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; + * sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; + * first set it to the HandShake timeout, wich is hardcoded for now: */ + sock->sk->sk_sndtimeo = + sock->sk->sk_rcvtimeo = 2*HZ; + sock->sk->sk_userlocks |= SOCK_SNDBUF_LOCK | SOCK_RCVBUF_LOCK; + + msock->sk->sk_priority = TC_PRIO_INTERACTIVE; + msock->sk->sk_sndbuf = 2*32767; + msock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; + msock->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; + + mdev->data.socket = sock; + mdev->meta.socket = msock; + mdev->last_received = jiffies; + + D_ASSERT(mdev->asender.task == NULL); + + h = drbd_do_handshake(mdev); + if (h <= 0) + return h; + + if (mdev->cram_hmac_tfm) { + /* drbd_request_state(mdev, NS(conn, WFAuth)); */ + if (!drbd_do_auth(mdev)) { + ERR("Authentication of peer failed\n"); + return -1; + } + } + + if (drbd_request_state(mdev, NS(conn, WFReportParams)) < SS_Success) + return 0; + + sock->sk->sk_sndtimeo = mdev->net_conf->timeout*HZ/10; + sock->sk->sk_rcvtimeo = MAX_SCHEDULE_TIMEOUT; + + atomic_set(&mdev->packet_seq, 0); + mdev->peer_seq = 0; + + drbd_thread_start(&mdev->asender); + + drbd_send_protocol(mdev); + drbd_send_sync_param(mdev, &mdev->sync_conf); + drbd_send_sizes(mdev); + drbd_send_uuids(mdev); + drbd_send_state(mdev); + clear_bit(USE_DEGR_WFC_T, &mdev->flags); + + return 1; +} + +STATIC int drbd_recv_header(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + int r; + + r = drbd_recv(mdev, h, sizeof(*h)); + + if (unlikely( r != sizeof(*h) )) { + ERR("short read expecting header on sock: r=%d\n", r); + return FALSE; + }; + h->command = be16_to_cpu(h->command); + h->length = be16_to_cpu(h->length); + if (unlikely( h->magic != BE_DRBD_MAGIC )) { + ERR("magic?? on data m: 0x%lx c: %d l: %d\n", + (long)be32_to_cpu(h->magic), + h->command, h->length); + return FALSE; + } + mdev->last_received = jiffies; + + return TRUE; +} + +STATIC int receive_Barrier_no_tcq(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + int rv; + int epoch_size; + struct Drbd_Barrier_Packet *p = (struct Drbd_Barrier_Packet *)h; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + + rv = drbd_recv(mdev, h->payload, h->length); + ERR_IF(rv != h->length) return FALSE; + + inc_unacked(mdev); + + if (mdev->net_conf->wire_protocol != DRBD_PROT_C) + drbd_kick_lo(mdev); + + spin_lock_irq(&mdev->req_lock); + _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + epoch_size = mdev->epoch_size; + mdev->epoch_size = 0; + spin_unlock_irq(&mdev->req_lock); + + /* BarrierAck may imply that the corresponding extent is dropped from + * the activity log, which means it would not be resynced in case the + * Primary crashes now. + * Just waiting for write_completion is not enough, + * better flush to make sure it is all on stable storage. */ + if (!test_bit(LL_DEV_NO_FLUSH, &mdev->flags) && inc_local(mdev)) { + rv = blkdev_issue_flush(mdev->bc->backing_bdev, NULL); + dec_local(mdev); + if (rv == -EOPNOTSUPP) /* don't try again */ + set_bit(LL_DEV_NO_FLUSH, &mdev->flags); + if (rv) + ERR("local disk flush failed with status %d\n",rv); + } + + /* FIXME CAUTION! receiver thread sending via msock. + * to make sure this BarrierAck will not be received before the asender + * had a chance to send all the write acks corresponding to this epoch, + * wait_for that bit to clear... */ + set_bit(WRITE_ACK_PENDING, &mdev->flags); + wake_asender(mdev); + rv = wait_event_interruptible(mdev->ee_wait, + !test_bit(WRITE_ACK_PENDING, &mdev->flags)); + + if (rv == 0 && mdev->state.conn >= Connected) + rv = drbd_send_b_ack(mdev, p->barrier, epoch_size); + else + rv = 0; + dec_unacked(mdev); + + return rv; +} + +/* used from receive_RSDataReply (recv_resync_read) + * and from receive_Data */ +STATIC struct Tl_epoch_entry * +read_in_block(struct drbd_conf *mdev, u64 id, sector_t sector, int data_size) __must_hold(local) +{ + struct Tl_epoch_entry *e; + struct bio_vec *bvec; + struct page *page; + struct bio *bio; + int dgs, ds, i, rr; + void *dig_in = mdev->int_dig_in; + void *dig_vv = mdev->int_dig_vv; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ? + crypto_hash_digestsize(mdev->integrity_r_tfm) : 0; + + if (dgs) { + rr = drbd_recv(mdev, dig_in, dgs); + if (rr != dgs) { + DRBD_WARN("short read receiving data digest: read %d expected %d\n", + rr, dgs); + return NULL; + } + } + + data_size -= dgs; + + ERR_IF(data_size & 0x1ff) return NULL; + ERR_IF(data_size > DRBD_MAX_SEGMENT_SIZE) return NULL; + + e = drbd_alloc_ee(mdev, id, sector, data_size, GFP_KERNEL); + if (!e) + return NULL; + bio = e->private_bio; + ds = data_size; + bio_for_each_segment(bvec, bio, i) { + page = bvec->bv_page; + rr = drbd_recv(mdev, kmap(page), min_t(int, ds, PAGE_SIZE)); + kunmap(page); + if ( rr != min_t(int, ds, PAGE_SIZE) ) { + drbd_free_ee(mdev, e); + DRBD_WARN("short read receiving data: read %d expected %d\n", + rr, min_t(int, ds, PAGE_SIZE)); + return NULL; + } + ds -= rr; + } + + if (dgs) { + drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv); + if (memcmp(dig_in,dig_vv,dgs)) { + ERR("Digest integrity check FAILED.\n"); + drbd_bcast_ee(mdev, "digest failed", + dgs, dig_in, dig_vv, e); + drbd_free_ee(mdev, e); + return NULL; + } + } + mdev->recv_cnt += data_size>>9; + return e; +} + +/* drbd_drain_block() just takes a data block + * out of the socket input buffer, and discards it. + */ +STATIC int drbd_drain_block(struct drbd_conf *mdev, int data_size) +{ + struct page *page; + int rr, rv = 1; + void *data; + + page = drbd_pp_alloc(mdev, GFP_KERNEL); + + data = kmap(page); + while (data_size) { + rr = drbd_recv(mdev, data, min_t(int, data_size, PAGE_SIZE)); + if ( rr != min_t(int, data_size, PAGE_SIZE) ) { + rv = 0; + DRBD_WARN("short read receiving data: read %d expected %d\n", + rr, min_t(int, data_size, PAGE_SIZE)); + break; + } + data_size -= rr; + } + kunmap(page); + drbd_pp_free(mdev, page); + return rv; +} + +/* kick lower level device, if we have more than (arbitrary number) + * reference counts on it, which typically are locally submitted io + * requests. don't use unacked_cnt, so we speed up proto A and B, too. */ +static void maybe_kick_lo(struct drbd_conf *mdev) +{ + /* FIXME hysteresis ?? */ + if (atomic_read(&mdev->local_cnt) >= mdev->net_conf->unplug_watermark) + drbd_kick_lo(mdev); +} + +STATIC int recv_dless_read(struct drbd_conf *mdev, struct drbd_request *req, + sector_t sector, int data_size) +{ + struct bio_vec *bvec; + struct bio *bio; + int dgs, rr, i, expect; + void *dig_in = mdev->int_dig_in; + void *dig_vv = mdev->int_dig_vv; + + dgs = (mdev->agreed_pro_version >= 87 && mdev->integrity_r_tfm) ? + crypto_hash_digestsize(mdev->integrity_r_tfm) : 0; + + if (dgs) { + rr = drbd_recv(mdev, dig_in, dgs); + if (rr != dgs) { + DRBD_WARN("short read receiving data reply digest: read %d expected %d\n", + rr, dgs); + return 0; + } + } + + data_size -= dgs; + + bio = req->master_bio; + D_ASSERT( sector == bio->bi_sector ); + + bio_for_each_segment(bvec, bio, i) { + expect = min_t(int, data_size, bvec->bv_len); + rr = drbd_recv(mdev, + kmap(bvec->bv_page)+bvec->bv_offset, + expect); + kunmap(bvec->bv_page); + if (rr != expect) { + DRBD_WARN("short read receiving data reply: " + "read %d expected %d\n", + rr, expect); + return 0; + } + data_size -= rr; + } + + if (dgs) { + drbd_csum(mdev, mdev->integrity_r_tfm, bio, dig_vv); + if (memcmp(dig_in,dig_vv,dgs)) { + ERR("Digest integrity check FAILED. Broken NICs?\n"); + return 0; + } + } + + D_ASSERT(data_size == 0); + /* FIXME recv_cnt accounting ?? */ + return 1; +} + +/* e_end_resync_block() is called via + * drbd_process_done_ee() by asender only */ +STATIC int e_end_resync_block(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + sector_t sector = e->sector; + int ok; + + D_ASSERT(hlist_unhashed(&e->colision)); + + if (likely( drbd_bio_uptodate(e->private_bio) )) { + drbd_set_in_sync(mdev, sector, e->size); + ok = drbd_send_ack(mdev, RSWriteAck, e); + } else { + /* Record failure to sync */ + drbd_rs_failed_io(mdev, sector, e->size); + + ok = drbd_send_ack(mdev, NegAck, e); + ok &= drbd_io_error(mdev, FALSE); + } + dec_unacked(mdev); + + return ok; +} + +STATIC int recv_resync_read(struct drbd_conf *mdev, sector_t sector, int data_size) __releases(local) +{ + struct Tl_epoch_entry *e; + + e = read_in_block(mdev, ID_SYNCER, sector, data_size); + if (!e) { + dec_local(mdev); + return FALSE; + } + + dec_rs_pending(mdev); + + e->private_bio->bi_end_io = drbd_endio_write_sec; + e->private_bio->bi_rw = WRITE; + e->w.cb = e_end_resync_block; + + inc_unacked(mdev); + /* corresponding dec_unacked() in e_end_resync_block() + * respective _drbd_clear_done_ee */ + + spin_lock_irq(&mdev->req_lock); + list_add(&e->w.list, &mdev->sync_ee); + spin_unlock_irq(&mdev->req_lock); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("submit EE (RS)WRITE sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + dump_internal_bio("Sec", mdev, e->private_bio, 0); + drbd_generic_make_request(mdev, DRBD_FAULT_RS_WR, e->private_bio); + /* accounting done in endio */ + + maybe_kick_lo(mdev); + return TRUE; +} + +STATIC int receive_DataReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct drbd_request *req; + sector_t sector; + unsigned int header_size, data_size; + int ok; + struct Drbd_Data_Packet *p = (struct Drbd_Data_Packet *)h; + + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + /* I expect a block to be a multiple of 512 byte, + * and no more than DRBD_MAX_SEGMENT_SIZE. + * is this too restrictive? */ + ERR_IF(data_size == 0) return FALSE; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + sector = be64_to_cpu(p->sector); + + spin_lock_irq(&mdev->req_lock); + req = _ar_id_to_req(mdev, p->block_id, sector); + spin_unlock_irq(&mdev->req_lock); + if (unlikely(!req)) { + ERR("Got a corrupt block_id/sector pair(1).\n"); + return FALSE; + } + + /* hlist_del(&req->colision) is done in _req_may_be_done, to avoid + * special casing it there for the various failure cases. + * still no race with drbd_fail_pending_reads */ + ok = recv_dless_read(mdev, req, sector, data_size); + + if (ok) + req_mod(req, data_received, 0); + /* else: nothing. handled from drbd_disconnect... + * I don't think we may complete this just yet + * in case we are "on-disconnect: freeze" */ + + return ok; +} + +STATIC int receive_RSDataReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + unsigned int header_size, data_size; + int ok; + struct Drbd_Data_Packet *p = (struct Drbd_Data_Packet *)h; + + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + sector = be64_to_cpu(p->sector); + D_ASSERT(p->block_id == ID_SYNCER); + + if (inc_local(mdev)) { + /* data is submitted to disk within recv_resync_read. + * corresponding dec_local done below on error, + * or in drbd_endio_write_sec. */ + /* FIXME paranoia: + * verify that the corresponding bit is set. + * in case we are Primary SyncTarget, + * verify there are no pending write request to that area. + */ + ok = recv_resync_read(mdev, sector, data_size); + } else { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Can not write resync data to local disk.\n"); + + ok = drbd_drain_block(mdev, data_size); + + drbd_send_ack_dp(mdev, NegAck, p); + } + + return ok; +} + +/* e_end_block() is called via drbd_process_done_ee(). + * this means this function only runs in the asender thread + * + * for a broken example implementation of the TCQ barrier version of + * e_end_block see older revisions... + */ +STATIC int e_end_block(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + sector_t sector = e->sector; + /* unsigned int epoch_size; */ + int ok = 1, pcmd; + + if (mdev->net_conf->wire_protocol == DRBD_PROT_C) { + if (likely(drbd_bio_uptodate(e->private_bio))) { + pcmd = (mdev->state.conn >= SyncSource && + mdev->state.conn <= PausedSyncT && + e->flags & EE_MAY_SET_IN_SYNC) ? + RSWriteAck : WriteAck; + ok &= drbd_send_ack(mdev, pcmd, e); + if (pcmd == RSWriteAck) + drbd_set_in_sync(mdev, sector, e->size); + } else { + /* FIXME I think we should send a NegAck regardless of + * which protocol is in effect. + * In which case we would need to make sure that any + * NegAck is sent. Basically that means that + * drbd_process_done_ee may not list_del() the ee + * before this callback did run... + * maybe even move the list_del(e) in here... */ + ok = drbd_send_ack(mdev, NegAck, e); + ok &= drbd_io_error(mdev, FALSE); + /* we expect it to be marked out of sync anyways... + * maybe assert this? */ + } + dec_unacked(mdev); + } else if (unlikely(!drbd_bio_uptodate(e->private_bio))) { + ok = drbd_io_error(mdev, FALSE); + } + + /* we delete from the conflict detection hash _after_ we sent out the + * WriteAck / NegAck, to get the sequence number right. */ + if (mdev->net_conf->two_primaries) { + spin_lock_irq(&mdev->req_lock); + D_ASSERT(!hlist_unhashed(&e->colision)); + hlist_del_init(&e->colision); + spin_unlock_irq(&mdev->req_lock); + } else { + D_ASSERT(hlist_unhashed(&e->colision)); + } + + return ok; +} + +STATIC int e_send_discard_ack(struct drbd_conf *mdev, struct drbd_work *w, int unused) +{ + struct Tl_epoch_entry *e = (struct Tl_epoch_entry *)w; + int ok = 1; + + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + ok = drbd_send_ack(mdev, DiscardAck, e); + + spin_lock_irq(&mdev->req_lock); + D_ASSERT(!hlist_unhashed(&e->colision)); + hlist_del_init(&e->colision); + spin_unlock_irq(&mdev->req_lock); + + dec_unacked(mdev); + + return ok; +} + +/* Called from receive_Data. + * Synchronize packets on sock with packets on msock. + * + * This is here so even when a Data packet traveling via sock overtook an Ack + * packet traveling on msock, they are still processed in the order they have + * been sent. + * + * Note: we don't care for Ack packets overtaking Data packets. + * + * In case packet_seq is larger than mdev->peer_seq number, there are + * outstanding packets on the msock. We wait for them to arrive. + * In case we are the logically next packet, we update mdev->peer_seq + * ourselves. Correctly handles 32bit wrap around. + * FIXME verify that atomic_t guarantees 32bit wrap around, + * otherwise we have to play tricks with << ... + * + * Assume we have a 10 GBit connection, that is about 1<<30 byte per second, + * about 1<<21 sectors per second. So "worst" case, we have 1<<3 == 8 seconds + * for the 24bit wrap (historical atomic_t guarantee on some archs), and we have + * 1<<9 == 512 seconds aka ages for the 32bit wrap around... + * + * returns 0 if we may process the packet, + * -ERESTARTSYS if we were interrupted (by disconnect signal). */ +static int drbd_wait_peer_seq(struct drbd_conf *mdev, const u32 packet_seq) +{ + DEFINE_WAIT(wait); + int ret = 0; + spin_lock(&mdev->peer_seq_lock); + for (;;) { + prepare_to_wait(&mdev->seq_wait, &wait, TASK_INTERRUPTIBLE); + if (seq_le(packet_seq, mdev->peer_seq+1)) + break; + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + spin_unlock(&mdev->peer_seq_lock); + schedule(); + spin_lock(&mdev->peer_seq_lock); + } + finish_wait(&mdev->seq_wait, &wait); + if (mdev->peer_seq+1 == packet_seq) + mdev->peer_seq++; + spin_unlock(&mdev->peer_seq_lock); + return ret; +} + +/* mirrored write */ +STATIC int receive_Data(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + struct Tl_epoch_entry *e; + struct Drbd_Data_Packet *p = (struct Drbd_Data_Packet *)h; + int header_size, data_size; + int rw = WRITE; + unsigned int barrier_nr = 0; + unsigned int epoch_size = 0; + u32 dp_flags; + + /* FIXME merge this code dups into some helper function */ + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + ERR_IF(data_size == 0) return FALSE; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + if (!inc_local(mdev)) { + /* data is submitted to disk at the end of this function. + * corresponding dec_local done either below (on error), + * or in drbd_endio_write_sec. */ + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Can not write mirrored data block " + "to local disk.\n"); + spin_lock(&mdev->peer_seq_lock); + if (mdev->peer_seq+1 == be32_to_cpu(p->seq_num)) + mdev->peer_seq++; + spin_unlock(&mdev->peer_seq_lock); + + drbd_send_ack_dp(mdev, NegAck, p); + mdev->epoch_size++; /* spin lock ? */ + return drbd_drain_block(mdev, data_size); + } + + sector = be64_to_cpu(p->sector); + e = read_in_block(mdev, p->block_id, sector, data_size); + if (!e) { + dec_local(mdev); + return FALSE; + } + + e->private_bio->bi_end_io = drbd_endio_write_sec; + e->private_bio->bi_rw = WRITE; + e->w.cb = e_end_block; + + dp_flags = be32_to_cpu(p->dp_flags); + if (dp_flags & DP_HARDBARRIER) + rw |= (1<flags |= EE_MAY_SET_IN_SYNC; + + /* I'm the receiver, I do hold a net_cnt reference. */ + if (!mdev->net_conf->two_primaries) { + spin_lock_irq(&mdev->req_lock); + } else { + /* don't get the req_lock yet, + * we may sleep in drbd_wait_peer_seq */ + const int size = e->size; + const int discard = test_bit(DISCARD_CONCURRENT, &mdev->flags); + DEFINE_WAIT(wait); + struct drbd_request *i; + struct hlist_node *n; + struct hlist_head *slot; + int first; + + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + BUG_ON(mdev->ee_hash == NULL); + BUG_ON(mdev->tl_hash == NULL); + + /* conflict detection and handling: + * 1. wait on the sequence number, + * in case this data packet overtook ACK packets. + * 2. check our hash tables for conflicting requests. + * we only need to walk the tl_hash, since an ee can not + * have a conflict with an other ee: on the submitting + * node, the corresponding req had already been conflicting, + * and a conflicting req is never sent. + * + * Note: for two_primaries, we are protocol C, + * so there cannot be any request that is DONE + * but still on the transfer log. + * + * unconditionally add to the ee_hash. + * + * if no conflicting request is found: + * submit. + * + * if any conflicting request is found + * that has not yet been acked, + * AND I have the "discard concurrent writes" flag: + * queue (via done_ee) the DiscardAck; OUT. + * + * if any conflicting request is found: + * block the receiver, waiting on misc_wait + * until no more conflicting requests are there, + * or we get interrupted (disconnect). + * + * we do not just write after local io completion of those + * requests, but only after req is done completely, i.e. + * we wait for the DiscardAck to arrive! + * + * then proceed normally, i.e. submit. + */ + if (drbd_wait_peer_seq(mdev, be32_to_cpu(p->seq_num))) + goto out_interrupted; + + spin_lock_irq(&mdev->req_lock); + + hlist_add_head(&e->colision, ee_hash_slot(mdev, sector)); + +#define OVERLAPS overlaps(i->sector, i->size, sector, size) + slot = tl_hash_slot(mdev, sector); + first = 1; + for (;;) { + int have_unacked = 0; + int have_conflict = 0; + prepare_to_wait(&mdev->misc_wait, &wait, + TASK_INTERRUPTIBLE); + hlist_for_each_entry(i, n, slot, colision) { + if (OVERLAPS) { + /* only ALERT on first iteration, + * we may be woken up early... */ + if (first) + ALERT("%s[%u] Concurrent local write detected!" + " new: %llus +%u; pending: %llus +%u\n", + current->comm, current->pid, + (unsigned long long)sector, size, + (unsigned long long)i->sector, i->size); + if (i->rq_state & RQ_NET_PENDING) + ++have_unacked; + ++have_conflict; + } + } +#undef OVERLAPS + if (!have_conflict) + break; + + /* Discard Ack only for the _first_ iteration */ + if (first && discard && have_unacked) { + ALERT("Concurrent write! [DISCARD BY FLAG] sec=%llus\n", + (unsigned long long)sector); + inc_unacked(mdev); + mdev->epoch_size++; + e->w.cb = e_send_discard_ack; + list_add_tail(&e->w.list, &mdev->done_ee); + + spin_unlock_irq(&mdev->req_lock); + + /* we could probably send that DiscardAck ourselves, + * but I don't like the receiver using the msock */ + + dec_local(mdev); + wake_asender(mdev); + finish_wait(&mdev->misc_wait, &wait); + return TRUE; + } + + if (signal_pending(current)) { + hlist_del_init(&e->colision); + + spin_unlock_irq(&mdev->req_lock); + + finish_wait(&mdev->misc_wait, &wait); + goto out_interrupted; + } + + spin_unlock_irq(&mdev->req_lock); + if (first) { + first = 0; + ALERT("Concurrent write! [W AFTERWARDS] " + "sec=%llus\n", (unsigned long long)sector); + } else if (discard) { + /* we had none on the first iteration. + * there must be none now. */ + D_ASSERT(have_unacked == 0); + } + schedule(); + spin_lock_irq(&mdev->req_lock); + } + finish_wait(&mdev->misc_wait, &wait); + } + + /* when using TCQ: + * note that, when using tagged command queuing, we may + * have more than one reorder domain "active" at a time. + * + * THINK: + * do we have any guarantees that we get the completion + * events of the different reorder domains in order? + * or does the api only "guarantee" that the events + * _happened_ in order, but eventually the completion + * callbacks are shuffeled again? + * + * note that I wonder about the order in which the + * callbacks are run, I am reasonable confident that the + * actual completion happens in order. + * + * - can it happen that the tagged write completion is + * called even though not all of the writes before it + * have run their completion callback? + * - can it happen that some completion callback of some + * write after the tagged one is run, even though the + * callback of the tagged one itself is still pending? + * + * if this can happen, we either need to drop our "debug + * assertion" about the epoch size and just trust our code + * and the layers below us (nah, won't do that). + * + * or we need to replace the "active_ee" list by some sort + * of "transfer log" on the receiving side, too, which + * uses epoch counters per reorder domain. + */ + + /* when using tcq: + * if we got a barrier packet before, but at that time the active_ee + * was not yet empty, we just "remembered" this barrier request. + * + * if this is the first data packet since that barrier, maybe meanwhile + * all previously active writes have been completed? + * if so, send the b_ack right now + * (though, maybe rather move it into the e_end_block callback, + * where it would be sent as soon as possible). + * + * otherwise, tag the write with the barrier number, so it + * will trigger the b_ack before its own ack. + */ + if (mdev->next_barrier_nr) { + /* only when using TCQ */ + if (list_empty(&mdev->active_ee)) { + barrier_nr = mdev->next_barrier_nr; + epoch_size = mdev->epoch_size; + mdev->epoch_size = 0; + } else { + e->barrier_nr = mdev->next_barrier_nr; + } + rw |= (1<next_barrier_nr = 0; + } + list_add(&e->w.list, &mdev->active_ee); + spin_unlock_irq(&mdev->req_lock); + + if (barrier_nr) { + /* only when using TCQ + * maybe rather move it into the e_end_block callback, + * where it would be sent as soon as possible). + */ + (void)drbd_send_b_ack(mdev, + cpu_to_be32(barrier_nr), epoch_size); + } + + switch (mdev->net_conf->wire_protocol) { + case DRBD_PROT_C: + inc_unacked(mdev); + /* corresponding dec_unacked() in e_end_block() + * respective _drbd_clear_done_ee */ + break; + case DRBD_PROT_B: + /* I really don't like it that the receiver thread + * sends on the msock, but anyways */ + drbd_send_ack(mdev, RecvAck, e); + break; + case DRBD_PROT_A: + /* nothing to do */ + break; + } + + if (mdev->state.pdsk == Diskless) { + /* In case we have the only disk of the cluster, */ + drbd_set_out_of_sync(mdev, e->sector, e->size); + e->flags |= EE_CALL_AL_COMPLETE_IO; + drbd_al_begin_io(mdev, e->sector); + } + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("submit EE (DATA)WRITE sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + /* FIXME drbd_al_begin_io in case we have two primaries... */ + e->private_bio->bi_rw = rw; + dump_internal_bio("Sec", mdev, e->private_bio, 0); + drbd_generic_make_request(mdev, DRBD_FAULT_DT_WR, e->private_bio); + /* accounting done in endio */ + + maybe_kick_lo(mdev); + return TRUE; + +out_interrupted: + /* yes, the epoch_size now is imbalanced. + * but we drop the connection anyways, so we don't have a chance to + * receive a barrier... atomic_inc(&mdev->epoch_size); */ + dec_local(mdev); + drbd_free_ee(mdev, e); + return FALSE; +} + +STATIC int receive_DataRequest(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + const sector_t capacity = drbd_get_capacity(mdev->this_bdev); + struct Tl_epoch_entry *e; + struct digest_info *di; + int size,digest_size; + unsigned int fault_type; + struct Drbd_BlockRequest_Packet *p = + (struct Drbd_BlockRequest_Packet *)h; + const int brps = sizeof(*p)-sizeof(*h); + + if (drbd_recv(mdev, h->payload, brps) != brps) + return FALSE; + + sector = be64_to_cpu(p->sector); + size = be32_to_cpu(p->blksize); + + if (size <= 0 || (size & 0x1ff) != 0 || size > DRBD_MAX_SEGMENT_SIZE) { + ERR("%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, + (unsigned long long)sector, size); + return FALSE; + } + if ( sector + (size>>9) > capacity) { + ERR("%s:%d: sector: %llus, size: %u\n", __FILE__, __LINE__, + (unsigned long long)sector, size); + return FALSE; + } + + if (!inc_local_if_state(mdev, UpToDate)) { + if (DRBD_ratelimit(5*HZ, 5)) + ERR("Can not satisfy peer's read request, " + "no local data.\n"); + drbd_send_ack_rp(mdev, h->command == DataRequest ? NegDReply : + NegRSDReply , p); + return TRUE; + } + + e = drbd_alloc_ee(mdev, p->block_id, sector, size, GFP_KERNEL); + if (!e) { + dec_local(mdev); + return FALSE; + } + + /* FIXME actually, it could be a READA originating from the peer, + * also it could have set some flags (e.g. BIO_RW_SYNC) ... */ + e->private_bio->bi_rw = READ; + e->private_bio->bi_end_io = drbd_endio_read_sec; + + switch (h->command) { + case DataRequest: + e->w.cb = w_e_end_data_req; + fault_type = DRBD_FAULT_DT_RD; + break; + case RSDataRequest: + e->w.cb = w_e_end_rsdata_req; + fault_type = DRBD_FAULT_RS_RD; + /* Eventually this should become asynchrously. Currently it + * blocks the whole receiver just to delay the reading of a + * resync data block. + * the drbd_work_queue mechanism is made for this... + */ + if (!drbd_rs_begin_io(mdev, sector)) { + /* we have been interrupted, + * probably connection lost! */ + D_ASSERT(signal_pending(current)); + dec_local(mdev); + drbd_free_ee(mdev, e); + return 0; + } + break; + + case OVReply: + fault_type = DRBD_FAULT_RS_RD; + digest_size = h->length - brps ; + di = kmalloc(sizeof(*di) + digest_size ,GFP_KERNEL); + if(!di) { + dec_local(mdev); + drbd_free_ee(mdev,e); + return 0; + } + + di->digest_size = digest_size; + di->digest = (((char *)di)+sizeof(struct digest_info)); + + if (drbd_recv(mdev, di->digest, digest_size) != digest_size) { + dec_local(mdev); + drbd_free_ee(mdev,e); + kfree(di); + return FALSE; + } + + e->block_id = (u64)(unsigned long)di; + e->w.cb = w_e_end_ov_reply; + dec_rs_pending(mdev); + break; + + case OVRequest: + e->w.cb = w_e_end_ov_req; + fault_type = DRBD_FAULT_RS_RD; + /* Eventually this should become asynchrously. Currently it + * blocks the whole receiver just to delay the reading of a + * resync data block. + * the drbd_work_queue mechanism is made for this... + */ + if (!drbd_rs_begin_io(mdev,sector)) { + /* we have been interrupted, + * probably connection lost! */ + D_ASSERT(signal_pending(current)); + dec_local(mdev); + drbd_free_ee(mdev,e); + return 0; + } + break; + + + default:; /* avoid compiler warning */ + ERR("unexpected command (%s) in receive_DataRequest\n", + cmdname(h->command)); + fault_type = DRBD_FAULT_MAX; + } + + spin_lock_irq(&mdev->req_lock); + list_add(&e->w.list, &mdev->read_ee); + spin_unlock_irq(&mdev->req_lock); + + inc_unacked(mdev); + + MTRACE(TraceTypeEE, TraceLvlAll, + INFO("submit EE READ sec=%llus size=%u ee=%p\n", + (unsigned long long)e->sector, e->size, e); + ); + + dump_internal_bio("Sec", mdev, e->private_bio, 0); + drbd_generic_make_request(mdev, fault_type, e->private_bio); + maybe_kick_lo(mdev); + + return TRUE; +} + +STATIC int drbd_asb_recover_0p(struct drbd_conf *mdev) __must_hold(local) +{ + int self, peer, rv = -100; + unsigned long ch_self, ch_peer; + + self = mdev->bc->md.uuid[Bitmap] & 1; + peer = mdev->p_uuid[Bitmap] & 1; + + ch_peer = mdev->p_uuid[UUID_SIZE]; + ch_self = mdev->comm_bm_set; + + switch ( mdev->net_conf->after_sb_0p ) { + case Consensus: + case DiscardSecondary: + case CallHelper: + ERR("Configuration error.\n"); + break; + case Disconnect: + break; + case DiscardYoungerPri: + if (self == 0 && peer == 1) { rv = -1; break; } + if (self == 1 && peer == 0) { rv = 1; break; } + /* Else fall through to one of the other strategies... */ + case DiscardOlderPri: + if (self == 0 && peer == 1) { rv = 1; break; } + if (self == 1 && peer == 0) { rv = -1; break; } + /* Else fall through to one of the other strategies... */ + DRBD_WARN("Discard younger/older primary did not found a decision\n" + "Using discard-least-changes instead\n"); + case DiscardZeroChg: + if (ch_peer == 0 && ch_self == 0) { + rv = test_bit(DISCARD_CONCURRENT, &mdev->flags) + ? -1 : 1; + break; + } else { + if (ch_peer == 0) { rv = 1; break; } + if (ch_self == 0) { rv = -1; break; } + } + if (mdev->net_conf->after_sb_0p == DiscardZeroChg) + break; + case DiscardLeastChg: + if ( ch_self < ch_peer ) + rv = -1; + else if (ch_self > ch_peer) + rv = 1; + else /* ( ch_self == ch_peer ) */ + /* Well, then use something else. */ + rv = test_bit(DISCARD_CONCURRENT, &mdev->flags) + ? -1 : 1; + break; + case DiscardLocal: + rv = -1; + break; + case DiscardRemote: + rv = 1; + } + + return rv; +} + +STATIC int drbd_asb_recover_1p(struct drbd_conf *mdev) __must_hold(local) +{ + int self, peer, hg, rv = -100; + + self = mdev->bc->md.uuid[Bitmap] & 1; + peer = mdev->p_uuid[Bitmap] & 1; + + switch ( mdev->net_conf->after_sb_1p ) { + case DiscardYoungerPri: + case DiscardOlderPri: + case DiscardLeastChg: + case DiscardLocal: + case DiscardRemote: + ERR("Configuration error.\n"); + break; + case Disconnect: + break; + case Consensus: + hg = drbd_asb_recover_0p(mdev); + if (hg == -1 && mdev->state.role == Secondary) + rv = hg; + if (hg == 1 && mdev->state.role == Primary) + rv = hg; + break; + case Violently: + rv = drbd_asb_recover_0p(mdev); + break; + case DiscardSecondary: + return mdev->state.role == Primary ? 1 : -1; + case CallHelper: + hg = drbd_asb_recover_0p(mdev); + if (hg == -1 && mdev->state.role == Primary) { + self = drbd_set_role(mdev, Secondary, 0); + if (self != SS_Success) { + drbd_khelper(mdev, "pri-lost-after-sb"); + } else { + DRBD_WARN("Sucessfully gave up primary role.\n"); + rv = hg; + } + } else + rv = hg; + } + + return rv; +} + +STATIC int drbd_asb_recover_2p(struct drbd_conf *mdev) __must_hold(local) +{ + int self, peer, hg, rv = -100; + + self = mdev->bc->md.uuid[Bitmap] & 1; + peer = mdev->p_uuid[Bitmap] & 1; + + switch ( mdev->net_conf->after_sb_2p ) { + case DiscardYoungerPri: + case DiscardOlderPri: + case DiscardLeastChg: + case DiscardLocal: + case DiscardRemote: + case Consensus: + case DiscardSecondary: + ERR("Configuration error.\n"); + break; + case Violently: + rv = drbd_asb_recover_0p(mdev); + break; + case Disconnect: + break; + case CallHelper: + hg = drbd_asb_recover_0p(mdev); + if (hg == -1) { + self = drbd_set_role(mdev, Secondary, 0); + if (self != SS_Success) { + drbd_khelper(mdev, "pri-lost-after-sb"); + } else { + DRBD_WARN("Sucessfully gave up primary role.\n"); + rv = hg; + } + } else + rv = hg; + } + + return rv; +} + +STATIC void drbd_uuid_dump(struct drbd_conf *mdev, char *text, u64 *uuid) +{ + INFO("%s %016llX:%016llX:%016llX:%016llX\n", + text, + uuid[Current], + uuid[Bitmap], + uuid[History_start], + uuid[History_end]); +} + +/* + 100 after split brain try auto recover + 2 SyncSource set BitMap + 1 SyncSource use BitMap + 0 no Sync + -1 SyncTarget use BitMap + -2 SyncTarget set BitMap + -100 after split brain, disconnect +-1000 unrelated data + */ +STATIC int drbd_uuid_compare(struct drbd_conf *mdev, int *rule_nr) __must_hold(local) +{ + u64 self, peer; + int i, j; + + self = mdev->bc->md.uuid[Current] & ~((u64)1); + peer = mdev->p_uuid[Current] & ~((u64)1); + + *rule_nr = 1; + if (self == UUID_JUST_CREATED && + peer == UUID_JUST_CREATED) return 0; + + *rule_nr = 2; + if ( (self == UUID_JUST_CREATED || self == (u64)0) && + peer != UUID_JUST_CREATED) return -2; + + *rule_nr = 3; + if ( self != UUID_JUST_CREATED && + (peer == UUID_JUST_CREATED || peer == (u64)0) ) return 2; + + *rule_nr = 4; + if (self == peer) { /* Common power [off|failure] */ + int rct, dc; /* roles at crash time */ + + rct = (test_bit(CRASHED_PRIMARY, &mdev->flags) ? 1 : 0) + + ( mdev->p_uuid[UUID_FLAGS] & 2 ); + /* lowest bit is set when we were primary, + * next bit (weight 2) is set when peer was primary */ + + MTRACE(TraceTypeUuid, TraceLvlMetrics, DUMPI(rct); ); + + switch (rct) { + case 0: /* !self_pri && !peer_pri */ return 0; + case 1: /* self_pri && !peer_pri */ return 1; + case 2: /* !self_pri && peer_pri */ return -1; + case 3: /* self_pri && peer_pri */ + dc = test_bit(DISCARD_CONCURRENT, &mdev->flags); + MTRACE(TraceTypeUuid, TraceLvlMetrics, DUMPI(dc); ); + return dc ? -1 : 1; + } + } + + *rule_nr = 5; + peer = mdev->p_uuid[Bitmap] & ~((u64)1); + if (self == peer) + return -1; + + *rule_nr = 6; + for ( i = History_start ; i <= History_end ; i++ ) { + peer = mdev->p_uuid[i] & ~((u64)1); + if (self == peer) + return -2; + } + + *rule_nr = 7; + self = mdev->bc->md.uuid[Bitmap] & ~((u64)1); + peer = mdev->p_uuid[Current] & ~((u64)1); + if (self == peer) + return 1; + + *rule_nr = 8; + for ( i = History_start ; i <= History_end ; i++ ) { + self = mdev->bc->md.uuid[i] & ~((u64)1); + if (self == peer) + return 2; + } + + *rule_nr = 9; + self = mdev->bc->md.uuid[Bitmap] & ~((u64)1); + peer = mdev->p_uuid[Bitmap] & ~((u64)1); + if (self == peer && self != ((u64)0) ) return 100; + + *rule_nr = 10; + for ( i = History_start ; i <= History_end ; i++ ) { + self = mdev->p_uuid[i] & ~((u64)1); + for ( j = History_start ; j <= History_end ; j++ ) { + peer = mdev->p_uuid[j] & ~((u64)1); + if (self == peer) + return -100; + } + } + + return -1000; +} + +/* drbd_sync_handshake() returns the new conn state on success, or + conn_mask (-1) on failure. + */ +STATIC enum drbd_conns drbd_sync_handshake(struct drbd_conf *mdev, enum drbd_role peer_role, + enum drbd_disk_state peer_disk) __must_hold(local) +{ + int hg, rule_nr; + enum drbd_conns rv = conn_mask; + enum drbd_disk_state mydisk; + + mydisk = mdev->state.disk; + if (mydisk == Negotiating) + mydisk = mdev->new_state_tmp.disk; + + hg = drbd_uuid_compare(mdev, &rule_nr); + + MTRACE(TraceTypeUuid, TraceLvlSummary, + INFO("drbd_sync_handshake:\n"); + drbd_uuid_dump(mdev, "self", mdev->bc->md.uuid); + drbd_uuid_dump(mdev, "peer", mdev->p_uuid); + INFO("uuid_compare()=%d by rule %d\n", hg, rule_nr); + ); + + if (hg == -1000) { + ALERT("Unrelated data, aborting!\n"); + return conn_mask; + } + + if ( (mydisk == Inconsistent && peer_disk > Inconsistent) || + (peer_disk == Inconsistent && mydisk > Inconsistent) ) { + int f = (hg == -100) || abs(hg) == 2; + hg = mydisk > Inconsistent ? 1 : -1; + if (f) + hg = hg*2; + INFO("Becoming sync %s due to disk states.\n", + hg > 0 ? "source" : "target"); + } + + if (hg == 100 || (hg == -100 && mdev->net_conf->always_asbp) ) { + int pcount = (mdev->state.role == Primary) + + (peer_role == Primary); + int forced = (hg == -100); + + switch (pcount) { + case 0: + hg = drbd_asb_recover_0p(mdev); + break; + case 1: + hg = drbd_asb_recover_1p(mdev); + break; + case 2: + hg = drbd_asb_recover_2p(mdev); + break; + } + if ( abs(hg) < 100 ) { + DRBD_WARN("Split-Brain detected, %d primaries, " + "automatically solved. Sync from %s node\n", + pcount, (hg < 0) ? "peer":"this"); + if (forced) { + DRBD_WARN("Doing a full sync, since" + " UUIDs where ambiguous.\n"); + drbd_uuid_dump(mdev, "self", mdev->bc->md.uuid); + drbd_uuid_dump(mdev, "peer", mdev->p_uuid); + hg = hg*2; + } + } + } + + if (hg == -100) { + if (mdev->net_conf->want_lose && !(mdev->p_uuid[UUID_FLAGS]&1)) + hg = -1; + if (!mdev->net_conf->want_lose && (mdev->p_uuid[UUID_FLAGS]&1)) + hg = 1; + + if ( abs(hg) < 100 ) + DRBD_WARN("Split-Brain detected, manually solved. " + "Sync from %s node\n", + (hg < 0) ? "peer":"this"); + } + + if (hg == -100) { + ALERT("Split-Brain detected, dropping connection!\n"); + drbd_uuid_dump(mdev, "self", mdev->bc->md.uuid); + drbd_uuid_dump(mdev, "peer", mdev->p_uuid); + drbd_khelper(mdev, "split-brain"); + return conn_mask; + } + + if (hg > 0 && mydisk <= Inconsistent) { + ERR("I shall become SyncSource, but I am inconsistent!\n"); + return conn_mask; + } + + if (hg < 0 && /* by intention we do not use mydisk here. */ + mdev->state.role == Primary && mdev->state.disk >= Consistent ) { + switch (mdev->net_conf->rr_conflict) { + case CallHelper: + drbd_khelper(mdev, "pri-lost"); + /* fall through */ + case Disconnect: + ERR("I shall become SyncTarget, but I am primary!\n"); + return conn_mask; + case Violently: + DRBD_WARN("Becoming SyncTarget, violating the stable-data" + "assumption\n"); + } + } + + if (abs(hg) >= 2) { + INFO("Writing the whole bitmap, full sync required after drbd_sync_handshake.\n"); + if (drbd_bitmap_io(mdev, &drbd_bmio_set_n_write)) + return conn_mask; + } + + if (hg > 0) { /* become sync source. */ + rv = WFBitMapS; + } else if (hg < 0) { /* become sync target */ + rv = WFBitMapT; + } else { + rv = Connected; + if (drbd_bm_total_weight(mdev)) { + INFO("No resync, but %lu bits in bitmap!\n", + drbd_bm_total_weight(mdev)); + } + } + + drbd_bm_recount_bits(mdev); + + return rv; +} + +/* returns 1 if invalid */ +STATIC int cmp_after_sb(enum after_sb_handler peer, enum after_sb_handler self) +{ + /* DiscardRemote - DiscardLocal is valid */ + if ( (peer == DiscardRemote && self == DiscardLocal) || + (self == DiscardRemote && peer == DiscardLocal) ) return 0; + + /* any other things with DiscardRemote or DiscardLocal are invalid */ + if ( peer == DiscardRemote || peer == DiscardLocal || + self == DiscardRemote || self == DiscardLocal ) return 1; + + /* everything else is valid if they are equal on both sides. */ + if (peer == self) + return 0; + + /* everything es is invalid. */ + return 1; +} + +STATIC int receive_protocol(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_Protocol_Packet *p = (struct Drbd_Protocol_Packet *)h; + int header_size, data_size; + int p_proto, p_after_sb_0p, p_after_sb_1p, p_after_sb_2p; + int p_want_lose, p_two_primaries; + char p_integrity_alg[SHARED_SECRET_MAX]; + + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + p_proto = be32_to_cpu(p->protocol); + p_after_sb_0p = be32_to_cpu(p->after_sb_0p); + p_after_sb_1p = be32_to_cpu(p->after_sb_1p); + p_after_sb_2p = be32_to_cpu(p->after_sb_2p); + p_want_lose = be32_to_cpu(p->want_lose); + p_two_primaries = be32_to_cpu(p->two_primaries); + + if (p_proto != mdev->net_conf->wire_protocol) { + ERR("incompatible communication protocols\n"); + goto disconnect; + } + + if ( cmp_after_sb(p_after_sb_0p, mdev->net_conf->after_sb_0p) ) { + ERR("incompatible after-sb-0pri settings\n"); + goto disconnect; + } + + if ( cmp_after_sb(p_after_sb_1p, mdev->net_conf->after_sb_1p) ) { + ERR("incompatible after-sb-1pri settings\n"); + goto disconnect; + } + + if ( cmp_after_sb(p_after_sb_2p, mdev->net_conf->after_sb_2p) ) { + ERR("incompatible after-sb-2pri settings\n"); + goto disconnect; + } + + if (p_want_lose && mdev->net_conf->want_lose) { + ERR("both sides have the 'want_lose' flag set\n"); + goto disconnect; + } + + if (p_two_primaries != mdev->net_conf->two_primaries) { + ERR("incompatible setting of the two-primaries options\n"); + goto disconnect; + } + + if (mdev->agreed_pro_version >= 87) { + unsigned char *my_alg = mdev->net_conf->integrity_alg; + + if (drbd_recv(mdev, p_integrity_alg, data_size) != data_size) + return FALSE; + + p_integrity_alg[SHARED_SECRET_MAX-1] = 0; + if (strcmp(p_integrity_alg, my_alg)) { + ERR("incompatible setting of the data-integrity-alg\n"); + goto disconnect; + } + INFO("data-integrity-alg: %s\n", + my_alg[0] ? my_alg : (unsigned char *)""); + } + + return TRUE; + +disconnect: + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; +} + +STATIC int receive_SyncParam(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + int ok = TRUE; + struct Drbd_SyncParam_Packet *p = (struct Drbd_SyncParam_Packet *)h; + int header_size, data_size; + char p_verify_alg[SHARED_SECRET_MAX]; + struct crypto_hash *verify_tfm = NULL, *old_verify_tfm; + + header_size = sizeof(*p) - sizeof(*h); + data_size = h->length - header_size; + + if (drbd_recv(mdev, h->payload, header_size) != header_size) + return FALSE; + + mdev->sync_conf.rate = be32_to_cpu(p->rate); + + if (mdev->agreed_pro_version >= 88) { + + if (drbd_recv(mdev, p_verify_alg, data_size) != data_size) + return FALSE; + + p_verify_alg[SHARED_SECRET_MAX-1] = 0; + if (strcpy(mdev->sync_conf.verify_alg, p_verify_alg)) { + if (strlen(p_verify_alg)) { + verify_tfm = crypto_alloc_hash(p_verify_alg, 0, + CRYPTO_ALG_ASYNC); + if (IS_ERR(verify_tfm)) { + ERR("Can not allocate \"%s\" as verify-alg\n", + p_verify_alg); + return FALSE; + } + + if (crypto_tfm_alg_type(crypto_hash_tfm(verify_tfm)) != + CRYPTO_ALG_TYPE_DIGEST) { + crypto_free_hash(verify_tfm); + ERR("\"%s\" is not a digest (verify-alg)\n", + p_verify_alg); + return FALSE; + } + } + + spin_lock(&mdev->peer_seq_lock); + /* lock against drbd_nl_syncer_conf() */ + strcpy(mdev->sync_conf.verify_alg, p_verify_alg); + mdev->sync_conf.verify_alg_len = strlen(p_verify_alg) + 1; + old_verify_tfm = mdev->verify_tfm; + mdev->verify_tfm = verify_tfm; + spin_unlock(&mdev->peer_seq_lock); + + crypto_free_hash(old_verify_tfm); + } + } + + return ok; +} + +STATIC void drbd_setup_order_type(struct drbd_conf *mdev, int peer) +{ + /* sorry, we currently have no working implementation + * of distributed TCQ */ +} + +/* warn if the arguments differ by more than 12.5% */ +static void warn_if_differ_considerably(struct drbd_conf *mdev, + const char *s, sector_t a, sector_t b) +{ + sector_t d; + if (a == 0 || b == 0) + return; + d = (a > b) ? (a - b) : (b - a); + if ( d > (a>>3) || d > (b>>3)) + DRBD_WARN("Considerable difference in %s: %llus vs. %llus\n", s, + (unsigned long long)a, (unsigned long long)b); +} + +STATIC int receive_sizes(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_Sizes_Packet *p = (struct Drbd_Sizes_Packet *)h; + enum determin_dev_size_enum dd = unchanged; + unsigned int max_seg_s; + sector_t p_size, p_usize, my_usize; + int ldsc = 0; /* local disk size changed */ + enum drbd_conns nconn; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + p_size = be64_to_cpu(p->d_size); + p_usize = be64_to_cpu(p->u_size); + + if (p_size == 0 && mdev->state.disk == Diskless) { + ERR("some backing storage is needed\n"); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + + /* just store the peer's disk size for now. + * we still need to figure out wether we accept that. */ + mdev->p_size = p_size; + +#define min_not_zero(l, r) (l == 0) ? r : ((r == 0) ? l : min(l, r)) + if (inc_local(mdev)) { + warn_if_differ_considerably(mdev, "lower level device sizes", + p_size, drbd_get_capacity(mdev->bc->backing_bdev)); + warn_if_differ_considerably(mdev, "user requested size", + p_usize, mdev->bc->dc.disk_size); + + /* if this is the first connect, or an otherwise expected + * param exchange, choose the minimum */ + if (mdev->state.conn == WFReportParams) + p_usize = min_not_zero((sector_t)mdev->bc->dc.disk_size, + p_usize); + + my_usize = mdev->bc->dc.disk_size; + + if (mdev->bc->dc.disk_size != p_usize) { + mdev->bc->dc.disk_size = p_usize; + INFO("Peer sets u_size to %lu sectors\n", + (unsigned long)mdev->bc->dc.disk_size); + } + + /* Never shrink a device with usable data during connect. + But allow online shrinking if we are connected. */ + if (drbd_new_dev_size(mdev, mdev->bc) < + drbd_get_capacity(mdev->this_bdev) && + mdev->state.disk >= Outdated && + mdev->state.conn < Connected ) { + ERR("The peer's disk size is too small!\n"); + drbd_force_state(mdev, NS(conn, Disconnecting)); + mdev->bc->dc.disk_size = my_usize; + dec_local(mdev); + return FALSE; + } + dec_local(mdev); + } +#undef min_not_zero + + if (inc_local(mdev)) { + dd = drbd_determin_dev_size(mdev); + dec_local(mdev); + if (dd == dev_size_error) return FALSE; + drbd_md_sync(mdev); + } else { + /* I am diskless, need to accept the peer's size. */ + drbd_set_my_capacity(mdev, p_size); + } + + if (mdev->p_uuid && mdev->state.conn <= Connected && inc_local(mdev)) { + nconn = drbd_sync_handshake(mdev, + mdev->state.peer, mdev->state.pdsk); + dec_local(mdev); + + if (nconn == conn_mask) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + + if (drbd_request_state(mdev, NS(conn, nconn)) < SS_Success) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + } + + if (inc_local(mdev)) { + if (mdev->bc->known_size != drbd_get_capacity(mdev->bc->backing_bdev)) { + mdev->bc->known_size = drbd_get_capacity(mdev->bc->backing_bdev); + ldsc = 1; + } + + max_seg_s = be32_to_cpu(p->max_segment_size); + if (max_seg_s != mdev->rq_queue->max_segment_size) + drbd_setup_queue_param(mdev, max_seg_s); + + drbd_setup_order_type(mdev, be32_to_cpu(p->queue_order_type)); + dec_local(mdev); + } + + if (mdev->state.conn > WFReportParams) { + if ( be64_to_cpu(p->c_size) != + drbd_get_capacity(mdev->this_bdev) || ldsc ) { + /* we have different sizes, probabely peer + * needs to know my new size... */ + drbd_send_sizes(mdev); + } + if (dd == grew && mdev->state.conn == Connected && + mdev->state.pdsk >= Inconsistent && + mdev->state.disk >= Inconsistent) { + /* With disk >= Inconsistent we take care to not get + here during an attach while we are connected. */ + resync_after_online_grow(mdev); + } + } + + return TRUE; +} + +STATIC int receive_uuids(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_GenCnt_Packet *p = (struct Drbd_GenCnt_Packet *)h; + u64 *p_uuid; + int i; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + p_uuid = kmalloc(sizeof(u64)*EXT_UUID_SIZE, GFP_KERNEL); + + for (i = Current; i < EXT_UUID_SIZE; i++) + p_uuid[i] = be64_to_cpu(p->uuid[i]); + + kfree(mdev->p_uuid); + mdev->p_uuid = p_uuid; + + if (mdev->state.conn < Connected && + mdev->state.disk < Outdated && + mdev->state.role == Primary && + (mdev->ed_uuid & ~((u64)1)) != (p_uuid[Current] & ~((u64)1))) { + ERR("Can only connect to data with current UUID=%016llX\n", + (unsigned long long)mdev->ed_uuid); + drbd_force_state(mdev,NS(conn,Disconnecting)); + return FALSE; + } + + if (mdev->state.conn >= Connected && mdev->state.disk < Inconsistent) + drbd_set_ed_uuid(mdev, p_uuid[Current]); + + return TRUE; +} + +/** + * convert_state: + * Switches the view of the state. + */ +STATIC union drbd_state_t convert_state(union drbd_state_t ps) +{ + union drbd_state_t ms; + + static enum drbd_conns c_tab[] = { + [Connected] = Connected, + + [StartingSyncS] = StartingSyncT, + [StartingSyncT] = StartingSyncS, + [Disconnecting] = TearDown, /* NetworkFailure, */ + [VerifyS] = VerifyT, + [conn_mask] = conn_mask, + }; + + ms.i = ps.i; + + ms.conn = c_tab[ps.conn]; + ms.peer = ps.role; + ms.role = ps.peer; + ms.pdsk = ps.disk; + ms.disk = ps.pdsk; + ms.peer_isp = ( ps.aftr_isp | ps.user_isp ); + + return ms; +} + +STATIC int receive_req_state(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_Req_State_Packet *p = (struct Drbd_Req_State_Packet *)h; + union drbd_state_t mask, val; + int rv; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + mask.i = be32_to_cpu(p->mask); + val.i = be32_to_cpu(p->val); + + if (test_bit(DISCARD_CONCURRENT, &mdev->flags) && + test_bit(CLUSTER_ST_CHANGE, &mdev->flags)) { + drbd_send_sr_reply(mdev, SS_ConcurrentStChg); + return TRUE; + } + + mask = convert_state(mask); + val = convert_state(val); + + rv = drbd_change_state(mdev, ChgStateVerbose, mask, val); + + drbd_send_sr_reply(mdev,rv); + drbd_md_sync(mdev); + + return TRUE; +} + +STATIC int receive_state(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_State_Packet *p = (struct Drbd_State_Packet *)h; + enum drbd_conns nconn, oconn; + union drbd_state_t ns, peer_state; + enum drbd_disk_state real_peer_disk; + int rv; + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) + return FALSE; + + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + peer_state.i = be32_to_cpu(p->state); + + real_peer_disk = peer_state.disk; + if (peer_state.disk == Negotiating) { + real_peer_disk = mdev->p_uuid[UUID_FLAGS] & 4 ? Inconsistent : Consistent; + INFO("real peer disk state = %s\n", disks_to_name(real_peer_disk)); + } + + spin_lock_irq(&mdev->req_lock); + retry: + oconn = nconn = mdev->state.conn; + spin_unlock_irq(&mdev->req_lock); + + if (nconn == WFReportParams) + nconn = Connected; + + if (mdev->p_uuid && peer_state.disk >= Negotiating && + inc_local_if_state(mdev, Negotiating) ) { + int cr; /* consider resync */ + + cr = (oconn < Connected); + cr |= (oconn == Connected && + (peer_state.disk == Negotiating || + mdev->state.disk == Negotiating)); + cr |= test_bit(CONSIDER_RESYNC, &mdev->flags); /* peer forced */ + cr |= (oconn == Connected && peer_state.conn > Connected); + + if (cr) nconn=drbd_sync_handshake(mdev, peer_state.role, real_peer_disk); + + dec_local(mdev); + if (nconn == conn_mask) { + if (mdev->state.disk == Negotiating) { + drbd_force_state(mdev, NS(disk, Diskless)); + nconn = Connected; + } else if (peer_state.disk == Negotiating) { + ERR("Disk attach process on the peer node was aborted.\n"); + peer_state.disk = Diskless; + } else { + D_ASSERT(oconn == WFReportParams); + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + } + } + + spin_lock_irq(&mdev->req_lock); + if (mdev->state.conn != oconn) + goto retry; + clear_bit(CONSIDER_RESYNC, &mdev->flags); + ns.i = mdev->state.i; + ns.conn = nconn; + ns.peer = peer_state.role; + ns.pdsk = real_peer_disk; + ns.peer_isp = ( peer_state.aftr_isp | peer_state.user_isp ); + if ((nconn == Connected || nconn == WFBitMapS) && ns.disk == Negotiating) + ns.disk = mdev->new_state_tmp.disk; + rv = _drbd_set_state(mdev, ns, ChgStateVerbose | ChgStateHard, NULL); + ns = mdev->state; + spin_unlock_irq(&mdev->req_lock); + + if (rv < SS_Success) { + drbd_force_state(mdev, NS(conn, Disconnecting)); + return FALSE; + } + + if (oconn > WFReportParams ) { + if (nconn > Connected && peer_state.conn <= Connected) { + // we want resync, peer has not yet decided to sync... + drbd_send_uuids(mdev); + drbd_send_state(mdev); + } + else if (nconn == Connected && peer_state.disk == Negotiating) { + // peer is waiting for us to respond... + drbd_send_state(mdev); + } + } + + mdev->net_conf->want_lose = 0; + + /* FIXME assertion for (gencounts do not diverge) */ + drbd_md_sync(mdev); /* update connected indicator, la_size, ... */ + + return TRUE; +} + +STATIC int receive_sync_uuid(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_SyncUUID_Packet *p = (struct Drbd_SyncUUID_Packet *)h; + + wait_event( mdev->misc_wait, + mdev->state.conn < Connected || + mdev->state.conn == WFSyncUUID); + + /* D_ASSERT( mdev->state.conn == WFSyncUUID ); */ + + ERR_IF(h->length != (sizeof(*p)-sizeof(*h))) return FALSE; + if (drbd_recv(mdev, h->payload, h->length) != h->length) + return FALSE; + + /* Here the _drbd_uuid_ functions are right, current should + _not_ be rotated into the history */ + if (inc_local_if_state(mdev, Negotiating)) { + _drbd_uuid_set(mdev, Current,be64_to_cpu(p->uuid)); + _drbd_uuid_set(mdev, Bitmap, 0UL); + + drbd_start_resync(mdev, SyncTarget); + + dec_local(mdev); + } else + ERR("Ignoring SyncUUID packet!\n"); + + return TRUE; +} + +/* Since we are processing the bitfild from lower addresses to higher, + it does not matter if the process it in 32 bit chunks or 64 bit + chunks as long as it is little endian. (Understand it as byte stream, + beginning with the lowest byte...) If we would use big endian + we would need to process it from the highest address to the lowest, + in order to be agnostic to the 32 vs 64 bits issue. + + returns 0 on failure, 1 if we suceessfully received it. */ +STATIC int receive_bitmap(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + size_t bm_words, bm_i, want, num_words; + unsigned long *buffer; + int ok = FALSE; + + wait_event(mdev->misc_wait, !atomic_read(&mdev->ap_bio_cnt)); + + drbd_bm_lock(mdev); + + bm_words = drbd_bm_words(mdev); + bm_i = 0; + buffer = vmalloc(BM_PACKET_WORDS*sizeof(long)); + + while (1) { + num_words = min_t(size_t, BM_PACKET_WORDS, bm_words-bm_i ); + want = num_words * sizeof(long); + ERR_IF(want != h->length) goto out; + if (want == 0) + break; + if (drbd_recv(mdev, buffer, want) != want) + goto out; + + drbd_bm_merge_lel(mdev, bm_i, num_words, buffer); + bm_i += num_words; + + if (!drbd_recv_header(mdev, h)) + goto out; + D_ASSERT(h->command == ReportBitMap); + } + + if (mdev->state.conn == WFBitMapS) { + drbd_start_resync(mdev, SyncSource); + } else if (mdev->state.conn == WFBitMapT) { + ok = !drbd_send_bitmap(mdev); + if (!ok) goto out; + ok = drbd_request_state(mdev, NS(conn, WFSyncUUID)); + D_ASSERT( ok == SS_Success ); + } else { + ERR("unexpected cstate (%s) in receive_bitmap\n", + conns_to_name(mdev->state.conn)); + } + + ok = TRUE; + out: + drbd_bm_unlock(mdev); + vfree(buffer); + return ok; +} + +STATIC int receive_skip(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + /* TODO zero copy sink :) */ + static char sink[128]; + int size, want, r; + + DRBD_WARN("skipping unknown optional packet type %d, l: %d!\n", + h->command, h->length ); + + size = h->length; + while (size > 0) { + want = min_t(int, size, sizeof(sink)); + r = drbd_recv(mdev, sink, want); + ERR_IF(r < 0) break; + size -= r; + } + return (size == 0); +} + +STATIC int receive_UnplugRemote(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + if (mdev->state.disk >= Inconsistent) + drbd_kick_lo(mdev); + return TRUE; /* cannot fail. */ +} + +typedef int (*drbd_cmd_handler_f)(struct drbd_conf *, struct Drbd_Header *); + +static drbd_cmd_handler_f drbd_default_handler[] = { + [Data] = receive_Data, + [DataReply] = receive_DataReply, + [RSDataReply] = receive_RSDataReply, + [Barrier] = receive_Barrier_no_tcq, + [ReportBitMap] = receive_bitmap, + [UnplugRemote] = receive_UnplugRemote, + [DataRequest] = receive_DataRequest, + [RSDataRequest] = receive_DataRequest, + [SyncParam] = receive_SyncParam, + [ReportProtocol] = receive_protocol, + [ReportUUIDs] = receive_uuids, + [ReportSizes] = receive_sizes, + [ReportState] = receive_state, + [StateChgRequest] = receive_req_state, + [ReportSyncUUID] = receive_sync_uuid, + [OVRequest] = receive_DataRequest, + [OVReply] = receive_DataRequest, + /* anything missing from this table is in + * the asender_tbl, see get_asender_cmd */ + [MAX_CMD] = NULL, +}; + +static drbd_cmd_handler_f *drbd_cmd_handler = drbd_default_handler; +static drbd_cmd_handler_f *drbd_opt_cmd_handler; + +STATIC void drbdd(struct drbd_conf *mdev) +{ + drbd_cmd_handler_f handler; + struct Drbd_Header *header = &mdev->data.rbuf.head; + + while (get_t_state(&mdev->receiver) == Running) { + if (!drbd_recv_header(mdev, header)) + break; + + if (header->command < MAX_CMD) + handler = drbd_cmd_handler[header->command]; + else if (MayIgnore < header->command + && header->command < MAX_OPT_CMD) + handler = drbd_opt_cmd_handler[header->command-MayIgnore]; + else if (header->command > MAX_OPT_CMD) + handler = receive_skip; + else + handler = NULL; + + if (unlikely(!handler)) { + ERR("unknown packet type %d, l: %d!\n", + header->command, header->length); + drbd_force_state(mdev, NS(conn, ProtocolError)); + break; + } + if (unlikely(!handler(mdev, header))) { + ERR("error receiving %s, l: %d!\n", + cmdname(header->command), header->length); + drbd_force_state(mdev, NS(conn, ProtocolError)); + break; + } + + dump_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf, + __FILE__, __LINE__); + } +} + +/* FIXME how should freeze-io be handled? */ +STATIC void drbd_fail_pending_reads(struct drbd_conf *mdev) +{ + struct hlist_head *slot; + struct hlist_node *n; + struct drbd_request *req; + struct list_head *le; + LIST_HEAD(workset); + int i; + + /* + * Application READ requests + */ + spin_lock_irq(&mdev->req_lock); + for (i = 0; i < APP_R_HSIZE; i++) { + slot = mdev->app_reads_hash+i; + hlist_for_each_entry(req, n, slot, colision) { + list_add(&req->w.list, &workset); + } + } + memset(mdev->app_reads_hash, 0, APP_R_HSIZE*sizeof(void *)); + + while (!list_empty(&workset)) { + le = workset.next; + req = list_entry(le, struct drbd_request, w.list); + list_del(le); + + _req_mod(req, connection_lost_while_pending, 0); + } + spin_unlock_irq(&mdev->req_lock); +} + +STATIC void drbd_disconnect(struct drbd_conf *mdev) +{ + struct drbd_work prev_work_done; + enum fencing_policy fp; + union drbd_state_t os, ns; + int rv = SS_UnknownError; + + D_ASSERT(mdev->state.conn < Connected); + if (mdev->state.conn == StandAlone) return; + /* FIXME verify that: + * the state change magic prevents us from becoming >= Connected again + * while we are still cleaning up. + */ + + /* asender does not clean up anything. it must not interfere, either */ + drbd_thread_stop(&mdev->asender); + + down(&mdev->data.mutex); + drbd_free_sock(mdev); + up(&mdev->data.mutex); + + spin_lock_irq(&mdev->req_lock); + _drbd_wait_ee_list_empty(mdev, &mdev->active_ee); + _drbd_wait_ee_list_empty(mdev, &mdev->sync_ee); + _drbd_clear_done_ee(mdev); + _drbd_wait_ee_list_empty(mdev, &mdev->read_ee); + reclaim_net_ee(mdev); + spin_unlock_irq(&mdev->req_lock); + + /* FIXME: fail pending reads? + * when we are configured for freeze io, + * we could retry them once we un-freeze. */ + drbd_fail_pending_reads(mdev); + + /* We do not have data structures that would allow us to + * get the rs_pending_cnt down to 0 again. + * * On SyncTarget we do not have any data structures describing + * the pending RSDataRequest's we have sent. + * * On SyncSource there is no data structure that tracks + * the RSDataReply blocks that we sent to the SyncTarget. + * And no, it is not the sum of the reference counts in the + * resync_LRU. The resync_LRU tracks the whole operation including + * the disk-IO, while the rs_pending_cnt only tracks the blocks + * on the fly. */ + drbd_rs_cancel_all(mdev); + mdev->rs_total = 0; + mdev->rs_failed = 0; + atomic_set(&mdev->rs_pending_cnt, 0); + wake_up(&mdev->misc_wait); + + /* make sure syncer is stopped and w_resume_next_sg queued */ + del_timer_sync(&mdev->resync_timer); + set_bit(STOP_SYNC_TIMER, &mdev->flags); + resync_timer_fn((unsigned long)mdev); + + /* wait for all w_e_end_data_req, w_e_end_rsdata_req, w_send_barrier, + * w_make_resync_request etc. which may still be on the worker queue + * to be "canceled" */ + set_bit(WORK_PENDING, &mdev->flags); + prev_work_done.cb = w_prev_work_done; + drbd_queue_work(&mdev->data.work, &prev_work_done); + wait_event(mdev->misc_wait, !test_bit(WORK_PENDING, &mdev->flags)); + + kfree(mdev->p_uuid); + mdev->p_uuid = NULL; + + /* queue cleanup for the worker. + * FIXME this should go into after_state_ch */ + if (!mdev->state.susp) + tl_clear(mdev); + + INFO("Connection closed\n"); + + drbd_md_sync(mdev); + + fp = DontCare; + if (inc_local(mdev)) { + fp = mdev->bc->dc.fencing; + dec_local(mdev); + } + + if (mdev->state.role == Primary) { + if (fp >= Resource && mdev->state.pdsk >= DUnknown) { + enum drbd_disk_state nps = drbd_try_outdate_peer(mdev); + drbd_request_state(mdev, NS(pdsk, nps)); + } + } + + spin_lock_irq(&mdev->req_lock); + os = mdev->state; + if (os.conn >= Unconnected) { + /* Do not restart in case we are Disconnecting */ + ns = os; + ns.conn = Unconnected; + rv = _drbd_set_state(mdev, ns, ChgStateVerbose, NULL); + } + spin_unlock_irq(&mdev->req_lock); + + if (os.conn == Disconnecting) { + wait_event( mdev->misc_wait, atomic_read(&mdev->net_cnt) == 0 ); + + kfree(mdev->ee_hash); + mdev->ee_hash = NULL; + mdev->ee_hash_s = 0; + + kfree(mdev->tl_hash); + mdev->tl_hash = NULL; + mdev->tl_hash_s = 0; + + crypto_free_hash(mdev->cram_hmac_tfm); + mdev->cram_hmac_tfm = NULL; + + kfree(mdev->net_conf); + mdev->net_conf = NULL; + drbd_request_state(mdev, NS(conn, StandAlone)); + } + + /* they do trigger all the time. + * hm. why won't tcp release the page references, + * we already released the socket!? + D_ASSERT(atomic_read(&mdev->pp_in_use) == 0); + D_ASSERT(list_empty(&mdev->net_ee)); + */ + D_ASSERT(list_empty(&mdev->read_ee)); + D_ASSERT(list_empty(&mdev->active_ee)); + D_ASSERT(list_empty(&mdev->sync_ee)); + D_ASSERT(list_empty(&mdev->done_ee)); + + /* ok, no more ee's on the fly, it is safe to reset the epoch_size */ + mdev->epoch_size = 0; +} + +/* + * We support PRO_VERSION_MIN to PRO_VERSION_MAX. The protocol version + * we can agree on is stored in agreed_pro_version. + * + * feature flags and the reserved array should be enough room for future + * enhancements of the handshake protocol, and possible plugins... + * + * for now, they are expected to be zero, but ignored. + */ +STATIC int drbd_send_handshake(struct drbd_conf *mdev) +{ + /* ASSERT current == mdev->receiver ... */ + struct Drbd_HandShake_Packet *p = &mdev->data.sbuf.HandShake; + int ok; + + if (down_interruptible(&mdev->data.mutex)) { + ERR("interrupted during initial handshake\n"); + return 0; /* interrupted. not ok. */ + } + /* FIXME do we need to verify this here? */ + if (mdev->data.socket == NULL) { + up(&mdev->data.mutex); + return 0; + } + + memset(p, 0, sizeof(*p)); + p->protocol_min = cpu_to_be32(PRO_VERSION_MIN); + p->protocol_max = cpu_to_be32(PRO_VERSION_MAX); + ok = _drbd_send_cmd( mdev, mdev->data.socket, HandShake, + (struct Drbd_Header *)p, sizeof(*p), 0 ); + up(&mdev->data.mutex); + return ok; +} + +/* + * return values: + * 1 yess, we have a valid connection + * 0 oops, did not work out, please try again + * -1 peer talks different language, + * no point in trying again, please go standalone. + */ +int drbd_do_handshake(struct drbd_conf *mdev) +{ + /* ASSERT current == mdev->receiver ... */ + struct Drbd_HandShake_Packet *p = &mdev->data.rbuf.HandShake; + const int expect = sizeof(struct Drbd_HandShake_Packet) + -sizeof(struct Drbd_Header); + int rv; + + rv = drbd_send_handshake(mdev); + if (!rv) + return 0; + + rv = drbd_recv_header(mdev, &p->head); + if (!rv) + return 0; + + if (p->head.command != HandShake) { + ERR( "expected HandShake packet, received: %s (0x%04x)\n", + cmdname(p->head.command), p->head.command ); + return -1; + } + + if (p->head.length != expect) { + ERR( "expected HandShake length: %u, received: %u\n", + expect, p->head.length ); + return -1; + } + + rv = drbd_recv(mdev, &p->head.payload, expect); + + if (rv != expect) { + ERR("short read receiving handshake packet: l=%u\n", rv); + return 0; + } + + dump_packet(mdev, mdev->data.socket, 2, &mdev->data.rbuf, + __FILE__, __LINE__); + + p->protocol_min = be32_to_cpu(p->protocol_min); + p->protocol_max = be32_to_cpu(p->protocol_max); + if(p->protocol_max == 0) p->protocol_max = p->protocol_min; + + if (PRO_VERSION_MAX < p->protocol_min ) goto incompat; + if (PRO_VERSION_MIN > p->protocol_max ) goto incompat; + + mdev->agreed_pro_version = min_t(int,PRO_VERSION_MAX,p->protocol_max); + + INFO("Handshake successful: " + "Agreed network protocol version %d\n", mdev->agreed_pro_version); + + return 1; + + incompat: + ERR("incompatible DRBD dialects: " + "I support %d-%d, peer supports %d-%d\n", + PRO_VERSION_MIN,PRO_VERSION_MAX, + p->protocol_min, p->protocol_max); + return -1; +} + +#if !defined(CONFIG_CRYPTO_HMAC) && !defined(CONFIG_CRYPTO_HMAC_MODULE) +int drbd_do_auth(struct drbd_conf *mdev) +{ + ERR( "This kernel was build without CONFIG_CRYPTO_HMAC.\n"); + ERR( "You need to disable 'cram-hmac-alg' in drbd.conf.\n"); + return 0; +} +#else +#define CHALLENGE_LEN 64 +int drbd_do_auth(struct drbd_conf *mdev) +{ + char my_challenge[CHALLENGE_LEN]; /* 64 Bytes... */ + struct scatterlist sg; + char *response = NULL; + char *right_response = NULL; + char *peers_ch = NULL; + struct Drbd_Header p; + unsigned int key_len = strlen(mdev->net_conf->shared_secret); + unsigned int resp_size; + struct hash_desc desc; + int rv; + + desc.tfm = mdev->cram_hmac_tfm; + desc.flags = 0; + + rv = crypto_hash_setkey(mdev->cram_hmac_tfm, + (u8 *)mdev->net_conf->shared_secret, key_len); + if (rv) { + ERR("crypto_hash_setkey() failed with %d\n", rv); + rv = 0; + goto fail; + } + + get_random_bytes(my_challenge, CHALLENGE_LEN); + + rv = drbd_send_cmd2(mdev, AuthChallenge, my_challenge, CHALLENGE_LEN); + if (!rv) + goto fail; + + rv = drbd_recv_header(mdev, &p); + if (!rv) + goto fail; + + if (p.command != AuthChallenge) { + ERR( "expected AuthChallenge packet, received: %s (0x%04x)\n", + cmdname(p.command), p.command ); + rv = 0; + goto fail; + } + + if (p.length > CHALLENGE_LEN*2) { + ERR( "expected AuthChallenge payload too big.\n"); + rv = 0; + goto fail; + } + + peers_ch = kmalloc(p.length, GFP_KERNEL); + if (peers_ch == NULL) { + ERR("kmalloc of peers_ch failed\n"); + rv = 0; + goto fail; + } + + rv = drbd_recv(mdev, peers_ch, p.length); + + if (rv != p.length) { + ERR("short read AuthChallenge: l=%u\n", rv); + rv = 0; + goto fail; + } + + resp_size = crypto_hash_digestsize(mdev->cram_hmac_tfm); + response = kmalloc(resp_size, GFP_KERNEL); + if (response == NULL) { + ERR("kmalloc of response failed\n"); + rv = 0; + goto fail; + } + + sg_init_table(&sg, 1); + sg_set_buf(&sg, peers_ch, p.length); + + rv = crypto_hash_digest(&desc, &sg, sg.length, response); + if (rv) { + ERR( "crypto_hash_digest() failed with %d\n", rv); + rv = 0; + goto fail; + } + + rv = drbd_send_cmd2(mdev, AuthResponse, response, resp_size); + if (!rv) + goto fail; + + rv = drbd_recv_header(mdev, &p); + if (!rv) + goto fail; + + if (p.command != AuthResponse) { + ERR( "expected AuthResponse packet, received: %s (0x%04x)\n", + cmdname(p.command), p.command ); + rv = 0; + goto fail; + } + + if (p.length != resp_size) { + ERR( "expected AuthResponse payload of wrong size\n" ); + rv = 0; + goto fail; + } + + rv = drbd_recv(mdev, response , resp_size); + + if (rv != resp_size) { + ERR("short read receiving AuthResponse: l=%u\n", rv); + rv = 0; + goto fail; + } + + right_response = kmalloc(resp_size, GFP_KERNEL); + if (response == NULL) { + ERR("kmalloc of right_response failed\n"); + rv = 0; + goto fail; + } + + sg_set_buf(&sg, my_challenge, CHALLENGE_LEN); + + rv = crypto_hash_digest(&desc, &sg, sg.length, right_response); + if (rv) { + ERR( "crypto_hash_digest() failed with %d\n", rv); + rv = 0; + goto fail; + } + + rv = !memcmp(response, right_response, resp_size); + + if (rv) + INFO("Peer authenticated using %d bytes of '%s' HMAC\n", + resp_size, mdev->net_conf->cram_hmac_alg); + + fail: + kfree(peers_ch); + kfree(response); + kfree(right_response); + + return rv; +} +#endif + +STATIC int drbdd_init(struct Drbd_thread *thi) +{ + struct drbd_conf *mdev = thi->mdev; + int minor = mdev_to_minor(mdev); + int h; + + sprintf(current->comm, "drbd%d_receiver", minor); + set_cpus_allowed(current, drbd_calc_cpu_mask(mdev)); + INFO("receiver (re)started\n"); + + do { + h = drbd_connect(mdev); + if (h == 0) { + drbd_disconnect(mdev); + schedule_timeout(HZ); + } + if (h == -1) { + DRBD_WARN("Discarding network configuration.\n"); + drbd_force_state(mdev, NS(conn, Disconnecting)); + } + } while ( h == 0 ); + + if (h > 0) { + if (inc_net(mdev)) { + drbdd(mdev); + dec_net(mdev); + } + } + + drbd_disconnect(mdev); + + /* Ensure that the thread state fits to our connection state. */ + if (mdev->state.conn == Unconnected) { + ERR_IF( mdev->receiver.t_state != Restarting ) + drbd_thread_restart_nowait(&mdev->receiver); + } else if (mdev->state.conn == StandAlone) { + ERR_IF( mdev->receiver.t_state != Exiting ) + drbd_thread_stop_nowait(&mdev->receiver); + } + + INFO("receiver terminated\n"); + return 0; +} + +/* ********* acknowledge sender ******** */ + +STATIC int got_RqSReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_RqS_Reply_Packet *p = (struct Drbd_RqS_Reply_Packet *)h; + + int retcode = be32_to_cpu(p->retcode); + + if (retcode >= SS_Success) { + set_bit(CL_ST_CHG_SUCCESS, &mdev->flags); + } else { + set_bit(CL_ST_CHG_FAIL, &mdev->flags); + ERR("Requested state change failed by peer: %s\n", + set_st_err_name(retcode)); + } + wake_up(&mdev->state_wait); + + return TRUE; +} + +STATIC int got_Ping(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + return drbd_send_ping_ack(mdev); + +} + +STATIC int got_PingAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + /* restore idle timeout */ + mdev->meta.socket->sk->sk_rcvtimeo = mdev->net_conf->ping_int*HZ; + + return TRUE; +} + +STATIC int got_BlockAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct drbd_request *req; + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + sector_t sector = be64_to_cpu(p->sector); + int blksize = be32_to_cpu(p->blksize); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + if ( is_syncer_block_id(p->block_id)) { + drbd_set_in_sync(mdev, sector, blksize); + dec_rs_pending(mdev); + } else { + spin_lock_irq(&mdev->req_lock); + req = _ack_id_to_req(mdev, p->block_id, sector); + + if (unlikely(!req)) { + spin_unlock_irq(&mdev->req_lock); + ERR("Got a corrupt block_id/sector pair(2).\n"); + return FALSE; + } + + switch (be16_to_cpu(h->command)) { + case RSWriteAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + _req_mod(req, write_acked_by_peer_and_sis, 0); + break; + case WriteAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + _req_mod(req, write_acked_by_peer, 0); + break; + case RecvAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_B); + _req_mod(req, recv_acked_by_peer, 0); + break; + case DiscardAck: + D_ASSERT(mdev->net_conf->wire_protocol == DRBD_PROT_C); + ALERT("Got DiscardAck packet %llus +%u!" + " DRBD is not a random data generator!\n", + (unsigned long long)req->sector, req->size); + _req_mod(req, conflict_discarded_by_peer, 0); + break; + default: + D_ASSERT(0); + } + spin_unlock_irq(&mdev->req_lock); + } + /* dec_ap_pending is handled within _req_mod */ + + return TRUE; +} + +STATIC int got_NegAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + sector_t sector = be64_to_cpu(p->sector); + struct drbd_request *req; + + if (DRBD_ratelimit(5*HZ, 5)) + DRBD_WARN("Got NegAck packet. Peer is in troubles?\n"); + + update_peer_seq(mdev, be32_to_cpu(p->seq_num)); + + if (is_syncer_block_id(p->block_id)) { + int size = be32_to_cpu(p->blksize); + + dec_rs_pending(mdev); + + drbd_rs_failed_io(mdev, sector, size); + } else { + spin_lock_irq(&mdev->req_lock); + req = _ack_id_to_req(mdev, p->block_id, sector); + + if (unlikely(!req)) { + spin_unlock_irq(&mdev->req_lock); + ERR("Got a corrupt block_id/sector pair(2).\n"); + return FALSE; + } + + _req_mod(req, neg_acked, 0); + spin_unlock_irq(&mdev->req_lock); + } + + return TRUE; +} + +STATIC int got_NegDReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct drbd_request *req; + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + sector_t sector = be64_to_cpu(p->sector); + + spin_lock_irq(&mdev->req_lock); + req = _ar_id_to_req(mdev, p->block_id, sector); + if (unlikely(!req)) { + spin_unlock_irq(&mdev->req_lock); + ERR("Got a corrupt block_id/sector pair(3).\n"); + return FALSE; + } + + /* FIXME explicitly warn if protocol != C */ + + ERR("Got NegDReply; Sector %llus, len %u; Fail original request.\n", + (unsigned long long)sector, be32_to_cpu(p->blksize)); + + _req_mod(req, neg_acked, 0); + spin_unlock_irq(&mdev->req_lock); + + /* "ugly and wrong" but what can we do !? */ + drbd_khelper(mdev, "pri-on-incon-degr"); + + return TRUE; +} + +STATIC int got_NegRSDReply(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + sector_t sector; + int size; + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet *)h; + + sector = be64_to_cpu(p->sector); + size = be32_to_cpu(p->blksize); + D_ASSERT(p->block_id == ID_SYNCER); + + dec_rs_pending(mdev); + + if (inc_local_if_state(mdev, Failed)) { + drbd_rs_complete_io(mdev, sector); + drbd_rs_failed_io(mdev, sector, size); + dec_local(mdev); + } + + return TRUE; +} + +STATIC int got_BarrierAck(struct drbd_conf *mdev, struct Drbd_Header *h) +{ + struct Drbd_BarrierAck_Packet *p = (struct Drbd_BarrierAck_Packet *)h; + + tl_release(mdev, p->barrier, be32_to_cpu(p->set_size)); + dec_ap_pending(mdev); + + return TRUE; +} + + +STATIC int got_OVResult(struct drbd_conf *mdev, struct Drbd_Header* h) +{ + struct Drbd_BlockAck_Packet *p = (struct Drbd_BlockAck_Packet*)h; + struct drbd_work* w; + sector_t sector; + int size; + + sector = be64_to_cpu(p->sector); + size = be32_to_cpu(p->blksize); + + if (be64_to_cpu(p->block_id) == ID_OUT_OF_SYNC) { + drbd_ov_oos_found(mdev, sector, size); + } else ov_oos_print(mdev); + + drbd_rs_complete_io(mdev, sector); + dec_rs_pending(mdev); + + if (--mdev->ov_left == 0) { + w = kmalloc(sizeof(w), GFP_KERNEL); + if (w) { + w->cb = w_ov_finished; + drbd_queue_work_front(&mdev->data.work, w); + } else { + ERR("kmalloc(w) failed."); + drbd_resync_finished(mdev); + } + } + return TRUE; +} + + +struct asender_cmd { + size_t pkt_size; + int (*process)(struct drbd_conf *mdev, struct Drbd_Header *h); +}; + +static struct asender_cmd* get_asender_cmd(int cmd) +{ + static struct asender_cmd asender_tbl[] = { + /* anything missing from this table is in + * the drbd_cmd_handler (drbd_default_handler) table, + * see the beginning of drbdd() */ + [Ping] = { sizeof(struct Drbd_Header), got_Ping }, + [PingAck] = { sizeof(struct Drbd_Header), got_PingAck }, + [RecvAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [WriteAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [RSWriteAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [DiscardAck] = { sizeof(struct Drbd_BlockAck_Packet), got_BlockAck }, + [NegAck] = { sizeof(struct Drbd_BlockAck_Packet), got_NegAck }, + [NegDReply] = + { sizeof(struct Drbd_BlockAck_Packet), got_NegDReply }, + [NegRSDReply] = + { sizeof(struct Drbd_BlockAck_Packet), got_NegRSDReply}, + [OVResult] = { sizeof(struct Drbd_BlockAck_Packet), got_OVResult }, + + [BarrierAck] = + { sizeof(struct Drbd_BarrierAck_Packet), got_BarrierAck }, + [StateChgReply] = + { sizeof(struct Drbd_RqS_Reply_Packet), got_RqSReply }, + }; + if (cmd == OVResult) + return &asender_tbl[cmd]; + if (cmd < FIRST_ASENDER_CMD) + return NULL; + if (cmd > LAST_ASENDER_CMD) + return NULL; + return &asender_tbl[cmd]; +} + +STATIC int drbd_asender(struct Drbd_thread *thi) +{ + struct drbd_conf *mdev = thi->mdev; + struct Drbd_Header *h = &mdev->meta.rbuf.head; + struct asender_cmd *cmd = NULL; + + int rv,len; + void *buf = h; + int received = 0; + int expect = sizeof(struct Drbd_Header); + int empty; + + sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev)); + + current->policy = SCHED_RR; /* Make this a realtime task! */ + current->rt_priority = 2; /* more important than all other tasks */ + + set_cpus_allowed(current, drbd_calc_cpu_mask(mdev)); + + while (get_t_state(thi) == Running) { + if (test_and_clear_bit(SEND_PING, &mdev->flags)) { + ERR_IF(!drbd_send_ping(mdev)) goto reconnect; + mdev->meta.socket->sk->sk_rcvtimeo = + mdev->net_conf->ping_timeo*HZ/10; + } + + while (1) { + if (!drbd_process_done_ee(mdev)) { + ERR("process_done_ee() = NOT_OK\n"); + goto reconnect; + } + set_bit(SIGNAL_ASENDER, &mdev->flags); + spin_lock_irq(&mdev->req_lock); + empty = list_empty(&mdev->done_ee); + spin_unlock_irq(&mdev->req_lock); + if (empty && !test_bit(WRITE_ACK_PENDING, &mdev->flags)) + break; + clear_bit(SIGNAL_ASENDER, &mdev->flags); + flush_signals(current); + } + drbd_tcp_flush(mdev->meta.socket); + + rv = drbd_recv_short(mdev, mdev->meta.socket, + buf, expect-received, 0); + clear_bit(SIGNAL_ASENDER, &mdev->flags); + + flush_signals(current); + + drbd_tcp_cork(mdev->meta.socket); + + /* Note: + * -EINTR (on meta) we got a signal + * -EAGAIN (on meta) rcvtimeo expired + * -ECONNRESET other side closed the connection + * -ERESTARTSYS (on data) we got a signal + * rv < 0 other than above: unexpected error! + * rv == expected: full header or command + * rv < expected: "woken" by signal during receive + * rv == 0 : "connection shut down by peer" + */ + if (likely(rv > 0)) { + received += rv; + buf += rv; + } else if (rv == 0) { + ERR("meta connection shut down by peer.\n"); + goto reconnect; + } else if (rv == -EAGAIN) { + if ( mdev->meta.socket->sk->sk_rcvtimeo == + mdev->net_conf->ping_timeo*HZ/10 ) { + ERR("PingAck did not arrive in time.\n"); + goto reconnect; + } + set_bit(SEND_PING, &mdev->flags); + continue; + } else if (rv == -EINTR) { + continue; + } else { + ERR("sock_recvmsg returned %d\n", rv); + goto reconnect; + } + + if (received == expect && cmd == NULL ) { + if (unlikely( h->magic != BE_DRBD_MAGIC )) { + ERR("magic?? on meta m: 0x%lx c: %d l: %d\n", + (long)be32_to_cpu(h->magic), + h->command, h->length); + goto reconnect; + } + cmd = get_asender_cmd(be16_to_cpu(h->command)); + len = be16_to_cpu(h->length); + if (unlikely(cmd == NULL)) { + ERR("unknown command?? on meta m: 0x%lx c: %d l: %d\n", + (long)be32_to_cpu(h->magic), + h->command, h->length); + goto disconnect; + } + expect = cmd->pkt_size; + ERR_IF(len != expect-sizeof(struct Drbd_Header)) { + dump_packet(mdev,mdev->meta.socket,1,(void*)h, __FILE__, __LINE__); + DUMPI(expect); + goto reconnect; + } + } + if (received == expect) { + D_ASSERT(cmd != NULL); + dump_packet(mdev,mdev->meta.socket,1,(void*)h, __FILE__, __LINE__); + if (!cmd->process(mdev,h)) goto reconnect; + + buf = h; + received = 0; + expect = sizeof(struct Drbd_Header); + cmd = NULL; + } + } + + if (0) { + reconnect: + drbd_force_state(mdev,NS(conn, NetworkFailure)); + } + if (0) { + disconnect: + drbd_force_state(mdev,NS(conn, Disconnecting)); + } + clear_bit(SIGNAL_ASENDER, &mdev->flags); + + D_ASSERT(mdev->state.conn < Connected); + INFO("asender terminated\n"); + + return 0; +} --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_tag_magic.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_tag_magic.h @@ -0,0 +1,83 @@ +#ifndef DRBD_TAG_MAGIC_H +#define DRBD_TAG_MAGIC_H + +#define TT_END 0 +#define TT_REMOVED 0xE000 + +/* declare packet_type enums */ +enum packet_types { +#define NL_PACKET(name, number, fields) P_ ## name = number, +#define NL_INTEGER(pn, pr, member) +#define NL_INT64(pn, pr, member) +#define NL_BIT(pn, pr, member) +#define NL_STRING(pn, pr, member, len) +#include "drbd_nl.h" + P_nl_after_last_packet, +}; + +/* These struct are used to deduce the size of the tag lists: */ +#define NL_PACKET(name, number, fields) \ + struct name ## _tag_len_struct { fields }; +#define NL_INTEGER(pn, pr, member) \ + int member; int tag_and_len ## member; +#define NL_INT64(pn, pr, member) \ + __u64 member; int tag_and_len ## member; +#define NL_BIT(pn, pr, member) \ + unsigned char member : 1; int tag_and_len ## member; +#define NL_STRING(pn, pr, member, len) \ + unsigned char member[len]; int member ## _len; \ + int tag_and_len ## member; +#include "linux/drbd_nl.h" + +/* declate tag-list-sizes */ +static const int tag_list_sizes[] = { +#define NL_PACKET(name, number, fields) 2 fields , +#define NL_INTEGER(pn, pr, member) + 4 + 4 +#define NL_INT64(pn, pr, member) + 4 + 8 +#define NL_BIT(pn, pr, member) + 4 + 1 +#define NL_STRING(pn, pr, member, len) + 4 + (len) +#include "drbd_nl.h" +}; + +/* The two highest bits are used for the tag type */ +#define TT_MASK 0xC000 +#define TT_INTEGER 0x0000 +#define TT_INT64 0x4000 +#define TT_BIT 0x8000 +#define TT_STRING 0xC000 +/* The next bit indicates if processing of the tag is mandatory */ +#define T_MANDATORY 0x2000 +#define T_MAY_IGNORE 0x0000 +#define TN_MASK 0x1fff +/* The remaining 13 bits are used to enumerate the tags */ + +#define tag_type(T) ((T) & TT_MASK) +#define tag_number(T) ((T) & TN_MASK) + +/* declare tag enums */ +#define NL_PACKET(name, number, fields) fields +enum drbd_tags { +#define NL_INTEGER(pn, pr, member) T_ ## member = pn | TT_INTEGER | pr , +#define NL_INT64(pn, pr, member) T_ ## member = pn | TT_INT64 | pr , +#define NL_BIT(pn, pr, member) T_ ## member = pn | TT_BIT | pr , +#define NL_STRING(pn, pr, member, len) T_ ## member = pn | TT_STRING | pr , +#include "drbd_nl.h" +}; + +struct tag { + const char *name; + int type_n_flags; + int max_len; +}; + +/* declare tag names */ +#define NL_PACKET(name, number, fields) fields +static const struct tag tag_descriptions[] = { +#define NL_INTEGER(pn, pr, member) [ pn ] = { #member, TT_INTEGER | pr, sizeof(int) }, +#define NL_INT64(pn, pr, member) [ pn ] = { #member, TT_INT64 | pr, sizeof(__u64) }, +#define NL_BIT(pn, pr, member) [ pn ] = { #member, TT_BIT | pr, sizeof(int) }, +#define NL_STRING(pn, pr, member, len) [ pn ] = { #member, TT_STRING | pr, (len) }, +#include "drbd_nl.h" +}; + +#endif --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_nl.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_nl.h @@ -0,0 +1,123 @@ +/* + PAKET( name, + TYPE ( pn, pr, member ) + ... + ) + + You may never reissue one of the pn arguments +*/ + +#if !defined(NL_PACKET) || !defined(NL_STRING) || !defined(NL_INTEGER) || !defined(NL_BIT) || !defined(NL_INT64) +#error "The macros NL_PACKET, NL_STRING, NL_INTEGER, NL_INT64 and NL_BIT needs to be defined" +#endif + +NL_PACKET(primary, 1, + NL_BIT( 1, T_MAY_IGNORE, overwrite_peer) +) + +NL_PACKET(secondary, 2, ) + +NL_PACKET(disk_conf, 3, + NL_INT64( 2, T_MAY_IGNORE, disk_size) + NL_STRING( 3, T_MANDATORY, backing_dev, 128) + NL_STRING( 4, T_MANDATORY, meta_dev, 128) + NL_INTEGER( 5, T_MANDATORY, meta_dev_idx) + NL_INTEGER( 6, T_MAY_IGNORE, on_io_error) + NL_INTEGER( 7, T_MAY_IGNORE, fencing) + NL_BIT( 37, T_MAY_IGNORE, use_bmbv) + NL_BIT( 53, T_MAY_IGNORE, no_disk_flush) + NL_BIT( 54, T_MAY_IGNORE, no_md_flush) + /* 55 max_bio_size was available in 8.2.6rc2 */ + NL_INTEGER( 56, T_MAY_IGNORE, max_bio_bvecs) +) + +NL_PACKET(detach, 4, ) +NL_PACKET(net_conf, 5, + NL_STRING( 8, T_MANDATORY, my_addr, 128) + NL_STRING( 9, T_MANDATORY, peer_addr, 128) + NL_STRING( 10, T_MAY_IGNORE, shared_secret, SHARED_SECRET_MAX) + NL_STRING( 11, T_MAY_IGNORE, cram_hmac_alg, SHARED_SECRET_MAX) + NL_STRING( 44, T_MAY_IGNORE, integrity_alg, SHARED_SECRET_MAX) + NL_INTEGER( 14, T_MAY_IGNORE, timeout) + NL_INTEGER( 15, T_MANDATORY, wire_protocol) + NL_INTEGER( 16, T_MAY_IGNORE, try_connect_int) + NL_INTEGER( 17, T_MAY_IGNORE, ping_int) + NL_INTEGER( 18, T_MAY_IGNORE, max_epoch_size) + NL_INTEGER( 19, T_MAY_IGNORE, max_buffers) + NL_INTEGER( 20, T_MAY_IGNORE, unplug_watermark) + NL_INTEGER( 21, T_MAY_IGNORE, sndbuf_size) + NL_INTEGER( 22, T_MAY_IGNORE, ko_count) + NL_INTEGER( 24, T_MAY_IGNORE, after_sb_0p) + NL_INTEGER( 25, T_MAY_IGNORE, after_sb_1p) + NL_INTEGER( 26, T_MAY_IGNORE, after_sb_2p) + NL_INTEGER( 39, T_MAY_IGNORE, rr_conflict) + NL_INTEGER( 40, T_MAY_IGNORE, ping_timeo) + NL_BIT( 27, T_MAY_IGNORE, want_lose) + NL_BIT( 28, T_MAY_IGNORE, two_primaries) + NL_BIT( 41, T_MAY_IGNORE, always_asbp) +) + +NL_PACKET(disconnect, 6, ) + +NL_PACKET(resize, 7, + NL_INT64( 29, T_MAY_IGNORE, resize_size) +) + +NL_PACKET(syncer_conf, 8, + NL_INTEGER( 30, T_MAY_IGNORE, rate) + NL_INTEGER( 31, T_MAY_IGNORE, after) + NL_INTEGER( 32, T_MAY_IGNORE, al_extents) + NL_STRING( 52, T_MAY_IGNORE, verify_alg, SHARED_SECRET_MAX) + NL_STRING( 51, T_MAY_IGNORE, cpu_mask, 32) +) + +NL_PACKET(invalidate, 9, ) +NL_PACKET(invalidate_peer, 10, ) +NL_PACKET(pause_sync, 11, ) +NL_PACKET(resume_sync, 12, ) +NL_PACKET(suspend_io, 13, ) +NL_PACKET(resume_io, 14, ) +NL_PACKET(outdate, 15, ) +NL_PACKET(get_config, 16, ) +NL_PACKET(get_state, 17, + NL_INTEGER( 33, T_MAY_IGNORE, state_i) +) + +NL_PACKET(get_uuids, 18, + NL_STRING( 34, T_MAY_IGNORE, uuids, (UUID_SIZE*sizeof(__u64))) + NL_INTEGER( 35, T_MAY_IGNORE, uuids_flags) +) + +NL_PACKET(get_timeout_flag, 19, + NL_BIT( 36, T_MAY_IGNORE, use_degraded) +) + +NL_PACKET(call_helper, 20, + NL_STRING( 38, T_MAY_IGNORE, helper, 32) +) + +/* Tag nr 42 already allocated in drbd-8.1 development. + * Packet numbers 21 and 22 already in drbd-8.1 development. */ + +NL_PACKET(sync_progress, 23, + NL_INTEGER( 43, T_MAY_IGNORE, sync_progress) +) + +NL_PACKET(dump_ee, 24, + NL_STRING( 45, T_MAY_IGNORE, dump_ee_reason, 32) + NL_STRING( 46, T_MAY_IGNORE, seen_digest, SHARED_SECRET_MAX) + NL_STRING( 47, T_MAY_IGNORE, calc_digest, SHARED_SECRET_MAX) + NL_INT64( 48, T_MAY_IGNORE, ee_sector) + NL_INT64( 49, T_MAY_IGNORE, ee_block_id) + NL_STRING( 50, T_MAY_IGNORE, ee_data, 32 << 10) +) + +NL_PACKET(start_ov, 25, +) + +#undef NL_PACKET +#undef NL_INTEGER +#undef NL_INT64 +#undef NL_BIT +#undef NL_STRING + --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd.h @@ -0,0 +1,355 @@ +/* + drbd.h + Kernel module for 2.6.x Kernels + + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. + + Copyright (C) 2001-2008, LINBIT Information Technologies GmbH. + Copyright (C) 2001-2008, Philipp Reisner . + Copyright (C) 2001-2008, Lars Ellenberg . + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ +#ifndef DRBD_H +#define DRBD_H +#include + +#include + +#ifdef __KERNEL__ +#include +#include +#else +#include +#include +#include + +/* Altough the Linux source code makes a difference between + generic endiness and the bitfields' endianess, there is no + architecture as of Linux-2.6.24-rc4 where the bitfileds' endianess + does not match the generic endianess. */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define __LITTLE_ENDIAN_BITFIELD +#elif __BYTE_ORDER == __BIG_ENDIAN +#define __BIG_ENDIAN_BITFIELD +#else +# error "sorry, weird endianness on this box" +#endif + +#endif + + +enum io_error_handler { + PassOn, /* FIXME should the better be named "Ignore"? */ + CallIOEHelper, + Detach +}; + +enum fencing_policy { + DontCare, + Resource, + Stonith +}; + +enum disconnect_handler { + Reconnect, + DropNetConf, + FreezeIO +}; + +enum after_sb_handler { + Disconnect, + DiscardYoungerPri, + DiscardOlderPri, + DiscardZeroChg, + DiscardLeastChg, + DiscardLocal, + DiscardRemote, + Consensus, + DiscardSecondary, + CallHelper, + Violently +}; + +/* KEEP the order, do not delete or insert! + * Or change the API_VERSION, too. */ +enum ret_codes { + RetCodeBase = 100, + NoError, /* 101 ... */ + LAAlreadyInUse, + OAAlreadyInUse, + LDNameInvalid, + MDNameInvalid, + LDAlreadyInUse, + LDNoBlockDev, + MDNoBlockDev, + LDOpenFailed, + MDOpenFailed, + LDDeviceTooSmall, + MDDeviceTooSmall, + LDNoConfig, + LDMounted, + MDMounted, + LDMDInvalid, + LDDeviceTooLarge, + MDIOError, + MDInvalid, + CRAMAlgNotAvail, + CRAMAlgNotDigest, + KMallocFailed, + DiscardNotAllowed, + HaveDiskConfig, + HaveNetConfig, + UnknownMandatoryTag, + MinorNotKnown, + StateNotAllowed, + GotSignal, /* EINTR */ + NoResizeDuringResync, + APrimaryNodeNeeded, + SyncAfterInvalid, + SyncAfterCycle, + PauseFlagAlreadySet, + PauseFlagAlreadyClear, + DiskLowerThanOutdated, /* obsolete, now SS_LowerThanOutdated */ + UnknownNetLinkPacket, + HaveNoDiskConfig, + ProtocolCRequired, + VMallocFailed, + IntegrityAlgNotAvail, + IntegrityAlgNotDigest, + CPUMaskParseFailed, + CSUMSAlgNotAvail, + CSUMSAlgNotDigest, + VERIFYAlgNotAvail, + VERIFYAlgNotDigest, + CSUMSResyncRunning, + VERIFYIsRunning, + DataOfWrongCurrent, + + /* insert new ones above this line */ + AfterLastRetCode, +}; + +#define DRBD_PROT_A 1 +#define DRBD_PROT_B 2 +#define DRBD_PROT_C 3 + +enum drbd_role { + Unknown = 0, + Primary = 1, /* role */ + Secondary = 2, /* role */ + role_mask = 3, +}; + +/* The order of these constants is important. + * The lower ones (=WFReportParams ==> There is a socket + * + * THINK + * Skipped should be < Connected, + * so writes on a Primary after Skipped sync are not mirrored either ? + */ +enum drbd_conns { + StandAlone, + Disconnecting, /* Temporal state on the way to StandAlone. */ + Unconnected, /* >= Unconnected -> inc_net() succeeds */ + + /* These temporal states are all used on the way + * from >= Connected to Unconnected. + * The 'disconnect reason' states + * I do not allow to change beween them. */ + Timeout, + BrokenPipe, + NetworkFailure, + ProtocolError, + TearDown, + + WFConnection, + WFReportParams, /* we have a socket */ + Connected, /* we have introduced each other */ + StartingSyncS, /* starting full sync by IOCTL. */ + StartingSyncT, /* stariing full sync by IOCTL. */ + WFBitMapS, + WFBitMapT, + WFSyncUUID, + + /* The distance between original state and pause + * state must be the same for source and target. (+2) + * All SyncStates are tested with this comparison + * xx >= SyncSource && xx <= PausedSyncT */ + SyncSource, + SyncTarget, + VerifyS, + VerifyT, + PausedSyncS, + PausedSyncT, + conn_mask = 31 +}; + +enum drbd_disk_state { + Diskless, + Attaching, /* In the process of reading the meta-data */ + Failed, /* Becomes Diskless as soon as we told it the peer */ + /* when >= Failed it is legal to access mdev->bc */ + Negotiating, /* Late attaching state, we need to talk to the peer */ + Inconsistent, + Outdated, + DUnknown, /* Only used for the peer, never for myself */ + Consistent, /* Might be Outdated, might be UpToDate ... */ + UpToDate, /* Only this disk state allows applications' IO ! */ + disk_mask = 15 +}; + +union drbd_state_t { +/* According to gcc's docs is the ... + * The order of allocation of bit-fields within a unit (C90 6.5.2.1, C99 6.7.2.1). + * Determined by ABI. + * pointed out by Maxim Uvarov q + * even though we transmit as "cpu_to_be32(state)", + * the offsets of the bitfields still need to be swapped + * on different endianess. + */ + struct { +#if defined(__LITTLE_ENDIAN_BITFIELD) + unsigned role : 2 ; /* 3/4 primary/secondary/unknown */ + unsigned peer : 2 ; /* 3/4 primary/secondary/unknown */ + unsigned conn : 5 ; /* 17/32 cstates */ + unsigned disk : 4 ; /* 8/16 from Diskless to UpToDate */ + unsigned pdsk : 4 ; /* 8/16 from Diskless to UpToDate */ + unsigned susp : 1 ; /* 2/2 IO suspended no/yes */ + unsigned aftr_isp : 1 ; /* isp .. imposed sync pause */ + unsigned peer_isp : 1 ; + unsigned user_isp : 1 ; + unsigned _pad : 11; /* 0 unused */ +#elif defined(__BIG_ENDIAN_BITFIELD) + unsigned _pad : 11; /* 0 unused */ + unsigned user_isp : 1 ; + unsigned peer_isp : 1 ; + unsigned aftr_isp : 1 ; /* isp .. imposed sync pause */ + unsigned susp : 1 ; /* 2/2 IO suspended no/yes */ + unsigned pdsk : 4 ; /* 8/16 from Diskless to UpToDate */ + unsigned disk : 4 ; /* 8/16 from Diskless to UpToDate */ + unsigned conn : 5 ; /* 17/32 cstates */ + unsigned peer : 2 ; /* 3/4 primary/secondary/unknown */ + unsigned role : 2 ; /* 3/4 primary/secondary/unknown */ +#else +# error "this endianess is not supported" +#endif + }; + unsigned int i; +}; + +enum set_st_err { + SS_CW_NoNeed = 4, + SS_CW_Success = 3, + SS_NothingToDo = 2, + SS_Success = 1, + SS_UnknownError = 0, /* Used to sleep longer in _drbd_request_state */ + SS_TwoPrimaries = -1, + SS_NoUpToDateDisk = -2, + SS_BothInconsistent = -4, + SS_SyncingDiskless = -5, + SS_ConnectedOutdates = -6, + SS_PrimaryNOP = -7, + SS_ResyncRunning = -8, + SS_AlreadyStandAlone = -9, + SS_CW_FailedByPeer = -10, + SS_IsDiskLess = -11, + SS_DeviceInUse = -12, + SS_NoNetConfig = -13, + SS_NoVerifyAlg = -14, /* drbd-8.2 only */ + SS_NeedConnection = -15, /* drbd-8.2 only */ + SS_LowerThanOutdated = -16, + SS_NotSupported = -17, /* drbd-8.2 only */ + SS_InTransientState = -18, /* Retry after the next state change */ + SS_ConcurrentStChg = -19, /* Concurrent cluster side state change! */ +}; + + +/* from drbd_strings.c */ +extern const char *conns_to_name(enum drbd_conns); +extern const char *roles_to_name(enum drbd_role); +extern const char *disks_to_name(enum drbd_disk_state); +extern const char *set_st_err_name(enum set_st_err); + +#ifndef BDEVNAME_SIZE +# define BDEVNAME_SIZE 32 +#endif + +#define SHARED_SECRET_MAX 64 + +enum MetaDataFlags { + __MDF_Consistent, + __MDF_PrimaryInd, + __MDF_ConnectedInd, + __MDF_FullSync, + __MDF_WasUpToDate, + __MDF_PeerOutDated /* or worse (e.g. invalid). */ +}; +#define MDF_Consistent (1<<__MDF_Consistent) +#define MDF_PrimaryInd (1<<__MDF_PrimaryInd) +#define MDF_ConnectedInd (1<<__MDF_ConnectedInd) +#define MDF_FullSync (1<<__MDF_FullSync) +#define MDF_WasUpToDate (1<<__MDF_WasUpToDate) +#define MDF_PeerOutDated (1<<__MDF_PeerOutDated) + +enum UuidIndex { + Current, + Bitmap, + History_start, + History_end, + UUID_SIZE, /* nl-packet: number of dirty bits */ + UUID_FLAGS, /* nl-packet: flags */ + EXT_UUID_SIZE /* Everything. */ +}; + +#define UUID_JUST_CREATED ((__u64)4) + +#define DRBD_MAGIC 0x83740267 +#define BE_DRBD_MAGIC __constant_cpu_to_be32(DRBD_MAGIC) + +/* these are of type "int" */ +#define DRBD_MD_INDEX_INTERNAL -1 +#define DRBD_MD_INDEX_FLEX_EXT -2 +#define DRBD_MD_INDEX_FLEX_INT -3 + +/* Start of the new netlink/connector stuff */ + +#define DRBD_NL_CREATE_DEVICE 0x01 +#define DRBD_NL_SET_DEFAULTS 0x02 + +/* The following line should be moved over to linux/connector.h + * when the time comes */ +//#define CN_IDX_DRBD 0x5 +//#define CN_VAL_DRBD 0x1 + +struct drbd_nl_cfg_req { + int packet_type; + int drbd_minor; + int flags; + unsigned short tag_list[]; +}; + +struct drbd_nl_cfg_reply { + int packet_type; + int minor; + int ret_code; /* enum ret_code or set_st_err_t */ + unsigned short tag_list[]; /* only used with get_* calls */ +}; + +#endif --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_config.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_config.h @@ -0,0 +1,89 @@ +/* + drbd_config.h + DRBD's compile time configuration. + + drbd 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. + + drbd 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 drbd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef DRBD_CONFIG_H +#define DRBD_CONFIG_H + +extern const char *drbd_buildtag(void); + +#define REL_VERSION "8.2.6" +#define API_VERSION 88 +#define PRO_VERSION_MIN 86 +#define PRO_VERSION_MAX 88 + +#ifndef __CHECKER__ /* for a sparse run, we need all STATICs */ +#define DBG_ALL_SYMBOLS /* no static functs, improves quality of OOPS traces */ +#endif + +/* drbd_assert_breakpoint() function +#define DBG_ASSERTS + */ + +/* Dump all cstate changes */ +#define DUMP_MD 2 + +/* some extra checks +#define PARANOIA + */ + +/* Dump every hour the usage / not usage of zero copy IO */ +/* #define SHOW_SENDPAGE_USAGE */ + +/* Define this to enable dynamic tracing controlled by module parameters + * at run time. This enables ALL use of dynamic tracing including packet + * and bio dumping, etc */ +#define ENABLE_DYNAMIC_TRACE + +/* You can disable the use of the sendpage() call (= zero copy IO) + * If you have the feeling that this might be the cause for troubles. +#define DRBD_DISABLE_SENDPAGE + */ + +/* Enable fault insertion code */ +#define DRBD_ENABLE_FAULTS + +/* RedHat's 2.6.9 kernels have the gfp_t type. Mainline has this feature + * since 2.6.16. If you build for RedHat enable the line below. */ +#define KERNEL_HAS_GFP_T + +/* kernel.org has atomic_add_return since 2.6.10. some vendor kernels + * have it backported, though. Others don't. */ +//#define NEED_BACKPORT_OF_ATOMIC_ADD + +/* 2.6.something has deprecated kmem_cache_t + * some older still use it. + * some have it defined as struct kmem_cache_s, some as struct kmem_cache */ +//#define USE_KMEM_CACHE_S + +/* 2.6.something has sock_create_kern (SE-linux security context stuff) + * some older distribution kernels don't. */ +//#define DEFINE_SOCK_CREATE_KERN + +/* in older kernels (vanilla < 2.6.16) struct netlink_skb_parms has a + * member called dst_groups. Later it is called dst_group (without 's'). */ +//#define DRBD_NL_DST_GROUPS + +/* in older kernels (vanilla < 2.6.14) is no kzalloc() */ +//#define NEED_BACKPORT_OF_KZALLOC + +// some vendor kernels have it, some don't +//#define NEED_SG_SET_BUF +#define HAVE_LINUX_SCATTERLIST_H + +#endif --- linux-2.6.28.orig/ubuntu/drbd/linux/drbd_limits.h +++ linux-2.6.28/ubuntu/drbd/linux/drbd_limits.h @@ -0,0 +1,128 @@ +/* + drbd_limits.h + This file is part of DRBD by Philipp Reisner and Lars Ellenberg. +*/ + +/* + * Our current limitations. + * Some of them are hard limits, + * some of them are arbitrary range limits, that make it easier to provide + * feedback about nonsense settings for certain configurable values. + */ + +#ifndef DRBD_LIMITS_H +#define DRBD_LIMITS_H 1 + +#define DEBUG_RANGE_CHECK 0 + +#define DRBD_MINOR_COUNT_MIN 1 +#define DRBD_MINOR_COUNT_MAX 255 + +#define DRBD_DIALOG_REFRESH_MIN 0 +#define DRBD_DIALOG_REFRESH_MAX 600 + +/* valid port number */ +#define DRBD_PORT_MIN 1 +#define DRBD_PORT_MAX 0xffff + +/* startup { */ + /* if you want more than 3.4 days, disable */ +#define DRBD_WFC_TIMEOUT_MIN 0 +#define DRBD_WFC_TIMEOUT_MAX 300000 +#define DRBD_WFC_TIMEOUT_DEF 0 + +#define DRBD_DEGR_WFC_TIMEOUT_MIN 0 +#define DRBD_DEGR_WFC_TIMEOUT_MAX 300000 +#define DRBD_DEGR_WFC_TIMEOUT_DEF 60 + +/* }*/ + +/* net { */ + /* timeout, unit centi seconds + * more than one minute timeout is not usefull */ +#define DRBD_TIMEOUT_MIN 1 +#define DRBD_TIMEOUT_MAX 600 +#define DRBD_TIMEOUT_DEF 60 /* 6 seconds */ + + /* active connection retries when WFConnection */ +#define DRBD_CONNECT_INT_MIN 1 +#define DRBD_CONNECT_INT_MAX 120 +#define DRBD_CONNECT_INT_DEF 10 /* seconds */ + + /* keep-alive probes when idle */ +#define DRBD_PING_INT_MIN 1 +#define DRBD_PING_INT_MAX 120 +#define DRBD_PING_INT_DEF 10 + + /* timeout for the ping packets.*/ +#define DRBD_PING_TIMEO_MIN 1 +#define DRBD_PING_TIMEO_MAX 100 +#define DRBD_PING_TIMEO_DEF 5 + + /* max number of write requests between write barriers */ +#define DRBD_MAX_EPOCH_SIZE_MIN 1 +#define DRBD_MAX_EPOCH_SIZE_MAX 20000 +#define DRBD_MAX_EPOCH_SIZE_DEF 2048 + + /* I don't think that a tcp send buffer of more than 10M is usefull */ +#define DRBD_SNDBUF_SIZE_MIN 1 +#define DRBD_SNDBUF_SIZE_MAX 10000000 +#define DRBD_SNDBUF_SIZE_DEF (2*65535) + + /* @4k PageSize -> 128kB - 512MB */ +#define DRBD_MAX_BUFFERS_MIN 32 +#define DRBD_MAX_BUFFERS_MAX 131072 +#define DRBD_MAX_BUFFERS_DEF 2048 + + /* @4k PageSize -> 4kB - 512MB */ +#define DRBD_UNPLUG_WATERMARK_MIN 1 +#define DRBD_UNPLUG_WATERMARK_MAX 131072 +#define DRBD_UNPLUG_WATERMARK_DEF (DRBD_MAX_BUFFERS_DEF/16) + + /* 0 is disabled. + * 200 should be more than enough even for very short timeouts */ +#define DRBD_KO_COUNT_MIN 0 +#define DRBD_KO_COUNT_MAX 200 +#define DRBD_KO_COUNT_DEF 0 +/* } */ + +/* syncer { */ + /* FIXME allow rate to be zero? */ +#define DRBD_RATE_MIN 1 +#define DRBD_RATE_MAX 700000 +#define DRBD_RATE_DEF 250 /* kb/second */ + + /* less than 7 would hit performance unneccessarily. + * 3833 is the largest prime that still does fit + * into 64 sectors of activity log */ +#define DRBD_AL_EXTENTS_MIN 7 +#define DRBD_AL_EXTENTS_MAX 3833 +#define DRBD_AL_EXTENTS_DEF 127 + +#define DRBD_AFTER_MIN -1 +#define DRBD_AFTER_MAX 255 +#define DRBD_AFTER_DEF -1 + +/* } */ + +/* drbdsetup XY resize -d Z + * you are free to reduce the device size to nothing, if you want to. + * but more than 3998G are currently not possible */ +/* DRBD_MAX_SECTORS */ +#define DRBD_DISK_SIZE_SECT_MIN 0 +#define DRBD_DISK_SIZE_SECT_MAX ((128LLU*1024*2 - 72)*512LLU*8*8) +#define DRBD_DISK_SIZE_SECT_DEF 0 /* = disabled = no user size... */ + +#define DRBD_ON_IO_ERROR_DEF PassOn +#define DRBD_FENCING_DEF DontCare +#define DRBD_AFTER_SB_0P_DEF Disconnect +#define DRBD_AFTER_SB_1P_DEF Disconnect +#define DRBD_AFTER_SB_2P_DEF Disconnect +#define DRBD_RR_CONFLICT_DEF Disconnect + +#define DRBD_MAX_BIO_BVECS_MIN 0 +#define DRBD_MAX_BIO_BVECS_MAX 128 +#define DRBD_MAX_BIO_BVECS_DEF 0 + +#undef RANGE +#endif --- linux-2.6.28.orig/Documentation/kernel-parameters.txt +++ linux-2.6.28/Documentation/kernel-parameters.txt @@ -180,6 +180,9 @@ acpi_no_auto_ssdt [HW,ACPI] Disable automatic loading of SSDT + acpi_no_initrd_override [KNL,ACPI] + Disable loading custom ACPI tables from the initramfs + acpi_os_name= [HW,ACPI] Tell ACPI BIOS the name of the OS Format: To spoof as Windows 98: ="Microsoft Windows" --- linux-2.6.28.orig/Documentation/networking/README.ipw2200 +++ linux-2.6.28/Documentation/networking/README.ipw2200 @@ -147,7 +147,7 @@ driver. If disabled, the driver will not attempt to scan for and associate to a network until it has been configured with one or more properties for the target network, for example configuring - the network SSID. Default is 1 (auto-associate) + the network SSID. Default is 0 (do not auto-associate) Example: % modprobe ipw2200 associate=0 --- linux-2.6.28.orig/Documentation/acpi/dsdt-override.txt +++ linux-2.6.28/Documentation/acpi/dsdt-override.txt @@ -1,7 +1,15 @@ -Linux supports a method of overriding the BIOS DSDT: +Linux supports two methods of overriding the BIOS DSDT: CONFIG_ACPI_CUSTOM_DSDT builds the image into the kernel. -When to use this method is described in detail on the +CONFIG_ACPI_CUSTOM_DSDT_INITRD adds the image to the initrd. + +When to use these methods is described in detail on the Linux/ACPI home page: http://www.lesswatts.org/projects/acpi/overridingDSDT.php + +Note that if both options are used, the DSDT supplied +by the INITRD method takes precedence. + +Documentation/initramfs-add-dsdt.sh is provided for convenience +for use with the CONFIG_ACPI_CUSTOM_DSDT_INITRD method. --- linux-2.6.28.orig/Documentation/acpi/initramfs-add-dsdt.sh +++ linux-2.6.28/Documentation/acpi/initramfs-add-dsdt.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# Adds a DSDT file to the initrd (if it's an initramfs) +# first argument is the name of archive +# second argument 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-2.6.28.orig/scripts/test-suspend +++ linux-2.6.28/scripts/test-suspend @@ -0,0 +1,198 @@ +#!/bin/bash +# +# Script to automate suspend / resume +# +# Copyright (C) 2008-2009 Canonical Ltd. +# +# Authors: +# Michael Frey +# Andy Whitcroft +# +# 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. +# +# 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, see . + +# +# Script to automate suspend / resume +# +# We set a RTC alarm that wakes the system back up and then sleep +# for seconds before we go back to sleep. +# +# Changelog: +# +# V2: +# - support newer rtc sysfs wakealarm interface +# - move to using pmi action suspend +# - allow the user to specify the number of iterations +# - ensure we are running as root +# - report the iterations to the user +# - clean up the output and put it in a standard logfile +# - add a descriptive warning and allow user cancel +# - add tracing enable/disable +# - fix logfile location +# - add a failure cleanup mode +# - make time sleep time and delay time configurable +# - ensure the log directory exists +# - clock will be fixed automatically on network connect +# - default sleep before wakeup to 20s +# - do not use dates after we have corrupted the clock +# - sort out the copyright information +# - we do not have any failure cleanup currently +# +# V1: +# - add the suspend test scripts +# +P="test-suspend" + +LOGDIR='/var/lib/pm-utils' +LOGFILE="$LOGDIR/stress.log" + +setup_wakeup_timer () +{ + timeout="$1" + + # + # Request wakeup from the RTC or ACPI alarm timers. Set the timeout + # at 'now' + $timeout seconds. + # + ctl='/sys/class/rtc/rtc0/wakealarm' + if [ -f "$ctl" ]; then + time=`date '+%s' -d "+ $timeout seconds"` + # Cancel any outstanding timers. + echo "0" >"$ctl" + # rtcN/wakealarm uses absolute time in seconds + echo "$time" >"$ctl" + return 0 + fi + ctl='/proc/acpu/alarm' + if [ -f "$ctl" ]; then + echo `date '+%F %H:%M:%S' -d '+ '$timeout' seconds'` >"$ctl" + return 0 + fi + + echo "no method to awaken machine automatically" 1>&2 + exit 1 +} + +suspend_system () +{ + + hwclock --directisa --localtime --systohc + + + setup_wakeup_timer "$timer_sleep" + + pmi action suspend >/dev/null + + # + # wait for $timer_delay seconds after system resume from S3 + # + ECHO "wait for $timer_delay seconds" + sleep $timer_delay + +} + +ECHO () +{ + echo "$@" | tee -a "$LOGFILE" +} + +run_suspend () +{ + CNT=1 + TOTAL=$1 + ECHO "Suspend Test starting on $(date '+%F %H:%M:%S') ($TOTAL cycles)" + while [ "$CNT" -le "$TOTAL" ] + do + ECHO "Suspend iteration $CNT of $TOTAL" + + suspend_system "$START" + + (( CNT++ )) + done + ECHO "Suspend Test completed" +} + +enable_trace() +{ + echo 1 > '/sys/power/pm_trace' +} + +disable_trace() +{ + echo 0 > '/sys/power/pm_trace' +} + +# +# MAIN +# +USAGE="$P [--sleep ] [--delay ] []" +# We need TEMP as the `eval set --' would nuke the return value of getopt. +TEMP=`getopt -o '' -l sleep:,delay: -n "$P" -- "$@"` +if [ $? != 0 ] ; then + echo "$USAGE" + exit 1 +fi + +# Note the quotes around `$TEMP': they are essential! +eval set -- "$TEMP" + +# Options handling. +iterations=10 +timer_sleep=20 +timer_delay=10 + +while : +do + case "$1" in + --sleep) timer_sleep="$2"; shift 2 ;; + --delay) timer_delay="$2"; shift 2 ;; + --) shift; break ;; + esac +done + +if [ "$#" -gt 1 ]; then + echo "Usage: $USAGE" 1>&2 + exit 1 +fi +if [ "$#" -eq 1 ]; then + iterations="$1" +fi + +# Check we are running as root as we are going to fiddle with the clock +# and use the rtc wakeups. +id=`id -u` +if [ "$id" -ne 0 ]; then + echo "ERROR: must be run as root to perform this test, use sudo:" 1>&2 + echo " sudo $0 $@" 1>&2 + exit 1 +fi + +cat - <start || !pr || request_resource(pr, r) < 0) { - dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx); + dev_warn(&dev->dev, "BAR %d: can't allocate resource\n", idx); /* * Something is wrong with the region. * Invalidate the resource to prevent @@ -170,7 +170,7 @@ r->flags, disabled, pass); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { - dev_err(&dev->dev, "BAR %d: can't allocate resource\n", idx); + dev_warn(&dev->dev, "BAR %d: can't allocate resource\n", idx); /* We'll assign a new address later */ r->end -= r->start; r->start = 0; --- linux-2.6.28.orig/arch/x86/mm/ioremap.c +++ linux-2.6.28/arch/x86/mm/ioremap.c @@ -688,7 +688,7 @@ */ offset = phys_addr & ~PAGE_MASK; phys_addr &= PAGE_MASK; - size = PAGE_ALIGN(last_addr + 1) - phys_addr; + size = PAGE_ALIGN(last_addr) - phys_addr; /* * Mappings have to fit in the FIX_BTMAP area. --- linux-2.6.28.orig/arch/x86/kernel/reboot.c +++ linux-2.6.28/arch/x86/kernel/reboot.c @@ -194,6 +194,15 @@ DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"), }, }, + { /* Handle problems with rebooting on Dell Dimension 9200 */ + .callback = set_bios_reboot, + .ident = "Dell Dimension 9200", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"), + DMI_MATCH(DMI_BOARD_NAME, "0CT017"), + }, + }, { /* Handle problems with rebooting on HP laptops */ .callback = set_bios_reboot, .ident = "HP Compaq Laptop", --- linux-2.6.28.orig/arch/x86/kernel/alternative.c +++ linux-2.6.28/arch/x86/kernel/alternative.c @@ -410,6 +410,8 @@ void __init alternative_instructions(void) { + unsigned long flags; + /* The patching is not fully atomic, so try to avoid local interruptions that might execute the to be patched code. Other CPUs are not running. */ @@ -418,7 +420,9 @@ stop_mce(); #endif + local_irq_save(flags); apply_alternatives(__alt_instructions, __alt_instructions_end); + local_irq_restore(flags); /* switch to patch-once-at-boottime-only mode and free the * tables in case we know the number of CPUs will never ever @@ -448,7 +452,9 @@ alternatives_smp_switch(0); } #endif + local_irq_save(flags); apply_paravirt(__parainstructions, __parainstructions_end); + local_irq_restore(flags); if (smp_alt_once) free_init_pages("SMP alternatives", --- linux-2.6.28.orig/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c +++ linux-2.6.28/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c @@ -45,6 +45,7 @@ CPU_DOTHAN_A1, CPU_DOTHAN_A2, CPU_DOTHAN_B0, + CPU_DOTHAN_C0, CPU_MP4HT_D0, CPU_MP4HT_E0, }; @@ -54,6 +55,7 @@ [CPU_DOTHAN_A1] = { 6, 13, 1 }, [CPU_DOTHAN_A2] = { 6, 13, 2 }, [CPU_DOTHAN_B0] = { 6, 13, 6 }, + [CPU_DOTHAN_C0] = { 6, 13, 8 }, [CPU_MP4HT_D0] = {15, 3, 4 }, [CPU_MP4HT_E0] = {15, 4, 1 }, }; @@ -196,6 +198,88 @@ }; #undef OP + +#define OPEX(mhz, base, mva, mvb, mvc, mvd) \ +{ \ + .frequency = (mhz) * 1000, \ + .index = (((mhz)/(base)) << 8) | ((mva - 700) / 16) \ +} + +/* Intel Pentium M processor 730 / 1.60 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1596[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1116, 1111, 1084, 1079), + OPEX(1330, 133, 1244, 1233, 1180, 1169), + OPEX(1596, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 740 / 1.73 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1729[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1100, 1093, 1068, 1066), + OPEX(1330, 133, 1212, 1198, 1148, 1143), + OPEX(1729, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 750 / 1.86 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1862[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1084, 1080, 1068, 1056), + OPEX(1330, 133, 1180, 1172, 1132, 1124), + OPEX(1596, 133, 1276, 1264, 1196, 1192), + OPEX(1862, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 760 / 2.00 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_1995[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1084, 1070, 1052, 1048), + OPEX(1330, 133, 1164, 1152, 1116, 1109), + OPEX(1596, 133, 1244, 1233, 1180, 1169), + OPEX(1995, 133, 1356, 1356, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; +/* Intel Pentium M processor 770 / 2.13 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_2128[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1068, 1065, 1052, 1042), + OPEX(1330, 133, 1148, 1142, 1100, 1097), + OPEX(1596, 133, 1228, 1218, 1164, 1151), + OPEX(1862, 133, 1308, 1295, 1212, 1206), + OPEX(2128, 133, 1372, 1372, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +/* Intel Pentium M processor 780 / 2.26 GHz (Sonoma) */ +static struct cpufreq_frequency_table sonoma_2261[] = +{ + OPEX( 798, 133, 988, 988, 988, 988), + OPEX(1064, 133, 1068, 1064, 1052, 1037), + OPEX(1330, 133, 1148, 1139, 1100, 1087), + OPEX(1596, 133, 1228, 1215, 1148, 1136), + OPEX(1862, 133, 1292, 1291, 1196, 1186), + OPEX(2261, 133, 1404, 1404, 1260, 1260), + { .frequency = CPUFREQ_TABLE_END } +}; + +#undef OPEX + +#define SONOMA(cpuid, max, base, name) \ +{ .cpu_id = cpuid, \ + .model_name = "Intel(R) Pentium(R) M processor " name "GHz", \ + .max_freq = (max)*1000, \ + .op_points = sonoma_##max, \ +} + + #define _BANIAS(cpuid, max, name) \ { .cpu_id = cpuid, \ .model_name = "Intel(R) Pentium(R) M processor " name "MHz", \ @@ -218,6 +302,15 @@ BANIAS(1600), BANIAS(1700), + /* Builtin tables for Dothan C0 CPUs, a.k.a Sonoma */ + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1596, 133, "1.60"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1729, 133, "1.73"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1862, 133, "1.86"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 1995, 133, "2.00"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2128, 133, "2.13"), + SONOMA(&cpu_ids[CPU_DOTHAN_C0], 2261, 133, "2.26"), + + /* NULL model_name is a wildcard */ { &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL }, { &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL }, --- linux-2.6.28.orig/sound/pci/hda/patch_realtek.c +++ linux-2.6.28/sound/pci/hda/patch_realtek.c @@ -8427,6 +8427,7 @@ SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), + SND_PCI_QUIRK(0x1043, 0x8284, "ASUS Z37E", ALC883_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), @@ -10473,6 +10474,7 @@ SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), SND_PCI_QUIRK(0x144d, 0xc039, "Samsung Q1U EL", ALC262_ULTRA), + SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31), --- linux-2.6.28.orig/sound/pci/hda/hda_intel.c +++ linux-2.6.28/sound/pci/hda/hda_intel.c @@ -2095,6 +2095,7 @@ SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01), SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01), + SND_PCI_QUIRK(0x1028, 0x0271, "unknown Dell", 0x11), {} }; --- linux-2.6.28.orig/drivers/bluetooth/bt3c_cs.c +++ linux-2.6.28/drivers/bluetooth/bt3c_cs.c @@ -345,7 +345,10 @@ int iir; irqreturn_t r = IRQ_NONE; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.28.orig/drivers/bluetooth/dtl1_cs.c +++ linux-2.6.28/drivers/bluetooth/dtl1_cs.c @@ -299,7 +299,10 @@ int iir, lsr; irqreturn_t r = IRQ_NONE; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.28.orig/drivers/bluetooth/bluecard_cs.c +++ linux-2.6.28/drivers/bluetooth/bluecard_cs.c @@ -503,7 +503,10 @@ unsigned int iobase; unsigned char reg; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } if (!test_bit(CARD_READY, &(info->hw_state))) return IRQ_HANDLED; --- linux-2.6.28.orig/drivers/bluetooth/btusb.c +++ linux-2.6.28/drivers/bluetooth/btusb.c @@ -125,6 +125,9 @@ /* Dell laptop with Broadcom chip */ { USB_DEVICE(0x413c, 0x8126), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, + /* Dell Wireless 365 */ + { USB_DEVICE(0x413c, 0x8160), .driver_info = BTUSB_RESET }, + /* Dell Wireless 370 */ { USB_DEVICE(0x413c, 0x8156), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, --- linux-2.6.28.orig/drivers/bluetooth/btuart_cs.c +++ linux-2.6.28/drivers/bluetooth/btuart_cs.c @@ -295,7 +295,10 @@ int iir, lsr; irqreturn_t r = IRQ_NONE; - BUG_ON(!info->hdev); + if (!info || !info->hdev) { + BT_ERR("Call of irq %d for unknown device", irq); + return IRQ_NONE; + } iobase = info->p_dev->io.BasePort1; --- linux-2.6.28.orig/drivers/bluetooth/hci_usb.c +++ linux-2.6.28/drivers/bluetooth/hci_usb.c @@ -137,6 +137,9 @@ { USB_DEVICE(0x413c, 0x8156), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, /* Dell Wireless 410 */ { USB_DEVICE(0x413c, 0x8152), .driver_info = HCI_RESET | HCI_WRONG_SCO_MTU }, + + /* Broadcom 2046 */ + { USB_DEVICE(0x0a5c, 0x2151), .driver_info = HCI_RESET }, /* Broadcom 2046 */ { USB_DEVICE(0x0a5c, 0x2151), .driver_info = HCI_RESET }, --- linux-2.6.28.orig/drivers/ata/libata-core.c +++ linux-2.6.28/drivers/ata/libata-core.c @@ -4121,6 +4121,7 @@ { "HTS541060G9SA00", "MB3OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541080G9SA00", "MB4OC60D", ATA_HORKAGE_NONCQ, }, { "HTS541010G9SA00", "MBZOC60D", ATA_HORKAGE_NONCQ, }, + { "FUJITSU MHW2160BH PL", "0084001E", ATA_HORKAGE_NONCQ, }, /* devices which puke on READ_NATIVE_MAX */ { "HDS724040KLSA80", "KFAOA20N", ATA_HORKAGE_BROKEN_HPA, }, --- linux-2.6.28.orig/drivers/pci/setup-res.c +++ linux-2.6.28/drivers/pci/setup-res.c @@ -157,7 +157,7 @@ } if (ret) { - dev_err(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", + dev_warn(&dev->dev, "BAR %d: can't allocate %s resource %pR\n", resno, res->flags & IORESOURCE_IO ? "I/O" : "mem", res); } else { res->flags &= ~IORESOURCE_STARTALIGN; --- linux-2.6.28.orig/drivers/hwmon/hdaps.c +++ linux-2.6.28/drivers/hwmon/hdaps.c @@ -533,6 +533,9 @@ HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"), HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61P"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R61"), + HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T61"), { .ident = NULL } }; --- linux-2.6.28.orig/drivers/input/mouse/alps.c +++ linux-2.6.28/drivers/input/mouse/alps.c @@ -422,7 +422,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-2.6.28.orig/drivers/mmc/core/core.c +++ linux-2.6.28/drivers/mmc/core/core.c @@ -524,7 +524,7 @@ * This delay must be at least 74 clock sizes, or 1 ms, or the * time required to reach a stable voltage. */ - mmc_delay(2); + mmc_delay(10); } static void mmc_power_off(struct mmc_host *host) --- linux-2.6.28.orig/drivers/net/r8169.c +++ linux-2.6.28/drivers/net/r8169.c @@ -2121,6 +2121,13 @@ dev->poll_controller = rtl8169_netpoll; #endif + /* Ubuntu temporary workaround for bug #76489, disable + * NETIF_F_TSO by default for RTL8111/8168B chipsets. + * People can re-enable if required */ + if (tp->mac_version == RTL_GIGA_MAC_VER_11 + || tp->mac_version == RTL_GIGA_MAC_VER_12) + dev->features &= ~NETIF_F_TSO; + tp->intr_mask = 0xffff; tp->align = cfg->align; tp->hw_start = cfg->hw_start; --- linux-2.6.28.orig/drivers/net/wireless/ipw2200.c +++ linux-2.6.28/drivers/net/wireless/ipw2200.c @@ -87,7 +87,7 @@ static int mode = 0; static u32 ipw_debug_level; -static int associate = 1; +static int associate; static int auto_create = 1; static int led = 0; static int disable = 0; --- linux-2.6.28.orig/drivers/net/wireless/orinoco_cs.c +++ linux-2.6.28/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 @@ -417,67 +418,94 @@ " (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(0x02ac, 0x3021), /* SpeedStream 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), @@ -494,11 +522,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); @@ -515,18 +540,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-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-agn.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1658,8 +1658,11 @@ * the driver as well won't allow loading if RFKILL is set * therefore no need to restart the driver from this handler */ - if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) + if (!hw_rf_kill && !test_bit(STATUS_ALIVE, &priv->status)) { clear_bit(STATUS_RF_KILL_HW, &priv->status); + if (priv->is_open && !iwl_is_rfkill(priv)) + queue_work(priv->workqueue, &priv->up); + } handled |= CSR_INT_BIT_RF_KILL; } --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -6260,6 +6260,11 @@ goto done; } + if (scan->channel_count == 0) { + IWL_DEBUG_SCAN("channel count %d\n", scan->channel_count); + goto done; + } + cmd.len += le16_to_cpu(scan->tx_cmd.len) + scan->channel_count * sizeof(struct iwl3945_scan_channel); cmd.data = scan; --- linux-2.6.28.orig/drivers/net/wireless/iwlwifi/iwl-core.c +++ linux-2.6.28/drivers/net/wireless/iwlwifi/iwl-core.c @@ -1465,6 +1465,16 @@ return 0; } + /* when driver is up while rfkill is on, it wont receive + * any CARD_STATE_NOTIFICATION notifications so we have to + * restart it in here + */ + if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) { + clear_bit(STATUS_RF_KILL_SW, &priv->status); + if (!iwl_is_rfkill(priv)) + queue_work(priv->workqueue, &priv->up); + } + /* If the driver is already loaded, it will receive * CARD_STATE_NOTIFICATION notifications and the handler will * call restart to reload the driver. --- linux-2.6.28.orig/drivers/net/wireless/hostap/hostap_info.c +++ linux-2.6.28/drivers/net/wireless/hostap/hostap_info.c @@ -238,6 +238,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 */ @@ -451,8 +452,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-2.6.28.orig/drivers/net/wireless/hostap/hostap_hw.c +++ linux-2.6.28/drivers/net/wireless/hostap/hostap_hw.c @@ -3447,6 +3447,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-2.6.28.orig/drivers/net/wireless/hostap/hostap_main.c +++ linux-2.6.28/drivers/net/wireless/hostap/hostap_main.c @@ -1094,6 +1094,7 @@ (u8 *) &val, 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-2.6.28.orig/drivers/net/wireless/p54/p54usb.c +++ linux-2.6.28/drivers/net/wireless/p54/p54usb.c @@ -61,7 +61,7 @@ {USB_DEVICE(0x0915, 0x2002)}, /* Cohiba Proto board */ {USB_DEVICE(0x0baf, 0x0118)}, /* U.S. Robotics U5 802.11g Adapter*/ {USB_DEVICE(0x0bf8, 0x1009)}, /* FUJITSU E-5400 USB D1700*/ - {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ +// DUPE {USB_DEVICE(0x0cde, 0x0006)}, /* Medion MD40900 */ {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x124a, 0x4025)}, /* IOGear GWU513 (GW3887IK chip) */ --- linux-2.6.28.orig/drivers/net/tulip/tulip_core.c +++ linux-2.6.28/drivers/net/tulip/tulip_core.c @@ -228,8 +228,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 }, @@ -392,6 +396,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-2.6.28.orig/drivers/net/tulip/tulip.h +++ linux-2.6.28/drivers/net/tulip/tulip.h @@ -38,7 +38,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-2.6.28.orig/drivers/net/e1000e/hw.h +++ linux-2.6.28/drivers/net/e1000e/hw.h @@ -355,6 +355,7 @@ #define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 #define E1000_DEV_ID_ICH9_IGP_M 0x10BF #define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB +#define E1000_DEV_ID_ICH9_IGP_M_V_2 0x10BE #define E1000_DEV_ID_ICH9_IGP_C 0x294C #define E1000_DEV_ID_ICH9_IFE 0x10C0 #define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 --- linux-2.6.28.orig/drivers/net/e1000e/netdev.c +++ linux-2.6.28/drivers/net/e1000e/netdev.c @@ -5146,6 +5146,7 @@ { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V_2), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan }, { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan }, --- linux-2.6.28.orig/drivers/video/Kconfig +++ linux-2.6.28/drivers/video/Kconfig @@ -684,8 +684,8 @@ If unsure, say N. 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-2.6.28.orig/drivers/video/vesafb.c +++ linux-2.6.28/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-2.6.28.orig/drivers/scsi/scsi_transport_fc.c +++ linux-2.6.28/drivers/scsi/scsi_transport_fc.c @@ -455,10 +455,30 @@ MODULE_PARM_DESC(dev_loss_tmo, "Maximum number of seconds that the FC transport should" " insulate the loss of a remote port. Once this value is" - " exceeded, the scsi target is removed. Value should be" + " exceeded, the scsi target may be removed. Reference the" + " remove_on_dev_loss module parameter. Value should be" " between 1 and SCSI_DEVICE_BLOCK_MAX_TIMEOUT."); /* + * remove_on_dev_loss: controls whether the transport will + * remove a scsi target after the device loss timer expires. + * Removal on disconnect is modeled after the USB subsystem + * and expects subsystems layered on SCSI to be aware of + * potential device loss and handle it appropriately. However, + * many subsystems do not support device removal, leaving situations + * where structure references may remain, causing new device + * name assignments, etc., if the target returns. + */ +static unsigned int fc_remove_on_dev_loss = 0; +module_param_named(remove_on_dev_loss, fc_remove_on_dev_loss, + int, S_IRUGO|S_IWUSR); +MODULE_PARM_DESC(remove_on_dev_loss, + "Boolean. When the device loss timer fires, this variable" + " controls whether the scsi infrastructure for the target" + " device is removed. Values: zero means do not remove," + " non-zero means remove. Default is zero."); + +/** * Netlink Infrastructure */ @@ -2357,7 +2377,8 @@ container_of(work, struct fc_rport, stgt_delete_work); fc_terminate_rport_io(rport); - scsi_remove_target(&rport->dev); + if (fc_remove_on_dev_loss) + scsi_remove_target(&rport->dev); } @@ -2991,9 +3012,13 @@ return; } - dev_printk(KERN_ERR, &rport->dev, - "blocked FC remote port time out: removing target and " - "saving binding\n"); + if (fc_remove_on_dev_loss) + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: removing target and " + "saving binding\n"); + else + dev_printk(KERN_ERR, &rport->dev, + "blocked FC remote port time out: saving binding\n"); list_move_tail(&rport->peers, &fc_host->rport_bindings); --- linux-2.6.28.orig/drivers/message/fusion/mptbase.c +++ linux-2.6.28/drivers/message/fusion/mptbase.c @@ -3014,6 +3014,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-2.6.28.orig/drivers/usb/serial/option.c +++ linux-2.6.28/drivers/usb/serial/option.c @@ -205,6 +205,7 @@ #define AMOI_VENDOR_ID 0x1614 #define AMOI_PRODUCT_H01 0x0800 #define AMOI_PRODUCT_H01A 0x7002 +#define AMOI_PRODUCT_9508 0x0800 #define AMOI_PRODUCT_H02 0x0802 #define DELL_VENDOR_ID 0x413C @@ -247,9 +248,6 @@ #define BANDRICH_PRODUCT_1011 0x1011 #define BANDRICH_PRODUCT_1012 0x1012 -#define AMOI_VENDOR_ID 0x1614 -#define AMOI_PRODUCT_9508 0x0800 - #define QUALCOMM_VENDOR_ID 0x05C6 #define MAXON_VENDOR_ID 0x16d8 --- linux-2.6.28.orig/drivers/usb/serial/ipaq.c +++ linux-2.6.28/drivers/usb/serial/ipaq.c @@ -548,7 +548,6 @@ { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ - { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */ { } /* Terminating entry */ }; --- linux-2.6.28.orig/drivers/media/video/uvc/uvc_v4l2.c +++ linux-2.6.28/drivers/media/video/uvc/uvc_v4l2.c @@ -252,9 +252,6 @@ if (ret < 0) return ret; - if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) - return ret; - memcpy(&video->streaming->ctrl, &probe, sizeof probe); video->streaming->cur_format = format; video->streaming->cur_frame = frame; @@ -315,10 +312,6 @@ if ((ret = uvc_probe_video(video, &probe)) < 0) return ret; - /* Commit the new settings. */ - if ((ret = uvc_set_video_ctrl(video, &probe, 0)) < 0) - return ret; - memcpy(&video->streaming->ctrl, &probe, sizeof probe); /* Return the actual frame period. */ --- linux-2.6.28.orig/drivers/media/video/uvc/uvc_driver.c +++ linux-2.6.28/drivers/media/video/uvc/uvc_driver.c @@ -1984,6 +1984,15 @@ .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX }, + /* COMPAL JHL90 */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x064e, + .idProduct = 0xa115, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, {} --- linux-2.6.28.orig/drivers/media/video/uvc/uvc_video.c +++ linux-2.6.28/drivers/media/video/uvc/uvc_video.c @@ -935,11 +935,8 @@ break; } - /* Commit the default settings. */ probe->bFormatIndex = format->index; probe->bFrameIndex = frame->bFrameIndex; - if ((ret = uvc_set_video_ctrl(video, probe, 0)) < 0) - return ret; video->streaming->cur_format = format; video->streaming->cur_frame = frame; @@ -979,6 +976,10 @@ if ((ret = uvc_queue_enable(&video->queue, 1)) < 0) return ret; + /* Commit the streaming parameters. */ + if ((ret = uvc_set_video_ctrl(video, &video->streaming->ctrl, 0)) < 0) + return ret; + return uvc_init_video(video, GFP_KERNEL); } --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-input.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-input.c @@ -231,6 +231,7 @@ ir->sampling = 1; break; case CX88_BOARD_WINFAST_DTV2000H: + case CX88_BOARD_WINFAST_DTV2000H_2: ir_codes = ir_codes_winfast; ir->gpio_addr = MO_GP0_IO; ir->mask_keycode = 0x8f8; --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-cards.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-cards.c @@ -1238,7 +1238,7 @@ }, [CX88_BOARD_WINFAST_DTV2000H] = { /* video inputs and radio still in testing */ - .name = "WinFast DTV2000 H", + .name = "WinFast DTV2000 H ver. I (old)", .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, .radio_type = UNSET, .tuner_addr = ADDR_UNSET, @@ -1254,6 +1254,45 @@ }}, .mpeg = CX88_MPEG_DVB, }, + [CX88_BOARD_WINFAST_DTV2000H_2] = { + /* this is just a try */ + .name = "WinFast DTV2000 H ver. J (new)", + .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, + .radio_type = UNSET, + .tuner_addr = ADDR_UNSET, + .radio_addr = ADDR_UNSET, + .tda9887_conf = TDA9887_PRESENT, + .input = { { + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x00017300, + .gpio1 = 0x00008207, + .gpio2 = 0x00000000, + .gpio3 = 0x02000000, + }, { + .type = CX88_VMUX_TELEVISION, + .vmux = 0, + .gpio0 = 0x00018300, + .gpio1 = 0x0000f207, + .gpio2 = 0x00017304, + .gpio3 = 0x02000000, + }, { + .type = CX88_VMUX_COMPOSITE1, + .vmux = 1, + .gpio0 = 0x00018301, + .gpio1 = 0x0000f207, + .gpio2 = 0x00017304, + .gpio3 = 0x02000000, + }, { + .type = CX88_VMUX_SVIDEO, + .vmux = 2, + .gpio0 = 0x00018301, + .gpio1 = 0x0000f207, + .gpio2 = 0x00017304, + .gpio3 = 0x02000000, + } }, + .mpeg = CX88_MPEG_DVB, + }, [CX88_BOARD_GENIATECH_DVBS] = { .name = "Geniatech DVB-S", .tuner_type = TUNER_ABSENT, @@ -2120,6 +2159,10 @@ .subdevice = 0x665e, .card = CX88_BOARD_WINFAST_DTV2000H, },{ + .subvendor = 0x107d, + .subdevice = 0x6f2b, + .card = CX88_BOARD_WINFAST_DTV2000H_2, + },{ .subvendor = 0x18ac, .subdevice = 0xd800, /* FusionHDTV 3 Gold (original revision) */ .card = CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q, --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-mpeg.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-mpeg.c @@ -126,6 +126,11 @@ cx_write(TS_VALERR_CNTRL, 0); udelay(100); break; + case CX88_BOARD_WINFAST_DTV2000H_2: + /* switch signal input to antena */ + cx_write(MO_GP0_IO, 0x00017300); + cx_write(TS_SOP_STAT, 0x00); + break; default: cx_write(TS_SOP_STAT, 0x00); break; --- linux-2.6.28.orig/drivers/media/video/cx88/cx88.h +++ linux-2.6.28/drivers/media/video/cx88/cx88.h @@ -229,6 +229,7 @@ #define CX88_BOARD_TEVII_S420 73 #define CX88_BOARD_PROLINK_PV_GLOBAL_XTREME 74 #define CX88_BOARD_PROF_7300 75 +#define CX88_BOARD_WINFAST_DTV2000H_2 76 enum cx88_itype { CX88_VMUX_COMPOSITE1 = 1, --- linux-2.6.28.orig/drivers/media/video/cx88/cx88-dvb.c +++ linux-2.6.28/drivers/media/video/cx88/cx88-dvb.c @@ -639,6 +639,7 @@ } break; case CX88_BOARD_WINFAST_DTV2000H: + case CX88_BOARD_WINFAST_DTV2000H_2: case CX88_BOARD_HAUPPAUGE_HVR1100: case CX88_BOARD_HAUPPAUGE_HVR1100LP: case CX88_BOARD_HAUPPAUGE_HVR1300: --- linux-2.6.28.orig/drivers/char/keyboard.c +++ linux-2.6.28/drivers/char/keyboard.c @@ -1068,6 +1068,8 @@ int code; switch (keycode) { + case KEY_RESERVED: + break; case KEY_PAUSE: put_queue(vc, 0xe1); put_queue(vc, 0x1d | up_flag); @@ -1127,6 +1129,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-2.6.28.orig/drivers/char/vt_ioctl.c +++ linux-2.6.28/drivers/char/vt_ioctl.c @@ -35,6 +35,8 @@ #include #include +#define max_font_size 65536 + char vt_dont_switch; extern struct tty_driver *console_driver; @@ -1254,6 +1256,7 @@ static void complete_change_console(struct vc_data *vc) { unsigned char old_vc_mode; + struct vc_data *oldvc = vc_cons[fg_console].d; last_console = fg_console; @@ -1262,9 +1265,31 @@ * KD_TEXT mode or vice versa, which means we need to blank or * unblank the screen later. */ - old_vc_mode = vc_cons[fg_console].d->vc_mode; + old_vc_mode = oldvc->vc_mode; + +#if defined(CONFIG_VGA_CONSOLE) + if (old_vc_mode == KD_TEXT && oldvc->vc_sw == &vga_con && + oldvc->vc_sw->con_font_get) { + if (!oldvc->vc_font.data) + oldvc->vc_font.data = kmalloc(max_font_size, + GFP_KERNEL); + lock_kernel(); + oldvc->vc_sw->con_font_get(oldvc, &oldvc->vc_font); + unlock_kernel(); + } +#endif switch_screen(vc); +#if defined(CONFIG_VGA_CONSOLE) + if (vc->vc_mode == KD_TEXT && vc->vc_sw == &vga_con && + vc->vc_sw->con_font_set) { + if (vc->vc_font.data) { + lock_kernel(); + vc->vc_sw->con_font_set(vc, &vc->vc_font, 0); + unlock_kernel(); + } + } +#endif /* * This can't appear below a successful kill_pid(). If it did, * then the *blank_screen operation could occur while X, having --- linux-2.6.28.orig/drivers/acpi/osl.c +++ linux-2.6.28/drivers/acpi/osl.c @@ -95,6 +95,11 @@ #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ static char osi_additional_string[OSI_STRING_LENGTH_MAX]; +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static __initdata int acpi_no_initrd_override; +extern struct acpi_table_header *acpi_find_dsdt_initrd(void); +#endif + /* * The story of _OSI(Linux) * @@ -327,6 +332,16 @@ if (strncmp(existing_table->signature, "DSDT", 4) == 0) *new_table = (struct acpi_table_header *)AmlCode; #endif +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD + if ((strncmp(existing_table->signature, "DSDT", 4) == 0) && + !acpi_no_initrd_override) { + struct acpi_table_header *initrd_table; + + initrd_table = acpi_find_dsdt_initrd(); + if (initrd_table) + *new_table = initrd_table; + } +#endif if (*new_table != NULL) { printk(KERN_WARNING PREFIX "Override [%4.4s-%8.8s], " "this is unsafe: tainting kernel\n", @@ -337,6 +352,15 @@ return AE_OK; } +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static int __init acpi_no_initrd_override_setup(char *s) +{ + acpi_no_initrd_override = 1; + return 1; +} +__setup("acpi_no_initrd_override", acpi_no_initrd_override_setup); +#endif + static irqreturn_t acpi_irq(int irq, void *dev_id) { u32 handled; --- linux-2.6.28.orig/drivers/acpi/Kconfig +++ linux-2.6.28/drivers/acpi/Kconfig @@ -297,6 +297,17 @@ bool default ACPI_CUSTOM_DSDT_FILE != "" +config ACPI_CUSTOM_DSDT_INITRD + bool "Read Custom DSDT from initramfs" + depends on BLK_DEV_INITRD + default n + help + This option supports a custom DSDT by optionally loading it from initrd. + See Documentation/acpi/dsdt-override.txt + + If you are not using this feature now, but may use it 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-2.6.28.orig/drivers/acpi/processor_idle.c +++ linux-2.6.28/drivers/acpi/processor_idle.c @@ -128,52 +128,7 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = { { set_max_cstate, "IBM ThinkPad R40e", { DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1}, - { set_max_cstate, "IBM ThinkPad R40e", { - DMI_MATCH(DMI_BIOS_VENDOR,"IBM"), - DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1}, + DMI_MATCH(DMI_BIOS_VERSION,"1SET")}, (void *)1}, { set_max_cstate, "Medion 41700", { DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"), DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1}, --- linux-2.6.28.orig/drivers/acpi/video_detect.c +++ linux-2.6.28/drivers/acpi/video_detect.c @@ -44,17 +44,88 @@ static bool acpi_video_caps_checked; static acpi_status +acpi_backlight_validate_bcl(acpi_handle handle) +{ + union acpi_object *obj, *obj2; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + int level_ac = 0, level_battery = 0; + int i, count; + int *levels; + acpi_status status; + + + status = acpi_evaluate_object(handle, "_BCL", NULL, &buffer); + if (!ACPI_SUCCESS(status)) + return status; + obj = (union acpi_object *)buffer.pointer; + if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { + printk(KERN_ERR PREFIX "Invalid _BCL data\n"); + status = AE_BAD_DATA; + goto out; + } + + if (obj->package.count < 2) { + status = AE_BAD_DATA; + goto out; + } + + levels = kzalloc(obj->package.count * sizeof(*levels), GFP_KERNEL); + if (!levels) { + status = AE_NO_MEMORY; + goto out; + } + + for (i = 0, count = 0; i < obj->package.count; i++) { + obj2 = (union acpi_object *)&obj->package.elements[i]; + if (obj2->type != ACPI_TYPE_INTEGER) { + printk(KERN_ERR PREFIX "Invalid data\n"); + continue; + } + levels[i] = (u32) obj2->integer.value; + count ++; + } + + if (count < 2) { + status = AE_BAD_DATA; + goto out_free_levels; + } + + for (i = 2, level_ac = levels[0], level_battery = levels[1]; i < count; i ++) { + if (levels[0] == levels[i]) + level_ac = 1; + if (levels[1] == levels[i]) + level_battery = 1; + } + + if (!level_ac || !level_battery) { + printk(KERN_ERR PREFIX "Invalid _BCL package\n"); + status = AE_BAD_DATA; + goto out_free_levels; + } + + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count)); + +out_free_levels: + kfree(levels); +out: + kfree(obj); + return status; +} + +static acpi_status acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context, void **retyurn_value) { long *cap = context; - acpi_handle h_dummy; + acpi_handle h_dummy1, h_dummy2; - if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy)) && - ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy))) { - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " - "support\n")); - *cap |= ACPI_VIDEO_BACKLIGHT; + if (ACPI_SUCCESS(acpi_get_handle(handle, "_BCM", &h_dummy1)) && + ACPI_SUCCESS(acpi_get_handle(handle, "_BCL", &h_dummy2))) { + if (ACPI_SUCCESS(acpi_backlight_validate_bcl(h_dummy2))) { + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight " + "support\n")); + *cap |= ACPI_VIDEO_BACKLIGHT; + } /* We have backlight support, no need to scan further */ return AE_CTRL_TERMINATE; } --- linux-2.6.28.orig/drivers/md/dm.c +++ linux-2.6.28/drivers/md/dm.c @@ -1666,6 +1666,7 @@ { return md->disk; } +EXPORT_SYMBOL_GPL(dm_disk); int dm_suspended(struct mapped_device *md) { --- linux-2.6.28.orig/net/unix/af_unix.c +++ linux-2.6.28/net/unix/af_unix.c @@ -829,7 +829,8 @@ err = mnt_want_write(nd.path.mnt); if (err) goto out_mknod_dput; - err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0); + err = vfs_mknod(nd.path.dentry->d_inode, dentry, nd.path.mnt, + mode, 0); mnt_drop_write(nd.path.mnt); if (err) goto out_mknod_dput; --- linux-2.6.28.orig/net/mac80211/debugfs_netdev.c +++ linux-2.6.28/net/mac80211/debugfs_netdev.c @@ -531,6 +531,7 @@ { struct net_device *dev = ndev; struct dentry *dir; + struct ieee80211_local *local; struct ieee80211_sub_if_data *sdata; char buf[10+IFNAMSIZ]; @@ -543,7 +544,12 @@ if (dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) return 0; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); + /* + * Do not use IEEE80211_DEV_TO_SUB_IF because that + * BUG_ONs for the master netdev which we need to + * handle here. + */ + sdata = netdev_priv(dev); dir = sdata->debugfsdir; --- linux-2.6.28.orig/fs/attr.c +++ linux-2.6.28/fs/attr.c @@ -100,7 +100,8 @@ } EXPORT_SYMBOL(inode_setattr); -int notify_change(struct dentry * dentry, struct iattr * attr) +int fnotify_change(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr, struct file *file) { struct inode *inode = dentry->d_inode; mode_t mode = inode->i_mode; @@ -159,7 +160,7 @@ if (!(attr->ia_valid & ~(ATTR_KILL_SUID | ATTR_KILL_SGID))) return 0; - error = security_inode_setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); if (error) return error; @@ -167,7 +168,24 @@ down_write(&dentry->d_inode->i_alloc_sem); if (inode->i_op && inode->i_op->setattr) { - error = inode->i_op->setattr(dentry, attr); + error = security_inode_setattr(dentry, mnt, attr); + if (!error) { + if (file && file->f_op && file->f_op->fsetattr) + error = file->f_op->fsetattr(file, attr); + else { + /* External file system still expect to be + * passed a file pointer via ia_file and + * have it announced via ATTR_FILE. This + * just makes it so they don't need to + * change their API just for us. External + * callers will have set these themselves. */ + if (file) { + attr->ia_valid |= ATTR_FILE; + attr->ia_file = file; + } + error = inode->i_op->setattr(dentry, attr); + } + } } else { error = inode_change_ok(inode, attr); if (!error) { @@ -187,5 +205,12 @@ return error; } +EXPORT_SYMBOL_GPL(fnotify_change); + +int notify_change(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr) +{ + return fnotify_change(dentry, mnt, attr, NULL); +} EXPORT_SYMBOL(notify_change); --- linux-2.6.28.orig/fs/dcache.c +++ linux-2.6.28/fs/dcache.c @@ -1907,44 +1907,46 @@ * @root: root vfsmnt/dentry (may be modified by this function) * @buffer: buffer to return value in * @buflen: buffer length + * @flags: flags controling behavior of d_path * - * Convert a dentry into an ASCII path name. If the entry has been deleted - * the string " (deleted)" is appended. Note that this is ambiguous. - * - * Returns the buffer or an error code if the path was too long. - * - * "buflen" should be positive. Caller holds the dcache_lock. + * Convert a dentry into an ASCII path name. If the entry has been deleted, + * then if @flags has D_PATH_FAIL_DELETED set, ERR_PTR(-ENOENT) is returned. + * Otherwise, the string " (deleted)" is appended. Note that this is ambiguous. * * If path is not reachable from the supplied root, then the value of - * root is changed (without modifying refcounts). + * root is changed (without modifying refcounts). The path returned in this + * case will be relative (i.e., it will not start with a slash). + * + * Returns the buffer or an error code if the path was too long. */ char *__d_path(const struct path *path, struct path *root, - char *buffer, int buflen) + char *buffer, int buflen, int flags) { struct dentry *dentry = path->dentry; struct vfsmount *vfsmnt = path->mnt; - char *end = buffer + buflen; - char *retval; + const unsigned char *name; + int namelen; + + buffer += buflen; + prepend(&buffer, &buflen, "\0", 1); spin_lock(&vfsmount_lock); - prepend(&end, &buflen, "\0", 1); - if (!IS_ROOT(dentry) && d_unhashed(dentry) && - (prepend(&end, &buflen, " (deleted)", 10) != 0)) + spin_lock(&dcache_lock); + if (!IS_ROOT(dentry) && d_unhashed(dentry)) { + if (flags & D_PATH_FAIL_DELETED) { + buffer = ERR_PTR(-ENOENT); + goto out; + } + if (prepend(&buffer, &buflen, " (deleted)", 10) != 0) goto Elong; - + } if (buflen < 1) goto Elong; - /* Get '/' right */ - retval = end-1; - *retval = '/'; - for (;;) { + while (dentry != root->dentry || vfsmnt != root->mnt) { struct dentry * parent; - if (dentry == root->dentry && vfsmnt == root->mnt) - break; if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { - /* Global root? */ if (vfsmnt->mnt_parent == vfsmnt) { goto global_root; } @@ -1954,27 +1956,51 @@ } parent = dentry->d_parent; prefetch(parent); - if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) || - (prepend(&end, &buflen, "/", 1) != 0)) + if ((prepend_name(&buffer, &buflen, &dentry->d_name) != 0) || + (prepend(&buffer, &buflen, "/", 1) != 0)) goto Elong; - retval = end; dentry = parent; } + /* Get '/' right. */ + if (*buffer != '/' && prepend(&buffer, &buflen, "/", 1)) + goto Elong; out: + spin_unlock(&dcache_lock); spin_unlock(&vfsmount_lock); - return retval; + return buffer; global_root: - retval += 1; /* hit the slash */ - if (prepend_name(&retval, &buflen, &dentry->d_name) != 0) + /* + * 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; + name = dentry->d_name.name; + + /* + * If this is a root dentry, then overwrite the slash. This + * will also DTRT with pseudo filesystems which have root + * dentries named "foo:". + */ + if (IS_ROOT(dentry) && *buffer == '/') { + buffer++; + buflen++; + } + if ((flags & D_PATH_DISCONNECT) && *name == '/') { + /* Make sure we won't return a pathname starting with '/' */ + name++; + namelen--; + } + if (prepend(&buffer, &buflen, name, namelen)) goto Elong; root->mnt = vfsmnt; root->dentry = dentry; goto out; Elong: - retval = ERR_PTR(-ENAMETOOLONG); + buffer = ERR_PTR(-ENAMETOOLONG); goto out; } @@ -2011,10 +2037,8 @@ root = current->fs->root; path_get(&root); read_unlock(¤t->fs->lock); - spin_lock(&dcache_lock); tmp = root; - res = __d_path(path, &tmp, buf, buflen); - spin_unlock(&dcache_lock); + res = __d_path(path, &tmp, buf, buflen, 0); path_put(&root); return res; } @@ -2097,9 +2121,9 @@ */ asmlinkage long sys_getcwd(char __user *buf, unsigned long size) { - int error; - struct path pwd, root; - char *page = (char *) __get_free_page(GFP_USER); + int error, len; + struct path pwd, root, tmp; + char *page = (char *) __get_free_page(GFP_USER), *cwd; if (!page) return -ENOMEM; @@ -2111,30 +2135,20 @@ path_get(&root); read_unlock(¤t->fs->lock); - error = -ENOENT; - /* Has the current directory has been unlinked? */ - spin_lock(&dcache_lock); - if (IS_ROOT(pwd.dentry) || !d_unhashed(pwd.dentry)) { - unsigned long len; - struct path tmp = root; - char * cwd; - - cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE); - spin_unlock(&dcache_lock); - + tmp = root; + cwd = __d_path(&pwd, &tmp, page, PAGE_SIZE, D_PATH_FAIL_DELETED); + if (IS_ERR(cwd)) { error = PTR_ERR(cwd); - if (IS_ERR(cwd)) - goto out; + 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); + error = -ERANGE; + len = PAGE_SIZE + page - cwd; + if (len <= size) { + error = len; + if (copy_to_user(buf, cwd, len)) + error = -EFAULT; + } out: path_put(&pwd); --- linux-2.6.28.orig/fs/seq_file.c +++ linux-2.6.28/fs/seq_file.c @@ -412,9 +412,7 @@ char *s = m->buf + m->count; char *p; - spin_lock(&dcache_lock); - p = __d_path(path, root, s, m->size - m->count); - spin_unlock(&dcache_lock); + p = __d_path(path, root, s, m->size - m->count, 0); err = PTR_ERR(p); if (!IS_ERR(p)) { s = mangle_path(s, p, esc); --- linux-2.6.28.orig/fs/exec.c +++ linux-2.6.28/fs/exec.c @@ -1829,7 +1829,8 @@ goto close_fail; if (!file->f_op->write) goto close_fail; - if (!ispipe && do_truncate(file->f_path.dentry, 0, 0, file) != 0) + if (!ispipe && + do_truncate(file->f_path.dentry, file->f_path.mnt, 0, 0, file) != 0) goto close_fail; retval = binfmt->core_dump(signr, regs, file, core_limit); --- linux-2.6.28.orig/fs/open.c +++ linux-2.6.28/fs/open.c @@ -197,8 +197,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; @@ -209,16 +209,15 @@ newattrs.ia_size = length; newattrs.ia_valid = ATTR_SIZE | time_attrs; - if (filp) { - newattrs.ia_file = filp; + + if (filp) newattrs.ia_valid |= ATTR_FILE; - } /* Remove suid/sgid on truncate too */ newattrs.ia_valid |= should_remove_suid(dentry); mutex_lock(&dentry->d_inode->i_mutex); - err = notify_change(dentry, &newattrs); + err = fnotify_change(dentry, mnt, &newattrs, filp); mutex_unlock(&dentry->d_inode->i_mutex); return err; } @@ -251,7 +250,7 @@ if (error) goto dput_and_out; - error = inode_permission(inode, MAY_WRITE); + error = path_permission(&path, MAY_WRITE); if (error) goto mnt_drop_write_and_out; @@ -274,7 +273,7 @@ error = locks_verify_truncate(inode, NULL, length); if (!error) { DQUOT_INIT(inode); - error = do_truncate(path.dentry, length, 0, NULL); + error = do_truncate(path.dentry, path.mnt, length, 0, NULL); } put_write_and_out: @@ -329,7 +328,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: @@ -474,7 +474,7 @@ goto out_path_release; } - res = inode_permission(inode, mode | MAY_ACCESS); + res = path_permission(&path, mode | MAY_ACCESS); /* SuS v2 requires we report a read only fs too */ if (res || !(mode & S_IWOTH) || special_file(inode->i_mode)) goto out_path_release; @@ -517,7 +517,7 @@ if (error) goto out; - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); + error = path_permission(&path, MAY_EXEC | MAY_ACCESS); if (error) goto dput_and_out; @@ -546,7 +546,7 @@ if (!S_ISDIR(inode->i_mode)) goto out_putf; - error = inode_permission(inode, MAY_EXEC | MAY_ACCESS); + error = path_permission(&file->f_path, MAY_EXEC | MAY_ACCESS); if (!error) set_fs_pwd(current->fs, &file->f_path); out_putf: @@ -564,7 +564,7 @@ if (error) goto out; - error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS); + error = path_permission(&path, MAY_EXEC | MAY_ACCESS); if (error) goto dput_and_out; @@ -604,8 +604,8 @@ if (mode == (mode_t) -1) 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_MODE | ATTR_CTIME | ATTR_FILE; + err = fnotify_change(dentry, file->f_path.mnt, &newattrs, file); mutex_unlock(&inode->i_mutex); mnt_drop_write(file->f_path.mnt); out_putf: @@ -635,7 +635,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(path.dentry, &newattrs); + error = notify_change(path.dentry, path.mnt, &newattrs); mutex_unlock(&inode->i_mutex); mnt_drop_write(path.mnt); dput_and_out: @@ -649,7 +649,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 = dentry->d_inode; int error; @@ -667,8 +668,11 @@ if (!S_ISDIR(inode->i_mode)) newattrs.ia_valid |= ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV; + if (file) + newattrs.ia_valid |= ATTR_FILE; + mutex_lock(&inode->i_mutex); - error = notify_change(dentry, &newattrs); + error = fnotify_change(dentry, mnt, &newattrs, file); mutex_unlock(&inode->i_mutex); return error; @@ -685,7 +689,7 @@ error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); + error = chown_common(path.dentry, path.mnt, user, group, NULL); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -710,7 +714,7 @@ error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); + error = chown_common(path.dentry, path.mnt, user, group, NULL); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -729,7 +733,7 @@ error = mnt_want_write(path.mnt); if (error) goto out_release; - error = chown_common(path.dentry, user, group); + error = chown_common(path.dentry, path.mnt, user, group, NULL); mnt_drop_write(path.mnt); out_release: path_put(&path); @@ -753,7 +757,7 @@ goto out_fput; dentry = file->f_path.dentry; audit_inode(NULL, dentry); - error = chown_common(dentry, user, group); + error = chown_common(dentry, file->f_path.mnt, user, group, file); mnt_drop_write(file->f_path.mnt); out_fput: fput(file); --- linux-2.6.28.orig/fs/file_table.c +++ linux-2.6.28/fs/file_table.c @@ -351,6 +351,7 @@ file_free(file); } } +EXPORT_SYMBOL(put_filp); void file_move(struct file *file, struct list_head *list) { --- linux-2.6.28.orig/fs/inotify_user.c +++ linux-2.6.28/fs/inotify_user.c @@ -372,7 +372,7 @@ if (error) return error; /* you can only watch an inode if you have read permissions on it */ - error = inode_permission(path->dentry->d_inode, MAY_READ); + error = path_permission(path, MAY_READ); if (error) path_put(path); return error; --- linux-2.6.28.orig/fs/namei.c +++ linux-2.6.28/fs/namei.c @@ -226,7 +226,7 @@ return -EACCES; } -int inode_permission(struct inode *inode, int mask) +static int __inode_permission(struct inode *inode, int mask) { int retval; @@ -256,7 +256,12 @@ if (retval) return retval; - retval = devcgroup_inode_permission(inode, mask); + return devcgroup_inode_permission(inode, mask); +} + +int inode_permission(struct inode *inode, int mask) +{ + int retval = __inode_permission(inode, mask); if (retval) return retval; @@ -264,6 +269,15 @@ mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND)); } +int path_permission(struct path *path, int mask) +{ + int retval = __inode_permission(path->dentry->d_inode, mask); + if (retval) + return retval; + return security_path_permission(path, + mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND)); +} + /** * vfs_permission - check for access rights to a given path * @nd: lookup result that describes the path @@ -276,7 +290,7 @@ */ int vfs_permission(struct nameidata *nd, int mask) { - return inode_permission(nd->path.dentry->d_inode, mask); + return path_permission(&nd->path, mask); } /** @@ -293,7 +307,7 @@ */ int file_permission(struct file *file, int mask) { - return inode_permission(file->f_path.dentry->d_inode, mask); + return path_permission(&file->f_path, mask); } /* @@ -434,8 +448,9 @@ * short-cut DAC fails, then call permission() to do more * complete permission check. */ -static int exec_permission_lite(struct inode *inode) +static int exec_permission_lite(struct path *path) { + struct inode *inode = path->dentry->d_inode; umode_t mode = inode->i_mode; if (inode->i_op && inode->i_op->permission) @@ -460,7 +475,7 @@ return -EACCES; ok: - return security_inode_permission(inode, MAY_EXEC); + return security_path_permission(path, MAY_EXEC); } /* @@ -857,7 +872,7 @@ unsigned int c; nd->flags |= LOOKUP_CONTINUE; - err = exec_permission_lite(inode); + err = exec_permission_lite(&nd->path); if (err == -EAGAIN) err = vfs_permission(nd, MAY_EXEC); if (err) @@ -1052,24 +1067,21 @@ path_get(&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->path = file->f_path; retval = -ENOTDIR; - if (!S_ISDIR(dentry->d_inode->i_mode)) + if (!S_ISDIR(nd->path.dentry->d_inode->i_mode)) goto fput_fail; retval = file_permission(file, MAY_EXEC); if (retval) goto fput_fail; - nd->path = file->f_path; path_get(&file->f_path); fput_light(file, fput_needed); @@ -1164,7 +1176,7 @@ return err; } -static struct dentry *__lookup_hash(struct qstr *name, +struct dentry *__lookup_hash(struct qstr *name, struct dentry *base, struct nameidata *nd) { struct dentry *dentry; @@ -1216,7 +1228,7 @@ { int err; - err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC); + err = path_permission(&nd->path, MAY_EXEC); if (err) return ERR_PTR(err); return __lookup_hash(&nd->last, nd->path.dentry, nd); @@ -1481,7 +1493,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->path.mnt : NULL, mode); if (error) return error; DQUOT_INIT(dir); @@ -1557,7 +1569,7 @@ if (!error) { DQUOT_INIT(inode); - error = do_truncate(dentry, 0, + error = do_truncate(dentry, nd->path.mnt, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, NULL); } @@ -1924,7 +1936,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); @@ -1941,7 +1954,7 @@ if (error) return error; - error = security_inode_mknod(dir, dentry, mode, dev); + error = security_inode_mknod(dir, dentry, mnt, mode, dev); if (error) return error; @@ -2002,11 +2015,12 @@ error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd); break; case S_IFCHR: case S_IFBLK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode, - new_decode_dev(dev)); + error = vfs_mknod(nd.path.dentry->d_inode, dentry, + nd.path.mnt, mode, new_decode_dev(dev)); break; case S_IFIFO: case S_IFSOCK: - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0); + error = vfs_mknod(nd.path.dentry->d_inode, dentry, + nd.path.mnt, mode, 0); break; } mnt_drop_write(nd.path.mnt); @@ -2025,7 +2039,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); @@ -2036,7 +2051,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; @@ -2068,7 +2083,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode); + error = vfs_mkdir(nd.path.dentry->d_inode, dentry, nd.path.mnt, mode); mnt_drop_write(nd.path.mnt); out_dput: dput(dentry); @@ -2112,7 +2127,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); @@ -2122,6 +2137,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); @@ -2129,12 +2148,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) { @@ -2178,7 +2194,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto exit3; - error = vfs_rmdir(nd.path.dentry->d_inode, dentry); + error = vfs_rmdir(nd.path.dentry->d_inode, dentry, nd.path.mnt); mnt_drop_write(nd.path.mnt); exit3: dput(dentry); @@ -2195,7 +2211,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); @@ -2211,7 +2227,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); } @@ -2263,7 +2279,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto exit2; - error = vfs_unlink(nd.path.dentry->d_inode, dentry); + error = vfs_unlink(nd.path.dentry->d_inode, dentry, nd.path.mnt); mnt_drop_write(nd.path.mnt); exit2: dput(dentry); @@ -2298,7 +2314,8 @@ return do_unlinkat(AT_FDCWD, pathname); } -int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) +int vfs_symlink(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt, + const char *oldname) { int error = may_create(dir, dentry); @@ -2308,7 +2325,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; @@ -2344,7 +2361,7 @@ error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_symlink(nd.path.dentry->d_inode, dentry, from); + error = vfs_symlink(nd.path.dentry->d_inode, dentry, nd.path.mnt, from); mnt_drop_write(nd.path.mnt); out_dput: dput(dentry); @@ -2362,7 +2379,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; @@ -2387,7 +2404,8 @@ if (S_ISDIR(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; @@ -2441,7 +2459,9 @@ error = mnt_want_write(nd.path.mnt); if (error) goto out_dput; - error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry); + error = vfs_link(old_path.dentry, old_path.mnt, + nd.path.dentry->d_inode, + new_dentry, nd.path.mnt); mnt_drop_write(nd.path.mnt); out_dput: dput(new_dentry); @@ -2494,7 +2514,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; @@ -2509,7 +2530,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; @@ -2537,12 +2559,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; @@ -2565,7 +2589,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); @@ -2594,9 +2619,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, @@ -2677,8 +2704,8 @@ error = mnt_want_write(oldnd.path.mnt); if (error) 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.path.mnt, + new_dir->d_inode, new_dentry, newnd.path.mnt); mnt_drop_write(oldnd.path.mnt); exit5: dput(new_dentry); @@ -2847,6 +2874,7 @@ EXPORT_SYMBOL(kern_path); EXPORT_SYMBOL(vfs_path_lookup); EXPORT_SYMBOL(inode_permission); +EXPORT_SYMBOL(path_permission); EXPORT_SYMBOL(vfs_permission); EXPORT_SYMBOL(file_permission); EXPORT_SYMBOL(unlock_rename); @@ -2863,3 +2891,5 @@ EXPORT_SYMBOL(vfs_unlink); EXPORT_SYMBOL(dentry_unhash); EXPORT_SYMBOL(generic_readlink); +EXPORT_SYMBOL(deny_write_access); +EXPORT_SYMBOL(__lookup_hash); --- linux-2.6.28.orig/fs/namespace.c +++ linux-2.6.28/fs/namespace.c @@ -2349,3 +2349,33 @@ release_mounts(&umount_list); kfree(ns); } + +char *d_namespace_path(struct dentry *dentry, struct vfsmount *vfsmnt, + char *buf, int buflen) +{ + struct path root, tmp, ns_root = { }; + struct path path = { .mnt = vfsmnt, .dentry = dentry }; + char *res; + + read_lock(¤t->fs->lock); + root = current->fs->root; + path_get(¤t->fs->root); + read_unlock(¤t->fs->lock); + spin_lock(&vfsmount_lock); + if (root.mnt) + ns_root.mnt = mntget(root.mnt->mnt_ns->root); + if (ns_root.mnt) + ns_root.dentry = dget(ns_root.mnt->mnt_root); + spin_unlock(&vfsmount_lock); + tmp = ns_root; + res = __d_path(&path, &tmp, buf, buflen, + D_PATH_FAIL_DELETED | D_PATH_DISCONNECT); + path_put(&root); + path_put(&ns_root); + + /* Prevent empty path for lazily unmounted filesystems. */ + if (!IS_ERR(res) && *res == '\0') + *--res = '.'; + return res; +} +EXPORT_SYMBOL(d_namespace_path); --- linux-2.6.28.orig/fs/utimes.c +++ linux-2.6.28/fs/utimes.c @@ -48,7 +48,8 @@ return nsec >= 0 && nsec <= 999999999; } -static int utimes_common(struct path *path, struct timespec *times) +static int utimes_common(struct path *path, struct timespec *times, + struct file *f) { int error; struct iattr newattrs; @@ -102,7 +103,7 @@ } } mutex_lock(&inode->i_mutex); - error = notify_change(path->dentry, &newattrs); + error = fnotify_change(path->dentry, path->mnt, &newattrs, f); mutex_unlock(&inode->i_mutex); mnt_drop_write_and_out: @@ -149,7 +150,7 @@ if (!file) goto out; - error = utimes_common(&file->f_path, times); + error = utimes_common(&file->f_path, times, file); fput(file); } else { struct path path; @@ -162,7 +163,7 @@ if (error) goto out; - error = utimes_common(&path, times); + error = utimes_common(&path, times, NULL); path_put(&path); } --- linux-2.6.28.orig/fs/splice.c +++ linux-2.6.28/fs/splice.c @@ -887,8 +887,8 @@ /* * Attempt to initiate a splice from pipe to file. */ -static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags) +long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { int ret; @@ -907,13 +907,14 @@ return out->f_op->splice_write(pipe, out, ppos, len, flags); } +EXPORT_SYMBOL(do_splice_from); /* * Attempt to initiate a splice from a file to a pipe. */ -static long do_splice_to(struct file *in, loff_t *ppos, - struct pipe_inode_info *pipe, size_t len, - unsigned int flags) +long do_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags) { int ret; @@ -929,6 +930,7 @@ return in->f_op->splice_read(in, ppos, pipe, len, flags); } +EXPORT_SYMBOL(do_splice_to); /** * splice_direct_to_actor - splices data directly between two non-pipes --- linux-2.6.28.orig/fs/stat.c +++ linux-2.6.28/fs/stat.c @@ -306,7 +306,7 @@ error = -EINVAL; if (inode->i_op && inode->i_op->readlink) { - error = security_inode_readlink(path.dentry); + error = security_inode_readlink(path.dentry, path.mnt); if (!error) { touch_atime(path.mnt, path.dentry); error = inode->i_op->readlink(path.dentry, --- linux-2.6.28.orig/fs/xattr.c +++ linux-2.6.28/fs/xattr.c @@ -67,8 +67,8 @@ } int -vfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags) +vfs_setxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, + const void *value, size_t size, int flags, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -78,7 +78,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; @@ -86,7 +86,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, @@ -131,7 +131,8 @@ EXPORT_SYMBOL_GPL(xattr_getsecurity); ssize_t -vfs_getxattr(struct dentry *dentry, const char *name, void *value, size_t size) +vfs_getxattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, + void *value, size_t size, struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -140,7 +141,7 @@ if (error) return error; - error = security_inode_getxattr(dentry, name); + error = security_inode_getxattr(dentry, mnt, name, file); if (error) return error; @@ -167,18 +168,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; } @@ -187,7 +190,8 @@ EXPORT_SYMBOL_GPL(vfs_listxattr); int -vfs_removexattr(struct dentry *dentry, const char *name) +vfs_removexattr(struct dentry *dentry, struct vfsmount *mnt, const char *name, + struct file *file) { struct inode *inode = dentry->d_inode; int error; @@ -199,7 +203,7 @@ if (error) return error; - error = security_inode_removexattr(dentry, name); + error = security_inode_removexattr(dentry, mnt, name, file); if (error) return error; @@ -218,8 +222,8 @@ * Extended attribute SET operations */ static long -setxattr(struct dentry *d, const char __user *name, const void __user *value, - size_t size, int flags) +setxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name, + const void __user *value, size_t size, int flags, struct file *file) { int error; void *kvalue = NULL; @@ -246,7 +250,7 @@ } } - error = vfs_setxattr(d, kname, kvalue, size, flags); + error = vfs_setxattr(dentry, mnt, kname, kvalue, size, flags, file); kfree(kvalue); return error; } @@ -263,7 +267,7 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = setxattr(path.dentry, name, value, size, flags); + error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL); mnt_drop_write(path.mnt); } path_put(&path); @@ -282,7 +286,7 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = setxattr(path.dentry, name, value, size, flags); + error = setxattr(path.dentry, path.mnt, name, value, size, flags, NULL); mnt_drop_write(path.mnt); } path_put(&path); @@ -304,7 +308,8 @@ audit_inode(NULL, dentry); error = mnt_want_write(f->f_path.mnt); if (!error) { - error = setxattr(dentry, name, value, size, flags); + error = setxattr(dentry, f->f_vfsmnt, name, value, size, flags, + f); mnt_drop_write(f->f_path.mnt); } fput(f); @@ -315,8 +320,8 @@ * Extended attribute GET operations */ static ssize_t -getxattr(struct dentry *d, const char __user *name, void __user *value, - size_t size) +getxattr(struct dentry *dentry, struct vfsmount *mnt, const char __user *name, + void __user *value, size_t size, struct file *file) { ssize_t error; void *kvalue = NULL; @@ -336,7 +341,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; @@ -359,7 +364,7 @@ error = user_path(pathname, &path); if (error) return error; - error = getxattr(path.dentry, name, value, size); + error = getxattr(path.dentry, path.mnt, name, value, size, NULL); path_put(&path); return error; } @@ -374,7 +379,7 @@ error = user_lpath(pathname, &path); if (error) return error; - error = getxattr(path.dentry, name, value, size); + error = getxattr(path.dentry, path.mnt, name, value, size, NULL); path_put(&path); return error; } @@ -389,7 +394,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry); - 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; } @@ -398,7 +403,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; @@ -411,7 +417,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; @@ -433,7 +439,7 @@ error = user_path(pathname, &path); if (error) return error; - error = listxattr(path.dentry, list, size); + error = listxattr(path.dentry, path.mnt, list, size, NULL); path_put(&path); return error; } @@ -447,7 +453,7 @@ error = user_lpath(pathname, &path); if (error) return error; - error = listxattr(path.dentry, list, size); + error = listxattr(path.dentry, path.mnt, list, size, NULL); path_put(&path); return error; } @@ -462,7 +468,7 @@ if (!f) return error; audit_inode(NULL, f->f_path.dentry); - 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; } @@ -471,7 +477,8 @@ * Extended attribute REMOVE operations */ static long -removexattr(struct dentry *d, const char __user *name) +removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char __user *name, struct file *file) { int error; char kname[XATTR_NAME_MAX + 1]; @@ -482,7 +489,7 @@ if (error < 0) return error; - return vfs_removexattr(d, kname); + return vfs_removexattr(dentry, mnt, kname, file); } asmlinkage long @@ -496,7 +503,7 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = removexattr(path.dentry, name); + error = removexattr(path.dentry, path.mnt, name, NULL); mnt_drop_write(path.mnt); } path_put(&path); @@ -514,7 +521,7 @@ return error; error = mnt_want_write(path.mnt); if (!error) { - error = removexattr(path.dentry, name); + error = removexattr(path.dentry, path.mnt, name, NULL); mnt_drop_write(path.mnt); } path_put(&path); @@ -535,7 +542,7 @@ audit_inode(NULL, dentry); error = mnt_want_write(f->f_path.mnt); if (!error) { - error = removexattr(dentry, name); + error = removexattr(dentry, f->f_path.mnt, name, f); mnt_drop_write(f->f_path.mnt); } fput(f); --- linux-2.6.28.orig/fs/fat/file.c +++ linux-2.6.28/fs/fat/file.c @@ -93,7 +93,7 @@ * out the RO attribute for checking by the security * module, just because it maps to a file mode. */ - err = security_inode_setattr(filp->f_path.dentry, &ia); + err = security_inode_setattr(filp->f_path.dentry, filp->f_path.mnt, &ia); if (err) goto up; --- linux-2.6.28.orig/fs/afs/dir.c +++ linux-2.6.28/fs/afs/dir.c @@ -46,6 +46,7 @@ .readdir = afs_readdir, .lock = afs_lock, .llseek = generic_file_llseek, + .fsetattr = afs_fsetattr, }; const struct inode_operations afs_dir_inode_operations = { --- linux-2.6.28.orig/fs/afs/file.c +++ linux-2.6.28/fs/afs/file.c @@ -36,6 +36,7 @@ .fsync = afs_fsync, .lock = afs_lock, .flock = afs_flock, + .fsetattr = afs_fsetattr, }; const struct inode_operations afs_file_inode_operations = { --- linux-2.6.28.orig/fs/afs/internal.h +++ linux-2.6.28/fs/afs/internal.h @@ -548,6 +548,7 @@ extern int afs_validate(struct afs_vnode *, struct key *); extern int afs_getattr(struct vfsmount *, struct dentry *, struct kstat *); extern int afs_setattr(struct dentry *, struct iattr *); +extern int afs_fsetattr(struct file *, struct iattr *); extern void afs_clear_inode(struct inode *); /* --- linux-2.6.28.orig/fs/afs/inode.c +++ linux-2.6.28/fs/afs/inode.c @@ -358,7 +358,8 @@ /* * set the attributes of an inode */ -int afs_setattr(struct dentry *dentry, struct iattr *attr) +static int afs_do_setattr(struct dentry *dentry, struct iattr *attr, + struct file *file) { struct afs_vnode *vnode = AFS_FS_I(dentry->d_inode); struct key *key; @@ -380,8 +381,8 @@ afs_writeback_all(vnode); } - if (attr->ia_valid & ATTR_FILE) { - key = attr->ia_file->private_data; + if (file) { + key = file->private_data; } else { key = afs_request_key(vnode->volume->cell); if (IS_ERR(key)) { @@ -391,10 +392,20 @@ } ret = afs_vnode_setattr(vnode, key, attr); - if (!(attr->ia_valid & ATTR_FILE)) + if (!file) key_put(key); error: _leave(" = %d", ret); return ret; } + +int afs_setattr(struct dentry *dentry, struct iattr *attr) +{ + return afs_do_setattr(dentry, attr, NULL); +} + +int afs_fsetattr(struct file *file, struct iattr *attr) +{ + return afs_do_setattr(file->f_path.dentry, attr, file); +} --- linux-2.6.28.orig/fs/reiserfs/xattr.c +++ linux-2.6.28/fs/reiserfs/xattr.c @@ -459,7 +459,7 @@ newattrs.ia_size = buffer_size; newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); - err = notify_change(dentry, &newattrs); + err = notify_change(dentry, NULL, &newattrs); if (err) goto out_filp; @@ -746,7 +746,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 { @@ -790,7 +790,7 @@ } if (!S_ISDIR(xafile->d_inode->i_mode)) - err = notify_change(xafile, attrs); + err = notify_change(xafile, NULL, attrs); dput(xafile); return err; @@ -834,7 +834,7 @@ goto out_dir; } - err = notify_change(dir, attrs); + err = notify_change(dir, NULL, attrs); unlock_kernel(); out_dir: --- linux-2.6.28.orig/fs/nfsd/nfs4xdr.c +++ linux-2.6.28/fs/nfsd/nfs4xdr.c @@ -1458,7 +1458,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_path.mnt, &acl); aclsupport = (err == 0); if (bmval0 & FATTR4_WORD0_ACL) { if (err == -EOPNOTSUPP) --- linux-2.6.28.orig/fs/nfsd/vfs.c +++ linux-2.6.28/fs/nfsd/vfs.c @@ -387,7 +387,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_path.mnt, iap); err = nfserrno(host_err); fh_unlock(fhp); } @@ -407,12 +407,13 @@ #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; ssize_t ret; - buflen = vfs_getxattr(dentry, key, NULL, 0); + buflen = vfs_getxattr(dentry, mnt, key, NULL, 0, NULL); if (buflen <= 0) return buflen; @@ -420,7 +421,7 @@ if (!*buf) return -ENOMEM; - ret = vfs_getxattr(dentry, key, *buf, buflen); + ret = vfs_getxattr(dentry, mnt, key, *buf, buflen, NULL); if (ret < 0) kfree(*buf); return ret; @@ -429,7 +430,8 @@ #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; @@ -448,7 +450,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; @@ -461,6 +463,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; @@ -471,6 +474,7 @@ return error; dentry = fhp->fh_dentry; + mnt = fhp->fh_export->ex_path.mnt; inode = dentry->d_inode; if (S_ISDIR(inode->i_mode)) flags = NFS4_ACL_DIR; @@ -481,12 +485,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_release; 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); out_release: posix_acl_release(pacl); @@ -499,13 +505,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) @@ -517,14 +523,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)) { @@ -534,7 +541,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)) { @@ -947,13 +954,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 | ATTR_KILL_PRIV; mutex_lock(&dentry->d_inode->i_mutex); - notify_change(dentry, &ia); + notify_change(dentry, mnt, &ia); mutex_unlock(&dentry->d_inode->i_mutex); } @@ -1012,7 +1019,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_path.mnt); if (host_err >= 0 && stable) { static ino_t last_ino; @@ -1190,6 +1197,7 @@ int type, dev_t rdev, struct svc_fh *resfhp) { struct dentry *dentry, *dchild = NULL; + struct svc_export *exp; struct inode *dirp; __be32 err; __be32 err2; @@ -1207,6 +1215,7 @@ goto out; dentry = fhp->fh_dentry; + exp = fhp->fh_export; dirp = dentry->d_inode; err = nfserr_notdir; @@ -1223,7 +1232,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 { @@ -1273,13 +1282,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_path.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_path.mnt, + iap->ia_mode, rdev); break; } if (host_err < 0) { @@ -1287,7 +1297,7 @@ 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); } @@ -1517,6 +1527,7 @@ struct iattr *iap) { struct dentry *dentry, *dnew; + struct svc_export *exp; __be32 err, cerr; int host_err; @@ -1541,6 +1552,7 @@ if (host_err) goto out_nfserr; + exp = fhp->fh_export; if (unlikely(path[plen] != 0)) { char *path_alloced = kmalloc(plen+1, GFP_KERNEL); if (path_alloced == NULL) @@ -1548,14 +1560,16 @@ else { strncpy(path_alloced, path, plen); path_alloced[plen] = 0; - host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced); + host_err = vfs_symlink(dentry->d_inode, dnew, + exp->ex_path.mnt, path_alloced); kfree(path_alloced); } } else - host_err = vfs_symlink(dentry->d_inode, dnew, path); + host_err = vfs_symlink(dentry->d_inode, dnew, exp->ex_path.mnt, + path); if (!host_err) { - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); } err = nfserrno(host_err); @@ -1563,7 +1577,7 @@ mnt_drop_write(fhp->fh_export->ex_path.mnt); - cerr = fh_compose(resfhp, fhp->fh_export, dnew, fhp); + cerr = fh_compose(resfhp, exp, dnew, fhp); dput(dnew); if (err==0) err = cerr; out: @@ -1618,7 +1632,8 @@ err = nfserrno(host_err); goto out_dput; } - host_err = vfs_link(dold, dirp, dnew); + host_err = vfs_link(dold, tfhp->fh_export->ex_path.mnt, dirp, + dnew, ffhp->fh_export->ex_path.mnt); if (!host_err) { if (EX_ISSYNC(ffhp->fh_export)) { err = nfserrno(nfsd_sync_dir(ddir)); @@ -1719,7 +1734,8 @@ if (host_err) goto out_dput_new; - host_err = vfs_rename(fdir, odentry, tdir, ndentry); + host_err = vfs_rename(fdir, odentry, ffhp->fh_export->ex_path.mnt, + tdir, ndentry, tfhp->fh_export->ex_path.mnt); if (!host_err && EX_ISSYNC(tfhp->fh_export)) { host_err = nfsd_sync_dir(tdentry); if (!host_err) @@ -1757,6 +1773,7 @@ char *fname, int flen) { struct dentry *dentry, *rdentry; + struct svc_export *exp; struct inode *dirp; __be32 err; int host_err; @@ -1771,6 +1788,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); @@ -1792,21 +1810,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_path.mnt); } else { /* It's RMDIR */ - host_err = vfs_rmdir(dirp, rdentry); + host_err = vfs_rmdir(dirp, rdentry, exp->ex_path.mnt); } dput(rdentry); if (host_err) goto out_drop; - if (EX_ISSYNC(fhp->fh_export)) + if (EX_ISSYNC(exp)) host_err = nfsd_sync_dir(dentry); out_drop: @@ -2143,7 +2161,8 @@ return ERR_PTR(-EOPNOTSUPP); } - size = nfsd_getxattr(fhp->fh_dentry, name, &value); + size = nfsd_getxattr(fhp->fh_dentry, fhp->fh_export->ex_path.mnt, name, + &value); if (size < 0) return ERR_PTR(size); @@ -2155,6 +2174,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; @@ -2187,21 +2207,24 @@ } else size = 0; - error = mnt_want_write(fhp->fh_export->ex_path.mnt); + mnt = fhp->fh_export->ex_path.mnt; + error = mnt_want_write(mnt); if (error) goto getout; 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; } } - mnt_drop_write(fhp->fh_export->ex_path.mnt); + mnt_drop_write(mnt); getout: kfree(value); --- linux-2.6.28.orig/fs/nfsd/nfs4recover.c +++ linux-2.6.28/fs/nfsd/nfs4recover.c @@ -158,7 +158,8 @@ status = mnt_want_write(rec_dir.mnt); if (status) 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); mnt_drop_write(rec_dir.mnt); out_put: dput(dentry); @@ -263,7 +264,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; } @@ -278,7 +279,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-2.6.28.orig/fs/proc/Makefile +++ linux-2.6.28/fs/proc/Makefile @@ -25,3 +25,4 @@ proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o proc-$(CONFIG_PRINTK) += kmsg.o proc-$(CONFIG_PROC_PAGE_MONITOR) += page.o +proc-y += version_signature.o --- linux-2.6.28.orig/fs/proc/version_signature.c +++ linux-2.6.28/fs/proc/version_signature.c @@ -0,0 +1,31 @@ +#include +#include +#include +#include +#include +#include + +static int version_signature_proc_show(struct seq_file *m, void *v) +{ + seq_printf(m, "%s\n", CONFIG_VERSION_SIGNATURE); + return 0; +} + +static int version_signature_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, version_signature_proc_show, NULL); +} + +static const struct file_operations version_signature_proc_fops = { + .open = version_signature_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init proc_version_signature_init(void) +{ + proc_create("version_signature", 0, NULL, &version_signature_proc_fops); + return 0; +} +module_init(proc_version_signature_init); --- linux-2.6.28.orig/fs/fuse/dir.c +++ linux-2.6.28/fs/fuse/dir.c @@ -1105,21 +1105,22 @@ return file ? fuse_fsync_common(file, de, datasync, 1) : 0; } -static bool update_mtime(unsigned ivalid) +static bool update_mtime(unsigned ivalid, bool have_file) { /* Always update if mtime is explicitly set */ if (ivalid & ATTR_MTIME_SET) return true; /* If it's an open(O_TRUNC) or an ftruncate(), don't update */ - if ((ivalid & ATTR_SIZE) && (ivalid & (ATTR_OPEN | ATTR_FILE))) + if ((ivalid & ATTR_SIZE) && ((ivalid & ATTR_OPEN) || have_file)) return false; /* In all other cases update */ return true; } -static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg) +static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, + bool have_file) { unsigned ivalid = iattr->ia_valid; @@ -1138,7 +1139,7 @@ if (!(ivalid & ATTR_ATIME_SET)) arg->valid |= FATTR_ATIME_NOW; } - if ((ivalid & ATTR_MTIME) && update_mtime(ivalid)) { + if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, have_file)) { arg->valid |= FATTR_MTIME; arg->mtime = iattr->ia_mtime.tv_sec; arg->mtimensec = iattr->ia_mtime.tv_nsec; @@ -1199,8 +1200,8 @@ * vmtruncate() doesn't allow for this case, so do the rlimit checking * and the actual truncation by hand. */ -static int fuse_do_setattr(struct dentry *entry, struct iattr *attr, - struct file *file) +int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + struct file *file) { struct inode *inode = entry->d_inode; struct fuse_conn *fc = get_fuse_conn(inode); @@ -1244,7 +1245,7 @@ memset(&inarg, 0, sizeof(inarg)); memset(&outarg, 0, sizeof(outarg)); - iattr_to_fattr(attr, &inarg); + iattr_to_fattr(attr, &inarg, file != NULL); if (file) { struct fuse_file *ff = file->private_data; inarg.valid |= FATTR_FH; @@ -1314,10 +1315,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) { - if (attr->ia_valid & ATTR_FILE) - return fuse_do_setattr(entry, attr, attr->ia_file); - else - return fuse_do_setattr(entry, attr, NULL); + return fuse_do_setattr(entry, attr, NULL); } static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry, --- linux-2.6.28.orig/fs/fuse/file.c +++ linux-2.6.28/fs/fuse/file.c @@ -1470,6 +1470,11 @@ return retval; } +static int fuse_fsetattr(struct file *file, struct iattr *attr) +{ + return fuse_do_setattr(file->f_path.dentry, attr, file); +} + static const struct file_operations fuse_file_operations = { .llseek = fuse_file_llseek, .read = do_sync_read, @@ -1483,6 +1488,7 @@ .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fsetattr = fuse_fsetattr, .splice_read = generic_file_splice_read, }; @@ -1496,6 +1502,7 @@ .fsync = fuse_fsync, .lock = fuse_file_lock, .flock = fuse_file_flock, + .fsetattr = fuse_fsetattr, /* no mmap and splice_read */ }; --- linux-2.6.28.orig/fs/fuse/fuse_i.h +++ linux-2.6.28/fs/fuse/fuse_i.h @@ -554,6 +554,10 @@ */ int fuse_dev_init(void); + +int fuse_do_setattr(struct dentry *entry, struct iattr *attr, + struct file *file); + /** * Cleanup the client device */ --- linux-2.6.28.orig/fs/hpfs/namei.c +++ linux-2.6.28/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-2.6.28.orig/fs/ecryptfs/inode.c +++ linux-2.6.28/fs/ecryptfs/inode.c @@ -403,19 +403,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); @@ -440,11 +445,12 @@ { 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); struct dentry *lower_dir_dentry; lower_dir_dentry = 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; @@ -464,6 +470,7 @@ { int rc; struct dentry *lower_dentry; + struct vfsmount *lower_mnt; struct dentry *lower_dir_dentry; char *encoded_symname; int encoded_symlen; @@ -471,6 +478,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); encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, strlen(symname), @@ -479,7 +487,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); kfree(encoded_symname); if (rc || !lower_dentry->d_inode) @@ -501,11 +509,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); @@ -524,14 +535,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); @@ -549,11 +562,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); @@ -574,19 +590,24 @@ { 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); @@ -849,6 +870,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; @@ -859,6 +881,7 @@ 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); @@ -910,7 +933,7 @@ ia->ia_valid &= ~ATTR_MODE; mutex_lock(&lower_dentry->d_inode->i_mutex); - rc = notify_change(lower_dentry, ia); + rc = notify_change(lower_dentry, lower_mnt, ia); mutex_unlock(&lower_dentry->d_inode->i_mutex); out: fsstack_copy_attr_all(inode, lower_inode, NULL); --- linux-2.6.28.orig/init/initramfs.c +++ linux-2.6.28/init/initramfs.c @@ -7,6 +7,9 @@ #include #include #include +#ifdef ACPI_CONFIG +#include +#endif static __initdata char *message; static void __init error(char *x) @@ -124,6 +127,12 @@ static __initdata uid_t uid; static __initdata gid_t gid; static __initdata unsigned rdev; +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static __initdata char *file_looked_for; +static __initdata struct acpi_table_header *file_mem; +#else +const char *file_looked_for = NULL; +#endif static void __init parse_header(char *s) { @@ -158,6 +167,7 @@ SkipIt, GotName, CopyFile, + CopyFileMem, GotSymlink, Reset } state, next_state; @@ -295,6 +305,54 @@ static __initdata int wfd; +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +static __init int is_file_looked_for(char *filename) +{ + char *tmp_collected = collected; + if (file_looked_for == NULL) + return 0; + if (!S_ISREG(mode)) + return 0; + /* remove the leading / */ + while (*tmp_collected == '/') + tmp_collected++; + return (strcmp(tmp_collected, file_looked_for) == 0); +} + +static int __init do_copy_mem(void) +{ + static void *file_current; /* current position in the memory */ + if (file_mem == NULL) { + if (body_len < 4) { /* check especially against empty files */ + error("file is less than 4 bytes"); + return 1; + } + file_mem = kmalloc(body_len, GFP_ATOMIC); + if (!file_mem) { + error("failed to allocate enough memory"); + return 1; + } + file_current = file_mem; + } + if (count >= body_len) { + memcpy(file_current, victim, body_len); + eat(body_len); + file_looked_for = NULL; /* don't find files with same name */ + state = SkipIt; + return 0; + } else { + memcpy(file_current, victim, count); + file_current += count; + body_len -= count; + eat(count); + return 1; + } +} +#else +static inline int is_file_looked_for(char *filename) {return 0;} +#define do_copy_mem NULL /* because it is used as a pointer */ +#endif + static int __init do_name(void) { state = SkipIt; @@ -303,6 +361,8 @@ free_hash(); return 0; } + if (is_file_looked_for(file_looked_for)) + state = CopyFileMem; if (dry_run) return 0; clean_path(collected, mode); @@ -375,6 +435,7 @@ [SkipIt] = do_skip, [GotName] = do_name, [CopyFile] = do_copy, + [CopyFileMem] = do_copy_mem, [GotSymlink] = do_symlink, [Reset] = do_reset, }; @@ -613,3 +674,31 @@ return 0; } rootfs_initcall(populate_rootfs); + +#ifdef CONFIG_ACPI_CUSTOM_DSDT_INITRD +struct __init acpi_table_header *acpi_find_dsdt_initrd(void) +{ + char *err, *ramfs_dsdt_name = "DSDT.aml"; + + printk(KERN_INFO "ACPI: Checking initramfs for custom DSDT\n"); + file_mem = NULL; + file_looked_for = ramfs_dsdt_name; + err = unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start, 1); + file_looked_for = NULL; + + if (err) { + /* + * Even if reading the DSDT file was successful, + * we give up if the initramfs cannot be entirely read. + */ + kfree(file_mem); + printk(KERN_ERR "ACPI: Aborted because %s.\n", err); + return NULL; + } + if (file_mem) + printk(KERN_INFO "ACPI: Found DSDT in %s.\n", ramfs_dsdt_name); + + return file_mem; +} +#endif --- linux-2.6.28.orig/init/do_mounts_rd.c +++ linux-2.6.28/init/do_mounts_rd.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ * numbers could not be found. * * We currently check for the following magic numbers: + * squashfs * minix * ext2 * romfs @@ -51,6 +53,7 @@ struct ext2_super_block *ext2sb; struct romfs_super_block *romfsb; struct cramfs_super *cramfsb; + struct squashfs_super_block *squashfsb; int nblocks = -1; unsigned char *buf; @@ -62,6 +65,7 @@ ext2sb = (struct ext2_super_block *) buf; romfsb = (struct romfs_super_block *) buf; cramfsb = (struct cramfs_super *) buf; + squashfsb = (struct squashfs_super_block *) buf; memset(buf, 0xe5, size); /* @@ -99,6 +103,18 @@ goto done; } + /* squashfs is at block zero too */ + if (squashfsb->s_magic == SQUASHFS_MAGIC) { + printk(KERN_NOTICE + "RAMDISK: squashfs filesystem found at block %d\n", + start_block); + if (squashfsb->s_major < 3) + nblocks = (squashfsb->bytes_used_2+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; + else + nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; + goto done; + } + /* * Read block 1 to test for minix and ext2 superblock */ --- linux-2.6.28.orig/init/Kconfig +++ linux-2.6.28/init/Kconfig @@ -101,6 +101,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 --- linux-2.6.28.orig/init/version.c +++ linux-2.6.28/init/version.c @@ -39,7 +39,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-2.6.28.orig/mm/filemap.c +++ linux-2.6.28/mm/filemap.c @@ -1773,12 +1773,12 @@ } EXPORT_SYMBOL(should_remove_suid); -static int __remove_suid(struct dentry *dentry, int kill) +static 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 file_remove_suid(struct file *file) @@ -1793,7 +1793,7 @@ if (killpriv) error = security_inode_killpriv(dentry); if (!error && killsuid) - error = __remove_suid(dentry, killsuid); + error = __remove_suid(&file->f_path, killsuid); return error; } --- linux-2.6.28.orig/mm/swapfile.c +++ linux-2.6.28/mm/swapfile.c @@ -286,6 +286,8 @@ swap_list.next = p - swap_info; nr_swap_pages++; p->inuse_pages--; + if (p->notify_swap_entry_free_fn) + p->notify_swap_entry_free_fn(offset); } } return count; @@ -1818,6 +1820,23 @@ } /* + * Sets callback for event when swap_map[offset] == 0 + * i.e. page at this swap offset is not longer used. + * + * type: identifies swap file + * fn: callback function + */ +void set_notify_swap_entry_free(unsigned type, void (*fn) (unsigned long)) +{ + struct swap_info_struct *sis; + sis = get_swap_info_struct(type); + BUG_ON(!sis); + sis->notify_swap_entry_free_fn = fn; + return; +} +EXPORT_SYMBOL(set_notify_swap_entry_free); + +/* * swap_lock prevents swap_map being freed. Don't grab an extra * reference on the swaphandle, it doesn't matter if it becomes unused. */ --- linux-2.6.28.orig/ipc/mqueue.c +++ linux-2.6.28/ipc/mqueue.c @@ -753,7 +753,7 @@ err = mnt_want_write(mqueue_mnt); if (err) goto out_err; - err = vfs_unlink(dentry->d_parent->d_inode, dentry); + err = vfs_unlink(dentry->d_parent->d_inode, dentry, mqueue_mnt); mnt_drop_write(mqueue_mnt); out_err: dput(dentry); --- linux-2.6.28.orig/kernel/cgroup.c +++ linux-2.6.28/kernel/cgroup.c @@ -2964,7 +2964,7 @@ } /* Create the cgroup directory, which also creates the cgroup */ - ret = vfs_mkdir(inode, dentry, S_IFDIR | 0755); + ret = vfs_mkdir(inode, dentry, NULL, S_IFDIR | 0755); child = __d_cgrp(dentry); dput(dentry); if (ret) { --- linux-2.6.28.orig/kernel/sysctl.c +++ linux-2.6.28/kernel/sysctl.c @@ -1528,6 +1528,33 @@ spin_unlock(&sysctl_lock); } +char *sysctl_pathname(struct 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_GPL(sysctl_pathname); + #ifdef CONFIG_SYSCTL_SYSCALL /* Perform the actual read/write of a sysctl table entry. */ static int do_sysctl_strategy(struct ctl_table_root *root, --- linux-2.6.28.orig/kernel/audit.c +++ linux-2.6.28/kernel/audit.c @@ -1243,8 +1243,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; @@ -1518,3 +1517,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-2.6.28.orig/kernel/power/console.c +++ linux-2.6.28/kernel/power/console.c @@ -33,6 +33,7 @@ int pm_prepare_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); if (disable_vt_switch) { @@ -66,11 +67,13 @@ } orig_kmsg = kmsg_redirect; kmsg_redirect = SUSPEND_CONSOLE; +#endif return 0; } void pm_restore_console(void) { +#ifndef CONFIG_PM_DISABLE_CONSOLE acquire_console_sem(); if (disable_vt_switch) { release_console_sem(); @@ -79,5 +82,6 @@ set_console(orig_fgconsole); release_console_sem(); kmsg_redirect = orig_kmsg; +#endif } #endif --- linux-2.6.28.orig/kernel/power/Kconfig +++ linux-2.6.28/kernel/power/Kconfig @@ -116,6 +116,21 @@ Turning OFF this setting is NOT recommended! If in doubt, say Y. +config PM_DISABLE_CONSOLE + bool "Disable Power Management messing with the active console" + depends on PM + default n + ---help--- + By default, 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 HIBERNATION bool "Hibernation (aka 'suspend to disk')" depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE --- linux-2.6.28.orig/debian/control.stub +++ linux-2.6.28/debian/control.stub @@ -0,0 +1,420 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), makedumpfile [!armel] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils +Vcs-Git: http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-jaunty.git + +Package: linux-source-2.6.28 +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.28 with Ubuntu patches + This package provides the source code for the Linux kernel version + 2.6.28. + . + This package is mainly meant for other packages to use, in order to build + custom flavours. + . + 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.28 +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.28 + This package provides the various readme's in the 2.6.28 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.28/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.28-4 +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.28 + This package provides kernel header files for version 2.6.28, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details + +Package: linux-libc-dev +Architecture: i386 amd64 armel +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), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers +Provides: 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. They are NOT meant to be used to build third-party modules for + your kernel. Use linux-headers-* packages for that. + +Package: linux-image-2.6.28-4-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, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 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.28-4-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-iop32x +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IOP32x-based systems + This package contains the Linux kernel image for version 2.6.28 on + IOP32x-based systems. + . + 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 IOP32x processors. + . + Thecus N2100, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-iop32x meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-iop32x +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IOP32x-based systems + This package provides kernel header files for version 2.6.28 on + IOP32x-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-iop32x +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IOP32x-based systems + This package provides a kernel debug image for version 2.6.28 on + IOP32x-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-ixp4xx +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IXP4xx-based systems + This package contains the Linux kernel image for version 2.6.28 on + IXP4xx-based systems. + . + 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 IXP4xx processors. + . + Linksys NSLU2, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-ixp4xx meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IXP4xx-based systems + This package provides kernel header files for version 2.6.28 on + IXP4xx-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IXP4xx-based systems + This package provides a kernel debug image for version 2.6.28 on + IXP4xx-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-orion5x +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Orion5x-based systems + This package contains the Linux kernel image for version 2.6.28 on + Orion5x-based systems. + . + 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 Orion 5181, 5182 and 5281 processors. + . + QNAP TS-109/TS-209, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-orion5x meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-orion5x +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Orion5x-based systems + This package provides kernel header files for version 2.6.28 on + Orion5x-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-orion5x +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Orion5x-based systems + This package provides a kernel debug image for version 2.6.28 on + Orion5x-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, kvm-api-4, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 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.28-4-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-versatile +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Versatile-based systems + This package contains the Linux kernel image for version 2.6.28 on + Versatile-based systems. + . + 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 Versatile processors. + . + PB, AB, Qemu, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-versatile meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-versatile +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Versatile-based systems + This package provides kernel header files for version 2.6.28 on + Versatile-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-versatile +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Versatile-based systems + This package provides a kernel debug image for version 2.6.28 on + Versatile-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-virtual +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1), linux-image-2.6.28-4-server +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 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 Virtual processors. + . + Geared toward virtual machine guests. + . + 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. --- linux-2.6.28.orig/debian/rules +++ linux-2.6.28/debian/rules @@ -0,0 +1,147 @@ +#!/usr/bin/make -f +# +# debian/rules for Ubuntu linux +# +# Use this however you want, just give credit where credit is due. +# +# Copyright (c) 2007 Ben Collins +# + +# dpkg-buildpackage passes options that are incomptatible +# with the kernel build. +unexport CFLAGS +unexport LDFLAGS + +# 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-* + rm -rf debian/linux-* + + # 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 + +# 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/* debian/sub-flavours/*.vars) + 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/$(release)/g' -e 's/ABINUM/$(abinum)/g' > \ + $$new; \ + done + flavours="$(wildcard debian/control.d/vars.* debian/sub-flavours/*.vars)";\ + for i in $$flavours; do \ + $(SHELL) debian/scripts/control-create $$i | \ + sed -e 's/PKGVER/$(release)/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 + + # Some files may need to differ between architectures + if [ -d debian/d-i/modules-$(arch) ]; then \ + cp debian/d-i/modules-$(arch)/* modules/$(arch)/; \ + fi + + # Remove unwanted stuff for this architecture + 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 + + # 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 modules/; tar cf - `cat ../$$flav`) | \ + (cd modules/$(arch)-$$name/; tar xf -); \ + touch modules/$(arch)-$$name/kernel-image; \ + done; \ + fi + + # Some files may need to differ between flavours + flavour_module_dirs=`ls -d debian/d-i/modules-$(arch)-* 2>/dev/null`\ + || true; \ + if [ "$$flavour_module_dirs" ]; then \ + for flav in $$flavour_module_dirs; do \ + name=`echo $$flav | sed 's/.*\/modules-$(arch)-//'`; \ + [ -d modules/$(arch)-$$name ] || \ + cp -a modules/$(arch) modules/$(arch)-$$name; \ + cp $$flav/* modules/$(arch)-$$name/; \ + done; \ + fi + + # Remove unwanted stuff for each flavour + flavour_exclude=`ls debian/d-i/exclude-modules.$(arch)-* 2>/dev/null`\ + || true; \ + if [ "$$flavour_exclude" ]; then \ + for flav in $$flavour_exclude; do \ + name=`echo $$flav | sed 's/.*\/exclude-modules.$(arch)-//'`;\ + [ -d modules/$(arch)-$$name ] || \ + cp -a modules/$(arch) modules/$(arch)-$$name; \ + (cat $$flav; \ + ls modules/$(arch)-$$name) | sort | uniq -d | \ + (cd modules/$(arch)-$$name/; xargs rm -f); \ + done; \ + 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-2.6.28.orig/debian/changelog.historical +++ linux-2.6.28/debian/changelog.historical @@ -0,0 +1,5745 @@ +linux (2.6.24-19.33) UNRELEASED; urgency=low + + CHANGELOG: Do not edit directly. Autogenerated at release. + CHANGELOG: Use the printchanges target to see the curent changes. + CHANGELOG: Use the insertchanges target to create the final log. + + -- Tim Gardner Sun, 04 May 2008 20:22:21 -0600 + +linux (2.6.24-18.32) hardy-security; urgency=low + + * CVE-2007-6694: [POWERPC] CHRP: Fix possible NULL pointer dereference + * fix SMP ordering hole in fcntl_setlk() (CVE-2008-1669) + * Fix dnotify/close race (CVE-2008-1375) + * tehuti: check register size (CVE-2008-1675) + * tehuti: move ioctl perm check closer to function start (CVE-2008-1675) + + -- Ben Collins Mon, 19 May 2008 16:50:11 +0000 + +linux (2.6.24-17.31) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix mutex in the toshiba_acpi driver + * rt: Updated configuration files + + [Ben Collins] + + * build: Fix revert detection in git-ubuntu-log + * SAUCE: Re-add eeprom_bad_csum_allow module-param + - LP: #60388 + + [Stefan Bader] + + * Pulled updates to openvz custom build. Fixes openvz 'refuses to boot' problem. + - LP: #210672 + * sched: retain vruntime, fix delayed key events when CONFIG_FAIR_GROUP_SCHED. + - LP: #218516 + * UBUNTU: SAUCE: Add blacklist support to fix Belkin bluetooth dongle. + - LP: #140511 + + [Tim Gardner] + + * Enable CONFIG_ISCSI_TCP for -virtual + - LP: #218215 + * build: Add fancontrol modules to powerpc64-smp debian installer + * Fix Xen Dom0/DomU bridging + - LP: #218126 + * TSC Clocksource can cause hangs and time jumps + - LP: #221351 + * Kernel should use CONFIG_FAIR_CGROUP_SCHED. Fixes high load issues + with pulseaudio. + - LP: #188226 + + [Upstream Kernel Changes] + + * KVM: MMU: prepopulate guest pages after write-protecting + - LP: #221032 + + -- Tim Gardner Fri, 11 Apr 2008 07:59:10 -0600 + +linux (2.6.24-16.30) hardy; urgency=low + + * Fix amd64/i386 ABI and module check FTBS by creating an ignore + and ignore.modules in the ABI directory. + + -- Tim Gardner Wed, 09 Apr 2008 21:58:25 -0600 + +linux (2.6.24-16.29) hardy; urgency=low + + [Stephan Bader] + + * UBUNTU: SAUCE: mmc: Increase power_up deleay to fix TI readers + + [Alessio Igor Bogani] + + * rt: Updated configuration files + + [Chuck Short] + + * Xen updates for vitrio changes. + + [Tim Gardner] + + * openvz updates for vitrio changes. + + -- Tim Gardner Tue, 08 Apr 2008 21:48:16 -0600 + +linux (2.6.24-16.28) hardy; urgency=low + + [Tim Gardner] + + * Revert "UBUNTU: x86: tsc prevent time going backwards" + + [Kees Cook] + + * AppArmor: implement mmap_min_addr check as done in mainline. + + [Soren Hansen] + + * Bring our virtio code up to date with 2.6.25-rc7 + + [Upstream Kernel Changes] + + * Ubuntu: Revert all our virtio changes + * lguest: Reboot support + * lguest: adapt launcher to per-cpuness + * virtio: Implement skb_partial_csum_set, for setting partial csums on + untrusted packets. + * virtio: simplify config mechanism. + * virtio: explicit enable_cb/disable_cb rather than callback return. + * virtio: configuration change callback + * virtio: Fix vring_init/vring_size to take unsigned long + * virtio: clarify NO_NOTIFY flag usage + * virtio: remove unused id field from struct virtio_blk_outhdr + * virtio: Net header needs hdr_len + * virtio: Tweak virtio_net defines + * virtio: populate network rings in the probe routine, not open + * virtio: reset function + * virtio: handle interrupts after callbacks turned off + * virtio: Use the sg_phys convenience function. + * virtio: Allow virtio to be modular and used by modules + * virtnet: remove double ether_setup + * virtio: flush buffers on open + * virtio: free transmit skbs when notified, not on next xmit. + * virtio_net: parametrize the napi_weight for virtio receive queue. + * virtio_blk: provide getgeo + * virtio_blk: Dont waste major numbers + * virtio_blk: implement naming for vda-vdz,vdaa-vdzz,vdaaa-vdzzz + * virtio: PCI device + * virtio: Use PCI revision field to indicate virtio PCI ABI version + * virtio: balloon driver + * virtio net: fix oops on interface-up + * virtio: add missing #include + * virtio: fix race in enable_cb + * virtio: handle > 2 billion page balloon targets + * virtio_net: Fix oops on early interrupts - introduced by virtio reset + code + * lguest: Do not append space to guests kernel command line + * virtio: Use spin_lock_irqsave/restore for virtio-pci + * virtio: Fix sysfs bits to have proper block symlink + * virtio: Enable netpoll interface for netconsole logging + * virtio_pci: unregister virtio device at device remove + * lguest: Add puppies which where previously missing. + * lguest: lguest.txt documentation fix + * lguest: Don't need comment terminator before disk section. + * virtio_pci iomem annotations + * virtio_net: remove overzealous printk + * virtio: remove overzealous BUG_ON. + + -- Tim Gardner Tue, 08 Apr 2008 11:53:49 -0600 + +linux (2.6.24-15.27) hardy; urgency=low + + [Alan Stern] + + * usb-storage: don't access beyond the end of the sg buffer + - LP: #204922 + + [Mario Limonciello] + + * Enable Reset and SCO workaround on Dell 410 BT adapter + + [Tim Gardner] + + * Enable CONFIG_E1000 in the i386 virtual image. + - LP: #205646 + + [Thomas Gleixner] + + * x86: tsc prevent time going backwards + + [Matthew Garrett] + + * Fix framebuffer fonts on non-x86 platforms + + -- Tim Gardner Fri, 04 Apr 2008 08:14:49 -0600 + +linux (2.6.24-15.26) hardy; urgency=low + + [Colin Ian King] + + * airprime.c supports more devices + - LP: #208250 + + [Kees Cook] + + * AppArmor: get latest batch of upstream fixes into Hardy (svn 1160) + + [Stefan Bader] + + * ACPI: fix boot oops regression in kernel + - LP: #207014 + + [Tim Gardner] + + * Enable CGROUPS for non x86/x86_64 arches, all flavours. + - LP: #188226 + + -- Tim Gardner Thu, 03 Apr 2008 07:00:29 -0600 + +linux (2.6.24-14.25) hardy; urgency=low + + [Mario Limonciello] + + * Resolve sky2 race condition leading to failed suspends + - LP: #210877 + + [Tim Gardner] + + * Copy drivers/media internal header files into header + package for external LUM compilation. This paves the + way for LP #202065. + + -- Tim Gardner Wed, 02 Apr 2008 08:28:32 -0600 + +linux (2.6.24-14.24) hardy; urgency=low + + [Amit Kucheria] + + * LPIA: Update from moblin + * LPIA: Fix reboot problem after S3/S4 + * LPIA: Integrate latest Dabney thermal patches + * LPIA: Change-umd_dbg-debug-level-to-KERN_INFO + * LPIA: Compile modules into kernel to save on boot time + * LPIA: lots of Dabney CONFIG options dissapeared + * LPIA: Purge nonexistent config options + + [Jay Chetty] + + * UBUNTU:USBC:Integrated USBC 2.0.0.32L.0009 + + [Misha Zhilin] + + * USB: ehci: handle large bulk URBs correctly (again) + - LP: #204857 + + [Tim Gardner] + + * frame buffer regression - screen blank except for blinking cursor after + fbcon vtswitch + - LP: #201591 + * Blacklist Bluetooth Dell Wireless 370 for SCO MTU + - LP: #209715 + * Set CONFIG_FAIR_CGROUP_SCHED for server flavours. + - LP: #188226 + * Add DMI IO_DELAY support. + - LP: #200057 + + -- Tim Gardner Mon, 31 Mar 2008 11:19:49 -0600 + +linux (2.6.24-13.23) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Updated configuration files + + [Ben Collins] + + * openvz: New custom flavour for OpenVZ + * config: Disable IDE AMD driver in favor of PATA version + - LP: #181561 + * config: Disable IDE VIA driver in favor of PATA version + - LP: #181561 + * drivers/video: Restore gutsy backlight dimming behavior + - LP: #205261 + * build/config: Enable CONFIG_CIFS_WEAK_PW_HASH + - LP: #202445 + + [Colin Ian King] + + * SAUCE: Add support for version 4 of Chelsio NICs in cxgb3 driver + - LP: #201893 + + [Kees Cook] + + * AppArmor: re-add missing "type" field in syslog reports. + - LP: #202888 + * kvm: reset TSS on x86_64 to avoid ioperm bitmap corruption + - LP: #144900 + + [Stefan Bader] + + * USB: EHCI: add separate IAA watchdog timer + - LP: #198619 + * SAUCE: Always use SCO protocol (disable eSCO support) + - LP: #39414 + * PM: Introduce PM_EVENT_HIBERNATE callback state + - LP: #201086 + + [Tim Gardner] + + * Disable DRM suspend/resume on pre-915 Intel chips + - LP: #207496 + * frame buffer regression - screen blank except for blinking cursor after fbcon + vtswitch + - LP: #201591 + + -- Tim Gardner Wed, 19 Mar 2008 10:05:05 -0400 + +linux (2.6.24-12.22) hardy; urgency=low + + [Ben Collins] + + * custom/rt: Disable toshiba_acpi, since it isn't compatible + + -- Ben Collins Wed, 12 Mar 2008 14:38:59 -0400 + +linux (2.6.24-12.21) hardy; urgency=low + + [Ben Collins] + + * build: Fix vesafb module inclusion into initrd subdir + - LP: #129910 + * net/bluetooth: POWERBOOK => APPLE, fix for apple keyboard patch + * custom/xen: Remove asix portion of xen patch, breaks driver + - LP: #199296 + + [Colin Ian King] + + * SAUCE: fix Udma not fully available in Acer 1694 Wlmi + - LP: #187121 + * SAUCE: Update toshiba_acpi.c to version 0.19a + - LP: #77026 + + [Stefan Bader] + + * x86: Clear DF before calling signal handler + * Enable FN key on Apple aluminum bluetooth keyboard + - LP: #162083 + + -- Ben Collins Tue, 11 Mar 2008 13:20:49 -0400 + +linux (2.6.24-12.20) hardy; urgency=low + + [Ben Collins] + + * Enable CONFIG_SOUND at least, so alsa build in lum works + - LP: #200338 + + -- Ben Collins Mon, 10 Mar 2008 08:15:00 -0400 + +linux (2.6.24-12.19) hardy; urgency=low + + * Re-upload of -12.18 to fix build failures + * Fixup binary-custom configs + * Fixup xen patch to cope with kvm changes + + [Amit Kucheria] + + * Move Marvell 8686 and 8688 to LUM + * Poulsbo: Sync patches with moblin/ume-hardy tree + * Break if a patch fails to apply + * SAUCE: implement smarter atime updates support + - LP: #199427 + * Enable USB_PERSIST to allow devices with /root on usb to work with + suspend + * Enable USB_PERSIST across the board + + [Ben Collins] + + * build/config: Really fix ide on smp ppc configs + * build/configs: Enable relatime config option for all flavors + * build/abi: Ignore ide-core module for ppc, moved to built-in + + [Colin Ian King] + + * fix reversed logic for bbuild check leads to -j1 default + - LP: #197040 + * Enable IDE_PMAC for powerpc-smp + - LP: #196686 + * Disable CONFIG_USB_OHCI_HCD_SSB + - LP: #182716 + * SAUCE: fix arcmsr + archttp64 calls dma_free_coherent() with irqs + disabled - dmesg filled with warnings + - LP: #194207 + + [Jorge Boncompte [DTI2]] + + * Fix Messed multicast lists after dev_mc_sync/unsync + - LP: #193468 + + [Stefan Bader] + + * Add support for Apple Aluminium keyboards. + - LP: #162083 + * SAUCE: Restore VT fonts on switch + + [Upstream Kernel Changes] + + * [NET]: Messed multicast lists after dev_mc_sync/unsync + * KVM: x86 emulator: add support for group decoding + * KVM: x86 emulator: group decoding for group 1A + * KVM: x86 emulator: Group decoding for group 3 + * KVM: x86 emulator: Group decoding for groups 4 and 5 + * KVM: x86 emulator: add group 7 decoding + * KVM: constify function pointer tables + * KVM: Only x86 has pio + * KVM: x86 emulator: group decoding for group 1 instructions + * KVM: MMU: Decouple mmio from shadow page tables + * KVM: Limit vcpu mmap size to one page on non-x86 + * KVM: VMX: Enable Virtual Processor Identification (VPID) + * KVM: Use CONFIG_PREEMPT_NOTIFIERS around struct preempt_notifier + * KVM: Disable pagefaults during copy_from_user_inatomic() + * KVM: make EFER_RESERVED_BITS configurable for architecture code + * KVM: align valid EFER bits with the features of the host system + * KVM: allow access to EFER in 32bit KVM + * kvm: i386 fix + * KVM: export information about NPT to generic x86 code + * KVM: MMU: make the __nonpaging_map function generic + * KVM: export the load_pdptrs() function to modules + * KVM: MMU: add TDP support to the KVM MMU + * KVM: x86 emulator: Fix 'jmp abs' + * KVM: x86 emulator: fix group 5 decoding + * KVM: Fix kvm_arch_vcpu_ioctl_set_sregs so that set_cr0 works properly + * KVM: Make the supported cpuid list a host property rather than a vm + property + * KVM: emulate access to MSR_IA32_MCG_CTL + * KVM: remove the usage of the mmap_sem for the protection of the memory + slots. + * KVM: SVM: allocate the MSR permission map per VCPU + * KVM: make MMU_DEBUG compile again + * KVM: paravirtualized clocksource: host part + * KVM: Add missing semicolon + * KVM: x86 emulator: add ad_mask static inline + * KVM: x86 emulator: make register_address, address_mask static inlines + * KVM: x86 emulator: make register_address_increment and JMP_REL static + inlines + * KVM: Add API to retrieve the number of supported vcpus per vm + * KVM: Increase vcpu count to 16 + * KVM: Add API for determining the number of supported memory slots + * KVM: Increase the number of user memory slots per vm + * KVM: Add stat counter for hypercalls + * KVM: x86 emulator: fix sparse warnings in x86_emulate.c + * KVM: sparse fixes for kvm/x86.c + * KVM: Implement dummy values for MSR_PERF_STATUS + * KVM: MMU: ignore zapped root pagetables + * KVM: call write_guest_time as soon as we register the paravirt clock + * KVM: MMU: large page support + * KVM: Prefix control register accessors with kvm_ to avoid namespace + pollution + * KVM: Avoid infinite-frequency local apic timer + * KVM: Route irq 0 to vcpu 0 exclusively + * KVM: SVM: add support for Nested Paging + * KVM: SVM: enable LBR virtualization + * KVM: SVM: make iopm_base static + * KVM: SVM: let init_vmcb() take struct vcpu_svm as parameter + * KVM: VMX: fix typo in VMX header define + * KVM: SVM: fix Windows XP 64 bit installation crash + * KVM: VMX: Fix invalid opcode of VPID + * KVM: VMX: Handle machines without EFER + * KVM: move alloc_apic_access_page() outside of non-preemptable region + * KVM: VMX: unifdef the EFER specific code + * KVM: SVM: move feature detection to hardware setup code + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * dlm: fix rcom_names message to self + * virtio: Net header needs hdr_len + + -- Tim Gardner Mon, 03 Mar 2008 07:07:16 -0700 + +linux (2.6.24-11.17) hardy; urgency=low + + [Alan Cox] + + * Pull in fixes for pata_it821x. + - LP: #106931 + + [Alessio Igor Bogani] + + * rt: Synchronized with upstream (2.6.24.3-rt3) + * rt: Updated configuration files + + [Amit Kucheria] + + * Add AGP support for Radeon Mobility 9000 chipset + - LP: #178634 + * Bluetooth: SCO flow control to enable bluetooth headsets + + [Ben Collins] + + * binary: Include vesafs in initrd subdir, should fix vga= usage + + [Colin Ian King] + + * AMD SB700 south bridge support patches + - LP: #195354 + * BCM4311 Revision 2 fix + - LP: #184600 + + [Mauro Carvalho Chehab] + + * V4L/DVB (6753): Fix vivi to support non-zero minor node + + [Tim Gardner] + + * Merged 2.6.24.3 + * Add atl1 to d-i bits. + - LP: #159561 + * SAUCE: Add xpad support for RedOctane Guitar Hero + - LP: #196745 + + [Upstream Kernel Changes] + + * DVB: cx23885: add missing subsystem ID for Hauppauge HVR1800 Retail + * slab: fix bootstrap on memoryless node + * vm audit: add VM_DONTEXPAND to mmap for drivers that need it + (CVE-2008-0007) + * USB: keyspan: Fix oops + * usb gadget: fix fsl_usb2_udc potential OOPS + * USB: CP2101 New Device IDs + * USB: add support for 4348:5523 WinChipHead USB->RS 232 adapter + * USB: Sierra - Add support for Aircard 881U + * USB: Adding YC Cable USB Serial device to pl2303 + * USB: sierra driver - add devices + * USB: ftdi_sio - enabling multiple ELV devices, adding EM1010PC + * USB: ftdi-sio: Patch to add vendor/device id for ATK_16IC CCD + * USB: sierra: add support for Onda H600/Zte MF330 datacard to USB Driver + for Sierra Wireless + * USB: remove duplicate entry in Option driver and Pl2303 driver for + Huawei modem + * USB: pl2303: add support for RATOC REX-USB60F + * USB: ftdi driver - add support for optical probe device + * USB: use GFP_NOIO in reset path + * USB: Variant of the Dell Wireless 5520 driver + * USB: storage: Add unusual_dev for HP r707 + * USB: fix usbtest halt check on big endian systems + * USB: handle idVendor of 0x0000 + * USB: Fix usb_serial_driver structure for Kobil cardreader driver. + * forcedeth: mac address mcp77/79 + * lockdep: annotate epoll + * sys_remap_file_pages: fix ->vm_file accounting + * PCI: Fix fakephp deadlock + * ACPI: update ACPI blacklist + * x86: restore correct module name for apm + * sky2: restore multicast addresses after recovery + * sky2: fix for WOL on some devices + * b43: Fix suspend/resume + * b43: Drop packets we are not able to encrypt + * b43: Fix dma-slot resource leakage + * b43legacy: fix PIO crash + * b43legacy: fix suspend/resume + * b43legacy: drop packets we are not able to encrypt + * b43legacy: fix DMA slot resource leakage + * selinux: fix labeling of /proc/net inodes + * b43: Reject new firmware early + * sched: let +nice tasks have smaller impact + * sched: fix high wake up latencies with FAIR_USER_SCHED + * fix writev regression: pan hanging unkillable and un-straceable + * Driver core: Revert "Fix Firmware class name collision" + * drm: the drm really should call pci_set_master.. + * splice: missing user pointer access verification (CVE-2008-0009/10) + * Linux 2.6.24.1 + * splice: fix user pointer access in get_iovec_page_array() + * Linux 2.6.24.2 + * ACPI: video: Rationalise ACPI backlight implementation + * ACPI: video: Ignore ACPI video devices that aren't present in hardware + * SPARC/SPARC64: Fix usage of .section .sched.text in assembler code. + * NETFILTER: nf_conntrack_tcp: conntrack reopening fix + * NFS: Fix a potential file corruption issue when writing + * inotify: fix check for one-shot watches before destroying them + * hugetlb: add locking for overcommit sysctl + * XFS: Fix oops in xfs_file_readdir() + * Fix dl2k constants + * SCSI: sd: handle bad lba in sense information + * TCP: Fix a bug in strategy_allowed_congestion_control + * TC: oops in em_meta + * SELinux: Fix double free in selinux_netlbl_sock_setsid() + * PKT_SCHED: ematch: oops from uninitialized variable (resend) + * NET: Add if_addrlabel.h to sanitized headers. + * IPV4: fib_trie: apply fixes from fib_hash + * IPV4: fib: fix route replacement, fib_info is shared + * IPCOMP: Fix reception of incompressible packets + * IPCOMP: Fetch nexthdr before ipch is destroyed + * INET_DIAG: Fix inet_diag_lock_handler error path. + * INET: Prevent out-of-sync truesize on ip_fragment slow path + * BLUETOOTH: Add conn add/del workqueues to avoid connection fail. + * AUDIT: Increase skb->truesize in audit_expand + * Be more robust about bad arguments in get_user_pages() + * Disable G5 NAP mode during SMU commands on U3 + * hrtimer: fix *rmtp handling in hrtimer_nanosleep() + * hrtimer: fix *rmtp/restarts handling in compat_sys_nanosleep() + * SLUB: Deal with annoying gcc warning on kfree() + * hrtimer: check relative timeouts for overflow + * hrtimer: catch expired CLOCK_REALTIME timers early + * genirq: do not leave interupts enabled on free_irq + * S390: Fix futex_atomic_cmpxchg_std inline assembly. + * USB: fix pm counter leak in usblp + * SCSI: gdth: scan for scsi devices + * PCMCIA: Fix station address detection in smc + * POWERPC: Revert chrp_pci_fixup_vt8231_ata devinit to fix libata on + pegasos + * bonding: fix NULL pointer deref in startup processing + * x86_64: CPA, fix cache attribute inconsistency bug + * Linux 2.6.24.3 + + -- Tim Gardner Mon, 25 Feb 2008 12:28:13 -0700 + +linux (2.6.24-10.16) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Synchronized with upstream (2.6.24.2-rt2) + * rt: Updated configuration files + + [Eric Piel] + + * SAUCE: ACPI: Allow custom DSDT tables to be loaded from initramfs + Amit Kucheria consolidated the DSDT patch with another fix that + ifdefs symbols required when BLK_DEV_INITR is disabled. + + [Stefan Bader] + + * Add Optiarc DVD drive to audio quirks list. + - LP: #186664 + * Update drm and i915 drm driver to fix suspend issues. + - LP: #189260 + + [Tim Gardner] + + * Fix FTBS without BLK_DEV_INITRD + - LP: #193507 + * 64 bit CPA cache attribute bug + - LP: #193736 + * Implemented default EDD control + + [Upstream Kernel Changes] + + * bonding: fix NULL pointer deref in startup processing + * dlm: bind connections from known local address when using TCP + * dlm: proper prototypes + * dlm: don't print common non-errors + * dlm: use dlm prefix on alloc and free functions + * dlm: close othercons + * dlm: align midcomms message buffer + * dlm: swap bytes for rcom lock reply + * dlm: use fixed errno values in messages + * dlm: clear ast_type when removing from astqueue + * dlm: recover locks waiting for overlap replies + * dlm: another call to confirm_master in receive_request_reply + * dlm: reject messages from non-members + * dlm: validate messages before processing + * dlm: reject normal unlock when lock is waiting for lookup + * dlm: limit dir lookup loop + * dlm: fix possible use-after-free + * dlm: change error message to debug + * dlm: keep cached master rsbs during recovery + * dlm: Sanity check namelen before copying it + * dlm: clean ups + * dlm: static initialization improvements + * dlm: use proper C for dlm/requestqueue stuff (and fix alignment bug) + * dlm: dlm_process_incoming_buffer() fixes + * dlm: do not byteswap rcom_lock + * dlm: do not byteswap rcom_config + * dlm: use proper type for ->ls_recover_buf + * dlm: missing length check in check_config() + * dlm: validate data in dlm_recover_directory() + * dlm: verify that places expecting rcom_lock have packet long enough + * dlm: receive_rcom_lock_args() overflow check + * dlm: make find_rsb() fail gracefully when namelen is too large + * dlm: fix overflows when copying from ->m_extra to lvb + * dlm: fix dlm_dir_lookup() handling of too long names + * dlm: dlm/user.c input validation fixes + * dlm: proper types for asts and basts + * dlm: eliminate astparam type casting + * dlm: add __init and __exit marks to init and exit functions + * virtio: Use PCI revision field to indicate virtio PCI ABI version + + -- Tim Gardner Tue, 19 Feb 2008 09:57:18 -0700 + +linux (2.6.24-9.15) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix FTBS + * rt: Updated configuration files + + [Tim Gardner] + + * SAUCE: make /dev/kmem a config option + * SAUCE: x86: introduce /dev/mem restrictions with a config option + * Fixed CGROUP FTBS caused by AppArmor patch. + * Enabled CGROUP and CPUSETS for server flavor. + - LP: #182434 + + [Colin King] + + * Turn on /proc/acpi/alarm for x86_64 (amd64) + - LP: #186297 + + [Upstream Kernel Changes] + + * Ubuntu: LatencyTOP infrastructure patch + + -- Tim Gardner Thu, 14 Feb 2008 13:34:55 -0700 + +linux (2.6.24-8.14) hardy; urgency=low + + [cking] + + * Support Novatel U727 EVDO modem: Add pid and vid to + drivers/usb/serial/airprime.c + - LP: #150996 + * Enable speedstep for sonoma processors. + - LP: #132271 + + [Stefan Bader] + + * SAUCE: Export dm_disk function of device-mapper + + -- Tim Gardner Wed, 13 Feb 2008 21:47:18 -0700 + +linux (2.6.24-8.13) hardy; urgency=low + + [Soren Hansen] + + * Add missing iscsi modules to kernel udebs + + [Stefan Bader] + + * Lower message level for PCI memory and I/O allocation. + + [Tim Gardner] + + * Enabled IP_ADVANCED_ROUTER and IP_MULTIPLE_TABLES in sparc, hppa + - LP: #189560 + * Compile RealTek 8139 using PIO method. + - LP: #90271 + * Add WD WD800ADFS NCQ horkage quirk support. + - LP: #147858 + + [Upstream Kernel Changes] + + * Introduce WEXT scan capabilities + * DVB: cx23885: add missing subsystem ID for Hauppauge HVR1800 Retail + * slab: fix bootstrap on memoryless node + * vm audit: add VM_DONTEXPAND to mmap for drivers that need it + (CVE-2008-0007) + * USB: keyspan: Fix oops + * usb gadget: fix fsl_usb2_udc potential OOPS + * USB: CP2101 New Device IDs + * USB: add support for 4348:5523 WinChipHead USB->RS 232 adapter + * USB: Sierra - Add support for Aircard 881U + * USB: Adding YC Cable USB Serial device to pl2303 + * USB: sierra driver - add devices + * USB: ftdi_sio - enabling multiple ELV devices, adding EM1010PC + * USB: ftdi-sio: Patch to add vendor/device id for ATK_16IC CCD + * USB: sierra: add support for Onda H600/Zte MF330 datacard to USB Driver + for Sierra Wireless + * USB: remove duplicate entry in Option driver and Pl2303 driver for + Huawei modem + * USB: pl2303: add support for RATOC REX-USB60F + * USB: ftdi driver - add support for optical probe device + * USB: use GFP_NOIO in reset path + * USB: Variant of the Dell Wireless 5520 driver + * USB: storage: Add unusual_dev for HP r707 + * USB: fix usbtest halt check on big endian systems + * USB: handle idVendor of 0x0000 + * forcedeth: mac address mcp77/79 + * lockdep: annotate epoll + * sys_remap_file_pages: fix ->vm_file accounting + * PCI: Fix fakephp deadlock + * ACPI: update ACPI blacklist + * x86: restore correct module name for apm + * sky2: restore multicast addresses after recovery + * sky2: fix for WOL on some devices + * b43: Fix suspend/resume + * b43: Drop packets we are not able to encrypt + * b43: Fix dma-slot resource leakage + * b43legacy: fix PIO crash + * b43legacy: fix suspend/resume + * b43legacy: drop packets we are not able to encrypt + * b43legacy: fix DMA slot resource leakage + * selinux: fix labeling of /proc/net inodes + * b43: Reject new firmware early + * sched: let +nice tasks have smaller impact + * sched: fix high wake up latencies with FAIR_USER_SCHED + * fix writev regression: pan hanging unkillable and un-straceable + * Driver core: Revert "Fix Firmware class name collision" + * drm: the drm really should call pci_set_master.. + * splice: missing user pointer access verification (CVE-2008-0009/10) + * Linux 2.6.24.1 + * splice: fix user pointer access in get_iovec_page_array() + * Linux 2.6.24.2 + + -- Tim Gardner Thu, 07 Feb 2008 06:50:13 -0700 + +linux (2.6.24-7.12) hardy; urgency=low + + [Jay Chetty] + + * Added patch to fix legacy USB interrupt issue + * Enabled Poulsbo PATA udma5 support + * Add touchscreen doubleclick workaround + + [Amit Kucheria] + + * Add AGP support for Radeon Mobility 9000 chipset + - LP: #178634 + + [Soren Hansen] + + * Add virtio modules to the relevant udebs + * Add missing "?" for virtio modules in storage-core-modules + + [Stefan Bader] + + * Added vendor id for Dell 5720 broadband modem + + -- Jay Chetty Wed, 06 Feb 2008 14:13:41 -0800 + +linux (2.6.24-7.11) hardy; urgency=low + + [Jay Chetty] + + * poulsbo: Add a 100ms delay for SiB workaround + + [Tim Gardner] + + * -6.10 should have been an ABI bump, but due to incomplete build testing + went undetected. + + -- Tim Gardner Mon, 04 Feb 2008 19:13:52 -0700 + +linux (2.6.24-6.10) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Synced with upstream, removed old kvm related patches and updated + configurations files. + + [Chuck Short] + + * SAUCE: Enable Xen + + [Soren Hansen] + + * Update kvm driver to kvm-60. + * Added CONFIG_ARCH_SUPPORTS_KVM=y for lpia, i386, and amd64 + * Add rtl8139 driver to -virtual flavour + + [Stefan Bader] + + * Fix usb_serial_driver structure for Kobil cardreader driver. + - LP: #183109 + * Lower warning level of pci resource allocation messages. + - LP: #159241 + + [Tim Gardner] + + * Enabled CONFIG_BLK_DEV_IDE_PMAC + - LP: #185862 + * Add virtio config options to lpiacompat. + * SAUCE: Export symbols for aufs (in lum). + * Enabled Xen + + [Upstream Kernel Changes] + + * KVM: mmu: add missing dirty page tracking cases + * KVM: Move virtualization deactivation from CPU_DEAD state to + CPU_DOWN_PREPARE + * KVM: Cosmetics + * KVM: vmx: hack set_cr0_no_modeswitch() to actually do modeswitch + * KVM: Use ARRAY_SIZE macro instead of manual calculation. + * KVM: Use page_private()/set_page_private() apis + * KVM: add MSR based hypercall API + * KVM: Add host hypercall support for vmx + * KVM: Add hypercall host support for svm + * KVM: Wire up hypercall handlers to a central arch-independent location + * KVM: svm: init cr0 with the wp bit set + * KVM: SVM: intercept SMI to handle it at host level + * KVM: More 0 -> NULL conversions + * kvm, dirty pages log: adding some calls to mark_page_dirty() + * KVM: Add internal filesystem for generating inodes + * KVM: Create an inode per virtual machine + * KVM: Rename some kvm_dev_ioctl_*() functions to kvm_vm_ioctl_*() + * KVM: Move kvm_vm_ioctl_create_vcpu() around + * KVM: Per-vcpu inodes + * KVM: Bump API version + * .gitignore: ignore emacs backup files (*~) + * kvm: dirty pages log: fix bitmap size/access calculation + * kvm: move do_remove_write_access() up + * kvm: dirty page logging: remove write access permissions when + dirty-page-logging is enabled + * KVM: Add missing calls to mark_page_dirty() + * KVM: Fix dirty page log bitmap size/access calculation + * kvm: move do_remove_write_access() up + * KVM: Remove write access permissions when dirty-page-logging is enabled + * KVM: Fix bogus failure in kvm.ko module initialization + * KVM: Move kvmfs magic number to + * KVM: Unset kvm_arch_ops if arch module loading failed + * KVM: Fix guest register corruption on paravirt hypercall + * KVM: Use the generic skip_emulated_instruction() in hypercall code + * KVM: Use own minor number + * KVM: Fix guest sysenter on vmx + * KVM: Export + * KVM: Fix bogus sign extension in mmu mapping audit + * KVM: MMU: Fix guest writes to nonpae pde + * KVM: MMU: Fix host memory corruption on i386 with >= 4GB ram + * KVM: trivial whitespace fixes + * KVM: always reload segment selectors + * KVM: Remove extraneous guest entry on mmio read + * added KVM_GET_MEM_MAP ioctl to get the memory bitmap for a memory slot + * KVM: Prevent system selectors leaking into guest on real->protected + mode transition on vmx + * KVM: Use a shared page for kernel/user communication when runing a vcpu + * KVM: Do not communicate to userspace through cpu registers during PIO + * KVM: Initialize PIO I/O count + * KVM: Handle cpuid in the kernel instead of punting to userspace + * KVM: Remove the 'emulated' field from the userspace interface + * KVM: Remove minor wart from KVM_CREATE_VCPU ioctl + * KVM: Renumber ioctls + * KVM: Add method to check for backwards-compatible API extensions + * KVM: Allow userspace to process hypercalls which have no kernel handler + * KVM: Fold kvm_run::exit_type into kvm_run::exit_reason + * KVM: Add a special exit reason when exiting due to an interrupt + * KVM: Initialize the apic_base msr on svm too + * KVM: Add guest mode signal mask + * KVM: Allow kernel to select size of mmap() buffer + * KVM: Future-proof argument-less ioctls + * KVM: Avoid guest virtual addresses in string pio userspace interface + * KVM: MMU: Remove unnecessary check for pdptr access + * KVM: MMU: Remove global pte tracking + * KVM: Workaround vmx inability to virtualize the reset state + * KVM: Remove set_cr0_no_modeswitch() arch op + * KVM: Modify guest segments after potentially switching modes + * KVM: Hack real-mode segments on vmx from KVM_SET_SREGS + * KVM: Don't allow the guest to turn off the cpu cache + * KVM: Remove unused and write-only variables + * KVM: Handle writes to MCG_STATUS msr + * KVM: MMU: Fix hugepage pdes mapping same physical address with + different access + * KVM: SVM: Ensure timestamp counter monotonicity + * KVM: Remove unused function + * KVM: Remove debug message + * KVM: x86 emulator: fix bit string operations operand size + * KVM: SVM: enable LBRV virtualization if available + * Add mmu cache clear function + * KVM: Simply gfn_to_page() + * KVM: Add physical memory aliasing feature + * KVM: Add fpu get/set operations + * KVM: Use kernel-standard types + * KVM: Fix overflow bug in overflow detection code + * KVM: Fix memory leak on pio completion + * KVM: Handle partial pae pdptr + * KVM: Fix string pio when count == 0 + * KVM: Use slab caches to allocate mmu data structures + * KVM: Retry sleeping allocation if atomic allocation fails + * KVM: Fix pio completion + * KVM: SVM: Report hardware exit reason to userspace instead of dmesg + * KVM: Handle guest page faults when emulating mmio + * KVM: VMX: Reduce unnecessary saving of host msrs + * KVM: Fix off-by-one when writing to a nonpae guest pde + * KVM: VMX: Don't switch 64-bit msrs for 32-bit guests + * KVM: Fold drivers/kvm/kvm_vmx.h into drivers/kvm/vmx.c + * KVM: VMX: Only save/restore MSR_K6_STAR if necessary + * KVM: Per-vcpu statistics + * KVM: Silence compile warning on i386 + * KVM: Allow passing 64-bit values to the emulated read/write API + * KVM: Lazy FPU support for SVM + * KVM: Fix msr-avoidance regression on Core processors + * KVM: Don't complain about cpu erratum AA15 + * KVM: Document MSR_K6_STAR's special place in the msr index array + * KVM: MMU: Avoid heavy ASSERT at non debug mode. + * KVM: Initialize cr0 to indicate an fpu is present + * KVM: We want asserts on debug builds, not release + * KVM: Avoid unused function warning due to assertion removal + * KVM: VMX: Avoid unnecessary vcpu_load()/vcpu_put() cycles + * KVM: Move need_resched() check to common code + * KVM: VMX: Properly shadow the CR0 register in the vcpu struct + * KVM: VMX: Add lazy FPU support for VT + * KVM: fix an if() condition + * KVM: SVM: Only save/restore MSRs when needed + * KVM: Remove trailing whitespace + * KVM: Remove extraneous guest entry on mmio read + * KVM: Don't require explicit indication of completion of mmio or pio + * KVM: Remove unused 'instruction_length' + * KVM: VMX: Enable io bitmaps to avoid IO port 0x80 VMEXITs + * KVM: SVM: Allow direct guest access to PC debug port + * KVM: Fix RMW mmio handling + * KVM: Assume that writes smaller than 4 bytes are to non-pagetable pages + * KVM: Avoid saving and restoring some host CPU state on lightweight + vmexit + * KVM: Unindent some code + * KVM: Reduce misfirings of the fork detector + * KVM: Be more careful restoring fs on lightweight vmexit + * KVM: Unify kvm_mmu_pre_write() and kvm_mmu_post_write() + * KVM: MMU: Respect nonpae pagetable quadrant when zapping ptes + * KVM: Update shadow pte on write to guest pte + * KVM: Increase mmu shadow cache to 1024 pages + * KVM: Fix potential guest state leak into host + * KVM: Prevent guest fpu state from leaking into the host + * KVM: Move some more msr mangling into vmx_save_host_state() + * KVM: Rationalize exception bitmap usage + * KVM: Consolidate guest fpu activation and deactivation + * KVM: Ensure host cr0.ts is saved + * KVM: Set cr0.mp for guests + * KVM: Implement IA32_EBL_CR_POWERON msr + * KVM: MMU: Simplify kvm_mmu_free_page() a tiny bit + * KVM: MMU: Store shadow page tables as kernel virtual addresses, not + physical + * KVM: VMX: Only reload guest msrs if they are already loaded + * KVM: Avoid corrupting tr in real mode + * KVM: Fix vmx I/O bitmap initialization on highmem systems + * KVM: Remove merge artifact + * KVM: VMX: Use local labels in inline assembly + * KVM: VMX: Handle #SS faults from real mode + * KVM: VMX: Avoid saving and restoring msrs on lightweight vmexit + * KVM: VMX: Compile-fix for 32-bit hosts + * KVM: VMX: Cleanup redundant code in MSR set + * KVM: VMX: Fix a typo which mixes X86_64 and CONFIG_X86_64 + * KVM: VMX: Avoid saving and restoring msr_efer on lightweight vmexit + * KVM: VMX: Remove warnings on i386 + * Use menuconfig objects II - KVM/Virt + * KVM: x86 emulator: implement wbinvd + * KVM: Fix includes + * KVM: Use symbolic constants instead of magic numbers + * KVM: MMU: Use slab caches for shadow pages and their headers + * KVM: MMU: Simplify fetch() a little bit + * KVM: MMU: Move set_pte_common() to pte width dependent code + * KVM: MMU: Pass the guest pde to set_pte_common + * KVM: MMU: Fold fix_read_pf() into set_pte_common() + * KVM: MMU: Fold fix_write_pf() into set_pte_common() + * KVM: Move shadow pte modifications from set_pte/set_pde to + set_pde_common() + * KVM: Make shadow pte updates atomic + * KVM: MMU: Make setting shadow ptes atomic on i386 + * KVM: MMU: Remove cr0.wp tricks + * KVM: MMU: Simpify accessed/dirty/present/nx bit handling + * KVM: MMU: Don't cache guest access bits in the shadow page table + * KVM: MMU: Remove unused large page marker + * KVM: VMX: Fix asm constraint + * KVM: Lazy guest cr3 switching + * KVM: Replace C code with call to ARRAY_SIZE() macro. + * KVM: Remove unnecessary initialization and checks in mark_page_dirty() + * KVM: Fix vcpu freeing for guest smp + * KVM: Fix adding an smp virtual machine to the vm list + * KVM: Enable guest smp + * KVM: Move duplicate halt handling code into kvm_main.c + * KVM: Emulate hlt on real mode for Intel + * KVM: Keep an upper bound of initialized vcpus + * KVM: Flush remote tlbs when reducing shadow pte permissions + * KVM: SVM: Replace memset(, 0, PAGESIZE) with clear_page() + * KVM: VMX: Replace memset(, 0, PAGESIZE) with clear_page() + * KVM: Require a cpu which can set 64-bit values atomically + * KVM: Initialize the BSP bit in the APIC_BASE msr correctly + * KVM: VMX: Ensure vcpu time stamp counter is monotonous + * KVM: Bring local tree in line with origin + * KVM: Implement emulation of "pop reg" instruction (opcode 0x58-0x5f) + * KVM: Implement emulation of instruction "ret" (opcode 0xc3) + * KVM: Adds support for in-kernel mmio handlers + * KVM: VMX: Fix interrupt checking on lightweight exit + * KVM: Add support for in-kernel pio handlers + * KVM: Fix x86 emulator writeback + * KVM: Avoid useless memory write when possible + * KVM: VMX: Reinitialize the real-mode tss when entering real mode + * KVM: MMU: Fix Wrong tlb flush order + * KVM: VMX: Remove unnecessary code in vmx_tlb_flush() + * KVM: SVM: Reliably detect if SVM was disabled by BIOS + * KVM: Remove kvmfs in favor of the anonymous inodes source + * KVM: Clean up #includes + * KVM: Fix svm availability check miscompile on i386 + * HOTPLUG: Add CPU_DYING notifier + * HOTPLUG: Adapt cpuset hotplug callback to CPU_DYING + * HOTPLUG: Adapt thermal throttle to CPU_DYING + * SMP: Implement on_cpu() + * KVM: Keep track of which cpus have virtualization enabled + * KVM: Tune hotplug/suspend IPIs + * KVM: Use CPU_DYING for disabling virtualization + * KVM: MMU: Store nx bit for large page shadows + * KVM: Fix *nopage() in kvm_main.c + * KVM: SMP: Add vcpu_id field in struct vcpu + * KVM - add hypercall nr to kvm_run + * KVM:: Future-proof the exit information union ABI + * KVM: In-kernel string pio write support + * KVM: Fix memory slot management functions for guest smp + * KVM: x86 emulator: implement rdmsr and wrmsr + * KVM: Trivial: /dev/kvm interface is no longer experimental. + * KVM: Trivial: Remove unused struct cpu_user_regs declaration + * KVM: Trivial: Make decode_register() static + * KVM: Trivial: Comment spelling may escape grep + * KVM: Trivial: Avoid hardware_disable predeclaration + * KVM: Trivial: Use standard CR0 flags macros from asm/cpu-features.h + * Use standard CR3 flags, tighten checking + * Use standard CR4 flags, tighten checking + * KVM: Trivial: Use standard BITMAP macros, open-code userspace-exposed + header + * KVM: Set exit_reason to KVM_EXIT_MMIO where run->mmio is initialized. + * KVM: Use standard CR8 flags, and fix TPR definition + * KVM: MMU: Fix oopses with SLUB + * KVM: x86 emulator: fix cmov for writeback changes + * KVM: MMU: Fix cleaning up the shadow page allocation cache + * KVM: Require CONFIG_ANON_INODES + * KVM: x86 emulator: fix faulty check for two-byte opcode + * KVM: Correctly handle writes crossing a page boundary + * KVM: Fix unlikely kvm_create vs decache_vcpus_on_cpu race + * KVM: Hoist kvm_mmu_reload() out of the critical section + * KVM: Fix removal of nx capability from guest cpuid + * KVM: Move gfn_to_page out of kmap/unmap pairs + * KVM: disable writeback for 0x0f 0x01 instructions. + * KVM: VMX: Import some constants of vmcs from IA32 SDM + * KVM: Remove dead code in the cmpxchg instruction emulation + * KVM: load_pdptrs() cleanups + * KVM: Remove arch specific components from the general code + * KVM: Dynamically allocate vcpus + * KVM: VMX: Improve the method of writing vmcs control + * KVM: Use the scheduler preemption notifiers to make kvm preemptible + * KVM: Convert vm lock to a mutex + * KVM: fx_init() needs preemption disabled while it plays with the FPU + state + * KVM: VMX: pass vcpu_vmx internally + * KVM: Remove three magic numbers + * KVM: SVM: de-containization + * KVM: SVM: internal function name cleanup + * KVM: x86 emulator: disable writeback for debug register instructions + * KVM: Change the emulator_{read,write,cmpxchg}_* functions to take a + vcpu + * KVM: Remove kvm_{read,write}_guest() + * KVM: Use kmem cache for allocating vcpus + * KVM: Use alignment properties of vcpu to simplify FPU ops + * KVM: kvm_vm_ioctl_get_dirty_log restore "nothing dirty" optimization + * KVM: VMX: Add cpu consistency check + * KVM: Don't assign vcpu->cr3 if it's invalid: check first, set last + * KVM: Cleanup mark_page_dirty + * KVM: SVM: Make set_msr_interception more reliable + * KVM: Remove redundant alloc_vmcs_cpu declaration + * KVM: Fix defined but not used warning in drivers/kvm/vmx.c + * KVM: Remove stat_set from debugfs + * KVM: Remove unneeded kvm_dev_open and kvm_dev_release functions. + * KVM: Add and use pr_unimpl for standard formatting of unimplemented + features + * KVM: Use kmem_cache_free for kmem_cache_zalloc'ed objects + * KVM: VMX: Remove a duplicated ia32e mode vm entry control + * KVM: Remove useless assignment + * KVM: Cleanup string I/O instruction emulation + * KVM: Clean up kvm_setup_pio() + * KVM: VMX: Don't require cr8 load/store exit capability when running on + 32-bit + * KVM: Close minor race in signal handling + * KVM: Communicate cr8 changes to userspace + * KVM: x86 emulator: implement 'and $imm, %{al|ax|eax}' + * KVM: x86 emulator: implement 'jmp rel' instruction (opcode 0xe9) + * KVM: x86 emulator: Implement 'jmp rel short' instruction (opcode 0xeb) + * KVM: x86 emulator: implement 'push reg' (opcodes 0x50-0x57) + * KVM: VMX: allow rmode_tss_base() to work with >2G of guest memory + * KVM: Avoid calling smp_call_function_single() with interrupts disabled + * KVM: MMU: Fix rare oops on guest context switch + * KVM: Support more memory slots + * KVM: X86 emulator: fix 'push reg' writeback + * KVM: VMX: Split segments reload in vmx_load_host_state() + * KVM: Add support for in-kernel PIC emulation + * KVM: Define and use cr8 access functions + * KVM: Emulate local APIC in kernel + * KVM: In-kernel I/O APIC model + * KVM: Emulate hlt in the kernel + * KVM: Protect in-kernel pio using kvm->lock + * KVM: Add get/set irqchip ioctls for in-kernel PIC live migration + support + * KVM: Bypass irq_pending get/set when using in kernel irqchip + * KVM: in-kernel IOAPIC save and restore support + * KVM: in-kernel LAPIC save and restore support + * KVM: pending irq save/restore + * KVM: VMX: Use shadow TPR/cr8 for 64-bits guests + * KVM: Keep track of missed timer irq injections + * KVM: Migrate lapic hrtimer when vcpu moves to another cpu + * KVM: disable tpr/cr8 sync when in-kernel APIC is used + * KVM: VMX: Fix tpr threshold updating + * KVM: deliver PIC interrupt only to vcpu0 + * KVM: round robin for APIC lowest priority delivery mode + * KVM: enable in-kernel APIC INIT/SIPI handling + * KVM: Set the ET flag in CR0 after initializing FX + * KVM: Remove the unused invlpg member of struct kvm_arch_ops. + * KVM: Clean up unloved invlpg emulation + * KVM: Keep control regs in sync + * KVM: Hoist SVM's get_cs_db_l_bits into core code. + * KVM: Simplify memory allocation + * KVM: Rename kvm_arch_ops to kvm_x86_ops + * KVM: Fix lapic 64-bit division on 32-bit hosts + * KVM: fix apic timer migration when inactive + * KVM: MMU: Don't do GFP_NOWAIT allocations + * KVM: Remove smp_processor_id() in kvm_vcpu_kick() + * KVM: VMX: Move vm entry failure handling to the exit handler + * KVM: Move main vcpu loop into subarch independent code + * KVM: Fix link error to "genapic" + * KVM: VMX: Fix exit qualification width on i386 + * KVM: x86 emulator: push imm8 + * KVM: x86 emulator: call near + * KVM: x86 emulator: pushf + * KVM: Improve emulation failure reporting + * KVM: VMX: Prevent setting CPU_BASED_TPR_SHADOW on i386 host + * KVM: x86 emulator: sort opcodes into ascending order + * KVM: x86 emulator: imlpement jump conditional relative + * KVM: X86 emulator: jump conditional short + * KVM: x86 emulator: lea + * KVM: x86 emulator: jmp abs + * KVM: x86 emulator: fix src, dst value initialization + * KVM: x86 emulator: popf + * KVM: Skip pio instruction when it is emulated, not executed + * KVM: fix PIC interrupt delivery on different APIC conditions + * KVM: Fix kvm_vcpu_ioctl_get_sregs() warning on i386 + * KVM: Remove errant printk() in kvm_vcpu_ioctl_get_sregs() + * KVM: Fix virtualization menu help text + * KVM: x86 emulator: Add vmmcall/vmcall to x86_emulate (v3) + * KVM: Refactor hypercall infrastructure (v3) + * KVM: x86 emulator: remove unused functions + * KVM: x86 emulator: move all x86_emulate_memop() to a structure + * KVM: x86 emulator: move all decoding process to function + x86_decode_insn() + * KVM: emulate_instruction() calls now x86_decode_insn() and + x86_emulate_insn() + * KVM: Call x86_decode_insn() only when needed + * KVM: Fix ioapic level-triggered interrupt redelivery + * KVM: Fix #UD exception delivery + * KVM: VMX: Further reduce efer reloads + * KVM: VMX: Fix build on i386 due to EFER_LMA not defined + * KVM: Fix ioapic.c compilation failure due to missing include + * KVM: x86 emulator: fix merge screwup due to emulator split + * KVM: x85 emulator: Correct inconcistency in between cr2 and ctxt->cr2. + * KVM: Avoid redelivery of edge-triggered irq if it is already in service + * KVM: Implement ioapic irq polarity bit + * KVM: x86 emulator: fix repne/repnz decoding + * KVM: Fix host oops due to guest changing efer + * KVM: Fix ioapic edge-triggered interrupts + * KVM: MMU: Set shadow pte atomically in mmu_pte_write_zap_pte() + * KVM: Allow not-present guest page faults to bypass kvm + * KVM: MMU: Make flooding detection work when guest page faults are + bypassed + * KVM: MMU: Ignore reserved bits in cr3 in non-pae mode + * KVM: x86 emulator: split some decoding into functions for readability + * KVM: x86 emulator: remove _eflags and use directly ctxt->eflags. + * KVM: x86 emulator: Remove no_wb, use dst.type = OP_NONE instead + * KVM: x86_emulator: no writeback for bt + * KVM: apic round robin cleanup + * KVM: Purify x86_decode_insn() error case management + * KVM: x86 emulator: Any legacy prefix after a REX prefix nullifies its + effect + * i386: Expose IOAPIC register definitions even if CONFIG_X86_IO_APIC is + not set + * KVM: x86 emulator: On a pop instruction, don't restore ECX and EIP on + error + * KVM: x86 emulator: remove unused variable + * KVM: VMX: Don't clear the vmcs if the vcpu is not loaded on any + processor + * KVM: VMX: Simplify vcpu_clear() + * KVM: Remove the usage of paeg->private field by rmap + * KVM: x86 emulator: Correct management of REP prefix + * KVM: Add general accessors to read and write guest memory + * KVM: Allow dynamic allocation of the mmu shadow cache size + * KVM: Check I/O APIC indirect index before writing + * KVM: Add kvm_free_lapic() to pair with kvm_create_lapic() + * KVM: Hoist kvm_create_lapic() into kvm_vcpu_init() + * KVM: Remove gratuitous casts from lapic.c + * KVM: CodingStyle cleanup + * KVM: VMX: Handle NMIs before enabling interrupts and preemption + * KVM: Support assigning userspace memory to the guest + * KVM: Export PIC reset for kernel device reset + * KVM: Split IOAPIC reset function and export for kernel RESET + * KVM: VMX: Reset mmu context when entering real mode + * KVM: Replace enum by #define + * KVM: Move x86 msr handling to new files x86.[ch] + * KVM: MMU: Clean up MMU functions to take struct kvm when appropriate + * KVM: MMU: More struct kvm_vcpu -> struct kvm cleanups + * KVM: Move guest pte dirty bit management to the guest pagetable walker + * KVM: MMU: Fix nx access bit for huge pages + * KVM: MMU: Disable write access on clean large pages + * KVM: MMU: Instatiate real-mode shadows as user writable shadows + * KVM: MMU: Move dirty bit updates to a separate function + * KVM: MMU: When updating the dirty bit, inform the mmu about it + * KVM: Portability: split kvm_vcpu_ioctl + * KVM: Restore missing #include + * KVM: Add some \n in ioapic_debug() + * KVM: x86 emulator: implement 'movnti mem, reg' + * KVM: MMU: Call update_dirty_bit() without disabling preemption + * KVM: Move apic timer interrupt backlog processing to common code + * KVM: Move interrupt injection out of interrupt disabled section + * KVM: Rename KVM_TLB_FLUSH to KVM_REQ_TLB_FLUSH + * KVM: VMX: Force vm86 mode if setting flags during real mode + * KVM: MMU: Simplify page table walker + * KVM: Actually move the interrupt injection code out of the critical + section + * KVM: x86 emulator: cmc, clc, cli, sti + * KVM: x86 emulator: use a defined flag definition + * KVM: x86 emulator: fix access registers for instructions with ModR/M + byte and Mod = 3 + * KVM: MMU: Add rmap_next(), a helper for walking kvm rmaps + * KVM: MMU: Keep a reverse mapping of non-writable translations + * KVM: MMU: Make gfn_to_page() always safe + * KVM: Partial swapping of guest memory + * KVM: VMX: Initialize vcpu with preemption enabled + * KVM: Use virtual cpu accounting if available for guest times. + * KVM: Move kvm_guest_exit() after local_irq_enable() + * KVM: MMU: Fix dirty bit pte gpa calculation + * KVM: Allocate userspace memory for older userspace + * KVM: Portability: Split kvm_vcpu into arch dependent and independent + parts (part 1) + * KVM: Fix local apic timer divide by zero + * KVM: Move vmx_vcpu_reset() out of vmx_vcpu_setup() + * KVM: Add a might_sleep() annotation to gfn_to_page() + * KVM: VMX: vmx_vcpu_setup(): remove unused variable. + * KVM: Per-architecture hypercall definitions + * KVM: Use new smp_call_function_mask() in kvm_flush_remote_tlbs() + * KVM: Unmap kernel-allocated memory on slot destruction + * KVM: Export memory slot allocation mechanism + * KVM: Add kernel-internal memory slots + * KVM: Add ioctl to tss address from userspace, + * KVM: x86 emulator: fix 'push imm8' emulation + * KVM: VMX: Let gcc to choose which registers to save (x86_64) + * KVM: VMX: Let gcc to choose which registers to save (i386) + * KVM: SVM: Let gcc to choose which registers to save (x86_64) + * KVM: SVM: Let gcc to choose which registers to save (i386) + * KVM: x86 emulator: invd instruction + * KVM: SVM: Intercept the 'invd' and 'wbinvd' instructions + * KVM: x86 emulator: don't depend on cr2 for mov abs emulation + * KVM: Move page fault processing to common code + * KVM: MMU: Topup the mmu memory preallocation caches before emulating an + insn + * KVM: Portability: Split kvm_vm_ioctl v3 + * KVM: Portability: Move memory segmentation to x86.c + * KVM: Portability: move get/set_apic_base to x86.c + * KVM: Portability: Move control register helper functions to x86.c + * KVM: VMX: Enable memory mapped TPR shadow (FlexPriority) + * KVM: Fix gfn_to_page() acquiring mmap_sem twice + * KVM: Portability: Move kvm_get/set_msr[_common] to x86.c + * KVM: Portability: Move x86 emulation and mmio device hook to x86.c + * KVM: Portability: Move pio emulation functions to x86.c + * KVM: x86 emulator: Extract the common code of SrcReg and DstReg + * KVM: x86 emulator: centralize decoding of one-byte register access + insns + * KVM: Simplify decode_register_operand() calling convention + * KVM: Make mark_page_dirty() work for aliased pages too. + * KVM: x86 emulator: Hoist modrm and abs decoding into separate functions + * KVM: Portability: Make exported debugfs data architecture-specific + * KVM: Portability: Move x86 instruction emulation code to x86.c + * KVM: Portability: Move x86 FPU handling to x86.c + * KVM: Portability: Move x86 vcpu ioctl handlers to x86.c + * KVM: x86 emulator: Move one-byte insns with reg operand into one-byte + section + * KVM: VMX: Fix repeated allocation of apic access page on smp + * KVM: SVM: Fix SMP with kernel apic + * KVM: Add make_page_dirty() to kvm_clear_guest_page() + * KVM: SVM: Defer nmi processing until switch to host state is complete + * KVM: VMX: Avoid reloading host efer on cpus that don't have it + * KVM: VMX: Use vmx to inject real interrupts + * KVM: Go back to atomically injecting interrupts + * KVM: VMX: Comment VMX primary/secondary exec ctl definitions + * KVM: VMX: wbinvd exiting + * KVM: x86 emulator: fix JMP_REL + * KVM: x86 emulator: fix the saving of of the eip value + * KVM: x86 emulator: remove 8 bytes operands emulator for call near + instruction + * KVM: Simplify CPU_TASKS_FROZEN cpu notifier handling + * KVM: add kvm_is_error_hva() + * KVM: introduce gfn_to_hva() + * KVM: Change kvm_{read,write}_guest() to use copy_{from,to}_user() + * KVM: Portability: Move some includes to x86.c + * KVM: Portability: Move kvm_x86_ops to x86.c + * KVM: Portability: Add vcpu and hardware management arch hooks + * KVM: Portability: Combine kvm_init and kvm_init_x86 + * KVM: Portability: Move x86 specific code from kvm_init() to kvm_arch() + * KVM: x86 emulator: modify 'lods', and 'stos' not to depend on CR2 + * KVM: Portability: move KVM_CHECK_EXTENSION + * KVM: VMX: Consolidate register usage in vmx_vcpu_run() + * KVM: Portability: Make kvm_vcpu_ioctl_translate arch dependent + * KVM: x86 emulator: Rename 'cr2' to 'memop' + * KVM: Remove ptr comparisons to 0 + * KVM: Remove __init attributes for kvm_init_debug and kvm_init_msr_list + * KVM: Portability: Add two hooks to handle kvm_create and destroy vm + * KVM: Replace 'light_exits' stat with 'host_state_reload' + * KVM: Add fpu_reload counter + * KVM: Add instruction emulation statistics + * KVM: Extend stats support for VM stats + * KVM: MMU: Add some mmu statistics + * KVM: x86 emulator: Use emulator_write_emulated and not + emulator_write_std + * KVM: Make unloading of FPU state when putting vcpu arch-independent + * KVM: SVM: Disable Lazy FPU optimization + * KVM: Portability: Move kvm_vcpu_ioctl_get_dirty_log to arch-specific + file + * KVM: Portability: MMU initialization and teardown split + * KVM: Portability: Move some macro definitions from kvm.h to x86.h + * KVM: Portability: Move struct kvm_x86_ops definition to x86.h + * KVM: Portability: Move vcpu regs enumeration definition to x86.h + * KVM: Move some static inline functions out from kvm.h into x86.h + * KVM: Portability: Move some function declarations to x86.h + * KVM: VMX: Force seg.base == (seg.sel << 4) in real mode + * KVM: MMU: Change guest pte access to kvm_{read,write}_guest() + * kvm: simplify kvm_clear_guest_page() + * KVM: Add missing #include + * KVM: MMU: Remove unused variable + * KVM: Remove unused "rmap_overflow" variable + * KVM: Correct consistent typo: "destory" -> "destroy" + * KVM: Move misplaced comment + * KVM: Portability: Move kvm_memory_alias to asm/kvm.h + * KVM: Portability: Move x86 pic strutctures + * KVM: Portability: Move kvm_regs to + * KVM: Portability: Move structure lapic_state to + * KVM: Portability: Move kvm_segment & kvm_dtable structure to + + * KVM: Portability: Move kvm_sregs and msr structures to + * KVM: Portability: Move cpuid structures to + * KVM: Export include/asm-x86/kvm.h + * KVM: MMU: Fix potential memory leak with smp real-mode + * KVM: MMU: Selectively set PageDirty when releasing guest memory + * KVM: x86 emulator: retire ->write_std() + * KVM: x86 emulator: prefetch up to 15 bytes of the instruction executed + * KVM: SVM: Fix FPU leak and re-enable lazy FPU switching + * KVM: Recalculate mmu pages needed for every memory region change + * KVM: Portability: Split kvm_set_memory_region() to have an arch + callout + * KVM: Split vcpu creation to avoid vcpu_load() before preemption setup + * KVM: MMU: Implement guest page fault bypass for nonpae + * KVM: Add statistic for remote tlb flushes + * KVM: MMU: Avoid unnecessary remote tlb flushes when guest updates a pte + * KVM: Add parentheses to silence gcc + * KVM: Don't bother the mmu if cr3 load doesn't change cr3 + * KVM: MMU: Code cleanup + * KVM: MMU: Introduce and use gpte_to_gfn() + * KVM: MMU: Move pse36 handling to the guest walker + * KVM: MMU: Remove extra gaddr parameter from set_pte_common() + * KVM: MMU: Remove set_pde() + * KVM: MMU: Adjust page_header_update_slot() to accept a gfn instead of a + gpa + * KVM: MMU: Introduce gfn_to_gpa() + * KVM: MMU: Simplify nonpaging_map() + * KVM: MMU: Remove gva_to_hpa() + * KVM: Remove gpa_to_hpa() + * KVM: MMU: Rename variable of type 'struct kvm_mmu_page *' + * KVM: MMU: Rename 'release_page' + * KVM: Disallow fork() and similar games when using a VM + * KVM: Enhance guest cpuid management + * KVM: Replace private 'struct segment descriptor' by x86's desc_struct + * KVM: Remove segment_descriptor, part 2 + * KVM: Fix compile error on i386 + * KVM: VMX: Read & store IDT_VECTORING_INFO_FIELD + * KVM: Fix faults during injection of real-mode interrupts + * KVM: x86 emulator: Fix instruction fetch cache hit check + * KVM: VMX: Remove the secondary execute control dependency on irqchip + * KVM: Portability: Move unalias_gfn to arch dependent file + * KVM: x86 emulator: Make a distinction between repeat prefixes F3 and F2 + * KVM: x86 emulator: address size and operand size overrides are sticky + * KVM: Remove desc.h include in kvm_main.c + * KVM: Revert segment_descriptor.h removal + * KVM: Remove misleading check for mmio during event injection + * KVM: MMU: mark pages that were inserted to the shadow pages table as + accessed + * KVM: x86 emulator: rename REP_REPE_PREFIX + * KVM: x86 emulator: cmps instruction + * KVM: Add ifdef in irqchip struct for x86 only structures + * KVM: Fix cpuid2 killing 32-bit guests on non-NX machines + * KVM: x86 emulator: Move rep processing before instruction execution + * KVM: x86 emulator: unify two switches + * KVM: x86 emulator: unify four switch statements into two + * KVM: Don't bypass the mmu if in pae and pdptrs changed + * KVM: Portability: Move KVM_INTERRUPT vcpu ioctl to x86.c + * KVM: Correct kvm_init() error paths not freeing bad_pge. + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * KVM: SVM: Remove KVM specific defines for MSR_EFER + * KVM: Replace kvm_lapic with kvm_vcpu in ioapic/lapic interface + * KVM: Replace dest_Lowest_Prio and dest_Fixed with self-defined macros + * KVM: Extend ioapic code to support iosapic + * KVM: Portability: Move address types to their own header file + * KVM: Portability: Move IO device definitions to its own header file + * KVM: Portability: Stop including x86-specific headers in kvm_main.c + * KVM: Portability: Create kvm_arch_vcpu_runnable() function + * KVM: Convert KVM from ->nopage() to ->fault() + * KVM: MMU: Remove unused prev_shadow_ent variable from fetch() + * KVM: Generalize exception injection mechanism + * KVM: Replace page fault injection by the generalized exception queue + * KVM: Replace #GP injection by the generalized exception queue + * KVM: Use generalized exception queue for injecting #UD + * KVM: x86 emulator: fix eflags preparation for emulation + * KVM: VMX: Avoid exit when setting cr8 if the local apic is in the + kernel + * KVM: SVM: Emulate read/write access to cr8 + * KVM: x86 emulator: Fix stack instructions on 64-bit mode + * KVM: SVM: Trap access to the cr8 register + * KVM: VMX: Fix cr8 exit optimization + * KVM: MMU: Use cmpxchg for pte updates on walk_addr() + * KVM: MMU: Simplify calculation of pte access + * KVM: MMU: Set nx bit correctly on shadow ptes + * KVM: MMU: Move pte access calculation into a helper function + * KVM: MMU: Fix inherited permissions for emulated guest pte updates + * KVM: MMU: No need to pick up nx bit from guest pte + * KVM: MMU: Pass pte dirty flag to set_pte() instead of calculating it + on-site + * KVM: MMU: Remove walker argument to set_pte() + * KVM: MMU: Move set_pte() into guest paging mode independent code + * KVM: MMU: Adjust mmu_set_spte() debug code for gpte removal + * KVM: MMU: Use mmu_set_spte() for real-mode shadows + * KVM: SVM: Exit to userspace if write to cr8 and not using in-kernel + apic + * KVM: SVM: support writing 0 to K8 performance counter control registers + * KVM: MMU: Fix kunmap_atomic() call in cmpxchg_gpte() + * KVM: MMU: Fix SMP shadow instantiation race + * KVM: LAPIC: minor debugging compile fix + * KVM: MMU: emulated cmpxchg8b should be atomic on i386 + * KVM: Fix bad kunmap_atomic() paramerter inm cmpxchg emulation + * KVM: Make cmpxchg emulation compile on i386 + * KVM: Another cmpxchg i386 compile fix + * KVM: Another cmpxchg emulation compile fix + * KVM: Another cmpxchg emulation compile fix + * KVM: Portability: Move kvm{pic,ioapic} accesors to x86 specific code + * KVM: Portability: Introduce kvm_vcpu_arch + * KVM: Portability: Split mmu-related static inline functions to mmu.h + * KVM: Portability: Move kvm_vcpu definition back to kvm.h + * KVM: Portability: Expand the KVM_VCPU_COMM in kvm_vcpu structure. + * KVM: Portability: Move kvm_vcpu_stat to x86.h + * KVM: Portability: Move memslot aliases to new struct kvm_arch + * KVM: Portability: Move mmu-related fields to kvm_arch + * KVM: Portability: move vpic and vioapic to kvm_arch + * KVM: Portability: Move round_robin_prev_vcpu and tss_addr to kvm_arch + * KVM: Portability: Move kvm_vm_stat to x86.h + * KVM: VMX: Add printk_ratelimit in vmx_intr_assist + * KVM: Move arch dependent files to new directory arch/x86/kvm/ + * KVM: Move drivers/kvm/* to virt/kvm/ + * KVM: Fix compile error in asm/kvm_host.h + * KVM: Move irqchip declarations into new ioapic.h and lapic.h + * KVM: Move ioapic code to common directory. + * KVM: Move kvm_vcpu_kick() to x86.c + * KVM: Expose ioapic to ia64 save/restore APIs + * KVM: MMU: Coalesce remote tlb flushes + * KVM: MMU: Add cache miss statistic + * KVM: Print data for unimplemented wrmsr + * KVM: Ensure pages are copied on write + * KVM: MMU: Fix cmpxchg8b emulation on i386 (again) + * KVM: x86 emulator: Add vmmcall/vmcall to x86_emulate (v3) + * KVM: Refactor hypercall infrastructure (v3) + * KVM: x86 emulator: remove unused functions + * KVM: x86 emulator: move all x86_emulate_memop() to a structure + * KVM: x86 emulator: move all decoding process to function + x86_decode_insn() + * KVM: emulate_instruction() calls now x86_decode_insn() and + x86_emulate_insn() + * KVM: Call x86_decode_insn() only when needed + * KVM: VMX: Further reduce efer reloads + * KVM: Allow not-present guest page faults to bypass kvm + * KVM: MMU: Make flooding detection work when guest page faults are + bypassed + * KVM: MMU: Ignore reserved bits in cr3 in non-pae mode + * KVM: x86 emulator: split some decoding into functions for readability + * KVM: x86 emulator: remove _eflags and use directly ctxt->eflags. + * KVM: x86 emulator: Remove no_wb, use dst.type = OP_NONE instead + * KVM: x86_emulator: no writeback for bt + * KVM: Purify x86_decode_insn() error case management + * KVM: x86 emulator: Any legacy prefix after a REX prefix nullifies its + effect + * KVM: VMX: Don't clear the vmcs if the vcpu is not loaded on any + processor + * KVM: VMX: Simplify vcpu_clear() + * KVM: Remove the usage of page->private field by rmap + * KVM: Add general accessors to read and write guest memory + * KVM: Allow dynamic allocation of the mmu shadow cache size + * KVM: Add kvm_free_lapic() to pair with kvm_create_lapic() + * KVM: Hoist kvm_create_lapic() into kvm_vcpu_init() + * KVM: Remove gratuitous casts from lapic.c + * KVM: CodingStyle cleanup + * KVM: Support assigning userspace memory to the guest + * KVM: Move x86 msr handling to new files x86.[ch] + * KVM: MMU: Clean up MMU functions to take struct kvm when appropriate + * KVM: MMU: More struct kvm_vcpu -> struct kvm cleanups + * KVM: Move guest pte dirty bit management to the guest pagetable walker + * KVM: MMU: Fix nx access bit for huge pages + * KVM: MMU: Disable write access on clean large pages + * KVM: MMU: Instantiate real-mode shadows as user writable shadows + * KVM: MMU: Move dirty bit updates to a separate function + * KVM: MMU: When updating the dirty bit, inform the mmu about it + * KVM: Portability: split kvm_vcpu_ioctl + * KVM: apic round robin cleanup + * KVM: Add some \n in ioapic_debug() + * KVM: Move apic timer interrupt backlog processing to common code + * KVM: Rename KVM_TLB_FLUSH to KVM_REQ_TLB_FLUSH + * KVM: x86 emulator: Implement emulation of instruction: inc & dec + * KVM: MMU: Simplify page table walker + * KVM: x86 emulator: cmc, clc, cli, sti + * KVM: MMU: Add rmap_next(), a helper for walking kvm rmaps + * KVM: MMU: Keep a reverse mapping of non-writable translations + * KVM: MMU: Make gfn_to_page() always safe + * KVM: MMU: Partial swapping of guest memory + * KVM: Use virtual cpu accounting if available for guest times. + * KVM: Allocate userspace memory for older userspace + * KVM: Portability: Split kvm_vcpu into arch dependent and independent + parts (part 1) + * KVM: Move vmx_vcpu_reset() out of vmx_vcpu_setup() + * KVM: Add a might_sleep() annotation to gfn_to_page() + * KVM: Export PIC reset for kernel device reset + * KVM: Split IOAPIC reset function and export for kernel RESET + * KVM: Per-architecture hypercall definitions + * KVM: Unmap kernel-allocated memory on slot destruction + * KVM: Export memory slot allocation mechanism + * KVM: Add kernel-internal memory slots + * KVM: Add ioctl to tss address from userspace, + * KVM: VMX: Let gcc to choose which registers to save (x86_64) + * KVM: VMX: Let gcc to choose which registers to save (i386) + * KVM: SVM: Let gcc to choose which registers to save (x86_64) + * KVM: SVM: Let gcc to choose which registers to save (i386) + * KVM: x86 emulator: don't depend on cr2 for mov abs emulation + * KVM: Move page fault processing to common code + * KVM: MMU: Topup the mmu memory preallocation caches before emulating an + insn + * KVM: Portability: Split kvm_vm_ioctl v3 + * KVM: Portability: Move memory segmentation to x86.c + * KVM: Portability: move get/set_apic_base to x86.c + * KVM: Portability: Move control register helper functions to x86.c + * KVM: VMX: Enable memory mapped TPR shadow (FlexPriority) + * KVM: Fix gfn_to_page() acquiring mmap_sem twice + * KVM: Portability: Move kvm_get/set_msr[_common] to x86.c + * KVM: Portability: Move x86 emulation and mmio device hook to x86.c + * KVM: Portability: Move pio emulation functions to x86.c + * KVM: x86 emulator: Extract the common code of SrcReg and DstReg + * KVM: x86 emulator: centralize decoding of one-byte register access + insns + * KVM: Simplify decode_register_operand() calling convention + * KVM: Make mark_page_dirty() work for aliased pages too. + * KVM: x86 emulator: Hoist modrm and abs decoding into separate functions + * KVM: Portability: Make exported debugfs data architecture-specific + * KVM: Portability: Move x86 instruction emulation code to x86.c + * KVM: Portability: Move x86 FPU handling to x86.c + * KVM: Portability: Move x86 vcpu ioctl handlers to x86.c + * KVM: Add make_page_dirty() to kvm_clear_guest_page() + * KVM: VMX: Use vmx to inject real-mode interrupts + * KVM: VMX: Read & store IDT_VECTORING_INFO_FIELD + * KVM: Fix faults during injection of real-mode interrupts + * KVM: VMX: Comment VMX primary/secondary exec ctl definitions + * KVM: VMX: wbinvd exiting + * KVM: x86 emulator: remove 8 bytes operands emulator for call near + instruction + * KVM: Simplify CPU_TASKS_FROZEN cpu notifier handling + * KVM: add kvm_is_error_hva() + * KVM: introduce gfn_to_hva() + * KVM: Change kvm_{read,write}_guest() to use copy_{from,to}_user() + * KVM: Portability: Move some includes to x86.c + * KVM: Portability: Move kvm_x86_ops to x86.c + * KVM: Portability: Add vcpu and hardware management arch hooks + * KVM: Portability: Combine kvm_init and kvm_init_x86 + * KVM: Portability: Move x86 specific code from kvm_init() to kvm_arch() + * KVM: x86 emulator: modify 'lods', and 'stos' not to depend on CR2 + * KVM: Portability: move KVM_CHECK_EXTENSION + * KVM: VMX: Consolidate register usage in vmx_vcpu_run() + * KVM: Portability: Make kvm_vcpu_ioctl_translate arch dependent + * KVM: Remove ptr comparisons to 0 + * KVM: Remove __init attributes for kvm_init_debug and kvm_init_msr_list + * KVM: Portability: Add two hooks to handle kvm_create and destroy vm + * KVM: Replace 'light_exits' stat with 'host_state_reload' + * KVM: Add fpu_reload counter + * KVM: Add instruction emulation statistics + * KVM: Extend stats support for VM stats + * KVM: MMU: Add some mmu statistics + * KVM: Make unloading of FPU state when putting vcpu arch-independent + * KVM: Portability: Move kvm_vcpu_ioctl_get_dirty_log to arch-specific + file + * KVM: Portability: MMU initialization and teardown split + * KVM: Portability: Move some macro definitions from kvm.h to x86.h + * KVM: Portability: Move struct kvm_x86_ops definition to x86.h + * KVM: Portability: Move vcpu regs enumeration definition to x86.h + * KVM: Move some static inline functions out from kvm.h into x86.h + * KVM: Portability: Move some function declarations to x86.h + * KVM: VMX: Force seg.base == (seg.sel << 4) in real mode + * KVM: MMU: Change guest pte access to kvm_{read,write}_guest() + * KVM: Simplify kvm_clear_guest_page() + * KVM: Add missing #include + * KVM: MMU: Remove unused variable + * KVM: Remove unused "rmap_overflow" variable + * KVM: Correct consistent typo: "destory" -> "destroy" + * KVM: Move misplaced comment + * KVM: Portability: Move kvm_memory_alias to asm/kvm.h + * KVM: Portability: Move x86 pic strutctures + * KVM: Portability: Move kvm_regs to + * KVM: Portability: Move structure lapic_state to + * KVM: Portability: Move kvm_segment & kvm_dtable structure to + + * KVM: Portability: Move kvm_sregs and msr structures to + * KVM: Portability: Move cpuid structures to + * KVM: Export include/asm-x86/kvm.h + * KVM: MMU: Fix potential memory leak with smp real-mode + * KVM: MMU: Selectively set PageDirty when releasing guest memory + * KVM: x86 emulator: retire ->write_std() + * KVM: x86 emulator: prefetch up to 15 bytes of the instruction executed + * KVM: Recalculate mmu pages needed for every memory region change + * KVM: Portability: Split kvm_set_memory_region() to have an arch + callout + * KVM: Split vcpu creation to avoid vcpu_load() before preemption setup + * KVM: MMU: Implement guest page fault bypass for nonpae + * KVM: Add statistic for remote tlb flushes + * KVM: MMU: Avoid unnecessary remote tlb flushes when guest updates a pte + * KVM: Don't bother the mmu if cr3 load doesn't change cr3 + * KVM: MMU: Code cleanup + * KVM: MMU: Introduce and use gpte_to_gfn() + * KVM: MMU: Move pse36 handling to the guest walker + * KVM: MMU: Remove extra gaddr parameter from set_pte_common() + * KVM: MMU: Remove set_pde() + * KVM: MMU: Adjust page_header_update_slot() to accept a gfn instead of a + gpa + * KVM: MMU: Introduce gfn_to_gpa() + * KVM: MMU: Simplify nonpaging_map() + * KVM: MMU: Remove gva_to_hpa() + * KVM: Remove gpa_to_hpa() + * KVM: MMU: Rename variables of type 'struct kvm_mmu_page *' + * KVM: MMU: Rename 'release_page' + * KVM: Disallow fork() and similar games when using a VM + * KVM: Enhance guest cpuid management + * KVM: VMX: Remove the secondary execute control dependency on irqchip + * KVM: Portability: Move unalias_gfn to arch dependent file + * KVM: x86 emulator: Make a distinction between repeat prefixes F3 and F2 + * KVM: x86 emulator: address size and operand size overrides are sticky + * KVM: Remove misleading check for mmio during event injection + * KVM: MMU: mark pages that were inserted to the shadow pages table as + accessed + * KVM: x86 emulator: rename REP_REPE_PREFIX + * KVM: x86 emulator: Rename 'cr2' to 'memop' + * KVM: x86 emulator: cmps instruction + * KVM: Add ifdef in irqchip struct for x86 only structures + * KVM: Fix cpuid2 killing 32-bit guests on non-NX machines + * KVM: x86 emulator: Move rep processing before instruction execution + * KVM: x86 emulator: unify two switches + * KVM: x86 emulator: unify four switch statements into two + * KVM: Portability: Move KVM_INTERRUPT vcpu ioctl to x86.c + * KVM: Correct kvm_init() error paths not freeing bad_pge. + * KVM: Export include/linux/kvm.h only if $ARCH actually supports KVM + * KVM: SVM: Remove KVM specific defines for MSR_EFER + * KVM: Replace kvm_lapic with kvm_vcpu in ioapic/lapic interface + * KVM: Replace dest_Lowest_Prio and dest_Fixed with self-defined macros + * KVM: Extend ioapic code to support iosapic + * KVM: Portability: Move address types to their own header file + * KVM: Portability: Move IO device definitions to its own header file + * KVM: Portability: Stop including x86-specific headers in kvm_main.c + * KVM: Portability: Create kvm_arch_vcpu_runnable() function + * KVM: Convert KVM from ->nopage() to ->fault() + * KVM: MMU: Remove unused prev_shadow_ent variable from fetch() + * KVM: Generalize exception injection mechanism + * KVM: Replace page fault injection by the generalized exception queue + * KVM: Replace #GP injection by the generalized exception queue + * KVM: Use generalized exception queue for injecting #UD + * KVM: x86 emulator: fix eflags preparation for emulation + * KVM: VMX: Avoid exit when setting cr8 if the local apic is in the + kernel + * KVM: SVM: Emulate read/write access to cr8 + * KVM: x86 emulator: Fix stack instructions on 64-bit mode + * KVM: SVM: Trap access to the cr8 register + * KVM: VMX: Fix cr8 exit optimization + * KVM: MMU: Use cmpxchg for pte updates on walk_addr() + * KVM: MMU: Simplify calculation of pte access + * KVM: MMU: Set nx bit correctly on shadow ptes + * KVM: MMU: Move pte access calculation into a helper function + * KVM: MMU: Fix inherited permissions for emulated guest pte updates + * KVM: MMU: No need to pick up nx bit from guest pte + * KVM: MMU: Pass pte dirty flag to set_pte() instead of calculating it + on-site + * KVM: MMU: Remove walker argument to set_pte() + * KVM: MMU: Move set_pte() into guest paging mode independent code + * KVM: MMU: Adjust mmu_set_spte() debug code for gpte removal + * KVM: MMU: Use mmu_set_spte() for real-mode shadows + * KVM: SVM: Exit to userspace if write to cr8 and not using in-kernel + apic + * KVM: MMU: Fix SMP shadow instantiation race + * KVM: LAPIC: minor debugging compile fix + * KVM: SVM: support writing 0 to K8 performance counter control registers + * KVM: MMU: emulated cmpxchg8b should be atomic on i386 + * KVM: Portability: Move kvm{pic,ioapic} accesors to x86 specific code + * KVM: Portability: Introduce kvm_vcpu_arch + * KVM: Portability: Split mmu-related static inline functions to mmu.h + * KVM: Portability: Move kvm_vcpu definition back to kvm.h + * KVM: Portability: Expand the KVM_VCPU_COMM in kvm_vcpu structure. + * KVM: Portability: Move kvm_vcpu_stat to x86.h + * KVM: Portability: Move memslot aliases to new struct kvm_arch + * KVM: Portability: Move mmu-related fields to kvm_arch + * KVM: Portability: move vpic and vioapic to kvm_arch + * KVM: Portability: Move round_robin_prev_vcpu and tss_addr to kvm_arch + * KVM: Portability: Move kvm_vm_stat to x86.h + * KVM: VMX: Add printk_ratelimit in vmx_intr_assist + * KVM: Move arch dependent files to new directory arch/x86/kvm/ + * KVM: Move drivers/kvm/* to virt/kvm/ + * KVM: Move irqchip declarations into new ioapic.h and lapic.h + * KVM: Move ioapic code to common directory. + * KVM: Move kvm_vcpu_kick() to x86.c + * KVM: Expose ioapic to ia64 save/restore APIs + * KVM: MMU: Coalesce remote tlb flushes + * KVM: MMU: Add cache miss statistic + * KVM: Print data for unimplemented wrmsr + * KVM: Ensure pages are copied on write + * KVM: local APIC TPR access reporting facility + * KVM: Accelerated apic support + * KVM: Disable vapic support on Intel machines with FlexPriority + * KVM: MMU: Concurrent guest walkers + * KVM: Add kvm_read_guest_atomic() + * KVM: MMU: Avoid calling gfn_to_page() in mmu_set_spte() + * KVM: MMU: Switch to mmu spinlock + * KVM: MMU: Move kvm_free_some_pages() into critical section + * KVM: MMU: Broaden scope of mmap_sem to include actual mapping + * KVM: MMU: Fix recursive locking of mmap_sem() + * KVM: Fix unbalanced mmap_sem operations in cmpxchg8b emulation + * KVM: Mark vapic page as dirty for save/restore/migrate + * KVM: x86 emulator: Only allow VMCALL/VMMCALL trapped by #UD + * KVM: MMU: Update shadow ptes on partial guest pte writes + * KVM: MMU: Simplify hash table indexing + * KVM: Portability: Move kvm_fpu to asm-x86/kvm.h + * KVM: MMU: Fix dirty page setting for pages removed from rmap + * KVM: Initialize the mmu caches only after verifying cpu support + * KVM: Fix unbounded preemption latency + * KVM: Put kvm_para.h include outside __KERNEL__ + * KVM: Move apic timer migration away from critical section + * KVM: SVM: Fix lazy FPU switching + * KVM: MMU: Fix gpa truncation when reading a pte + * [GFS2] Handle multiple glock demote requests + * [GFS2] Clean up internal read function + * [GFS2] Use ->page_mkwrite() for mmap() + * [GFS2] Remove useless i_cache from inodes + * [GFS2] Remove unused field in struct gfs2_inode + * [GFS2] Add gfs2_is_writeback() + * [GFS2] Introduce gfs2_set_aops() + * [GFS2] Split gfs2_writepage into three cases + * [GFS2] Add writepages for GFS2 jdata + * [GFS2] Don't hold page lock when starting transaction + * [GFS2] Use correct include file in ops_address.c + * [GFS2] Remove unused variables + * [GFS2] Remove "reclaim limit" + * [GFS2] Add sync_page to metadata address space operations + * [GFS2] Reorder writeback for glock sync + * [GFS2] Remove flags no longer required + * [GFS2] Given device ID rather than s_id in "id" sysfs file + * [GFS2] check kthread_should_stop when waiting + * [GFS2] Don't add glocks to the journal + * [GFS2] Use atomic_t for journal free blocks counter + * [GFS2] Move gfs2_logd into log.c + * [GFS2] Don't periodically update the jindex + * [GFS2] Check for installation of mount helpers for DLM mounts + * [GFS2] tidy up error message + * [GFS2] Fix runtime issue with UP kernels + * [GFS2] remove unnecessary permission checks + * [GFS2] Fix build warnings + * [GFS2] Remove unrequired code + * [GFS2] Remove lock methods for lock_nolock protocol + * [GFS2] patch to check for recursive lock requests in gfs2_rename code + path + * [GFS2] Remove unused variable + * [GFS2] use pid for plock owner for nfs clients + * [GFS2] Remove function gfs2_get_block + * [GFS2] Journal extent mapping + * [GFS2] Get rid of useless "found" variable in quota.c + * [GFS2] Run through full bitmaps quicker in gfs2_bitfit + * [GFS2] Reorganize function gfs2_glmutex_lock + * [GFS2] Only fetch the dinode once in block_map + * [GFS2] Function meta_read optimization + * [GFS2] Incremental patch to fix compiler warning + * [GFS2] Eliminate the no longer needed sd_statfs_mutex + * [GFS2] Minor correction + * [GFS2] Fix log block mapper + * [GFS2] Remove unused variable + * [GFS2] Allow page migration for writeback and ordered pages + * [GFS2] Initialize extent_list earlier + * [GFS2] Fix problems relating to execution of files on GFS2 + * [GFS2] Fix assert in log code + * [GFS2] Reduce inode size by moving i_alloc out of line + * [GFS2] Remove unneeded i_spin + * [GFS2] gfs2_alloc_required performance + * [GFS2] Fix write alloc required shortcut calculation + * [GFS2] Fix typo + * [GFS2] Fix page_mkwrite truncation race path + * [GFS2] Lockup on error + * [GFS2] Allow journal recovery on read-only mount + + -- Tim Gardner Sun, 27 Jan 2008 20:37:18 -0700 + +linux (2.6.24-5.9) hardy; urgency=low + + [Amit Kucheria] + + * Fix LPIA FTBFS due to virtio Ignore: yes + + [Upstream Kernel Changes] + + * ACPI: processor: Fix null pointer dereference in throttling + * [SPARC64]: Fix of section mismatch warnings. + * [SPARC64]: Fix section error in sparcspkr + * [SPARC]: Constify function pointer tables. + * [BLUETOOTH]: Move children of connection device to NULL before + connection down. + * [TULIP] DMFE: Fix SROM parsing regression. + * [IPV4]: Add missing skb->truesize increment in ip_append_page(). + * iwlwifi: fix possible read attempt on ucode that is not available + * [NETNS]: Re-export init_net via EXPORT_SYMBOL. + * [INET]: Fix truesize setting in ip_append_data + * sis190: add cmos ram access code for the SiS19x/968 chipset pair + * sis190: remove duplicate INIT_WORK + * sis190: mdio operation failure is not correctly detected + * sis190: scheduling while atomic error + * Update ctime and mtime for memory-mapped files + * [SCSI] initio: fix module hangs on loading + * xen: disable vcpu_info placement for now + * agp/intel: add support for E7221 chipset + * drm/i915: add support for E7221 chipset + * DMI: move dmi_available declaration to linux/dmi.h + * DMI: create dmi_get_slot() + * ACPI: create acpi_dmi_dump() + * ACPI: on OSI(Linux), print needed DMI rather than requesting dmidecode + output + * ACPI: Delete Intel Customer Reference Board (CRB) from OSI(Linux) DMI + list + * ACPI: make _OSI(Linux) console messages smarter + * ACPI: Add ThinkPad R61, ThinkPad T61 to OSI(Linux) white-list + * ACPI: DMI blacklist to reduce console warnings on OSI(Linux) systems. + * ACPI: EC: fix dmesg spam regression + * ACPI: EC: add leading zeros to debug messages + * Pull bugzilla-9747 into release branch + * Pull bugzilla-8459 into release branch + * Pull bugzilla-9798 into release branch + * Pull dmi-2.6.24 into release branch + * [SPARC64]: Partially revert "Constify function pointer tables." + * lockdep: fix kernel crash on module unload + * sysctl: kill binary sysctl KERN_PPC_L2CR + * fix hugepages leak due to pagetable page sharing + * spi: omap2_mcspi PIO RX fix + * Linux 2.6.24 + + -- Tim Gardner Fri, 25 Jan 2008 01:44:27 -0700 + +linux (2.6.24-5.8) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Update to 2.6.24-rc8-rt1 + * rt: Update configuration files + + [Amit Kucheria] + + * Asix: fix breakage caused in 2.6.24-rc7 + * Add CONFIG_CPUSETS to server-related flavours + - LP: #182434 + + [Chuck Short] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + - LP: #175834 + + [Kees Cook] + + * AppArmor: updated patch series to upstream SVN 1079. + + [Soren Hansen] + + * Updated configs to enable virtio stuff Ignore: yes + + [Stefan Bader] + + * Enabled CONFIG_BSD_PROCESS_ACCT=y for sparc. + - LP: #176587 + * Enable CONFIG_AUDITSYSCALL=y. + - LP: #140784 + * Added CONFIG_AUDIT_SYSCALL=y to custom lpia(compat) + * Enabled CONFIG_HUGETLBFS=y for i386/server amd64/server and ia64. + * Lower priority of pnpacpi resource messages to warning level. + - LP: #159241 + * Fix the messed up message level of pnpacpi parser. + + [Tim Gardner] + + * Start new release, bump ABI to -5 + * Disabled iwlwifi preperatory to moving it to l-u-m. + * Enabled CONFIG_USB_SERIAL_KEYSPAN + * Disabled CONFIG_CGROUPS. + * Virtio config settings for -rt. + * Re-enable IWLWIFI in the kernel. + * Fixed -rt saa7134-core.c FTBS + + [Upstream Kernel Changes] + + * Input: Handle EV_PWR type of input caps in input_set_capability. + * Input: jornada680_kbd - fix default keymap + * increase PNP_MAX_PORT to 40 from 24 + * sched: fix gcc warnings + * leds: Fix leds_list_lock locking issues + * leds: Fix locomo LED driver oops + * x86: fix asm-x86/byteorder.h for userspace export + * x86: fix asm-x86/msr.h for user-space export + * ACPI: EC: Enable boot EC before bus_scan + * ACPI: Make sysfs interface in ACPI power optional. + * fix lguest rmmod "bad pgd" + * slub: provide /proc/slabinfo + * [POWERPC] Fix build failure on Cell when CONFIG_SPU_FS=y + * slub: register slabinfo to procfs + * [SCSI] scsi_sysfs: restore prep_fn when ULD is removed + * Unify /proc/slabinfo configuration + * scsi: revert "[SCSI] Get rid of scsi_cmnd->done" + * restrict reading from /proc//maps to those who share ->mm or can + ptrace pid + * Fix kernel/ptrace.c compile problem (missing "may_attach()") + * hwmon: (w83627ehf) Be more careful when changing VID input level + * NFS: Fix a possible Oops in fs/nfs/super.c + * NFSv4: Fix circular locking dependency in nfs4_kill_renewd + * NFS: add newline to kernel warning message in auth_gss code + * NFSv4: nfs4_open_confirm must not set the open_owner as confirmed on + error + * NFSv4: Fix open_to_lock_owner sequenceid allocation... + * gameport: don't export functions that are static inline + * Input: spitzkbd - fix suspend key handling + * Input: pass EV_PWR events to event handlers + * [ARM] 4735/1: Unbreak pxa25x suspend/resume + * IB/srp: Fix list corruption/oops on module reload + * Console is utf-8 by default + * [IA64] Update Altix BTE error return status patch + * [IA64] Update Altix nofault code + * [X25]: Add missing x25_neigh_put + * [XFRM]: Do not define km_migrate() if !CONFIG_XFRM_MIGRATE + * [CASSINI]: Fix endianness bug. + * [CASSINI]: Revert 'dont touch page_count'. + * [CASSINI]: Program parent Intel31154 bridge when necessary. + * [CASSINI]: Set skb->truesize properly on receive packets. + * [CASSINI]: Fix two obvious NAPI bugs. + * [CASSINI]: Bump driver version and release date. + * [INET]: Fix netdev renaming and inet address labels + * [CONNECTOR]: Return proper error code in cn_call_callback() + * [ISDN] i4l: 'NO CARRIER' message lost after ldisc flush + * [ISDN]: i4l: Fix DLE handling for i4l-audio + * fix: using joysticks in 32 bit applications on 64 bit systems + * [ARM] 4691/1: add missing i2c_board_info struct for at91rm9200 + * hda_intel suspend latency: shorten codec read + * CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU + * Linux 2.6.24-rc7 + * sh: Fix argument page dcache flushing regression. + * V4L/DVB (6944a): Fix Regression VIDIOCGMBUF ioctl hangs on bttv driver + * V4L/DVB (6916): ivtv: udelay has to be changed *after* the eeprom was + read, not before + * [MIPS] Move inclusing of kernel/time/Kconfig menu to appropriate place + * [MIPS] Alchemy: Fix use of __init code bug exposed by modpost warning + * [MIPS] Fix IP32 breakage + * [MIPS] Assume R4000/R4400 newer than 3.0 don't have the mfc0 count bug + * [MIPS] Fix CONFIG_BOOT_RAW. + * ACPI: Reintroduce run time configurable max_cstate for !CPU_IDLE case + * core dump: real_parent ppid + * acct: real_parent ppid + * IB/mlx4: Fix value of pkey_index in QP1 completions + * IB/srp: Release transport before removing host + * x86: fix do_fork_idle section mismatch + * spi_bitbang: always grab lock with irqs blocked + * fat: optimize fat_count_free_clusters() + * KEYS: fix macro + * md: fix data corruption when a degraded raid5 array is reshaped + * xip: fix get_zeroed_page with __GFP_HIGHMEM + * eCryptfs: fix dentry handling on create error, unlink, and inode + destroy + * vmcoreinfo: add the array length of "free_list" for filtering free + pages + * dmi-id: fix for __you_cannot_kmalloc_that_much failure + * snd_mixer_oss_build_input(): fix for __you_cannot_kmalloc_that_much + failure with gcc-3.2 + * Fix crash with FLAT_MEMORY and ARCH_PFN_OFFSET != 0 + * hfs: handle more on-disk corruptions without oopsing + * pl2303: Fix mode switching regression + * futex: Prevent stale futex owner when interrupted/timeout + * [NIU]: Fix slowpath interrupt handling. + * [NIU]: Missing ->last_rx update. + * [NIU]: Fix potentially stuck TCP socket send queues. + * [NIU]: Update driver version and release date. + * [IPV4] raw: Strengthen check on validity of iph->ihl + * [IPV4] ipconfig: Fix regression in ip command line processing + * [NET]: Fix netx-eth.c compilation. + * [METH]: Fix MAC address handling. + * [TULIP]: NAPI full quantum bug. + * [ATM]: [nicstar] delay irq setup until card is configured + * [SCTP]: Fix the name of the authentication event. + * [SCTP]: Correctly handle AUTH parameters in unexpected INIT + * [SCTP]: Add back the code that accounted for FORWARD_TSN parameter in + INIT. + * [IRDA]: irda_create() nuke user triggable printk + * b43: Fix rxheader channel parsing + * [NET]: Do not grab device reference when scheduling a NAPI poll. + * [NET]: Add NAPI_STATE_DISABLE. + * [NET]: Do not check netif_running() and carrier state in ->poll() + * ssb: Fix probing of PCI cores if PCI and PCIE core is available + * mac80211: return an error when SIWRATE doesn't match any rate + * [NETXEN]: Fix ->poll() done logic. + * [NET]: Fix drivers to handle napi_disable() disabling interrupts. + * [NET]: Stop polling when napi_disable() is pending. + * [NET]: Make ->poll() breakout consistent in Intel ethernet drivers. + * [NET] Intel ethernet drivers: update MAINTAINERS + * [NET]: kaweth was forgotten in msec switchover of usb_start_wait_urb + * [IPV4] ROUTE: ip_rt_dump() is unecessary slow + * [NET]: Clone the sk_buff 'iif' field in __skb_clone() + * [LRO] Fix lro_mgr->features checks + * [NET]: mcs7830 passes msecs instead of jiffies to usb_control_msg + * [FORCEDETH]: Fix reversing the MAC address on suspend. + * [XFRM]: xfrm_algo_clone() allocates too much memory + * [SOCK]: Adds a rcu_dereference() in sk_filter + * [CONNECTOR]: Don't touch queue dev after decrement of ref count. + * [IPV6]: IPV6_MULTICAST_IF setting is ignored on link-local connect() + * [ATM]: Check IP header validity in mpc_send_packet + * show_task: real_parent + * [SCSI] qla1280: fix 32 bit segment code + * [NIU]: Support for Marvell PHY + * [NEIGH]: Fix race between neigh_parms_release and neightbl_fill_parms + * [IPV4] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache + * [AX25]: Kill user triggable printks. + * [ARM] pxa: silence warnings from cpu_is_xxx() macros + * [POWERPC] efika: add phy-handle property for fec_mpc52xx + * [ARM] vfp: fix fuitod/fsitod instructions + * [CRYPTO] padlock: Fix alignment fault in aes_crypt_copy + * rt2x00: Allow rt61 to catch up after a missing tx report + * rt2x00: Corectly initialize rt2500usb MAC + * rt2x00: Put 802.11 data on 4 byte boundary + * NFSv4: Give the lock stateid its own sequence queue + * sata_qstor: use hardreset instead of softreset + * libata-sff: PCI IRQ handling fix + * pata_pdc202xx_old: Further fixups + * pata_ixp4xx_cf: fix compilation introduced by ata_port_desc() + conversion + * libata-pmp: 4726 hates SRST + * libata-pmp: propagate timeout to host link + * libata: don't normalize UNKNOWN to NONE after reset + * Update kernel parameter document for libata DMA mode setting knobs. + * sata_sil24: prevent hba lockup when pass-through ATA commands are used + * ide: workaround suspend bug for ACPI IDE + * ide: fix cable detection for SATA bridges + * trm290: do hook dma_host_{on,off} methods (take 2) + * libata and starting/stopping ATAPI floppy devices + * ACPI : Not register gsi for PCI IDE controller in legacy mode + * ACPICA: fix acpi_serialize hang regression + * sh: Force __access_ok() to obey address space limit. + * [AX25] af_ax25: Possible circular locking. + * ACPI: apply quirk_ich6_lpc_acpi to more ICH8 and ICH9 + * [POWERPC] Fix CPU hotplug when using the SLB shadow buffer + * [BLUETOOTH]: rfcomm tty BUG_ON() code fix + * [BLUETOOTH]: Always send explicit hci_ll wake-up acks. + * [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache + * [VLAN]: nested VLAN: fix lockdep's recursive locking warning + * [MACVLAN]: Prevent nesting macvlan devices + * [NETFILTER]: ip6t_eui64: Fixes calculation of Universal/Local bit + * [NETFILTER]: xt_helper: Do not bypass RCU + * [XFS] fix unaligned access in readdir + * Don't blatt first element of prv in sg_chain() + * loop: fix bad bio_alloc() nr_iovec request + * block: fix blktrace timestamps + * blktrace: kill the unneeded initcall + * V4L/DVB (6999): ivtv: stick to udelay=10 after all + * V4L/DVB (7001): av7110: fix section mismatch + * [MIPS] Wrong CONFIG option prevents setup of DMA zone. + * [MIPS] pnx8xxx: move to clocksource + * [MIPS] Malta: Fix software reset on big endian + * [MIPS] Lasat: Fix built in separate object directory. + * [MIPS] Replace 40c7869b693b18412491fdcff64682215b739f9e kludge + * Pull bugzilla-5637 into release branch + * Pull bugzilla-8171 into release branch + * Pull bugzilla-8973 into release branch + * PM: ACPI and APM must not be enabled at the same time + * Pull bugzilla-9194 into release branch + * Pull bugzilla-9494 into release branch + * Pull bugzilla-9535 into release branch + * Pull bugzilla-9627 into release branch + * Pull bugzilla-9683 into release branch + * IDE: terminate ACPI DMI list + * cache invalidation error for buffered write + * ps3fb: prevent use after free of fb_info + * ps3fb: fix deadlock on kexec() + * [NETFILTER]: bridge: fix double POST_ROUTING invocation + * xircom_cb endianness fixes + * de4x5 fixes + * endianness noise in tulip_core + * netxen: update MAINTAINERS + * netxen: update driver version + * netxen: stop second phy correctly + * netxen: optimize tx handling + * netxen: fix byte-swapping in tx and rx + * 3c509: PnP resource management fix + * Fixed a small typo in the loopback driver + * ip1000: menu location change + * r8169: fix missing loop variable increment + * [usb netdev] asix: fix regression + * fs_enet: check for phydev existence in the ethtool handlers + * Use access mode instead of open flags to determine needed permissions + * sky2: large memory workaround. + * sky2: remove check for PCI wakeup setting from BIOS + * spidernet MAINTAINERship update + * pnpacpi: print resource shortage message only once + * Pull bugzilla-9535 into release branch + * [SPARC]: Make gettimeofday() monotonic again. + * [SPARC64]: Fix build with SPARSEMEM_VMEMMAP disabled. + * remove task_ppid_nr_ns + * knfsd: Allow NFSv2/3 WRITE calls to succeed when krb5i etc is used. + * Input: improve Kconfig help entries for HP Jornada devices + * [TOKENRING]: rif_timer not initialized properly + * modules: de-mutex more symbol lookup paths in the module code + * w1: decrement slave counter only in ->release() callback + * Kick CPUS that might be sleeping in cpus_idle_wait + * TPM: fix suspend and resume failure + * MAINTAINERS: email update and add missing entry + * quicklists: Only consider memory that can be used with GFP_KERNEL + * macintosh: fix fabrication of caplock key events + * scsi/qla2xxx/qla_os.c section fix + * cciss: section mismatch + * advansys: fix section mismatch warning + * hugetlbfs: fix quota leak + * s3c2410fb: fix incorrect argument type in resume function + * CRIS: define __ARCH_WANT_SYS_RT_SIGSUSPEND in unistd.h for CRIS + * CRIS v10: correct do_signal to fix oops and clean up signal handling in + general + * CRIS v10: kernel/time.c needs to include linux/vmstat.h to compile + * uvesafb: fix section mismatch warnings + * CRIS v10: driver for ds1302 needs to include cris-specific i2c.h + * OSS msnd: fix array overflows + * i2c-omap: Fix NULL pointer dereferencing + * i2c: Spelling fixes + * i2c: Driver IDs are optional + * i2c-sibyte: Fix an error path + * fix the "remove task_ppid_nr_ns" commit + * [MIPS] Kconfig fixes for BCM47XX platform + * [MIPS] Cobalt: Fix ethernet interrupts for RaQ1 + * [MIPS] Cobalt: Qube1 has no serial port so don't use it + * [MIPS] Cacheops.h: Fix typo. + * ata_piix: ignore ATA_DMA_ERR on vmware ich4 + * sata_sil24: fix stupid typo + * sata_sil24: freeze on non-dev errors reported via CERR + * libata: relocate sdev->manage_start_stop configuration + * [POWERPC] Fix boot failure on POWER6 + * x86: fix boot crash on HIGHMEM4G && SPARSEMEM + * x86: asm-x86/msr.h: pull in linux/types.h + * x86: fix RTC_AIE with CONFIG_HPET_EMULATE_RTC + * Fix ARM profiling/instrumentation configuration + * Fix Blackfin HARDWARE_PM support + * libata fixes for sparse-found problems + * [libata] pata_bf54x: checkpatch fixes + * [libata] core checkpatch fix + * libata: correct handling of TSS DVD + * [IA64] Fix unaligned handler for floating point instructions with base + update + * Linux 2.6.24-rc8 + * lockdep: fix internal double unlock during self-test + * lockdep: fix workqueue creation API lockdep interaction + * lockdep: more hardirq annotations for notify_die() + * hostap: section mismatch warning + * wireless/libertas support for 88w8385 sdio older revision + * ipw2200: fix typo in kerneldoc + * b43: fix use-after-free rfkill bug + * rt2x00: Fix ieee80211 payload alignment + * sysfs: make sysfs_lookup() return ERR_PTR(-ENOENT) on failed lookup + * sysfs: fix bugs in sysfs_rename/move_dir() + * Use access mode instead of open flags to determine needed permissions + (CVE-2008-0001) + * IB/ipath: Fix receiving UD messages with immediate data + * [NET]: Fix TX timeout regression in Intel drivers. + * [NIU]: Fix 1G PHY link state handling. + * [SPARC64]: Fix hypervisor TLB operation error reporting. + * Input: mousedev - handle mice that use absolute coordinates + * Input: usbtouchscreen - fix buffer overflow, make more egalax work + * Input: psmouse - fix potential memory leak in psmouse_connect() + * Input: psmouse - fix input_dev leak in lifebook driver + * Input: ALPS - fix sync loss on Acer Aspire 5720ZG + * ipg: balance locking in irq handler + * ipg: plug Tx completion leak + * ipg: fix queue stop condition in the xmit handler + * ipg: fix Tx completion irq request + * cpufreq: Initialise default governor before use + * hfs: fix coverity-found null deref + * pnpacpi: print resource shortage message only once (more) + * CRIS v10: vmlinux.lds.S: ix kernel oops on boot and use common defines + * mm: fix section mismatch warning in page_alloc.c + * jbd: do not try lock_acquire after handle made invalid + * alpha: fix conversion from denormal float to double + * #ifdef very expensive debug check in page fault path + * Fix unbalanced helper_lock in kernel/kmod.c + * fix wrong sized spinlock flags argument + * bonding: fix locking in sysfs primary/active selection + * bonding: fix ASSERT_RTNL that produces spurious warnings + * bonding: fix locking during alb failover and slave removal + * bonding: release slaves when master removed via sysfs + * bonding: Fix up parameter parsing + * bonding: fix lock ordering for rtnl and bonding_rwsem + * bonding: Don't hold lock when calling rtnl_unlock + * Documentation: add a guideline for hard_start_xmit method + * atl1: fix frame length bug + * S2io: Fixed synchronization between scheduling of napi with card reset + and close + * dscc4 endian fixes + * wan/lmc bitfields fixes + * sbni endian fixes + * 3c574, 3c515 bitfields abuse + * dl2k: BMCR_t fixes + * dl2k: ANAR, ANLPAR fixes + * dl2k: BMSR fixes + * dl2k: MSCR, MSSR, ESR, PHY_SCR fixes + * dl2k: the rest + * Replace cpmac fix + * [WATCHDOG] Revert "Stop looking for device as soon as one is found" + * [WATCHDOG] clarify watchdog operation in documentation + * x86: add support for the latest Intel processors to Oprofile + * Selecting LGUEST should turn on Guest support, as in 2.6.23. + * ARM: OMAP1: Keymap fix for f-sample and p2-sample + * ARM: OMAP1: Fix compile for board-nokia770 + * pata_pdc202xx_old: Fix crashes with ATAPI + * arch: Ignore arch/i386 and arch/x86_64 + * Remove bogus duplicate CONFIG_LGUEST_GUEST entry. + * [ARM] pxa: don't rely on r2 being preserved over a function call + * [ARM] 4748/1: dca: source drivers/dca/Kconfig in arch/arm/Kconfig to + fix warning + * rfkill: call rfkill_led_trigger_unregister() on error + * [IPV6]: Mischecked tw match in __inet6_check_established. + * [IPV4] fib_hash: fix duplicated route issue + * [IPV4] fib_trie: fix duplicated route issue + * [NET]: Fix interrupt semaphore corruption in Intel drivers. + * [IPV4] FIB_HASH : Avoid unecessary loop in fn_hash_dump_zone() + * [IPV6] ROUTE: Make sending algorithm more friendly with RFC 4861. + * [NETFILTER]: bridge-netfilter: fix net_device refcnt leaks + * [NEIGH]: Revert 'Fix race between neigh_parms_release and + neightbl_fill_parms' + * [IrDA]: af_irda memory leak fixes + * [ATM] atm/idt77105.c: Fix section mismatch. + * [ATM] atm/suni.c: Fix section mismatch. + * [AF_KEY]: Fix skb leak on pfkey_send_migrate() error + * [NET]: rtnl_link: fix use-after-free + * [IPV6]: ICMP6_MIB_OUTMSGS increment duplicated + * [IPV6]: RFC 2011 compatibility broken + * [ICMP]: ICMP_MIB_OUTMSGS increment duplicated + * selinux: fix memory leak in netlabel code + * [MIPS] SMTC: Fix build error. + * [MIPS] Malta: Fix reading the PCI clock frequency on big-endian + * tc35815: Use irq number for tc35815-mac platform device id + * keyspan: fix oops + * hrtimer: fix section mismatch + * timer: fix section mismatch + * CRIS: add missed local_irq_restore call + * s3c2410_fb: fix line length calculation + * Fix filesystem capability support + * sched: group scheduler, set uid share fix + * hwmon: (it87) request only Environment Controller ports + * W1: w1_therm.c ds18b20 decode freezing temperatures correctly + * W1: w1_therm.c is flagging 0C etc as invalid + * rcu: fix section mismatch + * Fix file references in documentation and Kconfig + * x86: GEODE fix a race condition in the MFGPT timer tick + * virtnet: remove double ether_setup + * virtio:simplify-config-mechanism + * virtio: An entropy device, as suggested by hpa. + * virtio: Export vring functions for modules to use + * virtio: Put the virtio under the virtualization menu + * virtio:pci-device + * Fix vring_init/vring_size to take unsigned long + * virtio:vring-kick-when-empty + * virtio:explicit-callback-disable + * virtio:net-flush-queue-on-init + * virtio:net-fix-xmit-skb-free-real + * Parametrize the napi_weight for virtio receive queue. + * Handle module unload Add the device release function. + * Update all status fields on driver unload + * Make virtio modules GPL + * Make virtio_pci license be GPL2+ + * Use Qumranet donated PCI vendor/device IDs + * virtio:more-interrupt-suppression + * Reboot Implemented + * lguest:reboot-fix + * introduce vcpu struct + * adapt lguest launcher to per-cpuness + * initialize vcpu + * per-cpu run guest + * make write() operation smp aware + * make hypercalls use the vcpu struct + * per-vcpu lguest timers + * per-vcpu interrupt processing. + * map_switcher_in_guest() per-vcpu + * make emulate_insn receive a vcpu struct. + * make registers per-vcpu + * replace lguest_arch with lg_cpu_arch. + * per-vcpu lguest task management + * makes special fields be per-vcpu + * make pending notifications per-vcpu + * per-vcpu lguest pgdir management + + -- Tim Gardner Thu, 17 Jan 2008 14:45:01 -0700 + +linux (2.6.24-4.7) hardy; urgency=low + + [Amit Kucheria] + + * Poulsbo: Add SD8686 and 8688 WLAN drivers + * Poulsbo: Mass update of patches to be identical to those on moblin + * SAUCE: make fc transport removal of target configurable OriginalAuthor: + Michael Reed sgi.com> OriginalLocation: + http://thread.gmane.org/gmane.linux.scsi/25318 Bug: 163075 + + [Fabio M. Di Nitto] + + * Fix handling of gcc-4.1 for powerpc and ia64 + + [Tim Gardner] + + * Re-engineered architecture specific linux-headers compiler version + dependencies. + * Doh! Changed header-depends to header_depends. + + -- Tim Gardner Fri, 11 Jan 2008 07:10:46 -0700 + +linux (2.6.24-4.6) hardy; urgency=low + + [Alessio Igor Bogani] + + * Fix -rt build FTBS. + + [Amit Kucheria] + + * LPIACOMPAT: Update thermal patches to be inline with lpia flavour + * Poulsbo: Add USB Controller patch and corresponding config change + + [Fabio M. Di Nitto] + + * Enable aoe and nbd modules on hppa Ignore: yes + * Fix ia64 build by using gcc-4.1 + + [Tim Gardner] + + * Enable JFFS2 LZO compression. + - LP: #178343 + * Remove IS_G33 special handling. + - LP: #174367 + * Enabled CONFIG_SECURITY_CAPABILITIES and + CONFIG_SECURITY_FILE_CAPABILITIES + - LP: #95089 + * Enabled CONFIG_TASKSTATS and CONFIG_TASK_IO_ACCOUNTING + * Turned CONFIG_SECURITY_FILE_CAPABILITIES back off. + * Enabled CONFIG_B43LEGACY=m + * Enabled CONFIG_SCSI_QLOGIC_1280=m + * Enabled CONFIG_FUSION=y for virtual + * USB bluetooth device 0x0e5e:0x6622 floods errors to syslog + - LP: #152689 + * Removed lpia from d-i. + * Added ia64 modules. + * Added hppa32/64 modules. + + [Upstream Kernel Changes] + + * DMI autoload dcdbas on all Dell systems. + * sched: fix gcc warnings + * leds: Fix leds_list_lock locking issues + * leds: Fix locomo LED driver oops + * x86: fix asm-x86/byteorder.h for userspace export + * x86: fix asm-x86/msr.h for user-space export + * fix lguest rmmod "bad pgd" + * slub: provide /proc/slabinfo + * [POWERPC] Fix build failure on Cell when CONFIG_SPU_FS=y + * slub: register slabinfo to procfs + * [SCSI] scsi_sysfs: restore prep_fn when ULD is removed + * Unify /proc/slabinfo configuration + * scsi: revert "[SCSI] Get rid of scsi_cmnd->done" + * restrict reading from /proc//maps to those who share ->mm or can + ptrace pid + * Fix kernel/ptrace.c compile problem (missing "may_attach()") + * hwmon: (w83627ehf) Be more careful when changing VID input level + * NFS: Fix a possible Oops in fs/nfs/super.c + * NFSv4: Fix circular locking dependency in nfs4_kill_renewd + * NFS: add newline to kernel warning message in auth_gss code + * NFSv4: nfs4_open_confirm must not set the open_owner as confirmed on + error + * NFSv4: Fix open_to_lock_owner sequenceid allocation... + * IB/srp: Fix list corruption/oops on module reload + * Console is utf-8 by default + * [IA64] Update Altix BTE error return status patch + * [IA64] Update Altix nofault code + * [X25]: Add missing x25_neigh_put + * [XFRM]: Do not define km_migrate() if !CONFIG_XFRM_MIGRATE + * [CASSINI]: Fix endianness bug. + * [CASSINI]: Revert 'dont touch page_count'. + * [CASSINI]: Program parent Intel31154 bridge when necessary. + * [CASSINI]: Set skb->truesize properly on receive packets. + * [CASSINI]: Fix two obvious NAPI bugs. + * [CASSINI]: Bump driver version and release date. + * [INET]: Fix netdev renaming and inet address labels + * [CONNECTOR]: Return proper error code in cn_call_callback() + * [ISDN] i4l: 'NO CARRIER' message lost after ldisc flush + * [ISDN]: i4l: Fix DLE handling for i4l-audio + * fix: using joysticks in 32 bit applications on 64 bit systems + * hda_intel suspend latency: shorten codec read + * CPU hotplug: fix cpu_is_offline() on !CONFIG_HOTPLUG_CPU + * Linux 2.6.24-rc7 + * PIE executable randomization (upstream cherry pick by kees) + + -- Tim Gardner Fri, 04 Jan 2008 07:15:47 -0700 + +linux (2.6.24-3.5) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: Fix rt preempt patchset version + * Updated README file for binary custom flavours + * Fix -rt build FTBS. + * rt: Update configuration files + + [Tim Gardner] + + * SAUCE: Add extra headers to linux-libc-dev + + [Upstream Kernel Changes] + + * [WATCHDOG] at32ap700x_wdt: add support for boot status and add fix for + silicon errata + * [WATCHDOG] Stop looking for device as soon as one is found + * [WATCHDOG] bfin_wdt, remove SPIN_LOCK_UNLOCKED + * [WATCHDOG] Sbus: cpwatchdog, remove SPIN_LOCK_UNLOCKED + * [WATCHDOG] IT8212F watchdog driver + * ACPI: acpiphp: Remove dmesg spam on device remove + * [WATCHDOG] ipmi: add the standard watchdog timeout ioctls + * [WATCHDOG] add Nano 7240 driver + * ACPI: battery: fix ACPI battery technology reporting + * [ARM] 4667/1: CM-X270 fixes + * [ARM] 4690/1: PXA: fix CKEN corruption in PXA27x AC97 cold reset code + * [IPV6] XFRM: Fix auditing rt6i_flags; use RTF_xxx flags instead of + RTCF_xxx. + * [IPV4]: Swap the ifa allocation with the"ipv4_devconf_setall" call + * [IPv4] ESP: Discard dummy packets introduced in rfc4303 + * [IPv6] ESP: Discard dummy packets introduced in rfc4303 + * [UM]: Fix use of skb after netif_rx + * [XTENSA]: Fix use of skb after netif_rx + * [S390]: Fix use of skb after netif_rx + * [BNX2]: Add PHY_DIS_EARLY_DAC workaround. + * [BNX2]: Fix RX packet rot. + * [BNX2]: Update version to 1.6.9. + * [NET]: Fix wrong comments for unregister_net* + * [VLAN]: Fix potential race in vlan_cleanup_module vs + vlan_ioctl_handler. + * [IPSEC]: Fix potential dst leak in xfrm_lookup + * V4L/DVB (6485): ivtv: fix compile warning + * V4L/DVB (6540): em28xx: fix failing autodetection after the reboot + * V4L/DVB (6542): Fix S-video mode on tvp5150 + * V4L/DVB (6579): Fix bug #8824: Correct support for Diseqc on tda10086 + * V4L/DVB (6581): Fix: avoids negative vma usage count + * V4L/DVB (6601): V4L: videobuf-core locking fixes and comments + * V4L/DVB (6602): V4L: Convert videobuf drivers to videobuf_stop + * V4L/DVB (6615): V4L: Fix VIDIOCGMBUF locking in saa7146 + * V4L/DVB (6629): zl10353: fix default adc_clock and TRL nominal rate + calculation + * V4L/DVB (6666): saa7134-alsa: fix period handling + * V4L/DVB (6684): Complement va_start() with va_end() + style fixes + * V4L/DVB (6686): saa7134: fix composite over s-video input on the Tevion + MD 9717 + * V4L/DVB (6690): saa7134: fix ignored interrupts + * V4L/DVB (6751): V4L: Memory leak! Fix count in videobuf-vmalloc mmap + * V4L/DVB (6746): saa7134-dvb: fix tuning for WinTV HVR-1110 + * V4L/DVB (6750): Fix in-kernel compilation for cxusb + * V4L/DVB (6733): DVB: Compile 3000MC-specific DIB code only for + CONFIG_DVB_DIB3000MC + * V4L/DVB (6794): Fix compilation when dib3000mc is compiled as a module + * NFS: Fix NFS mountpoint crossing... + * V4L/DVB (6796): ivtv/ section fix + * V4L/DVB (6797): bt8xx/ section fixes + * NFSv2/v3: Fix a memory leak when using -onolock + * V4L/DVB (6609): Re-adds lock safe videobuf_read_start + * i2c: Delete an outdated piece of documentation + * i2c-gpio: Initialize adapter class + * i2c: Add missing spaces in split log messages + * i2c/isp1301_omap: Build fix + * [SERIAL] sparc: Infrastructure to fix section mismatch bugs. + * NFS: Fix an Oops in NFS unmount + * sdhci: describe quirks + * sdhci: don't warn about sdhci 2.0 controllers + * sdhci: use PIO when DMA can't satisfy the request + * sdhci: support JMicron JMB38x chips + * mmc: remove unused 'mode' from the mmc_host structure + * IB/ehca: Return correct number of SGEs for SRQ + * IB/ehca: Serialize HCA-related hCalls if necessary + * ide-scsi: add ide_scsi_hex_dump() helper + * ide: add missing checks for control register existence + * ide: deprecate CONFIG_BLK_DEV_OFFBOARD + * ide: fix ide_scan_pcibus() error message + * ide: coding style fixes for drivers/ide/setup-pci.c + * ide: add /sys/bus/ide/devices/*/{model,firmware,serial} sysfs entries + * ide: DMA reporting and validity checking fixes (take 3) + * ide-cd: remove dead post_transform_command() + * pdc202xx_new: fix Promise TX4 support + * hpt366: fix HPT37x PIO mode timings (take 2) + * ide: remove dead code from __ide_dma_test_irq() + * ide: remove stale changelog from ide-disk.c + * ide: remove stale changelog from ide-probe.c + * ide: fix ->io_32bit race in set_io_32bit() + * MAINTAINERS: update the NFS CLIENT entry + * V4L/DVB (6803): buf-core.c locking fixes + * [SPARC64]: Fix two kernel linear mapping setup bugs. + * IB/ehca: Fix lock flag variable location, bump version number + * kbuild: re-enable Makefile generation in a new O=... directory + * V4L/DVB (6798): saa7134: enable LNA in analog mode for Hauppauge WinTV + HVR-1110 + * V4L/DVB (6814): Makefile: always enter video/ + * V4L/DVB (6819): i2c: fix drivers/media/video/bt866.c + * V4L/DVB (6820): s5h1409: QAM SNR related fixes + * ACPI: video_device_list corruption + * ACPI: fix modpost warnings + * ACPI: thinkpad-acpi: fix lenovo keymap for brightness + * Pull thinkpad-2.6.24 into release branch + * Pull battery-2.6.24 into release branch + * [POWERPC] Fix typo #ifdef -> #ifndef + * [POWERPC] Kill non-existent symbols from ksyms and commproc.h + * [POWRPC] CPM2: Eliminate section mismatch warning in cpm2_reset(). + * [POWERPC] 82xx: mpc8272ads, pq2fads: Update defconfig with + CONFIG_FS_ENET_MDIO_FCC + * [POWERPC] iSeries: don't printk with HV spinlock held + * [POWERPC] Fix rounding bug in emulation for double float operating + * [POWERPC] Make PS3_SYS_MANAGER default y, not m + * [MIPS] time: Set up Cobalt's mips_hpt_frequency + * [MIPS] Alchemy: fix PCI resource conflict + * [MIPS] Alchemy: fix off by two error in __fixup_bigphys_addr() + * [MIPS] Atlas, Malta: Don't free firmware memory on free_initmem. + * [MIPS] PCI: Make pcibios_fixup_device_resources ignore legacy + resources. + * [MIPS] time: Delete weak definition of plat_time_init() due to gcc bug. + * [MIPS] Ensure that ST0_FR is never set on a 32 bit kernel + * [SPARC32]: Silence sparc32 warnings on missing syscalls. + * Pull hotplug into release branch + * ACPI: SBS: Reset alarm bit + * ACPI: SBS: Ignore alarms coming from unknown devices + * ACPI: SBS: Return rate in mW if capacity in mWh + * Pull bugzilla-9362 into release branch + * sky2: RX lockup fix + * sundance fixes + * starfire VLAN fix + * e100: free IRQ to remove warningwhenrebooting + * hamachi endianness fixes + * drivers/net/sis190.c section fix + * drivers/net/s2io.c section fixes + * ucc_geth: minor whitespace fix + * net: smc911x: shut up compiler warnings + * Net: ibm_newemac, remove SPIN_LOCK_UNLOCKED + * ixgb: make sure jumbos stay enabled after reset + * [NETFILTER]: ctnetlink: set expected bit for related conntracks + * [NETFILTER]: ip_tables: fix compat copy race + * [XFRM]: Display the audited SPI value in host byte order. + * [NETFILTER]: xt_hashlimit should use time_after_eq() + * [TIPC]: Fix semaphore handling. + * [SYNCPPP]: Endianness and 64bit fixes. + * [NETFILTER]: bridge: fix missing link layer headers on outgoing routed + packets + * [ATM]: Fix compiler warning noise with FORE200E driver + * [IPV4]: Updates to nfsroot documentation + * [BRIDGE]: Assign random address. + * [IPV6]: Fix the return value of ipv6_getsockopt + * [IPV4]: Make tcp_input_metrics() get minimum RTO via tcp_rto_min() + * [AX25]: Locking dependencies fix in ax25_disconnect(). + * [SCTP]: Flush fragment queue when exiting partial delivery. + * [IRDA]: Race between open and disconnect in irda-usb. + * [IRDA]: mcs7780 needs to free allocated rx buffer. + * [IRDA]: irlmp_unregister_link() needs to free lsaps. + * [IRDA]: stir4200 fixes. + * [IRDA]: irda parameters warning fixes. + * [S390] pud_present/pmd_present bug. + * [ARM] 4710/1: Fix coprocessor 14 usage for debug messages via ICEDCC + * [ARM] 4694/1: IXP4xx: Update clockevent support for shutdown and resume + * kobject: fix the documentation of how kobject_set_name works + * tipar: remove obsolete module + * HOWTO: Change man-page maintainer address for Japanese HOWTO + * Add Documentation for FAIR_USER_SCHED sysfs files + * HOWTO: change addresses of maintainer and lxr url for Korean HOWTO + * add stable_api_nonsense.txt in korean + * HOWTO: update misspelling and word incorrected + * PCI: Restore PCI expansion ROM P2P prefetch window creation + * USB: sierra: fix product id + * usb-storage: Fix devices that cannot handle 32k transfers + * USB: cp2101: new device id + * USB: option: Bind to the correct interface of the Huawei E220 + * usb.h: fix kernel-doc warning + * USB: fix locking loop by avoiding flush_scheduled_work + * USB: use IRQF_DISABLED for HCD interrupt handlers + * USB: at91_udc: correct hanging while disconnecting usb cable + * usb: Remove broken optimisation in OHCI IRQ handler + * USB: revert portions of "UNUSUAL_DEV: Sync up some reported devices + from Ubuntu" + * ocfs2: fix exit-while-locked bug in ocfs2_queue_orphans() + * ocfs2: Don't panic when truncating an empty extent + * ocfs2: Allow for debugging of transaction extends + * ocfs2: Re-journal buffers after transaction extend + * pcnet_cs: add new id + * ucc_geth: really fix section mismatch + * sis190 endianness + * libertas: add Dan Williams as maintainer + * zd1211rw: Fix alignment problems + * wireless/ipw2200.c: add __dev{init,exit} annotations + * ieee80211_rate: missed unlock + * iwlwifi3945/4965: fix rate control algo reference leak + * libertas: select WIRELESS_EXT + * bcm43xx_debugfs sscanf fix + * b43: Fix rfkill radio LED + * iwlwifi: fix rf_kill state inconsistent during suspend and resume + * sata_sil: fix spurious IRQ handling + * libata: clear link->eh_info.serror from ata_std_postreset() + * libata: add ST3160023AS / 3.42 to NCQ blacklist + * sata_mv: improve warnings about Highpoint RocketRAID 23xx cards + * libata-acpi: adjust constness in ata_acpi_gtm/stm() parameters + * libata: update ata_*_printk() macros such that level can be a variable + * libata: add more opcodes to ata.h + * libata: ata_dev_disable() should be called from EH context + * libata-acpi: add new hooks ata_acpi_dissociate() and + ata_acpi_on_disable() + * libata-acpi: implement and use ata_acpi_init_gtm() + * libata-acpi: implement dev->gtf_cache and evaluate _GTF right after + _STM during resume + * libata-acpi: improve ACPI disabling + * libata-acpi: improve _GTF execution error handling and reporting + * libata-acpi: implement _GTF command filtering + * libata: update atapi_eh_request_sense() such that lbam/lbah contains + buffer size + * libata: fix ATAPI draining + * fix headers_install + * revert "Hibernation: Use temporary page tables for kernel text mapping + on x86_64" + * uml: stop gdb from deleting breakpoints when running UML + * alpha: strncpy/strncat fixes + * rtc-at32ap700x: fix irq init oops + * parport: "dev->timeslice" is an unsigned long, not an int + * ecryptfs: initialize new auth_tokens before teardown + * Fix lguest documentation + * sparsemem: make SPARSEMEM_VMEMMAP selectable + * fs/Kconfig: grammar fix + * ext3, ext4: avoid divide by zero + * alpha: build fixes + * cpufreq: fix missing unlocks in cpufreq_add_dev error paths. + * mm/sparse.c: check the return value of sparse_index_alloc() + * mm/sparse.c: improve the error handling for sparse_add_one_section() + * pktcdvd: add kobject_put when kobject register fails + * drivers/macintosh/via-pmu.c: Added a missing iounmap + * drivers/cpufreq/cpufreq_stats.c section fix + * apm_event{,info}_t are userspace types + * mm: fix page allocation for larger I/O segments + * ecryptfs: set s_blocksize from lower fs in sb + * I/OAT: fixups from code comments + * I/OAT: fix null device in call to dev_err() + * fix bloat-o-meter for ppc64 + * ecryptfs: fix fsx data corruption problems + * Documentation: update hugetlb information + * Fix compilation warning in dquot.c + * SLUB: remove useless masking of GFP_ZERO + * quicklist: Set tlb->need_flush if pages are remaining in quicklist 0 + * sysctl: fix ax25 checks + * [XFS] Don't wait for pending I/Os when purging blocks beyond eof. + * [XFS] Put the correct offset in dirent d_off + * block: use jiffies conversion functions in scsi_ioctl.c + * as-iosched: fix incorrect comments + * as-iosched: fix write batch start point + * block: let elv_register() return void + * Cleanup umem driver: fix most checkpatch warnings, conform to kernel + * sched: fix crash on ia64, introduce task_current() + * sched: mark rwsem functions as __sched for wchan/profiling + * sched: sysctl, proc_dointvec_minmax() expects int values for + * sched: touch softlockup watchdog after idling + * sched: do not hurt SCHED_BATCH on wakeup + * oprofile: op_model_athlon.c support for AMD family 10h barcelona + performance counters + * clockevents: fix reprogramming decision in oneshot broadcast + * genirq: add unlocked version of set_irq_handler() + * timer: kernel/timer.c section fixes + * x86: jprobe bugfix + * x86: kprobes bugfix + * x86: also define AT_VECTOR_SIZE_ARCH + * genirq: revert lazy irq disable for simple irqs + * x86: fix "Kernel panic - not syncing: IO-APIC + timer doesn't work!" + * [SCSI] sym53c8xx: fix free_irq() regression + * [SCSI] dpt_i2o: driver is only 32 bit so don't set 64 bit DMA mask + * [SCSI] sym53c8xx: fix "irq X: nobody cared" regression + * [SCSI] initio: fix conflict when loading driver + * [SCSI] st: fix kernel BUG at include/linux/scatterlist.h:59! + * [SCSI] initio: bugfix for accessors patch + * IA64: Slim down __clear_bit_unlock + * [IA64] signal: remove redundant code in setup_sigcontext() + * [IA64] ia32 nopage + * [IA64] Avoid unnecessary TLB flushes when allocating memory + * [IA64] Two trivial spelling fixes + * [IA64] print kernel release in OOPS to make kerneloops.org happy + * [IA64] set_thread_area fails in IA32 chroot + * [IA64] Remove compiler warinings about uninitialized variable in + irq_ia64.c + * [IA64] Remove assembler warnings on head.S + * [IA64] Fix Altix BTE error return status + * [IA64] Guard elfcorehdr_addr with #if CONFIG_PROC_FS + * [IA64] make flush_tlb_kernel_range() an inline function + * [IA64] Adjust CMCI mask on CPU hotplug + * Do dirty page accounting when removing a page from the page cache + * x86 apic_32.c section fix + * x86 smpboot_32.c section fixes + * x86_32: select_idle_routine() must be __cpuinit + * x86_32: disable_pse must be __cpuinitdata + * x86: fix show cpuinfo cpu number always zero + * ps3fb: Update for firmware 2.10 + * ps3fb: Fix ps3fb free_irq() dev_id + * pata_hpt37x: Fix HPT374 detection + * mac80211: Drop out of associated state if link is lost + * mac80211: fix header ops + * NET: mac80211: fix inappropriate memory freeing + * [TG3]: Endianness annotations. + * [TG3]: Endianness bugfix. + * rtl8187: Add USB ID for Sitecom WL-168 v1 001 + * p54: add Kconfig description + * iwlwifi: fix possible priv->mutex deadlock during suspend + * ipw2200: prevent alloc of unspecified size on stack + * [IPV4] ARP: Remove not used code + * [IPSEC]: Avoid undefined shift operation when testing algorithm ID + * [XFRM]: Audit function arguments misordered + * [IPV4] ip_gre: set mac_header correctly in receive path + * [NET]: Correct two mistaken skb_reset_mac_header() conversions. + * [SPARC64]: Fix OOPS in dma_sync_*_for_device() + * sched: rt: account the cpu time during the tick + * debug: add end-of-oops marker + * mm: fix exit_mmap BUG() on a.out binary exit + * dm: table detect io beyond device + * dm mpath: hp requires scsi + * dm crypt: fix write endio + * dm: trigger change uevent on rename + * dm: merge max_hw_sector + * dm crypt: use bio_add_page + * [SPARC64]: Spelling fixes + * [SPARC32]: Spelling fixes + * [NET] include/net/: Spelling fixes + * [DCCP]: Spelling fixes + * [IRDA]: Spelling fixes + * [IPV6]: Spelling fixes + * [NET] net/core/: Spelling fixes + * [PKT_SCHED]: Spelling fixes + * [NETLABEL]: Spelling fixes + * [SCTP]: Spelling fixes + * [NETFILTER]: Spelling fixes + * [NETFILTER] ipv4: Spelling fixes + * [ATM]: Spelling fixes + * [NET]: Fix function put_cmsg() which may cause usr application memory + overflow + * x86: fix die() to not be preemptible + * x86: intel_cacheinfo.c: cpu cache info entry for Intel Tolapai + * [XFS] Fix mknod regression + * [XFS] Initialise current offset in xfs_file_readdir correctly + * Linux 2.6.24-rc6 + * [IPV4]: OOPS with NETLINK_FIB_LOOKUP netlink socket + * SLUB: Improve hackbench speed + * typhoon: endianness bug in tx/rx byte counters + * typhoon: missing le32_to_cpu() in get_drvinfo + * typhoon: set_settings broken on big-endian + * typhoon: missed rx overruns on big-endian + * typhoon: memory corruptor on big-endian if TSO is enabled + * typhoon: trivial endianness annotations + * cycx: annotations and fixes (.24 fodder?) + * asix fixes + * yellowfin: annotations and fixes (.24 fodder?) + * dl2k endianness fixes (.24 fodder?) + * r8169 endianness + * rrunner: use offsetof() instead of homegrown insanity + * 3c574 and 3c589 endianness fixes (.24?) + * fec_mpc52xx: write in C... + * 3c359 endianness annotations and fixes + * MACB: clear transmit buffers properly on transmit underrun + * UIO: Add a MAINTAINERS entry for Userspace I/O + * Modules: fix memory leak of module names + * USB: Unbreak fsl_usb2_udc + * USB: VID/PID update for sierra + * USB: New device ID for the CP2101 driver + * quicklists: do not release off node pages early + * ecryptfs: fix string overflow on long cipher names + * Fix computation of SKB size for quota messages + * Don't send quota messages repeatedly when hardlimit reached + * ecryptfs: fix unlocking in error paths + * ecryptfs: redo dget,mntget on dentry_open failure + * MAINTAINERS: mailing list archives are web links + * ps3: vuart: fix error path locking + * lib: proportion: fix underflow in prop_norm_percpu() + * pcmcia: remove pxa2xx_lubbock build warning + * kconfig: obey KCONFIG_ALLCONFIG choices with randconfig. + * tty: fix logic change introduced by wait_event_interruptible_timeout() + * uml: user of helper_wait() got missed when it got extra arguments + * V4L/DVB (6871): Kconfig: VIDEO_CX23885 must select DVB_LGDT330X + * V4L/DVB (6876): ivtv: mspx4xx needs a longer i2c udelay + * drivers/ide/: Spelling fixes + * ide-cd: fix SAMSUNG CD-ROM SCR-3231 quirk + * ide-cd: fix ACER/AOpen 24X CDROM speed reporting on big-endian machines + * ide-cd: use ide_cd_release() in ide_cd_probe() + * ide-cd: fix error messages in cdrom_{read,write}_check_ireason() + * ide-cd: add missing 'ireason' masking to cdrom_write_intr() + * ide-cd: fix error messages in cdrom_write_intr() + * ide-cd: add error message for DMA error to cdrom_read_intr() + * ide-cd: fix error message in cdrom_pc_intr() + * ide-cd: fix 'ireason' reporting in cdrom_pc_intr() + * MAINTAINERS: update ide-cd entry + * [SPARC64]: Implement pci_resource_to_user() + * mac80211: round station cleanup timer + * mac80211: warn when receiving frames with unaligned data + * [NETFILTER]: nf_conntrack_ipv4: fix module parameter compatibility + * [TUNTAP]: Fix wrong debug message. + * [NET] tc_nat: header install + * [VETH]: move veth.h to include/linux + * [IPV4]: Fix ip command line processing. + * Revert quicklist need->flush fix + * [CRYPTO] padlock: Fix spurious ECB page fault + * [POWERPC] Oprofile: Remove dependency on spufs module + * [POWERPC] PS3: Fix printing of os-area magic numbers + * [PCI] Do not enable CRS Software Visibility by default + * [IPV4] Fix ip=dhcp regression + * [SERIAL]: Fix section mismatches in Sun serial console drivers. + * [TCP]: use non-delayed ACK for congestion control RTT + * [BLUETOOTH]: put_device before device_del fix + + -- Tim Gardner Sat, 22 Dec 2007 15:16:11 -0700 + +linux (2.6.24-2.4) hardy; urgency=low + + [Alessio Igor Bogani] + + * rt: First import for Hardy + + [Amit Kucheria] + + * LPIA: Fix FTBFS for hda + * LPIA: Trim configs including disabling stock DRM + + [Tim Gardner] + + * SAUCE: Increase CONFIG_IDE_MAX_HWIFS to 8 (from 4) + - LP: #157909 + Then reverted since it causes an ABI bump. Will pick it up + again when next the ABI changes. + * Expose apm for applications. + + -- Tim Gardner Wed, 19 Dec 2007 13:17:31 -0700 + +linux (2.6.24-2.3) hardy; urgency=low + + [Amit Kucheria] + + * LPIA: Add thermal framework from Intel + * LPIA: Poulsbo-specific patches + * LPIA: Add thermal framework from Intel + + [Tim Gardner] + + * SAUCE: hdaps module does not load on Thinkpad T61P + - LP: #133636 + + [Upstream Kernel Changes] + + * Rebased against 2.6.24-rc5 + + -- Tim Gardner Wed, 12 Dec 2007 13:58:52 -0700 + +linux (2.6.24-1.2) hardy; urgency=low + + [Ben Collins] + + * cell: Remove cell custom flavour, merged upstream + * apparmor: Added module from SVN repo + * ubuntu: Update configs to enable apparmor + * ubuntu/configs: Disable vga type framebuffers on hppa32. Fixes FTBFS + + [Tim Gardner] + + * Add support for PPA builds. + + [Upstream Kernel Changes] + + * [SPARC64] Export symbols for sunvnet and sunvdc to be built modular + + -- Ben Collins Fri, 07 Dec 2007 15:18:32 -0500 + +linux (2.6.24-1.1) hardy; urgency=low + + [Ben Collins] + + * ubuntu: Disable custom binary flavours for now + * ubuntu: Remove cruft in headers-postinst + * ubuntu: Set skipabi/skipmodule to true if prev_revions == 0.0 + * ubuntu: Do not fail on missing module lists when skipmodule is set + * ubuntu: capability.ko is built-in now, no need to place in initrd. + * ubuntu: Change to "linux" instead of "linux-source-2.6.x" + * d-i: cdrom-modules disappeared, and sha256/aes modules renamed. + * ubuntu-build: Add asm_link= to arch rules, and use them + * config: Re-enable snd-hda-intel + + -- Ben Collins Wed, 28 Nov 2007 12:58:37 -0500 + +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-2.6.28.orig/debian/copyright +++ linux-2.6.28/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-2.6.28.orig/debian/control.stub.in +++ linux-2.6.28/debian/control.stub.in @@ -0,0 +1,70 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), makedumpfile [!armel] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils +Vcs-Git: http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-jaunty.git + +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. + . + This package is mainly meant for other packages to use, in order to build + custom flavours. + . + 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: i386 amd64 armel +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), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers +Provides: 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. They are NOT meant to be used to build third-party modules for + your kernel. Use linux-headers-* packages for that. --- linux-2.6.28.orig/debian/control +++ linux-2.6.28/debian/control @@ -0,0 +1,420 @@ +Source: linux +Section: devel +Priority: optional +Maintainer: Ubuntu Kernel Team +Standards-Version: 3.6.1 +Build-Depends: debhelper (>= 3), module-init-tools, kernel-wedge (>= 2.24ubuntu1), makedumpfile [!armel] +Build-Depends-Indep: xmlto, docbook-utils, gs, transfig, bzip2, sharutils +Vcs-Git: http://kernel.ubuntu.com/git-repos/ubuntu/ubuntu-jaunty.git + +Package: linux-source-2.6.28 +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.28 with Ubuntu patches + This package provides the source code for the Linux kernel version + 2.6.28. + . + This package is mainly meant for other packages to use, in order to build + custom flavours. + . + 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.28 +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.28 + This package provides the various readme's in the 2.6.28 kernel + Documentation/ subdirectory: these typically contain kernel-specific + installation notes for some drivers for example. See + /usr/share/doc/linux-doc-2.6.28/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.28-4 +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.28 + This package provides kernel header files for version 2.6.28, for sites + that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details + +Package: linux-libc-dev +Architecture: i386 amd64 armel +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), linux-kernel-headers +Replaces: libc6-dev (<< 2.3.2.ds1-6), libc6.1-dev (<< 2.3.2.ds1-6), dvb-dev (<< 1.0.1-6), linux-kernel-headers +Provides: 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. They are NOT meant to be used to build third-party modules for + your kernel. Use linux-headers-* packages for that. + +Package: linux-image-2.6.28-4-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, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 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.28-4-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-generic +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-iop32x +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IOP32x-based systems + This package contains the Linux kernel image for version 2.6.28 on + IOP32x-based systems. + . + 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 IOP32x processors. + . + Thecus N2100, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-iop32x meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-iop32x +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IOP32x-based systems + This package provides kernel header files for version 2.6.28 on + IOP32x-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-iop32x +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IOP32x-based systems + This package provides a kernel debug image for version 2.6.28 on + IOP32x-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-ixp4xx +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on IXP4xx-based systems + This package contains the Linux kernel image for version 2.6.28 on + IXP4xx-based systems. + . + 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 IXP4xx processors. + . + Linksys NSLU2, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-ixp4xx meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on IXP4xx-based systems + This package provides kernel header files for version 2.6.28 on + IXP4xx-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-ixp4xx +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on IXP4xx-based systems + This package provides a kernel debug image for version 2.6.28 on + IXP4xx-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-orion5x +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Orion5x-based systems + This package contains the Linux kernel image for version 2.6.28 on + Orion5x-based systems. + . + 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 Orion 5181, 5182 and 5281 processors. + . + QNAP TS-109/TS-209, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-orion5x meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-orion5x +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Orion5x-based systems + This package provides kernel header files for version 2.6.28 on + Orion5x-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-orion5x +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Orion5x-based systems + This package provides a kernel debug image for version 2.6.28 on + Orion5x-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-server +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules, kvm-api-4, ivtv-modules, ndiswrapper-modules-1.9 +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 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.28-4-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on x86/x86_64 + This package provides kernel header files for version 2.6.28 on + x86/x86_64. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-server +Architecture: i386 amd64 +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on x86/x86_64 + This package provides a kernel debug image for version 2.6.28 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-versatile +Architecture: armel +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1) +Recommends: +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on Versatile-based systems + This package contains the Linux kernel image for version 2.6.28 on + Versatile-based systems. + . + 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 Versatile processors. + . + PB, AB, Qemu, etc. + . + You likely do not want to install this package directly. Instead, install + the linux-versatile meta-package, which will ensure that upgrades work + correctly, and that supporting packages are also installed. + +Package: linux-headers-2.6.28-4-versatile +Architecture: armel +Section: devel +Priority: optional +Depends: coreutils | fileutils (>= 4.0), linux-headers-2.6.28-4, ${shlibs:Depends} +Provides: linux-headers, linux-headers-2.6 +Description: Linux kernel headers for version 2.6.28 on Versatile-based systems + This package provides kernel header files for version 2.6.28 on + Versatile-based systems. + . + This is for sites that want the latest kernel headers. Please read + /usr/share/doc/linux-headers-2.6.28-4/debian.README.gz for details. + +Package: linux-image-debug-2.6.28-4-versatile +Architecture: armel +Section: devel +Priority: optional +Provides: linux-debug +Description: Linux kernel debug image for version 2.6.28 on Versatile-based systems + This package provides a kernel debug image for version 2.6.28 on + Versatile-based systems. + . + 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. This package also includes the + unstripped modules. + +Package: linux-image-2.6.28-4-virtual +Architecture: i386 amd64 +Section: base +Priority: optional +Pre-Depends: dpkg (>= 1.10.24) +Provides: linux-image, linux-image-2.6, fuse-module, redhat-cluster-modules +Depends: initramfs-tools (>= 0.36ubuntu6), coreutils | fileutils (>= 4.0), module-init-tools (>= 3.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1), linux-image-2.6.28-4-server +Recommends: grub | lilo (>= 19.1) +Suggests: fdutils, linux-doc-2.6.28 | linux-source-2.6.28 +Description: Linux kernel image for version 2.6.28 on x86/x86_64 + This package contains the Linux kernel image for version 2.6.28 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 Virtual processors. + . + Geared toward virtual machine guests. + . + 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. --- linux-2.6.28.orig/debian/changelog +++ linux-2.6.28/debian/changelog @@ -0,0 +1,2823 @@ +linux (2.6.28-4.10) jaunty; urgency=low + + [ Andy Whitcroft ] + + * update kernel bootloader recommends: to prefer grub + - LP: #314004 + * SAUCE: don't use buggy _BCL/_BCM/_BQC for backlight control + - LP: #311716 + * SAUCE: test-suspend -- add the suspend test scripts + - LP: #316419 + + [ Colin Watson ] + + * Enable udebs for armel + + [ Tim Gardner ] + + * SAUCE: Dell laptop digital mic does not work, PCI 1028:0271 + - LP: #309508 + * Enable CIFS_XATTR=y and CONFIG_CIFS_POSIX=y + - LP: #220658 + + -- Tim Gardner Thu, 08 Jan 2009 10:38:22 -0700 + +linux (2.6.28-4.9) jaunty; urgency=low + + [ Tim Gardner ] + + * Restore DM_CRYPT, AES, ECB, and CBC as modules. This fixes + some installer issues with encrypted /home and Private directories. + * Take one more stab at building armel without module or ABI errors. + + -- Tim Gardner Tue, 06 Jan 2009 08:38:23 -0700 + +linux (2.6.28-4.8) jaunty; urgency=low + + * Fix i386/amd64 FTBS by ignoring all module and ABI changes, + not something you would normally do, but I'm sure the ABI + has not changed. This will probably also allow the ARM builds to complete. + + -- Tim Gardner Mon, 05 Jan 2009 14:42:58 -0700 + +linux (2.6.28-4.7) jaunty; urgency=low + + [ Tim Gardner ] + + * Enable CONFIG_ATH5K=m for i386/amd64 + - LP: #306719 + * Build all i386/amd64 AGP/DRM components as modules. + - LP: #312721 + * git commands are now installed outside the default $PATH + Use 'git CMD' instead of 'git-CMD'. + * Build in most PATA/SATA drivers. This should allow most i386/amd64 systems to boot + without an initramfs, though some support work is still required in initramfs-tools + and grub. + - LP: #311730 + + -- Tim Gardner Fri, 02 Jan 2009 07:33:09 -0700 + +linux (2.6.28-4.6) jaunty; urgency=low + + [ Tim Gardner ] + + * Enable CONFIG_X86_E_POWERSAVER=m for i386 generic + - LP: #237405 + * Build i386 AGP drivers as modules + - LP: #312721 + * Build i386 DRM as a module + - LP: #312721 + + [ Upstream Kernel Changes ] + + * drm/i915: Add missing userland definitions for gem init/execbuffer. + - LP: #308387 + + -- Tim Gardner Mon, 29 Dec 2008 09:16:47 -0700 + +linux (2.6.28-4.5) jaunty; urgency=low + + [ Andy Whitcroft ] + + * clean up module dependancy information on package removal/purge + - LP: #300773 + + [ Tim Gardner ] + + * Update iscsitarget to 0.4.17 + * Build in ext{234} + * Build in Crypto modules AES, CBC, ECB + * Build in ACPI AC,BATTERY,BUTTON,FAN,PCI_SLOT,PROCESSOR,SBS,THERMAL,WMI + * Build in AGP intel,via,sis,ali,amd,amd64,efficeon,nvidia,sworks + * Build in ata,dev_dm,dev_loop,dev_md,dev_sd,dev_sr + * Build in BT l2cap,rfcomm,sco + * Reduce CONFIG_LEGACY_PTY_COUNT to 0 + * Build in CDROM_PKTCDVD and CHR_DEV_SG + * Build in CPU_FREQ + GOV_CONSERVATIVE,GOV_ONDEMAND,GOV_POWERSAVE,GOV_USERSPACE,STAT,TABLE + * Build in DM CRYPT,MIRROR,MULTIPATH,SNAPSHOT + * Build in DRM + * Build in HID + * Build in HOTPLUG PCI,PCIE + * Build in I2C + * Build in IEEE1394 OHCI1394 + * Build in INPUT EVDEV + * Build in IPV6 + * Build in MMC + * Build in PACKET + * Enable both IEEE1394 (Firewire) stacks as modules + - LP: #276463 + * Disable SUNRPC_REGISTER_V4 + - LP: #306016 + * Enable dm-raid4-5 + - LP: #309378 + * Build in PPP + * Build in RFKILL + * Build in USB SERIAL + + [ Upstream Kernel Changes ] + + * Rebased to v2.6.28 + + -- Tim Gardner Thu, 18 Dec 2008 21:18:44 -0700 + +linux (2.6.28-3.4) jaunty; urgency=low + + [ Tim Gardner ] + + * Build ecryptfs into the kernel + - LP: #302870 + * Deprecated gnbd + + [ Upstream Kernel Changes ] + + * Rebased to v2.6.28-rc8 + + -- Tim Gardner Wed, 10 Dec 2008 22:45:13 -0700 + +linux (2.6.28-2.3) jaunty; urgency=low + + [ Andy Whitcroft ] + + * update the templates so that we have spaces following the title line + + [ Tim Gardner ] + + * Add upload number to kernel version signature. This has the side effect + of renaming kernel packages back to the original way, e.g., without '-ub' + in the name. + + -- Tim Gardner Thu, 04 Dec 2008 12:18:31 -0700 + +linux (2.6.28-2.2) jaunty; urgency=low + + [ Andy Whitcroft ] + + * Revert "SAUCE: (no-up) version: Implement version_signature proc file." + * SAUCE: (no-up) version: Implement version_signature proc file. + * SAUCE: serial: RS485 ioctl structure uses __u32 include linux/types.h + - LP: #303711 + + [ Tim Gardner ] + + * UBUNTU: Removed CONFIG_DRM_VIA_CHROME9 since it is upstream. + * UBUNTU: Removed ubuntu/via_chrome9 + + [ Upstream Kernel Changes ] + + * Rebased to v2.6.28-rc7 + + -- Tim Gardner Tue, 02 Dec 2008 07:33:32 -0700 + +linux (2.6.28-1.1) jaunty; urgency=low + + [ Amit Kucheria ] + + * SAUCE: make fc transport removal of target configurable + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + * SAUCE: Adds support for COMPAL JHL90 webcam + * Map armel to arm to all editconfigs to work correctly + * Add armel to getabis for completeness sake + * Add -ub to our versioning to allow kerneloops.org to identify us + + [ Andy Whitcroft ] + + * Fix Vcs-Git path for the kernel repository. + - LP: #296915 + + [ Ben Collins ] + + * SAUCE: Lower warning level of some PCI messages + - LP: #159241 + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: (no-up) version: Implement version_signature proc file. + * SAUCE: (no-up) connector.h: Add idx/val for drbd + * SAUCE: (no-up) swap: Add notify_swap_entry_free callback for compcache + * SAUCE: drivers: Remove some duplicate device entries in various modules + * SAUCE: (no-up) [AppArmor] merge with upstream subversion r1291 + * SAUCE: (no-up) Enable ubuntu extra subdirectory + * SAUCE: (no-up) ACPI: initramfs DSDT override support + * ubuntu: Add drbd module + * ubuntu: Add iscsitarget module + * ubuntu: Add BOM for iscsitarget + * ubuntu: Add squashfs driver + * SAUCE: (no-up) Check for squashfs superblock in initramfs mounting. + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Added et131x driver + * ubuntu: Add dm-raid4-5 driver + * ubuntu: Add ndiswrapper driver + * ubuntu: Added ram backed compressed swap module (compcache) + * ubuntu: Add misc drivers from hardy lum + * ubuntu: Add heci driver 3.2.0.24 + * ubuntu: Add ov511 and bt-sco drivers + * ubuntu: Add acx, prism2_usb wireless drivers + * ubuntu: Add at76 driver to build + * ubuntu: Add fsam7400 sw kill switch driver + * ubuntu: Added qc-usb driver + * ubuntu: e1000e: Upgraded module to 0.4.1.7 + * ubuntu: Added rfkill drivers + * ubuntu: VIA - Add VIA DRM Chrome9 3D engine + * ubuntu: unionfs: Added v1.4 module from hardy + * ubuntu: Add LIRC driver + * ubuntu: Add GFS driver + * ubuntu: New tlsup driver for toshiba laptops + * SAUCE: (no-up) Export lookup_has for aufs + * SAUCE: (no-up) Modularize vesafb + * ubuntu: Config files + * Disable some modules that need porting to 2.6.28 + * ubuntu: Fixup headers creation to include arch/*/include + * ubuntu/module-check: Ignore comment lines + + [ Chuck Short ] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + + [ cking ] + + * SAUCE: Enable speedstep for sonoma processors. + + [ Colin Ian King ] + + * ubuntu: Add dm-loop + * SAUCE: cx88: Support Leadtek WinFast DTV2000 H version J. + * SAUCE: fix kernel oops in VirtualBox during paravirt patching + * SAUCE: qc-usb: Enable Logitech QuickCam Messenger + * SAUCE: appleir: Enable driver for new MacBook Pro + + [ Colin Watson ] + + * Enable configfs, fuse, jfs, reiserfs, and xfs for armel + * Extend debian/d-i/ modules handling to make armel easier to support + * Create udebs for armel + + [ Fabio M. Di Nitto ] + + * ubuntu: update GFS Cluster File System + + [ Kees Cook ] + + * SAUCE: AppArmor: update to upstream subversion r1302 + + [ Leann Ogasawara ] + + * Add automatic model setting for Samsung Q45 + * Add Dell Dimension 9200 reboot quirk + + [ Mackenzie Morgan ] + + * SAUCE: Add quirk for ASUS Z37E to make sound audible after resume + + [ Matthew Garrett ] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [ Michael Frey (Senior Manager, MID ] + + * SAUCE: Send HCI_RESET for Broadcomm 2046 + + [ Michael Haas ] + + * add proper aufs source tree from 20080922 + * Fix AUFS compilation in vfsub.c + * Add splice-2.6.23.patch from AUFS to export a symbol needed by AUFS + * Add put_filp.patch from AUFS to export a symbol needed by AUFS + * Add deny_write_access.patch from AUFS - export deny_write_access + * Add sec_perm-2.6.24.patch from AUFS - export security_inode_permission + * make sure TMPFS_MAGIC is defined in AUFS Makefile + * SAUCE: Revert aufs changes from AppArmor merge + + [ Mohamed Abbas ] + + * SAUCE: iwlagn -- fix rfkill when on when driver loaded + + [ Phillip Lougher ] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [ Stefan Bader ] + + * SAUCE: (no-up) Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: mmc: Increase power_up deleay to fix TI readers + * gfs1: GFS1 can't create more than 4kb file + * uvcvideo: Commit streaming parameters when enabling the video stream. + + [ Tim Gardner ] + + * SAUCE: Add extra headers to linux-libc-dev + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: (no-up) Take care of orinoco_cs overlap with hostap_cs + * ubuntu: Add GNBD driver + * SAUCE: e1000e: Map NV RAM dynamically only when needed. + * SAUCE: Correctly blacklist Thinkpad r40e in ACPI + * SAUCE: Update Wacom tablet driver to 1.49 + * SAUCE: Fix Wacom tablet 1.49 porting errors + * SAUCE: Enable an e1000e Intel Corporation 82567 Gigabit controller + * SAUCE: Fix Oops in wlan_setup + * SAUCE: ipw2200: change default policy for auto-associate + * Dell Wireless 365 needs BTUSB_RESET quirk. + * ndiswrapper remote buffer overflows on long ESSIDs (CVE 2008-4395) + * Disabled ubuntu/e1000e config + + [ Upstream Kernel Changes ] + + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + * Revert "x86, early_ioremap: fix fencepost error" + * mac80211: fix two issues in debugfs + * iwl3945: do not send scan command if channel count zero + + -- Ben Collins Fri, 07 Nov 2008 09:37:42 -0700 + +linux (2.6.27-8.17) intrepid-proposed; urgency=low + + [ John W. Linville ] + + * SAUCE: iwlagn: avoid sleep in softirq context + -LP: #286285 + + [ Tim Gardner ] + + * Dell Wireless 365 needs BTUSB_RESET quirk. + - LP: #293670 + * SAUCE: ALSA: hda: make a STAC_DELL_EQ option (version 2) + - LP: #293271 + + [ Upstream Kernel Changes ] + + * iwlagn: downgrade BUG_ON in interrupt + * Input: atkbd - expand Latitude's force release quirk to other Dells + * fbcon_set_all_vcs: fix kernel crash when switching the rotated consoles + * modules: fix module "notes" kobject leak + * Driver core: Fix cleanup in device_create_vargs(). + * Driver core: Clarify device cleanup. + * ath9k/mac80211: disallow fragmentation in ath9k, report to userspace + * md: Fix rdev_size_store with size == 0 + * xfs: fix remount rw with unrecognized options + * OHCI: Allow broken controllers to auto-stop + * USB: OHCI: fix endless polling behavior + * USB: Fix s3c2410_udc usb speed handling + * USB: EHCI: log a warning if ehci-hcd is not loaded first + * usb gadget: cdc ethernet notification bugfix + * usb: musb_hdrc build fixes + * drm/i915: fix ioremap of a user address for non-root (CVE-2008-3831) + * DVB: au0828: add support for another USB id for Hauppauge HVR950Q + * DVB: sms1xxx: support two new revisions of the Hauppauge WinTV + MiniStick + * security: avoid calling a NULL function pointer in + drivers/video/tvaudio.c + * Linux 2.6.27.3 + -LP: #294152 + + * gpiolib: fix oops in gpio_get_value_cansleep() + * edac cell: fix incorrect edac_mode + * x86 ACPI: fix breakage of resume on 64-bit UP systems with SMP kernel + * sched: fix the wrong mask_len + * USB: cdc-wdm: make module autoload work + * USB: don't rebind drivers after failed resume or reset + * USB: fix memory leak in cdc-acm + * USB: Speedtouch: add pre_reset and post_reset routines + * dm kcopyd: avoid queue shuffle + * dm snapshot: fix primary_pe race + * amd_iommu: fix nasty bug that caused ILLEGAL_DEVICE_TABLE_ENTRY errors + * CIFS: fix saving of resume key before CIFSFindNext + * netfilter: xt_iprange: fix range inversion match + * netfilter: snmp nat leaks memory in case of failure + * netfilter: restore lost ifdef guarding defrag exception + * anon_vma_prepare: properly lock even newly allocated entries + * hvc_console: Fix free_irq in spinlocked section + * ACPI Suspend: Enable ACPI during resume if SCI_EN is not set + * ACPI suspend: Blacklist HP xw4600 Workstation for old code ordering + * ACPI suspend: Always use the 32-bit waking vector + * proc: fix vma display mismatch between /proc/pid/{maps,smaps} + * SCSI: scsi_dh: add Dell product information into rdac device handler + * PCI hotplug: cpqphp: fix kernel NULL pointer dereference + * V4L/DVB (9300): pvrusb2: Fix deadlock problem + * Linux 2.6.27.4 + -LP: #294155 + + -- Tim Gardner Tue, 04 Nov 2008 12:16:07 -0700 + +linux (2.6.27-7.16) intrepid-security; urgency=low + + [ Tim Gardner ] + + * ndiswrapper remote buffer overflows on long ESSIDs (CVE 2008-4395) + - LP: #275860 + + [ Upstream Kernel Changes ] + + * ext[234]: Avoid printk floods in the face of directory corruption + (CVE-2008-3528) + + -- Tim Gardner Mon, 03 Nov 2008 13:34:42 -0700 + +linux (2.6.27-7.15) intrepid-security; urgency=low + + [ Upstream Kernel Changes ] + + * tcp: Restore ordering of TCP options for the sake of inter-operability + - LP: #264019 + + -- Tim Gardner Mon, 27 Oct 2008 19:28:06 -0600 + +linux (2.6.27-7.14) intrepid; urgency=low + + [ Tim Gardner ] + + * Disable ath5k in 2.6.27 + - LP: #288148 + + -- Tim Gardner Thu, 23 Oct 2008 07:40:43 -0600 + +linux (2.6.27-7.13) intrepid; urgency=low + + [ Stefan Bader ] + + * gfs1: GFS1 can't create more than 4kb file + + [ Tim Gardner ] + + * Revert "SAUCE: x86: Reserve FIRST_DEVICE_VECTOR in used_vectors + bitmap.". Use upstream commit to avoid future conflicts. + * Revert "STABLE queue: mac80211: fix two issues in debugfs". + Use upstream commit to avoid future conflicts. + * Revert "x86, early_ioremap: fix fencepost error" + Use upstream commit to avoid future conflicts. + + [ Upstream Kernel Changes ] + + * sched_rt.c: resch needed in rt_rq_enqueue() for the root rt_rq + * x86: Reserve FIRST_DEVICE_VECTOR in used_vectors bitmap. + * mac80211: fix two issues in debugfs + * Fix barrier fail detection in XFS + * tty: Termios locking - sort out real_tty confusions and lock reads + * CIFS: make sure we have the right resume info before calling + CIFSFindNext + * rfkill: update LEDs for all state changes + * libertas: clear current command on card removal + * b43legacy: Fix failure in rate-adjustment mechanism + * x86, early_ioremap: fix fencepost error + * x86: SB450: skip IRQ0 override if it is not routed to INT2 of IOAPIC + * x86: improve UP kernel when CPU-hotplug and SMP is enabled + * sky2: Fix WOL regression + * netdrvr: atl1e: Don't take the mdio_lock in atl1e_probe + * Linux 2.6.27.2 + + [ Amit Kucheria ] + + * Ubuntu: agp: Fix stolen memory counting on G4X. + -LP: 285572 + + [ Scott Remnant ] + + * add MODULE_ALIAS to load ipmi_devintf with ipmi_si + + -- Tim Gardner Sun, 19 Oct 2008 10:06:21 -0600 + +linux (2.6.27-7.12) intrepid; urgency=low + + [ Chuck Short ] + + * xen: Add xen modules to virtual flavours. + + [ Mario Limonciello ] + + * SAUCE: Add back in lost commit for Apple BT Wireless Keyboard + - LP: #162083 + + [ Tim Gardner ] + + * Remove depmod created files from packages. + - LP: #250511 + * Changed default TCP congestion algorithm to 'cubic' (again) + - LP: #278801 + * Update configs for 'disable CONFIG_DYNAMIC_FTRACE' + - LP: #263555 + + [ Upstream Kernel Changes ] + + * x86: register a platform RTC device if PNP doesn't describe it + * disable CONFIG_DYNAMIC_FTRACE due to possible memory corruption on + module unload + + -- Tim Gardner Fri, 17 Oct 2008 11:25:39 -0600 + +linux (2.6.27-7.11) intrepid; urgency=low + + [ Amit Kucheria ] + + * STABLE queue: mac80211: fix two issues in debugfs + - LP: #275227 + * SAUCE: Adds support for COMPAL JHL90 webcam + + [ Ben Collins ] + + * SAUCE: (no-up) x86: Quiet "Kernel alive" messages + - LP: #39985 + * SAUCE: (no-up) Modularize vesafb + * build/config: Enable vesafb module + * build: Switch to vesafb as preferred. + + [ Leann Ogasawara ] + + * Add Dell Dimension 9200 reboot quirk + - LP: #271370 + + [ Michael Haas ] + + * SAUCE: Revert aufs changes from AppArmor merge + + [ Tim Gardner ] + + * fix virtio udeb layout + - LP: #257739 + * Enabled CONFIG_EXT4DEV_FS=m + * Changed default TCP congestion algorithm to 'cubic' + - LP: #278801 + * SAUCE: ipw2200: change default policy for auto-associate + - LP: #264104 + + [ Upstream Kernel Changes ] + + * x86, early_ioremap: fix fencepost error + - LP: #263543 + + -- Tim Gardner Sat, 11 Oct 2008 08:07:42 -0600 + +linux (2.6.27-7.10) intrepid; urgency=low + + [ Alexey Starikovskiy ] + + * SAUCE: ACPI: EC: do transaction from interrupt context + - LP: #277802 + + [ Ben Collins ] + + * build/d-i: Change virtio-modules udeb to prio standard + + [ Colin Ian King ] + + * SAUCE: Blacklist IBM 2656 in serio/i8042 + - LP: #21558 + + [ Henrik Rydberg ] + + * Revert "SAUCE: applesmc: Add MacBookAir" + * SAUCE: [PATCH 1/5] hwmon: applesmc: Specified number of bytes to read + should match actual + * SAUCE: [PATCH 2/5] hwmon: applesmc: Fix the 'wait status failed: c != + 8' problem + * SAUCE: [PATCH 3/5] hwmon: applesmc: Prolong status wait + * SAUCE: [PATCH 4/5] hwmon: applesmc: Allow for variable ALV0 and ALV1 + package length + * SAUCE: [PATCH 5/5] hwmon: applesmc: Add support for Macbook Air + * SAUCE: hwmon: applesmc: Add support for Macbook Pro 4 + * SAUCE: hwmon: applesmc: Add support for Macbook Pro 3 + * SAUCE: hwmon: applesmc: Lighter wait mechanism, drastic improvement + + [ Leann Ogasawara ] + + * Add automatic model setting for Samsung Q45 + - LP: #200210 + + [ Tim Gardner ] + + * SAUCE: Correctly blacklist Thinkpad r40e in ACPI + - LP: #278794 + * SAUCE: Update Wacom tablet driver to 1.49 + - LP: #260675 + * SAUCE: ALPS touchpad for Dell Latitude E6500/E6400 + - LP: #270643 + * SAUCE: Fix Wacom tablet 1.49 porting errors + * SAUCE: Enable an e1000e Intel Corporation 82567 Gigabit controller + * SAUCE: Fix Oops in wlan_setup + - LP: #263309 + + [ Upstream Kernel Changes ] + + * ath9k: fix oops on trying to hold the wrong spinlock + * [Bluetooth] Fix double frees on error paths of btusb and bpa10x drivers + * [Bluetooth] Add reset quirk for new Targus and Belkin dongles + * [Bluetooth] Add reset quirk for A-Link BlueUSB21 dongle + * Revert "ax25: Fix std timer socket destroy handling." + * ax25: Quick fix for making sure unaccepted sockets get destroyed. + * netrom: Fix sock_orphan() use in nr_release + * Revert "V4L/DVB (8904): cx88: add missing unlock_kernel" + * SLOB: fix bogus ksize calculation + * net: only invoke dev->change_rx_flags when device is UP + * tcp: Fix possible double-ack w/ user dma + * net: Fix netdev_run_todo dead-lock + * tcp: Fix tcp_hybla zero congestion window growth with small rho and large cwnd. + * [MIPS] Sibyte: Register PIO PATA device only for Swarm and Litte Sur + * eeepc-laptop: Fix hwmon interface + * hwmon: (it87) Prevent power-off on Shuttle SN68PT + * hwmon: Define sysfs interface for energy consumption register + * hwmon: (adt7473) Fix some bogosity in documentation file + * hwmon: (abituguru3) Enable reading from AUX3 fan on Abit AT8 32X + * hwmon: (abituguru3) Enable DMI probing feature on Abit AT8 32X + * [CPUFREQ] correct broken links and email addresses + * SLOB: fix bogus ksize calculation fix + * Don't allow splice() to files opened with O_APPEND + * Linux 2.6.27 + + -- Tim Gardner Wed, 08 Oct 2008 21:19:34 -0600 + +linux (2.6.27-6.9) intrepid; urgency=low + + [ Kees Cook ] + + * SAUCE: AppArmor: update to upstream subversion r1302 + - LP: #269921 + + [ Stefan Bader ] + + * Update configuration files to be compliant to desktop specs + - LP: #279019 + + [ Tim Gardner ] + + * Add support in e1000e for a couple of ICH10 PCI IDs + * Enable CONFIG_INPUT_PCSPKR=m + - LP: #275453 + + [ Upstream Kernel Changes ] + + * V4L/DVB (8559a): Fix a merge conflict at gspca/sonixb + * V4L/DVB (8789): wm8739: remove wrong kfree + * V4L/DVB (8883): w9968cf: Fix order of usb_alloc_urb validation + * V4L/DVB (8884): em28xx-audio: fix memory leak + * V4L/DVB (8885): cpia2_usb: fix memory leak + * V4L/DVB (8886): ov511: fix memory leak + * V4L/DVB (8887): gspca: fix memory leak + * V4L/DVB (8892): pvrusb2: Handle USB ID 2040:2950 same as 2040:2900 + * V4L/DVB (8904): cx88: add missing unlock_kernel + * V4L/DVB (8905): ov511: fix exposure sysfs attribute bug + * V4L/DVB (8909): gspca: PAC 7302 webcam 093a:262a added. + * hrtimer: migrate pending list on cpu offline + * hrtimer: fix migration of CB_IRQSAFE_NO_SOFTIRQ hrtimers + * hrtimer: mark migration state + * hrtimer: prevent migration of per CPU hrtimers + * [IA64] Put the space for cpu0 per-cpu area into .data section + * powerpc: Fix PCI in Holly device tree + * powerpc: Fix failure to shutdown with CPU hotplug + * mfd: Fix Kconfig accroding to the new gpiolib symbols + * mfd: Fix asic3 compilation + * x86: fix typo in enable_mtrr_cleanup early parameter + * ipsec: Fix pskb_expand_head corruption in xfrm_state_check_space + * iucv: Fix mismerge again. + * ALSA: ASoC: Fix cs4270 error path + * ALSA: hda - Fix model for Dell Inspiron 1525 + * sctp: Fix kernel panic while process protocol violation parameter + * x86: Fix broken LDT access in VMI + * x86, vmi: fix broken LDT access + * tcp: Fix NULL dereference in tcp_4_send_ack() + * ipv6: NULL pointer dereferrence in tcp_v6_send_ack + * XFRM,IPv6: initialize ip6_dst_blackhole_ops.kmem_cachep + * af_key: Free dumping state on socket close + * dm: always allow one page in dm_merge_bvec + * dm: cope with access beyond end of device in dm_merge_bvec + * dm mpath: add missing path switching locking + * MN10300: Fix IRQ handling + * pxa2xx_spi: fix build breakage + * e1000e: write protect ICHx NVM to prevent malicious write/erase + * powerpc: Fix boot hang regression on MPC8544DS + * ASoC: Set correct name for WM8753 rec mixer output + * ALSA: snd-powermac: mixers for PowerMac G4 AGP + * ALSA: snd-powermac: HP detection for 1st iMac G3 SL + * fbcon: fix monochrome color value calculation + * inotify: fix lock ordering wrt do_page_fault's mmap_sem + * braille_console: only register notifiers when the braille console is used + * fix error-path NULL deref in alloc_posix_timer() + * memory hotplug: missing zone->lock in test_pages_isolated() + * mm: tiny-shmem nommu fix + * mm: handle initialising compound pages at orders greater than MAX_ORDER + * e1000e: reset swflag after resetting hardware + * e1000e: do not ever sleep in interrupt context + * e1000e: remove phy read from inside spinlock + * e1000e: drop stats lock + * e1000e: debug contention on NVM SWFLAG + * e1000e: update version from k4 to k6 + * Check mapped ranges on sysfs resource files + * e1000e: Fix incorrect debug warning + * [MIPS] Build fix: Fix irq flags type + * [MIPS] SMTC: Build fix: Fix filename in Makefile + * [MIPS] SMTC: Fix holes in SMTC and FPU affinity support. + * [MIPS] SMTC: Close tiny holes in the SMTC IPI replay system. + * [MIPS] SMTC: Fix SMTC dyntick support. + * [S390] nohz: Fix __udelay. + * [S390] qdio: prevent stack clobber + * Fix init/main.c to use regular printk with '%pF' for initcall fn + * x86 setup: correct segfault in generation of 32-bit reloc kernel + * selinux: Fix an uninitialized variable BUG/panic in selinux_secattr_to_sid() + * rtc: fix kernel panic on second use of SIGIO nofitication + * fbdev: fix recursive notifier and locking when fbdev console is blanked + * orion_spi: fix handling of default transfer speed + * include/linux/stacktrace.h: declare struct task_struct + * cpusets: remove pj from cpuset maintainers + * MAINTAINERS: add mailing list for man-pages + * SubmitChecklist: interfaces changes should CC linux-api@ + * Documentation/HOWTO: info about interface changes should CC linux-api@vger + * dw_dmac: fix copy/paste bug in tasklet + * leds-fsg: change order of initialization and deinitialization + * leds-pca955x: add proper error handling and fix bogus memory handling + * ACPI: Make /proc/acpi/wakeup interface handle PCI devices (again) + * clockevents: check broadcast tick device not the clock events device + * V4L/DVB (8919): cx18: Fix tuner audio input for Compro H900 cards + * V4L/DVB (8926): gspca: Bad fix of leak memory (changeset 43d2ead315b1). + * V4L/DVB (8933): gspca: Disable light frquency for zc3xx cs2102 Kokom. + * V4L/DVB (8935): em28xx-cards: Remove duplicate entry (EM2800_BOARD_KWORLD_USB2800) + * V4L/DVB (8955): bttv: Prevent NULL pointer dereference in radio_open + * V4L/DVB (8957): zr36067: Restore the default pixel format + * V4L/DVB (8958): zr36067: Return proper bytes-per-line value + * V4L/DVB (8960): drivers/media/video/cafe_ccic.c needs mm.h + * V4L/DVB (8961): zr36067: Fix RGBR pixel format + * V4L/DVB (8963): s2255drv field count fix + * V4L/DVB (8967): Use correct XC3028L firmware for AMD ATI TV Wonder 600 + * V4L/DVB (8978): sms1xxx: fix product name for Hauppauge WinTV MiniStick + * V4L/DVB (8979): sms1xxx: Add new USB product ID for Hauppauge WinTV MiniStick + * V4L/DVB (9029): Fix deadlock in demux code + * V4L/DVB (9037): Fix support for Hauppauge Nova-S SE + * V4L/DVB (9043): S5H1420: Fix size of shadow-array to avoid overflow + * V4L/DVB (9053): fix buffer overflow in uvc-video + * V4L/DVB (9075): gspca: Bad check of returned status in i2c_read() spca561. + * V4L/DVB (9080): gspca: Add a delay after writing to the sonixj sensors. + * V4L/DVB (9092): gspca: Bad init values for sonixj ov7660. + * V4L/DVB (9099): em28xx: Add detection for K-WORLD DVB-T 310U + * V4L/DVB (9103): em28xx: HVR-900 B3C0 - fix audio clicking issue + * x86: gart iommu have direct mapping when agp is present too + * ide-cd: temporary tray close fix + * ide-dma: fix ide_build_dmatable() for TRM290 + * IDE: Fix platform device registration in Swarm IDE driver (v2) + * ide-cd: Optiarc DVD RW AD-7200A does play audio + * ide: workaround for bogus gcc warning in ide_sysfs_register_port() + * [MIPS] Fix CMP Kconfig configuration and mark as broken. + * [MIPS] IP27: Fix build errors if CONFIG_MAPPED_KERNEL=y + * x86 ACPI: Blacklist two HP machines with buggy BIOSes + * kgdb, x86: Avoid invoking kgdb_nmicallback twice per NMI + * kgdb: call touch_softlockup_watchdog on resume + * atmel-mci: Initialize BLKR before sending data transfer command + * Marker depmod fix core kernel list + * Linux 2.6.27-rc9 + + -- Tim Gardner Sun, 05 Oct 2008 21:27:49 -0600 + +linux (2.6.27-5.8) intrepid; urgency=low + + [ Amit Kucheria ] + + * Update AUFS-related Kconfig + - LP: #264048 + + [ Michael Haas ] + + * add proper aufs source tree from 20080922 + * Fix AUFS compilation in vfsub.c + * Add splice-2.6.23.patch from AUFS to export a symbol needed by AUFS + * Add put_filp.patch from AUFS to export a symbol needed by AUFS + * apply (modified) lhash.patch from AUFS to export __lookup_hash() + * Add deny_write_access.patch from AUFS - export deny_write_access + * Add sec_perm-2.6.24.patch from AUFS - export security_inode_permission + * make sure TMPFS_MAGIC is defined in AUFS Makefile + + [ Tim Gardner ] + + * Enabled CONFIG_IPWIRELESS + - LP: #274748 + * Enabled CONFIG_E1000E, disabled CONFIG_E1000E_NEW + This takes advantage of the upstream NVM protection fix in + commit 4a7703582836f55a1cbad0e2c1c6ebbee3f9b3a7. + + [ Upstream Kernel Changes ] + + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + * [SCSI] qla2xxx: Defer enablement of RISC interrupts until ISP + initialization completes. + * PCI: Fix pcie_aspm=force + * PCI: fix compiler warnings in pci_get_subsys() + * UBIFS: create the name of the background thread in every case + * UBIFS: TNC / GC race fixes + * UBIFS: remove incorrect assert + * UBIFS: fix printk format warnings + * AMD IOMMU: set iommu sunc flag after command queuing + * AMD IOMMU: protect completion wait loop with iommu lock + * sparc64: Fix disappearing PCI devices on e3500. + * x86, oprofile: BUG scheduling while atomic + * ALSA: ASoC: Fix at32-pcm build breakage with PM enabled + * ath9k: connectivity is lost after Group rekeying is done + * wireless: zd1211rw: add device ID fix wifi dongle "trust nw-3100" + * [IA64] Ski simulator doesn't need check_sal_cache_flush + * [IA64] kexec fails on systems with blocks of uncached memory + * ath9k: Fix IRQ nobody cared issue with ath9k + * [Bluetooth] Fix I/O errors on MacBooks with Broadcom chips + * [Bluetooth] Fix wrong URB handling of btusb driver + * [Bluetooth] Fix USB disconnect handling of btusb driver + * sparc64: Fix missing devices due to PCI bridge test in + of_create_pci_dev(). + * [WATCHDOG] ibmasr: remove unnecessary spin_unlock() + * [WATCHDOG] wdt285: fix sparse warnings + * [WATCHDOG] unlocked_ioctl changes + * x86: fix 27-rc crash on vsmp due to paravirt during module load + * sched: fix init_hrtick() section mismatch warning + * clockevents: prevent cpu online to interfere with nohz + * x86: prevent stale state of c1e_mask across CPU offline/online + * clockevents: prevent stale tick_next_period for onlining CPUs + * clockevents: check broadcast device not tick device + * clockevents: prevent mode mismatch on cpu online + * x86: prevent C-states hang on AMD C1E enabled machines + * x86: c1e_idle: don't mark TSC unstable if CPU has invariant TSC + * timers: fix build error in !oneshot case + * ALSA: ASoC: maintainers - update email address for Liam Girdwood + * ibmasr: remove unnecessary spin_unlock() + * smb.h: do not include linux/time.h in userspace + * kernel-doc: allow structs whose members are all private + * kexec: fix segmentation fault in kimage_add_entry + * Documentation/DMA-mapping.txt: update for pci_dma_mapping_error() + changes + * sys_paccept: disable paccept() until API design is resolved + * mm: tiny-shmem fix lock ordering: mmap_sem vs i_mutex + * Documentation/sysctl/kernel.txt: fix softlockup_thresh description + * memcg: check under limit at shrink_usage + * atmel_serial: update the powersave handler to match serial core + * [SCSI] Fix hang with split requests + * USB Storage: Sierra: Non-configurable TRU-Install + * USB Serial: Sierra: Device addition & version rev + * USB: ehci: fix some ehci hangs and crashes + * USB: Fix the Nokia 6300 storage-mode. + * USB: Correct Sierra Wireless USB EVDO Modem Device ID + * USB: fix hcd interrupt disabling + * USB: update of Documentation/usb/anchors.txt + * usb gadget: fix omap_udc DMA regression + * USB: Fixing Nokia 3310c in storage mode + * usb: musb: fix include path + * USB: fix EHCI periodic transfers + * usb-serial: Add Siemens EF81 to PL-2303 hack triggers + * USB: SERIAL CP2101 add device IDs + * USB: unusual_devs addition for RockChip MP3 player + * USB: fsl_usb2_udc: fix VDBG() format string + * usb serial: ti_usb_3410_5052 obviously broken by firmware changes + * USB: ftdi_sio: Add 0x5050/0x0900 USB IDs (Papouch Quido USB 4/4) + * USB: serial: add ZTE CDMA Tech id to option driver + * USB Serial: Sierra: Add MC8785 VID/PID + * USB: drivers/usb/musb/: disable it on SuperH + * usb: ftdi_sio: add support for Domintell devices + * usb: unusual devs patch for Nokia 5310 Music Xpress + * USB: revert recovery from transient errors + * [MIPS] au1000: Fix gpio direction + * [MIPS] Fixe the definition of PTRS_PER_PGD + * x86: prevent stale state of c1e_mask across CPU offline/online, fix + * x86: disable apm on the olpc + * i2c-powermac: Fix section for probe and remove functions + * i2c-dev: Return correct error code on class_create() failure + * i2c: Fix mailing lists in two MAINTAINERS entries + * ath9k: disable MIB interrupts to fix interrupt storm + * 9p: implement proper trans module refcounting and unregistration + * 9p-trans_fd: fix trans_fd::p9_conn_destroy() + * 9p-trans_fd: clean up p9_conn_create() + * 9p-trans_fd: don't do fs segment mangling in p9_fd_poll() + * 9p-trans_fd: fix and clean up module init/exit paths + * 9p: introduce missing kfree + * 9p: use an IS_ERR test rather than a NULL test + * 9p: fix put_data error handling + * netfilter: ip6t_{hbh,dst}: Rejects not-strict mode on rule insertion + * MN10300: Move asm-arm/cnt32_to_63.h to include/linux/ + * MN10300: Make sched_clock() report time since boot + * ALSA: fix locking in snd_pcm_open*() and snd_rawmidi_open*() + * ALSA: remove unneeded power_mutex lock in snd_pcm_drop + * IPoIB: Fix crash when path record fails after path flush + * [XFS] Fix extent list corruption in xfs_iext_irec_compact_full(). + * [XFS] Remove xfs_iext_irec_compact_full() + * kgdb: could not write to the last of valid memory with kgdb + * kgdb, x86, arm, mips, powerpc: ignore user space single stepping + * kgdb, x86_64: gdb serial has BX and DX reversed + * kgdb, x86_64: fix PS CS SS registers in gdb serial + * kgdboc,tty: Fix tty polling search to use name correctly + * ARM: Delete ARM's own cnt32_to_63.h + * m32r: remove the unused NOHIGHMEM option + * m32r: don't offer CONFIG_ISA + * m32r: export empty_zero_page + * m32r: export __ndelay + * m32r/kernel/: cleanups + * [MIPS] au1000: Make sure GPIO value is zero or one + * [MIPS] IP27: Switch to dynamic interrupt routing avoding panic on + error. + * [MIPS] BCM47xx: Fix build error due to missing PCI functions + * [SSB] Initialise dma_mask for SSB_BUSTYPE_SSB devices + * Swarm: Fix crash due to missing initialization + * ide-tape: fix vendor strings + * ide: note that IDE generic may prevent other drivers from attaching + * cdrom: update ioctl documentation + * [SCSI] qlogicpti: fix sg list traversal error in continuation entries + * sata_nv: reinstate nv_hardreset() for non generic controllers + * scsi: fix fall out of sg-chaining patch in qlogicpti + * ALSA: make the CS4270 driver a new-style I2C driver + * ALSA: ASoC: Fix another cs4270 error path + * Fix NULL pointer dereference in proc_sys_compare + * kconfig: fix silentoldconfig + * kconfig: readd lost change count + * mm owner: fix race between swapoff and exit + * Linux 2.6.27-rc8 + * e1000e: write protect ICHx NVM to prevent malicious write/erase + + -- Amit Kucheria Tue, 30 Sep 2008 18:22:35 +0300 + +linux (2.6.27-4.7) intrepid; urgency=low + + [ Ben Collins ] + + * build/abi: Add gfs1 to perm blacklist + * build/abi: Ignored changes in gfs2 symbols + + [ Fabio M. Di Nitto ] + + * Revert "SAUCE: Export gfs2 symbols required for gfs1 kernel module" + * ubuntu: update GFS Cluster File System + + [ Stefan Bader ] + + * SAUCE: x86: Reserve FIRST_DEVICE_VECTOR in used_vectors bitmap. + - LP: #276334 + + [ Tim Gardner ] + + * Revert "Disable e1000e until the NVRAM corruption problem is found." + * Add atl1e and atl2 to Debian installer bits + - LP: #273904 + * SAUCE: e1000e: Map NV RAM dynamically only when needed. + - LP: #263555 + + -- Tim Gardner Fri, 26 Sep 2008 20:51:22 -0600 + +linux (2.6.27-4.6) intrepid; urgency=low + + [ Tim Gardner ] + + * Disable e1000e until the NVRAM corruption problem is found. + - LP: #263555 + + [ Upstream Kernel Changes ] + + * Revert "[Bluetooth] Eliminate checks for impossible conditions in IRQ + handler" + + -- Ben Collins Tue, 23 Sep 2008 09:53:57 -0400 + +linux (2.6.27-4.5) intrepid; urgency=low + + [ Upstream Kernel Changes ] + + * Revert "b43/b43legacy: add RFKILL_STATE_HARD_BLOCKED support" + * udf: Fix lock inversion between iprune_mutex and alloc_mutex (v2) + * udf: Fix error paths in udf_new_inode() + * [SCSI] sd: select CRC_T10DIF only when necessary + * [SCSI] zfcp: Fix request queue locking + * [SCSI] zfcp: Correctly query end flag in gpn_ft response + * [SCSI] zfcp: Simplify ccw notify handler + * [SCSI] zfcp: Fix reference counter for remote ports + * [SCSI] zfcp: channel cannot be detached due to refcount imbalance + * [SCSI] zfcp: Remove duplicated unlikely() macros. + * [SCSI] scsi_dh: make check_sense return ADD_TO_MLQUEUE + * [SCSI] make scsi_check_sense HARDWARE_ERROR return ADD_TO_MLQUEUE on + retry + * [SCSI] fix check of PQ and PDT bits for WLUNs + * pcm037: add rts/cts support for serial port + * i.MX serial: fix init failure + * imx serial: set RXD mux bit on i.MX27 and i.MX31 + * imx serial: fix rts handling for non imx1 based hardware + * mlx4_core: Set RAE and init mtt_sz field in FRMR MPT entries + * udf: add llseek method + * PCI/iommu: blacklist DMAR on Intel G31/G33 chipsets + * PCI: Fix printk warnings in probe.c + * PCI: Fix printk warnings in setup-bus.c + * PCI Hotplug: fakephp: fix deadlock... again + * clockevents: remove WARN_ON which was used to gather information + * ocfs2: Fix a bug in direct IO read. + * arch/x86/kernel/kdebugfs.c: introduce missing kfree + * [IA64] fix compile failure with non modular builds + * [IA64] fix up bte.h + * [IA64] arch/ia64/sn/pci/tioca_provider.c: introduce missing kfree + * PCI: fix pciehp_free_irq() + * [IA64] prevent ia64 from invoking irq handlers on offline CPUs + * ide: Fix pointer arithmetic in hpt3xx driver code (3rd try) + * add deprecated ide-scsi to feature-removal-schedule.txt + * swiotlb: fix back-off path when memory allocation fails + * sparc64: Fix interrupt register calculations on Psycho and Sabre. + * VIDEO_SH_MOBILE_CEU should depend on HAS_DMA + * m68k: Update defconfigs for 2.6.27-rc6 + * sparc32: Fix function signature of of_bus_sbus_get_flags(). + * sched: fix 2.6.27-rc5 couldn't boot on tulsa machine randomly + * sched: fix deadlock in setting scheduler parameter to zero + * KVM: SVM: fix random segfaults with NPT enabled + * KVM: SVM: fix guest global tlb flushes with NPT + * KVM: VMX: Always return old for clear_flush_young() when using EPT + * clocksource, acpi_pm.c: fix check for monotonicity + * [ARM] OMAP: Fix MMC device data + * block: disable sysfs parts of the disk command filter + * ath9k: Assign seq# when mac80211 requests this + * sg: disable interrupts inside sg_copy_buffer + * MN10300: Change the fault handler to check in_atomic() not + in_interrupt() + * [Bluetooth] Fix regression from using default link policy + * netlink: fix overrun in attribute iteration + * x86: fix possible x86_64 and EFI regression + * sparc64: Fix PCI error interrupt registry on PSYCHO. + * sparc: Fix user_regset 'n' field values. + * niu: panic on reset + * PCI: re-add debug prints for unmodified BARs + * [ARM] 5245/1: Fix warning about unused return value in drivers/pcmcia + * [ARM] 5246/1: tosa: add proper clock alias for tc6393xb clock + * [ARM] 5247/1: tosa: SW_EAR_IN support + * [ARM] Fix PCI_DMA_BUS_IS_PHYS for ARM + * ata: duplicate variable sparse warning + * sata_inic162x: enable LED blinking + * [libata] LBA28/LBA48 off-by-one bug in ata.h + * proc: more debugging for "already registered" case + * include/linux/ioport.h: add missing macro argument for devm_release_* + family + * cpuset: avoid changing cpuset's cpus when -errno returned + * cpuset: hotplug documentation fix + * coredump_filter: add description of bit 4 + * bfs: fix Lockdep warning + * mm: ifdef Quicklists in /proc/meminfo + * spi_mpc83xx: fix clockrate calculation for low speed + * spi_mpc83xx: reject invalid transfer sizes + * pxa2xx_spi: chipselect bugfixes + * pxa2xx_spi: dma bugfixes + * mm: mark the correct zone as full when scanning zonelists + * Documentation/ABI: /sys/class/gpio + * MAINTAINERS: fix USB VIDEO CLASS mail list address + * ia64: fix panic during `modprobe -r xpc' + * atmel_lcdfb: disable LCD and DMA engines when suspending + * spi_s3c24xx: fix section warning + * rescan_partitions(): make device capacity errors non-fatal + * memstick: fix MSProHG 8-bit interface mode support + * Add Uwe Kleine-König to .mailmap + * xen: fix for xen guest with mem > 3.7G + * x86/paravirt: Remove duplicate paravirt_pagetable_setup_{start, done}() + * crypto: talitos - Avoid consecutive packets going out with same IV + * slub: fixed uninitialized counter in struct kmem_cache_node + * udp: Fix rcv socket locking + * IB/mlx4: Fix up fast register page list format + * [MIPS] VR41xx: unsigned irq cannot be negative + * x86: completely disable NOPL on 32 bits + * [S390] cio: Fix driver_data handling for ccwgroup devices. + * [S390] cio: fix orb initialization in cio_start_key + * sparc64: Fix OOPS in psycho_pcierr_intr_other(). + * sparc64: Fix SMP bootup with CONFIG_STACK_DEBUG or ftrace. + * RDMA/nes: Fix client side QP destroy + * IPoIB: Fix deadlock on RTNL between bcast join comp and ipoib_stop() + * clockevents: make device shutdown robust + * powerpc: Fix interrupt values for DMA2 in MPC8610 HPCD device tree + * hpplus: fix build regression + * Fix PNP build failure, bugzilla #11276 + * warn: Turn the netdev timeout WARN_ON() into a WARN() + * [XFS] Move memory allocations for log tracing out of the critical path + * [XFS] Fix regression introduced by remount fixup + * [XFS] Prevent direct I/O from mapping extents beyond eof + * [XFS] Fix barrier status change detection. + * [XFS] Prevent lockdep false positives when locking two inodes. + * [XFS] Fix use-after-free with buffers + * [XFS] Don't do I/O beyond eof when unreserving space + * powerpc: Holly board needs dtbImage target + * Fix compile failure with non modular builds + * [ARM] 5249/1: davinci: remove redundant check in davinci_psc_config() + * [ARM] omap: back out 'internal_clock' support + * sctp: set the skb->ip_summed correctly when sending over loopback. + * [ARM] 5255/1: Update jornada ssp to remove build errors/warnings + * sctp: do not enable peer features if we can't do them. + * sctp: Fix oops when INIT-ACK indicates that peer doesn't support AUTH + * bnx2: Promote vector field in bnx2_irq structure from u16 to unsigned + int + * forcedeth: call restore mac addr in nv_shutdown path + * e1000: prevent corruption of EEPROM/NVM + * e100: Use pci_pme_active to clear PME_Status and disable PME# + * md: Don't wait UNINTERRUPTIBLE for other resync to finish + * atstk1000: fix build breakage with BOARD_ATSTK100X_SW2_CUSTOM=y + * avr32: add .gitignore files + * avr32: add generic_find_next_le_bit bit function + * avr32: fix sys_sync_file_range() call convention + * avr32: nmi_enter() without nmi_exit() + * KVM: ia64: 'struct fdesc' build fix + * hwmon: (atxp1) Fix device detection logic + * hwmon: (it87) Fix fan tachometer reading in IT8712F rev 0x7 (I) + * hwmon: (ad7414) Make ad7414_update_device() static + * tmio_mmc: fix compilation with debug enabled + * atmel-mci: debugfs: enable clock before dumping regs + * atmel-mci: Fix memory leak in atmci_regs_show + * atmel-mci: Fix bogus debugfs file size + * atmel-mci: Set MMC_CAP_NEEDS_POLL if no detect_pin + * mmc_block: handle error from mmc_register_driver() + * mmc_test: initialize mmc_test_lock statically + * [MIPS] Fix 64-bit IP checksum code + * [MIPS] SMTC: Clear TIF_FPUBOUND on clone / fork. + * [MIPS] Fix potential latency problem due to non-atomic cpu_wait. + * [MIPS] vmlinux.lds.S: handle .text.* + * MAINTAINERS: Trivial whitespace cleanups + * MAINTAINERS: Various fixes + * Linux 2.6.27-rc7 + + -- Tim Gardner Sun, 21 Sep 2008 21:49:28 -0600 + +linux (2.6.27-3.4) intrepid; urgency=low + + [ Colin Ian King ] + + * SAUCE: fix kernel oops in VirtualBox during paravirt patching + - LP: #246067 + * SAUCE: qc-usb: Enable Logitech QuickCam Messenger + - LP: #209901 + * SAUCE: appleir: Enable driver for new MacBook Pro + - LP: #157919 + + [ Tim Gardner ] + + * Enabled CONFIG_DEBUG_RODATA=y + + [ Upstream Kernel Changes ] + + * Revert "ALSA: hda - Added model selection for iMac 24"" + * Revert "x86: fix HPET regression in 2.6.26 versus 2.6.25, check hpet + against BAR, v3" + * Revert "[ARM] use the new byteorder headers" + * Revert "mac80211: Use IWEVASSOCREQIE instead of IWEVCUSTOM" + * Revert "crypto: camellia - Use kernel-provided bitops, unaligned access + helpers" + * svcrdma: Fix race between svc_rdma_recvfrom thread and the dto_tasklet + * sched, cpuset: rework sched domains and CPU hotplug handling (v4) + * ACPI: Fix now signed module parameter. + * ACPI: Change package length error to warning + * ACPI: Fix now signed module parameter. + * ACPI: Fix typo in "Disable MWAIT via DMI on broken Compal board" + * acpi: add checking for NULL early param + * UBIFS: fix zero-length truncations + * Input: bcm5974 - add maintainer entry + * sh64: re-add the __strnlen_user() prototype + * sh: fix ptrace_64.c:user_disable_single_step() + * PNPACPI: ignore the producer/consumer bit for extended IRQ descriptors + * UBIFS: always read hashed-key nodes under TNC mutex + * UBIFS: allow for racing between GC and TNC + * [CIFS] Fix plaintext authentication + * sparc32: Implement smp_call_function_single(). + * sh: crash kernel resource fix + * sh: fix kexec entry point for crash kernels + * sh: fix platform_resource_setup_memory() section mismatch + * sh: update Migo-R defconfig + * sh: update AP325RXA defconfig + * sh: fix semtimedop syscall + * cifs: fix O_APPEND on directio mounts + * [CIFS] update cifs change log + * [CIFS] Turn off Unicode during session establishment for plaintext + authentication + * ACPI: thinkpad-acpi: wan radio control is not experimental + * sparc: Fix resource flags for PCI children in OF device tree. + * remove blk_register_filter and blk_unregister_filter in gendisk + * ALSA: oxygen: fix distorted output on AK4396-based cards + * ipv6: When we droped a packet, we should return NET_RX_DROP instead of + 0 + * pkt_sched: Fix locking of qdisc_root with qdisc_root_sleeping_lock() + * net: Unbreak userspace usage of linux/mroute.h + * Don't trigger softlockup detector on network fs blocked tasks + * Resource handling: add 'insert_resource_expand_to_fit()' function + * sparc64: setup_valid_addr_bitmap_from_pavail() should be __init + * UBIFS: do not update min_idx_lebs in stafs + * UBIFS: push empty flash hack down + * UBIFS: remove incorrect index space check + * UBIFS: improve statfs reporting + * UBIFS: fix assertion + * UBIFS: add forgotten gc_idx_lebs component + * UBIFS: introduce LEB overhead + * UBIFS: improve statfs reporting even more + * UBIFS: fill f_fsid + * drm/radeon: downgrade debug message from info to debug. + * Remove invalidate_partition call from do_md_stop. + * Fix problem with waiting while holding rcu read lock in md/bitmap.c + * ALSA: hda: Distortion fix for dell_m6_core_init + * ALSA: ASoC: fix pxa2xx-i2s clk_get call + * block: restore original behavior of /proc/partition when there's no + partition + * debugobjects: fix lockdep warning + * avr32: Fix lockup after Java stack underflow in user mode + * avr32: pm_standby low-power ram bug fix + * nfsd: fix compound state allocation error handling + * sunrpc: fix possible overrun on read of /proc/sys/sunrpc/transports + * nfsd: fix buffer overrun decoding NFSv4 acl + * audit: Moved variable declaration to beginning of function + * Fix modules_install on RO nfs-exported trees. + * Remove '#include ' from mm/page_isolation.c + * dabusb_fpga_download(): fix a memory leak + * [MTD] mtdchar.c: Fix regression in MEMGETREGIONINFO ioctl() + * ALSA: hda - Fix ALC663 auto-probe + * ALSA: hda - Add mic-boost controls to ALC662/663 auto configuration + * Un-break printk strings in x86 PCI probing code + * kernel/resource.c: fix new kernel-doc warning + * softlockup: minor cleanup, don't check task->state twice + * fix typo in arch/parisc/hpux/fs.c + * m68k: atari_keyb_init operator precedence fix + * ACPI: Fix typo in "Disable MWAIT via DMI on broken Compal board" + * don't diff generated firmware files + * IDE: compile fix for sff_dma_ops + * IDE: palm_bk3710: fix compile warning for unused variable + * ide: fix hwif_to_node() + * palm_bk3710: improve IDE registration + * ide-disk: remove stale init_idedisk_capacity() documentation + * ide/Kconfig: mark ide-scsi as deprecated + * net/wireless/Kconfig: clarify the description for + CONFIG_WIRELESS_EXT_SYSFS + * iwlwifi: do not use GFP_DMA in iwl_tx_queue_init + * iwlwifi: workaround interrupt handling no some platforms + * iwlwifi: fix apm_stop (wrong bit polarity for FLAG_INIT_DONE) + * iwlwifi: fix 64bit platform firmware loading + * orinoco: Multicast to the specified addresses + * wireless/libertas/if_cs.c: fix memory leaks + * mac80211: Fix debugfs union misuse and pointer corruption + * rt2x00: Compiler warning unmasked by fix of BUILD_BUG_ON + * ath9k: Incorrect key used when group and pairwise ciphers are + different. + * ath9: Fix ath_rx_flush_tid() for IRQs disabled kernel warning message. + * net/xfrm: Use an IS_ERR test rather than a NULL test + * ipv: Re-enable IP when MTU > 68 + * NTFS: update homepage + * mm: make setup_zone_migrate_reserve() aware of overlapping nodes + * VFS: fix dio write returning EIO when try_to_release_page fails + * acer-wmi: remove debugfs entries upon unloading + * mm/bootmem: silence section mismatch warning - + contig_page_data/bootmem_node_data + * MAINTAINERS: add a maintainer for the BCM5974 multitouch driver + * 8250: improve workaround for UARTs that don't re-assert THRE correctly + * mmc: at91_mci: don't use coherent dma buffers + * pid_ns: zap_pid_ns_processes: fix the ->child_reaper changing + * pid_ns: (BUG 11391) change ->child_reaper when init->group_leader exits + * cirrusfb: check_par fixes + * devcgroup: fix race against rmdir() + * mm: show quicklist usage in /proc/meminfo + * mm: size of quicklists shouldn't be proportional to the number of CPUs + * ipc: document the new auto_msgmni proc file + * hp-wmi: update to match current rfkill semantics + * hp-wmi: add proper hotkey support + * tdfxfb: fix SDRAM memory size detection + * tdfxfb: fix frame buffer name overrun + * rtc_time_to_tm: fix signed/unsigned arithmetic + * ibft: fix target info parsing in ibft module + * sysfs: document files in /sys/firmware/sgi_uv/ + * rtc-cmos: wake again from S5 + * pm_qos_requirement might sleep + * drivers/char/random.c: fix a race which can lead to a bogus BUG() + * ipsec: Fix deadlock in xfrm_state management. + * [x86] Fix TSC calibration issues + * tipc: Don't use structure names which easily globally conflict. + * sparc64: Fix IPI call locking. + * [ARM] omap: fix gpio.c build error + * sparc64: Prevent sparc64 from invoking irq handlers on offline CPUs + * powerpc: Fix uninitialised variable in VSX alignment code + * powerpc: Only make kernel text pages of linear mapping executable + * powerpc: Make sure _etext is after all kernel text + * powerpc: Work around gcc's -fno-omit-frame-pointer bug + * powerpc: Fix build error with 64K pages and !hugetlbfs + * powerpc: Fix for getting CPU number in power_save_ppc32_restore() + * UBIFS: amend f_fsid + * net/usb/pegasus: avoid hundreds of diagnostics + * ixgbe: initialize interrupt throttle rate + * pcnet-cs, axnet_cs: add new IDs, remove dup ID with less info + * netxen: Remove workaround for chipset quirk + * Split up PIT part of TSC calibration from native_calibrate_tsc + * iwlwifi: W/A for the TSF correction in IBSS + * iwlwifi: fix hidden ssid discovery in passive channels + * iwlwifi: remove false rxon if rx chain changes + * iwlwifi: fix station mimo power save values + * iwlwifi: fix rx_chain computation + * iwlwifi: fix Tx cmd memory allocation failure handling + * iwlwifi: call apm stop on exit + * iwlwifi: fix STATUS_EXIT_PENDING is not set on pci_remove + * ath9k: Fix TX status reporting + * ath9k: Fix TX control flag use for no ACK and RTS/CTS + * V4L/DVB (8555): au8522: add mechanism to configure IF frequency for vsb + and qam + * V4L/DVB (8556): au0828: add support for Hauppauge Woodbury + * V4L/DVB (8598): au8522: clean up function au8522_set_if + * V4L/DVB (8599): au8522: remove if frequency settings from vsb/qam + modulation tables + * V4L/DVB (8600): au0828: explicitly set 6 MHz IF frequency in + hauppauge_hvr950q_config + * V4L/DVB (8629): v4l2-ioctl: do not try to handle private V4L1 ioctls + * V4L/DVB (8633): ivtv: update ivtv version number + * V4L/DVB (8648): ivtv: improve CC support + * V4L/DVB (8660): gspca: Simplify the scan of URB packets in pac7311. + * V4L/DVB (8661): gspca: Bug in the previous changeset about pac7311. + * V4L/DVB (8663): gspca: Webcam 0c45:6128 added in sonixj. + * V4L/DVB (8664): gspca: The bridge/sensor of the webcam 093a:2621 is a + PAC 7302. + * V4L/DVB (8665): gspca: Fix the 640x480 resolution of the webcam + 093a:2621. + * V4L/DVB (8666): gspca: Bad scanning of frames in pac7311. + * V4L/DVB (8667): gspca: Bad probe of Z-Star/Vimicro webcams with pas106 + sensor. + * V4L/DVB (8668): gspca: Conflict GSPCA / ET61X251 for the webcam + 102c:6251. + * V4L/DVB (8669): gspca: Add white balance control for spca561 rev 012A. + * V4L/DVB (8671): gspca: Remove the unused field 'dev_name' of the device + structure. + * V4L/DVB (8672): gspca: Big rewrite of spca561. + * V4L/DVB (8673): gspca: Bad frame scanning again and bad init in + pac7311. + * V4L/DVB (8674): gspca: Webcam 0c45:612e added in sonixj. + * V4L/DVB (8675): gspca: Pixmap PJPG (Pixart 73xx JPEG) added, generated + by pac7311. + * V4L/DVB (8678): Remove the dead CONFIG_RADIO_MIROPCM20{,_RDS} code + * V4L/DVB (8681): v4l2-ioctl.c: fix warning + * V4L/DVB (8682): V4L: fix return value of register video func + * V4L/DVB (8701): cx18: Add missing lock for when the irq handler + manipulates the queues + * V4L/DVB (8703): gspca: Do controls work for spca561 revision 12a. + * V4L/DVB (8705): gspca: Adjust some control limits in spca561. + * V4L/DVB (8706): Make contrast and brightness work for pac7302. + * V4L/DVB (8707): gspca: Colors, hflip and vflip controls added for + pac7302. + * V4L/DVB (8709): gspca: Fix initialization and controls of sn9x110 - + ov7630. + * V4L/DVB (8710): gspca: Bad color control in sonixj. + * V4L/DVB (8711): gspca: Bad controls and quantization table of pac7311. + * V4L/DVB (8712): gspca: Bad start of sonixj webcams since changeset + a8779025e7e8. + * V4L/DVB (8713): gspca: Bad color control again in sonixj. + * V4L/DVB (8714): gspca: Bad start of sn9c110 and sensor om6802. + * V4L/DVB (8715): gspca: Change the name of some webcam in the gspca doc. + * V4L/DVB (8716): gspca: Bad start of sn9c110 and sensor ov7630. + * V4L/DVB (8717): gspca: Frame buffer too small for small resolutions + (sonixj and t613). + * V4L/DVB (8718): gspca: suspend/resume added. + * V4L/DVB (8719): gspca: Have VIDIOC_QUERYCTRL more compliant to the + spec. + * V4L/DVB (8720): gspca: V4L2_CAP_SENSOR_UPSIDE_DOWN added as a cap for + some webcams. + * V4L/DVB (8722): sms1xxx: fix typo in license header + * V4L/DVB (8726): link tuner before saa7134 + * V4L/DVB (8727): V4L1: make PMS not autoprobe when builtin. + * V4L/DVB (8728): 1-make-pms-not-autoprobe-when-builtin update + * V4L/DVB (8749): Fix error code, when camera is not turned on by sonypi + * V4L/DVB (8750): V4L: check inval in video_register_device_index() + * V4L/DVB (8751): vivi: Fix some issues at vivi register routine + * V4L/DVB (8757): v4l-dvb: fix a bunch of sparse warnings + * V4L/DVB (8769): cx18: Simplify queue flush logic to prevent oops in + cx18_flush_queues() + * V4L/DVB (8778): radio: fix incorrect video_register_device result check + * V4L/DVB (8779): v4l: fix more incorrect video_register_device result + checks + * V4L/DVB (8790): saa7115: call i2c_set_clientdata only when state != + NULL + * V4L/DVB (8803): s5h1409: Enable QAM_AUTO mode + * V4L/DVB (8804): s5h1411: Enable QAM_AUTO mode + * V4L/DVB (8805): Steven Toth email address change + * V4L/DVB (8809): gspca: Revert commit + 9a9335776548d01525141c6e8f0c12e86bbde982 + * V4L/DVB (8810): gspca: Compile error when CONFIG_PM not defined. + * V4L/DVB (8812): gspca: Do pac73xx webcams work. + * V4L/DVB (8813): gspca: Adjust SOF detection for pac73xx. + * V4L/DVB (8814): gspca: Set DISABLED the disabled controls at query + control time. + * V4L/DVB (8815): gspca: Fix problems with disabled controls. + * V4L/DVB (8816): gspca: Set disabled ctrls and fix a register pb with + ovxxxx in sonixb. + * V4L/DVB (8817): gspca: LED and proble changes in sonixb. + * V4L/DVB (8818): gspca: Reinitialize the device on resume. + * V4L/DVB (8819): gspca: Initialize the ov519 at open time and source + cleanup. + * V4L/DVB (8820): gspca: Change initialization and gamma of zc3xx - + pas106. + * V4L/DVB (8822): gspca: Change some subdriver functions for + suspend/resume. + * V4L/DVB (8823): gspca: H and V flips work for ov7670 only in ov519. + * V4L/DVB (8824): gspca: Too much code removed in the suspend/resume + changeset. + * V4L/DVB (8825): gspca: More controls for pac73xx and new webcam + 093a:2624. + * V4L/DVB (8826): gspca: Webcam Labtec 2200 (093a:2626) added in pac7311. + * V4L/DVB (8827): gspca: Stop pac7302 autogain oscillation. + * V4L/DVB (8828): gspca: Set the clock at the end of initialization in + sonixj. + * V4L/DVB (8829): gspca: Have a clean kmalloc-ated buffer for USB + exchanges. + * V4L/DVB (8830): gspca: Move some probe code to the new init function. + * V4L/DVB (8831): gspca: Resolve webcam conflicts between some drivers. + * V4L/DVB (8832): gspca: Bad pixelformat of vc0321 webcams. + * V4L/DVB (8833): gspca: Cleanup the sonixb code. + * V4L/DVB (8834): gspca: Have a bigger buffer for sn9c10x compressed + images. + * V4L/DVB (8835): gspca: Same pixfmt as the sn9c102 driver and raw Bayer + added in sonixb. + * V4L/DVB (8837): dvb: fix I2C adapters name size + * V4L/DVB (8839): dib0700: add comment to identify 35th USB id pair + * V4L/DVB (8840): dib0700: add basic support for Hauppauge Nova-TD-500 + (84xxx) + * V4L/DVB (8842): vivi_release(): fix use-after-free + * V4L/DVB (8843): tda10048_firmware_upload(): fix a memory leak + * V4L/DVB (8844): dabusb_fpga_download(): fix a memory leak + * bnx2x: Accessing un-mapped page + * SELinux: memory leak in security_context_to_sid_core + * x86: add io delay quirk for Presario F700 + * mmap: fix petty bug in anonymous shared mmap offset handling + * x86: Change warning message in TSC calibration. + * PCI: fix pbus_size_mem() resource alignment for CardBus controllers + * [ARM] omap: fix build error in ohci-omap.c + * [ARM] remove unused #include + * ACPI: Make Len Brown the ACPI maintainer again + * fujitsu-laptop: fix regression for P8010 in 2.6.27-rc + * ACPI: Avoid bogus timeout about SMbus check + * acer-wmi: remove debugfs entries upon unloading + * forgotten refcount on sysctl root table + * V4L/DVB (8868): gspca: Support for vga modes with sif sensors in + sonixb. + * V4L/DVB (8869): gspca: Move the Sonix webcams with TAS5110C1B from + sn9c102 to gspca. + * V4L/DVB (8870): gspca: Fix dark room problem with sonixb. + * V4L/DVB (8872): gspca: Bad image format and offset with rev072a of + spca561. + * V4L/DVB (8873): gspca: Bad image offset with rev012a of spca561 and + adjust exposure. + * V4L/DVB (8874): gspca: Adjust hstart for sn9c103/ov7630 and update + usb-id's. + * [ARM] omap: fix virtual vs physical address space confusions + * V4L/DVB (8876): budget: udelay changed to mdelay + * V4L/DVB (8877): b2c2 and bt8xx: udelay to mdelay + * V4L/DVB (8880): PATCH: Fix parents on some webcam drivers + * V4L/DVB (8881): gspca: After 'while (retry--) {...}', retry will be -1 + but not 0. + * powerpc/spufs: Fix multiple get_spu_context() + * powerpc/spufs: Fix race for a free SPU + * Input: bcm5974 - small formatting cleanup + * Input: bcm5974 - improve finger tracking and counting + * Input: bcm5974 - add BTN_TOUCH event for mousedev benefit + * Input: i8042 - make Lenovo 3000 N100 blacklist entry more specific + * sh: resume_kernel fix for kernel oops built with CONFIG_BKL_PREEMPT=y. + * sh64: resume_kernel fix for kernel oops built with + CONFIG_BKL_PREEMPT=y. + * i2c: fix i2c-sh_mobile timing issues + * clockevents: prevent clockevent event_handler ending up handler_noop + * clockevents: prevent endless loop in periodic broadcast handler + * clockevents: enforce reprogram in oneshot setup + * clockevents: prevent multiple init/shutdown + * clockevents: prevent endless loop lockup + * HPET: make minimum reprogramming delta useful + * [MTD] [NAND] tmio_nand: fix base address programming + * Fix conditional export of kvh.h and a.out.h to userspace. + * async_tx: fix the bug in async_tx_run_dependencies + * sched_clock: fix NOHZ interaction + * sched: fix process time monotonicity + * UBIFS: fix division by zero + * UBIFS: make minimum fanout 3 + * [MIPS] Fix data bus error recovery + * [MIPS] Fix WARNING: at kernel/smp.c:290 + * [MIPS] TXx9: Fix txx9_pcode initialization + * [MIPS] TX39xx: Add missing local_flush_icache_range initialization + * [MIPS] Probe initrd header only if explicitly specified + * res_counter: fix off-by-one bug in setting limit + * forcedeth: fix kexec regression + * atmel_lcdfb: fix oops in rmmod when framebuffer fails to register + * tracehook: comment pasto fixes + * drivers/mmc/card/block.c: fix refcount leak in mmc_block_open() + * x86: boot: stub out unimplemented CPU feature words + * x86: add NOPL as a synthetic CPU feature bit + * x86: use X86_FEATURE_NOPL in alternatives + * clockevents: broadcast fixup possible waiters + * x86: HPET fix moronic 32/64bit thinko + * x86: HPET: read back compare register before reading counter + * Fix CONFIG_AC97_BUS dependency + * [ARM] 5241/1: provide ioremap_wc() + * ntp: fix calculation of the next jiffie to trigger RTC sync + * clocksource, acpi_pm.c: use proper read function also in errata mode + * clocksource, acpi_pm.c: check for monotonicity + * x86: delay early cpu initialization until cpuid is done + * x86: move mtrr cpu cap setting early in early_init_xxxx + * sched: arch_reinit_sched_domains() must destroy domains to force + rebuild + * x86, xen: Use native_pte_flags instead of native_pte_val for .pte_flags + * x86: pda_init(): fix memory leak when using CPU hotplug + * x86: cpu_init(): fix memory leak when using CPU hotplug + * powerpc/spufs: Fix possible scheduling of a context to multiple SPEs + * netfilter: nf_conntrack_sip: de-static helper pointers + * netfilter: nf_conntrack_gre: more locking around keymap list + * netfilter: nf_conntrack_gre: nf_ct_gre_keymap_flush() fixlet + * netfilter: nf_conntrack_irc: make sure string is terminated before + calling simple_strtoul + * pkt_sched: Fix qdisc state in net_tx_action() + * powerpc: Fix rare boot build breakage + * ahci, pata_marvell: play nicely together + * sata_mv: add RocketRaid 1720 PCI ID to driver + * ahci: disable PMP for marvell ahcis + * sata_nv: disable hardreset for generic + * libata-sff: kill spurious WARN_ON() in ata_hsm_move() + * pata_sil680: remove duplicate pcim_enable_device + * ahci: RAID mode SATA patch for Intel Ibex Peak DeviceIDs + * [MIPS] IP22: Fix detection of second HPC3 on Challenge S + * xen: fix 2.6.27-rc5 xen balloon driver warnings + * x86: disable static NOPLs on 32 bits + * netns : fix kernel panic in timewait socket destruction + * bridge: don't allow setting hello time to zero + * NFS: Restore missing hunk in NFS mount option parser + * usb: fix null deferences in low level usb serial + * Fix format of MAINTAINERS + * sparc64: Disable timer interrupts in fixup_irqs(). + * [Bluetooth] Fix reference counting during ACL config stage + * [Bluetooth] Enforce correct authentication requirements + * [Bluetooth] Reject L2CAP connections on an insecure ACL link + * [S390] CVE-2008-1514: prevent ptrace padding area read/write in 31-bit + mode + * [S390] cio: Correct cleanup on error. + * [S390] cio: handle ssch() return codes correctly. + * [S390] cio: allow offline processing for disconnected devices + * ipsec: Restore larval states and socket policies in dump + * update Documentation/filesystems/Locking for 2.6.27 changes + * MAINTAINERS: add Atheros maintainer for atlx + * lib: Correct printk %pF to work on all architectures + * x86: fix memmap=exactmap boot argument + * clockevents: remove WARN_ON which was used to gather information + * ipv6: Fix OOPS in ip6_dst_lookup_tail(). + * Linux 2.6.27-rc6 + + -- Ben Collins Tue, 02 Sep 2008 12:45:56 -0400 + +linux (2.6.27-2.3) intrepid; urgency=low + + [ Ben Collins ] + + * build/retag: Make script save .orig of tags for later use + * ubuntu/lirc: Fix device_create call + * build/firmware: Put in-kernel firmware into version specific subdir + - LP: #262115 + * Rebase on linux-2.6 git. + * ABI bump + + [ Herton Ronaldo Krzesinski ] + + * SAUCE: (no-up) Apparmor warning fixes + + [ John Johansen ] + + * SAUCE: (no-up) Proper AppArmor ptrace updates for newer lsm API + + [ Mackenzie Morgan ] + + * SAUCE: Add quirk for ASUS Z37E to make sound audible after resume + - LP: #25896 + + -- Ben Collins Wed, 27 Aug 2008 14:03:05 -0400 + +linux (2.6.27-1.2) intrepid; urgency=low + + [ Amit Kucheria ] + + * SAUCE: make fc transport removal of target configurable + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + + [ Ben Collins ] + + * SAUCE: Lower warning level of some PCI messages + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: (no-up) version: Implement version_signature proc file. + * SAUCE: (no-up) connector.h: Add idx/val for drbd + * SAUCE: (no-up) swap: Add notify_swap_entry_free callback for compcache + * SAUCE: drivers: Remove some duplicate device entries in various modules + * SAUCE: (no-up) [AppArmor] merge with upstream subversion r1291 + * SAUCE: apparmor: Update for changes to ptrace lsm hooks + * SAUCE: (no-up) Enable ubuntu extra subdirectory + * SAUCE: applesmc: Add MacBookAir + * SAUCE: (no-up) ACPI: initramfs DSDT override support + * ubuntu: Add drbd module + * ubuntu: Add iscsitarget module + * ubuntu: Add BOM for iscsitarget + * ubuntu: Add squashfs driver + * SAUCE: (no-up) Check for squashfs superblock in initramfs mounting. + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Added et131x driver + * ubuntu: Add dm-raid4-5 driver + * ubuntu: Add ndiswrapper driver + * ubuntu: Added ram backed compressed swap module (compcache) + * ubuntu: Add misc drivers from hardy lum + * ubuntu: Add heci driver 3.2.0.24 + * ubuntu: Add ov511 and bt-sco drivers + * ubuntu: Add acx, prism2_usb wireless drivers + * ubuntu: Add at76 driver to build + * ubuntu: Add fsam7400 sw kill switch driver + * ubuntu: Added qc-usb driver + * ubuntu: e1000e: Upgraded module to 0.4.1.7 + * ubuntu: Added rfkill drivers + * ubuntu: VIA - Add VIA DRM Chrome9 3D engine + * ubuntu: unionfs: Added v1.4 module from hardy + * ubuntu: Add LIRC driver + * ubuntu: Add GFS driver + * ubuntu: New tlsup driver for toshiba laptops + * Update config files + * build/d-i: Remove obsolete dm modules + + [ Chuck Short ] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + + [ Colin Ian King ] + + * ubuntu: Add dm-loop + * SAUCE: Enable speedstep for sonoma processors. + + [ Dennis Noordsij ] + + * SAUCE: Work around ACPI corruption upon suspend on some Dell machines. + + [ Fabio M. Di Nitto ] + + * SAUCE: Export gfs2 symbols required for gfs1 kernel module + + [ Matthew Garrett ] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [ Michael Frey (Senior Manager, MID ] + + * SAUCE: Send HCI_RESET for Broadcomm 2046 + + [ Phillip Lougher ] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [ Stefan Bader ] + + * SAUCE: (no-up) Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: mmc: Increase power_up deleay to fix TI readers + + [ Tim Gardner ] + + * SAUCE: Add extra headers to linux-libc-dev + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: (no-up) Take care of orinoco_cs overlap with hostap_cs + * ubuntu: Add GNBD driver + + -- Ben Collins Sat, 23 Aug 2008 15:48:35 -0400 + +linux (2.6.27-0.0) intrepid; urgency=low + + * Not uploaded, placeholder for new release + + -- Ben Collins Sat, 23 Aug 2008 15:48:35 -0400 + +linux (2.6.26-5.17) intrepid; urgency=low + + [ Ben Collins ] + + * build/abi: Add tosh_smm symbol to blacklist + + -- Ben Collins Fri, 15 Aug 2008 09:29:34 -0400 + +linux (2.6.26-5.16) intrepid; urgency=low + + [ Ben Collins ] + + * Revert "SAUCE: toshiba_acpi: Rewrote most of the proc entry bits." + * Revert "SAUCE: Update toshiba_acpi.c to version 0.19a" + * build/config: Disable in-kernel toshiba driver(s) + * ubuntu/tlsup: New driver for toshiba laptops + * build/config: Enable TLSUP driver + * SAUCE: e1000e: Fix E1000E_ENABLED logic to check for our E1000E_NEW + driver as well + * ubuntu/e1000e: Remove E1000E_ENABLED option in local config + * build/config: Update configs to have E1000E_ENABLED set + * ubuntu/prism2: Remove duplicate device + + [ Fabio M. Di Nitto ] + + * SAUCE: Export gfs2 symbols required for gfs1 kernel module + + [ Stefan Bader ] + + * SAUCE: x86: HPET rework for SB700 + - LP: #255910 + + [ Tim Gardner ] + + * Add GNBD driver + * Enable GNBD driver + * SAUCE: Add GFS driver + * SAUCE: Enable gfs driver configs + * b43: Linksys WMP54G (BCM4306/3) card in a PCI format has an SPROM + coding + + [ Upstream Kernel Changes ] + + * KVM: x86 emulator: emulate clflush + * USB: quirk PLL power down mode + + -- Ben Collins Mon, 11 Aug 2008 13:19:28 -0400 + +linux (2.6.26-5.15) intrepid; urgency=low + + [ Ben Collins ] + + * Revert "SAUCE: Add blacklist support to fix Belkin bluetooth dongle." + - Superceded by upstream changes. + * build/config: New option enabled for uvcvideo + * build/control: Add Vcs-Git meta data to control file + * SAUCE: toshiba_acpi: Rewrote most of the new code + * abi/perm-blacklist: Add emu10k1 driver to blacklist + + [ Upstream Kernel Changes ] + + * pxamci: trivial fix of DMA alignment register bit clearing + * udplite: Protection against coverage value wrap-around + * ipv6: use timer pending + * ipv6: __KERNEL__ ifdef struct ipv6_devconf + * hdlcdrv: Fix CRC calculation. + * quota: fix possible infinite loop in quota code + * isofs: fix minor filesystem corruption + * KVM: VMX: Fix a wrong usage of vmcs_config + * KVM: SVM: fix suspend/resume support + * KVM: mmu_shrink: kvm_mmu_zap_page requires slots_lock to be held + * KVM: VMX: Add ept_sync_context in flush_tlb + * KVM: x86 emulator: Fix HLT instruction + * KVM: MMU: nuke shadowed pgtable pages and ptes on memslot destruction + * KVM: MMU: Fix potential race setting upper shadow ptes on nonpae hosts + * Patch Upstream: x86 ptrace: fix PTRACE_GETFPXREGS error + * rcu: fix rcu_try_flip_waitack_needed() to prevent grace-period stall + * Fix typos from signal_32/64.h merge + * x86 reboot quirks: add Dell Precision WorkStation T5400 + * USB: fix usb serial pm counter decrement for disconnected interfaces + * x86, suspend, acpi: enter Big Real Mode + * markers: fix duplicate modpost entry + * Fix build on COMPAT platforms when CONFIG_EPOLL is disabled + * proc: fix /proc/*/pagemap some more + * cpusets: fix wrong domain attr updates + * x86: fix crash due to missing debugctlmsr on AMD K6-3 + * ide-cd: fix oops when using growisofs + * rtc-at91rm9200: avoid spurious irqs + * vmlinux.lds: move __attribute__((__cold__)) functions back into final + .text section + * ARM: fix fls() for 64-bit arguments + * tcp: Clear probes_out more aggressively in tcp_ack(). + * sparc64: Fix lockdep issues in LDC protocol layer. + * sparc64: Fix cpufreq notifier registry. + * sparc64: Do not define BIO_VMERGE_BOUNDARY. + * iop-adma: fix platform driver hotplug/coldplug + * myri10ge: do not forget to setup the single slice pointers + * myri10ge: do not use mgp->max_intr_slots before loading the firmware + * ALSA: trident - pause s/pdif output + * V4L: cx18: Upgrade to newer firmware & update documentation + * DVB: dib0700: add support for Hauppauge Nova-TD Stick 52009 + * V4L: uvcvideo: Fix a buffer overflow in format descriptor parsing + * V4L: uvcvideo: Use GFP_NOIO when allocating memory during resume + * V4L: uvcvideo: Don't free URB buffers on suspend + * V4L: uvcvideo: Make input device support optional + * V4L: uvcvideo: Add support for Medion Akoya Mini E1210 integrated + webcam + * V4L: saa7134: Copy tuner data earlier to avoid overwriting manual tuner + type + * V4L: cx23885: Bugfix for concurrent use of /dev/video0 and /dev/video1 + * DVB: cx23885: Ensure PAD_CTRL is always reset to a sensible default + * DVB: cx23885: DVB Transport cards using DVB port VIDB/TS1 did not + stream + * DVB: cx23885: Reallocated the sram to avoid concurrent VIDB/C issues + * DVB: cx23885: SRAM changes for the 885 and 887 silicon parts + * x86: fix kernel_physical_mapping_init() for large x86 systems + * eCryptfs: use page_alloc not kmalloc to get a page of memory + * UML - Fix boot crash + * ixgbe: remove device ID for unsupported device + * mpc52xx_psc_spi: fix block transfer + * tmpfs: fix kernel BUG in shmem_delete_inode + * markers: fix markers read barrier for multiple probes + * VFS: increase pseudo-filesystem block size to PAGE_SIZE + * cpufreq acpi: only call _PPC after cpufreq ACPI init funcs got called + already + * b43legacy: Release mutex in error handling code + * ath5k: don't enable MSI, we cannot handle it yet + * Fix off-by-one error in iov_iter_advance() + * Linux 2.6.26.1 + * ftrace: remove unneeded documentation + * romfs_readpage: don't report errors for pages beyond i_size + * netfilter: nf_nat_sip: c= is optional for session + * SCSI: bsg: fix bsg_mutex hang with device removal + * x86: idle process - add checking for NULL early param + * x86: io delay - add checking for NULL early param + * Close race in md_probe + * Kprobe smoke test lockdep warning + * netfilter: xt_time: fix time's time_mt()'s use of do_div() + * linear: correct disk numbering error check + * SCSI: ch: fix ch_remove oops + * NFS: Ensure we zap only the access and acl caches when setting new acls + * jbd: fix race between free buffer and commit transaction + * Input: i8042 - add Intel D845PESV to nopnp list + * Input: i8042 - add Gericom Bellagio to nomux blacklist + * Input: i8042 - add Acer Aspire 1360 to nomux blacklist + * Bluetooth: Signal user-space for HIDP and BNEP socket errors + * Add compat handler for PTRACE_GETSIGINFO + * ALSA: hda - Fix wrong volumes in AD1988 auto-probe mode + * ALSA: hda - Fix DMA position inaccuracy + * ALSA: hda - Add missing Thinkpad Z60m support + * ALSA: emu10k1 - Fix inverted Analog/Digital mixer switch on Audigy2 + * vfs: fix lookup on deleted directory + * Ath5k: fix memory corruption + * Ath5k: kill tasklets on shutdown + * sound: ensure device number is valid in snd_seq_oss_synth_make_info + * Linux 2.6.26.2 + + -- Ben Collins Sun, 03 Aug 2008 13:25:02 -0400 + +linux (2.6.26-5.14) intrepid; urgency=low + + [ Ben Collins ] + + * SAUCE: applesmc: Add MacBookAir + * build: Do not build ddeb unless we are on the buildd + * build: control: Consistency in arch fields. + * SAUCE: Update toshiba_acpi.c to version 0.19a + - LP: #77026 + * build: Added perm blacklist support and per-module support to abi-check + - Blacklist p80211 module from abi checks + * ubuntu/lirc: Get rid of drivers symlink and use real include stuff + + + [ Colin Ian King ] + + * SAUCE: acerhk module - add support for Amilo A1650g keyboard + - LP: #84159 + * SAUCE: rt2x00: Fix OOPS on failed creation of rt2x00lib workqueue + - LP: #249242 + + [ Mario Limonciello ] + + * Add LIRC back in + + [ Tim Gardner ] + + * Makefile race condition can lead to ndiswrapper build failure + - LP: #241547 + * update linux-wlan-ng (prism2_usb) to upstream version 1861 + - LP: #245026 + + [ Upstream Kernel Changes ] + + * Fix typos from signal_32/64.h merge + + -- Ben Collins Fri, 01 Aug 2008 00:05:01 -0400 + +linux (2.6.26-5.13) intrepid; urgency=low + + [ Ben Collins ] + + * build: Make makedumpfile an amd64/i386 only build-dep + * ubuntu/acerhk: Fixup assembly to compile with newer binutils + + -- Ben Collins Sat, 26 Jul 2008 16:41:50 -0400 + +linux (2.6.26-4.12) intrepid; urgency=low + + [ Ben Collins ] + + * e1000e: Upgraded module to 0.4.1.7 upstream. Placed in ubuntu/, + in-kernel driver disabled + * config: Disable e1000e in-kernel, and enable newer driver in ubuntu/ + * rfkill: Update to 1.3 drivers, and move to common location + * ubuntu: Actually link kconfig/kbuild into rfkill subdir + * config: Enable loading dsdt from initramfs + - LP: #246222 + * ubuntu: [compcache] Update to fix crashes in improper BUG() + * build: Create a retag scripts to recover tags from rebases + * build: Updates for dbg pkg + * build: Make sure no empty lines show up in debian/files + * ubuntu: atl1e: Add new driver from 2.6.27-pre-rc1 + - LP: #243894 + * sys_getcwd: Fix some brokeness introduced by AppArmor __d_path + changes + - LP: #251223 + * ubuntu: unionfs: Added v1.4 module from hardy + * build: Add sub-flavour infrastructure, and virtual subflav + + [ Eric Piel ] + + * ACPI: Allow custom DSDT tables to be loaded from initramfs + + [ Kees Cook ] + + * AppArmor: Smack VFS patches + + [ Mario Limonciello ] + + * Work around ACPI corruption upon suspend on some Dell machines. + - LP: #183033 + + [ Tim Gardner ] + + * Export usbhid_modify_dquirk for LBM module bcm5974 + - LP: #250838 + * VIA - Add VIA DRM Chrome9 3D engine + - LP: #251862 + * Define TRUE/FALSE for VIA DRM driver. + + -- Ben Collins Tue, 15 Jul 2008 12:51:39 -0400 + +linux (2.6.26-4.11) intrepid; urgency=low + + [ Ben Collins ] + + * config: Enable bcm5974 driver in all configs + + [ 2.6.26-4.10 ] + + [ Amit Kucheria ] + + * Fix typo in GSPCA Makefile and make it compile + + [ Ben Collins ] + + * ubuntu: Remove UVC driver in favor of in-kernel one (-rc9) + * config: Updates for -rc9 + * ubuntu: Add acx, prism2_usb wireless drivers + * config: Enable prism2_usb and acx drivers. + * ubuntu: Add at76 driver to build + * config: Enable at76_usb driver. + * iscsitarget: Fix prototype for bi_end_io callback. + * acx: Fix section type mismatch warnings + * fsam7400: Add sw kill switch driver + * config: Enable fsam7400 driver + * qc-usb: Added new driver + * config: Enable qc-usb driver + * drbd: Remove built-in connector usage + * drbd: Do not define idx/val for connector here + * connector.h: Add idx/val for drbd + * bcm5974: Added new driver + + [ Kees Cook ] + + * SAUCE: [AppArmor] merge with upstream subversion r1291 + * SAUCE: [AppArmor] fix typo in selinux_inode_link + * SAUCE: [AppArmor] aufs patches + + [ Michael Frey (Senior Manager, MID ] + + * SAUCE: Send HCI_RESET for Broadcomm 2046 + - LP: #241749 + + [ Tim Gardner ] + + * SAUCE: Medion Akoya Mini E1210 + + [ Upstream Kernel Changes ] + + * Revert "BAST: Remove old IDE driver" + * ARM: OMAP: DMA: Don't mark channel active in omap_enable_channel_irq + * ARM: OMAP: Correcting the gpmc prefetch control register address + * debugobjects: fix lockdep warning + * [ARM] 5115/1: pxafb: fix ifdef for command line option handling + * [ARM] 5116/1: pxafb: cleanup and fix order of failure handling + * [ARM] 5109/1: Mark rtc sa1100 driver as wakeup source before + registering it + * [ARM] Export dma_sync_sg_for_device() + * fix cgroup-inflicted breakage in block_dev.c + * [patch for 2.6.26 2/4] vfs: utimensat(): be consistent with utime() for + immutable and append-only files + * [patch for 2.6.26 1/4] vfs: utimensat(): ignore tv_sec if tv_nsec == + UTIME_OMIT or UTIME_NOW + * [patch for 2.6.26 3/4] vfs: utimensat(): fix error checking for + {UTIME_NOW,UTIME_OMIT} case + * [patch for 2.6.26 4/4] vfs: utimensat(): fix write access check for + futimens() + * [patch 1/4] vfs: path_{get,put}() cleanups + * [patch 2/4] fs: make struct file arg to d_path const + * [patch 3/4] vfs: fix ERR_PTR abuse in generic_readlink + * [patch 4/4] flock: remove unused fields from file_lock_operations + * [patch 3/3] vfs: make d_path() consistent across mount operations + * [patch 1/3] vfs: dcache sparse fixes + * [patch 2/3] vfs: dcache cleanups + * udf: Fix regression in UDF anchor block detection + * [SCSI] ses: Fix timeout + * netfilter: ip6table_mangle: don't reroute in LOCAL_IN + * [SCSI] esp: Fix OOPS in esp_reset_cleanup(). + * kernel/audit.c: nlh->nlmsg_type is gotten more than once + * audit: fix kernel-doc parameter notation + * remove useless argument type in audit_filter_user() + * Blackfin arch: fix bug - kernel boot fails when Spinlock and rw-lock + debugging enabled + * Blackfin arch: fix up section mismatch warning + * mac80211: implement EU regulatory domain + * b43: Do not return TX_BUSY from op_tx + * b43legacy: Do not return TX_BUSY from op_tx + * b43: Fix possible MMIO access while device is down + * b43legacy: Fix possible NULL pointer dereference in DMA code + * rt2x00: Fix unbalanced mutex locking + * iwlwifi: improve scanning band selection management + * [SCSI] esp: tidy up target reference counting + * [ARM] 5117/1: pxafb: fix __devinit/exit annotations + * thermal: Create CONFIG_THERMAL_HWMON=n + * ACPI: don't walk tables if ACPI was disabled + * dock: bay: Don't call acpi_walk_namespace() when ACPI is disabled. + * x86: shift bits the right way in native_read_tscp + * x86: section/warning fixes + * V4L/DVB (8004): Fix INPUT dependency at budget-ci + * V4L/DVB (8005): Fix OOPS if frontend is null + * V4L/DVB (8007): cx18/cx25840: the S-Video LUMA input can use all + In1-In8 inputs + * V4L/DVB (8008): cx18: remove duplicate audio and video input enums + * V4L/DVB (8010): em28xx: Properly register extensions for already + attached devices + * V4L/DVB (8011): em28xx: enable DVB for HVR-900 + * V4L/DVB (8012): gl861: sleep a little to avoid I2C errors + * V4L/DVB (8013): gl861: remove useless identify_state + * V4L/DVB (8015): gl861: replace non critical msleep(0) with msleep(1) to + be on the safe side + * V4L/DVB (8017): Ensure em28xx extensions only get run against devs that + support them + * V4L/DVB (8018): Add em2860 chip ID + * V4L/DVB (8020): Fix callbacks functions of saa7134_empress + * V4L/DVB (8022): saa7134: fix race between opening and closing the + device + * V4L/DVB (8026): Avoids an OOPS if dev struct can't be successfully + recovered + * V4L/DVB (8027): saa7134: Avermedia A700: only s-video and composite + input are working + * V4L/DVB (8028): Improve error messages for tda1004x attach + * V4L/DVB (8029): Improve error message at tda1004x_attach + * V4L/DVB (8034): tda18271: fix IF notch frequency handling + * V4L/DVB (8035): tda18271: dont touch EB14 if rf_cal lookup is out of + range + * V4L/DVB (8036): tda18271: toggle rf agc speed mode on TDA18271HD/C2 + only + * V4L/DVB (8037): tda18271: ensure that the thermometer is off during + channel configuration + * V4L/DVB (8039): pxa-camera: fix platform_get_irq() error handling. + * V4L/DVB (8040): soc-camera: remove soc_camera_host_class class + * V4L/DVB (8042): DVB-USB UMT-010 channel scan oops + * V4L/DVB (8043): au0828: add support for additional USB device id's + * V4L/DVB (8044): au8522: tuning optimizations + * V4L/DVB (8048): saa7134: Fix entries for Avermedia A16d and Avermedia + E506 + * V4L/DVB (8061): cx18: only select tuner / frontend modules if + !DVB_FE_CUSTOMISE + * V4L/DVB (8063): cx18: Fix unintended auto configurations in + cx18-av-core + * V4L/DVB (8066): cx18: Fix audio mux input definitions for HVR-1600 Line + In 2 and FM radio + * V4L/DVB (8067): cx18: Fix firmware load for case when digital capture + happens first + * V4L/DVB (8068): cx18: Add I2C slave reset via GPIO upon initialization + * V4L/DVB (8069): cx18: Fix S-Video and Compsite inputs for the Yuan + MPC718 and enable card entry + * V4L/DVB (8071): tda10023: Fix possible kernel oops during + initialisation + * V4L/DVB (8073): av7110: Catch another type of ARM crash + * V4L/DVB (8074): av7110: OSD transfers should not be interrupted + * V4L/DVB (8075): stv0299: Uncorrected block count and bit error rate + fixed + * V4L/DVB (8092): videodev: simplify and fix standard enumeration + * V4L/DVB (8096): au8522: prevent false-positive lock status + * V4L/DVB (8097): xc5000: check device hardware state to determine if + firmware download is needed + * V4L/DVB (8100): V4L/vivi: fix possible memory leak in vivi_fillbuff + * V4L/DVB (8108): Fix open/close race in saa7134 + * s2io: fix documentation about intr_type + * tc35815: Mark carrier-off before starting PHY + * tc35815: Fix receiver hangup on Rx FIFO overflow + * ixgbe: fix EEH recovery during reset on PPC + * igb: fix EEH recovery during reset on PPC + * e1000e: fix EEH recovery during reset on PPC + * pcnet_cs, axnet_cs: clear bogus interrupt before request_irq + * drivers/net/r6040.c: Eliminate double sizeof + * ipg: fix jumbo frame compilation + * ipg: use NULL, not zero, for pointers + * [netdrvr] 3c59x: remove irqs_disabled warning from local_bh_enable + * [netdrvr] netxen: fix netxen_pci_tbl[] breakage + * e100: Do pci_dma_sync after skb_alloc for proper operation on ixp4xx + * e1000: only enable TSO6 via ethtool when using correct hardware + * [netdrvr] Fix IOMMU overflow checking in s2io.c + * qla3xxx: Hold RTNL while calling dev_close() + * Hold RTNL while calling dev_close() + * sata_uli: hardreset is broken + * rt2x00: Fix lock dependency errror + * prism: islpci_eth.c endianness fix + * mac80211: fix an oops in several failure paths in key allocation + * firewire: fw-sbp2: fix parsing of logical unit directories + * kbuild: fix a.out.h export to userspace with O= build. + * Ensure interrupted recovery completed properly (v1 metadata plus + bitmap) + * Don't acknowlege that stripe-expand is complete until it really is. + * Fix error paths if md_probe fails. + * hamradio: remove unused variable + * tcp: calculate tcp_mem based on low memory instead of all memory + * tcp: fix for splice receive when used with software LRO + * af_unix: fix 'poll for write'/connected DGRAM sockets + * netdevice: Fix typo of dev_unicast_add() comment + * pkt_sched: ERR_PTR() ususally encodes an negative errno, not positive. + * pkt_sched: Remove CONFIG_NET_SCH_RR + * include/linux/netdevice.h: don't export MAX_HEADER to userspace + * tcp: /proc/net/tcp rto,ato values not scaled properly (v2) + * netlink: Fix some doc comments in net/netlink/attr.c + * CONNECTOR: add a proc entry to list connectors + * inet fragments: fix race between inet_frag_find and + inet_frag_secret_rebuild + * net/inet_lro: remove setting skb->ip_summed when not LRO-able + * netlabel: Fix a problem when dumping the default IPv6 static labels + * ipv6 route: Convert rt6_device_match() to use RT6_LOOKUP_F_xxx flags. + * sched: fix cpu hotplug + * Fix and clean top .gitignore + * x86: fix cpu hotplug crash + * ptrace GET/SET FPXREGS broken + * Input: add KEY_MEDIA_REPEAT definition + * Input: fix locking in force-feedback core + * [ARM] 5131/1: Annotate platform_secondary_init with trace_hardirqs_off + * ide: fix /proc/ide/ide?/mate reporting + * netfilter: nf_conntrack_tcp: fixing to check the lower bound of valid + ACK + * textsearch: fix Boyer-Moore text search bug + * hostap: don't report useless WDS frames by default + * hostap: fix sparse warnings + * mac80211: don't accept WEP keys other than WEP40 and WEP104 + * V4L/DVB (8145a): USB Video Class driver + * [IA64] Bugfix for system with 32 cpus + * [IA64] export account_system_vtime + * sched: fix divide error when trying to configure rt_period to zero + * x86: fix NODES_SHIFT Kconfig range + * block: Fix the starving writes bug in the anticipatory IO scheduler + * Properly notify block layer of sync writes + * rcu: fix hotplug vs rcu race + * I2C: S3C2410: Check ACK on byte transmission + * I2C: S3C2410: Fixup error codes returned rom a transfer. + * I2C: S3C2410: Add MODULE_ALIAS() for s3c2440 device. + * PCI: Restrict VPD read permission to root + * powerpc/bootwrapper: update for initrd with simpleImage + * i2c: Documentation: fix device matching description + * i2c: Fix bad hint about irqs in i2c.h + * powerpc/legacy_serial: Bail if reg-offset/shift properties are present + * powerpc/mpc5200: Fix lite5200b suspend/resume + * ipv4: fix sysctl documentation of time related values + * net-sched: change tcf_destroy_chain() to clear start of filter list + * net-sched: fix filter destruction in atm/hfsc qdisc destruction + * netlink: Unneeded local variable + * net: Tyop of sk_filter() comment + * netdevice: Fix wrong string handle in kernel command line parsing + * net: fib_rules: fix error code for unsupported families + * dm crypt: use cond_resched + * V4L/DVB (8178): uvc: Fix compilation breakage for the other drivers, if + uvc is selected + * PCI: Limit VPD read/write lengths for Broadcom 5706, 5708, 5709 rev. + * PCI: acpiphp: cleanup notify handler on all root bridges + * drivers/input/ff-core.c needs + * DRM/i915: only use tiled blits on 965+ + * tty: Fix inverted logic in send_break + * x86: fix Intel Mac booting with EFI + * arch/x86/mm/init_64.c: early_memtest(): fix types + * 9p: fix O_APPEND in legacy mode + * slub: Do not use 192 byte sized cache if minimum alignment is 128 byte + * Do not overwrite nr_zones on !NUMA when initialising zlcache_ptr + * [MIPS] IP32: Fix unexpected irq 71 + * [MIPS] IP22: Fix crashes due to wrong L1_CACHE_BYTES + * [MIPS] cevt-txx9: Reset timer counter on initialization + * hrtimer: prevent migration for raising softirq + * svcrpc: fix handling of garbage args + * OHCI: Fix problem if SM501 and another platform driver is selected + * USB: fix cdc-acm resume() + * USB: ehci - fix timer regression + * USB: ohci - record data toggle after unlink + * USB: mass storage: new id for US_SC_CYP_ATACB + * sisusbvga: Fix oops on disconnect. + * USB: New device ID for ftdi_sio driver + * USB: fix interrupt disabling for HCDs with shared interrupt handlers + * USB: don't lose disconnections during suspend + * USB: another option device id + * USB: add a pl2303 device id + * USB: fix Oops on loading ipaq module since 2.6.26 + * USB: adding comment for ipaq forcing number of ports + * [MIPS] Fix bug in atomic_sub_if_positive. + * xen: fix address truncation in pte mfn<->pfn conversion + * sata_sil24: add DID for another adaptec flavor + * ahci: always clear all bits in irq_stat + * libata-sff: improve HSM violation reporting + * sata_mv: safer logic for limit_warnings + * Update maintainers for powerpc + * Christoph has moved + * mm: dirty page accounting vs VM_MIXEDMAP + * rtc: rtc_read_alarm() handles wraparound + * firmware: fix the request_firmware() dummy + * serial: fix serial_match_port() for dynamic major tty-device numbers + * get_user_pages(): fix possible page leak on oom + * rtc-x1205: Fix alarm set + * rtc: fix CMOS time error after writing /proc/acpi/alarm + * pci: VT3336 can't do MSI either + * Miguel Ojeda has moved + * ext3: add missing unlock to error path in ext3_quota_write() + * ext4: add missing unlock to an error path in ext4_quota_write() + * reiserfs: add missing unlock to an error path in reiserfs_quota_write() + * ecryptfs: remove unnecessary mux from ecryptfs_init_ecryptfs_miscdev() + * lib: taint kernel in common report_bug() WARN path. + * gpio: pca953x (i2c) handles max7310 too + * fsl_diu_fb: fix build with CONFIG_PM=y, plus fix some warnings + * Update taskstats-struct document for scaled time accounting + * cciss: fix regression that no device nodes are created if no logical + drives are configured. + * delay accounting: maintainer update + * Doc*/kernel-parameters.txt: fix stale references + * hdaps: add support for various newer Lenovo thinkpads + * mn10300: export certain arch symbols required to build allmodconfig + * mn10300: provide __ucmpdi2() for MN10300 + * Introduce rculist.h + * man-pages is supported + * ntfs: update help text + * add kernel-doc for simple_read_from_buffer and memory_read_from_buffer + * w100fb: do not depend on SHARPSL + * w100fb: add 80 MHz modeline + * MFD maintainer + * cgroups: document the effect of attaching PID 0 to a cgroup + * spi: fix the read path in spidev + * doc: doc maintainers + * security: filesystem capabilities: fix fragile setuid fixup code + * security: filesystem capabilities: fix CAP_SETPCAP handling + * Alpha Linux kernel fails with inconsistent kallsyms data + * cpusets: document proc status cpus and mems allowed lists + * MAINTAINERS: update the email address of Andreas Dilger + * cciss: read config to obtain max outstanding commands per controller + * olpc: sdhci: add quirk for the Marvell CaFe's vdd/powerup issue + * olpc: sdhci: add quirk for the Marvell CaFe's interrupt timeout + * cpumask: introduce new APIs + * mm: switch node meminfo Active & Inactive pages to Kbytes + * Update MAINTAINERS file for the TPM device driver + * devcgroup: fix odd behaviour when writing 'a' to devices.allow + * doc: document the relax_domain_level kernel boot argument + * mmc: don't use DMA on newer ENE controllers + * mempolicy: mask off internal flags for userspace API + * x86 ACPI: normalize segment descriptor register on resume + * x86 ACPI: fix resume from suspend to RAM on uniprocessor x86-64 + * softlockup: print a module list on being stuck + * ide: fix hwif->gendev refcounting + * ide: ide_unregister() warm-plug bugfix + * ide: ide_unregister() locking bugfix + * ahci: give another shot at clearing all bits in irq_stat + * Fix clear_refs_write() use of struct mm_walk + * Move _RET_IP_ and _THIS_IP_ to include/linux/kernel.h + * Fix pagemap_read() use of struct mm_walk + * Linux 2.6.26-rc9 + * Revert "USB: don't explicitly reenable root-hub status interrupts" + * Revert "PCI: Correct last two HP entries in the bfsort whitelist" + * iwlwifi: fix incorrect 5GHz rates reported in monitor mode + * iwlwifi: drop skb silently for Tx request in monitor mode + * libertas: support USB persistence on suspend/resume (resend) + * tcp: net/ipv4/tcp.c needs linux/scatterlist.h + * tcp: fix a size_t < 0 comparison in tcp_read_sock + * bridge: fix use-after-free in br_cleanup_bridges() + * Add missing skb->dev assignment in Frame Relay RX code + * forcedeth: fix lockdep warning on ethtool -s + * ehea: fix might sleep problem + * ehea: add MODULE_DEVICE_TABLE + * ehea: fix race condition + * ehea: Access iph->tot_len with correct endianness + * pasemi_mac: Access iph->tot_len with correct endianness + * ibm_newemac: Fixes kernel crashes when speed of cable connected changes + * ibm_newemac: Fixes entry of short packets + * fs_enet: restore promiscuous and multicast settings in restart() + * can: add sanity checks + * x86: KVM guest: Add memory clobber to hypercalls + * KVM: IOAPIC: Fix level-triggered irq injection hang + * [SCSI] erase invalid data returned by device + * pxamci: fix byte aligned DMA transfers + * vsprintf: split out '%s' handling logic + * vsprintf: split out '%p' handling logic + * vsprintf: add infrastructure support for extended '%p' specifiers + * vsprintf: add support for '%pS' and '%pF' pointer formats + * powerpc: Fix unterminated of_device_id array in legacy_serial.c + * [UML] fix gcc ICEs and unresolved externs + * ocfs2/dlm: Fixes oops in dlm_new_lockres() + * hostap_cs: correct poor NULL checks in suspend/resume routines + * drivers/net/wireless/iwlwifi/iwl-3945.c Fix type issue on 64bit + * mac80211: move netif_carrier_on to after + ieee80211_bss_info_change_notify + * mac80211: Only flush workqueue when last interface was removed + * zd1211rw: add ID for AirTies WUS-201 + * ssb-pcicore: Fix IRQ-vector init on embedded devices + * mac80211: don't report selected IBSS when not found + * crypto: tcrypt - Fix memory leak in test_cipher + * sctp: Mark the tsn as received after all allocations finish + * [S390] protect _PAGE_SPECIAL bit against mprotect + * irda: via-ircc proper dma freeing + * irda: New device ID for nsc-ircc + * irda: Fix netlink error path return value + * [SCSI] mptspi: fix oops in mptspi_dv_renegotiate_work() + * Correct hash flushing from huge_ptep_set_wrprotect() + * ide: add __ide_default_irq() inline helper + * palm_bk3710: fix IDECLK period calculation + * it8213: fix return value in it8213_init_one() + * [MIPS] Atlas, decstation: Fix section mismatches triggered by + defconfigs + * [MIPS] Fix 32bit kernels on R4k with 128 byte cache line size + * NFS: Fix readdir cache invalidation + * SUNRPC: Fix a double-free in rpcbind + * SUNRPC: Fix an rpcbind breakage for the case of IPv6 lookups + * reiserfs: discard prealloc in reiserfs_delete_inode + * Fix broken fix for fsl-diu-db + * RDMA/cxgb3: Fix regression caused by class_device -> device conversion + * ipv6: fix race between ipv6_del_addr and DAD timer + * sctp: Add documentation for sctp sysctl variable + * kernel/printk.c: Made printk_recursion_bug_msg static. + * powerpc: Add missing reference to coherent_dma_mask + * rc80211_pid: Fix fast_start parameter handling + * rt2x00: Disable synchronization during initialization + * zd1211rw: stop beacons on remove_interface + * libertas: fix memory alignment problems on the blackfin + * netfilter: nf_conntrack_tcp: fix endless loop + * netfilter: nf_nat_snmp_basic: fix a range check in NAT for SNMP + * md: ensure all blocks are uptodate or locked when syncing + * sched: fix cpu hotplug + * x86: fix /dev/mem compatibility under PAT + * crypto: chainiv - Invoke completion function + * ocfs2: Fix flags in ocfs2_file_lock + * kernel/kprobes.c: Made kprobe_blacklist static. + * arch/x86/kernel/.gitignore: Added vmlinux.lds to .gitignore file + because it shouldn't be tracked. + * ftrace: Documentation + * Fix PREEMPT_RCU without HOTPLUG_CPU + * sched: fix cpu hotplug, cleanup + * exec: fix stack excutability without PT_GNU_STACK + * slub: Fix use-after-preempt of per-CPU data structure + * Documentation: clarify tcp_{r,w}mem sysctl docs + * ip: sysctl documentation cleanup + * tcp: correct kcalloc usage + * ipv4: fib_trie: Fix lookup error return + * netlabel: netlink_unicast calls kfree_skb on error path by itself + * ipv6: missed namespace context in ipv6_rthdr_rcv + * xfrm: Add a XFRM_STATE_AF_UNSPEC flag to xfrm_usersa_info + * tun: Persistent devices can get stuck in xoff state + * tpm: add Intel TPM TIS device HID + * rapidio: fix device reference counting + * Fix name of Russell King in various comments + * rtc: fix reported IRQ rate for when HPET is enabled + * libata-acpi: filter out DIPM enable + * Added Targa Visionary 1000 IDE adapter to pata_sis.c + * libata-acpi: don't call sleeping function from invalid context + * Fix reference counting race on log buffers + * [SCSI] ipr: Fix HDIO_GET_IDENTITY oops for SATA devices + * IPMI: return correct value from ipmi_write + * x86: fix ldt limit for 64 bit + * [SCSI] fusion: default MSI to disabled for SPI and FC controllers + * [SCSI] bsg: fix oops on remove + * drivers/char/pcmcia/ipwireless/hardware.c fix resource leak + * drivers/isdn/i4l/isdn_common.c fix small resource leak + * fbdev: bugfix for multiprocess defio + * serial8250: sanity check nr_uarts on all paths. + * ov7670: clean up ov7670_read semantics + * rtc-fm3130: fix chip naming + * rtc-pcf8563: add chip id + * OProfile kernel maintainership changes + * frv: fix irqs_disabled() to return an int, not an unsigned long + * cifs: fix inode leak in cifs_get_inode_info_unix + * cifs: fix wksidarr declaration to be big-endian friendly + * cpusets, hotplug, scheduler: fix scheduler domain breakage + * Documentation/HOWTO: correct wrong kernel bugzilla FAQ URL + * devcgroup: always show positive major/minor num + * devcgroup: fix permission check when adding entry to child cgroup + * Linux 2.6.26 + + -- Ben Collins Mon, 14 Jul 2008 13:41:50 -0400 + +linux (2.6.26-3.9) intrepid; urgency=low + + * abi: Add dca and ioatdma to modules.ignore + + [ 2.6.26-3.8 ] + + [ Ben Collins ] + + * ubuntu: Add heci driver 3.2.0.24 + * ubuntu: Add heci to kconfig/kbuild + * config: Enable heci module on all flavours + * dm-bbr: Update to get it to compile with 2.6.26 + * config: Enable dm-bbr + * ubuntu: Add some media drivers + * config: Enable misc media drivers + * udeb: Switch to uvesafb in fb-modules + * abi: Add more modules to ignore (known) + + [ 2.6.26-3.7 ] + + [Amit Kucheria] + + * SAUCE: make fc transport removal of target configurable + - LP: #163075 + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + + [Ben Collins] + + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: irda: Default to dongle type 9 on IBM hardware + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: version: Implement version_signature proc file. + * build: Cleanup arches + * build: Remove remnants of unused binary-custom infrastructure + * build: Remove disable_d_i (not needed) and cleanup ppa build stuff + * ubuntu: New modules, acer-acpi + * build: Remove -virtual, and rebuild configs + * ubuntu: Add drbd module + * acer-acpi: Fix makefile + * x86/Kconfig: Fix missing quote for ubuntu Kconfig source + * ubuntu: Add iscsitarget module + * ubuntu: Added Amiga FS driver + * ubuntu: Add squashfs driver + * ubuntu: Remove asfs (Amiga FS). Need to be in linux-ports instead + * squashfs: Move headers to real include directory + * build/configs: The Great Config Consistency Check of 2008 + * ubuntu: Move third-party includes to ubuntu/include + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Add dm-radi4-5 driver + * build: Add CONFIG_DEBUG_SECTION_MISMATCH=y to get old style warnings + from build + * ubuntu/Makefile: Fixup dm-raid4-5 and add kludge for kbuild + * squashfs: Fixes for VFS changes + * ubuntu/dm-raid4-5: Fixups for moved/renamed headers/functions in core + md + * ubuntu: Add ndiswrapper driver + * d-i: Update module listings + * build: Disable xd block device (ancient) + * ndiswrapper: Fixup makefile + * d-i: Remove efi-modules. The only module, efivars, is built-in + * build: Remove install-source, obsolete and caused build failure + * Ubuntu-2.6.26-1.3 + * build: linux-doc rules got broken when disabling html side. Fixed now. + * Ubuntu-2.6.26-1.4 + * x86: Update to -rc6 allows CONFIG_PCI_OLPC to work with PCI_GOANY + * d-i: Make virtio-ring optional (it's built-in on i386) + * Ubuntu-2.6.26-1.4 + * Ubuntu-2.6.26-1.5 + * config: Enable DVB devices + * ubuntu/aufs: Make aufs a bool config, since it needs to be built-in + * config: Build aufs into the kernels + * build: Fix arguments passed to link-headers script + * config: Disable early printk + * d-i: Move isofs to storage-core and kill st (scsi tape) from list + * config: Enable non-promiscuous access to /dev/mem + * x86: Add option to disable decompression info messages + * config: Enable no-bz-chatter config options + * build: Re-add linux-source package + * d-i: Re-add socket-modules. Accidentally removed + - LP: #241295 + * Ubuntu-2.6.26-2.6 + * Use makedumpfile to generate a vmcoreinfo file. + * build: Build-Depend on makedumpfile for vmcoreinfo generation + * build: Remove debug print from git-ubuntu-log + * Updated configs for -rc7 + * build: postinst, do not call depmod with -F + * config: Enable rtc-cmos as a built-in driver. + * control: Provide ndiswrapper-modules-1.9 + * build: Generate vmcoreinfo in image build for crashdumps without debug + image + * config: Disable vesafb, since we'll prefer uvesafb + * build: Copy uvesafb module to initrd mod directory + * abi-check: New, more robust script + * config: Enable heap randomization by default + * abi-check: Cleanup output and call with perl (not $SHELL) + * abi: Ignore missing vesafb (known) + * config: Disable pcspkr (in favor of snd-pcsp) + * swap: Add notify_swap_entry_free callback for compcache + * compcache: Added ram backed compressed swap module + * ubuntu: Enable kbuild and kconfig for compcache + * config: Enable compcache and tlsf allocator as modules + * config: Updated for -rc8. Disables XEN on i386 + * config: Switch i386-server to 64G, enable PAE, 64-bit res, and XEN + * ubuntu: Add misc drivers from hardy lum + * ubuntu: Enable build of misc/ subdir + * config: Enable misc drivers + * aufs: Fix warning about single non-string-literal arg to printf style + function + * drivers: Remove some duplicate device entries in various modules + * config: Disable some duplicate drivers + * keyspan: Remove duplicate device ID's + * check-aliases: Cleanup output, and fix rolling checks + * ubuntu: Disable dm-bbr for now + * dm-bbr: First cut at forward portiong. Still needs work. + * ubuntu: Disable dm-bbr in kbuild/kconfig + + [Chuck Short] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + - LP: #175834 + * SAUCE: [USB]: add ASUS LCM to the blacklist + + [Colin Ian King] + + * SAUCE: airprime.c supports more devices + - LP: #208250 + * SAUCE: Enable speedstep for sonoma processors. + - LP: #132271 + * Add dm-loop + * Add dm-loop BOM + + [Kyle McMartin] + + * SAUCE: fix orinoco_cs oops + + [Mario Limonciello] + + * SAUCE: Enable Reset and SCO workaround on Dell 410 BT adapter + + [Matthew Garrett] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [Phillip Lougher] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [Stefan Bader] + + * SAUCE: Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: Always use SCO protocol (disable eSCO support) Bug: #39414 + * SAUCE: mmc: Increase power_up deleay to fix TI readers OriginalAuthor: + Pascal Terjan Bug: #137686 + * SAUCE: Add blacklist support to fix Belkin bluetooth dongle. Bug: + #140511 + * SAUCE: Lower warning level of pci resource allocation messages. Bug: + 159241 + * SAUCE: Lower message level for PCI memory and I/O allocation. + - LP: #159241 + * Modify log generation to catch bug numbers when adding with git-am. + + [Tim Gardner] + + * Added the debian directory. Ignore: yes + * Add support for UBUNTUINCLUDE Ignore: yes + * LUM headers go in /usr/src Ignore: yes + * First pass at 2.6.25 configs Ignore: yes + * i386 -generic builds. Ignore: yes + * SAUCE: Increase CONFIG_IDE_MAX_HWIFS to 8 (from 4) + * SAUCE: Add extra headers to linux-libc-dev OriginalAuthor: Soren Hansen + OriginalLocation: + https://lists.ubuntu.com/archives/kernel-team/2007-November/001891.html + * Set CONFIG_DEVKMEM=n Ignore: yes + * Enabled ALSA and CGROUPS for i386 Ignore: yes + * Enabled amd64 configs. Ignore: yes + * CONFIG_STANDALONE=n Ignore: yes + * CONFIG_BLK_DEV_4DRIVES=n for i386 Ignore: yes + * CONFIG: CONFIG_DEFAULT_RELATIME=y for all flavours. Ignore: yes + * Set CONFIG_EDD_OFF=y Ignore: yes + * SAUCE: Blacklist Bluetooth Dell Wireless 370 for SCO MTU + OriginalAuthor: Mario Limonciello Bug: + #209715 + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: frame buffer regression - screen blank except for blinking + cursor after fbcon vtswitch OriginalAuthor: Matthew Garrett + Bug: #201591 + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + OriginalAuthor: Klaus S. Madsen + OriginalAuthor: Chuck Short + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: orinoco_cs.ko missing + * Set CONFIG_FB_VESA=m for i386/amd64 Ignore: yes + * Set CONFIG_PM_DISABLE_CONSOLE=y for all flavours Ignore: yes + * Thorough review of amd64 -generic config Ignore: yes + * Build PPA packages for Hardy until the Intrepid archive is opened. + * Deleted obsolete flavours Ignore: yes + * Don't build docs for PPA Ignore: yes + * Build all standard packages in PPA. Ignore: yes + * Remove duplicate USB ids + * SAUCE: DVB-USB UMT-010 driver oops on install Bug: #115284 + * Update configs after rebase to 2.6.26-rc1 Ignore: yes + * Update configs after rebase Ignore: yes + * Disable V4L until the build issues get ironed out. Ignore: yes + * Update configs after rebase. Ignore: yes + * Another device enable pass Ignore: yes + * Update configs after merge. Ignore: yes + * SAUCE: fn key doesn't work in hardy with macbook pro fourth generation + (4,1) + - LP: #207127 + * Enabled CONFIG_CIFS_DFS_UPCALL=y and CONFIG_CIFS_UPCALL=y + - LP: #236830 + + [Upstream Kernel Changes] + + * Revert "[WATCHDOG] hpwdt: Add CFLAGS to get driver working" + * mac80211: detect driver tx bugs + * hwmon: (lm85) Fix function RANGE_TO_REG() + * hwmon: (adt7473) Initialize max_duty_at_overheat before use + * hwmon: Update the sysfs interface documentation + * hwmon: (abituguru3) Identify Abit AW8D board as such + * hwmon: (w83791d) new maintainer + * hwmon: (abituguru3) update driver detection + * hwmon: (lm75) sensor reading bugfix + * ipv6: Remove options header when setsockopt's optlen is 0 + * ipv6: Drop packets for loopback address from outside of the box. + * sched: rt: dont stop the period timer when there are tasks wanting to + run + * sched: fix wait_for_completion_timeout() spurious failure under heavy + load + * x86: fix NULL pointer deref in __switch_to + * xen: Use wmb instead of rmb in xen_evtchn_do_upcall(). + * xen: mask unwanted pte bits in __supported_pte_mask + * xen: don't drop NX bit + * sched: refactor wait_for_completion_timeout() + * Ext4: Fix online resize block group descriptor corruption + * [IA64] SN2: security hole in sn2_ptc_proc_write + * alpha: fix module load failures on smp (bug #10926) + * alpha: link failure fix + * alpha: fix compile failures with gcc-4.3 (bug #10438) + * alpha: resurrect Cypress IDE quirk + * pppoe: warning fix + * sctp: Make sure N * sizeof(union sctp_addr) does not overflow. + * netns: Don't receive new packets in a dead network namespace. + * Add return value to reserve_bootmem_node() + * Slab: Fix memory leak in fallback_alloc() + * Fix performance regression on lmbench select benchmark + * ALSA: aw2 - Fix Oops at initialization + * ALSA: sb - Fix wrong assertions + * futexes: fix fault handling in futex_lock_pi + * IB/mthca: Clear ICM pages before handing to FW + * tty_driver: Update required method documentation + * removed unused var real_tty on n_tty_ioctl() + * Fix ZERO_PAGE breakage with vmware + * mm: fix race in COW logic + * NFS: Reduce the NFS mount code stack usage. + * NFS: Fix filehandle size comparisons in the mount code + * NFS: nfs_updatepage(): don't mark page as dirty if an error occurred + * alpha: fix compile error in arch/alpha/mm/init.c + * KVM: Fix race between timer migration and vcpu migration + * KVM: close timer injection race window in __vcpu_run + * KVM: MMU: Fix rmap_write_protect() hugepage iteration bug + * KVM: MMU: large page update_pte issue with non-PAE 32-bit guests + (resend) + * KVM: MMU: Fix oops on guest userspace access to guest pagetable + * KVM: ioapic: fix lost interrupt when changing a device's irq + * KVM: VMX: Fix host msr corruption with preemption enabled + * [GFS2] BUG: unable to handle kernel paging request at ffff81002690e000 + * xen: remove support for non-PAE 32-bit + * kgdb: documentation update - remove kgdboe + * kgdb: sparse fix + * [IA64] Fix boot failure on ia64/sn2 + * [IA64] Handle count==0 in sn2_ptc_proc_write() + * [IA64] Eliminate NULL test after alloc_bootmem in iosapic_alloc_rte() + * [GFS2] fix gfs2 block allocation (cleaned up) + * x86: Add structs and functions for paravirt clocksource + * x86: Make xen use the paravirt clocksource structs and functions + * KVM: Make kvm host use the paravirt clocksource structs + * x86: KVM guest: Use the paravirt clocksource structs and functions + * KVM: Remove now unused structs from kvm_para.h + * enable bus mastering on i915 at resume time + * Linux 2.6.26-rc8 + * # Ubuntu external driver commit. + * # Ubuntu commit template. + + -- Ben Collins Sat, 21 Jun 2008 09:05:15 -0400 + +linux (2.6.26-2.6) intrepid; urgency=low + + [Ben Collins] + + * Revert "SAUCE: Export symbols for aufs (in lum) (not needed) + * config: Enable DVB devices + * ubuntu/aufs: Make aufs a bool config, since it needs to be built-in + * config: Build aufs into the kernels + * build: Fix arguments passed to link-headers script + * config: Disable early printk + * d-i: Move isofs to storage-core and kill st (scsi tape) from list + * config: Enable non-promiscuous access to /dev/mem + * x86: Add option to disable decompression info messages + * config: Enable no-bz-chatter config options + * build: Re-add linux-source package + * d-i: Re-add socket-modules. Accidentally removed + - LP: #241295 + + [Colin Ian King] + + * Add dm-loop + + [Tim Gardner] + + * Revert "SAUCE: USB bluetooth device 0x0e5e:0x6622 floods errors to + syslog (merged upstream) + + -- Ben Collins Mon, 16 Jun 2008 10:56:01 -0400 + +linux (2.6.26-1.5) intrepid; urgency=low + + * d-i: Make virtio-ring optional (it's built-in on i386) + * Rebased on 2.6.26-rc6 + + [Ubuntu-2.6.26-1.4 Changes below] + + * build: linux-doc rules got broken when disabling html side. Fixed now. + + [Ubuntu-2.6.26-1.3 Changes below] + + * build: Remove install-source, obsolete and caused build failure + + [Ubuntu-2.6.26-1.2 Changes below] + + * Remove efi-modules from d-i module list (efivars is built-in). Caused a + build failure. + * Patch to arch/x86/xen/time.c to remove __divdi3 usage (build failure on + i386). + + [Ubuntu-2.6.26-1.1 Changes below] + + [Amit Kucheria] + + * SAUCE: make fc transport removal of target configurable + * SAUCE: Add AGP support for Radeon Mobility 9000 chipset + * SAUCE: pm: Config option to disable handling of console during + suspend/resume + + [Ben Collins] + + * SAUCE: input/mouse/alps: Do not call psmouse_reset() for alps + * SAUCE: irda: Default to dongle type 9 on IBM hardware + * SAUCE: tulip: Let dmfe handle davicom on non-sparc + * SAUCE: tulip: Define ULI PCI ID's + * SAUCE: version: Implement version_signature proc file. + * build: Remove remnants of unused binary-custom infrastructure + * mmc_block: Fix bad allocation on 64-bit (zero len array) + * ubuntu: New modules, acer-acpi + * build: Remove -virtual, and rebuild configs + * ubuntu: Add drbd module + * ubuntu: Add iscsitarget module + * ubuntu: Add squashfs driver + * build/configs: The Great Config Consistency Check of 2008 + * ubuntu: Add aufs module + * ubuntu: Added atl2 driver + * ubuntu: Add dm-radi4-5 driver + * build: Add CONFIG_DEBUG_SECTION_MISMATCH=y to get old style warnings + from build + * squashfs: Fixes for VFS changes + * ubuntu/dm-raid4-5: Fixups for moved/renamed headers/functions in core + md + * ubuntu: Add ndiswrapper driver + * d-i: Update module listings + + [Chuck Short] + + * SAUCE: ata: blacklist FUJITSU MHW2160BH PL + * SAUCE: [USB]: add ASUS LCM to the blacklist + + [Colin Ian King] + + * SAUCE: Enable speedstep for sonoma processors. + * SAUCE: airprime.c supports more devices + + [Kyle McMartin] + + * SAUCE: fix orinoco_cs oops + + [Mario Limonciello] + + * SAUCE: Enable Reset and SCO workaround on Dell 410 BT adapter + + [Matthew Garrett] + + * SAUCE: hostap: send events on data interface as well as master + interface + + [Phillip Lougher] + + * SAUCE: r8169: disable TSO by default for RTL8111/8168B chipsets. + + [Stefan Bader] + + * SAUCE: Export dm_disk function of device-mapper + * SAUCE: Restore VT fonts on switch + * SAUCE: Always use SCO protocol (disable eSCO support) Bug: #39414 + * SAUCE: mmc: Increase power_up deleay to fix TI readers + * SAUCE: Add blacklist support to fix Belkin bluetooth dongle. + * SAUCE: Lower warning level of pci resource allocation messages. + * SAUCE: Lower message level for PCI memory and I/O allocation. + - LP: #159241 + * Modify log generation to catch bug numbers when adding with git-am. + + [Tim Gardner] + + * SAUCE: hdaps module does not load on Thinkpad T61P + * SAUCE: Add extra headers to linux-libc-dev + * SAUCE: Export symbols for aufs (in lum). + * SAUCE: USB bluetooth device 0x0e5e:0x6622 floods errors to syslog + * SAUCE: Blacklist Bluetooth Dell Wireless 370 for SCO MTU + * SAUCE: Catch nonsense keycodes and silently ignore + * SAUCE: frame buffer regression - screen blank except for blinking + cursor after fbcon vtswitch + * SAUCE: Added support for HDAPS on various ThinkPads from Lenovo and IBM + * SAUCE: Guest OS does not recognize a lun with non zero target id on + Vmware ESX Server + * SAUCE: Modualrize vesafb + * SAUCE: DVB-USB UMT-010 driver oops on install + * SAUCE: fn key doesn't work in hardy with macbook pro fourth generation + (4,1) + - LP: #207127 + + -- Ben Collins Wed, 11 Jun 2008 05:28:35 -0400 --- linux-2.6.28.orig/debian/NOTES +++ linux-2.6.28/debian/NOTES @@ -0,0 +1,4 @@ +eSCO patch removed. Replaced upstream with a disable_esco module parm. +airprime: Module gone, use option driver instead +AppArmor: Patch is all there and ported. Ooops when enabled, so default + off (still can be enabled apparmor=1) --- linux-2.6.28.orig/debian/scripts/abi-check +++ linux-2.6.28/debian/scripts/abi-check @@ -0,0 +1,202 @@ +#!/usr/bin/perl -w + +my $flavour = shift; +my $prev_abinum = shift; +my $abinum = shift; +my $prev_abidir = shift; +my $abidir = shift; +my $skipabi = shift; + +my $fail_exit = 1; +my $EE = "EE:"; +my $errors = 0; + +my $count; + +print "II: Checking ABI for $flavour...\n"; + +if (-f "$prev_abidir/ignore" + or -f "$prev_abidir/$flavour.ignore" or "$skipabi" eq "true") { + print "WW: Explicitly asked to ignore ABI, running in no-fail mode\n"; + $fail_exit = 0; + $EE = "WW:"; +} + +if ($prev_abinum != $abinum) { + print "II: Different ABI's, running in no-fail mode\n"; + $fail_exit = 0; + $EE = "WW:"; +} + +if (not -f "$abidir/$flavour" or not -f "$prev_abidir/$flavour") { + print "EE: Previous or current ABI file missing!\n"; + print " $abidir/$flavour\n" if not -f "$abidir/$flavour"; + print " $prev_abidir/$flavour\n" if not -f "$prev_abidir/$flavour"; + # Always fail here. This is bad + exit(1); +} + +my %symbols; +my %symbols_ignore; +my %modules_ignore; +my %module_syms; + +# See if we have any ignores +my $ignore = 0; +print " Reading symbols/modules to ignore..."; + +for $file ("$prev_abidir/../blacklist", "$prev_abidir/../../perm-blacklist") { + if (-f $file) { + open(IGNORE, "< $file") or + die "Could not open $file"; + while () { + chomp; + if ($_ =~ m/M: (.*)/) { + $modules_ignore{$1} = 1; + } else { + $symbols_ignore{$_} = 1; + } + $ignore++; + } + close(IGNORE); + } +} +print "read $ignore symbols/modules.\n"; + +sub is_ignored($$) { + my ($mod, $sym) = @_; + + die "Missing module name in is_ignored()" if not defined($mod); + die "Missing symbol name in is_ignored()" if not defined($sym); + + if (defined($symbols_ignore{$sym}) or defined($modules_ignore{$mod})) { + return 1; + } + return 0; +} + +# Read new syms first +print " Reading new symbols ($abinum)..."; +$count = 0; +open(NEW, "< $abidir/$flavour") or + die "Could not open $abidir/$flavour"; +while () { + chomp; + m/^(EXPORT_.+)\s(.+)\s(0x[0-9a-f]+)\s(.+)$/; + $symbols{$4}{'type'} = $1; + $symbols{$4}{'loc'} = $2; + $symbols{$4}{'hash'} = $3; + $module_syms{$2} = 0; + $count++; +} +close(NEW); +print "read $count symbols.\n"; + +# Now the old symbols, checking for missing ones +print " Reading old symbols ($prev_abinum)..."; +$count = 0; +open(OLD, "< $prev_abidir/$flavour") or + die "Could not open $prev_abidir/$flavour"; +while () { + chomp; + m/^(EXPORT_.+)\s(.+)\s(0x[0-9a-f]+)\s(.+)$/; + $symbols{$4}{'old_type'} = $1; + $symbols{$4}{'old_loc'} = $2; + $symbols{$4}{'old_hash'} = $3; + $count++; +} +close(OLD); + +print "read $count symbols.\n"; + +print "II: Checking for missing symbols in new ABI..."; +$count = 0; +foreach $sym (keys(%symbols)) { + if (!defined($symbols{$sym}{'type'})) { + print "\n" if not $count; + printf(" MISS : %s%s\n", $sym, + is_ignored($symbols{$sym}{'old_loc'}, $sym) ? " (ignored)" : ""); + $count++ if !is_ignored($symbols{$sym}{'old_loc'}, $sym); + } +} +print " " if $count; +print "found $count missing symbols\n"; +if ($count) { + print "$EE Symbols gone missing (what did you do!?!)\n"; + $errors++; +} + + +print "II: Checking for new symbols in new ABI..."; +$count = 0; +foreach $sym (keys(%symbols)) { + if (!defined($symbols{$sym}{'old_type'})) { + print "\n" if not $count; + print " NEW : $sym\n"; + $count++; + } +} +print " " if $count; +print "found $count new symbols\n"; +if ($count and $prev_abinum == $abinum) { + print "WW: Found new symbols within same ABI. Not recommended\n"; +} + +print "II: Checking for changes to ABI...\n"; +$count = 0; +my $moved = 0; +my $changed_type = 0; +my $changed_hash = 0; +foreach $sym (keys(%symbols)) { + if (!defined($symbols{$sym}{'old_type'}) or + !defined($symbols{$sym}{'type'})) { + next; + } + + # Changes in location don't hurt us, but log it anyway + if ($symbols{$sym}{'loc'} ne $symbols{$sym}{'old_loc'}) { + printf(" MOVE : %-40s : %s => %s\n", $sym, $symbols{$sym}{'old_loc'}, + $symbols{$sym}{'loc'}); + $moved++; + } + + # Changes to export type are only bad if new type isn't + # EXPORT_SYMBOL. Changing things to GPL are bad. + if ($symbols{$sym}{'type'} ne $symbols{$sym}{'old_type'}) { + printf(" TYPE : %-40s : %s => %s%s\n", $sym, $symbols{$sym}{'old_type'}. + $symbols{$sym}{'type'}, is_ignored($symbols{$sym}{'loc'}, $sym) + ? " (ignored)" : ""); + $changed_type++ if $symbols{$sym}{'type'} ne "EXPORT_SYMBOL" + and !is_ignored($symbols{$sym}{'loc'}, $sym); + } + + # Changes to the hash are always bad + if ($symbols{$sym}{'hash'} ne $symbols{$sym}{'old_hash'}) { + printf(" HASH : %-40s : %s => %s%s\n", $sym, $symbols{$sym}{'old_hash'}, + $symbols{$sym}{'hash'}, is_ignored($symbols{$sym}{'loc'}, $sym) + ? " (ignored)" : ""); + $changed_hash++ if !is_ignored($symbols{$sym}{'loc'}, $sym); + $module_syms{$symbols{$sym}{'loc'}}++; + } +} + +print "WW: $moved symbols changed location\n" if $moved; +print "$EE $changed_type symbols changed export type and weren't ignored\n" if $changed_type; +print "$EE $changed_hash symbols changed hash and weren't ignored\n" if $changed_hash; + +$errors++ if $changed_hash or $changed_type; +if ($changed_hash) { + print "II: Module hash change summary...\n"; + foreach $mod (sort { $module_syms{$b} <=> $module_syms{$a} } keys %module_syms) { + next if ! $module_syms{$mod}; + printf(" %-40s: %d\n", $mod, $module_syms{$mod}); + } +} + +print "II: Done\n"; + +if ($errors) { + exit($fail_exit); +} else { + exit(0); +} --- linux-2.6.28.orig/debian/scripts/control-create +++ linux-2.6.28/debian/scripts/control-create @@ -0,0 +1,23 @@ +#!/bin/bash + +vars=$1 + +. $vars + +if [ "$is_sub" = "" ]; then + flavour=$(basename $vars | sed 's/.*\.//') + stub=debian/control.d/flavour-control.stub +else + flavour=$(basename $vars .vars) + stub=debian/sub-flavours/control.stub +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#=CONFLICTS=#$conflicts#g" --- linux-2.6.28.orig/debian/scripts/sub-flavour +++ linux-2.6.28/debian/scripts/sub-flavour @@ -0,0 +1,30 @@ +#!/bin/bash -e + + + +echo "SUB_PROCESS $FROM => $TO" + +export from_pkg="linux-image-$ABI_RELEASE-$FROM" +export to_pkg="linux-image-$ABI_RELEASE-$TO" + +from_moddir="debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM" +to_moddir="debian/$to_pkg/lib/modules/$ABI_RELEASE-$FROM" + +install -d "debian/$to_pkg/boot" +install -m644 debian/$from_pkg/boot/{vmlinuz,System.map}-$ABI_RELEASE-$FROM \ + debian/$to_pkg/boot/ + +cat debian/sub-flavours/$TO.list | while read line; do + (cd debian/$from_pkg/lib/modules/$ABI_RELEASE-$FROM/kernel; + eval find $line -name '*.ko'); +done | while read mod; do + echo "SUB_INST $mod" + grep "^/lib/modules/$ABI_RELEASE-$FROM/kernel/$mod:" \ + $from_moddir/modules.dep | sed -e 's/://' -e 's/ /\n/g' | \ + while read m; do + test -f debian/$to_pkg/$m && continue + echo "SUB_INST $mod" + install -D -m644 debian/$from_pkg/$m \ + debian/$to_pkg/$m + done +done --- linux-2.6.28.orig/debian/scripts/module-check +++ linux-2.6.28/debian/scripts/module-check @@ -0,0 +1,120 @@ +#!/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"; + if (defined($skipmodule)) { + exit(0); + } else { + 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; + next if /\s*#/; + $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-2.6.28.orig/debian/scripts/link-headers +++ linux-2.6.28/debian/scripts/link-headers @@ -0,0 +1,40 @@ +#!/bin/bash -e + +hdrdir="$1" +symdir="$2" +flavour="$3" + +echo "Symlinking and copying headers for $flavour..." + +excludes='( -path ./debian -prune -o -path ./.git ) -prune -o' + +( +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-2.6.28.orig/debian/scripts/misc/ppa-cron-job +++ linux-2.6.28/debian/scripts/misc/ppa-cron-job @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# Use this script as a template for the daily kernel build cron job. +# You should copy it somewhere outside of the git tree 'cause the whole +# git tree gets removed and recreated. +# +KNAME=jaunty +DAILY_BUILD_DIR=${KBDIR:=${HOME}/${KNAME}} +KERNEL_GIT_REPO=${KREPO:=/srv/kernel.ubuntu.com/git/ubuntu/ubuntu-${KNAME}.git} + +# +# Nothing works unless there is a dput configuration. +# +if [ ! -f ${HOME}/.dput.cf ] +then + echo No dput configuration. + exit 1 +fi + +if [ ! -d ${DAILY_BUILD_DIR} ] +then + rm -rf ${DAILY_BUILD_DIR} + mkdir -p ${DAILY_BUILD_DIR} +fi + +# +# Start with a fresh repo. +# +cd ${DAILY_BUILD_DIR} +rm -rf ubuntu-${KNAME} +git clone ${KERNEL_GIT_REPO} + +# +# Remember that the success of prepare-ppa depends on +# this user account having an un-passworded GPG key. +# Otherwise it requires user intervention, e.g., a +# user must enter the GPG key password. +# +rm -f *.changes +(cd ubuntu-${KNAME}; debian/scripts/misc/prepare-ppa-source) + +find . -maxdepth 1 -type f -name "*.changes" | while read f +do + echo dput my-ppa $f +done + --- linux-2.6.28.orig/debian/scripts/misc/doconfig +++ linux-2.6.28/debian/scripts/misc/doconfig @@ -0,0 +1,65 @@ +#!/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 + amd64) kernarch="x86_64" ;; + armel) kernarch="arm" ;; + *) 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 + + cat $confdir/$config > .config + + echo About to configure $arch $config + read + make -C ../ O=`pwd` ARCH=$kernarch menuconfig + + cat .config > $confdir/$config +done +cd .. + +echo "Running splitconfig.pl ... " +echo + +(cd $confdir ; $bindir/splitconfig.pl) --- linux-2.6.28.orig/debian/scripts/misc/retag +++ linux-2.6.28/debian/scripts/misc/retag @@ -0,0 +1,34 @@ +#!/usr/bin/perl -w + +open(TAGS, "git tag -l |") or die "Could not get list of tags"; +@tags = ; +close(TAGS); + +open(LOGS, "git log --pretty=short |") or die "ERROR: Calling git log"; +my $commit = ""; + +while () { + my $origtag; + + if (m|^commit (.*)$|) { + $commit = $1; + next; + } + + m|\s*UBUNTU: (Ubuntu-2\.6\..*)| or next; + + $tag = $1; + + ($origtag) = grep(/^$tag.orig$/, @tags); + + if (!defined($origtag)) { + print "I: Adding original tag for $tag\n"; + system("git tag -m $tag $tag.orig $tag"); + } + + print "I: Tagging $tag => $commit\n"; + + system("git tag -f -m $tag $tag $commit"); +} + +close(LOGS); --- linux-2.6.28.orig/debian/scripts/misc/insert-changes.pl +++ linux-2.6.28/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-2.6.28.orig/debian/scripts/misc/oldconfig +++ linux-2.6.28/debian/scripts/misc/oldconfig @@ -0,0 +1,64 @@ +#!/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 + amd64) kernarch="x86_64" ;; + armel) kernarch="arm" ;; + *) 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-2.6.28.orig/debian/scripts/misc/getabis +++ linux-2.6.28/debian/scripts/misc/getabis @@ -0,0 +1,83 @@ +#!/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/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_ports/linux/$filename + fi + if ! [ -f $filename ]; then + $WGET $repo_uni/linux/$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 amd64 generic server +getall i386 generic server +getall armel iop32x ixp4xx versatile orion5x + +rmdir $tmpdir --- linux-2.6.28.orig/debian/scripts/misc/splitconfig.pl +++ linux-2.6.28/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-2.6.28.orig/debian/scripts/misc/prepare-ppa-source +++ linux-2.6.28/debian/scripts/misc/prepare-ppa-source @@ -0,0 +1,106 @@ +#!/bin/sh +# +# This script prepares a source upload for a PPA build. +# +LAST_UPLOAD=../last-ppa-upload +LAST_GIT_CHANGELOG=../last_git_changelog +LAST_PPA_CHANGELOG=../last_ppa_changelog +PPA_FILE="`make --no-print-directory -f debian/rules print-ppa-file-name`" + +if [ "$1" = "scrub" ] +then + SCRUB=1 +fi + +# +# The identity of the git committer must be known. +# +if [ ! -z "$GIT_AUTHOR_NAME" ] && [ ! -z "$GIT_AUTHOR_EMAIL" ] +then + SIGNER_NAME="$GIT_AUTHOR_NAME" + SIGNER_EMAIL="$GIT_AUTHOR_EMAIL" +elif [ ! -z "$GIT_COMMITTER_NAME" ] && [ ! -z "$GIT_COMMITTER_EMAIL" ] +then + SIGNER_NAME="$GIT_COMMITTER_NAME" + SIGNER_EMAIL="$GIT_COMMITTER_EMAIL" +else + echo Error: Unknown committer. + exit 1 +fi + +# +# git current and cleanup. +# +git checkout -f +git ls-files --others | xargs rm -rf + +# +# Don't bother if the repo hasn't changed since the last upload. +# +if [ ! -f ${LAST_UPLOAD} ] +then + touch ${LAST_UPLOAD} +fi +git log|head -n 1|sed 's/commit //' > ${LAST_UPLOAD}.tmp +if cmp ${LAST_UPLOAD} ${LAST_UPLOAD}.tmp > /dev/null +then + rm -f ${LAST_UPLOAD}.tmp + echo No upload needed. + exit 0 +fi +mv ${LAST_UPLOAD}.tmp ${LAST_UPLOAD} + +# +# The git HEAD can change without anyone updating the debian/changelog. +# However, if the changelog version is updated, then we want to work +# forward from that version. +# +cp debian/changelog changelog.sav +if [ -f ${LAST_GIT_CHANGELOG} ] && [ -f ${LAST_PPA_CHANGELOG} ] +then + # + # If the changelog has not changed, then work forward from the + # last daily build version. + # + if cmp ${LAST_GIT_CHANGELOG} debian/changelog > /dev/null + then + cp ${LAST_PPA_CHANGELOG} debian/changelog + fi +fi +mv changelog.sav ${LAST_GIT_CHANGELOG} + +# +# Notify the build scripts that this is a PPA build. +# +cp -v ${LAST_UPLOAD} ${PPA_FILE} + +# +# In order to sign the package you must override the first signer's changelog entry. +# +export DEBEMAIL="$SIGNER_EMAIL" +export DEBFULLNAME="$SIGNER_NAME" +DEBCHANGE_COMMENT="PPA Upload from git HEAD `cat ${LAST_UPLOAD}`" +debchange --increment --preserve "${DEBCHANGE_COMMENT}" +if ! head -n 1 debian/changelog | grep ubuntu > /dev/null +then + echo debchange did not work. + exit 1 +fi + +# +# Make sure the third changelog field says hardy. +# +sed -i 's/) .*;/) hardy;/1' debian/changelog + +# +# Make sure the next daily build works forward from this version if the git +# changelog has not changed. +# +cp debian/changelog ${LAST_PPA_CHANGELOG} + +rm -rf ../linux* include/config .config +dpkg-buildpackage -S -sa -rfakeroot -I.git -I.gitignore -i'\.git.*' + +rm -f ${PPA_FILE} +exit 0 + --- linux-2.6.28.orig/debian/scripts/misc/git-ubuntu-log +++ linux-2.6.28/debian/scripts/misc/git-ubuntu-log @@ -0,0 +1,220 @@ +#!/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 ($check); + + foreach $check (reverse @reverts) { + my $desc = "Revert \"" . $entry->{'desc'} . "\""; + if ($check->{'desc'} eq $desc) { + @reverts = grep($_->{'desc'} ne $desc, @reverts); + return 1; + } + } + + return 0; +} + +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, $cve, $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->{'cve'} = $cve; + $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"; + } + if (defined($entry->{'cve'})) { + print " - " . $entry->{'cve'} . "\n"; + } + } + } +} + +sub changelog_input { + my ($author, $desc, $commit, $entry, $cve); + + 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; + $cve = 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: *(#|)(.*)/; + $cve = $1 if /^ *(CVE-.*)/; + last if /^commit /; + } + } else { + $author = $kernel_auth; + $ignore = 1 if $desc =~ /Merge /; + while () { + $bug = $2 if /^ *Bug: *(#|)(.*)/; + $cve = $1 if /^ *(CVE-.*)/; + last if /^commit /; + } + } + + if (!$ignore) { + &shortlog_entry($author, $desc, $bug, + $cve, $commit, 0); + } + + $pstate = 1; + if ($_ && /^commit (.*)/) { + $commit = $1; + $pstate++; + } + } + + else { + die "invalid parse state $pstate"; + } + } + + foreach $entry (@reverts) { + add_entry($entry); + } +} + +&changelog_input; +&shortlog_output; + +exit(0); --- linux-2.6.28.orig/debian/commit-templates/missing-modules +++ linux-2.6.28/debian/commit-templates/missing-modules @@ -0,0 +1,3 @@ +UBUNTU: build/modules: Add modules that have intentionally gone missing + +Ignore: yes --- linux-2.6.28.orig/debian/commit-templates/bumpabi +++ linux-2.6.28/debian/commit-templates/bumpabi @@ -0,0 +1,3 @@ +UBUNTU: Bump ABI + +Ignore: yes --- linux-2.6.28.orig/debian/commit-templates/external-driver +++ linux-2.6.28/debian/commit-templates/external-driver @@ -0,0 +1,20 @@ +# Ubuntu external driver commit. +# +# NOTE: This gets reformatted for README.Ubuntu-External-Drivers and +# debian/changelog. +# +# This is only needed when a driver is added, updated or removed. It is +# not needed when patches or fixes are applied to the driver. If the +# driver is being removed, add the line: +# +# Removing: yes +# +# to the commit, and you can remove all other tags (except UBUNTU:). +# +UBUNTU: + +ExternalDriver: +Description: +Url: +Mask: +Version: --- linux-2.6.28.orig/debian/commit-templates/patch +++ linux-2.6.28/debian/commit-templates/patch @@ -0,0 +1,28 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# Bug is a reference to a Malone bug number. Be sure to include the '#' as +# part of the bug number, e.g., 'Bug: #1'. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: + +# OriginalAuthor: +# OriginalLocation: +# Bug: # +# Ignore: yes +# Other text below here. --- linux-2.6.28.orig/debian/commit-templates/newrelease +++ linux-2.6.28/debian/commit-templates/newrelease @@ -0,0 +1,3 @@ +UBUNTU: Start new release + +Ignore: yes --- linux-2.6.28.orig/debian/commit-templates/update-configs +++ linux-2.6.28/debian/commit-templates/update-configs @@ -0,0 +1,10 @@ +# +# This template is used for commit messages that don't need to +# show up in debian/changelog. Administrative stuff like config +# updates, ABI bumps, etc. Setting 'Ignore: yes' prevents +# 'debian/rules insertchanges' from inserting this commit meesage +# as a changelog entry. +# +UBUNTU: Updating configs + +Ignore: yes --- linux-2.6.28.orig/debian/commit-templates/sauce-patch +++ linux-2.6.28/debian/commit-templates/sauce-patch @@ -0,0 +1,38 @@ +# Ubuntu commit template. +# +# NOTE: This gets reformatted for debian/changelog +# +# +# SAUCE refers to the fact that this patch might not go upstream, but we need to +# carry it to successive releases. In most cases you DONOT want to use this +# template. +# +# An example of a SAUCE patch is the ACPI DSDT-in-initramfs patch which has been +# refused upstream, but still provides useful functionality to users with broken +# BIOSes. +# +#------------------------------------------------------------------------- +# +# The initial UBUNTU is a flag that this is an Ubuntu commit. It will be +# referenced to the Author in the debian/changelog entry. +# +# The text following is the short message that will be placed in the +# changelog. Extra text on the following lines will be ignored, but left +# in the git commit. Lines with # will be ignored in the commit. +# +# OriginalAuthor allows for alternate attribution. +# +# OriginalLocation allows for a URL or description of where the patch came +# from. +# +# Bug is a reference to a Malone bug number. +# +# Ignore: yes will keep this commit from showing up in the changelog. +# +UBUNTU: SAUCE: + +# OriginalAuthor: +# OriginalLocation: +# Bug: # +# Ignore: yes +# Other text below here. --- linux-2.6.28.orig/debian/config/armel/config.orion5x +++ linux-2.6.28/debian/config/armel/config.orion5x @@ -0,0 +1,775 @@ +# +# Config options for config.orion5x automatically generated by splitconfig.pl +# +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_ACENIC is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AIO is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_APPLICOM is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IXP4XX is not set +CONFIG_ARCH_ORION5X=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCNET is not set +CONFIG_ARM_THUMB=y +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=y +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=y +# CONFIG_ATA_GENERIC is not set +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_PIIX is not set +CONFIG_ATA_SFF=y +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +# CONFIG_AX88796 is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_GENERIC=m +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +# CONFIG_BLK_DEV_IDEDMA is not set +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_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_MD=m +# CONFIG_BLK_DEV_NBD is not set +# 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_PLATFORM is not set +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_SC1200 is not set +# CONFIG_BLK_DEV_SD 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_SR is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SX8 is not set +# 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 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BNX2 is not set +# CONFIG_BRIDGE is not set +# CONFIG_BROADCOM_PHY is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_C2PORT is not set +# CONFIG_CASSINI is not set +# CONFIG_CFG80211 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 is not set +CONFIG_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +CONFIG_CMDLINE="" +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_COPY_FEROCEON=y +CONFIG_CPU_FEROCEON=y +CONFIG_CPU_FEROCEON_OLD_ID=y +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_TLB_FEROCEON=y +# CONFIG_CRC16 is not set +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_CRYPTO_HASH2=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_RNG2=m +# CONFIG_DAVICOM_PHY is not set +CONFIG_DEBUG_PREEMPT=y +CONFIG_DEBUG_USER=y +CONFIG_DEVPORT=y +# CONFIG_DL2K is not set +CONFIG_DMADEVICES=y +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DRM is not set +# CONFIG_DUMMY is not set +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=y +# CONFIG_EEPRO100 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_EMBEDDED=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_EPIC100 is not set +CONFIG_FAT_FS=y +# CONFIG_FB is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +# CONFIG_FIREWIRE is not set +# CONFIG_FIXED_PHY is not set +# CONFIG_FORCEDETH is not set +# CONFIG_FREEZER is not set +# CONFIG_FUSION is not set +# CONFIG_GACT_PROB is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +# CONFIG_HAMACHI is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +# CONFIG_HP100 is not set +# CONFIG_HP_ILO is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON_VID is not set +CONFIG_I2C_ALGOBIT=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_CHARDEV=y +CONFIG_I2C_GPIO=m +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_MV64XXX is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X 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_ICPLUS_PHY=m +# CONFIG_ICS932S401 is not set +CONFIG_IDE=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDE_ATAPI=y +# CONFIG_IDE_GD is not set +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IEEE1394 is not set +CONFIG_IFB=m +# CONFIG_IGB is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +# CONFIG_INET6_XFRM_TUNNEL is not set +CONFIG_INET_DIAG=y +# CONFIG_INET_LRO is not set +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_EVDEV=y +CONFIG_INPUT_FF_MEMLESS=m +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_IP1000 is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# 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 is not set +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MULTIPLE_TABLES is not set +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +# CONFIG_IP_NF_ARP_MANGLE is not set +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_TTL=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_VS is not set +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_ISO9660_FS=m +# CONFIG_JME is not set +CONFIG_JOLIET=y +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_LEDS=y +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_CPU=y +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTY_COUNT=16 +CONFIG_LOCALVERSION_AUTO=y +CONFIG_LOCK_KERNEL=y +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_LXT_PHY is not set +# CONFIG_MAC80211 is not set +CONFIG_MACH_DB88F5281=y +CONFIG_MACH_DNS323=y +CONFIG_MACH_EDMINI_V2=y +CONFIG_MACH_KUROBOX_PRO=y +# CONFIG_MACH_LINKSTATION_MINI is not set +CONFIG_MACH_LINKSTATION_PRO=y +CONFIG_MACH_MSS2=y +CONFIG_MACH_MV2120=y +CONFIG_MACH_RD88F5181L_FXO=y +CONFIG_MACH_RD88F5181L_GE=y +CONFIG_MACH_RD88F5182=y +CONFIG_MACH_RD88F6183AP_GE=y +# CONFIG_MACH_TERASTATION_PRO2 is not set +CONFIG_MACH_TS209=y +CONFIG_MACH_TS409=y +CONFIG_MACH_TS78XX=y +CONFIG_MACH_WNR854T=y +CONFIG_MACH_WRT350N_V2=y +# CONFIG_MARVELL_PHY is not set +CONFIG_MD=y +# CONFIG_MDIO_BITBANG is not set +# CONFIG_MD_FAULTY is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MD_RAID5_RESHAPE is not set +# CONFIG_MINIX_FS is not set +CONFIG_MISC_DEVICES=y +# CONFIG_MMC is not set +CONFIG_MODVERSIONS=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_AMDSTD=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_NOSWAP=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_ORION=m +# CONFIG_MTD_NAND_PLATFORM is not set +CONFIG_MTD_NAND_VERIFY_WRITE=y +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_OTP is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_BANKWIDTH=0 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_START=0x0 +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_UBI is not set +CONFIG_MV643XX_ETH=y +CONFIG_MV_XOR=y +# CONFIG_NAMESPACES is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NETDEV_1000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=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_IPRANGE=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_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=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_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FLOW=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 is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_FC is not set +CONFIG_NET_PCI=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 is not set +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_NETEM is not set +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 is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_NLS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NOZOMI is not set +CONFIG_NO_HZ=y +# CONFIG_NS83820 is not set +CONFIG_OPROFILE=y +# CONFIG_PANTHERLORD_FF 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_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_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 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_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH 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_PCI=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_QUIRKS is not set +CONFIG_PCI_SYSCALL=y +# CONFIG_PCNET32 is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +CONFIG_PHYLIB=y +CONFIG_PLAT_ORION=y +# CONFIG_PM is not set +CONFIG_PREEMPT=y +# CONFIG_PREEMPT_TRACER is not set +CONFIG_PROFILING=y +# CONFIG_QLA3XXX is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_R6040 is not set +# CONFIG_R8169 is not set +# CONFIG_REALTEK_PHY is not set +# CONFIG_RFKILL is not set +# CONFIG_ROMFS_FS is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +CONFIG_RTC_DRV_DS1307=y +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1511 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_FM3130 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +CONFIG_RTC_DRV_M41T80=y +# CONFIG_RTC_DRV_M41T80_WDT is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_PCF8563=y +# CONFIG_RTC_DRV_PCF8583 is not set +CONFIG_RTC_DRV_RS5C372=y +# CONFIG_RTC_DRV_RX8581 is not set +CONFIG_RTC_DRV_S35390A=y +# CONFIG_RTC_DRV_STK17TA8 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_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_INIC162X is not set +CONFIG_SATA_MV=y +# CONFIG_SATA_NV is not set +CONFIG_SATA_PMP=y +# 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_SC92031 is not set +CONFIG_SCSI=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_DH is not set +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_PROC_FS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +CONFIG_SENSORS_LM75=y +# 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 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +# CONFIG_SERIAL_8250_PCI is not set +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIO 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_SLUB_DEBUG is not set +# CONFIG_SMC91X is not set +# CONFIG_SMSC_PHY is not set +# CONFIG_SOUND is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +CONFIG_SYSCTL_SYSCALL_CHECK=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_TIFM_CORE is not set +# CONFIG_TIGON3 is not set +# CONFIG_TLAN is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TR is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_USB=y +# CONFIG_USB_ACM is not set +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# 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_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_FTDI_ELAN is not set +CONFIG_USB_HID=y +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_HWA_HCD=m +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_KAWETH 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=y +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# 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 is not set +# CONFIG_USB_STORAGE_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_TEST is not set +CONFIG_USB_TMC=m +# CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_UHCI_HCD is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_WHCI_HCD is not set +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_UWB=m +CONFIG_UWB_HWA=m +# CONFIG_UWB_I1480U is not set +# CONFIG_UWB_WHCI is not set +# CONFIG_UWB_WLP is not set +# CONFIG_VETH is not set +CONFIG_VFAT_FS=y +CONFIG_VFP=y +# CONFIG_VGA_CONSOLE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_VITESSE_PHY is not set +# CONFIG_WATCHDOG is not set +# CONFIG_WLAN_80211 is not set +CONFIG_XOR_BLOCKS=m +# CONFIG_YELLOWFIN is not set +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_ZISOFS is not set +CONFIG_ZONE_DMA_FLAG=0 --- linux-2.6.28.orig/debian/config/armel/config +++ linux-2.6.28/debian/config/armel/config @@ -0,0 +1,690 @@ +# +# Common config options automatically generated by splitconfig.pl +# +# CONFIG_ACCESSIBILITY is not set +# CONFIG_ACORN_PARTITION is not set +# CONFIG_ADFS_FS is not set +CONFIG_AEABI=y +# CONFIG_AFFS_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_AF_RXRPC is not set +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_AMIGA_PARTITION is not set +CONFIG_ANON_INODES=y +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +CONFIG_ARCH_FLATMEM_HAS_HOLES=y +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_HAS_ILOG2_U32 is not set +# CONFIG_ARCH_HAS_ILOG2_U64 is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_IXP23XX is not set +# CONFIG_ARCH_KIRKWOOD is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_LOKI is not set +# CONFIG_ARCH_MSM is not set +# CONFIG_ARCH_MV78XX0 is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_NS9XXX is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_PNX4008 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SUPPORTS_MSI is not set +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +# CONFIG_ARPD is not set +# CONFIG_AT24 is not set +# CONFIG_ATALK is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_ATA_OVER_ETH is not set +# CONFIG_ATM is not set +# CONFIG_AUDIT is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_B44 is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_BACKTRACE_SELF_TEST is not set +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 is not set +CONFIG_BITREVERSE=y +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_BSG is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_INITRD=y +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLOCK=y +# CONFIG_BONDING is not set +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +CONFIG_BOOT_TRACER=y +CONFIG_BROKEN_ON_SMP=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_BT is not set +CONFIG_BUG=y +# CONFIG_CAN is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_CGROUPS is not set +# CONFIG_CIFS is not set +CONFIG_CLASSIC_RCU=y +# CONFIG_CODA_FS is not set +# CONFIG_COMPAT_BRK is not set +CONFIG_CONFIGFS_FS=m +# CONFIG_CONNECTOR is not set +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_CPU_32=y +CONFIG_CPU_32v5=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +# CONFIG_CPU_DCACHE_DISABLE is not set +# CONFIG_CPU_IDLE is not set +CONFIG_CPU_PABRT_NOIFAR=y +CONFIG_CRAMFS=m +CONFIG_CRC32=y +# CONFIG_CRC7 is not set +# CONFIG_CRC_CCITT is not set +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=m +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_ANSI_CPRNG is not set +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLOWFISH=m +# CONFIG_CRYPTO_CAMELLIA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +# CONFIG_CRYPTO_CCM is not set +CONFIG_CRYPTO_CRC32C=m +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_ECB=m +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_FIPS is not set +# CONFIG_CRYPTO_GCM is not set +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=m +CONFIG_CRYPTO_HMAC=m +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_MANAGER=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +# CONFIG_CRYPTO_RMD128 is not set +# CONFIG_CRYPTO_RMD160 is not set +# CONFIG_CRYPTO_RMD256 is not set +# CONFIG_CRYPTO_RMD320 is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SEQIV is not set +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_CRYPTO_XTS is not set +# CONFIG_DAB is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +CONFIG_DEBUG_BUGVERBOSE=y +# CONFIG_DEBUG_DEVRES is not set +# CONFIG_DEBUG_DRIVER is not set +CONFIG_DEBUG_ERRORS=y +CONFIG_DEBUG_FS=y +# CONFIG_DEBUG_ICEDCC 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_LL=y +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set +# CONFIG_DEBUG_LOCK_ALLOC is not set +CONFIG_DEBUG_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG 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_DEBUG_WRITECOUNT 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_DETECT_SOFTLOCKUP=y +CONFIG_DEVKMEM=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_DISPLAY_SUPPORT is not set +# CONFIG_DLM is not set +# CONFIG_DM9000 is not set +CONFIG_DNOTIFY=y +# CONFIG_DS1682 is not set +CONFIG_DUMMY_CONSOLE=y +# CONFIG_DVB_CORE is not set +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_EFS_FS is not set +CONFIG_ELF_CORE=y +CONFIG_ENABLE_MUST_CHECK=y +CONFIG_ENABLE_WARN_DEPRECATED=y +CONFIG_EPOLL=y +# CONFIG_EQUALIZER is not set +CONFIG_EVENTFD=y +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=y +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_POSIX_ACL=y +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4_FS is not set +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_FAULT_INJECTION is not set +CONFIG_FILE_LOCKING=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FLATMEM=y +CONFIG_FLATMEM_MANUAL=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=1024 +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +# CONFIG_FTL is not set +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=m +CONFIG_FUTEX=y +CONFIG_FW_LOADER=y +# CONFIG_GAMEPORT is not set +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_IRQ_PROBE=y +# CONFIG_GROUP_SCHED is not set +# CONFIG_HAMRADIO is not set +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_OPROFILE=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_HFS_FS is not set +CONFIG_HID=y +# CONFIG_HIDRAW is not set +# CONFIG_HID_COMPAT is not set +# CONFIG_HID_DEBUG is not set +# CONFIG_HID_PID is not set +CONFIG_HID_SUPPORT=y +CONFIG_HOTPLUG=y +# CONFIG_HPFS_FS is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=m +CONFIG_HZ=100 +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +# 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_HELPER_AUTO=y +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +# CONFIG_IEEE80211 is not set +# CONFIG_IKCONFIG is not set +CONFIG_INET=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_XFRM_MODE_TRANSPORT=y +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INFTL is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INIT_ENV_ARG_LIMIT=32 +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_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_POLLDEV is not set +# CONFIG_INPUT_TABLET is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IPMI_HANDLER is not set +# CONFIG_IPX is not set +# CONFIG_IP_DCCP is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_MROUTE is not set +CONFIG_IP_MULTICAST=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_IP_SCTP is not set +# CONFIG_IRDA is not set +# CONFIG_ISDN is not set +# CONFIG_IWLWIFI_LEDS is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_LZO 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_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_KEXEC is not set +# CONFIG_KGDB is not set +CONFIG_KMOD=y +CONFIG_KPROBES=y +# CONFIG_KPROBES_SANITY_TEST is not set +CONFIG_KRETPROBES=y +# CONFIG_LAPB is not set +CONFIG_LATENCYTOP=y +# CONFIG_LBD is not set +# CONFIG_LDM_PARTITION is not set +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LIBCRC32C=m +# CONFIG_LKDTM is not set +# CONFIG_LLC2 is not set +CONFIG_LOCALVERSION="" +CONFIG_LOCKD=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_LOCKD_V4=y +# CONFIG_LOCK_STAT is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_LSF is not set +# CONFIG_MACVLAN is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARKERS=y +# CONFIG_MEMSTICK is not set +# CONFIG_MFD_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_WM8350_I2C is not set +# CONFIG_MFD_WM8400 is not set +CONFIG_MII=y +# CONFIG_MINIX_SUBPARTITION is not set +CONFIG_MMU=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# CONFIG_MODULE_FORCE_UNLOAD is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +CONFIG_MODULE_UNLOAD=y +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MTD=y +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_AFS_PARTS is not set +# CONFIG_MTD_AR7_PARTS is not set +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# CONFIG_MTD_BLOCK2MTD is not set +CONFIG_MTD_CFI=y +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=y +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +CONFIG_MTD_CHAR=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set +CONFIG_MTD_GEN_PROBE=y +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 is not set +# CONFIG_MTD_ONENAND is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_PLATRAM is not set +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_NCP_FS is not set +CONFIG_NET=y +# CONFIG_NETCONSOLE is not set +CONFIG_NETDEVICES=y +# CONFIG_NETDEV_10000 is not set +# CONFIG_NETPOLL is not set +CONFIG_NETWORK_FILESYSTEMS=y +# CONFIG_NETWORK_SECMARK is not set +# CONFIG_NET_9P is not set +# CONFIG_NET_DSA is not set +CONFIG_NET_ETHERNET=y +# CONFIG_NET_IPGRE is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_KEY is not set +# CONFIG_NET_PKTGEN is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_NET_TCPPROBE is not set +CONFIG_NEW_LEDS=y +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +# CONFIG_NFSD_V4 is not set +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFTL is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# 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_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 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 is not set +CONFIG_NOP_TRACER=y +# CONFIG_NO_IOPORT is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NVRAM is not set +# CONFIG_OABI_COMPAT is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_OUTER_CACHE is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +# CONFIG_PARPORT is not set +CONFIG_PARTITION_ADVANCED=y +# CONFIG_PCCARD is not set +# CONFIG_PCF8575 is not set +CONFIG_PHONET=m +# CONFIG_PHYS_ADDR_T_64BIT is not set +CONFIG_PLIST=y +# CONFIG_PMIC_DA903X is not set +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_POWER_SUPPLY is not set +# CONFIG_PPP is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTK=y +# CONFIG_PRINTK_TIME is not set +CONFIG_PROC_FS=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_SYSCTL=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QUOTA is not set +CONFIG_QUOTACTL=y +# CONFIG_R3964 is not set +# CONFIG_RAID_ATTRS is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_RCU_TORTURE_TEST is not set +CONFIG_REGULATOR=y +# CONFIG_REGULATOR_BQ24022 is not set +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +# 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 is not set +# CONFIG_RESOURCES_64BIT is not set +# CONFIG_RFD_FTL is not set +CONFIG_RING_BUFFER=y +CONFIG_ROOT_NFS=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_RTC_LIB=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_SAMPLES is not set +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +# CONFIG_SCHED_TRACER is not set +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set +# CONFIG_SECURITY_FILE_CAPABILITIES is not set +CONFIG_SELECT_MEMORY_MODEL=y +# 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_SENSORS_TSL2550 is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_NONSTANDARD is not set +# CONFIG_SGI_PARTITION is not set +CONFIG_SHMEM=y +CONFIG_SIGNALFD=y +# CONFIG_SLAB is not set +# CONFIG_SLIP is not set +# CONFIG_SLOB is not set +CONFIG_SLUB=y +# CONFIG_SMB_FS is not set +# CONFIG_SMC911X is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_SPARSEMEM_MANUAL is not set +# CONFIG_SPI is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +# CONFIG_SSB is not set +CONFIG_SSB_POSSIBLE=y +# CONFIG_SSFDC is not set +CONFIG_STACKTRACE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +CONFIG_STANDALONE=y +CONFIG_SUNRPC=y +# CONFIG_SUNRPC_REGISTER_V4 is not set +# CONFIG_SUN_PARTITION is not set +CONFIG_SWAP=y +# CONFIG_SYN_COOKIES is not set +CONFIG_SYSCTL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSV68_PARTITION is not set +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYS_HYPERVISOR is not set +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +# CONFIG_TASKSTATS is not set +# CONFIG_TCG_TPM is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_CUBIC=y +# CONFIG_TCP_MD5SIG is not set +# CONFIG_THERMAL is not set +# CONFIG_THERMAL_HWMON is not set +CONFIG_TIMERFD=y +# CONFIG_TIMER_STATS is not set +# CONFIG_TINY_SHMEM is not set +# CONFIG_TIPC is not set +CONFIG_TRACEPOINTS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACING=y +# CONFIG_TUN is not set +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_FS is not set +CONFIG_UID16=y +# CONFIG_UIO is not set +# CONFIG_ULTRIX_PARTITION is not set +CONFIG_UNEVICTABLE_LRU=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_UNUSED_SYMBOLS is not set +CONFIG_USB_ARCH_HAS_HCD=y +# CONFIG_USB_GADGET is not set +CONFIG_USB_SUPPORT=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_VERSION_SIGNATURE="" +# CONFIG_VGASTATE is not set +# CONFIG_VIDEO_DEV is not set +# CONFIG_VIDEO_MEDIA is not set +# CONFIG_VIDEO_OUTPUT_CONTROL is not set +CONFIG_VIRT_TO_BUS=y +# CONFIG_VLAN_8021Q is not set +# CONFIG_VMSPLIT_1G is not set +# CONFIG_VMSPLIT_2G is not set +CONFIG_VMSPLIT_3G=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +# CONFIG_VXFS_FS is not set +# CONFIG_W1 is not set +# CONFIG_WAN is not set +# CONFIG_WAN_ROUTER is not set +CONFIG_WIRELESS=y +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_WIRELESS_OLD_REGULATORY=y +# CONFIG_WLAN_PRE80211 is not set +# CONFIG_X25 is not set +CONFIG_XFRM=y +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_USER is not set +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +# CONFIG_XIP_KERNEL is not set +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y --- linux-2.6.28.orig/debian/config/armel/config.versatile +++ linux-2.6.28/debian/config/armel/config.versatile @@ -0,0 +1,301 @@ +# +# Config options for config.versatile automatically generated by splitconfig.pl +# +CONFIG_AC97_BUS=m +CONFIG_AIO=y +# CONFIG_APM_EMULATION is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_ORION5X is not set +CONFIG_ARCH_VERSATILE=y +CONFIG_ARCH_VERSATILE_PB=y +CONFIG_ARM_AMBA=y +CONFIG_ARM_THUMB=y +CONFIG_ARM_VIC=y +# CONFIG_ATA is not set +CONFIG_AX88796=m +# CONFIG_AX88796_93CX6 is not set +# CONFIG_B43 is not set +# CONFIG_B43LEGACY is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_BRIDGE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_CFG80211=m +CONFIG_CMDLINE="root=1f03 mem=32M" +CONFIG_CPU_ABRT_EV5TJ=y +CONFIG_CPU_ARM926T=y +# CONFIG_CPU_CACHE_ROUND_ROBIN is not set +CONFIG_CPU_COPY_V4WB=y +# CONFIG_CPU_DCACHE_WRITETHROUGH is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CRC16=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_RNG2=y +CONFIG_DEBUG_USER=y +# CONFIG_DMADEVICES is not set +# CONFIG_DUMMY is not set +# CONFIG_ECONET is not set +# CONFIG_EMBEDDED is not set +CONFIG_FAT_FS=m +CONFIG_FB=y +CONFIG_FB_ARMCLCD=y +# CONFIG_FB_BACKLIGHT is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +# CONFIG_FB_DDC is not set +# CONFIG_FB_FOREIGN_ENDIAN is not set +# CONFIG_FB_MACMODES is not set +# CONFIG_FB_MB862XX is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MODE_HELPERS is not set +# CONFIG_FB_S1D13XXX 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 is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FIRMWARE_EDID is not set +CONFIG_FONTS=y +# CONFIG_FONT_10x18 is not set +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_7x14 is not set +# CONFIG_FONT_8x16 is not set +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_ACORN_8x8=y +# CONFIG_FONT_MINI_4x6 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_SUN12x22 is not set +# CONFIG_FONT_SUN8x16 is not set +CONFIG_FRAMEBUFFER_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FREEZER=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +# CONFIG_GENERIC_GPIO is not set +CONFIG_GENERIC_TIME=y +CONFIG_HAVE_CLK=y +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HOSTAP is not set +# CONFIG_HWMON is not set +CONFIG_I2C_ALGOBIT=y +CONFIG_I2C_CHARDEV=m +CONFIG_I2C_VERSATILE=y +CONFIG_ICST307=y +# CONFIG_IDE is not set +# CONFIG_INET_DIAG is not set +CONFIG_INET_LRO=m +# CONFIG_INET_TUNNEL is not set +# CONFIG_INET_XFRM_MODE_BEET is not set +# CONFIG_INET_XFRM_MODE_TUNNEL is not set +# CONFIG_INOTIFY is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_KEYBOARD=y +# CONFIG_INPUT_MISC is not set +CONFIG_INPUT_MOUSE=y +CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_IPC_NS is not set +# CONFIG_IPV6 is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IRQSOFF_TRACER is not set +# CONFIG_ISO9660_FS is not set +CONFIG_KEYBOARD_ATKBD=y +# 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 is not set +CONFIG_LEDS=y +# CONFIG_LEDS_CLASS is not set +CONFIG_LEDS_CPU=y +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set +# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set +# CONFIG_LEDS_TRIGGER_TIMER is not set +CONFIG_LEGACY_PTY_COUNT=0 +# CONFIG_LIBERTAS is not set +CONFIG_LIBERTAS_THINFIRM=m +# CONFIG_LOCALVERSION_AUTO is not set +# CONFIG_LOGO is not set +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_PID=y +CONFIG_MACH_VERSATILE_AB=y +# CONFIG_MD is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +CONFIG_MINIX_FS=y +# CONFIG_MISC_DEVICES is not set +CONFIG_MMC=y +CONFIG_MMC_ARMMMCI=m +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +# CONFIG_MMC_SDHCI is not set +# CONFIG_MMC_TEST is not set +# CONFIG_MMC_UNSAFE_RESUME is not set +# CONFIG_MODVERSIONS is not set +# CONFIG_MOUSE_APPLETOUCH is not set +# CONFIG_MOUSE_BCM5974 is not set +CONFIG_MOUSE_PS2=y +CONFIG_MOUSE_PS2_ALPS=y +# CONFIG_MOUSE_PS2_ELANTECH is not set +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_MTD_ARM_INTEGRATOR=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_GEOMETRY is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_NOSWAP=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_JEDECPROBE is not set +# CONFIG_MTD_NAND is not set +CONFIG_MTD_OOPS=m +# CONFIG_MTD_OTP is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_BEB_RESERVE=1 +# CONFIG_MTD_UBI_DEBUG is not set +# CONFIG_MTD_UBI_GLUEBI is not set +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_NAMESPACES=y +# CONFIG_NETDEV_1000 is not set +# CONFIG_NETFILTER is not set +# CONFIG_NET_SCHED is not set +CONFIG_NL80211=y +CONFIG_NLS=m +# CONFIG_NLS_CODEPAGE_437 is not set +CONFIG_NLS_CODEPAGE_850=m +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +CONFIG_NO_HZ=y +# CONFIG_P54_COMMON is not set +# CONFIG_PCI is not set +# CONFIG_PCI_SYSCALL is not set +# CONFIG_PHYLIB is not set +# CONFIG_PID_NS is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_PM_DISABLE_CONSOLE is not set +CONFIG_PM_SLEEP=y +# CONFIG_PREEMPT is not set +# CONFIG_PROFILING is not set +CONFIG_RFKILL=m +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_ROMFS_FS=y +# CONFIG_RT2X00 is not set +# CONFIG_RTC_CLASS is not set +# CONFIG_SCSI is not set +# CONFIG_SCSI_DMA is not set +# CONFIG_SDIO_UART is not set +CONFIG_SENSORS_EEPROM=m +CONFIG_SERIAL_8250=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=4 +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +CONFIG_SERIAL_8250_SHARE_IRQ=y +CONFIG_SERIAL_AMBA_PL011=y +CONFIG_SERIAL_AMBA_PL011_CONSOLE=y +CONFIG_SERIO=y +CONFIG_SERIO_AMBAKMI=y +CONFIG_SERIO_LIBPS2=y +# CONFIG_SERIO_RAW is not set +# CONFIG_SERIO_SERPORT is not set +CONFIG_SLABINFO=y +CONFIG_SLUB_DEBUG=y +# CONFIG_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SMC91X=y +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_ARM=y +CONFIG_SND_ARMAACI=m +# CONFIG_SND_DEBUG is not set +# CONFIG_SND_DRIVERS is not set +# CONFIG_SND_DYNAMIC_MINORS is not set +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_SEQUENCER is not set +CONFIG_SND_SOC=m +# CONFIG_SND_SOC_ALL_CODECS is not set +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +# CONFIG_SND_VERBOSE_PRINTK is not set +CONFIG_SND_VERBOSE_PROCFS=y +CONFIG_SND_VMASTER=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +# CONFIG_SOUND_PRIME is not set +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_TMPFS is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +# CONFIG_UBIFS_FS_XATTR is not set +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UDF_FS is not set +# CONFIG_USB is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USER_NS is not set +# CONFIG_UTS_NS is not set +CONFIG_VETH=m +CONFIG_VFAT_FS=m +CONFIG_VFP=y +# CONFIG_WATCHDOG is not set +CONFIG_WLAN_80211=y +CONFIG_ZONE_DMA_FLAG=0 --- linux-2.6.28.orig/debian/config/armel/config.ixp4xx +++ linux-2.6.28/debian/config/armel/config.ixp4xx @@ -0,0 +1,800 @@ +# +# Config options for config.ixp4xx automatically generated by splitconfig.pl +# +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_ACENIC is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_AIO is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_APPLICOM is not set +CONFIG_ARCH_ADI_COYOTE=y +# CONFIG_ARCH_IOP32X is not set +CONFIG_ARCH_IXCDP1100=y +CONFIG_ARCH_IXDP425=y +CONFIG_ARCH_IXDP4XX=y +CONFIG_ARCH_IXP4XX=y +# CONFIG_ARCH_ORION5X is not set +CONFIG_ARCH_PRPMC1100=y +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCNET is not set +# CONFIG_ARM_THUMB is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=y +# CONFIG_ATA_GENERIC is not set +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_PIIX is not set +CONFIG_ATA_SFF=y +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +# CONFIG_AX88796 is not set +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_GENERIC=m +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDECD=m +CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +CONFIG_BLK_DEV_IDEDMA_SFF=y +CONFIG_BLK_DEV_IDEPCI=y +# CONFIG_BLK_DEV_IDESCSI is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDE_SATA 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_MD=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=y +# CONFIG_BLK_DEV_PDC202XX_OLD is not set +# CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_PLATFORM is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_SD=y +# 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 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SX8 is not set +# 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 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_BNX2 is not set +CONFIG_BOUNCE=y +CONFIG_BRIDGE=m +CONFIG_BRIDGE_NETFILTER=y +# CONFIG_BRIDGE_NF_EBTABLES is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_C2PORT is not set +# CONFIG_CASSINI is not set +# CONFIG_CFG80211 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_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +CONFIG_CMDLINE="console=ttyS0,115200 ip=bootp root=/dev/nfs" +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_CPU_IXP43X=y +CONFIG_CPU_IXP46X=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_XSCALE=y +CONFIG_CRC16=m +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_CRYPTO_DEV_IXP4XX=m +CONFIG_CRYPTO_HASH2=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_RNG2=m +# CONFIG_DEBUG_USER is not set +CONFIG_DEVPORT=y +# CONFIG_DL2K is not set +CONFIG_DMABOUNCE=y +CONFIG_DMADEVICES=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DRM is not set +CONFIG_DUMMY=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=y +CONFIG_EEPRO100=y +# CONFIG_EEPROM_93CX6 is not set +CONFIG_EMBEDDED=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_EPIC100 is not set +CONFIG_FAT_FS=y +# CONFIG_FB is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +# CONFIG_FIREWIRE is not set +# CONFIG_FORCEDETH is not set +# CONFIG_FREEZER is not set +# CONFIG_FUSION is not set +# CONFIG_GACT_PROB is not set +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_TIME=y +# CONFIG_HAMACHI is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HIGH_RES_TIMERS=y +# CONFIG_HIPPI is not set +# CONFIG_HP100 is not set +# CONFIG_HP_ILO is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +CONFIG_HWMON_VID=y +CONFIG_HW_RANDOM_IXP4XX=m +CONFIG_I2C_ALGOBIT=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_CHARDEV=y +CONFIG_I2C_GPIO=m +# CONFIG_I2C_I801 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X 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_ICS932S401 is not set +CONFIG_IDE=y +CONFIG_IDEPCI_PCIBUS_ORDER=y +# CONFIG_IDE_GD is not set +CONFIG_IDE_PROC_FS=y +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IEEE1394 is not set +CONFIG_IFB=m +# CONFIG_IGB is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +# CONFIG_INET6_XFRM_TUNNEL is not set +CONFIG_INET_DIAG=y +# CONFIG_INET_LRO is not set +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +# CONFIG_INPUT_ATI_REMOTE is not set +# CONFIG_INPUT_ATI_REMOTE2 is not set +# CONFIG_INPUT_CM109 is not set +CONFIG_INPUT_EVDEV=y +# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_IXP4XX_BEEPER=y +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_KEYSPAN_REMOTE is not set +CONFIG_INPUT_MISC=y +# CONFIG_INPUT_MOUSE is not set +CONFIG_INPUT_MOUSEDEV_PSAUX=y +# CONFIG_INPUT_POWERMATE is not set +# CONFIG_INPUT_UINPUT is not set +# CONFIG_INPUT_YEALINK is not set +# CONFIG_IP1000 is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# 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 is not set +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MULTIPLE_TABLES is not set +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARPTABLES=m +# CONFIG_IP_NF_ARP_MANGLE is not set +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_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_REJECT=m +# CONFIG_IP_NF_TARGET_TTL is not set +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_ROUTE_MULTIPATH=y +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_VS=m +CONFIG_IP_VS_DEBUG=y +CONFIG_IP_VS_DH=m +# CONFIG_IP_VS_IPV6 is not set +CONFIG_IP_VS_LBLC=m +CONFIG_IP_VS_LBLCR=m +CONFIG_IP_VS_LC=m +# CONFIG_IP_VS_NQ is not set +# CONFIG_IP_VS_PROTO_AH is not set +# CONFIG_IP_VS_PROTO_ESP is not set +# CONFIG_IP_VS_PROTO_TCP is not set +# CONFIG_IP_VS_PROTO_UDP is not set +CONFIG_IP_VS_RR=m +# CONFIG_IP_VS_SED is not set +CONFIG_IP_VS_SH=m +CONFIG_IP_VS_TAB_BITS=12 +CONFIG_IP_VS_WLC=m +CONFIG_IP_VS_WRR=m +# CONFIG_IRQSOFF_TRACER is not set +CONFIG_ISO9660_FS=m +# CONFIG_IWMMXT is not set +CONFIG_IXP4XX_ETH=y +# CONFIG_IXP4XX_INDIRECT_PCI is not set +CONFIG_IXP4XX_NPE=y +CONFIG_IXP4XX_QMGR=y +CONFIG_IXP4XX_WATCHDOG=y +# CONFIG_JME is not set +CONFIG_JOLIET=y +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_FSG=y +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LLC=m +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_MAC80211 is not set +CONFIG_MACH_AVILA=y +CONFIG_MACH_DSMG600=y +CONFIG_MACH_FSG=y +CONFIG_MACH_GATEWAY7001=y +CONFIG_MACH_GTWX5715=y +CONFIG_MACH_IXDP465=y +CONFIG_MACH_IXDPG425=y +CONFIG_MACH_KIXRP435=y +CONFIG_MACH_LOFT=y +CONFIG_MACH_NAS100D=y +CONFIG_MACH_NSLU2=y +CONFIG_MACH_WG302V2=y +CONFIG_MD=y +# CONFIG_MD_FAULTY is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MD_RAID5_RESHAPE is not set +# CONFIG_MINIX_FS is not set +CONFIG_MISC_DEVICES=y +# CONFIG_MMC is not set +CONFIG_MODVERSIONS=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_INTEL_VR_NOR is not set +CONFIG_MTD_IXP4XX=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND_GPIO=m +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_NANDSIM is not set +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_OOPS is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PMC551 is not set +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=y +# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set +# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set +# CONFIG_MTD_UBI is not set +# CONFIG_NAMESPACES is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NETDEV_1000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=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_IPRANGE=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_OWNER=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=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_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FLOW=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_EMATCH is not set +# CONFIG_NET_FC is not set +CONFIG_NET_PCI=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 is not set +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_NETEM is not set +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 is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_NLS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NOZOMI is not set +CONFIG_NO_HZ=y +# CONFIG_NS83820 is not set +# CONFIG_PANTHERLORD_FF is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +CONFIG_PATA_ARTOP=y +# 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_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_IXP4XX_CF=y +# 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_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 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_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH 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_PCI=y +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_QUIRKS is not set +CONFIG_PCI_SYSCALL=y +# CONFIG_PCNET32 is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +# CONFIG_PHYLIB is not set +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_PROFILING is not set +# CONFIG_QLA3XXX is not set +# CONFIG_R6040 is not set +# CONFIG_R8169 is not set +# CONFIG_RFKILL is not set +# CONFIG_ROMFS_FS is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1511 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_FM3130 is not set +CONFIG_RTC_DRV_ISL1208=y +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +CONFIG_RTC_DRV_PCF8563=y +# CONFIG_RTC_DRV_PCF8583 is not set +# CONFIG_RTC_DRV_RS5C372 is not set +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_STK17TA8 is not set +# CONFIG_RTC_DRV_TEST is not set +# CONFIG_RTC_DRV_V3020 is not set +CONFIG_RTC_DRV_X1205=y +CONFIG_RTC_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +# 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_PMP 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=y +# CONFIG_SATA_VITESSE is not set +# CONFIG_SC92031 is not set +CONFIG_SCSI=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_DH is not set +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_PROC_FS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DS1621 is not set +CONFIG_SENSORS_EEPROM=y +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# 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 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_W83627HF is not set +CONFIG_SENSORS_W83781D=y +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIO 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_SLUB_DEBUG is not set +# CONFIG_SMC91X is not set +# CONFIG_SOFT_WATCHDOG is not set +# CONFIG_SOUND is not set +CONFIG_STP=m +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +# CONFIG_THRUSTMASTER_FF is not set +CONFIG_TICK_ONESHOT=y +# CONFIG_TIFM_CORE is not set +# CONFIG_TIGON3 is not set +# CONFIG_TLAN is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TR is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_USB=y +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_USB_ACM is not set +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# 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_DESC=y +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y +CONFIG_USB_EHCI_HCD=y +# CONFIG_USB_EHCI_ROOT_HUB_TT 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_HID=y +# CONFIG_USB_HIDDEV is not set +# CONFIG_USB_HWA_HCD is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_KAWETH 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=y +# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set +# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# 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 is not set +# CONFIG_USB_STORAGE_ONETOUCH 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_TEST is not set +CONFIG_USB_TMC=m +# CONFIG_USB_TRANCEVIBRATOR is not set +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_USBNET is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_WHCI_HCD is not set +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_UWB=m +CONFIG_UWB_HWA=m +# CONFIG_UWB_I1480U is not set +# CONFIG_UWB_WHCI is not set +# CONFIG_UWB_WLP is not set +# CONFIG_VETH is not set +CONFIG_VFAT_FS=y +# CONFIG_VGA_CONSOLE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +# CONFIG_WDTPCI is not set +# CONFIG_WLAN_80211 is not set +CONFIG_XOR_BLOCKS=m +CONFIG_XSCALE_PMU=y +# CONFIG_YELLOWFIN is not set +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_ZISOFS is not set +CONFIG_ZONE_DMA=y +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.28.orig/debian/config/armel/config.iop32x +++ linux-2.6.28/debian/config/armel/config.iop32x @@ -0,0 +1,741 @@ +# +# Config options for config.iop32x automatically generated by splitconfig.pl +# +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_ACENIC is not set +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_AIO=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_APPLICOM is not set +CONFIG_ARCH_IOP32X=y +CONFIG_ARCH_IQ31244=y +CONFIG_ARCH_IQ80321=y +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_ORION5X is not set +CONFIG_ARCH_REQUIRE_GPIOLIB=y +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCNET is not set +# CONFIG_ARM_THUMB is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASYNC_CORE=y +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_ATA=y +# CONFIG_ATA_GENERIC is not set +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_ATA_PIIX is not set +CONFIG_ATA_SFF=y +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL2 is not set +# CONFIG_AX88796 is not set +CONFIG_BINFMT_AOUT=y +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# CONFIG_BLK_DEV_CMD64X is not set +# CONFIG_BLK_DEV_CS5520 is not set +# CONFIG_BLK_DEV_CS5530 is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_DM=m +CONFIG_BLK_DEV_GENERIC=m +# CONFIG_BLK_DEV_HPT366 is not set +CONFIG_BLK_DEV_IDECD=m +# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS is not set +# CONFIG_BLK_DEV_IDEDMA is not set +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_IT8213 is not set +# CONFIG_BLK_DEV_IT821X is not set +# CONFIG_BLK_DEV_JMICRON is not set +CONFIG_BLK_DEV_MD=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_PLATFORM is not set +CONFIG_BLK_DEV_RAM=m +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 +# CONFIG_BLK_DEV_SC1200 is not set +CONFIG_BLK_DEV_SD=y +# 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 is not set +# CONFIG_BLK_DEV_SVWKS is not set +# CONFIG_BLK_DEV_SX8 is not set +# 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 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_XIP is not set +# CONFIG_BNX2 is not set +# CONFIG_BRIDGE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +# CONFIG_C2PORT is not set +# CONFIG_CASSINI is not set +# CONFIG_CFG80211 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_CLS_U32_MARK=y +CONFIG_CLS_U32_PERF=y +CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/nfs ip=bootp cachepolicy=writealloc" +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_TLB_V4WBI=y +CONFIG_CPU_XSCALE=y +CONFIG_CRC16=m +CONFIG_CRYPTO_AEAD2=m +CONFIG_CRYPTO_ALGAPI=m +CONFIG_CRYPTO_ALGAPI2=m +# CONFIG_CRYPTO_AUTHENC is not set +CONFIG_CRYPTO_BLKCIPHER2=m +CONFIG_CRYPTO_DEFLATE=m +# CONFIG_CRYPTO_DEV_HIFN_795X is not set +CONFIG_CRYPTO_HASH2=m +# CONFIG_CRYPTO_LZO is not set +CONFIG_CRYPTO_MANAGER2=m +CONFIG_CRYPTO_RNG2=m +# CONFIG_DEBUG_GPIO is not set +CONFIG_DEBUG_USER=y +CONFIG_DEVPORT=y +# CONFIG_DL2K is not set +CONFIG_DMADEVICES=y +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_UEVENT is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DRM is not set +# CONFIG_DUMMY is not set +CONFIG_E100=y +CONFIG_E1000=y +# CONFIG_E1000E is not set +# CONFIG_ECONET is not set +CONFIG_ECRYPT_FS=y +# CONFIG_EEPRO100 is not set +# CONFIG_EEPROM_93CX6 is not set +CONFIG_EMBEDDED=y +# CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_EPIC100 is not set +CONFIG_FAT_FS=y +# CONFIG_FB is not set +# CONFIG_FDDI is not set +# CONFIG_FEALNX is not set +# CONFIG_FIREWIRE is not set +# CONFIG_FORCEDETH is not set +# CONFIG_FREEZER is not set +# CONFIG_FUSION is not set +# CONFIG_GACT_PROB is not set +# CONFIG_GENERIC_CLOCKEVENTS is not set +CONFIG_GENERIC_GPIO=y +# CONFIG_GENERIC_TIME is not set +CONFIG_GPIOLIB=y +# CONFIG_GPIO_BT8XX is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +CONFIG_GPIO_SYSFS=y +# CONFIG_HAMACHI is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +CONFIG_HID_CYPRESS=m +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +# CONFIG_HIPPI is not set +# CONFIG_HP100 is not set +# CONFIG_HP_ILO is not set +# CONFIG_HTC_EGPIO is not set +CONFIG_HWMON=y +# CONFIG_HWMON_DEBUG_CHIP is not set +# CONFIG_HWMON_VID is not set +CONFIG_I2C_ALGOBIT=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_CHARDEV=y +CONFIG_I2C_GPIO=m +# CONFIG_I2C_I801 is not set +CONFIG_I2C_IOP3XX=y +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X 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_ICS932S401 is not set +CONFIG_IDE=y +# CONFIG_IDEPCI_PCIBUS_ORDER is not set +CONFIG_IDE_ATAPI=y +# CONFIG_IDE_GD is not set +# CONFIG_IDE_PROC_FS is not set +# CONFIG_IDE_TASK_IOCTL is not set +# CONFIG_IEEE1394 is not set +CONFIG_IFB=m +# CONFIG_IGB is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +CONFIG_INET6_XFRM_MODE_BEET=m +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_INET6_XFRM_MODE_TRANSPORT=m +CONFIG_INET6_XFRM_MODE_TUNNEL=m +# CONFIG_INET6_XFRM_TUNNEL is not set +CONFIG_INET_DIAG=y +# CONFIG_INET_LRO is not set +CONFIG_INET_TCP_DIAG=y +CONFIG_INET_TUNNEL=m +CONFIG_INET_XFRM_MODE_BEET=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_INOTIFY=y +CONFIG_INOTIFY_USER=y +CONFIG_INPUT_EVDEV=y +# 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_MOUSEDEV_PSAUX is not set +CONFIG_INTEL_IOP_ADMA=y +# CONFIG_IP1000 is not set +# CONFIG_IP6_NF_IPTABLES is not set +# CONFIG_IP6_NF_QUEUE is not set +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +# CONFIG_IPV6_MULTIPLE_TABLES is not set +CONFIG_IPV6_NDISC_NODETYPE=y +# 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 is not set +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE is not set +# CONFIG_IP_MULTIPLE_TABLES is not set +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_TTL=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_LOG=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +# CONFIG_IP_PNP_DHCP is not set +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_VS is not set +CONFIG_ISO9660_FS=m +# CONFIG_IWMMXT is not set +# CONFIG_JME is not set +CONFIG_JOLIET=y +CONFIG_KEYS=y +# CONFIG_KEYS_DEBUG_PROC_KEYS is not set +CONFIG_LEDS_CLASS=y +CONFIG_LEDS_GPIO=y +# CONFIG_LEDS_PCA9532 is not set +# CONFIG_LEDS_PCA955X is not set +CONFIG_LEDS_TRIGGER_BACKLIGHT=y +CONFIG_LEDS_TRIGGER_DEFAULT_ON=y +CONFIG_LEDS_TRIGGER_HEARTBEAT=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_LOGIRUMBLEPAD2_FF is not set +# CONFIG_LOGITECH_FF is not set +# CONFIG_MAC80211 is not set +# CONFIG_MACH_EM7210 is not set +CONFIG_MACH_EP80219=y +CONFIG_MACH_GLANTANK=y +CONFIG_MACH_N2100=y +CONFIG_MD=y +# CONFIG_MD_FAULTY is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_MULTIPATH is not set +CONFIG_MD_RAID0=m +CONFIG_MD_RAID1=m +CONFIG_MD_RAID10=m +CONFIG_MD_RAID456=m +# CONFIG_MD_RAID5_RESHAPE is not set +# CONFIG_MFD_ASIC3 is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MINIX_FS is not set +CONFIG_MISC_DEVICES=y +# CONFIG_MMC is not set +CONFIG_MODVERSIONS=y +# CONFIG_MTD_ALAUDA is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_NAND=m +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_ECC_SMC is not set +# CONFIG_MTD_NAND_GPIO is not set +CONFIG_MTD_NAND_IDS=m +# CONFIG_MTD_NAND_MUSEUM_IDS is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_PLATFORM=m +# CONFIG_MTD_NAND_VERIFY_WRITE is not set +# CONFIG_MTD_OOPS is not set +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_PHYSMAP_BANKWIDTH=1 +CONFIG_MTD_PHYSMAP_LEN=0x0 +CONFIG_MTD_PHYSMAP_START=0x0 +# CONFIG_MTD_PMC551 is not set +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +# CONFIG_MTD_UBI is not set +# CONFIG_NAMESPACES is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NETDEV_1000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=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_IPRANGE=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_OWNER=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_QUOTA=m +CONFIG_NETFILTER_XT_MATCH_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATISTIC=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m +CONFIG_NETFILTER_XT_MATCH_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=m +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=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_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_FLOW=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 is not set +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_FC is not set +CONFIG_NET_PCI=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 is not set +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_INGRESS=m +# CONFIG_NET_SCH_MULTIQ is not set +# CONFIG_NET_SCH_NETEM is not set +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 is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_NF_CONNTRACK is not set +# CONFIG_NF_DEFRAG_IPV4 is not set +CONFIG_NLS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_ISO8859_2=y +# CONFIG_NOZOMI is not set +# CONFIG_NS83820 is not set +# CONFIG_PANTHERLORD_FF 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_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_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NINJA32 is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_NS87415 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_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SCH 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_PCI=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_LEGACY=y +# CONFIG_PCI_QUIRKS is not set +CONFIG_PCI_SYSCALL=y +# CONFIG_PCNET32 is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_PHANTOM is not set +# CONFIG_PHYLIB is not set +CONFIG_PLAT_IOP=y +# CONFIG_PM is not set +# CONFIG_PREEMPT is not set +# CONFIG_PROFILING is not set +# CONFIG_QLA3XXX is not set +# CONFIG_R6040 is not set +CONFIG_R8169=y +# CONFIG_RFKILL is not set +# CONFIG_ROMFS_FS is not set +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +# CONFIG_RTC_DRV_BQ4802 is not set +# CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set +# CONFIG_RTC_DRV_DS1307 is not set +# CONFIG_RTC_DRV_DS1374 is not set +# CONFIG_RTC_DRV_DS1511 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_FM3130 is not set +# CONFIG_RTC_DRV_ISL1208 is not set +# CONFIG_RTC_DRV_M41T80 is not set +# CONFIG_RTC_DRV_M48T35 is not set +# CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_MAX6900 is not set +# CONFIG_RTC_DRV_PCF8563 is not set +# CONFIG_RTC_DRV_PCF8583 is not set +CONFIG_RTC_DRV_RS5C372=y +# CONFIG_RTC_DRV_RX8581 is not set +# CONFIG_RTC_DRV_S35390A is not set +# CONFIG_RTC_DRV_STK17TA8 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_HCTOSYS=y +CONFIG_RTC_HCTOSYS_DEVICE="rtc0" +CONFIG_RTC_INTF_DEV=y +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set +CONFIG_RTC_INTF_PROC=y +CONFIG_RTC_INTF_SYSFS=y +# 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_PMP is not set +# CONFIG_SATA_PROMISE is not set +# CONFIG_SATA_QSTOR is not set +CONFIG_SATA_SIL=y +# 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=y +# CONFIG_SC92031 is not set +CONFIG_SCSI=y +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_DH is not set +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_LOGGING is not set +# CONFIG_SCSI_LOWLEVEL is not set +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_PROC_FS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SCAN_ASYNC is not set +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +# CONFIG_SCSI_TGT is not set +CONFIG_SCSI_WAIT_SCAN=m +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set +# CONFIG_SENSORS_ADS7828 is not set +# CONFIG_SENSORS_ADT7462 is not set +# CONFIG_SENSORS_ADT7470 is not set +# CONFIG_SENSORS_ADT7473 is not set +# CONFIG_SENSORS_ATXP1 is not set +# CONFIG_SENSORS_DME1737 is not set +# CONFIG_SENSORS_DS1621 is not set +# CONFIG_SENSORS_EEPROM is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_SENSORS_F71882FG is not set +# CONFIG_SENSORS_F75375S is not set +# CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set +# CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_IT87 is not set +# CONFIG_SENSORS_LM63 is not set +# 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 is not set +# CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set +# CONFIG_SENSORS_LM93 is not set +# CONFIG_SENSORS_MAX1619 is not set +# CONFIG_SENSORS_MAX6650 is not set +# CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_PC87427 is not set +# CONFIG_SENSORS_SIS5595 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SMSC47M1 is not set +# CONFIG_SENSORS_SMSC47M192 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_VIA686A is not set +# CONFIG_SENSORS_VT1211 is not set +# CONFIG_SENSORS_VT8231 is not set +# CONFIG_SENSORS_W83627EHF is not set +# CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83781D is not set +# CONFIG_SENSORS_W83791D is not set +# CONFIG_SENSORS_W83792D is not set +# CONFIG_SENSORS_W83793 is not set +# CONFIG_SENSORS_W83L785TS is not set +# CONFIG_SENSORS_W83L786NG is not set +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +# CONFIG_SERIAL_8250_EXTENDED is not set +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIO 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_SLUB_DEBUG is not set +# CONFIG_SMC91X is not set +# CONFIG_SOUND is not set +# CONFIG_SUNDANCE is not set +# CONFIG_SUNGEM is not set +# CONFIG_SYSCTL_SYSCALL_CHECK is not set +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_TIFM_CORE is not set +# CONFIG_TIGON3 is not set +# CONFIG_TLAN is not set +CONFIG_TMPFS=y +# CONFIG_TMPFS_POSIX_ACL is not set +# CONFIG_TPS65010 is not set +# CONFIG_TR is not set +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_USB=y +# CONFIG_USB_ACM is not set +# CONFIG_USB_ADUTUX is not set +CONFIG_USB_ANNOUNCE_NEW_DEVICES=y +# CONFIG_USB_APPLEDISPLAY is not set +CONFIG_USB_ARCH_HAS_EHCI=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB_BERRY_CHARGE is not set +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_CATC is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set +# CONFIG_USB_CYTHERM is not set +# 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_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_FTDI_ELAN is not set +CONFIG_USB_HID=y +# CONFIG_USB_HIDDEV is not set +CONFIG_USB_HWA_HCD=m +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IOWARRIOR is not set +# CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_ISP116X_HCD is not set +# CONFIG_USB_ISP1760_HCD is not set +# CONFIG_USB_KAWETH 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=y +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_PHIDGET is not set +# CONFIG_USB_PRINTER is not set +# CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_SERIAL is not set +# CONFIG_USB_SEVSEG is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_SL811_HCD is not set +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +# 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 is not set +# CONFIG_USB_STORAGE_ONETOUCH 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_TEST is not set +CONFIG_USB_TMC=m +# CONFIG_USB_TRANCEVIBRATOR is not set +CONFIG_USB_UHCI_HCD=y +# CONFIG_USB_USBNET is not set +# CONFIG_USB_VST is not set +# CONFIG_USB_WDM is not set +# CONFIG_USB_WHCI_HCD is not set +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_UWB=m +CONFIG_UWB_HWA=m +# CONFIG_UWB_I1480U is not set +# CONFIG_UWB_WHCI is not set +# CONFIG_UWB_WLP is not set +# CONFIG_VETH is not set +CONFIG_VFAT_FS=y +# CONFIG_VGA_CONSOLE is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_WATCHDOG is not set +# CONFIG_WLAN_80211 is not set +CONFIG_XOR_BLOCKS=m +CONFIG_XSCALE_PMU=y +# CONFIG_YELLOWFIN is not set +# CONFIG_ZEROPLUS_FF is not set +# CONFIG_ZISOFS is not set +CONFIG_ZONE_DMA_FLAG=0 --- linux-2.6.28.orig/debian/config/i386/config +++ linux-2.6.28/debian/config/i386/config @@ -0,0 +1,3923 @@ +# +# Common config options automatically generated by splitconfig.pl +# +CONFIG_3C359=m +CONFIG_3C515=m +# CONFIG_4KSTACKS is not set +CONFIG_60XX_WDT=m +# CONFIG_64BIT is not set +CONFIG_6PACK=m +CONFIG_8139CP=m +CONFIG_8139TOO=m +CONFIG_8139TOO_8129=y +CONFIG_8139TOO_PIO=y +# 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_AC97_BUS=m +# CONFIG_ACCESSIBILITY is not set +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACER_WMI=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=y +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=2000 +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SBS=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_WMI=y +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +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_ALI=m +CONFIG_AGP_AMD=m +CONFIG_AGP_AMD64=m +CONFIG_AGP_ATI=m +CONFIG_AGP_EFFICEON=m +CONFIG_AGP_INTEL=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_AIO=y +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +CONFIG_AMD8111_ETH=m +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +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_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig" +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +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_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=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_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_ARPD is not set +CONFIG_ASK_IP_FIB_HASH=y +CONFIG_ASUS_LAPTOP=m +CONFIG_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_AT1700=m +CONFIG_AT24=m +CONFIG_ATA=y +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=y +CONFIG_ATA_SFF=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH9K=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL2=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_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_AUDIT=y +CONFIG_AUDITSYSCALL=y +# CONFIG_AUDIT_ARCH is not set +CONFIG_AUDIT_GENERIC=y +CONFIG_AUDIT_TREE=y +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +CONFIG_AUFS_BR_NFS=y +CONFIG_AUFS_BR_XFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_LHASH_PATCH=y +CONFIG_AUFS_PUT_FILP_PATCH=y +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +CONFIG_AUFS_SEC_PERM_PATCH=y +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +# CONFIG_AUFS_WORKAROUND_FUSE is not set +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AVERATEC_5100P=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43LEGACY_RFKILL=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_DA903X=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_MBP_NVIDIA=m +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BACKLIGHT_SAHARA=m +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_BQ27x00=m +CONFIG_BATTERY_DS2760=m +CONFIG_BATTERY_OLPC=m +CONFIG_BAYCOM_EPP=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +# 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_CPQ_CISS_DA=m +CONFIG_BLK_CPQ_DA=m +CONFIG_BLK_DEV=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_COMPCACHE=m +# CONFIG_BLK_DEV_COMPCACHE_DEBUG is not set +# CONFIG_BLK_DEV_COMPCACHE_STATS is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DM=y +CONFIG_BLK_DEV_DM_BBR=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_UB=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_XD is not set +# CONFIG_BLK_DEV_XIP is not set +CONFIG_BLOCK=y +CONFIG_BNX2=m +CONFIG_BNX2X=m +CONFIG_BONDING=m +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BOUNCE=y +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_IP6=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_NFLOG=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=y +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_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=y +CONFIG_BUG=y +CONFIG_C101=m +CONFIG_C2PORT=m +CONFIG_C2PORT_DURAMAR_2150=m +# CONFIG_CAN is not set +CONFIG_CAN_PM_TRACE=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_CARMINE_DRAM_CUSTOM is not set +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=y +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLASSIC_RCU=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +CONFIG_COMPAL_LAPTOP=m +# CONFIG_COMPAT_BRK is not set +# CONFIG_COMPAT_VDSO is not set +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=y +CONFIG_CONSOLE_POLL=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_COPS is not set +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +CONFIG_COSA=m +# CONFIG_CPA_DEBUG is not set +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_32=y +CONFIG_CPU_SUP_CYRIX_32=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CPU_SUP_TRANSMETA_32=y +CONFIG_CPU_SUP_UMC_32=y +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_586=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_GEODE=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +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_FIPS=y +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_586=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=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_CRYPTO_XTS=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 is not set +CONFIG_DAVICOM_PHY=m +CONFIG_DCDBAS=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_BOOT_PARAMS 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_GPIO is not set +# 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_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_NX_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG 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_VIRTUAL is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT 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_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 +# CONFIG_DEFAULT_NOOP is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_DEFXX=m +# CONFIG_DEFXX_MMIO is not set +CONFIG_DELL_RBU=m +CONFIG_DEPCA=m +CONFIG_DETECT_SOFTLOCKUP=y +CONFIG_DEVKMEM=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +# CONFIG_DL2K is not set +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_LOOP=m +CONFIG_DM_MIRROR=y +CONFIG_DM_MULTIPATH=y +CONFIG_DM_RAID45=m +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_UEVENT=y +CONFIG_DM_ZERO=m +CONFIG_DNOTIFY=y +CONFIG_DONGLE=y +CONFIG_DOUBLEFAULT=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_DS1682=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DTLK=m +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AF9013=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AV7110=m +# CONFIG_DVB_AV7110_FIRMWARE is not set +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_CORE=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DM1105=m +CONFIG_DVB_DRX397XD=m +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGS8GL5=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_S5H1409=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CINERGY_T2=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 is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=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_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_E2100=m +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=y +CONFIG_EDAC=y +CONFIG_EDAC_AMD76X=m +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_E7XXX=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I82860=m +CONFIG_EDAC_I82875P=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_R82600=m +CONFIG_EDAC_X38=m +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +CONFIG_EEXPRESS=m +CONFIG_EEXPRESS_PRO=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_VARS=y +CONFIG_EFS_FS=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_ELF_CORE=y +CONFIG_ELMC=m +CONFIG_ELMC_II=m +CONFIG_ELPLUS=m +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENC28J60 is not set +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_ENIC=m +CONFIG_EPIC100=m +CONFIG_EPOLL=y +CONFIG_EQUALIZER=m +CONFIG_ES3210=m +CONFIG_ESI_DONGLE=m +CONFIG_ESPSERIAL=m +CONFIG_ETH16I=m +CONFIG_EUROTECH_WDT=m +CONFIG_EVENTFD=y +CONFIG_EWRK3=m +CONFIG_EXPERIMENTAL=y +CONFIG_EXPORTFS=m +CONFIG_EXT2_FS=y +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=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FARSYNC=m +CONFIG_FAST_CMPXCHG_LOCAL=y +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=m +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_BOOT_VESA_SUPPORT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CARMINE=m +CONFIG_FB_CARMINE_DRAM_EVAL=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_CYBLA=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_EFI=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_GEODE_LX=m +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_IMSTT=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_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_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +CONFIG_FB_METRONOME=m +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_N411=m +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_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +CONFIG_FB_VIA=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_FILE_LOCKING=y +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_OHCI_DEBUG=y +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=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_FORCEDETH=m +# CONFIG_FORCEDETH_NAPI is not set +CONFIG_FRAMEBUFFER_CONSOLE=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=1024 +CONFIG_FREEZER=y +CONFIG_FSAM7400=m +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FS_UNIONFS=m +CONFIG_FTL=m +# CONFIG_FTRACE_STARTUP_TEST is not set +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +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_GARP=m +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +# CONFIG_GENERIC_CPU is not set +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_GPIO=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 is not set +CONFIG_GFS2_FS=m +CONFIG_GFS2_FS_LOCKING_DLM=m +CONFIG_GFS_FS=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_GPIOLIB=y +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_MCP23S08=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_SYSFS=y +CONFIG_GROUP_SCHED=y +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_AOUT=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_ATOMIC_IOMAP=y +# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MTD_OTP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=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_HECI=m +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIBERNATION=y +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_COMPAT is not set +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PID=y +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HIGHMEM=y +CONFIG_HIGHPTE=y +CONFIG_HIGH_RES_TIMERS=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=y +CONFIG_HOTPLUG_CPU=y +CONFIG_HOTPLUG_PCI=y +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=y +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPET_MMAP=y +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +CONFIG_HPLAN=m +CONFIG_HPLAN_PLUS=m +CONFIG_HP_ILO=m +# CONFIG_HP_WATCHDOG is not set +CONFIG_HP_WMI=m +CONFIG_HTC_PASIC3=m +CONFIG_HT_IRQ=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVC_DRIVER=y +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_HW_RANDOM_VIRTIO=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +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_GPIO=m +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_ISA=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=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_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_ICS932S401=m +# CONFIG_IDE 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_IFB=m +CONFIG_IGB=m +# CONFIG_IGB_LRO 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_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_LRO=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_NES is not set +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_ACERHK=m +# CONFIG_INPUT_APANEL is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=y +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_UINPUT=m +CONFIG_INPUT_WISTRON_BTNS=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_MENLOW=m +# CONFIG_IOMMU_HELPER is not set +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IP1000=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_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPC_NS=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_IPPP_FILTER=y +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SUBTREES is not set +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_IPWIRELESS=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_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=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_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_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_IPV6=y +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_AH_ESP=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_IRQSOFF_TRACER is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA=y +CONFIG_ISAPNP=y +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_IBFT=m +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=y +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_ISO9660_FS=m +CONFIG_ISTALLION=m +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_IWL3945=m +# CONFIG_IWL3945_DEBUG is not set +CONFIG_IWL3945_LEDS=y +CONFIG_IWL3945_RFKILL=y +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWLAGN=m +CONFIG_IWLAGN_LEDS=y +CONFIG_IWLAGN_SPECTRUM_MEASUREMENT=y +CONFIG_IWLCORE=m +CONFIG_IWLWIFI=m +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLWIFI_RFKILL=y +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_JBD=y +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +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_JME=m +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_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_K8_NB=y +CONFIG_KALLSYMS=y +CONFIG_KALLSYMS_ALL=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_KARMA_PARTITION=y +CONFIG_KEXEC=y +CONFIG_KEXEC_JUMP=y +CONFIG_KEYBOARD_ATKBD=y +CONFIG_KEYBOARD_GPIO=m +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_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +# CONFIG_KPROBES_SANITY_TEST is not set +CONFIG_KRETPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +CONFIG_KTIME_SCALAR=y +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_CLOCK=y +CONFIG_KVM_GUEST=y +CONFIG_KVM_INTEL=m +# CONFIG_KVM_TRACE is not set +CONFIG_LANCE=m +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LATENCYTOP=y +CONFIG_LBD=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_PLATFORM=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +# CONFIG_LEDS_CLEVO_MAIL is not set +CONFIG_LEDS_DA903X=m +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_HP_DISK=m +CONFIG_LEDS_NET48XX=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_WRAP=m +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIRC_ATIUSB=m +CONFIG_LIRC_BT829=m +CONFIG_LIRC_CMDIR=m +CONFIG_LIRC_DEV=m +# CONFIG_LIRC_GPIO is not set +CONFIG_LIRC_I2C=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_IT87=m +CONFIG_LIRC_MCEUSB=m +CONFIG_LIRC_MCEUSB2=m +# CONFIG_LIRC_PARALLEL is not set +CONFIG_LIRC_PVR150=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_IGOR=m +CONFIG_LIRC_SIR=m +CONFIG_LIRC_STREAMZAP=m +CONFIG_LIRC_TTUSBIR=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LMPCM_USB=m +CONFIG_LNE390=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_LOCK_STAT is not set +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGITECH_FF=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +CONFIG_LP486E=m +# CONFIG_LP_CONSOLE is not set +CONFIG_LSF=y +CONFIG_LTPC=m +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_PID=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MACVLAN=m +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MADGEMC=m +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARKERS=y +CONFIG_MARVELL_PHY=m +# CONFIG_MATH_EMULATION is not set +CONFIG_MAX_RAW_DEVS=256 +CONFIG_MCA=y +CONFIG_MCA_LEGACY=y +# CONFIG_MCA_PROC_FS 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=y +CONFIG_MDA_CONSOLE=m +CONFIG_MDIO_BITBANG=m +CONFIG_MD_AUTODETECT=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_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +# CONFIG_MEFFICEON is not set +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +# CONFIG_MEMSTICK is not set +# CONFIG_MEMTEST is not set +# CONFIG_MFD_CORE is not set +CONFIG_MFD_SM501=m +# CONFIG_MFD_SM501_GPIO is not set +# CONFIG_MFD_TMIO is not set +CONFIG_MFD_WM8350=m +CONFIG_MFD_WM8350_I2C=m +CONFIG_MFD_WM8400=m +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_L1OIP=m +CONFIG_MIXCOMWD=m +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_SDRICOH_CS=m +# CONFIG_MMC_TEST is not set +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +# CONFIG_MMIOTRACE is not set +CONFIG_MMU=y +CONFIG_MMU_NOTIFIER=y +CONFIG_MM_OWNER=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# 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_BCM5974=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_INPORT=m +CONFIG_MOUSE_LOGIBM=m +CONFIG_MOUSE_PC110PAD=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_ELANTECH=y +CONFIG_MOUSE_PS2_LIFEBOOK=y +CONFIG_MOUSE_PS2_LOGIPS2PP=y +CONFIG_MOUSE_PS2_OLPC=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=m +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSI_LAPTOP=m +CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" +CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" +CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" +CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" +CONFIG_MT9M001_PCA9536_SWITCH=y +CONFIG_MT9V022_PCA9536_SWITCH=y +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_AR7_PARTS=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_DATAFLASH_OTP=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# 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_INTEL_VR_NOR=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_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +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_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_MTRR=y +CONFIG_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +CONFIG_MWAVE=m +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_MYRI10GE=m +CONFIG_N2=m +CONFIG_NAMESPACES=y +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_NDISWRAPPER=m +CONFIG_NE2000=m +CONFIG_NE2K_PCI=m +CONFIG_NE2_MCA=m +CONFIG_NE3210=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=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_IPRANGE=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_OWNER=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_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=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_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=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_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETLABEL=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_RDMA=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +# CONFIG_NET_CLS_FLOW is not set +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_DSA=y +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=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_ET131X=m +CONFIG_NET_ETHERNET=y +CONFIG_NET_FC=y +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_NET_IPIP=m +CONFIG_NET_ISA=y +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_MULTIQ=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_NET_VENDOR_RACAL=y +CONFIG_NET_VENDOR_SMC=y +CONFIG_NEW_LEDS=y +CONFIG_NFSD=m +CONFIG_NFSD_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=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_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_DEFRAG_IPV4=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_PROTO_SCTP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NI52=m +CONFIG_NI65=m +CONFIG_NIU=m +CONFIG_NL80211=y +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_NOP_TRACER=y +CONFIG_NORTEL_HERMES=m +CONFIG_NOZOMI=m +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=64 +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_NVRAM=m +CONFIG_N_HDLC=m +# CONFIG_OCFS2_COMPAT_JBD is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OLPC=y +CONFIG_OMFS_FS=m +CONFIG_OPROFILE=m +CONFIG_OPROFILE_IBS=y +CONFIG_OPTIMIZE_INLINING=y +CONFIG_OSF_PARTITION=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_P80211=m +CONFIG_PACKARDBELL_E5=m +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PANASONIC_LAPTOP=m +CONFIG_PANTHERLORD_FF=y +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_CLOCK=y +# CONFIG_PARAVIRT_DEBUG is not set +CONFIG_PARAVIRT_GUEST=y +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_PCMCIA=m +# CONFIG_PARPORT_PC_SUPERIO is not set +CONFIG_PARPORT_SERIAL=m +CONFIG_PARTITION_ADVANCED=y +CONFIG_PATA_ACPI=y +CONFIG_PATA_ALI=y +CONFIG_PATA_AMD=y +CONFIG_PATA_ARTOP=y +CONFIG_PATA_ATIIXP=y +CONFIG_PATA_CMD640_PCI=y +CONFIG_PATA_CMD64X=y +CONFIG_PATA_CS5520=y +CONFIG_PATA_CS5530=y +CONFIG_PATA_CS5535=m +CONFIG_PATA_CS5536=y +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=y +CONFIG_PATA_HPT366=y +CONFIG_PATA_HPT37X=m +CONFIG_PATA_HPT3X2N=y +CONFIG_PATA_HPT3X3=y +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_ISAPNP=m +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=y +CONFIG_PATA_JMICRON=y +CONFIG_PATA_LEGACY=m +CONFIG_PATA_MARVELL=y +CONFIG_PATA_MPIIX=y +CONFIG_PATA_NETCELL=y +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87410=y +CONFIG_PATA_NS87415=y +CONFIG_PATA_OLDPIIX=m +CONFIG_PATA_OPTI=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=y +CONFIG_PATA_PDC_OLD=y +CONFIG_PATA_QDI=y +CONFIG_PATA_RADISYS=m +CONFIG_PATA_RZ1000=y +CONFIG_PATA_SC1200=y +CONFIG_PATA_SCH=y +CONFIG_PATA_SERVERWORKS=y +CONFIG_PATA_SIL680=y +CONFIG_PATA_SIS=y +CONFIG_PATA_TRIFLEX=y +CONFIG_PATA_VIA=y +CONFIG_PATA_WINBOND=y +CONFIG_PATA_WINBOND_VLB=m +# CONFIG_PC300TOO is not set +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_PCIEASPM is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +CONFIG_PCI_BIOS=y +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=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_GOOLPC is not set +CONFIG_PCI_HERMES=m +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCI_OLPC=y +CONFIG_PCI_QUIRKS=y +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_PCNET32=m +CONFIG_PCSPKR_PLATFORM=y +CONFIG_PCWATCHDOG=m +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +CONFIG_PDC_ADMA=y +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONET=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=y +CONFIG_PHYSICAL_ALIGN=0x100000 +CONFIG_PHYSICAL_START=0x100000 +# CONFIG_PID_NS is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +CONFIG_PLX_HERMES=m +CONFIG_PM=y +CONFIG_PMIC_DA903X=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_TEST_SUSPEND=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +CONFIG_PNPBIOS=y +CONFIG_PNPBIOS_PROC_FS=y +CONFIG_PNP_DEBUG_MESSAGES=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=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_NOTIFIERS=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PRISM2_USB=m +CONFIG_PRISM54=m +CONFIG_PROC_EVENTS=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +CONFIG_PROTEON=m +# CONFIG_PROVE_LOCKING is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_PSS_HAVE_BOOT is not set +CONFIG_PSS_MIXER=y +CONFIG_QC_USB=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QLGE=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +# CONFIG_R6040 is not set +CONFIG_R8169=m +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=y +CONFIG_RADIO_ZOLTRIX=m +CONFIG_RAID_ATTRS=m +CONFIG_RAW_DRIVER=m +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REALTEK_PHY is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_BQ24022=m +CONFIG_REGULATOR_DA903X=m +CONFIG_REGULATOR_DEBUG=y +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +# 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_RESOURCE_COUNTERS=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RING_BUFFER=y +CONFIG_RIO=m +# CONFIG_RIO_OLDPCI is not set +CONFIG_RISCOM8=m +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_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_CRYPTO=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1390=m +# CONFIG_RTC_DRV_DS1511 is not set +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS3234=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=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_R9701 is not set +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_RX8581=m +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_WM8350=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_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RT_GROUP_SCHED=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=y +CONFIG_SATA_INIC162X=y +CONFIG_SATA_MV=m +CONFIG_SATA_NV=y +CONFIG_SATA_PMP=y +CONFIG_SATA_PROMISE=y +CONFIG_SATA_QSTOR=y +CONFIG_SATA_SIL=y +CONFIG_SATA_SIL24=y +CONFIG_SATA_SIS=y +CONFIG_SATA_SVW=y +CONFIG_SATA_SX4=m +CONFIG_SATA_ULI=y +CONFIG_SATA_VIA=y +CONFIG_SATA_VITESSE=y +CONFIG_SBC7240_WDT=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=0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +CONFIG_SCC=m +# CONFIG_SCC_DELAY is not set +# CONFIG_SCC_TRXECHO is not set +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_SMT=y +# CONFIG_SCHED_TRACER is not set +CONFIG_SCSI=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_AIC7XXX_OLD is not set +CONFIG_SCSI_AIC94XX=m +CONFIG_SCSI_ARCMSR=m +CONFIG_SCSI_ARCMSR_AER=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DMA=y +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_ENCLOSURE=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +CONFIG_SCSI_FD_MCS=m +# CONFIG_SCSI_FLASHPOINT is not set +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_ISCSITARGET=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_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_MVSAS is not set +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_NETLINK=y +CONFIG_SCSI_NSP32=m +CONFIG_SCSI_PAS16=m +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_QLOGIC_FAS=m +CONFIG_SCSI_SAS_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_HOST_SMP=y +CONFIG_SCSI_SAS_LIBSAS=m +# CONFIG_SCSI_SAS_LIBSAS_DEBUG is not set +CONFIG_SCSI_SCAN_ASYNC=y +CONFIG_SCSI_SIM710=m +CONFIG_SCSI_SPI_ATTRS=m +CONFIG_SCSI_SRP=m +CONFIG_SCSI_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +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_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=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_SDIO_UART=m +CONFIG_SDLA=m +CONFIG_SEALEVEL_4021=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_DISABLE=y +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +CONFIG_SECURITY_FILE_CAPABILITIES=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +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_SECURITY_SMACK=y +CONFIG_SEEQ8005=m +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADCXX=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_ADS7828=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LIS3LV02D=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_LM93=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=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_SENSORS_W83L786NG=m +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_ACCENT=m +CONFIG_SERIAL_8250_BOCA=m +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_CS=m +# CONFIG_SERIAL_8250_DETECT_IRQ is not set +CONFIG_SERIAL_8250_EXAR_ST16C554=m +CONFIG_SERIAL_8250_EXTENDED=y +CONFIG_SERIAL_8250_FOURPORT=m +CONFIG_SERIAL_8250_HUB6=m +CONFIG_SERIAL_8250_MANY_PORTS=y +CONFIG_SERIAL_8250_MCA=m +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_SFC=m +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKISA=m +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=y +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_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_SMC9194=m +CONFIG_SMCTR=m +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_AC97_POWER_SAVE_DEFAULT=0 +CONFIG_SND_AD1816A=m +CONFIG_SND_AD1848=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_AW2=m +CONFIG_SND_AZT2320=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_BTSCO=m +CONFIG_SND_CA0106=m +CONFIG_SND_CMI8330=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4231=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_CS5530=m +CONFIG_SND_CS5535AUDIO=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +CONFIG_SND_DT019X=m +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_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_HDA_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_HWDEP is not set +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=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_INTERWAVE=m +CONFIG_SND_INTERWAVE_STB=m +CONFIG_SND_ISA=y +CONFIG_SND_KORG1212=m +CONFIG_SND_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +CONFIG_SND_MIA=m +CONFIG_SND_MIRO=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_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_OSSEMUL=y +CONFIG_SND_OXYGEN=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_PCI=y +CONFIG_SND_PCM=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCSP=m +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_SB16=m +CONFIG_SND_SB16_CSP=y +CONFIG_SND_SB16_DSP=m +CONFIG_SND_SB8=m +CONFIG_SND_SB8_DSP=m +CONFIG_SND_SBAWE=m +CONFIG_SND_SB_COMMON=m +CONFIG_SND_SC6000=m +CONFIG_SND_SEQUENCER=m +CONFIG_SND_SEQUENCER_OSS=y +CONFIG_SND_SEQ_DUMMY=m +CONFIG_SND_SERIAL_U16550=m +CONFIG_SND_SGALAXY=m +CONFIG_SND_SIS7019=m +CONFIG_SND_SOC=m +CONFIG_SND_SOC_AD73311=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SPI=y +CONFIG_SND_SSCAPE=m +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +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_VIRTUOSO=m +CONFIG_SND_VMASTER=y +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_WSS_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_PLATFORM=m +CONFIG_SOFT_WATCHDOG=m +CONFIG_SOLARIS_X86_PARTITION=y +CONFIG_SONYPI=m +CONFIG_SONYPI_COMPAT=y +CONFIG_SONY_LAPTOP=m +CONFIG_SOUND=m +CONFIG_SOUND_AEDSP16=m +CONFIG_SOUND_DMAP=y +CONFIG_SOUND_KAHLUA=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSNDCLAS=m +CONFIG_SOUND_MSNDPIN=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_PAS=m +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_SB=m +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_SPARSEMEM_STATIC=y +CONFIG_SPECIALIX=m +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SSB=m +CONFIG_SSB_B43_PCI_BRIDGE=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB_SPROM=y +CONFIG_SSFDC=m +CONFIG_STACKTRACE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +# CONFIG_STAGING is not set +CONFIG_STALDRV=y +CONFIG_STALLION=m +# CONFIG_STANDALONE is not set +CONFIG_STOP_MACHINE=y +CONFIG_STP=m +CONFIG_STRICT_DEVMEM=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=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_SYSCTL_SYSCALL_CHECK=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSPROF_TRACER is not set +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=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TC1100_WMI=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_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THRUSTMASTER_FF=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=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_TLAN=m +CONFIG_TLSF=m +# CONFIG_TLSF_DEBUG is not set +# CONFIG_TLSF_STATS is not set +CONFIG_TLSUP=m +CONFIG_TMD_HERMES=m +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_TMS380TR=m +CONFIG_TMSPCI=m +# 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_HTCPEN=m +CONFIG_TOUCHSCREEN_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHIT213=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_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TPS65010=m +CONFIG_TP_SMAPI=m +CONFIG_TP_SMAPI_EC=m +CONFIG_TR=y +CONFIG_TRACEPOINTS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACING=y +CONFIG_TTPCI_EEPROM=m +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_TYPHOON=m +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UCB1400_CORE=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_SMX=m +CONFIG_ULI526X=m +CONFIG_ULTRA=m +CONFIG_ULTRA32=m +CONFIG_ULTRAMCA=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=y +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_APPLEIR=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_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_CATC=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +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_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_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_QE 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_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GSPCA=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HSO=m +CONFIG_USB_HWA_HCD=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_ISP1760_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_M5602=m +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_MR800=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_RNDIS_WLAN=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_ZAURUS=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_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_OV511_NEW=m +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_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_S2255=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CONSOLE=y +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_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN=m +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_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=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_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_SI470X=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_STKWEBCAM=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +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_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TMC=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_VST=m +CONFIG_USB_W9968CF=m +CONFIG_USB_WDM=m +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +# CONFIG_USER_SCHED is not set +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_UTS_NS=y +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_I1480U=m +CONFIG_UWB_I1480U_WLP=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_WLP=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="" +CONFIG_VETH=m +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=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BTCX=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_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=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_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_MEDIA=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PMS=m +CONFIG_VIDEO_PVRUSB2=m +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_DVB=y +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_SAA717X=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SH_MOBILE_CEU=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_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=m +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=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_VIRTIO=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +CONFIG_VLSI_FIR=m +CONFIG_VM86=y +CONFIG_VMI=y +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_GPIO=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83697UG_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_WAVELAN=m +CONFIG_WD80x3=m +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=y +CONFIG_WIRELESS_ACX=m +CONFIG_WIRELESS_AT76=m +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86=y +CONFIG_X86_32=y +CONFIG_X86_32_SMP=y +# CONFIG_X86_64 is not set +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_APM_BOOT=y +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_BSWAP=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CPU=y +CONFIG_X86_CPUFREQ_NFORCE2=m +CONFIG_X86_CPUID=m +# CONFIG_X86_ELAN 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_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=m +CONFIG_X86_LONGRUN=m +# CONFIG_X86_MCE is not set +CONFIG_X86_MINIMUM_CPU_FAMILY=4 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +CONFIG_X86_P4_CLOCKMOD=m +# CONFIG_X86_PAT is not set +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_PTDUMP is not set +# CONFIG_X86_RDC321X is not set +CONFIG_X86_REBOOTFIXUPS=y +CONFIG_X86_RESERVE_LOW_64K=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_CENTRINO=m +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=m +CONFIG_X86_TRAMPOLINE=y +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_X86_XADD=y +CONFIG_XFRM=y +CONFIG_XFRM_IPCOMP=m +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +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_ZEROPLUS_FF=m +CONFIG_ZISOFS=y +CONFIG_ZLIB_DEFLATE=m +CONFIG_ZLIB_INFLATE=y +CONFIG_ZNET=m +CONFIG_ZONE_DMA=y +# CONFIG_ZONE_DMA32 is not set +CONFIG_ZONE_DMA_FLAG=1 --- linux-2.6.28.orig/debian/config/i386/config.generic +++ linux-2.6.28/debian/config/i386/config.generic @@ -0,0 +1,32 @@ +# +# Config options for config.generic automatically generated by splitconfig.pl +# +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_DCA=m +CONFIG_DEFAULT_CFQ=y +# CONFIG_DEFAULT_DEADLINE is not set +CONFIG_DEFAULT_IOSCHED="cfq" +CONFIG_DMADEVICES=y +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +CONFIG_HIGHMEM4G=y +# CONFIG_HIGHMEM64G is not set +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_IGB_DCA=y +CONFIG_INTEL_IOATDMA=m +CONFIG_IXGBE_DCA=y +# CONFIG_LGUEST is not set +# CONFIG_LGUEST_GUEST is not set +CONFIG_M586=y +# CONFIG_M686 is not set +CONFIG_MYRI10GE_DCA=y +CONFIG_NET_DMA=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_RESOURCES_64BIT is not set +CONFIG_X86_ALIGNMENT_16=y +CONFIG_X86_E_POWERSAVER=m +CONFIG_X86_F00F_BUG=y --- linux-2.6.28.orig/debian/config/i386/config.server +++ linux-2.6.28/debian/config/i386/config.server @@ -0,0 +1,39 @@ +# +# Config options for config.server automatically generated by splitconfig.pl +# +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_DEADLINE=y +CONFIG_DEFAULT_IOSCHED="deadline" +# CONFIG_HIGHMEM4G is not set +CONFIG_HIGHMEM64G=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +CONFIG_HZ=100 +CONFIG_HZ_100=y +# CONFIG_HZ_250 is not set +CONFIG_I2O_EXT_ADAPTEC_DMA64=y +# CONFIG_M586 is not set +CONFIG_M686=y +CONFIG_PHYS_ADDR_T_64BIT=y +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_RESOURCES_64BIT=y +CONFIG_X86_CMOV=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_DEBUGCTLMSR=y +# CONFIG_X86_DS is not set +# CONFIG_X86_E_POWERSAVER is not set +CONFIG_X86_PAE=y +CONFIG_X86_TSC=y +CONFIG_X86_USE_PPRO_CHECKSUM=y +CONFIG_XEN=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_BLKDEV_FRONTEND=m +# CONFIG_XEN_DEBUG_FS is not set +CONFIG_XEN_FBDEV_FRONTEND=m +CONFIG_XEN_KBDDEV_FRONTEND=m +CONFIG_XEN_MAX_DOMAIN_MEMORY=8 +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_XEN_SCRUB_PAGES=y --- linux-2.6.28.orig/debian/config/amd64/config +++ linux-2.6.28/debian/config/amd64/config @@ -0,0 +1,3672 @@ +# +# 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=y +# 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_ACCESSIBILITY is not set +CONFIG_ACENIC=m +# CONFIG_ACENIC_OMIT_TIGON_I is not set +CONFIG_ACER_WMI=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=y +# CONFIG_ACPI_ASUS is not set +CONFIG_ACPI_BATTERY=y +CONFIG_ACPI_BLACKLIST_YEAR=0 +CONFIG_ACPI_BUTTON=y +CONFIG_ACPI_CONTAINER=y +# CONFIG_ACPI_CUSTOM_DSDT is not set +CONFIG_ACPI_CUSTOM_DSDT_FILE="" +CONFIG_ACPI_CUSTOM_DSDT_INITRD=y +# CONFIG_ACPI_DEBUG is not set +CONFIG_ACPI_DOCK=y +CONFIG_ACPI_FAN=y +CONFIG_ACPI_HOTPLUG_CPU=y +CONFIG_ACPI_PCI_SLOT=y +CONFIG_ACPI_PROCESSOR=y +CONFIG_ACPI_PROCFS=y +CONFIG_ACPI_PROCFS_POWER=y +CONFIG_ACPI_PROC_EVENT=y +CONFIG_ACPI_SBS=y +CONFIG_ACPI_SLEEP=y +CONFIG_ACPI_SYSFS_POWER=y +CONFIG_ACPI_SYSTEM=y +CONFIG_ACPI_THERMAL=y +# CONFIG_ACPI_TOSHIBA is not set +CONFIG_ACPI_VIDEO=m +CONFIG_ACPI_WMI=y +CONFIG_ACQUIRE_WDT=m +CONFIG_ACT200L_DONGLE=m +CONFIG_ACTISYS_DONGLE=m +CONFIG_ADAPTEC_STARFIRE=m +CONFIG_ADFS_FS=m +# CONFIG_ADFS_FS_RW is not set +CONFIG_ADM8211=m +CONFIG_ADVANTECH_WDT=m +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_AIO=y +CONFIG_AIRO=m +CONFIG_AIRO_CS=m +CONFIG_ALIM1535_WDT=m +CONFIG_ALIM7101_WDT=m +CONFIG_ALI_FIR=m +CONFIG_AMD8111_ETH=m +CONFIG_AMD_IOMMU=y +CONFIG_AMIGA_PARTITION=y +CONFIG_ANON_INODES=y +CONFIG_APPLICOM=m +CONFIG_ARCH_DEFCONFIG="arch/x86/configs/x86_64_defconfig" +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y +CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y +CONFIG_ARCH_HAS_CPU_RELAX=y +CONFIG_ARCH_HAS_DEFAULT_IDLE=y +CONFIG_ARCH_HIBERNATION_HEADER=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y +CONFIG_ARCH_POPULATES_NODE_MAP=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_DEFAULT=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUPPORTS_MSI=y +CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=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_ASYNC_CORE=m +CONFIG_ASYNC_MEMCPY=m +CONFIG_ASYNC_XOR=m +CONFIG_AT24=m +CONFIG_ATA=y +CONFIG_ATALK=m +CONFIG_ATARI_PARTITION=y +CONFIG_ATA_ACPI=y +CONFIG_ATA_GENERIC=y +# CONFIG_ATA_NONSTANDARD is not set +CONFIG_ATA_OVER_ETH=m +CONFIG_ATA_PIIX=y +CONFIG_ATA_SFF=y +CONFIG_ATH5K=m +# CONFIG_ATH5K_DEBUG is not set +CONFIG_ATH9K=m +CONFIG_ATL1=m +CONFIG_ATL1E=m +CONFIG_ATL2=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_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_TCP=m +CONFIG_ATM_ZATM=m +# CONFIG_ATM_ZATM_DEBUG is not set +CONFIG_ATP=m +CONFIG_AUDIT=y +CONFIG_AUDITSYSCALL=y +CONFIG_AUDIT_ARCH=y +CONFIG_AUDIT_TREE=y +CONFIG_AUFS=m +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +# CONFIG_AUFS_BRANCH_MAX_511 is not set +CONFIG_AUFS_BR_NFS=y +CONFIG_AUFS_BR_XFS=y +# CONFIG_AUFS_COMPAT is not set +# CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_DENY_WRITE_ACCESS_PATCH=y +# CONFIG_AUFS_DLGT is not set +CONFIG_AUFS_EXPORT=y +# CONFIG_AUFS_FSYNC_SUPER_PATCH is not set +CONFIG_AUFS_HINOTIFY=y +CONFIG_AUFS_HIN_OR_DLGT=y +CONFIG_AUFS_HIN_OR_FUSE=y +CONFIG_AUFS_INO_T_64=y +CONFIG_AUFS_LHASH_PATCH=y +CONFIG_AUFS_PUT_FILP_PATCH=y +# CONFIG_AUFS_ROBR is not set +CONFIG_AUFS_RR_SQUASHFS=y +CONFIG_AUFS_SEC_PERM_PATCH=y +CONFIG_AUFS_SHWH=y +CONFIG_AUFS_SPLICE_PATCH=y +CONFIG_AUFS_STAT=y +# CONFIG_AUFS_UNIONFS22_PATCH is not set +# CONFIG_AUFS_UNIONFS23_PATCH is not set +# CONFIG_AUFS_WORKAROUND_FUSE is not set +CONFIG_AUTOFS4_FS=m +CONFIG_AUTOFS_FS=m +CONFIG_AUXDISPLAY=y +CONFIG_AVERATEC_5100P=m +CONFIG_AX25=m +CONFIG_AX25_DAMA_SLAVE=y +CONFIG_B43=m +CONFIG_B43LEGACY=m +CONFIG_B43LEGACY_DEBUG=y +CONFIG_B43LEGACY_DMA=y +CONFIG_B43LEGACY_DMA_AND_PIO_MODE=y +# CONFIG_B43LEGACY_DMA_MODE is not set +CONFIG_B43LEGACY_LEDS=y +CONFIG_B43LEGACY_PCICORE_AUTOSELECT=y +CONFIG_B43LEGACY_PCI_AUTOSELECT=y +CONFIG_B43LEGACY_PIO=y +# CONFIG_B43LEGACY_PIO_MODE is not set +CONFIG_B43LEGACY_RFKILL=y +# CONFIG_B43_DEBUG is not set +CONFIG_B43_LEDS=y +CONFIG_B43_PCICORE_AUTOSELECT=y +CONFIG_B43_PCI_AUTOSELECT=y +# CONFIG_B43_PCMCIA is not set +CONFIG_B43_RFKILL=y +CONFIG_B44=m +CONFIG_B44_PCI=y +CONFIG_B44_PCICORE_AUTOSELECT=y +CONFIG_B44_PCI_AUTOSELECT=y +CONFIG_BACKLIGHT_CARILLO_RANCH=m +CONFIG_BACKLIGHT_CLASS_DEVICE=y +CONFIG_BACKLIGHT_CORGI=m +CONFIG_BACKLIGHT_DA903X=m +CONFIG_BACKLIGHT_LCD_SUPPORT=y +CONFIG_BACKLIGHT_MBP_NVIDIA=m +CONFIG_BACKLIGHT_PROGEAR=m +CONFIG_BACKLIGHT_SAHARA=m +# CONFIG_BACKTRACE_SELF_TEST is not set +CONFIG_BASE_FULL=y +CONFIG_BASE_SMALL=0 +CONFIG_BATTERY_BQ27x00=m +CONFIG_BATTERY_DS2760=m +CONFIG_BAYCOM_PAR=m +CONFIG_BAYCOM_SER_FDX=m +CONFIG_BAYCOM_SER_HDX=m +# 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=y +CONFIG_BLK_DEV_3W_XXXX_RAID=m +# CONFIG_BLK_DEV_BSG is not set +CONFIG_BLK_DEV_COMPCACHE=m +# CONFIG_BLK_DEV_COMPCACHE_DEBUG is not set +# CONFIG_BLK_DEV_COMPCACHE_STATS is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_DAC960=m +CONFIG_BLK_DEV_DM=y +CONFIG_BLK_DEV_DM_BBR=m +CONFIG_BLK_DEV_DRBD=m +CONFIG_BLK_DEV_FD=m +# CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_INITRD=y +CONFIG_BLK_DEV_INTEGRITY=y +CONFIG_BLK_DEV_IO_TRACE=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_MD=y +CONFIG_BLK_DEV_NBD=m +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=65536 +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SX8=m +CONFIG_BLK_DEV_UB=m +CONFIG_BLK_DEV_UMEM=m +# CONFIG_BLK_DEV_XIP is not set +CONFIG_BLOCK=y +CONFIG_BLOCK_COMPAT=y +CONFIG_BNX2=m +CONFIG_BNX2X=m +CONFIG_BONDING=m +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 +# CONFIG_BOOT_PRINTK_DELAY is not set +# CONFIG_BOOT_TRACER is not set +CONFIG_BOUNCE=y +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_IP6=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_NFLOG=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=y +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_HCIBTSDIO=m +CONFIG_BT_HCIBTUART=m +CONFIG_BT_HCIBTUSB=m +CONFIG_BT_HCIDTL1=m +CONFIG_BT_HCIUART=m +CONFIG_BT_HCIUART_BCSP=y +CONFIG_BT_HCIUART_H4=y +CONFIG_BT_HCIUART_LL=y +CONFIG_BT_HCIVHCI=m +CONFIG_BT_HIDP=m +CONFIG_BT_L2CAP=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_SCO=y +CONFIG_BUG=y +CONFIG_C2PORT=m +CONFIG_C2PORT_DURAMAR_2150=m +CONFIG_CALGARY_IOMMU=y +CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT=y +# CONFIG_CAN is not set +CONFIG_CAN_PM_TRACE=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_CARMINE_DRAM_CUSTOM is not set +CONFIG_CASSINI=m +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_CDROM_PKTCDVD=y +CONFIG_CDROM_PKTCDVD_BUFFERS=8 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set +CONFIG_CFAG12864B=m +CONFIG_CFAG12864B_RATE=20 +CONFIG_CFG80211=m +CONFIG_CGROUPS=y +CONFIG_CGROUP_CPUACCT=y +# CONFIG_CGROUP_DEBUG is not set +# CONFIG_CGROUP_DEVICE is not set +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_MEM_RES_CTLR=y +CONFIG_CGROUP_NS=y +CONFIG_CGROUP_SCHED=y +CONFIG_CHECK_SIGNATURE=y +CONFIG_CHELSIO_T1=m +CONFIG_CHELSIO_T1_1G=y +CONFIG_CHELSIO_T3=m +CONFIG_CHR_DEV_OSST=m +CONFIG_CHR_DEV_SCH=m +CONFIG_CHR_DEV_SG=y +CONFIG_CHR_DEV_ST=m +CONFIG_CICADA_PHY=m +CONFIG_CIFS=m +# CONFIG_CIFS_DEBUG2 is not set +CONFIG_CIFS_DFS_UPCALL=y +CONFIG_CIFS_EXPERIMENTAL=y +CONFIG_CIFS_POSIX=y +# CONFIG_CIFS_STATS is not set +CONFIG_CIFS_UPCALL=y +CONFIG_CIFS_WEAK_PW_HASH=y +CONFIG_CIFS_XATTR=y +CONFIG_CISS_SCSI_TAPE=y +CONFIG_CLASSIC_RCU=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_CLS_U32_MARK=y +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_CODA_FS=m +CONFIG_COMPAL_LAPTOP=m +CONFIG_COMPAT=y +CONFIG_COMPAT_BINFMT_ELF=y +# CONFIG_COMPAT_BRK is not set +CONFIG_COMPAT_FOR_U64_ALIGNMENT=y +# CONFIG_COMPAT_VDSO is not set +CONFIG_COMPUTONE=m +CONFIG_CONFIGFS_FS=m +CONFIG_CONNECTOR=y +CONFIG_CONSOLE_POLL=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTEXT_SWITCH_TRACER=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_CPA_DEBUG is not set +CONFIG_CPU5_WDT=m +CONFIG_CPUSETS=y +CONFIG_CPU_FREQ=y +# CONFIG_CPU_FREQ_DEBUG is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_FREQ_STAT_DETAILS=y +CONFIG_CPU_FREQ_TABLE=y +CONFIG_CPU_IDLE=y +CONFIG_CPU_IDLE_GOV_LADDER=y +CONFIG_CPU_IDLE_GOV_MENU=y +CONFIG_CPU_SUP_AMD=y +CONFIG_CPU_SUP_CENTAUR_64=y +CONFIG_CPU_SUP_INTEL=y +CONFIG_CRAMFS=y +CONFIG_CRASH_DUMP=y +CONFIG_CRC16=y +CONFIG_CRC32=y +CONFIG_CRC7=m +CONFIG_CRC_CCITT=m +CONFIG_CRC_ITU_T=m +CONFIG_CRC_T10DIF=y +CONFIG_CRYPTO=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_AES=m +CONFIG_CRYPTO_AES_X86_64=m +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_ANUBIS=m +CONFIG_CRYPTO_ARC4=m +CONFIG_CRYPTO_AUTHENC=m +CONFIG_CRYPTO_BLKCIPHER=m +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_CAMELLIA=m +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_CCM=m +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_CRC32C_INTEL=m +CONFIG_CRYPTO_CRYPTD=m +CONFIG_CRYPTO_CTR=m +CONFIG_CRYPTO_CTS=m +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_DES=m +CONFIG_CRYPTO_DEV_HIFN_795X=m +CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y +CONFIG_CRYPTO_ECB=m +CONFIG_CRYPTO_FCRYPT=m +CONFIG_CRYPTO_FIPS=y +CONFIG_CRYPTO_GCM=m +CONFIG_CRYPTO_GF128MUL=m +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_HW=y +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_LRW=m +CONFIG_CRYPTO_LZO=m +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y +CONFIG_CRYPTO_MICHAEL_MIC=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_PCBC=m +CONFIG_CRYPTO_RMD128=m +CONFIG_CRYPTO_RMD160=m +CONFIG_CRYPTO_RMD256=m +CONFIG_CRYPTO_RMD320=m +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_SALSA20=m +CONFIG_CRYPTO_SALSA20_X86_64=m +CONFIG_CRYPTO_SEED=m +CONFIG_CRYPTO_SEQIV=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_CRYPTO_XTS=m +CONFIG_CYCLADES=m +CONFIG_CYCLADES_SYNC=m +CONFIG_CYCLOMX_X25=y +# CONFIG_CYZ_INTR is not set +# CONFIG_DAB is not set +CONFIG_DAVICOM_PHY=m +CONFIG_DCA=m +CONFIG_DCDBAS=m +CONFIG_DE2104X=m +CONFIG_DE4X5=m +CONFIG_DE600=m +CONFIG_DE620=m +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set +# CONFIG_DEBUG_BOOT_PARAMS 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_GPIO 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_MEMORY_INIT=y +# CONFIG_DEBUG_MUTEXES is not set +# CONFIG_DEBUG_NX_TEST is not set +# CONFIG_DEBUG_OBJECTS is not set +# CONFIG_DEBUG_PAGEALLOC is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +CONFIG_DEBUG_RODATA=y +# CONFIG_DEBUG_RODATA_TEST is not set +# CONFIG_DEBUG_RT_MUTEXES is not set +# CONFIG_DEBUG_SG 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_VIRTUAL is not set +# CONFIG_DEBUG_VM is not set +# CONFIG_DEBUG_WRITECOUNT 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_BIC is not set +CONFIG_DEFAULT_CUBIC=y +# CONFIG_DEFAULT_HTCP is not set +CONFIG_DEFAULT_IO_DELAY_TYPE=1 +# CONFIG_DEFAULT_NOOP is not set +# CONFIG_DEFAULT_RENO is not set +CONFIG_DEFAULT_TCP_CONG="cubic" +# CONFIG_DEFAULT_VEGAS is not set +# CONFIG_DEFAULT_WESTWOOD is not set +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_DEVKMEM=y +CONFIG_DEVPORT=y +CONFIG_DEV_APPLETALK=m +CONFIG_DE_AOC=y +CONFIG_DIGIEPCA=m +# CONFIG_DIRECT_GBPAGES is not set +# CONFIG_DISCONTIGMEM_MANUAL is not set +CONFIG_DISPLAY_SUPPORT=m +# CONFIG_DL2K is not set +CONFIG_DLCI=m +CONFIG_DLCI_MAX=8 +CONFIG_DLM=m +# CONFIG_DLM_DEBUG is not set +CONFIG_DM9102=m +CONFIG_DMADEVICES=y +# CONFIG_DMAR is not set +# CONFIG_DMATEST is not set +CONFIG_DMA_ENGINE=y +CONFIG_DMI=y +CONFIG_DMIID=y +CONFIG_DM_CRYPT=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_DELAY is not set +CONFIG_DM_LOOP=m +CONFIG_DM_MIRROR=y +CONFIG_DM_MULTIPATH=y +CONFIG_DM_RAID45=m +CONFIG_DM_SNAPSHOT=y +CONFIG_DM_UEVENT=y +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_DS1682=m +CONFIG_DSCC4=m +CONFIG_DSCC4_PCISYNC=y +CONFIG_DSCC4_PCI_RST=y +CONFIG_DUMMY=m +CONFIG_DUMMY_CONSOLE=y +CONFIG_DVB_AF9013=m +CONFIG_DVB_AU8522=m +CONFIG_DVB_AV7110=m +# CONFIG_DVB_AV7110_FIRMWARE is not set +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_CORE=m +CONFIG_DVB_BUDGET_PATCH=m +CONFIG_DVB_CAPTURE_DRIVERS=y +CONFIG_DVB_CORE=m +CONFIG_DVB_CX22700=m +CONFIG_DVB_CX22702=m +CONFIG_DVB_CX24110=m +CONFIG_DVB_CX24116=m +CONFIG_DVB_CX24123=m +CONFIG_DVB_DIB3000MB=m +CONFIG_DVB_DIB3000MC=m +CONFIG_DVB_DIB7000M=m +CONFIG_DVB_DIB7000P=m +CONFIG_DVB_DM1105=m +CONFIG_DVB_DRX397XD=m +# CONFIG_DVB_DUMMY_FE is not set +# CONFIG_DVB_FE_CUSTOMISE is not set +CONFIG_DVB_ISL6405=m +CONFIG_DVB_ISL6421=m +CONFIG_DVB_L64781=m +CONFIG_DVB_LGDT330X=m +CONFIG_DVB_LGS8GL5=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_S5H1409=m +CONFIG_DVB_S5H1411=m +CONFIG_DVB_S5H1420=m +CONFIG_DVB_SI21XX=m +CONFIG_DVB_SIANO_SMS1XXX=m +CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS=y +CONFIG_DVB_SP8870=m +CONFIG_DVB_SP887X=m +CONFIG_DVB_STB6000=m +CONFIG_DVB_STV0288=m +CONFIG_DVB_STV0297=m +CONFIG_DVB_STV0299=m +CONFIG_DVB_TDA10021=m +CONFIG_DVB_TDA10023=m +CONFIG_DVB_TDA10048=m +CONFIG_DVB_TDA1004X=m +CONFIG_DVB_TDA10086=m +CONFIG_DVB_TDA8083=m +CONFIG_DVB_TDA826X=m +CONFIG_DVB_TTUSB_BUDGET=m +CONFIG_DVB_TTUSB_DEC=m +CONFIG_DVB_TUA6100=m +CONFIG_DVB_TUNER_DIB0070=m +CONFIG_DVB_TUNER_ITD1000=m +CONFIG_DVB_USB=m +CONFIG_DVB_USB_A800=m +CONFIG_DVB_USB_AF9005=m +CONFIG_DVB_USB_AF9005_REMOTE=m +CONFIG_DVB_USB_AF9015=m +CONFIG_DVB_USB_ANYSEE=m +CONFIG_DVB_USB_AU6610=m +CONFIG_DVB_USB_CINERGY_T2=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 is not set +CONFIG_DVB_USB_DIBUSB_MC=m +CONFIG_DVB_USB_DIGITV=m +CONFIG_DVB_USB_DTT200U=m +CONFIG_DVB_USB_DTV5100=m +CONFIG_DVB_USB_DW2102=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_DYNAMIC_PRINTK_DEBUG is not set +CONFIG_E100=m +CONFIG_E1000=m +CONFIG_E1000E=m +CONFIG_EARLY_PRINTK=y +# CONFIG_EARLY_PRINTK_DBGP is not set +CONFIG_ECONET=m +CONFIG_ECONET_AUNUDP=y +CONFIG_ECONET_NATIVE=y +CONFIG_ECRYPT_FS=y +CONFIG_EDAC=y +# CONFIG_EDAC_DEBUG is not set +CONFIG_EDAC_E752X=m +CONFIG_EDAC_I3000=m +CONFIG_EDAC_I5000=m +CONFIG_EDAC_I5100=m +CONFIG_EDAC_I82975X=m +CONFIG_EDAC_MM_EDAC=m +CONFIG_EDAC_X38=m +CONFIG_EDD=y +CONFIG_EDD_OFF=y +CONFIG_EEEPC_LAPTOP=m +CONFIG_EEPRO100=m +CONFIG_EEPROM_93CX6=m +CONFIG_EFI=y +CONFIG_EFI_PARTITION=y +CONFIG_EFI_VARS=y +CONFIG_EFS_FS=m +CONFIG_ELF_CORE=y +# CONFIG_EMBEDDED is not set +# CONFIG_ENABLE_MUST_CHECK is not set +# CONFIG_ENABLE_WARN_DEPRECATED is not set +# CONFIG_ENC28J60 is not set +CONFIG_ENCLOSURE_SERVICES=m +CONFIG_ENIC=m +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=y +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=y +CONFIG_EXT3_FS_POSIX_ACL=y +CONFIG_EXT3_FS_SECURITY=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_EXT4_FS_XATTR=y +CONFIG_EXTRA_FIRMWARE="" +CONFIG_FAIR_GROUP_SCHED=y +CONFIG_FARSYNC=m +CONFIG_FAST_CMPXCHG_LOCAL=y +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=m +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_BOOT_VESA_SUPPORT=y +CONFIG_FB_CARILLO_RANCH=m +CONFIG_FB_CARMINE=m +CONFIG_FB_CARMINE_DRAM_EVAL=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_IMAGEBLIT=y +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set +CONFIG_FB_CIRRUS=m +CONFIG_FB_CYBER2000=m +CONFIG_FB_DDC=m +CONFIG_FB_DEFERRED_IO=y +CONFIG_FB_EFI=y +# CONFIG_FB_FOREIGN_ENDIAN is not set +CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m +CONFIG_FB_GEODE_GX1=m +CONFIG_FB_GEODE_LX=m +CONFIG_FB_HECUBA=m +CONFIG_FB_HGA=m +# CONFIG_FB_HGA_ACCEL is not set +CONFIG_FB_IMSTT=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_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_MB862XX=m +CONFIG_FB_MB862XX_PCI_GDC=y +CONFIG_FB_METRONOME=m +CONFIG_FB_MODE_HELPERS=y +CONFIG_FB_N411=m +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_UVESA=m +CONFIG_FB_VESA=m +CONFIG_FB_VGA16=m +CONFIG_FB_VIA=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_FILE_LOCKING=y +CONFIG_FIREWIRE=m +CONFIG_FIREWIRE_OHCI=m +CONFIG_FIREWIRE_OHCI_DEBUG=y +# CONFIG_FIREWIRE_OHCI_REMOTE_DMA is not set +CONFIG_FIREWIRE_SBP2=m +CONFIG_FIRMWARE_EDID=y +# CONFIG_FIRMWARE_IN_KERNEL is not set +CONFIG_FIRMWARE_MEMMAP=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +# CONFIG_FLATMEM_MANUAL is not set +# 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=m +# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set +# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set +CONFIG_FRAME_POINTER=y +CONFIG_FRAME_WARN=1024 +CONFIG_FREEZER=y +CONFIG_FSAM7400=m +CONFIG_FS_MBCACHE=y +CONFIG_FS_POSIX_ACL=y +CONFIG_FS_UNIONFS=m +CONFIG_FTL=m +# CONFIG_FTRACE_STARTUP_TEST is not set +CONFIG_FUJITSU_LAPTOP=m +# CONFIG_FUJITSU_LAPTOP_DEBUG is not set +# CONFIG_FUNCTION_TRACER is not set +CONFIG_FUSE_FS=m +CONFIG_FUSION=y +CONFIG_FUSION_CTL=m +CONFIG_FUSION_FC=m +CONFIG_FUSION_LAN=m +CONFIG_FUSION_LOGGING=y +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_GARP=m +CONFIG_GART_IOMMU=y +CONFIG_GENERIC_ACL=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_CPU=y +CONFIG_GENERIC_FIND_FIRST_BIT=y +CONFIG_GENERIC_FIND_NEXT_BIT=y +CONFIG_GENERIC_GPIO=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_GFS_FS=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_GPIOLIB=y +CONFIG_GPIO_MAX7301=m +CONFIG_GPIO_MAX732X=m +CONFIG_GPIO_MCP23S08=m +CONFIG_GPIO_PCA953X=m +CONFIG_GPIO_PCF857X=m +CONFIG_GPIO_SYSFS=y +CONFIG_GROUP_SCHED=y +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_AOUT is not set +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_CPUMASK_OF_CPU_MAP=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_TRACER=y +# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IOREMAP_PROT=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_KVM=y +CONFIG_HAVE_LATENCYTOP_SUPPORT=y +CONFIG_HAVE_MEMORY_PRESENT=y +CONFIG_HAVE_MTD_OTP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_SETUP_PER_CPU_AREA=y +CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=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_HECI=m +CONFIG_HERMES=m +CONFIG_HFSPLUS_FS=m +CONFIG_HFS_FS=m +CONFIG_HIBERNATION=y +CONFIG_HID=y +CONFIG_HIDRAW=y +CONFIG_HID_A4TECH=m +CONFIG_HID_APPLE=m +CONFIG_HID_BELKIN=m +CONFIG_HID_BRIGHT=m +CONFIG_HID_CHERRY=m +CONFIG_HID_CHICONY=m +# CONFIG_HID_COMPAT is not set +CONFIG_HID_CYPRESS=m +# CONFIG_HID_DEBUG is not set +CONFIG_HID_DELL=m +CONFIG_HID_EZKEY=m +CONFIG_HID_GYRATION=m +CONFIG_HID_LOGITECH=m +CONFIG_HID_MICROSOFT=m +CONFIG_HID_MONTEREY=m +CONFIG_HID_PANTHERLORD=m +CONFIG_HID_PETALYNX=m +CONFIG_HID_PID=y +CONFIG_HID_SAMSUNG=m +CONFIG_HID_SONY=m +CONFIG_HID_SUNPLUS=m +CONFIG_HID_SUPPORT=y +CONFIG_HIGH_RES_TIMERS=y +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=y +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=y +CONFIG_HOTPLUG_PCI_SHPC=m +CONFIG_HP100=m +CONFIG_HPET=y +CONFIG_HPET_EMULATE_RTC=y +CONFIG_HPET_MMAP=y +CONFIG_HPET_TIMER=y +CONFIG_HPFS_FS=m +CONFIG_HP_ILO=m +# CONFIG_HP_WATCHDOG is not set +CONFIG_HP_WMI=m +CONFIG_HTC_PASIC3=m +CONFIG_HT_IRQ=y +CONFIG_HUGETLBFS=y +CONFIG_HUGETLB_PAGE=y +CONFIG_HVC_DRIVER=y +CONFIG_HVC_IRQ=y +CONFIG_HVC_XEN=y +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_INTEL=m +CONFIG_HW_RANDOM_VIRTIO=m +CONFIG_HYSDN=m +CONFIG_HYSDN_CAPI=y +# CONFIG_HZ_1000 is not set +# CONFIG_HZ_300 is not set +CONFIG_I2C=y +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_GPIO=m +# CONFIG_I2C_HELPER_AUTO is not set +CONFIG_I2C_I801=m +CONFIG_I2C_ISCH=m +CONFIG_I2C_NFORCE2=m +CONFIG_I2C_NFORCE2_S4985=m +CONFIG_I2C_OCORES=m +CONFIG_I2C_PARPORT=m +CONFIG_I2C_PARPORT_LIGHT=m +CONFIG_I2C_PCA_PLATFORM=m +CONFIG_I2C_PIIX4=m +CONFIG_I2C_SIMTEC=m +CONFIG_I2C_SIS5595=m +CONFIG_I2C_SIS630=m +CONFIG_I2C_SIS96X=m +CONFIG_I2C_STUB=m +CONFIG_I2C_TAOS_EVM=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_I7300_IDLE=m +CONFIG_I7300_IDLE_IOAT_CHANNEL=y +CONFIG_I82092=m +CONFIG_I8K=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_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_RGMII is not set +# CONFIG_IBM_NEW_EMAC_TAH is not set +# CONFIG_IBM_NEW_EMAC_ZMII is not set +CONFIG_ICPLUS_PHY=m +CONFIG_ICS932S401=m +# CONFIG_IDE 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_IFB=m +CONFIG_IGB=m +CONFIG_IGB_DCA=y +# CONFIG_IGB_LRO 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_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_LRO=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_NES is not set +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_APANEL is not set +CONFIG_INPUT_ATI_REMOTE=m +CONFIG_INPUT_ATI_REMOTE2=m +CONFIG_INPUT_ATLAS_BTNS=m +CONFIG_INPUT_CM109=m +CONFIG_INPUT_EVBUG=m +CONFIG_INPUT_EVDEV=y +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_UINPUT=m +CONFIG_INPUT_YEALINK=m +CONFIG_INTEL_IOATDMA=m +CONFIG_INTEL_MENLOW=m +# CONFIG_INTR_REMAP is not set +# CONFIG_IOMMU_DEBUG is not set +CONFIG_IOMMU_HELPER=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_CFQ=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_NOOP=y +# CONFIG_IO_DELAY_0X80 is not set +CONFIG_IO_DELAY_0XED=y +# CONFIG_IO_DELAY_NONE is not set +CONFIG_IO_DELAY_TYPE_0X80=0 +CONFIG_IO_DELAY_TYPE_0XED=1 +CONFIG_IO_DELAY_TYPE_NONE=3 +CONFIG_IO_DELAY_TYPE_UDELAY=2 +# CONFIG_IO_DELAY_UDELAY is not set +CONFIG_IP1000=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_RT=m +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_RAW=m +CONFIG_IP6_NF_SECURITY=m +CONFIG_IP6_NF_TARGET_HL=m +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IPC_NS=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_IPPP_FILTER=y +CONFIG_IPV6=y +# CONFIG_IPV6_MIP6 is not set +# CONFIG_IPV6_MROUTE is not set +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_NDISC_NODETYPE=y +# CONFIG_IPV6_OPTIMISTIC_DAD is not set +CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set +CONFIG_IPV6_SIT=m +# CONFIG_IPV6_SUBTREES is not set +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_IPWIRELESS=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_TTL=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_SECURITY=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_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_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_IPV6=y +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_AH_ESP=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_IRQSOFF_TRACER is not set +CONFIG_IRTTY_SIR=m +CONFIG_ISA_DMA_API=y +CONFIG_ISCSI_IBFT=m +CONFIG_ISCSI_IBFT_FIND=y +CONFIG_ISCSI_TCP=m +CONFIG_ISDN=y +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_ISTALLION=m +CONFIG_IT8712F_WDT=m +CONFIG_IT87_WDT=m +CONFIG_ITCO_VENDOR_SUPPORT=y +CONFIG_ITCO_WDT=m +CONFIG_IWL3945=m +# CONFIG_IWL3945_DEBUG is not set +CONFIG_IWL3945_LEDS=y +CONFIG_IWL3945_RFKILL=y +CONFIG_IWL3945_SPECTRUM_MEASUREMENT=y +CONFIG_IWL4965=y +CONFIG_IWL5000=y +CONFIG_IWLAGN=m +CONFIG_IWLAGN_LEDS=y +CONFIG_IWLAGN_SPECTRUM_MEASUREMENT=y +CONFIG_IWLCORE=m +CONFIG_IWLWIFI=m +# CONFIG_IWLWIFI_DEBUG is not set +CONFIG_IWLWIFI_LEDS=y +CONFIG_IWLWIFI_RFKILL=y +CONFIG_IXGB=m +CONFIG_IXGBE=m +CONFIG_IXGBE_DCA=y +CONFIG_JBD=y +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set +# CONFIG_JBD_DEBUG is not set +CONFIG_JFFS2_CMODE_FAVOURLZO=y +# CONFIG_JFFS2_CMODE_NONE is not set +# CONFIG_JFFS2_CMODE_PRIORITY is not set +# CONFIG_JFFS2_CMODE_SIZE is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_FS=m +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_XATTR is not set +CONFIG_JFFS2_LZO=y +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_JME=m +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_JOYSTICK_XPAD_FF=y +CONFIG_JOYSTICK_XPAD_LEDS=y +CONFIG_JOYSTICK_ZHENHUA=m +CONFIG_K8_NB=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_GPIO=m +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_KGDB=y +CONFIG_KGDB_SERIAL_CONSOLE=y +# CONFIG_KGDB_TESTS is not set +CONFIG_KINGSUN_DONGLE=m +CONFIG_KMOD=y +CONFIG_KPROBES=y +# CONFIG_KPROBES_SANITY_TEST is not set +CONFIG_KRETPROBES=y +CONFIG_KS0108=m +CONFIG_KS0108_DELAY=2 +CONFIG_KS0108_PORT=0x378 +CONFIG_KS959_DONGLE=m +CONFIG_KSDAZZLE_DONGLE=m +# CONFIG_KTIME_SCALAR is not set +CONFIG_KVM=m +CONFIG_KVM_AMD=m +CONFIG_KVM_CLOCK=y +CONFIG_KVM_GUEST=y +CONFIG_KVM_INTEL=m +# CONFIG_KVM_TRACE is not set +CONFIG_LANMEDIA=m +CONFIG_LAPB=m +CONFIG_LAPBETHER=m +CONFIG_LATENCYTOP=y +CONFIG_LCD_CLASS_DEVICE=m +CONFIG_LCD_ILI9320=m +CONFIG_LCD_LTV350QV=m +CONFIG_LCD_PLATFORM=m +CONFIG_LCD_TDO24M=m +CONFIG_LCD_VGG2432A4=m +# CONFIG_LDM_DEBUG is not set +CONFIG_LDM_PARTITION=y +CONFIG_LEDS_CLASS=m +# CONFIG_LEDS_CLEVO_MAIL is not set +CONFIG_LEDS_DA903X=m +CONFIG_LEDS_GPIO=m +CONFIG_LEDS_HP_DISK=m +CONFIG_LEDS_PCA9532=m +CONFIG_LEDS_PCA955X=m +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_BACKLIGHT=m +CONFIG_LEDS_TRIGGER_DEFAULT_ON=m +CONFIG_LEDS_TRIGGER_HEARTBEAT=m +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=0 +CONFIG_LIBCRC32C=m +CONFIG_LIBERTAS=m +CONFIG_LIBERTAS_CS=m +# CONFIG_LIBERTAS_DEBUG is not set +CONFIG_LIBERTAS_SDIO=m +CONFIG_LIBERTAS_THINFIRM=m +CONFIG_LIBERTAS_THINFIRM_USB=m +CONFIG_LIBERTAS_USB=m +CONFIG_LIRC_ATIUSB=m +CONFIG_LIRC_BT829=m +CONFIG_LIRC_CMDIR=m +CONFIG_LIRC_DEV=m +# CONFIG_LIRC_GPIO is not set +CONFIG_LIRC_I2C=m +CONFIG_LIRC_IGORPLUGUSB=m +CONFIG_LIRC_IMON=m +CONFIG_LIRC_IT87=m +CONFIG_LIRC_MCEUSB=m +CONFIG_LIRC_MCEUSB2=m +# CONFIG_LIRC_PARALLEL is not set +CONFIG_LIRC_PVR150=m +CONFIG_LIRC_SASEM=m +CONFIG_LIRC_SERIAL=m +CONFIG_LIRC_SERIAL_IGOR=m +CONFIG_LIRC_SIR=m +CONFIG_LIRC_STREAMZAP=m +CONFIG_LIRC_TTUSBIR=m +CONFIG_LITELINK_DONGLE=m +# CONFIG_LKDTM is not set +CONFIG_LLC=y +CONFIG_LLC2=m +CONFIG_LMPCM_USB=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_LOCK_STAT is not set +CONFIG_LOGIRUMBLEPAD2_FF=y +CONFIG_LOGITECH_FF=y +# CONFIG_LOGO is not set +CONFIG_LOG_BUF_SHIFT=17 +# CONFIG_LP_CONSOLE is not set +CONFIG_LXT_PHY=m +CONFIG_LZO_COMPRESS=m +CONFIG_LZO_DECOMPRESS=m +CONFIG_M25PXX_USE_FAST_READ=y +# CONFIG_M386 is not set +# CONFIG_M486 is not set +# CONFIG_M586 is not set +# CONFIG_M586MMX is not set +# CONFIG_M586TSC is not set +# CONFIG_M686 is not set +CONFIG_MA600_DONGLE=m +CONFIG_MAC80211=m +CONFIG_MAC80211_DEBUGFS=y +# CONFIG_MAC80211_DEBUG_MENU is not set +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +CONFIG_MAC80211_MESH=y +CONFIG_MAC80211_RC_DEFAULT="pid" +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set +CONFIG_MAC80211_RC_DEFAULT_PID=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MAC80211_RC_PID=y +CONFIG_MACHZ_WDT=m +CONFIG_MACINTOSH_DRIVERS=y +CONFIG_MACVLAN=m +CONFIG_MAC_EMUMOUSEBTN=y +CONFIG_MAC_PARTITION=y +CONFIG_MAGIC_SYSRQ=y +CONFIG_MARKERS=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_MD=y +CONFIG_MDIO_BITBANG=m +CONFIG_MD_AUTODETECT=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_MEDIA_ATTACH=y +CONFIG_MEDIA_TUNER=m +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set +CONFIG_MEDIA_TUNER_MT2060=m +CONFIG_MEDIA_TUNER_MT20XX=m +CONFIG_MEDIA_TUNER_MT2131=m +CONFIG_MEDIA_TUNER_MT2266=m +CONFIG_MEDIA_TUNER_MXL5005S=m +CONFIG_MEDIA_TUNER_MXL5007T=m +CONFIG_MEDIA_TUNER_QT1010=m +CONFIG_MEDIA_TUNER_SIMPLE=m +CONFIG_MEDIA_TUNER_TDA18271=m +CONFIG_MEDIA_TUNER_TDA827X=m +CONFIG_MEDIA_TUNER_TDA8290=m +CONFIG_MEDIA_TUNER_TDA9887=m +CONFIG_MEDIA_TUNER_TEA5761=m +CONFIG_MEDIA_TUNER_TEA5767=m +CONFIG_MEDIA_TUNER_XC2028=m +CONFIG_MEDIA_TUNER_XC5000=m +# CONFIG_MEFFICEON is not set +CONFIG_MEGARAID_LEGACY=m +CONFIG_MEGARAID_MAILBOX=m +CONFIG_MEGARAID_MM=m +CONFIG_MEGARAID_NEWGEN=y +CONFIG_MEGARAID_SAS=m +# CONFIG_MEMSTICK is not set +# CONFIG_MEMTEST is not set +# CONFIG_MFD_CORE is not set +CONFIG_MFD_SM501=m +# CONFIG_MFD_SM501_GPIO is not set +# CONFIG_MFD_TMIO is not set +CONFIG_MFD_WM8350=m +CONFIG_MFD_WM8350_I2C=m +CONFIG_MFD_WM8400=m +# CONFIG_MGEODEGX1 is not set +# CONFIG_MGEODE_LX is not set +CONFIG_MICROCODE=m +CONFIG_MICROCODE_AMD=y +CONFIG_MICROCODE_INTEL=y +CONFIG_MICROCODE_OLD_INTERFACE=y +CONFIG_MII=m +CONFIG_MINIX_FS=m +CONFIG_MINIX_SUBPARTITION=y +CONFIG_MISC_DEVICES=y +CONFIG_MISDN=m +CONFIG_MISDN_DSP=m +CONFIG_MISDN_HFCMULTI=m +CONFIG_MISDN_HFCPCI=m +CONFIG_MISDN_L1OIP=m +# CONFIG_MK6 is not set +# CONFIG_MK7 is not set +# CONFIG_MK8 is not set +CONFIG_MKISS=m +CONFIG_MLX4_CORE=m +CONFIG_MLX4_DEBUG=y +CONFIG_MLX4_EN=m +CONFIG_MLX4_INFINIBAND=m +CONFIG_MMC=y +CONFIG_MMC_BLOCK=m +CONFIG_MMC_BLOCK_BOUNCE=y +# CONFIG_MMC_DEBUG is not set +CONFIG_MMC_RICOH_MMC=m +CONFIG_MMC_SDHCI=m +CONFIG_MMC_SDHCI_PCI=m +CONFIG_MMC_SDRICOH_CS=m +CONFIG_MMC_SPI=m +# CONFIG_MMC_TEST is not set +CONFIG_MMC_TIFM_SD=m +# CONFIG_MMC_UNSAFE_RESUME is not set +CONFIG_MMC_WBSD=m +# CONFIG_MMIOTRACE is not set +CONFIG_MMU=y +CONFIG_MMU_NOTIFIER=y +CONFIG_MM_OWNER=y +CONFIG_MODULES=y +# CONFIG_MODULE_FORCE_LOAD is not set +# 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_BCM5974=m +CONFIG_MOUSE_GPIO=m +CONFIG_MOUSE_PS2=m +CONFIG_MOUSE_PS2_ALPS=y +CONFIG_MOUSE_PS2_ELANTECH=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=m +# CONFIG_MPENTIUM4 is not set +# CONFIG_MPENTIUMII is not set +# CONFIG_MPENTIUMIII is not set +# CONFIG_MPENTIUMM is not set +# CONFIG_MPSC is not set +CONFIG_MSDOS_FS=m +CONFIG_MSDOS_PARTITION=y +CONFIG_MSI_LAPTOP=m +CONFIG_MT9M001_PCA9536_SWITCH=y +CONFIG_MT9V022_PCA9536_SWITCH=y +CONFIG_MTD=m +CONFIG_MTDRAM_ERASE_SIZE=128 +CONFIG_MTDRAM_TOTAL_SIZE=4096 +CONFIG_MTD_ABSENT=m +CONFIG_MTD_ALAUDA=m +CONFIG_MTD_AMD76XROM=m +CONFIG_MTD_AR7_PARTS=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_DATAFLASH_OTP=y +# CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set +# 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_INTEL_VR_NOR=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_2X_PROGRAM=y +# CONFIG_MTD_ONENAND_OTP is not set +CONFIG_MTD_ONENAND_SIM=m +CONFIG_MTD_ONENAND_VERIFY_WRITE=y +CONFIG_MTD_OOPS=m +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_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_MTRR_SANITIZER=y +CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=0 +CONFIG_MTRR_SANITIZER_SPARE_REG_NR_DEFAULT=1 +# CONFIG_MVIAC3_2 is not set +# CONFIG_MVIAC7 is not set +CONFIG_MWAVE=m +# CONFIG_MWINCHIP3D is not set +# CONFIG_MWINCHIPC6 is not set +CONFIG_MYRI10GE=m +CONFIG_MYRI10GE_DCA=y +CONFIG_NAMESPACES=y +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_NDISWRAPPER=m +CONFIG_NE2K_PCI=m +CONFIG_NET=y +CONFIG_NETCONSOLE=m +CONFIG_NETCONSOLE_DYNAMIC=y +CONFIG_NETDEVICES=y +CONFIG_NETDEV_1000=y +CONFIG_NETDEV_10000=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_TPROXY=m +CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=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_IPRANGE=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_OWNER=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_RATEEST=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_RECENT=m +# CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT is not set +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_SOCKET=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_TIME=m +CONFIG_NETFILTER_XT_MATCH_U32=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_RATEEST=m +CONFIG_NETFILTER_XT_TARGET_SECMARK=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set +CONFIG_NETFILTER_XT_TARGET_TPROXY=m +CONFIG_NETFILTER_XT_TARGET_TRACE=m +CONFIG_NETLABEL=y +CONFIG_NETPOLL=y +# CONFIG_NETPOLL_TRAP is not set +CONFIG_NETROM=m +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NETWORK_SECMARK=y +CONFIG_NETXEN_NIC=m +CONFIG_NET_9P=m +# CONFIG_NET_9P_DEBUG is not set +CONFIG_NET_9P_RDMA=m +CONFIG_NET_9P_VIRTIO=m +CONFIG_NET_ACT_GACT=m +CONFIG_NET_ACT_IPT=m +CONFIG_NET_ACT_MIRRED=m +CONFIG_NET_ACT_NAT=m +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_SIMP=m +CONFIG_NET_ACT_SKBEDIT=m +CONFIG_NET_CLS=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_BASIC=m +# CONFIG_NET_CLS_FLOW is not set +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_DSA=y +CONFIG_NET_DSA_MV88E6060=y +CONFIG_NET_DSA_MV88E6123_61_65=y +CONFIG_NET_DSA_MV88E6131=y +CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y +CONFIG_NET_DSA_TAG_DSA=y +CONFIG_NET_DSA_TAG_EDSA=y +CONFIG_NET_DSA_TAG_TRAILER=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_ET131X=m +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_MULTIQ=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_V2_ACL=y +CONFIG_NFSD_V3=y +CONFIG_NFSD_V3_ACL=y +CONFIG_NFSD_V4=y +CONFIG_NFS_ACL_SUPPORT=m +CONFIG_NFS_COMMON=y +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFTL=m +CONFIG_NFTL_RW=y +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_AMANDA=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_DCCP is not set +CONFIG_NF_CT_PROTO_GRE=m +CONFIG_NF_CT_PROTO_SCTP=m +CONFIG_NF_CT_PROTO_UDPLITE=m +CONFIG_NF_DEFRAG_IPV4=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_PROTO_SCTP=m +CONFIG_NF_NAT_PROTO_UDPLITE=m +CONFIG_NF_NAT_SIP=m +CONFIG_NF_NAT_SNMP_BASIC=m +CONFIG_NF_NAT_TFTP=m +CONFIG_NIU=m +CONFIG_NL80211=y +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_NOP_TRACER=y +CONFIG_NORTEL_HERMES=m +CONFIG_NOZOMI=m +CONFIG_NO_HZ=y +CONFIG_NR_CPUS=64 +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 is not set +CONFIG_NVRAM=m +CONFIG_N_HDLC=m +# CONFIG_OCFS2_COMPAT_JBD is not set +# CONFIG_OCFS2_DEBUG_FS is not set +CONFIG_OCFS2_DEBUG_MASKLOG=y +CONFIG_OCFS2_FS=m +CONFIG_OCFS2_FS_O2CB=m +CONFIG_OCFS2_FS_STATS=y +CONFIG_OCFS2_FS_USERSPACE_CLUSTER=m +CONFIG_OLD_BELKIN_DONGLE=m +CONFIG_OMFS_FS=m +CONFIG_OPROFILE=m +CONFIG_OPROFILE_IBS=y +CONFIG_OPTIMIZE_INLINING=y +CONFIG_OSF_PARTITION=y +CONFIG_P54_COMMON=m +CONFIG_P54_PCI=m +CONFIG_P54_USB=m +CONFIG_P80211=m +CONFIG_PACKARDBELL_E5=m +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PANASONIC_LAPTOP=m +CONFIG_PANTHERLORD_FF=y +CONFIG_PARAVIRT=y +CONFIG_PARAVIRT_CLOCK=y +# CONFIG_PARAVIRT_DEBUG is not set +CONFIG_PARAVIRT_GUEST=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_ACPI=y +CONFIG_PATA_ALI=y +CONFIG_PATA_AMD=y +CONFIG_PATA_ARTOP=y +CONFIG_PATA_ATIIXP=y +CONFIG_PATA_CMD640_PCI=m +CONFIG_PATA_CMD64X=y +CONFIG_PATA_CS5520=y +CONFIG_PATA_CS5530=y +CONFIG_PATA_CYPRESS=m +CONFIG_PATA_EFAR=y +CONFIG_PATA_HPT366=y +CONFIG_PATA_HPT37X=y +CONFIG_PATA_HPT3X2N=m +CONFIG_PATA_HPT3X3=y +# CONFIG_PATA_HPT3X3_DMA is not set +CONFIG_PATA_IT8213=m +CONFIG_PATA_IT821X=y +CONFIG_PATA_JMICRON=y +CONFIG_PATA_MARVELL=y +CONFIG_PATA_MPIIX=y +CONFIG_PATA_NETCELL=y +CONFIG_PATA_NINJA32=m +CONFIG_PATA_NS87410=y +CONFIG_PATA_NS87415=y +CONFIG_PATA_OLDPIIX=y +CONFIG_PATA_OPTI=m +CONFIG_PATA_OPTIDMA=m +CONFIG_PATA_PCMCIA=m +CONFIG_PATA_PDC2027X=y +CONFIG_PATA_PDC_OLD=y +CONFIG_PATA_RADISYS=m +CONFIG_PATA_RZ1000=y +CONFIG_PATA_SC1200=y +CONFIG_PATA_SCH=y +CONFIG_PATA_SERVERWORKS=y +CONFIG_PATA_SIL680=y +CONFIG_PATA_SIS=y +CONFIG_PATA_TRIFLEX=y +CONFIG_PATA_VIA=y +CONFIG_PATA_WINBOND=y +# CONFIG_PC300TOO is not set +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_PCIEASPM is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCIPCWATCHDOG=m +CONFIG_PCI_ATMEL=m +# CONFIG_PCI_DEBUG is not set +CONFIG_PCI_DIRECT=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_HERMES=m +CONFIG_PCI_LEGACY=y +CONFIG_PCI_MMCONFIG=y +CONFIG_PCI_MSI=y +CONFIG_PCI_QUIRKS=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_IBMTR=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_PCSPKR_PLATFORM=y +CONFIG_PD6729=m +CONFIG_PDA_POWER=m +CONFIG_PDC_ADMA=y +CONFIG_PHANTOM=m +CONFIG_PHONE=m +CONFIG_PHONET=m +CONFIG_PHONE_IXJ=m +CONFIG_PHONE_IXJ_PCMCIA=m +CONFIG_PHYLIB=y +CONFIG_PHYSICAL_ALIGN=0x200000 +CONFIG_PHYSICAL_START=0x200000 +CONFIG_PHYS_ADDR_T_64BIT=y +# CONFIG_PID_NS is not set +CONFIG_PLIP=m +CONFIG_PLIST=y +CONFIG_PLX_HERMES=m +CONFIG_PM=y +CONFIG_PMIC_DA903X=y +CONFIG_PM_DEBUG=y +CONFIG_PM_DISABLE_CONSOLE=y +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +CONFIG_PM_STD_PARTITION="" +CONFIG_PM_TEST_SUSPEND=y +CONFIG_PM_TRACE=y +CONFIG_PM_TRACE_RTC=y +# CONFIG_PM_VERBOSE is not set +CONFIG_PNP=y +CONFIG_PNPACPI=y +CONFIG_PNP_DEBUG_MESSAGES=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POWER_SUPPLY=y +# CONFIG_POWER_SUPPLY_DEBUG is not set +CONFIG_PPDEV=m +CONFIG_PPP=y +CONFIG_PPPOATM=m +CONFIG_PPPOE=m +CONFIG_PPPOL2TP=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_NOTIFIERS=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_PRINTER=m +CONFIG_PRINTK=y +CONFIG_PRINTK_TIME=y +CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_PRISM2_USB=m +CONFIG_PRISM54=m +CONFIG_PROC_EVENTS=y +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_PROC_PAGE_MONITOR=y +CONFIG_PROC_PID_CPUSET=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_VMCORE=y +CONFIG_PROFILING=y +# CONFIG_PROVE_LOCKING is not set +# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set +# CONFIG_PSS_HAVE_BOOT is not set +CONFIG_PSS_MIXER=y +CONFIG_QC_USB=m +CONFIG_QFMT_V1=m +CONFIG_QFMT_V2=m +CONFIG_QLA3XXX=m +CONFIG_QLGE=m +CONFIG_QNX4FS_FS=m +CONFIG_QSEMI_PHY=m +CONFIG_QUOTA=y +CONFIG_QUOTACTL=y +CONFIG_QUOTA_NETLINK_INTERFACE=y +CONFIG_R3964=m +# CONFIG_R6040 is not set +CONFIG_R8169=m +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_RAW_DRIVER=m +# CONFIG_RCU_CPU_STALL_DETECTOR is not set +# CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_REALTEK_PHY is not set +CONFIG_REED_SOLOMON=m +CONFIG_REED_SOLOMON_DEC16=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_BQ24022=m +CONFIG_REGULATOR_DA903X=m +# CONFIG_REGULATOR_DEBUG is not set +# CONFIG_REGULATOR_FIXED_VOLTAGE is not set +CONFIG_REGULATOR_VIRTUAL_CONSUMER=m +CONFIG_REGULATOR_WM8350=m +CONFIG_REGULATOR_WM8400=m +# 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_RESOURCE_COUNTERS=y +CONFIG_RFD_FTL=m +CONFIG_RFKILL=y +CONFIG_RFKILL_INPUT=m +CONFIG_RFKILL_LEDS=y +CONFIG_RING_BUFFER=y +CONFIG_RIO=m +# CONFIG_RIO_OLDPCI is not set +CONFIG_RISCOM8=m +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_RT2400PCI=m +CONFIG_RT2500PCI=m +CONFIG_RT2500USB=m +CONFIG_RT2X00=m +# CONFIG_RT2X00_DEBUG is not set +CONFIG_RT2X00_LIB=m +CONFIG_RT2X00_LIB_CRYPTO=y +# CONFIG_RT2X00_LIB_DEBUGFS is not set +CONFIG_RT2X00_LIB_FIRMWARE=y +CONFIG_RT2X00_LIB_LEDS=y +CONFIG_RT2X00_LIB_PCI=m +CONFIG_RT2X00_LIB_RFKILL=y +CONFIG_RT2X00_LIB_USB=m +CONFIG_RT61PCI=m +CONFIG_RT73USB=m +CONFIG_RTC_CLASS=y +# CONFIG_RTC_DEBUG is not set +CONFIG_RTC_DRV_BQ4802=m +CONFIG_RTC_DRV_CMOS=y +CONFIG_RTC_DRV_DS1286=m +CONFIG_RTC_DRV_DS1305=m +CONFIG_RTC_DRV_DS1307=m +CONFIG_RTC_DRV_DS1374=m +CONFIG_RTC_DRV_DS1390=m +# CONFIG_RTC_DRV_DS1511 is not set +CONFIG_RTC_DRV_DS1553=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_DS1742=m +CONFIG_RTC_DRV_DS3234=m +CONFIG_RTC_DRV_FM3130=m +CONFIG_RTC_DRV_ISL1208=m +CONFIG_RTC_DRV_M41T80=m +CONFIG_RTC_DRV_M41T80_WDT=y +CONFIG_RTC_DRV_M41T94=m +CONFIG_RTC_DRV_M48T35=m +CONFIG_RTC_DRV_M48T59=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_R9701 is not set +CONFIG_RTC_DRV_RS5C348=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_RX8581=m +# CONFIG_RTC_DRV_S35390A is not set +CONFIG_RTC_DRV_STK17TA8=m +CONFIG_RTC_DRV_TEST=m +CONFIG_RTC_DRV_V3020=m +CONFIG_RTC_DRV_WM8350=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_RTL8180=m +CONFIG_RTL8187=m +CONFIG_RT_GROUP_SCHED=y +CONFIG_RT_MUTEXES=y +# CONFIG_RT_MUTEX_TESTER is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_RXKAD=m +CONFIG_S2IO=m +# CONFIG_SAMPLES is not set +CONFIG_SATA_AHCI=y +CONFIG_SATA_INIC162X=y +CONFIG_SATA_MV=m +CONFIG_SATA_NV=y +CONFIG_SATA_PMP=y +CONFIG_SATA_PROMISE=y +CONFIG_SATA_QSTOR=y +CONFIG_SATA_SIL=y +CONFIG_SATA_SIL24=y +CONFIG_SATA_SIS=y +CONFIG_SATA_SVW=y +CONFIG_SATA_SX4=y +CONFIG_SATA_ULI=y +CONFIG_SATA_VIA=y +CONFIG_SATA_VITESSE=y +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=0 +CONFIG_SC6600_JOY=y +CONFIG_SC92031=m +CONFIG_SCHEDSTATS=y +CONFIG_SCHED_DEBUG=y +CONFIG_SCHED_HRTICK=y +CONFIG_SCHED_MC=y +CONFIG_SCHED_SMT=y +# CONFIG_SCHED_TRACER is not set +CONFIG_SCSI=y +CONFIG_SCSI_3W_9XXX=m +CONFIG_SCSI_AACRAID=m +CONFIG_SCSI_ACARD=m +CONFIG_SCSI_ADVANSYS=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_ARCMSR_AER=y +CONFIG_SCSI_BUSLOGIC=m +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_DC390T=m +CONFIG_SCSI_DC395x=m +CONFIG_SCSI_DEBUG=m +CONFIG_SCSI_DH=y +CONFIG_SCSI_DH_ALUA=m +CONFIG_SCSI_DH_EMC=m +CONFIG_SCSI_DH_HP_SW=m +CONFIG_SCSI_DH_RDAC=m +CONFIG_SCSI_DMA=y +CONFIG_SCSI_DMX3191D=m +CONFIG_SCSI_DPT_I2O=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_ENCLOSURE=m +CONFIG_SCSI_FC_ATTRS=m +CONFIG_SCSI_FC_TGT_ATTRS=y +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_ISCSITARGET=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_LOWLEVEL=y +CONFIG_SCSI_LOWLEVEL_PCMCIA=y +CONFIG_SCSI_LPFC=m +CONFIG_SCSI_MULTI_LUN=y +# CONFIG_SCSI_MVSAS is not set +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_ATA=y +CONFIG_SCSI_SAS_ATTRS=m +CONFIG_SCSI_SAS_HOST_SMP=y +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_SRP_ATTRS=m +CONFIG_SCSI_SRP_TGT_ATTRS=y +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_SDIO_UART=m +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITYFS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1 +CONFIG_SECURITY_APPARMOR_DISABLE=y +CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0 +CONFIG_SECURITY_FILE_CAPABILITIES=y +CONFIG_SECURITY_NETWORK=y +# CONFIG_SECURITY_NETWORK_XFRM is not set +# CONFIG_SECURITY_ROOTPLUG is not set +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_SECURITY_SMACK=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_SENSORS_ABITUGURU=m +CONFIG_SENSORS_ABITUGURU3=m +CONFIG_SENSORS_AD7414=m +CONFIG_SENSORS_AD7418=m +CONFIG_SENSORS_ADCXX=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_ADS7828=m +CONFIG_SENSORS_ADT7462=m +CONFIG_SENSORS_ADT7470=m +CONFIG_SENSORS_ADT7473=m +CONFIG_SENSORS_APPLESMC=m +CONFIG_SENSORS_ASB100=m +CONFIG_SENSORS_ATXP1=m +CONFIG_SENSORS_CORETEMP=m +CONFIG_SENSORS_DME1737=m +CONFIG_SENSORS_DS1621=m +CONFIG_SENSORS_EEPROM=m +CONFIG_SENSORS_F71805F=m +CONFIG_SENSORS_F71882FG=m +CONFIG_SENSORS_F75375S=m +CONFIG_SENSORS_FSCHER=m +CONFIG_SENSORS_FSCHMD=m +CONFIG_SENSORS_FSCPOS=m +CONFIG_SENSORS_GL518SM=m +CONFIG_SENSORS_GL520SM=m +CONFIG_SENSORS_HDAPS=m +CONFIG_SENSORS_I5K_AMB=m +CONFIG_SENSORS_IBMAEM=m +CONFIG_SENSORS_IBMPEX=m +CONFIG_SENSORS_IT87=m +CONFIG_SENSORS_K8TEMP=m +CONFIG_SENSORS_LIS3LV02D=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_LM93=m +CONFIG_SENSORS_MAX1111=m +CONFIG_SENSORS_MAX1619=m +CONFIG_SENSORS_MAX6650=m +CONFIG_SENSORS_MAX6875=m +CONFIG_SENSORS_PC87360=m +CONFIG_SENSORS_PC87427=m +CONFIG_SENSORS_PCF8591=m +CONFIG_SENSORS_SIS5595=m +CONFIG_SENSORS_SMSC47B397=m +CONFIG_SENSORS_SMSC47M1=m +CONFIG_SENSORS_SMSC47M192=m +CONFIG_SENSORS_THMC50=m +CONFIG_SENSORS_TSL2550=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_SENSORS_W83L786NG=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_SFC=m +CONFIG_SGI_GRU=m +# CONFIG_SGI_GRU_DEBUG is not set +CONFIG_SGI_IOC4=m +CONFIG_SGI_PARTITION=y +CONFIG_SGI_XP=m +CONFIG_SHMEM=y +CONFIG_SIGMATEL_FIR=m +CONFIG_SIGNALFD=y +CONFIG_SIS190=m +CONFIG_SIS900=m +CONFIG_SKFP=m +CONFIG_SKGE=m +# CONFIG_SKGE_DEBUG is not set +CONFIG_SKY2=m +# CONFIG_SKY2_DEBUG is not set +# CONFIG_SLAB is not set +CONFIG_SLABINFO=y +CONFIG_SLHC=y +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_SLUB_DEBUG_ON is not set +# CONFIG_SLUB_STATS 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=m +CONFIG_SMSC_PHY=m +CONFIG_SND=m +CONFIG_SND_AC97_CODEC=m +CONFIG_SND_AC97_POWER_SAVE=y +CONFIG_SND_AC97_POWER_SAVE_DEFAULT=0 +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_AW2=m +CONFIG_SND_AZT3328=m +CONFIG_SND_BT87X=m +# CONFIG_SND_BT87X_OVERCLOCK is not set +CONFIG_SND_BTSCO=m +CONFIG_SND_CA0106=m +CONFIG_SND_CMIPCI=m +CONFIG_SND_CS4281=m +CONFIG_SND_CS46XX=m +CONFIG_SND_CS46XX_NEW_DSP=y +CONFIG_SND_CS5530=m +CONFIG_SND_DARLA20=m +CONFIG_SND_DARLA24=m +# CONFIG_SND_DEBUG is not set +CONFIG_SND_DRIVERS=y +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_CODEC_ANALOG=y +CONFIG_SND_HDA_CODEC_ATIHDMI=y +CONFIG_SND_HDA_CODEC_CMEDIA=y +CONFIG_SND_HDA_CODEC_CONEXANT=y +CONFIG_SND_HDA_CODEC_NVHDMI=y +CONFIG_SND_HDA_CODEC_REALTEK=y +CONFIG_SND_HDA_CODEC_SI3054=y +CONFIG_SND_HDA_CODEC_SIGMATEL=y +CONFIG_SND_HDA_CODEC_VIA=y +CONFIG_SND_HDA_GENERIC=y +# CONFIG_SND_HDA_HWDEP is not set +CONFIG_SND_HDA_INPUT_BEEP=y +CONFIG_SND_HDA_INTEL=m +CONFIG_SND_HDA_POWER_SAVE=y +CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0 +CONFIG_SND_HDSP=m +CONFIG_SND_HDSPM=m +CONFIG_SND_HIFIER=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_LAYLA20=m +CONFIG_SND_LAYLA24=m +CONFIG_SND_MAESTRO3=m +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_OXYGEN=m +CONFIG_SND_OXYGEN_LIB=m +CONFIG_SND_PCI=y +CONFIG_SND_PCM=m +CONFIG_SND_PCMCIA=y +CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y +CONFIG_SND_PCSP=m +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_SB16_DSP=m +CONFIG_SND_SB_COMMON=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_SOC_AD73311=m +CONFIG_SND_SOC_AK4535=m +CONFIG_SND_SOC_ALL_CODECS=m +CONFIG_SND_SOC_CS4270=m +CONFIG_SND_SOC_SSM2602=m +CONFIG_SND_SOC_TLV320AIC23=m +CONFIG_SND_SOC_TLV320AIC26=m +CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_UDA1380=m +CONFIG_SND_SOC_WM8510=m +CONFIG_SND_SOC_WM8580=m +CONFIG_SND_SOC_WM8731=m +CONFIG_SND_SOC_WM8750=m +CONFIG_SND_SOC_WM8753=m +CONFIG_SND_SOC_WM8900=m +CONFIG_SND_SOC_WM8903=m +CONFIG_SND_SOC_WM8971=m +CONFIG_SND_SOC_WM8990=m +CONFIG_SND_SONICVIBES=m +CONFIG_SND_SPI=y +CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_TIMER=m +CONFIG_SND_TRIDENT=m +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=m +CONFIG_SND_USB_CAIAQ=m +CONFIG_SND_USB_CAIAQ_INPUT=y +CONFIG_SND_USB_US122L=m +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_VIRTUOSO=m +CONFIG_SND_VMASTER=y +CONFIG_SND_VX222=m +CONFIG_SND_VXPOCKET=m +CONFIG_SND_VX_LIB=m +CONFIG_SND_YMFPCI=m +CONFIG_SOC_CAMERA=m +CONFIG_SOC_CAMERA_MT9M001=m +CONFIG_SOC_CAMERA_MT9M111=m +CONFIG_SOC_CAMERA_MT9V022=m +CONFIG_SOC_CAMERA_PLATFORM=m +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=y +CONFIG_SOUND_KAHLUA=m +CONFIG_SOUND_MPU401=m +CONFIG_SOUND_MSS=m +CONFIG_SOUND_OSS=m +CONFIG_SOUND_OSS_CORE=y +CONFIG_SOUND_PAS=m +CONFIG_SOUND_PRIME=m +CONFIG_SOUND_PSS=m +CONFIG_SOUND_SB=m +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=y +CONFIG_SPARSEMEM_EXTREME=y +CONFIG_SPARSEMEM_MANUAL=y +CONFIG_SPARSEMEM_VMEMMAP=y +CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y +CONFIG_SPECIALIX=m +CONFIG_SPI=y +CONFIG_SPI_AT25=m +CONFIG_SPI_BITBANG=m +CONFIG_SPI_BUTTERFLY=m +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_LM70_LLP=m +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=m +CONFIG_SPI_TLE62X0=m +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SQUASHFS=m +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +CONFIG_SSB=m +CONFIG_SSB_B43_PCI_BRIDGE=y +# CONFIG_SSB_DEBUG is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +# CONFIG_SSB_PCMCIAHOST is not set +CONFIG_SSB_PCMCIAHOST_POSSIBLE=y +CONFIG_SSB_POSSIBLE=y +CONFIG_SSB_SPROM=y +CONFIG_SSFDC=m +CONFIG_STACKTRACE=y +CONFIG_STACKTRACE_SUPPORT=y +# CONFIG_STACK_TRACER is not set +# CONFIG_STAGING is not set +CONFIG_STALDRV=y +CONFIG_STALLION=m +# CONFIG_STANDALONE is not set +CONFIG_STOP_MACHINE=y +CONFIG_STP=m +CONFIG_STRICT_DEVMEM=y +CONFIG_STRIP=m +CONFIG_SUNDANCE=m +# CONFIG_SUNDANCE_MMIO is not set +CONFIG_SUNGEM=m +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +# CONFIG_SUNRPC_REGISTER_V4 is not set +CONFIG_SUNRPC_XPRT_RDMA=m +CONFIG_SUN_PARTITION=y +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=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_SYSCTL_SYSCALL_CHECK=y +CONFIG_SYSFS=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set +# CONFIG_SYSPROF_TRACER is not set +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=y +# CONFIG_TASK_DELAY_ACCT is not set +CONFIG_TASK_IO_ACCOUNTING=y +CONFIG_TASK_XACCT=y +CONFIG_TCG_ATMEL=m +CONFIG_TCG_INFINEON=m +CONFIG_TCG_NSC=m +CONFIG_TCG_TIS=m +CONFIG_TCG_TPM=m +CONFIG_TCP_CONG_ADVANCED=y +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=y +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_ILLINOIS=m +CONFIG_TCP_CONG_LP=m +CONFIG_TCP_CONG_SCALABLE=m +CONFIG_TCP_CONG_VEGAS=m +CONFIG_TCP_CONG_VENO=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_YEAH=m +CONFIG_TCP_MD5SIG=y +CONFIG_TEHUTI=m +CONFIG_TEKRAM_DONGLE=m +CONFIG_TELCLOCK=m +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m +CONFIG_TEXTSEARCH_KMP=m +CONFIG_THERMAL=y +CONFIG_THERMAL_HWMON=y +CONFIG_THINKPAD_ACPI=m +CONFIG_THINKPAD_ACPI_BAY=y +# CONFIG_THINKPAD_ACPI_DEBUG is not set +CONFIG_THINKPAD_ACPI_HOTKEY_POLL=y +CONFIG_THINKPAD_ACPI_VIDEO=y +CONFIG_THRUSTMASTER_FF=m +CONFIG_TICK_ONESHOT=y +CONFIG_TIFM_7XX1=m +CONFIG_TIFM_CORE=m +CONFIG_TIGON3=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_TLAN=m +CONFIG_TLSF=m +# CONFIG_TLSF_DEBUG is not set +# CONFIG_TLSF_STATS is not set +CONFIG_TLSUP=m +CONFIG_TMD_HERMES=m +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +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_INEXIO=m +CONFIG_TOUCHSCREEN_MK712=m +CONFIG_TOUCHSCREEN_MTOUCH=m +CONFIG_TOUCHSCREEN_PENMOUNT=m +CONFIG_TOUCHSCREEN_TOUCHIT213=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_GENERAL_TOUCH=y +CONFIG_TOUCHSCREEN_USB_GOTOP=y +CONFIG_TOUCHSCREEN_USB_GUNZE=y +CONFIG_TOUCHSCREEN_USB_IDEALTEK=y +CONFIG_TOUCHSCREEN_USB_IRTOUCH=y +CONFIG_TOUCHSCREEN_USB_ITM=y +CONFIG_TOUCHSCREEN_USB_PANJIT=y +CONFIG_TOUCHSCREEN_WM9705=y +CONFIG_TOUCHSCREEN_WM9712=y +CONFIG_TOUCHSCREEN_WM9713=y +CONFIG_TOUCHSCREEN_WM97XX=m +CONFIG_TPS65010=m +CONFIG_TP_SMAPI=m +CONFIG_TP_SMAPI_EC=m +CONFIG_TR=y +CONFIG_TRACEPOINTS=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_TRACING=y +CONFIG_TTPCI_EEPROM=m +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_TYPHOON=m +CONFIG_UBIFS_FS=m +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +# CONFIG_UBIFS_FS_DEBUG is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_XATTR=y +CONFIG_UBIFS_FS_ZLIB=y +CONFIG_UCB1400_CORE=m +CONFIG_UDF_FS=m +CONFIG_UDF_NLS=y +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" +# CONFIG_UFS_DEBUG is not set +CONFIG_UFS_FS=m +# CONFIG_UFS_FS_WRITE is not set +CONFIG_UID16=y +CONFIG_UIO=m +CONFIG_UIO_CIF=m +CONFIG_UIO_PDRV=m +CONFIG_UIO_PDRV_GENIRQ=m +CONFIG_UIO_SERCOS3=m +CONFIG_UIO_SMX=m +CONFIG_ULI526X=m +CONFIG_ULTRIX_PARTITION=y +CONFIG_UNEVICTABLE_LRU=y +CONFIG_UNIX=y +CONFIG_UNIX98_PTYS=y +CONFIG_UNIXWARE_DISKLABEL=y +CONFIG_UNUSED_SYMBOLS=y +CONFIG_USB=y +CONFIG_USBPCWATCHDOG=m +CONFIG_USB_ACM=m +CONFIG_USB_ADUTUX=m +CONFIG_USB_ALI_M5632=y +CONFIG_USB_AN2720=y +# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set +CONFIG_USB_APPLEDISPLAY=m +CONFIG_USB_APPLEIR=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_BELKIN=y +CONFIG_USB_BERRY_CHARGE=m +CONFIG_USB_C67X00_HCD=m +CONFIG_USB_CATC=m +CONFIG_USB_CDC_COMPOSITE=m +CONFIG_USB_CXACRU=m +CONFIG_USB_CYPRESS_CY7C63=m +CONFIG_USB_CYTHERM=m +# CONFIG_USB_DEBUG is not set +CONFIG_USB_DEVICEFS=y +# CONFIG_USB_DEVICE_CLASS is not set +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_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_AMD5536UDC is not set +# CONFIG_USB_GADGET_AT91 is not set +# CONFIG_USB_GADGET_ATMEL_USBA is not set +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_DUALSPEED=y +# CONFIG_USB_GADGET_DUMMY_HCD is not set +# CONFIG_USB_GADGET_FSL_QE 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_M66592 is not set +# CONFIG_USB_GADGET_MUSB_HDRC is not set +CONFIG_USB_GADGET_NET2280=y +# CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_PXA25X is not set +# CONFIG_USB_GADGET_PXA27X is not set +# CONFIG_USB_GADGET_S3C2410 is not set +CONFIG_USB_GADGET_SELECTED=y +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GSPCA=m +CONFIG_USB_GSPCA_CONEX=m +CONFIG_USB_GSPCA_ETOMS=m +CONFIG_USB_GSPCA_FINEPIX=m +CONFIG_USB_GSPCA_MARS=m +CONFIG_USB_GSPCA_OV519=m +CONFIG_USB_GSPCA_PAC207=m +CONFIG_USB_GSPCA_PAC7311=m +CONFIG_USB_GSPCA_SONIXB=m +CONFIG_USB_GSPCA_SONIXJ=m +CONFIG_USB_GSPCA_SPCA500=m +CONFIG_USB_GSPCA_SPCA501=m +CONFIG_USB_GSPCA_SPCA505=m +CONFIG_USB_GSPCA_SPCA506=m +CONFIG_USB_GSPCA_SPCA508=m +CONFIG_USB_GSPCA_SPCA561=m +CONFIG_USB_GSPCA_STK014=m +CONFIG_USB_GSPCA_SUNPLUS=m +CONFIG_USB_GSPCA_T613=m +CONFIG_USB_GSPCA_TV8532=m +CONFIG_USB_GSPCA_VC032X=m +CONFIG_USB_GSPCA_ZC3XX=m +# CONFIG_USB_G_PRINTER is not set +CONFIG_USB_G_SERIAL=m +CONFIG_USB_HID=m +CONFIG_USB_HIDDEV=y +CONFIG_USB_HSO=m +CONFIG_USB_HWA_HCD=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_IOWARRIOR=m +CONFIG_USB_IRDA=m +CONFIG_USB_ISIGHTFW=m +CONFIG_USB_ISP116X_HCD=m +CONFIG_USB_ISP1760_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_M5602=m +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m +# CONFIG_USB_MIDI_GADGET is not set +CONFIG_USB_MON=y +CONFIG_USB_MOUSE=m +CONFIG_USB_MR800=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_RNDIS_WLAN=m +CONFIG_USB_NET_SMSC95XX=m +CONFIG_USB_NET_ZAURUS=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_HCD_SSB is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OV511 is not set +CONFIG_USB_OV511_NEW=m +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_R8A66597_HCD=m +CONFIG_USB_RIO500=m +CONFIG_USB_RTL8150=m +CONFIG_USB_S2255=m +CONFIG_USB_SE401=m +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_AIRCABLE=m +CONFIG_USB_SERIAL_ARK3116=m +CONFIG_USB_SERIAL_BELKIN=m +CONFIG_USB_SERIAL_CH341=m +CONFIG_USB_SERIAL_CONSOLE=y +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_IUU is not set +CONFIG_USB_SERIAL_KEYSPAN=m +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_MOTOROLA=m +CONFIG_USB_SERIAL_NAVMAN=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_SERIAL_OPTION=m +CONFIG_USB_SERIAL_OTI6858=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_SPCP8X5=m +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_VISOR=m +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SEVSEG=m +CONFIG_USB_SI470X=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_STKWEBCAM=m +CONFIG_USB_STORAGE=m +CONFIG_USB_STORAGE_ALAUDA=y +# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set +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_ONETOUCH is not set +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STV680=m +CONFIG_USB_SUPPORT=y +CONFIG_USB_SUSPEND=y +# CONFIG_USB_TEST is not set +CONFIG_USB_TMC=m +CONFIG_USB_TRANCEVIBRATOR=m +CONFIG_USB_U132_HCD=m +CONFIG_USB_UEAGLEATM=m +CONFIG_USB_UHCI_HCD=m +CONFIG_USB_USBNET=m +CONFIG_USB_USS720=m +CONFIG_USB_VICAM=m +CONFIG_USB_VIDEO_CLASS=m +CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y +CONFIG_USB_VST=m +CONFIG_USB_W9968CF=m +CONFIG_USB_WDM=m +CONFIG_USB_WHCI_HCD=m +CONFIG_USB_WUSB=m +CONFIG_USB_WUSB_CBAF=m +# CONFIG_USB_WUSB_CBAF_DEBUG is not set +CONFIG_USB_XUSBATM=m +CONFIG_USB_ZC0301=m +CONFIG_USB_ZD1201=m +CONFIG_USB_ZERO=m +CONFIG_USB_ZR364XX=m +# CONFIG_USER_NS is not set +# CONFIG_USER_SCHED is not set +CONFIG_USE_GENERIC_SMP_HELPERS=y +CONFIG_UTS_NS=y +CONFIG_UWB=m +CONFIG_UWB_HWA=m +CONFIG_UWB_I1480U=m +CONFIG_UWB_I1480U_WLP=m +CONFIG_UWB_WHCI=m +CONFIG_UWB_WLP=m +CONFIG_V4L_USB_DRIVERS=y +CONFIG_VERSION_SIGNATURE="" +CONFIG_VETH=m +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=y +CONFIG_VIA_VELOCITY=m +CONFIG_VIDEOBUF_DMA_CONTIG=m +CONFIG_VIDEOBUF_DMA_SG=m +CONFIG_VIDEOBUF_DVB=m +CONFIG_VIDEOBUF_GEN=m +CONFIG_VIDEOBUF_VMALLOC=m +CONFIG_VIDEO_ADV7170=m +CONFIG_VIDEO_ADV7175=m +# CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_ALLOW_V4L1=y +CONFIG_VIDEO_AU0828=m +CONFIG_VIDEO_BT819=m +CONFIG_VIDEO_BT848=m +CONFIG_VIDEO_BT848_DVB=y +CONFIG_VIDEO_BT856=m +CONFIG_VIDEO_BTCX=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_CS5345=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_CX18=m +CONFIG_VIDEO_CX2341X=m +CONFIG_VIDEO_CX23885=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_EM28XX=m +CONFIG_VIDEO_EM28XX_ALSA=m +CONFIG_VIDEO_EM28XX_DVB=m +CONFIG_VIDEO_FB_IVTV=m +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y +CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_HEXIUM_ORION=m +CONFIG_VIDEO_IR=m +CONFIG_VIDEO_IR_I2C=m +CONFIG_VIDEO_IVTV=m +CONFIG_VIDEO_KS0127=m +CONFIG_VIDEO_M52790=m +CONFIG_VIDEO_MEDIA=m +CONFIG_VIDEO_MEYE=m +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_MXB=m +CONFIG_VIDEO_OUTPUT_CONTROL=m +CONFIG_VIDEO_OV7670=m +CONFIG_VIDEO_OVCAMCHIP=m +CONFIG_VIDEO_PVRUSB2=m +# CONFIG_VIDEO_PVRUSB2_DEBUGIFC is not set +CONFIG_VIDEO_PVRUSB2_DVB=y +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_SAA717X=m +CONFIG_VIDEO_SAA7185=m +CONFIG_VIDEO_SH_MOBILE_CEU=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_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=m +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m +CONFIG_VIDEO_V4L2_COMMON=m +CONFIG_VIDEO_VIVI=m +CONFIG_VIDEO_VP27SMPX=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_VIRTIO=m +CONFIG_VIRTIO_BALLOON=m +CONFIG_VIRTIO_BLK=m +CONFIG_VIRTIO_CONSOLE=m +CONFIG_VIRTIO_NET=m +CONFIG_VIRTIO_PCI=m +CONFIG_VIRTIO_RING=m +CONFIG_VIRTUALIZATION=y +CONFIG_VIRT_TO_BUS=y +CONFIG_VITESSE_PHY=m +CONFIG_VLAN_8021Q=m +CONFIG_VLAN_8021Q_GVRP=y +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_GPIO=m +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_SLAVE_BQ27000=m +CONFIG_W1_SLAVE_DS2433=m +# CONFIG_W1_SLAVE_DS2433_CRC is not set +CONFIG_W1_SLAVE_DS2760=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_THERM=m +CONFIG_W83627HF_WDT=m +CONFIG_W83697HF_WDT=m +CONFIG_W83697UG_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_WDTPCI=m +CONFIG_WDT_501_PCI=y +CONFIG_WINBOND_840=m +CONFIG_WINBOND_FIR=m +CONFIG_WIRELESS=y +CONFIG_WIRELESS_ACX=m +CONFIG_WIRELESS_AT76=m +CONFIG_WIRELESS_EXT=y +CONFIG_WIRELESS_EXT_SYSFS=y +CONFIG_WIRELESS_OLD_REGULATORY=y +CONFIG_WLAN_80211=y +CONFIG_WLAN_PRE80211=y +CONFIG_X25=m +CONFIG_X25_ASY=m +CONFIG_X86=y +# CONFIG_X86_32 is not set +CONFIG_X86_64=y +CONFIG_X86_64_SMP=y +CONFIG_X86_ACPI_CPUFREQ=m +# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set +CONFIG_X86_BIOS_REBOOT=y +CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_CHECK_BIOS_CORRUPTION=y +CONFIG_X86_CMOV=y +CONFIG_X86_CMPXCHG=y +CONFIG_X86_CMPXCHG64=y +CONFIG_X86_CPU=y +CONFIG_X86_CPUID=m +CONFIG_X86_DEBUGCTLMSR=y +# CONFIG_X86_DS is not set +# CONFIG_X86_ELAN is not set +CONFIG_X86_FIND_SMP_CONFIG=y +# CONFIG_X86_GENERICARCH is not set +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 is not set +CONFIG_X86_MINIMUM_CPU_FAMILY=64 +CONFIG_X86_MPPARSE=y +CONFIG_X86_MSR=m +CONFIG_X86_P4_CLOCKMOD=m +# CONFIG_X86_PAT 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_PTDUMP is not set +CONFIG_X86_RESERVE_LOW_64K=y +CONFIG_X86_SMP=y +CONFIG_X86_SPEEDSTEP_CENTRINO=m +CONFIG_X86_SPEEDSTEP_LIB=m +CONFIG_X86_TRAMPOLINE=y +CONFIG_X86_TSC=y +# CONFIG_X86_VERBOSE_BOOTUP is not set +# CONFIG_X86_VOYAGER is not set +# CONFIG_X86_VSMP is not set +CONFIG_X86_WP_WORKS_OK=y +CONFIG_XEN=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_BLKDEV_FRONTEND=m +# CONFIG_XEN_DEBUG_FS is not set +CONFIG_XEN_FBDEV_FRONTEND=m +CONFIG_XEN_KBDDEV_FRONTEND=m +CONFIG_XEN_MAX_DOMAIN_MEMORY=32 +CONFIG_XEN_NETDEV_FRONTEND=m +CONFIG_XEN_SAVE_RESTORE=y +CONFIG_XEN_SCRUB_PAGES=y +CONFIG_XFRM=y +CONFIG_XFRM_IPCOMP=m +# CONFIG_XFRM_MIGRATE is not set +# CONFIG_XFRM_STATISTICS is not set +# CONFIG_XFRM_SUB_POLICY is not set +CONFIG_XFRM_USER=m +# CONFIG_XFS_DEBUG is not set +CONFIG_XFS_FS=m +CONFIG_XFS_POSIX_ACL=y +CONFIG_XFS_QUOTA=y +CONFIG_XFS_RT=y +CONFIG_XOR_BLOCKS=m +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_ZEROPLUS_FF=m +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-2.6.28.orig/debian/config/amd64/config.generic +++ linux-2.6.28/debian/config/amd64/config.generic @@ -0,0 +1,11 @@ +# +# 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_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y --- linux-2.6.28.orig/debian/config/amd64/config.server +++ linux-2.6.28/debian/config/amd64/config.server @@ -0,0 +1,11 @@ +# +# 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_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set --- linux-2.6.28.orig/debian/control-scripts/postrm +++ linux-2.6.28/debian/control-scripts/postrm @@ -0,0 +1,353 @@ +#! /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; +} + +exit 0; + +__END__ + + + + + + --- linux-2.6.28.orig/debian/control-scripts/postinst +++ linux-2.6.28/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 $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-2.6.28.orig/debian/control-scripts/preinst +++ linux-2.6.28/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-2.6.28.orig/debian/control-scripts/headers-postinst +++ linux-2.6.28/debian/control-scripts/headers-postinst @@ -0,0 +1,126 @@ +#!/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; + +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-2.6.28.orig/debian/control-scripts/prerm +++ linux-2.6.28/debian/control-scripts/prerm @@ -0,0 +1,306 @@ +#! /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 () { + 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 modules.ofmap modules.seriomap + }; + + foreach my $extra_file (@files_to_remove) { + if (-f "/lib/modules/$version/$extra_file") { + unlink "/lib/modules/$version/$extra_file"; + } + } + exit 0; +} + + + +&success(); +exit 0; +__END__ + + + + + --- linux-2.6.28.orig/debian/stamps/keep-dir +++ linux-2.6.28/debian/stamps/keep-dir @@ -0,0 +1 @@ +Place holder --- linux-2.6.28.orig/debian/sub-flavours/control.stub +++ linux-2.6.28/debian/sub-flavours/control.stub @@ -0,0 +1,39 @@ +# Items that get replaced: +# FLAVOUR +# DESC +# ARCH +# SUPPORTED +# TARGET +# BOOTLOADER +# =PROVIDES= +# =CONFLICTS= +# +# Items marked with =FOO= are optional +# +# XXX: Leave the blank line before the first package!! + +Package: linux-image-PKGVER-ABINUM-FLAVOUR +Architecture: ARCH +Section: base +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.3-pre11-4ubuntu3) +Conflicts: hotplug (<< 0.0.20040105-1), =CONFLICTS= +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. --- linux-2.6.28.orig/debian/sub-flavours/virtual.list +++ linux-2.6.28/debian/sub-flavours/virtual.list @@ -0,0 +1,111 @@ +arch/*/{crypto,kernel,oprofile} +crypto/* +drivers/acpi/* +drivers/ata/ata_generic.ko +drivers/ata/ata_piix.ko +drivers/ata/libata.ko +drivers/block/virtio_blk.ko +drivers/block/nbd.ko +drivers/block/loop.ko +drivers/block/floppy.ko +drivers/block/cryptoloop.ko +drivers/block/xen-blkfront.ko +drivers/cdrom/cdrom.ko +drivers/char/hangcheck-timer.ko +drivers/char/lp.ko +drivers/char/nvram.ko +drivers/char/ppdev.ko +drivers/char/raw.ko +drivers/input/evbug.ko +drivers/input/evdev.ko +drivers/input/gameport/gameport.ko +drivers/input/mouse/psmouse.ko +drivers/input/serio/serio_raw.ko +drivers/input/serio/serport.ko +drivers/input/joydev.ko +drivers/input/misc/uinput.ko +drivers/input/touchscreen/usbtouchscreen.ko +drivers/input/xen-kbdfront.ko +drivers/md/* +drivers/message/fusion* +drivers/misc/eeprom_93cx6.ko +drivers/net/8139too.ko +drivers/net/8139cp.ko +drivers/net/appletalk/ipddp.ko +drivers/net/bonding/bonding.ko +drivers/net/bsd_comp.ko +drivers/net/dummy.ko +drivers/net/e1000/e1000.ko +drivers/net/eql.ko +drivers/net/ifb.ko +drivers/net/mii.ko +drivers/net/ne2k-pci.ko +drivers/net/netconsole.ko +drivers/net/pcnet32.ko +drivers/net/ppp_async.ko +drivers/net/ppp_deflate.ko +drivers/net/ppp_generic.ko +drivers/net/ppp_mppe.ko +drivers/net/pppoe.ko +drivers/net/pppol2tp.ko +drivers/net/pppox.ko +drivers/net/ppp_synctty.ko +drivers/net/slhc.ko +drivers/net/slip.ko +drivers/net/tun.ko +drivers/net/veth.ko +drivers/net/virtio_net.ko +drivers/net/xen-netfront.ko +drivers/parport/parport.ko +drivers/parport/parport_pc.ko +drivers/net/tulip/tulip.ko +drivers/net/virtio_net.ko +drivers/scsi/BusLogic.ko +drivers/scsi/iscsi_tcp.ko +drivers/scsi/libiscsi.ko +drivers/scsi/libsas/* +drivers/scsi/libsas/libsas.ko +drivers/scsi/qla1280.ko +drivers/scsi/raid_class.ko +drivers/scsi/scsi_mod.ko +drivers/scsi/scsi_transport_fc.ko +drivers/scsi/scsi_transport_iscsi.ko +drivers/scsi/scsi_transport_sas.ko +drivers/scsi/scsi_transport_spi.ko +drivers/scsi/scsi_wait_scan.ko +drivers/scsi/sd_mod.ko +drivers/scsi/sg.ko +drivers/scsi/sr_mod.ko +drivers/usb/core/usbcore.ko +drivers/usb/host/ehci-hcd.ko +drivers/usb/host/uhci-hcd.ko +drivers/usb/storage/usb-storage.ko +drivers/video/cirrusfb.ko +drivers/video/console/bitblit.ko +drivers/video/console/fbcon.ko +drivers/video/console/font.ko +drivers/video/console/softcursor.ko +drivers/video/console/tileblit.ko +drivers/video/output.ko +drivers/video/syscopyarea.ko +drivers/video/sysfillrect.ko +drivers/video/sysimgblt.ko +drivers/video/vesafb.ko +drivers/video/vga16fb.ko +drivers/video/vgastate.ko +drivers/video/xen-fbfront.ko +drivers/virtio/virtio_balloon.ko +drivers/virtio/virtio.ko +drivers/virtio/virtio_pci.ko +drivers/virtio/virtio_ring.ko +drivers/watchdog/softdog.ko +drivers/xen/* +fs/* +lib/* +net/* +sound/core/* +sound/pci/snd-ens1370.ko +sound/drivers/pcsp/snd-pcsp.ko +ubuntu/e1000e/e1000e.ko +ubuntu/squashfs/squashfs.ko +ubuntu/iscsitarget/iscsi_trgt.ko --- linux-2.6.28.orig/debian/sub-flavours/virtual.vars +++ linux-2.6.28/debian/sub-flavours/virtual.vars @@ -0,0 +1,11 @@ +# Based on server flavour +arch="i386 amd64" +supported="Virtual" +target="Geared toward virtual machine guests." +desc="x86/x86_64" +bootloader="grub | lilo (>= 19.1)" +is_sub="true" +based_on="server" +# The provides and conflicts are REQUIRED +provides="redhat-cluster-modules" +conflicts="linux-image-PKGVER-ABINUM-${based_on}" --- linux-2.6.28.orig/debian/sub-flavours/README +++ linux-2.6.28/debian/sub-flavours/README @@ -0,0 +1,12 @@ +Sub flavours are flavours that are built based on other builds. IOW, they +are usually a subset of something else. + +Requirements: + +debian/sub-flavours/.list : The file list, uses glob syntax +debian/sub-flavours/.vars : The make vars, similar to normal flavours +debian/rules.d/.mk : Add _sub var listing the , e.g. + server_sub = virtual would mean virtual is + based on the server flavour. + +Note, the vars must include a conflicts with the flavour it was built on. --- linux-2.6.28.orig/debian/control.d/vars.generic +++ linux-2.6.28/debian/control.d/vars.generic @@ -0,0 +1,6 @@ +arch="i386 amd64" +supported="Generic" +target="Geared toward desktop systems." +desc="x86/x86_64" +bootloader="grub | lilo (>= 19.1)" +provides="kvm-api-4, redhat-cluster-modules, ivtv-modules, ndiswrapper-modules-1.9" --- linux-2.6.28.orig/debian/control.d/vars.server +++ linux-2.6.28/debian/control.d/vars.server @@ -0,0 +1,6 @@ +arch="i386 amd64" +supported="Server" +target="Geared toward server systems." +desc="x86/x86_64" +bootloader="grub | lilo (>= 19.1)" +provides="redhat-cluster-modules, kvm-api-4, ivtv-modules, ndiswrapper-modules-1.9" --- linux-2.6.28.orig/debian/control.d/flavour-control.stub +++ linux-2.6.28/debian/control.d/flavour-control.stub @@ -0,0 +1,66 @@ +# 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: base +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.3-pre11-4ubuntu3) +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: devel +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. + +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. This package also includes the + unstripped modules. --- linux-2.6.28.orig/debian/control.d/vars.iop32x +++ linux-2.6.28/debian/control.d/vars.iop32x @@ -0,0 +1,8 @@ +arch="armel" +supported="IOP32x" +desc="IOP32x-based systems" +target="Thecus N2100, etc." +bootloader="" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/control.d/vars.versatile +++ linux-2.6.28/debian/control.d/vars.versatile @@ -0,0 +1,8 @@ +arch="armel" +supported="Versatile" +desc="Versatile-based systems" +target="PB, AB, Qemu, etc." +bootloader="" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/control.d/vars.ixp4xx +++ linux-2.6.28/debian/control.d/vars.ixp4xx @@ -0,0 +1,8 @@ +arch="armel" +supported="IXP4xx" +desc="IXP4xx-based systems" +target="Linksys NSLU2, etc." +bootloader="" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/control.d/vars.orion5x +++ linux-2.6.28/debian/control.d/vars.orion5x @@ -0,0 +1,8 @@ +arch="armel" +supported="Orion 5181, 5182 and 5281" +desc="Orion5x-based systems" +target="QNAP TS-109/TS-209, etc." +bootloader="" +provides="" +section_image="universe/base" +do_debug="Yes" --- linux-2.6.28.orig/debian/abi/perm-blacklist +++ linux-2.6.28/debian/abi/perm-blacklist @@ -0,0 +1,3 @@ +M: ubuntu/misc/wireless/p80211/p80211 +M: sound/pci/emu10k1/snd-emu10k1 +M: fs/xfs/xfs --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/abiname +++ linux-2.6.28/debian/abi/2.6.28-4.9/abiname @@ -0,0 +1 @@ +4 --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/iop32x.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/iop32x.modules @@ -0,0 +1,187 @@ +act_gact +act_ipt +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +aead +aes_generic +anubis +arc4 +arptable_filter +arp_tables +arpt_mangle +async_memcpy +async_xor +blowfish +brd +cast5 +cast6 +cbc +cdrom +chainiv +cls_basic +cls_flow +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +configfs +cramfs +crc16 +crc32c +crc-itu-t +crc-t10dif +crypto_algapi +crypto_blkcipher +crypto_hash +cryptoloop +cryptomgr +crypto_null +deflate +des_generic +dm-mod +ecb +eseqiv +fuse +gf128mul +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hmac +hwa-hc +hwa-rc +i2c-algo-bit +i2c-gpio +ide-cd_mod +ide-pci-generic +ide-tape +ifb +iptable_filter +iptable_mangle +iptable_raw +ip_tables +ipt_addrtype +ipt_ah +ipt_ecn +ipt_ECN +ipt_LOG +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +isofs +jfs +khazad +krng +libcrc32c +lrw +md4 +md5 +md-mod +michael_mic +msdos +nand +nand_ecc +nand_ids +nbd +pcbc +phonet +plat_nand +pn_pep +raid0 +raid1 +raid10 +raid456 +reiserfs +rng +rng-core +sch_cbq +sch_dsmark +sch_gred +sch_htb +sch_ingress +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_wait_scan +serpent +sg +sha1_generic +sha256_generic +sha512_generic +sit +tea +tgr192 +ts_bm +ts_fsm +ts_kmp +tunnel4 +twofish +twofish_common +udf +uwb +virtual +wp512 +wusb-cbaf +wusbcore +wusb-wa +xcbc +xfrm6_mode_beet +xfrm6_mode_transport +xfrm6_mode_tunnel +xfs +xor +x_tables +xt_CLASSIFY +xt_comment +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_iprange +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_owner +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_TCPOPTSTRIP +xt_tcpudp +xt_time +xt_TRACE +xt_u32 --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/iop32x +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/iop32x @@ -0,0 +1,4034 @@ +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/cdrom/cdrom 0x0f9141bf cdrom_media_changed +EXPORT_SYMBOL drivers/cdrom/cdrom 0x1efad295 register_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x21ed6d24 cdrom_open +EXPORT_SYMBOL drivers/cdrom/cdrom 0x2508256a cdrom_mode_sense +EXPORT_SYMBOL drivers/cdrom/cdrom 0x2c62488c cdrom_release +EXPORT_SYMBOL drivers/cdrom/cdrom 0x3851621c cdrom_number_of_slots +EXPORT_SYMBOL drivers/cdrom/cdrom 0x421ba20c unregister_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4c24211a cdrom_mode_select +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL drivers/cdrom/cdrom 0x57af4cea cdrom_get_media_event +EXPORT_SYMBOL drivers/cdrom/cdrom 0x769b6813 cdrom_get_last_written +EXPORT_SYMBOL drivers/cdrom/cdrom 0xbc586428 cdrom_ioctl +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x87dfb01e i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xb7662a66 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/md/dm-mod 0x0b47f05a dm_unregister_target +EXPORT_SYMBOL drivers/md/dm-mod 0x138b1213 dm_get_mapinfo +EXPORT_SYMBOL drivers/md/dm-mod 0x16bbaa64 dm_kcopyd_copy +EXPORT_SYMBOL drivers/md/dm-mod 0x20e99657 dm_put_device +EXPORT_SYMBOL drivers/md/dm-mod 0x346ff061 dm_table_get_md +EXPORT_SYMBOL drivers/md/dm-mod 0x3652af3a dm_table_put +EXPORT_SYMBOL drivers/md/dm-mod 0x53958d61 dm_io_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x546f7a07 dm_io +EXPORT_SYMBOL drivers/md/dm-mod 0x54e39714 dm_kcopyd_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x6881f055 dm_register_target +EXPORT_SYMBOL drivers/md/dm-mod 0x76ca9817 dm_io_client_resize +EXPORT_SYMBOL drivers/md/dm-mod 0x8346a1ac dm_io_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x91828556 dm_kcopyd_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x9a5a5f06 dm_table_event +EXPORT_SYMBOL drivers/md/dm-mod 0xa630f875 dm_table_get_size +EXPORT_SYMBOL drivers/md/dm-mod 0xab42bb1f dm_get_device +EXPORT_SYMBOL drivers/md/dm-mod 0xae43ddb4 dm_table_get_mode +EXPORT_SYMBOL drivers/md/dm-mod 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL drivers/md/dm-mod 0xcc294cec dm_table_get +EXPORT_SYMBOL drivers/md/dm-mod 0xfe893113 dm_table_unplug_all +EXPORT_SYMBOL drivers/md/md-mod 0x01bbaeb4 md_write_start +EXPORT_SYMBOL drivers/md/md-mod 0x1a9979d2 register_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x1c5c18ac bitmap_startwrite +EXPORT_SYMBOL drivers/md/md-mod 0x2c156e82 md_check_recovery +EXPORT_SYMBOL drivers/md/md-mod 0x30d67a39 bitmap_unplug +EXPORT_SYMBOL drivers/md/md-mod 0x362a6ce9 md_unregister_thread +EXPORT_SYMBOL drivers/md/md-mod 0x6e5ca9b1 md_error +EXPORT_SYMBOL drivers/md/md-mod 0x6fec3259 bitmap_cond_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x70675ffe bitmap_start_sync +EXPORT_SYMBOL drivers/md/md-mod 0x751aedba bitmap_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x78f7f68a bitmap_close_sync +EXPORT_SYMBOL drivers/md/md-mod 0x81eeb6f4 md_done_sync +EXPORT_SYMBOL drivers/md/md-mod 0x882ac87e md_wakeup_thread +EXPORT_SYMBOL drivers/md/md-mod 0x8cd54b54 md_register_thread +EXPORT_SYMBOL drivers/md/md-mod 0xada23868 bitmap_endwrite +EXPORT_SYMBOL drivers/md/md-mod 0xaffd6140 md_write_end +EXPORT_SYMBOL drivers/md/md-mod 0xb9647e57 md_wait_for_blocked_rdev +EXPORT_SYMBOL drivers/md/md-mod 0xe2924f18 unregister_md_personality +EXPORT_SYMBOL drivers/mtd/nand/nand 0x73b58cc8 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xcd6c8aa5 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x078d057c nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x35e6cfc5 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL fs/configfs/configfs 0x2fdeb8e9 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x35c21432 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x3ac0af51 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0x420e48ac configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x5b2e2207 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x5b755835 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x8227b346 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0x91ab091e configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x93644469 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0x9c5c0889 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xcb02d8f3 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xf031d1b5 config_item_set_name +EXPORT_SYMBOL fs/xfs/xfs 0x3f934d0e xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc-t10dif 0xb6896671 crc_t10dif +EXPORT_SYMBOL lib/crc16 0x02a6ce5a crc16_table +EXPORT_SYMBOL lib/crc16 0x8ffdb3b8 crc16 +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x36b39e33 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xcae46983 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xcb56c829 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x0fb1c8f3 ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xd44aef0a ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xe6bbb87b ipt_register_table +EXPORT_SYMBOL net/ipv4/tunnel4 0x250d6b8a xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv4/tunnel4 0x7d297b45 xfrm4_tunnel_register +EXPORT_SYMBOL net/netfilter/x_tables 0x2fe244d4 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0x3c63df20 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x6a72e315 xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0x887f67db xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xc1a8fd08 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xd9276826 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xd9f78384 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xe51ba217 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0xf838cd17 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xfd017dd2 xt_unregister_targets +EXPORT_SYMBOL net/phonet/phonet 0x0e5e908b phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0x2777e5cf pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x392dc604 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x3e86bfec phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0x525cae40 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x97f8128c pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0xa4fcf311 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xb70408dd phonet_proto_register +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x005dc433 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x005f2f55 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x00aea361 sock_i_ino +EXPORT_SYMBOL vmlinux 0x00b3a758 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x0128be12 flush_dcache_page +EXPORT_SYMBOL vmlinux 0x01547bcf find_inode_number +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01f233ea poll_initwait +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02196324 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x0230a9f3 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x024f4cae xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x02d1df1b sock_map_fd +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x02f3436e proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x03011aea vfs_mknod +EXPORT_SYMBOL vmlinux 0x03305a9e kfree_skb +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x0350e2f4 up_read +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03b796bd blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03e618e8 force_sig +EXPORT_SYMBOL vmlinux 0x03f52ece dmam_pool_create +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x040542f3 no_llseek +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x043b8483 __kfifo_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x0452543f check_disk_size_change +EXPORT_SYMBOL vmlinux 0x0455e6c6 set_blocksize +EXPORT_SYMBOL vmlinux 0x04706457 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x047284d5 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x04f2bf2e tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x04f7ff9d pci_set_power_state +EXPORT_SYMBOL vmlinux 0x052b2967 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x0535399f tcp_sendpage +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x05a9637a dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x05c771d1 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL vmlinux 0x06029436 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x06090de7 __sg_free_table +EXPORT_SYMBOL vmlinux 0x0615abd3 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0618e633 dump_fpu +EXPORT_SYMBOL vmlinux 0x062aba95 mempool_free +EXPORT_SYMBOL vmlinux 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL vmlinux 0x0676fda5 __scm_send +EXPORT_SYMBOL vmlinux 0x068ea1cb path_permission +EXPORT_SYMBOL vmlinux 0x06c984fe pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x06cb34e5 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x06d8bae1 idr_get_new +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x075e7175 dcache_readdir +EXPORT_SYMBOL vmlinux 0x0791181b get_write_access +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d924a7 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x07ea0bf9 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x080cd650 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x08246bfd ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x0834f77d sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x08431602 dget_locked +EXPORT_SYMBOL vmlinux 0x084354d4 stop_tty +EXPORT_SYMBOL vmlinux 0x088d5c61 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x08b4574d sk_release_kernel +EXPORT_SYMBOL vmlinux 0x091a28e0 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x0926b78e journal_get_write_access +EXPORT_SYMBOL vmlinux 0x092b007a sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x0934f2a4 register_console +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x094c8a03 clear_inode +EXPORT_SYMBOL vmlinux 0x099bccb7 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x09a9ca34 vc_resize +EXPORT_SYMBOL vmlinux 0x09b1d52d nobh_write_end +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09cb5faa blk_start_queue +EXPORT_SYMBOL vmlinux 0x09d45c21 down_timeout +EXPORT_SYMBOL vmlinux 0x09dd30a1 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x09fd15e5 is_container_init +EXPORT_SYMBOL vmlinux 0x0a002a18 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x0a1bebc5 kernel_execve +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a393e7f xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x0a3a997b netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a892499 vfs_read +EXPORT_SYMBOL vmlinux 0x0aa13d05 __raw_readsw +EXPORT_SYMBOL vmlinux 0x0aba05e9 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x0ac8eee2 sk_stop_timer +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0ae3e3df i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x0b00c646 bio_split +EXPORT_SYMBOL vmlinux 0x0b0f18c4 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b569586 skb_clone +EXPORT_SYMBOL vmlinux 0x0b5f2d2c sg_next +EXPORT_SYMBOL vmlinux 0x0b651f67 dma_unmap_sg +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b902c63 vfs_unlink +EXPORT_SYMBOL vmlinux 0x0ba87b28 sk_dst_check +EXPORT_SYMBOL vmlinux 0x0baff99a request_firmware +EXPORT_SYMBOL vmlinux 0x0bd9a575 get_empty_filp +EXPORT_SYMBOL vmlinux 0x0bdc36f9 pci_reenable_device +EXPORT_SYMBOL vmlinux 0x0c3f9200 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c7e618c posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0c92fdc2 arp_xmit +EXPORT_SYMBOL vmlinux 0x0cf121a9 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x0d2970f1 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x0d3def21 idr_pre_get +EXPORT_SYMBOL vmlinux 0x0d3f57a2 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d56c218 lookup_one_len +EXPORT_SYMBOL vmlinux 0x0d69858a neigh_event_ns +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0dc230a7 __nla_reserve +EXPORT_SYMBOL vmlinux 0x0df6757c redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x0dfe73b2 generic_removexattr +EXPORT_SYMBOL vmlinux 0x0e47b797 km_state_expired +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e95808a elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x0e9b082f loop_register_transfer +EXPORT_SYMBOL vmlinux 0x0f1ef871 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x0f258f6e dev_set_mtu +EXPORT_SYMBOL vmlinux 0x0f28d994 unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL vmlinux 0x0f70a982 drive_is_ready +EXPORT_SYMBOL vmlinux 0x0f8a2ff7 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x0f9a9350 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x0fa2a45e __memzero +EXPORT_SYMBOL vmlinux 0x0fae8ab4 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x0fb0f1ec i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x0fc586ba down_trylock +EXPORT_SYMBOL vmlinux 0x0ff178f6 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x0fff5599 vmtruncate +EXPORT_SYMBOL vmlinux 0x10055957 __devm_release_region +EXPORT_SYMBOL vmlinux 0x10579454 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x105900b3 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x108da69b uart_match_port +EXPORT_SYMBOL vmlinux 0x10d28a3c tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x1104ec80 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x1108e781 blk_put_request +EXPORT_SYMBOL vmlinux 0x111bcb2c groups_free +EXPORT_SYMBOL vmlinux 0x1123a08b proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x1143f4b6 inet_bind +EXPORT_SYMBOL vmlinux 0x114a5176 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x115cf419 scsi_finish_command +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x116b457b tcp_poll +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x11776dde tcp_parse_options +EXPORT_SYMBOL vmlinux 0x117c930d pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x119b50e7 elf_check_arch +EXPORT_SYMBOL vmlinux 0x11ccf38e generic_block_fiemap +EXPORT_SYMBOL vmlinux 0x11cd4ecc ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x11fe9699 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x121431bc bdi_init +EXPORT_SYMBOL vmlinux 0x121a4f09 cfi_fixup +EXPORT_SYMBOL vmlinux 0x12454367 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x1263f2ef scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0x1267a3cf skb_store_bits +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1295993b ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0x129badc6 pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x12add9ae proc_mkdir +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL vmlinux 0x13266092 put_io_context +EXPORT_SYMBOL vmlinux 0x132e0a63 dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0x136ae955 nla_put +EXPORT_SYMBOL vmlinux 0x13908132 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x1396c396 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x13b76a46 arp_find +EXPORT_SYMBOL vmlinux 0x13d9d989 kobject_set_name +EXPORT_SYMBOL vmlinux 0x1414ed71 __neigh_event_send +EXPORT_SYMBOL vmlinux 0x141d4f7d sock_create_kern +EXPORT_SYMBOL vmlinux 0x144ed3a1 dev_base_lock +EXPORT_SYMBOL vmlinux 0x14799353 init_file +EXPORT_SYMBOL vmlinux 0x148b22ff set_device_ro +EXPORT_SYMBOL vmlinux 0x1502d40d xscale_flush_user_cache_range +EXPORT_SYMBOL vmlinux 0x1509ca4a d_splice_alias +EXPORT_SYMBOL vmlinux 0x150bbfc9 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x152d952d kill_fasync +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x156182c8 scsi_register +EXPORT_SYMBOL vmlinux 0x15915257 skb_truesize_bug +EXPORT_SYMBOL vmlinux 0x15b76592 poll_freewait +EXPORT_SYMBOL vmlinux 0x1634ddd3 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x16479e8f panic_notifier_list +EXPORT_SYMBOL vmlinux 0x165c93c2 blk_recount_segments +EXPORT_SYMBOL vmlinux 0x16c6d721 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x16d721ac tty_set_operations +EXPORT_SYMBOL vmlinux 0x1701a5dc scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17d66f07 put_page +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x186214f4 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x18877910 sock_no_getname +EXPORT_SYMBOL vmlinux 0x18998d01 inode_double_unlock +EXPORT_SYMBOL vmlinux 0x18ae22bb pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x18fb7b21 icmpv6_send +EXPORT_SYMBOL vmlinux 0x1921a526 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x1942c7a9 pci_choose_state +EXPORT_SYMBOL vmlinux 0x195a8adf scsi_free_command +EXPORT_SYMBOL vmlinux 0x197d9706 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x1995ba05 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19bbe2aa simple_lookup +EXPORT_SYMBOL vmlinux 0x19ff54a1 mii_nway_restart +EXPORT_SYMBOL vmlinux 0x1a14c83f inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x1a2f3ab3 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x1a444ca4 xdr_reserve_space +EXPORT_SYMBOL vmlinux 0x1a65f4ad __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x1a79658c ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0x1a7a3e61 pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x1aa9815b svc_destroy +EXPORT_SYMBOL vmlinux 0x1aae9062 ide_do_reset +EXPORT_SYMBOL vmlinux 0x1ac14c6c neigh_for_each +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad1f2e7 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x1ae3997f blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1aecd508 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b0d703d svc_process +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bab9774 blk_free_tags +EXPORT_SYMBOL vmlinux 0x1bb9b8dc bio_copy_user +EXPORT_SYMBOL vmlinux 0x1bd47cb8 journal_start +EXPORT_SYMBOL vmlinux 0x1bf8059b xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x1c1cc0b1 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x1c324357 idr_replace +EXPORT_SYMBOL vmlinux 0x1c45a83d pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x1c723b86 seq_puts +EXPORT_SYMBOL vmlinux 0x1c7de72a prepare_binprm +EXPORT_SYMBOL vmlinux 0x1ca88fbe simple_transaction_read +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ccf813d dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0x1cdd0bc8 ip6_frag_match +EXPORT_SYMBOL vmlinux 0x1d0aaf41 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x1d140de9 sk_filter +EXPORT_SYMBOL vmlinux 0x1d218b24 block_invalidatepage +EXPORT_SYMBOL vmlinux 0x1d2c0212 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x1d37d56f ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x1d3d7d11 con_is_bound +EXPORT_SYMBOL vmlinux 0x1d6595c2 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x1da34818 mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0x1dba92b8 rpc_unlink +EXPORT_SYMBOL vmlinux 0x1dc7e4d6 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x1dd236cb sysctl_data +EXPORT_SYMBOL vmlinux 0x1e49daa8 sg_init_one +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e77e653 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x1ea21a20 scsi_device_get +EXPORT_SYMBOL vmlinux 0x1ecb9943 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x1edc9598 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x1edebb7e bdi_register_dev +EXPORT_SYMBOL vmlinux 0x1ee2c0f7 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x1eeec8f9 sock_no_mmap +EXPORT_SYMBOL vmlinux 0x1ef17e27 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x1ef2e12b kobject_get +EXPORT_SYMBOL vmlinux 0x1efd58bb inet6_ioctl +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f421108 sync_blockdev +EXPORT_SYMBOL vmlinux 0x1f5ab168 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x1f70d32d dma_cache_maint +EXPORT_SYMBOL vmlinux 0x1f7cc628 mempool_create +EXPORT_SYMBOL vmlinux 0x1fae7a0b wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x1fc91fb2 request_irq +EXPORT_SYMBOL vmlinux 0x1fdb5d7a __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2043b449 starget_for_each_device +EXPORT_SYMBOL vmlinux 0x206d74c5 ip_defrag +EXPORT_SYMBOL vmlinux 0x2071d1bb pci_dev_get +EXPORT_SYMBOL vmlinux 0x20bfe802 xdr_buf_from_iov +EXPORT_SYMBOL vmlinux 0x20e85345 __bio_clone +EXPORT_SYMBOL vmlinux 0x20ffc95d netlink_unicast +EXPORT_SYMBOL vmlinux 0x211331fa __divsi3 +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x2169d085 udp_prot +EXPORT_SYMBOL vmlinux 0x218b9118 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x21a14361 save_mount_options +EXPORT_SYMBOL vmlinux 0x21b80da5 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x21d44c96 sk_common_release +EXPORT_SYMBOL vmlinux 0x21da468e inet_add_protocol +EXPORT_SYMBOL vmlinux 0x2216c334 icmp_send +EXPORT_SYMBOL vmlinux 0x222236f7 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x2225c7ca dev_add_pack +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x22569138 scsi_remove_device +EXPORT_SYMBOL vmlinux 0x2269b98d noop_qdisc +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x229cfd5b gen_new_estimator +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22d37315 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x22d64f07 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x231cf494 up_write +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x23838107 __down_write +EXPORT_SYMBOL vmlinux 0x2389c05d scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x23b1d7df bdput +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x2455c156 __clear_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x24651429 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x24770b1f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x248d992a register_qdisc +EXPORT_SYMBOL vmlinux 0x2491413a vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x249b8439 pskb_copy +EXPORT_SYMBOL vmlinux 0x24c6b6a2 dma_sync_wait +EXPORT_SYMBOL vmlinux 0x24d49058 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x24ed8a43 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x24edd27e call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x24fff9fa gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x252df3ae blk_execute_rq +EXPORT_SYMBOL vmlinux 0x2537bacb tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0x2557fcc9 bio_free +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x25928c63 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x25968616 journal_stop +EXPORT_SYMBOL vmlinux 0x259af0d6 rpc_mkpipe +EXPORT_SYMBOL vmlinux 0x25a00171 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0x25b218c7 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x25ba121c mempool_resize +EXPORT_SYMBOL vmlinux 0x25fa6f17 wait_for_completion +EXPORT_SYMBOL vmlinux 0x261a5bf3 dev_remove_pack +EXPORT_SYMBOL vmlinux 0x261c1766 __backtrace +EXPORT_SYMBOL vmlinux 0x26477c07 __vmalloc +EXPORT_SYMBOL vmlinux 0x265cbc4e __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x266110a6 kobject_del +EXPORT_SYMBOL vmlinux 0x26711c7d blk_plug_device +EXPORT_SYMBOL vmlinux 0x267ea568 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x267fc65b __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x268da785 netif_rx_ni +EXPORT_SYMBOL vmlinux 0x26a3daf4 vfs_readlink +EXPORT_SYMBOL vmlinux 0x26bcdf6a tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x26dbac93 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26f096b7 d_alloc_name +EXPORT_SYMBOL vmlinux 0x2704bf53 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x270f7dfd __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x2728d075 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x27411a43 journal_init_dev +EXPORT_SYMBOL vmlinux 0x276f8aed dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27b2b950 scsi_target_resume +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27bcf95c may_umount +EXPORT_SYMBOL vmlinux 0x27c5a522 is_bad_inode +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x280034f6 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x28118cb6 __get_user_1 +EXPORT_SYMBOL vmlinux 0x2837760d wireless_send_event +EXPORT_SYMBOL vmlinux 0x2846deee request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x286eabe6 bio_pair_release +EXPORT_SYMBOL vmlinux 0x2877d1de xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x2881be7b udplite_prot +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28bf9733 scsi_ioctl +EXPORT_SYMBOL vmlinux 0x28cee849 unlock_buffer +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x29016905 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x2902d544 pci_select_bars +EXPORT_SYMBOL vmlinux 0x29148969 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL vmlinux 0x293e0147 bio_alloc +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x297ca339 pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29d913d2 dma_map_sg +EXPORT_SYMBOL vmlinux 0x2a438f7d register_nls +EXPORT_SYMBOL vmlinux 0x2a6b180c __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2aa85b71 skb_queue_head +EXPORT_SYMBOL vmlinux 0x2ab4b8c4 blk_complete_request +EXPORT_SYMBOL vmlinux 0x2af9516b pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b17cf4b free_task +EXPORT_SYMBOL vmlinux 0x2b40baff __down_write_nested +EXPORT_SYMBOL vmlinux 0x2b428103 generic_fillattr +EXPORT_SYMBOL vmlinux 0x2b570dc0 ida_pre_get +EXPORT_SYMBOL vmlinux 0x2b6b164f tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bc6114b tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x2c013f50 d_namespace_path +EXPORT_SYMBOL vmlinux 0x2c12a591 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x2c866f1a generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0x2c93c78e scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x2ca1b10f pci_remove_bus +EXPORT_SYMBOL vmlinux 0x2cc1855c make_bad_inode +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2ce8edd0 pci_set_mwi +EXPORT_SYMBOL vmlinux 0x2ceaa5c0 journal_create +EXPORT_SYMBOL vmlinux 0x2d023852 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x2d6507b5 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x2d87b03c sg_miter_next +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d9b6c64 sock_kmalloc +EXPORT_SYMBOL vmlinux 0x2d9c2a39 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x2dbf210d dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x2dd9ad77 pci_save_state +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2e1eab34 ip6_xmit +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2ec2f1af xdr_init_encode +EXPORT_SYMBOL vmlinux 0x2ed24b38 vm_insert_page +EXPORT_SYMBOL vmlinux 0x2ede570d cdev_alloc +EXPORT_SYMBOL vmlinux 0x2eea0798 __getblk +EXPORT_SYMBOL vmlinux 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL vmlinux 0x2f45462b unlock_rename +EXPORT_SYMBOL vmlinux 0x2f846dda i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x2fbae9ee eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x2fc484eb wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x304bcf19 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x30be972b bdi_unregister +EXPORT_SYMBOL vmlinux 0x30d6158d xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x3110554b skb_find_text +EXPORT_SYMBOL vmlinux 0x31163366 d_genocide +EXPORT_SYMBOL vmlinux 0x312ddbee sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x313341a3 _set_bit_le +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x31593fd6 d_move +EXPORT_SYMBOL vmlinux 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL vmlinux 0x3177de33 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31d671c3 xfrm_register_km +EXPORT_SYMBOL vmlinux 0x31f3f103 journal_init_inode +EXPORT_SYMBOL vmlinux 0x32012860 skb_dequeue +EXPORT_SYMBOL vmlinux 0x321f6692 pci_bus_type +EXPORT_SYMBOL vmlinux 0x323222ba mutex_unlock +EXPORT_SYMBOL vmlinux 0x3238154a cfi_read_pri +EXPORT_SYMBOL vmlinux 0x328a05f1 strncpy +EXPORT_SYMBOL vmlinux 0x3295295d inet_select_addr +EXPORT_SYMBOL vmlinux 0x329bc555 register_exec_domain +EXPORT_SYMBOL vmlinux 0x32a38958 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x32a95b47 skb_push +EXPORT_SYMBOL vmlinux 0x32c625f0 ide_end_request +EXPORT_SYMBOL vmlinux 0x32ce623a sg_last +EXPORT_SYMBOL vmlinux 0x32d1670d nf_ip_checksum +EXPORT_SYMBOL vmlinux 0x32d6aca2 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x32dc61df blk_requeue_request +EXPORT_SYMBOL vmlinux 0x32f8d1c4 generic_setxattr +EXPORT_SYMBOL vmlinux 0x33067c2e fd_install +EXPORT_SYMBOL vmlinux 0x330971d4 scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x330e0d58 dev_mc_delete +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33706192 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x338279a6 kernel_getpeername +EXPORT_SYMBOL vmlinux 0x339438b4 tty_hangup +EXPORT_SYMBOL vmlinux 0x33bcf447 flush_signals +EXPORT_SYMBOL vmlinux 0x33c6b416 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x3404d4a5 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x341d619a read_bytes_from_xdr_buf +EXPORT_SYMBOL vmlinux 0x34247079 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x3437b64b elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x3443b936 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x344caf74 pci_enable_wake +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349456ef inet6_del_protocol +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34efabc8 i2c_transfer +EXPORT_SYMBOL vmlinux 0x35326646 key_validate +EXPORT_SYMBOL vmlinux 0x353e3fa5 __get_user_4 +EXPORT_SYMBOL vmlinux 0x354caefd kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x354e5054 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x359103fe bioset_create +EXPORT_SYMBOL vmlinux 0x35b20ce3 inode_get_bytes +EXPORT_SYMBOL vmlinux 0x35c560b7 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x35f00f5f dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0x35f99919 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3665264a netdev_features_change +EXPORT_SYMBOL vmlinux 0x366bdeaa init_timer +EXPORT_SYMBOL vmlinux 0x36719366 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x367aa193 generic_file_open +EXPORT_SYMBOL vmlinux 0x36d6dd45 i2c_master_recv +EXPORT_SYMBOL vmlinux 0x36e47222 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x36f9c981 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x37082a66 cdev_del +EXPORT_SYMBOL vmlinux 0x3713aefa bio_map_kern +EXPORT_SYMBOL vmlinux 0x3716f8e1 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x37254d63 mem_map +EXPORT_SYMBOL vmlinux 0x3741cf59 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374e7a9f tcp_ioctl +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x3755596b journal_restart +EXPORT_SYMBOL vmlinux 0x375dc1f0 simple_empty +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37feda2f pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x38021004 pci_restore_state +EXPORT_SYMBOL vmlinux 0x381a309a tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x3843b46b skb_gso_segment +EXPORT_SYMBOL vmlinux 0x3848dc93 svc_wake_up +EXPORT_SYMBOL vmlinux 0x3852ad19 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38bd994f xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x38e56ac0 d_alloc_root +EXPORT_SYMBOL vmlinux 0x38e8378d pgprot_kernel +EXPORT_SYMBOL vmlinux 0x391ba399 add_disk +EXPORT_SYMBOL vmlinux 0x393e1f58 inet_shutdown +EXPORT_SYMBOL vmlinux 0x3963ba3a mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x39751e6d __free_pages +EXPORT_SYMBOL vmlinux 0x3976addf neigh_seq_start +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x399cd6a6 generic_readlink +EXPORT_SYMBOL vmlinux 0x39aa243f follow_up +EXPORT_SYMBOL vmlinux 0x39b02021 blkdev_put +EXPORT_SYMBOL vmlinux 0x39b68fdc set_bh_page +EXPORT_SYMBOL vmlinux 0x39b706ca skb_insert +EXPORT_SYMBOL vmlinux 0x3a2e30c2 copy_io_context +EXPORT_SYMBOL vmlinux 0x3a39fe38 kset_unregister +EXPORT_SYMBOL vmlinux 0x3a57fcd2 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3a9fa721 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x3aa2674c inode_sub_bytes +EXPORT_SYMBOL vmlinux 0x3aa9affe mtd_do_chip_probe +EXPORT_SYMBOL vmlinux 0x3ab2d174 down_killable +EXPORT_SYMBOL vmlinux 0x3ab604c5 inet6_getname +EXPORT_SYMBOL vmlinux 0x3adc15b9 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x3ae831b6 kref_init +EXPORT_SYMBOL vmlinux 0x3b155a22 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x3b1ef6c2 key_alloc +EXPORT_SYMBOL vmlinux 0x3b2d2950 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x3b99472d vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3bde5941 task_nice +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c629d0d tcf_register_action +EXPORT_SYMBOL vmlinux 0x3c886acc pci_match_id +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ccf3ca9 log_wait_commit +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3d1d12d6 clocksource_register +EXPORT_SYMBOL vmlinux 0x3d3c540f elf_hwcap +EXPORT_SYMBOL vmlinux 0x3d550f4d bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x3d624f5a scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x3d637406 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x3d68bd4b flow_cache_genid +EXPORT_SYMBOL vmlinux 0x3d75b002 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x3da09e5b i2c_use_client +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e3a8003 svc_drop +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e592998 dev_open +EXPORT_SYMBOL vmlinux 0x3e6caebd add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x3eb0af5c posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x3eb2275c create_proc_entry +EXPORT_SYMBOL vmlinux 0x3ecb6f6e dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f7a4454 dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x3f8ba521 __inet6_hash +EXPORT_SYMBOL vmlinux 0x3f8ede07 xfrm_state_add +EXPORT_SYMBOL vmlinux 0x3fe34bda dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x400e9c68 compute_creds +EXPORT_SYMBOL vmlinux 0x40123aeb idr_for_each +EXPORT_SYMBOL vmlinux 0x404148f7 simple_link +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407136b1 __put_user_8 +EXPORT_SYMBOL vmlinux 0x407c1404 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40a6f522 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x40bdd41a posix_lock_file +EXPORT_SYMBOL vmlinux 0x40d84e12 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x40f07981 __ashldi3 +EXPORT_SYMBOL vmlinux 0x4101a975 ide_fixstring +EXPORT_SYMBOL vmlinux 0x41166725 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x412ddc0c dcache_lock +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x41573d06 sk_free +EXPORT_SYMBOL vmlinux 0x415b5f4c misc_register +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188918e end_page_writeback +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x41965b3c tcp_disconnect +EXPORT_SYMBOL vmlinux 0x41a91a11 find_get_page +EXPORT_SYMBOL vmlinux 0x420eb435 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x42306f41 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x4250b629 del_mtd_partitions +EXPORT_SYMBOL vmlinux 0x42567ce5 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x425f54dd __netif_schedule +EXPORT_SYMBOL vmlinux 0x42967b3c nf_afinfo +EXPORT_SYMBOL vmlinux 0x429758e3 get_sb_bdev +EXPORT_SYMBOL vmlinux 0x429d99fc sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x42a38709 xdr_decode_word +EXPORT_SYMBOL vmlinux 0x42b9ab83 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x42d265c3 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x42ea0095 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x42f41860 ilookup5 +EXPORT_SYMBOL vmlinux 0x430205aa __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x434556e5 neigh_lookup +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x4357052f con_copy_unimap +EXPORT_SYMBOL vmlinux 0x4380ea98 vm_map_ram +EXPORT_SYMBOL vmlinux 0x439a244f block_prepare_write +EXPORT_SYMBOL vmlinux 0x439d63d6 __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x43d1a771 scsi_host_get +EXPORT_SYMBOL vmlinux 0x43e1c073 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x440b9784 tty_name +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x44643b93 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x4470e8aa journal_dirty_data +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c214d1 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x44ce4ba0 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x44da5d0f __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x4562fd6c tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x456b31e6 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x4571be1d ipv4_specific +EXPORT_SYMBOL vmlinux 0x4575456b __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x45a55ec8 __iounmap +EXPORT_SYMBOL vmlinux 0x45bda0d5 system_serial_low +EXPORT_SYMBOL vmlinux 0x45f2f561 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x460029a6 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x46232e69 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x464e0c62 init_mm +EXPORT_SYMBOL vmlinux 0x4651e2ae arp_send +EXPORT_SYMBOL vmlinux 0x46bcfc2c current_fs_time +EXPORT_SYMBOL vmlinux 0x46c2a34c user_revoke +EXPORT_SYMBOL vmlinux 0x46d3b28c __div0 +EXPORT_SYMBOL vmlinux 0x46d9645c journal_abort +EXPORT_SYMBOL vmlinux 0x4710ffe5 simple_statfs +EXPORT_SYMBOL vmlinux 0x4713bffc __elv_add_request +EXPORT_SYMBOL vmlinux 0x4719ba4e kfifo_free +EXPORT_SYMBOL vmlinux 0x471ec179 pci_request_region +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x47624a0c ___pskb_trim +EXPORT_SYMBOL vmlinux 0x4762bffa i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x47691544 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x4769ac40 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x4796234f i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x47be4ef8 qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47f3d6b5 inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x47f757de elf_platform +EXPORT_SYMBOL vmlinux 0x48034724 zlib_deflateReset +EXPORT_SYMBOL vmlinux 0x4814d5a5 unload_nls +EXPORT_SYMBOL vmlinux 0x481e45f1 fifo_set_limit +EXPORT_SYMBOL vmlinux 0x4822238c inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x4838fba8 svc_create_pooled +EXPORT_SYMBOL vmlinux 0x48409742 mb_cache_create +EXPORT_SYMBOL vmlinux 0x484bd59b udp_disconnect +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48a5b067 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x48f9f12d complete_all +EXPORT_SYMBOL vmlinux 0x4909eade filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x494619a9 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x4948e051 single_release +EXPORT_SYMBOL vmlinux 0x496380a9 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x49727914 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x4972d463 bio_endio +EXPORT_SYMBOL vmlinux 0x498ef45c unregister_nls +EXPORT_SYMBOL vmlinux 0x49fbe8ac dma_async_client_register +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a3bc527 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4aab8da0 neigh_create +EXPORT_SYMBOL vmlinux 0x4acfd8ad down_interruptible +EXPORT_SYMBOL vmlinux 0x4ad9a6fe xscale_mc_copy_user_page +EXPORT_SYMBOL vmlinux 0x4aea4791 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b10996f tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b397076 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x4b8edde9 complete_and_exit +EXPORT_SYMBOL vmlinux 0x4b9b1120 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x4b9f3684 kfifo_init +EXPORT_SYMBOL vmlinux 0x4bb6a2ec blk_start_queueing +EXPORT_SYMBOL vmlinux 0x4befabe1 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c45bb02 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x4cac44a4 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x4cb4e196 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4ce94fa6 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x4d0d163d copy_page +EXPORT_SYMBOL vmlinux 0x4d395bc4 d_lookup +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d50c5cb udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x4d6214d7 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x4d94e901 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x4daca2bd inet_put_port +EXPORT_SYMBOL vmlinux 0x4db05540 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x4db7f290 cont_write_begin +EXPORT_SYMBOL vmlinux 0x4dbac54f scsi_print_sense +EXPORT_SYMBOL vmlinux 0x4dbdca13 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x4dbec324 ip6_route_output +EXPORT_SYMBOL vmlinux 0x4dc89422 scsi_print_command +EXPORT_SYMBOL vmlinux 0x4dd62b77 drop_super +EXPORT_SYMBOL vmlinux 0x4ddaa524 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4dec6038 memscan +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e0009da idr_get_new_above +EXPORT_SYMBOL vmlinux 0x4e079ab1 tcp_child_process +EXPORT_SYMBOL vmlinux 0x4e178820 sg_miter_start +EXPORT_SYMBOL vmlinux 0x4e2fed65 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e5f4dd3 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0x4e69e1f7 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4e94e807 sk_stream_error +EXPORT_SYMBOL vmlinux 0x4ef1dfa8 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x4ef2c925 inode_double_lock +EXPORT_SYMBOL vmlinux 0x4efb7d21 auth_unix_lookup +EXPORT_SYMBOL vmlinux 0x4f0ea0c0 up +EXPORT_SYMBOL vmlinux 0x4f39e6bc xfrm_nl +EXPORT_SYMBOL vmlinux 0x4f4a91b5 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x4f4ee37b cache_check +EXPORT_SYMBOL vmlinux 0x4f5651c3 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x4f8a3749 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x4f8ea848 kthread_stop +EXPORT_SYMBOL vmlinux 0x4fa86b50 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x4fc8dc28 ide_dump_status +EXPORT_SYMBOL vmlinux 0x5006eedd add_mtd_partitions +EXPORT_SYMBOL vmlinux 0x50477f6b inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x504b8593 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x504d89ce simple_transaction_get +EXPORT_SYMBOL vmlinux 0x5079c30e tty_unregister_device +EXPORT_SYMBOL vmlinux 0x5089c8d6 dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0x5093fa82 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x50b421ba udp_sendmsg +EXPORT_SYMBOL vmlinux 0x50b760cd mnt_pin +EXPORT_SYMBOL vmlinux 0x50bae815 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x50ce54ae unregister_console +EXPORT_SYMBOL vmlinux 0x512e327b inet_sendmsg +EXPORT_SYMBOL vmlinux 0x51493d94 finish_wait +EXPORT_SYMBOL vmlinux 0x514da037 udp_ioctl +EXPORT_SYMBOL vmlinux 0x5187ba82 journal_flush +EXPORT_SYMBOL vmlinux 0x51908eb8 __raw_writesl +EXPORT_SYMBOL vmlinux 0x51a929dd pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0x51c31674 igrab +EXPORT_SYMBOL vmlinux 0x51cc246c tcp_connect +EXPORT_SYMBOL vmlinux 0x51cd47e2 groups_alloc +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x51fd8915 flush_old_exec +EXPORT_SYMBOL vmlinux 0x52280bf3 send_sig +EXPORT_SYMBOL vmlinux 0x52354a0b mutex_trylock +EXPORT_SYMBOL vmlinux 0x525f856d neigh_update +EXPORT_SYMBOL vmlinux 0x526934a7 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x528116c5 proc_create_data +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52d9e2e3 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x53232d80 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x5326ea92 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53931c12 skb_copy +EXPORT_SYMBOL vmlinux 0x53b77a73 __bread +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53d55dea unregister_netdevice +EXPORT_SYMBOL vmlinux 0x53e01c2a pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x53e61fc4 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x53ee9c91 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x53fd2931 xdr_encode_pages +EXPORT_SYMBOL vmlinux 0x54054735 scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x5430a3f4 sock_rfree +EXPORT_SYMBOL vmlinux 0x5430b220 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x5434cc80 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x543cb674 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x548b0eb8 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x549005fe find_lock_page +EXPORT_SYMBOL vmlinux 0x54c3a8f0 __lock_buffer +EXPORT_SYMBOL vmlinux 0x54d92382 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x558a6097 pci_find_capability +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x559a63a3 check_disk_change +EXPORT_SYMBOL vmlinux 0x55b65f0c dcache_dir_close +EXPORT_SYMBOL vmlinux 0x55beac19 mii_check_media +EXPORT_SYMBOL vmlinux 0x55cf7b23 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x5604e48a task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x56405fff inet6_bind +EXPORT_SYMBOL vmlinux 0x566b06b8 uart_get_divisor +EXPORT_SYMBOL vmlinux 0x567fd4f2 dentry_unhash +EXPORT_SYMBOL vmlinux 0x5695f2ee generic_write_end +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56e194ae unix_domain_find +EXPORT_SYMBOL vmlinux 0x571f03c6 cpu_xscale_set_pte_ext +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x57680491 bmap +EXPORT_SYMBOL vmlinux 0x5770ddc1 pci_target_state +EXPORT_SYMBOL vmlinux 0x5774cf49 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x57806f2f per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x579bc029 cdev_init +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57f5c904 sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x581a9fe3 ide_do_drive_cmd +EXPORT_SYMBOL vmlinux 0x58201400 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x582e0d41 auth_unix_forget_old +EXPORT_SYMBOL vmlinux 0x583692b8 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584b5d74 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x585b8092 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x58b46abf generic_osync_inode +EXPORT_SYMBOL vmlinux 0x58e0c277 key_put +EXPORT_SYMBOL vmlinux 0x5907f0f6 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x594e1317 __modsi3 +EXPORT_SYMBOL vmlinux 0x59510d68 uart_resume_port +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x598b504b vfs_statfs +EXPORT_SYMBOL vmlinux 0x59908912 km_state_notify +EXPORT_SYMBOL vmlinux 0x5995d56f scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x59d1421f sock_create +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59e5070d __do_div64 +EXPORT_SYMBOL vmlinux 0x59f05267 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x59fc4da7 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x5a057faf elv_rb_find +EXPORT_SYMBOL vmlinux 0x5a133368 scsi_put_command +EXPORT_SYMBOL vmlinux 0x5a25422c console_start +EXPORT_SYMBOL vmlinux 0x5a726ee4 pci_release_regions +EXPORT_SYMBOL vmlinux 0x5a73562e bd_claim +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5aaf9681 fsync_bdev +EXPORT_SYMBOL vmlinux 0x5ab156b3 alloc_disk +EXPORT_SYMBOL vmlinux 0x5ac632f3 svc_seq_show +EXPORT_SYMBOL vmlinux 0x5ae337b8 locks_init_lock +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b39b130 generic_write_checks +EXPORT_SYMBOL vmlinux 0x5b51a113 cache_purge +EXPORT_SYMBOL vmlinux 0x5ba75b3f pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x5bb23e94 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x5bc8bf61 nf_log_packet +EXPORT_SYMBOL vmlinux 0x5bd80956 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x5bd9bd59 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x5bea4857 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x5c02136b auth_unix_add_addr +EXPORT_SYMBOL vmlinux 0x5c0b6c7c qdisc_reset +EXPORT_SYMBOL vmlinux 0x5c2eaac8 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x5c59028b alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x5c673bc8 tty_mutex +EXPORT_SYMBOL vmlinux 0x5c9284a0 processor_id +EXPORT_SYMBOL vmlinux 0x5cb34252 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x5cb9aeec secpath_dup +EXPORT_SYMBOL vmlinux 0x5d0782d2 seq_escape +EXPORT_SYMBOL vmlinux 0x5d9c44bb xdr_read_pages +EXPORT_SYMBOL vmlinux 0x5dcc8a91 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x5dd184d9 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x5e14b2f6 do_SAK +EXPORT_SYMBOL vmlinux 0x5e4d3f68 f_setown +EXPORT_SYMBOL vmlinux 0x5e5db4fe kernel_sendpage +EXPORT_SYMBOL vmlinux 0x5e68c605 dst_release +EXPORT_SYMBOL vmlinux 0x5e7519fb input_unregister_device +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5eab7503 inode_needs_sync +EXPORT_SYMBOL vmlinux 0x5ebb56fb down_read +EXPORT_SYMBOL vmlinux 0x5ec5e1fe uart_register_driver +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5ee2a728 scsi_remove_host +EXPORT_SYMBOL vmlinux 0x5f37f980 set_anon_super +EXPORT_SYMBOL vmlinux 0x5f4ccbac tty_write_room +EXPORT_SYMBOL vmlinux 0x5f754e5a memset +EXPORT_SYMBOL vmlinux 0x5fd0c3f6 inode_set_bytes +EXPORT_SYMBOL vmlinux 0x5ff8c649 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x6002446e pci_dev_put +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x600787c0 module_refcount +EXPORT_SYMBOL vmlinux 0x6010fbba __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x602187a1 lookup_bdev +EXPORT_SYMBOL vmlinux 0x602d47c0 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x6035cac7 pci_request_regions +EXPORT_SYMBOL vmlinux 0x60483d3c tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x60724e14 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x60747549 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x6095cfa7 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60a4efe2 ida_get_new +EXPORT_SYMBOL vmlinux 0x60eedb49 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x61593b72 __mod_timer +EXPORT_SYMBOL vmlinux 0x61899e1f sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61926fc3 generic_getxattr +EXPORT_SYMBOL vmlinux 0x6193c787 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x61a94239 generic_writepages +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61cbbd04 tcf_hash_check +EXPORT_SYMBOL vmlinux 0x62372022 skb_trim +EXPORT_SYMBOL vmlinux 0x6239dd43 do_splice_from +EXPORT_SYMBOL vmlinux 0x62525cae unregister_con_driver +EXPORT_SYMBOL vmlinux 0x62586a44 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x626d1f52 load_nls_default +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x635af8c2 scsi_host_put +EXPORT_SYMBOL vmlinux 0x638f4b31 tty_kref_put +EXPORT_SYMBOL vmlinux 0x63a47f90 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f516b3 put_filp +EXPORT_SYMBOL vmlinux 0x63fef547 svc_set_num_threads +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640a7078 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x64461a52 seq_printf +EXPORT_SYMBOL vmlinux 0x6464bb11 auth_domain_find +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64f2981a request_key_async +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x651ab882 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x65341b58 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6572fdfb set_irq_chip +EXPORT_SYMBOL vmlinux 0x6579e43f wireless_spy_update +EXPORT_SYMBOL vmlinux 0x659b533a dev_mc_add +EXPORT_SYMBOL vmlinux 0x65a5c3a2 cpu_present_map +EXPORT_SYMBOL vmlinux 0x65ed303c get_sb_nodev +EXPORT_SYMBOL vmlinux 0x660d6b07 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x661e6ec8 bioset_free +EXPORT_SYMBOL vmlinux 0x66268650 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0x66430355 bio_copy_kern +EXPORT_SYMBOL vmlinux 0x664673f6 ip6_frag_init +EXPORT_SYMBOL vmlinux 0x664d19bd shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x6667dcbe journal_release_buffer +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66998fcf blk_run_queue +EXPORT_SYMBOL vmlinux 0x66ba80d8 __lookup_hash +EXPORT_SYMBOL vmlinux 0x66c990b7 rt6_lookup +EXPORT_SYMBOL vmlinux 0x66cfa1a7 set_user_nice +EXPORT_SYMBOL vmlinux 0x66e61983 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x6724c489 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x6753cb8d inet_listen +EXPORT_SYMBOL vmlinux 0x676786a8 km_policy_expired +EXPORT_SYMBOL vmlinux 0x678defbd vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x67a01931 set_binfmt +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c03eb8 dev_get_by_index +EXPORT_SYMBOL vmlinux 0x67c2fa54 __copy_to_user +EXPORT_SYMBOL vmlinux 0x67d6f2d0 xdr_process_buf +EXPORT_SYMBOL vmlinux 0x67eb88f9 arp_create +EXPORT_SYMBOL vmlinux 0x67fe8680 inode_change_ok +EXPORT_SYMBOL vmlinux 0x67ffe21f blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x681eaef1 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x685a46af unregister_qdisc +EXPORT_SYMBOL vmlinux 0x68726aa8 bio_add_page +EXPORT_SYMBOL vmlinux 0x687518b2 i2c_master_send +EXPORT_SYMBOL vmlinux 0x687d3f68 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x6898a756 sg_init_table +EXPORT_SYMBOL vmlinux 0x691fb49c qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x6926d2c8 pci_enable_device +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x69496641 mod_timer +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69900486 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x699c1f3f end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x69af2327 idr_init +EXPORT_SYMBOL vmlinux 0x69c77a4d kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69ea8222 netlink_ack +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a2d07c6 journal_set_features +EXPORT_SYMBOL vmlinux 0x6a2e6774 tcp_close +EXPORT_SYMBOL vmlinux 0x6a454e01 d_alloc +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a737b85 eth_header +EXPORT_SYMBOL vmlinux 0x6a86febd nla_reserve +EXPORT_SYMBOL vmlinux 0x6aba7dfc bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x6ac45c28 __up_write +EXPORT_SYMBOL vmlinux 0x6acb33be unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b2fda05 setup_arg_pages +EXPORT_SYMBOL vmlinux 0x6bacdbdf auth_domain_lookup +EXPORT_SYMBOL vmlinux 0x6bd40a19 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6be250f8 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x6be894bc ide_set_handler +EXPORT_SYMBOL vmlinux 0x6c0456f3 xscale_mc_clear_user_page +EXPORT_SYMBOL vmlinux 0x6c16ba84 svc_sock_names +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c368f41 get_user_pages +EXPORT_SYMBOL vmlinux 0x6c36a5c1 __mutex_init +EXPORT_SYMBOL vmlinux 0x6c3d4b4d dev_get_flags +EXPORT_SYMBOL vmlinux 0x6c507138 tty_check_change +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c8a564d tty_shutdown +EXPORT_SYMBOL vmlinux 0x6cc0ec78 dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0x6cc42607 d_find_alias +EXPORT_SYMBOL vmlinux 0x6cc855fc __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6ce20f12 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x6cef247f __strnlen_user +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d16f2a8 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x6d258a57 seq_open_private +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d383491 journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x6d398a65 km_new_mapping +EXPORT_SYMBOL vmlinux 0x6d662533 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x6d888a41 elv_rb_del +EXPORT_SYMBOL vmlinux 0x6dc4a112 tty_vhangup +EXPORT_SYMBOL vmlinux 0x6dde4010 input_set_keycode +EXPORT_SYMBOL vmlinux 0x6dec5899 pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x6dee3d65 dst_discard +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e1a25b5 pneigh_lookup +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e5ce696 ide_stall_queue +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e7f4283 deny_write_access +EXPORT_SYMBOL vmlinux 0x6e84a85c save_time_delta +EXPORT_SYMBOL vmlinux 0x6e8d9574 xdr_init_decode +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ead43a7 thaw_bdev +EXPORT_SYMBOL vmlinux 0x6ee187e6 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL vmlinux 0x6ef94e4a locks_copy_lock +EXPORT_SYMBOL vmlinux 0x6f09b7af xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x6f14d660 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x6f3176c2 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x6f42b5e6 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x6f4e314f aio_complete +EXPORT_SYMBOL vmlinux 0x6f55d499 elv_queue_empty +EXPORT_SYMBOL vmlinux 0x6fa85925 simple_readpage +EXPORT_SYMBOL vmlinux 0x6fba7256 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x6fc9eeb5 proto_unregister +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fd48986 deactivate_super +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x7027418d dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x703d500c ide_wait_stat +EXPORT_SYMBOL vmlinux 0x70aeb595 tcp_proc_register +EXPORT_SYMBOL vmlinux 0x70bc2373 tc_classify_compat +EXPORT_SYMBOL vmlinux 0x70d47ade bio_phys_segments +EXPORT_SYMBOL vmlinux 0x70e696e6 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x714acdc5 serial8250_register_port +EXPORT_SYMBOL vmlinux 0x715af54e nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x7165ba74 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7199da93 kill_pid +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71b08beb vfs_permission +EXPORT_SYMBOL vmlinux 0x71b4a849 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x71c1f65e tty_port_init +EXPORT_SYMBOL vmlinux 0x71c90087 memcmp +EXPORT_SYMBOL vmlinux 0x71d45d8c skb_seq_read +EXPORT_SYMBOL vmlinux 0x71e6b9bb tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x71fa908a cache_flush +EXPORT_SYMBOL vmlinux 0x72070e1a dev_close +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x72430eda dst_destroy +EXPORT_SYMBOL vmlinux 0x72d5af61 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x72da9ea1 scsi_add_device +EXPORT_SYMBOL vmlinux 0x72e10953 fasync_helper +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fbae28 set_current_groups +EXPORT_SYMBOL vmlinux 0x73069aac cpu_possible_map +EXPORT_SYMBOL vmlinux 0x730aafd5 netif_device_detach +EXPORT_SYMBOL vmlinux 0x731201d8 brioctl_set +EXPORT_SYMBOL vmlinux 0x7319bc49 d_instantiate +EXPORT_SYMBOL vmlinux 0x732165e0 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x733f8008 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x734a34c6 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x734c03ea con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x735a2d7c neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x736e0002 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x73a64bd5 block_truncate_page +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x73e4a683 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x740aba2a kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x740cca6c __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x742a93b6 read_dev_sector +EXPORT_SYMBOL vmlinux 0x7463402e ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74c63e3f blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x75011de8 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0x7535e4d7 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x757e2aaa pcim_pin_device +EXPORT_SYMBOL vmlinux 0x75b28045 follow_down +EXPORT_SYMBOL vmlinux 0x75b4d29a elevator_exit +EXPORT_SYMBOL vmlinux 0x75c28419 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x75c84e21 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x75ca58de key_type_keyring +EXPORT_SYMBOL vmlinux 0x75d988bb pci_get_device +EXPORT_SYMBOL vmlinux 0x75fee7fd __raw_writesb +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x762d0574 sysctl_string +EXPORT_SYMBOL vmlinux 0x764c681c seq_path +EXPORT_SYMBOL vmlinux 0x765f75fb pgprot_user +EXPORT_SYMBOL vmlinux 0x766983e6 mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0x768c9772 nf_reinject +EXPORT_SYMBOL vmlinux 0x76989dcb invalidate_inodes +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76c93fe4 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x76cf47f6 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x77165942 nlmsvc_ops +EXPORT_SYMBOL vmlinux 0x7720fcf6 proc_symlink +EXPORT_SYMBOL vmlinux 0x773cbf1b __scsi_add_device +EXPORT_SYMBOL vmlinux 0x7740133f inet_ioctl +EXPORT_SYMBOL vmlinux 0x778c915b nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x77aaa774 inode_setattr +EXPORT_SYMBOL vmlinux 0x77d81a7a set_page_dirty +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x7807a779 __kfree_skb +EXPORT_SYMBOL vmlinux 0x7865684a invalidate_partition +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x789bb583 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x78b3047f filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x78ba8054 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x795678e8 vfs_link +EXPORT_SYMBOL vmlinux 0x79600d4a wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x796c6b9b tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79ad224b tasklet_kill +EXPORT_SYMBOL vmlinux 0x79bd35c7 pci_get_slot +EXPORT_SYMBOL vmlinux 0x79c94348 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x79f190b3 page_readlink +EXPORT_SYMBOL vmlinux 0x7a033125 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x7a10107a open_by_devnum +EXPORT_SYMBOL vmlinux 0x7a18338a svc_authenticate +EXPORT_SYMBOL vmlinux 0x7a20d62a page_put_link +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7ab873e2 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x7b0609f1 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x7b099899 __seq_open_private +EXPORT_SYMBOL vmlinux 0x7b0b805d nla_append +EXPORT_SYMBOL vmlinux 0x7b283b7f do_sync_write +EXPORT_SYMBOL vmlinux 0x7b602c8b elv_next_request +EXPORT_SYMBOL vmlinux 0x7b9351b3 neigh_table_init +EXPORT_SYMBOL vmlinux 0x7c000956 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x7c027e58 d_validate +EXPORT_SYMBOL vmlinux 0x7c1464ce scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c77f59b scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0x7c8ad066 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7cc035a7 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x7cc3bbdb journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x7cd6b8e0 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d18c794 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x7d4e8937 read_cache_page +EXPORT_SYMBOL vmlinux 0x7d54b984 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x7d81f5c9 generic_make_request +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d8c3503 sock_register +EXPORT_SYMBOL vmlinux 0x7dc6d6fe iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7de12dde mpage_writepages +EXPORT_SYMBOL vmlinux 0x7e058bfb xscale_coherent_kern_range +EXPORT_SYMBOL vmlinux 0x7e501d9e pci_pme_capable +EXPORT_SYMBOL vmlinux 0x7e531cde del_timer +EXPORT_SYMBOL vmlinux 0x7e8dada9 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x7e96ec53 register_key_type +EXPORT_SYMBOL vmlinux 0x7e973969 i2c_release_client +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ebc55d5 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x7f005588 ether_setup +EXPORT_SYMBOL vmlinux 0x7f08794f input_register_handle +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f351ccd dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x7f4af0bc blk_rq_init +EXPORT_SYMBOL vmlinux 0x7f5a5453 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x7f63b31e _memcpy_toio +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7f9f8512 kernel_accept +EXPORT_SYMBOL vmlinux 0x7fc18fc7 simple_release_fs +EXPORT_SYMBOL vmlinux 0x800e4ffa __muldi3 +EXPORT_SYMBOL vmlinux 0x8042aee5 gpio_line_get +EXPORT_SYMBOL vmlinux 0x8047a8b2 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x8058e63e dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x80722201 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x8085c7b1 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x80b48a05 pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x80c3d35c seq_bitmap +EXPORT_SYMBOL vmlinux 0x80c639b3 bdevname +EXPORT_SYMBOL vmlinux 0x80d64f8e tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x80ddbd1a seq_open +EXPORT_SYMBOL vmlinux 0x80f7e537 give_up_console +EXPORT_SYMBOL vmlinux 0x812e868e bio_map_user +EXPORT_SYMBOL vmlinux 0x813eeef8 d_add_ci +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x816d13eb __bforget +EXPORT_SYMBOL vmlinux 0x816dfe9d __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x81bd74b5 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x81e07bbc __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x81e65667 sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x81e7e1b0 tcf_exts_change +EXPORT_SYMBOL vmlinux 0x81f7e3d6 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x8207587c get_unmapped_area +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x82100316 sk_receive_skb +EXPORT_SYMBOL vmlinux 0x821d0d80 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x8228d25b ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x82490fa6 km_policy_notify +EXPORT_SYMBOL vmlinux 0x824ca9e1 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82692209 kref_set +EXPORT_SYMBOL vmlinux 0x82b49d7a scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x82d6349a task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x82e5a238 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x830c6d57 input_event +EXPORT_SYMBOL vmlinux 0x8320bea8 __umodsi3 +EXPORT_SYMBOL vmlinux 0x833e800c nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x835a2e45 dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83b2bf6f svc_sock_update_bufs +EXPORT_SYMBOL vmlinux 0x83ffbe92 netdev_state_change +EXPORT_SYMBOL vmlinux 0x8429ae7e neigh_seq_next +EXPORT_SYMBOL vmlinux 0x8432744e skb_put +EXPORT_SYMBOL vmlinux 0x8452188a __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x845972c5 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x84870dc5 textsearch_destroy +EXPORT_SYMBOL vmlinux 0x848d14b9 send_sig_info +EXPORT_SYMBOL vmlinux 0x84a00280 blk_insert_request +EXPORT_SYMBOL vmlinux 0x84b183ae strncmp +EXPORT_SYMBOL vmlinux 0x84cf67ed simple_transaction_release +EXPORT_SYMBOL vmlinux 0x8505d919 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x8509cdbb submit_bio +EXPORT_SYMBOL vmlinux 0x850df780 file_permission +EXPORT_SYMBOL vmlinux 0x852ea482 unregister_netdev +EXPORT_SYMBOL vmlinux 0x854017ff scsi_remove_target +EXPORT_SYMBOL vmlinux 0x8542df23 svc_auth_register +EXPORT_SYMBOL vmlinux 0x854398de inet_register_protosw +EXPORT_SYMBOL vmlinux 0x854d2d8f ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x856c1571 inode_init_once +EXPORT_SYMBOL vmlinux 0x858559fc bdget +EXPORT_SYMBOL vmlinux 0x8585c25e bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x85a5797c blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x85ac7f10 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x85ad2018 get_super +EXPORT_SYMBOL vmlinux 0x85b9c3a6 mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0x85d30fad ip_setsockopt +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e5ee9f gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x8610378c sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x8618d9a6 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x8647dac3 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x869f5618 ide_execute_command +EXPORT_SYMBOL vmlinux 0x86a854c1 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x86c7f35a tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x86ea3194 pci_get_subsys +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x87386f36 xfrm_input +EXPORT_SYMBOL vmlinux 0x8771b6ac journal_errno +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x878dfcb3 register_chrdev +EXPORT_SYMBOL vmlinux 0x87c7f69c nobh_writepage +EXPORT_SYMBOL vmlinux 0x87cac296 kernel_connect +EXPORT_SYMBOL vmlinux 0x87e97586 dcache_dir_open +EXPORT_SYMBOL vmlinux 0x87fd1ebc nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x884f97c1 simple_unlink +EXPORT_SYMBOL vmlinux 0x88640ef7 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x88b7267d inet_getname +EXPORT_SYMBOL vmlinux 0x88bfebfe block_commit_write +EXPORT_SYMBOL vmlinux 0x88cccb77 arp_tbl +EXPORT_SYMBOL vmlinux 0x88e10dab dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0x89016737 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x891e32b8 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x896b96df tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x8975a64b xdr_write_pages +EXPORT_SYMBOL vmlinux 0x897c3a77 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x8a0ed75b pcim_iomap +EXPORT_SYMBOL vmlinux 0x8a1203a9 kref_get +EXPORT_SYMBOL vmlinux 0x8a4fa83b __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x8a724571 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a846aa8 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x8a8f9aed dev_change_flags +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8adf1ea5 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x8b25ad4b ide_raw_taskfile +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b701395 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x8b9a4149 ida_destroy +EXPORT_SYMBOL vmlinux 0x8ba1d652 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x8bb1d390 neigh_compat_output +EXPORT_SYMBOL vmlinux 0x8bbade49 put_disk +EXPORT_SYMBOL vmlinux 0x8bbfa2b9 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x8bf1e142 gpio_line_set +EXPORT_SYMBOL vmlinux 0x8bf79f89 struct_module +EXPORT_SYMBOL vmlinux 0x8c131ba4 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x8c5c88e7 pci_find_device +EXPORT_SYMBOL vmlinux 0x8c7bc348 ida_remove +EXPORT_SYMBOL vmlinux 0x8c84069c restore_time_delta +EXPORT_SYMBOL vmlinux 0x8c878cba textsearch_register +EXPORT_SYMBOL vmlinux 0x8ccab211 submit_bh +EXPORT_SYMBOL vmlinux 0x8cccdf43 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x8d0b801a mpage_readpages +EXPORT_SYMBOL vmlinux 0x8d2f2370 path_put +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d43fc36 xdr_shift_buf +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5642fc wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x8d617e16 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d7e1073 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x8db82791 skb_queue_purge +EXPORT_SYMBOL vmlinux 0x8dcb5c27 idr_remove +EXPORT_SYMBOL vmlinux 0x8dd8cca9 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x8dd9b7ed dma_free_coherent +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e2c0b1f qdisc_destroy +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e44e1ee netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x8e48b5e6 sock_wake_async +EXPORT_SYMBOL vmlinux 0x8e5f1f48 invalidate_bdev +EXPORT_SYMBOL vmlinux 0x8e6e534a elv_abort_queue +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e79f0d2 elevator_init +EXPORT_SYMBOL vmlinux 0x8ede2767 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x8f07d8ca __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8f29c0c8 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x8f3374a9 xdr_enter_page +EXPORT_SYMBOL vmlinux 0x8f38225a journal_destroy +EXPORT_SYMBOL vmlinux 0x8f3e855c simple_write_end +EXPORT_SYMBOL vmlinux 0x8f44f4b5 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x8f684844 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f80a57f handle_sysrq +EXPORT_SYMBOL vmlinux 0x8f9b86b2 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x8fe5aaea clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x8ffd34c4 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x901d4f27 pci_scan_slot +EXPORT_SYMBOL vmlinux 0x905d672e xdr_inline_pages +EXPORT_SYMBOL vmlinux 0x906ad67c request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x90c5039e generic_file_llseek +EXPORT_SYMBOL vmlinux 0x90d1d034 textsearch_unregister +EXPORT_SYMBOL vmlinux 0x90e93cb4 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x911a2353 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0x9142fd6a try_to_release_page +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x914966ee pcim_iomap_table +EXPORT_SYMBOL vmlinux 0x919029aa __readwrite_bug +EXPORT_SYMBOL vmlinux 0x91a2b758 pci_dev_driver +EXPORT_SYMBOL vmlinux 0x920bbda4 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x920e5a5c qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0x926241f2 wake_up_process +EXPORT_SYMBOL vmlinux 0x926401f2 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x928eb60a seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x92c0d3d8 netdev_set_master +EXPORT_SYMBOL vmlinux 0x92dbb6bb xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x92fb9a42 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x9359e259 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x9379ec5c blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x93803e81 load_nls +EXPORT_SYMBOL vmlinux 0x93858ccb journal_lock_updates +EXPORT_SYMBOL vmlinux 0x9394f495 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93ac70bf sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x93c56527 pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93ed2a7c vfs_writev +EXPORT_SYMBOL vmlinux 0x93f6ddfd ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x943414dd vfs_write +EXPORT_SYMBOL vmlinux 0x943ce636 dput +EXPORT_SYMBOL vmlinux 0x9482e3ef skb_append +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x9501d078 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x952c78dd __scm_destroy +EXPORT_SYMBOL vmlinux 0x95408fa9 uart_update_timeout +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x95969a5b iget_locked +EXPORT_SYMBOL vmlinux 0x95aa3314 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x95dbe078 __get_user_2 +EXPORT_SYMBOL vmlinux 0x95e4255c proc_dostring +EXPORT_SYMBOL vmlinux 0x9620125f kernel_getsockname +EXPORT_SYMBOL vmlinux 0x96405e9b update_region +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x96908270 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96df5482 walk_stackframe +EXPORT_SYMBOL vmlinux 0x9718430b __nla_put +EXPORT_SYMBOL vmlinux 0x97255bdf strlen +EXPORT_SYMBOL vmlinux 0x974bba43 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x974fd8b1 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x975cd552 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x978e2350 input_set_capability +EXPORT_SYMBOL vmlinux 0x97c14ecc mpage_readpage +EXPORT_SYMBOL vmlinux 0x97f71f01 page_symlink +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x98690197 journal_extend +EXPORT_SYMBOL vmlinux 0x986cd2cb dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x988c3f76 devm_request_irq +EXPORT_SYMBOL vmlinux 0x988e8675 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x98965494 input_get_keycode +EXPORT_SYMBOL vmlinux 0x98c73192 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x98cb32b2 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x98d7b7c5 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x9943fc37 alloc_file +EXPORT_SYMBOL vmlinux 0x9960d4ab journal_update_format +EXPORT_SYMBOL vmlinux 0x998a9776 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x999b569a should_remove_suid +EXPORT_SYMBOL vmlinux 0x999c3148 __raw_readsb +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aa1961 scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bb8806 memmove +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99d0dbf0 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x99e15973 scsi_execute +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x9a0389ec proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x9a108cd3 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a9aee1a lease_get_mtime +EXPORT_SYMBOL vmlinux 0x9aba908b write_inode_now +EXPORT_SYMBOL vmlinux 0x9ac0732c mii_check_link +EXPORT_SYMBOL vmlinux 0x9ada948d d_delete +EXPORT_SYMBOL vmlinux 0x9ae7b1b3 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x9b19f8ae generic_listxattr +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b4461b0 scsi_init_io +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9c10bc1f sync_page_range +EXPORT_SYMBOL vmlinux 0x9c2571f4 __down_read +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c8c0fd4 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x9cabe8c8 vfs_rmdir +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cbbefd7 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x9ccadead svc_proc_register +EXPORT_SYMBOL vmlinux 0x9cd41d7a __f_setown +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9cf6f32c svc_reserve +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d34f7dc tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x9d54c57b kill_litter_super +EXPORT_SYMBOL vmlinux 0x9d627618 nonseekable_open +EXPORT_SYMBOL vmlinux 0x9d669763 memcpy +EXPORT_SYMBOL vmlinux 0x9d6d5cfb kmem_cache_create +EXPORT_SYMBOL vmlinux 0x9d792451 unlock_page +EXPORT_SYMBOL vmlinux 0x9d82b851 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x9d8348fb scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x9d83c1db qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x9dac9762 sock_release +EXPORT_SYMBOL vmlinux 0x9dacf83e do_munmap +EXPORT_SYMBOL vmlinux 0x9dbbf45d i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x9dfd1e84 open_exec +EXPORT_SYMBOL vmlinux 0x9e120414 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e80988f tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x9e91bde0 generic_unplug_device +EXPORT_SYMBOL vmlinux 0x9ea5ce0a unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x9eb4b161 sock_i_uid +EXPORT_SYMBOL vmlinux 0x9ed4da98 dma_pool_free +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9ed9448b tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9efdfb0d gpio_line_config +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f2943b6 sk_run_filter +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f5a715c vfs_rename +EXPORT_SYMBOL vmlinux 0x9f8b04b5 kernel_bind +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fd6cf48 unregister_key_type +EXPORT_SYMBOL vmlinux 0x9fe50ac4 scsi_get_command +EXPORT_SYMBOL vmlinux 0xa003dcd5 scsi_scan_target +EXPORT_SYMBOL vmlinux 0xa01c3cbf vfs_readv +EXPORT_SYMBOL vmlinux 0xa03c2f51 locks_remove_posix +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa0679fdd kern_path +EXPORT_SYMBOL vmlinux 0xa06b74c4 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0xa07a8d22 sleep_on +EXPORT_SYMBOL vmlinux 0xa07ac24b irq_stat +EXPORT_SYMBOL vmlinux 0xa08b01d3 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0xa095ca92 svc_create +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0e0c8dd input_free_device +EXPORT_SYMBOL vmlinux 0xa0ebab88 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108608e try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa141f8b2 proc_dointvec +EXPORT_SYMBOL vmlinux 0xa165b48a xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xa1720011 unlock_new_inode +EXPORT_SYMBOL vmlinux 0xa17bcd37 d_path +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1ee1051 pcim_iounmap +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa218bf61 complete +EXPORT_SYMBOL vmlinux 0xa23188a2 unlock_super +EXPORT_SYMBOL vmlinux 0xa29b1708 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xa2a323cc dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2f65515 skb_recycle_check +EXPORT_SYMBOL vmlinux 0xa2f8ca5a seq_release_private +EXPORT_SYMBOL vmlinux 0xa3009078 __dst_free +EXPORT_SYMBOL vmlinux 0xa3147586 user_path_at +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa3934b74 xdr_buf_subsegment +EXPORT_SYMBOL vmlinux 0xa3974f28 bdi_destroy +EXPORT_SYMBOL vmlinux 0xa3a4ed03 cond_resched_lock +EXPORT_SYMBOL vmlinux 0xa3c3dd39 page_follow_link_light +EXPORT_SYMBOL vmlinux 0xa40e8f25 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0xa4324111 scsi_dma_map +EXPORT_SYMBOL vmlinux 0xa474adaf do_sync_read +EXPORT_SYMBOL vmlinux 0xa486fb03 netif_device_attach +EXPORT_SYMBOL vmlinux 0xa4b3fe46 tty_throttle +EXPORT_SYMBOL vmlinux 0xa4fbc339 auth_domain_put +EXPORT_SYMBOL vmlinux 0xa51c5910 nf_register_hook +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa5808bbf tasklet_init +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5affb34 find_or_create_page +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5d747d2 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xa5f57602 pagevec_lookup +EXPORT_SYMBOL vmlinux 0xa64179c6 genl_register_ops +EXPORT_SYMBOL vmlinux 0xa653c32b elv_rb_add +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6985b2e pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xa6be363a test_set_page_writeback +EXPORT_SYMBOL vmlinux 0xa6c684c1 __iop3xx_ioremap +EXPORT_SYMBOL vmlinux 0xa6ca21e8 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e05496 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa757a7f1 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xa797ae32 filemap_flush +EXPORT_SYMBOL vmlinux 0xa7998d48 pci_get_class +EXPORT_SYMBOL vmlinux 0xa79e3f7e pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xa79ef9a6 fput +EXPORT_SYMBOL vmlinux 0xa7a04602 block_read_full_page +EXPORT_SYMBOL vmlinux 0xa7b405c5 skb_free_datagram +EXPORT_SYMBOL vmlinux 0xa7b599fc find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xa7b91a7b lockd_down +EXPORT_SYMBOL vmlinux 0xa7baf58d blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0xa7df1bf8 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xa824f402 filp_close +EXPORT_SYMBOL vmlinux 0xa83e04c3 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0xa862cac7 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0xa891b2a9 may_umount_tree +EXPORT_SYMBOL vmlinux 0xa895d3b0 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xa8d15ebe request_key +EXPORT_SYMBOL vmlinux 0xa8d94e01 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0xa8e45158 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0xa9015338 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa9306d26 nf_register_hooks +EXPORT_SYMBOL vmlinux 0xa93d0b4f devm_ioport_map +EXPORT_SYMBOL vmlinux 0xa9944f5b scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0xa9a32d20 udp_proc_register +EXPORT_SYMBOL vmlinux 0xa9bdb649 bdi_register +EXPORT_SYMBOL vmlinux 0xa9f1ed23 bit_waitqueue +EXPORT_SYMBOL vmlinux 0xa9f7d386 register_netdev +EXPORT_SYMBOL vmlinux 0xaa02f858 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0xaa13a820 register_gifconf +EXPORT_SYMBOL vmlinux 0xaa265906 dev_get_by_name +EXPORT_SYMBOL vmlinux 0xaa527612 __kfifo_put +EXPORT_SYMBOL vmlinux 0xaab4ab01 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0xaae65409 read_cache_page_async +EXPORT_SYMBOL vmlinux 0xaae9546a bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xab31949d pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xab3c7293 __ip_select_ident +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab53b0a8 mempool_alloc +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab64527d mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0xab680c96 __down_read_trylock +EXPORT_SYMBOL vmlinux 0xab6abab7 inet_frag_find +EXPORT_SYMBOL vmlinux 0xab80a8bc nf_log_register +EXPORT_SYMBOL vmlinux 0xabad83d7 udp_hash_lock +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabfad977 xdr_decode_array2 +EXPORT_SYMBOL vmlinux 0xac20c895 register_con_driver +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac495f98 neigh_parms_release +EXPORT_SYMBOL vmlinux 0xac54fc9f mempool_destroy +EXPORT_SYMBOL vmlinux 0xac5f113d cpu_all_bits +EXPORT_SYMBOL vmlinux 0xac7b8c95 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0xac7e7280 rpc_queue_upcall +EXPORT_SYMBOL vmlinux 0xac84f137 dev_driver_string +EXPORT_SYMBOL vmlinux 0xac89602c __devm_request_region +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xace4e6da pid_task +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad0ad362 journal_start_commit +EXPORT_SYMBOL vmlinux 0xad131fd1 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xad469779 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0xad66a494 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xad87799e qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0xadb60fb7 vfs_symlink +EXPORT_SYMBOL vmlinux 0xadb792c2 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0xadbe0a29 __rta_fill +EXPORT_SYMBOL vmlinux 0xadc91e21 __iop3xx_iounmap +EXPORT_SYMBOL vmlinux 0xadecd775 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0xadfb0457 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xadfdcd1d bio_unmap_user +EXPORT_SYMBOL vmlinux 0xae13539d proto_register +EXPORT_SYMBOL vmlinux 0xae40d985 close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xae7f3459 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed013b9 posix_acl_valid +EXPORT_SYMBOL vmlinux 0xaed9808a remove_inode_hash +EXPORT_SYMBOL vmlinux 0xaedb8d87 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0xaf1eaff7 ndisc_mc_map +EXPORT_SYMBOL vmlinux 0xaf2f3cbb tty_register_ldisc +EXPORT_SYMBOL vmlinux 0xaf3affe6 inet_addr_type +EXPORT_SYMBOL vmlinux 0xaf400b7b mnt_unpin +EXPORT_SYMBOL vmlinux 0xaf438976 get_disk +EXPORT_SYMBOL vmlinux 0xaf50e76d elf_set_personality +EXPORT_SYMBOL vmlinux 0xaf5d3431 dev_load +EXPORT_SYMBOL vmlinux 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL vmlinux 0xaf79aedb posix_acl_permission +EXPORT_SYMBOL vmlinux 0xaf8aa518 system_rev +EXPORT_SYMBOL vmlinux 0xafd5c8fb lock_rename +EXPORT_SYMBOL vmlinux 0xafdc3ee0 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0xafe2504f scsi_register_interface +EXPORT_SYMBOL vmlinux 0xb016c956 kill_pgrp +EXPORT_SYMBOL vmlinux 0xb0359d22 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0xb05bf114 vmap +EXPORT_SYMBOL vmlinux 0xb09ff4bb vfs_llseek +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb1068d10 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0xb120898d sock_no_bind +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb128de38 pci_set_master +EXPORT_SYMBOL vmlinux 0xb12c2c30 inet_stream_ops +EXPORT_SYMBOL vmlinux 0xb12dd691 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0xb1334813 vfs_getattr +EXPORT_SYMBOL vmlinux 0xb18f3f06 ide_xfer_verbose +EXPORT_SYMBOL vmlinux 0xb1948c7e simple_fill_super +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cb9706 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xb1d385e3 start_tty +EXPORT_SYMBOL vmlinux 0xb22404d0 cdev_add +EXPORT_SYMBOL vmlinux 0xb22d42d3 __invalidate_device +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb2594428 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0xb25f0aeb bd_set_size +EXPORT_SYMBOL vmlinux 0xb267b638 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xb2906944 key_payload_reserve +EXPORT_SYMBOL vmlinux 0xb2bf1312 __up_read +EXPORT_SYMBOL vmlinux 0xb2eec919 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0xb2fddbf1 file_update_time +EXPORT_SYMBOL vmlinux 0xb34f5553 kthread_create +EXPORT_SYMBOL vmlinux 0xb367512e dev_set_mac_address +EXPORT_SYMBOL vmlinux 0xb3707358 journal_load +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb37ad437 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3bb7d99 file_remove_suid +EXPORT_SYMBOL vmlinux 0xb3d69fcb input_register_handler +EXPORT_SYMBOL vmlinux 0xb3e9a2c4 kill_anon_super +EXPORT_SYMBOL vmlinux 0xb3fe02b1 down_write +EXPORT_SYMBOL vmlinux 0xb41ed261 blk_init_queue +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb424d2c0 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xb44818c0 devm_iounmap +EXPORT_SYMBOL vmlinux 0xb449af53 kmalloc_caches +EXPORT_SYMBOL vmlinux 0xb455adc4 generic_read_dir +EXPORT_SYMBOL vmlinux 0xb4a0e989 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0xb4a5c53f iget5_locked +EXPORT_SYMBOL vmlinux 0xb4c6aad4 sk_wait_data +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb5251cd3 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xb534763c sg_free_table +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb55ffe4f block_write_full_page +EXPORT_SYMBOL vmlinux 0xb56c9d6b init_net +EXPORT_SYMBOL vmlinux 0xb57be3ad inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0xb597b34f per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5f0e709 dev_disable_lro +EXPORT_SYMBOL vmlinux 0xb5f55e75 pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb619bbf3 bio_put +EXPORT_SYMBOL vmlinux 0xb6283508 __lock_page +EXPORT_SYMBOL vmlinux 0xb6289668 release_sock +EXPORT_SYMBOL vmlinux 0xb656128b xdr_encode_array2 +EXPORT_SYMBOL vmlinux 0xb66263e8 pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6c0738c mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c70a7d __wake_up +EXPORT_SYMBOL vmlinux 0xb6f55652 kick_iocb +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb71d09c6 eth_type_trans +EXPORT_SYMBOL vmlinux 0xb7339c57 __find_get_block +EXPORT_SYMBOL vmlinux 0xb74023f6 journal_clear_err +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb79704d2 ll_rw_block +EXPORT_SYMBOL vmlinux 0xb798898c __napi_schedule +EXPORT_SYMBOL vmlinux 0xb7aa1ee1 get_io_context +EXPORT_SYMBOL vmlinux 0xb7ad3321 ida_init +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7c79a44 pci_find_slot +EXPORT_SYMBOL vmlinux 0xb7cd5624 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0xb7fb6d4a rtnl_unicast +EXPORT_SYMBOL vmlinux 0xb81aa1dc vfs_mkdir +EXPORT_SYMBOL vmlinux 0xb859f38b krealloc +EXPORT_SYMBOL vmlinux 0xb861fbcd devm_free_irq +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb88c0b66 netif_carrier_on +EXPORT_SYMBOL vmlinux 0xb892b915 journal_get_create_access +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8af4f9e pci_fixup_device +EXPORT_SYMBOL vmlinux 0xb8cea3bf xdr_buf_read_netobj +EXPORT_SYMBOL vmlinux 0xb8d2d959 generic_show_options +EXPORT_SYMBOL vmlinux 0xb8e31467 xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0xb8ece8e0 do_splice_to +EXPORT_SYMBOL vmlinux 0xb8f831cf inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb9340404 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0xb95f98d6 _memset_io +EXPORT_SYMBOL vmlinux 0xb97d4c9c mutex_lock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb98ef804 vm_stat +EXPORT_SYMBOL vmlinux 0xb9acd3d9 __put_user_2 +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9db327b xfrm_state_update +EXPORT_SYMBOL vmlinux 0xb9e76ba7 journal_forget +EXPORT_SYMBOL vmlinux 0xba1d8383 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0xba3bda2a __downgrade_write +EXPORT_SYMBOL vmlinux 0xba3bef22 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xba44c926 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba4cbff2 ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0xba4d9ec4 __blk_run_queue +EXPORT_SYMBOL vmlinux 0xba5078fd xscale_flush_kern_cache_all +EXPORT_SYMBOL vmlinux 0xba5a7045 sock_no_poll +EXPORT_SYMBOL vmlinux 0xba5c9cd4 lock_super +EXPORT_SYMBOL vmlinux 0xba72711e notify_change +EXPORT_SYMBOL vmlinux 0xba83d494 ip_fragment +EXPORT_SYMBOL vmlinux 0xba8f8b68 completion_done +EXPORT_SYMBOL vmlinux 0xba9c40d7 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0xbaba703c complete_request_key +EXPORT_SYMBOL vmlinux 0xbabce3e7 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0xbaf48be3 journal_wipe +EXPORT_SYMBOL vmlinux 0xbafc6812 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0xbb0be76a copy_strings_kernel +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb24011d svc_exit_thread +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb648902 sock_init_data +EXPORT_SYMBOL vmlinux 0xbb71334b xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xbb72d4fe __put_user_1 +EXPORT_SYMBOL vmlinux 0xbb8efb43 tty_devnum +EXPORT_SYMBOL vmlinux 0xbba4ffc0 inet6_release +EXPORT_SYMBOL vmlinux 0xbbb06490 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbd0bb81 input_grab_device +EXPORT_SYMBOL vmlinux 0xbbdf0fb6 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0xbbf6d6d0 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xbc07223c bio_sector_offset +EXPORT_SYMBOL vmlinux 0xbc10dd97 __put_user_4 +EXPORT_SYMBOL vmlinux 0xbc2503aa inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xbc3a0b58 pci_pme_active +EXPORT_SYMBOL vmlinux 0xbc4000df inetdev_by_index +EXPORT_SYMBOL vmlinux 0xbc537898 input_allocate_device +EXPORT_SYMBOL vmlinux 0xbccb2c9c sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xbcd61869 sync_inode +EXPORT_SYMBOL vmlinux 0xbd161b01 ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xbd3080e4 pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0xbd418578 sunrpc_cache_lookup +EXPORT_SYMBOL vmlinux 0xbd7b7028 seq_lseek +EXPORT_SYMBOL vmlinux 0xbda741c8 fget +EXPORT_SYMBOL vmlinux 0xbdf2580d __raw_readsl +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe498a4e blk_register_region +EXPORT_SYMBOL vmlinux 0xbe5684c9 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe656942 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0xbe82135b cad_pid +EXPORT_SYMBOL vmlinux 0xbe8a589d scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0xbe8d9499 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xbebfa174 mii_link_ok +EXPORT_SYMBOL vmlinux 0xbecf13f2 pagecache_write_end +EXPORT_SYMBOL vmlinux 0xbed3c21b read_cache_pages +EXPORT_SYMBOL vmlinux 0xbedb476c dma_async_device_register +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbef4bcd4 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xbefc05ab pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0xbf121aa6 sock_create_lite +EXPORT_SYMBOL vmlinux 0xbf555fef devm_ioremap +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfb3e5b7 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xbfc245c7 vfs_create +EXPORT_SYMBOL vmlinux 0xbfcceb13 input_flush_device +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xbff4f9b2 skb_unlink +EXPORT_SYMBOL vmlinux 0xc042b458 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc05677cf scsi_device_resume +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc09248f8 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0xc096a389 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xc0a9b010 nf_getsockopt +EXPORT_SYMBOL vmlinux 0xc0b92264 dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0xc0d7c774 skb_dma_map +EXPORT_SYMBOL vmlinux 0xc0fa5268 svc_set_client +EXPORT_SYMBOL vmlinux 0xc10a7093 inet_accept +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc15a3024 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xc1601a4f _change_bit_le +EXPORT_SYMBOL vmlinux 0xc161c42c bio_init +EXPORT_SYMBOL vmlinux 0xc17c460b tcp_hashinfo +EXPORT_SYMBOL vmlinux 0xc1a77870 xfrm_init_state +EXPORT_SYMBOL vmlinux 0xc1b1db54 bio_kmalloc +EXPORT_SYMBOL vmlinux 0xc1ba898e sock_no_ioctl +EXPORT_SYMBOL vmlinux 0xc1bf37bb __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0xc1fc4511 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0xc21b4609 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0xc22616f1 __init_rwsem +EXPORT_SYMBOL vmlinux 0xc244467f redraw_screen +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc27487dd __bug +EXPORT_SYMBOL vmlinux 0xc2b9bd50 cache_register +EXPORT_SYMBOL vmlinux 0xc2bdd2ed set_bdi_congested +EXPORT_SYMBOL vmlinux 0xc2dc1ce7 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2ef9b56 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xc3520f8f keyring_search +EXPORT_SYMBOL vmlinux 0xc359fb65 abort +EXPORT_SYMBOL vmlinux 0xc362326c simple_sync_file +EXPORT_SYMBOL vmlinux 0xc3669046 svc_recv +EXPORT_SYMBOL vmlinux 0xc3672e61 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL vmlinux 0xc38f65f4 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0xc3cdaefb tty_unthrottle +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3e401f6 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0xc41fc953 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xc42ff603 default_llseek +EXPORT_SYMBOL vmlinux 0xc440c451 sg_alloc_table +EXPORT_SYMBOL vmlinux 0xc454a912 tty_register_driver +EXPORT_SYMBOL vmlinux 0xc465c9d5 sock_no_connect +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc5461728 bdget_disk +EXPORT_SYMBOL vmlinux 0xc5617cfc neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xc57ad0e4 pcibios_fixup_bus +EXPORT_SYMBOL vmlinux 0xc57c0918 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0xc591bbd7 skb_checksum +EXPORT_SYMBOL vmlinux 0xc598347a netlink_broadcast +EXPORT_SYMBOL vmlinux 0xc5a532f4 del_gendisk +EXPORT_SYMBOL vmlinux 0xc5a84100 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xc5bf65b2 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0xc5ebb2a3 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xc633495b schedule_work +EXPORT_SYMBOL vmlinux 0xc6361755 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0xc68d52e5 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xc6a8f8d3 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0xc7010763 blk_init_tags +EXPORT_SYMBOL vmlinux 0xc71613b5 ip_dev_find +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc722227e posix_acl_clone +EXPORT_SYMBOL vmlinux 0xc75b9f90 ide_end_drive_cmd +EXPORT_SYMBOL vmlinux 0xc766cad8 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7adaff3 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xc7d78ef6 kthread_bind +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc806e2cd blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xc80de694 down_write_trylock +EXPORT_SYMBOL vmlinux 0xc814b4cd inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xc87e10a5 datagram_poll +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8be701e map_destroy +EXPORT_SYMBOL vmlinux 0xc8bf3b6f i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xc8e96dea qword_addhex +EXPORT_SYMBOL vmlinux 0xc8fd97e3 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0xc91810e9 input_release_device +EXPORT_SYMBOL vmlinux 0xc91ec12c tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xc9944cd7 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc99e045b devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0xc99e40dc skb_pad +EXPORT_SYMBOL vmlinux 0xc9c52e1b __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xca3a4ae8 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xcb0bcf7d neigh_connected_output +EXPORT_SYMBOL vmlinux 0xcb29e17a blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb41b20e __brelse +EXPORT_SYMBOL vmlinux 0xcb5b2fb1 filp_open +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7cb7ab inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xcb9c644f __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xcbad705b register_netdevice +EXPORT_SYMBOL vmlinux 0xcbbe602a pci_disable_device +EXPORT_SYMBOL vmlinux 0xcbe0acbb inet_release +EXPORT_SYMBOL vmlinux 0xcc0e8f12 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc3a625b init_task +EXPORT_SYMBOL vmlinux 0xcc492bd5 block_write_end +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc8623a8 sk_reset_timer +EXPORT_SYMBOL vmlinux 0xcc9fbe29 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xccbcafff have_submounts +EXPORT_SYMBOL vmlinux 0xcccca482 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0xcccf68ac sg_miter_stop +EXPORT_SYMBOL vmlinux 0xccdf769f d_rehash +EXPORT_SYMBOL vmlinux 0xccfa02dc cancel_dirty_page +EXPORT_SYMBOL vmlinux 0xccfe4bdd scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xcd63c845 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0xcdbee101 skb_pull +EXPORT_SYMBOL vmlinux 0xcdef084f simple_write_begin +EXPORT_SYMBOL vmlinux 0xce10574b inet6_register_protosw +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce5db577 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0xce910277 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0xce9518ff nlmsg_notify +EXPORT_SYMBOL vmlinux 0xce98eb7c journal_ack_err +EXPORT_SYMBOL vmlinux 0xce9a042f lease_modify +EXPORT_SYMBOL vmlinux 0xcecba943 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xcef201cd get_iop_tick_rate +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf19e9d6 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0xcf45c676 tcp_splice_read +EXPORT_SYMBOL vmlinux 0xcf5f77e4 tcp_prot +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfe76536 I_BDEV +EXPORT_SYMBOL vmlinux 0xcff1521e __secpath_destroy +EXPORT_SYMBOL vmlinux 0xcff53400 kref_put +EXPORT_SYMBOL vmlinux 0xcffc1a01 inet_frag_kill +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd0484d20 keyring_clear +EXPORT_SYMBOL vmlinux 0xd077861b inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0xd07d44e0 init_buffer +EXPORT_SYMBOL vmlinux 0xd0ac7f04 file_fsync +EXPORT_SYMBOL vmlinux 0xd0ae14cc inet_frags_init +EXPORT_SYMBOL vmlinux 0xd0d71dec xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0xd0d752b7 udp_poll +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd12396a2 put_tty_driver +EXPORT_SYMBOL vmlinux 0xd12950b7 xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0xd168d8b9 cpu_xscale_dcache_clean_area +EXPORT_SYMBOL vmlinux 0xd1da8458 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0xd206e492 sget +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2f69f38 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0xd32d7f67 kset_register +EXPORT_SYMBOL vmlinux 0xd32e52c7 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0xd33a8f2b dev_unicast_add +EXPORT_SYMBOL vmlinux 0xd3427f73 mempool_create_node +EXPORT_SYMBOL vmlinux 0xd364bd33 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0xd36ddbc5 misc_deregister +EXPORT_SYMBOL vmlinux 0xd37e2fec d_invalidate +EXPORT_SYMBOL vmlinux 0xd37ea866 search_binary_handler +EXPORT_SYMBOL vmlinux 0xd3a04760 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0xd3a89b64 create_empty_buffers +EXPORT_SYMBOL vmlinux 0xd3c621d4 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0xd3cdb3ed take_over_console +EXPORT_SYMBOL vmlinux 0xd3dbfbc4 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0xd3e15698 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xd3fbd9e7 key_task_permission +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd4392fcd nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xd44147e4 uart_add_one_port +EXPORT_SYMBOL vmlinux 0xd449cac4 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xd4ba4fad dev_mc_unsync +EXPORT_SYMBOL vmlinux 0xd4c9ae51 scsi_print_result +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd55885b6 dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd5ad07ea tcp_check_req +EXPORT_SYMBOL vmlinux 0xd5c2fff9 mpage_writepage +EXPORT_SYMBOL vmlinux 0xd5cf0604 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0xd5d65e3b blkdev_get +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd61e6d5e svc_prepare_thread +EXPORT_SYMBOL vmlinux 0xd627480b strncat +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd66172c5 skb_queue_tail +EXPORT_SYMBOL vmlinux 0xd66c6228 down_read_trylock +EXPORT_SYMBOL vmlinux 0xd69368db aio_put_req +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd71a6b52 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xd72a9ca1 seq_read +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7b69fae idr_find +EXPORT_SYMBOL vmlinux 0xd7d75c16 scsi_block_requests +EXPORT_SYMBOL vmlinux 0xd7d7e1cf blk_rq_map_user +EXPORT_SYMBOL vmlinux 0xd7ecf2b6 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xd8094ec9 do_map_probe +EXPORT_SYMBOL vmlinux 0xd8282ff0 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0xd8703776 skb_under_panic +EXPORT_SYMBOL vmlinux 0xd870b785 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8b107b2 generic_ro_fops +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd94b64bc request_firmware_nowait +EXPORT_SYMBOL vmlinux 0xd96003ce n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0xd964ed87 blk_unplug +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9b950ea __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0xd9ce8f0c strnlen +EXPORT_SYMBOL vmlinux 0xd9e8f0b1 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xda12b7f4 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda31e721 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0xda5898bd pci_iounmap +EXPORT_SYMBOL vmlinux 0xda5ea696 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0xda6ada72 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xda6c6747 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xda7ca042 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xda8b5096 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xda9ae0ed neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0xdaa40a29 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0xdaa82aa2 end_request +EXPORT_SYMBOL vmlinux 0xdb4cdb0b new_inode +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb9b1aa7 ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0xdba0d122 neigh_destroy +EXPORT_SYMBOL vmlinux 0xdba1d40f xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdc053205 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc18c819 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc392916 nf_hook_slow +EXPORT_SYMBOL vmlinux 0xdc3f6d82 pci_iomap +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc62f829 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0xdc6f0eee scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcd68fb0 input_inject_event +EXPORT_SYMBOL vmlinux 0xdcd76eb9 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xdce161c1 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd1bd7e3 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0xdd27fa87 memchr +EXPORT_SYMBOL vmlinux 0xdd4f4210 kernel_listen +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xddc0d865 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0xdde17266 path_get +EXPORT_SYMBOL vmlinux 0xdde677ed blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde0b6781 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0xde0ec92a input_register_device +EXPORT_SYMBOL vmlinux 0xde385ffc input_close_device +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde9a2e07 cache_unregister +EXPORT_SYMBOL vmlinux 0xde9a7b81 init_special_inode +EXPORT_SYMBOL vmlinux 0xdea57827 dev_alloc_name +EXPORT_SYMBOL vmlinux 0xdebb252b udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0xdec982eb nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0xdecd1ae0 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xdf242e1b call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xdf2cae38 tcp_make_synack +EXPORT_SYMBOL vmlinux 0xdf355f99 journal_revoke +EXPORT_SYMBOL vmlinux 0xdf533862 scsi_add_host +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf7469f8 register_filesystem +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfac4c51 generic_permission +EXPORT_SYMBOL vmlinux 0xdfdf4266 uart_suspend_port +EXPORT_SYMBOL vmlinux 0xe04738a8 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xe04aface dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0878bfe __krealloc +EXPORT_SYMBOL vmlinux 0xe08cb4fa kobject_add +EXPORT_SYMBOL vmlinux 0xe0a73c28 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0c7be94 eth_header_cache +EXPORT_SYMBOL vmlinux 0xe0dba789 xdr_inline_decode +EXPORT_SYMBOL vmlinux 0xe0fb4783 simple_rename +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe122cdeb seq_release +EXPORT_SYMBOL vmlinux 0xe13cb528 scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0xe1496e0e dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0xe17ee316 skb_over_panic +EXPORT_SYMBOL vmlinux 0xe18724a3 generic_delete_inode +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1afdb4a tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xe1b267ef i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xe20249f6 dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0xe218a243 skb_split +EXPORT_SYMBOL vmlinux 0xe225e50d inode_permission +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe2541efe pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0xe2631760 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xe294fd43 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xe2c02ef8 mntput_no_expire +EXPORT_SYMBOL vmlinux 0xe2c3b917 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2d800e3 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0xe2e1c732 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0xe2ea250a sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0xe2f34db9 __alloc_skb +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe31e5069 free_buffer_head +EXPORT_SYMBOL vmlinux 0xe31f6503 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0xe350df3a contig_page_data +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe35c1efb lock_may_write +EXPORT_SYMBOL vmlinux 0xe36ccd63 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0xe3c56095 pci_assign_resource +EXPORT_SYMBOL vmlinux 0xe3f63ca2 remove_arg_zero +EXPORT_SYMBOL vmlinux 0xe402d9a3 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xe415b9ab cfi_varsize_frob +EXPORT_SYMBOL vmlinux 0xe42a4ff3 ip_route_input +EXPORT_SYMBOL vmlinux 0xe441f86e inet_stream_connect +EXPORT_SYMBOL vmlinux 0xe494a3c2 kmem_cache_size +EXPORT_SYMBOL vmlinux 0xe4a97c71 __down_write_trylock +EXPORT_SYMBOL vmlinux 0xe4c80097 cacheid +EXPORT_SYMBOL vmlinux 0xe5492bd6 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0xe566bb0b elv_add_request +EXPORT_SYMBOL vmlinux 0xe570d1b1 skb_copy_expand +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5860c4c bio_clone +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL vmlinux 0xe5c43c62 remove_proc_entry +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5df3c30 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe688c193 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe6c02289 tcf_hash_create +EXPORT_SYMBOL vmlinux 0xe6c3ebb0 __raw_writesw +EXPORT_SYMBOL vmlinux 0xe6c850cb empty_zero_page +EXPORT_SYMBOL vmlinux 0xe6dde77d xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe707d823 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0xe7112df5 key_unlink +EXPORT_SYMBOL vmlinux 0xe72a2659 get_fs_type +EXPORT_SYMBOL vmlinux 0xe7757cbe blk_verify_command +EXPORT_SYMBOL vmlinux 0xe78715db generic_file_direct_write +EXPORT_SYMBOL vmlinux 0xe787b44b generic_setlease +EXPORT_SYMBOL vmlinux 0xe7cf9093 bh_submit_read +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7d7ed5a kernel_read +EXPORT_SYMBOL vmlinux 0xe7d93114 nf_setsockopt +EXPORT_SYMBOL vmlinux 0xe7dda5a7 tty_free_termios +EXPORT_SYMBOL vmlinux 0xe80427df xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0xe81d9c55 pcim_enable_device +EXPORT_SYMBOL vmlinux 0xe81f3af6 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0xe864d393 i2c_probe +EXPORT_SYMBOL vmlinux 0xe8ab39d3 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xe8b1c7c1 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0xe8cd4fdb pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8ce2e46 write_one_page +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9152325 pcibios_resource_to_bus +EXPORT_SYMBOL vmlinux 0xe91d3fe1 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0xe942d464 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe947d384 iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0xe97f4ce5 qword_get +EXPORT_SYMBOL vmlinux 0xe9e5c283 kobject_init +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea5fd3d6 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0xea666618 journal_check_available_features +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xeaaa739f sunrpc_cache_update +EXPORT_SYMBOL vmlinux 0xeabae6bf netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0xeadd25f8 dst_alloc +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeae46d1d xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb623d2a __page_symlink +EXPORT_SYMBOL vmlinux 0xeb69603e scm_fp_dup +EXPORT_SYMBOL vmlinux 0xeb7c20ef wait_on_page_bit +EXPORT_SYMBOL vmlinux 0xeb7c6c98 pskb_expand_head +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xebcd4eef eth_header_parse +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebe973ee key_revoke +EXPORT_SYMBOL vmlinux 0xebf862b1 __grab_cache_page +EXPORT_SYMBOL vmlinux 0xebfdcbdf system_serial_high +EXPORT_SYMBOL vmlinux 0xec1c8454 input_open_device +EXPORT_SYMBOL vmlinux 0xec379e11 textsearch_prepare +EXPORT_SYMBOL vmlinux 0xec402b78 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0xec55ce7c unregister_filesystem +EXPORT_SYMBOL vmlinux 0xec591ea2 i2c_clients_command +EXPORT_SYMBOL vmlinux 0xec5ac21e seq_putc +EXPORT_SYMBOL vmlinux 0xec5e7adb simple_getattr +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec82c464 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0xec8ba972 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xec9cd4c9 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xec9d484f xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0xeca43807 kobject_put +EXPORT_SYMBOL vmlinux 0xecb1a63a scsi_is_host_device +EXPORT_SYMBOL vmlinux 0xecbb1e62 sock_wfree +EXPORT_SYMBOL vmlinux 0xeccbd728 sock_no_listen +EXPORT_SYMBOL vmlinux 0xed02beb3 scsi_register_driver +EXPORT_SYMBOL vmlinux 0xed260e1b set_disk_ro +EXPORT_SYMBOL vmlinux 0xed2a2dff i2c_detach_client +EXPORT_SYMBOL vmlinux 0xed49780e proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xed7538ed simple_pin_fs +EXPORT_SYMBOL vmlinux 0xed83be4f filemap_fault +EXPORT_SYMBOL vmlinux 0xed953ad3 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0xeda73b80 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedcf6be4 qword_add +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd9106d __ashrdi3 +EXPORT_SYMBOL vmlinux 0xededd48e iget_failed +EXPORT_SYMBOL vmlinux 0xedf85867 skb_make_writable +EXPORT_SYMBOL vmlinux 0xee0a0734 xdr_encode_word +EXPORT_SYMBOL vmlinux 0xee273638 journal_force_commit +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee430992 register_binfmt +EXPORT_SYMBOL vmlinux 0xee6d2a72 vfs_follow_link +EXPORT_SYMBOL vmlinux 0xee6fdf0b cpu_online_map +EXPORT_SYMBOL vmlinux 0xee8b663d dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0xee98d931 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xee9fa4ee scsi_host_lookup +EXPORT_SYMBOL vmlinux 0xee9fd334 skb_copy_bits +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeee7fbad dentry_open +EXPORT_SYMBOL vmlinux 0xef1a1668 km_waitq +EXPORT_SYMBOL vmlinux 0xef926823 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0xef9df211 kill_block_super +EXPORT_SYMBOL vmlinux 0xefec0445 scsi_device_put +EXPORT_SYMBOL vmlinux 0xefef0563 dma_pool_create +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf01d79b1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0xf04fb068 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0xf07a794d netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xf0b47479 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0b99b06 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf1013b44 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf19aa8ef pci_find_bus +EXPORT_SYMBOL vmlinux 0xf1cbb17d kmem_cache_name +EXPORT_SYMBOL vmlinux 0xf1d9d162 names_cachep +EXPORT_SYMBOL vmlinux 0xf1dced4c ide_lock +EXPORT_SYMBOL vmlinux 0xf1de54e7 lock_may_read +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1f04f71 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0xf1fe946d __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf285f7d7 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xf292a712 touch_atime +EXPORT_SYMBOL vmlinux 0xf2956409 sock_recvmsg +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2a80b6f generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2b85392 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0xf2d16fb6 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0xf2db72e2 path_lookup +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf32ce17b block_sync_page +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf3473b07 simple_rmdir +EXPORT_SYMBOL vmlinux 0xf397b9aa __tasklet_schedule +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf39cdb7d kmem_cache_free +EXPORT_SYMBOL vmlinux 0xf39d654f xrlim_allow +EXPORT_SYMBOL vmlinux 0xf3beddb0 console_stop +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3ecdd49 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xf44319fe ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xf45e23f8 sock_no_accept +EXPORT_SYMBOL vmlinux 0xf498433c register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xf4a7ddb8 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xf4aa65b0 revalidate_disk +EXPORT_SYMBOL vmlinux 0xf4b9f0e2 dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0xf4d65fdd dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf51821aa genl_sock +EXPORT_SYMBOL vmlinux 0xf5184d53 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xf51c639f interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf563bc30 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xf564412a __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0xf57747a1 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5ceea91 tc_classify +EXPORT_SYMBOL vmlinux 0xf612b6f9 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0xf6933c48 lockd_up +EXPORT_SYMBOL vmlinux 0xf69ffe03 __scsi_put_command +EXPORT_SYMBOL vmlinux 0xf6b96c6e ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6cb2b59 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf7384f52 downgrade_write +EXPORT_SYMBOL vmlinux 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL vmlinux 0xf762293e tty_port_tty_set +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf764dde5 ilookup +EXPORT_SYMBOL vmlinux 0xf77fbb46 idr_remove_all +EXPORT_SYMBOL vmlinux 0xf7802486 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf79eeb8a iunique +EXPORT_SYMBOL vmlinux 0xf7b91b41 freeze_bdev +EXPORT_SYMBOL vmlinux 0xf7ee184f posix_test_lock +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf81def6b __dev_get_by_index +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf8310743 sk_alloc +EXPORT_SYMBOL vmlinux 0xf84fa699 module_put +EXPORT_SYMBOL vmlinux 0xf854f498 scsi_unregister +EXPORT_SYMBOL vmlinux 0xf86b4be8 pci_release_region +EXPORT_SYMBOL vmlinux 0xf86becf2 inet_frags_fini +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf8a978d4 lock_sock_nested +EXPORT_SYMBOL vmlinux 0xf8b8c149 single_open +EXPORT_SYMBOL vmlinux 0xf8c2df1d mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xf8cd7f85 sysctl_intvec +EXPORT_SYMBOL vmlinux 0xf8ce49b7 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xf8dff2f9 vc_cons +EXPORT_SYMBOL vmlinux 0xf8fbb4f0 __bad_xchg +EXPORT_SYMBOL vmlinux 0xf918b36b netif_rx +EXPORT_SYMBOL vmlinux 0xf93cdac9 iput +EXPORT_SYMBOL vmlinux 0xf965acd7 svcauth_unix_set_client +EXPORT_SYMBOL vmlinux 0xf974cd0f bdev_read_only +EXPORT_SYMBOL vmlinux 0xf97fe3ca pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xf9948510 pci_map_rom +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9b28bac interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xf9d82a53 __kill_fasync +EXPORT_SYMBOL vmlinux 0xfa0de1d4 generic_block_bmap +EXPORT_SYMBOL vmlinux 0xfa36374b blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0xfac369f1 blk_get_request +EXPORT_SYMBOL vmlinux 0xfac68eba arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0xfae6488b km_query +EXPORT_SYMBOL vmlinux 0xfae6722a pcibios_bus_to_resource +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb04583e truncate_inode_pages +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb14e6d9 scsi_execute_req +EXPORT_SYMBOL vmlinux 0xfb326a5d down +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb72f638 xscale_flush_user_cache_all +EXPORT_SYMBOL vmlinux 0xfb7d9c45 __udivsi3 +EXPORT_SYMBOL vmlinux 0xfb82aaaa __breadahead +EXPORT_SYMBOL vmlinux 0xfb9a1f66 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0xfbc74f64 __copy_from_user +EXPORT_SYMBOL vmlinux 0xfbf5fbaa blk_sync_queue +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc3800bc get_sb_single +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc421eb9 rtnl_notify +EXPORT_SYMBOL vmlinux 0xfc51450c __break_lease +EXPORT_SYMBOL vmlinux 0xfc533f85 schedule_work_on +EXPORT_SYMBOL vmlinux 0xfc7fc055 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xfc81b555 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcbd88f2 generic_ide_ioctl +EXPORT_SYMBOL vmlinux 0xfccd85a8 write_cache_pages +EXPORT_SYMBOL vmlinux 0xfcd0ba2a bd_release +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfd210ea2 qdisc_list_del +EXPORT_SYMBOL vmlinux 0xfd3ad73b i2c_del_driver +EXPORT_SYMBOL vmlinux 0xfd66449d tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0xfd745da7 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0xfd829404 vfs_readdir +EXPORT_SYMBOL vmlinux 0xfd88559d free_netdev +EXPORT_SYMBOL vmlinux 0xfd88a2b1 block_write_begin +EXPORT_SYMBOL vmlinux 0xfd8dba4c add_wait_queue +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfde3c044 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe16775f idr_destroy +EXPORT_SYMBOL vmlinux 0xfe271510 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xfe3f436a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfeb4a117 tty_register_device +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xfefc301e dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff5e7e77 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xff67b37f __lshrdi3 +EXPORT_SYMBOL vmlinux 0xff6defb7 nf_register_sockopt +EXPORT_SYMBOL vmlinux 0xff6fb4e8 __pagevec_release +EXPORT_SYMBOL vmlinux 0xff851ea8 mapping_tagged +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffe232c9 key_link +EXPORT_SYMBOL vmlinux 0xffe9fcc8 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0xfffd93c9 find_vma +EXPORT_SYMBOL_GPL crypto/aead 0x1b8cbb2d aead_geniv_init +EXPORT_SYMBOL_GPL crypto/aead 0x1cba5241 aead_geniv_exit +EXPORT_SYMBOL_GPL crypto/aead 0x2f6abb04 crypto_alloc_aead +EXPORT_SYMBOL_GPL crypto/aead 0x31854ab5 crypto_grab_aead +EXPORT_SYMBOL_GPL crypto/aead 0x502f977c aead_geniv_alloc +EXPORT_SYMBOL_GPL crypto/aead 0x6f875ad9 crypto_aead_type +EXPORT_SYMBOL_GPL crypto/aead 0x854df34b aead_geniv_free +EXPORT_SYMBOL_GPL crypto/aead 0xe79a10fd crypto_aead_setauthsize +EXPORT_SYMBOL_GPL crypto/aead 0xee28e0a9 crypto_nivaead_type +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x3b993d9d crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x924d99d2 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x84371d32 async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xf447f2d2 async_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x1b6aa8e9 crypto_dequeue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x24560085 crypto_register_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x296d0770 crypto_unregister_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2f663e88 crypto_register_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x30847c87 crypto_enqueue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x50e16f7f crypto_tfm_in_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x58157640 scatterwalk_map +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5f1cced5 scatterwalk_start +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x83553786 scatterwalk_copychunks +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x87343643 crypto_init_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x98292296 crypto_unregister_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9b683b45 scatterwalk_done +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9fb3c4fa crypto_attr_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xb5bafba9 crypto_alloc_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc7ca725f crypto_lookup_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc9d28aa3 crypto_drop_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xcbd15801 crypto_spawn_tfm +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xe572f5ce crypto_register_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xf807fd65 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x06786f6d blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x16857dfe crypto_grab_skcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x290c9f97 skcipher_geniv_free +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x4f618ce0 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x5ac06ed3 blkcipher_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x6dca5f82 skcipher_geniv_exit +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x70ac8f13 skcipher_geniv_init +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x8148d9d8 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x830e91c6 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x8ed73777 crypto_blkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xb2bf0b0e blkcipher_walk_phys +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xcad82135 crypto_givcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xd7d8eb1c blkcipher_walk_virt +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x14e7509f crypto_hash_walk_first +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x8f8f6d84 crypto_ahash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x969396ba crypto_hash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0xbeadc8a6 crypto_hash_walk_done +EXPORT_SYMBOL_GPL crypto/cryptomgr 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/rng 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x94b17efd crypto_rng_type +EXPORT_SYMBOL_GPL crypto/rng 0xd23f9b22 crypto_default_rng +EXPORT_SYMBOL_GPL crypto/twofish_common 0x8bbe0532 twofish_setkey +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x0437931b dm_set_device_limits +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x6fef594e dm_disk +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xa541993b dm_device_name +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xaa4d87df dm_noflush_suspending +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xee69dfb8 dm_put +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x7213eb88 md_new_event +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xc1a84455 md_allow_write +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xe160afb4 sync_page_io +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xe3b51ca1 md_do_sync +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x3a61c43f nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x498a45c5 nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x95954026 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xcf6835f4 nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xed10b5b4 nand_scan +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x09f3c921 wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x0fb71139 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x4f6016af wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x62ba5d02 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x715e54ab wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x8668d134 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xe8d0acee __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x18327cbd wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x217d9642 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x37850c7e wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3996d0ea wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5c6e94ac wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5ca432ad wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x70988f3a __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x763aaaf8 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x8ec206ed wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa01d87b8 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xaa887459 wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb1dd4f38 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb83a910d wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd9f86270 wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xdf6e4f08 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xe4eb861d wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf4ec5e6c wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf728d21d wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1d74e88f uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x22bea17c __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2b121aec uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2ca2059f uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3085c14e uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x32028d96 uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x38d07c3e uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4774aa7f uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x52b9b0e7 uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x56f3addb uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5976f1b2 dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5c845ed7 uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5f82332b uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6a0e4eec uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6b50d3e6 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7674f8a6 uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x77608b24 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7ca759af uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x82a9ddde uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x887cba51 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x92e0eff2 uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x94b2c0b5 uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x967db4cc uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x97561d9d uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa6da6e8a uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaa519764 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaa8bd5ab uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaf9f370c uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb6c49d82 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbd2f97f6 uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc1b2c924 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xcbe6ded5 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd1c67a1f uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd44f6860 uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe4dca2ba uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe94e2826 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf77be771 uwb_rc_ie_add +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x04f264df xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x11fb0ba3 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x133ac60d xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x32f74470 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5bc5439c xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5d424817 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x61017511 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9953dff9 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xc628fe20 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xd15b5968 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0x01ca27cf xt_rateest_lookup +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xe62aee08 xt_rateest_put +EXPORT_SYMBOL_GPL vmlinux 0x0006db13 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x00e3fcf0 get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x018f5f42 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01d1d15e kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL vmlinux 0x01ff4adc ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0x0228cfc1 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0x0230e201 ide_init_disk +EXPORT_SYMBOL_GPL vmlinux 0x024047dd transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x02edcb60 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x0312c0dd tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x0325f609 svc_create_xprt +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04590f5b platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x046448a9 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x04bc5b4f ide_do_start_stop +EXPORT_SYMBOL_GPL vmlinux 0x04c84a6d sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x05131736 ide_pad_transfer +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x0602f3ea platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06508e0a inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x06754a22 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x06c3f367 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x072802dd rpc_call_async +EXPORT_SYMBOL_GPL vmlinux 0x07369ac4 sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07e5b0e9 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x083e8f51 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x086ab268 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x08ab71c6 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x08e7f976 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x0910630f blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x09111de6 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09edd1d4 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x0a352712 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x0a420346 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x0a53a7d1 rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0x0aacc99a ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x0ab4dffa ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0x0ad0f7a8 usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0x0ad15884 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x0ad1cd4b rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x0ad7e6d7 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x0aee0ad9 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x0b8d3406 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x0b9fe456 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x0bb28089 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x0bb62eb1 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x0bd31d4f __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c7315a1 put_rpccred +EXPORT_SYMBOL_GPL vmlinux 0x0c8f50e8 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0x0cd865ee ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x0cdb0dc3 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x0cedd8c1 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x0d7cfe6e device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x0ddada5f tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x0e21c69c fat_remove_entries +EXPORT_SYMBOL_GPL vmlinux 0x0e290f06 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x0e4766fb sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x0e79b8ee generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x0ecbfff1 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x0faa055f rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x0fcf4d09 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x0fe1222a disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x101a0bf8 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x10379deb tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x105be30a rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x108de8d3 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x10d75fe4 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x111dc54a ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x11d7216a sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x11db3a17 rpc_wake_up_next +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x1274353b bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x12b6c4ba regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x12eafdfe devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x12ed4748 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x130887c6 inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x13528855 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x13aa95fe usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x14086da1 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x1451b0cf sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x14688e02 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x14b4f456 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x1534f28e fat_fs_panic +EXPORT_SYMBOL_GPL vmlinux 0x156669df __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x157a72e3 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15da442c ide_input_data +EXPORT_SYMBOL_GPL vmlinux 0x169eba11 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x16a47781 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x17126472 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x17443855 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0x1799b4ad uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x17b1790d init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x17b8d73e sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL vmlinux 0x17d2ece1 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x17d47ad5 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x184b463a register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x18b3478b scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x191fb096 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19abe7ec register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x1a20ca80 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL vmlinux 0x1aa8f04f pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0x1ae46177 ide_end_dequeued_request +EXPORT_SYMBOL_GPL vmlinux 0x1af673df ide_execute_pkt_cmd +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1be85bc8 register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x1c1facc7 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0x1c535be7 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c8c81ca input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x1d1e617e ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x1d31fcd2 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x1d32a7f8 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x1d548444 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x1dc1b8c9 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x1df9bf7e skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x1e0ce788 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x1e1246dd fat_alloc_new_dir +EXPORT_SYMBOL_GPL vmlinux 0x1e5fd5bb do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ec676bb ide_setting_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x1efba8b6 rpc_print_iostats +EXPORT_SYMBOL_GPL vmlinux 0x1f647f8a uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x2006c124 rpcauth_create +EXPORT_SYMBOL_GPL vmlinux 0x201f4d20 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20596565 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0x205f5aa3 ide_port_unregister_devices +EXPORT_SYMBOL_GPL vmlinux 0x20b353c6 unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20d8fee4 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0x21699d07 ide_pci_setup_ports +EXPORT_SYMBOL_GPL vmlinux 0x21cf5717 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x21d57d87 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x221069a0 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x222ecf64 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x226e1055 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x227d0857 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x229c531c __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x22e2c20b atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x22eb3c18 hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x22ef75bd ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x231a3691 rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL vmlinux 0x234a1314 ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x234cff0c ide_legacy_device_add +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x23869dc7 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x23af18a3 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x23cbe8ca page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x23d091db ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x23d551a1 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL vmlinux 0x2407e405 cfi_qry_mode_off +EXPORT_SYMBOL_GPL vmlinux 0x2435905e disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x2464c096 usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x24cda041 ide_vlb_clk +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x24fc47c7 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x2506ada0 rpc_exit_task +EXPORT_SYMBOL_GPL vmlinux 0x250b6e8e __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x251da17d sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x25913fc3 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x25d32fc8 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x25f6abf3 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x25f9f896 regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x2600545b bus_register +EXPORT_SYMBOL_GPL vmlinux 0x264ed4bd hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x26b9eb47 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26e15f89 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL vmlinux 0x26e2e766 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x26eaded6 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x26f55570 ide_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x271e446f dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0x272d498e regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x2766fc0d async_tx_run_dependencies +EXPORT_SYMBOL_GPL vmlinux 0x28b2cc80 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28dc5e93 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x292fc8b4 rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x294a989e usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0x2965a03d crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x296dc612 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x298dc452 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x29b8315a driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x2a22829c rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x2a2d93b7 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x2a31979b ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x2a67e775 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2a74443a scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL vmlinux 0x2b12b9f7 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x2b50e683 rpc_shutdown_client +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2ba10778 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x2ba56f37 usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x2bcf4370 xprt_write_space +EXPORT_SYMBOL_GPL vmlinux 0x2be3af14 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c463444 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x2c715c19 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x2ca5abba ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x2cccf620 ide_retry_pc +EXPORT_SYMBOL_GPL vmlinux 0x2cf1e0fd blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0x2d10da31 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x2d469b5a anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x2d4c8730 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x2d82fdf7 device_del +EXPORT_SYMBOL_GPL vmlinux 0x2da11b0e crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x2dc59477 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x2dd6b797 sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x2e3d08b9 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x2e460db2 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x2e6e30f7 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x2e6f28eb scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x2e7bfcad simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x2e8a860d pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x2e928e18 get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0x2edea14c led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x2eeb008e ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x2f064582 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x2f88cc33 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x2f96196d blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x2f9acd0d ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x300adfad usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x300d0155 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x302ecf64 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0x30413a6a find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x3045a381 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x3048ed8e sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x306aee03 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x308ca230 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x30a86b41 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0x314f8c14 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x31683c27 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x317a77ba inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL vmlinux 0x31ebe309 xdr_skb_read_bits +EXPORT_SYMBOL_GPL vmlinux 0x31f9e158 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x32070c28 exportfs_encode_fh +EXPORT_SYMBOL_GPL vmlinux 0x320b5a7e blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x3239dfa4 rpc_wake_up_status +EXPORT_SYMBOL_GPL vmlinux 0x33286ff2 transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x3369721a blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x338d282e ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x33c2320d inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x33f10df4 rpc_call_null +EXPORT_SYMBOL_GPL vmlinux 0x341b87fe free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x3433dc32 put_device +EXPORT_SYMBOL_GPL vmlinux 0x3434aa87 rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x34442f5f tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x346283fa ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x347c7993 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x349659e9 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x34d17963 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x35310e4e crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x357f8cd2 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x35cf63ff rpc_init_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35d8e3d6 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x35ec7fcb klist_next +EXPORT_SYMBOL_GPL vmlinux 0x35f4c42c kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x36191dfe default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x367af558 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x3693da04 register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x369e6dcb led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x36e597e0 fat_dir_empty +EXPORT_SYMBOL_GPL vmlinux 0x3716d2a7 sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x374a1f46 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x3795a230 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0x380779d7 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x382d8064 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x384cbd8b fat_getattr +EXPORT_SYMBOL_GPL vmlinux 0x387b6a8c lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x38c5c6aa disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x39435a81 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x39819646 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x399dd6f2 ide_pktcmd_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x39f69472 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x3a14f537 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3ae2bdd8 exportfs_decode_fh +EXPORT_SYMBOL_GPL vmlinux 0x3af3a75c ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x3b49a76d sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x3bc33f65 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x3bc66b26 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x3be65a9c inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3bf5d801 driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x3c70f3f6 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3ce91e7f pci_intx +EXPORT_SYMBOL_GPL vmlinux 0x3cec9f20 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x3d1a68eb __async_tx_find_channel +EXPORT_SYMBOL_GPL vmlinux 0x3d594683 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x3d8618fa transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x3e8b137f xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL vmlinux 0x3eaeb974 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x3ef1d739 add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x3ef54874 ide_get_lba_addr +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f383ef7 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x3fab191f usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x4039a99b xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x4073f23c kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x410ce786 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x41143884 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x412e6ee2 hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4150dece debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x416ad205 ide_devset_execute +EXPORT_SYMBOL_GPL vmlinux 0x4173cf4c bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0x41aafdd0 rpc_killall_tasks +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x421fcf32 ide_port_scan +EXPORT_SYMBOL_GPL vmlinux 0x422284f7 mmput +EXPORT_SYMBOL_GPL vmlinux 0x424b105e sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x42632cdc register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x42782203 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL vmlinux 0x42bbf778 driver_register +EXPORT_SYMBOL_GPL vmlinux 0x42c3fad2 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x42ed0b38 nlmclnt_done +EXPORT_SYMBOL_GPL vmlinux 0x42f48b45 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x42fd0737 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x4468ecc5 fat_sync_inode +EXPORT_SYMBOL_GPL vmlinux 0x448f42f9 dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x44a8eb34 ide_check_atapi_device +EXPORT_SYMBOL_GPL vmlinux 0x4508f537 user_read +EXPORT_SYMBOL_GPL vmlinux 0x454c0c9f ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x454d29d8 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x45657b78 rpc_wake_up +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x457dccdc hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x45dfa43c ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x45f4d68e i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x4652a801 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x4668c6cd raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x467963ce xprt_disconnect_done +EXPORT_SYMBOL_GPL vmlinux 0x46c72860 usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x47406659 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x477a95a0 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4788e0a3 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x4794fbf9 xprt_register_transport +EXPORT_SYMBOL_GPL vmlinux 0x47e832cc xprt_lookup_rqst +EXPORT_SYMBOL_GPL vmlinux 0x4896ee64 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0x48eb517e uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x495b18c1 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0x49a2ecf4 sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x49dc0530 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x49df7420 tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x4a10cea8 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x4a36c558 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4aa974a0 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x4ae925ae ide_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x4aef2b37 ide_io_buffers +EXPORT_SYMBOL_GPL vmlinux 0x4b2a2586 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x4b351467 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0x4c3fcde7 ide_read_sff_dma_status +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c8e7947 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x4d2d89e7 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x4d2e6418 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x4dce7be5 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x4dd727a7 pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0x4e0e2608 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x4e17d658 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x4e49aec3 ide_create_request_sense_cmd +EXPORT_SYMBOL_GPL vmlinux 0x4e7d2c15 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x4e8c1f1b put_driver +EXPORT_SYMBOL_GPL vmlinux 0x4ee4caa2 pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0x4ef8ef0b put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x4f70f277 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x4fd47dfd ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x4ff91917 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x50014b1b regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x500b2391 svc_xprt_received +EXPORT_SYMBOL_GPL vmlinux 0x50a3fda8 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e40a26 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50f65ffc rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x515a86c6 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x51b1a65d fat_build_inode +EXPORT_SYMBOL_GPL vmlinux 0x51b8a6f6 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51de3875 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x51f2b482 inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x521bbca7 ide_scsi_expiry +EXPORT_SYMBOL_GPL vmlinux 0x52a71f1f __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL vmlinux 0x537d06eb crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53aa7e9f d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x53bf388b pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x53c0e982 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x53ec386e platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x54648a6d vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x54879bf9 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x548ce359 usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x54b51873 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x5512dd81 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x55175ec1 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x551fb7bb transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5542b913 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x554e6074 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x55b1e7e1 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x5613695c rpc_run_task +EXPORT_SYMBOL_GPL vmlinux 0x562b4c5b vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x56548c43 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x5697017b led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x56b9ab58 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x56d42418 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x57982ed7 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57b146d6 device_register +EXPORT_SYMBOL_GPL vmlinux 0x57b2ecdd devres_add +EXPORT_SYMBOL_GPL vmlinux 0x5844a23f ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x590e0a9f usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x591b03ae ide_host_remove +EXPORT_SYMBOL_GPL vmlinux 0x596a0d88 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59ca3224 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x59d576ef device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x59d700f4 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5a133ff2 mtd_table +EXPORT_SYMBOL_GPL vmlinux 0x5a29015d pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x5a5f8564 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a9498f1 fat_detach +EXPORT_SYMBOL_GPL vmlinux 0x5abe75a7 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5acc326a tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x5b0bca3e sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5b44202f xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x5b72bb0c devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x5b7dae12 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5bd5a619 async_tx_submit +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c0baf03 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x5c58ffec klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5c839e95 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x5c86b402 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x5ca24215 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x5cc44f7e klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d4a4572 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x5d531ad8 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d76e6d3 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x5d7e2f70 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x5d860d30 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e0b518c class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5e2577c1 led_classdev_suspend +EXPORT_SYMBOL_GPL vmlinux 0x5e3493b9 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x5e3b100d class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x5f434e72 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x5fc20e3a debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x5fe0974d rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x60338fe9 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60e5ff4a proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x611353ac regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x61715670 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x618521d6 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x622b3e2c srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x62878161 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x62a93185 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x62e4dd5b usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x62f399c4 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x630e0e81 svc_xprt_init +EXPORT_SYMBOL_GPL vmlinux 0x632e0151 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x6341d1e6 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x638c24db ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x63c6caa9 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x63f39f75 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x643d096a rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x64517785 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x64ffb51d sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x653e92d4 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x656c5411 __class_create +EXPORT_SYMBOL_GPL vmlinux 0x65bd5bfd inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x65df1e4a regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x66856ecb regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x671453e8 xprt_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0x6748bdf1 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x6752a708 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x688e99cc svc_xprt_enqueue +EXPORT_SYMBOL_GPL vmlinux 0x68adc2c6 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x68d5f006 ide_read_status +EXPORT_SYMBOL_GPL vmlinux 0x6973a154 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x697e8fa8 ide_setup_pci_noise +EXPORT_SYMBOL_GPL vmlinux 0x69bc3480 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x69be1557 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x69c8cd11 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x69e149c6 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a3f4f26 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x6ae19890 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x6b220992 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL vmlinux 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL vmlinux 0x6c824706 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x6c8ad7ed regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6c8d7bc8 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x6c9a3ee2 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x6cb0b9f7 fat_time_unix2fat +EXPORT_SYMBOL_GPL vmlinux 0x6ceae65f led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x6cfcc505 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d4f1b98 rpc_clone_client +EXPORT_SYMBOL_GPL vmlinux 0x6d581ae4 rpc_bind_new_program +EXPORT_SYMBOL_GPL vmlinux 0x6d68b63f platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x6ddc3596 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x6e03d7f3 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x6e0b2d36 get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0x6e401a07 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6edbc447 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL vmlinux 0x6edc9cf6 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x6f0fea0d pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x6f8a8f9c cfi_qry_mode_on +EXPORT_SYMBOL_GPL vmlinux 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6fe04fe6 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0x70017292 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x7001cf5c rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x700ad292 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x705507df inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x70594aa9 svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL vmlinux 0x706161b2 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7063538a ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x708fe308 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x70d227eb usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x70e57b30 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x71196147 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x71e75bcb __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x71f9246a leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x721cf8b4 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0x724b2a3c crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x724f7e43 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x7274791d inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x729a5bcc crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x7339db00 pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x73555b55 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x7376394c rpc_restart_call +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73fed78d inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x745bfcb0 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x7486289a init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x748f46bd led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x74bcf12e usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x74de418f simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x75b708f9 rpc_setbufsize +EXPORT_SYMBOL_GPL vmlinux 0x75f8f7f2 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x76242385 rpc_call_start +EXPORT_SYMBOL_GPL vmlinux 0x76436211 ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x7656758e ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7671eb44 fat_attach +EXPORT_SYMBOL_GPL vmlinux 0x7689516b rpc_alloc_iostats +EXPORT_SYMBOL_GPL vmlinux 0x769c4621 platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x7794a010 platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x77bee63b ide_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x77ead783 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x78321a82 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0x783bcba3 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x789d42d0 svc_close_xprt +EXPORT_SYMBOL_GPL vmlinux 0x78a8e38a ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x78af7c8f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x78cf6478 cfi_qry_present +EXPORT_SYMBOL_GPL vmlinux 0x78f000d8 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x7911cf19 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x7948d109 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x797d73e9 ide_pci_init_one +EXPORT_SYMBOL_GPL vmlinux 0x79a7e58e inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x79d2f8a1 usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x79fcb844 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x7a58bcde ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x7a5a62ea usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x7a68c5ab ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x7b764138 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x7b7c51da __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x7bcb4dd8 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x7be8b720 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x7c5a9eff input_class +EXPORT_SYMBOL_GPL vmlinux 0x7c6784ef ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x7c80c6e4 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x7c883027 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x7c96e149 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x7cb56b20 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x7d323414 ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0x7d6a10b1 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0x7d93b9ef rpcauth_init_cred +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL vmlinux 0x7df1b6d5 xprt_reserve_xprt +EXPORT_SYMBOL_GPL vmlinux 0x7e1924b2 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e2d29ec ide_pci_clk +EXPORT_SYMBOL_GPL vmlinux 0x7e562bd4 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e984b69 rpcauth_init_credcache +EXPORT_SYMBOL_GPL vmlinux 0x7e9fc062 usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x7ec784d1 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x7f183887 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x7f31fa36 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7f42c1c4 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7fa00ca4 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x7fa6e5e4 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x7fdb9423 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x805dfa3a bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x807a3ce5 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x80885f38 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x8095ef1b unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x80af48a2 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x80d606af ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x817b6f7e bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x81bc7d92 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x820e3912 rpc_force_rebind +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x8245fdad ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x824f14c8 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x827e44de user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x829cf6ff nlmclnt_proc +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x83213852 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x836d2cc9 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8412e3c5 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x8449318b schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x844d8fe1 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x8486de36 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x84bc5f10 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0x84eb5778 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x84f027b1 rpc_delay +EXPORT_SYMBOL_GPL vmlinux 0x8501182e ide_unregister_region +EXPORT_SYMBOL_GPL vmlinux 0x85455169 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x854c88fc led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x8550b1fb __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x8561cbe9 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x859a5423 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86dbebbd ide_set_irq +EXPORT_SYMBOL_GPL vmlinux 0x8707831c sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87d527a3 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x888cce9d sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x88a68f3a debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x88d605ed driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x88f1045b usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x89181d5d rpc_malloc +EXPORT_SYMBOL_GPL vmlinux 0x8938d3e5 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x89ea5418 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x8a0fa885 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x8a1044f7 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x8a2c92c5 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x8a5b138a zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x8a7dcf23 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x8a895ac6 device_create +EXPORT_SYMBOL_GPL vmlinux 0x8aa0a2d7 fat_search_long +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ad7cc6f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x8b4c065b hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x8b6bae33 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8c7b2e5e debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x8ceb4ffa ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x8cf34414 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x8d2831ad usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x8dda9fe3 crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x8dff60b8 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x8e139505 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x8e95e4e3 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x8ea7188b unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x8ec70968 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x8ede0edd attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x8ef7c98a tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x8f3000f7 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x8f3f5a69 ide_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f7cb60c async_trigger_callback +EXPORT_SYMBOL_GPL vmlinux 0x8f99eeee nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x8fb97b5d ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x8fcfbeb8 get_device +EXPORT_SYMBOL_GPL vmlinux 0x903d4359 device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90cb811f sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x910933f7 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL vmlinux 0x910ee9a8 device_move +EXPORT_SYMBOL_GPL vmlinux 0x9115197f device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x911c6df8 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x91a9cb2d device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92c9a528 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x93094eb5 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x933a4586 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x93408c86 ide_host_register +EXPORT_SYMBOL_GPL vmlinux 0x938f22f6 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x93a75da3 led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x93bf3dd3 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x93d0cee3 ide_wait_not_busy +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x94524761 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0x9459a796 svc_xprt_names +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94ae969a vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x94b215be ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x94c7da15 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94f847bb sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x94fd4a8a rpc_peeraddr +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x959c9924 ide_init_pc +EXPORT_SYMBOL_GPL vmlinux 0x95f25ca8 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x96449ec7 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL vmlinux 0x9687d82d inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x968be4eb ide_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x96bf68f0 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x96c90953 svc_find_xprt +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9784e6b4 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x97d05fae raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x97eeb2f6 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x98196f5b blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x98379e41 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x985d6f66 ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x999eec46 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x99d8337e d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x99e31f77 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x99e3dab3 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a4cf025 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x9a9179f1 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x9abec99e rpc_call_sync +EXPORT_SYMBOL_GPL vmlinux 0x9ae5bb9b pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x9af215bd ide_undecoded_slave +EXPORT_SYMBOL_GPL vmlinux 0x9b64ae3d usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x9b9fb999 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bc602b1 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x9be35fa2 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x9c0cec36 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x9c4ffb5a usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0x9c91c8b9 ide_do_test_unit_ready +EXPORT_SYMBOL_GPL vmlinux 0x9c93a97b scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9d05ffbd crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x9d5a5e7f ide_no_data_taskfile +EXPORT_SYMBOL_GPL vmlinux 0x9dca1879 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x9e0c4c60 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0x9e29beb0 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x9e370c26 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e8440c3 rpc_create +EXPORT_SYMBOL_GPL vmlinux 0x9ebecc1c ide_pci_init_two +EXPORT_SYMBOL_GPL vmlinux 0x9f6c3e14 svc_print_addr +EXPORT_SYMBOL_GPL vmlinux 0x9f879d21 ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa046be3f svc_reg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0xa0a3d6a7 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xa0e1ae77 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xa0e4e281 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0xa1498535 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0xa1be74f6 rpc_put_task +EXPORT_SYMBOL_GPL vmlinux 0xa29a1214 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa30bda06 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa43f0155 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL vmlinux 0xa4517616 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0xa456fda0 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xa45febf6 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0xa4775ef7 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0xa4e1da2a ide_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xa4f09479 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0xa54dceed pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0xa55a0cd1 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xa57afc74 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xa5af2608 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5f5574b ide_read_altstatus +EXPORT_SYMBOL_GPL vmlinux 0xa6923523 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xa6e93b2f cfi_cmdset_0003 +EXPORT_SYMBOL_GPL vmlinux 0xa73c0e56 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL_GPL vmlinux 0xa834f4d6 svc_xprt_put +EXPORT_SYMBOL_GPL vmlinux 0xa853f68e input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa895d95a ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0xa8bb6eee ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa915bb4b regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xa91e8d41 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL vmlinux 0xa950b809 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa99c093d rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa9bbf79b xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9c79eb4 ide_set_pio +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa2cf25c usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0xaa7a598f __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xaa7bbbed user_destroy +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaaabee94 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xaab12a74 usb_string +EXPORT_SYMBOL_GPL vmlinux 0xab291772 devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab7c0938 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0xabd05688 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0xacb31862 device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xacb9c24f transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xacc3d039 rpc_lookup_cred +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xacf14b93 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xacf1bd37 ide_device_get +EXPORT_SYMBOL_GPL vmlinux 0xada87e6e ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xadb85866 ide_read_error +EXPORT_SYMBOL_GPL vmlinux 0xadbb2197 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0xaddf426e hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae1ff9f2 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0xae959732 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xaecffe83 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0xaf12b7ed xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xaf153c56 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaf3aa28e tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xaf5439ce svc_unreg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL vmlinux 0xaf776324 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xafb3de3a regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb03bb301 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0xb067ba96 svc_addsock +EXPORT_SYMBOL_GPL vmlinux 0xb1a2c2df kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1c09675 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0xb1cd13f1 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0xb384e158 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0xb38a8391 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xb3b3be1d fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0xb3d4e7e4 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0xb449ed11 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0xb44dc7db apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xb4a4b9fb blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb4b035fc mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb4b13e61 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL vmlinux 0xb51b12c6 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0xb541bac0 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xb55f6889 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xb59ebab1 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xb5b20f2a transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0xb5c719c5 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xb5e8e089 unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0xb5f9c4ab ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0xb612dc57 pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xb69649f9 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0xb6aa0a95 led_classdev_resume +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6f0c1a9 tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xb6f97405 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xb71920f3 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xb7a8ca00 ide_host_add +EXPORT_SYMBOL_GPL vmlinux 0xb7dc69cb sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xb7e92537 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xb80610b9 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xb8759c2c srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xb8b0dc77 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xb8f37b34 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0xb8fee532 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0xb943d8bf do_rw_taskfile +EXPORT_SYMBOL_GPL vmlinux 0xb99bd291 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba1144f4 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xba17e520 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0xba377704 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xba395a55 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xba697301 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xba770209 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xba96ba7c async_tx_quiesce +EXPORT_SYMBOL_GPL vmlinux 0xbaaaf47c inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xbac8f45b queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xbaf09ec0 klist_del +EXPORT_SYMBOL_GPL vmlinux 0xbb082fa3 user_update +EXPORT_SYMBOL_GPL vmlinux 0xbb1daa82 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0xbb248c8a get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xbb3a9b8a single_open_net +EXPORT_SYMBOL_GPL vmlinux 0xbb45a5dc ide_read_bcount_and_ireason +EXPORT_SYMBOL_GPL vmlinux 0xbb578578 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0xbb8931f6 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0xbb9a2c75 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0xbbb438f6 nlmclnt_init +EXPORT_SYMBOL_GPL vmlinux 0xbc0465b9 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xbc163956 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xbc2099ca ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0xbc3a84f5 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0xbc4d7783 deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0xbca22ac2 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0xbccf4089 rpc_sleep_on +EXPORT_SYMBOL_GPL vmlinux 0xbd4e2e2d usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0xbdace338 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbe082a49 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe4637e6 scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xbe51bcae register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0xbe5bab89 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0xbebab681 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xbedc9c10 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xbeea7a2b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbf37168b ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL vmlinux 0xbfa86d7e register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xbfac1a72 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xbfafe31e rpcauth_register +EXPORT_SYMBOL_GPL vmlinux 0xbfc6ae2d __class_register +EXPORT_SYMBOL_GPL vmlinux 0xbfe7385b usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xc024edbc rpc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0xc0359a1c sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xc063dd1f ide_queue_pc_tail +EXPORT_SYMBOL_GPL vmlinux 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL vmlinux 0xc15e73cc raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc17f1dca fat_flush_inodes +EXPORT_SYMBOL_GPL vmlinux 0xc19dca09 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc1a368b1 put_pid +EXPORT_SYMBOL_GPL vmlinux 0xc1aa61d0 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xc1f57658 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc2853437 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0xc2e857bc regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0xc2f234a4 inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0xc2f94b72 device_add +EXPORT_SYMBOL_GPL vmlinux 0xc3135219 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc38d5dad pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xc3b29ced ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0xc3ba52ac ide_get_best_pio_mode +EXPORT_SYMBOL_GPL vmlinux 0xc3ea6adb inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc427bc36 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4b73909 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xc4e792c7 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0xc516d01b devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc5a0b012 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0xc6391cfd debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xc6613cf4 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc687d8c9 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0xc6c51264 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xc73e7577 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc75e7908 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc7b0572e screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0xc7b65e80 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0xc85675bf regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xc8605a38 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0xc876e17d class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xc90be65d hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xc9204255 ide_issue_pc +EXPORT_SYMBOL_GPL vmlinux 0xc932397b ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xc95bf3f5 ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0xc9832c6d sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xc9876bf8 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0xc99a2001 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0xc9ac11ea usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0xc9ba2de7 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0xc9ffae0c sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xca60d3f7 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0xca6c5d8e __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xcac9b1ba elv_register +EXPORT_SYMBOL_GPL vmlinux 0xcade53ff devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0xcb0c2ebf __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcb636f28 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0xcb7c9f72 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xcbf34838 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc4313fd unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xcca0c0c8 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0xcccadf40 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcda32a94 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0xcdb3cff0 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcdf924ad ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0xce4259d2 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xce684a36 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0xce99b016 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0xcef257d5 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xcf00a7cf sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xcf7bb156 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0xcfbad752 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd00c0556 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0abc241 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd12bd9a1 fat_free_clusters +EXPORT_SYMBOL_GPL vmlinux 0xd187ea91 svc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0xd1dacea8 fat_fill_super +EXPORT_SYMBOL_GPL vmlinux 0xd25acbdf ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd2dc7a6a vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0xd39c47d4 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0xd46753fc cfi_cmdset_0200 +EXPORT_SYMBOL_GPL vmlinux 0xd49fca97 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0xd4bd84af net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0xd4bf13df usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0xd55154ea fat_scan +EXPORT_SYMBOL_GPL vmlinux 0xd561b77f user_match +EXPORT_SYMBOL_GPL vmlinux 0xd5a28c0d device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd6cb3cb7 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0xd6f6c4b1 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xd73429bd ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0xd741cfcf blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xd7d3a05d usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0xd828845f bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd896188c ide_error +EXPORT_SYMBOL_GPL vmlinux 0xd8999b33 k_handler +EXPORT_SYMBOL_GPL vmlinux 0xd8efd908 xprt_complete_rqst +EXPORT_SYMBOL_GPL vmlinux 0xd909bd1c bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xd952959b regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0xd9d7681d register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xd9dfbee3 get_driver +EXPORT_SYMBOL_GPL vmlinux 0xd9fb7036 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xdaf11d13 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xdb7c6abb find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xdbba9d08 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0xdbfa7cbd proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0xdc2c9299 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xdc317da9 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xdc5c7529 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xdca503fa vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0xddb50279 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0xddd732ef xprt_unregister_transport +EXPORT_SYMBOL_GPL vmlinux 0xddebba51 usbhid_set_leds +EXPORT_SYMBOL_GPL vmlinux 0xde110e9e default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0xde457467 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0xde476d05 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0xde8cf709 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0xdeb039ff platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xdeef0a51 rpc_proc_register +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xe0040bdb platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0xe00df0a1 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xe0b95910 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xe163fa76 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xe22f5316 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0xe25643b4 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0xe2d70af3 usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0xe2fab84f usbhid_submit_report +EXPORT_SYMBOL_GPL vmlinux 0xe334f63b led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0xe3568a1d ide_set_media_lock +EXPORT_SYMBOL_GPL vmlinux 0xe35ce254 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xe3bf2b5f usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0xe3ef867a tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0xe4431ef2 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0xe47c331e scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4ba6379 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe4d1d012 ide_host_free +EXPORT_SYMBOL_GPL vmlinux 0xe4f46dd5 ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0xe50e330d led_classdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe53f3aa8 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0xe568625a ide_set_dma_mode +EXPORT_SYMBOL_GPL vmlinux 0xe5741c6c bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xe5ad409e fat_get_dotdot_entry +EXPORT_SYMBOL_GPL vmlinux 0xe5b43189 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0xe5fb0f83 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xe5ff9d1c ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe647dcdb gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0xe6d06349 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0xe6f9fdd1 ide_device_put +EXPORT_SYMBOL_GPL vmlinux 0xe72ca60e ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0xe73b79de ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xe751090c __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xe86bb130 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0xe8ccc61c blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0xe8d9afc0 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe94dc26b gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0xe9578178 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe97bec68 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xe98a953f rpc_peeraddr2str +EXPORT_SYMBOL_GPL vmlinux 0xe9ab9b13 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea62c60c hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0xea7a3d7a tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0xeabe76aa ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0xeb608325 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xeb7185d6 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xeb859d8a usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xeb8eb48a usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xebb65e9e __ide_error +EXPORT_SYMBOL_GPL vmlinux 0xebba8c5e inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0xebdc9890 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xec013e3e debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xec057122 ide_init_sg_cmd +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xed446f82 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0xed7fd839 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xeda99757 usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xedc26145 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0xee16e272 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0xee2b23d5 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0xef08a214 ide_output_data +EXPORT_SYMBOL_GPL vmlinux 0xef233ba3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0xef4e963e __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xef561d4c __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef82fdba srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0xef8da1ab sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf0c6f9c4 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf0ce5881 parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0xf0e99572 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xf0f4f511 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xf105d00d ide_in_drive_list +EXPORT_SYMBOL_GPL vmlinux 0xf1349926 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xf1463412 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1bcbf2b device_rename +EXPORT_SYMBOL_GPL vmlinux 0xf1d43abf pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0xf1f2ff3f rpcauth_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf27badce inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf3059062 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0xf3074680 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xf30a5457 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0xf30d91e1 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0xf34e10ae usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0xf350fe82 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0xf35ff64a crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf3e96307 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf3f02771 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xf3f1a307 fat_add_entries +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4e5e603 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xf50cd762 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf52990af fat_setattr +EXPORT_SYMBOL_GPL vmlinux 0xf53cfe2b klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5aaf6a5 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xf61aa233 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xf6aa8871 usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xf7403817 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf863e82a flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf86b8cd4 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8c88e14 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0xf8de3cca get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf90c3138 copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9cc24ba rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL vmlinux 0xfae2e37a ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xfb2ba180 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xfb41bab5 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0xfba56b8c xprt_release_xprt +EXPORT_SYMBOL_GPL vmlinux 0xfbb89e8a tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xfbf283d9 del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc00505e usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0xfc2703b2 ide_register_region +EXPORT_SYMBOL_GPL vmlinux 0xfcd9f146 rpcb_getport_async +EXPORT_SYMBOL_GPL vmlinux 0xfd4e92ed sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xfd932772 ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0xfdefe308 ide_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xfe3a2ca0 led_classdev_register +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xff042f7f dma_wait_for_async_tx +EXPORT_SYMBOL_GPL vmlinux 0xff93cd2d debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xffaf7bbb __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0xffce863b ata_wait_after_reset --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/ixp4xx.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/ixp4xx.modules @@ -0,0 +1,202 @@ +act_gact +act_ipt +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +aead +aes_generic +anubis +arc4 +arptable_filter +arp_tables +async_memcpy +async_tx +async_xor +authenc +blowfish +brd +bridge +cast5 +cast6 +cbc +cdrom +chainiv +cls_basic +cls_flow +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +configfs +cramfs +crc16 +crc32c +crc-itu-t +crc-t10dif +crypto_algapi +crypto_blkcipher +crypto_hash +cryptoloop +cryptomgr +crypto_null +deflate +des_generic +dm-mod +ecb +econet +eseqiv +fuse +gf128mul +gpio +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hmac +hwa-rc +i2c-algo-bit +i2c-gpio +ide-cd_mod +ide-pci-generic +ifb +ip_queue +iptable_filter +iptable_mangle +iptable_raw +ip_tables +ipt_addrtype +ipt_ah +ipt_ecn +ipt_ECN +ipt_LOG +ipt_REJECT +ipt_ttl +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_rr +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +isofs +ixp4xx_crypto +ixp4xx-rng +jfs +khazad +krng +libcrc32c +llc +lrw +md4 +md5 +md-mod +michael_mic +msdos +nand +nand_ecc +nand_ids +nbd +p8022 +pcbc +phonet +pn_pep +psnap +raid0 +raid1 +raid10 +raid456 +reiserfs +rng +rng-core +sch_cbq +sch_dsmark +sch_gred +sch_htb +sch_ingress +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_wait_scan +serpent +sg +sha1_generic +sha256_generic +sha512_generic +sit +stp +tea +tgr192 +ts_bm +ts_fsm +ts_kmp +tunnel4 +twofish +twofish_common +udf +uwb +virtual +wp512 +wusb-cbaf +wusbcore +xcbc +xfrm6_mode_beet +xfrm6_mode_transport +xfrm6_mode_tunnel +xfs +xor +x_tables +xt_CLASSIFY +xt_comment +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_iprange +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_owner +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_TCPOPTSTRIP +xt_tcpudp +xt_time +xt_TRACE +xt_u32 --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/orion5x.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/orion5x.modules @@ -0,0 +1,185 @@ +act_gact +act_ipt +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +aead +aes_generic +anubis +arc4 +arptable_filter +arp_tables +async_memcpy +async_xor +blowfish +cast5 +cast6 +cbc +cdrom +chainiv +cls_basic +cls_flow +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +configfs +cramfs +crc32c +crc-itu-t +crc-t10dif +crypto_algapi +crypto_blkcipher +crypto_hash +cryptoloop +cryptomgr +crypto_null +deflate +des_generic +dm-mod +ecb +eseqiv +ff-memless +fuse +gf128mul +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hmac +hwa-hc +hwa-rc +i2c-algo-bit +i2c-gpio +icplus +ide-cd_mod +ide-pci-generic +ide-tape +ifb +iptable_filter +iptable_mangle +iptable_raw +ip_tables +ipt_addrtype +ipt_ah +ipt_ecn +ipt_ECN +ipt_LOG +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +isofs +jfs +khazad +krng +libcrc32c +lrw +md4 +md5 +md-mod +michael_mic +msdos +nand +nand_ecc +nand_ids +orion_nand +pcbc +phonet +pn_pep +raid0 +raid1 +raid10 +raid456 +reiserfs +rng +rng-core +sch_cbq +sch_dsmark +sch_gred +sch_htb +sch_ingress +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_wait_scan +serpent +sg +sha1_generic +sha256_generic +sha512_generic +sit +tea +tgr192 +ts_bm +ts_fsm +ts_kmp +tunnel4 +twofish +twofish_common +udf +uwb +virtual +wp512 +wusb-cbaf +wusbcore +wusb-wa +xcbc +xfrm6_mode_beet +xfrm6_mode_transport +xfrm6_mode_tunnel +xfs +xor +x_tables +xt_CLASSIFY +xt_comment +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_iprange +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_owner +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_TCPOPTSTRIP +xt_tcpudp +xt_time +xt_TRACE +xt_u32 --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/orion5x +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/orion5x @@ -0,0 +1,4073 @@ +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/cdrom/cdrom 0x065c3e54 cdrom_mode_sense +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL drivers/cdrom/cdrom 0x51bb8964 register_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x545f7cc9 cdrom_open +EXPORT_SYMBOL drivers/cdrom/cdrom 0x548c4317 cdrom_ioctl +EXPORT_SYMBOL drivers/cdrom/cdrom 0x604b6b3e cdrom_media_changed +EXPORT_SYMBOL drivers/cdrom/cdrom 0x8705efce cdrom_get_last_written +EXPORT_SYMBOL drivers/cdrom/cdrom 0x9e6c328a cdrom_number_of_slots +EXPORT_SYMBOL drivers/cdrom/cdrom 0xc0532b21 unregister_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0xd9390338 cdrom_release +EXPORT_SYMBOL drivers/cdrom/cdrom 0xe84d27bf cdrom_get_media_event +EXPORT_SYMBOL drivers/cdrom/cdrom 0xfbbe7b5a cdrom_mode_select +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x131191a3 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xa73a8021 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/md/dm-mod 0x0b077d73 dm_table_put +EXPORT_SYMBOL drivers/md/dm-mod 0x14761041 dm_get_device +EXPORT_SYMBOL drivers/md/dm-mod 0x1d4c1f20 dm_kcopyd_copy +EXPORT_SYMBOL drivers/md/dm-mod 0x26ea64ba dm_table_get_mode +EXPORT_SYMBOL drivers/md/dm-mod 0x31031310 dm_register_target +EXPORT_SYMBOL drivers/md/dm-mod 0x53958d61 dm_io_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x61dce49e dm_kcopyd_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x63903134 dm_table_get +EXPORT_SYMBOL drivers/md/dm-mod 0x76ca9817 dm_io_client_resize +EXPORT_SYMBOL drivers/md/dm-mod 0x7b52513f dm_io +EXPORT_SYMBOL drivers/md/dm-mod 0x8346a1ac dm_io_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0xa4a726d2 dm_table_unplug_all +EXPORT_SYMBOL drivers/md/dm-mod 0xa7f6d714 dm_table_get_md +EXPORT_SYMBOL drivers/md/dm-mod 0xab21b531 dm_kcopyd_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0xb5fe256c dm_table_event +EXPORT_SYMBOL drivers/md/dm-mod 0xbb035dee dm_put_device +EXPORT_SYMBOL drivers/md/dm-mod 0xbfd9a725 dm_table_get_size +EXPORT_SYMBOL drivers/md/dm-mod 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL drivers/md/dm-mod 0xf116a2df dm_get_mapinfo +EXPORT_SYMBOL drivers/md/dm-mod 0xf980ec86 dm_unregister_target +EXPORT_SYMBOL drivers/md/md-mod 0x18d5965e md_error +EXPORT_SYMBOL drivers/md/md-mod 0x2cc22242 unregister_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0x48cdc34c bitmap_close_sync +EXPORT_SYMBOL drivers/md/md-mod 0x51883b06 md_register_thread +EXPORT_SYMBOL drivers/md/md-mod 0x5a342760 md_write_end +EXPORT_SYMBOL drivers/md/md-mod 0x5d856d05 bitmap_start_sync +EXPORT_SYMBOL drivers/md/md-mod 0x664313f2 bitmap_unplug +EXPORT_SYMBOL drivers/md/md-mod 0x6e2446ac md_check_recovery +EXPORT_SYMBOL drivers/md/md-mod 0x6f46d529 bitmap_cond_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x73b4dcbd bitmap_startwrite +EXPORT_SYMBOL drivers/md/md-mod 0x9e54b7b7 bitmap_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0xb793a826 md_write_start +EXPORT_SYMBOL drivers/md/md-mod 0xbe364c20 md_done_sync +EXPORT_SYMBOL drivers/md/md-mod 0xd833430f bitmap_endwrite +EXPORT_SYMBOL drivers/md/md-mod 0xe10984a5 md_wakeup_thread +EXPORT_SYMBOL drivers/md/md-mod 0xe3b54439 md_unregister_thread +EXPORT_SYMBOL drivers/md/md-mod 0xed134d56 register_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0xf33c211b md_wait_for_blocked_rdev +EXPORT_SYMBOL drivers/mtd/nand/nand 0x0dcf35f1 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0x3110e496 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x6025b25a nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x974b26b3 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL fs/configfs/configfs 0x418eaea0 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0x60380ce1 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x649af0ca config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x81f95566 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x8238c21b config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0x84156bfa configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x989ba6ac config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xa50b3306 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xd28187f3 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0xdf540c63 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0xe1f0cca8 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0xf08497e0 configfs_depend_item +EXPORT_SYMBOL fs/xfs/xfs 0x7645e262 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc-t10dif 0xb6896671 crc_t10dif +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x11db66a6 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xb5d97f3e arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xf26c8808 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x281ed5ab ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x53eab576 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xe0665160 ipt_do_table +EXPORT_SYMBOL net/ipv4/tunnel4 0x381d7d7b xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv4/tunnel4 0xe541903f xfrm4_tunnel_register +EXPORT_SYMBOL net/netfilter/x_tables 0x0198380a xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0x05ee26dd xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x0ce69106 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x430b740f xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0x5476b072 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x5a9a6459 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x7c8af666 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xbbc10508 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0xc192ec5e xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0xfa662a4e xt_find_match +EXPORT_SYMBOL net/phonet/phonet 0x0c7c5661 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x20103549 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x6d59e567 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x77309f53 phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x8da8db0f phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0xa572b9d0 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xcbc2f3e9 phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0xe2266abf pn_sock_unhash +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x0006427c proto_unregister +EXPORT_SYMBOL vmlinux 0x005448c4 svc_destroy +EXPORT_SYMBOL vmlinux 0x0069de0b nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x00886aff register_qdisc +EXPORT_SYMBOL vmlinux 0x00a45239 tcf_register_action +EXPORT_SYMBOL vmlinux 0x00cbec1e blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x00dfa7ab dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x01055ec9 skb_seq_read +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x0122d983 inet_addr_type +EXPORT_SYMBOL vmlinux 0x0148a92d __devm_release_region +EXPORT_SYMBOL vmlinux 0x015224e9 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x0157569c call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0x019e05ac i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01c8e9cd __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02196324 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x0220645a __devm_request_region +EXPORT_SYMBOL vmlinux 0x02573302 km_policy_notify +EXPORT_SYMBOL vmlinux 0x02bdf2de create_empty_buffers +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x03074593 km_new_mapping +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x033ca6cd scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0x0350e2f4 up_read +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03be7d87 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03edbd55 svcauth_unix_set_client +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0411a0e7 ip_route_input +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x0439de50 neigh_table_init +EXPORT_SYMBOL vmlinux 0x043b8483 __kfifo_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x04790d76 pci_dev_driver +EXPORT_SYMBOL vmlinux 0x04ae385b proc_dostring +EXPORT_SYMBOL vmlinux 0x04c43042 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x04e3fc49 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x04f20dfa call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x04f2bf2e tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x050cefed pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x0525c710 phy_connect +EXPORT_SYMBOL vmlinux 0x052b2967 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x056d769f blkdev_put +EXPORT_SYMBOL vmlinux 0x05771c5f tty_hangup +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x059a85a4 generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0x05a3e13c tc_classify_compat +EXPORT_SYMBOL vmlinux 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL vmlinux 0x06090de7 __sg_free_table +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0618e633 dump_fpu +EXPORT_SYMBOL vmlinux 0x062aba95 mempool_free +EXPORT_SYMBOL vmlinux 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL vmlinux 0x06900f14 __brelse +EXPORT_SYMBOL vmlinux 0x06968ab3 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x069f3b7f con_is_bound +EXPORT_SYMBOL vmlinux 0x06c26aa9 udp_prot +EXPORT_SYMBOL vmlinux 0x06cb34e5 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x06d654c2 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x06d8bae1 idr_get_new +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x076a5f19 skb_queue_purge +EXPORT_SYMBOL vmlinux 0x0784c3a4 i2c_release_client +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d6882f sk_free +EXPORT_SYMBOL vmlinux 0x07da36aa proto_register +EXPORT_SYMBOL vmlinux 0x07f57590 setup_arg_pages +EXPORT_SYMBOL vmlinux 0x080a7eb7 do_sync_write +EXPORT_SYMBOL vmlinux 0x0819e4ca xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x0825af49 textsearch_prepare +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x08309361 inet6_ioctl +EXPORT_SYMBOL vmlinux 0x08722cff datagram_poll +EXPORT_SYMBOL vmlinux 0x089edd70 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x08aa7048 ip_fragment +EXPORT_SYMBOL vmlinux 0x08d4d73c ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x08ece071 free_task +EXPORT_SYMBOL vmlinux 0x08ed3670 xdr_shift_buf +EXPORT_SYMBOL vmlinux 0x0903af83 sock_no_listen +EXPORT_SYMBOL vmlinux 0x0905b29e pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x092b007a sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x09689dc0 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x09a1f1bd pcim_pin_device +EXPORT_SYMBOL vmlinux 0x09af1d9a netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x09ba3b0c __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09c895d7 search_binary_handler +EXPORT_SYMBOL vmlinux 0x09d45c21 down_timeout +EXPORT_SYMBOL vmlinux 0x09e0e633 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x0a1bebc5 kernel_execve +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a25c6d9 dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a41424c phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a5ad15c skb_find_text +EXPORT_SYMBOL vmlinux 0x0a63b27a blk_remove_plug +EXPORT_SYMBOL vmlinux 0x0a80b43f phy_start +EXPORT_SYMBOL vmlinux 0x0aa13d05 __raw_readsw +EXPORT_SYMBOL vmlinux 0x0ab49a79 sock_map_fd +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0acd2907 generic_setxattr +EXPORT_SYMBOL vmlinux 0x0ad4679d unix_domain_find +EXPORT_SYMBOL vmlinux 0x0aef2d89 block_read_full_page +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b231858 journal_init_dev +EXPORT_SYMBOL vmlinux 0x0b28de05 uart_resume_port +EXPORT_SYMBOL vmlinux 0x0b5f2d2c sg_next +EXPORT_SYMBOL vmlinux 0x0b675bf2 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b75d82f pci_enable_device +EXPORT_SYMBOL vmlinux 0x0b90b724 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x0bb7ca8a tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x0bb7f7ad blk_unplug +EXPORT_SYMBOL vmlinux 0x0c15f76d simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c854d2d tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0c9c75cc scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0x0cbcfc47 __scm_send +EXPORT_SYMBOL vmlinux 0x0ce569b2 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x0d23c0a5 sock_no_poll +EXPORT_SYMBOL vmlinux 0x0d3def21 idr_pre_get +EXPORT_SYMBOL vmlinux 0x0d3f57a2 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d981827 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x0dde7d26 sk_stream_error +EXPORT_SYMBOL vmlinux 0x0de46ada xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x0de782fa blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x0df40c0a blk_register_region +EXPORT_SYMBOL vmlinux 0x0e04360c page_readlink +EXPORT_SYMBOL vmlinux 0x0e0b04ff skb_put +EXPORT_SYMBOL vmlinux 0x0e3ced74 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e573ac2 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x0e721a18 bd_set_size +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e88f7c5 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x0edb704c mdiobus_read +EXPORT_SYMBOL vmlinux 0x0f01fa96 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x0f1b8a0c journal_errno +EXPORT_SYMBOL vmlinux 0x0f1ef871 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x0f1f9a6c per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x0f2d6d11 uart_add_one_port +EXPORT_SYMBOL vmlinux 0x0f3f6b8b send_sig_info +EXPORT_SYMBOL vmlinux 0x0f61ac38 neigh_for_each +EXPORT_SYMBOL vmlinux 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL vmlinux 0x0f7f1b0d xdr_write_pages +EXPORT_SYMBOL vmlinux 0x0f8d21ef journal_start +EXPORT_SYMBOL vmlinux 0x0fa2a45e __memzero +EXPORT_SYMBOL vmlinux 0x0fa59221 pci_fixup_device +EXPORT_SYMBOL vmlinux 0x0fc586ba down_trylock +EXPORT_SYMBOL vmlinux 0x0ff178f6 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x103a55a0 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x105077ae drop_super +EXPORT_SYMBOL vmlinux 0x10579454 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x10602233 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x10c8c169 init_file +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x111bcb2c groups_free +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x11434907 ip_dev_find +EXPORT_SYMBOL vmlinux 0x11583cbf xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x115ec214 kthread_create +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x119a38e0 seq_read +EXPORT_SYMBOL vmlinux 0x119b50e7 elf_check_arch +EXPORT_SYMBOL vmlinux 0x11af9762 alloc_file +EXPORT_SYMBOL vmlinux 0x11fccc11 netdev_set_master +EXPORT_SYMBOL vmlinux 0x120aee1d call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1276f429 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x12b2da3b pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x12c34354 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL vmlinux 0x13266092 put_io_context +EXPORT_SYMBOL vmlinux 0x13272fde sock_sendmsg +EXPORT_SYMBOL vmlinux 0x1334a5dd generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x13439170 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x1350a5f3 tcp_ioctl +EXPORT_SYMBOL vmlinux 0x13653230 __neigh_event_send +EXPORT_SYMBOL vmlinux 0x141382a1 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x144ed3a1 dev_base_lock +EXPORT_SYMBOL vmlinux 0x149e4262 pci_pme_capable +EXPORT_SYMBOL vmlinux 0x14a3d225 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x14d61bb6 sock_i_ino +EXPORT_SYMBOL vmlinux 0x150512a9 inode_change_ok +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1578bada posix_lock_file +EXPORT_SYMBOL vmlinux 0x15c6e2aa bh_submit_read +EXPORT_SYMBOL vmlinux 0x16479e8f panic_notifier_list +EXPORT_SYMBOL vmlinux 0x164e91e1 wake_up_process +EXPORT_SYMBOL vmlinux 0x165aa9f1 pci_select_bars +EXPORT_SYMBOL vmlinux 0x16922c88 phy_print_status +EXPORT_SYMBOL vmlinux 0x16b015ba nf_log_unregister +EXPORT_SYMBOL vmlinux 0x16da95f1 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0x16f9aca8 proc_dointvec +EXPORT_SYMBOL vmlinux 0x17039d0f scsi_finish_command +EXPORT_SYMBOL vmlinux 0x17385af6 udplite_prot +EXPORT_SYMBOL vmlinux 0x176debf6 __rta_fill +EXPORT_SYMBOL vmlinux 0x1784d635 prepare_binprm +EXPORT_SYMBOL vmlinux 0x1789823c xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17c711d0 scsi_print_sense +EXPORT_SYMBOL vmlinux 0x17caaea4 phy_scan_fixups +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x1801fbd7 sk_dst_check +EXPORT_SYMBOL vmlinux 0x18104b5e truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18590fad neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x18707c7f bio_map_kern +EXPORT_SYMBOL vmlinux 0x1893a50c bio_unmap_user +EXPORT_SYMBOL vmlinux 0x18c828dd ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x1907a83b inode_permission +EXPORT_SYMBOL vmlinux 0x197d9706 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x1983e570 scsi_print_result +EXPORT_SYMBOL vmlinux 0x198af45e xdr_init_encode +EXPORT_SYMBOL vmlinux 0x199606be tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x199a29db skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19c4d0e9 phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0x19e07a77 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x19f008f1 skb_make_writable +EXPORT_SYMBOL vmlinux 0x19f88a1b proc_net_netfilter +EXPORT_SYMBOL vmlinux 0x1a14c83f inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x1a1ae61e scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x1a1f6385 __blk_run_queue +EXPORT_SYMBOL vmlinux 0x1a28d25b uart_match_port +EXPORT_SYMBOL vmlinux 0x1a3cde80 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x1a4f6e82 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x1a5a7ccb __ip_select_ident +EXPORT_SYMBOL vmlinux 0x1a65f4ad __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x1ab06d0c devm_request_irq +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad1f2e7 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b00a37e ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b2ab339 proc_create_data +EXPORT_SYMBOL vmlinux 0x1b556892 tcp_connect +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b785e33 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0x1b7bf52a blk_put_request +EXPORT_SYMBOL vmlinux 0x1b809a18 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9baa68 inet6_release +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bf6dd0a kernel_connect +EXPORT_SYMBOL vmlinux 0x1c179bde set_bdi_congested +EXPORT_SYMBOL vmlinux 0x1c324357 idr_replace +EXPORT_SYMBOL vmlinux 0x1c723b86 seq_puts +EXPORT_SYMBOL vmlinux 0x1c76b4bf xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1d0aaf41 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x1d0e6113 lookup_one_len +EXPORT_SYMBOL vmlinux 0x1d1871e3 __bio_clone +EXPORT_SYMBOL vmlinux 0x1d5a2f34 udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x1df65590 sock_create +EXPORT_SYMBOL vmlinux 0x1e427c4c map_destroy +EXPORT_SYMBOL vmlinux 0x1e49daa8 sg_init_one +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e87e834 set_user_nice +EXPORT_SYMBOL vmlinux 0x1e8e49bc mpage_readpages +EXPORT_SYMBOL vmlinux 0x1eba8905 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x1ebfee1f __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x1ecb9943 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x1edbf514 add_disk +EXPORT_SYMBOL vmlinux 0x1edc9598 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x1ef36336 journal_release_buffer +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f1c6c55 dst_release +EXPORT_SYMBOL vmlinux 0x1f40f52b blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x1f57f7a9 kernel_accept +EXPORT_SYMBOL vmlinux 0x1f70d32d dma_cache_maint +EXPORT_SYMBOL vmlinux 0x1f7cc628 mempool_create +EXPORT_SYMBOL vmlinux 0x1f82d034 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x1fab5fbf ide_stall_queue +EXPORT_SYMBOL vmlinux 0x1fae7a0b wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x1fc91fb2 request_irq +EXPORT_SYMBOL vmlinux 0x1fd42ba5 mdiobus_free +EXPORT_SYMBOL vmlinux 0x1fdc59a6 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2033fad6 lock_super +EXPORT_SYMBOL vmlinux 0x203b22a3 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x2078bba3 wireless_send_event +EXPORT_SYMBOL vmlinux 0x20b7bd60 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x20c4e4de arp_find +EXPORT_SYMBOL vmlinux 0x20d894b2 ide_set_handler +EXPORT_SYMBOL vmlinux 0x20edd060 unregister_qdisc +EXPORT_SYMBOL vmlinux 0x20f3dd7a rtnl_notify +EXPORT_SYMBOL vmlinux 0x2102154d tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x211331fa __divsi3 +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x21b232e1 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x21e4d53e eth_header_cache +EXPORT_SYMBOL vmlinux 0x21e7bc89 journal_check_available_features +EXPORT_SYMBOL vmlinux 0x21eb84ee seq_path +EXPORT_SYMBOL vmlinux 0x2214a058 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22955b37 sunrpc_cache_lookup +EXPORT_SYMBOL vmlinux 0x229cfd5b gen_new_estimator +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22bd12f4 journal_extend +EXPORT_SYMBOL vmlinux 0x22d8d0ed blk_free_tags +EXPORT_SYMBOL vmlinux 0x22f2ddd2 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x22f59c81 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0x2300129b bd_release +EXPORT_SYMBOL vmlinux 0x231580a0 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x231cf494 up_write +EXPORT_SYMBOL vmlinux 0x231f0a8b sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x232ddfff blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x235bf539 create_proc_entry +EXPORT_SYMBOL vmlinux 0x236c8490 generic_unplug_device +EXPORT_SYMBOL vmlinux 0x2374f4eb kmem_cache_free +EXPORT_SYMBOL vmlinux 0x23838107 __down_write +EXPORT_SYMBOL vmlinux 0x238d221d pci_request_region +EXPORT_SYMBOL vmlinux 0x23b16100 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x23da1b43 kset_register +EXPORT_SYMBOL vmlinux 0x23ec6843 misc_register +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x2413d6fa in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x24184abd skb_pull +EXPORT_SYMBOL vmlinux 0x2418a1b7 nf_register_hook +EXPORT_SYMBOL vmlinux 0x241e3c39 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x2455c156 __clear_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x245f5d9b tcp_make_synack +EXPORT_SYMBOL vmlinux 0x24651e00 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x24770b1f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x24c7fa77 bmap +EXPORT_SYMBOL vmlinux 0x24d2a60c scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x24df9643 default_llseek +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x24ffb408 generic_read_dir +EXPORT_SYMBOL vmlinux 0x24fff9fa gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x25240c44 skb_dma_map +EXPORT_SYMBOL vmlinux 0x25254157 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x2537bacb tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0x253e1397 dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x2550e63e set_disk_ro +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x259169d3 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x25928c63 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x25ba121c mempool_resize +EXPORT_SYMBOL vmlinux 0x25c9aae8 phy_detach +EXPORT_SYMBOL vmlinux 0x25d0df30 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x25df5726 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x25ed3e0e mnt_unpin +EXPORT_SYMBOL vmlinux 0x25f6d239 pci_disable_device +EXPORT_SYMBOL vmlinux 0x25fa6f17 wait_for_completion +EXPORT_SYMBOL vmlinux 0x2607d4bb simple_getattr +EXPORT_SYMBOL vmlinux 0x26101d80 xdr_buf_subsegment +EXPORT_SYMBOL vmlinux 0x261c1766 __backtrace +EXPORT_SYMBOL vmlinux 0x26294310 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x26477c07 __vmalloc +EXPORT_SYMBOL vmlinux 0x266c35cf svc_sock_names +EXPORT_SYMBOL vmlinux 0x267fc65b __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x26952ced __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x26dd3865 textsearch_register +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x271b3cce ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x271e149a simple_set_mnt +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x275b7cd5 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x2763a5ab bio_init +EXPORT_SYMBOL vmlinux 0x2781b050 dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0x27820395 pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27938572 skb_pad +EXPORT_SYMBOL vmlinux 0x279b9d0d __sk_dst_check +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c5d1ce seq_open +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x28118cb6 __get_user_1 +EXPORT_SYMBOL vmlinux 0x2830d347 blk_plug_device +EXPORT_SYMBOL vmlinux 0x2846deee request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x286b435b phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28ad7d2d alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x28b2392e tty_register_driver +EXPORT_SYMBOL vmlinux 0x28d5731e __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28e74a32 udp_disconnect +EXPORT_SYMBOL vmlinux 0x2909230f inode_set_bytes +EXPORT_SYMBOL vmlinux 0x29148969 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x29635422 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x299c5bcf scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x29b6d224 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29c1fbbf cache_unregister +EXPORT_SYMBOL vmlinux 0x2a0c79ec phy_disconnect +EXPORT_SYMBOL vmlinux 0x2a94ea6c netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2aa49bc2 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x2ab88ac3 is_container_init +EXPORT_SYMBOL vmlinux 0x2abd909a have_submounts +EXPORT_SYMBOL vmlinux 0x2abf4a7b xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x2ac95baf tty_write_room +EXPORT_SYMBOL vmlinux 0x2adf18f8 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0x2af4e067 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x2b0ae2f6 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b138b53 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x2b1c92d8 dev_set_mtu +EXPORT_SYMBOL vmlinux 0x2b2c6e38 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x2b40baff __down_write_nested +EXPORT_SYMBOL vmlinux 0x2b570dc0 ida_pre_get +EXPORT_SYMBOL vmlinux 0x2b93ecd1 __find_get_block +EXPORT_SYMBOL vmlinux 0x2b9bce8d sock_rfree +EXPORT_SYMBOL vmlinux 0x2ba290fe xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bd82fe5 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x2c53688e register_console +EXPORT_SYMBOL vmlinux 0x2c62d3ee scsi_device_get +EXPORT_SYMBOL vmlinux 0x2c8b13f4 cfi_fixup +EXPORT_SYMBOL vmlinux 0x2cd06528 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2ce65f64 find_get_page +EXPORT_SYMBOL vmlinux 0x2d1dce85 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x2d215308 phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0x2d6507b5 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d9544c1 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x2d9b0deb svc_sock_update_bufs +EXPORT_SYMBOL vmlinux 0x2db0b08a pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2ded5936 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x2e090263 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x2e11fab7 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e30b8e3 read_cache_pages +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e4a6e5d blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x2e8067bb register_nls +EXPORT_SYMBOL vmlinux 0x2e88bab9 d_invalidate +EXPORT_SYMBOL vmlinux 0x2ec9cc26 vfs_rename +EXPORT_SYMBOL vmlinux 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL vmlinux 0x2f2dd9fd pagecache_write_end +EXPORT_SYMBOL vmlinux 0x2f2e97d1 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x2f33fdcf cdev_add +EXPORT_SYMBOL vmlinux 0x2f4c61cf icmpv6_send +EXPORT_SYMBOL vmlinux 0x2f526d17 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x2f5f624b set_page_dirty +EXPORT_SYMBOL vmlinux 0x2fb93192 generic_make_request +EXPORT_SYMBOL vmlinux 0x2fe805df ip_defrag +EXPORT_SYMBOL vmlinux 0x2fe99c06 pid_task +EXPORT_SYMBOL vmlinux 0x2ff19476 inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x300a4b56 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x303127cd tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x30cb2d54 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x3106a80c mii_link_ok +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x313341a3 _set_bit_le +EXPORT_SYMBOL vmlinux 0x31357eed scsi_target_resume +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL vmlinux 0x31977a50 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31fa1211 dev_unicast_add +EXPORT_SYMBOL vmlinux 0x32040990 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x3204a30b skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x320fb195 xdr_inline_decode +EXPORT_SYMBOL vmlinux 0x323222ba mutex_unlock +EXPORT_SYMBOL vmlinux 0x323905a4 xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x323a3d65 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x32550b98 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x327d6769 generic_show_options +EXPORT_SYMBOL vmlinux 0x328a05f1 strncpy +EXPORT_SYMBOL vmlinux 0x329bd972 end_page_writeback +EXPORT_SYMBOL vmlinux 0x329f53e8 filemap_flush +EXPORT_SYMBOL vmlinux 0x32ce623a sg_last +EXPORT_SYMBOL vmlinux 0x332b0571 drive_is_ready +EXPORT_SYMBOL vmlinux 0x33582683 touch_atime +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33805760 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x339a4b6f sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x33fa260e sock_create_lite +EXPORT_SYMBOL vmlinux 0x340fb6bc get_phy_id +EXPORT_SYMBOL vmlinux 0x341f90f7 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x3455357f blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x345691b7 phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0x346ce0b3 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x34752946 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x348c42ee neigh_compat_output +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34ab39dc tcf_exts_change +EXPORT_SYMBOL vmlinux 0x34aeb159 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x34b2930e pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x34bc858e do_splice_from +EXPORT_SYMBOL vmlinux 0x34c57384 phy_stop +EXPORT_SYMBOL vmlinux 0x34d596f0 iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x3504ad9e simple_unlink +EXPORT_SYMBOL vmlinux 0x35326646 key_validate +EXPORT_SYMBOL vmlinux 0x35368714 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x3537cabc ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x353c4d40 pci_scan_slot +EXPORT_SYMBOL vmlinux 0x353e3fa5 __get_user_4 +EXPORT_SYMBOL vmlinux 0x356e7f37 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x35856ce4 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x3585f2c9 mapping_tagged +EXPORT_SYMBOL vmlinux 0x3589bf4d phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0x359103fe bioset_create +EXPORT_SYMBOL vmlinux 0x35a8bfb3 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x35cbbae1 journal_restart +EXPORT_SYMBOL vmlinux 0x35d26d9e invalidate_partition +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x366bdeaa init_timer +EXPORT_SYMBOL vmlinux 0x366d391f ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x36b3c09a skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x36e47222 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x370190de vfs_statfs +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374bc7b2 bio_map_user +EXPORT_SYMBOL vmlinux 0x374ced54 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x37546325 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x3793a179 dma_map_sg +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37d9b483 nf_afinfo +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37e7ca1b skb_free_datagram +EXPORT_SYMBOL vmlinux 0x37ef697c blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x38153c8a open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x3849c419 arp_send +EXPORT_SYMBOL vmlinux 0x38646631 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x3877ea4a generic_block_bmap +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38a2001a alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x38affbf8 skb_gso_segment +EXPORT_SYMBOL vmlinux 0x38c829b3 sk_filter +EXPORT_SYMBOL vmlinux 0x38d7305a kernel_getpeername +EXPORT_SYMBOL vmlinux 0x38e8378d pgprot_kernel +EXPORT_SYMBOL vmlinux 0x39707308 scsi_device_resume +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x399682da cdev_init +EXPORT_SYMBOL vmlinux 0x39c1f784 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x39f28bbb neigh_ifdown +EXPORT_SYMBOL vmlinux 0x3a2e30c2 copy_io_context +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3ab2d174 down_killable +EXPORT_SYMBOL vmlinux 0x3aba6243 do_map_probe +EXPORT_SYMBOL vmlinux 0x3ac4e285 simple_transaction_get +EXPORT_SYMBOL vmlinux 0x3aca9c66 phy_driver_register +EXPORT_SYMBOL vmlinux 0x3adbae6e dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x3adc15b9 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x3ae831b6 kref_init +EXPORT_SYMBOL vmlinux 0x3af1e99d ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x3b416bc6 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0x3b49bbf5 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x3b707a44 blk_run_queue +EXPORT_SYMBOL vmlinux 0x3bc02963 find_vma +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3c18bf9d generic_file_llseek +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c442cec inet_getname +EXPORT_SYMBOL vmlinux 0x3c5ace81 scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x3c77f4bd skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x3c8265c3 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3ca53d36 unlock_rename +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cccfbab scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x3cce8d33 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3d03cf0e dst_destroy +EXPORT_SYMBOL vmlinux 0x3d125a07 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0x3d1d12d6 clocksource_register +EXPORT_SYMBOL vmlinux 0x3d3c540f elf_hwcap +EXPORT_SYMBOL vmlinux 0x3d5204f4 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x3d68bd4b flow_cache_genid +EXPORT_SYMBOL vmlinux 0x3d734f4b blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x3dbfe3da xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x3ddb9be2 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x3e26afb9 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e5354da xdr_encode_pages +EXPORT_SYMBOL vmlinux 0x3e5b367a clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x3e659778 unlock_buffer +EXPORT_SYMBOL vmlinux 0x3e6caebd add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x3e7d2cd5 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x3e992d0c netlink_unicast +EXPORT_SYMBOL vmlinux 0x3ea7a247 km_state_notify +EXPORT_SYMBOL vmlinux 0x3ec79557 tcp_sendpage +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3efc1864 pci_match_id +EXPORT_SYMBOL vmlinux 0x3f065f4b i2c_probe +EXPORT_SYMBOL vmlinux 0x3f1964ef __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x3f29426b __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x3f2da520 ide_wait_stat +EXPORT_SYMBOL vmlinux 0x3f3749db udp_sendmsg +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f74c043 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0x3f77fef5 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x3f95b5bf tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x4002765a xfrm_init_state +EXPORT_SYMBOL vmlinux 0x40123aeb idr_for_each +EXPORT_SYMBOL vmlinux 0x40334a05 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x4065995b follow_up +EXPORT_SYMBOL vmlinux 0x407136b1 __put_user_8 +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40a6f522 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x40aa34e4 inode_get_bytes +EXPORT_SYMBOL vmlinux 0x40b2b9b0 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x40d1053c filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x40f07981 __ashldi3 +EXPORT_SYMBOL vmlinux 0x4101a975 ide_fixstring +EXPORT_SYMBOL vmlinux 0x41166725 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x411e342b proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x412250a5 fput +EXPORT_SYMBOL vmlinux 0x412ddc0c dcache_lock +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x41495219 inet_stream_ops +EXPORT_SYMBOL vmlinux 0x414f2b24 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x4156ba8b simple_rename +EXPORT_SYMBOL vmlinux 0x415f1cfa sock_register +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x416e2e5c generic_file_open +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x419b96a9 mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x41ab9e93 cdev_del +EXPORT_SYMBOL vmlinux 0x41e10c60 __pagevec_release +EXPORT_SYMBOL vmlinux 0x41ec5cd3 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x41f4efb4 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x4217849d kernel_read +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422d52bf init_net +EXPORT_SYMBOL vmlinux 0x4241771d elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x424e94a8 inet6_getname +EXPORT_SYMBOL vmlinux 0x4271a615 svc_proc_register +EXPORT_SYMBOL vmlinux 0x427ed53c sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x42c938dd udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x430205aa __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x430223f4 nf_reinject +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x4317a57a scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x434cf4b6 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435cfd29 input_set_capability +EXPORT_SYMBOL vmlinux 0x436f785d blk_rq_init +EXPORT_SYMBOL vmlinux 0x439a4b73 d_alloc_name +EXPORT_SYMBOL vmlinux 0x43ae1de5 vfs_llseek +EXPORT_SYMBOL vmlinux 0x43b0c9c3 preempt_schedule +EXPORT_SYMBOL vmlinux 0x43c8e759 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x43e54ecb neigh_destroy +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x44643b93 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x448d0607 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x44ad6617 vfs_symlink +EXPORT_SYMBOL vmlinux 0x44b60892 sock_recvmsg +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44c214d1 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x44cd4ee4 bdi_register_dev +EXPORT_SYMBOL vmlinux 0x44da5d0f __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x44e7eaf8 skb_copy +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x45351660 elv_queue_empty +EXPORT_SYMBOL vmlinux 0x457fc608 scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x45a55ec8 __iounmap +EXPORT_SYMBOL vmlinux 0x45b1aaf5 __nla_reserve +EXPORT_SYMBOL vmlinux 0x45bda0d5 system_serial_low +EXPORT_SYMBOL vmlinux 0x45c602f7 generic_write_end +EXPORT_SYMBOL vmlinux 0x45f2e02e ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x461d5e93 dev_get_flags +EXPORT_SYMBOL vmlinux 0x461d9b23 simple_readpage +EXPORT_SYMBOL vmlinux 0x4628d4a0 kernel_listen +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x4646178f phy_driver_unregister +EXPORT_SYMBOL vmlinux 0x46c2a34c user_revoke +EXPORT_SYMBOL vmlinux 0x46d3a43f pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x46d3b28c __div0 +EXPORT_SYMBOL vmlinux 0x470f5470 register_gifconf +EXPORT_SYMBOL vmlinux 0x47162309 del_mtd_partitions +EXPORT_SYMBOL vmlinux 0x4719ba4e kfifo_free +EXPORT_SYMBOL vmlinux 0x4721de2e neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x4776988a kfree_skb +EXPORT_SYMBOL vmlinux 0x477ab568 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x478b8818 sysctl_data +EXPORT_SYMBOL vmlinux 0x47a1f3b7 read_dev_sector +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47f757de elf_platform +EXPORT_SYMBOL vmlinux 0x48034724 zlib_deflateReset +EXPORT_SYMBOL vmlinux 0x480d00f9 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x4821007b xdr_buf_read_netobj +EXPORT_SYMBOL vmlinux 0x4827d8b4 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x4840f9fb iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x48478d6f xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x488d4d05 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x48a5b067 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x48af5a85 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x48b0097a ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x48be9058 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x48f9f12d complete_all +EXPORT_SYMBOL vmlinux 0x49387a4c blk_recount_segments +EXPORT_SYMBOL vmlinux 0x493d093c find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49a2d8e3 __scsi_add_device +EXPORT_SYMBOL vmlinux 0x49a9c184 take_over_console +EXPORT_SYMBOL vmlinux 0x49be262e scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x49f117c4 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x49fe0156 udp_ioctl +EXPORT_SYMBOL vmlinux 0x4a01ef87 __lock_page +EXPORT_SYMBOL vmlinux 0x4a07e8a9 do_SAK +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a58070e blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4acfd8ad down_interruptible +EXPORT_SYMBOL vmlinux 0x4ae580f3 proc_symlink +EXPORT_SYMBOL vmlinux 0x4ae714a9 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x4aea4791 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b8edde9 complete_and_exit +EXPORT_SYMBOL vmlinux 0x4b90cc52 input_unregister_device +EXPORT_SYMBOL vmlinux 0x4b9f3684 kfifo_init +EXPORT_SYMBOL vmlinux 0x4baaa9b5 input_register_device +EXPORT_SYMBOL vmlinux 0x4bbe6eff simple_pin_fs +EXPORT_SYMBOL vmlinux 0x4bbff4d1 kill_pid +EXPORT_SYMBOL vmlinux 0x4bcb32aa new_inode +EXPORT_SYMBOL vmlinux 0x4bccc4c2 path_lookup +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c1a1abb set_binfmt +EXPORT_SYMBOL vmlinux 0x4c6a42cb pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x4c6ff041 add_preempt_count +EXPORT_SYMBOL vmlinux 0x4c7c31d0 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x4c7db3d4 journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x4c87f060 dev_add_pack +EXPORT_SYMBOL vmlinux 0x4ca159d5 mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0x4cb54422 flush_dcache_page +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cd5817c journal_start_commit +EXPORT_SYMBOL vmlinux 0x4cfb0d2f load_nls +EXPORT_SYMBOL vmlinux 0x4d0b9831 pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x4d0d163d copy_page +EXPORT_SYMBOL vmlinux 0x4d21496c n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d413672 svc_authenticate +EXPORT_SYMBOL vmlinux 0x4d5e685e pcim_iounmap +EXPORT_SYMBOL vmlinux 0x4d6214d7 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x4d85a626 journal_update_format +EXPORT_SYMBOL vmlinux 0x4d8d0ffa tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x4db05540 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x4dbccf14 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0x4dbf9dbd input_grab_device +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4ddec102 put_disk +EXPORT_SYMBOL vmlinux 0x4dec6038 memscan +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4df9e392 inetdev_by_index +EXPORT_SYMBOL vmlinux 0x4e0009da idr_get_new_above +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e393754 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x4e3e972d xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x4e624863 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x4e64e52c page_follow_link_light +EXPORT_SYMBOL vmlinux 0x4e664ce0 redraw_screen +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4e97a2e9 path_put +EXPORT_SYMBOL vmlinux 0x4e9d62a9 sock_no_connect +EXPORT_SYMBOL vmlinux 0x4ebb1a11 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x4ee4b837 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x4f0ea0c0 up +EXPORT_SYMBOL vmlinux 0x4f1c5e79 skb_unlink +EXPORT_SYMBOL vmlinux 0x4f1db3ac generic_ro_fops +EXPORT_SYMBOL vmlinux 0x4f4c346c journal_destroy +EXPORT_SYMBOL vmlinux 0x4f4ca0ca __elv_add_request +EXPORT_SYMBOL vmlinux 0x4f5154f0 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x4f52c990 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x4f5651c3 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x4f687843 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x4f8a79a4 generic_delete_inode +EXPORT_SYMBOL vmlinux 0x4f915f81 sk_wait_data +EXPORT_SYMBOL vmlinux 0x4fc4b24a __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x4fd04261 scsi_register_driver +EXPORT_SYMBOL vmlinux 0x4fdb2b07 brioctl_set +EXPORT_SYMBOL vmlinux 0x4fdf41d7 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x4fe5fc75 dev_mc_delete +EXPORT_SYMBOL vmlinux 0x4fe93567 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x50280a2d ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x502d8f3a auth_unix_forget_old +EXPORT_SYMBOL vmlinux 0x503a2db7 pci_request_regions +EXPORT_SYMBOL vmlinux 0x506156fd mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x50625634 proc_mkdir +EXPORT_SYMBOL vmlinux 0x50863c84 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x5093fa82 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x50a0aada qdisc_list_del +EXPORT_SYMBOL vmlinux 0x50fb10bd bdget +EXPORT_SYMBOL vmlinux 0x50fed6f7 proc_ide_read_geometry +EXPORT_SYMBOL vmlinux 0x51198ab1 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x51493d94 finish_wait +EXPORT_SYMBOL vmlinux 0x516b0e60 mntput_no_expire +EXPORT_SYMBOL vmlinux 0x5171a87e feroceon_clear_user_page +EXPORT_SYMBOL vmlinux 0x51908eb8 __raw_writesl +EXPORT_SYMBOL vmlinux 0x519cd8a9 bio_sector_offset +EXPORT_SYMBOL vmlinux 0x519d53ec dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x51a6a358 pci_set_mwi +EXPORT_SYMBOL vmlinux 0x51a76958 mii_check_media +EXPORT_SYMBOL vmlinux 0x51c60bf2 seq_open_private +EXPORT_SYMBOL vmlinux 0x51cd47e2 groups_alloc +EXPORT_SYMBOL vmlinux 0x51d311d6 lock_may_read +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51e11b0e km_policy_expired +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x520dcacd scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x52354a0b mutex_trylock +EXPORT_SYMBOL vmlinux 0x5237946e pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x524f8e17 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x5250cdab ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0x5283ede6 scsi_unregister +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a285d9 ___pskb_trim +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x533d03c3 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x541237b6 update_region +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x543b580f inet_listen +EXPORT_SYMBOL vmlinux 0x549df021 do_splice_to +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x54f9f73a i2c_get_adapter +EXPORT_SYMBOL vmlinux 0x5504df3d generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55c4efaf remove_arg_zero +EXPORT_SYMBOL vmlinux 0x55f2ec6c dma_unmap_sg +EXPORT_SYMBOL vmlinux 0x55f7d3d3 bdi_register +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x562c6b13 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x5678701d register_sysctl_table +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56ef02cd tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x56f07154 svc_auth_register +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x575eb3b2 inode_setattr +EXPORT_SYMBOL vmlinux 0x57715ea5 unregister_filesystem +EXPORT_SYMBOL vmlinux 0x57806f2f per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57c9b702 noop_qdisc +EXPORT_SYMBOL vmlinux 0x57d63c1b pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x57ed58a3 kobject_get +EXPORT_SYMBOL vmlinux 0x58051a78 dput +EXPORT_SYMBOL vmlinux 0x583692b8 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x58393143 sock_kmalloc +EXPORT_SYMBOL vmlinux 0x5841ac65 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x58a310ff starget_for_each_device +EXPORT_SYMBOL vmlinux 0x58b4fd52 scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x58d4afcf xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x58d7f78c xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x58e0c277 key_put +EXPORT_SYMBOL vmlinux 0x58e96fca kill_fasync +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x594e1317 __modsi3 +EXPORT_SYMBOL vmlinux 0x594f5851 svc_wake_up +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x598ab408 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59e5070d __do_div64 +EXPORT_SYMBOL vmlinux 0x5a100343 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x5a17b06d netlink_broadcast +EXPORT_SYMBOL vmlinux 0x5a207eb8 skb_dequeue +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5aeb9d0d single_open +EXPORT_SYMBOL vmlinux 0x5b051fb1 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x5b0ca864 pneigh_lookup +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b296506 neigh_seq_start +EXPORT_SYMBOL vmlinux 0x5b453ac6 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x5bd0bbda netlink_dump_start +EXPORT_SYMBOL vmlinux 0x5bd3c647 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x5be3704e generic_getxattr +EXPORT_SYMBOL vmlinux 0x5beb7b4b wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x5c03ce79 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x5c673bc8 tty_mutex +EXPORT_SYMBOL vmlinux 0x5c9284a0 processor_id +EXPORT_SYMBOL vmlinux 0x5c96648a xdr_read_pages +EXPORT_SYMBOL vmlinux 0x5cbac0ee i2c_register_driver +EXPORT_SYMBOL vmlinux 0x5cfd2e44 input_allocate_device +EXPORT_SYMBOL vmlinux 0x5d0782d2 seq_escape +EXPORT_SYMBOL vmlinux 0x5d0a7826 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x5d0f52ff ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x5d4fe63d blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x5dc364d4 pci_find_slot +EXPORT_SYMBOL vmlinux 0x5ddebd9d sock_wake_async +EXPORT_SYMBOL vmlinux 0x5e0c3424 sg_miter_start +EXPORT_SYMBOL vmlinux 0x5e28c0ec simple_rmdir +EXPORT_SYMBOL vmlinux 0x5e31276e qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x5e498ea2 log_wait_commit +EXPORT_SYMBOL vmlinux 0x5e4e1605 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x5e53f1d3 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x5e5c8b03 scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x5e6eb6cb revalidate_disk +EXPORT_SYMBOL vmlinux 0x5e78331e d_delete +EXPORT_SYMBOL vmlinux 0x5e94e149 names_cachep +EXPORT_SYMBOL vmlinux 0x5ea0c872 ide_end_request +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ebb56fb down_read +EXPORT_SYMBOL vmlinux 0x5ec48f87 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f754e5a memset +EXPORT_SYMBOL vmlinux 0x5f86528a __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x5f96866b auth_domain_find +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x6028bb76 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x602d47c0 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x608b0bff d_lookup +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x608eab9a per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60a476b0 remove_proc_entry +EXPORT_SYMBOL vmlinux 0x60a4efe2 ida_get_new +EXPORT_SYMBOL vmlinux 0x60b661cb i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x60def33a kobject_add +EXPORT_SYMBOL vmlinux 0x6108d848 inode_double_lock +EXPORT_SYMBOL vmlinux 0x612e75c8 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x61593b72 __mod_timer +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61a2f456 dst_discard +EXPORT_SYMBOL vmlinux 0x61b644b8 journal_load +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61cdeb2b sync_page_range +EXPORT_SYMBOL vmlinux 0x62106d61 write_one_page +EXPORT_SYMBOL vmlinux 0x621ca62c blk_get_request +EXPORT_SYMBOL vmlinux 0x622704b2 auth_unix_lookup +EXPORT_SYMBOL vmlinux 0x62334ee5 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x6254f4a2 neigh_create +EXPORT_SYMBOL vmlinux 0x626ba05f phy_start_interrupts +EXPORT_SYMBOL vmlinux 0x62716f6a find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62e2794b dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0x62eb52da generic_block_fiemap +EXPORT_SYMBOL vmlinux 0x631ebd65 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x632d88aa copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x634a1bb8 mb_cache_create +EXPORT_SYMBOL vmlinux 0x634f66e0 no_llseek +EXPORT_SYMBOL vmlinux 0x6384d69b __mpage_writepage +EXPORT_SYMBOL vmlinux 0x63d8c77e vfs_rmdir +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63fa08c1 journal_flush +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640a7078 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x642a433e blk_init_tags +EXPORT_SYMBOL vmlinux 0x64461a52 seq_printf +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x6499af38 sunrpc_cache_update +EXPORT_SYMBOL vmlinux 0x64a8f9c0 vfs_link +EXPORT_SYMBOL vmlinux 0x64b6ef78 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x64bc6dfb dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0x64cf5ad0 simple_sync_file +EXPORT_SYMBOL vmlinux 0x64f2981a request_key_async +EXPORT_SYMBOL vmlinux 0x64fd92e0 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0x650c2598 bdev_read_only +EXPORT_SYMBOL vmlinux 0x651293d7 fget +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x651d50ec sock_no_mmap +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6572fdfb set_irq_chip +EXPORT_SYMBOL vmlinux 0x65a1c920 svc_create_pooled +EXPORT_SYMBOL vmlinux 0x65a5c3a2 cpu_present_map +EXPORT_SYMBOL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL vmlinux 0x65f7946b bio_phys_segments +EXPORT_SYMBOL vmlinux 0x661e6ec8 bioset_free +EXPORT_SYMBOL vmlinux 0x661f3cb6 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x6626afe8 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x66597038 dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0x665c7269 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x667f63cd pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x668c30b5 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66bec672 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x66cb44aa cfi_varsize_frob +EXPORT_SYMBOL vmlinux 0x66cf36b4 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x66e396c4 xfrm_nl +EXPORT_SYMBOL vmlinux 0x66e71c58 elv_rb_add +EXPORT_SYMBOL vmlinux 0x672c8ebe file_fsync +EXPORT_SYMBOL vmlinux 0x6751bc50 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c2fa54 __copy_to_user +EXPORT_SYMBOL vmlinux 0x67d1728e scsi_execute_req +EXPORT_SYMBOL vmlinux 0x67f06dd4 skb_insert +EXPORT_SYMBOL vmlinux 0x67f81bb2 scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x6800c908 devm_iounmap +EXPORT_SYMBOL vmlinux 0x683a8121 notify_change +EXPORT_SYMBOL vmlinux 0x6895b9ed kill_litter_super +EXPORT_SYMBOL vmlinux 0x6898a756 sg_init_table +EXPORT_SYMBOL vmlinux 0x68df3c7a sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x68e6699c do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x68fdf2f7 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x69033faf sget +EXPORT_SYMBOL vmlinux 0x690b040e get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x6914a2cf elevator_exit +EXPORT_SYMBOL vmlinux 0x6919dae4 open_by_devnum +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x6939755d pci_iomap +EXPORT_SYMBOL vmlinux 0x69496641 mod_timer +EXPORT_SYMBOL vmlinux 0x694cd29e dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x697ef230 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x69898ec0 dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69af2327 idr_init +EXPORT_SYMBOL vmlinux 0x69bfbdf8 sk_common_release +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a0e46d5 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x6a21ea85 pcibios_resource_to_bus +EXPORT_SYMBOL vmlinux 0x6a27a17b xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x6a2ffdac pcie_get_readrq +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a49f88c d_move +EXPORT_SYMBOL vmlinux 0x6a5c69eb journal_get_create_access +EXPORT_SYMBOL vmlinux 0x6abbbd20 iput +EXPORT_SYMBOL vmlinux 0x6ac45c28 __up_write +EXPORT_SYMBOL vmlinux 0x6acb1726 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0x6ada6256 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0x6ae753b9 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b1c0991 unregister_binfmt +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6ba84c07 unregister_con_driver +EXPORT_SYMBOL vmlinux 0x6bba2fe7 neigh_lookup +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c24a0f9 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x6c36a5c1 __mutex_init +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6cb92c06 cache_purge +EXPORT_SYMBOL vmlinux 0x6cbec924 tty_free_termios +EXPORT_SYMBOL vmlinux 0x6ccb399e elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cef247f __strnlen_user +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d29208c pci_bus_type +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d662533 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x6d7dae94 get_sb_nodev +EXPORT_SYMBOL vmlinux 0x6d8fa772 xdr_decode_array2 +EXPORT_SYMBOL vmlinux 0x6d9a351e scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x6da8e44e dev_get_by_name +EXPORT_SYMBOL vmlinux 0x6db23795 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e0d23f7 put_tty_driver +EXPORT_SYMBOL vmlinux 0x6e2c7105 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x6e379e27 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e45e407 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x6e49cf18 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x6e5f7b36 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e84a85c save_time_delta +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ed73caf tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x6ed7f4e4 simple_empty +EXPORT_SYMBOL vmlinux 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL vmlinux 0x6f2c8e14 kill_block_super +EXPORT_SYMBOL vmlinux 0x6f709288 netif_rx +EXPORT_SYMBOL vmlinux 0x6f8efc05 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x6fb5c1e3 tty_name +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fd8edb5 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x6feb79aa blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x7012e227 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x7036466d try_to_release_page +EXPORT_SYMBOL vmlinux 0x703ea82b eth_header +EXPORT_SYMBOL vmlinux 0x706b448e __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x707c1456 tcp_prot +EXPORT_SYMBOL vmlinux 0x7102dd0e write_inode_now +EXPORT_SYMBOL vmlinux 0x710cb22a bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x711efe2e tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x713f5979 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x71673ded journal_dirty_data +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x717229ec path_permission +EXPORT_SYMBOL vmlinux 0x718d3b9c d_genocide +EXPORT_SYMBOL vmlinux 0x7190f643 locks_init_lock +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71c90087 memcmp +EXPORT_SYMBOL vmlinux 0x71d418b3 svc_create +EXPORT_SYMBOL vmlinux 0x71fa908a cache_flush +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x726a57a9 end_request +EXPORT_SYMBOL vmlinux 0x729abb01 thaw_bdev +EXPORT_SYMBOL vmlinux 0x72d5af61 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x72e2a02b textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fbae28 set_current_groups +EXPORT_SYMBOL vmlinux 0x72fcf909 neigh_update +EXPORT_SYMBOL vmlinux 0x73069aac cpu_possible_map +EXPORT_SYMBOL vmlinux 0x731f0d2c svc_process +EXPORT_SYMBOL vmlinux 0x735a2d7c neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x735d53d0 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x73a21e4a input_close_device +EXPORT_SYMBOL vmlinux 0x73bf400e tcp_poll +EXPORT_SYMBOL vmlinux 0x73c347c2 genphy_update_link +EXPORT_SYMBOL vmlinux 0x73c9de0d kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x73ff431e elv_add_request +EXPORT_SYMBOL vmlinux 0x740fad67 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x744f071a scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x74763bd7 __breadahead +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x7492cf08 find_lock_page +EXPORT_SYMBOL vmlinux 0x74b98e32 vm_insert_page +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x752d5220 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x75646e68 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x757d747e ip6_frag_init +EXPORT_SYMBOL vmlinux 0x758d8c07 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x75c317ae mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x75ca58de key_type_keyring +EXPORT_SYMBOL vmlinux 0x75e19fa6 __alloc_skb +EXPORT_SYMBOL vmlinux 0x75e29e86 generic_writepages +EXPORT_SYMBOL vmlinux 0x75fee7fd __raw_writesb +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x760d9125 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x762ee22c xfrm_state_update +EXPORT_SYMBOL vmlinux 0x765f75fb pgprot_user +EXPORT_SYMBOL vmlinux 0x76881360 leds_event +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76c05ae9 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x76cf47f6 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76de7536 set_bh_page +EXPORT_SYMBOL vmlinux 0x76ef4844 bio_free +EXPORT_SYMBOL vmlinux 0x77b79b58 find_inode_number +EXPORT_SYMBOL vmlinux 0x77c4bbd0 xdr_decode_word +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x77f4d947 rpc_unlink +EXPORT_SYMBOL vmlinux 0x77f967d5 dcache_readdir +EXPORT_SYMBOL vmlinux 0x77fcf7a7 netdev_state_change +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x7893d9ad netif_device_detach +EXPORT_SYMBOL vmlinux 0x78aa2d87 nf_register_hooks +EXPORT_SYMBOL vmlinux 0x78bff9c9 pci_release_region +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x78eeaea6 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x78ef986b scm_fp_dup +EXPORT_SYMBOL vmlinux 0x793961d7 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x79600d4a wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79ad224b tasklet_kill +EXPORT_SYMBOL vmlinux 0x79eb072b arp_broken_ops +EXPORT_SYMBOL vmlinux 0x7a004f85 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x7a0ba3fa tty_unregister_device +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a2e9d53 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0x7aaca93e tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x7ae2a10d dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x7af3cb04 d_path +EXPORT_SYMBOL vmlinux 0x7b339f95 mdiobus_write +EXPORT_SYMBOL vmlinux 0x7b40340e rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x7b684f63 journal_forget +EXPORT_SYMBOL vmlinux 0x7b7aa3f9 rpc_mkpipe +EXPORT_SYMBOL vmlinux 0x7b879953 dentry_open +EXPORT_SYMBOL vmlinux 0x7b9161f3 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x7b93d7f8 block_sync_page +EXPORT_SYMBOL vmlinux 0x7b9abf8a tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x7c1cb28a balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0x7c494441 pcibios_bus_to_resource +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c90cc20 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x7cc035a7 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x7ccfe391 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d5d59f4 vmtruncate +EXPORT_SYMBOL vmlinux 0x7d7a25fd arp_xmit +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7db525b1 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7dcf1ada init_buffer +EXPORT_SYMBOL vmlinux 0x7de343ac pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x7e012d8b sysctl_intvec +EXPORT_SYMBOL vmlinux 0x7e144e61 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x7e20d054 mpage_readpage +EXPORT_SYMBOL vmlinux 0x7e3f41d5 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x7e4afb50 auth_domain_lookup +EXPORT_SYMBOL vmlinux 0x7e531cde del_timer +EXPORT_SYMBOL vmlinux 0x7e5d99b5 bio_endio +EXPORT_SYMBOL vmlinux 0x7e70566b pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x7e7a1ad8 generic_readlink +EXPORT_SYMBOL vmlinux 0x7e8a6d0d svc_prepare_thread +EXPORT_SYMBOL vmlinux 0x7e95c7c0 tty_kref_put +EXPORT_SYMBOL vmlinux 0x7e96ec53 register_key_type +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ed84c33 misc_deregister +EXPORT_SYMBOL vmlinux 0x7f036e75 xdr_reserve_space +EXPORT_SYMBOL vmlinux 0x7f22cf0d nobh_writepage +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f51d3be inet_ioctl +EXPORT_SYMBOL vmlinux 0x7f57d1a5 open_exec +EXPORT_SYMBOL vmlinux 0x7f63b31e _memcpy_toio +EXPORT_SYMBOL vmlinux 0x7f68b914 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x7f77512d dma_async_device_register +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7faf64b2 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x7fbdba1a nla_reserve +EXPORT_SYMBOL vmlinux 0x800e4ffa __muldi3 +EXPORT_SYMBOL vmlinux 0x80222ea7 dentry_unhash +EXPORT_SYMBOL vmlinux 0x805da360 lease_get_mtime +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x8085c7b1 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x80ab6dbf kset_unregister +EXPORT_SYMBOL vmlinux 0x80c3d35c seq_bitmap +EXPORT_SYMBOL vmlinux 0x80c86e15 kill_anon_super +EXPORT_SYMBOL vmlinux 0x80d2cd19 input_free_device +EXPORT_SYMBOL vmlinux 0x810c0ab7 dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0x81105e68 get_sb_single +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x816220ef ide_dump_status +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x81815096 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x8187b1d2 auth_domain_put +EXPORT_SYMBOL vmlinux 0x819271bb uart_update_timeout +EXPORT_SYMBOL vmlinux 0x81c095db flush_old_exec +EXPORT_SYMBOL vmlinux 0x81f6eafc sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x8233f804 init_mm +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x8252b6a9 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x82692209 kref_set +EXPORT_SYMBOL vmlinux 0x828a1083 nf_getsockopt +EXPORT_SYMBOL vmlinux 0x8292a19d pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0x829a8335 generic_setlease +EXPORT_SYMBOL vmlinux 0x82b99753 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x82c90885 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x82e5a238 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x83148960 loop_register_transfer +EXPORT_SYMBOL vmlinux 0x8320bea8 __umodsi3 +EXPORT_SYMBOL vmlinux 0x8336ee36 skb_clone +EXPORT_SYMBOL vmlinux 0x83403f21 igrab +EXPORT_SYMBOL vmlinux 0x83491bd4 skb_push +EXPORT_SYMBOL vmlinux 0x8390961c block_invalidatepage +EXPORT_SYMBOL vmlinux 0x8399c7c8 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x839b15bc inet_accept +EXPORT_SYMBOL vmlinux 0x83a0eab7 __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83ab3008 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x83f3cc3d mpage_writepages +EXPORT_SYMBOL vmlinux 0x8429ae7e neigh_seq_next +EXPORT_SYMBOL vmlinux 0x8440cbda genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0x8445f1a2 tty_throttle +EXPORT_SYMBOL vmlinux 0x84787ad4 sk_receive_skb +EXPORT_SYMBOL vmlinux 0x84928529 start_tty +EXPORT_SYMBOL vmlinux 0x84aff9a0 follow_down +EXPORT_SYMBOL vmlinux 0x84b183ae strncmp +EXPORT_SYMBOL vmlinux 0x84fb2acb ilookup5 +EXPORT_SYMBOL vmlinux 0x84fd5259 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x84fe3b07 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x850e0e07 journal_ack_err +EXPORT_SYMBOL vmlinux 0x8510ad5a journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x85304dac bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x853635b4 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0x854a60b7 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x85591dc3 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x85a938d2 scsi_remove_target +EXPORT_SYMBOL vmlinux 0x85aa331b __grab_cache_page +EXPORT_SYMBOL vmlinux 0x85ac7f10 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e5ee9f gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x867e4573 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86cf2f22 skb_append +EXPORT_SYMBOL vmlinux 0x86dbed7f struct_module +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x87191d27 mem_map +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x872ae52b scsi_dma_map +EXPORT_SYMBOL vmlinux 0x8769bba6 kernel_getsockname +EXPORT_SYMBOL vmlinux 0x876c787c km_query +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x8797e02d __nla_put +EXPORT_SYMBOL vmlinux 0x87a1e899 udp_poll +EXPORT_SYMBOL vmlinux 0x87d2d7f2 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x87e3a43a vfs_getattr +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x8836a348 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x8852c5b7 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x88a5c2de scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x88c6e0fb input_unregister_handle +EXPORT_SYMBOL vmlinux 0x88cfbdac xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x88d21c8f tcp_splice_read +EXPORT_SYMBOL vmlinux 0x88df4505 simple_release_fs +EXPORT_SYMBOL vmlinux 0x891e32b8 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x892f5c07 sock_wfree +EXPORT_SYMBOL vmlinux 0x893dcd84 iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x8941069c block_commit_write +EXPORT_SYMBOL vmlinux 0x896b96df tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898951f1 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x898f6744 check_disk_change +EXPORT_SYMBOL vmlinux 0x89959e26 get_disk +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89db0a0e stop_tty +EXPORT_SYMBOL vmlinux 0x89dd9600 sock_init_data +EXPORT_SYMBOL vmlinux 0x8a1203a9 kref_get +EXPORT_SYMBOL vmlinux 0x8a4fa83b __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x8a54a3ae blk_stop_queue +EXPORT_SYMBOL vmlinux 0x8a627cad tcp_check_req +EXPORT_SYMBOL vmlinux 0x8a791c5b end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8ab956f7 pci_dev_get +EXPORT_SYMBOL vmlinux 0x8ab96b5f sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x8ad71045 iget_locked +EXPORT_SYMBOL vmlinux 0x8afbfbc5 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x8afc5d50 pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0x8b34669b uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x8b5db7da dma_pool_create +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b936338 vfs_permission +EXPORT_SYMBOL vmlinux 0x8b9a4149 ida_destroy +EXPORT_SYMBOL vmlinux 0x8bbc1f82 d_splice_alias +EXPORT_SYMBOL vmlinux 0x8bbfa2b9 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x8bc8b496 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x8bc997b6 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x8bdca8e8 inet_release +EXPORT_SYMBOL vmlinux 0x8bf5e8c0 set_blocksize +EXPORT_SYMBOL vmlinux 0x8c28cc29 ide_raw_taskfile +EXPORT_SYMBOL vmlinux 0x8c46b63b __pci_register_driver +EXPORT_SYMBOL vmlinux 0x8c686759 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x8c7bc348 ida_remove +EXPORT_SYMBOL vmlinux 0x8c84069c restore_time_delta +EXPORT_SYMBOL vmlinux 0x8c84b7e6 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x8c8f13b4 I_BDEV +EXPORT_SYMBOL vmlinux 0x8c9dbaaf neigh_parms_release +EXPORT_SYMBOL vmlinux 0x8c9df349 console_start +EXPORT_SYMBOL vmlinux 0x8cb7cc27 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x8cd66789 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x8ce3bf55 svc_seq_show +EXPORT_SYMBOL vmlinux 0x8cede404 skb_queue_tail +EXPORT_SYMBOL vmlinux 0x8d3222bd dcache_dir_open +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d3d6453 tcp_child_process +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5642fc wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d778e29 save_mount_options +EXPORT_SYMBOL vmlinux 0x8da5f730 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x8dbbc422 submit_bio +EXPORT_SYMBOL vmlinux 0x8dcb5c27 idr_remove +EXPORT_SYMBOL vmlinux 0x8dfccd8d netif_device_attach +EXPORT_SYMBOL vmlinux 0x8e034532 clear_inode +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e160c25 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x8e1d52bf generic_removexattr +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e54ad89 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e89aae0 unlock_super +EXPORT_SYMBOL vmlinux 0x8eb8dd4a scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x8ec163e5 nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x8ee0b767 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x8ef66374 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x8f07d8ca __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8f27c39f input_flush_device +EXPORT_SYMBOL vmlinux 0x8f6128fe blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x8f67ca35 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f9b86b2 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x8fbcf900 input_open_device +EXPORT_SYMBOL vmlinux 0x8fe3c489 make_bad_inode +EXPORT_SYMBOL vmlinux 0x8fea7050 do_sync_read +EXPORT_SYMBOL vmlinux 0x9002445d unload_nls +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x9017e86f cache_check +EXPORT_SYMBOL vmlinux 0x9032252f force_sig +EXPORT_SYMBOL vmlinux 0x906ad67c request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x9098a568 pci_choose_state +EXPORT_SYMBOL vmlinux 0x909a3fc0 elv_next_request +EXPORT_SYMBOL vmlinux 0x90e39723 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x90e93cb4 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x910a9258 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x911831d6 deactivate_super +EXPORT_SYMBOL vmlinux 0x911ace65 skb_over_panic +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x9149b8a5 d_alloc +EXPORT_SYMBOL vmlinux 0x915515da kmem_cache_name +EXPORT_SYMBOL vmlinux 0x91901701 free_netdev +EXPORT_SYMBOL vmlinux 0x919029aa __readwrite_bug +EXPORT_SYMBOL vmlinux 0x91abc05c ip6_xmit +EXPORT_SYMBOL vmlinux 0x91bc7fcf xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x926401f2 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x928eb60a seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x92b5ff24 tty_shutdown +EXPORT_SYMBOL vmlinux 0x92ed7ec8 ll_rw_block +EXPORT_SYMBOL vmlinux 0x92fd45cf i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x9320f0fa mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x9382828a sock_no_getname +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x947a5bd4 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x949124fa dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94c1dd89 phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0x94ee58bd block_write_end +EXPORT_SYMBOL vmlinux 0x94f9e276 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x9501d078 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x95277179 d_add_ci +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x9592fcd5 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x959c08a2 __f_setown +EXPORT_SYMBOL vmlinux 0x95d61fa5 nobh_write_end +EXPORT_SYMBOL vmlinux 0x95dbe078 __get_user_2 +EXPORT_SYMBOL vmlinux 0x95e14026 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x95f746e3 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x960661f4 gpio_get_value +EXPORT_SYMBOL vmlinux 0x96328056 register_binfmt +EXPORT_SYMBOL vmlinux 0x967a7969 skb_copy_bits +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x9699b9d4 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96df5482 walk_stackframe +EXPORT_SYMBOL vmlinux 0x9705916d scsi_remove_device +EXPORT_SYMBOL vmlinux 0x97255bdf strlen +EXPORT_SYMBOL vmlinux 0x97427cf9 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x978d60fa pci_get_class +EXPORT_SYMBOL vmlinux 0x97b96de4 kernel_bind +EXPORT_SYMBOL vmlinux 0x97de7b9a i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x97e902ba inet_del_protocol +EXPORT_SYMBOL vmlinux 0x9803ee1f qdisc_reset +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x98198532 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x9823ef90 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x9844d234 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x9849d6c1 bio_clone +EXPORT_SYMBOL vmlinux 0x985eb9f4 scsi_host_put +EXPORT_SYMBOL vmlinux 0x9863524f scsi_add_host +EXPORT_SYMBOL vmlinux 0x988b8f07 bd_claim +EXPORT_SYMBOL vmlinux 0x98985094 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x98b32185 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x98c931bc contig_page_data +EXPORT_SYMBOL vmlinux 0x98d460a5 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x99192d1e tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x993fb142 register_filesystem +EXPORT_SYMBOL vmlinux 0x99536859 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x995f6d36 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x9979d3ac vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x9983a24e get_super +EXPORT_SYMBOL vmlinux 0x999c3148 __raw_readsb +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bb8806 memmove +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99c7331a blk_init_queue +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99d873b3 arp_tbl +EXPORT_SYMBOL vmlinux 0x99df3f77 del_gendisk +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x9a0e442d ip6_frag_match +EXPORT_SYMBOL vmlinux 0x9a108cd3 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a365b8b flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x9a36eeab tcp_read_sock +EXPORT_SYMBOL vmlinux 0x9a3e9625 filp_open +EXPORT_SYMBOL vmlinux 0x9a6405bd blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x9aa05777 put_filp +EXPORT_SYMBOL vmlinux 0x9aa074a9 genl_sock +EXPORT_SYMBOL vmlinux 0x9aad05a8 ipv4_specific +EXPORT_SYMBOL vmlinux 0x9ac51216 dget_locked +EXPORT_SYMBOL vmlinux 0x9aeb609c ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x9af5fc77 scsi_get_command +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b4b3e04 unregister_console +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bad448a scsi_init_io +EXPORT_SYMBOL vmlinux 0x9bb5cf72 rpc_queue_upcall +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9c0c2f36 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x9c2571f4 __down_read +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d088cf3 simple_write_begin +EXPORT_SYMBOL vmlinux 0x9d11d229 ide_do_drive_cmd +EXPORT_SYMBOL vmlinux 0x9d11f80a load_nls_default +EXPORT_SYMBOL vmlinux 0x9d2a7663 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x9d669763 memcpy +EXPORT_SYMBOL vmlinux 0x9d82540e vc_resize +EXPORT_SYMBOL vmlinux 0x9da47454 journal_create +EXPORT_SYMBOL vmlinux 0x9e120414 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x9e4313a6 input_release_device +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e96d04a shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x9e9b7b6d __dst_free +EXPORT_SYMBOL vmlinux 0x9e9d78aa mtd_do_chip_probe +EXPORT_SYMBOL vmlinux 0x9ea26f35 pci_set_master +EXPORT_SYMBOL vmlinux 0x9ebb69db blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x9ebd5f0d devm_free_irq +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9efe8363 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f17e7c0 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fb71772 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x9fd6cf48 unregister_key_type +EXPORT_SYMBOL vmlinux 0x9fd7e4e4 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x9fec30ca kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x9ffc0528 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0xa00b9276 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0xa024424c xdr_encode_array2 +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa07a8d22 sleep_on +EXPORT_SYMBOL vmlinux 0xa07ac24b irq_stat +EXPORT_SYMBOL vmlinux 0xa082d87e generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0bcea25 flush_signals +EXPORT_SYMBOL vmlinux 0xa0ce5024 generic_write_checks +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa11d1315 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa1443e66 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0xa1c75765 xdr_inline_pages +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1caa264 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0xa1e0ba04 i2c_del_driver +EXPORT_SYMBOL vmlinux 0xa2083d9a register_con_driver +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa218bf61 complete +EXPORT_SYMBOL vmlinux 0xa2583426 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xa26e372f task_nice +EXPORT_SYMBOL vmlinux 0xa270adee sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xa28b9e48 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xa29b1708 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2e1c192 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0xa3073ca3 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa33c2ff0 module_put +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa35b80fa page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa37df326 remove_inode_hash +EXPORT_SYMBOL vmlinux 0xa383e113 ide_proc_unregister_driver +EXPORT_SYMBOL vmlinux 0xa3926e2d sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0xa3a4ed03 cond_resched_lock +EXPORT_SYMBOL vmlinux 0xa3f08a0e bio_split +EXPORT_SYMBOL vmlinux 0xa41516b5 pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xa4411944 scsi_device_put +EXPORT_SYMBOL vmlinux 0xa45a6b8d dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0xa45cf777 tcp_proc_register +EXPORT_SYMBOL vmlinux 0xa462ca72 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0xa4aa741a invalidate_inodes +EXPORT_SYMBOL vmlinux 0xa4e872e8 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0xa4fc36ee xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa57b1b5a xdr_encode_word +EXPORT_SYMBOL vmlinux 0xa57f5988 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xa5808bbf tasklet_init +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5a187a2 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xa5c1c45f dst_alloc +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5e1127a tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xa5e2db4e dma_pool_alloc +EXPORT_SYMBOL vmlinux 0xa636a8e1 __invalidate_device +EXPORT_SYMBOL vmlinux 0xa646c888 mdiobus_register +EXPORT_SYMBOL vmlinux 0xa65f3cec may_umount +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa684d80f netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa70c1251 pci_enable_wake +EXPORT_SYMBOL vmlinux 0xa7108314 xfrm_register_type +EXPORT_SYMBOL vmlinux 0xa72cfb77 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa7535655 dcache_dir_close +EXPORT_SYMBOL vmlinux 0xa7b91a7b lockd_down +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7d508be bio_put +EXPORT_SYMBOL vmlinux 0xa7f3ff0a pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0xa841dc22 inet_stream_connect +EXPORT_SYMBOL vmlinux 0xa84ab8f5 dev_change_flags +EXPORT_SYMBOL vmlinux 0xa87dc327 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0xa8810554 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0xa8a00254 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0xa8d15ebe request_key +EXPORT_SYMBOL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa92c155c scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0xa9b8c143 init_task +EXPORT_SYMBOL vmlinux 0xa9f1ed23 bit_waitqueue +EXPORT_SYMBOL vmlinux 0xa9f43405 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0xaa1715c4 generic_ide_ioctl +EXPORT_SYMBOL vmlinux 0xaa21edab filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xaa527612 __kfifo_put +EXPORT_SYMBOL vmlinux 0xaa5279f5 inet_sendmsg +EXPORT_SYMBOL vmlinux 0xaa636ed4 d_alloc_root +EXPORT_SYMBOL vmlinux 0xaa70a5ae tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0xaa79fd86 kthread_stop +EXPORT_SYMBOL vmlinux 0xaa92c4b6 get_sb_bdev +EXPORT_SYMBOL vmlinux 0xaab02ec1 svc_drop +EXPORT_SYMBOL vmlinux 0xaad4b2eb ip_route_me_harder +EXPORT_SYMBOL vmlinux 0xaae3f583 __kfree_skb +EXPORT_SYMBOL vmlinux 0xaae3f5cb __bread +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab53b0a8 mempool_alloc +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab64527d mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0xab680c96 __down_read_trylock +EXPORT_SYMBOL vmlinux 0xab6abab7 inet_frag_find +EXPORT_SYMBOL vmlinux 0xab892022 do_munmap +EXPORT_SYMBOL vmlinux 0xaba02ea2 locks_copy_lock +EXPORT_SYMBOL vmlinux 0xabad83d7 udp_hash_lock +EXPORT_SYMBOL vmlinux 0xabca8b35 blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xabcae3c2 dev_open +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabdccbe7 ide_end_drive_cmd +EXPORT_SYMBOL vmlinux 0xabe3fe19 input_register_handler +EXPORT_SYMBOL vmlinux 0xabe768de tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac43e506 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0xac4c8187 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0xac54fc9f mempool_destroy +EXPORT_SYMBOL vmlinux 0xac58c3e6 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xac5f113d cpu_all_bits +EXPORT_SYMBOL vmlinux 0xac60cab6 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0xac7797e8 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xaccf21a1 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xacfbff89 pskb_copy +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad58e7ab block_prepare_write +EXPORT_SYMBOL vmlinux 0xad5e042e unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xad9d910e simple_link +EXPORT_SYMBOL vmlinux 0xadb792c2 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0xadec2735 should_remove_suid +EXPORT_SYMBOL vmlinux 0xae5ec0a6 get_empty_filp +EXPORT_SYMBOL vmlinux 0xae7ac95e journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xae7c790f uart_get_divisor +EXPORT_SYMBOL vmlinux 0xae899ebe vm_map_ram +EXPORT_SYMBOL vmlinux 0xaeb9d97f ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xaec6319c tty_unthrottle +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed013b9 posix_acl_valid +EXPORT_SYMBOL vmlinux 0xaee0d8b4 scsi_free_command +EXPORT_SYMBOL vmlinux 0xaef5e872 inode_init_once +EXPORT_SYMBOL vmlinux 0xaf06c98a journal_wipe +EXPORT_SYMBOL vmlinux 0xaf0a02d2 con_copy_unimap +EXPORT_SYMBOL vmlinux 0xaf3e7d14 scsi_scan_target +EXPORT_SYMBOL vmlinux 0xaf50e76d elf_set_personality +EXPORT_SYMBOL vmlinux 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL vmlinux 0xaf69a967 iget5_locked +EXPORT_SYMBOL vmlinux 0xaf8aa518 system_rev +EXPORT_SYMBOL vmlinux 0xaff3edac vc_cons +EXPORT_SYMBOL vmlinux 0xb016a7c6 journal_force_commit +EXPORT_SYMBOL vmlinux 0xb0338647 mnt_pin +EXPORT_SYMBOL vmlinux 0xb0417953 i2c_verify_client +EXPORT_SYMBOL vmlinux 0xb06df12b dev_mc_sync +EXPORT_SYMBOL vmlinux 0xb06e766d pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0be2e98 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb10d39b6 __lock_buffer +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb12c9754 dmam_pool_create +EXPORT_SYMBOL vmlinux 0xb18f3f06 ide_xfer_verbose +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cccf94 pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0xb1ce0dff xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xb1d5c9b6 xfrm_register_km +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb1fc1e86 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0xb1ff6ce4 elv_rb_find +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb25ad749 block_truncate_page +EXPORT_SYMBOL vmlinux 0xb25e97e9 __bforget +EXPORT_SYMBOL vmlinux 0xb276f71a find_or_create_page +EXPORT_SYMBOL vmlinux 0xb27ad417 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0xb2906944 key_payload_reserve +EXPORT_SYMBOL vmlinux 0xb2bd0464 d_validate +EXPORT_SYMBOL vmlinux 0xb2bf1312 __up_read +EXPORT_SYMBOL vmlinux 0xb2c21ca9 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xb31d209b pci_dev_put +EXPORT_SYMBOL vmlinux 0xb32fd0f4 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0xb33c7f8e ide_proc_register_driver +EXPORT_SYMBOL vmlinux 0xb35761d5 mdiobus_unregister +EXPORT_SYMBOL vmlinux 0xb35e6b09 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb382d868 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3af4eb4 tcf_hash_check +EXPORT_SYMBOL vmlinux 0xb3e20622 bdevname +EXPORT_SYMBOL vmlinux 0xb3f9bca6 fd_install +EXPORT_SYMBOL vmlinux 0xb3fe02b1 down_write +EXPORT_SYMBOL vmlinux 0xb4164cfb __netif_schedule +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb44dd110 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0xb45c92d5 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xb483201b nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xb4a0e989 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0xb4a405c7 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xb4a94c28 unregister_netdevice +EXPORT_SYMBOL vmlinux 0xb4aa67df simple_lookup +EXPORT_SYMBOL vmlinux 0xb4b45357 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xb50259ef xdr_process_buf +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb534763c sg_free_table +EXPORT_SYMBOL vmlinux 0xb53f6c05 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0xb5401c40 read_cache_page +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb56477d8 locks_remove_posix +EXPORT_SYMBOL vmlinux 0xb575acb3 dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0xb57f04aa inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0xb5a2e9ba dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5be9bc5 journal_check_used_features +EXPORT_SYMBOL vmlinux 0xb5c20cd9 __kill_fasync +EXPORT_SYMBOL vmlinux 0xb5cf754b pci_reenable_device +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb627524c xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0xb6327ef7 init_special_inode +EXPORT_SYMBOL vmlinux 0xb637d1e7 orion5x_gpio_set_blink +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb679015e nf_log_register +EXPORT_SYMBOL vmlinux 0xb6979817 xdr_init_decode +EXPORT_SYMBOL vmlinux 0xb69f9d6c kern_path +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c70a7d __wake_up +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb7166df1 elv_rb_del +EXPORT_SYMBOL vmlinux 0xb74f55b3 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb75f4bbc scsi_put_command +EXPORT_SYMBOL vmlinux 0xb76e48e9 get_write_access +EXPORT_SYMBOL vmlinux 0xb773da5c is_bad_inode +EXPORT_SYMBOL vmlinux 0xb78acff5 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xb798898c __napi_schedule +EXPORT_SYMBOL vmlinux 0xb7aa1ee1 get_io_context +EXPORT_SYMBOL vmlinux 0xb7ad3321 ida_init +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb805c490 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xb8148baa xfrm_state_add +EXPORT_SYMBOL vmlinux 0xb84eca0c console_stop +EXPORT_SYMBOL vmlinux 0xb84ed557 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xb856e365 register_netdevice +EXPORT_SYMBOL vmlinux 0xb859f38b krealloc +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb89c7f16 lookup_bdev +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8b03511 skb_under_panic +EXPORT_SYMBOL vmlinux 0xb8d79440 genphy_config_aneg +EXPORT_SYMBOL vmlinux 0xb9010e6f genphy_config_advert +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb959d989 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0xb95f98d6 _memset_io +EXPORT_SYMBOL vmlinux 0xb97d4c9c mutex_lock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb98ef804 vm_stat +EXPORT_SYMBOL vmlinux 0xb998c4bf cfi_read_pri +EXPORT_SYMBOL vmlinux 0xb9acd3d9 __put_user_2 +EXPORT_SYMBOL vmlinux 0xb9b50a2c ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0xb9c08e1f d_namespace_path +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9dab1e5 scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0xb9fadf14 dma_free_coherent +EXPORT_SYMBOL vmlinux 0xba16777a blk_verify_command +EXPORT_SYMBOL vmlinux 0xba3bda2a __downgrade_write +EXPORT_SYMBOL vmlinux 0xba3db9aa seq_release_private +EXPORT_SYMBOL vmlinux 0xba421af5 simple_statfs +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba8f8b68 completion_done +EXPORT_SYMBOL vmlinux 0xbaba703c complete_request_key +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb37d696 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0xbb42ce71 icmp_send +EXPORT_SYMBOL vmlinux 0xbb460581 nla_put +EXPORT_SYMBOL vmlinux 0xbb56f7fa kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb72d4fe __put_user_1 +EXPORT_SYMBOL vmlinux 0xbb86fabe sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0xbbbf987f posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbdf0fb6 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0xbc10dd97 __put_user_4 +EXPORT_SYMBOL vmlinux 0xbc5768e4 poll_initwait +EXPORT_SYMBOL vmlinux 0xbc8e5e98 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0xbc9822bc inet6_del_protocol +EXPORT_SYMBOL vmlinux 0xbc9f6e7b ndisc_mc_map +EXPORT_SYMBOL vmlinux 0xbcb8462e bdi_unregister +EXPORT_SYMBOL vmlinux 0xbcf24a42 dev_driver_string +EXPORT_SYMBOL vmlinux 0xbcfea6c9 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0xbd6073bd secpath_dup +EXPORT_SYMBOL vmlinux 0xbda9bfe7 con_set_default_unimap +EXPORT_SYMBOL vmlinux 0xbdbf5385 tty_register_device +EXPORT_SYMBOL vmlinux 0xbddd7631 scsi_register +EXPORT_SYMBOL vmlinux 0xbdf2580d __raw_readsl +EXPORT_SYMBOL vmlinux 0xbdf3963b ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe18a666 arp_create +EXPORT_SYMBOL vmlinux 0xbe4ce513 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0xbe512993 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe82135b cad_pid +EXPORT_SYMBOL vmlinux 0xbe9848ea tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0xbec0d1e5 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xbed60566 sub_preempt_count +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbef48882 sock_no_bind +EXPORT_SYMBOL vmlinux 0xbf1759f9 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xbf32eda3 sock_release +EXPORT_SYMBOL vmlinux 0xbf502bc2 vfs_unlink +EXPORT_SYMBOL vmlinux 0xbf7fac52 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf8f21b9 sock_wmalloc +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfb968a5 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0xbfc1adc2 register_exec_domain +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc0382933 ilookup +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc04aff02 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc05fd256 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0xc0635715 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0xc07dfe07 kobject_del +EXPORT_SYMBOL vmlinux 0xc09365b5 journal_get_write_access +EXPORT_SYMBOL vmlinux 0xc0f29d0c devm_ioremap +EXPORT_SYMBOL vmlinux 0xc11a46bf pskb_expand_head +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc13f9c9b feroceon_copy_user_page +EXPORT_SYMBOL vmlinux 0xc1601a4f _change_bit_le +EXPORT_SYMBOL vmlinux 0xc17e4e17 pci_remove_bus +EXPORT_SYMBOL vmlinux 0xc1834d97 __scm_destroy +EXPORT_SYMBOL vmlinux 0xc1b96e7e simple_dir_operations +EXPORT_SYMBOL vmlinux 0xc1e3f86b ide_do_reset +EXPORT_SYMBOL vmlinux 0xc1ef5ff7 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xc1f451a4 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0xc1fc4511 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0xc20dd177 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0xc21c1ac8 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xc22616f1 __init_rwsem +EXPORT_SYMBOL vmlinux 0xc23b7cb4 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0xc2416a62 mii_check_link +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc27487dd __bug +EXPORT_SYMBOL vmlinux 0xc28d2989 svc_exit_thread +EXPORT_SYMBOL vmlinux 0xc297ff27 skb_split +EXPORT_SYMBOL vmlinux 0xc29d3161 sock_kfree_s +EXPORT_SYMBOL vmlinux 0xc2b36649 iunique +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc320633b skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xc3520f8f keyring_search +EXPORT_SYMBOL vmlinux 0xc355827a pci_release_regions +EXPORT_SYMBOL vmlinux 0xc359fb65 abort +EXPORT_SYMBOL vmlinux 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL vmlinux 0xc38b5f30 get_fs_type +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3d2378f dma_sync_wait +EXPORT_SYMBOL vmlinux 0xc3d6fd86 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xc3e11964 kobject_set_name +EXPORT_SYMBOL vmlinux 0xc404656c dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0xc40f91c2 gpio_set_value +EXPORT_SYMBOL vmlinux 0xc41fc953 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xc440c451 sg_alloc_table +EXPORT_SYMBOL vmlinux 0xc4510405 dev_load +EXPORT_SYMBOL vmlinux 0xc45d9b40 pci_assign_resource +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc513cc0f blk_start_queueing +EXPORT_SYMBOL vmlinux 0xc51bd03f bio_alloc +EXPORT_SYMBOL vmlinux 0xc5241aa1 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0xc52d154f send_sig +EXPORT_SYMBOL vmlinux 0xc558c9d1 bio_copy_kern +EXPORT_SYMBOL vmlinux 0xc55d024d skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0xc59a48cc key_task_permission +EXPORT_SYMBOL vmlinux 0xc59ea0cc blkdev_get +EXPORT_SYMBOL vmlinux 0xc5ac12f7 tc_classify +EXPORT_SYMBOL vmlinux 0xc5ae126b blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xc5af8cca xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0xc5c7d169 sg_miter_stop +EXPORT_SYMBOL vmlinux 0xc5ca38aa ip_setsockopt +EXPORT_SYMBOL vmlinux 0xc6050ecf current_fs_time +EXPORT_SYMBOL vmlinux 0xc633495b schedule_work +EXPORT_SYMBOL vmlinux 0xc636442a nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0xc63adf45 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0xc6b39f10 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0xc6c7eb35 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0xc6e8bb14 set_anon_super +EXPORT_SYMBOL vmlinux 0xc6eb6146 tcp_close +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc722227e posix_acl_clone +EXPORT_SYMBOL vmlinux 0xc75ab80b compute_creds +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7c74cfd inode_double_unlock +EXPORT_SYMBOL vmlinux 0xc7d34601 bdi_destroy +EXPORT_SYMBOL vmlinux 0xc7e1f15d scsi_block_requests +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc80de694 down_write_trylock +EXPORT_SYMBOL vmlinux 0xc814b4cd inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xc8638f0f release_sock +EXPORT_SYMBOL vmlinux 0xc878ce9c elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0xc87ee5b4 invalidate_bdev +EXPORT_SYMBOL vmlinux 0xc8902f21 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8d312c0 kmalloc_caches +EXPORT_SYMBOL vmlinux 0xc8d514f4 vfs_create +EXPORT_SYMBOL vmlinux 0xc8e96dea qword_addhex +EXPORT_SYMBOL vmlinux 0xc917e655 debug_smp_processor_id +EXPORT_SYMBOL vmlinux 0xc9254c53 unregister_netdev +EXPORT_SYMBOL vmlinux 0xc94586d2 put_page +EXPORT_SYMBOL vmlinux 0xc975867b request_firmware +EXPORT_SYMBOL vmlinux 0xc98d7c90 scsi_print_command +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9f9d8e2 unlock_page +EXPORT_SYMBOL vmlinux 0xca4716c2 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca7d685b lock_sock_nested +EXPORT_SYMBOL vmlinux 0xca9d81d2 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0xcaaf6d1b inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xcb04a298 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xcb07d2bd proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7cb7ab inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xcbd8ffc6 dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc54ad6c vmap +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc90e443 i2c_use_client +EXPORT_SYMBOL vmlinux 0xcc97431d single_release +EXPORT_SYMBOL vmlinux 0xcccca482 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0xccf6addb tty_check_change +EXPORT_SYMBOL vmlinux 0xcd165e46 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xcd23d0a4 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xcd293590 xdr_buf_from_iov +EXPORT_SYMBOL vmlinux 0xcd400f62 eth_header_parse +EXPORT_SYMBOL vmlinux 0xcd63c845 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0xcd67bea2 scsi_add_device +EXPORT_SYMBOL vmlinux 0xcd7becfe inet6_bind +EXPORT_SYMBOL vmlinux 0xcdb31b26 inet_csk_accept +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce5645e3 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xceba7b8d ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xcee79fa6 sync_inode +EXPORT_SYMBOL vmlinux 0xcef2f928 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf424ae9 tcp_disconnect +EXPORT_SYMBOL vmlinux 0xcf8a15cc pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xcf918b3e poll_freewait +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfd4bc8e dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0xcff53400 kref_put +EXPORT_SYMBOL vmlinux 0xcff7c179 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xcffc1a01 inet_frag_kill +EXPORT_SYMBOL vmlinux 0xd00d9d30 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd028a47e bio_copy_user +EXPORT_SYMBOL vmlinux 0xd02bebac phy_device_create +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd02f4be5 blk_insert_request +EXPORT_SYMBOL vmlinux 0xd0484d20 keyring_clear +EXPORT_SYMBOL vmlinux 0xd0529d67 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0xd0895fff mpage_writepage +EXPORT_SYMBOL vmlinux 0xd0938bbd module_refcount +EXPORT_SYMBOL vmlinux 0xd0ac2f0c sk_alloc +EXPORT_SYMBOL vmlinux 0xd0ae14cc inet_frags_init +EXPORT_SYMBOL vmlinux 0xd0bbc045 rt6_lookup +EXPORT_SYMBOL vmlinux 0xd0c9e2e0 journal_lock_updates +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0fa76b8 page_symlink +EXPORT_SYMBOL vmlinux 0xd18b2f2a call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0xd1b22bef vfs_mkdir +EXPORT_SYMBOL vmlinux 0xd1d54fe9 svc_recv +EXPORT_SYMBOL vmlinux 0xd1da4e58 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xd1da8458 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0xd1e3fd2f inet_bind +EXPORT_SYMBOL vmlinux 0xd2046296 inet_add_protocol +EXPORT_SYMBOL vmlinux 0xd2404ff5 posix_test_lock +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd2665d52 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd314cd2c sock_create_kern +EXPORT_SYMBOL vmlinux 0xd3170302 sync_blockdev +EXPORT_SYMBOL vmlinux 0xd32e52c7 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0xd333f87d nonseekable_open +EXPORT_SYMBOL vmlinux 0xd3427f73 mempool_create_node +EXPORT_SYMBOL vmlinux 0xd3546045 vfs_readlink +EXPORT_SYMBOL vmlinux 0xd386f45b fasync_helper +EXPORT_SYMBOL vmlinux 0xd38d6cb1 user_path_at +EXPORT_SYMBOL vmlinux 0xd3c14d0c elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xd3d4f880 xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0xd3dbfbc4 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd494c33a blk_complete_request +EXPORT_SYMBOL vmlinux 0xd49e80db i2c_attach_client +EXPORT_SYMBOL vmlinux 0xd4b2ca85 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0xd4b98180 cpu_feroceon_dcache_clean_area +EXPORT_SYMBOL vmlinux 0xd4c1dab2 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0xd506be74 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0xd52006d7 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53d57c3 pci_iounmap +EXPORT_SYMBOL vmlinux 0xd5597425 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd56c3f26 scsi_execute +EXPORT_SYMBOL vmlinux 0xd5a99d27 __lookup_hash +EXPORT_SYMBOL vmlinux 0xd5ab13a9 kthread_bind +EXPORT_SYMBOL vmlinux 0xd5ade444 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0xd5d58082 nobh_write_begin +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd60f873e xrlim_allow +EXPORT_SYMBOL vmlinux 0xd611ee59 cache_register +EXPORT_SYMBOL vmlinux 0xd625e7ed set_device_ro +EXPORT_SYMBOL vmlinux 0xd627480b strncat +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd643a58c vfs_read +EXPORT_SYMBOL vmlinux 0xd65a2e98 dma_async_client_register +EXPORT_SYMBOL vmlinux 0xd66c6228 down_read_trylock +EXPORT_SYMBOL vmlinux 0xd68134bc skb_store_bits +EXPORT_SYMBOL vmlinux 0xd6920a32 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0xd6942bb4 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0xd6c2f641 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xd6d52c0f tcf_hash_create +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd712fbfa uart_register_driver +EXPORT_SYMBOL vmlinux 0xd7309659 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xd73bd7c0 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0xd74c9cc3 pci_get_device +EXPORT_SYMBOL vmlinux 0xd74cb4c4 ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0xd78326cd bio_kmalloc +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7b69fae idr_find +EXPORT_SYMBOL vmlinux 0xd7c39876 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xd7d4e3b7 dev_close +EXPORT_SYMBOL vmlinux 0xd7e4042d journal_clear_err +EXPORT_SYMBOL vmlinux 0xd8076fcd nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xd809f90c pcim_iomap +EXPORT_SYMBOL vmlinux 0xd80b8570 kernel_sendpage +EXPORT_SYMBOL vmlinux 0xd814afeb file_remove_suid +EXPORT_SYMBOL vmlinux 0xd8162b3f dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0xd8282ff0 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0xd82afa92 sock_no_accept +EXPORT_SYMBOL vmlinux 0xd855d9c5 textsearch_destroy +EXPORT_SYMBOL vmlinux 0xd862a9af nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8af6e28 pci_get_slot +EXPORT_SYMBOL vmlinux 0xd8c0d916 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0xd8df1425 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8f3ac51 devm_ioport_map +EXPORT_SYMBOL vmlinux 0xd90afb50 cont_write_begin +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9b0c855 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0xd9ce8f0c strnlen +EXPORT_SYMBOL vmlinux 0xd9d18a84 lock_may_write +EXPORT_SYMBOL vmlinux 0xd9d2d174 inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xd9e26a21 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xd9eb39a2 generic_listxattr +EXPORT_SYMBOL vmlinux 0xd9f77243 phy_register_fixup +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda1e7ec1 deny_write_access +EXPORT_SYMBOL vmlinux 0xda1fc224 cpu_cache +EXPORT_SYMBOL vmlinux 0xda412b6a pci_restore_state +EXPORT_SYMBOL vmlinux 0xda4471db read_cache_page_async +EXPORT_SYMBOL vmlinux 0xda4f9a69 register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xda4fd883 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xda5ea696 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0xda7fcc59 __seq_open_private +EXPORT_SYMBOL vmlinux 0xda8b5096 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xdaa17b22 generic_osync_inode +EXPORT_SYMBOL vmlinux 0xdb48982b ether_setup +EXPORT_SYMBOL vmlinux 0xdb66af68 iget_failed +EXPORT_SYMBOL vmlinux 0xdb6fa5a0 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0xdb704082 elevator_init +EXPORT_SYMBOL vmlinux 0xdb7c25eb ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb8f7cc4 tty_vhangup +EXPORT_SYMBOL vmlinux 0xdb911fbb __dev_get_by_index +EXPORT_SYMBOL vmlinux 0xdbac9483 ip6_route_output +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbe38c1b __page_symlink +EXPORT_SYMBOL vmlinux 0xdc053205 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0xdc0e6705 inet_select_addr +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc19d394 svc_reserve +EXPORT_SYMBOL vmlinux 0xdc2596b0 write_cache_pages +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc48b366 udp_proc_register +EXPORT_SYMBOL vmlinux 0xdc563ae3 wireless_spy_update +EXPORT_SYMBOL vmlinux 0xdc745cbe textsearch_unregister +EXPORT_SYMBOL vmlinux 0xdc7e33c9 pci_unmap_rom +EXPORT_SYMBOL vmlinux 0xdcaa1904 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdce18368 xfrm_input +EXPORT_SYMBOL vmlinux 0xdcffb182 simple_fill_super +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd127cfe neigh_event_ns +EXPORT_SYMBOL vmlinux 0xdd27fa87 memchr +EXPORT_SYMBOL vmlinux 0xdd415640 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0xdd567233 netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0xdd56e2d2 skb_truesize_bug +EXPORT_SYMBOL vmlinux 0xdd5c4118 i2c_master_send +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd76f76d input_register_handle +EXPORT_SYMBOL vmlinux 0xdd96c428 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0xdda3ebda posix_acl_permission +EXPORT_SYMBOL vmlinux 0xddbf6bb7 path_get +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde477438 dev_mc_add +EXPORT_SYMBOL vmlinux 0xde496be8 unregister_nls +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde9b6912 kobject_init +EXPORT_SYMBOL vmlinux 0xdeb6f23b __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0xdebace3e pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xdee8d336 i2c_transfer +EXPORT_SYMBOL vmlinux 0xdf564c0f tty_port_init +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfac53bb register_sysctl_paths +EXPORT_SYMBOL vmlinux 0xdfcb1474 pci_get_subsys +EXPORT_SYMBOL vmlinux 0xe049e57c blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xe069806f inet_sock_destruct +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0878bfe __krealloc +EXPORT_SYMBOL vmlinux 0xe0a28af3 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0ba5147 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xe0e2dc91 xdr_enter_page +EXPORT_SYMBOL vmlinux 0xe0f8f137 read_bytes_from_xdr_buf +EXPORT_SYMBOL vmlinux 0xe10a446d scsi_host_get +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe122add7 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0xe13c142c inet_shutdown +EXPORT_SYMBOL vmlinux 0xe1445d98 rtnl_unicast +EXPORT_SYMBOL vmlinux 0xe174b8cd pci_save_state +EXPORT_SYMBOL vmlinux 0xe19892d8 block_write_full_page +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1acd517 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xe1af16d0 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0xe1bb9a21 pci_pme_active +EXPORT_SYMBOL vmlinux 0xe1c8f9e5 file_update_time +EXPORT_SYMBOL vmlinux 0xe1ca1d7d sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0xe1cb2a74 nf_log_packet +EXPORT_SYMBOL vmlinux 0xe1d5781f inet_register_protosw +EXPORT_SYMBOL vmlinux 0xe1f9cca8 netlink_ack +EXPORT_SYMBOL vmlinux 0xe204014b __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xe216d41a sock_no_sendpage +EXPORT_SYMBOL vmlinux 0xe230968a vfs_readdir +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe2517cf9 seq_release +EXPORT_SYMBOL vmlinux 0xe25ba14c i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xe2645536 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0xe293ef9d svc_set_num_threads +EXPORT_SYMBOL vmlinux 0xe2abf2e9 dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0xe2b31f75 genl_register_ops +EXPORT_SYMBOL vmlinux 0xe2bcdbe3 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0xe2d390a4 input_inject_event +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2d79221 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe2fe020b netdev_features_change +EXPORT_SYMBOL vmlinux 0xe31f6503 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0xe32773bc dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe38010f3 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xe38912df blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0xe39ec534 blk_sync_queue +EXPORT_SYMBOL vmlinux 0xe47a49de skb_trim +EXPORT_SYMBOL vmlinux 0xe4a97c71 __down_write_trylock +EXPORT_SYMBOL vmlinux 0xe4bd88db free_buffer_head +EXPORT_SYMBOL vmlinux 0xe4c80097 cacheid +EXPORT_SYMBOL vmlinux 0xe4ce5748 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xe5119696 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL vmlinux 0xe59fa2b7 mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0xe5a42245 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe6310fa8 bdi_init +EXPORT_SYMBOL vmlinux 0xe638eed7 skb_checksum +EXPORT_SYMBOL vmlinux 0xe63e7242 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0xe6478c2d page_put_link +EXPORT_SYMBOL vmlinux 0xe66b3b92 tcf_hash_search +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe6b965c3 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0xe6c3ebb0 __raw_writesw +EXPORT_SYMBOL vmlinux 0xe6c850cb empty_zero_page +EXPORT_SYMBOL vmlinux 0xe6e258fc scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6f8a516 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe707d823 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0xe7112df5 key_unlink +EXPORT_SYMBOL vmlinux 0xe72b99c0 inode_needs_sync +EXPORT_SYMBOL vmlinux 0xe75568a7 alloc_disk +EXPORT_SYMBOL vmlinux 0xe76832ba iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe816251e sk_run_filter +EXPORT_SYMBOL vmlinux 0xe81f3af6 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0xe8272fed handle_sysrq +EXPORT_SYMBOL vmlinux 0xe899d266 nf_setsockopt +EXPORT_SYMBOL vmlinux 0xe8ae1045 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8db2ce9 vm_insert_pfn +EXPORT_SYMBOL vmlinux 0xe8e2159c pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe94298a0 bdget_disk +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe95b9e75 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0xe9637bcd elv_rb_former_request +EXPORT_SYMBOL vmlinux 0xe97f4ce5 qword_get +EXPORT_SYMBOL vmlinux 0xe9e69fc0 input_get_keycode +EXPORT_SYMBOL vmlinux 0xea04083d pneigh_enqueue +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea779e73 journal_abort +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea80ee40 sk_stop_timer +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xeab37369 mdiobus_scan +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb3d7830 sg_miter_next +EXPORT_SYMBOL vmlinux 0xeb5ca4bf submit_bh +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeba968a9 __getblk +EXPORT_SYMBOL vmlinux 0xebb4dfee inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebe973ee key_revoke +EXPORT_SYMBOL vmlinux 0xebfd02d3 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0xebfdcbdf system_serial_high +EXPORT_SYMBOL vmlinux 0xec336dcf ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0xec3f14c2 ide_execute_command +EXPORT_SYMBOL vmlinux 0xec49904c d_rehash +EXPORT_SYMBOL vmlinux 0xec5364cb svc_set_client +EXPORT_SYMBOL vmlinux 0xec5ac21e seq_putc +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec8c936e pci_target_state +EXPORT_SYMBOL vmlinux 0xec9ac40e kmem_cache_create +EXPORT_SYMBOL vmlinux 0xecf1eeed qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xed12bfd8 nf_hook_slow +EXPORT_SYMBOL vmlinux 0xed2e08f1 journal_stop +EXPORT_SYMBOL vmlinux 0xed3ae60e mdio_bus_type +EXPORT_SYMBOL vmlinux 0xed575c42 file_permission +EXPORT_SYMBOL vmlinux 0xeda827d5 vfs_write +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedbdde8b pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0xedcf6be4 qword_add +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd9106d __ashrdi3 +EXPORT_SYMBOL vmlinux 0xedeb75aa phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0xedf00d73 pcibios_fixup_bus +EXPORT_SYMBOL vmlinux 0xee0c2fe2 nlmsvc_ops +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee6648b9 redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0xee6fdf0b cpu_online_map +EXPORT_SYMBOL vmlinux 0xee8e2b2d ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0xee9080c0 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xee910e15 pci_find_capability +EXPORT_SYMBOL vmlinux 0xeea81f3f block_write_begin +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeeb337d3 phy_attach +EXPORT_SYMBOL vmlinux 0xef1097f8 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xef1a1668 km_waitq +EXPORT_SYMBOL vmlinux 0xef60ab69 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xefa3df3f phy_start_aneg +EXPORT_SYMBOL vmlinux 0xefee2faf simple_write_end +EXPORT_SYMBOL vmlinux 0xefee95a4 __free_pages +EXPORT_SYMBOL vmlinux 0xeff5a184 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf014aa97 fifo_set_limit +EXPORT_SYMBOL vmlinux 0xf01d79b1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0xf01efb16 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0xf042c513 bdput +EXPORT_SYMBOL vmlinux 0xf05b4f72 tty_devnum +EXPORT_SYMBOL vmlinux 0xf05d4e6d netif_rx_ni +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0bb8153 freeze_bdev +EXPORT_SYMBOL vmlinux 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL vmlinux 0xf0e1577a sysctl_string +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf17094cd d_instantiate +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf180aeb4 scsi_ioctl +EXPORT_SYMBOL vmlinux 0xf1987281 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0xf19e615e register_chrdev +EXPORT_SYMBOL vmlinux 0xf1a007ce dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xf1b04459 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xf1dced4c ide_lock +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf227d448 bio_add_page +EXPORT_SYMBOL vmlinux 0xf2518a7e posix_unblock_lock +EXPORT_SYMBOL vmlinux 0xf259e7ef close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2be9261 lease_modify +EXPORT_SYMBOL vmlinux 0xf2c719fa nla_append +EXPORT_SYMBOL vmlinux 0xf2d66ed7 journal_init_inode +EXPORT_SYMBOL vmlinux 0xf2dc23bc seq_lseek +EXPORT_SYMBOL vmlinux 0xf2e37591 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf33bb059 get_user_pages +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf3625df4 check_disk_size_change +EXPORT_SYMBOL vmlinux 0xf373e393 eth_type_trans +EXPORT_SYMBOL vmlinux 0xf38588dc input_event +EXPORT_SYMBOL vmlinux 0xf393c3eb pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xf3944fb2 genphy_read_status +EXPORT_SYMBOL vmlinux 0xf397b9aa __tasklet_schedule +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3afb275 sock_i_uid +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf48aeac8 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0xf4c4f228 i2c_clients_command +EXPORT_SYMBOL vmlinux 0xf4e28ffa filp_close +EXPORT_SYMBOL vmlinux 0xf4e68d71 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf50c41ba find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xf51a0f64 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0xf51c639f interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf564412a __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0xf57f3c9b ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0xf58597ed mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xf589e60f dev_get_by_index +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5c13281 vfs_readv +EXPORT_SYMBOL vmlinux 0xf5d155f9 phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0xf5fa854c serial8250_register_port +EXPORT_SYMBOL vmlinux 0xf6630b0c cpu_feroceon_set_pte_ext +EXPORT_SYMBOL vmlinux 0xf687d604 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0xf6933c48 lockd_up +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6c5cf4d __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0xf6d20f83 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0xf6df633c register_netdev +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf71f7b2b sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0xf72ef29a blk_start_queue +EXPORT_SYMBOL vmlinux 0xf7347f2f tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0xf7384f52 downgrade_write +EXPORT_SYMBOL vmlinux 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf77fbb46 idr_remove_all +EXPORT_SYMBOL vmlinux 0xf7802486 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7df1e8f km_state_expired +EXPORT_SYMBOL vmlinux 0xf7f67d97 __inet6_hash +EXPORT_SYMBOL vmlinux 0xf803c098 __scsi_put_command +EXPORT_SYMBOL vmlinux 0xf808d80d fsync_bdev +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82b5425 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf835b8c7 vfs_writev +EXPORT_SYMBOL vmlinux 0xf8400de3 pci_find_bus +EXPORT_SYMBOL vmlinux 0xf862fe72 mii_nway_restart +EXPORT_SYMBOL vmlinux 0xf86becf2 inet_frags_fini +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf892d7c7 dev_remove_pack +EXPORT_SYMBOL vmlinux 0xf8c058b3 kobject_put +EXPORT_SYMBOL vmlinux 0xf8d21053 scsi_remove_host +EXPORT_SYMBOL vmlinux 0xf8fbb4f0 __bad_xchg +EXPORT_SYMBOL vmlinux 0xf9194057 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9ad07ef __secpath_destroy +EXPORT_SYMBOL vmlinux 0xf9b28bac interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xf9b2b736 kill_pgrp +EXPORT_SYMBOL vmlinux 0xfa19500c xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0xfa273de5 journal_set_features +EXPORT_SYMBOL vmlinux 0xfa2fd8e5 generic_fillattr +EXPORT_SYMBOL vmlinux 0xfa46f716 get_unmapped_area +EXPORT_SYMBOL vmlinux 0xfa651767 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xfa6ad8fb __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0xfa8746b1 f_setown +EXPORT_SYMBOL vmlinux 0xfa8db167 pci_find_device +EXPORT_SYMBOL vmlinux 0xfa95e0a1 input_set_keycode +EXPORT_SYMBOL vmlinux 0xfabe6146 bio_pair_release +EXPORT_SYMBOL vmlinux 0xfac68eba arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0xfac9ed52 dma_pool_free +EXPORT_SYMBOL vmlinux 0xfacc17f0 __break_lease +EXPORT_SYMBOL vmlinux 0xfadce8a7 vfs_mknod +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb200496 add_mtd_partitions +EXPORT_SYMBOL vmlinux 0xfb326a5d down +EXPORT_SYMBOL vmlinux 0xfb5c271a pci_map_rom +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb7d9c45 __udivsi3 +EXPORT_SYMBOL vmlinux 0xfb8bfb80 generic_permission +EXPORT_SYMBOL vmlinux 0xfbc74f64 __copy_from_user +EXPORT_SYMBOL vmlinux 0xfbdb8707 cdev_alloc +EXPORT_SYMBOL vmlinux 0xfbe4bcda filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc066953 skb_queue_head +EXPORT_SYMBOL vmlinux 0xfc07940f sockfd_lookup +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc3f8070 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0xfc533f85 schedule_work_on +EXPORT_SYMBOL vmlinux 0xfc641a8f genl_unregister_ops +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcad9bb3 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfd0452b4 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xfd06c279 dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0xfd213c1a tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xfd60189f may_umount_tree +EXPORT_SYMBOL vmlinux 0xfd8dba4c add_wait_queue +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfd9fff38 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0xfdcac22d mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe16775f idr_destroy +EXPORT_SYMBOL vmlinux 0xfe271510 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xfe3f436a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xfe422213 d_find_alias +EXPORT_SYMBOL vmlinux 0xfe4a0c9e tty_set_operations +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe5e8ccf i2c_master_recv +EXPORT_SYMBOL vmlinux 0xfe6c4b6e inet_put_port +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL vmlinux 0xfe9d58e4 lock_rename +EXPORT_SYMBOL vmlinux 0xfebed14a key_alloc +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff2bf863 journal_revoke +EXPORT_SYMBOL vmlinux 0xff2e3ad6 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0xff35fa24 auth_unix_add_addr +EXPORT_SYMBOL vmlinux 0xff5666eb call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0xff572970 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0xff5b3912 filemap_fault +EXPORT_SYMBOL vmlinux 0xff67b37f __lshrdi3 +EXPORT_SYMBOL vmlinux 0xff6a078f give_up_console +EXPORT_SYMBOL vmlinux 0xff71bf86 simple_transaction_release +EXPORT_SYMBOL vmlinux 0xffbd2f65 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffe232c9 key_link +EXPORT_SYMBOL_GPL crypto/aead 0x03af237a crypto_nivaead_type +EXPORT_SYMBOL_GPL crypto/aead 0x0b2a99bd aead_geniv_exit +EXPORT_SYMBOL_GPL crypto/aead 0x18e5745f aead_geniv_alloc +EXPORT_SYMBOL_GPL crypto/aead 0x808fcca3 aead_geniv_init +EXPORT_SYMBOL_GPL crypto/aead 0x847ebb2c aead_geniv_free +EXPORT_SYMBOL_GPL crypto/aead 0x8588af74 crypto_grab_aead +EXPORT_SYMBOL_GPL crypto/aead 0x951eab8e crypto_aead_type +EXPORT_SYMBOL_GPL crypto/aead 0xf133a6b2 crypto_alloc_aead +EXPORT_SYMBOL_GPL crypto/aead 0xfb6bb972 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0xc5532904 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0xd0872974 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x2098ef7e async_xor +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x432f8cc6 async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x1c2179de crypto_attr_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x348c96c1 crypto_init_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5680bbbb crypto_spawn_tfm +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x58157640 scatterwalk_map +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5f1cced5 scatterwalk_start +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x62b99669 crypto_unregister_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x69698ef2 crypto_drop_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7ab41de2 crypto_dequeue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8199dba6 crypto_register_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x83553786 scatterwalk_copychunks +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8690ba25 crypto_alloc_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x88e27aef crypto_register_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x96a725a9 crypto_register_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9b683b45 scatterwalk_done +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9ba52f4b crypto_unregister_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xbeefeabe crypto_lookup_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc1e92e65 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xed7735a7 crypto_enqueue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xf807fd65 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x0e2a680c blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x210a25d7 crypto_blkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x34bf41f6 skcipher_geniv_free +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x5731a722 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x594f9da0 skcipher_geniv_init +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x65053395 crypto_givcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x6f46ddf8 blkcipher_walk_phys +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x923bc0c8 crypto_grab_skcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x9fa9cf04 blkcipher_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xa5fd4502 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xb50f5fdb blkcipher_walk_virt +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xbb4eba8a skcipher_geniv_exit +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xee6b2669 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x45588b8b crypto_ahash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x4923f6c6 crypto_hash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x7ce6efc2 crypto_hash_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x9ffaed49 crypto_hash_walk_first +EXPORT_SYMBOL_GPL crypto/cryptomgr 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/rng 0x4dd25928 crypto_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x8d75f79a crypto_rng_type +EXPORT_SYMBOL_GPL crypto/twofish_common 0x7a3ee2f2 twofish_setkey +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0x84b10919 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x3edb9d99 dm_device_name +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x6c418381 dm_disk +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xc8fa44c0 dm_set_device_limits +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xcc830602 dm_noflush_suspending +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xd7fa9cfd dm_put +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x39e0ffcf md_allow_write +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x82e40fa3 md_new_event +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xabcd40b0 sync_page_io +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xbab70bfb md_do_sync +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x3985314a nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x516ed9b3 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xef7d05fd nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xf33186dd nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xffdef54f nand_scan +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x09f3c921 wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x0f6cfa70 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x47c3ed75 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x5a322359 wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x8668d134 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xbee57d69 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xe4e7ae78 wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x12dbda4d wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x146409ba wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x2da7292b wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x38376750 wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3aa0b677 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x4e81d260 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x5b4c070b wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x6bc9fbbe wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x81935862 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa0a3f21d wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa381671f wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xadd3ce05 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xbe41fc5a wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcf0536dd wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd3864453 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd44caecd wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xdf6e4f08 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfebcc6cf __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1deff82a uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2da3bc17 uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x33bca847 uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x37499193 uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x37e6d43a uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x38cfcf4d uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3cff5abe uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x44594d0d uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x51ef49eb uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5c98b8f4 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5fc40128 uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x615a414b uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x64aac065 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x78ab47c2 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7b712561 uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7ee76e88 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x832ed056 uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8668b45c uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x86e94e0f uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x890e71a4 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x89318262 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8a3e4e65 uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9323689d uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x939b7cd3 dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x95e7e6a5 uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa3510c15 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa6ac3c43 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb1fcb019 uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb4a23ee9 uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb8ee7401 uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd4796e04 uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xeb488498 uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xecdfc119 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf19f8f33 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf2b46ecf uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf8bec17d uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfe75b083 uwb_notifs_register +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0d202c62 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x26265308 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x2ed986f6 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x3d162033 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x4d06e7a2 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6a37c7b2 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6bf57e3f xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x8ad477a4 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x8d0bf1c0 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xd9207317 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0x01ca27cf xt_rateest_lookup +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xe62aee08 xt_rateest_put +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x006590b3 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x00b42abd ide_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x00ba551a xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x012df4b2 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x012ea18a drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x01855825 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01d523e2 rpc_call_sync +EXPORT_SYMBOL_GPL vmlinux 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL vmlinux 0x02d40036 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x0310be1a uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03482dbf pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x034c0ff4 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0x038fb572 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x03b0b12d usb_string +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x04115893 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x041be61c map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x0438ab7d usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x043e0927 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x0485f421 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x04d12778 pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x053079eb rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x059e7d5e unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x05b6f95b bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x06285583 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x063c09f7 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06acd8d6 inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x06fc90cb rpc_malloc +EXPORT_SYMBOL_GPL vmlinux 0x070028dc dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0x071752a2 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x07580597 kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x08453dc9 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x086ab268 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x089ca3d6 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x08f33b9c bus_register +EXPORT_SYMBOL_GPL vmlinux 0x09012e9b find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09458b34 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x096b1fcb fat_attach +EXPORT_SYMBOL_GPL vmlinux 0x09961ca6 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x09e2a3d5 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x0a39e180 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x0ab1e893 ide_undecoded_slave +EXPORT_SYMBOL_GPL vmlinux 0x0ab9dfd3 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x0b067a9c ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x0b58b3a9 ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x0b748664 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x0bb424cb led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x0bd31d4f __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0ca8eb13 device_del +EXPORT_SYMBOL_GPL vmlinux 0x0cc1b60a ide_read_altstatus +EXPORT_SYMBOL_GPL vmlinux 0x0cfe7e4c bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x0d45d397 ide_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x0d82247a ide_read_sff_dma_status +EXPORT_SYMBOL_GPL vmlinux 0x0ded2822 put_device +EXPORT_SYMBOL_GPL vmlinux 0x0e0873e3 get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x0e5ddf14 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x0eef0715 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x10049667 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x1023caa6 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x10820a6b inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x10915209 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x109481e2 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x11222bac bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x11436b97 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x119b43bf ide_port_scan +EXPORT_SYMBOL_GPL vmlinux 0x11e267df nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x11e391fd rpcauth_create +EXPORT_SYMBOL_GPL vmlinux 0x11ec1373 ide_setting_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x1243e617 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x124f0d76 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x1271d74e ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x12a4e366 rpc_call_start +EXPORT_SYMBOL_GPL vmlinux 0x12ce7fde ide_retry_pc +EXPORT_SYMBOL_GPL vmlinux 0x12fcab2d tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x13410dd1 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x135988f2 pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x13b1d4b9 xprt_disconnect_done +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13d3a447 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x13dd893f flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x14039dc3 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x1430d2e7 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x1488e1e2 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x14ab6e62 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0x14d11be9 ide_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x14d2cdb7 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL vmlinux 0x1542a3eb ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0x1547fe03 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x16271697 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x16531561 usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x1713e608 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x17296a84 device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL vmlinux 0x186052b6 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x187b2313 regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x18f489b5 regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x191cd8b6 usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x191fb096 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x198d7c0c udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19c54ea7 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL vmlinux 0x1a8b8db0 hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1a8d3071 usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x1a941728 usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x1a94b41b svc_print_addr +EXPORT_SYMBOL_GPL vmlinux 0x1acb26de usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x1af489cf ide_create_request_sense_cmd +EXPORT_SYMBOL_GPL vmlinux 0x1b643e57 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x1b934855 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1ba96245 ide_pktcmd_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x1bccf434 scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0x1bfdc6ba dma_wait_for_async_tx +EXPORT_SYMBOL_GPL vmlinux 0x1c4fd011 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1cedc2a4 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x1d2abe1c device_add +EXPORT_SYMBOL_GPL vmlinux 0x1d62fd41 ide_pad_transfer +EXPORT_SYMBOL_GPL vmlinux 0x1d9b7031 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e9ac8fd sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1f007434 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x1f82741f __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x1fc8ebbd usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fe4457e blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x201dd687 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x2027eac2 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20596565 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20e719ba i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x21222cc1 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x212f4df4 ide_register_region +EXPORT_SYMBOL_GPL vmlinux 0x215fefae ide_read_bcount_and_ireason +EXPORT_SYMBOL_GPL vmlinux 0x21d57d87 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x21e293c6 raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x22526d1d hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x2265956e usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x22e2c20b atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x23054a8c fat_detach +EXPORT_SYMBOL_GPL vmlinux 0x230693b7 register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x236a6f2c ide_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x238291bc rpc_peeraddr2str +EXPORT_SYMBOL_GPL vmlinux 0x23869dc7 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x24147522 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x2418c5b8 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x246efa23 fat_free_clusters +EXPORT_SYMBOL_GPL vmlinux 0x24cda041 ide_vlb_clk +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x255ab69f platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x25646ece platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x25cf303d svc_unreg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x26570745 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x26589737 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL vmlinux 0x2676f788 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26cfd53f alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x26ed073c rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0x27307efb led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x2763b18a blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x278ca5af __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x27fa65e0 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x281d44a0 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x28481b10 cfi_qry_mode_on +EXPORT_SYMBOL_GPL vmlinux 0x28a9a9d7 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x28b2cc80 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28c0fc6c platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28e2e5d1 __class_register +EXPORT_SYMBOL_GPL vmlinux 0x28e6ffa0 rpc_alloc_iostats +EXPORT_SYMBOL_GPL vmlinux 0x294b1772 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x29c9ac59 get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0x29f05020 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x2a2d93b7 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x2a332dd1 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x2a4abe7b ide_no_data_taskfile +EXPORT_SYMBOL_GPL vmlinux 0x2a72adc0 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL vmlinux 0x2acd0708 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x2adc65dd __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x2b18fa96 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0x2b2d1346 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bef73e5 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x2c0a82fa blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x2c14c6c0 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c1e9f66 devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x2cb4db3e register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x2cf0b18b usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x2daefd5f class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2dc9ff4d deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x2dd25939 fat_add_entries +EXPORT_SYMBOL_GPL vmlinux 0x2e3d08b9 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x2e9076f1 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x2f00926d class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x2f0dbe29 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x2f33d39e sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x2f9395d6 svc_xprt_enqueue +EXPORT_SYMBOL_GPL vmlinux 0x3098f07c inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x30cffa84 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x30d8c7a5 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x310ae59f ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x31395847 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x3161ab54 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL vmlinux 0x31b479ff ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x320a3a1d get_device +EXPORT_SYMBOL_GPL vmlinux 0x321536c3 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x3225393d d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x3239dfa4 rpc_wake_up_status +EXPORT_SYMBOL_GPL vmlinux 0x32b12932 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x3387e0c7 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x33fa3050 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x34109f46 ide_get_best_pio_mode +EXPORT_SYMBOL_GPL vmlinux 0x34655f2f i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x3563219b rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL vmlinux 0x35cf63ff rpc_init_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35ec7fcb klist_next +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x36283fee inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x36b67d59 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x36bff31f xdr_skb_read_bits +EXPORT_SYMBOL_GPL vmlinux 0x36d1d77b ide_device_get +EXPORT_SYMBOL_GPL vmlinux 0x36e10368 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x3728b9e5 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x3760d98a debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x37912d10 rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x37a1ef5f copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x385e51b3 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x38633ac9 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x3874ce51 ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x389344cb class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x394c237c rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x39819646 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x398d3142 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x3992affa svc_close_xprt +EXPORT_SYMBOL_GPL vmlinux 0x39e49262 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3b0046e2 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x3b9a0268 rpc_peeraddr +EXPORT_SYMBOL_GPL vmlinux 0x3bc33f65 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3c590583 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3c8725b0 ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x3c8fbf68 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3d6f1a32 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x3d956c6f __class_create +EXPORT_SYMBOL_GPL vmlinux 0x3dce1b80 svc_create_xprt +EXPORT_SYMBOL_GPL vmlinux 0x3ddba5da __async_tx_find_channel +EXPORT_SYMBOL_GPL vmlinux 0x3e149bc6 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x3e2a060f platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x3e4abfca queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x3ea82144 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x3ef54874 ide_get_lba_addr +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f039e0a ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x3f1756dc rpc_call_async +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f726d44 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x3f7cb63e crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x3f9ed735 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x3fc330fe usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x3fd069de regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x401eac6c ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x4021afaa kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x405374c4 ide_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x408e1834 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40b34b5f ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0x40b6574f ide_read_error +EXPORT_SYMBOL_GPL vmlinux 0x40d23e6c scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x40dd16ee sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x40dd7557 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x410c6940 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x410e92ba driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0x41c0c5d7 ide_output_data +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x42035270 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x42173995 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x423a1276 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x4293f43a inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x429c76a7 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x42ae28de fat_time_unix2fat +EXPORT_SYMBOL_GPL vmlinux 0x430b67c0 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x43112984 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL vmlinux 0x432a949d rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x43850888 svc_addsock +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x440afdb4 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x440c4eab ide_devset_execute +EXPORT_SYMBOL_GPL vmlinux 0x442223f4 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x44444ee7 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x445e6c2f __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x4508f537 user_read +EXPORT_SYMBOL_GPL vmlinux 0x4524c514 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x45657b78 rpc_wake_up +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45cbe4d7 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x46514303 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x46947966 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x469d5a67 ide_do_test_unit_ready +EXPORT_SYMBOL_GPL vmlinux 0x46b2a30d proc_ide_read_capacity +EXPORT_SYMBOL_GPL vmlinux 0x46c72860 usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x46d910b5 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x4705c05b ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x472a4c2c rpc_lookup_cred +EXPORT_SYMBOL_GPL vmlinux 0x472bbed1 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x4751bbae ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x475854d2 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0x47628b3b unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x47b13916 cfi_qry_mode_off +EXPORT_SYMBOL_GPL vmlinux 0x47bc4af2 fat_alloc_new_dir +EXPORT_SYMBOL_GPL vmlinux 0x47c1e22f bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x48e605f7 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x4979d495 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x49a62e0b ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0x49b4eb88 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0x49edbbc0 tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x4a4a0629 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4b0b4bdc get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x4b302c63 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x4b6a2fbf register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x4b6e1160 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x4be59bd1 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x4c0c941b ide_host_register +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4caed5a2 ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x4cb7b930 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x4cbd1b01 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x4cd4dbb8 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0x4d250525 scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x4d38c4ff ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x4d88bd14 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x4de2b951 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x4dfc20a4 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x4e019881 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x4e2d952f dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x4e345317 ide_init_pc +EXPORT_SYMBOL_GPL vmlinux 0x4ed21059 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x4ef4e869 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL vmlinux 0x4efff9f8 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0x4f0a8f49 fat_search_long +EXPORT_SYMBOL_GPL vmlinux 0x4f391f8e tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x4f55b616 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x4f6ce4ba regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x4fbd2a73 led_classdev_register +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x50283e69 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x50a3fda8 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x512a6c17 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x51588eea ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x515a86c6 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x51b05262 ide_end_dequeued_request +EXPORT_SYMBOL_GPL vmlinux 0x51b5b2ab sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x51c15cc2 fat_remove_entries +EXPORT_SYMBOL_GPL vmlinux 0x51d325f2 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x51d4c63d ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x521085d2 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x5287a8a4 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x529b349c platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x52c7f615 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x5330fcb5 usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL vmlinux 0x5344f0be xprt_unregister_transport +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53c473b2 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x53c6122f led_classdev_resume +EXPORT_SYMBOL_GPL vmlinux 0x53d8df0e usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x55303624 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x5542b913 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x55aed768 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x55b1e7e1 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x55d959a0 ide_io_buffers +EXPORT_SYMBOL_GPL vmlinux 0x5633025a device_attach +EXPORT_SYMBOL_GPL vmlinux 0x5633dbf6 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x5655f394 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x56ab63a5 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x56d42418 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x574d8e86 rpc_wake_up_next +EXPORT_SYMBOL_GPL vmlinux 0x575bb15c kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x5832ee79 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x583eeeb0 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x58693aef async_tx_quiesce +EXPORT_SYMBOL_GPL vmlinux 0x5929412a bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x592ba296 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x595f6d6d disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59ca3224 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x59da6e5a driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x59edd3d7 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x5a3c7e11 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x5a6171ab queue_work +EXPORT_SYMBOL_GPL vmlinux 0x5a6c50de rpc_bind_new_program +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a82033f seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x5a8a036e pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x5a973618 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x5a9ed910 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0x5aa49c34 ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x5aac1199 hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x5acf242d xprt_release_xprt +EXPORT_SYMBOL_GPL vmlinux 0x5adb1e74 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x5b4bc53f __ide_error +EXPORT_SYMBOL_GPL vmlinux 0x5b7dae12 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5be04678 rpc_restart_call +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c30a047 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x5c58ffec klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5c6489b1 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x5c64b1c1 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x5c8331b4 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0x5c8b1c0c class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5cc44f7e klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x5d0ea4ab generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d239975 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x5d4a4572 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d7e2f70 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x5d99a474 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x5da8386b uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5ddeee7b input_class +EXPORT_SYMBOL_GPL vmlinux 0x5e027303 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x5e3acbf7 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x5e673868 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x5e718f79 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x5ec6a692 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x602571db regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x604a5f19 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x607897f9 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x607ad528 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x6084fb28 rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x608e3caa hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60e37d9c ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x6166c35d xprt_write_space +EXPORT_SYMBOL_GPL vmlinux 0x61d15c38 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x6206dc29 ide_host_add +EXPORT_SYMBOL_GPL vmlinux 0x622b3e2c srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x62a93185 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x62c491ac inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x62fdc767 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x639e012a ide_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x63ef8df4 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0x645e6dcc ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x647959b0 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x649fc2e2 regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x64f34ebf ide_pci_init_two +EXPORT_SYMBOL_GPL vmlinux 0x64fe77f9 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x654a9c8f sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x656b6163 sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x65b4d850 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65e967ff put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x65f3ea63 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x65ffbd46 fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x661eee7d sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x6631b62b usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x663bec94 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x664a98c0 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x665ca564 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL vmlinux 0x66644098 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x667699c2 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x6728663b ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x673c243b platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x67774bbc sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x67a222bd ide_host_free +EXPORT_SYMBOL_GPL vmlinux 0x67a5b87c usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0x67b1c545 scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x67e5d518 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6896d00b single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x68c15126 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x68fb3c5b rpc_put_task +EXPORT_SYMBOL_GPL vmlinux 0x6917b8c5 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x69543377 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x69b736e1 rpc_shutdown_client +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a5edf59 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0x6a6220fb ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x6a889e18 inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x6a9f8508 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6aa8bdf4 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x6af044fc ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x6afd4ad3 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x6b2be7ee usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL vmlinux 0x6bb10bd6 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x6bdfb373 transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x6bf5b421 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL vmlinux 0x6c72d379 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x6c852b24 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x6ca01c00 ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d38efcb ide_input_data +EXPORT_SYMBOL_GPL vmlinux 0x6d72f2d4 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x6d9fe23c regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x6ddbe2e2 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x6de4b364 xprt_complete_rqst +EXPORT_SYMBOL_GPL vmlinux 0x6e014098 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x6e018089 rpc_run_task +EXPORT_SYMBOL_GPL vmlinux 0x6e401a07 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6ea443f4 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x6ea7bcd2 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x6ec05aa2 ide_issue_pc +EXPORT_SYMBOL_GPL vmlinux 0x6f7ef3f9 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6f9cfa21 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x701313ac ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x707ace29 mtd_table +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70ee81a1 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL vmlinux 0x7114cfd4 ide_pci_setup_ports +EXPORT_SYMBOL_GPL vmlinux 0x71196147 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x7136df6d unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x71c7e429 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x71d4aeba cfi_qry_present +EXPORT_SYMBOL_GPL vmlinux 0x71ea6da1 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x71f9246a leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x724783ae tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72a30751 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x72ec1cb7 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x72f483fe do_rw_taskfile +EXPORT_SYMBOL_GPL vmlinux 0x732c330a class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0x7330f165 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x7394c1c4 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x73a15d54 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73ba9c76 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x73ffd894 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x740a4dcf xprt_reserve_xprt +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x7486289a init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74c423fc hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x750c59ae ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0x755204ba inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x759f0758 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x75d8c180 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x765363a9 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x766021fe i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x766bfc1c nlmclnt_done +EXPORT_SYMBOL_GPL vmlinux 0x76d885c7 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x7709382c uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x771a3e06 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x774a48e7 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x774a81d2 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x77d94b39 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x77e17b39 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x7846fe3c debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x78af7c8f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x78b31242 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x78b47409 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x7948d109 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x794e11f8 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x79d2f8a1 usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x79ff4a4d debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0x7a3b01b5 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x7a3fecd8 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x7a57a26b __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL vmlinux 0x7a73d9ec usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x7a7b3ecf single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x7abef945 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x7b004a2f fat_flush_inodes +EXPORT_SYMBOL_GPL vmlinux 0x7c40c9ca csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL vmlinux 0x7c5a8164 fat_fill_super +EXPORT_SYMBOL_GPL vmlinux 0x7c6784ef ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x7ca4ed80 async_trigger_callback +EXPORT_SYMBOL_GPL vmlinux 0x7cd5bef9 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x7d594a90 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x7d751c0f led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x7d7a24f4 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0x7d9f2e0a tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e29ea82 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0x7e2d29ec ide_pci_clk +EXPORT_SYMBOL_GPL vmlinux 0x7e338f05 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7f0d59f6 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x7f139f49 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x7f20b401 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7f31fa36 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7f873f17 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x7fb9d127 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x80159ff8 ide_set_pio +EXPORT_SYMBOL_GPL vmlinux 0x80409bd4 sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x8067f5c7 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x808bc898 led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x8095ef1b unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x80ecb657 transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x814030b3 debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x817e928b usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0x817fffa5 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x81cec458 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x81eda4bf device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x82246731 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x823754d1 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x82608fc2 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x827e44de user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x82d488bb ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82df308f usbhid_set_leds +EXPORT_SYMBOL_GPL vmlinux 0x8311a02e del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x831de57c svc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0x836d2cc9 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8397e8da ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x83d2222b svc_xprt_init +EXPORT_SYMBOL_GPL vmlinux 0x83e0d849 ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0x8412e3c5 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x8449318b schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x84499a40 ide_queue_pc_tail +EXPORT_SYMBOL_GPL vmlinux 0x84b6a389 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x8523d359 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x8561cbe9 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x8565f584 sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x8567526a screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7607a sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x85dd777f regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x86522708 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x8665298c pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x8690fdef crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x86c5ef0e fat_sync_inode +EXPORT_SYMBOL_GPL vmlinux 0x86d7975a find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x8748f9f0 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x8785922e driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x8797ca2b ide_setup_pci_noise +EXPORT_SYMBOL_GPL vmlinux 0x882ca548 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x8850a5a1 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x88749770 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x88ef5154 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x892a19e5 ide_host_remove +EXPORT_SYMBOL_GPL vmlinux 0x894b3dd6 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0x895d81bb usbhid_submit_report +EXPORT_SYMBOL_GPL vmlinux 0x897f6301 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x89a8cafe device_move +EXPORT_SYMBOL_GPL vmlinux 0x89eeccf1 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x8a640316 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x8a8ed81c ide_port_unregister_devices +EXPORT_SYMBOL_GPL vmlinux 0x8aa0392d ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ad7cc6f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x8b423625 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x8b6a6f1c net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8baf23f2 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x8bf33e57 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x8c18c2ec bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0x8c252d01 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x8c6e82a5 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x8c71bd34 rpcauth_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8cf5d949 svc_find_xprt +EXPORT_SYMBOL_GPL vmlinux 0x8d2831ad usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x8d46b6b8 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x8db629bd attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8dd81358 usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x8dfc410e ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0x8e08c2b4 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x8e29c8f0 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0x8e6465df ide_set_dma_mode +EXPORT_SYMBOL_GPL vmlinux 0x8e97a8a2 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x8eab8bc8 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x8ed4746c sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0x8f02e9d8 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8fcf8905 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x915b72df led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x916b3aab ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x91971167 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x9197cccf bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x923c6e0c sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x9250f461 usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x92947551 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x929d0195 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x92b7a6c3 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x93a77883 ide_device_put +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x94374845 inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x9493007a netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94b6fa27 hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94f31c2a sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x95fb436a put_driver +EXPORT_SYMBOL_GPL vmlinux 0x9600bee6 device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x96098e95 device_create +EXPORT_SYMBOL_GPL vmlinux 0x9626d57f usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0x962b4d56 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x965a48bc sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x974d5f7b devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x9784e6b4 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x97dd8773 rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x97eeb2f6 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x98196f5b blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x98379e41 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x983f6ebf dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x9904d57a tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x9928089f vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x993eaa71 driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x99af8502 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x99c01c2e rpc_delay +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a8867bf proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x9ac22401 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x9b0d256b ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x9b0efa21 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x9b1a7dfb led_classdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x9b8da338 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x9b8f97ae usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x9b949409 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x9b9fb999 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9be299a4 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0x9c28bff7 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x9c32d157 rpc_killall_tasks +EXPORT_SYMBOL_GPL vmlinux 0x9c9f60ec svc_xprt_put +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cbf36a4 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x9cdd23df get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x9d05ffbd crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x9d0ca2a0 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0x9d29874c platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x9d329e10 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x9d44acaa simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x9e5f90ad inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9eec7000 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9f512e1b ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0x9fcd8ad8 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9fdcd73a pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa0a3d6a7 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xa0d02f38 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0xa14ef9c4 ide_set_irq +EXPORT_SYMBOL_GPL vmlinux 0xa154913b pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0xa172d6ca devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0xa18b2a21 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0xa1eedb35 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xa26b016c tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xa26f34be sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xa29a1214 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2b99cd5 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0xa2d75dc2 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL vmlinux 0xa368fb52 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xa38e95cf xprt_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0xa396a116 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0xa3c1542e unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa4189d33 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xa46b4ac9 ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0xa48d5a1f get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xa490daf7 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0xa4f09479 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0xa53d39c5 rpc_create +EXPORT_SYMBOL_GPL vmlinux 0xa57afc74 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5e340bd ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0xa5ebea82 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xa5f25be4 ide_init_disk +EXPORT_SYMBOL_GPL vmlinux 0xa609a515 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL vmlinux 0xa6104dfa ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0xa638d75b ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0xa6923523 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xa6bce261 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xa6e97dfc led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xa739e823 driver_find +EXPORT_SYMBOL_GPL vmlinux 0xa7ee7aff hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0xa807e576 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0xa81b28af regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa874e664 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0xa87961a7 svc_reg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0xa8f7cb78 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0xa9510898 rpc_sleep_on +EXPORT_SYMBOL_GPL vmlinux 0xa95479e8 unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xa9762cc3 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa98c6ad1 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9de2bb8 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa7bbbed user_destroy +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaad02895 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0xaad8fc60 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0xaadcf3e8 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0xab07b8d4 ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0xab4266be dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab893127 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xab9fa7ff ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0xac283479 ide_scsi_expiry +EXPORT_SYMBOL_GPL vmlinux 0xac2d1042 ide_pci_init_one +EXPORT_SYMBOL_GPL vmlinux 0xac31430f vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0xac3a7ad5 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0xac779498 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0xac818637 rpc_force_rebind +EXPORT_SYMBOL_GPL vmlinux 0xacbd5ece sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xacdcf444 xprt_lookup_rqst +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xad3d8fe1 fat_build_inode +EXPORT_SYMBOL_GPL vmlinux 0xadbb2197 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae6e7e54 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0xaec40092 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0xaedffc0e nlmclnt_proc +EXPORT_SYMBOL_GPL vmlinux 0xaf05c722 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL vmlinux 0xaf8a6da7 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xafddc440 exportfs_encode_fh +EXPORT_SYMBOL_GPL vmlinux 0xaffb9e64 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xb0091bb9 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0xb01bb2b4 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0xb050196c ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0xb0a88177 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xb0d01b58 dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0xb0db738d device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0xb1909b2f usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xb1a5486a __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb2371039 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0xb379b2f3 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xb40712d2 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xb410d43f usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0xb449ed11 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0xb4544aed ide_check_atapi_device +EXPORT_SYMBOL_GPL vmlinux 0xb4625317 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0xb4734589 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xb493530c do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0xb49d6b1e rpc_proc_register +EXPORT_SYMBOL_GPL vmlinux 0xb4a4b9fb blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb4b695cc register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xb4e5475c inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xb509c475 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0xb56047be device_find_child +EXPORT_SYMBOL_GPL vmlinux 0xb5fbf1ed vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0xb65f7b88 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0xb693cffa usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6f4f691 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0xb705deec skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0xb7714021 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0xb797d7af sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xb7e7bb11 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0xb814f6ca usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0xb82e9004 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xb8759c2c srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xb89ad8b3 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0xb8c26c83 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xb8fee532 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0xb92357db pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0xb92cc5c2 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba1a4475 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0xba6be727 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0xba9060e6 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0xbaf09ec0 klist_del +EXPORT_SYMBOL_GPL vmlinux 0xbb082fa3 user_update +EXPORT_SYMBOL_GPL vmlinux 0xbb248c8a get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xbb9a2c75 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0xbbda22d9 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0xbbfbca24 ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0xbbfddb32 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0xbbff4f63 rpc_exit_task +EXPORT_SYMBOL_GPL vmlinux 0xbc27c1aa pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xbc3aa729 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0xbca35c26 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0xbd56c7b5 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0xbd70b795 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0xbd969687 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0xbdcc883a sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbdd5ce47 xprt_register_transport +EXPORT_SYMBOL_GPL vmlinux 0xbde87e7d console_drivers +EXPORT_SYMBOL_GPL vmlinux 0xbdfacd00 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbeb96f9d scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0xbeea7a2b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbef4b5ee rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xbf36a878 ide_read_status +EXPORT_SYMBOL_GPL vmlinux 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL vmlinux 0xbfe7385b usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xc0ccd1af input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL vmlinux 0xc1284833 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0xc16626f7 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0xc16ef0ed pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xc171d987 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc1e0dcb9 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0xc1f53a59 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc233a40e debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0xc2923994 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xc2a31d9d tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xc3082fcb svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc35bccfd __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xc3836741 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0xc3cd07cf usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0xc3d77301 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc45f0e36 rpcauth_init_credcache +EXPORT_SYMBOL_GPL vmlinux 0xc46a87a3 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4bdf2f5 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xc561260e pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0xc5761a71 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0xc5a656c8 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0xc5c2d7ad bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc76b9086 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xc7983432 rpc_clone_client +EXPORT_SYMBOL_GPL vmlinux 0xc7de63bd async_tx_submit +EXPORT_SYMBOL_GPL vmlinux 0xc80f9918 ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xc84dd0c9 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xc8787d0b ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xc8950ead rpcauth_init_cred +EXPORT_SYMBOL_GPL vmlinux 0xc8b74dd8 device_register +EXPORT_SYMBOL_GPL vmlinux 0xc8c92499 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xc90f3ddd mmput +EXPORT_SYMBOL_GPL vmlinux 0xc967a638 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0xc96a91d5 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xca10af4d exportfs_decode_fh +EXPORT_SYMBOL_GPL vmlinux 0xca18fcec ide_wait_not_busy +EXPORT_SYMBOL_GPL vmlinux 0xca1a4f95 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0xcaae05df destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xcac3e4e7 rpcauth_register +EXPORT_SYMBOL_GPL vmlinux 0xcae1f23a bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xcb0c2ebf __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcb67fec6 ide_do_start_stop +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc4ba4ac ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0xcc5f8768 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0xcc9e61f5 ide_set_media_lock +EXPORT_SYMBOL_GPL vmlinux 0xcca0c0c8 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0xcca723f8 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0xccb5e983 fat_scan +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcd0e0dba usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0xcd3f58aa deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0xcd4c73da sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xcd598a8a rpc_print_iostats +EXPORT_SYMBOL_GPL vmlinux 0xcd62a9d5 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0xcd77a072 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0xcda32a94 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0xcdb3cff0 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce003ece transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xce1af768 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0xce955915 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xce9b37d9 fat_dir_empty +EXPORT_SYMBOL_GPL vmlinux 0xcea11947 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xcedb0a2c hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0xcef34154 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xcf9da86a sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd00461a1 __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd07239a0 device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd08d66c0 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0ea12a9 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xd1624816 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0xd1711f5b regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xd17e8e1c usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xd1fd9eff sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0xd201275d svc_xprt_received +EXPORT_SYMBOL_GPL vmlinux 0xd24619fd class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xd2535d1e register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xd25d589c ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd2c202dd sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd2dbd2d6 rpc_call_null +EXPORT_SYMBOL_GPL vmlinux 0xd34e78b4 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xd35dbb97 rpc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0xd3828783 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL vmlinux 0xd3fbe66b dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0xd429c29e rpc_setbufsize +EXPORT_SYMBOL_GPL vmlinux 0xd44282e8 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0xd44f5cce usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0xd4533b21 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xd45d3988 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0xd4cffc6c ide_legacy_device_add +EXPORT_SYMBOL_GPL vmlinux 0xd50889c0 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xd527ce20 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0xd5502709 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd5608308 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xd561b77f user_match +EXPORT_SYMBOL_GPL vmlinux 0xd5e741b4 ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0xd6622c0a rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0xd6691726 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0xd693862a usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xd734135d inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0xd741cfcf blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xd7881458 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xd7b727dd platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0xd80d279a rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL vmlinux 0xd813142d sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd89a4411 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xd8e2d4c4 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0xd91e5894 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0xd9d2306e fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0xda2a71a8 inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0xdb5d1fd3 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xdb9cee52 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xdba12cec kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0xdc440c89 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0xdc4d3aa1 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0xdcb9dbea rpcb_getport_async +EXPORT_SYMBOL_GPL vmlinux 0xdcd3aed7 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0xdcddb372 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xdce96416 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xddc7773a skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0xde508e94 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xde5d8f41 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0xdf2c439a rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf547308 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0xdf59cae1 sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xdfbe08d8 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0xe051d646 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0xe0a3bde0 svc_xprt_names +EXPORT_SYMBOL_GPL vmlinux 0xe0c778c2 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe0dd5caa nlmclnt_init +EXPORT_SYMBOL_GPL vmlinux 0xe1866cfe register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xe1a2cdc6 sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe1b0baf3 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0xe1d42028 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xe21e9bf9 usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0xe24d6682 ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xe24f92be ide_execute_pkt_cmd +EXPORT_SYMBOL_GPL vmlinux 0xe2695970 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe285cfaf rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0xe360e68b __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xe363b32a led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe3a4ac4c fat_get_dotdot_entry +EXPORT_SYMBOL_GPL vmlinux 0xe3ba0118 ide_error +EXPORT_SYMBOL_GPL vmlinux 0xe3cb49e3 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0xe3ffc202 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0xe408d413 regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4d30333 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe530fedb ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xe55351f9 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xe558912a platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xe56a6ea3 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xe59562fc parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0xe5992d17 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0xe5be5f8f queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0xe654c1c2 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL vmlinux 0xe664b2cc sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0xe6da1be7 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0xe7a438ad inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0xe84381ec led_classdev_suspend +EXPORT_SYMBOL_GPL vmlinux 0xe87a5ded rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xe8fee2b4 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9443076 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea176b31 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xea3fffb0 register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea7dcbdc inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0xeaffca16 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xeb335dfe device_rename +EXPORT_SYMBOL_GPL vmlinux 0xeb5c6c84 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xebaf8a4d platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec49439d pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0xec8c6f55 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0xec96bff4 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0xecba1ef0 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0xeccb6b57 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xeced3a65 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0xed3b3985 put_rpccred +EXPORT_SYMBOL_GPL vmlinux 0xed460323 regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0xee74c298 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xee9f5020 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL vmlinux 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0xeee8231a blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xef233ba3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0xef3173ba sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0xef3e4171 usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0xef48e18f devres_add +EXPORT_SYMBOL_GPL vmlinux 0xef4e963e __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef767ec7 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0xef82fdba srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xefebcbf9 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0xf05577a6 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0xf09db9ab sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xf0a5a65e platform_bus +EXPORT_SYMBOL_GPL vmlinux 0xf0a86007 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0xf0d1c886 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0xf0f583ee simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xf105d00d ide_in_drive_list +EXPORT_SYMBOL_GPL vmlinux 0xf1134cec ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0xf1463412 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1b9b495 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xf1f7c8a5 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xf26e81da ide_unregister_region +EXPORT_SYMBOL_GPL vmlinux 0xf2875ac5 ide_init_sg_cmd +EXPORT_SYMBOL_GPL vmlinux 0xf299aa98 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0xf2a8d3c0 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xf2fc8305 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf449c36e default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0xf497cd61 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4e367af fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0xf519b17b ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0xf51b0bda pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0xf53cfe2b klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0xf54536d2 fat_setattr +EXPORT_SYMBOL_GPL vmlinux 0xf55d532e ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5abe1cb del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0xf5f8cb4b add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xf659ac7a unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0xf666ddc5 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0xf6747001 rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL vmlinux 0xf68b0f28 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xf7102eb7 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0xf7ee9b54 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0xf8120c36 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xf863e82a flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf9593fd4 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9bb6c73 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL vmlinux 0xfa02be5b inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0xfa1450cc driver_register +EXPORT_SYMBOL_GPL vmlinux 0xfa35a05f tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0xfa7cb430 async_tx_run_dependencies +EXPORT_SYMBOL_GPL vmlinux 0xfa85e95a scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0xfac0609d ide_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xfb41bab5 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0xfbd9354c usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0xfbf79aa8 get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc13a3a8 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0xfc18cb44 fat_getattr +EXPORT_SYMBOL_GPL vmlinux 0xfc202fff ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xfc67e709 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0xfc70f8af elv_register +EXPORT_SYMBOL_GPL vmlinux 0xfc94777b register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xfd22a5f2 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0xfd5b82a8 fat_fs_panic +EXPORT_SYMBOL_GPL vmlinux 0xfd68dc92 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0xfdb91f21 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xfe1212e5 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xfe96887e debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0xfec622a1 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xff0285f3 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xffaf7bbb __wake_up_sync --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/ixp4xx +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/ixp4xx @@ -0,0 +1,4076 @@ +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/cdrom/cdrom 0x1d74cfc8 cdrom_release +EXPORT_SYMBOL drivers/cdrom/cdrom 0x27a5ad03 unregister_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0x344adbd5 init_cdrom_command +EXPORT_SYMBOL drivers/cdrom/cdrom 0x4548abe4 cdrom_media_changed +EXPORT_SYMBOL drivers/cdrom/cdrom 0x557a1243 cdrom_get_media_event +EXPORT_SYMBOL drivers/cdrom/cdrom 0x77e51182 cdrom_number_of_slots +EXPORT_SYMBOL drivers/cdrom/cdrom 0xb1ae1cee cdrom_get_last_written +EXPORT_SYMBOL drivers/cdrom/cdrom 0xc07b1a02 register_cdrom +EXPORT_SYMBOL drivers/cdrom/cdrom 0xd7e73c81 cdrom_ioctl +EXPORT_SYMBOL drivers/cdrom/cdrom 0xe561f410 cdrom_mode_sense +EXPORT_SYMBOL drivers/cdrom/cdrom 0xecc11f5c cdrom_open +EXPORT_SYMBOL drivers/cdrom/cdrom 0xfe2749cf cdrom_mode_select +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x7796e5ff i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xa276dd9e i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/md/dm-mod 0x0b73d592 dm_kcopyd_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x1cb1eb66 dm_table_get_md +EXPORT_SYMBOL drivers/md/dm-mod 0x242bc5fd dm_register_target +EXPORT_SYMBOL drivers/md/dm-mod 0x289663f3 dm_get_mapinfo +EXPORT_SYMBOL drivers/md/dm-mod 0x2b4f7dca dm_get_device +EXPORT_SYMBOL drivers/md/dm-mod 0x378299ef dm_put_device +EXPORT_SYMBOL drivers/md/dm-mod 0x3d8f7862 dm_table_put +EXPORT_SYMBOL drivers/md/dm-mod 0x42b87fc0 dm_table_unplug_all +EXPORT_SYMBOL drivers/md/dm-mod 0x53958d61 dm_io_client_destroy +EXPORT_SYMBOL drivers/md/dm-mod 0x559ca112 dm_io +EXPORT_SYMBOL drivers/md/dm-mod 0x67454439 dm_table_event +EXPORT_SYMBOL drivers/md/dm-mod 0x69b50529 dm_table_get_size +EXPORT_SYMBOL drivers/md/dm-mod 0x76ca9817 dm_io_client_resize +EXPORT_SYMBOL drivers/md/dm-mod 0x7ff62401 dm_kcopyd_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x8346a1ac dm_io_client_create +EXPORT_SYMBOL drivers/md/dm-mod 0x88372b96 dm_table_get_mode +EXPORT_SYMBOL drivers/md/dm-mod 0xba89034f dm_table_get +EXPORT_SYMBOL drivers/md/dm-mod 0xbac74eb0 dm_kcopyd_copy +EXPORT_SYMBOL drivers/md/dm-mod 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL drivers/md/dm-mod 0xef510880 dm_unregister_target +EXPORT_SYMBOL drivers/md/md-mod 0x01b425fa md_wakeup_thread +EXPORT_SYMBOL drivers/md/md-mod 0x11e3ed7a bitmap_close_sync +EXPORT_SYMBOL drivers/md/md-mod 0x1e1105ab bitmap_cond_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0x41de1328 md_done_sync +EXPORT_SYMBOL drivers/md/md-mod 0x43e112e2 md_register_thread +EXPORT_SYMBOL drivers/md/md-mod 0x51b1de1c bitmap_unplug +EXPORT_SYMBOL drivers/md/md-mod 0x6ce0fcb1 md_check_recovery +EXPORT_SYMBOL drivers/md/md-mod 0x9522cf72 bitmap_endwrite +EXPORT_SYMBOL drivers/md/md-mod 0x9c31f1c7 bitmap_start_sync +EXPORT_SYMBOL drivers/md/md-mod 0xb55e15e7 md_wait_for_blocked_rdev +EXPORT_SYMBOL drivers/md/md-mod 0xb8632dca unregister_md_personality +EXPORT_SYMBOL drivers/md/md-mod 0xbdc931f5 md_error +EXPORT_SYMBOL drivers/md/md-mod 0xc6f40049 md_write_start +EXPORT_SYMBOL drivers/md/md-mod 0xcb92e725 md_write_end +EXPORT_SYMBOL drivers/md/md-mod 0xcba5a110 md_unregister_thread +EXPORT_SYMBOL drivers/md/md-mod 0xcbc8403b bitmap_end_sync +EXPORT_SYMBOL drivers/md/md-mod 0xe0f3271e bitmap_startwrite +EXPORT_SYMBOL drivers/md/md-mod 0xf224b5b7 register_md_personality +EXPORT_SYMBOL drivers/mtd/nand/nand 0x73b58cc8 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xcd6c8aa5 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x078d057c nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x35e6cfc5 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL fs/configfs/configfs 0x2fdeb8e9 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x35c21432 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x3ac0af51 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0x420e48ac configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x5b2e2207 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x5b755835 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x8227b346 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0x91ab091e configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x93644469 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0x9c5c0889 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xcb02d8f3 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xf031d1b5 config_item_set_name +EXPORT_SYMBOL fs/xfs/xfs 0xd18e0198 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc-t10dif 0xb6896671 crc_t10dif +EXPORT_SYMBOL lib/crc16 0x02a6ce5a crc16_table +EXPORT_SYMBOL lib/crc16 0x8ffdb3b8 crc16 +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL net/802/p8022 0x788732e5 register_8022_client +EXPORT_SYMBOL net/802/p8022 0xc9eea6c0 unregister_8022_client +EXPORT_SYMBOL net/802/psnap 0x05e7ef42 register_snap_client +EXPORT_SYMBOL net/802/psnap 0xba7f6be1 unregister_snap_client +EXPORT_SYMBOL net/bridge/bridge 0xfe183695 br_should_route_hook +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x41c05648 arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x42c98a24 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x62e410b1 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x4b31d2bd ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xa3d10ea7 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xafaf8af2 ipt_do_table +EXPORT_SYMBOL net/ipv4/tunnel4 0x53302627 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv4/tunnel4 0x85389c34 xfrm4_tunnel_register +EXPORT_SYMBOL net/llc/llc 0x38b92846 llc_remove_pack +EXPORT_SYMBOL net/llc/llc 0x4064e1a5 llc_add_pack +EXPORT_SYMBOL net/llc/llc 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL net/llc/llc 0x556643e3 llc_sap_list_lock +EXPORT_SYMBOL net/llc/llc 0x7484f57d llc_set_station_handler +EXPORT_SYMBOL net/llc/llc 0xadc11cda llc_mac_hdr_init +EXPORT_SYMBOL net/llc/llc 0xb919fbde llc_sap_open +EXPORT_SYMBOL net/llc/llc 0xc7d7bdbe llc_sap_find +EXPORT_SYMBOL net/llc/llc 0xdb68a2f5 llc_build_and_send_ui_pkt +EXPORT_SYMBOL net/llc/llc 0xf301ef03 llc_sap_close +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x4224dd79 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x67e784b0 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7176a134 ip_vs_get_debug_level +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7d57fb7f ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x8b2d7c3e unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x9a37bc45 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa5bd3ec6 ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xad9a61b6 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xcb6b8007 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xd1c95a1d register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xecfa3368 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/x_tables 0x1ddc686f xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x4c18377f xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0x5ab1764a xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0x5d6dbaf1 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x5f9f7a11 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0x83364972 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x844b88eb xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xadca0618 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xb07a29bf xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xde2401ae xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/phonet/phonet 0x0c110600 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x28a52c23 phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x5697009c pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xa258a390 phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0xaa145670 pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0xbe9be17c phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0xec253420 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0xf3e84059 phonet_proto_unregister +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x0038a14e pci_scan_slot +EXPORT_SYMBOL vmlinux 0x00457a38 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x006183f2 force_sig +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x009a8299 page_follow_link_light +EXPORT_SYMBOL vmlinux 0x00aadddc blk_start_queueing +EXPORT_SYMBOL vmlinux 0x00aebef8 d_path +EXPORT_SYMBOL vmlinux 0x00b8eac8 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x00bc4bd8 proc_symlink +EXPORT_SYMBOL vmlinux 0x00bf875b dev_change_flags +EXPORT_SYMBOL vmlinux 0x00e12bf9 __elv_add_request +EXPORT_SYMBOL vmlinux 0x00e64dc1 put_tty_driver +EXPORT_SYMBOL vmlinux 0x00e7096c nf_ip_checksum +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x011519f2 invalidate_partition +EXPORT_SYMBOL vmlinux 0x0115661c nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x0155123b journal_start_commit +EXPORT_SYMBOL vmlinux 0x0163bbc8 pci_dev_get +EXPORT_SYMBOL vmlinux 0x017e2cba gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x018cb84b sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01b08129 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x01c9bb34 input_close_device +EXPORT_SYMBOL vmlinux 0x02181931 inode_setattr +EXPORT_SYMBOL vmlinux 0x02196324 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x0252402a search_binary_handler +EXPORT_SYMBOL vmlinux 0x027fa4a9 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x0292190d skb_seq_read +EXPORT_SYMBOL vmlinux 0x029a0601 scsi_remove_target +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x034782a9 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x0350e2f4 up_read +EXPORT_SYMBOL vmlinux 0x03666930 ip_defrag +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03b8caa7 vfs_readv +EXPORT_SYMBOL vmlinux 0x03bb618b scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x03bb626d blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03e5e60a truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x03f4afcd qmgr_disable_irq +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x03fe0638 pcibios_resource_to_bus +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x043b8483 __kfifo_get +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x04afeff4 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x04e2fa60 sunrpc_cache_update +EXPORT_SYMBOL vmlinux 0x04f2bf2e tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x052b2967 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x05406c9a pci_disable_device +EXPORT_SYMBOL vmlinux 0x05504323 unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x056b0e8c block_read_full_page +EXPORT_SYMBOL vmlinux 0x05727bb2 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x059ab78b rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x05b472c1 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x05c771d1 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL vmlinux 0x05f4faac ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x0608a6d8 nf_log_packet +EXPORT_SYMBOL vmlinux 0x06090de7 __sg_free_table +EXPORT_SYMBOL vmlinux 0x060a3a69 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x060ad862 __getblk +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0618e633 dump_fpu +EXPORT_SYMBOL vmlinux 0x062aba95 mempool_free +EXPORT_SYMBOL vmlinux 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL vmlinux 0x06b15810 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x06cb34e5 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x06d2b49d vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x06d8bae1 idr_get_new +EXPORT_SYMBOL vmlinux 0x06d91a65 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x06de6e2b mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x0714e61c xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x07373475 page_put_link +EXPORT_SYMBOL vmlinux 0x073cfc13 ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x076b8a71 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x079e327e elevator_init +EXPORT_SYMBOL vmlinux 0x07a6367f get_user_pages +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d1bcac gpio_to_irq +EXPORT_SYMBOL vmlinux 0x081a6fad close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x08404d49 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x084652e8 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x08542b4f pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0x088226bd bio_copy_kern +EXPORT_SYMBOL vmlinux 0x0887be40 nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x08bbde32 path_permission +EXPORT_SYMBOL vmlinux 0x0903c239 vid_from_reg +EXPORT_SYMBOL vmlinux 0x091b2b61 blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x092b007a sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x096422eb generic_write_checks +EXPORT_SYMBOL vmlinux 0x09963315 neigh_update +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d45c21 down_timeout +EXPORT_SYMBOL vmlinux 0x09e3cd9f tty_name +EXPORT_SYMBOL vmlinux 0x09e71d9f pid_task +EXPORT_SYMBOL vmlinux 0x09f55d5d xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x0a0072f6 uart_add_one_port +EXPORT_SYMBOL vmlinux 0x0a1bebc5 kernel_execve +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a4b20a5 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x0a7ffd55 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x0a997969 inet_bind +EXPORT_SYMBOL vmlinux 0x0aa13d05 __raw_readsw +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0ad3c377 f_setown +EXPORT_SYMBOL vmlinux 0x0af93cdb ide_set_handler +EXPORT_SYMBOL vmlinux 0x0afcdcf2 nf_setsockopt +EXPORT_SYMBOL vmlinux 0x0afce361 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x0b00d118 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x0b05adf3 alloc_disk +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b2c14a8 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x0b430e8e kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x0b5f2d2c sg_next +EXPORT_SYMBOL vmlinux 0x0b67042c kill_pid +EXPORT_SYMBOL vmlinux 0x0b6dd09e dmabounce_sync_for_cpu +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b757d08 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x0bbf9c11 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x0c0b8e6d dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x0c346136 pci_get_subsys +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0cbf88d1 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x0ce681c6 init_special_inode +EXPORT_SYMBOL vmlinux 0x0cf3617d mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x0d06ae59 unlock_buffer +EXPORT_SYMBOL vmlinux 0x0d3def21 idr_pre_get +EXPORT_SYMBOL vmlinux 0x0d3f57a2 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x0d45dcfd blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d5b09b5 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x0d77324b __rta_fill +EXPORT_SYMBOL vmlinux 0x0d801361 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x0d8600b8 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d9e4fe5 bio_free +EXPORT_SYMBOL vmlinux 0x0d9fc5cd tty_kref_put +EXPORT_SYMBOL vmlinux 0x0da275c8 pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x0db61f1b skb_recycle_check +EXPORT_SYMBOL vmlinux 0x0dc8c344 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x0ddde76c bio_copy_user +EXPORT_SYMBOL vmlinux 0x0e0005c2 new_inode +EXPORT_SYMBOL vmlinux 0x0e267a59 pci_select_bars +EXPORT_SYMBOL vmlinux 0x0e407087 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x0e4c4c39 invalidate_bdev +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e71965e i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x0e747e79 is_container_init +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e7d67e0 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x0e8fd481 bdget_disk +EXPORT_SYMBOL vmlinux 0x0f1ef871 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x0f34ecf2 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x0f564b8d scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x0f585a4f vmtruncate +EXPORT_SYMBOL vmlinux 0x0f5b774d xfrm_input +EXPORT_SYMBOL vmlinux 0x0f620d76 do_SAK +EXPORT_SYMBOL vmlinux 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL vmlinux 0x0f92fa9e pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x0f95da9e d_rehash +EXPORT_SYMBOL vmlinux 0x0fa2a45e __memzero +EXPORT_SYMBOL vmlinux 0x0fc586ba down_trylock +EXPORT_SYMBOL vmlinux 0x0ff178f6 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x10009c75 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x10579454 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x108b6d97 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x10efb7fc input_get_keycode +EXPORT_SYMBOL vmlinux 0x1103f539 find_get_page +EXPORT_SYMBOL vmlinux 0x111bcb2c groups_free +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x113115ac i2c_master_send +EXPORT_SYMBOL vmlinux 0x113619e1 neigh_create +EXPORT_SYMBOL vmlinux 0x1142abd9 ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0x114e3a52 nf_afinfo +EXPORT_SYMBOL vmlinux 0x1151a53d skb_unlink +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x1199a52a skb_dequeue +EXPORT_SYMBOL vmlinux 0x119b50e7 elf_check_arch +EXPORT_SYMBOL vmlinux 0x11b4b9d2 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x11cd2027 get_sb_bdev +EXPORT_SYMBOL vmlinux 0x11e27d01 vfs_getattr +EXPORT_SYMBOL vmlinux 0x11ebe6a8 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x12153cdb scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x1275f72e dev_mc_delete +EXPORT_SYMBOL vmlinux 0x12999eb8 lock_may_read +EXPORT_SYMBOL vmlinux 0x12ae28e4 mpage_writepages +EXPORT_SYMBOL vmlinux 0x12af17eb xfrm_state_add +EXPORT_SYMBOL vmlinux 0x12b32f30 kernel_accept +EXPORT_SYMBOL vmlinux 0x12ba2a5c generic_listxattr +EXPORT_SYMBOL vmlinux 0x12c9af14 pci_get_class +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL vmlinux 0x12f067a3 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x130c82f8 block_write_begin +EXPORT_SYMBOL vmlinux 0x13266092 put_io_context +EXPORT_SYMBOL vmlinux 0x1343776a __grab_cache_page +EXPORT_SYMBOL vmlinux 0x1365b467 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0x136c627f mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0x13857889 redraw_screen +EXPORT_SYMBOL vmlinux 0x138ee83a pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0x138f620b __bforget +EXPORT_SYMBOL vmlinux 0x13955ace mpage_readpage +EXPORT_SYMBOL vmlinux 0x139a8350 neigh_table_init +EXPORT_SYMBOL vmlinux 0x139e0411 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x13ae0257 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x13ae0ec4 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x13b2f51b journal_clear_err +EXPORT_SYMBOL vmlinux 0x13d6d155 ip_route_input +EXPORT_SYMBOL vmlinux 0x13d9d989 kobject_set_name +EXPORT_SYMBOL vmlinux 0x1400864b tcp_prot +EXPORT_SYMBOL vmlinux 0x141fa82b __nla_reserve +EXPORT_SYMBOL vmlinux 0x144ed3a1 dev_base_lock +EXPORT_SYMBOL vmlinux 0x14608de8 find_vma +EXPORT_SYMBOL vmlinux 0x147b27de journal_flush +EXPORT_SYMBOL vmlinux 0x14a6fbbb netif_rx +EXPORT_SYMBOL vmlinux 0x14c6d2c3 bio_phys_segments +EXPORT_SYMBOL vmlinux 0x14de266d clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x1502d40d xscale_flush_user_cache_range +EXPORT_SYMBOL vmlinux 0x152888d8 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x152fc5a0 locks_init_lock +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1554f576 pci_find_device +EXPORT_SYMBOL vmlinux 0x158bc044 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x15fd9f7b set_device_ro +EXPORT_SYMBOL vmlinux 0x1631f4b1 __breadahead +EXPORT_SYMBOL vmlinux 0x1636a8bf console_start +EXPORT_SYMBOL vmlinux 0x16479e8f panic_notifier_list +EXPORT_SYMBOL vmlinux 0x166c30df blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x16879f5b skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x16d686fb pci_iounmap +EXPORT_SYMBOL vmlinux 0x170d50b1 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x174596f4 mii_link_ok +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17eb8dc4 uart_match_port +EXPORT_SYMBOL vmlinux 0x182c0deb sysctl_data +EXPORT_SYMBOL vmlinux 0x183cec25 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18bdf7c3 npe_send_message +EXPORT_SYMBOL vmlinux 0x18d8c2a4 neigh_lookup +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19c29216 vfs_create +EXPORT_SYMBOL vmlinux 0x19d62f51 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x1a4f909f elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x1a590cf7 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x1a65f4ad __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x1a7ed1f6 ip_getsockopt +EXPORT_SYMBOL vmlinux 0x1a865d92 journal_ack_err +EXPORT_SYMBOL vmlinux 0x1a957502 generic_setlease +EXPORT_SYMBOL vmlinux 0x1aab19dd submit_bh +EXPORT_SYMBOL vmlinux 0x1acac47a d_invalidate +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ad1f2e7 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x1ade9d51 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b29c05f skb_make_writable +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bc307cd cfi_fixup +EXPORT_SYMBOL vmlinux 0x1c324357 idr_replace +EXPORT_SYMBOL vmlinux 0x1c38b711 bio_split +EXPORT_SYMBOL vmlinux 0x1c723b86 seq_puts +EXPORT_SYMBOL vmlinux 0x1c80de9c ip_send_check +EXPORT_SYMBOL vmlinux 0x1c97cb07 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x1c98284d block_truncate_page +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ce3c6e6 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x1d02a6d6 mtd_do_chip_probe +EXPORT_SYMBOL vmlinux 0x1d0aaf41 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x1d20ba18 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x1d52c5d0 npe_running +EXPORT_SYMBOL vmlinux 0x1d5edb83 __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x1d6bbe1b netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x1d82bbfb _set_bit_be +EXPORT_SYMBOL vmlinux 0x1dcd49bb simple_readpage +EXPORT_SYMBOL vmlinux 0x1e04d18f tc_classify_compat +EXPORT_SYMBOL vmlinux 0x1e49daa8 sg_init_one +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e8ab47a lease_modify +EXPORT_SYMBOL vmlinux 0x1eaddb20 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x1eb297b6 locks_remove_posix +EXPORT_SYMBOL vmlinux 0x1ecb9943 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x1ed0e712 journal_load +EXPORT_SYMBOL vmlinux 0x1edc9598 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x1ef2e12b kobject_get +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f432fbe scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0x1f70d32d dma_cache_maint +EXPORT_SYMBOL vmlinux 0x1f7cc628 mempool_create +EXPORT_SYMBOL vmlinux 0x1f8c3776 nla_put +EXPORT_SYMBOL vmlinux 0x1fab1717 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x1fae7a0b wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x1fb1ebdb __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x1fc91fb2 request_irq +EXPORT_SYMBOL vmlinux 0x1fe6f07b dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0x1feec801 sock_i_uid +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2030ef43 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x204c3f2a d_alloc_name +EXPORT_SYMBOL vmlinux 0x20e33fef block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x211331fa __divsi3 +EXPORT_SYMBOL vmlinux 0x2144b051 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x2147cb74 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x215a1632 simple_write_begin +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x21601048 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x2167af64 sk_run_filter +EXPORT_SYMBOL vmlinux 0x21b1ff7a bio_init +EXPORT_SYMBOL vmlinux 0x21cfb643 igrab +EXPORT_SYMBOL vmlinux 0x22055407 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x2212aa82 skb_queue_head +EXPORT_SYMBOL vmlinux 0x22183b37 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x224c56ef __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x2274cfbe bio_unmap_user +EXPORT_SYMBOL vmlinux 0x22750192 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x227808a6 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x227b69a8 km_query +EXPORT_SYMBOL vmlinux 0x2281a69c simple_map_init +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x229cfd5b gen_new_estimator +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22d14cfa sock_rfree +EXPORT_SYMBOL vmlinux 0x22f72cdf inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x231286f6 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x231cf494 up_write +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x235d8b98 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x236d77f1 xdr_process_buf +EXPORT_SYMBOL vmlinux 0x23838107 __down_write +EXPORT_SYMBOL vmlinux 0x2390ca25 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x23a6e7e2 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x23b472f3 inet_frags_init +EXPORT_SYMBOL vmlinux 0x23d5b3ba sock_no_connect +EXPORT_SYMBOL vmlinux 0x23d6dc85 pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x23ef7c66 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x241789ae kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x24424773 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x2455c156 __clear_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x245efb8f arp_tbl +EXPORT_SYMBOL vmlinux 0x24770b1f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x24e58dca cache_register +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x2537bacb tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0x2538f2d8 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x2569dda9 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x2589be98 kfree_skb +EXPORT_SYMBOL vmlinux 0x25928c63 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x25b3b2c1 get_fs_type +EXPORT_SYMBOL vmlinux 0x25ba121c mempool_resize +EXPORT_SYMBOL vmlinux 0x25cc944c pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x25d134b0 block_prepare_write +EXPORT_SYMBOL vmlinux 0x25e3387c no_llseek +EXPORT_SYMBOL vmlinux 0x25fa6f17 wait_for_completion +EXPORT_SYMBOL vmlinux 0x260457eb svc_sock_names +EXPORT_SYMBOL vmlinux 0x260f8660 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x261c1766 __backtrace +EXPORT_SYMBOL vmlinux 0x26477c07 __vmalloc +EXPORT_SYMBOL vmlinux 0x26557c5b tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0x266110a6 kobject_del +EXPORT_SYMBOL vmlinux 0x26798c3a mnt_unpin +EXPORT_SYMBOL vmlinux 0x267a7cd9 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x267fc65b __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x26959fdc journal_stop +EXPORT_SYMBOL vmlinux 0x26a718ab sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x26e3b8f9 sock_create_kern +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26eb1b5d datagram_poll +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x275dbe83 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x275e0f73 sg_miter_next +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c1973f page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27ece5c1 qmgr_regs +EXPORT_SYMBOL vmlinux 0x28118cb6 __get_user_1 +EXPORT_SYMBOL vmlinux 0x282a52de tty_register_driver +EXPORT_SYMBOL vmlinux 0x2846deee request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x288d6fbd dma_pool_free +EXPORT_SYMBOL vmlinux 0x28966b24 stop_tty +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28c99394 blk_verify_command +EXPORT_SYMBOL vmlinux 0x28daae95 check_disk_change +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x29148969 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL vmlinux 0x293514f2 kernel_connect +EXPORT_SYMBOL vmlinux 0x293b59ed qmgr_request_queue +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x295567e7 get_write_access +EXPORT_SYMBOL vmlinux 0x297cea49 key_alloc +EXPORT_SYMBOL vmlinux 0x297d05ee dentry_open +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29f001c1 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x2a2295fc dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x2a438f7d register_nls +EXPORT_SYMBOL vmlinux 0x2a47c66b pcibios_fixup_bus +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2ab51ed4 vfs_readdir +EXPORT_SYMBOL vmlinux 0x2ae05b41 sock_no_getname +EXPORT_SYMBOL vmlinux 0x2ae65531 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b0cfcf2 elv_add_request +EXPORT_SYMBOL vmlinux 0x2b1a3ea7 nf_hook_slow +EXPORT_SYMBOL vmlinux 0x2b40baff __down_write_nested +EXPORT_SYMBOL vmlinux 0x2b570dc0 ida_pre_get +EXPORT_SYMBOL vmlinux 0x2b594225 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bbf4b1e kmem_cache_create +EXPORT_SYMBOL vmlinux 0x2be87de4 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x2c087075 pci_request_region +EXPORT_SYMBOL vmlinux 0x2cbefd49 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2d370968 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x2d6507b5 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x2d71b7d3 compute_creds +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2d8b1680 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x2d98af13 sk_alloc +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dee6ef1 misc_deregister +EXPORT_SYMBOL vmlinux 0x2e158903 tcp_close +EXPORT_SYMBOL vmlinux 0x2e1f0587 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e33d185 nf_register_hook +EXPORT_SYMBOL vmlinux 0x2e36119c remove_inode_hash +EXPORT_SYMBOL vmlinux 0x2e475639 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e659a99 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x2e6ef6d3 vfs_permission +EXPORT_SYMBOL vmlinux 0x2e723cdd tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x2e81c731 simple_link +EXPORT_SYMBOL vmlinux 0x2e9430d1 __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x2ede570d cdev_alloc +EXPORT_SYMBOL vmlinux 0x2ee4d851 tcp_make_synack +EXPORT_SYMBOL vmlinux 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL vmlinux 0x2ef8a933 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x2efe57cb unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x2f127de8 free_netdev +EXPORT_SYMBOL vmlinux 0x2f2a2a45 journal_restart +EXPORT_SYMBOL vmlinux 0x2f341916 kthread_bind +EXPORT_SYMBOL vmlinux 0x2f5152f0 input_grab_device +EXPORT_SYMBOL vmlinux 0x2f87366d sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x2fab64cf sk_stream_error +EXPORT_SYMBOL vmlinux 0x2fcada9f neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x302555eb dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x304c59fb journal_init_dev +EXPORT_SYMBOL vmlinux 0x3051654f vmap +EXPORT_SYMBOL vmlinux 0x30a5535e tcp_sendpage +EXPORT_SYMBOL vmlinux 0x30acf2ab scsi_register_interface +EXPORT_SYMBOL vmlinux 0x30bc2752 give_up_console +EXPORT_SYMBOL vmlinux 0x30be53a2 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x311ab677 svc_sock_update_bufs +EXPORT_SYMBOL vmlinux 0x311e2d46 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x3131a188 block_sync_page +EXPORT_SYMBOL vmlinux 0x313341a3 _set_bit_le +EXPORT_SYMBOL vmlinux 0x31353cba set_blocksize +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL vmlinux 0x31677623 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x31730d46 generic_removexattr +EXPORT_SYMBOL vmlinux 0x318c997b npe_release +EXPORT_SYMBOL vmlinux 0x31a2145f udp_disconnect +EXPORT_SYMBOL vmlinux 0x31aaf6d2 bio_alloc +EXPORT_SYMBOL vmlinux 0x31b28a10 write_one_page +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31d2de9d arp_find +EXPORT_SYMBOL vmlinux 0x31d435ae pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0x32121195 i2c_probe +EXPORT_SYMBOL vmlinux 0x321642fe sk_common_release +EXPORT_SYMBOL vmlinux 0x323222ba mutex_unlock +EXPORT_SYMBOL vmlinux 0x328a05f1 strncpy +EXPORT_SYMBOL vmlinux 0x3299d6cc do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x32a0ebb5 xdr_inline_pages +EXPORT_SYMBOL vmlinux 0x32a3bd7f pskb_expand_head +EXPORT_SYMBOL vmlinux 0x32c2845f tty_set_operations +EXPORT_SYMBOL vmlinux 0x32c5e165 pci_remove_bus +EXPORT_SYMBOL vmlinux 0x32ce623a sg_last +EXPORT_SYMBOL vmlinux 0x32d32525 init_net +EXPORT_SYMBOL vmlinux 0x32d72439 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x32dcb1e1 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x32eb0ff2 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x3305c4a3 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x333fc7bd scsi_ioctl +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x33691b70 tcp_connect +EXPORT_SYMBOL vmlinux 0x336d34d3 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x33995e91 devm_ioport_map +EXPORT_SYMBOL vmlinux 0x33f8f7d1 scsi_device_resume +EXPORT_SYMBOL vmlinux 0x3419bbae __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x342eeeca wireless_send_event +EXPORT_SYMBOL vmlinux 0x343da499 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x346e3cc7 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x34894abc sock_wake_async +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x34934629 read_dev_sector +EXPORT_SYMBOL vmlinux 0x349a80be genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34bd95dd inode_permission +EXPORT_SYMBOL vmlinux 0x34dad16b mpage_readpages +EXPORT_SYMBOL vmlinux 0x350d9e92 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x35326646 key_validate +EXPORT_SYMBOL vmlinux 0x353e3fa5 __get_user_4 +EXPORT_SYMBOL vmlinux 0x354fb794 ide_proc_unregister_driver +EXPORT_SYMBOL vmlinux 0x357a96ab neigh_destroy +EXPORT_SYMBOL vmlinux 0x359103fe bioset_create +EXPORT_SYMBOL vmlinux 0x360339f1 tcf_hash_check +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x361665a4 xdr_buf_from_iov +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x36452032 scsi_execute +EXPORT_SYMBOL vmlinux 0x364685c7 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x365747d5 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x366bdeaa init_timer +EXPORT_SYMBOL vmlinux 0x36bdae15 dma_free_coherent +EXPORT_SYMBOL vmlinux 0x36c2386f simple_empty +EXPORT_SYMBOL vmlinux 0x36e47222 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x36e57974 uart_get_divisor +EXPORT_SYMBOL vmlinux 0x36f68550 pcim_iounmap +EXPORT_SYMBOL vmlinux 0x37082a66 cdev_del +EXPORT_SYMBOL vmlinux 0x372a1b6f tty_unregister_device +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x3759e77c sk_free +EXPORT_SYMBOL vmlinux 0x3773fbbd mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37cbc551 netlink_broadcast +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x37f70884 kern_path +EXPORT_SYMBOL vmlinux 0x380436fb find_or_create_page +EXPORT_SYMBOL vmlinux 0x3825aed1 svcauth_unix_set_client +EXPORT_SYMBOL vmlinux 0x3825d435 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x38307252 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0x38450de0 simple_getattr +EXPORT_SYMBOL vmlinux 0x384ff6a9 __lookup_hash +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38d5864e sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x38e8378d pgprot_kernel +EXPORT_SYMBOL vmlinux 0x38e9facc register_netdev +EXPORT_SYMBOL vmlinux 0x38f7d042 simple_unlink +EXPORT_SYMBOL vmlinux 0x3934d8a4 unlock_page +EXPORT_SYMBOL vmlinux 0x396666f6 pci_assign_resource +EXPORT_SYMBOL vmlinux 0x39791ccd register_filesystem +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x39a70099 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x39af7126 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x39bf5efd do_splice_to +EXPORT_SYMBOL vmlinux 0x39eeaeaf __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x39f0095f __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x3a2e30c2 copy_io_context +EXPORT_SYMBOL vmlinux 0x3a39fe38 kset_unregister +EXPORT_SYMBOL vmlinux 0x3a3d02c8 generic_setxattr +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3ab054ae ip_dev_find +EXPORT_SYMBOL vmlinux 0x3ab2d174 down_killable +EXPORT_SYMBOL vmlinux 0x3abaa592 pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0x3adc15b9 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x3ae831b6 kref_init +EXPORT_SYMBOL vmlinux 0x3aee7849 inet6_del_protocol +EXPORT_SYMBOL vmlinux 0x3b2c3c33 icmp_send +EXPORT_SYMBOL vmlinux 0x3b411517 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x3b6930bc generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x3b707850 pci_iomap +EXPORT_SYMBOL vmlinux 0x3b76ef61 vfs_read +EXPORT_SYMBOL vmlinux 0x3b7edd13 xdr_write_pages +EXPORT_SYMBOL vmlinux 0x3bc43d3e ide_stall_queue +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3becbcfc __starget_for_each_device +EXPORT_SYMBOL vmlinux 0x3c187c44 dma_map_sg +EXPORT_SYMBOL vmlinux 0x3c287464 inet6_add_protocol +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c8e41dc pagevec_lookup +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3ca017e9 revalidate_disk +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cbd75a4 wireless_spy_update +EXPORT_SYMBOL vmlinux 0x3cbffcb2 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3d14c30d unregister_con_driver +EXPORT_SYMBOL vmlinux 0x3d1d12d6 clocksource_register +EXPORT_SYMBOL vmlinux 0x3d2e22ea scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x3d2fe4fb kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x3d3c540f elf_hwcap +EXPORT_SYMBOL vmlinux 0x3d5f3eab sget +EXPORT_SYMBOL vmlinux 0x3d684625 pci_choose_state +EXPORT_SYMBOL vmlinux 0x3d68bd4b flow_cache_genid +EXPORT_SYMBOL vmlinux 0x3d844c07 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x3d94dcb2 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x3da5a2ab _find_next_bit_be +EXPORT_SYMBOL vmlinux 0x3dc5e6e1 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x3df589fe skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e6caebd add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x3ec143fe generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ed9a446 pcie_get_readrq +EXPORT_SYMBOL vmlinux 0x3f0274eb test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x3f0c0409 module_refcount +EXPORT_SYMBOL vmlinux 0x3f36b8e2 vfs_llseek +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f52a705 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x3f63d318 devm_iounmap +EXPORT_SYMBOL vmlinux 0x3f6af720 d_move +EXPORT_SYMBOL vmlinux 0x3f7a7b4b pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x3f977c98 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x3fbdc140 npe_names +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x40123aeb idr_for_each +EXPORT_SYMBOL vmlinux 0x4016e84f __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x402162b3 pci_target_state +EXPORT_SYMBOL vmlinux 0x40357784 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407136b1 __put_user_8 +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x409a2f68 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0x40a6f522 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x40a747af xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x40f07981 __ashldi3 +EXPORT_SYMBOL vmlinux 0x4101a975 ide_fixstring +EXPORT_SYMBOL vmlinux 0x41166725 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x4119d80f blk_put_request +EXPORT_SYMBOL vmlinux 0x412ddc0c dcache_lock +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x41505d3b pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x4150f395 do_sync_write +EXPORT_SYMBOL vmlinux 0x4161c634 drop_super +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x41a611bb xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x41adc83d __dst_free +EXPORT_SYMBOL vmlinux 0x41b1c0fa get_super +EXPORT_SYMBOL vmlinux 0x420424c6 bmap +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x4233e1ca skb_checksum +EXPORT_SYMBOL vmlinux 0x425048cb journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x4250b629 del_mtd_partitions +EXPORT_SYMBOL vmlinux 0x4252c50c dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x426cc5dc _find_first_bit_be +EXPORT_SYMBOL vmlinux 0x42707b2c sock_no_bind +EXPORT_SYMBOL vmlinux 0x428ff752 input_register_device +EXPORT_SYMBOL vmlinux 0x4293b331 journal_dirty_data +EXPORT_SYMBOL vmlinux 0x4295475d i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x42a62b67 names_cachep +EXPORT_SYMBOL vmlinux 0x42bb4a09 xdr_decode_word +EXPORT_SYMBOL vmlinux 0x42bf0f79 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x430205aa __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x43529242 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0x437cd34e iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x43bb6f46 lock_sock_nested +EXPORT_SYMBOL vmlinux 0x43bd2450 generic_getxattr +EXPORT_SYMBOL vmlinux 0x43d36784 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x43d8750e journal_force_commit +EXPORT_SYMBOL vmlinux 0x4409322c ndisc_mc_map +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x44643b93 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x448611e9 mii_nway_restart +EXPORT_SYMBOL vmlinux 0x44ac5813 scsi_register_driver +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44bfa020 generic_writepages +EXPORT_SYMBOL vmlinux 0x44c214d1 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x44d24bf2 sock_kmalloc +EXPORT_SYMBOL vmlinux 0x44da5d0f __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x44db2d08 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x44e1e515 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44fadd69 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x4508e4f9 blk_rq_init +EXPORT_SYMBOL vmlinux 0x451769bf nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x45785602 qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0x45a55ec8 __iounmap +EXPORT_SYMBOL vmlinux 0x45bda0d5 system_serial_low +EXPORT_SYMBOL vmlinux 0x45ee1fc1 bio_map_user +EXPORT_SYMBOL vmlinux 0x45f4152f release_sock +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x466ab1dc __pagevec_release +EXPORT_SYMBOL vmlinux 0x46761cab uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x46c2a34c user_revoke +EXPORT_SYMBOL vmlinux 0x46cc1bf4 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x46ce83b7 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0x46d3b28c __div0 +EXPORT_SYMBOL vmlinux 0x470f9335 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x4719ba4e kfifo_free +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x47431da5 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x4792ff75 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x479f1c69 inode_init_once +EXPORT_SYMBOL vmlinux 0x47baf626 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47cf0d7b tty_hangup +EXPORT_SYMBOL vmlinux 0x47f5bf07 elv_next_request +EXPORT_SYMBOL vmlinux 0x47f757de elf_platform +EXPORT_SYMBOL vmlinux 0x47ff3ed5 dev_close +EXPORT_SYMBOL vmlinux 0x48034724 zlib_deflateReset +EXPORT_SYMBOL vmlinux 0x480bdffb blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x4814d5a5 unload_nls +EXPORT_SYMBOL vmlinux 0x4858eb04 pci_restore_state +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48894f83 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x48a5b067 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x48e59f2d sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x48ef0e87 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x48f9f12d complete_all +EXPORT_SYMBOL vmlinux 0x4923cd03 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x496fafd1 scsi_host_get +EXPORT_SYMBOL vmlinux 0x498c38ab blkdev_put +EXPORT_SYMBOL vmlinux 0x498ef45c unregister_nls +EXPORT_SYMBOL vmlinux 0x49bf4c1f blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x4a1f2bc1 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a3e98e5 follow_down +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4ac0844f sg_miter_stop +EXPORT_SYMBOL vmlinux 0x4ac19b7d udp_sendmsg +EXPORT_SYMBOL vmlinux 0x4acfd8ad down_interruptible +EXPORT_SYMBOL vmlinux 0x4ad9a6fe xscale_mc_copy_user_page +EXPORT_SYMBOL vmlinux 0x4aea4791 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b48c2a8 clear_inode +EXPORT_SYMBOL vmlinux 0x4b52b425 __f_setown +EXPORT_SYMBOL vmlinux 0x4b5df41a file_permission +EXPORT_SYMBOL vmlinux 0x4b5effa4 nobh_writepage +EXPORT_SYMBOL vmlinux 0x4b626e61 posix_acl_permission +EXPORT_SYMBOL vmlinux 0x4b7e10ab dev_disable_lro +EXPORT_SYMBOL vmlinux 0x4b8b62c6 __inet6_hash +EXPORT_SYMBOL vmlinux 0x4b8edde9 complete_and_exit +EXPORT_SYMBOL vmlinux 0x4b9f3684 kfifo_init +EXPORT_SYMBOL vmlinux 0x4ba097f5 ixp4xx_pci_write +EXPORT_SYMBOL vmlinux 0x4bdccb4b inode_get_bytes +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c2b1a76 dma_unmap_single +EXPORT_SYMBOL vmlinux 0x4c4ec8f2 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cde13ed ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x4d0d163d copy_page +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d4b039d pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x4d6214d7 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x4d666f3b unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x4dc305f0 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4dec6038 memscan +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e0009da idr_get_new_above +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4f0ea0c0 up +EXPORT_SYMBOL vmlinux 0x4f219629 dev_add_pack +EXPORT_SYMBOL vmlinux 0x4f5651c3 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x4f672384 skb_queue_purge +EXPORT_SYMBOL vmlinux 0x4f78359b simple_release_fs +EXPORT_SYMBOL vmlinux 0x4fa7d13f flush_dcache_page +EXPORT_SYMBOL vmlinux 0x4fb816d3 skb_trim +EXPORT_SYMBOL vmlinux 0x5006eedd add_mtd_partitions +EXPORT_SYMBOL vmlinux 0x502e8b70 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x50392360 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x5082799d uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x508f91fd simple_sync_file +EXPORT_SYMBOL vmlinux 0x5093fa82 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x50fed6f7 proc_ide_read_geometry +EXPORT_SYMBOL vmlinux 0x51493d94 finish_wait +EXPORT_SYMBOL vmlinux 0x5177fc69 page_symlink +EXPORT_SYMBOL vmlinux 0x51891750 blk_register_region +EXPORT_SYMBOL vmlinux 0x51908eb8 __raw_writesl +EXPORT_SYMBOL vmlinux 0x5197f0b0 get_unmapped_area +EXPORT_SYMBOL vmlinux 0x51c5929e blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x51cd47e2 groups_alloc +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x51f88b7c alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x520071ed ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x520af3f5 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x52354a0b mutex_trylock +EXPORT_SYMBOL vmlinux 0x52383f9e register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x525025c6 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a2cd0c sysctl_string +EXPORT_SYMBOL vmlinux 0x52a4546e skb_put +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52d20a28 auth_unix_lookup +EXPORT_SYMBOL vmlinux 0x52de24de i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x5320bb6d blk_start_queue +EXPORT_SYMBOL vmlinux 0x532b9daf generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x536c2e68 unregister_netdevice +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53f2630c find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x5419bcad pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x547fccfd dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x5491fc84 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x55105a91 svc_reserve +EXPORT_SYMBOL vmlinux 0x55345f3a scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x557fdf14 unlock_rename +EXPORT_SYMBOL vmlinux 0x5584c1a7 dma_pool_create +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55952cb6 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x55a46f22 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x55f71e53 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x55f9e05b fifo_set_limit +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5614c321 mii_check_link +EXPORT_SYMBOL vmlinux 0x56193688 svc_destroy +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x56742745 blk_complete_request +EXPORT_SYMBOL vmlinux 0x568ea235 i2c_use_client +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56e76c03 __secpath_destroy +EXPORT_SYMBOL vmlinux 0x571625d8 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x571f03c6 cpu_xscale_set_pte_ext +EXPORT_SYMBOL vmlinux 0x572af993 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x5751b21e i2c_master_recv +EXPORT_SYMBOL vmlinux 0x577c9ea5 lookup_bdev +EXPORT_SYMBOL vmlinux 0x57806f2f per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x579bc029 cdev_init +EXPORT_SYMBOL vmlinux 0x579eab31 pci_bus_type +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57b87e32 scsi_register +EXPORT_SYMBOL vmlinux 0x57d75567 uart_resume_port +EXPORT_SYMBOL vmlinux 0x583692b8 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x58a0b705 vfs_link +EXPORT_SYMBOL vmlinux 0x58aaa5cd xdr_enter_page +EXPORT_SYMBOL vmlinux 0x58cb9045 input_register_handle +EXPORT_SYMBOL vmlinux 0x58da7aca journal_wipe +EXPORT_SYMBOL vmlinux 0x58e0c277 key_put +EXPORT_SYMBOL vmlinux 0x5903b795 get_disk +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594e1317 __modsi3 +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x597853b9 dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0x598f7621 qmgr_enable_irq +EXPORT_SYMBOL vmlinux 0x599f2b0d __kfree_skb +EXPORT_SYMBOL vmlinux 0x59a272c4 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x59a62ca2 set_binfmt +EXPORT_SYMBOL vmlinux 0x59bd00da nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x59c711da npe_recv_message +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59ddece8 skb_find_text +EXPORT_SYMBOL vmlinux 0x59e5070d __do_div64 +EXPORT_SYMBOL vmlinux 0x5a0477da remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a7e47c2 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x5a8e8dea lease_get_mtime +EXPORT_SYMBOL vmlinux 0x5a9c7cb6 sock_release +EXPORT_SYMBOL vmlinux 0x5ab0c8f0 proc_create_data +EXPORT_SYMBOL vmlinux 0x5af55b42 d_alloc +EXPORT_SYMBOL vmlinux 0x5afa23c6 svc_create_pooled +EXPORT_SYMBOL vmlinux 0x5b078b70 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b3a39fd sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x5b509c6b sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x5b783504 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x5b91f398 ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0x5b9ab16d secpath_dup +EXPORT_SYMBOL vmlinux 0x5bc35124 __devm_release_region +EXPORT_SYMBOL vmlinux 0x5bd69dd9 neigh_compat_output +EXPORT_SYMBOL vmlinux 0x5c66340e unregister_filesystem +EXPORT_SYMBOL vmlinux 0x5c673bc8 tty_mutex +EXPORT_SYMBOL vmlinux 0x5c6d983d blk_recount_segments +EXPORT_SYMBOL vmlinux 0x5c9284a0 processor_id +EXPORT_SYMBOL vmlinux 0x5c9dab18 dev_get_flags +EXPORT_SYMBOL vmlinux 0x5cb1404f sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x5cc57165 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x5d0782d2 seq_escape +EXPORT_SYMBOL vmlinux 0x5d0a4698 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x5d0e311d vfs_symlink +EXPORT_SYMBOL vmlinux 0x5d180bb8 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0x5d6b7fed block_commit_write +EXPORT_SYMBOL vmlinux 0x5dbe5f9c add_disk +EXPORT_SYMBOL vmlinux 0x5e009949 sock_init_data +EXPORT_SYMBOL vmlinux 0x5e1c91ff seq_lseek +EXPORT_SYMBOL vmlinux 0x5e28ebef udp_proc_register +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5eb3332a file_update_time +EXPORT_SYMBOL vmlinux 0x5eb8b35b generic_file_mmap +EXPORT_SYMBOL vmlinux 0x5eb8eb5d dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x5ebb56fb down_read +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f1e2b6c blk_run_queue +EXPORT_SYMBOL vmlinux 0x5f265508 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x5f27013f udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x5f754e5a memset +EXPORT_SYMBOL vmlinux 0x5f7cd1ce scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x5fac3c20 pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x5fca6ca2 xdr_reserve_space +EXPORT_SYMBOL vmlinux 0x60032a91 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x601f6c30 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x602d47c0 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60a4efe2 ida_get_new +EXPORT_SYMBOL vmlinux 0x60f5c442 mpage_writepage +EXPORT_SYMBOL vmlinux 0x612ad00c tcf_hash_create +EXPORT_SYMBOL vmlinux 0x61593b72 __mod_timer +EXPORT_SYMBOL vmlinux 0x617507eb find_lock_page +EXPORT_SYMBOL vmlinux 0x617851b0 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61944fe7 pci_set_master +EXPORT_SYMBOL vmlinux 0x61b0c34f dcache_dir_close +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61bd6f15 dma_unmap_sg +EXPORT_SYMBOL vmlinux 0x61e6fbbb nf_register_hooks +EXPORT_SYMBOL vmlinux 0x61f04569 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x623c7741 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x626d1f52 load_nls_default +EXPORT_SYMBOL vmlinux 0x62706dab dst_discard +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62998344 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x62a42cdf sk_reset_timer +EXPORT_SYMBOL vmlinux 0x62c947a5 ___pskb_trim +EXPORT_SYMBOL vmlinux 0x62cc105f alloc_file +EXPORT_SYMBOL vmlinux 0x62e0d203 file_fsync +EXPORT_SYMBOL vmlinux 0x632b67d8 sock_recvmsg +EXPORT_SYMBOL vmlinux 0x63c7d9e1 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x63e6983e __find_get_block +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f9d28d task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640a7078 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x6428c4b7 bio_clone +EXPORT_SYMBOL vmlinux 0x64461a52 seq_printf +EXPORT_SYMBOL vmlinux 0x64547ddb blk_stop_queue +EXPORT_SYMBOL vmlinux 0x6464bb11 auth_domain_find +EXPORT_SYMBOL vmlinux 0x6476f256 path_get +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64f2981a request_key_async +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x6513d902 ipv4_specific +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x6526e164 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x654f05d7 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x655f0653 __invalidate_device +EXPORT_SYMBOL vmlinux 0x6572fdfb set_irq_chip +EXPORT_SYMBOL vmlinux 0x658dbeff do_splice_from +EXPORT_SYMBOL vmlinux 0x65a5c3a2 cpu_present_map +EXPORT_SYMBOL vmlinux 0x65ce2b64 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x661e6ec8 bioset_free +EXPORT_SYMBOL vmlinux 0x665ac310 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x665c0618 tcp_child_process +EXPORT_SYMBOL vmlinux 0x66643a0a call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x668b2f1a kill_block_super +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x668faf36 set_disk_ro +EXPORT_SYMBOL vmlinux 0x6690ec23 elv_rb_find +EXPORT_SYMBOL vmlinux 0x6697c200 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x66ca3bba generic_block_bmap +EXPORT_SYMBOL vmlinux 0x66e2f9a8 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x66e752c6 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x6740eec8 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x6741757e starget_for_each_device +EXPORT_SYMBOL vmlinux 0x67539d8b scsi_device_get +EXPORT_SYMBOL vmlinux 0x678a68c3 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x6791a3aa pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x67a9ecd4 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c2fa54 __copy_to_user +EXPORT_SYMBOL vmlinux 0x68782378 genl_register_ops +EXPORT_SYMBOL vmlinux 0x688a8368 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0x6898a756 sg_init_table +EXPORT_SYMBOL vmlinux 0x68ee853a mntput_no_expire +EXPORT_SYMBOL vmlinux 0x68f2ede3 scsi_add_device +EXPORT_SYMBOL vmlinux 0x690b8609 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x6929b6cc br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x69318470 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0x69496641 mod_timer +EXPORT_SYMBOL vmlinux 0x695456e5 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x695d98e8 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x6970e3ad init_buffer +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69967a44 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x69af2327 idr_init +EXPORT_SYMBOL vmlinux 0x69b13d5f blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x69c54db3 poll_freewait +EXPORT_SYMBOL vmlinux 0x69cb771c blk_remove_plug +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69d463cb __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69e3f887 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x69ee8e5f filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a6d23db take_over_console +EXPORT_SYMBOL vmlinux 0x6aa0f7de bio_add_page +EXPORT_SYMBOL vmlinux 0x6aa3c138 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x6ac45c28 __up_write +EXPORT_SYMBOL vmlinux 0x6ae76ceb flush_old_exec +EXPORT_SYMBOL vmlinux 0x6aed5ba9 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x6af0be28 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x6af60cda unlock_super +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b2aae32 clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b346c8f bd_release +EXPORT_SYMBOL vmlinux 0x6b63bf64 generic_delete_inode +EXPORT_SYMBOL vmlinux 0x6b6a77c4 vfs_readlink +EXPORT_SYMBOL vmlinux 0x6ba15f1f xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x6bacdbdf auth_domain_lookup +EXPORT_SYMBOL vmlinux 0x6bb7d6c8 wake_up_process +EXPORT_SYMBOL vmlinux 0x6bc35cf6 sock_create_lite +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6bfb027d blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x6c0456f3 xscale_mc_clear_user_page +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c36a5c1 __mutex_init +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c753704 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x6cd6b503 inode_needs_sync +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6ce16c26 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x6ce86a73 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x6cef247f __strnlen_user +EXPORT_SYMBOL vmlinux 0x6d07314b nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d1a8d73 inet_select_addr +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d662533 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x6db59ab3 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x6dc5e9e6 simple_dir_operations +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6df76ab2 d_lookup +EXPORT_SYMBOL vmlinux 0x6e429e97 irq_to_gpio +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e72395d scsi_block_requests +EXPORT_SYMBOL vmlinux 0x6e77c0af tcf_action_exec +EXPORT_SYMBOL vmlinux 0x6e84a85c save_time_delta +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6eddc093 do_munmap +EXPORT_SYMBOL vmlinux 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL vmlinux 0x6f08d4bc ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x6f7c850a __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x6f82c279 prepare_binprm +EXPORT_SYMBOL vmlinux 0x6f94f72c kthread_create +EXPORT_SYMBOL vmlinux 0x6f971840 skb_pull +EXPORT_SYMBOL vmlinux 0x6fa26c80 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x6fb569dd pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x6fc7404b skb_pad +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6ff833dd pci_release_region +EXPORT_SYMBOL vmlinux 0x7001d411 console_stop +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x70bdb227 dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0x70fc5c9f ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0x710e11d4 should_remove_suid +EXPORT_SYMBOL vmlinux 0x710e5d2f module_put +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x714815a2 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x714e2240 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x71723808 init_mm +EXPORT_SYMBOL vmlinux 0x71918a88 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71a87966 __pci_register_driver +EXPORT_SYMBOL vmlinux 0x71b819d0 iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x71c90087 memcmp +EXPORT_SYMBOL vmlinux 0x71d8c86d tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x71fa908a cache_flush +EXPORT_SYMBOL vmlinux 0x72015f49 ide_execute_command +EXPORT_SYMBOL vmlinux 0x72152c59 deny_write_access +EXPORT_SYMBOL vmlinux 0x72186ee7 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x726479f0 struct_module +EXPORT_SYMBOL vmlinux 0x72753715 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x72b0418a contig_page_data +EXPORT_SYMBOL vmlinux 0x72cb1ea2 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x72d5af61 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72fbae28 set_current_groups +EXPORT_SYMBOL vmlinux 0x73069aac cpu_possible_map +EXPORT_SYMBOL vmlinux 0x7308a449 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0x73451e3c uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x7345f2de sunrpc_cache_lookup +EXPORT_SYMBOL vmlinux 0x735a2d7c neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x73650e4d kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x736d5d86 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x73a99a5c seq_path +EXPORT_SYMBOL vmlinux 0x73d829c4 vfs_mknod +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x741b328d pci_map_rom +EXPORT_SYMBOL vmlinux 0x74293c6a pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x7468aa52 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x747275a1 journal_get_create_access +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74a1109e set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x74c5d857 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74fb8475 udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x74fef16d page_readlink +EXPORT_SYMBOL vmlinux 0x7510492b kernel_sendpage +EXPORT_SYMBOL vmlinux 0x75277585 inet_getname +EXPORT_SYMBOL vmlinux 0x7553c84b km_state_expired +EXPORT_SYMBOL vmlinux 0x7585c10e xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0x75ca58de key_type_keyring +EXPORT_SYMBOL vmlinux 0x75fee7fd __raw_writesb +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x762136ba scsi_execute_req +EXPORT_SYMBOL vmlinux 0x762cf14e scsi_target_resume +EXPORT_SYMBOL vmlinux 0x76445220 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x765f75fb pgprot_user +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76cb3257 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x76cf47f6 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76e9e78c mem_map +EXPORT_SYMBOL vmlinux 0x77075481 blk_init_queue +EXPORT_SYMBOL vmlinux 0x772e60e3 create_empty_buffers +EXPORT_SYMBOL vmlinux 0x773ec4e3 dst_release +EXPORT_SYMBOL vmlinux 0x77919504 xdr_init_encode +EXPORT_SYMBOL vmlinux 0x779a9522 iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x77ad0764 vm_map_ram +EXPORT_SYMBOL vmlinux 0x77c608cd __page_symlink +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x784b82f9 send_sig +EXPORT_SYMBOL vmlinux 0x786a9a96 blk_sync_queue +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78aa27f3 nlmsvc_ops +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x78f080da inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x7912b387 blkdev_get +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x7949ef1c scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x79600d4a wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79a71031 file_remove_suid +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79ad224b tasklet_kill +EXPORT_SYMBOL vmlinux 0x79b445a9 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x79b50e48 auth_unix_forget_old +EXPORT_SYMBOL vmlinux 0x79f00cd8 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x79f0239a input_set_keycode +EXPORT_SYMBOL vmlinux 0x7a124fa2 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x7a18338a svc_authenticate +EXPORT_SYMBOL vmlinux 0x7a1e395c generic_readlink +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a42f8cb seq_open_private +EXPORT_SYMBOL vmlinux 0x7a542eb0 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x7a558988 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x7a5bee35 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x7a7050c7 mb_cache_create +EXPORT_SYMBOL vmlinux 0x7a785526 write_inode_now +EXPORT_SYMBOL vmlinux 0x7a7b3812 input_event +EXPORT_SYMBOL vmlinux 0x7a972cd1 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x7aa6563a scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x7b7b46de qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x7ba6eb7c scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x7bb87838 netif_rx_ni +EXPORT_SYMBOL vmlinux 0x7be99691 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x7bf240bf journal_create +EXPORT_SYMBOL vmlinux 0x7c2200da _clear_bit_be +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c7c5f5a scm_fp_dup +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7cc035a7 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d88c4ab kmalloc_caches +EXPORT_SYMBOL vmlinux 0x7dae45b8 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7e058bfb xscale_coherent_kern_range +EXPORT_SYMBOL vmlinux 0x7e2c0cea bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x7e5277a8 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x7e531cde del_timer +EXPORT_SYMBOL vmlinux 0x7e5c5141 do_sync_read +EXPORT_SYMBOL vmlinux 0x7e743422 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x7e96ec53 register_key_type +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7ea633f7 pci_save_state +EXPORT_SYMBOL vmlinux 0x7eeb9b51 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x7f23390c tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f63b31e _memcpy_toio +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fdf9903 __nla_put +EXPORT_SYMBOL vmlinux 0x7ffe0893 kmem_cache_name +EXPORT_SYMBOL vmlinux 0x80038675 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x80052ad8 end_page_writeback +EXPORT_SYMBOL vmlinux 0x800e4ffa __muldi3 +EXPORT_SYMBOL vmlinux 0x8015d9ed dcache_readdir +EXPORT_SYMBOL vmlinux 0x802a739b fsync_bdev +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x8085c7b1 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x80bb22af pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x80c3d35c seq_bitmap +EXPORT_SYMBOL vmlinux 0x80d33e58 update_region +EXPORT_SYMBOL vmlinux 0x80e0f8bc tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x80f01cd7 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x8101b563 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x81388c78 path_put +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x81a3ca64 lock_rename +EXPORT_SYMBOL vmlinux 0x81c5fe96 sock_no_listen +EXPORT_SYMBOL vmlinux 0x81c8b508 npe_request +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82553058 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0x82692209 kref_set +EXPORT_SYMBOL vmlinux 0x82858801 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x8297d2f8 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x82b4cfaa _find_first_zero_bit_be +EXPORT_SYMBOL vmlinux 0x82cfd6c3 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x82e5a238 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x830bcd77 con_copy_unimap +EXPORT_SYMBOL vmlinux 0x8320bea8 __umodsi3 +EXPORT_SYMBOL vmlinux 0x833585dd loop_register_transfer +EXPORT_SYMBOL vmlinux 0x833a53ac ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x833c30f4 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x83517ac5 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0x8360f594 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x8377b5d8 sk_dst_check +EXPORT_SYMBOL vmlinux 0x838ef2a5 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0x839d43a1 put_page +EXPORT_SYMBOL vmlinux 0x839f9ae8 ilookup +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83ba000f del_gendisk +EXPORT_SYMBOL vmlinux 0x83bf638e npe_send_recv_message +EXPORT_SYMBOL vmlinux 0x83c4513d proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x8429ae7e neigh_seq_next +EXPORT_SYMBOL vmlinux 0x84870dc5 textsearch_destroy +EXPORT_SYMBOL vmlinux 0x84b0fc29 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x84b183ae strncmp +EXPORT_SYMBOL vmlinux 0x84f7bb84 is_bad_inode +EXPORT_SYMBOL vmlinux 0x850cf932 auth_unix_add_addr +EXPORT_SYMBOL vmlinux 0x85291fff unregister_netdev +EXPORT_SYMBOL vmlinux 0x8542df23 svc_auth_register +EXPORT_SYMBOL vmlinux 0x855ba854 pci_match_id +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x8578a0d0 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x85ac7f10 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x85d8674d register_binfmt +EXPORT_SYMBOL vmlinux 0x85d9c993 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x85f3127b generic_permission +EXPORT_SYMBOL vmlinux 0x85f9d7a1 rtnl_notify +EXPORT_SYMBOL vmlinux 0x861eda7b __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x8660866a pci_enable_wake +EXPORT_SYMBOL vmlinux 0x8679ec19 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x873e24de _find_next_zero_bit_be +EXPORT_SYMBOL vmlinux 0x87656291 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x878dfcb3 register_chrdev +EXPORT_SYMBOL vmlinux 0x87b9bf44 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x87bf920e journal_update_format +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x88204330 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x887e79c9 cont_write_begin +EXPORT_SYMBOL vmlinux 0x88a924b8 nf_log_register +EXPORT_SYMBOL vmlinux 0x89164a1e blk_unplug +EXPORT_SYMBOL vmlinux 0x891e32b8 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x892009db elv_rb_del +EXPORT_SYMBOL vmlinux 0x8949ae07 xfrm_register_km +EXPORT_SYMBOL vmlinux 0x8958c203 block_write_end +EXPORT_SYMBOL vmlinux 0x895c7116 scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x896b96df tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x899627a6 vfs_write +EXPORT_SYMBOL vmlinux 0x899c829e xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89d8bf0c qdisc_reset +EXPORT_SYMBOL vmlinux 0x89db053a pcim_iomap +EXPORT_SYMBOL vmlinux 0x89dc3966 journal_forget +EXPORT_SYMBOL vmlinux 0x8a0593ac dev_remove_pack +EXPORT_SYMBOL vmlinux 0x8a1203a9 kref_get +EXPORT_SYMBOL vmlinux 0x8a324958 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x8a4fa83b __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x8a60daab gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x8a71a2df input_inject_event +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aaec693 sock_create +EXPORT_SYMBOL vmlinux 0x8b4304ee pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b62af55 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x8b9a4149 ida_destroy +EXPORT_SYMBOL vmlinux 0x8bbfa2b9 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x8bc27b65 vfs_writev +EXPORT_SYMBOL vmlinux 0x8bf37798 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0x8c18dd16 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x8c615277 tty_write_room +EXPORT_SYMBOL vmlinux 0x8c7bc348 ida_remove +EXPORT_SYMBOL vmlinux 0x8c84069c restore_time_delta +EXPORT_SYMBOL vmlinux 0x8c878cba textsearch_register +EXPORT_SYMBOL vmlinux 0x8c94774f __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x8cab99d3 unix_domain_find +EXPORT_SYMBOL vmlinux 0x8cb5e714 __brelse +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d5642fc wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d8f5007 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x8da0e6bc pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x8db89ffb pci_set_power_state +EXPORT_SYMBOL vmlinux 0x8dcb5c27 idr_remove +EXPORT_SYMBOL vmlinux 0x8de3cd00 scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x8e0a5f48 pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e398b22 vfs_rmdir +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e465bc2 blk_plug_device +EXPORT_SYMBOL vmlinux 0x8e4e5172 sk_stop_timer +EXPORT_SYMBOL vmlinux 0x8e63bf7c seq_release_private +EXPORT_SYMBOL vmlinux 0x8e7378f7 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e8d60d4 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x8f07d8ca __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8f5a9add mapping_tagged +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f8ba392 scsi_print_command +EXPORT_SYMBOL vmlinux 0x8f98b585 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x8f9b86b2 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x8fae5ca3 kill_litter_super +EXPORT_SYMBOL vmlinux 0x8fd9cd08 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x8fda8d22 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x8fdb8197 try_to_release_page +EXPORT_SYMBOL vmlinux 0x8feebee1 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x900e3efc neigh_seq_start +EXPORT_SYMBOL vmlinux 0x9020845e xdr_inline_decode +EXPORT_SYMBOL vmlinux 0x9028bdf8 eth_header_parse +EXPORT_SYMBOL vmlinux 0x906ad67c request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x907d1c90 sk_receive_skb +EXPORT_SYMBOL vmlinux 0x90a7c3b1 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x90aa82e9 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x90b041a1 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x90d1d034 textsearch_unregister +EXPORT_SYMBOL vmlinux 0x90e93cb4 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x90f8e3f7 nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x9110c790 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x919029aa __readwrite_bug +EXPORT_SYMBOL vmlinux 0x9199f03c sync_inode +EXPORT_SYMBOL vmlinux 0x91a8168c dev_driver_string +EXPORT_SYMBOL vmlinux 0x91aa0ecc blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x91c4e610 svc_create +EXPORT_SYMBOL vmlinux 0x91c92dff set_anon_super +EXPORT_SYMBOL vmlinux 0x91ef34b2 tcp_ioctl +EXPORT_SYMBOL vmlinux 0x91efa4e6 fput +EXPORT_SYMBOL vmlinux 0x92359483 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x926401f2 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x927aab13 ip6_route_output +EXPORT_SYMBOL vmlinux 0x928eb60a seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x92ab9a55 skb_over_panic +EXPORT_SYMBOL vmlinux 0x930a0f0a ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x9362134a sock_no_poll +EXPORT_SYMBOL vmlinux 0x93788b37 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x93803e81 load_nls +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x940e2fe7 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x94239b8b call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x943283f5 open_by_devnum +EXPORT_SYMBOL vmlinux 0x943e42b9 fasync_helper +EXPORT_SYMBOL vmlinux 0x947a6c34 dma_map_page +EXPORT_SYMBOL vmlinux 0x9489ed17 svc_drop +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94a824c1 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x94ca29f8 unregister_binfmt +EXPORT_SYMBOL vmlinux 0x94ccaee5 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0x94df3f1f netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x9501d078 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x95087ef5 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x95241b87 xdr_buf_subsegment +EXPORT_SYMBOL vmlinux 0x952a4470 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x952f804f simple_transaction_release +EXPORT_SYMBOL vmlinux 0x9540d054 bdevname +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x955b3456 bdi_register_dev +EXPORT_SYMBOL vmlinux 0x95963101 open_exec +EXPORT_SYMBOL vmlinux 0x95d4074a generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x95dbe078 __get_user_2 +EXPORT_SYMBOL vmlinux 0x95f36b53 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x96156a7f nlmsg_notify +EXPORT_SYMBOL vmlinux 0x9651c932 __bio_clone +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x96ac0099 dma_map_single +EXPORT_SYMBOL vmlinux 0x96ca2e7d pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96d277af blk_get_request +EXPORT_SYMBOL vmlinux 0x96dbf0af mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x96df5482 walk_stackframe +EXPORT_SYMBOL vmlinux 0x97255bdf strlen +EXPORT_SYMBOL vmlinux 0x972eac6d filemap_fault +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x97641b18 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x9789c319 generic_show_options +EXPORT_SYMBOL vmlinux 0x979434cf scsi_finish_command +EXPORT_SYMBOL vmlinux 0x97a9c2d2 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x97b3347f neigh_connected_output +EXPORT_SYMBOL vmlinux 0x97f86273 cache_check +EXPORT_SYMBOL vmlinux 0x97f8fc88 simple_fill_super +EXPORT_SYMBOL vmlinux 0x98016a4a xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x98281757 netdev_set_master +EXPORT_SYMBOL vmlinux 0x9833cec1 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x983fb16c netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x984fe491 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x9899f6e8 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x98ab0f00 npe_load_firmware +EXPORT_SYMBOL vmlinux 0x98dcfc78 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x98e8b3cb sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x9930f997 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x994a3195 pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0x999c3148 __raw_readsb +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99a0bc52 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99aea658 journal_revoke +EXPORT_SYMBOL vmlinux 0x99bb8806 memmove +EXPORT_SYMBOL vmlinux 0x99bcf897 pci_release_regions +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c0befa netdev_features_change +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x9a0cb19b blk_init_tags +EXPORT_SYMBOL vmlinux 0x9a108cd3 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a64353f sock_i_ino +EXPORT_SYMBOL vmlinux 0x9a69530d read_cache_page +EXPORT_SYMBOL vmlinux 0x9aaba553 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x9ab3f4b4 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x9afc3b4c ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x9b0483ac ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x9b2ccc9b i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x9b31f119 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b4bbaa9 dmabounce_register_dev +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bb07de5 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0x9bbe6426 blk_insert_request +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9bf3b6ef __ide_dma_bad_drive +EXPORT_SYMBOL vmlinux 0x9c1700ed add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x9c1f3ace input_allocate_device +EXPORT_SYMBOL vmlinux 0x9c2571f4 __down_read +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c8958f8 current_fs_time +EXPORT_SYMBOL vmlinux 0x9ca41a23 __scm_destroy +EXPORT_SYMBOL vmlinux 0x9ca9459c netdev_state_change +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9cbec294 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x9ce29bf2 proto_unregister +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d669763 memcpy +EXPORT_SYMBOL vmlinux 0x9d7ca585 skb_clone +EXPORT_SYMBOL vmlinux 0x9d7d4134 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x9d9d74f1 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x9dd0a234 netif_device_attach +EXPORT_SYMBOL vmlinux 0x9ddba533 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x9e120414 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x9e1a408b ether_setup +EXPORT_SYMBOL vmlinux 0x9e2f1818 inetdev_by_index +EXPORT_SYMBOL vmlinux 0x9e3a857e cfi_read_pri +EXPORT_SYMBOL vmlinux 0x9e440c87 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x9e684a52 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9ea428e2 journal_set_features +EXPORT_SYMBOL vmlinux 0x9eacb976 scsi_print_result +EXPORT_SYMBOL vmlinux 0x9eb7e86d generic_make_request +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9efc9ad0 bio_map_kern +EXPORT_SYMBOL vmlinux 0x9f01b20a scsi_unregister +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f26a4fd __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f4643a3 dmam_pool_create +EXPORT_SYMBOL vmlinux 0x9f7c87de dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x9f8c2542 skb_under_panic +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9f9f536e input_flush_device +EXPORT_SYMBOL vmlinux 0x9fb19e3a posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9fc04d68 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x9fd6cf48 unregister_key_type +EXPORT_SYMBOL vmlinux 0xa02e8386 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xa036ebc5 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa063236c inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0xa070d940 end_request +EXPORT_SYMBOL vmlinux 0xa07a8d22 sleep_on +EXPORT_SYMBOL vmlinux 0xa07ac24b irq_stat +EXPORT_SYMBOL vmlinux 0xa0af2369 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0b40948 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0xa0b4f78b inode_sub_bytes +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0eae86a blk_init_queue_node +EXPORT_SYMBOL vmlinux 0xa0edfed4 xfrm_state_update +EXPORT_SYMBOL vmlinux 0xa0f03db0 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa16d4189 nonseekable_open +EXPORT_SYMBOL vmlinux 0xa16e1636 input_release_device +EXPORT_SYMBOL vmlinux 0xa199cd6c may_umount_tree +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa218bf61 complete +EXPORT_SYMBOL vmlinux 0xa219d87b unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xa23d5429 qdisc_list_del +EXPORT_SYMBOL vmlinux 0xa27afd71 sock_setsockopt +EXPORT_SYMBOL vmlinux 0xa295cd0d __scm_send +EXPORT_SYMBOL vmlinux 0xa2997d03 journal_lock_updates +EXPORT_SYMBOL vmlinux 0xa29b1708 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xa29b67c2 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa3349eb3 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xa346da2e tcp_check_req +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa354db27 inet_shutdown +EXPORT_SYMBOL vmlinux 0xa3577ba2 seq_open +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa36d98e5 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0xa38002d7 d_splice_alias +EXPORT_SYMBOL vmlinux 0xa395bec9 seq_read +EXPORT_SYMBOL vmlinux 0xa3a4ed03 cond_resched_lock +EXPORT_SYMBOL vmlinux 0xa3b803a2 inet_release +EXPORT_SYMBOL vmlinux 0xa3daf28a init_task +EXPORT_SYMBOL vmlinux 0xa3f87373 register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0xa42ea3d1 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0xa47e8b12 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0xa47ed1c7 sync_blockdev +EXPORT_SYMBOL vmlinux 0xa48f58dc d_instantiate +EXPORT_SYMBOL vmlinux 0xa4ac5275 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xa4dd05cb i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0xa4fbc339 auth_domain_put +EXPORT_SYMBOL vmlinux 0xa5100c92 svc_prepare_thread +EXPORT_SYMBOL vmlinux 0xa532d08a scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xa5359f5d create_proc_entry +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa5559cdd gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0xa5690ef5 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xa5808bbf tasklet_init +EXPORT_SYMBOL vmlinux 0xa58b1081 __free_pages +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5acaa66 tty_register_device +EXPORT_SYMBOL vmlinux 0xa5cdf467 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5f620d4 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xa601e3c7 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0xa625df90 inet_stream_ops +EXPORT_SYMBOL vmlinux 0xa62c4063 tty_devnum +EXPORT_SYMBOL vmlinux 0xa65d4cee xfrm_nl +EXPORT_SYMBOL vmlinux 0xa6743f99 bdi_unregister +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa69903e8 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6f5b6d9 dmabounce_unregister_dev +EXPORT_SYMBOL vmlinux 0xa7242cd7 have_submounts +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa7a47911 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xa7b91a7b lockd_down +EXPORT_SYMBOL vmlinux 0xa7c2f91f iunique +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7d6acae pci_get_device +EXPORT_SYMBOL vmlinux 0xa826f33d sock_no_accept +EXPORT_SYMBOL vmlinux 0xa8402a90 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0xa86fab56 proc_dointvec +EXPORT_SYMBOL vmlinux 0xa8c9c0f8 inode_double_unlock +EXPORT_SYMBOL vmlinux 0xa8d15ebe request_key +EXPORT_SYMBOL vmlinux 0xa900d8a6 set_bh_page +EXPORT_SYMBOL vmlinux 0xa90a8755 vm_insert_page +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa931187d tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0xa9a7c041 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0xa9f1ed23 bit_waitqueue +EXPORT_SYMBOL vmlinux 0xaa16baee sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0xaa2c8747 brioctl_set +EXPORT_SYMBOL vmlinux 0xaa527612 __kfifo_put +EXPORT_SYMBOL vmlinux 0xaa69dffd tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0xaa6cb0da shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0xaa715fb6 nobh_write_end +EXPORT_SYMBOL vmlinux 0xaa772042 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0xaa957f3c kill_pgrp +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xab0c6d3d devm_ioremap +EXPORT_SYMBOL vmlinux 0xab2fc84b inet_put_port +EXPORT_SYMBOL vmlinux 0xab39b4d8 inet_frags_fini +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab53b0a8 mempool_alloc +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab64527d mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0xab680c96 __down_read_trylock +EXPORT_SYMBOL vmlinux 0xab75e30f tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xab7e2360 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0xabad83d7 udp_hash_lock +EXPORT_SYMBOL vmlinux 0xabba39b0 inet_frag_find +EXPORT_SYMBOL vmlinux 0xabc1829d pci_scan_single_device +EXPORT_SYMBOL vmlinux 0xabcf5af0 dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac50392f mnt_pin +EXPORT_SYMBOL vmlinux 0xac54fc9f mempool_destroy +EXPORT_SYMBOL vmlinux 0xac5989af n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0xac5f113d cpu_all_bits +EXPORT_SYMBOL vmlinux 0xac612569 kernel_listen +EXPORT_SYMBOL vmlinux 0xac88cb73 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0xac893ba2 generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0xac959bd2 pneigh_lookup +EXPORT_SYMBOL vmlinux 0xacade279 inet_register_protosw +EXPORT_SYMBOL vmlinux 0xacaf1858 netlink_unicast +EXPORT_SYMBOL vmlinux 0xacb1be9d pci_set_mwi +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacd29362 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0xacdc6b8e proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad15b41f tcf_register_action +EXPORT_SYMBOL vmlinux 0xad1b89fe input_unregister_handler +EXPORT_SYMBOL vmlinux 0xad7f8d9c scsi_print_sense +EXPORT_SYMBOL vmlinux 0xad883fc5 kmem_cache_free +EXPORT_SYMBOL vmlinux 0xadb792c2 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0xaddddc73 inet_addr_type +EXPORT_SYMBOL vmlinux 0xae1c6542 vc_cons +EXPORT_SYMBOL vmlinux 0xae1fbd06 sk_filter +EXPORT_SYMBOL vmlinux 0xae296be4 kill_anon_super +EXPORT_SYMBOL vmlinux 0xae78911f sk_release_kernel +EXPORT_SYMBOL vmlinux 0xae87330e d_find_alias +EXPORT_SYMBOL vmlinux 0xae9cd5c4 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xaebabfa6 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0xaec2adaa iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaed013b9 posix_acl_valid +EXPORT_SYMBOL vmlinux 0xaee034a3 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0xaee3ff66 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0xaeed7a11 dev_alloc_name +EXPORT_SYMBOL vmlinux 0xaf193413 pcim_enable_device +EXPORT_SYMBOL vmlinux 0xaf50e76d elf_set_personality +EXPORT_SYMBOL vmlinux 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL vmlinux 0xaf69e333 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0xaf6e423b generic_fillattr +EXPORT_SYMBOL vmlinux 0xaf8aa518 system_rev +EXPORT_SYMBOL vmlinux 0xaf9b3fe8 neigh_parms_release +EXPORT_SYMBOL vmlinux 0xafb11371 default_llseek +EXPORT_SYMBOL vmlinux 0xafb9117b gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0xafcce897 vc_resize +EXPORT_SYMBOL vmlinux 0xafd80110 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0xb045ae8c generic_osync_inode +EXPORT_SYMBOL vmlinux 0xb0a4dad9 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb14f0d13 simple_transaction_get +EXPORT_SYMBOL vmlinux 0xb15fe9cf proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0xb18f3f06 ide_xfer_verbose +EXPORT_SYMBOL vmlinux 0xb1918605 journal_errno +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb199a771 tty_port_init +EXPORT_SYMBOL vmlinux 0xb1aeee5d d_validate +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1d01e4b __bread +EXPORT_SYMBOL vmlinux 0xb1e90af7 __lock_page +EXPORT_SYMBOL vmlinux 0xb1e98ef4 cache_purge +EXPORT_SYMBOL vmlinux 0xb1ed744c netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0xb1f223a8 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0xb2095490 iget_locked +EXPORT_SYMBOL vmlinux 0xb22404d0 cdev_add +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb24becd7 iget5_locked +EXPORT_SYMBOL vmlinux 0xb2906944 key_payload_reserve +EXPORT_SYMBOL vmlinux 0xb295dea9 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xb2960c5e mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0xb2a960d3 pagecache_write_end +EXPORT_SYMBOL vmlinux 0xb2b1b43a pskb_copy +EXPORT_SYMBOL vmlinux 0xb2b75a5a scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0xb2bf1312 __up_read +EXPORT_SYMBOL vmlinux 0xb2cdefb2 xdr_read_pages +EXPORT_SYMBOL vmlinux 0xb2d42520 tcp_poll +EXPORT_SYMBOL vmlinux 0xb33c3a8b pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xb3480607 locks_copy_lock +EXPORT_SYMBOL vmlinux 0xb34acb65 send_sig_info +EXPORT_SYMBOL vmlinux 0xb353ebc8 filp_close +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb37b421a svc_recv +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3a42f65 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xb3c0cfa7 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0xb3c92d07 tc_classify +EXPORT_SYMBOL vmlinux 0xb3cf9032 i2c_release_client +EXPORT_SYMBOL vmlinux 0xb3fe02b1 down_write +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb4517277 xdr_decode_array2 +EXPORT_SYMBOL vmlinux 0xb452a3be __mpage_writepage +EXPORT_SYMBOL vmlinux 0xb4596d29 remap_pfn_range +EXPORT_SYMBOL vmlinux 0xb45e06d7 lock_super +EXPORT_SYMBOL vmlinux 0xb47c84d5 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4a0e989 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0xb4b52c65 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xb4d08c96 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb534763c sg_free_table +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb54b249e d_namespace_path +EXPORT_SYMBOL vmlinux 0xb55473c0 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0xb5567412 scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0xb598fa06 sock_sendmsg +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5c4b676 elevator_exit +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb64fe754 pci_fixup_device +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6b39e66 unregister_console +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6c70a7d __wake_up +EXPORT_SYMBOL vmlinux 0xb6fe41d3 proc_mkdir +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb70f9269 blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb7153e52 __neigh_event_send +EXPORT_SYMBOL vmlinux 0xb71710c0 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0xb7272a3c __seq_open_private +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb77eabea journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xb78d2146 mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0xb798898c __napi_schedule +EXPORT_SYMBOL vmlinux 0xb7aa1ee1 get_io_context +EXPORT_SYMBOL vmlinux 0xb7ad3321 ida_init +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb808d4c3 devm_free_irq +EXPORT_SYMBOL vmlinux 0xb8126417 sync_page_range +EXPORT_SYMBOL vmlinux 0xb82e499a simple_rename +EXPORT_SYMBOL vmlinux 0xb859f38b krealloc +EXPORT_SYMBOL vmlinux 0xb863e241 noop_qdisc +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8d14b32 input_open_device +EXPORT_SYMBOL vmlinux 0xb8d4e258 scsi_scan_host +EXPORT_SYMBOL vmlinux 0xb8de45e8 scsi_remove_device +EXPORT_SYMBOL vmlinux 0xb8fff273 generic_unplug_device +EXPORT_SYMBOL vmlinux 0xb905879c neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb91b48d8 I_BDEV +EXPORT_SYMBOL vmlinux 0xb93f4a14 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0xb948286b pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0xb95f98d6 _memset_io +EXPORT_SYMBOL vmlinux 0xb976fa61 put_filp +EXPORT_SYMBOL vmlinux 0xb97d4c9c mutex_lock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb98ef804 vm_stat +EXPORT_SYMBOL vmlinux 0xb9a5a89a d_add_ci +EXPORT_SYMBOL vmlinux 0xb9acd3d9 __put_user_2 +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xba1b14e5 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xba2bd3ee rpc_unlink +EXPORT_SYMBOL vmlinux 0xba3bda2a __downgrade_write +EXPORT_SYMBOL vmlinux 0xba432734 register_gifconf +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba5078fd xscale_flush_kern_cache_all +EXPORT_SYMBOL vmlinux 0xba7c85c6 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xba86735f tcf_exts_validate +EXPORT_SYMBOL vmlinux 0xba8f8b68 completion_done +EXPORT_SYMBOL vmlinux 0xbaba703c complete_request_key +EXPORT_SYMBOL vmlinux 0xbaff52f9 write_cache_pages +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb24757a blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0xbb3b5285 arp_xmit +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb721c62 unregister_qdisc +EXPORT_SYMBOL vmlinux 0xbb72d4fe __put_user_1 +EXPORT_SYMBOL vmlinux 0xbb78e157 rtnl_unicast +EXPORT_SYMBOL vmlinux 0xbba61c16 ixp4xx_pci_read +EXPORT_SYMBOL vmlinux 0xbba6c00d rpc_queue_upcall +EXPORT_SYMBOL vmlinux 0xbbb41912 tcf_hash_search +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbbcbb388 handle_sysrq +EXPORT_SYMBOL vmlinux 0xbbf75a93 journal_get_write_access +EXPORT_SYMBOL vmlinux 0xbc10dd97 __put_user_4 +EXPORT_SYMBOL vmlinux 0xbca6579e task_nice +EXPORT_SYMBOL vmlinux 0xbcb243f3 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0xbcd2579e netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0xbd245b58 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0xbd424778 bdi_destroy +EXPORT_SYMBOL vmlinux 0xbd8685d2 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xbdf2580d __raw_readsl +EXPORT_SYMBOL vmlinux 0xbe03ff4e serial8250_register_port +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe2518b8 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0xbe38826a tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0xbe62261a scsi_free_command +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe68d169 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0xbe7b2177 pci_enable_device +EXPORT_SYMBOL vmlinux 0xbe82135b cad_pid +EXPORT_SYMBOL vmlinux 0xbead0f20 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0xbeb810d8 skb_queue_tail +EXPORT_SYMBOL vmlinux 0xbebc16e4 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0xbebd3406 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xbecbf0fb tcp_hashinfo +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbef86b32 ilookup5 +EXPORT_SYMBOL vmlinux 0xbf3c3e9b skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0xbf5e17e2 block_write_full_page +EXPORT_SYMBOL vmlinux 0xbf60fec3 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfb42474 inet_ioctl +EXPORT_SYMBOL vmlinux 0xbfc73eb4 single_release +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc0561354 bdi_init +EXPORT_SYMBOL vmlinux 0xc0565edd bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc08e9d9d simple_write_end +EXPORT_SYMBOL vmlinux 0xc0d89cb2 qmgr_set_irq +EXPORT_SYMBOL vmlinux 0xc0dabcc0 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0xc0fa5268 svc_set_client +EXPORT_SYMBOL vmlinux 0xc0fb2592 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc1601a4f _change_bit_le +EXPORT_SYMBOL vmlinux 0xc18000da pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0xc1d701d9 journal_init_inode +EXPORT_SYMBOL vmlinux 0xc1fa1d82 simple_pin_fs +EXPORT_SYMBOL vmlinux 0xc1fc4511 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0xc22616f1 __init_rwsem +EXPORT_SYMBOL vmlinux 0xc22ef812 __devm_request_region +EXPORT_SYMBOL vmlinux 0xc250f4f8 inode_set_bytes +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc259d509 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xc26ea970 ip6_frag_match +EXPORT_SYMBOL vmlinux 0xc27487dd __bug +EXPORT_SYMBOL vmlinux 0xc27bc7cf cfi_varsize_frob +EXPORT_SYMBOL vmlinux 0xc28ea0dd pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xc2909ca7 elv_rb_former_request +EXPORT_SYMBOL vmlinux 0xc29e3c2e generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xc2b8df73 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0xc2d4293d __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2f5a2a5 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xc3085e3a bio_put +EXPORT_SYMBOL vmlinux 0xc3520f8f keyring_search +EXPORT_SYMBOL vmlinux 0xc359fb65 abort +EXPORT_SYMBOL vmlinux 0xc35b0bf0 __alloc_skb +EXPORT_SYMBOL vmlinux 0xc372dcfe ide_end_request +EXPORT_SYMBOL vmlinux 0xc37b040e xdr_encode_pages +EXPORT_SYMBOL vmlinux 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL vmlinux 0xc38e72a6 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xc395815b udp_ioctl +EXPORT_SYMBOL vmlinux 0xc3caf013 user_path_at +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3fdd1a5 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xc440c451 sg_alloc_table +EXPORT_SYMBOL vmlinux 0xc46fe2b0 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4f8b5a9 neigh_for_each +EXPORT_SYMBOL vmlinux 0xc4fb7bd7 free_task +EXPORT_SYMBOL vmlinux 0xc566a405 uart_register_driver +EXPORT_SYMBOL vmlinux 0xc5974eaf inode_double_lock +EXPORT_SYMBOL vmlinux 0xc625d2b9 ixp4xx_exp_bus_size +EXPORT_SYMBOL vmlinux 0xc633495b schedule_work +EXPORT_SYMBOL vmlinux 0xc6729dad posix_lock_file +EXPORT_SYMBOL vmlinux 0xc67cac6f dput +EXPORT_SYMBOL vmlinux 0xc6c55e3a tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc722227e posix_acl_clone +EXPORT_SYMBOL vmlinux 0xc7891623 svc_seq_show +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7d043cb tty_shutdown +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc7f71e62 single_open +EXPORT_SYMBOL vmlinux 0xc80de694 down_write_trylock +EXPORT_SYMBOL vmlinux 0xc85aef9a neigh_table_clear +EXPORT_SYMBOL vmlinux 0xc889d11a vfs_rename +EXPORT_SYMBOL vmlinux 0xc8b3b024 register_con_driver +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8be701e map_destroy +EXPORT_SYMBOL vmlinux 0xc8c4fc6a nf_reinject +EXPORT_SYMBOL vmlinux 0xc8ce8774 netif_device_detach +EXPORT_SYMBOL vmlinux 0xc8cff85f __ip_select_ident +EXPORT_SYMBOL vmlinux 0xc8d318ad xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0xc8e1941c dmabounce_sync_for_device +EXPORT_SYMBOL vmlinux 0xc8e96dea qword_addhex +EXPORT_SYMBOL vmlinux 0xc8f50f48 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0xc90f8c52 xdr_encode_word +EXPORT_SYMBOL vmlinux 0xc9146919 xfrm_init_state +EXPORT_SYMBOL vmlinux 0xc93c243c xdr_shift_buf +EXPORT_SYMBOL vmlinux 0xc9862162 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xc993cd11 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9c0c698 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0xca00030b dget_locked +EXPORT_SYMBOL vmlinux 0xca4a41c7 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0xca4faed2 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xcad32ac0 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0xcaf936e7 bio_endio +EXPORT_SYMBOL vmlinux 0xcb0e1e09 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0xcb22e06c dmam_free_coherent +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb5060b4 remove_arg_zero +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7036cb fget +EXPORT_SYMBOL vmlinux 0xcbdf2595 __lock_buffer +EXPORT_SYMBOL vmlinux 0xcc2140ee tcp_read_sock +EXPORT_SYMBOL vmlinux 0xcc220e17 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc8a870a scsi_prep_return +EXPORT_SYMBOL vmlinux 0xcc9aacb1 read_bytes_from_xdr_buf +EXPORT_SYMBOL vmlinux 0xcccca482 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0xcce87c5c blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0xcd0a2c68 pci_find_capability +EXPORT_SYMBOL vmlinux 0xcd0c41c2 elv_queue_empty +EXPORT_SYMBOL vmlinux 0xcd2987fb inet_listen +EXPORT_SYMBOL vmlinux 0xcd2cb005 register_netdevice +EXPORT_SYMBOL vmlinux 0xcd3e19fc generic_file_open +EXPORT_SYMBOL vmlinux 0xcd63c845 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0xcd751352 get_sb_nodev +EXPORT_SYMBOL vmlinux 0xcd7e4450 sk_wait_data +EXPORT_SYMBOL vmlinux 0xcd8c6b63 scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0xcd942530 key_task_permission +EXPORT_SYMBOL vmlinux 0xcd9b489e sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0xcd9c63c8 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xcdb3b4db input_free_device +EXPORT_SYMBOL vmlinux 0xcdc4c4b8 pci_find_slot +EXPORT_SYMBOL vmlinux 0xcdd2ea72 register_console +EXPORT_SYMBOL vmlinux 0xcdf3a8fb ip_mc_join_group +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce2e1a73 pcim_pin_device +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce58a51d ide_do_drive_cmd +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce79f9e4 con_is_bound +EXPORT_SYMBOL vmlinux 0xce9c1ea5 path_lookup +EXPORT_SYMBOL vmlinux 0xceb456d8 udp_poll +EXPORT_SYMBOL vmlinux 0xcec76e98 pcibios_bus_to_resource +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf168a20 blk_free_tags +EXPORT_SYMBOL vmlinux 0xcf29c436 dst_destroy +EXPORT_SYMBOL vmlinux 0xcf4b89f4 cache_unregister +EXPORT_SYMBOL vmlinux 0xcf5b7735 block_invalidatepage +EXPORT_SYMBOL vmlinux 0xcf6a0aab vfs_statfs +EXPORT_SYMBOL vmlinux 0xcfa9c731 skb_insert +EXPORT_SYMBOL vmlinux 0xcfadb97c dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0xcfbf3bfb task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcff53400 kref_put +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd03a7dae set_user_nice +EXPORT_SYMBOL vmlinux 0xd0484d20 keyring_clear +EXPORT_SYMBOL vmlinux 0xd0673637 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0xd0b832b9 tty_throttle +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0f32b80 svc_set_num_threads +EXPORT_SYMBOL vmlinux 0xd10cc839 elv_rb_add +EXPORT_SYMBOL vmlinux 0xd13564e8 __kill_fasync +EXPORT_SYMBOL vmlinux 0xd164b0e1 skb_split +EXPORT_SYMBOL vmlinux 0xd164fafd nf_register_sockopt +EXPORT_SYMBOL vmlinux 0xd168d8b9 cpu_xscale_dcache_clean_area +EXPORT_SYMBOL vmlinux 0xd19a652d tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0xd1cb21c9 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0xd1cffa30 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xd21a84b8 dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0xd234a365 kthread_stop +EXPORT_SYMBOL vmlinux 0xd238e23b simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0xd2478f28 bd_claim +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd256a8ee unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd26cb1a1 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0xd295a7a8 sg_miter_start +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2a8696c pci_dev_put +EXPORT_SYMBOL vmlinux 0xd2b6591f input_unregister_device +EXPORT_SYMBOL vmlinux 0xd2d45b10 qmgr_release_queue +EXPORT_SYMBOL vmlinux 0xd2ed8789 inet6_bind +EXPORT_SYMBOL vmlinux 0xd32d7f67 kset_register +EXPORT_SYMBOL vmlinux 0xd32e52c7 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0xd3427f73 mempool_create_node +EXPORT_SYMBOL vmlinux 0xd35d572f simple_statfs +EXPORT_SYMBOL vmlinux 0xd3abb989 follow_up +EXPORT_SYMBOL vmlinux 0xd3be4904 submit_bio +EXPORT_SYMBOL vmlinux 0xd3d8bcc1 neigh_ifdown +EXPORT_SYMBOL vmlinux 0xd3dbfbc4 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0xd3fd0426 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd423ba63 i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xd4315c14 i2c_clients_command +EXPORT_SYMBOL vmlinux 0xd44fd853 scsi_remove_host +EXPORT_SYMBOL vmlinux 0xd47553a0 vm_insert_pfn +EXPORT_SYMBOL vmlinux 0xd485c3c5 sock_map_fd +EXPORT_SYMBOL vmlinux 0xd4a45018 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0xd4b2645d scsi_scan_target +EXPORT_SYMBOL vmlinux 0xd4cfe815 iget_failed +EXPORT_SYMBOL vmlinux 0xd4d338bc scsi_host_put +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd5c8e445 eth_header_cache +EXPORT_SYMBOL vmlinux 0xd5e7520e request_firmware +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd60f840d scsi_dma_map +EXPORT_SYMBOL vmlinux 0xd627480b strncat +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd62f4e5f tcf_generic_walker +EXPORT_SYMBOL vmlinux 0xd66c6228 down_read_trylock +EXPORT_SYMBOL vmlinux 0xd686cf6f scsi_device_put +EXPORT_SYMBOL vmlinux 0xd6c6bb10 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6f27efd scsi_init_io +EXPORT_SYMBOL vmlinux 0xd6f808c5 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0xd723dfc2 tty_vhangup +EXPORT_SYMBOL vmlinux 0xd72ba695 tcf_exts_change +EXPORT_SYMBOL vmlinux 0xd766babc generic_ide_ioctl +EXPORT_SYMBOL vmlinux 0xd76ed995 svc_process +EXPORT_SYMBOL vmlinux 0xd77e4e0e svc_wake_up +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7a595ca scsi_get_command +EXPORT_SYMBOL vmlinux 0xd7b69fae idr_find +EXPORT_SYMBOL vmlinux 0xd8282ff0 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0xd84a149f dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0xd84b168f inet_accept +EXPORT_SYMBOL vmlinux 0xd854cf12 pci_reenable_device +EXPORT_SYMBOL vmlinux 0xd8589ae1 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0xd87763e0 free_buffer_head +EXPORT_SYMBOL vmlinux 0xd899b0e3 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8f98d41 proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xd91a3236 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0xd91c9b7a rt6_lookup +EXPORT_SYMBOL vmlinux 0xd9721b25 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9899623 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0xd9b387ee filemap_fdatawait +EXPORT_SYMBOL vmlinux 0xd9bda371 __netif_schedule +EXPORT_SYMBOL vmlinux 0xd9cd435a journal_start +EXPORT_SYMBOL vmlinux 0xd9ce8f0c strnlen +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda1c3ca3 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0xda1ca181 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xda44f7c5 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xda5ea696 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0xda6aacf5 udp_prot +EXPORT_SYMBOL vmlinux 0xda8b5096 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xdabe8064 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0xdaf41b68 ide_dma_off_quietly +EXPORT_SYMBOL vmlinux 0xdb343964 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0xdb4a8232 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdba3bf61 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0xdbaa6f20 netlink_ack +EXPORT_SYMBOL vmlinux 0xdbbf3f79 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbd16602 make_bad_inode +EXPORT_SYMBOL vmlinux 0xdbe1f3ec pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xdbffb8c3 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0xdc053205 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc17de7b blk_requeue_request +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc42b7fd sysctl_intvec +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc76d904 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0xdc7b5d06 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0xdc8a2b8c journal_abort +EXPORT_SYMBOL vmlinux 0xdc8dae67 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0xdc93047e i2c_register_driver +EXPORT_SYMBOL vmlinux 0xdca89278 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcb17ab9 bh_submit_read +EXPORT_SYMBOL vmlinux 0xdcf380bd xdr_encode_array2 +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd1bfc2c journal_release_buffer +EXPORT_SYMBOL vmlinux 0xdd27fa87 memchr +EXPORT_SYMBOL vmlinux 0xdd597abc save_mount_options +EXPORT_SYMBOL vmlinux 0xdd5deace blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd82fc94 bdget +EXPORT_SYMBOL vmlinux 0xdd85029a km_new_mapping +EXPORT_SYMBOL vmlinux 0xddbcecef con_set_default_unimap +EXPORT_SYMBOL vmlinux 0xddc721fa in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xddcbad65 iput +EXPORT_SYMBOL vmlinux 0xddd0d97d i2c_detach_client +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde02ff22 dev_load +EXPORT_SYMBOL vmlinux 0xde1da073 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0xde1dd559 svc_proc_register +EXPORT_SYMBOL vmlinux 0xde6b365c ide_dma_off +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde7fdcab dev_mc_add +EXPORT_SYMBOL vmlinux 0xde830ead proto_register +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xdea58214 skb_store_bits +EXPORT_SYMBOL vmlinux 0xdecacb17 pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xdf04c12a vfs_unlink +EXPORT_SYMBOL vmlinux 0xdf1c9772 kernel_getsockname +EXPORT_SYMBOL vmlinux 0xdf25e9e4 bdi_register +EXPORT_SYMBOL vmlinux 0xdf3f846e iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf6c31d3 i2c_transfer +EXPORT_SYMBOL vmlinux 0xdf7366be journal_extend +EXPORT_SYMBOL vmlinux 0xdf8dbb52 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfa99c8e input_set_capability +EXPORT_SYMBOL vmlinux 0xdfac0d80 skb_free_datagram +EXPORT_SYMBOL vmlinux 0xdfcf2de3 kernel_read +EXPORT_SYMBOL vmlinux 0xdff57b57 uart_update_timeout +EXPORT_SYMBOL vmlinux 0xe065ccbc ide_raw_taskfile +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe07d5eda _test_and_clear_bit_be +EXPORT_SYMBOL vmlinux 0xe0878bfe __krealloc +EXPORT_SYMBOL vmlinux 0xe08cb4fa kobject_add +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0ddb0c8 __break_lease +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe1204956 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xe15e0863 simple_rmdir +EXPORT_SYMBOL vmlinux 0xe16af4cb km_policy_expired +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1ce3d32 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xe208deb0 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xe21258ef pci_enable_device_io +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe25c4cd0 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0xe29140cb mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0xe2ae3dd5 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2e1c732 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0xe2e73b94 notify_change +EXPORT_SYMBOL vmlinux 0xe2f6be27 inet6_release +EXPORT_SYMBOL vmlinux 0xe2f98472 fd_install +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe311cbc2 set_bdi_congested +EXPORT_SYMBOL vmlinux 0xe336831f blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0xe33b4f17 ip6_xmit +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe3699c79 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0xe36aaa59 pci_pme_active +EXPORT_SYMBOL vmlinux 0xe3b7b081 pci_pme_capable +EXPORT_SYMBOL vmlinux 0xe3fb9210 d_delete +EXPORT_SYMBOL vmlinux 0xe40707c9 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0xe4116e7b svc_exit_thread +EXPORT_SYMBOL vmlinux 0xe41e11de arp_create +EXPORT_SYMBOL vmlinux 0xe435bb4c __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0xe4403745 lock_may_write +EXPORT_SYMBOL vmlinux 0xe46130bf pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xe48d7df2 dev_get_by_index +EXPORT_SYMBOL vmlinux 0xe4a97c71 __down_write_trylock +EXPORT_SYMBOL vmlinux 0xe4c16604 nla_append +EXPORT_SYMBOL vmlinux 0xe4c80097 cacheid +EXPORT_SYMBOL vmlinux 0xe4f3f721 register_qdisc +EXPORT_SYMBOL vmlinux 0xe50d1971 ide_do_reset +EXPORT_SYMBOL vmlinux 0xe5117965 kernel_bind +EXPORT_SYMBOL vmlinux 0xe53af974 skb_append +EXPORT_SYMBOL vmlinux 0xe542da60 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0xe56d7a46 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe57c450c inet_stream_connect +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL vmlinux 0xe5a24ad7 sock_register +EXPORT_SYMBOL vmlinux 0xe5b8a5d6 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xe5bcf29a ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5d0e5a9 put_disk +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe6204da4 xdr_buf_read_netobj +EXPORT_SYMBOL vmlinux 0xe622a2cc xdr_init_decode +EXPORT_SYMBOL vmlinux 0xe62b1d84 generic_write_end +EXPORT_SYMBOL vmlinux 0xe65407fc cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe69e034b ll_rw_block +EXPORT_SYMBOL vmlinux 0xe6c3ebb0 __raw_writesw +EXPORT_SYMBOL vmlinux 0xe6c850cb empty_zero_page +EXPORT_SYMBOL vmlinux 0xe6ce5f61 touch_atime +EXPORT_SYMBOL vmlinux 0xe6dae6da sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0xe6e89e4b generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6f491b8 dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe7068235 may_umount +EXPORT_SYMBOL vmlinux 0xe707d823 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0xe70b203f inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xe7112df5 key_unlink +EXPORT_SYMBOL vmlinux 0xe721a144 lookup_one_len +EXPORT_SYMBOL vmlinux 0xe757b1ff misc_register +EXPORT_SYMBOL vmlinux 0xe76ae7db skb_truesize_bug +EXPORT_SYMBOL vmlinux 0xe7a2c2c1 neigh_event_ns +EXPORT_SYMBOL vmlinux 0xe7a3423c ide_dump_status +EXPORT_SYMBOL vmlinux 0xe7bd4765 kill_fasync +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe802540d register_sysrq_key +EXPORT_SYMBOL vmlinux 0xe80a37ed tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xe81f3af6 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0xe844cee7 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0xe890f5c1 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0xe8a14faf scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe903619a pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0xe9146118 rpc_mkpipe +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe91c656d poll_initwait +EXPORT_SYMBOL vmlinux 0xe92e6c33 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe9753463 skb_dma_map +EXPORT_SYMBOL vmlinux 0xe97f4ce5 qword_get +EXPORT_SYMBOL vmlinux 0xe9cfa52d bio_sector_offset +EXPORT_SYMBOL vmlinux 0xe9e5c283 kobject_init +EXPORT_SYMBOL vmlinux 0xe9f38c76 kmem_cache_size +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea55ee5a do_map_probe +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea81b315 remove_proc_entry +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xea89ab8c tty_check_change +EXPORT_SYMBOL vmlinux 0xeaa2f3ab arp_send +EXPORT_SYMBOL vmlinux 0xeadc20d2 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeb044a74 dentry_unhash +EXPORT_SYMBOL vmlinux 0xeb23c324 bio_pair_release +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb43628a tty_free_termios +EXPORT_SYMBOL vmlinux 0xeb439dae bdput +EXPORT_SYMBOL vmlinux 0xeb7a59cc filemap_flush +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xebaa266d skb_gso_segment +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebe49a32 inode_add_bytes +EXPORT_SYMBOL vmlinux 0xebe973ee key_revoke +EXPORT_SYMBOL vmlinux 0xebfdcbdf system_serial_high +EXPORT_SYMBOL vmlinux 0xec379e11 textsearch_prepare +EXPORT_SYMBOL vmlinux 0xec3c6f93 inet_sendmsg +EXPORT_SYMBOL vmlinux 0xec5ac21e seq_putc +EXPORT_SYMBOL vmlinux 0xec6d7398 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec8a7f34 mii_check_media +EXPORT_SYMBOL vmlinux 0xec97aa39 ide_wait_stat +EXPORT_SYMBOL vmlinux 0xec9f9a2c blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xeca43807 kobject_put +EXPORT_SYMBOL vmlinux 0xecc34c9a blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0xecc4f23e filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0xecfeb04a dev_set_mtu +EXPORT_SYMBOL vmlinux 0xed23759b scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xed4dbf49 _test_and_change_bit_be +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc4c316 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xedcf6be4 qword_add +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd1e017 _change_bit_be +EXPORT_SYMBOL vmlinux 0xedd9106d __ashrdi3 +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee50084e dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0xee5eda20 bio_kmalloc +EXPORT_SYMBOL vmlinux 0xee6fdf0b cpu_online_map +EXPORT_SYMBOL vmlinux 0xee7ca5e7 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0xee9564fe get_empty_filp +EXPORT_SYMBOL vmlinux 0xee9ae924 icmpv6_send +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xef1a1668 km_waitq +EXPORT_SYMBOL vmlinux 0xef1c781c vid_which_vrm +EXPORT_SYMBOL vmlinux 0xef4263bb netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xef466ef4 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xef8f4a1c dev_unicast_sync +EXPORT_SYMBOL vmlinux 0xef976cac ip6_frag_init +EXPORT_SYMBOL vmlinux 0xefaa9194 genl_sock +EXPORT_SYMBOL vmlinux 0xefef0fe8 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf0055493 start_tty +EXPORT_SYMBOL vmlinux 0xf01d79b1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0xf03853a8 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xf077fb0b inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xf07a9023 log_wait_commit +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf1176799 pci_find_bus +EXPORT_SYMBOL vmlinux 0xf12a2277 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0xf13dd070 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf16c2182 __blk_run_queue +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf17672a2 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0xf1dced4c ide_lock +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1fd4e7d __scsi_add_device +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf26d2dcd redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2d8143b inet6_getname +EXPORT_SYMBOL vmlinux 0xf2f7f01e tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0xf2fec27a proc_dostring +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf31e8685 tcp_proc_register +EXPORT_SYMBOL vmlinux 0xf32a5601 dst_alloc +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf33ace13 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf3760d1e filp_open +EXPORT_SYMBOL vmlinux 0xf38e9e65 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xf397b9aa __tasklet_schedule +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf39f5398 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3cc29d4 kernel_getpeername +EXPORT_SYMBOL vmlinux 0xf3dd6f5f skb_push +EXPORT_SYMBOL vmlinux 0xf3ec7357 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0xf41f64c8 xfrm_register_type +EXPORT_SYMBOL vmlinux 0xf45094fa nf_getsockopt +EXPORT_SYMBOL vmlinux 0xf476d6b6 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xf49838a9 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xf4b40b3b generic_read_dir +EXPORT_SYMBOL vmlinux 0xf4bebd9d inet6_register_protosw +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf50af2c9 d_prune_aliases +EXPORT_SYMBOL vmlinux 0xf516f8d6 pci_request_regions +EXPORT_SYMBOL vmlinux 0xf5186871 check_disk_size_change +EXPORT_SYMBOL vmlinux 0xf51c639f interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf564412a __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0xf57fa76e sock_no_mmap +EXPORT_SYMBOL vmlinux 0xf583b450 km_policy_notify +EXPORT_SYMBOL vmlinux 0xf5994490 generic_ro_fops +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5e1531e inode_change_ok +EXPORT_SYMBOL vmlinux 0xf5efd8a4 set_page_dirty +EXPORT_SYMBOL vmlinux 0xf5fee204 thaw_bdev +EXPORT_SYMBOL vmlinux 0xf6068d0b ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xf6211b74 setup_arg_pages +EXPORT_SYMBOL vmlinux 0xf62d0ba1 dev_unicast_add +EXPORT_SYMBOL vmlinux 0xf68260e0 xrlim_allow +EXPORT_SYMBOL vmlinux 0xf6933c48 lockd_up +EXPORT_SYMBOL vmlinux 0xf6b49477 dcache_dir_open +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6d970c9 skb_copy +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf6eedc0c pci_dev_driver +EXPORT_SYMBOL vmlinux 0xf6ef5cce _test_and_set_bit_be +EXPORT_SYMBOL vmlinux 0xf6f87a7a eth_type_trans +EXPORT_SYMBOL vmlinux 0xf701bce4 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xf70f02c3 skb_copy_bits +EXPORT_SYMBOL vmlinux 0xf70fd874 sock_wfree +EXPORT_SYMBOL vmlinux 0xf73033e6 seq_release +EXPORT_SYMBOL vmlinux 0xf7384f52 downgrade_write +EXPORT_SYMBOL vmlinux 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL vmlinux 0xf7554aee __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf7746391 scsi_put_command +EXPORT_SYMBOL vmlinux 0xf77fbb46 idr_remove_all +EXPORT_SYMBOL vmlinux 0xf7802486 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7c78d1a sockfd_lookup +EXPORT_SYMBOL vmlinux 0xf7edf218 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xf804a7b1 udplite_prot +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf832aa66 elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf8934fbc register_exec_domain +EXPORT_SYMBOL vmlinux 0xf8d2d41c bdev_read_only +EXPORT_SYMBOL vmlinux 0xf8eadacb sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0xf8f0dcb7 journal_check_available_features +EXPORT_SYMBOL vmlinux 0xf8fbb4f0 __bad_xchg +EXPORT_SYMBOL vmlinux 0xf913bfcc blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0xf914b945 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0xf9175868 bd_set_size +EXPORT_SYMBOL vmlinux 0xf91ec75a journal_destroy +EXPORT_SYMBOL vmlinux 0xf950587a pci_get_slot +EXPORT_SYMBOL vmlinux 0xf9823696 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9a686ae eth_header +EXPORT_SYMBOL vmlinux 0xf9b28bac interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xf9f9b746 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xfa372f35 input_register_handler +EXPORT_SYMBOL vmlinux 0xfa4cdd11 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xfa5e0e5d generic_file_llseek +EXPORT_SYMBOL vmlinux 0xfaa67fc9 d_alloc_root +EXPORT_SYMBOL vmlinux 0xfab3bb8d deactivate_super +EXPORT_SYMBOL vmlinux 0xfac68eba arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0xfac776ba sk_stream_write_space +EXPORT_SYMBOL vmlinux 0xfad9efdd tcp_splice_read +EXPORT_SYMBOL vmlinux 0xfae7afc5 vfs_follow_link +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb1e9dde nla_reserve +EXPORT_SYMBOL vmlinux 0xfb326a5d down +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb72f638 xscale_flush_user_cache_all +EXPORT_SYMBOL vmlinux 0xfb7d9c45 __udivsi3 +EXPORT_SYMBOL vmlinux 0xfb952f70 flush_signals +EXPORT_SYMBOL vmlinux 0xfbc74f64 __copy_from_user +EXPORT_SYMBOL vmlinux 0xfbf6b99c find_inode_number +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc16050d devm_request_irq +EXPORT_SYMBOL vmlinux 0xfc533f85 schedule_work_on +EXPORT_SYMBOL vmlinux 0xfc723a5b drive_is_ready +EXPORT_SYMBOL vmlinux 0xfc88c7ea freeze_bdev +EXPORT_SYMBOL vmlinux 0xfc8b184c d_genocide +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfd10422c read_cache_pages +EXPORT_SYMBOL vmlinux 0xfd11194f get_sb_single +EXPORT_SYMBOL vmlinux 0xfd5a59da pneigh_enqueue +EXPORT_SYMBOL vmlinux 0xfd8c7eba dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xfd8dba4c add_wait_queue +EXPORT_SYMBOL vmlinux 0xfd8f806c sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb12739 i2c_del_driver +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe16775f idr_destroy +EXPORT_SYMBOL vmlinux 0xfe271510 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xfe54edde alloc_disk_node +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe8a36e0 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0xfea611ba simple_lookup +EXPORT_SYMBOL vmlinux 0xfec15e86 ip_fragment +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xfefd202a scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0xff119ae3 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0xff167c01 dev_open +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff22013c km_state_notify +EXPORT_SYMBOL vmlinux 0xff5b28c5 inet6_ioctl +EXPORT_SYMBOL vmlinux 0xff67b37f __lshrdi3 +EXPORT_SYMBOL vmlinux 0xffb7602d ide_end_drive_cmd +EXPORT_SYMBOL vmlinux 0xffbef221 ide_proc_register_driver +EXPORT_SYMBOL vmlinux 0xffbf9567 scsi_add_host +EXPORT_SYMBOL vmlinux 0xffc3aaed init_file +EXPORT_SYMBOL vmlinux 0xffcc4b2f pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffd9f549 posix_test_lock +EXPORT_SYMBOL vmlinux 0xffe232c9 key_link +EXPORT_SYMBOL_GPL crypto/aead 0x134d398c crypto_aead_type +EXPORT_SYMBOL_GPL crypto/aead 0x295f78d4 aead_geniv_alloc +EXPORT_SYMBOL_GPL crypto/aead 0x38172427 crypto_alloc_aead +EXPORT_SYMBOL_GPL crypto/aead 0x49cf9277 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL crypto/aead 0x6bf8ae1e crypto_grab_aead +EXPORT_SYMBOL_GPL crypto/aead 0x8690fa38 aead_geniv_free +EXPORT_SYMBOL_GPL crypto/aead 0xb13e1f44 crypto_nivaead_type +EXPORT_SYMBOL_GPL crypto/aead 0xdbae8630 aead_geniv_exit +EXPORT_SYMBOL_GPL crypto/aead 0xf5c891a3 aead_geniv_init +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0xb24233b8 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0xa3ffeef4 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x53f55f7d async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x54007a35 async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x546831e1 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x7384a7a4 async_xor +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x8608d5a6 async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x1fc14ae6 crypto_register_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x41cc2e08 crypto_lookup_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x58157640 scatterwalk_map +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5b19cccf crypto_register_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5d786715 crypto_init_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x5f1cced5 scatterwalk_start +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x66f27e95 crypto_unregister_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x83553786 scatterwalk_copychunks +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x891942cb crypto_enqueue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8c12540f crypto_register_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x8c67f47f crypto_drop_spawn +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x97b9c5de crypto_spawn_tfm +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0x9b683b45 scatterwalk_done +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xa22aff3b crypto_attr_alg +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc6d08cb0 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc72d2dd5 crypto_alloc_instance +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xc92fe393 crypto_dequeue_request +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xe402d2fc crypto_unregister_template +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xf807fd65 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL crypto/crypto_algapi 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x1026f702 blkcipher_walk_virt +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x2d423b40 skcipher_geniv_free +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x2ddce24d crypto_ablkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x4f2301fd skcipher_geniv_init +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x5434c2df blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x604bd5c3 crypto_grab_skcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x70a204eb blkcipher_walk_phys +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0x8e68b38d blkcipher_walk_done +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xa615e25c crypto_blkcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xb538004f skcipher_geniv_exit +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xd4d6593d crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xe21af41e crypto_givcipher_type +EXPORT_SYMBOL_GPL crypto/crypto_blkcipher 0xe39059af skcipher_geniv_alloc +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x73ae6341 crypto_ahash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0x881b4fe7 crypto_hash_type +EXPORT_SYMBOL_GPL crypto/crypto_hash 0xde26369f crypto_hash_walk_first +EXPORT_SYMBOL_GPL crypto/crypto_hash 0xf7d97b42 crypto_hash_walk_done +EXPORT_SYMBOL_GPL crypto/cryptomgr 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/rng 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL crypto/rng 0xc29d2082 crypto_rng_type +EXPORT_SYMBOL_GPL crypto/rng 0xef34eaf2 crypto_default_rng +EXPORT_SYMBOL_GPL crypto/twofish_common 0x5e363c34 twofish_setkey +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x8b7a965f dm_disk +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0x8e22b095 dm_noflush_suspending +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xb19b72ce dm_set_device_limits +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xdd58a42f dm_put +EXPORT_SYMBOL_GPL drivers/md/dm-mod 0xe5a933be dm_device_name +EXPORT_SYMBOL_GPL drivers/md/md-mod 0x31de72d8 sync_page_io +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xe0686705 md_do_sync +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xe37a3a37 md_new_event +EXPORT_SYMBOL_GPL drivers/md/md-mod 0xee06d06c md_allow_write +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x3219d36b nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x3629ac61 nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xb9f53214 nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xcce9c788 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xf596408a nand_release +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x180f05ed wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x23bc79ed wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x2c70a1e4 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x87dca5e9 wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x96500272 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x9a026eee wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x9fa77177 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb67400ee wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xc70fcc0e wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xc7c654e5 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcaa56e6e __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcd564e56 wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd1cae2f2 wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd27ae2c5 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xdf6e4f08 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xe0348736 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xec47e2bf wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf45ae444 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0145ac82 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x08dba25a uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1807806b uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1a5142da uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1fa84fcf uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x248ab176 uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2b400c91 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x320be8c4 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d7b908f uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x52ee3b74 uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x57c9f9b2 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x581d46cc uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5c6b673e dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5efa25f8 uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6ab479c7 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x735a9bda uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x79b66e96 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x812f098f uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88f45cfa uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8f6505bf uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x93e315ea uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9d3071af uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa409012f uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa9b88256 uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb0dad961 uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbf42b1d1 uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc06b761d uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc52608cc uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd4867637 uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd49ddf0f uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd6b226ec uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd95e4244 uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xddf030cb uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdf74c80d uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf56e0c5d uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfb0f6b57 uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfb8392bf uwb_rsv_create +EXPORT_SYMBOL_GPL net/802/stp 0x00df6670 stp_proto_register +EXPORT_SYMBOL_GPL net/802/stp 0xf6c855c0 stp_proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x24432cf9 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x26be20c8 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x2b9d678e xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x3699798e xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x3d60eb96 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5cf745e2 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x67a27503 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9f24ae38 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xa9ff740f xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xdaee492b xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0x01ca27cf xt_rateest_lookup +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xe62aee08 xt_rateest_put +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x007c04b4 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x00c17892 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x014d95e3 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x01565c3a rpcauth_create +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01d1d15e kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL vmlinux 0x026478fc usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x02bb0d5b hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x02ef8130 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03a54484 default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x040b4094 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x042d76a8 rpc_print_iostats +EXPORT_SYMBOL_GPL vmlinux 0x043ce381 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04c799b7 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x04e2d0e3 scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0x050ee178 ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05f6b7a5 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x05fe51bd led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x06eb3472 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x06fc0ecc pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x0742f55f ide_port_unregister_devices +EXPORT_SYMBOL_GPL vmlinux 0x079fd803 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x08466bd4 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x086ab268 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x087320fd zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x08c88b8b led_classdev_resume +EXPORT_SYMBOL_GPL vmlinux 0x08fd6b2b fat_fill_super +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x0968056c disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x099856bf tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x09d3df40 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x0a352712 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x0b04412e device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x0b1193a9 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x0b27d22e regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x0b45499c ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x0b660015 usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0x0b6d741f usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0x0bd31d4f __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x0c1264b2 hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c3780e9 rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x0cc02e45 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0cf635d5 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0x0e199cf6 devres_add +EXPORT_SYMBOL_GPL vmlinux 0x0e4766fb sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x0e502923 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x0eaa5a6e usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0x0ec40487 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x0ed74050 xprt_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0x0f6fb65e sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x0f710437 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x0f7a440b xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL vmlinux 0x0f7f68ea led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x1000537e fat_fs_panic +EXPORT_SYMBOL_GPL vmlinux 0x100a2608 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x100ad733 rpc_alloc_iostats +EXPORT_SYMBOL_GPL vmlinux 0x108de8d3 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x10a0c540 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x10a9f948 put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x10ff57ee device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x119e26a9 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x126c7ee1 get_device +EXPORT_SYMBOL_GPL vmlinux 0x1288c7f7 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x1291eb14 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x12ee8866 usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x135af603 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x14238735 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x1457d8f7 ide_allocate_dma_engine +EXPORT_SYMBOL_GPL vmlinux 0x14e2ecec __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x14ed9ef0 unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x153657b2 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x156f1548 ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x159f1ace inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x16a43ff0 class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x170c5da0 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0x172c8a34 rpc_delay +EXPORT_SYMBOL_GPL vmlinux 0x175ac30d rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0x176dc9c4 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x1798d46c regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x17b8d73e sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL vmlinux 0x188fc04e class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x18f2f477 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x191d5acf usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x191eec86 ide_pci_check_simplex +EXPORT_SYMBOL_GPL vmlinux 0x191fb096 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x196f3e8f kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x1982aedb kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19abe7ec register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x19c205fa pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0x19e83ad9 pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x19fd329e nlmclnt_proc +EXPORT_SYMBOL_GPL vmlinux 0x1a018c3e __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1a1475ad get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x1a539893 scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL vmlinux 0x1a9b415f platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x1aa8f04f pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0x1abab166 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x1ac0e5e9 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x1b0df92f ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x1b3d945c __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL vmlinux 0x1b4122f8 sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x1b697e6e platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1bbb301c vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x1bcb10d1 xprt_lookup_rqst +EXPORT_SYMBOL_GPL vmlinux 0x1c18c623 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x1c1ef97e rpc_force_rebind +EXPORT_SYMBOL_GPL vmlinux 0x1c389990 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1d40bdc1 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x1d6d29d9 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x1d7ffdc3 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x1d9fed7b ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x1da73e15 ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0x1ddd1d9b ide_register_region +EXPORT_SYMBOL_GPL vmlinux 0x1de59a9c tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x1e047a7a regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x1e30b319 rpc_restart_call +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e7ca372 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x1e800eaf ide_pci_init_two +EXPORT_SYMBOL_GPL vmlinux 0x1e97ee01 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ee70cf0 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x1efad85b init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x1f304ef6 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x1f6e18f1 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x1f8ddcca ide_dma_lost_irq +EXPORT_SYMBOL_GPL vmlinux 0x1fb5db9b usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fe667f1 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x1ffc01fb pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x1ffc1ba1 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20596565 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0x20a80079 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x21157e52 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x21d57d87 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x226e27b8 driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x229cc8c8 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x22e2c20b atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x235ad180 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x23869dc7 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x2432698a platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x2468a84d rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x24c4a0f5 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x24cda041 ide_vlb_clk +EXPORT_SYMBOL_GPL vmlinux 0x24e29a9e rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x250eb841 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x255e9ebf rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x2563dce5 pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x256fdbec scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x25c39fa8 device_register +EXPORT_SYMBOL_GPL vmlinux 0x25c7ae9f d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x25d73e72 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x25d905fb ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x25eaa47e xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x25f04975 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x25f4b472 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x26208b92 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x2656727f bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x266e1c9f tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x2675aa0a ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x2683a320 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x271682fe ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x2754ed21 ide_find_dma_mode +EXPORT_SYMBOL_GPL vmlinux 0x27768f88 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x277a8d78 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x279487cb ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x27a33f14 usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x27a817c5 rpc_peeraddr +EXPORT_SYMBOL_GPL vmlinux 0x27ae7e1e rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL vmlinux 0x280a4348 svc_find_xprt +EXPORT_SYMBOL_GPL vmlinux 0x2877ca37 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x28b2cc80 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28f0fd4d pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0x2915b8d3 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0x294cb0ae tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x29b6140d debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x29c4e3ce rpc_run_task +EXPORT_SYMBOL_GPL vmlinux 0x29e998ab ide_build_sglist +EXPORT_SYMBOL_GPL vmlinux 0x2a2d93b7 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x2a6f2b57 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL vmlinux 0x2b56bf4a inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x2b607170 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x2b7872a8 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x2b83d2f5 rpc_killall_tasks +EXPORT_SYMBOL_GPL vmlinux 0x2b85f897 ide_no_data_taskfile +EXPORT_SYMBOL_GPL vmlinux 0x2b926605 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bb7fb14 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x2bce3642 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c1a3c5a drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x2c82a6bd usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x2cb4fea8 tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x2cfa3e17 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x2d3ec322 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x2d6bfbd0 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x2d841627 ide_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x2db4d7ed inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x2dd6b797 sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x2e01cb65 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x2e3d08b9 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x2e928e18 get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0x2e9bde5f platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x2ee776e1 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x2ee92b4b usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x2efbda45 __class_create +EXPORT_SYMBOL_GPL vmlinux 0x2f60a04a svc_xprt_init +EXPORT_SYMBOL_GPL vmlinux 0x2fb3527f ide_read_status +EXPORT_SYMBOL_GPL vmlinux 0x2fd004fd blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x300a4ff2 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x3050c090 ide_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x3075bd4a flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x308ca230 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x31471faf usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL vmlinux 0x31c7b774 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x32070c28 exportfs_encode_fh +EXPORT_SYMBOL_GPL vmlinux 0x321ecf2b usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x3239dfa4 rpc_wake_up_status +EXPORT_SYMBOL_GPL vmlinux 0x3293c54c svc_xprt_put +EXPORT_SYMBOL_GPL vmlinux 0x32c91f8b rpc_call_null +EXPORT_SYMBOL_GPL vmlinux 0x32f88fa7 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x331e0807 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x336f172d elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x339762e9 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x33df675d usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x34442f5f tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x34de0d47 fat_alloc_new_dir +EXPORT_SYMBOL_GPL vmlinux 0x351b8760 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x35665fb3 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x35730450 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x35cf63ff rpc_init_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35ec7fcb klist_next +EXPORT_SYMBOL_GPL vmlinux 0x35ff8f04 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x36213b34 svc_reg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x36458fa8 rpcauth_register +EXPORT_SYMBOL_GPL vmlinux 0x3698e102 ide_pci_setup_ports +EXPORT_SYMBOL_GPL vmlinux 0x36aff237 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x3743cc56 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x37601ace xprt_register_transport +EXPORT_SYMBOL_GPL vmlinux 0x37707711 ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x37fddd3a raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x3864809c ide_output_data +EXPORT_SYMBOL_GPL vmlinux 0x386b1cda page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0x38f887d7 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x39819646 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x399bf6c2 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x3a2ef25e queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x3a7b18b9 ide_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3aab4c98 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x3adabeb9 rpc_peeraddr2str +EXPORT_SYMBOL_GPL vmlinux 0x3ae2bdd8 exportfs_decode_fh +EXPORT_SYMBOL_GPL vmlinux 0x3ae68b90 led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x3b706840 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x3bb398e4 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x3bc33f65 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3c02e767 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x3c4fd99c tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x3c5f3c9b generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cfabb38 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x3db1eed3 ide_read_error +EXPORT_SYMBOL_GPL vmlinux 0x3dc281b6 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3df1dd9c regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x3e25376f fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0x3e77d2dd rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL vmlinux 0x3e8460f0 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x3ec2c9f8 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x3ece7454 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x3ef3657c rpc_malloc +EXPORT_SYMBOL_GPL vmlinux 0x3ef54874 ide_get_lba_addr +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f040207 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL vmlinux 0x3f0d825e inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0x3f17ba49 rpcauth_init_cred +EXPORT_SYMBOL_GPL vmlinux 0x3f2b1b4e map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x3f2c0ff3 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x3f3a2e47 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x3f470e46 hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3fce686d usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x40a62b43 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40c91169 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x41822333 register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x41abb7c4 svc_xprt_received +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x42a54506 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x42c16b7a ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x431b2632 ide_end_dequeued_request +EXPORT_SYMBOL_GPL vmlinux 0x4324430a inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x43d645f9 xprt_complete_rqst +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x43f6dd52 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x44095161 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x4480b51c sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x44a70e3e regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x44a7f37e svc_xprt_names +EXPORT_SYMBOL_GPL vmlinux 0x44bd446b ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x44d30725 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0x44e131b4 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x44f04b4f led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x4508f537 user_read +EXPORT_SYMBOL_GPL vmlinux 0x454a4fdf sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x45508630 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x45657b78 rpc_wake_up +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x4622e688 fat_detach +EXPORT_SYMBOL_GPL vmlinux 0x463b0db8 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x4651f6dd proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x46b2a30d proc_ide_read_capacity +EXPORT_SYMBOL_GPL vmlinux 0x46c72860 usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x4722089d usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x4734e51f usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x473ae56c tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x474c4c87 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x47a228db __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x4841be4e rpc_put_task +EXPORT_SYMBOL_GPL vmlinux 0x48bd1af9 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x48bfb7db simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x49e10488 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x49e4cca9 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4a94aadd find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x4aa76093 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0x4acf4f4d ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x4ae58488 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x4af14850 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x4b7859f0 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x4b963091 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x4b96ba79 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0x4bc2bee6 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x4bd96151 device_del +EXPORT_SYMBOL_GPL vmlinux 0x4c145abc ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x4c594abf bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4d09dba0 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x4d58b9c0 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x4d7608d7 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x4d906269 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x4daa2b19 ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x4db4d0e5 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x4dd3a01c fat_time_unix2fat +EXPORT_SYMBOL_GPL vmlinux 0x4e1d88d7 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x4e62da42 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x4edd8848 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x4f0eab93 ide_init_disk +EXPORT_SYMBOL_GPL vmlinux 0x4f43e556 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x4fdda378 usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x500abd32 ide_set_dma_mode +EXPORT_SYMBOL_GPL vmlinux 0x504983a9 ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x506513fb svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL vmlinux 0x508f1e10 regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x50a3fda8 user_describe +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x511f6e9c led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x515a86c6 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x51a2fa0a rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x51a38e3f device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x52154b5c ide_host_free +EXPORT_SYMBOL_GPL vmlinux 0x52482477 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x528c53d2 rpc_call_async +EXPORT_SYMBOL_GPL vmlinux 0x52b5ba9b elv_register +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x531c0c31 input_class +EXPORT_SYMBOL_GPL vmlinux 0x532219c2 ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53f26064 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x540dc0d6 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL vmlinux 0x5427438f blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x543ecb93 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x54509482 fat_scan +EXPORT_SYMBOL_GPL vmlinux 0x54686ee0 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x547da677 ide_undecoded_slave +EXPORT_SYMBOL_GPL vmlinux 0x547ef282 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0x5491445d xprt_reserve_xprt +EXPORT_SYMBOL_GPL vmlinux 0x54c4db60 usb_string +EXPORT_SYMBOL_GPL vmlinux 0x553fab28 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0x5542b913 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x55599485 ide_pktcmd_tf_load +EXPORT_SYMBOL_GPL vmlinux 0x55b1e7e1 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x55b323d6 rpc_exit_task +EXPORT_SYMBOL_GPL vmlinux 0x55e089af device_move +EXPORT_SYMBOL_GPL vmlinux 0x55ed6c56 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x563da61b blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x566b9ce5 fat_add_entries +EXPORT_SYMBOL_GPL vmlinux 0x56ba5744 svc_close_xprt +EXPORT_SYMBOL_GPL vmlinux 0x56d42418 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x56ec4b0e ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x57021bc0 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0x574ec7a4 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x579bbfd6 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x5809b1fc ide_dma_host_set +EXPORT_SYMBOL_GPL vmlinux 0x584e8ef9 led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x58929606 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x58be11a7 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x58e2c245 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x59000082 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x592d2bc6 rpc_wake_up_next +EXPORT_SYMBOL_GPL vmlinux 0x596c9844 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59a196a4 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x59ca3224 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x59e3e4c5 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x5a041397 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5a56a58e sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x5a5c9c73 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x5a5ef77e debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0x5a6043ac fat_attach +EXPORT_SYMBOL_GPL vmlinux 0x5a757542 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5ab0175b ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x5af823b6 regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5b0bca3e sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5b7dae12 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x5b83e594 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5beb87a4 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c25d48c xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL vmlinux 0x5c52c157 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x5c58ffec klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5c59f8d8 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0x5c766514 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x5c9e6ade ide_host_add +EXPORT_SYMBOL_GPL vmlinux 0x5cc44f7e klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x5cf882d0 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d6fa960 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d7e2f70 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x5db72fda ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x5dbae6d4 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x5dcee695 ide_setting_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e1aa9b4 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x5e7aa752 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x5eb987a5 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x5efa3d4b pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x5ff6e46d transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60bbe793 usbhid_submit_report +EXPORT_SYMBOL_GPL vmlinux 0x60d5f60c disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x60de4927 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0x60f6f875 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x61275f8b ide_pad_transfer +EXPORT_SYMBOL_GPL vmlinux 0x616b79ca pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0x618c1bc4 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x621d38c9 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x622b3e2c srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x622e38ed inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x6259b461 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x62a93185 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x63401c22 ide_set_irq +EXPORT_SYMBOL_GPL vmlinux 0x635ff52a __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x63ecab77 usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x63f39f75 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x641438a2 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x64304612 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0x6430ee57 tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x6479242b ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x65765796 usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0x65870d57 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65dbcacd fat_getattr +EXPORT_SYMBOL_GPL vmlinux 0x65df7572 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x663f079f sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x66412181 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x664af840 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x6714d17a pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x677a2c3d ide_device_put +EXPORT_SYMBOL_GPL vmlinux 0x67e1d9e5 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x67e6e759 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0x686a9519 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6936847b ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x6998b549 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x69bc3480 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x69dc83f9 register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x69f3d143 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x6a4ec44c ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x6a687951 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x6a6d4705 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x6a755736 regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x6ad58249 rpcauth_init_credcache +EXPORT_SYMBOL_GPL vmlinux 0x6adccc12 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x6ae8430f rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x6b172d3e rpc_shutdown_client +EXPORT_SYMBOL_GPL vmlinux 0x6b3454b6 devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x6bcb7553 fat_sync_inode +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL vmlinux 0x6c8c6079 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x6c9289d0 inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x6c99ed25 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0x6cc97465 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0x6cfd0ad9 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x6d0002fb rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6dbf36fd blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x6dc4062b usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x6dc72381 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL vmlinux 0x6e29599a usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x6e401a07 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x6e48a8ca xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x6eba016a register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x6ebe7a11 svc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0x6ede8e19 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x6f031319 do_rw_taskfile +EXPORT_SYMBOL_GPL vmlinux 0x6f63d070 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6fcb49eb ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x707cd47a get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70b491f3 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x70c9ac3e ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x70e28613 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x710ab0bd crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x71196147 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x7156d44a rpc_clone_client +EXPORT_SYMBOL_GPL vmlinux 0x71f9246a leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x72708473 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73c4bbb7 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x74419c98 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x7486289a init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x74e60b43 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x74fff348 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x7555ac72 ide_devset_execute +EXPORT_SYMBOL_GPL vmlinux 0x755e634b ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x757c3db1 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x75ce3e1f nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x76709db6 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x76754e26 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x76a3e81e pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x76ce525b tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x77ee9295 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x78022097 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x781143b7 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x783b8600 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x783cd271 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x78af7c8f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x78bd9099 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x7948d109 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x79b14a38 mtd_table +EXPORT_SYMBOL_GPL vmlinux 0x79b564d3 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x79c33f87 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x79ca9d26 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x79d2f8a1 usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x7a1082b3 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0x7a3d7ee1 pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x7a4104d0 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x7ab5a30b d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x7afe2e8f debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x7b0df3c4 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x7b3aeb65 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x7b63a0f1 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x7bab3167 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x7bcbac12 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x7be8b720 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x7c326cb7 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0x7c666344 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x7d0c68bf fat_search_long +EXPORT_SYMBOL_GPL vmlinux 0x7d1ce7b8 svc_print_addr +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e2d29ec ide_pci_clk +EXPORT_SYMBOL_GPL vmlinux 0x7e508339 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7ed21f89 put_device +EXPORT_SYMBOL_GPL vmlinux 0x7f15a695 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7f31fa36 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7fa6e5e4 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x7fa70292 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x7fe5acf4 rpc_create +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x7ff25aaf usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0x8022ff45 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x8095ef1b unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x818c935d skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x81ffaaf0 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x820a82ae disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x82152f45 ide_host_remove +EXPORT_SYMBOL_GPL vmlinux 0x8218adf5 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x8244d998 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x827e44de user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x83444780 ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x8358d716 ide_device_get +EXPORT_SYMBOL_GPL vmlinux 0x836d2cc9 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x836fafa1 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0x83880f91 rpc_sleep_on +EXPORT_SYMBOL_GPL vmlinux 0x83ca70bb rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL vmlinux 0x8412e3c5 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x8477e7cb ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x8486de36 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x848a85b2 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x84aba91d inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x8561cbe9 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x8620ef93 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x863b5621 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x866ecbdf sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x867fc984 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86bb548e pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x86e48198 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x8713b469 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL vmlinux 0x87302a1b tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x8767c6ed devres_find +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87ab269f class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x87c7a32c rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x8863ed00 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x888cce9d sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x88aff77e crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x890e58d0 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x894b9693 __ide_pci_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x897531e2 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x89923c27 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x899d9dd1 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x89b62c80 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0x89ce80c7 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x8a0fa885 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x8a2f55d8 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x8a5b213c kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x8a7f0253 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ad7cc6f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x8b132fb1 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x8b5b425d platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8bb1b199 ide_host_register +EXPORT_SYMBOL_GPL vmlinux 0x8be80c3d cfi_qry_present +EXPORT_SYMBOL_GPL vmlinux 0x8c02b193 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x8c050223 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x8c0d2e86 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x8c272897 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x8c374e7c pci_intx +EXPORT_SYMBOL_GPL vmlinux 0x8c8fc6a2 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x8c99cc7c ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x8ca8eeed ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x8d2831ad usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x8d34f678 rpc_lookup_cred +EXPORT_SYMBOL_GPL vmlinux 0x8d807191 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0x8e2de68e device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x8e9c2cca sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x8eba1d73 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x8f0ac5dc tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x8f0f0c3f crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x8f2dd0fb anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x8f6597e2 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x901432d0 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x9081eced hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x9086d9f2 inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90cb811f sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x919a65b4 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x91f2d20e usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92c9a528 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x92f2221f vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x92f98d62 device_rename +EXPORT_SYMBOL_GPL vmlinux 0x9378c360 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0x93bf3dd3 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93eac5e5 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x94355a72 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x9455796f page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x949d4c4d devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94ce1bd2 sff_dma_ops +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94e8bffa tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x954398ea regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x9544d247 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x957efc9b rpc_call_sync +EXPORT_SYMBOL_GPL vmlinux 0x9597d763 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x95a695c0 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x95ceda1e pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0x96266883 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL vmlinux 0x96bc64e1 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x97225005 xprt_write_space +EXPORT_SYMBOL_GPL vmlinux 0x97427128 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x977e9e02 usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x9784e6b4 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x97e98370 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x97eeb2f6 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x98196f5b blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x98379e41 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x9871f8fb i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x9877ffb1 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x98ae2337 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x98d31693 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x98fea21c fat_flush_inodes +EXPORT_SYMBOL_GPL vmlinux 0x9917f8cd driver_find +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x99483001 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x994f3b7b bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x999eec46 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x99c32b6e shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x99dd6c2e hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x99ec84a2 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x9a17375d apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x9a32fe7a inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a5504b3 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0x9a8a218f fat_setattr +EXPORT_SYMBOL_GPL vmlinux 0x9ac55f68 rpc_bind_new_program +EXPORT_SYMBOL_GPL vmlinux 0x9ac6bd99 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x9ae920c9 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x9b36d877 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x9b9fb999 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bb00deb rpc_setbufsize +EXPORT_SYMBOL_GPL vmlinux 0x9bf270cb regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x9bf3ab2e tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x9bf9c61f usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x9c08fbe0 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x9c94b5d5 __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cd93b55 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x9ce5f98e ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x9d05ffbd crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x9d1ef5bf nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x9ddd917f usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x9e20ad1a skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x9e314b56 usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x9e4b1144 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x9e53e138 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa057eed5 crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0xa0a3d6a7 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xa1563f84 svc_xprt_enqueue +EXPORT_SYMBOL_GPL vmlinux 0xa2464faf ide_release_dma_engine +EXPORT_SYMBOL_GPL vmlinux 0xa2950e8b xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0xa29a1214 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2a0308a find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xa2d4448d ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0xa314d737 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xa3218de2 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xa34b4765 del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xa357d56e ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xa372720d rpcauth_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa3d37045 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa427a0f9 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0xa45a9bb8 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0xa46f5dea usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xa4e7243b svc_addsock +EXPORT_SYMBOL_GPL vmlinux 0xa4f09479 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0xa50bb765 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xa524d7f7 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xa52fd0ef led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0xa531f19b pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0xa54ba443 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa61c99b5 ide_dma_test_irq +EXPORT_SYMBOL_GPL vmlinux 0xa62effa7 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0xa64d5023 rpc_call_start +EXPORT_SYMBOL_GPL vmlinux 0xa6923523 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xa6a1f45b fat_build_inode +EXPORT_SYMBOL_GPL vmlinux 0xa6dd3751 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0xa78a6d76 device_add +EXPORT_SYMBOL_GPL vmlinux 0xa869ee72 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0xa86e7559 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xa8c0d328 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0xa908187a usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0xa97471a8 xprt_release_xprt +EXPORT_SYMBOL_GPL vmlinux 0xa9910485 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xaa13c5fd unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0xaa15dd05 transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0xaa27dd00 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa33d0fe driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0xaa7bbbed user_destroy +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaacfcb82 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0xab078e8c ide_pci_set_master +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xacb9bc05 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0xacbe74c3 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xacf74a07 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0xad022b86 usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0xad200d95 copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xada8bbaa get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0xadb7f53e transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0xadbb2197 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0xade5666a sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xadfc8831 ide_get_best_pio_mode +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xaea931d9 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0xaef0d94d device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0xaf153c56 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaf3aa28e tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL vmlinux 0xafe0a686 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0xb0283162 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0xb04d0b3b debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0xb05fdf80 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xb0a6f924 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xb1722044 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0xb1993e13 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb21368d6 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0xb25d21b2 hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0xb2b85d3b tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xb2d5a022 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb2f24f74 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xb2f2c40f usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xb34e7ea7 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL vmlinux 0xb38a8391 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xb3a1a61b sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb3aa3e06 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb3e91200 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0xb4182ad3 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0xb449ed11 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0xb4a4b9fb blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb4b035fc mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb541bac0 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xb558b04d xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xb5ace53d input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xb5c719c5 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0xb6386adf blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6d9d649 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xb6f355a7 svc_create_xprt +EXPORT_SYMBOL_GPL vmlinux 0xb7b9b631 ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0xb7df1028 led_classdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb7e92537 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xb82a9b90 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0xb865db25 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb8664a67 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xb8759c2c srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xb8fee532 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0xb960cb11 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0xb96c069b rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb9b8a0be ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0xb9d4ff71 usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xb9fa5207 unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xba0d24a0 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xba5f1e42 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL vmlinux 0xbac3dd41 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0xbade96e1 ide_wait_not_busy +EXPORT_SYMBOL_GPL vmlinux 0xbaf09ec0 klist_del +EXPORT_SYMBOL_GPL vmlinux 0xbb082fa3 user_update +EXPORT_SYMBOL_GPL vmlinux 0xbb248c8a get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xbbafe4bd ide_read_sff_dma_status +EXPORT_SYMBOL_GPL vmlinux 0xbc1d2f7c nlmclnt_init +EXPORT_SYMBOL_GPL vmlinux 0xbc4d7783 deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0xbc6e651e mmput +EXPORT_SYMBOL_GPL vmlinux 0xbc934614 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0xbd298c70 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0xbd2f3ba4 k_handler +EXPORT_SYMBOL_GPL vmlinux 0xbd3b9eb2 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbe082a49 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe53d0e0 cfi_qry_mode_on +EXPORT_SYMBOL_GPL vmlinux 0xbe5bab89 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0xbe6c6c57 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0xbe6cadc3 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0xbeea7a2b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbf0526d7 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xbf5fcd46 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xbf60af81 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0xbf645d1d transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xbf757c3e ide_dma_start +EXPORT_SYMBOL_GPL vmlinux 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL vmlinux 0xbfe7385b usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xbfe78224 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0xc0258eb4 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xc0342eb3 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xc03e6266 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0xc05b8f24 fat_free_clusters +EXPORT_SYMBOL_GPL vmlinux 0xc0b66c80 usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0xc11681c4 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL vmlinux 0xc12d6cf4 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc18a3e83 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0xc2127c5d ide_unregister_region +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc2a6568f xprt_release_rqst_cong +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc3b8d04c ide_read_altstatus +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc445c040 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0xc47a9945 ide_dma_exec_cmd +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc49cd176 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc554cbe9 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0xc5c53bff rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0xc5d02814 devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc5e3e7e5 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0xc5e9ef03 get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xc617a607 hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xc65c549f ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc68bb808 xprt_disconnect_done +EXPORT_SYMBOL_GPL vmlinux 0xc6942774 nlmclnt_done +EXPORT_SYMBOL_GPL vmlinux 0xc74ae4f8 ide_legacy_device_add +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc83e47a7 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xc8a891a2 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xc9216716 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xc9353a16 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xc95a8fdb ide_destroy_dmatable +EXPORT_SYMBOL_GPL vmlinux 0xc9744155 usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0xc9832c6d sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xc98ca368 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0xc993fcfe ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0xc9a71a67 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xc9ae9de7 __ide_error +EXPORT_SYMBOL_GPL vmlinux 0xca905ec5 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0xcacd8c2b ide_pci_dma_base +EXPORT_SYMBOL_GPL vmlinux 0xcacf1a7b devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0xcb0c2ebf __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xcb31fb7f file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0xcb934c15 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0xcbc08c75 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xcbd331ce debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc8693c1 usbhid_set_leds +EXPORT_SYMBOL_GPL vmlinux 0xcc89f6a9 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xccb63047 ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcd49b95a cfi_cmdset_0001 +EXPORT_SYMBOL_GPL vmlinux 0xcd9f0680 transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xcda32a94 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0xcdb01877 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0xcdb3cff0 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcddfce40 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0xcf00a7cf sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xcf3a91a2 ide_dma_setup +EXPORT_SYMBOL_GPL vmlinux 0xcf4b530d ide_dma_end +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd02f80d2 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd07c6397 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0c3c50d regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0xd0c6db03 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0xd0ef72a2 pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xd10ff79f fat_get_dotdot_entry +EXPORT_SYMBOL_GPL vmlinux 0xd11ab125 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xd1202743 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0xd128b55a ide_dma_intr +EXPORT_SYMBOL_GPL vmlinux 0xd1824d42 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xd19f464c device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0xd1d44c69 ide_execute_pkt_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd2232941 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd27897fa usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0xd27f1830 inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0xd28da235 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xd303f3a9 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xd310322f ide_error +EXPORT_SYMBOL_GPL vmlinux 0xd3a61cce rpc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0xd3de934b ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0xd3fe31ca dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0xd402e08e ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0xd4030a64 inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xd40aecdf get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0xd48fd495 ide_dma_timeout +EXPORT_SYMBOL_GPL vmlinux 0xd4a226e4 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0xd4a8aaaa ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0xd5030cb5 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xd5184c07 device_attach +EXPORT_SYMBOL_GPL vmlinux 0xd5598329 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xd561b77f user_match +EXPORT_SYMBOL_GPL vmlinux 0xd58f4562 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0xd5ad4c30 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xd5cb0cde __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xd6469557 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0xd64f667a unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xd6a9c8a7 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xd6c8a81a ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0xd6e01d7e generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0xd6e4c7ad inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xd72c25c0 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0xd7320e6b ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xd741cfcf blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xd756d34f sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xd7d84c5a pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xd81c416d rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0xd81e2e89 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd88abf94 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0xd8fe69dc usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0xd92f0114 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xd9781d52 usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0xd978fc29 led_classdev_register +EXPORT_SYMBOL_GPL vmlinux 0xda0c3b1f lookup_create +EXPORT_SYMBOL_GPL vmlinux 0xda1ba4ec led_classdev_suspend +EXPORT_SYMBOL_GPL vmlinux 0xda8b53ad inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0xdaa5ec6b usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0xdac169eb platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0xdadb6421 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0xdaf27a9b ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xdb0156e9 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xdb1325f5 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xdb2e7e53 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0xdb979f1b ide_setup_pci_noise +EXPORT_SYMBOL_GPL vmlinux 0xdbf2a4e0 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xdc394191 ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0xdd075390 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0xdd30ad53 ide_read_bcount_and_ireason +EXPORT_SYMBOL_GPL vmlinux 0xdd43c092 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0xdd440c40 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xdd4ff4ff __class_register +EXPORT_SYMBOL_GPL vmlinux 0xdd6a3887 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0xddca8a0a bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xddf9f058 fat_dir_empty +EXPORT_SYMBOL_GPL vmlinux 0xddfd58a8 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xddff65aa ide_init_sg_cmd +EXPORT_SYMBOL_GPL vmlinux 0xded4aa5f fat_remove_entries +EXPORT_SYMBOL_GPL vmlinux 0xdf0d1ee2 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf73f01a put_pid +EXPORT_SYMBOL_GPL vmlinux 0xdf8569dc led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0xdfdbeed9 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0xdfdf2f15 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0xe006bfa8 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL vmlinux 0xe042f0a5 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0xe073ce16 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0xe085e9ef device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xe0d38e5c class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xe0ed1d5e sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0xe18e4adb inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xe1e25da6 put_rpccred +EXPORT_SYMBOL_GPL vmlinux 0xe1e29cc5 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xe2018352 ide_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xe2be4c7f ide_build_dmatable +EXPORT_SYMBOL_GPL vmlinux 0xe2d29916 xprt_unregister_transport +EXPORT_SYMBOL_GPL vmlinux 0xe3338fdd udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0xe3c493bc alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xe400f181 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4f11e80 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe54cba65 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0xe68f2ae6 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xe7ef6737 ide_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xe8860578 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0xe89d11a5 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xe8a07df3 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0xe8db77b2 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0xe91a7f2f bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0xe9357ca5 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe97a2167 uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xe97a9a1f xdr_skb_read_bits +EXPORT_SYMBOL_GPL vmlinux 0xe99aa3f9 ide_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0xea0f62b5 device_create +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xeaa8ea63 rpc_proc_register +EXPORT_SYMBOL_GPL vmlinux 0xeabcc37b ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0xeae18be9 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0xeb2f2935 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0xeb398d92 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0xeb5e2b7e ide_tf_read +EXPORT_SYMBOL_GPL vmlinux 0xeb608325 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xeb7cd5f5 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0xeb7f3bcd sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec4a0ee9 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0xecb5380b register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xecf684a0 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xecf7853e platform_bus +EXPORT_SYMBOL_GPL vmlinux 0xedbbfe1b ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xedc2994d ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0xee39cbf4 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xee3e3b21 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0xef17b2dc ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0xef233ba3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0xef24a07c transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xef4e963e __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef82fdba srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf010b045 ide_set_pio +EXPORT_SYMBOL_GPL vmlinux 0xf09a9b39 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xf0ae63b0 dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xf0c6f9c4 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf0ce5881 parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0xf105d00d ide_in_drive_list +EXPORT_SYMBOL_GPL vmlinux 0xf112d001 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xf1463412 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf14ace15 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1907db7 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0xf233a595 ide_port_scan +EXPORT_SYMBOL_GPL vmlinux 0xf2601dbf vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0xf2a7c121 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0xf2b042cc driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xf2b39015 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf30a5457 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0xf317a6c9 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0xf31b0d33 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0xf31c4bf5 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xf357f59e xprt_adjust_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xf35f37bc cfi_qry_mode_off +EXPORT_SYMBOL_GPL vmlinux 0xf37d7dcd ide_pci_init_one +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf3f7c836 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xf453730d platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4afec6c sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0xf4ea99a5 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xf50cd762 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf5267a64 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0xf53cfe2b klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0xf56b81f7 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5cd7a76 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf6e61f7b bus_register +EXPORT_SYMBOL_GPL vmlinux 0xf732320a vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0xf789a796 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0xf7bf90eb rpcb_getport_async +EXPORT_SYMBOL_GPL vmlinux 0xf863e82a flush_work +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf886289f ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0xf8eea40d xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf92116ea led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0xf92b6e4c rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0xf9613a23 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL vmlinux 0xf9fc6b9c hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0xfa04cc81 ide_input_data +EXPORT_SYMBOL_GPL vmlinux 0xfa88d87d platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0xfac1a845 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0xfad05a29 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0xfb06b0fa devres_get +EXPORT_SYMBOL_GPL vmlinux 0xfb41bab5 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0xfb62fe39 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfcb85927 scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xfcf3ff7d usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xfd4decc8 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xfd53d4bb vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0xfe0e431a pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0xfe64c33c add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfeef6a81 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0xff0ad129 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0xff59d8cc attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0xff73b4ef fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0xffa7bf9a sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xffaf7bbb __wake_up_sync --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/versatile.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/versatile.modules @@ -0,0 +1,76 @@ +8250 +ac97_bus +aes_generic +anubis +arc4 +authenc +ax88796 +blowfish +brd +cast5 +cast6 +cbc +cfg80211 +configfs +cramfs +crc32c +crc-itu-t +crc-t10dif +cryptoloop +crypto_null +des_generic +ecb +eeprom +fat +fuse +gf128mul +hmac +i2c-dev +inet_lro +jfs +khazad +libcrc32c +libertas_tf +lrw +mac80211 +md4 +md5 +michael_mic +mmci +msdos +mtdoops +nbd +nls_base +nls_cp850 +nls_iso8859-1 +pcbc +phonet +pn_pep +reiserfs +rfkill +rfkill-input +rng-core +serpent +sha1_generic +sha256_generic +sha512_generic +snd +snd-aaci +snd-ac97-codec +snd-mixer-oss +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-soc-core +snd-timer +stowaway +tea +tgr192 +twofish +twofish_common +veth +vfat +virtual +wp512 +xcbc +xfs --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/armel/versatile +++ linux-2.6.28/debian/abi/2.6.28-4.9/armel/versatile @@ -0,0 +1,3484 @@ +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_free_64k +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0x00000000 gf128mul_x_ble +EXPORT_SYMBOL drivers/serial/8250 0x00000000 serial8250_register_port +EXPORT_SYMBOL drivers/serial/8250 0x00000000 serial8250_resume_port +EXPORT_SYMBOL drivers/serial/8250 0x00000000 serial8250_suspend_port +EXPORT_SYMBOL drivers/serial/8250 0x00000000 serial8250_unregister_port +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x00000000 configfs_unregister_subsystem +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 load_nls +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 load_nls_default +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 register_nls +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 unload_nls +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 unregister_nls +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 utf8_mbstowcs +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 utf8_mbtowc +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 utf8_wcstombs +EXPORT_SYMBOL fs/nls/nls_base 0x00000000 utf8_wctomb +EXPORT_SYMBOL fs/xfs/xfs 0x00000000 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-itu-t 0x00000000 crc_itu_t +EXPORT_SYMBOL lib/crc-itu-t 0x00000000 crc_itu_t_table +EXPORT_SYMBOL lib/crc-t10dif 0x00000000 crc_t10dif +EXPORT_SYMBOL lib/libcrc32c 0x00000000 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x00000000 crc32c_le +EXPORT_SYMBOL net/ipv4/inet_lro 0x00000000 lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0x00000000 lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0x00000000 lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x00000000 lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x00000000 lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x00000000 lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x00000000 wiphy_to_hw +EXPORT_SYMBOL net/phonet/phonet 0x00000000 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x00000000 phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x00000000 phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0x00000000 phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0x00000000 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x00000000 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0x00000000 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x00000000 pn_sock_unhash +EXPORT_SYMBOL net/rfkill/rfkill 0x00000000 rfkill_allocate +EXPORT_SYMBOL net/rfkill/rfkill 0x00000000 rfkill_force_state +EXPORT_SYMBOL net/rfkill/rfkill 0x00000000 rfkill_free +EXPORT_SYMBOL net/rfkill/rfkill 0x00000000 rfkill_register +EXPORT_SYMBOL net/rfkill/rfkill 0x00000000 rfkill_switch_all +EXPORT_SYMBOL net/rfkill/rfkill 0x00000000 rfkill_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0x00000000 wiphy_unregister +EXPORT_SYMBOL sound/ac97_bus 0x00000000 ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x00000000 snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/snd 0x00000000 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0x00000000 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x00000000 release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_free +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_new +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_card_register +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_cards +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_component_add +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_device_free +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_device_new +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_device_register +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_info_register +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_iprintf +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_major +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x00000000 snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd-page-alloc 0x00000000 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x00000000 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x00000000 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x00000000 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x00000000 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x00000000 snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x00000000 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x00000000 snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0x00000000 snd_timer_stop +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00000000 snd_ac97_write_cache +EXPORT_SYMBOL vmlinux 0x00000000 I_BDEV +EXPORT_SYMBOL vmlinux 0x00000000 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x00000000 ___pskb_trim +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_idiv +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_idivmod +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_lasr +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_llsl +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_llsr +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_lmul +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_uidiv +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_uidivmod +EXPORT_SYMBOL vmlinux 0x00000000 __aeabi_ulcmp +EXPORT_SYMBOL vmlinux 0x00000000 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x00000000 __alloc_skb +EXPORT_SYMBOL vmlinux 0x00000000 __arm_ioremap +EXPORT_SYMBOL vmlinux 0x00000000 __arm_ioremap_pfn +EXPORT_SYMBOL vmlinux 0x00000000 __ashldi3 +EXPORT_SYMBOL vmlinux 0x00000000 __ashrdi3 +EXPORT_SYMBOL vmlinux 0x00000000 __backtrace +EXPORT_SYMBOL vmlinux 0x00000000 __bad_xchg +EXPORT_SYMBOL vmlinux 0x00000000 __bdevname +EXPORT_SYMBOL vmlinux 0x00000000 __bforget +EXPORT_SYMBOL vmlinux 0x00000000 __bio_clone +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_and +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_complement +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_equal +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_full +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_intersects +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_or +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_parse +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x00000000 __bitmap_xor +EXPORT_SYMBOL vmlinux 0x00000000 __blk_run_queue +EXPORT_SYMBOL vmlinux 0x00000000 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x00000000 __bread +EXPORT_SYMBOL vmlinux 0x00000000 __breadahead +EXPORT_SYMBOL vmlinux 0x00000000 __break_lease +EXPORT_SYMBOL vmlinux 0x00000000 __brelse +EXPORT_SYMBOL vmlinux 0x00000000 __bug +EXPORT_SYMBOL vmlinux 0x00000000 __cap_empty_set +EXPORT_SYMBOL vmlinux 0x00000000 __cap_full_set +EXPORT_SYMBOL vmlinux 0x00000000 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x00000000 __check_region +EXPORT_SYMBOL vmlinux 0x00000000 __clear_user +EXPORT_SYMBOL vmlinux 0x00000000 __const_udelay +EXPORT_SYMBOL vmlinux 0x00000000 __copy_from_user +EXPORT_SYMBOL vmlinux 0x00000000 __copy_to_user +EXPORT_SYMBOL vmlinux 0x00000000 __csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x00000000 __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x00000000 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x00000000 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x00000000 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x00000000 __devm_release_region +EXPORT_SYMBOL vmlinux 0x00000000 __devm_request_region +EXPORT_SYMBOL vmlinux 0x00000000 __div0 +EXPORT_SYMBOL vmlinux 0x00000000 __div64_32 +EXPORT_SYMBOL vmlinux 0x00000000 __divsi3 +EXPORT_SYMBOL vmlinux 0x00000000 __do_div64 +EXPORT_SYMBOL vmlinux 0x00000000 __down_read +EXPORT_SYMBOL vmlinux 0x00000000 __down_read_trylock +EXPORT_SYMBOL vmlinux 0x00000000 __down_write +EXPORT_SYMBOL vmlinux 0x00000000 __down_write_nested +EXPORT_SYMBOL vmlinux 0x00000000 __down_write_trylock +EXPORT_SYMBOL vmlinux 0x00000000 __downgrade_write +EXPORT_SYMBOL vmlinux 0x00000000 __dst_free +EXPORT_SYMBOL vmlinux 0x00000000 __elv_add_request +EXPORT_SYMBOL vmlinux 0x00000000 __f_setown +EXPORT_SYMBOL vmlinux 0x00000000 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x00000000 __find_get_block +EXPORT_SYMBOL vmlinux 0x00000000 __free_pages +EXPORT_SYMBOL vmlinux 0x00000000 __get_free_pages +EXPORT_SYMBOL vmlinux 0x00000000 __get_user_1 +EXPORT_SYMBOL vmlinux 0x00000000 __get_user_2 +EXPORT_SYMBOL vmlinux 0x00000000 __get_user_4 +EXPORT_SYMBOL vmlinux 0x00000000 __getblk +EXPORT_SYMBOL vmlinux 0x00000000 __grab_cache_page +EXPORT_SYMBOL vmlinux 0x00000000 __init_rwsem +EXPORT_SYMBOL vmlinux 0x00000000 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x00000000 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x00000000 __invalidate_device +EXPORT_SYMBOL vmlinux 0x00000000 __iounmap +EXPORT_SYMBOL vmlinux 0x00000000 __ip_select_ident +EXPORT_SYMBOL vmlinux 0x00000000 __kfifo_get +EXPORT_SYMBOL vmlinux 0x00000000 __kfifo_put +EXPORT_SYMBOL vmlinux 0x00000000 __kfree_skb +EXPORT_SYMBOL vmlinux 0x00000000 __kill_fasync +EXPORT_SYMBOL vmlinux 0x00000000 __kmalloc +EXPORT_SYMBOL vmlinux 0x00000000 __krealloc +EXPORT_SYMBOL vmlinux 0x00000000 __lock_buffer +EXPORT_SYMBOL vmlinux 0x00000000 __lock_page +EXPORT_SYMBOL vmlinux 0x00000000 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0x00000000 __lookup_hash +EXPORT_SYMBOL vmlinux 0x00000000 __lshrdi3 +EXPORT_SYMBOL vmlinux 0x00000000 __machine_arch_type +EXPORT_SYMBOL vmlinux 0x00000000 __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x00000000 __memzero +EXPORT_SYMBOL vmlinux 0x00000000 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x00000000 __mod_timer +EXPORT_SYMBOL vmlinux 0x00000000 __modsi3 +EXPORT_SYMBOL vmlinux 0x00000000 __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x00000000 __mpage_writepage +EXPORT_SYMBOL vmlinux 0x00000000 __muldi3 +EXPORT_SYMBOL vmlinux 0x00000000 __mutex_init +EXPORT_SYMBOL vmlinux 0x00000000 __napi_schedule +EXPORT_SYMBOL vmlinux 0x00000000 __neigh_event_send +EXPORT_SYMBOL vmlinux 0x00000000 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x00000000 __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x00000000 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x00000000 __netif_schedule +EXPORT_SYMBOL vmlinux 0x00000000 __nla_put +EXPORT_SYMBOL vmlinux 0x00000000 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x00000000 __nla_reserve +EXPORT_SYMBOL vmlinux 0x00000000 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x00000000 __page_symlink +EXPORT_SYMBOL vmlinux 0x00000000 __pagevec_release +EXPORT_SYMBOL vmlinux 0x00000000 __print_symbol +EXPORT_SYMBOL vmlinux 0x00000000 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x00000000 __put_user_1 +EXPORT_SYMBOL vmlinux 0x00000000 __put_user_2 +EXPORT_SYMBOL vmlinux 0x00000000 __put_user_4 +EXPORT_SYMBOL vmlinux 0x00000000 __put_user_8 +EXPORT_SYMBOL vmlinux 0x00000000 __ratelimit +EXPORT_SYMBOL vmlinux 0x00000000 __raw_readsb +EXPORT_SYMBOL vmlinux 0x00000000 __raw_readsl +EXPORT_SYMBOL vmlinux 0x00000000 __raw_readsw +EXPORT_SYMBOL vmlinux 0x00000000 __raw_writesb +EXPORT_SYMBOL vmlinux 0x00000000 __raw_writesl +EXPORT_SYMBOL vmlinux 0x00000000 __raw_writesw +EXPORT_SYMBOL vmlinux 0x00000000 __readwrite_bug +EXPORT_SYMBOL vmlinux 0x00000000 __release_region +EXPORT_SYMBOL vmlinux 0x00000000 __request_region +EXPORT_SYMBOL vmlinux 0x00000000 __rta_fill +EXPORT_SYMBOL vmlinux 0x00000000 __scm_destroy +EXPORT_SYMBOL vmlinux 0x00000000 __scm_send +EXPORT_SYMBOL vmlinux 0x00000000 __secpath_destroy +EXPORT_SYMBOL vmlinux 0x00000000 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0x00000000 __seq_open_private +EXPORT_SYMBOL vmlinux 0x00000000 __serio_register_driver +EXPORT_SYMBOL vmlinux 0x00000000 __serio_register_port +EXPORT_SYMBOL vmlinux 0x00000000 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x00000000 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x00000000 __set_personality +EXPORT_SYMBOL vmlinux 0x00000000 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x00000000 __sg_free_table +EXPORT_SYMBOL vmlinux 0x00000000 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x00000000 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x00000000 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x00000000 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x00000000 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x00000000 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x00000000 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x00000000 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x00000000 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0x00000000 __strnlen_user +EXPORT_SYMBOL vmlinux 0x00000000 __symbol_put +EXPORT_SYMBOL vmlinux 0x00000000 __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x00000000 __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x00000000 __ucmpdi2 +EXPORT_SYMBOL vmlinux 0x00000000 __udelay +EXPORT_SYMBOL vmlinux 0x00000000 __udivsi3 +EXPORT_SYMBOL vmlinux 0x00000000 __umodsi3 +EXPORT_SYMBOL vmlinux 0x00000000 __up_read +EXPORT_SYMBOL vmlinux 0x00000000 __up_write +EXPORT_SYMBOL vmlinux 0x00000000 __vmalloc +EXPORT_SYMBOL vmlinux 0x00000000 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x00000000 __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x00000000 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x00000000 __wake_up +EXPORT_SYMBOL vmlinux 0x00000000 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x00000000 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x00000000 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x00000000 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x00000000 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x00000000 __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x00000000 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x00000000 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x00000000 _change_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _clear_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _cond_resched +EXPORT_SYMBOL vmlinux 0x00000000 _ctype +EXPORT_SYMBOL vmlinux 0x00000000 _find_first_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _find_first_zero_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _find_next_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _find_next_zero_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _local_bh_enable +EXPORT_SYMBOL vmlinux 0x00000000 _memcpy_fromio +EXPORT_SYMBOL vmlinux 0x00000000 _memcpy_toio +EXPORT_SYMBOL vmlinux 0x00000000 _memset_io +EXPORT_SYMBOL vmlinux 0x00000000 _set_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _test_and_change_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _test_and_clear_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 _test_and_set_bit_le +EXPORT_SYMBOL vmlinux 0x00000000 abort +EXPORT_SYMBOL vmlinux 0x00000000 acquire_console_sem +EXPORT_SYMBOL vmlinux 0x00000000 add_disk +EXPORT_SYMBOL vmlinux 0x00000000 add_mtd_partitions +EXPORT_SYMBOL vmlinux 0x00000000 add_taint +EXPORT_SYMBOL vmlinux 0x00000000 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x00000000 add_wait_queue +EXPORT_SYMBOL vmlinux 0x00000000 add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x00000000 adjust_resource +EXPORT_SYMBOL vmlinux 0x00000000 aio_complete +EXPORT_SYMBOL vmlinux 0x00000000 aio_put_req +EXPORT_SYMBOL vmlinux 0x00000000 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x00000000 alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x00000000 alloc_disk +EXPORT_SYMBOL vmlinux 0x00000000 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x00000000 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x00000000 alloc_file +EXPORT_SYMBOL vmlinux 0x00000000 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x00000000 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0x00000000 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x00000000 allocate_resource +EXPORT_SYMBOL vmlinux 0x00000000 allow_signal +EXPORT_SYMBOL vmlinux 0x00000000 amba_device_register +EXPORT_SYMBOL vmlinux 0x00000000 amba_device_unregister +EXPORT_SYMBOL vmlinux 0x00000000 amba_driver_register +EXPORT_SYMBOL vmlinux 0x00000000 amba_driver_unregister +EXPORT_SYMBOL vmlinux 0x00000000 amba_find_device +EXPORT_SYMBOL vmlinux 0x00000000 amba_release_regions +EXPORT_SYMBOL vmlinux 0x00000000 amba_request_regions +EXPORT_SYMBOL vmlinux 0x00000000 argv_free +EXPORT_SYMBOL vmlinux 0x00000000 argv_split +EXPORT_SYMBOL vmlinux 0x00000000 arm926_coherent_kern_range +EXPORT_SYMBOL vmlinux 0x00000000 arm926_flush_kern_cache_all +EXPORT_SYMBOL vmlinux 0x00000000 arm926_flush_user_cache_all +EXPORT_SYMBOL vmlinux 0x00000000 arm926_flush_user_cache_range +EXPORT_SYMBOL vmlinux 0x00000000 arm_elf_read_implies_exec +EXPORT_SYMBOL vmlinux 0x00000000 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x00000000 arp_create +EXPORT_SYMBOL vmlinux 0x00000000 arp_find +EXPORT_SYMBOL vmlinux 0x00000000 arp_send +EXPORT_SYMBOL vmlinux 0x00000000 arp_tbl +EXPORT_SYMBOL vmlinux 0x00000000 arp_xmit +EXPORT_SYMBOL vmlinux 0x00000000 auth_domain_find +EXPORT_SYMBOL vmlinux 0x00000000 auth_domain_lookup +EXPORT_SYMBOL vmlinux 0x00000000 auth_domain_put +EXPORT_SYMBOL vmlinux 0x00000000 auth_unix_add_addr +EXPORT_SYMBOL vmlinux 0x00000000 auth_unix_forget_old +EXPORT_SYMBOL vmlinux 0x00000000 auth_unix_lookup +EXPORT_SYMBOL vmlinux 0x00000000 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0x00000000 avenrun +EXPORT_SYMBOL vmlinux 0x00000000 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0x00000000 bcd2bin +EXPORT_SYMBOL vmlinux 0x00000000 bd_claim +EXPORT_SYMBOL vmlinux 0x00000000 bd_release +EXPORT_SYMBOL vmlinux 0x00000000 bd_set_size +EXPORT_SYMBOL vmlinux 0x00000000 bdev_read_only +EXPORT_SYMBOL vmlinux 0x00000000 bdevname +EXPORT_SYMBOL vmlinux 0x00000000 bdget +EXPORT_SYMBOL vmlinux 0x00000000 bdget_disk +EXPORT_SYMBOL vmlinux 0x00000000 bdi_destroy +EXPORT_SYMBOL vmlinux 0x00000000 bdi_init +EXPORT_SYMBOL vmlinux 0x00000000 bdi_register +EXPORT_SYMBOL vmlinux 0x00000000 bdi_register_dev +EXPORT_SYMBOL vmlinux 0x00000000 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x00000000 bdi_unregister +EXPORT_SYMBOL vmlinux 0x00000000 bdput +EXPORT_SYMBOL vmlinux 0x00000000 bh_submit_read +EXPORT_SYMBOL vmlinux 0x00000000 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x00000000 bin2bcd +EXPORT_SYMBOL vmlinux 0x00000000 bio_add_page +EXPORT_SYMBOL vmlinux 0x00000000 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x00000000 bio_alloc +EXPORT_SYMBOL vmlinux 0x00000000 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x00000000 bio_clone +EXPORT_SYMBOL vmlinux 0x00000000 bio_copy_kern +EXPORT_SYMBOL vmlinux 0x00000000 bio_copy_user +EXPORT_SYMBOL vmlinux 0x00000000 bio_endio +EXPORT_SYMBOL vmlinux 0x00000000 bio_free +EXPORT_SYMBOL vmlinux 0x00000000 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x00000000 bio_init +EXPORT_SYMBOL vmlinux 0x00000000 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x00000000 bio_map_kern +EXPORT_SYMBOL vmlinux 0x00000000 bio_map_user +EXPORT_SYMBOL vmlinux 0x00000000 bio_pair_release +EXPORT_SYMBOL vmlinux 0x00000000 bio_phys_segments +EXPORT_SYMBOL vmlinux 0x00000000 bio_put +EXPORT_SYMBOL vmlinux 0x00000000 bio_sector_offset +EXPORT_SYMBOL vmlinux 0x00000000 bio_split +EXPORT_SYMBOL vmlinux 0x00000000 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x00000000 bio_unmap_user +EXPORT_SYMBOL vmlinux 0x00000000 bioset_create +EXPORT_SYMBOL vmlinux 0x00000000 bioset_free +EXPORT_SYMBOL vmlinux 0x00000000 bit_waitqueue +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_bitremap +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_fold +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_onto +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_remap +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x00000000 bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x00000000 bitrev16 +EXPORT_SYMBOL vmlinux 0x00000000 bitrev32 +EXPORT_SYMBOL vmlinux 0x00000000 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x00000000 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x00000000 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x00000000 blk_complete_request +EXPORT_SYMBOL vmlinux 0x00000000 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x00000000 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x00000000 blk_free_tags +EXPORT_SYMBOL vmlinux 0x00000000 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x00000000 blk_get_request +EXPORT_SYMBOL vmlinux 0x00000000 blk_init_queue +EXPORT_SYMBOL vmlinux 0x00000000 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x00000000 blk_init_tags +EXPORT_SYMBOL vmlinux 0x00000000 blk_insert_request +EXPORT_SYMBOL vmlinux 0x00000000 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x00000000 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x00000000 blk_plug_device +EXPORT_SYMBOL vmlinux 0x00000000 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x00000000 blk_put_request +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x00000000 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x00000000 blk_recount_segments +EXPORT_SYMBOL vmlinux 0x00000000 blk_register_region +EXPORT_SYMBOL vmlinux 0x00000000 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x00000000 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x00000000 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x00000000 blk_rq_init +EXPORT_SYMBOL vmlinux 0x00000000 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x00000000 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x00000000 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x00000000 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x00000000 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x00000000 blk_run_queue +EXPORT_SYMBOL vmlinux 0x00000000 blk_start_queue +EXPORT_SYMBOL vmlinux 0x00000000 blk_start_queueing +EXPORT_SYMBOL vmlinux 0x00000000 blk_stop_queue +EXPORT_SYMBOL vmlinux 0x00000000 blk_sync_queue +EXPORT_SYMBOL vmlinux 0x00000000 blk_unplug +EXPORT_SYMBOL vmlinux 0x00000000 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x00000000 blk_verify_command +EXPORT_SYMBOL vmlinux 0x00000000 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x00000000 blkdev_get +EXPORT_SYMBOL vmlinux 0x00000000 blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0x00000000 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x00000000 blkdev_put +EXPORT_SYMBOL vmlinux 0x00000000 block_all_signals +EXPORT_SYMBOL vmlinux 0x00000000 block_commit_write +EXPORT_SYMBOL vmlinux 0x00000000 block_invalidatepage +EXPORT_SYMBOL vmlinux 0x00000000 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0x00000000 block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x00000000 block_prepare_write +EXPORT_SYMBOL vmlinux 0x00000000 block_read_full_page +EXPORT_SYMBOL vmlinux 0x00000000 block_sync_page +EXPORT_SYMBOL vmlinux 0x00000000 block_truncate_page +EXPORT_SYMBOL vmlinux 0x00000000 block_write_begin +EXPORT_SYMBOL vmlinux 0x00000000 block_write_end +EXPORT_SYMBOL vmlinux 0x00000000 block_write_full_page +EXPORT_SYMBOL vmlinux 0x00000000 bmap +EXPORT_SYMBOL vmlinux 0x00000000 boot_tvec_bases +EXPORT_SYMBOL vmlinux 0x00000000 brioctl_set +EXPORT_SYMBOL vmlinux 0x00000000 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x00000000 cache_check +EXPORT_SYMBOL vmlinux 0x00000000 cache_flush +EXPORT_SYMBOL vmlinux 0x00000000 cache_purge +EXPORT_SYMBOL vmlinux 0x00000000 cache_register +EXPORT_SYMBOL vmlinux 0x00000000 cache_unregister +EXPORT_SYMBOL vmlinux 0x00000000 cacheid +EXPORT_SYMBOL vmlinux 0x00000000 cad_pid +EXPORT_SYMBOL vmlinux 0x00000000 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0x00000000 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x00000000 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x00000000 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x00000000 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x00000000 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x00000000 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0x00000000 can_do_mlock +EXPORT_SYMBOL vmlinux 0x00000000 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x00000000 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x00000000 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x00000000 cap_set_effective +EXPORT_SYMBOL vmlinux 0x00000000 capable +EXPORT_SYMBOL vmlinux 0x00000000 cdev_add +EXPORT_SYMBOL vmlinux 0x00000000 cdev_alloc +EXPORT_SYMBOL vmlinux 0x00000000 cdev_del +EXPORT_SYMBOL vmlinux 0x00000000 cdev_init +EXPORT_SYMBOL vmlinux 0x00000000 cfb_copyarea +EXPORT_SYMBOL vmlinux 0x00000000 cfb_fillrect +EXPORT_SYMBOL vmlinux 0x00000000 cfb_imageblit +EXPORT_SYMBOL vmlinux 0x00000000 cfi_fixup +EXPORT_SYMBOL vmlinux 0x00000000 cfi_read_pri +EXPORT_SYMBOL vmlinux 0x00000000 cfi_varsize_frob +EXPORT_SYMBOL vmlinux 0x00000000 check_disk_change +EXPORT_SYMBOL vmlinux 0x00000000 check_disk_size_change +EXPORT_SYMBOL vmlinux 0x00000000 clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x00000000 clear_inode +EXPORT_SYMBOL vmlinux 0x00000000 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x00000000 clk_disable +EXPORT_SYMBOL vmlinux 0x00000000 clk_enable +EXPORT_SYMBOL vmlinux 0x00000000 clk_get +EXPORT_SYMBOL vmlinux 0x00000000 clk_get_rate +EXPORT_SYMBOL vmlinux 0x00000000 clk_put +EXPORT_SYMBOL vmlinux 0x00000000 clk_register +EXPORT_SYMBOL vmlinux 0x00000000 clk_round_rate +EXPORT_SYMBOL vmlinux 0x00000000 clk_set_rate +EXPORT_SYMBOL vmlinux 0x00000000 clk_unregister +EXPORT_SYMBOL vmlinux 0x00000000 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 clocksource_register +EXPORT_SYMBOL vmlinux 0x00000000 close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x00000000 color_table +EXPORT_SYMBOL vmlinux 0x00000000 complete +EXPORT_SYMBOL vmlinux 0x00000000 complete_all +EXPORT_SYMBOL vmlinux 0x00000000 complete_and_exit +EXPORT_SYMBOL vmlinux 0x00000000 completion_done +EXPORT_SYMBOL vmlinux 0x00000000 compute_creds +EXPORT_SYMBOL vmlinux 0x00000000 con_copy_unimap +EXPORT_SYMBOL vmlinux 0x00000000 con_is_bound +EXPORT_SYMBOL vmlinux 0x00000000 con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x00000000 cond_resched_lock +EXPORT_SYMBOL vmlinux 0x00000000 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x00000000 congestion_wait +EXPORT_SYMBOL vmlinux 0x00000000 console_blank_hook +EXPORT_SYMBOL vmlinux 0x00000000 console_blanked +EXPORT_SYMBOL vmlinux 0x00000000 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0x00000000 console_print +EXPORT_SYMBOL vmlinux 0x00000000 console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x00000000 console_start +EXPORT_SYMBOL vmlinux 0x00000000 console_stop +EXPORT_SYMBOL vmlinux 0x00000000 console_suspend_enabled +EXPORT_SYMBOL vmlinux 0x00000000 cont_write_begin +EXPORT_SYMBOL vmlinux 0x00000000 contig_page_data +EXPORT_SYMBOL vmlinux 0x00000000 copy_io_context +EXPORT_SYMBOL vmlinux 0x00000000 copy_page +EXPORT_SYMBOL vmlinux 0x00000000 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x00000000 cpu_all_bits +EXPORT_SYMBOL vmlinux 0x00000000 cpu_arm926_dcache_clean_area +EXPORT_SYMBOL vmlinux 0x00000000 cpu_arm926_set_pte_ext +EXPORT_SYMBOL vmlinux 0x00000000 cpu_online_map +EXPORT_SYMBOL vmlinux 0x00000000 cpu_possible_map +EXPORT_SYMBOL vmlinux 0x00000000 cpu_present_map +EXPORT_SYMBOL vmlinux 0x00000000 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x00000000 crc16 +EXPORT_SYMBOL vmlinux 0x00000000 crc16_table +EXPORT_SYMBOL vmlinux 0x00000000 crc32_be +EXPORT_SYMBOL vmlinux 0x00000000 crc32_le +EXPORT_SYMBOL vmlinux 0x00000000 create_empty_buffers +EXPORT_SYMBOL vmlinux 0x00000000 create_proc_entry +EXPORT_SYMBOL vmlinux 0x00000000 csum_partial +EXPORT_SYMBOL vmlinux 0x00000000 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x00000000 csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x00000000 csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x00000000 current_fs_time +EXPORT_SYMBOL vmlinux 0x00000000 current_kernel_time +EXPORT_SYMBOL vmlinux 0x00000000 d_add_ci +EXPORT_SYMBOL vmlinux 0x00000000 d_alloc +EXPORT_SYMBOL vmlinux 0x00000000 d_alloc_name +EXPORT_SYMBOL vmlinux 0x00000000 d_alloc_root +EXPORT_SYMBOL vmlinux 0x00000000 d_delete +EXPORT_SYMBOL vmlinux 0x00000000 d_find_alias +EXPORT_SYMBOL vmlinux 0x00000000 d_genocide +EXPORT_SYMBOL vmlinux 0x00000000 d_instantiate +EXPORT_SYMBOL vmlinux 0x00000000 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x00000000 d_invalidate +EXPORT_SYMBOL vmlinux 0x00000000 d_lookup +EXPORT_SYMBOL vmlinux 0x00000000 d_move +EXPORT_SYMBOL vmlinux 0x00000000 d_namespace_path +EXPORT_SYMBOL vmlinux 0x00000000 d_path +EXPORT_SYMBOL vmlinux 0x00000000 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x00000000 d_rehash +EXPORT_SYMBOL vmlinux 0x00000000 d_splice_alias +EXPORT_SYMBOL vmlinux 0x00000000 d_validate +EXPORT_SYMBOL vmlinux 0x00000000 daemonize +EXPORT_SYMBOL vmlinux 0x00000000 datagram_poll +EXPORT_SYMBOL vmlinux 0x00000000 dcache_dir_close +EXPORT_SYMBOL vmlinux 0x00000000 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x00000000 dcache_dir_open +EXPORT_SYMBOL vmlinux 0x00000000 dcache_lock +EXPORT_SYMBOL vmlinux 0x00000000 dcache_readdir +EXPORT_SYMBOL vmlinux 0x00000000 deactivate_super +EXPORT_SYMBOL vmlinux 0x00000000 default_blu +EXPORT_SYMBOL vmlinux 0x00000000 default_grn +EXPORT_SYMBOL vmlinux 0x00000000 default_llseek +EXPORT_SYMBOL vmlinux 0x00000000 default_red +EXPORT_SYMBOL vmlinux 0x00000000 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x00000000 default_wake_function +EXPORT_SYMBOL vmlinux 0x00000000 del_gendisk +EXPORT_SYMBOL vmlinux 0x00000000 del_mtd_partitions +EXPORT_SYMBOL vmlinux 0x00000000 del_timer +EXPORT_SYMBOL vmlinux 0x00000000 dentry_open +EXPORT_SYMBOL vmlinux 0x00000000 dentry_unhash +EXPORT_SYMBOL vmlinux 0x00000000 deny_write_access +EXPORT_SYMBOL vmlinux 0x00000000 dev_add_pack +EXPORT_SYMBOL vmlinux 0x00000000 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x00000000 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x00000000 dev_base_lock +EXPORT_SYMBOL vmlinux 0x00000000 dev_change_flags +EXPORT_SYMBOL vmlinux 0x00000000 dev_close +EXPORT_SYMBOL vmlinux 0x00000000 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x00000000 dev_driver_string +EXPORT_SYMBOL vmlinux 0x00000000 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0x00000000 dev_get_by_index +EXPORT_SYMBOL vmlinux 0x00000000 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x00000000 dev_get_flags +EXPORT_SYMBOL vmlinux 0x00000000 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x00000000 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x00000000 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x00000000 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x00000000 dev_load +EXPORT_SYMBOL vmlinux 0x00000000 dev_mc_add +EXPORT_SYMBOL vmlinux 0x00000000 dev_mc_delete +EXPORT_SYMBOL vmlinux 0x00000000 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x00000000 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x00000000 dev_open +EXPORT_SYMBOL vmlinux 0x00000000 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x00000000 dev_remove_pack +EXPORT_SYMBOL vmlinux 0x00000000 dev_set_allmulti +EXPORT_SYMBOL vmlinux 0x00000000 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x00000000 dev_set_mtu +EXPORT_SYMBOL vmlinux 0x00000000 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x00000000 dev_unicast_add +EXPORT_SYMBOL vmlinux 0x00000000 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x00000000 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x00000000 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x00000000 dev_valid_name +EXPORT_SYMBOL vmlinux 0x00000000 devm_free_irq +EXPORT_SYMBOL vmlinux 0x00000000 devm_ioport_map +EXPORT_SYMBOL vmlinux 0x00000000 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x00000000 devm_ioremap +EXPORT_SYMBOL vmlinux 0x00000000 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x00000000 devm_iounmap +EXPORT_SYMBOL vmlinux 0x00000000 devm_request_irq +EXPORT_SYMBOL vmlinux 0x00000000 dget_locked +EXPORT_SYMBOL vmlinux 0x00000000 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x00000000 disable_hlt +EXPORT_SYMBOL vmlinux 0x00000000 disable_irq +EXPORT_SYMBOL vmlinux 0x00000000 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x00000000 disallow_signal +EXPORT_SYMBOL vmlinux 0x00000000 div64_u64 +EXPORT_SYMBOL vmlinux 0x00000000 div_s64_rem +EXPORT_SYMBOL vmlinux 0x00000000 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0x00000000 dma_alloc_coherent +EXPORT_SYMBOL vmlinux 0x00000000 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x00000000 dma_alloc_writecombine +EXPORT_SYMBOL vmlinux 0x00000000 dma_cache_maint +EXPORT_SYMBOL vmlinux 0x00000000 dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x00000000 dma_free_coherent +EXPORT_SYMBOL vmlinux 0x00000000 dma_map_sg +EXPORT_SYMBOL vmlinux 0x00000000 dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x00000000 dma_mmap_coherent +EXPORT_SYMBOL vmlinux 0x00000000 dma_mmap_writecombine +EXPORT_SYMBOL vmlinux 0x00000000 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x00000000 dma_pool_create +EXPORT_SYMBOL vmlinux 0x00000000 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x00000000 dma_pool_free +EXPORT_SYMBOL vmlinux 0x00000000 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x00000000 dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x00000000 dma_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0x00000000 dma_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0x00000000 dma_unmap_sg +EXPORT_SYMBOL vmlinux 0x00000000 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x00000000 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x00000000 dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x00000000 dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x00000000 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x00000000 dmam_pool_create +EXPORT_SYMBOL vmlinux 0x00000000 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x00000000 dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x00000000 do_SAK +EXPORT_SYMBOL vmlinux 0x00000000 do_blank_screen +EXPORT_SYMBOL vmlinux 0x00000000 do_brk +EXPORT_SYMBOL vmlinux 0x00000000 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x00000000 do_map_probe +EXPORT_SYMBOL vmlinux 0x00000000 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x00000000 do_munmap +EXPORT_SYMBOL vmlinux 0x00000000 do_settimeofday +EXPORT_SYMBOL vmlinux 0x00000000 do_splice_from +EXPORT_SYMBOL vmlinux 0x00000000 do_splice_to +EXPORT_SYMBOL vmlinux 0x00000000 do_sync_read +EXPORT_SYMBOL vmlinux 0x00000000 do_sync_write +EXPORT_SYMBOL vmlinux 0x00000000 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x00000000 down +EXPORT_SYMBOL vmlinux 0x00000000 down_interruptible +EXPORT_SYMBOL vmlinux 0x00000000 down_killable +EXPORT_SYMBOL vmlinux 0x00000000 down_read +EXPORT_SYMBOL vmlinux 0x00000000 down_read_trylock +EXPORT_SYMBOL vmlinux 0x00000000 down_timeout +EXPORT_SYMBOL vmlinux 0x00000000 down_trylock +EXPORT_SYMBOL vmlinux 0x00000000 down_write +EXPORT_SYMBOL vmlinux 0x00000000 down_write_trylock +EXPORT_SYMBOL vmlinux 0x00000000 downgrade_write +EXPORT_SYMBOL vmlinux 0x00000000 dput +EXPORT_SYMBOL vmlinux 0x00000000 drop_super +EXPORT_SYMBOL vmlinux 0x00000000 dst_alloc +EXPORT_SYMBOL vmlinux 0x00000000 dst_destroy +EXPORT_SYMBOL vmlinux 0x00000000 dst_discard +EXPORT_SYMBOL vmlinux 0x00000000 dst_release +EXPORT_SYMBOL vmlinux 0x00000000 dump_fpu +EXPORT_SYMBOL vmlinux 0x00000000 dump_stack +EXPORT_SYMBOL vmlinux 0x00000000 elevator_exit +EXPORT_SYMBOL vmlinux 0x00000000 elevator_init +EXPORT_SYMBOL vmlinux 0x00000000 elf_check_arch +EXPORT_SYMBOL vmlinux 0x00000000 elf_hwcap +EXPORT_SYMBOL vmlinux 0x00000000 elf_platform +EXPORT_SYMBOL vmlinux 0x00000000 elf_set_personality +EXPORT_SYMBOL vmlinux 0x00000000 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x00000000 elv_add_request +EXPORT_SYMBOL vmlinux 0x00000000 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x00000000 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x00000000 elv_next_request +EXPORT_SYMBOL vmlinux 0x00000000 elv_queue_empty +EXPORT_SYMBOL vmlinux 0x00000000 elv_rb_add +EXPORT_SYMBOL vmlinux 0x00000000 elv_rb_del +EXPORT_SYMBOL vmlinux 0x00000000 elv_rb_find +EXPORT_SYMBOL vmlinux 0x00000000 elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x00000000 elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x00000000 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x00000000 empty_zero_page +EXPORT_SYMBOL vmlinux 0x00000000 enable_hlt +EXPORT_SYMBOL vmlinux 0x00000000 enable_irq +EXPORT_SYMBOL vmlinux 0x00000000 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0x00000000 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x00000000 end_page_writeback +EXPORT_SYMBOL vmlinux 0x00000000 end_request +EXPORT_SYMBOL vmlinux 0x00000000 eth_header +EXPORT_SYMBOL vmlinux 0x00000000 eth_header_cache +EXPORT_SYMBOL vmlinux 0x00000000 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x00000000 eth_header_parse +EXPORT_SYMBOL vmlinux 0x00000000 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x00000000 eth_type_trans +EXPORT_SYMBOL vmlinux 0x00000000 ether_setup +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x00000000 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0x00000000 f_setown +EXPORT_SYMBOL vmlinux 0x00000000 fasync_helper +EXPORT_SYMBOL vmlinux 0x00000000 fb_add_videomode +EXPORT_SYMBOL vmlinux 0x00000000 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x00000000 fb_blank +EXPORT_SYMBOL vmlinux 0x00000000 fb_class +EXPORT_SYMBOL vmlinux 0x00000000 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x00000000 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x00000000 fb_default_cmap +EXPORT_SYMBOL vmlinux 0x00000000 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x00000000 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0x00000000 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x00000000 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x00000000 fb_find_mode +EXPORT_SYMBOL vmlinux 0x00000000 fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0x00000000 fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x00000000 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x00000000 fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x00000000 fb_get_mode +EXPORT_SYMBOL vmlinux 0x00000000 fb_get_options +EXPORT_SYMBOL vmlinux 0x00000000 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0x00000000 fb_match_mode +EXPORT_SYMBOL vmlinux 0x00000000 fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0x00000000 fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x00000000 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x00000000 fb_pan_display +EXPORT_SYMBOL vmlinux 0x00000000 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x00000000 fb_register_client +EXPORT_SYMBOL vmlinux 0x00000000 fb_set_cmap +EXPORT_SYMBOL vmlinux 0x00000000 fb_set_suspend +EXPORT_SYMBOL vmlinux 0x00000000 fb_set_var +EXPORT_SYMBOL vmlinux 0x00000000 fb_show_logo +EXPORT_SYMBOL vmlinux 0x00000000 fb_unregister_client +EXPORT_SYMBOL vmlinux 0x00000000 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x00000000 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0x00000000 fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0x00000000 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0x00000000 fbcon_set_bitops +EXPORT_SYMBOL vmlinux 0x00000000 fd_install +EXPORT_SYMBOL vmlinux 0x00000000 fg_console +EXPORT_SYMBOL vmlinux 0x00000000 fget +EXPORT_SYMBOL vmlinux 0x00000000 fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x00000000 fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0x00000000 file_fsync +EXPORT_SYMBOL vmlinux 0x00000000 file_permission +EXPORT_SYMBOL vmlinux 0x00000000 file_remove_suid +EXPORT_SYMBOL vmlinux 0x00000000 file_update_time +EXPORT_SYMBOL vmlinux 0x00000000 filemap_fault +EXPORT_SYMBOL vmlinux 0x00000000 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x00000000 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x00000000 filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x00000000 filemap_flush +EXPORT_SYMBOL vmlinux 0x00000000 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x00000000 filp_close +EXPORT_SYMBOL vmlinux 0x00000000 filp_open +EXPORT_SYMBOL vmlinux 0x00000000 find_font +EXPORT_SYMBOL vmlinux 0x00000000 find_get_page +EXPORT_SYMBOL vmlinux 0x00000000 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x00000000 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x00000000 find_inode_number +EXPORT_SYMBOL vmlinux 0x00000000 find_lock_page +EXPORT_SYMBOL vmlinux 0x00000000 find_or_create_page +EXPORT_SYMBOL vmlinux 0x00000000 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x00000000 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x00000000 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0x00000000 find_vma +EXPORT_SYMBOL vmlinux 0x00000000 finish_wait +EXPORT_SYMBOL vmlinux 0x00000000 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x00000000 flow_cache_genid +EXPORT_SYMBOL vmlinux 0x00000000 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x00000000 flush_dcache_page +EXPORT_SYMBOL vmlinux 0x00000000 flush_old_exec +EXPORT_SYMBOL vmlinux 0x00000000 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x00000000 flush_signals +EXPORT_SYMBOL vmlinux 0x00000000 follow_down +EXPORT_SYMBOL vmlinux 0x00000000 follow_up +EXPORT_SYMBOL vmlinux 0x00000000 force_sig +EXPORT_SYMBOL vmlinux 0x00000000 fp_printk +EXPORT_SYMBOL vmlinux 0x00000000 fp_send_sig +EXPORT_SYMBOL vmlinux 0x00000000 fput +EXPORT_SYMBOL vmlinux 0x00000000 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x00000000 framebuffer_release +EXPORT_SYMBOL vmlinux 0x00000000 free_buffer_head +EXPORT_SYMBOL vmlinux 0x00000000 free_irq +EXPORT_SYMBOL vmlinux 0x00000000 free_netdev +EXPORT_SYMBOL vmlinux 0x00000000 free_pages +EXPORT_SYMBOL vmlinux 0x00000000 free_pages_exact +EXPORT_SYMBOL vmlinux 0x00000000 free_task +EXPORT_SYMBOL vmlinux 0x00000000 freeze_bdev +EXPORT_SYMBOL vmlinux 0x00000000 fs_overflowgid +EXPORT_SYMBOL vmlinux 0x00000000 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x00000000 fsync_bdev +EXPORT_SYMBOL vmlinux 0x00000000 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0x00000000 gen_new_estimator +EXPORT_SYMBOL vmlinux 0x00000000 gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x00000000 generate_random_uuid +EXPORT_SYMBOL vmlinux 0x00000000 generic_block_bmap +EXPORT_SYMBOL vmlinux 0x00000000 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0x00000000 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x00000000 generic_delete_inode +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_llseek +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_open +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x00000000 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x00000000 generic_fillattr +EXPORT_SYMBOL vmlinux 0x00000000 generic_getxattr +EXPORT_SYMBOL vmlinux 0x00000000 generic_listxattr +EXPORT_SYMBOL vmlinux 0x00000000 generic_make_request +EXPORT_SYMBOL vmlinux 0x00000000 generic_mii_ioctl +EXPORT_SYMBOL vmlinux 0x00000000 generic_osync_inode +EXPORT_SYMBOL vmlinux 0x00000000 generic_permission +EXPORT_SYMBOL vmlinux 0x00000000 generic_read_dir +EXPORT_SYMBOL vmlinux 0x00000000 generic_readlink +EXPORT_SYMBOL vmlinux 0x00000000 generic_removexattr +EXPORT_SYMBOL vmlinux 0x00000000 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x00000000 generic_segment_checks +EXPORT_SYMBOL vmlinux 0x00000000 generic_setlease +EXPORT_SYMBOL vmlinux 0x00000000 generic_setxattr +EXPORT_SYMBOL vmlinux 0x00000000 generic_show_options +EXPORT_SYMBOL vmlinux 0x00000000 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x00000000 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0x00000000 generic_unplug_device +EXPORT_SYMBOL vmlinux 0x00000000 generic_write_checks +EXPORT_SYMBOL vmlinux 0x00000000 generic_write_end +EXPORT_SYMBOL vmlinux 0x00000000 generic_writepages +EXPORT_SYMBOL vmlinux 0x00000000 genl_register_family +EXPORT_SYMBOL vmlinux 0x00000000 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x00000000 genl_register_ops +EXPORT_SYMBOL vmlinux 0x00000000 genl_sock +EXPORT_SYMBOL vmlinux 0x00000000 genl_unregister_family +EXPORT_SYMBOL vmlinux 0x00000000 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x00000000 get_default_font +EXPORT_SYMBOL vmlinux 0x00000000 get_disk +EXPORT_SYMBOL vmlinux 0x00000000 get_empty_filp +EXPORT_SYMBOL vmlinux 0x00000000 get_fs_type +EXPORT_SYMBOL vmlinux 0x00000000 get_io_context +EXPORT_SYMBOL vmlinux 0x00000000 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x00000000 get_option +EXPORT_SYMBOL vmlinux 0x00000000 get_options +EXPORT_SYMBOL vmlinux 0x00000000 get_random_bytes +EXPORT_SYMBOL vmlinux 0x00000000 get_sb_bdev +EXPORT_SYMBOL vmlinux 0x00000000 get_sb_nodev +EXPORT_SYMBOL vmlinux 0x00000000 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x00000000 get_sb_single +EXPORT_SYMBOL vmlinux 0x00000000 get_seconds +EXPORT_SYMBOL vmlinux 0x00000000 get_super +EXPORT_SYMBOL vmlinux 0x00000000 get_unmapped_area +EXPORT_SYMBOL vmlinux 0x00000000 get_unused_fd +EXPORT_SYMBOL vmlinux 0x00000000 get_user_pages +EXPORT_SYMBOL vmlinux 0x00000000 get_write_access +EXPORT_SYMBOL vmlinux 0x00000000 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x00000000 getname +EXPORT_SYMBOL vmlinux 0x00000000 getnstimeofday +EXPORT_SYMBOL vmlinux 0x00000000 getrawmonotonic +EXPORT_SYMBOL vmlinux 0x00000000 give_up_console +EXPORT_SYMBOL vmlinux 0x00000000 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x00000000 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x00000000 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x00000000 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x00000000 gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x00000000 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x00000000 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x00000000 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x00000000 groups_alloc +EXPORT_SYMBOL vmlinux 0x00000000 groups_free +EXPORT_SYMBOL vmlinux 0x00000000 half_md4_transform +EXPORT_SYMBOL vmlinux 0x00000000 handle_sysrq +EXPORT_SYMBOL vmlinux 0x00000000 have_submounts +EXPORT_SYMBOL vmlinux 0x00000000 hex_asc +EXPORT_SYMBOL vmlinux 0x00000000 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x00000000 high_memory +EXPORT_SYMBOL vmlinux 0x00000000 hweight16 +EXPORT_SYMBOL vmlinux 0x00000000 hweight32 +EXPORT_SYMBOL vmlinux 0x00000000 hweight64 +EXPORT_SYMBOL vmlinux 0x00000000 hweight8 +EXPORT_SYMBOL vmlinux 0x00000000 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x00000000 i2c_attach_client +EXPORT_SYMBOL vmlinux 0x00000000 i2c_bit_add_bus +EXPORT_SYMBOL vmlinux 0x00000000 i2c_bit_add_numbered_bus +EXPORT_SYMBOL vmlinux 0x00000000 i2c_clients_command +EXPORT_SYMBOL vmlinux 0x00000000 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x00000000 i2c_del_driver +EXPORT_SYMBOL vmlinux 0x00000000 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x00000000 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0x00000000 i2c_master_recv +EXPORT_SYMBOL vmlinux 0x00000000 i2c_master_send +EXPORT_SYMBOL vmlinux 0x00000000 i2c_probe +EXPORT_SYMBOL vmlinux 0x00000000 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x00000000 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x00000000 i2c_release_client +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0x00000000 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x00000000 i2c_transfer +EXPORT_SYMBOL vmlinux 0x00000000 i2c_use_client +EXPORT_SYMBOL vmlinux 0x00000000 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x00000000 icmp_err_convert +EXPORT_SYMBOL vmlinux 0x00000000 icmp_send +EXPORT_SYMBOL vmlinux 0x00000000 icst307_khz +EXPORT_SYMBOL vmlinux 0x00000000 icst307_khz_to_vco +EXPORT_SYMBOL vmlinux 0x00000000 icst307_ps_to_vco +EXPORT_SYMBOL vmlinux 0x00000000 ida_destroy +EXPORT_SYMBOL vmlinux 0x00000000 ida_get_new +EXPORT_SYMBOL vmlinux 0x00000000 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x00000000 ida_init +EXPORT_SYMBOL vmlinux 0x00000000 ida_pre_get +EXPORT_SYMBOL vmlinux 0x00000000 ida_remove +EXPORT_SYMBOL vmlinux 0x00000000 idr_destroy +EXPORT_SYMBOL vmlinux 0x00000000 idr_find +EXPORT_SYMBOL vmlinux 0x00000000 idr_for_each +EXPORT_SYMBOL vmlinux 0x00000000 idr_get_new +EXPORT_SYMBOL vmlinux 0x00000000 idr_get_new_above +EXPORT_SYMBOL vmlinux 0x00000000 idr_init +EXPORT_SYMBOL vmlinux 0x00000000 idr_pre_get +EXPORT_SYMBOL vmlinux 0x00000000 idr_remove +EXPORT_SYMBOL vmlinux 0x00000000 idr_remove_all +EXPORT_SYMBOL vmlinux 0x00000000 idr_replace +EXPORT_SYMBOL vmlinux 0x00000000 ifla_policy +EXPORT_SYMBOL vmlinux 0x00000000 iget5_locked +EXPORT_SYMBOL vmlinux 0x00000000 iget_failed +EXPORT_SYMBOL vmlinux 0x00000000 iget_locked +EXPORT_SYMBOL vmlinux 0x00000000 igrab +EXPORT_SYMBOL vmlinux 0x00000000 ilookup +EXPORT_SYMBOL vmlinux 0x00000000 ilookup5 +EXPORT_SYMBOL vmlinux 0x00000000 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x00000000 in4_pton +EXPORT_SYMBOL vmlinux 0x00000000 in6_pton +EXPORT_SYMBOL vmlinux 0x00000000 in_aton +EXPORT_SYMBOL vmlinux 0x00000000 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x00000000 in_egroup_p +EXPORT_SYMBOL vmlinux 0x00000000 in_group_p +EXPORT_SYMBOL vmlinux 0x00000000 inet_accept +EXPORT_SYMBOL vmlinux 0x00000000 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x00000000 inet_addr_type +EXPORT_SYMBOL vmlinux 0x00000000 inet_bind +EXPORT_SYMBOL vmlinux 0x00000000 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x00000000 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x00000000 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x00000000 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x00000000 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x00000000 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x00000000 inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x00000000 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x00000000 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x00000000 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x00000000 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x00000000 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0x00000000 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0x00000000 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x00000000 inet_frag_find +EXPORT_SYMBOL vmlinux 0x00000000 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x00000000 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x00000000 inet_frags_fini +EXPORT_SYMBOL vmlinux 0x00000000 inet_frags_init +EXPORT_SYMBOL vmlinux 0x00000000 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x00000000 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x00000000 inet_getname +EXPORT_SYMBOL vmlinux 0x00000000 inet_ioctl +EXPORT_SYMBOL vmlinux 0x00000000 inet_listen +EXPORT_SYMBOL vmlinux 0x00000000 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x00000000 inet_put_port +EXPORT_SYMBOL vmlinux 0x00000000 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x00000000 inet_release +EXPORT_SYMBOL vmlinux 0x00000000 inet_select_addr +EXPORT_SYMBOL vmlinux 0x00000000 inet_sendmsg +EXPORT_SYMBOL vmlinux 0x00000000 inet_shutdown +EXPORT_SYMBOL vmlinux 0x00000000 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x00000000 inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x00000000 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x00000000 inet_stream_ops +EXPORT_SYMBOL vmlinux 0x00000000 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x00000000 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x00000000 inetdev_by_index +EXPORT_SYMBOL vmlinux 0x00000000 init_buffer +EXPORT_SYMBOL vmlinux 0x00000000 init_file +EXPORT_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_SYMBOL vmlinux 0x00000000 init_net +EXPORT_SYMBOL vmlinux 0x00000000 init_special_inode +EXPORT_SYMBOL vmlinux 0x00000000 init_task +EXPORT_SYMBOL vmlinux 0x00000000 init_timer +EXPORT_SYMBOL vmlinux 0x00000000 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x00000000 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x00000000 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x00000000 inode_change_ok +EXPORT_SYMBOL vmlinux 0x00000000 inode_double_lock +EXPORT_SYMBOL vmlinux 0x00000000 inode_double_unlock +EXPORT_SYMBOL vmlinux 0x00000000 inode_get_bytes +EXPORT_SYMBOL vmlinux 0x00000000 inode_init_once +EXPORT_SYMBOL vmlinux 0x00000000 inode_needs_sync +EXPORT_SYMBOL vmlinux 0x00000000 inode_permission +EXPORT_SYMBOL vmlinux 0x00000000 inode_set_bytes +EXPORT_SYMBOL vmlinux 0x00000000 inode_setattr +EXPORT_SYMBOL vmlinux 0x00000000 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0x00000000 input_allocate_device +EXPORT_SYMBOL vmlinux 0x00000000 input_close_device +EXPORT_SYMBOL vmlinux 0x00000000 input_event +EXPORT_SYMBOL vmlinux 0x00000000 input_flush_device +EXPORT_SYMBOL vmlinux 0x00000000 input_free_device +EXPORT_SYMBOL vmlinux 0x00000000 input_get_keycode +EXPORT_SYMBOL vmlinux 0x00000000 input_grab_device +EXPORT_SYMBOL vmlinux 0x00000000 input_inject_event +EXPORT_SYMBOL vmlinux 0x00000000 input_open_device +EXPORT_SYMBOL vmlinux 0x00000000 input_register_device +EXPORT_SYMBOL vmlinux 0x00000000 input_register_handle +EXPORT_SYMBOL vmlinux 0x00000000 input_register_handler +EXPORT_SYMBOL vmlinux 0x00000000 input_release_device +EXPORT_SYMBOL vmlinux 0x00000000 input_set_capability +EXPORT_SYMBOL vmlinux 0x00000000 input_set_keycode +EXPORT_SYMBOL vmlinux 0x00000000 input_unregister_device +EXPORT_SYMBOL vmlinux 0x00000000 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x00000000 input_unregister_handler +EXPORT_SYMBOL vmlinux 0x00000000 int_sqrt +EXPORT_SYMBOL vmlinux 0x00000000 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0x00000000 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x00000000 invalidate_bdev +EXPORT_SYMBOL vmlinux 0x00000000 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x00000000 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x00000000 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x00000000 invalidate_partition +EXPORT_SYMBOL vmlinux 0x00000000 io_schedule +EXPORT_SYMBOL vmlinux 0x00000000 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x00000000 iomem_resource +EXPORT_SYMBOL vmlinux 0x00000000 ioport_map +EXPORT_SYMBOL vmlinux 0x00000000 ioport_resource +EXPORT_SYMBOL vmlinux 0x00000000 ioport_unmap +EXPORT_SYMBOL vmlinux 0x00000000 iov_iter_advance +EXPORT_SYMBOL vmlinux 0x00000000 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x00000000 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x00000000 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x00000000 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0x00000000 iov_shorten +EXPORT_SYMBOL vmlinux 0x00000000 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x00000000 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x00000000 ip_defrag +EXPORT_SYMBOL vmlinux 0x00000000 ip_dev_find +EXPORT_SYMBOL vmlinux 0x00000000 ip_fragment +EXPORT_SYMBOL vmlinux 0x00000000 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0x00000000 ip_getsockopt +EXPORT_SYMBOL vmlinux 0x00000000 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x00000000 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x00000000 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x00000000 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x00000000 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x00000000 ip_route_input +EXPORT_SYMBOL vmlinux 0x00000000 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x00000000 ip_send_check +EXPORT_SYMBOL vmlinux 0x00000000 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x00000000 iput +EXPORT_SYMBOL vmlinux 0x00000000 ipv4_config +EXPORT_SYMBOL vmlinux 0x00000000 ipv4_specific +EXPORT_SYMBOL vmlinux 0x00000000 irq_stat +EXPORT_SYMBOL vmlinux 0x00000000 is_bad_inode +EXPORT_SYMBOL vmlinux 0x00000000 is_container_init +EXPORT_SYMBOL vmlinux 0x00000000 iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0x00000000 iunique +EXPORT_SYMBOL vmlinux 0x00000000 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x00000000 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x00000000 iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x00000000 iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x00000000 jiffies +EXPORT_SYMBOL vmlinux 0x00000000 jiffies_64 +EXPORT_SYMBOL vmlinux 0x00000000 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0x00000000 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x00000000 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x00000000 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x00000000 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0x00000000 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x00000000 journal_abort +EXPORT_SYMBOL vmlinux 0x00000000 journal_ack_err +EXPORT_SYMBOL vmlinux 0x00000000 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x00000000 journal_check_available_features +EXPORT_SYMBOL vmlinux 0x00000000 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x00000000 journal_clear_err +EXPORT_SYMBOL vmlinux 0x00000000 journal_create +EXPORT_SYMBOL vmlinux 0x00000000 journal_destroy +EXPORT_SYMBOL vmlinux 0x00000000 journal_dirty_data +EXPORT_SYMBOL vmlinux 0x00000000 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x00000000 journal_errno +EXPORT_SYMBOL vmlinux 0x00000000 journal_extend +EXPORT_SYMBOL vmlinux 0x00000000 journal_flush +EXPORT_SYMBOL vmlinux 0x00000000 journal_force_commit +EXPORT_SYMBOL vmlinux 0x00000000 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x00000000 journal_forget +EXPORT_SYMBOL vmlinux 0x00000000 journal_get_create_access +EXPORT_SYMBOL vmlinux 0x00000000 journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x00000000 journal_get_write_access +EXPORT_SYMBOL vmlinux 0x00000000 journal_init_dev +EXPORT_SYMBOL vmlinux 0x00000000 journal_init_inode +EXPORT_SYMBOL vmlinux 0x00000000 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x00000000 journal_load +EXPORT_SYMBOL vmlinux 0x00000000 journal_lock_updates +EXPORT_SYMBOL vmlinux 0x00000000 journal_release_buffer +EXPORT_SYMBOL vmlinux 0x00000000 journal_restart +EXPORT_SYMBOL vmlinux 0x00000000 journal_revoke +EXPORT_SYMBOL vmlinux 0x00000000 journal_set_features +EXPORT_SYMBOL vmlinux 0x00000000 journal_start +EXPORT_SYMBOL vmlinux 0x00000000 journal_start_commit +EXPORT_SYMBOL vmlinux 0x00000000 journal_stop +EXPORT_SYMBOL vmlinux 0x00000000 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x00000000 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x00000000 journal_update_format +EXPORT_SYMBOL vmlinux 0x00000000 journal_wipe +EXPORT_SYMBOL vmlinux 0x00000000 kasprintf +EXPORT_SYMBOL vmlinux 0x00000000 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x00000000 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x00000000 kd_mksound +EXPORT_SYMBOL vmlinux 0x00000000 kern_fp_enter +EXPORT_SYMBOL vmlinux 0x00000000 kern_path +EXPORT_SYMBOL vmlinux 0x00000000 kernel_accept +EXPORT_SYMBOL vmlinux 0x00000000 kernel_bind +EXPORT_SYMBOL vmlinux 0x00000000 kernel_connect +EXPORT_SYMBOL vmlinux 0x00000000 kernel_execve +EXPORT_SYMBOL vmlinux 0x00000000 kernel_getpeername +EXPORT_SYMBOL vmlinux 0x00000000 kernel_getsockname +EXPORT_SYMBOL vmlinux 0x00000000 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x00000000 kernel_listen +EXPORT_SYMBOL vmlinux 0x00000000 kernel_read +EXPORT_SYMBOL vmlinux 0x00000000 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x00000000 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x00000000 kernel_sendpage +EXPORT_SYMBOL vmlinux 0x00000000 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x00000000 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x00000000 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x00000000 kernel_thread +EXPORT_SYMBOL vmlinux 0x00000000 kfifo_alloc +EXPORT_SYMBOL vmlinux 0x00000000 kfifo_free +EXPORT_SYMBOL vmlinux 0x00000000 kfifo_init +EXPORT_SYMBOL vmlinux 0x00000000 kfree +EXPORT_SYMBOL vmlinux 0x00000000 kfree_skb +EXPORT_SYMBOL vmlinux 0x00000000 kick_iocb +EXPORT_SYMBOL vmlinux 0x00000000 kill_anon_super +EXPORT_SYMBOL vmlinux 0x00000000 kill_block_super +EXPORT_SYMBOL vmlinux 0x00000000 kill_fasync +EXPORT_SYMBOL vmlinux 0x00000000 kill_litter_super +EXPORT_SYMBOL vmlinux 0x00000000 kill_pgrp +EXPORT_SYMBOL vmlinux 0x00000000 kill_pid +EXPORT_SYMBOL vmlinux 0x00000000 km_new_mapping +EXPORT_SYMBOL vmlinux 0x00000000 km_policy_expired +EXPORT_SYMBOL vmlinux 0x00000000 km_policy_notify +EXPORT_SYMBOL vmlinux 0x00000000 km_query +EXPORT_SYMBOL vmlinux 0x00000000 km_report +EXPORT_SYMBOL vmlinux 0x00000000 km_state_expired +EXPORT_SYMBOL vmlinux 0x00000000 km_state_notify +EXPORT_SYMBOL vmlinux 0x00000000 km_waitq +EXPORT_SYMBOL vmlinux 0x00000000 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x00000000 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x00000000 kmem_cache_create +EXPORT_SYMBOL vmlinux 0x00000000 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x00000000 kmem_cache_free +EXPORT_SYMBOL vmlinux 0x00000000 kmem_cache_name +EXPORT_SYMBOL vmlinux 0x00000000 kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x00000000 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x00000000 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0x00000000 kmemdup +EXPORT_SYMBOL vmlinux 0x00000000 kobject_add +EXPORT_SYMBOL vmlinux 0x00000000 kobject_del +EXPORT_SYMBOL vmlinux 0x00000000 kobject_get +EXPORT_SYMBOL vmlinux 0x00000000 kobject_init +EXPORT_SYMBOL vmlinux 0x00000000 kobject_put +EXPORT_SYMBOL vmlinux 0x00000000 kobject_set_name +EXPORT_SYMBOL vmlinux 0x00000000 krealloc +EXPORT_SYMBOL vmlinux 0x00000000 kref_get +EXPORT_SYMBOL vmlinux 0x00000000 kref_init +EXPORT_SYMBOL vmlinux 0x00000000 kref_put +EXPORT_SYMBOL vmlinux 0x00000000 kref_set +EXPORT_SYMBOL vmlinux 0x00000000 kset_register +EXPORT_SYMBOL vmlinux 0x00000000 kset_unregister +EXPORT_SYMBOL vmlinux 0x00000000 kstrdup +EXPORT_SYMBOL vmlinux 0x00000000 kstrndup +EXPORT_SYMBOL vmlinux 0x00000000 kthread_bind +EXPORT_SYMBOL vmlinux 0x00000000 kthread_create +EXPORT_SYMBOL vmlinux 0x00000000 kthread_should_stop +EXPORT_SYMBOL vmlinux 0x00000000 kthread_stop +EXPORT_SYMBOL vmlinux 0x00000000 kvasprintf +EXPORT_SYMBOL vmlinux 0x00000000 laptop_mode +EXPORT_SYMBOL vmlinux 0x00000000 lease_get_mtime +EXPORT_SYMBOL vmlinux 0x00000000 lease_modify +EXPORT_SYMBOL vmlinux 0x00000000 leds_event +EXPORT_SYMBOL vmlinux 0x00000000 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0x00000000 ll_rw_block +EXPORT_SYMBOL vmlinux 0x00000000 local_bh_disable +EXPORT_SYMBOL vmlinux 0x00000000 local_bh_enable +EXPORT_SYMBOL vmlinux 0x00000000 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0x00000000 lock_may_read +EXPORT_SYMBOL vmlinux 0x00000000 lock_may_write +EXPORT_SYMBOL vmlinux 0x00000000 lock_rename +EXPORT_SYMBOL vmlinux 0x00000000 lock_sock_nested +EXPORT_SYMBOL vmlinux 0x00000000 lock_super +EXPORT_SYMBOL vmlinux 0x00000000 lockd_down +EXPORT_SYMBOL vmlinux 0x00000000 lockd_up +EXPORT_SYMBOL vmlinux 0x00000000 locks_copy_lock +EXPORT_SYMBOL vmlinux 0x00000000 locks_init_lock +EXPORT_SYMBOL vmlinux 0x00000000 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x00000000 locks_remove_posix +EXPORT_SYMBOL vmlinux 0x00000000 log_wait_commit +EXPORT_SYMBOL vmlinux 0x00000000 lookup_bdev +EXPORT_SYMBOL vmlinux 0x00000000 lookup_one_len +EXPORT_SYMBOL vmlinux 0x00000000 loop_register_transfer +EXPORT_SYMBOL vmlinux 0x00000000 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0x00000000 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0x00000000 make_bad_inode +EXPORT_SYMBOL vmlinux 0x00000000 map_destroy +EXPORT_SYMBOL vmlinux 0x00000000 mapping_tagged +EXPORT_SYMBOL vmlinux 0x00000000 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x00000000 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x00000000 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x00000000 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x00000000 match_hex +EXPORT_SYMBOL vmlinux 0x00000000 match_int +EXPORT_SYMBOL vmlinux 0x00000000 match_octal +EXPORT_SYMBOL vmlinux 0x00000000 match_strdup +EXPORT_SYMBOL vmlinux 0x00000000 match_strlcpy +EXPORT_SYMBOL vmlinux 0x00000000 match_token +EXPORT_SYMBOL vmlinux 0x00000000 max_mapnr +EXPORT_SYMBOL vmlinux 0x00000000 may_umount +EXPORT_SYMBOL vmlinux 0x00000000 may_umount_tree +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_create +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x00000000 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x00000000 mem_map +EXPORT_SYMBOL vmlinux 0x00000000 memchr +EXPORT_SYMBOL vmlinux 0x00000000 memcmp +EXPORT_SYMBOL vmlinux 0x00000000 memcpy +EXPORT_SYMBOL vmlinux 0x00000000 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x00000000 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x00000000 memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x00000000 memmove +EXPORT_SYMBOL vmlinux 0x00000000 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x00000000 memparse +EXPORT_SYMBOL vmlinux 0x00000000 mempool_alloc +EXPORT_SYMBOL vmlinux 0x00000000 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x00000000 mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x00000000 mempool_create +EXPORT_SYMBOL vmlinux 0x00000000 mempool_create_node +EXPORT_SYMBOL vmlinux 0x00000000 mempool_destroy +EXPORT_SYMBOL vmlinux 0x00000000 mempool_free +EXPORT_SYMBOL vmlinux 0x00000000 mempool_free_pages +EXPORT_SYMBOL vmlinux 0x00000000 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x00000000 mempool_kfree +EXPORT_SYMBOL vmlinux 0x00000000 mempool_kmalloc +EXPORT_SYMBOL vmlinux 0x00000000 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x00000000 mempool_resize +EXPORT_SYMBOL vmlinux 0x00000000 memscan +EXPORT_SYMBOL vmlinux 0x00000000 memset +EXPORT_SYMBOL vmlinux 0x00000000 mii_check_gmii_support +EXPORT_SYMBOL vmlinux 0x00000000 mii_check_link +EXPORT_SYMBOL vmlinux 0x00000000 mii_check_media +EXPORT_SYMBOL vmlinux 0x00000000 mii_ethtool_gset +EXPORT_SYMBOL vmlinux 0x00000000 mii_ethtool_sset +EXPORT_SYMBOL vmlinux 0x00000000 mii_link_ok +EXPORT_SYMBOL vmlinux 0x00000000 mii_nway_restart +EXPORT_SYMBOL vmlinux 0x00000000 misc_deregister +EXPORT_SYMBOL vmlinux 0x00000000 misc_register +EXPORT_SYMBOL vmlinux 0x00000000 mktime +EXPORT_SYMBOL vmlinux 0x00000000 mmc_add_host +EXPORT_SYMBOL vmlinux 0x00000000 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x00000000 mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x00000000 mmc_cleanup_queue +EXPORT_SYMBOL vmlinux 0x00000000 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x00000000 mmc_free_host +EXPORT_SYMBOL vmlinux 0x00000000 mmc_register_driver +EXPORT_SYMBOL vmlinux 0x00000000 mmc_release_host +EXPORT_SYMBOL vmlinux 0x00000000 mmc_remove_host +EXPORT_SYMBOL vmlinux 0x00000000 mmc_request_done +EXPORT_SYMBOL vmlinux 0x00000000 mmc_resume_host +EXPORT_SYMBOL vmlinux 0x00000000 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0x00000000 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x00000000 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0x00000000 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0x00000000 mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x00000000 mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0x00000000 mnt_pin +EXPORT_SYMBOL vmlinux 0x00000000 mnt_unpin +EXPORT_SYMBOL vmlinux 0x00000000 mntput_no_expire +EXPORT_SYMBOL vmlinux 0x00000000 mod_timer +EXPORT_SYMBOL vmlinux 0x00000000 module_put +EXPORT_SYMBOL vmlinux 0x00000000 module_refcount +EXPORT_SYMBOL vmlinux 0x00000000 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0x00000000 mpage_readpage +EXPORT_SYMBOL vmlinux 0x00000000 mpage_readpages +EXPORT_SYMBOL vmlinux 0x00000000 mpage_writepage +EXPORT_SYMBOL vmlinux 0x00000000 mpage_writepages +EXPORT_SYMBOL vmlinux 0x00000000 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 msleep +EXPORT_SYMBOL vmlinux 0x00000000 msleep_interruptible +EXPORT_SYMBOL vmlinux 0x00000000 mtd_do_chip_probe +EXPORT_SYMBOL vmlinux 0x00000000 mutex_lock +EXPORT_SYMBOL vmlinux 0x00000000 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x00000000 mutex_lock_killable +EXPORT_SYMBOL vmlinux 0x00000000 mutex_trylock +EXPORT_SYMBOL vmlinux 0x00000000 mutex_unlock +EXPORT_SYMBOL vmlinux 0x00000000 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x00000000 names_cachep +EXPORT_SYMBOL vmlinux 0x00000000 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x00000000 neigh_compat_output +EXPORT_SYMBOL vmlinux 0x00000000 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x00000000 neigh_create +EXPORT_SYMBOL vmlinux 0x00000000 neigh_destroy +EXPORT_SYMBOL vmlinux 0x00000000 neigh_event_ns +EXPORT_SYMBOL vmlinux 0x00000000 neigh_for_each +EXPORT_SYMBOL vmlinux 0x00000000 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x00000000 neigh_lookup +EXPORT_SYMBOL vmlinux 0x00000000 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x00000000 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x00000000 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x00000000 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x00000000 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x00000000 neigh_seq_next +EXPORT_SYMBOL vmlinux 0x00000000 neigh_seq_start +EXPORT_SYMBOL vmlinux 0x00000000 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x00000000 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x00000000 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x00000000 neigh_table_clear +EXPORT_SYMBOL vmlinux 0x00000000 neigh_table_init +EXPORT_SYMBOL vmlinux 0x00000000 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x00000000 neigh_update +EXPORT_SYMBOL vmlinux 0x00000000 net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x00000000 net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x00000000 net_msg_warn +EXPORT_SYMBOL vmlinux 0x00000000 net_ratelimit +EXPORT_SYMBOL vmlinux 0x00000000 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x00000000 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x00000000 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x00000000 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x00000000 netdev_features_change +EXPORT_SYMBOL vmlinux 0x00000000 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x00000000 netdev_increment_features +EXPORT_SYMBOL vmlinux 0x00000000 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x00000000 netdev_set_master +EXPORT_SYMBOL vmlinux 0x00000000 netdev_state_change +EXPORT_SYMBOL vmlinux 0x00000000 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x00000000 netif_carrier_on +EXPORT_SYMBOL vmlinux 0x00000000 netif_device_attach +EXPORT_SYMBOL vmlinux 0x00000000 netif_device_detach +EXPORT_SYMBOL vmlinux 0x00000000 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x00000000 netif_rx +EXPORT_SYMBOL vmlinux 0x00000000 netif_rx_ni +EXPORT_SYMBOL vmlinux 0x00000000 netlink_ack +EXPORT_SYMBOL vmlinux 0x00000000 netlink_broadcast +EXPORT_SYMBOL vmlinux 0x00000000 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x00000000 netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x00000000 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x00000000 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x00000000 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x00000000 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x00000000 netlink_register_notifier +EXPORT_SYMBOL vmlinux 0x00000000 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x00000000 netlink_unicast +EXPORT_SYMBOL vmlinux 0x00000000 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0x00000000 new_inode +EXPORT_SYMBOL vmlinux 0x00000000 nla_append +EXPORT_SYMBOL vmlinux 0x00000000 nla_find +EXPORT_SYMBOL vmlinux 0x00000000 nla_memcmp +EXPORT_SYMBOL vmlinux 0x00000000 nla_memcpy +EXPORT_SYMBOL vmlinux 0x00000000 nla_parse +EXPORT_SYMBOL vmlinux 0x00000000 nla_put +EXPORT_SYMBOL vmlinux 0x00000000 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x00000000 nla_reserve +EXPORT_SYMBOL vmlinux 0x00000000 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x00000000 nla_strcmp +EXPORT_SYMBOL vmlinux 0x00000000 nla_strlcpy +EXPORT_SYMBOL vmlinux 0x00000000 nla_validate +EXPORT_SYMBOL vmlinux 0x00000000 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x00000000 nlmsvc_ops +EXPORT_SYMBOL vmlinux 0x00000000 no_llseek +EXPORT_SYMBOL vmlinux 0x00000000 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x00000000 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x00000000 nobh_write_end +EXPORT_SYMBOL vmlinux 0x00000000 nobh_writepage +EXPORT_SYMBOL vmlinux 0x00000000 node_states +EXPORT_SYMBOL vmlinux 0x00000000 nonseekable_open +EXPORT_SYMBOL vmlinux 0x00000000 noop_qdisc +EXPORT_SYMBOL vmlinux 0x00000000 notify_change +EXPORT_SYMBOL vmlinux 0x00000000 ns_to_timespec +EXPORT_SYMBOL vmlinux 0x00000000 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x00000000 num_physpages +EXPORT_SYMBOL vmlinux 0x00000000 num_registered_fb +EXPORT_SYMBOL vmlinux 0x00000000 oops_in_progress +EXPORT_SYMBOL vmlinux 0x00000000 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x00000000 open_by_devnum +EXPORT_SYMBOL vmlinux 0x00000000 open_exec +EXPORT_SYMBOL vmlinux 0x00000000 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0x00000000 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0x00000000 overflowgid +EXPORT_SYMBOL vmlinux 0x00000000 overflowuid +EXPORT_SYMBOL vmlinux 0x00000000 page_follow_link_light +EXPORT_SYMBOL vmlinux 0x00000000 page_put_link +EXPORT_SYMBOL vmlinux 0x00000000 page_readlink +EXPORT_SYMBOL vmlinux 0x00000000 page_symlink +EXPORT_SYMBOL vmlinux 0x00000000 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x00000000 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x00000000 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x00000000 pagecache_write_end +EXPORT_SYMBOL vmlinux 0x00000000 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x00000000 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0x00000000 panic +EXPORT_SYMBOL vmlinux 0x00000000 panic_blink +EXPORT_SYMBOL vmlinux 0x00000000 panic_notifier_list +EXPORT_SYMBOL vmlinux 0x00000000 param_array_get +EXPORT_SYMBOL vmlinux 0x00000000 param_array_set +EXPORT_SYMBOL vmlinux 0x00000000 param_get_bool +EXPORT_SYMBOL vmlinux 0x00000000 param_get_byte +EXPORT_SYMBOL vmlinux 0x00000000 param_get_charp +EXPORT_SYMBOL vmlinux 0x00000000 param_get_int +EXPORT_SYMBOL vmlinux 0x00000000 param_get_invbool +EXPORT_SYMBOL vmlinux 0x00000000 param_get_long +EXPORT_SYMBOL vmlinux 0x00000000 param_get_short +EXPORT_SYMBOL vmlinux 0x00000000 param_get_string +EXPORT_SYMBOL vmlinux 0x00000000 param_get_uint +EXPORT_SYMBOL vmlinux 0x00000000 param_get_ulong +EXPORT_SYMBOL vmlinux 0x00000000 param_get_ushort +EXPORT_SYMBOL vmlinux 0x00000000 param_set_bool +EXPORT_SYMBOL vmlinux 0x00000000 param_set_byte +EXPORT_SYMBOL vmlinux 0x00000000 param_set_charp +EXPORT_SYMBOL vmlinux 0x00000000 param_set_copystring +EXPORT_SYMBOL vmlinux 0x00000000 param_set_int +EXPORT_SYMBOL vmlinux 0x00000000 param_set_invbool +EXPORT_SYMBOL vmlinux 0x00000000 param_set_long +EXPORT_SYMBOL vmlinux 0x00000000 param_set_short +EXPORT_SYMBOL vmlinux 0x00000000 param_set_uint +EXPORT_SYMBOL vmlinux 0x00000000 param_set_ulong +EXPORT_SYMBOL vmlinux 0x00000000 param_set_ushort +EXPORT_SYMBOL vmlinux 0x00000000 path_get +EXPORT_SYMBOL vmlinux 0x00000000 path_lookup +EXPORT_SYMBOL vmlinux 0x00000000 path_permission +EXPORT_SYMBOL vmlinux 0x00000000 path_put +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x00000000 pgprot_kernel +EXPORT_SYMBOL vmlinux 0x00000000 pgprot_user +EXPORT_SYMBOL vmlinux 0x00000000 pid_task +EXPORT_SYMBOL vmlinux 0x00000000 pm_flags +EXPORT_SYMBOL vmlinux 0x00000000 pm_idle +EXPORT_SYMBOL vmlinux 0x00000000 pm_power_off +EXPORT_SYMBOL vmlinux 0x00000000 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x00000000 pm_suspend +EXPORT_SYMBOL vmlinux 0x00000000 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x00000000 pneigh_lookup +EXPORT_SYMBOL vmlinux 0x00000000 poll_freewait +EXPORT_SYMBOL vmlinux 0x00000000 poll_initwait +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_alloc +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_clone +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_permission +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x00000000 posix_acl_valid +EXPORT_SYMBOL vmlinux 0x00000000 posix_lock_file +EXPORT_SYMBOL vmlinux 0x00000000 posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x00000000 posix_test_lock +EXPORT_SYMBOL vmlinux 0x00000000 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x00000000 prepare_binprm +EXPORT_SYMBOL vmlinux 0x00000000 prepare_to_wait +EXPORT_SYMBOL vmlinux 0x00000000 prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x00000000 print_hex_dump +EXPORT_SYMBOL vmlinux 0x00000000 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x00000000 print_mac +EXPORT_SYMBOL vmlinux 0x00000000 printk +EXPORT_SYMBOL vmlinux 0x00000000 printk_ratelimit +EXPORT_SYMBOL vmlinux 0x00000000 printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x00000000 probe_irq_mask +EXPORT_SYMBOL vmlinux 0x00000000 probe_irq_off +EXPORT_SYMBOL vmlinux 0x00000000 probe_irq_on +EXPORT_SYMBOL vmlinux 0x00000000 proc_create_data +EXPORT_SYMBOL vmlinux 0x00000000 proc_dointvec +EXPORT_SYMBOL vmlinux 0x00000000 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x00000000 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 proc_dostring +EXPORT_SYMBOL vmlinux 0x00000000 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x00000000 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x00000000 proc_mkdir +EXPORT_SYMBOL vmlinux 0x00000000 proc_symlink +EXPORT_SYMBOL vmlinux 0x00000000 processor_id +EXPORT_SYMBOL vmlinux 0x00000000 proto_register +EXPORT_SYMBOL vmlinux 0x00000000 proto_unregister +EXPORT_SYMBOL vmlinux 0x00000000 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x00000000 ps2_command +EXPORT_SYMBOL vmlinux 0x00000000 ps2_drain +EXPORT_SYMBOL vmlinux 0x00000000 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0x00000000 ps2_handle_response +EXPORT_SYMBOL vmlinux 0x00000000 ps2_init +EXPORT_SYMBOL vmlinux 0x00000000 ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x00000000 ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x00000000 pskb_copy +EXPORT_SYMBOL vmlinux 0x00000000 pskb_expand_head +EXPORT_SYMBOL vmlinux 0x00000000 put_cmsg +EXPORT_SYMBOL vmlinux 0x00000000 put_disk +EXPORT_SYMBOL vmlinux 0x00000000 put_filp +EXPORT_SYMBOL vmlinux 0x00000000 put_io_context +EXPORT_SYMBOL vmlinux 0x00000000 put_page +EXPORT_SYMBOL vmlinux 0x00000000 put_pages_list +EXPORT_SYMBOL vmlinux 0x00000000 put_tty_driver +EXPORT_SYMBOL vmlinux 0x00000000 put_unused_fd +EXPORT_SYMBOL vmlinux 0x00000000 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x00000000 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x00000000 qdisc_reset +EXPORT_SYMBOL vmlinux 0x00000000 qword_add +EXPORT_SYMBOL vmlinux 0x00000000 qword_addhex +EXPORT_SYMBOL vmlinux 0x00000000 qword_get +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_insert +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0x00000000 radix_tree_tagged +EXPORT_SYMBOL vmlinux 0x00000000 random32 +EXPORT_SYMBOL vmlinux 0x00000000 rb_erase +EXPORT_SYMBOL vmlinux 0x00000000 rb_first +EXPORT_SYMBOL vmlinux 0x00000000 rb_insert_color +EXPORT_SYMBOL vmlinux 0x00000000 rb_last +EXPORT_SYMBOL vmlinux 0x00000000 rb_next +EXPORT_SYMBOL vmlinux 0x00000000 rb_prev +EXPORT_SYMBOL vmlinux 0x00000000 rb_replace_node +EXPORT_SYMBOL vmlinux 0x00000000 read_bytes_from_xdr_buf +EXPORT_SYMBOL vmlinux 0x00000000 read_cache_page +EXPORT_SYMBOL vmlinux 0x00000000 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x00000000 read_cache_pages +EXPORT_SYMBOL vmlinux 0x00000000 read_dev_sector +EXPORT_SYMBOL vmlinux 0x00000000 recalc_sigpending +EXPORT_SYMBOL vmlinux 0x00000000 redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x00000000 redraw_screen +EXPORT_SYMBOL vmlinux 0x00000000 refrigerator +EXPORT_SYMBOL vmlinux 0x00000000 register_binfmt +EXPORT_SYMBOL vmlinux 0x00000000 register_blkdev +EXPORT_SYMBOL vmlinux 0x00000000 register_chrdev +EXPORT_SYMBOL vmlinux 0x00000000 register_chrdev_region +EXPORT_SYMBOL vmlinux 0x00000000 register_con_driver +EXPORT_SYMBOL vmlinux 0x00000000 register_console +EXPORT_SYMBOL vmlinux 0x00000000 register_exec_domain +EXPORT_SYMBOL vmlinux 0x00000000 register_filesystem +EXPORT_SYMBOL vmlinux 0x00000000 register_framebuffer +EXPORT_SYMBOL vmlinux 0x00000000 register_gifconf +EXPORT_SYMBOL vmlinux 0x00000000 register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x00000000 register_module_notifier +EXPORT_SYMBOL vmlinux 0x00000000 register_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0x00000000 register_netdev +EXPORT_SYMBOL vmlinux 0x00000000 register_netdevice +EXPORT_SYMBOL vmlinux 0x00000000 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x00000000 register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x00000000 register_shrinker +EXPORT_SYMBOL vmlinux 0x00000000 register_sound_dsp +EXPORT_SYMBOL vmlinux 0x00000000 register_sound_midi +EXPORT_SYMBOL vmlinux 0x00000000 register_sound_mixer +EXPORT_SYMBOL vmlinux 0x00000000 register_sound_special +EXPORT_SYMBOL vmlinux 0x00000000 register_sound_special_device +EXPORT_SYMBOL vmlinux 0x00000000 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x00000000 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x00000000 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x00000000 registered_fb +EXPORT_SYMBOL vmlinux 0x00000000 release_console_sem +EXPORT_SYMBOL vmlinux 0x00000000 release_firmware +EXPORT_SYMBOL vmlinux 0x00000000 release_resource +EXPORT_SYMBOL vmlinux 0x00000000 release_sock +EXPORT_SYMBOL vmlinux 0x00000000 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x00000000 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x00000000 remove_arg_zero +EXPORT_SYMBOL vmlinux 0x00000000 remove_inode_hash +EXPORT_SYMBOL vmlinux 0x00000000 remove_proc_entry +EXPORT_SYMBOL vmlinux 0x00000000 remove_wait_queue +EXPORT_SYMBOL vmlinux 0x00000000 request_firmware +EXPORT_SYMBOL vmlinux 0x00000000 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x00000000 request_irq +EXPORT_SYMBOL vmlinux 0x00000000 request_module +EXPORT_SYMBOL vmlinux 0x00000000 request_resource +EXPORT_SYMBOL vmlinux 0x00000000 reset_devices +EXPORT_SYMBOL vmlinux 0x00000000 restore_time_delta +EXPORT_SYMBOL vmlinux 0x00000000 revalidate_disk +EXPORT_SYMBOL vmlinux 0x00000000 rpc_mkpipe +EXPORT_SYMBOL vmlinux 0x00000000 rpc_queue_upcall +EXPORT_SYMBOL vmlinux 0x00000000 rpc_unlink +EXPORT_SYMBOL vmlinux 0x00000000 rtc_month_days +EXPORT_SYMBOL vmlinux 0x00000000 rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0x00000000 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0x00000000 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x00000000 rtc_year_days +EXPORT_SYMBOL vmlinux 0x00000000 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_lock +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_notify +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_trylock +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x00000000 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x00000000 save_mount_options +EXPORT_SYMBOL vmlinux 0x00000000 save_time_delta +EXPORT_SYMBOL vmlinux 0x00000000 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x00000000 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x00000000 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x00000000 schedule +EXPORT_SYMBOL vmlinux 0x00000000 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x00000000 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x00000000 schedule_timeout +EXPORT_SYMBOL vmlinux 0x00000000 schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x00000000 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0x00000000 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0x00000000 schedule_work +EXPORT_SYMBOL vmlinux 0x00000000 schedule_work_on +EXPORT_SYMBOL vmlinux 0x00000000 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x00000000 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x00000000 scnprintf +EXPORT_SYMBOL vmlinux 0x00000000 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x00000000 scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x00000000 search_binary_handler +EXPORT_SYMBOL vmlinux 0x00000000 secpath_dup +EXPORT_SYMBOL vmlinux 0x00000000 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x00000000 send_sig +EXPORT_SYMBOL vmlinux 0x00000000 send_sig_info +EXPORT_SYMBOL vmlinux 0x00000000 seq_bitmap +EXPORT_SYMBOL vmlinux 0x00000000 seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x00000000 seq_escape +EXPORT_SYMBOL vmlinux 0x00000000 seq_list_next +EXPORT_SYMBOL vmlinux 0x00000000 seq_list_start +EXPORT_SYMBOL vmlinux 0x00000000 seq_list_start_head +EXPORT_SYMBOL vmlinux 0x00000000 seq_lseek +EXPORT_SYMBOL vmlinux 0x00000000 seq_open +EXPORT_SYMBOL vmlinux 0x00000000 seq_open_private +EXPORT_SYMBOL vmlinux 0x00000000 seq_path +EXPORT_SYMBOL vmlinux 0x00000000 seq_printf +EXPORT_SYMBOL vmlinux 0x00000000 seq_putc +EXPORT_SYMBOL vmlinux 0x00000000 seq_puts +EXPORT_SYMBOL vmlinux 0x00000000 seq_read +EXPORT_SYMBOL vmlinux 0x00000000 seq_release +EXPORT_SYMBOL vmlinux 0x00000000 seq_release_private +EXPORT_SYMBOL vmlinux 0x00000000 serio_close +EXPORT_SYMBOL vmlinux 0x00000000 serio_interrupt +EXPORT_SYMBOL vmlinux 0x00000000 serio_open +EXPORT_SYMBOL vmlinux 0x00000000 serio_reconnect +EXPORT_SYMBOL vmlinux 0x00000000 serio_rescan +EXPORT_SYMBOL vmlinux 0x00000000 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x00000000 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x00000000 serio_unregister_port +EXPORT_SYMBOL vmlinux 0x00000000 set_anon_super +EXPORT_SYMBOL vmlinux 0x00000000 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x00000000 set_bh_page +EXPORT_SYMBOL vmlinux 0x00000000 set_binfmt +EXPORT_SYMBOL vmlinux 0x00000000 set_blocksize +EXPORT_SYMBOL vmlinux 0x00000000 set_current_groups +EXPORT_SYMBOL vmlinux 0x00000000 set_device_ro +EXPORT_SYMBOL vmlinux 0x00000000 set_disk_ro +EXPORT_SYMBOL vmlinux 0x00000000 set_irq_chip +EXPORT_SYMBOL vmlinux 0x00000000 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x00000000 set_irq_data +EXPORT_SYMBOL vmlinux 0x00000000 set_irq_type +EXPORT_SYMBOL vmlinux 0x00000000 set_irq_wake +EXPORT_SYMBOL vmlinux 0x00000000 set_normalized_timespec +EXPORT_SYMBOL vmlinux 0x00000000 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x00000000 set_page_dirty +EXPORT_SYMBOL vmlinux 0x00000000 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x00000000 set_user_nice +EXPORT_SYMBOL vmlinux 0x00000000 setup_arg_pages +EXPORT_SYMBOL vmlinux 0x00000000 sg_alloc_table +EXPORT_SYMBOL vmlinux 0x00000000 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x00000000 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x00000000 sg_free_table +EXPORT_SYMBOL vmlinux 0x00000000 sg_init_one +EXPORT_SYMBOL vmlinux 0x00000000 sg_init_table +EXPORT_SYMBOL vmlinux 0x00000000 sg_last +EXPORT_SYMBOL vmlinux 0x00000000 sg_miter_next +EXPORT_SYMBOL vmlinux 0x00000000 sg_miter_start +EXPORT_SYMBOL vmlinux 0x00000000 sg_miter_stop +EXPORT_SYMBOL vmlinux 0x00000000 sg_next +EXPORT_SYMBOL vmlinux 0x00000000 sget +EXPORT_SYMBOL vmlinux 0x00000000 sha_transform +EXPORT_SYMBOL vmlinux 0x00000000 should_remove_suid +EXPORT_SYMBOL vmlinux 0x00000000 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x00000000 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x00000000 si_meminfo +EXPORT_SYMBOL vmlinux 0x00000000 sigprocmask +EXPORT_SYMBOL vmlinux 0x00000000 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x00000000 simple_dir_operations +EXPORT_SYMBOL vmlinux 0x00000000 simple_empty +EXPORT_SYMBOL vmlinux 0x00000000 simple_fill_super +EXPORT_SYMBOL vmlinux 0x00000000 simple_getattr +EXPORT_SYMBOL vmlinux 0x00000000 simple_link +EXPORT_SYMBOL vmlinux 0x00000000 simple_lookup +EXPORT_SYMBOL vmlinux 0x00000000 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x00000000 simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x00000000 simple_readpage +EXPORT_SYMBOL vmlinux 0x00000000 simple_release_fs +EXPORT_SYMBOL vmlinux 0x00000000 simple_rename +EXPORT_SYMBOL vmlinux 0x00000000 simple_rmdir +EXPORT_SYMBOL vmlinux 0x00000000 simple_set_mnt +EXPORT_SYMBOL vmlinux 0x00000000 simple_statfs +EXPORT_SYMBOL vmlinux 0x00000000 simple_strtol +EXPORT_SYMBOL vmlinux 0x00000000 simple_strtoul +EXPORT_SYMBOL vmlinux 0x00000000 simple_strtoull +EXPORT_SYMBOL vmlinux 0x00000000 simple_sync_file +EXPORT_SYMBOL vmlinux 0x00000000 simple_transaction_get +EXPORT_SYMBOL vmlinux 0x00000000 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x00000000 simple_transaction_release +EXPORT_SYMBOL vmlinux 0x00000000 simple_unlink +EXPORT_SYMBOL vmlinux 0x00000000 simple_write_begin +EXPORT_SYMBOL vmlinux 0x00000000 simple_write_end +EXPORT_SYMBOL vmlinux 0x00000000 single_open +EXPORT_SYMBOL vmlinux 0x00000000 single_release +EXPORT_SYMBOL vmlinux 0x00000000 sk_alloc +EXPORT_SYMBOL vmlinux 0x00000000 sk_chk_filter +EXPORT_SYMBOL vmlinux 0x00000000 sk_common_release +EXPORT_SYMBOL vmlinux 0x00000000 sk_dst_check +EXPORT_SYMBOL vmlinux 0x00000000 sk_filter +EXPORT_SYMBOL vmlinux 0x00000000 sk_free +EXPORT_SYMBOL vmlinux 0x00000000 sk_receive_skb +EXPORT_SYMBOL vmlinux 0x00000000 sk_release_kernel +EXPORT_SYMBOL vmlinux 0x00000000 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x00000000 sk_run_filter +EXPORT_SYMBOL vmlinux 0x00000000 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x00000000 sk_stop_timer +EXPORT_SYMBOL vmlinux 0x00000000 sk_stream_error +EXPORT_SYMBOL vmlinux 0x00000000 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x00000000 sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x00000000 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x00000000 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x00000000 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x00000000 sk_wait_data +EXPORT_SYMBOL vmlinux 0x00000000 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x00000000 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x00000000 skb_append +EXPORT_SYMBOL vmlinux 0x00000000 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x00000000 skb_checksum +EXPORT_SYMBOL vmlinux 0x00000000 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x00000000 skb_clone +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy_bits +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x00000000 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x00000000 skb_dequeue +EXPORT_SYMBOL vmlinux 0x00000000 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x00000000 skb_dma_map +EXPORT_SYMBOL vmlinux 0x00000000 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x00000000 skb_find_text +EXPORT_SYMBOL vmlinux 0x00000000 skb_free_datagram +EXPORT_SYMBOL vmlinux 0x00000000 skb_gso_segment +EXPORT_SYMBOL vmlinux 0x00000000 skb_insert +EXPORT_SYMBOL vmlinux 0x00000000 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x00000000 skb_over_panic +EXPORT_SYMBOL vmlinux 0x00000000 skb_pad +EXPORT_SYMBOL vmlinux 0x00000000 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x00000000 skb_pull +EXPORT_SYMBOL vmlinux 0x00000000 skb_push +EXPORT_SYMBOL vmlinux 0x00000000 skb_put +EXPORT_SYMBOL vmlinux 0x00000000 skb_queue_head +EXPORT_SYMBOL vmlinux 0x00000000 skb_queue_purge +EXPORT_SYMBOL vmlinux 0x00000000 skb_queue_tail +EXPORT_SYMBOL vmlinux 0x00000000 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0x00000000 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x00000000 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x00000000 skb_seq_read +EXPORT_SYMBOL vmlinux 0x00000000 skb_split +EXPORT_SYMBOL vmlinux 0x00000000 skb_store_bits +EXPORT_SYMBOL vmlinux 0x00000000 skb_trim +EXPORT_SYMBOL vmlinux 0x00000000 skb_truesize_bug +EXPORT_SYMBOL vmlinux 0x00000000 skb_under_panic +EXPORT_SYMBOL vmlinux 0x00000000 skb_unlink +EXPORT_SYMBOL vmlinux 0x00000000 sleep_on +EXPORT_SYMBOL vmlinux 0x00000000 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x00000000 snprintf +EXPORT_SYMBOL vmlinux 0x00000000 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x00000000 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x00000000 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x00000000 sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x00000000 sock_create +EXPORT_SYMBOL vmlinux 0x00000000 sock_create_kern +EXPORT_SYMBOL vmlinux 0x00000000 sock_create_lite +EXPORT_SYMBOL vmlinux 0x00000000 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0x00000000 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0x00000000 sock_i_ino +EXPORT_SYMBOL vmlinux 0x00000000 sock_i_uid +EXPORT_SYMBOL vmlinux 0x00000000 sock_init_data +EXPORT_SYMBOL vmlinux 0x00000000 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x00000000 sock_kmalloc +EXPORT_SYMBOL vmlinux 0x00000000 sock_map_fd +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_accept +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_bind +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_connect +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_getname +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_listen +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_mmap +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_poll +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_shutdown +EXPORT_SYMBOL vmlinux 0x00000000 sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x00000000 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x00000000 sock_recvmsg +EXPORT_SYMBOL vmlinux 0x00000000 sock_register +EXPORT_SYMBOL vmlinux 0x00000000 sock_release +EXPORT_SYMBOL vmlinux 0x00000000 sock_rfree +EXPORT_SYMBOL vmlinux 0x00000000 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x00000000 sock_setsockopt +EXPORT_SYMBOL vmlinux 0x00000000 sock_unregister +EXPORT_SYMBOL vmlinux 0x00000000 sock_wake_async +EXPORT_SYMBOL vmlinux 0x00000000 sock_wfree +EXPORT_SYMBOL vmlinux 0x00000000 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x00000000 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x00000000 soft_cursor +EXPORT_SYMBOL vmlinux 0x00000000 sort +EXPORT_SYMBOL vmlinux 0x00000000 sound_class +EXPORT_SYMBOL vmlinux 0x00000000 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x00000000 sprintf +EXPORT_SYMBOL vmlinux 0x00000000 srandom32 +EXPORT_SYMBOL vmlinux 0x00000000 sscanf +EXPORT_SYMBOL vmlinux 0x00000000 start_tty +EXPORT_SYMBOL vmlinux 0x00000000 stop_tty +EXPORT_SYMBOL vmlinux 0x00000000 strcasecmp +EXPORT_SYMBOL vmlinux 0x00000000 strcat +EXPORT_SYMBOL vmlinux 0x00000000 strchr +EXPORT_SYMBOL vmlinux 0x00000000 strcmp +EXPORT_SYMBOL vmlinux 0x00000000 strcpy +EXPORT_SYMBOL vmlinux 0x00000000 strcspn +EXPORT_SYMBOL vmlinux 0x00000000 strict_strtol +EXPORT_SYMBOL vmlinux 0x00000000 strict_strtoll +EXPORT_SYMBOL vmlinux 0x00000000 strict_strtoul +EXPORT_SYMBOL vmlinux 0x00000000 strict_strtoull +EXPORT_SYMBOL vmlinux 0x00000000 string_get_size +EXPORT_SYMBOL vmlinux 0x00000000 strlcat +EXPORT_SYMBOL vmlinux 0x00000000 strlcpy +EXPORT_SYMBOL vmlinux 0x00000000 strlen +EXPORT_SYMBOL vmlinux 0x00000000 strncasecmp +EXPORT_SYMBOL vmlinux 0x00000000 strncat +EXPORT_SYMBOL vmlinux 0x00000000 strnchr +EXPORT_SYMBOL vmlinux 0x00000000 strncmp +EXPORT_SYMBOL vmlinux 0x00000000 strncpy +EXPORT_SYMBOL vmlinux 0x00000000 strndup_user +EXPORT_SYMBOL vmlinux 0x00000000 strnicmp +EXPORT_SYMBOL vmlinux 0x00000000 strnlen +EXPORT_SYMBOL vmlinux 0x00000000 strpbrk +EXPORT_SYMBOL vmlinux 0x00000000 strrchr +EXPORT_SYMBOL vmlinux 0x00000000 strsep +EXPORT_SYMBOL vmlinux 0x00000000 strspn +EXPORT_SYMBOL vmlinux 0x00000000 strstr +EXPORT_SYMBOL vmlinux 0x00000000 strstrip +EXPORT_SYMBOL vmlinux 0x00000000 submit_bh +EXPORT_SYMBOL vmlinux 0x00000000 submit_bio +EXPORT_SYMBOL vmlinux 0x00000000 sunrpc_cache_lookup +EXPORT_SYMBOL vmlinux 0x00000000 sunrpc_cache_update +EXPORT_SYMBOL vmlinux 0x00000000 svc_auth_register +EXPORT_SYMBOL vmlinux 0x00000000 svc_auth_unregister +EXPORT_SYMBOL vmlinux 0x00000000 svc_authenticate +EXPORT_SYMBOL vmlinux 0x00000000 svc_create +EXPORT_SYMBOL vmlinux 0x00000000 svc_create_pooled +EXPORT_SYMBOL vmlinux 0x00000000 svc_destroy +EXPORT_SYMBOL vmlinux 0x00000000 svc_drop +EXPORT_SYMBOL vmlinux 0x00000000 svc_exit_thread +EXPORT_SYMBOL vmlinux 0x00000000 svc_prepare_thread +EXPORT_SYMBOL vmlinux 0x00000000 svc_proc_register +EXPORT_SYMBOL vmlinux 0x00000000 svc_proc_unregister +EXPORT_SYMBOL vmlinux 0x00000000 svc_process +EXPORT_SYMBOL vmlinux 0x00000000 svc_recv +EXPORT_SYMBOL vmlinux 0x00000000 svc_reserve +EXPORT_SYMBOL vmlinux 0x00000000 svc_seq_show +EXPORT_SYMBOL vmlinux 0x00000000 svc_set_client +EXPORT_SYMBOL vmlinux 0x00000000 svc_set_num_threads +EXPORT_SYMBOL vmlinux 0x00000000 svc_sock_names +EXPORT_SYMBOL vmlinux 0x00000000 svc_sock_update_bufs +EXPORT_SYMBOL vmlinux 0x00000000 svc_wake_up +EXPORT_SYMBOL vmlinux 0x00000000 svcauth_unix_purge +EXPORT_SYMBOL vmlinux 0x00000000 svcauth_unix_set_client +EXPORT_SYMBOL vmlinux 0x00000000 sync_blockdev +EXPORT_SYMBOL vmlinux 0x00000000 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x00000000 sync_inode +EXPORT_SYMBOL vmlinux 0x00000000 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x00000000 sync_page_range +EXPORT_SYMBOL vmlinux 0x00000000 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x00000000 synchronize_net +EXPORT_SYMBOL vmlinux 0x00000000 sys_close +EXPORT_SYMBOL vmlinux 0x00000000 sys_tz +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_data +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_intvec +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_string +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0x00000000 sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0x00000000 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x00000000 sysfs_streq +EXPORT_SYMBOL vmlinux 0x00000000 system_rev +EXPORT_SYMBOL vmlinux 0x00000000 system_serial_high +EXPORT_SYMBOL vmlinux 0x00000000 system_serial_low +EXPORT_SYMBOL vmlinux 0x00000000 system_state +EXPORT_SYMBOL vmlinux 0x00000000 take_over_console +EXPORT_SYMBOL vmlinux 0x00000000 task_nice +EXPORT_SYMBOL vmlinux 0x00000000 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x00000000 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x00000000 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0x00000000 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x00000000 tasklet_init +EXPORT_SYMBOL vmlinux 0x00000000 tasklet_kill +EXPORT_SYMBOL vmlinux 0x00000000 tcp_check_req +EXPORT_SYMBOL vmlinux 0x00000000 tcp_child_process +EXPORT_SYMBOL vmlinux 0x00000000 tcp_close +EXPORT_SYMBOL vmlinux 0x00000000 tcp_connect +EXPORT_SYMBOL vmlinux 0x00000000 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x00000000 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x00000000 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x00000000 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x00000000 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x00000000 tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x00000000 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x00000000 tcp_ioctl +EXPORT_SYMBOL vmlinux 0x00000000 tcp_make_synack +EXPORT_SYMBOL vmlinux 0x00000000 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0x00000000 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x00000000 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x00000000 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x00000000 tcp_poll +EXPORT_SYMBOL vmlinux 0x00000000 tcp_proc_register +EXPORT_SYMBOL vmlinux 0x00000000 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x00000000 tcp_prot +EXPORT_SYMBOL vmlinux 0x00000000 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x00000000 tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0x00000000 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x00000000 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x00000000 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x00000000 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x00000000 tcp_sendpage +EXPORT_SYMBOL vmlinux 0x00000000 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x00000000 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x00000000 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x00000000 tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x00000000 tcp_splice_read +EXPORT_SYMBOL vmlinux 0x00000000 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x00000000 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x00000000 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x00000000 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x00000000 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x00000000 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x00000000 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x00000000 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x00000000 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x00000000 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x00000000 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x00000000 test_taint +EXPORT_SYMBOL vmlinux 0x00000000 thaw_bdev +EXPORT_SYMBOL vmlinux 0x00000000 thaw_process +EXPORT_SYMBOL vmlinux 0x00000000 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 timespec_trunc +EXPORT_SYMBOL vmlinux 0x00000000 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 totalram_pages +EXPORT_SYMBOL vmlinux 0x00000000 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0x00000000 touch_atime +EXPORT_SYMBOL vmlinux 0x00000000 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x00000000 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x00000000 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x00000000 try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x00000000 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x00000000 try_to_release_page +EXPORT_SYMBOL vmlinux 0x00000000 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x00000000 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x00000000 tty_check_change +EXPORT_SYMBOL vmlinux 0x00000000 tty_devnum +EXPORT_SYMBOL vmlinux 0x00000000 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x00000000 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x00000000 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x00000000 tty_free_termios +EXPORT_SYMBOL vmlinux 0x00000000 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x00000000 tty_hangup +EXPORT_SYMBOL vmlinux 0x00000000 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x00000000 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0x00000000 tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x00000000 tty_kref_put +EXPORT_SYMBOL vmlinux 0x00000000 tty_mutex +EXPORT_SYMBOL vmlinux 0x00000000 tty_name +EXPORT_SYMBOL vmlinux 0x00000000 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x00000000 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x00000000 tty_port_init +EXPORT_SYMBOL vmlinux 0x00000000 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x00000000 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0x00000000 tty_register_device +EXPORT_SYMBOL vmlinux 0x00000000 tty_register_driver +EXPORT_SYMBOL vmlinux 0x00000000 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x00000000 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x00000000 tty_set_operations +EXPORT_SYMBOL vmlinux 0x00000000 tty_shutdown +EXPORT_SYMBOL vmlinux 0x00000000 tty_std_termios +EXPORT_SYMBOL vmlinux 0x00000000 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x00000000 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x00000000 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0x00000000 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x00000000 tty_throttle +EXPORT_SYMBOL vmlinux 0x00000000 tty_unregister_device +EXPORT_SYMBOL vmlinux 0x00000000 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x00000000 tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0x00000000 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x00000000 tty_vhangup +EXPORT_SYMBOL vmlinux 0x00000000 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x00000000 tty_write_room +EXPORT_SYMBOL vmlinux 0x00000000 uart_add_one_port +EXPORT_SYMBOL vmlinux 0x00000000 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x00000000 uart_get_divisor +EXPORT_SYMBOL vmlinux 0x00000000 uart_match_port +EXPORT_SYMBOL vmlinux 0x00000000 uart_register_driver +EXPORT_SYMBOL vmlinux 0x00000000 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x00000000 uart_resume_port +EXPORT_SYMBOL vmlinux 0x00000000 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x00000000 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x00000000 uart_update_timeout +EXPORT_SYMBOL vmlinux 0x00000000 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x00000000 udp_disconnect +EXPORT_SYMBOL vmlinux 0x00000000 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x00000000 udp_hash +EXPORT_SYMBOL vmlinux 0x00000000 udp_hash_lock +EXPORT_SYMBOL vmlinux 0x00000000 udp_ioctl +EXPORT_SYMBOL vmlinux 0x00000000 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0x00000000 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x00000000 udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x00000000 udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x00000000 udp_poll +EXPORT_SYMBOL vmlinux 0x00000000 udp_proc_register +EXPORT_SYMBOL vmlinux 0x00000000 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x00000000 udp_prot +EXPORT_SYMBOL vmlinux 0x00000000 udp_sendmsg +EXPORT_SYMBOL vmlinux 0x00000000 udplite_hash +EXPORT_SYMBOL vmlinux 0x00000000 udplite_prot +EXPORT_SYMBOL vmlinux 0x00000000 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x00000000 unix_domain_find +EXPORT_SYMBOL vmlinux 0x00000000 unlock_buffer +EXPORT_SYMBOL vmlinux 0x00000000 unlock_new_inode +EXPORT_SYMBOL vmlinux 0x00000000 unlock_page +EXPORT_SYMBOL vmlinux 0x00000000 unlock_rename +EXPORT_SYMBOL vmlinux 0x00000000 unlock_super +EXPORT_SYMBOL vmlinux 0x00000000 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x00000000 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x00000000 unregister_binfmt +EXPORT_SYMBOL vmlinux 0x00000000 unregister_blkdev +EXPORT_SYMBOL vmlinux 0x00000000 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x00000000 unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x00000000 unregister_con_driver +EXPORT_SYMBOL vmlinux 0x00000000 unregister_console +EXPORT_SYMBOL vmlinux 0x00000000 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x00000000 unregister_filesystem +EXPORT_SYMBOL vmlinux 0x00000000 unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x00000000 unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x00000000 unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x00000000 unregister_mtd_chip_driver +EXPORT_SYMBOL vmlinux 0x00000000 unregister_netdev +EXPORT_SYMBOL vmlinux 0x00000000 unregister_netdevice +EXPORT_SYMBOL vmlinux 0x00000000 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x00000000 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x00000000 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x00000000 unregister_sound_dsp +EXPORT_SYMBOL vmlinux 0x00000000 unregister_sound_midi +EXPORT_SYMBOL vmlinux 0x00000000 unregister_sound_mixer +EXPORT_SYMBOL vmlinux 0x00000000 unregister_sound_special +EXPORT_SYMBOL vmlinux 0x00000000 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x00000000 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x00000000 up +EXPORT_SYMBOL vmlinux 0x00000000 up_read +EXPORT_SYMBOL vmlinux 0x00000000 up_write +EXPORT_SYMBOL vmlinux 0x00000000 update_region +EXPORT_SYMBOL vmlinux 0x00000000 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x00000000 user_path_at +EXPORT_SYMBOL vmlinux 0x00000000 v4wb_clear_user_page +EXPORT_SYMBOL vmlinux 0x00000000 v4wb_copy_user_page +EXPORT_SYMBOL vmlinux 0x00000000 vc_cons +EXPORT_SYMBOL vmlinux 0x00000000 vc_resize +EXPORT_SYMBOL vmlinux 0x00000000 vfree +EXPORT_SYMBOL vmlinux 0x00000000 vfs_create +EXPORT_SYMBOL vmlinux 0x00000000 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x00000000 vfs_fstat +EXPORT_SYMBOL vmlinux 0x00000000 vfs_getattr +EXPORT_SYMBOL vmlinux 0x00000000 vfs_link +EXPORT_SYMBOL vmlinux 0x00000000 vfs_llseek +EXPORT_SYMBOL vmlinux 0x00000000 vfs_lstat +EXPORT_SYMBOL vmlinux 0x00000000 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x00000000 vfs_mknod +EXPORT_SYMBOL vmlinux 0x00000000 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x00000000 vfs_permission +EXPORT_SYMBOL vmlinux 0x00000000 vfs_read +EXPORT_SYMBOL vmlinux 0x00000000 vfs_readdir +EXPORT_SYMBOL vmlinux 0x00000000 vfs_readlink +EXPORT_SYMBOL vmlinux 0x00000000 vfs_readv +EXPORT_SYMBOL vmlinux 0x00000000 vfs_rename +EXPORT_SYMBOL vmlinux 0x00000000 vfs_rmdir +EXPORT_SYMBOL vmlinux 0x00000000 vfs_stat +EXPORT_SYMBOL vmlinux 0x00000000 vfs_statfs +EXPORT_SYMBOL vmlinux 0x00000000 vfs_symlink +EXPORT_SYMBOL vmlinux 0x00000000 vfs_unlink +EXPORT_SYMBOL vmlinux 0x00000000 vfs_write +EXPORT_SYMBOL vmlinux 0x00000000 vfs_writev +EXPORT_SYMBOL vmlinux 0x00000000 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x00000000 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x00000000 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x00000000 vm_insert_page +EXPORT_SYMBOL vmlinux 0x00000000 vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x00000000 vm_map_ram +EXPORT_SYMBOL vmlinux 0x00000000 vm_stat +EXPORT_SYMBOL vmlinux 0x00000000 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x00000000 vmalloc +EXPORT_SYMBOL vmlinux 0x00000000 vmalloc_32 +EXPORT_SYMBOL vmlinux 0x00000000 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x00000000 vmalloc_node +EXPORT_SYMBOL vmlinux 0x00000000 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x00000000 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x00000000 vmalloc_user +EXPORT_SYMBOL vmlinux 0x00000000 vmap +EXPORT_SYMBOL vmlinux 0x00000000 vmtruncate +EXPORT_SYMBOL vmlinux 0x00000000 vprintk +EXPORT_SYMBOL vmlinux 0x00000000 vscnprintf +EXPORT_SYMBOL vmlinux 0x00000000 vsnprintf +EXPORT_SYMBOL vmlinux 0x00000000 vsprintf +EXPORT_SYMBOL vmlinux 0x00000000 vsscanf +EXPORT_SYMBOL vmlinux 0x00000000 vunmap +EXPORT_SYMBOL vmlinux 0x00000000 wait_for_completion +EXPORT_SYMBOL vmlinux 0x00000000 wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0x00000000 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0x00000000 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0x00000000 wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x00000000 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x00000000 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0x00000000 wake_bit_function +EXPORT_SYMBOL vmlinux 0x00000000 wake_up_bit +EXPORT_SYMBOL vmlinux 0x00000000 wake_up_process +EXPORT_SYMBOL vmlinux 0x00000000 walk_stackframe +EXPORT_SYMBOL vmlinux 0x00000000 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x00000000 warn_slowpath +EXPORT_SYMBOL vmlinux 0x00000000 wireless_send_event +EXPORT_SYMBOL vmlinux 0x00000000 wireless_spy_update +EXPORT_SYMBOL vmlinux 0x00000000 write_cache_pages +EXPORT_SYMBOL vmlinux 0x00000000 write_inode_now +EXPORT_SYMBOL vmlinux 0x00000000 write_one_page +EXPORT_SYMBOL vmlinux 0x00000000 xdr_buf_from_iov +EXPORT_SYMBOL vmlinux 0x00000000 xdr_buf_read_netobj +EXPORT_SYMBOL vmlinux 0x00000000 xdr_buf_subsegment +EXPORT_SYMBOL vmlinux 0x00000000 xdr_decode_array2 +EXPORT_SYMBOL vmlinux 0x00000000 xdr_decode_netobj +EXPORT_SYMBOL vmlinux 0x00000000 xdr_decode_string_inplace +EXPORT_SYMBOL vmlinux 0x00000000 xdr_decode_word +EXPORT_SYMBOL vmlinux 0x00000000 xdr_encode_array2 +EXPORT_SYMBOL vmlinux 0x00000000 xdr_encode_netobj +EXPORT_SYMBOL vmlinux 0x00000000 xdr_encode_opaque +EXPORT_SYMBOL vmlinux 0x00000000 xdr_encode_opaque_fixed +EXPORT_SYMBOL vmlinux 0x00000000 xdr_encode_pages +EXPORT_SYMBOL vmlinux 0x00000000 xdr_encode_string +EXPORT_SYMBOL vmlinux 0x00000000 xdr_encode_word +EXPORT_SYMBOL vmlinux 0x00000000 xdr_enter_page +EXPORT_SYMBOL vmlinux 0x00000000 xdr_init_decode +EXPORT_SYMBOL vmlinux 0x00000000 xdr_init_encode +EXPORT_SYMBOL vmlinux 0x00000000 xdr_inline_decode +EXPORT_SYMBOL vmlinux 0x00000000 xdr_inline_pages +EXPORT_SYMBOL vmlinux 0x00000000 xdr_process_buf +EXPORT_SYMBOL vmlinux 0x00000000 xdr_read_pages +EXPORT_SYMBOL vmlinux 0x00000000 xdr_reserve_space +EXPORT_SYMBOL vmlinux 0x00000000 xdr_shift_buf +EXPORT_SYMBOL vmlinux 0x00000000 xdr_write_pages +EXPORT_SYMBOL vmlinux 0x00000000 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x00000000 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x00000000 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_init_state +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_input +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_lookup +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_nl +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_count +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_register_km +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_add +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_update +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x00000000 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x00000000 xrlim_allow +EXPORT_SYMBOL vmlinux 0x00000000 yield +EXPORT_SYMBOL vmlinux 0x00000000 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x00000000 zlib_deflate +EXPORT_SYMBOL vmlinux 0x00000000 zlib_deflateEnd +EXPORT_SYMBOL vmlinux 0x00000000 zlib_deflateInit2 +EXPORT_SYMBOL vmlinux 0x00000000 zlib_deflateReset +EXPORT_SYMBOL vmlinux 0x00000000 zlib_deflate_workspacesize +EXPORT_SYMBOL vmlinux 0x00000000 zlib_inflate +EXPORT_SYMBOL vmlinux 0x00000000 zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x00000000 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x00000000 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x00000000 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x00000000 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x00000000 zlib_inflate_workspacesize +EXPORT_SYMBOL_GPL crypto/aes_generic 0x00000000 crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x00000000 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x00000000 crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x00000000 crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x00000000 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x00000000 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/des_generic 0x00000000 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0x00000000 twofish_setkey +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x00000000 hwrng_register +EXPORT_SYMBOL_GPL drivers/char/hw_random/rng-core 0x00000000 hwrng_unregister +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x00000000 lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x00000000 fat_time_unix2fat +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x00000000 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x00000000 ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x00000000 register_rfkill_notifier +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x00000000 rfkill_epo +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x00000000 rfkill_restore_states +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x00000000 rfkill_set_default +EXPORT_SYMBOL_GPL net/rfkill/rfkill 0x00000000 unregister_rfkill_notifier +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_test_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x00000000 snd_soc_update_bits +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __class_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __class_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x00000000 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x00000000 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x00000000 add_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0x00000000 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x00000000 aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 alg_test +EXPORT_SYMBOL_GPL vmlinux 0x00000000 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x00000000 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x00000000 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x00000000 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x00000000 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0x00000000 arm_pm_restart +EXPORT_SYMBOL_GPL vmlinux 0x00000000 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x00000000 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x00000000 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x00000000 call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x00000000 call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cfi_qry_mode_off +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cfi_qry_mode_on +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cfi_qry_present +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x00000000 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x00000000 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x00000000 copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x00000000 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0x00000000 crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x00000000 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x00000000 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x00000000 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x00000000 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x00000000 default_mtd_writev +EXPORT_SYMBOL_GPL vmlinux 0x00000000 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL vmlinux 0x00000000 del_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0x00000000 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x00000000 deregister_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x00000000 destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_del +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_move +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_rename +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x00000000 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_free +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x00000000 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x00000000 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x00000000 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x00000000 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x00000000 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x00000000 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x00000000 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x00000000 do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x00000000 do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x00000000 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x00000000 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0x00000000 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0x00000000 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x00000000 exportfs_decode_fh +EXPORT_SYMBOL_GPL vmlinux 0x00000000 exportfs_encode_fh +EXPORT_SYMBOL_GPL vmlinux 0x00000000 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0x00000000 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0x00000000 fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x00000000 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x00000000 flush_work +EXPORT_SYMBOL_GPL vmlinux 0x00000000 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x00000000 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x00000000 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x00000000 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0x00000000 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x00000000 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x00000000 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x00000000 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x00000000 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_mtd_device_nm +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_sb_mtd +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x00000000 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x00000000 hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x00000000 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x00000000 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x00000000 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x00000000 init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x00000000 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x00000000 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x00000000 input_class +EXPORT_SYMBOL_GPL vmlinux 0x00000000 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x00000000 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x00000000 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x00000000 invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0x00000000 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x00000000 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x00000000 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x00000000 jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x00000000 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kill_mtd_super +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_next +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x00000000 klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x00000000 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ktime_add_ns +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ktime_sub_ns +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x00000000 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x00000000 leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 locks_end_grace +EXPORT_SYMBOL_GPL vmlinux 0x00000000 locks_in_grace +EXPORT_SYMBOL_GPL vmlinux 0x00000000 locks_start_grace +EXPORT_SYMBOL_GPL vmlinux 0x00000000 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x00000000 lzo1x_1_compress +EXPORT_SYMBOL_GPL vmlinux 0x00000000 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x00000000 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x00000000 marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0x00000000 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mmput +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mtd_erase_callback +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mtd_table +EXPORT_SYMBOL_GPL vmlinux 0x00000000 mtd_table_mutex +EXPORT_SYMBOL_GPL vmlinux 0x00000000 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x00000000 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x00000000 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x00000000 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nfs_debug +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nfsd_debug +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nlm_debug +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nlmclnt_done +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nlmclnt_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nlmclnt_proc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x00000000 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0x00000000 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x00000000 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x00000000 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0x00000000 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x00000000 parse_mtd_partitions +EXPORT_SYMBOL_GPL vmlinux 0x00000000 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0x00000000 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x00000000 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x00000000 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0x00000000 pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0x00000000 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x00000000 pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x00000000 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x00000000 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x00000000 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x00000000 probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x00000000 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x00000000 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x00000000 put_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 put_mtd_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 put_rpccred +EXPORT_SYMBOL_GPL vmlinux 0x00000000 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x00000000 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x00000000 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x00000000 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x00000000 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_mtd_blktrans +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_mtd_parser +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x00000000 round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x00000000 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x00000000 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_alloc_iostats +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_bind_new_program +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_calc_rto +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_call_async +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_call_null +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_call_start +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_call_sync +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_clone_client +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_debug +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_delay +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_exit_task +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_force_rebind +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_free +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_free_iostats +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_init_rtt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_init_wait_queue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_killall_tasks +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_lookup_cred +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_malloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_peeraddr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_peeraddr2str +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_print_iostats +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_proc_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_proc_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_put_task +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_restart_call +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_run_task +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_setbufsize +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_shutdown_client +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_sleep_on +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_wake_up +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_wake_up_next +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpc_wake_up_status +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_create +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_init_cred +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_init_credcache +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcauth_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcb_getport_async +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rpcb_getport_sync +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x00000000 save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x00000000 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x00000000 scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x00000000 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0x00000000 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0x00000000 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x00000000 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x00000000 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x00000000 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x00000000 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0x00000000 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x00000000 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x00000000 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x00000000 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x00000000 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x00000000 simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x00000000 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0x00000000 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x00000000 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x00000000 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0x00000000 snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x00000000 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x00000000 srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00000000 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x00000000 srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x00000000 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_addsock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_close_xprt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_create_xprt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_find_xprt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_max_payload +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_print_addr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_reg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_unreg_xprt_class +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_xprt_enqueue +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_xprt_init +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_xprt_names +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_xprt_put +EXPORT_SYMBOL_GPL vmlinux 0x00000000 svc_xprt_received +EXPORT_SYMBOL_GPL vmlinux 0x00000000 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x00000000 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x00000000 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x00000000 thread_notify_head +EXPORT_SYMBOL_GPL vmlinux 0x00000000 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x00000000 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x00000000 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x00000000 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x00000000 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x00000000 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0x00000000 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_close_volume +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_get_device_info +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_get_volume_info +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_is_mapped +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_leb_change +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_leb_erase +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_leb_map +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_leb_read +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_leb_unmap +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_leb_write +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_open_volume +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_open_volume_nm +EXPORT_SYMBOL_GPL vmlinux 0x00000000 ubi_sync +EXPORT_SYMBOL_GPL vmlinux 0x00000000 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_mtd_user +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x00000000 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xdr_skb_read_bits +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_complete_rqst +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_disconnect_done +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_lookup_rqst +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_register_transport +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_release_xprt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_reserve_xprt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_unregister_transport +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_update_rtt +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL vmlinux 0x00000000 xprt_write_space +EXPORT_SYMBOL_GPL vmlinux 0x00000000 zap_vma_ptes --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/i386/generic +++ linux-2.6.28/debian/abi/2.6.28-4.9/i386/generic @@ -0,0 +1,8642 @@ +EXPORT_SYMBOL arch/x86/kernel/scx200 0x254e5667 scx200_gpio_base +EXPORT_SYMBOL arch/x86/kernel/scx200 0x35a3c008 scx200_gpio_configure +EXPORT_SYMBOL arch/x86/kernel/scx200 0x8cfa375c scx200_gpio_shadow +EXPORT_SYMBOL arch/x86/kernel/scx200 0x907665bd scx200_cb_base +EXPORT_SYMBOL arch/x86/kvm/kvm 0x215fe36b kvm_cpu_has_pending_timer +EXPORT_SYMBOL arch/x86/kvm/kvm 0x4049a886 kvm_read_guest_atomic +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0xba1fa30c suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0xd3f3978d uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x0ca221ad pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0x41c300e3 pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0x8b13c3f1 paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0xc5d28fb0 pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xc91bbab7 pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0xce4ae8bb pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xd0812bc1 pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0xd3f9d5de pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0xd70b8164 pi_disconnect +EXPORT_SYMBOL drivers/block/paride/paride 0xdd0e653c pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0xe59f08ad paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0xf32255db pi_read_regr +EXPORT_SYMBOL drivers/char/agp/agpgart 0x06d98114 agp_free_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0d053f35 agp_generic_mask_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0e93ef68 get_agp_version +EXPORT_SYMBOL drivers/char/agp/agpgart 0x0f402ead agp_generic_alloc_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x10043ec4 agp_backend_release +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1361c7d5 agp3_generic_tlbflush +EXPORT_SYMBOL drivers/char/agp/agpgart 0x19e36e67 agp_put_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x219d689b agp_generic_type_to_mask_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2527df23 agp_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x30226ddf agp_device_command +EXPORT_SYMBOL drivers/char/agp/agpgart 0x30bafca3 agp_alloc_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x3f0fc87a agp_generic_free_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL drivers/char/agp/agpgart 0x4e324faf agp_generic_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x63c45e5e agp_alloc_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x673f815e agp_bridges +EXPORT_SYMBOL drivers/char/agp/agpgart 0x6751f6b6 agp_generic_alloc_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7538b132 agp_off +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7bf25190 agp_generic_create_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7fcc3fa0 agp_create_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x820ae4ec agp_generic_insert_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x83a78a8c agp_allocate_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x8b1be008 agp_generic_free_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa6f8361c agp_generic_remove_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb6980988 agp_collect_device_status +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb8cf045c agp_free_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xbc7c90e7 agp_bind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc48fa898 agp_generic_alloc_user +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc81006b4 agp_unbind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd03e31f2 agp_generic_alloc_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd258c1c9 agp_copy_info +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd6267ffa agp_flush_chipset +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd946a3bf agp_generic_destroy_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL drivers/char/agp/agpgart 0xed78ca5a agp_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0xf56dc254 agp_backend_acquire +EXPORT_SYMBOL drivers/char/agp/agpgart 0xfa496b4d agp_find_bridge +EXPORT_SYMBOL drivers/char/generic_serial 0x03f6560a gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0x131f8fb0 gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0x139ca6ed gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x4eec3555 gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0x533336e8 gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0x6130c2f8 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x7e06a249 gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0x9cc7d392 gs_stop +EXPORT_SYMBOL drivers/char/generic_serial 0xa37cfaba gs_put_char +EXPORT_SYMBOL drivers/char/generic_serial 0xa680887c gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0xa8d44342 gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0xb4586e6c gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0xe5b46473 gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0xeed4f4fd gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0xf574626f gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0xf835488f gs_start +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1e170dfc ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x259567e1 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x25ad1f88 ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x30b948b7 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x319f5b4f ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x343f5723 ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x389e371a ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x4303a218 ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x4766279b ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x481804d2 ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x4a0628f6 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x56e62728 ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6086a11e ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7309dba3 ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x757b5ce0 ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x766ce2ff ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x87f50f12 ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x9d7f7195 ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa6624900 ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc8c4eb8d ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xdce66bbc ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe03618df ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xed4ac83f ipmi_get_version +EXPORT_SYMBOL drivers/char/nsc_gpio 0x361dfc80 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0x5440e251 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nsc_gpio 0xc664ec68 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x31dc4d14 edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0x3749ba69 edac_mc_find +EXPORT_SYMBOL drivers/edac/edac_core 0x83cf6e87 edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/firewire/firewire-core 0x14d709dc fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x263e18ad fw_cancel_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3a89d578 fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x45d4781c fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x4e01ff0b fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0x578dc53c fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x77136b75 fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x8c150227 fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0x8c3e7707 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0x9fee1369 fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0xa7621e64 fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0xac05ff18 fw_send_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xc7757ecc fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0xd8e57cab fw_fill_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0xe1f883bc fw_core_remove_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0xe3d7d698 fw_run_transaction +EXPORT_SYMBOL drivers/gpu/drm/drm 0x009fedc3 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x01c6e128 drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x06a118e0 drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x096d8e4a drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0a395f72 drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0b0e211e drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0f621c32 drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0x11402c33 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0x14393a8d drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1c03fabb drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1f737c1c drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x22f6cab0 drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x26996133 drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2aa2abb0 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2e578de8 drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3b30ce2e drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3c8abdcc drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4193b197 drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0x48e365b6 drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b13c287 drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4c627290 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x540de5a8 drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x57eb75d9 drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5a39a99b drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x615acc4d drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7879a7ee drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7d51a074 drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7f9186ec drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8d895542 drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x979c54e5 drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9e9f7823 drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9f26717f drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa0776d08 drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xad60264f drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbb4fe1e0 drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbc290623 drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbd36eed9 drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xbf7e25d4 drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc073fee2 drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc3803fa0 drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc76a7bbc drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcb499907 drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcd428718 drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcfa88ea2 drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd08a025d drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd359413a drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd62bc955 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd99957bd drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0xda446b21 drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xdac8755f drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0xde50497e drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe2216a80 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf6613f13 drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfcd492c4 drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x6d12272a i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xfc231253 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0xa858ce2c i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0xc0c26dd3 i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0xd1226efa i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0xa29555f9 amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0056526d dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x05117a0a hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x09222748 hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0b072315 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x191d823a hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1934b9f0 hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1b34fc57 hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x20b6339d hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x20f81726 hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x219cbabe dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x22187956 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x272956f1 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2752b9a8 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x347c10dc hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x365d5039 hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x37a736c9 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x396324ad hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3c2e51d5 hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3fddac30 hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x42ee207e hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x496f5cb5 hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x49c6fdea hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4fa76d8b hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x57f3d270 hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5b51fd55 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x63094913 hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x69e2415f hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6b9a46bb hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6cbf5ab4 __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6ee096e2 hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6faf165a hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7046e886 csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x73bcc68a hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76dfde7b hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7de10481 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x807eda75 hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8a54dd8b hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ddbb9d0 hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8f3b11c2 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x91b750f1 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x94326bc5 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9563fd51 hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9564bc22 hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x959e811b hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x979b3052 dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa42d0252 hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa4c37b18 hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa5211c89 hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa85c6d75 hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa924dac6 dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xae70161e hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb0d58fca hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb1ce7a0a hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb3568609 hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb45cb712 hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb65da4d3 hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb6a05d36 hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb91e20ed hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbba70620 dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc4a9697e hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc8e37b2c hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcc895891 hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xccef9274 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd559ac01 hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe0757bfb hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe1d6a8da hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf5fc6fad hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfc34dde3 hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfe115c71 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x64705f63 ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x83109ec4 ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xc0ba50fc ohci1394_stop_context +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x1ba3794f rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x4510a158 rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xa17e1e35 rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xeba2fa0d rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x0ff8e01f ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x16171272 ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x2f5082cb ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x306637ca ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x32b2791b ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4a81f350 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x6e4e2c79 ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x76b2b195 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x90773eba ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xad415643 cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xb267aa9b ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd603d2fa ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd8d5ddb0 ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd95ba648 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe88a3814 ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe995a520 ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xfe7db477 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x086986ba ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x10be4465 ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x17c26c9e ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x195af52a ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1969dc6e ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1c8aaddc ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1d602754 ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x21d8cc65 ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x29c7de19 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2b79d6f9 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x30a690fb ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x32c68693 ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x32e342f0 ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3526c544 ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3602098d ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3b6f941e ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3de7894a ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x45be3c2d ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x48d30148 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x50678b77 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x520b2638 ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x52176b20 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x540a9a53 ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x55b40948 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x55f315e4 ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x60763148 ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x60871888 ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x608cc302 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x627132a5 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x695db0f2 ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6a64d53b ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6eda00e2 ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x751b5c96 ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x755b1a0e ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x758e5299 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x775a8bb6 ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7a9d9649 ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7d30c3e2 ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87eec73b ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x894cddf3 ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a82ac6a ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a87c81f ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8da3a4fd ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x931a559b ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x959449ff ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x99855cbb ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9bcabedc ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d8f1096 ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa790d6ef ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xaa003b61 ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb0552fba ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1901f35 ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1a312e1 ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb208acaf ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb7719536 ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbf058a19 ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xcc12792e ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd0060e61 ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd215a308 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd344b56a ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd3f45dfb ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd48a3bb5 ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe8d59343 ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe92319fb ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xeadb2e8a ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xef341da4 ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf38e745a ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfb563dea ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x0f497256 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x196f1683 ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x22516e23 ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x2a9a9888 ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x633fb155 ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7c00b631 ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x8121237b ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x8fb1b4a8 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x99084efa ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xbfc6a460 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xde0399e5 ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xf749aee4 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x239b3d62 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x62ed796d ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xaa98150c ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xaf0d0a87 ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xb8215d0e ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf0ee897f ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf29471fe ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x0158d80f iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x467e1e8a iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x7ed45aef iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xb765c829 iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xb9abe15d iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xc4203284 iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xc8531540 iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xdc5a2ae9 iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x0673f09f rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x08342011 rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x0a91ba30 rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x1e00431c rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x2de38fb1 rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x38269772 rdma_create_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x63bf6995 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x98a45f6a rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xab823110 rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xb492f740 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xbce0badd rdma_leave_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xbd8bdbd1 rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xbe411023 rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xc6270563 rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xc997798e rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xc9e7361a rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd63a404c rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xe351c7d7 rdma_resolve_route +EXPORT_SYMBOL drivers/input/gameport/gameport 0x0d6d64f4 gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x1526b086 __gameport_register_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0x1f53749c gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x4bd11d53 gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x50ca56ac gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0x51c7cc97 gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0x60c0abfd gameport_stop_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0xd4b91de2 gameport_unregister_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xeba062ac __gameport_register_port +EXPORT_SYMBOL drivers/input/input-polldev 0x78b9a27b input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x9d02cda2 input_free_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xd2c4eeec input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xe9824372 input_allocate_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x1556344a capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2085a724 capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x3a63f766 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x3be7b125 capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x756995e7 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8cc1d275 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9bef1b44 capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa7c4fd6c capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa398e99 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc10fe128 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc780572e capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc8020850 capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe8ad9bd1 capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xf4f0b275 attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x069636d5 b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x0e61a828 b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x2378dbc3 b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x254adf5b b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x34e03267 b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x3690c0fb b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x53e05084 b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x6996604f b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x81ae105e b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x8ac87de5 b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xb3eb206b avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xb6c6326c avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xb7eb9676 b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xde2e84be b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xf81e4eae b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2f87c128 b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x5d03be7f t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x66edddd3 b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x69e0cd6e b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x8ef73b06 b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x90fb573e b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xba75bf03 b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xc4c2e6ab b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xff695ad1 b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0xeb902c9a proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x5729a0a1 hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x78eb1307 isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x9d4f5113 isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xd3d81baa isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xdbe5e0ef isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xe22909b8 isac_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x0d16aad1 isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x579a6e06 register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xd9458d0f isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x1646b0b1 get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2b696bad mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x307403d2 get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3729b327 recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x380ba0af bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3e59e42b mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x55d50725 mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x767ab908 mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x87a8818c recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x9b2bc458 recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x9c761e70 confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb22d7ea3 l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc4e1ab49 dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xca3bd287 create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xcf67dbc7 mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd1787070 mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xea8718c1 mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xedcf8314 recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf25a3fc2 mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf6771208 queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0xdf0c64a0 mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0x89058558 mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0xdc5d0e9e mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0xfeaa61bc mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0x69ae9dfe qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0xfd4684c7 xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0x61f23b25 xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x128c3fa3 flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x24852b8e flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x388b83f6 flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x389fd6c2 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x4c7743a7 flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x632a68cb flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xa25f2b2a flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xaa74def4 flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb267d2ef flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb32e51ac flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb5e59ec3 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb5fa728c flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc414a08a flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd4198321 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xda39e81e flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xe01c01dd flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xed04b8b1 flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xf5494a85 flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xfdd1bcd4 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x9b0f9773 bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xb8105988 bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xf1967e69 bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xf9eae67d bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x0fe3517a dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x226c127b rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x3d678255 dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x52b14d12 dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x57836e46 read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x598a911d dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x6478f912 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xc9bf34a6 dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xf4bcaf2f write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0xed030527 dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x07522ec0 dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x14eb630c dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x30c1b83b dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x44bd5621 dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x48c1f7cb dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x50867a9b dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x54ff45ee dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x635eb40e dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x692a0776 dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6a30edc4 dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f7f7d73 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f9c72e3 dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x7f1c4386 dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x923aa88e dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x943d1f1a dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x988043f6 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9cbff999 dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9e73655d dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xaf96fd2a dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb2db2592 dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb56f0404 dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb5b95805 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbed559e1 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbfde43b3 dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc5a1ad8e dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc938e566 dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd7f95dfe dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xded1f877 dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xdf08cbc3 dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe23c382b dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe7949e59 dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xeb7daf80 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xfe019727 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x62ad06d1 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x743fa160 dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x898bc8aa dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x8fd99df4 dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xb5406ae1 dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xd6931f71 dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xf2e6e6fe usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x6e787e23 af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x16018d5a dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x1aebb255 dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x252ec525 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x2e4bb1cd dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x4369d5c9 dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x463d55dc dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x8f5bbb5e dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xc018c379 dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xc475fae7 dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xe45d335f dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xf8c4a497 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0x30d5347c af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0x7d86983b au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0xbc5be8e3 bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0x481adccc cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0x16adf14d cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0x19bab8f3 cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0x567c12bd cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xa1cb9f87 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xf477ea03 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x141d1ff7 dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x3997b9dd dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0xa31ef387 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x0ccd6382 dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x2880054c dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x31211f85 dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x36b8543e dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x56d110b1 dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xcf2dbb0e dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x34fedb7a dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x42872471 dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x6a5d06fc dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xccdac9a7 dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xf261ce9a dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xf2c40f10 dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xf4b9f3f6 dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xfe1f5dfa dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x6557cc1b dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x771c31fd dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x84026f77 dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0x7c5a4114 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0xb4a480cb dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0x283bde68 isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0x4dd69951 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0x0b5488ed itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0xdb652a52 l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0x0f5e9e54 lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0x29e7a8a7 lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0xcb9189ed lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0xb784bdce mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0x514dfd73 mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0x7ff56c86 nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0x5b652b6d nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0x7b31aeb7 or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0xf6b3140f or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0x349298be s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0xc09df453 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x47693829 s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x514ca212 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0xea4069d0 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0xc943883e sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x76f1e6a8 sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0xb010dec5 stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x07aabf95 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x09ee2ff3 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0xa31a0004 stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0x5b7a75fc tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x65d12e6b tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0x64afd19d tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xcec47bae tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xe985c25e tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0xb1f59328 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0x772a5422 tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0x34a012e2 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0xab6305f8 tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x9346f562 ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0x5bdb51da ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x1cb25698 zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0x12007275 ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xdf18773e ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xf4df76f4 ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x232a2d28 bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x52e07fb6 bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x77dcd4c3 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x8d900a46 btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xaa4fec25 btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/cpia 0xe73f5e53 cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xf0a2ece7 cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0x2ae8ec1d vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xfe9de798 vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x0a69124d cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x43c8c572 cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x620fee33 cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x88067db9 cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xa6f92698 cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xaa231b73 cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x0c43c5a4 cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x2c04d054 cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x772d0642 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x813af354 cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x893244b2 cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x93dc62c7 cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xe1919f79 cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x0f5146a9 cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1364f343 cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1c192d3b cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x24efe48b cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x52dc7a60 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5b4a4a1d cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5d864a05 cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5eb90e6c cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6dc5f091 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x7a19d7d8 cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x8edd35f4 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x97fa0e49 cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9a57ab8c cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xa2bcf49c cx88_shutdown +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xaf36aa30 cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb0d5ea60 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc00c2c24 cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd8c7778a cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xe5f5102a cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xeb69b0b4 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xf3912c61 cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xff62426f cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x6c8ec841 em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0xa74cecc8 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x01c1297b gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x439256fa gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x92be2618 gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xbdbbbc03 gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xdb38b757 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xe00e543d gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xef7e36e2 gspca_frame_add +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0bdf7ee5 ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x394aafb4 ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x41dd54ec ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x67bd6b42 ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x7985369f ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x962e7976 ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x9dd9c224 ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa0528773 ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xafb74f0f ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xb7d67970 ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xc3cbc8f8 ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xccdaaa6b ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xde1edf11 ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x076557b8 saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x167778a7 saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x3c68565a saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x67249a6d saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x986fb28a saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xa7ac5964 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd43affe8 saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xdb849360 saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xe7b22ca3 saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xf0005ae4 saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xf4f204bc saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xffd79e76 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0x257d0152 soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0x2e4e8443 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x4ebdaa37 soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0x6f3721c9 soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0xd5c78d9e soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0xfefca2d9 soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/tveeprom 0x4d47c25d tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0xa6e6beda tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x58d9bce8 usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x97f096ae usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xa83539d0 usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xab02acf1 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xe1283088 usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf450e699 usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0x38b68514 v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0338881f v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x9393d699 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe214aab4 v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x046f1fc9 videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x90574f0c videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xa041b038 videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xa917bbe9 videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xb9ff9b58 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xcf14033c videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videodev 0x02b5e57a video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x02cacc72 video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0x099a3466 video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x483e8970 video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x6d04d484 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x7c432105 video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0x8b24712a video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0x9dbb1812 video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0xb453411e video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0xcd403463 video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5d940430 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x6068f54e videocodec_detach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xd4f479d5 videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xec014351 videocodec_unregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x06877e40 mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0826bdb8 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x19a94446 mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x2c3573b4 mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x2d7ab1a3 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x332ca98a mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3627e5a2 mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x375d8126 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3abfa6a5 mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x414ff6ee mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x49a357d0 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6dbcfb31 mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x763eacd1 mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7ccfaab7 mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x81b51b6e mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x87f9b87f mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x9810fc54 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xa996f3d4 mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xa9fa4d78 mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xac38687d mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xad0bca31 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc7ec699f mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd31c3f96 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xf9cc4e68 mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x0039d3c7 mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x0bf995d6 mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x0ee94ea3 mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x2f8ebf39 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x30e58506 mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x415f6a1f mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x4919a617 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x55c4fb7b mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x5c170cd9 mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x64959970 mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x6977e06e mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x6ed28cb5 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x6f24b0a2 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x9f5abe12 mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xaa417ede mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xae5110d0 mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xb72befce mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xbd1d01d1 mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xc6963bcc mptscsih_suspend +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd40b69d0 mptscsih_shutdown +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xf3b70bdb mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xf61aea3a mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfe795f78 mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfe84c824 mptscsih_io_done +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x12f1f798 i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1f8cf8a3 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x329279a1 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x39955acc i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x416a3c34 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x41bdf56d i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x7a09b3e8 i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x7d8d4efd i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x90242ccc i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xab72ae8f i2o_device_claim +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xac396cb3 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xc043794a i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xc3a38d99 i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xcfd3f94f i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd6bb55b5 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe1133836 i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xf32a9d97 i2o_parm_issue +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xffc41310 i2o_iop_find_device +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x98841457 pasic3_read_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0xf85fc113 pasic3_write_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x25da8f4f c2port_device_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x5f72c217 c2port_device_unregister +EXPORT_SYMBOL drivers/misc/ioc4 0x0e567731 ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0x9505f865 ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x1e74ab52 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x3427bdcc tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x39f86aa1 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0x57a73183 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x6a29ebaa tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x6e459c7d tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x90748f39 tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x929c3d19 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0x9ec83a33 tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xbf5d34d7 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xcc75950c tifm_unmap_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0xd8f974c9 tifm_register_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xf92b042a tifm_free_adapter +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x8fd5b47c mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x03fa1788 cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x0b8253f8 cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x79d0b7e9 cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x4f314ab9 do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x6315abd1 map_destroy +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x78df02de unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x9cdd55e3 register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0x8ee9433a mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0x70582b3b simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x417901cb del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0xd74b0245 add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x6e4384c0 mtd_concat_create +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x8b45ce23 mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/nand/nand 0x4ba5a176 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xa14e4112 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x5930200b nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x5b8ad617 nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x6bd19823 onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xf31e665d onenand_scan_bbt +EXPORT_SYMBOL drivers/net/8390 0x2bcfb7c2 NS8390_init +EXPORT_SYMBOL drivers/net/8390 0x4511ddea __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/8390 0x721d7513 ei_poll +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0xaa7ad762 ei_close +EXPORT_SYMBOL drivers/net/8390 0xf802507e ei_open +EXPORT_SYMBOL drivers/net/8390p 0x7a45de1c eip_close +EXPORT_SYMBOL drivers/net/8390p 0x83d5eb98 __alloc_eip_netdev +EXPORT_SYMBOL drivers/net/8390p 0x841bc69f eip_interrupt +EXPORT_SYMBOL drivers/net/8390p 0xa2f5b9d2 eip_poll +EXPORT_SYMBOL drivers/net/8390p 0xa71dd99b eip_open +EXPORT_SYMBOL drivers/net/8390p 0xc5709515 NS8390p_init +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x557a1871 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x7382c45a alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x7f7ca95e arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x9606486b arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x9bce81c5 arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xea1cf99e arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x2838e61c com20020_found +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x310f7bc9 com20020_check +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x03076c0f cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x13246555 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x48bda8fd cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x50f36c49 dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x62b96a5c cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x75f4c4e0 cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x7a181263 t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8fba85df t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa2a74233 cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa70a54ca t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xaa7f911b t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xc2eaf231 cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xc4701803 cxgb3_free_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xd05b4136 cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xf269b499 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xfc83fdf8 cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x201c5fdc hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x585bd580 hdlcdrv_register +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x6f2d23c0 hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x70cbfa96 hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xc20c6119 hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x19a9e31a sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x27ee3439 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2b5e62ef sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2f477748 sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x72051709 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x7e5061b9 sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x920a2072 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xb1d3f40f sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xd05ef1ab sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xdc158928 irda_unregister_dongle +EXPORT_SYMBOL drivers/net/mii 0x354c4b7d mii_nway_restart +EXPORT_SYMBOL drivers/net/mii 0x37420c5f mii_link_ok +EXPORT_SYMBOL drivers/net/mii 0x425d2d45 mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xa4c8eaaa generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0xa721e27e mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0xd8031052 mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0xe4202b89 mii_check_media +EXPORT_SYMBOL drivers/net/mii 0xf0d70a92 mii_check_link +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x45fec05b free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xf2940737 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x44f9c796 pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0x8d14c8df register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xc3741577 pppox_unbind_sock +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/sungem_phy 0xccbdad07 mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x46014581 tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x4f38083f tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xc2c60eba tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xe06295bf tms380tr_open +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x122600a9 detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x33103701 unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0x640fce78 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0x6f7b7705 unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x7b817bf0 attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x9a5ca0a0 alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/hdlc 0x9fff4bc6 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xc6e8242e hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0xcd6e07d3 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x12b16f28 sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x25dcebae sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x2bd55eae sppp_attach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x5867d0c8 sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0x8705b42d sppp_open +EXPORT_SYMBOL drivers/net/wan/syncppp 0x883b26f0 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/z85230 0x0546fcae z8530_channel_load +EXPORT_SYMBOL drivers/net/wan/z85230 0x0e71b1d4 z8530_null_rx +EXPORT_SYMBOL drivers/net/wan/z85230 0x10c78988 z8530_dead_port +EXPORT_SYMBOL drivers/net/wan/z85230 0x144ca90c z8530_sync_txdma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0x1a75e5db z8530_txdma_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x2031a53a z8530_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x2395c240 z8530_sync_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x283e799e z8530_interrupt +EXPORT_SYMBOL drivers/net/wan/z85230 0x5cd24d29 z8530_hdlc_kilostream +EXPORT_SYMBOL drivers/net/wan/z85230 0x66558733 z8530_describe +EXPORT_SYMBOL drivers/net/wan/z85230 0x707a82b1 z8530_sync_dma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x75b584b9 z8530_shutdown +EXPORT_SYMBOL drivers/net/wan/z85230 0x77817cf5 z8530_dma_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x7ca9db23 z8530_init +EXPORT_SYMBOL drivers/net/wan/z85230 0x827bddc9 z8530_sync_dma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0x9be283fa z8530_sync_txdma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0xb79f4612 z8530_queue_xmit +EXPORT_SYMBOL drivers/net/wan/z85230 0xd0068606 z8530_nop +EXPORT_SYMBOL drivers/net/wan/z85230 0xdea81c3b z8530_sync_open +EXPORT_SYMBOL drivers/net/wan/z85230 0xe3d80064 z8530_hdlc_kilostream_85230 +EXPORT_SYMBOL drivers/net/wireless/airo 0x8f696022 stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xa78caac6 reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xefb2f431 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x0343ed4c atmel_open +EXPORT_SYMBOL drivers/net/wireless/atmel 0x53b6f6a9 stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0xbfebf4f9 init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeeef9f73 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x09cbcc1f hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0ad69602 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x126e9a3d hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1db9aee4 hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x24ab3546 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x382a5dd2 hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3b979257 hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x43c65d3d hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x5746bc0e hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x599781d4 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x66918c04 hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6c0c46ff hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x844602eb hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8ada3843 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x97276d92 hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x9dc0519c hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa0941c9d hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa3e94c53 hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xaad7d0d3 hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xaed12a06 hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbe5696fc hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xce7f2aeb hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xda6c927f hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xdcb6e3bf hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xdf407da0 hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xec958f70 prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xfb699a40 hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x01fa9ff2 iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x02afc563 iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x032da833 iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0456b1da iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x04fa3d15 iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0702a242 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0b0df107 iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0caa90c2 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0cd3c96d iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x11fb943e iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x161524cf iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x17153e28 iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x19f02b2e iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1b466880 iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x203bb9e6 iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x22de8bb5 iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x234e0022 iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2367fdaa iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x23cbf5cd iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x24e387de iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x265e8139 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2ae21ce8 iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2f4620e9 iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2f755a8b iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2f91a6be iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x30af6ece iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x356ab5a3 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x393cb067 iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x395b431a iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3bab78ae iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3fc5e585 iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x40974ac2 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x41a2eab1 iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50c04445 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x53a7ca29 iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x555d9769 iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x56d39974 iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x56fffce2 iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5af98a5d iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5c021482 iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5e20bd63 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5e7c7863 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6132b5db iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x62727d56 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x634c4398 iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x63c4ca96 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6489489a iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x65b75387 iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x69fd372e iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6b089fc0 iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6db3ba66 iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6f362d52 iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6ff7062a iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x74d0404e iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x773959ba iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7b30163f iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7b4e63d3 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7c36023b iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7c94dc33 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x82d60207 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8452dd6e iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x84675362 iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x853f200f iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8e38ca5d iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8e7376c6 iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x90cfb790 iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9645225c iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9c286854 iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9cde1f24 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9d34b274 iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9ff3dd53 iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa0a64d7a iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa71cb6c9 iwl_rx_allocate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa7d201c5 iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xab399384 iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xab3fa57a iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xac078ad4 iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb1cbb291 iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb2cebe16 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb3b1b7f5 iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb67f833e iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb9d0d46d iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbb164f05 iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbd66afd5 iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xca329ebd iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcad809dc iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcc406b21 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xce5e133d iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcf018768 iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd3226760 iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd4a4bb5e iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd4c0b762 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdfffbd12 iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe150f53b iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe2af86b5 iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe44d1df1 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe5bd3e7b iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe9ba8eeb iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf02590c6 iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf07d9394 iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf216969e iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf8cf2966 iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfa038616 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xff1a82c9 iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x32ada6cd __orinoco_down +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x591211c6 orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xb3aa41c8 __orinoco_up +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xc275c524 free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xd95f1255 alloc_orinocodev +EXPORT_SYMBOL drivers/parport/parport 0x13c55d28 parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0x1c9756e4 parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x2519bb1b parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0x2a34520d parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0x2acc44b1 parport_write +EXPORT_SYMBOL drivers/parport/parport 0x3ebc9a40 parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0x41d65fce parport_read +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x4ef7d230 parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0x51925d06 parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0x5426e070 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x556ecd4b parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x5a2304b9 parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0x61235f2a parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0x659e3723 parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x6e32614d parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x7c26552d parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0x88590dff parport_release +EXPORT_SYMBOL drivers/parport/parport 0x8b18c62e parport_negotiate +EXPORT_SYMBOL drivers/parport/parport 0x991cbcf1 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x9cfeb31a parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0xa28c3ac7 parport_claim +EXPORT_SYMBOL drivers/parport/parport 0xac0e4972 parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0xb40e9641 parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0xb97883a1 parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0xbd82f989 parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0xc2f45135 parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0xd6f22afc parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0xe64fb02c parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0xf3fce63c parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport 0xfac26398 parport_get_port +EXPORT_SYMBOL drivers/parport/parport_pc 0x5f550f0c parport_pc_unregister_port +EXPORT_SYMBOL drivers/parport/parport_pc 0x8d531115 parport_pc_probe_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x1be07e02 pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x2ffa50e6 pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x502bc5cb pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x5200a30c pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x5bd05bb0 pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x652d96dc pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x6b3bb552 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x7fa1fb4e pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x9724c087 pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xa088b6e7 pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb390248e pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xbb4fc98e pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xcd63509b pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xea771056 pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xfd976b1d pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0740e4fb pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x09637353 pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x14b6e9f3 pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x1e66265d pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x221596cf pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x35d7c3c3 pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3779c058 pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x3c9596f6 pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x5050a228 pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x5053f40c pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x59da54c1 pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x5e252e03 pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x61b347d6 pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x81c79c2a pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x82ba2143 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x854fb759 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8758f051 pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x91870661 release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa78876ee pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa85f90b6 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa8e20605 pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc07b3963 pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc368f687 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd949db0a pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe1afacdc pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe3024d7c pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe52a1214 pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xeeb36ef2 destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf6e5934d pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xf9dcecdc pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xfae1d6eb pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0xc6c526f7 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/53c700 0x4a8e4bdd NCR_700_detect +EXPORT_SYMBOL drivers/scsi/53c700 0x5175c0f0 NCR_700_intr +EXPORT_SYMBOL drivers/scsi/53c700 0x6c9cdecc NCR_700_release +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0xf970c991 mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x0207fce0 qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x1032450a qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x65bc3842 qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x9d8f776f qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x9e5982b0 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xd7428d70 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/raid_class 0x35cb7ce8 raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0xa20d9655 raid_component_add +EXPORT_SYMBOL drivers/scsi/raid_class 0xddbb3e1c raid_class_release +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x05e78886 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x2faee5ae fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x59b5eeac fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x5dc275ac scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x6e0e9610 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x76d1f00a fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x8fd39083 scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xaf4fcd04 fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xd83a6fd3 fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe3d43067 fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe84a4853 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xec4dd5d4 fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x234aad35 sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x243d07d7 scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x31dcdb62 sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x32685a51 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x48ce955a sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4ac3d8bf sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4bce470f sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x63b78081 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x67c9a5f9 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x68b3f8b8 sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x6f446f2b sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x70d99d6b sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x73ad8931 sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x799d8ecc sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7a9c038f sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7afc34ba sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x7dcce950 sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x84b0ffbb sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x97e883e5 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xacc06bc7 sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb96de8a6 sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc5501ecb sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xcb38776c sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xde34994d scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf431c2d2 scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf79508b3 sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3c80635e spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x5801d083 spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x7fbe299f spi_display_xfer_agreement +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xdf15d4ac spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xe444f7b4 spi_schedule_dv_device +EXPORT_SYMBOL drivers/ssb/ssb 0x1276e370 ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0x2779b9a3 ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x46179dad ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x4d3d082e ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0x69defb3c ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0x72f29518 ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0x7ef7af30 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0x7f00f04c ssb_set_devtypedata +EXPORT_SYMBOL drivers/ssb/ssb 0x8680e042 ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0x8a47378e ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0x8b3c4687 ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0x9d92f6e6 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xa018fd9c ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xa32d8b60 ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0xa98005d3 ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xb11c6985 ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xe047a7ef ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0xe32975d6 ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xea455f92 ssb_pcihost_register +EXPORT_SYMBOL drivers/telephony/ixj 0x8c1c8c35 ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x30f38c55 phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0xa09f2269 phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x755a3215 usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/gadget/net2280 0xbd3ef562 usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/net2280 0xbdda1160 net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0xdc013b57 sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x27fe226a lcd_device_register +EXPORT_SYMBOL drivers/video/backlight/lcd 0xb55541d1 lcd_device_unregister +EXPORT_SYMBOL drivers/video/console/bitblit 0x4c9f7abb fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0x41c01a58 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0x6481d77c fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x2f88ac62 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x6a64f5f3 cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/cyber2000fb 0x82dca37a cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0xacf0dd94 cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/display/display 0x4473724a display_device_register +EXPORT_SYMBOL drivers/video/display/display 0x6f2fbadc display_device_unregister +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0xb8d992c8 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x5ccf1ce1 matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x6983d1c5 matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0xae00bc0f g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x6d1fd00f matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xb9bfaa15 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xcfc3527f matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xf97e7aa6 DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0x52978d45 matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0xc1a2a120 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x369caf2a matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x6518253f matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xb6e7f1e0 matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xf61b26cf matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x59ce6ab9 matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x96b2eafe matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x3d479d62 matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x41983938 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x67fe3413 matroxfb_read_pins +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xba86305e matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xff033146 matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/output 0x19b4508a video_output_register +EXPORT_SYMBOL drivers/video/output 0x2d8502e2 video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x01bb43ee svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x5118a8a2 svga_tilefill +EXPORT_SYMBOL drivers/video/svgalib 0x52bca797 svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0x5c2a1a2d svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0x936a202b svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/svgalib 0xf7d12c77 svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0xfb8a3d4c svga_get_tilemax +EXPORT_SYMBOL drivers/video/syscopyarea 0xac3814ca sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0x9560b5c6 sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0x33b2d455 sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x0ef147f8 w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x30766848 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x0c58777b w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xed26f24f w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x2b11224e w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0x4408ca03 w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0x44e37eb9 w1_register_family +EXPORT_SYMBOL drivers/w1/wire 0xfadb369f w1_remove_master_device +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x1bdb8ab5 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x22cfa18a configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x26a95739 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0x6d1cd965 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x7dd0c5f8 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0xa0c47823 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xa4d156a8 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xc1344cb1 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0xe0969648 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xe65b1fab configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xececabf9 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0xf04aa220 config_group_find_item +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xed032237 nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x6342bda2 nfsacl_encode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xceaa822a nfsacl_decode +EXPORT_SYMBOL fs/nfsd/nfsd 0x0f3e6e01 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x2095976a nfs4_acl_new +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x7ee78c79 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/xfs/xfs 0x95f7e1dd xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x3771b461 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc7 0xa7587646 crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0x4f4ef3f8 destroy_8023_client +EXPORT_SYMBOL net/802/p8023 0x900043d6 make_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x0c18200b p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0x0d246dd6 p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x17dc20ef v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x1f38bfe2 p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0x28ce7efd p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0x3455711e p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x6b754e6f p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x6c1906f4 p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x85e52a63 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0x8c2cf0e3 v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0x8ced840e p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0x8d4bdd81 p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x98e5eb06 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0x9992e841 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0x9d002cb1 p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0xa14a1b93 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0xa3c58437 p9_client_walk +EXPORT_SYMBOL net/9p/9pnet 0xaab8671a p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0xb2cdd76a p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0xb38c03d2 p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0xc536ccd2 p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0xcae61af3 p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0xd0cd0ce9 v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0xd0faf92e p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0xd331fc1d p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0xdc0b3385 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0xe1a146f8 p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/9p/9pnet 0xef7127b0 p9_idpool_put +EXPORT_SYMBOL net/appletalk/appletalk 0x06838e32 atalk_find_dev_addr +EXPORT_SYMBOL net/appletalk/appletalk 0x65945c6a atrtr_get_dev +EXPORT_SYMBOL net/appletalk/appletalk 0xc6954e09 aarp_send_ddp +EXPORT_SYMBOL net/appletalk/appletalk 0xf9fafcfd alloc_ltalkdev +EXPORT_SYMBOL net/ax25/ax25 0x1b499fc2 ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x49ab5314 ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x571cdd25 ax25_find_cb +EXPORT_SYMBOL net/ax25/ax25 0x746fa5d0 ax25_rebuild_header +EXPORT_SYMBOL net/ax25/ax25 0x7dd53264 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0x92e8c994 ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0x9dd4e0af ax25_linkfail_release +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xc27e62d3 ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0xc82e65c9 ax25_listen_register +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/ax25/ax25 0xd619eebc ax25_send_frame +EXPORT_SYMBOL net/bridge/bridge 0x226f533a br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x1c87a041 ebt_do_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x45dc1233 ebt_register_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xba71d279 ebt_unregister_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x0687f7b9 ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x2b9eae0e ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x483d5a17 ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211 0x4908ffff ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x56602a23 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x5e516018 ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x62b2a513 ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x84bd7321 alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x918d25f3 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x97a4bdd2 ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0x99e8f755 ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa1e19055 free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa90fd0d7 ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xc87c3d30 ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211 0xd04456e4 ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe2e4ed3f ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf12e68ca ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf87b4272 ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x08605230 ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x2452a2e2 ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x302caded ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x3421053b ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x5764e33e ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x8a1f94e9 ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ipv4/inet_lro 0x01c35fa4 lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0x0371a6b4 lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x483fabaa lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0xb128a241 lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xb9331a4b lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xe40ce065 lro_flush_all +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x79fb6c3b arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x90121e3a arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xa69227a8 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x614f4f60 ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x7af5dfd4 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xf2b1fc71 ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x096710f5 nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x0b614f80 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x452cd0e8 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x67f2c91b nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xfc69eafc nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/tunnel4 0x8bd15846 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0xabc21c58 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x263916cc ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x3aeac8ae ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x5a1f2244 ip6t_do_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xa6e1eef8 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/tunnel6 0x2625f169 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0xa329970b xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x1064c362 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x28d65443 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x2cd24cda ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x35b95dc8 ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4104db78 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x72796380 ircomm_connect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x8c834fd1 ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xa94436db ircomm_control_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x102076f0 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0x17c4a3cc async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0x1bf960d9 irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x260e94f6 iriap_open +EXPORT_SYMBOL net/irda/irda 0x2c49bee5 irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0x2f13a6ac irda_notify_init +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x433e29d2 irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x464114fe irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x4902d535 alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x53d1d16d proc_irda +EXPORT_SYMBOL net/irda/irda 0x54814e5f irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x80349d59 irlap_close +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x9543fb45 irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9e23f3f5 irttp_dup +EXPORT_SYMBOL net/irda/irda 0x9ee05dd4 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0xa0ae7c38 irlap_open +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xbf4b4a7b irttp_data_request +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xc80b0e2c irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0xcafa56bb irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xdc73c68a async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xe55df154 irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0xeaed57d0 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xeeb5c8ac irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0xf04dede2 iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0xf39b7fe0 irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xf4f7766f irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0xf6acc101 iriap_close +EXPORT_SYMBOL net/lapb/lapb 0x1e69f2f1 lapb_data_received +EXPORT_SYMBOL net/lapb/lapb 0x4c30fc64 lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0x9789196d lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0x983b340a lapb_register +EXPORT_SYMBOL net/lapb/lapb 0xd6fc6b4e lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0xe3e272bd lapb_data_request +EXPORT_SYMBOL net/lapb/lapb 0xf9c2df39 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0xfced037e lapb_disconnect_request +EXPORT_SYMBOL net/mac80211/mac80211 0x08adfc55 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x1691935e ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x16fb19ba ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x1bfbf7a8 __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x1d6d1ec3 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x20642586 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x22c85007 ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x2a13adb9 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0x2d7ee79f ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x3ac75e35 ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0x43e70bef ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x443b66fd ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x4829c403 ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x52596cb5 ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x5446e997 ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x5814722e ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x5f0dca99 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x6830106b __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x6c723541 ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x6c7c5a57 wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x6e2e9dc0 ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x74a6756b ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x7944da2a ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x7e3fa0d6 ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x823ad255 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x8d29a9af ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x9e3ea240 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x9ec6cc3c ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xa9b22767 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xbaaf3e36 ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0xbb72a6a9 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xc7f71f61 ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xd3852568 ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0xd97a5e1d ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0xe8581f09 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0xf854c49b ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xff420962 __ieee80211_rx +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x06bfc0bf register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x0c0110b1 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x0f76a50f ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x106b2a82 ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x1486ad83 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x17a2d92a ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x55000448 ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x722bb8ca unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe7fa1f8e ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xf1257361 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xf4ca37b3 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x4b656f54 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x1943e560 xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0x1dd6300b xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x58e5ccd3 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0x75d02f4c xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0x889f2c4a xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x988a47d5 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xb947f707 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xc399a107 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xc6b37fdb xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xda1b0078 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/phonet/phonet 0x3fd1b1cb phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0x6cf0738c pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x77a2e7d0 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x84e708f7 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0xa34202cc pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xbed6569a phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0xc5b0926a phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0xec37fd66 pn_sock_unhash +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x027feeab rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x133b35c1 rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1da38e38 rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1f063f81 rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1f891dcc rxrpc_kernel_begin_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x240e7910 rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x4e2fbf39 rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x53711e56 rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x621b7ad3 rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x98ee4e29 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xaa5281da rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb05e1049 rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xbd35b770 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xbd7b382f rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xbf659992 key_type_rxrpc +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x3f963b55 gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x408bf634 gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x4972bc88 svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x4d94cbd1 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x62202ac8 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x90f01d65 gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xad76c056 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xadb704f7 gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb2d3c63b gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf06e516b gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0d34fa5c auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x113984d5 xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x16769472 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1b77f789 xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x27e0497f svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2aac3fcc svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x311a9c66 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x332c9e26 svc_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x344f55b1 rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x35958899 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x36975f13 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x36baae88 xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x39f3fa42 svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4420d987 xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0x444385ae read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4907b7b6 svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4a3ab65e auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4a401a17 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x552c32b3 xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x602d942b xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0x650fb97d xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x69a40f7c xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6bf6b9c5 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6e760e8c svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6fe992d9 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x70319169 cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x70626382 svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x725ec3ba xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7317a5aa xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x73d652da auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x74dacff2 xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x845afab2 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8a87dbbb xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8e4608ea svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9b588713 xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9d4908cd xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9fe97189 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa265a252 cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa495a80f svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xae701a38 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb12177ab rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb3cd725d sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb82a8a2d svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb85d05ff cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0xba851963 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc1774a62 svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc223f13a svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc482a8e9 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc9cea5b0 auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd91cd3e6 xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xde34f49e cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe2e5b137 xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf8a836bd rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfe7bd9de sunrpc_cache_lookup +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x27d8bb58 tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x31d1b22a tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x387914fd tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4ba3cfc8 tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0x4e2a07fe tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x64357d3c tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x75453aa2 tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x8001e3d7 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa030f575 tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb01ffc2c tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xbb2b2504 tipc_send +EXPORT_SYMBOL net/tipc/tipc 0xc2d3754e tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xea1f8c69 tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0xec203287 tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xef651f54 tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0xf7f737d8 tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0xff220d2c tipc_send_buf2name +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0xa89918bb register_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x0364351a regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x21506073 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0x229071ad wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0x24cbd984 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x610fc833 wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xf045d4dc wiphy_unregister +EXPORT_SYMBOL sound/ac97_bus 0xfb83558c ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x1eae3296 snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x04fd51b9 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x26a2425d snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xaa2fc86f snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0xed726b07 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x075bc508 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x5b0b0421 snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0x43eb4cfa snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x0c1f9f68 snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x105ff3bb snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x14e86dce snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x18fcdb13 snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x25f2123c snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x285b570e snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x2fcd6cc9 snd_card_register +EXPORT_SYMBOL sound/core/snd 0x328c64b3 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x3fffa946 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4cfac966 snd_cards +EXPORT_SYMBOL sound/core/snd 0x54609c2d snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x57862528 snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x5af5615e snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x5d2c7ba1 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x6229494e snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x62ffb78d snd_card_free +EXPORT_SYMBOL sound/core/snd 0x642ad5b7 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0x67dde0a1 snd_device_free +EXPORT_SYMBOL sound/core/snd 0x6ed1f4f3 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x73618dbb snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x7477f288 snd_device_register +EXPORT_SYMBOL sound/core/snd 0x842c9c7a snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0x86f398bc snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0x8b8ee391 snd_component_add +EXPORT_SYMBOL sound/core/snd 0x8d26c189 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x93dfee48 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x93fde5f3 snd_info_register +EXPORT_SYMBOL sound/core/snd 0x97665339 snd_card_new +EXPORT_SYMBOL sound/core/snd 0xa770fe26 snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0xab633fb2 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0xaebe8735 snd_device_new +EXPORT_SYMBOL sound/core/snd 0xafa84cba snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0xce3d6083 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0xd1157735 release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0xd9ce06a1 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xda654a9b snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xe540dfd0 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0xeac38978 snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0xf52a4920 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0xf803b26c snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0xfb5c6bfd snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0xffecd53a snd_card_proc_new +EXPORT_SYMBOL sound/core/snd-hwdep 0xb91dcd42 snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x06cdd4ab snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x0c879491 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3b91f3af snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xcc22de2d snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xcd128d00 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xdd8d5cf1 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x0fa15f63 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x1044bf6e snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0x153a766a snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0x1c7fe520 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x37b8c17a snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x41a36210 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x42a7ba4d snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x486454a9 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x55755fe7 snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0x55ed53c0 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x61ab704e snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x62c25e14 snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x6ff2a738 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x77bd4e0f snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x7f5aaf7c snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0x8177acbd snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x86e3348c snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x8e44d8f0 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x91927352 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x9f818e78 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0xa268824f snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xb8c6650c snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xba64fcfd snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0xbc97e1d0 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0xc84895e0 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0xcbfc8c9f snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd353f964 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0xd61bb702 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0xd6f50b96 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0xda16eca0 snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0xdb702250 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0xdcca236f snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xe4fddcb0 snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xec81808c snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0xed9399ee snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0xf2fe49ea snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xf5b5289a snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0xf8dd17e7 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0xfeea9ef0 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-rawmidi 0x036a69a9 snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x1a093d69 snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x1ce13773 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0x3a27379b snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0x4054c60a snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0x43c6aae1 snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0x4f951661 snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x6898e776 snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0x8fe13f65 snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0xb545d316 snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc7a485ff snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0xcb21cf3d snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xd327ad25 snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0xdc8455c2 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xdc8fc0bd snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0xea2c84b9 snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf9eb3eca snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-timer 0x069f0a75 snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0x1008f8b1 snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0x29445469 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x2c1afd78 snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0x506bc6d0 snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0x5b7d4e52 snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0x90c2659c snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x96326598 snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0xa4c84f5b snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0xba12fb62 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0xd07f0c89 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0xf697d357 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0xf82b4994 snd_timer_interrupt +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x59fa8668 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x12be4533 snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x289e3680 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x3b96a737 snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x3f64a0e6 snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x9b9aa82d snd_opl3_create +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xb8ab1fa2 snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xd50d5aae snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xefa3af77 snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xfdedb716 snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x0025b237 snd_opl4_create +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x246fe809 snd_opl4_read_memory +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x5e7caeec snd_opl4_read +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x66c5e239 snd_opl4_write +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0xce420431 snd_opl4_write_memory +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x04bef86c snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x0dadd9fc snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x12a84e99 snd_vx_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x420a54fd snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x74cba98f snd_vx_load_boot_image +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xc0b4cbe9 snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xd70224f4 snd_vx_dsp_load +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xebfae784 snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xfdffb5b4 snd_vx_dsp_boot +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x201f3ec8 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x3a110d37 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x4a168211 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x7567c83b snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x899ca8c6 snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xec82024b snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x6fa14fe3 snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x74e88d9e snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x7c0848d5 snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xa4a29793 snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xa658f7a6 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xea7439b5 snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x76ae6aed snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x88159bf8 snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xa027357e snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xf5018a96 snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0xbcfaadcf snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0xc90115b0 snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x85fd14c0 snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0xba585716 snd_tea575x_init +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x14aaa1d6 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x2d3bef5b snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x3d282175 snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xc694faaf snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xd2dc2633 snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-i2c 0x80118d9a snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x83c3a3c6 snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0x86302dd9 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0xa1d22b58 snd_i2c_device_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xaa2f6149 snd_i2c_sendbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0xfdb9f024 snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0x73ebf32f snd_tea6330t_update_mixer +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0x805a4cc9 snd_tea6330t_detect +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0x7a2b0189 snd_cs4236_pcm +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0xa9eb62b4 snd_cs4236_mixer +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0xb371c1a9 snd_cs4236_create +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x1ded6cd1 snd_es1688_pcm +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x4f79d85f snd_es1688_mixer_write +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0xf475b4a2 snd_es1688_create +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0xfbcdeaa0 snd_es1688_mixer +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x065a5c2d snd_gf1_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x06ced536 snd_gf1_write16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x0bec3256 snd_gf1_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x0cb71a36 snd_gf1_peek +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x0e18f743 snd_gf1_free_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x2c17885a snd_gf1_rawmidi_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x393334fa snd_gus_dram_write +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x39b37499 snd_gf1_write_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x4571e1b6 snd_gf1_i_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x46db8d67 snd_gf1_lvol_to_gvol_raw +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x4d1f3e31 snd_gf1_pcm_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x53445dec snd_gf1_dram_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x59875288 snd_gus_initialize +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x7a9b1be2 snd_gf1_delay +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x7c2973b6 snd_gf1_poke +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x7e10029f snd_gf1_ctrl_stop +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x9a459a63 snd_gus_use_dec +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xa5e0c1d0 snd_gf1_translate_freq +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xa6c787db snd_gf1_alloc_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc31af61d snd_gf1_mem_alloc +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc43a5527 snd_gf1_atten_table +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xce9d0377 snd_gf1_i_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xd85053ba snd_gf1_mem_free +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xd9868d79 snd_gf1_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xdb252880 snd_gf1_mem_xfree +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe12a7459 snd_gf1_i_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe6e6f0fd snd_gf1_new_mixer +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xeca2dd3e snd_gf1_mem_lock +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf5d4512f snd_gf1_stop_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf6805df4 snd_gus_dram_read +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf963a997 snd_gus_interrupt +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xfda34d1e snd_gus_create +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xfeb88110 snd_gus_use_inc +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x0bfdc31b snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x0c40d674 snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x2e81eda5 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x35640f9e snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x7306e6eb snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x75be0c5d snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x7e299f97 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x8b069478 snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xdcb902ea snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xe516d172 snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb16-csp 0x0e5bcd85 snd_sb_csp_new +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x9eafa564 snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xacb908c8 snd_sb16dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xdf0907f3 snd_sb16dsp_configure +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x13ed9f87 snd_sb8dsp_midi_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x27984f0a snd_sb8dsp_midi +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x96a4dbbd snd_sb8dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0xc3276ea7 snd_sb8dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x06597b34 snd_emu8000_poke +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x5d391ae8 snd_emu8000_update_chorus_mode +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x6201e396 snd_emu8000_init_fm +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x8089ac89 snd_emu8000_load_chorus_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xb03d9f90 snd_emu8000_update_equalizer +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xb59c3056 snd_emu8000_update_reverb_mode +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xc35b7d80 snd_emu8000_dma_chan +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xc63110fa snd_emu8000_load_reverb_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xd73ab41d snd_emu8000_poke_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xedf01fd3 snd_emu8000_peek_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xff1fe911 snd_emu8000_peek +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x096cfb46 snd_cs4236_ext_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x22dccbf1 snd_wss_chip_id +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x60c5a165 snd_cs4236_ext_out +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x61c38720 snd_wss_mce_up +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x70c0b0ec snd_wss_mce_down +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x773304fb snd_wss_mixer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x8be549bc snd_wss_get_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x8eb25462 snd_wss_info_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x8f20aaab snd_wss_get_pcm_ops +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x99190aa1 snd_wss_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x9e5f6eb7 snd_wss_interrupt +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xa3191903 snd_wss_pcm +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xb1ed63bd snd_wss_put_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xba0877db snd_wss_out +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xbaffdf47 snd_wss_create +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xbdf76098 snd_wss_timer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xda47dc48 snd_wss_overrange +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xda5e62cf snd_wss_get_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xe05648ce snd_wss_put_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xeb991d53 snd_wss_info_double +EXPORT_SYMBOL sound/oss/ad1848 0x2b5d9dae ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x4f2c41cf attach_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x6d4e2417 ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xa3e16c6b probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0x61641749 probe_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xdd48aa10 attach_mpu401 +EXPORT_SYMBOL sound/oss/msnd 0x1186f48f msnd_fifo_read +EXPORT_SYMBOL sound/oss/msnd 0x234f64e0 msnd_register +EXPORT_SYMBOL sound/oss/msnd 0x340a3ddf msnd_init_queue +EXPORT_SYMBOL sound/oss/msnd 0x54230dc1 msnd_fifo_write +EXPORT_SYMBOL sound/oss/msnd 0x5fb94ecb msnd_unregister +EXPORT_SYMBOL sound/oss/msnd 0x6587640b msnd_disable_irq +EXPORT_SYMBOL sound/oss/msnd 0x6601493b msnd_fifo_make_empty +EXPORT_SYMBOL sound/oss/msnd 0x8e3c524b msnd_send_dsp_cmd +EXPORT_SYMBOL sound/oss/msnd 0x9274d677 msnd_fifo_free +EXPORT_SYMBOL sound/oss/msnd 0x95d37486 msnd_upload_host +EXPORT_SYMBOL sound/oss/msnd 0xa1bcc420 msnd_send_word +EXPORT_SYMBOL sound/oss/msnd 0xade99e25 msnd_fifo_alloc +EXPORT_SYMBOL sound/oss/msnd 0xb3520772 msnd_fifo_init +EXPORT_SYMBOL sound/oss/msnd 0xdf0f59eb msnd_fifo_write_io +EXPORT_SYMBOL sound/oss/msnd 0xefdd1843 msnd_enable_irq +EXPORT_SYMBOL sound/oss/msnd 0xf4c4f662 msnd_fifo_read_io +EXPORT_SYMBOL sound/oss/sb_lib 0x02fa2439 probe_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x51ee7cbc sb_dsp_init +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x34e77654 mixer_devs +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x56f8b347 sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0x57de7eb1 sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x89338d34 audio_devs +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0x9deff95d sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa468a0d6 synth_devs +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb34f84b3 midi_devs +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/uart401 0x1d111ae8 probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x04951681 snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x052e1f32 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0555de2a snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x23882135 snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x23c228c1 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x28c952d7 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x28d283b7 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x4ac537a2 snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x51dbcce5 snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x591fcc2d snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x7b5ed615 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x810abd07 snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x96ba6c14 snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xa3789409 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xd22230c4 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xe2409951 snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xf6001771 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x3ac4e9a5 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x496d7187 snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x53863cfe snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x62f0a4dc snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x6a5d8b60 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xb64366d9 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xce14c609 snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xeb145167 snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xef3cd482 snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x2d3dccff snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x6a701996 snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xdecbc188 snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x0a374783 oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x13422b79 oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x21ddda30 oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x330d9f42 oxygen_pci_resume +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x3aad5a10 oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x3cd4a700 oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x4ec4e3e3 oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x589c0f97 oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x78aca774 oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7a71cfd7 oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7c968308 oxygen_write16_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x84bee763 oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xac83fb03 oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xb0d22268 oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xbad12aa3 oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xbd94d4ee oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xc79745a3 oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xda55a62e oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xdaf62c70 oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xfe146ed2 oxygen_write8 +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x286a1573 snd_trident_start_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x31f532e1 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x4acffc7b snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x8940c8a0 snd_trident_stop_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xf905fcce snd_trident_free_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x1fb376fc register_sound_midi +EXPORT_SYMBOL sound/soundcore 0x3c1cb415 register_sound_special +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xbe7790bd register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xf6df6ade register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0xf82ab2f2 sound_class +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/soundcore 0xff62024d register_sound_special_device +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x00e08c21 snd_emux_register +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x069e62ca snd_emux_new +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x144c31e6 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x16b5e077 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x4af68c63 snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x6ba87361 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x422b0ba8 snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x27eed56d dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x6720b2b8 dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xa5b890a3 dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xb1bfc415 dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xcb2536f1 dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xcf719cc4 dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0329d132 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x108f2649 rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x2bcadf29 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c0b8352 rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8252ef05 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8821f9a7 rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa4a7321f rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xab2c8ab9 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc44723fe rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xd3d3744b rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xd99f0978 rh_inc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xda581f7b rh_get_region_size +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x60b2e316 cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x5c412482 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x9b8c7045 lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0xc5370137 ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x0d59df57 unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x112e9c79 p80211skb_rxmeta_attach +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x3f8beb98 p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x518c8c7a wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x558b7054 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x66354ac4 wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x7a926549 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0bc5686 p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xc747faae p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xd1f55d35 p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xe36776cc register_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xef0301c3 p80211_suspend +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x00112f51 groups_alloc +EXPORT_SYMBOL vmlinux 0x004f990c blk_rq_init +EXPORT_SYMBOL vmlinux 0x005516a1 xfrm_nl +EXPORT_SYMBOL vmlinux 0x00701c0f put_io_context +EXPORT_SYMBOL vmlinux 0x007e03aa i2c_master_send +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x008f5ca1 del_gendisk +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00b75525 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x00dd2c7e tcp_prot +EXPORT_SYMBOL vmlinux 0x00dea9f8 dev_mc_add +EXPORT_SYMBOL vmlinux 0x00e3f761 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x00f1076c netif_receive_skb +EXPORT_SYMBOL vmlinux 0x0109a50f mnt_pin +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x01306a95 phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0x0153696d journal_create +EXPORT_SYMBOL vmlinux 0x016f3afa thaw_process +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01b76da2 unregister_netdevice +EXPORT_SYMBOL vmlinux 0x01b9121c mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x01d9c81c vfs_rmdir +EXPORT_SYMBOL vmlinux 0x01eb353e d_find_alias +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x02474fe4 generic_permission +EXPORT_SYMBOL vmlinux 0x025277f6 profile_pc +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x025b604a fifo_set_limit +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x0264f2f0 read_cache_page +EXPORT_SYMBOL vmlinux 0x029319cb mca_bus_type +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02aac4ad mnt_unpin +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02dc3b09 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x035e5398 dquot_initialize +EXPORT_SYMBOL vmlinux 0x036fae6a sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x038c39e5 start_tty +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03d02074 uart_get_divisor +EXPORT_SYMBOL vmlinux 0x03fcfe5b kobject_init +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x0446a70c bio_endio +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x0462f23e clear_inode +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x04977814 mdiobus_free +EXPORT_SYMBOL vmlinux 0x04a1032e dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x04b4e15a dma_pool_create +EXPORT_SYMBOL vmlinux 0x04bb0921 con_is_bound +EXPORT_SYMBOL vmlinux 0x04bd6035 vfs_permission +EXPORT_SYMBOL vmlinux 0x04c87b73 journal_load +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04e7a1f2 xfrm_state_walk +EXPORT_SYMBOL vmlinux 0x05167fa8 pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x05205930 journal_check_available_features +EXPORT_SYMBOL vmlinux 0x053b83d5 tty_write_room +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x057ff5da mca_device_transform_memory +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x059e8768 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x05b291d5 ps2_command +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x05e7bb11 audit_log_end +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0616c083 hci_conn_auth +EXPORT_SYMBOL vmlinux 0x0626092d xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0x06558896 touch_atime +EXPORT_SYMBOL vmlinux 0x065828af i2c_register_driver +EXPORT_SYMBOL vmlinux 0x066717e2 module_put +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x068a3099 inet6_release +EXPORT_SYMBOL vmlinux 0x0692f390 rfkill_free +EXPORT_SYMBOL vmlinux 0x069b3356 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x06c37749 acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0x06c97faa __kill_fasync +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x07178a77 mca_device_set_name +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x0733cf57 tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x07608604 acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x0765ca2e blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x07749dad acpi_bus_add +EXPORT_SYMBOL vmlinux 0x0788f25d i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d50a24 csum_partial +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x07e44544 register_gifconf +EXPORT_SYMBOL vmlinux 0x07e445f3 jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0x07faabf9 tcf_em_unregister +EXPORT_SYMBOL vmlinux 0x08043a6d bt_sock_register +EXPORT_SYMBOL vmlinux 0x081c553f __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x08738ff8 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0x088ca2c2 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0x08c23e05 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x08f3b653 pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x092375ff xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x09244f30 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x093e947e posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x0951431b jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09b39b51 journal_errno +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09cf07b7 cdrom_open +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x09fab547 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a2ff701 pci_find_capability +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a4747ff allocate_resource +EXPORT_SYMBOL vmlinux 0x0a576002 pci_pme_active +EXPORT_SYMBOL vmlinux 0x0a683a22 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x0a7c76a7 blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x0a7fd5c8 blk_plug_device +EXPORT_SYMBOL vmlinux 0x0ac0a7f1 inode_get_bytes +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0acf36e0 netpoll_poll +EXPORT_SYMBOL vmlinux 0x0ad4b1d2 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x0b0e54b7 ipv4_specific +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b219eef open_by_devnum +EXPORT_SYMBOL vmlinux 0x0b2b9521 tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0x0b363c5e bio_put +EXPORT_SYMBOL vmlinux 0x0b3b6bf9 xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b758e75 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x0b9c0ed4 key_alloc +EXPORT_SYMBOL vmlinux 0x0babc04e tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x0be685d4 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x0be89fff sock_wake_async +EXPORT_SYMBOL vmlinux 0x0bfc2c22 pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x0c241948 pv_mmu_ops +EXPORT_SYMBOL vmlinux 0x0c277728 km_state_expired +EXPORT_SYMBOL vmlinux 0x0c55e87c rfkill_force_state +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c60d0c6 locks_copy_lock +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c6ab542 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x0c6f5ac1 f_setown +EXPORT_SYMBOL vmlinux 0x0c7833ae pci_get_subsys +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0c9dce2f journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x0cd5d880 mca_device_transform_irq +EXPORT_SYMBOL vmlinux 0x0cdb7576 skb_copy +EXPORT_SYMBOL vmlinux 0x0d1a1943 open_exec +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d4b77b7 gen_pool_add +EXPORT_SYMBOL vmlinux 0x0d4f46c4 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d5ea14c pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x0d6acd08 hci_register_dev +EXPORT_SYMBOL vmlinux 0x0d6c963c copy_from_user +EXPORT_SYMBOL vmlinux 0x0d7a3520 module_refcount +EXPORT_SYMBOL vmlinux 0x0d83774e rtnl_notify +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0db49e3d register_md_personality +EXPORT_SYMBOL vmlinux 0x0db994f1 poll_freewait +EXPORT_SYMBOL vmlinux 0x0dc5588e inet6_bind +EXPORT_SYMBOL vmlinux 0x0dc7005d rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x0dce5863 cdev_init +EXPORT_SYMBOL vmlinux 0x0e4272ee thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e58985d uart_add_one_port +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0e795f02 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x0e8f3aa8 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x0ea3313e __f_setown +EXPORT_SYMBOL vmlinux 0x0eb6e005 cdrom_media_changed +EXPORT_SYMBOL vmlinux 0x0ed2f718 journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x0ed8ab8b pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x0ee38f6c hci_unregister_cb +EXPORT_SYMBOL vmlinux 0x0f064e82 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x0f10c614 fasync_helper +EXPORT_SYMBOL vmlinux 0x0f1d3265 kern_path +EXPORT_SYMBOL vmlinux 0x0f32f84b block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x0f3b66d2 ip6_xmit +EXPORT_SYMBOL vmlinux 0x0f809d9d scsi_remove_host +EXPORT_SYMBOL vmlinux 0x0fa7f830 journal_forget +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x0ffbecee phy_start_interrupts +EXPORT_SYMBOL vmlinux 0x1047f77b __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x107ed2eb textsearch_prepare +EXPORT_SYMBOL vmlinux 0x108f299b skb_queue_tail +EXPORT_SYMBOL vmlinux 0x10af5442 inode_needs_sync +EXPORT_SYMBOL vmlinux 0x10c1e450 get_disk +EXPORT_SYMBOL vmlinux 0x10c8998f ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x11108a7d posix_lock_file +EXPORT_SYMBOL vmlinux 0x1117951e default_llseek +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x113a424d acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x1189152e sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11e6c324 pci_dev_get +EXPORT_SYMBOL vmlinux 0x11f578e0 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x120507ac idr_get_new +EXPORT_SYMBOL vmlinux 0x12050cf0 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x1246c1b3 jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0x1251dea9 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x12783f50 km_query +EXPORT_SYMBOL vmlinux 0x1286bc2b tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x128c0a4b put_tty_driver +EXPORT_SYMBOL vmlinux 0x1295a235 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x12971b28 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12e2ed4c kmalloc_caches +EXPORT_SYMBOL vmlinux 0x12f1b1ac mb_cache_create +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x1310bacf md_write_start +EXPORT_SYMBOL vmlinux 0x131d3156 sock_no_connect +EXPORT_SYMBOL vmlinux 0x1321b6c7 dentry_unhash +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x135b627f xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x13bbe27f tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x13ff1648 seq_release +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x1443a0de notify_change +EXPORT_SYMBOL vmlinux 0x14540159 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x148bbc1f arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0x149658cf sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14c592ce tty_set_operations +EXPORT_SYMBOL vmlinux 0x14c95aac generic_block_bmap +EXPORT_SYMBOL vmlinux 0x14e0077e inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x14f332ea up_read +EXPORT_SYMBOL vmlinux 0x14f71926 jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0x15281833 nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x1559ca1c cfb_fillrect +EXPORT_SYMBOL vmlinux 0x1560e05b blk_free_tags +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x15ffe324 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x162e65b6 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x165c5d6f write_inode_now +EXPORT_SYMBOL vmlinux 0x166315d2 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16b67299 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x16befc31 bio_free +EXPORT_SYMBOL vmlinux 0x16e15a93 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x16eec108 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x16f59d8c cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x17052027 thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x172ed4d7 __vmalloc +EXPORT_SYMBOL vmlinux 0x172f94c1 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x1733f577 dcache_readdir +EXPORT_SYMBOL vmlinux 0x17470585 vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0x174b7a7f devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x175a298d acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x175d5a7d scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x175f836d fb_find_mode +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17bd7de2 sock_no_listen +EXPORT_SYMBOL vmlinux 0x17bebdba hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17effc51 cdrom_ioctl +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x1831d50a kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x1845e7c5 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x18496855 __devm_request_region +EXPORT_SYMBOL vmlinux 0x184c7602 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0x184defad sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x1865acbe __brelse +EXPORT_SYMBOL vmlinux 0x187fea42 acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0x18a35908 dev_get_by_index +EXPORT_SYMBOL vmlinux 0x18a4c592 bio_integrity_advance +EXPORT_SYMBOL vmlinux 0x18a6ba63 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x18b06235 nf_getsockopt +EXPORT_SYMBOL vmlinux 0x18b55d77 serio_rescan +EXPORT_SYMBOL vmlinux 0x18dafdee tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x18dde6c0 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x18f1d1cb tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x190b37ea sg_miter_stop +EXPORT_SYMBOL vmlinux 0x190c0fd9 skb_insert +EXPORT_SYMBOL vmlinux 0x190e4f8a blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0x193ad3ca unregister_nls +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x199ad291 simple_getattr +EXPORT_SYMBOL vmlinux 0x199c546f sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19da018a sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x19f5d6f0 thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x19f5e181 dma_sync_wait +EXPORT_SYMBOL vmlinux 0x1a0f4d95 pci_enable_wake +EXPORT_SYMBOL vmlinux 0x1a137cbf keyring_clear +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a4c4268 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x1a5deecd unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x1a70ac9d da903x_query_status +EXPORT_SYMBOL vmlinux 0x1a7372bc ip6_route_output +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a814e51 skb_checksum +EXPORT_SYMBOL vmlinux 0x1a854228 get_io_context +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1a8ced77 seq_bitmap +EXPORT_SYMBOL vmlinux 0x1a8d06a2 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b07c47d simple_write_begin +EXPORT_SYMBOL vmlinux 0x1b27ffc4 vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b586ac3 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x1b628edd bio_phys_segments +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b7f41c2 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b911479 uart_match_port +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bc1580a hci_register_proto +EXPORT_SYMBOL vmlinux 0x1bc214b2 have_submounts +EXPORT_SYMBOL vmlinux 0x1bd85067 init_file +EXPORT_SYMBOL vmlinux 0x1be24073 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x1bf30a26 skb_store_bits +EXPORT_SYMBOL vmlinux 0x1c03df42 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x1c3986f2 register_chrdev +EXPORT_SYMBOL vmlinux 0x1c42cbd3 mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x1c463ff9 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x1c5c54af input_get_keycode +EXPORT_SYMBOL vmlinux 0x1c805c15 netpoll_print_options +EXPORT_SYMBOL vmlinux 0x1c941a31 d_alloc_name +EXPORT_SYMBOL vmlinux 0x1c9633dd textsearch_register +EXPORT_SYMBOL vmlinux 0x1cbd567d call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x1cbe3436 dma_async_device_register +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ce1e467 load_nls_default +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1d092753 cdev_add +EXPORT_SYMBOL vmlinux 0x1d30b70c rwsem_wake +EXPORT_SYMBOL vmlinux 0x1d52969a send_sig_info +EXPORT_SYMBOL vmlinux 0x1d9df2c5 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dc3a332 bd_release +EXPORT_SYMBOL vmlinux 0x1dd4048c alloc_disk_node +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1ddf651f dev_change_flags +EXPORT_SYMBOL vmlinux 0x1de19313 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x1dedf5f6 get_phy_id +EXPORT_SYMBOL vmlinux 0x1df4423a __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e3323fd kill_fasync +EXPORT_SYMBOL vmlinux 0x1e3c7794 proc_mkdir +EXPORT_SYMBOL vmlinux 0x1e59e3f0 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e979507 nf_afinfo +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ec347f3 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x1ec72d8d neigh_table_init +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f21fff5 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f4179a1 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1fbd0b0e tc_classify_compat +EXPORT_SYMBOL vmlinux 0x1fe5ede6 per_cpu__irq_stat +EXPORT_SYMBOL vmlinux 0x1ff6eeec ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x20082b93 fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x201c8cec jbd2_journal_load +EXPORT_SYMBOL vmlinux 0x2035879d mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x2046fff6 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x20a04728 i2c_master_recv +EXPORT_SYMBOL vmlinux 0x20a04ef5 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0x20ad06fc skb_pull +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20c98fe5 inet_frag_find +EXPORT_SYMBOL vmlinux 0x21359b12 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x21362e15 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x218480f6 mca_register_driver_integrated +EXPORT_SYMBOL vmlinux 0x21ab2a78 input_grab_device +EXPORT_SYMBOL vmlinux 0x21adbbfc tcp_proc_register +EXPORT_SYMBOL vmlinux 0x21bfdc71 pci_release_region +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21e3f3bb sk_receive_skb +EXPORT_SYMBOL vmlinux 0x21f5fc2e fb_validate_mode +EXPORT_SYMBOL vmlinux 0x22082292 nf_register_hook +EXPORT_SYMBOL vmlinux 0x22203ff9 set_pages_nx +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x22497467 bd_claim +EXPORT_SYMBOL vmlinux 0x225c5984 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x2270e67b mca_device_write_pos +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22a1d098 fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22fdcd17 neigh_create +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x2356fb13 ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x2368be6d posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x23744d52 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x23ad070a set_current_groups +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23f3af4a vfs_read +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x242ea196 scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x243ffddc idr_destroy +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x245e79e9 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0x24705297 alloc_fddidev +EXPORT_SYMBOL vmlinux 0x248fff0c jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x24ac854c journal_update_format +EXPORT_SYMBOL vmlinux 0x24b2dea3 update_region +EXPORT_SYMBOL vmlinux 0x24b8f22a simple_empty +EXPORT_SYMBOL vmlinux 0x24ba668c find_task_by_vpid +EXPORT_SYMBOL vmlinux 0x24bb3b53 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x24beb021 jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0x24c27bef mpage_readpages +EXPORT_SYMBOL vmlinux 0x24d1e148 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x251343af bio_clone +EXPORT_SYMBOL vmlinux 0x252917b9 km_state_notify +EXPORT_SYMBOL vmlinux 0x252eb268 serio_reconnect +EXPORT_SYMBOL vmlinux 0x25365032 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25762830 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x258f609c inode_sub_bytes +EXPORT_SYMBOL vmlinux 0x2596feff dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x25989c5a nf_ct_attach +EXPORT_SYMBOL vmlinux 0x25a481d2 arp_create +EXPORT_SYMBOL vmlinux 0x25c20bdc kernel_getsockname +EXPORT_SYMBOL vmlinux 0x25d81960 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x260c381a dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0x260da896 free_task +EXPORT_SYMBOL vmlinux 0x262a2107 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x262b5a60 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x264cfde2 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x2661dd99 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0x2674a94f jbd2_journal_start +EXPORT_SYMBOL vmlinux 0x2679d1e3 vcc_release_async +EXPORT_SYMBOL vmlinux 0x268cc6a2 sys_close +EXPORT_SYMBOL vmlinux 0x2697cb33 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x26ca48c4 kernel_getpeername +EXPORT_SYMBOL vmlinux 0x26e41551 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0x26e65b78 acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x270ea3a7 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0x2714c1d9 llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x271dd6e9 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x2724bfe0 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x272b66ec proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273cae41 nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x2769384d udp_disconnect +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x278e7e35 input_register_handle +EXPORT_SYMBOL vmlinux 0x27902389 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27ba722d framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27f74276 simple_link +EXPORT_SYMBOL vmlinux 0x27f979f0 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x2837e03b bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x285abfa1 __find_get_block +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x28649f29 get_user_pages +EXPORT_SYMBOL vmlinux 0x286e0987 inode_change_ok +EXPORT_SYMBOL vmlinux 0x2885b9f6 kmem_cache_create +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28b715a6 isapnp_cfg_end +EXPORT_SYMBOL vmlinux 0x28c5c7ce iunique +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28de42b4 bio_alloc +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x29592b27 bh_submit_read +EXPORT_SYMBOL vmlinux 0x2961d568 datagram_poll +EXPORT_SYMBOL vmlinux 0x296f0ac2 input_close_device +EXPORT_SYMBOL vmlinux 0x2997e38c tcp_ioctl +EXPORT_SYMBOL vmlinux 0x29a7f457 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0x29b1c366 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x29b7bc8c bd_set_size +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29d7caec jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x29e75ee0 vfs_readdir +EXPORT_SYMBOL vmlinux 0x2a05a0ef neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x2a29e860 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x2a2f645b fb_get_mode +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a7877aa __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x2a7efb63 journal_restart +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2ae2a9f8 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2af5f20a netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0x2af7a332 pcie_port_service_register +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b131652 neigh_lookup +EXPORT_SYMBOL vmlinux 0x2b27a233 unregister_filesystem +EXPORT_SYMBOL vmlinux 0x2b27c240 devm_iounmap +EXPORT_SYMBOL vmlinux 0x2b2c1004 tcf_hash_check +EXPORT_SYMBOL vmlinux 0x2b395a52 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x2b4e126b nobh_writepage +EXPORT_SYMBOL vmlinux 0x2b6a96e1 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2bc95bd4 memset +EXPORT_SYMBOL vmlinux 0x2bcc8b31 dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c016b10 cfb_copyarea +EXPORT_SYMBOL vmlinux 0x2c2c57e2 nla_put +EXPORT_SYMBOL vmlinux 0x2c2d6fe3 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x2c356ffd read_cache_pages +EXPORT_SYMBOL vmlinux 0x2c55907f gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c743f7f lease_modify +EXPORT_SYMBOL vmlinux 0x2c89bc37 request_key +EXPORT_SYMBOL vmlinux 0x2c8f5989 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0x2c9874fe ida_remove +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cd2fd07 page_address +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cdd061a write_cache_pages +EXPORT_SYMBOL vmlinux 0x2cf0a223 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2d078839 bdi_init +EXPORT_SYMBOL vmlinux 0x2d5d3aa2 sk_run_filter +EXPORT_SYMBOL vmlinux 0x2d5eb479 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0x2d64a73e contig_page_data +EXPORT_SYMBOL vmlinux 0x2d6c75b9 mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x2d86629e write_one_page +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2da90b25 generic_write_end +EXPORT_SYMBOL vmlinux 0x2dc34c5d neigh_connected_output +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2de28d77 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x2de2be96 scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2df6a725 dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x2df91093 inet6_ioctl +EXPORT_SYMBOL vmlinux 0x2e0eff6d pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x2e27d604 add_disk +EXPORT_SYMBOL vmlinux 0x2e28bf85 kernel_sendpage +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e36c869 misc_deregister +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e60bace memcpy +EXPORT_SYMBOL vmlinux 0x2e879b79 cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0x2e88a6d6 inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x2e97859f rwsem_downgrade_wake +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2ec562d1 handle_sysrq +EXPORT_SYMBOL vmlinux 0x2ee8815c copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x2eeed6e2 keyring_search +EXPORT_SYMBOL vmlinux 0x2f02be3b netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x2f05436d __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x2f0e20a1 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x2f27aec8 ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0x2f287f0d copy_to_user +EXPORT_SYMBOL vmlinux 0x2f52f1a3 unlock_rename +EXPORT_SYMBOL vmlinux 0x2f71a421 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x2f9e3d9a seq_puts +EXPORT_SYMBOL vmlinux 0x2fa431b0 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x2fb4aced remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x2fb9f37d ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x2fe01db4 audit_log_format +EXPORT_SYMBOL vmlinux 0x2fe3832e dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0x2fea099d dst_discard +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x2ff990cd __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x3019f7ac vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0x3054ef58 follow_down +EXPORT_SYMBOL vmlinux 0x30556bb8 vcc_insert_socket +EXPORT_SYMBOL vmlinux 0x3077f6e7 ip6_frag_init +EXPORT_SYMBOL vmlinux 0x30b50f06 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x30d8f5db set_pages_x +EXPORT_SYMBOL vmlinux 0x30e4de72 cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x30f5cbd8 dm_put_device +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x3114c3e0 I_BDEV +EXPORT_SYMBOL vmlinux 0x3123840e inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x3147b4d8 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x318cc727 alloc_file +EXPORT_SYMBOL vmlinux 0x3191f109 __krealloc +EXPORT_SYMBOL vmlinux 0x31e76b57 recalibrate_cpu_khz +EXPORT_SYMBOL vmlinux 0x3230b672 scsi_remove_device +EXPORT_SYMBOL vmlinux 0x325f0282 scsi_get_command +EXPORT_SYMBOL vmlinux 0x3269415a dma_supported +EXPORT_SYMBOL vmlinux 0x32825e6a bio_split +EXPORT_SYMBOL vmlinux 0x32ba5da9 arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32f6efd8 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x331e8e49 set_page_dirty +EXPORT_SYMBOL vmlinux 0x33476a27 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x335162a8 journal_start_commit +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x337dfeaf ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x3385c8cb per_cpu__this_cpu_off +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x34130538 xfrm_state_add +EXPORT_SYMBOL vmlinux 0x342f60fe apm_info +EXPORT_SYMBOL vmlinux 0x347b70fe tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x34986c3d simple_transaction_get +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34d5fea0 lock_sock_nested +EXPORT_SYMBOL vmlinux 0x34e4648f isapnp_protocol +EXPORT_SYMBOL vmlinux 0x34ed7cc9 pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x3519d156 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x3530e930 rt6_lookup +EXPORT_SYMBOL vmlinux 0x3554d5e6 elevator_init +EXPORT_SYMBOL vmlinux 0x35599f49 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0x3568af4b vfs_mkdir +EXPORT_SYMBOL vmlinux 0x35775ab8 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x35825634 fddi_type_trans +EXPORT_SYMBOL vmlinux 0x359188bc directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x359c8833 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x35b51aa3 elv_rb_add +EXPORT_SYMBOL vmlinux 0x35bbf58c init_task +EXPORT_SYMBOL vmlinux 0x35c02eaa kernel_bind +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35cc7614 lookup_bdev +EXPORT_SYMBOL vmlinux 0x35decc3f thaw_bdev +EXPORT_SYMBOL vmlinux 0x35e07b26 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x35f0faa2 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x3611e329 udp_ioctl +EXPORT_SYMBOL vmlinux 0x362d4436 bdget_disk +EXPORT_SYMBOL vmlinux 0x36363ed3 get_fs_type +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x366fc250 pcim_pin_device +EXPORT_SYMBOL vmlinux 0x3688bb02 sk_stream_error +EXPORT_SYMBOL vmlinux 0x36ef93db tr_type_trans +EXPORT_SYMBOL vmlinux 0x370194d8 get_empty_filp +EXPORT_SYMBOL vmlinux 0x3712f889 bdev_read_only +EXPORT_SYMBOL vmlinux 0x371960ee bdi_register_dev +EXPORT_SYMBOL vmlinux 0x3725ffc5 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x37289a06 vc_cons +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x3791bfd2 input_event +EXPORT_SYMBOL vmlinux 0x379d65f5 gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x37b982b7 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37c705a5 jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x37dfd47a pci_save_state +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x380f97cf atm_init_aal5 +EXPORT_SYMBOL vmlinux 0x382038bf __rta_fill +EXPORT_SYMBOL vmlinux 0x38203ca1 __init_rwsem +EXPORT_SYMBOL vmlinux 0x382d0eeb journal_flush +EXPORT_SYMBOL vmlinux 0x3839a902 hci_resume_dev +EXPORT_SYMBOL vmlinux 0x384c76f5 user_revoke +EXPORT_SYMBOL vmlinux 0x385ddbbc mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38db27e5 bio_map_kern +EXPORT_SYMBOL vmlinux 0x38ebbf06 ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0x38f9de5d bdget +EXPORT_SYMBOL vmlinux 0x39333b73 bio_pair_release +EXPORT_SYMBOL vmlinux 0x3937d3e5 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x39381b28 elevator_exit +EXPORT_SYMBOL vmlinux 0x39488bf2 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x397b2fcb flush_signals +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x399cc90c __dst_free +EXPORT_SYMBOL vmlinux 0x399f8bce pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x39c645a2 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x39cab296 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x39e30207 con_copy_unimap +EXPORT_SYMBOL vmlinux 0x3a014e40 tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x3a054468 dm_register_target +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a344181 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x3a933f01 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3ac69b1c seq_escape +EXPORT_SYMBOL vmlinux 0x3ad58175 log_wait_commit +EXPORT_SYMBOL vmlinux 0x3af28b69 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x3af98f9e ioremap_nocache +EXPORT_SYMBOL vmlinux 0x3b24846f __scm_destroy +EXPORT_SYMBOL vmlinux 0x3b2624ca seq_putc +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b3342a3 pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x3b573ba2 brioctl_set +EXPORT_SYMBOL vmlinux 0x3b678c16 __kfree_skb +EXPORT_SYMBOL vmlinux 0x3b6fbf12 journal_init_inode +EXPORT_SYMBOL vmlinux 0x3b7c4121 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x3b9e80f5 tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0x3ba50aae ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0x3ba5d711 skb_queue_head +EXPORT_SYMBOL vmlinux 0x3bd009cc rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3be5cb2a dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x3bfb1d4e tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x3c0d97bb jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x3c0e06b7 generic_make_request +EXPORT_SYMBOL vmlinux 0x3c108130 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x3c16bc47 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c4d856e dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c9a9429 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb32661 tty_port_init +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cee68d5 dquot_drop +EXPORT_SYMBOL vmlinux 0x3cfc23a9 dm_table_event +EXPORT_SYMBOL vmlinux 0x3d11f441 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0x3d1a4daf set_device_ro +EXPORT_SYMBOL vmlinux 0x3d856400 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x3d97a875 dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3db7d69d pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x3dc131bf icmp_send +EXPORT_SYMBOL vmlinux 0x3de03492 sg_miter_start +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e2d6db0 create_empty_buffers +EXPORT_SYMBOL vmlinux 0x3e32c5d6 acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e53a0af invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x3e58ed46 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x3e867a70 jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0x3e88244a dev_load +EXPORT_SYMBOL vmlinux 0x3e884e49 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x3eaf5c5c dma_async_client_register +EXPORT_SYMBOL vmlinux 0x3eb28de9 scsi_add_device +EXPORT_SYMBOL vmlinux 0x3ec8a9b7 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ed9b02b serio_close +EXPORT_SYMBOL vmlinux 0x3f04d9b7 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f0ce3c6 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f1f77db mmc_release_host +EXPORT_SYMBOL vmlinux 0x3f2c8eaf deny_write_access +EXPORT_SYMBOL vmlinux 0x3f39b162 up_write +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f6823a0 pci_fixup_device +EXPORT_SYMBOL vmlinux 0x3f6d019f prepare_binprm +EXPORT_SYMBOL vmlinux 0x3f6d1520 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x3f9ff492 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0x3fba3acc kthread_create +EXPORT_SYMBOL vmlinux 0x3fd72eed scsi_prep_return +EXPORT_SYMBOL vmlinux 0x3ff2ef45 dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x403e5c03 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x407ef3cc dma_pool_free +EXPORT_SYMBOL vmlinux 0x40892785 sock_i_uid +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x40ce0f65 scsi_execute +EXPORT_SYMBOL vmlinux 0x40d30eaa splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x413aea47 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x41527fa9 uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x41885662 thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x4190751c unregister_binfmt +EXPORT_SYMBOL vmlinux 0x4198b8d7 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x419e7b75 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41ad136e jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x41e0d832 kobject_get +EXPORT_SYMBOL vmlinux 0x41f2288e dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x42625344 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x426c3e36 fd_install +EXPORT_SYMBOL vmlinux 0x4292364c schedule +EXPORT_SYMBOL vmlinux 0x42b12597 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x42b89ce6 registered_fb +EXPORT_SYMBOL vmlinux 0x42c4d10a sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x42d40b58 nf_setsockopt +EXPORT_SYMBOL vmlinux 0x42d83f07 page_symlink +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x431051dc secpath_dup +EXPORT_SYMBOL vmlinux 0x4331152e __sk_dst_check +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x4361ebfc generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x4382e4d1 acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0x438a6705 ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x4395c569 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x439b288f udp_proc_register +EXPORT_SYMBOL vmlinux 0x43b40de7 kunmap_atomic +EXPORT_SYMBOL vmlinux 0x43bb16b0 bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x43de1dc2 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x4439b112 phy_attach +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x445d9a0c remove_arg_zero +EXPORT_SYMBOL vmlinux 0x4467de7b tty_port_tty_get +EXPORT_SYMBOL vmlinux 0x44970ec2 kmap_atomic +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44e72165 pci_bus_type +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44ec5e39 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x44f21bea idr_for_each +EXPORT_SYMBOL vmlinux 0x44fd8744 bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0x45264aa1 scsi_scan_target +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x45729cb4 skb_copy_bits +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x45d766a4 kset_unregister +EXPORT_SYMBOL vmlinux 0x45e38dca dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x45ef8bfa unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x463bd8db journal_release_buffer +EXPORT_SYMBOL vmlinux 0x4643ce3f unlock_new_inode +EXPORT_SYMBOL vmlinux 0x46595925 block_write_full_page +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x466c9963 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x466d81e0 generic_writepages +EXPORT_SYMBOL vmlinux 0x46a092a8 serio_unregister_port +EXPORT_SYMBOL vmlinux 0x46acb73b acpi_root_dir +EXPORT_SYMBOL vmlinux 0x46f265e2 generic_setxattr +EXPORT_SYMBOL vmlinux 0x46f4a894 audit_log_start +EXPORT_SYMBOL vmlinux 0x47047b9e proc_net_netfilter +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475ba927 arp_tbl +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x476dc659 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x4779d3fa simple_release_fs +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47a4c37f hci_connect +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47d4ea68 bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x47ea0a61 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x481f7066 scsi_host_put +EXPORT_SYMBOL vmlinux 0x482d519e journal_ack_err +EXPORT_SYMBOL vmlinux 0x4840f491 phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0x48414480 genphy_config_aneg +EXPORT_SYMBOL vmlinux 0x4850691a invalidate_partition +EXPORT_SYMBOL vmlinux 0x48554616 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x4863906d bio_init +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x48de3ace dma_set_mask +EXPORT_SYMBOL vmlinux 0x48e6348e pnp_start_dev +EXPORT_SYMBOL vmlinux 0x49073841 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0x490f813a udp_lib_get_port +EXPORT_SYMBOL vmlinux 0x49161c0d scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x49191f4a jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0x49390bb8 blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x4948dfa3 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x497936b0 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0x498c0e79 filemap_fault +EXPORT_SYMBOL vmlinux 0x499eeade mmc_free_host +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x49e453c4 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x4a105d93 dst_destroy +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a65943f nf_register_hooks +EXPORT_SYMBOL vmlinux 0x4a815567 generic_getxattr +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4ac1489c send_sig +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b136848 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b4f9597 __scm_send +EXPORT_SYMBOL vmlinux 0x4b6f3a5d inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4bad1ca7 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x4bb3d254 journal_get_create_access +EXPORT_SYMBOL vmlinux 0x4bb874cf sock_map_fd +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4be8c568 check_disk_size_change +EXPORT_SYMBOL vmlinux 0x4bf4c7ea skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x4bfc012c kill_pgrp +EXPORT_SYMBOL vmlinux 0x4bfd169a jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0x4c085430 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c6c3721 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0x4c7279d9 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cc71254 framebuffer_release +EXPORT_SYMBOL vmlinux 0x4cde122f inet_add_protocol +EXPORT_SYMBOL vmlinux 0x4d2dc830 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d632284 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x4d6d3bd4 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x4d6f4cca skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x4d76f0b7 kmem_cache_free +EXPORT_SYMBOL vmlinux 0x4db90644 nla_append +EXPORT_SYMBOL vmlinux 0x4dcb2ff5 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x4dcb5110 i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0x4dcd1139 pci_enable_msix +EXPORT_SYMBOL vmlinux 0x4dd295fe rfkill_register +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e0924fe scsi_host_get +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e342269 generic_listxattr +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e3d9c2e i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4e932484 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0x4eb47ad3 blk_integrity_register +EXPORT_SYMBOL vmlinux 0x4ed74c8b tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0x4edb482c alloc_trdev +EXPORT_SYMBOL vmlinux 0x4f3da99f mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f4d7fd6 release_sock +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4f6c192e bio_copy_kern +EXPORT_SYMBOL vmlinux 0x4f964d8a dentry_open +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4fe1af5c follow_up +EXPORT_SYMBOL vmlinux 0x4fed064f dev_mc_sync +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x50229925 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x5028c546 mark_info_dirty +EXPORT_SYMBOL vmlinux 0x504ce5ee blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x509294f9 fb_is_primary_device +EXPORT_SYMBOL vmlinux 0x50ad05bc pci_reenable_device +EXPORT_SYMBOL vmlinux 0x50b5ff1b misc_register +EXPORT_SYMBOL vmlinux 0x50eea825 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0x51104a42 input_allocate_device +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x51435a57 file_permission +EXPORT_SYMBOL vmlinux 0x5144b640 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x5147b595 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0x5147f4d6 md_unregister_thread +EXPORT_SYMBOL vmlinux 0x5152e605 memcmp +EXPORT_SYMBOL vmlinux 0x515d34cf bitmap_startwrite +EXPORT_SYMBOL vmlinux 0x5169af3f neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x518245ca init_buffer +EXPORT_SYMBOL vmlinux 0x51848c73 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x518eb764 per_cpu__cpu_number +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ed4dbe pci_restore_state +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x52004f0e pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x520c6333 pci_get_device +EXPORT_SYMBOL vmlinux 0x520fe0af netif_device_attach +EXPORT_SYMBOL vmlinux 0x52256b55 __page_symlink +EXPORT_SYMBOL vmlinux 0x522c20a4 qdisc_list_del +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52c8a069 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52e24296 key_validate +EXPORT_SYMBOL vmlinux 0x530af042 sk_stop_timer +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x53172628 request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x5372bad5 uart_resume_port +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53f5dbe4 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x5436acc2 __ht_create_irq +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x543f9bff pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x5487cc3a dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x54935666 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0x54ad8a66 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x54eb7021 dm_io +EXPORT_SYMBOL vmlinux 0x54fd88c2 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0x553f9dd3 down_read_trylock +EXPORT_SYMBOL vmlinux 0x5570a812 pci_request_regions +EXPORT_SYMBOL vmlinux 0x557eb83d __blk_run_queue +EXPORT_SYMBOL vmlinux 0x55847079 new_inode +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55be4c14 may_umount_tree +EXPORT_SYMBOL vmlinux 0x55ca79f9 d_alloc_root +EXPORT_SYMBOL vmlinux 0x55e1898c generic_delete_inode +EXPORT_SYMBOL vmlinux 0x55eb1733 sync_inode +EXPORT_SYMBOL vmlinux 0x55ebeb1d dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x5608354e nonseekable_open +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x5617a159 neigh_for_each +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x563feb93 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56d0d9b0 acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0x56dfe330 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0x56f1c5dd pci_assign_resource +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x56fc603b pagecache_write_end +EXPORT_SYMBOL vmlinux 0x570028f7 register_binfmt +EXPORT_SYMBOL vmlinux 0x571475f1 ppp_input +EXPORT_SYMBOL vmlinux 0x5721574c i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x5739f570 simple_fill_super +EXPORT_SYMBOL vmlinux 0x573ea46a shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x578394bf proto_register +EXPORT_SYMBOL vmlinux 0x578b9a02 journal_force_commit +EXPORT_SYMBOL vmlinux 0x578cb0fd ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x57a3a7c1 __elv_add_request +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57a9cf21 register_8022_client +EXPORT_SYMBOL vmlinux 0x57dc8bc3 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x580beab6 nf_log_packet +EXPORT_SYMBOL vmlinux 0x581c5241 fb_show_logo +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x586de011 inet_getname +EXPORT_SYMBOL vmlinux 0x58a79678 set_pages_uc +EXPORT_SYMBOL vmlinux 0x58ad58eb blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x58c83a61 d_genocide +EXPORT_SYMBOL vmlinux 0x58fef6f8 ist_info +EXPORT_SYMBOL vmlinux 0x59128910 skb_dma_map +EXPORT_SYMBOL vmlinux 0x5931b9d1 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x59320710 blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x593408b7 __pci_register_driver +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594a8651 alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x596a1466 jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x59788703 pci_disable_msix +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x5992a86c d_validate +EXPORT_SYMBOL vmlinux 0x59b4a752 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59d8223a ioport_resource +EXPORT_SYMBOL vmlinux 0x59e04f25 phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0x59ff49e9 sk_dst_check +EXPORT_SYMBOL vmlinux 0x5a12892e kobject_put +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a4dacf1 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x5a5e2106 jbd2_journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x5a619b01 inode_setattr +EXPORT_SYMBOL vmlinux 0x5a694b00 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5a82e1c9 blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x5aa3c0c6 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x5aad9570 vfs_readv +EXPORT_SYMBOL vmlinux 0x5ab6a6ab setup_arg_pages +EXPORT_SYMBOL vmlinux 0x5ab82ec6 scsi_print_sense +EXPORT_SYMBOL vmlinux 0x5abfe1ea sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5ad5fb16 mdio_bus_type +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b355ff2 input_set_keycode +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5b703ec0 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0x5b761564 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x5b933fab register_nls +EXPORT_SYMBOL vmlinux 0x5bba1689 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0x5c15a686 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x5c19c70e scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x5c1ad8df blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x5c1badd8 kernel_read +EXPORT_SYMBOL vmlinux 0x5c1bfd22 dmam_pool_create +EXPORT_SYMBOL vmlinux 0x5c265cba sg_init_one +EXPORT_SYMBOL vmlinux 0x5c68705b mca_read_pos +EXPORT_SYMBOL vmlinux 0x5c744d74 seq_open +EXPORT_SYMBOL vmlinux 0x5cfd2452 freeze_bdev +EXPORT_SYMBOL vmlinux 0x5d2f4f14 skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x5d3c3c8d vmap +EXPORT_SYMBOL vmlinux 0x5d54a66e i2c_transfer +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5db2bcfc __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x5db8b229 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dd4cc9f set_binfmt +EXPORT_SYMBOL vmlinux 0x5e095f11 cdrom_release +EXPORT_SYMBOL vmlinux 0x5e160be1 pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x5e29331d unlock_page +EXPORT_SYMBOL vmlinux 0x5e2de2dd pcie_get_readrq +EXPORT_SYMBOL vmlinux 0x5e56c388 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x5e57c772 ilookup5 +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e8af1da dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x5e8f7507 phy_register_fixup +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ea72cf2 hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0x5eaabac9 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x5eb11b78 netlink_broadcast +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f123ead ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0x5f1bd579 mca_find_adapter +EXPORT_SYMBOL vmlinux 0x5f388541 ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x5f5a778a blk_sync_queue +EXPORT_SYMBOL vmlinux 0x5f98ee36 cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0x5fbfdbeb dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x5fc9bbdf i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x5ff3d3dd vfs_getattr +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x6005137c inet_frags_fini +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x6061f790 tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x607e2aa2 xfrm_init_state +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x6092a34d inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60adf259 tty_devnum +EXPORT_SYMBOL vmlinux 0x60aec81f dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x60b7f0a6 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0x60d997d4 kunmap_high +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x611b6b8c xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61910d2a wireless_spy_update +EXPORT_SYMBOL vmlinux 0x6194821c inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x61a2cbfc pci_find_slot +EXPORT_SYMBOL vmlinux 0x61a8cbc2 unregister_con_driver +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61d6198f inet_accept +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6228d3b9 vfs_follow_link +EXPORT_SYMBOL vmlinux 0x622fea50 path_put +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x6241a2ab __copy_from_user_ll_nocache +EXPORT_SYMBOL vmlinux 0x6241fd2c acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0x624cf50f set_bh_page +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62812076 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x62c87b46 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0x632994e6 dquot_commit_info +EXPORT_SYMBOL vmlinux 0x633ccc46 unregister_console +EXPORT_SYMBOL vmlinux 0x634edd41 posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x6354a49d pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x63777fcf ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x638b5baa mdiobus_scan +EXPORT_SYMBOL vmlinux 0x63ec7b58 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f2828d end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x64004167 skb_unlink +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x64143622 jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x6420a40f kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x64223927 bio_sector_offset +EXPORT_SYMBOL vmlinux 0x64230654 mapping_tagged +EXPORT_SYMBOL vmlinux 0x6429f238 block_write_begin +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x643dda50 hci_unregister_proto +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x647d31b1 scm_detach_fds +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64b23183 security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x64f131ec register_con_driver +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650dcabe kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x65344f41 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x65434294 generic_fillattr +EXPORT_SYMBOL vmlinux 0x656c053b dget_locked +EXPORT_SYMBOL vmlinux 0x6587c38b generic_readlink +EXPORT_SYMBOL vmlinux 0x6590304f elv_rb_del +EXPORT_SYMBOL vmlinux 0x659d6c5b pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0x65c1b622 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x65d688a2 __neigh_event_send +EXPORT_SYMBOL vmlinux 0x662a8031 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x66377d70 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66c6fe82 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x66cdd741 init_special_inode +EXPORT_SYMBOL vmlinux 0x66d5d510 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x66d7083d tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x66de1f4c invalidate_bdev +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x67314176 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x679bf522 d_invalidate +EXPORT_SYMBOL vmlinux 0x679c0c1c scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x679fc786 md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67ded4d0 llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x6853c5cb bt_accept_unlink +EXPORT_SYMBOL vmlinux 0x6872228c __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x68783e70 sk_wait_data +EXPORT_SYMBOL vmlinux 0x6895fca3 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x68abf5d7 bt_sock_unlink +EXPORT_SYMBOL vmlinux 0x68b5dff8 phy_connect +EXPORT_SYMBOL vmlinux 0x68f358ab input_free_device +EXPORT_SYMBOL vmlinux 0x692c2d9c __request_region +EXPORT_SYMBOL vmlinux 0x694ff9b8 sock_rfree +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x697d5c87 register_snap_client +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69cc21ff km_new_mapping +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69dac956 inetdev_by_index +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69f26828 kobject_set_name +EXPORT_SYMBOL vmlinux 0x69f3e32f xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a21d477 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x6a27bfce csum_partial_copy_generic +EXPORT_SYMBOL vmlinux 0x6a3d908b tcp_sync_mss +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a4ffc6c bitmap_end_sync +EXPORT_SYMBOL vmlinux 0x6a663476 bdput +EXPORT_SYMBOL vmlinux 0x6a6cc4bb key_payload_reserve +EXPORT_SYMBOL vmlinux 0x6a96947c kunmap +EXPORT_SYMBOL vmlinux 0x6a9e53c2 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x6ac9e583 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6ae0d8a0 pnp_possible_config +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b250f7d task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b35c110 sock_no_getname +EXPORT_SYMBOL vmlinux 0x6b38c524 simple_rmdir +EXPORT_SYMBOL vmlinux 0x6b688eee take_over_console +EXPORT_SYMBOL vmlinux 0x6b937ffb mca_mark_as_used +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6baff430 qdisc_destroy +EXPORT_SYMBOL vmlinux 0x6bd15acc tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c2e3320 strncmp +EXPORT_SYMBOL vmlinux 0x6c308358 load_nls +EXPORT_SYMBOL vmlinux 0x6c3812c6 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6caff4bb nf_log_unregister +EXPORT_SYMBOL vmlinux 0x6cb04278 kmap_high +EXPORT_SYMBOL vmlinux 0x6cdac053 kill_anon_super +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6cec7b09 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x6cefce95 scsi_unregister +EXPORT_SYMBOL vmlinux 0x6d03a186 generic_file_mmap +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d10832b key_put +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d464175 __sg_free_table +EXPORT_SYMBOL vmlinux 0x6d56994a cmpxchg_486_u64 +EXPORT_SYMBOL vmlinux 0x6d5fb993 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x6d771ec2 phy_device_create +EXPORT_SYMBOL vmlinux 0x6dbd6e20 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6dc37077 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0x6dcca038 kick_iocb +EXPORT_SYMBOL vmlinux 0x6dd459e2 phy_driver_register +EXPORT_SYMBOL vmlinux 0x6decbf46 blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x6dee7be5 dump_fpu +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6df98977 d_splice_alias +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e3595eb scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e46f06c grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0x6e670711 alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e7d3db3 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x6e868010 tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0x6e9a538a sockfd_lookup +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6eac7410 skb_split +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ebe3fdf vfs_link +EXPORT_SYMBOL vmlinux 0x6ec0c3e6 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0x6eed36b9 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x6ef9ddce hci_get_route +EXPORT_SYMBOL vmlinux 0x6f330795 kmap +EXPORT_SYMBOL vmlinux 0x6f872a71 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x6fa9b581 journal_wipe +EXPORT_SYMBOL vmlinux 0x6fbd7beb unlock_buffer +EXPORT_SYMBOL vmlinux 0x6fc5cd88 file_update_time +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fceef9d kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x6fd4c54e kernel_listen +EXPORT_SYMBOL vmlinux 0x6ff1a367 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701996b0 vfs_symlink +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x702f66cd __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x70461a22 key_revoke +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x707081b3 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x70a03aef mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x70a854c6 inet_ioctl +EXPORT_SYMBOL vmlinux 0x70ab7283 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x70b285b0 sock_sendmsg +EXPORT_SYMBOL vmlinux 0x70bf2cba phy_disconnect +EXPORT_SYMBOL vmlinux 0x70c6264f journal_lock_updates +EXPORT_SYMBOL vmlinux 0x70d1f8f3 strncat +EXPORT_SYMBOL vmlinux 0x70d2f648 i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x70ed1a26 noop_qdisc +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x712e4669 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x713d2149 sysctl_data +EXPORT_SYMBOL vmlinux 0x714c7a81 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x71519f43 do_splice_from +EXPORT_SYMBOL vmlinux 0x716a4d77 set_pages_wb +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7172b26e dm_table_put +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71afab3d xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0x71dfee8f iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0x71e53a18 xfrm_state_update +EXPORT_SYMBOL vmlinux 0x71eff7f3 md_done_sync +EXPORT_SYMBOL vmlinux 0x71f4c0bf fb_class +EXPORT_SYMBOL vmlinux 0x7202585a xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x72150358 mca_device_set_claim +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x722abc0e journal_start +EXPORT_SYMBOL vmlinux 0x722b13ac arp_xmit +EXPORT_SYMBOL vmlinux 0x722d5390 llc_sap_find +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x726cb1d4 pci_release_regions +EXPORT_SYMBOL vmlinux 0x727ba946 pci_set_mwi +EXPORT_SYMBOL vmlinux 0x728b0b39 pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x728b0bff scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x72ab6c64 sysctl_intvec +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72b4bede inet_shutdown +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72c945b7 lock_may_write +EXPORT_SYMBOL vmlinux 0x72ca2736 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x72d11c5b input_release_device +EXPORT_SYMBOL vmlinux 0x72e89b84 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x72e8d61b __ip_select_ident +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72ecc76b xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x7300d611 bitmap_endwrite +EXPORT_SYMBOL vmlinux 0x7319fc63 tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x7340eeee blk_register_region +EXPORT_SYMBOL vmlinux 0x7359911b register_qdisc +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x7373bf16 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x737ae737 tty_register_device +EXPORT_SYMBOL vmlinux 0x738803e6 strnlen +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x73b2203e vfs_quota_off +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x73eaff59 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x74031ff1 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x7413793a EISA_bus +EXPORT_SYMBOL vmlinux 0x74164462 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x74470d95 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x74671acf pci_set_master +EXPORT_SYMBOL vmlinux 0x74780751 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74d38929 alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0x75271716 save_processor_state +EXPORT_SYMBOL vmlinux 0x75566739 complete_request_key +EXPORT_SYMBOL vmlinux 0x75707815 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x758a15ba register_key_type +EXPORT_SYMBOL vmlinux 0x75cbf1f2 simple_sync_file +EXPORT_SYMBOL vmlinux 0x75f4563f cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x76406e31 devm_ioremap +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x76859dc1 scsi_print_command +EXPORT_SYMBOL vmlinux 0x768c33c4 inet_addr_type +EXPORT_SYMBOL vmlinux 0x76928ad3 scsi_print_result +EXPORT_SYMBOL vmlinux 0x76b0f8f8 bad_dma_address +EXPORT_SYMBOL vmlinux 0x76b2de16 scsi_scan_host +EXPORT_SYMBOL vmlinux 0x76b320c8 put_disk +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x770a0036 isapnp_cfg_begin +EXPORT_SYMBOL vmlinux 0x772657f4 ps2_drain +EXPORT_SYMBOL vmlinux 0x772e6c93 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x774d4cec dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0x775f4839 sync_page_range +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x7780f5b9 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77a33baa xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0x77ca661b netdev_features_change +EXPORT_SYMBOL vmlinux 0x77cdd7f9 blkdev_get +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x78196d62 file_fsync +EXPORT_SYMBOL vmlinux 0x78345ec1 qdisc_reset +EXPORT_SYMBOL vmlinux 0x7868cbc1 tcp_child_process +EXPORT_SYMBOL vmlinux 0x78862935 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x788fe103 iomem_resource +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78cb2783 down_write_trylock +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x79180acd phy_start +EXPORT_SYMBOL vmlinux 0x7923aa78 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x7924fbce scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79834f28 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0x79875f57 register_netdev +EXPORT_SYMBOL vmlinux 0x79a531d0 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79b5ad20 udplite_prot +EXPORT_SYMBOL vmlinux 0x79cb041b flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x7a22a9b8 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a47ff5f get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x7a61f66a ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0x7a725361 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x7a7a8f68 scsi_add_host +EXPORT_SYMBOL vmlinux 0x7a817f76 ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7a84dbd8 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x7a8b7285 block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0x7ab275ba hci_send_sco +EXPORT_SYMBOL vmlinux 0x7ada6b9d ndisc_mc_map +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7afba4f3 wireless_send_event +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b134ddf acpi_get_name +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b69467e posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x7b87cb3b ilookup +EXPORT_SYMBOL vmlinux 0x7b8b85fb dump_trace +EXPORT_SYMBOL vmlinux 0x7b935b18 netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x7b9feeb6 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x7ba2c30d wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x7bb627e6 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x7bbbf7c6 udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x7bc27785 inet_sendmsg +EXPORT_SYMBOL vmlinux 0x7bc52287 devm_ioport_map +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7c0edd7d acpi_check_region +EXPORT_SYMBOL vmlinux 0x7c44dcd8 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c4e8c59 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c76c61f mdiobus_read +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7ca8bbf3 bdi_unregister +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7ce5271e nobh_write_end +EXPORT_SYMBOL vmlinux 0x7cef9dd6 bio_integrity_trim +EXPORT_SYMBOL vmlinux 0x7cf766a9 km_policy_notify +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d1b4e2d journal_stop +EXPORT_SYMBOL vmlinux 0x7d2eb58b dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0x7d32666c scsi_remove_target +EXPORT_SYMBOL vmlinux 0x7d46119b skb_checksum_help +EXPORT_SYMBOL vmlinux 0x7d69b957 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x7d79a978 request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x7d7d991e xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7da9e65d eisa_driver_register +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7dd19d94 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x7dd8bbf0 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x7e0f9289 jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x7e109480 unregister_md_personality +EXPORT_SYMBOL vmlinux 0x7e16ccb2 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x7e1d9bf8 end_request +EXPORT_SYMBOL vmlinux 0x7e379fc3 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x7e712f53 generic_write_checks +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7eb5a593 __scsi_add_device +EXPORT_SYMBOL vmlinux 0x7ebbc8f3 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x7edb9c6a acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f3b5d1a __lock_page +EXPORT_SYMBOL vmlinux 0x7f5728af key_type_keyring +EXPORT_SYMBOL vmlinux 0x7f6b437d md_write_end +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7f8cfd72 __break_lease +EXPORT_SYMBOL vmlinux 0x7fb33538 tty_name +EXPORT_SYMBOL vmlinux 0x7fbe9989 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x7fc3629c mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x7fef7eee phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0x80153fe8 nf_hook_slow +EXPORT_SYMBOL vmlinux 0x80241a23 xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x80321a52 task_nice +EXPORT_SYMBOL vmlinux 0x8041902f pnpbios_protocol +EXPORT_SYMBOL vmlinux 0x804b288a mpage_readpage +EXPORT_SYMBOL vmlinux 0x8059093d simple_transaction_release +EXPORT_SYMBOL vmlinux 0x805d39a0 bdevname +EXPORT_SYMBOL vmlinux 0x805dbbd2 dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x806b5d8b free_buffer_head +EXPORT_SYMBOL vmlinux 0x8086365b ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0x8099d247 nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x80c427b0 i2c_release_client +EXPORT_SYMBOL vmlinux 0x80d84445 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x80e223c0 acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0x80e4761b flush_tlb_page +EXPORT_SYMBOL vmlinux 0x812c382b __breadahead +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x816697cc uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x8181295d pcibios_set_irq_routing +EXPORT_SYMBOL vmlinux 0x81934640 __pagevec_release +EXPORT_SYMBOL vmlinux 0x81adf86a tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x8226a985 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x8235805b memmove +EXPORT_SYMBOL vmlinux 0x823631fa scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x824ca972 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82673561 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x82786b06 input_flush_device +EXPORT_SYMBOL vmlinux 0x827acb2f xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x82898b25 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x828d5b95 d_alloc +EXPORT_SYMBOL vmlinux 0x828f6b2b request_key_async +EXPORT_SYMBOL vmlinux 0x82b12fa2 make_EII_client +EXPORT_SYMBOL vmlinux 0x82b1ad25 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x82e1e45b sk_free +EXPORT_SYMBOL vmlinux 0x82e637cc pci_choose_state +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x8313bebd sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x8342311c __nla_reserve +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83c9f9ec netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x83d47263 i2c_clients_command +EXPORT_SYMBOL vmlinux 0x83d8ae11 i2c_use_client +EXPORT_SYMBOL vmlinux 0x84130c61 zero_fill_bio +EXPORT_SYMBOL vmlinux 0x84265db3 pnp_device_attach +EXPORT_SYMBOL vmlinux 0x8488cb28 __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x84b3afee proc_create_data +EXPORT_SYMBOL vmlinux 0x84b5c17a alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x8507c8ba __napi_schedule +EXPORT_SYMBOL vmlinux 0x851c3d5b netif_device_detach +EXPORT_SYMBOL vmlinux 0x854285f8 set_disk_ro +EXPORT_SYMBOL vmlinux 0x855f2d54 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x85729cab udp_poll +EXPORT_SYMBOL vmlinux 0x857bb470 proto_unregister +EXPORT_SYMBOL vmlinux 0x85a578f7 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x85b0a504 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x85b913e6 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x85bd6254 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x85df6b0e dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e26801 dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x85ee5498 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x86085f06 sg_miter_next +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x867a5fa4 __getblk +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86c2b936 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0x86e29041 kill_litter_super +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x870cf3d2 bt_sock_poll +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x872ac729 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x872c830f pci_select_bars +EXPORT_SYMBOL vmlinux 0x872e77de d_lookup +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x87412c57 pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0x8747d16d skb_under_panic +EXPORT_SYMBOL vmlinux 0x874df003 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87a5ad3a save_mount_options +EXPORT_SYMBOL vmlinux 0x87a62295 force_sig +EXPORT_SYMBOL vmlinux 0x87bef93f fb_set_var +EXPORT_SYMBOL vmlinux 0x87c26f4b mark_page_accessed +EXPORT_SYMBOL vmlinux 0x880198e4 nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x886ba1e0 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0x88a53b3c phy_scan_fixups +EXPORT_SYMBOL vmlinux 0x88d21435 sync_blockdev +EXPORT_SYMBOL vmlinux 0x88e86e33 mca_device_read_pos +EXPORT_SYMBOL vmlinux 0x88e88136 ioremap_prot +EXPORT_SYMBOL vmlinux 0x88f0dbc5 jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x89368404 mca_device_status +EXPORT_SYMBOL vmlinux 0x8941125a dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x8949858b schedule_work +EXPORT_SYMBOL vmlinux 0x894a4181 xfrm_lookup +EXPORT_SYMBOL vmlinux 0x89536a92 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x8959c2f7 devm_free_irq +EXPORT_SYMBOL vmlinux 0x8969b997 ida_get_new +EXPORT_SYMBOL vmlinux 0x896e8b1c xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x897a7746 blkdev_put +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89cb601b unregister_qdisc +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89d7a6e8 seq_open_private +EXPORT_SYMBOL vmlinux 0x89e910c5 jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a4cd1d9 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a93a957 scsi_device_get +EXPORT_SYMBOL vmlinux 0x8a9805a2 lookup_one_len +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aaf00db tty_throttle +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8ad181e9 dev_set_mtu +EXPORT_SYMBOL vmlinux 0x8afe00f6 devm_request_irq +EXPORT_SYMBOL vmlinux 0x8b18496f __copy_to_user_ll +EXPORT_SYMBOL vmlinux 0x8b4321b2 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b523f65 should_remove_suid +EXPORT_SYMBOL vmlinux 0x8b57e096 gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b7869a1 tc_classify +EXPORT_SYMBOL vmlinux 0x8b9339c1 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8ba20cc5 dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0x8babedd8 tty_check_change +EXPORT_SYMBOL vmlinux 0x8bba0910 register_console +EXPORT_SYMBOL vmlinux 0x8bc5b95e __alloc_skb +EXPORT_SYMBOL vmlinux 0x8bf1830a __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c19fc3a phy_driver_unregister +EXPORT_SYMBOL vmlinux 0x8c3f4778 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x8c418390 do_splice_to +EXPORT_SYMBOL vmlinux 0x8c5e6be9 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0x8c886c70 __invalidate_device +EXPORT_SYMBOL vmlinux 0x8c932932 blk_init_queue +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8cd55216 set_blocksize +EXPORT_SYMBOL vmlinux 0x8d29a1a4 arp_find +EXPORT_SYMBOL vmlinux 0x8d2c1653 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x8d2ccb94 seq_path +EXPORT_SYMBOL vmlinux 0x8d37f690 mca_device_read_stored_pos +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d4c9b61 mca_register_driver +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8d9b5928 blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0x8dc6e564 restore_processor_state +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0243f8 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e1b20f3 acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x8e1dda62 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x8e25d9a9 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x8e337d8e __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x8e537fce dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0x8e55cd3b proc_symlink +EXPORT_SYMBOL vmlinux 0x8e693771 uart_register_driver +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8eb34bcf ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0x8eea456c pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x8f1650ce blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x8f338b9a alloc_disk +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8fbecdf3 sock_no_bind +EXPORT_SYMBOL vmlinux 0x8fccae57 inet_csk_accept +EXPORT_SYMBOL vmlinux 0x8ff31ab5 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x8ffdb3b8 crc16 +EXPORT_SYMBOL vmlinux 0x8fffba3f inet_release +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x904d25a2 boot_cpu_data +EXPORT_SYMBOL vmlinux 0x907d3d86 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x909de549 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a4343e textsearch_destroy +EXPORT_SYMBOL vmlinux 0x90a56b73 blk_integrity_compare +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90d07b1b pneigh_lookup +EXPORT_SYMBOL vmlinux 0x90e4125c inet_bind +EXPORT_SYMBOL vmlinux 0x9109c43e sock_create_kern +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x917f61b6 sock_recvmsg +EXPORT_SYMBOL vmlinux 0x91847945 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x919d4756 per_cpu__current_task +EXPORT_SYMBOL vmlinux 0x91a64f99 __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x91b23afd sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x91f17061 mdiobus_unregister +EXPORT_SYMBOL vmlinux 0x92006973 scsi_ioctl +EXPORT_SYMBOL vmlinux 0x922b9eaf pnp_disable_dev +EXPORT_SYMBOL vmlinux 0x922ff447 eisa_bus_type +EXPORT_SYMBOL vmlinux 0x9230b924 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x923533fb scsi_free_command +EXPORT_SYMBOL vmlinux 0x9249cceb iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x9273599b i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0x92823079 pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x92897e3d default_idle +EXPORT_SYMBOL vmlinux 0x928e8070 posix_test_lock +EXPORT_SYMBOL vmlinux 0x92c5cfb0 lock_super +EXPORT_SYMBOL vmlinux 0x92ef09d6 tcp_shutdown +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x932bb57b tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x9330cb9f sg_alloc_table +EXPORT_SYMBOL vmlinux 0x934233d8 sk_filter +EXPORT_SYMBOL vmlinux 0x935cd69d skb_find_text +EXPORT_SYMBOL vmlinux 0x938f99e1 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93a81f3f blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x93afa72e vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x941a1a78 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x941f9534 sget +EXPORT_SYMBOL vmlinux 0x94234b93 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x942941e6 d_delete +EXPORT_SYMBOL vmlinux 0x943ba017 pci_pme_capable +EXPORT_SYMBOL vmlinux 0x945bd05f fsync_bdev +EXPORT_SYMBOL vmlinux 0x9475496c ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94aa3e1e dm_table_get +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x951c6cc0 sock_create +EXPORT_SYMBOL vmlinux 0x95214ab2 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x9550a47a pci_request_region +EXPORT_SYMBOL vmlinux 0x9550ebfc pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x956b4798 page_put_link +EXPORT_SYMBOL vmlinux 0x9579dabf blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x95871d5d gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x959b0ba8 proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0x95b39eb0 iput +EXPORT_SYMBOL vmlinux 0x95bd0799 dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0x95cee834 __serio_register_port +EXPORT_SYMBOL vmlinux 0x95d435f5 xrlim_allow +EXPORT_SYMBOL vmlinux 0x95d58dc8 km_policy_expired +EXPORT_SYMBOL vmlinux 0x95e958cb tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x95eaba58 mca_unregister_driver +EXPORT_SYMBOL vmlinux 0x95f638d5 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x96163c66 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x962cf617 skb_push +EXPORT_SYMBOL vmlinux 0x9634498a rfkill_allocate +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x9651fa13 ip_defrag +EXPORT_SYMBOL vmlinux 0x96577a89 pci_find_device +EXPORT_SYMBOL vmlinux 0x96589fb1 dquot_free_space +EXPORT_SYMBOL vmlinux 0x96609839 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x9674edd9 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x968acd8f pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0x968d0f44 dst_alloc +EXPORT_SYMBOL vmlinux 0x96978e8c elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x96c6452c kill_block_super +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96ddda45 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x97086474 mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x974ec76a may_umount +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x9768aabc tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0x978550b9 dquot_transfer +EXPORT_SYMBOL vmlinux 0x978b774f dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x9798be38 call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0x97b83a8d i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x97eda7e5 find_get_page +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x9810e696 generic_removexattr +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x98884059 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x98902632 inet_put_port +EXPORT_SYMBOL vmlinux 0x98953d2c ppp_channel_index +EXPORT_SYMBOL vmlinux 0x98c945ee cfb_imageblit +EXPORT_SYMBOL vmlinux 0x98f0a4e8 inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x99052a84 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x9911117f sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x9920963f set_trace_device +EXPORT_SYMBOL vmlinux 0x994fe524 put_page +EXPORT_SYMBOL vmlinux 0x99547913 journal_set_features +EXPORT_SYMBOL vmlinux 0x9980b143 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99ed3b57 pci_find_bus +EXPORT_SYMBOL vmlinux 0x9a091a4b tcf_exts_change +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a6a83f9 cmos_lock +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9ac72c28 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x9ae9a7ef xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b4de8eb idr_replace +EXPORT_SYMBOL vmlinux 0x9b50eb50 dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0x9b796bb2 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x9b816ffa nf_reinject +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bce482f __release_region +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c02d1f4 put_filp +EXPORT_SYMBOL vmlinux 0x9c04217d blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x9c0a0640 skb_trim +EXPORT_SYMBOL vmlinux 0x9c22a4b8 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x9c2c944a __copy_from_user_ll_nocache_nozero +EXPORT_SYMBOL vmlinux 0x9c419f48 generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x9c5413c3 pci_map_rom +EXPORT_SYMBOL vmlinux 0x9c54f661 sock_setsockopt +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c9f358d serio_open +EXPORT_SYMBOL vmlinux 0x9cb2ca9f inet6_add_protocol +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d0b4a47 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0x9d13b7a6 tcp_poll +EXPORT_SYMBOL vmlinux 0x9d2f5cd2 scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x9d30bb32 scsi_register +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9d856db0 journal_get_write_access +EXPORT_SYMBOL vmlinux 0x9d93719a dm_table_get_mode +EXPORT_SYMBOL vmlinux 0x9d9f0d41 rwsem_down_write_failed +EXPORT_SYMBOL vmlinux 0x9dc5cee0 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x9df8846e per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0x9e03e41a nf_log_register +EXPORT_SYMBOL vmlinux 0x9e066b7c end_page_writeback +EXPORT_SYMBOL vmlinux 0x9e26f1a2 key_unlink +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e3cc838 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e672ff6 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x9e72e4df dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9e833fba scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x9e9b9f03 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9ed6b7bf hippi_type_trans +EXPORT_SYMBOL vmlinux 0x9ee5ea36 __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef42842 pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f0ba79e dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9ffd5c59 neigh_seq_next +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa071a02f sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0xa096cfb2 alloc_fcdev +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0fa4d5f dm_unregister_target +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa0fec2ec vfs_writev +EXPORT_SYMBOL vmlinux 0xa1003014 tcp_parse_options +EXPORT_SYMBOL vmlinux 0xa108cc9b dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa1174263 key_task_permission +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa130db30 drop_super +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa158f9e0 inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0xa1774840 unregister_quota_format +EXPORT_SYMBOL vmlinux 0xa1814c2d neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xa19a55e5 user_path_at +EXPORT_SYMBOL vmlinux 0xa1b5fedd jbd2_journal_create +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1bd0b84 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1ca2bb8 journal_abort +EXPORT_SYMBOL vmlinux 0xa1f350f5 __secpath_destroy +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa212f14c simple_statfs +EXPORT_SYMBOL vmlinux 0xa23a1cad is_container_init +EXPORT_SYMBOL vmlinux 0xa258c3d8 __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0xa2751f88 scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0xa285bdd8 neigh_destroy +EXPORT_SYMBOL vmlinux 0xa2892a4d blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0xa28ad126 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2a6d70c md_check_recovery +EXPORT_SYMBOL vmlinux 0xa2b09feb nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0xa2b2886a tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0xa2eb2e1c mpage_bio_submit +EXPORT_SYMBOL vmlinux 0xa2f0bcae remove_inode_hash +EXPORT_SYMBOL vmlinux 0xa2f2f5ad block_invalidatepage +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa330fce8 llc_sap_close +EXPORT_SYMBOL vmlinux 0xa332b7e7 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0xa344fbd5 proc_dostring +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa356f0a1 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0xa35c1f05 acpi_extract_package +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3c13893 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0xa408a346 jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0xa422b36f kset_register +EXPORT_SYMBOL vmlinux 0xa43013de __bread +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa4a0953a nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0xa4a704a2 ether_setup +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4b955ab bio_integrity_clone +EXPORT_SYMBOL vmlinux 0xa4daf8bb block_write_end +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa4fea44d ppp_input_error +EXPORT_SYMBOL vmlinux 0xa51cdfe8 __FIXADDR_TOP +EXPORT_SYMBOL vmlinux 0xa5373be6 kobject_del +EXPORT_SYMBOL vmlinux 0xa538b48a pnp_find_dev +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa57a2f99 blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0xa58a1fb8 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa5a633b9 sg_last +EXPORT_SYMBOL vmlinux 0xa5ab5a1a skb_truesize_bug +EXPORT_SYMBOL vmlinux 0xa5c5214d backlight_device_register +EXPORT_SYMBOL vmlinux 0xa5caeb68 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0xa5cef8ad release_resource +EXPORT_SYMBOL vmlinux 0xa5da0abd acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0xa5e78533 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0xa5eac6e9 netdev_set_master +EXPORT_SYMBOL vmlinux 0xa5efd22e sk_release_kernel +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa676e393 bio_uncopy_user +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa6814433 groups_free +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6bad16b try_to_release_page +EXPORT_SYMBOL vmlinux 0xa6d51f18 atm_dev_register +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6dd73e4 scsi_put_command +EXPORT_SYMBOL vmlinux 0xa7046549 vprintk +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa7283d32 journal_extend +EXPORT_SYMBOL vmlinux 0xa743830c dma_ops +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa76cc2d5 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0xa7705d48 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0xa770b803 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0xa7791b0e serio_interrupt +EXPORT_SYMBOL vmlinux 0xa7904830 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0xa7a9968a llc_sap_open +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7cae636 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0xa807e55f jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0xa81f1f81 lock_may_read +EXPORT_SYMBOL vmlinux 0xa82e0991 request_firmware +EXPORT_SYMBOL vmlinux 0xa89acbb3 acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xa8a990cc vc_resize +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa958cdfd vfs_create +EXPORT_SYMBOL vmlinux 0xa9669975 journal_check_used_features +EXPORT_SYMBOL vmlinux 0xa9888f0e ip_dev_find +EXPORT_SYMBOL vmlinux 0xa9a14377 unregister_key_type +EXPORT_SYMBOL vmlinux 0xa9a2348b genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0xa9c39bbe seq_release_private +EXPORT_SYMBOL vmlinux 0xa9e4c932 init_net +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa0a7c2b fput +EXPORT_SYMBOL vmlinux 0xaa4363cc __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xaa67d371 elv_queue_empty +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaaa530ea journal_destroy +EXPORT_SYMBOL vmlinux 0xaaafcd56 tcp_close +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaab71a28 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaaead03d vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0xaaebe34f mca_write_pos +EXPORT_SYMBOL vmlinux 0xaafcc71e acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab2dd48d tcp_make_synack +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab597260 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xab83393c input_unregister_handle +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabe2c4f3 tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xac118c7a __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xac21db57 jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0xac2e39a0 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0xac326a52 proc_dointvec +EXPORT_SYMBOL vmlinux 0xac35b84d elv_rb_former_request +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac554fb2 phy_detach +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacec1002 end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad17b5ea pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xad387921 pci_get_slot +EXPORT_SYMBOL vmlinux 0xad41e034 iget5_locked +EXPORT_SYMBOL vmlinux 0xad7257f3 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0xad996823 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xade2cfee mdiobus_write +EXPORT_SYMBOL vmlinux 0xadf7d9bf generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xae051348 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0xae065f44 udp_prot +EXPORT_SYMBOL vmlinux 0xae0c5b9b bio_integrity_free +EXPORT_SYMBOL vmlinux 0xae219789 d_move +EXPORT_SYMBOL vmlinux 0xae23de8f kill_pid +EXPORT_SYMBOL vmlinux 0xae6f655d scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0xae75f004 ida_destroy +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaecd2aee input_register_device +EXPORT_SYMBOL vmlinux 0xaee9228a blk_queue_make_request +EXPORT_SYMBOL vmlinux 0xaf310c7b input_unregister_device +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf4b1540 acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xaf4ca128 dev_close +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf58c683 __nla_put +EXPORT_SYMBOL vmlinux 0xaf893ec7 xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0xaf8d763c skb_queue_purge +EXPORT_SYMBOL vmlinux 0xafd840fc con_set_default_unimap +EXPORT_SYMBOL vmlinux 0xafe01377 down_read +EXPORT_SYMBOL vmlinux 0xb077ef32 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb08d2a51 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xb08f76ad gen_pool_free +EXPORT_SYMBOL vmlinux 0xb0a3ebbf scsi_block_requests +EXPORT_SYMBOL vmlinux 0xb0a93c1c hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0b9dd4c blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0e689ab dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb13ad181 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0xb13c4dba down_write +EXPORT_SYMBOL vmlinux 0xb16a8c91 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0xb182d526 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb20ad34a tcf_action_exec +EXPORT_SYMBOL vmlinux 0xb21446a4 seq_read +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb25077fb eth_type_trans +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb28d8c09 netpoll_setup +EXPORT_SYMBOL vmlinux 0xb29bc8bd idr_remove +EXPORT_SYMBOL vmlinux 0xb29dd9cc clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0xb29ff6a5 dm_table_get_md +EXPORT_SYMBOL vmlinux 0xb2be638a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xb2efb6be mca_read_stored_pos +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb30a1438 i2c_detach_client +EXPORT_SYMBOL vmlinux 0xb30abf8d idr_get_new_above +EXPORT_SYMBOL vmlinux 0xb312f05a gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0xb31526ee sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb3319e80 flush_old_exec +EXPORT_SYMBOL vmlinux 0xb331eb8c dput +EXPORT_SYMBOL vmlinux 0xb3417704 input_inject_event +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3583b43 pci_disable_msi +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb36ff583 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3b4e5c5 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0xb3d6a61f netlink_dump_start +EXPORT_SYMBOL vmlinux 0xb3e0590d acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0xb3f14bda tty_shutdown +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb429410a posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0xb42bebab file_remove_suid +EXPORT_SYMBOL vmlinux 0xb45578b8 memscan +EXPORT_SYMBOL vmlinux 0xb457a24c xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb4769f76 sock_create_lite +EXPORT_SYMBOL vmlinux 0xb4839261 mmc_request_done +EXPORT_SYMBOL vmlinux 0xb4856d25 generic_osync_inode +EXPORT_SYMBOL vmlinux 0xb49362db mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4f1cc79 console_start +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb5080b97 tcf_register_action +EXPORT_SYMBOL vmlinux 0xb543f60b blk_put_request +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb59c739d redraw_screen +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5c7f47f uart_update_timeout +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5e9d64d bio_map_user +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb63fe332 pci_match_id +EXPORT_SYMBOL vmlinux 0xb643cd9e block_commit_write +EXPORT_SYMBOL vmlinux 0xb647eb66 kfree_skb +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb67f2a5f scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0xb6896671 crc_t10dif +EXPORT_SYMBOL vmlinux 0xb6955697 __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6c3dbfc skb_dequeue +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6cc2ff9 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6ed1e53 strncpy +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb72397d5 printk +EXPORT_SYMBOL vmlinux 0xb7478a8a acpi_bus_start +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb7a8f7a6 bio_integrity_split +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7d13f4d unload_nls +EXPORT_SYMBOL vmlinux 0xb7d5fbae __starget_for_each_device +EXPORT_SYMBOL vmlinux 0xb7da46e1 iget_failed +EXPORT_SYMBOL vmlinux 0xb7edfb96 cont_write_begin +EXPORT_SYMBOL vmlinux 0xb802df22 jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0xb8234d67 current_fs_time +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb82bcbec read_cache_page_async +EXPORT_SYMBOL vmlinux 0xb8473f7e xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0xb85b2bac vm_stat +EXPORT_SYMBOL vmlinux 0xb86650a9 sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb88db145 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xb894926d schedule_work_on +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8aa2342 __check_region +EXPORT_SYMBOL vmlinux 0xb8c0d5f9 acpi_is_video_device +EXPORT_SYMBOL vmlinux 0xb8cb219a __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0xb8cf97f6 dm_table_get_size +EXPORT_SYMBOL vmlinux 0xb8dcb5e0 dquot_alloc_space +EXPORT_SYMBOL vmlinux 0xb8df39e3 bdi_register +EXPORT_SYMBOL vmlinux 0xb8e3043e sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb97dd015 pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9b0019a inode_double_lock +EXPORT_SYMBOL vmlinux 0xb9b5a4d9 do_munmap +EXPORT_SYMBOL vmlinux 0xb9b865e6 inet_frags_init +EXPORT_SYMBOL vmlinux 0xb9bab301 scsi_device_resume +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9cbd96e pci_iomap +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba2da41d sock_register +EXPORT_SYMBOL vmlinux 0xba38173e get_sb_bdev +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xbaa4124b br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0xbab2b830 dcache_dir_open +EXPORT_SYMBOL vmlinux 0xbb00e16c dev_alloc_name +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb1a09da set_anon_super +EXPORT_SYMBOL vmlinux 0xbb1fe527 phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb6f1410 tcp_connect +EXPORT_SYMBOL vmlinux 0xbb7d453d simple_readpage +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbb89de17 ida_init +EXPORT_SYMBOL vmlinux 0xbbb0ae54 xfrm_input +EXPORT_SYMBOL vmlinux 0xbbbe4d4b aio_complete +EXPORT_SYMBOL vmlinux 0xbbbf5061 seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xbbc7723e pci_unregister_driver +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbc31a262 __lock_buffer +EXPORT_SYMBOL vmlinux 0xbc653689 scsi_register_driver +EXPORT_SYMBOL vmlinux 0xbc71f829 i2c_probe +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcda7adf generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0xbcfda57d __inet6_hash +EXPORT_SYMBOL vmlinux 0xbd02cb21 wake_up_process +EXPORT_SYMBOL vmlinux 0xbd0a9035 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0xbd29a327 phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0xbd73fe0e hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0xbd886f2a xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xbdae69c4 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xbdc74599 netif_rx +EXPORT_SYMBOL vmlinux 0xbddf6f1e ___pskb_trim +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe3fbb3c sb_min_blocksize +EXPORT_SYMBOL vmlinux 0xbe63ee40 request_resource +EXPORT_SYMBOL vmlinux 0xbe9778f0 ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xbeab405d free_netdev +EXPORT_SYMBOL vmlinux 0xbeb5cd32 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbef5f83f unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0xbf09d6b3 neigh_event_ns +EXPORT_SYMBOL vmlinux 0xbf13b163 rwsem_down_read_failed +EXPORT_SYMBOL vmlinux 0xbf43b7d8 tcf_hash_create +EXPORT_SYMBOL vmlinux 0xbf4984cb netlink_ack +EXPORT_SYMBOL vmlinux 0xbf69645a inet_select_addr +EXPORT_SYMBOL vmlinux 0xbf6cf2ee textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0xbf7a4370 jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf8b39e9 isapnp_present +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfc60429 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0xbfe9d6ed tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xbff7064c genphy_read_status +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01eed33 __copy_from_user_ll_nozero +EXPORT_SYMBOL vmlinux 0xc02a05b8 pnp_is_active +EXPORT_SYMBOL vmlinux 0xc02a2a52 jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc058bfd2 dcache_dir_close +EXPORT_SYMBOL vmlinux 0xc0839bb0 ip6_frag_match +EXPORT_SYMBOL vmlinux 0xc099132d __mpage_writepage +EXPORT_SYMBOL vmlinux 0xc0a2223b tcp_mtup_init +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0f65988 machine_real_restart +EXPORT_SYMBOL vmlinux 0xc109b431 skb_append +EXPORT_SYMBOL vmlinux 0xc11c221d xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc152e856 nla_reserve +EXPORT_SYMBOL vmlinux 0xc163cbc3 bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0xc1709d43 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xc19e7055 generic_file_splice_read +EXPORT_SYMBOL vmlinux 0xc1a9d656 get_sb_nodev +EXPORT_SYMBOL vmlinux 0xc1bb8221 mmc_remove_host +EXPORT_SYMBOL vmlinux 0xc1ce2d53 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0xc1df14c2 scsi_init_io +EXPORT_SYMBOL vmlinux 0xc1fdea70 pci_enable_device +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc20a295d pci_scan_slot +EXPORT_SYMBOL vmlinux 0xc21f4dc8 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xc225f7f2 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xc235f5bd tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0xc24e3338 path_get +EXPORT_SYMBOL vmlinux 0xc24e8f70 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc26a38f7 sock_no_socketpair +EXPORT_SYMBOL vmlinux 0xc280a525 __copy_from_user_ll +EXPORT_SYMBOL vmlinux 0xc2d0228c unregister_netdev +EXPORT_SYMBOL vmlinux 0xc2d711e1 krealloc +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2f23e12 bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0xc32a2ae2 pnp_get_resource +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc34eb9db key_link +EXPORT_SYMBOL vmlinux 0xc35c54e2 pcim_enable_device +EXPORT_SYMBOL vmlinux 0xc36a1b1e sock_wmalloc +EXPORT_SYMBOL vmlinux 0xc3940f18 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xc399591e aio_put_req +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc3b97c9a scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3fa6a59 memchr +EXPORT_SYMBOL vmlinux 0xc3fc6cc8 vfs_write +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc419e9d8 eth_header_parse +EXPORT_SYMBOL vmlinux 0xc443dd68 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0xc4445fec __free_pages +EXPORT_SYMBOL vmlinux 0xc45cc61f sock_no_mmap +EXPORT_SYMBOL vmlinux 0xc47a8936 blk_insert_request +EXPORT_SYMBOL vmlinux 0xc4828945 security_d_instantiate +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4b46b92 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0xc4bbcaf4 pcim_iomap +EXPORT_SYMBOL vmlinux 0xc4c14620 atm_charge +EXPORT_SYMBOL vmlinux 0xc4f0f8ec simple_rename +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc54db74a tty_vhangup +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc56d935e dst_release +EXPORT_SYMBOL vmlinux 0xc5718627 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0xc57374f4 phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0xc5844fb8 __per_cpu_offset +EXPORT_SYMBOL vmlinux 0xc5b456be blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0xc5e23829 inet_dgram_ops +EXPORT_SYMBOL vmlinux 0xc5fea432 struct_module +EXPORT_SYMBOL vmlinux 0xc60b9855 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xc67f9bb2 clear_bdi_congested +EXPORT_SYMBOL vmlinux 0xc6a57856 elv_next_request +EXPORT_SYMBOL vmlinux 0xc6a767b0 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xc6abec78 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0xc6b38087 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xc6f55cc7 dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xc70c137d sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0xc70e918b igrab +EXPORT_SYMBOL vmlinux 0xc7131591 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc7230724 vm_map_ram +EXPORT_SYMBOL vmlinux 0xc723f720 dev_get_by_name +EXPORT_SYMBOL vmlinux 0xc74eec0a xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0xc75ff1e7 blk_init_tags +EXPORT_SYMBOL vmlinux 0xc76eb9b2 blk_unplug +EXPORT_SYMBOL vmlinux 0xc7773c93 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xc779459e sock_no_poll +EXPORT_SYMBOL vmlinux 0xc77c761c fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7d938c9 jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc80a2cf4 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0xc81811a7 journal_clear_err +EXPORT_SYMBOL vmlinux 0xc829d4af blk_start_queueing +EXPORT_SYMBOL vmlinux 0xc836fc96 pcim_iounmap +EXPORT_SYMBOL vmlinux 0xc83cd3d5 ip_ct_attach +EXPORT_SYMBOL vmlinux 0xc84eded8 mpage_writepages +EXPORT_SYMBOL vmlinux 0xc87b584c neigh_seq_start +EXPORT_SYMBOL vmlinux 0xc8991fae neigh_table_clear +EXPORT_SYMBOL vmlinux 0xc8b35ec7 md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8ed4d83 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xc8ff2287 ps2_handle_response +EXPORT_SYMBOL vmlinux 0xc9030461 ll_rw_block +EXPORT_SYMBOL vmlinux 0xc931e5ee destroy_EII_client +EXPORT_SYMBOL vmlinux 0xc933f6f3 netdev_state_change +EXPORT_SYMBOL vmlinux 0xc93b6f05 kernel_connect +EXPORT_SYMBOL vmlinux 0xc95da1a0 seq_printf +EXPORT_SYMBOL vmlinux 0xc962832f serial8250_register_port +EXPORT_SYMBOL vmlinux 0xc96d9244 single_open +EXPORT_SYMBOL vmlinux 0xc974c5c8 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc99fb30f pskb_expand_head +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9b09745 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xc9d236b0 hci_register_cb +EXPORT_SYMBOL vmlinux 0xca4a8a14 inode_init_once +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca719a46 dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xcaabe95c scsi_dma_map +EXPORT_SYMBOL vmlinux 0xcabe5778 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xcb07a55d bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0xcb0c8b0e __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb406a7b generic_file_aio_read +EXPORT_SYMBOL vmlinux 0xcb60df65 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0xcb69e27a genphy_config_advert +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb71542e locks_remove_posix +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcbccdfd6 mntput_no_expire +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc2d0cc0 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc473a5e vm_insert_page +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc77c7ba fb_blank +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc89a8b5 security_inode_init_security +EXPORT_SYMBOL vmlinux 0xcca58923 simple_dir_operations +EXPORT_SYMBOL vmlinux 0xccb5431e dquot_acquire +EXPORT_SYMBOL vmlinux 0xccbdfb5f pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0xccceaf8e dev_driver_string +EXPORT_SYMBOL vmlinux 0xccf342b4 inet6_del_protocol +EXPORT_SYMBOL vmlinux 0xcd1c4018 blk_start_queue +EXPORT_SYMBOL vmlinux 0xcd2abdf5 input_unregister_handler +EXPORT_SYMBOL vmlinux 0xcd9875b5 vfs_dq_drop +EXPORT_SYMBOL vmlinux 0xcdb0d6a2 sock_no_accept +EXPORT_SYMBOL vmlinux 0xcdcd9e85 xfrm_find_acq +EXPORT_SYMBOL vmlinux 0xcdd0acf4 find_vma +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4520e4 block_read_full_page +EXPORT_SYMBOL vmlinux 0xce48920d __serio_register_driver +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce55d2bb generic_read_dir +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce6f3e55 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xce8fa87c netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xcee1e1b8 pci_set_power_state +EXPORT_SYMBOL vmlinux 0xceef99d4 neigh_update +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf0b3592 pci_disable_device +EXPORT_SYMBOL vmlinux 0xcf0eca4b __dev_get_by_index +EXPORT_SYMBOL vmlinux 0xcf29b72c pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xcf586c32 vfs_unlink +EXPORT_SYMBOL vmlinux 0xcf59430e __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0xcf66b0c9 atm_dev_lookup +EXPORT_SYMBOL vmlinux 0xcf7a060a balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0xcf956155 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcff2b574 vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xd0094d73 submit_bio +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd04025a7 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0xd042c0c7 icmpv6_send +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd09cd31b inet_stream_ops +EXPORT_SYMBOL vmlinux 0xd0d793f0 vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0xd0d8621b strlen +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd151a199 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd1cf7378 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd2421e25 inet_listen +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25b5856 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd285207a vmtruncate +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2981b51 request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0xd299086c scsi_target_resume +EXPORT_SYMBOL vmlinux 0xd29e11c4 poll_initwait +EXPORT_SYMBOL vmlinux 0xd2a941d4 sg_init_table +EXPORT_SYMBOL vmlinux 0xd2a9d1cb tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0xd2aa1dae hci_send_acl +EXPORT_SYMBOL vmlinux 0xd2b8c5e7 lease_get_mtime +EXPORT_SYMBOL vmlinux 0xd2b9fe46 tty_unregister_device +EXPORT_SYMBOL vmlinux 0xd2d5eaed netpoll_parse_options +EXPORT_SYMBOL vmlinux 0xd2fbecca dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xd312b3e2 fget +EXPORT_SYMBOL vmlinux 0xd32991ab __splice_from_pipe +EXPORT_SYMBOL vmlinux 0xd3306f94 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0xd33ba7e8 security_task_getsecid +EXPORT_SYMBOL vmlinux 0xd34a53d4 inode_double_unlock +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd363bdea pnp_request_card_device +EXPORT_SYMBOL vmlinux 0xd3713896 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0xd3872b4b xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xd3928c13 sock_i_ino +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd3c659f5 skb_seq_read +EXPORT_SYMBOL vmlinux 0xd3ca9485 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xd3db76d6 generic_show_options +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd3fc8b16 blk_execute_rq +EXPORT_SYMBOL vmlinux 0xd418e1c0 adjust_resource +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd4303a04 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0xd45af0f9 tty_free_termios +EXPORT_SYMBOL vmlinux 0xd4628e1d vfs_mknod +EXPORT_SYMBOL vmlinux 0xd46741ec vfs_quota_sync +EXPORT_SYMBOL vmlinux 0xd46de54f make_bad_inode +EXPORT_SYMBOL vmlinux 0xd4767211 mem_map +EXPORT_SYMBOL vmlinux 0xd485e4a4 register_atm_ioctl +EXPORT_SYMBOL vmlinux 0xd4a064bf __devm_release_region +EXPORT_SYMBOL vmlinux 0xd4a78884 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0xd4a7fe74 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xd4c40e95 md_error +EXPORT_SYMBOL vmlinux 0xd4df12b7 blk_run_queue +EXPORT_SYMBOL vmlinux 0xd4df73e2 __grab_cache_page +EXPORT_SYMBOL vmlinux 0xd4f6f512 __bforget +EXPORT_SYMBOL vmlinux 0xd4fa34aa blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xd51a528c simple_write_end +EXPORT_SYMBOL vmlinux 0xd51b0cd4 posix_acl_permission +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd54e72c3 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0xd558ec75 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd58bb126 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0xd5a8e8a1 is_bad_inode +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5dd69e3 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd63fdcad truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0xd64b8c39 dev_get_flags +EXPORT_SYMBOL vmlinux 0xd6724286 atm_dev_deregister +EXPORT_SYMBOL vmlinux 0xd67a684a jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0xd6809ce0 skb_put +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6ace8af neigh_compat_output +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6b6ca23 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xd6cc1a2c phy_start_aneg +EXPORT_SYMBOL vmlinux 0xd6d53c48 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0xd6e1f504 redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd70ac7ff tcp_setsockopt +EXPORT_SYMBOL vmlinux 0xd717d598 bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0xd762f334 usb_serial_resume +EXPORT_SYMBOL vmlinux 0xd770ff1d fb_set_suspend +EXPORT_SYMBOL vmlinux 0xd78e5d8f generic_setlease +EXPORT_SYMBOL vmlinux 0xd7903d07 d_instantiate +EXPORT_SYMBOL vmlinux 0xd79958e6 mpage_writepage +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7cc2014 __lookup_hash +EXPORT_SYMBOL vmlinux 0xd7d36d1a idr_find +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd8439c82 ip_fragment +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd89ee11f check_disk_change +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8bb5fc5 search_binary_handler +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8f8f795 no_llseek +EXPORT_SYMBOL vmlinux 0xd9074daf journal_init_dev +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd93dd107 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xd941081b path_permission +EXPORT_SYMBOL vmlinux 0xd95442a8 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0xd9679f33 phy_print_status +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd996d859 idr_pre_get +EXPORT_SYMBOL vmlinux 0xd9a66b25 journal_dirty_data +EXPORT_SYMBOL vmlinux 0xd9c272aa mca_mark_as_unused +EXPORT_SYMBOL vmlinux 0xd9eec125 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0xda08c0d7 pcibios_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda3f4b33 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8fd495 isapnp_write_byte +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xdaa4ed78 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xdaa57ec3 totalhigh_pages +EXPORT_SYMBOL vmlinux 0xdaebe417 iget_locked +EXPORT_SYMBOL vmlinux 0xdb16a0ea unbind_con_driver +EXPORT_SYMBOL vmlinux 0xdb326d06 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0xdb6c054a do_SAK +EXPORT_SYMBOL vmlinux 0xdb6ce750 copy_io_context +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb8f8bf6 mca_device_claimed +EXPORT_SYMBOL vmlinux 0xdb9b6483 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0xdba921d5 bitmap_unplug +EXPORT_SYMBOL vmlinux 0xdbab1945 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xdbc052b4 d_add_ci +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbecd498 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc159db1 genl_register_ops +EXPORT_SYMBOL vmlinux 0xdc1f9163 vfs_rename +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc30d756 pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0xdc3c222e skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdca53b1f ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0xdcc60256 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0xdcc9383e submit_bh +EXPORT_SYMBOL vmlinux 0xdce5db56 scsi_device_put +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd0fa475 simple_unlink +EXPORT_SYMBOL vmlinux 0xdd112f37 d_rehash +EXPORT_SYMBOL vmlinux 0xdd2252e9 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xdd696adf skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd7340e8 bitmap_start_sync +EXPORT_SYMBOL vmlinux 0xdda699a5 pskb_copy +EXPORT_SYMBOL vmlinux 0xdda93679 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddc3fb49 register_sysrq_key +EXPORT_SYMBOL vmlinux 0xddc8db8c d_path +EXPORT_SYMBOL vmlinux 0xddda8f07 blk_rq_map_user +EXPORT_SYMBOL vmlinux 0xdde0809a scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0xddec4a5a sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xddef6f4f __netif_schedule +EXPORT_SYMBOL vmlinux 0xde17a9fd tcp_check_req +EXPORT_SYMBOL vmlinux 0xde1b75a4 pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xde466483 pv_cpu_ops +EXPORT_SYMBOL vmlinux 0xde5a4c00 console_stop +EXPORT_SYMBOL vmlinux 0xde610abd do_sync_read +EXPORT_SYMBOL vmlinux 0xde63e9fa generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde9f47fd __dev_remove_pack +EXPORT_SYMBOL vmlinux 0xdee1b81b netpoll_cleanup +EXPORT_SYMBOL vmlinux 0xdee2158c block_prepare_write +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf4bd11a pci_iounmap +EXPORT_SYMBOL vmlinux 0xdf55618a tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xdf5dcf9e read_dev_sector +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf69bb97 dev_mc_delete +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xe0098df3 phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0xe00e5601 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xe0243e8f register_cdrom +EXPORT_SYMBOL vmlinux 0xe054fde1 netif_rx_ni +EXPORT_SYMBOL vmlinux 0xe06b4431 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe094ef39 sg_next +EXPORT_SYMBOL vmlinux 0xe0995d29 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0xe0a501e3 idr_remove_all +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe12cc982 eth_rebuild_header +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe15aeee2 downgrade_write +EXPORT_SYMBOL vmlinux 0xe15be563 inet6_getname +EXPORT_SYMBOL vmlinux 0xe15f2410 skb_over_panic +EXPORT_SYMBOL vmlinux 0xe16f8a79 per_cpu__irq_regs +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe17e0bf6 stop_tty +EXPORT_SYMBOL vmlinux 0xe18b728a bio_copy_user +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1af2eb9 find_or_create_page +EXPORT_SYMBOL vmlinux 0xe1b219e8 qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xe1cd9659 pci_dev_driver +EXPORT_SYMBOL vmlinux 0xe1f9fb5c scsi_release_buffers +EXPORT_SYMBOL vmlinux 0xe1ff85b8 sock_release +EXPORT_SYMBOL vmlinux 0xe20cf437 filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0xe2175f7e skb_gso_segment +EXPORT_SYMBOL vmlinux 0xe217f1eb hci_suspend_dev +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2dcd77a inode_set_bytes +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe30331ef tty_register_driver +EXPORT_SYMBOL vmlinux 0xe307136b ip_getsockopt +EXPORT_SYMBOL vmlinux 0xe312c2a4 pnp_find_card +EXPORT_SYMBOL vmlinux 0xe33da212 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0xe343ace2 block_sync_page +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe3533223 filemap_flush +EXPORT_SYMBOL vmlinux 0xe374564b pci_clear_mwi +EXPORT_SYMBOL vmlinux 0xe37a8f1c journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xe37b0162 i2c_del_driver +EXPORT_SYMBOL vmlinux 0xe3a36c54 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0xe3be4eb3 find_inode_number +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe40ab29c vfs_statfs +EXPORT_SYMBOL vmlinux 0xe40c33e9 bio_unmap_user +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe457f4a4 pci_remove_bus +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe48f3039 ida_get_new_above +EXPORT_SYMBOL vmlinux 0xe4975980 genl_sock +EXPORT_SYMBOL vmlinux 0xe49a9db8 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0xe4a43f1b kernel_accept +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4ceaae4 jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0xe50d7c11 get_sb_single +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe51dce13 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe52848f8 page_readlink +EXPORT_SYMBOL vmlinux 0xe5512dce mca_device_transform_ioport +EXPORT_SYMBOL vmlinux 0xe55e0808 clip_tbl_hook +EXPORT_SYMBOL vmlinux 0xe5606317 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5c15615 llc_add_pack +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5d22061 pci_enable_msi +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe60fc317 input_open_device +EXPORT_SYMBOL vmlinux 0xe610ac0e give_up_console +EXPORT_SYMBOL vmlinux 0xe61b347a vfs_quota_on +EXPORT_SYMBOL vmlinux 0xe61efab0 kmem_cache_name +EXPORT_SYMBOL vmlinux 0xe683d3c0 x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe6911271 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0xe6e09f6a fb_set_cmap +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6f68c83 lock_rename +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe6fcf9de jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe77aedb1 genphy_update_link +EXPORT_SYMBOL vmlinux 0xe798b930 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0xe7a200c0 key_negate_and_link +EXPORT_SYMBOL vmlinux 0xe7c02b72 elv_rb_find +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7e2e3da loop_register_transfer +EXPORT_SYMBOL vmlinux 0xe7f215d6 pid_task +EXPORT_SYMBOL vmlinux 0xe7fee0dd scsi_finish_command +EXPORT_SYMBOL vmlinux 0xe80ce219 sysctl_tcp_dma_copybreak +EXPORT_SYMBOL vmlinux 0xe815d76d netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0xe81f16bb compute_creds +EXPORT_SYMBOL vmlinux 0xe8216dbc sk_common_release +EXPORT_SYMBOL vmlinux 0xe8427ea5 kobject_add +EXPORT_SYMBOL vmlinux 0xe867441a eth_header +EXPORT_SYMBOL vmlinux 0xe8745016 vfs_readlink +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8c88193 cdev_alloc +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe904fb87 register_filesystem +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe9164f76 skb_free_datagram +EXPORT_SYMBOL vmlinux 0xe92e3688 dquot_free_inode +EXPORT_SYMBOL vmlinux 0xe9308ce9 vfs_llseek +EXPORT_SYMBOL vmlinux 0xe9420a17 mdiobus_register +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe94bf4ea cdev_del +EXPORT_SYMBOL vmlinux 0xe967aa81 skb_make_writable +EXPORT_SYMBOL vmlinux 0xe96f5a27 get_unmapped_area +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9b46cae blk_recount_segments +EXPORT_SYMBOL vmlinux 0xe9e00f96 sock_wfree +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea712d97 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xea90b3d1 inode_permission +EXPORT_SYMBOL vmlinux 0xea96866d uart_remove_one_port +EXPORT_SYMBOL vmlinux 0xead5ddc8 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb28c421 vfs_path_lookup +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb4e0eca tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0xeb6a5ea8 bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeb965d66 blk_verify_command +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebd39068 blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xec031ac9 arp_send +EXPORT_SYMBOL vmlinux 0xec24887e simple_lookup +EXPORT_SYMBOL vmlinux 0xec412878 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xec497228 hci_alloc_dev +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xecac925f unregister_8022_client +EXPORT_SYMBOL vmlinux 0xecb778b0 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xecb93795 blk_stop_queue +EXPORT_SYMBOL vmlinux 0xecbf6bd7 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xeccbb11e mmc_register_driver +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xed0908a6 dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0xed2a1c06 phy_stop +EXPORT_SYMBOL vmlinux 0xed3b88de tcp_splice_read +EXPORT_SYMBOL vmlinux 0xed633abc pv_irq_ops +EXPORT_SYMBOL vmlinux 0xeda92168 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0xedb8dbf1 blk_complete_request +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedc3a854 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedd80150 filp_open +EXPORT_SYMBOL vmlinux 0xedda7993 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0xee064251 dquot_release +EXPORT_SYMBOL vmlinux 0xee244f49 pci_get_class +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee3330c3 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0xee41b90f __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0xee43db2d tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0xee77138c scsi_is_host_device +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xee9207ae sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xee967746 find_lock_page +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeebc8844 ht_create_irq +EXPORT_SYMBOL vmlinux 0xeebd649b register_quota_format +EXPORT_SYMBOL vmlinux 0xeec294ea bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0xeed6983e dev_open +EXPORT_SYMBOL vmlinux 0xeef04263 atm_proc_root +EXPORT_SYMBOL vmlinux 0xeef79384 dev_unicast_add +EXPORT_SYMBOL vmlinux 0xeef810b0 tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0xef23af78 blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0xef2f096a jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0xef3bd862 mca_find_unused_adapter +EXPORT_SYMBOL vmlinux 0xef430c58 deactivate_super +EXPORT_SYMBOL vmlinux 0xef599cf9 dev_add_pack +EXPORT_SYMBOL vmlinux 0xef5cfedb __bio_clone +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefa8a81d hci_free_dev +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xefe5bbd9 register_exec_domain +EXPORT_SYMBOL vmlinux 0xeff14be9 ioremap_cache +EXPORT_SYMBOL vmlinux 0xeff5578e xfrm_register_km +EXPORT_SYMBOL vmlinux 0xeff57424 register_netdevice +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf05b5753 get_super +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf086b49a netif_carrier_on +EXPORT_SYMBOL vmlinux 0xf09dc19c qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0xf0b0875d block_truncate_page +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0c0c77d i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0xf0d93168 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0xf0eba5b0 unregister_snap_client +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf10d7878 atm_alloc_charge +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf134b4f6 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0xf1415cd4 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0xf159f618 sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf16cf928 starget_for_each_device +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf1899ae1 d_namespace_path +EXPORT_SYMBOL vmlinux 0xf18a5d1e close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xf190396f ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf1af9172 ps2_init +EXPORT_SYMBOL vmlinux 0xf1d22bfc sk_alloc +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf23a6984 journal_get_undo_access +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf25c85c0 create_proc_entry +EXPORT_SYMBOL vmlinux 0xf26b881a skb_clone +EXPORT_SYMBOL vmlinux 0xf278baf7 mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0xf27f58ae blk_get_request +EXPORT_SYMBOL vmlinux 0xf291d91c kthread_bind +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2e74040 mca_set_adapter_name +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf33eab27 kthread_stop +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf37f6962 phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0xf394c960 pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3a495e3 neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0xf3a74fba tty_kref_put +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3d1d0e2 deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0xf3ee0aa2 names_cachep +EXPORT_SYMBOL vmlinux 0xf3f4fddb bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0xf40f3a8e filp_close +EXPORT_SYMBOL vmlinux 0xf42aa1e4 dev_remove_pack +EXPORT_SYMBOL vmlinux 0xf43e52c8 do_sync_write +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf445028d page_follow_link_light +EXPORT_SYMBOL vmlinux 0xf4457edc blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0xf4505e82 input_register_handler +EXPORT_SYMBOL vmlinux 0xf48a2c4c MCA_bus +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4aca88d generic_unplug_device +EXPORT_SYMBOL vmlinux 0xf4ae9d51 ida_pre_get +EXPORT_SYMBOL vmlinux 0xf4b90e26 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0xf4d4e54a dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0xf4d855c6 dev_disable_lro +EXPORT_SYMBOL vmlinux 0xf4f0b5d1 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f17d44 md_register_thread +EXPORT_SYMBOL vmlinux 0xf4f4f552 udp_sendmsg +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf502d273 acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf52c282a cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0xf52da35d dma_pool_destroy +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf56903c5 inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0xf587de9f security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0xf5952f8a fb_pan_display +EXPORT_SYMBOL vmlinux 0xf5a3a33b set_user_nice +EXPORT_SYMBOL vmlinux 0xf5b3591c mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0xf5bcd6f6 netlink_unicast +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5d2600f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0xf5d2a588 mmc_resume_host +EXPORT_SYMBOL vmlinux 0xf5d69cc8 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0xf5dea399 unregister_cdrom +EXPORT_SYMBOL vmlinux 0xf601fdc9 ppp_register_channel +EXPORT_SYMBOL vmlinux 0xf6272dbb eisa_driver_unregister +EXPORT_SYMBOL vmlinux 0xf645ea81 path_lookup +EXPORT_SYMBOL vmlinux 0xf6492bb1 skb_pad +EXPORT_SYMBOL vmlinux 0xf67d06a0 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0xf688e485 sock_kmalloc +EXPORT_SYMBOL vmlinux 0xf6ad170c elv_add_request +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6eb3812 arp_broken_ops +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf6f692a1 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0xf7138f80 sock_init_data +EXPORT_SYMBOL vmlinux 0xf714ee59 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0xf71aa515 generic_file_llseek +EXPORT_SYMBOL vmlinux 0xf75064ca vm_insert_pfn +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf786ef5e idr_init +EXPORT_SYMBOL vmlinux 0xf78cd6a3 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7a0c51b __seq_open_private +EXPORT_SYMBOL vmlinux 0xf7c78c91 inet_stream_connect +EXPORT_SYMBOL vmlinux 0xf7e783c4 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xf80cfddd locks_init_lock +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82bc6fb skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf840dca3 bdi_destroy +EXPORT_SYMBOL vmlinux 0xf847e358 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0xf855261c bmap +EXPORT_SYMBOL vmlinux 0xf860a555 bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0xf86a90ff llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8e7f4a8 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0xf90dcb55 input_set_capability +EXPORT_SYMBOL vmlinux 0xf97cb55c call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0xf99cbe72 tty_hangup +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9addac9 register_framebuffer +EXPORT_SYMBOL vmlinux 0xf9b8c3f4 ppp_unit_number +EXPORT_SYMBOL vmlinux 0xf9d7e461 dm_get_device +EXPORT_SYMBOL vmlinux 0xf9e9a66c simple_set_mnt +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa172920 revalidate_disk +EXPORT_SYMBOL vmlinux 0xfa4be753 pci_dev_put +EXPORT_SYMBOL vmlinux 0xfa80b268 pci_target_state +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb038d63 cpu_mask_all +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb75ea6b xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xfb7a13a8 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0xfb7c47a7 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfba38c31 tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0xfbdea729 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0xfbe21ae7 skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc309c3e cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc4b1695 sysctl_string +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcd4ad45 journal_revoke +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd2199e7 __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0xfd2b2322 ip_route_input +EXPORT_SYMBOL vmlinux 0xfd3ac266 generic_file_open +EXPORT_SYMBOL vmlinux 0xfd3dfa41 unlock_super +EXPORT_SYMBOL vmlinux 0xfd4ccffb pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb10534 mmc_add_host +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfdd6cc54 elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfdfb4a0d seq_lseek +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe14db03 eth_header_cache +EXPORT_SYMBOL vmlinux 0xfe188e89 tcf_em_register +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfe7f8a3b remove_proc_entry +EXPORT_SYMBOL vmlinux 0xfe8459ce __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0xfebf7103 tcp_sendpage +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfecb5d53 dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xfefd6db0 bio_add_page +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff2d92b4 get_write_access +EXPORT_SYMBOL vmlinux 0xff527dd3 dquot_commit +EXPORT_SYMBOL vmlinux 0xff57b1fb proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff8beb94 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0xff91ac3b pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0xff9a5a53 single_release +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffb3703a k8_northbridges +EXPORT_SYMBOL vmlinux 0xffc3c604 bt_sock_link +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffdb82bc sg_free_table +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x02c8cfcf kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x046696b8 kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0a1295c9 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0b954d3b kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0be0947f kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0f0a013e kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x10c9d701 kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x140eb6af kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x17928558 kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x185813a2 kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x19846d37 kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1dd0ea58 load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x29be7af7 __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2c5cc50d kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2c905a14 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2e484cac kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x35c3b4cf kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x361c447b kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3bd2a6b9 kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3c301b39 kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4c953f14 kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4d990408 kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x51e63b4c kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x51f1cf3e kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x599086dd kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5b750116 kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5dc8659e kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6b4bb384 kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7470633c kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x751d31b6 kvm_get_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x75687016 gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7c7a3eb4 kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7f048877 gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x85bd708e kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x86620fe4 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x89025513 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x92129eb8 kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x942dab23 kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x94b548ef kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x96b4a584 kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x96fb9338 kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x995fe074 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x999a1b53 kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9be15eea fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9f398470 kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa20bfa5d kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa301d03d kvm_vcpu_cache +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa4a0b61d kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa4c32809 kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa5d35823 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa881f1eb kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaa51459e kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaed16bb2 kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaf287bf5 kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xafcd701c emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb016f59b kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbcaa4964 kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc71d06f6 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcc5761ee kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xda006468 kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xda398af8 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xda3ba115 emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xde75a80b kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe16f84fb kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe4f93eb2 kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xef3cff16 kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf2e42713 kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfd2a547d kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x3339118e crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0xbd9aba3d async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x374a9afb dma_wait_for_async_tx +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x82b082fb async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x91befdc9 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x994aa470 __async_tx_find_channel +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xcb0f25fd async_tx_run_dependencies +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xd6492bc7 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x15e27dba async_xor +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xa4b17e7f async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xe8e4dd13 twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xd508e3a9 agp_add_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xe0b70325 agp_remove_bridge +EXPORT_SYMBOL_GPL drivers/char/scx200_gpio 0x385ba5d9 scx200_gpio_ops +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x0131bed4 tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x050ad934 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x0f06a82a tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x2c2ad61b tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x3350efcc tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x438208fe tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x4e35307d tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x530ad7e8 tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x68c206a0 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x701dbbe3 tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x73059c61 tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7a403732 tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7bb22524 tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9f158712 tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa35106c1 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa360a744 tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xbdfcd498 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xbf5ff810 tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc88a6831 tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xca993d3c tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xe3c0d979 tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xf30d7dc4 tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xf5c935f2 tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x6675b89d tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xb7756bc6 tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/dca/dca 0x2e471f01 dca_register_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x31a2c8df dca_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x44a721c8 free_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0x61ebf42f dca_remove_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0x6823cd90 register_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0x8006c614 dca_unregister_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x889a364d dca3_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0xad8910ba dca_add_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0xc785f6ed alloc_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xddb923c3 unregister_dca_provider +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0672fa01 edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x1f394b55 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x21914a30 edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x33567010 edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x3b23e35a edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x428c96cd edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x50493050 edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x598b2233 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5b10a4d3 edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x65da831c edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x71b9cbcc edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x734407f9 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x7af05058 edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x7f7815a4 edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa71ae8fe edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb1d9d2d6 edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xbb3c8204 edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xbd430dd3 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcbfa284e edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd4a41d6c edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xebac4157 edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xefc7d8a2 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf3b6660d edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf3dfdc00 edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x050c05c5 usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x45a2d46f hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xbbaf42de usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0x4b2ee1d7 nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0x6121bd49 hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xb7e36f3b hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0x98db1a67 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x14061acb wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x14428418 wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x1cb6c0f0 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x3498c95b wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x35cf84d5 wm9713_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x594e808e wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x6e3c992f wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x71ff1152 wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xdb7c4eb4 wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xdcc1b36b wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xe4db9911 wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xf965844b wm9712_codec +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x28b751e1 gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x32fb7aea gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x425e8e9a gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x426fb154 gigaset_initcs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x4e792275 gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x562dd0ee gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x66b0ee21 gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x8bf637c7 gigaset_stop +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x90b66085 gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9c5db0f3 gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xb3c947db gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xc8341876 gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xcec4cefe gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xd817d281 gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xdf5282d4 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xf64bd597 gigaset_add_event +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x001a452c led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x3477a6c5 led_classdev_register +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x4d02026f led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x834bd65a led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1c54574e ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2eeb0972 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x56b779a8 ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x1f97d441 saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x3e8761ed saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x5f20d4df saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x70b64636 saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x8fc9acd7 saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xae83b1b1 saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xb92c934d saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xbee5f190 saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xbf556075 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xdf3fa027 saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x2fcbfd98 saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x3293c611 saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x39fe644d saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x441d6daf saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xc5a182d1 saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xe4db303a saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xfaa1850f saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0xb419c855 microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0xbeaa9052 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0xb43cb658 tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x0cdeba0c tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x5a0c0c9a tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x9379deb1 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0x4cea4400 tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x30c0ad8d tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0xf830c71f tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x3e0ef081 tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x4b1105a6 tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0x498d74b5 simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x293cddd3 ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x2f451abf ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x4c05a427 ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x81b0ac8f ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x827fd087 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xbaad700c ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xdf5af067 ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0x076b6177 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0x64cb25b1 cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x35cd69aa em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x47232c6a em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x6a595cb9 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x9aee193d em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x131e8ae6 saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x326d0508 saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x56f0c9de saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x6841c118 saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xa33250df saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xbb32dcac saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x0a64fa00 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x18dcd5a5 v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x36b7989d v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x7f89ff21 v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x11311e57 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3243fc44 videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3f46de82 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x4400b044 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x44f99b00 videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x61ffe23e videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x690feb9d videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x6cf22ed6 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x78eaa1ef videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x823d6e8d videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x84b93365 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x8a5c054a videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x8b7dd20c videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x99c12300 videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x9cca8a95 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x9e36b581 videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa59230f6 videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xad36ac61 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xbef880bd videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc16f01b7 __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xc8b66cce videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd02b290b videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf1a17616 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf6602230 videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xff920f0a videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x37d2d76b videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x50d580b8 videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x6056f7e8 videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x16d28320 videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x221fe1a9 videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x24a839da videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x3b42b38c videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x4100815d videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x4fadec87 videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x893a75f6 videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x96bc2b95 videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa825c75b videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xbbec7fe3 videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xce8fb127 videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xe8a24336 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xf6c89cc7 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xfcadb75a videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x10d1fc16 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x120d20cf videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xbb4c7eb7 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x0c28d894 i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x32256dd1 i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x6f4551c7 i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x98d97244 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xc2d9008a i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xd82d6f8b i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xf03dba09 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xff582359 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x0fb419e2 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x1052a5cb sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x20cd6bc7 sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xa170245e sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xc0509cc6 sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x154c7090 wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x20ba1cab wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x29f4be56 wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x6a4a1395 wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x76523110 wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x7686e2a2 wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x7b087a51 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x970f725a wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xae02f436 wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xb75cb9b7 wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xb89ce3b7 wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd2684cd0 wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xedd80919 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xf1524229 wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xfe1f15a7 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x0bde774b wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x0d3a7ac1 wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x5377123e wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x6eba282c wm8400_block_read +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x3f99015a enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x4029c968 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x5169a604 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x80bda328 enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xb6417eaa enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd062078b enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdea09b14 enclosure_component_register +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x86599125 sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x8697ad2f sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xa80c78bf sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xb5680f49 sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xdf40ace5 sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xef927865 sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x235fd309 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xba1baa85 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xd1126854 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0xf6b99643 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0x8b6a64bd cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x539ea66e cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xba7aea4b cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xe615a2c4 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0xa2d5608d DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0xad91d591 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0xef1b13eb DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x18ff9bb6 del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x23064f49 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x2fc7a7db get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3b16adcc default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x4761687b mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x4ae565f2 put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x4af87c0e add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x50e5e38a get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x5b8b14d7 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x6692d8ff parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x7ae8858a mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x9a2ebefb kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xa0292e35 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xc187894b register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xd1d66776 unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x12077121 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x777dbbdc deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xc47768f3 del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xf049b552 register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x0ac2a71c nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x6c97a87f nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xcf45f711 nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xd42ffee1 nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xee0fe65e nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x0bbd3458 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0xac0e144e onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x258f99fb ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x4aa884e2 ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x6207c027 ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x684dbce2 ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x7039e14a ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x7313e981 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x839a0f41 ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xa6f5a101 ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xaf2f84a0 ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xc4cc7275 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xfba5c460 ubi_leb_map +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0385b3b5 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0e05d510 mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0e970be6 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x11fbbce9 mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1e1d6808 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1f74337f mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1fc33d87 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x31884cfe mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x367a0ca3 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x392bb997 mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x39a77d92 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3ac35d08 mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x40bb8d8e mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4ae49dbe mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x4fc0c00e mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5299b0c3 mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x540ad9d7 mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5733ee3c mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5a1bac3f mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5adbf23b mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5fcbe6cc mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6102a025 mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x62de7405 mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x68aa376e mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6a1d70e6 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x82698db7 mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x857bdd9f mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8bdeb575 mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8cf7660e mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x95b1bd1e mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9cbc8f12 mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa563a2ae mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa6412be9 mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xaa0c87f9 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xaad220fb __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb2596162 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb3e94154 mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb43c708d mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb888cfd0 mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc3e92d0e mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcef12d83 mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd29acbc1 mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd6a0dc01 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd6b3facb mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xda766c22 mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xdcd3ab04 mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe28c14d6 mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe549aef7 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe6ab1403 mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xed35ec69 mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xedf1fdba mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf4aec2b0 mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf4ce9a64 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x2d8dad7c usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x341f063e usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x0a4e9802 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x1cc4f003 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x4dc18df5 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x9c4087ea rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xc2ded047 rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xc92a24ad rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x018a35ec usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x0bfed382 usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x1c16c244 usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x1ce92d19 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x4189d3bd usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x5b316c46 usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x7b2d4b33 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb6594e27 usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xbd2d911c usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xc4070274 usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd382a2df usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xde446a61 usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe1e51251 usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf2ec836e usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xfb04c170 usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0c2cac1c __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x19f69509 lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x34721c5b lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x72b5cfc2 lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x7d471b4e lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xadcd806d lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xb3f7a8ac lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xb7995595 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xcedd8503 lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd11a3936 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd19a2b87 lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd90a2575 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe3d791cf lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xee1ca4aa lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xef148a75 lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x2121eac7 lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x4a8ce4f5 lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x4b4e90ff lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x6378238d lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x7b6f2bdd lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xc99994e1 __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xf53ab23b lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xf8d68ce2 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x297a78be if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x853a7657 if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x0bc95884 p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x1d8bdc83 p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xb136517d p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xcf4cd449 p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xd97694df p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x0890a091 rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1d086f09 rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x20345141 rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x280bae30 rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3a6d64b4 rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x46d0391d rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4ce6741b rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x573e55ed rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x57aef9a8 rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x66822a4a rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x7ac19d1c rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x8978aa5c rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x914f8578 rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x91c488c8 rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa48e3ad5 rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xc4c19948 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xc85baddb rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xc9ca3eda rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe0e3b8c6 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe24dced4 rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe83d9985 rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xeebe2b31 rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf95a7b09 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0261fd55 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0acced60 rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x1da2b502 rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x43826622 rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x65e49b10 rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x81e1b546 rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x8fe91ea6 rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x913316db rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x00db5232 rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x1cf8a55c rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x2126117d rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x25eec04d rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x282d1c6c rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x33329e26 rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x495cd8ba rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x53417b14 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x60b1f10f rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x8acfa353 rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xd4edaf96 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xd93ee04a rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xe4979626 rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xfc747310 rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xfee905c3 rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x18d883ed acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0xa15b31d2 acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x36f3f6e0 wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x3ec1f0e0 wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x437611c9 wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x5b72d115 wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x75ad9178 wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0xbc93d6f9 wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x12844438 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x1e46a0f7 iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x30252eb0 iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x40b16740 iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x4333a029 iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x463afa1e iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x49496e17 iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x4eea7ee4 __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5066a654 iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5da87c27 iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5f4e9cd1 iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5f98fa60 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x659a037f iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6ab836d8 iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6ccc79d6 __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x76f54989 iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7bae2059 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7c079d03 iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7deb95e4 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x893ed2c9 iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x91d67d77 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x94316281 iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9c548063 iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa40909f0 iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa95e3012 iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb71af08a iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbbc182e2 iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbefefcfb iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc30dae97 iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xcbc93dd6 iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xd19f7a90 iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe8cacc61 iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf389d867 iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf55cae95 iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xfc2b66dc iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x01a3dd2f sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x0cdd6eda sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x13135581 __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x1a8bb4f7 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x22f07be6 sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x22f58691 sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x26b05e9c sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x542007b0 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x5fc7f4da sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x6097fe6c sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x73e34366 sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x75c2ed5c sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x76ce2aa0 sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x90064078 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x94183904 sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xa5564e2e sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xa953ee5e sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xb43d21f3 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xbf4dc33e sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc19b2d00 sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc68b1ad9 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe2fa37d2 sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe551e775 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x5d822de8 srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x7d07fb28 srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x90344f38 srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xcf4a6655 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xeb134de3 srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xfe89ea3b srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x08c245f7 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x101d9da8 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x2a1662f5 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x2f59b54f scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x549e99e1 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x56980d00 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xdc15ee2d scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xecf6113c scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xf72752e9 scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x01ce5dc3 iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x01fc8290 iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0e38b32d iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x16bbdaa4 iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x3fa3618e iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x64d6a9af iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x680c5882 iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x69f8cbf4 iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x797ce7db iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x8704d019 iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x96a32bea iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa19982d1 iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa993f0be iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc0eb5b33 iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc2ab3bf8 iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc3efeab8 iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc8a8e2a3 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd889bcc0 iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf5ec8f97 iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfa1ed15b iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfe7a5cc3 iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x21b1605d srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x2c1d5eef srp_rport_add +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x3c5f6d7d srp_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x71effe3b srp_remove_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x90b41138 srp_rport_del +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x0f5656e4 spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x1243d332 spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x36cfb947 spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x7aa2f89a spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xa5d8df43 spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xad2f1c6b spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/uio/uio 0x391ec208 uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0xf1daf203 __uio_register_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0xf7931023 uio_event_notify +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x55568e0f usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x603f3c43 usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x64acb87a usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x6fb7c682 usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x7cf1de22 usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x9439e1a7 usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa6f70f01 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xd0f1a228 usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xdd6c89bf usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xe5076350 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xefae73c8 usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x13a0b2da phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x15bd415a wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x7bac59e9 wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x80588912 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x95e13042 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcf9f5ac0 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xf4654c3f wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x02cbec92 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x04f523a4 wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0b23e908 wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x16371189 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x4399e471 wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x47b0fa50 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x77cd7f47 wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x8dc94eea wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x90c1e273 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x927f85d5 wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa55d5b51 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xaa0dc7fe wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xae73e3db wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcab8f226 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xce522d41 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xe7a1cf30 wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xeaec665c wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x132a9b94 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x419cbede i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xcca0de85 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x344d22ac uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x34dc4993 uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x5c794c64 uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x75f2678c uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x789aec33 uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x88f453af uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x965032cc uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xd0ec3c3f uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x1ee5bb71 umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x2ed7a2ec umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x53b07df9 umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x5dca06a3 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x7c936bc2 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x8d06fb19 umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9fe595a8 umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xe85a63c6 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x00e1ace7 uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1a243c4c uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1af4cf76 uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x21f14b05 uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x23ab1d75 uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x25248a19 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x28ccd00d uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2e5d17f9 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x30539dcf uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3de5f6cf uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x444b4580 uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x484ed37a uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4aef23a2 uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e8dd11d uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x68e5f1ec uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6e51a07d uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x71330fd5 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x757a56a8 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x77581e5b uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x811e0833 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x853f2936 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88a2774f uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88e4909f uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9d1ee42f uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa189aaf8 dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa408eab8 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa529f6c3 uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb783e96c uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbff20dce uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc36192c4 uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xd2f0b3e8 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe17e49b4 uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1b3c43d uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe625e3a5 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xebb145d1 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfa251ecf uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xffe82870 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/whci 0x26dd0259 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x04439a19 wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x129c1b48 wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1950358e wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1ebbfd87 wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x288e06f5 wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x345809d4 wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x43a5df98 wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x44c32912 wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x5876cf60 wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x5c8bdef0 wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x5ce164dc wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x66ff271a wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x8023edd0 wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x92a59a61 wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x92b676e9 wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x95cc4682 wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x96a5edd1 wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x97041e84 wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9f41acc1 wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa09b5e8a wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa1545f01 wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa339f6aa wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa6ea982b wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xbcb2a88d wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xc1f7b582 wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xed2c547e wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf256f2d8 wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf46f9903 wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf7de791b wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf9fec561 wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xfc423088 wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xfe11b45e wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x157b52e2 ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x2b665d2b ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x3c63f266 ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x3f434d57 ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x6e789028 ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xa1a9a835 ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xaa22df8a ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0x34f450a8 fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xf90ef147 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xfc6bb947 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x2aaf04a6 sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x384d00e8 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1685ea99 unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x3bb6f505 unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x4af3a22d virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x5c30d55a register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xa104c3a3 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x2fb6c405 vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x974ad0b5 vring_transport_features +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x9febb2c1 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/w1/wire 0x4530aa8d w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5bfb4dbc w1_next_pullup +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5c1323fa w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x891c90f3 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xa36ac307 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xb68c805f w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xbf3c2589 w1_reset_select_slave +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x1c1c866b dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x8b5237e7 dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x8ff86aa9 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x013f63e2 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x464e4c91 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x1b1e3608 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x1d1e434b fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x3b98f7f9 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x3ea792a6 fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x3fadf666 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x566ab4cc fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x5d20e44d fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0x6329efde fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x65dcf584 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0x6942527f fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x8c4db092 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xa19da4b1 fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0xad0fbee4 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xb72de0b4 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0xcc6b53ca fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0xd0123c7e fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0xe6333ce1 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0xfeb2c7d2 fat_dir_empty +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x25dfd408 gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0xd179a0ec gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x0fba09f1 nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6eef0d56 nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x7b6e4108 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xc75d5d12 nlmclnt_done +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x05154e87 o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1cb231d0 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x40e4880e o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x630ca4ba o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x687f6251 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x6b58f6a9 o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x6dc97052 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa9f5379a o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xb934747b o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xe654a21c o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x143548f7 dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x1a0ec05e dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x3ccac557 dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x6960276b dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xc51e25a4 dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x19c6e0db ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x22106ad3 ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x390be1d0 ocfs2_plock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x651f2094 garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0x6c92348d garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x85b826e4 garp_init_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x93d3652e garp_request_leave +EXPORT_SYMBOL_GPL net/802/garp 0xb5de9082 garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0xe33ed404 garp_register_application +EXPORT_SYMBOL_GPL net/802/stp 0x3f3cdc1e stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0x5437e98c stp_proto_register +EXPORT_SYMBOL_GPL net/ax25/ax25 0x279d6469 ax25_register_pid +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x1cc3f342 tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x387cbd08 tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x39ff5926 tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x4bd894ce tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x7ae904f2 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xd579cdcd tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x089c47f8 dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x11985c11 dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1287c80f dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0x13c575e8 dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1448d42d dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1ae3b729 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1b13f0f0 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1f5c8b15 dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x31139d5b dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0x384587f0 dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3ea059a9 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x459f474a dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x49132008 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x498f9611 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4acbe812 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5003518b dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x51468622 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x55062096 inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5f5c3ea3 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x628de481 dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x63fbc056 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6e3d7305 ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x7773772d dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x81660348 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x97f23af4 ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9cb09f28 dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa472d4d9 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xaa73b134 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb1ef7c6a dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbbbef144 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbef5f181 dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc21755fb dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc22fcb15 dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc726700b dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc9bfc374 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0xca6ed04b ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xda426ecd dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe6899040 dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xef4d5cca dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf24581ee dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf2944a18 dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf4a156af dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf9fd2408 dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfc287b47 dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x1db4cc3e dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x32edcc07 dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x3ae22671 dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x58095dcc dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xbf31ca49 dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xca8c0264 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0xc4e91462 ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x5e4ceca9 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x0e9a0d61 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x3a714ccf nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x7243ccc8 nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x77f00aa8 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xa9d3fef9 nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x364f88c0 tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x60373420 tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xbd542f09 tcp_vegas_init +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xe120ff04 tcp_vegas_state +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xfa25abad tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x5010db59 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x76c3cfe9 ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0157722c nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0e806d22 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x197efca1 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1d977a41 nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x21a2a068 nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x21b90898 nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x22c7caad nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x27a12a48 nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3110bb3f print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x336110ae nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4026a279 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x471e14da nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4872c8c4 nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x54c39bf5 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x587d7111 nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5a873f01 __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5b172be8 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5d051180 nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x60265493 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6ee669c3 __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7f16d829 nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x86591872 nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x886a1333 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x94b7ed4c nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x95a6807f __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x987eb398 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9ab61288 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9eeb750b nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa3708b68 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa9179d19 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xadce9ad0 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb9b13255 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbe6ce830 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc49a6c88 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd32a10d0 nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd88fc6e9 nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xdb80699c nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe231a186 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe891762a nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe9b60b1e nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf138279d nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfe3422e2 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfe5edbdd nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xffbf6993 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x886d0f47 nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x1ca0ba9a nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x08038dc1 nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x377cc433 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x3c08fd1b nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x451a5e23 nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x77d9582b nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xd39e825d set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xdc324918 set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe1c6b96c set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xf0dbe7c4 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0x9919b808 nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x03945dcd nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x09d94e29 nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x34b86b5b nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x8d1376e4 nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x05f4e97f nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c76ba38 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x748df661 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x8979110d nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xac089269 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xd4898e54 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0xdd520e89 nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x661dbc76 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0xe03b8bcb nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x80238161 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x8417f17f nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xb6633175 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xe39e797e nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x0444bcdb xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x21c62e82 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x220128db xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x24fb40a5 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5b762a04 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x616ad8a3 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f758f10 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6fcacd09 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x7796d900 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xfc9b665f xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x108d51a3 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x20e79171 rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x06f5abfa svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0b12cf05 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0e152629 svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x10309d71 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x10a42a5b rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1552a9a0 svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1690cad7 rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1afbff39 rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1f2a218a rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1f76780f xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2093525e xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x247440bb rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x26fadeb7 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2f5baf7b svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32e0a3da rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x35bbdb8d svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x37280403 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3a7ea269 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x411063f9 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x420b4fcb rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x42f7e728 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4428cdac rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x48ffd61d xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4c47c2bc rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4f68229d rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x534ad7ec rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x56fba4d2 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bf6ebae xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5dbf00a1 xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6d88ca8a rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6f38e526 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x74e5a0dd xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x74e82dca svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7c9be7f4 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7cf4e2de xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7fbdce6c xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x83e74b2c xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x850d5e26 rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x87355af2 xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8eb7b4b7 rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8ee72980 xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x92bf1cac rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9308f425 svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x964aa46f rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x97312929 rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x98e4ccbb svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa3e98a08 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb11444f0 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbad0c8ac xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbb71d24e rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc3b69329 rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc411f71f xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc6a2ae98 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc78d7290 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc8b9c393 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcaf6ca7c svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd2bb01c4 rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd3a5c66b svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd3fab0b9 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd621fba7 xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd68fbdda rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xda10cdd5 rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe0e5748f rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe355930a svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe4a51f23 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe520a520 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xebe31774 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xec142ac3 xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xed561f96 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xee124d8f rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeedccead rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf073666f rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfc336d05 put_rpccred +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x0e2e243f ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x6f95d06a ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xf5d3aa3d ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xffea2dd3 ipcomp_destroy +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x4e42f875 ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x50efefeb soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x1c537a66 ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x78b5d559 soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x1720097a soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0xde01be02 cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x414cb01a soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0xf8e22fe2 ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x1863ee24 tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x9dc03256 soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x370a7198 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0xe1b4a8a8 aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x4f733ca6 aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x7291c800 aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x7d395875 aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xc0c09374 aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xebb1e1a2 soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x1ec3627e soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x9a250ef7 uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x11e1529a soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x76687727 wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x1e306915 soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x322af0ff wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0x688eb2d6 wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xa1777f3e soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xbce132cd soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xc0025449 wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x97cc610e soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0xe9a2bd1c wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x5af58715 soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x87b069dc wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x01241b72 wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x71d8d4d6 soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x46a1a0d1 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x894b84f7 wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x12282c0f wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x5524bc9a soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0309f4a5 snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x12225bb5 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x17387bde snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1b113b11 snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x21a0be5b snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x21e3b236 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x235d418b snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x245d5d35 snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x2f4e2017 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x34099198 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x375c0e6a snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3a510b81 snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x41a3b8b9 snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x448945f4 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x47434cf7 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x5742755a snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x65d7f787 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x67587c5e snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6eec27d2 snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6fd59494 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x70dc7d3f snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7dd2c12a snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7fb4575d snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8024e117 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x84e12ce8 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x85d66a89 snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x95749b8b snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9886b855 snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x99983e90 snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa276d311 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa42b7ee3 snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb14ea835 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb577438e snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb6303e6f snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xbc983bfc snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc8f71ed2 snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd9aada65 snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xda2b3f1b snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xde3f945e snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xde798b8f snd_soc_test_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe1483c27 snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe2376273 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe7c5e9ed snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xea2edb6c dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xebe58425 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf37dee6a snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfa767d77 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x002c2093 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0x0033f441 usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x00616ef3 sk_clone +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x0069ba91 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00b7f6ff inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x00ceafb8 sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x00f1d4eb bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x014df9f9 cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x01713585 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x0191d512 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01bb99ab unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x01f80c10 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x021742c9 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x021eb672 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0220fb8b device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x02335660 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x02b81119 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x02eab7d0 ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x02eef299 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x0300fad5 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x03011c7b rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0x03365098 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x03803d54 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x0389f55c sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0x039bda97 fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x03d4d38b rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x03e358fe led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x040e13ff ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x04192678 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x046f177e ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x047eaa2f inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x04afe50e vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x0503fc20 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05b5ace1 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x05d497c0 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x05e65e20 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x063d70ab put_device +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x0684e6a7 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x06ef8a6c debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x071c2968 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07ca2707 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x087a1b3a md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0x089b3e5b bus_register +EXPORT_SYMBOL_GPL vmlinux 0x089bba87 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x0929b12a usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x09e013e2 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x0a11c436 preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x0a433457 preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0a669d94 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x0ab1a5a7 crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0ade26c7 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0x0b262d9b single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x0b53a167 device_move +EXPORT_SYMBOL_GPL vmlinux 0x0b87da7b ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x0b9d29cc devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x0bb7e672 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x0bcee550 dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c236dba sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0ca4e305 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x0caf4539 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x0cb63add securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x0cb9c908 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x0cf47a52 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x0d4fa615 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0d872005 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x0da44cbb mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x0da91564 bt_class +EXPORT_SYMBOL_GPL vmlinux 0x0dffd83d usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0x0e22e5f5 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x0e2411b3 relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0x0e5e43dd ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x0e614c04 pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0x0f0a38a6 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x0f0d238a key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x0f578f8c tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0x0f765091 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x0fa67298 dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0x0fd28fc9 usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x10c33ec9 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0x10c490b9 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x10dbc0b9 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0x10dd571e debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x1129488f usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x11382702 user_match +EXPORT_SYMBOL_GPL vmlinux 0x116477d7 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x11fa5233 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x12150c94 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x12321303 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x125ea497 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x130678ab ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x130873c6 fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x13354608 scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0x1348961d invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x13577276 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x13605cb1 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x13945e9c usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13e29235 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x13f2b874 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x141eb283 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x1457eab6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14ad1411 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x14b7f1fb hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0x1577733a device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x157e8558 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15cb37fa bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x162c4fcf sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x170354ab hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x17201986 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x172bffee skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x172e72d4 vdso_enabled +EXPORT_SYMBOL_GPL vmlinux 0x174e20f1 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x1769f2c6 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x177b8eff usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x17ad72d5 ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0x17c36184 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x17fd6ab1 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x181937dd usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0x18235ced ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x1825b9d9 ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0x18674aa5 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x18767490 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x1883d3ec inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x18c29075 pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x1925fc82 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x1945ef9b generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x1991bd78 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x1a35c6fa ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x1a43c332 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x1a54c906 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0x1a70ca58 crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x1a71c7e7 da903x_read +EXPORT_SYMBOL_GPL vmlinux 0x1a7a2d29 cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1ab2cb9e usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1ad69db6 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1bd3758a rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x1c0eca58 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x1c16e474 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x1c311c77 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0x1c716aec usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c951520 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x1cb034d6 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x1ccb5838 mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1d1403b6 usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0x1d32e0ce usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x1d830203 sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1dda0809 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0x1df9d5ae shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x1e4be096 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1eabb723 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ecba220 dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0x1eeda530 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x1eeda7f3 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x1ef830fb inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x1efc7e80 hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x1f232cd1 kmap_atomic_pfn +EXPORT_SYMBOL_GPL vmlinux 0x1f79f8dc sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fa55198 fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1fd58b36 regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x1ffa0d44 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x20041297 ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x20459dee crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x206584ed simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x206bd994 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x215831af ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x217a0319 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0x21aeb7b8 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x220a1275 hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x22662f91 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x228a2c73 pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22dd52ed ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x23294a83 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x234bb3d6 ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x23e3e7b9 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0x2409cf40 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x24234f11 crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0x24353142 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x2495c24e dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0x249b4b0d tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0x24d54e5b device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x24de6c0d driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x25049b64 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x250f1e4c input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x2538d3b5 usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x25421e78 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x25679f3d blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x25b78eac dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x25dc0915 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0x26389fb1 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x2660e3e8 xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x26c85cac usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x271bbb38 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0x2750845c tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x27976132 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x2801fd41 rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x287d7a54 cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0x288c70b4 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x2899673a d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28cc6efb inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x295394e2 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x2959a78d rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x29c175c4 usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x29f16771 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0x2a1f6555 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x2a27ab5b console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x2a48022d dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2aa10c29 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x2aa53db6 cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0x2ad0ef58 relay_flush +EXPORT_SYMBOL_GPL vmlinux 0x2ad12f9e cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0x2ad62b4d tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0x2afddb2d regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x2b5b493d blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c4275e2 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0x2cb1afd2 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2cf49fd4 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x2d33a920 ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0x2d45bcda crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2e1a38d5 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x2e2b1625 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0x2e2d697e regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x2e4baf57 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0x2e862eb0 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x2e877e83 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x2eb91dfe scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0x2eeadf6b pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x2f1935a0 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f4dfcee platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x2fdaf798 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x301ec33c regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x307e40ff __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x30d41724 xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0x30e254ec da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0x314a0038 blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3196642c xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0x31cf9da2 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x31e2e7a3 fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x328a28fa regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x32b665d9 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x32e99e3a rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x32f09ed5 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x336eef4a get_driver +EXPORT_SYMBOL_GPL vmlinux 0x33719418 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0x3372a10e crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0x33756dae relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x33cc933f rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x33d743f3 relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0x340b39d2 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x3445ff59 sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0x344dfbc0 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x34d0a7f8 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x34fdf7fe find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x35575b83 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0x3582c244 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x358c2513 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x359f9ed4 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35dda27b scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x35e19fde skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x35f20b53 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x36218707 usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x364c0652 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x3684ba31 pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x36f79a6d ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0x37553ead sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x381abae5 crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x3850e17d mmput +EXPORT_SYMBOL_GPL vmlinux 0x3864c6b0 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x386e3bb0 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x38f9553f spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x39105bca pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x39178152 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x396aa0af da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x397821cd dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0x39a8ac19 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0x3a1262ad aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x3a31ae3f ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x3a5fa251 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3b008e13 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0x3b0886ab driver_register +EXPORT_SYMBOL_GPL vmlinux 0x3b171493 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x3b79360b hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3c38d3f5 usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3e5b5089 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x3e6f79e2 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x3e8078ad relay_close +EXPORT_SYMBOL_GPL vmlinux 0x3ea8150d raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x3eb787a7 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x3eb8f0ec usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x3ecb904c seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f588432 power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x3f810a12 led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x3fb0bbe3 device_del +EXPORT_SYMBOL_GPL vmlinux 0x3fd0016b scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0x40258bf0 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0x40260ccc ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x40888e5b proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40c3a5c8 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x40e798ec tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x40ebd419 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x40efff1b ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0x40f2c8f5 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x414255ed platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x41e193ab scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x4209eb55 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x4216f634 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x423e55fa usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0x42b364ef scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x42c32fa7 device_attach +EXPORT_SYMBOL_GPL vmlinux 0x42e91928 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x43030f40 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x43d02cfd ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x4439b2e8 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0x448907a8 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44dc8d5f dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0x4505faaf aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x450f41c5 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0x45321eb5 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x456afa6e usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45a0cc2c relay_reset +EXPORT_SYMBOL_GPL vmlinux 0x45b97091 dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x45d73b92 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0x45faaabd pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x4606950e dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x461c3e30 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x46313471 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x4639556f xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46c9d957 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0x46d4fa72 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x46d6df7e __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x4746c2c7 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x4791c82c hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x47d352e7 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0x4843b940 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x487019ab debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0x48a114a2 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x48f66a9a sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0x498ee7e6 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49c56ca4 ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x4a6c1c5c crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4aab66c4 pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x4ac3aac5 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x4b9e12c4 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x4bcef498 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x4c105e6b unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x4c1bb689 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x4c248b6a dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0x4c32215e power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4ccfed1f transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x4cf06b68 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x4d2d9e1b sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x4d92415e ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x4de0463e __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x4e21a9f9 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x4f3503cc vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0x4f40073f inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x4f59287a input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x4fa420e5 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x4fb963c6 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x4fddef91 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x4ff24d19 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x504acde3 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50bf8c53 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50ed4679 regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x5108b3fc acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x5112f5da transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x512fb85e task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51e6045b usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x52322f51 fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x52561a9c bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x529688bd cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0x52b036ea driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x52baac6d i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x52cc59b5 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x52edf4ea crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x5343124c skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5371175c inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x53725095 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x544c826c inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x545e768e led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x54714292 pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0x54e45ed2 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0x55c30f34 tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x5636fafc dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x56844a81 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x56d788fa ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0x56dee697 usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x57192dbd platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x571cfce0 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x57346cf7 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x5744aa4d tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x57514bb9 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57a6e137 securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x5886445c tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x58a1872a ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x58a3618f hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x58a65786 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x58c5f9fb crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x590cd4fc usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x5921ae08 __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x5988fdc2 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x59a3af1c device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x59bf5440 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x5a08d3b4 seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x5a1da202 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x5a24a866 sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0x5a488a54 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x5a6d1f6e ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x5a6f5cff cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5ac8c6b7 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x5aee9322 tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x5ba7a634 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c0266c1 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x5c84bcb9 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x5c966d92 usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d51bcf7 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5daf76f4 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e0178e7 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x5e045425 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0x5e099c16 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x5ed3fd9c ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0x5f0e5a5f ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x5f1e0c6a usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f65bbc2 dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0x5fbe2a51 sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0x601cf691 inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x60349785 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x6109a791 vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x610aa116 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x6175d6d0 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x6191aadd map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x61d5f003 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x626cfc21 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x6330d231 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x635487ad ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x63a20831 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63b1d791 dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0x63ce33d7 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x649abd20 usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x64ebe677 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0x64f725ef debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x65dc38bc ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x66573506 rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x670743f6 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x67239da0 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x67425ad0 pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0x6750c323 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x6795cc15 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x67c51be1 pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0x67f0fc63 sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x684b82f7 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x69143884 unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x691d4b44 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x698713dd led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x69bac3e9 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x69f33fb3 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x6a288e5d rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x6a2fe472 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6aa26f89 inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x6ab869f5 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x6af66389 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x6b957554 hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0x6b9f9236 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x6bc41182 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x6bcbb91e simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6cc6fbc5 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0x6cce7815 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0x6d04b6a5 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x6d0bb0b5 crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0x6d23e43f do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d78fe5b crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0x6d86b8e5 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6e2a11e6 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x6ebe305d raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x6ed917bc ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x6ee96731 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0x6f28fecb usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x6f3e22c6 register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x6f5958d6 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6fbc049c scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0x6fe15128 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x700c6e4b sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x704eff72 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x707b305d ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x71b094fe inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x71cea0b0 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x71cf73d3 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0x722066fe ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72a5b379 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0x72cb039a scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x72f257fa ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x734e832e sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x734ea682 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x740796b3 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74ace104 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x74deb10c used_vectors +EXPORT_SYMBOL_GPL vmlinux 0x74e5202c tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x7568b92e register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x75b27d80 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x75c3736c devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x75c8a11c inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x765d519a inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x767bd777 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x76ee2ea6 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0x76f0ddc0 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x77000fde crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x772b4f22 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x78483caa tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x787cd3a5 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x78b44e08 get_device +EXPORT_SYMBOL_GPL vmlinux 0x78c36155 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0x78dedf9a sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x7903a123 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79b8e0a8 dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a76e921 input_class +EXPORT_SYMBOL_GPL vmlinux 0x7ab1c68f sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x7ac3db93 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7b0f4391 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7b48aca8 unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x7b85a346 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x7b8e250e ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x7bdd3223 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x7c075faa register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0x7c1d2459 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x7c258b93 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0x7c335c2a pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0x7c6dc88b tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x7cb19d9f blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x7ccfc15e crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x7cf2b9cc devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7d33b5be register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x7d58123c sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0x7d94be41 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7dffc6c4 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x7e01bce6 ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e64ac68 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x7e698a51 unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7e7232d9 tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x7e9c955c dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x7ee93659 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7eefa204 inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f782dc3 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x7fc9c37c inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x803e4900 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x8044efe2 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80c4274f tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x8171179a sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x8186485f debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x81b733f8 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x81c5682f sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x81facfd9 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x8268ead4 iounmap_atomic +EXPORT_SYMBOL_GPL vmlinux 0x82742a6b attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82dfd9ba blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0x82f5273b register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x83368956 device_create +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83c2bc46 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x83cf1f24 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x83d74569 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x850de4b6 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x85481842 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x85540ca3 raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x8558c418 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x868da92d queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x86b10394 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x870404b8 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x870ddfe9 sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0x870e2c5a crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x884d54eb netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x8858b5c5 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x886736fc olpc_platform_info +EXPORT_SYMBOL_GPL vmlinux 0x889e0191 isa_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x88b8daec platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0x893cbf54 ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x8950a2d9 blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x89e77c5d tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x8a051ccc regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x8a392aae __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x8a5ef3a9 usb_string +EXPORT_SYMBOL_GPL vmlinux 0x8a9af98f rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8b109a56 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x8b235b05 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x8b3126cd sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x8b6b6c10 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8be75d85 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x8c103671 bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8cfe7574 find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x8d02a6bf disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x8d1d6f31 usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0x8d2d4995 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x8d35eb15 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x8d376de8 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x8d5d1bd1 user_update +EXPORT_SYMBOL_GPL vmlinux 0x8da17b42 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x8dc834cc usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x8dd78d25 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x8dd897db usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x8defb1a0 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x8df0a8b0 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8df2bfba xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0x8df91d8f sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x8e161fb9 sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0x8e6d9a0a user_read +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8eee05b8 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x8ef2e631 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x8ef51d90 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x8f265b5a __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0x8f2fdd9f blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f8d3742 proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x8f96a000 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x8fc3fd71 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0x8fddd08d unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x8ff8dbcd blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x9064d621 sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x907a8b85 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x90811115 device_add +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90c74215 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x90e62d78 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x90f439ab cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x91a01ed8 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x91f0004e kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x921d02c0 hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92a2012b ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x9308c817 pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x930d0ced inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x933740ca cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x9381debf xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x93917cf9 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x93926d78 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x9422247b platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x942d06f0 ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94c32db2 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x94c3ca10 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x9598cf88 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x95dc0ee5 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x95dec4b0 fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96cd1568 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x96d78150 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x96f13738 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0x9762e385 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0x97728349 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x977a302c crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x97dbe3e1 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x9862d0e3 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x988e4bf6 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x9980dc70 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0x99d8fedf da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0x99e7e3ea sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x99f74ccb gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0x99fceef5 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a64eff7 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x9a752c07 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x9a87a430 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x9aac86f8 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9af14948 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x9af46895 __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x9b0a7058 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x9b8d993f gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0x9b997a75 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bb0dfe7 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x9bc08428 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x9bc47866 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x9bc49ecc uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x9c132ade __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cb8a62d usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x9cecf848 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x9d6bb699 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x9df15e40 __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x9e1701b1 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9e87ff69 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0x9f0e85c7 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x9f2d526a sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0x9f95081e inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0x9fc816c8 cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9fd32062 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0xa00f3e4c cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xa024a1e6 dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa041b8b2 pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0xa0aa2b44 usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xa14be281 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa1ab3866 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xa1e3f052 blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0xa23ec09f ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa33bb852 __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0xa38bb0c9 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0xa3d3d8c0 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xa3f6d2ca pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa43deabe ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa4857100 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xa495ac7f usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0xa534a52e ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0xa5925fb8 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0xa5b879ba ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5fe4305 elv_register +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa6caa3b0 pskb_put +EXPORT_SYMBOL_GPL vmlinux 0xa6ea0fcd usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa789e515 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0xa78a073b sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa7b090c7 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0xa7dc10d7 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0xa7e4734f put_driver +EXPORT_SYMBOL_GPL vmlinux 0xa80fcdb7 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa8305e11 device_rename +EXPORT_SYMBOL_GPL vmlinux 0xa85cb65e ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0xa8a146dc inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa90834ab cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa94c00bc inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0xa95306ab ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0xa956a362 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa9b7afd8 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9d3e56e sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa5968a8 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xaa70c006 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xaa87cae4 usb_root_hub_lost_power +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaa8da4fa usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0xaabc598d cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0xab0e2811 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab7b99ec security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0xabb5242f securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0xabf57a7a put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xac0292be blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xac137572 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0xac45ecfe hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xac5ae2c6 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0xacb301a6 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xaccfc678 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xacfc667c scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xad149a47 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0xad1770e3 usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0xad424a25 scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0xad57ed88 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0xad789630 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0xada6e0a2 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0xadb42e94 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae45356a sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xae4919dc relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0xae492f0e dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xae5037ab regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xae9354b6 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0xaeb7f977 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xaf18d951 ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0xaf8d4264 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xb07a994a fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0xb09a9ee8 iomap_atomic_prot_pfn +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0ab9f8c flush_work +EXPORT_SYMBOL_GPL vmlinux 0xb0ad7775 ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0xb0bbac35 platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0xb0d9abdc register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb12794a8 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xb132ea5c md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0xb1406e4e ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1cfb61f sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xb1dfedbc usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0xb2536058 acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb28c5cad raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0xb2b2abc7 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0xb3069641 crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xb313a59e unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xb31c38fd vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb3741ca1 fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0xb37d7544 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xb37dfd3f skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0xb3bb437a invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb3ee54ea tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xb41cb079 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb431023b regulator_register +EXPORT_SYMBOL_GPL vmlinux 0xb476fbc1 cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xb4a9999a hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xb4c6e4f4 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0xb4c80c75 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0xb4e65327 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb5c27f6c dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0xb5e76edf mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0xb6220b6c drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb658ef94 blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0xb65a94b4 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0xb696c9e3 usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6daf4e2 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xb7586f76 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xb7ae9d40 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0xb7ba6928 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb7f51bb0 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xb9041d8a crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0xb94384bb generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0xb944971e tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba1cacca usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0xba356aa7 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0xba698916 __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbb40aa83 dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0xbbb48c14 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbbf20bcb inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0xbc0b3561 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xbc1ed56c scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0xbc7e5bc1 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xbc841043 usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0xbc9a4533 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0xbd17d36c hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0xbd46f67d dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbdcce1b1 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbdfa9ae7 crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe413599 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xbe47ec45 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xbe75b9c6 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0xbee6d86b i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xbf397dd2 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xbf44f305 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbf4a1fcb dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0xbf77a040 pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xbf85e297 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0xbf94fe3c rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0xbfa415bc spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xbfb59968 da903x_update +EXPORT_SYMBOL_GPL vmlinux 0xbfd4da78 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xc017eb53 sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xc03f23ee blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xc1193db9 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc1b9670d leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0xc1e61494 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc268904d regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0xc339a3d3 dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc364cbd7 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc38b55f6 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3a9e7ce dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0xc3c1e9f9 sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0xc3c86dd6 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0xc4241b26 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc45268ee proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4e1107b ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0xc50ce906 usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0xc512626a __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xc5528d04 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xc58cdb60 lookup_address +EXPORT_SYMBOL_GPL vmlinux 0xc5b83f66 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc5e3dddf wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0xc62facf4 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0xc63f43c7 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc65396d1 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6eb1d53 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc751c582 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0xc7829aca relay_open +EXPORT_SYMBOL_GPL vmlinux 0xc7c5ec3c sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc7ef5ba9 dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0xc835d25a ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xc879a6ad driver_attach +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc8ad884f ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0xc8cc740a usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0xc921089f ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0xc93fa017 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9b924ff debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xc9e37865 isa_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xca414ff7 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xca56f0ff xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0xca677983 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0xca989032 exit_fs +EXPORT_SYMBOL_GPL vmlinux 0xca9d52a9 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcac686f2 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xcacc4105 queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0xcb029d14 usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0xcb51832a usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0xcb6ca6e8 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcc764f95 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcce5c9ac ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcdd6550e register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xce4aa154 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xceb06d36 device_register +EXPORT_SYMBOL_GPL vmlinux 0xcee44482 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xceedd1df nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xcf0bfd12 start_thread +EXPORT_SYMBOL_GPL vmlinux 0xcf19db98 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0xcf38e83d pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0xcf82bff5 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0xcf8a41a8 pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0xcf96cdd2 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcffe0317 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd0280ce0 inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0xd038cd31 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd041483f scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xd05a11ac audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0c0d52b hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd0db33b1 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xd0de4e51 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xd0e3cc37 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xd1202f3f inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xd12ac59b olpc_ec_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd1802c8e sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xd23ac61d tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0xd24da1cb transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd27d2d95 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd2acc5e3 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0xd2cc8d75 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0xd3234245 rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd345db28 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0xd36c1831 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0xd375266e crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xd3b8b6b0 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0xd3bc088a scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xd3db2a0e crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0xd3dc94d9 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xd4110883 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xd4605677 devres_add +EXPORT_SYMBOL_GPL vmlinux 0xd5308b70 sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xd5352db6 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0xd5416e39 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0xd6098170 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xd622a36b tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xd680e49c device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xd68eefd4 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0xd69e72ca fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0xd6acd633 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xd6e3c6c4 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0xd6eb74a7 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xd7d0879c crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0xd7d3c017 sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd83242e6 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd8473604 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0xd849977d blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd8cb9ee1 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0xd8f49b2d audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0xd951a804 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xd9d83a77 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xda07acde usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0xda2ffb60 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xda9a27d1 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0xdad3685a scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb269c8b pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0xdb749b95 save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0xdcd8b934 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xdcf47478 fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0xdd385c50 ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xddab8228 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xddd8b5e9 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0xde117192 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde255409 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0xde4b1757 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xde4b43b3 spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xde76bf98 register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xde7f8b30 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xdea0e5f5 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0xdf09d37f apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xdf27ebfd mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xdfb97773 blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0xdffaa1db spi_sync +EXPORT_SYMBOL_GPL vmlinux 0xe0406b5a blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xe14ca691 scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xe193b149 sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0xe1c813d9 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xe2426710 wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2e1574f __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0xe2f1340e inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0xe35c65a4 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0xe3707fbe destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xe3846ed1 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xe3b3f003 usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0xe42609c4 blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xe44f8b2e xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe4934a3e crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4a89dc6 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0xe4c331b6 acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0xe4d02b0a inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xe4da633b platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe517de3d ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0xe51c616a fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe56bf229 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0xe57ed309 crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xe5a98637 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xe600f2a8 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe6bc5d9b copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xe7a6e174 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe8910c99 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xe8982bb4 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xe8da2002 cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xe90d3d64 page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe99bdb7f macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0xe99f6324 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xe9ce6654 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea4c8ff4 k_handler +EXPORT_SYMBOL_GPL vmlinux 0xea503d01 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xeab61435 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0xeab91aa9 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0xeac02b10 dm_put +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb2c15d1 ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xeb5d218a ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0xeb78746f inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec41644f sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0xec674d43 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0xec6fabd6 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xec937e1b ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xecce638e hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xecd1ee2a crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0xece07a3d dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0xed35ccd8 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0xed6bb521 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0xee1a5071 put_pid +EXPORT_SYMBOL_GPL vmlinux 0xee33b755 crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0xee9e846b crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0xeec9018f dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0xeecc5cc0 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xeeea2010 blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0xeef0a490 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xeef77484 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xef4ba172 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef7a0682 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0xefe0cab3 __class_create +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf0170d79 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xf0a7c66e device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf15549f6 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xf158b8dc fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0xf1676b41 user_describe +EXPORT_SYMBOL_GPL vmlinux 0xf17f29b9 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf187ad00 input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0xf18c6013 da903x_write +EXPORT_SYMBOL_GPL vmlinux 0xf2568daa tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xf265d993 aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xf2955f56 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf3026d73 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0xf31a7561 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xf39e13bc bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf435f7bc sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0xf453fae5 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4a5030e ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xf52c3e02 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf591b7d0 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0xf59cb304 fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0xf5a5ee70 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5bc167f pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0xf5c03271 pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xf5d2eb19 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xf5df06c1 __class_register +EXPORT_SYMBOL_GPL vmlinux 0xf5ec7448 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf5fdc073 dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0xf650ebf0 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0xf65b9513 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf6770692 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xf6a2fee5 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0xf6afda70 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0xf6b2c8aa spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0xf6bcb602 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf6e0f6e1 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0xf6f46c4a ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0xf71271b0 class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf7656fab __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0xf7790a6f skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xf7827222 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xf79b1b22 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0xf7fe01cf sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0xf7fe3a22 rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xf82f16b3 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf83b449f usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0xf84c295b ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xf84f7143 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xf852b9c4 set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0xf87a8b57 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8914d8f usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0xf8a0f99c pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xf8b66770 spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf914cf59 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xf922a52a usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf984f5dc usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xfa1c5172 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xfad1133e bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0xfb04c273 md_new_event +EXPORT_SYMBOL_GPL vmlinux 0xfb0576a9 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0xfb2a3293 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xfb50f54b ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0xfb815413 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc93dcfb da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfce40c1b blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0xfce66e06 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0xfd3930d7 unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xfd86d431 regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xfda74e28 user_destroy +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfdf1c041 per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0xfe28c463 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xfe86213a tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfebd63c8 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfed93be5 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL vmlinux 0xff899128 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0xff9fcaf7 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0xffc0d222 ata_eh_analyze_ncq_error +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/i386/server.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/i386/server.modules @@ -0,0 +1,2303 @@ +3c359 +3c501 +3c503 +3c505 +3c507 +3c509 +3c515 +3c523 +3c527 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +53c700 +6pack +8021q +8139cp +8139too +8250_accent +8250_boca +8250_exar_st16c554 +8250_fourport +8250_hub6 +8250_mca +82596 +8390 +8390p +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac3200 +ac97_bus +acecad +acenic +acerhk +acer-wmi +acpi-cpufreq +acpiphp +acpiphp_ibm +acquirewdt +act2000 +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-i586 +af9013 +affs +af_key +af-rxrpc +agpgart +ah4 +ah6 +aha152x +aha152x_cs +aha1542 +aha1740 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-agp +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd64-agp +amd76x_edac +amd76xrom +amd8111e +amd-k7-agp +amd-rng +analog +ansi_cprng +anubis +aoe +apm +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arlan +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at1700 +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati-agp +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1isa +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_epp +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_aout +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpck6 +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c101 +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-isa +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cosa +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpqphp +cpu5wdt +cpufreq-nforce2 +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +cs5535_gpio +cs553x_nand +cs89x0 +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyblafb +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +depca +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +donauboe +dpt_i2o +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtc +dtl1_cs +dtlk +dummy +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e2100 +e752x_edac +e7xxx_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro +eepro100 +eeprom +eeprom_93cx6 +eexpress +efficeon-agp +efs +ehci-hcd +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +eql +es3210 +esb2rom +esi-sir +esp +esp4 +esp6 +et131x +et61x251 +eth1394 +eth16i +eurotechwdt +evbug +ewrk3 +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fd_mcs +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +fuse +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +geode-aes +geode-rng +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +g_NCR5380 +g_NCR5380_mmio +gpio_keys +gpio_mouse +grip +grip_mp +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +gx-suspmod +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hostess_sv11 +hp +hp100 +hp4x +hpfs +hpilo +hp-plus +hptiop +hp-wmi +hso +htc-pasic3 +htcpen +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-isa +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i810 +i810fb +i82092 +i82365 +i82860_edac +i82875p_edac +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmlana +ibmmca +ibmpex +ibmphp +ib_mthca +ibmtr +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icn +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +in2000 +inet_lro +inexio +inftl +initio +inport +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lance +lanstreamer +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-net48xx +leds-pca9532 +leds-pca955x +leds-wrap +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lne390 +lockd +lock_dlm +logibm +longhaul +longrun +lp +lp486e +lpfc +lrw +ltpc +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +madgemc +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdacon +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mixcomwd +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msnd +msnd_classic +msnd_pinnacle +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +n2 +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +NCR53c406a +NCR_D700 +NCR_Q720_mod +ndiswrapper +ne +ne2 +ne2k-pci +ne3210 +neofb +net1080 +net2280 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +ni52 +ni65 +nicstar +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +nsp32 +nsp_cs +ntfs +nvidia-agp +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +ohci-hcd +old_belkin-sir +olpc_battery +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +padlock-aes +padlock-sha +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas16 +pas2 +pata_cs5535 +pata_cypress +pata_hpt37x +pata_isapnp +pata_it8213 +pata_legacy +pata_ninja32 +pata_oldpiix +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pata_winbond +pbe5 +pc110pad +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcbit +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pms +pn_pep +powermate +powernow-k6 +powernow-k7 +powernow-k8 +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +proteon +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r82600_edac +r8a66597-hcd +radeon +radeonfb +radio-aimslab +radio-aztech +radio-cadet +radio-gemtek +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-rtrack2 +radio-sf16fmi +radio-sf16fmr2 +radio-si470x +radio-terratec +radio-trust +radio-typhoon +radio-zoltrix +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-i586 +sata_mv +sata_sx4 +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc7240_wdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +scc +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +scx200 +scx200_acb +scx200_docflash +scx200_gpio +scx200_hrt +scx200_i2c +scx200_wdt +sdhci +sdhci-pci +sdio_uart +sdla +sdricoh_cs +se401 +sealevel +sedlbauer_cs +seed +seeq8005 +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sim710 +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +skisa +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc9194 +smc91c92_cs +smc-mca +smctr +smc-ultra +smc-ultra32 +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1816a +snd-ad1848 +snd-ad1889 +snd-adlib +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als100 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt2320 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmi8330 +snd-cmipci +snd-cs4231 +snd-cs4232 +snd-cs4236 +snd-cs4236-lib +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs5535audio +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dt019x +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emu8000-synth +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1688 +snd-es1688-lib +snd-es18xx +snd-es1938 +snd-es1968 +snd-es968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-gusclassic +snd-gusextreme +snd-gus-lib +snd-gusmax +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-interwave +snd-interwave-stb +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-miro +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3sa2 +snd-opl3-synth +snd-opl4-lib +snd-opl4-synth +snd-opti92x-ad1848 +snd-opti92x-cs4231 +snd-opti93x +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16 +snd-sb16-csp +snd-sb16-dsp +snd-sb8 +snd-sb8-dsp +snd-sbawe +snd-sb-common +snd-sc6000 +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-sgalaxy +snd-sis7019 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-sscape +snd-tea575x-tuner +snd-tea6330t +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-wavefront +snd-wss-lib +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sonypi +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedstep-centrino +speedstep-ich +speedstep-lib +speedstep-smi +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sworks-agp +sx +sx8 +sym53c416 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t128 +t1isa +t1pci +tc1100-wmi +tcic +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tlsup +tmdc +tms380tr +tmscsim +tmspci +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-i586 +typhoon +u132-hcd +u14-34f +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uhci-hcd +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +ultrastor +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-rng +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan +wavelan_cs +wbsd +wd +wd7000 +wdt +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wistron_btns +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xen-blkfront +xen-fbfront +xen-kbdfront +xen-netfront +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xpad +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +z85230 +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +znet +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/i386/generic.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/i386/generic.modules @@ -0,0 +1,2302 @@ +3c359 +3c501 +3c503 +3c505 +3c507 +3c509 +3c515 +3c523 +3c527 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +53c700 +6pack +8021q +8139cp +8139too +8250_accent +8250_boca +8250_exar_st16c554 +8250_fourport +8250_hub6 +8250_mca +82596 +8390 +8390p +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac3200 +ac97_bus +acecad +acenic +acerhk +acer-wmi +acpi-cpufreq +acpiphp +acpiphp_ibm +acquirewdt +act2000 +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-i586 +af9013 +affs +af_key +af-rxrpc +agpgart +ah4 +ah6 +aha152x +aha152x_cs +aha1542 +aha1740 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-agp +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd64-agp +amd76x_edac +amd76xrom +amd8111e +amd-k7-agp +amd-rng +analog +ansi_cprng +anubis +aoe +apm +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arlan +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at1700 +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati-agp +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1isa +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_epp +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_aout +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpck6 +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c101 +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-isa +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cosa +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpqphp +cpu5wdt +cpufreq-nforce2 +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +cs5535_gpio +cs553x_nand +cs89x0 +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyblafb +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dca +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +depca +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +donauboe +dpt_i2o +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtc +dtl1_cs +dtlk +dummy +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e2100 +e752x_edac +e7xxx_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro +eepro100 +eeprom +eeprom_93cx6 +eexpress +efficeon-agp +efs +ehci-hcd +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +e_powersaver +eql +es3210 +esb2rom +esi-sir +esp +esp4 +esp6 +et131x +et61x251 +eth1394 +eth16i +eurotechwdt +evbug +ewrk3 +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fd_mcs +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +fuse +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +geode-aes +geode-rng +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +g_NCR5380 +g_NCR5380_mmio +gpio_keys +gpio_mouse +grip +grip_mp +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +gx-suspmod +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hostess_sv11 +hp +hp100 +hp4x +hpfs +hpilo +hp-plus +hptiop +hp-wmi +hso +htc-pasic3 +htcpen +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-isa +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i810 +i810fb +i82092 +i82365 +i82860_edac +i82875p_edac +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmlana +ibmmca +ibmpex +ibmphp +ib_mthca +ibmtr +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icn +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +in2000 +inet_lro +inexio +inftl +initio +inport +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioatdma +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lance +lanstreamer +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-net48xx +leds-pca9532 +leds-pca955x +leds-wrap +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lne390 +lockd +lock_dlm +logibm +longhaul +longrun +lp +lp486e +lpfc +lrw +ltpc +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +madgemc +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdacon +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mixcomwd +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msnd +msnd_classic +msnd_pinnacle +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +n2 +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +NCR53c406a +NCR_D700 +NCR_Q720_mod +ndiswrapper +ne +ne2 +ne2k-pci +ne3210 +neofb +net1080 +net2280 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +ni52 +ni65 +nicstar +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +nsp32 +nsp_cs +ntfs +nvidia-agp +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +ohci-hcd +old_belkin-sir +olpc_battery +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +padlock-aes +padlock-sha +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas16 +pas2 +pata_cs5535 +pata_cypress +pata_hpt37x +pata_isapnp +pata_it8213 +pata_legacy +pata_ninja32 +pata_oldpiix +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pata_winbond +pbe5 +pc110pad +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcbit +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pms +pn_pep +powermate +powernow-k6 +powernow-k7 +powernow-k8 +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +proteon +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r82600_edac +r8a66597-hcd +radeon +radeonfb +radio-aimslab +radio-aztech +radio-cadet +radio-gemtek +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-rtrack2 +radio-sf16fmi +radio-sf16fmr2 +radio-si470x +radio-terratec +radio-trust +radio-typhoon +radio-zoltrix +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-i586 +sata_mv +sata_sx4 +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc7240_wdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +scc +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +scx200 +scx200_acb +scx200_docflash +scx200_gpio +scx200_hrt +scx200_i2c +scx200_wdt +sdhci +sdhci-pci +sdio_uart +sdla +sdricoh_cs +se401 +sealevel +sedlbauer_cs +seed +seeq8005 +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sim710 +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +skisa +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc9194 +smc91c92_cs +smc-mca +smctr +smc-ultra +smc-ultra32 +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1816a +snd-ad1848 +snd-ad1889 +snd-adlib +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als100 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt2320 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmi8330 +snd-cmipci +snd-cs4231 +snd-cs4232 +snd-cs4236 +snd-cs4236-lib +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs5535audio +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dt019x +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emu8000-synth +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1688 +snd-es1688-lib +snd-es18xx +snd-es1938 +snd-es1968 +snd-es968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-gusclassic +snd-gusextreme +snd-gus-lib +snd-gusmax +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-interwave +snd-interwave-stb +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-miro +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3sa2 +snd-opl3-synth +snd-opl4-lib +snd-opl4-synth +snd-opti92x-ad1848 +snd-opti92x-cs4231 +snd-opti93x +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16 +snd-sb16-csp +snd-sb16-dsp +snd-sb8 +snd-sb8-dsp +snd-sbawe +snd-sb-common +snd-sc6000 +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-sgalaxy +snd-sis7019 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-sscape +snd-tea575x-tuner +snd-tea6330t +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-wavefront +snd-wss-lib +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sonypi +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedstep-centrino +speedstep-ich +speedstep-lib +speedstep-smi +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sworks-agp +sx +sx8 +sym53c416 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t128 +t1isa +t1pci +tc1100-wmi +tcic +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tlsup +tmdc +tms380tr +tmscsim +tmspci +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-i586 +typhoon +u132-hcd +u14-34f +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uhci-hcd +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +ultrastor +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-rng +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan +wavelan_cs +wbsd +wd +wd7000 +wdt +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wistron_btns +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xpad +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +z85230 +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +znet +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/i386/server +++ linux-2.6.28/debian/abi/2.6.28-4.9/i386/server @@ -0,0 +1,8678 @@ +EXPORT_SYMBOL arch/x86/kernel/scx200 0x254e5667 scx200_gpio_base +EXPORT_SYMBOL arch/x86/kernel/scx200 0x35a3c008 scx200_gpio_configure +EXPORT_SYMBOL arch/x86/kernel/scx200 0x8cfa375c scx200_gpio_shadow +EXPORT_SYMBOL arch/x86/kernel/scx200 0x907665bd scx200_cb_base +EXPORT_SYMBOL arch/x86/kvm/kvm 0xd666cdab kvm_cpu_has_pending_timer +EXPORT_SYMBOL arch/x86/kvm/kvm 0xf5661575 kvm_read_guest_atomic +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0x4da3fbc7 suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0xa0871b09 uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x05113120 pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0x070faa83 pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0x1413d08e pi_disconnect +EXPORT_SYMBOL drivers/block/paride/paride 0x685b957d paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0x7eb7fadc pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xb5138040 pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0xca6067c8 pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0xd059d7ea pi_read_regr +EXPORT_SYMBOL drivers/block/paride/paride 0xdd2b1d2b pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0xde833617 paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0xe4d630b2 pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xee98c12e pi_connect +EXPORT_SYMBOL drivers/char/agp/agpgart 0x08eea316 get_agp_version +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1257fb51 agp_alloc_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1b11f1f4 agp_create_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1b92ca45 agp_generic_remove_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x22341eb4 agp_put_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x2677b8a2 agp_generic_type_to_mask_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x30226ddf agp_device_command +EXPORT_SYMBOL drivers/char/agp/agpgart 0x357c71ab agp_generic_destroy_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x3825116f agp_alloc_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x3f3785aa agp_generic_alloc_user +EXPORT_SYMBOL drivers/char/agp/agpgart 0x41ccc5a3 agp_unbind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL drivers/char/agp/agpgart 0x5f1a8c1b agp_generic_alloc_pages +EXPORT_SYMBOL drivers/char/agp/agpgart 0x5fae00c5 agp_generic_alloc_page +EXPORT_SYMBOL drivers/char/agp/agpgart 0x665b6504 agp_generic_free_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0x673f815e agp_bridges +EXPORT_SYMBOL drivers/char/agp/agpgart 0x6b732e07 agp_collect_device_status +EXPORT_SYMBOL drivers/char/agp/agpgart 0x6bf19e6a agp_free_page_array +EXPORT_SYMBOL drivers/char/agp/agpgart 0x746cdc48 agp_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x7538b132 agp_off +EXPORT_SYMBOL drivers/char/agp/agpgart 0x81b6741e agp_copy_info +EXPORT_SYMBOL drivers/char/agp/agpgart 0x89593d75 agp_find_bridge +EXPORT_SYMBOL drivers/char/agp/agpgart 0x8b7c9327 agp_generic_enable +EXPORT_SYMBOL drivers/char/agp/agpgart 0x8bef2b33 agp_generic_mask_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0x901960a8 agp_generic_free_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0x971398f9 agp_free_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xa76385e7 agp_generic_create_gatt_table +EXPORT_SYMBOL drivers/char/agp/agpgart 0xaeaa7f20 agp_flush_chipset +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xb9a1d0e0 agp_backend_acquire +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL drivers/char/agp/agpgart 0xc9148d32 agp3_generic_tlbflush +EXPORT_SYMBOL drivers/char/agp/agpgart 0xcd3f7ef9 agp_generic_alloc_by_type +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd1061083 agp_allocate_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xd8dc4ec0 agp_generic_insert_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xda3ec98e agp_backend_release +EXPORT_SYMBOL drivers/char/agp/agpgart 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL drivers/char/agp/agpgart 0xdeb6e7a2 agp_bind_memory +EXPORT_SYMBOL drivers/char/agp/agpgart 0xfecb29d5 agp_bridge +EXPORT_SYMBOL drivers/char/generic_serial 0x0211c697 gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0x0f904059 gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x0fb51f0a gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0x1763a4ca gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0x22a0dbc8 gs_put_char +EXPORT_SYMBOL drivers/char/generic_serial 0x2eaea71d gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0x324ecc34 gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0x361ac6e9 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x4a617b70 gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0x69325319 gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0x705d0c61 gs_stop +EXPORT_SYMBOL drivers/char/generic_serial 0x9b8eaf56 gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0xac8dbd8b gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0xbe6a29bb gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0xe2065bc3 gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0xea456d80 gs_init_port +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x13ec7886 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x1af2acc9 ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x371e0e67 ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x3aa4227f ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x3f8cd798 ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x3f93ba3f ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x451d5046 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x5eaae6f0 ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6699500a ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x8146377d ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x88b00ec9 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x88b805e9 ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x974a5611 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xa523affa ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xac82227e ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xad93ffde ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb50ab216 ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb960f692 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc78340fb ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc7e77f68 ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd87fa3bf ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe56b98cc ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf07637cd ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/nsc_gpio 0x361dfc80 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0x5440e251 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nsc_gpio 0xc664ec68 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x0c70a920 edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0xdf3301c4 edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0xe4d4de0d edac_mc_find +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1610ec67 fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2a4b10a4 fw_run_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x307795d0 fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3277f8b0 fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3af5c788 fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3b350b7c fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0x4fa5149d fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0x758b736b fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90a5c8e4 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x9ed84e8b fw_core_remove_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb4459dcb fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0xba8e9dd5 fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0xbe8f1eab fw_cancel_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0xc681bead fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0xeda64e47 fw_send_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0xf7f94a03 fw_fill_response +EXPORT_SYMBOL drivers/gpu/drm/drm 0x032074a1 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0x06cd8c03 drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x07fedf27 drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x096d8e4a drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0df0ec65 drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0e7ec2d9 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0x11dffd3a drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x167666fa drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x16b8690c drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x187e9294 drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1f9c1733 drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x209926bd drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x31a3e686 drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0x32f16f06 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x33418c60 drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x420b262e drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x49890c03 drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x49aeeebe drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b04c780 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4bc34124 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x57e8f248 drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5ef4af6b drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5f3b74dc drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0x63703f2f drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x688a791c drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6bbc1b77 drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x754710c7 drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0x77f2f5e0 drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0x793f55e0 drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x878bbc94 drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8a1e9917 drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8ae1bb04 drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x92531e37 drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x92f65221 drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x930a5e36 drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x97b55fe9 drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9b6820e7 drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa6b829b4 drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf02e811 drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb40306db drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb993f08c drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc91d43d3 drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd09a77a4 drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd26e6ef3 drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd62bc955 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd75e7159 drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0xddafa489 drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xec355c1b drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0xecb6d86b drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0xedb149c8 drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf1d5e4a9 drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf2a7e231 drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf3e4b760 drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xffef81c4 drm_agp_unbind +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x029477b2 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0xc2cd8569 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x6cfc515b i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x855ed176 i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0x4ee21624 i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0xfc9d2de0 amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x03d91f3a hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x053f6861 hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x060714e4 hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0a67906e hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0a6dc8ea hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0b234c4e dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x11a45ff9 hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x158ac548 dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x163d2c09 hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x17a97e22 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x1c10c955 hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2752b9a8 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2c5a319a hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ebf6e5a dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x31ab94c6 hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x37a736c9 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3cbbb129 hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3d64b1f2 dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x489edfe8 hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4c47ece2 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5a7e7c27 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5fc0f6c8 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6596c3c3 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x65ce53a0 hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x66dacaa2 hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6aa98223 hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7046e886 csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x827c9e24 hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x84c30598 hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8bc65497 hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9160d865 hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x932bb406 hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x94cd7a52 hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x97793120 hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x97db9cfd hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9aafc156 hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9ca8c562 hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9d11f2f8 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9e1b78da hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xac8daa5a hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xacbcd7fa hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xade632f0 hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb114c4aa __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb287be7b hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb2ad3af7 hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb4c82bdb hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb5e59233 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc345dc65 hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc355dc06 hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc9835d56 hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcd9e772b dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd0c5f158 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd19c8b4a hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd4bb06bf hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd4d85501 hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd9e1b12a hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xddc3803e hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe378822d hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe7018578 hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe9cf57c8 hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeb456383 hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xeba30034 hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xed7d6535 hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf7fb3635 hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf96c9ed2 hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfa3c26de hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xface268a hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfae46d24 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfea76fca hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x461065d0 ohci1394_stop_context +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x918edc1c ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xc34ce828 ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x10f65233 rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x587120fc rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x9a91c6b6 rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xc26a81f9 rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x2fd799c6 ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x312871c9 ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x34080852 ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x447c53e0 ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4ecf4aa6 cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4fd75f6e ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x602677ec ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x6c16cac4 ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x7429077c ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x76debe48 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x7ad59944 ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xb45207ed ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xbd9ccb22 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd522f785 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd53c76b6 ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xe76fcab3 ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xf15b39c6 ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0422e6b4 ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x04230dcc ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0b481fde ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0ea234ff ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2672c71f ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x28af0a39 ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2c955610 ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x340aa3a3 ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3624f8e3 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x36ff9dbb ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x392db943 ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x393095d1 ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3a5dad5f ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3efa6499 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x401a8d54 ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x43ae59ab ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x478a55b5 ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x487690fa ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x520b2638 ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5423113a ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x549a5906 ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5898a6cb ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5b4bbcb1 ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x5c1a0d8f ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x62d1fe64 ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x647438af ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x64a9ae76 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x65e3f821 ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6782e508 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x679d835c ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7031af57 ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7b814a65 ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x84417dd4 ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x856b108f ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x88889f74 ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8b2e708f ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x960a0968 ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9678f58b ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96b0c89e ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x97bde09a ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9ca0354b ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa0f15e74 ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa1171a58 ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa255e5d8 ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa500ed92 ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa9a26c4c ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1a312e1 ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb26c1194 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb367887b ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb54dbb02 ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb879e87a ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb9f6840a ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbc77dbee ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbd30f2e5 ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc0619e38 ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc16208a9 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd2ea6b21 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd451b17b ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd89752a0 ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdb1c642e ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdd1ef044 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe1374ea7 ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe24ff95f ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe435f758 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe6d33ad3 ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xe7d7f901 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xee601453 ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfa5f343f ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x05cffb54 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x1cd5fd58 ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x274aa892 ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x278074ab ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6faf079f ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x82710b38 ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x8827e03e ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x9564d954 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xa3914e53 ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xd74e8eb7 ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xdf9387d3 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xf1586366 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x522f2229 ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x732ae351 ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x93e17792 ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xc2071fc5 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xcd3e5e9b ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf58fe770 ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xf5e7c693 ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x2324cffa iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x34b6a324 iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x3ef314b9 iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x6ea0cc8b iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x9f5b1c9a iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xd34c665a iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xed82326c iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xf4d35cb4 iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x189099ed rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x2b54f7bf rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x2d63751b rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x395bda67 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x553b8bc6 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x56a2ca29 rdma_resolve_route +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x5ba45bf1 rdma_create_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x66827b83 rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x6cc58752 rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x8f64ef4c rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x924064b4 rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x94412c3c rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x9728cde6 rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xb4cec7b7 rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd0b04d4f rdma_leave_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd4ee651b rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xdcf18938 rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xee9056a6 rdma_listen +EXPORT_SYMBOL drivers/input/gameport/gameport 0x1d3b9f4d gameport_unregister_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0x294da779 gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x2debf3a5 gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x4fa0df2e gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0x683d2eaa gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x906edddd gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0x95f4441a __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xf1cc0834 gameport_stop_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0xfe4b052b __gameport_register_driver +EXPORT_SYMBOL drivers/input/input-polldev 0x78b9a27b input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x9d02cda2 input_free_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xd2c4eeec input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xe9824372 input_allocate_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x5e3bcd9e capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x5fc5af5d capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8e422e7f capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9895ff08 capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9cb0eee5 attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa7c4fd6c capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xac67f4e1 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xae68d8b2 capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xbc795c59 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc10fe128 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc6dc42b6 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xccda278c capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe8ad9bd1 capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xfad5ab53 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x25881a90 b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x30a9d058 b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x31a27aaa b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x32437167 b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x3ce18e0c b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x625f4516 b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x9614530e avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x967ec311 b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xa8c08835 b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xb99d6981 b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xc00cce15 b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xc3532d61 b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd88f6e11 b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xe0474cef avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xf3f85925 b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x152e3d40 b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x224f9225 b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x26141cf5 b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x5b649157 b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x5e5a6f7c b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x7bd82259 t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xcc87f42f b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xd6ef1921 b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xff252a41 b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x3ecbfaf2 proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x7fefbfa1 hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x0ac52835 isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x369cf534 isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x5530619c isac_init +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x58545245 isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x645b6dbb isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x18d79f56 isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x3fc91e68 register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xcbd5945c isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3257e1a0 recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x37b215e4 confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3a0cf2f6 bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3bd96fbd mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3f889c1a queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x4d1bec71 create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x544f8404 get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x635fe451 dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa9764d2a mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xad54352d mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb067138d recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb254f867 mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb99c6817 get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc2229ee8 recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xcce63132 recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xcdfba7df mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd4a28f71 mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd8b9907b mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xdfbf2e00 l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xe4a0e933 mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0x580a223e mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0x0e03c3c6 mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0x4cf87763 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0x8db551e7 mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0xf90be403 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0x69c283c3 xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0xc422274e xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1eabe89c flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x251283f1 flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x251f5d38 flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3ac88119 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x4a6eb1be flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x55fa46d5 flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x61c0367a flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x676a290d flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x7a20c475 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x83c69944 flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x8c2a793f flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x8daaea5c flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x9546d6ed flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x99955692 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x9e30af38 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x9fb18222 flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xbf0bd07c flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc6dee160 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd4406ff3 flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x0ff429cb bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x1fea4532 bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x79feaf80 bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xa800f4c3 bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x18903040 dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x3b8b0b11 dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x4fe73847 write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x70cfdf7f dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x7a740d20 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x9478449a read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xd3044bcc rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xdbca647c dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xde0c75e5 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0x7d8c6644 dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x14eb630c dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x16a31859 dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x2366e181 dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4a303f29 dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x635eb40e dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f7f7d73 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6f9c72e3 dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x72f200dc dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80328dbf dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x81f37885 dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x830c467d dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x880d5e53 dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8f97193e dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x923aa88e dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x9cbff999 dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xa87c2159 dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xa9520d43 dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xaf413ba4 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb2db2592 dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb56f0404 dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb5b95805 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb6e5f15d dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xbed559e1 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc938e566 dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xca4575ef dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcdecf6e2 dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xdc91b67d dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe643377b dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe7949e59 dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xeb7daf80 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf03e0ef2 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf2e131f3 dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf728ed4d dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x1e0db4dc dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x62ad06d1 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x6a3508d5 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xaf5cf4c5 dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xce5cdcbe dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xe23fc939 usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xea1c8117 dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xdb61cb5a af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x058650f5 dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x301a97e4 dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x3668ea79 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x60fcc47c dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x67aeab7d dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x7c02119b dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x84b1650c dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x946327da dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x9c46abc6 dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd9fa22e0 dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xee54a28b dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0x0b900b86 af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0x08c2e914 au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0x3e409095 bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0xa0437e9a cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0xf3f08486 cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0xf1e31aa5 cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0x9cd15f20 cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xb6da3f92 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0xe4c3b342 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x951a9e92 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xcf2cb597 dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0x8647cf2b dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x2420861e dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x44b7deba dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x5138ce80 dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x514927a2 dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x57905a09 dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x5f4098d5 dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x7ec5ef38 dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0xc294a7ad dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x4cc94a7b dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x5601233e dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x71204f1e dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x75bd7724 dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x9899c633 dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xf7beb0ad dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x64ffe89e dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xb463ce6a dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xca37a3a1 dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0xbd1b6776 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x79105227 dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0xd35fefaa isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0xb6b2a893 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0x839f4e20 itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0xa3987519 l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0xc257d5d4 lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0xc1be0af1 lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0xa0727ece lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0x1d506e29 mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0x379bac9a mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0x5c5773c8 nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0x92dddc06 nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0x5893b1f9 or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0xd3ea28a3 or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0x8128747f s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0xcaa8d9b6 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x026114ec s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0xd786d7d8 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x0f1d1c1b si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0x296c8826 sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x96dee6b0 sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0xeccc4c2d stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x7cf74273 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x7296de04 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0x5ddd8a84 stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0x531b1b97 tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x2cc334db tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0xcb404a3d tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x044fdaa9 tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x230e6359 tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0xe9e0d602 tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0x9f73f674 tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0x6c552e88 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0xf7bf9710 tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x277f6a0d ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0x7ffdfa37 ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x8df59810 zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0x7cf0235e ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0x1f3e9f41 ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0x34f99e8b ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x05af4fd9 bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x7cb23f1a bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x82724921 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x8cc3c07b btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc881ecda btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/cpia 0x242819cc cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cpia 0x49d93d6c cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0x6645260a vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xb2ab666b vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x2832ff18 cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x35930706 cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x37441cc4 cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x3f085b9b cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x83a26f73 cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xc3cfdef6 cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x021d2650 cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x220ac2c3 cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x68e38ee0 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x80bf6d02 cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xa5b1cdad cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xd952c69f cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xd9604635 cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x0c58f4c5 cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x0c64b350 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x20e758a0 cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x2789dd8d cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x2a89c3e0 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3af425b3 cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x50320c5e cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x568d4b52 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x5b69af5b cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6372eb4c cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6b0f25fd cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x747ad9d2 cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x85937f7d cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b1bbdd9 cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xaad7a433 cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xae2f4bd3 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xbd241733 cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xbef6a067 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xce5440de cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd38b840b cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd6c8b33b cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xea19b202 cx88_shutdown +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x3e73ef6c em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0xfa30f7da em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x25485b25 gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x27418913 gspca_disconnect +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x29476331 gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x30dde711 gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x318bd72d gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xa019ceed gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xc4cf2cef gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4e57b7a1 ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x5f3a4a7d ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x88699851 ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x8fae30bf ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x9034f33d ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x978e2731 ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa394bc8c ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xc886ad35 ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xd53908c6 ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xdc305ec3 ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xe664500b ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xf002aee2 ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xfc7a07f3 ivtv_api +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x2b978c44 saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x2f8ee718 saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x35cde2f7 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x581407ca saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x5d453205 saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x5fd4592e saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x62002115 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x67b70b58 saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x6e0bc85c saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x79e59a4b saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x92ec5cef saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x9ff0a6a2 saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x2888514a soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0x2b62d0f7 soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0xc1a4b779 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0xc36e8ac9 soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0xd523f49e soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0xeb890805 soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/tveeprom 0x539af753 tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0x75195a5b tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x02ae85e6 usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x086235c2 usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x2f85e187 usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x8617a725 usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xb044dbfd usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xd57b131b usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0x19eda8e3 v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x06f4b9b0 v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x087e4b7f v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x10544d96 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x003169b6 videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x78d9a41e videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x850f55d6 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xbea4b70e videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xddb3794b videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xe9045d6f videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x23735152 video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0x38fa15e1 video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x60871c86 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0x78950acb video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0x8c487a7c video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xa762bf25 video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0xa81efb6e video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0xb3dc6708 video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0xbd5eb14d video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0xcb059924 video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5d940430 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x6068f54e videocodec_detach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xd4f479d5 videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xec014351 videocodec_unregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0f671dfb mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x105d4f47 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x14a0100e mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x2155e5f8 mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x257d85f3 mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x30b1371e mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4db501f2 mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4e8930f8 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x51cd7f00 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x570210fa mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x598a81a1 mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x641bc564 mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6abfc94c mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x74482520 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x769ed0fe mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7cfb87f4 mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x946a4ad0 mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x99a897d5 mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xa37e0535 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xa5daece9 mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47cd0ad mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdc039912 mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xe69e2a36 mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xf4c3552e mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x03ff299e mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x1684df4b mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x35ed9d4f mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x4101ba74 mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x4e91198c mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x69a683ae mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x6ad3fa90 mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x82acbd8e mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x8a27fc1d mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x92644cc9 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x9323bc81 mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x96647c1c mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x9bd1b4fb mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x9c4f0450 mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xa6ca761b mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xab4d7e11 mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xabd01b04 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xb1b0a1c8 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xb8b79262 mptscsih_shutdown +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xdd8aeb27 mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xe3ea072b mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xee36ffa6 mptscsih_suspend +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xef06f783 mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xf0c6ba85 mptscsih_io_done +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x06246184 i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x16fa28ec i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x349d5099 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x3b1f5e6d i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x3e6bb392 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x45c9bb03 i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x4afa2a47 i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x672a04e9 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x68aa2ce5 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x6bc259ef i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x6f72def9 i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x996d96a7 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xa662eb92 i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb6806aa1 i2o_parm_issue +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb6decc2e i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xba232d88 i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd404da41 i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xdb5bcbc3 i2o_device_claim +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x131fe480 pasic3_read_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x7018d91c pasic3_write_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x3fb67248 c2port_device_register +EXPORT_SYMBOL drivers/misc/c2port/core 0xd17707a0 c2port_device_unregister +EXPORT_SYMBOL drivers/misc/ioc4 0xc92e3aa7 ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0xf74dcc17 ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x0558cb05 tifm_unmap_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x381671aa tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x39f86aa1 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0x427af69d tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x4d805b14 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x5c4db833 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x65bcef4b tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0x6d8a6054 tifm_register_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x6e4774f4 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0x948bce2f tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0xbfd1602d tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xd0cc8d52 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0xe817cb6a tifm_add_adapter +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x020e9b94 mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x47041087 cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x5f751beb cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x80506ac1 cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x05df204e unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x33ea9711 register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x9f65ba4e do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xbc4fa889 map_destroy +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0x1917e370 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0xc5e32a35 simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x6eacd476 del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0x911b5afb add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x57e70e90 mtd_concat_create +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x82beeb63 mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/nand/nand 0x874bf508 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xd9cac8bc nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x28cfbfd7 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x422fdb02 nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xae914bd9 onenand_scan_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xf5a8fa24 onenand_default_bbt +EXPORT_SYMBOL drivers/net/8390 0x15f365b0 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/8390 0x19f78e40 ei_open +EXPORT_SYMBOL drivers/net/8390 0x303ae255 NS8390_init +EXPORT_SYMBOL drivers/net/8390 0x45fe6134 ei_poll +EXPORT_SYMBOL drivers/net/8390 0x55c60b18 ei_close +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390p 0x083bb1ca __alloc_eip_netdev +EXPORT_SYMBOL drivers/net/8390p 0x34257cd0 NS8390p_init +EXPORT_SYMBOL drivers/net/8390p 0x7c8ba282 eip_close +EXPORT_SYMBOL drivers/net/8390p 0x841bc69f eip_interrupt +EXPORT_SYMBOL drivers/net/8390p 0x8d978c39 eip_open +EXPORT_SYMBOL drivers/net/8390p 0xd5ec1084 eip_poll +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x0039b993 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x0864c39e arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x1be5ae07 arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x5657d696 arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x83f8cf5e alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0xcf108ad4 arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/com20020 0x86dd4d1d com20020_found +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xc8bbd711 com20020_check +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x0f54e195 cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x13ca8389 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x1766c06c t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x52fd4a7b cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x5c987c10 cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6a9455a2 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x71cbd3e2 dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x76e44a21 cxgb3_free_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x885dfe82 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8d30494e cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa206420c cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa630ab88 t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa7023725 t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xb9ef1f7d cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xbd971ca8 cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xc9188f37 cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x10e3a47b hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x4b4e92d3 hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xa0c3b1f0 hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xd3e57ef4 hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xf683038f hdlcdrv_register +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2a32b701 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x2abb945f sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x3e339401 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x560fcd0f sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x869e6099 sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xa2a11b4d sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xb7de42b2 irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xd041e99e sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xd06149a6 sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xef0d55eb sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/mii 0x04e8fbfe mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0x525785e8 generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0x83fa575f mii_link_ok +EXPORT_SYMBOL drivers/net/mii 0x8a9e906f mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0x9f4ebb61 mii_nway_restart +EXPORT_SYMBOL drivers/net/mii 0xbc372f8c mii_check_media +EXPORT_SYMBOL drivers/net/mii 0xbd548797 mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0xcd39d366 mii_check_link +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x45fec05b free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xf2940737 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x7f81929d pppox_unbind_sock +EXPORT_SYMBOL drivers/net/pppox 0x87fce740 register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xe0c7710b pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/sungem_phy 0x0ddb238a mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x47ee6e80 tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x59e6025f tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x8fe5f18b tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xc86d64c7 tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x03024432 detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x2dd3e9a3 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/hdlc 0x46f6b751 alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/hdlc 0x64e1de5b hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0xb2627f21 hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0xb60f41ff attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xde46a463 unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xf5f2362c unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0xf79735c0 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/syncppp 0x12e0e713 sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0x5791fd7f sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x6ec12554 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/syncppp 0x8dd4faae sppp_open +EXPORT_SYMBOL drivers/net/wan/syncppp 0xc716efc5 sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0xe762555a sppp_attach +EXPORT_SYMBOL drivers/net/wan/z85230 0x10c78988 z8530_dead_port +EXPORT_SYMBOL drivers/net/wan/z85230 0x20a1c6fd z8530_sync_open +EXPORT_SYMBOL drivers/net/wan/z85230 0x20c14417 z8530_sync_txdma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0x283e799e z8530_interrupt +EXPORT_SYMBOL drivers/net/wan/z85230 0x2d91cdca z8530_dma_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x4258851f z8530_nop +EXPORT_SYMBOL drivers/net/wan/z85230 0x44c853f9 z8530_sync +EXPORT_SYMBOL drivers/net/wan/z85230 0x5cd24d29 z8530_hdlc_kilostream +EXPORT_SYMBOL drivers/net/wan/z85230 0x65861135 z8530_describe +EXPORT_SYMBOL drivers/net/wan/z85230 0xa34db32a z8530_init +EXPORT_SYMBOL drivers/net/wan/z85230 0xac237643 z8530_sync_dma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0xc3d8956d z8530_shutdown +EXPORT_SYMBOL drivers/net/wan/z85230 0xc5dd5519 z8530_sync_close +EXPORT_SYMBOL drivers/net/wan/z85230 0xd7bef2d0 z8530_channel_load +EXPORT_SYMBOL drivers/net/wan/z85230 0xe3d80064 z8530_hdlc_kilostream_85230 +EXPORT_SYMBOL drivers/net/wan/z85230 0xe90ec530 z8530_sync_txdma_open +EXPORT_SYMBOL drivers/net/wan/z85230 0xe9884922 z8530_sync_dma_close +EXPORT_SYMBOL drivers/net/wan/z85230 0xefd805e1 z8530_null_rx +EXPORT_SYMBOL drivers/net/wan/z85230 0xf1d776e6 z8530_queue_xmit +EXPORT_SYMBOL drivers/net/wan/z85230 0xfecd16ed z8530_txdma_sync +EXPORT_SYMBOL drivers/net/wireless/airo 0x57d4c77d stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0x59a73ef4 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xcabb3f16 reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x6317ac53 atmel_open +EXPORT_SYMBOL drivers/net/wireless/atmel 0x6fd21c5a stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0xc303ca05 init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeeef9f73 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x006e5754 hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0ad69602 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x176b91ba hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1f5728a6 hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x27d1e1b6 hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x2dbb40cd hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3dede659 hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x46bcf4b9 hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6008dae9 prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x61fa4fe2 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6985d0f0 hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x78f110af hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x79a248b8 hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x83d35868 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8b93581e hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8fc8a800 hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x925d46f2 hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x97657250 hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x99da598f hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa4532047 hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbe517642 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xbf98c4bb hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xd5551c4e hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xdf359ac5 hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xdfa9f129 hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf5a1ea34 hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xfe1bbaa0 hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x03eaff2f iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x05785edc iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0774f47c iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0841c1cb iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0d871228 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x10d068cf iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x118ac045 iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x12bd4eb1 iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x13cac5e0 iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1b88966f iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1bc1ff34 iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1c9cfe34 iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x21ca618a iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x24017a03 iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2600d0a8 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2c071cf8 iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2dd14f05 iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2e137ccc iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2f3defea iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2ff15604 iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3008104d iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x35023946 iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x38886e37 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3bc0c90f iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3cea52c2 iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4295fdb4 iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x45c38834 iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x480366b8 iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4940c57e iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4a6401f3 iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4a971ca6 iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x541690f9 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5b128079 iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5bfde863 iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5c4e6439 iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5cab864f iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5fb5b0a1 iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x60774702 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x62727d56 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x62d2ff9a iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x653b4710 iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x66983dab iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6732b2d8 iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x693f12b4 iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6de30bb3 iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6e128cc3 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x702e8eeb iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x73f9a081 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x74ea65a6 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x74fc2ace iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x78589f1d iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7b1771c7 iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7dcf8255 iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7f72ac17 iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x809f3f42 iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8260634d iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x831efd97 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x924360ce iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9680b830 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x97c794fe iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9cb5f6a7 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9fc0be6e iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa02ae165 iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa393b25f iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa4a571ee iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa4f70d66 iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa8a3c411 iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa95b1d02 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb04c86d2 iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb057a07e iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb19dd9c2 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb1e64c59 iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb54393ed iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb5545063 iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb945e2bd iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb9a5a829 iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbcfdb3e5 iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xbefc09e4 iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc208298a iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc20ec6a0 iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc4e40c79 iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc782c866 iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcb7b8706 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcc89aa77 iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd0356d44 iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd08f9097 iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd231324e iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xda709db9 iwl_rx_allocate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdba329f6 iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdf0d8e97 iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdf2775ff iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdf3046d0 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe14526b1 iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe1d40437 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe1ec850b iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe3218685 iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe32b0110 iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xedaf2f29 iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xee23db76 iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xefc7d875 iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf25c567b iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf3d635f3 iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xf91a8864 iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfc557423 iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x668416f4 free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xa57ae184 __orinoco_up +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xb91f74fc alloc_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xbc933479 orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xcb2e31c4 __orinoco_down +EXPORT_SYMBOL drivers/parport/parport 0x00be33cd parport_negotiate +EXPORT_SYMBOL drivers/parport/parport 0x01d0405d parport_write +EXPORT_SYMBOL drivers/parport/parport 0x036b31a7 parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0x05077c8d parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0x064cae2b parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x0c33c3ae parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0x0d330aba parport_release +EXPORT_SYMBOL drivers/parport/parport 0x161c0578 parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x209d36da parport_read +EXPORT_SYMBOL drivers/parport/parport 0x37587109 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x378d4a3e parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0x3db7244c parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0x3de3c131 parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x3df44ed5 parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0x48f393f4 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x52e1641f parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0x583a3373 parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0x586cdcbf parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0x6edc66d3 parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0x77b71af4 parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0x8f0b4efa parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0x9873af45 parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0x9dd47dd1 parport_claim +EXPORT_SYMBOL drivers/parport/parport 0xa0241639 parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0xb11d042f parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xb123ace8 parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xdf07f550 parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0xe3cf9242 parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0xf4f83119 parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0xfbc983ba parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport_pc 0x6893a266 parport_pc_probe_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xf281446a parport_pc_unregister_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x03fd3aea pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x1883547f pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4a4adaa6 pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x619a59fd pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xae9cfdbe pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb45c8e61 pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xcc7e2675 pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xd1b7e418 pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xe5febfc8 pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xedabbc60 pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0fea414 pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf5875087 pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf945c50f pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xfbb8bc55 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xfc35f6b8 pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x018dd228 pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x09f41fab pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x12382a2d pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x309c92e5 pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x392047a9 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x43b165c3 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x460cfc6a pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4c910eba destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x6b48a8ce pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7a4a6322 pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7e15413a pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7f755bce pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x82c56b0b pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8a8d2c31 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8e81f322 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8fdae17b pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x91a3908e pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x9ca98812 release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa55a6b03 pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xaf0a8b90 pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xaf749168 pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xbcc50b1d pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc368f687 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd523d104 pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd5e3b9cf pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd8a26dfd pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe29ee099 pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe6a43ee8 pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xea23253f pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xee419908 pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xffd36e45 pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0x55d99c8c pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/53c700 0x2295b630 NCR_700_release +EXPORT_SYMBOL drivers/scsi/53c700 0x5175c0f0 NCR_700_intr +EXPORT_SYMBOL drivers/scsi/53c700 0x9232103c NCR_700_detect +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x8099f574 mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x0a3f0ac5 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x1ba8dfa3 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x6436b160 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x9a61094d qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xce50b9b7 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xd1f18683 qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/raid_class 0x1627a32e raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0x379849ec raid_class_release +EXPORT_SYMBOL drivers/scsi/raid_class 0xffd205a0 raid_component_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x0e9eea5e fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x1d447560 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x272c2b32 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x29dc50d7 fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x3d060223 fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x4ffeb78a fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x5c786bd3 scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x66da8760 scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x73c86365 fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x890a76a7 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xde1d7fd0 fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xfb7eae45 fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x07aa8066 sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x13e977d5 scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x23fae0cb sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2ac47a23 sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x2cf19ced scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x42667c64 sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x483fd126 sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4fd37f2d sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x64b35ab7 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x681b8988 sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x69e35351 sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x8044c435 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x8663daeb sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa328425e scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xa7ad4d34 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xad4bd6c0 sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb031512d sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb46867de sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb84d77d7 sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc10e056f sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc74c3d6f sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xdb692e21 sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe3fd6922 sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xe765aa33 sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf232b907 sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf2566614 sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x0823c1f6 spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x096762ac spi_display_xfer_agreement +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3cf9c4ce spi_schedule_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x40ee162b spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x87cf4c8f spi_release_transport +EXPORT_SYMBOL drivers/ssb/ssb 0x0f324869 ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0x220b6265 ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0x301240c1 ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x31094d24 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0x39071ba2 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0x56703dac ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0x5e0eeb8a ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x5e9f1dae ssb_set_devtypedata +EXPORT_SYMBOL drivers/ssb/ssb 0x628661f3 ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0x7da260d6 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0x91cbd47e ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0xa0198320 ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xa426fbdc ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xaf58cc15 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xc3a94689 ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0xd3005046 ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xf148a290 ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0xfa1dbdc7 ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0xfa58ae1e ssb_device_is_enabled +EXPORT_SYMBOL drivers/telephony/ixj 0xc29758c1 ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x4fa618a3 phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0xe7ae592d phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x9aaa102c net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/gadget/net2280 0xaa2ef2d7 usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/net2280 0xba25d701 usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0xc09ccf5f sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x8be7227b lcd_device_unregister +EXPORT_SYMBOL drivers/video/backlight/lcd 0xb27a499e lcd_device_register +EXPORT_SYMBOL drivers/video/console/bitblit 0x733ea085 fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0xcbdb39da soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0xf63c3308 fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x85da8112 cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0x924d7b4c cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/cyber2000fb 0xe710ea16 cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0xefc92d77 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/display/display 0x4473724a display_device_register +EXPORT_SYMBOL drivers/video/display/display 0x6f2fbadc display_device_unregister +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0xab8a09fe mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x6b9d61fb matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x92c93236 matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x9ad4986c g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x1d2baee7 matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x1d6bcee9 DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x3668d0e4 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x4c99c295 matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0x738dd8ae matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0xf74a2e16 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x5fbd109d matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xa034525c matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xfa452f70 matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xfac96ef6 matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x253d33db matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x5f2a6bcc matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x1abaf1f8 matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x7cb705e0 matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xa23007ff matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xaf470d85 matroxfb_read_pins +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xf4b3f053 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/output 0x19b4508a video_output_register +EXPORT_SYMBOL drivers/video/output 0x2d8502e2 video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x201a6889 svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0x39537104 svga_tilefill +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x76ff81d3 svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x87d6bd60 svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xb3ecdbbb svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0xd51c20a0 svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xee5e99ac svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/syscopyarea 0x0988e6da sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0xef873ad2 sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0x70e29942 sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x0ef147f8 w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x30766848 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x0c58777b w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xed26f24f w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x0bc38e74 w1_unregister_family +EXPORT_SYMBOL drivers/w1/wire 0xb0467b04 w1_register_family +EXPORT_SYMBOL drivers/w1/wire 0xb8ad4328 w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0xda395554 w1_remove_master_device +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x1bdb8ab5 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x22cfa18a configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0x26a95739 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0x6d1cd965 config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x7dd0c5f8 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0xa0c47823 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xa4d156a8 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xc1344cb1 config_group_init +EXPORT_SYMBOL fs/configfs/configfs 0xe0969648 config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xe65b1fab configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xececabf9 configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0xf04aa220 config_group_find_item +EXPORT_SYMBOL fs/lockd/lockd 0x729487ed nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x1c8e4ef8 nfsacl_encode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0xc2c032e6 nfsacl_decode +EXPORT_SYMBOL fs/nfsd/nfsd 0x0f3e6e01 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x2095976a nfs4_acl_new +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x7ee78c79 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/xfs/xfs 0x3cb9a1f5 xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x3771b461 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc-itu-t 0xf5b4a948 crc_itu_t +EXPORT_SYMBOL lib/crc7 0xa7587646 crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x2329b292 crc32c_be +EXPORT_SYMBOL lib/libcrc32c 0x37d0b921 crc32c_le +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0x4eb12573 make_8023_client +EXPORT_SYMBOL net/802/p8023 0xdeb5cc62 destroy_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x0e976f74 p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x1142352a p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x11b1ea33 p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0x17dc20ef v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x1ebfe801 p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0x222227ce p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x3455711e p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0x388f8a21 p9_client_walk +EXPORT_SYMBOL net/9p/9pnet 0x3a17f9f8 p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x6b754e6f p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x80977b58 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0x809c54c2 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0x84c0fa99 p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0x8c2cf0e3 v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0x9992e841 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0xaab8671a p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0xae940b15 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0xaf8aa3ea p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0xc8906c79 p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0xcae61af3 p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0xd0cd0ce9 v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0xd0faf92e p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0xd331fc1d p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0xd87762bd p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0xdf002840 p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/9p/9pnet 0xeb4fd77e p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0xef7127b0 p9_idpool_put +EXPORT_SYMBOL net/9p/9pnet 0xf8f26a13 p9_client_disconnect +EXPORT_SYMBOL net/appletalk/appletalk 0x03087bb9 alloc_ltalkdev +EXPORT_SYMBOL net/appletalk/appletalk 0x2ff66579 atrtr_get_dev +EXPORT_SYMBOL net/appletalk/appletalk 0x608371fa aarp_send_ddp +EXPORT_SYMBOL net/appletalk/appletalk 0xa33bc84a atalk_find_dev_addr +EXPORT_SYMBOL net/ax25/ax25 0x0083b848 ax25_send_frame +EXPORT_SYMBOL net/ax25/ax25 0x041813f8 ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x34f29719 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x49ab5314 ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0xbd619047 ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xce08133d ax25_linkfail_release +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/ax25/ax25 0xf5533311 ax25_rebuild_header +EXPORT_SYMBOL net/ax25/ax25 0xf805143e ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0xf96d304f ax25_listen_register +EXPORT_SYMBOL net/ax25/ax25 0xfb7a6860 ax25_find_cb +EXPORT_SYMBOL net/bridge/bridge 0x1abd774a br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x2f405ef8 ebt_do_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x4aad1ede ebt_register_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xca76e8a5 ebt_unregister_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x07bf790e ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0x09c40df4 ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x0af97c7f ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x2c11cb24 ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211 0x33221ecd ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0x4c508b0f ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0x628a0c61 free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x6a3e6b41 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x78f1b83e ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0x80677db3 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x8c304e6c ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x8f09bbb7 ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x997ca571 ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211 0x9ff43aac ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xb00eee09 ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xd153a815 ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe1e5539f alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0xe52ea084 ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x15761bbd ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x1e8eef27 ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x20b6a6c3 ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xa96a80e0 ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xcc871316 ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0xe62c9721 ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ipv4/inet_lro 0x019ab49f lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0x7748aa3c lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0x7b29b11c lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xb5f050bf lro_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xd2136be2 lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xfdc8f1e3 lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x06a3732e arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x49d3df65 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0xfb33d48c arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x173f1a8f ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x7d8db56b ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xc5576e11 ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x8bfe3214 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x9796491b nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xbae5c891 nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xe3ac36b3 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xe8962782 nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/tunnel4 0x623b07b3 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0xf2a7a596 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x0a675265 ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x6fcd4874 ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb641c0d4 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xcb6d72e3 ip6t_do_table +EXPORT_SYMBOL net/ipv6/tunnel6 0xb4e0fd72 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0xf85ab0db xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x43f3bc5e ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4c57c681 ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x508498f5 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x72e7de46 ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x94fd1be1 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xbe668683 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xee74c779 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xfd3e387d ircomm_connect_request +EXPORT_SYMBOL net/irda/irda 0x016859db irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x1b40a867 irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0x1dcf1bde irttp_data_request +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x248ca7b3 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x3cd00bcd iriap_close +EXPORT_SYMBOL net/irda/irda 0x3ea78c15 alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x48080ff5 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0x4c51285b irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0x5218b522 irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0x6448d2d0 irlap_close +EXPORT_SYMBOL net/irda/irda 0x6496fcff iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6b88bb64 iriap_open +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x727d1cad async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x8b24b9db irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x8e22b515 async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9b5c0e04 irlap_open +EXPORT_SYMBOL net/irda/irda 0xb2428e4c irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0xb75ff418 irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0xb7dcf769 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xd08a7aa2 irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0xd3a3a766 irttp_dup +EXPORT_SYMBOL net/irda/irda 0xd3f89b8b irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0xd6deeaae irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe414a62e proc_irda +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xe78e1bb0 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf84b4457 irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xf864ed3f irlmp_close_lsap +EXPORT_SYMBOL net/lapb/lapb 0x1c824305 lapb_register +EXPORT_SYMBOL net/lapb/lapb 0x3657e401 lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0x49a93aba lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0x81bc100b lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0xa48f85d6 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0xb7dc50ad lapb_data_received +EXPORT_SYMBOL net/lapb/lapb 0xbf13537b lapb_data_request +EXPORT_SYMBOL net/lapb/lapb 0xf40309fa lapb_setparms +EXPORT_SYMBOL net/mac80211/mac80211 0x0154a805 __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x04a6bfdf ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x0983875e ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x09cc8986 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x0d58134a ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0x13eef138 ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x14088ba2 ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x16bb2340 ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x1d6ec9aa ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x1dacf27b wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x2905eca3 ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x2c646a71 ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x2d2359d1 ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x372911ee ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x39f3b230 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x3a725691 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x4a2ec51d __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x4e8dc4bc ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x5027d6d5 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x54e92fdb ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x77ceec72 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x7d377aa2 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x865576cd ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x8b06d930 ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x9829c1ed ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x9d68febe ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x9d7afc4c ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0xa2a74d8b ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0xa2f39461 __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xb49b9b5e ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xda8ecb66 ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xe6a5da07 ieee80211_rts_get +EXPORT_SYMBOL net/mac80211/mac80211 0xec55a5d3 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0xef3bfd1c ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xf0ebe2e6 ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0xf671da82 __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xfbba20ae ieee80211_ctstoself_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x01506c94 register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x132de27e ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x22090cb4 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x51505459 ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x54aac469 unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x674f661e register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x7053bd5f ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x82a6f6b2 register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x9445afa0 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xf7a8dd3f ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xfcac25d2 ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0xeebffb3c nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x1279a674 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x271d0f35 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x32c25e3e xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x488d6b7f xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0x94f6b3ae xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xb12fe94e xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xd2abc70d xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0xda0fc96a xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xe4c77ddd xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf56c1b11 xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/phonet/phonet 0x32ceee40 phonet_proto_unregister +EXPORT_SYMBOL net/phonet/phonet 0x5b059305 pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x75fd8179 pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xdd3f62a7 phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0xde94e7ec phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0xec59901a phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0xed98281f pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0xf3d9d801 pn_sock_unhash +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x103b878c rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1da09f8b rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x240e7910 rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x46b66c7e rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x5a87dfd6 rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x5d6fd3bc rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x6393958d rxrpc_kernel_begin_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x67fd6b77 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x685b91a1 rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x6920a0d9 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x80ce98d6 rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x9dc027a4 rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xbf659992 key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xc8e1120f rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xca31235a rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x1356ca22 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x1ddb1fa8 gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x28338faa gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x3a1ecd32 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x632d94d7 gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x97830d7f svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xc19773a2 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xd417ec65 gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xe97a5105 gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xec96ac13 gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x03c034de svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0780cfdf auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0e4ece1b svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x13e34abb xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x190765e6 svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0x21078bd5 xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x254daea0 xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2cfacafe xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2d5fb86a rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x3380ce7b xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x33e69250 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x423e08a7 svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0x442b5506 xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x44965a4f unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x47db5619 xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4b1800ff auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0x52ab9dd2 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x583ebca6 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5a10416a xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0x61e85225 cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x646aa71e auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x66ed8e9b svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6cc59dd0 svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6f36d3a7 svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7068397a auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x7b932ccc svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8270676d cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8628fe28 read_bytes_from_xdr_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8898c2a1 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x892617b2 xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8aee3dca xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x8e534fa3 svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x953b47c1 xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa2aeb2c2 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc0b14c26 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc7027671 sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xccfad339 rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0xce378e9e xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0xcf3522b6 svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd03df116 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd63df897 xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd68a136e svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdb7dfe8c xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdc6487bf rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0xdd99d23d svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0xde47ac2e xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5726953 xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe640790b xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe7a21866 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe81b8e90 cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xeeffd264 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf877a961 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfdc8c870 cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0xffc76e65 svc_set_client +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x0ef9d47d tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x111cbedd tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0x130212e5 tipc_createport_raw +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x27d8bb58 tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x28424cd2 tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4ba3cfc8 tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x59d43d86 tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x64357d3c tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x8001e3d7 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x9b5b43b1 tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa746e206 tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb01ffc2c tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xbb2b2504 tipc_send +EXPORT_SYMBOL net/tipc/tipc 0xca4fb0b9 tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xd8cf9d62 tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe0c5b1e5 tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0xe622c86f tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0x19e36a1c register_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x4afc6152 wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0x54d5bd57 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0x6727e7ad __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0xa9c29817 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xd24f6f34 wiphy_register +EXPORT_SYMBOL net/wireless/cfg80211 0xf5846600 regulatory_hint +EXPORT_SYMBOL sound/ac97_bus 0xfb83558c ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0x5d6e66d7 snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1b4e1d33 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x39dd848c snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x43c6fef2 snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6c36ba7f snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x46257e89 snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xe3f33470 snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0x86bf187d snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x0418b9d7 snd_card_new +EXPORT_SYMBOL sound/core/snd 0x04287cad snd_card_register +EXPORT_SYMBOL sound/core/snd 0x064f2c94 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0x0f19e4d0 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x1218e140 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x1942fed1 snd_info_register +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x1a4d21ef snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0x1ac28a05 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x1cfd4fd3 snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd 0x21c731f1 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x2a2fb882 snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x2ae3deaa release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0x2ff5575f snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x3222bd73 snd_device_new +EXPORT_SYMBOL sound/core/snd 0x324cf9fa snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x333d428b snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x34686f4e snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0x34a5f27d snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x3b9e8cf6 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4bbc5ae1 snd_card_free +EXPORT_SYMBOL sound/core/snd 0x602c96f0 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0x62c9a08c snd_device_register +EXPORT_SYMBOL sound/core/snd 0x639b0a8f snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x6e96d14f snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x6fbc8ee1 snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x756907a6 snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x787f737a snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x7fdf0ec9 snd_device_free +EXPORT_SYMBOL sound/core/snd 0x8bb26d07 snd_cards +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x9051b9ca snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x9d93ecda snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0xa76f1495 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xba566429 snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0xbac72b03 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0xbf7997ad snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0xc63ee88d snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0xce3ca308 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0xd1719507 snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0xd21986b4 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0xd430e7c2 snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0xd5775264 snd_component_add +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xf296c976 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0xfb081d19 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xfb4252b2 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd-hwdep 0xf302df40 snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x0fc33a41 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x3b91f3af snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x846710b4 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x9abb9712 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xade88e76 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xfb3a8515 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xfc6629d9 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-pcm 0x04045432 snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x079618b2 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x0ed54a62 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x1a1614f8 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0x1c74c428 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x255a75ee snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0x319a9c00 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x327dfe7a snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0x356c3baa snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x423acd95 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x4d9b6d35 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x526c51cf snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x581af79b snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x6433c2ab snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x67b0150e snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6cecf54d snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x7337b8ab snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x8505d4e2 snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x8e6572cf snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x8e71077d snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x9a859256 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x9a921bf4 snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0x9e70c61b snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x9f2829e6 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0xa088c2fd snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0xa1ebaf7c snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0xa33d0564 snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0xa34b7300 snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xa6ae5472 snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0xa795a698 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0xab1ebbb9 snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0xadd3d278 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xc4100748 snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0xc49eb24f snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0xc6bf11c4 snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0xcf6e88f6 snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd13e3ebb snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xeea2dc69 snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xfd93cc32 snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0xfd94ca71 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-rawmidi 0x02bda31f snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-rawmidi 0x358da914 snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0x488030cd snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x4ec4ad74 snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0x6a17ea20 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0x86d1d00a snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0x9f5e4068 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xa58daeca snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0xb4489577 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc258995c snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc57825b1 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0xc7172d80 snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0xcea5ef2f snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0xdbd694fd snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0xe7722627 snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf0218501 snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf0babd73 snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-timer 0x00eb968c snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x010742d3 snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x24f85689 snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0x37f47c53 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x45987a65 snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0x5a72800c snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0x76294072 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0x7935968e snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0x83c0b9cb snd_timer_start +EXPORT_SYMBOL sound/core/snd-timer 0xb398ccda snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0xb5503e1e snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0xc539b7c9 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0xc696f409 snd_timer_pause +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x0734165c snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x1357c85c snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x22f087a8 snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x491f5c38 snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x5c238cb7 snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x6097679c snd_opl3_create +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x89a62f80 snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x92af6851 snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x9736f8e2 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x9a69bffb snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x4aec2d2b snd_opl4_create +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x7ad18766 snd_opl4_write_memory +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0x8956050a snd_opl4_write +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0xd336312f snd_opl4_read_memory +EXPORT_SYMBOL sound/drivers/opl4/snd-opl4-lib 0xf06a7271 snd_opl4_read +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x196ed646 snd_vx_dsp_load +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x259339d3 snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x2ad8559e snd_vx_load_boot_image +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x584d86e2 snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x8928228e snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xab428a6f snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xb42bd878 snd_vx_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xb45e81a6 snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xbfd28d66 snd_vx_resume +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x14918663 snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x274d5f20 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x32bf8f74 snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x63a3fca2 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x8b916a1a snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xd301e74d snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x2b5a0dcd snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x50f58431 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x93967005 snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x9e2b170d snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xc2bee1ee snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xcbc1d886 snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x13d1d4af snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x205ec768 snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xb5d1533f snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xd38767ab snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x34c09adb snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x4da7bc92 snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x26684407 snd_tea575x_init +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x8d6eb2e2 snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x2c13b3cb snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x6b30c01d snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xa44ac94e snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xaf10f384 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xb4c4af5e snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x0cdbed8b snd_i2c_device_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x174f8c00 snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0x22c30914 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x276f9940 snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x3c1b50eb snd_i2c_sendbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x503d225e snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0x6962a61d snd_tea6330t_update_mixer +EXPORT_SYMBOL sound/i2c/snd-tea6330t 0xcc11293f snd_tea6330t_detect +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0x49f7a947 snd_cs4236_mixer +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0xf086ec26 snd_cs4236_create +EXPORT_SYMBOL sound/isa/cs423x/snd-cs4236-lib 0xfed7aba6 snd_cs4236_pcm +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x29e88768 snd_es1688_create +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0x66ff8798 snd_es1688_mixer +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0xce68ec83 snd_es1688_pcm +EXPORT_SYMBOL sound/isa/es1688/snd-es1688-lib 0xf44d62d1 snd_es1688_mixer_write +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x00b1d33c snd_gus_create +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x0f70f0be snd_gus_dram_read +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x1082719a snd_gf1_new_mixer +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x10fe4347 snd_gf1_delay +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x16666f9c snd_gf1_pcm_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x1ebe1211 snd_gus_initialize +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x20024f12 snd_gf1_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x242a6318 snd_gf1_rawmidi_new +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x24fc1c32 snd_gf1_i_look8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x27392873 snd_gf1_i_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x2b011001 snd_gf1_look16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x42b73329 snd_gf1_i_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x46db8d67 snd_gf1_lvol_to_gvol_raw +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x66fdd667 snd_gus_use_inc +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x7a21a5c1 snd_gf1_write8 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x7c9b3d27 snd_gf1_translate_freq +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0x81fafd5b snd_gf1_ctrl_stop +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xacb27c08 snd_gf1_peek +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xb42ea7e7 snd_gus_dram_write +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xb6264046 snd_gf1_write_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xb7af1b6b snd_gf1_free_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xbffd0c68 snd_gf1_dram_addr +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc31af61d snd_gf1_mem_alloc +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc43a5527 snd_gf1_atten_table +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xc7d04b5f snd_gus_use_dec +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xd85053ba snd_gf1_mem_free +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xdb252880 snd_gf1_mem_xfree +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe0390828 snd_gf1_write16 +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe25b704e snd_gf1_stop_voice +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xe592808d snd_gf1_poke +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xeca2dd3e snd_gf1_mem_lock +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xf963a997 snd_gus_interrupt +EXPORT_SYMBOL sound/isa/gus/snd-gus-lib 0xfd84430b snd_gf1_alloc_voice +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x0eafbbae snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x657760b7 snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x6e32143f snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x824dffc5 snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x9a771afc snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xae2dafb4 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xb8e107ff snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xbb40af6a snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xbff2e5d3 snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xf3c644db snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb16-csp 0xe54795cf snd_sb_csp_new +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x9ed62457 snd_sb16dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xa476433a snd_sb16dsp_configure +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xabfac7cc snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x1e0f7b59 snd_sb8dsp_midi +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x2b6d2e0f snd_sb8dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0x9156d703 snd_sb8dsp_midi_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb8-dsp 0xabc9f4c8 snd_sb8dsp_pcm +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x114494bc snd_emu8000_update_chorus_mode +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x323da135 snd_emu8000_peek +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x356f91ce snd_emu8000_peek_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x38cae15a snd_emu8000_poke +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x779bb3d1 snd_emu8000_update_equalizer +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x77ce834d snd_emu8000_dma_chan +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0x8525f441 snd_emu8000_poke_dw +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xa22cb12f snd_emu8000_load_chorus_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xbc8f92f5 snd_emu8000_init_fm +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xd4d99ca0 snd_emu8000_load_reverb_fx +EXPORT_SYMBOL sound/isa/sb/snd-sbawe 0xe6a0c921 snd_emu8000_update_reverb_mode +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x013bf3e9 snd_wss_timer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x0416b497 snd_wss_overrange +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x0f7e342a snd_wss_chip_id +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x20d5966e snd_wss_mixer +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x2920e2d7 snd_wss_put_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x4170e216 snd_wss_get_pcm_ops +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x420f79a4 snd_wss_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x5889b8f0 snd_wss_create +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x710e5881 snd_wss_get_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x7188ed9c snd_wss_mce_up +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x789aa458 snd_wss_out +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x8a27a83a snd_wss_info_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x925a11a8 snd_cs4236_ext_out +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x92e56f87 snd_cs4236_ext_in +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0x9e5f6eb7 snd_wss_interrupt +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xa61840f8 snd_wss_pcm +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xae127a4a snd_wss_put_double +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xb01ce7ab snd_wss_info_single +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xe80ce334 snd_wss_mce_down +EXPORT_SYMBOL sound/isa/wss/snd-wss-lib 0xf63cc01c snd_wss_get_single +EXPORT_SYMBOL sound/oss/ad1848 0x26c427ee ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x55262c70 probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x8a32d64d ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/ad1848 0xcbca72b9 attach_ms_sound +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xcac19c5a attach_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xd9ec5db4 probe_mpu401 +EXPORT_SYMBOL sound/oss/msnd 0x1186f48f msnd_fifo_read +EXPORT_SYMBOL sound/oss/msnd 0x234f64e0 msnd_register +EXPORT_SYMBOL sound/oss/msnd 0x340a3ddf msnd_init_queue +EXPORT_SYMBOL sound/oss/msnd 0x54230dc1 msnd_fifo_write +EXPORT_SYMBOL sound/oss/msnd 0x5fb94ecb msnd_unregister +EXPORT_SYMBOL sound/oss/msnd 0x6587640b msnd_disable_irq +EXPORT_SYMBOL sound/oss/msnd 0x6601493b msnd_fifo_make_empty +EXPORT_SYMBOL sound/oss/msnd 0x8e3c524b msnd_send_dsp_cmd +EXPORT_SYMBOL sound/oss/msnd 0x9274d677 msnd_fifo_free +EXPORT_SYMBOL sound/oss/msnd 0x95d37486 msnd_upload_host +EXPORT_SYMBOL sound/oss/msnd 0xa1bcc420 msnd_send_word +EXPORT_SYMBOL sound/oss/msnd 0xade99e25 msnd_fifo_alloc +EXPORT_SYMBOL sound/oss/msnd 0xb3520772 msnd_fifo_init +EXPORT_SYMBOL sound/oss/msnd 0xdf0f59eb msnd_fifo_write_io +EXPORT_SYMBOL sound/oss/msnd 0xefdd1843 msnd_enable_irq +EXPORT_SYMBOL sound/oss/msnd 0xf4c4f662 msnd_fifo_read_io +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x485245ab probe_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0x5f7c1626 sb_dsp_init +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x1604b3f7 synth_devs +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1e07bfb2 sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x45ebb19a midi_devs +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x72981d1f sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xdf977bd4 mixer_devs +EXPORT_SYMBOL sound/oss/sound 0xe017f183 audio_devs +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xefdb2c34 sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/uart401 0x3505c8ed probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0855153e snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0a66bb23 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x19129012 snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x193f2583 snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x316bb98d snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x3ff6a78e snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x42035945 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x42c98980 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8fe8f22d snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xa47140a4 snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xbe54640a snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xbea6f595 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xcdb680a3 snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xd6f8e046 snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xd776a9cb snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xf41dbe58 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xf933f541 snd_ac97_update_power +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x37969bc9 snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x7bc421f7 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x8a65f5fc snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x96cb8ad4 snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xa1daf4d8 snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xb45733b8 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xc808f8b3 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xe882218f snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xf9bdb907 snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x3ae1ee4c snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x5088df91 snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0x92f67d41 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x048afe3b oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x1d4dbc75 oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x20395a38 oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x25a80649 oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x2cde37f8 oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x390684ac oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x62a35f47 oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x687b56f9 oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x760afeb8 oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x77b1bfc2 oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7f6451e4 oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x865a1b4e oxygen_pci_resume +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x9a8133a1 oxygen_write16_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xbc376e10 oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xc69afea7 oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xca44818d oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xce014a51 oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd7a1abcd oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xd8de26f2 oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf8bf8e8a oxygen_write32 +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x4e6e2dc3 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x5097d04f snd_trident_free_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x55056702 snd_trident_stop_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x5ca96c61 snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xe261e502 snd_trident_start_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x0463c2f6 register_sound_midi +EXPORT_SYMBOL sound/soundcore 0x3f2d23e4 register_sound_special +EXPORT_SYMBOL sound/soundcore 0x64b296ff register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x8c622fb1 register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xed5426bf register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0xf82ab2f2 sound_class +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x2ae63bce snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x4987a24e snd_emux_register +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xa45e8bd1 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xd2b75a2a snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xe90d322a snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xee5de7c1 snd_emux_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x234e8f51 snd_usb_create_midi_interface +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x6b6b4f2d dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x6bcd5995 dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x7e10321f dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xb2efff38 dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xbb8bf94b dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xe2131490 dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0329d132 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x06b6d02c rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x108f2649 rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x2d9aa7a9 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x3e7269b2 rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x4ae24513 rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x68cb9ae8 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8252ef05 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x8821f9a7 rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa4a7321f rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xd99f0978 rh_inc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xda581f7b rh_get_region_size +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x60b2e316 cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x0c37f3ff lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xc2b2c524 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0xdd2eecab ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x1287cf1e p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x144ac8bf p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x20d82f42 p80211skb_rxmeta_attach +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x2f3bc0b4 wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x3b8771c4 p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x51709442 p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x6fb689f0 unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xa98fbaf4 p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xd5525d0d wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xdb525264 p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xe492904a p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xea5ddc6f register_wlandev +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x00112f51 groups_alloc +EXPORT_SYMBOL vmlinux 0x0046cb18 remove_proc_entry +EXPORT_SYMBOL vmlinux 0x004f00a5 __rta_fill +EXPORT_SYMBOL vmlinux 0x0051f190 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x005724c0 phy_driver_unregister +EXPORT_SYMBOL vmlinux 0x00701c0f put_io_context +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x008cf709 pci_bus_type +EXPORT_SYMBOL vmlinux 0x00920163 dma_alloc_from_coherent +EXPORT_SYMBOL vmlinux 0x0094c3d2 jbd2_journal_start +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00b787b0 iget_failed +EXPORT_SYMBOL vmlinux 0x00e8097b csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x00fb4238 unlock_buffer +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01abf730 kunmap_high +EXPORT_SYMBOL vmlinux 0x01acc17f dm_table_get +EXPORT_SYMBOL vmlinux 0x01b910cd dev_get_by_name +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x01e57740 tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x02373db8 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x025277f6 profile_pc +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x029319cb mca_bus_type +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02d14144 vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02dddb8a i2c_transfer +EXPORT_SYMBOL vmlinux 0x02e376e7 jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x02ee26c1 free_pages_exact +EXPORT_SYMBOL vmlinux 0x02fae013 ip_fragment +EXPORT_SYMBOL vmlinux 0x030867c2 jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0x03213a6e set_trace_device +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03fcfe5b kobject_init +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x04249b08 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x045c9bbe __wait_on_buffer +EXPORT_SYMBOL vmlinux 0x04685f95 skb_gso_segment +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x04c00a82 skb_unlink +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04fced0d blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0x052ebd08 con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x05384ab7 pci_dev_put +EXPORT_SYMBOL vmlinux 0x0555e3d7 should_remove_suid +EXPORT_SYMBOL vmlinux 0x0560cdeb xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x05664f17 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0x05761b71 pci_disable_msix +EXPORT_SYMBOL vmlinux 0x057ce975 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x057ff5da mca_device_transform_memory +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x059a9064 tcf_action_exec +EXPORT_SYMBOL vmlinux 0x059cf4fc simple_lookup +EXPORT_SYMBOL vmlinux 0x05a22a89 pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x05c47519 rtnl_notify +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x05eed8d2 d_rehash +EXPORT_SYMBOL vmlinux 0x05f60c31 neigh_compat_output +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0629d683 kernel_getsockname +EXPORT_SYMBOL vmlinux 0x063f558e tty_write_room +EXPORT_SYMBOL vmlinux 0x06506a3c vfs_mknod +EXPORT_SYMBOL vmlinux 0x066caa81 key_task_permission +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x068c7263 ioremap_cache +EXPORT_SYMBOL vmlinux 0x0692f390 rfkill_free +EXPORT_SYMBOL vmlinux 0x069c1282 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x06a84fad sock_release +EXPORT_SYMBOL vmlinux 0x06ba3af8 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06e32104 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x06e41f15 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x06f085b7 pci_request_region +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x0703edf0 block_truncate_page +EXPORT_SYMBOL vmlinux 0x07178a77 mca_device_set_name +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x07476646 rtnl_unicast +EXPORT_SYMBOL vmlinux 0x0749ce94 tty_vhangup +EXPORT_SYMBOL vmlinux 0x074dcba3 fb_is_primary_device +EXPORT_SYMBOL vmlinux 0x07601c72 genphy_read_status +EXPORT_SYMBOL vmlinux 0x07608604 acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07d50a24 csum_partial +EXPORT_SYMBOL vmlinux 0x07d60280 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x07dd6ad5 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x0885a39d init_special_inode +EXPORT_SYMBOL vmlinux 0x08ac66d9 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x0903b2ed tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x090728ba skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x090dd3f8 phy_print_status +EXPORT_SYMBOL vmlinux 0x09118775 netdev_state_change +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x093e947e posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098398e7 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0x0984f16b input_unregister_device +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x09e01596 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0x09e0d962 phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a3131f6 strnchr +EXPORT_SYMBOL vmlinux 0x0a47d82f filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x0a57d162 kernel_listen +EXPORT_SYMBOL vmlinux 0x0a5ef655 ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0x0a8c5bff vfs_rmdir +EXPORT_SYMBOL vmlinux 0x0ac43c0f init_buffer +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0ad456a3 make_bad_inode +EXPORT_SYMBOL vmlinux 0x0ae9c438 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0x0af1534e write_inode_now +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b4d674b blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x0b6170d1 ilookup +EXPORT_SYMBOL vmlinux 0x0b68a2df arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b758e75 dma_release_declared_memory +EXPORT_SYMBOL vmlinux 0x0b892405 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x0b93c9df init_net +EXPORT_SYMBOL vmlinux 0x0b9c4fd2 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x0bb41a6c netlink_kernel_create +EXPORT_SYMBOL vmlinux 0x0bc02d85 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x0bc44062 hci_register_cb +EXPORT_SYMBOL vmlinux 0x0be8efd1 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0x0bfc2c22 pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x0c03bba2 pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x0c2bada9 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x0c42203f neigh_seq_start +EXPORT_SYMBOL vmlinux 0x0c55e87c rfkill_force_state +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0ca1646c dm_table_get_size +EXPORT_SYMBOL vmlinux 0x0ca730a2 acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x0ca7b7a8 acpi_check_region +EXPORT_SYMBOL vmlinux 0x0cadfcc4 bd_set_size +EXPORT_SYMBOL vmlinux 0x0cd4118c __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0x0cd5d880 mca_device_transform_irq +EXPORT_SYMBOL vmlinux 0x0d0441b8 tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d2d4f88 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0x0d2fd938 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x0d384c76 inet_frag_evictor +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d49e509 md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x0d4b77b7 gen_pool_add +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d6bd6db check_disk_change +EXPORT_SYMBOL vmlinux 0x0d6c963c copy_from_user +EXPORT_SYMBOL vmlinux 0x0d791415 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0d96c727 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0x0d976e44 tcp_prot +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0db33b83 ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x0dc0d8fe tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0x0dcde0be inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x0dd1e80f ps2_drain +EXPORT_SYMBOL vmlinux 0x0ddbef96 mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0x0e084550 register_gifconf +EXPORT_SYMBOL vmlinux 0x0e23e472 xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x0e4272ee thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e632599 __pagevec_release +EXPORT_SYMBOL vmlinux 0x0e69bb2d tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0eb48212 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x0f0475b1 __bforget +EXPORT_SYMBOL vmlinux 0x0f8975c0 pci_dev_get +EXPORT_SYMBOL vmlinux 0x0f8a553e scsi_remove_host +EXPORT_SYMBOL vmlinux 0x0fa4a4fc bdget_disk +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fcc5d0f call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0fe58ce8 jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x102a4561 starget_for_each_device +EXPORT_SYMBOL vmlinux 0x103a4157 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x103fd3ae ether_setup +EXPORT_SYMBOL vmlinux 0x107092ef udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x107b17a5 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0x107ed2eb textsearch_prepare +EXPORT_SYMBOL vmlinux 0x1087359c pci_remove_bus +EXPORT_SYMBOL vmlinux 0x10cf6de1 inet_frags_init +EXPORT_SYMBOL vmlinux 0x10d70e75 dev_remove_pack +EXPORT_SYMBOL vmlinux 0x10ddf54d alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x10f0907b invalidate_bdev +EXPORT_SYMBOL vmlinux 0x10f19d36 inet_accept +EXPORT_SYMBOL vmlinux 0x10f45607 tcp_ioctl +EXPORT_SYMBOL vmlinux 0x110c0cba secpath_dup +EXPORT_SYMBOL vmlinux 0x1116c3f4 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x114a30f2 mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x11520e8e jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x115ea8de blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x1194e9db vfs_quota_on +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11ad4273 tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0x11e78f3b neigh_update +EXPORT_SYMBOL vmlinux 0x11e81a6d mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x11ea4c31 mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0x11f5f111 sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0x120507ac idr_get_new +EXPORT_SYMBOL vmlinux 0x120c5166 alloc_fcdev +EXPORT_SYMBOL vmlinux 0x1212f734 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x1213515e skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x124f8c8c tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0x1253ec61 llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x1268134e kill_fasync +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x128b3741 set_bdi_congested +EXPORT_SYMBOL vmlinux 0x129d2e8b unlock_rename +EXPORT_SYMBOL vmlinux 0x12a88a3c xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x12da5bb2 __kmalloc +EXPORT_SYMBOL vmlinux 0x12f688fa invalidate_inodes +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x133e75d4 tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x133fe826 nf_reinject +EXPORT_SYMBOL vmlinux 0x136c0894 dm_table_event +EXPORT_SYMBOL vmlinux 0x13781784 gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x139dd793 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x13ac418f __serio_register_driver +EXPORT_SYMBOL vmlinux 0x13d0b410 no_llseek +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x13ff1648 seq_release +EXPORT_SYMBOL vmlinux 0x140d4e3e __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x14576d2f cfb_imageblit +EXPORT_SYMBOL vmlinux 0x145daa04 generic_unplug_device +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x1493b58b xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14c1984d pv_mmu_ops +EXPORT_SYMBOL vmlinux 0x14f332ea up_read +EXPORT_SYMBOL vmlinux 0x1543e3fc journal_release_buffer +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x155edf60 scsi_scan_target +EXPORT_SYMBOL vmlinux 0x1585050d get_user_pages +EXPORT_SYMBOL vmlinux 0x15938be4 jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0x159c9560 register_chrdev +EXPORT_SYMBOL vmlinux 0x15d2b18d jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x1610dd3e blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0x163056ef __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0x16588713 pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x1675606f bad_dma_address +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x1681a547 udp_ioctl +EXPORT_SYMBOL vmlinux 0x169641b5 __lock_page +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16a7dfe6 cdev_add +EXPORT_SYMBOL vmlinux 0x16be78c2 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x16d76dc7 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x16e45455 cdev_init +EXPORT_SYMBOL vmlinux 0x16e5b21e bd_claim +EXPORT_SYMBOL vmlinux 0x17052027 thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x1733ed61 hci_get_route +EXPORT_SYMBOL vmlinux 0x17417525 thaw_process +EXPORT_SYMBOL vmlinux 0x1750392a phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0x175a298d acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x176b9e12 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x17823d26 kernel_connect +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17b4ba9f dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0x17d95dfd bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17e557ea alloc_disk +EXPORT_SYMBOL vmlinux 0x17eb2aa2 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x17f297d9 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0x180af084 fb_show_logo +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x183f05fe acpi_bus_start +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x1845e7c5 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x1858f107 eth_type_trans +EXPORT_SYMBOL vmlinux 0x186903d6 i2c_release_client +EXPORT_SYMBOL vmlinux 0x187644e4 register_snap_client +EXPORT_SYMBOL vmlinux 0x18d60c4b journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x18e01838 scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x1920f8c3 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0x1939e3e2 hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0x193ad3ca unregister_nls +EXPORT_SYMBOL vmlinux 0x194f209b bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0x195f7800 register_cdrom +EXPORT_SYMBOL vmlinux 0x19656891 simple_release_fs +EXPORT_SYMBOL vmlinux 0x197582a9 journal_start_commit +EXPORT_SYMBOL vmlinux 0x197961c4 framebuffer_release +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x198ca580 tty_unregister_device +EXPORT_SYMBOL vmlinux 0x198e8893 tcp_poll +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19a057ba simple_transaction_get +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19f5d6f0 thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x1a137cbf keyring_clear +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a5e72f6 xfrm_state_add +EXPORT_SYMBOL vmlinux 0x1a758ed5 register_8022_client +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a854228 get_io_context +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1a8ced77 seq_bitmap +EXPORT_SYMBOL vmlinux 0x1a937a44 d_instantiate +EXPORT_SYMBOL vmlinux 0x1a9835ac i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0x1aa0dfe2 backlight_device_register +EXPORT_SYMBOL vmlinux 0x1abcc41b netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0x1ac2e31f phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1adba511 hci_register_dev +EXPORT_SYMBOL vmlinux 0x1ae55444 simple_rmdir +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b146605 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0x1b2adb85 tcp_make_synack +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b4b5064 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b742543 bdget +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1bb38463 bio_alloc +EXPORT_SYMBOL vmlinux 0x1bd137b3 ip_route_input +EXPORT_SYMBOL vmlinux 0x1be48e9d blk_get_request +EXPORT_SYMBOL vmlinux 0x1be5cd23 simple_transaction_release +EXPORT_SYMBOL vmlinux 0x1bf3f3a9 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x1c5ed04b tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0x1c9633dd textsearch_register +EXPORT_SYMBOL vmlinux 0x1c9656cc tcf_exts_dump +EXPORT_SYMBOL vmlinux 0x1c9db56b shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0x1cb0821f dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ce1e467 load_nls_default +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1d30b70c rwsem_wake +EXPORT_SYMBOL vmlinux 0x1d3d8fc8 bio_integrity_advance +EXPORT_SYMBOL vmlinux 0x1d56ca4e blk_queue_ordered +EXPORT_SYMBOL vmlinux 0x1da890bb pci_get_subsys +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dce73fb sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1ddc22e4 end_request +EXPORT_SYMBOL vmlinux 0x1e1d1498 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e32d23a neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e6f68e0 misc_register +EXPORT_SYMBOL vmlinux 0x1e6fe2d1 rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ec94f53 __f_setown +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1f4cc01a pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0x1f51d0e8 uart_register_driver +EXPORT_SYMBOL vmlinux 0x1f62f8d1 poll_initwait +EXPORT_SYMBOL vmlinux 0x1f90f38c kunmap +EXPORT_SYMBOL vmlinux 0x1f9d7afd vfs_quota_off +EXPORT_SYMBOL vmlinux 0x1fe5ede6 per_cpu__irq_stat +EXPORT_SYMBOL vmlinux 0x1fe8d848 llc_sap_find +EXPORT_SYMBOL vmlinux 0x1ff695fe vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x200c9020 free_task +EXPORT_SYMBOL vmlinux 0x200ed116 dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0x2058ed15 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x2072e581 tcp_splice_read +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x20b727e6 jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0x20b79892 posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x21221280 udp_prot +EXPORT_SYMBOL vmlinux 0x215e3fd0 bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x218480f6 mca_register_driver_integrated +EXPORT_SYMBOL vmlinux 0x21a6f83a serial8250_register_port +EXPORT_SYMBOL vmlinux 0x21aab73c neigh_connected_output +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21ede2ae jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0x2215a548 thaw_bdev +EXPORT_SYMBOL vmlinux 0x222169b7 sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x22303ac5 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0x2239afab dev_unicast_add +EXPORT_SYMBOL vmlinux 0x22435776 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x224e4d4e drop_super +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x2270e67b mca_device_write_pos +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22999166 skb_store_bits +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22e84a39 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x22ee5664 invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0x231e3da6 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x2368be6d posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x237c6ead skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x238357f2 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x2383f3e2 audit_log_start +EXPORT_SYMBOL vmlinux 0x23a19432 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x23ad070a set_current_groups +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23d75fe8 notify_change +EXPORT_SYMBOL vmlinux 0x23f13985 iunique +EXPORT_SYMBOL vmlinux 0x23f7344f elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x24287361 truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x243ffddc idr_destroy +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x246342fc sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x2470a176 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x249ba953 pci_target_state +EXPORT_SYMBOL vmlinux 0x24a43d87 vfs_writev +EXPORT_SYMBOL vmlinux 0x24b82949 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x24c37175 d_alloc +EXPORT_SYMBOL vmlinux 0x24e1ff40 ps2_handle_response +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x250113b4 memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x257d762d __devm_release_region +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x2596feff dmam_release_declared_memory +EXPORT_SYMBOL vmlinux 0x25ac46ec input_release_device +EXPORT_SYMBOL vmlinux 0x25b09541 sk_alloc +EXPORT_SYMBOL vmlinux 0x25bcf7a2 xfrm_register_km +EXPORT_SYMBOL vmlinux 0x25d81960 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x25f02cd0 ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0x25f0d8e3 __nla_put +EXPORT_SYMBOL vmlinux 0x265aed16 sk_free +EXPORT_SYMBOL vmlinux 0x2674893e register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x2685c3d7 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x268cc6a2 sys_close +EXPORT_SYMBOL vmlinux 0x269166e4 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x26b49653 __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x26bd2717 pci_disable_msi +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x27553c78 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27885fef bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x27a45ba2 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0x27a83068 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27b8f7e7 wireless_send_event +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x281c1514 simple_pin_fs +EXPORT_SYMBOL vmlinux 0x2839c5cd md_done_sync +EXPORT_SYMBOL vmlinux 0x28427720 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x285f1b39 dquot_release +EXPORT_SYMBOL vmlinux 0x2862cd14 add_disk +EXPORT_SYMBOL vmlinux 0x288d1ac1 pnp_possible_config +EXPORT_SYMBOL vmlinux 0x289fdbca mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28b715a6 isapnp_cfg_end +EXPORT_SYMBOL vmlinux 0x28d5cb1e netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x292af804 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x292ba61c xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x292c7624 blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x29504268 cdrom_ioctl +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x295d6605 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x295e02b6 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29c90670 give_up_console +EXPORT_SYMBOL vmlinux 0x29de63b1 vfs_create +EXPORT_SYMBOL vmlinux 0x2a1039dc sock_sendmsg +EXPORT_SYMBOL vmlinux 0x2a10a26f nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x2a1d8df1 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x2a1e2a2d poll_freewait +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a386d2d vfs_quota_sync +EXPORT_SYMBOL vmlinux 0x2a4af2b1 __free_pages +EXPORT_SYMBOL vmlinux 0x2a86c37a unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x2a9274fb xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x2aa0e4fc strncasecmp +EXPORT_SYMBOL vmlinux 0x2ab82809 phy_start_interrupts +EXPORT_SYMBOL vmlinux 0x2abb9cf6 I_BDEV +EXPORT_SYMBOL vmlinux 0x2ac41b91 __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2b081459 f_setown +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b27a233 unregister_filesystem +EXPORT_SYMBOL vmlinux 0x2b27c240 devm_iounmap +EXPORT_SYMBOL vmlinux 0x2b371e3d ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x2b4d9b7e input_register_handle +EXPORT_SYMBOL vmlinux 0x2b54d8fc xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b6ac936 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x2b730499 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2ba8e4f2 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x2bb10ae3 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2bbb9cd4 posix_test_lock +EXPORT_SYMBOL vmlinux 0x2bc95bd4 memset +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c109cef get_super +EXPORT_SYMBOL vmlinux 0x2c25e5b2 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0x2c29798f dst_release +EXPORT_SYMBOL vmlinux 0x2c4c68b4 __ht_create_irq +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c89bc37 request_key +EXPORT_SYMBOL vmlinux 0x2c8f5989 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0x2c905056 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0x2c9874fe ida_remove +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cccf73d sock_init_data +EXPORT_SYMBOL vmlinux 0x2cd1ad50 simple_fill_super +EXPORT_SYMBOL vmlinux 0x2cd4ac16 skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2cf904b8 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x2cfc9cc0 sock_rfree +EXPORT_SYMBOL vmlinux 0x2cff98b2 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0x2d323387 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x2d5eb479 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0x2d6236ae sysctl_string +EXPORT_SYMBOL vmlinux 0x2d877104 scsi_prep_return +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2dacb6c8 inode_add_bytes +EXPORT_SYMBOL vmlinux 0x2dbafbe3 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2de3cb53 __bio_clone +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e0ed245 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e31829b __scsi_add_device +EXPORT_SYMBOL vmlinux 0x2e331559 llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x2e437081 deny_write_access +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e60bace memcpy +EXPORT_SYMBOL vmlinux 0x2e8ee079 xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x2e97859f rwsem_downgrade_wake +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2eeed6e2 keyring_search +EXPORT_SYMBOL vmlinux 0x2f205a19 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0x2f26d309 generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x2f287f0d copy_to_user +EXPORT_SYMBOL vmlinux 0x2f9e3d9a seq_puts +EXPORT_SYMBOL vmlinux 0x2fe20a88 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x3018817b fb_get_mode +EXPORT_SYMBOL vmlinux 0x3021aa3d jbd2_journal_create +EXPORT_SYMBOL vmlinux 0x304296c4 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0x3070a7a7 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x309756b6 __splice_from_pipe +EXPORT_SYMBOL vmlinux 0x30c18575 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0x30d09b8e input_event +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x310917fe sort +EXPORT_SYMBOL vmlinux 0x3123f92a uart_unregister_driver +EXPORT_SYMBOL vmlinux 0x312b4235 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x318a2cc4 usb_serial_resume +EXPORT_SYMBOL vmlinux 0x3191f109 __krealloc +EXPORT_SYMBOL vmlinux 0x31a18ff5 path_permission +EXPORT_SYMBOL vmlinux 0x31c193ea proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x31e76b57 recalibrate_cpu_khz +EXPORT_SYMBOL vmlinux 0x31e9ad2c pci_find_next_bus +EXPORT_SYMBOL vmlinux 0x32034972 sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x321c6749 dquot_acquire +EXPORT_SYMBOL vmlinux 0x32288c1f sock_no_shutdown +EXPORT_SYMBOL vmlinux 0x322dc4f4 page_address +EXPORT_SYMBOL vmlinux 0x324c82df get_unmapped_area +EXPORT_SYMBOL vmlinux 0x3275a391 skb_split +EXPORT_SYMBOL vmlinux 0x3294c30d devm_ioremap +EXPORT_SYMBOL vmlinux 0x32a2abff unregister_netdevice +EXPORT_SYMBOL vmlinux 0x32a4eaff deactivate_super +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32d1a45c pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0x32d70e7d module_put +EXPORT_SYMBOL vmlinux 0x32dc63fd acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0x332cc613 ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0x33385001 fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x3385c8cb per_cpu__this_cpu_off +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x33f38c8b inode_setattr +EXPORT_SYMBOL vmlinux 0x340a1b1d page_follow_link_light +EXPORT_SYMBOL vmlinux 0x342e98bf dst_discard +EXPORT_SYMBOL vmlinux 0x342f60fe apm_info +EXPORT_SYMBOL vmlinux 0x344cba6e arp_create +EXPORT_SYMBOL vmlinux 0x3452730c key_alloc +EXPORT_SYMBOL vmlinux 0x347abbd9 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x34908c14 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34e4648f isapnp_protocol +EXPORT_SYMBOL vmlinux 0x357158f2 pci_dev_driver +EXPORT_SYMBOL vmlinux 0x3582d5d7 dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35dcc4a7 dev_open +EXPORT_SYMBOL vmlinux 0x35f0faa2 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x35f16543 pcibios_set_irq_routing +EXPORT_SYMBOL vmlinux 0x360336b0 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x36363ed3 get_fs_type +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x3663192d simple_unlink +EXPORT_SYMBOL vmlinux 0x36a823dd scsi_finish_command +EXPORT_SYMBOL vmlinux 0x36c1ee06 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x36dce9ad dquot_drop +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x374ed073 scnprintf +EXPORT_SYMBOL vmlinux 0x377eca69 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x377f8933 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0x3786f606 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x379d65f5 gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x37a2db17 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x37b28829 scsi_dma_map +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37d483e1 dev_get_by_index +EXPORT_SYMBOL vmlinux 0x37e74642 get_jiffies_64 +EXPORT_SYMBOL vmlinux 0x380a54aa bio_put +EXPORT_SYMBOL vmlinux 0x38203ca1 __init_rwsem +EXPORT_SYMBOL vmlinux 0x38291202 fb_set_var +EXPORT_SYMBOL vmlinux 0x383c986c scsi_device_get +EXPORT_SYMBOL vmlinux 0x38462b7c acpi_root_dir +EXPORT_SYMBOL vmlinux 0x3849e67f pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x384c76f5 user_revoke +EXPORT_SYMBOL vmlinux 0x3865dc2a tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0x3874fc2b write_cache_pages +EXPORT_SYMBOL vmlinux 0x387c0967 vfs_lstat +EXPORT_SYMBOL vmlinux 0x38883ed7 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38c29708 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x395b8439 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0x3968c66e blk_rq_init +EXPORT_SYMBOL vmlinux 0x396afc01 take_over_console +EXPORT_SYMBOL vmlinux 0x396d024b bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0x3973279c dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x399381bb netpoll_cleanup +EXPORT_SYMBOL vmlinux 0x39a2c0da bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x39a953b2 netpoll_poll +EXPORT_SYMBOL vmlinux 0x39be2e9c scsi_print_sense +EXPORT_SYMBOL vmlinux 0x39c48171 jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0x39c645a2 schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x39deb2d7 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x39e1ac47 unregister_con_driver +EXPORT_SYMBOL vmlinux 0x39e5ae57 __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x3a186169 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a25facf inet6_release +EXPORT_SYMBOL vmlinux 0x3a2e5a52 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x3a314d37 fsync_bdev +EXPORT_SYMBOL vmlinux 0x3a3f62c2 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0x3a70a0ce phy_scan_fixups +EXPORT_SYMBOL vmlinux 0x3a8a86fa blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x3a8e99db tcp_sendpage +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa0c6aa input_unregister_handler +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3aaa00d9 inode_double_lock +EXPORT_SYMBOL vmlinux 0x3aad815d simple_write_end +EXPORT_SYMBOL vmlinux 0x3ab708e1 skb_queue_head +EXPORT_SYMBOL vmlinux 0x3ac69b1c seq_escape +EXPORT_SYMBOL vmlinux 0x3ada503c netif_device_detach +EXPORT_SYMBOL vmlinux 0x3b1242b8 __kfree_skb +EXPORT_SYMBOL vmlinux 0x3b167d7c jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0x3b2624ca seq_putc +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b334e6e bdi_register +EXPORT_SYMBOL vmlinux 0x3b364681 inet6_ioctl +EXPORT_SYMBOL vmlinux 0x3b573579 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x3b5fde6e journal_force_commit +EXPORT_SYMBOL vmlinux 0x3b7f4255 task_nice +EXPORT_SYMBOL vmlinux 0x3ba7258b pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3bf074c1 nf_log_unregister +EXPORT_SYMBOL vmlinux 0x3c03f2d1 prepare_binprm +EXPORT_SYMBOL vmlinux 0x3c1cece2 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c3e0a70 pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c93e3a9 ppp_unit_number +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb3931b sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cd44b7e blk_run_queue +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cf30b4d pagecache_write_end +EXPORT_SYMBOL vmlinux 0x3cff4624 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x3d0515c0 iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0x3d1c8707 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x3d7216e2 journal_flush +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da3ae4f alloc_disk_node +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3db2f21f set_bh_page +EXPORT_SYMBOL vmlinux 0x3deec671 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e6484b4 kill_block_super +EXPORT_SYMBOL vmlinux 0x3e6ac078 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x3ec00af1 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ef2d29b vfs_permission +EXPORT_SYMBOL vmlinux 0x3ef3b482 nobh_writepage +EXPORT_SYMBOL vmlinux 0x3efc22e8 input_set_capability +EXPORT_SYMBOL vmlinux 0x3efecbfd cdrom_mode_select +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f233de3 __netif_schedule +EXPORT_SYMBOL vmlinux 0x3f260099 follow_up +EXPORT_SYMBOL vmlinux 0x3f39b162 up_write +EXPORT_SYMBOL vmlinux 0x3f432464 ps2_init +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3f53866b md_write_end +EXPORT_SYMBOL vmlinux 0x3f5ea5ec blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x3f6204c0 scsi_register +EXPORT_SYMBOL vmlinux 0x3f7df497 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x3fec048f sg_next +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x400f3070 mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x4014aab8 __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x402858b6 qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x40532f85 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0x4059792f print_hex_dump +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x408dbf79 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x41045a13 sock_no_getname +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x41194f64 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x41236db1 generic_readlink +EXPORT_SYMBOL vmlinux 0x413ee741 pid_task +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x4152f69a vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x417cc6f4 generic_osync_inode +EXPORT_SYMBOL vmlinux 0x4185cf4b radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x41885662 thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x418f4e43 tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41e0d832 kobject_get +EXPORT_SYMBOL vmlinux 0x4202bb68 vfs_rename +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x425ee678 release_sock +EXPORT_SYMBOL vmlinux 0x427d74bc iput +EXPORT_SYMBOL vmlinux 0x4292364c schedule +EXPORT_SYMBOL vmlinux 0x4299c90e do_sync_write +EXPORT_SYMBOL vmlinux 0x429d3de1 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0x42c8de35 ioremap_nocache +EXPORT_SYMBOL vmlinux 0x42c9904e pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x42d2bf51 __dst_free +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x432c2912 skb_truesize_bug +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x4371a521 pci_enable_wake +EXPORT_SYMBOL vmlinux 0x437796f6 sync_inode +EXPORT_SYMBOL vmlinux 0x43b40de7 kunmap_atomic +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x44252639 mark_page_accessed +EXPORT_SYMBOL vmlinux 0x442ac9de km_policy_expired +EXPORT_SYMBOL vmlinux 0x44314efb radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x446dcf09 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x44a974c9 scsi_add_host +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44b320b6 phy_device_create +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44be0027 lease_get_mtime +EXPORT_SYMBOL vmlinux 0x44c52166 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x44e06c4d scm_fp_dup +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x44ef77b3 vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0x44f21bea idr_for_each +EXPORT_SYMBOL vmlinux 0x44faa8c5 ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0x450fded0 update_region +EXPORT_SYMBOL vmlinux 0x4517db3c d_validate +EXPORT_SYMBOL vmlinux 0x45360828 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0x4537db5a ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0x453b0ac5 neigh_for_each +EXPORT_SYMBOL vmlinux 0x453bc1bb path_get +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x458e1b4a __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x4590c066 dev_set_mac_address +EXPORT_SYMBOL vmlinux 0x459c0696 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0x45a6fbcd neigh_parms_release +EXPORT_SYMBOL vmlinux 0x45b8ea8b phy_start_aneg +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x45d766a4 kset_unregister +EXPORT_SYMBOL vmlinux 0x45dd4d9d tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0x45f99bc1 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x462a2e75 match_strlcpy +EXPORT_SYMBOL vmlinux 0x463ffabd acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0x465ac850 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x469e78cc md_wakeup_thread +EXPORT_SYMBOL vmlinux 0x46a2a9ff jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0x46a5c30f do_munmap +EXPORT_SYMBOL vmlinux 0x46ce7668 follow_down +EXPORT_SYMBOL vmlinux 0x46e55f55 scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x4715e293 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0x47167d19 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x472d2a9a radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x473eb2ee dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x4743701c dev_mc_sync +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x4756479c elv_abort_queue +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47c62d70 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x47c92759 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x47f26512 dcache_dir_open +EXPORT_SYMBOL vmlinux 0x47ffbde0 put_page +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x4843c8fa freeze_bdev +EXPORT_SYMBOL vmlinux 0x484500a9 jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x489a8ab0 phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0x48a9ed73 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x48e6348e pnp_start_dev +EXPORT_SYMBOL vmlinux 0x48f19c39 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x48f1ec45 put_disk +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x494147a1 datagram_poll +EXPORT_SYMBOL vmlinux 0x494635ec elevator_exit +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x49d786fc call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x4a289005 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0x4a322113 d_invalidate +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a3f47e4 generic_listxattr +EXPORT_SYMBOL vmlinux 0x4a855364 blk_execute_rq +EXPORT_SYMBOL vmlinux 0x4a971ec7 radix_tree_delete +EXPORT_SYMBOL vmlinux 0x4acd93d3 release_resource +EXPORT_SYMBOL vmlinux 0x4ad34f03 sk_stop_timer +EXPORT_SYMBOL vmlinux 0x4adf7c2b lock_may_read +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4affc0cf jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b30cb43 bio_sector_offset +EXPORT_SYMBOL vmlinux 0x4b34fbf5 block_all_signals +EXPORT_SYMBOL vmlinux 0x4b4822fa nf_hook_slow +EXPORT_SYMBOL vmlinux 0x4b4aa72e sk_receive_skb +EXPORT_SYMBOL vmlinux 0x4b5ced24 hci_send_sco +EXPORT_SYMBOL vmlinux 0x4b698ffa skb_trim +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4b831fe3 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x4ba96f3a locks_copy_lock +EXPORT_SYMBOL vmlinux 0x4bb02278 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x4bb89ff5 find_or_create_page +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4be9aa77 pci_match_id +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c1db819 kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0x4c438702 do_sync_read +EXPORT_SYMBOL vmlinux 0x4c65e1e7 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0x4c8f6ada touch_atime +EXPORT_SYMBOL vmlinux 0x4ca9023a gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x4ca90a05 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0x4cb1ec8a llc_sap_close +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cc18945 bio_phys_segments +EXPORT_SYMBOL vmlinux 0x4cd80edf bio_unmap_user +EXPORT_SYMBOL vmlinux 0x4ce7361b sg_miter_stop +EXPORT_SYMBOL vmlinux 0x4cedce6b jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0x4cee17af pskb_copy +EXPORT_SYMBOL vmlinux 0x4cefd883 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0x4cf763af fddi_type_trans +EXPORT_SYMBOL vmlinux 0x4d2dc830 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0x4d3c153f sigprocmask +EXPORT_SYMBOL vmlinux 0x4d62a3cc inode_init_once +EXPORT_SYMBOL vmlinux 0x4d75704f simple_rename +EXPORT_SYMBOL vmlinux 0x4d992803 tcf_hash_create +EXPORT_SYMBOL vmlinux 0x4dd295fe rfkill_register +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e1be841 bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e4e4362 free_netdev +EXPORT_SYMBOL vmlinux 0x4e58bb96 tcp_check_req +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e7cb59c dst_alloc +EXPORT_SYMBOL vmlinux 0x4e830a3e strnicmp +EXPORT_SYMBOL vmlinux 0x4ebe2856 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x4efeb89b sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x4f3b36ea sync_page_range +EXPORT_SYMBOL vmlinux 0x4f417a7f scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x4f42b138 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4f560548 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x4f9ba4bc scsi_remove_target +EXPORT_SYMBOL vmlinux 0x4fb1da66 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0x4fbc2be3 inet_stream_ops +EXPORT_SYMBOL vmlinux 0x4fc804c9 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x4fd745a1 blk_sync_queue +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4fe873b4 ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x503e004d sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x504a41cf simple_link +EXPORT_SYMBOL vmlinux 0x5065cc11 cdrom_release +EXPORT_SYMBOL vmlinux 0x50694c04 ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x507cfc3e names_cachep +EXPORT_SYMBOL vmlinux 0x509ac417 __devm_request_region +EXPORT_SYMBOL vmlinux 0x509bfecd fasync_helper +EXPORT_SYMBOL vmlinux 0x509f7f06 netlink_unicast +EXPORT_SYMBOL vmlinux 0x50b21613 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x5102f786 skb_push +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x513fec90 tty_kref_put +EXPORT_SYMBOL vmlinux 0x5150613e md_unregister_thread +EXPORT_SYMBOL vmlinux 0x5152e605 memcmp +EXPORT_SYMBOL vmlinux 0x518eb764 per_cpu__cpu_number +EXPORT_SYMBOL vmlinux 0x519177a0 __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x519930df sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x51af4aa1 dm_register_target +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d55ad8 con_is_bound +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x51ef33b8 kstrndup +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x5222e1e2 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x5223115a bdput +EXPORT_SYMBOL vmlinux 0x523e038a udp_proc_register +EXPORT_SYMBOL vmlinux 0x5252adcc setup_arg_pages +EXPORT_SYMBOL vmlinux 0x525c1115 tcp_connect +EXPORT_SYMBOL vmlinux 0x5260f00d fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x526be42c inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x527162cc hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0x528c709d simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52aaeba9 sock_no_listen +EXPORT_SYMBOL vmlinux 0x52b471f5 kthread_create +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52e24296 key_validate +EXPORT_SYMBOL vmlinux 0x530a2241 journal_dirty_data +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x5328aa37 qdisc_list_del +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x53443401 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x534551b1 kernel_sendpage +EXPORT_SYMBOL vmlinux 0x535e4755 open_exec +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53984b1e xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0x53a2b2f1 hci_send_acl +EXPORT_SYMBOL vmlinux 0x53ac0d1e kernel_getpeername +EXPORT_SYMBOL vmlinux 0x53bb31ba pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0x53be78d7 igrab +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x53ca3770 may_umount +EXPORT_SYMBOL vmlinux 0x53d7b98f set_user_nice +EXPORT_SYMBOL vmlinux 0x53e1204a dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x53e35e7f mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0x540bbbf1 scsi_get_command +EXPORT_SYMBOL vmlinux 0x541b5dfc init_task +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x54351d09 netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x546f1de3 mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0x54935666 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0x54aa15dd dm_table_get_md +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x550395a3 pci_release_regions +EXPORT_SYMBOL vmlinux 0x553f9dd3 down_read_trylock +EXPORT_SYMBOL vmlinux 0x5542e3d7 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0x5558baa6 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x555984d1 dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55abd182 read_cache_page +EXPORT_SYMBOL vmlinux 0x55ac67d0 x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0x55c306e0 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x55c410a4 __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0x55c71d23 bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x55d46133 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x560d7ce5 udp_sendmsg +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x56171004 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x561c9b76 pci_find_bus +EXPORT_SYMBOL vmlinux 0x562d562f lookup_bdev +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x5651404b compute_creds +EXPORT_SYMBOL vmlinux 0x56788756 phy_detach +EXPORT_SYMBOL vmlinux 0x568f7c65 bio_pair_release +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x56ffae94 simple_empty +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x576c7f07 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x5784ceda sk_filter +EXPORT_SYMBOL vmlinux 0x57a6504e vsnprintf +EXPORT_SYMBOL vmlinux 0x57e12bc1 skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5849d553 genl_sock +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x588f676f tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x58aa51a2 block_write_full_page +EXPORT_SYMBOL vmlinux 0x58b89f08 skb_queue_tail +EXPORT_SYMBOL vmlinux 0x58d564bb elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0x58e06295 scsi_print_command +EXPORT_SYMBOL vmlinux 0x58fef6f8 ist_info +EXPORT_SYMBOL vmlinux 0x59025166 d_namespace_path +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x5938b325 inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x595126f7 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0x596693e3 neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x59866f8f blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0x59a4bf35 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0x59a6d3a7 input_grab_device +EXPORT_SYMBOL vmlinux 0x59d5307c i2c_verify_client +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x5a12892e kobject_put +EXPORT_SYMBOL vmlinux 0x5a200982 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5aa41c10 phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5aeab0f3 xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x5afe656f inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x5b19634d div_s64_rem +EXPORT_SYMBOL vmlinux 0x5b391e2b mem_map +EXPORT_SYMBOL vmlinux 0x5b41a64c udp_disconnect +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5b6ba14f phy_register_fixup +EXPORT_SYMBOL vmlinux 0x5b8d6ada dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0x5b933fab register_nls +EXPORT_SYMBOL vmlinux 0x5b9f70bc xfrm_input +EXPORT_SYMBOL vmlinux 0x5bbe5805 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x5bd81706 phy_connect +EXPORT_SYMBOL vmlinux 0x5c09fa85 inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x5c2be3b1 icmpv6_send +EXPORT_SYMBOL vmlinux 0x5c3fd9e8 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x5c5256ab xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x5c610acf serio_open +EXPORT_SYMBOL vmlinux 0x5c68705b mca_read_pos +EXPORT_SYMBOL vmlinux 0x5c7029ce scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x5c744d74 seq_open +EXPORT_SYMBOL vmlinux 0x5c7c6060 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0x5cd74b38 tty_register_driver +EXPORT_SYMBOL vmlinux 0x5cd9a8c5 pci_iounmap +EXPORT_SYMBOL vmlinux 0x5cfd59b2 tcp_disconnect +EXPORT_SYMBOL vmlinux 0x5d267e7c journal_update_format +EXPORT_SYMBOL vmlinux 0x5d3ecbfc skb_copy +EXPORT_SYMBOL vmlinux 0x5d41457e dev_get_by_flags +EXPORT_SYMBOL vmlinux 0x5d6eeac7 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5d991093 inet_frags_fini +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5df022e7 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0x5e3a3b92 is_container_init +EXPORT_SYMBOL vmlinux 0x5e62d517 put_filp +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e99be63 proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0x5e9b31b1 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ec7e93c scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x5ec9fac9 journal_init_inode +EXPORT_SYMBOL vmlinux 0x5eca982b proto_unregister +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5f12f8b4 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x5f1bd579 mca_find_adapter +EXPORT_SYMBOL vmlinux 0x5f26a9dd dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0x5f4042df pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0x5f6520f7 skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0x5f6b73d6 submit_bh +EXPORT_SYMBOL vmlinux 0x5f77f436 sget +EXPORT_SYMBOL vmlinux 0x5f9a75a2 vfs_statfs +EXPORT_SYMBOL vmlinux 0x5fd708bb jbd2_journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x5ffe0da3 bt_sock_poll +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x6025bb16 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x6063db68 vfs_link +EXPORT_SYMBOL vmlinux 0x60677ed5 llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60b56b6f xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0x60d78148 pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x61206548 blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x6130ce7e generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x615054f6 kmem_cache_create +EXPORT_SYMBOL vmlinux 0x618bac08 bio_integrity_trim +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x618ec3b8 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0x61a07099 skb_make_writable +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61c09949 ip_defrag +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6209a166 sock_setsockopt +EXPORT_SYMBOL vmlinux 0x62373106 flush_tlb_page +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x6241a2ab __copy_from_user_ll_nocache +EXPORT_SYMBOL vmlinux 0x6241fd2c acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0x624ad6a0 ndisc_mc_map +EXPORT_SYMBOL vmlinux 0x62672ec6 ip_route_output_key +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x6277527a elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x627fdeba aio_complete +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x62a2a610 generic_writepages +EXPORT_SYMBOL vmlinux 0x630ba180 cfb_copyarea +EXPORT_SYMBOL vmlinux 0x63230610 skb_clone +EXPORT_SYMBOL vmlinux 0x633e6231 jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0x6340f99b blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0x63496ddf __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0x634ead4b cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0x63699028 journal_wipe +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x637164b8 atm_init_aal5 +EXPORT_SYMBOL vmlinux 0x637bb655 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x6384fd27 serio_reconnect +EXPORT_SYMBOL vmlinux 0x63b50761 dma_pool_free +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x64039953 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6466cb5b dput +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x648d3aec scsi_free_command +EXPORT_SYMBOL vmlinux 0x648e450f pci_find_slot +EXPORT_SYMBOL vmlinux 0x648fc6ac serio_close +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64b4874a sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x64bbdac3 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x64fc745a fd_install +EXPORT_SYMBOL vmlinux 0x64fe2b06 dev_close +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x6539ed24 nobh_write_begin +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x6565d33f scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x6578225d find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x6581ef95 ppp_input_error +EXPORT_SYMBOL vmlinux 0x6598c2ac fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x65d3243f pci_select_bars +EXPORT_SYMBOL vmlinux 0x65de2cf4 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x66102419 journal_check_used_features +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66933549 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x66a0a4d2 mpage_readpage +EXPORT_SYMBOL vmlinux 0x66a9d854 d_alloc_name +EXPORT_SYMBOL vmlinux 0x66b3b231 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x66bfa400 i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x66c83aa1 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0x671c3f64 blk_put_request +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x6730a642 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x6733e5da elevator_init +EXPORT_SYMBOL vmlinux 0x673dbe54 __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x67502168 dm_io +EXPORT_SYMBOL vmlinux 0x675179c3 vfs_read +EXPORT_SYMBOL vmlinux 0x6782ca33 k8_northbridges +EXPORT_SYMBOL vmlinux 0x67a84d53 i2c_use_client +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67d6db39 register_qdisc +EXPORT_SYMBOL vmlinux 0x67e18dc2 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x682531b1 input_flush_device +EXPORT_SYMBOL vmlinux 0x682e14c2 blk_unplug +EXPORT_SYMBOL vmlinux 0x682f5c40 inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0x6845e9fc call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x685a22e5 km_policy_notify +EXPORT_SYMBOL vmlinux 0x685b8f39 kill_pid +EXPORT_SYMBOL vmlinux 0x686caaff __find_get_block +EXPORT_SYMBOL vmlinux 0x688ccaeb inet_select_addr +EXPORT_SYMBOL vmlinux 0x689ceb11 netlink_ack +EXPORT_SYMBOL vmlinux 0x68cbb76c bio_add_page +EXPORT_SYMBOL vmlinux 0x68d7f68f sk_run_filter +EXPORT_SYMBOL vmlinux 0x6956ca69 tty_free_termios +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x698ec46d filemap_flush +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69a358a6 iomem_resource +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69f26828 kobject_set_name +EXPORT_SYMBOL vmlinux 0x69fccdd5 iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a27bfce csum_partial_copy_generic +EXPORT_SYMBOL vmlinux 0x6a294557 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x6a34e291 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a519288 blkdev_get +EXPORT_SYMBOL vmlinux 0x6a6cc4bb key_payload_reserve +EXPORT_SYMBOL vmlinux 0x6a789ca3 kill_litter_super +EXPORT_SYMBOL vmlinux 0x6a78c985 vfs_write +EXPORT_SYMBOL vmlinux 0x6a98ca45 vfs_unlink +EXPORT_SYMBOL vmlinux 0x6aae09de gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0x6ac019bc redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6af5c120 __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x6b07ef5f generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b1e8c1f journal_clear_err +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b35cf5e inet_frag_kill +EXPORT_SYMBOL vmlinux 0x6b54995e atm_dev_lookup +EXPORT_SYMBOL vmlinux 0x6b5e02bb inet_csk_accept +EXPORT_SYMBOL vmlinux 0x6b8b2ce4 generic_block_bmap +EXPORT_SYMBOL vmlinux 0x6b937ffb mca_mark_as_used +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bd16c80 journal_restart +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6c1ce5ce strcspn +EXPORT_SYMBOL vmlinux 0x6c2e3320 strncmp +EXPORT_SYMBOL vmlinux 0x6c308358 load_nls +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c619b0b inet_release +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c7b1d61 hci_connect +EXPORT_SYMBOL vmlinux 0x6c82b158 arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0x6c8385e1 dma_supported +EXPORT_SYMBOL vmlinux 0x6c8ef8b8 scsi_put_command +EXPORT_SYMBOL vmlinux 0x6cb3039e kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0x6cdc5c6b nla_strlcpy +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d10832b key_put +EXPORT_SYMBOL vmlinux 0x6d1af93c blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d288375 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d356fc3 tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x6d51d7c2 dquot_commit +EXPORT_SYMBOL vmlinux 0x6d73c153 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0x6d8b30b7 generic_read_dir +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6dccfb7b xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x6dcf4d24 kmap +EXPORT_SYMBOL vmlinux 0x6dd1e028 kill_anon_super +EXPORT_SYMBOL vmlinux 0x6dee7be5 dump_fpu +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e3d809c remove_arg_zero +EXPORT_SYMBOL vmlinux 0x6e440b58 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e95969a request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ea23c6d scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x6ea98ca5 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ee7b853 md_check_recovery +EXPORT_SYMBOL vmlinux 0x6efe099f bitmap_end_sync +EXPORT_SYMBOL vmlinux 0x6f19ab56 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0x6f26028a inet_sock_destruct +EXPORT_SYMBOL vmlinux 0x6fa46cc3 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x6facd3d8 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fcf5a30 unregister_8022_client +EXPORT_SYMBOL vmlinux 0x6fdd2205 redraw_screen +EXPORT_SYMBOL vmlinux 0x6fea5ca5 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0x6ff1059a proc_create_data +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x701d0ebd snprintf +EXPORT_SYMBOL vmlinux 0x70461a22 key_revoke +EXPORT_SYMBOL vmlinux 0x704a77db skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x707081b3 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x70d1f8f3 strncat +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x71002f3b dma_mark_declared_memory_occupied +EXPORT_SYMBOL vmlinux 0x710a6eea i2c_attach_client +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x713046c8 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x71472ea7 scsi_unregister +EXPORT_SYMBOL vmlinux 0x7151a904 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x7171dddd proto_register +EXPORT_SYMBOL vmlinux 0x71a0627f call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0x71a426ec vm_insert_page +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x72150358 mca_device_set_claim +EXPORT_SYMBOL vmlinux 0x72234e66 pci_scan_slot +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x722f2b09 bitmap_endwrite +EXPORT_SYMBOL vmlinux 0x7257ab1a skb_checksum +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x7270a4ab tcf_em_unregister +EXPORT_SYMBOL vmlinux 0x728b0b39 pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x72aa4e44 block_read_full_page +EXPORT_SYMBOL vmlinux 0x72ae6902 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72cee3b4 ipv4_specific +EXPORT_SYMBOL vmlinux 0x72df8bf0 ps2_command +EXPORT_SYMBOL vmlinux 0x72e1c1c9 blk_start_queueing +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x730c073f user_path_at +EXPORT_SYMBOL vmlinux 0x730e8013 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x7316fc07 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x7373bf16 neigh_seq_stop +EXPORT_SYMBOL vmlinux 0x737af40e sock_recvmsg +EXPORT_SYMBOL vmlinux 0x738803e6 strnlen +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x739dce60 journal_stop +EXPORT_SYMBOL vmlinux 0x73c87fc2 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x73d51377 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x73d80fb9 ip6_frag_match +EXPORT_SYMBOL vmlinux 0x73e20c1c strlcpy +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x7413793a EISA_bus +EXPORT_SYMBOL vmlinux 0x7416cdb4 pci_map_rom +EXPORT_SYMBOL vmlinux 0x7457124b pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x7460fffd deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0x746c8f0b ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0x746f5f68 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x749e1aed scsi_host_get +EXPORT_SYMBOL vmlinux 0x74a4b705 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x750d70a6 loop_register_transfer +EXPORT_SYMBOL vmlinux 0x7517f2a3 pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x75271716 save_processor_state +EXPORT_SYMBOL vmlinux 0x75566739 complete_request_key +EXPORT_SYMBOL vmlinux 0x7558628b ip_ct_attach +EXPORT_SYMBOL vmlinux 0x75761332 kmap_high +EXPORT_SYMBOL vmlinux 0x75786506 ps2_sendbyte +EXPORT_SYMBOL vmlinux 0x758a15ba register_key_type +EXPORT_SYMBOL vmlinux 0x75ad29ac generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x75b3095f scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x75cd7893 send_sig_info +EXPORT_SYMBOL vmlinux 0x7600807f scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x761073f5 proc_net_netfilter +EXPORT_SYMBOL vmlinux 0x763a7a1e inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x764bd77c request_resource +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76e8e9e1 netif_rx +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x7708809b unregister_cdrom +EXPORT_SYMBOL vmlinux 0x770a0036 isapnp_cfg_begin +EXPORT_SYMBOL vmlinux 0x7735c910 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x778fba1e register_binfmt +EXPORT_SYMBOL vmlinux 0x7791bfdb __elv_add_request +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77ab1abf page_symlink +EXPORT_SYMBOL vmlinux 0x77b9589b neigh_event_ns +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x784209c8 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0x7868981a blk_init_tags +EXPORT_SYMBOL vmlinux 0x7890ceec journal_errno +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78b50d63 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0x78b65f2a fb_find_mode +EXPORT_SYMBOL vmlinux 0x78cb2783 down_write_trylock +EXPORT_SYMBOL vmlinux 0x78cb8915 skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x78faa102 netdev_features_change +EXPORT_SYMBOL vmlinux 0x78fdec91 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0x7919c805 scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x794487ee disable_hlt +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x797882a3 scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x7979b316 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x7a0712e9 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a3ff5b8 inet_addr_type +EXPORT_SYMBOL vmlinux 0x7a4cd13e set_pages_x +EXPORT_SYMBOL vmlinux 0x7a6bc608 proc_dointvec +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7ac78e52 scsi_execute +EXPORT_SYMBOL vmlinux 0x7ad75de3 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0x7ae379ac pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7aff155f tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0x7b01bd1f bdevname +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b0f4cd6 fb_blank +EXPORT_SYMBOL vmlinux 0x7b134ddf acpi_get_name +EXPORT_SYMBOL vmlinux 0x7b26c6ed scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x7b28e55b simple_statfs +EXPORT_SYMBOL vmlinux 0x7b351b36 km_new_mapping +EXPORT_SYMBOL vmlinux 0x7b3d1910 check_disk_size_change +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b54254d ppp_input +EXPORT_SYMBOL vmlinux 0x7b69467e posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0x7b815123 mmc_free_host +EXPORT_SYMBOL vmlinux 0x7b83bf6c create_empty_buffers +EXPORT_SYMBOL vmlinux 0x7b87823e kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x7b9ff04d inode_double_unlock +EXPORT_SYMBOL vmlinux 0x7bc52287 devm_ioport_map +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7be5b223 dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0x7be6bb8a tcf_em_register +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c61340c __release_region +EXPORT_SYMBOL vmlinux 0x7c627e6d tcf_hash_check +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7c9ada55 xfrm_nl +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cc0e180 eth_header +EXPORT_SYMBOL vmlinux 0x7cfc9180 get_sb_nodev +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d1b82a5 ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x7d284f59 bio_init +EXPORT_SYMBOL vmlinux 0x7d3e3b58 destroy_EII_client +EXPORT_SYMBOL vmlinux 0x7d5f7bbc mdiobus_scan +EXPORT_SYMBOL vmlinux 0x7d69b957 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x7d79a978 request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7da9e65d eisa_driver_register +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7e16883f unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0x7e18da4b dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0x7e2bfe86 mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x7e3e7d2e hci_unregister_cb +EXPORT_SYMBOL vmlinux 0x7e42903f acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0x7e5297a6 task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0x7e648921 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7eb86d81 i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x7eca4b61 jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7efbb53d filp_open +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f41bb29 search_binary_handler +EXPORT_SYMBOL vmlinux 0x7f5728af key_type_keyring +EXPORT_SYMBOL vmlinux 0x7f6b0ab3 read_cache_pages +EXPORT_SYMBOL vmlinux 0x7f76395b skb_dma_map +EXPORT_SYMBOL vmlinux 0x7f798d54 fb_pan_display +EXPORT_SYMBOL vmlinux 0x7f7a1b86 dev_load +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7f9f5d27 bt_sock_register +EXPORT_SYMBOL vmlinux 0x7fc19b3c mmc_detect_change +EXPORT_SYMBOL vmlinux 0x7fef28ec kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0x800f15a1 open_by_devnum +EXPORT_SYMBOL vmlinux 0x8013d773 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0x801725a4 journal_revoke +EXPORT_SYMBOL vmlinux 0x8026ec02 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0x804a7ba1 bdi_destroy +EXPORT_SYMBOL vmlinux 0x80528ad5 scsi_add_device +EXPORT_SYMBOL vmlinux 0x805dbbd2 dma_release_from_coherent +EXPORT_SYMBOL vmlinux 0x8063f83d radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x8082460c arp_tbl +EXPORT_SYMBOL vmlinux 0x808e3ce2 jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0x80c5e6e3 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0x80dc5c06 genphy_config_advert +EXPORT_SYMBOL vmlinux 0x813379c9 bio_clone +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x81799cee vscnprintf +EXPORT_SYMBOL vmlinux 0x817c2a3c blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0x81b7569a __alloc_skb +EXPORT_SYMBOL vmlinux 0x81ba5554 __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x81d92d26 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x82009c0a bdi_unregister +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x82250053 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x822ecf83 unbind_con_driver +EXPORT_SYMBOL vmlinux 0x8235805b memmove +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82673561 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x8267cfed ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x826cecd5 inet_ioctl +EXPORT_SYMBOL vmlinux 0x828f6b2b request_key_async +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x830e547b ioremap_prot +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x831bb49a netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83df2c1b wireless_spy_update +EXPORT_SYMBOL vmlinux 0x83e0ec55 ip_getsockopt +EXPORT_SYMBOL vmlinux 0x83ea937e tty_devnum +EXPORT_SYMBOL vmlinux 0x84265db3 pnp_device_attach +EXPORT_SYMBOL vmlinux 0x8454cb23 atm_alloc_charge +EXPORT_SYMBOL vmlinux 0x8458882a request_firmware +EXPORT_SYMBOL vmlinux 0x8488ed56 register_con_driver +EXPORT_SYMBOL vmlinux 0x84c10f36 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x8503fc39 dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0x85047d88 cfb_fillrect +EXPORT_SYMBOL vmlinux 0x85100118 uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x854f3820 km_state_notify +EXPORT_SYMBOL vmlinux 0x856310bc pci_pme_capable +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x8573b31a netif_rx_ni +EXPORT_SYMBOL vmlinux 0x8587d510 pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x858baa40 cdev_del +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85e28217 __napi_schedule +EXPORT_SYMBOL vmlinux 0x85e7deb2 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x85efa29a inode_needs_sync +EXPORT_SYMBOL vmlinux 0x8632673a skb_insert +EXPORT_SYMBOL vmlinux 0x863454a6 find_lock_page +EXPORT_SYMBOL vmlinux 0x8639b9c0 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x8682f352 skb_pad +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x869da119 journal_set_features +EXPORT_SYMBOL vmlinux 0x869e2e94 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x86c68afc audit_log_format +EXPORT_SYMBOL vmlinux 0x86e621c3 __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x8707076c dev_change_flags +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x87409807 set_pages_wb +EXPORT_SYMBOL vmlinux 0x8742fc32 i2c_master_recv +EXPORT_SYMBOL vmlinux 0x874df003 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x87612a76 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0x8767a660 block_write_begin +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x876def50 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0x876fb381 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x8781813f kernel_bind +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87c513e5 bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0x87ec7e2e xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0x87f6e9f3 vfs_readv +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x88272f1d zero_fill_bio +EXPORT_SYMBOL vmlinux 0x883156e4 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0x8836c863 tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0x883e354e default_llseek +EXPORT_SYMBOL vmlinux 0x88494f4f make_EII_client +EXPORT_SYMBOL vmlinux 0x8858b0d7 do_splice_from +EXPORT_SYMBOL vmlinux 0x889a00ad rt6_lookup +EXPORT_SYMBOL vmlinux 0x88e86e33 mca_device_read_pos +EXPORT_SYMBOL vmlinux 0x88ef8a7a pcim_iomap +EXPORT_SYMBOL vmlinux 0x890db3f9 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x892223ee scm_detach_fds +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x89368404 mca_device_status +EXPORT_SYMBOL vmlinux 0x893a724f end_page_writeback +EXPORT_SYMBOL vmlinux 0x8949858b schedule_work +EXPORT_SYMBOL vmlinux 0x894b1bcd tty_port_init +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x8969b997 ida_get_new +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x898eda8b gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x8990cf50 tty_name +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89d7a6e8 seq_open_private +EXPORT_SYMBOL vmlinux 0x89e40708 pci_request_regions +EXPORT_SYMBOL vmlinux 0x89e9b5ba set_binfmt +EXPORT_SYMBOL vmlinux 0x89f789cd bio_uncopy_user +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a914643 blk_register_region +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8abb1e18 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x8ac477fe mmc_add_host +EXPORT_SYMBOL vmlinux 0x8aec4fa1 netif_receive_skb +EXPORT_SYMBOL vmlinux 0x8b18496f __copy_to_user_ll +EXPORT_SYMBOL vmlinux 0x8b35e873 sg_last +EXPORT_SYMBOL vmlinux 0x8b47558f brioctl_set +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b5fdb4d llc_sap_open +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b6227e9 balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0x8b66ddd5 bio_integrity_free +EXPORT_SYMBOL vmlinux 0x8b7e4a58 ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8baac15c page_put_link +EXPORT_SYMBOL vmlinux 0x8bb0187e mdio_bus_type +EXPORT_SYMBOL vmlinux 0x8bfbe57e mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x8c12c4b7 del_gendisk +EXPORT_SYMBOL vmlinux 0x8c17b085 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c43d338 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x8cb35402 dev_mc_delete +EXPORT_SYMBOL vmlinux 0x8cbd606b i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x8cc1ca97 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8d09fc84 blk_verify_command +EXPORT_SYMBOL vmlinux 0x8d2ccb94 seq_path +EXPORT_SYMBOL vmlinux 0x8d37f690 mca_device_read_stored_pos +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d4c9b61 mca_register_driver +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d569ca9 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x8d626d8b pci_get_slot +EXPORT_SYMBOL vmlinux 0x8d66e694 __serio_register_port +EXPORT_SYMBOL vmlinux 0x8d6f81b4 __div64_32 +EXPORT_SYMBOL vmlinux 0x8d70609b try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x8d817c7a sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8d95a0ec generic_make_request +EXPORT_SYMBOL vmlinux 0x8d9e2733 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x8db8c254 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0x8dc6e564 restore_processor_state +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e45d9a8 unlock_super +EXPORT_SYMBOL vmlinux 0x8e4dd831 force_sig +EXPORT_SYMBOL vmlinux 0x8e5df493 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8e77009e fb_set_cmap +EXPORT_SYMBOL vmlinux 0x8e9fd4bb unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x8eb0a301 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x8ec13624 pci_scan_bridge +EXPORT_SYMBOL vmlinux 0x8f056386 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x8f067e2f posix_acl_permission +EXPORT_SYMBOL vmlinux 0x8f2e2c74 mpage_writepages +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f82f880 generic_file_aio_write +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8fab1a07 scsi_register_driver +EXPORT_SYMBOL vmlinux 0x8fb85b30 kthread_bind +EXPORT_SYMBOL vmlinux 0x8ffdb3b8 crc16 +EXPORT_SYMBOL vmlinux 0x8ffe0a6a dst_destroy +EXPORT_SYMBOL vmlinux 0x8fff2b69 inode_change_ok +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x904c29bd genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0x904d25a2 boot_cpu_data +EXPORT_SYMBOL vmlinux 0x904ef64d sock_i_uid +EXPORT_SYMBOL vmlinux 0x90971384 find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a1d206 elv_rb_del +EXPORT_SYMBOL vmlinux 0x90a4343e textsearch_destroy +EXPORT_SYMBOL vmlinux 0x90a44fb8 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90c7a6e1 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x915fd44d task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x91c6e907 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x922b9eaf pnp_disable_dev +EXPORT_SYMBOL vmlinux 0x922bf749 generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x922dd2cc tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x922ff447 eisa_bus_type +EXPORT_SYMBOL vmlinux 0x924fe965 kmem_cache_name +EXPORT_SYMBOL vmlinux 0x925bc0e9 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0x925f9c1a netif_carrier_on +EXPORT_SYMBOL vmlinux 0x9283d77e i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0x92897e3d default_idle +EXPORT_SYMBOL vmlinux 0x928b0b3e tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x928bdb7e eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x928fd5f1 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0x92947d15 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x92a55d5c nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x92b731d0 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x92d2f247 jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0x92df0ff2 sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x92f37a81 bitmap_unplug +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x9312ef2b dmam_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x934f3f37 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x9363de3b nla_append +EXPORT_SYMBOL vmlinux 0x9381d62c uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x939a5e6d unlock_page +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93ba6e14 skb_under_panic +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93d4363e udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x940f4b26 __breadahead +EXPORT_SYMBOL vmlinux 0x943e1309 unregister_md_personality +EXPORT_SYMBOL vmlinux 0x94646a11 vfs_dq_drop +EXPORT_SYMBOL vmlinux 0x947d0662 pci_enable_msi +EXPORT_SYMBOL vmlinux 0x94844e66 mdiobus_free +EXPORT_SYMBOL vmlinux 0x949406a4 pci_find_capability +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x94969691 cont_write_begin +EXPORT_SYMBOL vmlinux 0x9498667d genl_register_ops +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x94feb71f mdiobus_write +EXPORT_SYMBOL vmlinux 0x950dba9f pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0x95352ea9 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x95497939 kernel_setsockopt +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x956234d6 __nla_reserve +EXPORT_SYMBOL vmlinux 0x95859817 __lookup_hash +EXPORT_SYMBOL vmlinux 0x95eaba58 mca_unregister_driver +EXPORT_SYMBOL vmlinux 0x95f638d5 posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x95fe5e6c console_stop +EXPORT_SYMBOL vmlinux 0x96314de9 i2c_master_send +EXPORT_SYMBOL vmlinux 0x9634498a rfkill_allocate +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x965000f7 journal_load +EXPORT_SYMBOL vmlinux 0x965bc983 dev_mc_unsync +EXPORT_SYMBOL vmlinux 0x966fb0e0 __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x9677bece flush_signals +EXPORT_SYMBOL vmlinux 0x96898769 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0x9692002c d_path +EXPORT_SYMBOL vmlinux 0x96b8608c udplite_prot +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x970e6e0e aio_put_req +EXPORT_SYMBOL vmlinux 0x9727e36b journal_extend +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x979a3789 hci_resume_dev +EXPORT_SYMBOL vmlinux 0x97a1a098 pci_set_master +EXPORT_SYMBOL vmlinux 0x97a21cc0 tcp_close +EXPORT_SYMBOL vmlinux 0x97ba8e8e mmc_resume_host +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x97e02407 elv_add_request +EXPORT_SYMBOL vmlinux 0x98034a42 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x981026f6 km_report +EXPORT_SYMBOL vmlinux 0x9848537d scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x984f55ef ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0x986527d2 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x986feff8 bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x9873f554 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0x988121dc serio_rescan +EXPORT_SYMBOL vmlinux 0x98884059 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x98b089b0 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0x98c6394f tc_classify +EXPORT_SYMBOL vmlinux 0x98e0e4d4 arp_xmit +EXPORT_SYMBOL vmlinux 0x99052a84 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x990fee5c blk_alloc_queue +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99bde738 dm_table_put +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99c3c0b0 vfs_fstat +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99e2d6de __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x99eac64f proc_dostring +EXPORT_SYMBOL vmlinux 0x99f1536f sync_blockdev +EXPORT_SYMBOL vmlinux 0x9a0c9de7 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x9a1741cf dma_ops +EXPORT_SYMBOL vmlinux 0x9a184d22 nf_getsockopt +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a2146b2 skb_dequeue +EXPORT_SYMBOL vmlinux 0x9a6a83f9 cmos_lock +EXPORT_SYMBOL vmlinux 0x9a6d9896 log_wait_commit +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a714920 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0x9a8814db sock_no_poll +EXPORT_SYMBOL vmlinux 0x9a88646a kick_iocb +EXPORT_SYMBOL vmlinux 0x9a9814a9 console_start +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9ac72c28 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x9ae172d7 tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x9af1a545 pcie_port_service_register +EXPORT_SYMBOL vmlinux 0x9b1585b1 inet_stream_connect +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b4de8eb idr_replace +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bb6b150 skb_pull +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c07e7d0 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x9c1f609e blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x9c2c944a __copy_from_user_ll_nocache_nozero +EXPORT_SYMBOL vmlinux 0x9c491f60 sg_alloc_table +EXPORT_SYMBOL vmlinux 0x9c613afe inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0x9c7077bd enable_hlt +EXPORT_SYMBOL vmlinux 0x9c7d0d97 vcc_insert_socket +EXPORT_SYMBOL vmlinux 0x9ca6730d write_one_page +EXPORT_SYMBOL vmlinux 0x9caee725 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9cd8127f pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0x9ceb163c memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d3fc972 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x9d52cf39 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x9d55c69d hci_unregister_proto +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9d7795d9 cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x9d909d69 send_sig +EXPORT_SYMBOL vmlinux 0x9d9f0d41 rwsem_down_write_failed +EXPORT_SYMBOL vmlinux 0x9dad6cad i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x9daebd3d pci_enable_msix +EXPORT_SYMBOL vmlinux 0x9dd5a94a nf_register_hooks +EXPORT_SYMBOL vmlinux 0x9df8846e per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0x9e04f5e2 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0x9e094e71 phy_attach +EXPORT_SYMBOL vmlinux 0x9e26f1a2 key_unlink +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e3cc838 devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x9e471961 jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0x9e4b3747 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x9e548311 blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e68a7de blk_insert_request +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9ea0ad49 __sg_free_table +EXPORT_SYMBOL vmlinux 0x9ea8f3c1 blk_plug_device +EXPORT_SYMBOL vmlinux 0x9ebd4c04 adjust_resource +EXPORT_SYMBOL vmlinux 0x9ed685ee iov_iter_advance +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9eecf6e9 vfs_readdir +EXPORT_SYMBOL vmlinux 0x9ef42842 pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f16258b dma_declare_coherent_memory +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f3e93f2 tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0x9f4bdc62 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x9f4bfdbe jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0x9f637353 d_alloc_root +EXPORT_SYMBOL vmlinux 0x9f809963 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9f9d64e3 dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9fb3dd30 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9ffd5c59 neigh_seq_next +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa0386e63 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xa03e8eee cap_netlink_recv +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa0504832 sk_stream_error +EXPORT_SYMBOL vmlinux 0xa05989aa scsi_device_put +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa076f6ab sock_kmalloc +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0e115d1 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0xa0e1274f inet_getname +EXPORT_SYMBOL vmlinux 0xa0e26317 pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa10888a2 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa12efa78 unregister_qdisc +EXPORT_SYMBOL vmlinux 0xa1327892 try_to_release_page +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa138cc93 proc_mkdir +EXPORT_SYMBOL vmlinux 0xa14c0f60 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0xa154ae00 nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0xa1a2b53f simple_dir_operations +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1c4289f bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0xa1c58a7e bdev_read_only +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1d05c51 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0xa1d442fa acpi_bus_add +EXPORT_SYMBOL vmlinux 0xa1fa31e6 i2c_detach_client +EXPORT_SYMBOL vmlinux 0xa1ff8dde d_lookup +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa2131ece xfrm_register_type +EXPORT_SYMBOL vmlinux 0xa231f450 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xa25c87c2 i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0xa25fa3ac pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0xa28f2913 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xa28f7213 con_copy_unimap +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2af4a3a tty_hangup +EXPORT_SYMBOL vmlinux 0xa2d1906c register_framebuffer +EXPORT_SYMBOL vmlinux 0xa2e1bc9a journal_destroy +EXPORT_SYMBOL vmlinux 0xa2f31189 pci_pme_active +EXPORT_SYMBOL vmlinux 0xa308d5ba ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0xa325d466 acpi_is_video_device +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa32cd72b scsi_ioctl +EXPORT_SYMBOL vmlinux 0xa34f1ef5 crc32_le +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa35c1f05 acpi_extract_package +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa3602340 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0xa3824c5f sysctl_intvec +EXPORT_SYMBOL vmlinux 0xa38c56f4 nf_ct_attach +EXPORT_SYMBOL vmlinux 0xa3a824f2 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0xa3b011b0 scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xa3b51587 elv_rb_add +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3bddc13 bh_submit_read +EXPORT_SYMBOL vmlinux 0xa3c0d4e2 __kill_fasync +EXPORT_SYMBOL vmlinux 0xa3d6896a blkdev_put +EXPORT_SYMBOL vmlinux 0xa3f07238 dm_table_get_mode +EXPORT_SYMBOL vmlinux 0xa3fba285 generic_permission +EXPORT_SYMBOL vmlinux 0xa40826ad pcim_enable_device +EXPORT_SYMBOL vmlinux 0xa422a5a7 __neigh_event_send +EXPORT_SYMBOL vmlinux 0xa422b36f kset_register +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa47e8791 neigh_lookup +EXPORT_SYMBOL vmlinux 0xa4b356a1 scsi_remove_device +EXPORT_SYMBOL vmlinux 0xa4b62060 pci_set_mwi +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4c195b9 generic_getxattr +EXPORT_SYMBOL vmlinux 0xa4ddf534 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa4f580df simple_sync_file +EXPORT_SYMBOL vmlinux 0xa50afc15 handle_sysrq +EXPORT_SYMBOL vmlinux 0xa51cdfe8 __FIXADDR_TOP +EXPORT_SYMBOL vmlinux 0xa52616b3 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0xa5373be6 kobject_del +EXPORT_SYMBOL vmlinux 0xa538b48a pnp_find_dev +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa56280d6 start_tty +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa569b900 bt_accept_unlink +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa57a5716 uart_add_one_port +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa58f17ed scsi_init_io +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa5a75747 tcf_register_action +EXPORT_SYMBOL vmlinux 0xa5caeb68 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0xa5da0abd acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0xa5fdf878 filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0xa60ca8a9 vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0xa6189898 linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa641ff7c tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa6741270 filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0xa67d54a4 netpoll_setup +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa6814433 groups_free +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa6c57620 lock_super +EXPORT_SYMBOL vmlinux 0xa6cf8d9b ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6f02a47 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0xa6f9b9de cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0xa7046549 vprintk +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa729d3ce arp_find +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa770b803 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0xa78182ca blk_free_tags +EXPORT_SYMBOL vmlinux 0xa78913d3 pci_find_device +EXPORT_SYMBOL vmlinux 0xa795ae6e blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xa7bf5883 sk_dst_check +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa800c18e sysctl_jiffies +EXPORT_SYMBOL vmlinux 0xa82ebffd serio_unregister_port +EXPORT_SYMBOL vmlinux 0xa83a822e km_query +EXPORT_SYMBOL vmlinux 0xa89acbb3 acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xa8a6f639 __check_region +EXPORT_SYMBOL vmlinux 0xa8b2f666 scsi_block_requests +EXPORT_SYMBOL vmlinux 0xa8c9639d __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0xa8e913ea kmap_atomic +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa90174fd acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0xa91110e6 alloc_fddidev +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa9315131 __mpage_writepage +EXPORT_SYMBOL vmlinux 0xa931c312 alloc_file +EXPORT_SYMBOL vmlinux 0xa93701c2 fput +EXPORT_SYMBOL vmlinux 0xa9a14377 unregister_key_type +EXPORT_SYMBOL vmlinux 0xa9c39bbe seq_release_private +EXPORT_SYMBOL vmlinux 0xa9c584ee bt_sock_unlink +EXPORT_SYMBOL vmlinux 0xa9d8f2d9 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa07b21c journal_lock_updates +EXPORT_SYMBOL vmlinux 0xaa29728a pagecache_write_begin +EXPORT_SYMBOL vmlinux 0xaa374ddf iget5_locked +EXPORT_SYMBOL vmlinux 0xaa3aa11d do_SAK +EXPORT_SYMBOL vmlinux 0xaa600880 bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0xaa6bb5ed skb_copy_bits +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaa8f70dc mdiobus_register +EXPORT_SYMBOL vmlinux 0xaaaf3081 d_genocide +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaaebe34f mca_write_pos +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab167257 file_permission +EXPORT_SYMBOL vmlinux 0xab246a78 nf_setsockopt +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xab868370 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0xab8ccf4d bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0xab9ecdce pci_reenable_device +EXPORT_SYMBOL vmlinux 0xaba9ff34 allocate_resource +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabfc6165 uart_get_divisor +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xac6f0c71 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0xac6fb77f ip6_route_output +EXPORT_SYMBOL vmlinux 0xac84957f vmap +EXPORT_SYMBOL vmlinux 0xac8aaea3 dev_get_flags +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xace13719 iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0xacea4ca5 input_register_handler +EXPORT_SYMBOL vmlinux 0xaceea69b get_write_access +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad1566a6 phy_start +EXPORT_SYMBOL vmlinux 0xad273169 get_phy_id +EXPORT_SYMBOL vmlinux 0xad48a587 new_inode +EXPORT_SYMBOL vmlinux 0xad49d2ce scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0xad6da359 generic_delete_inode +EXPORT_SYMBOL vmlinux 0xad7de09a d_prune_aliases +EXPORT_SYMBOL vmlinux 0xad8b7fd0 bio_kmalloc +EXPORT_SYMBOL vmlinux 0xad905cd4 neigh_create +EXPORT_SYMBOL vmlinux 0xad97995b hci_conn_auth +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadb44819 proc_symlink +EXPORT_SYMBOL vmlinux 0xaddb004e generic_show_options +EXPORT_SYMBOL vmlinux 0xadebf237 tty_throttle +EXPORT_SYMBOL vmlinux 0xae1e5c4d hci_register_proto +EXPORT_SYMBOL vmlinux 0xae3059fe skb_queue_purge +EXPORT_SYMBOL vmlinux 0xae3e2a3c scsi_release_buffers +EXPORT_SYMBOL vmlinux 0xae709946 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0xae75f004 ida_destroy +EXPORT_SYMBOL vmlinux 0xaec655c7 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0xaecc34f3 blk_recount_segments +EXPORT_SYMBOL vmlinux 0xaedf49e8 nf_log_packet +EXPORT_SYMBOL vmlinux 0xaedf67db pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0xaf0c473f vm_insert_pfn +EXPORT_SYMBOL vmlinux 0xaf29582e dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf4b1540 acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf5ac56a page_readlink +EXPORT_SYMBOL vmlinux 0xaf63af12 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0xaf6d161b dcache_dir_close +EXPORT_SYMBOL vmlinux 0xaf760dec dquot_transfer +EXPORT_SYMBOL vmlinux 0xaf7e5e10 dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0xafb2ef14 lock_sock_nested +EXPORT_SYMBOL vmlinux 0xafb6c250 md_write_start +EXPORT_SYMBOL vmlinux 0xafc50f91 dget_locked +EXPORT_SYMBOL vmlinux 0xafe01377 down_read +EXPORT_SYMBOL vmlinux 0xaff8d5a4 vm_map_ram +EXPORT_SYMBOL vmlinux 0xb067ea2e acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0xb077ef32 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb08f76ad gen_pool_free +EXPORT_SYMBOL vmlinux 0xb0ac8813 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0xb0acb8d3 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xb0af2558 skb_over_panic +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0d20593 blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb13c4dba down_write +EXPORT_SYMBOL vmlinux 0xb1526718 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0xb15b7152 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xb1645a2e sg_free_table +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1b08eb1 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1caffe3 blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1ddf924 pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0xb1e6e678 bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0xb1ea5dc7 blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0xb1ebaa0e do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb21446a4 seq_read +EXPORT_SYMBOL vmlinux 0xb21bdb25 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb29bc8bd idr_remove +EXPORT_SYMBOL vmlinux 0xb2bf7fc6 clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0xb2d0c779 sk_wait_data +EXPORT_SYMBOL vmlinux 0xb2efb6be mca_read_stored_pos +EXPORT_SYMBOL vmlinux 0xb2f4f6c8 vfs_symlink +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb307b96d i2c_del_driver +EXPORT_SYMBOL vmlinux 0xb30abf8d idr_get_new_above +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb35188ef sock_wake_async +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3691086 sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb370c357 simple_write_begin +EXPORT_SYMBOL vmlinux 0xb376d79d radix_tree_tagged +EXPORT_SYMBOL vmlinux 0xb38862bf get_sb_single +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3a54b88 inet6_del_protocol +EXPORT_SYMBOL vmlinux 0xb3ade72d nobh_write_end +EXPORT_SYMBOL vmlinux 0xb3cc268b end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0xb3d438e2 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0xb3e0590d acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0xb4125e2d pneigh_lookup +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb429410a posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0xb43e2380 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0xb44df7b9 pci_unmap_rom +EXPORT_SYMBOL vmlinux 0xb45578b8 memscan +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb46bacc9 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0xb48a4bd7 mmc_release_host +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4954aa2 misc_deregister +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb53a0aa3 blk_start_queue +EXPORT_SYMBOL vmlinux 0xb53c606a submit_bio +EXPORT_SYMBOL vmlinux 0xb53f2879 bmap +EXPORT_SYMBOL vmlinux 0xb540fe9d bio_integrity_clone +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb54561fd blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0xb5540ae8 kernel_getsockopt +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5bc449a read_dev_sector +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5db80f6 generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xb5eff348 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb61d4061 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0xb6244511 sg_init_one +EXPORT_SYMBOL vmlinux 0xb62ea19a vcc_release_async +EXPORT_SYMBOL vmlinux 0xb63029c3 generic_file_mmap +EXPORT_SYMBOL vmlinux 0xb64e5028 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0xb67383d4 arp_send +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb67bf618 udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xb67e5778 pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xb6896671 crc_t10dif +EXPORT_SYMBOL vmlinux 0xb6933647 sock_no_connect +EXPORT_SYMBOL vmlinux 0xb69348b1 __sk_dst_check +EXPORT_SYMBOL vmlinux 0xb696fe5a xrlim_allow +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6b85f46 xfrm_init_state +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6df2ca9 atm_dev_register +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6ed1e53 strncpy +EXPORT_SYMBOL vmlinux 0xb703911e release_firmware +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb72397d5 printk +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb755a0db acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb7709894 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0xb7b61546 crc32_be +EXPORT_SYMBOL vmlinux 0xb7c0086f vfs_readlink +EXPORT_SYMBOL vmlinux 0xb7d13f4d unload_nls +EXPORT_SYMBOL vmlinux 0xb7e2786a ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0xb7e680a7 inet6_getname +EXPORT_SYMBOL vmlinux 0xb8025e99 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0xb808486a alloc_buffer_head +EXPORT_SYMBOL vmlinux 0xb811ba0e __vmalloc +EXPORT_SYMBOL vmlinux 0xb818087d cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0xb81fa59b acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0xb826d6e6 vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb829db5b kern_path +EXPORT_SYMBOL vmlinux 0xb85b2bac vm_stat +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb894926d schedule_work_on +EXPORT_SYMBOL vmlinux 0xb89668f3 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8afef96 init_file +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb96b1029 inet_put_port +EXPORT_SYMBOL vmlinux 0xb9765905 tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9970caa mmc_request_done +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9d4c0c0 scsi_print_result +EXPORT_SYMBOL vmlinux 0xb9d9a93e pskb_expand_head +EXPORT_SYMBOL vmlinux 0xb9f8e9b1 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba0492b2 __bread +EXPORT_SYMBOL vmlinux 0xba212d86 ilookup5 +EXPORT_SYMBOL vmlinux 0xba2bdfd6 pci_choose_state +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbb89de17 ida_init +EXPORT_SYMBOL vmlinux 0xbba817bc kernel_read +EXPORT_SYMBOL vmlinux 0xbbbf5061 seq_bitmap_list +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbc2280e2 dump_trace +EXPORT_SYMBOL vmlinux 0xbc3d40b6 vmtruncate +EXPORT_SYMBOL vmlinux 0xbc712e50 dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0xbc7533b2 scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0xbc7e5aa4 inet_bind +EXPORT_SYMBOL vmlinux 0xbc9cb44e dquot_alloc_space +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbd3556f4 bio_copy_kern +EXPORT_SYMBOL vmlinux 0xbd47e38d inetdev_by_index +EXPORT_SYMBOL vmlinux 0xbd540601 pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0xbd6efc05 pci_fixup_device +EXPORT_SYMBOL vmlinux 0xbd96cd24 pci_assign_resource +EXPORT_SYMBOL vmlinux 0xbda47f85 set_pages_nx +EXPORT_SYMBOL vmlinux 0xbdb49ed7 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xbddcf07c wake_up_process +EXPORT_SYMBOL vmlinux 0xbe0e5118 nla_memcmp +EXPORT_SYMBOL vmlinux 0xbe4ffecc filemap_fault +EXPORT_SYMBOL vmlinux 0xbe76e60e xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0xbea48766 qdisc_reset +EXPORT_SYMBOL vmlinux 0xbebc751b xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xbed17876 __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0xbedf4436 netif_device_attach +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbf03fb5a inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0xbf13b163 rwsem_down_read_failed +EXPORT_SYMBOL vmlinux 0xbf4f1f36 __starget_for_each_device +EXPORT_SYMBOL vmlinux 0xbf6cf2ee textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf8b39e9 isapnp_present +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfa064a2 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0xbfaa8139 remap_pfn_range +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfd0376d registered_fb +EXPORT_SYMBOL vmlinux 0xbfe27808 nf_log_register +EXPORT_SYMBOL vmlinux 0xbfed0304 ll_rw_block +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01eed33 __copy_from_user_ll_nozero +EXPORT_SYMBOL vmlinux 0xc024e03a mdiobus_unregister +EXPORT_SYMBOL vmlinux 0xc02a05b8 pnp_is_active +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc056c450 uart_resume_port +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0b8332f input_get_keycode +EXPORT_SYMBOL vmlinux 0xc0d97152 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xc0f65988 machine_real_restart +EXPORT_SYMBOL vmlinux 0xc11b2edb dev_set_mtu +EXPORT_SYMBOL vmlinux 0xc11d8093 iov_shorten +EXPORT_SYMBOL vmlinux 0xc12fdb57 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0xc1339ec4 set_anon_super +EXPORT_SYMBOL vmlinux 0xc1986b4e jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0xc2008f32 tcp_sync_mss +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc211983b elv_next_request +EXPORT_SYMBOL vmlinux 0xc22bbf73 dentry_unhash +EXPORT_SYMBOL vmlinux 0xc23f773a blk_init_queue +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc255a509 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc2604656 __getblk +EXPORT_SYMBOL vmlinux 0xc280a525 __copy_from_user_ll +EXPORT_SYMBOL vmlinux 0xc2b95379 pci_release_region +EXPORT_SYMBOL vmlinux 0xc2c36f1d unlock_new_inode +EXPORT_SYMBOL vmlinux 0xc2c3c8b5 sk_common_release +EXPORT_SYMBOL vmlinux 0xc2cf7f9e pci_save_state +EXPORT_SYMBOL vmlinux 0xc2d711e1 krealloc +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc34eb9db key_link +EXPORT_SYMBOL vmlinux 0xc360f890 sk_release_kernel +EXPORT_SYMBOL vmlinux 0xc36284d4 tcp_proc_register +EXPORT_SYMBOL vmlinux 0xc388d54c scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc3ae10a5 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xc3cf1128 in_group_p +EXPORT_SYMBOL vmlinux 0xc3fa6a59 memchr +EXPORT_SYMBOL vmlinux 0xc3fb8e75 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc4098985 set_pages_uc +EXPORT_SYMBOL vmlinux 0xc424e2da ip_dev_find +EXPORT_SYMBOL vmlinux 0xc4553950 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc49cf013 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0xc4b23985 skb_find_text +EXPORT_SYMBOL vmlinux 0xc4b8779f bdi_register_dev +EXPORT_SYMBOL vmlinux 0xc4c23a9b skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xc4ef93a3 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0xc4fb626b bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc540aeb0 set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xc550eb6e sock_no_bind +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc5831c8c elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0xc5844fb8 __per_cpu_offset +EXPORT_SYMBOL vmlinux 0xc593504c xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0xc5bd8118 generic_setlease +EXPORT_SYMBOL vmlinux 0xc5ccc593 d_move +EXPORT_SYMBOL vmlinux 0xc5d0a73d dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0xc5ef6213 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0xc6431abe __scm_destroy +EXPORT_SYMBOL vmlinux 0xc65e3baf clear_bdi_congested +EXPORT_SYMBOL vmlinux 0xc661f2ba struct_module +EXPORT_SYMBOL vmlinux 0xc6708756 hippi_type_trans +EXPORT_SYMBOL vmlinux 0xc69f045f ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0xc6a1d12e sock_no_sendpage +EXPORT_SYMBOL vmlinux 0xc6aff993 dma_set_mask +EXPORT_SYMBOL vmlinux 0xc6b10d9c tcf_generic_walker +EXPORT_SYMBOL vmlinux 0xc6b4c44b phy_stop +EXPORT_SYMBOL vmlinux 0xc7024e37 jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0xc707dc4b scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0xc7164e6e sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc7213b33 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xc77d6574 tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7a612af dmam_pool_create +EXPORT_SYMBOL vmlinux 0xc7b3be11 kmalloc_caches +EXPORT_SYMBOL vmlinux 0xc7bd1792 inet_frag_find +EXPORT_SYMBOL vmlinux 0xc7d375bf dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xc7ec6c27 strspn +EXPORT_SYMBOL vmlinux 0xc812053a register_sysrq_key +EXPORT_SYMBOL vmlinux 0xc83c8799 ___pskb_trim +EXPORT_SYMBOL vmlinux 0xc85ebf43 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0xc86b0cdd pnp_get_resource +EXPORT_SYMBOL vmlinux 0xc897c382 sg_init_table +EXPORT_SYMBOL vmlinux 0xc8aedb62 tc_classify_compat +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8c567df nla_reserve +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8da4da7 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0xc8e71267 blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0xc8f15b79 devm_request_irq +EXPORT_SYMBOL vmlinux 0xc9518f85 vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0xc95da1a0 seq_printf +EXPORT_SYMBOL vmlinux 0xc96d9244 single_open +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc9aaea64 tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9e50814 devm_free_irq +EXPORT_SYMBOL vmlinux 0xc9eac37b hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0xca5d62df vc_cons +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xcabe1837 create_proc_entry +EXPORT_SYMBOL vmlinux 0xcac72a9d __break_lease +EXPORT_SYMBOL vmlinux 0xcadd466b journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xcb0468ff lease_modify +EXPORT_SYMBOL vmlinux 0xcb2d5b28 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb423f94 d_find_alias +EXPORT_SYMBOL vmlinux 0xcb54a776 dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcb878062 bio_integrity_split +EXPORT_SYMBOL vmlinux 0xcb9f523f __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0xcbd04f0b d_delete +EXPORT_SYMBOL vmlinux 0xcbd8c38f xfrm_state_walk +EXPORT_SYMBOL vmlinux 0xcc19482b register_netdev +EXPORT_SYMBOL vmlinux 0xcc1bd125 security_task_getsecid +EXPORT_SYMBOL vmlinux 0xcc1c583b atm_charge +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc263f5c sock_create_lite +EXPORT_SYMBOL vmlinux 0xcc2cbc6d scsi_device_lookup +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc411f1c current_fs_time +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc7d4be5 stop_tty +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xccb69a2f vc_resize +EXPORT_SYMBOL vmlinux 0xccb87a1b filp_close +EXPORT_SYMBOL vmlinux 0xccceaf8e dev_driver_string +EXPORT_SYMBOL vmlinux 0xccd95b5d skb_put +EXPORT_SYMBOL vmlinux 0xccf25952 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0xcd12c32f set_disk_ro +EXPORT_SYMBOL vmlinux 0xcd3f33a4 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0xcd8b3729 ht_create_irq +EXPORT_SYMBOL vmlinux 0xcdb818a4 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0xcdc934ad tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xce12b2af cdev_alloc +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce6706d8 pci_restore_state +EXPORT_SYMBOL vmlinux 0xce88a4b3 locks_remove_posix +EXPORT_SYMBOL vmlinux 0xceaf058e register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xced04808 tr_type_trans +EXPORT_SYMBOL vmlinux 0xceeb86e2 qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf00c809 km_state_expired +EXPORT_SYMBOL vmlinux 0xcf482459 journal_start +EXPORT_SYMBOL vmlinux 0xcf51636b journal_init_dev +EXPORT_SYMBOL vmlinux 0xcf518c04 neigh_table_clear +EXPORT_SYMBOL vmlinux 0xcf82eeaa lock_may_write +EXPORT_SYMBOL vmlinux 0xcf91d7a2 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0xcf9f9765 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfb215f4 bio_endio +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xcfdaa02c xfrm_state_update +EXPORT_SYMBOL vmlinux 0xcfe0ce6e fifo_create_dflt +EXPORT_SYMBOL vmlinux 0xcfe3ace5 fget +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd01d4a78 bio_copy_user +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd056be9a blk_integrity_compare +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd08dcd9e journal_forget +EXPORT_SYMBOL vmlinux 0xd0913848 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0xd09acbfb jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0xd0aa94b0 scsi_device_resume +EXPORT_SYMBOL vmlinux 0xd0b4f33d free_buffer_head +EXPORT_SYMBOL vmlinux 0xd0c03d25 md_register_thread +EXPORT_SYMBOL vmlinux 0xd0c577ae phy_driver_register +EXPORT_SYMBOL vmlinux 0xd0d8621b strlen +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd11422a8 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0xd1286e1b scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0xd1307414 contig_page_data +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd14ceb38 input_register_device +EXPORT_SYMBOL vmlinux 0xd1565c05 phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0xd176322f elv_queue_empty +EXPORT_SYMBOL vmlinux 0xd17f9908 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd1eebb27 __mmc_claim_host +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd2038f4e sock_wfree +EXPORT_SYMBOL vmlinux 0xd20c3264 bd_release +EXPORT_SYMBOL vmlinux 0xd2331e5b bio_map_kern +EXPORT_SYMBOL vmlinux 0xd23dd49c __insert_inode_hash +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd2763928 register_md_personality +EXPORT_SYMBOL vmlinux 0xd278c985 pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0xd2815c0a sock_no_mmap +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd2981b51 request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0xd2ace80b invalidate_partition +EXPORT_SYMBOL vmlinux 0xd2ade3e1 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xd2c45b32 journal_abort +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd363bdea pnp_request_card_device +EXPORT_SYMBOL vmlinux 0xd3691e4d d_instantiate_unique +EXPORT_SYMBOL vmlinux 0xd3723a55 bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0xd393ca93 tcp_shutdown +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd39c5cda da903x_query_status +EXPORT_SYMBOL vmlinux 0xd3e3e036 blk_complete_request +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd42b87e8 md_error +EXPORT_SYMBOL vmlinux 0xd43beea7 ip6_frag_init +EXPORT_SYMBOL vmlinux 0xd44db038 inode_get_bytes +EXPORT_SYMBOL vmlinux 0xd453e329 fifo_set_limit +EXPORT_SYMBOL vmlinux 0xd4560a18 acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0xd4640b48 may_umount_tree +EXPORT_SYMBOL vmlinux 0xd4742330 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xd494c093 nf_register_hook +EXPORT_SYMBOL vmlinux 0xd49c7d44 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0xd4a6f750 xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0xd4f35cb0 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xd4f8fab1 generic_write_checks +EXPORT_SYMBOL vmlinux 0xd50906df find_inode_number +EXPORT_SYMBOL vmlinux 0xd51f1e33 scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0xd51fe019 sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd5508841 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0xd5688a7a radix_tree_insert +EXPORT_SYMBOL vmlinux 0xd58ce634 __scm_send +EXPORT_SYMBOL vmlinux 0xd592e064 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0xd598e3c3 scsi_scan_host +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5bb644c qdisc_destroy +EXPORT_SYMBOL vmlinux 0xd5d75901 mnt_unpin +EXPORT_SYMBOL vmlinux 0xd5fb0290 dcache_readdir +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd621d349 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0xd62a4e11 register_console +EXPORT_SYMBOL vmlinux 0xd62c0b2b proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd639c48a mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0xd6514aec __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0xd6530fb5 pnpbios_protocol +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6cde80e sb_set_blocksize +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd6ffa5f8 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0xd706c40b blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xd707f7ae clear_inode +EXPORT_SYMBOL vmlinux 0xd7359eb6 netdev_class_create_file +EXPORT_SYMBOL vmlinux 0xd7534f89 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xd76c5e82 atm_dev_deregister +EXPORT_SYMBOL vmlinux 0xd780900c blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7a514d0 inet_sendmsg +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7d36d1a idr_find +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7ef0c18 mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0xd8075fab pci_get_class +EXPORT_SYMBOL vmlinux 0xd81833eb security_d_instantiate +EXPORT_SYMBOL vmlinux 0xd82def72 skb_free_datagram +EXPORT_SYMBOL vmlinux 0xd83d126b jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0xd84f4506 nf_afinfo +EXPORT_SYMBOL vmlinux 0xd855d402 journal_check_available_features +EXPORT_SYMBOL vmlinux 0xd862ada5 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0xd86aff85 atm_proc_root +EXPORT_SYMBOL vmlinux 0xd86c7ed7 bio_split +EXPORT_SYMBOL vmlinux 0xd8723bf0 locks_init_lock +EXPORT_SYMBOL vmlinux 0xd88e8eaf proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xd88efde0 hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a2ab95 in_egroup_p +EXPORT_SYMBOL vmlinux 0xd8affce2 neigh_table_init +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd92e7244 skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0xd9398fa2 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0xd93d1e4a vfs_follow_link +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd996d859 idr_pre_get +EXPORT_SYMBOL vmlinux 0xd9c272aa mca_mark_as_unused +EXPORT_SYMBOL vmlinux 0xd9c8dcc6 udp_poll +EXPORT_SYMBOL vmlinux 0xda0369fe page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0xda08c0d7 pcibios_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda256c43 alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0xda26e114 i2c_put_adapter +EXPORT_SYMBOL vmlinux 0xda374187 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xda3a58cf cancel_dirty_page +EXPORT_SYMBOL vmlinux 0xda633962 __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0xda63a084 scsi_target_resume +EXPORT_SYMBOL vmlinux 0xda63aa6a dm_unregister_target +EXPORT_SYMBOL vmlinux 0xda7c8bf4 __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8fd495 isapnp_write_byte +EXPORT_SYMBOL vmlinux 0xda90d998 serio_interrupt +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xdaa57ec3 totalhigh_pages +EXPORT_SYMBOL vmlinux 0xdaaed9da clip_tbl_hook +EXPORT_SYMBOL vmlinux 0xdab644cf generic_file_open +EXPORT_SYMBOL vmlinux 0xdad86bda inode_permission +EXPORT_SYMBOL vmlinux 0xdb0a8b18 mb_cache_create +EXPORT_SYMBOL vmlinux 0xdb3e6a14 vfs_getattr +EXPORT_SYMBOL vmlinux 0xdb54c9dc rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0xdb692f7d sock_wmalloc +EXPORT_SYMBOL vmlinux 0xdb6ce750 copy_io_context +EXPORT_SYMBOL vmlinux 0xdb8086fc journal_get_create_access +EXPORT_SYMBOL vmlinux 0xdb864d65 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0xdb8f8bf6 mca_device_claimed +EXPORT_SYMBOL vmlinux 0xdb916ae5 register_quota_format +EXPORT_SYMBOL vmlinux 0xdbb389c9 blk_integrity_register +EXPORT_SYMBOL vmlinux 0xdbbf2d09 flush_old_exec +EXPORT_SYMBOL vmlinux 0xdbc683b1 block_invalidatepage +EXPORT_SYMBOL vmlinux 0xdbca7d6e tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdc07a47e nf_register_sockopt +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc30d756 pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0xdc3dc8ab eth_header_cache +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc769659 register_netdevice +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdc9e554c pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xdc9ef88a input_free_device +EXPORT_SYMBOL vmlinux 0xdcc8b3a5 __secpath_destroy +EXPORT_SYMBOL vmlinux 0xdcd72a36 input_set_keycode +EXPORT_SYMBOL vmlinux 0xdd0a0983 bt_sock_link +EXPORT_SYMBOL vmlinux 0xdd0a2ba2 strlcat +EXPORT_SYMBOL vmlinux 0xdd333019 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0xdd386225 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0xdd430ff9 block_prepare_write +EXPORT_SYMBOL vmlinux 0xdd6bfccd radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0xdd85fa57 mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0xdd99dc9a dma_pool_create +EXPORT_SYMBOL vmlinux 0xddc05c39 inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddcfd06d nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xdddaae2b pcim_iounmap +EXPORT_SYMBOL vmlinux 0xddeef053 vfs_stat +EXPORT_SYMBOL vmlinux 0xde0000fd pci_unregister_driver +EXPORT_SYMBOL vmlinux 0xde1a4e3c ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0xde2e5b3c jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0xde33c3ad security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0xde466483 pv_cpu_ops +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde884030 blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde9a3949 revalidate_disk +EXPORT_SYMBOL vmlinux 0xdeacbc1f tty_register_device +EXPORT_SYMBOL vmlinux 0xdec15d59 sock_i_ino +EXPORT_SYMBOL vmlinux 0xdec30667 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf0e4321 scsi_host_put +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf8178a7 netdev_set_master +EXPORT_SYMBOL vmlinux 0xdf86f3c0 __invalidate_device +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfaff52d noop_qdisc +EXPORT_SYMBOL vmlinux 0xdfb7bada acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xdfdb5e10 eth_header_cache_update +EXPORT_SYMBOL vmlinux 0xdfe1fa14 input_inject_event +EXPORT_SYMBOL vmlinux 0xe0091886 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0xe06b4431 wait_for_key_construction +EXPORT_SYMBOL vmlinux 0xe06c0417 dev_mc_add +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe07e9bf4 module_refcount +EXPORT_SYMBOL vmlinux 0xe08358dc serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0xe0914190 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0xe0a501e3 idr_remove_all +EXPORT_SYMBOL vmlinux 0xe0ab4a7a d_add_ci +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe11017b0 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0xe1170be3 phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0xe11b5f10 simple_set_mnt +EXPORT_SYMBOL vmlinux 0xe130076b kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe145f307 save_mount_options +EXPORT_SYMBOL vmlinux 0xe15aeee2 downgrade_write +EXPORT_SYMBOL vmlinux 0xe15cff60 uart_match_port +EXPORT_SYMBOL vmlinux 0xe16306ee truncate_inode_pages +EXPORT_SYMBOL vmlinux 0xe16f8a79 per_cpu__irq_regs +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe19673d5 sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1b29903 __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0xe1d1d29a generic_file_llseek +EXPORT_SYMBOL vmlinux 0xe1ea7cb1 pcim_pin_device +EXPORT_SYMBOL vmlinux 0xe1fda0ce neigh_destroy +EXPORT_SYMBOL vmlinux 0xe23dc924 sock_create_kern +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe25a1469 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0xe271a79c scsi_register_interface +EXPORT_SYMBOL vmlinux 0xe2bfa880 netlink_broadcast +EXPORT_SYMBOL vmlinux 0xe2d1b6d6 kfree_skb +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2ebd69d pci_get_device +EXPORT_SYMBOL vmlinux 0xe2fae716 kmemdup +EXPORT_SYMBOL vmlinux 0xe312c2a4 pnp_find_card +EXPORT_SYMBOL vmlinux 0xe32ed104 sg_miter_start +EXPORT_SYMBOL vmlinux 0xe3402324 kernel_accept +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe374cb1f elv_rb_find +EXPORT_SYMBOL vmlinux 0xe3bbbbfa ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0xe3e9eb3b path_lookup +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe416fcc6 lock_rename +EXPORT_SYMBOL vmlinux 0xe41f2ee7 put_tty_driver +EXPORT_SYMBOL vmlinux 0xe4309cc7 block_write_end +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe43e93dc journal_ack_err +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe4791e85 sysctl_data +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe48f3039 ida_get_new_above +EXPORT_SYMBOL vmlinux 0xe496a311 tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4db9111 tcp_recvmsg +EXPORT_SYMBOL vmlinux 0xe4e9ceec pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe52856c8 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0xe5390471 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0xe53b59ac tty_set_operations +EXPORT_SYMBOL vmlinux 0xe5469b9c kmem_cache_free +EXPORT_SYMBOL vmlinux 0xe5512dce mca_device_transform_ioport +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe5c2a34e is_bad_inode +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5ccf762 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xe5e0eea2 tty_check_change +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe5f250dc block_commit_write +EXPORT_SYMBOL vmlinux 0xe60abfd2 dquot_initialize +EXPORT_SYMBOL vmlinux 0xe6143093 blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0xe63cf384 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xe64cab2f add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0xe6570306 hci_free_dev +EXPORT_SYMBOL vmlinux 0xe66a163c nonseekable_open +EXPORT_SYMBOL vmlinux 0xe675d2fc generic_setxattr +EXPORT_SYMBOL vmlinux 0xe681517f ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe69d386f block_page_mkwrite +EXPORT_SYMBOL vmlinux 0xe6e7b13f jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xe6ebc016 key_create_or_update +EXPORT_SYMBOL vmlinux 0xe6ed8bc2 dm_put_device +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe7a200c0 key_negate_and_link +EXPORT_SYMBOL vmlinux 0xe7a2c3d7 posix_lock_file +EXPORT_SYMBOL vmlinux 0xe7c6b83f hci_alloc_dev +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7ded143 i2c_probe +EXPORT_SYMBOL vmlinux 0xe7f98f77 sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xe81139a3 dev_add_pack +EXPORT_SYMBOL vmlinux 0xe8348ce0 inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0xe83c1503 d_splice_alias +EXPORT_SYMBOL vmlinux 0xe8427ea5 kobject_add +EXPORT_SYMBOL vmlinux 0xe85de635 jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe87b4675 sock_create +EXPORT_SYMBOL vmlinux 0xe87dbf37 find_get_page +EXPORT_SYMBOL vmlinux 0xe8885a83 icmp_send +EXPORT_SYMBOL vmlinux 0xe88b1bd5 sock_no_accept +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8a60f20 cdrom_media_changed +EXPORT_SYMBOL vmlinux 0xe8c30c5e dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0xe8c5bdc7 llc_add_pack +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe904fb87 register_filesystem +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe94477c0 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe955eef7 inet_register_protosw +EXPORT_SYMBOL vmlinux 0xe96d667a bitmap_start_sync +EXPORT_SYMBOL vmlinux 0xe96e6e11 neigh_ifdown +EXPORT_SYMBOL vmlinux 0xe98c3e21 vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9b312d9 ppp_channel_index +EXPORT_SYMBOL vmlinux 0xe9e50919 file_remove_suid +EXPORT_SYMBOL vmlinux 0xe9ec0b40 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xea0b436b sock_map_fd +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea26bb24 ip_route_me_harder +EXPORT_SYMBOL vmlinux 0xea2abc33 generic_removexattr +EXPORT_SYMBOL vmlinux 0xea2d33a2 radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0xea31dce8 inet_shutdown +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea7987f1 key_update +EXPORT_SYMBOL vmlinux 0xea832a2b block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xea858cb5 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xea880218 dquot_free_space +EXPORT_SYMBOL vmlinux 0xeabe1049 pci_iomap +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeaed39c9 mark_info_dirty +EXPORT_SYMBOL vmlinux 0xeb1667f2 i2c_clients_command +EXPORT_SYMBOL vmlinux 0xeb176113 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb4a38d5 skb_seq_read +EXPORT_SYMBOL vmlinux 0xeb628cb6 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0xeb71a3ba iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xec3304f4 remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0xec39ae12 phy_disconnect +EXPORT_SYMBOL vmlinux 0xec4865d5 skb_append +EXPORT_SYMBOL vmlinux 0xec5dead9 blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec7b924b acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xeca0c2e1 __blk_run_queue +EXPORT_SYMBOL vmlinux 0xecaa5695 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0xecb778b0 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xeccfc5bb mpage_readpages +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xed04a506 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0xed40b543 br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0xed4c3f11 hci_suspend_dev +EXPORT_SYMBOL vmlinux 0xed538516 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xed633abc pv_irq_ops +EXPORT_SYMBOL vmlinux 0xed7be9b1 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0xed7d5b25 mmc_remove_host +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedd144dc netpoll_print_options +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xedf66389 vfs_llseek +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee30364d phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0xee557a65 grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0xee612855 mdiobus_read +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea22b2f blk_stop_queue +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeee2c5a5 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xef23abc3 security_inode_init_security +EXPORT_SYMBOL vmlinux 0xef3bd862 mca_find_unused_adapter +EXPORT_SYMBOL vmlinux 0xef7df93c nf_unregister_hook +EXPORT_SYMBOL vmlinux 0xef81f4e0 bdi_init +EXPORT_SYMBOL vmlinux 0xef85c071 audit_log_end +EXPORT_SYMBOL vmlinux 0xef8d23cd mapping_tagged +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xefe5e0b6 __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xefe83afd netpoll_parse_options +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf00d1442 tty_port_tty_get +EXPORT_SYMBOL vmlinux 0xf012ff10 file_update_time +EXPORT_SYMBOL vmlinux 0xf02be42d tcp_tso_segment +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf0937595 register_atm_ioctl +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0dfd5c5 kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf1182dfb genphy_config_aneg +EXPORT_SYMBOL vmlinux 0xf134742d vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0xf14d217b file_fsync +EXPORT_SYMBOL vmlinux 0xf14e5151 get_sb_bdev +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf1752afe __request_region +EXPORT_SYMBOL vmlinux 0xf180604c tcf_exts_change +EXPORT_SYMBOL vmlinux 0xf1846cee kthread_stop +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf1b92417 nla_put +EXPORT_SYMBOL vmlinux 0xf1c8411c genphy_update_link +EXPORT_SYMBOL vmlinux 0xf1d651ab find_vma +EXPORT_SYMBOL vmlinux 0xf1deabf2 div64_u64 +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1fb0575 uart_update_timeout +EXPORT_SYMBOL vmlinux 0xf20371ec iget_locked +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf22baff0 inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xf23ed715 dquot_free_inode +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2c981f5 __inet6_hash +EXPORT_SYMBOL vmlinux 0xf2d4a399 remove_inode_hash +EXPORT_SYMBOL vmlinux 0xf2e74040 mca_set_adapter_name +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf3448f01 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf386acb7 acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0xf396d7aa fb_set_suspend +EXPORT_SYMBOL vmlinux 0xf39bf4d9 put_cmsg +EXPORT_SYMBOL vmlinux 0xf3ae4a69 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3e1c4e3 set_blocksize +EXPORT_SYMBOL vmlinux 0xf4004c26 i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0xf4084f72 fb_class +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf462f321 do_splice_to +EXPORT_SYMBOL vmlinux 0xf463939e tcp_child_process +EXPORT_SYMBOL vmlinux 0xf4668d49 path_put +EXPORT_SYMBOL vmlinux 0xf48a2c4c MCA_bus +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4ae9d51 ida_pre_get +EXPORT_SYMBOL vmlinux 0xf4b7fd4b blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0xf4cfab89 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f28424 inet6_bind +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf502d273 acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0xf516b0c9 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xf518c034 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf548131b get_empty_filp +EXPORT_SYMBOL vmlinux 0xf55424dc __lock_buffer +EXPORT_SYMBOL vmlinux 0xf596f287 mod_zone_page_state +EXPORT_SYMBOL vmlinux 0xf5aa181f journal_get_write_access +EXPORT_SYMBOL vmlinux 0xf5bbda6e sg_miter_next +EXPORT_SYMBOL vmlinux 0xf5bcec93 journal_create +EXPORT_SYMBOL vmlinux 0xf5c05914 generic_segment_checks +EXPORT_SYMBOL vmlinux 0xf5c13cb4 have_submounts +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5d2600f key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0xf5f8c316 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0xf620c8eb per_cpu__current_task +EXPORT_SYMBOL vmlinux 0xf6272dbb eisa_driver_unregister +EXPORT_SYMBOL vmlinux 0xf62a9c9b input_open_device +EXPORT_SYMBOL vmlinux 0xf6517edf dmam_free_coherent +EXPORT_SYMBOL vmlinux 0xf68a278c eth_header_parse +EXPORT_SYMBOL vmlinux 0xf68a6dcb end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0xf6925057 generic_write_end +EXPORT_SYMBOL vmlinux 0xf6a275d4 mnt_pin +EXPORT_SYMBOL vmlinux 0xf6a42c49 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xf6a73b3a dm_get_device +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf6fd830e get_disk +EXPORT_SYMBOL vmlinux 0xf713eb1b __brelse +EXPORT_SYMBOL vmlinux 0xf7140987 generic_fillattr +EXPORT_SYMBOL vmlinux 0xf71a4538 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0xf71f8b36 ppp_register_channel +EXPORT_SYMBOL vmlinux 0xf7623914 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xf766ba73 tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0xf76c9254 bio_free +EXPORT_SYMBOL vmlinux 0xf77ac4bf tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0xf782a3c4 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0xf7845ff7 cdrom_open +EXPORT_SYMBOL vmlinux 0xf786ef5e idr_init +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7a0c51b __seq_open_private +EXPORT_SYMBOL vmlinux 0xf7b0982a ip6_xmit +EXPORT_SYMBOL vmlinux 0xf7b50060 xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0xf7d938df kill_pgrp +EXPORT_SYMBOL vmlinux 0xf7eafc66 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0xf7f1db04 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xf80c4192 blk_requeue_request +EXPORT_SYMBOL vmlinux 0xf80eb0cc __page_symlink +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf8147881 pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf842a7e7 dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0xf86b0d50 unregister_snap_client +EXPORT_SYMBOL vmlinux 0xf8798a18 cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8d991ea close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xf924ebe4 lookup_one_len +EXPORT_SYMBOL vmlinux 0xf971370f register_exec_domain +EXPORT_SYMBOL vmlinux 0xf98470f7 inet_del_protocol +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa141634 mntput_no_expire +EXPORT_SYMBOL vmlinux 0xfa3dd826 dquot_commit_info +EXPORT_SYMBOL vmlinux 0xfa58065a simple_readpage +EXPORT_SYMBOL vmlinux 0xfa7c129d simple_getattr +EXPORT_SYMBOL vmlinux 0xfa887528 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0xfaa2cc25 set_page_dirty +EXPORT_SYMBOL vmlinux 0xfac2ec52 mpage_writepage +EXPORT_SYMBOL vmlinux 0xfaecd354 inode_set_bytes +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfafb83f1 pci_enable_device +EXPORT_SYMBOL vmlinux 0xfb038d63 cpu_mask_all +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0a1d92 unregister_quota_format +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb19dc00 __ip_select_ident +EXPORT_SYMBOL vmlinux 0xfb43c7f7 phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0xfb4c168f __grab_cache_page +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfbbe8167 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0xfbf473c6 jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0xfbf675dc input_close_device +EXPORT_SYMBOL vmlinux 0xfbf8faad jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc309c3e cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc41d6f8 alloc_trdev +EXPORT_SYMBOL vmlinux 0xfc963fa2 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0xfc9d4229 block_sync_page +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfd094dbf netif_carrier_off +EXPORT_SYMBOL vmlinux 0xfd2ff20f unregister_netdev +EXPORT_SYMBOL vmlinux 0xfd41b6b0 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xfd4386fe input_allocate_device +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfdc16d5a sock_register +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfde8e97d skb_copy_expand +EXPORT_SYMBOL vmlinux 0xfdfa7bf3 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0xfdfb4a0d seq_lseek +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe097498 sockfd_lookup +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe694ca7 tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0xfe6f786a bitmap_close_sync +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfe9713a6 qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0xfea00720 inet_listen +EXPORT_SYMBOL vmlinux 0xfea718e8 dentry_open +EXPORT_SYMBOL vmlinux 0xfebd729d pci_disable_device +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfed09119 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfeee93d5 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff0924c0 vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff496769 unregister_console +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff7559e4 ioport_resource +EXPORT_SYMBOL vmlinux 0xff9a5a53 single_release +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffd1692b bio_map_user +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffe84a75 tty_shutdown +EXPORT_SYMBOL vmlinux 0xffff4fec set_device_ro +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x03e7f792 kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x08318027 kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x09611bd8 kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0e8a6782 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x112485e6 kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x15496414 kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x168b0861 kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1b53ff31 kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1be34c5a kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x21ef9a70 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2b2d7699 kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2b4c8c3f kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2feedab7 kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x307c3d60 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x30d1e0f8 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x372daa87 kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x378d6135 load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x499a35b5 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cf80a kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4e19a9f6 kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x528359e0 gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x55437fa0 kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x55ae5da7 emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x599086dd kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5e2504e9 kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5ea44d1a kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x651cfa9c kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6ab4eaad kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6ed52f9e __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x70d90630 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x73cd9e19 kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x773c0da7 kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7997c97b kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7b69d4f5 kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7b912f4b kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7bae6623 kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7f97934d gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x857cebf0 kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8a119a75 kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8b106ed3 kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9a08e74c kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa736c454 fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa9cd6507 kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaaf18a9b kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb3a9d24e kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb3bf8493 kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb4bf3ecf emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb8066a76 kvm_vcpu_cache +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbbd1ebb5 kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd290e1b kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd4d3825 kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcb1be1bc kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd076972d kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd14c5173 kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd2d4cce2 kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd97a9bc6 kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdc4b7ced kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdc6935d1 kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdf882aa3 kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe3640358 kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe9a20e33 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf01a3d9b kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf15de9e0 kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf2aa11c0 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf4d7a3ae kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf760b57a kvm_get_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfc6bb8e6 kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfcbdf6c9 kvm_lapic_enabled +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x3339118e crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x91cf5eed async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x0e037625 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6ddf8512 async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x9a66f183 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x4fd9bff5 async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x84fe468a async_xor +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xe8e4dd13 twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0x065632d7 agp_remove_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xdae43f10 agp_add_bridge +EXPORT_SYMBOL_GPL drivers/char/agp/agpgart 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL drivers/char/scx200_gpio 0xcda18fef scx200_gpio_ops +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x12eec576 tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x13338c24 tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1a395bc1 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1c6308ce tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1e7d5eb4 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x30eeafd6 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x367e7971 tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x4f1651b3 tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x68ca0eb0 tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x72958440 tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7683a4ba tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x769051a6 tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7731ba56 tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x84ceaba5 tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x865a9438 tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9872544a tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9a8d34a9 tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa877dde1 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xb1430d0b tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xc9fe17c6 tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xcf18b345 tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xee86f17e tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xef0aadcf tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x601669ea tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xc4770da8 tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x04df647a edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0535fa30 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0a7d7990 edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0ee63a32 edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x24902e44 edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x25046cc3 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x3a2e82aa edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x45cd71ca edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x49cc21ae edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x52cf0cab edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x57e6bb52 edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5877c354 edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5c8a5f68 edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8ff5f76b edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xbf5f238a edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcb46f06f edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcc11bccc edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xcc40dbbf edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe0977dd3 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe3ff6f52 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xe6c6e552 edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xeb411706 edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xefaa4378 edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf28f373b edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x1f5f5d83 hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x9cdb2a6d usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xdddf03dd usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0xb1e402ba nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0x4a06792e hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xcd7e8b4b hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0x98db1a67 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x2b49f395 wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x3230fb83 wm9713_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x47653308 wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x4a8db296 wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x973a2426 wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xac6939f1 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xc8f7f05d wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xc9159ae0 wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xdb39b6c8 wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xe324e647 wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xeffea2a7 wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xfe9afb1d wm9712_codec +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x054ebba8 gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x28235b85 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x4de4a02c gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x4e792275 gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x4fe92a16 gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x59b743a6 gigaset_initcs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x6572384c gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x6597b33e gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x65d1c076 gigaset_add_event +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x81904fda gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x85603ba0 gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9a2776ea gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xc618bac4 gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xd02fe481 gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xf1cd5ce2 gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xf3dbd889 gigaset_stop +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x001a452c led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x3477a6c5 led_classdev_register +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x4d02026f led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x834bd65a led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x8baee3db ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xa81ae004 ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xe3d8dcea ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x0599711d saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x06f1d4ed saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x32ad53bc saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x54e5fa34 saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x6a97372b saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x995a6085 saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xb3e47985 saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xb671be44 saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe07cf757 saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xf845d2c6 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x060e69f0 saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x2b6fb5a8 saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x4b78e456 saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x7a633121 saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x8f0ee0ff saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xbc1f5cbb saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xcb4520e2 saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0x1a947e8d microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x8aa2a919 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0x16e5d914 tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x91cf0ef9 tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x334ad8ed tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x79ae13d4 tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0x0d182084 tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x0cab06a7 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x5f384136 tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x24e9e91d tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x68e0c0b2 tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0x5642ffe3 simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x262c5de4 ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x84cac41e ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x9088a11b ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xa75d7691 ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xbcaf9b94 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xd19c8b57 ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xf67a5b14 ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0xff1c5046 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0x905112c5 cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x0a3daa56 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x2dee66d5 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x73f3eac5 em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7a57aecc em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x3b38585c saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x4b02ea69 saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x5b48bbec saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x5c6a8eff saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x86df9ccf saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xe9206626 saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x149b69e8 v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x25461741 v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x31355c3c v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xf0baa33d v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x01fc8036 videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x0adb4f3f videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x13b5e9d9 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x15e281ab videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x1b81e331 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x54b835b7 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x635c838e videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x6618a631 videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x68946082 videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x74b9e660 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x7d57a81a videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x8031239d videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x86850e2a videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x86e94186 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x88b6f3cb videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x91f625bc videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa49254a3 videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa80a29f5 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xab5533bb videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xae70fef9 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xaefc14bf __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb58a4cb3 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd0a2bf14 videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd3d5ab9e videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf96a4080 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x4f3e520d videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xa4685abf videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xf9f93358 videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x2918bf2b videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x32ed16be videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x4db452fa videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x555891ba videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x5846c3ae videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x5e47e16c videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x832fe167 videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x84788d46 videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x933dfb43 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x9cf78277 videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa2196032 videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa825c75b videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xdb9f7999 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xf83d7653 videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x872c5b3d videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xc62bd544 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xcd038bb7 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x0c28d894 i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x23f59268 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x48503872 i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x520d2108 i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x6748cc58 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xa1a4e3fb i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xb1f19ea5 i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xff582359 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x188a453e sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x51f7b36e sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x6837a932 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x8bcba061 sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xb9d2fafc sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x07af8ae6 wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x1d568064 wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x24a84606 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x7de7e6fc wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xa4d27961 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xa9333f4d wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xb2f96166 wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xc094480c wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xc413c907 wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xc504a2cf wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xc6c4271d wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd0e30446 wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xd86f61db wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xe70724c2 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xf446afb7 wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x1ffa78d7 wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x214cd747 wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x574b1e86 wm8400_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x6d318617 wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x3f99015a enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x4029c968 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x5169a604 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x80bda328 enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xb6417eaa enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd062078b enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdea09b14 enclosure_component_register +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x1719fdaf sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x4270418e sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x8da18037 sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xb8e1afbb sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xd2fe9d06 sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xee17acd3 sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x3e5a147f cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xa71e6df3 cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xcc17af22 cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0xebbc5135 cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0x966fa3cb cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0x49bba355 cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xbcae2f7b cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xc194f62d cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0xd349d337 DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0x6d37cad4 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0x5021f6f9 DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x0278a216 register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x0518010a mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x1736df31 get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x21cccd48 kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x44b4276b put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x4d46ccc4 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x63c887f7 unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x743a78b7 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x758db550 add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x7bfc8e20 parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x862f1535 default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x9ad42fa6 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xc2875c93 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xed9da711 del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xf353aea3 get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x2b75a62e del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x3d18dc55 register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x59cfad00 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x6acc6ccc deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x7d01284d nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xc1120847 nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xdcfb1f31 nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xf22deacf nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xfb3f45dc nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0xb80071c1 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0xc42a0e4b onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x107e8663 ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x246b1168 ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x2eb9f3fc ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x63db522f ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x9e341d7c ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xa66f3827 ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xacfa2cdd ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xb51e6f55 ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xc1fb4902 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf6df339c ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xfb2d6cad ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x069bcbb2 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x07ae71bb mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0f04dbaa mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x115dd3fd mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x13842f57 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1be2a78b mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1c032c87 mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x266292fd mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x270b814b mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2b9d0ed1 mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x303e8b69 mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x30655051 __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x33763e3e mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x372516a5 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3a1764ee mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x422770b4 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x55f435d7 mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5674535c mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5b9e9a7e mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x64e21a4e mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x66f8d5ae mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x72180bb3 mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7cc27174 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7d0ade5e mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x809e7039 mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x80b92740 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x820a14ac mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x83ab7d9b mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x870660cc mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x8ee5889b mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x93515c3c mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x964c1580 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9662d538 mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x976e5500 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa2d00bd4 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa7571951 mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa78ac9a4 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb6569f92 mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb863eeb6 mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xb988ab2e mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbb08c44f mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbe4b8854 mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc2b3cb83 mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc6483513 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcfdd91f9 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd1a0bc91 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd6891d77 mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd8b1235f mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xd941aa3f mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe0690c1d mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe6bce53c mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf8afec43 mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xfe5ae10e mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x5bacb2e9 usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0xf5d764ee usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x04083f45 rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x0d391234 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xa9bf6b78 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xc78d06c7 rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xca8c0368 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xd5133dea rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x03e071c5 usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x080c40f1 usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x104f8a20 usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x3f83dc34 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6b309b70 usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6e62a722 usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x7708ccda usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x875b1403 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x943809fa usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb9a5586b usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xd9abe4fe usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf0b14da5 usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xf238ba7c usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xfe34dc22 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xff40f8f6 usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x09d012e8 lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x0e871f40 lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x1f35be85 lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x38413091 lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x8e59034c lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x927aa6fd lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xa7d398c5 lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xb0d0e4a4 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xc8e96a82 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd0293d35 lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd0be57b0 lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd5471e3b lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd768f625 __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xdc10826b lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe686071d lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x2b380a91 lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x396d881e lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x3ac0ebb9 lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x400495b4 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x407155af __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x63850379 lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xaffed1a4 lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xe400c92d lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x5506404c if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0xa2bf9776 if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x156657d2 p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x3fba6aad p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xd4fed25e p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xe5c21a38 p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xe5f69e24 p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x05d33691 rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x06d417ef rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1f3f0b10 rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x2571ae35 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x282f23ce rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x28db49c1 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3d81e01a rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4eac67b2 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x52b14b14 rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x55f31755 rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x642f5adf rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x70b9fdf1 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x88a76497 rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x92c1c8b6 rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x94a866c6 rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x958e283d rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x9ed6106a rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa3113cde rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xb116e84e rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xda45a5d6 rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf11e62b4 rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf33d5f6b rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xfdfb0381 rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0d74366b rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x2c79c146 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x3331013e rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x86c74a03 rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x98b6cbcf rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x9c314b88 rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xb76b4a63 rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xc1f66a4b rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x0811d4d8 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x0e190984 rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x169fd05a rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x1bb81448 rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x32b5a0e4 rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x5816dd09 rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x725e16d1 rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x8c352505 rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa2c02a66 rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa8d3a472 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xb63db5f8 rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xb95a22bb rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xe4a7e3f8 rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xf0e2b790 rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xf46deef2 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x318c3dbe acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0xf92e2eeb acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x51a5c055 wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x98ad8a87 wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x9b33c85f wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xa2fe3c9b wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xfd5fc278 wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0xf760aa55 wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x06e161f0 __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x13df5044 iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x16124b9a iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x16548c44 iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x24d79d78 iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x314e60e9 iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x36e71573 iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x424c82b8 iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x42e71afe iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x47f40ddb iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x4f02f22e iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x51dd94a6 iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x69dbd888 iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x759ea188 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7d1a2237 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x81e4b385 iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x89db15ac iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x89f1e059 iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x933c2c28 iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x946b6984 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x98c63220 iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9cf358f1 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9e8f2fea iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa2cf6f1f iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa4fc2b33 __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa585b043 iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xa952c0e0 iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb413ab3a iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbf1783eb iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbf1eebfc iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc2b93791 iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xdbb39ed3 iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe27a42fa iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe366219c iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xfdccde5a iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x0958ad37 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x1c5e89fa sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x1e484e5e sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x34247c49 sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x41c16c35 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4429fced sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x44ee65c0 sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x54cf151e sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x674f3087 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x69415c49 sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x87a4c583 sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8e1002bf sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x8f28e19c __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x94f957e5 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9ab9d29e sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc05c5373 sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xc2723b24 sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xcddf8f82 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe48ab713 sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe617fcd5 sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf4da9430 sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xf5fbd24d sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xfdf6b066 sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x1a9ee81a srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x22cd45ad srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x817f8cb4 srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xaba8ad55 srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xc9fb0877 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xdc4739a5 srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x3dc31674 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x4cf60d57 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x83b8d9f6 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x94a70e37 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xbad00af2 scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xbbafb604 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xd17638c9 scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xeb51db2f scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xf46b145e scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0236c7ac iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x04c64c96 iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x12b40ebd iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2cb8bc4b iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x409f49a3 iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x47014880 iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x4fdcf098 iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x53fb795a iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x567eace5 iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x77a6a172 iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x92acfff3 iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x95775bc3 iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x97dbfb1b iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x9c58b055 iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xac6d45e5 iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xb9e4ca49 iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xda0236d3 iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xe151afc5 iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf05fcee4 iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf7a0e5d0 iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf953ff5f iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x1d27e8c4 srp_rport_add +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xa1424ca1 srp_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xa880b8e3 srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xaa15096d srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xcede4fb8 srp_remove_host +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x1148a45b spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x7ca125a6 spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xb091734b spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xd15cad91 spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xe355ef27 spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xf3bcf2e0 spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/uio/uio 0x03e9b72d __uio_register_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0x184d2d10 uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0x9194e8a3 uio_event_notify +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x1ebaa595 usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x45a043ae usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x101a87c3 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x11aa9b33 usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x23c596cd usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x25e49dd5 usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa48f9a82 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xa5e09a70 usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xc5929e87 usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xde350321 usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xdef66a72 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x13a0b2da phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x7b63ae78 wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x863bd191 wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x8c8c8fd4 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x9b3cd188 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xc0f687d3 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xf4654c3f wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x08de354a wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bbfe024 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x19f13c72 wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x1d9a629f wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x25091577 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x2b6170af wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x2bd7d65d wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3005daa3 wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x360ccc66 wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x4acd53e2 wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x519e0d53 wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x72e5b0a0 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x9077b172 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcce664c1 wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xd15d2cd7 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xe32188b0 wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfa11169c wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x132a9b94 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x419cbede i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xcca0de85 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x344d22ac uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x34dc4993 uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x5c794c64 uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x75f2678c uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x789aec33 uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x88f453af uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x965032cc uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xd0ec3c3f uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x24b6392a umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x5dca06a3 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x67a37cf3 umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x6ca83800 umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x70178485 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x8820089a umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9cb4f0f9 umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xe11abc58 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x00a0f5cb __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0b8aad57 uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1a243c4c uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1af4cf76 uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x21b7c3eb uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x270b7d70 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x28ccd00d uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2e5d17f9 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x30539dcf uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x383bdddf uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3de5f6cf uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x444b4580 uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x484ed37a uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4a267799 uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4aef23a2 uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4ba7011d uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x547966a4 uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e4bc088 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5e8dd11d uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x68e5f1ec uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x757a56a8 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7dcfcd23 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x853f2936 uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88a2774f uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x88e4909f uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8ed0535a uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9d5b9784 uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa189aaf8 dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa408eab8 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa529f6c3 uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb783e96c uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbff20dce uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc36192c4 uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1716f06 uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe17e49b4 uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe1b3c43d uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe37e7963 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe625e3a5 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xebb145d1 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfa251ecf uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xffe82870 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/whci 0x26dd0259 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x02527550 wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1fcb266c wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x28348979 wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x2de5f08a wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4664ccef wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x47da7048 wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4c77924f wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x52357d91 wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x58f21120 wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x67af246a wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6f3d5239 wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6fe8dcce wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7e0ba3ad wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9b2a996e wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9bcac937 wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa12094eb wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa1235d2a wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xa312b243 wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xafa5665f wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb1da025d wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb6000d56 wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xb765441a wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xbd9ddbd4 wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xc17b175b wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xcbfe3ecc wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xcf208917 wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe05e57bb wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe21dd33f wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe818088d wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xea1ee1ee wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xed1dd40c wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf1095abd wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x22a2daf4 ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x334092b3 ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x98828bac ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xb7ba1c2f ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe5520524 ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe91daa25 ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xfb9ebc6c ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0xb2af3942 fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xd9114df3 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xfb2306f2 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0x1772e234 sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0xd6fc7d09 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1c062519 register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x2ca05ede unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x3954c1f9 virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x56b31ada unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xb6126878 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x16c07e42 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x49323c8d vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x805c7b6e vring_transport_features +EXPORT_SYMBOL_GPL drivers/w1/wire 0x4530aa8d w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5bfb4dbc w1_next_pullup +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5c1323fa w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x891c90f3 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xa36ac307 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xb68c805f w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0xbf3c2589 w1_reset_select_slave +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x07128722 dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x653a0d80 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xa53d462d dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x013f63e2 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x464e4c91 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x07e8c300 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0x27698ddb fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x320d4ef0 fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x40738611 fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/fat/fat 0x502dd3f8 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x56b791c0 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0x5e7bafec fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x73fcf63e fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x762e7d80 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x78dba585 fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x7df0ecdd fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x97c79979 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0xaa030947 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0xb6e0f132 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0xc5e545e4 fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0xcca80706 fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0xd3582941 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xd5c05c7a fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x6e01c5fd gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0xeeb3f956 gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x2a733662 nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x52f920ed nlmclnt_done +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6c9306cd nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xe1ebfc1d nlmclnt_init +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x07aa87a3 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x113dc662 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1cb231d0 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x687f6251 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x6b325e7e o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x77c6c4b0 o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x86ba61c6 o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa9f5379a o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xe140a907 o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xed593a63 o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x0f29137b dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x3334115a dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x4c450549 dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x50b404db dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xa728de08 dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x19c6e0db ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x22106ad3 ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x390be1d0 ocfs2_plock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x56b63670 lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0xf30fda27 lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x1905bf37 garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0x33dda7bc garp_request_leave +EXPORT_SYMBOL_GPL net/802/garp 0xb5beac33 garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0xccac035d garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0xd76861a2 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0xe6dc999b garp_init_applicant +EXPORT_SYMBOL_GPL net/802/stp 0x23de0a8d stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0xae2db850 stp_proto_register +EXPORT_SYMBOL_GPL net/ax25/ax25 0x3a4b8df8 ax25_register_pid +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x7514415e tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x751ef25e tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc850083f tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xd0cb50a5 tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xea620f6c tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xf41fa521 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/dccp 0x0237d2d6 dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x06e8a5f6 dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0x18302513 dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2480de03 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2ddb509b dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2e62978e ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2e759c3e dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3f76a82e dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x44d1a969 dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x464068ea dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5285ef8d dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5a6ee066 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6052b279 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x65e60dab ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0x6736c7a4 dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0x696b8a2d dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0x69bcd0f6 dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x73fe7d31 ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x82543a16 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8785de31 inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x90c99ce7 dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9333ee0d dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa44f7f56 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa72e9dc4 dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0xaa1afaa4 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0xab75b114 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb20c87b4 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb437f1db dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc4065824 dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc8080341 dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0xcd95b5c5 dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd1992f59 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd622b266 dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd685221e dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0xd839a1ed dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe0c411d4 ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe1bddd12 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe699068a dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe6cc93d9 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe8b4f49e dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0xee12fc6c dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf19caaab dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf4d821c9 dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf988bd5e dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x6ac097d7 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x6c37f3bf dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x99ec2361 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x9dfd9cd4 dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xadf195ab dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xd6d83c8c dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x1c627005 ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x5ff962b2 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x01bce45e nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x21973b9d nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xc2238a34 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xc66869a7 nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xc6f9c39c nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x1b735b12 tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x5b5ad939 tcp_vegas_state +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x7e11c909 tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x8271508e tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xbc411569 tcp_vegas_init +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x0b56e366 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x957c692c ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x03f81d0b nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x106be7e5 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x113189e1 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x16e8ce67 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x197f0613 __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1b0039f2 __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x203edf3b nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x217395b7 nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x2307eb63 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3019cae0 nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x35a283b0 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3bc7064e nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3cf0fc64 nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f9fe8f3 nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x415a8005 nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x4256d9ec nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x43f618ae nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x55deb3e0 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x57cd26bb nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x60f3c5ce nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x688a308f nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x71c07a2c nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x745ac4f4 nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x886a1333 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x895ca7fb nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ce90bc2 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8f22da76 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x92a2a677 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x92f22583 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa27f598e nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xab5d1650 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xae17a0a9 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb5c1ade0 nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbed9280e __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc03f61fb print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc758ce7c nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd0dbf34b nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd7f1237c __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xde4ea798 __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xeb6b8cce nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xef83067a nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf65adce8 nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf99a1663 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff503eb3 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x633940d1 nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0xb7c33fa5 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x27fcb943 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x41920d84 nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x5e8a0b4e nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x66c0eaff nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x7de6c206 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x94e78608 set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xb121d6a9 nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xe5b5c31c set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xf62cbfdf set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0x322c31dd nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x1f4780ac nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x31aeb66f nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x6919cdc8 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xc6ca0193 nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x227a9515 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x27a10e1c nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x88a0dbb6 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xc538124d nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf272dbe1 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xfab1e4fc nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0x229a53cc nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x2f1358b1 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x6fa0fe96 nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x382dfd27 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x4b681b40 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x9fa647a2 nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xa7cd404d nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x18168f20 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x55326b98 xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x74e40401 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x7ab668c4 xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x8afe8c80 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xb1756ea4 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xb970fbbb xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xc43dda75 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xd41fba2b xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe74bbbef xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x1ddb9d08 rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xc90e140e rxrpc_register_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0105cd2c svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x048e9b77 rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x091b0d6a rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0a94e332 rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0d2fc2e1 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0f782c36 rpc_put_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x12272fdd rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x133d9a26 svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1877f989 rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x18db2171 rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x190152d5 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1a0845c9 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1b4d2323 rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1be70fc1 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1ca63463 rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1d5b2c0a rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x220a0793 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x23eeba7c xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2601565e rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x29127db7 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2a0eb03b rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2a25e503 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2de6d45a xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2f37f82a rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x356601c4 xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3ac9af48 xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3ce38d75 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x430f6577 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4476343f xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x449b9cbe rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x44f05321 svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x453cdae3 rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4e8fd9a6 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x521c6d19 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5241ee5c svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x59b65a18 xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5e1429dd rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6abc1d29 svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6bf0d398 svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6d77bcd3 svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x70920641 xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x71703050 rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x71cd1b65 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x78cbfb6b svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x82dd21b2 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x86353609 rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x87bcda45 rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8e603d69 rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8fa0807d rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa102ffaa rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa2f8a8a8 rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa509b932 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa5102e83 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xac2ab459 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf8d622a rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb3fd6e86 xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbcf25c7f rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbe2c7543 svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc2292774 xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc568b802 xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb87cdfe csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcba65042 rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd1222da3 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd3bdaad7 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd7d89622 rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe2fb082e xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeae2db1f rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xec7aff6e rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf5defdb6 xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf8684cf3 svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfc883c02 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfd151728 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfeb47895 xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x09e7234c ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x1d2f7876 ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x33c13385 ipcomp_destroy +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xafd8ad49 ipcomp_output +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x76f3477a soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0xeaee138a ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x617ce800 ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0xbd2de869 soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0xa32e2c64 cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0xa777bfe7 soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x5c4ec41d ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x6750188b soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x7b2d60ef soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0xb0d84380 tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x150cff20 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0xc9b87f27 aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x0f22781e aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x10bcc8a2 aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x32a5237d aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x5a9d1f8f aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xc9b76f1a soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x38dfcaef soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xf82900f4 uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x0b47e541 wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0xd4796faa soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0xdba85425 soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0xee580152 wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0x15a120b0 wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0x64ef420e soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0x79790ffd soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xbd2dc62f wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x38b16140 wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x52545c3e soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x9f6dba25 soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0xfa9ffbba wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x7c0b8914 wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0xb440e9e6 soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x83399de1 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0xf4641691 wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x6f07be69 wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x90bc81aa soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x016f4874 snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x02e81d55 snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x043be54a snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0441a31f snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0a86dd43 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0e442028 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x163d2749 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1fc87b7e snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x28ec34e8 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x34c3cefb snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x40980e3d snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4b4d2f0c snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4d1fee5b snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x511cce5f snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x59277ae7 snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x5f39e125 snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x63585183 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x652cf422 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x696a8f56 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x74a6c99e snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7b27db32 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7cfc2fd8 snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8d1db217 snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x941f868c snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x946c3d5e snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x95f00f0f snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x97445230 snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9a113ad4 snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9cbe8e4a snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa0359134 snd_soc_test_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xaa67bda6 snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xae4dc234 snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xafae754a dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xba435fb3 snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xbd1b81f9 snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc43f59ad snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc60876e8 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xcd32ed3b snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd39ed1db snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd6800bcb snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xdd720b65 snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe66056a6 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xe6dc6987 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf10086f3 snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf4fa66f9 snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfafa5a89 snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xff037757 snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x42a50f11 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x66da3d8f tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xee6c65c9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xeec8caeb tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xf9805f1b tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x00f1d4eb bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x015e0eeb hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01b08feb dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0x01b8db0a ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x01f80c10 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x021eb672 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0220fb8b device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0x025a98b6 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x028886cd usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0x028a1dab blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x02bd14f1 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x02d4aa1c ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x02f8d2c8 xenbus_grant_ring +EXPORT_SYMBOL_GPL vmlinux 0x02fc60f9 sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x0300fad5 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x0333214b ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x0397cdd0 blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x03e358fe led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x04c3f2c1 gnttab_empty_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x04d7ef84 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0x0502a727 inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x05518ee0 do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x05cebb79 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0x05d497c0 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x063d70ab put_device +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x0684e6a7 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07d8b8c6 dm_put +EXPORT_SYMBOL_GPL vmlinux 0x07ff4aea xenbus_scanf +EXPORT_SYMBOL_GPL vmlinux 0x0866c8ee inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x08888c6d sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x089b3e5b bus_register +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x092a62fa crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0x09b1263a ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x09e68aa6 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x0a16f0cb skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x0a5c1b3d xenbus_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x0a64d23e disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x0a6f1664 ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0x0ab125a3 d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0ae0480d ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x0afba278 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0x0b2a9748 vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0x0b2d7d3e usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x0b3736e7 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x0b53a167 device_move +EXPORT_SYMBOL_GPL vmlinux 0x0b8b07ac preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x0b9d29cc devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x0ba151ec kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x0bc20826 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x0c1002af cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c236dba sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0c5e7fca rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x0c64f4aa blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x0cce3500 pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x0cf47a52 fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x0d160148 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0d1c6676 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x0d41381c ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0e15a811 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x0e3ebbcd ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0x0ec210b8 xen_start_info +EXPORT_SYMBOL_GPL vmlinux 0x0ee473df platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x0f0a38a6 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0x0f0d238a key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x0f1669cf usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0x0f1a5477 platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x0f340e6d ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x0f8cfb42 fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x0fe2d570 xenbus_directory +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x1045b9b8 vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x10bf1327 sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x10f358df skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x1103b923 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0x11382702 user_match +EXPORT_SYMBOL_GPL vmlinux 0x1166ec41 i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x118db5fa zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x11a8f038 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x11fd5086 usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0x12150c94 class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x126df1fc crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x12f410ab scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x1313b748 tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x13155494 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0x13605cb1 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x13c994c4 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x13f2b874 devres_find +EXPORT_SYMBOL_GPL vmlinux 0x1457eab6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x1461d144 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14a3afde usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0x14fc37f9 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x1517cb9c usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0x15568631 lookup_address +EXPORT_SYMBOL_GPL vmlinux 0x15627934 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x1577733a device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x1599497a pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15cb37fa bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x15e9777f sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x1604808a xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0x162dd55b ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x16c6b935 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0x16d2ca66 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0x16e8bc00 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x16f76869 probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x17223389 dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x172e72d4 vdso_enabled +EXPORT_SYMBOL_GPL vmlinux 0x174e20f1 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x1769f2c6 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x17854265 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0x17bf873c regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x18132d0e blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x18405bf5 hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0x185beed1 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x18674aa5 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x187cf3ed blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x18b79515 simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x18f83fab gnttab_grant_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0x199231be platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x1a43c332 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x1a758c33 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1ab00a03 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1adb2c9c inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x1afa3fa9 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x1b8d588c dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0x1b922bd6 ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1ba93b30 ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x1c0fa108 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0x1c16e474 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x1c4a5a90 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1cc3fcfb platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1d22e547 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x1d761575 pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0x1dc2ee9c usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x1dc3ab7c dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1df80741 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0x1e3e2857 sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e8761cc crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x1e92f15e ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x1eaf8de0 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1eca2e06 dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0x1ed75d4d ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x1f0d0431 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x1f1768e4 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x1f232cd1 kmap_atomic_pfn +EXPORT_SYMBOL_GPL vmlinux 0x1f470e33 regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fc4ef61 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x1ffa0d44 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x200cb54e ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x20b22f3c pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20dc90a9 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0x210c1a6d find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x210cf086 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x21cac914 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22be8c71 sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x22f7583c scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x2306d938 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0x230c4975 __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x232231fa skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x234b2ce8 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0x23679939 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x23712588 tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x23f7cd18 crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0x2417647b bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x243c7611 usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x2449a350 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x249071cd fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x24adb0c3 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0x24b5565e tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0x24c7698a xenbus_write +EXPORT_SYMBOL_GPL vmlinux 0x24de6c0d driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x24f422fd crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0x25352c82 ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x2545c170 unregister_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x2563818d alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x256fd9dd pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x25c55aa4 hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0x25d813c7 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0x25e27027 register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0x25f5dca9 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0x26111f7a __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0x262c58cb blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x26435584 xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x2744d6ea raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x27976132 sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x27a7f92c tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0x27dbb24a xenbus_frontend_closed +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x28170c6c alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x28740ea5 dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x2885bfe4 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x289b3755 tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28c876cb fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x290f5ede usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x291114a4 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0x295394e2 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x29dbfaeb get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x29f292b0 blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x2a1f6555 kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x2a24accd ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2a973879 crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2aa10c29 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0x2b102070 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x2b302405 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2b524624 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2cb1986d audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0x2cb1afd2 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x2cdd04fd debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x2d45bcda crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2da626a5 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x2e1a38d5 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x2e1b08ab ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0x2e6a89be xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0x2f1935a0 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f957200 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x2fa66bcd tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0x2fa73add sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0x2fce52b8 proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0x2fdaf798 devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x2fe55e35 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0x30348217 xenbus_alloc_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x306faed2 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x30aa4925 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x30d385e5 fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0x311ead93 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x31303cc9 usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0x3184272b ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x31c2decd tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0x31cbce14 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x31dbef47 tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0x31f55924 usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0x32252b02 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x322f8378 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x32310473 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x325e677c gnttab_grant_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x32867045 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0x32924a4d scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x32b4ae01 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0x336295fa __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x336eef4a get_driver +EXPORT_SYMBOL_GPL vmlinux 0x33993de8 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x33c55949 regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x33f9eda8 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0x3404e47f ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x3430cc20 usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x34819b2a input_class +EXPORT_SYMBOL_GPL vmlinux 0x34ccc0dd rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3526a925 dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0x353fa192 regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x35eccdbe securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x362e39bc ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x3637d399 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x364c0652 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x369eea62 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x382c95b6 sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x386ef54d usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x38f9553f spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x3910a0c5 hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x3932f661 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x396bf91e usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0x396c63c5 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x397651ee ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x3a0650ab elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3a4f71b9 regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3ad0ddbc pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x3b04dfab usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x3b0886ab driver_register +EXPORT_SYMBOL_GPL vmlinux 0x3b3103ab usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x3be4b0ca xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3c103389 pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0x3c1f4698 usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x3c7dd7ae usb_string +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3cad4080 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0x3ccc0e35 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d2966d9 hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0x3d5ec376 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0x3d7ce814 usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0x3d7ea99a gnttab_grant_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x3d7f4890 usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0x3da18eab sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x3ddc1da0 ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x3e00525e debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x3e19b092 pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x3e9952ff nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3ed73d0a regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f01570a probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f3d6465 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x3f588432 power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x3f628fe8 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x3f71a1d1 ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x3f810a12 led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0x3f84d4c9 gnttab_release_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x3fb0bbe3 device_del +EXPORT_SYMBOL_GPL vmlinux 0x3ff9688b sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x40827ccf lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x4089efd9 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x414255ed platform_bus +EXPORT_SYMBOL_GPL vmlinux 0x4177dddb cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x41900da5 shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x424acc6d scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x43550767 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x436945ef inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0x43a40d8d sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x43b6fc61 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x44236660 cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0x444bee6c pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x4465088a pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44c5608b usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x44e3e859 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x450f41c5 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0x45156dc1 xenbus_dev_fatal +EXPORT_SYMBOL_GPL vmlinux 0x451b82ff usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0x4526b1b9 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x458a5301 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0x459b8533 dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x45d14bdf hypercall_page +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x461c3e30 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x461e68ac blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0x464874d8 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46930b48 dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0x4710fb52 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x4756e941 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x47eef36d scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0x47fb08ca mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0x48732d43 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0x487bbe99 regulator_get +EXPORT_SYMBOL_GPL vmlinux 0x48d41393 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0x49295ba9 sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0x492f0ef2 unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49aa228f ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0x4a11a4fb bind_virq_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x4a5ed12a crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4af39f2a platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x4b1c251a blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x4b41d7dd bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0x4bc77ba9 hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x4bcef498 dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x4c07ed7e sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x4c1461c1 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0x4c1bb689 class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x4c32215e power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4c3baea6 inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x4c3deb44 ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x4c406a92 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x4c456297 pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x4c48b577 do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x4c4b1989 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x4c732b4c uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c9f00ee cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x4cab4344 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x4cbf1eed scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x4ccfed1f transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x4cf06b68 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x4d2d9e1b sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0x4e42dd1b crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x4e787c9d rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x4e96630d uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x4ea7afa6 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0x4ee8eea8 fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x4ef635c0 ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0x4f040b1b register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x4f3e5982 ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0x4f6230e1 __xenbus_register_frontend +EXPORT_SYMBOL_GPL vmlinux 0x4f9801a9 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x50144a10 pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x5026c23f get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x504acde3 device_find_child +EXPORT_SYMBOL_GPL vmlinux 0x5056f28e rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x50845937 sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50bdbc92 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x5108b3fc acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x5112f5da transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x5161d493 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0x517d5a68 usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x52561a9c bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x5275adad sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x52a891f1 xenbus_watch_path +EXPORT_SYMBOL_GPL vmlinux 0x52b036ea driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x52fc1a70 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53f3a377 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x545e768e led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5496d078 regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x549a8a4d __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x54ac31a1 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x54f4e1d7 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0x55526907 xen_features +EXPORT_SYMBOL_GPL vmlinux 0x558d74aa dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x55a345fa usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x5662e7be crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x56bc4b93 mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x56c29de1 blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0x575c76e5 find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0x5779d445 xenbus_exists +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57e2f72a rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x58a3618f hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x58b869a4 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0x58e7dc00 sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59a3af1c device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x59e1fbea __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x5a2b1b67 gnttab_free_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5a3216fc sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0x5a3a48db vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0x5a41eafe dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0x5a6f5cff cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5aaa84d6 scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0x5ac8c6b7 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x5af03a28 gnttab_claim_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5afb683f tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x5b2e87c7 debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x5b8b0928 cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x5b8e9bb6 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0x5b9dbea3 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x5bb6be5d xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c15bb4f debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d366dec gnttab_cancel_free_callback +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e099c16 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0x5e5988af xenbus_free_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x5e5f3c7d ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x5e7ec8dd xenbus_dev_error +EXPORT_SYMBOL_GPL vmlinux 0x5e9400a7 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x5e9a654e relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0x5ea82314 pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0x5ee7937f pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f43244a inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x5f5e7dc8 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x607ffad4 usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60ceb4a4 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x60e5a1f9 da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x61720cc2 blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0x619a83ab crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x61bde1a2 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x61d5f003 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x6294217b skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x62a2f902 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x631cce64 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0x6328161c crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x63493e60 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0x6366afaf ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x6368b3ea usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x6372bf2d crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63ed5492 pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0x6456f8fa ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0x64775dda dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0x64ebe677 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0x656cac19 drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x6572be55 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x65b30f56 bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x65f50a14 ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x664d5e81 scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x66540f43 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x6684bdbe seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66b8b277 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x66c9e6bb pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x66ee563e queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0x672cfbf7 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x679694af screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x679eacfd ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x67d88b7a usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x687bd26d ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x693cb2b3 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x698713dd led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0x69bac3e9 driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x69ccb7bf ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a2fe472 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0x6a49dda1 __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6ac15b4b tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0x6ad1414f ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x6b8aa68f scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0x6b91268c crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0x6b9178b3 xenbus_strstate +EXPORT_SYMBOL_GPL vmlinux 0x6bb8cc52 skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c22ece6 __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c530bd3 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6c936bd3 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d6a2970 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x6dc62fe2 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6e58ddf0 gnttab_end_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x6e62637c tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x6e84bed7 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x6e8c28a1 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x6ebe305d raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x6ec7f217 __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x6f5958d6 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0x6f607291 ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x70250c8b ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x7093c0eb inotify_init +EXPORT_SYMBOL_GPL vmlinux 0x709fc199 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x713d91d9 regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x717e0cd1 cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x71ef19e9 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x723487a4 usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0x723eabaf usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72e9d49e ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x731dba7a xen_domain_type +EXPORT_SYMBOL_GPL vmlinux 0x734ea682 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73c7e0dc sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0x73c855c6 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x74091e1c fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x7457d528 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0x748b5e01 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x749bda4f da903x_update +EXPORT_SYMBOL_GPL vmlinux 0x74aba92a dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74b9d459 ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x74d928d3 inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x74d9605b rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x74deb10c used_vectors +EXPORT_SYMBOL_GPL vmlinux 0x752140b0 usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x7568b92e register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x75c0bb11 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x75c3736c devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x75c8a11c inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x75d0c8d1 hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7699fe55 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x76f0ddc0 driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x7712771a unbind_from_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x77e9caf5 bt_class +EXPORT_SYMBOL_GPL vmlinux 0x77ebc832 inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x77fdeea7 usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x77fed30e ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x78a4c5cd debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0x78b44e08 get_device +EXPORT_SYMBOL_GPL vmlinux 0x78c36155 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79a9a1b4 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x79cf12b4 ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a5d6f88 usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0x7a8bd34f inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x7a922150 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7b1bf7ed da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7bd797f2 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x7cce8e89 sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x7cf2b9cc devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7d2f7be2 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x7d410aa7 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7e1acb11 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e698a51 unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f1bde1a dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0x7f245482 sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x7f33481a tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0x7f3a7657 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x7f8ed603 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x7f8fdb6a inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x803e4900 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x8168c858 cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x81c63d58 tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0x81f30a04 ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x81facfd9 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x825c4bd5 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x8268ead4 iounmap_atomic +EXPORT_SYMBOL_GPL vmlinux 0x82742a6b attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x827a14d1 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x82cd19f3 register_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82e42015 regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x82f5273b register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x832c0ce3 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x83368956 device_create +EXPORT_SYMBOL_GPL vmlinux 0x837d4945 usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83c2bc46 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x83cf1f24 class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x842c6121 sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x84314504 ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x844dac79 relay_open +EXPORT_SYMBOL_GPL vmlinux 0x8458465b inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x851351d0 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0x8513a9d1 pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x855e1fcb sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x860f3341 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x8643f0d8 usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x8655e6f7 ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x86623fd7 notify_remote_via_irq +EXPORT_SYMBOL_GPL vmlinux 0x866371e4 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0x8669bba7 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0x86715433 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86a51007 gnttab_end_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x86b10394 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x870404b8 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x87862fd7 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x87919ee7 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x88350acf fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x88629491 blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0x886736fc olpc_platform_info +EXPORT_SYMBOL_GPL vmlinux 0x889e0191 isa_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x88d4b8ca regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0x894e1b1d inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0x89afbe16 ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x89d61ee9 xenbus_map_ring +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8b5c808a ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8be75d85 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0x8c06a108 xenbus_transaction_start +EXPORT_SYMBOL_GPL vmlinux 0x8c103671 bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8c38074a unregister_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8c8c797d sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x8c98c612 dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0x8cc178cf scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x8ccaee66 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8cd81d8f inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x8cde098b ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0x8cff647b ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x8d14e534 ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x8d376de8 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x8d5d1bd1 user_update +EXPORT_SYMBOL_GPL vmlinux 0x8d8966b3 ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0x8d8d80f6 proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0x8dd78d25 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x8e0768c7 fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0x8e62442e crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x8e6d9a0a user_read +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8eee05b8 class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x8f0804e8 rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0x8f11d1cf ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x8f4be858 blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x8f591688 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f96a000 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x8fae52b4 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0x8ff8dbcd blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x9017112f usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x904c84fc usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0x904c9c50 ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0x905cae4d usb_root_hub_lost_power +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x90811115 device_add +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90e62d78 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0x9126eff5 ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x9131d95d fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x915a3c5f usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x9178d5aa generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x9198c12b rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x91990771 crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x91e54d82 relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0x9220bb9d crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x92566b3b debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x92628a5f blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x92a086cb usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0x92cc6570 task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92f57fbf sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x932b4378 usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x933740ca cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x9348eb70 tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0x934d2bb9 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x938005b1 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x93a5f757 usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x94508ed2 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94aea11b fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x94c1d06b rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x9507c24f pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0x9511416c mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x957a321c cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0x95800ab1 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x95f4e09d scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x9606e09c inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x968a8fcc tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x9698fb3c pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96d78150 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x96d9b469 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x971ba2a1 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x97325e9a raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x976bbd09 __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0x97a8a52e acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x97bbe826 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x9862d0e3 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x988e4bf6 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x997e50d2 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x99baec42 ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x99cc2539 ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x99f74ccb gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0x99fceef5 bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a752c07 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x9aac86f8 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9af14948 device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x9b0a7058 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0x9b4e4edd register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x9b8c88ac xenbus_map_ring_valloc +EXPORT_SYMBOL_GPL vmlinux 0x9b8d993f gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bc47866 devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x9c02897f sk_clone +EXPORT_SYMBOL_GPL vmlinux 0x9cb3f473 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9d06688b register_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x9d3850e1 gnttab_alloc_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x9dcccdf9 ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0x9df339c9 xenbus_unmap_ring_vfree +EXPORT_SYMBOL_GPL vmlinux 0x9e2c922b regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x9e413d63 relay_close +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9e7d3442 xenbus_resume +EXPORT_SYMBOL_GPL vmlinux 0x9ea32ecb ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x9fc48eaa cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x9fd32062 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x9fdf171f platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xa0091514 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa00f3e4c cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa0301c82 proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xa0c9551f tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xa119e9aa xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa1904cd1 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0xa1ab3866 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xa2317139 unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0xa2435c25 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2b8831f ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xa2c03841 bind_evtchn_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa30dc708 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0xa3129824 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0xa3404106 crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0xa353fffc xenbus_rm +EXPORT_SYMBOL_GPL vmlinux 0xa35db7ca __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xa36ed72c do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xa3830fc7 ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0xa3f46d23 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa4834865 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0xa4857100 bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0xa4e2aad4 seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0xa4e797fa pskb_put +EXPORT_SYMBOL_GPL vmlinux 0xa57d827b lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5cfaaf3 inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0xa5f53fac regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0xa5f66099 platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0xa63a7704 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa6839c0e dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0xa6d38a79 hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xa6e60056 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa70918c6 simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0xa772260c disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xa789e515 sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0xa78a073b sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa7dfe5e1 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0xa7e4734f put_driver +EXPORT_SYMBOL_GPL vmlinux 0xa80fcdb7 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa8137814 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xa8237541 scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0xa8305e11 device_rename +EXPORT_SYMBOL_GPL vmlinux 0xa83cd13e pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0xa8d3d3be skb_morph +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa9064868 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa954d6eb pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xa956a362 register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa9b7afd8 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xa9c012f3 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xaa265a50 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0xaa2a72bf __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xab01acbe gnttab_request_free_callback +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab7b94a5 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0xab998da3 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0xac0292be blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0xac2435da debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0xac4a1905 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xacb301a6 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xaccfc678 cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0xace2d2de sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xacf364f2 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0xad096363 xenbus_printf +EXPORT_SYMBOL_GPL vmlinux 0xad57ed88 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0xad7aaa9b ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0xad93753b tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0xade81d1f regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0xade8c9b1 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae45356a sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0xae606b45 rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0xaeb7f977 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xafbc73e4 sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xb0409b16 blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0ab9f8c flush_work +EXPORT_SYMBOL_GPL vmlinux 0xb0c5edf7 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb0fdbcb8 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb1232014 dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0xb12794a8 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xb12b5367 usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0xb149cde2 save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0xb18298c6 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb2206bff __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0xb244ca15 ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0xb2464a21 ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb2764ad5 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0xb28c5cad raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0xb29c08bb usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0xb2acaf9c crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0xb2febe48 rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0xb313a59e unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb3349ffa tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0xb34018d4 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0xb37d7544 class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xb3bb88bd set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0xb3d39de6 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb404d722 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xb41cb079 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xb4423424 dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0xb476fbc1 cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xb4e14553 gnttab_query_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb4e3825b crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0xb4e5a25d flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb548ecd7 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb6230f1f gnttab_grant_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb65a94b4 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6bc49a9 __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xb6c80004 usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0xb6ed4fe6 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0xb77c0201 blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0xb7ba6928 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb81a69fa ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0xb8e62e47 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xb8f56317 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xb903674c scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0xb9041d8a crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0xb91aa7ad ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xb96655c1 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0xb969906d debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0xb99d5837 xenbus_read +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xba356aa7 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0xba698916 __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0xba8e0967 dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0xba9f6172 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0xbaa3b17b destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbb05128d ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0xbb35800e blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbbf36c0d ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xbc8986f3 device_attach +EXPORT_SYMBOL_GPL vmlinux 0xbc9a4533 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0xbcb96737 inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xbccad1cf sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xbcdf4553 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xbcf981df dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0xbd17d36c hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0xbd273d59 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbdcce1b1 register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbe0f9fdb sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe2a6779 iomap_atomic_prot_pfn +EXPORT_SYMBOL_GPL vmlinux 0xbe3e29b1 rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xbe413599 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xbe5c5149 preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbe778b44 usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0xbe92ba7b inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0xbeb48409 i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0xbef37ac5 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xbf2d7d94 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0xbfa415bc spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xbfd4da78 transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xc00b14f1 ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0xc028984c ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0xc04ca6d8 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xc0a261c0 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc10e7bc2 __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xc1193db9 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0xc141c01d aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc18883ba relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0xc1b9670d leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0xc1c7561f usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0xc1d1e868 sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xc2142add queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc23d91a5 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xc250ac5d hid_connect +EXPORT_SYMBOL_GPL vmlinux 0xc26351f8 bind_evtchn_to_irq +EXPORT_SYMBOL_GPL vmlinux 0xc26ec1c0 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xc2986049 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0xc3164655 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc364cbd7 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc3991363 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3baa30b dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc42f2f94 xenbus_read_driver_state +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4a432ce da903x_read +EXPORT_SYMBOL_GPL vmlinux 0xc4a44f26 relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4f7cada usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0xc52d95aa hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0xc5397da6 xenbus_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xc54edcbd invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0xc591472b blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0xc5a9886f pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0xc5b83f66 devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc5c31e70 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0xc5c5054a tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xc5d9f4de inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0xc5e3dddf wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0xc63f43c7 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc65d41fe sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc67e9c4b ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0xc6f3d5f5 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0xc71c1a7f dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc751c582 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0xc7bedf22 disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xc7d74eb9 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0xc7dbfc64 ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc82a04ae crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0xc82c5c6f dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0xc87a4470 tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc87f7312 ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0xc8c79e39 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xc8d03e75 copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0xc8f3da25 usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0xc8f5e6f1 relay_flush +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc992c940 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xc9d7252f inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xc9e37865 isa_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xca56e871 usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0xca81ea9a xenbus_transaction_end +EXPORT_SYMBOL_GPL vmlinux 0xca9ab70e tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0xcab3d653 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcb061686 kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0xcb34cbee scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xcb901032 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc31db19 scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcc7a3980 xenbus_watch_pathfmt +EXPORT_SYMBOL_GPL vmlinux 0xcc96198b sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xcd22eabd tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcda49909 __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0xcdb4faa1 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xcdd6550e register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0xcdeec0c8 security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0xcdfca707 da903x_write +EXPORT_SYMBOL_GPL vmlinux 0xce4aa154 bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xce736cad blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xce9b8a80 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0xceb06d36 device_register +EXPORT_SYMBOL_GPL vmlinux 0xcebf90cd generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0xcee44482 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xcf0bfd12 start_thread +EXPORT_SYMBOL_GPL vmlinux 0xcf82bff5 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xcfdf8d3c usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0xd0237f17 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd0de4e51 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xd12ac59b olpc_ec_cmd +EXPORT_SYMBOL_GPL vmlinux 0xd14810c4 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0xd152ce4e uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd18adf96 mmput +EXPORT_SYMBOL_GPL vmlinux 0xd1a9a5c7 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0xd21746dd cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0xd223c0c3 ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0xd22eec85 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xd2400a71 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xd24da1cb transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd27d2d95 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0xd27f02f5 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd2cb39f4 sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0xd3160f33 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xd39d7417 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0xd3b62353 xenbus_bind_evtchn +EXPORT_SYMBOL_GPL vmlinux 0xd3b78da3 xenbus_suspend_cancel +EXPORT_SYMBOL_GPL vmlinux 0xd3c64487 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0xd3d14789 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0xd42f1775 sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0xd4605677 devres_add +EXPORT_SYMBOL_GPL vmlinux 0xd49d556b page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0xd4eb1ec1 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0xd4fe4b6e da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd51c4926 rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xd5371df8 dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0xd544bc49 driver_attach +EXPORT_SYMBOL_GPL vmlinux 0xd5ae1e14 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0xd680e49c device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0xd68eaa14 sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xd69bf422 da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0xd69e72ca fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0xd6eb74a7 led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xd6f19cad register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0xd77927bb skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd7fa2a77 crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0xd83242e6 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd846eecf kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd8aedc6b crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0xd901256e audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0xd9042fa8 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0xd951a804 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0xd9ad14a7 regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xd9db21d5 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0xd9fb0aaf inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0xda3a1526 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0xda567280 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0xda9a27d1 led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0xda9e85dc ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0xdaebd354 register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdb216c67 scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xdba8682b crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0xdbdd1bae inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0xdbfbd066 cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0xdc4d5d6b securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xdc5bdda4 ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0xdc69afe8 usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0xdc8630f4 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xdc99cf23 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0xdd08d7fa exit_fs +EXPORT_SYMBOL_GPL vmlinux 0xdd0c292d dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0xdd3f206c tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0xdd512aa0 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xdd5eb6c8 usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0xddd8b5e9 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde255409 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0xde4b1757 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xde4b43b3 spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xde5a4da0 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0xde75a0bb xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0xdee82b0d blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xdf7f5b94 crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0xdffaa1db spi_sync +EXPORT_SYMBOL_GPL vmlinux 0xe0339115 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xe03b1f4b sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xe0406b5a blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xe05c1568 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xe08046d3 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0xe0c7007a usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0xe0ea4d68 ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0xe0f26e9d usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xe12f509b ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xe186abbb crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xe1c813d9 led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0xe1d8d007 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0xe2426710 wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2c868c8 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xe2df2994 md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xe2e3ce38 debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xe2ea96fe crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0xe302200d ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0xe30f18e2 skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0xe329ba3c input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xe358f91f rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0xe3846ed1 kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xe3f7d0d7 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0xe41ef99e sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0xe43b379f input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe4c331b6 acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0xe4c46bea vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xe4d62fbd __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0xe4ee16a2 dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0xe4f9d9e5 rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe51c616a fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe5532d76 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0xe55ece97 __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0xe56267c8 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0xe56566c8 queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xe56bf229 hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0xe5a6f23c xenbus_unmap_ring +EXPORT_SYMBOL_GPL vmlinux 0xe5a98637 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xe5bfc76e hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe65e22a9 usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe6a79538 aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0xe6c0efbb unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xe72f03e5 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xe76176d5 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0xe7840ad1 k_handler +EXPORT_SYMBOL_GPL vmlinux 0xe7a6e174 kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe848460b sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xe8e24702 unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xe918ca2e ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0xe91eb997 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe972e229 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0xe99cc52f ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0xe9c16c72 free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xe9e3d2da regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea14d636 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea503d01 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0xea65ad7c crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0xea6692de dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeb612188 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0xeb8a43ed disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xecce638e hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xed200c77 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0xed939267 regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xedbc6f67 gnttab_end_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xee3ce3c6 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0xee63d23b xenbus_switch_state +EXPORT_SYMBOL_GPL vmlinux 0xeeb91083 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xeecc5cc0 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xef3dacc1 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0xef6bdfcc md_new_event +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xefe0cab3 __class_create +EXPORT_SYMBOL_GPL vmlinux 0xefe21106 snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xf0a7c66e device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xf0fd1d48 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xf161b64a net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0xf1676b41 user_describe +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1985577 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0xf1a86345 __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xf1c03602 rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0xf1f97db5 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xf271bf38 scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0xf2758b6c ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0xf287580f usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf3026d73 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0xf3754d50 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0xf39e13bc bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf453fae5 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xf45b4834 rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf472b71b crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4aebdc3 xenbus_suspend +EXPORT_SYMBOL_GPL vmlinux 0xf4c18e45 ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0xf4cb6f9c usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0xf4f38464 cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0xf5004962 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xf5097427 pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0xf52c3e02 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf577df12 single_release_net +EXPORT_SYMBOL_GPL vmlinux 0xf5945bac gnttab_free_grant_references +EXPORT_SYMBOL_GPL vmlinux 0xf5a401b5 ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0xf5a5ee70 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5a7bca4 platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0xf5c518ae pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0xf5d2eb19 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xf5df06c1 __class_register +EXPORT_SYMBOL_GPL vmlinux 0xf5ec7448 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf5fac6ff dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0xf65b9513 sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xf6b2c8aa spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf6e6d8c6 ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0xf7016530 xenbus_gather +EXPORT_SYMBOL_GPL vmlinux 0xf71271b0 class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf774897f usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0xf78cb5e8 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xf7d28f51 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0xf7f603aa debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xf82f16b3 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0xf84f7143 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xf85b3c8a ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xf87fa9ef ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf88ce198 ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0xf89aea3c dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0xf8b66770 spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0xf8d8bc85 __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf925df77 usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0xf9296970 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9a06fab usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xfa10939f usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0xfa1f4662 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0xfa583f56 inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0xfaa743e7 __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0xfae5e104 pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0xfb2a3293 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xfb46ca86 posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0xfb815413 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xfb8c98ca sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0xfb8e91b9 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xfba732dc md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0xfbc4a860 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc36054c hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0xfc3d5cf5 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xfc407994 rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0xfc5c9430 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0xfc726806 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xfca5158d default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfcd3da9c debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0xfd3930d7 unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xfd51b281 gnttab_end_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0xfd629cf8 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0xfda74e28 user_destroy +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfdf1c041 per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0xfe22c688 usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xfe66371d tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0xfe6c796a inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0xfe727411 get_phys_to_machine +EXPORT_SYMBOL_GPL vmlinux 0xfe74d5e7 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0xfe7a9876 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xfe94d641 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0xfe9790c3 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfed93be5 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0xff2761ce ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_SYMBOL_GPL vmlinux 0xff86dda6 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0xff93fcae sysfs_remove_file_from_group +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/amd64/generic +++ linux-2.6.28/debian/abi/2.6.28-4.9/amd64/generic @@ -0,0 +1,8600 @@ +EXPORT_SYMBOL arch/x86/kvm/kvm 0x37ca7b43 kvm_cpu_has_pending_timer +EXPORT_SYMBOL arch/x86/kvm/kvm 0x39338afa kvm_read_guest_atomic +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0xcd82957b suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0x47172608 uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x1f5ff5cb pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x3ab42e6d paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0x46b16a3c pi_read_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x4e771e3c paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0x4f50394e pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0x5af66929 pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0x5e1fa9f0 pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0x6c76d28c pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0x6f231e8f pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0x8cfb6f65 pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0xa77ac881 pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xf5983080 pi_disconnect +EXPORT_SYMBOL drivers/char/generic_serial 0x0f9e6943 gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0x1737d3d6 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x19306178 gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0x1d282d0b gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x224e090a gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0x3c9a6fc8 gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0x3cd6b610 gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0x51c8cdcb gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0x5d435a4c gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0x976daf76 gs_put_char +EXPORT_SYMBOL drivers/char/generic_serial 0xa5079500 gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0xbe6ec6ca gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0xc2bd11a5 gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0xcf5ce6e1 gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0xef9fa86f gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0xfc518053 gs_stop +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x02861b5e ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x04ca3ec0 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x0b01e325 ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x13475d8a ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x200ea071 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x26284d15 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x27ce61ee ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x2dce01f3 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x444ae8ae ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6496d039 ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6f24d18f ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7186dc05 ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7350102f ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x89f3c07d ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x98558bcc ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xaaee129e ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb83ee62c ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc04bea08 ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc5b7348a ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc8b0fb0d ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd1c60122 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf1291660 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf55f0864 ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/nsc_gpio 0x2f843aa7 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0x30890b34 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nsc_gpio 0xb1b1f859 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x7a7f9e73 edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0x83f5827f edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0xf0b743fa edac_mc_find +EXPORT_SYMBOL drivers/firewire/firewire-core 0x0733d1b4 fw_send_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x12c21cb4 fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1c0bbf77 fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2208fe81 fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0x279983a9 fw_run_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2876619c fw_core_remove_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2fe73c90 fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3c4159d3 fw_cancel_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x45e18cca fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0x66af3f77 fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x80c98e89 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0x973ecc19 fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0xa7433922 fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xc5160813 fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0xdc85ab2a fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0xddde8337 fw_fill_response +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x08b242b6 drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0a83577f drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x143cbe31 drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x15586d50 drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x17041634 drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1b2efe9f drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1f3982ee drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2857a5af drm_compat_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2a25a915 drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2bd035c5 drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2d9db240 drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x349bd7c2 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4659d60c drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x48c19324 drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x49bcc6aa drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x523f0ea4 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5575a9c1 drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x56549195 drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6b173633 drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6bf5422d drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7c356de9 drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x84ac6867 drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8990e44b drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0x89ca5152 drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8bd42f64 drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x96f05528 drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9a3295d6 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa2542dd5 drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa28c8bfd drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa591ed6e drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa9c62548 drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0xacfc33e0 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0xadb4b278 drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb20c0523 drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb2985feb drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb3f6e179 drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb5efce5b drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb790b837 drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb7fa269f drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc618316b drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcb9cbbe2 drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcc726971 drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0xce417905 drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd2588649 drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd8dd582b drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0xdf8e20b3 drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe2376c93 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe3591a99 drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe9ef8778 drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xeaf8ca27 drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf29d48a8 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf4862727 drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf523c71d drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf64a775c drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfafa88 drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x4b62ca08 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x5c50f142 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x28bfb788 i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x69565bf9 i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0x679f4ce4 i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0x4ad66132 amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x027a402f hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x036aa0e3 hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x04403e90 dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x079eebac hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x07d9bfe5 hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0b234c4e dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0cd62da6 hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e134e24 hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0f161e6f hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x10be8193 hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x10bfeda4 hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x158ac548 dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x168dc4b8 hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x19f1f97b csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2112202e hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x28495931 hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2a36d053 hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2c0df5d8 hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2dd29f75 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ebf6e5a dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x32de3c19 hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3bdbb53f hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3bf52960 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3d5aa39a hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x410365fa hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4323d6e6 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4d064a36 hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5619e578 hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5e05c474 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5ee0fab9 hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x688fd8ec hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6c41e3c8 hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x75afbe37 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x79530b08 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7c1a236c __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x85c9cab9 hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x86f6e10b hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x88282bbc hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8bb1fe70 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8c3bd8d0 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8e8339f0 hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9419aee0 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x942311c3 hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9bef271b hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9d853e5b hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa401a5f9 hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xae5e5000 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb1d4482d hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb23060fb hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb68063aa hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xba723e79 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbe69e245 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc3eaa8af hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc6561207 hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcd9e772b dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd177b64c hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd667156f hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdc765214 hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdfff6f2a hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe4f1ebd8 hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe5d2a4e8 hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xed6fe814 hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf1ceb20b hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf21de5ab hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf67bcaf9 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf702630f hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf76c5fc6 hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfa720bbf hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfcd578c9 hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x0c386903 ohci1394_stop_context +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x750956d9 ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xd35dd036 ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x5735c4b6 rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x6392ac33 rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x970caeac rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xe6f70808 rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x14b96159 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x1f2a4a4d ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x2b135513 ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x30961910 ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x32f5b4c3 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4cb69488 ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x73a6f57e ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x77eef51a ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x7a0be102 ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x86f22e07 ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x951fafb6 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xba48a8d4 ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xc555bf62 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xca28bbc4 ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xcc23419b cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd08b6ca4 ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xf9b6699f ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x000ad6aa ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x06830b9a ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x073373bf ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0ae1742e ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0fc7f5cf ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x10a0cdc9 ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x14fb18a7 ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x17f563c9 ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x185953ef ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x19de8c51 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1ade0b3c ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1d0242a5 ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2ae082f0 ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2d284e61 ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2f0db218 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x304535a0 ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x350f6ca4 ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3d396cfe ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3e7bd1ad ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x440a5411 ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x48b59153 ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x521e828b ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x523def05 ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x62000940 ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x63cac1cd ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6518539b ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x71199f76 ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7235cc54 ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x77f52ce7 ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x78025171 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x816eeafb ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x830e43d1 ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x85144001 ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a5c35ff ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8d97ce82 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x90aa1213 ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x92fe2ad9 ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x968d4200 ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96cab678 ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x980b1149 ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x99cb120c ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9a23c171 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d5a599b ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d69bca7 ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9def2f32 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa33390c8 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa83c316f ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xaf2e3edb ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1216612 ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb617feab ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb66fd438 ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbd9cd88a ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbe5782b4 ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc3cff0d9 ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc723dd4e ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xcf7b8dec ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd78660f9 ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdc598cc9 ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xde01606d ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xeccda842 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xed26e1df ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xefa569cf ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf04608a5 ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf0ee3787 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf260cef4 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf45c0c5c ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf96fc9de ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfae3c49d ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x1169e3c7 ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x4a40d5b9 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x587b39b7 ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6246f687 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x63882290 ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6cdd8d85 ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x838c907e ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xa93cbb1d ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xb03a52cd ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xcf13b864 ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xe9284e33 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xeabdbb12 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x0bc535c5 ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x1db44053 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x24b092a3 ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x9a0f35d3 ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xe7a48ed8 ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xfe4a4a4e ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xfe7ea33e ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x0bef1a88 iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x1219eed5 iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x32ba9e92 iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x3f00f6b3 iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x8a05cd71 iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x982a5cb9 iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xa8a8f91c iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xe9a59d79 iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x092d6344 rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x0c2f4875 rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x133b7f38 rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3360af81 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3d0c18fe rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x4de08fa0 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x5395a7a4 rdma_resolve_route +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x91a73844 rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x9c5e9341 rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xa0a7271d rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xa623c75e rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xace96d79 rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xb078209f rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xbaa502f8 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xc2c42d47 rdma_leave_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd3118291 rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xe211426d rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xf447edc5 rdma_create_id +EXPORT_SYMBOL drivers/input/gameport/gameport 0x36e027ca gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x43c1369e gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0x450b2d34 __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x4d90d62f gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x9bda5274 __gameport_register_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa5c63580 gameport_stop_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa78f83c1 gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0xb62240f8 gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xf037f56b gameport_unregister_driver +EXPORT_SYMBOL drivers/input/input-polldev 0x6d022e0e input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x8281219c input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x8f9d46e0 input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xeea0795a input_free_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x26af63eb capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2bc042ff capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47dbfa0a capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x56d382d3 capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x56d99518 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x788d398c capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f71ada9 capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa1bd9981 attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa59e0d2c capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xada5fb07 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb5a664be capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc5327ee3 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc809f770 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe9f62f29 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x010bdc70 avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x3056750d b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x3aaf3c5e b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x4efefdf1 b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x600a40ea b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x7596b3a0 b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x8f92e06e b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x9396f7cc avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x94ea01d7 b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xce310059 b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd2cca776 b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xe1277e1f b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xe8de02d6 b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xf0d1ccf2 b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xfbd07e3f b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x0b534c61 b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x0fbafecf b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2da940da b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x308428cc b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x44c908f3 b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x53935fc2 b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x54b26454 b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xb1aff250 t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xbf995abd b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0xd4981563 proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd81cd6e1 hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x5d53f88d isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x62c47f59 isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xb79acc00 isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xcd5d8723 isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xecbe61bd isac_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x65f7a34e isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x86fe1db5 register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x8b7619c2 isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x044005fa recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x08d4b7e6 recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x1a5161ef bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3a8b3b18 mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3aaa53ca get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x4da50dd9 recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x6d8da0ad mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x86688c84 recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x950d3fc5 mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x9a21d0ef create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x9f0102ea mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa71a9a55 mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xab2cb383 mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb548a5eb l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb62ddfef mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xbc8b4f9d mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc21a8eea confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc308c3a1 queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc4a99c1b dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xebc60954 get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0xa6e507de mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0xf0ece626 mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0x15c7f7f5 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0xde4df415 mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0xa0346495 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0xd1b80cd3 xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0xeefe06e6 xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x09417631 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x14bb1b80 flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1ce8ee3b flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3e0354fd flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x4f066cef flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x67e2df1a flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x6aa2d6e2 flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x76260730 flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x90052dc7 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x961d5416 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xa1e63042 flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xab61432d flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb3bbe807 flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb5078dee flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc0e47184 flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc4439c58 flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd7024164 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xe06f55f2 flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xf22bafd4 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x15fd1a8d bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x669968ee bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x6aef312a bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xddcc0c7e bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x272cda06 dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x7028aa56 dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x713c32c0 read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xa0c0ddf7 write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xa0f91369 dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xaf651d53 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xb873e685 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xd3dd54dc dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xf4826979 rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0x1dd1378f dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x04cb99db dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0c457c5c dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0d3785b4 dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x1bbd3d4c dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x273c762e dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36397c4d dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4db3899f dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x51f3767c dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x53efe99e dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x5497e6fa dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6988f784 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6c29bdbc dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8f326272 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x97614994 dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac3153eb dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb031117d dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb3a4edac dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc324b69b dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc5694d34 dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc80754c1 dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcb89fc7d dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcca08cb5 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcce0eeed dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xce138fe8 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd2a792b6 dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd52e8cf3 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd639b9bc dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd7765e69 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xde915a0b dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xee73de0a dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf3990030 dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf61bb3f8 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf86f20c5 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x047e966c usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x8a412dc2 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xafb7fc3b dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xbabc5756 dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xcdf89d2b dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xce99a786 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xde20518c dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2e45e3dc af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0bbc3b0e dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x495d64a4 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x700da642 dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x9f3660c8 dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xbda7cd31 dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xcd386de4 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xdae85c33 dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xe8d38cd3 dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xf0d1cede dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xfae9ae1f dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xff8a8435 dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0xf43578a5 af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0xa21d924d au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0x2b61daec bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0xebc4c7a2 cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0x878bf5eb cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0xba64a39d cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0x425d558b cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x845d1cf6 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x8d24aca7 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x189a3589 dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xa23fd840 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0xbce99c45 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x12194dcf dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x184c4e33 dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x361e6fbc dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x4d4020e4 dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x8c5b5fae dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xc257914d dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x02f6a2f0 dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x3c127722 dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x522042ce dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x7abcd71c dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xa4cf76cc dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xae2073b8 dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xb24f9af4 dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xb69926e2 dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x1b6efa3e dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x66d93f68 dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xa5c1014f dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0x88fb2e82 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x81233094 dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0x2622b858 isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0x43cfff61 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0x493cb9a3 itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0x1d62970e l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0x6d3f6bab lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0x8a39b3c9 lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0xb2829354 lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0xae717259 mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0xb9d26467 mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0x33be1bd4 nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0xfe9b09fe nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0x377ad9e5 or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0xe9447bcd or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0x41232796 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0x8ffb1922 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x62ffbb58 s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0xdfd039c8 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x7b666d76 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0x9a10b079 sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x25a2deef sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0x8fc79f12 stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x0129ca93 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x2b8923d2 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0xee25d306 stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0xa44a3bac tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x8cb4082b tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0x2f93d6f3 tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x98d39ed9 tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xbf922729 tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0xd09722ba tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0xd4f44f4c tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0xcabc6c01 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0x94b4442f tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x00fc0484 ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0xab6c7dd9 ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x999b2d37 zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0x97c9baa5 ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xc7e262ac ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xec256366 ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x3f3b9a4d bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8d16fd93 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xf428815d bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x85f16026 btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc77d98bf btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/cpia 0x75affab9 cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xb93903ba cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0x2b83e4f9 vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xf57a0bec vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x85d97a00 cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x99d13592 cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xb27942aa cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xb49be76f cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xedf73980 cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xf65096cf cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x3a349d5a cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x3e9612d8 cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x4959b9a7 cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x635f22cf cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x70264e66 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x71cf0284 cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xf98c4a62 cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x0720dad5 cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1e5dbe45 cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3ef00fdd cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x512264db cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x577a621d cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x59c55b9e cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x62da3f80 cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x711b33dc cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x76b3aaaf cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x8b6d7686 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x911ca9b9 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x92fc3c41 cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9bc224aa cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xae242734 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb57fceb9 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xbfda1f59 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc4ef6497 cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xca69ba3d cx88_shutdown +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd6eea48d cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xea0cf6f0 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xfd8a838d cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xfec41258 cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x55c39821 em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x5f928542 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x0e207c55 gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x13cd9eee gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x347d2757 gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x5b4540ca gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x99aacb41 gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xba0a9c48 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xba2f2cdc gspca_disconnect +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0d96278a ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4205c92c ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x43cbdf5a ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4eac4bbb ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x570664fa ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x79a507e1 ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa964ca64 ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xbe6182f0 ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xcbde9982 ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xe5be385f ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xeb1f4dac ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xf5c94337 ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xfa0bb38e ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x3d52c253 saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x4db99a14 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x6cde5a42 saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb12de8be saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb539df6b saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb6c0eca5 saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xc7c3b07a saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xceb910e3 saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd89f2fc1 saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xdce94601 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xedb1593b saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xf9ff4952 saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/soc_camera 0x007ad137 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x51518a15 soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0x6d0666ca soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0xb452a2e4 soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0xbdec897e soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0xf263ac37 soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/tveeprom 0x1690b3c8 tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0x83cae89f tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x0d0b2da1 usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x0dfd23fe usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x297bc6b5 usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x7e2d191c usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x94ee644f usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xca88aff4 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0x6f469c50 v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x85440cea v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb3758c6e v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd2894ef5 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x34c080b8 videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x701f9958 videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x8ce9b366 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xc5a7d102 videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xcf23894b videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xf751e685 videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x3a5c5f8e video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x49cfb47c video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x97325554 video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0xaeb5335b video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0xb1981559 video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0xbc0ec31e video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0xdbed55ac video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/videodev 0xf4ab57de video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xf4dc31b7 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0xf93a194b video_ioctl2 +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x3762dd30 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5aa1a02c videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x7d26cdd9 videocodec_unregister +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xb15312b4 videocodec_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x03337386 mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x04186eee mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0faa86a8 mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x105d4f47 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1fd4520a mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x26a16e53 mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x29020507 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x30f385c0 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3737497f mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4cc235f6 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x51387c0a mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x57bc6003 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x69682b92 mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6c47b0d8 mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6e83a3c9 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x729fae62 mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7da11614 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x88f9163b mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x94b67367 mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x957a0862 mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x9ab8426e mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xab0a461c mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd2c30974 mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xe56585f1 mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x03dbfc9d mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x198305c9 mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x2fd29758 mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x3eb15dc1 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x5343f5a3 mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x673465f9 mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x67bf9095 mptscsih_suspend +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x68502b74 mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x69cee3ac mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x724162ff mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x74b4c2b3 mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x7c95522a mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x8ef6ac13 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x94e6bdd1 mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x99fe908b mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xaedc6b0d mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xca25b525 mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd116e2ad mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd8ee0896 mptscsih_io_done +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd902c7a6 mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xecf49c68 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xf8a92a81 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfc1b87f4 mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfd3e8e32 mptscsih_shutdown +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x02e531d2 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1b4eb87f i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1e6386c7 i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2b6e2695 i2o_device_claim +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x32b35498 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x44049f41 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x44639581 i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x5957cc68 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x692dc3cf i2o_cntxt_list_remove +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x720b95b0 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x80cae138 i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x97d1531b i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xa7e63cf0 i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xab766960 i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xac2c3c2c i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xc8b4e188 i2o_cntxt_list_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd9f06a17 i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xdcc7b04d i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe7c5a2a1 i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe975ee0b i2o_cntxt_list_get_ptr +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xfa8b63be i2o_parm_issue +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xfaaca1bd i2o_cntxt_list_add +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x8d8072bf pasic3_write_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0xf2989247 pasic3_read_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x61580116 c2port_device_unregister +EXPORT_SYMBOL drivers/misc/c2port/core 0x8efd8748 c2port_device_register +EXPORT_SYMBOL drivers/misc/ioc4 0x213544c6 ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0x4a1b4db2 ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x13288034 tifm_register_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x479b4d60 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x4c569de9 tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x523a43ff tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x587d36e8 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x6da5888b tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x8e596611 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0xa71353f0 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0xa8c2ec46 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0xb3193714 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xcfd04908 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0xd18a9482 tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xda9626db tifm_unmap_sg +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x17314b93 mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x6e9be3cb cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xcb1ee961 cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xe012f0f1 cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x14087773 unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x25bbe5aa register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xadcf4d3a map_destroy +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xd2cda739 do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0x60064125 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0x2bb097e1 simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x7756c0a5 add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0xbaf734c8 del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x046812fa mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/mtdconcat 0xf64b8bfa mtd_concat_create +EXPORT_SYMBOL drivers/mtd/nand/nand 0x048072b9 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xc09627f4 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x4aa2274e nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0xb779cfd9 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x4b7c4d6d onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xd2ee8327 onenand_scan_bbt +EXPORT_SYMBOL drivers/net/8390 0x01f2f66c ei_poll +EXPORT_SYMBOL drivers/net/8390 0x430ecaf8 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0x85d9f5e1 NS8390_init +EXPORT_SYMBOL drivers/net/8390 0xb2d94754 ei_close +EXPORT_SYMBOL drivers/net/8390 0xb5aacd24 ei_open +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x44578575 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4f4f6fb7 arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x711cba15 arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x7ae1f9b7 arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x868e1fdf alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x89d26a69 arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xa84f0ce2 com20020_check +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xac0c6866 com20020_found +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x0b879f3c cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x1485ed18 dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x15c3ebce cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x2ee3d53f cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x3a01f06c cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6e26251f t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x7cae4e14 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x88212784 t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8a911a55 cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8d9d51c0 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa9043926 cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xac40f7d3 t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xb6ae4892 cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xbaec17d3 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xe2bf58ff cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xf06e258b cxgb3_free_atid +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x243033f6 hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x30d5f471 hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x5a70a07b hdlcdrv_register +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xb892355d hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xc8db23bf hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x0f23e0f5 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x452343a8 sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x560753a0 sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x6025bc52 sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x6d4d2dd6 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x738a80ed sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x817e1bbc sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xb1b071ea sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xb4389d15 irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xec563aa1 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/mii 0x0d0b49df mii_check_link +EXPORT_SYMBOL drivers/net/mii 0x14780d20 mii_nway_restart +EXPORT_SYMBOL drivers/net/mii 0x2278eb66 mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0x351b7c17 mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0x39c4e24e mii_check_media +EXPORT_SYMBOL drivers/net/mii 0x5ade8469 generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0xe529560d mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xf7543166 mii_link_ok +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x70dc209c free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xff804612 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x6e4e49dd register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xcb4e828e pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xe42c8acd pppox_unbind_sock +EXPORT_SYMBOL drivers/net/sungem_phy 0x6c6b8091 mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x10aabcdd tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x726ef1d2 tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x73da2224 tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xb21f37bb tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x02beffba alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/hdlc 0x29a8a9e6 unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x5495abdb detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x890562a3 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0x97534d12 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xc3a64c26 hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0xd5f50fc4 attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xde91ced4 unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0xffbedea6 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x1f58396c sppp_open +EXPORT_SYMBOL drivers/net/wan/syncppp 0x6bb186be sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x82ec86f1 sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x8a0829c2 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/syncppp 0xca747c02 sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0xe1248617 sppp_attach +EXPORT_SYMBOL drivers/net/wireless/airo 0x76e7f2e0 stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xccdb682f reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xf2d5dc57 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x47a45c8d atmel_open +EXPORT_SYMBOL drivers/net/wireless/atmel 0x6d0909f1 stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0xc09eecbe init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeb824e25 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0b9a6277 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x162165b3 prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1723ac32 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x18fdb875 hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1cef48be hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x20893968 hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x20bc7c22 hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x279a2f45 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x30486678 hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3890733e hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x4726cd9e hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x563eb543 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x60a31486 hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x63c1a373 hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x69000d93 hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x70e7bbbd hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x7d16a1f8 hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x87057bf4 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8a775075 hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8af1f3d6 hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8f9248ea hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x949556d6 hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb81f7343 hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb87cb543 hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf40eb4e6 hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf5a0512d hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf5c4d747 hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x00b4cbc7 iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x029ea41e iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x04f5e005 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x09fbd3a3 iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0af8ade2 iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0b607ef2 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0cc386b7 iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x133ee5f2 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x19bf4ec1 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x203b991d iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x21017036 iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x22670d78 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x23692254 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2408d9b2 iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2bf91e35 iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2d490587 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3244d8fd iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x349093eb iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x36e42206 iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3786d444 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x384f22d2 iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x45dbdda3 iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x45fff929 iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x46d82df0 iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x49f12938 iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4a189256 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4dda9ec1 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50cdf051 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50f72c5d iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x513e8f74 iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x58070b7c iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x58577c30 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5a2ebf22 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5b56fe2b iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5c59811b iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5ea6f9ab iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x60774702 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x620ee33c iwl_rx_allocate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x65c159b0 iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x66ec2637 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x680d1efd iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x68be5273 iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x69187843 iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6c7f3073 iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6d9d1e6d iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6e16ff25 iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6ed5e34b iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x73a96638 iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7672435e iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x78b6694c iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7fdef185 iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x81742f1a iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8751c872 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x887a3982 iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8c57cfbe iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8fb5242e iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x91bd4bde iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9452e4d4 iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9516977b iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9971bcb8 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9a5b2923 iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9b38acb2 iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9f943e14 iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9faced57 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa398909e iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa633a23a iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa95ce5c2 iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaf95ef6c iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb26cfc87 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb3c73a71 iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb667156c iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb8870094 iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc217c721 iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc47b95b7 iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc6ece9aa iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc862437e iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xca2ad44f iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcad7e242 iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcaf1bd96 iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcb7abdf6 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xceb812c4 iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcfc3fad8 iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd1a829e0 iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd3e5fdd5 iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd4762469 iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd56f7f34 iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd646fb38 iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd6b38bba iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd6d305fd iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd86372dc iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xda67de82 iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdabb757c iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdc94b17b iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe1ad9e55 iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe246f32f iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe2f4e259 iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe5d48e88 iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe76a87f9 iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xea678353 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec3525aa iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec723c20 iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xed26b188 iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xee6c199a iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfc097269 iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x081f289c __orinoco_down +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x3c828441 alloc_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x6d109184 free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x76c13b5a orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xfea52ac5 __orinoco_up +EXPORT_SYMBOL drivers/parport/parport 0x0218cd30 parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0x0649c985 parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x121501f0 parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x1358f7cf parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x27a59632 parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport 0x280213d9 parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0x2d8a86ed parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0x4b6dcdbe parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x52665f44 parport_release +EXPORT_SYMBOL drivers/parport/parport 0x5bacab77 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x6391b648 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x6c866812 parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x6dcb9e2d parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x6ee52af6 parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0x8ae3f27b parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0x8bd666c0 parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0x9e95230b parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0xa74ba9b2 parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0xa8453476 parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xa9d55575 parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0xc30479dd parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xd128bdbf parport_read +EXPORT_SYMBOL drivers/parport/parport 0xd37be8dd parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0xdb3ef6c1 parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0xea374aef parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0xeba9d0d0 parport_write +EXPORT_SYMBOL drivers/parport/parport 0xf0b96358 parport_claim +EXPORT_SYMBOL drivers/parport/parport 0xf3ce8c7e parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0xf6ad155f parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0xfbbf186b parport_negotiate +EXPORT_SYMBOL drivers/parport/parport_pc 0x6483beb2 parport_pc_unregister_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xf5c67f4e parport_pc_probe_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x044c0b21 pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x3ad47365 pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x3c8a3855 pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x3da78356 pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x799082c4 pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x980a440e pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x9c18d752 pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x9e8244ce pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xa298ed51 pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb033e7a6 pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb25a0347 pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xbff8c39f pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xce18f57b pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xda494283 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xdf6e7b3b pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x02f8058d pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x035a75ff destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x03ee0008 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0eff5a3a pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x12382e9f pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x125112fa pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x248bfd1d pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2dc9b21f release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2e7dc57a pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x30e8c5bf pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x42f2631a pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4435b0b9 pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x5913a5e4 pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x599bbc04 pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x6f6e1822 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7e679582 pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x84d9c4c6 pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8f0807c8 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa45c5cb8 pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa71add6e pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa8df65b6 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb00a692e pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb41c0b5c pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb85aadf9 pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb85cb926 pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd24f1bb6 pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd33e53c9 pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd5e4dd93 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xdddf8b02 pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe06ab998 pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xefc47ae3 pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0x5feb83a3 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0xede2fc3b mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x15f6c874 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5666e559 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x64cf012e qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x775afc49 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x95bac046 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xda8e3ae5 qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/raid_class 0x0dc57d18 raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0xc5563359 raid_component_add +EXPORT_SYMBOL drivers/scsi/raid_class 0xe0bf0663 raid_class_release +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x10c00f59 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x1d4e448e fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x2e043bc4 scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x3d67ab72 fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x62ebb53f fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x6c000492 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x77d175c0 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7c6174f2 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x961ada1a fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xba5acaa8 scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xcafda9cc fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe32bc6cf fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x08c07e10 sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1a095fca sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1cac7425 sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x288707a9 sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x3618098c scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x381d0afa sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x3fc59649 scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x458292f7 sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4b6b549a sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x549aac81 sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x5a467155 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x644eba08 sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x6a6c2d17 sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x75f28d70 sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x8030b71c sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x95c48265 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x99e34eee sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xae3654d8 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb537ea1f sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xba7faaee sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xbacd035b sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xbef8d0c7 sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc1003102 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc5c1c5bf sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf429169a scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xffad1e35 sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x04498940 spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x23e00bdd spi_display_xfer_agreement +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x52afaa8d spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x546aa1f6 spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xbda98451 spi_schedule_dv_device +EXPORT_SYMBOL drivers/ssb/ssb 0x0afc1c1c ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0x1bc66f60 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0x2168a3db ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x221580d0 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0x3f440019 ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0x4c921c03 ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0x5ace0c95 ssb_set_devtypedata +EXPORT_SYMBOL drivers/ssb/ssb 0x65c3fb0b ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x87adfe51 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0x8f197b01 ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x90e11565 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x92e0d08a ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0xa2363ca0 ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xb20becbe ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0xb2970c40 ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0xb322d03d ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xdaacf0c0 ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0xe0e7985a ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0xe351c81d ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/telephony/ixj 0x20e3d9d0 ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x5b6f6d79 phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0xb6c52ce9 phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x23e3c4b5 usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x5413aab3 usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x800a17a8 net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0xa64d0663 sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x1c63be7d lcd_device_unregister +EXPORT_SYMBOL drivers/video/backlight/lcd 0x5d9bca00 lcd_device_register +EXPORT_SYMBOL drivers/video/console/bitblit 0xfedea34a fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0x38e63574 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0xfa6b2f0f fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x5100a206 cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0x54ea6ef8 cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/cyber2000fb 0x72c495c5 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x8631248c cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/display/display 0x2137b5f4 display_device_unregister +EXPORT_SYMBOL drivers/video/display/display 0xac53975d display_device_register +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0x1be1b159 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x5c701b36 g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x7c23a93f matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x8edca8de matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x5388d5aa DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x8eb68ae8 matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xbe103682 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xf8be559c matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0xc816b32d matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0x704a8af7 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x000cb93a matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xa00ce4a6 matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xa48e5544 matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xf4571ace matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x9645a5e9 matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x9cb8fe7d matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x09c1e2ca matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x6fbcdf3e matroxfb_read_pins +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x8fee172f matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x9a8a0f73 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xce44db56 matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/output 0x8a205396 video_output_register +EXPORT_SYMBOL drivers/video/output 0xfbbaabdc video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x3da4a575 svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0x46c77568 svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0xa94cf78b svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xd9422b1b svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xe9688576 svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0xeb8cd4cd svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/svgalib 0xf469d55a svga_tilefill +EXPORT_SYMBOL drivers/video/syscopyarea 0x4c48a27b sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0x48c51b69 sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0x3b7d8c46 sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x12a2face w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0xed142032 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x1597cae7 w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xaaa7c65c w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x14e6edbe w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0x1852edb2 w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0xa5bcb89a w1_register_family +EXPORT_SYMBOL drivers/w1/wire 0xb24549c5 w1_unregister_family +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x16398583 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x19ebf19b config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x5399c7f3 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x59c48d4f configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x9f906c69 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xa0f6c135 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xa1cf56cf config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xa750e5d9 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0xd45a6ca6 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0xda34f9e0 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xf166c617 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xf8da3fd7 config_group_init +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xc4ec2c71 nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x34510db0 nfsacl_encode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x9a9ea58f nfsacl_decode +EXPORT_SYMBOL fs/nfsd/nfsd 0x23f0a2c8 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x46ffdc39 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x96ce9bb4 nfs4_acl_new +EXPORT_SYMBOL fs/xfs/xfs 0x1a97edde xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x651c2313 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0x276c7e62 crc_itu_t +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc7 0xc086bfba crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x13c0c38e crc32c_le +EXPORT_SYMBOL lib/libcrc32c 0x41bcd8b3 crc32c_be +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0xe561bb4b make_8023_client +EXPORT_SYMBOL net/802/p8023 0xe6ebda46 destroy_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x0b3ac49a p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0x129c0285 p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x160dd0c2 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x18c0e953 p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0x244c6d40 p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0x2c9cab58 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0x2fa4eca4 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0x3239bbfe p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0x38a117d9 p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x41e6bc51 p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x4d58a998 p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0x5e0ef374 p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0x61852dea p9_idpool_put +EXPORT_SYMBOL net/9p/9pnet 0x6954df87 p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x6aa3ee42 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0x6c5e479c p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x79472263 v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x7b9ce06c p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x7d3881d5 p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0x7fcbcded v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0x80ecf101 p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0xb84ef7fa p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0xbaa17b44 p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0xccdf7c0f v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0xd1a8e4ef p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0xd51b2a6b p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0xe23d2391 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/9p/9pnet 0xe7c9809b p9_client_walk +EXPORT_SYMBOL net/appletalk/appletalk 0x5b1e786f alloc_ltalkdev +EXPORT_SYMBOL net/appletalk/appletalk 0x9b301834 aarp_send_ddp +EXPORT_SYMBOL net/appletalk/appletalk 0xa2cec9cb atalk_find_dev_addr +EXPORT_SYMBOL net/appletalk/appletalk 0xb1e60933 atrtr_get_dev +EXPORT_SYMBOL net/ax25/ax25 0x0479d44f ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x57eaaaa4 ax25_linkfail_release +EXPORT_SYMBOL net/ax25/ax25 0x66986d66 ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0x7f9b55f4 ax25_send_frame +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0x91133aac ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0xa2d15533 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0xa2e8404e ax25_find_cb +EXPORT_SYMBOL net/ax25/ax25 0xa7bc88de ax25_listen_register +EXPORT_SYMBOL net/ax25/ax25 0xbc2f982a ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/ax25/ax25 0xe0e640d6 ax25_rebuild_header +EXPORT_SYMBOL net/bridge/bridge 0x94f3df88 br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x8e432571 ebt_unregister_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xda872124 ebt_register_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xfc79efb0 ebt_do_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x0023e882 ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x29c8b44b ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x3098e858 ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x319c6a99 ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x34712d7c ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0x35085f97 ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0x413e2f80 ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211 0x44c08902 alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x4aea2c47 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x693afdbd ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x6f7b72ff free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x7cbdc8a3 ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x89cbdbd3 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x9bde5b18 ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xcc5a16ff ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf06b79c5 ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf2abe29b ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xfe7d9840 ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x246bf6ed ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x350791bc ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x67bd664a ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x697d2bc7 ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x8b047759 ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x9f669335 ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ipv4/inet_lro 0x03ec658e lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x147289bc lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0x66c33f81 lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xad6e1e8c lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0xb5893412 lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xd8ae7e6b lro_receive_skb +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x85e34277 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x87673fa1 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x8db4d1cd arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x8e6bb6ee ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xd4a1a856 ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xf2485421 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x1733b73c nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x33d2465a nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x4a8472d8 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x88248ea3 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x8d3cb970 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/tunnel4 0x42498ec7 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0x93abb9f4 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x14502172 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x61641806 ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xa3729832 ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xdc1c5c1b ip6t_do_table +EXPORT_SYMBOL net/ipv6/tunnel6 0x5d489da9 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0x66df2d70 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x03a4d370 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4907b9c7 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4f7944c7 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x6d02444c ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x778f667c ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x805666b8 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x89a36967 ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xe1d5bd76 ircomm_connect_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x02646a7b irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x1c3c5ed7 irttp_data_request +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x27a81314 irttp_dup +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x40f175dd iriap_close +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x48f4665d irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0x529bd046 irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0x5bc6f219 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6e27ab0b irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x72e09736 async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x74084d63 irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x79a5bbd2 iriap_open +EXPORT_SYMBOL net/irda/irda 0x79c8734b irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9a95b2c1 irlap_close +EXPORT_SYMBOL net/irda/irda 0xa5d9a86e irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0xa8ea8d75 async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0xac7660d2 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0xb4dc0e5e irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xb60e3d4b irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0xb90e45af alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbdcbcaa5 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xc48e02fa irlap_open +EXPORT_SYMBOL net/irda/irda 0xc4f83df4 irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xd6deeaae irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xe7c4626c irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0xe91212c5 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0xea3717cc iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf3866b3a proc_irda +EXPORT_SYMBOL net/lapb/lapb 0x01f280f2 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0x05a53f6c lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0x0cedfa6d lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0x26ab30a5 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0x38a0748b lapb_register +EXPORT_SYMBOL net/lapb/lapb 0x3d3bbc42 lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0x887b3182 lapb_data_received +EXPORT_SYMBOL net/lapb/lapb 0x989e9a91 lapb_data_request +EXPORT_SYMBOL net/mac80211/mac80211 0x005ec1fa ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x015a9bb3 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x02bd1c8d ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x0382e53e ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x12cd250c ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x15d8cb36 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x16438b95 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0x17bec652 ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x23dec480 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x27e0ffa5 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x2e21261b ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x4965dc2f wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x4d370b4b ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x50227405 ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x5801f61b ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x77d1e6af ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x7bab58bd __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x7e5d9c80 ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x7f1473e1 ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x84a950c1 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x89472716 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x89655926 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x96186dca ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x9dd09d58 ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x9e4bc95e __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x9f0f00bf ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0xa6a1c718 __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xbc17239c __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xc0770aba ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xc94eb638 ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xd7901b4e ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0xdaae9a94 ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xe4a47dd9 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xe64445ba ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xe7107b61 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xf6655f1b ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xf6acdec2 ieee80211_rts_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x10559051 register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x1b1bae1f register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x3200ca89 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xbc352f79 ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xc57ba2d6 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xc8132e28 ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xcccb6698 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xdc6c9dff unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xde6e64a3 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe12f1d59 ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe180956a ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x01563892 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x0340e888 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0x119c7478 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x2446c584 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x7d7cbaf7 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0x8ec467d3 xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0xbc3e10a6 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xc1c7cf1c xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xcc641c44 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xd314bfb6 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xdc33b3da xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/phonet/phonet 0x04685db6 phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0x1123cf0c pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0x341f58c9 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x569e300d phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x59272dfd pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x7303355c phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x914a703d pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xf00bfd57 phonet_proto_unregister +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x02b7f895 rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x133ba0f6 rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1753e81c rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1e050a28 key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x4d72f762 rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x6170abba rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x83541c85 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x83d6f51a rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xabac1425 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xae046a2a rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb01e171c rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb26d1725 rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb6d4ba21 rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xdf4202c8 rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf5cc50eb rxrpc_kernel_begin_call +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x0a18033f gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x19ce6372 gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x1d2d6602 gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x31d0dbe1 gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x38941db6 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x43c0965f gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x57df116d svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x6c9391a3 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x7ba94fc2 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8836eccc gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x00bd19ed svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x047b2fb0 svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05a80cb4 svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0a8f9ccc rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0b267f41 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1302f79a xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x145e92b9 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1b30a51e svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x23c35a2b xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x241c0230 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x27d0e2db svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x32064700 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x32ff2a90 auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0x334834ba xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x37d14b81 xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x392307c8 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x476ed128 xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4c6a4ca9 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4f21a52c xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x521b8168 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x549aa492 xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x551e1977 xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x566c4388 svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5e4252ad svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x72ab7c8b svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x769d8f12 auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0x77aeae2c rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x77d52968 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x81c256b1 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x89a00b58 svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0x987442a6 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x98fd545d svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0x99c9ef7f xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9c0215aa cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9e264ddd xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9efbd587 xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa35efa45 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa64e4e9d xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xab91f75e cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xac2c9fc9 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb53b14cd svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc2ccdd1d rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc62283f4 svc_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd377133d xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd99a9b2a sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0xde56bc35 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe20f13c0 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe57f161c cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe8d7e9f0 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xeb595f84 xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf2fdb746 xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf89dfa40 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfce29555 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfe53cd8d read_bytes_from_xdr_buf +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x0b074a7b tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x23daecbd tipc_send +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x33ec328c tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x419b02fc tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4da5191a tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x6ab8bc0e tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa1b42d32 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb1f8eacc tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xb6e7e20c tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0xb75aed2f tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xbc0026f1 tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0xca395aba tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xcee290be tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xd169c8c1 tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xd9b134f9 tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xe8338d1b tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xfb470a7d tipc_createport_raw +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0x27c3ac49 register_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x00e425f3 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x272a0fb9 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0x798f29c0 regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xbaffd8f2 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xf462259c wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0xf914ac04 wiphy_register +EXPORT_SYMBOL sound/ac97_bus 0x07918f29 ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0xec2611ea snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x5f33beab snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x81855aa8 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xc04ce214 snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xdb4236a5 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x06852efa snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x093c8e7e snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0x320a4f60 snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x012e6c7a snd_card_register +EXPORT_SYMBOL sound/core/snd 0x0383ac59 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x04f49fc3 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x11dc229e snd_device_free +EXPORT_SYMBOL sound/core/snd 0x14fc7185 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x19f13bdc snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x1cf17319 snd_component_add +EXPORT_SYMBOL sound/core/snd 0x2200a697 snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x2ae3deaa release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0x2e82b405 snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x30083944 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x3130359f snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x3267b069 snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x4100c868 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x42144d83 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x45f9daab snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4b59efd9 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x4e6fa4c1 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x515094e5 snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x518bb7f8 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0x5c1e9440 snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x74df9df8 snd_card_new +EXPORT_SYMBOL sound/core/snd 0x79bc7b8a snd_ctl_register_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0x80b9d986 snd_info_register +EXPORT_SYMBOL sound/core/snd 0x817cb26f snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x8359c3b7 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0x848deec1 snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x8913208a snd_card_free +EXPORT_SYMBOL sound/core/snd 0x891d4a77 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x8b9befdf snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x9033b9e1 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x95825832 snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x9777256a snd_cards +EXPORT_SYMBOL sound/core/snd 0xa0469e71 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0xaa40b2dd snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0xaab12cb1 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xb57e4bb1 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0xbfbf7863 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0xe243dde3 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xed00ec72 snd_device_register +EXPORT_SYMBOL sound/core/snd 0xf5d4c2a8 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0xf70e1ee9 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0xf8707307 snd_ctl_unregister_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0xf9d7892d snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0xfe4617e3 snd_device_new +EXPORT_SYMBOL sound/core/snd 0xfe5efee2 snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd-hwdep 0xf39ccf0d snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x19cc2ce3 snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x2ca6c797 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x399fe6f1 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5a1328a3 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5d2a3a58 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xc6829020 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xf2d3e8c4 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x06003fe1 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0x0ce43d8c snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0x0e309e28 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x1a54e0f7 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x1d236cde snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x2ab122c3 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x2e8be812 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x393574f5 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x4226e4b4 snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x4cac593e snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x5813bfdc snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x627701c4 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x64c03c6b snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x671c6cb0 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x706b70ac snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x719614e6 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x95a1e15e snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x9bd5ef78 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x9e0d15b9 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xacdd33ec snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xad6c3250 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0xb267c67c snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0xb2f8cfb0 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xb9831582 snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0xc11b203b snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0xc4a31c56 snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0xc9865e0e snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0xc9901771 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd5039c6c snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xd76a3496 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0xdfe4cac8 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0xe0f6408c snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0xe51a1c64 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xe7a64f52 snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0xeda6d608 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0xf06fe2c1 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xf75351dc snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xf95e655c snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0xfa7aae98 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xfeff32ec snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-rawmidi 0x210631d5 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0x28036db7 snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x3138628a snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0x4de0958e snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0x4e1b234f snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x58052732 snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0x619d48ad snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0x679d9229 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x795b37ac snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0x916ec20e snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x954b2ff5 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0xa74bd9fc snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xbf395332 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0xcede065a snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0xdcb7cc58 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xe5e1c662 snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf7a3757c snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-timer 0x086a1982 snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x4cad173d snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x511f61d2 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x5f6aecda snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0x9c25e64a snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0xa78651c9 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0xbbe6cd52 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0xc27b7619 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0xca6518ed snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0xd036d07a snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xd0eb636f snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0xe0d08ef8 snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0xefe0f9da snd_timer_start +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xc515d390 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x036f5b74 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05b1bf24 snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x106a139f snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x14f1923b snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x4844f636 snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x5e8ff940 snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x7361b9a6 snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x7e1428dd snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xc34963c7 snd_opl3_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x2ca48922 snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x38d11b6f snd_vx_dsp_load +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x50ad95f5 snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x741250bb snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x88bef506 snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x9b35aa12 snd_vx_load_boot_image +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xa0e10508 snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xbe94844d snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xffedf260 snd_vx_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x1f6caac0 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x1fc28704 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x25a4362b snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x4a7ea3bb snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xe1819fe6 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xe4a551bf snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x1ea2298a snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x3758dcb5 snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x522cd331 snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xa8534511 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xdba2e24f snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xf835d2f4 snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x0bbc1902 snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x35548c88 snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x560730a5 snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xfd81cb9a snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x49176490 snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0xee0a08d8 snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x6196ec0e snd_tea575x_init +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x973c77fd snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x13cbaf2e snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x50f62fd8 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x6039b003 snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x87e6ad95 snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xecf2a18f snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x0b8ad976 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x3b397fdd snd_i2c_sendbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x6973e42c snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x6a1f02a9 snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xd3d1ffba snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0xf2ace499 snd_i2c_device_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1bc99362 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x2b606d27 snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x3d05c4f2 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x55c31e3f snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x5ec553aa snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x8bc3c50a snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xbac25f4b snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xc461bfd9 snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xceafd18c snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xd8bcaa21 snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x3976304f snd_sb16dsp_configure +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x91775e2b snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xbe9a5270 snd_sb16dsp_pcm +EXPORT_SYMBOL sound/oss/ad1848 0x1583482b ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0x26c427ee ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x41faa6a4 attach_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x55262c70 probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/mpu401 0x4200d430 attach_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xd9ec5db4 probe_mpu401 +EXPORT_SYMBOL sound/oss/sb_lib 0x2cc65c73 sb_dsp_init +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0x7aba10e7 probe_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x5b74b9fb mixer_devs +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x7e1186bc sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0x88b23099 midi_devs +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xaba70058 synth_devs +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb0225017 audio_devs +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xc8c20e01 sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd834275e sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0x962bf60b probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00b77dd5 snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0a7ab1ba snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x1d2d7717 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x37fbd68a snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x384e9532 snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x46c82a01 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x57613ffe snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x85252551 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8c056a47 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8f18c738 snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x917c8ea0 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x9b9c5348 snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xa2b8a4a5 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xa9106947 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xbf13957f snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xdaacebfb snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xecb0ebb5 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x0ab1580d snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x793ada23 snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x86271ec7 snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xc3e5a7b8 snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xcf32f696 snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd3e32780 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd9a778f0 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xdc47e0e1 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xe9218c24 snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xbbf71823 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xbca81734 snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xd60d07fa snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x1c7f9b58 oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x2aa796dc oxygen_pci_resume +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x39b0cb4a oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x4bbc738e oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x54c094e1 oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x57565c89 oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x64adc05c oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x68902447 oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x6c46630a oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7a9f1958 oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x952a0d29 oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xae6a2218 oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xc03ac7ba oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xced1bdd5 oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xdae26ef9 oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xe61213cd oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xe6408301 oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xed8d2e64 oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf4d4359a oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xfb65564c oxygen_write16_masked +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x3d1092d0 snd_trident_start_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x51ba1c39 snd_trident_free_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x6c3ceb39 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xb79e0311 snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xd2db4a82 snd_trident_stop_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x14aba2e9 register_sound_midi +EXPORT_SYMBOL sound/soundcore 0x3ad7916b sound_class +EXPORT_SYMBOL sound/soundcore 0x6ad49501 register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xa4acbf2d register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xbfeeb1ff register_sound_special +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xf52b61ba register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x3437dea9 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x6ee7e233 snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x70aa6617 snd_emux_new +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x8aec6be0 snd_emux_register +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xea7cf402 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xedf81621 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xebcb67bb snd_usb_create_midi_interface +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x18571732 dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x3c723c4f dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x46c4c70a dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x9390a15e dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x9d133e59 dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xc866ec78 dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0050f52c rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x02198b66 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x29e53a6b rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x2db33b15 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x69c8d13c rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x83baca27 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x87d45b9d rh_get_region_size +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x9ffc4e07 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb7aa1ca6 rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbd3452f9 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xe9f7f71a rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xf3e0a2b0 rh_inc +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0xf4c689aa cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x93413ebb lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xbbc00c08 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x317f8229 ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x048227a8 p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x0d4705f1 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x13cf8eb2 wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x1cdd2707 p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x24dd3c53 unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x3aabc9d9 p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x69124844 p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x6e20f06c p80211skb_rxmeta_attach +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x7436f36c p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x8431b63f wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x9f6fdf68 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xe5f5d958 register_wlandev +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x002fbcb7 vfs_readdir +EXPORT_SYMBOL vmlinux 0x003ed923 pci_release_region +EXPORT_SYMBOL vmlinux 0x005c155f ppp_input_error +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00af0ce7 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x00beea50 mmc_add_host +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x010c8932 agp_bind_memory +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x011aee6c mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x015a4521 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x016555a0 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x017751cd phy_stop +EXPORT_SYMBOL vmlinux 0x0179d81c bitmap_start_sync +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01cb0568 sock_release +EXPORT_SYMBOL vmlinux 0x01ceb4aa kill_anon_super +EXPORT_SYMBOL vmlinux 0x01d0dcbb pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x01f8415c seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x0204dc42 agp_generic_create_gatt_table +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x024c0b1d vc_cons +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x02681888 load_nls_default +EXPORT_SYMBOL vmlinux 0x027467be dm_register_target +EXPORT_SYMBOL vmlinux 0x0277dc24 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a14b69 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02a86a53 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x02a96c81 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02b59c84 neigh_seq_next +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02e1af76 vfs_writev +EXPORT_SYMBOL vmlinux 0x030ad9c5 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x031a4974 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x0352cfc4 unregister_8022_client +EXPORT_SYMBOL vmlinux 0x03574b79 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x0380a84c i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03c8597f bt_sock_link +EXPORT_SYMBOL vmlinux 0x03e134eb pci_find_bus +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x0423b6eb bio_integrity_advance +EXPORT_SYMBOL vmlinux 0x043998ba log_wait_commit +EXPORT_SYMBOL vmlinux 0x04442da6 atm_dev_lookup +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x0495829e xrlim_allow +EXPORT_SYMBOL vmlinux 0x04a83fa1 __scm_destroy +EXPORT_SYMBOL vmlinux 0x04c84a4f skb_pull +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04de2cff inet_bind +EXPORT_SYMBOL vmlinux 0x04fd04b3 redraw_screen +EXPORT_SYMBOL vmlinux 0x055721dd mntput_no_expire +EXPORT_SYMBOL vmlinux 0x055c94e0 read_cache_page +EXPORT_SYMBOL vmlinux 0x05624e45 md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x057dee90 md_error +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x05a82ba8 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x05c6dacc ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x05d357a2 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x05d6f228 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x0606e82b sock_create_lite +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0636da5d genphy_config_aneg +EXPORT_SYMBOL vmlinux 0x063cd37b scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0x06743511 simple_unlink +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x068c7263 ioremap_cache +EXPORT_SYMBOL vmlinux 0x0693d608 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x06a485f2 __krealloc +EXPORT_SYMBOL vmlinux 0x06aa3084 ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x06aaea98 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x06c3156a generic_write_checks +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x070b22d4 pci_iounmap +EXPORT_SYMBOL vmlinux 0x070d4db6 blk_init_tags +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x07480749 simple_rmdir +EXPORT_SYMBOL vmlinux 0x076983a7 sock_no_connect +EXPORT_SYMBOL vmlinux 0x077078fb __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x078d9032 md_write_end +EXPORT_SYMBOL vmlinux 0x078db55e blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07c6b8cc scsi_get_command +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07cd03d8 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x07e4b19f generic_getxattr +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x083b705b journal_extend +EXPORT_SYMBOL vmlinux 0x0845e96d textsearch_prepare +EXPORT_SYMBOL vmlinux 0x084635ff scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x0866b318 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x08a8fc54 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x08acd0e4 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x08b35d38 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x08bd004b ppp_unit_number +EXPORT_SYMBOL vmlinux 0x08cb528f eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x08d18fac bio_integrity_free +EXPORT_SYMBOL vmlinux 0x08d98d80 md_register_thread +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x094ec99b request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x0954446d skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098431ba acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09bb1c71 mnt_pin +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09cc758d keyring_search +EXPORT_SYMBOL vmlinux 0x09d29dff key_link +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x09e3272a swiotlb_sync_single_for_device +EXPORT_SYMBOL vmlinux 0x09eadc1a tcf_action_exec +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a55aa4b posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x0a6dccb5 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x0a8ebd21 agp_allocate_memory +EXPORT_SYMBOL vmlinux 0x0a9e090a generic_listxattr +EXPORT_SYMBOL vmlinux 0x0ac9f221 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0ae43cfc lookup_one_len +EXPORT_SYMBOL vmlinux 0x0b1284f2 aio_put_req +EXPORT_SYMBOL vmlinux 0x0b15192a seq_printf +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b2a55bb generic_file_mmap +EXPORT_SYMBOL vmlinux 0x0b44c9e9 lock_may_read +EXPORT_SYMBOL vmlinux 0x0b635a43 framebuffer_release +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b9bcfa1 vmtruncate +EXPORT_SYMBOL vmlinux 0x0ba1c90a journal_get_write_access +EXPORT_SYMBOL vmlinux 0x0ba2af0d vfs_quota_on +EXPORT_SYMBOL vmlinux 0x0bb995cf nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x0bd60355 check_disk_change +EXPORT_SYMBOL vmlinux 0x0bdfc39c i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x0be9b6e5 find_vma +EXPORT_SYMBOL vmlinux 0x0c02642e __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x0c082413 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x0c0afe5b locks_copy_lock +EXPORT_SYMBOL vmlinux 0x0c255f01 ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c79500f bio_free +EXPORT_SYMBOL vmlinux 0x0c881589 hci_send_acl +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0ca1efd8 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x0ca7b7a8 acpi_check_region +EXPORT_SYMBOL vmlinux 0x0cad9317 task_nice +EXPORT_SYMBOL vmlinux 0x0cb05519 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x0ce346dd write_one_page +EXPORT_SYMBOL vmlinux 0x0cf65e7f deactivate_super +EXPORT_SYMBOL vmlinux 0x0d089d85 __getblk +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d2bce97 scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d51c3b7 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d6457a4 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x0d790c19 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x0d846099 iget_locked +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0dd9d75e x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0x0e0252ec downgrade_write +EXPORT_SYMBOL vmlinux 0x0e30dc7e sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e608c9c i2c_clients_command +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0ea239aa xfrm_register_km +EXPORT_SYMBOL vmlinux 0x0eaa7fd1 scsi_device_resume +EXPORT_SYMBOL vmlinux 0x0ecb9204 new_inode +EXPORT_SYMBOL vmlinux 0x0eccd840 skb_truesize_bug +EXPORT_SYMBOL vmlinux 0x0ed43f66 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x0edbde1a jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0x0edcbef0 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x0ef50f01 unregister_md_personality +EXPORT_SYMBOL vmlinux 0x0f0491d7 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x0f0b6a49 bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0x0f3addde put_disk +EXPORT_SYMBOL vmlinux 0x0f504a85 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0x0fa34479 dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fc5e8eb radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0fd11422 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x0fde54cc __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x0fea0372 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x100ac59d truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x101228ca scsi_remove_device +EXPORT_SYMBOL vmlinux 0x10153581 remove_proc_entry +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x107a105c genphy_config_advert +EXPORT_SYMBOL vmlinux 0x10998e7e ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x109f5dce inet_frag_find +EXPORT_SYMBOL vmlinux 0x10bc1ac0 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x111fef58 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x11328b06 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x1139e1d7 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x11488dd6 init_task +EXPORT_SYMBOL vmlinux 0x1149e9b6 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x116240db key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x1166b8c9 serio_rescan +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x11877fff pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11dab346 __down_read +EXPORT_SYMBOL vmlinux 0x1203262a pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x121c614c default_llseek +EXPORT_SYMBOL vmlinux 0x124b74d1 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x125cbba9 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x12ba1e92 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x12da6695 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x12e84703 agp_generic_enable +EXPORT_SYMBOL vmlinux 0x12e8e17d scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x12ebdf0b inet_listen +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x130f3abb i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x1334dc5e scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x13553601 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x138d4983 agp_put_bridge +EXPORT_SYMBOL vmlinux 0x1393f520 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0x13bd9417 kick_iocb +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x144903c0 __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x146118b1 thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x147cbb76 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x149112ce set_user_nice +EXPORT_SYMBOL vmlinux 0x149e124f vfs_create +EXPORT_SYMBOL vmlinux 0x14a87866 alloc_fddidev +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14c524ab f_setown +EXPORT_SYMBOL vmlinux 0x14d5c9ff dev_remove_pack +EXPORT_SYMBOL vmlinux 0x14e9bae5 cdrom_open +EXPORT_SYMBOL vmlinux 0x150d66e1 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x15666734 da903x_query_status +EXPORT_SYMBOL vmlinux 0x15b712c3 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x15f7a8dc netif_carrier_on +EXPORT_SYMBOL vmlinux 0x165b5a26 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x166449c5 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x1675606f bad_dma_address +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x169c7358 serio_interrupt +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16a895b8 km_policy_notify +EXPORT_SYMBOL vmlinux 0x16b2e0e2 setup_arg_pages +EXPORT_SYMBOL vmlinux 0x16bbba4f nf_getsockopt +EXPORT_SYMBOL vmlinux 0x16dafd80 unregister_qdisc +EXPORT_SYMBOL vmlinux 0x16e4e983 set_pages_x +EXPORT_SYMBOL vmlinux 0x16e51ddf mapping_tagged +EXPORT_SYMBOL vmlinux 0x16f98e8c posix_test_lock +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x17178730 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x172ed4d7 __vmalloc +EXPORT_SYMBOL vmlinux 0x175eae30 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x178ff66a pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x17a33d26 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17c85a66 radix_tree_tagged +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17e16be9 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x17f3cd19 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x17f5928e bdi_register +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18471524 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x1876e4c6 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x187929b3 nla_append +EXPORT_SYMBOL vmlinux 0x189b6bac memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x18bb9aff nf_log_register +EXPORT_SYMBOL vmlinux 0x18d78421 may_umount +EXPORT_SYMBOL vmlinux 0x18d78905 mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x18e8841b register_gifconf +EXPORT_SYMBOL vmlinux 0x18f3d73c skb_over_panic +EXPORT_SYMBOL vmlinux 0x18f5188a key_put +EXPORT_SYMBOL vmlinux 0x19006762 kobject_add +EXPORT_SYMBOL vmlinux 0x190c63d3 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x19218f7d flush_signals +EXPORT_SYMBOL vmlinux 0x192f952d scsi_execute +EXPORT_SYMBOL vmlinux 0x19391763 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x19603ad3 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x196f2b26 sock_no_poll +EXPORT_SYMBOL vmlinux 0x1982a842 km_new_mapping +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19a8ef70 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x19c09104 filemap_flush +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19daa9bb pci_match_id +EXPORT_SYMBOL vmlinux 0x19e8ed6b find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x19f3c264 __free_pages +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a23f361 generic_writepages +EXPORT_SYMBOL vmlinux 0x1a270128 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a55d259 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x1a757412 compat_ip_getsockopt +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b246066 llc_sap_open +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b8e8926 scsi_add_device +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1baaa54d jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0x1bbb8ae8 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x1be5489f input_get_keycode +EXPORT_SYMBOL vmlinux 0x1c0493c9 elv_next_request +EXPORT_SYMBOL vmlinux 0x1c120b08 dcache_dir_close +EXPORT_SYMBOL vmlinux 0x1c4193c1 uart_register_driver +EXPORT_SYMBOL vmlinux 0x1c450a51 tty_register_driver +EXPORT_SYMBOL vmlinux 0x1c4a113f seq_putc +EXPORT_SYMBOL vmlinux 0x1c7e2cd9 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x1cb01357 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ce3810f xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1cf96dc5 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x1d7ce97b pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x1da1eb97 dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0x1db7706b __copy_user_nocache +EXPORT_SYMBOL vmlinux 0x1dc13db2 skb_clone +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1de00958 vm_map_ram +EXPORT_SYMBOL vmlinux 0x1df5cc80 swiotlb_map_single_attrs +EXPORT_SYMBOL vmlinux 0x1e02df6c clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x1e2b6cd5 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x1e2cfc66 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL vmlinux 0x1e315574 __blk_run_queue +EXPORT_SYMBOL vmlinux 0x1e4223c4 simple_statfs +EXPORT_SYMBOL vmlinux 0x1e4dbe40 free_netdev +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e7e4bcf __neigh_event_send +EXPORT_SYMBOL vmlinux 0x1e889cc4 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x1e8cb617 cdev_init +EXPORT_SYMBOL vmlinux 0x1ea42fa6 unregister_nls +EXPORT_SYMBOL vmlinux 0x1ea4c0fe dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0x1ea52a7f give_up_console +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ee18a4e tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f04966f complete_request_key +EXPORT_SYMBOL vmlinux 0x1f0a59ab hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0x1f1e0bbe should_remove_suid +EXPORT_SYMBOL vmlinux 0x1f2067af textsearch_destroy +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1f4f4923 inet_accept +EXPORT_SYMBOL vmlinux 0x1f65a6ee genphy_update_link +EXPORT_SYMBOL vmlinux 0x1f720436 seq_read +EXPORT_SYMBOL vmlinux 0x1f7eef1c skb_under_panic +EXPORT_SYMBOL vmlinux 0x1fbe375a ether_setup +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x20092385 acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0x201096a9 elevator_exit +EXPORT_SYMBOL vmlinux 0x2037f50a thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x209d4173 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x20be472c phy_detach +EXPORT_SYMBOL vmlinux 0x20c80e6e scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20eadeb6 ip_compute_csum +EXPORT_SYMBOL vmlinux 0x20ebda14 compat_sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x20f9322a idr_pre_get +EXPORT_SYMBOL vmlinux 0x2126031b skb_append +EXPORT_SYMBOL vmlinux 0x21502407 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x21656686 destroy_EII_client +EXPORT_SYMBOL vmlinux 0x219f7d4f pci_scan_slot +EXPORT_SYMBOL vmlinux 0x21b1eebb no_llseek +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21e5679c copy_user_generic +EXPORT_SYMBOL vmlinux 0x21e9d3da journal_start +EXPORT_SYMBOL vmlinux 0x2220ae59 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0x222c00a1 unlock_buffer +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x224f2942 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x2253c959 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x2255c911 cfb_imageblit +EXPORT_SYMBOL vmlinux 0x226dae7d set_disk_ro +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22748ebc compat_sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22bb73b5 bdget +EXPORT_SYMBOL vmlinux 0x22e599ed usb_serial_resume +EXPORT_SYMBOL vmlinux 0x22fd7c78 dst_discard +EXPORT_SYMBOL vmlinux 0x23159794 compute_creds +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x232c6cc5 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x234509f3 strncat +EXPORT_SYMBOL vmlinux 0x23519eb0 phy_connect +EXPORT_SYMBOL vmlinux 0x236c8c64 memcpy +EXPORT_SYMBOL vmlinux 0x23ba8458 dput +EXPORT_SYMBOL vmlinux 0x23bab004 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23cc765c simple_link +EXPORT_SYMBOL vmlinux 0x23f090fa boot_cpu_data +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x2412c01b cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x2415d360 unlock_super +EXPORT_SYMBOL vmlinux 0x244001fb dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x249e08c1 journal_errno +EXPORT_SYMBOL vmlinux 0x24b272c0 pci_find_capability +EXPORT_SYMBOL vmlinux 0x24de1c10 phy_device_create +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x24fdb1e2 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x252e31b5 jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x2549c07d kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x25b59353 scsi_device_put +EXPORT_SYMBOL vmlinux 0x25dd7785 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0x25ec1b28 strlen +EXPORT_SYMBOL vmlinux 0x25fae8a7 mb_cache_create +EXPORT_SYMBOL vmlinux 0x25fd10d0 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x25fff88d unregister_quota_format +EXPORT_SYMBOL vmlinux 0x26015e4c pci_request_regions +EXPORT_SYMBOL vmlinux 0x260554af init_special_inode +EXPORT_SYMBOL vmlinux 0x26084734 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0x263782b5 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x2660b1fd xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x2685c3d7 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x268ffc6f bdev_read_only +EXPORT_SYMBOL vmlinux 0x26b01d42 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x26b8d863 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x26c8b391 atm_dev_deregister +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26f771a6 set_pages_uc +EXPORT_SYMBOL vmlinux 0x270cbe60 get_user_pages +EXPORT_SYMBOL vmlinux 0x270e60bc pcim_pin_device +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x272fa85c blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x27443564 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x27593c3d bdi_register_dev +EXPORT_SYMBOL vmlinux 0x277da47c agp_unbind_memory +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27917d65 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c33efe csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27c969fc generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x27e85494 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0x27eb701a i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x27fc0644 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x282ccfe4 bt_sock_register +EXPORT_SYMBOL vmlinux 0x283cae2e uart_match_port +EXPORT_SYMBOL vmlinux 0x283d0b9e bdi_destroy +EXPORT_SYMBOL vmlinux 0x284a388b fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x284a62c6 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x285135e6 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x2876a6d3 memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x289b255f inode_double_lock +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28bf2c37 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x28d2dc6f dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28e06e8c pci_reenable_device +EXPORT_SYMBOL vmlinux 0x28e78c07 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x28eeed36 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0x29205e8c security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x293d2176 uart_update_timeout +EXPORT_SYMBOL vmlinux 0x2952963d input_release_device +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x2978360c kernel_sendpage +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29d39a8c vfs_unlink +EXPORT_SYMBOL vmlinux 0x2a1afb23 arp_tbl +EXPORT_SYMBOL vmlinux 0x2a1d8e3c cont_write_begin +EXPORT_SYMBOL vmlinux 0x2a27ea43 eth_type_trans +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a719b06 skb_checksum +EXPORT_SYMBOL vmlinux 0x2a7fd08a blk_start_queueing +EXPORT_SYMBOL vmlinux 0x2ab457c2 blk_integrity_register +EXPORT_SYMBOL vmlinux 0x2abd8fe9 cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0x2adb4c63 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2aef8523 acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b30cba6 submit_bh +EXPORT_SYMBOL vmlinux 0x2b4a5bd4 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b8bedcd con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2bb62d3a tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x2bc1bfb5 udp_prot +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2be0d4aa sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c1c3775 i2c_transfer +EXPORT_SYMBOL vmlinux 0x2c257777 sock_create_kern +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c6731f7 dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0x2c70c0c5 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x2c8e708a __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x2ca4b79d console_stop +EXPORT_SYMBOL vmlinux 0x2cadb4dd __elv_add_request +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2ceab16d may_umount_tree +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2d43aaad open_exec +EXPORT_SYMBOL vmlinux 0x2d49e48b mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x2d5528c9 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x2d80bfef nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x2d891384 swiotlb_unmap_sg_attrs +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2db3ee32 skb_queue_tail +EXPORT_SYMBOL vmlinux 0x2dbafbe3 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e18c2bd ppp_register_channel +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e59bf67 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0x2e72c2ec xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x2e849abe __mpage_writepage +EXPORT_SYMBOL vmlinux 0x2e90874e neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x2e97a729 idr_remove +EXPORT_SYMBOL vmlinux 0x2eb083b5 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2ec86031 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x2ee0549b register_binfmt +EXPORT_SYMBOL vmlinux 0x2ef3d52f thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x2fa5a500 memcmp +EXPORT_SYMBOL vmlinux 0x2fb0b354 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x2fb7fbb5 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x2fbb9e5d tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x2ff063b5 acpi_get_name +EXPORT_SYMBOL vmlinux 0x2ff4de68 page_put_link +EXPORT_SYMBOL vmlinux 0x2ff7594d xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x3018de55 dm_unregister_target +EXPORT_SYMBOL vmlinux 0x301cdbff user_revoke +EXPORT_SYMBOL vmlinux 0x30226ddf agp_device_command +EXPORT_SYMBOL vmlinux 0x303ce535 inet_addr_type +EXPORT_SYMBOL vmlinux 0x305f5901 mpage_writepages +EXPORT_SYMBOL vmlinux 0x306a8ebe agp_find_bridge +EXPORT_SYMBOL vmlinux 0x306bd3c3 vfs_fstat +EXPORT_SYMBOL vmlinux 0x306fd0bf mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0x30a114be end_request +EXPORT_SYMBOL vmlinux 0x30b22bab swiotlb_sync_single_for_cpu +EXPORT_SYMBOL vmlinux 0x30c7587a sync_inode +EXPORT_SYMBOL vmlinux 0x30dc561a __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x30de8b2e copy_io_context +EXPORT_SYMBOL vmlinux 0x30df26fd dm_table_get_size +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x30f7b5e1 register_netdev +EXPORT_SYMBOL vmlinux 0x31153bf8 tcp_check_req +EXPORT_SYMBOL vmlinux 0x312baafb fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3146774a __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315363b6 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x316a3ba5 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x3171e93f mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x31735008 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x31a30414 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31c69df5 blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x31ebadcd in_group_p +EXPORT_SYMBOL vmlinux 0x31fb8c02 bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0x320c2c0d pskb_copy +EXPORT_SYMBOL vmlinux 0x32382dba qdisc_destroy +EXPORT_SYMBOL vmlinux 0x323cc80d vm_insert_page +EXPORT_SYMBOL vmlinux 0x3251f905 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x326ba0c4 km_report +EXPORT_SYMBOL vmlinux 0x32b3916f do_splice_to +EXPORT_SYMBOL vmlinux 0x32bbac02 pci_choose_state +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32f87920 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x3301823a bio_map_kern +EXPORT_SYMBOL vmlinux 0x330d556f gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x331b0bf5 bio_endio +EXPORT_SYMBOL vmlinux 0x33217539 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x3347827b get_sb_nodev +EXPORT_SYMBOL vmlinux 0x335b7dc0 fb_show_logo +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x3360ba94 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x33a317a3 jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x33b84f74 copy_page +EXPORT_SYMBOL vmlinux 0x33bab407 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0x33cda660 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x33f5a8b4 blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0x3495e340 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34def7ff tty_port_init +EXPORT_SYMBOL vmlinux 0x34e8656d do_sync_write +EXPORT_SYMBOL vmlinux 0x34fce488 pci_remove_bus +EXPORT_SYMBOL vmlinux 0x35072add pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x350cc8c2 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x352ab046 genl_sock +EXPORT_SYMBOL vmlinux 0x35352718 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x353ca524 qdisc_reset +EXPORT_SYMBOL vmlinux 0x355737ac llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x355f029a tcf_register_action +EXPORT_SYMBOL vmlinux 0x356ed56a clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x3572a48b input_unregister_handler +EXPORT_SYMBOL vmlinux 0x3580d864 register_atm_ioctl +EXPORT_SYMBOL vmlinux 0x35a07e32 vfs_stat +EXPORT_SYMBOL vmlinux 0x35b0650f vsnprintf +EXPORT_SYMBOL vmlinux 0x35b55e54 ps2_command +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35ff32bf inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x36139a51 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x361dec09 __page_symlink +EXPORT_SYMBOL vmlinux 0x36212135 simple_readpage +EXPORT_SYMBOL vmlinux 0x362412d5 agp_generic_alloc_page +EXPORT_SYMBOL vmlinux 0x36274d01 blkdev_put +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x363f4209 sg_miter_start +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x3663cc74 kmem_cache_name +EXPORT_SYMBOL vmlinux 0x36881d29 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x36bc4e3c unregister_netdev +EXPORT_SYMBOL vmlinux 0x3701a196 csum_partial_copy_to_user +EXPORT_SYMBOL vmlinux 0x371cd187 dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x3747ad09 d_invalidate +EXPORT_SYMBOL vmlinux 0x375465a7 radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x375ccbca check_disk_size_change +EXPORT_SYMBOL vmlinux 0x37bc8966 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37c34486 km_query +EXPORT_SYMBOL vmlinux 0x37f81fe7 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x3800d56b pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x3829c5a0 sysctl_data +EXPORT_SYMBOL vmlinux 0x38748d2e skb_queue_purge +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38f33bed dump_fpu +EXPORT_SYMBOL vmlinux 0x38facb18 scsi_unregister +EXPORT_SYMBOL vmlinux 0x390e0b3b mdiobus_scan +EXPORT_SYMBOL vmlinux 0x391109b6 cdev_del +EXPORT_SYMBOL vmlinux 0x3912cd77 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x392963c3 dquot_release +EXPORT_SYMBOL vmlinux 0x392b725a pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x3937b22a atm_alloc_charge +EXPORT_SYMBOL vmlinux 0x395f5e09 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x396960e0 scsi_target_resume +EXPORT_SYMBOL vmlinux 0x396cf390 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x39c16f1e release_firmware +EXPORT_SYMBOL vmlinux 0x39cd891a __down_write_trylock +EXPORT_SYMBOL vmlinux 0x3a0ab085 dentry_unhash +EXPORT_SYMBOL vmlinux 0x3a0d9f8b generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x3a199193 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x3a2003a3 iommu_nr_pages +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a3f5a06 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x3a751ecb bio_pair_release +EXPORT_SYMBOL vmlinux 0x3a88e9a7 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x3a911e65 lock_may_write +EXPORT_SYMBOL vmlinux 0x3a97aa27 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3ab0161b dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0x3acd5712 bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x3adf2c2a phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0x3af292c0 kill_litter_super +EXPORT_SYMBOL vmlinux 0x3b2a3782 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b40d5a1 tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x3b592412 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x3b67cbbf __init_rwsem +EXPORT_SYMBOL vmlinux 0x3bab9b29 filp_open +EXPORT_SYMBOL vmlinux 0x3bc50e0d scsi_finish_command +EXPORT_SYMBOL vmlinux 0x3bcba798 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3be4ce31 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x3c027dcf jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x3c2162c0 cdev_alloc +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c5829f6 scsi_block_requests +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c7d4963 put_tty_driver +EXPORT_SYMBOL vmlinux 0x3c94f3b7 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cc5a3e3 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x3cd3b8c7 __dst_free +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cf29580 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x3d22f0a7 dm_table_put +EXPORT_SYMBOL vmlinux 0x3d2cd33a tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x3d61c0ed elv_rb_find +EXPORT_SYMBOL vmlinux 0x3d8af420 journal_create +EXPORT_SYMBOL vmlinux 0x3d9a9ba2 journal_force_commit +EXPORT_SYMBOL vmlinux 0x3d9ee9f0 clear_page +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3db2e258 radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x3db46789 sock_init_data +EXPORT_SYMBOL vmlinux 0x3e1097ee inode_get_bytes +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e1f37d5 bio_integrity_clone +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e8ff310 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x3ea27cf5 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0x3eaa72d0 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x3eace113 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x3ebed522 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x3ece8ae4 pci_find_device +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ee1fd0e seq_open_private +EXPORT_SYMBOL vmlinux 0x3efcadda register_nls +EXPORT_SYMBOL vmlinux 0x3efed9c1 pnp_request_card_device +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f09bad1 sk_stream_error +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f3455d8 put_page +EXPORT_SYMBOL vmlinux 0x3f42a41f __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3fa913da strspn +EXPORT_SYMBOL vmlinux 0x3fab4896 netlink_unicast +EXPORT_SYMBOL vmlinux 0x3fec048f sg_next +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x40228261 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x4056da6b tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x408190eb scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x40d38b07 block_write_end +EXPORT_SYMBOL vmlinux 0x40e860ca agp_generic_alloc_user +EXPORT_SYMBOL vmlinux 0x40eafccb bitmap_unplug +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x413167a1 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x413a5f4c tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x413dd170 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x413ee1aa scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x41471579 ppp_input +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x41711c46 seq_puts +EXPORT_SYMBOL vmlinux 0x4180c189 __f_setown +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x4194481b pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x41a7c227 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41e0356b pskb_expand_head +EXPORT_SYMBOL vmlinux 0x41e81663 agp_free_memory +EXPORT_SYMBOL vmlinux 0x41f38cc7 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x41f706ef udp_proc_register +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x421feb8f qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x42612fa2 journal_abort +EXPORT_SYMBOL vmlinux 0x4271ac1a generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x42981536 bh_submit_read +EXPORT_SYMBOL vmlinux 0x429eb7f5 arp_create +EXPORT_SYMBOL vmlinux 0x42a4bdf2 in_egroup_p +EXPORT_SYMBOL vmlinux 0x42c8de35 ioremap_nocache +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x430a71cc scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x430bb7a8 dev_load +EXPORT_SYMBOL vmlinux 0x4327f0d5 memset_io +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x4344f8b7 dquot_transfer +EXPORT_SYMBOL vmlinux 0x43455865 take_over_console +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x43618370 proto_register +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x43bf17d8 neigh_update +EXPORT_SYMBOL vmlinux 0x43e42c0e set_pages_wb +EXPORT_SYMBOL vmlinux 0x43ec913a put_cmsg +EXPORT_SYMBOL vmlinux 0x43f7b266 xfrm_nl +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x4430d571 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x4437b44d tcp_splice_read +EXPORT_SYMBOL vmlinux 0x44451a2e kthread_stop +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x4481556f scsi_add_host +EXPORT_SYMBOL vmlinux 0x448403ed bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44d560e3 init_level4_pgt +EXPORT_SYMBOL vmlinux 0x44df8ba6 proc_create_data +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x451c96f9 scsi_free_command +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455e4098 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x45704798 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x4572534c key_payload_reserve +EXPORT_SYMBOL vmlinux 0x4593a18d pci_dev_get +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x4601877c d_path +EXPORT_SYMBOL vmlinux 0x4605ebee generic_read_dir +EXPORT_SYMBOL vmlinux 0x4607dad1 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x46456a12 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x46527008 journal_lock_updates +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x4679020d pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0x468c3de6 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x469e5c91 phy_start_interrupts +EXPORT_SYMBOL vmlinux 0x46c5bac8 bdput +EXPORT_SYMBOL vmlinux 0x46d5a947 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x46e04778 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x46f7e6ce __bforget +EXPORT_SYMBOL vmlinux 0x46faaa1c xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x470ce841 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x475f05af acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x4792b78d __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47e1699f neigh_lookup +EXPORT_SYMBOL vmlinux 0x47ffe546 register_chrdev +EXPORT_SYMBOL vmlinux 0x4813bc30 ip6_frag_match +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x48395714 path_get +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x485e5818 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x486b7b2e simple_sync_file +EXPORT_SYMBOL vmlinux 0x4871f34d hci_free_dev +EXPORT_SYMBOL vmlinux 0x4888b72a pci_get_subsys +EXPORT_SYMBOL vmlinux 0x48a08d04 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x48adab09 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x48bdccd8 agp_collect_device_status +EXPORT_SYMBOL vmlinux 0x48bf4309 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49430cd3 skb_seq_read +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x496cb7f6 netdev_state_change +EXPORT_SYMBOL vmlinux 0x499eb01d inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x49ef3927 __invalidate_device +EXPORT_SYMBOL vmlinux 0x4a29e253 i2c_master_recv +EXPORT_SYMBOL vmlinux 0x4a30fe8a remove_inode_hash +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a555407 key_alloc +EXPORT_SYMBOL vmlinux 0x4a5aa29f scsi_register_driver +EXPORT_SYMBOL vmlinux 0x4a6d6a67 cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0x4a93fe5c backlight_device_register +EXPORT_SYMBOL vmlinux 0x4aaf9b7f dm_table_get_mode +EXPORT_SYMBOL vmlinux 0x4acd93d3 release_resource +EXPORT_SYMBOL vmlinux 0x4ae37fb7 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x4aec9d60 rfkill_force_state +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b3a68c5 set_anon_super +EXPORT_SYMBOL vmlinux 0x4b52f497 llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4b8a9c9b tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0x4b91a078 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x4ba20638 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x4ba5baa0 load_gs_index +EXPORT_SYMBOL vmlinux 0x4bb068c4 pneigh_lookup +EXPORT_SYMBOL vmlinux 0x4bb1b7da netpoll_setup +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bbcb530 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x4bdf028e idr_find +EXPORT_SYMBOL vmlinux 0x4c07b61a mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c32aa00 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x4c4135a6 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x4c4c956e nla_memcmp +EXPORT_SYMBOL vmlinux 0x4c7b057f __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x4ca32965 sync_blockdev +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cc28465 dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0x4cc2d305 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x4d0cf8ef have_submounts +EXPORT_SYMBOL vmlinux 0x4d16055e scsi_register +EXPORT_SYMBOL vmlinux 0x4d2c3bdd sock_no_listen +EXPORT_SYMBOL vmlinux 0x4d32e32c journal_check_used_features +EXPORT_SYMBOL vmlinux 0x4d32e928 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x4d4dc484 nf_ct_attach +EXPORT_SYMBOL vmlinux 0x4d51dc47 register_md_personality +EXPORT_SYMBOL vmlinux 0x4d875b0e tcp_poll +EXPORT_SYMBOL vmlinux 0x4d8859fc dquot_commit +EXPORT_SYMBOL vmlinux 0x4db1e1d4 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x4dc88d79 ps2_handle_response +EXPORT_SYMBOL vmlinux 0x4dda726b match_strlcpy +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4df47e9f xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x4e0fb2da neigh_create +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e2d15e3 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x4e304a2b sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e35c4bd jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0x4e4d0c4a dev_mc_delete +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e94ea23 jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x4e97fc4e bio_phys_segments +EXPORT_SYMBOL vmlinux 0x4e9f82f6 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x4ed244a1 netpoll_print_options +EXPORT_SYMBOL vmlinux 0x4edd72f7 block_all_signals +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4f584a17 mpage_readpage +EXPORT_SYMBOL vmlinux 0x4f720a26 bio_copy_kern +EXPORT_SYMBOL vmlinux 0x4fa75270 inet_frags_fini +EXPORT_SYMBOL vmlinux 0x4faa2fe0 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x4fb796e6 md_done_sync +EXPORT_SYMBOL vmlinux 0x4fcee107 __up_read +EXPORT_SYMBOL vmlinux 0x4fd96f21 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4fe4723a dma_pool_free +EXPORT_SYMBOL vmlinux 0x4fe4a875 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x4ffdd0e6 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x509189e0 single_open +EXPORT_SYMBOL vmlinux 0x509611e0 inode_double_unlock +EXPORT_SYMBOL vmlinux 0x509dd4fd blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x50b5cb2d idr_get_new_above +EXPORT_SYMBOL vmlinux 0x50cb73c5 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x50f10820 bio_clone +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x51458dfb pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x51503ac2 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x517ce3af simple_write_end +EXPORT_SYMBOL vmlinux 0x51a45271 rtnl_notify +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x520af169 nf_reinject +EXPORT_SYMBOL vmlinux 0x521d63ec wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x522f5573 pv_irq_ops +EXPORT_SYMBOL vmlinux 0x5252f304 __memcpy_toio +EXPORT_SYMBOL vmlinux 0x526618e5 handle_sysrq +EXPORT_SYMBOL vmlinux 0x526f7ce8 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x527c75e1 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x529dabda devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x529deb40 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52d39396 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52d7d17b bt_sock_unlink +EXPORT_SYMBOL vmlinux 0x52ec38f1 inode_set_bytes +EXPORT_SYMBOL vmlinux 0x5306db6e jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x536ee332 sg_miter_stop +EXPORT_SYMBOL vmlinux 0x537dc195 tty_name +EXPORT_SYMBOL vmlinux 0x5381f539 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53895d69 file_permission +EXPORT_SYMBOL vmlinux 0x538e2460 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x53bdca17 nf_afinfo +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x541818ec elv_rb_add +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x5471a0bb xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x54757923 agp_backend_release +EXPORT_SYMBOL vmlinux 0x547a8a7c scsi_print_command +EXPORT_SYMBOL vmlinux 0x548d56c3 rfkill_register +EXPORT_SYMBOL vmlinux 0x54934569 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54bfaf35 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x54d69b36 atm_dev_register +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x54e954d5 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x54ed4e86 __ip_select_ident +EXPORT_SYMBOL vmlinux 0x550f8ade groups_alloc +EXPORT_SYMBOL vmlinux 0x55578d2c pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x5575d022 acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0x557f01d2 i2c_release_client +EXPORT_SYMBOL vmlinux 0x5584b852 netif_device_attach +EXPORT_SYMBOL vmlinux 0x558dae7d bdget_disk +EXPORT_SYMBOL vmlinux 0x558e869c do_SAK +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55b03981 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x55b309bd sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x55e1d220 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x55f151fe cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x560ece3e sock_no_getname +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x562a4180 tc_classify +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x563acb40 compat_nf_setsockopt +EXPORT_SYMBOL vmlinux 0x567c018f lease_modify +EXPORT_SYMBOL vmlinux 0x56831d40 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x568728c9 pci_enable_msi +EXPORT_SYMBOL vmlinux 0x56a4a1a9 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x56b2149d create_empty_buffers +EXPORT_SYMBOL vmlinux 0x56b8878c blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56d38b40 send_sig_info +EXPORT_SYMBOL vmlinux 0x56d5e4ef ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x56f2a90c thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x5706fe40 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x570d62bf sock_wake_async +EXPORT_SYMBOL vmlinux 0x572c1556 netpoll_poll +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x5740bbbc vfs_statfs +EXPORT_SYMBOL vmlinux 0x57509861 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x5792721e bdevname +EXPORT_SYMBOL vmlinux 0x57c9dfa2 register_8022_client +EXPORT_SYMBOL vmlinux 0x57dab10e register_netdevice +EXPORT_SYMBOL vmlinux 0x58011f50 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x5810f6f2 put_io_context +EXPORT_SYMBOL vmlinux 0x5823ee60 serio_open +EXPORT_SYMBOL vmlinux 0x5827adf9 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x588ab303 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x58941e75 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x58cfb592 clear_inode +EXPORT_SYMBOL vmlinux 0x58ec2925 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x590bf11e thaw_process +EXPORT_SYMBOL vmlinux 0x591ec956 find_get_page +EXPORT_SYMBOL vmlinux 0x592c12d5 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594a1892 acpi_bus_add +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x59653ff0 invalidate_partition +EXPORT_SYMBOL vmlinux 0x59679f93 dst_release +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x599f4195 iget_failed +EXPORT_SYMBOL vmlinux 0x59cefff4 mmc_resume_host +EXPORT_SYMBOL vmlinux 0x59d36624 unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59e1c47c sk_stop_timer +EXPORT_SYMBOL vmlinux 0x5a062b0c filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x5a11ec92 scsi_ioctl +EXPORT_SYMBOL vmlinux 0x5a34a45c __kmalloc +EXPORT_SYMBOL vmlinux 0x5a4738f9 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a5e7ea3 simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x5a60ae2d dquot_initialize +EXPORT_SYMBOL vmlinux 0x5a67e4b1 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x5a69219f __up_write +EXPORT_SYMBOL vmlinux 0x5a704bb4 sysctl_intvec +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5ab8e1b4 wireless_send_event +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5ac47916 phy_attach +EXPORT_SYMBOL vmlinux 0x5ac74482 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0x5ae10545 xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x5b36df0f ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5b547aa2 ip_defrag +EXPORT_SYMBOL vmlinux 0x5b5ca7c6 block_commit_write +EXPORT_SYMBOL vmlinux 0x5b650190 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x5b733bf3 md_unregister_thread +EXPORT_SYMBOL vmlinux 0x5bae2eac acpi_extract_package +EXPORT_SYMBOL vmlinux 0x5bb5f76a kill_pid +EXPORT_SYMBOL vmlinux 0x5bb80581 dev_get_by_index +EXPORT_SYMBOL vmlinux 0x5bb97a98 proc_symlink +EXPORT_SYMBOL vmlinux 0x5bcc0b2e atm_proc_root +EXPORT_SYMBOL vmlinux 0x5bdbec0a kthread_bind +EXPORT_SYMBOL vmlinux 0x5be1ae55 d_add_ci +EXPORT_SYMBOL vmlinux 0x5bec44cb __down_write +EXPORT_SYMBOL vmlinux 0x5c1bfc35 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x5c46b6fa posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x5c5b1f92 phy_driver_register +EXPORT_SYMBOL vmlinux 0x5c5bf4dd journal_init_inode +EXPORT_SYMBOL vmlinux 0x5c6241f0 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x5c75bdd3 mmc_free_host +EXPORT_SYMBOL vmlinux 0x5ca0000d schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x5cc8e015 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0x5cdd7614 get_agp_version +EXPORT_SYMBOL vmlinux 0x5ce8a248 register_con_driver +EXPORT_SYMBOL vmlinux 0x5cf6bc93 get_super +EXPORT_SYMBOL vmlinux 0x5d113035 vm_stat +EXPORT_SYMBOL vmlinux 0x5d36f216 agp_generic_remove_memory +EXPORT_SYMBOL vmlinux 0x5d37d497 tcp_prot +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dcdf7b2 icmp_send +EXPORT_SYMBOL vmlinux 0x5dfa7d8f tcf_hash_check +EXPORT_SYMBOL vmlinux 0x5e07df81 blk_rq_init +EXPORT_SYMBOL vmlinux 0x5e1a8dea nf_setsockopt +EXPORT_SYMBOL vmlinux 0x5e30a6e5 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x5e498497 __secpath_destroy +EXPORT_SYMBOL vmlinux 0x5e4f995f uart_get_divisor +EXPORT_SYMBOL vmlinux 0x5e617dd5 proc_dointvec +EXPORT_SYMBOL vmlinux 0x5e703255 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e9b9578 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x5e9f09df get_io_context +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ec03951 sock_no_bind +EXPORT_SYMBOL vmlinux 0x5ecdce4e ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5ee27766 kill_pgrp +EXPORT_SYMBOL vmlinux 0x5f292f70 jbd2_journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x5f2ca5e3 ps2_drain +EXPORT_SYMBOL vmlinux 0x5f581a10 current_fs_time +EXPORT_SYMBOL vmlinux 0x5f6f0663 is_container_init +EXPORT_SYMBOL vmlinux 0x5f7a743c vfs_rmdir +EXPORT_SYMBOL vmlinux 0x5f8755fc block_write_full_page +EXPORT_SYMBOL vmlinux 0x5f8a9e0f pci_assign_resource +EXPORT_SYMBOL vmlinux 0x5fbbb73b dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x5fd02b6d pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x5fdacb57 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0x5fdb5efe eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x5fe7c069 __kill_fasync +EXPORT_SYMBOL vmlinux 0x5fe941b9 cdrom_release +EXPORT_SYMBOL vmlinux 0x5fed2942 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x6006da77 mmc_request_done +EXPORT_SYMBOL vmlinux 0x604bc767 names_cachep +EXPORT_SYMBOL vmlinux 0x60599772 generic_readlink +EXPORT_SYMBOL vmlinux 0x605c8bde radix_tree_delete +EXPORT_SYMBOL vmlinux 0x60612cef ip_dev_find +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60c841d0 __breadahead +EXPORT_SYMBOL vmlinux 0x60d9bf15 ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0x610c9818 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x6159c44d request_key_async +EXPORT_SYMBOL vmlinux 0x6177aea3 md_write_start +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61a43a00 d_instantiate +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61c1c365 unregister_key_type +EXPORT_SYMBOL vmlinux 0x61e7eba8 tcp_close +EXPORT_SYMBOL vmlinux 0x61f6e9df skb_gso_segment +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6211c1b4 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62748e70 acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x628d761c dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x6297f30d jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x62e5d67c block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x6302a83f jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x630712b5 pnp_get_resource +EXPORT_SYMBOL vmlinux 0x630c5b0f i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x635278d7 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x6356753f scsi_dma_map +EXPORT_SYMBOL vmlinux 0x63694ce7 key_unlink +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x636e086f skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x63727852 tty_unregister_device +EXPORT_SYMBOL vmlinux 0x6381baa9 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0x63875eee neigh_seq_start +EXPORT_SYMBOL vmlinux 0x63a9345f udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x63abe61b skb_store_bits +EXPORT_SYMBOL vmlinux 0x63cd2085 remove_arg_zero +EXPORT_SYMBOL vmlinux 0x63db67fc kobject_set_name +EXPORT_SYMBOL vmlinux 0x63dfe9ad jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f1300b put_filp +EXPORT_SYMBOL vmlinux 0x63f1d58f request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x63fc232f strlen_user +EXPORT_SYMBOL vmlinux 0x63fd48db neigh_table_clear +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640684f1 tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0x640db09d set_pages_nx +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x643d51f1 release_sock +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6464870b register_snap_client +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6468ba15 vfs_dq_drop +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x647eea3c balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0x648300b9 pci_save_state +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64d68d5c fddi_type_trans +EXPORT_SYMBOL vmlinux 0x64e1d6a4 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x64e36171 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x64ed8b81 phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x651f2599 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x65367084 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x654ab4af sk_alloc +EXPORT_SYMBOL vmlinux 0x656e4dda elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x65ca1581 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x65d7a243 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x6645885a eth_header_parse +EXPORT_SYMBOL vmlinux 0x665737b3 init_file +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66ae9537 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x66d966ea misc_register +EXPORT_SYMBOL vmlinux 0x6708231c bd_release +EXPORT_SYMBOL vmlinux 0x670cf232 bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x672144bd strlcpy +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x673f815e agp_bridges +EXPORT_SYMBOL vmlinux 0x67825481 arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0x678d21c6 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x679a6bf0 sk_dst_check +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c2ee94 jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x681cda32 compat_ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x68257c4c swiotlb_map_sg_attrs +EXPORT_SYMBOL vmlinux 0x6833130b vfs_read +EXPORT_SYMBOL vmlinux 0x68470ac2 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x684ad884 __bread +EXPORT_SYMBOL vmlinux 0x685902da locks_remove_posix +EXPORT_SYMBOL vmlinux 0x687521dd open_by_devnum +EXPORT_SYMBOL vmlinux 0x68765772 alloc_trdev +EXPORT_SYMBOL vmlinux 0x68852816 freeze_bdev +EXPORT_SYMBOL vmlinux 0x68a7fd80 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0x68b2b105 compat_mc_getsockopt +EXPORT_SYMBOL vmlinux 0x68df643b blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x6907d4e9 idr_for_each +EXPORT_SYMBOL vmlinux 0x694169dc unlock_page +EXPORT_SYMBOL vmlinux 0x695b2d52 journal_stop +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x698f8712 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x6999b675 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x699eae01 nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69a358a6 iomem_resource +EXPORT_SYMBOL vmlinux 0x69a994fa sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x69ae5d94 journal_wipe +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69e51b9f skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a3b301e hci_alloc_dev +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a5f98a0 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x6a5fa363 sigprocmask +EXPORT_SYMBOL vmlinux 0x6a657804 key_task_permission +EXPORT_SYMBOL vmlinux 0x6a9e3089 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x6abfb1be rtnl_unicast +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6aefd07b xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x6b0947ec dma_set_mask +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b29281c skb_copy +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b4e5a52 radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x6b75459c sock_recvmsg +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bc1d2bd __kfree_skb +EXPORT_SYMBOL vmlinux 0x6bc56c67 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6beea115 jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0x6c0138d5 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x6c11e64f pci_request_region +EXPORT_SYMBOL vmlinux 0x6c1aa58c bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x6c2197a9 pci_target_state +EXPORT_SYMBOL vmlinux 0x6c330a1b ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c58406c phy_start +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c66324c uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x6c6dfe32 fifo_set_limit +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c75b0d4 acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x6c97fff2 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x6ca81052 hci_unregister_cb +EXPORT_SYMBOL vmlinux 0x6cb9c88f kernel_getsockname +EXPORT_SYMBOL vmlinux 0x6cbe7632 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x6cc07f0f register_framebuffer +EXPORT_SYMBOL vmlinux 0x6cd5ba8f sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x6cf643bf elevator_init +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d1d3747 tcp_make_synack +EXPORT_SYMBOL vmlinux 0x6d1f3083 kernel_bind +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d2a193e tty_shutdown +EXPORT_SYMBOL vmlinux 0x6d334118 __get_user_8 +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d47c2e3 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x6d47c62a __scm_send +EXPORT_SYMBOL vmlinux 0x6d47d90d groups_free +EXPORT_SYMBOL vmlinux 0x6d524947 simple_dir_operations +EXPORT_SYMBOL vmlinux 0x6d54fd97 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x6d83e2bf ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x6da43125 vfs_readv +EXPORT_SYMBOL vmlinux 0x6da626ff free_task +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6de6bf83 radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e026770 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e1f7574 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x6e5ad508 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e8bacb9 iunique +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ecd3a7c genphy_read_status +EXPORT_SYMBOL vmlinux 0x6ed881a0 invalidate_bdev +EXPORT_SYMBOL vmlinux 0x6f79a319 pci_dev_driver +EXPORT_SYMBOL vmlinux 0x6f9678cd iput +EXPORT_SYMBOL vmlinux 0x6f9b9bbc bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0x6fb1dc03 tcf_em_register +EXPORT_SYMBOL vmlinux 0x6fc80be3 phy_driver_unregister +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fdb639d agp_generic_free_gatt_table +EXPORT_SYMBOL vmlinux 0x6fe1ffa1 tty_set_operations +EXPORT_SYMBOL vmlinux 0x6fe295f9 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x6fe91ddb __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x700fda5f simple_transaction_get +EXPORT_SYMBOL vmlinux 0x702d47c6 proc_mkdir +EXPORT_SYMBOL vmlinux 0x702ff8e7 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x70538c79 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x70679d78 seq_release_private +EXPORT_SYMBOL vmlinux 0x706ed5fb d_alloc +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x70d27d90 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70ded075 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x70dedb1e kernel_getpeername +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x70f2a8ed blk_insert_request +EXPORT_SYMBOL vmlinux 0x70f80486 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x70f89459 clip_tbl_hook +EXPORT_SYMBOL vmlinux 0x71273786 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x7163c496 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x716eb724 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71abfb6b bd_claim +EXPORT_SYMBOL vmlinux 0x71d9e386 agp_generic_type_to_mask_type +EXPORT_SYMBOL vmlinux 0x71e8e2b3 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x71f64d3a phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0x71f6eb38 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x71f7c5ef swiotlb_alloc_coherent +EXPORT_SYMBOL vmlinux 0x72166196 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x721732c0 inet_shutdown +EXPORT_SYMBOL vmlinux 0x721f31ff pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x722ea4fe fb_blank +EXPORT_SYMBOL vmlinux 0x7242e96d strnchr +EXPORT_SYMBOL vmlinux 0x72515048 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x725f33c3 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x72abd4d0 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x72acb99a jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72f1b1f9 tcf_exts_change +EXPORT_SYMBOL vmlinux 0x73304295 vfs_permission +EXPORT_SYMBOL vmlinux 0x7335e17a blk_register_region +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x735e480e inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x736b0869 noop_qdisc +EXPORT_SYMBOL vmlinux 0x737a7803 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0x738568e3 tty_throttle +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x739ee22d gen_pool_add +EXPORT_SYMBOL vmlinux 0x73a4ca5e vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x73d628ed netif_rx_ni +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x740aba46 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x74164334 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x741b2b7a register_exec_domain +EXPORT_SYMBOL vmlinux 0x748162fb pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74891f3a journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x748af56b i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74949b44 kthread_create +EXPORT_SYMBOL vmlinux 0x74a3330d inet_sendmsg +EXPORT_SYMBOL vmlinux 0x74b1136a sk_wait_data +EXPORT_SYMBOL vmlinux 0x74b6c0db lock_sock_nested +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74e420b1 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x750f5252 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0x75136eb3 skb_split +EXPORT_SYMBOL vmlinux 0x751873f0 single_release +EXPORT_SYMBOL vmlinux 0x752c31ff blk_sync_queue +EXPORT_SYMBOL vmlinux 0x7538b132 agp_off +EXPORT_SYMBOL vmlinux 0x75409b2f cdrom_ioctl +EXPORT_SYMBOL vmlinux 0x756e6992 strnicmp +EXPORT_SYMBOL vmlinux 0x7578cf96 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x75a73f3d ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x75bdea12 iommu_area_alloc +EXPORT_SYMBOL vmlinux 0x75d4e616 ps2_init +EXPORT_SYMBOL vmlinux 0x75ea9531 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x761c1854 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x7641b0cc alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x764bd77c request_resource +EXPORT_SYMBOL vmlinux 0x76534767 compat_tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x765f202a tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x766bdc4b blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x767dd8fd acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x768ea2c4 unregister_console +EXPORT_SYMBOL vmlinux 0x76bb0a0e devm_request_irq +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76cc1fa4 km_policy_expired +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76d79e4a unlock_rename +EXPORT_SYMBOL vmlinux 0x76de1690 netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x76e770d7 get_fs_type +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x771ffb79 uart_resume_port +EXPORT_SYMBOL vmlinux 0x7736f5c6 ip_fragment +EXPORT_SYMBOL vmlinux 0x773f80aa get_sb_bdev +EXPORT_SYMBOL vmlinux 0x77489bd3 register_key_type +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x778ddaf5 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x779144ee seq_open +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77c19ec7 ip6_route_output +EXPORT_SYMBOL vmlinux 0x77dc5172 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x77e7b968 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x77f53abc acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x780585d6 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x782acba5 crc_t10dif +EXPORT_SYMBOL vmlinux 0x7833a29a generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x78480718 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x785148a3 idr_destroy +EXPORT_SYMBOL vmlinux 0x7854a4e6 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x785fe35c bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x789eb258 inet6_ioctl +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78a53baf bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x793a1a91 submit_bio +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79a6db31 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79aa0a56 bdi_unregister +EXPORT_SYMBOL vmlinux 0x79d2d1cd page_follow_link_light +EXPORT_SYMBOL vmlinux 0x79d8fbaa pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a505433 input_event +EXPORT_SYMBOL vmlinux 0x7a552743 sock_no_accept +EXPORT_SYMBOL vmlinux 0x7a56bba0 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x7a79107e pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x7a79b72c proto_unregister +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7a8565c6 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x7a8b7885 mdio_bus_type +EXPORT_SYMBOL vmlinux 0x7a99e63f module_refcount +EXPORT_SYMBOL vmlinux 0x7ab6871d start_tty +EXPORT_SYMBOL vmlinux 0x7ac4c24b scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x7ae0c38c block_invalidatepage +EXPORT_SYMBOL vmlinux 0x7ae73de1 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b244373 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x7b340536 dma_ops +EXPORT_SYMBOL vmlinux 0x7b4c16c6 get_sb_single +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b572b1a nonseekable_open +EXPORT_SYMBOL vmlinux 0x7b5fc621 ip_ct_attach +EXPORT_SYMBOL vmlinux 0x7b5fd87f blk_put_request +EXPORT_SYMBOL vmlinux 0x7b743ed0 scsi_put_command +EXPORT_SYMBOL vmlinux 0x7b8f4c40 key_create_or_update +EXPORT_SYMBOL vmlinux 0x7bb376da tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7bcdfd33 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x7bd4797d simple_rename +EXPORT_SYMBOL vmlinux 0x7bd75868 udplite_prot +EXPORT_SYMBOL vmlinux 0x7bdba91e scsi_print_result +EXPORT_SYMBOL vmlinux 0x7bec7200 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0x7bff3be7 iov_iter_advance +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c59da36 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c61340c __release_region +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7ca6a4c1 acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0x7ca87216 pci_bus_type +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cbaef11 nobh_writepage +EXPORT_SYMBOL vmlinux 0x7cc5db64 dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0x7ce13fec scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x7cf495f2 stop_tty +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d05d489 security_d_instantiate +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d18ce10 serio_reconnect +EXPORT_SYMBOL vmlinux 0x7d2f2495 input_open_device +EXPORT_SYMBOL vmlinux 0x7d43021c input_register_handle +EXPORT_SYMBOL vmlinux 0x7d66c1ef blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d94f746 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7df74779 simple_write_begin +EXPORT_SYMBOL vmlinux 0x7dfe6340 scsi_scan_target +EXPORT_SYMBOL vmlinux 0x7e2df88e read_cache_pages +EXPORT_SYMBOL vmlinux 0x7e8156c6 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x7e9265e2 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7eaac2e2 create_proc_entry +EXPORT_SYMBOL vmlinux 0x7ec9bfbc strncpy +EXPORT_SYMBOL vmlinux 0x7edef578 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fa250c3 poll_initwait +EXPORT_SYMBOL vmlinux 0x7ffc9624 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x8050cf44 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x806761d8 journal_restart +EXPORT_SYMBOL vmlinux 0x806a0baf dev_mc_add +EXPORT_SYMBOL vmlinux 0x808776c2 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x80a56b6f tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x80b2c800 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x80b64773 ip6_frag_init +EXPORT_SYMBOL vmlinux 0x80f86851 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x812037b1 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x8128f097 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x81933aa4 mdiobus_read +EXPORT_SYMBOL vmlinux 0x819b65c7 agp_generic_mask_memory +EXPORT_SYMBOL vmlinux 0x81b24d48 find_or_create_page +EXPORT_SYMBOL vmlinux 0x81cd51e7 pci_find_slot +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x81ffc810 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x82047b6d i2c_probe +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x820d4867 d_lookup +EXPORT_SYMBOL vmlinux 0x824cccf2 user_path_at +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82909a12 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x82def1c6 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x82e6ab3a kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x82e9c083 csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x82f839ca netif_device_detach +EXPORT_SYMBOL vmlinux 0x830e547b ioremap_prot +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83c53890 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x83ce0d01 kobject_del +EXPORT_SYMBOL vmlinux 0x83f5d309 acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0x840a4206 dquot_free_space +EXPORT_SYMBOL vmlinux 0x84206846 dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0x842d9e14 llc_add_pack +EXPORT_SYMBOL vmlinux 0x843e8958 __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x844a2183 nf_register_hooks +EXPORT_SYMBOL vmlinux 0x84bf0b77 blk_get_request +EXPORT_SYMBOL vmlinux 0x84d2a886 serio_close +EXPORT_SYMBOL vmlinux 0x84d7f055 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x84e291ab try_to_release_page +EXPORT_SYMBOL vmlinux 0x852b2bbd sk_run_filter +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x8584ea96 _cpu_pda +EXPORT_SYMBOL vmlinux 0x85abc85f strncmp +EXPORT_SYMBOL vmlinux 0x85c18861 bio_split +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85edc595 request_firmware +EXPORT_SYMBOL vmlinux 0x863064fc vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x8631f188 radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0x863bd0ec alloc_fcdev +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x863f8fdc pci_disable_device +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x866774fa __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x866906df pci_fixup_device +EXPORT_SYMBOL vmlinux 0x86713cd3 keyring_clear +EXPORT_SYMBOL vmlinux 0x867d57e8 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0x8680fc4a netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x86894974 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86bddbc3 generic_permission +EXPORT_SYMBOL vmlinux 0x86d4ab6f inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x86fdd5c5 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x870e5a99 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87b038a5 bdi_init +EXPORT_SYMBOL vmlinux 0x87b7e481 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x87b7e9f6 inet6_bind +EXPORT_SYMBOL vmlinux 0x87dfe41f sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x87e2feac scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x87f978f3 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x886ad577 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x8872d11c pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x8877494c ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0x889376f7 do_munmap +EXPORT_SYMBOL vmlinux 0x889d0bf9 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x88b331a1 xfrm_state_update +EXPORT_SYMBOL vmlinux 0x88d31373 block_read_full_page +EXPORT_SYMBOL vmlinux 0x892469a9 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89b016fd pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x89be41e7 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89e5f087 fget +EXPORT_SYMBOL vmlinux 0x89ea2e60 make_EII_client +EXPORT_SYMBOL vmlinux 0x8a0735c5 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x8a10cfd8 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8ac40297 iommu_area_free +EXPORT_SYMBOL vmlinux 0x8b1edb1d pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x8b35e873 sg_last +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b57c981 input_set_keycode +EXPORT_SYMBOL vmlinux 0x8b59069d vfs_follow_link +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b6d8490 inode_init_once +EXPORT_SYMBOL vmlinux 0x8b7fe311 kmemdup +EXPORT_SYMBOL vmlinux 0x8b873394 tcp_child_process +EXPORT_SYMBOL vmlinux 0x8b89b245 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0x8b922c0f __strnlen_user +EXPORT_SYMBOL vmlinux 0x8b966b63 sn_rtc_cycles_per_second +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8ba82374 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x8bcbbda7 mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x8be7c274 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x8c08b567 swiotlb_unmap_single +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c519be9 dev_change_flags +EXPORT_SYMBOL vmlinux 0x8c7a10f6 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x8c87c243 kill_fasync +EXPORT_SYMBOL vmlinux 0x8c99c0cf register_console +EXPORT_SYMBOL vmlinux 0x8ca85385 block_truncate_page +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8cca283e icmpv6_send +EXPORT_SYMBOL vmlinux 0x8ced58a2 follow_up +EXPORT_SYMBOL vmlinux 0x8d0698d0 udp_ioctl +EXPORT_SYMBOL vmlinux 0x8d0d8d4a sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x8d249a6e nf_hook_slow +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d446625 pv_cpu_ops +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d65e07b filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8db066d5 nf_register_hook +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e46936e pci_enable_wake +EXPORT_SYMBOL vmlinux 0x8e48dbf8 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8eafe5be atm_charge +EXPORT_SYMBOL vmlinux 0x8ec7f377 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x8f1ae4c9 pcim_iounmap +EXPORT_SYMBOL vmlinux 0x8f3046d2 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x8f37d3a6 acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x8f4b4e4e remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x8f4fe587 scsi_device_get +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f73ef50 blk_free_tags +EXPORT_SYMBOL vmlinux 0x8f7d81f1 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x8f8d78ec mdiobus_unregister +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8f9f6fb3 vc_resize +EXPORT_SYMBOL vmlinux 0x8fad5bd5 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x8fb7e07a dev_add_pack +EXPORT_SYMBOL vmlinux 0x8fc33ffd sock_i_uid +EXPORT_SYMBOL vmlinux 0x8ff327dd agp_free_page_array +EXPORT_SYMBOL vmlinux 0x8ff5f7c6 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x8ffbe5e9 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x90022b44 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x90758194 audit_log_end +EXPORT_SYMBOL vmlinux 0x90835f33 seq_release +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a6af3e xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90dfea22 dma_async_client_register +EXPORT_SYMBOL vmlinux 0x90e8c307 tty_free_termios +EXPORT_SYMBOL vmlinux 0x910ad3ff rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x91297586 journal_clear_err +EXPORT_SYMBOL vmlinux 0x9134d476 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x9161de6b do_sync_read +EXPORT_SYMBOL vmlinux 0x9163ef23 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x916789a2 dquot_free_inode +EXPORT_SYMBOL vmlinux 0x9187d7ad dcache_readdir +EXPORT_SYMBOL vmlinux 0x91890811 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x919b7497 dump_trace +EXPORT_SYMBOL vmlinux 0x91a273fa blk_init_queue +EXPORT_SYMBOL vmlinux 0x91b0dee2 fasync_helper +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x91d08bcd __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x91d3b820 sg_miter_next +EXPORT_SYMBOL vmlinux 0x920dd64a __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x92304ab9 iget5_locked +EXPORT_SYMBOL vmlinux 0x92390758 phy_disconnect +EXPORT_SYMBOL vmlinux 0x92392cd9 iov_shorten +EXPORT_SYMBOL vmlinux 0x923a626d simple_release_fs +EXPORT_SYMBOL vmlinux 0x92755c43 alloc_file +EXPORT_SYMBOL vmlinux 0x927cbb1e skb_trim +EXPORT_SYMBOL vmlinux 0x927e989f gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x92856b3d vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x92d701b6 dquot_acquire +EXPORT_SYMBOL vmlinux 0x92ea4ae4 crc32_le +EXPORT_SYMBOL vmlinux 0x92f66d19 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x930315a4 __seq_open_private +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x9312c9c5 bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x933b222e __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x9341eb90 dget_locked +EXPORT_SYMBOL vmlinux 0x934d565d tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x9357c5c9 sock_kmalloc +EXPORT_SYMBOL vmlinux 0x936417c3 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x9384cb13 file_update_time +EXPORT_SYMBOL vmlinux 0x93850b28 init_net +EXPORT_SYMBOL vmlinux 0x93886409 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93afa72e vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93d7cb85 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x93ed6a1b mem_section +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x9428750c skb_copy_bits +EXPORT_SYMBOL vmlinux 0x943e868f ida_get_new +EXPORT_SYMBOL vmlinux 0x945bc6a7 copy_from_user +EXPORT_SYMBOL vmlinux 0x94883ab2 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x949e7c75 phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0x94e3cf88 igrab +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x952cd34f jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0x95352ea9 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x954445ad hci_register_proto +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x9552bc9a netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x9561cace udp_sendmsg +EXPORT_SYMBOL vmlinux 0x95ceb864 key_update +EXPORT_SYMBOL vmlinux 0x95dd999a gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x96066cc6 swiotlb_dma_mapping_error +EXPORT_SYMBOL vmlinux 0x960e010f scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x9642740d tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x9675a809 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x96b2039f qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x96b67592 dquot_alloc_space +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96dc7576 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x96f33400 up_read +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x97518060 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x977fc100 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x9782442e agp_enable +EXPORT_SYMBOL vmlinux 0x97a073fd netlink_broadcast +EXPORT_SYMBOL vmlinux 0x97a4768e neigh_for_each +EXPORT_SYMBOL vmlinux 0x97be1693 ht_create_irq +EXPORT_SYMBOL vmlinux 0x97c5c874 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x97cc5076 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x980eae57 mpage_readpages +EXPORT_SYMBOL vmlinux 0x9836a2b0 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x9839449c load_nls +EXPORT_SYMBOL vmlinux 0x984138d7 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x98ca299b blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x98e02636 generic_setlease +EXPORT_SYMBOL vmlinux 0x98e5f680 __devm_release_region +EXPORT_SYMBOL vmlinux 0x9906f3c2 tty_vhangup +EXPORT_SYMBOL vmlinux 0x9978b36e bd_set_size +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x9996b654 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x999c3fd1 hci_send_sco +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99a75ec9 lookup_bdev +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99b9e975 dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99d93be4 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x9a13b31b __rta_fill +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a2b0c3f thaw_bdev +EXPORT_SYMBOL vmlinux 0x9a2c8195 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x9a2d04e3 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x9a3bdcb7 sock_wfree +EXPORT_SYMBOL vmlinux 0x9a3c4f55 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a807877 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0x9a92cb2e pci_pme_active +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9aabc564 crc16 +EXPORT_SYMBOL vmlinux 0x9abe1988 page_symlink +EXPORT_SYMBOL vmlinux 0x9ad1c6db tty_register_device +EXPORT_SYMBOL vmlinux 0x9ae526c4 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x9aecd4b1 pci_release_regions +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b44582e posix_lock_file +EXPORT_SYMBOL vmlinux 0x9b492f6e bio_put +EXPORT_SYMBOL vmlinux 0x9b579600 audit_log_format +EXPORT_SYMBOL vmlinux 0x9b6408d6 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x9b897111 is_bad_inode +EXPORT_SYMBOL vmlinux 0x9b962abf nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bc565c5 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x9bc8c39b journal_destroy +EXPORT_SYMBOL vmlinux 0x9bcf1979 elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x9bfc92de __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c028b08 aio_complete +EXPORT_SYMBOL vmlinux 0x9c0362d6 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x9c0ea3cd memscan +EXPORT_SYMBOL vmlinux 0x9c1f2afd ll_rw_block +EXPORT_SYMBOL vmlinux 0x9c23ee7f dm_get_device +EXPORT_SYMBOL vmlinux 0x9c491f60 sg_alloc_table +EXPORT_SYMBOL vmlinux 0x9c5b3050 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x9c8648cf pci_select_bars +EXPORT_SYMBOL vmlinux 0x9c87939a d_splice_alias +EXPORT_SYMBOL vmlinux 0x9c9048d7 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x9c94c107 nobh_write_end +EXPORT_SYMBOL vmlinux 0x9ca9043d tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x9ca95a0e sort +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d016b53 vfs_rename +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d5f8d51 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9db21624 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x9dfb5072 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x9e01e590 blk_verify_command +EXPORT_SYMBOL vmlinux 0x9e200ead generic_file_llseek +EXPORT_SYMBOL vmlinux 0x9e2d2184 llc_sap_find +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9ea0ad49 __sg_free_table +EXPORT_SYMBOL vmlinux 0x9ea28ec7 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x9ea85063 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0x9ebd4c04 adjust_resource +EXPORT_SYMBOL vmlinux 0x9edbecae snprintf +EXPORT_SYMBOL vmlinux 0x9ee91b1a hippi_type_trans +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f1fdf0f revalidate_disk +EXPORT_SYMBOL vmlinux 0x9f210879 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f44e800 dm_table_get_md +EXPORT_SYMBOL vmlinux 0x9f46b01d mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x9f6b6587 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x9f890637 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9ff70bdb call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa077e376 tcf_hash_create +EXPORT_SYMBOL vmlinux 0xa07fad56 inode_add_bytes +EXPORT_SYMBOL vmlinux 0xa09b497b inet6_del_protocol +EXPORT_SYMBOL vmlinux 0xa0a16651 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0xa0a59547 vfs_link +EXPORT_SYMBOL vmlinux 0xa0a5d4eb alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10d22cb contig_page_data +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa133538e generic_unplug_device +EXPORT_SYMBOL vmlinux 0xa1371257 sock_sendmsg +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa13aecfc cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0xa14a5135 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xa16d2fb8 elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xa1862c7d mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0xa1a7cf0e sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0xa1aeec23 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1b7d706 arp_send +EXPORT_SYMBOL vmlinux 0xa1bcc850 ps2_sendbyte +EXPORT_SYMBOL vmlinux 0xa1c0117b console_start +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1f4cd89 devm_iounmap +EXPORT_SYMBOL vmlinux 0xa1fd1ec9 write_cache_pages +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa230751c blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xa23fa523 wireless_spy_update +EXPORT_SYMBOL vmlinux 0xa261b90c scsi_init_io +EXPORT_SYMBOL vmlinux 0xa285db3e swiotlb_map_sg +EXPORT_SYMBOL vmlinux 0xa28dc9cf block_write_begin +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2c294a3 misc_deregister +EXPORT_SYMBOL vmlinux 0xa2cfa0db alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0xa2e73912 tty_devnum +EXPORT_SYMBOL vmlinux 0xa2eb9d1d jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0xa2f03981 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0xa31f172d __copy_from_user_inatomic +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa32b0139 skb_insert +EXPORT_SYMBOL vmlinux 0xa32da8ad sk_common_release +EXPORT_SYMBOL vmlinux 0xa337507f update_region +EXPORT_SYMBOL vmlinux 0xa33d8da9 agp_alloc_page_array +EXPORT_SYMBOL vmlinux 0xa33f7c7c nla_strlcpy +EXPORT_SYMBOL vmlinux 0xa34cabc1 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa3677d9c vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0xa3a5be95 memmove +EXPORT_SYMBOL vmlinux 0xa3ad38d1 secpath_dup +EXPORT_SYMBOL vmlinux 0xa3b6cfdc pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3e79752 d_alloc_root +EXPORT_SYMBOL vmlinux 0xa3f8d47c bio_sector_offset +EXPORT_SYMBOL vmlinux 0xa424ad44 i2c_master_send +EXPORT_SYMBOL vmlinux 0xa4295360 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa46b4aa4 hci_resume_dev +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4bae13d grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa4fb0631 bio_alloc +EXPORT_SYMBOL vmlinux 0xa506d10a kobject_init +EXPORT_SYMBOL vmlinux 0xa5114b0b pcie_port_service_register +EXPORT_SYMBOL vmlinux 0xa5239fde input_close_device +EXPORT_SYMBOL vmlinux 0xa523d30b inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa562e74b dec_zone_page_state +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa5739e8e set_device_ro +EXPORT_SYMBOL vmlinux 0xa5838f6b neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa5962225 fsync_bdev +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa59aa051 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0xa5adbe8c ida_destroy +EXPORT_SYMBOL vmlinux 0xa5c4a043 kill_block_super +EXPORT_SYMBOL vmlinux 0xa613f372 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0xa61e9a53 tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa68de2b8 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e0fa68 k8_northbridges +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa71b5aac generic_show_options +EXPORT_SYMBOL vmlinux 0xa72ac454 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa79850e9 bio_add_page +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7c78b2a __starget_for_each_device +EXPORT_SYMBOL vmlinux 0xa7e89a4e sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xa7f3c5d1 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xa7ff79e2 d_delete +EXPORT_SYMBOL vmlinux 0xa8026c53 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xa806bd71 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0xa816c525 schedule_work_on +EXPORT_SYMBOL vmlinux 0xa822dae7 down_read +EXPORT_SYMBOL vmlinux 0xa827f4e5 vcc_release_async +EXPORT_SYMBOL vmlinux 0xa82a0d6d pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xa83fcb38 input_set_capability +EXPORT_SYMBOL vmlinux 0xa8551679 tty_kref_put +EXPORT_SYMBOL vmlinux 0xa85c2b0a netdev_features_change +EXPORT_SYMBOL vmlinux 0xa8691c45 skb_unlink +EXPORT_SYMBOL vmlinux 0xa886a958 krealloc +EXPORT_SYMBOL vmlinux 0xa8901e14 generic_block_bmap +EXPORT_SYMBOL vmlinux 0xa89600ea set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xa8a6f639 __check_region +EXPORT_SYMBOL vmlinux 0xa8accb43 mark_page_accessed +EXPORT_SYMBOL vmlinux 0xa8bb9b14 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0xa8c5b1e6 audit_log_start +EXPORT_SYMBOL vmlinux 0xa8c64c4b journal_update_format +EXPORT_SYMBOL vmlinux 0xa8dcedce I_BDEV +EXPORT_SYMBOL vmlinux 0xa8f27f9d simple_empty +EXPORT_SYMBOL vmlinux 0xa8fbf582 idr_replace +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa951c6a8 generic_make_request +EXPORT_SYMBOL vmlinux 0xa97233c1 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0xa9854ce1 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xa991e09a tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xa9b74a53 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xa9c622c0 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa0a6292 blk_run_queue +EXPORT_SYMBOL vmlinux 0xaa53ad6b blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0xaa6cbd87 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa89b982 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaab41f64 pnp_possible_config +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab1fb136 input_allocate_device +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab62d741 notify_change +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xab6da3aa input_grab_device +EXPORT_SYMBOL vmlinux 0xab95e164 vfs_write +EXPORT_SYMBOL vmlinux 0xaba9ff34 allocate_resource +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabe85a21 idr_init +EXPORT_SYMBOL vmlinux 0xac074eee lock_super +EXPORT_SYMBOL vmlinux 0xac0bbfa8 _proxy_pda +EXPORT_SYMBOL vmlinux 0xac235b9e pci_get_device +EXPORT_SYMBOL vmlinux 0xac383451 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac43c36b deny_write_access +EXPORT_SYMBOL vmlinux 0xac473d80 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xac4ea2d6 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0xac522c8f elv_add_request +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xac76e2c2 scsi_prep_return +EXPORT_SYMBOL vmlinux 0xac770feb filemap_fault +EXPORT_SYMBOL vmlinux 0xaca16bc0 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xacf538f3 unregister_filesystem +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad18330f force_sig +EXPORT_SYMBOL vmlinux 0xad2531da blk_execute_rq +EXPORT_SYMBOL vmlinux 0xad25fb12 __memcpy +EXPORT_SYMBOL vmlinux 0xad43d100 kernel_connect +EXPORT_SYMBOL vmlinux 0xad68b2a1 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0xad8de1b3 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0xad93331a qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xad960b6f dst_destroy +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadbe3ddd dma_supported +EXPORT_SYMBOL vmlinux 0xadc19a9c inet6_release +EXPORT_SYMBOL vmlinux 0xae17a1d1 phy_scan_fixups +EXPORT_SYMBOL vmlinux 0xae638f4a netif_rx +EXPORT_SYMBOL vmlinux 0xaea1bef8 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0xaea773fb scsi_host_get +EXPORT_SYMBOL vmlinux 0xaec7f6e3 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0xaee7e6f8 pci_enable_device +EXPORT_SYMBOL vmlinux 0xaf187f04 tr_type_trans +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf486c5e save_mount_options +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf68d101 ipv4_specific +EXPORT_SYMBOL vmlinux 0xaf84d9c8 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xafb6a879 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xafd83430 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0xafd9ab8d nla_reserve +EXPORT_SYMBOL vmlinux 0xafe82e10 strcspn +EXPORT_SYMBOL vmlinux 0xaff3c472 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0xb01e7189 simple_transaction_release +EXPORT_SYMBOL vmlinux 0xb032b650 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xb034eab6 ndisc_mc_map +EXPORT_SYMBOL vmlinux 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL vmlinux 0xb051909f ida_init +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb08d7d4a agp_generic_alloc_by_type +EXPORT_SYMBOL vmlinux 0xb09d0f79 netif_receive_skb +EXPORT_SYMBOL vmlinux 0xb0a2ad20 unlock_new_inode +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0dc68bc dst_alloc +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0ef077e vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xb1130341 acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0xb116807f vfs_lstat +EXPORT_SYMBOL vmlinux 0xb11fa1ce strlcat +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb1293c36 inode_change_ok +EXPORT_SYMBOL vmlinux 0xb137d9d5 bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0xb1645a2e sg_free_table +EXPORT_SYMBOL vmlinux 0xb16ae628 sk_filter +EXPORT_SYMBOL vmlinux 0xb18e02c3 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xb18f0114 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1a9ff75 tty_write_room +EXPORT_SYMBOL vmlinux 0xb1c0acc0 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb20359a9 input_inject_event +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb233861e km_state_notify +EXPORT_SYMBOL vmlinux 0xb2704f72 scsi_remove_host +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb2897551 sync_page_range +EXPORT_SYMBOL vmlinux 0xb295600e mpage_writepage +EXPORT_SYMBOL vmlinux 0xb2ab1111 brioctl_set +EXPORT_SYMBOL vmlinux 0xb2ab43ab kobject_put +EXPORT_SYMBOL vmlinux 0xb2be638a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xb2dfd300 make_bad_inode +EXPORT_SYMBOL vmlinux 0xb2f84f76 loop_register_transfer +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb306f164 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3247c4a sock_register +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb33095d9 blk_complete_request +EXPORT_SYMBOL vmlinux 0xb3318ded __down_read_trylock +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb3509e7a sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb384fc45 arp_find +EXPORT_SYMBOL vmlinux 0xb3897fad kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xb3a06c04 follow_down +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3a726a9 __pagevec_release +EXPORT_SYMBOL vmlinux 0xb3c5be64 agp_bridge +EXPORT_SYMBOL vmlinux 0xb3d8772c rfkill_free +EXPORT_SYMBOL vmlinux 0xb3dea9b7 file_fsync +EXPORT_SYMBOL vmlinux 0xb3e7021a register_quota_format +EXPORT_SYMBOL vmlinux 0xb3f0af31 deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0xb3ff1f69 free_pages_exact +EXPORT_SYMBOL vmlinux 0xb40ce811 path_permission +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb46d0970 send_sig +EXPORT_SYMBOL vmlinux 0xb4875d25 vfs_llseek +EXPORT_SYMBOL vmlinux 0xb489940a mdiobus_register +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4b75b2d jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4d84444 dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0xb4dddf03 unbind_con_driver +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb537ea4d udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb547ad2d mmc_remove_host +EXPORT_SYMBOL vmlinux 0xb59e3f5e nla_put +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5b8b6d8 proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb61d3b59 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xb6244511 sg_init_one +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb67b9a7e journal_revoke +EXPORT_SYMBOL vmlinux 0xb68a2012 __napi_schedule +EXPORT_SYMBOL vmlinux 0xb69ef2a7 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6abeae3 fb_get_mode +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6ce9ff8 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6e4ad9b input_register_handler +EXPORT_SYMBOL vmlinux 0xb70a8b45 kfree_skb +EXPORT_SYMBOL vmlinux 0xb70bb200 vcc_insert_socket +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb7585fb0 agp3_generic_tlbflush +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb75f9e0b dev_unicast_add +EXPORT_SYMBOL vmlinux 0xb7814404 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xb7eda8b2 rt6_lookup +EXPORT_SYMBOL vmlinux 0xb7ee3f25 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb84176d2 path_lookup +EXPORT_SYMBOL vmlinux 0xb867aaf3 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb8735b41 tcp_connect +EXPORT_SYMBOL vmlinux 0xb87ee4cc journal_check_available_features +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8b54871 vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb8f34f8e tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb92bcc82 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0xb9358749 d_validate +EXPORT_SYMBOL vmlinux 0xb96c9058 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0xb9767d21 pnp_device_attach +EXPORT_SYMBOL vmlinux 0xb9805b0c down_read_trylock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9bbe97d pci_scan_bridge +EXPORT_SYMBOL vmlinux 0xb9bf23c7 pci_disable_msix +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9d2510b bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0xb9d57c4f blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xb9f64a58 dma_async_device_register +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba02cdf2 cdev_add +EXPORT_SYMBOL vmlinux 0xba094669 set_trace_device +EXPORT_SYMBOL vmlinux 0xba16f720 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0xba2b884b journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba31c345 skb_push +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba9532bf dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0xbaa2782a kstrndup +EXPORT_SYMBOL vmlinux 0xbaa79c56 devm_ioport_map +EXPORT_SYMBOL vmlinux 0xbad66fad vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0xbb09f52b inet_ioctl +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb4d3101 dev_close +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb5fcfb4 jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbb897ccd cfb_fillrect +EXPORT_SYMBOL vmlinux 0xbb956674 simple_fill_super +EXPORT_SYMBOL vmlinux 0xbb9e0721 blk_recount_segments +EXPORT_SYMBOL vmlinux 0xbba68558 scsi_remove_target +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbc30661e find_lock_page +EXPORT_SYMBOL vmlinux 0xbc4f81fb blk_alloc_queue +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcc935d2 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0xbccbb49c idr_remove_all +EXPORT_SYMBOL vmlinux 0xbcf148cf inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xbd01ce87 journal_load +EXPORT_SYMBOL vmlinux 0xbd131953 bio_map_user +EXPORT_SYMBOL vmlinux 0xbd782863 input_free_device +EXPORT_SYMBOL vmlinux 0xbdaf5b07 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0xbdc50c27 dev_set_mtu +EXPORT_SYMBOL vmlinux 0xbdd1032e prepare_binprm +EXPORT_SYMBOL vmlinux 0xbdd3fac3 acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0xbdd80660 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0xbde0f165 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0xbe321fd4 seq_lseek +EXPORT_SYMBOL vmlinux 0xbe3518d9 i2c_use_client +EXPORT_SYMBOL vmlinux 0xbe499d81 copy_to_user +EXPORT_SYMBOL vmlinux 0xbe5c9eee blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0xbe86cdd5 atm_init_aal5 +EXPORT_SYMBOL vmlinux 0xbeabf6c2 scsi_scan_host +EXPORT_SYMBOL vmlinux 0xbeacdc35 ip_route_input +EXPORT_SYMBOL vmlinux 0xbeb2b930 __inet6_hash +EXPORT_SYMBOL vmlinux 0xbeb95b9a hci_suspend_dev +EXPORT_SYMBOL vmlinux 0xbebf1e01 bt_sock_poll +EXPORT_SYMBOL vmlinux 0xbecdce74 ida_pre_get +EXPORT_SYMBOL vmlinux 0xbef0040f tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbefee397 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0xbf04c5df cfb_copyarea +EXPORT_SYMBOL vmlinux 0xbf2345fd __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0xbf358b45 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0xbf5e9c12 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0xbf718c97 ___pskb_trim +EXPORT_SYMBOL vmlinux 0xbf7adee1 cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfa52fc5 hci_register_dev +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfd28796 scsi_host_put +EXPORT_SYMBOL vmlinux 0xbfe56d79 lock_rename +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01eac97 netlink_ack +EXPORT_SYMBOL vmlinux 0xc031b5f5 tcp_ioctl +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc05e41e7 get_empty_filp +EXPORT_SYMBOL vmlinux 0xc061e56a get_write_access +EXPORT_SYMBOL vmlinux 0xc07d43ae acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xc09651d9 crc32_be +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0b3b04f elv_queue_empty +EXPORT_SYMBOL vmlinux 0xc0b76cc8 nobh_write_begin +EXPORT_SYMBOL vmlinux 0xc0bdcb4c jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0xc0be790d bitmap_end_sync +EXPORT_SYMBOL vmlinux 0xc0d7fa39 pci_iomap +EXPORT_SYMBOL vmlinux 0xc0f31263 ip_route_output_key +EXPORT_SYMBOL vmlinux 0xc1103f21 md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xc1155451 tcp_shutdown +EXPORT_SYMBOL vmlinux 0xc131500d con_is_bound +EXPORT_SYMBOL vmlinux 0xc13d7e4c __downgrade_write +EXPORT_SYMBOL vmlinux 0xc1403886 bio_init +EXPORT_SYMBOL vmlinux 0xc14d1047 acpi_bus_start +EXPORT_SYMBOL vmlinux 0xc16a9eaf skb_dma_map +EXPORT_SYMBOL vmlinux 0xc17e96bd free_buffer_head +EXPORT_SYMBOL vmlinux 0xc18454dd set_binfmt +EXPORT_SYMBOL vmlinux 0xc1a9fec4 phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0xc1e5799b unload_nls +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc20f0469 __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0xc21cc374 pcim_iomap +EXPORT_SYMBOL vmlinux 0xc229eaee flush_old_exec +EXPORT_SYMBOL vmlinux 0xc22b4bfd generic_osync_inode +EXPORT_SYMBOL vmlinux 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL vmlinux 0xc253a04f __splice_from_pipe +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc26c26b8 dev_open +EXPORT_SYMBOL vmlinux 0xc292b222 xfrm_state_add +EXPORT_SYMBOL vmlinux 0xc2aaa3e4 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xc2b87933 hci_register_cb +EXPORT_SYMBOL vmlinux 0xc2c3a3eb dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xc2c95270 pnp_start_dev +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2fdc37a mmc_release_host +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc340960a swiotlb_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0xc3611976 input_unregister_device +EXPORT_SYMBOL vmlinux 0xc36f1fa1 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xc37e2868 km_state_expired +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc41d175f kset_register +EXPORT_SYMBOL vmlinux 0xc43c9a8c dev_mc_unsync +EXPORT_SYMBOL vmlinux 0xc444efaf compat_sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xc465cc6c iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0xc4925812 pci_map_rom +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4a2be5e sget +EXPORT_SYMBOL vmlinux 0xc4ac5c17 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xc4cdb705 unregister_netdevice +EXPORT_SYMBOL vmlinux 0xc4d489e9 up_write +EXPORT_SYMBOL vmlinux 0xc4d8a050 jbd2_journal_start +EXPORT_SYMBOL vmlinux 0xc5094c2b journal_release_buffer +EXPORT_SYMBOL vmlinux 0xc51ca174 inet_put_port +EXPORT_SYMBOL vmlinux 0xc51e6d2e generic_file_open +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc53c882d idr_get_new +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc558530d profile_pc +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc5644d18 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xc57d4378 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0xc59e230f input_register_device +EXPORT_SYMBOL vmlinux 0xc5a06657 textsearch_register +EXPORT_SYMBOL vmlinux 0xc5af5143 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xc5bd4d75 dquot_commit_info +EXPORT_SYMBOL vmlinux 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL vmlinux 0xc610c0f1 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xc63d3d3b eth_header_cache +EXPORT_SYMBOL vmlinux 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL vmlinux 0xc65ce1b2 swiotlb_unmap_single_attrs +EXPORT_SYMBOL vmlinux 0xc65e5a84 hci_get_route +EXPORT_SYMBOL vmlinux 0xc68944ce swiotlb_dma_supported +EXPORT_SYMBOL vmlinux 0xc6bd0d12 dev_get_flags +EXPORT_SYMBOL vmlinux 0xc6c176e7 find_inode_number +EXPORT_SYMBOL vmlinux 0xc6d87e82 __find_get_block +EXPORT_SYMBOL vmlinux 0xc6f8264d phy_register_fixup +EXPORT_SYMBOL vmlinux 0xc6fe73e3 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0xc7080a71 compat_mc_setsockopt +EXPORT_SYMBOL vmlinux 0xc71c0305 vmap +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc740c64a memchr +EXPORT_SYMBOL vmlinux 0xc753a96a ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0xc75d189b bio_integrity_trim +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc79d214a mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xc7a24d76 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7be3788 __nla_reserve +EXPORT_SYMBOL vmlinux 0xc7ca9e77 jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0xc7ceb53a end_page_writeback +EXPORT_SYMBOL vmlinux 0xc7fa68bf register_qdisc +EXPORT_SYMBOL vmlinux 0xc8483bab ilookup5 +EXPORT_SYMBOL vmlinux 0xc86249a0 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xc897c382 sg_init_table +EXPORT_SYMBOL vmlinux 0xc8a90017 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0xc8abf7c6 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8bece9a page_readlink +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8e0130b dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0xc8e94ef8 key_validate +EXPORT_SYMBOL vmlinux 0xc900f860 inet_stream_ops +EXPORT_SYMBOL vmlinux 0xc908c116 udp_poll +EXPORT_SYMBOL vmlinux 0xc90fc82b d_genocide +EXPORT_SYMBOL vmlinux 0xc921f453 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0xc923dac9 pv_mmu_ops +EXPORT_SYMBOL vmlinux 0xc9408dd4 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0xc940b538 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xc9437ede __down_write_nested +EXPORT_SYMBOL vmlinux 0xc9482f0e __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0xc96659bf skb_dequeue +EXPORT_SYMBOL vmlinux 0xc966f75c nf_log_packet +EXPORT_SYMBOL vmlinux 0xc96eefa9 __serio_register_driver +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc99cf467 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0xc9aaf360 __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0xc9ab0d46 agp_generic_alloc_pages +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9ae59c2 register_filesystem +EXPORT_SYMBOL vmlinux 0xc9c0cd17 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0xc9c40a9e mnt_unpin +EXPORT_SYMBOL vmlinux 0xc9eb9866 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0xca222911 pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xca48501c jbd2_journal_create +EXPORT_SYMBOL vmlinux 0xca4df118 block_sync_page +EXPORT_SYMBOL vmlinux 0xca544c7a inetdev_by_index +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca621e87 generic_delete_inode +EXPORT_SYMBOL vmlinux 0xca662826 phy_print_status +EXPORT_SYMBOL vmlinux 0xca730459 pid_task +EXPORT_SYMBOL vmlinux 0xca89da02 kernel_accept +EXPORT_SYMBOL vmlinux 0xca8abced request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xcb090571 swiotlb_map_single +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb47a797 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0xcb48fe0e register_cdrom +EXPORT_SYMBOL vmlinux 0xcb6361fb generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcb876f03 journal_start_commit +EXPORT_SYMBOL vmlinux 0xcbc1f02f sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0xcbf5162b tcp_disconnect +EXPORT_SYMBOL vmlinux 0xcc07af75 strnlen +EXPORT_SYMBOL vmlinux 0xcc182a63 bt_accept_unlink +EXPORT_SYMBOL vmlinux 0xcc18747e sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc20274a md_check_recovery +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc2b1629 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc4c1e02 search_binary_handler +EXPORT_SYMBOL vmlinux 0xcc4ec4fe neigh_compat_output +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc73a93e __bio_clone +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc93e89f blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0xcca75064 serial8250_register_port +EXPORT_SYMBOL vmlinux 0xccc06e90 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0xccc2390b task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0xccc43bfa jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0xccd048c4 xfrm_input +EXPORT_SYMBOL vmlinux 0xcce9ccab dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xccf77ad8 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0xcd23496d dev_set_mac_address +EXPORT_SYMBOL vmlinux 0xcd28e957 file_remove_suid +EXPORT_SYMBOL vmlinux 0xcd290e0e close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xcd625888 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0xcd8a1951 dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0xcdd3f3dc blk_start_queue +EXPORT_SYMBOL vmlinux 0xcdf6f59a netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce1f2cc2 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0xce28f08c blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce82a1ca vfs_quota_off +EXPORT_SYMBOL vmlinux 0xce971b6b llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0xceb4c77f blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0xcec47845 agp_flush_chipset +EXPORT_SYMBOL vmlinux 0xcecee2c0 bio_unmap_user +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf1242a4 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xcf28b263 jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0xcf953ec8 sock_rfree +EXPORT_SYMBOL vmlinux 0xcfab02ce eth_header +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfc277f4 arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0xcfc96384 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xd0020122 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd01ffb64 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd05907c3 scm_detach_fds +EXPORT_SYMBOL vmlinux 0xd07bb451 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd0a8e245 alloc_disk +EXPORT_SYMBOL vmlinux 0xd0e9df1e kernel_read +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL vmlinux 0xd103767e con_copy_unimap +EXPORT_SYMBOL vmlinux 0xd1076263 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd1558a90 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0xd1892179 del_gendisk +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd18c53d4 agp_generic_destroy_pages +EXPORT_SYMBOL vmlinux 0xd19bb294 acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0xd1c445b3 dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0xd1de3f0d drop_super +EXPORT_SYMBOL vmlinux 0xd1e85783 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0xd1eaa0a5 inode_permission +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f74e1c proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd232a94c path_put +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd2695e43 hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0xd291a1f7 blk_unplug +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd29fface i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0xd2d1893d add_disk +EXPORT_SYMBOL vmlinux 0xd2eb48fa tty_port_tty_get +EXPORT_SYMBOL vmlinux 0xd30f6e80 module_put +EXPORT_SYMBOL vmlinux 0xd3253af8 skb_queue_head +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd424873a proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd464a892 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xd46702fa tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0xd482d2df skb_find_text +EXPORT_SYMBOL vmlinux 0xd4903145 sysctl_string +EXPORT_SYMBOL vmlinux 0xd4a4a57f inode_needs_sync +EXPORT_SYMBOL vmlinux 0xd4d109c5 dma_sync_wait +EXPORT_SYMBOL vmlinux 0xd4fd9318 __break_lease +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd57f8789 iommu_num_pages +EXPORT_SYMBOL vmlinux 0xd5963d0c pci_set_mwi +EXPORT_SYMBOL vmlinux 0xd5a7feac mdiobus_write +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5cc4183 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xd5d96178 poll_freewait +EXPORT_SYMBOL vmlinux 0xd5ffc24b compat_tcp_setsockopt +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd60b5fe5 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0xd60d7af4 ida_remove +EXPORT_SYMBOL vmlinux 0xd61152fa blkdev_get +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd6315ab2 registered_fb +EXPORT_SYMBOL vmlinux 0xd6517380 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xd6526e41 pci_dev_put +EXPORT_SYMBOL vmlinux 0xd6a55706 kmem_cache_free +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6ad3b79 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6e00170 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd712f2c0 ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0xd758cd26 get_phy_id +EXPORT_SYMBOL vmlinux 0xd779bad1 llc_sap_close +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7b1b790 elv_rb_del +EXPORT_SYMBOL vmlinux 0xd7c11f42 inet_release +EXPORT_SYMBOL vmlinux 0xd7c8954a dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0xd7d8580d agp_alloc_bridge +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7e48b73 kset_unregister +EXPORT_SYMBOL vmlinux 0xd8216045 unregister_cdrom +EXPORT_SYMBOL vmlinux 0xd83a320a pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0xd8511b69 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0xd86fcd8b compat_ip_setsockopt +EXPORT_SYMBOL vmlinux 0xd88bc27b uart_add_one_port +EXPORT_SYMBOL vmlinux 0xd88e5781 pci_disable_msi +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a0514c kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xd8d74cab phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8efd3b7 phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0xd8f85285 wake_up_process +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd9262c76 generic_removexattr +EXPORT_SYMBOL vmlinux 0xd9370b06 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0xd9528c86 acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0xd96e0564 tty_check_change +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9ca3514 bio_integrity_split +EXPORT_SYMBOL vmlinux 0xda05d1c7 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda1c2975 __grab_cache_page +EXPORT_SYMBOL vmlinux 0xda2ee9c7 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xda45ba06 inet_sock_destruct +EXPORT_SYMBOL vmlinux 0xda4629e4 radix_tree_insert +EXPORT_SYMBOL vmlinux 0xda597d34 __ht_create_irq +EXPORT_SYMBOL vmlinux 0xda69a1f7 simple_set_mnt +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8d7811 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xda9ca32a serio_unregister_port +EXPORT_SYMBOL vmlinux 0xdaa5128a iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0xdac63607 qdisc_list_del +EXPORT_SYMBOL vmlinux 0xdacfc5f5 struct_module +EXPORT_SYMBOL vmlinux 0xdb0ae632 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xdb1977fb devm_free_irq +EXPORT_SYMBOL vmlinux 0xdb458957 agp_backend_acquire +EXPORT_SYMBOL vmlinux 0xdb795516 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0xdbbd6a92 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbd737e1 pci_get_class +EXPORT_SYMBOL vmlinux 0xdbe4a214 dmam_pool_create +EXPORT_SYMBOL vmlinux 0xdbf97e31 generic_write_end +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc4a5d44 compat_ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xdc611106 __lock_buffer +EXPORT_SYMBOL vmlinux 0xdc624d41 __lock_page +EXPORT_SYMBOL vmlinux 0xdc7166cc pci_restore_state +EXPORT_SYMBOL vmlinux 0xdc79e6bc tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0xdc7b8a08 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcdc9d18 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0xdd4388ae hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0xdd604f27 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0xdd6a25c5 neigh_event_ns +EXPORT_SYMBOL vmlinux 0xdd781b6f sock_setsockopt +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddca82ca bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0xddec02a9 compat_nf_getsockopt +EXPORT_SYMBOL vmlinux 0xddf43bc4 __serio_register_port +EXPORT_SYMBOL vmlinux 0xde0bdcff memset +EXPORT_SYMBOL vmlinux 0xde17c7d8 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0xde2180a2 inet_getname +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL vmlinux 0xdea9a13f tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0xdeab735c input_flush_device +EXPORT_SYMBOL vmlinux 0xdec62a8f pci_pme_capable +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf478691 journal_ack_err +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfa87a3d skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xdfb7bada acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xdfee58a0 genl_register_ops +EXPORT_SYMBOL vmlinux 0xe003ea39 neigh_table_init +EXPORT_SYMBOL vmlinux 0xe00e4296 journal_flush +EXPORT_SYMBOL vmlinux 0xe00ffa4e pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0xe016aa6b pci_set_master +EXPORT_SYMBOL vmlinux 0xe01e3aa9 tty_hangup +EXPORT_SYMBOL vmlinux 0xe02744c9 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0xe04fb17d __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0ad8b27 acpi_is_video_device +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0b30f72 sk_release_kernel +EXPORT_SYMBOL vmlinux 0xe0d2b488 skb_pad +EXPORT_SYMBOL vmlinux 0xe0f7dca7 sk_receive_skb +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe1287a1f do_splice_from +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe13fdb64 blk_integrity_compare +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1afcd98 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xe1c265d8 fd_install +EXPORT_SYMBOL vmlinux 0xe1e31e9b block_prepare_write +EXPORT_SYMBOL vmlinux 0xe1f7328d dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0xe20d2639 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0xe24050c7 scnprintf +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe2a6fd16 hci_conn_auth +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2d9e701 d_namespace_path +EXPORT_SYMBOL vmlinux 0xe2e3c78e blk_plug_device +EXPORT_SYMBOL vmlinux 0xe3053c0e dcache_dir_open +EXPORT_SYMBOL vmlinux 0xe30deaa1 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0xe325583d kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xe33f5247 per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0xe342c953 i2c_del_driver +EXPORT_SYMBOL vmlinux 0xe3446fa6 get_unmapped_area +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe3b0192b vscnprintf +EXPORT_SYMBOL vmlinux 0xe3b693b8 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0xe3b93a66 swiotlb_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe44dd841 dquot_drop +EXPORT_SYMBOL vmlinux 0xe44e09a9 d_alloc_name +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4c2e19a __scsi_add_device +EXPORT_SYMBOL vmlinux 0xe4cfd571 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xe4d372c3 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0xe4ff6bf9 journal_forget +EXPORT_SYMBOL vmlinux 0xe50c3845 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0xe50d8af5 fb_find_mode +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe5123687 hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe52947e7 __phys_addr +EXPORT_SYMBOL vmlinux 0xe542862a pnp_disable_dev +EXPORT_SYMBOL vmlinux 0xe55484ce neigh_seq_stop +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe583a2bf blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe59a710d filp_close +EXPORT_SYMBOL vmlinux 0xe5a04af5 pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5c800d9 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe5f9f7e9 dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0xe60b3450 sock_i_ino +EXPORT_SYMBOL vmlinux 0xe65a2175 hci_connect +EXPORT_SYMBOL vmlinux 0xe66ea6c0 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe694cc8a set_current_groups +EXPORT_SYMBOL vmlinux 0xe6951fb6 sock_create +EXPORT_SYMBOL vmlinux 0xe6ead2b1 bitmap_endwrite +EXPORT_SYMBOL vmlinux 0xe6fb136e d_move +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe713533c uart_unregister_driver +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe751ba22 rfkill_allocate +EXPORT_SYMBOL vmlinux 0xe7546fa3 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0xe75ef7f8 journal_init_dev +EXPORT_SYMBOL vmlinux 0xe778a831 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0xe77a01af sock_no_mmap +EXPORT_SYMBOL vmlinux 0xe77f9872 locks_init_lock +EXPORT_SYMBOL vmlinux 0xe786737e __netif_schedule +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7f28ed8 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0xe801db27 read_dev_sector +EXPORT_SYMBOL vmlinux 0xe80ce219 sysctl_tcp_dma_copybreak +EXPORT_SYMBOL vmlinux 0xe828b876 fb_set_cmap +EXPORT_SYMBOL vmlinux 0xe82b4cbf init_buffer +EXPORT_SYMBOL vmlinux 0xe8304561 vfs_getattr +EXPORT_SYMBOL vmlinux 0xe84e0bdf nf_log_unregister +EXPORT_SYMBOL vmlinux 0xe85498e4 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xe8583614 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0xe860436c tcf_em_unregister +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe88be0b3 tcp_sendpage +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8d0b674 simple_getattr +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe916c7ec xfrm_state_walk +EXPORT_SYMBOL vmlinux 0xe9387c3c dentry_open +EXPORT_SYMBOL vmlinux 0xe93e3144 kernel_listen +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe945c261 ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9ace35a swiotlb_unmap_sg +EXPORT_SYMBOL vmlinux 0xe9d627e1 starget_for_each_device +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea13320e blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea44461f key_type_keyring +EXPORT_SYMBOL vmlinux 0xea531368 mem_map +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea757d9e inet_frags_init +EXPORT_SYMBOL vmlinux 0xeac68305 set_page_dirty +EXPORT_SYMBOL vmlinux 0xeac6ebe1 vfs_quota_sync +EXPORT_SYMBOL vmlinux 0xead58fb9 print_hex_dump +EXPORT_SYMBOL vmlinux 0xeae03e48 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeae6025c skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0xeaf935f0 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xeb1d3f86 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb228272 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb58800e tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0xeb6137a4 swiotlb_free_coherent +EXPORT_SYMBOL vmlinux 0xeb8ddae2 unregister_snap_client +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeb9b4287 hci_unregister_proto +EXPORT_SYMBOL vmlinux 0xebbf1dba strncasecmp +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebe82b09 pci_get_slot +EXPORT_SYMBOL vmlinux 0xec381ddf ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0xec38ca43 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0xec3d368c block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xec3e0dd2 agp_create_memory +EXPORT_SYMBOL vmlinux 0xec539ad8 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xec93ca7f sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0xecb07aef blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0xecb46b04 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0xecd2b662 acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xece730b6 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0xeceb106e skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xed2789a3 vfs_readlink +EXPORT_SYMBOL vmlinux 0xed3b0e2f ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0xed583512 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xed60c586 skb_make_writable +EXPORT_SYMBOL vmlinux 0xed6b03e6 kern_path +EXPORT_SYMBOL vmlinux 0xed6cc474 __devm_request_region +EXPORT_SYMBOL vmlinux 0xed789ad9 pagecache_write_end +EXPORT_SYMBOL vmlinux 0xed819f4b agp_generic_free_by_type +EXPORT_SYMBOL vmlinux 0xed8b72d8 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0xeda59dcd vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedcd9dd0 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xee1e05a8 fb_pan_display +EXPORT_SYMBOL vmlinux 0xee1f0594 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xee2a4028 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee5281cd pnp_is_active +EXPORT_SYMBOL vmlinux 0xee5614e7 __brelse +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeaa7d0d security_task_getsecid +EXPORT_SYMBOL vmlinux 0xeeae6246 get_disk +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeecaea22 down_write_trylock +EXPORT_SYMBOL vmlinux 0xef13da58 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xef241669 agp_copy_info +EXPORT_SYMBOL vmlinux 0xef651e6e pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefa4f7bf set_bh_page +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xefef1e93 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf0551f96 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xf05b108d bio_uncopy_user +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf097d3e1 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0c411c1 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xf0ca0e43 bio_copy_user +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf0fee2e8 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0xf1004740 lease_get_mtime +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf116d4b5 copy_in_user +EXPORT_SYMBOL vmlinux 0xf11cf629 bmap +EXPORT_SYMBOL vmlinux 0xf12b6039 tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xf12fcd38 __lookup_hash +EXPORT_SYMBOL vmlinux 0xf14a1ca3 inode_setattr +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf174fe36 mark_info_dirty +EXPORT_SYMBOL vmlinux 0xf1752afe __request_region +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf19eedb3 fput +EXPORT_SYMBOL vmlinux 0xf1bf30c6 ilookup +EXPORT_SYMBOL vmlinux 0xf1d1a9e2 neigh_destroy +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1f11437 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0xf1fa89a0 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf23d5cb8 zero_fill_bio +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf25087b8 compat_sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xf2642953 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a4a545 generic_fillattr +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2ab1416 ip6_xmit +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2db10e2 ppp_channel_index +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf319450e tcp_proc_register +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf3360449 fb_class +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf34805cb dma_pool_create +EXPORT_SYMBOL vmlinux 0xf38681a9 dm_io +EXPORT_SYMBOL vmlinux 0xf3b62b46 inet_csk_accept +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3c4932c udp_disconnect +EXPORT_SYMBOL vmlinux 0xf3c9c001 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xf3e7d76e phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf4528073 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0xf4553b62 journal_set_features +EXPORT_SYMBOL vmlinux 0xf464ef69 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a27a03 arp_xmit +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4b4ace8 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf5240dae skb_put +EXPORT_SYMBOL vmlinux 0xf52441d9 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0xf53c4c3f touch_atime +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf567f3cb agp_generic_insert_memory +EXPORT_SYMBOL vmlinux 0xf5829132 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xf58dc7b0 seq_bitmap +EXPORT_SYMBOL vmlinux 0xf5981e94 d_rehash +EXPORT_SYMBOL vmlinux 0xf5a48326 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xf5ac7d9f tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xf5c6299b set_bdi_congested +EXPORT_SYMBOL vmlinux 0xf5c835f4 blk_stop_queue +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5dd687e tc_classify_compat +EXPORT_SYMBOL vmlinux 0xf5e61615 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0xf605b87d br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0xf61aebaa skb_free_datagram +EXPORT_SYMBOL vmlinux 0xf64c09d6 devm_ioremap +EXPORT_SYMBOL vmlinux 0xf666cbb3 __memcpy_fromio +EXPORT_SYMBOL vmlinux 0xf6ae2505 jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6cdb69b key_revoke +EXPORT_SYMBOL vmlinux 0xf6d7b2e6 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0xf6de9c22 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf705c09f scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xf70d1d93 inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xf71907cf fb_set_suspend +EXPORT_SYMBOL vmlinux 0xf749534a gen_pool_free +EXPORT_SYMBOL vmlinux 0xf778e05d fb_set_var +EXPORT_SYMBOL vmlinux 0xf784d337 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7979dff proc_dostring +EXPORT_SYMBOL vmlinux 0xf79cf7d7 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0xf7b4b4f1 seq_path +EXPORT_SYMBOL vmlinux 0xf7c6db95 d_find_alias +EXPORT_SYMBOL vmlinux 0xf7e9716d iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0xf810bc55 write_inode_now +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf8232b03 set_blocksize +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf85547b9 sock_map_fd +EXPORT_SYMBOL vmlinux 0xf857333a skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0xf868ca9c dm_put_device +EXPORT_SYMBOL vmlinux 0xf874fa61 jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0xf876683c dev_driver_string +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88360af inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf89843f9 schedule_work +EXPORT_SYMBOL vmlinux 0xf8985592 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xf8a108d1 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8ba23e8 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0xf8bbdc5c kmem_cache_create +EXPORT_SYMBOL vmlinux 0xf8c6fc4e inet6_getname +EXPORT_SYMBOL vmlinux 0xf8cb6e0d pci_enable_msix +EXPORT_SYMBOL vmlinux 0xf8ee3e17 scsi_print_sense +EXPORT_SYMBOL vmlinux 0xf9203217 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xf923054b pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xf943f0de seq_escape +EXPORT_SYMBOL vmlinux 0xf9512711 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xf963871f inet_select_addr +EXPORT_SYMBOL vmlinux 0xf971bd6d netdev_set_master +EXPORT_SYMBOL vmlinux 0xf97f1f63 dm_table_event +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9a99db4 vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0xf9d1223f tcp_sync_mss +EXPORT_SYMBOL vmlinux 0xfa022dc6 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0xfa02dc9c tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa32d61e mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0xfa65425b pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xfa7a5c43 tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0xfa7d4bb0 dm_table_get +EXPORT_SYMBOL vmlinux 0xfa842fdc down_write +EXPORT_SYMBOL vmlinux 0xfaa2331f journal_dirty_data +EXPORT_SYMBOL vmlinux 0xfaae9c9d kobject_get +EXPORT_SYMBOL vmlinux 0xfab0b2a3 mdiobus_free +EXPORT_SYMBOL vmlinux 0xfae7c24b invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb3566e8 cdrom_media_changed +EXPORT_SYMBOL vmlinux 0xfb480350 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0xfb493c1c pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xfb5cbd91 datagram_poll +EXPORT_SYMBOL vmlinux 0xfb68002d vfs_symlink +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb6bdbae inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xfb74167f inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfba39acb generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc1b1aeb jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0xfc2762bb netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc9cff26 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfcfe2304 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xfd1c92a8 per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0xfd82759b generic_setxattr +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb13ff3 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfdc8d28f unregister_con_driver +EXPORT_SYMBOL vmlinux 0xfdd734f3 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0xfddc5b13 __alloc_skb +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfde87705 inet_stream_connect +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe047ce6 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xfe09013f blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xfe0f5e62 request_key +EXPORT_SYMBOL vmlinux 0xfe392bcd generic_segment_checks +EXPORT_SYMBOL vmlinux 0xfe3e6c22 journal_get_create_access +EXPORT_SYMBOL vmlinux 0xfe5be5bc end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe65841b posix_acl_permission +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfe92c28a jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xfeaf7781 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0xfeb63f8f netpoll_cleanup +EXPORT_SYMBOL vmlinux 0xfebd6559 phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0xfebf53a2 vfs_mknod +EXPORT_SYMBOL vmlinux 0xfec26f5f inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xfec347fb xfrm_init_state +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfec848d6 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0xfed339ba __nla_put +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfeebd2ad redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0xfef0c2f5 sk_free +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1da7d7 jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff4bbf44 simple_pin_fs +EXPORT_SYMBOL vmlinux 0xff5d819c linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff74c433 jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0xff7559e4 ioport_resource +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa7a83f simple_lookup +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffc620db phy_start_aneg +EXPORT_SYMBOL vmlinux 0xffcdd28a jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0xffcf2f77 acpi_root_dir +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffd6affa genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0xffe630fb ip_route_me_harder +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0133148d kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0839e704 kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x083bbe3b kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x095afc83 kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0a0e20a8 kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0bd8d682 kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0c1ab58e kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0deeb3ac kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x18e2e5c1 gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27fef950 kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x280d9b96 kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x34337730 kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x352fa74c kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3afefa4b kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x42813812 fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5518abc2 emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5729313c kvm_vcpu_cache +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5a35d832 gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5c2672f6 kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x63cd47c8 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x641c9e46 kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x67fd926d emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x688da311 kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x69f0bef9 kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6dde419c kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6ffa8f3f kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7821d506 kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7f6c2d92 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x83902554 kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x899be1fc kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x90893149 kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x91693d45 kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x99937d4d kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9cd81aed kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa0141585 kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa18e7092 kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa236a5ec kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa3778434 kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa7c7937f kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa7d65617 kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaa2b5a07 __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaafc48d3 kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xad952420 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb19bead3 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb53bf244 kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb76788b7 kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb9cb3d28 kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbcdf566e kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd86163a kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc10c71ed kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc2ef33d1 load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc3d5b17f kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcc6540c0 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xce521b48 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd745c627 kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdba0b5b3 kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdc5576d2 kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdd6446cb kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdef3323e kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdf90bcea kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe4ad2d9c kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe7688100 kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe9cd01f8 kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf3e54b1d kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf54ea8e1 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf68d2262 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfbe6b3f4 kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfe24b205 kvm_get_msr_common +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0xe30299c5 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x0b324270 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x1edf2050 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x54e1d644 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6cba723c __async_tx_find_channel +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x71b34850 dma_wait_for_async_tx +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x8c21e99c async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xfc823483 async_tx_run_dependencies +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x5d187c8b async_xor +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xe9b931ec async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xb296502d twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x01521c1d tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x0f53e82f tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1b4ffedc tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1f44f9eb tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x221a341c tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x25a26343 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x28cb941d tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x2e58e1da tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x45fcd352 tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x4ac1b9aa tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x645fb111 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x64952ed6 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x65369496 tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x6a7ef9d6 tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x6b817cc9 tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x6bc82d96 tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x70376287 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7ff16e43 tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x8150de28 tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9685a546 tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa635a89f tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa638b9e5 tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xafaa8f43 tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x4c74f794 tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xd9d89bf4 tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/dca/dca 0x28f12408 dca3_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x2e471f01 dca_register_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x31a2c8df dca_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x8006c614 dca_unregister_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x9c555a61 unregister_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xb575212e dca_remove_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0xc6989265 free_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xd8d79dbe register_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xe1528c60 alloc_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xf5f54a23 dca_add_requester +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x033d6be9 edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0d1f088f edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4cd46c22 edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5a145d6a edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x64c98c40 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x696deff3 edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8098b7f8 edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x853d58f7 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8c78199c edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8dd14f13 edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8e392436 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x9688e1b2 edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x9f208fca edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa2887eb6 edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb9952ab7 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd233c7da edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd349c1f3 edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd5687ea1 edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xdafdc70e edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf0cbf304 edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf22be988 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf6d117be edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf92c3027 edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf956ecbf edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x21b55ddb hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x9282a98f usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xfb685c9f usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0x822b7b43 nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xa0d9bb0c hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xc22bb034 hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/infiniband/hw/ipath/ib_ipath 0x1514b2b2 ipath_debug +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0xee15c201 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x34b737f7 wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x52833b6b wm9713_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x69a816b9 wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x839726af wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x9e293bf5 wm9712_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xa14cda92 wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xb78fa1b8 wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xc457e356 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xd9eb0541 wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xdaa7e144 wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xed200a03 wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xf3d2ffcd wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x0bb7789a gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x1f24a0cd gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x24900f6c gigaset_stop +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2c0979ce gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x3aacf24b gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x3b59c350 gigaset_add_event +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x50440084 gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x60dda9f0 gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x6fd87eee gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x70438266 gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x8b3fe55d gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9e462954 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa4c2f504 gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa986e705 gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa9b2868d gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xaeea5616 gigaset_initcs +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x0f5a72c9 led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x73413396 led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbac80395 led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbdb0d224 led_classdev_register +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2816876a ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x703953c7 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfba9ac56 ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x085a6a4b saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x1587d4d5 saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x1c61dd63 saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x3115a7d4 saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x40a98dea saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x89d7a23c saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xad70ec0f saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xd7f90c7d saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xed9ededc saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xf8a245a0 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x20e87a68 saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x42cc7b8b saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x4ada37dc saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x82a02834 saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xbfff4758 saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xd81e063c saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xf3d11f51 saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0xac915863 microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x227da997 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0x97ac724a tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x14dbda74 tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x16477bc8 tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x72f055e5 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0xd60b9b0a tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x5287a72b tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0xcfc50be6 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x29560f00 tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x7af2dc49 tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0xa05f58cb simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x60dcbd28 ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x69298f1f ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x98ec76a9 ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xa805ce96 ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xb5549a85 ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xc7003384 ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xcc06eef5 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0xaa40a8c2 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0x606766ad cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x2007947c em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x259d8132 em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x28e37bb1 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x73ad47e0 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x1bc5ffd3 saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x27a462d2 saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x4ee17ba2 saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x68592aaf saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xac4f98c4 saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xd056a3b4 saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x33a87b62 v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x72aebfcf v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x7bbb11c7 v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x85b8615f v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x028ded1e videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x08070e43 videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x15aac856 videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x2b1d2878 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3c16f657 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x41679d22 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x5392b23f __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x56569a22 videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x64f1fb59 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x682c60cd videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x6ef2b478 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x725f1d06 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x75a65ea5 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x7871094a videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa20e7a93 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xaa18c639 videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xab0bd49d videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb51d58a8 videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb9f6b2a0 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd8597a36 videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdcf88226 videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe064cf39 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe292d283 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xec56e5e4 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf9bf1bc8 videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x820b679e videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x8ce3c2c4 videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xdabb307c videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x070921de videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x1e50017d videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x2679493b videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x41099974 videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x4643d653 videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x6e939ac9 videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x82d920ba videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x933dfb43 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa38faed2 videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa65e0da7 videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xaf92083c videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xb9dd20d2 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xe728301d videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xedf0b2e2 videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x43a07b69 videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x6ef909b3 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xf625a375 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x1fc93f38 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x427f9239 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x7449fa91 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8bfd28aa i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8fd3ef7d i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xa408630a i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xdecd4ca1 i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xf60f392d i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x35f6367c sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x59192986 sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x8ae6a23c sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xb9df9876 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xba066096 sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x07e11eed wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x095bcc29 wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x15ae2a89 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x187c079f wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x21fe55ff wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x2f7facc0 wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x878ede44 wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xa56cc813 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xabbf99ba wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xaca681a9 wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xaf11c285 wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xbb0a160d wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xdb0e7dda wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xefa37765 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xf89b2ef7 wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x1b640edc wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x2d23a5fb wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x32e7eb2e wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0xa03eb223 wm8400_block_read +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x0777a7bb enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x38a18ea8 enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x8978690d enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x90f9a7df enclosure_component_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x98210099 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd369abf2 enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdd30a8a6 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x2293c8e0 gru_get_next_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x5927a880 gru_send_message_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x7e83f3fc gru_free_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x81b3b8e3 gru_create_message_queue +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x9c7283a1 gru_copy_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x345c9217 xpc_disconnect +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x39046c7a xpc_clear_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x43a01eea xpc_registrations +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x6285dfe8 xp_cpu_to_nasid +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x64ba5017 xp_pa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x76e36d39 xp_region_size +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9823adb0 xpc_set_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9acd8cf8 xpc_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xba3694f3 xp_remote_memcpy +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xead4f7fe xp_max_npartitions +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xf3b47f67 xp_partition_id +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xfe709b6c xpc_connect +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x268152ce sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x74c89318 sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x88e96dbe sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x89de8482 sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xa01efc11 sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xac91e58b sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x6cd547f0 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x9e98fcad cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xf5913e7c cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0xb93302ba cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0xc4e0f044 cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xa6bed1c5 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xc5f4dcc6 cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xccfbe182 cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0x2368b5ea DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0x704103a1 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0x7209b2a0 DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x105ab83c get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x1cfb41a2 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3d556e8e mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x40363953 del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x406d1f31 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x436392b8 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x47697e41 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x6336be3b add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x6fdd50c0 kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x7d4b0486 parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x868fd4bd unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x8c0eecb2 default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xa403b0d5 put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xade33c5f get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xea902073 register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x228ceea6 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x4319183a del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x7047b246 register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xe0d5d1e0 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x30481940 nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x64f14b5c nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x760bd66f nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x7f38406b nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xc656ef51 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x4ca59a01 onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x959013f9 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x0a9d9d2a ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x547e8265 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x593a6015 ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x5dbd3ad7 ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x87cb0886 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x8cb07575 ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xd23e3773 ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xdbc3f62d ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf0bca593 ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf10e443f ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf802676f ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0c34e52e mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d1ffc23 mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d61c3a2 mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d84b31d mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0fc6643d mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1dadc924 mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2376c32b mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x265975b8 mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2c3f4f18 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x32f97ac5 mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x33e15ee5 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x39b08a0d mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e01c338 mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e9f0f69 mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x41ae37a7 mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5179ceb1 mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x530598b6 mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x547a5a0d mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5492704c mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x57081571 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x59198627 mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5b40ac08 mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x65e2573f mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6b3a6d90 mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6c288f36 mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6c3c4817 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6dfc6f95 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7176a3d3 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x76e49be9 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x781305fe mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x78b636f1 mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x853bc27f mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x91877bd4 mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x95424208 mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9833505d mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9cd1ec57 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa56f3812 mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa9bfc610 mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xabd9402b mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbd11a45f mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbf96a560 mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc966dbe6 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcb42adf5 mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xccb2c3a5 __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe3cf82d0 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea210cd4 mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea2224e0 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xece2073c mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf33437a8 mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf5487691 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf8a90d04 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf9b4e7ca mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xff3487ea mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x06f79aef usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x9e3c0e3c usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x20ee54b1 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x3a48fbc0 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x5de4ff14 rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xb842eb2d rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xdd4d421c rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xe38c0a55 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x2afed2a3 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x48f44dcf usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6377c73c usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x729db97c usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x80dfdcc1 usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa0c044df usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa4b6e4a1 usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa8f88659 usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xaee17b6a usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb397762f usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb60ee515 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb9169889 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe6c70c3f usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xeadf35cd usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xfeb73f37 usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x16168fe6 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x4aef9f2e lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5c1a0adc lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x715db28b lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x82cbe565 lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x9ec44f11 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xadda9c81 lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xb9f1e849 lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xccabc313 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xcd0f8514 __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd5707398 lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe43fc393 lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xeab3b096 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xfc34eddd lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xff4c4c42 lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x0135aa28 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x292a3ec2 lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x46587c04 lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x5b8417eb __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x8b90f618 lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xb8034ebe lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xb89ea397 lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xbe0392d8 lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x1484ee91 if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x57de90a4 if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x33afb0dd p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x50c0fb80 p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x61dfb005 p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xc9090042 p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xd3869b07 p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x12f276db rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1c045598 rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x21e82e8c rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x286545f1 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x30f25231 rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x37a40d6b rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3853238c rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3d5f0ae5 rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3f0b7aef rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x42aa7c1c rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4eff162f rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x700eccfd rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x724dff87 rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x74606e8f rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa79b2b97 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xb9aacd40 rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd0fe9a12 rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe4f4f6c3 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe6211b32 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xec9f8dfe rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf5d6238c rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf81dea51 rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xfe7d469e rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0a9dc0b0 rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x2f602cef rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x5e75ce86 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x66f9e36e rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x68d1bf24 rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xf339f56b rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xfb8735eb rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xfef5761a rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x0695fbda rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x08ce63d1 rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x15d2af25 rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x29973098 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x2f7db660 rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x7361ac6f rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x82dfe123 rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x87399741 rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa23cf11b rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa95688c7 rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xaea5776d rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xb69a9ba4 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xdb8e6128 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xdbb969a5 rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xf6f44a75 rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x185b6e1c acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0xc9de8ecb acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x31b92204 wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x52706573 wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x75c8a0eb wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xa298f954 wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xec24d0c6 wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0x4c7d86b6 wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x1d26ee5c iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x34e327af iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x35c7986d __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3b75783f iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x46c388d8 iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x4aa9ee95 iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x57519ea2 iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x58b43ce1 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5b5636d1 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5ca14e73 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5cca05a8 iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6a47876b iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7075b4e3 iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x738af53e iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7894eb07 iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7b070b3e iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x83dac8b8 iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x84298257 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x858eeb0a iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x87ef59fd iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x97d513ab __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9bf53f34 iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xac4eb565 iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb1c3c45e iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb7ebfdf1 iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb94263af iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb9c80053 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xba5face0 iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xba67f71c iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbd374bf0 iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc259162e iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe46aa1a3 iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xeb40fa3e iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf4b458d3 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf8540630 iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x0b8bf836 sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x133853c7 sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2dbb3846 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2e2b1858 sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x37921014 sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3c5cdb0e sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3e3e7f37 sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4be56004 sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4c9a0672 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4d98d2ea sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x549870a7 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x620984da sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x6d9a6fb4 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x78107936 __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x7cb41202 sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x80a9b77e sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x80cdcb1f sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x887011f6 sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x91ab44f3 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9e7a595d sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xb3eee442 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe1d28daf sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xfae6209c sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x63cbf8ff srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x6fc79cd3 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x7ebd7ecd srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xaa71b248 srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xc2e2d795 srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xef4c7cab srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x0d3aaf60 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x2a180412 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x2a9ddce3 scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x3b62d8e0 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x7582c268 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x90ec9ca4 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x9b8cb09c scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xb82af24a scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xe4551492 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0d2f06ca iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x20951f5f iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x25e6e56c iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2942ba3c iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x5fb27155 iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x689779ef iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x68f61758 iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x7d3fca42 iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x854ecff2 iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x94be649e iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa5fe1422 iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc0cfa10b iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc7db9bac iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xce3ca31d iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd3d9d020 iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xe3b58ace iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf33b106f iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf78655d5 iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf866cd9c iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf9aea7b7 iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfa2a12bf iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x27c3f20f srp_remove_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x67023903 srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x68a3af38 srp_rport_add +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x9e340c70 srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xe7770a14 srp_attach_transport +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x2dd5893d spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x50c9b431 spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x79abc0cc spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x81c0180e spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xbd0935ea spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xe670adac spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/uio/uio 0x13186007 uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0x44171087 __uio_register_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0x861aafcc uio_event_notify +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x36280474 usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x92743959 usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x3d5aeecc usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x47225c28 usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x619eb03a usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x629386ed usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x90e68dc1 usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x955a7869 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xba6d5a26 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xcda969ad usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xe60c0775 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x11443006 phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x122f15ac wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x4f27347b wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xb72719fa wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xbd067c35 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xd4d61ef8 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xe834bc82 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x09b00a96 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x09f01407 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0fb0d58b wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x31df11a4 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3fc450be wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x67e277a4 wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x6ea0c1d3 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x806814c4 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x8fea766c wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x90f6658b wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x983af7a6 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x999d7ac1 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa610d1bc wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa96df458 wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xc00d185c wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcc562985 wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xe717bb54 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x89353975 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xb5d3791c i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xbe1e6d10 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x184ae104 uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x4fea41b0 uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x629af4ac uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x6b78ce6b uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x7e37e9d8 uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xa6074e56 uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xde1a063c uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xfdf789d7 uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x44501c9e umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x55212a1f umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9c38507d umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9cce3f63 umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xaeadc5b7 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xbae3dba9 umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xf1ac24d2 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xfe831d27 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0ccb5b3a uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1d5cc8d3 uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x22a6d823 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x262dbf90 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2ca10493 uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3ad6dfa8 uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x45f41cb0 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x487aa8e0 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x499cbe01 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4a65b2ee uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4c1c4dea uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x54a30a9a uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5a1a5f78 uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6625c91d dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6b9377c5 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6c520475 uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6ef9c4c4 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7367dfcc uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x80e5fccc uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85b780e3 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85de05ea uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x879baead uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8cb42db6 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8e2d74dc uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8fde6d5a uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9024117b uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9058988e uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9a970122 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa4f8bc8c uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa9d1f3c4 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaaf6cdc5 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaed6ccee uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb7c8c825 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbf6a1b3d uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc348d995 uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdac98b7c uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe6077cba uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xeb4cab9a uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xefddc9f6 uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf7ca313a uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfd2c2f1e uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/whci 0xf52983e0 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x138cb4c9 wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1774f10a wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x23c22d99 wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x24c096ad wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x257a57cc wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x29321f9d wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3add81e1 wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3b64408e wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3e7c2cf7 wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4386cf35 wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x50725233 wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x51ad4df5 wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6722790d wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x709d65bd wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x72eb28c8 wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7568b56a wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7b6a5f8e wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7dc0c966 wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x8b8cb893 wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x94b585af wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9909935f wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9abccd13 wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9d208efd wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xbdc0ddef wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd6a17b5e wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd8450ff3 wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xdbe6ab27 wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe7af5f47 wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf5d5075e wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf8402c05 wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf8526cde wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xfc7f743f wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x189b3630 ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x21cf84ab ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x5e908620 ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xce31f0fd ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe621f381 ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe9e5f1bf ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xfbc8b3ae ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0x3adb8a7a fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xd0c3bc68 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xd8d2bc77 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0xb9430f3f sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0xf2e04965 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1bf1bae0 virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x36c04a91 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x7176ad10 unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x74c0608e register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xfcdd6498 unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x4f924c62 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x67d130a2 vring_transport_features +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x7274b59b vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/w1/wire 0x0472e1dc w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x3c93f792 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5e2d88f7 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x90a52159 w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x9f1117d5 w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xdba68dd7 w1_reset_select_slave +EXPORT_SYMBOL_GPL drivers/w1/wire 0xddb5bcb3 w1_next_pullup +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x009bc27c dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x5a87e727 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x69113ce4 dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x17cca875 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xdd0dc0f2 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x05b6f71d fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x26812cb5 fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x2fcb4aae fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x570053a4 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0x5791d305 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x6dfc6082 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x7015d2f8 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x73e960a6 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x7b71ed4b fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x7d5d79fe fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x92e003b1 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0xa2157453 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xc34010e3 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0xc3401568 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0xcac6e9f7 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0xed4dbbef fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0xf913f87b fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0xf9526ace fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x58a66091 gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x9f71f6c2 gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x01a2527e nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x48ad1642 nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x7ca542b7 nlmclnt_done +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xadc1fb94 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x47717e97 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x521e0726 o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x68430423 o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x71cd3833 o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x81a17396 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xc639b96c o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xe620dac6 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xe91ec6dc o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xeebf147d o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf56c2017 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x082b1776 dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x1c7e3428 dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x62cd9de9 dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xa436114a dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfa3ec9ea dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x2d4a8243 ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x9ed86d1c ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xe5930098 ocfs2_plock +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x2e1d43cf lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0x2a1538ca lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x328be6ba garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0x8538ab11 garp_init_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x8bd9ecf3 garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0xa876d91f garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0xdc584bd5 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0xe10f5703 garp_request_leave +EXPORT_SYMBOL_GPL net/802/stp 0x64d7d18c stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0x68404fa6 stp_proto_register +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/ax25/ax25 0xd50d4509 ax25_register_pid +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x1c37b8e7 tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x3539011c tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x7712c750 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8dffdb8b tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xbc57b83c tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xec262634 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/dccp 0x00e407da dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0x08f75ce9 dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x10604202 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0x15829cda dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x164eb3b4 dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x21a5a964 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x23a08b77 dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x24af1201 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x258e1cd5 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x29a9d61d dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2b42c986 ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2fd38ce3 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0x30009d95 dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x333b0ea3 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x364fa7db dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3a35ec98 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3af61004 dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x487d9086 dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x489894b2 dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4d8db45a ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5fd9fd42 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0x76de2339 ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x81c76c7a compat_dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x849b89ed dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8ae29230 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8d74230c dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x91693d0c dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0x91a009cc dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x98a17352 dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9df933c4 dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa9c98065 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb328f65c dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbcd811a4 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc76584af dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdb18dbf1 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdbfeb328 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdd798a49 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe3eccdd1 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe411230c dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe508f80b dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0xea83645f inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0xec356935 dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0xed835ce6 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf50ca884 compat_dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf8fdfb5a dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfe4952c5 dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x2b8bd5a9 dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x3a41ef9a dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x3cc69885 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x4cdd6ded dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x9010bf49 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xd1cdf38c dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x92230f26 ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x2c57af41 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07be8c33 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x65000330 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x6645954b nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xc83d57ae nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xf97cb62c nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x8f7b44a8 tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x931a8507 tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xb07d010e tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xd346a3e9 tcp_vegas_init +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xe3ffa1cc tcp_vegas_state +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x93a8db03 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0xdfc2159e ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x005d8343 nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0219f067 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0272305a nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0522d7c0 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0ca491ed __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x124612c4 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x16689d42 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x194bd879 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x23803a2b nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x326be1c1 nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38e28bb0 nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3e57620c nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5395a9e9 nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5a871abe nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x658bba8a __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x700d1765 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7a4db985 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7f8891d2 nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x834ea1fd print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x85bfffe5 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x88209636 nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9928a806 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x996446b7 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xab522435 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xab957273 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb2562c68 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb4a8138d nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb8164512 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbbce2128 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbe46ddbd nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbf220526 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbfd9b730 nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc1be4166 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc23d9be9 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xccf1abac nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcd1f8d68 nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xda6a93b1 nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe0fe6d4e __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe1a811d6 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe3222e54 nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xee6e4a14 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf1d19fe1 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf26d7271 nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf2e4de29 nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x5f36bce6 nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x2bef4034 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x2e11cd47 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x42fa7b19 set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x510bd464 set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x59241825 set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x5d3785ff nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x67e4504a nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x71945c47 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xc69d54b5 nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xeda8cdd1 nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0xb73f26cc nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x0e2ef26d nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x1d2680c9 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x542d50cb nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xd5e569a2 nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x0f98a608 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3d809024 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x9c90d923 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xd848b563 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xd911079f nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8291790 nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0x7a86395b nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x02cfe272 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x0825679f nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x9fe27888 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xc89ba9c4 nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xe0713618 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xf18c1438 nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x12103513 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x161d1417 xt_compat_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x1e6965af xt_compat_target_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x23036aa2 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x2afce3e2 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x3d57081d xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x3dc83245 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x4036f87d xt_compat_match_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5f82f1f7 xt_compat_flush_offsets +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x684694c5 xt_compat_add_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f9aa2fb xt_compat_calc_jump +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x706b5638 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9003c4dc xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x93beeab7 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x95893d42 xt_compat_match_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9b5d5ab2 xt_compat_target_to_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xa7b19a1f xt_compat_target_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xb74b0739 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xc77e9cb8 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe0b4971b xt_compat_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe2206cd2 xt_compat_match_to_user +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x634197a8 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xff9ab42a rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0e38d6ec xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0e516e3a xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x10b97469 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x13134d5d svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1b13c3fe svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1ecb4162 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1f1b3035 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x20441125 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2282b102 xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x28ebfb80 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x29836513 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aae2d89 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2eec107a xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32334f0e rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32501d49 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32a74bde rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x39377dff rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x399bfcb8 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3a111940 rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3f1ef307 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3fa78873 rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3fe4ac92 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3ffd6e2a rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x42eb258d rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x47f1e1bf rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4aa6891a svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4bc1cb6c rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4d0c78b6 xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4fc0627b xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5cf51603 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5d9755d0 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5e327fd1 svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5fed17c2 svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x606cf97b xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6261de53 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x671e0d83 xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x68b98d5d rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x69d6a5bd rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6b8f4304 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c85411c svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6ea741b0 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x70c8a73d svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x76740690 rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7b6e2469 rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7ebb692b rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x848bd467 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8554b613 svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x85a3ddf4 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8824dc59 rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c460b7c rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x913c0291 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9381edd9 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9d1a6a1e xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9d638591 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa5aa0383 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa92d33d2 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xac872bc3 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xae9a8aa9 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb0786759 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb8c0f53d rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb969b2eb rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc07f2d1c rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xca78f4f1 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb64426e rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd912d96a rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdbe5ecba rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe304bbd5 rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe32d348f rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe4fb8394 rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeaa0ba7e svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xed326360 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfbba2c38 xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfe396e6e rpc_put_task +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x2a865800 ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x71056cf1 ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x89e6a070 ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xd1c0110f ipcomp_destroy +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x28e16093 ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x28f8ccc2 soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x685f5e11 soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0xb9f056bc ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x7ba292d8 cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0xf1019ff4 soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x395b9333 soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x9e41b704 ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x21ac57c3 soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x398c32cf tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x07fb6302 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x482d198f aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x1983596b aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x5c1b1d11 aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x9c8f5f3c aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xdb087927 aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xdb40f338 soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x66d44157 soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xa8ca9bc0 uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x010bd9d2 soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0xd3cb5bfd wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x0edae25d soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x6902aecb wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xb19df476 soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xcd2d9e0c wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0x65a17893 wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xac0bb985 soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x8726ea46 soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0xde5b6930 wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x22134506 wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x4a1f0c5d soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x61325f9e soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0xa48737a8 wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x2ce8a82d wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x564b2b99 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x45ce37d2 soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0xb78b00d5 wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0338c866 dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x077428ce snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0bda36b9 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0c5dc0ff snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x138da970 snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x18c99a08 snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1bd53a48 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x28573d65 snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3710c0c5 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3caff903 snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x40175b4e snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x49af5acc snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4e7c7c2f snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4fb6ba0a snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x52da0264 snd_soc_test_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x623d1cb8 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6850a6bd snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x693efbfe snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6e0e2cd6 snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x73eb28e4 snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x75b65410 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x776b9056 snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7913693c snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x84762a37 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8a8037d7 snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x902bebeb snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x92437e48 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x95ffbc2e snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9e0666b5 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa4045334 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa41584be snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa7d4acab snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa922d6c4 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xac4d1786 snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb77dd0a8 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc1c4901b snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc410c17a snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xce0714b0 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd0ac1b5c snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd40638b1 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xdf1e8882 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xee1dcad6 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf38b3755 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf3e5b28a snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf680c1ce snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf87e9903 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfef58d9e snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x0d93d0e1 tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x2c383ca4 tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x54064cb9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x60d233a6 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xbe77d1fe tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x00029e69 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x00620e10 sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00902a78 cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0x00b8ecf8 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x00c6cc8f kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x016228b1 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x0164a9ef regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x019d6aff usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01e06afe device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x01fada5d tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x020a0f8a devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x0270bce3 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x028e6f97 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x02a9ac14 user_update +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x030a1563 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x03317f4b pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x03377cec scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0x033fc019 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x038ea63d __xenbus_register_frontend +EXPORT_SYMBOL_GPL vmlinux 0x03956ae7 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x03bb04ac rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x03e7c75d devres_find +EXPORT_SYMBOL_GPL vmlinux 0x03fe2cca flush_work +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x0447d159 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x047d9031 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x04c3f2c1 gnttab_empty_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x04ddf3b0 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x04e271cb inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x04e628cd leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x04ea8706 __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0x04f0af4f usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x04f7df9a uv_teardown_irq +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x053716ee rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x054f566a xenbus_alloc_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x059a61a2 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x064aaabc usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x065ad2bb drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x06eebe74 crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0x06f8aa16 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07198ccb ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x0776238f __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x0786c4ff inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x079beaf1 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x07a92a87 put_device +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07cc66c9 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x07d43a2a fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0x07e3878b ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x07ff4aea xenbus_scanf +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09536365 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x095ca626 xenbus_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x098bd839 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x09901f4a do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x09b5fba5 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x0a44c61d sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0af76eed tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x0b09aec0 cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0x0b0f8665 spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0x0b4394d1 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x0b6fe268 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c40a966 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0c597897 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x0ca3c4fc driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0cb542de ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x0cfa0916 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x0cfb8983 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x0d35ddd7 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0d9a8022 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0x0d9e382c usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0x0daced87 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x0dbf8659 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0e21b770 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x0e29bf3c driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x0ebf0827 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0ec210b8 xen_start_info +EXPORT_SYMBOL_GPL vmlinux 0x0f2961f2 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x0f59164b fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x0f6ff757 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x0fe2d570 xenbus_directory +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x10293ee3 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x1076769f vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x1091007c blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x111cb472 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11e36ba4 scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x12350a68 __class_register +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x128afe11 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x12beb949 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0x12c9faf4 ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x12d861b2 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0x12e285ec is_uv_system +EXPORT_SYMBOL_GPL vmlinux 0x12e50f30 sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0x130238b3 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x134d12e0 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14cdda22 hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x14dda409 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1595ec1d ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x15966052 xenbus_watch_path +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15a61e12 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15e5f816 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0x160e994e audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x16735dff fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x16a5b4c8 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x1703de9d dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0x17140902 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1760ac92 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x1781c704 mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1799fa49 agp_remove_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1830ac53 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x183a4077 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x1851259a do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x187afd58 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x1881ee00 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0x1885fbd1 sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x18be231c ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x18ce5206 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x18f83fab gnttab_grant_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0x19184d9c rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x193dcbb2 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19a3ce45 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x19bcecd1 usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x19d01a22 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x1a06c571 ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0x1a10607f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x1a83ecfb ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad12d5f devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1af4a8c8 ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1c0413b7 crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c911fa0 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x1c9769ed ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1cb1b6ef inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x1ce06916 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1ce61a59 relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0x1ce9f482 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x1cf2e70c ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1d0defe7 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x1d735315 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x1d897bde ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0x1d8db736 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0x1da0e893 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1df485d9 xenbus_map_ring_valloc +EXPORT_SYMBOL_GPL vmlinux 0x1e3275f7 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x1e426896 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x1e5a5f22 sn_partition_id +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e8e02bd unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x1eabb429 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ed4ac67 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x1f57e18e pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fa14371 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x20079332 aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x2036c46f blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x206fc621 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x2082cf13 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x20ad3c92 xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20eace40 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x21032dd8 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x2112165f sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x214e416a mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x2171b7a5 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x21907a46 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x21aa5385 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x2240d211 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x224479ff dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x226b2210 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x227f3606 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22ac5c07 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x22cb3835 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x22e3aab3 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x22e4e191 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x231706d0 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x233c8541 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x2358fb8d crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x239fb7bd kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x23b72f0d dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x23fd84d6 usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0x2403e5ad ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x2462915e __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x2469ca66 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x24a23c3b usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x24c7698a xenbus_write +EXPORT_SYMBOL_GPL vmlinux 0x24e29e3c usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x24e37267 fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x24e8db91 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x24fa14f4 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x2531c51d sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x2545c170 unregister_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x255556a6 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x255692d0 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x258a6b45 da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0x259a6d7e hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x25ce8ff8 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x25e7f770 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x25eb627a scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0x2624902c ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0x263ad179 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x266155fb regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x2665b4b3 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26da2c43 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x26dd3f6f regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x27b8db75 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x28471e55 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x28503e2e platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x2894bb86 usb_root_hub_lost_power +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e0fb5b relay_open +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28f38f18 gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0x292fd278 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x2954ec67 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x2a12e51a fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2a1a8626 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x2a4e8cbc dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2aa5c1c4 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x2afe6f72 rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x2b24e4a0 uv_blade_info +EXPORT_SYMBOL_GPL vmlinux 0x2b30f50d rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2b79a31c pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bb57a0f usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x2be92318 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2bf20d1a agp_add_bridge +EXPORT_SYMBOL_GPL vmlinux 0x2c06e1a4 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c467a60 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0x2c678f07 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x2c6e7553 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x2ccdd2b5 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x2d165ecd copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x2d2056e9 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x2d323fc6 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x2d53b1fd tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d6afcfd blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2de9f755 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x2df188c3 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x2dfd4290 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x2e20b575 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x2e2995cc led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x2e453393 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x2ec3b51d hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2ec92012 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x2ee087e8 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x2efc956d blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x2f3a1cf1 pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f887b8a ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0x2f8bb891 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x2f8e3d2c usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x2fcb8489 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x3011e931 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x30196eb4 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0x3080fb39 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x30bb317d simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x3122f540 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x3160efaf device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x31797610 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x31e4f224 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x32096d79 crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x320cd591 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x3227d4cb class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x325e677c gnttab_grant_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x328b2a12 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x329adf4d relay_close +EXPORT_SYMBOL_GPL vmlinux 0x330e075d led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x3320402e tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x3348c521 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x34105c01 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x34241f7f blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x34337d05 cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x34f8096d relay_flush +EXPORT_SYMBOL_GPL vmlinux 0x3569939c usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x359e8c24 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0x35ba78ac user_match +EXPORT_SYMBOL_GPL vmlinux 0x35cbb359 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x35d402b1 simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x365c2c94 spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x3669e185 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x36969fdb devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x36b64c9a dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0x36fb3414 xenbus_dev_fatal +EXPORT_SYMBOL_GPL vmlinux 0x3789a802 scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x37b534f9 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x37bf012a devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x37f21418 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x3814f19b ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x3819bbd5 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x383480b5 hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0x386e8b71 dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x38bb757b single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x391b5056 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x39942348 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x39a438e8 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x39faab89 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x3a311560 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3aff2595 ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x3b17aec1 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x3b1c0782 xenbus_watch_pathfmt +EXPORT_SYMBOL_GPL vmlinux 0x3b93d9b7 ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x3b954dde pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x3be6de9a sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3bf6c3b2 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x3c1ec4ca i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x3c4bf8b6 sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0x3c8e2ebd xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3ccb8337 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cf85bcd inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x3cf9bf4f platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d29867d per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0x3d5f392d acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0x3d7ea99a gnttab_grant_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x3e0d8846 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0x3e0e1237 relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0x3e404bfb rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x3ebdf2c8 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f84d4c9 gnttab_release_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x3fab9be6 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x3fce9bf9 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x3fced94c regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x400162a3 fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x409dcca7 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40fe2898 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x42308f55 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x424acc6d scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x424af8be usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x42b56980 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x42bf4650 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x437bb7c9 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x439b8e0e usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0x43b4bc49 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x43dc6200 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x444a66a1 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x44a38f89 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44b5ba8b platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x44f97ca3 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x4516d33d devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x4572ad38 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x45d14bdf hypercall_page +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x463fd0a9 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46951814 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x46fffe97 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x47583845 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x47932555 xenbus_unmap_ring +EXPORT_SYMBOL_GPL vmlinux 0x4817ac2e bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x484cac0f save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0x484fafc6 usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x486b6ff6 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x49436e3e preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x4982bad3 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49fdab31 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x4a11a4fb bind_virq_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4ace7eb7 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x4b2aa1d4 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x4b31fc73 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x4b762828 start_thread +EXPORT_SYMBOL_GPL vmlinux 0x4be5694f usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x4c074931 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x4c0b763b skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x4c371d7a ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c8d52a8 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x4cc2ab92 preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4cda6860 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0x4d44c06d platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x4dba6719 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x4df99b5a ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0x4e1892ea ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x4e37ea35 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x4e442681 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x4e6f5ed7 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x4eab20da ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x4f8db399 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x4fa0a6c9 sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x5048788c inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x508f7be5 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x50a130be fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x50b319ce cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50da844c usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x5121c2f0 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x51488d34 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x51596651 led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51a4c094 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x51b46321 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x51cb6bbf register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51fc8b26 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x5246d3a3 __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x52859f2f hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x531468f2 crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53a9cf24 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x53c43ba8 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x53c4f99e ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x53dfbf13 cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0x53f4269b blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x542652cf bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5440ae2b class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x547e1497 scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0x54872532 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x54fa9959 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x551c1a57 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0x552bea82 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x552cb3eb regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x55526907 xen_features +EXPORT_SYMBOL_GPL vmlinux 0x5595b08d crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x561c634a wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x5662e8f0 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x56a217f6 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0x56f064db queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x575c5f94 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0x57736ede dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0x5779d445 xenbus_exists +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57d77890 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x580a49e3 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0x585fa898 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x591e216f dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x59594121 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x5974c15f usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0x597d8523 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59cf8cec device_move +EXPORT_SYMBOL_GPL vmlinux 0x5a2b1b67 gnttab_free_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5a3a50bf sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x5a6958c2 usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a8d9932 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x5af03a28 gnttab_claim_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5b1b2997 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5b1c9c4e dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c0525cf fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5c783951 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5cb5a638 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x5cb94ab9 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x5cc852e3 uv_coherency_id +EXPORT_SYMBOL_GPL vmlinux 0x5cd9b5f3 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d366dec gnttab_cancel_free_callback +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5d987421 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x5d9c0967 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e3c6464 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x5e51be23 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x5eb05848 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x5f005583 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f5b628b ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0x5f602dac exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x5f6411e5 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x5f8327b5 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x60341bf2 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x608ae3ef proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60f20463 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x61904363 cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x61aeac91 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x61b13635 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0x62434387 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x62b6814d tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x62f0a5e0 inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0x62fbd617 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x631ab0eb sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63b5a62e ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x64335767 usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x644f3cb1 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x646050af __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x64828aee scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x64b0bd5a tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x64fc53c3 ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x6537f30d fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x655693de usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x65642fe2 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x667a14cc regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x672cf8a5 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x67dccb0f sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x687926bd ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x68818bc6 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x68b455c5 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x698d2ce7 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a0c408d platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x6a22f277 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x6a323371 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x6a4c8d04 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x6a72f0c4 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6af19b0e bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x6b371aaf sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x6b9178b3 xenbus_strstate +EXPORT_SYMBOL_GPL vmlinux 0x6b93bf60 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x6ba6b5b6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x6be62dfd probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x6c0e7dad usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d808c11 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x6d936e69 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x6d938da6 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x6d9f8efc transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x6dc0fba0 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6e0a3f91 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x6e248a62 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x6e3d5a2e ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x6e3f44d6 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x6e58ddf0 gnttab_end_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x6ea72a40 uv_bios_freq_base +EXPORT_SYMBOL_GPL vmlinux 0x6ee34090 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x6eff03a7 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x6f0aa015 dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0x6f1eb09b inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x6f5c3348 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6fbf8658 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x6fe5b7c3 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x6ff679f3 usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70b1944d fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x710b5f0f inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x715e767c da903x_update +EXPORT_SYMBOL_GPL vmlinux 0x7171fd8b __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x7193919f bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72846d8d usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x728a1e7f device_attach +EXPORT_SYMBOL_GPL vmlinux 0x72e852c3 usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x731433ee unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x731dba7a xen_domain_type +EXPORT_SYMBOL_GPL vmlinux 0x7386b9e4 usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x7386f2c7 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73a64601 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73f04c2f input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x743261eb debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x746735da sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x746a0649 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x747b9021 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74cda9ea regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x75141b4d class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x7542e059 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x7553f80d power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x757b31b9 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x75c552c0 gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x762b7132 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x7675d5ca pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x7679a804 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x769e423a blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x76a7a5cf pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x76c31dc7 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x76cd4588 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x76de6e9f ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0x7712771a unbind_from_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x7734fb11 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x774fc39c __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0x77a8e7d9 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x77a939c8 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x77ca03be crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0x77deac3f acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x7812fdd1 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0x7826b77d dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0x78349290 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x7847ce38 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7862db1e sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0x787eb854 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x788b847f pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x78a7d8d6 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x796ef331 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79843bf8 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a6cb59f class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x7ac10ebc uv_node_to_blade +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7af3a31b usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7c6d7605 blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7d06d334 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x7d1cd2a2 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0x7d4527ec inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x7d470559 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x7d607bd5 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x7d688ce2 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x7d99c1a8 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x7da5cdb1 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dbc6935 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7decc727 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x7e092a46 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e49bd00 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e6e488a free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x7eb00b07 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0x7ee2d094 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x7efb9c56 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f21dc8d pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0x7f4a0672 xenbus_unmap_ring_vfree +EXPORT_SYMBOL_GPL vmlinux 0x7f4ad793 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x7fb5c81e sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8009be18 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x807f9c27 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x8099e89e pskb_put +EXPORT_SYMBOL_GPL vmlinux 0x80b527c4 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x8106054d pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x81409d49 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x815efcb3 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x81cbb4e7 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x81ecefef spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0x81fd16fe pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x824bf0c1 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x8276e170 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0x8277488a ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x82cd19f3 register_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x8315abb2 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x831e6780 device_rename +EXPORT_SYMBOL_GPL vmlinux 0x833fea5f sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83ca6417 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x83d96307 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x83e71453 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x83fab8d3 power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x83fda26e ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x84170449 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x8452d272 xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x8452dd8e bus_register +EXPORT_SYMBOL_GPL vmlinux 0x8454dca5 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x84827556 md_new_event +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x84fe3f5a md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0x853cd53e unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d77905 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x8639655d ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x86623fd7 notify_remote_via_irq +EXPORT_SYMBOL_GPL vmlinux 0x867b5ed2 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86a51007 gnttab_end_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x86ac5f33 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x86d4d734 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x86f64feb __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x86f71944 pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x871a9910 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x874aded9 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x87526081 pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x876d29f1 wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x877a53a0 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x87bfb3bb ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x87f2cf3a blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x882134de blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x8849febd register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x888c12b2 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x88af5b99 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0x88f0db24 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x88fde7b1 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0x892b9c8f tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x89414704 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x899ad6a0 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0x89aaf9ba ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x89b712fc sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x89ee2653 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x89f6ffd5 xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ad9be80 xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x8b1aab6a spi_sync +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b9200fd lookup_address +EXPORT_SYMBOL_GPL vmlinux 0x8b97bddc ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x8bbfdf48 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x8c06a108 xenbus_transaction_start +EXPORT_SYMBOL_GPL vmlinux 0x8c30095d pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0x8c38074a unregister_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8d0f74f2 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8d15fee3 da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0x8def058f cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0x8e781471 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x8e7cbaf0 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x8e8d86e8 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8f02e2d7 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x8f49ec3a regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f9eb46d dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x8fb0e979 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x8fc2da97 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8ff3c043 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90ac4102 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x90f786dc usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x9138c654 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x919f34f7 ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x92183295 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x927f4af5 __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x93035e84 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x936ef94d sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x93b0230e usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0x93b32d5b dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93d4d74a __class_create +EXPORT_SYMBOL_GPL vmlinux 0x93f1254b cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x9481713a get_device +EXPORT_SYMBOL_GPL vmlinux 0x9483c81f sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94b5ab68 ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x94bb91b9 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x94f661ed skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x94f78d38 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x951c26ae led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x959e62ae ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x95ddadcf ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x964d5c39 acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x96540da3 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x96757641 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x96b8eebf usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96f1bd3e blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x9724dad4 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x974f99a5 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x97c9ece1 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x97d8375d sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0x97f52e0d d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x9835a15d ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x989327ef blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0x989424f8 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x98a62878 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x98ce553a fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0x98dc1cb8 xenbus_switch_state +EXPORT_SYMBOL_GPL vmlinux 0x99065d5a dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x99ceb25a disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x99dc9bde i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a21b92c regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x9a31f39f dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a3df726 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x9a4d1034 idle_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x9a545456 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0x9ae6e68f __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0x9afac575 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x9afbfad0 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x9b08655a dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0x9b5225b6 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x9b5ac242 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x9b6e594b raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x9b8a1454 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x9b9840bf usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bab96ac crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x9bafbb15 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x9c71db87 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x9c918b90 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x9cae3ded ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cbb776c fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x9d06688b register_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x9d3850e1 gnttab_alloc_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x9de5e149 devres_add +EXPORT_SYMBOL_GPL vmlinux 0x9e1a109e rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x9e30627a sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x9e5f1f98 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9e7d3442 xenbus_resume +EXPORT_SYMBOL_GPL vmlinux 0x9e7f3792 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x9e9662ab user_describe +EXPORT_SYMBOL_GPL vmlinux 0x9eb0125b inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x9ec8e34a page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x9ef123c8 ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x9f14b527 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x9f438b81 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x9f5deba4 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x9f628956 device_add +EXPORT_SYMBOL_GPL vmlinux 0x9faf54e5 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x9fb5d63b sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x9fb6822d cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0x9fbdf859 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x9fc6ed55 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa0040e57 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa02948f9 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xa0523f4b crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa052fac9 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xa0f72bce unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xa126e58b ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0xa14c50e4 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa1a2f865 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0xa2245576 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xa23d4044 blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xa2480258 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0xa2665331 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2c03841 bind_evtchn_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa3008b2d proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0xa3421352 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa353fffc xenbus_rm +EXPORT_SYMBOL_GPL vmlinux 0xa384e9de ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xa39fa209 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xa3c80b59 dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0xa3d8109b hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0xa3e91bd7 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa42ed0c8 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa480e2ed led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0xa4d58669 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xa4ea5c84 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0xa5533946 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xa583d5be blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0xa596f330 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5e14357 dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0xa5f38da7 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0xa5f406d5 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0xa60bc83d sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa6bd68b0 rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xa6d2154e tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0xa6df8c9c regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa6f70ba4 da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa71b5a8a usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0xa71b6e79 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0xa75c9a24 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0xa76ed488 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0xa82bab60 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xa88ca2c2 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa91fab15 sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0xa92c6424 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0xa93df210 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa9843cc0 usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9d3a194 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0xa9df995a tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0xa9e4fd1c sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xaa0435f8 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0xaa0cf39d set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0xaa7bd6dd sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xaa86cfb5 uv_possible_blades +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaabe8903 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaacae138 __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0xaadef866 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xab01acbe gnttab_request_free_callback +EXPORT_SYMBOL_GPL vmlinux 0xab1777fd ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab5addab ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0xab689607 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xabb566fc device_create +EXPORT_SYMBOL_GPL vmlinux 0xac11ee71 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0xac41f592 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xac439840 usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0xac9d742d class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xad096363 xenbus_printf +EXPORT_SYMBOL_GPL vmlinux 0xad1ea67b rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xad3fcdf0 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xad63a24e per_cpu____uv_hub_info +EXPORT_SYMBOL_GPL vmlinux 0xad8f4364 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xadcf69bb crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0xade5f8e0 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae1c6f5f cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xae23e835 relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0xae2812fe debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0xae500d74 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0xaea20e3e blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xaf7112f6 device_register +EXPORT_SYMBOL_GPL vmlinux 0xaf7ecedd ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0xaf803abd pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0xaf8766c9 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xaf87b8c6 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xafc654a1 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xb047f6a0 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0xb0605150 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xb07dfe09 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb17c8ad4 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0xb1833c5e register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1e6ca54 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xb215526b input_class +EXPORT_SYMBOL_GPL vmlinux 0xb247c957 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb284888e crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0xb287a1da ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb3275fd6 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xb38a628f unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xb3ba5eb6 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb3e6fdf6 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0xb4d1eb51 sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xb4da3a51 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0xb4e14553 gnttab_query_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb4fe6005 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb538b352 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb5be7b03 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xb5e0f163 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0xb5eb38c2 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb606c00b tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0xb612444d snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xb6230f1f gnttab_grant_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb698195a posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6b0f9f0 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xb6c7316f hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0xb73d9775 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0xb74c3e63 crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xb79f8787 cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0xb7c2d4b2 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb8252b2b dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0xb8eeffd9 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0xb903674c scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0xb907290d tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0xb99d5837 xenbus_read +EXPORT_SYMBOL_GPL vmlinux 0xb9c3a6a9 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xbabd9f0d tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xbabfe114 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbb290917 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0xbb33082b crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xbb36377a driver_attach +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbbcdd269 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0xbbef7a76 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0xbc215c4a ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0xbc2f8692 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0xbc44a462 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0xbc5cf950 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0xbc7227df inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0xbcb1e855 da903x_read +EXPORT_SYMBOL_GPL vmlinux 0xbce12308 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd25a9e8 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd41529c usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbd7387a6 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xbdc028b8 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbde5e56e transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe214d59 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xbe28ec59 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xbe50b3c9 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xbe73f8af register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xbe76ba15 ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0xbe9b94bd sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0xbeb3dfae transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xbeb6552c pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xbf0606a2 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0xbf0be2f5 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0xbf2d7d79 hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0xbf46212e proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0xbf74eb20 probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0xbfadf2ac crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0xc009d72b blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xc00c8f8d swiotlb_sync_single_range_for_device +EXPORT_SYMBOL_GPL vmlinux 0xc01da9bd inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc0ec11a7 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0xc10fa781 hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0xc15991d8 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc1a86893 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0xc1c60b1b inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xc2083518 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc26351f8 bind_evtchn_to_irq +EXPORT_SYMBOL_GPL vmlinux 0xc28bd7f2 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0xc2f2284e usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0xc2f7292c destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xc2fb2b59 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc388c73c dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3bd7fc1 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0xc3cbe1e5 scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3f11443 usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xc41b487b kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc42f2f94 xenbus_read_driver_state +EXPORT_SYMBOL_GPL vmlinux 0xc42f91e0 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c05569 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4ce6189 idle_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4db6be8 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0xc512626a __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xc5397da6 xenbus_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xc54bd4d7 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xc5a61718 dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0xc5b169ba crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0xc60b9a6c xenbus_free_evtchn +EXPORT_SYMBOL_GPL vmlinux 0xc60fe172 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0xc635ae8b hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6876ba3 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xc6c85b87 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc7727a2a crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0xc77bbc73 cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xc7aaec22 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc83b32f0 uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xc83be3dc cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xc84bcf55 bt_class +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc8ea1705 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc8ea8106 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xc9256184 crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0xc9323108 dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0xc94d8c75 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9a56afa ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0xc9d2b99d driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xc9dcefd9 cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0xc9fb576b tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0xca2bc12f security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0xca33647d inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0xca42a604 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xca81ea9a xenbus_transaction_end +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcae444a5 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0xcb0296f5 usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0xcb02ee42 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0xcb78b726 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xcb8d669e seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0xcbdcedad dm_put +EXPORT_SYMBOL_GPL vmlinux 0xcc018d9c register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc4fb3b7 sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xccfa05ae scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xcd141bb1 task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0xcd3d395b tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0xcd46e856 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0xcd856bfb __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcda06d2e spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xcdb5a0bc da903x_write +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce0c22cc ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0xce24aa99 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0xcea58ab4 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xcecbaeff sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xcf26b70d pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xcf487ee1 inet_csk_compat_getsockopt +EXPORT_SYMBOL_GPL vmlinux 0xcf6fe774 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0xcf96b4b1 relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0xcfb2ec6c usb_string +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd0292050 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd074f1e6 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xd082fe82 dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0xd09aebb2 scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd11df9db device_find_child +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd17e528d debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xd1ce26aa device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd23fbb35 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd287c829 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd2ee9f4e queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xd39d813f led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0xd3b78da3 xenbus_suspend_cancel +EXPORT_SYMBOL_GPL vmlinux 0xd3caf79d devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd4815ae7 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0xd4eb8d99 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0xd53d535d sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xd58bfbd9 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xd599ec20 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0xd5cc685c usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0xd5dfabf7 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xd662b14c mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xd6f4c2af mmput +EXPORT_SYMBOL_GPL vmlinux 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL vmlinux 0xd71c2a71 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xd751263b rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xd77423d9 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0xd7a08a6c usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd7ea2c4f rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0xd830b79f sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd85d7d23 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xd8c3c5fe sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0xd8cd63cd dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0xd8eae586 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xd8f4e07f securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xd9042fa8 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0xd90a18ed find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xda29f8b0 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xda7ba0de inet_csk_compat_setsockopt +EXPORT_SYMBOL_GPL vmlinux 0xdaab02df crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0xdab5baca pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdc1f8f2e register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xdc8c92a2 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xdd526358 da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xddb0bc1c __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde6afccd ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0xdec38cd4 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xdf61ca24 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xe01d75df tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0xe04eb9f6 usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xe060fea6 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0xe087c883 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL vmlinux 0xe0ef923b led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0xe0fd3846 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xe1093c71 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0xe12ef4cc usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0xe14fbc07 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0xe187df9c __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xe21a0bcb vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xe24ff917 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xe2745581 pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2cc626b device_del +EXPORT_SYMBOL_GPL vmlinux 0xe2cd352e bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xe3198ba2 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0xe34358a0 spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xe3774e81 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0xe3b5f581 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe3be2a7e usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0xe3e69990 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0xe3e7ba4a user_read +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe52c0d40 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe52fa4a4 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe53090cd ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0xe597bc89 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0xe5a0d977 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe62c4f50 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe6491b9d md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xe66e531c dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe6a92a86 rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe72589b0 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xe75382b6 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xe7b6c28a dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe81af31a crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0xe8448267 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xe8514def kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0xe89f0e9e hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xe8be598a ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xe8f9dfaf uv_cpu_to_blade +EXPORT_SYMBOL_GPL vmlinux 0xe8ff38c4 dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0xe9323263 usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9428a2c hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0xe9511ef3 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe9cb5d4d usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0xe9ce504f cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea195699 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea7a2825 xenbus_dev_error +EXPORT_SYMBOL_GPL vmlinux 0xea7e21b9 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xea863751 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea8b5cf1 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xea998a5d debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeafa576d usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0xeb46cadf xenbus_frontend_closed +EXPORT_SYMBOL_GPL vmlinux 0xeb537537 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xeb55ca25 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0xec127d57 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec31d3c8 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0xec95a47c crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0xeccea98f xenbus_map_ring +EXPORT_SYMBOL_GPL vmlinux 0xecd045c5 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xed0690a5 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0xed54d3c0 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xed9867c9 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xedaa25f5 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xedbc6f67 gnttab_end_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xee97d6b9 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0xeeca13e9 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0xeefc9777 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xef45a23f bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef6ed231 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xef8b39cd vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0xef961022 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0xef9beca8 uv_region_size +EXPORT_SYMBOL_GPL vmlinux 0xf0209ea5 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xf031a2dd blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0xf042da1a shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xf0e369af usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xf10e1d07 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0xf1150e76 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xf146c070 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1b445cd tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xf1d55bb3 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xf22c8905 crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0xf2683bd9 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0xf2756a75 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf2855040 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xf2c53d61 sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xf2dac98f ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf30ff34a device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0xf3407eae xenbus_bind_evtchn +EXPORT_SYMBOL_GPL vmlinux 0xf3432821 crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xf383cbac class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf3a6af55 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0xf3be8436 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf43a05b5 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4aebdc3 xenbus_suspend +EXPORT_SYMBOL_GPL vmlinux 0xf51f4f40 pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0xf53bbc2e regulator_get +EXPORT_SYMBOL_GPL vmlinux 0xf5498c4e tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xf54f2944 dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf5945bac gnttab_free_grant_references +EXPORT_SYMBOL_GPL vmlinux 0xf5965790 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5d148a1 user_destroy +EXPORT_SYMBOL_GPL vmlinux 0xf64c8572 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xf654381a ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0xf66eeb6e crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0xf6aaa689 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf6d6cd44 crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0xf6e9813e xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0xf7016530 xenbus_gather +EXPORT_SYMBOL_GPL vmlinux 0xf7394c69 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xf73e8612 swiotlb_sync_single_range_for_cpu +EXPORT_SYMBOL_GPL vmlinux 0xf7427c4c register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xf74b6102 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0xf77b41de ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xf7889e8d seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xf7cd966e sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf7d34928 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xf7f513d0 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0xf8025dd7 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0xf80c560d tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xf83a49cb ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8814a46 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf8f3b59f sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xf934120c vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xf95c4473 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xf96b2026 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9c788ff xenbus_grant_ring +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xfa1f4662 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0xfa45d31c driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0xfa7715bf scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xfb2404c2 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0xfb882fb7 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0xfbc016de blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xfbd43757 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0xfbe2a752 pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0xfbf3d2d8 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc083425 usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0xfc0c3095 dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0xfc271a87 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0xfc2ff860 uv_setup_irq +EXPORT_SYMBOL_GPL vmlinux 0xfc4d24e6 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xfc66a194 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xfc91103e find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0xfcaf4b91 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfd51b281 gnttab_end_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0xfda9c1d9 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0xfdc42073 scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xfddb5844 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfe727411 get_phys_to_machine +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfeb35a9e usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfee18453 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0xfefee878 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xff14e1e4 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xff479ecb blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/amd64/server.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/amd64/server.modules @@ -0,0 +1,2092 @@ +3c359 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +6pack +8021q +8139cp +8139too +8390 +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac97_bus +acecad +acenic +acer-wmi +acpi-cpufreq +acpiphp +acpiphp_ibm +acquirewdt +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-x86_64 +af9013 +affs +af_key +af-rxrpc +ah4 +ah6 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd76xrom +amd8111e +amd-rng +analog +ansi_cprng +anubis +aoe +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpu5wdt +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dca +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +dpt_i2o +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtl1_cs +dummy +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e752x_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro100 +eeprom +eeprom_93cx6 +efs +ehci-hcd +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +eql +esb2rom +esi-sir +esp4 +esp6 +et131x +et61x251 +eth1394 +eurotechwdt +evbug +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +fuse +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +gpio_keys +gpio_mouse +grip +grip_mp +gru +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hp100 +hp4x +hpfs +hpilo +hptiop +hp-wmi +hso +htc-pasic3 +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i7300_idle +i810 +i82092 +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipath +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmpex +ib_mthca +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +inet_lro +inexio +inftl +initio +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioatdma +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-pca9532 +leds-pca955x +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lockd +lock_dlm +lp +lpfc +lrw +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mmc_spi +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +ndiswrapper +ne2k-pci +neofb +net1080 +net2280 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +ntfs +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +ohci-hcd +old_belkin-sir +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas2 +pata_cmd640 +pata_cypress +pata_hpt3x2n +pata_it8213 +pata_ninja32 +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pbe5 +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pn_pep +powermate +powernow-k8 +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r8a66597-hcd +radeon +radeonfb +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-si470x +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-x86_64 +sata_mv +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +sdhci +sdhci-pci +sdio_uart +sdricoh_cs +se401 +sedlbauer_cs +seed +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc91c92_cs +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1889 +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmipci +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1938 +snd-es1968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3-synth +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16-dsp +snd-sb-common +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-tea575x-tuner +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedstep-centrino +speedstep-lib +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sx +sx8 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t1pci +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tlsup +tmdc +tms380tr +tmscsim +tmspci +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-x86_64 +typhoon +u132-hcd +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uhci-hcd +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan_cs +wbsd +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xen-blkfront +xen-fbfront +xen-kbdfront +xen-netfront +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xp +xpad +xpc +xpnet +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/amd64/generic.modules +++ linux-2.6.28/debian/abi/2.6.28-4.9/amd64/generic.modules @@ -0,0 +1,2092 @@ +3c359 +3c574_cs +3c589_cs +3c59x +3w-9xxx +3w-xxxx +6pack +8021q +8139cp +8139too +8390 +9p +9pnet +9pnet_rdma +9pnet_virtio +a100u2w +a3d +aacraid +abituguru +abituguru3 +abyss +ac97_bus +acecad +acenic +acer-wmi +acpi-cpufreq +acpiphp +acpiphp_ibm +acquirewdt +act200l-sir +act_gact +act_ipt +actisys-sir +act_mirred +act_nat +act_pedit +act_police +act_simple +act_skbedit +acx +ad1848 +ad7414 +ad7418 +adcxx +adfs +adi +adm1021 +adm1025 +adm1026 +adm1029 +adm1031 +adm8211 +adm9240 +ads7828 +ads7846 +adt7462 +adt7470 +adt7473 +adutux +adv7170 +adv7175 +advansys +advantechwdt +aedsp16 +aes_generic +aes-x86_64 +af9013 +affs +af_key +af-rxrpc +ah4 +ah6 +aic79xx +aic7xxx +aic94xx +aiptek +aircable +airo +airo_cs +alauda +ali-ircc +alim1535_wdt +alim7101_wdt +ambassador +amd76xrom +amd8111e +amd-rng +analog +ansi_cprng +anubis +aoe +appledisplay +appleir +applesmc +appletalk +appletouch +applicom +ar7part +arc4 +arcfb +arcmsr +arcnet +arc-rawmode +arc-rimi +ark3116 +arkfb +arptable_filter +arp_tables +arpt_mangle +asb100 +asix +asus-laptop +async_memcpy +async_tx +async_xor +at24 +at25 +at76_usb +aten +ath5k +ath9k +ati_remote +ati_remote2 +atl1 +atl1e +atl2 +atlas_btns +atmel +atmel_cs +atmel_pci +atmtcp +atp +atp870u +atxp1 +aty128fb +atyfb +au0828 +au8522 +aufs +authenc +auth_rpcgss +autofs +autofs4 +av5100 +avma1_cs +avm_cs +ax25 +axnet_cs +b1 +b1dma +b1pci +b1pcmcia +b2c2-flexcop +b2c2-flexcop-pci +b2c2-flexcop-usb +b43 +b43legacy +b44 +bas_gigaset +baycom_par +baycom_ser_fdx +baycom_ser_hdx +bcm203x +bcm3510 +bcm5974 +befs +belkin_sa +berry_charge +bfs +bfusb +binfmt_misc +bitblit +block2mtd +blowfish +bluecard_cs +bnep +bnx2 +bnx2x +bonding +bpa10x +bpck +bpqether +bq24022 +bq27x00_battery +br2684 +bridge +broadcom +bsd_comp +bt3c_cs +bt819 +bt856 +bt878 +btcx-risc +btsdio +bttv +btuart_cs +btusb +budget +budget-av +budget-ci +budget-core +budget-patch +BusLogic +bw-qcam +c2port-duramar2150 +c4 +c67x00 +cafe_ccic +cafe_nand +camellia +capi +capidrv +capifs +capmode +carminefb +cassini +cast5 +cast6 +catc +cbc +cciss +ccm +cdc-acm +cdc_ether +cdc_subset +cdc-wdm +cfag12864b +cfag12864bfb +cfg80211 +cfi_cmdset_0001 +cfi_cmdset_0002 +cfi_cmdset_0020 +cfi_probe +cfi_util +ch +ch341 +chipreg +cicada +cifs +cirrusfb +ck804xrom +cls_basic +cls_fw +cls_route +cls_rsvp +cls_rsvp6 +cls_tcindex +cls_u32 +cm109 +cm4000_cs +cm4040_cs +cmtp +cobra +coda +com20020 +com20020_cs +com20020-pci +com90io +com90xx +comm +commandir +compal-laptop +compat_ioctl32 +compcache +configfs +core +coretemp +corgi_bl +cp2101 +cpcihp_generic +cpcihp_zt5550 +cpia +cpia2 +cpia_pp +cpia_usb +cpqarray +cpu5wdt +cpuid +c-qcam +cr_bllcd +crc32c +crc32c-intel +crc7 +crc-ccitt +crc-itu-t +crvml +cryptd +cryptoloop +crypto_null +cs5345 +cs53l32a +ct82c710 +ctr +cts +cx18 +cx22700 +cx22702 +cx2341x +cx23885 +cx24110 +cx24116 +cx24123 +cx25840 +cx8800 +cx8802 +cx88-alsa +cx88-blackbird +cx88-dvb +cx88-vp3054-i2c +cx88xx +cxacru +cxgb +cxgb3 +cyber2000fb +cyberjack +cyclades +cyclomx +cycx_drv +cypress_cy7c63 +cypress_m8 +cytherm +da903x +DAC960 +davicom +db9 +dc395x +dca +dccp +dccp_ccid2 +dccp_ccid3 +dccp_diag +dccp_ipv4 +dccp_ipv6 +dccp_probe +dccp_tfrc_lib +dcdbas +de2104x +de4x5 +de600 +de620 +decnet +deflate +defxx +dell_rbu +des_generic +dib0070 +dib3000mb +dib3000mc +dib7000m +dib7000p +dibx000_common +digi_acceleport +dilnetpc +diskonchip +display +divacapi +divadidd +diva_idi +diva_mnt +divas +dlci +dlm +dm1105 +dm9601 +dm-bbr +dm-crypt +dme1737 +dmfe +dm-loop +dm-mem-cache +dm-message +dm-raid4-5 +dm-region_hash +dmx3191d +dm-zero +dn_rtmsg +doc2000 +doc2001 +doc2001plus +docecc +docprobe +dpt_i2o +drm +drx397xD +ds1621 +ds1682 +ds2482 +ds2490 +ds2760_battery +dsbr100 +dscc4 +dss1_divert +dst +dst_ca +dstr +dtl1_cs +dummy +dv1394 +dvb-bt8xx +dvb-core +dvb-pll +dvb-ttpci +dvb-ttusb-budget +dvb-usb +dvb-usb-a800 +dvb-usb-af9005 +dvb-usb-af9005-remote +dvb-usb-af9015 +dvb-usb-anysee +dvb-usb-au6610 +dvb-usb-cinergyT2 +dvb-usb-cxusb +dvb-usb-dib0700 +dvb-usb-dibusb-common +dvb-usb-dibusb-mb +dvb-usb-dibusb-mc +dvb-usb-digitv +dvb-usb-dtt200u +dvb-usb-dtv5100 +dvb-usb-dw2102 +dvb-usb-gl861 +dvb-usb-gp8psk +dvb-usb-m920x +dvb-usb-nova-t-usb2 +dvb-usb-opera +dvb-usb-ttusb2 +dvb-usb-umt-010 +dvb-usb-vp702x +dvb-usb-vp7045 +e100 +e1000 +e1000e +e752x_edac +eata +ebt_802_3 +ebtable_broute +ebtable_filter +ebtable_nat +ebtables +ebt_among +ebt_arp +ebt_arpreply +ebt_dnat +ebt_ip +ebt_ip6 +ebt_limit +ebt_log +ebt_mark +ebt_mark_m +ebt_nflog +ebt_pkttype +ebt_redirect +ebt_snat +ebt_stp +ebt_ulog +ebt_vlan +ecb +econet +edac_core +eeepc-laptop +eepro100 +eeprom +eeprom_93cx6 +efs +ehci-hcd +elo +elsa_cs +em28xx +em28xx-alsa +em28xx-dvb +em_cmp +emi26 +emi62 +em_meta +em_nbyte +empeg +em_text +emu10k1-gp +em_u32 +enclosure +eni +enic +epat +epca +epia +epic100 +eql +esb2rom +esi-sir +esp4 +esp6 +et131x +et61x251 +eth1394 +eurotechwdt +evbug +exportfs +f71805f +f71882fg +f75375s +fakephp +farsync +fat +faulty +fbcon +fb_ddc +fb_sys_fops +fcrypt +fdomain +fdomain_cs +fealnx +ff-memless +firestream +firewire-core +firewire-ohci +firewire-sbp2 +fit2 +fit3 +floppy +fm801-gp +fmvj18x_cs +font +forcedeth +fore_200e +freevxfs +friq +frpw +fsam7400 +fscher +fschmd +fscpos +ftdi-elan +ftdi_sio +ftl +fujitsu-laptop +fujitsu_ts +funsoft +fuse +g450_pll +gadgetfs +gamecon +gameport +garmin_gps +garp +g_cdc +gcm +gdth +generic_serial +gen_probe +g_ether +gf128mul +gf2k +g_file_storage +gfs2 +gigaset +girbil-sir +gl518sm +gl520sm +gl620a +gpio_keys +gpio_mouse +grip +grip_mp +gru +g_serial +gspca_conex +gspca_etoms +gspca_finepix +gspca_m5602 +gspca_main +gspca_mars +gspca_ov519 +gspca_pac207 +gspca_pac7311 +gspca_sonixb +gspca_sonixj +gspca_spca500 +gspca_spca501 +gspca_spca505 +gspca_spca506 +gspca_spca508 +gspca_spca561 +gspca_stk014 +gspca_sunplus +gspca_t613 +gspca_tv8532 +gspca_vc032x +gspca_zc3xx +gtco +guillemot +gunze +gx1fb +gxfb +g_zero +hamachi +hangcheck-timer +hci_uart +hci_vhci +hdaps +hdlc +hdlc_cisco +hdlcdrv +hdlc_fr +hdlc_ppp +hdlc_raw +hdlc_raw_eth +hdlc_x25 +he +heci +hecubafb +hermes +hermes_dld +hexium_gemini +hexium_orion +hfc4s8s_l1 +hfcmulti +hfcpci +hfc_usb +hfs +hfsplus +hgafb +hid-a4tech +hid-apple +hid-belkin +hid-bright +hid-cherry +hid-chicony +hid-cypress +hid-dell +hid-ezkey +hid-gyration +hid-logitech +hid-microsoft +hid-monterey +hidp +hid-petalynx +hid-pl +hid-samsung +hid-sony +hid-sunplus +hid-tmff +hid-zpff +hifn_795x +hisax +hisax_fcpcipnp +hisax_isac +hisax_st5481 +horizon +hostap +hostap_cs +hostap_pci +hostap_plx +hp100 +hp4x +hpfs +hpilo +hptiop +hp-wmi +hso +htc-pasic3 +hwa-hc +hwa-rc +hwmon-vid +hysdn +i1480-dfu-usb +i1480-est +i1480u-wlp +i2c-algo-bit +i2c-algo-pca +i2c-algo-pcf +i2c-ali1535 +i2c-ali1563 +i2c-ali15x3 +i2c-amd756 +i2c-amd756-s4882 +i2c-amd8111 +i2c-dev +i2c-gpio +i2c-i801 +i2c-isch +i2c-matroxfb +i2c-nforce2 +i2c-nforce2-s4985 +i2c-ocores +i2c-parport +i2c-parport-light +i2c-pca-platform +i2c-piix4 +i2c-simtec +i2c-sis5595 +i2c-sis630 +i2c-sis96x +i2c-stub +i2c-taos-evm +i2c-tiny-usb +i2c-via +i2c-viapro +i2c-voodoo3 +i2o_block +i2o_bus +i2o_config +i2o_core +i2o_proc +i2o_scsi +i3000_edac +i5000_edac +i5100_edac +i5k_amb +i6300esb +i7300_idle +i810 +i82092 +i82975x_edac +i830 +i8k +i915 +ib700wdt +ib_addr +ib_cm +ib_core +ib_ipath +ib_ipoib +ib_iser +ib_mad +ibmaem +ibmasm +ibmasr +ibmcam +ibmpex +ib_mthca +ibmtr_cs +ib_sa +ib_srp +ib_ucm +ib_umad +ib_uverbs +ichxrom +icplus +ics932s401 +idmouse +idt77252 +ieee1394 +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep +ifb +iforce +igb +ili9320 +imm +inet_lro +inexio +inftl +initio +input-polldev +intel-agp +intelfb +intel_menlow +intel-rng +intel_vr_nor +interact +ioatdma +ioc4 +io_edgeport +io_ti +iowarrior +ip2 +ip6_queue +ip6table_filter +ip6table_mangle +ip6table_raw +ip6_tables +ip6table_security +ip6t_ah +ip6t_eui64 +ip6t_frag +ip6t_hbh +ip6t_hl +ip6t_HL +ip6t_ipv6header +ip6t_LOG +ip6t_mh +ip6t_REJECT +ip6t_rt +ip6_tunnel +ipaq +ipcomp +ipcomp6 +ipddp +ipg +ip_gre +iphase +ipip +ipmi_devintf +ipmi_msghandler +ipmi_poweroff +ipmi_si +ipmi_watchdog +ip_queue +ipr +ips +iptable_filter +iptable_mangle +iptable_nat +iptable_raw +ip_tables +iptable_security +ipt_addrtype +ipt_ah +ipt_CLUSTERIP +ipt_ecn +ipt_ECN +ipt_LOG +ipt_MASQUERADE +ipt_NETMAP +ipt_REDIRECT +ipt_REJECT +ipt_ttl +ipt_TTL +ipt_ULOG +ip_vs +ip_vs_dh +ip_vs_ftp +ip_vs_lblc +ip_vs_lblcr +ip_vs_lc +ip_vs_nq +ip_vs_rr +ip_vs_sed +ip_vs_sh +ip_vs_wlc +ip_vs_wrr +ipw +ipw2100 +ipw2200 +ipwireless +ipx +ircomm +ir-common +ircomm-tty +irda +irda-usb +ir-kbd-i2c +irlan +irnet +irtty-sir +iscsi_ibft +iscsi_tcp +iscsi_trgt +isdn +isdn_bsdcomp +isdnhdlc +isight_firmware +isl6405 +isl6421 +isofs +isp116x-hcd +isp1760 +istallion +it87 +it8712f_wdt +it87_wdt +iTCO_vendor_support +iTCO_wdt +itd1000 +ivtv +ivtvfb +iw_c2 +iw_cm +iw_cxgb3 +iwl3945 +iwlagn +iwlcore +ixgb +ixgbe +ixj +ixj_pcmcia +jedec_probe +jffs2 +jfs +jme +joydev +joydump +jsm +k8temp +kafs +kahlua +kaweth +kb3886_bl +kbic +kbtab +kernelcapi +keyspan +keyspan_pda +keyspan_remote +khazad +kingsun-sir +kl5kusb105 +kobil_sct +konicawc +ks0108 +ks0127 +ks959-sir +ksdazzle-sir +ktti +kvm +kvm-amd +kvm-intel +kyrofb +l1oip +l440gx +l64781 +lanai +lapb +lapbether +lcd +ldusb +lec +led-class +leds-da903x +leds-gpio +leds-hp-disk +leds-pca9532 +leds-pca955x +ledtrig-backlight +ledtrig-default-on +ledtrig-heartbeat +ledtrig-timer +legousbtower +lgdt330x +lgs8gl5 +libcrc32c +libertas +libertas_cs +libertas_sdio +libertas_tf +libertas_tf_usb +libiscsi +libsas +libsrp +lightning +linear +lirc_atiusb +lirc_bt829 +lirc_cmdir +lirc_dev +lirc_i2c +lirc_igorplugusb +lirc_imon +lirc_it87 +lirc_mceusb +lirc_mceusb2 +lirc_pvr150 +lirc_sasem +lirc_serial +lirc_serial_igor +lirc_sir +lirc_streamzap +lirc_ttusbir +lis3lv02d +litelink-sir +lkkbd +llc2 +lm63 +lm70 +lm75 +lm77 +lm78 +lm80 +lm83 +lm85 +lm87 +lm90 +lm92 +lm93 +lmc +lmpcm_usb +lnbp21 +lockd +lock_dlm +lp +lpfc +lrw +ltv350qv +lxfb +lxt +lzo +lzo_compress +lzo_decompress +m25p80 +m52790 +ma600-sir +mac80211 +machzwd +macmodes +macvlan +magellan +map_absent +map_funcs +map_ram +map_rom +marvell +matroxfb_accel +matroxfb_base +matroxfb_crtc2 +matroxfb_DAC1064 +matroxfb_g450 +matroxfb_maven +matroxfb_misc +matroxfb_Ti3026 +matrox_w1 +max1111 +max1619 +max6650 +max6875 +max7301 +max732x +mb862xxfb +mbp_nvidia_bl +mcp2120-sir +mcp23s08 +mcs7780 +mcs7830 +mct_u232 +md4 +mdc800 +mdio-bitbang +megaraid +megaraid_mbox +megaraid_mm +megaraid_sas +metronomefb +meye +mga +michael_mic +microcode +microtek +mii +minix +mISDN_core +mISDN_dsp +mk712 +mkiss +mlx4_core +mlx4_en +mlx4_ib +mmc_block +mmc_spi +mos7720 +mos7840 +moto_modem +moxa +mpoa +mptbase +mptctl +mptfc +mptlan +mptsas +mptscsih +mptspi +mpu401 +msdos +msi-laptop +msp3400 +msr +mt2060 +mt20xx +mt2131 +mt2266 +mt312 +mt352 +mt9m001 +mt9m111 +mt9v022 +mtd +mtd_blkdevs +mtdblock +mtdblock_ro +mtdchar +mtdconcat +mtd_dataflash +mtdoops +mtdram +mtouch +multipath +mwave +mxb +mxl5005s +mxl5007t +mxser +myri10ge +nand +nand_ecc +nand_ids +nandsim +natsemi +navman +nbd +ncpfs +ndiswrapper +ne2k-pci +neofb +net1080 +net2280 +netconsole +netrom +netsc520 +nettel +netwave_cs +netxen_nic +newtonkbd +nf_conntrack +nf_conntrack_amanda +nf_conntrack_ftp +nf_conntrack_h323 +nf_conntrack_ipv4 +nf_conntrack_ipv6 +nf_conntrack_irc +nf_conntrack_netbios_ns +nf_conntrack_netlink +nf_conntrack_pptp +nf_conntrack_proto_gre +nf_conntrack_proto_sctp +nf_conntrack_proto_udplite +nf_conntrack_sip +nf_conntrack_tftp +nf_defrag_ipv4 +nf_nat +nf_nat_amanda +nf_nat_ftp +nf_nat_h323 +nf_nat_irc +nf_nat_pptp +nf_nat_proto_gre +nf_nat_proto_sctp +nf_nat_proto_udplite +nf_nat_sip +nf_nat_snmp_basic +nf_nat_tftp +nfnetlink +nfnetlink_log +nfnetlink_queue +nfs +nfs_acl +nfsd +nftl +nf_tproxy_core +n_hdlc +niu +nls_ascii +nls_cp1250 +nls_cp1251 +nls_cp1255 +nls_cp437 +nls_cp737 +nls_cp775 +nls_cp850 +nls_cp852 +nls_cp855 +nls_cp857 +nls_cp860 +nls_cp861 +nls_cp862 +nls_cp863 +nls_cp864 +nls_cp865 +nls_cp866 +nls_cp869 +nls_cp874 +nls_cp932 +nls_cp936 +nls_cp949 +nls_cp950 +nls_euc-jp +nls_iso8859-1 +nls_iso8859-13 +nls_iso8859-14 +nls_iso8859-15 +nls_iso8859-2 +nls_iso8859-3 +nls_iso8859-4 +nls_iso8859-5 +nls_iso8859-6 +nls_iso8859-7 +nls_iso8859-9 +nls_koi8-r +nls_koi8-ru +nls_koi8-u +nls_utf8 +nmclan_cs +nozomi +n_r3964 +ns558 +ns83820 +nsc_gpio +nsc-ircc +ntfs +nvidiafb +nvram +nxt200x +nxt6000 +ocfs2 +ocfs2_dlm +ocfs2_dlmfs +ocfs2_nodemanager +ocfs2_stackglue +ocfs2_stack_o2cb +ocfs2_stack_user +ohci1394 +ohci-hcd +old_belkin-sir +olympic +omfs +omninet +on20 +on26 +onenand +onenand_sim +opl3 +oprofile +option +or51132 +or51211 +orinoco +orinoco_cs +orinoco_nortel +orinoco_pci +orinoco_plx +orinoco_tmd +osst +oti6858 +output +ov511 +ov511_decomp +ov518_decomp +ov7670 +ovcamchip +p4-clockmod +p54common +p54pci +p54usb +p80211 +p8023 +panasonic-laptop +paride +parkbd +parport +parport_ax88796 +parport_cs +parport_pc +parport_serial +pas2 +pata_cmd640 +pata_cypress +pata_hpt3x2n +pata_it8213 +pata_ninja32 +pata_opti +pata_optidma +pata_pcmcia +pata_radisys +pbe5 +pc87360 +pc8736x_gpio +pc87413_wdt +pc87427 +pca953x +pcbc +pcd +pcf857x +pcf8591 +pci +pci200syn +pcilynx +pcips2 +pcmcia +pcmcia_core +pcnet32 +pcnet_cs +pcspkr +pcwd_pci +pcwd_usb +pd +pd6729 +pda_power +pegasus +penmount +pf +pg +phantom +phidget +phidgetkit +phidgetmotorcontrol +phidgetservo +phonedev +phonet +phram +physmap +pktgen +pl2303 +platform_lcd +plat_nand +plat-ram +plip +plusb +pluto2 +pm2fb +pm3fb +pmc551 +pn_pep +powermate +powernow-k8 +ppa +ppdev +ppp_async +ppp_deflate +ppp_mppe +pppoatm +pppoe +pppol2tp +pppox +ppp_synctty +prism2_usb +prism54 +progear_bl +psmouse +pss +pt +pvrusb2 +pwc +qla1280 +qla2xxx +qla3xxx +qla4xxx +qlge +qlogic_cs +qlogicfas408 +qnx4 +qsemi +qt1010 +quickcam_messenger +quota_v1 +quota_v2 +r128 +r8169 +r8a66597-hcd +radeon +radeonfb +radio-gemtek-pci +radio-maestro +radio-maxiradio +radio-mr800 +radio-si470x +raid0 +raid1 +raid10 +raid456 +raid_class +raw +raw1394 +ray_cs +rdma_cm +rdma_ucm +redboot +reed_solomon +reiserfs +rfc1051 +rfc1201 +rfd_ftl +rfkill-input +ricoh_mmc +rio +rio500 +riscom8 +rivafb +rmd128 +rmd160 +rmd256 +rmd320 +rndis_host +rndis_wlan +rocket +romfs +rose +rpcsec_gss_krb5 +rpcsec_gss_spkm3 +rrunner +rsrc_nonstatic +rt2400pci +rt2500pci +rt2500usb +rt2x00lib +rt2x00pci +rt2x00usb +rt61pci +rt73usb +rtc-bq4802 +rtc-ds1286 +rtc-ds1305 +rtc-ds1307 +rtc-ds1374 +rtc-ds1390 +rtc-ds1553 +rtc-ds1672 +rtc-ds1742 +rtc-ds3234 +rtc-fm3130 +rtc-isl1208 +rtc-m41t80 +rtc-m41t94 +rtc-m48t35 +rtc-m48t59 +rtc-m48t86 +rtc-max6900 +rtc-max6902 +rtc-pcf8563 +rtc-pcf8583 +rtc-rs5c348 +rtc-rs5c372 +rtc-rx8581 +rtc-stk17ta8 +rtc-test +rtc-v3020 +rtc-wm8350 +rtc-x1205 +rtl8150 +rtl8180 +rtl8187 +rxkad +s1d13xxxfb +s2255drv +s2io +s3fb +s5h1409 +s5h1411 +s5h1420 +saa5246a +saa5249 +saa6588 +saa6752hs +saa7110 +saa7111 +saa7114 +saa7115 +saa7127 +saa7134 +saa7134-alsa +saa7134-dvb +saa7134-empress +saa7146 +saa7146_vv +saa717x +saa7185 +safe_serial +salsa20_generic +salsa20-x86_64 +sata_mv +savage +savagefb +sb +sb1000 +sbc60xxwdt +sbc8360 +sbc_epx_c3 +sbc_gxx +sb_lib +sbni +sbp2 +sc1200wdt +sc520cdp +sc520_wdt +sc92031 +scb2_flash +sch_atm +sch_cbq +sch_dsmark +sch_gred +sch_hfsc +sch_htb +sch_ingress +sch_multiq +sch_netem +sch_prio +sch_red +sch_sfq +sch_tbf +sch_teql +scsi_debug +scsi_dh_alua +scsi_dh_emc +scsi_dh_hp_sw +scsi_dh_rdac +scsi_tgt +scsi_transport_fc +scsi_transport_iscsi +scsi_transport_sas +scsi_transport_spi +scsi_transport_srp +scsi_wait_scan +sctp +sdhci +sdhci-pci +sdio_uart +sdricoh_cs +se401 +sedlbauer_cs +seed +seqiv +ser_gigaset +serial_cs +serio_raw +sermouse +serpent +serport +ses +sfc +sha1_generic +sha256_generic +sha512_generic +sh_mobile_ceu_camera +shpchp +si21xx +sidewinder +sierra +sir-dev +sis +sis190 +sis5595 +sis900 +sis-agp +sisfb +sisusbvga +sit +skfp +skge +sky2 +sl811_cs +sl811-hcd +slip +slram +sm501 +sm501fb +smbfs +smc91c92_cs +sms1xxx +smsc +smsc37b787_wdt +smsc47b397 +smsc47m1 +smsc47m192 +smsc95xx +smsc-ircc2 +sn9c102 +snd +snd-ac97-codec +snd-ad1889 +snd-ak4114 +snd-ak4117 +snd-ak4xxx-adda +snd-ali5451 +snd-als300 +snd-als4000 +snd-atiixp +snd-atiixp-modem +snd-au8810 +snd-au8820 +snd-au8830 +snd-aw2 +snd-azt3328 +snd-bt87x +snd-ca0106 +snd-cmipci +snd-cs4281 +snd-cs46xx +snd-cs5530 +snd-cs8427 +snd-darla20 +snd-darla24 +snd-dummy +snd-echo3g +snd-emu10k1 +snd-emu10k1-synth +snd-emu10k1x +snd-emux-synth +snd-ens1370 +snd-ens1371 +snd-es1938 +snd-es1968 +snd-fm801 +snd-gina20 +snd-gina24 +snd-hda-intel +snd-hdsp +snd-hdspm +snd-hifier +snd-hwdep +snd-i2c +snd-ice1712 +snd-ice1724 +snd-ice17xx-ak4xxx +snd-indigo +snd-indigodj +snd-indigoio +snd-intel8x0 +snd-intel8x0m +snd-korg1212 +snd-layla20 +snd-layla24 +snd-maestro3 +snd-mia +snd-mixart +snd-mixer-oss +snd-mona +snd-mpu401 +snd-mpu401-uart +snd-mtpav +snd-mts64 +snd-nm256 +snd-opl3-lib +snd-opl3-synth +snd-oxygen +snd-oxygen-lib +snd-page-alloc +snd-pcm +snd-pcm-oss +snd-pcsp +snd-pcxhr +snd-pdaudiocf +snd-portman2x4 +snd-pt2258 +snd-rawmidi +snd-riptide +snd-rme32 +snd-rme96 +snd-rme9652 +snd-sb16-dsp +snd-sb-common +snd-seq +snd-seq-device +snd-seq-dummy +snd-seq-midi +snd-seq-midi-emul +snd-seq-midi-event +snd-seq-oss +snd-seq-virmidi +snd-serial-u16550 +snd-soc-ad73311 +snd-soc-ak4535 +snd-soc-core +snd-soc-cs4270 +snd-soc-ssm2602 +snd-soc-tlv320aic23 +snd-soc-tlv320aic26 +snd-soc-tlv320aic3x +snd-soc-uda1380 +snd-soc-wm8510 +snd-soc-wm8580 +snd-soc-wm8731 +snd-soc-wm8750 +snd-soc-wm8753 +snd-soc-wm8900 +snd-soc-wm8903 +snd-soc-wm8971 +snd-soc-wm8990 +snd-sonicvibes +snd-tea575x-tuner +snd-timer +snd-trident +snd-usb-audio +snd-usb-caiaq +snd-usb-lib +snd-usb-us122l +snd-usb-usx2y +snd-util-mem +snd-via82xx +snd-via82xx-modem +snd-virmidi +snd-virtuoso +snd-vx222 +snd-vx-lib +snd-vxpocket +snd-ymfpci +soc_camera +soc_camera_platform +softcursor +softdog +sony-laptop +sound +soundcore +sound_firmware +sp8870 +sp887x +spaceball +spaceorb +spcp8x5 +specialix +spectrum_cs +speedstep-centrino +speedstep-lib +speedtch +spi_bitbang +spi_butterfly +spidev +spi_lm70llp +squashfs +ssb +sscape +ssfdc +sstfb +st +stallion +starfire +stb6000 +stex +stinger +stir4200 +stkwebcam +stowaway +stp +stradis +strip +stv0288 +stv0297 +stv0299 +stv680 +sundance +sungem +sungem_phy +sunhme +suni +sunkbd +sunrpc +svcrdma +svgalib +sx +sx8 +sym53c500_cs +sym53c8xx +synclink +synclink_cs +synclink_gt +synclinkmp +syncppp +syscopyarea +sysfillrect +sysimgblt +sysv +t1pci +tcp_bic +tcp_highspeed +tcp_htcp +tcp_hybla +tcp_illinois +tcp_lp +tcp_probe +tcp_scalable +tcp_vegas +tcp_veno +tcp_westwood +tcp_yeah +tcrypt +tda10021 +tda10023 +tda10048 +tda1004x +tda10086 +tda18271 +tda7432 +tda8083 +tda826x +tda827x +tda8290 +tda9840 +tda9875 +tda9887 +tdfx +tdfxfb +tdo24m +tea +tea5761 +tea5767 +tea6415c +tea6420 +tehuti +tekram-sir +teles_cs +tg3 +tgr192 +thinkpad_acpi +thinkpad_ec +thmc50 +tifm_7xx1 +tifm_core +tifm_sd +tileblit +tipc +ti_usb_3410_5052 +tlan +tlclk +tle62x0 +tlsf +tlsup +tmdc +tms380tr +tmscsim +tmspci +touchit213 +touchright +touchwin +tpm +tpm_atmel +tpm_bios +tpm_infineon +tpm_nsc +tpm_tis +tps65010 +tp_smapi +trancevibrator +tridentfb +trix +ts5500_flash +ts_bm +ts_fsm +ts_kmp +tsl2550 +ttpci-eeprom +ttusb_dec +ttusbdecfe +tua6100 +tulip +tun +tuner +tuner-simple +tuner-types +tuner-xc2028 +tunnel4 +tunnel6 +turbografx +tvaudio +tveeprom +tvp5150 +twidjoy +twofish +twofish_common +twofish-x86_64 +typhoon +u132-hcd +uart401 +uart6850 +ub +ubi +ubifs +ucb1400_core +ucb1400_ts +udf +ueagle-atm +ufs +uhci-hcd +uinput +uio +uio_cif +uio_pdrv +uio_pdrv_genirq +uio_sercos3 +uio_smx +uli526x +ultracam +umc +umem +unionfs +upd64031a +upd64083 +uPD98402 +usb8xxx +usbatm +usb_debug +usb_gigaset +usbhid +usbkbd +usblcd +usbled +usblp +usbmouse +usbnet +usbsevseg +usb-storage +usbtmc +usbtouchscreen +usbvideo +usbvision +uss720 +uvcvideo +uvesafb +uwb +v4l1-compat +v4l2-common +v4l2-int-device +ves1820 +ves1x93 +vesafb +veth +vfat +vga16fb +vgastate +vgg2432a4 +via +via686a +via-agp +viafb +via-ircc +via-rhine +via-velocity +vicam +video +video1394 +videobuf-core +videobuf-dma-contig +videobuf-dma-sg +videobuf-dvb +videobuf-vmalloc +videocodec +videodev +virtio +virtio_balloon +virtio_blk +virtio_console +virtio_net +virtio_pci +virtio_ring +virtio-rng +virtual +visor +vitesse +vivi +vlsi_ir +v_midi +vmlfb +vp27smpx +vpx3220 +vstusb +vsxxxaa +vt1211 +vt8231 +vt8623fb +w1_bq27000 +w1_ds2433 +w1_ds2760 +w1-gpio +w1_smem +w1_therm +w83627ehf +w83627hf +w83627hf_wdt +w83697hf_wdt +w83697ug_wdt +w83781d +w83791d +w83792d +w83793 +w83877f_wdt +w83977af_ir +w83977f_wdt +w83l785ts +w83l786ng +w9966 +w9968cf +wacom +wafer5823wdt +wanrouter +wanxl +warrior +wavelan_cs +wbsd +wdt_pci +whci +whci-hcd +whc-rc +whiteheat +winbond-840 +wire +wl3501_cs +wlp +wm8350 +wm8350-i2c +wm8350-regulator +wm8400-core +wm8400-regulator +wm8739 +wm8775 +wm97xx-ts +wp512 +wusb-cbaf +wusbcore +wusb-wa +x25 +x25_asy +x38_edac +xc5000 +xcbc +xen-blkfront +xen-fbfront +xen-kbdfront +xen-netfront +xfrm4_mode_beet +xfrm4_mode_transport +xfrm4_mode_tunnel +xfrm4_tunnel +xfrm6_mode_beet +xfrm6_mode_ro +xfrm6_mode_transport +xfrm6_mode_tunnel +xfrm6_tunnel +xfrm_ipcomp +xfrm_user +xfs +xirc2ps_cs +xircom_cb +xor +xp +xpad +xpc +xpnet +xprtrdma +x_tables +xt_CLASSIFY +xt_comment +xt_connbytes +xt_connlimit +xt_connmark +xt_CONNMARK +xt_CONNSECMARK +xt_conntrack +xt_dccp +xt_dscp +xt_DSCP +xt_esp +xt_hashlimit +xt_helper +xt_iprange +xtkbd +xt_length +xt_limit +xt_mac +xt_mark +xt_MARK +xt_multiport +xt_NFLOG +xt_NFQUEUE +xt_NOTRACK +xt_owner +xt_physdev +xt_pkttype +xt_policy +xt_quota +xt_rateest +xt_RATEEST +xt_realm +xt_recent +xts +xt_sctp +xt_SECMARK +xt_socket +xt_state +xt_statistic +xt_string +xt_tcpmss +xt_TCPMSS +xt_tcpudp +xt_time +xt_TPROXY +xt_TRACE +xt_u32 +xusbatm +yam +yealink +yellowfin +yenta_socket +zatm +zaurus +zc0301 +zd1201 +zd1211rw +zhenhua +zl10353 +zlib_deflate +zr36016 +zr36050 +zr36060 +zr36067 +zr364xx --- linux-2.6.28.orig/debian/abi/2.6.28-4.9/amd64/server +++ linux-2.6.28/debian/abi/2.6.28-4.9/amd64/server @@ -0,0 +1,8600 @@ +EXPORT_SYMBOL arch/x86/kvm/kvm 0x37ca7b43 kvm_cpu_has_pending_timer +EXPORT_SYMBOL arch/x86/kvm/kvm 0x39338afa kvm_read_guest_atomic +EXPORT_SYMBOL crypto/gf128mul 0x0c2f123f gf128mul_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x1068004b gf128mul_bbe +EXPORT_SYMBOL crypto/gf128mul 0x2f2889a0 gf128mul_init_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0x3755f990 gf128mul_init_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x384ef9ce gf128mul_64k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x56af0dbd gf128mul_x_ble +EXPORT_SYMBOL crypto/gf128mul 0x83581089 gf128mul_init_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0x9b2560b9 gf128mul_init_4k_bbe +EXPORT_SYMBOL crypto/gf128mul 0x9e13f6f6 gf128mul_lle +EXPORT_SYMBOL crypto/gf128mul 0xbd17a0df gf128mul_4k_lle +EXPORT_SYMBOL crypto/gf128mul 0xc0890413 gf128mul_64k_lle +EXPORT_SYMBOL crypto/gf128mul 0xd60736ec gf128mul_free_64k +EXPORT_SYMBOL crypto/xor 0x5b6c00e6 xor_blocks +EXPORT_SYMBOL drivers/atm/suni 0xcd82957b suni_init +EXPORT_SYMBOL drivers/atm/uPD98402 0x47172608 uPD98402_init +EXPORT_SYMBOL drivers/block/paride/paride 0x1f5ff5cb pi_do_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0x3ab42e6d paride_unregister +EXPORT_SYMBOL drivers/block/paride/paride 0x46b16a3c pi_read_regr +EXPORT_SYMBOL drivers/block/paride/paride 0x4e771e3c paride_register +EXPORT_SYMBOL drivers/block/paride/paride 0x4f50394e pi_release +EXPORT_SYMBOL drivers/block/paride/paride 0x5af66929 pi_read_block +EXPORT_SYMBOL drivers/block/paride/paride 0x5e1fa9f0 pi_write_block +EXPORT_SYMBOL drivers/block/paride/paride 0x6c76d28c pi_connect +EXPORT_SYMBOL drivers/block/paride/paride 0x6f231e8f pi_init +EXPORT_SYMBOL drivers/block/paride/paride 0x8cfb6f65 pi_write_regr +EXPORT_SYMBOL drivers/block/paride/paride 0xa77ac881 pi_schedule_claimed +EXPORT_SYMBOL drivers/block/paride/paride 0xf5983080 pi_disconnect +EXPORT_SYMBOL drivers/char/generic_serial 0x0f9e6943 gs_close +EXPORT_SYMBOL drivers/char/generic_serial 0x1737d3d6 gs_write_room +EXPORT_SYMBOL drivers/char/generic_serial 0x19306178 gs_init_port +EXPORT_SYMBOL drivers/char/generic_serial 0x1d282d0b gs_flush_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0x224e090a gs_getserial +EXPORT_SYMBOL drivers/char/generic_serial 0x3c9a6fc8 gs_start +EXPORT_SYMBOL drivers/char/generic_serial 0x3cd6b610 gs_flush_chars +EXPORT_SYMBOL drivers/char/generic_serial 0x51c8cdcb gs_set_termios +EXPORT_SYMBOL drivers/char/generic_serial 0x5d435a4c gs_got_break +EXPORT_SYMBOL drivers/char/generic_serial 0x976daf76 gs_put_char +EXPORT_SYMBOL drivers/char/generic_serial 0xa5079500 gs_write +EXPORT_SYMBOL drivers/char/generic_serial 0xbe6ec6ca gs_block_til_ready +EXPORT_SYMBOL drivers/char/generic_serial 0xc2bd11a5 gs_hangup +EXPORT_SYMBOL drivers/char/generic_serial 0xcf5ce6e1 gs_setserial +EXPORT_SYMBOL drivers/char/generic_serial 0xef9fa86f gs_chars_in_buffer +EXPORT_SYMBOL drivers/char/generic_serial 0xfc518053 gs_stop +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x02861b5e ipmi_get_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x04ca3ec0 ipmi_poll_interface +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x0b01e325 ipmi_set_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x13475d8a ipmi_create_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x200ea071 ipmi_free_recv_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x26284d15 ipmi_get_maintenance_mode +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x27ce61ee ipmi_register_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x2dce01f3 ipmi_unregister_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x40f2b10c ipmi_alloc_smi_msg +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x444ae8ae ipmi_set_gets_events +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6496d039 ipmi_smi_add_proc_entry +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x6f24d18f ipmi_request_supply_msgs +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7186dc05 ipmi_smi_watchdog_pretimeout +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x7350102f ipmi_destroy_user +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x804f922a ipmi_addr_length +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x89f3c07d ipmi_get_version +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0x98558bcc ipmi_request_settime +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xaaee129e ipmi_smi_watcher_register +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xb83ee62c ipmi_get_my_LUN +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc04bea08 ipmi_register_smi +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc5b7348a ipmi_smi_watcher_unregister +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xc8b0fb0d ipmi_smi_msg_received +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xd1c60122 ipmi_unregister_for_cmd +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xe4f4665b ipmi_validate_addr +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf1291660 ipmi_set_my_address +EXPORT_SYMBOL drivers/char/ipmi/ipmi_msghandler 0xf55f0864 ipmi_set_my_LUN +EXPORT_SYMBOL drivers/char/nsc_gpio 0x2f843aa7 nsc_gpio_read +EXPORT_SYMBOL drivers/char/nsc_gpio 0x30890b34 nsc_gpio_write +EXPORT_SYMBOL drivers/char/nsc_gpio 0xb1b1f859 nsc_gpio_dump +EXPORT_SYMBOL drivers/char/nvram 0x0f28cb91 nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x17ff2c1d __nvram_read_byte +EXPORT_SYMBOL drivers/char/nvram 0x2adec1e0 __nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x7da28f12 nvram_check_checksum +EXPORT_SYMBOL drivers/char/nvram 0x9ce3f83f nvram_write_byte +EXPORT_SYMBOL drivers/char/nvram 0xa8813189 __nvram_write_byte +EXPORT_SYMBOL drivers/edac/edac_core 0x7a7f9e73 edac_mc_handle_fbd_ce +EXPORT_SYMBOL drivers/edac/edac_core 0x83f5827f edac_mc_handle_fbd_ue +EXPORT_SYMBOL drivers/edac/edac_core 0xf0b743fa edac_mc_find +EXPORT_SYMBOL drivers/firewire/firewire-core 0x0733d1b4 fw_send_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x12c21cb4 fw_device_enable_phys_dma +EXPORT_SYMBOL drivers/firewire/firewire-core 0x1c0bbf77 fw_core_handle_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2208fe81 fw_card_add +EXPORT_SYMBOL drivers/firewire/firewire-core 0x279983a9 fw_run_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2876619c fw_core_remove_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x2fe73c90 fw_core_handle_response +EXPORT_SYMBOL drivers/firewire/firewire-core 0x3c4159d3 fw_cancel_transaction +EXPORT_SYMBOL drivers/firewire/firewire-core 0x45e18cca fw_core_remove_card +EXPORT_SYMBOL drivers/firewire/firewire-core 0x66af3f77 fw_core_add_address_handler +EXPORT_SYMBOL drivers/firewire/firewire-core 0x80c98e89 fw_core_initiate_bus_reset +EXPORT_SYMBOL drivers/firewire/firewire-core 0x90863005 fw_high_memory_region +EXPORT_SYMBOL drivers/firewire/firewire-core 0x973ecc19 fw_send_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0xa7433922 fw_bus_type +EXPORT_SYMBOL drivers/firewire/firewire-core 0xafc1c793 fw_csr_iterator_next +EXPORT_SYMBOL drivers/firewire/firewire-core 0xb047a2c6 fw_csr_iterator_init +EXPORT_SYMBOL drivers/firewire/firewire-core 0xc5160813 fw_core_handle_request +EXPORT_SYMBOL drivers/firewire/firewire-core 0xdc85ab2a fw_card_initialize +EXPORT_SYMBOL drivers/firewire/firewire-core 0xddde8337 fw_fill_response +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0836695c drm_sman_takedown +EXPORT_SYMBOL drivers/gpu/drm/drm 0x08b242b6 drm_get_resource_start +EXPORT_SYMBOL drivers/gpu/drm/drm 0x0a83577f drm_agp_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x143cbe31 drm_open +EXPORT_SYMBOL drivers/gpu/drm/drm 0x148e1e3a drm_mm_search_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x15586d50 drm_pci_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x17041634 drm_core_get_reg_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1b2efe9f drm_addbufs_pci +EXPORT_SYMBOL drivers/gpu/drm/drm 0x1f3982ee drm_vblank_count +EXPORT_SYMBOL drivers/gpu/drm/drm 0x20645642 drm_debug +EXPORT_SYMBOL drivers/gpu/drm/drm 0x21451ac4 drm_sman_owner_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2857a5af drm_compat_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2916bf63 drm_sman_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2a25a915 drm_ati_pcigart_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2bd035c5 drm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2d9db240 drm_poll +EXPORT_SYMBOL drivers/gpu/drm/drm 0x2eb2f903 drm_sman_free_key +EXPORT_SYMBOL drivers/gpu/drm/drm 0x3074f033 drm_order +EXPORT_SYMBOL drivers/gpu/drm/drm 0x349bd7c2 drm_agp_acquire +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4659d60c drm_core_ioremap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x48c19324 drm_rmmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0x49bcc6aa drm_vblank_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4b8082b9 drm_mm_put_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x4ea1f5a2 drm_gem_object_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x523f0ea4 drm_free_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0x5575a9c1 drm_idlelock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x55f060ee drm_sman_set_range +EXPORT_SYMBOL drivers/gpu/drm/drm 0x56549195 drm_clflush_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6370b050 drm_mm_get_block +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6b173633 drm_get_drawable_info +EXPORT_SYMBOL drivers/gpu/drm/drm 0x6bf5422d drm_ati_pcigart_cleanup +EXPORT_SYMBOL drivers/gpu/drm/drm 0x7c356de9 drm_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0x84ac6867 drm_agp_bind_pages +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8873dc30 drm_mm_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8990e44b drm_agp_enable +EXPORT_SYMBOL drivers/gpu/drm/drm 0x89ca5152 drm_lock_take +EXPORT_SYMBOL drivers/gpu/drm/drm 0x8bd42f64 drm_get_resource_len +EXPORT_SYMBOL drivers/gpu/drm/drm 0x96f05528 drm_agp_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9a3295d6 drm_vblank_get +EXPORT_SYMBOL drivers/gpu/drm/drm 0x9c25b192 drm_core_get_map_ofs +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa2542dd5 drm_unbind_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa28c8bfd drm_ioctl +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa591ed6e drm_core_reclaim_buffers +EXPORT_SYMBOL drivers/gpu/drm/drm 0xa9c62548 drm_gem_object_lookup +EXPORT_SYMBOL drivers/gpu/drm/drm 0xacfc33e0 drm_gem_handle_create +EXPORT_SYMBOL drivers/gpu/drm/drm 0xadb4b278 drm_idlelock_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xaf29788e drm_sman_init +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb20c0523 drm_agp_bind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb2985feb drm_lock_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb3f6e179 drm_agp_chipset_flush +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb5efce5b drm_addmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb790b837 drm_agp_release +EXPORT_SYMBOL drivers/gpu/drm/drm 0xb7fa269f drm_handle_vblank +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc080eb9b drm_gem_object_handle_free +EXPORT_SYMBOL drivers/gpu/drm/drm 0xc618316b drm_agp_unbind +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcb9cbbe2 drm_irq_uninstall +EXPORT_SYMBOL drivers/gpu/drm/drm 0xcc726971 drm_getsarea +EXPORT_SYMBOL drivers/gpu/drm/drm 0xce417905 drm_sg_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd2588649 drm_vblank_put +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd3028e75 drm_sman_set_manager +EXPORT_SYMBOL drivers/gpu/drm/drm 0xd8dd582b drm_irq_install +EXPORT_SYMBOL drivers/gpu/drm/drm 0xdf8e20b3 drm_mmap +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe2376c93 drm_fasync +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe3591a99 drm_exit +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe919dd5c drm_sman_owner_clean +EXPORT_SYMBOL drivers/gpu/drm/drm 0xe9ef8778 drm_pci_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xeaf8ca27 drm_addbufs_agp +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf29d48a8 drm_gem_object_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf4862727 drm_agp_alloc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf523c71d drm_i_have_hw_lock +EXPORT_SYMBOL drivers/gpu/drm/drm 0xf64a775c drm_core_ioremapfree +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfafa88 drm_core_ioremap_wc +EXPORT_SYMBOL drivers/gpu/drm/drm 0xfdfbad19 drm_sman_alloc +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0x0903c239 vid_from_reg +EXPORT_SYMBOL drivers/hwmon/hwmon-vid 0xef1c781c vid_which_vrm +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x4b62ca08 i2c_bit_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-bit 0x5c50f142 i2c_bit_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x28bfb788 i2c_pca_add_numbered_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pca 0x69565bf9 i2c_pca_add_bus +EXPORT_SYMBOL drivers/i2c/algos/i2c-algo-pcf 0x679f4ce4 i2c_pcf_add_bus +EXPORT_SYMBOL drivers/i2c/busses/i2c-amd756 0x4ad66132 amd756_smbus +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x02d4ad0f tps65013_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x28485130 tps65010_config_vregs1 +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x33739de7 tps65010_set_vib +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0x9fd44c69 tps65010_set_led +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xb14080cc tps65010_set_low_pwr +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xd5bb106d tps65010_set_vbus_draw +EXPORT_SYMBOL drivers/i2c/chips/tps65010 0xe99b3f36 tps65010_set_gpio_out_value +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x027a402f hpsb_get_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x036aa0e3 hpsb_alloc_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x04403e90 dma_region_mmap +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x079eebac hpsb_unregister_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x07d9bfe5 hpsb_iso_wake +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0b234c4e dma_prog_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0c6da941 csr1212_release_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0cd62da6 hpsb_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e134e24 hpsb_create_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0e5a659c csr1212_new_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x0f161e6f hpsb_iso_recv_release_packets +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x10be8193 hpsb_iso_recv_set_channel_mask +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x10bfeda4 hpsb_unregister_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x13b4a268 csr1212_attach_keyval_to_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x158ac548 dma_region_offset_to_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x168dc4b8 hpsb_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x19f1f97b csr1212_parse_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2112202e hpsb_make_lockpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x28495931 hpsb_make_writepacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2a36d053 hpsb_iso_xmit_sync +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2c0df5d8 hpsb_iso_recv_listen_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2dd29f75 csr1212_read +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x2ebf6e5a dma_prog_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x32de3c19 hpsb_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3bdbb53f hpsb_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3bf52960 hpsb_destroy_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x3d5aa39a hpsb_iso_shutdown +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x410365fa hpsb_resume_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4323d6e6 hpsb_make_readpacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x4d064a36 hpsb_iso_recv_unlisten_channel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5619e578 hpsb_make_lock64packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5e05c474 hpsb_make_streampacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x5ee0fab9 hpsb_iso_xmit_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x672ad148 dma_region_sync_for_device +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x688fd8ec hpsb_protocol_class +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x6c41e3c8 hpsb_read_cycle_timer +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x75afbe37 hpsb_add_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x76bc1a5c dma_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x79530b08 csr1212_get_keyval +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x7c1a236c __hpsb_register_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x85c9cab9 hpsb_iso_xmit_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x86f6e10b hpsb_remove_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x88282bbc hpsb_free_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8879f8f0 dma_region_sync_for_cpu +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8bb1fe70 hpsb_node_write +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8c3bd8d0 hpsb_iso_recv_start +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8e8339f0 hpsb_selfid_complete +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x8ec2b312 dma_region_alloc +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9419aee0 hpsb_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x942311c3 hpsb_free_tlabel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9bef271b hpsb_selfid_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0x9d853e5b hpsb_register_highlevel +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xa401a5f9 hpsb_set_hostinfo_key +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xae5e5000 hpsb_get_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb1d4482d hpsb_iso_packet_sent +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb23060fb hpsb_iso_recv_flush +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xb68063aa hpsb_unregister_protocol +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xba723e79 hpsb_node_fill_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xbe69e245 hpsb_iso_packet_received +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc3eaa8af hpsb_update_config_rom_image +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc6561207 hpsb_iso_xmit_queue_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xc669a4d3 csr1212_detach_keyval_from_directory +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xcd9e772b dma_prog_region_free +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd177b64c hpsb_set_hostinfo +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xd667156f hpsb_set_packet_complete_task +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdc765214 hpsb_make_phypacket +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xdfff6f2a hpsb_bus_reset +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe4f1ebd8 hpsb_update_config_rom +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xe5d2a4e8 hpsb_iso_stop +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xea4152ff dma_region_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xed6fe814 hpsb_allocate_and_register_addrspace +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf1ceb20b hpsb_packet_success +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf21de5ab hpsb_iso_recv_init +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf67bcaf9 hpsb_send_packet +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf702630f hpsb_reset_bus +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xf76c5fc6 hpsb_get_hostinfo_bykey +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfa720bbf hpsb_alloc_host +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfba57f51 hpsb_speedto_str +EXPORT_SYMBOL drivers/ieee1394/ieee1394 0xfcd578c9 hpsb_iso_n_ready +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x0c386903 ohci1394_stop_context +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0x750956d9 ohci1394_unregister_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xb37ab086 ohci1394_init_iso_tasklet +EXPORT_SYMBOL drivers/ieee1394/ohci1394 0xd35dd036 ohci1394_register_iso_tasklet +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x5735c4b6 rdma_translate_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x6392ac33 rdma_copy_addr +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x71de06c2 rdma_addr_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0x970caeac rdma_addr_cancel +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xbe81bb46 rdma_addr_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_addr 0xe6f70808 rdma_resolve_ip +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x14b96159 ib_send_cm_rtu +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x1f2a4a4d ib_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x2b135513 ib_send_cm_lap +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x30961910 ib_cm_notify +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x32f5b4c3 ib_send_cm_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x4cb69488 ib_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x73a6f57e ib_send_cm_rej +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x77eef51a ib_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x7a0be102 ib_send_cm_sidr_rep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x86f22e07 ib_send_cm_drep +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0x951fafb6 ib_send_cm_apr +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xba48a8d4 ib_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xc555bf62 ib_send_cm_sidr_req +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xca28bbc4 ib_send_cm_dreq +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xcc23419b cm_class +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xd08b6ca4 ib_send_cm_mra +EXPORT_SYMBOL drivers/infiniband/core/ib_cm 0xf9b6699f ib_send_cm_req +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x000ad6aa ib_query_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x06830b9a ib_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x073373bf ib_create_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0ae1742e ib_get_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x0fc7f5cf ib_find_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x10a0cdc9 ib_destroy_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x14fb18a7 ib_query_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x17f563c9 ib_alloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x185953ef ib_create_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x19de8c51 ib_get_dma_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1ade0b3c ib_detach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1d0242a5 ib_umem_release +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x1e491a04 ib_unmap_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2ae082f0 ib_query_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2d284e61 ib_unregister_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x2f0db218 ib_query_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x304535a0 ib_free_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x350f6ca4 ib_destroy_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3d396cfe ib_umem_get +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3e7bd1ad ib_dereg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x3f7567fd ib_rate_to_mult +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x440a5411 ib_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x48b59153 ib_dealloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x521e828b ib_query_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x523def05 ib_find_cached_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x62000940 ib_modify_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x63cac1cd ib_flush_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x6518539b ib_set_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x71199f76 ib_alloc_fast_reg_page_list +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x7235cc54 ib_query_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x77f52ce7 ib_dispatch_event +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x78025171 ib_unregister_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x816eeafb ib_rereg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x830e43d1 ib_umem_page_count +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x85144001 ib_alloc_fast_reg_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8640eaeb ib_modify_qp_is_ok +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x87b614d8 ib_ud_header_pack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8a5c35ff ib_get_client_data +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x8d97ce82 ib_find_gid +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x90aa1213 ib_resize_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x92fe2ad9 ib_fmr_pool_map_phys +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x968d4200 ib_alloc_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96cab678 ib_create_fmr_pool +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x96ce6c46 rdma_node_get_transport +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x980b1149 ib_modify_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x99cb120c ib_dealloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9a23c171 ib_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d5a599b ib_destroy_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d69bca7 ib_create_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9d804fa1 mult_to_ib_rate +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0x9def2f32 ib_modify_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa33390c8 ib_create_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xa83c316f ib_find_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xaf2e3edb ib_modify_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb1216612 ib_alloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb617feab ib_dealloc_fmr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xb66fd438 ib_attach_mcast +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbd9cd88a ib_get_cached_lmc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xbe5782b4 ib_query_port +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc3cff0d9 ib_modify_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xc723dd4e ib_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xcf7b8dec ib_alloc_mw +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd17ba9d1 ib_ud_header_init +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xd78660f9 ib_init_ah_from_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xdc598cc9 ib_reg_phys_mr +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xde01606d ib_destroy_cq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xeccda842 ib_register_device +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xed26e1df ib_modify_srq +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xefa569cf ib_dealloc_pd +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf04608a5 ib_query_ah +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf0ee3787 ib_get_cached_pkey +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf260cef4 ib_register_event_handler +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf36498b9 ib_ud_header_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf45c0c5c ib_create_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xf96fc9de ib_unpack +EXPORT_SYMBOL drivers/infiniband/core/ib_core 0xfae3c49d ib_fmr_pool_unmap +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x1169e3c7 ib_cancel_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x4a40d5b9 ib_process_mad_wc +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x587b39b7 ib_redirect_mad_qp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6246f687 ib_post_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x63882290 ib_get_rmpp_segment +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6cdd8d85 ib_register_mad_snoop +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6ef787ed ib_response_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x6f077fcf ib_get_mad_data_offset +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x7b5d4b7a ib_is_mad_class_rmpp +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0x838c907e ib_create_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xa93cbb1d ib_modify_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xb03a52cd ib_free_recv_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xcf13b864 ib_free_send_mad +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xe9284e33 ib_register_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_mad 0xeabdbb12 ib_unregister_mad_agent +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x0bc535c5 ib_sa_service_rec_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x16199856 ib_sa_register_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x1db44053 ib_sa_get_mcmember_rec +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x24b092a3 ib_init_ah_from_mcmember +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x512ba124 ib_sa_unregister_client +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x576fdbac ib_sa_free_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0x9a0f35d3 ib_sa_cancel_query +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xe7a48ed8 ib_init_ah_from_path +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xfe4a4a4e ib_sa_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/ib_sa 0xfe7ea33e ib_sa_path_rec_get +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x02f847bc ib_copy_path_rec_from_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x07cf5a51 ib_copy_ah_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x18382f6a ib_copy_path_rec_to_user +EXPORT_SYMBOL drivers/infiniband/core/ib_uverbs 0x184f3575 ib_copy_qp_attr_to_user +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x0bef1a88 iw_cm_reject +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x1219eed5 iw_cm_accept +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x32ba9e92 iw_cm_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x3f00f6b3 iw_cm_connect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x8a05cd71 iw_cm_listen +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0x982a5cb9 iw_cm_disconnect +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xa8a8f91c iw_create_cm_id +EXPORT_SYMBOL drivers/infiniband/core/iw_cm 0xe9a59d79 iw_destroy_cm_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x092d6344 rdma_accept +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x0c2f4875 rdma_resolve_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x133b7f38 rdma_init_qp_attr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3360af81 rdma_listen +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x3d0c18fe rdma_bind_addr +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x4de08fa0 rdma_create_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x5395a7a4 rdma_resolve_route +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x91a73844 rdma_destroy_qp +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0x9c5e9341 rdma_set_ib_paths +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xa0a7271d rdma_connect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xa623c75e rdma_destroy_id +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xace96d79 rdma_set_service_type +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xb078209f rdma_join_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xbaa502f8 rdma_notify +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xc2c42d47 rdma_leave_multicast +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xd3118291 rdma_reject +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xe211426d rdma_disconnect +EXPORT_SYMBOL drivers/infiniband/core/rdma_cm 0xf447edc5 rdma_create_id +EXPORT_SYMBOL drivers/input/gameport/gameport 0x36e027ca gameport_close +EXPORT_SYMBOL drivers/input/gameport/gameport 0x43c1369e gameport_set_phys +EXPORT_SYMBOL drivers/input/gameport/gameport 0x450b2d34 __gameport_register_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0x4d90d62f gameport_start_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0x9bda5274 __gameport_register_driver +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa5c63580 gameport_stop_polling +EXPORT_SYMBOL drivers/input/gameport/gameport 0xa78f83c1 gameport_open +EXPORT_SYMBOL drivers/input/gameport/gameport 0xb62240f8 gameport_unregister_port +EXPORT_SYMBOL drivers/input/gameport/gameport 0xf037f56b gameport_unregister_driver +EXPORT_SYMBOL drivers/input/input-polldev 0x6d022e0e input_unregister_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x8281219c input_allocate_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0x8f9d46e0 input_register_polled_device +EXPORT_SYMBOL drivers/input/input-polldev 0xeea0795a input_free_polled_device +EXPORT_SYMBOL drivers/isdn/capi/capifs 0x2c54c957 capifs_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/capifs 0xd0bc06ce capifs_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x04403fcf unregister_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x14f2aa5a capi20_get_version +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x26af63eb capi_ctr_ready +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2b8eab1f capilib_free_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2baa6586 capilib_new_ncci +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x2bc042ff capi_ctr_suspend_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x31c24aa4 capi20_isinstalled +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47d3fc51 capi_info2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x47dbfa0a capi_message2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x50b33ca4 capi_cmsg2message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x56d382d3 capi_ctr_handle_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x56d99518 capi20_set_callback +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x6057c6f3 capi_message2cmsg +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x62e32d43 capilib_data_b3_conf +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x71e8d5ba capilib_data_b3_req +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x788d398c capi_cmsg2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7a33596c capi20_get_serial +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x7e6f1307 capi20_get_manufacturer +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f699913 capilib_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x8f71ada9 capi20_release +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0x9f823278 register_capi_driver +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa1bd9981 attach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xa59e0d2c capi_ctr_reseted +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xaa165d27 capilib_release_appl +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xada5fb07 capi20_put_message +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb19fda8d capi_cmd2str +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb5a664be capi_ctr_resume_output +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xb60e5e5f capi_cmsg_header +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc5327ee3 capi20_register +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xc809f770 detach_capi_ctr +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe19a11ac capi20_get_profile +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xe9f62f29 cdebbuf_free +EXPORT_SYMBOL drivers/isdn/capi/kernelcapi 0xed061606 capi20_manufacturer +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x010bdc70 avmcard_dma_free +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x3056750d b1_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x3aaf3c5e b1_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x4efefdf1 b1_parse_version +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x600a40ea b1_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x7596b3a0 b1_free_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x85f09690 b1_irq_table +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x8f92e06e b1_alloc_card +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x9396f7cc avmcard_dma_alloc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x94ea01d7 b1ctl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0x96f9d2f4 b1_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xce310059 b1_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xd2cca776 b1_getrevision +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xdfd28376 b1_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xe1277e1f b1_load_config +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xe8de02d6 b1_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xf0d1ccf2 b1_load_t4file +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1 0xfbd07e3f b1_loaded +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x0b534c61 b1dma_register_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x0fbafecf b1pciv4_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2a386384 b1dma_interrupt +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x2da940da b1dma_release_appl +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x308428cc b1dma_load_firmware +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x44c908f3 b1dma_send_message +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x53935fc2 b1dmactl_read_proc +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0x54b26454 b1dma_reset +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xb1aff250 t1pci_detect +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1dma 0xbf995abd b1dma_reset_ctr +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0x29562993 b1pcmcia_delcard +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xaec3240e b1pcmcia_addcard_m1 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xea620116 b1pcmcia_addcard_m2 +EXPORT_SYMBOL drivers/isdn/hardware/avm/b1pcmcia 0xf14bf8b1 b1pcmcia_addcard_b1 +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0x2974ead1 DIVA_DIDD_Read +EXPORT_SYMBOL drivers/isdn/hardware/eicon/divadidd 0xd4981563 proc_net_eicon +EXPORT_SYMBOL drivers/isdn/hardware/mISDN/hfcmulti 0x5293ed86 plx_lock +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x07f4f2ce hisax_unregister +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x148f0c99 FsmFree +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x2844a899 FsmInitTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x93a64734 FsmChangeState +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0x9df0cd27 FsmEvent +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xc0c558f9 FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd81cd6e1 hisax_init_pcmcia +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xd94696e8 FsmDelTimer +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xee93522c hisax_register +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xf0a16657 FsmNew +EXPORT_SYMBOL drivers/isdn/hisax/hisax 0xfc27303b HiSax_closecard +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x3f3b323a isac_d_l2l1 +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x5d53f88d isac_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0x62c47f59 isac_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xb79acc00 isacsx_irq +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xcd5d8723 isacsx_setup +EXPORT_SYMBOL drivers/isdn/hisax/hisax_isac 0xecbe61bd isac_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x1ee629e2 isdnhdlc_rcv_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x95aed401 isdnhdlc_decode +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0x9ffc8215 isdnhdlc_out_init +EXPORT_SYMBOL drivers/isdn/hisax/isdnhdlc 0xf5c8131d isdnhdlc_encode +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x65f7a34e isdn_ppp_unregister_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x86fe1db5 register_isdn +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0x8b7619c2 isdn_ppp_register_compressor +EXPORT_SYMBOL drivers/isdn/i4l/isdn 0xfa06820f isdn_register_divert +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x044005fa recv_Dchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x08d4b7e6 recv_Dchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x1a5161ef bchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x2348cc3c mISDN_FsmFree +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3a8b3b18 mISDN_freebchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3aaa53ca get_next_bframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x3ea336fd mISDN_FsmAddTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x429129f2 mISDN_FsmRestartTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x4da50dd9 recv_Bchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x50c2230c mISDN_FsmChangeState +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x6d8da0ad mISDN_unregister_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x86688c84 recv_Bchannel_skb +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x950d3fc5 mISDN_unregister_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x9a21d0ef create_l1 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0x9f0102ea mISDN_freedchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xa71a9a55 mISDN_initbchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xab2cb383 mISDN_initdchannel +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xace35cae mISDN_FsmDelTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb548a5eb l1_event +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xb62ddfef mISDN_register_Bprotocol +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xbc8b4f9d mISDN_register_device +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc21a8eea confirm_Bsend +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc308c3a1 queue_ch_frame +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xc4a99c1b dchannel_senddata +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd5145151 mISDN_FsmEvent +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xd9a7fbfd mISDN_FsmInitTimer +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xebc60954 get_next_dframe +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_core 0xf9e7832f mISDN_FsmNew +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x4c2ec443 mISDN_dsp_element_register +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0x60721da7 dsp_audio_law_to_s32 +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xa215f1b2 dsp_audio_s16_to_law +EXPORT_SYMBOL drivers/isdn/mISDN/mISDN_dsp 0xd3a023b8 mISDN_dsp_element_unregister +EXPORT_SYMBOL drivers/media/common/tuners/mt2060 0xa6e507de mt2060_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2131 0xf0ece626 mt2131_attach +EXPORT_SYMBOL drivers/media/common/tuners/mt2266 0x15c7f7f5 mt2266_attach +EXPORT_SYMBOL drivers/media/common/tuners/mxl5005s 0xde4df415 mxl5005s_attach +EXPORT_SYMBOL drivers/media/common/tuners/qt1010 0xa0346495 qt1010_attach +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0x0cb4b189 tuners +EXPORT_SYMBOL drivers/media/common/tuners/tuner-types 0xc2821775 tuner_count +EXPORT_SYMBOL drivers/media/common/tuners/tuner-xc2028 0xd1b80cd3 xc2028_attach +EXPORT_SYMBOL drivers/media/common/tuners/xc5000 0xeefe06e6 xc5000_attach +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x09417631 flexcop_device_initialize +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x14bb1b80 flexcop_dma_config_timer +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x1ce8ee3b flexcop_dma_allocate +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x3e0354fd flexcop_i2c_request +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x4f066cef flexcop_pass_dmx_data +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x67e2df1a flexcop_dma_xfer_control +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x6aa2d6e2 flexcop_device_exit +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x76260730 flexcop_wan_set_speed +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x90052dc7 flexcop_dma_control_timer_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0x961d5416 flexcop_sram_ctrl +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xa1e63042 flexcop_dma_free +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xab61432d flexcop_dma_config +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb3bbe807 flexcop_pass_dmx_packets +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xb5078dee flexcop_sram_set_dest +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc0e47184 flexcop_device_kmalloc +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xc4439c58 flexcop_dma_control_size_irq +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xd7024164 flexcop_eeprom_check_mac_addr +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xe06f55f2 flexcop_dump_reg +EXPORT_SYMBOL drivers/media/dvb/b2c2/b2c2-flexcop 0xf22bafd4 flexcop_device_kfree +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x15fd1a8d bt878_start +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x669968ee bt878 +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0x6aef312a bt878_stop +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xd5d0bdef bt878_num +EXPORT_SYMBOL drivers/media/dvb/bt8xx/bt878 0xddcc0c7e bt878_device_control +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x272cda06 dst_pio_disable +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x7028aa56 dst_error_recovery +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0x713c32c0 read_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xa0c0ddf7 write_dst +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xa0f91369 dst_wait_dst_ready +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xaf651d53 dst_error_bailout +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xb873e685 dst_comm_init +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xd3dd54dc dst_attach +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xe94b8c9c dst_check_sum +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst 0xf4826979 rdc_reset_state +EXPORT_SYMBOL drivers/media/dvb/bt8xx/dst_ca 0x1dd1378f dst_ca_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x04cb99db dvb_register_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0c457c5c dvb_ringbuffer_flush_spinlock_wakeup +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x0d3785b4 dvb_unregister_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x1bbd3d4c dvb_net_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x273c762e dvb_generic_open +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36397c4d dvb_ca_en50221_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x36c8ea1f dvb_frontend_sleep_until +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x4db3899f dvb_dmx_swfilter_packets +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x51f3767c dvb_ringbuffer_read +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x53efe99e dvb_ca_en50221_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x5497e6fa dvb_frontend_detach +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6988f784 dvb_ringbuffer_read_user +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x6c29bdbc dvb_register_device +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x74a5a698 dvb_filter_pes2ts_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x80e3832d dvb_filter_get_ac3info +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8b49a23f timeval_usec_diff +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x8f326272 dvb_generic_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0x97614994 dvb_unregister_frontend +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac3153eb dvb_net_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xac4ca1b0 intlog2 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb031117d dvb_register_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xb3a4edac dvb_dmxdev_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc324b69b dvb_dmx_swfilter_204 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc5694d34 dvb_dmxdev_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xc80754c1 dvb_dmx_release +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcb89fc7d dvb_ringbuffer_free +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcca08cb5 dvb_ringbuffer_avail +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xcce0eeed dvb_ringbuffer_init +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xce138fe8 dvb_ca_en50221_camchange_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd2a792b6 dvb_ca_en50221_frda_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd52e8cf3 dvb_generic_ioctl +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd639b9bc dvb_ringbuffer_write +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xd7765e69 dvb_ringbuffer_empty +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xde915a0b dvb_frontend_reinitialise +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xe5ae8707 intlog10 +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xee73de0a dvb_dmx_swfilter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf3990030 dvb_ca_en50221_camready_irq +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf61bb3f8 dvb_unregister_adapter +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf826deb0 dvb_filter_pes2ts +EXPORT_SYMBOL drivers/media/dvb/dvb-core/dvb-core 0xf86f20c5 dvb_dmx_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x047e966c usb_cypress_load_firmware +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0x8a412dc2 dvb_usb_get_hexline +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xafb7fc3b dvb_usb_device_exit +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xbabc5756 dvb_usb_nec_rc_key_to_event +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xcdf89d2b dvb_usb_generic_rw +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xce99a786 dvb_usb_generic_write +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb 0xde20518c dvb_usb_device_init +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2e45e3dc af9005_rc_decode +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0x2edc4728 af9005_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-af9005-remote 0xd3383957 af9005_rc_keys_size +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x0bbc3b0e dibusb_pid_filter +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x495d64a4 dibusb_pid_filter_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x700da642 dibusb2_0_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0x9f3660c8 dibusb_read_eeprom_byte +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xbda7cd31 dibusb2_0_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xcd386de4 dibusb_dib3000mc_tuner_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xd4d3dddc dibusb_rc_keys +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xdae85c33 dibusb_dib3000mc_frontend_attach +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xe8d38cd3 dibusb_streaming_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xf0d1cede dibusb_power_ctrl +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xfae9ae1f dibusb_rc_query +EXPORT_SYMBOL drivers/media/dvb/dvb-usb/dvb-usb-dibusb-common 0xff8a8435 dibusb_i2c_algo +EXPORT_SYMBOL drivers/media/dvb/frontends/af9013 0xf43578a5 af9013_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/au8522 0xa21d924d au8522_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/bcm3510 0x2b61daec bcm3510_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22700 0xebc4c7a2 cx22700_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx22702 0x878bf5eb cx22702_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24110 0xba64a39d cx24110_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24116 0x425d558b cx24116_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x845d1cf6 cx24123_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/cx24123 0x8d24aca7 cx24123_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0x189a3589 dib0070_wbd_offset +EXPORT_SYMBOL drivers/media/dvb/frontends/dib0070 0xa23fd840 dib0070_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mb 0xbce99c45 dib3000mb_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x12194dcf dib3000mc_set_config +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x184c4e33 dib3000mc_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x361e6fbc dib3000mc_pid_parse +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x4d4020e4 dib3000mc_get_tuner_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0x8c5b5fae dib3000mc_pid_control +EXPORT_SYMBOL drivers/media/dvb/frontends/dib3000mc 0xc257914d dib3000mc_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x02f6a2f0 dib7000m_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000m 0x3c127722 dib7000m_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x522042ce dib7000p_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0x7abcd71c dib7000p_set_gpio +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xa4cf76cc dib7000p_i2c_enumeration +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xae2073b8 dib7000pc_detection +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xb24f9af4 dib7000p_get_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dib7000p 0xb69926e2 dib7000p_set_wbd_ref +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x1b6efa3e dibx000_get_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0x66d93f68 dibx000_init_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/dibx000_common 0xa5c1014f dibx000_exit_i2c_master +EXPORT_SYMBOL drivers/media/dvb/frontends/drx397xD 0x88fb2e82 drx397xD_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/dvb-pll 0x81233094 dvb_pll_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6405 0x2622b858 isl6405_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/isl6421 0x43cfff61 isl6421_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/itd1000 0x493cb9a3 itd1000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/l64781 0x1d62970e l64781_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgdt330x 0x6d3f6bab lgdt330x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lgs8gl5 0x8a39b3c9 lgs8gl5_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/lnbp21 0xb2829354 lnbp21_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt312 0xae717259 mt312_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/mt352 0xb9d26467 mt352_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt200x 0x33be1bd4 nxt200x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/nxt6000 0xfe9b09fe nxt6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51132 0x377ad9e5 or51132_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/or51211 0xe9447bcd or51211_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1409 0x41232796 s5h1409_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1411 0x8ffb1922 s5h1411_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0x62ffbb58 s5h1420_get_tuner_i2c_adapter +EXPORT_SYMBOL drivers/media/dvb/frontends/s5h1420 0xdfd039c8 s5h1420_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/si21xx 0x7b666d76 si21xx_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp8870 0x9a10b079 sp8870_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/sp887x 0x25a2deef sp887x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stb6000 0x8fc79f12 stb6000_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0288 0x0129ca93 stv0288_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0297 0x2b8923d2 stv0297_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/stv0299 0xee25d306 stv0299_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10021 0xa44a3bac tda10021_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10023 0x8cb4082b tda10023_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10048 0x2f93d6f3 tda10048_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0x98d39ed9 tda10045_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda1004x 0xbf922729 tda10046_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda10086 0xd09722ba tda10086_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda8083 0xd4f44f4c tda8083_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tda826x 0xcabc6c01 tda826x_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/tua6100 0x94b4442f tua6100_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1820 0x00fc0484 ves1820_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/ves1x93 0xab6c7dd9 ves1x93_attach +EXPORT_SYMBOL drivers/media/dvb/frontends/zl10353 0x999b2d37 zl10353_attach +EXPORT_SYMBOL drivers/media/dvb/ttpci/ttpci-eeprom 0x97c9baa5 ttpci_eeprom_parse_mac +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xc7e262ac ttusbdecfe_dvbt_attach +EXPORT_SYMBOL drivers/media/dvb/ttusb-dec/ttusbdecfe 0xec256366 ttusbdecfe_dvbs_attach +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x11dc4b6d bttv_gpio_enable +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x3f3b9a4d bttv_get_pcidev +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8d16fd93 bttv_sub_register +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0x8ecf4acc bttv_write_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xbcf2d2fb bttv_read_gpio +EXPORT_SYMBOL drivers/media/video/bt8xx/bttv 0xf428815d bttv_sub_unregister +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x495e4b0c btcx_calc_skips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0x85f16026 btcx_riscmem_free +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xad2fe38b btcx_sort_clips +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc368f8e6 btcx_align +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xc77d98bf btcx_riscmem_alloc +EXPORT_SYMBOL drivers/media/video/btcx-risc 0xcda0ded2 btcx_screen_clips +EXPORT_SYMBOL drivers/media/video/cpia 0x75affab9 cpia_unregister_camera +EXPORT_SYMBOL drivers/media/video/cpia 0xb93903ba cpia_register_camera +EXPORT_SYMBOL drivers/media/video/cx18/cx18 0x2cdea06d cx18_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/cx2341x 0x226b4360 cx2341x_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/cx2341x 0x484d9064 cx2341x_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx2341x 0x61b38569 cx2341x_ext_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0x62f2c86b cx2341x_log_status +EXPORT_SYMBOL drivers/media/video/cx2341x 0x7f09da7c cx2341x_fill_defaults +EXPORT_SYMBOL drivers/media/video/cx2341x 0xcf8b77a4 cx2341x_mpeg_ctrls +EXPORT_SYMBOL drivers/media/video/cx2341x 0xe58ec2e3 cx2341x_update +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0x2b83e4f9 vp3054_i2c_remove +EXPORT_SYMBOL drivers/media/video/cx88/cx88-vp3054-i2c 0xf57a0bec vp3054_i2c_probe +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x85d97a00 cx88_set_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0x99d13592 cx8800_ctrl_query +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xac4e53b9 cx88_user_ctrls +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xb27942aa cx88_get_control +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xb49be76f cx88_set_freq +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xedf73980 cx88_enum_input +EXPORT_SYMBOL drivers/media/video/cx88/cx8800 0xf65096cf cx88_video_mux +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x3a349d5a cx8802_buf_prepare +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x3e9612d8 cx8802_register_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x4959b9a7 cx8802_get_device +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x635f22cf cx8802_get_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x70264e66 cx8802_cancel_buffers +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0x71cf0284 cx8802_unregister_driver +EXPORT_SYMBOL drivers/media/video/cx88/cx8802 0xf98c4a62 cx8802_buf_queue +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x0720dad5 cx88_core_put +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x1e5dbe45 cx88_wakeup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x3ef00fdd cx88_core_irq +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x512264db cx88_sram_channel_dump +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x577a621d cx88_set_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x59c55b9e cx88_core_get +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x6141c8c5 cx88_tuner_callback +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x62da3f80 cx88_sram_channel_setup +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x711b33dc cx88_risc_stopper +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x76b3aaaf cx88_ir_stop +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x8b6d7686 cx88_risc_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x904b8696 cx88_audio_thread +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x911ca9b9 cx88_risc_databuffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x92fc3c41 cx88_ir_start +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9b140fff cx88_sram_channels +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0x9bc224aa cx88_set_scale +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xae242734 cx88_free_buffer +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb47f6cda cx88_print_irqbits +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xb57fceb9 cx88_vdev_init +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xbfda1f59 cx88_reset +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xc4ef6497 cx88_call_i2c_clients +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xca69ba3d cx88_shutdown +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xd6eea48d cx88_set_tvnorm +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xea0cf6f0 cx88_get_stereo +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xfd8a838d cx88_newstation +EXPORT_SYMBOL drivers/media/video/cx88/cx88xx 0xfec41258 cx88_set_tvaudio +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x55c39821 em28xx_register_extension +EXPORT_SYMBOL drivers/media/video/em28xx/em28xx 0x5f928542 em28xx_unregister_extension +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x0e207c55 gspca_frame_add +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x13cd9eee gspca_get_i_frame +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x347d2757 gspca_dev_probe +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x5b4540ca gspca_suspend +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x9670af2c gspca_debug +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0x99aacb41 gspca_resume +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xba0a9c48 gspca_auto_gain_n_exposure +EXPORT_SYMBOL drivers/media/video/gspca/gspca_main 0xba2f2cdc gspca_disconnect +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0538e449 ivtv_cards_lock +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x0d96278a ivtv_saa7127 +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x14f67530 ivtv_debug +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4205c92c ivtv_udma_alloc +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x43cbdf5a ivtv_clear_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x4eac4bbb ivtv_api +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x570664fa ivtv_udma_unmap +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x70196ffb ivtv_cards_active +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0x79a507e1 ivtv_udma_prepare +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xa964ca64 ivtv_vapi +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xbe6182f0 ivtv_cards +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xcbde9982 ivtv_set_irq_mask +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xe5be385f ivtv_reset_ir_gpio +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xeb1f4dac ivtv_vapi_result +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xf5c94337 ivtv_init_on_first_open +EXPORT_SYMBOL drivers/media/video/ivtv/ivtv 0xfa0bb38e ivtv_udma_setup +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x04e83446 saa7134_tuner_callback +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x1211df5d saa7134_devlist +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x3d52c253 saa7134_dmasound_init +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x4db99a14 saa7134_ts_register +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x6cde5a42 saa7134_ts_unregister +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0x98af79c1 saa7134_boards +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb12de8be saa7134_pgtable_alloc +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb539df6b saa7134_set_dmabits +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xb6c0eca5 saa7134_i2c_call_clients +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xc7c3b07a saa7134_pgtable_build +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xceb910e3 saa7134_dmasound_exit +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xd89f2fc1 saa7134_set_gpio +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xdce94601 saa7134_tvaudio_setmute +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xedb1593b saa_dsp_writel +EXPORT_SYMBOL drivers/media/video/saa7134/saa7134 0xf9ff4952 saa7134_pgtable_free +EXPORT_SYMBOL drivers/media/video/soc_camera 0x007ad137 soc_camera_device_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0x51518a15 soc_camera_video_start +EXPORT_SYMBOL drivers/media/video/soc_camera 0x6d0666ca soc_camera_host_unregister +EXPORT_SYMBOL drivers/media/video/soc_camera 0xb452a2e4 soc_camera_device_register +EXPORT_SYMBOL drivers/media/video/soc_camera 0xbdec897e soc_camera_video_stop +EXPORT_SYMBOL drivers/media/video/soc_camera 0xf263ac37 soc_camera_host_register +EXPORT_SYMBOL drivers/media/video/tveeprom 0x1690b3c8 tveeprom_read +EXPORT_SYMBOL drivers/media/video/tveeprom 0x83cae89f tveeprom_hauppauge_analog +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x0d0b2da1 usbvideo_RegisterVideoDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x0dfd23fe usbvideo_Deregister +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x16a2915c RingQueue_Dequeue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x297bc6b5 usbvideo_DeinterlaceFrame +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x407a321c RingQueue_WakeUpInterruptible +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x7e2d191c usbvideo_TestPattern +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0x94ee644f usbvideo_AllocateDevice +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xca88aff4 usbvideo_register +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xddecac6d RingQueue_Enqueue +EXPORT_SYMBOL drivers/media/video/usbvideo/usbvideo 0xf5011f67 RingQueue_Flush +EXPORT_SYMBOL drivers/media/video/v4l1-compat 0x6f469c50 v4l_compat_translate_ioctl +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x03165a85 v4l2_ctrl_get_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x0dfb5e57 v4l2_prio_max +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x1c427ecb v4l2_ctrl_query_fill +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2de2b633 v4l2_prio_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x2e9a955d v4l2_prio_close +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x42c8e001 v4l2_ctrl_next +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x495426ee v4l2_ctrl_get_name +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x50766d69 v4l2_ctrl_query_menu_valid_items +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x57abfbd8 v4l2_chip_match_host +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x5fef1b4a v4l2_ctrl_query_fill_std +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x85440cea v4l2_i2c_attach +EXPORT_SYMBOL drivers/media/video/v4l2-common 0x942892ab v4l2_prio_open +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb2d1e17e v4l2_prio_change +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xb3758c6e v4l2_chip_ident_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xc369097d v4l2_ctrl_check +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd2894ef5 v4l2_chip_match_i2c_client +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xd464e760 v4l2_ctrl_query_menu +EXPORT_SYMBOL drivers/media/video/v4l2-common 0xe330bce9 v4l2_prio_init +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x34c080b8 videobuf_dvb_find_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x701f9958 videobuf_dvb_alloc_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0x8ce9b366 videobuf_dvb_get_frontend +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xc5a7d102 videobuf_dvb_unregister_bus +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xcf23894b videobuf_dvb_dealloc_frontends +EXPORT_SYMBOL drivers/media/video/videobuf-dvb 0xf751e685 videobuf_dvb_register_bus +EXPORT_SYMBOL drivers/media/video/videodev 0x123959a1 v4l2_type_names +EXPORT_SYMBOL drivers/media/video/videodev 0x3a5c5f8e video_register_device_index +EXPORT_SYMBOL drivers/media/video/videodev 0x3adbd595 v4l2_field_names +EXPORT_SYMBOL drivers/media/video/videodev 0x49cfb47c video_device_release +EXPORT_SYMBOL drivers/media/video/videodev 0x5ebefe4b v4l_printk_ioctl +EXPORT_SYMBOL drivers/media/video/videodev 0x97325554 video_device_alloc +EXPORT_SYMBOL drivers/media/video/videodev 0xaeb5335b video_device_release_empty +EXPORT_SYMBOL drivers/media/video/videodev 0xb1981559 video_unregister_device +EXPORT_SYMBOL drivers/media/video/videodev 0xbc0ec31e video_devdata +EXPORT_SYMBOL drivers/media/video/videodev 0xdbed55ac video_usercopy +EXPORT_SYMBOL drivers/media/video/videodev 0xe2b92059 v4l2_video_std_construct +EXPORT_SYMBOL drivers/media/video/videodev 0xf3251e7b v4l2_norm_to_name +EXPORT_SYMBOL drivers/media/video/videodev 0xf4ab57de video_register_device +EXPORT_SYMBOL drivers/media/video/videodev 0xf4dc31b7 __video_ioctl2 +EXPORT_SYMBOL drivers/media/video/videodev 0xf93a194b video_ioctl2 +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x3762dd30 videocodec_register +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x5aa1a02c videocodec_attach +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0x7d26cdd9 videocodec_unregister +EXPORT_SYMBOL drivers/media/video/zoran/videocodec 0xb15312b4 videocodec_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x03337386 mpt_alloc_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x04186eee mptbase_sas_persist_operation +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x0faa86a8 mpt_suspend +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x105d4f47 mpt_add_sge +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x1fd4520a mpt_free_fw_memory +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x26a16e53 mpt_print_ioc_summary +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x29020507 mpt_get_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x30f385c0 mpt_detach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x3737497f mpt_send_handshake_request +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4526289b mpt_event_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x4cc235f6 mpt_config +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x51387c0a mpt_put_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x57bc6003 mpt_attach +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x69682b92 mpt_free_msg_frame +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6c47b0d8 mpt_HardResetHandler +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x6e83a3c9 mpt_reset_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x729fae62 mpt_verify_adapter +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x7da11614 mpt_resume +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x88f9163b mpt_device_driver_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x94b67367 mpt_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x957a0862 mpt_event_register +EXPORT_SYMBOL drivers/message/fusion/mptbase 0x9ab8426e mpt_findImVolumes +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xab0a461c mpt_raid_phys_disk_pg0 +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc0e69f82 mpt_device_driver_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xc47c22e8 mpt_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd2c30974 mpt_GetIocState +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xd9a92a75 mpt_reset_deregister +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xdd805159 ioc_list +EXPORT_SYMBOL drivers/message/fusion/mptbase 0xe56585f1 mpt_put_msg_frame_hi_pri +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x03dbfc9d mptscsih_remove +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x198305c9 mptscsih_slave_destroy +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x2fd29758 mptscsih_bios_param +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x3eb15dc1 mptscsih_bus_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x5343f5a3 mptscsih_scandv_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x673465f9 mptscsih_taskmgmt_complete +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x67bf9095 mptscsih_suspend +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x68502b74 mptscsih_host_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x69cee3ac mptscsih_proc_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x724162ff mptscsih_is_phys_disk +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x74b4c2b3 mptscsih_abort +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x764ddf1a mptscsih_timer_expired +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x7c95522a mptscsih_host_attrs +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x8ef6ac13 mptscsih_slave_configure +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x94e6bdd1 mptscsih_raid_id_to_num +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0x99fe908b mptscsih_info +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xaedc6b0d mptscsih_change_queue_depth +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xca25b525 mptscsih_qcmd +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd116e2ad mptscsih_resume +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd8ee0896 mptscsih_io_done +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xd902c7a6 mptscsih_TMHandler +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xecf49c68 mptscsih_event_process +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xf8a92a81 mptscsih_ioc_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfc1b87f4 mptscsih_dev_reset +EXPORT_SYMBOL drivers/message/fusion/mptscsih 0xfd3e8e32 mptscsih_shutdown +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x02e531d2 i2o_parm_field_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1b4eb87f i2o_event_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x1e6386c7 i2o_status_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2a843bef i2o_dump_message +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x2b6e2695 i2o_device_claim +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x32b35498 i2o_driver_notify_device_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x44049f41 i2o_find_iop +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x44639581 i2o_iop_find_device +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x5957cc68 i2o_driver_notify_controller_remove_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x692dc3cf i2o_cntxt_list_remove +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x720b95b0 i2o_device_claim_release +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x80cae138 i2o_driver_register +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0x97d1531b i2o_parm_table_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xa7e63cf0 i2o_exec_lct_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xab766960 i2o_driver_notify_device_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xac2c3c2c i2o_driver_unregister +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xb4c00dcf i2o_controllers +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xc8b4e188 i2o_cntxt_list_get +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xd9f06a17 i2o_driver_notify_controller_add_all +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xdcc7b04d i2o_msg_get_wait +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe7c5a2a1 i2o_msg_post_wait_mem +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xe975ee0b i2o_cntxt_list_get_ptr +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xfa8b63be i2o_parm_issue +EXPORT_SYMBOL drivers/message/i2o/i2o_core 0xfaaca1bd i2o_cntxt_list_add +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0x8d8072bf pasic3_write_register +EXPORT_SYMBOL drivers/mfd/htc-pasic3 0xf2989247 pasic3_read_register +EXPORT_SYMBOL drivers/misc/c2port/core 0x61580116 c2port_device_unregister +EXPORT_SYMBOL drivers/misc/c2port/core 0x8efd8748 c2port_device_register +EXPORT_SYMBOL drivers/misc/ioc4 0x213544c6 ioc4_register_submodule +EXPORT_SYMBOL drivers/misc/ioc4 0x4a1b4db2 ioc4_unregister_submodule +EXPORT_SYMBOL drivers/misc/sony-laptop 0x5bb1e117 sony_pic_camera_command +EXPORT_SYMBOL drivers/misc/tifm_core 0x13288034 tifm_register_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x479b4d60 tifm_unregister_driver +EXPORT_SYMBOL drivers/misc/tifm_core 0x4c569de9 tifm_alloc_device +EXPORT_SYMBOL drivers/misc/tifm_core 0x523a43ff tifm_has_ms_pif +EXPORT_SYMBOL drivers/misc/tifm_core 0x587d36e8 tifm_remove_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x6da5888b tifm_free_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0x8e596611 tifm_eject +EXPORT_SYMBOL drivers/misc/tifm_core 0xa71353f0 tifm_free_device +EXPORT_SYMBOL drivers/misc/tifm_core 0xa8c2ec46 tifm_queue_work +EXPORT_SYMBOL drivers/misc/tifm_core 0xb3193714 tifm_add_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xcfd04908 tifm_map_sg +EXPORT_SYMBOL drivers/misc/tifm_core 0xd18a9482 tifm_alloc_adapter +EXPORT_SYMBOL drivers/misc/tifm_core 0xda9626db tifm_unmap_sg +EXPORT_SYMBOL drivers/mmc/card/mmc_block 0x17314b93 mmc_cleanup_queue +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0x6e9be3cb cfi_fixup +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xcb1ee961 cfi_read_pri +EXPORT_SYMBOL drivers/mtd/chips/cfi_util 0xe012f0f1 cfi_varsize_frob +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x14087773 unregister_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0x25bbe5aa register_mtd_chip_driver +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xadcf4d3a map_destroy +EXPORT_SYMBOL drivers/mtd/chips/chipreg 0xd2cda739 do_map_probe +EXPORT_SYMBOL drivers/mtd/chips/gen_probe 0x60064125 mtd_do_chip_probe +EXPORT_SYMBOL drivers/mtd/maps/map_funcs 0x2bb097e1 simple_map_init +EXPORT_SYMBOL drivers/mtd/mtd 0x7756c0a5 add_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtd 0xbaf734c8 del_mtd_partitions +EXPORT_SYMBOL drivers/mtd/mtdconcat 0x046812fa mtd_concat_destroy +EXPORT_SYMBOL drivers/mtd/mtdconcat 0xf64b8bfa mtd_concat_create +EXPORT_SYMBOL drivers/mtd/nand/nand 0x048072b9 nand_scan_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand 0xc09627f4 nand_default_bbt +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0x4aa2274e nand_calculate_ecc +EXPORT_SYMBOL drivers/mtd/nand/nand_ecc 0xb779cfd9 nand_correct_data +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0x836bdb72 nand_flash_ids +EXPORT_SYMBOL drivers/mtd/nand/nand_ids 0xa336feb7 nand_manuf_ids +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0x4b7c4d6d onenand_default_bbt +EXPORT_SYMBOL drivers/mtd/onenand/onenand 0xd2ee8327 onenand_scan_bbt +EXPORT_SYMBOL drivers/net/8390 0x01f2f66c ei_poll +EXPORT_SYMBOL drivers/net/8390 0x430ecaf8 __alloc_ei_netdev +EXPORT_SYMBOL drivers/net/8390 0x7d7e0dbc ei_interrupt +EXPORT_SYMBOL drivers/net/8390 0x85d9f5e1 NS8390_init +EXPORT_SYMBOL drivers/net/8390 0xb2d94754 ei_close +EXPORT_SYMBOL drivers/net/8390 0xb5aacd24 ei_open +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x44578575 arc_raw_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4641bd7d arcnet_interrupt +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x4f4f6fb7 arc_proto_default +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x6534792a arcnet_debug +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x711cba15 arc_bcast_proto +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x7ae1f9b7 arc_proto_map +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x868e1fdf alloc_arcdev +EXPORT_SYMBOL drivers/net/arcnet/arcnet 0x89d26a69 arcnet_unregister_proto +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xa84f0ce2 com20020_check +EXPORT_SYMBOL drivers/net/arcnet/com20020 0xac0c6866 com20020_found +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x0b879f3c cxgb3_free_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x1485ed18 dev2t3cdev +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x15c3ebce cxgb3_alloc_atid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x2ee3d53f cxgb3_register_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x3a01f06c cxgb3_alloc_stid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x6e26251f t3_l2t_send_event +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x7cae4e14 t3_l2e_free +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x88212784 t3_register_cpl_handler +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8a911a55 cxgb3_insert_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0x8d9d51c0 cxgb3_ofld_send +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xa9043926 cxgb3_queue_tid_release +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xac40f7d3 t3_l2t_send_slow +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xb6ae4892 cxgb3_remove_tid +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xbaec17d3 t3_l2t_get +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xe2bf58ff cxgb3_unregister_client +EXPORT_SYMBOL drivers/net/cxgb3/cxgb3 0xf06e258b cxgb3_free_atid +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x243033f6 hdlcdrv_unregister +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x30d5f471 hdlcdrv_arbitrate +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0x5a70a07b hdlcdrv_register +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xb892355d hdlcdrv_transmitter +EXPORT_SYMBOL drivers/net/hamradio/hdlcdrv 0xc8db23bf hdlcdrv_receiver +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x0f23e0f5 sirdev_set_dtr_rts +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x452343a8 sirdev_get_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x560753a0 sirdev_write_complete +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x6025bc52 sirdev_raw_write +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x6d4d2dd6 irda_register_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x738a80ed sirdev_receive +EXPORT_SYMBOL drivers/net/irda/sir-dev 0x817e1bbc sirdev_put_instance +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xb1b071ea sirdev_raw_read +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xb4389d15 irda_unregister_dongle +EXPORT_SYMBOL drivers/net/irda/sir-dev 0xec563aa1 sirdev_set_dongle +EXPORT_SYMBOL drivers/net/mii 0x0d0b49df mii_check_link +EXPORT_SYMBOL drivers/net/mii 0x14780d20 mii_nway_restart +EXPORT_SYMBOL drivers/net/mii 0x2278eb66 mii_check_gmii_support +EXPORT_SYMBOL drivers/net/mii 0x351b7c17 mii_ethtool_gset +EXPORT_SYMBOL drivers/net/mii 0x39c4e24e mii_check_media +EXPORT_SYMBOL drivers/net/mii 0x5ade8469 generic_mii_ioctl +EXPORT_SYMBOL drivers/net/mii 0xe529560d mii_ethtool_sset +EXPORT_SYMBOL drivers/net/mii 0xf7543166 mii_link_ok +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0x70dc209c free_mdio_bitbang +EXPORT_SYMBOL drivers/net/phy/mdio-bitbang 0xff804612 alloc_mdio_bitbang +EXPORT_SYMBOL drivers/net/pppox 0x6e4e49dd register_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xcb4e828e pppox_ioctl +EXPORT_SYMBOL drivers/net/pppox 0xe0ff7a18 unregister_pppox_proto +EXPORT_SYMBOL drivers/net/pppox 0xe42c8acd pppox_unbind_sock +EXPORT_SYMBOL drivers/net/sungem_phy 0x6c6b8091 mii_phy_probe +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x10aabcdd tmsdev_term +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x518fcbfb tms380tr_interrupt +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x726ef1d2 tmsdev_init +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0x73da2224 tms380tr_open +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xb21f37bb tms380tr_close +EXPORT_SYMBOL drivers/net/tokenring/tms380tr 0xd2328794 tms380tr_wait +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x38da4725 cycx_intr +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x62be23ea cycx_setup +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x66a4c4e6 cycx_down +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0x968458a6 cycx_peek +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xb6f383de cycx_poke +EXPORT_SYMBOL drivers/net/wan/cycx_drv 0xfe7cd576 cycx_exec +EXPORT_SYMBOL drivers/net/wan/hdlc 0x02beffba alloc_hdlcdev +EXPORT_SYMBOL drivers/net/wan/hdlc 0x29a8a9e6 unregister_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x5495abdb detach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0x890562a3 hdlc_open +EXPORT_SYMBOL drivers/net/wan/hdlc 0x97534d12 register_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xc3a64c26 hdlc_close +EXPORT_SYMBOL drivers/net/wan/hdlc 0xd5f50fc4 attach_hdlc_protocol +EXPORT_SYMBOL drivers/net/wan/hdlc 0xde91ced4 unregister_hdlc_device +EXPORT_SYMBOL drivers/net/wan/hdlc 0xffbedea6 hdlc_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x1f58396c sppp_open +EXPORT_SYMBOL drivers/net/wan/syncppp 0x6bb186be sppp_do_ioctl +EXPORT_SYMBOL drivers/net/wan/syncppp 0x82ec86f1 sppp_detach +EXPORT_SYMBOL drivers/net/wan/syncppp 0x8a0829c2 sppp_reopen +EXPORT_SYMBOL drivers/net/wan/syncppp 0xca747c02 sppp_close +EXPORT_SYMBOL drivers/net/wan/syncppp 0xe1248617 sppp_attach +EXPORT_SYMBOL drivers/net/wireless/airo 0x76e7f2e0 stop_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xccdb682f reset_airo_card +EXPORT_SYMBOL drivers/net/wireless/airo 0xf2d5dc57 init_airo_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0x47a45c8d atmel_open +EXPORT_SYMBOL drivers/net/wireless/atmel 0x6d0909f1 stop_atmel_card +EXPORT_SYMBOL drivers/net/wireless/atmel 0xc09eecbe init_atmel_card +EXPORT_SYMBOL drivers/net/wireless/hermes 0x4196c38b hermes_write_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xa031d8e4 hermes_doicmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xc60b5e9e hermes_bap_pwrite +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd38d8ae2 hermes_read_ltv +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd3f714e5 hermes_bap_pread +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5168829 hermes_allocate +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd5336e5d hermes_init +EXPORT_SYMBOL drivers/net/wireless/hermes 0xd54e219d hermes_docmd_wait +EXPORT_SYMBOL drivers/net/wireless/hermes 0xed47b224 hermes_struct_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x161a199c hermes_program +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x2e340491 hermesi_program_end +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x3e7d91b2 hermesi_program_init +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0x79a2030e hermes_read_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xc4026a52 hermes_apply_pda +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xcbd49cae hermes_apply_pda_with_defaults +EXPORT_SYMBOL drivers/net/wireless/hermes_dld 0xeb824e25 hermes_blocks_length +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x0b9a6277 hostap_set_antsel +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x162165b3 prism2_update_comms_qual +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1723ac32 hostap_set_multicast_list_queue +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x18fdb875 hostap_get_stats +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x1cef48be hostap_init_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x20893968 hostap_setup_dev +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x20bc7c22 hostap_set_string +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x279a2f45 hostap_80211_rx +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x30486678 hostap_info_process +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x3890733e hostap_info_init +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x4726cd9e hostap_set_encryption +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x563eb543 hostap_free_data +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x60a31486 hostap_master_start_xmit +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x63c1a373 hostap_80211_ops +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x69000d93 hostap_init_ap_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x6903f16c hostap_80211_get_hdrlen +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x70e7bbbd hostap_set_auth_algs +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x7d16a1f8 hostap_set_hostapd +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x87057bf4 hostap_add_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8a775075 hostap_set_word +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8af1f3d6 hostap_check_sta_fw_version +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x8f9248ea hostap_init_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0x949556d6 hostap_set_hostapd_sta +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xa12ad27f hostap_dump_tx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb2a945e0 hostap_dump_rx_header +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb81f7343 hostap_remove_proc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xb87cb543 hostap_handle_sta_tx_exc +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf40eb4e6 hostap_remove_interface +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf5a0512d hostap_set_roaming +EXPORT_SYMBOL drivers/net/wireless/hostap/hostap 0xf5c4d747 hostap_get_porttype +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x00b4cbc7 iwl_rfkill_set_hw_state +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x029ea41e iwl_init_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x04f5e005 iwl_rx_missed_beacon_notif +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x09fbd3a3 iwl_rx_queue_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0af8ade2 iwl_dump_nic_event_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0b607ef2 iwl_rx_statistics +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x0cc386b7 iwlcore_eeprom_acquire_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x133ee5f2 iwl_send_lq_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x19bf4ec1 iwlcore_eeprom_verify_signature +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x1d77b399 iwl_bcast_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x203b991d iwl_send_cmd_pdu +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x21017036 iwl_send_statistics_request +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x22670d78 iwl_tx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x23692254 iwl_set_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2408d9b2 iwl_alloc_all +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2bf91e35 iwl_init_sensitivity +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x2d490587 iwl_is_fat_tx_allowed +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3244d8fd iwl_scan_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x349093eb iwl_set_rxon_ht +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x36e42206 iwl_power_enable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x3786d444 iwl_power_update_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x384f22d2 iwl_power_set_system_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x45dbdda3 iwl_set_rxon_chain +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x45fff929 iwl_rx_queue_restock +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x46d82df0 iwl_radio_kill_sw_disable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x49f12938 iwl_power_initialize +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4a189256 iwl_reset_qos +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x4dda9ec1 iwl_rx_reply_rx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50cdf051 iwl_eeprom_query16 +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x50f72c5d iwl_power_set_user_mode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x513e8f74 iwl_eeprom_get_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x58070b7c iwl_rxq_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x58577c30 iwl_power_cancel_timeout +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5a2ebf22 iwl_radio_kill_sw_enable_radio +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5b56fe2b iwl_hwrate_to_tx_control +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5c59811b iwl_setup_mac +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x5ea6f9ab iwl_rx_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x60774702 iwl_queue_space +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x620ee33c iwl_rx_allocate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x65c159b0 iwl_tx_skb +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x66ec2637 iwl_rx_reply_rx_phy +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x680d1efd iwl_get_ra_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x68be5273 iwl_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x69187843 iwl_set_rxon_channel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6c7f3073 iwl_hw_detect +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6d9d1e6d iwl_send_add_sta +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6e16ff25 iwl_rf_kill_ct_config +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x6ed5e34b iwl_hw_nic_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x73a96638 iwl_remove_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7672435e iwl_set_hw_params +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x78b6694c iwlcore_eeprom_release_semaphore +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x7fdef185 iwl_sensitivity_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x81742f1a iwl_setup_power_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8670273d iwl_hwrate_to_plcp_idx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8751c872 iwl_rx_queue_alloc +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x887a3982 iwl_sta_modify_enable_tid_tx +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8c57cfbe iwl_send_static_wepkey_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x8fb5242e iwl_send_calib_results +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x91bd4bde iwl_rx_replenish +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9452e4d4 iwl_set_tx_power +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9516977b iwl_send_cmd_sync +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9971bcb8 iwl_scan_initiate +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9a5b2923 iwl_leds_register +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9b38acb2 iwl_rx_queue_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9f943e14 iwl_rxon_add_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0x9faced57 iwl_calib_set +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa398909e iwl_set_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa633a23a iwl_get_sta_id +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xa95ce5c2 iwl_init_channel_map +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xaf95ef6c iwl_leds_background +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb26cfc87 iwl_scan_cancel +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb3c73a71 iwl_rx_agg_start +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb667156c iwl_get_channel_info +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xb8870094 iwl_rx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc217c721 iwl_remove_dynamic_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc47b95b7 iwl_verify_ucode +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc6ece9aa iwl_setup_rx_scan_handlers +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xc862437e iwl_uninit_drv +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xca2ad44f iwl_tx_queue_reclaim +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcad7e242 iwlcore_eeprom_query_addr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcaf1bd96 iwl_txq_check_empty +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcb7abdf6 iwl_find_station +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcbaf4931 get_cmd_string +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xceb812c4 iwl_txq_ctx_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xcfc3fad8 iwl_send_cmd_pdu_async +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd1a829e0 iwl_clear_stations_table +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd3e5fdd5 iwl_remove_default_wep_key +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd4762469 iwl_power_temperature_change +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd56f7f34 iwl_eeprom_check_version +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd646fb38 iwl_tx_cmd_complete +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd6b38bba iwl_rx_reply_compressed_ba +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd6d305fd iwl_chain_noise_calibration +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xd86372dc iwl_reset_run_time_calib +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xda67de82 iwl_leds_unregister +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdabb757c iwl_eeprom_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xdc94b17b iwl_send_cmd +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe1ad9e55 iwl_setup_scan_deferred_work +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe246f32f iwl_txq_update_write_ptr +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe2f4e259 iwl_dump_nic_error_log +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe5d48e88 iwl_power_disable_management +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe76a87f9 iwl_add_station_flags +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xe7ce5d70 iwl_rates +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xea678353 iwl_hw_txq_ctx_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec3525aa iwl_rx_queue_reset +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xec723c20 iwl_rfkill_init +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xed26b188 iwl_tx_agg_stop +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xee6c199a iwl_eeprom_free +EXPORT_SYMBOL drivers/net/wireless/iwlwifi/iwlcore 0xfc097269 iwl_rfkill_unregister +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x081f289c __orinoco_down +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x1a9d334a orinoco_interrupt +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x3c828441 alloc_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x6d109184 free_orinocodev +EXPORT_SYMBOL drivers/net/wireless/orinoco 0x76c13b5a orinoco_reinit_firmware +EXPORT_SYMBOL drivers/net/wireless/orinoco 0xfea52ac5 __orinoco_up +EXPORT_SYMBOL drivers/parport/parport 0x0218cd30 parport_set_timeout +EXPORT_SYMBOL drivers/parport/parport 0x0649c985 parport_put_port +EXPORT_SYMBOL drivers/parport/parport 0x121501f0 parport_ieee1284_epp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x1358f7cf parport_ieee1284_ecp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x1dbe8d84 parport_irq_handler +EXPORT_SYMBOL drivers/parport/parport 0x27a59632 parport_ieee1284_write_compat +EXPORT_SYMBOL drivers/parport/parport 0x280213d9 parport_ieee1284_read_byte +EXPORT_SYMBOL drivers/parport/parport 0x2d8a86ed parport_wait_event +EXPORT_SYMBOL drivers/parport/parport 0x4b6dcdbe parport_register_device +EXPORT_SYMBOL drivers/parport/parport 0x4d2a941b parport_ieee1284_interrupt +EXPORT_SYMBOL drivers/parport/parport 0x52665f44 parport_release +EXPORT_SYMBOL drivers/parport/parport 0x5bacab77 parport_wait_peripheral +EXPORT_SYMBOL drivers/parport/parport 0x6391b648 parport_announce_port +EXPORT_SYMBOL drivers/parport/parport 0x6c866812 parport_ieee1284_epp_write_addr +EXPORT_SYMBOL drivers/parport/parport 0x6dcb9e2d parport_ieee1284_ecp_write_data +EXPORT_SYMBOL drivers/parport/parport 0x6ee52af6 parport_remove_port +EXPORT_SYMBOL drivers/parport/parport 0x8ae3f27b parport_unregister_device +EXPORT_SYMBOL drivers/parport/parport 0x8bd666c0 parport_ieee1284_read_nibble +EXPORT_SYMBOL drivers/parport/parport 0x9e95230b parport_register_driver +EXPORT_SYMBOL drivers/parport/parport 0xa74ba9b2 parport_unregister_driver +EXPORT_SYMBOL drivers/parport/parport 0xa8453476 parport_ieee1284_epp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xa9d55575 parport_find_number +EXPORT_SYMBOL drivers/parport/parport 0xc30479dd parport_ieee1284_ecp_read_data +EXPORT_SYMBOL drivers/parport/parport 0xd128bdbf parport_read +EXPORT_SYMBOL drivers/parport/parport 0xd37be8dd parport_register_port +EXPORT_SYMBOL drivers/parport/parport 0xdb3ef6c1 parport_ieee1284_epp_read_addr +EXPORT_SYMBOL drivers/parport/parport 0xea374aef parport_find_base +EXPORT_SYMBOL drivers/parport/parport 0xeba9d0d0 parport_write +EXPORT_SYMBOL drivers/parport/parport 0xf0b96358 parport_claim +EXPORT_SYMBOL drivers/parport/parport 0xf3ce8c7e parport_claim_or_block +EXPORT_SYMBOL drivers/parport/parport 0xf6ad155f parport_get_port +EXPORT_SYMBOL drivers/parport/parport 0xfbbf186b parport_negotiate +EXPORT_SYMBOL drivers/parport/parport_pc 0x6483beb2 parport_pc_unregister_port +EXPORT_SYMBOL drivers/parport/parport_pc 0xf5c67f4e parport_pc_probe_port +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x044c0b21 pcmcia_request_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x3ad47365 pcmcia_release_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x3c8a3855 pcmcia_loop_config +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x3da78356 pcmcia_request_io +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x4fd033a0 pcmcia_error_func +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x799082c4 pcmcia_dev_present +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x980a440e pcmcia_map_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x9c18d752 pcmcia_get_window +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0x9e8244ce pcmcia_access_configuration_register +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xa298ed51 pcmcia_register_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb033e7a6 pcmcia_request_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xb25a0347 pcmcia_modify_configuration +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xbff8c39f pcmcia_get_mem_page +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xce18f57b pcmcia_unregister_driver +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xda494283 pcmcia_request_irq +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xdf6e7b3b pcmcia_disable_device +EXPORT_SYMBOL drivers/pcmcia/pcmcia 0xf0a25e12 pcmcia_error_ret +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x02f8058d pccard_get_next_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x035a75ff destroy_cis_cache +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x03ee0008 pcmcia_register_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x0eff5a3a pccard_get_tuple_data +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x12382e9f pcmcia_insert_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x125112fa pcmcia_read_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x212db8d2 pcmcia_socket_list +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x248bfd1d pcmcia_get_socket_by_nr +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2dc9b21f release_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x2e7dc57a pcmcia_put_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x30e8c5bf pcmcia_socket_class +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x42f2631a pcmcia_socket_dev_resume +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x4435b0b9 pccard_validate_cis +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x5913a5e4 pcmcia_parse_events +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x599bbc04 pccard_read_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x6f6e1822 pcmcia_unregister_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x7e679582 pcmcia_find_mem_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x84d9c4c6 pcmcia_eject_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0x8f0807c8 pcmcia_reset_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa45c5cb8 pccard_get_first_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa71add6e pcmcia_suspend_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xa8df65b6 pcmcia_socket_list_rwsem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb00a692e pcmcia_get_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb41c0b5c pcmcia_resume_card +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb85aadf9 pcmcia_adjust_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xb85cb926 pcmcia_socket_dev_suspend +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xc02ef2c8 pcmcia_parse_tuple +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xcf97f3bd dead_socket +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd24f1bb6 pcmcia_write_cis_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd33e53c9 pcmcia_find_io_region +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xd5e4dd93 pccard_register_pcmcia +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xdddf8b02 pcmcia_validate_mem +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xe06ab998 pccard_static_ops +EXPORT_SYMBOL drivers/pcmcia/pcmcia_core 0xefc47ae3 pcmcia_replace_cis +EXPORT_SYMBOL drivers/pcmcia/rsrc_nonstatic 0x5feb83a3 pccard_nonstatic_ops +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x2250c66e mraid_mm_adapter_app_handle +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0x512c956d mraid_mm_unregister_adp +EXPORT_SYMBOL drivers/scsi/megaraid/megaraid_mm 0xede2fc3b mraid_mm_register_adp +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x15f6c874 qlogicfas408_info +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x3fd8cd71 qlogicfas408_detect +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5666e559 qlogicfas408_biosparam +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x5cd179e6 qlogicfas408_ihandl +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x64cf012e qlogicfas408_disable_ints +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x775afc49 qlogicfas408_abort +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0x95bac046 qlogicfas408_queuecommand +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xda8e3ae5 qlogicfas408_bus_reset +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xe76b3b20 qlogicfas408_get_chip_type +EXPORT_SYMBOL drivers/scsi/qlogicfas408 0xf2b95199 qlogicfas408_setup +EXPORT_SYMBOL drivers/scsi/raid_class 0x0dc57d18 raid_class_attach +EXPORT_SYMBOL drivers/scsi/raid_class 0xc5563359 raid_component_add +EXPORT_SYMBOL drivers/scsi/raid_class 0xe0bf0663 raid_class_release +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x10c00f59 fc_remote_port_rolechg +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x1d4e448e fc_vport_terminate +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x2e043bc4 scsi_is_fc_vport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x3d67ab72 fc_remote_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x62ebb53f fc_vport_create +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x6c000492 fc_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x77d175c0 fc_host_post_vendor_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7954b1ea fc_get_event_number +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x7c6174f2 fc_host_post_event +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0x961ada1a fc_remote_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xba5acaa8 scsi_is_fc_rport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xcafda9cc fc_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_fc 0xe32bc6cf fc_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x08c07e10 sas_port_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1a095fca sas_remove_children +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x1cac7425 sas_phy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x288707a9 sas_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x3618098c scsi_is_sas_port +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x381d0afa sas_port_delete_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x3fc59649 scsi_is_sas_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x458292f7 sas_port_mark_backlink +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x4b6b549a sas_rphy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x549aac81 sas_rphy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x5a467155 sas_port_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x644eba08 sas_port_alloc_num +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x6a6c2d17 sas_rphy_remove +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x75f28d70 sas_rphy_delete +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x8030b71c sas_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x95c48265 sas_remove_host +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0x99e34eee sas_read_port_mode_page +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xae3654d8 sas_end_device_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xb537ea1f sas_phy_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xba7faaee sas_port_add +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xbacd035b sas_phy_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xbef8d0c7 sas_expander_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc1003102 sas_phy_free +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xc5c1c5bf sas_port_add_phy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xf429169a scsi_is_sas_rphy +EXPORT_SYMBOL drivers/scsi/scsi_transport_sas 0xffad1e35 sas_port_alloc +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x04498940 spi_dv_device +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x23e00bdd spi_display_xfer_agreement +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x3686ea09 spi_print_msg +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x52afaa8d spi_release_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0x546aa1f6 spi_attach_transport +EXPORT_SYMBOL drivers/scsi/scsi_transport_spi 0xbda98451 spi_schedule_dv_device +EXPORT_SYMBOL drivers/ssb/ssb 0x0afc1c1c ssb_dma_translation +EXPORT_SYMBOL drivers/ssb/ssb 0x1bc66f60 ssb_pcihost_register +EXPORT_SYMBOL drivers/ssb/ssb 0x2168a3db ssb_device_enable +EXPORT_SYMBOL drivers/ssb/ssb 0x221580d0 __ssb_driver_register +EXPORT_SYMBOL drivers/ssb/ssb 0x3f440019 ssb_bus_pcibus_register +EXPORT_SYMBOL drivers/ssb/ssb 0x4c921c03 ssb_device_disable +EXPORT_SYMBOL drivers/ssb/ssb 0x5ace0c95 ssb_set_devtypedata +EXPORT_SYMBOL drivers/ssb/ssb 0x65c3fb0b ssb_driver_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0x87adfe51 ssb_bus_suspend +EXPORT_SYMBOL drivers/ssb/ssb 0x8f197b01 ssb_dma_alloc_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x90e11565 ssb_dma_free_consistent +EXPORT_SYMBOL drivers/ssb/ssb 0x92e0d08a ssb_device_is_enabled +EXPORT_SYMBOL drivers/ssb/ssb 0xa2363ca0 ssb_bus_resume +EXPORT_SYMBOL drivers/ssb/ssb 0xb20becbe ssb_clockspeed +EXPORT_SYMBOL drivers/ssb/ssb 0xb2970c40 ssb_bus_may_powerdown +EXPORT_SYMBOL drivers/ssb/ssb 0xb322d03d ssb_dma_set_mask +EXPORT_SYMBOL drivers/ssb/ssb 0xc0512e0f ssb_admatch_base +EXPORT_SYMBOL drivers/ssb/ssb 0xd481192b ssb_admatch_size +EXPORT_SYMBOL drivers/ssb/ssb 0xdaacf0c0 ssb_bus_unregister +EXPORT_SYMBOL drivers/ssb/ssb 0xe0e7985a ssb_bus_powerup +EXPORT_SYMBOL drivers/ssb/ssb 0xe351c81d ssb_pcicore_dev_irqvecs_enable +EXPORT_SYMBOL drivers/telephony/ixj 0x20e3d9d0 ixj_pcmcia_probe +EXPORT_SYMBOL drivers/telephony/phonedev 0x5b6f6d79 phone_unregister_device +EXPORT_SYMBOL drivers/telephony/phonedev 0xb6c52ce9 phone_register_device +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x23e3c4b5 usb_gadget_unregister_driver +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x5413aab3 usb_gadget_register_driver +EXPORT_SYMBOL drivers/usb/gadget/net2280 0x800a17a8 net2280_set_fifo_mode +EXPORT_SYMBOL drivers/usb/host/sl811-hcd 0xa64d0663 sl811h_driver +EXPORT_SYMBOL drivers/video/backlight/corgi_bl 0xc86baa7c corgibl_limit_intensity +EXPORT_SYMBOL drivers/video/backlight/lcd 0x1c63be7d lcd_device_unregister +EXPORT_SYMBOL drivers/video/backlight/lcd 0x5d9bca00 lcd_device_register +EXPORT_SYMBOL drivers/video/console/bitblit 0xfedea34a fbcon_set_bitops +EXPORT_SYMBOL drivers/video/console/font 0x09c8eb55 font_vga_8x16 +EXPORT_SYMBOL drivers/video/console/font 0xbb99125c get_default_font +EXPORT_SYMBOL drivers/video/console/font 0xf7584a9c find_font +EXPORT_SYMBOL drivers/video/console/softcursor 0x38e63574 soft_cursor +EXPORT_SYMBOL drivers/video/console/tileblit 0xfa6b2f0f fbcon_set_tileops +EXPORT_SYMBOL drivers/video/cyber2000fb 0x0cc3ede5 cyber2000fb_detach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x5100a206 cyber2000fb_disable_extregs +EXPORT_SYMBOL drivers/video/cyber2000fb 0x54ea6ef8 cyber2000fb_get_fb_var +EXPORT_SYMBOL drivers/video/cyber2000fb 0x72c495c5 cyber2000fb_attach +EXPORT_SYMBOL drivers/video/cyber2000fb 0x8631248c cyber2000fb_enable_extregs +EXPORT_SYMBOL drivers/video/display/display 0x2137b5f4 display_device_unregister +EXPORT_SYMBOL drivers/video/display/display 0xac53975d display_device_register +EXPORT_SYMBOL drivers/video/macmodes 0x08ed0b62 mac_vmode_to_var +EXPORT_SYMBOL drivers/video/macmodes 0x1be1b159 mac_find_mode +EXPORT_SYMBOL drivers/video/macmodes 0xe2304303 mac_map_monitor_sense +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x5c701b36 g450_mnp2f +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x7c23a93f matroxfb_g450_setclk +EXPORT_SYMBOL drivers/video/matrox/g450_pll 0x8edca8de matroxfb_g450_setpll_cond +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x5388d5aa DAC1064_global_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0x8eb68ae8 matrox_mystique +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xbe103682 DAC1064_global_restore +EXPORT_SYMBOL drivers/video/matrox/matroxfb_DAC1064 0xf8be559c matrox_G100 +EXPORT_SYMBOL drivers/video/matrox/matroxfb_Ti3026 0xc816b32d matrox_millennium +EXPORT_SYMBOL drivers/video/matrox/matroxfb_accel 0x704a8af7 matrox_cfbX_init +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0x000cb93a matroxfb_wait_for_sync +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xa00ce4a6 matroxfb_register_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xa48e5544 matroxfb_unregister_driver +EXPORT_SYMBOL drivers/video/matrox/matroxfb_base 0xf4571ace matroxfb_enable_irq +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x9645a5e9 matroxfb_g450_shutdown +EXPORT_SYMBOL drivers/video/matrox/matroxfb_g450 0x9cb8fe7d matroxfb_g450_connect +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x09c1e2ca matroxfb_vgaHWinit +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x25cf8049 matroxfb_PLL_calcclock +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x6fbcdf3e matroxfb_read_pins +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x8fee172f matroxfb_DAC_out +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0x9a8a0f73 matroxfb_DAC_in +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xabd8e427 matroxfb_var2my +EXPORT_SYMBOL drivers/video/matrox/matroxfb_misc 0xce44db56 matroxfb_vgaHWrestore +EXPORT_SYMBOL drivers/video/output 0x8a205396 video_output_register +EXPORT_SYMBOL drivers/video/output 0xfbbaabdc video_output_unregister +EXPORT_SYMBOL drivers/video/sis/sisfb 0x3037658e sis_malloc +EXPORT_SYMBOL drivers/video/sis/sisfb 0x454a3cf0 sis_free +EXPORT_SYMBOL drivers/video/svgalib 0x00d1fce9 svga_set_default_seq_regs +EXPORT_SYMBOL drivers/video/svgalib 0x07b3da30 svga_wseq_multi +EXPORT_SYMBOL drivers/video/svgalib 0x1b95c56a svga_check_timings +EXPORT_SYMBOL drivers/video/svgalib 0x3da4a575 svga_get_caps +EXPORT_SYMBOL drivers/video/svgalib 0x46c77568 svga_tilecursor +EXPORT_SYMBOL drivers/video/svgalib 0x63e898d1 svga_set_default_crt_regs +EXPORT_SYMBOL drivers/video/svgalib 0x7a3ae959 svga_wcrt_multi +EXPORT_SYMBOL drivers/video/svgalib 0x80408443 svga_set_timings +EXPORT_SYMBOL drivers/video/svgalib 0x8fa8438b svga_set_textmode_vga_regs +EXPORT_SYMBOL drivers/video/svgalib 0xa94cf78b svga_get_tilemax +EXPORT_SYMBOL drivers/video/svgalib 0xab3b22ad svga_set_default_gfx_regs +EXPORT_SYMBOL drivers/video/svgalib 0xd9422b1b svga_settile +EXPORT_SYMBOL drivers/video/svgalib 0xdad682b1 svga_set_default_atc_regs +EXPORT_SYMBOL drivers/video/svgalib 0xe9688576 svga_tileblit +EXPORT_SYMBOL drivers/video/svgalib 0xeb8cd4cd svga_tilecopy +EXPORT_SYMBOL drivers/video/svgalib 0xec83c473 svga_match_format +EXPORT_SYMBOL drivers/video/svgalib 0xef774f5d svga_compute_pll +EXPORT_SYMBOL drivers/video/svgalib 0xf469d55a svga_tilefill +EXPORT_SYMBOL drivers/video/syscopyarea 0x4c48a27b sys_copyarea +EXPORT_SYMBOL drivers/video/sysfillrect 0x48c51b69 sys_fillrect +EXPORT_SYMBOL drivers/video/sysimgblt 0x3b7d8c46 sys_imageblit +EXPORT_SYMBOL drivers/video/vgastate 0x686de290 restore_vga +EXPORT_SYMBOL drivers/video/vgastate 0xe7a2620e save_vga +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0x12a2face w1_bq27000_write +EXPORT_SYMBOL drivers/w1/slaves/w1_bq27000 0xed142032 w1_bq27000_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0x1597cae7 w1_ds2760_read +EXPORT_SYMBOL drivers/w1/slaves/w1_ds2760 0xaaa7c65c w1_ds2760_write +EXPORT_SYMBOL drivers/w1/wire 0x14e6edbe w1_remove_master_device +EXPORT_SYMBOL drivers/w1/wire 0x1852edb2 w1_add_master_device +EXPORT_SYMBOL drivers/w1/wire 0xa5bcb89a w1_register_family +EXPORT_SYMBOL drivers/w1/wire 0xb24549c5 w1_unregister_family +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x04e133fc iTCO_vendor_check_noreboot_on +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0x672c9d44 iTCO_vendor_pre_keepalive +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa78bd894 iTCO_vendor_pre_set_heartbeat +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xa8d6daac iTCO_vendor_pre_start +EXPORT_SYMBOL drivers/watchdog/iTCO_vendor_support 0xd0efe320 iTCO_vendor_pre_stop +EXPORT_SYMBOL fs/configfs/configfs 0x16398583 configfs_depend_item +EXPORT_SYMBOL fs/configfs/configfs 0x19ebf19b config_item_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0x5399c7f3 config_item_init +EXPORT_SYMBOL fs/configfs/configfs 0x59c48d4f configfs_undepend_item +EXPORT_SYMBOL fs/configfs/configfs 0x9f906c69 configfs_register_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xa0f6c135 config_item_put +EXPORT_SYMBOL fs/configfs/configfs 0xa1cf56cf config_group_init_type_name +EXPORT_SYMBOL fs/configfs/configfs 0xa750e5d9 config_group_find_item +EXPORT_SYMBOL fs/configfs/configfs 0xd45a6ca6 config_item_set_name +EXPORT_SYMBOL fs/configfs/configfs 0xda34f9e0 configfs_unregister_subsystem +EXPORT_SYMBOL fs/configfs/configfs 0xf166c617 config_item_get +EXPORT_SYMBOL fs/configfs/configfs 0xf8da3fd7 config_group_init +EXPORT_SYMBOL fs/lockd/lockd 0xa7b91a7b lockd_down +EXPORT_SYMBOL fs/lockd/lockd 0xc4ec2c71 nlmsvc_ops +EXPORT_SYMBOL fs/lockd/lockd 0xf6933c48 lockd_up +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x34510db0 nfsacl_encode +EXPORT_SYMBOL fs/nfs_common/nfs_acl 0x9a9ea58f nfsacl_decode +EXPORT_SYMBOL fs/nfsd/nfsd 0x23f0a2c8 nfs4_acl_nfsv4_to_posix +EXPORT_SYMBOL fs/nfsd/nfsd 0x35e33c1e nfs4_acl_write_who +EXPORT_SYMBOL fs/nfsd/nfsd 0x46ffdc39 nfs4_acl_posix_to_nfsv4 +EXPORT_SYMBOL fs/nfsd/nfsd 0x5a157ae4 nfs4_acl_get_whotype +EXPORT_SYMBOL fs/nfsd/nfsd 0x96ce9bb4 nfs4_acl_new +EXPORT_SYMBOL fs/xfs/xfs 0x1a97edde xfs_qmcore_xfs +EXPORT_SYMBOL lib/crc-ccitt 0x651c2313 crc_ccitt +EXPORT_SYMBOL lib/crc-ccitt 0x75811312 crc_ccitt_table +EXPORT_SYMBOL lib/crc-itu-t 0x276c7e62 crc_itu_t +EXPORT_SYMBOL lib/crc-itu-t 0xd29b009f crc_itu_t_table +EXPORT_SYMBOL lib/crc7 0xc086bfba crc7 +EXPORT_SYMBOL lib/crc7 0xd80c3603 crc7_syndrome_table +EXPORT_SYMBOL lib/libcrc32c 0x13c0c38e crc32c_le +EXPORT_SYMBOL lib/libcrc32c 0x41bcd8b3 crc32c_be +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x315c65fd zlib_deflateInit2 +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0x48034724 zlib_deflateReset +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xaf64ad0d zlib_deflate +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf0caf44b zlib_deflate_workspacesize +EXPORT_SYMBOL lib/zlib_deflate/zlib_deflate 0xf741c793 zlib_deflateEnd +EXPORT_SYMBOL net/802/p8023 0xe561bb4b make_8023_client +EXPORT_SYMBOL net/802/p8023 0xe6ebda46 destroy_8023_client +EXPORT_SYMBOL net/9p/9pnet 0x0b3ac49a p9pdu_dump +EXPORT_SYMBOL net/9p/9pnet 0x129c0285 p9_client_create +EXPORT_SYMBOL net/9p/9pnet 0x160dd0c2 v9fs_unregister_trans +EXPORT_SYMBOL net/9p/9pnet 0x18c0e953 p9_client_read +EXPORT_SYMBOL net/9p/9pnet 0x244c6d40 p9_idpool_get +EXPORT_SYMBOL net/9p/9pnet 0x2c9cab58 p9_client_clunk +EXPORT_SYMBOL net/9p/9pnet 0x2fa4eca4 p9_client_remove +EXPORT_SYMBOL net/9p/9pnet 0x3239bbfe p9_client_wstat +EXPORT_SYMBOL net/9p/9pnet 0x38a117d9 p9_client_fcreate +EXPORT_SYMBOL net/9p/9pnet 0x3d73a797 p9_errstr2errno +EXPORT_SYMBOL net/9p/9pnet 0x41e6bc51 p9_parse_header +EXPORT_SYMBOL net/9p/9pnet 0x4d58a998 p9_client_version +EXPORT_SYMBOL net/9p/9pnet 0x5e0ef374 p9_idpool_check +EXPORT_SYMBOL net/9p/9pnet 0x61852dea p9_idpool_put +EXPORT_SYMBOL net/9p/9pnet 0x6954df87 p9_client_stat +EXPORT_SYMBOL net/9p/9pnet 0x6aa3ee42 p9_client_cb +EXPORT_SYMBOL net/9p/9pnet 0x6c5e479c p9_idpool_create +EXPORT_SYMBOL net/9p/9pnet 0x76b79bf1 p9stat_read +EXPORT_SYMBOL net/9p/9pnet 0x79472263 v9fs_get_default_trans +EXPORT_SYMBOL net/9p/9pnet 0x7b9ce06c p9_client_write +EXPORT_SYMBOL net/9p/9pnet 0x7d3881d5 p9_client_destroy +EXPORT_SYMBOL net/9p/9pnet 0x7fcbcded v9fs_register_trans +EXPORT_SYMBOL net/9p/9pnet 0x80ecf101 p9_client_disconnect +EXPORT_SYMBOL net/9p/9pnet 0x9c964743 p9stat_free +EXPORT_SYMBOL net/9p/9pnet 0xb84ef7fa p9_client_attach +EXPORT_SYMBOL net/9p/9pnet 0xbaa17b44 p9_idpool_destroy +EXPORT_SYMBOL net/9p/9pnet 0xccdf7c0f v9fs_get_trans_by_name +EXPORT_SYMBOL net/9p/9pnet 0xd1a8e4ef p9_client_auth +EXPORT_SYMBOL net/9p/9pnet 0xd51b2a6b p9_client_open +EXPORT_SYMBOL net/9p/9pnet 0xe23d2391 p9_tag_lookup +EXPORT_SYMBOL net/9p/9pnet 0xe58a3360 p9_error_init +EXPORT_SYMBOL net/9p/9pnet 0xe7c9809b p9_client_walk +EXPORT_SYMBOL net/appletalk/appletalk 0x5b1e786f alloc_ltalkdev +EXPORT_SYMBOL net/appletalk/appletalk 0x9b301834 aarp_send_ddp +EXPORT_SYMBOL net/appletalk/appletalk 0xa2cec9cb atalk_find_dev_addr +EXPORT_SYMBOL net/appletalk/appletalk 0xb1e60933 atrtr_get_dev +EXPORT_SYMBOL net/ax25/ax25 0x0479d44f ax25_findbyuid +EXPORT_SYMBOL net/ax25/ax25 0x242852b9 ax25_uid_policy +EXPORT_SYMBOL net/ax25/ax25 0x3d2d82ec ax25_display_timer +EXPORT_SYMBOL net/ax25/ax25 0x4502c65a asc2ax +EXPORT_SYMBOL net/ax25/ax25 0x53dea1ff ax2asc +EXPORT_SYMBOL net/ax25/ax25 0x57eaaaa4 ax25_linkfail_release +EXPORT_SYMBOL net/ax25/ax25 0x66986d66 ax25_listen_release +EXPORT_SYMBOL net/ax25/ax25 0x7f9b55f4 ax25_send_frame +EXPORT_SYMBOL net/ax25/ax25 0x8ede9e26 ax25_protocol_release +EXPORT_SYMBOL net/ax25/ax25 0x91133aac ax25_hard_header +EXPORT_SYMBOL net/ax25/ax25 0xa2d15533 ax25_header_ops +EXPORT_SYMBOL net/ax25/ax25 0xa2e8404e ax25_find_cb +EXPORT_SYMBOL net/ax25/ax25 0xa7bc88de ax25_listen_register +EXPORT_SYMBOL net/ax25/ax25 0xbc2f982a ax25_linkfail_register +EXPORT_SYMBOL net/ax25/ax25 0xc1444946 ax25cmp +EXPORT_SYMBOL net/ax25/ax25 0xd43ecbf1 null_ax25_address +EXPORT_SYMBOL net/ax25/ax25 0xe0e640d6 ax25_rebuild_header +EXPORT_SYMBOL net/bridge/bridge 0x94f3df88 br_should_route_hook +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0x8e432571 ebt_unregister_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xda872124 ebt_register_table +EXPORT_SYMBOL net/bridge/netfilter/ebtables 0xfc79efb0 ebt_do_table +EXPORT_SYMBOL net/ieee80211/ieee80211 0x0023e882 ieee80211_is_valid_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x29c8b44b ieee80211_freq_to_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x3098e858 ieee80211_get_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x319c6a99 ieee80211_wx_set_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x34712d7c ieee80211_rx +EXPORT_SYMBOL net/ieee80211/ieee80211 0x35085f97 ieee80211_txb_free +EXPORT_SYMBOL net/ieee80211/ieee80211 0x413e2f80 ieee80211_wx_get_scan +EXPORT_SYMBOL net/ieee80211/ieee80211 0x44c08902 alloc_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x4aea2c47 ieee80211_rx_mgt +EXPORT_SYMBOL net/ieee80211/ieee80211 0x693afdbd ieee80211_wx_get_encode +EXPORT_SYMBOL net/ieee80211/ieee80211 0x6f7b72ff free_ieee80211 +EXPORT_SYMBOL net/ieee80211/ieee80211 0x7cbdc8a3 ieee80211_set_geo +EXPORT_SYMBOL net/ieee80211/ieee80211 0x89cbdbd3 ieee80211_get_channel +EXPORT_SYMBOL net/ieee80211/ieee80211 0x9bde5b18 ieee80211_channel_to_index +EXPORT_SYMBOL net/ieee80211/ieee80211 0xa9fb135f escape_essid +EXPORT_SYMBOL net/ieee80211/ieee80211 0xcc5a16ff ieee80211_wx_set_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf06b79c5 ieee80211_channel_to_freq +EXPORT_SYMBOL net/ieee80211/ieee80211 0xf2abe29b ieee80211_wx_get_encodeext +EXPORT_SYMBOL net/ieee80211/ieee80211 0xfe7d9840 ieee80211_get_channel_flags +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x246bf6ed ieee80211_register_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x279e265f ieee80211_crypt_deinit_handler +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x350791bc ieee80211_crypt_quiescing +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x67bd664a ieee80211_crypt_delayed_deinit +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x697d2bc7 ieee80211_crypt_deinit_entries +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x8b047759 ieee80211_unregister_crypto_ops +EXPORT_SYMBOL net/ieee80211/ieee80211_crypt 0x9f669335 ieee80211_get_crypto_ops +EXPORT_SYMBOL net/ipv4/inet_lro 0x03ec658e lro_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0x147289bc lro_flush_pkt +EXPORT_SYMBOL net/ipv4/inet_lro 0x66c33f81 lro_vlan_hwaccel_receive_skb +EXPORT_SYMBOL net/ipv4/inet_lro 0xad6e1e8c lro_flush_all +EXPORT_SYMBOL net/ipv4/inet_lro 0xb5893412 lro_vlan_hwaccel_receive_frags +EXPORT_SYMBOL net/ipv4/inet_lro 0xd8ae7e6b lro_receive_skb +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x85e34277 arpt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x87673fa1 arpt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/arp_tables 0x8db4d1cd arpt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0x8e6bb6ee ipt_do_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xd4a1a856 ipt_register_table +EXPORT_SYMBOL net/ipv4/netfilter/ip_tables 0xf2485421 ipt_unregister_table +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x093387d2 nf_nat_setup_info +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x1733b73c nf_nat_protocol_register +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x33d2465a nf_nat_follow_master +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x4a8472d8 nf_nat_mangle_udp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x88248ea3 nf_nat_mangle_tcp_packet +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0x8d3cb970 nf_nat_protocol_unregister +EXPORT_SYMBOL net/ipv4/netfilter/nf_nat 0xcf5f7ac6 nf_nat_used_tuple +EXPORT_SYMBOL net/ipv4/tunnel4 0x42498ec7 xfrm4_tunnel_register +EXPORT_SYMBOL net/ipv4/tunnel4 0x93abb9f4 xfrm4_tunnel_deregister +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x14502172 ipv6_find_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0x61641806 ip6t_unregister_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xa3729832 ip6t_register_table +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xb8bddf33 ip6t_ext_hdr +EXPORT_SYMBOL net/ipv6/netfilter/ip6_tables 0xdc1c5c1b ip6t_do_table +EXPORT_SYMBOL net/ipv6/tunnel6 0x5d489da9 xfrm6_tunnel_deregister +EXPORT_SYMBOL net/ipv6/tunnel6 0x66df2d70 xfrm6_tunnel_register +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0x9cd013f2 xfrm6_tunnel_alloc_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xab14e193 xfrm6_tunnel_free_spi +EXPORT_SYMBOL net/ipv6/xfrm6_tunnel 0xdb1b42d1 xfrm6_tunnel_spi_lookup +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x03a4d370 ircomm_close +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4907b9c7 ircomm_flow_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x4f7944c7 ircomm_disconnect_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x6d02444c ircomm_data_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x778f667c ircomm_open +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x805666b8 ircomm_control_request +EXPORT_SYMBOL net/irda/ircomm/ircomm 0x89a36967 ircomm_connect_response +EXPORT_SYMBOL net/irda/ircomm/ircomm 0xe1d5bd76 ircomm_connect_request +EXPORT_SYMBOL net/irda/irda 0x01d1fcdb hashbin_delete +EXPORT_SYMBOL net/irda/irda 0x02646a7b irlmp_data_request +EXPORT_SYMBOL net/irda/irda 0x06a3ee58 irias_new_integer_value +EXPORT_SYMBOL net/irda/irda 0x072e026f irias_add_octseq_attrib +EXPORT_SYMBOL net/irda/irda 0x07d3647c irlmp_register_service +EXPORT_SYMBOL net/irda/irda 0x1c3c5ed7 irttp_data_request +EXPORT_SYMBOL net/irda/irda 0x2036ad06 irda_param_insert +EXPORT_SYMBOL net/irda/irda 0x27a81314 irttp_dup +EXPORT_SYMBOL net/irda/irda 0x3462950f hashbin_remove +EXPORT_SYMBOL net/irda/irda 0x38a20e5b irda_debug +EXPORT_SYMBOL net/irda/irda 0x40f175dd iriap_close +EXPORT_SYMBOL net/irda/irda 0x448b8aaa irda_qos_bits_to_value +EXPORT_SYMBOL net/irda/irda 0x46c1c4a2 irlmp_unregister_service +EXPORT_SYMBOL net/irda/irda 0x48f4665d irttp_connect_response +EXPORT_SYMBOL net/irda/irda 0x529bd046 irttp_close_tsap +EXPORT_SYMBOL net/irda/irda 0x5bc6f219 irlmp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0x6758f8ac irias_new_object +EXPORT_SYMBOL net/irda/irda 0x68b7447c hashbin_find +EXPORT_SYMBOL net/irda/irda 0x6b043eba irda_init_max_qos_capabilies +EXPORT_SYMBOL net/irda/irda 0x6e27ab0b irttp_connect_request +EXPORT_SYMBOL net/irda/irda 0x7042bc54 irlmp_register_client +EXPORT_SYMBOL net/irda/irda 0x72e09736 async_wrap_skb +EXPORT_SYMBOL net/irda/irda 0x74084d63 irlmp_close_lsap +EXPORT_SYMBOL net/irda/irda 0x747d6779 irias_delete_object +EXPORT_SYMBOL net/irda/irda 0x7621e908 hashbin_insert +EXPORT_SYMBOL net/irda/irda 0x76243bc9 irias_insert_object +EXPORT_SYMBOL net/irda/irda 0x763e54a4 irlmp_unregister_client +EXPORT_SYMBOL net/irda/irda 0x781e2db5 irias_find_object +EXPORT_SYMBOL net/irda/irda 0x7957f728 irlmp_update_client +EXPORT_SYMBOL net/irda/irda 0x79a5bbd2 iriap_open +EXPORT_SYMBOL net/irda/irda 0x79c8734b irlmp_connect_response +EXPORT_SYMBOL net/irda/irda 0x7a57b6f3 hashbin_remove_this +EXPORT_SYMBOL net/irda/irda 0x91815586 irda_param_pack +EXPORT_SYMBOL net/irda/irda 0x993ad14b irda_param_extract_all +EXPORT_SYMBOL net/irda/irda 0x9a95b2c1 irlap_close +EXPORT_SYMBOL net/irda/irda 0xa5d9a86e irlmp_open_lsap +EXPORT_SYMBOL net/irda/irda 0xa8ea8d75 async_unwrap_char +EXPORT_SYMBOL net/irda/irda 0xac7660d2 irda_notify_init +EXPORT_SYMBOL net/irda/irda 0xb4dc0e5e irttp_disconnect_request +EXPORT_SYMBOL net/irda/irda 0xb60e3d4b irttp_udata_request +EXPORT_SYMBOL net/irda/irda 0xb90e45af alloc_irdadev +EXPORT_SYMBOL net/irda/irda 0xb9394173 irias_delete_value +EXPORT_SYMBOL net/irda/irda 0xbcd3ef13 irias_object_change_attribute +EXPORT_SYMBOL net/irda/irda 0xbdcbcaa5 irttp_open_tsap +EXPORT_SYMBOL net/irda/irda 0xbe40ace9 irlmp_discovery_request +EXPORT_SYMBOL net/irda/irda 0xc14e9b6a hashbin_get_next +EXPORT_SYMBOL net/irda/irda 0xc48e02fa irlap_open +EXPORT_SYMBOL net/irda/irda 0xc4f83df4 irttp_flow_request +EXPORT_SYMBOL net/irda/irda 0xcd41236c hashbin_new +EXPORT_SYMBOL net/irda/irda 0xd6deeaae irda_setup_dma +EXPORT_SYMBOL net/irda/irda 0xd7172ff4 hashbin_get_first +EXPORT_SYMBOL net/irda/irda 0xd8bfb6d4 hashbin_lock_find +EXPORT_SYMBOL net/irda/irda 0xde4c6b3c irlmp_service_to_hint +EXPORT_SYMBOL net/irda/irda 0xe5260e0e irias_add_integer_attrib +EXPORT_SYMBOL net/irda/irda 0xe7c4626c irda_device_set_media_busy +EXPORT_SYMBOL net/irda/irda 0xe91212c5 irlmp_connect_request +EXPORT_SYMBOL net/irda/irda 0xea3717cc iriap_getvaluebyclass_request +EXPORT_SYMBOL net/irda/irda 0xec41fe7f irias_add_string_attrib +EXPORT_SYMBOL net/irda/irda 0xedd521c2 irlmp_get_discoveries +EXPORT_SYMBOL net/irda/irda 0xf3866b3a proc_irda +EXPORT_SYMBOL net/lapb/lapb 0x01f280f2 lapb_setparms +EXPORT_SYMBOL net/lapb/lapb 0x05a53f6c lapb_getparms +EXPORT_SYMBOL net/lapb/lapb 0x0cedfa6d lapb_unregister +EXPORT_SYMBOL net/lapb/lapb 0x26ab30a5 lapb_disconnect_request +EXPORT_SYMBOL net/lapb/lapb 0x38a0748b lapb_register +EXPORT_SYMBOL net/lapb/lapb 0x3d3bbc42 lapb_connect_request +EXPORT_SYMBOL net/lapb/lapb 0x887b3182 lapb_data_received +EXPORT_SYMBOL net/lapb/lapb 0x989e9a91 lapb_data_request +EXPORT_SYMBOL net/mac80211/mac80211 0x005ec1fa ieee80211_start_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x015a9bb3 ieee80211_find_sta +EXPORT_SYMBOL net/mac80211/mac80211 0x02bd1c8d ieee80211_queue_stopped +EXPORT_SYMBOL net/mac80211/mac80211 0x0382e53e ieee80211_beacon_get +EXPORT_SYMBOL net/mac80211/mac80211 0x12cd250c ieee80211_wake_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x15d8cb36 ieee80211_wake_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x16438b95 ieee80211_get_buffered_bc +EXPORT_SYMBOL net/mac80211/mac80211 0x17bec652 ieee80211_rts_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x23dec480 ieee80211_start_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0x27e0ffa5 ieee80211_stop_queue +EXPORT_SYMBOL net/mac80211/mac80211 0x2e21261b ieee80211_tx_status +EXPORT_SYMBOL net/mac80211/mac80211 0x4965dc2f wiphy_to_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x4d370b4b ieee80211_scan_completed +EXPORT_SYMBOL net/mac80211/mac80211 0x50227405 ieee80211_rate_control_unregister +EXPORT_SYMBOL net/mac80211/mac80211 0x5801f61b ieee80211_ctstoself_duration +EXPORT_SYMBOL net/mac80211/mac80211 0x77d1e6af ieee80211_free_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x7bab58bd __ieee80211_get_radio_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0x7e5d9c80 ieee80211_start_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0x7f1473e1 ieee80211_stop_tx_ba_session +EXPORT_SYMBOL net/mac80211/mac80211 0x84a950c1 ieee80211_rate_control_register +EXPORT_SYMBOL net/mac80211/mac80211 0x89472716 ieee80211_register_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x89655926 ieee80211_get_tkip_key +EXPORT_SYMBOL net/mac80211/mac80211 0x8c35d732 ieee80211_hdrlen +EXPORT_SYMBOL net/mac80211/mac80211 0x96186dca ieee80211_unregister_hw +EXPORT_SYMBOL net/mac80211/mac80211 0x9dd09d58 ieee80211_stop_queues +EXPORT_SYMBOL net/mac80211/mac80211 0x9e4bc95e __ieee80211_rx +EXPORT_SYMBOL net/mac80211/mac80211 0x9f0f00bf ieee80211_ctstoself_get +EXPORT_SYMBOL net/mac80211/mac80211 0xa6a1c718 __ieee80211_get_rx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xbc17239c __ieee80211_get_tx_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xc0770aba ieee80211_stop_tx_ba_cb +EXPORT_SYMBOL net/mac80211/mac80211 0xc94eb638 ieee80211_rx_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xd7901b4e ieee80211_get_hdrlen_from_skb +EXPORT_SYMBOL net/mac80211/mac80211 0xdaae9a94 ieee80211_tx_status_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xe4a47dd9 __ieee80211_get_assoc_led_name +EXPORT_SYMBOL net/mac80211/mac80211 0xe64445ba ieee80211_stop_tx_ba_cb_irqsafe +EXPORT_SYMBOL net/mac80211/mac80211 0xe7107b61 ieee80211_alloc_hw +EXPORT_SYMBOL net/mac80211/mac80211 0xf6655f1b ieee80211_generic_frame_duration +EXPORT_SYMBOL net/mac80211/mac80211 0xf6acdec2 ieee80211_rts_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x10559051 register_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x1b1bae1f register_ip_vs_app_inc +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0x3200ca89 register_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xa1dbc2d8 ip_vs_proto_name +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xbc352f79 ip_vs_tcp_conn_listen +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xc57ba2d6 ip_vs_conn_new +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xc8132e28 ip_vs_conn_out_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xcccb6698 unregister_ip_vs_scheduler +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xdc6c9dff unregister_ip_vs_app +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xde6e64a3 ip_vs_conn_in_get +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe12f1d59 ip_vs_skb_replace +EXPORT_SYMBOL net/netfilter/ipvs/ip_vs 0xe180956a ip_vs_conn_put +EXPORT_SYMBOL net/netfilter/nf_conntrack 0x8fb4ee7a __nf_ct_ext_destroy +EXPORT_SYMBOL net/netfilter/nf_conntrack 0xe372c1b6 __nf_ct_ext_add +EXPORT_SYMBOL net/netfilter/nf_conntrack_proto_gre 0x01563892 nf_ct_gre_keymap_flush +EXPORT_SYMBOL net/netfilter/x_tables 0x0340e888 xt_register_match +EXPORT_SYMBOL net/netfilter/x_tables 0x119c7478 xt_unregister_matches +EXPORT_SYMBOL net/netfilter/x_tables 0x2446c584 xt_unregister_targets +EXPORT_SYMBOL net/netfilter/x_tables 0x3dcd58c5 xt_alloc_table_info +EXPORT_SYMBOL net/netfilter/x_tables 0x7d7cbaf7 xt_find_target +EXPORT_SYMBOL net/netfilter/x_tables 0x8ec467d3 xt_unregister_match +EXPORT_SYMBOL net/netfilter/x_tables 0xbc3e10a6 xt_unregister_target +EXPORT_SYMBOL net/netfilter/x_tables 0xc1c7cf1c xt_register_target +EXPORT_SYMBOL net/netfilter/x_tables 0xcc641c44 xt_register_matches +EXPORT_SYMBOL net/netfilter/x_tables 0xd314bfb6 xt_register_targets +EXPORT_SYMBOL net/netfilter/x_tables 0xdc33b3da xt_find_match +EXPORT_SYMBOL net/netfilter/x_tables 0xf7037dc6 xt_free_table_info +EXPORT_SYMBOL net/phonet/phonet 0x04685db6 phonet_stream_ops +EXPORT_SYMBOL net/phonet/phonet 0x1123cf0c pn_sock_unhash +EXPORT_SYMBOL net/phonet/phonet 0x341f58c9 pn_skb_send +EXPORT_SYMBOL net/phonet/phonet 0x569e300d phonet_header_ops +EXPORT_SYMBOL net/phonet/phonet 0x59272dfd pn_sock_hash +EXPORT_SYMBOL net/phonet/phonet 0x7303355c phonet_proto_register +EXPORT_SYMBOL net/phonet/phonet 0x914a703d pn_sock_get_port +EXPORT_SYMBOL net/phonet/phonet 0xf00bfd57 phonet_proto_unregister +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x02b7f895 rxrpc_kernel_abort_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x133ba0f6 rxrpc_kernel_reject_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1753e81c rxrpc_kernel_free_skb +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x1e050a28 key_type_rxrpc +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x4d72f762 rxrpc_get_server_data_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x6170abba rxrpc_kernel_send_data +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x83541c85 rxrpc_kernel_accept_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0x83d6f51a rxrpc_kernel_is_data_last +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xabac1425 rxrpc_kernel_intercept_rx_messages +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xae046a2a rxrpc_get_null_key +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb01e171c rxrpc_kernel_get_abort_code +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb26d1725 rxrpc_kernel_end_call +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xb6d4ba21 rxrpc_kernel_get_error_number +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xdf4202c8 rxrpc_kernel_data_delivered +EXPORT_SYMBOL net/rxrpc/af-rxrpc 0xf5cc50eb rxrpc_kernel_begin_call +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x00c52ef5 g_make_token_header +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x0a18033f gss_service_to_auth_domain_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x19ce6372 gss_pseudoflavor_to_service +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x1d2d6602 gss_mech_put +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x31d0dbe1 gss_mech_register +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x38941db6 gss_svc_to_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x43c0965f gss_mech_get_by_name +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x57df116d svcauth_gss_flavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x6c9391a3 gss_mech_get +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x7ba94fc2 gss_mech_unregister +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8836eccc gss_mech_get_by_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0x8d1a827e svcauth_gss_register_pseudoflavor +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xb5dea7ef g_token_size +EXPORT_SYMBOL net/sunrpc/auth_gss/auth_rpcgss 0xf8b2ff6e g_verify_token_header +EXPORT_SYMBOL net/sunrpc/sunrpc 0x00bd19ed svc_recv +EXPORT_SYMBOL net/sunrpc/sunrpc 0x047b2fb0 svc_destroy +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05a80cb4 svc_sock_names +EXPORT_SYMBOL net/sunrpc/sunrpc 0x05e807a9 xdr_encode_string +EXPORT_SYMBOL net/sunrpc/sunrpc 0x065994f1 xdr_encode_opaque_fixed +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0a8f9ccc rpc_unlink +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0b267f41 auth_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0x0f668ba9 svc_auth_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x12e280e3 svc_proc_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1302f79a xdr_shift_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x145e92b9 auth_unix_add_addr +EXPORT_SYMBOL net/sunrpc/sunrpc 0x1b30a51e svc_proc_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x23c35a2b xdr_decode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x241c0230 xdr_decode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x27d0e2db svc_set_num_threads +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2919b156 xdr_decode_string_inplace +EXPORT_SYMBOL net/sunrpc/sunrpc 0x2eec63c9 xdr_encode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x32064700 sunrpc_cache_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0x32ff2a90 auth_domain_put +EXPORT_SYMBOL net/sunrpc/sunrpc 0x334834ba xdr_init_encode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x37d14b81 xdr_buf_read_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0x392307c8 svcauth_unix_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0x476ed128 xdr_enter_page +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4c6a4ca9 svc_seq_show +EXPORT_SYMBOL net/sunrpc/sunrpc 0x4f21a52c xdr_process_buf +EXPORT_SYMBOL net/sunrpc/sunrpc 0x521b8168 svc_exit_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0x549aa492 xdr_init_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0x551e1977 xdr_encode_word +EXPORT_SYMBOL net/sunrpc/sunrpc 0x566c4388 svc_drop +EXPORT_SYMBOL net/sunrpc/sunrpc 0x5e4252ad svc_auth_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0x6eea229d svcauth_unix_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0x71fa908a cache_flush +EXPORT_SYMBOL net/sunrpc/sunrpc 0x72ab7c8b svc_sock_update_bufs +EXPORT_SYMBOL net/sunrpc/sunrpc 0x769d8f12 auth_unix_forget_old +EXPORT_SYMBOL net/sunrpc/sunrpc 0x77aeae2c rpc_queue_upcall +EXPORT_SYMBOL net/sunrpc/sunrpc 0x77d52968 xdr_buf_from_iov +EXPORT_SYMBOL net/sunrpc/sunrpc 0x81c256b1 svc_authenticate +EXPORT_SYMBOL net/sunrpc/sunrpc 0x89a00b58 svc_create_pooled +EXPORT_SYMBOL net/sunrpc/sunrpc 0x987442a6 svc_reserve +EXPORT_SYMBOL net/sunrpc/sunrpc 0x98fd545d svc_create +EXPORT_SYMBOL net/sunrpc/sunrpc 0x99c9ef7f xdr_encode_array2 +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9c0215aa cache_check +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9e264ddd xdr_read_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0x9efbd587 xdr_encode_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa35efa45 cache_purge +EXPORT_SYMBOL net/sunrpc/sunrpc 0xa64e4e9d xdr_inline_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xab91f75e cache_register +EXPORT_SYMBOL net/sunrpc/sunrpc 0xac2c9fc9 unix_domain_find +EXPORT_SYMBOL net/sunrpc/sunrpc 0xb53b14cd svc_process +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc2ccdd1d rpc_mkpipe +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc3880471 xdr_decode_netobj +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc62283f4 svc_set_client +EXPORT_SYMBOL net/sunrpc/sunrpc 0xc8e96dea qword_addhex +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd377133d xdr_write_pages +EXPORT_SYMBOL net/sunrpc/sunrpc 0xd99a9b2a sunrpc_cache_update +EXPORT_SYMBOL net/sunrpc/sunrpc 0xde56bc35 svc_wake_up +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe20f13c0 xdr_buf_subsegment +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe57f161c cache_unregister +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe5919cb1 xdr_encode_opaque +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe8d7e9f0 auth_unix_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xe97f4ce5 qword_get +EXPORT_SYMBOL net/sunrpc/sunrpc 0xeb595f84 xdr_reserve_space +EXPORT_SYMBOL net/sunrpc/sunrpc 0xedcf6be4 qword_add +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf2fdb746 xdr_inline_decode +EXPORT_SYMBOL net/sunrpc/sunrpc 0xf89dfa40 svc_prepare_thread +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfce29555 auth_domain_lookup +EXPORT_SYMBOL net/sunrpc/sunrpc 0xfe53cd8d read_bytes_from_xdr_buf +EXPORT_SYMBOL net/tipc/tipc 0x08acf310 tipc_available_nodes +EXPORT_SYMBOL net/tipc/tipc 0x0b074a7b tipc_multicast +EXPORT_SYMBOL net/tipc/tipc 0x10d40fcd tipc_isconnected +EXPORT_SYMBOL net/tipc/tipc 0x1472b270 tipc_disconnect +EXPORT_SYMBOL net/tipc/tipc 0x1479cb03 tipc_deleteport +EXPORT_SYMBOL net/tipc/tipc 0x15b5ecde tipc_set_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x16f27683 tipc_block_bearer +EXPORT_SYMBOL net/tipc/tipc 0x23daecbd tipc_send +EXPORT_SYMBOL net/tipc/tipc 0x259b74f9 tipc_acknowledge +EXPORT_SYMBOL net/tipc/tipc 0x310d1bc9 tipc_detach +EXPORT_SYMBOL net/tipc/tipc 0x33ec328c tipc_createport +EXPORT_SYMBOL net/tipc/tipc 0x3712e340 tipc_portunreliable +EXPORT_SYMBOL net/tipc/tipc 0x3976041f tipc_set_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x419b02fc tipc_send2port +EXPORT_SYMBOL net/tipc/tipc 0x4b2243c6 tipc_portimportance +EXPORT_SYMBOL net/tipc/tipc 0x4da5191a tipc_send_buf +EXPORT_SYMBOL net/tipc/tipc 0x538b228a tipc_withdraw +EXPORT_SYMBOL net/tipc/tipc 0x5637ed44 tipc_get_mode +EXPORT_SYMBOL net/tipc/tipc 0x56e52bc1 tipc_continue +EXPORT_SYMBOL net/tipc/tipc 0x5c0d4b5c tipc_ref_valid +EXPORT_SYMBOL net/tipc/tipc 0x62a681a3 tipc_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0x6ab8bc0e tipc_forward_buf2name +EXPORT_SYMBOL net/tipc/tipc 0x88b73627 tipc_get_addr +EXPORT_SYMBOL net/tipc/tipc 0x9c45558e tipc_enable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xa1b42d32 tipc_forward2port +EXPORT_SYMBOL net/tipc/tipc 0xa936a24b tipc_get_port +EXPORT_SYMBOL net/tipc/tipc 0xadd203d0 tipc_connect2port +EXPORT_SYMBOL net/tipc/tipc 0xae0103c3 tipc_shutdown +EXPORT_SYMBOL net/tipc/tipc 0xb1f8eacc tipc_send2name +EXPORT_SYMBOL net/tipc/tipc 0xb35b672c tipc_publish +EXPORT_SYMBOL net/tipc/tipc 0xb6e7e20c tipc_send_buf_fast +EXPORT_SYMBOL net/tipc/tipc 0xb75aed2f tipc_forward_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xbc0026f1 tipc_send_buf2name +EXPORT_SYMBOL net/tipc/tipc 0xca395aba tipc_send_buf2port +EXPORT_SYMBOL net/tipc/tipc 0xcec8514a tipc_set_portunreturnable +EXPORT_SYMBOL net/tipc/tipc 0xcee290be tipc_forward2name +EXPORT_SYMBOL net/tipc/tipc 0xd169c8c1 tipc_reject_msg +EXPORT_SYMBOL net/tipc/tipc 0xd44731e5 tipc_ownidentity +EXPORT_SYMBOL net/tipc/tipc 0xd9b134f9 tipc_recv_msg +EXPORT_SYMBOL net/tipc/tipc 0xda7f9d3f tipc_attach +EXPORT_SYMBOL net/tipc/tipc 0xdf5008fc tipc_peer +EXPORT_SYMBOL net/tipc/tipc 0xe7aece47 tipc_ispublished +EXPORT_SYMBOL net/tipc/tipc 0xe8338d1b tipc_register_media +EXPORT_SYMBOL net/tipc/tipc 0xeefd49b3 tipc_get_handle +EXPORT_SYMBOL net/tipc/tipc 0xef50a1ef tipc_disable_bearer +EXPORT_SYMBOL net/tipc/tipc 0xfb470a7d tipc_createport_raw +EXPORT_SYMBOL net/wanrouter/wanrouter 0x0ebe03d1 unregister_wan_device +EXPORT_SYMBOL net/wanrouter/wanrouter 0x27c3ac49 register_wan_device +EXPORT_SYMBOL net/wireless/cfg80211 0x00e425f3 wiphy_new +EXPORT_SYMBOL net/wireless/cfg80211 0x07e7ac5a ieee80211_radiotap_iterator_init +EXPORT_SYMBOL net/wireless/cfg80211 0x09c64fbd ieee80211_frequency_to_channel +EXPORT_SYMBOL net/wireless/cfg80211 0x272a0fb9 wiphy_unregister +EXPORT_SYMBOL net/wireless/cfg80211 0x798f29c0 regulatory_hint +EXPORT_SYMBOL net/wireless/cfg80211 0xbaffd8f2 __ieee80211_get_channel +EXPORT_SYMBOL net/wireless/cfg80211 0xc4e85ec5 ieee80211_radiotap_iterator_next +EXPORT_SYMBOL net/wireless/cfg80211 0xccc291b3 ieee80211_channel_to_frequency +EXPORT_SYMBOL net/wireless/cfg80211 0xf462259c wiphy_free +EXPORT_SYMBOL net/wireless/cfg80211 0xf914ac04 wiphy_register +EXPORT_SYMBOL sound/ac97_bus 0x07918f29 ac97_bus_type +EXPORT_SYMBOL sound/core/oss/snd-mixer-oss 0xec2611ea snd_mixer_oss_ioctl_card +EXPORT_SYMBOL sound/core/seq/snd-seq 0x1a724fcc snd_seq_kernel_client_ctl +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3061c52d snd_use_lock_sync_helper +EXPORT_SYMBOL sound/core/seq/snd-seq 0x3fb4d161 snd_seq_kernel_client_dispatch +EXPORT_SYMBOL sound/core/seq/snd-seq 0x5f33beab snd_seq_kernel_client_enqueue_blocking +EXPORT_SYMBOL sound/core/seq/snd-seq 0x6bb71038 snd_seq_delete_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7ac2f329 snd_seq_expand_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq 0x7b8699eb snd_seq_event_port_detach +EXPORT_SYMBOL sound/core/seq/snd-seq 0x81855aa8 snd_seq_create_kernel_client +EXPORT_SYMBOL sound/core/seq/snd-seq 0xb8e448a0 snd_seq_set_queue_tempo +EXPORT_SYMBOL sound/core/seq/snd-seq 0xc04ce214 snd_seq_event_port_attach +EXPORT_SYMBOL sound/core/seq/snd-seq 0xcac0a3be snd_seq_kernel_client_enqueue +EXPORT_SYMBOL sound/core/seq/snd-seq 0xdb4236a5 snd_seq_kernel_client_write_poll +EXPORT_SYMBOL sound/core/seq/snd-seq 0xe934da1d snd_seq_dump_var_event +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x06852efa snd_seq_device_new +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x093c8e7e snd_seq_device_register_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x3a57f235 snd_seq_autoload_unlock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0x6339b6d0 snd_seq_device_load_drivers +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xb90668b2 snd_seq_autoload_lock +EXPORT_SYMBOL sound/core/seq/snd-seq-device 0xc622fb29 snd_seq_device_unregister_driver +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x6ea09972 snd_midi_channel_alloc_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0x833a3e07 snd_midi_channel_set_clear +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xb9948d2c snd_midi_channel_free_set +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-emul 0xf0a1fdb3 snd_midi_process_event +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x17c15809 snd_midi_event_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x4ad3f518 snd_midi_event_reset_decode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x62384d3a snd_midi_event_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x8a348811 snd_midi_event_reset_encode +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0x9df7af8b snd_midi_event_free +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xc482499d snd_midi_event_new +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xd9072e1a snd_midi_event_no_status +EXPORT_SYMBOL sound/core/seq/snd-seq-midi-event 0xe6df29c7 snd_midi_event_encode_byte +EXPORT_SYMBOL sound/core/seq/snd-seq-virmidi 0x320a4f60 snd_virmidi_new +EXPORT_SYMBOL sound/core/snd 0x012e6c7a snd_card_register +EXPORT_SYMBOL sound/core/snd 0x0383ac59 snd_power_wait +EXPORT_SYMBOL sound/core/snd 0x04f49fc3 snd_ctl_find_id +EXPORT_SYMBOL sound/core/snd 0x11dc229e snd_device_free +EXPORT_SYMBOL sound/core/snd 0x14fc7185 snd_ctl_boolean_stereo_info +EXPORT_SYMBOL sound/core/snd 0x18e1683f snd_dma_program +EXPORT_SYMBOL sound/core/snd 0x191e88cf snd_dma_pointer +EXPORT_SYMBOL sound/core/snd 0x198788b4 snd_lookup_oss_minor_data +EXPORT_SYMBOL sound/core/snd 0x19f13bdc snd_ctl_find_numid +EXPORT_SYMBOL sound/core/snd 0x1cf17319 snd_component_add +EXPORT_SYMBOL sound/core/snd 0x2200a697 snd_pci_quirk_lookup +EXPORT_SYMBOL sound/core/snd 0x24a94b26 snd_info_get_line +EXPORT_SYMBOL sound/core/snd 0x2ae3deaa release_and_free_resource +EXPORT_SYMBOL sound/core/snd 0x2e82b405 snd_ctl_boolean_mono_info +EXPORT_SYMBOL sound/core/snd 0x30083944 snd_card_file_add +EXPORT_SYMBOL sound/core/snd 0x3130359f snd_info_free_entry +EXPORT_SYMBOL sound/core/snd 0x3267b069 snd_register_device_for_dev +EXPORT_SYMBOL sound/core/snd 0x3971b4df snd_ecards_limit +EXPORT_SYMBOL sound/core/snd 0x4100c868 snd_add_device_sysfs_file +EXPORT_SYMBOL sound/core/snd 0x42144d83 snd_ctl_remove_id +EXPORT_SYMBOL sound/core/snd 0x45f9daab snd_unregister_device +EXPORT_SYMBOL sound/core/snd 0x4a3ea5c0 snd_request_card +EXPORT_SYMBOL sound/core/snd 0x4b59efd9 snd_register_oss_device +EXPORT_SYMBOL sound/core/snd 0x4e6fa4c1 snd_ctl_free_one +EXPORT_SYMBOL sound/core/snd 0x515094e5 snd_ctl_remove +EXPORT_SYMBOL sound/core/snd 0x518bb7f8 copy_from_user_toio +EXPORT_SYMBOL sound/core/snd 0x5c1e9440 snd_ctl_make_virtual_master +EXPORT_SYMBOL sound/core/snd 0x70c15ac1 snd_dma_disable +EXPORT_SYMBOL sound/core/snd 0x74df9df8 snd_card_new +EXPORT_SYMBOL sound/core/snd 0x79bc7b8a snd_ctl_register_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0x80b9d986 snd_info_register +EXPORT_SYMBOL sound/core/snd 0x817cb26f snd_unregister_oss_device +EXPORT_SYMBOL sound/core/snd 0x8359c3b7 snd_ctl_add_slave +EXPORT_SYMBOL sound/core/snd 0x848deec1 snd_ctl_new1 +EXPORT_SYMBOL sound/core/snd 0x8913208a snd_card_free +EXPORT_SYMBOL sound/core/snd 0x891d4a77 snd_info_create_module_entry +EXPORT_SYMBOL sound/core/snd 0x8b9befdf snd_card_proc_new +EXPORT_SYMBOL sound/core/snd 0x8df3789f snd_oss_info_register +EXPORT_SYMBOL sound/core/snd 0x8f595b11 snd_major +EXPORT_SYMBOL sound/core/snd 0x9033b9e1 snd_ctl_add +EXPORT_SYMBOL sound/core/snd 0x95825832 snd_mixer_oss_notify_callback +EXPORT_SYMBOL sound/core/snd 0x9777256a snd_cards +EXPORT_SYMBOL sound/core/snd 0xa0469e71 snd_info_create_card_entry +EXPORT_SYMBOL sound/core/snd 0xaa40b2dd snd_ctl_notify +EXPORT_SYMBOL sound/core/snd 0xaab12cb1 snd_seq_root +EXPORT_SYMBOL sound/core/snd 0xb213fe8b snd_info_get_str +EXPORT_SYMBOL sound/core/snd 0xb2e5ae4a snd_lookup_minor_data +EXPORT_SYMBOL sound/core/snd 0xb57e4bb1 snd_card_free_when_closed +EXPORT_SYMBOL sound/core/snd 0xbfbf7863 snd_ctl_register_ioctl +EXPORT_SYMBOL sound/core/snd 0xe243dde3 copy_to_user_fromio +EXPORT_SYMBOL sound/core/snd 0xe4854cea snd_iprintf +EXPORT_SYMBOL sound/core/snd 0xed00ec72 snd_device_register +EXPORT_SYMBOL sound/core/snd 0xf5d4c2a8 snd_card_file_remove +EXPORT_SYMBOL sound/core/snd 0xf70e1ee9 snd_ctl_unregister_ioctl +EXPORT_SYMBOL sound/core/snd 0xf8707307 snd_ctl_unregister_ioctl_compat +EXPORT_SYMBOL sound/core/snd 0xf9d7892d snd_card_disconnect +EXPORT_SYMBOL sound/core/snd 0xfe4617e3 snd_device_new +EXPORT_SYMBOL sound/core/snd 0xfe5efee2 snd_ctl_rename_id +EXPORT_SYMBOL sound/core/snd-hwdep 0xf39ccf0d snd_hwdep_new +EXPORT_SYMBOL sound/core/snd-page-alloc 0x19cc2ce3 snd_free_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x2ca6c797 snd_dma_alloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0x399fe6f1 snd_dma_alloc_pages_fallback +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5a1328a3 snd_dma_get_reserved_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0x5d2a3a58 snd_dma_reserve_buf +EXPORT_SYMBOL sound/core/snd-page-alloc 0xc6829020 snd_malloc_pages +EXPORT_SYMBOL sound/core/snd-page-alloc 0xf2d3e8c4 snd_dma_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x04cda566 snd_interval_refine +EXPORT_SYMBOL sound/core/snd-pcm 0x06003fe1 snd_pcm_notify +EXPORT_SYMBOL sound/core/snd-pcm 0x0ce43d8c snd_pcm_hw_constraint_pow2 +EXPORT_SYMBOL sound/core/snd-pcm 0x0e309e28 snd_pcm_release_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x1a54e0f7 snd_pcm_set_sync +EXPORT_SYMBOL sound/core/snd-pcm 0x1d027e4b snd_pcm_format_signed +EXPORT_SYMBOL sound/core/snd-pcm 0x1d236cde snd_pcm_sgbuf_ops_page +EXPORT_SYMBOL sound/core/snd-pcm 0x2ab122c3 snd_pcm_lib_free_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x2e8be812 snd_pcm_hw_constraint_ratdens +EXPORT_SYMBOL sound/core/snd-pcm 0x3796bdcc snd_pcm_format_little_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x393574f5 snd_pcm_period_elapsed +EXPORT_SYMBOL sound/core/snd-pcm 0x4226e4b4 snd_pcm_lib_readv +EXPORT_SYMBOL sound/core/snd-pcm 0x4cac593e snd_pcm_open_substream +EXPORT_SYMBOL sound/core/snd-pcm 0x4f816e9b snd_pcm_format_big_endian +EXPORT_SYMBOL sound/core/snd-pcm 0x5813bfdc snd_pcm_lib_preallocate_pages +EXPORT_SYMBOL sound/core/snd-pcm 0x5e7f4920 snd_pcm_format_set_silence +EXPORT_SYMBOL sound/core/snd-pcm 0x627701c4 snd_pcm_kernel_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x63f51c49 snd_pcm_hw_param_value +EXPORT_SYMBOL sound/core/snd-pcm 0x64c03c6b snd_pcm_suspend_all +EXPORT_SYMBOL sound/core/snd-pcm 0x650f8603 snd_pcm_format_silence_64 +EXPORT_SYMBOL sound/core/snd-pcm 0x671c6cb0 snd_pcm_stop +EXPORT_SYMBOL sound/core/snd-pcm 0x68a24153 snd_pcm_format_physical_width +EXPORT_SYMBOL sound/core/snd-pcm 0x6ef8fcd8 snd_pcm_format_linear +EXPORT_SYMBOL sound/core/snd-pcm 0x706b70ac snd_pcm_lib_ioctl +EXPORT_SYMBOL sound/core/snd-pcm 0x719614e6 snd_pcm_lib_read +EXPORT_SYMBOL sound/core/snd-pcm 0x77b9ccac _snd_pcm_hw_param_setempty +EXPORT_SYMBOL sound/core/snd-pcm 0x88cc66cc snd_pcm_link_rwlock +EXPORT_SYMBOL sound/core/snd-pcm 0x952d5f21 _snd_pcm_hw_params_any +EXPORT_SYMBOL sound/core/snd-pcm 0x95a1e15e snd_pcm_limit_hw_rates +EXPORT_SYMBOL sound/core/snd-pcm 0x9bd5ef78 snd_pcm_hw_constraint_ratnums +EXPORT_SYMBOL sound/core/snd-pcm 0x9e0d15b9 snd_pcm_hw_constraint_minmax +EXPORT_SYMBOL sound/core/snd-pcm 0xa61aa028 snd_pcm_format_unsigned +EXPORT_SYMBOL sound/core/snd-pcm 0xacdd33ec snd_pcm_lib_preallocate_free_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xad6c3250 snd_pcm_hw_param_last +EXPORT_SYMBOL sound/core/snd-pcm 0xb267c67c snd_pcm_lib_mmap_iomem +EXPORT_SYMBOL sound/core/snd-pcm 0xb2f8cfb0 snd_pcm_sgbuf_get_chunk_size +EXPORT_SYMBOL sound/core/snd-pcm 0xb9638db4 snd_pcm_rate_to_rate_bit +EXPORT_SYMBOL sound/core/snd-pcm 0xb9831582 snd_pcm_new_stream +EXPORT_SYMBOL sound/core/snd-pcm 0xc11b203b snd_pcm_hw_constraint_integer +EXPORT_SYMBOL sound/core/snd-pcm 0xc4a31c56 snd_pcm_hw_refine +EXPORT_SYMBOL sound/core/snd-pcm 0xc9865e0e snd_pcm_lib_write +EXPORT_SYMBOL sound/core/snd-pcm 0xc9901771 snd_pcm_hw_constraint_msbits +EXPORT_SYMBOL sound/core/snd-pcm 0xd0b9b8b8 snd_interval_list +EXPORT_SYMBOL sound/core/snd-pcm 0xd5039c6c snd_pcm_lib_malloc_pages +EXPORT_SYMBOL sound/core/snd-pcm 0xd76a3496 snd_pcm_set_ops +EXPORT_SYMBOL sound/core/snd-pcm 0xdfe4cac8 snd_pcm_lib_writev +EXPORT_SYMBOL sound/core/snd-pcm 0xe0f6408c snd_pcm_mmap_data +EXPORT_SYMBOL sound/core/snd-pcm 0xe51a1c64 snd_pcm_format_size +EXPORT_SYMBOL sound/core/snd-pcm 0xe56a9336 snd_pcm_format_width +EXPORT_SYMBOL sound/core/snd-pcm 0xe7a64f52 snd_pcm_suspend +EXPORT_SYMBOL sound/core/snd-pcm 0xeda6d608 snd_pcm_hw_constraint_list +EXPORT_SYMBOL sound/core/snd-pcm 0xf06fe2c1 snd_pcm_new +EXPORT_SYMBOL sound/core/snd-pcm 0xf3797152 snd_interval_ratnum +EXPORT_SYMBOL sound/core/snd-pcm 0xf75351dc snd_pcm_hw_rule_add +EXPORT_SYMBOL sound/core/snd-pcm 0xf95e655c snd_pcm_hw_param_first +EXPORT_SYMBOL sound/core/snd-pcm 0xfa7aae98 snd_pcm_lib_preallocate_pages_for_all +EXPORT_SYMBOL sound/core/snd-pcm 0xfeff32ec snd_pcm_hw_constraint_step +EXPORT_SYMBOL sound/core/snd-rawmidi 0x210631d5 snd_rawmidi_transmit_empty +EXPORT_SYMBOL sound/core/snd-rawmidi 0x28036db7 snd_rawmidi_drain_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x3138628a snd_rawmidi_kernel_read +EXPORT_SYMBOL sound/core/snd-rawmidi 0x4de0958e snd_rawmidi_info_select +EXPORT_SYMBOL sound/core/snd-rawmidi 0x4e1b234f snd_rawmidi_drop_output +EXPORT_SYMBOL sound/core/snd-rawmidi 0x58052732 snd_rawmidi_kernel_open +EXPORT_SYMBOL sound/core/snd-rawmidi 0x619d48ad snd_rawmidi_transmit +EXPORT_SYMBOL sound/core/snd-rawmidi 0x679d9229 snd_rawmidi_output_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0x795b37ac snd_rawmidi_receive +EXPORT_SYMBOL sound/core/snd-rawmidi 0x916ec20e snd_rawmidi_kernel_release +EXPORT_SYMBOL sound/core/snd-rawmidi 0x954b2ff5 snd_rawmidi_transmit_peek +EXPORT_SYMBOL sound/core/snd-rawmidi 0xa74bd9fc snd_rawmidi_input_params +EXPORT_SYMBOL sound/core/snd-rawmidi 0xbf395332 snd_rawmidi_drain_input +EXPORT_SYMBOL sound/core/snd-rawmidi 0xcede065a snd_rawmidi_transmit_ack +EXPORT_SYMBOL sound/core/snd-rawmidi 0xdcb7cc58 snd_rawmidi_new +EXPORT_SYMBOL sound/core/snd-rawmidi 0xe5e1c662 snd_rawmidi_kernel_write +EXPORT_SYMBOL sound/core/snd-rawmidi 0xf7a3757c snd_rawmidi_set_ops +EXPORT_SYMBOL sound/core/snd-timer 0x086a1982 snd_timer_interrupt +EXPORT_SYMBOL sound/core/snd-timer 0x4cad173d snd_timer_notify +EXPORT_SYMBOL sound/core/snd-timer 0x511f61d2 snd_timer_continue +EXPORT_SYMBOL sound/core/snd-timer 0x5f6aecda snd_timer_close +EXPORT_SYMBOL sound/core/snd-timer 0x9c25e64a snd_timer_stop +EXPORT_SYMBOL sound/core/snd-timer 0xa78651c9 snd_timer_global_free +EXPORT_SYMBOL sound/core/snd-timer 0xbbe6cd52 snd_timer_resolution +EXPORT_SYMBOL sound/core/snd-timer 0xc27b7619 snd_timer_global_new +EXPORT_SYMBOL sound/core/snd-timer 0xca6518ed snd_timer_new +EXPORT_SYMBOL sound/core/snd-timer 0xd036d07a snd_timer_global_register +EXPORT_SYMBOL sound/core/snd-timer 0xd0eb636f snd_timer_open +EXPORT_SYMBOL sound/core/snd-timer 0xe0d08ef8 snd_timer_pause +EXPORT_SYMBOL sound/core/snd-timer 0xefe0f9da snd_timer_start +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0x73c4c993 snd_mpu401_uart_interrupt_tx +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xc515d390 snd_mpu401_uart_new +EXPORT_SYMBOL sound/drivers/mpu401/snd-mpu401-uart 0xfe618b58 snd_mpu401_uart_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x036f5b74 snd_opl3_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05060a19 snd_opl3_regmap +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x05b1bf24 snd_opl3_find_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x106a139f snd_opl3_load_patch +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x14f1923b snd_opl3_interrupt +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x4844f636 snd_opl3_init +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x5e8ff940 snd_opl3_timer_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x7361b9a6 snd_opl3_hwdep_new +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0x7e1428dd snd_opl3_reset +EXPORT_SYMBOL sound/drivers/opl3/snd-opl3-lib 0xc34963c7 snd_opl3_create +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x1cadb14b snd_vx_irq_handler +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x2ca48922 snd_vx_suspend +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x38d11b6f snd_vx_dsp_load +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x50ad95f5 snd_vx_check_reg_bit +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x741250bb snd_vx_dsp_boot +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x88bef506 snd_vx_setup_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0x9b35aa12 snd_vx_load_boot_image +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xa0e10508 snd_vx_resume +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xbe94844d snd_vx_free_firmware +EXPORT_SYMBOL sound/drivers/vx/snd-vx-lib 0xffedf260 snd_vx_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x1f6caac0 snd_ak4114_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x1fc28704 snd_ak4114_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x25a4362b snd_ak4114_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0x4a7ea3bb snd_ak4114_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xe1819fe6 snd_ak4114_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4114 0xe4a551bf snd_ak4114_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x1ea2298a snd_ak4117_create +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x3758dcb5 snd_ak4117_check_rate_and_errors +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0x522cd331 snd_ak4117_build +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xa8534511 snd_ak4117_reg_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xdba2e24f snd_ak4117_external_rate +EXPORT_SYMBOL sound/i2c/other/snd-ak4117 0xf835d2f4 snd_ak4117_reinit +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x0bbc1902 snd_akm4xxx_write +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x35548c88 snd_akm4xxx_reset +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0x560730a5 snd_akm4xxx_init +EXPORT_SYMBOL sound/i2c/other/snd-ak4xxx-adda 0xfd81cb9a snd_akm4xxx_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0x49176490 snd_pt2258_reset +EXPORT_SYMBOL sound/i2c/other/snd-pt2258 0xee0a08d8 snd_pt2258_build_controls +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x6196ec0e snd_tea575x_init +EXPORT_SYMBOL sound/i2c/other/snd-tea575x-tuner 0x973c77fd snd_tea575x_exit +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x13cbaf2e snd_cs8427_reg_write +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x50f62fd8 snd_cs8427_iec958_active +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x6039b003 snd_cs8427_iec958_pcm +EXPORT_SYMBOL sound/i2c/snd-cs8427 0x87e6ad95 snd_cs8427_iec958_build +EXPORT_SYMBOL sound/i2c/snd-cs8427 0xecf2a18f snd_cs8427_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0x0b8ad976 snd_i2c_probeaddr +EXPORT_SYMBOL sound/i2c/snd-i2c 0x3b397fdd snd_i2c_sendbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x6973e42c snd_i2c_readbytes +EXPORT_SYMBOL sound/i2c/snd-i2c 0x6a1f02a9 snd_i2c_bus_create +EXPORT_SYMBOL sound/i2c/snd-i2c 0xd3d1ffba snd_i2c_device_free +EXPORT_SYMBOL sound/i2c/snd-i2c 0xf2ace499 snd_i2c_device_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x1bc99362 snd_sbmixer_suspend +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x2b606d27 snd_sbdsp_create +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x3d05c4f2 snd_sbmixer_resume +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x55c31e3f snd_sbdsp_reset +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x5ec553aa snd_sbdsp_get_byte +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0x8bc3c50a snd_sbmixer_new +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xbac25f4b snd_sbmixer_read +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xc461bfd9 snd_sbmixer_write +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xceafd18c snd_sbmixer_add_ctl +EXPORT_SYMBOL sound/isa/sb/snd-sb-common 0xd8bcaa21 snd_sbdsp_command +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x0ba4ef1d snd_sb16dsp_interrupt +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x3976304f snd_sb16dsp_configure +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0x91775e2b snd_sb16dsp_get_pcm_ops +EXPORT_SYMBOL sound/isa/sb/snd-sb16-dsp 0xbe9a5270 snd_sb16dsp_pcm +EXPORT_SYMBOL sound/oss/ad1848 0x1583482b ad1848_init +EXPORT_SYMBOL sound/oss/ad1848 0x26c427ee ad1848_detect +EXPORT_SYMBOL sound/oss/ad1848 0x41faa6a4 attach_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x55262c70 probe_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0x9bf1cc62 ad1848_unload +EXPORT_SYMBOL sound/oss/ad1848 0xb29a9148 unload_ms_sound +EXPORT_SYMBOL sound/oss/ad1848 0xc04f6f67 ad1848_control +EXPORT_SYMBOL sound/oss/mpu401 0x4200d430 attach_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0x5febf284 unload_mpu401 +EXPORT_SYMBOL sound/oss/mpu401 0xd9ec5db4 probe_mpu401 +EXPORT_SYMBOL sound/oss/sb_lib 0x2cc65c73 sb_dsp_init +EXPORT_SYMBOL sound/oss/sb_lib 0x42424109 sb_be_quiet +EXPORT_SYMBOL sound/oss/sb_lib 0x450f9aea smw_free +EXPORT_SYMBOL sound/oss/sb_lib 0x74afd69c unload_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0x7aba10e7 probe_sbmpu +EXPORT_SYMBOL sound/oss/sb_lib 0xc4884969 sb_dsp_unload +EXPORT_SYMBOL sound/oss/sb_lib 0xd8a2731c sb_dsp_detect +EXPORT_SYMBOL sound/oss/sound 0x04c87ec8 compute_finetune +EXPORT_SYMBOL sound/oss/sound 0x06339815 sound_unload_synthdev +EXPORT_SYMBOL sound/oss/sound 0x0f280035 conf_printf +EXPORT_SYMBOL sound/oss/sound 0x17ba231d seq_input_event +EXPORT_SYMBOL sound/oss/sound 0x1b3df3cf sound_alloc_mixerdev +EXPORT_SYMBOL sound/oss/sound 0x1f395686 MIDIbuf_avail +EXPORT_SYMBOL sound/oss/sound 0x2161d5e8 sound_timer_init +EXPORT_SYMBOL sound/oss/sound 0x2aa31695 midi_synth_kill_note +EXPORT_SYMBOL sound/oss/sound 0x394cb088 sound_free_dma +EXPORT_SYMBOL sound/oss/sound 0x418f5fbe sound_close_dma +EXPORT_SYMBOL sound/oss/sound 0x4cd01bdd num_audiodevs +EXPORT_SYMBOL sound/oss/sound 0x4ff47e9d midi_synth_setup_voice +EXPORT_SYMBOL sound/oss/sound 0x51e354b2 sound_alloc_timerdev +EXPORT_SYMBOL sound/oss/sound 0x56504ca2 midi_synth_reset +EXPORT_SYMBOL sound/oss/sound 0x5b74b9fb mixer_devs +EXPORT_SYMBOL sound/oss/sound 0x5d986fc9 note_to_freq +EXPORT_SYMBOL sound/oss/sound 0x7679ee76 seq_copy_to_input +EXPORT_SYMBOL sound/oss/sound 0x7bdf0907 conf_printf2 +EXPORT_SYMBOL sound/oss/sound 0x7e1186bc sound_install_mixer +EXPORT_SYMBOL sound/oss/sound 0x88b23099 midi_devs +EXPORT_SYMBOL sound/oss/sound 0x892093e0 midi_synth_controller +EXPORT_SYMBOL sound/oss/sound 0x90bd9714 sequencer_timer +EXPORT_SYMBOL sound/oss/sound 0x987bcf12 DMAbuf_outputintr +EXPORT_SYMBOL sound/oss/sound 0x9a95733f sound_alloc_dma +EXPORT_SYMBOL sound/oss/sound 0x9bdaf24d midi_synth_start_note +EXPORT_SYMBOL sound/oss/sound 0x9d845b18 num_mixers +EXPORT_SYMBOL sound/oss/sound 0xa1d5f04f load_mixer_volumes +EXPORT_SYMBOL sound/oss/sound 0xa1eae7cf num_midis +EXPORT_SYMBOL sound/oss/sound 0xa41ead5f sound_unload_timerdev +EXPORT_SYMBOL sound/oss/sound 0xa51c913b sound_unload_mixerdev +EXPORT_SYMBOL sound/oss/sound 0xa6bb414c sound_unload_mididev +EXPORT_SYMBOL sound/oss/sound 0xa948751e sound_unload_audiodev +EXPORT_SYMBOL sound/oss/sound 0xaba70058 synth_devs +EXPORT_SYMBOL sound/oss/sound 0xad45df73 midi_synth_close +EXPORT_SYMBOL sound/oss/sound 0xaef743b2 midi_synth_ioctl +EXPORT_SYMBOL sound/oss/sound 0xb0225017 audio_devs +EXPORT_SYMBOL sound/oss/sound 0xb14b22cd midi_synth_hw_control +EXPORT_SYMBOL sound/oss/sound 0xb51587f6 do_midi_msg +EXPORT_SYMBOL sound/oss/sound 0xba413f87 sound_alloc_mididev +EXPORT_SYMBOL sound/oss/sound 0xba7dd041 midi_synth_bender +EXPORT_SYMBOL sound/oss/sound 0xc748d109 sound_alloc_synthdev +EXPORT_SYMBOL sound/oss/sound 0xc8c20e01 sound_timer_devs +EXPORT_SYMBOL sound/oss/sound 0xcc4b8797 sound_open_dma +EXPORT_SYMBOL sound/oss/sound 0xd834275e sound_install_audiodrv +EXPORT_SYMBOL sound/oss/sound 0xd85be938 midi_synth_set_instr +EXPORT_SYMBOL sound/oss/sound 0xdb400afa midi_synth_panning +EXPORT_SYMBOL sound/oss/sound 0xe056b71c DMAbuf_start_dma +EXPORT_SYMBOL sound/oss/sound 0xe2675a79 sound_timer_interrupt +EXPORT_SYMBOL sound/oss/sound 0xeb315d99 DMAbuf_inputintr +EXPORT_SYMBOL sound/oss/sound 0xf1ea8a20 midi_synth_aftertouch +EXPORT_SYMBOL sound/oss/sound 0xf6b3a2fb midi_synth_open +EXPORT_SYMBOL sound/oss/sound 0xf7426da3 midi_synth_load_patch +EXPORT_SYMBOL sound/oss/sound 0xf78f6363 sequencer_init +EXPORT_SYMBOL sound/oss/sound 0xfa6871be sound_timer_syncinterval +EXPORT_SYMBOL sound/oss/sound 0xfddcbfb3 midi_synth_send_sysex +EXPORT_SYMBOL sound/oss/uart401 0x46248c57 uart401intr +EXPORT_SYMBOL sound/oss/uart401 0x962bf60b probe_uart401 +EXPORT_SYMBOL sound/oss/uart401 0xecfdd9c9 unload_uart401 +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x00b77dd5 snd_ac97_bus +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x0a7ab1ba snd_ac97_read +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x1d2d7717 snd_ac97_write +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x37fbd68a snd_ac97_pcm_open +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x384e9532 snd_ac97_update +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x46c82a01 snd_ac97_write_cache +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x57613ffe snd_ac97_pcm_close +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x85252551 snd_ac97_mixer +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8c056a47 snd_ac97_suspend +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x8f18c738 snd_ac97_set_rate +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x917c8ea0 snd_ac97_pcm_assign +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0x9b9c5348 snd_ac97_resume +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xa2b8a4a5 snd_ac97_get_short_name +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xa9106947 snd_ac97_pcm_double_rate_rules +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xbf13957f snd_ac97_update_power +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xdaacebfb snd_ac97_tune_hardware +EXPORT_SYMBOL sound/pci/ac97/snd-ac97-codec 0xecb0ebb5 snd_ac97_update_bits +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x0ab1580d snd_emu10k1_synth_copy_from_user +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x793ada23 snd_emu10k1_voice_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0x86271ec7 snd_emu10k1_synth_bzero +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xc3e5a7b8 snd_emu10k1_synth_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xcf32f696 snd_emu10k1_memblk_map +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd3e32780 snd_emu10k1_voice_free +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xd9a778f0 snd_emu10k1_synth_alloc +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xdc47e0e1 snd_emu10k1_ptr_read +EXPORT_SYMBOL sound/pci/emu10k1/snd-emu10k1 0xe9218c24 snd_emu10k1_ptr_write +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xbbf71823 snd_ice1712_akm4xxx_init +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xbca81734 snd_ice1712_akm4xxx_free +EXPORT_SYMBOL sound/pci/ice1712/snd-ice17xx-ak4xxx 0xd60d07fa snd_ice1712_akm4xxx_build_controls +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x1c7f9b58 oxygen_pci_suspend +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x2aa796dc oxygen_pci_resume +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x39b0cb4a oxygen_read32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x4bbc738e oxygen_read8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x54c094e1 oxygen_pci_probe +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x57565c89 oxygen_read_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x64adc05c oxygen_write_ac97_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x68902447 oxygen_write8_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x6c46630a oxygen_write_spi +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x7a9f1958 oxygen_reset_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0x952a0d29 oxygen_write32 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xae6a2218 oxygen_write8 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xc03ac7ba oxygen_read16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xced1bdd5 oxygen_pci_remove +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xdae26ef9 oxygen_write_ac97 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xe61213cd oxygen_write32_masked +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xe6408301 oxygen_write16 +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xed8d2e64 oxygen_write_i2c +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xf4d4359a oxygen_write_uart +EXPORT_SYMBOL sound/pci/oxygen/snd-oxygen-lib 0xfb65564c oxygen_write16_masked +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x3d1092d0 snd_trident_start_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x51ba1c39 snd_trident_free_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0x6c3ceb39 snd_trident_alloc_voice +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xb79e0311 snd_trident_write_voice_regs +EXPORT_SYMBOL sound/pci/trident/snd-trident 0xd2db4a82 snd_trident_stop_voice +EXPORT_SYMBOL sound/sound_firmware 0x39e3dd23 mod_firmware_load +EXPORT_SYMBOL sound/soundcore 0x14aba2e9 register_sound_midi +EXPORT_SYMBOL sound/soundcore 0x3ad7916b sound_class +EXPORT_SYMBOL sound/soundcore 0x6ad49501 register_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x7afc9d8a unregister_sound_mixer +EXPORT_SYMBOL sound/soundcore 0x99c95fa5 unregister_sound_special +EXPORT_SYMBOL sound/soundcore 0xa4acbf2d register_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xbfeeb1ff register_sound_special +EXPORT_SYMBOL sound/soundcore 0xcd083b10 unregister_sound_dsp +EXPORT_SYMBOL sound/soundcore 0xf52b61ba register_sound_special_device +EXPORT_SYMBOL sound/soundcore 0xfdab6de3 unregister_sound_midi +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x3437dea9 snd_emux_terminate_all +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x655cb202 snd_sf_linear_to_log +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x6ee7e233 snd_emux_free +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x70aa6617 snd_emux_new +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0x8aec6be0 snd_emux_register +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xea7cf402 snd_emux_unlock_voice +EXPORT_SYMBOL sound/synth/emux/snd-emux-synth 0xedf81621 snd_emux_lock_voice +EXPORT_SYMBOL sound/synth/snd-util-mem 0x20d65978 snd_util_memhdr_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x24886293 __snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0x569d614e snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0x7a007343 snd_util_memhdr_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd197c5db __snd_util_memblk_new +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd34b56e4 __snd_util_mem_free +EXPORT_SYMBOL sound/synth/snd-util-mem 0xd8b55e81 snd_util_mem_alloc +EXPORT_SYMBOL sound/synth/snd-util-mem 0xf158252c snd_util_mem_avail +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x16756dc0 snd_usbmidi_input_start +EXPORT_SYMBOL sound/usb/snd-usb-lib 0x63343b1d snd_usbmidi_input_stop +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xd9d2bb03 snd_usbmidi_disconnect +EXPORT_SYMBOL sound/usb/snd-usb-lib 0xebcb67bb snd_usb_create_midi_interface +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x18571732 dm_mem_cache_client_create +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x3c723c4f dm_mem_cache_alloc +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x46c4c70a dm_mem_cache_client_destroy +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x9390a15e dm_mem_cache_grow +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0x9d133e59 dm_mem_cache_shrink +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-mem-cache 0xc866ec78 dm_mem_cache_free +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-message 0x920a7a41 dm_message_parse +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x0050f52c rh_get_region_key +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x02198b66 rh_delay +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x275fdd04 rh_recovery_start +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x29e53a6b rh_dec +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x2db33b15 rh_delay_by_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x5c2a0632 rh_recovery_end +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x62842029 rh_flush +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x69c8d13c rh_inc_pending +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x83baca27 rh_state +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x87d45b9d rh_get_region_size +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0x9ffc4e07 rh_bio_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xa923d788 rh_start_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xac274ed3 rh_stop_recovery +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb513be98 rh_update_states +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xb7aa1ca6 rh_init +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbb748327 rh_reg_set_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xbd3452f9 rh_sector_to_region +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4fdf256 rh_recovery_prepare +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc4ff7745 rh_reg_get_context +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xc57bafec rh_exit +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xe9f7f71a rh_region_to_sector +EXPORT_SYMBOL ubuntu/dm-raid4-5/dm-region_hash 0xf3e0a2b0 rh_inc +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x29c887a9 set_tx_channels +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0x7789312a cmdir_write +EXPORT_SYMBOL ubuntu/lirc/lirc_cmdir/commandir 0xf4c689aa cmdir_read +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0x93413ebb lirc_register_plugin +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xbbc00c08 lirc_get_pdata +EXPORT_SYMBOL ubuntu/lirc/lirc_dev/lirc_dev 0xe96379eb lirc_unregister_plugin +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x317f8229 ov511_register_decomp_module +EXPORT_SYMBOL ubuntu/misc/media/ov511/ov511 0x7db9be3c ov511_deregister_decomp_module +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x048227a8 p80211_allow_ioctls +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x0d4705f1 p80211netdev_rx +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x13cf8eb2 wlan_unsetup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x1cdd2707 p80211skb_free +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x24dd3c53 unregister_wlandev +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x3aabc9d9 p80211netdev_hwremoved +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x69124844 p80211_suspend +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x6e20f06c p80211skb_rxmeta_attach +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x7436f36c p80211_resume +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x8431b63f wlan_setup +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0x9f6fdf68 p80211wext_event_associated +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xb0af0799 wlan_wext_write +EXPORT_SYMBOL ubuntu/misc/wireless/p80211/p80211 0xe5f5d958 register_wlandev +EXPORT_SYMBOL vmlinux 0x00000000 per_cpu__softirq_work_list +EXPORT_SYMBOL vmlinux 0x002fbcb7 vfs_readdir +EXPORT_SYMBOL vmlinux 0x003ed923 pci_release_region +EXPORT_SYMBOL vmlinux 0x005c155f ppp_input_error +EXPORT_SYMBOL vmlinux 0x00801678 flush_scheduled_work +EXPORT_SYMBOL vmlinux 0x0080fcd6 tcf_hash_release +EXPORT_SYMBOL vmlinux 0x009d258f _write_lock +EXPORT_SYMBOL vmlinux 0x00af0ce7 invalidate_inodes +EXPORT_SYMBOL vmlinux 0x00beea50 mmc_add_host +EXPORT_SYMBOL vmlinux 0x01000e51 schedule +EXPORT_SYMBOL vmlinux 0x010c8932 agp_bind_memory +EXPORT_SYMBOL vmlinux 0x01139ffc max_mapnr +EXPORT_SYMBOL vmlinux 0x011aee6c mmc_wait_for_cmd +EXPORT_SYMBOL vmlinux 0x015a4521 pci_bus_alloc_resource +EXPORT_SYMBOL vmlinux 0x016555a0 dev_mc_sync +EXPORT_SYMBOL vmlinux 0x017751cd phy_stop +EXPORT_SYMBOL vmlinux 0x0179d81c bitmap_start_sync +EXPORT_SYMBOL vmlinux 0x0186d073 percpu_counter_set +EXPORT_SYMBOL vmlinux 0x01902adf netpoll_trap +EXPORT_SYMBOL vmlinux 0x01a4aab6 set_irq_chip_data +EXPORT_SYMBOL vmlinux 0x01cb0568 sock_release +EXPORT_SYMBOL vmlinux 0x01ceb4aa kill_anon_super +EXPORT_SYMBOL vmlinux 0x01d0dcbb pci_prepare_to_sleep +EXPORT_SYMBOL vmlinux 0x01d19038 acpi_enable_subsystem +EXPORT_SYMBOL vmlinux 0x01f8415c seq_bitmap_list +EXPORT_SYMBOL vmlinux 0x0204dc42 agp_generic_create_gatt_table +EXPORT_SYMBOL vmlinux 0x02124474 ip_send_check +EXPORT_SYMBOL vmlinux 0x02138f9d bioset_integrity_create +EXPORT_SYMBOL vmlinux 0x0237b57a arch_unregister_cpu +EXPORT_SYMBOL vmlinux 0x024c0b1d vc_cons +EXPORT_SYMBOL vmlinux 0x0256389f bit_waitqueue +EXPORT_SYMBOL vmlinux 0x02649054 security_sock_rcv_skb +EXPORT_SYMBOL vmlinux 0x02681888 load_nls_default +EXPORT_SYMBOL vmlinux 0x027467be dm_register_target +EXPORT_SYMBOL vmlinux 0x0277dc24 i2c_smbus_write_byte +EXPORT_SYMBOL vmlinux 0x029444f0 native_read_tsc +EXPORT_SYMBOL vmlinux 0x02a14b69 flock_lock_file_wait +EXPORT_SYMBOL vmlinux 0x02a18c74 nf_conntrack_destroy +EXPORT_SYMBOL vmlinux 0x02a6ce5a crc16_table +EXPORT_SYMBOL vmlinux 0x02a86a53 scsi_eh_restore_cmnd +EXPORT_SYMBOL vmlinux 0x02a96c81 jbd2_journal_init_dev +EXPORT_SYMBOL vmlinux 0x02aff2f4 acpi_install_gpe_handler +EXPORT_SYMBOL vmlinux 0x02b59c84 neigh_seq_next +EXPORT_SYMBOL vmlinux 0x02d81845 audit_log_task_context +EXPORT_SYMBOL vmlinux 0x02e1af76 vfs_writev +EXPORT_SYMBOL vmlinux 0x030ad9c5 pci_remove_behind_bridge +EXPORT_SYMBOL vmlinux 0x031a4974 uart_remove_one_port +EXPORT_SYMBOL vmlinux 0x0334da4e scsi_command_size_tbl +EXPORT_SYMBOL vmlinux 0x0352cfc4 unregister_8022_client +EXPORT_SYMBOL vmlinux 0x03574b79 inet_add_protocol +EXPORT_SYMBOL vmlinux 0x037a0cba kfree +EXPORT_SYMBOL vmlinux 0x0380a84c i2c_smbus_read_i2c_block_data +EXPORT_SYMBOL vmlinux 0x03a99c3b rb_prev +EXPORT_SYMBOL vmlinux 0x03c06156 bitmap_fold +EXPORT_SYMBOL vmlinux 0x03c8597f bt_sock_link +EXPORT_SYMBOL vmlinux 0x03e134eb pci_find_bus +EXPORT_SYMBOL vmlinux 0x03fd2571 vm_unmap_ram +EXPORT_SYMBOL vmlinux 0x0422fe4a inet_csk_timer_bug_msg +EXPORT_SYMBOL vmlinux 0x0423b6eb bio_integrity_advance +EXPORT_SYMBOL vmlinux 0x043998ba log_wait_commit +EXPORT_SYMBOL vmlinux 0x04442da6 atm_dev_lookup +EXPORT_SYMBOL vmlinux 0x044fbf49 mempool_kzalloc +EXPORT_SYMBOL vmlinux 0x0487f831 fb_find_best_display +EXPORT_SYMBOL vmlinux 0x0495829e xrlim_allow +EXPORT_SYMBOL vmlinux 0x04a83fa1 __scm_destroy +EXPORT_SYMBOL vmlinux 0x04c84a4f skb_pull +EXPORT_SYMBOL vmlinux 0x04d8c750 release_perfctr_nmi +EXPORT_SYMBOL vmlinux 0x04de2cff inet_bind +EXPORT_SYMBOL vmlinux 0x04fd04b3 redraw_screen +EXPORT_SYMBOL vmlinux 0x055721dd mntput_no_expire +EXPORT_SYMBOL vmlinux 0x055c94e0 read_cache_page +EXPORT_SYMBOL vmlinux 0x05624e45 md_wait_for_blocked_rdev +EXPORT_SYMBOL vmlinux 0x057dee90 md_error +EXPORT_SYMBOL vmlinux 0x058c75d9 acpi_get_pci_id +EXPORT_SYMBOL vmlinux 0x05a82ba8 xfrm_policy_byid +EXPORT_SYMBOL vmlinux 0x05c6dacc ilookup5_nowait +EXPORT_SYMBOL vmlinux 0x05d357a2 xfrm_prepare_input +EXPORT_SYMBOL vmlinux 0x05d6f228 pagevec_lookup +EXPORT_SYMBOL vmlinux 0x05e28d43 __first_cpu +EXPORT_SYMBOL vmlinux 0x0606e82b sock_create_lite +EXPORT_SYMBOL vmlinux 0x061651be strcat +EXPORT_SYMBOL vmlinux 0x0636da5d genphy_config_aneg +EXPORT_SYMBOL vmlinux 0x063cd37b scsi_adjust_queue_depth +EXPORT_SYMBOL vmlinux 0x06743511 simple_unlink +EXPORT_SYMBOL vmlinux 0x067d8d35 security_release_secctx +EXPORT_SYMBOL vmlinux 0x068c7263 ioremap_cache +EXPORT_SYMBOL vmlinux 0x0693d608 pci_back_from_sleep +EXPORT_SYMBOL vmlinux 0x06a485f2 __krealloc +EXPORT_SYMBOL vmlinux 0x06aa3084 ppp_register_compressor +EXPORT_SYMBOL vmlinux 0x06aaea98 get_sb_pseudo +EXPORT_SYMBOL vmlinux 0x06c3156a generic_write_checks +EXPORT_SYMBOL vmlinux 0x06d728b1 tcp_parse_md5sig_option +EXPORT_SYMBOL vmlinux 0x06fe3b14 default_grn +EXPORT_SYMBOL vmlinux 0x070b22d4 pci_iounmap +EXPORT_SYMBOL vmlinux 0x070d4db6 blk_init_tags +EXPORT_SYMBOL vmlinux 0x0727c4f3 iowrite8 +EXPORT_SYMBOL vmlinux 0x073dfa12 generate_resume_trace +EXPORT_SYMBOL vmlinux 0x07480749 simple_rmdir +EXPORT_SYMBOL vmlinux 0x076983a7 sock_no_connect +EXPORT_SYMBOL vmlinux 0x077078fb __module_put_and_exit +EXPORT_SYMBOL vmlinux 0x078d9032 md_write_end +EXPORT_SYMBOL vmlinux 0x078db55e blk_queue_resize_tags +EXPORT_SYMBOL vmlinux 0x0799aca4 local_bh_enable +EXPORT_SYMBOL vmlinux 0x079cd7f1 ns_to_timeval +EXPORT_SYMBOL vmlinux 0x07a890c8 fb_alloc_cmap +EXPORT_SYMBOL vmlinux 0x07c6b8cc scsi_get_command +EXPORT_SYMBOL vmlinux 0x07cc4a5d printk_timed_ratelimit +EXPORT_SYMBOL vmlinux 0x07cd03d8 tcf_generic_walker +EXPORT_SYMBOL vmlinux 0x07d9b783 scsi_nl_send_vendor_msg +EXPORT_SYMBOL vmlinux 0x07e4b19f generic_getxattr +EXPORT_SYMBOL vmlinux 0x082c3213 pci_root_buses +EXPORT_SYMBOL vmlinux 0x083b705b journal_extend +EXPORT_SYMBOL vmlinux 0x0845e96d textsearch_prepare +EXPORT_SYMBOL vmlinux 0x084635ff scsi_nonblockable_ioctl +EXPORT_SYMBOL vmlinux 0x0866b318 xfrm_policy_alloc +EXPORT_SYMBOL vmlinux 0x08a8fc54 framebuffer_alloc +EXPORT_SYMBOL vmlinux 0x08acd0e4 scsi_dma_unmap +EXPORT_SYMBOL vmlinux 0x08b35d38 netdev_bonding_change +EXPORT_SYMBOL vmlinux 0x08bd004b ppp_unit_number +EXPORT_SYMBOL vmlinux 0x08cb528f eth_header_cache_update +EXPORT_SYMBOL vmlinux 0x08d18fac bio_integrity_free +EXPORT_SYMBOL vmlinux 0x08d98d80 md_register_thread +EXPORT_SYMBOL vmlinux 0x0933aae1 efi_enabled +EXPORT_SYMBOL vmlinux 0x0948cde9 num_physpages +EXPORT_SYMBOL vmlinux 0x094ec99b request_firmware_nowait +EXPORT_SYMBOL vmlinux 0x0954446d skb_copy_and_csum_dev +EXPORT_SYMBOL vmlinux 0x09775cdc kref_get +EXPORT_SYMBOL vmlinux 0x098431ba acpi_get_current_resources +EXPORT_SYMBOL vmlinux 0x098b71c6 fb_dealloc_cmap +EXPORT_SYMBOL vmlinux 0x09bb1c71 mnt_pin +EXPORT_SYMBOL vmlinux 0x09c55cec schedule_timeout_interruptible +EXPORT_SYMBOL vmlinux 0x09cc758d keyring_search +EXPORT_SYMBOL vmlinux 0x09d29dff key_link +EXPORT_SYMBOL vmlinux 0x09d44df9 in_lock_functions +EXPORT_SYMBOL vmlinux 0x09e3272a swiotlb_sync_single_for_device +EXPORT_SYMBOL vmlinux 0x09eadc1a tcf_action_exec +EXPORT_SYMBOL vmlinux 0x0a2487e0 unblock_all_signals +EXPORT_SYMBOL vmlinux 0x0a55aa4b posix_lock_file_wait +EXPORT_SYMBOL vmlinux 0x0a6dccb5 tcp_enter_memory_pressure +EXPORT_SYMBOL vmlinux 0x0a8ebd21 agp_allocate_memory +EXPORT_SYMBOL vmlinux 0x0a9e090a generic_listxattr +EXPORT_SYMBOL vmlinux 0x0ac9f221 in_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0x0acb1a3c __bitmap_shift_right +EXPORT_SYMBOL vmlinux 0x0ae43cfc lookup_one_len +EXPORT_SYMBOL vmlinux 0x0b1284f2 aio_put_req +EXPORT_SYMBOL vmlinux 0x0b15192a seq_printf +EXPORT_SYMBOL vmlinux 0x0b1beb31 vmalloc_32_user +EXPORT_SYMBOL vmlinux 0x0b2a55bb generic_file_mmap +EXPORT_SYMBOL vmlinux 0x0b44c9e9 lock_may_read +EXPORT_SYMBOL vmlinux 0x0b635a43 framebuffer_release +EXPORT_SYMBOL vmlinux 0x0b742fd7 simple_strtol +EXPORT_SYMBOL vmlinux 0x0b9bcfa1 vmtruncate +EXPORT_SYMBOL vmlinux 0x0ba1c90a journal_get_write_access +EXPORT_SYMBOL vmlinux 0x0ba2af0d vfs_quota_on +EXPORT_SYMBOL vmlinux 0x0bb995cf nf_register_sockopt +EXPORT_SYMBOL vmlinux 0x0bd60355 check_disk_change +EXPORT_SYMBOL vmlinux 0x0bdfc39c i2c_smbus_write_i2c_block_data +EXPORT_SYMBOL vmlinux 0x0be9b6e5 find_vma +EXPORT_SYMBOL vmlinux 0x0c02642e __set_page_dirty_nobuffers +EXPORT_SYMBOL vmlinux 0x0c082413 simple_transaction_read +EXPORT_SYMBOL vmlinux 0x0c0afe5b locks_copy_lock +EXPORT_SYMBOL vmlinux 0x0c255f01 ipv6_chk_addr +EXPORT_SYMBOL vmlinux 0x0c5ef91b per_cpu__vm_event_states +EXPORT_SYMBOL vmlinux 0x0c65e73c scsi_normalize_sense +EXPORT_SYMBOL vmlinux 0x0c79500f bio_free +EXPORT_SYMBOL vmlinux 0x0c881589 hci_send_acl +EXPORT_SYMBOL vmlinux 0x0c8c9e99 scsi_show_extd_sense +EXPORT_SYMBOL vmlinux 0x0ca1efd8 neigh_sysctl_register +EXPORT_SYMBOL vmlinux 0x0ca7b7a8 acpi_check_region +EXPORT_SYMBOL vmlinux 0x0cad9317 task_nice +EXPORT_SYMBOL vmlinux 0x0cb05519 xfrm4_rcv +EXPORT_SYMBOL vmlinux 0x0ce346dd write_one_page +EXPORT_SYMBOL vmlinux 0x0cf65e7f deactivate_super +EXPORT_SYMBOL vmlinux 0x0d089d85 __getblk +EXPORT_SYMBOL vmlinux 0x0d26a76d _write_lock_irq +EXPORT_SYMBOL vmlinux 0x0d2bce97 scsi_unblock_requests +EXPORT_SYMBOL vmlinux 0x0d3dda14 acpi_get_type +EXPORT_SYMBOL vmlinux 0x0d51c3b7 __sk_dst_check +EXPORT_SYMBOL vmlinux 0x0d542439 __ipv6_addr_type +EXPORT_SYMBOL vmlinux 0x0d6457a4 neigh_ifdown +EXPORT_SYMBOL vmlinux 0x0d790c19 inet_del_protocol +EXPORT_SYMBOL vmlinux 0x0d846099 iget_locked +EXPORT_SYMBOL vmlinux 0x0d8ab500 param_set_copystring +EXPORT_SYMBOL vmlinux 0x0da10ec3 security_sock_graft +EXPORT_SYMBOL vmlinux 0x0dd9d75e x86_dma_fallback_dev +EXPORT_SYMBOL vmlinux 0x0e0252ec downgrade_write +EXPORT_SYMBOL vmlinux 0x0e30dc7e sock_alloc_send_skb +EXPORT_SYMBOL vmlinux 0x0e52592a panic +EXPORT_SYMBOL vmlinux 0x0e608c9c i2c_clients_command +EXPORT_SYMBOL vmlinux 0x0e762d6e request_module +EXPORT_SYMBOL vmlinux 0x0ea239aa xfrm_register_km +EXPORT_SYMBOL vmlinux 0x0eaa7fd1 scsi_device_resume +EXPORT_SYMBOL vmlinux 0x0ecb9204 new_inode +EXPORT_SYMBOL vmlinux 0x0eccd840 skb_truesize_bug +EXPORT_SYMBOL vmlinux 0x0ed43f66 pci_set_power_state +EXPORT_SYMBOL vmlinux 0x0edbde1a jbd2_journal_init_jbd_inode +EXPORT_SYMBOL vmlinux 0x0edcbef0 xfrm_register_type +EXPORT_SYMBOL vmlinux 0x0ef50f01 unregister_md_personality +EXPORT_SYMBOL vmlinux 0x0f0491d7 tcp_create_openreq_child +EXPORT_SYMBOL vmlinux 0x0f0b6a49 bt_sock_wait_state +EXPORT_SYMBOL vmlinux 0x0f3addde put_disk +EXPORT_SYMBOL vmlinux 0x0f504a85 jbd2_journal_get_create_access +EXPORT_SYMBOL vmlinux 0x0fa34479 dm_dirty_log_type_unregister +EXPORT_SYMBOL vmlinux 0x0faef0ed __tasklet_schedule +EXPORT_SYMBOL vmlinux 0x0fc5e8eb radix_tree_gang_lookup_slot +EXPORT_SYMBOL vmlinux 0x0fd00a68 acpi_clear_event +EXPORT_SYMBOL vmlinux 0x0fd11422 nf_unregister_sockopt +EXPORT_SYMBOL vmlinux 0x0fde54cc __skb_checksum_complete +EXPORT_SYMBOL vmlinux 0x0fea0372 jbd2_journal_extend +EXPORT_SYMBOL vmlinux 0x0ff2b602 slhc_compress +EXPORT_SYMBOL vmlinux 0x100ac59d truncate_inode_pages_range +EXPORT_SYMBOL vmlinux 0x101228ca scsi_remove_device +EXPORT_SYMBOL vmlinux 0x10153581 remove_proc_entry +EXPORT_SYMBOL vmlinux 0x1072a394 csum_partial_copy_from_user +EXPORT_SYMBOL vmlinux 0x107a105c genphy_config_advert +EXPORT_SYMBOL vmlinux 0x10998e7e ethtool_op_get_tso +EXPORT_SYMBOL vmlinux 0x109f5dce inet_frag_find +EXPORT_SYMBOL vmlinux 0x10bc1ac0 proc_dointvec_jiffies +EXPORT_SYMBOL vmlinux 0x10ee20bb default_blu +EXPORT_SYMBOL vmlinux 0x111fef58 kmem_cache_size +EXPORT_SYMBOL vmlinux 0x11267875 scsi_extd_sense_format +EXPORT_SYMBOL vmlinux 0x11328b06 scsi_report_bus_reset +EXPORT_SYMBOL vmlinux 0x1139e1d7 pcim_enable_device +EXPORT_SYMBOL vmlinux 0x11488dd6 init_task +EXPORT_SYMBOL vmlinux 0x1149e9b6 per_cpu__softnet_data +EXPORT_SYMBOL vmlinux 0x116240db key_instantiate_and_link +EXPORT_SYMBOL vmlinux 0x1163f0a7 blk_max_low_pfn +EXPORT_SYMBOL vmlinux 0x1166b8c9 serio_rescan +EXPORT_SYMBOL vmlinux 0x117093be qdisc_class_hash_init +EXPORT_SYMBOL vmlinux 0x11877fff pci_wake_from_d3 +EXPORT_SYMBOL vmlinux 0x118f01ea putname +EXPORT_SYMBOL vmlinux 0x11a18b14 __wake_up_bit +EXPORT_SYMBOL vmlinux 0x11dab346 __down_read +EXPORT_SYMBOL vmlinux 0x1203262a pci_unmap_rom +EXPORT_SYMBOL vmlinux 0x121c614c default_llseek +EXPORT_SYMBOL vmlinux 0x124b74d1 tcp_hashinfo +EXPORT_SYMBOL vmlinux 0x125cbba9 end_buffer_write_sync +EXPORT_SYMBOL vmlinux 0x125fbca7 cad_pid +EXPORT_SYMBOL vmlinux 0x126970ed param_set_uint +EXPORT_SYMBOL vmlinux 0x12ba1e92 mmc_suspend_host +EXPORT_SYMBOL vmlinux 0x12da6695 i2c_verify_client +EXPORT_SYMBOL vmlinux 0x12e84703 agp_generic_enable +EXPORT_SYMBOL vmlinux 0x12e8e17d scsi_is_host_device +EXPORT_SYMBOL vmlinux 0x12ebdf0b inet_listen +EXPORT_SYMBOL vmlinux 0x12f99022 inet_frags_init_net +EXPORT_SYMBOL vmlinux 0x130f3abb i2c_smbus_write_word_data +EXPORT_SYMBOL vmlinux 0x132f45f2 cookie_check_timestamp +EXPORT_SYMBOL vmlinux 0x1334dc5e scsi_eh_prep_cmnd +EXPORT_SYMBOL vmlinux 0x13553601 sk_reset_timer +EXPORT_SYMBOL vmlinux 0x1378e714 acpi_video_display_switch_support +EXPORT_SYMBOL vmlinux 0x138d4983 agp_put_bridge +EXPORT_SYMBOL vmlinux 0x1393f520 qdisc_calculate_pkt_len +EXPORT_SYMBOL vmlinux 0x13bd9417 kick_iocb +EXPORT_SYMBOL vmlinux 0x13f71731 tcf_hash_lookup +EXPORT_SYMBOL vmlinux 0x1430e6e0 unregister_acpi_notifier +EXPORT_SYMBOL vmlinux 0x144903c0 __tcf_em_tree_match +EXPORT_SYMBOL vmlinux 0x146118b1 thermal_cooling_device_unregister +EXPORT_SYMBOL vmlinux 0x1477c728 flow_cache_lookup +EXPORT_SYMBOL vmlinux 0x147cbb76 elv_dispatch_sort +EXPORT_SYMBOL vmlinux 0x149112ce set_user_nice +EXPORT_SYMBOL vmlinux 0x149e124f vfs_create +EXPORT_SYMBOL vmlinux 0x14a87866 alloc_fddidev +EXPORT_SYMBOL vmlinux 0x14af0cf7 gen_pool_destroy +EXPORT_SYMBOL vmlinux 0x14c524ab f_setown +EXPORT_SYMBOL vmlinux 0x14d5c9ff dev_remove_pack +EXPORT_SYMBOL vmlinux 0x14e9bae5 cdrom_open +EXPORT_SYMBOL vmlinux 0x150d66e1 tcp_read_sock +EXPORT_SYMBOL vmlinux 0x1544aad4 genl_register_mc_group +EXPORT_SYMBOL vmlinux 0x1551dc51 bitmap_find_free_region +EXPORT_SYMBOL vmlinux 0x15666734 da903x_query_status +EXPORT_SYMBOL vmlinux 0x15b712c3 fifo_create_dflt +EXPORT_SYMBOL vmlinux 0x15ef2dd9 kfifo_free +EXPORT_SYMBOL vmlinux 0x15f7a8dc netif_carrier_on +EXPORT_SYMBOL vmlinux 0x165b5a26 serio_unregister_child_port +EXPORT_SYMBOL vmlinux 0x166449c5 tcp_parse_options +EXPORT_SYMBOL vmlinux 0x1675606f bad_dma_address +EXPORT_SYMBOL vmlinux 0x167e7f9d __get_user_1 +EXPORT_SYMBOL vmlinux 0x169c7358 serio_interrupt +EXPORT_SYMBOL vmlinux 0x16a35878 _read_unlock +EXPORT_SYMBOL vmlinux 0x16a895b8 km_policy_notify +EXPORT_SYMBOL vmlinux 0x16b2e0e2 setup_arg_pages +EXPORT_SYMBOL vmlinux 0x16bbba4f nf_getsockopt +EXPORT_SYMBOL vmlinux 0x16dafd80 unregister_qdisc +EXPORT_SYMBOL vmlinux 0x16e4e983 set_pages_x +EXPORT_SYMBOL vmlinux 0x16e51ddf mapping_tagged +EXPORT_SYMBOL vmlinux 0x16f98e8c posix_test_lock +EXPORT_SYMBOL vmlinux 0x170c25ee acpi_get_next_object +EXPORT_SYMBOL vmlinux 0x17178730 blkdev_issue_flush +EXPORT_SYMBOL vmlinux 0x172ed4d7 __vmalloc +EXPORT_SYMBOL vmlinux 0x175eae30 generic_file_aio_read +EXPORT_SYMBOL vmlinux 0x178ff66a pci_bus_add_devices +EXPORT_SYMBOL vmlinux 0x17a33d26 add_to_page_cache_locked +EXPORT_SYMBOL vmlinux 0x17a76e71 rb_first +EXPORT_SYMBOL vmlinux 0x17c85a66 radix_tree_tagged +EXPORT_SYMBOL vmlinux 0x17df17bc sysctl_tcp_ecn +EXPORT_SYMBOL vmlinux 0x17e16be9 directly_mappable_cdev_bdi +EXPORT_SYMBOL vmlinux 0x17f3cd19 sock_no_sendpage +EXPORT_SYMBOL vmlinux 0x17f5928e bdi_register +EXPORT_SYMBOL vmlinux 0x181b6ff2 mempool_resize +EXPORT_SYMBOL vmlinux 0x183fa88b mempool_alloc_slab +EXPORT_SYMBOL vmlinux 0x18471524 pnp_device_detach +EXPORT_SYMBOL vmlinux 0x1876e4c6 netlink_kernel_release +EXPORT_SYMBOL vmlinux 0x187929b3 nla_append +EXPORT_SYMBOL vmlinux 0x189b6bac memory_read_from_buffer +EXPORT_SYMBOL vmlinux 0x18bb9aff nf_log_register +EXPORT_SYMBOL vmlinux 0x18d78421 may_umount +EXPORT_SYMBOL vmlinux 0x18d78905 mdiobus_alloc +EXPORT_SYMBOL vmlinux 0x18e8841b register_gifconf +EXPORT_SYMBOL vmlinux 0x18f3d73c skb_over_panic +EXPORT_SYMBOL vmlinux 0x18f5188a key_put +EXPORT_SYMBOL vmlinux 0x19006762 kobject_add +EXPORT_SYMBOL vmlinux 0x190c63d3 dma_pool_destroy +EXPORT_SYMBOL vmlinux 0x19218f7d flush_signals +EXPORT_SYMBOL vmlinux 0x192f952d scsi_execute +EXPORT_SYMBOL vmlinux 0x19391763 iov_iter_fault_in_readable +EXPORT_SYMBOL vmlinux 0x19603ad3 dev_get_by_name +EXPORT_SYMBOL vmlinux 0x196f2b26 sock_no_poll +EXPORT_SYMBOL vmlinux 0x1982a842 km_new_mapping +EXPORT_SYMBOL vmlinux 0x1985ed3c prepare_to_wait_exclusive +EXPORT_SYMBOL vmlinux 0x199ed0cd net_disable_timestamp +EXPORT_SYMBOL vmlinux 0x19a8ef70 skb_recycle_check +EXPORT_SYMBOL vmlinux 0x19c09104 filemap_flush +EXPORT_SYMBOL vmlinux 0x19d5d20a acpi_walk_namespace +EXPORT_SYMBOL vmlinux 0x19daa9bb pci_match_id +EXPORT_SYMBOL vmlinux 0x19e8ed6b find_task_by_pid_type_ns +EXPORT_SYMBOL vmlinux 0x19f3c264 __free_pages +EXPORT_SYMBOL vmlinux 0x1a1ab15d tty_mutex +EXPORT_SYMBOL vmlinux 0x1a1d7bed dm_io_client_create +EXPORT_SYMBOL vmlinux 0x1a23f361 generic_writepages +EXPORT_SYMBOL vmlinux 0x1a270128 blk_rq_unmap_user +EXPORT_SYMBOL vmlinux 0x1a45cb6c acpi_disabled +EXPORT_SYMBOL vmlinux 0x1a55d259 scsi_device_set_state +EXPORT_SYMBOL vmlinux 0x1a757412 compat_ip_getsockopt +EXPORT_SYMBOL vmlinux 0x1a75caa3 _read_lock +EXPORT_SYMBOL vmlinux 0x1a8a845e idle_nomwait +EXPORT_SYMBOL vmlinux 0x1ace138d bitmap_allocate_region +EXPORT_SYMBOL vmlinux 0x1ae8d7dc param_set_invbool +EXPORT_SYMBOL vmlinux 0x1b015d25 bitmap_parselist +EXPORT_SYMBOL vmlinux 0x1b246066 llc_sap_open +EXPORT_SYMBOL vmlinux 0x1b3c678a gen_new_estimator +EXPORT_SYMBOL vmlinux 0x1b6314fd in_aton +EXPORT_SYMBOL vmlinux 0x1b89419f add_wait_queue_exclusive +EXPORT_SYMBOL vmlinux 0x1b8e8926 scsi_add_device +EXPORT_SYMBOL vmlinux 0x1b9981cc set_irq_wake +EXPORT_SYMBOL vmlinux 0x1b9e0ff1 scsilun_to_int +EXPORT_SYMBOL vmlinux 0x1baaa54d jbd2_log_wait_commit +EXPORT_SYMBOL vmlinux 0x1bbb8ae8 mmc_align_data_size +EXPORT_SYMBOL vmlinux 0x1be5489f input_get_keycode +EXPORT_SYMBOL vmlinux 0x1c0493c9 elv_next_request +EXPORT_SYMBOL vmlinux 0x1c120b08 dcache_dir_close +EXPORT_SYMBOL vmlinux 0x1c4193c1 uart_register_driver +EXPORT_SYMBOL vmlinux 0x1c450a51 tty_register_driver +EXPORT_SYMBOL vmlinux 0x1c4a113f seq_putc +EXPORT_SYMBOL vmlinux 0x1c7e2cd9 inet_sk_rebuild_header +EXPORT_SYMBOL vmlinux 0x1cb01357 mark_buffer_dirty +EXPORT_SYMBOL vmlinux 0x1cc6719a register_reboot_notifier +EXPORT_SYMBOL vmlinux 0x1ce3810f xfrm4_prepare_output +EXPORT_SYMBOL vmlinux 0x1cefe352 wait_for_completion +EXPORT_SYMBOL vmlinux 0x1cf96dc5 i2c_smbus_read_word_data +EXPORT_SYMBOL vmlinux 0x1d7ce97b pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x1da1eb97 dm_kcopyd_copy +EXPORT_SYMBOL vmlinux 0x1db7706b __copy_user_nocache +EXPORT_SYMBOL vmlinux 0x1dc13db2 skb_clone +EXPORT_SYMBOL vmlinux 0x1dc36131 fb_destroy_modedb +EXPORT_SYMBOL vmlinux 0x1dd571e6 fb_copy_cmap +EXPORT_SYMBOL vmlinux 0x1de00958 vm_map_ram +EXPORT_SYMBOL vmlinux 0x1df5cc80 swiotlb_map_single_attrs +EXPORT_SYMBOL vmlinux 0x1e02df6c clear_bdi_congested +EXPORT_SYMBOL vmlinux 0x1e2b6cd5 wait_on_page_bit +EXPORT_SYMBOL vmlinux 0x1e2cfc66 journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x1e2e427f cpumask_next_and +EXPORT_SYMBOL vmlinux 0x1e2f5175 agp_generic_destroy_page +EXPORT_SYMBOL vmlinux 0x1e315574 __blk_run_queue +EXPORT_SYMBOL vmlinux 0x1e4223c4 simple_statfs +EXPORT_SYMBOL vmlinux 0x1e4dbe40 free_netdev +EXPORT_SYMBOL vmlinux 0x1e6d26a8 strstr +EXPORT_SYMBOL vmlinux 0x1e7e4bcf __neigh_event_send +EXPORT_SYMBOL vmlinux 0x1e889cc4 __skb_warn_lro_forwarding +EXPORT_SYMBOL vmlinux 0x1e8cb617 cdev_init +EXPORT_SYMBOL vmlinux 0x1ea42fa6 unregister_nls +EXPORT_SYMBOL vmlinux 0x1ea4c0fe dma_async_memcpy_buf_to_buf +EXPORT_SYMBOL vmlinux 0x1ea52a7f give_up_console +EXPORT_SYMBOL vmlinux 0x1eb922a3 IO_APIC_get_PCI_irq_vector +EXPORT_SYMBOL vmlinux 0x1ee18a4e tcp_initialize_rcv_mss +EXPORT_SYMBOL vmlinux 0x1efe283f __cap_full_set +EXPORT_SYMBOL vmlinux 0x1f04966f complete_request_key +EXPORT_SYMBOL vmlinux 0x1f0a59ab hci_conn_encrypt +EXPORT_SYMBOL vmlinux 0x1f1e0bbe should_remove_suid +EXPORT_SYMBOL vmlinux 0x1f2067af textsearch_destroy +EXPORT_SYMBOL vmlinux 0x1f27d6d7 _write_unlock +EXPORT_SYMBOL vmlinux 0x1f4ac055 acpi_processor_preregister_performance +EXPORT_SYMBOL vmlinux 0x1f4f4923 inet_accept +EXPORT_SYMBOL vmlinux 0x1f65a6ee genphy_update_link +EXPORT_SYMBOL vmlinux 0x1f720436 seq_read +EXPORT_SYMBOL vmlinux 0x1f7eef1c skb_under_panic +EXPORT_SYMBOL vmlinux 0x1fbe375a ether_setup +EXPORT_SYMBOL vmlinux 0x20000329 simple_strtoul +EXPORT_SYMBOL vmlinux 0x2005e68a acpi_remove_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x20092385 acpi_enter_sleep_state_s4bios +EXPORT_SYMBOL vmlinux 0x201096a9 elevator_exit +EXPORT_SYMBOL vmlinux 0x2037f50a thermal_zone_bind_cooling_device +EXPORT_SYMBOL vmlinux 0x208739f6 acpi_load_table +EXPORT_SYMBOL vmlinux 0x209d4173 i2c_add_adapter +EXPORT_SYMBOL vmlinux 0x20be472c phy_detach +EXPORT_SYMBOL vmlinux 0x20c80e6e scsi_host_lookup +EXPORT_SYMBOL vmlinux 0x20c8fc33 pci_osc_control_set +EXPORT_SYMBOL vmlinux 0x20eadeb6 ip_compute_csum +EXPORT_SYMBOL vmlinux 0x20ebda14 compat_sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0x20f9322a idr_pre_get +EXPORT_SYMBOL vmlinux 0x2126031b skb_append +EXPORT_SYMBOL vmlinux 0x21502407 netdev_class_remove_file +EXPORT_SYMBOL vmlinux 0x215ebd78 bitrev16 +EXPORT_SYMBOL vmlinux 0x21656686 destroy_EII_client +EXPORT_SYMBOL vmlinux 0x219f7d4f pci_scan_slot +EXPORT_SYMBOL vmlinux 0x21b1eebb no_llseek +EXPORT_SYMBOL vmlinux 0x21e0ea22 acpi_get_id +EXPORT_SYMBOL vmlinux 0x21e5679c copy_user_generic +EXPORT_SYMBOL vmlinux 0x21e9d3da journal_start +EXPORT_SYMBOL vmlinux 0x2220ae59 tcf_exts_dump +EXPORT_SYMBOL vmlinux 0x222c00a1 unlock_buffer +EXPORT_SYMBOL vmlinux 0x222e7ce2 sysfs_streq +EXPORT_SYMBOL vmlinux 0x224f2942 ip_setsockopt +EXPORT_SYMBOL vmlinux 0x2253c959 kblockd_flush_work +EXPORT_SYMBOL vmlinux 0x2255c911 cfb_imageblit +EXPORT_SYMBOL vmlinux 0x226dae7d set_disk_ro +EXPORT_SYMBOL vmlinux 0x226e86a9 audit_log +EXPORT_SYMBOL vmlinux 0x22748ebc compat_sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0x2288378f system_state +EXPORT_SYMBOL vmlinux 0x22a73912 __tcp_put_md5sig_pool +EXPORT_SYMBOL vmlinux 0x22b325d5 kd_mksound +EXPORT_SYMBOL vmlinux 0x22b6533b xfrm_sad_getinfo +EXPORT_SYMBOL vmlinux 0x22bb73b5 bdget +EXPORT_SYMBOL vmlinux 0x22e599ed usb_serial_resume +EXPORT_SYMBOL vmlinux 0x22fd7c78 dst_discard +EXPORT_SYMBOL vmlinux 0x23159794 compute_creds +EXPORT_SYMBOL vmlinux 0x231f3a66 __kfifo_put +EXPORT_SYMBOL vmlinux 0x23269a13 strict_strtoul +EXPORT_SYMBOL vmlinux 0x232c6cc5 filemap_fdatawait +EXPORT_SYMBOL vmlinux 0x234509f3 strncat +EXPORT_SYMBOL vmlinux 0x23519eb0 phy_connect +EXPORT_SYMBOL vmlinux 0x236c8c64 memcpy +EXPORT_SYMBOL vmlinux 0x23ba8458 dput +EXPORT_SYMBOL vmlinux 0x23bab004 __dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x23c8f257 slhc_uncompress +EXPORT_SYMBOL vmlinux 0x23cc765c simple_link +EXPORT_SYMBOL vmlinux 0x23f090fa boot_cpu_data +EXPORT_SYMBOL vmlinux 0x23fd3028 vmalloc_node +EXPORT_SYMBOL vmlinux 0x2412c01b cpu_sysdev_class +EXPORT_SYMBOL vmlinux 0x2415d360 unlock_super +EXPORT_SYMBOL vmlinux 0x244001fb dma_async_tx_descriptor_init +EXPORT_SYMBOL vmlinux 0x24428be5 strncpy_from_user +EXPORT_SYMBOL vmlinux 0x2459bbcc console_set_on_cmdline +EXPORT_SYMBOL vmlinux 0x249e08c1 journal_errno +EXPORT_SYMBOL vmlinux 0x24b272c0 pci_find_capability +EXPORT_SYMBOL vmlinux 0x24de1c10 phy_device_create +EXPORT_SYMBOL vmlinux 0x24fdac79 wake_bit_function +EXPORT_SYMBOL vmlinux 0x24fdb1e2 task_tgid_nr_ns +EXPORT_SYMBOL vmlinux 0x252e31b5 jbd2_journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0x2549c07d kernel_getsockopt +EXPORT_SYMBOL vmlinux 0x256887e1 warn_slowpath +EXPORT_SYMBOL vmlinux 0x25820c64 fs_overflowuid +EXPORT_SYMBOL vmlinux 0x258355b4 fb_find_best_mode +EXPORT_SYMBOL vmlinux 0x25b59353 scsi_device_put +EXPORT_SYMBOL vmlinux 0x25dd7785 usb_serial_suspend +EXPORT_SYMBOL vmlinux 0x25ec1b28 strlen +EXPORT_SYMBOL vmlinux 0x25fae8a7 mb_cache_create +EXPORT_SYMBOL vmlinux 0x25fd10d0 dma_pool_alloc +EXPORT_SYMBOL vmlinux 0x25fff88d unregister_quota_format +EXPORT_SYMBOL vmlinux 0x26015e4c pci_request_regions +EXPORT_SYMBOL vmlinux 0x260554af init_special_inode +EXPORT_SYMBOL vmlinux 0x26084734 netpoll_send_udp +EXPORT_SYMBOL vmlinux 0x263782b5 cancel_delayed_work_sync +EXPORT_SYMBOL vmlinux 0x2660b1fd xfrm6_prepare_output +EXPORT_SYMBOL vmlinux 0x2685c3d7 __sg_alloc_table +EXPORT_SYMBOL vmlinux 0x268ffc6f bdev_read_only +EXPORT_SYMBOL vmlinux 0x26b01d42 bio_kmalloc +EXPORT_SYMBOL vmlinux 0x26b8d863 pci_set_dma_seg_boundary +EXPORT_SYMBOL vmlinux 0x26c8b391 atm_dev_deregister +EXPORT_SYMBOL vmlinux 0x26e76fb8 sysctl_udp_wmem_min +EXPORT_SYMBOL vmlinux 0x26f771a6 set_pages_uc +EXPORT_SYMBOL vmlinux 0x270cbe60 get_user_pages +EXPORT_SYMBOL vmlinux 0x270e60bc pcim_pin_device +EXPORT_SYMBOL vmlinux 0x272d394e mtrr_del +EXPORT_SYMBOL vmlinux 0x272e7488 cond_resched_softirq +EXPORT_SYMBOL vmlinux 0x272fa85c blk_rq_map_kern +EXPORT_SYMBOL vmlinux 0x273f066e _write_unlock_irq +EXPORT_SYMBOL vmlinux 0x27443564 security_inode_init_security +EXPORT_SYMBOL vmlinux 0x27593c3d bdi_register_dev +EXPORT_SYMBOL vmlinux 0x277da47c agp_unbind_memory +EXPORT_SYMBOL vmlinux 0x27864d57 memparse +EXPORT_SYMBOL vmlinux 0x27917d65 alloc_pci_dev +EXPORT_SYMBOL vmlinux 0x27a9a7eb ns_to_timespec +EXPORT_SYMBOL vmlinux 0x27bbf221 disable_irq_nosync +EXPORT_SYMBOL vmlinux 0x27c33efe csum_ipv6_magic +EXPORT_SYMBOL vmlinux 0x27c61ece qdisc_put_stab +EXPORT_SYMBOL vmlinux 0x27c969fc generic_file_splice_read +EXPORT_SYMBOL vmlinux 0x27e85494 pci_find_next_bus +EXPORT_SYMBOL vmlinux 0x27eb701a i2c_smbus_xfer +EXPORT_SYMBOL vmlinux 0x27fc0644 nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0x282ccfe4 bt_sock_register +EXPORT_SYMBOL vmlinux 0x283cae2e uart_match_port +EXPORT_SYMBOL vmlinux 0x283d0b9e bdi_destroy +EXPORT_SYMBOL vmlinux 0x284a388b fib_default_rule_add +EXPORT_SYMBOL vmlinux 0x284a62c6 call_usermodehelper_setup +EXPORT_SYMBOL vmlinux 0x285135e6 acpi_evaluate_integer +EXPORT_SYMBOL vmlinux 0x285ac517 strict_strtoll +EXPORT_SYMBOL vmlinux 0x2876a6d3 memcpy_toiovec +EXPORT_SYMBOL vmlinux 0x289b255f inode_double_lock +EXPORT_SYMBOL vmlinux 0x28a2ed02 scsi_build_sense_buffer +EXPORT_SYMBOL vmlinux 0x28bf2c37 pcim_iomap_regions +EXPORT_SYMBOL vmlinux 0x28d2dc6f dmam_free_coherent +EXPORT_SYMBOL vmlinux 0x28dcf25c udplite_hash +EXPORT_SYMBOL vmlinux 0x28e06e8c pci_reenable_device +EXPORT_SYMBOL vmlinux 0x28e78c07 nf_unregister_queue_handler +EXPORT_SYMBOL vmlinux 0x28eeed36 vfs_dq_quota_on_remount +EXPORT_SYMBOL vmlinux 0x29205e8c security_sb_set_mnt_opts +EXPORT_SYMBOL vmlinux 0x293d2176 uart_update_timeout +EXPORT_SYMBOL vmlinux 0x2952963d input_release_device +EXPORT_SYMBOL vmlinux 0x29537c9e alloc_chrdev_region +EXPORT_SYMBOL vmlinux 0x2978360c kernel_sendpage +EXPORT_SYMBOL vmlinux 0x29bd4c46 __cap_init_eff_set +EXPORT_SYMBOL vmlinux 0x29d39a8c vfs_unlink +EXPORT_SYMBOL vmlinux 0x2a1afb23 arp_tbl +EXPORT_SYMBOL vmlinux 0x2a1d8e3c cont_write_begin +EXPORT_SYMBOL vmlinux 0x2a27ea43 eth_type_trans +EXPORT_SYMBOL vmlinux 0x2a303d4d check_signature +EXPORT_SYMBOL vmlinux 0x2a719b06 skb_checksum +EXPORT_SYMBOL vmlinux 0x2a7fd08a blk_start_queueing +EXPORT_SYMBOL vmlinux 0x2ab457c2 blk_integrity_register +EXPORT_SYMBOL vmlinux 0x2abd8fe9 cdrom_get_media_event +EXPORT_SYMBOL vmlinux 0x2adb4c63 kmalloc_caches +EXPORT_SYMBOL vmlinux 0x2aeb2800 mempool_create_node +EXPORT_SYMBOL vmlinux 0x2aef8523 acpi_bus_unregister_driver +EXPORT_SYMBOL vmlinux 0x2b0ba2b0 scsi_sense_desc_find +EXPORT_SYMBOL vmlinux 0x2b30cba6 submit_bh +EXPORT_SYMBOL vmlinux 0x2b4a5bd4 proc_dointvec_minmax +EXPORT_SYMBOL vmlinux 0x2b6aac8c tcp_sockets_allocated +EXPORT_SYMBOL vmlinux 0x2b8bedcd con_set_default_unimap +EXPORT_SYMBOL vmlinux 0x2ba707a8 sysctl_tcp_low_latency +EXPORT_SYMBOL vmlinux 0x2bb55d6e acpi_remove_notify_handler +EXPORT_SYMBOL vmlinux 0x2bb62d3a tty_register_ldisc +EXPORT_SYMBOL vmlinux 0x2bc1bfb5 udp_prot +EXPORT_SYMBOL vmlinux 0x2be09893 _atomic_dec_and_lock +EXPORT_SYMBOL vmlinux 0x2be0d4aa sock_no_sendmsg +EXPORT_SYMBOL vmlinux 0x2bfeb410 acpi_get_handle +EXPORT_SYMBOL vmlinux 0x2c1c3775 i2c_transfer +EXPORT_SYMBOL vmlinux 0x2c257777 sock_create_kern +EXPORT_SYMBOL vmlinux 0x2c5749e6 acpi_clear_gpe +EXPORT_SYMBOL vmlinux 0x2c6731f7 dm_kcopyd_client_create +EXPORT_SYMBOL vmlinux 0x2c70c0c5 sk_stream_write_space +EXPORT_SYMBOL vmlinux 0x2c8e708a __scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x2ca4b79d console_stop +EXPORT_SYMBOL vmlinux 0x2cadb4dd __elv_add_request +EXPORT_SYMBOL vmlinux 0x2cc2d52d vcc_hash +EXPORT_SYMBOL vmlinux 0x2cd9e459 param_set_short +EXPORT_SYMBOL vmlinux 0x2ceab16d may_umount_tree +EXPORT_SYMBOL vmlinux 0x2cf190e3 request_irq +EXPORT_SYMBOL vmlinux 0x2d43aaad open_exec +EXPORT_SYMBOL vmlinux 0x2d49e48b mb_cache_entry_insert +EXPORT_SYMBOL vmlinux 0x2d5528c9 sg_copy_to_buffer +EXPORT_SYMBOL vmlinux 0x2d80bfef nf_register_queue_handler +EXPORT_SYMBOL vmlinux 0x2d891384 swiotlb_unmap_sg_attrs +EXPORT_SYMBOL vmlinux 0x2d89342a scsi_show_sense_hdr +EXPORT_SYMBOL vmlinux 0x2db3ee32 skb_queue_tail +EXPORT_SYMBOL vmlinux 0x2dbafbe3 pcibios_align_resource +EXPORT_SYMBOL vmlinux 0x2dd16564 arch_register_cpu +EXPORT_SYMBOL vmlinux 0x2de9f66f param_get_long +EXPORT_SYMBOL vmlinux 0x2dedc4c2 acpi_format_exception +EXPORT_SYMBOL vmlinux 0x2def7f76 rtc_cmos_write +EXPORT_SYMBOL vmlinux 0x2e18c2bd ppp_register_channel +EXPORT_SYMBOL vmlinux 0x2e2ce9e0 sysctl_tcp_syncookies +EXPORT_SYMBOL vmlinux 0x2e4a39f8 sysctl_udp_mem +EXPORT_SYMBOL vmlinux 0x2e59bf67 pnp_activate_dev +EXPORT_SYMBOL vmlinux 0x2e72c2ec xfrm_unregister_km +EXPORT_SYMBOL vmlinux 0x2e849abe __mpage_writepage +EXPORT_SYMBOL vmlinux 0x2e90874e neigh_parms_alloc +EXPORT_SYMBOL vmlinux 0x2e97a729 idr_remove +EXPORT_SYMBOL vmlinux 0x2eb083b5 sock_no_setsockopt +EXPORT_SYMBOL vmlinux 0x2eb9a0e8 _read_lock_irq +EXPORT_SYMBOL vmlinux 0x2ec86031 input_unregister_handle +EXPORT_SYMBOL vmlinux 0x2ee0549b register_binfmt +EXPORT_SYMBOL vmlinux 0x2ef3d52f thermal_cooling_device_register +EXPORT_SYMBOL vmlinux 0x2fa5a500 memcmp +EXPORT_SYMBOL vmlinux 0x2fb0b354 filemap_fdatawrite +EXPORT_SYMBOL vmlinux 0x2fb7fbb5 dev_getfirstbyhwtype +EXPORT_SYMBOL vmlinux 0x2fbb9e5d tcf_destroy_chain +EXPORT_SYMBOL vmlinux 0x2ff063b5 acpi_get_name +EXPORT_SYMBOL vmlinux 0x2ff4de68 page_put_link +EXPORT_SYMBOL vmlinux 0x2ff7594d xfrm_policy_delete +EXPORT_SYMBOL vmlinux 0x2ff7efaa tcf_hash_new_index +EXPORT_SYMBOL vmlinux 0x30123eb5 icmpv6_statistics +EXPORT_SYMBOL vmlinux 0x3018de55 dm_unregister_target +EXPORT_SYMBOL vmlinux 0x301cdbff user_revoke +EXPORT_SYMBOL vmlinux 0x30226ddf agp_device_command +EXPORT_SYMBOL vmlinux 0x303ce535 inet_addr_type +EXPORT_SYMBOL vmlinux 0x305f5901 mpage_writepages +EXPORT_SYMBOL vmlinux 0x306a8ebe agp_find_bridge +EXPORT_SYMBOL vmlinux 0x306bd3c3 vfs_fstat +EXPORT_SYMBOL vmlinux 0x306fd0bf mmc_wait_for_req +EXPORT_SYMBOL vmlinux 0x30a114be end_request +EXPORT_SYMBOL vmlinux 0x30b22bab swiotlb_sync_single_for_cpu +EXPORT_SYMBOL vmlinux 0x30c7587a sync_inode +EXPORT_SYMBOL vmlinux 0x30dc561a __vlan_hwaccel_rx +EXPORT_SYMBOL vmlinux 0x30de8b2e copy_io_context +EXPORT_SYMBOL vmlinux 0x30df26fd dm_table_get_size +EXPORT_SYMBOL vmlinux 0x30e74134 tty_termios_copy_hw +EXPORT_SYMBOL vmlinux 0x30f7b5e1 register_netdev +EXPORT_SYMBOL vmlinux 0x31153bf8 tcp_check_req +EXPORT_SYMBOL vmlinux 0x312baafb fb_firmware_edid +EXPORT_SYMBOL vmlinux 0x3145216f pci_dev_present +EXPORT_SYMBOL vmlinux 0x3146774a __mmc_claim_host +EXPORT_SYMBOL vmlinux 0x3147857d default_red +EXPORT_SYMBOL vmlinux 0x315363b6 i2c_register_driver +EXPORT_SYMBOL vmlinux 0x316a3ba5 blk_queue_update_dma_pad +EXPORT_SYMBOL vmlinux 0x3171e93f mmc_alloc_host +EXPORT_SYMBOL vmlinux 0x31735008 ip_nat_decode_session +EXPORT_SYMBOL vmlinux 0x31a30414 xfrm_state_lookup_byaddr +EXPORT_SYMBOL vmlinux 0x31b31f5c csum_partial_copy_nocheck +EXPORT_SYMBOL vmlinux 0x31c69df5 blk_rq_map_integrity_sg +EXPORT_SYMBOL vmlinux 0x31ebadcd in_group_p +EXPORT_SYMBOL vmlinux 0x31fb8c02 bt_sock_ioctl +EXPORT_SYMBOL vmlinux 0x320c2c0d pskb_copy +EXPORT_SYMBOL vmlinux 0x32382dba qdisc_destroy +EXPORT_SYMBOL vmlinux 0x323cc80d vm_insert_page +EXPORT_SYMBOL vmlinux 0x3251f905 xfrm_find_acq_byseq +EXPORT_SYMBOL vmlinux 0x326ba0c4 km_report +EXPORT_SYMBOL vmlinux 0x32b3916f do_splice_to +EXPORT_SYMBOL vmlinux 0x32bbac02 pci_choose_state +EXPORT_SYMBOL vmlinux 0x32d01fec acpi_attach_data +EXPORT_SYMBOL vmlinux 0x32f87920 inet_frag_kill +EXPORT_SYMBOL vmlinux 0x3301823a bio_map_kern +EXPORT_SYMBOL vmlinux 0x330d556f gnet_stats_copy_app +EXPORT_SYMBOL vmlinux 0x331b0bf5 bio_endio +EXPORT_SYMBOL vmlinux 0x33217539 call_usermodehelper_setcleanup +EXPORT_SYMBOL vmlinux 0x3347827b get_sb_nodev +EXPORT_SYMBOL vmlinux 0x335b7dc0 fb_show_logo +EXPORT_SYMBOL vmlinux 0x3360a963 param_set_ulong +EXPORT_SYMBOL vmlinux 0x3360ba94 inet_register_protosw +EXPORT_SYMBOL vmlinux 0x33a317a3 jbd2_journal_dirty_metadata +EXPORT_SYMBOL vmlinux 0x33b84f74 copy_page +EXPORT_SYMBOL vmlinux 0x33bab407 mpage_bio_submit +EXPORT_SYMBOL vmlinux 0x33cda660 posix_acl_from_mode +EXPORT_SYMBOL vmlinux 0x33d92f9a prepare_to_wait +EXPORT_SYMBOL vmlinux 0x33f5a8b4 blk_integrity_unregister +EXPORT_SYMBOL vmlinux 0x3495e340 pci_bus_read_config_byte +EXPORT_SYMBOL vmlinux 0x349cba85 strchr +EXPORT_SYMBOL vmlinux 0x34def7ff tty_port_init +EXPORT_SYMBOL vmlinux 0x34e8656d do_sync_write +EXPORT_SYMBOL vmlinux 0x34fce488 pci_remove_bus +EXPORT_SYMBOL vmlinux 0x35072add pci_bus_write_config_byte +EXPORT_SYMBOL vmlinux 0x350cc8c2 scm_fp_dup +EXPORT_SYMBOL vmlinux 0x352ab046 genl_sock +EXPORT_SYMBOL vmlinux 0x35352718 blk_queue_merge_bvec +EXPORT_SYMBOL vmlinux 0x353ca524 qdisc_reset +EXPORT_SYMBOL vmlinux 0x355737ac llc_mac_hdr_init +EXPORT_SYMBOL vmlinux 0x355f029a tcf_register_action +EXPORT_SYMBOL vmlinux 0x356ed56a clear_page_dirty_for_io +EXPORT_SYMBOL vmlinux 0x3572a48b input_unregister_handler +EXPORT_SYMBOL vmlinux 0x3580d864 register_atm_ioctl +EXPORT_SYMBOL vmlinux 0x35a07e32 vfs_stat +EXPORT_SYMBOL vmlinux 0x35b0650f vsnprintf +EXPORT_SYMBOL vmlinux 0x35b55e54 ps2_command +EXPORT_SYMBOL vmlinux 0x35c2ba9e refrigerator +EXPORT_SYMBOL vmlinux 0x35ff32bf inet_dgram_ops +EXPORT_SYMBOL vmlinux 0x360b1afe probe_irq_mask +EXPORT_SYMBOL vmlinux 0x36139a51 memcpy_fromiovec +EXPORT_SYMBOL vmlinux 0x361dec09 __page_symlink +EXPORT_SYMBOL vmlinux 0x36212135 simple_readpage +EXPORT_SYMBOL vmlinux 0x362412d5 agp_generic_alloc_page +EXPORT_SYMBOL vmlinux 0x36274d01 blkdev_put +EXPORT_SYMBOL vmlinux 0x363ad247 cap_set_effective +EXPORT_SYMBOL vmlinux 0x363f4209 sg_miter_start +EXPORT_SYMBOL vmlinux 0x3656bf5a lock_kernel +EXPORT_SYMBOL vmlinux 0x3663cc74 kmem_cache_name +EXPORT_SYMBOL vmlinux 0x36881d29 inet_dgram_connect +EXPORT_SYMBOL vmlinux 0x36bc4e3c unregister_netdev +EXPORT_SYMBOL vmlinux 0x3701a196 csum_partial_copy_to_user +EXPORT_SYMBOL vmlinux 0x371cd187 dm_dirty_log_destroy +EXPORT_SYMBOL vmlinux 0x3744cf36 vmalloc_to_pfn +EXPORT_SYMBOL vmlinux 0x3747ad09 d_invalidate +EXPORT_SYMBOL vmlinux 0x375465a7 radix_tree_gang_lookup_tag_slot +EXPORT_SYMBOL vmlinux 0x375ccbca check_disk_size_change +EXPORT_SYMBOL vmlinux 0x37bc8966 generic_ro_fops +EXPORT_SYMBOL vmlinux 0x37befc70 jiffies_to_msecs +EXPORT_SYMBOL vmlinux 0x37c34486 km_query +EXPORT_SYMBOL vmlinux 0x37f81fe7 scsi_register_interface +EXPORT_SYMBOL vmlinux 0x3800d56b pci_bus_read_config_dword +EXPORT_SYMBOL vmlinux 0x3829c5a0 sysctl_data +EXPORT_SYMBOL vmlinux 0x38748d2e skb_queue_purge +EXPORT_SYMBOL vmlinux 0x388f9128 xfrm_state_walk_done +EXPORT_SYMBOL vmlinux 0x38b92846 llc_remove_pack +EXPORT_SYMBOL vmlinux 0x38f33bed dump_fpu +EXPORT_SYMBOL vmlinux 0x38facb18 scsi_unregister +EXPORT_SYMBOL vmlinux 0x390e0b3b mdiobus_scan +EXPORT_SYMBOL vmlinux 0x391109b6 cdev_del +EXPORT_SYMBOL vmlinux 0x3912cd77 find_get_pages_contig +EXPORT_SYMBOL vmlinux 0x392963c3 dquot_release +EXPORT_SYMBOL vmlinux 0x392b725a pci_clear_mwi +EXPORT_SYMBOL vmlinux 0x3937b22a atm_alloc_charge +EXPORT_SYMBOL vmlinux 0x395f5e09 bio_add_pc_page +EXPORT_SYMBOL vmlinux 0x396960e0 scsi_target_resume +EXPORT_SYMBOL vmlinux 0x396cf390 register_sysctl_table +EXPORT_SYMBOL vmlinux 0x3980aac1 unregister_reboot_notifier +EXPORT_SYMBOL vmlinux 0x39c16f1e release_firmware +EXPORT_SYMBOL vmlinux 0x39cd891a __down_write_trylock +EXPORT_SYMBOL vmlinux 0x3a0ab085 dentry_unhash +EXPORT_SYMBOL vmlinux 0x3a0d9f8b generic_file_aio_write_nolock +EXPORT_SYMBOL vmlinux 0x3a199193 skb_copy_expand +EXPORT_SYMBOL vmlinux 0x3a2003a3 iommu_nr_pages +EXPORT_SYMBOL vmlinux 0x3a2204c6 security_netlink_recv +EXPORT_SYMBOL vmlinux 0x3a3f5a06 xfrm_alloc_spi +EXPORT_SYMBOL vmlinux 0x3a751ecb bio_pair_release +EXPORT_SYMBOL vmlinux 0x3a88e9a7 skb_checksum_help +EXPORT_SYMBOL vmlinux 0x3a911e65 lock_may_write +EXPORT_SYMBOL vmlinux 0x3a97aa27 tcp_v4_send_check +EXPORT_SYMBOL vmlinux 0x3a9b6fb9 blk_unregister_region +EXPORT_SYMBOL vmlinux 0x3aa1dbcf _spin_unlock_bh +EXPORT_SYMBOL vmlinux 0x3ab0161b dma_async_client_chan_request +EXPORT_SYMBOL vmlinux 0x3acd5712 bio_integrity_enabled +EXPORT_SYMBOL vmlinux 0x3adf2c2a phy_disable_interrupts +EXPORT_SYMBOL vmlinux 0x3af292c0 kill_litter_super +EXPORT_SYMBOL vmlinux 0x3b2a3782 scsi_setup_blk_pc_cmnd +EXPORT_SYMBOL vmlinux 0x3b3016d3 cpufreq_unregister_notifier +EXPORT_SYMBOL vmlinux 0x3b40d5a1 tcp_v4_md5_lookup +EXPORT_SYMBOL vmlinux 0x3b592412 neigh_parms_release +EXPORT_SYMBOL vmlinux 0x3b67cbbf __init_rwsem +EXPORT_SYMBOL vmlinux 0x3bab9b29 filp_open +EXPORT_SYMBOL vmlinux 0x3bc50e0d scsi_finish_command +EXPORT_SYMBOL vmlinux 0x3bcba798 gnet_stats_copy_queue +EXPORT_SYMBOL vmlinux 0x3bd1b1f6 msecs_to_jiffies +EXPORT_SYMBOL vmlinux 0x3be4ce31 blk_init_queue_node +EXPORT_SYMBOL vmlinux 0x3c027dcf jbd2_journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0x3c2162c0 cdev_alloc +EXPORT_SYMBOL vmlinux 0x3c2c5af5 sprintf +EXPORT_SYMBOL vmlinux 0x3c5829f6 scsi_block_requests +EXPORT_SYMBOL vmlinux 0x3c7227bf complete_all +EXPORT_SYMBOL vmlinux 0x3c7d4963 put_tty_driver +EXPORT_SYMBOL vmlinux 0x3c94f3b7 tty_unregister_driver +EXPORT_SYMBOL vmlinux 0x3c9d1211 string_get_size +EXPORT_SYMBOL vmlinux 0x3cb8a495 param_get_string +EXPORT_SYMBOL vmlinux 0x3cc0a3bb xfrm_spd_getinfo +EXPORT_SYMBOL vmlinux 0x3cc5a3e3 tcp_simple_retransmit +EXPORT_SYMBOL vmlinux 0x3cd3b8c7 __dst_free +EXPORT_SYMBOL vmlinux 0x3ce4ca6f disable_irq +EXPORT_SYMBOL vmlinux 0x3cf29580 serio_unregister_driver +EXPORT_SYMBOL vmlinux 0x3d22f0a7 dm_table_put +EXPORT_SYMBOL vmlinux 0x3d2cd33a tty_chars_in_buffer +EXPORT_SYMBOL vmlinux 0x3d61c0ed elv_rb_find +EXPORT_SYMBOL vmlinux 0x3d8af420 journal_create +EXPORT_SYMBOL vmlinux 0x3d9a9ba2 journal_force_commit +EXPORT_SYMBOL vmlinux 0x3d9ee9f0 clear_page +EXPORT_SYMBOL vmlinux 0x3da171f9 pci_mem_start +EXPORT_SYMBOL vmlinux 0x3da5eb6d kfifo_alloc +EXPORT_SYMBOL vmlinux 0x3db2e258 radix_tree_gang_lookup +EXPORT_SYMBOL vmlinux 0x3db46789 sock_init_data +EXPORT_SYMBOL vmlinux 0x3e1097ee inode_get_bytes +EXPORT_SYMBOL vmlinux 0x3e1f073d wait_for_completion_timeout +EXPORT_SYMBOL vmlinux 0x3e1f37d5 bio_integrity_clone +EXPORT_SYMBOL vmlinux 0x3e219de6 try_wait_for_completion +EXPORT_SYMBOL vmlinux 0x3e2ae3a8 acpi_release_global_lock +EXPORT_SYMBOL vmlinux 0x3e383385 nf_hooks +EXPORT_SYMBOL vmlinux 0x3e45e9ff register_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x3e8ff310 ____pagevec_lru_add +EXPORT_SYMBOL vmlinux 0x3ea27cf5 jbd2_journal_destroy +EXPORT_SYMBOL vmlinux 0x3eaa72d0 blk_queue_init_tags +EXPORT_SYMBOL vmlinux 0x3eace113 pagecache_write_begin +EXPORT_SYMBOL vmlinux 0x3ebed522 devm_ioremap_nocache +EXPORT_SYMBOL vmlinux 0x3ece8ae4 pci_find_device +EXPORT_SYMBOL vmlinux 0x3ed63055 zlib_inflateReset +EXPORT_SYMBOL vmlinux 0x3ee1fd0e seq_open_private +EXPORT_SYMBOL vmlinux 0x3efcadda register_nls +EXPORT_SYMBOL vmlinux 0x3efed9c1 pnp_request_card_device +EXPORT_SYMBOL vmlinux 0x3f0546a8 ioread32_rep +EXPORT_SYMBOL vmlinux 0x3f09bad1 sk_stream_error +EXPORT_SYMBOL vmlinux 0x3f1899f1 up +EXPORT_SYMBOL vmlinux 0x3f3455d8 put_page +EXPORT_SYMBOL vmlinux 0x3f42a41f __sk_mem_reclaim +EXPORT_SYMBOL vmlinux 0x3f4547a7 put_unused_fd +EXPORT_SYMBOL vmlinux 0x3fa913da strspn +EXPORT_SYMBOL vmlinux 0x3fab4896 netlink_unicast +EXPORT_SYMBOL vmlinux 0x3fec048f sg_next +EXPORT_SYMBOL vmlinux 0x3ff62317 local_bh_disable +EXPORT_SYMBOL vmlinux 0x40228261 pci_scan_single_device +EXPORT_SYMBOL vmlinux 0x4056da6b tcp_recvmsg +EXPORT_SYMBOL vmlinux 0x405c1144 get_seconds +EXPORT_SYMBOL vmlinux 0x408190eb scsi_target_quiesce +EXPORT_SYMBOL vmlinux 0x409873e3 tty_termios_baud_rate +EXPORT_SYMBOL vmlinux 0x40c89d46 acpi_get_table_by_index +EXPORT_SYMBOL vmlinux 0x40d38b07 block_write_end +EXPORT_SYMBOL vmlinux 0x40e860ca agp_generic_alloc_user +EXPORT_SYMBOL vmlinux 0x40eafccb bitmap_unplug +EXPORT_SYMBOL vmlinux 0x4108e69a fb_match_mode +EXPORT_SYMBOL vmlinux 0x413167a1 scsi_allocate_command +EXPORT_SYMBOL vmlinux 0x413a5f4c tcf_action_dump_1 +EXPORT_SYMBOL vmlinux 0x413dd170 __inode_dir_notify +EXPORT_SYMBOL vmlinux 0x413ee1aa scsi_release_buffers +EXPORT_SYMBOL vmlinux 0x41471579 ppp_input +EXPORT_SYMBOL vmlinux 0x41482d8b strndup_user +EXPORT_SYMBOL vmlinux 0x416983d9 netdev_fix_features +EXPORT_SYMBOL vmlinux 0x41711c46 seq_puts +EXPORT_SYMBOL vmlinux 0x4180c189 __f_setown +EXPORT_SYMBOL vmlinux 0x4188d439 neigh_rand_reach_time +EXPORT_SYMBOL vmlinux 0x4194481b pneigh_enqueue +EXPORT_SYMBOL vmlinux 0x41a7c227 schedule_delayed_work +EXPORT_SYMBOL vmlinux 0x41a9c68d _spin_trylock_bh +EXPORT_SYMBOL vmlinux 0x41e0356b pskb_expand_head +EXPORT_SYMBOL vmlinux 0x41e81663 agp_free_memory +EXPORT_SYMBOL vmlinux 0x41f38cc7 scsi_is_target_device +EXPORT_SYMBOL vmlinux 0x41f706ef udp_proc_register +EXPORT_SYMBOL vmlinux 0x4211c3c1 zlib_inflateInit2 +EXPORT_SYMBOL vmlinux 0x421feb8f qdisc_watchdog_cancel +EXPORT_SYMBOL vmlinux 0x42224298 sscanf +EXPORT_SYMBOL vmlinux 0x422c05d0 acpi_get_data +EXPORT_SYMBOL vmlinux 0x42612fa2 journal_abort +EXPORT_SYMBOL vmlinux 0x4271ac1a generic_cont_expand_simple +EXPORT_SYMBOL vmlinux 0x42981536 bh_submit_read +EXPORT_SYMBOL vmlinux 0x429eb7f5 arp_create +EXPORT_SYMBOL vmlinux 0x42a4bdf2 in_egroup_p +EXPORT_SYMBOL vmlinux 0x42c8de35 ioremap_nocache +EXPORT_SYMBOL vmlinux 0x4302d0eb free_pages +EXPORT_SYMBOL vmlinux 0x430a71cc scsi_free_host_dev +EXPORT_SYMBOL vmlinux 0x430bb7a8 dev_load +EXPORT_SYMBOL vmlinux 0x4327f0d5 memset_io +EXPORT_SYMBOL vmlinux 0x43385ad9 acpi_pci_unregister_driver +EXPORT_SYMBOL vmlinux 0x4344f8b7 dquot_transfer +EXPORT_SYMBOL vmlinux 0x43455865 take_over_console +EXPORT_SYMBOL vmlinux 0x434fa55c release_console_sem +EXPORT_SYMBOL vmlinux 0x435b566d _spin_unlock +EXPORT_SYMBOL vmlinux 0x43618370 proto_register +EXPORT_SYMBOL vmlinux 0x436c2179 iowrite32 +EXPORT_SYMBOL vmlinux 0x43bf17d8 neigh_update +EXPORT_SYMBOL vmlinux 0x43e42c0e set_pages_wb +EXPORT_SYMBOL vmlinux 0x43ec913a put_cmsg +EXPORT_SYMBOL vmlinux 0x43f7b266 xfrm_nl +EXPORT_SYMBOL vmlinux 0x44161c19 unregister_shrinker +EXPORT_SYMBOL vmlinux 0x4430d571 blk_get_backing_dev_info +EXPORT_SYMBOL vmlinux 0x4437b44d tcp_splice_read +EXPORT_SYMBOL vmlinux 0x44451a2e kthread_stop +EXPORT_SYMBOL vmlinux 0x444779c4 nla_find +EXPORT_SYMBOL vmlinux 0x4481556f scsi_add_host +EXPORT_SYMBOL vmlinux 0x448403ed bio_integrity_alloc_bioset +EXPORT_SYMBOL vmlinux 0x44aaf30f tsc_khz +EXPORT_SYMBOL vmlinux 0x44b911c3 rb_replace_node +EXPORT_SYMBOL vmlinux 0x44d560e3 init_level4_pgt +EXPORT_SYMBOL vmlinux 0x44df8ba6 proc_create_data +EXPORT_SYMBOL vmlinux 0x44e9a829 match_token +EXPORT_SYMBOL vmlinux 0x451c96f9 scsi_free_command +EXPORT_SYMBOL vmlinux 0x4550ba8a register_cpu_notifier +EXPORT_SYMBOL vmlinux 0x455e4098 elv_abort_queue +EXPORT_SYMBOL vmlinux 0x455fd57d acpi_set_register +EXPORT_SYMBOL vmlinux 0x45704798 print_hex_dump_bytes +EXPORT_SYMBOL vmlinux 0x4572534c key_payload_reserve +EXPORT_SYMBOL vmlinux 0x4593a18d pci_dev_get +EXPORT_SYMBOL vmlinux 0x45bb123e try_to_del_timer_sync +EXPORT_SYMBOL vmlinux 0x45d11c43 down_interruptible +EXPORT_SYMBOL vmlinux 0x4601877c d_path +EXPORT_SYMBOL vmlinux 0x4605ebee generic_read_dir +EXPORT_SYMBOL vmlinux 0x4607dad1 scsi_set_medium_removal +EXPORT_SYMBOL vmlinux 0x46456a12 blk_cleanup_queue +EXPORT_SYMBOL vmlinux 0x46527008 journal_lock_updates +EXPORT_SYMBOL vmlinux 0x466c14a7 __delay +EXPORT_SYMBOL vmlinux 0x4679020d pnp_register_card_driver +EXPORT_SYMBOL vmlinux 0x468c3de6 sock_kfree_s +EXPORT_SYMBOL vmlinux 0x469e5c91 phy_start_interrupts +EXPORT_SYMBOL vmlinux 0x46c5bac8 bdput +EXPORT_SYMBOL vmlinux 0x46d5a947 iov_iter_copy_from_user_atomic +EXPORT_SYMBOL vmlinux 0x46e04778 register_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0x46f7e6ce __bforget +EXPORT_SYMBOL vmlinux 0x46faaa1c xfrm_state_delete_tunnel +EXPORT_SYMBOL vmlinux 0x470ce841 pci_bus_find_capability +EXPORT_SYMBOL vmlinux 0x475100c2 inet_get_local_port_range +EXPORT_SYMBOL vmlinux 0x475f010b acpi_purge_cached_objects +EXPORT_SYMBOL vmlinux 0x475f05af acpi_set_firmware_waking_vector +EXPORT_SYMBOL vmlinux 0x478d10b2 ht_destroy_irq +EXPORT_SYMBOL vmlinux 0x4792b78d __dev_get_by_index +EXPORT_SYMBOL vmlinux 0x47939e0d __tasklet_hi_schedule +EXPORT_SYMBOL vmlinux 0x479c3c86 find_next_zero_bit +EXPORT_SYMBOL vmlinux 0x47e1699f neigh_lookup +EXPORT_SYMBOL vmlinux 0x47ffe546 register_chrdev +EXPORT_SYMBOL vmlinux 0x4813bc30 ip6_frag_match +EXPORT_SYMBOL vmlinux 0x481cb9ab acpi_enter_sleep_state_prep +EXPORT_SYMBOL vmlinux 0x48395714 path_get +EXPORT_SYMBOL vmlinux 0x4859b8bb rtc_year_days +EXPORT_SYMBOL vmlinux 0x485e5818 vfs_dq_transfer +EXPORT_SYMBOL vmlinux 0x486b6407 hweight64 +EXPORT_SYMBOL vmlinux 0x486b7b2e simple_sync_file +EXPORT_SYMBOL vmlinux 0x4871f34d hci_free_dev +EXPORT_SYMBOL vmlinux 0x4888b72a pci_get_subsys +EXPORT_SYMBOL vmlinux 0x48a08d04 mark_buffer_dirty_inode +EXPORT_SYMBOL vmlinux 0x48adab09 invalidate_mapping_pages +EXPORT_SYMBOL vmlinux 0x48bdccd8 agp_collect_device_status +EXPORT_SYMBOL vmlinux 0x48bf4309 bh_uptodate_or_lock +EXPORT_SYMBOL vmlinux 0x493e25e1 udp_hash +EXPORT_SYMBOL vmlinux 0x49430cd3 skb_seq_read +EXPORT_SYMBOL vmlinux 0x49603fb8 security_sb_copy_data +EXPORT_SYMBOL vmlinux 0x496cb7f6 netdev_state_change +EXPORT_SYMBOL vmlinux 0x499eb01d inet_csk_delete_keepalive_timer +EXPORT_SYMBOL vmlinux 0x49da9a9a _read_unlock_bh +EXPORT_SYMBOL vmlinux 0x49ef3927 __invalidate_device +EXPORT_SYMBOL vmlinux 0x4a29e253 i2c_master_recv +EXPORT_SYMBOL vmlinux 0x4a30fe8a remove_inode_hash +EXPORT_SYMBOL vmlinux 0x4a358252 __bitmap_subset +EXPORT_SYMBOL vmlinux 0x4a555407 key_alloc +EXPORT_SYMBOL vmlinux 0x4a5aa29f scsi_register_driver +EXPORT_SYMBOL vmlinux 0x4a6d6a67 cdrom_mode_sense +EXPORT_SYMBOL vmlinux 0x4a93fe5c backlight_device_register +EXPORT_SYMBOL vmlinux 0x4aaf9b7f dm_table_get_mode +EXPORT_SYMBOL vmlinux 0x4acd93d3 release_resource +EXPORT_SYMBOL vmlinux 0x4ae37fb7 thermal_zone_device_unregister +EXPORT_SYMBOL vmlinux 0x4aec9d60 rfkill_force_state +EXPORT_SYMBOL vmlinux 0x4afe9a77 scsi_partsize +EXPORT_SYMBOL vmlinux 0x4b07e779 _spin_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x4b085dbf agp3_generic_configure +EXPORT_SYMBOL vmlinux 0x4b2f14b4 jiffies_to_timespec +EXPORT_SYMBOL vmlinux 0x4b3a68c5 set_anon_super +EXPORT_SYMBOL vmlinux 0x4b52f497 llc_set_station_handler +EXPORT_SYMBOL vmlinux 0x4b77c0d1 tcf_hash_insert +EXPORT_SYMBOL vmlinux 0x4b8a9c9b tcp_v4_md5_do_add +EXPORT_SYMBOL vmlinux 0x4b91a078 scsi_execute_req +EXPORT_SYMBOL vmlinux 0x4ba20638 vmalloc_to_page +EXPORT_SYMBOL vmlinux 0x4ba5baa0 load_gs_index +EXPORT_SYMBOL vmlinux 0x4bb068c4 pneigh_lookup +EXPORT_SYMBOL vmlinux 0x4bb1b7da netpoll_setup +EXPORT_SYMBOL vmlinux 0x4bbc3e5f pm_flags +EXPORT_SYMBOL vmlinux 0x4bbcb530 thermal_zone_device_register +EXPORT_SYMBOL vmlinux 0x4bdf028e idr_find +EXPORT_SYMBOL vmlinux 0x4c07b61a mb_cache_entry_find_next +EXPORT_SYMBOL vmlinux 0x4c1182cb bitmap_scnprintf +EXPORT_SYMBOL vmlinux 0x4c32aa00 cancel_dirty_page +EXPORT_SYMBOL vmlinux 0x4c4135a6 xfrm_unregister_mode +EXPORT_SYMBOL vmlinux 0x4c4c956e nla_memcmp +EXPORT_SYMBOL vmlinux 0x4c7b057f __xfrm_decode_session +EXPORT_SYMBOL vmlinux 0x4ca32965 sync_blockdev +EXPORT_SYMBOL vmlinux 0x4cbbd171 __bitmap_weight +EXPORT_SYMBOL vmlinux 0x4cc28465 dm_dirty_log_type_register +EXPORT_SYMBOL vmlinux 0x4cc2d305 proc_dointvec_userhz_jiffies +EXPORT_SYMBOL vmlinux 0x4d0cf8ef have_submounts +EXPORT_SYMBOL vmlinux 0x4d16055e scsi_register +EXPORT_SYMBOL vmlinux 0x4d2c3bdd sock_no_listen +EXPORT_SYMBOL vmlinux 0x4d32e32c journal_check_used_features +EXPORT_SYMBOL vmlinux 0x4d32e928 scsi_block_when_processing_errors +EXPORT_SYMBOL vmlinux 0x4d4dc484 nf_ct_attach +EXPORT_SYMBOL vmlinux 0x4d51dc47 register_md_personality +EXPORT_SYMBOL vmlinux 0x4d875b0e tcp_poll +EXPORT_SYMBOL vmlinux 0x4d8859fc dquot_commit +EXPORT_SYMBOL vmlinux 0x4db1e1d4 posix_acl_equiv_mode +EXPORT_SYMBOL vmlinux 0x4dc88d79 ps2_handle_response +EXPORT_SYMBOL vmlinux 0x4dda726b match_strlcpy +EXPORT_SYMBOL vmlinux 0x4ddc4b9f utf8_mbtowc +EXPORT_SYMBOL vmlinux 0x4df119fa __bitmap_parse +EXPORT_SYMBOL vmlinux 0x4df47e9f xfrm_state_flush +EXPORT_SYMBOL vmlinux 0x4e0fb2da neigh_create +EXPORT_SYMBOL vmlinux 0x4e100f60 _spin_unlock_irq +EXPORT_SYMBOL vmlinux 0x4e2d15e3 d_instantiate_unique +EXPORT_SYMBOL vmlinux 0x4e304a2b sk_stream_wait_close +EXPORT_SYMBOL vmlinux 0x4e3567f7 match_int +EXPORT_SYMBOL vmlinux 0x4e35c4bd jbd2_journal_update_format +EXPORT_SYMBOL vmlinux 0x4e4d0c4a dev_mc_delete +EXPORT_SYMBOL vmlinux 0x4e6e8ea7 fg_console +EXPORT_SYMBOL vmlinux 0x4e94ea23 jbd2_journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x4e97fc4e bio_phys_segments +EXPORT_SYMBOL vmlinux 0x4e9f82f6 alloc_netdev_mq +EXPORT_SYMBOL vmlinux 0x4ed244a1 netpoll_print_options +EXPORT_SYMBOL vmlinux 0x4edd72f7 block_all_signals +EXPORT_SYMBOL vmlinux 0x4f476e96 init_cdrom_command +EXPORT_SYMBOL vmlinux 0x4f5438c1 idle_halt +EXPORT_SYMBOL vmlinux 0x4f584a17 mpage_readpage +EXPORT_SYMBOL vmlinux 0x4f720a26 bio_copy_kern +EXPORT_SYMBOL vmlinux 0x4fa75270 inet_frags_fini +EXPORT_SYMBOL vmlinux 0x4faa2fe0 dma_async_memcpy_pg_to_pg +EXPORT_SYMBOL vmlinux 0x4fb796e6 md_done_sync +EXPORT_SYMBOL vmlinux 0x4fcee107 __up_read +EXPORT_SYMBOL vmlinux 0x4fd96f21 mmc_detect_change +EXPORT_SYMBOL vmlinux 0x4fdee897 i8042_command +EXPORT_SYMBOL vmlinux 0x4fe4723a dma_pool_free +EXPORT_SYMBOL vmlinux 0x4fe4a875 register_sysrq_key +EXPORT_SYMBOL vmlinux 0x4ffdd0e6 __xfrm_policy_check +EXPORT_SYMBOL vmlinux 0x50211ee3 tcp_free_md5sig_pool +EXPORT_SYMBOL vmlinux 0x509189e0 single_open +EXPORT_SYMBOL vmlinux 0x509611e0 inode_double_unlock +EXPORT_SYMBOL vmlinux 0x509dd4fd blk_rq_map_user +EXPORT_SYMBOL vmlinux 0x50b5cb2d idr_get_new_above +EXPORT_SYMBOL vmlinux 0x50cb73c5 inet_twsk_deschedule +EXPORT_SYMBOL vmlinux 0x50f10820 bio_clone +EXPORT_SYMBOL vmlinux 0x5118c382 secure_dccp_sequence_number +EXPORT_SYMBOL vmlinux 0x51458dfb pnp_release_card_device +EXPORT_SYMBOL vmlinux 0x51503ac2 nobh_truncate_page +EXPORT_SYMBOL vmlinux 0x517ce3af simple_write_end +EXPORT_SYMBOL vmlinux 0x51a45271 rtnl_notify +EXPORT_SYMBOL vmlinux 0x51d12d4e acpi_pci_disabled +EXPORT_SYMBOL vmlinux 0x51d7a776 acpi_detach_data +EXPORT_SYMBOL vmlinux 0x51dce73b xfrm_state_walk_init +EXPORT_SYMBOL vmlinux 0x52026cdf security_sb_parse_opts_str +EXPORT_SYMBOL vmlinux 0x520af169 nf_reinject +EXPORT_SYMBOL vmlinux 0x521d63ec wait_for_key_construction +EXPORT_SYMBOL vmlinux 0x522f5573 pv_irq_ops +EXPORT_SYMBOL vmlinux 0x5252f304 __memcpy_toio +EXPORT_SYMBOL vmlinux 0x526618e5 handle_sysrq +EXPORT_SYMBOL vmlinux 0x526f7ce8 __xfrm_route_forward +EXPORT_SYMBOL vmlinux 0x527c75e1 blkdev_dequeue_request +EXPORT_SYMBOL vmlinux 0x529dabda devm_ioport_unmap +EXPORT_SYMBOL vmlinux 0x529deb40 shrink_dcache_parent +EXPORT_SYMBOL vmlinux 0x52a58c24 ifla_policy +EXPORT_SYMBOL vmlinux 0x52d39396 elv_rq_merge_ok +EXPORT_SYMBOL vmlinux 0x52d7b2fd llc_sap_list +EXPORT_SYMBOL vmlinux 0x52d7d17b bt_sock_unlink +EXPORT_SYMBOL vmlinux 0x52ec38f1 inode_set_bytes +EXPORT_SYMBOL vmlinux 0x5306db6e jbd2_journal_clear_features +EXPORT_SYMBOL vmlinux 0x530b1e98 pm_suspend +EXPORT_SYMBOL vmlinux 0x531b604e __virt_addr_valid +EXPORT_SYMBOL vmlinux 0x532f2924 param_get_byte +EXPORT_SYMBOL vmlinux 0x53326531 mempool_alloc_pages +EXPORT_SYMBOL vmlinux 0x536ee332 sg_miter_stop +EXPORT_SYMBOL vmlinux 0x537dc195 tty_name +EXPORT_SYMBOL vmlinux 0x5381f539 backlight_device_unregister +EXPORT_SYMBOL vmlinux 0x538383c0 unregister_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0x53895d69 file_permission +EXPORT_SYMBOL vmlinux 0x538e2460 inet_proto_csum_replace4 +EXPORT_SYMBOL vmlinux 0x53bdca17 nf_afinfo +EXPORT_SYMBOL vmlinux 0x53c0767c sk_chk_filter +EXPORT_SYMBOL vmlinux 0x541818ec elv_rb_add +EXPORT_SYMBOL vmlinux 0x54290dc9 nla_validate +EXPORT_SYMBOL vmlinux 0x543affb5 per_cpu__kstat +EXPORT_SYMBOL vmlinux 0x5471a0bb xfrm_find_acq +EXPORT_SYMBOL vmlinux 0x54757923 agp_backend_release +EXPORT_SYMBOL vmlinux 0x547a8a7c scsi_print_command +EXPORT_SYMBOL vmlinux 0x548d56c3 rfkill_register +EXPORT_SYMBOL vmlinux 0x54934569 bio_integrity_tag_size +EXPORT_SYMBOL vmlinux 0x54b81541 init_timer_deferrable +EXPORT_SYMBOL vmlinux 0x54bfaf35 tcp_sendmsg +EXPORT_SYMBOL vmlinux 0x54d69b36 atm_dev_register +EXPORT_SYMBOL vmlinux 0x54e6fcdd net_enable_timestamp +EXPORT_SYMBOL vmlinux 0x54e954d5 pci_enable_device_mem +EXPORT_SYMBOL vmlinux 0x54ed4e86 __ip_select_ident +EXPORT_SYMBOL vmlinux 0x550f8ade groups_alloc +EXPORT_SYMBOL vmlinux 0x55578d2c pci_lost_interrupt +EXPORT_SYMBOL vmlinux 0x5575d022 acpi_processor_notify_smm +EXPORT_SYMBOL vmlinux 0x557f01d2 i2c_release_client +EXPORT_SYMBOL vmlinux 0x5584b852 netif_device_attach +EXPORT_SYMBOL vmlinux 0x558dae7d bdget_disk +EXPORT_SYMBOL vmlinux 0x558e869c do_SAK +EXPORT_SYMBOL vmlinux 0x5594be03 bitmap_remap +EXPORT_SYMBOL vmlinux 0x55b03981 journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x55b309bd sysctl_ms_jiffies +EXPORT_SYMBOL vmlinux 0x55e1d220 xfrm_policy_unregister_afinfo +EXPORT_SYMBOL vmlinux 0x55f151fe cap_netlink_recv +EXPORT_SYMBOL vmlinux 0x5600904f fb_get_color_depth +EXPORT_SYMBOL vmlinux 0x560ece3e sock_no_getname +EXPORT_SYMBOL vmlinux 0x5614b010 xfrm_policy_walk_done +EXPORT_SYMBOL vmlinux 0x562a4180 tc_classify +EXPORT_SYMBOL vmlinux 0x5635a60a vmalloc_user +EXPORT_SYMBOL vmlinux 0x563acb40 compat_nf_setsockopt +EXPORT_SYMBOL vmlinux 0x567c018f lease_modify +EXPORT_SYMBOL vmlinux 0x56831d40 netif_carrier_off +EXPORT_SYMBOL vmlinux 0x568728c9 pci_enable_msi +EXPORT_SYMBOL vmlinux 0x56a4a1a9 dev_unicast_sync +EXPORT_SYMBOL vmlinux 0x56b2149d create_empty_buffers +EXPORT_SYMBOL vmlinux 0x56b8878c blk_queue_invalidate_tags +EXPORT_SYMBOL vmlinux 0x56c8799d scsi_kunmap_atomic_sg +EXPORT_SYMBOL vmlinux 0x56d38b40 send_sig_info +EXPORT_SYMBOL vmlinux 0x56d5e4ef ethtool_op_get_flags +EXPORT_SYMBOL vmlinux 0x56f2a90c thermal_zone_unbind_cooling_device +EXPORT_SYMBOL vmlinux 0x56f494e0 smp_call_function +EXPORT_SYMBOL vmlinux 0x5706fe40 ethtool_op_set_tso +EXPORT_SYMBOL vmlinux 0x570d62bf sock_wake_async +EXPORT_SYMBOL vmlinux 0x572c1556 netpoll_poll +EXPORT_SYMBOL vmlinux 0x572e85d4 blk_lookup_devt +EXPORT_SYMBOL vmlinux 0x5740bbbc vfs_statfs +EXPORT_SYMBOL vmlinux 0x57509861 truncate_inode_pages +EXPORT_SYMBOL vmlinux 0x577cc638 mutex_unlock +EXPORT_SYMBOL vmlinux 0x5792721e bdevname +EXPORT_SYMBOL vmlinux 0x57c9dfa2 register_8022_client +EXPORT_SYMBOL vmlinux 0x57dab10e register_netdevice +EXPORT_SYMBOL vmlinux 0x58011f50 __netdev_alloc_skb +EXPORT_SYMBOL vmlinux 0x5810f6f2 put_io_context +EXPORT_SYMBOL vmlinux 0x5823ee60 serio_open +EXPORT_SYMBOL vmlinux 0x5827adf9 copy_strings_kernel +EXPORT_SYMBOL vmlinux 0x5838f6c9 rtc_valid_tm +EXPORT_SYMBOL vmlinux 0x584738f9 rdmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x5857b225 ioread16_rep +EXPORT_SYMBOL vmlinux 0x588ab303 pcie_port_service_unregister +EXPORT_SYMBOL vmlinux 0x58941e75 tcp_setsockopt +EXPORT_SYMBOL vmlinux 0x58cfb592 clear_inode +EXPORT_SYMBOL vmlinux 0x58ec2925 ipv6_skip_exthdr +EXPORT_SYMBOL vmlinux 0x590bf11e thaw_process +EXPORT_SYMBOL vmlinux 0x591ec956 find_get_page +EXPORT_SYMBOL vmlinux 0x592c12d5 blk_plug_device_unlocked +EXPORT_SYMBOL vmlinux 0x5934392b fb_register_client +EXPORT_SYMBOL vmlinux 0x594a1892 acpi_bus_add +EXPORT_SYMBOL vmlinux 0x594bf15b ioport_map +EXPORT_SYMBOL vmlinux 0x59653ff0 invalidate_partition +EXPORT_SYMBOL vmlinux 0x59679f93 dst_release +EXPORT_SYMBOL vmlinux 0x59706f79 nf_log_unregister_pf +EXPORT_SYMBOL vmlinux 0x5984e4fd acpi_processor_register_performance +EXPORT_SYMBOL vmlinux 0x599f4195 iget_failed +EXPORT_SYMBOL vmlinux 0x59cefff4 mmc_resume_host +EXPORT_SYMBOL vmlinux 0x59d36624 unregister_framebuffer +EXPORT_SYMBOL vmlinux 0x59d696b6 register_module_notifier +EXPORT_SYMBOL vmlinux 0x59e1c47c sk_stop_timer +EXPORT_SYMBOL vmlinux 0x5a062b0c filemap_fdatawrite_range +EXPORT_SYMBOL vmlinux 0x5a11ec92 scsi_ioctl +EXPORT_SYMBOL vmlinux 0x5a34a45c __kmalloc +EXPORT_SYMBOL vmlinux 0x5a4738f9 try_to_free_buffers +EXPORT_SYMBOL vmlinux 0x5a4896a8 __put_user_2 +EXPORT_SYMBOL vmlinux 0x5a5e7ea3 simple_read_from_buffer +EXPORT_SYMBOL vmlinux 0x5a60ae2d dquot_initialize +EXPORT_SYMBOL vmlinux 0x5a67e4b1 blk_rq_map_sg +EXPORT_SYMBOL vmlinux 0x5a69219f __up_write +EXPORT_SYMBOL vmlinux 0x5a704bb4 sysctl_intvec +EXPORT_SYMBOL vmlinux 0x5a744b86 netlink_set_nonroot +EXPORT_SYMBOL vmlinux 0x5ab8e1b4 wireless_send_event +EXPORT_SYMBOL vmlinux 0x5ac376a5 acpi_install_fixed_event_handler +EXPORT_SYMBOL vmlinux 0x5ac47916 phy_attach +EXPORT_SYMBOL vmlinux 0x5ac74482 call_usermodehelper_exec +EXPORT_SYMBOL vmlinux 0x5ae10545 xfrm6_rcv_spi +EXPORT_SYMBOL vmlinux 0x5b36df0f ip_queue_xmit +EXPORT_SYMBOL vmlinux 0x5b51c6a7 acpi_walk_resources +EXPORT_SYMBOL vmlinux 0x5b547aa2 ip_defrag +EXPORT_SYMBOL vmlinux 0x5b5ca7c6 block_commit_write +EXPORT_SYMBOL vmlinux 0x5b650190 scsi_host_set_state +EXPORT_SYMBOL vmlinux 0x5b733bf3 md_unregister_thread +EXPORT_SYMBOL vmlinux 0x5bae2eac acpi_extract_package +EXPORT_SYMBOL vmlinux 0x5bb5f76a kill_pid +EXPORT_SYMBOL vmlinux 0x5bb80581 dev_get_by_index +EXPORT_SYMBOL vmlinux 0x5bb97a98 proc_symlink +EXPORT_SYMBOL vmlinux 0x5bcc0b2e atm_proc_root +EXPORT_SYMBOL vmlinux 0x5bdbec0a kthread_bind +EXPORT_SYMBOL vmlinux 0x5be1ae55 d_add_ci +EXPORT_SYMBOL vmlinux 0x5bec44cb __down_write +EXPORT_SYMBOL vmlinux 0x5c1bfc35 skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x5c46b6fa posix_acl_chmod_masq +EXPORT_SYMBOL vmlinux 0x5c5b1f92 phy_driver_register +EXPORT_SYMBOL vmlinux 0x5c5bf4dd journal_init_inode +EXPORT_SYMBOL vmlinux 0x5c6241f0 kernel_sendmsg +EXPORT_SYMBOL vmlinux 0x5c75bdd3 mmc_free_host +EXPORT_SYMBOL vmlinux 0x5ca0000d schedule_delayed_work_on +EXPORT_SYMBOL vmlinux 0x5cc8e015 iov_iter_single_seg_count +EXPORT_SYMBOL vmlinux 0x5cdd7614 get_agp_version +EXPORT_SYMBOL vmlinux 0x5ce8a248 register_con_driver +EXPORT_SYMBOL vmlinux 0x5cf6bc93 get_super +EXPORT_SYMBOL vmlinux 0x5d113035 vm_stat +EXPORT_SYMBOL vmlinux 0x5d36f216 agp_generic_remove_memory +EXPORT_SYMBOL vmlinux 0x5d37d497 tcp_prot +EXPORT_SYMBOL vmlinux 0x5d73b5f8 km_waitq +EXPORT_SYMBOL vmlinux 0x5dbcfa4f boot_cpu_physical_apicid +EXPORT_SYMBOL vmlinux 0x5dcdf7b2 icmp_send +EXPORT_SYMBOL vmlinux 0x5dfa7d8f tcf_hash_check +EXPORT_SYMBOL vmlinux 0x5e07df81 blk_rq_init +EXPORT_SYMBOL vmlinux 0x5e1a8dea nf_setsockopt +EXPORT_SYMBOL vmlinux 0x5e30a6e5 sb_has_dirty_inodes +EXPORT_SYMBOL vmlinux 0x5e498497 __secpath_destroy +EXPORT_SYMBOL vmlinux 0x5e4f995f uart_get_divisor +EXPORT_SYMBOL vmlinux 0x5e617dd5 proc_dointvec +EXPORT_SYMBOL vmlinux 0x5e703255 ethtool_op_set_ufo +EXPORT_SYMBOL vmlinux 0x5e79ebec gen_replace_estimator +EXPORT_SYMBOL vmlinux 0x5e9b9578 tcf_exts_validate +EXPORT_SYMBOL vmlinux 0x5e9f09df get_io_context +EXPORT_SYMBOL vmlinux 0x5ea520c5 tcp_select_initial_window +EXPORT_SYMBOL vmlinux 0x5ec03951 sock_no_bind +EXPORT_SYMBOL vmlinux 0x5ecdce4e ppp_unregister_channel +EXPORT_SYMBOL vmlinux 0x5ed040b0 pm_set_vt_switch +EXPORT_SYMBOL vmlinux 0x5edd0762 bin2bcd +EXPORT_SYMBOL vmlinux 0x5ee27766 kill_pgrp +EXPORT_SYMBOL vmlinux 0x5f292f70 jbd2_journal_unlock_updates +EXPORT_SYMBOL vmlinux 0x5f2ca5e3 ps2_drain +EXPORT_SYMBOL vmlinux 0x5f581a10 current_fs_time +EXPORT_SYMBOL vmlinux 0x5f6f0663 is_container_init +EXPORT_SYMBOL vmlinux 0x5f7a743c vfs_rmdir +EXPORT_SYMBOL vmlinux 0x5f8755fc block_write_full_page +EXPORT_SYMBOL vmlinux 0x5f8a9e0f pci_assign_resource +EXPORT_SYMBOL vmlinux 0x5fbbb73b dmam_pool_destroy +EXPORT_SYMBOL vmlinux 0x5fd02b6d pci_request_selected_regions +EXPORT_SYMBOL vmlinux 0x5fdacb57 tcp_v4_md5_do_del +EXPORT_SYMBOL vmlinux 0x5fdb5efe eth_rebuild_header +EXPORT_SYMBOL vmlinux 0x5fe7c069 __kill_fasync +EXPORT_SYMBOL vmlinux 0x5fe941b9 cdrom_release +EXPORT_SYMBOL vmlinux 0x5fed2942 netlink_rcv_skb +EXPORT_SYMBOL vmlinux 0x5ff42b08 acpi_video_get_capabilities +EXPORT_SYMBOL vmlinux 0x600683d3 do_unblank_screen +EXPORT_SYMBOL vmlinux 0x6006da77 mmc_request_done +EXPORT_SYMBOL vmlinux 0x604bc767 names_cachep +EXPORT_SYMBOL vmlinux 0x60599772 generic_readlink +EXPORT_SYMBOL vmlinux 0x605c8bde radix_tree_delete +EXPORT_SYMBOL vmlinux 0x60612cef ip_dev_find +EXPORT_SYMBOL vmlinux 0x608c2831 warn_on_slowpath +EXPORT_SYMBOL vmlinux 0x609f1c7e synchronize_net +EXPORT_SYMBOL vmlinux 0x60a32ea9 pm_power_off +EXPORT_SYMBOL vmlinux 0x60c841d0 __breadahead +EXPORT_SYMBOL vmlinux 0x60d9bf15 ppp_output_wakeup +EXPORT_SYMBOL vmlinux 0x610c9818 udp_lib_getsockopt +EXPORT_SYMBOL vmlinux 0x6111e1bc init_timer +EXPORT_SYMBOL vmlinux 0x612390ad netpoll_set_trap +EXPORT_SYMBOL vmlinux 0x6159c44d request_key_async +EXPORT_SYMBOL vmlinux 0x6177aea3 md_write_start +EXPORT_SYMBOL vmlinux 0x618d8299 set_notify_swap_entry_free +EXPORT_SYMBOL vmlinux 0x61a43a00 d_instantiate +EXPORT_SYMBOL vmlinux 0x61b7b126 simple_strtoull +EXPORT_SYMBOL vmlinux 0x61c1c365 unregister_key_type +EXPORT_SYMBOL vmlinux 0x61e7eba8 tcp_close +EXPORT_SYMBOL vmlinux 0x61f6e9df skb_gso_segment +EXPORT_SYMBOL vmlinux 0x62049256 acpi_disable +EXPORT_SYMBOL vmlinux 0x6211c1b4 iov_iter_copy_from_user +EXPORT_SYMBOL vmlinux 0x6237f6b5 acpi_enable_event +EXPORT_SYMBOL vmlinux 0x62737e1d sock_unregister +EXPORT_SYMBOL vmlinux 0x62748e70 acpi_set_current_resources +EXPORT_SYMBOL vmlinux 0x62827bec security_secctx_to_secid +EXPORT_SYMBOL vmlinux 0x628d761c dev_queue_xmit +EXPORT_SYMBOL vmlinux 0x6297f30d jbd2_journal_errno +EXPORT_SYMBOL vmlinux 0x62e5d67c block_page_mkwrite +EXPORT_SYMBOL vmlinux 0x6302a83f jbd2_journal_wipe +EXPORT_SYMBOL vmlinux 0x630712b5 pnp_get_resource +EXPORT_SYMBOL vmlinux 0x630c5b0f i2c_put_adapter +EXPORT_SYMBOL vmlinux 0x635278d7 ethtool_op_get_link +EXPORT_SYMBOL vmlinux 0x6356753f scsi_dma_map +EXPORT_SYMBOL vmlinux 0x63694ce7 key_unlink +EXPORT_SYMBOL vmlinux 0x636a5691 acpi_register_ioapic +EXPORT_SYMBOL vmlinux 0x636e086f skb_copy_datagram_from_iovec +EXPORT_SYMBOL vmlinux 0x63727852 tty_unregister_device +EXPORT_SYMBOL vmlinux 0x6381baa9 hci_unregister_dev +EXPORT_SYMBOL vmlinux 0x63875eee neigh_seq_start +EXPORT_SYMBOL vmlinux 0x63a9345f udp_lib_setsockopt +EXPORT_SYMBOL vmlinux 0x63abe61b skb_store_bits +EXPORT_SYMBOL vmlinux 0x63cd2085 remove_arg_zero +EXPORT_SYMBOL vmlinux 0x63db67fc kobject_set_name +EXPORT_SYMBOL vmlinux 0x63dfe9ad jbd2_journal_check_available_features +EXPORT_SYMBOL vmlinux 0x63ecad53 register_netdevice_notifier +EXPORT_SYMBOL vmlinux 0x63f1300b put_filp +EXPORT_SYMBOL vmlinux 0x63f1d58f request_key_async_with_auxdata +EXPORT_SYMBOL vmlinux 0x63fc232f strlen_user +EXPORT_SYMBOL vmlinux 0x63fd48db neigh_table_clear +EXPORT_SYMBOL vmlinux 0x6403e338 tcp_memory_pressure +EXPORT_SYMBOL vmlinux 0x640684f1 tcp_md5_hash_skb_data +EXPORT_SYMBOL vmlinux 0x640db09d set_pages_nx +EXPORT_SYMBOL vmlinux 0x642e54ac __wake_up +EXPORT_SYMBOL vmlinux 0x643d51f1 release_sock +EXPORT_SYMBOL vmlinux 0x6451294b posix_acl_valid +EXPORT_SYMBOL vmlinux 0x6464870b register_snap_client +EXPORT_SYMBOL vmlinux 0x6466a1e6 mempool_alloc +EXPORT_SYMBOL vmlinux 0x6468ba15 vfs_dq_drop +EXPORT_SYMBOL vmlinux 0x6478134c ec_burst_enable +EXPORT_SYMBOL vmlinux 0x647eea3c balance_dirty_pages_ratelimited_nr +EXPORT_SYMBOL vmlinux 0x648300b9 pci_save_state +EXPORT_SYMBOL vmlinux 0x64999478 congestion_wait +EXPORT_SYMBOL vmlinux 0x64cd5d16 init_waitqueue_head +EXPORT_SYMBOL vmlinux 0x64d68d5c fddi_type_trans +EXPORT_SYMBOL vmlinux 0x64e1d6a4 __scsi_put_command +EXPORT_SYMBOL vmlinux 0x64e36171 skb_dequeue_tail +EXPORT_SYMBOL vmlinux 0x64eae7ad set_memory_array_wb +EXPORT_SYMBOL vmlinux 0x64ed8b81 phy_sanitize_settings +EXPORT_SYMBOL vmlinux 0x650128e7 br_fdb_get_hook +EXPORT_SYMBOL vmlinux 0x650fb346 add_wait_queue +EXPORT_SYMBOL vmlinux 0x651a4139 test_taint +EXPORT_SYMBOL vmlinux 0x651f2599 generic_file_splice_write +EXPORT_SYMBOL vmlinux 0x65367084 genl_unregister_ops +EXPORT_SYMBOL vmlinux 0x65408378 zlib_inflate_blob +EXPORT_SYMBOL vmlinux 0x65414e67 dev_valid_name +EXPORT_SYMBOL vmlinux 0x654ab4af sk_alloc +EXPORT_SYMBOL vmlinux 0x656e4dda elv_dispatch_add_tail +EXPORT_SYMBOL vmlinux 0x65ca1581 blk_requeue_request +EXPORT_SYMBOL vmlinux 0x65d7a243 blk_queue_softirq_done +EXPORT_SYMBOL vmlinux 0x6645885a eth_header_parse +EXPORT_SYMBOL vmlinux 0x665737b3 init_file +EXPORT_SYMBOL vmlinux 0x668da8d5 zlib_inflateIncomp +EXPORT_SYMBOL vmlinux 0x66ae9537 dcache_dir_lseek +EXPORT_SYMBOL vmlinux 0x66d966ea misc_register +EXPORT_SYMBOL vmlinux 0x6708231c bd_release +EXPORT_SYMBOL vmlinux 0x670cf232 bio_integrity_get_tag +EXPORT_SYMBOL vmlinux 0x672144bd strlcpy +EXPORT_SYMBOL vmlinux 0x6729d3df __get_user_4 +EXPORT_SYMBOL vmlinux 0x673f815e agp_bridges +EXPORT_SYMBOL vmlinux 0x67825481 arch_debugfs_dir +EXPORT_SYMBOL vmlinux 0x678d21c6 n_tty_ioctl_helper +EXPORT_SYMBOL vmlinux 0x679a6bf0 sk_dst_check +EXPORT_SYMBOL vmlinux 0x67b27ec1 tty_std_termios +EXPORT_SYMBOL vmlinux 0x67c2ee94 jbd2_journal_revoke +EXPORT_SYMBOL vmlinux 0x67e71b77 __mutex_init +EXPORT_SYMBOL vmlinux 0x681cda32 compat_ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x68257c4c swiotlb_map_sg_attrs +EXPORT_SYMBOL vmlinux 0x6833130b vfs_read +EXPORT_SYMBOL vmlinux 0x68470ac2 alloc_disk_node +EXPORT_SYMBOL vmlinux 0x684ad884 __bread +EXPORT_SYMBOL vmlinux 0x685902da locks_remove_posix +EXPORT_SYMBOL vmlinux 0x687521dd open_by_devnum +EXPORT_SYMBOL vmlinux 0x68765772 alloc_trdev +EXPORT_SYMBOL vmlinux 0x68852816 freeze_bdev +EXPORT_SYMBOL vmlinux 0x68a7fd80 scsi_bios_ptable +EXPORT_SYMBOL vmlinux 0x68b2b105 compat_mc_getsockopt +EXPORT_SYMBOL vmlinux 0x68df643b blk_rq_count_integrity_sg +EXPORT_SYMBOL vmlinux 0x6907d4e9 idr_for_each +EXPORT_SYMBOL vmlinux 0x694169dc unlock_page +EXPORT_SYMBOL vmlinux 0x695b2d52 journal_stop +EXPORT_SYMBOL vmlinux 0x6971447a rtc_month_days +EXPORT_SYMBOL vmlinux 0x698f8712 test_set_page_writeback +EXPORT_SYMBOL vmlinux 0x69927dff try_acquire_console_sem +EXPORT_SYMBOL vmlinux 0x6999b675 scsi_cmd_ioctl +EXPORT_SYMBOL vmlinux 0x699eae01 nf_ip6_checksum +EXPORT_SYMBOL vmlinux 0x69a0ca7d iowrite16be +EXPORT_SYMBOL vmlinux 0x69a358a6 iomem_resource +EXPORT_SYMBOL vmlinux 0x69a994fa sk_stream_wait_memory +EXPORT_SYMBOL vmlinux 0x69ae5d94 journal_wipe +EXPORT_SYMBOL vmlinux 0x69c8c1d5 security_req_classify_flow +EXPORT_SYMBOL vmlinux 0x69d2575f efi +EXPORT_SYMBOL vmlinux 0x69d38ed9 __scsi_print_sense +EXPORT_SYMBOL vmlinux 0x69e27c7a bitmap_copy_le +EXPORT_SYMBOL vmlinux 0x69e51b9f skb_copy_and_csum_bits +EXPORT_SYMBOL vmlinux 0x6a037cf1 mempool_kfree +EXPORT_SYMBOL vmlinux 0x6a3b301e hci_alloc_dev +EXPORT_SYMBOL vmlinux 0x6a47571d __set_personality +EXPORT_SYMBOL vmlinux 0x6a5f98a0 ida_get_new_above +EXPORT_SYMBOL vmlinux 0x6a5fa363 sigprocmask +EXPORT_SYMBOL vmlinux 0x6a657804 key_task_permission +EXPORT_SYMBOL vmlinux 0x6a9e3089 fb_get_buffer_offset +EXPORT_SYMBOL vmlinux 0x6abfb1be rtnl_unicast +EXPORT_SYMBOL vmlinux 0x6acb973d iowrite32be +EXPORT_SYMBOL vmlinux 0x6ad85887 acpi_enable_gpe +EXPORT_SYMBOL vmlinux 0x6add5c9a dmi_find_device +EXPORT_SYMBOL vmlinux 0x6aefd07b xfrm_register_mode +EXPORT_SYMBOL vmlinux 0x6b0947ec dma_set_mask +EXPORT_SYMBOL vmlinux 0x6b1b67d3 __bdevname +EXPORT_SYMBOL vmlinux 0x6b29281c skb_copy +EXPORT_SYMBOL vmlinux 0x6b2dc060 dump_stack +EXPORT_SYMBOL vmlinux 0x6b4e5a52 radix_tree_lookup_slot +EXPORT_SYMBOL vmlinux 0x6b75459c sock_recvmsg +EXPORT_SYMBOL vmlinux 0x6b9b88f3 sleep_on +EXPORT_SYMBOL vmlinux 0x6bafbced mod_timer +EXPORT_SYMBOL vmlinux 0x6bc1d2bd __kfree_skb +EXPORT_SYMBOL vmlinux 0x6bc56c67 radix_tree_next_hole +EXPORT_SYMBOL vmlinux 0x6bdcfd99 qdisc_class_hash_remove +EXPORT_SYMBOL vmlinux 0x6beea115 jbd2_journal_restart +EXPORT_SYMBOL vmlinux 0x6c0138d5 uart_write_wakeup +EXPORT_SYMBOL vmlinux 0x6c11e64f pci_request_region +EXPORT_SYMBOL vmlinux 0x6c1aa58c bio_get_nr_vecs +EXPORT_SYMBOL vmlinux 0x6c2197a9 pci_target_state +EXPORT_SYMBOL vmlinux 0x6c330a1b ip_mc_rejoin_group +EXPORT_SYMBOL vmlinux 0x6c389761 acpi_bus_get_private_data +EXPORT_SYMBOL vmlinux 0x6c58406c phy_start +EXPORT_SYMBOL vmlinux 0x6c61ce70 num_registered_fb +EXPORT_SYMBOL vmlinux 0x6c66324c uart_get_baud_rate +EXPORT_SYMBOL vmlinux 0x6c6dfe32 fifo_set_limit +EXPORT_SYMBOL vmlinux 0x6c702af7 sysctl_udp_rmem_min +EXPORT_SYMBOL vmlinux 0x6c75b0d4 acpi_unlock_battery_dir +EXPORT_SYMBOL vmlinux 0x6c97fff2 pcie_set_readrq +EXPORT_SYMBOL vmlinux 0x6ca81052 hci_unregister_cb +EXPORT_SYMBOL vmlinux 0x6cb9c88f kernel_getsockname +EXPORT_SYMBOL vmlinux 0x6cbe7632 posix_acl_to_xattr +EXPORT_SYMBOL vmlinux 0x6cc07f0f register_framebuffer +EXPORT_SYMBOL vmlinux 0x6cd5ba8f sb_min_blocksize +EXPORT_SYMBOL vmlinux 0x6cf643bf elevator_init +EXPORT_SYMBOL vmlinux 0x6d0da34c param_get_short +EXPORT_SYMBOL vmlinux 0x6d1ced27 vcc_sklist_lock +EXPORT_SYMBOL vmlinux 0x6d1d3747 tcp_make_synack +EXPORT_SYMBOL vmlinux 0x6d1f3083 kernel_bind +EXPORT_SYMBOL vmlinux 0x6d27ef64 __bitmap_empty +EXPORT_SYMBOL vmlinux 0x6d294e43 clock_t_to_jiffies +EXPORT_SYMBOL vmlinux 0x6d2a193e tty_shutdown +EXPORT_SYMBOL vmlinux 0x6d334118 __get_user_8 +EXPORT_SYMBOL vmlinux 0x6d340f64 tty_termios_input_baud_rate +EXPORT_SYMBOL vmlinux 0x6d47c2e3 tcp_timewait_state_process +EXPORT_SYMBOL vmlinux 0x6d47c62a __scm_send +EXPORT_SYMBOL vmlinux 0x6d47d90d groups_free +EXPORT_SYMBOL vmlinux 0x6d524947 simple_dir_operations +EXPORT_SYMBOL vmlinux 0x6d54fd97 blk_queue_set_discard +EXPORT_SYMBOL vmlinux 0x6d83e2bf ip_mc_join_group +EXPORT_SYMBOL vmlinux 0x6da43125 vfs_readv +EXPORT_SYMBOL vmlinux 0x6da626ff free_task +EXPORT_SYMBOL vmlinux 0x6dc0c24b complete_and_exit +EXPORT_SYMBOL vmlinux 0x6de6bf83 radix_tree_lookup +EXPORT_SYMBOL vmlinux 0x6def2db2 half_md4_transform +EXPORT_SYMBOL vmlinux 0x6e026770 iw_handler_get_thrspy +EXPORT_SYMBOL vmlinux 0x6e07a54e acpi_get_gpe_status +EXPORT_SYMBOL vmlinux 0x6e1a4bbb udp_hash_lock +EXPORT_SYMBOL vmlinux 0x6e1f7574 sk_send_sigurg +EXPORT_SYMBOL vmlinux 0x6e5ad508 __blockdev_direct_IO +EXPORT_SYMBOL vmlinux 0x6e720ff2 rtnl_unlock +EXPORT_SYMBOL vmlinux 0x6e8bacb9 iunique +EXPORT_SYMBOL vmlinux 0x6e9dd606 __symbol_put +EXPORT_SYMBOL vmlinux 0x6ead242b cond_resched_lock +EXPORT_SYMBOL vmlinux 0x6ecd3a7c genphy_read_status +EXPORT_SYMBOL vmlinux 0x6ed881a0 invalidate_bdev +EXPORT_SYMBOL vmlinux 0x6f79a319 pci_dev_driver +EXPORT_SYMBOL vmlinux 0x6f9678cd iput +EXPORT_SYMBOL vmlinux 0x6f9b9bbc bt_sock_recvmsg +EXPORT_SYMBOL vmlinux 0x6fb1dc03 tcf_em_register +EXPORT_SYMBOL vmlinux 0x6fc80be3 phy_driver_unregister +EXPORT_SYMBOL vmlinux 0x6fcb87a1 touch_softlockup_watchdog +EXPORT_SYMBOL vmlinux 0x6fdb639d agp_generic_free_gatt_table +EXPORT_SYMBOL vmlinux 0x6fe1ffa1 tty_set_operations +EXPORT_SYMBOL vmlinux 0x6fe295f9 tty_unthrottle +EXPORT_SYMBOL vmlinux 0x6fe91ddb __netdev_alloc_page +EXPORT_SYMBOL vmlinux 0x7008a9b7 timespec_to_jiffies +EXPORT_SYMBOL vmlinux 0x700fda5f simple_transaction_get +EXPORT_SYMBOL vmlinux 0x702d47c6 proc_mkdir +EXPORT_SYMBOL vmlinux 0x702ff8e7 pnp_register_driver +EXPORT_SYMBOL vmlinux 0x70538c79 textsearch_find_continuous +EXPORT_SYMBOL vmlinux 0x7054a3e4 request_dma +EXPORT_SYMBOL vmlinux 0x70679d78 seq_release_private +EXPORT_SYMBOL vmlinux 0x706ed5fb d_alloc +EXPORT_SYMBOL vmlinux 0x7094f8ae bt_err +EXPORT_SYMBOL vmlinux 0x70d27d90 ethtool_op_get_tx_csum +EXPORT_SYMBOL vmlinux 0x70d8ab82 acpi_acquire_global_lock +EXPORT_SYMBOL vmlinux 0x70ded075 sock_wmalloc +EXPORT_SYMBOL vmlinux 0x70dedb1e kernel_getpeername +EXPORT_SYMBOL vmlinux 0x70e0d61f cpu_all_bits +EXPORT_SYMBOL vmlinux 0x70f2a8ed blk_insert_request +EXPORT_SYMBOL vmlinux 0x70f80486 mb_cache_entry_release +EXPORT_SYMBOL vmlinux 0x70f89459 clip_tbl_hook +EXPORT_SYMBOL vmlinux 0x71273786 tcp_v4_syn_recv_sock +EXPORT_SYMBOL vmlinux 0x7129e5f8 hex_asc +EXPORT_SYMBOL vmlinux 0x712aa29b _spin_lock_irqsave +EXPORT_SYMBOL vmlinux 0x71356fba remove_wait_queue +EXPORT_SYMBOL vmlinux 0x7163c496 dev_kfree_skb_any +EXPORT_SYMBOL vmlinux 0x716eb724 xfrm_bundle_ok +EXPORT_SYMBOL vmlinux 0x7171121c overflowgid +EXPORT_SYMBOL vmlinux 0x71a50dbc register_blkdev +EXPORT_SYMBOL vmlinux 0x71abfb6b bd_claim +EXPORT_SYMBOL vmlinux 0x71d9e386 agp_generic_type_to_mask_type +EXPORT_SYMBOL vmlinux 0x71e8e2b3 tcp_v4_do_rcv +EXPORT_SYMBOL vmlinux 0x71f64d3a phy_ethtool_sset +EXPORT_SYMBOL vmlinux 0x71f6eb38 sg_copy_from_buffer +EXPORT_SYMBOL vmlinux 0x71f7c5ef swiotlb_alloc_coherent +EXPORT_SYMBOL vmlinux 0x72166196 neigh_changeaddr +EXPORT_SYMBOL vmlinux 0x721732c0 inet_shutdown +EXPORT_SYMBOL vmlinux 0x721f31ff pci_enable_bridges +EXPORT_SYMBOL vmlinux 0x72270e35 do_gettimeofday +EXPORT_SYMBOL vmlinux 0x722ea4fe fb_blank +EXPORT_SYMBOL vmlinux 0x7242e96d strnchr +EXPORT_SYMBOL vmlinux 0x72515048 tcf_unregister_action +EXPORT_SYMBOL vmlinux 0x725dc6df clocksource_register +EXPORT_SYMBOL vmlinux 0x725f33c3 sb_set_blocksize +EXPORT_SYMBOL vmlinux 0x72abd4d0 pci_do_scan_bus +EXPORT_SYMBOL vmlinux 0x72acb99a jbd2_journal_start_commit +EXPORT_SYMBOL vmlinux 0x72b243d4 free_dma +EXPORT_SYMBOL vmlinux 0x72bf2140 mtrr_add +EXPORT_SYMBOL vmlinux 0x72ea7b2d scsi_device_type +EXPORT_SYMBOL vmlinux 0x72f1b1f9 tcf_exts_change +EXPORT_SYMBOL vmlinux 0x73304295 vfs_permission +EXPORT_SYMBOL vmlinux 0x7335e17a blk_register_region +EXPORT_SYMBOL vmlinux 0x735a0bd5 native_io_delay +EXPORT_SYMBOL vmlinux 0x735e480e inet6_unregister_protosw +EXPORT_SYMBOL vmlinux 0x736b0869 noop_qdisc +EXPORT_SYMBOL vmlinux 0x737a7803 scsi_track_queue_full +EXPORT_SYMBOL vmlinux 0x738568e3 tty_throttle +EXPORT_SYMBOL vmlinux 0x7389c9a8 acpi_bus_get_power +EXPORT_SYMBOL vmlinux 0x739ee22d gen_pool_add +EXPORT_SYMBOL vmlinux 0x73a4ca5e vfs_path_lookup +EXPORT_SYMBOL vmlinux 0x73d628ed netif_rx_ni +EXPORT_SYMBOL vmlinux 0x740a1b95 reserve_evntsel_nmi +EXPORT_SYMBOL vmlinux 0x740aba46 __alloc_pages_internal +EXPORT_SYMBOL vmlinux 0x74164334 scsi_device_lookup +EXPORT_SYMBOL vmlinux 0x741b2b7a register_exec_domain +EXPORT_SYMBOL vmlinux 0x748162fb pci_setup_cardbus +EXPORT_SYMBOL vmlinux 0x7485e15e unregister_chrdev_region +EXPORT_SYMBOL vmlinux 0x74891f3a journal_get_undo_access +EXPORT_SYMBOL vmlinux 0x748af56b i2c_smbus_process_call +EXPORT_SYMBOL vmlinux 0x748caf40 down +EXPORT_SYMBOL vmlinux 0x74949b44 kthread_create +EXPORT_SYMBOL vmlinux 0x74a3330d inet_sendmsg +EXPORT_SYMBOL vmlinux 0x74b1136a sk_wait_data +EXPORT_SYMBOL vmlinux 0x74b6c0db lock_sock_nested +EXPORT_SYMBOL vmlinux 0x74cc1cbe unregister_cpu_notifier +EXPORT_SYMBOL vmlinux 0x74cc238d current_kernel_time +EXPORT_SYMBOL vmlinux 0x74e420b1 call_usermodehelper_pipe +EXPORT_SYMBOL vmlinux 0x750f5252 cdrom_number_of_slots +EXPORT_SYMBOL vmlinux 0x75136eb3 skb_split +EXPORT_SYMBOL vmlinux 0x751873f0 single_release +EXPORT_SYMBOL vmlinux 0x752c31ff blk_sync_queue +EXPORT_SYMBOL vmlinux 0x7538b132 agp_off +EXPORT_SYMBOL vmlinux 0x75409b2f cdrom_ioctl +EXPORT_SYMBOL vmlinux 0x756e6992 strnicmp +EXPORT_SYMBOL vmlinux 0x7578cf96 rfkill_unregister +EXPORT_SYMBOL vmlinux 0x75a73f3d ethtool_op_set_tx_csum +EXPORT_SYMBOL vmlinux 0x75bdea12 iommu_area_alloc +EXPORT_SYMBOL vmlinux 0x75d4e616 ps2_init +EXPORT_SYMBOL vmlinux 0x75ea9531 key_negate_and_link +EXPORT_SYMBOL vmlinux 0x760a0f4f yield +EXPORT_SYMBOL vmlinux 0x760b437a unregister_inetaddr_notifier +EXPORT_SYMBOL vmlinux 0x761c1854 skb_copy_and_csum_datagram_iovec +EXPORT_SYMBOL vmlinux 0x7641b0cc alloc_buffer_head +EXPORT_SYMBOL vmlinux 0x764bd77c request_resource +EXPORT_SYMBOL vmlinux 0x76534767 compat_tcp_getsockopt +EXPORT_SYMBOL vmlinux 0x765f202a tcp_v4_remember_stamp +EXPORT_SYMBOL vmlinux 0x766bdc4b blk_queue_stack_limits +EXPORT_SYMBOL vmlinux 0x767dd8fd acpi_get_irq_routing_table +EXPORT_SYMBOL vmlinux 0x767ddb02 set_memory_wc +EXPORT_SYMBOL vmlinux 0x768ea2c4 unregister_console +EXPORT_SYMBOL vmlinux 0x76bb0a0e devm_request_irq +EXPORT_SYMBOL vmlinux 0x76bf656d __bitmap_shift_left +EXPORT_SYMBOL vmlinux 0x76cc1fa4 km_policy_expired +EXPORT_SYMBOL vmlinux 0x76d3cd60 laptop_mode +EXPORT_SYMBOL vmlinux 0x76d79e4a unlock_rename +EXPORT_SYMBOL vmlinux 0x76de1690 netpoll_parse_options +EXPORT_SYMBOL vmlinux 0x76e770d7 get_fs_type +EXPORT_SYMBOL vmlinux 0x76f3f8a5 num_k8_northbridges +EXPORT_SYMBOL vmlinux 0x771ffb79 uart_resume_port +EXPORT_SYMBOL vmlinux 0x7736f5c6 ip_fragment +EXPORT_SYMBOL vmlinux 0x773f80aa get_sb_bdev +EXPORT_SYMBOL vmlinux 0x77489bd3 register_key_type +EXPORT_SYMBOL vmlinux 0x7772220d rfkill_switch_all +EXPORT_SYMBOL vmlinux 0x778ddaf5 qdisc_create_dflt +EXPORT_SYMBOL vmlinux 0x779144ee seq_open +EXPORT_SYMBOL vmlinux 0x77a108df _write_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x77c19ec7 ip6_route_output +EXPORT_SYMBOL vmlinux 0x77dc5172 kmem_cache_alloc +EXPORT_SYMBOL vmlinux 0x77e7b968 generic_file_buffered_write +EXPORT_SYMBOL vmlinux 0x77ecac9f zlib_inflateEnd +EXPORT_SYMBOL vmlinux 0x77f53abc acpi_get_vendor_resource +EXPORT_SYMBOL vmlinux 0x780585d6 udp_proc_unregister +EXPORT_SYMBOL vmlinux 0x782acba5 crc_t10dif +EXPORT_SYMBOL vmlinux 0x7833a29a generic_file_llseek_unlocked +EXPORT_SYMBOL vmlinux 0x78480718 dev_disable_lro +EXPORT_SYMBOL vmlinux 0x785148a3 idr_destroy +EXPORT_SYMBOL vmlinux 0x7854a4e6 scsi_host_alloc +EXPORT_SYMBOL vmlinux 0x785fe35c bio_alloc_bioset +EXPORT_SYMBOL vmlinux 0x789eb258 inet6_ioctl +EXPORT_SYMBOL vmlinux 0x78a484c9 _read_unlock_irqrestore +EXPORT_SYMBOL vmlinux 0x78a53baf bt_accept_enqueue +EXPORT_SYMBOL vmlinux 0x78df6bd7 no_pci_devices +EXPORT_SYMBOL vmlinux 0x793a1a91 submit_bio +EXPORT_SYMBOL vmlinux 0x796fc5ce scsi_get_sense_info_fld +EXPORT_SYMBOL vmlinux 0x79a6db31 arp_broken_ops +EXPORT_SYMBOL vmlinux 0x79aa04a2 get_random_bytes +EXPORT_SYMBOL vmlinux 0x79aa0a56 bdi_unregister +EXPORT_SYMBOL vmlinux 0x79d2d1cd page_follow_link_light +EXPORT_SYMBOL vmlinux 0x79d8fbaa pnp_unregister_driver +EXPORT_SYMBOL vmlinux 0x7a2a837d strict_strtol +EXPORT_SYMBOL vmlinux 0x7a505433 input_event +EXPORT_SYMBOL vmlinux 0x7a552743 sock_no_accept +EXPORT_SYMBOL vmlinux 0x7a56bba0 dev_unicast_unsync +EXPORT_SYMBOL vmlinux 0x7a79107e pci_remove_bus_device +EXPORT_SYMBOL vmlinux 0x7a79b72c proto_unregister +EXPORT_SYMBOL vmlinux 0x7a848702 _read_lock_irqsave +EXPORT_SYMBOL vmlinux 0x7a8565c6 call_usermodehelper_freeinfo +EXPORT_SYMBOL vmlinux 0x7a8b7885 mdio_bus_type +EXPORT_SYMBOL vmlinux 0x7a99e63f module_refcount +EXPORT_SYMBOL vmlinux 0x7ab6871d start_tty +EXPORT_SYMBOL vmlinux 0x7ac4c24b scsi_command_normalize_sense +EXPORT_SYMBOL vmlinux 0x7ae0c38c block_invalidatepage +EXPORT_SYMBOL vmlinux 0x7ae73de1 alloc_pages_exact +EXPORT_SYMBOL vmlinux 0x7aec9089 clear_user +EXPORT_SYMBOL vmlinux 0x7b0c84c4 acpi_remove_table_handler +EXPORT_SYMBOL vmlinux 0x7b244373 tcp_tso_segment +EXPORT_SYMBOL vmlinux 0x7b340536 dma_ops +EXPORT_SYMBOL vmlinux 0x7b4c16c6 get_sb_single +EXPORT_SYMBOL vmlinux 0x7b52a859 wrmsr_safe_on_cpu +EXPORT_SYMBOL vmlinux 0x7b572b1a nonseekable_open +EXPORT_SYMBOL vmlinux 0x7b5fc621 ip_ct_attach +EXPORT_SYMBOL vmlinux 0x7b5fd87f blk_put_request +EXPORT_SYMBOL vmlinux 0x7b743ed0 scsi_put_command +EXPORT_SYMBOL vmlinux 0x7b8f4c40 key_create_or_update +EXPORT_SYMBOL vmlinux 0x7bb376da tcp_mtup_init +EXPORT_SYMBOL vmlinux 0x7bc5ca03 acpi_processor_unregister_performance +EXPORT_SYMBOL vmlinux 0x7bcdfd33 i2c_smbus_read_byte_data +EXPORT_SYMBOL vmlinux 0x7bd4797d simple_rename +EXPORT_SYMBOL vmlinux 0x7bd75868 udplite_prot +EXPORT_SYMBOL vmlinux 0x7bdba91e scsi_print_result +EXPORT_SYMBOL vmlinux 0x7bec7200 acpi_bus_get_status +EXPORT_SYMBOL vmlinux 0x7bff3be7 iov_iter_advance +EXPORT_SYMBOL vmlinux 0x7c46233a cpufreq_quick_get +EXPORT_SYMBOL vmlinux 0x7c59da36 fb_validate_mode +EXPORT_SYMBOL vmlinux 0x7c60d66e getname +EXPORT_SYMBOL vmlinux 0x7c61340c __release_region +EXPORT_SYMBOL vmlinux 0x7c904ded unregister_module_notifier +EXPORT_SYMBOL vmlinux 0x7ca6a4c1 acpi_notifier_call_chain +EXPORT_SYMBOL vmlinux 0x7ca87216 pci_bus_type +EXPORT_SYMBOL vmlinux 0x7cb1ae69 cpu_down +EXPORT_SYMBOL vmlinux 0x7cbaef11 nobh_writepage +EXPORT_SYMBOL vmlinux 0x7cc5db64 dm_table_unplug_all +EXPORT_SYMBOL vmlinux 0x7ce13fec scsi_calculate_bounce_limit +EXPORT_SYMBOL vmlinux 0x7cf495f2 stop_tty +EXPORT_SYMBOL vmlinux 0x7d047e7e acpi_ut_exception +EXPORT_SYMBOL vmlinux 0x7d05d489 security_d_instantiate +EXPORT_SYMBOL vmlinux 0x7d11c268 jiffies +EXPORT_SYMBOL vmlinux 0x7d18ce10 serio_reconnect +EXPORT_SYMBOL vmlinux 0x7d2f2495 input_open_device +EXPORT_SYMBOL vmlinux 0x7d43021c input_register_handle +EXPORT_SYMBOL vmlinux 0x7d66c1ef blk_rq_map_user_iov +EXPORT_SYMBOL vmlinux 0x7d850612 utf8_mbstowcs +EXPORT_SYMBOL vmlinux 0x7d94f746 acpi_os_write_port +EXPORT_SYMBOL vmlinux 0x7dceceac capable +EXPORT_SYMBOL vmlinux 0x7df74779 simple_write_begin +EXPORT_SYMBOL vmlinux 0x7dfe6340 scsi_scan_target +EXPORT_SYMBOL vmlinux 0x7e2df88e read_cache_pages +EXPORT_SYMBOL vmlinux 0x7e8156c6 acpi_bus_generate_proc_event +EXPORT_SYMBOL vmlinux 0x7e9265e2 xfrm_dst_ifdown +EXPORT_SYMBOL vmlinux 0x7e9ebb05 kernel_thread +EXPORT_SYMBOL vmlinux 0x7eaac2e2 create_proc_entry +EXPORT_SYMBOL vmlinux 0x7ec9bfbc strncpy +EXPORT_SYMBOL vmlinux 0x7edef578 xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x7ee91c1d _spin_trylock +EXPORT_SYMBOL vmlinux 0x7f24de73 jiffies_to_usecs +EXPORT_SYMBOL vmlinux 0x7f8723bd pcie_mch_quirk +EXPORT_SYMBOL vmlinux 0x7fa250c3 poll_initwait +EXPORT_SYMBOL vmlinux 0x7ffc9624 __skb_recv_datagram +EXPORT_SYMBOL vmlinux 0x8050cf44 dev_alloc_name +EXPORT_SYMBOL vmlinux 0x806761d8 journal_restart +EXPORT_SYMBOL vmlinux 0x806a0baf dev_mc_add +EXPORT_SYMBOL vmlinux 0x808776c2 sync_page_range_nolock +EXPORT_SYMBOL vmlinux 0x80a56b6f tty_schedule_flip +EXPORT_SYMBOL vmlinux 0x80b2c800 blk_queue_start_tag +EXPORT_SYMBOL vmlinux 0x80b64773 ip6_frag_init +EXPORT_SYMBOL vmlinux 0x80f86851 __scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0x812037b1 tcp_rcv_established +EXPORT_SYMBOL vmlinux 0x8128f097 scsi_report_device_reset +EXPORT_SYMBOL vmlinux 0x81472677 acpi_get_table +EXPORT_SYMBOL vmlinux 0x814e7730 nf_ct_destroy +EXPORT_SYMBOL vmlinux 0x815b5dd4 match_octal +EXPORT_SYMBOL vmlinux 0x815f2897 empty_zero_page +EXPORT_SYMBOL vmlinux 0x81933aa4 mdiobus_read +EXPORT_SYMBOL vmlinux 0x819b65c7 agp_generic_mask_memory +EXPORT_SYMBOL vmlinux 0x81b24d48 find_or_create_page +EXPORT_SYMBOL vmlinux 0x81cd51e7 pci_find_slot +EXPORT_SYMBOL vmlinux 0x81e6b37f dmi_get_system_info +EXPORT_SYMBOL vmlinux 0x81ffc810 blk_remove_plug +EXPORT_SYMBOL vmlinux 0x82047b6d i2c_probe +EXPORT_SYMBOL vmlinux 0x82072614 tasklet_kill +EXPORT_SYMBOL vmlinux 0x820d225f print_mac +EXPORT_SYMBOL vmlinux 0x820d4867 d_lookup +EXPORT_SYMBOL vmlinux 0x824cccf2 user_path_at +EXPORT_SYMBOL vmlinux 0x8251bcc3 bitmap_release_region +EXPORT_SYMBOL vmlinux 0x82909a12 scsi_is_sdev_device +EXPORT_SYMBOL vmlinux 0x82def1c6 __neigh_for_each_release +EXPORT_SYMBOL vmlinux 0x82e6ab3a kmem_cache_destroy +EXPORT_SYMBOL vmlinux 0x82e9c083 csum_partial_copy_fromiovecend +EXPORT_SYMBOL vmlinux 0x82f65633 dm_io_client_resize +EXPORT_SYMBOL vmlinux 0x82f839ca netif_device_detach +EXPORT_SYMBOL vmlinux 0x830e547b ioremap_prot +EXPORT_SYMBOL vmlinux 0x8317e20a completion_done +EXPORT_SYMBOL vmlinux 0x83800bfa kref_init +EXPORT_SYMBOL vmlinux 0x83a476ce bitmap_scnlistprintf +EXPORT_SYMBOL vmlinux 0x83c53890 tty_flip_buffer_push +EXPORT_SYMBOL vmlinux 0x83ce0d01 kobject_del +EXPORT_SYMBOL vmlinux 0x83f5d309 acpi_lock_ac_dir +EXPORT_SYMBOL vmlinux 0x840a4206 dquot_free_space +EXPORT_SYMBOL vmlinux 0x84206846 dquot_mark_dquot_dirty +EXPORT_SYMBOL vmlinux 0x842d9e14 llc_add_pack +EXPORT_SYMBOL vmlinux 0x843e8958 __dec_zone_page_state +EXPORT_SYMBOL vmlinux 0x844a2183 nf_register_hooks +EXPORT_SYMBOL vmlinux 0x84bf0b77 blk_get_request +EXPORT_SYMBOL vmlinux 0x84d2a886 serio_close +EXPORT_SYMBOL vmlinux 0x84d7f055 gnet_stats_start_copy_compat +EXPORT_SYMBOL vmlinux 0x84e291ab try_to_release_page +EXPORT_SYMBOL vmlinux 0x852b2bbd sk_run_filter +EXPORT_SYMBOL vmlinux 0x85670f1d rtnl_is_locked +EXPORT_SYMBOL vmlinux 0x8584ea96 _cpu_pda +EXPORT_SYMBOL vmlinux 0x85abc85f strncmp +EXPORT_SYMBOL vmlinux 0x85c18861 bio_split +EXPORT_SYMBOL vmlinux 0x85df9b6c strsep +EXPORT_SYMBOL vmlinux 0x85edc595 request_firmware +EXPORT_SYMBOL vmlinux 0x863064fc vm_insert_pfn +EXPORT_SYMBOL vmlinux 0x8631f188 radix_tree_tag_set +EXPORT_SYMBOL vmlinux 0x863bd0ec alloc_fcdev +EXPORT_SYMBOL vmlinux 0x863cb91a utf8_wcstombs +EXPORT_SYMBOL vmlinux 0x863f8fdc pci_disable_device +EXPORT_SYMBOL vmlinux 0x8664f62e cpufreq_update_policy +EXPORT_SYMBOL vmlinux 0x866774fa __xfrm_lookup +EXPORT_SYMBOL vmlinux 0x866906df pci_fixup_device +EXPORT_SYMBOL vmlinux 0x86713cd3 keyring_clear +EXPORT_SYMBOL vmlinux 0x867d57e8 bio_integrity_prep +EXPORT_SYMBOL vmlinux 0x8680fc4a netdev_boot_setup_check +EXPORT_SYMBOL vmlinux 0x86894974 tty_driver_flush_buffer +EXPORT_SYMBOL vmlinux 0x868acba5 get_options +EXPORT_SYMBOL vmlinux 0x86bddbc3 generic_permission +EXPORT_SYMBOL vmlinux 0x86d4ab6f inet_csk_clear_xmit_timers +EXPORT_SYMBOL vmlinux 0x86fb9b05 bitmap_parse_user +EXPORT_SYMBOL vmlinux 0x86fdd5c5 sync_dirty_buffer +EXPORT_SYMBOL vmlinux 0x870e5a99 dev_unicast_delete +EXPORT_SYMBOL vmlinux 0x871c0a7e fiemap_check_flags +EXPORT_SYMBOL vmlinux 0x8733e9a3 sleep_on_timeout +EXPORT_SYMBOL vmlinux 0x876dafc3 ec_write +EXPORT_SYMBOL vmlinux 0x8785725d param_set_charp +EXPORT_SYMBOL vmlinux 0x878ab3ce sysctl_tcp_adv_win_scale +EXPORT_SYMBOL vmlinux 0x87b038a5 bdi_init +EXPORT_SYMBOL vmlinux 0x87b7e481 scsi_prep_state_check +EXPORT_SYMBOL vmlinux 0x87b7e9f6 inet6_bind +EXPORT_SYMBOL vmlinux 0x87dfe41f sock_no_getsockopt +EXPORT_SYMBOL vmlinux 0x87e2feac scsi_get_host_dev +EXPORT_SYMBOL vmlinux 0x87f978f3 scsi_test_unit_ready +EXPORT_SYMBOL vmlinux 0x881039d0 zlib_inflate +EXPORT_SYMBOL vmlinux 0x886ad577 blk_queue_max_sectors +EXPORT_SYMBOL vmlinux 0x8872d11c pnp_unregister_card_driver +EXPORT_SYMBOL vmlinux 0x8877494c ipv6_dev_get_saddr +EXPORT_SYMBOL vmlinux 0x889376f7 do_munmap +EXPORT_SYMBOL vmlinux 0x889d0bf9 mark_buffer_async_write +EXPORT_SYMBOL vmlinux 0x88b331a1 xfrm_state_update +EXPORT_SYMBOL vmlinux 0x88d31373 block_read_full_page +EXPORT_SYMBOL vmlinux 0x892469a9 unregister_exec_domain +EXPORT_SYMBOL vmlinux 0x892b26a0 set_memory_nx +EXPORT_SYMBOL vmlinux 0x8953bb27 del_timer +EXPORT_SYMBOL vmlinux 0x897473df mktime +EXPORT_SYMBOL vmlinux 0x898b1fec mutex_trylock +EXPORT_SYMBOL vmlinux 0x89949018 down_timeout +EXPORT_SYMBOL vmlinux 0x89b016fd pci_find_parent_resource +EXPORT_SYMBOL vmlinux 0x89be41e7 do_mmap_pgoff +EXPORT_SYMBOL vmlinux 0x89d5538d fb_pad_aligned_buffer +EXPORT_SYMBOL vmlinux 0x89d66811 build_ehash_secret +EXPORT_SYMBOL vmlinux 0x89e5f087 fget +EXPORT_SYMBOL vmlinux 0x89ea2e60 make_EII_client +EXPORT_SYMBOL vmlinux 0x8a0735c5 kernel_sock_shutdown +EXPORT_SYMBOL vmlinux 0x8a10cfd8 simple_dir_inode_operations +EXPORT_SYMBOL vmlinux 0x8a3eabf0 __wait_on_bit +EXPORT_SYMBOL vmlinux 0x8a7d1c31 high_memory +EXPORT_SYMBOL vmlinux 0x8a99a016 mempool_free_slab +EXPORT_SYMBOL vmlinux 0x8aaf8654 mutex_lock +EXPORT_SYMBOL vmlinux 0x8ac40297 iommu_area_free +EXPORT_SYMBOL vmlinux 0x8b1edb1d pci_set_consistent_dma_mask +EXPORT_SYMBOL vmlinux 0x8b35e873 sg_last +EXPORT_SYMBOL vmlinux 0x8b50bd1c udp_memory_allocated +EXPORT_SYMBOL vmlinux 0x8b57c981 input_set_keycode +EXPORT_SYMBOL vmlinux 0x8b59069d vfs_follow_link +EXPORT_SYMBOL vmlinux 0x8b618d08 overflowuid +EXPORT_SYMBOL vmlinux 0x8b6d8490 inode_init_once +EXPORT_SYMBOL vmlinux 0x8b7fe311 kmemdup +EXPORT_SYMBOL vmlinux 0x8b873394 tcp_child_process +EXPORT_SYMBOL vmlinux 0x8b89b245 security_sb_clone_mnt_opts +EXPORT_SYMBOL vmlinux 0x8b922c0f __strnlen_user +EXPORT_SYMBOL vmlinux 0x8b966b63 sn_rtc_cycles_per_second +EXPORT_SYMBOL vmlinux 0x8b989cf9 acpi_bus_can_wakeup +EXPORT_SYMBOL vmlinux 0x8ba82374 ps2_cmd_aborted +EXPORT_SYMBOL vmlinux 0x8bcbbda7 mod_zone_page_state +EXPORT_SYMBOL vmlinux 0x8be7c274 xfrm6_rcv +EXPORT_SYMBOL vmlinux 0x8c08b567 swiotlb_unmap_single +EXPORT_SYMBOL vmlinux 0x8c183cbe iowrite16 +EXPORT_SYMBOL vmlinux 0x8c519be9 dev_change_flags +EXPORT_SYMBOL vmlinux 0x8c7a10f6 pci_add_new_bus +EXPORT_SYMBOL vmlinux 0x8c87c243 kill_fasync +EXPORT_SYMBOL vmlinux 0x8c99c0cf register_console +EXPORT_SYMBOL vmlinux 0x8ca85385 block_truncate_page +EXPORT_SYMBOL vmlinux 0x8cc79cab iowrite16_rep +EXPORT_SYMBOL vmlinux 0x8cca283e icmpv6_send +EXPORT_SYMBOL vmlinux 0x8ced58a2 follow_up +EXPORT_SYMBOL vmlinux 0x8d0698d0 udp_ioctl +EXPORT_SYMBOL vmlinux 0x8d0d8d4a sock_no_socketpair +EXPORT_SYMBOL vmlinux 0x8d249a6e nf_hook_slow +EXPORT_SYMBOL vmlinux 0x8d3894f2 _ctype +EXPORT_SYMBOL vmlinux 0x8d446625 pv_cpu_ops +EXPORT_SYMBOL vmlinux 0x8d551bef sysctl_tcp_rmem +EXPORT_SYMBOL vmlinux 0x8d65e07b filemap_write_and_wait +EXPORT_SYMBOL vmlinux 0x8d8d96c6 acpi_get_sleep_type_data +EXPORT_SYMBOL vmlinux 0x8db066d5 nf_register_hook +EXPORT_SYMBOL vmlinux 0x8dca832f __percpu_counter_sum +EXPORT_SYMBOL vmlinux 0x8e002cda acpi_remove_gpe_block +EXPORT_SYMBOL vmlinux 0x8e0637ba i8253_lock +EXPORT_SYMBOL vmlinux 0x8e0b7743 ipv6_ext_hdr +EXPORT_SYMBOL vmlinux 0x8e3c9cc3 vprintk +EXPORT_SYMBOL vmlinux 0x8e46936e pci_enable_wake +EXPORT_SYMBOL vmlinux 0x8e48dbf8 netlink_dump_start +EXPORT_SYMBOL vmlinux 0x8e763ae1 send_remote_softirq +EXPORT_SYMBOL vmlinux 0x8eafe5be atm_charge +EXPORT_SYMBOL vmlinux 0x8ec7f377 register_sysctl_paths +EXPORT_SYMBOL vmlinux 0x8f1ae4c9 pcim_iounmap +EXPORT_SYMBOL vmlinux 0x8f3046d2 journal_invalidatepage +EXPORT_SYMBOL vmlinux 0x8f37d3a6 acpi_bus_register_driver +EXPORT_SYMBOL vmlinux 0x8f4b4e4e remap_vmalloc_range +EXPORT_SYMBOL vmlinux 0x8f4fe587 scsi_device_get +EXPORT_SYMBOL vmlinux 0x8f6b7950 set_irq_data +EXPORT_SYMBOL vmlinux 0x8f73ef50 blk_free_tags +EXPORT_SYMBOL vmlinux 0x8f7d81f1 task_pid_nr_ns +EXPORT_SYMBOL vmlinux 0x8f8d78ec mdiobus_unregister +EXPORT_SYMBOL vmlinux 0x8f9c199c __get_user_2 +EXPORT_SYMBOL vmlinux 0x8f9f6fb3 vc_resize +EXPORT_SYMBOL vmlinux 0x8fad5bd5 bfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0x8fb7e07a dev_add_pack +EXPORT_SYMBOL vmlinux 0x8fc33ffd sock_i_uid +EXPORT_SYMBOL vmlinux 0x8ff327dd agp_free_page_array +EXPORT_SYMBOL vmlinux 0x8ff5f7c6 ipv6_setsockopt +EXPORT_SYMBOL vmlinux 0x8ffbe5e9 remap_pfn_range +EXPORT_SYMBOL vmlinux 0x90022b44 xfrm_policy_flush +EXPORT_SYMBOL vmlinux 0x90035333 secure_tcpv6_sequence_number +EXPORT_SYMBOL vmlinux 0x90758194 audit_log_end +EXPORT_SYMBOL vmlinux 0x90835f33 seq_release +EXPORT_SYMBOL vmlinux 0x90a1601f dmi_check_system +EXPORT_SYMBOL vmlinux 0x90a6af3e xfrm_state_register_afinfo +EXPORT_SYMBOL vmlinux 0x90a943ba nmi_active +EXPORT_SYMBOL vmlinux 0x90dfea22 dma_async_client_register +EXPORT_SYMBOL vmlinux 0x90e8c307 tty_free_termios +EXPORT_SYMBOL vmlinux 0x910ad3ff rtnetlink_put_metrics +EXPORT_SYMBOL vmlinux 0x91297586 journal_clear_err +EXPORT_SYMBOL vmlinux 0x9134d476 bio_integrity_endio +EXPORT_SYMBOL vmlinux 0x9144a8e2 ec_burst_disable +EXPORT_SYMBOL vmlinux 0x91481982 __ratelimit +EXPORT_SYMBOL vmlinux 0x91607d95 set_memory_wb +EXPORT_SYMBOL vmlinux 0x9161de6b do_sync_read +EXPORT_SYMBOL vmlinux 0x9163ef23 nla_put_nohdr +EXPORT_SYMBOL vmlinux 0x916789a2 dquot_free_inode +EXPORT_SYMBOL vmlinux 0x9187d7ad dcache_readdir +EXPORT_SYMBOL vmlinux 0x91890811 tcp_v4_connect +EXPORT_SYMBOL vmlinux 0x919b7497 dump_trace +EXPORT_SYMBOL vmlinux 0x91a273fa blk_init_queue +EXPORT_SYMBOL vmlinux 0x91b0dee2 fasync_helper +EXPORT_SYMBOL vmlinux 0x91ca8959 acpi_get_register +EXPORT_SYMBOL vmlinux 0x91d08bcd __skb_checksum_complete_head +EXPORT_SYMBOL vmlinux 0x91d3b820 sg_miter_next +EXPORT_SYMBOL vmlinux 0x920dd64a __insert_inode_hash +EXPORT_SYMBOL vmlinux 0x92304ab9 iget5_locked +EXPORT_SYMBOL vmlinux 0x92390758 phy_disconnect +EXPORT_SYMBOL vmlinux 0x92392cd9 iov_shorten +EXPORT_SYMBOL vmlinux 0x923a626d simple_release_fs +EXPORT_SYMBOL vmlinux 0x92755c43 alloc_file +EXPORT_SYMBOL vmlinux 0x927cbb1e skb_trim +EXPORT_SYMBOL vmlinux 0x927e989f gen_pool_alloc +EXPORT_SYMBOL vmlinux 0x92856b3d vlan_ioctl_set +EXPORT_SYMBOL vmlinux 0x92d701b6 dquot_acquire +EXPORT_SYMBOL vmlinux 0x92ea4ae4 crc32_le +EXPORT_SYMBOL vmlinux 0x92f66d19 neigh_connected_output +EXPORT_SYMBOL vmlinux 0x930315a4 __seq_open_private +EXPORT_SYMBOL vmlinux 0x9305f8e6 cpufreq_get +EXPORT_SYMBOL vmlinux 0x9312c9c5 bio_integrity_add_page +EXPORT_SYMBOL vmlinux 0x933b222e __mark_inode_dirty +EXPORT_SYMBOL vmlinux 0x9341eb90 dget_locked +EXPORT_SYMBOL vmlinux 0x934d565d tcf_exts_dump_stats +EXPORT_SYMBOL vmlinux 0x9357c5c9 sock_kmalloc +EXPORT_SYMBOL vmlinux 0x936417c3 ethtool_op_get_sg +EXPORT_SYMBOL vmlinux 0x9384cb13 file_update_time +EXPORT_SYMBOL vmlinux 0x93850b28 init_net +EXPORT_SYMBOL vmlinux 0x93886409 dev_kfree_skb_irq +EXPORT_SYMBOL vmlinux 0x93a6e0b2 io_schedule +EXPORT_SYMBOL vmlinux 0x93afa72e vm_get_page_prot +EXPORT_SYMBOL vmlinux 0x93b8ef56 mutex_lock_interruptible +EXPORT_SYMBOL vmlinux 0x93c69acf param_set_byte +EXPORT_SYMBOL vmlinux 0x93cbd1ec _spin_lock_bh +EXPORT_SYMBOL vmlinux 0x93d7cb85 __fatal_signal_pending +EXPORT_SYMBOL vmlinux 0x93ed6a1b mem_section +EXPORT_SYMBOL vmlinux 0x93fca811 __get_free_pages +EXPORT_SYMBOL vmlinux 0x9428750c skb_copy_bits +EXPORT_SYMBOL vmlinux 0x943e868f ida_get_new +EXPORT_SYMBOL vmlinux 0x945bc6a7 copy_from_user +EXPORT_SYMBOL vmlinux 0x94883ab2 gnet_stats_copy_rate_est +EXPORT_SYMBOL vmlinux 0x94961283 vunmap +EXPORT_SYMBOL vmlinux 0x949e7c75 phy_register_fixup_for_id +EXPORT_SYMBOL vmlinux 0x94e3cf88 igrab +EXPORT_SYMBOL vmlinux 0x94fcf08e bioset_create +EXPORT_SYMBOL vmlinux 0x952cd34f jbd2_journal_force_commit +EXPORT_SYMBOL vmlinux 0x95352ea9 acpi_check_mem_region +EXPORT_SYMBOL vmlinux 0x954445ad hci_register_proto +EXPORT_SYMBOL vmlinux 0x954488a4 syncookie_secret +EXPORT_SYMBOL vmlinux 0x9545af6d tasklet_init +EXPORT_SYMBOL vmlinux 0x954c8af3 dm_io_client_destroy +EXPORT_SYMBOL vmlinux 0x954cbb26 vsprintf +EXPORT_SYMBOL vmlinux 0x9552bc9a netdev_class_create_file +EXPORT_SYMBOL vmlinux 0x9561cace udp_sendmsg +EXPORT_SYMBOL vmlinux 0x95ceb864 key_update +EXPORT_SYMBOL vmlinux 0x95dd999a gnet_stats_finish_copy +EXPORT_SYMBOL vmlinux 0x96066cc6 swiotlb_dma_mapping_error +EXPORT_SYMBOL vmlinux 0x960e010f scsi_device_quiesce +EXPORT_SYMBOL vmlinux 0x9642740d tcf_em_tree_destroy +EXPORT_SYMBOL vmlinux 0x96481cc7 per_cpu__x86_cpu_to_apicid +EXPORT_SYMBOL vmlinux 0x9675a809 uart_suspend_port +EXPORT_SYMBOL vmlinux 0x96b2039f qdisc_class_hash_grow +EXPORT_SYMBOL vmlinux 0x96b67592 dquot_alloc_space +EXPORT_SYMBOL vmlinux 0x96cd2b04 scsi_sense_key_string +EXPORT_SYMBOL vmlinux 0x96dc7576 default_unplug_io_fn +EXPORT_SYMBOL vmlinux 0x96f33400 up_read +EXPORT_SYMBOL vmlinux 0x973873ab _spin_lock +EXPORT_SYMBOL vmlinux 0x97518060 inode_sub_bytes +EXPORT_SYMBOL vmlinux 0x9754ec10 radix_tree_preload +EXPORT_SYMBOL vmlinux 0x977fc100 nlmsg_notify +EXPORT_SYMBOL vmlinux 0x9782442e agp_enable +EXPORT_SYMBOL vmlinux 0x97a073fd netlink_broadcast +EXPORT_SYMBOL vmlinux 0x97a4768e neigh_for_each +EXPORT_SYMBOL vmlinux 0x97be1693 ht_create_irq +EXPORT_SYMBOL vmlinux 0x97c5c874 unmap_mapping_range +EXPORT_SYMBOL vmlinux 0x97cc5076 i2c_detach_client +EXPORT_SYMBOL vmlinux 0x97de0ddd acpi_install_gpe_block +EXPORT_SYMBOL vmlinux 0x980eae57 mpage_readpages +EXPORT_SYMBOL vmlinux 0x9836a2b0 page_symlink_inode_operations +EXPORT_SYMBOL vmlinux 0x9839449c load_nls +EXPORT_SYMBOL vmlinux 0x984138d7 __dev_remove_pack +EXPORT_SYMBOL vmlinux 0x986e6135 fb_pad_unaligned_buffer +EXPORT_SYMBOL vmlinux 0x988ed85d set_memory_x +EXPORT_SYMBOL vmlinux 0x98ca299b blk_queue_segment_boundary +EXPORT_SYMBOL vmlinux 0x98e02636 generic_setlease +EXPORT_SYMBOL vmlinux 0x98e5f680 __devm_release_region +EXPORT_SYMBOL vmlinux 0x9906f3c2 tty_vhangup +EXPORT_SYMBOL vmlinux 0x9978b36e bd_set_size +EXPORT_SYMBOL vmlinux 0x9994c0ca ps2_is_keyboard_id +EXPORT_SYMBOL vmlinux 0x9996b654 skb_abort_seq_read +EXPORT_SYMBOL vmlinux 0x999c3fd1 hci_send_sco +EXPORT_SYMBOL vmlinux 0x999e8297 vfree +EXPORT_SYMBOL vmlinux 0x99a75ec9 lookup_bdev +EXPORT_SYMBOL vmlinux 0x99aadb21 param_get_ulong +EXPORT_SYMBOL vmlinux 0x99b9e975 dma_async_memcpy_buf_to_pg +EXPORT_SYMBOL vmlinux 0x99bfbe39 get_unused_fd +EXPORT_SYMBOL vmlinux 0x99cdc86b sysctl_tcp_reordering +EXPORT_SYMBOL vmlinux 0x99d93be4 proc_doulongvec_ms_jiffies_minmax +EXPORT_SYMBOL vmlinux 0x99ea12ce panic_blink +EXPORT_SYMBOL vmlinux 0x9a13b31b __rta_fill +EXPORT_SYMBOL vmlinux 0x9a1dfd65 strpbrk +EXPORT_SYMBOL vmlinux 0x9a2b0c3f thaw_bdev +EXPORT_SYMBOL vmlinux 0x9a2c8195 tcf_hash_search +EXPORT_SYMBOL vmlinux 0x9a2d04e3 d_prune_aliases +EXPORT_SYMBOL vmlinux 0x9a3bdcb7 sock_wfree +EXPORT_SYMBOL vmlinux 0x9a3c4f55 qdisc_tree_decrease_qlen +EXPORT_SYMBOL vmlinux 0x9a6eb5ba per_cpu__cpu_core_map +EXPORT_SYMBOL vmlinux 0x9a807877 mmc_unregister_driver +EXPORT_SYMBOL vmlinux 0x9a92cb2e pci_pme_active +EXPORT_SYMBOL vmlinux 0x9a9985be percpu_counter_destroy +EXPORT_SYMBOL vmlinux 0x9aabc564 crc16 +EXPORT_SYMBOL vmlinux 0x9abe1988 page_symlink +EXPORT_SYMBOL vmlinux 0x9ad1c6db tty_register_device +EXPORT_SYMBOL vmlinux 0x9ae526c4 sockfd_lookup +EXPORT_SYMBOL vmlinux 0x9aecd4b1 pci_release_regions +EXPORT_SYMBOL vmlinux 0x9b388444 get_zeroed_page +EXPORT_SYMBOL vmlinux 0x9b44582e posix_lock_file +EXPORT_SYMBOL vmlinux 0x9b492f6e bio_put +EXPORT_SYMBOL vmlinux 0x9b579600 audit_log_format +EXPORT_SYMBOL vmlinux 0x9b6408d6 gnet_stats_start_copy +EXPORT_SYMBOL vmlinux 0x9b897111 is_bad_inode +EXPORT_SYMBOL vmlinux 0x9b962abf nf_unregister_hook +EXPORT_SYMBOL vmlinux 0x9ba7089d argv_split +EXPORT_SYMBOL vmlinux 0x9bc565c5 memcpy_fromiovecend +EXPORT_SYMBOL vmlinux 0x9bc8c39b journal_destroy +EXPORT_SYMBOL vmlinux 0x9bcf1979 elv_rb_former_request +EXPORT_SYMBOL vmlinux 0x9bfc92de __xfrm_state_delete +EXPORT_SYMBOL vmlinux 0x9c012508 fb_parse_edid +EXPORT_SYMBOL vmlinux 0x9c028b08 aio_complete +EXPORT_SYMBOL vmlinux 0x9c0362d6 xfrm6_find_1stfragopt +EXPORT_SYMBOL vmlinux 0x9c0ea3cd memscan +EXPORT_SYMBOL vmlinux 0x9c1f2afd ll_rw_block +EXPORT_SYMBOL vmlinux 0x9c23ee7f dm_get_device +EXPORT_SYMBOL vmlinux 0x9c491f60 sg_alloc_table +EXPORT_SYMBOL vmlinux 0x9c5b3050 blk_queue_bounce +EXPORT_SYMBOL vmlinux 0x9c8648cf pci_select_bars +EXPORT_SYMBOL vmlinux 0x9c87939a d_splice_alias +EXPORT_SYMBOL vmlinux 0x9c9048d7 rtnl_create_link +EXPORT_SYMBOL vmlinux 0x9c94c107 nobh_write_end +EXPORT_SYMBOL vmlinux 0x9ca9043d tty_wait_until_sent +EXPORT_SYMBOL vmlinux 0x9ca95a0e sort +EXPORT_SYMBOL vmlinux 0x9cb96e92 qdisc_put_rtab +EXPORT_SYMBOL vmlinux 0x9ccb2622 finish_wait +EXPORT_SYMBOL vmlinux 0x9ced38aa down_trylock +EXPORT_SYMBOL vmlinux 0x9cfd56c5 scsi_print_status +EXPORT_SYMBOL vmlinux 0x9d016b53 vfs_rename +EXPORT_SYMBOL vmlinux 0x9d33ef5e acpi_enable +EXPORT_SYMBOL vmlinux 0x9d5f8d51 read_cache_page_async +EXPORT_SYMBOL vmlinux 0x9d711f1f percpu_counter_init +EXPORT_SYMBOL vmlinux 0x9db21624 hex_dump_to_buffer +EXPORT_SYMBOL vmlinux 0x9dfb5072 vfs_mkdir +EXPORT_SYMBOL vmlinux 0x9e01e590 blk_verify_command +EXPORT_SYMBOL vmlinux 0x9e200ead generic_file_llseek +EXPORT_SYMBOL vmlinux 0x9e2d2184 llc_sap_find +EXPORT_SYMBOL vmlinux 0x9e363b6b acpi_disable_gpe +EXPORT_SYMBOL vmlinux 0x9e64fbfe rtc_cmos_read +EXPORT_SYMBOL vmlinux 0x9e7d6bd0 __udelay +EXPORT_SYMBOL vmlinux 0x9ea0ad49 __sg_free_table +EXPORT_SYMBOL vmlinux 0x9ea28ec7 acpi_evaluate_object +EXPORT_SYMBOL vmlinux 0x9ea85063 ipv6_push_nfrag_opts +EXPORT_SYMBOL vmlinux 0x9ebd4c04 adjust_resource +EXPORT_SYMBOL vmlinux 0x9edbecae snprintf +EXPORT_SYMBOL vmlinux 0x9ee91b1a hippi_type_trans +EXPORT_SYMBOL vmlinux 0x9eecde16 do_brk +EXPORT_SYMBOL vmlinux 0x9ef749e2 unregister_chrdev +EXPORT_SYMBOL vmlinux 0x9f100139 jiffies_to_clock_t +EXPORT_SYMBOL vmlinux 0x9f1fdf0f revalidate_disk +EXPORT_SYMBOL vmlinux 0x9f210879 sysctl_jiffies +EXPORT_SYMBOL vmlinux 0x9f2bdaac __bitmap_or +EXPORT_SYMBOL vmlinux 0x9f44e800 dm_table_get_md +EXPORT_SYMBOL vmlinux 0x9f46b01d mb_cache_entry_free +EXPORT_SYMBOL vmlinux 0x9f6b6587 inet_frags_exit_net +EXPORT_SYMBOL vmlinux 0x9f890637 ip_mc_inc_group +EXPORT_SYMBOL vmlinux 0x9f984513 strrchr +EXPORT_SYMBOL vmlinux 0x9fa274b4 dq_data_lock +EXPORT_SYMBOL vmlinux 0x9feaf287 sonet_subtract_stats +EXPORT_SYMBOL vmlinux 0x9ff70bdb call_usermodehelper_stdinpipe +EXPORT_SYMBOL vmlinux 0xa03523d5 security_unix_stream_connect +EXPORT_SYMBOL vmlinux 0xa04a01bd qdisc_class_hash_insert +EXPORT_SYMBOL vmlinux 0xa05c03df mempool_kmalloc +EXPORT_SYMBOL vmlinux 0xa077e376 tcf_hash_create +EXPORT_SYMBOL vmlinux 0xa07fad56 inode_add_bytes +EXPORT_SYMBOL vmlinux 0xa09b497b inet6_del_protocol +EXPORT_SYMBOL vmlinux 0xa0a16651 vm_insert_mixed +EXPORT_SYMBOL vmlinux 0xa0a59547 vfs_link +EXPORT_SYMBOL vmlinux 0xa0a5d4eb alloc_etherdev_mq +EXPORT_SYMBOL vmlinux 0xa0b04675 vmalloc_32 +EXPORT_SYMBOL vmlinux 0xa0ceef51 out_of_line_wait_on_bit +EXPORT_SYMBOL vmlinux 0xa0fbac79 wake_up_bit +EXPORT_SYMBOL vmlinux 0xa108eb4d sysctl_optmem_max +EXPORT_SYMBOL vmlinux 0xa10d22cb contig_page_data +EXPORT_SYMBOL vmlinux 0xa10dcc13 getrawmonotonic +EXPORT_SYMBOL vmlinux 0xa120d33c tty_unregister_ldisc +EXPORT_SYMBOL vmlinux 0xa133538e generic_unplug_device +EXPORT_SYMBOL vmlinux 0xa1371257 sock_sendmsg +EXPORT_SYMBOL vmlinux 0xa13798f8 printk_ratelimit +EXPORT_SYMBOL vmlinux 0xa13aecfc cpufreq_get_policy +EXPORT_SYMBOL vmlinux 0xa14a5135 journal_force_commit_nested +EXPORT_SYMBOL vmlinux 0xa16d2fb8 elv_rb_latter_request +EXPORT_SYMBOL vmlinux 0xa1862c7d mb_cache_entry_alloc +EXPORT_SYMBOL vmlinux 0xa1a7cf0e sock_common_recvmsg +EXPORT_SYMBOL vmlinux 0xa1aeec23 netlink_kernel_create +EXPORT_SYMBOL vmlinux 0xa1b759ce fb_add_videomode +EXPORT_SYMBOL vmlinux 0xa1b7d706 arp_send +EXPORT_SYMBOL vmlinux 0xa1bcc850 ps2_sendbyte +EXPORT_SYMBOL vmlinux 0xa1c0117b console_start +EXPORT_SYMBOL vmlinux 0xa1c76e0a _cond_resched +EXPORT_SYMBOL vmlinux 0xa1f4cd89 devm_iounmap +EXPORT_SYMBOL vmlinux 0xa1fd1ec9 write_cache_pages +EXPORT_SYMBOL vmlinux 0xa20ce1b8 net_msg_warn +EXPORT_SYMBOL vmlinux 0xa230751c blk_queue_ordered +EXPORT_SYMBOL vmlinux 0xa23fa523 wireless_spy_update +EXPORT_SYMBOL vmlinux 0xa261b90c scsi_init_io +EXPORT_SYMBOL vmlinux 0xa285db3e swiotlb_map_sg +EXPORT_SYMBOL vmlinux 0xa28dc9cf block_write_begin +EXPORT_SYMBOL vmlinux 0xa2a1e5c9 _write_lock_bh +EXPORT_SYMBOL vmlinux 0xa2a5fd77 inet_ehash_secret +EXPORT_SYMBOL vmlinux 0xa2c294a3 misc_deregister +EXPORT_SYMBOL vmlinux 0xa2cfa0db alloc_hippi_dev +EXPORT_SYMBOL vmlinux 0xa2e73912 tty_devnum +EXPORT_SYMBOL vmlinux 0xa2eb9d1d jbd2_journal_get_write_access +EXPORT_SYMBOL vmlinux 0xa2f03981 rtnl_set_sk_err +EXPORT_SYMBOL vmlinux 0xa31f172d __copy_from_user_inatomic +EXPORT_SYMBOL vmlinux 0xa329f07e register_shrinker +EXPORT_SYMBOL vmlinux 0xa32b0139 skb_insert +EXPORT_SYMBOL vmlinux 0xa32da8ad sk_common_release +EXPORT_SYMBOL vmlinux 0xa337507f update_region +EXPORT_SYMBOL vmlinux 0xa33d8da9 agp_alloc_page_array +EXPORT_SYMBOL vmlinux 0xa33f7c7c nla_strlcpy +EXPORT_SYMBOL vmlinux 0xa34cabc1 sock_no_ioctl +EXPORT_SYMBOL vmlinux 0xa350a8f8 set_memory_array_uc +EXPORT_SYMBOL vmlinux 0xa35de80f ipv4_config +EXPORT_SYMBOL vmlinux 0xa3677d9c vfs_get_dqinfo +EXPORT_SYMBOL vmlinux 0xa3a5be95 memmove +EXPORT_SYMBOL vmlinux 0xa3ad38d1 secpath_dup +EXPORT_SYMBOL vmlinux 0xa3b6cfdc pci_bus_write_config_dword +EXPORT_SYMBOL vmlinux 0xa3bbcd80 acpi_set_gpe_type +EXPORT_SYMBOL vmlinux 0xa3e79752 d_alloc_root +EXPORT_SYMBOL vmlinux 0xa3f8d47c bio_sector_offset +EXPORT_SYMBOL vmlinux 0xa424ad44 i2c_master_send +EXPORT_SYMBOL vmlinux 0xa4295360 textsearch_unregister +EXPORT_SYMBOL vmlinux 0xa44072fc posix_acl_alloc +EXPORT_SYMBOL vmlinux 0xa44ad274 wait_for_completion_interruptible_timeout +EXPORT_SYMBOL vmlinux 0xa46b4aa4 hci_resume_dev +EXPORT_SYMBOL vmlinux 0xa4b94fea iowrite8_rep +EXPORT_SYMBOL vmlinux 0xa4bae13d grab_cache_page_nowait +EXPORT_SYMBOL vmlinux 0xa4d4f0e6 global_cache_flush +EXPORT_SYMBOL vmlinux 0xa4df1151 kref_set +EXPORT_SYMBOL vmlinux 0xa4fb0631 bio_alloc +EXPORT_SYMBOL vmlinux 0xa506d10a kobject_init +EXPORT_SYMBOL vmlinux 0xa5114b0b pcie_port_service_register +EXPORT_SYMBOL vmlinux 0xa5239fde input_close_device +EXPORT_SYMBOL vmlinux 0xa523d30b inet_csk_destroy_sock +EXPORT_SYMBOL vmlinux 0xa5423cc4 param_get_int +EXPORT_SYMBOL vmlinux 0xa562e74b dec_zone_page_state +EXPORT_SYMBOL vmlinux 0xa5693df7 posix_acl_clone +EXPORT_SYMBOL vmlinux 0xa56f1315 mempool_free +EXPORT_SYMBOL vmlinux 0xa5739e8e set_device_ro +EXPORT_SYMBOL vmlinux 0xa5838f6b neigh_lookup_nodev +EXPORT_SYMBOL vmlinux 0xa58b6804 nla_parse +EXPORT_SYMBOL vmlinux 0xa5922bb1 kfifo_init +EXPORT_SYMBOL vmlinux 0xa5962225 fsync_bdev +EXPORT_SYMBOL vmlinux 0xa598e29c vesa_modes +EXPORT_SYMBOL vmlinux 0xa59aa051 blk_queue_bounce_limit +EXPORT_SYMBOL vmlinux 0xa5adbe8c ida_destroy +EXPORT_SYMBOL vmlinux 0xa5c4a043 kill_block_super +EXPORT_SYMBOL vmlinux 0xa613f372 xfrm_user_policy +EXPORT_SYMBOL vmlinux 0xa61e9a53 tcf_em_tree_dump +EXPORT_SYMBOL vmlinux 0xa63d85ab slhc_remember +EXPORT_SYMBOL vmlinux 0xa6484eae smp_call_function_mask +EXPORT_SYMBOL vmlinux 0xa68124fa hweight8 +EXPORT_SYMBOL vmlinux 0xa681fe88 generate_random_uuid +EXPORT_SYMBOL vmlinux 0xa68de2b8 tty_port_alloc_xmit_buf +EXPORT_SYMBOL vmlinux 0xa6dcc773 rb_insert_color +EXPORT_SYMBOL vmlinux 0xa6e0fa68 k8_northbridges +EXPORT_SYMBOL vmlinux 0xa70fabbe release_evntsel_nmi +EXPORT_SYMBOL vmlinux 0xa71b5aac generic_show_options +EXPORT_SYMBOL vmlinux 0xa72ac454 ip_getsockopt +EXPORT_SYMBOL vmlinux 0xa7502f48 jiffies_to_timeval +EXPORT_SYMBOL vmlinux 0xa79850e9 bio_add_page +EXPORT_SYMBOL vmlinux 0xa7c35c6b getnstimeofday +EXPORT_SYMBOL vmlinux 0xa7c78b2a __starget_for_each_device +EXPORT_SYMBOL vmlinux 0xa7e89a4e sock_no_shutdown +EXPORT_SYMBOL vmlinux 0xa7f3c5d1 ps2_handle_ack +EXPORT_SYMBOL vmlinux 0xa7ff79e2 d_delete +EXPORT_SYMBOL vmlinux 0xa8026c53 sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xa806bd71 jbd2_journal_load +EXPORT_SYMBOL vmlinux 0xa816c525 schedule_work_on +EXPORT_SYMBOL vmlinux 0xa822dae7 down_read +EXPORT_SYMBOL vmlinux 0xa827f4e5 vcc_release_async +EXPORT_SYMBOL vmlinux 0xa82a0d6d pci_try_set_mwi +EXPORT_SYMBOL vmlinux 0xa83fcb38 input_set_capability +EXPORT_SYMBOL vmlinux 0xa8551679 tty_kref_put +EXPORT_SYMBOL vmlinux 0xa85c2b0a netdev_features_change +EXPORT_SYMBOL vmlinux 0xa8691c45 skb_unlink +EXPORT_SYMBOL vmlinux 0xa886a958 krealloc +EXPORT_SYMBOL vmlinux 0xa8901e14 generic_block_bmap +EXPORT_SYMBOL vmlinux 0xa89600ea set_page_dirty_lock +EXPORT_SYMBOL vmlinux 0xa8a6f639 __check_region +EXPORT_SYMBOL vmlinux 0xa8accb43 mark_page_accessed +EXPORT_SYMBOL vmlinux 0xa8bb9b14 tcp_proc_unregister +EXPORT_SYMBOL vmlinux 0xa8c5b1e6 audit_log_start +EXPORT_SYMBOL vmlinux 0xa8c64c4b journal_update_format +EXPORT_SYMBOL vmlinux 0xa8dcedce I_BDEV +EXPORT_SYMBOL vmlinux 0xa8f27f9d simple_empty +EXPORT_SYMBOL vmlinux 0xa8fbf582 idr_replace +EXPORT_SYMBOL vmlinux 0xa8fef7bb security_unix_may_send +EXPORT_SYMBOL vmlinux 0xa91b5561 acpi_video_backlight_support +EXPORT_SYMBOL vmlinux 0xa925899a param_set_bool +EXPORT_SYMBOL vmlinux 0xa951c6a8 generic_make_request +EXPORT_SYMBOL vmlinux 0xa97233c1 skb_kill_datagram +EXPORT_SYMBOL vmlinux 0xa9854ce1 skb_realloc_headroom +EXPORT_SYMBOL vmlinux 0xa991e09a tty_driver_kref_put +EXPORT_SYMBOL vmlinux 0xa9b74a53 xfrm_state_alloc +EXPORT_SYMBOL vmlinux 0xa9c622c0 tcp_md5_hash_header +EXPORT_SYMBOL vmlinux 0xa9e56605 set_irq_chip +EXPORT_SYMBOL vmlinux 0xa9fcf31d wait_for_completion_interruptible +EXPORT_SYMBOL vmlinux 0xaa024146 sonet_copy_stats +EXPORT_SYMBOL vmlinux 0xaa0a6292 blk_run_queue +EXPORT_SYMBOL vmlinux 0xaa53ad6b blk_queue_max_segment_size +EXPORT_SYMBOL vmlinux 0xaa6cbd87 locks_mandatory_area +EXPORT_SYMBOL vmlinux 0xaa84a8ae acpi_processor_power_init_bm_check +EXPORT_SYMBOL vmlinux 0xaa89b982 i2c_smbus_read_block_data +EXPORT_SYMBOL vmlinux 0xaa8ab19e cpu_online_map +EXPORT_SYMBOL vmlinux 0xaab06af8 _write_lock_irqsave +EXPORT_SYMBOL vmlinux 0xaab41f64 pnp_possible_config +EXPORT_SYMBOL vmlinux 0xaae8ab0e acpi_bus_power_manageable +EXPORT_SYMBOL vmlinux 0xaafdc258 strcasecmp +EXPORT_SYMBOL vmlinux 0xaaffb9a5 acpi_bus_private_data_handler +EXPORT_SYMBOL vmlinux 0xab1fb136 input_allocate_device +EXPORT_SYMBOL vmlinux 0xab471003 param_array_set +EXPORT_SYMBOL vmlinux 0xab600421 probe_irq_off +EXPORT_SYMBOL vmlinux 0xab62d741 notify_change +EXPORT_SYMBOL vmlinux 0xab65ed80 set_memory_uc +EXPORT_SYMBOL vmlinux 0xab6da3aa input_grab_device +EXPORT_SYMBOL vmlinux 0xab95e164 vfs_write +EXPORT_SYMBOL vmlinux 0xaba9ff34 allocate_resource +EXPORT_SYMBOL vmlinux 0xabd0c91c rtc_time_to_tm +EXPORT_SYMBOL vmlinux 0xabe85a21 idr_init +EXPORT_SYMBOL vmlinux 0xac074eee lock_super +EXPORT_SYMBOL vmlinux 0xac0bbfa8 _proxy_pda +EXPORT_SYMBOL vmlinux 0xac235b9e pci_get_device +EXPORT_SYMBOL vmlinux 0xac383451 radix_tree_tag_clear +EXPORT_SYMBOL vmlinux 0xac3b3cee __bitmap_and +EXPORT_SYMBOL vmlinux 0xac43c36b deny_write_access +EXPORT_SYMBOL vmlinux 0xac473d80 open_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xac4ea2d6 ioctl_by_bdev +EXPORT_SYMBOL vmlinux 0xac522c8f elv_add_request +EXPORT_SYMBOL vmlinux 0xac58ea5e acpi_unload_table_id +EXPORT_SYMBOL vmlinux 0xac76e2c2 scsi_prep_return +EXPORT_SYMBOL vmlinux 0xac770feb filemap_fault +EXPORT_SYMBOL vmlinux 0xaca16bc0 xfrm4_rcv_encap +EXPORT_SYMBOL vmlinux 0xaccabc6a in4_pton +EXPORT_SYMBOL vmlinux 0xacf4d843 match_strdup +EXPORT_SYMBOL vmlinux 0xacf538f3 unregister_filesystem +EXPORT_SYMBOL vmlinux 0xad0413d4 match_hex +EXPORT_SYMBOL vmlinux 0xad13c689 acpi_os_execute +EXPORT_SYMBOL vmlinux 0xad18330f force_sig +EXPORT_SYMBOL vmlinux 0xad2531da blk_execute_rq +EXPORT_SYMBOL vmlinux 0xad25fb12 __memcpy +EXPORT_SYMBOL vmlinux 0xad43d100 kernel_connect +EXPORT_SYMBOL vmlinux 0xad68b2a1 udp_flush_pending_frames +EXPORT_SYMBOL vmlinux 0xad8de1b3 acpi_remove_address_space_handler +EXPORT_SYMBOL vmlinux 0xad93331a qdisc_watchdog_schedule +EXPORT_SYMBOL vmlinux 0xad960b6f dst_destroy +EXPORT_SYMBOL vmlinux 0xadaa2657 cpufreq_register_notifier +EXPORT_SYMBOL vmlinux 0xadbe3ddd dma_supported +EXPORT_SYMBOL vmlinux 0xadc19a9c inet6_release +EXPORT_SYMBOL vmlinux 0xae17a1d1 phy_scan_fixups +EXPORT_SYMBOL vmlinux 0xae638f4a netif_rx +EXPORT_SYMBOL vmlinux 0xaea1bef8 i2c_smbus_write_block_data +EXPORT_SYMBOL vmlinux 0xaea773fb scsi_host_get +EXPORT_SYMBOL vmlinux 0xaec7f6e3 dev_alloc_skb +EXPORT_SYMBOL vmlinux 0xaee7e6f8 pci_enable_device +EXPORT_SYMBOL vmlinux 0xaf187f04 tr_type_trans +EXPORT_SYMBOL vmlinux 0xaf3dd7dc scsi_logging_level +EXPORT_SYMBOL vmlinux 0xaf486c5e save_mount_options +EXPORT_SYMBOL vmlinux 0xaf52c2d3 iommu_bio_merge +EXPORT_SYMBOL vmlinux 0xaf68d101 ipv4_specific +EXPORT_SYMBOL vmlinux 0xaf84d9c8 journal_blocks_per_page +EXPORT_SYMBOL vmlinux 0xafb6a879 scsi_eh_finish_cmd +EXPORT_SYMBOL vmlinux 0xafd83430 tty_port_tty_set +EXPORT_SYMBOL vmlinux 0xafd9ab8d nla_reserve +EXPORT_SYMBOL vmlinux 0xafe82e10 strcspn +EXPORT_SYMBOL vmlinux 0xaff3c472 blk_queue_update_dma_alignment +EXPORT_SYMBOL vmlinux 0xb01e7189 simple_transaction_release +EXPORT_SYMBOL vmlinux 0xb032b650 nf_ip_checksum +EXPORT_SYMBOL vmlinux 0xb034eab6 ndisc_mc_map +EXPORT_SYMBOL vmlinux 0xb04ea8f0 agp_rebind_memory +EXPORT_SYMBOL vmlinux 0xb051909f ida_init +EXPORT_SYMBOL vmlinux 0xb07dfb3d acpi_remove_gpe_handler +EXPORT_SYMBOL vmlinux 0xb08d7d4a agp_generic_alloc_by_type +EXPORT_SYMBOL vmlinux 0xb09d0f79 netif_receive_skb +EXPORT_SYMBOL vmlinux 0xb0a2ad20 unlock_new_inode +EXPORT_SYMBOL vmlinux 0xb0b847ac __bitmap_full +EXPORT_SYMBOL vmlinux 0xb0dc68bc dst_alloc +EXPORT_SYMBOL vmlinux 0xb0e10781 get_option +EXPORT_SYMBOL vmlinux 0xb0ef077e vfs_set_dqblk +EXPORT_SYMBOL vmlinux 0xb1130341 acpi_get_physical_pci_device +EXPORT_SYMBOL vmlinux 0xb116807f vfs_lstat +EXPORT_SYMBOL vmlinux 0xb11fa1ce strlcat +EXPORT_SYMBOL vmlinux 0xb121390a probe_irq_on +EXPORT_SYMBOL vmlinux 0xb1293c36 inode_change_ok +EXPORT_SYMBOL vmlinux 0xb137d9d5 bio_integrity_set_tag +EXPORT_SYMBOL vmlinux 0xb1645a2e sg_free_table +EXPORT_SYMBOL vmlinux 0xb16ae628 sk_filter +EXPORT_SYMBOL vmlinux 0xb18e02c3 radix_tree_gang_lookup_tag +EXPORT_SYMBOL vmlinux 0xb18f0114 pci_bus_assign_resources +EXPORT_SYMBOL vmlinux 0xb19760c3 bitmap_onto +EXPORT_SYMBOL vmlinux 0xb1a9ff75 tty_write_room +EXPORT_SYMBOL vmlinux 0xb1c0acc0 acpi_get_physical_device +EXPORT_SYMBOL vmlinux 0xb1c3a01a oops_in_progress +EXPORT_SYMBOL vmlinux 0xb1cfad22 rdmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xb1f975aa unlock_kernel +EXPORT_SYMBOL vmlinux 0xb2017c1d per_cpu__x86_bios_cpu_apicid +EXPORT_SYMBOL vmlinux 0xb20359a9 input_inject_event +EXPORT_SYMBOL vmlinux 0xb22fe6a3 netdev_increment_features +EXPORT_SYMBOL vmlinux 0xb233861e km_state_notify +EXPORT_SYMBOL vmlinux 0xb2704f72 scsi_remove_host +EXPORT_SYMBOL vmlinux 0xb279da12 pv_lock_ops +EXPORT_SYMBOL vmlinux 0xb2897551 sync_page_range +EXPORT_SYMBOL vmlinux 0xb295600e mpage_writepage +EXPORT_SYMBOL vmlinux 0xb2ab1111 brioctl_set +EXPORT_SYMBOL vmlinux 0xb2ab43ab kobject_put +EXPORT_SYMBOL vmlinux 0xb2be638a dma_chan_cleanup +EXPORT_SYMBOL vmlinux 0xb2dfd300 make_bad_inode +EXPORT_SYMBOL vmlinux 0xb2f84f76 loop_register_transfer +EXPORT_SYMBOL vmlinux 0xb2fd5ceb __put_user_4 +EXPORT_SYMBOL vmlinux 0xb306f164 ethtool_op_set_tx_hw_csum +EXPORT_SYMBOL vmlinux 0xb3205415 wait_for_completion_killable +EXPORT_SYMBOL vmlinux 0xb3247c4a sock_register +EXPORT_SYMBOL vmlinux 0xb3284531 acpi_dbg_layer +EXPORT_SYMBOL vmlinux 0xb33095d9 blk_complete_request +EXPORT_SYMBOL vmlinux 0xb3318ded __down_read_trylock +EXPORT_SYMBOL vmlinux 0xb34d4c2e acpi_terminate +EXPORT_SYMBOL vmlinux 0xb3509e7a sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xb352177e find_first_bit +EXPORT_SYMBOL vmlinux 0xb3692eb4 ioremap_wc +EXPORT_SYMBOL vmlinux 0xb384fc45 arp_find +EXPORT_SYMBOL vmlinux 0xb3897fad kernel_setsockopt +EXPORT_SYMBOL vmlinux 0xb3a06c04 follow_down +EXPORT_SYMBOL vmlinux 0xb3a307c6 si_meminfo +EXPORT_SYMBOL vmlinux 0xb3a726a9 __pagevec_release +EXPORT_SYMBOL vmlinux 0xb3c5be64 agp_bridge +EXPORT_SYMBOL vmlinux 0xb3d8772c rfkill_free +EXPORT_SYMBOL vmlinux 0xb3dea9b7 file_fsync +EXPORT_SYMBOL vmlinux 0xb3e7021a register_quota_format +EXPORT_SYMBOL vmlinux 0xb3f0af31 deregister_atm_ioctl +EXPORT_SYMBOL vmlinux 0xb3ff1f69 free_pages_exact +EXPORT_SYMBOL vmlinux 0xb40ce811 path_permission +EXPORT_SYMBOL vmlinux 0xb423dba1 console_blanked +EXPORT_SYMBOL vmlinux 0xb45b24f6 k8_nb_ids +EXPORT_SYMBOL vmlinux 0xb46d0970 send_sig +EXPORT_SYMBOL vmlinux 0xb4875d25 vfs_llseek +EXPORT_SYMBOL vmlinux 0xb489940a mdiobus_register +EXPORT_SYMBOL vmlinux 0xb494e82a br_fdb_put_hook +EXPORT_SYMBOL vmlinux 0xb4b75b2d jbd2_journal_check_used_features +EXPORT_SYMBOL vmlinux 0xb4ca9447 __kfifo_get +EXPORT_SYMBOL vmlinux 0xb4d84444 dma_async_device_unregister +EXPORT_SYMBOL vmlinux 0xb4dddf03 unbind_con_driver +EXPORT_SYMBOL vmlinux 0xb5044271 vsscanf +EXPORT_SYMBOL vmlinux 0xb537ea4d udp_lib_get_port +EXPORT_SYMBOL vmlinux 0xb54533f7 usecs_to_jiffies +EXPORT_SYMBOL vmlinux 0xb547ad2d mmc_remove_host +EXPORT_SYMBOL vmlinux 0xb59e3f5e nla_put +EXPORT_SYMBOL vmlinux 0xb5a459dc unregister_blkdev +EXPORT_SYMBOL vmlinux 0xb5b8b6d8 proc_net_netfilter +EXPORT_SYMBOL vmlinux 0xb5ca1c46 slhc_free +EXPORT_SYMBOL vmlinux 0xb5d52c27 ec_transaction +EXPORT_SYMBOL vmlinux 0xb5f28b5f __any_online_cpu +EXPORT_SYMBOL vmlinux 0xb60e34a8 nla_memcpy +EXPORT_SYMBOL vmlinux 0xb61d3b59 pagevec_lookup_tag +EXPORT_SYMBOL vmlinux 0xb6244511 sg_init_one +EXPORT_SYMBOL vmlinux 0xb678366f int_sqrt +EXPORT_SYMBOL vmlinux 0xb67b9a7e journal_revoke +EXPORT_SYMBOL vmlinux 0xb68a2012 __napi_schedule +EXPORT_SYMBOL vmlinux 0xb69ef2a7 tty_hung_up_p +EXPORT_SYMBOL vmlinux 0xb6a61a86 qdisc_get_rtab +EXPORT_SYMBOL vmlinux 0xb6abeae3 fb_get_mode +EXPORT_SYMBOL vmlinux 0xb6c5a973 scsi_show_result +EXPORT_SYMBOL vmlinux 0xb6ce9ff8 xfrm_state_insert +EXPORT_SYMBOL vmlinux 0xb6e227aa rtc_lock +EXPORT_SYMBOL vmlinux 0xb6e4ad9b input_register_handler +EXPORT_SYMBOL vmlinux 0xb70a8b45 kfree_skb +EXPORT_SYMBOL vmlinux 0xb70bb200 vcc_insert_socket +EXPORT_SYMBOL vmlinux 0xb714a981 console_print +EXPORT_SYMBOL vmlinux 0xb7555f12 timeval_to_jiffies +EXPORT_SYMBOL vmlinux 0xb7585fb0 agp3_generic_tlbflush +EXPORT_SYMBOL vmlinux 0xb758b225 acpi_disable_event +EXPORT_SYMBOL vmlinux 0xb75f9e0b dev_unicast_add +EXPORT_SYMBOL vmlinux 0xb7814404 sync_mapping_buffers +EXPORT_SYMBOL vmlinux 0xb7eda8b2 rt6_lookup +EXPORT_SYMBOL vmlinux 0xb7ee3f25 inet_frag_destroy +EXPORT_SYMBOL vmlinux 0xb828c786 per_cpu__cpu_sibling_map +EXPORT_SYMBOL vmlinux 0xb84176d2 path_lookup +EXPORT_SYMBOL vmlinux 0xb867aaf3 bitmap_startwrite +EXPORT_SYMBOL vmlinux 0xb86e4ab9 random32 +EXPORT_SYMBOL vmlinux 0xb8735b41 tcp_connect +EXPORT_SYMBOL vmlinux 0xb87ee4cc journal_check_available_features +EXPORT_SYMBOL vmlinux 0xb89af9bf srandom32 +EXPORT_SYMBOL vmlinux 0xb8b54871 vfs_quota_on_mount +EXPORT_SYMBOL vmlinux 0xb8e7ce2c __put_user_8 +EXPORT_SYMBOL vmlinux 0xb8f34f8e tcp_getsockopt +EXPORT_SYMBOL vmlinux 0xb905ad82 icmpv6_err_convert +EXPORT_SYMBOL vmlinux 0xb92bcc82 kblockd_schedule_work +EXPORT_SYMBOL vmlinux 0xb9358749 d_validate +EXPORT_SYMBOL vmlinux 0xb96c9058 splice_direct_to_actor +EXPORT_SYMBOL vmlinux 0xb9767d21 pnp_device_attach +EXPORT_SYMBOL vmlinux 0xb9805b0c down_read_trylock +EXPORT_SYMBOL vmlinux 0xb98a0185 rtc_tm_to_time +EXPORT_SYMBOL vmlinux 0xb9bbe97d pci_scan_bridge +EXPORT_SYMBOL vmlinux 0xb9bf23c7 pci_disable_msix +EXPORT_SYMBOL vmlinux 0xb9c74bf1 gen_kill_estimator +EXPORT_SYMBOL vmlinux 0xb9d2510b bitmap_cond_end_sync +EXPORT_SYMBOL vmlinux 0xb9d57c4f blk_queue_max_hw_segments +EXPORT_SYMBOL vmlinux 0xb9f64a58 dma_async_device_register +EXPORT_SYMBOL vmlinux 0xb9fd2205 add_efi_memmap +EXPORT_SYMBOL vmlinux 0xba02cdf2 cdev_add +EXPORT_SYMBOL vmlinux 0xba094669 set_trace_device +EXPORT_SYMBOL vmlinux 0xba16f720 unmap_underlying_metadata +EXPORT_SYMBOL vmlinux 0xba2b884b journal_unlock_updates +EXPORT_SYMBOL vmlinux 0xba2d8594 ec_read +EXPORT_SYMBOL vmlinux 0xba31c345 skb_push +EXPORT_SYMBOL vmlinux 0xba497f13 loops_per_jiffy +EXPORT_SYMBOL vmlinux 0xba9532bf dm_kcopyd_client_destroy +EXPORT_SYMBOL vmlinux 0xbaa2782a kstrndup +EXPORT_SYMBOL vmlinux 0xbaa79c56 devm_ioport_map +EXPORT_SYMBOL vmlinux 0xbad66fad vfs_quota_on_path +EXPORT_SYMBOL vmlinux 0xbb09f52b inet_ioctl +EXPORT_SYMBOL vmlinux 0xbb167766 fb_var_to_videomode +EXPORT_SYMBOL vmlinux 0xbb189cad disallow_signal +EXPORT_SYMBOL vmlinux 0xbb4d3101 dev_close +EXPORT_SYMBOL vmlinux 0xbb5d343d xfrm_get_acqseq +EXPORT_SYMBOL vmlinux 0xbb5fcfb4 jbd2_journal_invalidatepage +EXPORT_SYMBOL vmlinux 0xbb83bd29 xfrm_cfg_mutex +EXPORT_SYMBOL vmlinux 0xbb897ccd cfb_fillrect +EXPORT_SYMBOL vmlinux 0xbb956674 simple_fill_super +EXPORT_SYMBOL vmlinux 0xbb9e0721 blk_recount_segments +EXPORT_SYMBOL vmlinux 0xbba68558 scsi_remove_target +EXPORT_SYMBOL vmlinux 0xbbc8e804 param_set_ushort +EXPORT_SYMBOL vmlinux 0xbc30661e find_lock_page +EXPORT_SYMBOL vmlinux 0xbc4f81fb blk_alloc_queue +EXPORT_SYMBOL vmlinux 0xbcc308bb strnlen_user +EXPORT_SYMBOL vmlinux 0xbcc935d2 dmam_free_noncoherent +EXPORT_SYMBOL vmlinux 0xbccbb49c idr_remove_all +EXPORT_SYMBOL vmlinux 0xbcf148cf inet_frag_evictor +EXPORT_SYMBOL vmlinux 0xbd01ce87 journal_load +EXPORT_SYMBOL vmlinux 0xbd131953 bio_map_user +EXPORT_SYMBOL vmlinux 0xbd782863 input_free_device +EXPORT_SYMBOL vmlinux 0xbdaf5b07 acpi_os_read_port +EXPORT_SYMBOL vmlinux 0xbdc50c27 dev_set_mtu +EXPORT_SYMBOL vmlinux 0xbdd1032e prepare_binprm +EXPORT_SYMBOL vmlinux 0xbdd3fac3 acpi_bus_get_device +EXPORT_SYMBOL vmlinux 0xbdd80660 cdrom_mode_select +EXPORT_SYMBOL vmlinux 0xbde0f165 sock_no_recvmsg +EXPORT_SYMBOL vmlinux 0xbe321fd4 seq_lseek +EXPORT_SYMBOL vmlinux 0xbe3518d9 i2c_use_client +EXPORT_SYMBOL vmlinux 0xbe499d81 copy_to_user +EXPORT_SYMBOL vmlinux 0xbe5c9eee blk_rq_append_bio +EXPORT_SYMBOL vmlinux 0xbe86cdd5 atm_init_aal5 +EXPORT_SYMBOL vmlinux 0xbeabf6c2 scsi_scan_host +EXPORT_SYMBOL vmlinux 0xbeacdc35 ip_route_input +EXPORT_SYMBOL vmlinux 0xbeb2b930 __inet6_hash +EXPORT_SYMBOL vmlinux 0xbeb95b9a hci_suspend_dev +EXPORT_SYMBOL vmlinux 0xbebf1e01 bt_sock_poll +EXPORT_SYMBOL vmlinux 0xbecdce74 ida_pre_get +EXPORT_SYMBOL vmlinux 0xbef0040f tty_insert_flip_string_flags +EXPORT_SYMBOL vmlinux 0xbef43296 console_conditional_schedule +EXPORT_SYMBOL vmlinux 0xbefee397 acpi_get_object_info +EXPORT_SYMBOL vmlinux 0xbf04c5df cfb_copyarea +EXPORT_SYMBOL vmlinux 0xbf2345fd __inet6_lookup_established +EXPORT_SYMBOL vmlinux 0xbf358b45 kernel_recvmsg +EXPORT_SYMBOL vmlinux 0xbf5e9c12 wait_on_sync_kiocb +EXPORT_SYMBOL vmlinux 0xbf718c97 ___pskb_trim +EXPORT_SYMBOL vmlinux 0xbf7adee1 cdrom_get_last_written +EXPORT_SYMBOL vmlinux 0xbf7fd2f5 schedule_timeout_killable +EXPORT_SYMBOL vmlinux 0xbf9bcc8d __cap_empty_set +EXPORT_SYMBOL vmlinux 0xbfa52fc5 hci_register_dev +EXPORT_SYMBOL vmlinux 0xbfc177bc iowrite32_rep +EXPORT_SYMBOL vmlinux 0xbfd28796 scsi_host_put +EXPORT_SYMBOL vmlinux 0xbfe56d79 lock_rename +EXPORT_SYMBOL vmlinux 0xbfee3ad5 loop_unregister_transfer +EXPORT_SYMBOL vmlinux 0xc003c637 __strncpy_from_user +EXPORT_SYMBOL vmlinux 0xc01eac97 netlink_ack +EXPORT_SYMBOL vmlinux 0xc031b5f5 tcp_ioctl +EXPORT_SYMBOL vmlinux 0xc045ad4e timespec_trunc +EXPORT_SYMBOL vmlinux 0xc0580937 rb_erase +EXPORT_SYMBOL vmlinux 0xc05e41e7 get_empty_filp +EXPORT_SYMBOL vmlinux 0xc061e56a get_write_access +EXPORT_SYMBOL vmlinux 0xc07d43ae acpi_evaluate_reference +EXPORT_SYMBOL vmlinux 0xc09651d9 crc32_be +EXPORT_SYMBOL vmlinux 0xc0a3d105 find_next_bit +EXPORT_SYMBOL vmlinux 0xc0b3b04f elv_queue_empty +EXPORT_SYMBOL vmlinux 0xc0b76cc8 nobh_write_begin +EXPORT_SYMBOL vmlinux 0xc0bdcb4c jbd2_journal_init_inode +EXPORT_SYMBOL vmlinux 0xc0be790d bitmap_end_sync +EXPORT_SYMBOL vmlinux 0xc0d7fa39 pci_iomap +EXPORT_SYMBOL vmlinux 0xc0f31263 ip_route_output_key +EXPORT_SYMBOL vmlinux 0xc1103f21 md_wakeup_thread +EXPORT_SYMBOL vmlinux 0xc1155451 tcp_shutdown +EXPORT_SYMBOL vmlinux 0xc131500d con_is_bound +EXPORT_SYMBOL vmlinux 0xc13d7e4c __downgrade_write +EXPORT_SYMBOL vmlinux 0xc1403886 bio_init +EXPORT_SYMBOL vmlinux 0xc14d1047 acpi_bus_start +EXPORT_SYMBOL vmlinux 0xc16a9eaf skb_dma_map +EXPORT_SYMBOL vmlinux 0xc17e96bd free_buffer_head +EXPORT_SYMBOL vmlinux 0xc18454dd set_binfmt +EXPORT_SYMBOL vmlinux 0xc1a9fec4 phy_register_fixup_for_uid +EXPORT_SYMBOL vmlinux 0xc1e5799b unload_nls +EXPORT_SYMBOL vmlinux 0xc2066af0 batostr +EXPORT_SYMBOL vmlinux 0xc20f0469 __mod_zone_page_state +EXPORT_SYMBOL vmlinux 0xc21cc374 pcim_iomap +EXPORT_SYMBOL vmlinux 0xc229eaee flush_old_exec +EXPORT_SYMBOL vmlinux 0xc22b4bfd generic_osync_inode +EXPORT_SYMBOL vmlinux 0xc2424641 agp3_generic_cleanup +EXPORT_SYMBOL vmlinux 0xc253a04f __splice_from_pipe +EXPORT_SYMBOL vmlinux 0xc254af48 dcache_lock +EXPORT_SYMBOL vmlinux 0xc256e762 __bitmap_equal +EXPORT_SYMBOL vmlinux 0xc26c26b8 dev_open +EXPORT_SYMBOL vmlinux 0xc292b222 xfrm_state_add +EXPORT_SYMBOL vmlinux 0xc2aaa3e4 pcim_iomap_regions_request_all +EXPORT_SYMBOL vmlinux 0xc2b87933 hci_register_cb +EXPORT_SYMBOL vmlinux 0xc2c3a3eb dev_set_allmulti +EXPORT_SYMBOL vmlinux 0xc2c95270 pnp_start_dev +EXPORT_SYMBOL vmlinux 0xc2e587d1 reset_devices +EXPORT_SYMBOL vmlinux 0xc2fdc37a mmc_release_host +EXPORT_SYMBOL vmlinux 0xc33f6f4c on_each_cpu +EXPORT_SYMBOL vmlinux 0xc340960a swiotlb_sync_sg_for_cpu +EXPORT_SYMBOL vmlinux 0xc3611976 input_unregister_device +EXPORT_SYMBOL vmlinux 0xc36f1fa1 __scsi_iterate_devices +EXPORT_SYMBOL vmlinux 0xc37e2868 km_state_expired +EXPORT_SYMBOL vmlinux 0xc3aaf0a9 __put_user_1 +EXPORT_SYMBOL vmlinux 0xc402cc99 register_acpi_notifier +EXPORT_SYMBOL vmlinux 0xc41d175f kset_register +EXPORT_SYMBOL vmlinux 0xc43c9a8c dev_mc_unsync +EXPORT_SYMBOL vmlinux 0xc444efaf compat_sock_get_timestamp +EXPORT_SYMBOL vmlinux 0xc465cc6c iw_handler_get_spy +EXPORT_SYMBOL vmlinux 0xc4925812 pci_map_rom +EXPORT_SYMBOL vmlinux 0xc499ae1e kstrdup +EXPORT_SYMBOL vmlinux 0xc4a2be5e sget +EXPORT_SYMBOL vmlinux 0xc4ac5c17 generic_file_readonly_mmap +EXPORT_SYMBOL vmlinux 0xc4cdb705 unregister_netdevice +EXPORT_SYMBOL vmlinux 0xc4d489e9 up_write +EXPORT_SYMBOL vmlinux 0xc4d8a050 jbd2_journal_start +EXPORT_SYMBOL vmlinux 0xc5094c2b journal_release_buffer +EXPORT_SYMBOL vmlinux 0xc51ca174 inet_put_port +EXPORT_SYMBOL vmlinux 0xc51e6d2e generic_file_open +EXPORT_SYMBOL vmlinux 0xc52f5714 fb_videomode_to_var +EXPORT_SYMBOL vmlinux 0xc53c882d idr_get_new +EXPORT_SYMBOL vmlinux 0xc5534d64 ioread16 +EXPORT_SYMBOL vmlinux 0xc558530d profile_pc +EXPORT_SYMBOL vmlinux 0xc55f7dc7 _write_trylock +EXPORT_SYMBOL vmlinux 0xc5644d18 page_zero_new_buffers +EXPORT_SYMBOL vmlinux 0xc57d4378 sock_common_getsockopt +EXPORT_SYMBOL vmlinux 0xc59e230f input_register_device +EXPORT_SYMBOL vmlinux 0xc5a06657 textsearch_register +EXPORT_SYMBOL vmlinux 0xc5af5143 mmc_register_driver +EXPORT_SYMBOL vmlinux 0xc5bd4d75 dquot_commit_info +EXPORT_SYMBOL vmlinux 0xc5d9c46c agp_try_unsupported_boot +EXPORT_SYMBOL vmlinux 0xc610c0f1 in6_dev_finish_destroy +EXPORT_SYMBOL vmlinux 0xc63d3d3b eth_header_cache +EXPORT_SYMBOL vmlinux 0xc65abeb7 agp3_generic_sizes +EXPORT_SYMBOL vmlinux 0xc65ce1b2 swiotlb_unmap_single_attrs +EXPORT_SYMBOL vmlinux 0xc65e5a84 hci_get_route +EXPORT_SYMBOL vmlinux 0xc68944ce swiotlb_dma_supported +EXPORT_SYMBOL vmlinux 0xc6bd0d12 dev_get_flags +EXPORT_SYMBOL vmlinux 0xc6c176e7 find_inode_number +EXPORT_SYMBOL vmlinux 0xc6d87e82 __find_get_block +EXPORT_SYMBOL vmlinux 0xc6f8264d phy_register_fixup +EXPORT_SYMBOL vmlinux 0xc6fe73e3 pci_bus_size_bridges +EXPORT_SYMBOL vmlinux 0xc7080a71 compat_mc_setsockopt +EXPORT_SYMBOL vmlinux 0xc71c0305 vmap +EXPORT_SYMBOL vmlinux 0xc7208c3a serial8250_resume_port +EXPORT_SYMBOL vmlinux 0xc740c64a memchr +EXPORT_SYMBOL vmlinux 0xc753a96a ethtool_op_set_tx_ipv6_csum +EXPORT_SYMBOL vmlinux 0xc75d189b bio_integrity_trim +EXPORT_SYMBOL vmlinux 0xc79bcd36 dm_vcalloc +EXPORT_SYMBOL vmlinux 0xc79d214a mb_cache_entry_get +EXPORT_SYMBOL vmlinux 0xc7a24d76 sysfs_format_mac +EXPORT_SYMBOL vmlinux 0xc7a4fbed rtnl_lock +EXPORT_SYMBOL vmlinux 0xc7be3788 __nla_reserve +EXPORT_SYMBOL vmlinux 0xc7ca9e77 jbd2_journal_set_features +EXPORT_SYMBOL vmlinux 0xc7ceb53a end_page_writeback +EXPORT_SYMBOL vmlinux 0xc7fa68bf register_qdisc +EXPORT_SYMBOL vmlinux 0xc8483bab ilookup5 +EXPORT_SYMBOL vmlinux 0xc86249a0 dmam_alloc_noncoherent +EXPORT_SYMBOL vmlinux 0xc897c382 sg_init_table +EXPORT_SYMBOL vmlinux 0xc8a90017 scsi_setup_fs_cmnd +EXPORT_SYMBOL vmlinux 0xc8abf7c6 mmc_set_data_timeout +EXPORT_SYMBOL vmlinux 0xc8b57c27 autoremove_wake_function +EXPORT_SYMBOL vmlinux 0xc8bece9a page_readlink +EXPORT_SYMBOL vmlinux 0xc8ca3e25 acpi_get_child +EXPORT_SYMBOL vmlinux 0xc8e0130b dev_getbyhwaddr +EXPORT_SYMBOL vmlinux 0xc8e94ef8 key_validate +EXPORT_SYMBOL vmlinux 0xc900f860 inet_stream_ops +EXPORT_SYMBOL vmlinux 0xc908c116 udp_poll +EXPORT_SYMBOL vmlinux 0xc90fc82b d_genocide +EXPORT_SYMBOL vmlinux 0xc921f453 ethtool_op_set_flags +EXPORT_SYMBOL vmlinux 0xc923dac9 pv_mmu_ops +EXPORT_SYMBOL vmlinux 0xc9408dd4 inet6_register_protosw +EXPORT_SYMBOL vmlinux 0xc940b538 pcix_get_max_mmrbc +EXPORT_SYMBOL vmlinux 0xc9437ede __down_write_nested +EXPORT_SYMBOL vmlinux 0xc9482f0e __scsi_alloc_queue +EXPORT_SYMBOL vmlinux 0xc96659bf skb_dequeue +EXPORT_SYMBOL vmlinux 0xc966f75c nf_log_packet +EXPORT_SYMBOL vmlinux 0xc96eefa9 __serio_register_driver +EXPORT_SYMBOL vmlinux 0xc998d641 icmp_err_convert +EXPORT_SYMBOL vmlinux 0xc99cf467 jbd2_journal_release_jbd_inode +EXPORT_SYMBOL vmlinux 0xc9aaf360 __tcp_get_md5sig_pool +EXPORT_SYMBOL vmlinux 0xc9ab0d46 agp_generic_alloc_pages +EXPORT_SYMBOL vmlinux 0xc9ab2eef acpi_os_wait_events_complete +EXPORT_SYMBOL vmlinux 0xc9ae59c2 register_filesystem +EXPORT_SYMBOL vmlinux 0xc9c0cd17 gnet_stats_copy_basic +EXPORT_SYMBOL vmlinux 0xc9c40a9e mnt_unpin +EXPORT_SYMBOL vmlinux 0xc9eb9866 xfrm_state_check_expire +EXPORT_SYMBOL vmlinux 0xca222911 pci_get_bus_and_slot +EXPORT_SYMBOL vmlinux 0xca48501c jbd2_journal_create +EXPORT_SYMBOL vmlinux 0xca4df118 block_sync_page +EXPORT_SYMBOL vmlinux 0xca544c7a inetdev_by_index +EXPORT_SYMBOL vmlinux 0xca5dbc50 scsi_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xca621e87 generic_delete_inode +EXPORT_SYMBOL vmlinux 0xca662826 phy_print_status +EXPORT_SYMBOL vmlinux 0xca730459 pid_task +EXPORT_SYMBOL vmlinux 0xca89da02 kernel_accept +EXPORT_SYMBOL vmlinux 0xca8abced request_key_with_auxdata +EXPORT_SYMBOL vmlinux 0xca8acc78 acpi_dbg_level +EXPORT_SYMBOL vmlinux 0xcb090571 swiotlb_map_single +EXPORT_SYMBOL vmlinux 0xcb32da10 param_set_int +EXPORT_SYMBOL vmlinux 0xcb47a797 blk_queue_free_tags +EXPORT_SYMBOL vmlinux 0xcb48fe0e register_cdrom +EXPORT_SYMBOL vmlinux 0xcb6361fb generic_splice_sendpage +EXPORT_SYMBOL vmlinux 0xcb6beb40 hweight32 +EXPORT_SYMBOL vmlinux 0xcb7131fb fb_get_options +EXPORT_SYMBOL vmlinux 0xcb733bf2 acpi_bus_set_power +EXPORT_SYMBOL vmlinux 0xcb876f03 journal_start_commit +EXPORT_SYMBOL vmlinux 0xcbc1f02f sock_common_setsockopt +EXPORT_SYMBOL vmlinux 0xcbf5162b tcp_disconnect +EXPORT_SYMBOL vmlinux 0xcc07af75 strnlen +EXPORT_SYMBOL vmlinux 0xcc182a63 bt_accept_unlink +EXPORT_SYMBOL vmlinux 0xcc18747e sk_stream_kill_queues +EXPORT_SYMBOL vmlinux 0xcc1fb551 baswap +EXPORT_SYMBOL vmlinux 0xcc20274a md_check_recovery +EXPORT_SYMBOL vmlinux 0xcc248d26 serial8250_suspend_port +EXPORT_SYMBOL vmlinux 0xcc2b1629 find_task_by_pid_ns +EXPORT_SYMBOL vmlinux 0xcc36f32e fb_unregister_client +EXPORT_SYMBOL vmlinux 0xcc4c1e02 search_binary_handler +EXPORT_SYMBOL vmlinux 0xcc4ec4fe neigh_compat_output +EXPORT_SYMBOL vmlinux 0xcc5005fe msleep_interruptible +EXPORT_SYMBOL vmlinux 0xcc51ee50 dma_spin_lock +EXPORT_SYMBOL vmlinux 0xcc73a93e __bio_clone +EXPORT_SYMBOL vmlinux 0xcc7fa952 local_bh_enable_ip +EXPORT_SYMBOL vmlinux 0xcc93e89f blk_queue_dma_alignment +EXPORT_SYMBOL vmlinux 0xcca75064 serial8250_register_port +EXPORT_SYMBOL vmlinux 0xccc06e90 call_usermodehelper_setkeys +EXPORT_SYMBOL vmlinux 0xccc2390b task_pgrp_nr_ns +EXPORT_SYMBOL vmlinux 0xccc43bfa jbd2_journal_clear_err +EXPORT_SYMBOL vmlinux 0xccd048c4 xfrm_input +EXPORT_SYMBOL vmlinux 0xcce9ccab dev_get_by_flags +EXPORT_SYMBOL vmlinux 0xccf77ad8 __sk_mem_schedule +EXPORT_SYMBOL vmlinux 0xcd23496d dev_set_mac_address +EXPORT_SYMBOL vmlinux 0xcd28e957 file_remove_suid +EXPORT_SYMBOL vmlinux 0xcd290e0e close_bdev_exclusive +EXPORT_SYMBOL vmlinux 0xcd625888 blk_dump_rq_flags +EXPORT_SYMBOL vmlinux 0xcd8a1951 dm_get_mapinfo +EXPORT_SYMBOL vmlinux 0xcdd3f3dc blk_start_queue +EXPORT_SYMBOL vmlinux 0xcdf6f59a netdev_rx_csum_fault +EXPORT_SYMBOL vmlinux 0xce19bac5 register_inet6addr_notifier +EXPORT_SYMBOL vmlinux 0xce1f2cc2 bio_integrity_alloc +EXPORT_SYMBOL vmlinux 0xce28f08c blk_alloc_queue_node +EXPORT_SYMBOL vmlinux 0xce36ded6 sysctl_tcp_mem +EXPORT_SYMBOL vmlinux 0xce4904a4 acpi_leave_sleep_state +EXPORT_SYMBOL vmlinux 0xce5ac24f zlib_inflate_workspacesize +EXPORT_SYMBOL vmlinux 0xce82a1ca vfs_quota_off +EXPORT_SYMBOL vmlinux 0xce971b6b llc_build_and_send_ui_pkt +EXPORT_SYMBOL vmlinux 0xceb4c77f blk_queue_hardsect_size +EXPORT_SYMBOL vmlinux 0xcec47845 agp_flush_chipset +EXPORT_SYMBOL vmlinux 0xcecee2c0 bio_unmap_user +EXPORT_SYMBOL vmlinux 0xcefcd99a serial8250_unregister_port +EXPORT_SYMBOL vmlinux 0xcf1242a4 tty_insert_flip_string +EXPORT_SYMBOL vmlinux 0xcf28b263 jbd2_journal_release_buffer +EXPORT_SYMBOL vmlinux 0xcf953ec8 sock_rfree +EXPORT_SYMBOL vmlinux 0xcfab02ce eth_header +EXPORT_SYMBOL vmlinux 0xcfadd723 __percpu_counter_add +EXPORT_SYMBOL vmlinux 0xcfc277f4 arch_acpi_processor_init_pdc +EXPORT_SYMBOL vmlinux 0xcfc96384 bdi_set_max_ratio +EXPORT_SYMBOL vmlinux 0xcfd3018e set_normalized_timespec +EXPORT_SYMBOL vmlinux 0xd0020122 generic_block_fiemap +EXPORT_SYMBOL vmlinux 0xd0181f4f __bitmap_xor +EXPORT_SYMBOL vmlinux 0xd01ffb64 sock_queue_rcv_skb +EXPORT_SYMBOL vmlinux 0xd02cc869 __bitmap_andnot +EXPORT_SYMBOL vmlinux 0xd05907c3 scm_detach_fds +EXPORT_SYMBOL vmlinux 0xd07bb451 ip_generic_getfrag +EXPORT_SYMBOL vmlinux 0xd08197fa acpi_load_tables +EXPORT_SYMBOL vmlinux 0xd0a8e245 alloc_disk +EXPORT_SYMBOL vmlinux 0xd0e9df1e kernel_read +EXPORT_SYMBOL vmlinux 0xd0ee38b8 schedule_timeout_uninterruptible +EXPORT_SYMBOL vmlinux 0xd0fef3b2 agp_free_key +EXPORT_SYMBOL vmlinux 0xd103767e con_copy_unimap +EXPORT_SYMBOL vmlinux 0xd1076263 __pskb_pull_tail +EXPORT_SYMBOL vmlinux 0xd1472061 acpi_pci_register_driver +EXPORT_SYMBOL vmlinux 0xd1558a90 neigh_resolve_output +EXPORT_SYMBOL vmlinux 0xd1892179 del_gendisk +EXPORT_SYMBOL vmlinux 0xd18b6eb2 acpi_unmap_lsapic +EXPORT_SYMBOL vmlinux 0xd18c53d4 agp_generic_destroy_pages +EXPORT_SYMBOL vmlinux 0xd19bb294 acpi_install_address_space_handler +EXPORT_SYMBOL vmlinux 0xd1c445b3 dquot_alloc_inode +EXPORT_SYMBOL vmlinux 0xd1de3f0d drop_super +EXPORT_SYMBOL vmlinux 0xd1e85783 mb_cache_shrink +EXPORT_SYMBOL vmlinux 0xd1eaa0a5 inode_permission +EXPORT_SYMBOL vmlinux 0xd1f6c5f3 smp_num_siblings +EXPORT_SYMBOL vmlinux 0xd1f74e1c proc_dointvec_ms_jiffies +EXPORT_SYMBOL vmlinux 0xd1f91bcd dev_base_lock +EXPORT_SYMBOL vmlinux 0xd232a94c path_put +EXPORT_SYMBOL vmlinux 0xd251d7b0 security_socket_getpeersec_dgram +EXPORT_SYMBOL vmlinux 0xd2555f19 jiffies_64_to_clock_t +EXPORT_SYMBOL vmlinux 0xd25d4f74 console_blank_hook +EXPORT_SYMBOL vmlinux 0xd267d42c down_killable +EXPORT_SYMBOL vmlinux 0xd2695e43 hci_conn_check_link_mode +EXPORT_SYMBOL vmlinux 0xd291a1f7 blk_unplug +EXPORT_SYMBOL vmlinux 0xd2965f6f kthread_should_stop +EXPORT_SYMBOL vmlinux 0xd29fface i2c_smbus_write_byte_data +EXPORT_SYMBOL vmlinux 0xd2d1893d add_disk +EXPORT_SYMBOL vmlinux 0xd2eb48fa tty_port_tty_get +EXPORT_SYMBOL vmlinux 0xd30f6e80 module_put +EXPORT_SYMBOL vmlinux 0xd3253af8 skb_queue_head +EXPORT_SYMBOL vmlinux 0xd34f0c62 gen_pool_create +EXPORT_SYMBOL vmlinux 0xd3951da4 acpi_resource_to_address64 +EXPORT_SYMBOL vmlinux 0xd3f74cf1 interruptible_sleep_on_timeout +EXPORT_SYMBOL vmlinux 0xd424873a proc_doulongvec_minmax +EXPORT_SYMBOL vmlinux 0xd42b7232 _write_unlock_bh +EXPORT_SYMBOL vmlinux 0xd464a892 find_get_pages_tag +EXPORT_SYMBOL vmlinux 0xd46702fa tcp_v4_destroy_sock +EXPORT_SYMBOL vmlinux 0xd482d2df skb_find_text +EXPORT_SYMBOL vmlinux 0xd4903145 sysctl_string +EXPORT_SYMBOL vmlinux 0xd4a4a57f inode_needs_sync +EXPORT_SYMBOL vmlinux 0xd4d109c5 dma_sync_wait +EXPORT_SYMBOL vmlinux 0xd4fd9318 __break_lease +EXPORT_SYMBOL vmlinux 0xd5263820 mb_cache_destroy +EXPORT_SYMBOL vmlinux 0xd53aec49 cpu_possible_map +EXPORT_SYMBOL vmlinux 0xd57f8789 iommu_num_pages +EXPORT_SYMBOL vmlinux 0xd5963d0c pci_set_mwi +EXPORT_SYMBOL vmlinux 0xd5a7feac mdiobus_write +EXPORT_SYMBOL vmlinux 0xd5b037e1 kref_put +EXPORT_SYMBOL vmlinux 0xd5cc4183 generic_file_splice_write_nolock +EXPORT_SYMBOL vmlinux 0xd5d96178 poll_freewait +EXPORT_SYMBOL vmlinux 0xd5ffc24b compat_tcp_setsockopt +EXPORT_SYMBOL vmlinux 0xd6035d05 do_settimeofday +EXPORT_SYMBOL vmlinux 0xd60b5fe5 xfrm_policy_register_afinfo +EXPORT_SYMBOL vmlinux 0xd60d7af4 ida_remove +EXPORT_SYMBOL vmlinux 0xd61152fa blkdev_get +EXPORT_SYMBOL vmlinux 0xd62c833f schedule_timeout +EXPORT_SYMBOL vmlinux 0xd6315ab2 registered_fb +EXPORT_SYMBOL vmlinux 0xd6517380 __inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xd6526e41 pci_dev_put +EXPORT_SYMBOL vmlinux 0xd6a55706 kmem_cache_free +EXPORT_SYMBOL vmlinux 0xd6a78d08 smp_call_function_single +EXPORT_SYMBOL vmlinux 0xd6ad3b79 ethtool_op_set_sg +EXPORT_SYMBOL vmlinux 0xd6b33026 cpu_khz +EXPORT_SYMBOL vmlinux 0xd6e00170 scsi_reset_provider +EXPORT_SYMBOL vmlinux 0xd6ee688f vmalloc +EXPORT_SYMBOL vmlinux 0xd712f2c0 ip6_route_me_harder +EXPORT_SYMBOL vmlinux 0xd758cd26 get_phy_id +EXPORT_SYMBOL vmlinux 0xd779bad1 llc_sap_close +EXPORT_SYMBOL vmlinux 0xd79b5a02 allow_signal +EXPORT_SYMBOL vmlinux 0xd7a6fafa panic_notifier_list +EXPORT_SYMBOL vmlinux 0xd7b1b790 elv_rb_del +EXPORT_SYMBOL vmlinux 0xd7c11f42 inet_release +EXPORT_SYMBOL vmlinux 0xd7c8954a dm_dirty_log_create +EXPORT_SYMBOL vmlinux 0xd7d8580d agp_alloc_bridge +EXPORT_SYMBOL vmlinux 0xd7dd777b reserve_perfctr_nmi +EXPORT_SYMBOL vmlinux 0xd7e48b73 kset_unregister +EXPORT_SYMBOL vmlinux 0xd8216045 unregister_cdrom +EXPORT_SYMBOL vmlinux 0xd83a320a pci_release_selected_regions +EXPORT_SYMBOL vmlinux 0xd8511b69 tcp_md5_hash_key +EXPORT_SYMBOL vmlinux 0xd86fcd8b compat_ip_setsockopt +EXPORT_SYMBOL vmlinux 0xd88bc27b uart_add_one_port +EXPORT_SYMBOL vmlinux 0xd88e5781 pci_disable_msi +EXPORT_SYMBOL vmlinux 0xd88f695a __mod_timer +EXPORT_SYMBOL vmlinux 0xd89da37f movable_zone +EXPORT_SYMBOL vmlinux 0xd8a0514c kmem_ptr_validate +EXPORT_SYMBOL vmlinux 0xd8d74cab phy_ethtool_gset +EXPORT_SYMBOL vmlinux 0xd8e484f0 register_chrdev_region +EXPORT_SYMBOL vmlinux 0xd8efd3b7 phy_enable_interrupts +EXPORT_SYMBOL vmlinux 0xd8f85285 wake_up_process +EXPORT_SYMBOL vmlinux 0xd9091363 acpi_install_notify_handler +EXPORT_SYMBOL vmlinux 0xd9262c76 generic_removexattr +EXPORT_SYMBOL vmlinux 0xd9370b06 skb_dma_unmap +EXPORT_SYMBOL vmlinux 0xd9528c86 acpi_unlock_ac_dir +EXPORT_SYMBOL vmlinux 0xd96e0564 tty_check_change +EXPORT_SYMBOL vmlinux 0xd985dc99 mempool_free_pages +EXPORT_SYMBOL vmlinux 0xd9ca3514 bio_integrity_split +EXPORT_SYMBOL vmlinux 0xda05d1c7 xfrm_state_unregister_afinfo +EXPORT_SYMBOL vmlinux 0xda0a6b0e acpi_map_lsapic +EXPORT_SYMBOL vmlinux 0xda1a7335 kasprintf +EXPORT_SYMBOL vmlinux 0xda1c2975 __grab_cache_page +EXPORT_SYMBOL vmlinux 0xda2ee9c7 __nla_put_nohdr +EXPORT_SYMBOL vmlinux 0xda45ba06 inet_sock_destruct +EXPORT_SYMBOL vmlinux 0xda4629e4 radix_tree_insert +EXPORT_SYMBOL vmlinux 0xda597d34 __ht_create_irq +EXPORT_SYMBOL vmlinux 0xda69a1f7 simple_set_mnt +EXPORT_SYMBOL vmlinux 0xda7ca6cb fb_mode_is_equal +EXPORT_SYMBOL vmlinux 0xda8af7ad fb_find_nearest_mode +EXPORT_SYMBOL vmlinux 0xda8d7811 alloc_tty_driver +EXPORT_SYMBOL vmlinux 0xda928914 nmi_watchdog +EXPORT_SYMBOL vmlinux 0xda9ca32a serio_unregister_port +EXPORT_SYMBOL vmlinux 0xdaa5128a iw_handler_set_thrspy +EXPORT_SYMBOL vmlinux 0xdac63607 qdisc_list_del +EXPORT_SYMBOL vmlinux 0xdacfc5f5 struct_module +EXPORT_SYMBOL vmlinux 0xdb0ae632 find_task_by_vpid +EXPORT_SYMBOL vmlinux 0xdb1977fb devm_free_irq +EXPORT_SYMBOL vmlinux 0xdb458957 agp_backend_acquire +EXPORT_SYMBOL vmlinux 0xdb795516 ipv6_chk_prefix +EXPORT_SYMBOL vmlinux 0xdbbd6a92 ip_cmsg_recv +EXPORT_SYMBOL vmlinux 0xdbcd416e sysctl_ip_nonlocal_bind +EXPORT_SYMBOL vmlinux 0xdbd737e1 pci_get_class +EXPORT_SYMBOL vmlinux 0xdbe4a214 dmam_pool_create +EXPORT_SYMBOL vmlinux 0xdbf97e31 generic_write_end +EXPORT_SYMBOL vmlinux 0xdc14eda7 pci_pci_problems +EXPORT_SYMBOL vmlinux 0xdc2adb35 add_taint +EXPORT_SYMBOL vmlinux 0xdc43a9c8 daemonize +EXPORT_SYMBOL vmlinux 0xdc4a5d44 compat_ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xdc611106 __lock_buffer +EXPORT_SYMBOL vmlinux 0xdc624d41 __lock_page +EXPORT_SYMBOL vmlinux 0xdc7166cc pci_restore_state +EXPORT_SYMBOL vmlinux 0xdc79e6bc tcp_v4_conn_request +EXPORT_SYMBOL vmlinux 0xdc7b8a08 neigh_sysctl_unregister +EXPORT_SYMBOL vmlinux 0xdc873a70 screen_info +EXPORT_SYMBOL vmlinux 0xdcb0349b sys_close +EXPORT_SYMBOL vmlinux 0xdcdc9d18 xfrm6_input_addr +EXPORT_SYMBOL vmlinux 0xdd4388ae hci_conn_change_link_key +EXPORT_SYMBOL vmlinux 0xdd604f27 acpi_lock_battery_dir +EXPORT_SYMBOL vmlinux 0xdd6a25c5 neigh_event_ns +EXPORT_SYMBOL vmlinux 0xdd781b6f sock_setsockopt +EXPORT_SYMBOL vmlinux 0xddc1ac11 bioset_integrity_free +EXPORT_SYMBOL vmlinux 0xddca82ca bt_accept_dequeue +EXPORT_SYMBOL vmlinux 0xddec02a9 compat_nf_getsockopt +EXPORT_SYMBOL vmlinux 0xddf43bc4 __serio_register_port +EXPORT_SYMBOL vmlinux 0xde0bdcff memset +EXPORT_SYMBOL vmlinux 0xde17c7d8 ip4_datagram_connect +EXPORT_SYMBOL vmlinux 0xde2180a2 inet_getname +EXPORT_SYMBOL vmlinux 0xde75b689 set_irq_type +EXPORT_SYMBOL vmlinux 0xde9360ba totalram_pages +EXPORT_SYMBOL vmlinux 0xde9b17ed agp3_generic_fetch_size +EXPORT_SYMBOL vmlinux 0xdea9a13f tcf_exts_destroy +EXPORT_SYMBOL vmlinux 0xdeab735c input_flush_device +EXPORT_SYMBOL vmlinux 0xdec62a8f pci_pme_capable +EXPORT_SYMBOL vmlinux 0xdf0da3cc acpi_get_devices +EXPORT_SYMBOL vmlinux 0xdf478691 journal_ack_err +EXPORT_SYMBOL vmlinux 0xdf60cc27 __print_symbol +EXPORT_SYMBOL vmlinux 0xdf8c695a __ndelay +EXPORT_SYMBOL vmlinux 0xdf929370 fs_overflowgid +EXPORT_SYMBOL vmlinux 0xdfa87a3d skb_add_rx_frag +EXPORT_SYMBOL vmlinux 0xdfb7bada acpi_check_resource_conflict +EXPORT_SYMBOL vmlinux 0xdfc5169b slhc_init +EXPORT_SYMBOL vmlinux 0xdfee58a0 genl_register_ops +EXPORT_SYMBOL vmlinux 0xe003ea39 neigh_table_init +EXPORT_SYMBOL vmlinux 0xe00e4296 journal_flush +EXPORT_SYMBOL vmlinux 0xe00ffa4e pci_set_dma_mask +EXPORT_SYMBOL vmlinux 0xe016aa6b pci_set_master +EXPORT_SYMBOL vmlinux 0xe01e3aa9 tty_hangup +EXPORT_SYMBOL vmlinux 0xe02744c9 xfrm_policy_insert +EXPORT_SYMBOL vmlinux 0xe04fb17d __nla_reserve_nohdr +EXPORT_SYMBOL vmlinux 0xe075d6eb iter_div_u64_rem +EXPORT_SYMBOL vmlinux 0xe0ac8bd2 acpi_bus_generate_netlink_event +EXPORT_SYMBOL vmlinux 0xe0ad8b27 acpi_is_video_device +EXPORT_SYMBOL vmlinux 0xe0b13336 argv_free +EXPORT_SYMBOL vmlinux 0xe0b30f72 sk_release_kernel +EXPORT_SYMBOL vmlinux 0xe0d2b488 skb_pad +EXPORT_SYMBOL vmlinux 0xe0f7dca7 sk_receive_skb +EXPORT_SYMBOL vmlinux 0xe113bbbc csum_partial +EXPORT_SYMBOL vmlinux 0xe1287a1f do_splice_from +EXPORT_SYMBOL vmlinux 0xe13cd8a7 dmi_name_in_vendors +EXPORT_SYMBOL vmlinux 0xe13fdb64 blk_integrity_compare +EXPORT_SYMBOL vmlinux 0xe1761617 security_inet_conn_request +EXPORT_SYMBOL vmlinux 0xe1a81c3a icmpv6msg_statistics +EXPORT_SYMBOL vmlinux 0xe1afcd98 xfrm_policy_walk +EXPORT_SYMBOL vmlinux 0xe1c265d8 fd_install +EXPORT_SYMBOL vmlinux 0xe1e31e9b block_prepare_write +EXPORT_SYMBOL vmlinux 0xe1f7328d dev_set_promiscuity +EXPORT_SYMBOL vmlinux 0xe20d2639 unregister_sysrq_key +EXPORT_SYMBOL vmlinux 0xe24050c7 scnprintf +EXPORT_SYMBOL vmlinux 0xe24d3a97 jiffies_64 +EXPORT_SYMBOL vmlinux 0xe2a6fd16 hci_conn_auth +EXPORT_SYMBOL vmlinux 0xe2d5255a strcmp +EXPORT_SYMBOL vmlinux 0xe2d9e701 d_namespace_path +EXPORT_SYMBOL vmlinux 0xe2e3c78e blk_plug_device +EXPORT_SYMBOL vmlinux 0xe3053c0e dcache_dir_open +EXPORT_SYMBOL vmlinux 0xe30deaa1 jbd2_journal_stop +EXPORT_SYMBOL vmlinux 0xe325583d kmem_cache_shrink +EXPORT_SYMBOL vmlinux 0xe33f5247 per_cpu__cpu_info +EXPORT_SYMBOL vmlinux 0xe342c953 i2c_del_driver +EXPORT_SYMBOL vmlinux 0xe3446fa6 get_unmapped_area +EXPORT_SYMBOL vmlinux 0xe351633f genl_register_family +EXPORT_SYMBOL vmlinux 0xe3b0192b vscnprintf +EXPORT_SYMBOL vmlinux 0xe3b693b8 jbd2_journal_forget +EXPORT_SYMBOL vmlinux 0xe3b93a66 swiotlb_sync_sg_for_device +EXPORT_SYMBOL vmlinux 0xe3fbe148 acpi_install_table_handler +EXPORT_SYMBOL vmlinux 0xe43617f7 acpi_gbl_FADT +EXPORT_SYMBOL vmlinux 0xe44dd841 dquot_drop +EXPORT_SYMBOL vmlinux 0xe44e09a9 d_alloc_name +EXPORT_SYMBOL vmlinux 0xe456bd3a complete +EXPORT_SYMBOL vmlinux 0xe484e35f ioread32 +EXPORT_SYMBOL vmlinux 0xe4870354 _read_trylock +EXPORT_SYMBOL vmlinux 0xe4b24b8c __next_cpu +EXPORT_SYMBOL vmlinux 0xe4c1df3e _read_lock_bh +EXPORT_SYMBOL vmlinux 0xe4c2e19a __scsi_add_device +EXPORT_SYMBOL vmlinux 0xe4cfd571 mb_cache_entry_find_first +EXPORT_SYMBOL vmlinux 0xe4d372c3 blk_queue_dma_pad +EXPORT_SYMBOL vmlinux 0xe4ff6bf9 journal_forget +EXPORT_SYMBOL vmlinux 0xe50c3845 kernel_sock_ioctl +EXPORT_SYMBOL vmlinux 0xe50d8af5 fb_find_mode +EXPORT_SYMBOL vmlinux 0xe5122890 flow_cache_genid +EXPORT_SYMBOL vmlinux 0xe5123687 hci_conn_switch_role +EXPORT_SYMBOL vmlinux 0xe523ad75 synchronize_irq +EXPORT_SYMBOL vmlinux 0xe52947e7 __phys_addr +EXPORT_SYMBOL vmlinux 0xe542862a pnp_disable_dev +EXPORT_SYMBOL vmlinux 0xe55484ce neigh_seq_stop +EXPORT_SYMBOL vmlinux 0xe57878a1 in6_pton +EXPORT_SYMBOL vmlinux 0xe583a2bf blk_queue_end_tag +EXPORT_SYMBOL vmlinux 0xe5844107 cpu_present_map +EXPORT_SYMBOL vmlinux 0xe5867808 dlci_ioctl_set +EXPORT_SYMBOL vmlinux 0xe59a710d filp_close +EXPORT_SYMBOL vmlinux 0xe5a04af5 pcix_get_mmrbc +EXPORT_SYMBOL vmlinux 0xe5c78a99 do_blank_screen +EXPORT_SYMBOL vmlinux 0xe5c800d9 scsi_cmd_print_sense_hdr +EXPORT_SYMBOL vmlinux 0xe5ed5467 xfrm_policy_walk_init +EXPORT_SYMBOL vmlinux 0xe5f9f7e9 dma_async_client_unregister +EXPORT_SYMBOL vmlinux 0xe60b3450 sock_i_ino +EXPORT_SYMBOL vmlinux 0xe65a2175 hci_connect +EXPORT_SYMBOL vmlinux 0xe66ea6c0 __wait_on_buffer +EXPORT_SYMBOL vmlinux 0xe690b8fd __ipv6_isatap_ifid +EXPORT_SYMBOL vmlinux 0xe694cc8a set_current_groups +EXPORT_SYMBOL vmlinux 0xe6951fb6 sock_create +EXPORT_SYMBOL vmlinux 0xe6ead2b1 bitmap_endwrite +EXPORT_SYMBOL vmlinux 0xe6fb136e d_move +EXPORT_SYMBOL vmlinux 0xe6fbe430 can_do_mlock +EXPORT_SYMBOL vmlinux 0xe713533c uart_unregister_driver +EXPORT_SYMBOL vmlinux 0xe716baed acpi_unregister_ioapic +EXPORT_SYMBOL vmlinux 0xe751ba22 rfkill_allocate +EXPORT_SYMBOL vmlinux 0xe7546fa3 dmam_alloc_coherent +EXPORT_SYMBOL vmlinux 0xe75ef7f8 journal_init_dev +EXPORT_SYMBOL vmlinux 0xe778a831 pci_bus_read_config_word +EXPORT_SYMBOL vmlinux 0xe77a01af sock_no_mmap +EXPORT_SYMBOL vmlinux 0xe77f9872 locks_init_lock +EXPORT_SYMBOL vmlinux 0xe786737e __netif_schedule +EXPORT_SYMBOL vmlinux 0xe7d2aca1 security_sk_classify_flow +EXPORT_SYMBOL vmlinux 0xe7d4daac seq_list_next +EXPORT_SYMBOL vmlinux 0xe7f28ed8 nf_unregister_hooks +EXPORT_SYMBOL vmlinux 0xe801db27 read_dev_sector +EXPORT_SYMBOL vmlinux 0xe80ce219 sysctl_tcp_dma_copybreak +EXPORT_SYMBOL vmlinux 0xe828b876 fb_set_cmap +EXPORT_SYMBOL vmlinux 0xe82b4cbf init_buffer +EXPORT_SYMBOL vmlinux 0xe8304561 vfs_getattr +EXPORT_SYMBOL vmlinux 0xe84e0bdf nf_log_unregister +EXPORT_SYMBOL vmlinux 0xe85498e4 i2c_get_adapter +EXPORT_SYMBOL vmlinux 0xe8583614 posix_acl_from_xattr +EXPORT_SYMBOL vmlinux 0xe860436c tcf_em_unregister +EXPORT_SYMBOL vmlinux 0xe8794ce1 slhc_toss +EXPORT_SYMBOL vmlinux 0xe88be0b3 tcp_sendpage +EXPORT_SYMBOL vmlinux 0xe8a3605f acpi_processor_set_thermal_limit +EXPORT_SYMBOL vmlinux 0xe8cd902e hweight16 +EXPORT_SYMBOL vmlinux 0xe8d0b674 simple_getattr +EXPORT_SYMBOL vmlinux 0xe910b532 del_timer_sync +EXPORT_SYMBOL vmlinux 0xe914e41e strcpy +EXPORT_SYMBOL vmlinux 0xe916c7ec xfrm_state_walk +EXPORT_SYMBOL vmlinux 0xe9387c3c dentry_open +EXPORT_SYMBOL vmlinux 0xe93e3144 kernel_listen +EXPORT_SYMBOL vmlinux 0xe9456a5a sysctl_xfrm_aevent_rseqth +EXPORT_SYMBOL vmlinux 0xe945c261 ipv6_getsockopt +EXPORT_SYMBOL vmlinux 0xe997667b wrmsr_on_cpu +EXPORT_SYMBOL vmlinux 0xe9ace35a swiotlb_unmap_sg +EXPORT_SYMBOL vmlinux 0xe9d627e1 starget_for_each_device +EXPORT_SYMBOL vmlinux 0xea10212a int_to_scsilun +EXPORT_SYMBOL vmlinux 0xea10655a __bitmap_intersects +EXPORT_SYMBOL vmlinux 0xea13320e blk_queue_find_tag +EXPORT_SYMBOL vmlinux 0xea147363 printk +EXPORT_SYMBOL vmlinux 0xea44461f key_type_keyring +EXPORT_SYMBOL vmlinux 0xea531368 mem_map +EXPORT_SYMBOL vmlinux 0xea6fcdaa genl_unregister_family +EXPORT_SYMBOL vmlinux 0xea757d9e inet_frags_init +EXPORT_SYMBOL vmlinux 0xeac68305 set_page_dirty +EXPORT_SYMBOL vmlinux 0xeac6ebe1 vfs_quota_sync +EXPORT_SYMBOL vmlinux 0xead58fb9 print_hex_dump +EXPORT_SYMBOL vmlinux 0xeae03e48 qdisc_watchdog_init +EXPORT_SYMBOL vmlinux 0xeae3dfd6 __const_udelay +EXPORT_SYMBOL vmlinux 0xeae6025c skb_prepare_seq_read +EXPORT_SYMBOL vmlinux 0xeaf935f0 xfrm_input_resume +EXPORT_SYMBOL vmlinux 0xeb1d3f86 __pci_register_driver +EXPORT_SYMBOL vmlinux 0xeb1fabf6 interruptible_sleep_on +EXPORT_SYMBOL vmlinux 0xeb228272 posix_acl_create_masq +EXPORT_SYMBOL vmlinux 0xeb395084 param_get_invbool +EXPORT_SYMBOL vmlinux 0xeb58800e tcf_em_tree_validate +EXPORT_SYMBOL vmlinux 0xeb6137a4 swiotlb_free_coherent +EXPORT_SYMBOL vmlinux 0xeb8ddae2 unregister_snap_client +EXPORT_SYMBOL vmlinux 0xeb8f54b3 strstrip +EXPORT_SYMBOL vmlinux 0xeb9b4287 hci_unregister_proto +EXPORT_SYMBOL vmlinux 0xebbf1dba strncasecmp +EXPORT_SYMBOL vmlinux 0xebd273a6 strict_strtoull +EXPORT_SYMBOL vmlinux 0xebe82b09 pci_get_slot +EXPORT_SYMBOL vmlinux 0xec381ddf ip_xfrm_me_harder +EXPORT_SYMBOL vmlinux 0xec38ca43 pci_enable_device_io +EXPORT_SYMBOL vmlinux 0xec3d368c block_is_partially_uptodate +EXPORT_SYMBOL vmlinux 0xec3e0dd2 agp_create_memory +EXPORT_SYMBOL vmlinux 0xec539ad8 generic_file_direct_write +EXPORT_SYMBOL vmlinux 0xec794ba0 __send_remote_softirq +EXPORT_SYMBOL vmlinux 0xec860422 bioset_free +EXPORT_SYMBOL vmlinux 0xec93ca7f sk_stream_wait_connect +EXPORT_SYMBOL vmlinux 0xecb07aef blk_queue_prep_rq +EXPORT_SYMBOL vmlinux 0xecb46b04 acpi_get_hp_hw_control_from_firmware +EXPORT_SYMBOL vmlinux 0xecd2b662 acpi_match_device_ids +EXPORT_SYMBOL vmlinux 0xecde1418 _spin_lock_irq +EXPORT_SYMBOL vmlinux 0xece730b6 posix_unblock_lock +EXPORT_SYMBOL vmlinux 0xeceb106e skb_copy_datagram_iovec +EXPORT_SYMBOL vmlinux 0xed2789a3 vfs_readlink +EXPORT_SYMBOL vmlinux 0xed3b0e2f ppp_unregister_compressor +EXPORT_SYMBOL vmlinux 0xed583512 neigh_table_init_no_netlink +EXPORT_SYMBOL vmlinux 0xed60c586 skb_make_writable +EXPORT_SYMBOL vmlinux 0xed6b03e6 kern_path +EXPORT_SYMBOL vmlinux 0xed6cc474 __devm_request_region +EXPORT_SYMBOL vmlinux 0xed789ad9 pagecache_write_end +EXPORT_SYMBOL vmlinux 0xed819f4b agp_generic_free_by_type +EXPORT_SYMBOL vmlinux 0xed8b72d8 xfrm_unregister_type +EXPORT_SYMBOL vmlinux 0xeda59dcd vfs_set_dqinfo +EXPORT_SYMBOL vmlinux 0xedbaee5e nla_strcmp +EXPORT_SYMBOL vmlinux 0xedc03953 iounmap +EXPORT_SYMBOL vmlinux 0xedcd9dd0 generic_shutdown_super +EXPORT_SYMBOL vmlinux 0xedd14538 param_get_uint +EXPORT_SYMBOL vmlinux 0xee1e05a8 fb_pan_display +EXPORT_SYMBOL vmlinux 0xee1f0594 xfrm_stateonly_find +EXPORT_SYMBOL vmlinux 0xee2a4028 pfifo_qdisc_ops +EXPORT_SYMBOL vmlinux 0xee2d0fc7 _local_bh_enable +EXPORT_SYMBOL vmlinux 0xee5281cd pnp_is_active +EXPORT_SYMBOL vmlinux 0xee5614e7 __brelse +EXPORT_SYMBOL vmlinux 0xee7eb9e1 pnp_platform_devices +EXPORT_SYMBOL vmlinux 0xeea9dbaf bitmap_bitremap +EXPORT_SYMBOL vmlinux 0xeeaa7d0d security_task_getsecid +EXPORT_SYMBOL vmlinux 0xeeae6246 get_disk +EXPORT_SYMBOL vmlinux 0xeeb1717c param_array_get +EXPORT_SYMBOL vmlinux 0xeecaea22 down_write_trylock +EXPORT_SYMBOL vmlinux 0xef13da58 xfrm_policy_bysel_ctx +EXPORT_SYMBOL vmlinux 0xef241669 agp_copy_info +EXPORT_SYMBOL vmlinux 0xef651e6e pci_bus_write_config_word +EXPORT_SYMBOL vmlinux 0xef9aedfc boot_option_idle_override +EXPORT_SYMBOL vmlinux 0xefa4f7bf set_bh_page +EXPORT_SYMBOL vmlinux 0xefdd70ce security_secid_to_secctx +EXPORT_SYMBOL vmlinux 0xefe099c3 acpi_get_event_status +EXPORT_SYMBOL vmlinux 0xefef1e93 inet_unregister_protosw +EXPORT_SYMBOL vmlinux 0xf0009fee put_pages_list +EXPORT_SYMBOL vmlinux 0xf0551f96 ethtool_op_get_ufo +EXPORT_SYMBOL vmlinux 0xf05b108d bio_uncopy_user +EXPORT_SYMBOL vmlinux 0xf065f629 ioread16be +EXPORT_SYMBOL vmlinux 0xf097d3e1 pcim_iomap_table +EXPORT_SYMBOL vmlinux 0xf0b57c68 param_set_long +EXPORT_SYMBOL vmlinux 0xf0c411c1 scsi_device_lookup_by_target +EXPORT_SYMBOL vmlinux 0xf0ca0e43 bio_copy_user +EXPORT_SYMBOL vmlinux 0xf0f1246c kvasprintf +EXPORT_SYMBOL vmlinux 0xf0fee2e8 pcim_iounmap_regions +EXPORT_SYMBOL vmlinux 0xf1004740 lease_get_mtime +EXPORT_SYMBOL vmlinux 0xf10de535 ioread8 +EXPORT_SYMBOL vmlinux 0xf11543ff find_first_zero_bit +EXPORT_SYMBOL vmlinux 0xf116d4b5 copy_in_user +EXPORT_SYMBOL vmlinux 0xf11cf629 bmap +EXPORT_SYMBOL vmlinux 0xf12b6039 tcp_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xf12fcd38 __lookup_hash +EXPORT_SYMBOL vmlinux 0xf14a1ca3 inode_setattr +EXPORT_SYMBOL vmlinux 0xf162fe2d sysctl_xfrm_aevent_etime +EXPORT_SYMBOL vmlinux 0xf174ed48 acquire_console_sem +EXPORT_SYMBOL vmlinux 0xf174fe36 mark_info_dirty +EXPORT_SYMBOL vmlinux 0xf1752afe __request_region +EXPORT_SYMBOL vmlinux 0xf19294db bt_sock_unregister +EXPORT_SYMBOL vmlinux 0xf195c682 fb_invert_cmaps +EXPORT_SYMBOL vmlinux 0xf19eedb3 fput +EXPORT_SYMBOL vmlinux 0xf1bf30c6 ilookup +EXPORT_SYMBOL vmlinux 0xf1d1a9e2 neigh_destroy +EXPORT_SYMBOL vmlinux 0xf1e98c74 avenrun +EXPORT_SYMBOL vmlinux 0xf1f11437 scsi_mode_sense +EXPORT_SYMBOL vmlinux 0xf1fa89a0 __locks_copy_lock +EXPORT_SYMBOL vmlinux 0xf20dabd8 free_irq +EXPORT_SYMBOL vmlinux 0xf23d5cb8 zero_fill_bio +EXPORT_SYMBOL vmlinux 0xf246de13 tcf_hash_destroy +EXPORT_SYMBOL vmlinux 0xf25087b8 compat_sock_get_timestampns +EXPORT_SYMBOL vmlinux 0xf2642953 i2c_smbus_read_byte +EXPORT_SYMBOL vmlinux 0xf2997713 tty_termios_hw_change +EXPORT_SYMBOL vmlinux 0xf2a4a545 generic_fillattr +EXPORT_SYMBOL vmlinux 0xf2a6d2bf xfrm_policy_count +EXPORT_SYMBOL vmlinux 0xf2ab1416 ip6_xmit +EXPORT_SYMBOL vmlinux 0xf2afa595 param_get_charp +EXPORT_SYMBOL vmlinux 0xf2db10e2 ppp_channel_index +EXPORT_SYMBOL vmlinux 0xf313da4e sha_transform +EXPORT_SYMBOL vmlinux 0xf319450e tcp_proc_register +EXPORT_SYMBOL vmlinux 0xf3341268 __clear_user +EXPORT_SYMBOL vmlinux 0xf3360449 fb_class +EXPORT_SYMBOL vmlinux 0xf338d4c3 netlink_unregister_notifier +EXPORT_SYMBOL vmlinux 0xf346231f seq_list_start_head +EXPORT_SYMBOL vmlinux 0xf34805cb dma_pool_create +EXPORT_SYMBOL vmlinux 0xf38681a9 dm_io +EXPORT_SYMBOL vmlinux 0xf3b62b46 inet_csk_accept +EXPORT_SYMBOL vmlinux 0xf3bf0bce __bitmap_complement +EXPORT_SYMBOL vmlinux 0xf3c4932c udp_disconnect +EXPORT_SYMBOL vmlinux 0xf3c9c001 i2c_attach_client +EXPORT_SYMBOL vmlinux 0xf3e7d76e phy_stop_interrupts +EXPORT_SYMBOL vmlinux 0xf441ac43 ioread8_rep +EXPORT_SYMBOL vmlinux 0xf4528073 scsi_kmap_atomic_sg +EXPORT_SYMBOL vmlinux 0xf4553b62 journal_set_features +EXPORT_SYMBOL vmlinux 0xf464ef69 pnp_stop_dev +EXPORT_SYMBOL vmlinux 0xf49bc67a atm_pcr_goal +EXPORT_SYMBOL vmlinux 0xf4a27a03 arp_xmit +EXPORT_SYMBOL vmlinux 0xf4a5c213 avail_to_resrv_perfctr_nmi_bit +EXPORT_SYMBOL vmlinux 0xf4b4ace8 hci_recv_fragment +EXPORT_SYMBOL vmlinux 0xf4f14de6 rtnl_trylock +EXPORT_SYMBOL vmlinux 0xf4f52f93 dqstats +EXPORT_SYMBOL vmlinux 0xf51ae235 touch_nmi_watchdog +EXPORT_SYMBOL vmlinux 0xf5240dae skb_put +EXPORT_SYMBOL vmlinux 0xf52441d9 shrink_dcache_sb +EXPORT_SYMBOL vmlinux 0xf53c4c3f touch_atime +EXPORT_SYMBOL vmlinux 0xf53d4c26 qdisc_class_hash_destroy +EXPORT_SYMBOL vmlinux 0xf567f3cb agp_generic_insert_memory +EXPORT_SYMBOL vmlinux 0xf5829132 scsicam_bios_param +EXPORT_SYMBOL vmlinux 0xf58dc7b0 seq_bitmap +EXPORT_SYMBOL vmlinux 0xf5981e94 d_rehash +EXPORT_SYMBOL vmlinux 0xf5a48326 xfrm_policy_destroy +EXPORT_SYMBOL vmlinux 0xf5ac7d9f tcp_rcv_state_process +EXPORT_SYMBOL vmlinux 0xf5c6299b set_bdi_congested +EXPORT_SYMBOL vmlinux 0xf5c835f4 blk_stop_queue +EXPORT_SYMBOL vmlinux 0xf5ce9811 tcp_memory_allocated +EXPORT_SYMBOL vmlinux 0xf5dd687e tc_classify_compat +EXPORT_SYMBOL vmlinux 0xf5e61615 __xfrm_state_destroy +EXPORT_SYMBOL vmlinux 0xf605b87d br_handle_frame_hook +EXPORT_SYMBOL vmlinux 0xf61aebaa skb_free_datagram +EXPORT_SYMBOL vmlinux 0xf64c09d6 devm_ioremap +EXPORT_SYMBOL vmlinux 0xf666cbb3 __memcpy_fromio +EXPORT_SYMBOL vmlinux 0xf6ae2505 jbd2_journal_file_inode +EXPORT_SYMBOL vmlinux 0xf6bb4729 color_table +EXPORT_SYMBOL vmlinux 0xf6cdb69b key_revoke +EXPORT_SYMBOL vmlinux 0xf6d7b2e6 blk_queue_max_phys_segments +EXPORT_SYMBOL vmlinux 0xf6de9c22 i2c_del_adapter +EXPORT_SYMBOL vmlinux 0xf6ebc03b net_ratelimit +EXPORT_SYMBOL vmlinux 0xf705c09f scsi_rescan_device +EXPORT_SYMBOL vmlinux 0xf70d1d93 inc_zone_page_state +EXPORT_SYMBOL vmlinux 0xf71907cf fb_set_suspend +EXPORT_SYMBOL vmlinux 0xf749534a gen_pool_free +EXPORT_SYMBOL vmlinux 0xf778e05d fb_set_var +EXPORT_SYMBOL vmlinux 0xf784d337 xfrm_state_lookup +EXPORT_SYMBOL vmlinux 0xf78d04ab netlink_register_notifier +EXPORT_SYMBOL vmlinux 0xf7979dff proc_dostring +EXPORT_SYMBOL vmlinux 0xf79cf7d7 unregister_sysctl_table +EXPORT_SYMBOL vmlinux 0xf7b4b4f1 seq_path +EXPORT_SYMBOL vmlinux 0xf7c6db95 d_find_alias +EXPORT_SYMBOL vmlinux 0xf7e9716d iw_handler_set_spy +EXPORT_SYMBOL vmlinux 0xf810bc55 write_inode_now +EXPORT_SYMBOL vmlinux 0xf811e69d scsi_eh_flush_done_q +EXPORT_SYMBOL vmlinux 0xf8232b03 set_blocksize +EXPORT_SYMBOL vmlinux 0xf82abc1d isa_dma_bridge_buggy +EXPORT_SYMBOL vmlinux 0xf82e3d47 acpi_initialize_objects +EXPORT_SYMBOL vmlinux 0xf82f1109 utf8_wctomb +EXPORT_SYMBOL vmlinux 0xf85547b9 sock_map_fd +EXPORT_SYMBOL vmlinux 0xf857333a skb_append_datato_frags +EXPORT_SYMBOL vmlinux 0xf868ca9c dm_put_device +EXPORT_SYMBOL vmlinux 0xf874fa61 jbd2_journal_lock_updates +EXPORT_SYMBOL vmlinux 0xf876683c dev_driver_string +EXPORT_SYMBOL vmlinux 0xf8814f73 rb_last +EXPORT_SYMBOL vmlinux 0xf88360af inet6_add_protocol +EXPORT_SYMBOL vmlinux 0xf88e0ee2 acpi_get_table_header +EXPORT_SYMBOL vmlinux 0xf890fe7f pm_idle +EXPORT_SYMBOL vmlinux 0xf89843f9 schedule_work +EXPORT_SYMBOL vmlinux 0xf8985592 xfrm_lookup +EXPORT_SYMBOL vmlinux 0xf8a108d1 netlink_change_ngroups +EXPORT_SYMBOL vmlinux 0xf8aa47ae mutex_lock_killable +EXPORT_SYMBOL vmlinux 0xf8b30e93 mempool_create +EXPORT_SYMBOL vmlinux 0xf8ba23e8 tty_port_free_xmit_buf +EXPORT_SYMBOL vmlinux 0xf8bbdc5c kmem_cache_create +EXPORT_SYMBOL vmlinux 0xf8c6fc4e inet6_getname +EXPORT_SYMBOL vmlinux 0xf8cb6e0d pci_enable_msix +EXPORT_SYMBOL vmlinux 0xf8ee3e17 scsi_print_sense +EXPORT_SYMBOL vmlinux 0xf9203217 task_session_nr_ns +EXPORT_SYMBOL vmlinux 0xf923054b pcix_set_mmrbc +EXPORT_SYMBOL vmlinux 0xf943f0de seq_escape +EXPORT_SYMBOL vmlinux 0xf9512711 tty_get_baud_rate +EXPORT_SYMBOL vmlinux 0xf963871f inet_select_addr +EXPORT_SYMBOL vmlinux 0xf971bd6d netdev_set_master +EXPORT_SYMBOL vmlinux 0xf97f1f63 dm_table_event +EXPORT_SYMBOL vmlinux 0xf9a482f9 msleep +EXPORT_SYMBOL vmlinux 0xf9a99db4 vfs_get_dqblk +EXPORT_SYMBOL vmlinux 0xf9d1223f tcp_sync_mss +EXPORT_SYMBOL vmlinux 0xfa022dc6 __dev_get_by_name +EXPORT_SYMBOL vmlinux 0xfa02dc9c tcp_v4_md5_hash_skb +EXPORT_SYMBOL vmlinux 0xfa0564fc __wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfa32d61e mmc_wait_for_app_cmd +EXPORT_SYMBOL vmlinux 0xfa65425b pcie_get_readrq +EXPORT_SYMBOL vmlinux 0xfa7a5c43 tcp_alloc_md5sig_pool +EXPORT_SYMBOL vmlinux 0xfa7d4bb0 dm_table_get +EXPORT_SYMBOL vmlinux 0xfa842fdc down_write +EXPORT_SYMBOL vmlinux 0xfaa2331f journal_dirty_data +EXPORT_SYMBOL vmlinux 0xfaae9c9d kobject_get +EXPORT_SYMBOL vmlinux 0xfab0b2a3 mdiobus_free +EXPORT_SYMBOL vmlinux 0xfae7c24b invalidate_inode_buffers +EXPORT_SYMBOL vmlinux 0xfaf98462 bitrev32 +EXPORT_SYMBOL vmlinux 0xfb0443fb acpi_get_parent +EXPORT_SYMBOL vmlinux 0xfb0cf2e9 touch_all_softlockup_watchdogs +EXPORT_SYMBOL vmlinux 0xfb3566e8 cdrom_media_changed +EXPORT_SYMBOL vmlinux 0xfb480350 blk_queue_make_request +EXPORT_SYMBOL vmlinux 0xfb493c1c pci_scan_bus_parented +EXPORT_SYMBOL vmlinux 0xfb5cbd91 datagram_poll +EXPORT_SYMBOL vmlinux 0xfb68002d vfs_symlink +EXPORT_SYMBOL vmlinux 0xfb6af58d recalc_sigpending +EXPORT_SYMBOL vmlinux 0xfb6bdbae inet_csk_reset_keepalive_timer +EXPORT_SYMBOL vmlinux 0xfb74167f inet_dev_addr_type +EXPORT_SYMBOL vmlinux 0xfba0c2e0 llc_sap_list_lock +EXPORT_SYMBOL vmlinux 0xfba39acb generic_file_aio_write +EXPORT_SYMBOL vmlinux 0xfbf92453 param_get_bool +EXPORT_SYMBOL vmlinux 0xfc02b7ad sysctl_tcp_wmem +EXPORT_SYMBOL vmlinux 0xfc1b1aeb jbd2_journal_begin_ordered_truncate +EXPORT_SYMBOL vmlinux 0xfc2762bb netlink_clear_multicast_users +EXPORT_SYMBOL vmlinux 0xfc31fe88 l2cap_load +EXPORT_SYMBOL vmlinux 0xfc39e32f ioport_unmap +EXPORT_SYMBOL vmlinux 0xfc9cff26 ip_mc_dec_group +EXPORT_SYMBOL vmlinux 0xfcaa04a0 out_of_line_wait_on_bit_lock +EXPORT_SYMBOL vmlinux 0xfcda63a3 node_states +EXPORT_SYMBOL vmlinux 0xfcdd8cf6 param_get_ushort +EXPORT_SYMBOL vmlinux 0xfcec0987 enable_irq +EXPORT_SYMBOL vmlinux 0xfcfa03ff fb_videomode_to_modelist +EXPORT_SYMBOL vmlinux 0xfcfe2304 unregister_tcf_proto_ops +EXPORT_SYMBOL vmlinux 0xfd1c92a8 per_cpu____irq_regs +EXPORT_SYMBOL vmlinux 0xfd82759b generic_setxattr +EXPORT_SYMBOL vmlinux 0xfd98879a rb_next +EXPORT_SYMBOL vmlinux 0xfdb13ff3 unregister_binfmt +EXPORT_SYMBOL vmlinux 0xfdb9b629 ioread32be +EXPORT_SYMBOL vmlinux 0xfdc8d28f unregister_con_driver +EXPORT_SYMBOL vmlinux 0xfdd734f3 pci_set_dma_max_seg_size +EXPORT_SYMBOL vmlinux 0xfddc5b13 __alloc_skb +EXPORT_SYMBOL vmlinux 0xfde2145a boot_tvec_bases +EXPORT_SYMBOL vmlinux 0xfde87705 inet_stream_connect +EXPORT_SYMBOL vmlinux 0xfdfc0b3b fiemap_fill_next_extent +EXPORT_SYMBOL vmlinux 0xfe047ce6 acpi_enter_sleep_state +EXPORT_SYMBOL vmlinux 0xfe09013f blkdev_issue_discard +EXPORT_SYMBOL vmlinux 0xfe0f5e62 request_key +EXPORT_SYMBOL vmlinux 0xfe392bcd generic_segment_checks +EXPORT_SYMBOL vmlinux 0xfe3e6c22 journal_get_create_access +EXPORT_SYMBOL vmlinux 0xfe5be5bc end_buffer_read_sync +EXPORT_SYMBOL vmlinux 0xfe5d4bb2 sys_tz +EXPORT_SYMBOL vmlinux 0xfe65841b posix_acl_permission +EXPORT_SYMBOL vmlinux 0xfe769456 unregister_netdevice_notifier +EXPORT_SYMBOL vmlinux 0xfe7c4287 nr_cpu_ids +EXPORT_SYMBOL vmlinux 0xfe92c28a jbd2_journal_try_to_free_buffers +EXPORT_SYMBOL vmlinux 0xfeaf7781 __set_page_dirty_buffers +EXPORT_SYMBOL vmlinux 0xfeb63f8f netpoll_cleanup +EXPORT_SYMBOL vmlinux 0xfebd6559 phy_mii_ioctl +EXPORT_SYMBOL vmlinux 0xfebf53a2 vfs_mknod +EXPORT_SYMBOL vmlinux 0xfec26f5f inet_csk_init_xmit_timers +EXPORT_SYMBOL vmlinux 0xfec347fb xfrm_init_state +EXPORT_SYMBOL vmlinux 0xfec3c2f2 bcd2bin +EXPORT_SYMBOL vmlinux 0xfec848d6 bitmap_close_sync +EXPORT_SYMBOL vmlinux 0xfed339ba __nla_put +EXPORT_SYMBOL vmlinux 0xfedd35fc console_suspend_enabled +EXPORT_SYMBOL vmlinux 0xfeebd2ad redirty_page_for_writepage +EXPORT_SYMBOL vmlinux 0xfef0c2f5 sk_free +EXPORT_SYMBOL vmlinux 0xfef96e23 __scsi_print_command +EXPORT_SYMBOL vmlinux 0xff1da7d7 jbd2_journal_ack_err +EXPORT_SYMBOL vmlinux 0xff1e9dd8 seq_list_start +EXPORT_SYMBOL vmlinux 0xff4bbf44 simple_pin_fs +EXPORT_SYMBOL vmlinux 0xff5d819c linkwatch_fire_event +EXPORT_SYMBOL vmlinux 0xff6878cf fb_default_cmap +EXPORT_SYMBOL vmlinux 0xff708fd3 mempool_destroy +EXPORT_SYMBOL vmlinux 0xff74c433 jbd2_journal_flush +EXPORT_SYMBOL vmlinux 0xff7559e4 ioport_resource +EXPORT_SYMBOL vmlinux 0xff9ca065 fb_edid_to_monspecs +EXPORT_SYMBOL vmlinux 0xffa7a83f simple_lookup +EXPORT_SYMBOL vmlinux 0xffafdc5c _read_unlock_irq +EXPORT_SYMBOL vmlinux 0xffc620db phy_start_aneg +EXPORT_SYMBOL vmlinux 0xffcdd28a jbd2_journal_abort +EXPORT_SYMBOL vmlinux 0xffcf2f77 acpi_root_dir +EXPORT_SYMBOL vmlinux 0xffd5a395 default_wake_function +EXPORT_SYMBOL vmlinux 0xffd6affa genphy_restart_aneg +EXPORT_SYMBOL vmlinux 0xffe630fb ip_route_me_harder +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x16836e04 speedstep_detect_processor +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0x4cdb4bd0 speedstep_get_processor_frequency +EXPORT_SYMBOL_GPL arch/x86/kernel/cpu/cpufreq/speedstep-lib 0xd494ee54 speedstep_get_freqs +EXPORT_SYMBOL_GPL arch/x86/kernel/microcode 0xdf66ca81 ucode_cpu_info +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x00aaf935 kvm_disable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0133148d kvm_get_cs_db_l_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0839e704 kvm_set_cr4 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x083bbe3b kvm_clear_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x094ac8f4 kvm_get_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x095afc83 kvm_report_emulation_failure +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0a0e20a8 kvm_emulate_cpuid +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0bd8d682 kvm_set_cr0 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0c1ab58e kvm_set_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x0deeb3ac kvm_release_page_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x12d1b23b kvm_release_pfn_clean +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x18e2e5c1 gfn_to_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x1e4580bb kvm_release_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x2322e039 kvm_set_pfn_accessed +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27046576 kvm_exit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x27fef950 kvm_lapic_reset +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x280d9b96 kvm_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x317f9e6b kvm_enable_efer_bits +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x34337730 kvm_mmu_page_fault +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x352fa74c kvm_lapic_set_tpr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x3afefa4b kvm_get_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x42813812 fx_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x4a7cbe69 is_error_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5518abc2 emulate_instruction +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5729313c kvm_vcpu_cache +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5a35d832 gfn_to_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x5c2672f6 kvm_is_visible_gfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x63cd47c8 kvm_emulate_hypercall +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x641c9e46 kvm_mmu_invlpg +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x67fd926d emulator_write_emulated +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x688da311 kvm_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x69f0bef9 kvm_mmu_unprotect_page_virt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6dde419c kvm_mmu_reset_context +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x6ffa8f3f kvm_inject_pending_timer_irqs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7821d506 kvm_task_switch +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x7f6c2d92 emulator_read_std +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x83902554 kvm_lapic_get_cr8 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x899be1fc kvm_get_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8ce4f3ab kvm_enable_tdp +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x8e7f9b47 segment_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x90893149 kvm_cpu_has_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x91693d45 kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x99937d4d kvm_queue_exception +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0x9cd81aed kvm_read_guest +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa0141585 kvm_read_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa18e7092 kvm_queue_exception_e +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa236a5ec kvm_timer_intr_post +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa361bc65 kvm_set_pfn_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa3778434 kvm_x86_ops +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa7c7937f kvm_cpu_get_interrupt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xa7d65617 kvm_lapic_enabled +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaa2b5a07 __kvm_set_memory_region +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xaafc48d3 kvm_lapic_find_highest_irr +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xad952420 gfn_to_pfn +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb19bead3 kvm_set_msr_common +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb53bf244 kvm_set_apic_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb76788b7 kvm_resched +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xb9cb3d28 kvm_inject_nmi +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbcdf566e kvm_lmsw +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd377dc9 kvm_mmu_set_nonpresent_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd86163a kvm_handle_fault_on_reboot +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xbd94103b kvm_mmu_set_base_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc10c71ed kvm_emulate_pio_string +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc2ef33d1 load_pdptrs +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xc3d5b17f kvm_vcpu_uninit +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xcc6540c0 kvm_lapic_get_base +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xce521b48 kvm_mmu_load +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd0b2727a kvm_mmu_set_mask_ptes +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd296def9 kvm_is_error_hva +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xd745c627 kvm_emulate_halt +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdba0b5b3 kvm_release_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdc5576d2 kvm_vcpu_init +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdd6446cb kvm_load_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdef3323e kvm_put_guest_fpu +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xdf90bcea kvm_clear_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe4ad2d9c kvm_create_lapic +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe7688100 kvm_set_cr3 +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xe9cd01f8 kvm_put_kvm +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf3e54b1d kvm_write_guest_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf54ea8e1 kvm_set_page_dirty +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xf68d2262 is_error_page +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfbe6b3f4 kvm_emulate_pio +EXPORT_SYMBOL_GPL arch/x86/kvm/kvm 0xfe24b205 kvm_get_msr_common +EXPORT_SYMBOL_GPL crypto/aes_generic 0x1381bf2d crypto_ft_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x22894d94 crypto_il_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5f943003 crypto_it_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0x5fe743de crypto_aes_expand_key +EXPORT_SYMBOL_GPL crypto/aes_generic 0x6e9cc2ba crypto_fl_tab +EXPORT_SYMBOL_GPL crypto/aes_generic 0xe30299c5 crypto_aes_set_key +EXPORT_SYMBOL_GPL crypto/async_tx/async_memcpy 0x0b324270 async_memcpy +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x1edf2050 async_trigger_callback +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x54e1d644 async_tx_submit +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6b4a6db2 async_tx_issue_pending_all +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x6cba723c __async_tx_find_channel +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x71b34850 dma_wait_for_async_tx +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0x8c21e99c async_tx_quiesce +EXPORT_SYMBOL_GPL crypto/async_tx/async_tx 0xfc823483 async_tx_run_dependencies +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0x5d187c8b async_xor +EXPORT_SYMBOL_GPL crypto/async_tx/async_xor 0xe9b931ec async_xor_zero_sum +EXPORT_SYMBOL_GPL crypto/des_generic 0xcfd9a2c0 des_ekey +EXPORT_SYMBOL_GPL crypto/twofish_common 0xb296502d twofish_setkey +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x02ff9464 cfag12864b_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x0ecb2e5d cfag12864b_disable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x305dc3c6 cfag12864b_isenabled +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x3389f926 cfag12864b_enable +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0x9522a342 cfag12864b_getrate +EXPORT_SYMBOL_GPL drivers/auxdisplay/cfag12864b 0xc48e9d95 cfag12864b_buffer +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x14102f23 ks0108_displaystate +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x48a70518 ks0108_writedata +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x4f506333 ks0108_startline +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0x6edae968 ks0108_isinited +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xbf4774db ks0108_writecontrol +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xedde6df2 ks0108_page +EXPORT_SYMBOL_GPL drivers/auxdisplay/ks0108 0xfee8ef7b ks0108_address +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x01521c1d tpm_continue_selftest +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x0f53e82f tpm_show_enabled +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1b4ffedc tpm_show_pubek +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x1f44f9eb tpm_pm_resume +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x221a341c tpm_dev_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x25a26343 tpm_show_caps_1_2 +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x28cb941d tpm_gen_interrupt +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x2e58e1da tpm_read +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x45fcd352 tpm_show_temp_deactivated +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x4ac1b9aa tpm_register_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x645fb111 tpm_show_owned +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x64952ed6 tpm_remove_hardware +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x65369496 tpm_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x6a7ef9d6 tpm_dev_vendor_release +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x6b817cc9 tpm_calc_ordinal_duration +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x6bc82d96 tpm_show_pcrs +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x70376287 tpm_store_cancel +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x7ff16e43 tpm_open +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x8150de28 tpm_write +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0x9685a546 tpm_show_caps +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa635a89f tpm_get_timeouts +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xa638b9e5 tpm_pm_suspend +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm 0xafaa8f43 tpm_show_active +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0x4c74f794 tpm_bios_log_setup +EXPORT_SYMBOL_GPL drivers/char/tpm/tpm_bios 0xd9d89bf4 tpm_bios_log_teardown +EXPORT_SYMBOL_GPL drivers/dca/dca 0x28f12408 dca3_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x2e471f01 dca_register_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x31a2c8df dca_get_tag +EXPORT_SYMBOL_GPL drivers/dca/dca 0x8006c614 dca_unregister_notify +EXPORT_SYMBOL_GPL drivers/dca/dca 0x9c555a61 unregister_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xb575212e dca_remove_requester +EXPORT_SYMBOL_GPL drivers/dca/dca 0xc6989265 free_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xd8d79dbe register_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xe1528c60 alloc_dca_provider +EXPORT_SYMBOL_GPL drivers/dca/dca 0xf5f54a23 dca_add_requester +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x033d6be9 edac_device_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x0d1f088f edac_mc_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x4cd46c22 edac_pci_handle_npe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x5a145d6a edac_device_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x64c98c40 edac_mc_handle_ce_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x696deff3 edac_mc_find_csrow_by_page +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8098b7f8 edac_mc_handle_ue_no_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x853d58f7 edac_device_handle_ce +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8c78199c edac_mc_alloc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8dd14f13 edac_device_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x8e392436 edac_pci_release_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x9688e1b2 edac_mc_add_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0x9f208fca edac_pci_handle_pe +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xa2887eb6 edac_pci_alloc_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xb9952ab7 edac_pci_reset_delay_period +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd233c7da edac_mc_del_mc +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd349c1f3 edac_pci_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xd5687ea1 edac_device_add_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xdafdc70e edac_pci_del_device +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf0cbf304 edac_mc_handle_ue +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf22be988 edac_pci_create_generic_ctl +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf6d117be edac_pci_free_ctl_info +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf92c3027 edac_mc_free +EXPORT_SYMBOL_GPL drivers/edac/edac_core 0xf956ecbf edac_device_free_ctl_info +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x01fd453e usbhid_lookup_quirk +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x21b55ddb hiddev_hid_event +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0x9282a98f usbhid_set_leds +EXPORT_SYMBOL_GPL drivers/hid/usbhid/usbhid 0xfb685c9f usbhid_submit_report +EXPORT_SYMBOL_GPL drivers/i2c/busses/i2c-nforce2 0x822b7b43 nforce2_smbus +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xa0d9bb0c hpsb_config_rom_ip1394_add +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xc22bb034 hpsb_config_rom_ip1394_remove +EXPORT_SYMBOL_GPL drivers/ieee1394/ieee1394 0xec8d18cf hpsb_disable_irm +EXPORT_SYMBOL_GPL drivers/infiniband/hw/ipath/ib_ipath 0x1514b2b2 ipath_debug +EXPORT_SYMBOL_GPL drivers/input/ff-memless 0xee15c201 input_ff_create_memless +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x34b737f7 wm97xx_reg_write +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x52833b6b wm9713_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x69a816b9 wm97xx_get_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x839726af wm9705_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0x9e293bf5 wm9712_codec +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xa14cda92 wm97xx_read_aux_adc +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xb78fa1b8 wm97xx_set_suspend_mode +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xc457e356 wm97xx_config_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xd9eb0541 wm97xx_set_gpio +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xdaa7e144 wm97xx_register_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xed200a03 wm97xx_unregister_mach_ops +EXPORT_SYMBOL_GPL drivers/input/touchscreen/wm97xx-ts 0xf3d2ffcd wm97xx_reg_read +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x0bb7789a gigaset_freedriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x1f24a0cd gigaset_fill_inbuf +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x24900f6c gigaset_stop +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x2c0979ce gigaset_dbg_buffer +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x3aacf24b gigaset_blockdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x3b59c350 gigaset_add_event +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x454aa44f gigaset_debuglevel +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x50440084 gigaset_initdriver +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x60dda9f0 gigaset_freecs +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x6fd87eee gigaset_if_receive +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x70438266 gigaset_shutdown +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x8b3fe55d gigaset_skb_sent +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0x9e462954 gigaset_start +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa4c2f504 gigaset_m10x_send_skb +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa986e705 gigaset_handle_modem_response +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xa9b2868d gigaset_m10x_input +EXPORT_SYMBOL_GPL drivers/isdn/gigaset/gigaset 0xaeea5616 gigaset_initcs +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x0f5a72c9 led_classdev_suspend +EXPORT_SYMBOL_GPL drivers/leds/led-class 0x73413396 led_classdev_resume +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbac80395 led_classdev_unregister +EXPORT_SYMBOL_GPL drivers/leds/led-class 0xbdb0d224 led_classdev_register +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x04662e0f ir_codes_fusionhdtv_mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x07e92917 ir_codes_avermedia_a16d +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x083661f9 ir_codes_avertv_303 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x088631b9 ir_codes_behold +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x1cb148f5 ir_extract_bits +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2456e513 ir_decode_pulsedistance +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2816876a ir_input_init +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2a4852cc ir_codes_dntv_live_dvb_t +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x2af1a608 ir_codes_proteus_2309 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x3811daea ir_codes_manli +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x43c89ef4 ir_decode_biphase +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x45b08f68 ir_codes_pinnacle_grey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4740e7a3 ir_codes_empty +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4beb7618 ir_codes_encore_enltv_fm53 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x4ea698a2 ir_codes_purpletv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x55338dda ir_codes_pixelview_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x589cad50 ir_codes_apac_viewcomp +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x5db13554 ir_codes_encore_enltv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6606596a ir_rc5_timer_keyup +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6adc476d ir_codes_powercolor_real_angel +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6aefdbea ir_codes_npgtech +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6b87c69d ir_codes_iodata_bctv7e +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6d6511e7 ir_dump_samples +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x6e2a1870 ir_codes_adstech_dvb_t_pci +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x703953c7 ir_input_nokey +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7277973d ir_codes_pctv_sedna +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x75e89cc3 ir_codes_flydvb +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x772a30a2 ir_codes_nebula +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x7b38143b ir_codes_encore_enltv2 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x85d37490 ir_codes_dntv_live_dvbt_pro +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x89cc1189 ir_codes_winfast +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x902a3cd2 ir_codes_hauppauge_new +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x933d0bb3 ir_codes_msi_tvanywhere +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x9451e232 ir_codes_behold_columbus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0x96470cab ir_codes_cinergy +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb1f4eb35 ir_codes_avermedia_dvbt +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb50812de ir_codes_real_audio_220_32_keys +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xb6cd4666 ir_codes_eztv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbb08d146 ir_codes_msi_tvanywhere_plus +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xbdce6594 ir_codes_tt_1500 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc1fea0c1 ir_codes_pv951 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc42bd037 ir_codes_budget_ci_old +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xc6c5a7a1 ir_codes_em_terratec +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xcdf2859f ir_codes_avermedia_m135a +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd1e0258a ir_codes_flyvideo +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd55e6891 ir_codes_gotview7135 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xd9c7f010 ir_codes_rc5_tv +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdaa041ad ir_codes_cinergy_1400 +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xdfcf23df ir_codes_norwood +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xee2f5e0e ir_codes_pinnacle_pctv_hd +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf07533a1 ir_codes_videomate_tv_pvr +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf0fc9374 ir_codes_avermedia +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf2b421aa ir_codes_genius_tvgo_a11mce +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xf4f7a4d6 ir_rc5_timer_end +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfa177653 ir_codes_pixelview +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfb981300 ir_codes_pinnacle_color +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfba9ac56 ir_input_keydown +EXPORT_SYMBOL_GPL drivers/media/common/ir-common 0xfc54a5cd ir_codes_asus_pc39 +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x085a6a4b saa7146_i2c_adapter_prepare +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x1587d4d5 saa7146_vmalloc_build_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x1c61dd63 saa7146_register_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x3115a7d4 saa7146_pgtable_free +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x40a98dea saa7146_unregister_extension +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0x89d7a23c saa7146_vfree_destroy_pgtable +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xad70ec0f saa7146_pgtable_build_single +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xc98faf20 saa7146_devices_lock +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xcf683cf2 saa7146_devices +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xd7f90c7d saa7146_wait_for_debi_done +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xe3cd9b5c saa7146_debug +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xed9ededc saa7146_pgtable_alloc +EXPORT_SYMBOL_GPL drivers/media/common/saa7146 0xf8a245a0 saa7146_setgpio +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x20e87a68 saa7146_set_hps_source_and_sync +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x42cc7b8b saa7146_start_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x4ada37dc saa7146_vv_release +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0x82a02834 saa7146_vv_init +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xbfff4758 saa7146_unregister_device +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xd81e063c saa7146_stop_preview +EXPORT_SYMBOL_GPL drivers/media/common/saa7146_vv 0xf3d11f51 saa7146_register_device +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mt20xx 0xac915863 microtune_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/mxl5007t 0x227da997 mxl5007t_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda18271 0x97ac724a tda18271_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda827x 0x14dbda74 tda827x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x16477bc8 tda829x_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda8290 0x72f055e5 tda829x_probe +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tda9887 0xd60b9b0a tda9887_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0x5287a72b tea5761_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5761 0xcfc50be6 tea5761_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x29560f00 tea5767_attach +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tea5767 0x7af2dc49 tea5767_autodetection +EXPORT_SYMBOL_GPL drivers/media/common/tuners/tuner-simple 0xa05f58cb simple_tuner_attach +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x60dcbd28 ttpci_budget_init +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x69298f1f ttpci_budget_debiwrite +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x7948c222 budget_debug +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0x98ec76a9 ttpci_budget_set_video_port +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xa805ce96 ttpci_budget_deinit +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xb5549a85 ttpci_budget_init_hooks +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xc7003384 ttpci_budget_irq10_handler +EXPORT_SYMBOL_GPL drivers/media/dvb/ttpci/budget-core 0xcc06eef5 ttpci_budget_debiread +EXPORT_SYMBOL_GPL drivers/media/video/compat_ioctl32 0xaa40a8c2 v4l_compat_ioctl32 +EXPORT_SYMBOL_GPL drivers/media/video/cx88/cx88xx 0x606766ad cx88_setup_xc3028 +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x2007947c em28xx_set_mode +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x259d8132 em28xx_init_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x28e37bb1 em28xx_audio_analog_set +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x73ad47e0 em28xx_uninit_isoc +EXPORT_SYMBOL_GPL drivers/media/video/em28xx/em28xx 0x7fc8652c em28xx_tuner_callback +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x1bc5ffd3 saa7134_ts_qops +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x27a462d2 saa7134_g_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x4ee17ba2 saa7134_i2c_call_saa6752 +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0x68592aaf saa7134_queryctrl +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xac4f98c4 saa7134_s_std_internal +EXPORT_SYMBOL_GPL drivers/media/video/saa7134/saa7134 0xd056a3b4 saa7134_s_ctrl_internal +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x33a87b62 v4l2_int_ioctl_0 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x72aebfcf v4l2_int_device_unregister +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x7bbb11c7 v4l2_int_ioctl_1 +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0x85b8615f v4l2_int_device_register +EXPORT_SYMBOL_GPL drivers/media/video/v4l2-int-device 0xa5228b24 v4l2_int_device_try_attach_all +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x028ded1e videobuf_mmap_mapper +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x08070e43 videobuf_streamoff +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x15aac856 videobuf_read_one +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x2b1d2878 videobuf_poll_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x3c16f657 videobuf_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x41679d22 videobuf_mmap_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x5392b23f __videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x56569a22 videobuf_waiton +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x64f1fb59 videobuf_querybuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x682c60cd videobuf_dqbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x6ef2b478 videobuf_reqbufs +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x725f1d06 videobuf_queue_to_vmalloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x75a65ea5 videobuf_mmap_setup +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0x7871094a videobuf_read_start +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xa20e7a93 videobuf_read_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xaa18c639 videobuf_iolock +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xab0bd49d videobuf_read_stream +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb51d58a8 videobuf_stop +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xb9f6b2a0 videobuf_next_field +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xd8597a36 videobuf_queue_cancel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xdcf88226 videobuf_streamon +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe064cf39 videobuf_queue_core_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xe292d283 videobuf_cgmbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xec56e5e4 videobuf_queue_is_busy +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-core 0xf9bf1bc8 videobuf_qbuf +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x820b679e videobuf_dma_contig_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0x8ce3c2c4 videobuf_to_dma_contig +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-contig 0xdabb307c videobuf_queue_dma_contig_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x070921de videobuf_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x1e50017d videobuf_dma_init_user +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x2679493b videobuf_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x41099974 videobuf_sg_dma_map +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x4643d653 videobuf_dma_init_kernel +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x6e939ac9 videobuf_dma_init_overlay +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x82d920ba videobuf_queue_sg_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0x933dfb43 videobuf_vmalloc_to_sg +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa38faed2 videobuf_sg_alloc +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xa65e0da7 videobuf_dma_sync +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xaf92083c videobuf_to_dma +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xb9dd20d2 videobuf_dma_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xe728301d videobuf_sg_dma_unmap +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-dma-sg 0xedf0b2e2 videobuf_dma_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x43a07b69 videobuf_vmalloc_free +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0x6ef909b3 videobuf_queue_vmalloc_init +EXPORT_SYMBOL_GPL drivers/media/video/videobuf-vmalloc 0xf625a375 videobuf_to_vmalloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x1fc93f38 i2o_dma_map_single +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x427f9239 i2o_dma_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x7449fa91 i2o_pool_free +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8bfd28aa i2o_sg_tablesize +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0x8fd3ef7d i2o_pool_alloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xa408630a i2o_dma_map_sg +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xdecd4ca1 i2o_dma_realloc +EXPORT_SYMBOL_GPL drivers/message/i2o/i2o_core 0xf60f392d i2o_dma_alloc +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x35f6367c sm501_set_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x59192986 sm501_find_clock +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0x8ae6a23c sm501_modify_reg +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xb9df9876 sm501_misc_control +EXPORT_SYMBOL_GPL drivers/mfd/sm501 0xba066096 sm501_unit_power +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x07e11eed wm8350_reg_unlock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x095bcc29 wm8350_block_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x15ae2a89 wm8350_gpio_config +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x187c079f wm8350_mask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x21fe55ff wm8350_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x2f7facc0 wm8350_register_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0x878ede44 wm8350_clear_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xa56cc813 wm8350_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xabbf99ba wm8350_device_init +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xaca681a9 wm8350_reg_lock +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xaf11c285 wm8350_unmask_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xbb0a160d wm8350_block_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xdb0e7dda wm8350_reg_write +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xefa37765 wm8350_free_irq +EXPORT_SYMBOL_GPL drivers/mfd/wm8350 0xf89b2ef7 wm8350_device_exit +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x1b640edc wm8400_set_bits +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x2d23a5fb wm8400_reset_codec_reg_cache +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0x32e7eb2e wm8400_reg_read +EXPORT_SYMBOL_GPL drivers/mfd/wm8400-core 0xa03eb223 wm8400_block_read +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x2df115d4 eeprom_93cx6_multiread +EXPORT_SYMBOL_GPL drivers/misc/eeprom_93cx6 0x63d14d2f eeprom_93cx6_read +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x0777a7bb enclosure_remove_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x38a18ea8 enclosure_for_each_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x8978690d enclosure_find +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x90f9a7df enclosure_component_register +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0x98210099 enclosure_unregister +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xd369abf2 enclosure_add_device +EXPORT_SYMBOL_GPL drivers/misc/enclosure 0xdd30a8a6 enclosure_register +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x2293c8e0 gru_get_next_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x5927a880 gru_send_message_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x7e83f3fc gru_free_message +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x81b3b8e3 gru_create_message_queue +EXPORT_SYMBOL_GPL drivers/misc/sgi-gru/gru 0x9c7283a1 gru_copy_gpa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x345c9217 xpc_disconnect +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x39046c7a xpc_clear_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x43a01eea xpc_registrations +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x6285dfe8 xp_cpu_to_nasid +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x64ba5017 xp_pa +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x76e36d39 xp_region_size +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9823adb0 xpc_set_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0x9acd8cf8 xpc_interface +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xba3694f3 xp_remote_memcpy +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xead4f7fe xp_max_npartitions +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xf3b47f67 xp_partition_id +EXPORT_SYMBOL_GPL drivers/misc/sgi-xp/xp 0xfe709b6c xpc_connect +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x268152ce sdhci_alloc_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x74c89318 sdhci_suspend_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x88e96dbe sdhci_add_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0x89de8482 sdhci_remove_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xa01efc11 sdhci_resume_host +EXPORT_SYMBOL_GPL drivers/mmc/host/sdhci 0xac91e58b sdhci_free_host +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x6cd547f0 cfi_cmdset_0001 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0x9e98fcad cfi_cmdset_0200 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0001 0xf5913e7c cfi_cmdset_0003 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0002 0xb93302ba cfi_cmdset_0002 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_cmdset_0020 0xc4e0f044 cfi_cmdset_0020 +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xa6bed1c5 cfi_qry_mode_on +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xc5f4dcc6 cfi_qry_present +EXPORT_SYMBOL_GPL drivers/mtd/chips/cfi_util 0xccfbe182 cfi_qry_mode_off +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2000 0x2368b5ea DoC2k_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001 0x704103a1 DoCMil_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/doc2001plus 0x7209b2a0 DoCMilPlus_init +EXPORT_SYMBOL_GPL drivers/mtd/devices/docecc 0x45937659 doc_decode_ecc +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x105ab83c get_mtd_device_nm +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x1cfb41a2 get_sb_mtd +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x3d556e8e mtd_erase_callback +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x40363953 del_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x406d1f31 register_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x436392b8 deregister_mtd_parser +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x47697e41 mtd_table +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x6336be3b add_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x6fdd50c0 kill_mtd_super +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x7d4b0486 parse_mtd_partitions +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x868fd4bd unregister_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0x8c0eecb2 default_mtd_writev +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xa403b0d5 put_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xade33c5f get_mtd_device +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xea902073 register_mtd_user +EXPORT_SYMBOL_GPL drivers/mtd/mtd 0xeff64be1 mtd_table_mutex +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x228ceea6 add_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x4319183a del_mtd_blktrans_dev +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0x7047b246 register_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/mtd_blkdevs 0xe0d5d1e0 deregister_mtd_blktrans +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x30481940 nand_wait_ready +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x64f14b5c nand_release +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x760bd66f nand_scan +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0x7f38406b nand_scan_tail +EXPORT_SYMBOL_GPL drivers/mtd/nand/nand 0xc656ef51 nand_scan_ident +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x4ca59a01 onenand_scan +EXPORT_SYMBOL_GPL drivers/mtd/onenand/onenand 0x959013f9 onenand_release +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x0a9d9d2a ubi_leb_write +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x42801d20 ubi_sync +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x547e8265 ubi_close_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x593a6015 ubi_leb_change +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x5dbd3ad7 ubi_leb_erase +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x87cb0886 ubi_open_volume_nm +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0x8cb07575 ubi_leb_read +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xbc505df4 ubi_get_device_info +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xd23e3773 ubi_open_volume +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xdbc3f62d ubi_is_mapped +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf0bca593 ubi_leb_unmap +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf10e443f ubi_leb_map +EXPORT_SYMBOL_GPL drivers/mtd/ubi/ubi 0xf802676f ubi_get_volume_info +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0c34e52e mlx4_free_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d1ffc23 mlx4_unregister_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d61c3a2 mlx4_buf_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0d84b31d mlx4_db_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x0fc6643d mlx4_alloc_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x1dadc924 mlx4_cq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2376c32b mlx4_register_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x265975b8 mlx4_srq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x2c3f4f18 mlx4_srq_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x32f97ac5 mlx4_srq_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x33e15ee5 mlx4_qp_reserve_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x39b08a0d mlx4_CLOSE_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e01c338 mlx4_INIT_PORT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x3e9f0f69 mlx4_buf_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x41ae37a7 mlx4_fmr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5179ceb1 mlx4_fmr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x530598b6 mlx4_qp_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x547a5a0d mlx4_write_mtt +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5492704c mlx4_multicast_detach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x57081571 mlx4_cq_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x59198627 mlx4_qp_to_ready +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x5b40ac08 mlx4_map_phys_fmr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x65e2573f mlx4_fmr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6b3a6d90 mlx4_qp_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6c288f36 mlx4_mtt_init +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6c3c4817 mlx4_cq_resize +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x6dfc6f95 mlx4_qp_remove +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x7176a3d3 mlx4_buf_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x76e49be9 mlx4_multicast_attach +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x781305fe mlx4_qp_release_range +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x78b636f1 mlx4_uar_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x853bc27f mlx4_SYNC_TPT +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x91877bd4 mlx4_cq_modify +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x95424208 mlx4_unregister_mac +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9833505d mlx4_mr_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0x9cd1ec57 mlx4_mr_enable +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa56f3812 mlx4_mtt_cleanup +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xa9bfc610 mlx4_qp_query +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xabd9402b mlx4_pd_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbd11a45f mlx4_db_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xbf96a560 mlx4_srq_arm +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xc966dbe6 mlx4_free_cmd_mailbox +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xcb42adf5 mlx4_qp_alloc +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xccb2c3a5 __mlx4_cmd +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xe3cf82d0 mlx4_register_interface +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea210cd4 mlx4_pd_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xea2224e0 mlx4_mr_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xece2073c mlx4_alloc_hwq_res +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf33437a8 mlx4_uar_free +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf5487691 mlx4_mtt_addr +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf8a90d04 mlx4_unregister_vlan +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xf9b4e7ca mlx4_fmr_unmap +EXPORT_SYMBOL_GPL drivers/net/mlx4/mlx4_core 0xff3487ea mlx4_register_vlan +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x06f79aef usbnet_generic_cdc_bind +EXPORT_SYMBOL_GPL drivers/net/usb/cdc_ether 0x9e3c0e3c usbnet_cdc_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x20ee54b1 rndis_rx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x3a48fbc0 generic_rndis_bind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0x5de4ff14 rndis_unbind +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xb842eb2d rndis_command +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xdd4d421c rndis_status +EXPORT_SYMBOL_GPL drivers/net/usb/rndis_host 0xe38c0a55 rndis_tx_fixup +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x2afed2a3 usbnet_nway_reset +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x48f44dcf usbnet_disconnect +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x6377c73c usbnet_unlink_rx_urbs +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x729db97c usbnet_get_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0x80dfdcc1 usbnet_get_endpoints +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa0c044df usbnet_probe +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa4b6e4a1 usbnet_get_link +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xa8f88659 usbnet_set_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xaee17b6a usbnet_get_drvinfo +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb397762f usbnet_suspend +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb60ee515 usbnet_set_settings +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xb9169889 usbnet_skb_return +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xe6c70c3f usbnet_defer_kevent +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xeadf35cd usbnet_get_msglevel +EXPORT_SYMBOL_GPL drivers/net/usb/usbnet 0xfeb73f37 usbnet_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x16168fe6 lbs_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x4aef9f2e lbs_host_to_card_done +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x5c1a0adc lbs_host_sleep_cfg +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x715db28b lbs_cmd_802_11_rate_adapt_rateset +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x82cbe565 lbs_queue_event +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0x9ec44f11 lbs_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xadda9c81 lbs_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xb9f1e849 lbs_notify_command_response +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xccabc313 lbs_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xcd0f8514 __lbs_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xd5707398 lbs_stop_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xe43fc393 lbs_process_rxed_packet +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xeab3b096 lbs_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xf64277de lbs_debug +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xfc34eddd lbs_start_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas/libertas 0xff4c4c42 lbs_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x0135aa28 lbtf_add_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x292a3ec2 lbtf_send_tx_feedback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x46587c04 lbtf_bcn_sent +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x5b8417eb __lbtf_cmd +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0x8b90f618 lbtf_cmd_copyback +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xb8034ebe lbtf_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xb89ea397 lbtf_remove_card +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf 0xbe0392d8 lbtf_cmd_response_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x1484ee91 if_usb_reset_device +EXPORT_SYMBOL_GPL drivers/net/wireless/libertas_tf/libertas_tf_usb 0x57de90a4 if_usb_prog_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x33afb0dd p54_parse_firmware +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x50c0fb80 p54_rx +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0x61dfb005 p54_read_eeprom +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xc9090042 p54_free_common +EXPORT_SYMBOL_GPL drivers/net/wireless/p54/p54common 0xd3869b07 p54_init_common +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x12f276db rt2x00mac_get_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x1c045598 rt2x00mac_add_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x21e82e8c rt2x00lib_beacondone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x286545f1 rt2x00mac_remove_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x30f25231 rt2x00mac_bss_info_changed +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x37a40d6b rt2x00lib_remove_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3853238c rt2x00mac_start +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3d5f0ae5 rt2x00queue_get_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x3f0b7aef rt2x00lib_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x42aa7c1c rt2x00lib_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x4eff162f rt2x00queue_map_txskb +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x700eccfd rt2x00mac_get_tx_stats +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x724dff87 rt2x00lib_probe_dev +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0x74606e8f rt2x00mac_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xa79b2b97 rt2x00lib_txdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xb9aacd40 rt2x00mac_set_key +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xd0fe9a12 rt2x00lib_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe4f4f6c3 rt2x00mac_config_interface +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xe6211b32 rt2x00mac_stop +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xec9f8dfe rt2x00mac_conf_tx +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf5d6238c rt2x00mac_config +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xf81dea51 rt2x00mac_configure_filter +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00lib 0xfe7d469e rt2x00queue_get_entry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x0a9dc0b0 rt2x00pci_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x2f602cef rt2x00pci_rxdone +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x5e75ce86 rt2x00pci_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x66f9e36e rt2x00pci_resume +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0x68d1bf24 rt2x00pci_remove +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xf339f56b rt2x00pci_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xfb8735eb rt2x00pci_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00pci 0xfef5761a rt2x00pci_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x0695fbda rt2x00usb_vendor_req_buff_lock +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x08ce63d1 rt2x00usb_disconnect +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x15d2af25 rt2x00usb_uninitialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x29973098 rt2x00usb_init_rxentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x2f7db660 rt2x00usb_init_txentry +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x7361ac6f rt2x00usb_vendor_request +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x82dfe123 rt2x00usb_vendor_request_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0x87399741 rt2x00usb_suspend +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa23cf11b rt2x00usb_probe +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xa95688c7 rt2x00usb_vendor_request_large_buff +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xaea5776d rt2x00usb_disable_radio +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xb69a9ba4 rt2x00usb_write_tx_data +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xdb8e6128 rt2x00usb_kick_tx_queue +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xdbb969a5 rt2x00usb_initialize +EXPORT_SYMBOL_GPL drivers/net/wireless/rt2x00/rt2x00usb 0xf6f44a75 rt2x00usb_resume +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0x185b6e1c acpiphp_unregister_attention +EXPORT_SYMBOL_GPL drivers/pci/hotplug/acpiphp 0xc9de8ecb acpiphp_register_attention +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x31b92204 wm8350_register_regulator +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x52706573 wm8350_dcdc25_set_mode +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0x75c8a0eb wm8350_isink_set_flash +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xa298f954 wm8350_ldo_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8350-regulator 0xec24d0c6 wm8350_dcdc_set_slot +EXPORT_SYMBOL_GPL drivers/regulator/wm8400-regulator 0x4c7d86b6 wm8400_register_regulator +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x0233f349 iscsi_pool_init +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x1d26ee5c iscsi_eh_target_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x34e327af iscsi_eh_device_reset +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x35c7986d __iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x3b75783f iscsi_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x41ba1d14 iscsi_pool_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x46c388d8 iscsi_session_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x4aa9ee95 iscsi_session_recovery_timedout +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x57519ea2 iscsi_update_cmdsn +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x58b43ce1 iscsi_itt_to_ctask +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5b5636d1 iscsi_requeue_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5ca14e73 iscsi_host_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x5cca05a8 iscsi_conn_send_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x6a47876b iscsi_complete_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7075b4e3 iscsi_session_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x738af53e iscsi_put_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7894eb07 iscsi_session_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x7b070b3e iscsi_conn_bind +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x83dac8b8 iscsi_host_remove +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x84298257 iscsi_verify_itt +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x858eeb0a iscsi_conn_stop +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x87ef59fd iscsi_conn_setup +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x97d513ab __iscsi_get_task +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0x9bf53f34 iscsi_host_free +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xac4eb565 iscsi_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb1c3c45e iscsi_conn_teardown +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb7ebfdf1 iscsi_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb94263af iscsi_conn_start +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xb9c80053 iscsi_suspend_tx +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xba5face0 iscsi_conn_failure +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xba67f71c iscsi_host_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xbd374bf0 iscsi_conn_get_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xc259162e iscsi_host_set_param +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xe46aa1a3 iscsi_host_add +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xeb40fa3e iscsi_prep_unsolicit_data_pdu +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf4b458d3 iscsi_eh_abort +EXPORT_SYMBOL_GPL drivers/scsi/libiscsi 0xf8540630 iscsi_session_setup +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x0b8bf836 sas_phy_enable +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x133853c7 sas_slave_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2dbb3846 sas_bios_param +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x2e2b1858 sas_domain_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x37921014 sas_slave_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3c5cdb0e sas_queuecommand +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x3e3e7f37 sas_change_queue_type +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4be56004 sas_domain_attach_transport +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4c9a0672 sas_find_local_phy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x4d98d2ea sas_target_destroy +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x549870a7 sas_register_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x620984da sas_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x6d9a6fb4 sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x78107936 __sas_task_abort +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x7cb41202 sas_eh_bus_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x80a9b77e sas_phy_reset +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x80cdcb1f sas_change_queue_depth +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x887011f6 sas_unregister_ha +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x91ab44f3 sas_ioctl +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0x9e7a595d sas_ssp_task_response +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xb3eee442 sas_slave_configure +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xe1d28daf sas_eh_device_reset_handler +EXPORT_SYMBOL_GPL drivers/scsi/libsas/libsas 0xfae6209c sas_request_addr +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x63cbf8ff srp_target_alloc +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x6fc79cd3 srp_iu_put +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0x7ebd7ecd srp_iu_get +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xaa71b248 srp_target_free +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xc2e2d795 srp_transfer_data +EXPORT_SYMBOL_GPL drivers/scsi/libsrp 0xef4c7cab srp_cmd_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x0d3aaf60 scsi_tgt_tsk_mgmt_request +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x2a180412 scsi_tgt_it_nexus_destroy +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x2a9ddce3 scsi_tgt_queue_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x3b62d8e0 scsi_host_get_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x7582c268 scsi_tgt_cmd_to_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x90ec9ca4 scsi_tgt_free_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0x9b8cb09c scsi_tgt_it_nexus_create +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xb82af24a scsi_tgt_alloc_queue +EXPORT_SYMBOL_GPL drivers/scsi/scsi_tgt 0xe4551492 scsi_host_put_command +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x0d2f06ca iscsi_destroy_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x20951f5f iscsi_free_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x25e6e56c iscsi_create_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x2942ba3c iscsi_recv_pdu +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x5fb27155 iscsi_session_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x689779ef iscsi_create_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x68f61758 iscsi_session_chkready +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x7d3fca42 iscsi_host_for_each_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x854ecff2 iscsi_destroy_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0x94be649e iscsi_register_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xa5fe1422 iscsi_lookup_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc0cfa10b iscsi_create_conn +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xc7db9bac iscsi_add_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xce3ca31d iscsi_unregister_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xd3d9d020 iscsi_block_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xe3b58ace iscsi_alloc_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf33b106f iscsi_scan_finished +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf78655d5 iscsi_unblock_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf866cd9c iscsi_remove_session +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xf9aea7b7 iscsi_destroy_endpoint +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_iscsi 0xfa2a12bf iscsi_conn_error_event +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0x0ef06974 spi_populate_ppr_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xa0c71dac spi_populate_sync_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_spi 0xcffa2aff spi_populate_width_msg +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x27c3f20f srp_remove_host +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x67023903 srp_rport_del +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x68a3af38 srp_rport_add +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0x9e340c70 srp_release_transport +EXPORT_SYMBOL_GPL drivers/scsi/scsi_transport_srp 0xe7770a14 srp_attach_transport +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x2dd5893d spi_bitbang_setup_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x50c9b431 spi_bitbang_setup +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x79abc0cc spi_bitbang_stop +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0x81c0180e spi_bitbang_start +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xbd0935ea spi_bitbang_transfer +EXPORT_SYMBOL_GPL drivers/spi/spi_bitbang 0xe670adac spi_bitbang_cleanup +EXPORT_SYMBOL_GPL drivers/uio/uio 0x13186007 uio_unregister_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0x44171087 __uio_register_device +EXPORT_SYMBOL_GPL drivers/uio/uio 0x861aafcc uio_event_notify +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x36280474 usbatm_usb_probe +EXPORT_SYMBOL_GPL drivers/usb/atm/usbatm 0x92743959 usbatm_usb_disconnect +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x3d5aeecc usb_ftdi_elan_edset_output +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x47225c28 usb_ftdi_elan_write_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x619eb03a usb_ftdi_elan_edset_setup +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x629386ed usb_ftdi_elan_edset_empty +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x90e68dc1 usb_ftdi_elan_edset_input +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0x955a7869 ftdi_elan_gone_away +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xba6d5a26 usb_ftdi_elan_read_pcimem +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xcda969ad usb_ftdi_elan_edset_flush +EXPORT_SYMBOL_GPL drivers/usb/misc/ftdi-elan 0xe60c0775 usb_ftdi_elan_edset_single +EXPORT_SYMBOL_GPL drivers/usb/misc/phidget 0x11443006 phidget_class +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x122f15ac wa_urb_enqueue_run +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0x4f27347b wa_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xb72719fa wa_urb_dequeue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xbd067c35 rpipe_ep_disable +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xcb55ad58 rpipe_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xd4d61ef8 __wa_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusb-wa 0xe834bc82 wa_urb_enqueue +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x09b00a96 wusbhc_rh_control +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x09f01407 wusbhc_handle_dn +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0bb6bf5e wusb_cluster_id_get +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x0fb0d58b wusbhc_reset_all +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x31df11a4 wusbhc_rh_start_port_reset +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x3fc450be wusbhc_b_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x67e277a4 wusbhc_rh_resume +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x6ea0c1d3 __wusb_dev_get_by_usb_dev +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x7f0b7631 wusb_dev_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x806814c4 wusbhc_b_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x8fea766c wusbhc_chid_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x90f6658b wusbhc_create +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x983af7a6 wusbhc_destroy +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0x999d7ac1 wusbhc_rh_status_data +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa610d1bc wusbhc_giveback_urb +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xa96df458 wusbhc_stop +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xb725d128 wusb_cluster_id_put +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xc00d185c wusbhc_rh_suspend +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xcc562985 wusbhc_mmcie_rm +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xe717bb54 wusbhc_mmcie_set +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xf770a6b4 wusbd +EXPORT_SYMBOL_GPL drivers/usb/wusbcore/wusbcore 0xfe2e17d7 wusb_et_name +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0x89353975 i1480_fw_upload +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xb5d3791c i1480_rceb_check +EXPORT_SYMBOL_GPL drivers/uwb/i1480/dfu/i1480-dfu-usb 0xbe1e6d10 i1480_cmd +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x184ae104 uwb_ack_policy_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x4fea41b0 uwb_phy_rate_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x629af4ac uwb_ack_policy_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x6b78ce6b uwb_rts_cts_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0x7e37e9d8 uwb_phy_rate_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xa6074e56 uwb_pca_base_priority_show +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xde1a063c uwb_pca_base_priority_store +EXPORT_SYMBOL_GPL drivers/uwb/i1480/i1480u-wlp/i1480u-wlp 0xfdf789d7 uwb_rts_cts_show +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x44501c9e umc_device_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x55212a1f umc_device_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9c38507d umc_match_pci_id +EXPORT_SYMBOL_GPL drivers/uwb/umc 0x9cce3f63 umc_driver_unregister +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xaeadc5b7 umc_bus_type +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xbae3dba9 umc_controller_reset +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xf1ac24d2 __umc_driver_register +EXPORT_SYMBOL_GPL drivers/uwb/umc 0xfe831d27 umc_device_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x0ccb5b3a uwb_rc_vcmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x1d5cc8d3 uwb_bg_joined +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x22a6d823 uwb_rc_cmd_async +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x262dbf90 uwb_est_find_size +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x2ca10493 uwb_rsv_create +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x3ad6dfa8 uwb_rc_put +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x45f41cb0 uwb_rc_ie_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x487aa8e0 uwb_rc_neh_error +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x499cbe01 uwb_rc_alloc +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4a65b2ee uwb_pal_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4c1c4dea uwb_rc_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x4d57ae3c uwb_rsv_type_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x54a30a9a uwb_rc_init +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x5a1a5f78 uwb_rsv_terminate +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6625c91d dump_bytes +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6b9377c5 uwb_ie_next +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6c520475 uwb_rsv_accept +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x6ef9c4c4 uwb_rc_mac_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7367dfcc uwb_rsv_modify +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x7613c0e2 uwb_rsv_state_str +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x80e5fccc uwb_rc_ie_add +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85b780e3 uwb_pal_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x85de05ea uwb_ie_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x879baead uwb_rc_get_by_grandpa +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8cb42db6 __uwb_addr_print +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8e2d74dc uwb_notifs_deregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x8fde6d5a uwb_rsv_establish +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9024117b uwb_notifs_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9058988e uwb_dev_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0x9a970122 uwb_rc_get_by_dev +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa4f8bc8c uwb_ie_dump_hex +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xa9d1f3c4 __uwb_rc_try_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaaf6cdc5 uwb_rsv_destroy +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xaed6ccee uwb_rc_dev_addr_get +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xb7c8c825 uwb_rc_cmd +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xbf6a1b3d uwb_rc_get_ie +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xc348d995 uwb_pal_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xdac98b7c uwb_rc_rm +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xe6077cba uwb_rc_neh_grok +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xeb4cab9a uwb_est_register +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xefddc9f6 uwb_dev_for_each +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xf7ca313a uwb_est_unregister +EXPORT_SYMBOL_GPL drivers/uwb/uwb 0xfd2c2f1e uwb_rc_add +EXPORT_SYMBOL_GPL drivers/uwb/whci 0xf52983e0 whci_wait_for +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x138cb4c9 wlp_eda_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x1774f10a wlp_neighborhood_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x23c22d99 wlp_dev_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x24c096ad wlp_dev_model_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x257a57cc wlp_dev_manufacturer_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x29321f9d wlp_dev_prim_OUI_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3add81e1 wlp_dev_model_nr_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3b64408e wlp_dev_manufacturer_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x3e7c2cf7 wlp_receive_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x4386cf35 wlp_dev_serial_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x50725233 wlp_dev_prim_OUI_sub_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x51ad4df5 wlp_wss_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x6722790d wlp_wss_activate_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x709d65bd wlp_dev_prim_subcat_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x72eb28c8 wlp_dev_model_nr_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7568b56a wlp_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7b6a5f8e wlp_dev_serial_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x7dc0c966 wlp_dev_prim_category_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x8b8cb893 wlp_uuid_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x94b585af wlp_prepare_tx_frame +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9909935f wlp_wss_activate_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9abccd13 wlp_dev_prim_category_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0x9d208efd wlp_setup +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xbdc0ddef wlp_eda_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd6a17b5e wlp_uuid_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xd8450ff3 wlp_dev_name_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xdbe6ab27 wlp_dev_prim_subcat_store +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xe7af5f47 wlp_dev_model_name_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf5d5075e wlp_wss_remove +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf8402c05 wlp_dev_prim_OUI_sub_show +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xf8526cde wlp_reset_all +EXPORT_SYMBOL_GPL drivers/uwb/wlp/wlp 0xfc7f743f wlp_dev_prim_OUI_show +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x189b3630 ili9320_remove +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x21cf84ab ili9320_write +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0x5e908620 ili9320_resume +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xce31f0fd ili9320_suspend +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe621f381 ili9320_shutdown +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xe9e5f1bf ili9320_probe_spi +EXPORT_SYMBOL_GPL drivers/video/backlight/ili9320 0xfbc8b3ae ili9320_write_regs +EXPORT_SYMBOL_GPL drivers/video/fb_ddc 0x3adb8a7a fb_ddc_read +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xd0c3bc68 fb_sys_write +EXPORT_SYMBOL_GPL drivers/video/fb_sys_fops 0xd8d2bc77 fb_sys_read +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0xb9430f3f sis_free_new +EXPORT_SYMBOL_GPL drivers/video/sis/sisfb 0xf2e04965 sis_malloc_new +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x016e6c20 vmlfb_unregister_subsys +EXPORT_SYMBOL_GPL drivers/video/vermilion/vmlfb 0x90c018c6 vmlfb_register_subsys +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x1bf1bae0 virtio_check_driver_offered_feature +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x36c04a91 register_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x7176ad10 unregister_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0x74c0608e register_virtio_driver +EXPORT_SYMBOL_GPL drivers/virtio/virtio 0xfcdd6498 unregister_virtio_device +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x03c4687d vring_interrupt +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x4f924c62 vring_del_virtqueue +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x67d130a2 vring_transport_features +EXPORT_SYMBOL_GPL drivers/virtio/virtio_ring 0x7274b59b vring_new_virtqueue +EXPORT_SYMBOL_GPL drivers/w1/wire 0x0472e1dc w1_reset_bus +EXPORT_SYMBOL_GPL drivers/w1/wire 0x3c93f792 w1_write_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x5e2d88f7 w1_write_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x7c2f2afb w1_calc_crc8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0x90a52159 w1_read_block +EXPORT_SYMBOL_GPL drivers/w1/wire 0x9f1117d5 w1_read_8 +EXPORT_SYMBOL_GPL drivers/w1/wire 0xdba68dd7 w1_reset_select_slave +EXPORT_SYMBOL_GPL drivers/w1/wire 0xddb5bcb3 w1_next_pullup +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x009bc27c dlm_posix_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x5a87e727 dlm_posix_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x69113ce4 dlm_posix_get +EXPORT_SYMBOL_GPL fs/dlm/dlm 0x9321df95 dlm_lock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xcf9f3328 dlm_release_lockspace +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdc583c08 dlm_unlock +EXPORT_SYMBOL_GPL fs/dlm/dlm 0xdf3c14de dlm_new_lockspace +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0x17cca875 exportfs_decode_fh +EXPORT_SYMBOL_GPL fs/exportfs/exportfs 0xdd0dc0f2 exportfs_encode_fh +EXPORT_SYMBOL_GPL fs/fat/fat 0x05b6f71d fat_detach +EXPORT_SYMBOL_GPL fs/fat/fat 0x26812cb5 fat_free_clusters +EXPORT_SYMBOL_GPL fs/fat/fat 0x2fcb4aae fat_search_long +EXPORT_SYMBOL_GPL fs/fat/fat 0x570053a4 fat_dir_empty +EXPORT_SYMBOL_GPL fs/fat/fat 0x5791d305 fat_build_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x6dfc6082 fat_getattr +EXPORT_SYMBOL_GPL fs/fat/fat 0x7015d2f8 fat_add_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0x73e960a6 fat_fs_panic +EXPORT_SYMBOL_GPL fs/fat/fat 0x7b71ed4b fat_sync_inode +EXPORT_SYMBOL_GPL fs/fat/fat 0x7d5d79fe fat_flush_inodes +EXPORT_SYMBOL_GPL fs/fat/fat 0x92e003b1 fat_get_dotdot_entry +EXPORT_SYMBOL_GPL fs/fat/fat 0xa2157453 fat_remove_entries +EXPORT_SYMBOL_GPL fs/fat/fat 0xc34010e3 fat_alloc_new_dir +EXPORT_SYMBOL_GPL fs/fat/fat 0xc3401568 fat_fill_super +EXPORT_SYMBOL_GPL fs/fat/fat 0xcac6e9f7 fat_attach +EXPORT_SYMBOL_GPL fs/fat/fat 0xed4dbbef fat_setattr +EXPORT_SYMBOL_GPL fs/fat/fat 0xf913f87b fat_scan +EXPORT_SYMBOL_GPL fs/fat/fat 0xf9526ace fat_time_unix2fat +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x58a66091 gfs2_unregister_lockproto +EXPORT_SYMBOL_GPL fs/gfs2/gfs2 0x9f71f6c2 gfs2_register_lockproto +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x01a2527e nlmclnt_proc +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x17ce645d locks_end_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x1a618932 nlmsvc_unlock_all_by_ip +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x48ad1642 nlmclnt_init +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x6f959b35 locks_in_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x7ca542b7 nlmclnt_done +EXPORT_SYMBOL_GPL fs/lockd/lockd 0x96877ac4 locks_start_grace +EXPORT_SYMBOL_GPL fs/lockd/lockd 0xadc1fb94 nlmsvc_unlock_all_by_sb +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1b89c6ee o2hb_fill_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x1d747ce3 o2hb_check_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x36418553 o2net_send_message +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x47717e97 o2nm_get_node_by_num +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x4900035b o2hb_stop_all_regions +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x521e0726 o2net_send_message_vec +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x68430423 o2hb_setup_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x71cd3833 o2nm_node_get +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0x81a17396 mlog_and_bits +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa82a8645 o2nm_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xa87bc9e7 o2nm_configured_node_map +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xae808bac o2net_register_handler +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xbaeb4700 o2hb_check_node_heartbeating_from_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xc639b96c o2hb_register_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xd60f2c6c o2hb_check_local_node_heartbeating +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xe620dac6 o2nm_get_node_by_ip +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xe91ec6dc o2hb_unregister_callback +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xeebf147d o2nm_node_put +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf1a5611d o2net_unregister_handler_list +EXPORT_SYMBOL_GPL fs/ocfs2/cluster/ocfs2_nodemanager 0xf56c2017 mlog_not_bits +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x082b1776 dlm_register_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x1c7e3428 dlmunlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x62cd9de9 dlm_register_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0x7a1211f8 dlm_setup_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xa436114a dlmlock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xcbc0b1f5 dlm_print_one_lock +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd7ba575e dlm_errmsg +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xd8fa57a6 dlm_unregister_eviction_cb +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfa3ec9ea dlm_unregister_domain +EXPORT_SYMBOL_GPL fs/ocfs2/dlm/ocfs2_dlm 0xfb86b96f dlm_errname +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0562c415 ocfs2_cluster_this_node +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x0e27f909 ocfs2_dlm_lock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x21db5b88 ocfs2_cluster_disconnect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x2d4a8243 ocfs2_stack_glue_unregister +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4a1f6fe9 ocfs2_cluster_connect +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x4d3af7fa ocfs2_cluster_hangup +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x81c85a68 ocfs2_dlm_lock_status +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x91fab465 ocfs2_dlm_lvb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x963932a3 ocfs2_stack_glue_set_locking_protocol +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0x9ed86d1c ocfs2_stack_glue_register +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xa7d5c1c0 ocfs2_dlm_unlock +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xbbc4ef97 ocfs2_stack_supports_plocks +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xd066711e ocfs2_dlm_dump_lksb +EXPORT_SYMBOL_GPL fs/ocfs2/ocfs2_stackglue 0xe5930098 ocfs2_plock +EXPORT_SYMBOL_GPL lib/lzo/lzo_compress 0x2e1d43cf lzo1x_1_compress +EXPORT_SYMBOL_GPL lib/lzo/lzo_decompress 0x2a1538ca lzo1x_decompress_safe +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x300d7e57 free_rs +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0x6fbb3bd9 init_rs_non_canonical +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xabda1e2e decode_rs16 +EXPORT_SYMBOL_GPL lib/reed_solomon/reed_solomon 0xb050f329 init_rs +EXPORT_SYMBOL_GPL net/802/garp 0x328be6ba garp_unregister_application +EXPORT_SYMBOL_GPL net/802/garp 0x8538ab11 garp_init_applicant +EXPORT_SYMBOL_GPL net/802/garp 0x8bd9ecf3 garp_request_join +EXPORT_SYMBOL_GPL net/802/garp 0xa876d91f garp_register_application +EXPORT_SYMBOL_GPL net/802/garp 0xdc584bd5 garp_uninit_applicant +EXPORT_SYMBOL_GPL net/802/garp 0xe10f5703 garp_request_leave +EXPORT_SYMBOL_GPL net/802/stp 0x64d7d18c stp_proto_unregister +EXPORT_SYMBOL_GPL net/802/stp 0x68404fa6 stp_proto_register +EXPORT_SYMBOL_GPL net/ax25/ax25 0xac93ae05 ax25_bcast +EXPORT_SYMBOL_GPL net/ax25/ax25 0xaeb7451e ax25_defaddr +EXPORT_SYMBOL_GPL net/ax25/ax25 0xd50d4509 ax25_register_pid +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x09c5ed3c tfrc_tx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x0a487ea5 tfrc_calc_x +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x106fe6d3 tfrc_tx_hist_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x1c37b8e7 tfrc_rx_handle_loss +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x3539011c tfrc_lh_update_i_mean +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x69ec5731 tfrc_tx_hist_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x6c252d29 tfrc_calc_x_reverse_lookup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x7712c750 tfrc_lh_interval_add +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x8dffdb8b tfrc_rx_hist_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x902206f0 tfrc_lh_cleanup +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0x92285650 tfrc_rx_hist_alloc +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xbc57b83c tfrc_rx_hist_duplicate +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xc612a5b6 tfrc_rx_hist_purge +EXPORT_SYMBOL_GPL net/dccp/ccids/lib/dccp_tfrc_lib 0xec262634 tfrc_rx_hist_add_packet +EXPORT_SYMBOL_GPL net/dccp/dccp 0x00e407da dccp_insert_option_elapsed_time +EXPORT_SYMBOL_GPL net/dccp/dccp 0x08f75ce9 dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x10604202 ccid_register +EXPORT_SYMBOL_GPL net/dccp/dccp 0x15829cda dccp_feat_confirm_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x164eb3b4 dccp_disconnect +EXPORT_SYMBOL_GPL net/dccp/dccp 0x1d99d49a dccp_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0x21a5a964 dccp_reqsk_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x23a08b77 dccp_send_ack +EXPORT_SYMBOL_GPL net/dccp/dccp 0x24af1201 dccp_destroy_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x258e1cd5 dccp_create_openreq_child +EXPORT_SYMBOL_GPL net/dccp/dccp 0x29a9d61d dccp_rcv_established +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2b42c986 ccid_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x2fd38ce3 dccp_done +EXPORT_SYMBOL_GPL net/dccp/dccp 0x30009d95 dccp_init_sock +EXPORT_SYMBOL_GPL net/dccp/dccp 0x333b0ea3 dccp_sync_mss +EXPORT_SYMBOL_GPL net/dccp/dccp 0x364fa7db dccp_make_response +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3a35ec98 dccp_feat_clone +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3af61004 dccp_sendmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x3b3c0b1b dccp_feat_clean +EXPORT_SYMBOL_GPL net/dccp/dccp 0x487d9086 dccp_poll +EXPORT_SYMBOL_GPL net/dccp/dccp 0x489894b2 dccp_ctl_make_reset +EXPORT_SYMBOL_GPL net/dccp/dccp 0x4d8db45a ccid_hc_tx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0x56ea266a dccp_state_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x5fd9fd42 dccp_insert_option +EXPORT_SYMBOL_GPL net/dccp/dccp 0x76de2339 ccid_hc_tx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0x81c76c7a compat_dccp_getsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x849b89ed dccp_recvmsg +EXPORT_SYMBOL_GPL net/dccp/dccp 0x86be7924 dccp_packet_name +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8ae29230 dccp_parse_options +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8b7d8caf dccp_statistics +EXPORT_SYMBOL_GPL net/dccp/dccp 0x8d74230c dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0x91693d0c dccp_reqsk_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0x91a009cc dccp_feat_change_recv +EXPORT_SYMBOL_GPL net/dccp/dccp 0x98a17352 dccp_set_state +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9d6a3846 dccp_orphan_count +EXPORT_SYMBOL_GPL net/dccp/dccp 0x9df933c4 dccp_shutdown +EXPORT_SYMBOL_GPL net/dccp/dccp 0xa9c98065 dccp_hashinfo +EXPORT_SYMBOL_GPL net/dccp/dccp 0xb328f65c dccp_insert_option_timestamp +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbcd811a4 ccid_unregister +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbe4cf010 dccp_feat_init +EXPORT_SYMBOL_GPL net/dccp/dccp 0xbf6b58ba dccp_feat_change +EXPORT_SYMBOL_GPL net/dccp/dccp 0xc76584af dccp_ioctl +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdb18dbf1 dccp_connect +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdbfeb328 ccid_hc_rx_delete +EXPORT_SYMBOL_GPL net/dccp/dccp 0xdd798a49 dccp_rcv_state_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe3eccdd1 ccid_hc_rx_new +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe411230c dccp_child_process +EXPORT_SYMBOL_GPL net/dccp/dccp 0xe508f80b dccp_close +EXPORT_SYMBOL_GPL net/dccp/dccp 0xea83645f inet_dccp_listen +EXPORT_SYMBOL_GPL net/dccp/dccp 0xec356935 dccp_check_req +EXPORT_SYMBOL_GPL net/dccp/dccp 0xed835ce6 dccp_send_sync +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf50ca884 compat_dccp_setsockopt +EXPORT_SYMBOL_GPL net/dccp/dccp 0xf8fdfb5a dccp_death_row +EXPORT_SYMBOL_GPL net/dccp/dccp 0xfe4952c5 dccp_sample_rtt +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x2b8bd5a9 dccp_v4_connect +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x3a41ef9a dccp_v4_conn_request +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x3cc69885 dccp_v4_request_recv_sock +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x4cdd6ded dccp_invalid_packet +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0x9010bf49 dccp_v4_send_check +EXPORT_SYMBOL_GPL net/dccp/dccp_ipv4 0xd1cdf38c dccp_v4_do_rcv +EXPORT_SYMBOL_GPL net/ieee80211/ieee80211 0x92230f26 ieee80211_rx_any +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x2c57af41 nf_nat_seq_adjust_hook +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_conntrack_ipv4 0x6d40a921 need_ipv4_conntrack +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_defrag_ipv4 0x6b6c3d10 nf_defrag_ipv4_enable +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07ae60b6 nf_nat_proto_in_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x07be8c33 nf_nat_icmp_reply_translation +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x59c3072f nf_nat_proto_unique_tuple +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x65000330 nf_nat_packet +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x6645954b nf_nat_proto_put +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0x94a08134 nf_nat_proto_nlattr_to_range +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xc83d57ae nf_nat_proto_range_to_nlattr +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat 0xf97cb62c nf_nat_proto_find_get +EXPORT_SYMBOL_GPL net/ipv4/netfilter/nf_nat_proto_gre 0x636b12c8 nf_nat_need_gre +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x8f7b44a8 tcp_vegas_cwnd_event +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0x931a8507 tcp_vegas_get_info +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xb07d010e tcp_vegas_pkts_acked +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xd346a3e9 tcp_vegas_init +EXPORT_SYMBOL_GPL net/ipv4/tcp_vegas 0xe3ffa1cc tcp_vegas_state +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0x93a8db03 ieee80211_iterate_active_interfaces +EXPORT_SYMBOL_GPL net/mac80211/mac80211 0xdfc2159e ieee80211_iterate_active_interfaces_atomic +EXPORT_SYMBOL_GPL net/netfilter/ipvs/ip_vs 0xe6476b4a net_vs_ctl_path +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x005d8343 nf_conntrack_l4proto_udp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0219f067 nf_ct_unlink_expect +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0272305a nf_conntrack_helper_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x041013fd nf_conntrack_lock +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x045072cd nf_ct_port_nla_policy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0522d7c0 nf_conntrack_l4proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x0ca491ed __nf_conntrack_confirm +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x124612c4 __nf_ct_expect_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x1283d711 nf_ct_expect_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x15c10b0b nf_conntrack_unregister_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x16689d42 nf_ct_l4proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x194bd879 __nf_conntrack_helper_find_byname +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x23803a2b nf_conntrack_l3proto_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x326be1c1 nf_conntrack_l4proto_udp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38630158 nf_conntrack_tuple_taken +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38c9440b nf_ct_extend_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x38e28bb0 nf_conntrack_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3e57620c nf_ct_expect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x3f5b1415 nf_ct_port_nlattr_to_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x40387ccf __nf_ct_event_cache_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5395a9e9 nf_conntrack_tcp_update +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x5a871abe nf_ct_expect_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x658bba8a __nf_ct_helper_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x6e224a7a need_conntrack +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x700d1765 seq_print_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x72836f4a nf_conntrack_free +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x77aadb54 nf_conntrack_alter_reply +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x78f9b710 nf_ct_l3proto_try_module_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x79ca2e53 nf_ct_expect_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7a4db985 nf_ct_expect_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x7f8891d2 nf_ct_port_tuple_to_nlattr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x834ea1fd print_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x85bfffe5 nf_conntrack_l4proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x88209636 nf_conntrack_l3proto_generic +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x8ffe7e89 nf_conntrack_htable_size +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x90ff6c9f nf_ct_invert_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x9928a806 nf_ct_helper_ext_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0x996446b7 nf_conntrack_l4proto_tcp6 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xa6f62ec0 nf_conntrack_set_hashsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xab522435 nf_conntrack_l4proto_tcp4 +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xab957273 __nf_ct_refresh_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xaf57e66f nf_ct_extend_unregister +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb2562c68 nf_ct_iterate_cleanup +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb4a8138d nf_conntrack_in +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb602c57e nf_ct_l3proto_module_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xb8164512 nf_ct_expect_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbbce2128 nf_ct_get_tuplepr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbc887e16 nf_ct_expect_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbe46ddbd nf_ct_invert_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbf220526 nf_ct_get_tuple +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xbfd9b730 nf_conntrack_l3proto_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc044befe nf_ct_free_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc18ac88d nf_ct_expect_hsize +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc1be4166 __nf_ct_l4proto_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc23d9be9 nf_ct_expect_init +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc35a7a3e nf_conntrack_chain +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xc7b64d79 nf_conntrack_hash_insert +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcbf7fd2a nf_conntrack_register_notifier +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xccf1abac nf_ct_unexpect_related +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xcd1f8d68 nf_conntrack_alloc +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd50a96a2 nf_ct_alloc_hashtable +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xd9efb053 nf_ct_deliver_cached_events +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xda6a93b1 nf_ct_l3proto_find_get +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe0fe6d4e __nf_ct_kill_acct +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe1a811d6 nf_ct_l4proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xe3222e54 nf_conntrack_helper_register +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xee6e4a14 __nf_conntrack_find +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf1d19fe1 nf_ct_l3proto_put +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf26d7271 nf_conntrack_flush +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf2e4de29 nf_ct_l3protos +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xf9ae81a1 nf_conntrack_max +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfa169dac nf_conntrack_untracked +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xfb839673 nf_ct_remove_expectations +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack 0xff9e9fc3 nfnetlink_parse_nat_setup_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_amanda 0x5f36bce6 nf_nat_amanda_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_ftp 0x2bef4034 nf_nat_ftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x264c0cf3 get_h225_addr +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x2e11cd47 nat_t120_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x42fa7b19 set_h225_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x510bd464 set_sig_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x59241825 set_h245_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x5d3785ff nat_h245_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x67e4504a nat_q931_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0x71945c47 set_ras_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xc69d54b5 nat_rtp_rtcp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_h323 0xeda8cdd1 nat_callforwarding_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_irc 0xb73f26cc nf_nat_irc_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x0e2ef26d nf_nat_pptp_hook_exp_gre +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x1d2680c9 nf_nat_pptp_hook_outbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0x542d50cb nf_nat_pptp_hook_inbound +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_pptp 0xd5e569a2 nf_nat_pptp_hook_expectfn +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x05f8e58c nf_ct_gre_keymap_destroy +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_proto_gre 0x6f59d77c nf_ct_gre_keymap_add +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x0f98a608 nf_nat_sip_expect_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x13169b79 ct_sip_parse_request +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3c2058a6 ct_sip_parse_numerical_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x3d809024 nf_nat_sdp_addr_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5333cb69 ct_sip_parse_header_uri +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x5343611e ct_sip_get_sdp_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x56ad8f6e ct_sip_parse_address_param +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0x9c90d923 nf_nat_sdp_media_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xd848b563 nf_nat_sdp_port_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xd911079f nf_nat_sip_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8291790 nf_nat_sdp_session_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_sip 0xf8b610ea ct_sip_get_header +EXPORT_SYMBOL_GPL net/netfilter/nf_conntrack_tftp 0x7a86395b nf_nat_tftp_hook +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x02cfe272 nf_tproxy_assign_sock +EXPORT_SYMBOL_GPL net/netfilter/nf_tproxy_core 0x0825679f nf_tproxy_get_sock_v4 +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x1f58e71b nfnl_lock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x3895cd7a nfnl_unlock +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0x9fe27888 nfnetlink_subsys_register +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xc89ba9c4 nfnetlink_subsys_unregister +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xe0713618 nfnetlink_send +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xeca95329 nfnetlink_has_listeners +EXPORT_SYMBOL_GPL net/netfilter/nfnetlink 0xf18c1438 nfnetlink_unicast +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x12103513 xt_replace_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x161d1417 xt_compat_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x1e6965af xt_compat_target_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x23036aa2 xt_check_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x2afce3e2 xt_proto_fini +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x3d57081d xt_request_find_target +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x3dc83245 xt_table_unlock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x4036f87d xt_compat_match_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x40728a63 xt_find_revision +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x5f82f1f7 xt_compat_flush_offsets +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x684694c5 xt_compat_add_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x6f9aa2fb xt_compat_calc_jump +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x706b5638 xt_proto_init +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9003c4dc xt_register_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x93beeab7 xt_unregister_table +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x95893d42 xt_compat_match_from_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0x9b5d5ab2 xt_compat_target_to_user +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xa7b19a1f xt_compat_target_offset +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xb74b0739 xt_check_match +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xc77e9cb8 xt_find_table_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe0b4971b xt_compat_lock +EXPORT_SYMBOL_GPL net/netfilter/x_tables 0xe2206cd2 xt_compat_match_to_user +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xc177bee0 xt_rateest_put +EXPORT_SYMBOL_GPL net/netfilter/xt_RATEEST 0xdb8418cc xt_rateest_lookup +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0x634197a8 rxrpc_register_security +EXPORT_SYMBOL_GPL net/rxrpc/af-rxrpc 0xff9ab42a rxrpc_unregister_security +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0e38d6ec xprt_complete_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x0e516e3a xprt_reserve_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x10b97469 xprt_wait_for_buffer_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x13134d5d svc_addsock +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1b13c3fe svc_unreg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1ecb4162 svc_xprt_enqueue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x1f1b3035 xprt_adjust_cwnd +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x20441125 xprt_set_retrans_timeout_def +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2282b102 xprt_unregister_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x28ebfb80 rpc_killall_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x29836513 rpc_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aa17774 rpc_free_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2aae2d89 xprt_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x2eec107a xprt_set_retrans_timeout_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x31a89d59 rpc_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32334f0e rpc_bind_new_program +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32501d49 rpc_restart_call +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x32a74bde rpc_call_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x39377dff rpcauth_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x399bfcb8 __rpc_wait_for_completion_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3a111940 rpc_peeraddr2str +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3f1ef307 rpcb_getport_async +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3fa78873 rpcauth_init_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3fe4ac92 rpc_malloc +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x3ffd6e2a rpc_setbufsize +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x42eb258d rpc_call_null +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x47f1e1bf rpc_call_start +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4aa6891a svc_xprt_put +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4bc1cb6c rpc_sleep_on +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4d0c78b6 xdr_skb_read_bits +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x4fc0627b xprt_wake_pending_tasks +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x53445f68 nlm_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x550547a3 rpc_destroy_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5bd26000 rpc_proc_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5cf51603 xprt_write_space +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5d9755d0 rpc_peeraddr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5e327fd1 svc_print_addr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x5fed17c2 svc_find_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x606cf97b xprt_disconnect_done +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6261de53 xprt_reserve_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x671e0d83 xprt_lookup_rqst +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x68b98d5d rpcauth_lookup_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x69d6a5bd rpc_lookup_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6b8f4304 xdr_partial_copy_from_skb +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c5304c5 rpcb_getport_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6c85411c svc_xprt_received +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x6ea741b0 rpcauth_generic_bind_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x70c8a73d svc_create_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x76740690 rpc_run_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7b6e2469 rpc_call_sync +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7de53067 rpc_init_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x7ebb692b rpc_exit_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x848bd467 svc_xprt_init +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8554b613 svc_reg_xprt_class +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x85a3ddf4 put_rpccred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8824dc59 rpc_print_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x8c460b7c rpc_wake_up_queued_task +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x913c0291 xprt_register_transport +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9381edd9 svc_xprt_names +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9d1a6a1e xprt_release_xprt_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0x9d638591 svc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa5aa0383 rpc_alloc_iostats +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xa92d33d2 rpcauth_unregister +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xac872bc3 rpcauth_create +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xae9a8aa9 csum_partial_copy_to_xdr +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xaf5bf6ef nfs_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb0786759 rpc_proc_register +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb387b246 rpc_wake_up_status +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb8c0f53d rpcauth_destroy_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xb969b2eb rpc_force_rebind +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xbf9d1b96 nfsd_debug +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc07f2d1c rpc_max_payload +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xc12435e3 rpc_calc_rto +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xca78f4f1 xprt_release_rqst_cong +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xcb64426e rpc_lookup_machine_cred +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd82c728e rpc_init_wait_queue +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xd912d96a rpcauth_init_credcache +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xdbe5ecba rpc_clone_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe304bbd5 rpc_wake_up_next +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe32d348f rpc_delay +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xe4fb8394 rpc_shutdown_client +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeaa0ba7e svc_xprt_copy_addrs +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xed326360 svc_close_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xedd1ba52 rpc_wake_up +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xeeacab69 rpc_update_rtt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xf9d1164c rpc_free +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfbba2c38 xprt_release_xprt +EXPORT_SYMBOL_GPL net/sunrpc/sunrpc 0xfe396e6e rpc_put_task +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x2a865800 ipcomp_input +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x71056cf1 ipcomp_init_state +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0x89e6a070 ipcomp_output +EXPORT_SYMBOL_GPL net/xfrm/xfrm_ipcomp 0xd1c0110f ipcomp_destroy +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x28e16093 ad73311_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ad73311 0x28f8ccc2 soc_codec_dev_ad73311 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0x685f5e11 soc_codec_dev_ak4535 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ak4535 0xb9f056bc ak4535_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0x7ba292d8 cs4270_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-cs4270 0xf1019ff4 soc_codec_device_cs4270 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x395b9333 soc_codec_dev_ssm2602 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-ssm2602 0x9e41b704 ssm2602_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x21ac57c3 soc_codec_dev_tlv320aic23 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic23 0x398c32cf tlv320aic23_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x07fb6302 aic26_soc_codec_dev +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic26 0x482d198f aic26_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x1983596b aic3x_get_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x5c1b1d11 aic3x_headset_detected +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0x9c8f5f3c aic3x_set_gpio +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xdb087927 aic3x_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-tlv320aic3x 0xdb40f338 soc_codec_dev_aic3x +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0x66d44157 soc_codec_dev_uda1380 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-uda1380 0xa8ca9bc0 uda1380_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0x010bd9d2 soc_codec_dev_wm8510 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8510 0xd3cb5bfd wm8510_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x0edae25d soc_codec_dev_wm8580 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8580 0x6902aecb wm8580_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xb19df476 soc_codec_dev_wm8731 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8731 0xcd2d9e0c wm8731_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0x65a17893 wm8750_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8750 0xac0bb985 soc_codec_dev_wm8750 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0x8726ea46 soc_codec_dev_wm8753 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8753 0xde5b6930 wm8753_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x22134506 wm8900_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8900 0x4a1f0c5d soc_codec_dev_wm8900 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0x61325f9e soc_codec_dev_wm8903 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8903 0xa48737a8 wm8903_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x2ce8a82d wm8971_dai +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8971 0x564b2b99 soc_codec_dev_wm8971 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0x45ce37d2 soc_codec_dev_wm8990 +EXPORT_SYMBOL_GPL sound/soc/codecs/snd-soc-wm8990 0xb78b00d5 wm8990_dai +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0338c866 dapm_reg_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x077428ce snd_soc_dapm_stream_event +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0bda36b9 snd_soc_info_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x0c5dc0ff snd_soc_dai_set_tdm_slot +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x138da970 snd_soc_dapm_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x18c99a08 snd_soc_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x1bd53a48 snd_soc_put_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x28573d65 snd_soc_register_card +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3710c0c5 snd_soc_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x3caff903 snd_soc_dapm_sync +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x40175b4e snd_soc_new_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x49af5acc snd_soc_dai_set_clkdiv +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4e7c7c2f snd_soc_get_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x4fb6ba0a snd_soc_dai_set_sysclk +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x52da0264 snd_soc_test_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x623d1cb8 snd_soc_dapm_enable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6850a6bd snd_soc_put_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x693efbfe snd_soc_free_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x6e0e2cd6 snd_soc_update_bits +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x73eb28e4 snd_soc_dapm_new_controls +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x75b65410 snd_soc_dapm_new_widgets +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x776b9056 snd_soc_new_ac97_codec +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x7913693c snd_soc_dai_set_pll +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x84762a37 snd_soc_cnew +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x8a8037d7 snd_soc_dapm_new_control +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x902bebeb snd_soc_dapm_get_pin_status +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x92437e48 snd_soc_dapm_add_routes +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x95ffbc2e snd_soc_dai_set_fmt +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0x9e0666b5 snd_soc_info_volsw_s8 +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa4045334 snd_soc_set_runtime_hwparams +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa41584be snd_soc_dapm_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa7d4acab snd_soc_dapm_free +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xa922d6c4 snd_soc_dapm_nc_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xac4d1786 snd_soc_get_enum_double +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xb77dd0a8 snd_soc_dai_set_tristate +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc1c4901b snd_soc_dapm_put_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xc410c17a snd_soc_info_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xce0714b0 snd_soc_free_pcms +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd0ac1b5c snd_soc_put_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xd40638b1 snd_soc_dapm_connect_input +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xdf1e8882 snd_soc_info_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xee1dcad6 snd_soc_dapm_get_volsw +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf38b3755 snd_soc_info_enum_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf3e5b28a snd_soc_dapm_disable_pin +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf680c1ce snd_soc_get_volsw_2r +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xf87e9903 snd_soc_info_volsw_ext +EXPORT_SYMBOL_GPL sound/soc/snd-soc-core 0xfef58d9e snd_soc_dai_digital_mute +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x0d93d0e1 tlsf_create_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x1584fdb9 tlsf_destroy_memory_pool +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x2c383ca4 tlsf_calloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x54064cb9 tlsf_get_used_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0x60d233a6 tlsf_malloc +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xbe77d1fe tlsf_get_total_size +EXPORT_SYMBOL_GPL ubuntu/compcache/tlsf 0xe6acc368 tlsf_free +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x02500586 thinkpad_ec_unlock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x0dc7484e thinkpad_ec_try_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x2552d213 thinkpad_ec_lock +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x3dbfef12 thinkpad_ec_read_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0x8dbbd831 thinkpad_ec_invalidate +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xa3042743 thinkpad_ec_prefetch_row +EXPORT_SYMBOL_GPL ubuntu/misc/thinkpad_ec 0xfb5aa917 thinkpad_ec_try_lock +EXPORT_SYMBOL_GPL vmlinux 0x00029e69 fb_deferred_io_fsync +EXPORT_SYMBOL_GPL vmlinux 0x00566d8f inotify_get_cookie +EXPORT_SYMBOL_GPL vmlinux 0x00620e10 sata_set_spd +EXPORT_SYMBOL_GPL vmlinux 0x0067df75 ata_tf_from_fis +EXPORT_SYMBOL_GPL vmlinux 0x006d7cad srcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x00902a78 cpci_hp_unregister_controller +EXPORT_SYMBOL_GPL vmlinux 0x00b8ecf8 __iowrite32_copy +EXPORT_SYMBOL_GPL vmlinux 0x00c6cc8f kobject_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0x00ebcb5d ata_id_string +EXPORT_SYMBOL_GPL vmlinux 0x0110b3d1 register_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0x016228b1 ata_pci_sff_activate_host +EXPORT_SYMBOL_GPL vmlinux 0x0164a9ef regulator_force_disable +EXPORT_SYMBOL_GPL vmlinux 0x01848a8e local_apic_timer_c2_ok +EXPORT_SYMBOL_GPL vmlinux 0x019d6aff usb_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x01a4ea6d unregister_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x01e06afe device_reprobe +EXPORT_SYMBOL_GPL vmlinux 0x01e1a8de kgdb_breakpoint +EXPORT_SYMBOL_GPL vmlinux 0x01fada5d tty_put_char +EXPORT_SYMBOL_GPL vmlinux 0x020a0f8a devres_remove +EXPORT_SYMBOL_GPL vmlinux 0x0270bce3 regulator_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x028e6f97 __blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x02a9ac14 user_update +EXPORT_SYMBOL_GPL vmlinux 0x02ccea56 lock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x030a1563 device_destroy +EXPORT_SYMBOL_GPL vmlinux 0x03317f4b pci_test_config_bits +EXPORT_SYMBOL_GPL vmlinux 0x03377cec scsi_dh_detach +EXPORT_SYMBOL_GPL vmlinux 0x033fc019 queue_work +EXPORT_SYMBOL_GPL vmlinux 0x0343bdf1 __i2c_board_list +EXPORT_SYMBOL_GPL vmlinux 0x038ea63d __xenbus_register_frontend +EXPORT_SYMBOL_GPL vmlinux 0x03956ae7 sdio_f0_readb +EXPORT_SYMBOL_GPL vmlinux 0x03bb04ac rdev_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x03e3686c ata_timing_cycle2mode +EXPORT_SYMBOL_GPL vmlinux 0x03e7c75d devres_find +EXPORT_SYMBOL_GPL vmlinux 0x03fe2cca flush_work +EXPORT_SYMBOL_GPL vmlinux 0x04136bca klist_init +EXPORT_SYMBOL_GPL vmlinux 0x0447d159 raw_seq_stop +EXPORT_SYMBOL_GPL vmlinux 0x04486e88 rcu_batches_completed +EXPORT_SYMBOL_GPL vmlinux 0x04566c7f init_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x047d9031 elv_register +EXPORT_SYMBOL_GPL vmlinux 0x04c3f2c1 gnttab_empty_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x04ddf3b0 lookup_create +EXPORT_SYMBOL_GPL vmlinux 0x04e271cb inotify_init_watch +EXPORT_SYMBOL_GPL vmlinux 0x04e628cd leds_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x04ea8706 __iowrite64_copy +EXPORT_SYMBOL_GPL vmlinux 0x04f0af4f usb_serial_probe +EXPORT_SYMBOL_GPL vmlinux 0x04f7df9a uv_teardown_irq +EXPORT_SYMBOL_GPL vmlinux 0x0531dcb8 ata_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0x053716ee rtc_device_register +EXPORT_SYMBOL_GPL vmlinux 0x054e550b kernel_halt +EXPORT_SYMBOL_GPL vmlinux 0x054f566a xenbus_alloc_evtchn +EXPORT_SYMBOL_GPL vmlinux 0x059a61a2 __ip_route_output_key +EXPORT_SYMBOL_GPL vmlinux 0x060d1064 set_memory_ro +EXPORT_SYMBOL_GPL vmlinux 0x064aaabc usb_lock_device_for_reset +EXPORT_SYMBOL_GPL vmlinux 0x064db9a5 mark_mounts_for_expiry +EXPORT_SYMBOL_GPL vmlinux 0x065ad2bb drop_file_write_access +EXPORT_SYMBOL_GPL vmlinux 0x06d222f8 device_resume +EXPORT_SYMBOL_GPL vmlinux 0x06eebe74 crypto_unregister_alg +EXPORT_SYMBOL_GPL vmlinux 0x06f8aa16 anon_transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07198ccb ata_bmdma_status +EXPORT_SYMBOL_GPL vmlinux 0x0776238f __inet_twsk_hashdance +EXPORT_SYMBOL_GPL vmlinux 0x0786c4ff inet6_sk_rebuild_header +EXPORT_SYMBOL_GPL vmlinux 0x079beaf1 dev_attr_em_message +EXPORT_SYMBOL_GPL vmlinux 0x07a92a87 put_device +EXPORT_SYMBOL_GPL vmlinux 0x07b52e38 rtnl_unregister +EXPORT_SYMBOL_GPL vmlinux 0x07cc66c9 lookup_instantiate_filp +EXPORT_SYMBOL_GPL vmlinux 0x07d43a2a fixed_phy_set_link_update +EXPORT_SYMBOL_GPL vmlinux 0x07e3878b ata_eh_freeze_port +EXPORT_SYMBOL_GPL vmlinux 0x07ff4aea xenbus_scanf +EXPORT_SYMBOL_GPL vmlinux 0x08a3e5d1 net_ipv6_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0x091eb9b4 round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0x09536365 usb_anchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x095ca626 xenbus_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x098bd839 __crypto_alloc_tfm +EXPORT_SYMBOL_GPL vmlinux 0x09901f4a do_add_mount +EXPORT_SYMBOL_GPL vmlinux 0x09b5fba5 user_instantiate +EXPORT_SYMBOL_GPL vmlinux 0x09bd30e5 hrtimer_init +EXPORT_SYMBOL_GPL vmlinux 0x0a44c61d sdio_disable_func +EXPORT_SYMBOL_GPL vmlinux 0x0ad5c33f acpi_smbus_register_callback +EXPORT_SYMBOL_GPL vmlinux 0x0af76eed tcp_unregister_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x0b09aec0 cpci_hp_register_controller +EXPORT_SYMBOL_GPL vmlinux 0x0b0f8665 spi_new_device +EXPORT_SYMBOL_GPL vmlinux 0x0b4394d1 get_task_mm +EXPORT_SYMBOL_GPL vmlinux 0x0b6fe268 inet_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x0c17e274 xfrm_aalg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x0c40a966 ata_host_register +EXPORT_SYMBOL_GPL vmlinux 0x0c4717f7 srcu_init_notifier_head +EXPORT_SYMBOL_GPL vmlinux 0x0c597897 debugfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x0ca3c4fc driver_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x0cb542de ata_sff_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x0cfa0916 inet_csk_get_port +EXPORT_SYMBOL_GPL vmlinux 0x0cfb8983 ata_scsi_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x0d35ddd7 __blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0x0d814646 klist_add_head +EXPORT_SYMBOL_GPL vmlinux 0x0d9a8022 ata_sff_qc_fill_rtf +EXPORT_SYMBOL_GPL vmlinux 0x0d9e382c usb_interrupt_msg +EXPORT_SYMBOL_GPL vmlinux 0x0daced87 transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x0dbf8659 devres_get +EXPORT_SYMBOL_GPL vmlinux 0x0e21b770 default_backing_dev_info +EXPORT_SYMBOL_GPL vmlinux 0x0e29bf3c driver_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x0ebf0827 transport_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0x0ec210b8 xen_start_info +EXPORT_SYMBOL_GPL vmlinux 0x0f2961f2 regulator_set_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x0f59164b fs_kobj +EXPORT_SYMBOL_GPL vmlinux 0x0f6ff757 __hid_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x0fe2d570 xenbus_directory +EXPORT_SYMBOL_GPL vmlinux 0x100c13c6 usb_kill_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x100c48a2 unregister_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x10293ee3 inet_unhash +EXPORT_SYMBOL_GPL vmlinux 0x1076769f vfs_getxattr +EXPORT_SYMBOL_GPL vmlinux 0x1091007c blk_trace_setup +EXPORT_SYMBOL_GPL vmlinux 0x111cb472 debugfs_create_u16 +EXPORT_SYMBOL_GPL vmlinux 0x117d6c8b klist_add_after +EXPORT_SYMBOL_GPL vmlinux 0x11e36ba4 scsi_dh_activate +EXPORT_SYMBOL_GPL vmlinux 0x11f447ce __gpio_to_irq +EXPORT_SYMBOL_GPL vmlinux 0x12350a68 __class_register +EXPORT_SYMBOL_GPL vmlinux 0x124f2056 crypto_get_attr_type +EXPORT_SYMBOL_GPL vmlinux 0x1251d30f call_rcu +EXPORT_SYMBOL_GPL vmlinux 0x128afe11 sdio_readw +EXPORT_SYMBOL_GPL vmlinux 0x12beb949 sdio_claim_irq +EXPORT_SYMBOL_GPL vmlinux 0x12c9faf4 ata_acpi_stm +EXPORT_SYMBOL_GPL vmlinux 0x12d861b2 usb_get_status +EXPORT_SYMBOL_GPL vmlinux 0x12e285ec is_uv_system +EXPORT_SYMBOL_GPL vmlinux 0x12e50f30 sata_pmp_qc_defer_cmd_switch +EXPORT_SYMBOL_GPL vmlinux 0x130238b3 get_cpu_sysdev +EXPORT_SYMBOL_GPL vmlinux 0x134d12e0 ata_sas_port_stop +EXPORT_SYMBOL_GPL vmlinux 0x13b2a946 register_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x145eebd0 device_power_up +EXPORT_SYMBOL_GPL vmlinux 0x149db923 selinux_string_to_sid +EXPORT_SYMBOL_GPL vmlinux 0x14cdda22 hidraw_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x14dda409 power_supply_register +EXPORT_SYMBOL_GPL vmlinux 0x158c2ad0 acpi_smbus_unregister_callback +EXPORT_SYMBOL_GPL vmlinux 0x1595ec1d ata_acpi_cbl_80wire +EXPORT_SYMBOL_GPL vmlinux 0x15966052 xenbus_watch_path +EXPORT_SYMBOL_GPL vmlinux 0x1598dc9d unregister_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x15a61e12 regulator_set_optimum_mode +EXPORT_SYMBOL_GPL vmlinux 0x15b0606e e820_any_mapped +EXPORT_SYMBOL_GPL vmlinux 0x15e5f816 spi_add_device +EXPORT_SYMBOL_GPL vmlinux 0x160e994e audit_log_untrustedstring +EXPORT_SYMBOL_GPL vmlinux 0x16735dff fib_rules_lookup +EXPORT_SYMBOL_GPL vmlinux 0x16a5b4c8 key_type_user +EXPORT_SYMBOL_GPL vmlinux 0x1703de9d dm_rh_recovery_end +EXPORT_SYMBOL_GPL vmlinux 0x17140902 ata_bmdma_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1760ac92 __inet_hash_nolisten +EXPORT_SYMBOL_GPL vmlinux 0x1781c704 mmu_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1799fa49 agp_remove_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1830ac53 generic_sync_sb_inodes +EXPORT_SYMBOL_GPL vmlinux 0x183a4077 spi_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x1851259a do_sync_mapping_range +EXPORT_SYMBOL_GPL vmlinux 0x1878f62b edac_err_assert +EXPORT_SYMBOL_GPL vmlinux 0x187afd58 crypto_hash_walk_done +EXPORT_SYMBOL_GPL vmlinux 0x1881ee00 crypto_register_alg +EXPORT_SYMBOL_GPL vmlinux 0x1885fbd1 sata_pmp_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x18be231c ata_host_alloc +EXPORT_SYMBOL_GPL vmlinux 0x18ce5206 scsi_eh_ready_devs +EXPORT_SYMBOL_GPL vmlinux 0x18d53420 kgdb_register_io_module +EXPORT_SYMBOL_GPL vmlinux 0x18f83fab gnttab_grant_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0x19184d9c rt_mutex_trylock +EXPORT_SYMBOL_GPL vmlinux 0x193dcbb2 securityfs_create_dir +EXPORT_SYMBOL_GPL vmlinux 0x19a304ba usb_disabled +EXPORT_SYMBOL_GPL vmlinux 0x19a3ce45 d_obtain_alias +EXPORT_SYMBOL_GPL vmlinux 0x19bcecd1 usb_get_dev +EXPORT_SYMBOL_GPL vmlinux 0x19d01a22 cpuidle_register_driver +EXPORT_SYMBOL_GPL vmlinux 0x1a06c571 ezusb_set_reset +EXPORT_SYMBOL_GPL vmlinux 0x1a10607f unregister_jprobes +EXPORT_SYMBOL_GPL vmlinux 0x1a83ecfb ata_host_alloc_pinfo +EXPORT_SYMBOL_GPL vmlinux 0x1a938737 atomic_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x1acda5b2 atomic_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x1ad12d5f devres_destroy +EXPORT_SYMBOL_GPL vmlinux 0x1ad3b491 acpi_root_bridge +EXPORT_SYMBOL_GPL vmlinux 0x1af4a8c8 ata_pci_device_suspend +EXPORT_SYMBOL_GPL vmlinux 0x1b9aca3f jprobe_return +EXPORT_SYMBOL_GPL vmlinux 0x1c0413b7 crypto_aead_type +EXPORT_SYMBOL_GPL vmlinux 0x1c87a811 __round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x1c911fa0 inet_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x1c9769ed ata_base_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x1cb1b6ef inet_csk_listen_start +EXPORT_SYMBOL_GPL vmlinux 0x1ce06916 sysdev_create_file +EXPORT_SYMBOL_GPL vmlinux 0x1ce61a59 relay_subbufs_consumed +EXPORT_SYMBOL_GPL vmlinux 0x1ce9f482 led_trigger_store +EXPORT_SYMBOL_GPL vmlinux 0x1cf2e70c ata_acpi_gtm +EXPORT_SYMBOL_GPL vmlinux 0x1d023170 schedule_hrtimeout +EXPORT_SYMBOL_GPL vmlinux 0x1d0defe7 ata_std_postreset +EXPORT_SYMBOL_GPL vmlinux 0x1d735315 kobject_rename +EXPORT_SYMBOL_GPL vmlinux 0x1d897bde ata_pio_need_iordy +EXPORT_SYMBOL_GPL vmlinux 0x1d8db736 gpiochip_is_requested +EXPORT_SYMBOL_GPL vmlinux 0x1da0e893 ata_port_freeze +EXPORT_SYMBOL_GPL vmlinux 0x1dd70100 dmi_walk +EXPORT_SYMBOL_GPL vmlinux 0x1df485d9 xenbus_map_ring_valloc +EXPORT_SYMBOL_GPL vmlinux 0x1e3275f7 raw_seq_open +EXPORT_SYMBOL_GPL vmlinux 0x1e426896 aead_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0x1e5a5f22 sn_partition_id +EXPORT_SYMBOL_GPL vmlinux 0x1e7bbcb3 kernel_restart +EXPORT_SYMBOL_GPL vmlinux 0x1e8e02bd unregister_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0x1eabb429 usb_driver_set_configuration +EXPORT_SYMBOL_GPL vmlinux 0x1eb9516e round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x1ed4ac67 dev_attr_link_power_management_policy +EXPORT_SYMBOL_GPL vmlinux 0x1f57e18e pci_disable_rom +EXPORT_SYMBOL_GPL vmlinux 0x1f8ec1b3 acpi_get_pci_rootbridge_handle +EXPORT_SYMBOL_GPL vmlinux 0x1f9a0fbf hpet_unregister_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x1fa14371 hid_output_report +EXPORT_SYMBOL_GPL vmlinux 0x1fcece42 inet_twdr_twcal_tick +EXPORT_SYMBOL_GPL vmlinux 0x20079332 aead_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x2036c46f blk_update_request +EXPORT_SYMBOL_GPL vmlinux 0x20577ea2 xfrm_ealg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x206fc621 generic_fh_to_parent +EXPORT_SYMBOL_GPL vmlinux 0x2082cf13 rtc_read_time +EXPORT_SYMBOL_GPL vmlinux 0x20ad3c92 xfrm_audit_state_delete +EXPORT_SYMBOL_GPL vmlinux 0x20b82470 hpet_register_irq_handler +EXPORT_SYMBOL_GPL vmlinux 0x20bc3470 orderly_poweroff +EXPORT_SYMBOL_GPL vmlinux 0x20cd788f __ftrace_printk +EXPORT_SYMBOL_GPL vmlinux 0x20eace40 elv_unregister +EXPORT_SYMBOL_GPL vmlinux 0x21032dd8 find_vpid +EXPORT_SYMBOL_GPL vmlinux 0x2112165f sata_async_notification +EXPORT_SYMBOL_GPL vmlinux 0x213c1513 klist_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0x214e416a mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x2171b7a5 devres_alloc +EXPORT_SYMBOL_GPL vmlinux 0x21907a46 sdio_readsb +EXPORT_SYMBOL_GPL vmlinux 0x21aa5385 regulator_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x2240d211 unregister_jprobe +EXPORT_SYMBOL_GPL vmlinux 0x224479ff dm_noflush_suspending +EXPORT_SYMBOL_GPL vmlinux 0x22472bf4 xfrm_calg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x226b2210 nf_unregister_queue_handlers +EXPORT_SYMBOL_GPL vmlinux 0x227f3606 device_bind_driver +EXPORT_SYMBOL_GPL vmlinux 0x2296c00d crypto_attr_u32 +EXPORT_SYMBOL_GPL vmlinux 0x22ac5c07 unregister_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x22cb3835 xattr_getsecurity +EXPORT_SYMBOL_GPL vmlinux 0x22e3aab3 scsi_flush_work +EXPORT_SYMBOL_GPL vmlinux 0x22e4e191 usb_add_hcd +EXPORT_SYMBOL_GPL vmlinux 0x231706d0 ata_dummy_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x233c8541 sdio_writel +EXPORT_SYMBOL_GPL vmlinux 0x2358fb8d crypto_attr_alg +EXPORT_SYMBOL_GPL vmlinux 0x23864ce7 cpuset_mem_spread_node +EXPORT_SYMBOL_GPL vmlinux 0x239fb7bd kobject_get_path +EXPORT_SYMBOL_GPL vmlinux 0x23b72f0d dev_attr_em_message_type +EXPORT_SYMBOL_GPL vmlinux 0x23fd84d6 usb_serial_register +EXPORT_SYMBOL_GPL vmlinux 0x2403e5ad ata_sas_queuecmd +EXPORT_SYMBOL_GPL vmlinux 0x24196ba2 init_uts_ns +EXPORT_SYMBOL_GPL vmlinux 0x2447533c ktime_get_real +EXPORT_SYMBOL_GPL vmlinux 0x2462915e __sock_recv_timestamp +EXPORT_SYMBOL_GPL vmlinux 0x2469ca66 platform_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x24a23c3b usb_hcd_poll_rh_status +EXPORT_SYMBOL_GPL vmlinux 0x24c7698a xenbus_write +EXPORT_SYMBOL_GPL vmlinux 0x24e29e3c usb_deregister_dev +EXPORT_SYMBOL_GPL vmlinux 0x24e37267 fb_deferred_io_open +EXPORT_SYMBOL_GPL vmlinux 0x24e8db91 zap_vma_ptes +EXPORT_SYMBOL_GPL vmlinux 0x24eb7e32 leds_list +EXPORT_SYMBOL_GPL vmlinux 0x24fa14f4 sysctl_pathname +EXPORT_SYMBOL_GPL vmlinux 0x2531c51d sysdev_class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0x2545c170 unregister_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x255556a6 scsi_queue_work +EXPORT_SYMBOL_GPL vmlinux 0x255692d0 hid_set_field +EXPORT_SYMBOL_GPL vmlinux 0x258a6b45 da903x_clr_bits +EXPORT_SYMBOL_GPL vmlinux 0x259a6d7e hid_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x25ce8ff8 inet_hash +EXPORT_SYMBOL_GPL vmlinux 0x25e7f770 usb_get_urb +EXPORT_SYMBOL_GPL vmlinux 0x25eb627a scsi_nl_add_transport +EXPORT_SYMBOL_GPL vmlinux 0x2624902c ezusb_writememory +EXPORT_SYMBOL_GPL vmlinux 0x263ad179 usb_hcd_link_urb_to_ep +EXPORT_SYMBOL_GPL vmlinux 0x266155fb regulator_enable +EXPORT_SYMBOL_GPL vmlinux 0x2665b4b3 spi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x26c90ea4 scsi_eh_get_sense +EXPORT_SYMBOL_GPL vmlinux 0x26da2c43 pci_stop_bus_device +EXPORT_SYMBOL_GPL vmlinux 0x26dd3f6f regulator_bulk_disable +EXPORT_SYMBOL_GPL vmlinux 0x27b8db75 debugfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x28088f0f pv_time_ops +EXPORT_SYMBOL_GPL vmlinux 0x28471e55 driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0x28503e2e platform_device_add_resources +EXPORT_SYMBOL_GPL vmlinux 0x2894bb86 usb_root_hub_lost_power +EXPORT_SYMBOL_GPL vmlinux 0x28bdacde hrtimer_start_range_ns +EXPORT_SYMBOL_GPL vmlinux 0x28d664ff __raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x28e0fb5b relay_open +EXPORT_SYMBOL_GPL vmlinux 0x28e23139 xfrm_probe_algs +EXPORT_SYMBOL_GPL vmlinux 0x28f38f18 gpiochip_add +EXPORT_SYMBOL_GPL vmlinux 0x292fd278 class_destroy +EXPORT_SYMBOL_GPL vmlinux 0x2954ec67 pci_set_pcie_reset_state +EXPORT_SYMBOL_GPL vmlinux 0x2a12e51a fl6_sock_lookup +EXPORT_SYMBOL_GPL vmlinux 0x2a1a8626 uart_set_options +EXPORT_SYMBOL_GPL vmlinux 0x2a4e8cbc dm_rh_inc_pending +EXPORT_SYMBOL_GPL vmlinux 0x2a678a13 __suspend_report_result +EXPORT_SYMBOL_GPL vmlinux 0x2aa5c1c4 __inet_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x2afe6f72 rtc_update_irq +EXPORT_SYMBOL_GPL vmlinux 0x2b24e4a0 uv_blade_info +EXPORT_SYMBOL_GPL vmlinux 0x2b30f50d rtc_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2b79a31c pciserial_init_ports +EXPORT_SYMBOL_GPL vmlinux 0x2b9f8e23 nf_net_ipv4_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x2bb57a0f usb_hcd_pci_remove +EXPORT_SYMBOL_GPL vmlinux 0x2be92318 inet_diag_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2bf20d1a agp_add_bridge +EXPORT_SYMBOL_GPL vmlinux 0x2c06e1a4 __blk_add_trace +EXPORT_SYMBOL_GPL vmlinux 0x2c16ed76 xfrm_calg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x2c208607 power_supply_is_system_supplied +EXPORT_SYMBOL_GPL vmlinux 0x2c467a60 pci_find_next_capability +EXPORT_SYMBOL_GPL vmlinux 0x2c678f07 ata_pci_remove_one +EXPORT_SYMBOL_GPL vmlinux 0x2c6e7553 __mnt_is_readonly +EXPORT_SYMBOL_GPL vmlinux 0x2ccdd2b5 tcp_init_congestion_ops +EXPORT_SYMBOL_GPL vmlinux 0x2d165ecd copy_fs_struct +EXPORT_SYMBOL_GPL vmlinux 0x2d2056e9 usb_get_from_anchor +EXPORT_SYMBOL_GPL vmlinux 0x2d323fc6 crypto_larval_kill +EXPORT_SYMBOL_GPL vmlinux 0x2d53b1fd tty_ldisc_ref +EXPORT_SYMBOL_GPL vmlinux 0x2d59c954 edac_handlers +EXPORT_SYMBOL_GPL vmlinux 0x2d6afcfd blk_queue_rq_timeout +EXPORT_SYMBOL_GPL vmlinux 0x2d9f2ce3 sched_clock_idle_wakeup_event +EXPORT_SYMBOL_GPL vmlinux 0x2de9f755 anon_transport_class_register +EXPORT_SYMBOL_GPL vmlinux 0x2df188c3 inet6_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0x2dfd4290 cpuidle_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0x2e20b575 rt_mutex_timed_lock +EXPORT_SYMBOL_GPL vmlinux 0x2e2995cc led_trigger_unregister_simple +EXPORT_SYMBOL_GPL vmlinux 0x2e453393 sata_scr_valid +EXPORT_SYMBOL_GPL vmlinux 0x2ec3b51d hwmon_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x2ec92012 scatterwalk_copychunks +EXPORT_SYMBOL_GPL vmlinux 0x2ee087e8 put_pid +EXPORT_SYMBOL_GPL vmlinux 0x2efc956d blk_insert_cloned_request +EXPORT_SYMBOL_GPL vmlinux 0x2f3a1cf1 pci_cleanup_aer_uncorrect_error_status +EXPORT_SYMBOL_GPL vmlinux 0x2f47d8c7 cpufreq_frequency_get_table +EXPORT_SYMBOL_GPL vmlinux 0x2f887b8a ipv6_find_tlv +EXPORT_SYMBOL_GPL vmlinux 0x2f8bb891 usb_unpoison_urb +EXPORT_SYMBOL_GPL vmlinux 0x2f8e3d2c usb_buffer_free +EXPORT_SYMBOL_GPL vmlinux 0x2fcb8489 usb_driver_release_interface +EXPORT_SYMBOL_GPL vmlinux 0x3011e931 devm_kzalloc +EXPORT_SYMBOL_GPL vmlinux 0x30196eb4 xfrm_output +EXPORT_SYMBOL_GPL vmlinux 0x3080fb39 inet6_lookup_listener +EXPORT_SYMBOL_GPL vmlinux 0x30bb317d simple_attr_read +EXPORT_SYMBOL_GPL vmlinux 0x3122f540 ata_bmdma_setup +EXPORT_SYMBOL_GPL vmlinux 0x3160efaf device_schedule_callback_owner +EXPORT_SYMBOL_GPL vmlinux 0x31797610 tracepoint_iter_reset +EXPORT_SYMBOL_GPL vmlinux 0x318920b1 register_dock_notifier +EXPORT_SYMBOL_GPL vmlinux 0x31e4f224 rtnl_put_cacheinfo +EXPORT_SYMBOL_GPL vmlinux 0x32096d79 crypto_grab_skcipher +EXPORT_SYMBOL_GPL vmlinux 0x320cd591 ip6_local_out +EXPORT_SYMBOL_GPL vmlinux 0x3227d4cb class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x325e677c gnttab_grant_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x328b2a12 transport_configure_device +EXPORT_SYMBOL_GPL vmlinux 0x329adf4d relay_close +EXPORT_SYMBOL_GPL vmlinux 0x330e075d led_trigger_set +EXPORT_SYMBOL_GPL vmlinux 0x3320402e tcp_register_congestion_control +EXPORT_SYMBOL_GPL vmlinux 0x3348c521 input_ff_create +EXPORT_SYMBOL_GPL vmlinux 0x33b6e752 acpi_ec_remove_query_handler +EXPORT_SYMBOL_GPL vmlinux 0x34105c01 bus_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x34241f7f blk_execute_rq_nowait +EXPORT_SYMBOL_GPL vmlinux 0x34337d05 cpuidle_disable_device +EXPORT_SYMBOL_GPL vmlinux 0x3441c3d6 gpio_set_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x34f8096d relay_flush +EXPORT_SYMBOL_GPL vmlinux 0x3569939c usb_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x359e8c24 scsi_dh_attach +EXPORT_SYMBOL_GPL vmlinux 0x35ba78ac user_match +EXPORT_SYMBOL_GPL vmlinux 0x35cbb359 scsi_target_block +EXPORT_SYMBOL_GPL vmlinux 0x35d402b1 simple_attr_release +EXPORT_SYMBOL_GPL vmlinux 0x35d8c94a sdev_evt_alloc +EXPORT_SYMBOL_GPL vmlinux 0x361e2bcc save_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0x362e23ec call_rcu_bh +EXPORT_SYMBOL_GPL vmlinux 0x365c2c94 spi_busnum_to_master +EXPORT_SYMBOL_GPL vmlinux 0x3669e185 sdio_readb +EXPORT_SYMBOL_GPL vmlinux 0x36969fdb devres_close_group +EXPORT_SYMBOL_GPL vmlinux 0x36b64c9a dm_rh_recovery_start +EXPORT_SYMBOL_GPL vmlinux 0x36fb3414 xenbus_dev_fatal +EXPORT_SYMBOL_GPL vmlinux 0x3789a802 scsi_mode_select +EXPORT_SYMBOL_GPL vmlinux 0x37b534f9 invalidate_inode_pages2 +EXPORT_SYMBOL_GPL vmlinux 0x37bf012a devres_release_group +EXPORT_SYMBOL_GPL vmlinux 0x37f21418 ata_std_bios_param +EXPORT_SYMBOL_GPL vmlinux 0x3814f19b ata_sff_data_xfer_noirq +EXPORT_SYMBOL_GPL vmlinux 0x3819bbd5 generic_drop_inode +EXPORT_SYMBOL_GPL vmlinux 0x383480b5 hidraw_report_event +EXPORT_SYMBOL_GPL vmlinux 0x386e8b71 dm_rh_get_state +EXPORT_SYMBOL_GPL vmlinux 0x3895233b srcu_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x38bb757b single_release_net +EXPORT_SYMBOL_GPL vmlinux 0x391b5056 usb_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x39238b57 klist_del +EXPORT_SYMBOL_GPL vmlinux 0x39942348 bus_for_each_drv +EXPORT_SYMBOL_GPL vmlinux 0x39a438e8 put_driver +EXPORT_SYMBOL_GPL vmlinux 0x39faab89 uart_console_write +EXPORT_SYMBOL_GPL vmlinux 0x3a311560 unregister_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x3a7f8b86 __local_bh_enable +EXPORT_SYMBOL_GPL vmlinux 0x3aff2595 ata_common_sdev_attrs +EXPORT_SYMBOL_GPL vmlinux 0x3b17aec1 device_initialize +EXPORT_SYMBOL_GPL vmlinux 0x3b1c0782 xenbus_watch_pathfmt +EXPORT_SYMBOL_GPL vmlinux 0x3b93d9b7 ata_cable_unknown +EXPORT_SYMBOL_GPL vmlinux 0x3b954dde pci_destroy_slot +EXPORT_SYMBOL_GPL vmlinux 0x3be6de9a sata_pmp_error_handler +EXPORT_SYMBOL_GPL vmlinux 0x3be7af02 get_max_files +EXPORT_SYMBOL_GPL vmlinux 0x3be89d3c usb_register_notify +EXPORT_SYMBOL_GPL vmlinux 0x3bf6c3b2 usb_ifnum_to_if +EXPORT_SYMBOL_GPL vmlinux 0x3c1ec4ca i2c_new_dummy +EXPORT_SYMBOL_GPL vmlinux 0x3c4bf8b6 sync_page_io +EXPORT_SYMBOL_GPL vmlinux 0x3c8e2ebd xfrm_inner_extract_output +EXPORT_SYMBOL_GPL vmlinux 0x3c942368 profile_event_unregister +EXPORT_SYMBOL_GPL vmlinux 0x3ccb8337 skb_morph +EXPORT_SYMBOL_GPL vmlinux 0x3cd06035 add_input_randomness +EXPORT_SYMBOL_GPL vmlinux 0x3cf85bcd inet_diag_register +EXPORT_SYMBOL_GPL vmlinux 0x3cf9bf4f platform_driver_probe +EXPORT_SYMBOL_GPL vmlinux 0x3cfedb3f register_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x3d29867d per_cpu__gdt_page +EXPORT_SYMBOL_GPL vmlinux 0x3d5f392d acpi_os_unmap_memory +EXPORT_SYMBOL_GPL vmlinux 0x3d7ea99a gnttab_grant_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x3e0d8846 raw_unhash_sk +EXPORT_SYMBOL_GPL vmlinux 0x3e0e1237 relay_switch_subbuf +EXPORT_SYMBOL_GPL vmlinux 0x3e404bfb rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0x3ebdf2c8 __rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0x3ecf6cfc wmi_install_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0x3edad223 usb_usual_clear_present +EXPORT_SYMBOL_GPL vmlinux 0x3efb35c9 get_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0x3f238101 dcookie_register +EXPORT_SYMBOL_GPL vmlinux 0x3f84d4c9 gnttab_release_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x3fab9be6 regulator_bulk_get +EXPORT_SYMBOL_GPL vmlinux 0x3fce9bf9 inotify_find_watch +EXPORT_SYMBOL_GPL vmlinux 0x3fced94c regulator_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x400162a3 fb_deferred_io_init +EXPORT_SYMBOL_GPL vmlinux 0x40380ad6 hrtimer_cancel +EXPORT_SYMBOL_GPL vmlinux 0x409dcca7 usb_buffer_unmap_sg +EXPORT_SYMBOL_GPL vmlinux 0x40af0dec ata_xfer_mode2mask +EXPORT_SYMBOL_GPL vmlinux 0x40fe2898 regulator_is_enabled +EXPORT_SYMBOL_GPL vmlinux 0x41f3cc90 xfrm_aalg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x42308f55 bus_for_each_dev +EXPORT_SYMBOL_GPL vmlinux 0x424acc6d scatterwalk_done +EXPORT_SYMBOL_GPL vmlinux 0x424af8be usb_get_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x42b56980 vlan_dev_vlan_id +EXPORT_SYMBOL_GPL vmlinux 0x42bf4650 skcipher_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0x432fd7f6 __gpio_set_value +EXPORT_SYMBOL_GPL vmlinux 0x437bb7c9 blk_end_bidi_request +EXPORT_SYMBOL_GPL vmlinux 0x439b8e0e usb_put_dev +EXPORT_SYMBOL_GPL vmlinux 0x43b4bc49 register_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0x43dc6200 platform_device_del +EXPORT_SYMBOL_GPL vmlinux 0x43f56e82 ata_xfer_mode2shift +EXPORT_SYMBOL_GPL vmlinux 0x444a66a1 led_trigger_show +EXPORT_SYMBOL_GPL vmlinux 0x44a38f89 ata_port_desc +EXPORT_SYMBOL_GPL vmlinux 0x44a65d5c lock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x44b5ba8b platform_device_add +EXPORT_SYMBOL_GPL vmlinux 0x44f97ca3 blk_queue_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x4516d33d devres_open_group +EXPORT_SYMBOL_GPL vmlinux 0x4572ad38 init_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0x457594fa crypto_alg_list +EXPORT_SYMBOL_GPL vmlinux 0x45bf1ff3 crypto_inc +EXPORT_SYMBOL_GPL vmlinux 0x45d14bdf hypercall_page +EXPORT_SYMBOL_GPL vmlinux 0x460f31aa rodata_test_data +EXPORT_SYMBOL_GPL vmlinux 0x463fd0a9 crypto_alg_mod_lookup +EXPORT_SYMBOL_GPL vmlinux 0x4689bc88 klist_node_attached +EXPORT_SYMBOL_GPL vmlinux 0x46951814 scsi_target_unblock +EXPORT_SYMBOL_GPL vmlinux 0x46fffe97 blkcipher_walk_virt +EXPORT_SYMBOL_GPL vmlinux 0x47229b5c gpio_request +EXPORT_SYMBOL_GPL vmlinux 0x47583845 platform_get_resource +EXPORT_SYMBOL_GPL vmlinux 0x47932555 xenbus_unmap_ring +EXPORT_SYMBOL_GPL vmlinux 0x4817ac2e bus_find_device +EXPORT_SYMBOL_GPL vmlinux 0x484cac0f save_stack_trace_tsk +EXPORT_SYMBOL_GPL vmlinux 0x484fafc6 usb_autopm_set_interface +EXPORT_SYMBOL_GPL vmlinux 0x486b6ff6 attribute_container_find_class_device +EXPORT_SYMBOL_GPL vmlinux 0x49436e3e preempt_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x4982bad3 dm_rh_recovery_in_flight +EXPORT_SYMBOL_GPL vmlinux 0x499043d3 crypto_init_queue +EXPORT_SYMBOL_GPL vmlinux 0x49fdab31 tty_prepare_flip_string +EXPORT_SYMBOL_GPL vmlinux 0x4a11a4fb bind_virq_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x4a7e30d9 marker_probe_unregister_private_data +EXPORT_SYMBOL_GPL vmlinux 0x4ace7eb7 platform_add_devices +EXPORT_SYMBOL_GPL vmlinux 0x4b2aa1d4 ata_sff_port_start +EXPORT_SYMBOL_GPL vmlinux 0x4b31fc73 usb_hcd_unlink_urb_from_ep +EXPORT_SYMBOL_GPL vmlinux 0x4b762828 start_thread +EXPORT_SYMBOL_GPL vmlinux 0x4be5694f usb_hc_died +EXPORT_SYMBOL_GPL vmlinux 0x4c074931 disk_part_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x4c0b763b skb_pull_rcsum +EXPORT_SYMBOL_GPL vmlinux 0x4c371d7a ata_link_abort +EXPORT_SYMBOL_GPL vmlinux 0x4c759827 byte_rev_table +EXPORT_SYMBOL_GPL vmlinux 0x4c8d52a8 input_ff_destroy +EXPORT_SYMBOL_GPL vmlinux 0x4cc2ab92 preempt_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0x4cda6860 ata_host_resume +EXPORT_SYMBOL_GPL vmlinux 0x4d44c06d platform_get_irq +EXPORT_SYMBOL_GPL vmlinux 0x4dba6719 usb_register_dev +EXPORT_SYMBOL_GPL vmlinux 0x4df99b5a ata_pci_device_do_resume +EXPORT_SYMBOL_GPL vmlinux 0x4e1892ea ata_sff_thaw +EXPORT_SYMBOL_GPL vmlinux 0x4e37ea35 rt_mutex_unlock +EXPORT_SYMBOL_GPL vmlinux 0x4e442681 inotify_inode_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x4e6f5ed7 regulator_set_voltage +EXPORT_SYMBOL_GPL vmlinux 0x4eab20da ata_cable_80wire +EXPORT_SYMBOL_GPL vmlinux 0x4f8db399 xfrm_output_resume +EXPORT_SYMBOL_GPL vmlinux 0x4fa0a6c9 sata_std_hardreset +EXPORT_SYMBOL_GPL vmlinux 0x4fdc945d sata_deb_timing_normal +EXPORT_SYMBOL_GPL vmlinux 0x5048788c inet_csk_reqsk_queue_prune +EXPORT_SYMBOL_GPL vmlinux 0x5086ac3a alg_test +EXPORT_SYMBOL_GPL vmlinux 0x508f7be5 sata_scr_write +EXPORT_SYMBOL_GPL vmlinux 0x50a130be fib_rules_cleanup_ops +EXPORT_SYMBOL_GPL vmlinux 0x50b319ce cpu_bit_bitmap +EXPORT_SYMBOL_GPL vmlinux 0x50b67174 xfrm_ealg_get_byid +EXPORT_SYMBOL_GPL vmlinux 0x50da844c usb_sg_cancel +EXPORT_SYMBOL_GPL vmlinux 0x50e7193a __i2c_first_dynamic_bus_num +EXPORT_SYMBOL_GPL vmlinux 0x50fad434 round_jiffies_up +EXPORT_SYMBOL_GPL vmlinux 0x511f3e1f apic_ops +EXPORT_SYMBOL_GPL vmlinux 0x5121c2f0 sysfs_update_group +EXPORT_SYMBOL_GPL vmlinux 0x51488d34 ata_sff_data_xfer +EXPORT_SYMBOL_GPL vmlinux 0x51596651 led_trigger_unregister +EXPORT_SYMBOL_GPL vmlinux 0x518c2fc6 hpet_rtc_dropped_irq +EXPORT_SYMBOL_GPL vmlinux 0x51a4c094 unregister_kprobe +EXPORT_SYMBOL_GPL vmlinux 0x51b46321 regulator_put +EXPORT_SYMBOL_GPL vmlinux 0x51cb6bbf register_posix_clock +EXPORT_SYMBOL_GPL vmlinux 0x51dd6488 xfrm_aalg_get_byidx +EXPORT_SYMBOL_GPL vmlinux 0x51fc8b26 pci_renumber_slot +EXPORT_SYMBOL_GPL vmlinux 0x5246d3a3 __audit_inode_child +EXPORT_SYMBOL_GPL vmlinux 0x526b867a acpi_smbus_read +EXPORT_SYMBOL_GPL vmlinux 0x52859f2f hidraw_connect +EXPORT_SYMBOL_GPL vmlinux 0x52d111ea pm_qos_update_requirement +EXPORT_SYMBOL_GPL vmlinux 0x531468f2 crypto_alloc_aead +EXPORT_SYMBOL_GPL vmlinux 0x53614269 get_cpu_idle_time_us +EXPORT_SYMBOL_GPL vmlinux 0x5372dede unregister_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53986488 register_die_notifier +EXPORT_SYMBOL_GPL vmlinux 0x53a9cf24 debugfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x53c43ba8 securityfs_remove +EXPORT_SYMBOL_GPL vmlinux 0x53c4f99e ata_sff_prereset +EXPORT_SYMBOL_GPL vmlinux 0x53dfbf13 cpuidle_enable_device +EXPORT_SYMBOL_GPL vmlinux 0x53f4269b blk_trace_remove +EXPORT_SYMBOL_GPL vmlinux 0x542652cf bus_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5440ae2b class_dev_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x547e1497 scsi_unregister_device_handler +EXPORT_SYMBOL_GPL vmlinux 0x54872532 sdio_memcpy_toio +EXPORT_SYMBOL_GPL vmlinux 0x54fa9959 pci_bus_max_busnr +EXPORT_SYMBOL_GPL vmlinux 0x551c1a57 dm_disk +EXPORT_SYMBOL_GPL vmlinux 0x552bea82 device_for_each_child +EXPORT_SYMBOL_GPL vmlinux 0x552cb3eb regulator_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x55526907 xen_features +EXPORT_SYMBOL_GPL vmlinux 0x5595b08d crypto_free_tfm +EXPORT_SYMBOL_GPL vmlinux 0x561c634a wmi_evaluate_method +EXPORT_SYMBOL_GPL vmlinux 0x56398615 mark_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5641485b tty_termios_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0x5662e8f0 xfrm_audit_state_icvfail +EXPORT_SYMBOL_GPL vmlinux 0x56a217f6 sdio_f0_writeb +EXPORT_SYMBOL_GPL vmlinux 0x56f064db queue_work_on +EXPORT_SYMBOL_GPL vmlinux 0x575c5f94 execute_in_process_context +EXPORT_SYMBOL_GPL vmlinux 0x57736ede dm_rh_recovery_prepare +EXPORT_SYMBOL_GPL vmlinux 0x5779d445 xenbus_exists +EXPORT_SYMBOL_GPL vmlinux 0x579e0bf5 rtnl_unregister_all +EXPORT_SYMBOL_GPL vmlinux 0x57d77890 inet_csk_listen_stop +EXPORT_SYMBOL_GPL vmlinux 0x580a49e3 power_supply_class +EXPORT_SYMBOL_GPL vmlinux 0x585fa898 __inet_inherit_port +EXPORT_SYMBOL_GPL vmlinux 0x591e216f dev_set_name +EXPORT_SYMBOL_GPL vmlinux 0x593a36c2 scsi_dh_handler_exist +EXPORT_SYMBOL_GPL vmlinux 0x59594121 ata_dummy_port_info +EXPORT_SYMBOL_GPL vmlinux 0x5974c15f usb_init_urb +EXPORT_SYMBOL_GPL vmlinux 0x597d8523 __inet_lookup_established +EXPORT_SYMBOL_GPL vmlinux 0x597f3bc3 marker_get_private_data +EXPORT_SYMBOL_GPL vmlinux 0x59cf8cec device_move +EXPORT_SYMBOL_GPL vmlinux 0x5a2b1b67 gnttab_free_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5a3a50bf sched_setscheduler +EXPORT_SYMBOL_GPL vmlinux 0x5a6958c2 usb_hcd_platform_shutdown +EXPORT_SYMBOL_GPL vmlinux 0x5a7bfe41 crypto_probing_notify +EXPORT_SYMBOL_GPL vmlinux 0x5a8d9932 put_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x5af03a28 gnttab_claim_grant_reference +EXPORT_SYMBOL_GPL vmlinux 0x5b1b2997 sysdev_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5b1c9c4e dm_send_uevents +EXPORT_SYMBOL_GPL vmlinux 0x5bfc03c3 unregister_keyboard_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5c0525cf fib_rules_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5c783951 class_dev_iter_init +EXPORT_SYMBOL_GPL vmlinux 0x5cb5a638 ip_route_output_flow +EXPORT_SYMBOL_GPL vmlinux 0x5cb94ab9 invalidate_inode_pages2_range +EXPORT_SYMBOL_GPL vmlinux 0x5cc852e3 uv_coherency_id +EXPORT_SYMBOL_GPL vmlinux 0x5cd9b5f3 ata_pci_sff_init_one +EXPORT_SYMBOL_GPL vmlinux 0x5cfcf0f1 percpu_free +EXPORT_SYMBOL_GPL vmlinux 0x5d0f6f57 kbd_table +EXPORT_SYMBOL_GPL vmlinux 0x5d366dec gnttab_cancel_free_callback +EXPORT_SYMBOL_GPL vmlinux 0x5d730e7b raw_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x5d87c067 register_acpi_bus_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5d987421 skb_cow_data +EXPORT_SYMBOL_GPL vmlinux 0x5d9c0967 class_find_device +EXPORT_SYMBOL_GPL vmlinux 0x5dd67618 register_netevent_notifier +EXPORT_SYMBOL_GPL vmlinux 0x5e3c6464 kill_pid_info_as_uid +EXPORT_SYMBOL_GPL vmlinux 0x5e51be23 led_trigger_event +EXPORT_SYMBOL_GPL vmlinux 0x5eb05848 raw_seq_next +EXPORT_SYMBOL_GPL vmlinux 0x5f005583 ata_do_eh +EXPORT_SYMBOL_GPL vmlinux 0x5f2da8c4 check_tsc_unstable +EXPORT_SYMBOL_GPL vmlinux 0x5f5b628b ata_sff_pause +EXPORT_SYMBOL_GPL vmlinux 0x5f602dac exit_fs +EXPORT_SYMBOL_GPL vmlinux 0x5f6411e5 netlink_has_listeners +EXPORT_SYMBOL_GPL vmlinux 0x5f8327b5 debugfs_create_u32 +EXPORT_SYMBOL_GPL vmlinux 0x60341bf2 usb_find_interface +EXPORT_SYMBOL_GPL vmlinux 0x605ff123 klist_add_tail +EXPORT_SYMBOL_GPL vmlinux 0x608ae3ef proc_net_mkdir +EXPORT_SYMBOL_GPL vmlinux 0x6091797f synchronize_rcu +EXPORT_SYMBOL_GPL vmlinux 0x60a13e90 rcu_barrier +EXPORT_SYMBOL_GPL vmlinux 0x60f20463 sysdev_store_int +EXPORT_SYMBOL_GPL vmlinux 0x61904363 cpuidle_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x61aeac91 devm_kfree +EXPORT_SYMBOL_GPL vmlinux 0x61b13635 kobject_init_and_add +EXPORT_SYMBOL_GPL vmlinux 0x62434387 inet6_csk_addr2sockaddr +EXPORT_SYMBOL_GPL vmlinux 0x62b6814d tty_get_pgrp +EXPORT_SYMBOL_GPL vmlinux 0x62f0a5e0 inet6_destroy_sock +EXPORT_SYMBOL_GPL vmlinux 0x62fbd617 macvlan_handle_frame_hook +EXPORT_SYMBOL_GPL vmlinux 0x631ab0eb sata_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x63ae27d6 add_nops +EXPORT_SYMBOL_GPL vmlinux 0x63b5a62e ata_sff_wait_ready +EXPORT_SYMBOL_GPL vmlinux 0x64335767 usb_driver_claim_interface +EXPORT_SYMBOL_GPL vmlinux 0x644f3cb1 ata_port_probe +EXPORT_SYMBOL_GPL vmlinux 0x646050af __get_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x64828aee scsi_execute_async +EXPORT_SYMBOL_GPL vmlinux 0x64b0bd5a tty_wakeup +EXPORT_SYMBOL_GPL vmlinux 0x64fc53c3 ata_cable_ignore +EXPORT_SYMBOL_GPL vmlinux 0x6537f30d fnotify_change +EXPORT_SYMBOL_GPL vmlinux 0x655693de usb_get_current_frame_number +EXPORT_SYMBOL_GPL vmlinux 0x65642fe2 blk_lld_busy +EXPORT_SYMBOL_GPL vmlinux 0x65ccb6f0 call_netevent_notifiers +EXPORT_SYMBOL_GPL vmlinux 0x65d6d0f0 gpio_direction_input +EXPORT_SYMBOL_GPL vmlinux 0x6610ad99 synchronize_srcu +EXPORT_SYMBOL_GPL vmlinux 0x661601de sprint_symbol +EXPORT_SYMBOL_GPL vmlinux 0x667a14cc regulator_get_init_drvdata +EXPORT_SYMBOL_GPL vmlinux 0x668402aa crypto_put_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x66b2a859 nr_free_buffer_pages +EXPORT_SYMBOL_GPL vmlinux 0x66d87d38 symbol_put_addr +EXPORT_SYMBOL_GPL vmlinux 0x672cf8a5 ata_bmdma_mode_filter +EXPORT_SYMBOL_GPL vmlinux 0x67955ce6 profile_hits +EXPORT_SYMBOL_GPL vmlinux 0x67dccb0f sata_scr_read +EXPORT_SYMBOL_GPL vmlinux 0x686c703f xfrm_count_auth_supported +EXPORT_SYMBOL_GPL vmlinux 0x6875d38c klist_next +EXPORT_SYMBOL_GPL vmlinux 0x687926bd ata_dev_disable +EXPORT_SYMBOL_GPL vmlinux 0x68818bc6 firmware_kobj +EXPORT_SYMBOL_GPL vmlinux 0x6892088c unregister_pm_notifier +EXPORT_SYMBOL_GPL vmlinux 0x68b455c5 ata_host_activate +EXPORT_SYMBOL_GPL vmlinux 0x69349c63 schedule_hrtimeout_range +EXPORT_SYMBOL_GPL vmlinux 0x698d2ce7 sysdev_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x69e9a2cb ata_scsi_slave_config +EXPORT_SYMBOL_GPL vmlinux 0x6a0c408d platform_device_register +EXPORT_SYMBOL_GPL vmlinux 0x6a22f277 crypto_spawn_tfm +EXPORT_SYMBOL_GPL vmlinux 0x6a323371 sysdev_class_create_file +EXPORT_SYMBOL_GPL vmlinux 0x6a4c8d04 usb_hcd_check_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0x6a72f0c4 tracepoint_iter_stop +EXPORT_SYMBOL_GPL vmlinux 0x6a8441be cpci_hp_start +EXPORT_SYMBOL_GPL vmlinux 0x6af19b0e bus_get_kset +EXPORT_SYMBOL_GPL vmlinux 0x6b371aaf sysfs_put +EXPORT_SYMBOL_GPL vmlinux 0x6b9178b3 xenbus_strstate +EXPORT_SYMBOL_GPL vmlinux 0x6b93bf60 inet_twdr_twkill_work +EXPORT_SYMBOL_GPL vmlinux 0x6ba6b5b6 sysdev_register +EXPORT_SYMBOL_GPL vmlinux 0x6be62dfd probe_kernel_read +EXPORT_SYMBOL_GPL vmlinux 0x6c0e7dad usb_poison_urb +EXPORT_SYMBOL_GPL vmlinux 0x6c11059b __srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x6c49c4f2 clockevents_notify +EXPORT_SYMBOL_GPL vmlinux 0x6c8d5ae8 __gpio_get_value +EXPORT_SYMBOL_GPL vmlinux 0x6d2fc5a6 net_namespace_list +EXPORT_SYMBOL_GPL vmlinux 0x6d808c11 rtc_read_alarm +EXPORT_SYMBOL_GPL vmlinux 0x6d936e69 crypto_alloc_ablkcipher +EXPORT_SYMBOL_GPL vmlinux 0x6d938da6 ata_ehi_clear_desc +EXPORT_SYMBOL_GPL vmlinux 0x6d9f8efc transport_add_device +EXPORT_SYMBOL_GPL vmlinux 0x6dc0fba0 uhci_check_and_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0x6dce94bf usb_bus_list_lock +EXPORT_SYMBOL_GPL vmlinux 0x6e0a3f91 inet_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0x6e248a62 usb_get_intf +EXPORT_SYMBOL_GPL vmlinux 0x6e3d5a2e ata_sff_dumb_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x6e3f44d6 attribute_container_register +EXPORT_SYMBOL_GPL vmlinux 0x6e58ddf0 gnttab_end_foreign_transfer_ref +EXPORT_SYMBOL_GPL vmlinux 0x6ea72a40 uv_bios_freq_base +EXPORT_SYMBOL_GPL vmlinux 0x6ee34090 vfs_setxattr +EXPORT_SYMBOL_GPL vmlinux 0x6eff03a7 rtc_set_time +EXPORT_SYMBOL_GPL vmlinux 0x6f0aa015 dm_rh_region_to_sector +EXPORT_SYMBOL_GPL vmlinux 0x6f1eb09b inotify_add_watch +EXPORT_SYMBOL_GPL vmlinux 0x6f5c3348 register_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0x6f9c2efe marker_probe_cb +EXPORT_SYMBOL_GPL vmlinux 0x6fbf8658 driver_find +EXPORT_SYMBOL_GPL vmlinux 0x6fe5b7c3 ata_pci_sff_prepare_host +EXPORT_SYMBOL_GPL vmlinux 0x6ff607b6 crypto_get_default_rng +EXPORT_SYMBOL_GPL vmlinux 0x6ff679f3 usb_unanchor_urb +EXPORT_SYMBOL_GPL vmlinux 0x702a12cc klist_iter_init_node +EXPORT_SYMBOL_GPL vmlinux 0x7037d79d k8_flush_garts +EXPORT_SYMBOL_GPL vmlinux 0x706b3a33 cpufreq_frequency_table_get_attr +EXPORT_SYMBOL_GPL vmlinux 0x707ff1bb ata_xfer_mask2mode +EXPORT_SYMBOL_GPL vmlinux 0x70b1944d fib_rules_register +EXPORT_SYMBOL_GPL vmlinux 0x710b5f0f inotify_remove_watch_locked +EXPORT_SYMBOL_GPL vmlinux 0x715e767c da903x_update +EXPORT_SYMBOL_GPL vmlinux 0x7171fd8b __cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0x7193919f bdi_writeout_inc +EXPORT_SYMBOL_GPL vmlinux 0x71c8bc95 kgdb_unregister_io_module +EXPORT_SYMBOL_GPL vmlinux 0x722c4f65 usb_scuttle_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0x7278d328 all_vm_events +EXPORT_SYMBOL_GPL vmlinux 0x72846d8d usb_serial_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x728a1e7f device_attach +EXPORT_SYMBOL_GPL vmlinux 0x72e852c3 usb_deregister +EXPORT_SYMBOL_GPL vmlinux 0x731433ee unregister_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0x731dba7a xen_domain_type +EXPORT_SYMBOL_GPL vmlinux 0x7386b9e4 usb_put_hcd +EXPORT_SYMBOL_GPL vmlinux 0x7386f2c7 i2c_unregister_device +EXPORT_SYMBOL_GPL vmlinux 0x73a48b4a ata_sff_std_ports +EXPORT_SYMBOL_GPL vmlinux 0x73a64601 platform_driver_register +EXPORT_SYMBOL_GPL vmlinux 0x73b1f76d do_posix_clock_nosettime +EXPORT_SYMBOL_GPL vmlinux 0x73f04c2f input_ff_event +EXPORT_SYMBOL_GPL vmlinux 0x743261eb debugfs_create_u64 +EXPORT_SYMBOL_GPL vmlinux 0x743a165e ata_pack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x746735da sysfs_schedule_callback +EXPORT_SYMBOL_GPL vmlinux 0x746a0649 spi_alloc_master +EXPORT_SYMBOL_GPL vmlinux 0x747b9021 ata_port_pbar_desc +EXPORT_SYMBOL_GPL vmlinux 0x74abdafa task_handoff_register +EXPORT_SYMBOL_GPL vmlinux 0x74cda9ea regulator_register +EXPORT_SYMBOL_GPL vmlinux 0x74d61a4d get_dcookie +EXPORT_SYMBOL_GPL vmlinux 0x75141b4d class_interface_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7521afb6 leave_mm +EXPORT_SYMBOL_GPL vmlinux 0x7542e059 kernel_kobj +EXPORT_SYMBOL_GPL vmlinux 0x7553f80d power_supply_changed +EXPORT_SYMBOL_GPL vmlinux 0x757b31b9 kobject_uevent +EXPORT_SYMBOL_GPL vmlinux 0x75c552c0 gpiochip_remove +EXPORT_SYMBOL_GPL vmlinux 0x75e8f3c3 crypto_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0x762b7132 inet_twsk_schedule +EXPORT_SYMBOL_GPL vmlinux 0x7675d5ca pci_enable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x7679a804 device_release_driver +EXPORT_SYMBOL_GPL vmlinux 0x769e423a blkcipher_walk_virt_block +EXPORT_SYMBOL_GPL vmlinux 0x76a7a5cf pci_unblock_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x76c31dc7 screen_glyph +EXPORT_SYMBOL_GPL vmlinux 0x76cd4588 ata_pci_sff_init_host +EXPORT_SYMBOL_GPL vmlinux 0x76de6e9f ata_pci_device_do_suspend +EXPORT_SYMBOL_GPL vmlinux 0x7712771a unbind_from_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0x7734fb11 usb_buffer_alloc +EXPORT_SYMBOL_GPL vmlinux 0x774fc39c __percpu_alloc_mask +EXPORT_SYMBOL_GPL vmlinux 0x77a8e7d9 k_handler +EXPORT_SYMBOL_GPL vmlinux 0x77a939c8 ata_sg_init +EXPORT_SYMBOL_GPL vmlinux 0x77ca03be crypto_ahash_type +EXPORT_SYMBOL_GPL vmlinux 0x77deac3f acpi_bus_trim +EXPORT_SYMBOL_GPL vmlinux 0x7804f40d klist_remove +EXPORT_SYMBOL_GPL vmlinux 0x7812fdd1 ata_sff_busy_sleep +EXPORT_SYMBOL_GPL vmlinux 0x7826b77d dm_rh_delay +EXPORT_SYMBOL_GPL vmlinux 0x78349290 ata_slave_link_init +EXPORT_SYMBOL_GPL vmlinux 0x7847ce38 platform_device_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7862db1e sk_setup_caps +EXPORT_SYMBOL_GPL vmlinux 0x787eb854 i2c_bus_type +EXPORT_SYMBOL_GPL vmlinux 0x788b847f pci_scan_child_bus +EXPORT_SYMBOL_GPL vmlinux 0x78a7d8d6 ata_sff_check_status +EXPORT_SYMBOL_GPL vmlinux 0x796ef331 sg_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x797423ac klist_add_before +EXPORT_SYMBOL_GPL vmlinux 0x79843bf8 sysfs_remove_link +EXPORT_SYMBOL_GPL vmlinux 0x7a4c1438 pv_info +EXPORT_SYMBOL_GPL vmlinux 0x7a6cb59f class_for_each_device +EXPORT_SYMBOL_GPL vmlinux 0x7ac10ebc uv_node_to_blade +EXPORT_SYMBOL_GPL vmlinux 0x7ae1ae8e cpufreq_frequency_table_put_attr +EXPORT_SYMBOL_GPL vmlinux 0x7af3a31b usb_mon_register +EXPORT_SYMBOL_GPL vmlinux 0x7b1d544d edac_handler_set +EXPORT_SYMBOL_GPL vmlinux 0x7c6d7605 blocking_notifier_chain_unregister +EXPORT_SYMBOL_GPL vmlinux 0x7d06d334 sysfs_add_file_to_group +EXPORT_SYMBOL_GPL vmlinux 0x7d1cd2a2 register_net_sysctl_rotable +EXPORT_SYMBOL_GPL vmlinux 0x7d4527ec inet6_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0x7d470559 ip6_dst_blackhole +EXPORT_SYMBOL_GPL vmlinux 0x7d607bd5 vfs_setlease +EXPORT_SYMBOL_GPL vmlinux 0x7d688ce2 init_user_ns +EXPORT_SYMBOL_GPL vmlinux 0x7d99c1a8 ata_host_init +EXPORT_SYMBOL_GPL vmlinux 0x7da5cdb1 console_drivers +EXPORT_SYMBOL_GPL vmlinux 0x7da8d037 marker_probe_register +EXPORT_SYMBOL_GPL vmlinux 0x7dbc6935 __ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0x7dc5d0b6 crypto_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0x7decc727 net_assign_generic +EXPORT_SYMBOL_GPL vmlinux 0x7e092a46 inet_twsk_alloc +EXPORT_SYMBOL_GPL vmlinux 0x7e275ea8 scsi_complete_async_scans +EXPORT_SYMBOL_GPL vmlinux 0x7e49bd00 rtnl_kill_links +EXPORT_SYMBOL_GPL vmlinux 0x7e64181d usb_calc_bus_time +EXPORT_SYMBOL_GPL vmlinux 0x7e6e488a free_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x7eb00b07 fb_deferred_io_cleanup +EXPORT_SYMBOL_GPL vmlinux 0x7ee2d094 hidinput_report_event +EXPORT_SYMBOL_GPL vmlinux 0x7efb9c56 flush_workqueue +EXPORT_SYMBOL_GPL vmlinux 0x7f19c836 unlock_policy_rwsem_write +EXPORT_SYMBOL_GPL vmlinux 0x7f21dc8d pciserial_resume_ports +EXPORT_SYMBOL_GPL vmlinux 0x7f4a0672 xenbus_unmap_ring_vfree +EXPORT_SYMBOL_GPL vmlinux 0x7f4ad793 ata_port_disable +EXPORT_SYMBOL_GPL vmlinux 0x7fb5c81e sata_link_debounce +EXPORT_SYMBOL_GPL vmlinux 0x7ff10ccf raw_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8009be18 generic_fh_to_dentry +EXPORT_SYMBOL_GPL vmlinux 0x8039d043 selinux_secmark_relabel_packet_permission +EXPORT_SYMBOL_GPL vmlinux 0x807f9c27 rtc_class_close +EXPORT_SYMBOL_GPL vmlinux 0x808ec1a3 crypto_alg_tested +EXPORT_SYMBOL_GPL vmlinux 0x8099e89e pskb_put +EXPORT_SYMBOL_GPL vmlinux 0x80b527c4 acpi_get_hp_params_from_firmware +EXPORT_SYMBOL_GPL vmlinux 0x80ee55c3 selinux_secmark_refcount_inc +EXPORT_SYMBOL_GPL vmlinux 0x8106054d pci_block_user_cfg_access +EXPORT_SYMBOL_GPL vmlinux 0x812c7fac hrtimer_try_to_cancel +EXPORT_SYMBOL_GPL vmlinux 0x81409d49 sdio_writeb +EXPORT_SYMBOL_GPL vmlinux 0x815efcb3 hid_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0x81cbb4e7 crypto_aead_setauthsize +EXPORT_SYMBOL_GPL vmlinux 0x81ecefef spi_register_master +EXPORT_SYMBOL_GPL vmlinux 0x81fd16fe pci_execute_reset_function +EXPORT_SYMBOL_GPL vmlinux 0x8226642f __gpio_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x824bf0c1 simple_attr_open +EXPORT_SYMBOL_GPL vmlinux 0x826360fd do_posix_clock_nonanosleep +EXPORT_SYMBOL_GPL vmlinux 0x8276e170 dm_set_device_limits +EXPORT_SYMBOL_GPL vmlinux 0x8277488a ata_sff_port_ops +EXPORT_SYMBOL_GPL vmlinux 0x82cd19f3 register_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x82d79b51 sysctl_vfs_cache_pressure +EXPORT_SYMBOL_GPL vmlinux 0x82f776b7 gpio_export +EXPORT_SYMBOL_GPL vmlinux 0x8315abb2 raw_seq_start +EXPORT_SYMBOL_GPL vmlinux 0x831e6780 device_rename +EXPORT_SYMBOL_GPL vmlinux 0x833fea5f sdio_set_block_size +EXPORT_SYMBOL_GPL vmlinux 0x83b2e956 register_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0x83ca6417 sock_prot_inuse_add +EXPORT_SYMBOL_GPL vmlinux 0x83d96307 ata_sff_post_internal_cmd +EXPORT_SYMBOL_GPL vmlinux 0x83e71453 hidinput_disconnect +EXPORT_SYMBOL_GPL vmlinux 0x83fab8d3 power_supply_unregister +EXPORT_SYMBOL_GPL vmlinux 0x83fda26e ata_scsi_simulate +EXPORT_SYMBOL_GPL vmlinux 0x84170449 ata_noop_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0x8452d272 xfrm_audit_state_add +EXPORT_SYMBOL_GPL vmlinux 0x8452dd8e bus_register +EXPORT_SYMBOL_GPL vmlinux 0x8454dca5 get_inotify_watch +EXPORT_SYMBOL_GPL vmlinux 0x84827556 md_new_event +EXPORT_SYMBOL_GPL vmlinux 0x84834145 hrtimer_get_remaining +EXPORT_SYMBOL_GPL vmlinux 0x84fe3f5a md_allow_write +EXPORT_SYMBOL_GPL vmlinux 0x853cd53e unregister_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x85478a0b inet6_hash_frag +EXPORT_SYMBOL_GPL vmlinux 0x85c10896 rcu_batches_completed_bh +EXPORT_SYMBOL_GPL vmlinux 0x85d77905 cpufreq_cpu_put +EXPORT_SYMBOL_GPL vmlinux 0x85d7edfd hpet_set_periodic_freq +EXPORT_SYMBOL_GPL vmlinux 0x85e5a3db ktime_get_ts +EXPORT_SYMBOL_GPL vmlinux 0x8639655d ip_local_out +EXPORT_SYMBOL_GPL vmlinux 0x86623fd7 notify_remote_via_irq +EXPORT_SYMBOL_GPL vmlinux 0x867b5ed2 single_open_net +EXPORT_SYMBOL_GPL vmlinux 0x867c684a setup_APIC_eilvt_ibs +EXPORT_SYMBOL_GPL vmlinux 0x868784cb __symbol_get +EXPORT_SYMBOL_GPL vmlinux 0x86a51007 gnttab_end_foreign_transfer +EXPORT_SYMBOL_GPL vmlinux 0x86ac5f33 regulator_disable +EXPORT_SYMBOL_GPL vmlinux 0x86b1667d hwrng_unregister +EXPORT_SYMBOL_GPL vmlinux 0x86c722f8 rfkill_epo +EXPORT_SYMBOL_GPL vmlinux 0x86d4d734 vfs_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0x86f64feb __create_workqueue_key +EXPORT_SYMBOL_GPL vmlinux 0x86f71944 pci_restore_msi_state +EXPORT_SYMBOL_GPL vmlinux 0x871a9910 register_kprobes +EXPORT_SYMBOL_GPL vmlinux 0x873fbaea edac_atomic_assert_error +EXPORT_SYMBOL_GPL vmlinux 0x874aded9 regulator_get_voltage +EXPORT_SYMBOL_GPL vmlinux 0x87526081 pci_disable_pcie_error_reporting +EXPORT_SYMBOL_GPL vmlinux 0x876d29f1 wmi_get_event_data +EXPORT_SYMBOL_GPL vmlinux 0x87754115 raw_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0x877a53a0 dnotify_parent +EXPORT_SYMBOL_GPL vmlinux 0x87bfb3bb ata_cable_sata +EXPORT_SYMBOL_GPL vmlinux 0x87f2cf3a blocking_notifier_chain_cond_register +EXPORT_SYMBOL_GPL vmlinux 0x880b189a __atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x8810ad5e crypto_xor +EXPORT_SYMBOL_GPL vmlinux 0x882134de blk_abort_request +EXPORT_SYMBOL_GPL vmlinux 0x8849febd register_pernet_subsys +EXPORT_SYMBOL_GPL vmlinux 0x885142a6 nf_net_netfilter_sysctl_path +EXPORT_SYMBOL_GPL vmlinux 0x888c12b2 rtc_irq_register +EXPORT_SYMBOL_GPL vmlinux 0x88af5b99 crypto_register_instance +EXPORT_SYMBOL_GPL vmlinux 0x88f0db24 cancel_work_sync +EXPORT_SYMBOL_GPL vmlinux 0x88fde7b1 xfrm_audit_state_notfound_simple +EXPORT_SYMBOL_GPL vmlinux 0x892b9c8f tcp_is_cwnd_limited +EXPORT_SYMBOL_GPL vmlinux 0x89414704 inet_twsk_purge +EXPORT_SYMBOL_GPL vmlinux 0x899ad6a0 ata_sff_irq_clear +EXPORT_SYMBOL_GPL vmlinux 0x89aaf9ba ata_sff_host_intr +EXPORT_SYMBOL_GPL vmlinux 0x89b712fc sata_scr_write_flush +EXPORT_SYMBOL_GPL vmlinux 0x89d4dbaf usb_usual_check_type +EXPORT_SYMBOL_GPL vmlinux 0x89ee2653 anon_inode_getfd +EXPORT_SYMBOL_GPL vmlinux 0x89f6ffd5 xfrm_audit_policy_add +EXPORT_SYMBOL_GPL vmlinux 0x8abed13d xfrm_aead_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x8ad9be80 xfrm_audit_state_replay_overflow +EXPORT_SYMBOL_GPL vmlinux 0x8b1aab6a spi_sync +EXPORT_SYMBOL_GPL vmlinux 0x8b752ac1 ata_tf_to_fis +EXPORT_SYMBOL_GPL vmlinux 0x8b9200fd lookup_address +EXPORT_SYMBOL_GPL vmlinux 0x8b97bddc ata_eh_analyze_ncq_error +EXPORT_SYMBOL_GPL vmlinux 0x8bbfdf48 input_ff_upload +EXPORT_SYMBOL_GPL vmlinux 0x8c06a108 xenbus_transaction_start +EXPORT_SYMBOL_GPL vmlinux 0x8c30095d pciserial_suspend_ports +EXPORT_SYMBOL_GPL vmlinux 0x8c38074a unregister_xenstore_notifier +EXPORT_SYMBOL_GPL vmlinux 0x8d0f74f2 attribute_container_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8d15fee3 da903x_set_bits +EXPORT_SYMBOL_GPL vmlinux 0x8def058f cpuidle_register_device +EXPORT_SYMBOL_GPL vmlinux 0x8e781471 inet6_csk_reqsk_queue_hash_add +EXPORT_SYMBOL_GPL vmlinux 0x8e7cbaf0 sysdev_class_register +EXPORT_SYMBOL_GPL vmlinux 0x8e8d86e8 bus_rescan_devices +EXPORT_SYMBOL_GPL vmlinux 0x8eb58c6e __wake_up_sync +EXPORT_SYMBOL_GPL vmlinux 0x8f02e2d7 skb_partial_csum_set +EXPORT_SYMBOL_GPL vmlinux 0x8f49ec3a regulator_set_mode +EXPORT_SYMBOL_GPL vmlinux 0x8f6cee77 __round_jiffies_relative +EXPORT_SYMBOL_GPL vmlinux 0x8f9eb46d dev_attr_sw_activity +EXPORT_SYMBOL_GPL vmlinux 0x8fb0e979 sysfs_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x8fc2da97 __rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0x8ff3c043 __rt_mutex_init +EXPORT_SYMBOL_GPL vmlinux 0x9009602a acpi_bus_get_ejd +EXPORT_SYMBOL_GPL vmlinux 0x906b805e srcu_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0x90a1004a crypto_has_alg +EXPORT_SYMBOL_GPL vmlinux 0x90ac4102 ata_bus_reset +EXPORT_SYMBOL_GPL vmlinux 0x90f786dc usb_altnum_to_altsetting +EXPORT_SYMBOL_GPL vmlinux 0x9138c654 ata_sff_exec_command +EXPORT_SYMBOL_GPL vmlinux 0x91482eef usb_anchor_empty +EXPORT_SYMBOL_GPL vmlinux 0x9159b9d6 profile_event_register +EXPORT_SYMBOL_GPL vmlinux 0x919f34f7 ata_acpi_gtm_xfermask +EXPORT_SYMBOL_GPL vmlinux 0x91dacaa2 acpi_processor_ffh_cstate_probe +EXPORT_SYMBOL_GPL vmlinux 0x92183295 crypto_chain +EXPORT_SYMBOL_GPL vmlinux 0x9241c3ee device_power_down +EXPORT_SYMBOL_GPL vmlinux 0x92445aee hrtimer_get_res +EXPORT_SYMBOL_GPL vmlinux 0x927f4af5 __mmu_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x92d31cfb fixed_phy_add +EXPORT_SYMBOL_GPL vmlinux 0x92fb217b dcookie_unregister +EXPORT_SYMBOL_GPL vmlinux 0x93035e84 alloc_page_buffers +EXPORT_SYMBOL_GPL vmlinux 0x936ef94d sysfs_create_link +EXPORT_SYMBOL_GPL vmlinux 0x93b0230e usb_serial_port_softint +EXPORT_SYMBOL_GPL vmlinux 0x93b32d5b dm_rh_get_region_key +EXPORT_SYMBOL_GPL vmlinux 0x93d2422d snmp_mib_free +EXPORT_SYMBOL_GPL vmlinux 0x93d4d74a __class_create +EXPORT_SYMBOL_GPL vmlinux 0x93f1254b cpufreq_freq_attr_scaling_available_freqs +EXPORT_SYMBOL_GPL vmlinux 0x942c1704 cleanup_srcu_struct +EXPORT_SYMBOL_GPL vmlinux 0x9481713a get_device +EXPORT_SYMBOL_GPL vmlinux 0x9483c81f sysfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0x94a68723 ata_scsi_slave_destroy +EXPORT_SYMBOL_GPL vmlinux 0x94b5ab68 ata_std_qc_defer +EXPORT_SYMBOL_GPL vmlinux 0x94bb91b9 crypto_alg_lookup +EXPORT_SYMBOL_GPL vmlinux 0x94dc62d2 ata_scsi_ioctl +EXPORT_SYMBOL_GPL vmlinux 0x94ef4d05 cpci_hp_stop +EXPORT_SYMBOL_GPL vmlinux 0x94f661ed skb_to_sgvec +EXPORT_SYMBOL_GPL vmlinux 0x94f78d38 debugfs_create_blob +EXPORT_SYMBOL_GPL vmlinux 0x951c26ae led_trigger_register_simple +EXPORT_SYMBOL_GPL vmlinux 0x952664c5 do_exit +EXPORT_SYMBOL_GPL vmlinux 0x956a91ba gpio_get_value_cansleep +EXPORT_SYMBOL_GPL vmlinux 0x9577271c hpet_rtc_interrupt +EXPORT_SYMBOL_GPL vmlinux 0x959e62ae ata_sff_tf_read +EXPORT_SYMBOL_GPL vmlinux 0x95ddadcf ata_sff_dev_select +EXPORT_SYMBOL_GPL vmlinux 0x961a8cd3 unlock_policy_rwsem_read +EXPORT_SYMBOL_GPL vmlinux 0x964d5c39 acpi_os_map_memory +EXPORT_SYMBOL_GPL vmlinux 0x96540da3 inotify_dentry_parent_queue_event +EXPORT_SYMBOL_GPL vmlinux 0x96757641 debugfs_create_x16 +EXPORT_SYMBOL_GPL vmlinux 0x96b8eebf usb_sg_wait +EXPORT_SYMBOL_GPL vmlinux 0x96cbcf31 pm_qos_add_notifier +EXPORT_SYMBOL_GPL vmlinux 0x96f1bd3e blk_abort_queue +EXPORT_SYMBOL_GPL vmlinux 0x9724dad4 sysfs_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0x974f99a5 tcp_reno_ssthresh +EXPORT_SYMBOL_GPL vmlinux 0x97c9ece1 ata_eh_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0x97d8375d sdio_enable_func +EXPORT_SYMBOL_GPL vmlinux 0x97f52e0d d_materialise_unique +EXPORT_SYMBOL_GPL vmlinux 0x9833bc0c hvc_kick +EXPORT_SYMBOL_GPL vmlinux 0x9835a15d ata_link_online +EXPORT_SYMBOL_GPL vmlinux 0x989327ef blkcipher_walk_phys +EXPORT_SYMBOL_GPL vmlinux 0x989424f8 debugfs_rename +EXPORT_SYMBOL_GPL vmlinux 0x98a62878 bus_create_file +EXPORT_SYMBOL_GPL vmlinux 0x98adb824 hrtimer_forward +EXPORT_SYMBOL_GPL vmlinux 0x98ce553a fb_bl_default_curve +EXPORT_SYMBOL_GPL vmlinux 0x98dc1cb8 xenbus_switch_state +EXPORT_SYMBOL_GPL vmlinux 0x99065d5a dm_rh_mark_nosync +EXPORT_SYMBOL_GPL vmlinux 0x9924c496 __usb_get_extra_descriptor +EXPORT_SYMBOL_GPL vmlinux 0x995d1071 prof_on +EXPORT_SYMBOL_GPL vmlinux 0x99ceb25a disk_part_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x99dc9bde i2c_add_numbered_adapter +EXPORT_SYMBOL_GPL vmlinux 0x9a11a0fc crypto_attr_alg_name +EXPORT_SYMBOL_GPL vmlinux 0x9a21b92c regulator_get_mode +EXPORT_SYMBOL_GPL vmlinux 0x9a31f39f dm_rh_stop_recovery +EXPORT_SYMBOL_GPL vmlinux 0x9a398f5c xfrm_ealg_get_byname +EXPORT_SYMBOL_GPL vmlinux 0x9a3df726 get_current_tty +EXPORT_SYMBOL_GPL vmlinux 0x9a4d1034 idle_notifier_register +EXPORT_SYMBOL_GPL vmlinux 0x9a545456 usb_hcd_pci_probe +EXPORT_SYMBOL_GPL vmlinux 0x9ae6e68f __trace_note_message +EXPORT_SYMBOL_GPL vmlinux 0x9afac575 map_vm_area +EXPORT_SYMBOL_GPL vmlinux 0x9afbfad0 skcipher_geniv_init +EXPORT_SYMBOL_GPL vmlinux 0x9b08655a dm_region_hash_destroy +EXPORT_SYMBOL_GPL vmlinux 0x9b5225b6 i2c_new_device +EXPORT_SYMBOL_GPL vmlinux 0x9b5ac242 scsi_internal_device_block +EXPORT_SYMBOL_GPL vmlinux 0x9b6e594b raw_hash_sk +EXPORT_SYMBOL_GPL vmlinux 0x9b8a1454 tracepoint_iter_next +EXPORT_SYMBOL_GPL vmlinux 0x9b9840bf usb_clear_halt +EXPORT_SYMBOL_GPL vmlinux 0x9ba0501e unregister_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0x9bab96ac crypto_ablkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0x9bafbb15 ata_std_prereset +EXPORT_SYMBOL_GPL vmlinux 0x9c71db87 usb_create_hcd +EXPORT_SYMBOL_GPL vmlinux 0x9c918b90 disk_get_part +EXPORT_SYMBOL_GPL vmlinux 0x9cae3ded ata_wait_after_reset +EXPORT_SYMBOL_GPL vmlinux 0x9cb8037b xfrm_count_enc_supported +EXPORT_SYMBOL_GPL vmlinux 0x9cbb776c fsstack_copy_inode_size +EXPORT_SYMBOL_GPL vmlinux 0x9d06688b register_xenbus_watch +EXPORT_SYMBOL_GPL vmlinux 0x9d3850e1 gnttab_alloc_grant_references +EXPORT_SYMBOL_GPL vmlinux 0x9de5e149 devres_add +EXPORT_SYMBOL_GPL vmlinux 0x9e1a109e rt_mutex_lock_interruptible +EXPORT_SYMBOL_GPL vmlinux 0x9e30627a sata_link_resume +EXPORT_SYMBOL_GPL vmlinux 0x9e5f1f98 blk_queue_dma_drain +EXPORT_SYMBOL_GPL vmlinux 0x9e711ad2 pm_qos_requirement +EXPORT_SYMBOL_GPL vmlinux 0x9e7b7952 hrtimer_start +EXPORT_SYMBOL_GPL vmlinux 0x9e7d3442 xenbus_resume +EXPORT_SYMBOL_GPL vmlinux 0x9e7f3792 get_driver +EXPORT_SYMBOL_GPL vmlinux 0x9e9662ab user_describe +EXPORT_SYMBOL_GPL vmlinux 0x9eb0125b inet6_lookup +EXPORT_SYMBOL_GPL vmlinux 0x9ec8e34a page_cache_async_readahead +EXPORT_SYMBOL_GPL vmlinux 0x9ef123c8 ata_link_offline +EXPORT_SYMBOL_GPL vmlinux 0x9f14b527 hid_input_report +EXPORT_SYMBOL_GPL vmlinux 0x9f438b81 ata_port_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0x9f5deba4 register_kretprobes +EXPORT_SYMBOL_GPL vmlinux 0x9f628956 device_add +EXPORT_SYMBOL_GPL vmlinux 0x9faf54e5 crypto_tfm_in_queue +EXPORT_SYMBOL_GPL vmlinux 0x9fb5d63b sysdev_show_int +EXPORT_SYMBOL_GPL vmlinux 0x9fb6822d cpufreq_register_governor +EXPORT_SYMBOL_GPL vmlinux 0x9fbdf859 sdio_writew +EXPORT_SYMBOL_GPL vmlinux 0x9fc6ed55 dm_rh_dirty_log +EXPORT_SYMBOL_GPL vmlinux 0x9fce80db fb_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xa0040e57 mnt_drop_write +EXPORT_SYMBOL_GPL vmlinux 0xa0255440 net_ipv4_ctl_path +EXPORT_SYMBOL_GPL vmlinux 0xa02948f9 part_round_stats +EXPORT_SYMBOL_GPL vmlinux 0xa0523f4b crypto_larval_lookup +EXPORT_SYMBOL_GPL vmlinux 0xa052fac9 alloc_vm_area +EXPORT_SYMBOL_GPL vmlinux 0xa0f72bce unregister_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xa126e58b ata_sff_qc_issue +EXPORT_SYMBOL_GPL vmlinux 0xa14c50e4 hid_connect +EXPORT_SYMBOL_GPL vmlinux 0xa1596d98 acpi_processor_ffh_cstate_enter +EXPORT_SYMBOL_GPL vmlinux 0xa1a2f865 hidinput_connect +EXPORT_SYMBOL_GPL vmlinux 0xa2245576 platform_device_alloc +EXPORT_SYMBOL_GPL vmlinux 0xa23d4044 blkcipher_walk_done +EXPORT_SYMBOL_GPL vmlinux 0xa2480258 dm_device_name +EXPORT_SYMBOL_GPL vmlinux 0xa2665331 scsi_nl_sock +EXPORT_SYMBOL_GPL vmlinux 0xa28d8527 usb_poison_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xa2c03841 bind_evtchn_to_irqhandler +EXPORT_SYMBOL_GPL vmlinux 0xa2e67f08 acpi_bus_generate_proc_event4 +EXPORT_SYMBOL_GPL vmlinux 0xa3008b2d proc_net_fops_create +EXPORT_SYMBOL_GPL vmlinux 0xa3421352 sysdev_class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xa353fffc xenbus_rm +EXPORT_SYMBOL_GPL vmlinux 0xa384e9de ata_sff_qc_prep +EXPORT_SYMBOL_GPL vmlinux 0xa39fa209 inet6_csk_bind_conflict +EXPORT_SYMBOL_GPL vmlinux 0xa3c80b59 dm_rh_start_recovery +EXPORT_SYMBOL_GPL vmlinux 0xa3d8109b hidinput_find_field +EXPORT_SYMBOL_GPL vmlinux 0xa3e91bd7 ata_port_abort +EXPORT_SYMBOL_GPL vmlinux 0xa3fc96f0 marker_probe_cb_noarg +EXPORT_SYMBOL_GPL vmlinux 0xa42ed0c8 tty_ldisc_flush +EXPORT_SYMBOL_GPL vmlinux 0xa452c297 hpet_mask_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa480e2ed led_trigger_remove +EXPORT_SYMBOL_GPL vmlinux 0xa4d58669 math_state_restore +EXPORT_SYMBOL_GPL vmlinux 0xa4ea5c84 hid_allocate_device +EXPORT_SYMBOL_GPL vmlinux 0xa5533946 get_user_pages_fast +EXPORT_SYMBOL_GPL vmlinux 0xa583d5be blk_set_cmd_filter_defaults +EXPORT_SYMBOL_GPL vmlinux 0xa596f330 tracepoint_iter_start +EXPORT_SYMBOL_GPL vmlinux 0xa5bf5c3e pm_qos_add_requirement +EXPORT_SYMBOL_GPL vmlinux 0xa5c36cec inotify_unmount_inodes +EXPORT_SYMBOL_GPL vmlinux 0xa5e14357 dm_rh_update_states +EXPORT_SYMBOL_GPL vmlinux 0xa5f38da7 ata_sff_dev_classify +EXPORT_SYMBOL_GPL vmlinux 0xa5f406d5 cpufreq_cpu_get +EXPORT_SYMBOL_GPL vmlinux 0xa60bc83d sk_clone +EXPORT_SYMBOL_GPL vmlinux 0xa64ccd3d pv_apic_ops +EXPORT_SYMBOL_GPL vmlinux 0xa6bd68b0 rtc_irq_set_freq +EXPORT_SYMBOL_GPL vmlinux 0xa6d2154e tty_ldisc_ref_wait +EXPORT_SYMBOL_GPL vmlinux 0xa6df8c9c regulator_bulk_free +EXPORT_SYMBOL_GPL vmlinux 0xa6f4320d unregister_rfkill_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa6f70ba4 da903x_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa71b5a8a usb_ep0_reinit +EXPORT_SYMBOL_GPL vmlinux 0xa71b6e79 kobject_uevent_env +EXPORT_SYMBOL_GPL vmlinux 0xa75c9a24 sdio_release_irq +EXPORT_SYMBOL_GPL vmlinux 0xa76ed488 sis_info133_for_sata +EXPORT_SYMBOL_GPL vmlinux 0xa82bab60 skcipher_geniv_free +EXPORT_SYMBOL_GPL vmlinux 0xa88ca2c2 usb_hcd_giveback_urb +EXPORT_SYMBOL_GPL vmlinux 0xa8f59416 gpio_direction_output +EXPORT_SYMBOL_GPL vmlinux 0xa9126bff hpet_set_rtc_irq_bit +EXPORT_SYMBOL_GPL vmlinux 0xa91fab15 sdio_writesb +EXPORT_SYMBOL_GPL vmlinux 0xa92c6424 pci_enable_rom +EXPORT_SYMBOL_GPL vmlinux 0xa93df210 pci_slots_kset +EXPORT_SYMBOL_GPL vmlinux 0xa963f49c tcp_orphan_count +EXPORT_SYMBOL_GPL vmlinux 0xa9843cc0 usb_hcd_pci_resume +EXPORT_SYMBOL_GPL vmlinux 0xa9c530b8 unregister_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xa9d3a194 ata_bmdma_stop +EXPORT_SYMBOL_GPL vmlinux 0xa9df995a tcp_reno_cong_avoid +EXPORT_SYMBOL_GPL vmlinux 0xa9e4fd1c sata_link_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xaa0435f8 blk_rq_cur_bytes +EXPORT_SYMBOL_GPL vmlinux 0xaa0cf39d set_cpus_allowed_ptr +EXPORT_SYMBOL_GPL vmlinux 0xaa7bd6dd sdio_claim_host +EXPORT_SYMBOL_GPL vmlinux 0xaa86cfb5 uv_possible_blades +EXPORT_SYMBOL_GPL vmlinux 0xaa8c4696 cpu_clock +EXPORT_SYMBOL_GPL vmlinux 0xaabe8903 mm_kobj +EXPORT_SYMBOL_GPL vmlinux 0xaacae138 __cpufreq_driver_getavg +EXPORT_SYMBOL_GPL vmlinux 0xaadef866 sdev_evt_send +EXPORT_SYMBOL_GPL vmlinux 0xab01acbe gnttab_request_free_callback +EXPORT_SYMBOL_GPL vmlinux 0xab1777fd ata_qc_complete +EXPORT_SYMBOL_GPL vmlinux 0xab57e311 tracepoint_probe_register +EXPORT_SYMBOL_GPL vmlinux 0xab5addab ata_qc_complete_multiple +EXPORT_SYMBOL_GPL vmlinux 0xab689607 audit_log_d_path +EXPORT_SYMBOL_GPL vmlinux 0xabb566fc device_create +EXPORT_SYMBOL_GPL vmlinux 0xac11ee71 audit_log_vformat +EXPORT_SYMBOL_GPL vmlinux 0xac41f592 tty_buffer_request_room +EXPORT_SYMBOL_GPL vmlinux 0xac439840 usb_autopm_put_interface +EXPORT_SYMBOL_GPL vmlinux 0xac9d742d class_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xacc19485 ibft_addr +EXPORT_SYMBOL_GPL vmlinux 0xace5c0fc usb_bus_list +EXPORT_SYMBOL_GPL vmlinux 0xad096363 xenbus_printf +EXPORT_SYMBOL_GPL vmlinux 0xad1ea67b rtc_set_mmss +EXPORT_SYMBOL_GPL vmlinux 0xad3fcdf0 blk_end_request_callback +EXPORT_SYMBOL_GPL vmlinux 0xad63a24e per_cpu____uv_hub_info +EXPORT_SYMBOL_GPL vmlinux 0xad8f4364 sdio_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xadcf69bb crypto_enqueue_request +EXPORT_SYMBOL_GPL vmlinux 0xade5f8e0 sysdev_show_ulong +EXPORT_SYMBOL_GPL vmlinux 0xae0c87ee pm_qos_remove_notifier +EXPORT_SYMBOL_GPL vmlinux 0xae1c6f5f cpufreq_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xae23e835 relay_file_operations +EXPORT_SYMBOL_GPL vmlinux 0xae2812fe debugfs_remove_recursive +EXPORT_SYMBOL_GPL vmlinux 0xae500d74 usb_match_id +EXPORT_SYMBOL_GPL vmlinux 0xaea20e3e blkdev_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xaf7112f6 device_register +EXPORT_SYMBOL_GPL vmlinux 0xaf7ecedd ata_host_detach +EXPORT_SYMBOL_GPL vmlinux 0xaf803abd pci_hp_change_slot_info +EXPORT_SYMBOL_GPL vmlinux 0xaf8766c9 ata_sff_freeze +EXPORT_SYMBOL_GPL vmlinux 0xaf87b8c6 do_kern_mount +EXPORT_SYMBOL_GPL vmlinux 0xafc654a1 vfs_removexattr +EXPORT_SYMBOL_GPL vmlinux 0xafc7c996 usb_unlink_anchored_urbs +EXPORT_SYMBOL_GPL vmlinux 0xb047f6a0 regulator_bulk_enable +EXPORT_SYMBOL_GPL vmlinux 0xb0605150 regulator_get_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xb07dfe09 file_ra_state_init +EXPORT_SYMBOL_GPL vmlinux 0xb0aa812e fips_enabled +EXPORT_SYMBOL_GPL vmlinux 0xb0eedea9 usb_wait_anchor_empty_timeout +EXPORT_SYMBOL_GPL vmlinux 0xb10d55bc cn_netlink_send +EXPORT_SYMBOL_GPL vmlinux 0xb17c8ad4 __blk_put_request +EXPORT_SYMBOL_GPL vmlinux 0xb1833c5e register_kretprobe +EXPORT_SYMBOL_GPL vmlinux 0xb1acbcce rcu_barrier_sched +EXPORT_SYMBOL_GPL vmlinux 0xb1e6ca54 nf_register_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xb215526b input_class +EXPORT_SYMBOL_GPL vmlinux 0xb247c957 usb_reset_configuration +EXPORT_SYMBOL_GPL vmlinux 0xb27005f5 device_suspend +EXPORT_SYMBOL_GPL vmlinux 0xb284888e crypto_mod_put +EXPORT_SYMBOL_GPL vmlinux 0xb287a1da ata_ehi_push_desc +EXPORT_SYMBOL_GPL vmlinux 0xb3253ed9 hpet_rtc_timer_init +EXPORT_SYMBOL_GPL vmlinux 0xb3275fd6 ip_build_and_send_pkt +EXPORT_SYMBOL_GPL vmlinux 0xb38a628f unregister_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xb3ba5eb6 xfrm_audit_policy_delete +EXPORT_SYMBOL_GPL vmlinux 0xb3d5e527 acpi_smbus_write +EXPORT_SYMBOL_GPL vmlinux 0xb3e6fdf6 ata_bmdma_start +EXPORT_SYMBOL_GPL vmlinux 0xb4d1eb51 sdio_align_size +EXPORT_SYMBOL_GPL vmlinux 0xb4da3a51 dma_get_required_mask +EXPORT_SYMBOL_GPL vmlinux 0xb4e14553 gnttab_query_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb4ea7cf7 kgdb_connected +EXPORT_SYMBOL_GPL vmlinux 0xb4fe6005 bus_find_device_by_name +EXPORT_SYMBOL_GPL vmlinux 0xb51fbd64 edac_op_state +EXPORT_SYMBOL_GPL vmlinux 0xb538b352 page_cache_sync_readahead +EXPORT_SYMBOL_GPL vmlinux 0xb53ae573 cpu_idle_wait +EXPORT_SYMBOL_GPL vmlinux 0xb5a6ebe2 wmi_remove_notify_handler +EXPORT_SYMBOL_GPL vmlinux 0xb5be7b03 apply_to_page_range +EXPORT_SYMBOL_GPL vmlinux 0xb5e0f163 vfs_test_lock +EXPORT_SYMBOL_GPL vmlinux 0xb5eb38c2 device_create_file +EXPORT_SYMBOL_GPL vmlinux 0xb606c00b tty_ldisc_deref +EXPORT_SYMBOL_GPL vmlinux 0xb612444d snmp_mib_init +EXPORT_SYMBOL_GPL vmlinux 0xb6230f1f gnttab_grant_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xb63550f5 __i2c_board_lock +EXPORT_SYMBOL_GPL vmlinux 0xb65091b3 selinux_secmark_refcount_dec +EXPORT_SYMBOL_GPL vmlinux 0xb698195a posix_timer_event +EXPORT_SYMBOL_GPL vmlinux 0xb6aeb661 ata_id_c_string +EXPORT_SYMBOL_GPL vmlinux 0xb6b0f9f0 ata_sff_tf_load +EXPORT_SYMBOL_GPL vmlinux 0xb6c7316f hid_add_device +EXPORT_SYMBOL_GPL vmlinux 0xb73d9775 rt_mutex_destroy +EXPORT_SYMBOL_GPL vmlinux 0xb74c3e63 crypto_blkcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xb79f8787 cpci_hp_register_bus +EXPORT_SYMBOL_GPL vmlinux 0xb7c2d4b2 relay_reset +EXPORT_SYMBOL_GPL vmlinux 0xb7d7c12e hpet_set_alarm_time +EXPORT_SYMBOL_GPL vmlinux 0xb8252b2b dm_rh_region_context +EXPORT_SYMBOL_GPL vmlinux 0xb8eeffd9 inotify_rm_wd +EXPORT_SYMBOL_GPL vmlinux 0xb903674c scatterwalk_map_and_copy +EXPORT_SYMBOL_GPL vmlinux 0xb907290d tcp_get_info +EXPORT_SYMBOL_GPL vmlinux 0xb99d5837 xenbus_read +EXPORT_SYMBOL_GPL vmlinux 0xb9c3a6a9 platform_device_add_data +EXPORT_SYMBOL_GPL vmlinux 0xb9eb3aa9 add_uevent_var +EXPORT_SYMBOL_GPL vmlinux 0xbabd9f0d tty_prepare_flip_string_flags +EXPORT_SYMBOL_GPL vmlinux 0xbabfe114 __scsi_get_command +EXPORT_SYMBOL_GPL vmlinux 0xbae34c27 scsi_nl_remove_transport +EXPORT_SYMBOL_GPL vmlinux 0xbb290917 rtc_class_open +EXPORT_SYMBOL_GPL vmlinux 0xbb33082b crypto_lookup_template +EXPORT_SYMBOL_GPL vmlinux 0xbb36377a driver_attach +EXPORT_SYMBOL_GPL vmlinux 0xbbb98859 edid_info +EXPORT_SYMBOL_GPL vmlinux 0xbbcdd269 usb_bulk_msg +EXPORT_SYMBOL_GPL vmlinux 0xbbef7a76 ata_sas_slave_configure +EXPORT_SYMBOL_GPL vmlinux 0xbc215c4a ata_host_suspend +EXPORT_SYMBOL_GPL vmlinux 0xbc2f8692 __ata_port_next_link +EXPORT_SYMBOL_GPL vmlinux 0xbc44a462 cpufreq_unregister_governor +EXPORT_SYMBOL_GPL vmlinux 0xbc5cf950 tcp_slow_start +EXPORT_SYMBOL_GPL vmlinux 0xbc7227df inet_csk_route_req +EXPORT_SYMBOL_GPL vmlinux 0xbcb1e855 da903x_read +EXPORT_SYMBOL_GPL vmlinux 0xbce12308 rtc_irq_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd25a9e8 device_unregister +EXPORT_SYMBOL_GPL vmlinux 0xbd41529c usb_kill_urb +EXPORT_SYMBOL_GPL vmlinux 0xbd506a46 unregister_hotplug_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xbd7387a6 driver_create_file +EXPORT_SYMBOL_GPL vmlinux 0xbdc028b8 tcp_reno_min_cwnd +EXPORT_SYMBOL_GPL vmlinux 0xbdd295f0 trace_vprintk +EXPORT_SYMBOL_GPL vmlinux 0xbde5e56e transport_destroy_device +EXPORT_SYMBOL_GPL vmlinux 0xbe1887e4 ata_unpack_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xbe214d59 platform_device_register_simple +EXPORT_SYMBOL_GPL vmlinux 0xbe28ec59 sock_prot_inuse_get +EXPORT_SYMBOL_GPL vmlinux 0xbe50b3c9 disk_part_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xbe73f8af register_net_sysctl_table +EXPORT_SYMBOL_GPL vmlinux 0xbe76ba15 ata_pci_device_resume +EXPORT_SYMBOL_GPL vmlinux 0xbe9b94bd sdio_memcpy_fromio +EXPORT_SYMBOL_GPL vmlinux 0xbeb3dfae transport_setup_device +EXPORT_SYMBOL_GPL vmlinux 0xbeb6552c pci_find_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xbf0606a2 inotify_inode_is_dead +EXPORT_SYMBOL_GPL vmlinux 0xbf0be2f5 usb_submit_urb +EXPORT_SYMBOL_GPL vmlinux 0xbf2d7d79 hvc_instantiate +EXPORT_SYMBOL_GPL vmlinux 0xbf46212e proc_net_remove +EXPORT_SYMBOL_GPL vmlinux 0xbf74eb20 probe_kernel_write +EXPORT_SYMBOL_GPL vmlinux 0xbfadf2ac crypto_init_spawn +EXPORT_SYMBOL_GPL vmlinux 0xc009d72b blk_rq_bytes +EXPORT_SYMBOL_GPL vmlinux 0xc00c8f8d swiotlb_sync_single_range_for_device +EXPORT_SYMBOL_GPL vmlinux 0xc01da9bd inotify_destroy +EXPORT_SYMBOL_GPL vmlinux 0xc0ec11a7 skcipher_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0xc10fa781 hvc_poll +EXPORT_SYMBOL_GPL vmlinux 0xc15991d8 fsstack_copy_attr_all +EXPORT_SYMBOL_GPL vmlinux 0xc17515d7 usb_hcds_loaded +EXPORT_SYMBOL_GPL vmlinux 0xc1a86893 cpufreq_frequency_table_target +EXPORT_SYMBOL_GPL vmlinux 0xc1c60b1b inet_csk_search_req +EXPORT_SYMBOL_GPL vmlinux 0xc2083518 class_interface_register +EXPORT_SYMBOL_GPL vmlinux 0xc22a3091 vm_unmap_aliases +EXPORT_SYMBOL_GPL vmlinux 0xc26351f8 bind_evtchn_to_irq +EXPORT_SYMBOL_GPL vmlinux 0xc28bd7f2 ata_eh_thaw_port +EXPORT_SYMBOL_GPL vmlinux 0xc2f2284e usb_hub_tt_clear_buffer +EXPORT_SYMBOL_GPL vmlinux 0xc2f7292c destroy_workqueue +EXPORT_SYMBOL_GPL vmlinux 0xc2fb2b59 hwmon_device_register +EXPORT_SYMBOL_GPL vmlinux 0xc34efe27 snmp_fold_field +EXPORT_SYMBOL_GPL vmlinux 0xc388c73c dev_attr_unload_heads +EXPORT_SYMBOL_GPL vmlinux 0xc399468f scsi_nl_remove_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3bd7fc1 ata_eh_qc_retry +EXPORT_SYMBOL_GPL vmlinux 0xc3cbe1e5 scsi_nl_add_driver +EXPORT_SYMBOL_GPL vmlinux 0xc3f11443 usb_deregister_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xc41b487b kset_create_and_add +EXPORT_SYMBOL_GPL vmlinux 0xc428068d sata_deb_timing_long +EXPORT_SYMBOL_GPL vmlinux 0xc42f2f94 xenbus_read_driver_state +EXPORT_SYMBOL_GPL vmlinux 0xc42f91e0 sysdev_store_ulong +EXPORT_SYMBOL_GPL vmlinux 0xc48b7ccf ata_mode_string +EXPORT_SYMBOL_GPL vmlinux 0xc4b33aa6 tracepoint_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4c05569 input_ff_erase +EXPORT_SYMBOL_GPL vmlinux 0xc4c552d7 stop_machine +EXPORT_SYMBOL_GPL vmlinux 0xc4ce6189 idle_notifier_unregister +EXPORT_SYMBOL_GPL vmlinux 0xc4db6be8 pci_find_ext_capability +EXPORT_SYMBOL_GPL vmlinux 0xc512626a __supported_pte_mask +EXPORT_SYMBOL_GPL vmlinux 0xc5397da6 xenbus_mkdir +EXPORT_SYMBOL_GPL vmlinux 0xc54bd4d7 power_supply_am_i_supplied +EXPORT_SYMBOL_GPL vmlinux 0xc5a61718 dm_unregister_path_selector +EXPORT_SYMBOL_GPL vmlinux 0xc5b169ba crypto_register_template +EXPORT_SYMBOL_GPL vmlinux 0xc60b9a6c xenbus_free_evtchn +EXPORT_SYMBOL_GPL vmlinux 0xc60fe172 crypto_alloc_instance +EXPORT_SYMBOL_GPL vmlinux 0xc635ae8b hid_report_raw_event +EXPORT_SYMBOL_GPL vmlinux 0xc6730fc2 klist_iter_init +EXPORT_SYMBOL_GPL vmlinux 0xc673e23e ata_scsi_change_queue_depth +EXPORT_SYMBOL_GPL vmlinux 0xc6876ba3 usb_unlink_urb +EXPORT_SYMBOL_GPL vmlinux 0xc6c85b87 page_mkclean +EXPORT_SYMBOL_GPL vmlinux 0xc7504484 tracepoint_get_iter_range +EXPORT_SYMBOL_GPL vmlinux 0xc7727a2a crypto_grab_aead +EXPORT_SYMBOL_GPL vmlinux 0xc77bbc73 cpufreq_frequency_table_verify +EXPORT_SYMBOL_GPL vmlinux 0xc7aaec22 spi_write_then_read +EXPORT_SYMBOL_GPL vmlinux 0xc7ec11f6 atomic_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xc83b32f0 uhci_reset_hc +EXPORT_SYMBOL_GPL vmlinux 0xc83be3dc cpufreq_register_driver +EXPORT_SYMBOL_GPL vmlinux 0xc84bcf55 bt_class +EXPORT_SYMBOL_GPL vmlinux 0xc87c1f84 ktime_get +EXPORT_SYMBOL_GPL vmlinux 0xc87e487a sched_clock_idle_sleep_event +EXPORT_SYMBOL_GPL vmlinux 0xc8ea1705 sysfs_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xc8ea8106 ip6_sk_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xc9256184 crypto_drop_spawn +EXPORT_SYMBOL_GPL vmlinux 0xc9323108 dm_rh_get_region_size +EXPORT_SYMBOL_GPL vmlinux 0xc94d8c75 pcie_port_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xc9561772 fb_destroy_modelist +EXPORT_SYMBOL_GPL vmlinux 0xc9a56afa ata_sff_irq_on +EXPORT_SYMBOL_GPL vmlinux 0xc9d2b99d driver_find_device +EXPORT_SYMBOL_GPL vmlinux 0xc9d4d6d1 wmi_has_guid +EXPORT_SYMBOL_GPL vmlinux 0xc9dcefd9 cpci_hp_unregister_bus +EXPORT_SYMBOL_GPL vmlinux 0xc9fb576b tty_encode_baud_rate +EXPORT_SYMBOL_GPL vmlinux 0xca2bc12f security_inode_setattr +EXPORT_SYMBOL_GPL vmlinux 0xca33647d inotify_find_update_watch +EXPORT_SYMBOL_GPL vmlinux 0xca42a604 rdev_get_drvdata +EXPORT_SYMBOL_GPL vmlinux 0xca81ea9a xenbus_transaction_end +EXPORT_SYMBOL_GPL vmlinux 0xcabe04de cpuidle_resume_and_unlock +EXPORT_SYMBOL_GPL vmlinux 0xcae444a5 security_inode_permission +EXPORT_SYMBOL_GPL vmlinux 0xcb0296f5 usb_serial_generic_open +EXPORT_SYMBOL_GPL vmlinux 0xcb02ee42 ata_port_start +EXPORT_SYMBOL_GPL vmlinux 0xcb78b726 inet_hash_connect +EXPORT_SYMBOL_GPL vmlinux 0xcb8d669e seq_release_net +EXPORT_SYMBOL_GPL vmlinux 0xcbdcedad dm_put +EXPORT_SYMBOL_GPL vmlinux 0xcc018d9c register_kprobe +EXPORT_SYMBOL_GPL vmlinux 0xcc1f1c3d inet_twdr_hangman +EXPORT_SYMBOL_GPL vmlinux 0xcc4fb3b7 sdio_release_host +EXPORT_SYMBOL_GPL vmlinux 0xcc6ab305 is_dock_device +EXPORT_SYMBOL_GPL vmlinux 0xcccfb2fa sata_deb_timing_hotplug +EXPORT_SYMBOL_GPL vmlinux 0xccfa05ae scsi_internal_device_unblock +EXPORT_SYMBOL_GPL vmlinux 0xcd141bb1 task_current_syscall +EXPORT_SYMBOL_GPL vmlinux 0xcd3d395b tty_perform_flush +EXPORT_SYMBOL_GPL vmlinux 0xcd46e856 tcp_set_state +EXPORT_SYMBOL_GPL vmlinux 0xcd856bfb __rtnl_register +EXPORT_SYMBOL_GPL vmlinux 0xcd9991a9 usb_usual_set_present +EXPORT_SYMBOL_GPL vmlinux 0xcda06d2e spi_alloc_device +EXPORT_SYMBOL_GPL vmlinux 0xcdb5a0bc da903x_write +EXPORT_SYMBOL_GPL vmlinux 0xcdca3691 nr_irqs +EXPORT_SYMBOL_GPL vmlinux 0xce0c22cc ata_sas_port_start +EXPORT_SYMBOL_GPL vmlinux 0xce24aa99 debugfs_create_bool +EXPORT_SYMBOL_GPL vmlinux 0xcea58ab4 ata_do_dev_read_id +EXPORT_SYMBOL_GPL vmlinux 0xcecbaeff sysfs_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xcf26b70d pciserial_remove_ports +EXPORT_SYMBOL_GPL vmlinux 0xcf487ee1 inet_csk_compat_getsockopt +EXPORT_SYMBOL_GPL vmlinux 0xcf6fe774 inotify_init +EXPORT_SYMBOL_GPL vmlinux 0xcf96b4b1 relay_buf_full +EXPORT_SYMBOL_GPL vmlinux 0xcfb2ec6c usb_string +EXPORT_SYMBOL_GPL vmlinux 0xcfcc83ad register_vt_notifier +EXPORT_SYMBOL_GPL vmlinux 0xd027a07d marker_probe_unregister +EXPORT_SYMBOL_GPL vmlinux 0xd0292050 ata_cable_40wire +EXPORT_SYMBOL_GPL vmlinux 0xd03c7700 secure_ipv4_port_ephemeral +EXPORT_SYMBOL_GPL vmlinux 0xd074f1e6 class_dev_iter_exit +EXPORT_SYMBOL_GPL vmlinux 0xd082fe82 dm_rh_bio_to_region +EXPORT_SYMBOL_GPL vmlinux 0xd09aebb2 scsi_register_device_handler +EXPORT_SYMBOL_GPL vmlinux 0xd0c05159 emergency_restart +EXPORT_SYMBOL_GPL vmlinux 0xd0d342a1 smp_ops +EXPORT_SYMBOL_GPL vmlinux 0xd11df9db device_find_child +EXPORT_SYMBOL_GPL vmlinux 0xd16712f3 crypto_check_attr_type +EXPORT_SYMBOL_GPL vmlinux 0xd17e528d debugfs_create_symlink +EXPORT_SYMBOL_GPL vmlinux 0xd1ce26aa device_create_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xd23fbb35 simple_attr_write +EXPORT_SYMBOL_GPL vmlinux 0xd273b1b1 __round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xd287c829 ipv6_dup_options +EXPORT_SYMBOL_GPL vmlinux 0xd2a8caf0 work_on_cpu +EXPORT_SYMBOL_GPL vmlinux 0xd2ee9f4e queue_delayed_work +EXPORT_SYMBOL_GPL vmlinux 0xd39d813f led_trigger_register +EXPORT_SYMBOL_GPL vmlinux 0xd3b78da3 xenbus_suspend_cancel +EXPORT_SYMBOL_GPL vmlinux 0xd3caf79d devres_remove_group +EXPORT_SYMBOL_GPL vmlinux 0xd4815ae7 sysfs_chmod_file +EXPORT_SYMBOL_GPL vmlinux 0xd4eb8d99 inet6_csk_xmit +EXPORT_SYMBOL_GPL vmlinux 0xd53d535d sysfs_remove_file_from_group +EXPORT_SYMBOL_GPL vmlinux 0xd58bfbd9 sysfs_get +EXPORT_SYMBOL_GPL vmlinux 0xd599ec20 sysfs_notify +EXPORT_SYMBOL_GPL vmlinux 0xd5cc685c usb_serial_deregister +EXPORT_SYMBOL_GPL vmlinux 0xd5dfabf7 ata_sas_port_destroy +EXPORT_SYMBOL_GPL vmlinux 0xd662b14c mnt_want_write +EXPORT_SYMBOL_GPL vmlinux 0xd6f4c2af mmput +EXPORT_SYMBOL_GPL vmlinux 0xd6feefa5 agp_num_entries +EXPORT_SYMBOL_GPL vmlinux 0xd71c2a71 sata_sff_hardreset +EXPORT_SYMBOL_GPL vmlinux 0xd751263b rtc_irq_set_state +EXPORT_SYMBOL_GPL vmlinux 0xd77423d9 inotify_rm_watch +EXPORT_SYMBOL_GPL vmlinux 0xd7a08a6c usb_put_intf +EXPORT_SYMBOL_GPL vmlinux 0xd7d79132 put_online_cpus +EXPORT_SYMBOL_GPL vmlinux 0xd7ea2c4f rdev_get_id +EXPORT_SYMBOL_GPL vmlinux 0xd830b79f sysfs_create_group +EXPORT_SYMBOL_GPL vmlinux 0xd84cd7f4 ata_timing_find_mode +EXPORT_SYMBOL_GPL vmlinux 0xd85d7d23 usb_store_new_id +EXPORT_SYMBOL_GPL vmlinux 0xd8c3c5fe sdio_readl +EXPORT_SYMBOL_GPL vmlinux 0xd8cd63cd dm_rh_flush +EXPORT_SYMBOL_GPL vmlinux 0xd8eae586 debugfs_create_x32 +EXPORT_SYMBOL_GPL vmlinux 0xd8f4e07f securityfs_create_file +EXPORT_SYMBOL_GPL vmlinux 0xd9042fa8 scatterwalk_map +EXPORT_SYMBOL_GPL vmlinux 0xd90a18ed find_pid_ns +EXPORT_SYMBOL_GPL vmlinux 0xda29f8b0 wmi_set_block +EXPORT_SYMBOL_GPL vmlinux 0xda7ba0de inet_csk_compat_setsockopt +EXPORT_SYMBOL_GPL vmlinux 0xdaab02df crypto_dequeue_request +EXPORT_SYMBOL_GPL vmlinux 0xdab5baca pid_vnr +EXPORT_SYMBOL_GPL vmlinux 0xdaf4dfb3 fb_mode_option +EXPORT_SYMBOL_GPL vmlinux 0xdc1f8f2e register_timer_hook +EXPORT_SYMBOL_GPL vmlinux 0xdc8c92a2 blk_end_request +EXPORT_SYMBOL_GPL vmlinux 0xdd526358 da903x_unregister_notifier +EXPORT_SYMBOL_GPL vmlinux 0xdd5c4942 srcu_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xddb0bc1c __blkdev_driver_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xde134c69 storage_usb_ids +EXPORT_SYMBOL_GPL vmlinux 0xde6afccd ipv6_opt_accepted +EXPORT_SYMBOL_GPL vmlinux 0xdec38cd4 transport_remove_device +EXPORT_SYMBOL_GPL vmlinux 0xdf3022b2 ata_sff_interrupt +EXPORT_SYMBOL_GPL vmlinux 0xdf3c19ec cn_add_callback +EXPORT_SYMBOL_GPL vmlinux 0xdf61ca24 usb_alloc_urb +EXPORT_SYMBOL_GPL vmlinux 0xe01d75df tty_find_polling_driver +EXPORT_SYMBOL_GPL vmlinux 0xe04eb9f6 usb_buffer_map_sg +EXPORT_SYMBOL_GPL vmlinux 0xe060fea6 inverse_translate +EXPORT_SYMBOL_GPL vmlinux 0xe087c883 debugfs_create_u8 +EXPORT_SYMBOL_GPL vmlinux 0xe089cfcc agp_memory_reserved +EXPORT_SYMBOL_GPL vmlinux 0xe0ef923b led_trigger_set_default +EXPORT_SYMBOL_GPL vmlinux 0xe0fd3846 pci_create_slot +EXPORT_SYMBOL_GPL vmlinux 0xe1093c71 queue_delayed_work_on +EXPORT_SYMBOL_GPL vmlinux 0xe12ef4cc usb_control_msg +EXPORT_SYMBOL_GPL vmlinux 0xe14fbc07 usb_serial_generic_read_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0xe187df9c __mmdrop +EXPORT_SYMBOL_GPL vmlinux 0xe21a0bcb vfs_cancel_lock +EXPORT_SYMBOL_GPL vmlinux 0xe24ff917 blocking_notifier_chain_register +EXPORT_SYMBOL_GPL vmlinux 0xe2745581 pci_hp_register +EXPORT_SYMBOL_GPL vmlinux 0xe295c0ff is_hpet_enabled +EXPORT_SYMBOL_GPL vmlinux 0xe2cc626b device_del +EXPORT_SYMBOL_GPL vmlinux 0xe2cd352e bus_sort_breadthfirst +EXPORT_SYMBOL_GPL vmlinux 0xe3198ba2 ata_sff_hsm_move +EXPORT_SYMBOL_GPL vmlinux 0xe34358a0 spi_unregister_master +EXPORT_SYMBOL_GPL vmlinux 0xe3774e81 crypto_unregister_template +EXPORT_SYMBOL_GPL vmlinux 0xe3b5f581 device_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe3be2a7e usb_hcd_resume_root_hub +EXPORT_SYMBOL_GPL vmlinux 0xe3e69990 attribute_container_classdev_to_container +EXPORT_SYMBOL_GPL vmlinux 0xe3e7ba4a user_read +EXPORT_SYMBOL_GPL vmlinux 0xe48d5eac acpi_ec_add_query_handler +EXPORT_SYMBOL_GPL vmlinux 0xe49ff3b0 ata_wait_register +EXPORT_SYMBOL_GPL vmlinux 0xe513afc0 cache_k8_northbridges +EXPORT_SYMBOL_GPL vmlinux 0xe52c0d40 bus_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xe52fa4a4 blk_rq_check_limits +EXPORT_SYMBOL_GPL vmlinux 0xe530071c pm_qos_remove_requirement +EXPORT_SYMBOL_GPL vmlinux 0xe53090cd ata_sff_dma_pause +EXPORT_SYMBOL_GPL vmlinux 0xe597bc89 i2c_new_probed_device +EXPORT_SYMBOL_GPL vmlinux 0xe5a0d977 ip6_dst_lookup +EXPORT_SYMBOL_GPL vmlinux 0xe61a6d2f gpio_unexport +EXPORT_SYMBOL_GPL vmlinux 0xe62c4f50 rtc_set_alarm +EXPORT_SYMBOL_GPL vmlinux 0xe6488b47 cpufreq_notify_transition +EXPORT_SYMBOL_GPL vmlinux 0xe6491b9d md_do_sync +EXPORT_SYMBOL_GPL vmlinux 0xe66e531c dequeue_signal +EXPORT_SYMBOL_GPL vmlinux 0xe674a5cb srcu_read_lock +EXPORT_SYMBOL_GPL vmlinux 0xe6a92a86 rtnl_link_unregister +EXPORT_SYMBOL_GPL vmlinux 0xe72589b0 ata_sff_softreset +EXPORT_SYMBOL_GPL vmlinux 0xe75382b6 bus_register_notifier +EXPORT_SYMBOL_GPL vmlinux 0xe7b6c28a dm_region_hash_create +EXPORT_SYMBOL_GPL vmlinux 0xe7fa47ad srcu_read_unlock +EXPORT_SYMBOL_GPL vmlinux 0xe81af31a crypto_alg_sem +EXPORT_SYMBOL_GPL vmlinux 0xe8448267 platform_get_resource_byname +EXPORT_SYMBOL_GPL vmlinux 0xe8514def kern_mount_data +EXPORT_SYMBOL_GPL vmlinux 0xe89f0e9e hid_parse_report +EXPORT_SYMBOL_GPL vmlinux 0xe8be598a ata_sas_port_init +EXPORT_SYMBOL_GPL vmlinux 0xe8f9dfaf uv_cpu_to_blade +EXPORT_SYMBOL_GPL vmlinux 0xe8ff38c4 dm_rh_dec +EXPORT_SYMBOL_GPL vmlinux 0xe9323263 usb_hcd_pci_suspend +EXPORT_SYMBOL_GPL vmlinux 0xe93e49c3 devres_free +EXPORT_SYMBOL_GPL vmlinux 0xe9428a2c hvc_alloc +EXPORT_SYMBOL_GPL vmlinux 0xe9511ef3 unregister_pernet_device +EXPORT_SYMBOL_GPL vmlinux 0xe9587909 usb_unregister_notify +EXPORT_SYMBOL_GPL vmlinux 0xe9cb5d4d usb_free_urb +EXPORT_SYMBOL_GPL vmlinux 0xe9ce504f cpufreq_frequency_table_cpuinfo +EXPORT_SYMBOL_GPL vmlinux 0xea065e01 task_handoff_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea195699 usb_remove_hcd +EXPORT_SYMBOL_GPL vmlinux 0xea418e0f atapi_cmd_type +EXPORT_SYMBOL_GPL vmlinux 0xea7a2825 xenbus_dev_error +EXPORT_SYMBOL_GPL vmlinux 0xea7e21b9 sysdev_remove_file +EXPORT_SYMBOL_GPL vmlinux 0xea863751 regulator_unregister +EXPORT_SYMBOL_GPL vmlinux 0xea8b5cf1 crypto_mod_get +EXPORT_SYMBOL_GPL vmlinux 0xea998a5d debugfs_create_x8 +EXPORT_SYMBOL_GPL vmlinux 0xeae74760 scsi_nl_send_transport_msg +EXPORT_SYMBOL_GPL vmlinux 0xeafa576d usb_autopm_get_interface +EXPORT_SYMBOL_GPL vmlinux 0xeb46cadf xenbus_frontend_closed +EXPORT_SYMBOL_GPL vmlinux 0xeb537537 regulator_set_current_limit +EXPORT_SYMBOL_GPL vmlinux 0xeb55ca25 platform_device_put +EXPORT_SYMBOL_GPL vmlinux 0xec127d57 usb_reset_device +EXPORT_SYMBOL_GPL vmlinux 0xec1b043e regulator_suspend_prepare +EXPORT_SYMBOL_GPL vmlinux 0xec31d3c8 crypto_rng_type +EXPORT_SYMBOL_GPL vmlinux 0xec95a47c crypto_larval_alloc +EXPORT_SYMBOL_GPL vmlinux 0xeccea98f xenbus_map_ring +EXPORT_SYMBOL_GPL vmlinux 0xecd045c5 usb_hcd_pci_shutdown +EXPORT_SYMBOL_GPL vmlinux 0xed0690a5 ehci_cf_port_reset_rwsem +EXPORT_SYMBOL_GPL vmlinux 0xed54d3c0 platform_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xed9867c9 inet_twsk_put +EXPORT_SYMBOL_GPL vmlinux 0xedaa25f5 ata_sff_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xedbc6f67 gnttab_end_foreign_access +EXPORT_SYMBOL_GPL vmlinux 0xee97d6b9 platform_bus +EXPORT_SYMBOL_GPL vmlinux 0xeeca13e9 crypto_hash_walk_first +EXPORT_SYMBOL_GPL vmlinux 0xeefc9777 pci_intx +EXPORT_SYMBOL_GPL vmlinux 0xef45a23f bd_release_from_disk +EXPORT_SYMBOL_GPL vmlinux 0xef6c3f70 round_jiffies_up_relative +EXPORT_SYMBOL_GPL vmlinux 0xef6ed231 tcp_done +EXPORT_SYMBOL_GPL vmlinux 0xef8b39cd vlan_dev_real_dev +EXPORT_SYMBOL_GPL vmlinux 0xef961022 tcp_twsk_unique +EXPORT_SYMBOL_GPL vmlinux 0xef9beca8 uv_region_size +EXPORT_SYMBOL_GPL vmlinux 0xf0209ea5 register_pernet_gen_device +EXPORT_SYMBOL_GPL vmlinux 0xf031a2dd blk_trace_startstop +EXPORT_SYMBOL_GPL vmlinux 0xf042da1a shmem_file_setup +EXPORT_SYMBOL_GPL vmlinux 0xf0e369af usb_register_device_driver +EXPORT_SYMBOL_GPL vmlinux 0xf10e1d07 rtnl_link_register +EXPORT_SYMBOL_GPL vmlinux 0xf1150e76 cpufreq_driver_target +EXPORT_SYMBOL_GPL vmlinux 0xf146c070 pci_reset_function +EXPORT_SYMBOL_GPL vmlinux 0xf184d189 kernel_power_off +EXPORT_SYMBOL_GPL vmlinux 0xf1b445cd tcp_twsk_destructor +EXPORT_SYMBOL_GPL vmlinux 0xf1d55bb3 pci_find_next_ht_capability +EXPORT_SYMBOL_GPL vmlinux 0xf22c8905 crypto_default_rng +EXPORT_SYMBOL_GPL vmlinux 0xf2683bd9 disk_map_sector_rcu +EXPORT_SYMBOL_GPL vmlinux 0xf2756a75 aead_geniv_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf2855040 platform_get_irq_byname +EXPORT_SYMBOL_GPL vmlinux 0xf2c53d61 sdio_unregister_driver +EXPORT_SYMBOL_GPL vmlinux 0xf2dac98f ata_host_start +EXPORT_SYMBOL_GPL vmlinux 0xf2fca922 uart_parse_options +EXPORT_SYMBOL_GPL vmlinux 0xf30ff34a device_create_vargs +EXPORT_SYMBOL_GPL vmlinux 0xf3407eae xenbus_bind_evtchn +EXPORT_SYMBOL_GPL vmlinux 0xf3432821 crypto_givcipher_type +EXPORT_SYMBOL_GPL vmlinux 0xf383cbac class_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf3a6af55 register_jprobes +EXPORT_SYMBOL_GPL vmlinux 0xf3be8436 __pneigh_lookup +EXPORT_SYMBOL_GPL vmlinux 0xf3d5cc13 ata_timing_merge +EXPORT_SYMBOL_GPL vmlinux 0xf43a05b5 ata_sas_port_alloc +EXPORT_SYMBOL_GPL vmlinux 0xf499fdb2 rcu_barrier_bh +EXPORT_SYMBOL_GPL vmlinux 0xf4aebdc3 xenbus_suspend +EXPORT_SYMBOL_GPL vmlinux 0xf51f4f40 pci_hp_deregister +EXPORT_SYMBOL_GPL vmlinux 0xf53bbc2e regulator_get +EXPORT_SYMBOL_GPL vmlinux 0xf5498c4e tty_mode_ioctl +EXPORT_SYMBOL_GPL vmlinux 0xf54f2944 dm_register_path_selector +EXPORT_SYMBOL_GPL vmlinux 0xf553318d cpuidle_pause_and_lock +EXPORT_SYMBOL_GPL vmlinux 0xf5945bac gnttab_free_grant_references +EXPORT_SYMBOL_GPL vmlinux 0xf5965790 ata_sff_postreset +EXPORT_SYMBOL_GPL vmlinux 0xf5a691cd invalidate_bh_lrus +EXPORT_SYMBOL_GPL vmlinux 0xf5d148a1 user_destroy +EXPORT_SYMBOL_GPL vmlinux 0xf64c8572 unregister_pernet_gen_subsys +EXPORT_SYMBOL_GPL vmlinux 0xf654381a ata_pci_bmdma_init +EXPORT_SYMBOL_GPL vmlinux 0xf66eeb6e crypto_alloc_base +EXPORT_SYMBOL_GPL vmlinux 0xf6aaa689 bd_claim_by_disk +EXPORT_SYMBOL_GPL vmlinux 0xf6bcbd73 hwrng_register +EXPORT_SYMBOL_GPL vmlinux 0xf6d6cd44 crypto_hash_type +EXPORT_SYMBOL_GPL vmlinux 0xf6e9813e xfrm_audit_state_notfound +EXPORT_SYMBOL_GPL vmlinux 0xf7016530 xenbus_gather +EXPORT_SYMBOL_GPL vmlinux 0xf7394c69 skb_icv_walk +EXPORT_SYMBOL_GPL vmlinux 0xf73e8612 swiotlb_sync_single_range_for_cpu +EXPORT_SYMBOL_GPL vmlinux 0xf7427c4c register_jprobe +EXPORT_SYMBOL_GPL vmlinux 0xf74b6102 vfs_lock_file +EXPORT_SYMBOL_GPL vmlinux 0xf77b41de ata_do_set_mode +EXPORT_SYMBOL_GPL vmlinux 0xf7889e8d seq_open_net +EXPORT_SYMBOL_GPL vmlinux 0xf7cd966e sysdev_driver_unregister +EXPORT_SYMBOL_GPL vmlinux 0xf7d34928 bus_get_device_klist +EXPORT_SYMBOL_GPL vmlinux 0xf7f513d0 rt_mutex_lock +EXPORT_SYMBOL_GPL vmlinux 0xf8025dd7 ata_timing_compute +EXPORT_SYMBOL_GPL vmlinux 0xf80c560d tcp_death_row +EXPORT_SYMBOL_GPL vmlinux 0xf83a49cb ata_dev_pair +EXPORT_SYMBOL_GPL vmlinux 0xf8802492 print_stack_trace +EXPORT_SYMBOL_GPL vmlinux 0xf8814a46 skb_segment +EXPORT_SYMBOL_GPL vmlinux 0xf8f3a0fb ata_ratelimit +EXPORT_SYMBOL_GPL vmlinux 0xf8f3b59f sysfs_notify_dirent +EXPORT_SYMBOL_GPL vmlinux 0xf934120c vfs_listxattr +EXPORT_SYMBOL_GPL vmlinux 0xf95c4473 ata_pci_bmdma_clear_simplex +EXPORT_SYMBOL_GPL vmlinux 0xf96b2026 crypto_nivaead_type +EXPORT_SYMBOL_GPL vmlinux 0xf972e196 rfkill_restore_states +EXPORT_SYMBOL_GPL vmlinux 0xf97666a0 set_memory_rw +EXPORT_SYMBOL_GPL vmlinux 0xf9a054b5 __round_jiffies +EXPORT_SYMBOL_GPL vmlinux 0xf9c788ff xenbus_grant_ring +EXPORT_SYMBOL_GPL vmlinux 0xf9ca3160 ata_id_xfermask +EXPORT_SYMBOL_GPL vmlinux 0xfa1f4662 scatterwalk_start +EXPORT_SYMBOL_GPL vmlinux 0xfa45d31c driver_add_kobj +EXPORT_SYMBOL_GPL vmlinux 0xfa7715bf scsi_bus_type +EXPORT_SYMBOL_GPL vmlinux 0xfb2404c2 inet_csk_clone +EXPORT_SYMBOL_GPL vmlinux 0xfb882fb7 wmi_query_block +EXPORT_SYMBOL_GPL vmlinux 0xfbc016de blocking_notifier_call_chain +EXPORT_SYMBOL_GPL vmlinux 0xfbd43757 udp4_lib_lookup +EXPORT_SYMBOL_GPL vmlinux 0xfbe2a752 pci_bus_add_device +EXPORT_SYMBOL_GPL vmlinux 0xfbf3d2d8 inet_ctl_sock_create +EXPORT_SYMBOL_GPL vmlinux 0xfbf9be5d register_oom_notifier +EXPORT_SYMBOL_GPL vmlinux 0xfc083425 usb_serial_generic_write_bulk_callback +EXPORT_SYMBOL_GPL vmlinux 0xfc0c3095 dm_path_uevent +EXPORT_SYMBOL_GPL vmlinux 0xfc271a87 sdev_evt_send_simple +EXPORT_SYMBOL_GPL vmlinux 0xfc2ff860 uv_setup_irq +EXPORT_SYMBOL_GPL vmlinux 0xfc4d24e6 ata_std_error_handler +EXPORT_SYMBOL_GPL vmlinux 0xfc66a194 nf_unregister_afinfo +EXPORT_SYMBOL_GPL vmlinux 0xfc91103e find_get_pid +EXPORT_SYMBOL_GPL vmlinux 0xfcaf4b91 device_remove_bin_file +EXPORT_SYMBOL_GPL vmlinux 0xfcce694c rfkill_set_default +EXPORT_SYMBOL_GPL vmlinux 0xfd51b281 gnttab_end_foreign_access_ref +EXPORT_SYMBOL_GPL vmlinux 0xfda9c1d9 aead_geniv_exit +EXPORT_SYMBOL_GPL vmlinux 0xfdc42073 scsi_schedule_eh +EXPORT_SYMBOL_GPL vmlinux 0xfddb5844 usb_get_hcd +EXPORT_SYMBOL_GPL vmlinux 0xfde0b92c crypto_larval_error +EXPORT_SYMBOL_GPL vmlinux 0xfe727411 get_phys_to_machine +EXPORT_SYMBOL_GPL vmlinux 0xfe990052 gpio_free +EXPORT_SYMBOL_GPL vmlinux 0xfeb35a9e usb_match_one_id +EXPORT_SYMBOL_GPL vmlinux 0xfecbff96 __mark_empty_function +EXPORT_SYMBOL_GPL vmlinux 0xfed11ed1 usb_mon_deregister +EXPORT_SYMBOL_GPL vmlinux 0xfee18453 crypto_shoot_alg +EXPORT_SYMBOL_GPL vmlinux 0xfefee878 driver_register +EXPORT_SYMBOL_GPL vmlinux 0xff14e1e4 sysfs_get_dirent +EXPORT_SYMBOL_GPL vmlinux 0xff479ecb blk_queue_rq_timed_out +EXPORT_SYMBOL_GPL vmlinux 0xff5a8cfe cn_del_callback +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 init_mm +EXPORT_UNUSED_SYMBOL vmlinux 0x00000000 simple_prepare_write --- linux-2.6.28.orig/debian/d-i/kernel-versions.in +++ linux-2.6.28/debian/d-i/kernel-versions.in @@ -0,0 +1,9 @@ +# arch version flavour installedname suffix bdep +amd64 PKGVER-ABINUM generic PKGVER-ABINUM-generic - + +armel PKGVER-ABINUM iop32x PKGVER-ABINUM-iop32x y +armel PKGVER-ABINUM ixp4xx PKGVER-ABINUM-ixp4xx y +armel PKGVER-ABINUM orion5x PKGVER-ABINUM-orion5x y +armel PKGVER-ABINUM versatile PKGVER-ABINUM-versatile y + +i386 PKGVER-ABINUM generic PKGVER-ABINUM-generic - --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-ixp4xx +++ linux-2.6.28/debian/d-i/exclude-modules.armel-ixp4xx @@ -0,0 +1,2 @@ +fat-modules +storage-core-modules --- linux-2.6.28.orig/debian/d-i/package-list +++ linux-2.6.28/debian/d-i/package-list @@ -0,0 +1,169 @@ +Package: kernel-image +Provides_armel: crypto-modules, ext2-modules, ext3-modules, socket-modules, fat-modules +Provides_armel_versatile: crypto-modules, ext2-modules, ext3-modules, socket-modules, fb-modules + +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: jfs-modules, reiserfs-modules, xfs-modules +Provides_armel: jfs-modules, reiserfs-modules, xfs-modules +Description: Base filesystem modules + This includes jfs, reiserfs and xfs. + +Package: fs-secondary-modules +Depends: kernel-image, fat-modules +Priority: standard +Provides: ntfs-modules, hfs-modules +Description: Extra filesystem modules + This includes support for Windows NTFS and MacOS HFS/HFSPlus + +Package: input-modules +Depends: kernel-image, usb-modules +Priority: standard +Description: Support for various input methods + +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, virtio-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: 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: block-modules +Priority: standard +Depends: kernel-image, storage-core-modules, parport-modules, virtio-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. + +Package: virtio-modules +Priority: standard +Depends: kernel-image +Description: VirtIO Modules + Includes modules for VirtIO (virtual machine, generally kvm guests) + +Package: socket-modules +Depends: kernel-image +Priority: standard +Description: Unix socket support + +Package: mouse-modules +Depends: kernel-image, input-modules, usb-modules +Priority: extra +Description: Mouse support + This package contains mouse drivers for the Linux kernel. --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-iop32x +++ linux-2.6.28/debian/d-i/exclude-modules.armel-iop32x @@ -0,0 +1,2 @@ +fat-modules +storage-core-modules --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-versatile +++ linux-2.6.28/debian/d-i/exclude-modules.armel-versatile @@ -0,0 +1,2 @@ +fb-modules +storage-core-modules --- linux-2.6.28.orig/debian/d-i/kernel-versions +++ linux-2.6.28/debian/d-i/kernel-versions @@ -0,0 +1,9 @@ +# arch version flavour installedname suffix bdep +amd64 2.6.28-4 generic 2.6.28-4-generic - + +armel 2.6.28-4 iop32x 2.6.28-4-iop32x y +armel 2.6.28-4 ixp4xx 2.6.28-4-ixp4xx y +armel 2.6.28-4 orion5x 2.6.28-4-orion5x y +armel 2.6.28-4 versatile 2.6.28-4-versatile y + +i386 2.6.28-4 generic 2.6.28-4-generic - --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel +++ linux-2.6.28/debian/d-i/exclude-modules.armel @@ -0,0 +1,26 @@ +acpi-modules +block-modules +crypto-modules +ext2-modules +ext3-modules +fb-modules +firewire-core-modules +floppy-modules +input-modules +irda-modules +md-modules +message-modules +mouse-modules +nfs-modules +nic-shared-modules +parport-modules +pata-modules +pcmcia-modules +pcmcia-storage-modules +plip-modules +ppp-modules +sata-modules +serial-modules +socket-modules +usb-modules +virtio-modules --- linux-2.6.28.orig/debian/d-i/exclude-modules.armel-orion5x +++ linux-2.6.28/debian/d-i/exclude-modules.armel-orion5x @@ -0,0 +1 @@ +fat-modules --- linux-2.6.28.orig/debian/d-i/modules-armel-orion5x/storage-core-modules +++ linux-2.6.28/debian/d-i/modules-armel-orion5x/storage-core-modules @@ -0,0 +1,6 @@ +# Block level +cdrom +sr_mod + +# Needs to be here for better cdrom initrd layout +isofs --- linux-2.6.28.orig/debian/d-i/modules/storage-core-modules +++ linux-2.6.28/debian/d-i/modules/storage-core-modules @@ -0,0 +1,10 @@ +# Core stacks +usb-storage + +# Block level + +# Loop modules +cryptoloop + +# Needs to be here for better cdrom initrd layout +isofs --- linux-2.6.28.orig/debian/d-i/modules/ppp-modules +++ linux-2.6.28/debian/d-i/modules/ppp-modules @@ -0,0 +1,7 @@ +ppp_async +ppp_deflate +ppp_mppe +pppoe +pppox +ppp_synctty +syncppp --- linux-2.6.28.orig/debian/d-i/modules/virtio-modules +++ linux-2.6.28/debian/d-i/modules/virtio-modules @@ -0,0 +1,4 @@ +virtio_balloon +virtio_pci +virtio_ring ? +virtio-rng --- linux-2.6.28.orig/debian/d-i/modules/firewire-core-modules +++ linux-2.6.28/debian/d-i/modules/firewire-core-modules @@ -0,0 +1,4 @@ +ieee1394 +ohci1394 +sbp2 +eth1394 --- linux-2.6.28.orig/debian/d-i/modules/serial-modules +++ linux-2.6.28/debian/d-i/modules/serial-modules @@ -0,0 +1,3 @@ +generic_serial +serial_cs +synclink_cs --- linux-2.6.28.orig/debian/d-i/modules/usb-modules +++ linux-2.6.28/debian/d-i/modules/usb-modules @@ -0,0 +1,9 @@ +ehci-hcd +isp116x-hcd +isp1760 +ohci-hcd +r8a66597-hcd +sl811_cs +sl811-hcd +u132-hcd +uhci-hcd --- linux-2.6.28.orig/debian/d-i/modules/floppy-modules +++ linux-2.6.28/debian/d-i/modules/floppy-modules @@ -0,0 +1 @@ +floppy --- linux-2.6.28.orig/debian/d-i/modules/fb-modules +++ linux-2.6.28/debian/d-i/modules/fb-modules @@ -0,0 +1,3 @@ +fbcon +vesafb +vga16fb --- linux-2.6.28.orig/debian/d-i/modules/pcmcia-storage-modules +++ linux-2.6.28/debian/d-i/modules/pcmcia-storage-modules @@ -0,0 +1,6 @@ +pata_pcmcia +qlogic_cs +fdomain_cs +aha152x_cs ? +nsp_cs ? +sym53c500_cs --- linux-2.6.28.orig/debian/d-i/modules/nic-usb-modules +++ linux-2.6.28/debian/d-i/modules/nic-usb-modules @@ -0,0 +1,11 @@ +catc ? +kaweth ? +pegasus ? +prism2_usb ? +rtl8150 ? +usbnet ? +zd1211rw ? +zd1201 ? +rt2500usb ? +rt73usb ? +rt2570 ? --- linux-2.6.28.orig/debian/d-i/modules/pcmcia-modules +++ linux-2.6.28/debian/d-i/modules/pcmcia-modules @@ -0,0 +1,8 @@ +i82092 +i82365 ? +pcmcia +pcmcia_core +pd6729 +rsrc_nonstatic +tcic ? +yenta_socket --- linux-2.6.28.orig/debian/d-i/modules/input-modules +++ linux-2.6.28/debian/d-i/modules/input-modules @@ -0,0 +1,2 @@ +usbhid +usbkbd --- linux-2.6.28.orig/debian/d-i/modules/block-modules +++ linux-2.6.28/debian/d-i/modules/block-modules @@ -0,0 +1,30 @@ +aoe +aten +bpck +bpck6 ? +cciss +comm +cpqarray +DAC960 +dstr +epat +epia +fit2 +fit3 +friq +frpw +kbic +ktti +nbd +on20 +on26 +paride +pcd +pd +pf +pg +pt +sx8 +ub +umem +virtio_blk ? --- linux-2.6.28.orig/debian/d-i/modules/fs-core-modules +++ linux-2.6.28/debian/d-i/modules/fs-core-modules @@ -0,0 +1,3 @@ +jfs +reiserfs +xfs --- linux-2.6.28.orig/debian/d-i/modules/crypto-modules +++ linux-2.6.28/debian/d-i/modules/crypto-modules @@ -0,0 +1,8 @@ +aes_generic +blowfish +twofish +serpent +sha256_generic +cbc +ecb +crc32c --- linux-2.6.28.orig/debian/d-i/modules/mouse-modules +++ linux-2.6.28/debian/d-i/modules/mouse-modules @@ -0,0 +1,2 @@ +psmouse +usbmouse ? --- linux-2.6.28.orig/debian/d-i/modules/message-modules +++ linux-2.6.28/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-2.6.28.orig/debian/d-i/modules/plip-modules +++ linux-2.6.28/debian/d-i/modules/plip-modules @@ -0,0 +1 @@ +plip --- linux-2.6.28.orig/debian/d-i/modules/nfs-modules +++ linux-2.6.28/debian/d-i/modules/nfs-modules @@ -0,0 +1,4 @@ +nfs +nfs_acl +lockd +sunrpc --- linux-2.6.28.orig/debian/d-i/modules/nic-pcmcia-modules +++ linux-2.6.28/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-2.6.28.orig/debian/d-i/modules/parport-modules +++ linux-2.6.28/debian/d-i/modules/parport-modules @@ -0,0 +1,2 @@ +parport +parport_pc --- linux-2.6.28.orig/debian/d-i/modules/pata-modules +++ linux-2.6.28/debian/d-i/modules/pata-modules @@ -0,0 +1,2 @@ +pata_it8213 +pata_ninja32 --- linux-2.6.28.orig/debian/d-i/modules/md-modules +++ linux-2.6.28/debian/d-i/modules/md-modules @@ -0,0 +1,14 @@ +dm-crypt +dm-zero +faulty +linear +multipath +raid0 +raid1 +raid10 +raid456 + +# Extras +dm-raid4-5 ? +dm-loop +dm-bbr --- linux-2.6.28.orig/debian/d-i/modules/nic-shared-modules +++ linux-2.6.28/debian/d-i/modules/nic-shared-modules @@ -0,0 +1,21 @@ +# PHY +8390 +mii + +# CRC modules +crc-ccitt +crc-itu-t + +# mac80211 stuff +mac80211 +cfg80211 + +# rt2x00 lib (since rt2x00 is split across usb/pci/cb +rt2x00lib + +# Wireless 802.11 modules +ieee80211 +ieee80211_crypt +ieee80211_crypt_ccmp +ieee80211_crypt_tkip +ieee80211_crypt_wep --- linux-2.6.28.orig/debian/d-i/modules/irda-modules +++ linux-2.6.28/debian/d-i/modules/irda-modules @@ -0,0 +1,30 @@ +act200l-sir +actisys-sir +ali-ircc +donauboe ? +esi-sir +girbil-sir +ircomm +ircomm-tty +irda +irda-usb +irlan +irnet +irport ? +irtty-sir +kingsun-sir +ks959-sir +ksdazzle-sir +litelink-sir +ma600-sir +mcp2120-sir +mcs7780 +nsc-ircc +old_belkin-sir +sir-dev +smsc-ircc2 +stir4200 +tekram-sir +via-ircc +vlsi_ir +w83977af_ir --- linux-2.6.28.orig/debian/d-i/modules/sata-modules +++ linux-2.6.28/debian/d-i/modules/sata-modules @@ -0,0 +1,2 @@ + +sata_mv --- linux-2.6.28.orig/debian/d-i/modules/fs-secondary-modules +++ linux-2.6.28/debian/d-i/modules/fs-secondary-modules @@ -0,0 +1,4 @@ +fuse +ntfs ? +hfs ? +hfsplus ? --- linux-2.6.28.orig/debian/d-i/modules/fat-modules +++ linux-2.6.28/debian/d-i/modules/fat-modules @@ -0,0 +1,7 @@ +fat +vfat + +# Supporting modules ? +nls_cp437 ? +nls_iso8859-1 ? +nls_utf8 ? --- linux-2.6.28.orig/debian/d-i/modules/scsi-modules +++ linux-2.6.28/debian/d-i/modules/scsi-modules @@ -0,0 +1,113 @@ +# SCSI +raid_class ? +scsi_transport_spi ? +scsi_transport_fc ? +scsi_transport_iscsi ? +scsi_transport_sas ? +iscsi_tcp ? +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-2.6.28.orig/debian/d-i/modules/nic-modules +++ linux-2.6.28/debian/d-i/modules/nic-modules @@ -0,0 +1,150 @@ +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 ? +atl1 ? +atl1e ? +atl2 ? +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 ? +e1000e ? +e2100 ? +eepro ? +eepro100 ? +eexpress ? +epic100 ? +eql ? +es3210 ? +eth16i ? +ewrk3 ? +fealnx ? +forcedeth ? +igb ? +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 ? +virtio_net ? +wavelan ? +wd ? +winbond-840 ? +yellowfin ? +znet ? --- linux-2.6.28.orig/debian/d-i/modules-armel/fs-core-modules +++ linux-2.6.28/debian/d-i/modules-armel/fs-core-modules @@ -0,0 +1,5 @@ +# ext2 and ext3 are built-in. + +jfs +reiserfs +xfs --- linux-2.6.28.orig/debian/tests/check-aliases +++ linux-2.6.28/debian/tests/check-aliases @@ -0,0 +1,24 @@ +#!/usr/bin/perl -w + +my %map; + +print "Checking for dupe aliases in $ENV{'FLAVOUR'}...\n"; + +$aliases = + "$ENV{'INSTALL_DIR'}/lib/modules/$ENV{'VERSION'}-$ENV{'FLAVOUR'}/modules.alias"; + +open(ALIASES, "< $aliases") or die "Could not open $aliases"; + +while () { + chomp; + my ($junk, $alias, $module) = split; + + if (defined($map{$alias})) { + printf("%s %20s / %-20s : %s \n", ("$map{$alias}" eq "$module") + ? "INT" : " ", $map{$alias}, $module, $alias); + } else { + $map{$alias} = $module; + } +} + +exit(0); --- linux-2.6.28.orig/debian/tests/README +++ linux-2.6.28/debian/tests/README @@ -0,0 +1,21 @@ +Scripts placed in this directory get called one at a time by run-parts(8). +The scripts are expected to perform some sort of sanity checks on the +finished build. Scripts will be called once for each flavour. + +Some environment variables are exported to make life a little easier: + +DPKG_ARCH : The dpkg architecture (e.g. "amd64") +KERN_ARCH : The kernel architecture (e.g. "x86_64") +FLAVOUR : The specific flavour for this run (e.g. "generic") +VERSION : The full version of this build (e.g. 2.6.22-1) +REVISION : The exact revision of this build (e.g. 1.3) +PREV_REVISION : The revision prior to this one +ABI_NUM : The specific ABI number for this build (e.g. 2) +PREV_ABI_NUM : The previous ABI number. Can be the same as ABI_NUM. +BUILD_DIR : The directory where this build took place +INSTALL_DIR : The directory where the package is prepared +SOURCE_DIR : Where the main kernel source is + +Scripts are expected to have a zero exit status when no problems occur, +and non-zero when an error occurs that should stop the build. Scripts +should print whatever info they deem needed to deduce the problem. --- linux-2.6.28.orig/debian/rules.d/1-maintainer.mk +++ linux-2.6.28/debian/rules.d/1-maintainer.mk @@ -0,0 +1,105 @@ +# The following targets are for the maintainer only! do no run if you don't +# know what they do. + +.PHONY: printenv updateconfigs printchanges insertchanges startnewrelease diffupstream help + +help: + @echo "These are the targets in addition to the normal debian ones:" + @echo + @echo " printenv : Print some variables used in the build" + @echo + @echo " updateconfigs : Update debian/config/*" + @echo + @echo " editconfigs : Update debian/config/* interactively" + @echo + @echo " printchanges : Print the current changelog entries (from git)" + @echo + @echo " insertchanges : Insert current changelog entries (from git)" + @echo + @echo " startnewrelease : Start a new changelog set" + @echo + @echo " diffupstream : Diff stock kernel code against upstream (git)" + @echo + @echo " help : If you are kernel hacking, you need the professional" + @echo " version of this" + @echo + @echo "Environment variables:" + @echo + @echo " NOKERNLOG : Do not add upstream kernel commits to changelog" + @echo " CONCURRENCY_LEVEL=X" + @echo " : Use -jX for kernel compile" + @echo " PRINTSHAS : Include SHAs for commits in changelog" + +ARCH_CONFIGS=i386 amd64 armel + +updateconfigs: + dh_testdir + @for arch in $(ARCH_CONFIGS); do \ + $(SHELL) debian/scripts/misc/oldconfig $$arch; \ + done + rm -rf build + +editconfigs: + dh_testdir + @for arch in $(ARCH_CONFIGS); do \ + $(SHELL) debian/scripts/misc/doconfig $$arch; \ + done + rm -rf build + +printenv: + dh_testdir + @echo "release = $(release)" + @echo "revisions = $(revisions)" + @echo "revision = $(revision)" + @echo "uploadnum = $(uploadnum)" + @echo "prev_revisions = $(prev_revisions)" + @echo "prev_revision = $(prev_revision)" + @echo "abinum = $(abinum)" + @echo "gitver = $(gitver)" + @echo "flavours = $(flavours)" + @echo "skipabi = $(skipabi)" + @echo "skipmodule = $(skipmodule)" + @echo "skipdbg = $(skipdbg)" + @echo "ubuntu_log_opts = $(ubuntu_log_opts)" +ifneq ($(SUBLEVEL),) + @echo "SUBLEVEL = $(SUBLEVEL)" +endif + @echo "CONCURRENCY_LEVEL = $(CONCURRENCY_LEVEL)" + +printchanges: + @git log Ubuntu-$(release)-$(prev_revision)..HEAD | \ + perl -w -f debian/scripts/misc/git-ubuntu-log $(ubuntu_log_opts) + +insertchanges: + @perl -w -f debian/scripts/misc/insert-changes.pl + +diffupstream: + @git diff-tree -p refs/remotes/linux-2.6/master..HEAD $(shell ls | grep -vE '^(ubuntu|debian|\.git.*)') + +startnewrelease: + dh_testdir + @nextminor=$(shell expr `echo $(revision) | awk -F. '{print $$2}'` + 1); \ + now="$(shell date -R)"; \ + echo "Creating new changelog set for $(abi_release).$$nextminor..."; \ + echo -e "$(stub) ($(abi_release).$$nextminor) UNRELEASED; urgency=low\n" > debian/changelog.new; \ + echo " CHANGELOG: Do not edit directly. Autogenerated at release." >> \ + debian/changelog.new; \ + echo " CHANGELOG: Use the printchanges target to see the curent changes." \ + >> debian/changelog.new; \ + echo " CHANGELOG: Use the insertchanges target to create the final log." \ + >> debian/changelog.new; \ + echo -e "\n -- $$DEBFULLNAME <$$DEBEMAIL> $$now\n" >> \ + debian/changelog.new ; \ + cat debian/changelog >> debian/changelog.new; \ + mv debian/changelog.new debian/changelog +# +# If $(ppa_file) exists, then only the standard flavours are built for PPA, e.g., +# 386, 386-generic, and amd64-generic. +# +prepare-ppa: + @echo Execute debian/scripts/misc/prepare-ppa-source to prepare an upload + @echo for a PPA build. You must do this outside of debian/rules since it cannot + @echo nest. + +print-ppa-file-name: + @echo $(ppa_file) --- linux-2.6.28.orig/debian/rules.d/2-binary-arch.mk +++ linux-2.6.28/debian/rules.d/2-binary-arch.mk @@ -0,0 +1,277 @@ +# We don't want make removing intermediary stamps +.SECONDARY : + +# Prepare the out-of-tree build directory + +prepare-%: $(stampdir)/stamp-prepare-% + @# Empty for make to be happy +$(stampdir)/stamp-prepare-%: target_flavour = $* +$(stampdir)/stamp-prepare-%: $(confdir)/config $(confdir)/config.% + @echo "Preparing $*..." + install -d $(builddir)/build-$* + touch $(builddir)/build-$*/ubuntu-build + cat $^ | sed -e 's/.*CONFIG_VERSION_SIGNATURE.*/CONFIG_VERSION_SIGNATURE="Ubuntu $(release)-$(revision)-$*"/' > $(builddir)/build-$*/.config + find $(builddir)/build-$* -name "*.ko" | xargs rm -f + $(kmake) O=$(builddir)/build-$* silentoldconfig prepare scripts + touch $@ + + +# Do the actual build, including image and modules +build-%: $(stampdir)/stamp-build-% + @# Empty for make to be happy +$(stampdir)/stamp-build-%: target_flavour = $* +$(stampdir)/stamp-build-%: $(stampdir)/stamp-prepare-% + @echo "Building $*..." + $(kmake) O=$(builddir)/build-$* $(conc_level) $(build_image) + $(kmake) O=$(builddir)/build-$* $(conc_level) modules + @touch $@ + +# Install the finished build +install-%: pkgdir = $(CURDIR)/debian/linux-image-$(abi_release)-$* +install-%: dbgpkgdir = $(CURDIR)/debian/linux-image-debug-$(abi_release)-$* +install-%: basepkg = linux-headers-$(abi_release) +install-%: hdrdir = $(CURDIR)/debian/$(basepkg)-$*/usr/src/$(basepkg)-$* +install-%: target_flavour = $* +install-%: $(stampdir)/stamp-build-% checks-% + dh_testdir + dh_testroot + dh_clean -k -plinux-image-$(abi_release)-$* + dh_clean -k -plinux-headers-$(abi_release)-$* + dh_clean -k -plinux-image-debug-$(abi_release)-$* + + # The main image + install -m644 -D $(builddir)/build-$*/$(kernel_file) \ + $(pkgdir)/boot/$(install_file)-$(abi_release)-$* + + install -m644 $(builddir)/build-$*/.config \ + $(pkgdir)/boot/config-$(abi_release)-$* + install -m644 $(abidir)/$* \ + $(pkgdir)/boot/abi-$(abi_release)-$* + install -m644 $(builddir)/build-$*/System.map \ + $(pkgdir)/boot/System.map-$(abi_release)-$* +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux +endif + + $(kmake) O=$(builddir)/build-$* modules_install \ + INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$(pkgdir)/ \ + INSTALL_FW_PATH=$(pkgdir)/lib/firmware/$(abi_release)-$* + +ifeq ($(no_dumpfile),) + makedumpfile -g $(pkgdir)/boot/vmcoreinfo-$(abi_release)-$* \ + -x $(builddir)/build-$*/vmlinux +endif + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/build + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/source + + # Some initramfs-tools specific modules + install -d $(pkgdir)/lib/modules/$(abi_release)-$*/initrd + if [ -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko ]; then\ + ln -f $(pkgdir)/lib/modules/$(abi_release)-$*/kernel/drivers/video/vesafb.ko \ + $(pkgdir)/lib/modules/$(abi_release)-$*/initrd/; \ + fi + + # Now the image scripts + install -d $(pkgdir)/DEBIAN + for script in postinst postrm preinst prerm; do \ + sed -e 's/=V/$(abi_release)-$*/g' -e 's/=K/$(install_file)/g' \ + -e 's/=L/$(loader)/g' -e 's@=B@$(build_arch)@g' \ + debian/control-scripts/$$script > $(pkgdir)/DEBIAN/$$script; \ + chmod 755 $(pkgdir)/DEBIAN/$$script; \ + done + +ifneq ($(skipsub),true) + @set -e; for sub in $($(*)_sub); do \ + TO=$$sub FROM=$* ABI_RELEASE=$(abi_release) $(SHELL) \ + debian/scripts/sub-flavour; \ + /sbin/depmod -b debian/linux-image-$(abi_release)-$$sub \ + -ea -F debian/linux-image-$(abi_release)-$$sub/boot/System.map-$(abi_release)-$* \ + $(abi_release)-$*; \ + install -d debian/linux-image-$(abi_release)-$$sub/DEBIAN; \ + for script in postinst postrm preinst prerm; do \ + sed -e 's/=V/$(abi_release)-$*/g' \ + -e 's/=K/$(install_file)/g' \ + -e 's/=L/$(loader)/g' \ + -e 's@=B@$(build_arch)@g' \ + debian/control-scripts/$$script > \ + debian/linux-image-$(abi_release)-$$sub/DEBIAN/$$script;\ + chmod 755 debian/linux-image-$(abi_release)-$$sub/DEBIAN/$$script;\ + done; \ + done +endif + +ifneq ($(skipdbg),true) + # Debug image is simple + install -m644 -D $(builddir)/build-$*/vmlinux \ + $(dbgpkgdir)/usr/lib/debug/boot/vmlinux-$(abi_release)-$* + $(kmake) O=$(builddir)/build-$* modules_install \ + INSTALL_MOD_PATH=$(dbgpkgdir)/usr/lib/debug + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/build + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/source + rm -f $(dbgpkgdir)/usr/lib/debug/lib/modules/$(abi_release)-$*/modules.* + rm -fr $(dbgpkgdir)/usr/lib/debug/lib/firmware +endif + + # The flavour specific headers image + # TODO: Would be nice if we didn't have to dupe the original builddir + install -d -m755 $(hdrdir) + cat $(builddir)/build-$*/.config | \ + sed -e 's/.*CONFIG_DEBUG_INFO=.*/# CONFIG_DEBUG_INFO is not set/g' > \ + $(hdrdir)/.config + chmod 644 $(hdrdir)/.config + $(kmake) O=$(hdrdir) silentoldconfig prepare scripts + # We'll symlink this stuff + rm -f $(hdrdir)/Makefile + rm -rf $(hdrdir)/include2 + # Script to symlink everything up + $(SHELL) debian/scripts/link-headers "$(hdrdir)" "$(basepkg)" "$*" + # Setup the proper asm symlink + rm -f $(hdrdir)/include/asm + ln -s asm-$(asm_link) $(hdrdir)/include/asm + # The build symlink + install -d debian/$(basepkg)-$*/lib/modules/$(abi_release)-$* + ln -s /usr/src/$(basepkg)-$* \ + debian/$(basepkg)-$*/lib/modules/$(abi_release)-$*/build + # And finally the symvers + install -m644 $(builddir)/build-$*/Module.symvers \ + $(hdrdir)/Module.symvers + + # Now the header scripts + install -d $(CURDIR)/debian/$(basepkg)-$*/DEBIAN + for script in postinst; do \ + sed -e 's/=V/$(abi_release)-$*/g' -e 's/=K/$(install_file)/g' \ + debian/control-scripts/headers-$$script > \ + $(CURDIR)/debian/$(basepkg)-$*/DEBIAN/$$script; \ + chmod 755 $(CURDIR)/debian/$(basepkg)-$*/DEBIAN/$$script; \ + done + + # At the end of the package prep, call the tests + DPKG_ARCH="$(arch)" KERN_ARCH="$(build_arch)" FLAVOUR="$*" \ + VERSION="$(abi_release)" REVISION="$(revision)" \ + PREV_REVISION="$(prev_revision)" ABI_NUM="$(abinum)" \ + PREV_ABI_NUM="$(prev_abinum)" BUILD_DIR="$(builddir)/build-$*" \ + INSTALL_DIR="$(pkgdir)" SOURCE_DIR="$(CURDIR)" \ + run-parts -v debian/tests + + # + # Remove files which are generated at installation by postinst. + # + rm -f $(pkgdir)/lib/modules/$(abi_release)-$*/modules.* + +headers_tmp := $(CURDIR)/debian/tmp-headers +headers_dir := $(CURDIR)/debian/linux-libc-dev + +hmake := $(MAKE) -C $(CURDIR) O=$(headers_tmp) SUBLEVEL=$(SUBLEVEL) \ + EXTRAVERSION=-$(abinum) INSTALL_HDR_PATH=$(headers_tmp)/install \ + SHELL="$(SHELL)" ARCH=$(header_arch) + +install-arch-headers: + dh_testdir + dh_testroot + dh_clean -k -plinux-libc-dev + + rm -rf $(headers_tmp) + install -d $(headers_tmp) $(headers_dir)/usr/include/ + + $(hmake) $(defconfig) + mv $(headers_tmp)/.config $(headers_tmp)/.config.old + sed -e 's/^# \(CONFIG_MODVERSIONS\) is not set$$/\1=y/' \ + -e 's/.*CONFIG_LOCALVERSION_AUTO.*/# CONFIG_LOCALVERSION_AUTO is not set/' \ + $(headers_tmp)/.config.old > $(headers_tmp)/.config + $(hmake) silentoldconfig + $(hmake) headers_install + + ( cd $(headers_tmp)/install/include/ && \ + find . -name '.' -o -name '.*' -prune -o -print | \ + cpio -pvd --preserve-modification-time \ + $(headers_dir)/usr/include/ ) + + rm -rf $(headers_tmp) + +binary-arch-headers: install-arch-headers + dh_testdir + dh_testroot + + dh_installchangelogs -plinux-libc-dev + dh_installdocs -plinux-libc-dev + dh_compress -plinux-libc-dev + dh_fixperms -plinux-libc-dev + dh_installdeb -plinux-libc-dev + dh_gencontrol -plinux-libc-dev + dh_md5sums -plinux-libc-dev + dh_builddeb -plinux-libc-dev + +binary-%: pkgimg = linux-image-$(abi_release)-$* +binary-%: pkghdr = linux-headers-$(abi_release)-$* +binary-%: dbgpkg = linux-image-debug-$(abi_release)-$* +binary-%: install-% + dh_testdir + dh_testroot + + dh_installchangelogs -p$(pkgimg) + dh_installdocs -p$(pkgimg) + dh_compress -p$(pkgimg) + dh_fixperms -p$(pkgimg) + dh_installdeb -p$(pkgimg) + dh_gencontrol -p$(pkgimg) + dh_md5sums -p$(pkgimg) + dh_builddeb -p$(pkgimg) -- -Zbzip2 -z9 + + dh_installchangelogs -p$(pkghdr) + dh_installdocs -p$(pkghdr) + dh_compress -p$(pkghdr) + dh_fixperms -p$(pkghdr) + dh_shlibdeps -p$(pkghdr) + dh_installdeb -p$(pkghdr) + dh_gencontrol -p$(pkghdr) + dh_md5sums -p$(pkghdr) + dh_builddeb -p$(pkghdr) + +ifneq ($(skipsub),true) + @set -e; for sub in $($(*)_sub); do \ + pkg=linux-image-$(abi_release)-$$sub; \ + dh_installchangelogs -p$$pkg; \ + dh_installdocs -p$$pkg; \ + dh_compress -p$$pkg; \ + dh_fixperms -p$$pkg; \ + dh_shlibdeps -p$$pkg; \ + dh_installdeb -p$$pkg; \ + dh_gencontrol -p$$pkg; \ + dh_md5sums -p$$pkg; \ + dh_builddeb -p$$pkg; \ + done +endif + +ifneq ($(skipdbg),true) + dh_installchangelogs -p$(dbgpkg) + dh_installdocs -p$(dbgpkg) + dh_compress -p$(dbgpkg) + dh_fixperms -p$(dbgpkg) + dh_installdeb -p$(dbgpkg) + dh_gencontrol -p$(dbgpkg) + dh_md5sums -p$(dbgpkg) + dh_builddeb -p$(dbgpkg) + + # Hokay...here's where we do a little twiddling... + mv ../$(dbgpkg)_$(release)-$(revision)_$(arch).deb \ + ../$(dbgpkg)_$(release)-$(revision)_$(arch).ddeb + grep -v '^$(dbgpkg)_.*$$' debian/files > debian/files.new + mv debian/files.new debian/files + # Now, the package wont get into the archive, but it will get put + # into the debug system. +endif + +$(stampdir)/stamp-flavours: + @echo $(flavours) > $@ + +binary-debs: $(stampdir)/stamp-flavours $(addprefix binary-,$(flavours)) \ + binary-arch-headers + +build-arch: $(addprefix build-,$(flavours)) + +binary-arch-deps = binary-debs +ifeq ($(AUTOBUILD),) +binary-arch-deps += binary-udebs +endif +binary-arch: $(binary-arch-deps) --- linux-2.6.28.orig/debian/rules.d/i386.mk +++ linux-2.6.28/debian/rules.d/i386.mk @@ -0,0 +1,12 @@ +build_arch = i386 +header_arch = x86_64 +asm_link = x86 +defconfig = defconfig +flavours = generic server +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz + +server_sub = virtual + +loader = grub --- linux-2.6.28.orig/debian/rules.d/amd64.mk +++ linux-2.6.28/debian/rules.d/amd64.mk @@ -0,0 +1,12 @@ +build_arch = x86_64 +header_arch = $(build_arch) +asm_link = x86 +defconfig = defconfig +flavours = generic server +build_image = bzImage +kernel_file = arch/$(build_arch)/boot/bzImage +install_file = vmlinuz + +server_sub = virtual + +loader = grub --- linux-2.6.28.orig/debian/rules.d/armel.mk +++ linux-2.6.28/debian/rules.d/armel.mk @@ -0,0 +1,11 @@ +build_arch = arm +header_arch = arm +asm_link = arm +defconfig = defconfig +flavours = orion5x iop32x ixp4xx versatile +build_image = zImage +kernel_file = arch/$(build_arch)/boot/zImage +install_file = vmlinuz +no_dumpfile = true + +loader = grub --- linux-2.6.28.orig/debian/rules.d/5-udebs.mk +++ linux-2.6.28/debian/rules.d/5-udebs.mk @@ -0,0 +1,33 @@ +# Do udebs if not disabled in the arch-specific makefile +binary-udebs: binary-debs debian/control +ifeq ($(disable_d_i),) + debian/rules do-binary-udebs; +endif + +do-binary-udebs: + dh_testdir + dh_testroot + + # unpack the kernels into a temporary directory + mkdir -p debian/d-i-${arch} + + imagelist=$$(cat kernel-versions | grep ^${arch} | awk '{print $$4}') && \ + for i in $$imagelist; do \ + dpkg -x $$(ls ../linux-image-$$i\_$(release)-$(revision)_${arch}.deb) \ + debian/d-i-${arch}; \ + /sbin/depmod -b debian/d-i-${arch} $$i; \ + done + + touch ignore-dups + export SOURCEDIR=debian/d-i-${arch} && \ + kernel-wedge install-files && \ + kernel-wedge check + + # Build just the udebs + dilist=$$(dh_listpackages -s | grep "\-di$$") && \ + [ -z "$dilist" ] || \ + for i in $$dilist; do \ + dh_fixperms -p$$i; \ + dh_gencontrol -p$$i; \ + dh_builddeb -p$$i; \ + done --- linux-2.6.28.orig/debian/rules.d/0-common-vars.mk +++ linux-2.6.28/debian/rules.d/0-common-vars.mk @@ -0,0 +1,104 @@ +# Get some version info +stub=linux + +release := $(shell sed -n '1s/^.*(\(.*\)-.*).*$$/\1/p' debian/changelog) +revisions := $(shell sed -n 's/^$(stub)\ .*($(release)-\(.*\)).*$$/\1/p' debian/changelog | tac) +revision ?= $(word $(words $(revisions)),$(revisions)) +prev_revisions := $(filter-out $(revision),0.0 $(revisions)) +prev_revision := $(word $(words $(prev_revisions)),$(prev_revisions)) + +# This is an internally used mechanism for the daily kernel builds. It +# creates packages who's ABI is suffixed with a minimal representation of +# the current git HEAD sha. If .git/HEAD is not present, then it uses the +# uuidgen program, +# +# AUTOBUILD can also be used by anyone wanting to build a custom kernel +# image, or rebuild the entire set of Ubuntu packages using custom patches +# or configs. +AUTOBUILD= + +# +# This is a way to support some external variables. A good example is +# a local setup for ccache and distcc See LOCAL_ENV_CC and +# LOCAL_ENV_DISTCC_HOSTS in the definition of kmake. +# For example: +# LOCAL_ENV_CC="ccache distcc" +# LOCAL_ENV_DISTCC_HOSTS="localhost 10.0.2.5 10.0.2.221" +# +-include $(CURDIR)/../.jaunty-env + +ifneq ($(AUTOBUILD),) +skipabi = true +skipmodule = true +skipdbg = true +gitver=$(shell if test -f .git/HEAD; then cat .git/HEAD; else uuidgen; fi) +gitverpre=$(shell echo $(gitver) | cut -b -3) +gitverpost=$(shell echo $(gitver) | cut -b 38-40) +abi_suffix = -$(gitverpre)$(gitverpost) +endif + +ifneq ($(NOKERNLOG),) +ubuntu_log_opts += --no-kern-log +endif +ifneq ($(PRINTSHAS),) +ubuntu_log_opts += --print-shas +endif + +ifeq ($(wildcard /CurrentlyBuilding),) +skipdbg=true +endif + +abinum := $(shell echo $(revision) | sed -e 's/\..*//')$(abi_suffix) +prev_abinum := $(shell echo $(prev_revision) | sed -e 's/\..*//')$(abi_suffix) + +abi_release := $(release)-$(abinum) + +uploadnum := $(shell echo $(revision) | sed -e 's/.*\.//') +ifneq ($(wildcard /CurrentlyBuilding),) + uploadnum := $(uploadnum)-Ubuntu +endif + +# We force the sublevel to be exactly what we want. The actual source may +# be an in development git tree. We want to force it here instead of +# committing changes to the top level Makefile +SUBLEVEL := $(shell echo $(release) | awk -F. '{print $$3}') + +arch := $(shell dpkg-architecture -qDEB_HOST_ARCH) +abidir := $(CURDIR)/debian/abi/$(release)-$(revision)/$(arch) +prev_abidir := $(CURDIR)/debian/abi/$(release)-$(prev_revision)/$(arch) +confdir := $(CURDIR)/debian/config/$(arch) +builddir := $(CURDIR)/debian/build +stampdir := $(CURDIR)/debian/stamps + +# Support parallel= in DEB_BUILD_OPTIONS (see #209008) +COMMA=, +DEB_BUILD_OPTIONS_PARA = $(subst parallel=,,$(filter parallel=%,$(subst $(COMMA), ,$(DEB_BUILD_OPTIONS)))) +ifneq (,$(DEB_BUILD_OPTIONS_PARA)) + CONCURRENCY_LEVEL := $(DEB_BUILD_OPTIONS_PARA) +endif + +ifeq ($(CONCURRENCY_LEVEL),) + # Check the environment + CONCURRENCY_LEVEL := $(shell echo $$CONCURRENCY_LEVEL) + # No? Check if this is on a buildd + ifeq ($(CONCURRENCY_LEVEL),) + ifeq ($(wildcard /CurrentlyBuilding),) + CONCURRENCY_LEVEL := $(shell expr `getconf _NPROCESSORS_ONLN` \* 2) + endif + endif + # Oh hell, give 'em one + ifeq ($(CONCURRENCY_LEVEL),) + CONCURRENCY_LEVEL := 1 + endif +endif + +conc_level = -j$(CONCURRENCY_LEVEL) + +# target_flavour is filled in for each step +kmake = make ARCH=$(build_arch) \ + EXTRAVERSION=-$(abinum)-$(target_flavour) \ + CONFIG_DEBUG_SECTION_MISMATCH=y SUBLEVEL=$(SUBLEVEL) \ + KBUILD_BUILD_VERSION="$(uploadnum)" +ifneq ($(LOCAL_ENV_CC),) +kmake += CC=$(LOCAL_ENV_CC) DISTCC_HOSTS=$(LOCAL_ENV_DISTCC_HOSTS) +endif --- linux-2.6.28.orig/debian/rules.d/4-checks.mk +++ linux-2.6.28/debian/rules.d/4-checks.mk @@ -0,0 +1,26 @@ +# Check ABI for package against last release (if not same abinum) +abi-%: $(abidir)/% + @# Empty for make to be happy +$(abidir)/%: $(stampdir)/stamp-build-% + install -d $(abidir) + sed -e 's/^\(.\+\)[[:space:]]\+\(.\+\)[[:space:]]\(.\+\)$$/\3 \2 \1/' \ + $(builddir)/build-$*/Module.symvers | sort > $@ + +abi-check-%: $(abidir)/% + @perl -f debian/scripts/abi-check "$*" "$(prev_abinum)" "$(abinum)" \ + "$(prev_abidir)" "$(abidir)" "$(skipabi)" + +# Check the module list against the last release (always) +module-%: $(abidir)/%.modules + @# Empty for make to be happy +$(abidir)/%.modules: $(stampdir)/stamp-build-% + install -d $(abidir) + find $(builddir)/build-$*/ -name \*.ko | \ + sed -e 's/.*\/\([^\/]*\)\.ko/\1/' | sort > $@ + +module-check-%: $(abidir)/%.modules + @perl -f debian/scripts/module-check "$*" \ + "$(prev_abidir)" "$(abidir)" $(skipmodule) + +checks-%: abi-check-% module-check-% + @# Will be calling more stuff later --- linux-2.6.28.orig/debian/rules.d/3-binary-indep.mk +++ linux-2.6.28/debian/rules.d/3-binary-indep.mk @@ -0,0 +1,85 @@ +build-indep: + +docpkg = linux-doc-$(release) +docdir = $(CURDIR)/debian/$(docpkg)/usr/share/doc/$(docpkg) +install-doc: + dh_testdir + dh_testroot + dh_clean -k -p$(docpkg) + + install -d $(docdir) + + # First the html docs. We skip these for autobuilds + if [ -z "$(AUTOBUILD) nobuild" ]; then \ + install -d $(docdir)/linux-doc-tmp; \ + $(kmake) O=$(docdir)/linux-doc-tmp htmldocs; \ + mv $(docdir)/linux-doc-tmp/Documentation/DocBook \ + $(docdir)/html; \ + rm -rf $(docdir)/linux-doc-tmp; \ + fi + + # Copy the rest + cp -a Documentation/* $(docdir) + rm -rf $(docdir)/DocBook + +indep_hdrpkg = linux-headers-$(abi_release) +indep_hdrdir = $(CURDIR)/debian/$(indep_hdrpkg)/usr/src/$(indep_hdrpkg) +install-headers: + dh_testdir + dh_testroot + dh_clean -k -p$(indep_hdrpkg) + + install -d $(indep_hdrdir) + find . -path './debian/*' -prune -o -path './include/*' -prune \ + -o -path './scripts/*' -prune -o -type f \ + \( -name 'Makefile*' -o -name 'Kconfig*' -o -name 'Kbuild*' -o \ + -name '*.sh' -o -name '*.pl' -o -name '*.lds' \) \ + -print | cpio -pd --preserve-modification-time $(indep_hdrdir) + cp -a scripts include $(indep_hdrdir) + (find arch -name include -type d -print | \ + xargs -n1 -i: find : -type f) | \ + cpio -pd --preserve-modification-time $(indep_hdrdir) + +srcpkg = linux-source-$(release) +srcdir = $(CURDIR)/debian/$(srcpkg)/usr/src/$(srcpkg) +install-source: + dh_testdir + dh_testroot + dh_clean -k -p$(srcpkg) + + install -d $(srcdir) + find . -path './debian/*' -prune -o \ + -path './.*' -prune -o -print | \ + cpio -pd --preserve-modification-time $(srcdir) + (cd $(srcdir)/..; tar cf - $(srcpkg)) | bzip2 -9c > \ + $(srcdir).tar.bz2 + rm -rf $(srcdir) + +install-indep: install-headers install-doc install-source + +# This is just to make it easy to call manually. Normally done in +# binary-indep target during builds. +binary-headers: install-headers + dh_testdir + dh_testroot + dh_installchangelogs -p$(indep_hdrpkg) + dh_installdocs -p$(indep_hdrpkg) + dh_compress -p$(indep_hdrpkg) + dh_fixperms -p$(indep_hdrpkg) + dh_installdeb -p$(indep_hdrpkg) + dh_gencontrol -p$(indep_hdrpkg) + dh_md5sums -p$(indep_hdrpkg) + dh_builddeb -p$(indep_hdrpkg) + +binary-indep: install-indep + dh_testdir + dh_testroot + + dh_installchangelogs -i + dh_installdocs -i + dh_compress -i + dh_fixperms -i + dh_installdeb -i + dh_gencontrol -i + dh_md5sums -i + dh_builddeb -i --- linux-2.6.28.orig/security/capability.c +++ linux-2.6.28/security/capability.c @@ -155,52 +155,56 @@ } static int cap_inode_create(struct inode *inode, struct dentry *dentry, - int mask) + struct vfsmount *mnt, int mask) { return 0; } -static int cap_inode_link(struct dentry *old_dentry, struct inode *inode, - struct dentry *new_dentry) +static int cap_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *inode, + struct dentry *new_dentry, struct vfsmount *new_mnt) { return 0; } -static int cap_inode_unlink(struct inode *inode, struct dentry *dentry) +static int cap_inode_unlink(struct inode *inode, struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static int cap_inode_symlink(struct inode *inode, struct dentry *dentry, - const char *name) + struct vfsmount *mnt, const char *name) { return 0; } static int cap_inode_mkdir(struct inode *inode, struct dentry *dentry, - int mask) + struct vfsmount *mnt, int mask) { return 0; } -static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry) +static int cap_inode_rmdir(struct inode *inode, struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static int cap_inode_mknod(struct inode *inode, struct dentry *dentry, - int mode, dev_t dev) + struct vfsmount *mnt, int mode, dev_t dev) { return 0; } static int cap_inode_rename(struct inode *old_inode, struct dentry *old_dentry, - struct inode *new_inode, struct dentry *new_dentry) + struct vfsmount *old_mnt, struct inode *new_inode, + struct dentry *new_dentry, struct vfsmount *new_mnt) { return 0; } -static int cap_inode_readlink(struct dentry *dentry) +static int cap_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) { return 0; } @@ -216,7 +220,8 @@ return 0; } -static int cap_inode_setattr(struct dentry *dentry, struct iattr *iattr) +static int cap_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) { return 0; } @@ -230,17 +235,20 @@ { } -static void cap_inode_post_setxattr(struct dentry *dentry, const char *name, +static void cap_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, int flags) { } -static int cap_inode_getxattr(struct dentry *dentry, const char *name) +static int cap_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *f) { return 0; } -static int cap_inode_listxattr(struct dentry *dentry) +static int cap_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *f) { return 0; } @@ -335,6 +343,11 @@ return 0; } +static int cap_path_permission(struct path *path, int mask) +{ + return security_inode_permission(path->dentry->d_inode, mask); +} + static int cap_task_create(unsigned long clone_flags) { return 0; @@ -889,6 +902,7 @@ set_to_cap_if_null(ops, file_send_sigiotask); set_to_cap_if_null(ops, file_receive); set_to_cap_if_null(ops, dentry_open); + set_to_cap_if_null(ops, path_permission); set_to_cap_if_null(ops, task_create); set_to_cap_if_null(ops, task_alloc_security); set_to_cap_if_null(ops, task_free_security); --- linux-2.6.28.orig/security/commoncap.c +++ linux-2.6.28/security/commoncap.c @@ -411,8 +411,9 @@ current->egid != current->gid); } -int cap_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file) { if (!strcmp(name, XATTR_NAME_CAPS)) { if (!capable(CAP_SETFCAP)) @@ -425,7 +426,8 @@ return 0; } -int cap_inode_removexattr(struct dentry *dentry, const char *name) +int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { if (!strcmp(name, XATTR_NAME_CAPS)) { if (!capable(CAP_SETFCAP)) --- linux-2.6.28.orig/security/Kconfig +++ linux-2.6.28/security/Kconfig @@ -125,6 +125,7 @@ source security/selinux/Kconfig source security/smack/Kconfig +source security/apparmor/Kconfig endmenu --- linux-2.6.28.orig/security/Makefile +++ linux-2.6.28/security/Makefile @@ -15,5 +15,6 @@ # Must precede capability.o in order to stack properly. obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o -obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o +obj-$(CONFIG_SECURITY_APPARMOR) += commoncap.o apparmor/ + obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o --- linux-2.6.28.orig/security/security.c +++ linux-2.6.28/security/security.c @@ -367,72 +367,81 @@ } EXPORT_SYMBOL(security_inode_init_security); -int security_inode_create(struct inode *dir, struct dentry *dentry, int mode) +int security_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_create(dir, dentry, mode); + return security_ops->inode_create(dir, dentry, mnt, mode); } -int security_inode_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry) +int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, struct dentry *new_dentry, + struct vfsmount *new_mnt) { if (unlikely(IS_PRIVATE(old_dentry->d_inode))) return 0; - return security_ops->inode_link(old_dentry, dir, new_dentry); + return security_ops->inode_link(old_dentry, old_mnt, dir, + new_dentry, new_mnt); } -int security_inode_unlink(struct inode *dir, struct dentry *dentry) +int security_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_unlink(dir, dentry); + return security_ops->inode_unlink(dir, dentry, mnt); } int security_inode_symlink(struct inode *dir, struct dentry *dentry, - const char *old_name) + struct vfsmount *mnt, const char *old_name) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_symlink(dir, dentry, old_name); + return security_ops->inode_symlink(dir, dentry, mnt, old_name); } -int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode) +int security_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_mkdir(dir, dentry, mode); + return security_ops->inode_mkdir(dir, dentry, mnt, mode); } -int security_inode_rmdir(struct inode *dir, struct dentry *dentry) +int security_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_rmdir(dir, dentry); + return security_ops->inode_rmdir(dir, dentry, mnt); } -int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +int security_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) { if (unlikely(IS_PRIVATE(dir))) return 0; - return security_ops->inode_mknod(dir, dentry, mode, dev); + return security_ops->inode_mknod(dir, dentry, mnt, mode, dev); } +EXPORT_SYMBOL_GPL(security_inode_permission); int security_inode_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) { if (unlikely(IS_PRIVATE(old_dentry->d_inode) || (new_dentry->d_inode && IS_PRIVATE(new_dentry->d_inode)))) return 0; - return security_ops->inode_rename(old_dir, old_dentry, - new_dir, new_dentry); + return security_ops->inode_rename(old_dir, old_dentry, old_mnt, + new_dir, new_dentry, new_mnt); } -int security_inode_readlink(struct dentry *dentry) +int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_readlink(dentry); + return security_ops->inode_readlink(dentry, mnt); } int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) @@ -449,11 +458,12 @@ return security_ops->inode_permission(inode, mask); } -int security_inode_setattr(struct dentry *dentry, struct iattr *attr) +int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_setattr(dentry, attr); + return security_ops->inode_setattr(dentry, mnt, attr); } EXPORT_SYMBOL_GPL(security_inode_setattr); @@ -471,41 +481,48 @@ security_ops->inode_delete(inode); } -int security_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_setxattr(dentry, name, value, size, flags); + return security_ops->inode_setxattr(dentry, mnt, name, value, size, + flags, file); } -void security_inode_post_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return; - security_ops->inode_post_setxattr(dentry, name, value, size, flags); + security_ops->inode_post_setxattr(dentry, mnt, name, value, size, + flags); } -int security_inode_getxattr(struct dentry *dentry, const char *name) +int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_getxattr(dentry, name); + return security_ops->inode_getxattr(dentry, mnt, name, file); } -int security_inode_listxattr(struct dentry *dentry) +int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_listxattr(dentry); + return security_ops->inode_listxattr(dentry, mnt, file); } -int security_inode_removexattr(struct dentry *dentry, const char *name) +int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { if (unlikely(IS_PRIVATE(dentry->d_inode))) return 0; - return security_ops->inode_removexattr(dentry, name); + return security_ops->inode_removexattr(dentry, mnt, name, file); } int security_inode_need_killpriv(struct dentry *dentry) @@ -608,6 +625,15 @@ return security_ops->dentry_open(file); } +int security_path_permission(struct path *path, int mask) +{ + struct inode *inode = path->dentry->d_inode; + if (unlikely(IS_PRIVATE(inode))) + return 0; + + return security_ops->path_permission(path, mask); +} + int security_task_create(unsigned long clone_flags) { return security_ops->task_create(clone_flags); --- linux-2.6.28.orig/security/selinux/hooks.c +++ linux-2.6.28/security/selinux/hooks.c @@ -1814,40 +1814,16 @@ static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid) { - int buflen, rc; - char *buffer, *path, *end; + char *buffer, *path; + int rc = -ENOMEM; - rc = -ENOMEM; buffer = (char *)__get_free_page(GFP_KERNEL); if (!buffer) goto out; - buflen = PAGE_SIZE; - end = buffer+buflen; - *--end = '\0'; - buflen--; - path = end-1; - *path = '/'; - while (table) { - const char *name = table->procname; - size_t namelen = strlen(name); - buflen -= namelen + 1; - if (buflen < 0) - goto out_free; - end -= namelen; - memcpy(end, name, namelen); - *--end = '/'; - path = end; - table = table->parent; - } - buflen -= 4; - if (buflen < 0) - goto out_free; - end -= 4; - memcpy(end, "/sys", 4); - path = end; - rc = security_genfs_sid("proc", path, tclass, sid); -out_free: + path = sysctl_pathname(table, buffer, PAGE_SIZE); + if (path) + rc = security_genfs_sid("proc", path, tclass, sid); free_page((unsigned long)buffer); out: return rc; @@ -2564,64 +2540,79 @@ return 0; } -static int selinux_inode_create(struct inode *dir, struct dentry *dentry, int mask) +static int selinux_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) { return may_create(dir, dentry, SECCLASS_FILE); } -static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) +static int selinux_inode_link(struct dentry *old_dentry, + struct vfsmount *old_mnt, + struct inode *dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) { int rc; - rc = secondary_ops->inode_link(old_dentry, dir, new_dentry); + rc = secondary_ops->inode_link(old_dentry, old_mnt, dir, new_dentry, + new_mnt); if (rc) return rc; return may_link(dir, old_dentry, MAY_LINK); } -static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry) +static int selinux_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { int rc; - rc = secondary_ops->inode_unlink(dir, dentry); + rc = secondary_ops->inode_unlink(dir, dentry, mnt); if (rc) return rc; return may_link(dir, dentry, MAY_UNLINK); } -static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, const char *name) +static int selinux_inode_symlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *name) { return may_create(dir, dentry, SECCLASS_LNK_FILE); } -static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, int mask) +static int selinux_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) { return may_create(dir, dentry, SECCLASS_DIR); } -static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry) +static int selinux_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { return may_link(dir, dentry, MAY_RMDIR); } -static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) { int rc; - rc = secondary_ops->inode_mknod(dir, dentry, mode, dev); + rc = secondary_ops->inode_mknod(dir, dentry, mnt, mode, dev); if (rc) return rc; return may_create(dir, dentry, inode_mode_to_security_class(mode)); } -static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry, - struct inode *new_inode, struct dentry *new_dentry) +static int selinux_inode_rename(struct inode *old_inode, + struct dentry *old_dentry, + struct vfsmount *old_mnt, + struct inode *new_inode, + struct dentry *new_dentry, + struct vfsmount *new_mnt) { return may_rename(old_inode, old_dentry, new_inode, new_dentry); } -static int selinux_inode_readlink(struct dentry *dentry) +static int selinux_inode_readlink(struct dentry *dentry, struct vfsmount *mnt) { return dentry_has_perm(current, NULL, dentry, FILE__READ); } @@ -2653,11 +2644,12 @@ open_file_mask_to_av(inode->i_mode, mask), NULL); } -static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) +static int selinux_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) { int rc; - rc = secondary_ops->inode_setattr(dentry, iattr); + rc = secondary_ops->inode_setattr(dentry, mnt, iattr); if (rc) return rc; @@ -2695,8 +2687,9 @@ return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); } -static int selinux_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +static int selinux_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file) { struct task_security_struct *tsec = current->security; struct inode *inode = dentry->d_inode; @@ -2750,7 +2743,8 @@ &ad); } -static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, +static void selinux_inode_post_setxattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, const void *value, size_t size, int flags) { @@ -2776,17 +2770,21 @@ return; } -static int selinux_inode_getxattr(struct dentry *dentry, const char *name) +static int selinux_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); } -static int selinux_inode_listxattr(struct dentry *dentry) +static int selinux_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file) { return dentry_has_perm(current, NULL, dentry, FILE__GETATTR); } -static int selinux_inode_removexattr(struct dentry *dentry, const char *name) +static int selinux_inode_removexattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, + struct file *file) { if (strcmp(name, XATTR_NAME_SELINUX)) return selinux_inode_setotherxattr(dentry, name); --- linux-2.6.28.orig/security/apparmor/inline.h +++ linux-2.6.28/security/apparmor/inline.h @@ -0,0 +1,250 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * 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. + */ + +#ifndef __INLINE_H +#define __INLINE_H + +#include + +#include "match.h" + +static inline int mediated_filesystem(struct inode *inode) +{ + return !(inode->i_sb->s_flags & MS_NOUSER); +} + +static inline struct aa_task_context *aa_task_context(struct task_struct *task) +{ + return (struct aa_task_context *) rcu_dereference(task->security); +} + +static inline struct aa_namespace *aa_get_namespace(struct aa_namespace *ns) +{ + if (ns) + kref_get(&(ns->count)); + + return ns; +} + +static inline void aa_put_namespace(struct aa_namespace *ns) +{ + if (ns) + kref_put(&ns->count, free_aa_namespace_kref); +} + + +static inline struct aa_namespace *aa_find_namespace(const char *name) +{ + struct aa_namespace *ns = NULL; + + read_lock(&profile_ns_list_lock); + ns = aa_get_namespace(__aa_find_namespace(name, &profile_ns_list)); + read_unlock(&profile_ns_list_lock); + + return ns; +} + +/** + * aa_dup_profile - increment refcount on profile @p + * @p: profile + */ +static inline struct aa_profile *aa_dup_profile(struct aa_profile *p) +{ + if (p) + kref_get(&(p->count)); + + return p; +} + +/** + * aa_put_profile - decrement refcount on profile @p + * @p: profile + */ +static inline void aa_put_profile(struct aa_profile *p) +{ + if (p) + kref_put(&p->count, free_aa_profile_kref); +} + +static inline struct aa_profile *aa_get_profile(struct task_struct *task) +{ + struct aa_task_context *cxt; + struct aa_profile *profile = NULL; + + rcu_read_lock(); + cxt = aa_task_context(task); + if (cxt) { + profile = cxt->profile; + aa_dup_profile(profile); + } + rcu_read_unlock(); + + return profile; +} + +static inline struct aa_profile *aa_find_profile(struct aa_namespace *ns, + const char *name) +{ + struct aa_profile *profile = NULL; + + read_lock(&ns->lock); + profile = aa_dup_profile(__aa_find_profile(name, &ns->profiles)); + read_unlock(&ns->lock); + + return profile; +} + +static inline struct aa_task_context *aa_alloc_task_context(gfp_t flags) +{ + struct aa_task_context *cxt; + + cxt = kzalloc(sizeof(*cxt), flags); + if (cxt) { + INIT_LIST_HEAD(&cxt->list); + INIT_RCU_HEAD(&cxt->rcu); + } + + return cxt; +} + +static inline void aa_free_task_context(struct aa_task_context *cxt) +{ + if (cxt) { + aa_put_profile(cxt->profile); + aa_put_profile(cxt->previous_profile); + kfree(cxt); + } +} + +/** + * lock_profile - lock a profile + * @profile: the profile to lock + * + * While the profile is locked, local interrupts are disabled. This also + * gives us RCU reader safety. + */ +static inline void lock_profile_nested(struct aa_profile *profile, + enum aa_lock_class lock_class) +{ + /* + * Lock the profile. + * + * Need to disable interrupts here because this lock is used in + * the task_free_security hook, which may run in RCU context. + */ + if (profile) + spin_lock_irqsave_nested(&profile->lock, profile->int_flags, + lock_class); +} + +static inline void lock_profile(struct aa_profile *profile) +{ + lock_profile_nested(profile, aa_lock_normal); +} + +/** + * unlock_profile - unlock a profile + * @profile: the profile to unlock + */ +static inline void unlock_profile(struct aa_profile *profile) +{ + /* Unlock the profile. */ + if (profile) + spin_unlock_irqrestore(&profile->lock, profile->int_flags); +} + +/** + * lock_both_profiles - lock two profiles in a deadlock-free way + * @profile1: profile to lock (may be NULL) + * @profile2: profile to lock (may be NULL) + * + * The order in which profiles are passed into lock_both_profiles() / + * unlock_both_profiles() does not matter. + * While the profile is locked, local interrupts are disabled. This also + * gives us RCU reader safety. + */ +static inline void lock_both_profiles(struct aa_profile *profile1, + struct aa_profile *profile2) +{ + /* + * Lock the two profiles. + * + * We need to disable interrupts because the profile locks are + * used in the task_free_security hook, which may run in RCU + * context. + * + * Do not nest spin_lock_irqsave()/spin_unlock_irqresore(): + * interrupts only need to be turned off once. + */ + if (!profile1 || profile1 == profile2) { + if (profile2) + spin_lock_irqsave_nested(&profile2->lock, + profile2->int_flags, + aa_lock_normal); + } else if (profile1 > profile2) { + /* profile1 cannot be NULL here. */ + spin_lock_irqsave_nested(&profile1->lock, profile1->int_flags, + aa_lock_normal); + if (profile2) + spin_lock_nested(&profile2->lock, aa_lock_nested); + + } else { + /* profile2 cannot be NULL here. */ + spin_lock_irqsave_nested(&profile2->lock, profile2->int_flags, + aa_lock_normal); + spin_lock_nested(&profile1->lock, aa_lock_nested); + } +} + +/** + * unlock_both_profiles - unlock two profiles in a deadlock-free way + * @profile1: profile to unlock (may be NULL) + * @profile2: profile to unlock (may be NULL) + * + * The order in which profiles are passed into lock_both_profiles() / + * unlock_both_profiles() does not matter. + * While the profile is locked, local interrupts are disabled. This also + * gives us RCU reader safety. + */ +static inline void unlock_both_profiles(struct aa_profile *profile1, + struct aa_profile *profile2) +{ + /* Unlock the two profiles. */ + if (!profile1 || profile1 == profile2) { + if (profile2) + spin_unlock_irqrestore(&profile2->lock, + profile2->int_flags); + } else if (profile1 > profile2) { + /* profile1 cannot be NULL here. */ + if (profile2) + spin_unlock(&profile2->lock); + spin_unlock_irqrestore(&profile1->lock, profile1->int_flags); + } else { + /* profile2 cannot be NULL here. */ + spin_unlock(&profile1->lock); + spin_unlock_irqrestore(&profile2->lock, profile2->int_flags); + } +} + +static inline unsigned int aa_match(struct aa_dfa *dfa, const char *pathname, + int *audit_mask) +{ + if (dfa) + return aa_dfa_match(dfa, pathname, audit_mask); + if (audit_mask) + *audit_mask = 0; + return 0; +} + +static inline int dfa_audit_mask(struct aa_dfa *dfa, unsigned int state) +{ + return ACCEPT_TABLE2(dfa)[state]; +} + +#endif /* __INLINE_H__ */ --- linux-2.6.28.orig/security/apparmor/apparmorfs.c +++ linux-2.6.28/security/apparmor/apparmorfs.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * 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. + * + * AppArmor filesystem (part of securityfs) + */ + +#include +#include +#include +#include +#include +#include + +#include "apparmor.h" +#include "inline.h" + +static char *aa_simple_write_to_buffer(const char __user *userbuf, + size_t alloc_size, size_t copy_size, + loff_t *pos, const char *operation) +{ + struct aa_profile *profile; + char *data; + + if (*pos != 0) { + /* only writes from pos 0, that is complete writes */ + data = ERR_PTR(-ESPIPE); + goto out; + } + + /* + * Don't allow confined processes to load/replace/remove profiles. + * No sane person would add rules allowing this to a profile + * but we enforce the restriction anyways. + */ + profile = aa_get_profile(current); + if (profile) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.error_code = -EACCES; + data = ERR_PTR(aa_audit_reject(profile, &sa)); + aa_put_profile(profile); + goto out; + } + + data = vmalloc(alloc_size); + if (data == NULL) { + data = ERR_PTR(-ENOMEM); + goto out; + } + + if (copy_from_user(data, userbuf, copy_size)) { + vfree(data); + data = ERR_PTR(-EFAULT); + goto out; + } + +out: + return data; +} + +/* apparmor/profiles */ +extern struct seq_operations apparmorfs_profiles_op; + +static int aa_profiles_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &apparmorfs_profiles_op); +} + + +static int aa_profiles_release(struct inode *inode, struct file *file) +{ + return seq_release(inode, file); +} + +static struct file_operations apparmorfs_profiles_fops = { + .open = aa_profiles_open, + .read = seq_read, + .llseek = seq_lseek, + .release = aa_profiles_release, +}; + +/* apparmor/matching */ +static ssize_t aa_matching_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + const char *matching = "pattern=aadfa audit perms=rwxamlk/ user::other"; + + return simple_read_from_buffer(buf, size, ppos, matching, + strlen(matching)); +} + +static struct file_operations apparmorfs_matching_fops = { + .read = aa_matching_read, +}; + +/* apparmor/features */ +static ssize_t aa_features_read(struct file *file, char __user *buf, + size_t size, loff_t *ppos) +{ + const char *features = "file=3.0 capability=2.0 network=1.0 " + "change_hat=1.5 change_profile=1.0 " + "aanamespaces=1.0 rlimit=1.0"; + + return simple_read_from_buffer(buf, size, ppos, features, + strlen(features)); +} + +static struct file_operations apparmorfs_features_fops = { + .read = aa_features_read, +}; + +/* apparmor/.load */ +static ssize_t aa_profile_load(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + char *data; + ssize_t error; + + data = aa_simple_write_to_buffer(buf, size, size, pos, "profile_load"); + + error = PTR_ERR(data); + if (!IS_ERR(data)) { + error = aa_add_profile(data, size); + vfree(data); + } + + return error; +} + + +static struct file_operations apparmorfs_profile_load = { + .write = aa_profile_load +}; + +/* apparmor/.replace */ +static ssize_t aa_profile_replace(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + char *data; + ssize_t error; + + data = aa_simple_write_to_buffer(buf, size, size, pos, + "profile_replace"); + + error = PTR_ERR(data); + if (!IS_ERR(data)) { + error = aa_replace_profile(data, size); + vfree(data); + } + + return error; +} + + +static struct file_operations apparmorfs_profile_replace = { + .write = aa_profile_replace +}; + +/* apparmor/.remove */ +static ssize_t aa_profile_remove(struct file *f, const char __user *buf, + size_t size, loff_t *pos) +{ + char *data; + ssize_t error; + + /* + * aa_remove_profile needs a null terminated string so 1 extra + * byte is allocated and the copied data is null terminated. + */ + data = aa_simple_write_to_buffer(buf, size + 1, size, pos, + "profile_remove"); + + error = PTR_ERR(data); + if (!IS_ERR(data)) { + data[size] = 0; + error = aa_remove_profile(data, size); + vfree(data); + } + + return error; +} + +static struct file_operations apparmorfs_profile_remove = { + .write = aa_profile_remove +}; + +static struct dentry *apparmor_dentry; + +static void aafs_remove(const char *name) +{ + struct dentry *dentry; + + dentry = lookup_one_len(name, apparmor_dentry, strlen(name)); + if (!IS_ERR(dentry)) { + securityfs_remove(dentry); + dput(dentry); + } +} + +static int aafs_create(const char *name, int mask, struct file_operations *fops) +{ + struct dentry *dentry; + + dentry = securityfs_create_file(name, S_IFREG | mask, apparmor_dentry, + NULL, fops); + + return IS_ERR(dentry) ? PTR_ERR(dentry) : 0; +} + +void destroy_apparmorfs(void) +{ + if (apparmor_dentry) { + aafs_remove(".remove"); + aafs_remove(".replace"); + aafs_remove(".load"); + aafs_remove("matching"); + aafs_remove("features"); + aafs_remove("profiles"); + securityfs_remove(apparmor_dentry); + apparmor_dentry = NULL; + } +} + +int create_apparmorfs(void) +{ + int error; + + if (!apparmor_initialized) + return 0; + + if (apparmor_dentry) { + AA_ERROR("%s: AppArmor securityfs already exists\n", + __FUNCTION__); + return -EEXIST; + } + + apparmor_dentry = securityfs_create_dir("apparmor", NULL); + if (IS_ERR(apparmor_dentry)) { + error = PTR_ERR(apparmor_dentry); + apparmor_dentry = NULL; + goto error; + } + error = aafs_create("profiles", 0440, &apparmorfs_profiles_fops); + if (error) + goto error; + error = aafs_create("matching", 0444, &apparmorfs_matching_fops); + if (error) + goto error; + error = aafs_create("features", 0444, &apparmorfs_features_fops); + if (error) + goto error; + error = aafs_create(".load", 0640, &apparmorfs_profile_load); + if (error) + goto error; + error = aafs_create(".replace", 0640, &apparmorfs_profile_replace); + if (error) + goto error; + error = aafs_create(".remove", 0640, &apparmorfs_profile_remove); + if (error) + goto error; + + /* Report that AppArmor fs is enabled */ + info_message("AppArmor Filesystem Enabled"); + return 0; + +error: + destroy_apparmorfs(); + AA_ERROR("Error creating AppArmor securityfs\n"); + apparmor_disable(); + return error; +} + +fs_initcall(create_apparmorfs); + --- linux-2.6.28.orig/security/apparmor/procattr.c +++ linux-2.6.28/security/apparmor/procattr.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * 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. + * + * AppArmor /proc/pid/attr handling + */ + +#include "apparmor.h" +#include "inline.h" + +int aa_getprocattr(struct aa_profile *profile, char **string, unsigned *len) +{ + char *str; + + if (profile) { + const char *mode_str = PROFILE_COMPLAIN(profile) ? + " (complain)" : " (enforce)"; + int mode_len, name_len, ns_len = 0; + + mode_len = strlen(mode_str); + name_len = strlen(profile->name); + if (profile->ns != default_namespace) + ns_len = strlen(profile->ns->name) + 2; + *len = mode_len + ns_len + name_len + 1; + str = kmalloc(*len, GFP_ATOMIC); + if (!str) + return -ENOMEM; + + if (ns_len) { + *str++ = ':'; + memcpy(str, profile->ns->name, ns_len - 2); + str += ns_len - 2; + *str++ = ':'; + } + memcpy(str, profile->name, name_len); + str += name_len; + memcpy(str, mode_str, mode_len); + str += mode_len; + *str++ = '\n'; + str -= *len; + } else { + const char *unconfined_str = "unconfined\n"; + + *len = strlen(unconfined_str); + str = kmalloc(*len, GFP_ATOMIC); + if (!str) + return -ENOMEM; + + memcpy(str, unconfined_str, *len); + } + *string = str; + + return 0; +} + +static char *split_token_from_name(const char *op, char *args, u64 *cookie) +{ + char *name; + + *cookie = simple_strtoull(args, &name, 16); + if ((name == args) || *name != '^') { + AA_ERROR("%s: Invalid input '%s'", op, args); + return ERR_PTR(-EINVAL); + } + + name++; /* skip ^ */ + if (!*name) + name = NULL; + return name; +} + +int aa_setprocattr_changehat(char *args) +{ + char *hat; + u64 cookie; + + hat = split_token_from_name("change_hat", args, &cookie); + if (IS_ERR(hat)) + return PTR_ERR(hat); + + if (!hat && !cookie) { + AA_ERROR("change_hat: Invalid input, NULL hat and NULL magic"); + return -EINVAL; + } + + AA_DEBUG("%s: Magic 0x%llx Hat '%s'\n", + __FUNCTION__, cookie, hat ? hat : NULL); + + return aa_change_hat(hat, cookie); +} + +int aa_setprocattr_changeprofile(char *args) +{ + char *name = args, *ns_name = NULL; + + if (name[0] == ':') { + char *split = strchr(&name[1], ':'); + if (split) { + *split = 0; + ns_name = &name[1]; + name = split + 1; + } + } + + return aa_change_profile(ns_name, name); +} + +int aa_setprocattr_setprofile(struct task_struct *task, char *args) +{ + struct aa_profile *old_profile, *new_profile; + struct aa_namespace *ns; + struct aa_audit sa; + char *name, *ns_name = NULL; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_set"; + sa.gfp_mask = GFP_KERNEL; + sa.task = task->pid; + + AA_DEBUG("%s: current %d\n", + __FUNCTION__, current->pid); + + name = args; + if (args[0] != '/') { + char *split = strchr(args, ':'); + if (split) { + *split = 0; + ns_name = args; + name = split + 1; + } + } + if (ns_name) + ns = aa_find_namespace(ns_name); + else + ns = aa_get_namespace(default_namespace); + if (!ns) { + sa.name = ns_name; + sa.info = "unknown namespace"; + aa_audit_reject(NULL, &sa); + aa_put_namespace(ns); + return -EINVAL; + } + +repeat: + if (strcmp(name, "unconfined") == 0) + new_profile = NULL; + else { + new_profile = aa_find_profile(ns, name); + if (!new_profile) { + sa.name = ns_name; + sa.name2 = name; + sa.info = "unknown profile"; + aa_audit_reject(NULL, &sa); + aa_put_namespace(ns); + return -EINVAL; + } + } + + old_profile = __aa_replace_profile(task, new_profile); + if (IS_ERR(old_profile)) { + int error; + + aa_put_profile(new_profile); + error = PTR_ERR(old_profile); + if (error == -ESTALE) + goto repeat; + aa_put_namespace(ns); + return error; + } + + if (new_profile) { + sa.name = ns_name; + sa.name2 = name; + sa.name3 = old_profile ? old_profile->name : + "unconfined"; + aa_audit_status(NULL, &sa); + } else { + if (old_profile) { + sa.name = "unconfined"; + sa.name2 = old_profile->name; + aa_audit_status(NULL, &sa); + } else { + sa.info = "task is unconfined"; + aa_audit_status(NULL, &sa); + } + } + aa_put_namespace(ns); + aa_put_profile(old_profile); + aa_put_profile(new_profile); + return 0; +} --- linux-2.6.28.orig/security/apparmor/main.c +++ linux-2.6.28/security/apparmor/main.c @@ -0,0 +1,1690 @@ +/* + * Copyright (C) 2002-2007 Novell/SUSE + * + * 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. + * + * AppArmor Core + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apparmor.h" + +#include "inline.h" + +/* + * Table of capability names: we generate it from capabilities.h. + */ +static const char *capability_names[] = { +#include "capability_names.h" +}; + +struct aa_namespace *default_namespace; + +static int aa_inode_mode(struct inode *inode) +{ + /* if the inode doesn't exist the user is creating it */ + if (!inode || current->fsuid == inode->i_uid) + return AA_USER_SHIFT; + return AA_OTHER_SHIFT; +} + +int alloc_default_namespace(void) +{ + struct aa_namespace *ns; + char *name = kstrdup("default", GFP_KERNEL); + if (!name) + return -ENOMEM; + ns = alloc_aa_namespace(name); + if (!ns) { + kfree(name); + return -ENOMEM; + } + + write_lock(&profile_ns_list_lock); + default_namespace = ns; + aa_get_namespace(ns); + list_add(&ns->list, &profile_ns_list); + write_unlock(&profile_ns_list_lock); + + return 0; +} + +void free_default_namespace(void) +{ + write_lock(&profile_ns_list_lock); + list_del_init(&default_namespace->list); + write_unlock(&profile_ns_list_lock); + aa_put_namespace(default_namespace); + default_namespace = NULL; +} + +static void aa_audit_file_sub_mask(struct audit_buffer *ab, char *buffer, + int mask) +{ + const char unsafex[] = "upcn"; + const char safex[] = "UPCN"; + char *m = buffer; + + if (mask & AA_EXEC_MMAP) + *m++ = 'm'; + if (mask & MAY_READ) + *m++ = 'r'; + if (mask & MAY_WRITE) + *m++ = 'w'; + else if (mask & MAY_APPEND) + *m++ = 'a'; + if (mask & MAY_EXEC) { + int index = AA_EXEC_INDEX(mask); + /* all indexes > 4 are also named transitions */ + if (index > 4) + index = 4; + if (index > 0) { + if (mask & AA_EXEC_UNSAFE) + *m++ = unsafex[index - 1]; + else + *m++ = safex[index - 1]; + } + if (mask & AA_EXEC_INHERIT) + *m++ = 'i'; + *m++ = 'x'; + } + if (mask & AA_MAY_LINK) + *m++ = 'l'; + if (mask & AA_MAY_LOCK) + *m++ = 'k'; + *m++ = '\0'; +} + +static void aa_audit_file_mask(struct audit_buffer *ab, const char *name, + int mask) +{ + char user[10], other[10]; + + aa_audit_file_sub_mask(ab, user, + (mask & AA_USER_PERMS) >> AA_USER_SHIFT); + aa_audit_file_sub_mask(ab, other, + (mask & AA_OTHER_PERMS) >> AA_OTHER_SHIFT); + + audit_log_format(ab, " %s=\"%s::%s\"", name, user, other); +} + +static const char *address_families[] = { +#include "af_names.h" +}; + +static const char *sock_types[] = { + "unknown(0)", + "stream", + "dgram", + "raw", + "rdm", + "seqpacket", + "dccp", + "unknown(7)", + "unknown(8)", + "unknown(9)", + "packet", +}; + +/** + * aa_audit - Log an audit event to the audit subsystem + * @profile: profile to check against + * @sa: audit event + * @audit_cxt: audit context to log message to + * @type: audit event number + */ +static int aa_audit_base(struct aa_profile *profile, struct aa_audit *sa, + struct audit_context *audit_cxt, int type) +{ + struct audit_buffer *ab = NULL; + + ab = audit_log_start(audit_cxt, sa->gfp_mask, type); + + if (!ab) { + AA_ERROR("Unable to log event (%d) to audit subsys\n", + type); + /* don't fail operations in complain mode even if logging + * fails */ + return type == AUDIT_APPARMOR_ALLOWED ? 0 : -ENOMEM; + } + + if (sa->operation) + audit_log_format(ab, "operation=\"%s\"", sa->operation); + + if (sa->info) { + audit_log_format(ab, " info=\"%s\"", sa->info); + if (sa->error_code) + audit_log_format(ab, " error=%d", sa->error_code); + } + + if (sa->request_mask) + aa_audit_file_mask(ab, "requested_mask", sa->request_mask); + + if (sa->denied_mask) + aa_audit_file_mask(ab, "denied_mask", sa->denied_mask); + + if (sa->request_mask) + audit_log_format(ab, " fsuid=%d", current->fsuid); + + if (sa->rlimit) + audit_log_format(ab, " rlimit=%d", sa->rlimit - 1); + + if (sa->iattr) { + struct iattr *iattr = sa->iattr; + + audit_log_format(ab, " attribute=\"%s%s%s%s%s%s%s\"", + iattr->ia_valid & ATTR_MODE ? "mode," : "", + iattr->ia_valid & ATTR_UID ? "uid," : "", + iattr->ia_valid & ATTR_GID ? "gid," : "", + iattr->ia_valid & ATTR_SIZE ? "size," : "", + iattr->ia_valid & (ATTR_ATIME | ATTR_ATIME_SET) ? + "atime," : "", + iattr->ia_valid & (ATTR_MTIME | ATTR_MTIME_SET) ? + "mtime," : "", + iattr->ia_valid & ATTR_CTIME ? "ctime," : ""); + } + + if (sa->task) + audit_log_format(ab, " task=%d", sa->task); + + if (sa->parent) + audit_log_format(ab, " parent=%d", sa->parent); + + if (sa->name) { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, sa->name); + } + + if (sa->name2) { + audit_log_format(ab, " name2="); + audit_log_untrustedstring(ab, sa->name2); + } + + if (sa->family || sa->type) { + if (address_families[sa->family]) + audit_log_format(ab, " family=\"%s\"", + address_families[sa->family]); + else + audit_log_format(ab, " family=\"unknown(%d)\"", + sa->family); + + if (sock_types[sa->type]) + audit_log_format(ab, " sock_type=\"%s\"", + sock_types[sa->type]); + else + audit_log_format(ab, " sock_type=\"unknown(%d)\"", + sa->type); + + audit_log_format(ab, " protocol=%d", sa->protocol); + } + + audit_log_format(ab, " pid=%d", current->pid); + + if (profile) { + audit_log_format(ab, " profile="); + audit_log_untrustedstring(ab, profile->name); + + if (profile->ns != default_namespace) { + audit_log_format(ab, " namespace="); + audit_log_untrustedstring(ab, profile->ns->name); + } + } + + audit_log_end(ab); + + return type == AUDIT_APPARMOR_ALLOWED ? 0 : sa->error_code; +} + +/** + * aa_audit_syscallreject - Log a syscall rejection to the audit subsystem + * @profile: profile to check against + * @gfp: memory allocation flags + * @msg: string describing syscall being rejected + */ +int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, + const char *msg) +{ + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "syscall"; + sa.name = msg; + sa.gfp_mask = gfp; + sa.error_code = -EPERM; + + return aa_audit_base(profile, &sa, current->audit_context, + AUDIT_APPARMOR_DENIED); +} + +int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa, + int type) +{ + struct audit_context *audit_cxt; + + audit_cxt = apparmor_logsyscall ? current->audit_context : NULL; + return aa_audit_base(profile, sa, audit_cxt, type); +} + +void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa) +{ + aa_audit_message(profile, sa, AUDIT_APPARMOR_HINT); +} + +void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa) +{ + aa_audit_message(profile, sa, AUDIT_APPARMOR_STATUS); +} + +int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa) +{ + return aa_audit_message(profile, sa, AUDIT_APPARMOR_DENIED); +} + +/** + * aa_audit - Log an audit event to the audit subsystem + * @profile: profile to check against + * @sa: audit event + */ +int aa_audit(struct aa_profile *profile, struct aa_audit *sa) +{ + int type = AUDIT_APPARMOR_DENIED; + struct audit_context *audit_cxt; + + if (likely(!sa->error_code)) + type = AUDIT_APPARMOR_AUDIT; + else if (PROFILE_COMPLAIN(profile)) + type = AUDIT_APPARMOR_ALLOWED; + + audit_cxt = apparmor_logsyscall ? current->audit_context : NULL; + return aa_audit_base(profile, sa, audit_cxt, type); +} + +static int aa_audit_file(struct aa_profile *profile, struct aa_audit *sa) +{ + if (likely(!sa->error_code)) { + int mask = sa->audit_mask & AUDIT_FILE_MASK; + + if (unlikely(PROFILE_AUDIT(profile))) + mask |= AUDIT_FILE_MASK; + + if (likely(!(sa->request_mask & mask))) + return 0; + + /* mask off perms that are not being force audited */ + sa->request_mask &= mask | ALL_AA_EXEC_TYPE; + } else { + int mask = AUDIT_QUIET_MASK(sa->audit_mask); + + if (!(sa->denied_mask & ~mask)) + return sa->error_code; + + /* mask off perms whose denial is being silenced */ + if (!PROFILE_COMPLAIN(profile)) + sa->denied_mask &= (~mask) | ALL_AA_EXEC_TYPE; + } + + return aa_audit(profile, sa); +} + +static int aa_audit_caps(struct aa_profile *profile, struct aa_audit *sa, + int cap) +{ + if (likely(!sa->error_code)) { + if (likely(!PROFILE_AUDIT(profile) && + !cap_raised(profile->audit_caps, cap))) + return 0; + } + + /* quieting of capabilities is handled the caps_logged cache */ + return aa_audit(profile, sa); +} + +/** + * aa_file_denied - check for @mask access on a file + * @profile: profile to check against + * @name: pathname of file + * @mask: permission mask requested for file + * @audit_mask: return audit mask for the match + * + * Return %0 on success, or else the permissions in @mask that the + * profile denies. + */ +static int aa_file_denied(struct aa_profile *profile, const char *name, + int mask, int *audit_mask) +{ + return (mask & ~aa_match(profile->file_rules, name, audit_mask)); +} + +/** + * aa_link_denied - check for permission to link a file + * @profile: profile to check against + * @link: pathname of link being created + * @target: pathname of target to be linked to + * @target_mode: UGO shift for target inode + * @request_mask: the permissions subset valid only if link succeeds + * @audit_mask: return the audit_mask for the link permission + * Return %0 on success, or else the permissions that the profile denies. + */ +static int aa_link_denied(struct aa_profile *profile, const char *link, + const char *target, int target_mode, + int *request_mask, int *audit_mask) +{ + unsigned int state; + int l_mode, t_mode, l_x, t_x, denied_mask = 0; + int link_mask = AA_MAY_LINK << target_mode; + + *request_mask = link_mask; + + l_mode = aa_match_state(profile->file_rules, DFA_START, link, &state); + + if (l_mode & link_mask) { + int mode; + /* test to see if target can be paired with link */ + state = aa_dfa_null_transition(profile->file_rules, state); + mode = aa_match_state(profile->file_rules, state, target, + &state); + + if (!(mode & link_mask)) + denied_mask |= link_mask; + + *audit_mask = dfa_audit_mask(profile->file_rules, state); + + /* return if link subset test is not required */ + if (!(mode & (AA_LINK_SUBSET_TEST << target_mode))) + return denied_mask; + } + + /* Do link perm subset test requiring permission on link are a + * subset of the permissions on target. + * If a subset test is required a permission subset test of the + * perms for the link are done against the user::other of the + * target's 'r', 'w', 'x', 'a', 'k', and 'm' permissions. + * + * If the link has 'x', an exact match of all the execute flags + * must match. + */ + denied_mask |= ~l_mode & link_mask; + + t_mode = aa_match(profile->file_rules, target, NULL); + + l_x = l_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS); + t_x = t_mode & (ALL_AA_EXEC_TYPE | AA_EXEC_BITS); + + /* For actual subset test ignore valid-profile-transition flags, + * and link bits + */ + l_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; + t_mode &= AA_FILE_PERMS & ~AA_LINK_BITS; + + *request_mask = l_mode | link_mask; + + if (l_mode) { + int x = l_x | (t_x & ALL_AA_EXEC_UNSAFE); + denied_mask |= l_mode & ~t_mode; + /* mask off x modes not used by link */ + + /* handle exec subset + * - link safe exec issubset of unsafe exec + * - no link x perm is subset of target having x perm + */ + if ((l_mode & AA_USER_EXEC) && + (x & AA_USER_EXEC_TYPE) != (t_x & AA_USER_EXEC_TYPE)) + denied_mask = AA_USER_EXEC | (l_x & AA_USER_EXEC_TYPE); + if ((l_mode & AA_OTHER_EXEC) && + (x & AA_OTHER_EXEC_TYPE) != (t_x & AA_OTHER_EXEC_TYPE)) + denied_mask = AA_OTHER_EXEC | (l_x & AA_OTHER_EXEC_TYPE); + } + + return denied_mask; +} + +/** + * aa_get_name - compute the pathname of a file + * @dentry: dentry of the file + * @mnt: vfsmount of the file + * @buffer: buffer that aa_get_name() allocated + * @check: AA_CHECK_DIR is set if the file is a directory + * + * Returns a pointer to the beginning of the pathname (which usually differs + * from the beginning of the buffer), or an error code. + * + * We need @check to indicate whether the file is a directory or not because + * the file may not yet exist, and so we cannot check the inode's file type. + */ +static char *aa_get_name(struct dentry *dentry, struct vfsmount *mnt, + char **buffer, int check) +{ + char *name; + int is_dir, size = 256; + + is_dir = (check & AA_CHECK_DIR) ? 1 : 0; + + for (;;) { + char *buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return ERR_PTR(-ENOMEM); + + name = d_namespace_path(dentry, mnt, buf, size - is_dir); + if (!IS_ERR(name)) { + if (name[0] != '/') { + /* + * This dentry is not connected to the + * namespace root -- reject access. + */ + kfree(buf); + return ERR_PTR(-ENOENT); + } + if (is_dir && name[1] != '\0') { + /* + * Append "/" to the pathname. The root + * directory is a special case; it already + * ends in slash. + */ + buf[size - 2] = '/'; + buf[size - 1] = '\0'; + } + + *buffer = buf; + return name; + } + if (PTR_ERR(name) != -ENAMETOOLONG) + return name; + + kfree(buf); + size <<= 1; + if (size > apparmor_path_max) + return ERR_PTR(-ENAMETOOLONG); + } +} + +static char *new_compound_name(const char *n1, const char *n2) +{ + char *name = kmalloc(strlen(n1) + strlen(n2) + 3, GFP_KERNEL); + if (name) + sprintf(name, "%s//%s", n1, n2); + return name; +} +static inline void aa_put_name_buffer(char *buffer) +{ + kfree(buffer); +} + +/** + * aa_perm_dentry - check if @profile allows @mask for a file + * @profile: profile to check against + * @dentry: dentry of the file + * @mnt: vfsmount o the file + * @sa: audit context + * @mask: requested profile permissions + * @check: kind of check to perform + * + * Returns 0 upon success, or else an error code. + * + * @check indicates the file type, and whether the file was accessed through + * an open file descriptor (AA_CHECK_FD) or not. + */ +static int aa_perm_dentry(struct aa_profile *profile, struct dentry *dentry, + struct vfsmount *mnt, struct aa_audit *sa, int check) +{ + int error; + char *buffer = NULL; + + sa->name = aa_get_name(dentry, mnt, &buffer, check); + sa->request_mask <<= aa_inode_mode(dentry->d_inode); + if (IS_ERR(sa->name)) { + /* + * deleted files are given a pass on permission checks when + * accessed through a file descriptor. + */ + if (PTR_ERR(sa->name) == -ENOENT && (check & AA_CHECK_FD)) + sa->denied_mask = 0; + else { + sa->denied_mask = sa->request_mask; + sa->error_code = PTR_ERR(sa->name); + if (sa->error_code == -ENOENT) + sa->info = "Failed name resolution - object not a valid entry"; + else if (sa->error_code == -ENAMETOOLONG) + sa->info = "Failed name resolution - name too long"; + else + sa->info = "Failed name resolution"; + } + sa->name = NULL; + } else + sa->denied_mask = aa_file_denied(profile, sa->name, + sa->request_mask, + &sa->audit_mask); + + if (!sa->denied_mask) + sa->error_code = 0; + + error = aa_audit_file(profile, sa); + aa_put_name_buffer(buffer); + + return error; +} + +/** + * aa_attr - check if attribute change is allowed + * @profile: profile to check against + * @dentry: dentry of the file to check + * @mnt: vfsmount of the file to check + * @iattr: attribute changes requested + */ +int aa_attr(struct aa_profile *profile, struct dentry *dentry, + struct vfsmount *mnt, struct iattr *iattr) +{ + struct inode *inode = dentry->d_inode; + int error, check; + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "setattr"; + sa.gfp_mask = GFP_KERNEL; + sa.iattr = iattr; + sa.request_mask = MAY_WRITE; + sa.error_code = -EACCES; + + check = 0; + if (inode && S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + if (iattr->ia_valid & ATTR_FILE) + check |= AA_CHECK_FD; + + error = aa_perm_dentry(profile, dentry, mnt, &sa, check); + + return error; +} + +/** + * aa_perm_xattr - check if xattr attribute change is allowed + * @profile: profile to check against + * @dentry: dentry of the file to check + * @mnt: vfsmount of the file to check + * @operation: xattr operation being done + * @mask: access mode requested + * @check: kind of check to perform + */ +int aa_perm_xattr(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask, + int check) +{ + struct inode *inode = dentry->d_inode; + int error; + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.error_code = -EACCES; + + if (inode && S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + + error = aa_perm_dentry(profile, dentry, mnt, &sa, check); + + return error; +} + +/** + * aa_perm - basic apparmor permissions check + * @profile: profile to check against + * @dentry: dentry of the file to check + * @mnt: vfsmount of the file to check + * @mask: access mode requested + * @check: kind of check to perform + * + * Determine if access @mask for the file is authorized by @profile. + * Returns 0 on success, or else an error code. + */ +int aa_perm(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask, int check) +{ + struct aa_audit sa; + int error = 0; + + if (mask == 0) + goto out; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.error_code = -EACCES; + + error = aa_perm_dentry(profile, dentry, mnt, &sa, check); + +out: + return error; +} + +/** + * aa_perm_dir + * @profile: profile to check against + * @dentry: dentry of directory to check + * @mnt: vfsmount of directory to check + * @operation: directory operation being performed + * @mask: access mode requested + * + * Determine if directory operation (make/remove) for dentry is authorized + * by @profile. + * Returns 0 on success, or else an error code. + */ +int aa_perm_dir(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask) +{ + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.error_code = -EACCES; + + return aa_perm_dentry(profile, dentry, mnt, &sa, AA_CHECK_DIR); +} + +int aa_perm_path(struct aa_profile *profile, const char *operation, + const char *name, int mask, uid_t uid) +{ + struct aa_audit sa; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = mask; + sa.name = name; + if (current->fsuid == uid) + sa.request_mask = mask << AA_USER_SHIFT; + else + sa.request_mask = mask << AA_OTHER_SHIFT; + + sa.denied_mask = aa_file_denied(profile, name, sa.request_mask, + &sa.audit_mask) ; + sa.error_code = sa.denied_mask ? -EACCES : 0; + + return aa_audit_file(profile, &sa); +} + +/** + * aa_capability - test permission to use capability + * @cxt: aa_task_context with profile to check against + * @cap: capability to be tested + * + * Look up capability in profile capability set. + * Returns 0 on success, or else an error code. + */ +int aa_capability(struct aa_task_context *cxt, int cap) +{ + int error = cap_raised(cxt->profile->capabilities, cap) ? 0 : -EPERM; + struct aa_audit sa; + + /* test if cap has alread been logged */ + if (cap_raised(cxt->caps_logged, cap)) { + if (PROFILE_COMPLAIN(cxt->profile)) + error = 0; + return error; + } else + /* don't worry about rcu replacement of the cxt here. + * caps_logged is a cache to reduce the occurence of + * duplicate messages in the log. The worst that can + * happen is duplicate capability messages shows up in + * the audit log + */ + cap_raise(cxt->caps_logged, cap); + + memset(&sa, 0, sizeof(sa)); + sa.operation = "capable"; + sa.gfp_mask = GFP_ATOMIC; + sa.name = capability_names[cap]; + sa.error_code = error; + + error = aa_audit_caps(cxt->profile, &sa, cap); + + return error; +} + +/* must be used inside rcu_read_lock or task_lock */ +int aa_may_ptrace(struct aa_task_context *cxt, struct aa_profile *tracee) +{ + if (!cxt || cxt->profile == tracee) + return 0; + return aa_capability(cxt, CAP_SYS_PTRACE); +} + +/** + * aa_link - hard link check + * @profile: profile to check against + * @link: dentry of link being created + * @link_mnt: vfsmount of link being created + * @target: dentry of link target + * @target_mnt: vfsmunt of link target + * + * Returns 0 on success, or else an error code. + */ +int aa_link(struct aa_profile *profile, + struct dentry *link, struct vfsmount *link_mnt, + struct dentry *target, struct vfsmount *target_mnt) +{ + int error; + struct aa_audit sa; + char *buffer = NULL, *buffer2 = NULL; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "inode_link"; + sa.gfp_mask = GFP_KERNEL; + sa.name = aa_get_name(link, link_mnt, &buffer, 0); + sa.name2 = aa_get_name(target, target_mnt, &buffer2, 0); + + if (IS_ERR(sa.name)) { + sa.error_code = PTR_ERR(sa.name); + sa.name = NULL; + } + if (IS_ERR(sa.name2)) { + sa.error_code = PTR_ERR(sa.name2); + sa.name2 = NULL; + } + + if (sa.name && sa.name2) { + sa.denied_mask = aa_link_denied(profile, sa.name, sa.name2, + aa_inode_mode(target->d_inode), + &sa.request_mask, + &sa.audit_mask); + sa.error_code = sa.denied_mask ? -EACCES : 0; + } + + error = aa_audit_file(profile, &sa); + + aa_put_name_buffer(buffer); + aa_put_name_buffer(buffer2); + + return error; +} + +int aa_net_perm(struct aa_profile *profile, char *operation, + int family, int type, int protocol) +{ + struct aa_audit sa; + int error = 0; + u16 family_mask, audit_mask, quiet_mask; + + if ((family < 0) || (family >= AF_MAX)) + return -EINVAL; + + if ((type < 0) || (type >= SOCK_MAX)) + return -EINVAL; + + /* unix domain and netlink sockets are handled by ipc */ + if (family == AF_UNIX || family == AF_NETLINK) + return 0; + + family_mask = profile->network_families[family]; + audit_mask = profile->audit_network[family]; + quiet_mask = profile->quiet_network[family]; + + error = (family_mask & (1 << type)) ? 0 : -EACCES; + + memset(&sa, 0, sizeof(sa)); + sa.operation = operation; + sa.gfp_mask = GFP_KERNEL; + sa.family = family; + sa.type = type; + sa.protocol = protocol; + sa.error_code = error; + + if (likely(!error)) { + if (!PROFILE_AUDIT(profile) && !(family_mask & audit_mask)) + return 0; + } else if (!((1 << type) & ~quiet_mask)) { + return error; + } + + error = aa_audit(profile, &sa); + + return error; +} + +int aa_revalidate_sk(struct sock *sk, char *operation) +{ + struct aa_profile *profile; + int error = 0; + + /* this is some debugging code to flush out the network hooks that + that are called in interrupt context */ + if (in_interrupt()) { + printk("AppArmor Debug: Hook being called from interrupt context\n"); + dump_stack(); + return 0; + } + + profile = aa_get_profile(current); + if (profile) + error = aa_net_perm(profile, operation, + sk->sk_family, sk->sk_type, + sk->sk_protocol); + aa_put_profile(profile); + + return error; +} +/** + * aa_task_setrlimit - test permission to set an rlimit + * @profile - profile confining the task + * @resource - the resource being set + * @new_rlim - the new resource limit + * + * Control raising the processes hard limit. + */ +int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, + struct rlimit *new_rlim) +{ + struct aa_audit sa; + int error = 0; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "setrlimit"; + sa.gfp_mask = GFP_KERNEL; + sa.rlimit = resource + 1; + + if (profile->rlimits.mask & (1 << resource) && + new_rlim->rlim_max > profile->rlimits.limits[resource].rlim_max) { + sa.error_code = -EACCES; + + error = aa_audit(profile, &sa); + } + + return error; +} + +static int aa_rlimit_nproc(struct aa_profile *profile) { + if (profile && (profile->rlimits.mask & (1 << RLIMIT_NPROC)) && + profile->task_count >= profile->rlimits.limits[RLIMIT_NPROC].rlim_max) + return -EAGAIN; + return 0; +} + +void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile) +{ + int i, mask; + + if (!profile) + return; + + if (!profile->rlimits.mask) + return; + + task_lock(task->group_leader); + mask = 1; + for (i = 0; i < RLIM_NLIMITS; i++, mask <<= 1) { + struct rlimit new_rlim, *old_rlim; + + /* check to see if NPROC which is per profile and handled + * in clone/exec or whether this is a limit to be set + * can't set cpu limit either right now + */ + if (i == RLIMIT_NPROC || i == RLIMIT_CPU) + continue; + + old_rlim = task->signal->rlim + i; + new_rlim = *old_rlim; + + if (mask & profile->rlimits.mask && + profile->rlimits.limits[i].rlim_max < new_rlim.rlim_max) { + new_rlim.rlim_max = profile->rlimits.limits[i].rlim_max; + /* soft limit should not exceed hard limit */ + if (new_rlim.rlim_cur > new_rlim.rlim_max) + new_rlim.rlim_cur = new_rlim.rlim_max; + } + + *old_rlim = new_rlim; + } + task_unlock(task->group_leader); +} + +/******************************* + * Global task related functions + *******************************/ + +/** + * aa_clone - initialize the task context for a new task + * @child: task that is being created + * + * Returns 0 on success, or else an error code. + */ +int aa_clone(struct task_struct *child) +{ + struct aa_audit sa; + struct aa_task_context *cxt, *child_cxt; + struct aa_profile *profile; + + if (!aa_task_context(current)) + return 0; + child_cxt = aa_alloc_task_context(GFP_KERNEL); + if (!child_cxt) + return -ENOMEM; + + memset(&sa, 0, sizeof(sa)); + sa.operation = "clone"; + sa.task = child->pid; + sa.gfp_mask = GFP_KERNEL; + +repeat: + profile = aa_get_profile(current); + if (profile) { + lock_profile(profile); + cxt = aa_task_context(current); + if (unlikely(profile->isstale || !cxt || + cxt->profile != profile)) { + /** + * Race with profile replacement or removal, or with + * task context removal. + */ + unlock_profile(profile); + aa_put_profile(profile); + goto repeat; + } + + if (aa_rlimit_nproc(profile)) { + sa.info = "rlimit nproc limit exceeded"; + unlock_profile(profile); + aa_audit_reject(profile, &sa); + aa_put_profile(profile); + return -EAGAIN; + } + + /* No need to grab the child's task lock here. */ + aa_change_task_context(child, child_cxt, profile, + cxt->cookie, cxt->previous_profile); + + unlock_profile(profile); + + if (APPARMOR_COMPLAIN(child_cxt) && + profile == profile->ns->null_complain_profile) { + aa_audit_hint(profile, &sa); + } + aa_put_profile(profile); + } else + aa_free_task_context(child_cxt); + + return 0; +} + +static struct aa_profile * +aa_register_find(struct aa_profile *profile, const char* ns_name, + const char *name, int mandatory, int complain, + struct aa_audit *sa) +{ + struct aa_namespace *ns; + struct aa_profile *new_profile; + int ns_ref = 0; + + if (profile) + ns = profile->ns; + else + ns = default_namespace; + + if (ns_name) { + /* locate the profile namespace */ + ns = aa_find_namespace(ns_name); + if (!ns) { + if (mandatory) { + sa->info = "profile namespace not found"; + sa->denied_mask = sa->request_mask; + sa->error_code = -ENOENT; + return ERR_PTR(-ENOENT); + } else { + return NULL; + } + } + ns_ref++; + } + + /* Locate new profile */ + new_profile = aa_find_profile(ns, name); + + if (new_profile) { + AA_DEBUG("%s: setting profile %s\n", + __FUNCTION__, new_profile->name); + } else if (mandatory && profile) { + sa->info = "mandatory profile missing"; + sa->denied_mask = sa->request_mask; /* shifted MAY_EXEC */ + if (complain) { + aa_audit_hint(profile, sa); + new_profile = + aa_dup_profile(profile->ns->null_complain_profile); + } else { + sa->error_code = -EACCES; + if (ns_ref) + aa_put_namespace(ns); + return ERR_PTR(-EACCES); + } + } else { + /* Only way we can get into this code is if task + * is unconfined, pix, nix. + */ + AA_DEBUG("%s: No profile found for exec image '%s'\n", + __FUNCTION__, + name); + } + if (ns_ref) + aa_put_namespace(ns); + return new_profile; +} + +static struct aa_profile * +aa_x_to_profile(struct aa_profile *profile, const char *filename, int xmode, + struct aa_audit *sa, char **child) +{ + struct aa_profile *new_profile = NULL; + int ix = xmode & AA_EXEC_INHERIT; + int complain = PROFILE_COMPLAIN(profile); + int index; + + *child = NULL; + switch (xmode & AA_EXEC_MODIFIERS) { + case 0: + /* only valid with ix flag */ + ix = 1; + break; + case AA_EXEC_UNCONFINED: + /* only valid without ix flag */ + ix = 0; + break; + case AA_EXEC_PROFILE: + new_profile = aa_register_find(profile, NULL, filename, !ix, + complain, sa); + break; + case AA_EXEC_CHILD: + *child = new_compound_name(profile->name, filename); + sa->name2 = *child; + if (!*child) { + sa->info = "Failed name resolution - exec failed"; + sa->error_code = -ENOMEM; + new_profile = ERR_PTR(-ENOMEM); + } else { + new_profile = aa_register_find(profile, NULL, *child, + !ix, complain, sa); + } + break; + default: + /* all other indexes are named transitions */ + index = AA_EXEC_INDEX(xmode); + if (index - 4 > profile->exec_table_size) { + sa->info = "invalid named transition - exec failed"; + sa->error_code = -EACCES; + new_profile = ERR_PTR(-EACCES); + } else { + char *ns_name = NULL; + char *name = profile->exec_table[index - 4]; + if (*name == ':') { + ns_name = name + 1; + name = ns_name + strlen(ns_name) + 1; + } + sa->name2 = name; + sa->name3 = ns_name; + new_profile = + aa_register_find(profile, ns_name, name, + !ix, complain, sa); + } + } + if (IS_ERR(new_profile)) + /* all these failures must be audited - no quieting */ + return ERR_PTR(aa_audit_reject(profile, sa)); + return new_profile; +} + +/** + * aa_register - register a new program + * @bprm: binprm of program being registered + * + * Try to register a new program during execve(). This should give the + * new program a valid aa_task_context if confined. + */ +int aa_register(struct linux_binprm *bprm) +{ + const char *filename; + char *buffer = NULL, *child = NULL; + struct file *filp = bprm->file; + struct aa_profile *profile, *old_profile, *new_profile = NULL; + int exec_mode, complain = 0, shift; + struct aa_audit sa; + + AA_DEBUG("%s\n", __FUNCTION__); + + profile = aa_get_profile(current); + + shift = aa_inode_mode(filp->f_dentry->d_inode); + memset(&sa, 0, sizeof(sa)); + sa.operation = "exec"; + sa.gfp_mask = GFP_KERNEL; + sa.request_mask = MAY_EXEC << shift; + + filename = aa_get_name(filp->f_dentry, filp->f_vfsmnt, &buffer, 0); + if (IS_ERR(filename)) { + if (profile) { + sa.info = "Failed name resolution - exec failed"; + sa.error_code = PTR_ERR(filename); + aa_audit_file(profile, &sa); + return sa.error_code; + } else + return 0; + } + sa.name = filename; + + exec_mode = AA_EXEC_UNSAFE << shift; + +repeat: + if (profile) { + complain = PROFILE_COMPLAIN(profile); + + /* Confined task, determine what mode inherit, unconfined or + * mandatory to load new profile + */ + exec_mode = aa_match(profile->file_rules, filename, + &sa.audit_mask); + + + if (exec_mode & sa.request_mask) { + int xm = exec_mode >> shift; + new_profile = aa_x_to_profile(profile, filename, + xm, &sa, &child); + + if (!new_profile && (xm & AA_EXEC_INHERIT)) + /* (p|c|n|)ix - don't change profile */ + goto cleanup; + /* error case caught below */ + + } else if (sa.request_mask & AUDIT_QUIET_MASK(sa.audit_mask)) { + /* quiet failed exit */ + new_profile = ERR_PTR(-EACCES); + } else if (complain) { + /* There was no entry in calling profile + * describing mode to execute image in. + * Drop into null-profile (disabling secure exec). + */ + new_profile = + aa_dup_profile(profile->ns->null_complain_profile); + exec_mode |= AA_EXEC_UNSAFE << shift; + } else { + sa.denied_mask = sa.request_mask; + sa.error_code = -EACCES; + new_profile = ERR_PTR(aa_audit_file(profile, &sa)); + } + } else { + /* Unconfined task, load profile if it exists */ + new_profile = aa_register_find(NULL, NULL, filename, 0, 0, &sa); + if (new_profile == NULL) + goto cleanup; + } + + if (IS_ERR(new_profile)) + goto cleanup; + + old_profile = __aa_replace_profile(current, new_profile); + if (IS_ERR(old_profile)) { + aa_put_profile(new_profile); + aa_put_profile(profile); + if (PTR_ERR(old_profile) == -ESTALE) { + profile = aa_get_profile(current); + goto repeat; + } + if (PTR_ERR(old_profile) == -EPERM) { + sa.denied_mask = sa.request_mask; + sa.info = "unable to set profile due to ptrace"; + sa.task = current->parent->pid; + aa_audit_reject(profile, &sa); + } + if (PTR_ERR(old_profile) == -EAGAIN) { + sa.info = "rlimit nproc limit exceeded"; + aa_audit_reject(profile, &sa); + } + new_profile = old_profile; + goto cleanup; + } + aa_put_profile(old_profile); + aa_put_profile(profile); + + /* Handle confined exec. + * Can be at this point for the following reasons: + * 1. unconfined switching to confined + * 2. confined switching to different confinement + * 3. confined switching to unconfined + * + * Cases 2 and 3 are marked as requiring secure exec + * (unless policy specified "unsafe exec") + */ + if (!(exec_mode & (AA_EXEC_UNSAFE << shift))) { + unsigned long bprm_flags; + + bprm_flags = AA_SECURE_EXEC_NEEDED; + bprm->security = (void*) + ((unsigned long)bprm->security | bprm_flags); + } + + if (complain && new_profile && + new_profile == new_profile->ns->null_complain_profile) { + sa.request_mask = 0; + sa.name = NULL; + sa.info = "set profile"; + aa_audit_hint(new_profile, &sa); + } + +cleanup: + aa_put_name_buffer(child); + aa_put_name_buffer(buffer); + if (IS_ERR(new_profile)) + return PTR_ERR(new_profile); + aa_put_profile(new_profile); + return 0; +} + +/** + * aa_release - release a task context + * @task: task being released + * + * This is called after a task has exited and the parent has reaped it. + */ +void aa_release(struct task_struct *task) +{ + struct aa_task_context *cxt; + struct aa_profile *profile; + /* + * While the task context is still on a profile's task context + * list, another process could replace the profile under us, + * leaving us with a locked profile that is no longer attached + * to this task. So after locking the profile, we check that + * the profile is still attached. The profile lock is + * sufficient to prevent the replacement race so we do not lock + * the task. + * + * Use lock subtyping to avoid lockdep reporting a false irq + * possible inversion between the task_lock and profile_lock + * + * We also avoid taking the task_lock here because lock_dep + * would report another false {softirq-on-W} potential irq_lock + * inversion. + * + * If the task does not have a profile attached we are safe; + * nothing can race with us at this point. + */ + +repeat: + profile = aa_get_profile(task); + if (profile) { + lock_profile_nested(profile, aa_lock_task_release); + cxt = aa_task_context(task); + if (unlikely(!cxt || cxt->profile != profile)) { + unlock_profile(profile); + aa_put_profile(profile); + goto repeat; + } + aa_change_task_context(task, NULL, NULL, 0, NULL); + unlock_profile(profile); + aa_put_profile(profile); + } +} + +static int do_change_profile(struct aa_profile *expected, + struct aa_namespace *ns, const char *name, + u64 cookie, int restore, int hat, + struct aa_audit *sa) +{ + struct aa_profile *new_profile = NULL, *old_profile = NULL, + *previous_profile = NULL; + struct aa_task_context *new_cxt, *cxt; + int error = 0; + + sa->name = name; + + new_cxt = aa_alloc_task_context(GFP_KERNEL); + if (!new_cxt) + return -ENOMEM; + + new_profile = aa_find_profile(ns, name); + if (!new_profile && !restore) { + if (!PROFILE_COMPLAIN(expected)) { + aa_free_task_context(new_cxt); + return -ENOENT; + } + new_profile = aa_dup_profile(ns->null_complain_profile); + } else if (new_profile && hat && !PROFILE_IS_HAT(new_profile)) { + aa_free_task_context(new_cxt); + aa_put_profile(new_profile); + return error; + } + + cxt = lock_task_and_profiles(current, new_profile); + if (!cxt) { + error = -EPERM; + goto out; + } + old_profile = cxt->profile; + + if (cxt->profile != expected || (new_profile && new_profile->isstale)) { + error = -ESTALE; + goto out; + } + + if (cxt->previous_profile) { + if (cxt->cookie != cookie) { + error = -EACCES; + sa->info = "killing process"; + aa_audit_reject(cxt->profile, sa); + /* terminate process */ + (void)send_sig_info(SIGKILL, NULL, current); + goto out; + } + + if (!restore) + previous_profile = cxt->previous_profile; + } else + previous_profile = cxt->profile; + + if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, new_profile)) { + error = -EACCES; + goto out; + } + + if ((error = aa_rlimit_nproc(new_profile))) { + sa->info = "rlimit nproc limit exceeded"; + aa_audit_reject(cxt->profile, sa); + goto out; + } + + if (new_profile == ns->null_complain_profile) + aa_audit_hint(cxt->profile, sa); + + if (APPARMOR_AUDIT(cxt)) + aa_audit_message(cxt->profile, sa, AUDIT_APPARMOR_AUDIT); + + if (!restore && cookie) + aa_change_task_context(current, new_cxt, new_profile, cookie, + previous_profile); + else + /* either return to previous_profile, or a permanent change */ + aa_change_task_context(current, new_cxt, new_profile, 0, NULL); + +out: + if (aa_task_context(current) != new_cxt) + aa_free_task_context(new_cxt); + task_unlock(current); + unlock_both_profiles(old_profile, new_profile); + aa_put_profile(new_profile); + return error; +} + +/** + * aa_change_profile - perform a one-way profile transition + * @ns_name: name of the profile namespace to change to + * @name: name of profile to change to + * Change to new profile @name. Unlike with hats, there is no way + * to change back. + * + * Returns %0 on success, error otherwise. + */ +int aa_change_profile(const char *ns_name, const char *name) +{ + struct aa_task_context *cxt; + struct aa_profile *profile = NULL; + struct aa_namespace *ns = NULL; + struct aa_audit sa; + unsigned int state; + int error = -EINVAL; + + if (!name) + return -EINVAL; + + memset(&sa, 0, sizeof(sa)); + sa.gfp_mask = GFP_ATOMIC; + sa.operation = "change_profile"; + +repeat: + task_lock(current); + cxt = aa_task_context(current); + if (cxt) + profile = aa_dup_profile(cxt->profile); + task_unlock(current); + + if (ns_name) + ns = aa_find_namespace(ns_name); + else if (profile) + ns = aa_get_namespace(profile->ns); + else + ns = aa_get_namespace(default_namespace); + + if (!ns) { + aa_put_profile(profile); + return -ENOENT; + } + + if (!profile || PROFILE_COMPLAIN(profile) || + (ns == profile->ns && + (aa_match(profile->file_rules, name, NULL) & AA_CHANGE_PROFILE))) + error = do_change_profile(profile, ns, name, 0, 0, 0, &sa); + else { + /* check for a rule with a namespace prepended */ + aa_match_state(profile->file_rules, DFA_START, ns->name, + &state); + state = aa_dfa_null_transition(profile->file_rules, state); + if ((aa_match_state(profile->file_rules, state, name, NULL) & + AA_CHANGE_PROFILE)) + error = do_change_profile(profile, ns, name, 0, 0, 0, + &sa); + else + /* no permission to transition to profile @name */ + error = -EACCES; + } + + aa_put_namespace(ns); + aa_put_profile(profile); + if (error == -ESTALE) + goto repeat; + + return error; +} + +/** + * aa_change_hat - change hat to/from subprofile + * @hat_name: hat to change to + * @cookie: magic value to validate the hat change + * + * Change to new @hat_name, and store the @hat_magic in the current task + * context. If the new @hat_name is %NULL and the @cookie matches that + * stored in the current task context and is not 0, return to the top level + * profile. + * Returns %0 on success, error otherwise. + */ +int aa_change_hat(const char *hat_name, u64 cookie) +{ + struct aa_task_context *cxt; + struct aa_profile *profile, *previous_profile; + struct aa_audit sa; + int error = 0; + + memset(&sa, 0, sizeof(sa)); + sa.gfp_mask = GFP_ATOMIC; + sa.operation = "change_hat"; + +repeat: + task_lock(current); + cxt = aa_task_context(current); + if (!cxt) { + task_unlock(current); + return -EPERM; + } + profile = aa_dup_profile(cxt->profile); + previous_profile = aa_dup_profile(cxt->previous_profile); + task_unlock(current); + + if (hat_name) { + char *name, *profile_name; + + if (previous_profile) + profile_name = previous_profile->name; + else + profile_name = profile->name; + + name = new_compound_name(profile_name, hat_name); + if (!name) { + error = -ENOMEM; + goto out; + } + error = do_change_profile(profile, profile->ns, name, cookie, + 0, 1, &sa); + aa_put_name_buffer(name); + } else if (previous_profile) + error = do_change_profile(profile, profile->ns, + previous_profile->name, cookie, 1, 0, + &sa); + /* else ignore restores when there is no saved profile */ + +out: + aa_put_profile(previous_profile); + aa_put_profile(profile); + if (error == -ESTALE) + goto repeat; + + return error; +} + +/** + * __aa_replace_profile - replace a task's profile + * @task: task to switch the profile of + * @profile: profile to switch to + * + * Returns a handle to the previous profile upon success, or else an + * error code. + */ +struct aa_profile *__aa_replace_profile(struct task_struct *task, + struct aa_profile *profile) +{ + struct aa_task_context *cxt, *new_cxt = NULL; + struct aa_profile *old_profile = NULL; + + if (profile) { + new_cxt = aa_alloc_task_context(GFP_KERNEL); + if (!new_cxt) + return ERR_PTR(-ENOMEM); + } + + cxt = lock_task_and_profiles(task, profile); + if (unlikely(profile && profile->isstale)) { + old_profile = ERR_PTR(-ESTALE); + goto error; + } + + if ((current->ptrace & PT_PTRACED) && aa_may_ptrace(cxt, profile)) { + old_profile = ERR_PTR(-EPERM); + goto error; + } + + if (aa_rlimit_nproc(profile)) { + old_profile = ERR_PTR(-EAGAIN); + goto error; + } + + if (cxt) + old_profile = aa_dup_profile(cxt->profile); + aa_change_task_context(task, new_cxt, profile, 0, NULL); + + task_unlock(task); + aa_set_rlimits(task, profile); + unlock_both_profiles(profile, old_profile); + return old_profile; + +error: + task_unlock(task); + unlock_both_profiles(profile, cxt ? cxt->profile : NULL); + aa_free_task_context(new_cxt); + return old_profile; +} + +/** + * lock_task_and_profiles - lock the task and confining profiles and @profile + * @task: task to lock + * @profile: extra profile to lock in addition to the current profile + * + * Handle the spinning on locking to make sure the task context and + * profile are consistent once all locks are aquired. + * + * return the aa_task_context currently confining the task. The task lock + * will be held whether or not the task is confined. + */ +struct aa_task_context * +lock_task_and_profiles(struct task_struct *task, struct aa_profile *profile) +{ + struct aa_task_context *cxt; + struct aa_profile *old_profile = NULL; + + rcu_read_lock(); +repeat: + cxt = aa_task_context(task); + if (cxt) + old_profile = cxt->profile; + + lock_both_profiles(profile, old_profile); + task_lock(task); + + /* check for race with profile transition, replacement or removal */ + if (unlikely(cxt != aa_task_context(task))) { + task_unlock(task); + unlock_both_profiles(profile, old_profile); + old_profile = NULL; + goto repeat; + } + rcu_read_unlock(); + return cxt; +} + +static void free_aa_task_context_rcu_callback(struct rcu_head *head) +{ + struct aa_task_context *cxt; + + cxt = container_of(head, struct aa_task_context, rcu); + aa_free_task_context(cxt); +} + +/** + * aa_change_task_context - switch a task to use a new context and profile + * @task: task that is having its task context changed + * @new_cxt: new task context to use after the switch + * @profile: new profile to use after the switch + * @cookie: magic value to switch to + * @previous_profile: profile the task can return to + */ +void aa_change_task_context(struct task_struct *task, + struct aa_task_context *new_cxt, + struct aa_profile *profile, u64 cookie, + struct aa_profile *previous_profile) +{ + struct aa_task_context *old_cxt = aa_task_context(task); + + if (old_cxt) { + list_del_init(&old_cxt->list); + old_cxt->profile->task_count--; + call_rcu(&old_cxt->rcu, free_aa_task_context_rcu_callback); + } + if (new_cxt) { + /* set the caps_logged cache to the quiet_caps mask + * this has the effect of quieting caps that are not + * supposed to be logged + */ + new_cxt->caps_logged = profile->quiet_caps; + new_cxt->cookie = cookie; + new_cxt->task = task; + new_cxt->profile = aa_dup_profile(profile); + profile->task_count++; + new_cxt->previous_profile = aa_dup_profile(previous_profile); + list_move(&new_cxt->list, &profile->task_contexts); + } + rcu_assign_pointer(task->security, new_cxt); +} --- linux-2.6.28.orig/security/apparmor/Kconfig +++ linux-2.6.28/security/apparmor/Kconfig @@ -0,0 +1,42 @@ +config SECURITY_APPARMOR + bool "AppArmor support" + depends on SECURITY + select AUDIT + help + This enables the AppArmor security module. + Required userspace tools (if they are not included in your + distribution) and further information may be found at + + + If you are unsure how to answer this question, answer N. + +config SECURITY_APPARMOR_BOOTPARAM_VALUE + int "AppArmor boot parameter default value" + depends on SECURITY_APPARMOR + range 0 1 + default 1 + help + This option sets the default value for the kernel parameter + 'apparmor', which allows AppArmor to be enabled or disabled + at boot. If this option is set to 0 (zero), the AppArmor + kernel parameter will default to 0, disabling AppArmor at + bootup. If this option is set to 1 (one), the AppArmor + kernel parameter will default to 1, enabling AppArmor at + bootup. + + If you are unsure how to answer this question, answer 1. + +config SECURITY_APPARMOR_DISABLE + bool "AppArmor runtime disable" + depends on SECURITY_APPARMOR + default n + help + This option enables writing to a apparmorfs node 'disable', which + allows AppArmor to be disabled at runtime prior to the policy load. + AppArmor will then remain disabled until the next boot. + This option is similar to the apparmor.enabled=0 boot parameter, + but is to support runtime disabling of AppArmor, e.g. from + /sbin/init, for portability across platforms where boot + parameters are difficult to employ. + + If you are unsure how to answer this question, answer N. --- linux-2.6.28.orig/security/apparmor/locking.txt +++ linux-2.6.28/security/apparmor/locking.txt @@ -0,0 +1,68 @@ +Locking in AppArmor +=================== + +Lock hierarchy: + + aa_interface_lock + profile_list_lock + aa_profile->lock + task_lock() + + +Which lock protects what? + + /-----------------------+-------------------------------\ + | Variable | Lock | + >-----------------------+-------------------------------< + | profile_list | profile_list_lock | + +-----------------------+-------------------------------+ + | aa_profile | (reference count) | + +-----------------------+-------------------------------+ + | aa_profile-> | aa_profile->lock | + | isstale, | | + | task_contexts | | + +-----------------------+-------------------------------+ + | task_struct->security | read: RCU | + | | write: task_lock() | + +-----------------------+-------------------------------+ + | aa_profile->sub | handle on the profile (list | + | | is never modified) | + \-----------------------+-------------------------------/ + +(Obviously, the list_heads embedded in data structures are always +protected with the lock that also protects the list.) + +When moving a task context from one profile to another, we grab both +profile locks with lock_both_profiles(). This ensures that both locks +are always taken in the same order, and so we won't deadlock. + +Since task_struct->security is RCU protected the aa_task_struct it +references is only guarenteed to exist for the rcu cycle. Where +aa_task_context->profile is needed in blocking operations the +profile's reference count is incremented and the profile reference +is used. + +Profiles on profile_list are never stale: when a profile becomes stale, +it is removed from profile_list at the same time (under profile_list_lock +and aa_profile->lock). + +The aa_interface_lock is taken whenever user-space modifies the profile +list, and can sleep. This ensures that profile loading/replacement/removal +won't race with itself. We release the profile_list_lock as soon as +possible to avoid stalling exec during profile loading/replacement/removal. + +AppArmor uses lock subtyping to avoid false positives from lockdep. The +profile lock is often taken nested, but it is guaranteed to be in a lock +safe order and not the same lock when done, so it is safe. + +A third lock type (aa_lock_task_release) is given to the profile lock +when it is taken in soft irq context during task release (aa_release). +This is to avoid a false positive between the task lock and the profile +lock. In task context the profile lock wraps the task lock with irqs +off, but the kernel takes the task lock with irqs enabled. This won't +result in a deadlock because for a deadlock to occur the kernel must +take dead task A's lock (irqs on), the rcu callback hook freeing +dead task A must be run and AppArmor must be changing the profile on +dead task A. The kernel should not be taking a dead task's task_lock +at the same time the task is being freed by task rcu cleanup other wise +the task would not be out of its quiescent period. --- linux-2.6.28.orig/security/apparmor/lsm.c +++ linux-2.6.28/security/apparmor/lsm.c @@ -0,0 +1,1060 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * 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. + * + * AppArmor LSM interface + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "apparmor.h" +#include "inline.h" + +/* Flag indicating whether initialization completed */ +int apparmor_initialized = 0; + +static int param_set_aabool(const char *val, struct kernel_param *kp); +static int param_get_aabool(char *buffer, struct kernel_param *kp); +#define param_check_aabool(name, p) __param_check(name, p, int) + +static int param_set_aauint(const char *val, struct kernel_param *kp); +static int param_get_aauint(char *buffer, struct kernel_param *kp); +#define param_check_aauint(name, p) __param_check(name, p, int) + +/* Flag values, also controllable via /sys/module/apparmor/parameters + * We define special types as we want to do additional mediation. + * + * Complain mode -- in complain mode access failures result in auditing only + * and task is allowed access. audit events are processed by userspace to + * generate policy. Default is 'enforce' (0). + * Value is also togglable per profile and referenced when global value is + * enforce. + */ +int apparmor_complain = 0; +module_param_named(complain, apparmor_complain, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_complain, "Toggle AppArmor complain mode"); + +/* Debug mode */ +int apparmor_debug = 0; +module_param_named(debug, apparmor_debug, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_debug, "Toggle AppArmor debug mode"); + +/* Audit mode */ +int apparmor_audit = 0; +module_param_named(audit, apparmor_audit, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_audit, "Toggle AppArmor audit mode"); + +/* Syscall logging mode */ +int apparmor_logsyscall = 0; +module_param_named(logsyscall, apparmor_logsyscall, aabool, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_logsyscall, "Toggle AppArmor logsyscall mode"); + +/* Maximum pathname length before accesses will start getting rejected */ +unsigned int apparmor_path_max = 2 * PATH_MAX; +module_param_named(path_max, apparmor_path_max, aauint, S_IRUSR | S_IWUSR); +MODULE_PARM_DESC(apparmor_path_max, "Maximum pathname length allowed"); + +/* Boot time disable flag */ +#ifdef CONFIG_SECURITY_APPARMOR_DISABLE +#define AA_ENABLED_PERMS 0600 +#else +#define AA_ENABLED_PERMS 0400 +#endif +static int param_set_aa_enabled(const char *val, struct kernel_param *kp); +unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE; +module_param_call(enabled, param_set_aa_enabled, param_get_aauint, + &apparmor_enabled, AA_ENABLED_PERMS); +MODULE_PARM_DESC(apparmor_enabled, "Enable/Disable Apparmor on boot"); + +static int __init apparmor_enabled_setup(char *str) +{ + apparmor_enabled = simple_strtol(str, NULL, 0); + return 1; +} +__setup("apparmor=", apparmor_enabled_setup); + +static int param_set_aabool(const char *val, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_set_bool(val, kp); +} + +static int param_get_aabool(char *buffer, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_get_bool(buffer, kp); +} + +static int param_set_aauint(const char *val, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_set_uint(val, kp); +} + +static int param_get_aauint(char *buffer, struct kernel_param *kp) +{ + if (aa_task_context(current)) + return -EPERM; + return param_get_uint(buffer, kp); +} + +/* allow run time disabling of apparmor */ +static int param_set_aa_enabled(const char *val, struct kernel_param *kp) +{ + char *endp; + unsigned long l; + + if (!apparmor_initialized) { + apparmor_enabled = 0; + return 0; + } + + if (aa_task_context(current)) + return -EPERM; + + if (!apparmor_enabled) + return -EINVAL; + + if (!val) + return -EINVAL; + + l = simple_strtoul(val, &endp, 0); + if (endp == val || l != 0) + return -EINVAL; + + apparmor_enabled = 0; + apparmor_disable(); + return 0; +} + +static int aa_reject_syscall(struct task_struct *task, gfp_t flags, + const char *name) +{ + struct aa_profile *profile = aa_get_profile(task); + int error = 0; + + if (profile) { + error = aa_audit_syscallreject(profile, flags, name); + aa_put_profile(profile); + } + + return error; +} + +static int apparmor_ptrace(struct task_struct *tracer, + struct task_struct *tracee) +{ + struct aa_task_context *cxt; + int error = 0; + + /* + * tracer can ptrace tracee when + * - tracer is unconfined + * - tracer & tracee are in the same namespace && + * - tracer is in complain mode + * - tracer and tracee are confined by the same profile + * - tracer profile has CAP_SYS_PTRACE + */ + + rcu_read_lock(); + cxt = aa_task_context(tracer); + if (cxt) { + if (tracer->nsproxy != tracee->nsproxy) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "ptrace"; + sa.gfp_mask = GFP_ATOMIC; + sa.parent = tracer->pid; + sa.task = tracee->pid; + sa.info = "different namespaces"; + aa_audit_reject(cxt->profile, &sa); + error = -EPERM; + } else { + struct aa_task_context *tracee_cxt = + aa_task_context(tracee); + + error = aa_may_ptrace(cxt, tracee_cxt ? + tracee_cxt->profile : NULL); + if (error && PROFILE_COMPLAIN(cxt->profile)) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "ptrace"; + sa.gfp_mask = GFP_ATOMIC; + sa.parent = tracer->pid; + sa.task = tracee->pid; + aa_audit_hint(cxt->profile, &sa); + } + } + } + rcu_read_unlock(); + + return error; +} + +static int apparmor_ptrace_may_access(struct task_struct *child, + unsigned int mode) +{ + return apparmor_ptrace(current, child); +} + + +static int apparmor_ptrace_traceme(struct task_struct *parent) +{ + return apparmor_ptrace(parent, current); +} + +static int apparmor_capable(struct task_struct *task, int cap) +{ + int error; + struct aa_task_context *cxt; + + /* cap_capable returns 0 on success, else -EPERM */ + error = cap_capable(task, cap); + + rcu_read_lock(); + cxt = aa_task_context(task); + if (cxt && (!error || cap_raised(cxt->profile->set_caps, cap))) + error = aa_capability(cxt, cap); + rcu_read_unlock(); + + return error; +} + +static int apparmor_sysctl(struct ctl_table *table, int op) +{ + struct aa_profile *profile = aa_get_profile(current); + int error = 0; + + if (profile) { + char *buffer, *name; + int mask; + + mask = 0; + if (op & 4) + mask |= MAY_READ; + if (op & 2) + mask |= MAY_WRITE; + + error = -ENOMEM; + buffer = (char*)__get_free_page(GFP_KERNEL); + if (!buffer) + goto out; + name = sysctl_pathname(table, buffer, PAGE_SIZE); + if (name && name - buffer >= 5) { + name -= 5; + memcpy(name, "/proc", 5); + error = aa_perm_path(profile, "sysctl", name, mask, 0); + } + free_page((unsigned long)buffer); + } + +out: + aa_put_profile(profile); + return error; +} + +static int apparmor_bprm_set_security(struct linux_binprm *bprm) +{ + /* handle capability bits with setuid, etc */ + cap_bprm_set_security(bprm); + /* already set based on script name */ + if (bprm->sh_bang) + return 0; + return aa_register(bprm); +} + +static int apparmor_bprm_secureexec(struct linux_binprm *bprm) +{ + int ret = cap_bprm_secureexec(bprm); + + if (!ret && (unsigned long)bprm->security & AA_SECURE_EXEC_NEEDED) { + AA_DEBUG("%s: secureexec required for %s\n", + __FUNCTION__, bprm->filename); + ret = 1; + } + + return ret; +} + +static int apparmor_sb_mount(char *dev_name, struct path *path, char *type, + unsigned long flags, void *data) +{ + return aa_reject_syscall(current, GFP_KERNEL, "mount"); +} + +static int apparmor_umount(struct vfsmount *mnt, int flags) +{ + return aa_reject_syscall(current, GFP_KERNEL, "umount"); +} + +static int apparmor_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) +{ + struct aa_profile *profile; + int error = 0; + + if (!mnt || !mediated_filesystem(dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) + error = aa_perm_dir(profile, "inode_mkdir", dentry, mnt, + MAY_WRITE); + + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) +{ + struct aa_profile *profile; + int error = 0; + + if (!mnt || !mediated_filesystem(dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) + error = aa_perm_dir(profile, "inode_rmdir", dentry, mnt, + MAY_WRITE); + + aa_put_profile(profile); + +out: + return error; +} + +static int aa_permission(const char *operation, struct inode *inode, + struct dentry *dentry, struct vfsmount *mnt, + int mask, int check) +{ + int error = 0; + + if (mnt && mediated_filesystem(inode)) { + struct aa_profile *profile; + + profile = aa_get_profile(current); + if (profile) + error = aa_perm(profile, operation, dentry, mnt, mask, + check); + aa_put_profile(profile); + } + return error; +} + +static inline int aa_mask_permissions(int mask) +{ + if (mask & MAY_APPEND) + mask &= (MAY_READ | MAY_APPEND | MAY_EXEC); + else + mask &= (MAY_READ | MAY_WRITE | MAY_EXEC); + return mask; +} + +static int apparmor_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mask) +{ + return aa_permission("inode_create", dir, dentry, mnt, MAY_APPEND, 0); +} + +static int apparmor_inode_link(struct dentry *old_dentry, + struct vfsmount *old_mnt, struct inode *dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) +{ + int error = 0; + struct aa_profile *profile; + + if (!old_mnt || !new_mnt || !mediated_filesystem(dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) + error = aa_link(profile, new_dentry, new_mnt, + old_dentry, old_mnt); + + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) +{ + int check = 0; + + if (S_ISDIR(dentry->d_inode->i_mode)) + check |= AA_CHECK_DIR; + return aa_permission("inode_unlink", dir, dentry, mnt, MAY_WRITE, + check); +} + +static int apparmor_inode_symlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *old_name) +{ + return aa_permission("inode_symlink", dir, dentry, mnt, MAY_WRITE, 0); +} + +static int apparmor_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) +{ + return aa_permission("inode_mknod", dir, dentry, mnt, MAY_WRITE, 0); +} + +static int apparmor_inode_rename(struct inode *old_dir, + struct dentry *old_dentry, + struct vfsmount *old_mnt, + struct inode *new_dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) +{ + struct aa_profile *profile; + int error = 0; + + if ((!old_mnt && !new_mnt) || !mediated_filesystem(old_dir)) + goto out; + + profile = aa_get_profile(current); + + if (profile) { + struct inode *inode = old_dentry->d_inode; + int check = 0; + + if (inode && S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + if (old_mnt) + error = aa_perm(profile, "inode_rename", old_dentry, + old_mnt, MAY_READ | MAY_WRITE, check); + + if (!error && new_mnt) { + error = aa_perm(profile, "inode_rename", new_dentry, + new_mnt, MAY_WRITE, check); + } + } + + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_inode_permission(struct inode *inode, int mask) +{ + return 0; +} + +static int apparmor_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) +{ + int error = 0; + + if (!mnt) + goto out; + + if (mediated_filesystem(dentry->d_inode)) { + struct aa_profile *profile; + + profile = aa_get_profile(current); + /* + * Mediate any attempt to change attributes of a file + * (chmod, chown, chgrp, etc) + */ + if (profile) + error = aa_attr(profile, dentry, mnt, iattr); + + aa_put_profile(profile); + } + +out: + return error; +} + +static int aa_xattr_permission(struct dentry *dentry, struct vfsmount *mnt, + const char *operation, int mask, + struct file *file) +{ + int error = 0; + + if (mnt && mediated_filesystem(dentry->d_inode)) { + struct aa_profile *profile = aa_get_profile(current); + int check = file ? AA_CHECK_FD : 0; + + if (profile) + error = aa_perm_xattr(profile, operation, dentry, mnt, + mask, check); + aa_put_profile(profile); + } + + return error; +} + +static int apparmor_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file) +{ + int error = cap_inode_setxattr(dentry, mnt, name, value, size, flags, + file); + + if (!error) + error = aa_xattr_permission(dentry, mnt, "xattr set", + MAY_WRITE, file); + return error; +} + +static int apparmor_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) +{ + return aa_xattr_permission(dentry, mnt, "xattr get", MAY_READ, file); +} + +static int apparmor_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file) +{ + return aa_xattr_permission(dentry, mnt, "xattr list", MAY_READ, file); +} + +static int apparmor_inode_removexattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, + struct file *file) +{ + return aa_xattr_permission(dentry, mnt, "xattr remove", MAY_WRITE, + file); +} + +static int aa_file_permission(const char *op, struct file *file, int mask) +{ + struct aa_profile *profile; + struct aa_profile *file_profile = (struct aa_profile*)file->f_security; + int error = 0; + + if (!file_profile) + goto out; + + /* + * If this file was opened under a different profile, we + * revalidate the access against the current profile. + */ + profile = aa_get_profile(current); + if (profile && (file_profile != profile || mask & AA_MAY_LOCK)) { + struct dentry *dentry = file->f_dentry; + struct vfsmount *mnt = file->f_vfsmnt; + struct inode *inode = dentry->d_inode; + int check = AA_CHECK_FD; + + /* + * FIXME: We should remember which profiles we revalidated + * against. + */ + if (S_ISDIR(inode->i_mode)) + check |= AA_CHECK_DIR; + error = aa_permission(op, inode, dentry, mnt, mask, check); + } + aa_put_profile(profile); + +out: + return error; +} + +static int apparmor_file_permission(struct file *file, int mask) +{ + return aa_file_permission("file_permission", file, + aa_mask_permissions(mask)); +} + +static inline int apparmor_file_lock (struct file *file, unsigned int cmd) +{ + int mask = AA_MAY_LOCK; + if (cmd == F_WRLCK) + mask |= MAY_WRITE; + return aa_file_permission("file_lock", file, mask); +} + +static int apparmor_file_alloc_security(struct file *file) +{ + struct aa_profile *profile; + + profile = aa_get_profile(current); + if (profile) + file->f_security = profile; + + return 0; +} + +static void apparmor_file_free_security(struct file *file) +{ + struct aa_profile *file_profile = (struct aa_profile*)file->f_security; + + aa_put_profile(file_profile); +} + +static inline int aa_mmap(struct file *file, const char *operation, + unsigned long prot, unsigned long flags) +{ + struct dentry *dentry; + int mask = 0; + + if (!file || !file->f_security) + return 0; + + if (prot & PROT_READ) + mask |= MAY_READ; + /* Private mappings don't require write perms since they don't + * write back to the files */ + if ((prot & PROT_WRITE) && !(flags & MAP_PRIVATE)) + mask |= MAY_WRITE; + if (prot & PROT_EXEC) + mask |= AA_EXEC_MMAP; + + dentry = file->f_dentry; + return aa_permission(operation, dentry->d_inode, dentry, + file->f_vfsmnt, mask, AA_CHECK_FD); +} + +static int apparmor_file_mmap(struct file *file, unsigned long reqprot, + unsigned long prot, unsigned long flags, + unsigned long addr, unsigned long addr_only) +{ + if ((addr < mmap_min_addr) && !capable(CAP_SYS_RAWIO)) { + struct aa_profile *profile = aa_get_profile(current); + if (profile) + /* future control check here */ + return -EACCES; + else + return -EACCES; + aa_put_profile(profile); + } + + return aa_mmap(file, "file_mmap", prot, flags); +} + +static int apparmor_file_mprotect(struct vm_area_struct *vma, + unsigned long reqprot, unsigned long prot) +{ + return aa_mmap(vma->vm_file, "file_mprotect", prot, + !(vma->vm_flags & VM_SHARED) ? MAP_PRIVATE : 0); +} + +static int apparmor_path_permission(struct path *path, int mask) +{ + struct inode *inode; + int check = 0; + + if (!path) + return 0; + + inode = path->dentry->d_inode; + + mask = aa_mask_permissions(mask); + if (S_ISDIR(inode->i_mode)) { + check |= AA_CHECK_DIR; + /* allow traverse accesses to directories */ + mask &= ~MAY_EXEC; + if (!mask) + return 0; + } + + return aa_permission("inode_permission", inode, path->dentry, + path->mnt, mask, check); +} + +static int apparmor_task_alloc_security(struct task_struct *task) +{ + return aa_clone(task); +} + +/* + * Called from IRQ context from RCU callback. + */ +static void apparmor_task_free_security(struct task_struct *task) +{ + aa_release(task); +} + +static int apparmor_socket_create(int family, int type, int protocol, int kern) +{ + struct aa_profile *profile; + int error = 0; + + if (kern) + return 0; + + profile = aa_get_profile(current); + if (profile) + error = aa_net_perm(profile, "socket_create", family, + type, protocol); + aa_put_profile(profile); + + return error; +} + +static int apparmor_socket_post_create(struct socket *sock, int family, + int type, int protocol, int kern) +{ + struct sock *sk = sock->sk; + + if (kern) + return 0; + + return aa_revalidate_sk(sk, "socket_post_create"); +} + +static int apparmor_socket_bind(struct socket *sock, + struct sockaddr *address, int addrlen) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_bind"); +} + +static int apparmor_socket_connect(struct socket *sock, + struct sockaddr *address, int addrlen) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_connect"); +} + +static int apparmor_socket_listen(struct socket *sock, int backlog) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_listen"); +} + +static int apparmor_socket_accept(struct socket *sock, struct socket *newsock) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_accept"); +} + +static int apparmor_socket_sendmsg(struct socket *sock, + struct msghdr *msg, int size) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_sendmsg"); +} + +static int apparmor_socket_recvmsg(struct socket *sock, + struct msghdr *msg, int size, int flags) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_recvmsg"); +} + +static int apparmor_socket_getsockname(struct socket *sock) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_getsockname"); +} + +static int apparmor_socket_getpeername(struct socket *sock) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_getpeername"); +} + +static int apparmor_socket_getsockopt(struct socket *sock, int level, + int optname) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_getsockopt"); +} + +static int apparmor_socket_setsockopt(struct socket *sock, int level, + int optname) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_setsockopt"); +} + +static int apparmor_socket_shutdown(struct socket *sock, int how) +{ + struct sock *sk = sock->sk; + + return aa_revalidate_sk(sk, "socket_shutdown"); +} + +static int apparmor_getprocattr(struct task_struct *task, char *name, + char **value) +{ + unsigned len; + int error; + struct aa_profile *profile; + + /* AppArmor only supports the "current" process attribute */ + if (strcmp(name, "current") != 0) + return -EINVAL; + + /* must be task querying itself or admin */ + if (current != task && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + profile = aa_get_profile(task); + error = aa_getprocattr(profile, value, &len); + aa_put_profile(profile); + if (!error) + error = len; + + return error; +} + +static int apparmor_setprocattr(struct task_struct *task, char *name, + void *value, size_t size) +{ + char *command, *args; + int error; + + if (strcmp(name, "current") != 0 || size == 0 || size >= PAGE_SIZE) + return -EINVAL; + args = value; + args[size] = '\0'; + args = strstrip(args); + command = strsep(&args, " "); + if (!args) + return -EINVAL; + while (isspace(*args)) + args++; + if (!*args) + return -EINVAL; + + if (strcmp(command, "changehat") == 0) { + if (current != task) + return -EACCES; + error = aa_setprocattr_changehat(args); + } else if (strcmp(command, "changeprofile") == 0) { + if (current != task) + return -EACCES; + error = aa_setprocattr_changeprofile(args); + } else if (strcmp(command, "setprofile") == 0) { + struct aa_profile *profile; + + /* Only an unconfined process with admin capabilities + * may change the profile of another task. + */ + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + profile = aa_get_profile(current); + if (profile) { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_set"; + sa.gfp_mask = GFP_KERNEL; + sa.task = task->pid; + sa.info = "from confined process"; + aa_audit_reject(profile, &sa); + aa_put_profile(profile); + return -EACCES; + } + error = aa_setprocattr_setprofile(task, args); + } else { + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "setprocattr"; + sa.gfp_mask = GFP_KERNEL; + sa.info = "invalid command"; + sa.name = command; + sa.task = task->pid; + aa_audit_reject(NULL, &sa); + return -EINVAL; + } + + if (!error) + error = size; + return error; +} + +static int apparmor_task_setrlimit(unsigned int resource, + struct rlimit *new_rlim) +{ + struct aa_profile *profile; + int error = 0; + + profile = aa_get_profile(current); + if (profile) { + error = aa_task_setrlimit(profile, resource, new_rlim); + } + aa_put_profile(profile); + + return error; +} + +struct security_operations apparmor_ops = { + .ptrace_may_access = apparmor_ptrace_may_access, + .ptrace_traceme = apparmor_ptrace_traceme, + .capget = cap_capget, + .capset_check = cap_capset_check, + .capset_set = cap_capset_set, + .sysctl = apparmor_sysctl, + .capable = apparmor_capable, + .syslog = cap_syslog, + + .bprm_apply_creds = cap_bprm_apply_creds, + .bprm_set_security = apparmor_bprm_set_security, + .bprm_secureexec = apparmor_bprm_secureexec, + + .sb_mount = apparmor_sb_mount, + .sb_umount = apparmor_umount, + + .inode_mkdir = apparmor_inode_mkdir, + .inode_rmdir = apparmor_inode_rmdir, + .inode_create = apparmor_inode_create, + .inode_link = apparmor_inode_link, + .inode_unlink = apparmor_inode_unlink, + .inode_symlink = apparmor_inode_symlink, + .inode_mknod = apparmor_inode_mknod, + .inode_rename = apparmor_inode_rename, + .inode_permission = apparmor_inode_permission, + .inode_setattr = apparmor_inode_setattr, + .inode_setxattr = apparmor_inode_setxattr, + .inode_getxattr = apparmor_inode_getxattr, + .inode_listxattr = apparmor_inode_listxattr, + .inode_removexattr = apparmor_inode_removexattr, + .file_permission = apparmor_file_permission, + .file_alloc_security = apparmor_file_alloc_security, + .file_free_security = apparmor_file_free_security, + .file_mmap = apparmor_file_mmap, + .file_mprotect = apparmor_file_mprotect, + .file_lock = apparmor_file_lock, + + .path_permission = apparmor_path_permission, + + .task_alloc_security = apparmor_task_alloc_security, + .task_free_security = apparmor_task_free_security, + .task_post_setuid = cap_task_post_setuid, + .task_reparent_to_init = cap_task_reparent_to_init, + .task_setrlimit = apparmor_task_setrlimit, + + .getprocattr = apparmor_getprocattr, + .setprocattr = apparmor_setprocattr, + + .socket_create = apparmor_socket_create, + .socket_post_create = apparmor_socket_post_create, + .socket_bind = apparmor_socket_bind, + .socket_connect = apparmor_socket_connect, + .socket_listen = apparmor_socket_listen, + .socket_accept = apparmor_socket_accept, + .socket_sendmsg = apparmor_socket_sendmsg, + .socket_recvmsg = apparmor_socket_recvmsg, + .socket_getsockname = apparmor_socket_getsockname, + .socket_getpeername = apparmor_socket_getpeername, + .socket_getsockopt = apparmor_socket_getsockopt, + .socket_setsockopt = apparmor_socket_setsockopt, + .socket_shutdown = apparmor_socket_shutdown, +}; + +void info_message(const char *str) +{ + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.gfp_mask = GFP_KERNEL; + sa.info = str; + printk(KERN_INFO "AppArmor: %s\n", str); + if (audit_enabled) + aa_audit_message(NULL, &sa, AUDIT_APPARMOR_STATUS); +} + +static int __init apparmor_init(void) +{ + int error; + + if (!apparmor_enabled) { + info_message("AppArmor disabled by boottime parameter\n"); + return 0; + } + + if ((error = create_apparmorfs())) { + AA_ERROR("Unable to activate AppArmor filesystem\n"); + goto createfs_out; + } + + if ((error = alloc_default_namespace())){ + AA_ERROR("Unable to allocate default profile namespace\n"); + goto alloc_out; + } + + if ((error = register_security(&apparmor_ops))) { + AA_ERROR("Unable to register AppArmor\n"); + goto register_security_out; + } + + /* Report that AppArmor successfully initialized */ + apparmor_initialized = 1; + if (apparmor_complain) + info_message("AppArmor initialized: complainmode enabled"); + else + info_message("AppArmor initialized"); + + return error; + +register_security_out: + free_default_namespace(); + +alloc_out: + destroy_apparmorfs(); + +createfs_out: + return error; + +} + +security_initcall(apparmor_init); + +void apparmor_disable(void) +{ + /* Remove and release all the profiles on the profile list. */ + mutex_lock(&aa_interface_lock); + aa_profile_ns_list_release(); + + /* FIXME: cleanup profiles references on files */ + free_default_namespace(); + + /* + * Delay for an rcu cycle to make sure that all active task + * context readers have finished, and all profiles have been + * freed by their rcu callbacks. + */ + synchronize_rcu(); + + destroy_apparmorfs(); + mutex_unlock(&aa_interface_lock); + + apparmor_initialized = 0; + + info_message("AppArmor protection removed"); +} + +MODULE_DESCRIPTION("AppArmor process confinement"); +MODULE_AUTHOR("Novell/Immunix, http://bugs.opensuse.org"); +MODULE_LICENSE("GPL"); --- linux-2.6.28.orig/security/apparmor/Makefile +++ linux-2.6.28/security/apparmor/Makefile @@ -0,0 +1,18 @@ +# Makefile for AppArmor Linux Security Module +# +obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o + +apparmor-y := main.o list.o procattr.o lsm.o apparmorfs.o \ + module_interface.o match.o + +quiet_cmd_make-caps = GEN $@ +cmd_make-caps = sed -n -e "/CAP_FS_MASK/d" -e "s/^\#define[ \\t]\\+CAP_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@ + +quiet_cmd_make-af = GEN $@ +cmd_make-af = sed -n -e "/AF_MAX/d" -e "/AF_LOCAL/d" -e "s/^\#define[ \\t]\\+AF_\\([A-Z0-9_]\\+\\)[ \\t]\\+\\([0-9]\\+\\)\\(.*\\)\$$/[\\2] = \"\\1\",/p" $< | tr A-Z a-z > $@ + +$(obj)/main.o : $(obj)/capability_names.h $(obj)/af_names.h +$(obj)/capability_names.h : $(srctree)/include/linux/capability.h + $(call cmd,make-caps) +$(obj)/af_names.h : $(srctree)/include/linux/socket.h + $(call cmd,make-af) --- linux-2.6.28.orig/security/apparmor/match.h +++ linux-2.6.28/security/apparmor/match.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2007 Novell/SUSE + * + * 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. + * + * AppArmor submodule (match) prototypes + */ + +#ifndef __MATCH_H +#define __MATCH_H + +#define DFA_START 1 + +/** + * The format used for transition tables is based on the GNU flex table + * file format (--tables-file option; see Table File Format in the flex + * info pages and the flex sources for documentation). The magic number + * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because + * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used + * slightly differently (see the apparmor-parser package). + */ + +#define YYTH_MAGIC 0x1B5E783D + +struct table_set_header { + u32 th_magic; /* YYTH_MAGIC */ + u32 th_hsize; + u32 th_ssize; + u16 th_flags; + char th_version[]; +}; + +#define YYTD_ID_ACCEPT 1 +#define YYTD_ID_BASE 2 +#define YYTD_ID_CHK 3 +#define YYTD_ID_DEF 4 +#define YYTD_ID_EC 5 +#define YYTD_ID_META 6 +#define YYTD_ID_ACCEPT2 7 +#define YYTD_ID_NXT 8 + + +#define YYTD_DATA8 1 +#define YYTD_DATA16 2 +#define YYTD_DATA32 4 + +struct table_header { + u16 td_id; + u16 td_flags; + u32 td_hilen; + u32 td_lolen; + char td_data[]; +}; + +#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF - 1]->td_data)) +#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE - 1]->td_data)) +#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT - 1]->td_data)) +#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data)) +#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data)) +#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data)) +#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2 -1]->td_data)) + +struct aa_dfa { + struct table_header *tables[YYTD_ID_NXT]; +}; + +#define byte_to_byte(X) (X) + +#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \ + do { \ + typeof(LEN) __i; \ + TYPE *__t = (TYPE *) TABLE; \ + TYPE *__b = (TYPE *) BLOB; \ + for (__i = 0; __i < LEN; __i++) { \ + __t[__i] = NTOHX(__b[__i]); \ + } \ + } while (0) + +static inline size_t table_size(size_t len, size_t el_size) +{ + return ALIGN(sizeof(struct table_header) + len * el_size, 8); +} + +#endif /* __MATCH_H */ --- linux-2.6.28.orig/security/apparmor/list.c +++ linux-2.6.28/security/apparmor/list.c @@ -0,0 +1,174 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * 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. + * + * AppArmor Profile List Management + */ + +#include +#include "apparmor.h" +#include "inline.h" + +/* list of profile namespaces and lock */ +LIST_HEAD(profile_ns_list); +rwlock_t profile_ns_list_lock = RW_LOCK_UNLOCKED; + +/** + * __aa_find_namespace - look up a profile namespace on the namespace list + * @name: name of namespace to find + * @head: list to search + * + * Returns a pointer to the namespace on the list, or NULL if no namespace + * called @name exists. The caller must hold the profile_ns_list_lock. + */ +struct aa_namespace *__aa_find_namespace(const char *name, + struct list_head *head) +{ + struct aa_namespace *ns; + + list_for_each_entry(ns, head, list) { + if (!strcmp(ns->name, name)) + return ns; + } + + return NULL; +} + +/** + * __aa_find_profile - look up a profile on the profile list + * @name: name of profile to find + * @head: list to search + * + * Returns a pointer to the profile on the list, or NULL if no profile + * called @name exists. The caller must hold the profile_list_lock. + */ +struct aa_profile *__aa_find_profile(const char *name, struct list_head *head) +{ + struct aa_profile *profile; + + list_for_each_entry(profile, head, list) { + if (!strcmp(profile->name, name)) + return profile; + } + + return NULL; +} + +static void aa_profile_list_release(struct list_head *head) +{ + struct aa_profile *profile, *tmp; + list_for_each_entry_safe(profile, tmp, head, list) { + /* Remove the profile from each task context it is on. */ + lock_profile(profile); + profile->isstale = 1; + aa_unconfine_tasks(profile); + list_del_init(&profile->list); + unlock_profile(profile); + aa_put_profile(profile); + } +} + +/** + * aa_profilelist_release - Remove all profiles from profile_list + */ +void aa_profile_ns_list_release(void) +{ + struct aa_namespace *ns, *tmp; + + /* Remove and release all the profiles on namespace profile lists. */ + write_lock(&profile_ns_list_lock); + list_for_each_entry_safe(ns, tmp, &profile_ns_list, list) { + write_lock(&ns->lock); + aa_profile_list_release(&ns->profiles); + list_del_init(&ns->list); + write_unlock(&ns->lock); + aa_put_namespace(ns); + } + write_unlock(&profile_ns_list_lock); +} + + +static struct aa_profile *next_profile(struct aa_profile *profile) +{ + struct aa_profile *next = profile; + struct aa_namespace *ns; + + list_for_each_entry_continue(next, &profile->ns->profiles, list) + return next; + + ns = profile->ns; + read_unlock(&ns->lock); + list_for_each_entry_continue(ns, &profile_ns_list, list) { + read_lock(&ns->lock); + list_for_each_entry(profile, &ns->profiles, list) + return profile; + read_unlock(&ns->lock); + } + return NULL; +} + +static void *p_start(struct seq_file *f, loff_t *pos) +{ + struct aa_namespace *ns; + loff_t l = *pos; + + read_lock(&profile_ns_list_lock); + if (!list_empty(&profile_ns_list)) { + struct aa_profile *profile = NULL; + ns = list_first_entry(&profile_ns_list, typeof(*ns), list); + read_lock(&ns->lock); + if (!list_empty(&ns->profiles)) + profile = list_first_entry(&ns->profiles, + typeof(*profile), list); + else + read_unlock(&ns->lock); + for ( ; profile && l > 0; l--) + profile = next_profile(profile); + return profile; + } + return NULL; +} + +static void *p_next(struct seq_file *f, void *p, loff_t *pos) +{ + struct aa_profile *profile = (struct aa_profile *) p; + + (*pos)++; + profile = next_profile(profile); + + return profile; +} + +static void p_stop(struct seq_file *f, void *p) +{ + struct aa_profile *profile = (struct aa_profile *) p; + + if (profile) + read_unlock(&profile->ns->lock); + read_unlock(&profile_ns_list_lock); +} + +static int seq_show_profile(struct seq_file *f, void *p) +{ + struct aa_profile *profile = (struct aa_profile *)p; + + if (profile->ns == default_namespace) + seq_printf(f, "%s (%s)\n", profile->name, + PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); + else + seq_printf(f, ":%s:%s (%s)\n", profile->ns->name, profile->name, + PROFILE_COMPLAIN(profile) ? "complain" : "enforce"); + return 0; +} + +/* Used in apparmorfs.c */ +struct seq_operations apparmorfs_profiles_op = { + .start = p_start, + .next = p_next, + .stop = p_stop, + .show = seq_show_profile, +}; --- linux-2.6.28.orig/security/apparmor/match.c +++ linux-2.6.28/security/apparmor/match.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2007 Novell/SUSE + * + * 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. + * + * Regular expression transition table matching + */ + +#include +#include +#include +#include "apparmor.h" +#include "match.h" +#include "inline.h" + +static struct table_header *unpack_table(void *blob, size_t bsize) +{ + struct table_header *table = NULL; + struct table_header th; + size_t tsize; + + if (bsize < sizeof(struct table_header)) + goto out; + + th.td_id = be16_to_cpu(*(u16 *) (blob)); + th.td_flags = be16_to_cpu(*(u16 *) (blob + 2)); + th.td_lolen = be32_to_cpu(*(u32 *) (blob + 8)); + blob += sizeof(struct table_header); + + if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 || + th.td_flags == YYTD_DATA8)) + goto out; + + tsize = table_size(th.td_lolen, th.td_flags); + if (bsize < tsize) + goto out; + + table = kmalloc(tsize, GFP_KERNEL); + if (table) { + *table = th; + if (th.td_flags == YYTD_DATA8) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, + u8, byte_to_byte); + else if (th.td_flags == YYTD_DATA16) + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, + u16, be16_to_cpu); + else + UNPACK_ARRAY(table->td_data, blob, th.td_lolen, + u32, be32_to_cpu); + } + +out: + return table; +} + +int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size) +{ + int hsize, i; + int error = -ENOMEM; + + /* get dfa table set header */ + if (size < sizeof(struct table_set_header)) + goto fail; + + if (ntohl(*(u32 *)blob) != YYTH_MAGIC) + goto fail; + + hsize = ntohl(*(u32 *)(blob + 4)); + if (size < hsize) + goto fail; + + blob += hsize; + size -= hsize; + + error = -EPROTO; + while (size > 0) { + struct table_header *table; + table = unpack_table(blob, size); + if (!table) + goto fail; + + switch(table->td_id) { + case YYTD_ID_ACCEPT: + case YYTD_ID_ACCEPT2: + case YYTD_ID_BASE: + dfa->tables[table->td_id - 1] = table; + if (table->td_flags != YYTD_DATA32) + goto fail; + break; + case YYTD_ID_DEF: + case YYTD_ID_NXT: + case YYTD_ID_CHK: + dfa->tables[table->td_id - 1] = table; + if (table->td_flags != YYTD_DATA16) + goto fail; + break; + case YYTD_ID_EC: + dfa->tables[table->td_id - 1] = table; + if (table->td_flags != YYTD_DATA8) + goto fail; + break; + default: + kfree(table); + goto fail; + } + + blob += table_size(table->td_lolen, table->td_flags); + size -= table_size(table->td_lolen, table->td_flags); + } + + return 0; + +fail: + for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) { + if (dfa->tables[i]) { + kfree(dfa->tables[i]); + dfa->tables[i] = NULL; + } + } + return error; +} + +/** + * verify_dfa - verify that all the transitions and states in the dfa tables + * are in bounds. + * @dfa: dfa to test + * + * assumes dfa has gone through the verification done by unpacking + */ +int verify_dfa(struct aa_dfa *dfa) +{ + size_t i, state_count, trans_count; + int error = -EPROTO; + + /* check that required tables exist */ + if (!(dfa->tables[YYTD_ID_ACCEPT - 1] && + dfa->tables[YYTD_ID_ACCEPT2 - 1] && + dfa->tables[YYTD_ID_DEF - 1] && + dfa->tables[YYTD_ID_BASE - 1] && + dfa->tables[YYTD_ID_NXT - 1] && + dfa->tables[YYTD_ID_CHK - 1])) + goto out; + + /* accept.size == default.size == base.size */ + state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen; + if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen && + state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen && + state_count == dfa->tables[YYTD_ID_ACCEPT2 - 1]->td_lolen)) + goto out; + + /* next.size == chk.size */ + trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen; + if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen) + goto out; + + /* if equivalence classes then its table size must be 256 */ + if (dfa->tables[YYTD_ID_EC - 1] && + dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256) + goto out; + + for (i = 0; i < state_count; i++) { + if (DEFAULT_TABLE(dfa)[i] >= state_count) + goto out; + if (BASE_TABLE(dfa)[i] >= trans_count + 256) + goto out; + } + + for (i = 0; i < trans_count ; i++) { + if (NEXT_TABLE(dfa)[i] >= state_count) + goto out; + if (CHECK_TABLE(dfa)[i] >= state_count) + goto out; + } + + /* verify accept permissions */ + for (i = 0; i < state_count; i++) { + int mode = ACCEPT_TABLE(dfa)[i]; + + if (mode & ~AA_VALID_PERM_MASK) + goto out; + if (ACCEPT_TABLE2(dfa)[i] & ~AA_VALID_PERM2_MASK) + goto out; + + /* if any exec modifier is set MAY_EXEC must be set */ + if ((mode & AA_USER_EXEC_TYPE) && !(mode & AA_USER_EXEC)) + goto out; + if ((mode & AA_OTHER_EXEC_TYPE) && !(mode & AA_OTHER_EXEC)) + goto out; + } + + error = 0; +out: + return error; +} + +struct aa_dfa *aa_match_alloc(void) +{ + return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL); +} + +void aa_match_free(struct aa_dfa *dfa) +{ + if (dfa) { + int i; + + for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) + kfree(dfa->tables[i]); + } + kfree(dfa); +} + +/** + * aa_dfa_next_state_len - traverse @dfa to find state @str stops at + * @dfa: the dfa to match @str against + * @start: the state of the dfa to start matching in + * @str: the string of bytes to match against the dfa + * @len: length of the string of bytes to match + * + * aa_dfa_next_state will match @str against the dfa and return the state it + * finished matching in. The final state can be used to look up the accepting + * label, or as the start state of a continuing match. + * + * aa_dfa_next_state could be implement using this function by doing + * return aa_dfa_next_state_len(dfa, start, str, strlen(str)); + * but that would require traversing the string twice and be slightly + * slower. + */ +unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa, unsigned int start, + const char *str, int len) +{ + u16 *def = DEFAULT_TABLE(dfa); + u32 *base = BASE_TABLE(dfa); + u16 *next = NEXT_TABLE(dfa); + u16 *check = CHECK_TABLE(dfa); + unsigned int state = start, pos; + + if (state == 0) + return 0; + + /* current state is , matching character *str */ + if (dfa->tables[YYTD_ID_EC - 1]) { + u8 *equiv = EQUIV_TABLE(dfa); + for (; len; len--) { + pos = base[state] + equiv[(u8)*str++]; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } else { + for (; len; len--) { + pos = base[state] + (u8)*str++; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } + return state; +} + +/** + * aa_dfa_next_state - traverse @dfa to find state @str stops at + * @dfa: the dfa to match @str against + * @start: the state of the dfa to start matching in + * @str: the null terminated string of bytes to match against the dfa + * + * aa_dfa_next_state will match @str against the dfa and return the state it + * finished matching in. The final state can be used to look up the accepting + * label, or as the start state of a continuing match. + */ +unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, + const char *str) +{ + u16 *def = DEFAULT_TABLE(dfa); + u32 *base = BASE_TABLE(dfa); + u16 *next = NEXT_TABLE(dfa); + u16 *check = CHECK_TABLE(dfa); + unsigned int state = start, pos; + + if (state == 0) + return 0; + + /* current state is , matching character *str */ + if (dfa->tables[YYTD_ID_EC - 1]) { + u8 *equiv = EQUIV_TABLE(dfa); + while (*str) { + pos = base[state] + equiv[(u8)*str++]; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } else { + while (*str) { + pos = base[state] + (u8)*str++; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } + return state; +} + +/** + * aa_dfa_null_transition - step to next state after null character + * @dfa: the dfa to match against + * @start: the state of the dfa to start matching in + * + * aa_dfa_null_transition transitions to the next state after a null + * character which is not used in standard matching and is only + * used to seperate pairs. + */ +unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) +{ + return aa_dfa_next_state_len(dfa, start, "", 1); +} + +/** + * aa_dfa_match - find accept perm for @str in @dfa + * @dfa: the dfa to match @str against + * @str: the string to match against the dfa + * @audit_mask: the audit_mask for the final state + * + * aa_dfa_match will match @str and return the accept perms for the + * final state. + */ +unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *audit_mask) +{ + int state = aa_dfa_next_state(dfa, DFA_START, str); + if (audit_mask) + *audit_mask = dfa_audit_mask(dfa, state); + return ACCEPT_TABLE(dfa)[state]; +} + +/** + * aa_match_state - find accept perm and state for @str in @dfa + * @dfa: the dfa to match @str against + * @start: the state to start the match from + * @str: the string to match against the dfa + * @final: the state that the match finished in + * + * aa_match_state will match @str and return the accept perms, and @final + * state, the match occured in. + */ +unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, + const char *str, unsigned int *final) +{ + unsigned int state; + if (dfa) { + state = aa_dfa_next_state(dfa, start, str); + if (final) + *final = state; + return ACCEPT_TABLE(dfa)[state]; + } + if (final) + *final = 0; + return 0; +} + --- linux-2.6.28.orig/security/apparmor/apparmor.h +++ linux-2.6.28/security/apparmor/apparmor.h @@ -0,0 +1,403 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * 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. + * + * AppArmor internal prototypes + */ + +#ifndef __APPARMOR_H +#define __APPARMOR_H + +#include +#include +#include +#include +#include +#include +#include + +/* + * We use MAY_READ, MAY_WRITE, MAY_EXEC, MAY_APPEND and the following flags + * for profile permissions + */ +#define AA_MAY_LINK 0x0010 +#define AA_MAY_LOCK 0x0020 +#define AA_EXEC_MMAP 0x0040 +#define AA_MAY_MOUNT 0x0080 /* no direct audit mapping */ +#define AA_EXEC_UNSAFE 0x0100 +#define AA_EXEC_INHERIT 0x0200 +#define AA_EXEC_MOD_0 0x0400 +#define AA_EXEC_MOD_1 0x0800 +#define AA_EXEC_MOD_2 0x1000 +#define AA_EXEC_MOD_3 0x2000 + +#define AA_BASE_PERMS (MAY_READ | MAY_WRITE | MAY_EXEC | \ + MAY_APPEND | AA_MAY_LINK | \ + AA_MAY_LOCK | AA_EXEC_MMAP | \ + AA_MAY_MOUNT | AA_EXEC_UNSAFE | \ + AA_EXEC_INHERIT | AA_EXEC_MOD_0 | \ + AA_EXEC_MOD_1 | AA_EXEC_MOD_2 | \ + AA_EXEC_MOD_3) + +#define AA_EXEC_MODIFIERS (AA_EXEC_MOD_0 | AA_EXEC_MOD_1 | \ + AA_EXEC_MOD_2 | AA_EXEC_MOD_3) + +#define AA_EXEC_TYPE (AA_EXEC_UNSAFE | AA_EXEC_INHERIT | \ + AA_EXEC_MODIFIERS) + +#define AA_EXEC_UNCONFINED AA_EXEC_MOD_0 +#define AA_EXEC_PROFILE AA_EXEC_MOD_1 +#define AA_EXEC_CHILD (AA_EXEC_MOD_0 | AA_EXEC_MOD_1) +/* remaining exec modes are index into profile name table */ +#define AA_EXEC_INDEX(mode) ((mode & AA_EXEC_MODIFIERS) >> 10) + +#define AA_USER_SHIFT 0 +#define AA_OTHER_SHIFT 14 + +#define AA_USER_PERMS (AA_BASE_PERMS << AA_USER_SHIFT) +#define AA_OTHER_PERMS (AA_BASE_PERMS << AA_OTHER_SHIFT) + +#define AA_FILE_PERMS (AA_USER_PERMS | AA_OTHER_PERMS) + +#define AA_LINK_BITS ((AA_MAY_LINK << AA_USER_SHIFT) | \ + (AA_MAY_LINK << AA_OTHER_SHIFT)) + +#define AA_USER_EXEC (MAY_EXEC << AA_USER_SHIFT) +#define AA_OTHER_EXEC (MAY_EXEC << AA_OTHER_SHIFT) + +#define AA_USER_EXEC_TYPE (AA_EXEC_TYPE << AA_USER_SHIFT) +#define AA_OTHER_EXEC_TYPE (AA_EXEC_TYPE << AA_OTHER_SHIFT) + +#define AA_EXEC_BITS (AA_USER_EXEC | AA_OTHER_EXEC) + +#define ALL_AA_EXEC_UNSAFE ((AA_EXEC_UNSAFE << AA_USER_SHIFT) | \ + (AA_EXEC_UNSAFE << AA_OTHER_SHIFT)) + +#define ALL_AA_EXEC_TYPE (AA_USER_EXEC_TYPE | AA_OTHER_EXEC_TYPE) + +/* overloaded permissions for link pairs */ +#define AA_LINK_SUBSET_TEST 0x0020 + +#define AA_USER_PTRACE 0x10000000 +#define AA_OTHER_PTRACE 0x20000000 +#define AA_PTRACE_PERMS (AA_USER_PTRACE | AA_OTHER_PTRACE) + +/* shared permissions that are not duplicated in user::other */ +#define AA_CHANGE_HAT 0x40000000 +#define AA_CHANGE_PROFILE 0x80000000 + +#define AA_SHARED_PERMS (AA_CHANGE_HAT | AA_CHANGE_PROFILE) + +#define AA_VALID_PERM_MASK (AA_FILE_PERMS | AA_PTRACE_PERMS | \ + AA_SHARED_PERMS) + +/* audit bits for the second accept field */ +#define AUDIT_FILE_MASK 0x1fc07f +#define AUDIT_QUIET_MASK(mask) ((mask >> 7) & AUDIT_FILE_MASK) +#define AA_VALID_PERM2_MASK 0x0fffffff + +#define AA_SECURE_EXEC_NEEDED 1 + +/* Control parameters (0 or 1), settable thru module/boot flags or + * via /sys/kernel/security/apparmor/control */ +extern int apparmor_complain; +extern int apparmor_debug; +extern int apparmor_audit; +extern int apparmor_logsyscall; +extern unsigned int apparmor_path_max; + +#define PROFILE_COMPLAIN(_profile) \ + (apparmor_complain == 1 || ((_profile) && (_profile)->flags.complain)) + +#define APPARMOR_COMPLAIN(_cxt) \ + (apparmor_complain == 1 || \ + ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.complain)) + +#define PROFILE_AUDIT(_profile) \ + (apparmor_audit == 1 || ((_profile) && (_profile)->flags.audit)) + +#define APPARMOR_AUDIT(_cxt) \ + (apparmor_audit == 1 || \ + ((_cxt) && (_cxt)->profile && (_cxt)->profile->flags.audit)) + +#define PROFILE_IS_HAT(_profile) \ + ((_profile) && (_profile)->flags.hat) + +/* + * DEBUG remains global (no per profile flag) since it is mostly used in sysctl + * which is not related to profile accesses. + */ + +#define AA_DEBUG(fmt, args...) \ + do { \ + if (apparmor_debug) \ + printk(KERN_DEBUG "AppArmor: " fmt, ##args); \ + } while (0) + +#define AA_ERROR(fmt, args...) printk(KERN_ERR "AppArmor: " fmt, ##args) + +/* struct aa_rlimit - rlimits settings for the profile + * @mask: which hard limits to set + * @limits: rlimit values that override task limits + * + * AppArmor rlimits are used to set confined task rlimits. Only the + * limits specified in @mask will be controlled by apparmor. + */ +struct aa_rlimit { + unsigned int mask; + struct rlimit limits[RLIM_NLIMITS]; +}; + +struct aa_profile; + +/* struct aa_namespace - namespace for a set of profiles + * @name: the name of the namespace + * @list: list the namespace is on + * @profiles: list of profile in the namespace + * @profile_count: the number of profiles in the namespace + * @null_complain_profile: special profile used for learning in this namespace + * @count: reference count on the namespace + * @lock: lock for adding/removing profile to the namespace + */ +struct aa_namespace { + char *name; + struct list_head list; + struct list_head profiles; + int profile_count; + struct aa_profile *null_complain_profile; + + struct kref count; + rwlock_t lock; +}; + +/* struct aa_profile - basic confinement data + * @name: the profiles name + * @list: list this profile is on + * @ns: namespace the profile is in + * @file_rules: dfa containing the profiles file rules + * @flags: flags controlling profile behavior + * @isstale: flag indicating if profile is stale + * @set_caps: capabilities that are being set + * @capabilities: capabilities mask + * @audit_caps: caps that are to be audited + * @quiet_caps: caps that should not be audited + * @capabilities: capabilities granted by the process + * @rlimits: rlimits for the profile + * @task_count: how many tasks the profile is attached to + * @count: reference count of the profile + * @task_contexts: list of tasks confined by profile + * @lock: lock for the task_contexts list + * @network_families: basic network permissions + * @audit_network: which network permissions to force audit + * @quiet_network: which network permissions to quiet rejects + * + * The AppArmor profile contains the basic confinement data. Each profile + * has a name, and all nonstale profile are in a profile namespace. + * + * The task_contexts list and the isstale flag are protected by the + * profile lock. + * + * If a task context is moved between two profiles, we first need to grab + * both profile locks. lock_both_profiles() does that in a deadlock-safe + * way. + */ +struct aa_profile { + char *name; + struct list_head list; + struct aa_namespace *ns; + + int exec_table_size; + char **exec_table; + struct aa_dfa *file_rules; + struct { + int hat; + int complain; + int audit; + } flags; + int isstale; + + kernel_cap_t set_caps; + kernel_cap_t capabilities; + kernel_cap_t audit_caps; + kernel_cap_t quiet_caps; + + struct aa_rlimit rlimits; + unsigned int task_count; + + struct kref count; + struct list_head task_contexts; + spinlock_t lock; + unsigned long int_flags; + u16 network_families[AF_MAX]; + u16 audit_network[AF_MAX]; + u16 quiet_network[AF_MAX]; +}; + +extern struct list_head profile_ns_list; +extern rwlock_t profile_ns_list_lock; +extern struct mutex aa_interface_lock; + +/** + * struct aa_task_context - primary label for confined tasks + * @profile: the current profile + * @previous_profile: profile the task may return to + * @cookie: magic value the task must know for returning to @previous_profile + * @list: list this aa_task_context is on + * @task: task that the aa_task_context confines + * @rcu: rcu head used when freeing the aa_task_context + * @caps_logged: caps that have previously generated log entries + * + * Contains the task's current profile (which could change due to + * change_hat). Plus the hat_magic needed during change_hat. + */ +struct aa_task_context { + struct aa_profile *profile; + struct aa_profile *previous_profile; + u64 cookie; + struct list_head list; + struct task_struct *task; + struct rcu_head rcu; + kernel_cap_t caps_logged; +}; + +extern struct aa_namespace *default_namespace; + +/* aa_audit - AppArmor auditing structure + * Structure is populated by access control code and passed to aa_audit which + * provides for a single point of logging. + */ + +struct aa_audit { + const char *operation; + gfp_t gfp_mask; + const char *info; + const char *name; + const char *name2; + const char *name3; + int request_mask, denied_mask, audit_mask; + int rlimit; + struct iattr *iattr; + pid_t task, parent; + int family, type, protocol; + int error_code; +}; + +/* Flags for the permission check functions */ +#define AA_CHECK_FD 1 /* coming from a file descriptor */ +#define AA_CHECK_DIR 2 /* file type is directory */ + +/* lock subtypes so lockdep does not raise false dependencies */ +enum aa_lock_class { + aa_lock_normal, + aa_lock_nested, + aa_lock_task_release +}; + +/* main.c */ +extern int alloc_default_namespace(void); +extern void free_default_namespace(void); +extern int aa_audit_message(struct aa_profile *profile, struct aa_audit *sa, + int type); +void aa_audit_hint(struct aa_profile *profile, struct aa_audit *sa); +void aa_audit_status(struct aa_profile *profile, struct aa_audit *sa); +int aa_audit_reject(struct aa_profile *profile, struct aa_audit *sa); +extern int aa_audit_syscallreject(struct aa_profile *profile, gfp_t gfp, + const char *); +extern int aa_audit(struct aa_profile *profile, struct aa_audit *); + +extern int aa_attr(struct aa_profile *profile, struct dentry *dentry, + struct vfsmount *mnt, struct iattr *iattr); +extern int aa_perm_xattr(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, + int mask, int check); +extern int aa_capability(struct aa_task_context *cxt, int cap); +extern int aa_perm(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, int mask, + int check); +extern int aa_perm_dir(struct aa_profile *profile, const char *operation, + struct dentry *dentry, struct vfsmount *mnt, + int mask); +extern int aa_perm_path(struct aa_profile *, const char *operation, + const char *name, int mask, uid_t uid); +extern int aa_link(struct aa_profile *profile, + struct dentry *link, struct vfsmount *link_mnt, + struct dentry *target, struct vfsmount *target_mnt); +extern int aa_clone(struct task_struct *task); +extern int aa_register(struct linux_binprm *bprm); +extern void aa_release(struct task_struct *task); +extern int aa_change_hat(const char *id, u64 hat_magic); +extern int aa_change_profile(const char *ns_name, const char *name); +extern struct aa_profile *__aa_replace_profile(struct task_struct *task, + struct aa_profile *profile); +extern struct aa_task_context *lock_task_and_profiles(struct task_struct *task, + struct aa_profile *profile); +extern void unlock_task_and_profiles(struct task_struct *task, + struct aa_task_context *cxt, + struct aa_profile *profile); +extern void aa_change_task_context(struct task_struct *task, + struct aa_task_context *new_cxt, + struct aa_profile *profile, u64 cookie, + struct aa_profile *previous_profile); +extern int aa_may_ptrace(struct aa_task_context *cxt, + struct aa_profile *tracee); +extern int aa_net_perm(struct aa_profile *profile, char *operation, + int family, int type, int protocol); +extern int aa_revalidate_sk(struct sock *sk, char *operation); +extern int aa_task_setrlimit(struct aa_profile *profile, unsigned int resource, + struct rlimit *new_rlim); +extern void aa_set_rlimits(struct task_struct *task, struct aa_profile *profile); + + +/* lsm.c */ +extern int apparmor_initialized; +extern void info_message(const char *str); +extern void apparmor_disable(void); + +/* list.c */ +extern struct aa_namespace *__aa_find_namespace(const char *name, + struct list_head *list); +extern struct aa_profile *__aa_find_profile(const char *name, + struct list_head *list); +extern void aa_profile_ns_list_release(void); + +/* module_interface.c */ +extern ssize_t aa_add_profile(void *, size_t); +extern ssize_t aa_replace_profile(void *, size_t); +extern ssize_t aa_remove_profile(char *, size_t); +extern struct aa_namespace *alloc_aa_namespace(char *name); +extern void free_aa_namespace(struct aa_namespace *ns); +extern void free_aa_namespace_kref(struct kref *kref); +extern struct aa_profile *alloc_aa_profile(void); +extern void free_aa_profile(struct aa_profile *profile); +extern void free_aa_profile_kref(struct kref *kref); +extern void aa_unconfine_tasks(struct aa_profile *profile); + +/* procattr.c */ +extern int aa_getprocattr(struct aa_profile *profile, char **string, + unsigned *len); +extern int aa_setprocattr_changehat(char *args); +extern int aa_setprocattr_changeprofile(char *args); +extern int aa_setprocattr_setprofile(struct task_struct *task, char *args); + +/* apparmorfs.c */ +extern int create_apparmorfs(void); +extern void destroy_apparmorfs(void); + +/* match.c */ +extern struct aa_dfa *aa_match_alloc(void); +extern void aa_match_free(struct aa_dfa *dfa); +extern int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size); +extern int verify_dfa(struct aa_dfa *dfa); +extern unsigned int aa_dfa_match(struct aa_dfa *dfa, const char *str, int *); +extern unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start, + const char *str); +extern unsigned int aa_match_state(struct aa_dfa *dfa, unsigned int start, + const char *str, unsigned int *final); +extern unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, + unsigned int start); + +#endif /* __APPARMOR_H */ --- linux-2.6.28.orig/security/apparmor/module_interface.c +++ linux-2.6.28/security/apparmor/module_interface.c @@ -0,0 +1,967 @@ +/* + * Copyright (C) 1998-2007 Novell/SUSE + * + * 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. + * + * AppArmor userspace policy interface + */ + +#include + +#include "apparmor.h" +#include "inline.h" + +/* + * This mutex is used to synchronize profile adds, replacements, and + * removals: we only allow one of these operations at a time. + * We do not use the profile list lock here in order to avoid blocking + * exec during those operations. (Exec involves a profile list lookup + * for named-profile transitions.) + */ +DEFINE_MUTEX(aa_interface_lock); + +/* + * The AppArmor interface treats data as a type byte followed by the + * actual data. The interface has the notion of a a named entry + * which has a name (AA_NAME typecode followed by name string) followed by + * the entries typecode and data. Named types allow for optional + * elements and extensions to be added and tested for without breaking + * backwards compatability. + */ + +enum aa_code { + AA_U8, + AA_U16, + AA_U32, + AA_U64, + AA_NAME, /* same as string except it is items name */ + AA_STRING, + AA_BLOB, + AA_STRUCT, + AA_STRUCTEND, + AA_LIST, + AA_LISTEND, + AA_ARRAY, + AA_ARRAYEND, +}; + +/* + * aa_ext is the read of the buffer containing the serialized profile. The + * data is copied into a kernel buffer in apparmorfs and then handed off to + * the unpack routines. + */ +struct aa_ext { + void *start; + void *end; + void *pos; /* pointer to current position in the buffer */ + u32 version; + char *ns_name; +}; + +static inline int aa_inbounds(struct aa_ext *e, size_t size) +{ + return (size <= e->end - e->pos); +} + +/** + * aa_u16_chunck - test and do bounds checking for a u16 size based chunk + * @e: serialized data read head + * @chunk: start address for chunk of data + * + * return the size of chunk found with the read head at the end of + * the chunk. + */ +static size_t aa_is_u16_chunk(struct aa_ext *e, char **chunk) +{ + void *pos = e->pos; + size_t size = 0; + + if (!aa_inbounds(e, sizeof(u16))) + goto fail; + size = le16_to_cpu(get_unaligned((u16 *)e->pos)); + e->pos += sizeof(u16); + if (!aa_inbounds(e, size)) + goto fail; + *chunk = e->pos; + e->pos += size; + return size; + +fail: + e->pos = pos; + return 0; +} + +static inline int aa_is_X(struct aa_ext *e, enum aa_code code) +{ + if (!aa_inbounds(e, 1)) + return 0; + if (*(u8 *) e->pos != code) + return 0; + e->pos++; + return 1; +} + +/** + * aa_is_nameX - check is the next element is of type X with a name of @name + * @e: serialized data extent information + * @code: type code + * @name: name to match to the serialized element. + * + * check that the next serialized data element is of type X and has a tag + * name @name. If @name is specified then there must be a matching + * name element in the stream. If @name is NULL any name element will be + * skipped and only the typecode will be tested. + * returns 1 on success (both type code and name tests match) and the read + * head is advanced past the headers + * returns %0 if either match failes, the read head does not move + */ +static int aa_is_nameX(struct aa_ext *e, enum aa_code code, const char *name) +{ + void *pos = e->pos; + /* + * Check for presence of a tagname, and if present name size + * AA_NAME tag value is a u16. + */ + if (aa_is_X(e, AA_NAME)) { + char *tag; + size_t size = aa_is_u16_chunk(e, &tag); + /* if a name is specified it must match. otherwise skip tag */ + if (name && (!size || strcmp(name, tag))) + goto fail; + } else if (name) { + /* if a name is specified and there is no name tag fail */ + goto fail; + } + + /* now check if type code matches */ + if (aa_is_X(e, code)) + return 1; + +fail: + e->pos = pos; + return 0; +} + +static int aa_is_u16(struct aa_ext *e, u16 *data, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_U16, name)) { + if (!aa_inbounds(e, sizeof(u16))) + goto fail; + if (data) + *data = le16_to_cpu(get_unaligned((u16 *)e->pos)); + e->pos += sizeof(u16); + return 1; + } +fail: + e->pos = pos; + return 0; +} + +static int aa_is_u32(struct aa_ext *e, u32 *data, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_U32, name)) { + if (!aa_inbounds(e, sizeof(u32))) + goto fail; + if (data) + *data = le32_to_cpu(get_unaligned((u32 *)e->pos)); + e->pos += sizeof(u32); + return 1; + } +fail: + e->pos = pos; + return 0; +} + +static int aa_is_u64(struct aa_ext *e, u64 *data, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_U64, name)) { + if (!aa_inbounds(e, sizeof(u64))) + goto fail; + if (data) + *data = le64_to_cpu(get_unaligned((u64 *)e->pos)); + e->pos += sizeof(u64); + return 1; + } +fail: + e->pos = pos; + return 0; +} + +static size_t aa_is_array(struct aa_ext *e, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_ARRAY, name)) { + int size; + if (!aa_inbounds(e, sizeof(u16))) + goto fail; + size = (int) le16_to_cpu(get_unaligned((u16 *)e->pos)); + e->pos += sizeof(u16); + return size; + } +fail: + e->pos = pos; + return 0; +} + +static size_t aa_is_blob(struct aa_ext *e, char **blob, const char *name) +{ + void *pos = e->pos; + if (aa_is_nameX(e, AA_BLOB, name)) { + u32 size; + if (!aa_inbounds(e, sizeof(u32))) + goto fail; + size = le32_to_cpu(get_unaligned((u32 *)e->pos)); + e->pos += sizeof(u32); + if (aa_inbounds(e, (size_t) size)) { + * blob = e->pos; + e->pos += size; + return size; + } + } +fail: + e->pos = pos; + return 0; +} + +static int aa_is_dynstring(struct aa_ext *e, char **string, const char *name) +{ + char *src_str; + size_t size = 0; + void *pos = e->pos; + *string = NULL; + if (aa_is_nameX(e, AA_STRING, name) && + (size = aa_is_u16_chunk(e, &src_str))) { + char *str; + if (!(str = kmalloc(size, GFP_KERNEL))) + goto fail; + memcpy(str, src_str, size); + *string = str; + } + + return size; + +fail: + e->pos = pos; + return 0; +} + +/** + * aa_unpack_dfa - unpack a file rule dfa + * @e: serialized data extent information + * + * returns dfa or ERR_PTR + */ +static struct aa_dfa *aa_unpack_dfa(struct aa_ext *e) +{ + char *blob = NULL; + size_t size, error = 0; + struct aa_dfa *dfa = NULL; + + size = aa_is_blob(e, &blob, "aadfa"); + if (size) { + dfa = aa_match_alloc(); + if (dfa) { + /* + * The dfa is aligned with in the blob to 8 bytes + * from the beginning of the stream. + */ + size_t sz = blob - (char *) e->start; + size_t pad = ALIGN(sz, 8) - sz; + error = unpack_dfa(dfa, blob + pad, size - pad); + if (!error) + error = verify_dfa(dfa); + } else { + error = -ENOMEM; + } + + if (error) { + aa_match_free(dfa); + dfa = ERR_PTR(error); + } + } + + return dfa; +} + +static int aa_unpack_exec_table(struct aa_ext *e, struct aa_profile *profile) +{ + void *pos = e->pos; + + /* exec table is optional */ + if (aa_is_nameX(e, AA_STRUCT, "xtable")) { + int i, size; + + size = aa_is_array(e, NULL); + /* currently 4 exec bits and entries 0-3 are reserved iupcx */ + if (size > 16 - 4) + goto fail; + profile->exec_table = kzalloc(sizeof(char *) * size, + GFP_KERNEL); + if (!profile->exec_table) + goto fail; + + for (i = 0; i < size; i++) { + char *tmp; + if (!aa_is_dynstring(e, &tmp, NULL)) + goto fail; + /* note: strings beginning with a : have an embedded + \0 seperating the profile ns name from the profile + name */ + profile->exec_table[i] = tmp; + } + if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + profile->exec_table_size = size; + } + return 1; + +fail: + e->pos = pos; + return 0; +} + +int aa_unpack_rlimits(struct aa_ext *e, struct aa_profile *profile) +{ + void *pos = e->pos; + + /* rlimits are optional */ + if (aa_is_nameX(e, AA_STRUCT, "rlimits")) { + int i, size; + u32 tmp = 0; + if (!aa_is_u32(e, &tmp, NULL)) + goto fail; + profile->rlimits.mask = tmp; + + size = aa_is_array(e, NULL); + if (size > RLIM_NLIMITS) + goto fail; + for (i = 0; i < size; i++) { + u64 tmp = 0; + if (!aa_is_u64(e, &tmp, NULL)) + goto fail; + profile->rlimits.limits[i].rlim_max = tmp; + } + if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + } + return 1; + +fail: + e->pos = pos; + return 0; +} + +/** + * aa_unpack_profile - unpack a serialized profile + * @e: serialized data extent information + * @sa: audit struct for the operation + */ +static struct aa_profile *aa_unpack_profile(struct aa_ext *e, + struct aa_audit *sa) +{ + struct aa_profile *profile = NULL; + size_t size = 0; + int i, error = -EPROTO; + + profile = alloc_aa_profile(); + if (!profile) + return ERR_PTR(-ENOMEM); + + /* check that we have the right struct being passed */ + if (!aa_is_nameX(e, AA_STRUCT, "profile")) + goto fail; + if (!aa_is_dynstring(e, &profile->name, NULL)) + goto fail; + + /* per profile debug flags (complain, audit) */ + if (!aa_is_nameX(e, AA_STRUCT, "flags")) + goto fail; + if (!aa_is_u32(e, &(profile->flags.hat), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->flags.complain), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->flags.audit), NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + + if (!aa_is_u32(e, &(profile->capabilities.cap[0]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->audit_caps.cap[0]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->quiet_caps.cap[0]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->set_caps.cap[0]), NULL)) + goto fail; + + if (aa_is_nameX(e, AA_STRUCT, "caps64")) { + /* optional upper half of 64 bit caps */ + if (!aa_is_u32(e, &(profile->capabilities.cap[1]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->audit_caps.cap[1]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->quiet_caps.cap[1]), NULL)) + goto fail; + if (!aa_is_u32(e, &(profile->set_caps.cap[1]), NULL)) + goto fail; + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + } + + if (!aa_unpack_rlimits(e, profile)) + goto fail; + + size = aa_is_array(e, "net_allowed_af"); + if (size) { + if (size > AF_MAX) + goto fail; + + for (i = 0; i < size; i++) { + if (!aa_is_u16(e, &profile->network_families[i], NULL)) + goto fail; + if (!aa_is_u16(e, &profile->audit_network[i], NULL)) + goto fail; + if (!aa_is_u16(e, &profile->quiet_network[i], NULL)) + goto fail; + } + if (!aa_is_nameX(e, AA_ARRAYEND, NULL)) + goto fail; + /* allow unix domain and netlink sockets they are handled + * by IPC + */ + } + profile->network_families[AF_UNIX] = 0xffff; + profile->network_families[AF_NETLINK] = 0xffff; + + /* get file rules */ + profile->file_rules = aa_unpack_dfa(e); + if (IS_ERR(profile->file_rules)) { + error = PTR_ERR(profile->file_rules); + profile->file_rules = NULL; + goto fail; + } + + if (!aa_unpack_exec_table(e, profile)) + goto fail; + + if (!aa_is_nameX(e, AA_STRUCTEND, NULL)) + goto fail; + + return profile; + +fail: + sa->name = profile && profile->name ? profile->name : "unknown"; + if (!sa->info) + sa->info = "failed to unpack profile"; + aa_audit_status(NULL, sa); + + if (profile) + free_aa_profile(profile); + + return ERR_PTR(error); +} + +/** + * aa_verify_head - unpack serialized stream header + * @e: serialized data read head + * @operation: operation header is being verified for + * + * returns error or 0 if header is good + */ +static int aa_verify_header(struct aa_ext *e, struct aa_audit *sa) +{ + /* get the interface version */ + if (!aa_is_u32(e, &e->version, "version")) { + sa->info = "invalid profile format"; + aa_audit_status(NULL, sa); + return -EPROTONOSUPPORT; + } + + /* check that the interface version is currently supported */ + if (e->version != 5) { + sa->info = "unsupported interface version"; + aa_audit_status(NULL, sa); + return -EPROTONOSUPPORT; + } + + /* read the namespace if present */ + if (!aa_is_dynstring(e, &e->ns_name, "namespace")) { + e->ns_name = NULL; + } + + return 0; +} + +/** + * aa_add_profile - Unpack and add a new profile to the profile list + * @data: serialized data stream + * @size: size of the serialized data stream + */ +ssize_t aa_add_profile(void *data, size_t size) +{ + struct aa_profile *profile = NULL; + struct aa_namespace *ns = NULL; + struct aa_ext e = { + .start = data, + .end = data + size, + .pos = data, + .ns_name = NULL + }; + ssize_t error; + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_load"; + sa.gfp_mask = GFP_KERNEL; + + error = aa_verify_header(&e, &sa); + if (error) + return error; + + profile = aa_unpack_profile(&e, &sa); + if (IS_ERR(profile)) + return PTR_ERR(profile); + + mutex_lock(&aa_interface_lock); + write_lock(&profile_ns_list_lock); + if (e.ns_name) + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + else + ns = default_namespace; + if (!ns) { + struct aa_namespace *new_ns; + write_unlock(&profile_ns_list_lock); + new_ns = alloc_aa_namespace(e.ns_name); + if (!new_ns) { + mutex_unlock(&aa_interface_lock); + return -ENOMEM; + } + write_lock(&profile_ns_list_lock); + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + if (!ns) { + list_add(&new_ns->list, &profile_ns_list); + ns = new_ns; + } else + free_aa_namespace(new_ns); + } + + write_lock(&ns->lock); + if (__aa_find_profile(profile->name, &ns->profiles)) { + /* A profile with this name exists already. */ + write_unlock(&ns->lock); + write_unlock(&profile_ns_list_lock); + sa.name = profile->name; + sa.name2 = ns->name; + sa.info = "failed: profile already loaded"; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + aa_put_profile(profile); + return -EEXIST; + } + profile->ns = aa_get_namespace(ns); + ns->profile_count++; + list_add(&profile->list, &ns->profiles); + write_unlock(&ns->lock); + write_unlock(&profile_ns_list_lock); + + sa.name = profile->name; + sa.name2 = ns->name; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + return size; +} + +/** + * task_replace - replace a task's profile + * @task: task to replace profile on + * @new_cxt: new aa_task_context to do replacement with + * @new_profile: new profile + */ +static inline void task_replace(struct task_struct *task, + struct aa_task_context *new_cxt, + struct aa_profile *new_profile) +{ + struct aa_task_context *cxt = aa_task_context(task); + + AA_DEBUG("%s: replacing profile for task %d " + "profile=%s (%p)\n", + __FUNCTION__, + cxt->task->pid, + cxt->profile->name, cxt->profile); + + aa_change_task_context(task, new_cxt, new_profile, cxt->cookie, + cxt->previous_profile); +} + +/** + * aa_replace_profile - replace a profile on the profile list + * @udata: serialized data stream + * @size: size of the serialized data stream + * + * unpack and replace a profile on the profile list and uses of that profile + * by any aa_task_context. If the profile does not exist on the profile list + * it is added. Return %0 or error. + */ +ssize_t aa_replace_profile(void *udata, size_t size) +{ + struct aa_profile *old_profile, *new_profile; + struct aa_namespace *ns; + struct aa_task_context *new_cxt; + struct aa_ext e = { + .start = udata, + .end = udata + size, + .pos = udata, + .ns_name = NULL + }; + ssize_t error; + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_replace"; + sa.gfp_mask = GFP_KERNEL; + + error = aa_verify_header(&e, &sa); + if (error) + return error; + + new_profile = aa_unpack_profile(&e, &sa); + if (IS_ERR(new_profile)) + return PTR_ERR(new_profile); + + mutex_lock(&aa_interface_lock); + write_lock(&profile_ns_list_lock); + if (e.ns_name) + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + else + ns = default_namespace; + if (!ns) { + struct aa_namespace *new_ns; + write_unlock(&profile_ns_list_lock); + new_ns = alloc_aa_namespace(e.ns_name); + if (!new_ns) { + mutex_unlock(&aa_interface_lock); + return -ENOMEM; + } + write_lock(&profile_ns_list_lock); + ns = __aa_find_namespace(e.ns_name, &profile_ns_list); + if (!ns) { + list_add(&new_ns->list, &profile_ns_list); + ns = new_ns; + } else + free_aa_namespace(new_ns); + } + + write_lock(&ns->lock); + old_profile = __aa_find_profile(new_profile->name, &ns->profiles); + if (old_profile) { + lock_profile(old_profile); + old_profile->isstale = 1; + list_del_init(&old_profile->list); + unlock_profile(old_profile); + ns->profile_count--; + } + new_profile->ns = aa_get_namespace(ns); + ns->profile_count++; + /* not don't need an extra ref count to keep new_profile as + * it is protect by the interface mutex */ + list_add(&new_profile->list, &ns->profiles); + write_unlock(&ns->lock); + write_unlock(&profile_ns_list_lock); + + if (!old_profile) { + sa.operation = "profile_load"; + goto out; + } + /* do not fail replacement based off of profile's NPROC rlimit */ + + /* + * Replacement needs to allocate a new aa_task_context for each + * task confined by old_profile. To do this the profile locks + * are only held when the actual switch is done per task. While + * looping to allocate a new aa_task_context the old_task list + * may get shorter if tasks exit/change their profile but will + * not get longer as new task will not use old_profile detecting + * that is stale. + */ + do { + new_cxt = aa_alloc_task_context(GFP_KERNEL | __GFP_NOFAIL); + + lock_both_profiles(old_profile, new_profile); + if (!list_empty(&old_profile->task_contexts)) { + struct task_struct *task = + list_entry(old_profile->task_contexts.next, + struct aa_task_context, list)->task; + task_lock(task); + task_replace(task, new_cxt, new_profile); + task_unlock(task); + aa_set_rlimits(task, new_profile); + new_cxt = NULL; + } + unlock_both_profiles(old_profile, new_profile); + } while (!new_cxt); + aa_free_task_context(new_cxt); + aa_put_profile(old_profile); + +out: + sa.name = new_profile->name; + sa.name2 = ns->name; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + return size; +} + +/** + * aa_remove_profile - remove a profile from the system + * @name: name of the profile to remove + * @size: size of the name + * + * remove a profile from the profile list and all aa_task_context references + * to said profile. + * NOTE: removing confinement does not restore rlimits to preconfinemnet values + */ +ssize_t aa_remove_profile(char *name, size_t size) +{ + struct aa_namespace *ns; + struct aa_profile *profile; + struct aa_audit sa; + memset(&sa, 0, sizeof(sa)); + sa.operation = "profile_remove"; + sa.gfp_mask = GFP_KERNEL; + + mutex_lock(&aa_interface_lock); + write_lock(&profile_ns_list_lock); + + if (name[0] == ':') { + char *split = strchr(name + 1, ':'); + if (!split) + goto noent; + *split = 0; + ns = __aa_find_namespace(name + 1, &profile_ns_list); + name = split + 1; + } else { + ns = default_namespace; + } + + if (!ns) + goto noent; + sa.name2 = ns->name; + write_lock(&ns->lock); + profile = __aa_find_profile(name, &ns->profiles); + if (!profile) { + write_unlock(&ns->lock); + goto noent; + } + sa.name = profile->name; + + /* Remove the profile from each task context it is on. */ + lock_profile(profile); + profile->isstale = 1; + aa_unconfine_tasks(profile); + list_del_init(&profile->list); + ns->profile_count--; + unlock_profile(profile); + /* Release the profile itself. */ + write_unlock(&ns->lock); + /* check to see if the namespace has become stale */ + if (ns != default_namespace && ns->profile_count == 0) { + list_del_init(&ns->list); + aa_put_namespace(ns); + } + write_unlock(&profile_ns_list_lock); + + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + aa_put_profile(profile); + + return size; + +noent: + write_unlock(&profile_ns_list_lock); + sa.info = "failed: profile does not exist"; + aa_audit_status(NULL, &sa); + mutex_unlock(&aa_interface_lock); + return -ENOENT; +} + +/** + * free_aa_namespace_kref - free aa_namespace by kref (see aa_put_namespace) + * @kr: kref callback for freeing of a namespace + */ +void free_aa_namespace_kref(struct kref *kref) +{ + struct aa_namespace *ns=container_of(kref, struct aa_namespace, count); + + free_aa_namespace(ns); +} + +/** + * alloc_aa_namespace - allocate, initialize and return a new namespace + * @name: a preallocated name + * Returns NULL on failure. + */ +struct aa_namespace *alloc_aa_namespace(char *name) +{ + struct aa_namespace *ns; + + ns = kzalloc(sizeof(*ns), GFP_KERNEL); + AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); + if (ns) { + ns->name = name; + INIT_LIST_HEAD(&ns->list); + INIT_LIST_HEAD(&ns->profiles); + kref_init(&ns->count); + rwlock_init(&ns->lock); + + ns->null_complain_profile = alloc_aa_profile(); + if (!ns->null_complain_profile) { + if (!name) + kfree(ns->name); + kfree(ns); + return NULL; + } + ns->null_complain_profile->name = + kstrdup("null-complain-profile", GFP_KERNEL); + if (!ns->null_complain_profile->name) { + free_aa_profile(ns->null_complain_profile); + if (!name) + kfree(ns->name); + kfree(ns); + return NULL; + } + ns->null_complain_profile->flags.complain = 1; + /* null_complain_profile doesn't contribute to ns ref count */ + ns->null_complain_profile->ns = ns; + } + return ns; +} + +/** + * free_aa_namespace - free a profile namespace + * @namespace: the namespace to free + * + * Free a namespace. All references to the namespace must have been put. + * If the namespace was referenced by a profile confining a task, + * free_aa_namespace will be called indirectly (through free_aa_profile) + * from an rcu callback routine, so we must not sleep here. + */ +void free_aa_namespace(struct aa_namespace *ns) +{ + AA_DEBUG("%s(%p)\n", __FUNCTION__, ns); + + if (!ns) + return; + + /* namespace still contains profiles -- invalid */ + if (!list_empty(&ns->profiles)) { + AA_ERROR("%s: internal error, " + "namespace '%s' still contains profiles\n", + __FUNCTION__, + ns->name); + BUG(); + } + if (!list_empty(&ns->list)) { + AA_ERROR("%s: internal error, " + "namespace '%s' still on list\n", + __FUNCTION__, + ns->name); + BUG(); + } + /* null_complain_profile doesn't contribute to ns ref counting */ + ns->null_complain_profile->ns = NULL; + aa_put_profile(ns->null_complain_profile); + kfree(ns->name); + kfree(ns); +} + +/** + * free_aa_profile_kref - free aa_profile by kref (called by aa_put_profile) + * @kr: kref callback for freeing of a profile + */ +void free_aa_profile_kref(struct kref *kref) +{ + struct aa_profile *p=container_of(kref, struct aa_profile, count); + + free_aa_profile(p); +} + +/** + * alloc_aa_profile - allocate, initialize and return a new profile + * Returns NULL on failure. + */ +struct aa_profile *alloc_aa_profile(void) +{ + struct aa_profile *profile; + + profile = kzalloc(sizeof(*profile), GFP_KERNEL); + AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); + if (profile) { + INIT_LIST_HEAD(&profile->list); + kref_init(&profile->count); + INIT_LIST_HEAD(&profile->task_contexts); + spin_lock_init(&profile->lock); + } + return profile; +} + +/** + * free_aa_profile - free a profile + * @profile: the profile to free + * + * Free a profile, its hats and null_profile. All references to the profile, + * its hats and null_profile must have been put. + * + * If the profile was referenced from a task context, free_aa_profile() will + * be called from an rcu callback routine, so we must not sleep here. + */ +void free_aa_profile(struct aa_profile *profile) +{ + AA_DEBUG("%s(%p)\n", __FUNCTION__, profile); + + if (!profile) + return; + + /* profile is still on profile namespace list -- invalid */ + if (!list_empty(&profile->list)) { + AA_ERROR("%s: internal error, " + "profile '%s' still on global list\n", + __FUNCTION__, + profile->name); + BUG(); + } + aa_put_namespace(profile->ns); + + aa_match_free(profile->file_rules); + + if (profile->name) { + AA_DEBUG("%s: %s\n", __FUNCTION__, profile->name); + kfree(profile->name); + } + + kfree(profile); +} + +/** + * aa_unconfine_tasks - remove tasks on a profile's task context list + * @profile: profile to remove tasks from + * + * Assumes that @profile lock is held. + */ +void aa_unconfine_tasks(struct aa_profile *profile) +{ + while (!list_empty(&profile->task_contexts)) { + struct task_struct *task = + list_entry(profile->task_contexts.next, + struct aa_task_context, list)->task; + task_lock(task); + aa_change_task_context(task, NULL, NULL, 0, NULL); + task_unlock(task); + } +} --- linux-2.6.28.orig/security/smack/smack_lsm.c +++ linux-2.6.28/security/smack/smack_lsm.c @@ -432,8 +432,9 @@ * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry) +static int smack_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, + struct dentry *new_dentry, struct vfsmount *new_mnt) { int rc; char *isp; @@ -453,11 +454,13 @@ * smack_inode_unlink - Smack check on inode deletion * @dir: containing directory object * @dentry: file to unlink + * @mnt: vfsmount of file to unlink * * Returns 0 if current can write the containing directory * and the object, error code otherwise */ -static int smack_inode_unlink(struct inode *dir, struct dentry *dentry) +static int smack_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { struct inode *ip = dentry->d_inode; int rc; @@ -479,11 +482,13 @@ * smack_inode_rmdir - Smack check on directory deletion * @dir: containing directory object * @dentry: directory to unlink + * @mnt: vfsmount @dentry to unlink * * Returns 0 if current can write the containing directory * and the directory, error code otherwise */ -static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry) +static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) { int rc; @@ -504,8 +509,10 @@ * smack_inode_rename - Smack check on rename * @old_inode: the old directory * @old_dentry: unused + * @old_mnt: unused * @new_inode: the new directory * @new_dentry: unused + * @new_mnt: unused * * Read and write access is required on both the old and * new directories. @@ -514,8 +521,10 @@ */ static int smack_inode_rename(struct inode *old_inode, struct dentry *old_dentry, + struct vfsmount *old_mnt, struct inode *new_inode, - struct dentry *new_dentry) + struct dentry *new_dentry, + struct vfsmount *new_mnt) { int rc; char *isp; @@ -559,7 +568,8 @@ * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr) +static int smack_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *iattr) { /* * Need to allow for clearing the setuid bit. @@ -585,17 +595,20 @@ /** * smack_inode_setxattr - Smack check for setting xattrs * @dentry: the object + * @mnt: unused * @name: name of the attribute * @value: unused * @size: unused * @flags: unused + * @file: unused * * This protects the Smack attribute explicitly. * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +static int smack_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file) { int rc = 0; @@ -605,7 +618,8 @@ if (!capable(CAP_MAC_ADMIN)) rc = -EPERM; } else - rc = cap_inode_setxattr(dentry, name, value, size, flags); + rc = cap_inode_setxattr(dentry, mnt, name, value, size, flags, + file); if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); @@ -616,6 +630,7 @@ /** * smack_inode_post_setxattr - Apply the Smack update approved above * @dentry: object + * @mnt: unused * @name: attribute name * @value: attribute value * @size: attribute size @@ -624,7 +639,8 @@ * Set the pointer in the inode blob to the entry found * in the master label list. */ -static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, +static void smack_inode_post_setxattr(struct dentry *dentry, + struct vfsmount *mnt, const char *name, const void *value, size_t size, int flags) { struct inode_smack *isp; @@ -657,11 +673,14 @@ /* * smack_inode_getxattr - Smack check on getxattr * @dentry: the object + * @mnt: unused * @name: unused + * @file: unused * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_getxattr(struct dentry *dentry, const char *name) +static int smack_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ); } @@ -669,13 +688,16 @@ /* * smack_inode_removexattr - Smack check on removexattr * @dentry: the object + * @mnt: unused * @name: name of the attribute + * @file: unused * * Removing the Smack attribute requires CAP_MAC_ADMIN * * Returns 0 if access is permitted, an error code otherwise */ -static int smack_inode_removexattr(struct dentry *dentry, const char *name) +static int smack_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file) { int rc = 0; @@ -685,7 +707,7 @@ if (!capable(CAP_MAC_ADMIN)) rc = -EPERM; } else - rc = cap_inode_removexattr(dentry, name); + rc = cap_inode_removexattr(dentry, mnt, name, file); if (rc == 0) rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE); --- linux-2.6.28.orig/include/drm/i915_drm.h +++ linux-2.6.28/include/drm/i915_drm.h @@ -177,6 +177,8 @@ #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t) #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t) +#define DRM_IOCTL_I915_GEM_INIT DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_INIT, struct drm_i915_gem_init) +#define DRM_IOCTL_I915_GEM_EXECBUFFER DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_EXECBUFFER, struct drm_i915_gem_execbuffer) #define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin) #define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin) #define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy) --- linux-2.6.28.orig/include/linux/swap.h +++ linux-2.6.28/include/linux/swap.h @@ -150,6 +150,7 @@ unsigned int max; unsigned int inuse_pages; int next; /* next entry on swap list */ + void (*notify_swap_entry_free_fn) (unsigned long); }; struct swap_list_t { @@ -309,6 +310,7 @@ extern int can_share_swap_page(struct page *); extern int remove_exclusive_swap_page(struct page *); extern int remove_exclusive_swap_page_ref(struct page *); +extern void set_notify_swap_entry_free(unsigned, void (*) (unsigned long)); struct backing_dev_info; /* linux/mm/thrash.c */ --- linux-2.6.28.orig/include/linux/mount.h +++ linux-2.6.28/include/linux/mount.h @@ -112,4 +112,6 @@ extern spinlock_t vfsmount_lock; extern dev_t name_to_dev_t(char *name); +extern char *d_namespace_path(struct dentry *, struct vfsmount *, char *, int); + #endif /* _LINUX_MOUNT_H */ --- linux-2.6.28.orig/include/linux/splice.h +++ linux-2.6.28/include/linux/splice.h @@ -71,4 +71,10 @@ extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *, splice_direct_actor *); +extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); +extern long do_splice_to(struct file *in, loff_t *ppos, + struct pipe_inode_info *pipe, size_t len, + unsigned int flags); + #endif --- linux-2.6.28.orig/include/linux/serial.h +++ linux-2.6.28/include/linux/serial.h @@ -10,8 +10,9 @@ #ifndef _LINUX_SERIAL_H #define _LINUX_SERIAL_H -#ifdef __KERNEL__ #include + +#ifdef __KERNEL__ #include /* --- linux-2.6.28.orig/include/linux/sysctl.h +++ linux-2.6.28/include/linux/sysctl.h @@ -996,6 +996,8 @@ extern int proc_doulongvec_ms_jiffies_minmax(struct ctl_table *table, int, struct file *, void __user *, size_t *, loff_t *); +extern char *sysctl_pathname(ctl_table *, char *, int); + extern int do_sysctl (int __user *name, int nlen, void __user *oldval, size_t __user *oldlenp, void __user *newval, size_t newlen); --- linux-2.6.28.orig/include/linux/connector.h +++ linux-2.6.28/include/linux/connector.h @@ -39,8 +39,10 @@ #define CN_IDX_V86D 0x4 #define CN_VAL_V86D_UVESAFB 0x1 #define CN_IDX_BB 0x5 /* BlackBoard, from the TSP GPL sampling framework */ +#define CN_IDX_DRBD 0x6 +#define CN_VAL_DRBD 0x1 -#define CN_NETLINK_USERS 6 +#define CN_NETLINK_USERS 7 /* * Maximum connector's message size. --- linux-2.6.28.orig/include/linux/dcache.h +++ linux-2.6.28/include/linux/dcache.h @@ -300,9 +300,12 @@ /* * helper function for dentry_operations.d_dname() members */ +#define D_PATH_FAIL_DELETED 1 +#define D_PATH_DISCONNECT 2 extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); -extern char *__d_path(const struct path *path, struct path *root, char *, int); +extern char *__d_path(const struct path *path, struct path *root, char *, int, + int); extern char *d_path(const struct path *, char *, int); extern char *dentry_path(struct dentry *, char *, int); --- linux-2.6.28.orig/include/linux/xattr.h +++ linux-2.6.28/include/linux/xattr.h @@ -16,6 +16,8 @@ #ifdef __KERNEL__ #include +#include +#include /* Namespaces */ #define XATTR_OS2_PREFIX "os2." @@ -47,10 +49,10 @@ }; ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); -ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); -ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); -int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); -int vfs_removexattr(struct dentry *, const char *); +ssize_t vfs_getxattr(struct dentry *, struct vfsmount *, const char *, void *, size_t, struct file *file); +ssize_t vfs_listxattr(struct dentry *d, struct vfsmount *, char *list, size_t size, struct file *file); +int vfs_setxattr(struct dentry *, struct vfsmount *, const char *, const void *, size_t, int, struct file *file); +int vfs_removexattr(struct dentry *, struct vfsmount *mnt, const char *, struct file *file); ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size); ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size); --- linux-2.6.28.orig/include/linux/namei.h +++ linux-2.6.28/include/linux/namei.h @@ -84,6 +84,8 @@ extern struct dentry *lock_rename(struct dentry *, struct dentry *); extern void unlock_rename(struct dentry *, struct dentry *); +struct dentry * __lookup_hash(struct qstr *name, struct dentry * base, struct nameidata *nd); + static inline void nd_set_link(struct nameidata *nd, char *path) { nd->saved_names[nd->depth] = path; --- linux-2.6.28.orig/include/linux/audit.h +++ linux-2.6.28/include/linux/audit.h @@ -33,7 +33,7 @@ * 1200 - 1299 messages internal to the audit daemon * 1300 - 1399 audit event messages * 1400 - 1499 SE Linux use - * 1500 - 1599 kernel LSPP events + * 1500 - 1599 AppArmor use * 1600 - 1699 kernel crypto events * 1700 - 1799 kernel anomaly records * 1800 - 1999 future kernel use (maybe integrity labels and related events) @@ -119,6 +119,13 @@ #define AUDIT_MAC_UNLBL_STCADD 1416 /* NetLabel: add a static label */ #define AUDIT_MAC_UNLBL_STCDEL 1417 /* NetLabel: del a static label */ +#define AUDIT_APPARMOR_AUDIT 1501 /* AppArmor audited grants */ +#define AUDIT_APPARMOR_ALLOWED 1502 /* Allowed Access for learning */ +#define AUDIT_APPARMOR_DENIED 1503 +#define AUDIT_APPARMOR_HINT 1504 /* Process Tracking information */ +#define AUDIT_APPARMOR_STATUS 1505 /* Changes in config */ +#define AUDIT_APPARMOR_ERROR 1506 /* Internal AppArmor Errors */ + #define AUDIT_FIRST_KERN_ANOM_MSG 1700 #define AUDIT_LAST_KERN_ANOM_MSG 1799 #define AUDIT_ANOM_PROMISCUOUS 1700 /* Device changed promiscuous mode */ @@ -547,6 +554,9 @@ __attribute__((format(printf,4,5))); extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type); +extern void audit_log_vformat(struct audit_buffer *ab, + const char *fmt, va_list args) + __attribute__((format(printf,2,0))); extern void audit_log_format(struct audit_buffer *ab, const char *fmt, ...) __attribute__((format(printf,2,3))); --- linux-2.6.28.orig/include/linux/fs.h +++ linux-2.6.28/include/linux/fs.h @@ -372,6 +372,10 @@ * Not an attribute, but an auxilary info for filesystems wanting to * implement an ftruncate() like method. NOTE: filesystem should * check for (ia_valid & ATTR_FILE), and not for (ia_file != NULL). + * + * NOTE: With patches.apparmor/fsetattr.diff applied, this is + * for compatibility with external file system modules only. There + * should not be any in-kernel users left. */ struct file *ia_file; }; @@ -1205,13 +1209,13 @@ */ extern int vfs_permission(struct nameidata *, int); extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); -extern int vfs_mkdir(struct inode *, struct dentry *, int); -extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); -extern int vfs_symlink(struct inode *, struct dentry *, const char *); -extern int vfs_link(struct dentry *, struct inode *, struct dentry *); -extern int vfs_rmdir(struct inode *, struct dentry *); -extern int vfs_unlink(struct inode *, struct dentry *); -extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +extern int vfs_mkdir(struct inode *, struct dentry *, struct vfsmount *, int); +extern int vfs_mknod(struct inode *, struct dentry *, struct vfsmount *, int, dev_t); +extern int vfs_symlink(struct inode *, struct dentry *, struct vfsmount *, const char *); +extern int vfs_link(struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); +extern int vfs_rmdir(struct inode *, struct dentry *, struct vfsmount *); +extern int vfs_unlink(struct inode *, struct dentry *, struct vfsmount *); +extern int vfs_rename(struct inode *, struct dentry *, struct vfsmount *, struct inode *, struct dentry *, struct vfsmount *); /* * VFS dentry helper functions. @@ -1224,6 +1228,11 @@ extern int file_permission(struct file *, int); /* + * VFS path helper functions. + */ +extern int path_permission(struct path *, int); + +/* * VFS FS_IOC_FIEMAP helper definitions. */ struct fiemap_extent_info { @@ -1306,6 +1315,7 @@ ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **); + int (*fsetattr)(struct file *, struct iattr *); }; struct inode_operations { @@ -1669,8 +1679,8 @@ /* fs/open.c */ -extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, - struct file *filp); +extern int do_truncate(struct dentry *, struct vfsmount *, loff_t start, + unsigned int time_attrs, struct file *filp); extern long do_sys_open(int dfd, const char __user *filename, int flags, int mode); extern struct file *filp_open(const char *, int, int); @@ -1830,7 +1840,8 @@ #ifdef CONFIG_BLOCK extern sector_t bmap(struct inode *, sector_t); #endif -extern int notify_change(struct dentry *, struct iattr *); +extern int notify_change(struct dentry *, struct vfsmount *, struct iattr *); +extern int fnotify_change(struct dentry *, struct vfsmount *, struct iattr *, struct file *); extern int inode_permission(struct inode *, int); extern int generic_permission(struct inode *, int, int (*check_acl)(struct inode *, int)); --- linux-2.6.28.orig/include/linux/aufs_type.h +++ linux-2.6.28/include/linux/aufs_type.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2005-2008 Junjiro Okajima + * + * This program, aufs 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* $Id: aufs_type.h,v 1.124 2008/09/22 03:52:19 sfjro Exp $ */ + +#include + +#ifndef __AUFS_TYPE_H__ +#define __AUFS_TYPE_H__ + +#define AUFS_VERSION "20080922" + +/* move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') + +/* ---------------------------------------------------------------------- */ + +#ifdef CONFIG_AUFS_BRANCH_MAX_127 +/* some environments treat 'char' as 'unsigned char' by default */ +typedef signed char aufs_bindex_t; +#define AUFS_BRANCH_MAX 127 +#else +typedef short aufs_bindex_t; +#ifdef CONFIG_AUFS_BRANCH_MAX_511 +#define AUFS_BRANCH_MAX 511 +#elif defined(CONFIG_AUFS_BRANCH_MAX_1023) +#define AUFS_BRANCH_MAX 1023 +#elif defined(CONFIG_AUFS_BRANCH_MAX_32767) +#define AUFS_BRANCH_MAX 32767 +#else +#error unknown CONFIG_AUFS_BRANCH_MAX value +#endif +#endif + +#define AUFS_NAME "aufs" +#define AUFS_FSTYPE AUFS_NAME + +#define AUFS_ROOT_INO 2 +#define AUFS_FIRST_INO 11 + +#define AUFS_WH_PFX ".wh." +#define AUFS_WH_PFX_LEN ((int)sizeof(AUFS_WH_PFX) - 1) +#define AUFS_XINO_FNAME "." AUFS_NAME ".xino" +#define AUFS_XINO_DEFPATH "/tmp/" AUFS_XINO_FNAME +#define AUFS_XINO_TRUNC_INIT 64 /* blocks */ +#define AUFS_XINO_TRUNC_STEP 4 /* blocks */ +#define AUFS_DIRWH_DEF 3 +#define AUFS_RDCACHE_DEF 10 /* seconds */ +#define AUFS_WKQ_NAME AUFS_NAME "d" +#define AUFS_NWKQ_DEF 4 +#define AUFS_MFS_SECOND_DEF 30 /* seconds */ +#define AUFS_PLINK_WARN 100 /* number of plinks */ + +#ifdef CONFIG_AUFS_COMPAT +#define AUFS_DIROPQ_NAME "__dir_opaque" +#else +#define AUFS_DIROPQ_NAME AUFS_WH_PFX ".opq" /* whiteouted doubly */ +#endif +#define AUFS_WH_DIROPQ AUFS_WH_PFX AUFS_DIROPQ_NAME + +/* will be whiteouted doubly */ +#define AUFS_WH_BASENAME AUFS_WH_PFX AUFS_NAME +#define AUFS_WH_PLINKDIR AUFS_WH_PFX "plnk" +#define AUFS_WH_TMPDIR AUFS_WH_PFX ".tmp" + +/* ---------------------------------------------------------------------- */ + +/* ioctl */ +#if 0 /* reserved for future use */ +enum { + AuCtlErr, + AuCtlErr_Last +}; +enum { + AuCtl_REFRESH, AuCtl_REFRESHV, + AuCtl_FLUSH_PLINK, + AuCtl_CPUP, + AuCtl_CPDOWN, AuCtl_MVDOWN, + AuCtl_DIROPQ +}; + +struct aufs_ctl_cp { + int bsrc, bdst; + int err; +}; + +#define AuCtlType 'A' +#define AUFS_CTL_REFRESH _IO(AuCtlType, AuCtl_REFRESH) +#define AUFS_CTL_REFRESHV _IO(AuCtlType, AuCtl_REFRESHV) +#define AUFS_CTL_FLUSH_PLINK _IOR(AuCtlType, AuCtl_FLUSH_PLINK) +#define AUFS_CTL_CPUP _IOWR(AuCtlType, AuCtl_CPUP, struct aufs_ctl_cp) +#define AUFS_CTL_CPDOWN \ + _IOWR(AuCtlType, AuCtl_CPDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_MVDOWN \ + _IOWR(AuCtlType, AuCtl_MVDOWN, struct aufs_ctl_cp) +#define AUFS_CTL_DIROPQ _IO(AuCtlType, AuCtl_DIROPQ) +#endif + +#endif /* __AUFS_TYPE_H__ */ --- linux-2.6.28.orig/include/linux/security.h +++ linux-2.6.28/include/linux/security.h @@ -54,9 +54,11 @@ extern int cap_bprm_set_security(struct linux_binprm *bprm); extern void cap_bprm_apply_creds(struct linux_binprm *bprm, int unsafe); extern int cap_bprm_secureexec(struct linux_binprm *bprm); -extern int cap_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -extern int cap_inode_removexattr(struct dentry *dentry, const char *name); +extern int cap_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file); +extern int cap_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); extern int cap_inode_need_killpriv(struct dentry *dentry); extern int cap_inode_killpriv(struct dentry *dentry); extern int cap_task_post_setuid(uid_t old_ruid, uid_t old_euid, uid_t old_suid, int flags); @@ -337,23 +339,28 @@ * Check permission to create a regular file. * @dir contains inode structure of the parent of the new file. * @dentry contains the dentry structure for the file to be created. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @mode contains the file mode of the file to be created. * Return 0 if permission is granted. * @inode_link: * Check permission before creating a new hard link to a file. * @old_dentry contains the dentry structure for an existing link to the file. + * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL). * @dir contains the inode structure of the parent directory of the new link. * @new_dentry contains the dentry structure for the new link. + * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL). * Return 0 if permission is granted. * @inode_unlink: * Check the permission to remove a hard link to a file. * @dir contains the inode structure of parent directory of the file. * @dentry contains the dentry structure for file to be unlinked. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * Return 0 if permission is granted. * @inode_symlink: * Check the permission to create a symbolic link to a file. * @dir contains the inode structure of parent directory of the symbolic link. * @dentry contains the dentry structure of the symbolic link. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @old_name contains the pathname of file. * Return 0 if permission is granted. * @inode_mkdir: @@ -361,12 +368,14 @@ * associated with inode strcture @dir. * @dir containst the inode structure of parent of the directory to be created. * @dentry contains the dentry structure of new directory. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @mode contains the mode of new directory. * Return 0 if permission is granted. * @inode_rmdir: * Check the permission to remove a directory. * @dir contains the inode structure of parent of the directory to be removed. * @dentry contains the dentry structure of directory to be removed. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * Return 0 if permission is granted. * @inode_mknod: * Check permissions when creating a special file (or a socket or a fifo @@ -375,6 +384,7 @@ * and not this hook. * @dir contains the inode structure of parent of the new file. * @dentry contains the dentry structure of the new file. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @mode contains the mode of the new file. * @dev contains the device number. * Return 0 if permission is granted. @@ -382,12 +392,15 @@ * Check for permission to rename a file or directory. * @old_dir contains the inode structure for parent of the old link. * @old_dentry contains the dentry structure of the old link. + * @old_mnt is the vfsmount corresponding to @old_dentry (may be NULL). * @new_dir contains the inode structure for parent of the new link. * @new_dentry contains the dentry structure of the new link. + * @new_mnt is the vfsmount corresponding to @new_dentry (may be NULL). * Return 0 if permission is granted. * @inode_readlink: * Check the permission to read the symbolic link. * @dentry contains the dentry structure for the file link. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * Return 0 if permission is granted. * @inode_follow_link: * Check permission to follow a symbolic link when looking up a pathname. @@ -411,6 +424,7 @@ * file attributes change (such as when a file is truncated, chown/chmod * operations, transferring disk quotas, etc). * @dentry contains the dentry structure for the file. + * @mnt is the vfsmount corresponding to @dentry (may be NULL). * @attr is the iattr structure containing the new file attributes. * Return 0 if permission is granted. * @inode_getattr: @@ -426,18 +440,18 @@ * inode. * @inode_setxattr: * Check permission before setting the extended attributes - * @value identified by @name for @dentry. + * @value identified by @name for @dentry and @mnt. * Return 0 if permission is granted. * @inode_post_setxattr: * Update inode security field after successful setxattr operation. - * @value identified by @name for @dentry. + * @value identified by @name for @dentry and @mnt. * @inode_getxattr: * Check permission before obtaining the extended attributes - * identified by @name for @dentry. + * identified by @name for @dentry and @mnt. * Return 0 if permission is granted. * @inode_listxattr: * Check permission before obtaining the list of extended attribute - * names for @dentry. + * names for @dentry and @mnt. * Return 0 if permission is granted. * @inode_removexattr: * Check permission before removing the extended attribute @@ -578,6 +592,20 @@ * file_permission, and recheck access if anything has changed * since inode_permission. * + * Security hook for path + * + * @path_permission: + * Check permission before accessing a path. This hook is called by the + * existing Linux permission function, so a security module can use it to + * provide additional checking for existing Linux permission checks. + * Notice that this hook is called when a file is opened (as well as many + * other operations), whereas the file_security_ops permission hook is + * called when the actual read/write operations are performed. This + * hook is optional and if absent, inode_permission will be substituted. + * @path contains the path structure to check. + * @mask contains the permission mask. + * Return 0 if permission is granted. + * Security hooks for task operations. * * @task_create: @@ -1354,32 +1382,45 @@ void (*inode_free_security) (struct inode *inode); int (*inode_init_security) (struct inode *inode, struct inode *dir, char **name, void **value, size_t *len); - int (*inode_create) (struct inode *dir, - struct dentry *dentry, int mode); - int (*inode_link) (struct dentry *old_dentry, - struct inode *dir, struct dentry *new_dentry); - int (*inode_unlink) (struct inode *dir, struct dentry *dentry); - int (*inode_symlink) (struct inode *dir, - struct dentry *dentry, const char *old_name); - int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode); - int (*inode_rmdir) (struct inode *dir, struct dentry *dentry); + int (*inode_create) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); + int (*inode_link) (struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, struct dentry *new_dentry, + struct vfsmount *new_mnt); + int (*inode_unlink) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); + int (*inode_symlink) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *old_name); + int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); + int (*inode_rmdir) (struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); int (*inode_mknod) (struct inode *dir, struct dentry *dentry, - int mode, dev_t dev); + struct vfsmount *mnt, int mode, dev_t dev); int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); - int (*inode_readlink) (struct dentry *dentry); + struct vfsmount *old_mnt, + struct inode *new_dir, struct dentry *new_dentry, + struct vfsmount *new_mnt); + int (*inode_readlink) (struct dentry *dentry, struct vfsmount *mnt); int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); int (*inode_permission) (struct inode *inode, int mask); - int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); + int (*inode_setattr) (struct dentry *dentry, struct vfsmount *, + struct iattr *attr); int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); void (*inode_delete) (struct inode *inode); - int (*inode_setxattr) (struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); - void (*inode_post_setxattr) (struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); - int (*inode_getxattr) (struct dentry *dentry, const char *name); - int (*inode_listxattr) (struct dentry *dentry); - int (*inode_removexattr) (struct dentry *dentry, const char *name); + int (*inode_setxattr) (struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, size_t size, + int flags, struct file *file); + void (*inode_post_setxattr) (struct dentry *dentry, + struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags); + int (*inode_getxattr) (struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); + int (*inode_listxattr) (struct dentry *dentry, struct vfsmount *mnt, + struct file *file); + int (*inode_removexattr) (struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); int (*inode_need_killpriv) (struct dentry *dentry); int (*inode_killpriv) (struct dentry *dentry); int (*inode_getsecurity) (const struct inode *inode, const char *name, void **buffer, bool alloc); @@ -1407,6 +1448,7 @@ struct fown_struct *fown, int sig); int (*file_receive) (struct file *file); int (*dentry_open) (struct file *file); + int (*path_permission) (struct path *path, int mask); int (*task_create) (unsigned long clone_flags); int (*task_alloc_security) (struct task_struct *p); @@ -1618,30 +1660,43 @@ void security_inode_free(struct inode *inode); int security_inode_init_security(struct inode *inode, struct inode *dir, char **name, void **value, size_t *len); -int security_inode_create(struct inode *dir, struct dentry *dentry, int mode); -int security_inode_link(struct dentry *old_dentry, struct inode *dir, - struct dentry *new_dentry); -int security_inode_unlink(struct inode *dir, struct dentry *dentry); +int security_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); +int security_inode_link(struct dentry *old_dentry, struct vfsmount *old_mnt, + struct inode *dir, struct dentry *new_dentry, + struct vfsmount *new_mnt); +int security_inode_unlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); int security_inode_symlink(struct inode *dir, struct dentry *dentry, - const char *old_name); -int security_inode_mkdir(struct inode *dir, struct dentry *dentry, int mode); -int security_inode_rmdir(struct inode *dir, struct dentry *dentry); -int security_inode_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); + struct vfsmount *mnt, const char *old_name); +int security_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode); +int security_inode_rmdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt); +int security_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev); int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); -int security_inode_readlink(struct dentry *dentry); + struct vfsmount *old_mnt, struct inode *new_dir, + struct dentry *new_dentry, struct vfsmount *new_mnt); +int security_inode_readlink(struct dentry *dentry, struct vfsmount *mnt); int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd); int security_inode_permission(struct inode *inode, int mask); -int security_inode_setattr(struct dentry *dentry, struct iattr *attr); +int security_inode_setattr(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr); int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry); void security_inode_delete(struct inode *inode); -int security_inode_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -void security_inode_post_setxattr(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags); -int security_inode_getxattr(struct dentry *dentry, const char *name); -int security_inode_listxattr(struct dentry *dentry); -int security_inode_removexattr(struct dentry *dentry, const char *name); +int security_inode_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, struct file *file); +void security_inode_post_setxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags); +int security_inode_getxattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); +int security_inode_listxattr(struct dentry *dentry, struct vfsmount *mnt, + struct file *file); +int security_inode_removexattr(struct dentry *dentry, struct vfsmount *mnt, + const char *name, struct file *file); int security_inode_need_killpriv(struct dentry *dentry); int security_inode_killpriv(struct dentry *dentry); int security_inode_getsecurity(const struct inode *inode, const char *name, void **buffer, bool alloc); @@ -1664,6 +1719,7 @@ struct fown_struct *fown, int sig); int security_file_receive(struct file *file); int security_dentry_open(struct file *file); +int security_path_permission(struct path *path, int mask); int security_task_create(unsigned long clone_flags); int security_task_alloc(struct task_struct *p); void security_task_free(struct task_struct *p); @@ -1973,26 +2029,31 @@ static inline int security_inode_create(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { return 0; } static inline int security_inode_link(struct dentry *old_dentry, - struct inode *dir, - struct dentry *new_dentry) + struct vfsmount *old_mnt, + struct inode *dir, + struct dentry *new_dentry, + struct vfsmount *new_mnt) { return 0; } static inline int security_inode_unlink(struct inode *dir, - struct dentry *dentry) + struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static inline int security_inode_symlink(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *old_name) { return 0; @@ -2000,19 +2061,22 @@ static inline int security_inode_mkdir(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) { return 0; } static inline int security_inode_rmdir(struct inode *dir, - struct dentry *dentry) + struct dentry *dentry, + struct vfsmount *mnt) { return 0; } static inline int security_inode_mknod(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) { return 0; @@ -2020,13 +2084,16 @@ static inline int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry, + struct vfsmount *old_mnt, struct inode *new_dir, - struct dentry *new_dentry) + struct dentry *new_dentry, + struct vfsmount *new_mnt) { return 0; } -static inline int security_inode_readlink(struct dentry *dentry) +static inline int security_inode_readlink(struct dentry *dentry, + struct vfsmount *mnt) { return 0; } @@ -2043,7 +2110,8 @@ } static inline int security_inode_setattr(struct dentry *dentry, - struct iattr *attr) + struct vfsmount *mnt, + struct iattr *attr) { return 0; } @@ -2058,30 +2126,42 @@ { } static inline int security_inode_setxattr(struct dentry *dentry, - const char *name, const void *value, size_t size, int flags) + struct vfsmount *mnt, + const char *name, const void *value, + size_t size, int flags, + struct file *file) { - return cap_inode_setxattr(dentry, name, value, size, flags); + return cap_inode_setxattr(dentry, mnt, name, value, size, flags, file); } static inline void security_inode_post_setxattr(struct dentry *dentry, - const char *name, const void *value, size_t size, int flags) + struct vfsmount *mnt, + const char *name, + const void *value, + size_t size, int flags) { } static inline int security_inode_getxattr(struct dentry *dentry, - const char *name) + struct vfsmount *mnt, + const char *name, + struct file *file) { return 0; } -static inline int security_inode_listxattr(struct dentry *dentry) +static inline int security_inode_listxattr(struct dentry *dentry, + struct vfsmount *mnt, + struct file *file) { return 0; } static inline int security_inode_removexattr(struct dentry *dentry, - const char *name) + struct vfsmount *mnt, + const char *name, + struct file *file) { - return cap_inode_removexattr(dentry, name); + return cap_inode_removexattr(dentry, mnt, name, file); } static inline int security_inode_need_killpriv(struct dentry *dentry) @@ -2182,6 +2262,11 @@ return 0; } +static inline int security_path_permission(struct path *path, int mask) +{ + return 0; +} + static inline int security_task_create(unsigned long clone_flags) { return 0; --- linux-2.6.28.orig/include/linux/netfilter_ipv6/Kbuild +++ linux-2.6.28/include/linux/netfilter_ipv6/Kbuild @@ -11,6 +11,7 @@ header-y += ip6t_limit.h header-y += ip6t_mac.h header-y += ip6t_mark.h +header-y += ip6t_mh.h header-y += ip6t_multiport.h header-y += ip6t_opts.h header-y += ip6t_owner.h --- linux-2.6.28.orig/include/linux/netfilter/Kbuild +++ linux-2.6.28/include/linux/netfilter/Kbuild @@ -31,6 +31,8 @@ header-y += xt_owner.h header-y += xt_pkttype.h header-y += xt_rateest.h +header-y += xt_policy.h +header-y += xt_quota.h header-y += xt_realm.h header-y += xt_recent.h header-y += xt_sctp.h --- linux-2.6.28.orig/include/linux/nfsd/nfsd.h +++ linux-2.6.28/include/linux/nfsd/nfsd.h @@ -86,7 +86,8 @@ #ifdef CONFIG_NFSD_V4 __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, struct nfs4_acl *); -int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); +int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, + struct vfsmount *mnt, struct nfs4_acl **); #endif /* CONFIG_NFSD_V4 */ __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, char *name, int len, struct iattr *attrs,